Merge tag 'drm-intel-next-2024-11-04' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next

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

Features and functionality:

- Pantherlake (PTL) Xe3 LPD display enabling for xe driver (Clint, Suraj,
  Dnyaneshwar, Matt, Gustavo, Radhakrishna, Chaitanya, Haridhar, Juha-Pekka, Ravi)
- Enable dbuf overlap detection on Lunarlake and later (Stanislav, Vinod)
- Allow fastset for HDR infoframe changes (Chaitanya)
- Write DP source OUI also for non-eDP sinks (Imre)

Refactoring and cleanups:
- Independent platform identification for display (Jani)
- Display tracepoint fixes and cleanups (Gustavo)
- Share PCI ID headers between i915 and xe drivers (Jani)
- Use x100 version for full version and release checks (Jani)
- Conversions to struct intel_display (Jani, Ville)
- Reuse DP DPCD and AUX macros in gvt instead of duplication (Jani)
- Use string choice helpers (R Sundar, Sai Teja)
- Remove unused underrun detection irq code (Sai Teja)
- Color management debug improvements and other cleanups (Ville)
- Refactor panel fitter code to a separate file (Ville)
- Use try_cmpxchg() instead of open-coding (Uros Bizjak)

Fixes:
- PSR and Panel Replay fixes and workarounds (Jouni)
- Fix panel power during connector detection (Imre)
- Fix connector detection and modeset races (Imre)
- Fix C20 PHY TX MISC configuration (Gustavo)
- Improve panel fitter validity checks (Ville)
- Fix eDP short HPD interrupt handling while runtime suspended (Imre)
- Propagate DP MST DSC BW overhead/slice calculation errors (Imre)
- Stop hotplug polling for eDP connectors (Imre)
- Workaround panels reporting bad link status after PSR enable (Jouni)
- Panel Replay VRR VSC SDP related workaround and refactor (Animesh, Mitul)
- Fix memory leak on eDP init error path (Shuicheng)
- Fix GVT KVMGT Kconfig dependencies (Arnd Bergmann)
- Fix irq function documentation build warning (Rodrigo)
- Add platform check to power management fuse bit read (Clint)
- Revert kstrdup_const() and kfree_const() usage for clarity (Christophe JAILLET)
- Workaround horizontal odd panning issues in display versions 20 and 30 (Nemesa)
- Fix xe drive HDCP GSC firmware check (Suraj)

Merges:
- Backmerge drm-next to get some KVM changes (Rodrigo)
- Fix a build failure originating from previous backmerge (Jani)

Signed-off-by: Dave Airlie <airlied@redhat.com>

# Conflicts:
#	drivers/gpu/drm/i915/display/intel_dp_mst.c
From: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/87h68ni0wd.fsf@intel.com
This commit is contained in:
Dave Airlie 2024-11-06 09:08:52 +10:00
commit bf99ceb6e0
118 changed files with 3690 additions and 2975 deletions

View File

@ -35,10 +35,10 @@ Interrupt Handling
:functions: intel_irq_init intel_irq_init_hw intel_hpd_init
.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c
:functions: intel_runtime_pm_disable_interrupts
:functions: intel_irq_suspend
.. kernel-doc:: drivers/gpu/drm/i915/i915_irq.c
:functions: intel_runtime_pm_enable_interrupts
:functions: intel_irq_resume
Intel GVT-g Guest Support(vGPU)
-------------------------------

View File

@ -18,7 +18,7 @@
#include <linux/bcma/bcma_regs.h>
#include <linux/platform_data/x86/apple.h>
#include <drm/intel/i915_drm.h>
#include <drm/intel/i915_pciids.h>
#include <drm/intel/pciids.h>
#include <asm/pci-direct.h>
#include <asm/dma.h>
#include <asm/io_apic.h>

View File

@ -339,6 +339,7 @@ i915-y += \
display/intel_lspcon.o \
display/intel_lvds.o \
display/intel_panel.o \
display/intel_pfit.o \
display/intel_pps.o \
display/intel_qp_tables.o \
display/intel_sdvo.o \

View File

@ -170,13 +170,12 @@ static void assert_dp_port(struct intel_dp *intel_dp, bool state)
{
struct intel_display *display = to_intel_display(intel_dp);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
bool cur_state = intel_de_read(display, intel_dp->output_reg) & DP_PORT_EN;
I915_STATE_WARN(dev_priv, cur_state != state,
"[ENCODER:%d:%s] state assertion failure (expected %s, current %s)\n",
dig_port->base.base.base.id, dig_port->base.base.name,
str_on_off(state), str_on_off(cur_state));
INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
"[ENCODER:%d:%s] state assertion failure (expected %s, current %s)\n",
dig_port->base.base.base.id, dig_port->base.base.name,
str_on_off(state), str_on_off(cur_state));
}
#define assert_dp_port_disabled(d) assert_dp_port((d), false)
@ -185,9 +184,9 @@ static void assert_edp_pll(struct drm_i915_private *dev_priv, bool state)
struct intel_display *display = &dev_priv->display;
bool cur_state = intel_de_read(display, DP_A) & DP_PLL_ENABLE;
I915_STATE_WARN(dev_priv, cur_state != state,
"eDP PLL state assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
"eDP PLL state assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
}
#define assert_edp_pll_enabled(d) assert_edp_pll((d), true)
#define assert_edp_pll_disabled(d) assert_edp_pll((d), false)
@ -706,8 +705,7 @@ static void intel_enable_dp(struct intel_atomic_state *state,
if (IS_CHERRYVIEW(dev_priv))
lane_mask = intel_dp_unused_lane_mask(pipe_config->lane_count);
vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp),
lane_mask);
vlv_wait_port_ready(display, dp_to_dig_port(intel_dp), lane_mask);
}
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
@ -1251,6 +1249,7 @@ static void intel_dp_encoder_reset(struct drm_encoder *encoder)
intel_dp->DP = intel_de_read(display, intel_dp->output_reg);
intel_dp->reset_link_params = true;
intel_dp_invalidate_source_oui(intel_dp);
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
vlv_pps_pipe_reset(intel_dp);

View File

@ -480,8 +480,8 @@ static void vlv_hdmi_pre_enable(struct intel_atomic_state *state,
const struct intel_crtc_state *pipe_config,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(encoder);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
vlv_phy_pre_encoder_enable(encoder, pipe_config);
@ -496,7 +496,7 @@ static void vlv_hdmi_pre_enable(struct intel_atomic_state *state,
g4x_hdmi_enable_port(encoder, pipe_config);
vlv_wait_port_ready(dev_priv, dig_port, 0x0);
vlv_wait_port_ready(display, dig_port, 0x0);
}
static void vlv_hdmi_pre_pll_enable(struct intel_atomic_state *state,
@ -557,9 +557,8 @@ static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
const struct intel_crtc_state *pipe_config,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(encoder);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
chv_phy_pre_encoder_enable(encoder, pipe_config);
@ -573,7 +572,7 @@ static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
g4x_hdmi_enable_port(encoder, pipe_config);
vlv_wait_port_ready(dev_priv, dig_port, 0x0);
vlv_wait_port_ready(display, dig_port, 0x0);
/* Second common lane will stay alive on its own now */
chv_phy_release_cl2_override(encoder);

View File

@ -15,6 +15,7 @@
static void hsw_ips_enable(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
u32 val;
@ -27,16 +28,16 @@ static void hsw_ips_enable(const struct intel_crtc_state *crtc_state)
* This function is called from post_plane_update, which is run after
* a vblank wait.
*/
drm_WARN_ON(&i915->drm,
drm_WARN_ON(display->drm,
!(crtc_state->active_planes & ~BIT(PLANE_CURSOR)));
val = IPS_ENABLE;
if (i915->display.ips.false_color)
if (display->ips.false_color)
val |= IPS_FALSE_COLOR;
if (IS_BROADWELL(i915)) {
drm_WARN_ON(&i915->drm,
drm_WARN_ON(display->drm,
snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL,
val | IPS_PCODE_CONTROL));
/*
@ -46,7 +47,7 @@ static void hsw_ips_enable(const struct intel_crtc_state *crtc_state)
* so we need to just enable it and continue on.
*/
} else {
intel_de_write(i915, IPS_CTL, val);
intel_de_write(display, IPS_CTL, val);
/*
* The bit only becomes 1 in the next vblank, so this wait here
* is essentially intel_wait_for_vblank. If we don't have this
@ -54,14 +55,15 @@ static void hsw_ips_enable(const struct intel_crtc_state *crtc_state)
* the HW state readout code will complain that the expected
* IPS_CTL value is not the one we read.
*/
if (intel_de_wait_for_set(i915, IPS_CTL, IPS_ENABLE, 50))
drm_err(&i915->drm,
if (intel_de_wait_for_set(display, IPS_CTL, IPS_ENABLE, 50))
drm_err(display->drm,
"Timed out waiting for IPS enable\n");
}
}
bool hsw_ips_disable(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
bool need_vblank_wait = false;
@ -70,19 +72,19 @@ bool hsw_ips_disable(const struct intel_crtc_state *crtc_state)
return need_vblank_wait;
if (IS_BROADWELL(i915)) {
drm_WARN_ON(&i915->drm,
drm_WARN_ON(display->drm,
snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL, 0));
/*
* Wait for PCODE to finish disabling IPS. The BSpec specified
* 42ms timeout value leads to occasional timeouts so use 100ms
* instead.
*/
if (intel_de_wait_for_clear(i915, IPS_CTL, IPS_ENABLE, 100))
drm_err(&i915->drm,
if (intel_de_wait_for_clear(display, IPS_CTL, IPS_ENABLE, 100))
drm_err(display->drm,
"Timed out waiting for IPS disable\n");
} else {
intel_de_write(i915, IPS_CTL, 0);
intel_de_posting_read(i915, IPS_CTL);
intel_de_write(display, IPS_CTL, 0);
intel_de_posting_read(display, IPS_CTL);
}
/* We need to wait for a vblank before we can disable the plane. */
@ -188,6 +190,7 @@ bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
@ -195,7 +198,7 @@ bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
if (!hsw_crtc_supports_ips(crtc))
return false;
if (!i915->display.params.enable_ips)
if (!display->params.enable_ips)
return false;
if (crtc_state->pipe_bpp > 24)
@ -209,7 +212,7 @@ bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
* Should measure whether using a lower cdclk w/o IPS
*/
if (IS_BROADWELL(i915) &&
crtc_state->pixel_rate > i915->display.cdclk.max_cdclk_freq * 95 / 100)
crtc_state->pixel_rate > display->cdclk.max_cdclk_freq * 95 / 100)
return false;
return true;
@ -259,6 +262,7 @@ int hsw_ips_compute_config(struct intel_atomic_state *state,
void hsw_ips_get_config(struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
@ -266,7 +270,7 @@ void hsw_ips_get_config(struct intel_crtc_state *crtc_state)
return;
if (IS_HASWELL(i915)) {
crtc_state->ips_enabled = intel_de_read(i915, IPS_CTL) & IPS_ENABLE;
crtc_state->ips_enabled = intel_de_read(display, IPS_CTL) & IPS_ENABLE;
} else {
/*
* We cannot readout IPS state on broadwell, set to
@ -280,9 +284,9 @@ void hsw_ips_get_config(struct intel_crtc_state *crtc_state)
static int hsw_ips_debugfs_false_color_get(void *data, u64 *val)
{
struct intel_crtc *crtc = data;
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
*val = i915->display.ips.false_color;
*val = display->ips.false_color;
return 0;
}
@ -290,7 +294,7 @@ static int hsw_ips_debugfs_false_color_get(void *data, u64 *val)
static int hsw_ips_debugfs_false_color_set(void *data, u64 val)
{
struct intel_crtc *crtc = data;
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
struct intel_crtc_state *crtc_state;
int ret;
@ -298,7 +302,7 @@ static int hsw_ips_debugfs_false_color_set(void *data, u64 val)
if (ret)
return ret;
i915->display.ips.false_color = val;
display->ips.false_color = val;
crtc_state = to_intel_crtc_state(crtc->base.state);
@ -325,18 +329,19 @@ DEFINE_DEBUGFS_ATTRIBUTE(hsw_ips_debugfs_false_color_fops,
static int hsw_ips_debugfs_status_show(struct seq_file *m, void *unused)
{
struct intel_crtc *crtc = m->private;
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
intel_wakeref_t wakeref;
wakeref = intel_runtime_pm_get(&i915->runtime_pm);
seq_printf(m, "Enabled by kernel parameter: %s\n",
str_yes_no(i915->display.params.enable_ips));
str_yes_no(display->params.enable_ips));
if (DISPLAY_VER(i915) >= 8) {
if (DISPLAY_VER(display) >= 8) {
seq_puts(m, "Currently: unknown\n");
} else {
if (intel_de_read(i915, IPS_CTL) & IPS_ENABLE)
if (intel_de_read(display, IPS_CTL) & IPS_ENABLE)
seq_puts(m, "Currently: enabled\n");
else
seq_puts(m, "Currently: disabled\n");

File diff suppressed because it is too large Load Diff

View File

@ -6,11 +6,11 @@
#ifndef __ICL_DSI_H__
#define __ICL_DSI_H__
struct drm_i915_private;
struct intel_bios_encoder_data;
struct intel_crtc_state;
struct intel_display;
void icl_dsi_init(struct drm_i915_private *dev_priv,
void icl_dsi_init(struct intel_display *display,
const struct intel_bios_encoder_data *devdata);
void icl_dsi_frame_update(struct intel_crtc_state *crtc_state);

View File

@ -1024,6 +1024,12 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
*/
hsub = 1;
vsub = 1;
/* Wa_16023981245 */
if ((DISPLAY_VERx100(i915) == 2000 ||
DISPLAY_VERx100(i915) == 3000) &&
src_x % 2 != 0)
hsub = 2;
} else {
hsub = fb->format->hsub;
vsub = fb->format->vsub;

View File

@ -949,7 +949,7 @@ int intel_backlight_device_register(struct intel_connector *connector)
else
props.power = BACKLIGHT_POWER_OFF;
name = kstrdup_const("intel_backlight", GFP_KERNEL);
name = kstrdup("intel_backlight", GFP_KERNEL);
if (!name)
return -ENOMEM;
@ -963,7 +963,7 @@ int intel_backlight_device_register(struct intel_connector *connector)
* compatibility. Use unique names for subsequent backlight devices as a
* fallback when the default name already exists.
*/
kfree_const(name);
kfree(name);
name = kasprintf(GFP_KERNEL, "card%d-%s-backlight",
i915->drm.primary->index, connector->base.name);
if (!name)
@ -987,7 +987,7 @@ int intel_backlight_device_register(struct intel_connector *connector)
connector->base.base.id, connector->base.name, name);
out:
kfree_const(name);
kfree(name);
return ret;
}

View File

@ -1169,7 +1169,6 @@ static int intel_bios_ssc_frequency(struct intel_display *display,
static void
parse_general_features(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
const struct bdb_general_features *general;
general = bdb_find_section(display, BDB_GENERAL_FEATURES);
@ -1179,7 +1178,7 @@ parse_general_features(struct intel_display *display)
display->vbt.int_tv_support = general->int_tv_support;
/* int_crt_support can't be trusted on earlier platforms */
if (display->vbt.version >= 155 &&
(HAS_DDI(display) || IS_VALLEYVIEW(i915)))
(HAS_DDI(display) || display->platform.valleyview))
display->vbt.int_crt_support = general->int_crt_support;
display->vbt.lvds_use_ssc = general->enable_ssc;
display->vbt.lvds_ssc_freq =
@ -1542,7 +1541,6 @@ static void
parse_psr(struct intel_display *display,
struct intel_panel *panel)
{
struct drm_i915_private *i915 = to_i915(display->drm);
const struct bdb_psr *psr;
const struct psr_table *psr_table;
int panel_type = panel->vbt.panel_type;
@ -1567,7 +1565,7 @@ parse_psr(struct intel_display *display,
* Old decimal value is wake up time in multiples of 100 us.
*/
if (display->vbt.version >= 205 &&
(DISPLAY_VER(display) >= 9 && !IS_BROXTON(i915))) {
(DISPLAY_VER(display) >= 9 && !display->platform.broxton)) {
switch (psr_table->tp1_wakeup_time) {
case 0:
panel->vbt.psr.tp1_wakeup_time_us = 500;
@ -2029,11 +2027,9 @@ static void icl_fixup_mipi_sequences(struct intel_display *display,
static void fixup_mipi_sequences(struct intel_display *display,
struct intel_panel *panel)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(display) >= 11)
icl_fixup_mipi_sequences(display, panel);
else if (IS_VALLEYVIEW(i915))
else if (display->platform.valleyview)
vlv_fixup_mipi_sequences(display, panel);
}
@ -2243,15 +2239,15 @@ static u8 map_ddc_pin(struct intel_display *display, u8 vbt_pin)
const u8 *ddc_pin_map;
int i, n_entries;
if (INTEL_PCH_TYPE(i915) >= PCH_MTL || IS_ALDERLAKE_P(i915)) {
if (INTEL_PCH_TYPE(i915) >= PCH_MTL || display->platform.alderlake_p) {
ddc_pin_map = adlp_ddc_pin_map;
n_entries = ARRAY_SIZE(adlp_ddc_pin_map);
} else if (IS_ALDERLAKE_S(i915)) {
} else if (display->platform.alderlake_s) {
ddc_pin_map = adls_ddc_pin_map;
n_entries = ARRAY_SIZE(adls_ddc_pin_map);
} else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) {
return vbt_pin;
} else if (IS_ROCKETLAKE(i915) && INTEL_PCH_TYPE(i915) == PCH_TGP) {
} else if (display->platform.rocketlake && INTEL_PCH_TYPE(i915) == PCH_TGP) {
ddc_pin_map = rkl_pch_tgp_ddc_pin_map;
n_entries = ARRAY_SIZE(rkl_pch_tgp_ddc_pin_map);
} else if (HAS_PCH_TGP(i915) && DISPLAY_VER(display) == 9) {
@ -2334,7 +2330,6 @@ static enum port __dvo_port_to_port(int n_ports, int n_dvo,
static enum port dvo_port_to_port(struct intel_display *display,
u8 dvo_port)
{
struct drm_i915_private *i915 = to_i915(display->drm);
/*
* Each DDI port can have more than one value on the "DVO Port" field,
* so look for all the possible values for each port.
@ -2391,12 +2386,12 @@ static enum port dvo_port_to_port(struct intel_display *display,
ARRAY_SIZE(xelpd_port_mapping[0]),
xelpd_port_mapping,
dvo_port);
else if (IS_ALDERLAKE_S(i915))
else if (display->platform.alderlake_s)
return __dvo_port_to_port(ARRAY_SIZE(adls_port_mapping),
ARRAY_SIZE(adls_port_mapping[0]),
adls_port_mapping,
dvo_port);
else if (IS_DG1(i915) || IS_ROCKETLAKE(i915))
else if (display->platform.dg1 || display->platform.rocketlake)
return __dvo_port_to_port(ARRAY_SIZE(rkl_port_mapping),
ARRAY_SIZE(rkl_port_mapping[0]),
rkl_port_mapping,
@ -2519,7 +2514,6 @@ static void sanitize_hdmi_level_shift(struct intel_bios_encoder_data *devdata,
enum port port)
{
struct intel_display *display = devdata->display;
struct drm_i915_private *i915 = to_i915(display->drm);
if (!intel_bios_encoder_supports_dvi(devdata))
return;
@ -2529,7 +2523,7 @@ static void sanitize_hdmi_level_shift(struct intel_bios_encoder_data *devdata,
* with a HSW VBT where the level shifter value goes
* up to 11, whereas the BDW max is 9.
*/
if (IS_BROADWELL(i915) && devdata->child.hdmi_level_shifter_value > 9) {
if (display->platform.broadwell && devdata->child.hdmi_level_shifter_value > 9) {
drm_dbg_kms(display->drm,
"Bogus port %c VBT HDMI level shift %d, adjusting to %d\n",
port_name(port), devdata->child.hdmi_level_shifter_value, 9);
@ -2618,14 +2612,13 @@ int intel_bios_hdmi_max_tmds_clock(const struct intel_bios_encoder_data *devdata
static bool is_port_valid(struct intel_display *display, enum port port)
{
struct drm_i915_private *i915 = to_i915(display->drm);
/*
* On some ICL SKUs port F is not present, but broken VBTs mark
* the port as present. Only try to initialize port F for the
* SKUs that may actually have it.
*/
if (port == PORT_F && IS_ICELAKE(i915))
return IS_ICL_WITH_PORT_F(i915);
if (port == PORT_F && display->platform.icelake)
return display->platform.icelake_port_f;
return true;
}
@ -2723,9 +2716,7 @@ static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
static bool has_ddi_port_info(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
return DISPLAY_VER(display) >= 5 || IS_G4X(i915);
return DISPLAY_VER(display) >= 5 || display->platform.g4x;
}
static void parse_ddi_ports(struct intel_display *display)
@ -2796,7 +2787,6 @@ static bool child_device_size_valid(struct intel_display *display, int size)
static void
parse_general_definitions(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
const struct bdb_general_definitions *defs;
struct intel_bios_encoder_data *devdata;
const struct child_device_config *child;
@ -2821,7 +2811,7 @@ parse_general_definitions(struct intel_display *display)
bus_pin = defs->crt_ddc_gmbus_pin;
drm_dbg_kms(display->drm, "crt_ddc_bus_pin: %d\n", bus_pin);
if (intel_gmbus_is_valid_pin(i915, bus_pin))
if (intel_gmbus_is_valid_pin(display, bus_pin))
display->vbt.crt_ddc_pin = bus_pin;
if (!child_device_size_valid(display, defs->child_dev_size))
@ -2907,7 +2897,7 @@ init_vbt_missing_defaults(struct intel_display *display)
unsigned int ports = DISPLAY_RUNTIME_INFO(display)->port_mask;
enum port port;
if (!HAS_DDI(display) && !IS_CHERRYVIEW(i915))
if (!HAS_DDI(display) && !display->platform.cherryview)
return;
for_each_port_masked(port, ports) {
@ -3338,7 +3328,6 @@ bool intel_bios_is_tv_present(struct intel_display *display)
*/
bool intel_bios_is_lvds_present(struct intel_display *display, u8 *i2c_pin)
{
struct drm_i915_private *i915 = to_i915(display->drm);
const struct intel_bios_encoder_data *devdata;
if (list_empty(&display->vbt.display_devices))
@ -3355,7 +3344,7 @@ bool intel_bios_is_lvds_present(struct intel_display *display, u8 *i2c_pin)
child->device_type != DEVICE_TYPE_LFP)
continue;
if (intel_gmbus_is_valid_pin(i915, child->i2c_pin))
if (intel_gmbus_is_valid_pin(display, child->i2c_pin))
*i2c_pin = child->i2c_pin;
/* However, we cannot trust the BIOS writers to populate
@ -3603,17 +3592,16 @@ static const u8 direct_aux_ch_map[] = {
static enum aux_ch map_aux_ch(struct intel_display *display, u8 aux_channel)
{
struct drm_i915_private *i915 = to_i915(display->drm);
const u8 *aux_ch_map;
int i, n_entries;
if (DISPLAY_VER(display) >= 13) {
aux_ch_map = adlp_aux_ch_map;
n_entries = ARRAY_SIZE(adlp_aux_ch_map);
} else if (IS_ALDERLAKE_S(i915)) {
} else if (display->platform.alderlake_s) {
aux_ch_map = adls_aux_ch_map;
n_entries = ARRAY_SIZE(adls_aux_ch_map);
} else if (IS_DG1(i915) || IS_ROCKETLAKE(i915)) {
} else if (display->platform.dg1 || display->platform.rocketlake) {
aux_ch_map = rkl_aux_ch_map;
n_entries = ARRAY_SIZE(rkl_aux_ch_map);
} else {

View File

@ -743,7 +743,7 @@ void intel_bw_init_hw(struct drm_i915_private *dev_priv)
if (!HAS_DISPLAY(dev_priv))
return;
if (DISPLAY_VER_FULL(dev_priv) >= IP_VER(14, 1) && IS_DGFX(dev_priv))
if (DISPLAY_VERx100(dev_priv) >= 1401 && IS_DGFX(dev_priv))
xe2_hpd_get_bw_info(dev_priv, &xe2_hpd_sa_info);
else if (DISPLAY_VER(dev_priv) >= 14)
tgl_get_bw_info(dev_priv, &mtl_sa_info);

View File

@ -1468,6 +1468,39 @@ static const struct intel_cdclk_vals xe2hpd_cdclk_table[] = {
{}
};
static const struct intel_cdclk_vals xe3lpd_cdclk_table[] = {
{ .refclk = 38400, .cdclk = 153600, .ratio = 16, .waveform = 0xaaaa },
{ .refclk = 38400, .cdclk = 172800, .ratio = 16, .waveform = 0xad5a },
{ .refclk = 38400, .cdclk = 192000, .ratio = 16, .waveform = 0xb6b6 },
{ .refclk = 38400, .cdclk = 211200, .ratio = 16, .waveform = 0xdbb6 },
{ .refclk = 38400, .cdclk = 230400, .ratio = 16, .waveform = 0xeeee },
{ .refclk = 38400, .cdclk = 249600, .ratio = 16, .waveform = 0xf7de },
{ .refclk = 38400, .cdclk = 268800, .ratio = 16, .waveform = 0xfefe },
{ .refclk = 38400, .cdclk = 288000, .ratio = 16, .waveform = 0xfffe },
{ .refclk = 38400, .cdclk = 307200, .ratio = 16, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 326400, .ratio = 17, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 345600, .ratio = 18, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 364800, .ratio = 19, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 384000, .ratio = 20, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 403200, .ratio = 21, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 422400, .ratio = 22, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 441600, .ratio = 23, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 460800, .ratio = 24, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 480000, .ratio = 25, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 499200, .ratio = 26, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 518400, .ratio = 27, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 537600, .ratio = 28, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 556800, .ratio = 29, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 576000, .ratio = 30, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 595200, .ratio = 31, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 614400, .ratio = 32, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 633600, .ratio = 33, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 652800, .ratio = 34, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 672000, .ratio = 35, .waveform = 0xffff },
{ .refclk = 38400, .cdclk = 691200, .ratio = 36, .waveform = 0xffff },
{}
};
static const int cdclk_squash_len = 16;
static int cdclk_squash_divider(u16 waveform)
@ -1594,6 +1627,16 @@ static u8 rplu_calc_voltage_level(int cdclk)
rplu_voltage_level_max_cdclk);
}
static u8 xe3lpd_calc_voltage_level(int cdclk)
{
/*
* Starting with xe3lpd power controller does not need the voltage
* index when doing the modeset update. This function is best left
* defined but returning 0 to the mask.
*/
return 0;
}
static void icl_readout_refclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config)
{
@ -2015,8 +2058,8 @@ static bool pll_enable_wa_needed(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
return (DISPLAY_VER_FULL(display) == IP_VER(20, 0) ||
DISPLAY_VER_FULL(display) == IP_VER(14, 0) ||
return (DISPLAY_VERx100(display) == 2000 ||
DISPLAY_VERx100(display) == 1400 ||
IS_DG2(dev_priv)) &&
display->cdclk.hw.vco > 0;
}
@ -3437,7 +3480,9 @@ void intel_update_max_cdclk(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) {
if (DISPLAY_VER(display) >= 30) {
display->cdclk.max_cdclk_freq = 691200;
} else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) {
if (display->cdclk.hw.ref == 24000)
display->cdclk.max_cdclk_freq = 552000;
else
@ -3650,6 +3695,13 @@ void intel_cdclk_debugfs_register(struct intel_display *display)
display, &i915_cdclk_info_fops);
}
static const struct intel_cdclk_funcs xe3lpd_cdclk_funcs = {
.get_cdclk = bxt_get_cdclk,
.set_cdclk = bxt_set_cdclk,
.modeset_calc_cdclk = bxt_modeset_calc_cdclk,
.calc_voltage_level = xe3lpd_calc_voltage_level,
};
static const struct intel_cdclk_funcs rplu_cdclk_funcs = {
.get_cdclk = bxt_get_cdclk,
.set_cdclk = bxt_set_cdclk,
@ -3794,10 +3846,13 @@ void intel_init_cdclk_hooks(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (DISPLAY_VER(display) >= 20) {
if (DISPLAY_VER(display) >= 30) {
display->funcs.cdclk = &xe3lpd_cdclk_funcs;
display->cdclk.table = xe3lpd_cdclk_table;
} else if (DISPLAY_VER(display) >= 20) {
display->funcs.cdclk = &rplu_cdclk_funcs;
display->cdclk.table = xe2lpd_cdclk_table;
} else if (DISPLAY_VER_FULL(display) >= IP_VER(14, 1)) {
} else if (DISPLAY_VERx100(display) >= 1401) {
display->funcs.cdclk = &rplu_cdclk_funcs;
display->cdclk.table = xe2hpd_cdclk_table;
} else if (DISPLAY_VER(display) >= 14) {

File diff suppressed because it is too large Load Diff

View File

@ -11,12 +11,12 @@
struct intel_atomic_state;
struct intel_crtc_state;
struct intel_crtc;
struct intel_display;
struct intel_dsb;
struct drm_i915_private;
struct drm_property_blob;
void intel_color_init_hooks(struct drm_i915_private *i915);
int intel_color_init(struct drm_i915_private *i915);
void intel_color_init_hooks(struct intel_display *display);
int intel_color_init(struct intel_display *display);
void intel_color_crtc_init(struct intel_crtc *crtc);
int intel_color_check(struct intel_atomic_state *state,
struct intel_crtc *crtc);

View File

@ -81,12 +81,13 @@ static struct intel_crt *intel_attached_crt(struct intel_connector *connector)
return intel_encoder_to_crt(intel_attached_encoder(connector));
}
bool intel_crt_port_enabled(struct drm_i915_private *dev_priv,
bool intel_crt_port_enabled(struct intel_display *display,
i915_reg_t adpa_reg, enum pipe *pipe)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 val;
val = intel_de_read(dev_priv, adpa_reg);
val = intel_de_read(display, adpa_reg);
/* asserts want to know the pipe even if the port is disabled */
if (HAS_PCH_CPT(dev_priv))
@ -100,6 +101,7 @@ bool intel_crt_port_enabled(struct drm_i915_private *dev_priv,
static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
enum pipe *pipe)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crt *crt = intel_encoder_to_crt(encoder);
intel_wakeref_t wakeref;
@ -110,7 +112,7 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
if (!wakeref)
return false;
ret = intel_crt_port_enabled(dev_priv, crt->adpa_reg, pipe);
ret = intel_crt_port_enabled(display, crt->adpa_reg, pipe);
intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
@ -119,11 +121,11 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
static unsigned int intel_crt_get_flags(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
struct intel_crt *crt = intel_encoder_to_crt(encoder);
u32 tmp, flags = 0;
tmp = intel_de_read(dev_priv, crt->adpa_reg);
tmp = intel_de_read(display, crt->adpa_reg);
if (tmp & ADPA_HSYNC_ACTIVE_HIGH)
flags |= DRM_MODE_FLAG_PHSYNC;
@ -168,13 +170,14 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int mode)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crt *crt = intel_encoder_to_crt(encoder);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
u32 adpa;
if (DISPLAY_VER(dev_priv) >= 5)
if (DISPLAY_VER(display) >= 5)
adpa = ADPA_HOTPLUG_BITS;
else
adpa = 0;
@ -193,7 +196,7 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder,
adpa |= ADPA_PIPE_SEL(crtc->pipe);
if (!HAS_PCH_SPLIT(dev_priv))
intel_de_write(dev_priv, BCLRPAT(dev_priv, crtc->pipe), 0);
intel_de_write(display, BCLRPAT(display, crtc->pipe), 0);
switch (mode) {
case DRM_MODE_DPMS_ON:
@ -210,7 +213,7 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder,
break;
}
intel_de_write(dev_priv, crt->adpa_reg, adpa);
intel_de_write(display, crt->adpa_reg, adpa);
}
static void intel_disable_crt(struct intel_atomic_state *state,
@ -241,9 +244,10 @@ static void hsw_disable_crt(struct intel_atomic_state *state,
const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
drm_WARN_ON(&dev_priv->drm, !old_crtc_state->has_pch_encoder);
drm_WARN_ON(display->drm, !old_crtc_state->has_pch_encoder);
intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
}
@ -253,6 +257,7 @@ static void hsw_post_disable_crt(struct intel_atomic_state *state,
const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state)
{
struct intel_display *display = to_intel_display(state);
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@ -272,7 +277,7 @@ static void hsw_post_disable_crt(struct intel_atomic_state *state,
hsw_fdi_disable(encoder);
drm_WARN_ON(&dev_priv->drm, !old_crtc_state->has_pch_encoder);
drm_WARN_ON(display->drm, !old_crtc_state->has_pch_encoder);
intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
}
@ -282,9 +287,10 @@ static void hsw_pre_pll_enable_crt(struct intel_atomic_state *state,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
drm_WARN_ON(&dev_priv->drm, !crtc_state->has_pch_encoder);
drm_WARN_ON(display->drm, !crtc_state->has_pch_encoder);
intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
}
@ -294,11 +300,12 @@ static void hsw_pre_enable_crt(struct intel_atomic_state *state,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum pipe pipe = crtc->pipe;
drm_WARN_ON(&dev_priv->drm, !crtc_state->has_pch_encoder);
drm_WARN_ON(display->drm, !crtc_state->has_pch_encoder);
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
@ -312,11 +319,12 @@ static void hsw_enable_crt(struct intel_atomic_state *state,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum pipe pipe = crtc->pipe;
drm_WARN_ON(&dev_priv->drm, !crtc_state->has_pch_encoder);
drm_WARN_ON(display->drm, !crtc_state->has_pch_encoder);
intel_ddi_enable_transcoder_func(encoder, crtc_state);
@ -346,9 +354,10 @@ static enum drm_mode_status
intel_crt_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct intel_display *display = to_intel_display(connector->dev);
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
int max_dotclk = dev_priv->display.cdclk.max_dotclk_freq;
int max_dotclk = display->cdclk.max_dotclk_freq;
enum drm_mode_status status;
int max_clock;
@ -367,7 +376,7 @@ intel_crt_mode_valid(struct drm_connector *connector,
* DAC limit supposedly 355 MHz.
*/
max_clock = 270000;
else if (IS_DISPLAY_VER(dev_priv, 3, 4))
else if (IS_DISPLAY_VER(display, 3, 4))
max_clock = 400000;
else
max_clock = 350000;
@ -428,6 +437,7 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode;
@ -450,7 +460,7 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder,
if (HAS_PCH_LPT(dev_priv)) {
/* TODO: Check crtc_state->max_link_bpp_x16 instead of bw_constrained */
if (pipe_config->bw_constrained && pipe_config->pipe_bpp < 24) {
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"LPT only supports 24bpp\n");
return -EINVAL;
}
@ -470,6 +480,7 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder,
static bool ilk_crt_detect_hotplug(struct drm_connector *connector)
{
struct intel_display *display = to_intel_display(connector->dev);
struct drm_device *dev = connector->dev;
struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
struct drm_i915_private *dev_priv = to_i915(dev);
@ -483,36 +494,36 @@ static bool ilk_crt_detect_hotplug(struct drm_connector *connector)
crt->force_hotplug_required = false;
save_adpa = adpa = intel_de_read(dev_priv, crt->adpa_reg);
drm_dbg_kms(&dev_priv->drm,
save_adpa = adpa = intel_de_read(display, crt->adpa_reg);
drm_dbg_kms(display->drm,
"trigger hotplug detect cycle: adpa=0x%x\n", adpa);
adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER;
if (turn_off_dac)
adpa &= ~ADPA_DAC_ENABLE;
intel_de_write(dev_priv, crt->adpa_reg, adpa);
intel_de_write(display, crt->adpa_reg, adpa);
if (intel_de_wait_for_clear(dev_priv,
if (intel_de_wait_for_clear(display,
crt->adpa_reg,
ADPA_CRT_HOTPLUG_FORCE_TRIGGER,
1000))
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"timed out waiting for FORCE_TRIGGER");
if (turn_off_dac) {
intel_de_write(dev_priv, crt->adpa_reg, save_adpa);
intel_de_posting_read(dev_priv, crt->adpa_reg);
intel_de_write(display, crt->adpa_reg, save_adpa);
intel_de_posting_read(display, crt->adpa_reg);
}
}
/* Check the status to see if both blue and green are on now */
adpa = intel_de_read(dev_priv, crt->adpa_reg);
adpa = intel_de_read(display, crt->adpa_reg);
if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0)
ret = true;
else
ret = false;
drm_dbg_kms(&dev_priv->drm, "ironlake hotplug adpa=0x%x, result %d\n",
drm_dbg_kms(display->drm, "ironlake hotplug adpa=0x%x, result %d\n",
adpa, ret);
return ret;
@ -520,6 +531,7 @@ static bool ilk_crt_detect_hotplug(struct drm_connector *connector)
static bool valleyview_crt_detect_hotplug(struct drm_connector *connector)
{
struct intel_display *display = to_intel_display(connector->dev);
struct drm_device *dev = connector->dev;
struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
struct drm_i915_private *dev_priv = to_i915(dev);
@ -542,29 +554,29 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector)
*/
reenable_hpd = intel_hpd_disable(dev_priv, crt->base.hpd_pin);
save_adpa = adpa = intel_de_read(dev_priv, crt->adpa_reg);
drm_dbg_kms(&dev_priv->drm,
save_adpa = adpa = intel_de_read(display, crt->adpa_reg);
drm_dbg_kms(display->drm,
"trigger hotplug detect cycle: adpa=0x%x\n", adpa);
adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER;
intel_de_write(dev_priv, crt->adpa_reg, adpa);
intel_de_write(display, crt->adpa_reg, adpa);
if (intel_de_wait_for_clear(dev_priv, crt->adpa_reg,
if (intel_de_wait_for_clear(display, crt->adpa_reg,
ADPA_CRT_HOTPLUG_FORCE_TRIGGER, 1000)) {
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"timed out waiting for FORCE_TRIGGER");
intel_de_write(dev_priv, crt->adpa_reg, save_adpa);
intel_de_write(display, crt->adpa_reg, save_adpa);
}
/* Check the status to see if both blue and green are on now */
adpa = intel_de_read(dev_priv, crt->adpa_reg);
adpa = intel_de_read(display, crt->adpa_reg);
if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0)
ret = true;
else
ret = false;
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"valleyview hotplug adpa=0x%x, result %d\n", adpa, ret);
if (reenable_hpd)
@ -575,6 +587,7 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector)
static bool intel_crt_detect_hotplug(struct drm_connector *connector)
{
struct intel_display *display = to_intel_display(connector->dev);
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
u32 stat;
@ -603,18 +616,18 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
CRT_HOTPLUG_FORCE_DETECT,
CRT_HOTPLUG_FORCE_DETECT);
/* wait for FORCE_DETECT to go off */
if (intel_de_wait_for_clear(dev_priv, PORT_HOTPLUG_EN(dev_priv),
if (intel_de_wait_for_clear(display, PORT_HOTPLUG_EN(display),
CRT_HOTPLUG_FORCE_DETECT, 1000))
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"timed out waiting for FORCE_DETECT to go off");
}
stat = intel_de_read(dev_priv, PORT_HOTPLUG_STAT(dev_priv));
stat = intel_de_read(display, PORT_HOTPLUG_STAT(display));
if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE)
ret = true;
/* clear the interrupt we just generated, if any */
intel_de_write(dev_priv, PORT_HOTPLUG_STAT(dev_priv),
intel_de_write(display, PORT_HOTPLUG_STAT(display),
CRT_HOTPLUG_INT_STATUS);
i915_hotplug_interrupt_update(dev_priv, CRT_HOTPLUG_FORCE_DETECT, 0);
@ -660,8 +673,7 @@ static int intel_crt_ddc_get_modes(struct drm_connector *connector,
static bool intel_crt_detect_ddc(struct drm_connector *connector)
{
struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
struct drm_i915_private *dev_priv = to_i915(crt->base.base.dev);
struct intel_display *display = to_intel_display(connector->dev);
const struct drm_edid *drm_edid;
bool ret = false;
@ -674,15 +686,15 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
* have to check the EDID input spec of the attached device.
*/
if (drm_edid_is_digital(drm_edid)) {
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");
} else {
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"CRT detected via DDC:0x50 [EDID]\n");
ret = true;
}
} else {
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"CRT not detected via DDC:0x50 [no valid EDID found]\n");
}
@ -695,8 +707,6 @@ static enum drm_connector_status
intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
{
struct intel_display *display = to_intel_display(&crt->base);
struct drm_device *dev = crt->base.base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
enum transcoder cpu_transcoder = (enum transcoder)pipe;
u32 save_bclrpat;
u32 save_vtotal;
@ -707,14 +717,14 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
u8 st00;
enum drm_connector_status status;
drm_dbg_kms(&dev_priv->drm, "starting load-detect on CRT\n");
drm_dbg_kms(display->drm, "starting load-detect on CRT\n");
save_bclrpat = intel_de_read(dev_priv,
BCLRPAT(dev_priv, cpu_transcoder));
save_vtotal = intel_de_read(dev_priv,
TRANS_VTOTAL(dev_priv, cpu_transcoder));
vblank = intel_de_read(dev_priv,
TRANS_VBLANK(dev_priv, cpu_transcoder));
save_bclrpat = intel_de_read(display,
BCLRPAT(display, cpu_transcoder));
save_vtotal = intel_de_read(display,
TRANS_VTOTAL(display, cpu_transcoder));
vblank = intel_de_read(display,
TRANS_VBLANK(display, cpu_transcoder));
vtotal = REG_FIELD_GET(VTOTAL_MASK, save_vtotal) + 1;
vactive = REG_FIELD_GET(VACTIVE_MASK, save_vtotal) + 1;
@ -723,25 +733,25 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
vblank_end = REG_FIELD_GET(VBLANK_END_MASK, vblank) + 1;
/* Set the border color to purple. */
intel_de_write(dev_priv, BCLRPAT(dev_priv, cpu_transcoder), 0x500050);
intel_de_write(display, BCLRPAT(display, cpu_transcoder), 0x500050);
if (DISPLAY_VER(dev_priv) != 2) {
u32 transconf = intel_de_read(dev_priv,
TRANSCONF(dev_priv, cpu_transcoder));
if (DISPLAY_VER(display) != 2) {
u32 transconf = intel_de_read(display,
TRANSCONF(display, cpu_transcoder));
intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
intel_de_write(display, TRANSCONF(display, cpu_transcoder),
transconf | TRANSCONF_FORCE_BORDER);
intel_de_posting_read(dev_priv,
TRANSCONF(dev_priv, cpu_transcoder));
intel_de_posting_read(display,
TRANSCONF(display, cpu_transcoder));
/* Wait for next Vblank to substitue
* border color for Color info */
intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(display, pipe));
st00 = intel_de_read8(dev_priv, _VGA_MSR_WRITE);
st00 = intel_de_read8(display, _VGA_MSR_WRITE);
status = ((st00 & (1 << 4)) != 0) ?
connector_status_connected :
connector_status_disconnected;
intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
intel_de_write(display, TRANSCONF(display, cpu_transcoder),
transconf);
} else {
bool restore_vblank = false;
@ -752,13 +762,13 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
* Yes, this will flicker
*/
if (vblank_start <= vactive && vblank_end >= vtotal) {
u32 vsync = intel_de_read(dev_priv,
TRANS_VSYNC(dev_priv, cpu_transcoder));
u32 vsync = intel_de_read(display,
TRANS_VSYNC(display, cpu_transcoder));
u32 vsync_start = REG_FIELD_GET(VSYNC_START_MASK, vsync) + 1;
vblank_start = vsync_start;
intel_de_write(dev_priv,
TRANS_VBLANK(dev_priv, cpu_transcoder),
intel_de_write(display,
TRANS_VBLANK(display, cpu_transcoder),
VBLANK_START(vblank_start - 1) |
VBLANK_END(vblank_end - 1));
restore_vblank = true;
@ -772,9 +782,9 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
/*
* Wait for the border to be displayed
*/
while (intel_de_read(dev_priv, PIPEDSL(dev_priv, pipe)) >= vactive)
while (intel_de_read(display, PIPEDSL(display, pipe)) >= vactive)
;
while ((dsl = intel_de_read(dev_priv, PIPEDSL(dev_priv, pipe))) <= vsample)
while ((dsl = intel_de_read(display, PIPEDSL(display, pipe))) <= vsample)
;
/*
* Watch ST00 for an entire scanline
@ -784,15 +794,15 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
do {
count++;
/* Read the ST00 VGA status register */
st00 = intel_de_read8(dev_priv, _VGA_MSR_WRITE);
st00 = intel_de_read8(display, _VGA_MSR_WRITE);
if (st00 & (1 << 4))
detect++;
} while ((intel_de_read(dev_priv, PIPEDSL(dev_priv, pipe)) == dsl));
} while ((intel_de_read(display, PIPEDSL(display, pipe)) == dsl));
/* restore vblank if necessary */
if (restore_vblank)
intel_de_write(dev_priv,
TRANS_VBLANK(dev_priv, cpu_transcoder),
intel_de_write(display,
TRANS_VBLANK(display, cpu_transcoder),
vblank);
/*
* If more than 3/4 of the scanline detected a monitor,
@ -806,7 +816,7 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
}
/* Restore previous settings */
intel_de_write(dev_priv, BCLRPAT(dev_priv, cpu_transcoder),
intel_de_write(display, BCLRPAT(display, cpu_transcoder),
save_bclrpat);
return status;
@ -843,6 +853,7 @@ intel_crt_detect(struct drm_connector *connector,
struct drm_modeset_acquire_ctx *ctx,
bool force)
{
struct intel_display *display = to_intel_display(connector->dev);
struct drm_i915_private *dev_priv = to_i915(connector->dev);
struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
struct intel_encoder *intel_encoder = &crt->base;
@ -850,7 +861,7 @@ intel_crt_detect(struct drm_connector *connector,
intel_wakeref_t wakeref;
int status;
drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s] force=%d\n",
drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] force=%d\n",
connector->base.id, connector->name,
force);
@ -860,7 +871,7 @@ intel_crt_detect(struct drm_connector *connector,
if (!intel_display_driver_check_access(dev_priv))
return connector->status;
if (dev_priv->display.params.load_detect_test) {
if (display->params.load_detect_test) {
wakeref = intel_display_power_get(dev_priv,
intel_encoder->power_domain);
goto load_detect;
@ -873,18 +884,18 @@ intel_crt_detect(struct drm_connector *connector,
wakeref = intel_display_power_get(dev_priv,
intel_encoder->power_domain);
if (I915_HAS_HOTPLUG(dev_priv)) {
if (I915_HAS_HOTPLUG(display)) {
/* We can not rely on the HPD pin always being correctly wired
* up, for example many KVM do not pass it through, and so
* only trust an assertion that the monitor is connected.
*/
if (intel_crt_detect_hotplug(connector)) {
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"CRT detected via hotplug\n");
status = connector_status_connected;
goto out;
} else
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"CRT not detected via hotplug\n");
}
@ -897,7 +908,7 @@ intel_crt_detect(struct drm_connector *connector,
* broken monitor (without edid) to work behind a broken kvm (that fails
* to have the right resistors for HP detection) needs to fix this up.
* For now just bail out. */
if (I915_HAS_HOTPLUG(dev_priv)) {
if (I915_HAS_HOTPLUG(display)) {
status = connector_status_disconnected;
goto out;
}
@ -917,10 +928,10 @@ intel_crt_detect(struct drm_connector *connector,
} else {
if (intel_crt_detect_ddc(connector))
status = connector_status_connected;
else if (DISPLAY_VER(dev_priv) < 4)
else if (DISPLAY_VER(display) < 4)
status = intel_crt_load_detect(crt,
to_intel_crtc(connector->state->crtc)->pipe);
else if (dev_priv->display.params.load_detect_test)
else if (display->params.load_detect_test)
status = connector_status_disconnected;
else
status = connector_status_unknown;
@ -935,6 +946,7 @@ intel_crt_detect(struct drm_connector *connector,
static int intel_crt_get_modes(struct drm_connector *connector)
{
struct intel_display *display = to_intel_display(connector->dev);
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
@ -954,7 +966,7 @@ static int intel_crt_get_modes(struct drm_connector *connector)
goto out;
/* Try to probe digital port for output in DVI-I -> VGA mode. */
ddc = intel_gmbus_get_adapter(dev_priv, GMBUS_PIN_DPB);
ddc = intel_gmbus_get_adapter(display, GMBUS_PIN_DPB);
ret = intel_crt_ddc_get_modes(connector, ddc);
out:
@ -965,19 +977,19 @@ static int intel_crt_get_modes(struct drm_connector *connector)
void intel_crt_reset(struct drm_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->dev);
struct intel_display *display = to_intel_display(encoder->dev);
struct intel_crt *crt = intel_encoder_to_crt(to_intel_encoder(encoder));
if (DISPLAY_VER(dev_priv) >= 5) {
if (DISPLAY_VER(display) >= 5) {
u32 adpa;
adpa = intel_de_read(dev_priv, crt->adpa_reg);
adpa = intel_de_read(display, crt->adpa_reg);
adpa &= ~ADPA_CRT_HOTPLUG_MASK;
adpa |= ADPA_HOTPLUG_BITS;
intel_de_write(dev_priv, crt->adpa_reg, adpa);
intel_de_posting_read(dev_priv, crt->adpa_reg);
intel_de_write(display, crt->adpa_reg, adpa);
intel_de_posting_read(display, crt->adpa_reg);
drm_dbg_kms(&dev_priv->drm, "crt adpa set to 0x%x\n", adpa);
drm_dbg_kms(display->drm, "crt adpa set to 0x%x\n", adpa);
crt->force_hotplug_required = true;
}
@ -1007,8 +1019,9 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
.destroy = intel_encoder_destroy,
};
void intel_crt_init(struct drm_i915_private *dev_priv)
void intel_crt_init(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct drm_connector *connector;
struct intel_crt *crt;
struct intel_connector *intel_connector;
@ -1023,7 +1036,7 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
else
adpa_reg = ADPA;
adpa = intel_de_read(dev_priv, adpa_reg);
adpa = intel_de_read(display, adpa_reg);
if ((adpa & ADPA_DAC_ENABLE) == 0) {
/*
* On some machines (some IVB at least) CRT can be
@ -1033,11 +1046,11 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
* take. So the only way to tell is attempt to enable
* it and see what happens.
*/
intel_de_write(dev_priv, adpa_reg,
intel_de_write(display, adpa_reg,
adpa | ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
if ((intel_de_read(dev_priv, adpa_reg) & ADPA_DAC_ENABLE) == 0)
if ((intel_de_read(display, adpa_reg) & ADPA_DAC_ENABLE) == 0)
return;
intel_de_write(dev_priv, adpa_reg, adpa);
intel_de_write(display, adpa_reg, adpa);
}
crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL);
@ -1050,16 +1063,16 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
return;
}
ddc_pin = dev_priv->display.vbt.crt_ddc_pin;
ddc_pin = display->vbt.crt_ddc_pin;
connector = &intel_connector->base;
crt->connector = intel_connector;
drm_connector_init_with_ddc(&dev_priv->drm, connector,
drm_connector_init_with_ddc(display->drm, connector,
&intel_crt_connector_funcs,
DRM_MODE_CONNECTOR_VGA,
intel_gmbus_get_adapter(dev_priv, ddc_pin));
intel_gmbus_get_adapter(display, ddc_pin));
drm_encoder_init(&dev_priv->drm, &crt->base.base, &intel_crt_enc_funcs,
drm_encoder_init(display->drm, &crt->base.base, &intel_crt_enc_funcs,
DRM_MODE_ENCODER_DAC, "CRT");
intel_connector_attach_encoder(intel_connector, &crt->base);
@ -1071,14 +1084,14 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
else
crt->base.pipe_mask = ~0;
if (DISPLAY_VER(dev_priv) != 2)
if (DISPLAY_VER(display) != 2)
connector->interlace_allowed = true;
crt->adpa_reg = adpa_reg;
crt->base.power_domain = POWER_DOMAIN_PORT_CRT;
if (I915_HAS_HOTPLUG(dev_priv) &&
if (I915_HAS_HOTPLUG(display) &&
!dmi_check_system(intel_spurious_crt_detect)) {
crt->base.hpd_pin = HPD_CRT;
crt->base.hotplug = intel_encoder_hotplug;
@ -1088,7 +1101,7 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
}
intel_connector->base.polled = intel_connector->polled;
if (HAS_DDI(dev_priv)) {
if (HAS_DDI(display)) {
assert_port_valid(dev_priv, PORT_E);
crt->base.port = PORT_E;
@ -1132,8 +1145,8 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT |
FDI_RX_LINK_REVERSAL_OVERRIDE;
dev_priv->display.fdi.rx_config = intel_de_read(dev_priv,
FDI_RX_CTL(PIPE_A)) & fdi_config;
display->fdi.rx_config = intel_de_read(display,
FDI_RX_CTL(PIPE_A)) & fdi_config;
}
intel_crt_reset(&crt->base.base);

View File

@ -10,20 +10,20 @@
enum pipe;
struct drm_encoder;
struct drm_i915_private;
struct intel_display;
#ifdef I915
bool intel_crt_port_enabled(struct drm_i915_private *dev_priv,
bool intel_crt_port_enabled(struct intel_display *display,
i915_reg_t adpa_reg, enum pipe *pipe);
void intel_crt_init(struct drm_i915_private *dev_priv);
void intel_crt_init(struct intel_display *display);
void intel_crt_reset(struct drm_encoder *encoder);
#else
static inline bool intel_crt_port_enabled(struct drm_i915_private *dev_priv,
static inline bool intel_crt_port_enabled(struct intel_display *display,
i915_reg_t adpa_reg, enum pipe *pipe)
{
return false;
}
static inline void intel_crt_init(struct drm_i915_private *dev_priv)
static inline void intel_crt_init(struct intel_display *display)
{
}
static inline void intel_crt_reset(struct drm_encoder *encoder)

View File

@ -36,11 +36,11 @@
static void assert_vblank_disabled(struct drm_crtc *crtc)
{
struct drm_i915_private *i915 = to_i915(crtc->dev);
struct intel_display *display = to_intel_display(crtc->dev);
if (I915_STATE_WARN(i915, drm_crtc_vblank_get(crtc) == 0,
"[CRTC:%d:%s] vblank assertion failure (expected off, current on)\n",
crtc->base.id, crtc->name))
if (INTEL_DISPLAY_STATE_WARN(display, drm_crtc_vblank_get(crtc) == 0,
"[CRTC:%d:%s] vblank assertion failure (expected off, current on)\n",
crtc->base.id, crtc->name))
drm_crtc_vblank_put(crtc);
}

File diff suppressed because it is too large Load Diff

View File

@ -7,17 +7,15 @@
#define __INTEL_CX0_PHY_H__
#include <linux/types.h>
#include <linux/bitfield.h>
#include <linux/bits.h>
enum icl_port_dpll_id;
struct drm_i915_private;
struct intel_atomic_state;
struct intel_c10pll_state;
struct intel_c20pll_state;
struct intel_cx0pll_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_cx0pll_state;
struct intel_display;
struct intel_encoder;
struct intel_hdmi;
@ -35,7 +33,7 @@ void intel_cx0pll_readout_hw_state(struct intel_encoder *encoder,
int intel_cx0pll_calc_port_clock(struct intel_encoder *encoder,
const struct intel_cx0pll_state *pll_state);
void intel_cx0pll_dump_hw_state(struct drm_i915_private *dev_priv,
void intel_cx0pll_dump_hw_state(struct intel_display *display,
const struct intel_cx0pll_state *hw_state);
void intel_cx0pll_state_verify(struct intel_atomic_state *state,
struct intel_crtc *crtc);

View File

@ -273,13 +273,15 @@
#define _XE2HPD_C20_A_MPLLB_CFG 0xCCC2
#define _XE2HPD_C20_B_MPLLB_CFG 0xCCB6
#define _IS_XE2HPD_C20(i915) (DISPLAY_VER_FULL(i915) == IP_VER(14, 1))
#define _IS_XE2HPD_C20(i915) (DISPLAY_VERx100(i915) == 1401)
#define PHY_C20_A_TX_CNTX_CFG(i915, idx) \
((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_TX_CNTX_CFG : _MTL_C20_A_TX_CNTX_CFG) - (idx))
#define PHY_C20_B_TX_CNTX_CFG(i915, idx) \
((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_B_TX_CNTX_CFG : _MTL_C20_B_TX_CNTX_CFG) - (idx))
#define C20_PHY_TX_RATE REG_GENMASK(2, 0)
#define C20_PHY_TX_MISC_MASK REG_GENMASK16(7, 0)
#define C20_PHY_TX_MISC(val) REG_FIELD_PREP16(C20_PHY_TX_MISC_MASK, (val))
#define PHY_C20_A_CMN_CNTX_CFG(i915, idx) \
((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_CMN_CNTX_CFG : _MTL_C20_A_CMN_CNTX_CFG) - (idx))
@ -363,4 +365,7 @@
#define HDMI_DIV_MASK REG_GENMASK16(2, 0)
#define HDMI_DIV(val) REG_FIELD_PREP16(HDMI_DIV_MASK, val)
#define PICA_PHY_CONFIG_CONTROL _MMIO(0x16FE68)
#define EDP_ON_TYPEC REG_BIT(31)
#endif /* __INTEL_CX0_REG_DEFS_H__ */

View File

@ -2236,7 +2236,7 @@ static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_FEC_CONFIGURATION,
enable ? DP_FEC_READY : 0) <= 0)
drm_dbg_kms(display->drm, "Failed to set FEC_READY to %s in the sink\n",
enable ? "enabled" : "disabled");
str_enabled_disabled(enable));
if (enable &&
drm_dp_dpcd_writeb(&intel_dp->aux, DP_FEC_STATUS,
@ -2256,9 +2256,9 @@ static int read_fec_detected_status(struct drm_dp_aux *aux)
return status;
}
static void wait_for_fec_detected(struct drm_dp_aux *aux, bool enabled)
static int wait_for_fec_detected(struct drm_dp_aux *aux, bool enabled)
{
struct drm_i915_private *i915 = to_i915(aux->drm_dev);
struct intel_display *display = to_intel_display(aux->drm_dev);
int mask = enabled ? DP_FEC_DECODE_EN_DETECTED : DP_FEC_DECODE_DIS_DETECTED;
int status;
int err;
@ -2267,57 +2267,92 @@ static void wait_for_fec_detected(struct drm_dp_aux *aux, bool enabled)
status & mask || status < 0,
10000, 200000);
if (!err && status >= 0)
return;
if (err || status < 0) {
drm_dbg_kms(display->drm,
"Failed waiting for FEC %s to get detected: %d (status %d)\n",
str_enabled_disabled(enabled), err, status);
return err ? err : status;
}
if (err == -ETIMEDOUT)
drm_dbg_kms(&i915->drm, "Timeout waiting for FEC %s to get detected\n",
str_enabled_disabled(enabled));
else
drm_dbg_kms(&i915->drm, "FEC detected status read error: %d\n", status);
return 0;
}
void intel_ddi_wait_for_fec_status(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
bool enabled)
int intel_ddi_wait_for_fec_status(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
bool enabled)
{
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
struct intel_display *display = to_intel_display(encoder);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
int ret;
if (!crtc_state->fec_enable)
return;
return 0;
if (enabled)
ret = intel_de_wait_for_set(i915, dp_tp_status_reg(encoder, crtc_state),
ret = intel_de_wait_for_set(display, dp_tp_status_reg(encoder, crtc_state),
DP_TP_STATUS_FEC_ENABLE_LIVE, 1);
else
ret = intel_de_wait_for_clear(i915, dp_tp_status_reg(encoder, crtc_state),
ret = intel_de_wait_for_clear(display, dp_tp_status_reg(encoder, crtc_state),
DP_TP_STATUS_FEC_ENABLE_LIVE, 1);
if (ret)
drm_err(&i915->drm,
if (ret) {
drm_err(display->drm,
"Timeout waiting for FEC live state to get %s\n",
str_enabled_disabled(enabled));
return ret;
}
/*
* At least the Synoptics MST hub doesn't set the detected flag for
* FEC decoding disabling so skip waiting for that.
*/
if (enabled)
wait_for_fec_detected(&intel_dp->aux, enabled);
if (enabled) {
ret = wait_for_fec_detected(&intel_dp->aux, enabled);
if (ret)
return ret;
}
return 0;
}
static void intel_ddi_enable_fec(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
int i;
int ret;
if (!crtc_state->fec_enable)
return;
intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state),
intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state),
0, DP_TP_CTL_FEC_ENABLE);
if (DISPLAY_VER(display) < 30)
return;
ret = intel_ddi_wait_for_fec_status(encoder, crtc_state, true);
if (!ret)
return;
for (i = 0; i < 3; i++) {
drm_dbg_kms(display->drm, "Retry FEC enabling\n");
intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state),
DP_TP_CTL_FEC_ENABLE, 0);
ret = intel_ddi_wait_for_fec_status(encoder, crtc_state, false);
if (ret)
continue;
intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state),
0, DP_TP_CTL_FEC_ENABLE);
ret = intel_ddi_wait_for_fec_status(encoder, crtc_state, true);
if (!ret)
return;
}
drm_err(display->drm, "Failed to enable FEC after retries\n");
}
static void intel_ddi_disable_fec(struct intel_encoder *encoder,
@ -3478,6 +3513,13 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state,
drm_connector_update_privacy_screen(conn_state);
}
static void intel_ddi_update_pipe_hdmi(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
intel_hdmi_fastset_infoframes(encoder, crtc_state, conn_state);
}
void intel_ddi_update_pipe(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
@ -3489,6 +3531,10 @@ void intel_ddi_update_pipe(struct intel_atomic_state *state,
intel_ddi_update_pipe_dp(state, encoder, crtc_state,
conn_state);
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
intel_ddi_update_pipe_hdmi(encoder, crtc_state,
conn_state);
intel_hdcp_update_pipe(state, encoder, crtc_state, conn_state);
}
@ -4392,6 +4438,7 @@ static void intel_ddi_encoder_reset(struct drm_encoder *encoder)
struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder));
intel_dp->reset_link_params = true;
intel_dp_invalidate_source_oui(intel_dp);
intel_pps_encoder_reset(intel_dp);
@ -4885,7 +4932,7 @@ void intel_ddi_init(struct intel_display *display,
if (!assert_has_icl_dsi(dev_priv))
return;
icl_dsi_init(dev_priv, devdata);
icl_dsi_init(display, devdata);
return;
}

View File

@ -63,9 +63,9 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
void intel_ddi_enable_transcoder_clock(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
void intel_ddi_disable_transcoder_clock(const struct intel_crtc_state *crtc_state);
void intel_ddi_wait_for_fec_status(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
bool enabled);
int intel_ddi_wait_for_fec_status(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
bool enabled);
void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);

View File

@ -32,7 +32,7 @@ __intel_de_read(struct intel_display *display, i915_reg_t reg)
#define intel_de_read(p,...) __intel_de_read(__to_intel_display(p), __VA_ARGS__)
static inline u8
__intel_de_read8(struct intel_display *display, i915_reg_t reg)
intel_de_read8(struct intel_display *display, i915_reg_t reg)
{
u8 val;
@ -44,11 +44,10 @@ __intel_de_read8(struct intel_display *display, i915_reg_t reg)
return val;
}
#define intel_de_read8(p,...) __intel_de_read8(__to_intel_display(p), __VA_ARGS__)
static inline u64
__intel_de_read64_2x32(struct intel_display *display,
i915_reg_t lower_reg, i915_reg_t upper_reg)
intel_de_read64_2x32(struct intel_display *display,
i915_reg_t lower_reg, i915_reg_t upper_reg)
{
u64 val;
@ -63,7 +62,6 @@ __intel_de_read64_2x32(struct intel_display *display,
return val;
}
#define intel_de_read64_2x32(p,...) __intel_de_read64_2x32(__to_intel_display(p), __VA_ARGS__)
static inline void
__intel_de_posting_read(struct intel_display *display, i915_reg_t reg)
@ -88,12 +86,11 @@ __intel_de_write(struct intel_display *display, i915_reg_t reg, u32 val)
#define intel_de_write(p,...) __intel_de_write(__to_intel_display(p), __VA_ARGS__)
static inline u32
____intel_de_rmw_nowl(struct intel_display *display, i915_reg_t reg,
u32 clear, u32 set)
__intel_de_rmw_nowl(struct intel_display *display, i915_reg_t reg,
u32 clear, u32 set)
{
return intel_uncore_rmw(__to_uncore(display), reg, clear, set);
}
#define __intel_de_rmw_nowl(p,...) ____intel_de_rmw_nowl(__to_intel_display(p), __VA_ARGS__)
static inline u32
__intel_de_rmw(struct intel_display *display, i915_reg_t reg, u32 clear,
@ -112,18 +109,17 @@ __intel_de_rmw(struct intel_display *display, i915_reg_t reg, u32 clear,
#define intel_de_rmw(p,...) __intel_de_rmw(__to_intel_display(p), __VA_ARGS__)
static inline int
____intel_de_wait_for_register_nowl(struct intel_display *display,
i915_reg_t reg,
u32 mask, u32 value, unsigned int timeout)
__intel_de_wait_for_register_nowl(struct intel_display *display,
i915_reg_t reg,
u32 mask, u32 value, unsigned int timeout)
{
return intel_wait_for_register(__to_uncore(display), reg, mask,
value, timeout);
}
#define __intel_de_wait_for_register_nowl(p,...) ____intel_de_wait_for_register_nowl(__to_intel_display(p), __VA_ARGS__)
static inline int
__intel_de_wait(struct intel_display *display, i915_reg_t reg,
u32 mask, u32 value, unsigned int timeout)
intel_de_wait(struct intel_display *display, i915_reg_t reg,
u32 mask, u32 value, unsigned int timeout)
{
int ret;
@ -136,11 +132,10 @@ __intel_de_wait(struct intel_display *display, i915_reg_t reg,
return ret;
}
#define intel_de_wait(p,...) __intel_de_wait(__to_intel_display(p), __VA_ARGS__)
static inline int
__intel_de_wait_fw(struct intel_display *display, i915_reg_t reg,
u32 mask, u32 value, unsigned int timeout)
intel_de_wait_fw(struct intel_display *display, i915_reg_t reg,
u32 mask, u32 value, unsigned int timeout)
{
int ret;
@ -153,13 +148,12 @@ __intel_de_wait_fw(struct intel_display *display, i915_reg_t reg,
return ret;
}
#define intel_de_wait_fw(p,...) __intel_de_wait_fw(__to_intel_display(p), __VA_ARGS__)
static inline int
__intel_de_wait_custom(struct intel_display *display, i915_reg_t reg,
u32 mask, u32 value,
unsigned int fast_timeout_us,
unsigned int slow_timeout_ms, u32 *out_value)
intel_de_wait_custom(struct intel_display *display, i915_reg_t reg,
u32 mask, u32 value,
unsigned int fast_timeout_us,
unsigned int slow_timeout_ms, u32 *out_value)
{
int ret;
@ -173,7 +167,6 @@ __intel_de_wait_custom(struct intel_display *display, i915_reg_t reg,
return ret;
}
#define intel_de_wait_custom(p,...) __intel_de_wait_custom(__to_intel_display(p), __VA_ARGS__)
static inline int
__intel_de_wait_for_set(struct intel_display *display, i915_reg_t reg,
@ -220,19 +213,16 @@ __intel_de_write_fw(struct intel_display *display, i915_reg_t reg, u32 val)
#define intel_de_write_fw(p,...) __intel_de_write_fw(__to_intel_display(p), __VA_ARGS__)
static inline u32
__intel_de_read_notrace(struct intel_display *display, i915_reg_t reg)
intel_de_read_notrace(struct intel_display *display, i915_reg_t reg)
{
return intel_uncore_read_notrace(__to_uncore(display), reg);
}
#define intel_de_read_notrace(p,...) __intel_de_read_notrace(__to_intel_display(p), __VA_ARGS__)
static inline void
__intel_de_write_notrace(struct intel_display *display, i915_reg_t reg,
u32 val)
intel_de_write_notrace(struct intel_display *display, i915_reg_t reg, u32 val)
{
intel_uncore_write_notrace(__to_uncore(display), reg, val);
}
#define intel_de_write_notrace(p,...) __intel_de_write_notrace(__to_intel_display(p), __VA_ARGS__)
static __always_inline void
intel_de_write_dsb(struct intel_display *display, struct intel_dsb *dsb,

View File

@ -422,6 +422,7 @@ intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state)
void assert_transcoder(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder, bool state)
{
struct intel_display *display = &dev_priv->display;
bool cur_state;
enum intel_display_power_domain power_domain;
intel_wakeref_t wakeref;
@ -442,24 +443,24 @@ void assert_transcoder(struct drm_i915_private *dev_priv,
cur_state = false;
}
I915_STATE_WARN(dev_priv, cur_state != state,
"transcoder %s assertion failure (expected %s, current %s)\n",
transcoder_name(cpu_transcoder), str_on_off(state),
str_on_off(cur_state));
INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
"transcoder %s assertion failure (expected %s, current %s)\n",
transcoder_name(cpu_transcoder), str_on_off(state),
str_on_off(cur_state));
}
static void assert_plane(struct intel_plane *plane, bool state)
{
struct drm_i915_private *i915 = to_i915(plane->base.dev);
struct intel_display *display = to_intel_display(plane->base.dev);
enum pipe pipe;
bool cur_state;
cur_state = plane->get_hw_state(plane, &pipe);
I915_STATE_WARN(i915, cur_state != state,
"%s assertion failure (expected %s, current %s)\n",
plane->base.name, str_on_off(state),
str_on_off(cur_state));
INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
"%s assertion failure (expected %s, current %s)\n",
plane->base.name, str_on_off(state),
str_on_off(cur_state));
}
#define assert_plane_enabled(p) assert_plane(p, true)
@ -474,7 +475,7 @@ static void assert_planes_disabled(struct intel_crtc *crtc)
assert_plane_disabled(plane);
}
void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
void vlv_wait_port_ready(struct intel_display *display,
struct intel_digital_port *dig_port,
unsigned int expected_mask)
{
@ -487,11 +488,11 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
fallthrough;
case PORT_B:
port_mask = DPLL_PORTB_READY_MASK;
dpll_reg = DPLL(dev_priv, 0);
dpll_reg = DPLL(display, 0);
break;
case PORT_C:
port_mask = DPLL_PORTC_READY_MASK;
dpll_reg = DPLL(dev_priv, 0);
dpll_reg = DPLL(display, 0);
expected_mask <<= 4;
break;
case PORT_D:
@ -500,11 +501,11 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
break;
}
if (intel_de_wait(dev_priv, dpll_reg, port_mask, expected_mask, 1000))
drm_WARN(&dev_priv->drm, 1,
if (intel_de_wait(display, dpll_reg, port_mask, expected_mask, 1000))
drm_WARN(display->drm, 1,
"timed out waiting for [ENCODER:%d:%s] port ready: got 0x%x, expected 0x%x\n",
dig_port->base.base.base.id, dig_port->base.base.name,
intel_de_read(dev_priv, dpll_reg) & port_mask,
intel_de_read(display, dpll_reg) & port_mask,
expected_mask);
}
@ -861,7 +862,7 @@ static void icl_set_pipe_chicken(const struct intel_crtc_state *crtc_state)
*/
if (IS_DG2(dev_priv))
tmp &= ~UNDERRUN_RECOVERY_ENABLE_DG2;
else if (DISPLAY_VER(dev_priv) >= 13)
else if ((DISPLAY_VER(dev_priv) >= 13) && (DISPLAY_VER(dev_priv) < 30))
tmp |= UNDERRUN_RECOVERY_DISABLE_ADLP;
/* Wa_14010547955:dg2 */
@ -2609,13 +2610,29 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
return 0;
}
static bool intel_crtc_needs_wa_14015401596(struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
return intel_vrr_possible(crtc_state) && crtc_state->has_psr &&
adjusted_mode->crtc_vblank_start == adjusted_mode->crtc_vdisplay &&
IS_DISPLAY_VER(display, 13, 14);
}
static int intel_crtc_compute_config(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
int ret;
/* Wa_14015401596 */
if (intel_crtc_needs_wa_14015401596(crtc_state))
adjusted_mode->crtc_vblank_start += 1;
ret = intel_dpll_crtc_compute_clock(state, crtc);
if (ret)
return ret;
@ -5050,6 +5067,8 @@ intel_modeset_pipe_config_late(struct intel_atomic_state *state,
struct drm_connector *connector;
int i;
intel_vrr_compute_config_late(crtc_state);
for_each_new_connector_in_state(&state->base, connector,
conn_state, i) {
struct intel_encoder *encoder =
@ -5287,15 +5306,15 @@ pipe_config_cx0pll_mismatch(struct drm_printer *p, bool fastset,
const struct intel_cx0pll_state *a,
const struct intel_cx0pll_state *b)
{
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
char *chipname = a->use_c10 ? "C10" : "C20";
pipe_config_mismatch(p, fastset, crtc, name, chipname);
drm_printf(p, "expected:\n");
intel_cx0pll_dump_hw_state(i915, a);
intel_cx0pll_dump_hw_state(display, a);
drm_printf(p, "found:\n");
intel_cx0pll_dump_hw_state(i915, b);
intel_cx0pll_dump_hw_state(display, b);
}
bool
@ -5683,7 +5702,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_INFOFRAME(avi);
PIPE_CONF_CHECK_INFOFRAME(spd);
PIPE_CONF_CHECK_INFOFRAME(hdmi);
PIPE_CONF_CHECK_INFOFRAME(drm);
if (!fastset)
PIPE_CONF_CHECK_INFOFRAME(drm);
PIPE_CONF_CHECK_DP_VSC_SDP(vsc);
PIPE_CONF_CHECK_DP_AS_SDP(as_sdp);
@ -8129,7 +8149,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv)
if (HAS_DDI(dev_priv)) {
if (intel_ddi_crt_present(dev_priv))
intel_crt_init(dev_priv);
intel_crt_init(display);
intel_bios_for_each_encoder(display, intel_ddi_init);
@ -8144,7 +8164,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv)
* incorrect sharing of the PPS.
*/
intel_lvds_init(dev_priv);
intel_crt_init(dev_priv);
intel_crt_init(display);
dpd_is_edp = intel_dp_is_port_edp(dev_priv, PORT_D);
@ -8175,7 +8195,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv)
bool has_edp, has_port;
if (IS_VALLEYVIEW(dev_priv) && dev_priv->display.vbt.int_crt_support)
intel_crt_init(dev_priv);
intel_crt_init(display);
/*
* The DP_DETECTED bit is the latched state of the DDC
@ -8221,14 +8241,14 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv)
vlv_dsi_init(dev_priv);
} else if (IS_PINEVIEW(dev_priv)) {
intel_lvds_init(dev_priv);
intel_crt_init(dev_priv);
intel_crt_init(display);
} else if (IS_DISPLAY_VER(dev_priv, 3, 4)) {
bool found = false;
if (IS_MOBILE(dev_priv))
intel_lvds_init(dev_priv);
intel_crt_init(dev_priv);
intel_crt_init(display);
if (intel_de_read(dev_priv, GEN3_SDVOB) & SDVO_DETECTED) {
drm_dbg_kms(&dev_priv->drm, "probing SDVOB\n");
@ -8270,7 +8290,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv)
if (IS_I85X(dev_priv))
intel_lvds_init(dev_priv);
intel_crt_init(dev_priv);
intel_crt_init(display);
intel_dvo_init(dev_priv);
}
@ -8432,7 +8452,10 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
* plane so let's not advertize modes that are
* too big for that.
*/
if (DISPLAY_VER(dev_priv) >= 11) {
if (DISPLAY_VER(dev_priv) >= 30) {
plane_width_max = 6144 * num_joined_pipes;
plane_height_max = 4800;
} else if (DISPLAY_VER(dev_priv) >= 11) {
plane_width_max = 5120 * num_joined_pipes;
plane_height_max = 4320;
} else {

View File

@ -492,7 +492,7 @@ bool intel_encoder_is_tc(struct intel_encoder *encoder);
enum tc_port intel_encoder_to_tc(struct intel_encoder *encoder);
int ilk_get_lanes_required(int target_clock, int link_bw, int bpp);
void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
void vlv_wait_port_ready(struct intel_display *display,
struct intel_digital_port *dig_port,
unsigned int expected_mask);
@ -585,18 +585,17 @@ void assert_transcoder(struct drm_i915_private *dev_priv,
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
* visible problem. This will either WARN() or DRM_ERROR() depending on the
* verbose_state_checks module param, to enable distros and users to tailor
* their preferred amount of i915 abrt spam.
* Use INTEL_DISPLAY_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 visible problem. This will either drm_WARN() or
* drm_err() depending on the verbose_state_checks module param, to enable
* distros and users to tailor their preferred amount of i915 abrt spam.
*/
#define I915_STATE_WARN(__i915, condition, format...) ({ \
struct drm_device *drm = &(__i915)->drm; \
#define INTEL_DISPLAY_STATE_WARN(__display, condition, format...) ({ \
int __ret_warn_on = !!(condition); \
if (unlikely(__ret_warn_on)) \
if (!drm_WARN(drm, __i915->display.params.verbose_state_checks, format)) \
drm_err(drm, format); \
if (!drm_WARN((__display)->drm, (__display)->params.verbose_state_checks, format)) \
drm_err((__display)->drm, format); \
unlikely(__ret_warn_on); \
})

View File

@ -284,6 +284,9 @@ struct intel_display {
/* drm device backpointer */
struct drm_device *drm;
/* Platform (and subplatform, if any) identification */
struct intel_display_platforms platform;
/* Display functions */
struct {
/* Top level crtc-ish functions */
@ -455,6 +458,8 @@ struct intel_display {
/* For i915gm/i945gm vblank irq workaround */
u8 vblank_enabled;
int vblank_wa_num_pipes;
struct work_struct vblank_dc_work;
u32 de_irq_mask[I915_MAX_PIPES];

View File

@ -3,12 +3,13 @@
* Copyright © 2023 Intel Corporation
*/
#include <drm/intel/i915_pciids.h>
#include <drm/intel/pciids.h>
#include <drm/drm_color_mgmt.h>
#include <linux/pci.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_cx0_phy_regs.h"
#include "intel_de.h"
#include "intel_display.h"
#include "intel_display_device.h"
@ -31,14 +32,25 @@ struct stepping_desc {
.step_info.size = ARRAY_SIZE(_map)
struct subplatform_desc {
enum intel_display_subplatform subplatform;
struct intel_display_platforms platforms;
const char *name;
const u16 *pciidlist;
struct stepping_desc step_info;
};
#define SUBPLATFORM(_platform, _subplatform) \
.platforms._platform##_##_subplatform = 1, \
.name = #_subplatform
/*
* Group subplatform alias that matches multiple subplatforms. For making ult
* cover both ult and ulx on HSW/BDW.
*/
#define SUBPLATFORM_GROUP(_platform, _subplatform) \
.platforms._platform##_##_subplatform = 1
struct platform_desc {
enum intel_display_platform platform;
struct intel_display_platforms platforms;
const char *name;
const struct subplatform_desc *subplatforms;
const struct intel_display_device_info *info; /* NULL for GMD ID */
@ -46,9 +58,16 @@ struct platform_desc {
};
#define PLATFORM(_platform) \
.platform = (INTEL_DISPLAY_##_platform), \
.platforms._platform = 1, \
.name = #_platform
/*
* Group platform alias that matches multiple platforms. For aliases such as g4x
* that covers both g45 and gm45.
*/
#define PLATFORM_GROUP(_platform) \
.platforms._platform = 1
#define ID(id) (id)
static const struct intel_display_device_info no_display = {};
@ -232,7 +251,7 @@ static const struct intel_display_device_info no_display = {};
.__runtime_defaults.cpu_transcoder_mask = BIT(TRANSCODER_A)
static const struct platform_desc i830_desc = {
PLATFORM(I830),
PLATFORM(i830),
.info = &(const struct intel_display_device_info) {
I830_DISPLAY,
@ -241,7 +260,7 @@ static const struct platform_desc i830_desc = {
};
static const struct platform_desc i845_desc = {
PLATFORM(I845G),
PLATFORM(i845g),
.info = &(const struct intel_display_device_info) {
I845_DISPLAY,
@ -250,7 +269,7 @@ static const struct platform_desc i845_desc = {
};
static const struct platform_desc i85x_desc = {
PLATFORM(I85X),
PLATFORM(i85x),
.info = &(const struct intel_display_device_info) {
I830_DISPLAY,
@ -260,7 +279,7 @@ static const struct platform_desc i85x_desc = {
};
static const struct platform_desc i865g_desc = {
PLATFORM(I865G),
PLATFORM(i865g),
.info = &(const struct intel_display_device_info) {
I845_DISPLAY,
@ -282,7 +301,7 @@ static const struct platform_desc i865g_desc = {
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) /* SDVO B/C */
static const struct platform_desc i915g_desc = {
PLATFORM(I915G),
PLATFORM(i915g),
.info = &(const struct intel_display_device_info) {
GEN3_DISPLAY,
I845_COLORS,
@ -292,7 +311,7 @@ static const struct platform_desc i915g_desc = {
};
static const struct platform_desc i915gm_desc = {
PLATFORM(I915GM),
PLATFORM(i915gm),
.info = &(const struct intel_display_device_info) {
GEN3_DISPLAY,
I9XX_COLORS,
@ -305,7 +324,7 @@ static const struct platform_desc i915gm_desc = {
};
static const struct platform_desc i945g_desc = {
PLATFORM(I945G),
PLATFORM(i945g),
.info = &(const struct intel_display_device_info) {
GEN3_DISPLAY,
I845_COLORS,
@ -316,7 +335,7 @@ static const struct platform_desc i945g_desc = {
};
static const struct platform_desc i945gm_desc = {
PLATFORM(I915GM),
PLATFORM(i915gm),
.info = &(const struct intel_display_device_info) {
GEN3_DISPLAY,
I9XX_COLORS,
@ -330,7 +349,7 @@ static const struct platform_desc i945gm_desc = {
};
static const struct platform_desc g33_desc = {
PLATFORM(G33),
PLATFORM(g33),
.info = &(const struct intel_display_device_info) {
GEN3_DISPLAY,
I845_COLORS,
@ -339,7 +358,7 @@ static const struct platform_desc g33_desc = {
};
static const struct platform_desc pnv_desc = {
PLATFORM(PINEVIEW),
PLATFORM(pineview),
.info = &(const struct intel_display_device_info) {
GEN3_DISPLAY,
I9XX_COLORS,
@ -360,7 +379,7 @@ static const struct platform_desc pnv_desc = {
BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
static const struct platform_desc i965g_desc = {
PLATFORM(I965G),
PLATFORM(i965g),
.info = &(const struct intel_display_device_info) {
GEN4_DISPLAY,
.has_overlay = 1,
@ -370,7 +389,7 @@ static const struct platform_desc i965g_desc = {
};
static const struct platform_desc i965gm_desc = {
PLATFORM(I965GM),
PLATFORM(i965gm),
.info = &(const struct intel_display_device_info) {
GEN4_DISPLAY,
.has_overlay = 1,
@ -382,7 +401,8 @@ static const struct platform_desc i965gm_desc = {
};
static const struct platform_desc g45_desc = {
PLATFORM(G45),
PLATFORM(g45),
PLATFORM_GROUP(g4x),
.info = &(const struct intel_display_device_info) {
GEN4_DISPLAY,
@ -391,7 +411,8 @@ static const struct platform_desc g45_desc = {
};
static const struct platform_desc gm45_desc = {
PLATFORM(GM45),
PLATFORM(gm45),
PLATFORM_GROUP(g4x),
.info = &(const struct intel_display_device_info) {
GEN4_DISPLAY,
.supports_tv = 1,
@ -414,14 +435,14 @@ static const struct platform_desc gm45_desc = {
.__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 platform_desc ilk_d_desc = {
PLATFORM(IRONLAKE),
PLATFORM(ironlake),
.info = &(const struct intel_display_device_info) {
ILK_DISPLAY,
},
};
static const struct platform_desc ilk_m_desc = {
PLATFORM(IRONLAKE),
PLATFORM(ironlake),
.info = &(const struct intel_display_device_info) {
ILK_DISPLAY,
@ -430,7 +451,7 @@ static const struct platform_desc ilk_m_desc = {
};
static const struct platform_desc snb_desc = {
PLATFORM(SANDYBRIDGE),
PLATFORM(sandybridge),
.info = &(const struct intel_display_device_info) {
.has_hotplug = 1,
I9XX_PIPE_OFFSETS,
@ -447,7 +468,7 @@ static const struct platform_desc snb_desc = {
};
static const struct platform_desc ivb_desc = {
PLATFORM(IVYBRIDGE),
PLATFORM(ivybridge),
.info = &(const struct intel_display_device_info) {
.has_hotplug = 1,
IVB_PIPE_OFFSETS,
@ -464,7 +485,7 @@ static const struct platform_desc ivb_desc = {
};
static const struct platform_desc vlv_desc = {
PLATFORM(VALLEYVIEW),
PLATFORM(valleyview),
.info = &(const struct intel_display_device_info) {
.has_gmch = 1,
.has_hotplug = 1,
@ -495,10 +516,19 @@ static const u16 hsw_ulx_ids[] = {
};
static const struct platform_desc hsw_desc = {
PLATFORM(HASWELL),
PLATFORM(haswell),
.subplatforms = (const struct subplatform_desc[]) {
{ INTEL_DISPLAY_HASWELL_ULT, "ULT", hsw_ult_ids },
{ INTEL_DISPLAY_HASWELL_ULX, "ULX", hsw_ulx_ids },
/* Special case: Use ult both as group and subplatform. */
{
SUBPLATFORM(haswell, ult),
SUBPLATFORM_GROUP(haswell, ult),
.pciidlist = hsw_ult_ids,
},
{
SUBPLATFORM(haswell, ulx),
SUBPLATFORM_GROUP(haswell, ult),
.pciidlist = hsw_ulx_ids,
},
{},
},
.info = &(const struct intel_display_device_info) {
@ -539,10 +569,19 @@ static const u16 bdw_ulx_ids[] = {
};
static const struct platform_desc bdw_desc = {
PLATFORM(BROADWELL),
PLATFORM(broadwell),
.subplatforms = (const struct subplatform_desc[]) {
{ INTEL_DISPLAY_BROADWELL_ULT, "ULT", bdw_ult_ids },
{ INTEL_DISPLAY_BROADWELL_ULX, "ULX", bdw_ulx_ids },
/* Special case: Use ult both as group and subplatform. */
{
SUBPLATFORM(broadwell, ult),
SUBPLATFORM_GROUP(broadwell, ult),
.pciidlist = bdw_ult_ids,
},
{
SUBPLATFORM(broadwell, ulx),
SUBPLATFORM_GROUP(broadwell, ult),
.pciidlist = bdw_ulx_ids,
},
{},
},
.info = &(const struct intel_display_device_info) {
@ -567,7 +606,7 @@ static const struct platform_desc bdw_desc = {
};
static const struct platform_desc chv_desc = {
PLATFORM(CHERRYVIEW),
PLATFORM(cherryview),
.info = &(const struct intel_display_device_info) {
.has_hotplug = 1,
.has_gmch = 1,
@ -630,10 +669,16 @@ static const enum intel_step skl_steppings[] = {
};
static const struct platform_desc skl_desc = {
PLATFORM(SKYLAKE),
PLATFORM(skylake),
.subplatforms = (const struct subplatform_desc[]) {
{ INTEL_DISPLAY_SKYLAKE_ULT, "ULT", skl_ult_ids },
{ INTEL_DISPLAY_SKYLAKE_ULX, "ULX", skl_ulx_ids },
{
SUBPLATFORM(skylake, ult),
.pciidlist = skl_ult_ids,
},
{
SUBPLATFORM(skylake, ulx),
.pciidlist = skl_ulx_ids,
},
{},
},
.info = &skl_display,
@ -665,10 +710,16 @@ static const enum intel_step kbl_steppings[] = {
};
static const struct platform_desc kbl_desc = {
PLATFORM(KABYLAKE),
PLATFORM(kabylake),
.subplatforms = (const struct subplatform_desc[]) {
{ INTEL_DISPLAY_KABYLAKE_ULT, "ULT", kbl_ult_ids },
{ INTEL_DISPLAY_KABYLAKE_ULX, "ULX", kbl_ulx_ids },
{
SUBPLATFORM(kabylake, ult),
.pciidlist = kbl_ult_ids,
},
{
SUBPLATFORM(kabylake, ulx),
.pciidlist = kbl_ulx_ids,
},
{},
},
.info = &skl_display,
@ -690,10 +741,16 @@ static const u16 cfl_ulx_ids[] = {
};
static const struct platform_desc cfl_desc = {
PLATFORM(COFFEELAKE),
PLATFORM(coffeelake),
.subplatforms = (const struct subplatform_desc[]) {
{ INTEL_DISPLAY_COFFEELAKE_ULT, "ULT", cfl_ult_ids },
{ INTEL_DISPLAY_COFFEELAKE_ULX, "ULX", cfl_ulx_ids },
{
SUBPLATFORM(coffeelake, ult),
.pciidlist = cfl_ult_ids,
},
{
SUBPLATFORM(coffeelake, ulx),
.pciidlist = cfl_ulx_ids,
},
{},
},
.info = &skl_display,
@ -706,9 +763,12 @@ static const u16 cml_ult_ids[] = {
};
static const struct platform_desc cml_desc = {
PLATFORM(COMETLAKE),
PLATFORM(cometlake),
.subplatforms = (const struct subplatform_desc[]) {
{ INTEL_DISPLAY_COMETLAKE_ULT, "ULT", cml_ult_ids },
{
SUBPLATFORM(cometlake, ult),
.pciidlist = cml_ult_ids,
},
{},
},
.info = &skl_display,
@ -745,7 +805,7 @@ static const enum intel_step bxt_steppings[] = {
};
static const struct platform_desc bxt_desc = {
PLATFORM(BROXTON),
PLATFORM(broxton),
.info = &(const struct intel_display_device_info) {
GEN9_LP_DISPLAY,
.dbuf.size = 512 - 4, /* 4 blocks for bypass path allocation */
@ -760,7 +820,7 @@ static const enum intel_step glk_steppings[] = {
};
static const struct platform_desc glk_desc = {
PLATFORM(GEMINILAKE),
PLATFORM(geminilake),
.info = &(const struct intel_display_device_info) {
GEN9_LP_DISPLAY,
.dbuf.size = 1024 - 4, /* 4 blocks for bypass path allocation */
@ -822,9 +882,12 @@ static const enum intel_step icl_steppings[] = {
};
static const struct platform_desc icl_desc = {
PLATFORM(ICELAKE),
PLATFORM(icelake),
.subplatforms = (const struct subplatform_desc[]) {
{ INTEL_DISPLAY_ICELAKE_PORT_F, "Port F", icl_port_f_ids },
{
SUBPLATFORM(icelake, port_f),
.pciidlist = icl_port_f_ids,
},
{},
},
.info = &(const struct intel_display_device_info) {
@ -847,13 +910,13 @@ static const enum intel_step jsl_ehl_steppings[] = {
};
static const struct platform_desc jsl_desc = {
PLATFORM(JASPERLAKE),
PLATFORM(jasperlake),
.info = &jsl_ehl_display,
STEP_INFO(jsl_ehl_steppings),
};
static const struct platform_desc ehl_desc = {
PLATFORM(ELKHARTLAKE),
PLATFORM(elkhartlake),
.info = &jsl_ehl_display,
STEP_INFO(jsl_ehl_steppings),
};
@ -919,10 +982,13 @@ static const enum intel_step tgl_uy_steppings[] = {
};
static const struct platform_desc tgl_desc = {
PLATFORM(TIGERLAKE),
PLATFORM(tigerlake),
.subplatforms = (const struct subplatform_desc[]) {
{ INTEL_DISPLAY_TIGERLAKE_UY, "UY", tgl_uy_ids,
STEP_INFO(tgl_uy_steppings) },
{
SUBPLATFORM(tigerlake, uy),
.pciidlist = tgl_uy_ids,
STEP_INFO(tgl_uy_steppings),
},
{},
},
.info = &(const struct intel_display_device_info) {
@ -944,7 +1010,7 @@ static const enum intel_step dg1_steppings[] = {
};
static const struct platform_desc dg1_desc = {
PLATFORM(DG1),
PLATFORM(dg1),
.info = &(const struct intel_display_device_info) {
XE_D_DISPLAY,
@ -961,7 +1027,7 @@ static const enum intel_step rkl_steppings[] = {
};
static const struct platform_desc rkl_desc = {
PLATFORM(ROCKETLAKE),
PLATFORM(rocketlake),
.info = &(const struct intel_display_device_info) {
XE_D_DISPLAY,
.abox_mask = BIT(0),
@ -996,10 +1062,13 @@ static const enum intel_step adl_s_rpl_s_steppings[] = {
};
static const struct platform_desc adl_s_desc = {
PLATFORM(ALDERLAKE_S),
PLATFORM(alderlake_s),
.subplatforms = (const struct subplatform_desc[]) {
{ INTEL_DISPLAY_ALDERLAKE_S_RAPTORLAKE_S, "RPL-S", adls_rpls_ids,
STEP_INFO(adl_s_rpl_s_steppings) },
{
SUBPLATFORM(alderlake_s, raptorlake_s),
.pciidlist = adls_rpls_ids,
STEP_INFO(adl_s_rpl_s_steppings),
},
{},
},
.info = &(const struct intel_display_device_info) {
@ -1100,14 +1169,23 @@ static const enum intel_step adl_p_rpl_pu_steppings[] = {
};
static const struct platform_desc adl_p_desc = {
PLATFORM(ALDERLAKE_P),
PLATFORM(alderlake_p),
.subplatforms = (const struct subplatform_desc[]) {
{ INTEL_DISPLAY_ALDERLAKE_P_ALDERLAKE_N, "ADL-N", adlp_adln_ids,
STEP_INFO(adl_p_adl_n_steppings) },
{ INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_P, "RPL-P", adlp_rplp_ids,
STEP_INFO(adl_p_rpl_pu_steppings) },
{ INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_U, "RPL-U", adlp_rplu_ids,
STEP_INFO(adl_p_rpl_pu_steppings) },
{
SUBPLATFORM(alderlake_p, alderlake_n),
.pciidlist = adlp_adln_ids,
STEP_INFO(adl_p_adl_n_steppings),
},
{
SUBPLATFORM(alderlake_p, raptorlake_p),
.pciidlist = adlp_rplp_ids,
STEP_INFO(adl_p_rpl_pu_steppings),
},
{
SUBPLATFORM(alderlake_p, raptorlake_u),
.pciidlist = adlp_rplu_ids,
STEP_INFO(adl_p_rpl_pu_steppings),
},
{},
},
.info = &xe_lpd_display,
@ -1159,14 +1237,23 @@ static const enum intel_step dg2_g12_steppings[] = {
};
static const struct platform_desc dg2_desc = {
PLATFORM(DG2),
PLATFORM(dg2),
.subplatforms = (const struct subplatform_desc[]) {
{ INTEL_DISPLAY_DG2_G10, "G10", dg2_g10_ids,
STEP_INFO(dg2_g10_steppings) },
{ INTEL_DISPLAY_DG2_G11, "G11", dg2_g11_ids,
STEP_INFO(dg2_g11_steppings) },
{ INTEL_DISPLAY_DG2_G12, "G12", dg2_g12_ids,
STEP_INFO(dg2_g12_steppings) },
{
SUBPLATFORM(dg2, g10),
.pciidlist = dg2_g10_ids,
STEP_INFO(dg2_g10_steppings),
},
{
SUBPLATFORM(dg2, g11),
.pciidlist = dg2_g11_ids,
STEP_INFO(dg2_g11_steppings),
},
{
SUBPLATFORM(dg2, g12),
.pciidlist = dg2_g12_ids,
STEP_INFO(dg2_g12_steppings),
},
{},
},
.info = &xe_hpd_display,
@ -1227,6 +1314,7 @@ static const struct intel_display_device_info xe2_lpd_display = {
.__runtime_defaults.fbc_mask =
BIT(INTEL_FBC_A) | BIT(INTEL_FBC_B) |
BIT(INTEL_FBC_C) | BIT(INTEL_FBC_D),
.__runtime_defaults.has_dbuf_overlap_detection = true,
};
static const struct intel_display_device_info xe2_hpd_display = {
@ -1241,15 +1329,19 @@ static const struct intel_display_device_info xe2_hpd_display = {
* reported by the hardware.
*/
static const struct platform_desc mtl_desc = {
PLATFORM(METEORLAKE),
PLATFORM(meteorlake),
};
static const struct platform_desc lnl_desc = {
PLATFORM(LUNARLAKE),
PLATFORM(lunarlake),
};
static const struct platform_desc bmg_desc = {
PLATFORM(BATTLEMAGE),
PLATFORM(battlemage),
};
static const struct platform_desc ptl_desc = {
PLATFORM(pantherlake),
};
__diag_pop();
@ -1322,6 +1414,7 @@ static const struct {
INTEL_MTL_IDS(INTEL_DISPLAY_DEVICE, &mtl_desc),
INTEL_LNL_IDS(INTEL_DISPLAY_DEVICE, &lnl_desc),
INTEL_BMG_IDS(INTEL_DISPLAY_DEVICE, &bmg_desc),
INTEL_PTL_IDS(INTEL_DISPLAY_DEVICE, &ptl_desc),
};
static const struct {
@ -1332,6 +1425,7 @@ static const struct {
{ 14, 0, &xe_lpdp_display },
{ 14, 1, &xe2_hpd_display },
{ 20, 0, &xe2_lpd_display },
{ 30, 0, &xe2_lpd_display },
};
static const struct intel_display_device_info *
@ -1392,7 +1486,7 @@ find_subplatform_desc(struct pci_dev *pdev, const struct platform_desc *desc)
const struct subplatform_desc *sp;
const u16 *id;
for (sp = desc->subplatforms; sp && sp->subplatform; sp++)
for (sp = desc->subplatforms; sp && sp->pciidlist; sp++)
for (id = sp->pciidlist; *id; id++)
if (*id == pdev->device)
return sp;
@ -1451,6 +1545,25 @@ static enum intel_step get_pre_gmdid_step(struct intel_display *display,
return step;
}
/* Size of the entire bitmap, not the number of platforms */
static unsigned int display_platforms_num_bits(void)
{
return sizeof(((struct intel_display_platforms *)0)->bitmap) * BITS_PER_BYTE;
}
/* Number of platform bits set */
static unsigned int display_platforms_weight(const struct intel_display_platforms *p)
{
return bitmap_weight(p->bitmap, display_platforms_num_bits());
}
/* Merge the subplatform information from src to dst */
static void display_platforms_or(struct intel_display_platforms *dst,
const struct intel_display_platforms *src)
{
bitmap_or(dst->bitmap, dst->bitmap, src->bitmap, display_platforms_num_bits());
}
void intel_display_device_probe(struct drm_i915_private *i915)
{
struct intel_display *display = &i915->display;
@ -1490,13 +1603,23 @@ void intel_display_device_probe(struct drm_i915_private *i915)
&DISPLAY_INFO(i915)->__runtime_defaults,
sizeof(*DISPLAY_RUNTIME_INFO(i915)));
drm_WARN_ON(&i915->drm, !desc->platform || !desc->name);
DISPLAY_RUNTIME_INFO(i915)->platform = desc->platform;
drm_WARN_ON(&i915->drm, !desc->name ||
!display_platforms_weight(&desc->platforms));
display->platform = desc->platforms;
subdesc = find_subplatform_desc(pdev, desc);
if (subdesc) {
drm_WARN_ON(&i915->drm, !subdesc->subplatform || !subdesc->name);
DISPLAY_RUNTIME_INFO(i915)->subplatform = subdesc->subplatform;
drm_WARN_ON(&i915->drm, !subdesc->name ||
!display_platforms_weight(&subdesc->platforms));
display_platforms_or(&display->platform, &subdesc->platforms);
/* Ensure platform and subplatform are distinct */
drm_WARN_ON(&i915->drm,
display_platforms_weight(&display->platform) !=
display_platforms_weight(&desc->platforms) +
display_platforms_weight(&subdesc->platforms));
}
if (ip_ver.ver || ip_ver.rel || ip_ver.step) {
@ -1653,8 +1776,10 @@ static void __intel_display_device_info_runtime_init(struct drm_i915_private *i9
if (dfsm & SKL_DFSM_DISPLAY_HDCP_DISABLE)
display_runtime->has_hdcp = 0;
if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE)
display_runtime->fbc_mask = 0;
if (IS_DG2(i915) || DISPLAY_VER(i915) < 13) {
if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE)
display_runtime->fbc_mask = 0;
}
if (DISPLAY_VER(i915) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE))
display_runtime->has_dmc = 0;
@ -1662,6 +1787,10 @@ static void __intel_display_device_info_runtime_init(struct drm_i915_private *i9
if (IS_DISPLAY_VER(i915, 10, 12) &&
(dfsm & GLK_DFSM_DISPLAY_DSC_DISABLE))
display_runtime->has_dsc = 0;
if (DISPLAY_VER(display) >= 20 &&
(dfsm & XE2LPD_DFSM_DBUF_OVERLAP_DISABLE))
display_runtime->has_dbuf_overlap_detection = false;
}
if (DISPLAY_VER(i915) >= 20) {
@ -1679,6 +1808,10 @@ static void __intel_display_device_info_runtime_init(struct drm_i915_private *i9
}
}
if (DISPLAY_VER(i915) >= 30)
display_runtime->edp_typec_support =
intel_de_read(display, PICA_PHY_CONFIG_CONTROL) & EDP_ON_TYPEC;
display_runtime->rawclk_freq = intel_read_rawclk(display);
drm_dbg_kms(&i915->drm, "rawclk rate: %d kHz\n", display_runtime->rawclk_freq);

View File

@ -6,6 +6,7 @@
#ifndef __INTEL_DISPLAY_DEVICE_H__
#define __INTEL_DISPLAY_DEVICE_H__
#include <linux/bitops.h>
#include <linux/types.h>
#include "intel_display_conversion.h"
@ -14,88 +15,107 @@
struct drm_i915_private;
struct drm_printer;
/* Keep in gen based order, and chronological order within a gen */
enum intel_display_platform {
INTEL_DISPLAY_PLATFORM_UNINITIALIZED = 0,
/* Display ver 2 */
INTEL_DISPLAY_I830,
INTEL_DISPLAY_I845G,
INTEL_DISPLAY_I85X,
INTEL_DISPLAY_I865G,
/* Display ver 3 */
INTEL_DISPLAY_I915G,
INTEL_DISPLAY_I915GM,
INTEL_DISPLAY_I945G,
INTEL_DISPLAY_I945GM,
INTEL_DISPLAY_G33,
INTEL_DISPLAY_PINEVIEW,
/* Display ver 4 */
INTEL_DISPLAY_I965G,
INTEL_DISPLAY_I965GM,
INTEL_DISPLAY_G45,
INTEL_DISPLAY_GM45,
/* Display ver 5 */
INTEL_DISPLAY_IRONLAKE,
/* Display ver 6 */
INTEL_DISPLAY_SANDYBRIDGE,
/* Display ver 7 */
INTEL_DISPLAY_IVYBRIDGE,
INTEL_DISPLAY_VALLEYVIEW,
INTEL_DISPLAY_HASWELL,
/* Display ver 8 */
INTEL_DISPLAY_BROADWELL,
INTEL_DISPLAY_CHERRYVIEW,
/* Display ver 9 */
INTEL_DISPLAY_SKYLAKE,
INTEL_DISPLAY_BROXTON,
INTEL_DISPLAY_KABYLAKE,
INTEL_DISPLAY_GEMINILAKE,
INTEL_DISPLAY_COFFEELAKE,
INTEL_DISPLAY_COMETLAKE,
/* Display ver 11 */
INTEL_DISPLAY_ICELAKE,
INTEL_DISPLAY_JASPERLAKE,
INTEL_DISPLAY_ELKHARTLAKE,
/* Display ver 12 */
INTEL_DISPLAY_TIGERLAKE,
INTEL_DISPLAY_ROCKETLAKE,
INTEL_DISPLAY_DG1,
INTEL_DISPLAY_ALDERLAKE_S,
/* Display ver 13 */
INTEL_DISPLAY_ALDERLAKE_P,
INTEL_DISPLAY_DG2,
/* Display ver 14 (based on GMD ID) */
INTEL_DISPLAY_METEORLAKE,
/* Display ver 20 (based on GMD ID) */
INTEL_DISPLAY_LUNARLAKE,
/* Display ver 14.1 (based on GMD ID) */
INTEL_DISPLAY_BATTLEMAGE,
/*
* Display platforms and subplatforms. Keep platforms in display version based
* order, chronological order within a version, and subplatforms next to the
* platform.
*/
#define INTEL_DISPLAY_PLATFORMS(func) \
/* Display ver 2 */ \
func(i830) \
func(i845g) \
func(i85x) \
func(i865g) \
/* Display ver 3 */ \
func(i915g) \
func(i915gm) \
func(i945g) \
func(i945gm) \
func(g33) \
func(pineview) \
/* Display ver 4 */ \
func(i965g) \
func(i965gm) \
func(g45) \
func(gm45) \
func(g4x) /* group alias for g45 and gm45 */ \
/* Display ver 5 */ \
func(ironlake) \
/* Display ver 6 */ \
func(sandybridge) \
/* Display ver 7 */ \
func(ivybridge) \
func(valleyview) \
func(haswell) \
func(haswell_ult) \
func(haswell_ulx) \
/* Display ver 8 */ \
func(broadwell) \
func(broadwell_ult) \
func(broadwell_ulx) \
func(cherryview) \
/* Display ver 9 */ \
func(skylake) \
func(skylake_ult) \
func(skylake_ulx) \
func(broxton) \
func(kabylake) \
func(kabylake_ult) \
func(kabylake_ulx) \
func(geminilake) \
func(coffeelake) \
func(coffeelake_ult) \
func(coffeelake_ulx) \
func(cometlake) \
func(cometlake_ult) \
func(cometlake_ulx) \
/* Display ver 11 */ \
func(icelake) \
func(icelake_port_f) \
func(jasperlake) \
func(elkhartlake) \
/* Display ver 12 */ \
func(tigerlake) \
func(tigerlake_uy) \
func(rocketlake) \
func(dg1) \
func(alderlake_s) \
func(alderlake_s_raptorlake_s) \
/* Display ver 13 */ \
func(alderlake_p) \
func(alderlake_p_alderlake_n) \
func(alderlake_p_raptorlake_p) \
func(alderlake_p_raptorlake_u) \
func(dg2) \
func(dg2_g10) \
func(dg2_g11) \
func(dg2_g12) \
/* Display ver 14 (based on GMD ID) */ \
func(meteorlake) \
/* Display ver 20 (based on GMD ID) */ \
func(lunarlake) \
/* Display ver 14.1 (based on GMD ID) */ \
func(battlemage) \
/* Display ver 30 (based on GMD ID) */ \
func(pantherlake)
#define __MEMBER(name) unsigned long name:1;
#define __COUNT(x) 1 +
#define __NUM_PLATFORMS (INTEL_DISPLAY_PLATFORMS(__COUNT) 0)
struct intel_display_platforms {
union {
struct {
INTEL_DISPLAY_PLATFORMS(__MEMBER);
};
DECLARE_BITMAP(bitmap, __NUM_PLATFORMS);
};
};
enum intel_display_subplatform {
INTEL_DISPLAY_SUBPLATFORM_UNINITIALIZED = 0,
INTEL_DISPLAY_HASWELL_ULT,
INTEL_DISPLAY_HASWELL_ULX,
INTEL_DISPLAY_BROADWELL_ULT,
INTEL_DISPLAY_BROADWELL_ULX,
INTEL_DISPLAY_SKYLAKE_ULT,
INTEL_DISPLAY_SKYLAKE_ULX,
INTEL_DISPLAY_KABYLAKE_ULT,
INTEL_DISPLAY_KABYLAKE_ULX,
INTEL_DISPLAY_COFFEELAKE_ULT,
INTEL_DISPLAY_COFFEELAKE_ULX,
INTEL_DISPLAY_COMETLAKE_ULT,
INTEL_DISPLAY_COMETLAKE_ULX,
INTEL_DISPLAY_ICELAKE_PORT_F,
INTEL_DISPLAY_TIGERLAKE_UY,
INTEL_DISPLAY_ALDERLAKE_S_RAPTORLAKE_S,
INTEL_DISPLAY_ALDERLAKE_P_ALDERLAKE_N,
INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_P,
INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_U,
INTEL_DISPLAY_DG2_G10,
INTEL_DISPLAY_DG2_G11,
INTEL_DISPLAY_DG2_G12,
};
#undef __MEMBER
#undef __COUNT
#undef __NUM_PLATFORMS
#define DEV_INFO_DISPLAY_FOR_EACH_FLAG(func) \
/* Keep in alphabetical order */ \
@ -123,6 +143,7 @@ enum intel_display_subplatform {
#define HAS_CDCLK_SQUASH(i915) (DISPLAY_INFO(i915)->has_cdclk_squash)
#define HAS_CUR_FBC(i915) (!HAS_GMCH(i915) && IS_DISPLAY_VER(i915, 7, 13))
#define HAS_D12_PLANE_MINIMIZATION(i915) (IS_ROCKETLAKE(i915) || IS_ALDERLAKE_S(i915))
#define HAS_DBUF_OVERLAP_DETECTION(__i915) (DISPLAY_RUNTIME_INFO(__i915)->has_dbuf_overlap_detection)
#define HAS_DDI(i915) (DISPLAY_INFO(i915)->has_ddi)
#define HAS_DISPLAY(i915) (DISPLAY_RUNTIME_INFO(i915)->pipe_mask != 0)
#define HAS_DMC(i915) (DISPLAY_RUNTIME_INFO(i915)->has_dmc)
@ -166,10 +187,10 @@ enum intel_display_subplatform {
#define SUPPORTS_TV(i915) (DISPLAY_INFO(i915)->supports_tv)
/* Check that device has a display IP version within the specific range. */
#define IS_DISPLAY_VER_FULL(__i915, from, until) ( \
BUILD_BUG_ON_ZERO((from) < IP_VER(2, 0)) + \
(DISPLAY_VER_FULL(__i915) >= (from) && \
DISPLAY_VER_FULL(__i915) <= (until)))
#define IS_DISPLAY_VERx100(__i915, from, until) ( \
BUILD_BUG_ON_ZERO((from) < 200) + \
(DISPLAY_VERx100(__i915) >= (from) && \
DISPLAY_VERx100(__i915) <= (until)))
/*
* Check if a device has a specific IP version as well as a stepping within the
@ -180,22 +201,22 @@ enum intel_display_subplatform {
* hardware fix is present and the software workaround is no longer necessary.
* E.g.,
*
* IS_DISPLAY_VER_STEP(i915, IP_VER(14, 0), STEP_A0, STEP_B2)
* IS_DISPLAY_VER_STEP(i915, IP_VER(14, 0), STEP_C0, STEP_FOREVER)
* IS_DISPLAY_VERx100_STEP(i915, 1400, STEP_A0, STEP_B2)
* IS_DISPLAY_VERx100_STEP(i915, 1400, STEP_C0, STEP_FOREVER)
*
* "STEP_FOREVER" can be passed as "until" for workarounds that have no upper
* stepping bound for the specified IP version.
*/
#define IS_DISPLAY_VER_STEP(__i915, ipver, from, until) \
(IS_DISPLAY_VER_FULL((__i915), (ipver), (ipver)) && \
#define IS_DISPLAY_VERx100_STEP(__i915, ipver, from, until) \
(IS_DISPLAY_VERx100((__i915), (ipver), (ipver)) && \
IS_DISPLAY_STEP((__i915), (from), (until)))
#define DISPLAY_INFO(i915) (__to_intel_display(i915)->info.__device_info)
#define DISPLAY_RUNTIME_INFO(i915) (&__to_intel_display(i915)->info.__runtime_info)
#define DISPLAY_VER(i915) (DISPLAY_RUNTIME_INFO(i915)->ip.ver)
#define DISPLAY_VER_FULL(i915) IP_VER(DISPLAY_RUNTIME_INFO(i915)->ip.ver, \
DISPLAY_RUNTIME_INFO(i915)->ip.rel)
#define DISPLAY_VERx100(i915) (DISPLAY_RUNTIME_INFO(i915)->ip.ver * 100 + \
DISPLAY_RUNTIME_INFO(i915)->ip.rel)
#define IS_DISPLAY_VER(i915, from, until) \
(DISPLAY_VER(i915) >= (from) && DISPLAY_VER(i915) <= (until))
@ -206,9 +227,6 @@ enum intel_display_subplatform {
INTEL_DISPLAY_STEP(__i915) >= (since) && INTEL_DISPLAY_STEP(__i915) < (until))
struct intel_display_runtime_info {
enum intel_display_platform platform;
enum intel_display_subplatform subplatform;
struct intel_display_ip_ver {
u16 ver;
u16 rel;
@ -230,6 +248,8 @@ struct intel_display_runtime_info {
bool has_hdcp;
bool has_dmc;
bool has_dsc;
bool edp_typec_support;
bool has_dbuf_overlap_detection;
};
struct intel_display_device_info {

View File

@ -194,7 +194,7 @@ void intel_display_driver_early_probe(struct drm_i915_private *i915)
intel_display_irq_init(i915);
intel_dkl_phy_init(i915);
intel_color_init_hooks(i915);
intel_color_init_hooks(&i915->display);
intel_init_cdclk_hooks(&i915->display);
intel_audio_hooks_init(i915);
intel_dpll_init_clock_hook(i915);
@ -249,7 +249,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
if (ret)
goto cleanup_vga_client_pw_domain_dmc;
ret = intel_color_init(i915);
ret = intel_color_init(display);
if (ret)
goto cleanup_vga_client_pw_domain_dmc;
@ -432,7 +432,7 @@ int intel_display_driver_probe_nogem(struct drm_i915_private *i915)
intel_pps_setup(display);
intel_gmbus_setup(i915);
intel_gmbus_setup(display);
drm_dbg_kms(&i915->drm, "%d display pipe%s available.\n",
INTEL_NUM_PIPES(i915),
@ -485,7 +485,7 @@ int intel_display_driver_probe_nogem(struct drm_i915_private *i915)
return 0;
err_hdcp:
intel_hdcp_component_fini(i915);
intel_hdcp_component_fini(display);
err_mode_config:
intel_mode_config_cleanup(i915);
@ -495,6 +495,7 @@ int intel_display_driver_probe_nogem(struct drm_i915_private *i915)
/* part #3: call after gem init */
int intel_display_driver_probe(struct drm_i915_private *i915)
{
struct intel_display *display = &i915->display;
int ret;
if (!HAS_DISPLAY(i915))
@ -505,7 +506,7 @@ int intel_display_driver_probe(struct drm_i915_private *i915)
* the BIOS fb takeover and whatever else magic ggtt reservations
* happen during gem/ggtt init.
*/
intel_hdcp_component_init(i915);
intel_hdcp_component_init(display);
/*
* Force all active planes to recompute their states. So that on
@ -600,7 +601,7 @@ void intel_display_driver_remove_noirq(struct drm_i915_private *i915)
/* flush any delayed tasks or pending work */
flush_workqueue(i915->unordered_wq);
intel_hdcp_component_fini(i915);
intel_hdcp_component_fini(display);
intel_mode_config_cleanup(i915);
@ -608,7 +609,7 @@ void intel_display_driver_remove_noirq(struct drm_i915_private *i915)
intel_overlay_cleanup(i915);
intel_gmbus_teardown(i915);
intel_gmbus_teardown(display);
destroy_workqueue(i915->display.wq.flip);
destroy_workqueue(i915->display.wq.modeset);

View File

@ -543,12 +543,13 @@ void i965_pipestat_irq_handler(struct drm_i915_private *dev_priv,
intel_opregion_asle_intr(display);
if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS)
intel_gmbus_irq_handler(dev_priv);
intel_gmbus_irq_handler(display);
}
void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
u32 pipe_stats[I915_MAX_PIPES])
{
struct intel_display *display = &dev_priv->display;
enum pipe pipe;
for_each_pipe(dev_priv, pipe) {
@ -566,7 +567,7 @@ void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
}
if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS)
intel_gmbus_irq_handler(dev_priv);
intel_gmbus_irq_handler(display);
}
static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
@ -588,7 +589,7 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
intel_dp_aux_irq_handler(display);
if (pch_iir & SDE_GMBUS)
intel_gmbus_irq_handler(dev_priv);
intel_gmbus_irq_handler(display);
if (pch_iir & SDE_AUDIO_HDCP_MASK)
drm_dbg(&dev_priv->drm, "PCH HDCP audio interrupt\n");
@ -677,7 +678,7 @@ static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
intel_dp_aux_irq_handler(display);
if (pch_iir & SDE_GMBUS_CPT)
intel_gmbus_irq_handler(dev_priv);
intel_gmbus_irq_handler(display);
if (pch_iir & SDE_AUDIO_CP_REQ_CPT)
drm_dbg(&dev_priv->drm, "Audio CP request interrupt\n");
@ -902,6 +903,13 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
struct intel_display *display = &dev_priv->display;
bool found = false;
if (HAS_DBUF_OVERLAP_DETECTION(display)) {
if (iir & XE2LPD_DBUF_OVERLAP_DETECTED) {
drm_warn(display->drm, "DBuf overlap detected\n");
found = true;
}
}
if (DISPLAY_VER(dev_priv) >= 14) {
if (iir & (XELPDP_PMDEMAND_RSP |
XELPDP_PMDEMAND_RSPTOUT_ERR)) {
@ -1021,17 +1029,6 @@ static u32 gen8_de_pipe_flip_done_mask(struct drm_i915_private *i915)
return GEN8_PIPE_PRIMARY_FLIP_DONE;
}
u32 gen8_de_pipe_underrun_mask(struct drm_i915_private *dev_priv)
{
u32 mask = GEN8_PIPE_FIFO_UNDERRUN;
if (DISPLAY_VER(dev_priv) >= 13)
mask |= XELPD_PIPE_SOFT_UNDERRUN |
XELPD_PIPE_HARD_UNDERRUN;
return mask;
}
static void gen8_read_and_ack_pch_irqs(struct drm_i915_private *i915, u32 *pch_iir, u32 *pica_iir)
{
u32 pica_ier = 0;
@ -1120,7 +1117,7 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
(iir & BXT_DE_PORT_GMBUS)) {
intel_gmbus_irq_handler(dev_priv);
intel_gmbus_irq_handler(display);
found = true;
}
@ -1177,7 +1174,7 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
if (iir & GEN8_PIPE_CDCLK_CRC_DONE)
hsw_pipe_crc_irq_handler(dev_priv, pipe);
if (iir & gen8_de_pipe_underrun_mask(dev_priv))
if (iir & GEN8_PIPE_FIFO_UNDERRUN)
intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
fault_errors = iir & gen8_de_pipe_fault_mask(dev_priv);
@ -1424,7 +1421,7 @@ static void intel_display_vblank_dc_work(struct work_struct *work)
struct intel_display *display =
container_of(work, typeof(*display), irq.vblank_dc_work);
struct drm_i915_private *i915 = to_i915(display->drm);
u8 vblank_enabled = READ_ONCE(display->irq.vblank_enabled);
int vblank_wa_num_pipes = READ_ONCE(display->irq.vblank_wa_num_pipes);
/*
* NOTE: intel_display_power_set_target_dc_state is used only by PSR
@ -1432,7 +1429,7 @@ static void intel_display_vblank_dc_work(struct work_struct *work)
* PSR code. If DC3CO is taken into use we need take that into account
* here as well.
*/
intel_display_power_set_target_dc_state(i915, vblank_enabled ? DC_STATE_DISABLE :
intel_display_power_set_target_dc_state(i915, vblank_wa_num_pipes ? DC_STATE_DISABLE :
DC_STATE_EN_UPTO_DC6);
}
@ -1447,7 +1444,7 @@ int bdw_enable_vblank(struct drm_crtc *_crtc)
if (gen11_dsi_configure_te(crtc, true))
return 0;
if (display->irq.vblank_enabled++ == 0 && crtc->block_dc_for_vblank)
if (crtc->block_dc_for_vblank && display->irq.vblank_wa_num_pipes++ == 0)
schedule_work(&display->irq.vblank_dc_work);
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
@ -1478,7 +1475,7 @@ void bdw_disable_vblank(struct drm_crtc *_crtc)
bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
if (--display->irq.vblank_enabled == 0 && crtc->block_dc_for_vblank)
if (crtc->block_dc_for_vblank && --display->irq.vblank_wa_num_pipes == 0)
schedule_work(&display->irq.vblank_dc_work);
}
@ -1496,7 +1493,7 @@ void vlv_display_irq_reset(struct drm_i915_private *dev_priv)
i9xx_pipestat_irq_reset(dev_priv);
gen3_irq_reset(uncore, VLV_IRQ_REGS);
gen2_irq_reset(uncore, VLV_IRQ_REGS);
dev_priv->irq_mask = ~0u;
}
@ -1539,7 +1536,7 @@ void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv)
dev_priv->irq_mask = ~enable_mask;
gen3_irq_init(uncore, VLV_IRQ_REGS, dev_priv->irq_mask, enable_mask);
gen2_irq_init(uncore, VLV_IRQ_REGS, dev_priv->irq_mask, enable_mask);
}
void gen8_display_irq_reset(struct drm_i915_private *dev_priv)
@ -1556,10 +1553,10 @@ void gen8_display_irq_reset(struct drm_i915_private *dev_priv)
for_each_pipe(dev_priv, pipe)
if (intel_display_power_is_enabled(dev_priv,
POWER_DOMAIN_PIPE(pipe)))
gen3_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe));
gen2_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe));
gen3_irq_reset(uncore, GEN8_DE_PORT_IRQ_REGS);
gen3_irq_reset(uncore, GEN8_DE_MISC_IRQ_REGS);
gen2_irq_reset(uncore, GEN8_DE_PORT_IRQ_REGS);
gen2_irq_reset(uncore, GEN8_DE_MISC_IRQ_REGS);
}
void gen11_display_irq_reset(struct drm_i915_private *dev_priv)
@ -1599,26 +1596,25 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv)
for_each_pipe(dev_priv, pipe)
if (intel_display_power_is_enabled(dev_priv,
POWER_DOMAIN_PIPE(pipe)))
gen3_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe));
gen2_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe));
gen3_irq_reset(uncore, GEN8_DE_PORT_IRQ_REGS);
gen3_irq_reset(uncore, GEN8_DE_MISC_IRQ_REGS);
gen2_irq_reset(uncore, GEN8_DE_PORT_IRQ_REGS);
gen2_irq_reset(uncore, GEN8_DE_MISC_IRQ_REGS);
if (DISPLAY_VER(dev_priv) >= 14)
gen3_irq_reset(uncore, PICAINTERRUPT_IRQ_REGS);
gen2_irq_reset(uncore, PICAINTERRUPT_IRQ_REGS);
else
gen3_irq_reset(uncore, GEN11_DE_HPD_IRQ_REGS);
gen2_irq_reset(uncore, GEN11_DE_HPD_IRQ_REGS);
if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
gen3_irq_reset(uncore, SDE_IRQ_REGS);
gen2_irq_reset(uncore, SDE_IRQ_REGS);
}
void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
u8 pipe_mask)
{
struct intel_uncore *uncore = &dev_priv->uncore;
u32 extra_ier = GEN8_PIPE_VBLANK |
gen8_de_pipe_underrun_mask(dev_priv) |
u32 extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN |
gen8_de_pipe_flip_done_mask(dev_priv);
enum pipe pipe;
@ -1630,7 +1626,7 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
}
for_each_pipe_masked(dev_priv, pipe, pipe_mask)
gen3_irq_init(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe),
gen2_irq_init(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe),
dev_priv->display.irq.de_irq_mask[pipe],
~dev_priv->display.irq.de_irq_mask[pipe] | extra_ier);
@ -1651,7 +1647,7 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv,
}
for_each_pipe_masked(dev_priv, pipe, pipe_mask)
gen3_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe));
gen2_irq_reset(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe));
spin_unlock_irq(&dev_priv->irq_lock);
@ -1685,7 +1681,7 @@ static void ibx_irq_postinstall(struct drm_i915_private *dev_priv)
else
mask = SDE_GMBUS_CPT;
gen3_irq_init(uncore, SDE_IRQ_REGS, ~mask, 0xffffffff);
gen2_irq_init(uncore, SDE_IRQ_REGS, ~mask, 0xffffffff);
}
void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv)
@ -1742,7 +1738,7 @@ void ilk_de_irq_postinstall(struct drm_i915_private *i915)
}
if (IS_HASWELL(i915)) {
gen3_assert_iir_is_zero(uncore, EDP_PSR_IIR);
gen2_assert_iir_is_zero(uncore, EDP_PSR_IIR);
display_mask |= DE_EDP_PSR_INT_HSW;
}
@ -1753,7 +1749,7 @@ void ilk_de_irq_postinstall(struct drm_i915_private *i915)
ibx_irq_postinstall(i915);
gen3_irq_init(uncore, DE_IRQ_REGS, i915->irq_mask,
gen2_irq_init(uncore, DE_IRQ_REGS, i915->irq_mask,
display_mask | extra_mask);
}
@ -1801,14 +1797,16 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
de_port_masked |= DSI0_TE | DSI1_TE;
}
if (HAS_DBUF_OVERLAP_DETECTION(display))
de_misc_masked |= XE2LPD_DBUF_OVERLAP_DETECTED;
if (HAS_DSB(dev_priv))
de_pipe_masked |= GEN12_DSB_INT(INTEL_DSB_0) |
GEN12_DSB_INT(INTEL_DSB_1) |
GEN12_DSB_INT(INTEL_DSB_2);
de_pipe_enables = de_pipe_masked |
GEN8_PIPE_VBLANK |
gen8_de_pipe_underrun_mask(dev_priv) |
GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN |
gen8_de_pipe_flip_done_mask(dev_priv);
de_port_enables = de_port_masked;
@ -1827,11 +1825,11 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
if (!intel_display_power_is_enabled(dev_priv, domain))
continue;
gen3_assert_iir_is_zero(uncore,
gen2_assert_iir_is_zero(uncore,
TRANS_PSR_IIR(dev_priv, trans));
}
} else {
gen3_assert_iir_is_zero(uncore, EDP_PSR_IIR);
gen2_assert_iir_is_zero(uncore, EDP_PSR_IIR);
}
for_each_pipe(dev_priv, pipe) {
@ -1839,20 +1837,20 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
if (intel_display_power_is_enabled(dev_priv,
POWER_DOMAIN_PIPE(pipe)))
gen3_irq_init(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe),
gen2_irq_init(uncore, GEN8_DE_PIPE_IRQ_REGS(pipe),
dev_priv->display.irq.de_irq_mask[pipe],
de_pipe_enables);
}
gen3_irq_init(uncore, GEN8_DE_PORT_IRQ_REGS, ~de_port_masked, de_port_enables);
gen3_irq_init(uncore, GEN8_DE_MISC_IRQ_REGS, ~de_misc_masked, de_misc_masked);
gen2_irq_init(uncore, GEN8_DE_PORT_IRQ_REGS, ~de_port_masked, de_port_enables);
gen2_irq_init(uncore, GEN8_DE_MISC_IRQ_REGS, ~de_misc_masked, de_misc_masked);
if (IS_DISPLAY_VER(dev_priv, 11, 13)) {
u32 de_hpd_masked = 0;
u32 de_hpd_enables = GEN11_DE_TC_HOTPLUG_MASK |
GEN11_DE_TBT_HOTPLUG_MASK;
gen3_irq_init(uncore, GEN11_DE_HPD_IRQ_REGS, ~de_hpd_masked,
gen2_irq_init(uncore, GEN11_DE_HPD_IRQ_REGS, ~de_hpd_masked,
de_hpd_enables);
}
}
@ -1865,10 +1863,10 @@ static void mtp_irq_postinstall(struct drm_i915_private *i915)
u32 de_hpd_enables = de_hpd_mask | XELPDP_DP_ALT_HOTPLUG_MASK |
XELPDP_TBT_HOTPLUG_MASK;
gen3_irq_init(uncore, PICAINTERRUPT_IRQ_REGS, ~de_hpd_mask,
gen2_irq_init(uncore, PICAINTERRUPT_IRQ_REGS, ~de_hpd_mask,
de_hpd_enables);
gen3_irq_init(uncore, SDE_IRQ_REGS, ~sde_mask, 0xffffffff);
gen2_irq_init(uncore, SDE_IRQ_REGS, ~sde_mask, 0xffffffff);
}
static void icp_irq_postinstall(struct drm_i915_private *dev_priv)
@ -1876,7 +1874,7 @@ static void icp_irq_postinstall(struct drm_i915_private *dev_priv)
struct intel_uncore *uncore = &dev_priv->uncore;
u32 mask = SDE_GMBUS_ICP;
gen3_irq_init(uncore, SDE_IRQ_REGS, ~mask, 0xffffffff);
gen2_irq_init(uncore, SDE_IRQ_REGS, ~mask, 0xffffffff);
}
void gen11_de_irq_postinstall(struct drm_i915_private *dev_priv)

View File

@ -33,7 +33,6 @@ void ibx_disable_display_interrupt(struct drm_i915_private *i915, u32 bits);
void gen8_irq_power_well_post_enable(struct drm_i915_private *i915, u8 pipe_mask);
void gen8_irq_power_well_pre_disable(struct drm_i915_private *i915, u8 pipe_mask);
u32 gen8_de_pipe_underrun_mask(struct drm_i915_private *i915);
int i8xx_enable_vblank(struct drm_crtc *crtc);
int i915gm_enable_vblank(struct drm_crtc *crtc);

View File

@ -1176,43 +1176,44 @@ static void hsw_assert_cdclk(struct drm_i915_private *dev_priv)
static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
{
struct intel_display *display = &dev_priv->display;
struct intel_crtc *crtc;
for_each_intel_crtc(&dev_priv->drm, crtc)
I915_STATE_WARN(dev_priv, crtc->active,
"CRTC for pipe %c enabled\n",
pipe_name(crtc->pipe));
for_each_intel_crtc(display->drm, crtc)
INTEL_DISPLAY_STATE_WARN(display, crtc->active,
"CRTC for pipe %c enabled\n",
pipe_name(crtc->pipe));
I915_STATE_WARN(dev_priv, intel_de_read(dev_priv, HSW_PWR_WELL_CTL2),
"Display power well on\n");
I915_STATE_WARN(dev_priv,
intel_de_read(dev_priv, SPLL_CTL) & SPLL_PLL_ENABLE,
"SPLL enabled\n");
I915_STATE_WARN(dev_priv,
intel_de_read(dev_priv, WRPLL_CTL(0)) & WRPLL_PLL_ENABLE,
"WRPLL1 enabled\n");
I915_STATE_WARN(dev_priv,
intel_de_read(dev_priv, WRPLL_CTL(1)) & WRPLL_PLL_ENABLE,
"WRPLL2 enabled\n");
I915_STATE_WARN(dev_priv,
intel_de_read(dev_priv, PP_STATUS(dev_priv, 0)) & PP_ON,
"Panel power on\n");
I915_STATE_WARN(dev_priv,
intel_de_read(dev_priv, BLC_PWM_CPU_CTL2) & BLM_PWM_ENABLE,
"CPU PWM1 enabled\n");
INTEL_DISPLAY_STATE_WARN(display, intel_de_read(display, HSW_PWR_WELL_CTL2),
"Display power well on\n");
INTEL_DISPLAY_STATE_WARN(display,
intel_de_read(display, SPLL_CTL) & SPLL_PLL_ENABLE,
"SPLL enabled\n");
INTEL_DISPLAY_STATE_WARN(display,
intel_de_read(display, WRPLL_CTL(0)) & WRPLL_PLL_ENABLE,
"WRPLL1 enabled\n");
INTEL_DISPLAY_STATE_WARN(display,
intel_de_read(display, WRPLL_CTL(1)) & WRPLL_PLL_ENABLE,
"WRPLL2 enabled\n");
INTEL_DISPLAY_STATE_WARN(display,
intel_de_read(display, PP_STATUS(display, 0)) & PP_ON,
"Panel power on\n");
INTEL_DISPLAY_STATE_WARN(display,
intel_de_read(display, BLC_PWM_CPU_CTL2) & BLM_PWM_ENABLE,
"CPU PWM1 enabled\n");
if (IS_HASWELL(dev_priv))
I915_STATE_WARN(dev_priv,
intel_de_read(dev_priv, HSW_BLC_PWM2_CTL) & BLM_PWM_ENABLE,
"CPU PWM2 enabled\n");
I915_STATE_WARN(dev_priv,
intel_de_read(dev_priv, BLC_PWM_PCH_CTL1) & BLM_PCH_PWM_ENABLE,
"PCH PWM1 enabled\n");
I915_STATE_WARN(dev_priv,
(intel_de_read(dev_priv, UTIL_PIN_CTL) & (UTIL_PIN_ENABLE | UTIL_PIN_MODE_MASK)) == (UTIL_PIN_ENABLE | UTIL_PIN_MODE_PWM),
"Utility pin enabled in PWM mode\n");
I915_STATE_WARN(dev_priv,
intel_de_read(dev_priv, PCH_GTC_CTL) & PCH_GTC_ENABLE,
"PCH GTC enabled\n");
INTEL_DISPLAY_STATE_WARN(display,
intel_de_read(display, HSW_BLC_PWM2_CTL) & BLM_PWM_ENABLE,
"CPU PWM2 enabled\n");
INTEL_DISPLAY_STATE_WARN(display,
intel_de_read(display, BLC_PWM_PCH_CTL1) & BLM_PCH_PWM_ENABLE,
"PCH PWM1 enabled\n");
INTEL_DISPLAY_STATE_WARN(display,
(intel_de_read(display, UTIL_PIN_CTL) & (UTIL_PIN_ENABLE | UTIL_PIN_MODE_MASK)) == (UTIL_PIN_ENABLE | UTIL_PIN_MODE_PWM),
"Utility pin enabled in PWM mode\n");
INTEL_DISPLAY_STATE_WARN(display,
intel_de_read(display, PCH_GTC_CTL) & PCH_GTC_ENABLE,
"PCH GTC enabled\n");
/*
* In theory we can still leave IRQs enabled, as long as only the HPD
@ -1220,8 +1221,8 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
* gen-specific and since we only disable LCPLL after we fully disable
* the interrupts, the check below should be enough.
*/
I915_STATE_WARN(dev_priv, intel_irqs_enabled(dev_priv),
"IRQs enabled\n");
INTEL_DISPLAY_STATE_WARN(display, intel_irqs_enabled(dev_priv),
"IRQs enabled\n");
}
static u32 hsw_read_dcomp(struct drm_i915_private *dev_priv)
@ -1683,14 +1684,14 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
intel_snps_phy_wait_for_calibration(dev_priv);
/* 9. XE2_HPD: Program CHICKEN_MISC_2 before any cursor or planes are enabled */
if (DISPLAY_VER_FULL(dev_priv) == IP_VER(14, 1))
if (DISPLAY_VERx100(dev_priv) == 1401)
intel_de_rmw(dev_priv, CHICKEN_MISC_2, BMG_DARB_HALF_BLK_END_BURST, 1);
if (resume)
intel_dmc_load_program(display);
/* Wa_14011508470:tgl,dg1,rkl,adl-s,adl-p,dg2 */
if (IS_DISPLAY_VER_FULL(dev_priv, IP_VER(12, 0), IP_VER(13, 0)))
if (IS_DISPLAY_VERx100(dev_priv, 1200, 1300))
intel_de_rmw(dev_priv, GEN11_CHICKEN_DCPR_2, 0,
DCPR_CLEAR_MEMSTAT_DIS | DCPR_SEND_RESP_IMM |
DCPR_MASK_LPMODE | DCPR_MASK_MAXLATENCY_MEMUP_CLR);

View File

@ -1586,6 +1586,136 @@ static const struct i915_power_well_desc_list xe2lpd_power_wells[] = {
I915_PW_DESCRIPTORS(xe2lpd_power_wells_pica),
};
/*
* Xe3 changes the power well hierarchy slightly from Xe_LPD+; PGB now
* depends on PG1 instead of PG2:
*
* PG0
* |
* --PG1--
* / | \
* PGA PGB PG2
* / \
* PGC PGD
*/
#define XE3LPD_PW_C_POWER_DOMAINS \
POWER_DOMAIN_PIPE_C, \
POWER_DOMAIN_PIPE_PANEL_FITTER_C
#define XE3LPD_PW_D_POWER_DOMAINS \
POWER_DOMAIN_PIPE_D, \
POWER_DOMAIN_PIPE_PANEL_FITTER_D
#define XE3LPD_PW_2_POWER_DOMAINS \
XE3LPD_PW_C_POWER_DOMAINS, \
XE3LPD_PW_D_POWER_DOMAINS, \
POWER_DOMAIN_TRANSCODER_C, \
POWER_DOMAIN_TRANSCODER_D, \
POWER_DOMAIN_VGA, \
POWER_DOMAIN_PORT_DDI_LANES_TC1, \
POWER_DOMAIN_PORT_DDI_LANES_TC2, \
POWER_DOMAIN_PORT_DDI_LANES_TC3, \
POWER_DOMAIN_PORT_DDI_LANES_TC4
I915_DECL_PW_DOMAINS(xe3lpd_pwdoms_pw_2,
XE3LPD_PW_2_POWER_DOMAINS,
POWER_DOMAIN_INIT);
I915_DECL_PW_DOMAINS(xe3lpd_pwdoms_pw_b,
POWER_DOMAIN_PIPE_B,
POWER_DOMAIN_PIPE_PANEL_FITTER_B,
POWER_DOMAIN_INIT);
I915_DECL_PW_DOMAINS(xe3lpd_pwdoms_pw_c,
XE3LPD_PW_C_POWER_DOMAINS,
POWER_DOMAIN_INIT);
I915_DECL_PW_DOMAINS(xe3lpd_pwdoms_pw_d,
XE3LPD_PW_D_POWER_DOMAINS,
POWER_DOMAIN_INIT);
static const struct i915_power_well_desc xe3lpd_power_wells_main[] = {
{
.instances = &I915_PW_INSTANCES(
I915_PW("PW_2", &xe3lpd_pwdoms_pw_2,
.hsw.idx = ICL_PW_CTL_IDX_PW_2,
.id = SKL_DISP_PW_2),
),
.ops = &hsw_power_well_ops,
.has_vga = true,
.has_fuses = true,
}, {
.instances = &I915_PW_INSTANCES(
I915_PW("PW_A", &xelpd_pwdoms_pw_a,
.hsw.idx = XELPD_PW_CTL_IDX_PW_A),
),
.ops = &hsw_power_well_ops,
.irq_pipe_mask = BIT(PIPE_A),
.has_fuses = true,
}, {
.instances = &I915_PW_INSTANCES(
I915_PW("PW_B", &xe3lpd_pwdoms_pw_b,
.hsw.idx = XELPD_PW_CTL_IDX_PW_B),
),
.ops = &hsw_power_well_ops,
.irq_pipe_mask = BIT(PIPE_B),
.has_fuses = true,
}, {
.instances = &I915_PW_INSTANCES(
I915_PW("PW_C", &xe3lpd_pwdoms_pw_c,
.hsw.idx = XELPD_PW_CTL_IDX_PW_C),
),
.ops = &hsw_power_well_ops,
.irq_pipe_mask = BIT(PIPE_C),
.has_fuses = true,
}, {
.instances = &I915_PW_INSTANCES(
I915_PW("PW_D", &xe3lpd_pwdoms_pw_d,
.hsw.idx = XELPD_PW_CTL_IDX_PW_D),
),
.ops = &hsw_power_well_ops,
.irq_pipe_mask = BIT(PIPE_D),
.has_fuses = true,
}, {
.instances = &I915_PW_INSTANCES(
I915_PW("AUX_A", &icl_pwdoms_aux_a, .xelpdp.aux_ch = AUX_CH_A),
I915_PW("AUX_B", &icl_pwdoms_aux_b, .xelpdp.aux_ch = AUX_CH_B),
I915_PW("AUX_TC1", &xelpdp_pwdoms_aux_tc1, .xelpdp.aux_ch = AUX_CH_USBC1),
I915_PW("AUX_TC2", &xelpdp_pwdoms_aux_tc2, .xelpdp.aux_ch = AUX_CH_USBC2),
I915_PW("AUX_TC3", &xelpdp_pwdoms_aux_tc3, .xelpdp.aux_ch = AUX_CH_USBC3),
I915_PW("AUX_TC4", &xelpdp_pwdoms_aux_tc4, .xelpdp.aux_ch = AUX_CH_USBC4),
),
.ops = &xelpdp_aux_power_well_ops,
},
};
I915_DECL_PW_DOMAINS(xe3lpd_pwdoms_dc_off,
POWER_DOMAIN_DC_OFF,
XE3LPD_PW_2_POWER_DOMAINS,
XE3LPD_PW_C_POWER_DOMAINS,
XE3LPD_PW_D_POWER_DOMAINS,
POWER_DOMAIN_AUDIO_MMIO,
POWER_DOMAIN_INIT);
static const struct i915_power_well_desc xe3lpd_power_wells_dcoff[] = {
{
.instances = &I915_PW_INSTANCES(
I915_PW("DC_off", &xe3lpd_pwdoms_dc_off,
.id = SKL_DISP_DC_OFF),
),
.ops = &gen9_dc_off_power_well_ops,
},
};
static const struct i915_power_well_desc_list xe3lpd_power_wells[] = {
I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
I915_PW_DESCRIPTORS(icl_power_wells_pw_1),
I915_PW_DESCRIPTORS(xe3lpd_power_wells_dcoff),
I915_PW_DESCRIPTORS(xe3lpd_power_wells_main),
I915_PW_DESCRIPTORS(xe2lpd_power_wells_pica),
};
static void init_power_well_domains(const struct i915_power_well_instance *inst,
struct i915_power_well *power_well)
{
@ -1693,7 +1823,9 @@ int intel_display_power_map_init(struct i915_power_domains *power_domains)
return 0;
}
if (DISPLAY_VER(i915) >= 20)
if (DISPLAY_VER(i915) >= 30)
return set_power_wells(power_domains, xe3lpd_power_wells);
else if (DISPLAY_VER(i915) >= 20)
return set_power_wells(power_domains, xe2lpd_power_wells);
else if (DISPLAY_VER(i915) >= 14)
return set_power_wells(power_domains, xelpdp_power_wells);

View File

@ -919,38 +919,45 @@ static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
static void bxt_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
bxt_dpio_phy_init(dev_priv, i915_power_well_instance(power_well)->bxt.phy);
struct intel_display *display = &dev_priv->display;
bxt_dpio_phy_init(display, i915_power_well_instance(power_well)->bxt.phy);
}
static void bxt_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
bxt_dpio_phy_uninit(dev_priv, i915_power_well_instance(power_well)->bxt.phy);
struct intel_display *display = &dev_priv->display;
bxt_dpio_phy_uninit(display, i915_power_well_instance(power_well)->bxt.phy);
}
static bool bxt_dpio_cmn_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
return bxt_dpio_phy_is_enabled(dev_priv, i915_power_well_instance(power_well)->bxt.phy);
struct intel_display *display = &dev_priv->display;
return bxt_dpio_phy_is_enabled(display, i915_power_well_instance(power_well)->bxt.phy);
}
static void bxt_verify_dpio_phy_power_wells(struct drm_i915_private *dev_priv)
{
struct intel_display *display = &dev_priv->display;
struct i915_power_well *power_well;
power_well = lookup_power_well(dev_priv, BXT_DISP_PW_DPIO_CMN_A);
if (intel_power_well_refcount(power_well) > 0)
bxt_dpio_phy_verify_state(dev_priv, i915_power_well_instance(power_well)->bxt.phy);
bxt_dpio_phy_verify_state(display, i915_power_well_instance(power_well)->bxt.phy);
power_well = lookup_power_well(dev_priv, VLV_DISP_PW_DPIO_CMN_BC);
if (intel_power_well_refcount(power_well) > 0)
bxt_dpio_phy_verify_state(dev_priv, i915_power_well_instance(power_well)->bxt.phy);
bxt_dpio_phy_verify_state(display, i915_power_well_instance(power_well)->bxt.phy);
if (IS_GEMINILAKE(dev_priv)) {
power_well = lookup_power_well(dev_priv,
GLK_DISP_PW_DPIO_CMN_C);
if (intel_power_well_refcount(power_well) > 0)
bxt_dpio_phy_verify_state(dev_priv,
bxt_dpio_phy_verify_state(display,
i915_power_well_instance(power_well)->bxt.phy);
}
}
@ -1330,13 +1337,14 @@ static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
#define BITS_SET(val, bits) (((val) & (bits)) == (bits))
static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
static void assert_chv_phy_status(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct i915_power_well *cmn_bc =
lookup_power_well(dev_priv, VLV_DISP_PW_DPIO_CMN_BC);
struct i915_power_well *cmn_d =
lookup_power_well(dev_priv, CHV_DISP_PW_DPIO_CMN_D);
u32 phy_control = dev_priv->display.power.chv_phy_control;
u32 phy_control = display->power.chv_phy_control;
u32 phy_status = 0;
u32 phy_status_mask = 0xffffffff;
@ -1347,7 +1355,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
* reset (ie. the power well has been disabled at
* least once).
*/
if (!dev_priv->display.power.chv_phy_assert[DPIO_PHY0])
if (!display->power.chv_phy_assert[DPIO_PHY0])
phy_status_mask &= ~(PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH0) |
PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH0, 0) |
PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH0, 1) |
@ -1355,7 +1363,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 0) |
PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 1));
if (!dev_priv->display.power.chv_phy_assert[DPIO_PHY1])
if (!display->power.chv_phy_assert[DPIO_PHY1])
phy_status_mask &= ~(PHY_STATUS_CMN_LDO(DPIO_PHY1, DPIO_CH0) |
PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 0) |
PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 1));
@ -1383,7 +1391,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
*/
if (BITS_SET(phy_control,
PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH1)) &&
(intel_de_read(dev_priv, DPLL(dev_priv, PIPE_B)) & DPLL_VCO_ENABLE) == 0)
(intel_de_read(display, DPLL(display, PIPE_B)) & DPLL_VCO_ENABLE) == 0)
phy_status |= PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH1);
if (BITS_SET(phy_control,
@ -1426,12 +1434,12 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
* The PHY may be busy with some initial calibration and whatnot,
* so the power state can take a while to actually change.
*/
if (intel_de_wait(dev_priv, DISPLAY_PHY_STATUS,
if (intel_de_wait(display, DISPLAY_PHY_STATUS,
phy_status_mask, phy_status, 10))
drm_err(&dev_priv->drm,
drm_err(display->drm,
"Unexpected PHY_STATUS 0x%08x, expected 0x%08x (PHY_CONTROL=0x%08x)\n",
intel_de_read(dev_priv, DISPLAY_PHY_STATUS) & phy_status_mask,
phy_status, dev_priv->display.power.chv_phy_control);
intel_de_read(display, DISPLAY_PHY_STATUS) & phy_status_mask,
phy_status, display->power.chv_phy_control);
}
#undef BITS_SET
@ -1439,11 +1447,12 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
struct intel_display *display = &dev_priv->display;
enum i915_power_well_id id = i915_power_well_instance(power_well)->id;
enum dpio_phy phy;
u32 tmp;
drm_WARN_ON_ONCE(&dev_priv->drm,
drm_WARN_ON_ONCE(display->drm,
id != VLV_DISP_PW_DPIO_CMN_BC &&
id != CHV_DISP_PW_DPIO_CMN_D);
@ -1457,9 +1466,9 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
vlv_set_power_well(dev_priv, power_well, true);
/* Poll for phypwrgood signal */
if (intel_de_wait_for_set(dev_priv, DISPLAY_PHY_STATUS,
if (intel_de_wait_for_set(display, DISPLAY_PHY_STATUS,
PHY_POWERGOOD(phy), 1))
drm_err(&dev_priv->drm, "Display PHY %d is not power up\n",
drm_err(display->drm, "Display PHY %d is not power up\n",
phy);
vlv_dpio_get(dev_priv);
@ -1487,24 +1496,25 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
vlv_dpio_put(dev_priv);
dev_priv->display.power.chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(phy);
intel_de_write(dev_priv, DISPLAY_PHY_CONTROL,
dev_priv->display.power.chv_phy_control);
display->power.chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(phy);
intel_de_write(display, DISPLAY_PHY_CONTROL,
display->power.chv_phy_control);
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"Enabled DPIO PHY%d (PHY_CONTROL=0x%08x)\n",
phy, dev_priv->display.power.chv_phy_control);
phy, display->power.chv_phy_control);
assert_chv_phy_status(dev_priv);
assert_chv_phy_status(display);
}
static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
struct intel_display *display = &dev_priv->display;
enum i915_power_well_id id = i915_power_well_instance(power_well)->id;
enum dpio_phy phy;
drm_WARN_ON_ONCE(&dev_priv->drm,
drm_WARN_ON_ONCE(display->drm,
id != VLV_DISP_PW_DPIO_CMN_BC &&
id != CHV_DISP_PW_DPIO_CMN_D);
@ -1517,20 +1527,20 @@ static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
assert_pll_disabled(dev_priv, PIPE_C);
}
dev_priv->display.power.chv_phy_control &= ~PHY_COM_LANE_RESET_DEASSERT(phy);
intel_de_write(dev_priv, DISPLAY_PHY_CONTROL,
dev_priv->display.power.chv_phy_control);
display->power.chv_phy_control &= ~PHY_COM_LANE_RESET_DEASSERT(phy);
intel_de_write(display, DISPLAY_PHY_CONTROL,
display->power.chv_phy_control);
vlv_set_power_well(dev_priv, power_well, false);
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"Disabled DPIO PHY%d (PHY_CONTROL=0x%08x)\n",
phy, dev_priv->display.power.chv_phy_control);
phy, display->power.chv_phy_control);
/* PHY is fully reset now, so we can enable the PHY state asserts */
dev_priv->display.power.chv_phy_assert[phy] = true;
display->power.chv_phy_assert[phy] = true;
assert_chv_phy_status(dev_priv);
assert_chv_phy_status(display);
}
static void assert_chv_phy_powergate(struct drm_i915_private *dev_priv, enum dpio_phy phy,
@ -1600,29 +1610,30 @@ static void assert_chv_phy_powergate(struct drm_i915_private *dev_priv, enum dpi
bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
enum dpio_channel ch, bool override)
{
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
struct intel_display *display = &dev_priv->display;
struct i915_power_domains *power_domains = &display->power.domains;
bool was_override;
mutex_lock(&power_domains->lock);
was_override = dev_priv->display.power.chv_phy_control & PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
was_override = display->power.chv_phy_control & PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
if (override == was_override)
goto out;
if (override)
dev_priv->display.power.chv_phy_control |= PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
display->power.chv_phy_control |= PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
else
dev_priv->display.power.chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
display->power.chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
intel_de_write(dev_priv, DISPLAY_PHY_CONTROL,
dev_priv->display.power.chv_phy_control);
intel_de_write(display, DISPLAY_PHY_CONTROL,
display->power.chv_phy_control);
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"Power gating DPIO PHY%d CH%d (DPIO_PHY_CONTROL=0x%08x)\n",
phy, ch, dev_priv->display.power.chv_phy_control);
phy, ch, display->power.chv_phy_control);
assert_chv_phy_status(dev_priv);
assert_chv_phy_status(display);
out:
mutex_unlock(&power_domains->lock);
@ -1633,29 +1644,30 @@ bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
void chv_phy_powergate_lanes(struct intel_encoder *encoder,
bool override, unsigned int mask)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
struct i915_power_domains *power_domains = &display->power.domains;
enum dpio_phy phy = vlv_dig_port_to_phy(enc_to_dig_port(encoder));
enum dpio_channel ch = vlv_dig_port_to_channel(enc_to_dig_port(encoder));
mutex_lock(&power_domains->lock);
dev_priv->display.power.chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD(0xf, phy, ch);
dev_priv->display.power.chv_phy_control |= PHY_CH_POWER_DOWN_OVRD(mask, phy, ch);
display->power.chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD(0xf, phy, ch);
display->power.chv_phy_control |= PHY_CH_POWER_DOWN_OVRD(mask, phy, ch);
if (override)
dev_priv->display.power.chv_phy_control |= PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
display->power.chv_phy_control |= PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
else
dev_priv->display.power.chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
display->power.chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
intel_de_write(dev_priv, DISPLAY_PHY_CONTROL,
dev_priv->display.power.chv_phy_control);
intel_de_write(display, DISPLAY_PHY_CONTROL,
display->power.chv_phy_control);
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"Power gating DPIO PHY%d CH%d lanes 0x%x (PHY_CONTROL=0x%08x)\n",
phy, ch, mask, dev_priv->display.power.chv_phy_control);
phy, ch, mask, display->power.chv_phy_control);
assert_chv_phy_status(dev_priv);
assert_chv_phy_status(display);
assert_chv_phy_powergate(dev_priv, phy, ch, override, mask);

View File

@ -9,44 +9,85 @@
#if !defined(__INTEL_DISPLAY_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ)
#define __INTEL_DISPLAY_TRACE_H__
#include <linux/string.h>
#include <linux/string_helpers.h>
#include <linux/types.h>
#include <linux/tracepoint.h>
#include "i915_drv.h"
#include "intel_crtc.h"
#include "intel_display_limits.h"
#include "intel_display_types.h"
#include "intel_vblank.h"
#define __dev_name_display(display) dev_name((display)->drm->dev)
#define __dev_name_kms(obj) dev_name((obj)->base.dev->dev)
/*
* Using identifiers from enum pipe in TP_printk() will confuse tools that
* parse /sys/kernel/debug/tracing/{xe,i915}/<event>/format. So we use CPP
* macros instead.
*/
#define _TRACE_PIPE_A 0
#define _TRACE_PIPE_B 1
#define _TRACE_PIPE_C 2
#define _TRACE_PIPE_D 3
/*
* FIXME: Several TP_printk() calls below display frame and scanline numbers for
* all possible pipes (regardless of whether they are available) and that is
* done with a constant format string. A better approach would be to generate
* that info dynamically based on available pipes, but, while we do not have
* that implemented yet, let's assert that the constant format string indeed
* covers all possible pipes.
*/
static_assert(I915_MAX_PIPES - 1 == _TRACE_PIPE_D);
#define _PIPES_FRAME_AND_SCANLINE_FMT \
"pipe A: frame=%u, scanline=%u" \
", pipe B: frame=%u, scanline=%u" \
", pipe C: frame=%u, scanline=%u" \
", pipe D: frame=%u, scanline=%u"
#define _PIPES_FRAME_AND_SCANLINE_VALUES \
__entry->frame[_TRACE_PIPE_A], __entry->scanline[_TRACE_PIPE_A] \
, __entry->frame[_TRACE_PIPE_B], __entry->scanline[_TRACE_PIPE_B] \
, __entry->frame[_TRACE_PIPE_C], __entry->scanline[_TRACE_PIPE_C] \
, __entry->frame[_TRACE_PIPE_D], __entry->scanline[_TRACE_PIPE_D]
/*
* Paranoid sanity check that at least the enumeration starts at the
* same value as _TRACE_PIPE_A.
*/
static_assert(PIPE_A == _TRACE_PIPE_A);
TRACE_EVENT(intel_pipe_enable,
TP_PROTO(struct intel_crtc *crtc),
TP_ARGS(crtc),
TP_STRUCT__entry(
__string(dev, __dev_name_kms(crtc))
__array(u32, frame, 3)
__array(u32, scanline, 3)
__field(enum pipe, pipe)
__array(u32, frame, I915_MAX_PIPES)
__array(u32, scanline, I915_MAX_PIPES)
__field(char, pipe_name)
),
TP_fast_assign(
struct intel_display *display = to_intel_display(crtc);
struct intel_crtc *it__;
__assign_str(dev);
memset(__entry->frame, 0,
sizeof(__entry->frame[0]) * I915_MAX_PIPES);
memset(__entry->scanline, 0,
sizeof(__entry->scanline[0]) * I915_MAX_PIPES);
for_each_intel_crtc(display->drm, it__) {
__entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__);
__entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__);
}
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
),
TP_printk("dev %s, pipe %c enable, pipe A: frame=%u, scanline=%u, pipe B: frame=%u, scanline=%u, pipe C: frame=%u, scanline=%u",
__get_str(dev), pipe_name(__entry->pipe),
__entry->frame[PIPE_A], __entry->scanline[PIPE_A],
__entry->frame[PIPE_B], __entry->scanline[PIPE_B],
__entry->frame[PIPE_C], __entry->scanline[PIPE_C])
TP_printk("dev %s, pipe %c enable, " _PIPES_FRAME_AND_SCANLINE_FMT,
__get_str(dev), __entry->pipe_name, _PIPES_FRAME_AND_SCANLINE_VALUES)
);
TRACE_EVENT(intel_pipe_disable,
@ -55,27 +96,28 @@ TRACE_EVENT(intel_pipe_disable,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(crtc))
__array(u32, frame, 3)
__array(u32, scanline, 3)
__field(enum pipe, pipe)
__array(u32, frame, I915_MAX_PIPES)
__array(u32, scanline, I915_MAX_PIPES)
__field(char, pipe_name)
),
TP_fast_assign(
struct intel_display *display = to_intel_display(crtc);
struct intel_crtc *it__;
__assign_str(dev);
memset(__entry->frame, 0,
sizeof(__entry->frame[0]) * I915_MAX_PIPES);
memset(__entry->scanline, 0,
sizeof(__entry->scanline[0]) * I915_MAX_PIPES);
for_each_intel_crtc(display->drm, it__) {
__entry->frame[it__->pipe] = intel_crtc_get_vblank_counter(it__);
__entry->scanline[it__->pipe] = intel_get_crtc_scanline(it__);
}
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
),
TP_printk("dev %s, pipe %c disable, pipe A: frame=%u, scanline=%u, pipe B: frame=%u, scanline=%u, pipe C: frame=%u, scanline=%u",
__get_str(dev), pipe_name(__entry->pipe),
__entry->frame[PIPE_A], __entry->scanline[PIPE_A],
__entry->frame[PIPE_B], __entry->scanline[PIPE_B],
__entry->frame[PIPE_C], __entry->scanline[PIPE_C])
TP_printk("dev %s, pipe %c disable, " _PIPES_FRAME_AND_SCANLINE_FMT,
__get_str(dev), __entry->pipe_name, _PIPES_FRAME_AND_SCANLINE_VALUES)
);
TRACE_EVENT(intel_crtc_flip_done,
@ -84,20 +126,20 @@ TRACE_EVENT(intel_crtc_flip_done,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(crtc))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
),
TP_fast_assign(
__assign_str(dev);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
),
TP_printk("dev %s, pipe %c, frame=%u, scanline=%u",
__get_str(dev), pipe_name(__entry->pipe),
__get_str(dev), __entry->pipe_name,
__entry->frame, __entry->scanline)
);
@ -107,7 +149,7 @@ TRACE_EVENT(intel_pipe_crc,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(crtc))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
__array(u32, crcs, 5)
@ -115,14 +157,14 @@ TRACE_EVENT(intel_pipe_crc,
TP_fast_assign(
__assign_str(dev);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
memcpy(__entry->crcs, crcs, sizeof(__entry->crcs));
),
TP_printk("dev %s, pipe %c, frame=%u, scanline=%u crc=%08x %08x %08x %08x %08x",
__get_str(dev), pipe_name(__entry->pipe),
__get_str(dev), __entry->pipe_name,
__entry->frame, __entry->scanline,
__entry->crcs[0], __entry->crcs[1],
__entry->crcs[2], __entry->crcs[3],
@ -135,7 +177,7 @@ TRACE_EVENT(intel_cpu_fifo_underrun,
TP_STRUCT__entry(
__string(dev, __dev_name_display(display))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
),
@ -143,13 +185,13 @@ TRACE_EVENT(intel_cpu_fifo_underrun,
TP_fast_assign(
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
__assign_str(dev);
__entry->pipe = pipe;
__entry->pipe_name = pipe_name(pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
),
TP_printk("dev %s, pipe %c, frame=%u, scanline=%u",
__get_str(dev), pipe_name(__entry->pipe),
__get_str(dev), __entry->pipe_name,
__entry->frame, __entry->scanline)
);
@ -159,7 +201,7 @@ TRACE_EVENT(intel_pch_fifo_underrun,
TP_STRUCT__entry(
__string(dev, __dev_name_display(display))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
),
@ -168,13 +210,13 @@ TRACE_EVENT(intel_pch_fifo_underrun,
enum pipe pipe = pch_transcoder;
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
__assign_str(dev);
__entry->pipe = pipe;
__entry->pipe_name = pipe_name(pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
),
TP_printk("dev %s, pch transcoder %c, frame=%u, scanline=%u",
__get_str(dev), pipe_name(__entry->pipe),
__get_str(dev), __entry->pipe_name,
__entry->frame, __entry->scanline)
);
@ -184,8 +226,8 @@ TRACE_EVENT(intel_memory_cxsr,
TP_STRUCT__entry(
__string(dev, __dev_name_display(display))
__array(u32, frame, 3)
__array(u32, scanline, 3)
__array(u32, frame, I915_MAX_PIPES)
__array(u32, scanline, I915_MAX_PIPES)
__field(bool, old)
__field(bool, new)
),
@ -193,6 +235,10 @@ TRACE_EVENT(intel_memory_cxsr,
TP_fast_assign(
struct intel_crtc *crtc;
__assign_str(dev);
memset(__entry->frame, 0,
sizeof(__entry->frame[0]) * I915_MAX_PIPES);
memset(__entry->scanline, 0,
sizeof(__entry->scanline[0]) * I915_MAX_PIPES);
for_each_intel_crtc(display->drm, crtc) {
__entry->frame[crtc->pipe] = intel_crtc_get_vblank_counter(crtc);
__entry->scanline[crtc->pipe] = intel_get_crtc_scanline(crtc);
@ -201,11 +247,9 @@ TRACE_EVENT(intel_memory_cxsr,
__entry->new = new;
),
TP_printk("dev %s, cxsr %s->%s, pipe A: frame=%u, scanline=%u, pipe B: frame=%u, scanline=%u, pipe C: frame=%u, scanline=%u",
TP_printk("dev %s, cxsr %s->%s, " _PIPES_FRAME_AND_SCANLINE_FMT,
__get_str(dev), str_on_off(__entry->old), str_on_off(__entry->new),
__entry->frame[PIPE_A], __entry->scanline[PIPE_A],
__entry->frame[PIPE_B], __entry->scanline[PIPE_B],
__entry->frame[PIPE_C], __entry->scanline[PIPE_C])
_PIPES_FRAME_AND_SCANLINE_VALUES)
);
TRACE_EVENT(g4x_wm,
@ -214,7 +258,7 @@ TRACE_EVENT(g4x_wm,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(crtc))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
__field(u16, primary)
@ -233,7 +277,7 @@ TRACE_EVENT(g4x_wm,
TP_fast_assign(
__assign_str(dev);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
__entry->primary = wm->pipe[crtc->pipe].plane[PLANE_PRIMARY];
@ -251,7 +295,7 @@ TRACE_EVENT(g4x_wm,
),
TP_printk("dev %s, pipe %c, frame=%u, scanline=%u, wm %d/%d/%d, sr %s/%d/%d/%d, hpll %s/%d/%d/%d, fbc %s",
__get_str(dev), pipe_name(__entry->pipe),
__get_str(dev), __entry->pipe_name,
__entry->frame, __entry->scanline,
__entry->primary, __entry->sprite, __entry->cursor,
str_yes_no(__entry->cxsr), __entry->sr_plane, __entry->sr_cursor, __entry->sr_fbc,
@ -265,7 +309,7 @@ TRACE_EVENT(vlv_wm,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(crtc))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
__field(u32, level)
@ -280,7 +324,7 @@ TRACE_EVENT(vlv_wm,
TP_fast_assign(
__assign_str(dev);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
__entry->level = wm->level;
@ -294,7 +338,7 @@ TRACE_EVENT(vlv_wm,
),
TP_printk("dev %s, pipe %c, frame=%u, scanline=%u, level=%d, cxsr=%d, wm %d/%d/%d/%d, sr %d/%d",
__get_str(dev), pipe_name(__entry->pipe),
__get_str(dev), __entry->pipe_name,
__entry->frame, __entry->scanline,
__entry->level, __entry->cxsr,
__entry->primary, __entry->sprite0, __entry->sprite1, __entry->cursor,
@ -307,7 +351,7 @@ TRACE_EVENT(vlv_fifo_size,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(crtc))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
__field(u32, sprite0_start)
@ -317,7 +361,7 @@ TRACE_EVENT(vlv_fifo_size,
TP_fast_assign(
__assign_str(dev);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
__entry->sprite0_start = sprite0_start;
@ -326,7 +370,7 @@ TRACE_EVENT(vlv_fifo_size,
),
TP_printk("dev %s, pipe %c, frame=%u, scanline=%u, %d/%d/%d",
__get_str(dev), pipe_name(__entry->pipe),
__get_str(dev), __entry->pipe_name,
__entry->frame, __entry->scanline,
__entry->sprite0_start, __entry->sprite1_start, __entry->fifo_size)
);
@ -337,7 +381,7 @@ TRACE_EVENT(intel_plane_async_flip,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(plane))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
__field(bool, async_flip)
@ -347,14 +391,14 @@ TRACE_EVENT(intel_plane_async_flip,
TP_fast_assign(
__assign_str(dev);
__assign_str(name);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
__entry->async_flip = async_flip;
),
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u, async_flip=%s",
__get_str(dev), pipe_name(__entry->pipe), __get_str(name),
__get_str(dev), __entry->pipe_name, __get_str(name),
__entry->frame, __entry->scanline, str_yes_no(__entry->async_flip))
);
@ -364,7 +408,7 @@ TRACE_EVENT(intel_plane_update_noarm,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(plane))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
__array(int, src, 4)
@ -375,7 +419,7 @@ TRACE_EVENT(intel_plane_update_noarm,
TP_fast_assign(
__assign_str(dev);
__assign_str(name);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
memcpy(__entry->src, &plane->base.state->src, sizeof(__entry->src));
@ -383,7 +427,7 @@ TRACE_EVENT(intel_plane_update_noarm,
),
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT,
__get_str(dev), pipe_name(__entry->pipe), __get_str(name),
__get_str(dev), __entry->pipe_name, __get_str(name),
__entry->frame, __entry->scanline,
DRM_RECT_FP_ARG((const struct drm_rect *)__entry->src),
DRM_RECT_ARG((const struct drm_rect *)__entry->dst))
@ -395,7 +439,7 @@ TRACE_EVENT(intel_plane_update_arm,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(plane))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
__array(int, src, 4)
@ -406,7 +450,7 @@ TRACE_EVENT(intel_plane_update_arm,
TP_fast_assign(
__assign_str(dev);
__assign_str(name);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
memcpy(__entry->src, &plane->base.state->src, sizeof(__entry->src));
@ -414,7 +458,7 @@ TRACE_EVENT(intel_plane_update_arm,
),
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT,
__get_str(dev), pipe_name(__entry->pipe), __get_str(name),
__get_str(dev), __entry->pipe_name, __get_str(name),
__entry->frame, __entry->scanline,
DRM_RECT_FP_ARG((const struct drm_rect *)__entry->src),
DRM_RECT_ARG((const struct drm_rect *)__entry->dst))
@ -426,7 +470,7 @@ TRACE_EVENT(intel_plane_disable_arm,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(plane))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
__string(name, plane->base.name)
@ -435,13 +479,13 @@ TRACE_EVENT(intel_plane_disable_arm,
TP_fast_assign(
__assign_str(dev);
__assign_str(name);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
),
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u",
__get_str(dev), pipe_name(__entry->pipe), __get_str(name),
__get_str(dev), __entry->pipe_name, __get_str(name),
__entry->frame, __entry->scanline)
);
@ -452,7 +496,7 @@ TRACE_EVENT(intel_fbc_activate,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(plane))
__string(name, plane->base.name)
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
),
@ -463,13 +507,13 @@ TRACE_EVENT(intel_fbc_activate,
plane->pipe);
__assign_str(dev);
__assign_str(name);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
),
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u",
__get_str(dev), pipe_name(__entry->pipe), __get_str(name),
__get_str(dev), __entry->pipe_name, __get_str(name),
__entry->frame, __entry->scanline)
);
@ -480,7 +524,7 @@ TRACE_EVENT(intel_fbc_deactivate,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(plane))
__string(name, plane->base.name)
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
),
@ -491,13 +535,13 @@ TRACE_EVENT(intel_fbc_deactivate,
plane->pipe);
__assign_str(dev);
__assign_str(name);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
),
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u",
__get_str(dev), pipe_name(__entry->pipe), __get_str(name),
__get_str(dev), __entry->pipe_name, __get_str(name),
__entry->frame, __entry->scanline)
);
@ -508,7 +552,7 @@ TRACE_EVENT(intel_fbc_nuke,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(plane))
__string(name, plane->base.name)
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
),
@ -519,13 +563,13 @@ TRACE_EVENT(intel_fbc_nuke,
plane->pipe);
__assign_str(dev);
__assign_str(name);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
),
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u",
__get_str(dev), pipe_name(__entry->pipe), __get_str(name),
__get_str(dev), __entry->pipe_name, __get_str(name),
__entry->frame, __entry->scanline)
);
@ -535,20 +579,20 @@ TRACE_EVENT(intel_crtc_vblank_work_start,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(crtc))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
),
TP_fast_assign(
__assign_str(dev);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
),
TP_printk("dev %s, pipe %c, frame=%u, scanline=%u",
__get_str(dev), pipe_name(__entry->pipe),
__get_str(dev), __entry->pipe_name,
__entry->frame, __entry->scanline)
);
@ -558,20 +602,20 @@ TRACE_EVENT(intel_crtc_vblank_work_end,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(crtc))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
),
TP_fast_assign(
__assign_str(dev);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
),
TP_printk("dev %s, pipe %c, frame=%u, scanline=%u",
__get_str(dev), pipe_name(__entry->pipe),
__get_str(dev), __entry->pipe_name,
__entry->frame, __entry->scanline)
);
@ -581,7 +625,7 @@ TRACE_EVENT(intel_pipe_update_start,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(crtc))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
__field(u32, min)
@ -590,7 +634,7 @@ TRACE_EVENT(intel_pipe_update_start,
TP_fast_assign(
__assign_str(dev);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = intel_crtc_get_vblank_counter(crtc);
__entry->scanline = intel_get_crtc_scanline(crtc);
__entry->min = crtc->debug.min_vbl;
@ -598,7 +642,7 @@ TRACE_EVENT(intel_pipe_update_start,
),
TP_printk("dev %s, pipe %c, frame=%u, scanline=%u, min=%u, max=%u",
__get_str(dev), pipe_name(__entry->pipe),
__get_str(dev), __entry->pipe_name,
__entry->frame, __entry->scanline,
__entry->min, __entry->max)
);
@ -609,7 +653,7 @@ TRACE_EVENT(intel_pipe_update_vblank_evaded,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(crtc))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
__field(u32, min)
@ -618,7 +662,7 @@ TRACE_EVENT(intel_pipe_update_vblank_evaded,
TP_fast_assign(
__assign_str(dev);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = crtc->debug.start_vbl_count;
__entry->scanline = crtc->debug.scanline_start;
__entry->min = crtc->debug.min_vbl;
@ -626,7 +670,7 @@ TRACE_EVENT(intel_pipe_update_vblank_evaded,
),
TP_printk("dev %s, pipe %c, frame=%u, scanline=%u, min=%u, max=%u",
__get_str(dev), pipe_name(__entry->pipe),
__get_str(dev), __entry->pipe_name,
__entry->frame, __entry->scanline,
__entry->min, __entry->max)
);
@ -637,20 +681,20 @@ TRACE_EVENT(intel_pipe_update_end,
TP_STRUCT__entry(
__string(dev, __dev_name_kms(crtc))
__field(enum pipe, pipe)
__field(char, pipe_name)
__field(u32, frame)
__field(u32, scanline)
),
TP_fast_assign(
__assign_str(dev);
__entry->pipe = crtc->pipe;
__entry->pipe_name = pipe_name(crtc->pipe);
__entry->frame = frame;
__entry->scanline = scanline_end;
),
TP_printk("dev %s, pipe %c, frame=%u, scanline=%u",
__get_str(dev), pipe_name(__entry->pipe),
__get_str(dev), __entry->pipe_name,
__entry->frame, __entry->scanline)
);

View File

@ -1618,6 +1618,8 @@ struct intel_psr {
u32 dc3co_exit_delay;
struct delayed_work dc3co_work;
u8 entry_setup_frames;
bool link_ok;
};
struct intel_dp {
@ -1765,6 +1767,7 @@ struct intel_dp {
/* When we last wrote the OUI for eDP */
unsigned long last_oui_write;
bool oui_valid;
bool colorimetry_support;
@ -2104,6 +2107,10 @@ to_intel_frontbuffer(struct drm_framebuffer *fb)
__drm_device_to_intel_display((p)->base.dev)
#define __intel_hdmi_to_intel_display(p) \
__drm_device_to_intel_display(hdmi_to_dig_port(p)->base.base.dev)
#define __intel_plane_to_intel_display(p) \
__drm_device_to_intel_display((p)->base.dev)
#define __intel_plane_state_to_intel_display(p) \
__drm_device_to_intel_display((p)->uapi.plane->dev)
/* Helper for generic association. Map types to conversion functions/macros. */
#define __assoc(type, p) \
@ -2122,6 +2129,8 @@ to_intel_frontbuffer(struct drm_framebuffer *fb)
__assoc(intel_digital_port, p), \
__assoc(intel_dp, p), \
__assoc(intel_encoder, p), \
__assoc(intel_hdmi, p))
__assoc(intel_hdmi, p), \
__assoc(intel_plane, p), \
__assoc(intel_plane_state, p))
#endif /* __INTEL_DISPLAY_TYPES_H__ */

View File

@ -113,6 +113,9 @@ static bool dmc_firmware_param_disabled(struct intel_display *display)
#define DISPLAY_VER13_DMC_MAX_FW_SIZE 0x20000
#define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE
#define XE3LPD_DMC_PATH DMC_PATH(xe3lpd)
MODULE_FIRMWARE(XE3LPD_DMC_PATH);
#define XE2LPD_DMC_PATH DMC_PATH(xe2lpd)
MODULE_FIRMWARE(XE2LPD_DMC_PATH);
@ -168,13 +171,16 @@ static const char *dmc_firmware_default(struct intel_display *display, u32 *size
const char *fw_path = NULL;
u32 max_fw_size = 0;
if (DISPLAY_VER_FULL(display) == IP_VER(20, 0)) {
if (DISPLAY_VERx100(display) == 3000) {
fw_path = XE3LPD_DMC_PATH;
max_fw_size = XE2LPD_DMC_MAX_FW_SIZE;
} else if (DISPLAY_VERx100(display) == 2000) {
fw_path = XE2LPD_DMC_PATH;
max_fw_size = XE2LPD_DMC_MAX_FW_SIZE;
} else if (DISPLAY_VER_FULL(display) == IP_VER(14, 1)) {
} else if (DISPLAY_VERx100(display) == 1401) {
fw_path = BMG_DMC_PATH;
max_fw_size = XELPDP_DMC_MAX_FW_SIZE;
} else if (DISPLAY_VER_FULL(display) == IP_VER(14, 0)) {
} else if (DISPLAY_VERx100(display) == 1400) {
fw_path = MTL_DMC_PATH;
max_fw_size = XELPDP_DMC_MAX_FW_SIZE;
} else if (IS_DG2(i915)) {

View File

@ -83,8 +83,10 @@
#include "intel_modeset_lock.h"
#include "intel_panel.h"
#include "intel_pch_display.h"
#include "intel_pfit.h"
#include "intel_pps.h"
#include "intel_psr.h"
#include "intel_runtime_pm.h"
#include "intel_quirks.h"
#include "intel_tc.h"
#include "intel_vdsc.h"
@ -495,7 +497,7 @@ static int mtl_max_source_rate(struct intel_dp *intel_dp)
if (intel_encoder_is_c10phy(encoder))
return 810000;
if (DISPLAY_VER_FULL(to_i915(encoder->base.dev)) == IP_VER(14, 1))
if (DISPLAY_VERx100(to_i915(encoder->base.dev)) == 1401)
return 1350000;
return 2000000;
@ -1313,14 +1315,17 @@ bool intel_dp_needs_joiner(struct intel_dp *intel_dp,
int num_joined_pipes)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int hdisplay_limit;
if (!intel_dp_has_joiner(intel_dp))
return false;
num_joined_pipes /= 2;
hdisplay_limit = DISPLAY_VER(i915) >= 30 ? 6144 : 5120;
return clock > num_joined_pipes * i915->display.cdclk.max_dotclk_freq ||
hdisplay > num_joined_pipes * 5120;
hdisplay > num_joined_pipes * hdisplay_limit;
}
int intel_dp_num_joined_pipes(struct intel_dp *intel_dp,
@ -2475,7 +2480,7 @@ intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
encoder->base.base.id, encoder->base.name,
crtc->base.base.id, crtc->base.name,
adjusted_mode->crtc_clock,
dsc ? "on" : "off",
str_on_off(dsc),
limits->max_lane_count,
limits->max_rate,
limits->pipe.max_bpp,
@ -3399,30 +3404,43 @@ void intel_dp_sink_disable_decompression(struct intel_atomic_state *state,
}
static void
intel_edp_init_source_oui(struct intel_dp *intel_dp, bool careful)
intel_dp_init_source_oui(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 oui[] = { 0x00, 0xaa, 0x01 };
u8 buf[3] = {};
if (READ_ONCE(intel_dp->oui_valid))
return;
WRITE_ONCE(intel_dp->oui_valid, true);
/*
* During driver init, we want to be careful and avoid changing the source OUI if it's
* already set to what we want, so as to avoid clearing any state by accident
*/
if (careful) {
if (drm_dp_dpcd_read(&intel_dp->aux, DP_SOURCE_OUI, buf, sizeof(buf)) < 0)
drm_err(&i915->drm, "Failed to read source OUI\n");
if (drm_dp_dpcd_read(&intel_dp->aux, DP_SOURCE_OUI, buf, sizeof(buf)) < 0)
drm_err(&i915->drm, "Failed to read source OUI\n");
if (memcmp(oui, buf, sizeof(oui)) == 0)
return;
if (memcmp(oui, buf, sizeof(oui)) == 0) {
/* Assume the OUI was written now. */
intel_dp->last_oui_write = jiffies;
return;
}
if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0)
drm_err(&i915->drm, "Failed to write source OUI\n");
if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0) {
drm_info(&i915->drm, "Failed to write source OUI\n");
WRITE_ONCE(intel_dp->oui_valid, false);
}
intel_dp->last_oui_write = jiffies;
}
void intel_dp_invalidate_source_oui(struct intel_dp *intel_dp)
{
WRITE_ONCE(intel_dp->oui_valid, false);
}
void intel_dp_wait_source_oui(struct intel_dp *intel_dp)
{
struct intel_connector *connector = intel_dp->attached_connector;
@ -3458,8 +3476,7 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode)
lspcon_resume(dp_to_dig_port(intel_dp));
/* Write the source OUI as early as possible */
if (intel_dp_is_edp(intel_dp))
intel_edp_init_source_oui(intel_dp, false);
intel_dp_init_source_oui(intel_dp);
/*
* When turning on, we need to retry for 1ms to give the sink
@ -3997,6 +4014,23 @@ static void intel_edp_get_dsc_sink_cap(u8 edp_dpcd_rev, struct intel_connector *
intel_dp_read_dsc_dpcd(connector->dp.dsc_decompression_aux, connector->dp.dsc_dpcd);
}
static void
intel_dp_detect_dsc_caps(struct intel_dp *intel_dp, struct intel_connector *connector)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
/* Read DP Sink DSC Cap DPCD regs for DP v1.4 */
if (!HAS_DSC(i915))
return;
if (intel_dp_is_edp(intel_dp))
intel_edp_get_dsc_sink_cap(intel_dp->edp_dpcd[0],
connector);
else
intel_dp_get_dsc_sink_cap(intel_dp->dpcd[DP_DPCD_REV],
connector);
}
static void intel_edp_mso_mode_fixup(struct intel_connector *connector,
struct drm_display_mode *mode)
{
@ -4162,6 +4196,12 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
intel_dp->use_max_params = intel_dp->edp_dpcd[0] < DP_EDP_14;
}
/*
* If needed, program our source OUI so we can make various Intel-specific AUX services
* available (such as HDR backlight controls)
*/
intel_dp_init_source_oui(intel_dp);
/*
* This has to be called after intel_dp->edp_dpcd is filled, PSR checks
* for SET_POWER_CAPABLE bit in intel_dp->edp_dpcd[1]
@ -4172,15 +4212,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
intel_dp_set_max_sink_lane_count(intel_dp);
/* Read the eDP DSC DPCD registers */
if (HAS_DSC(dev_priv))
intel_edp_get_dsc_sink_cap(intel_dp->edp_dpcd[0],
connector);
/*
* If needed, program our source OUI so we can make various Intel-specific AUX services
* available (such as HDR backlight controls)
*/
intel_edp_init_source_oui(intel_dp, true);
intel_dp_detect_dsc_caps(intel_dp, connector);
return true;
}
@ -5006,7 +5038,8 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
return true;
/* Retrain if link not ok */
return !intel_dp_link_ok(intel_dp, link_status);
return !intel_dp_link_ok(intel_dp, link_status) &&
!intel_psr_link_ok(intel_dp);
}
bool intel_dp_has_connector(struct intel_dp *intel_dp,
@ -5034,6 +5067,21 @@ bool intel_dp_has_connector(struct intel_dp *intel_dp,
return false;
}
static void wait_for_connector_hw_done(const struct drm_connector_state *conn_state)
{
struct intel_connector *connector = to_intel_connector(conn_state->connector);
struct intel_display *display = to_intel_display(connector);
drm_modeset_lock_assert_held(&display->drm->mode_config.connection_mutex);
if (!conn_state->commit)
return;
drm_WARN_ON(display->drm,
!wait_for_completion_timeout(&conn_state->commit->hw_done,
msecs_to_jiffies(5000)));
}
int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
struct drm_modeset_acquire_ctx *ctx,
u8 *pipe_mask)
@ -5070,10 +5118,7 @@ int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
if (!crtc_state->hw.active)
continue;
if (conn_state->commit)
drm_WARN_ON(&i915->drm,
!wait_for_completion_timeout(&conn_state->commit->hw_done,
msecs_to_jiffies(5000)));
wait_for_connector_hw_done(conn_state);
*pipe_mask |= BIT(crtc->pipe);
}
@ -5082,6 +5127,11 @@ int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
return ret;
}
void intel_dp_flush_connector_commits(struct intel_connector *connector)
{
wait_for_connector_hw_done(connector->base.state);
}
static bool intel_dp_is_connected(struct intel_dp *intel_dp)
{
struct intel_connector *connector = intel_dp->attached_connector;
@ -5544,23 +5594,6 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
false);
}
static void
intel_dp_detect_dsc_caps(struct intel_dp *intel_dp, struct intel_connector *connector)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
/* Read DP Sink DSC Cap DPCD regs for DP v1.4 */
if (!HAS_DSC(i915))
return;
if (intel_dp_is_edp(intel_dp))
intel_edp_get_dsc_sink_cap(intel_dp->edp_dpcd[0],
connector);
else
intel_dp_get_dsc_sink_cap(intel_dp->dpcd[DP_DPCD_REV],
connector);
}
static void
intel_dp_detect_sdp_caps(struct intel_dp *intel_dp)
{
@ -5595,6 +5628,10 @@ intel_dp_detect(struct drm_connector *connector,
if (!intel_display_driver_check_access(dev_priv))
return connector->status;
intel_dp_flush_connector_commits(intel_connector);
intel_pps_vdd_on(intel_dp);
/* Can't disconnect eDP */
if (intel_dp_is_edp(intel_dp))
status = edp_detect(intel_dp);
@ -5625,12 +5662,17 @@ intel_dp_detect(struct drm_connector *connector,
intel_dp_tunnel_disconnect(intel_dp);
goto out;
goto out_unset_edid;
}
intel_dp_init_source_oui(intel_dp);
ret = intel_dp_tunnel_detect(intel_dp, ctx);
if (ret == -EDEADLK)
return ret;
if (ret == -EDEADLK) {
status = ret;
goto out_vdd_off;
}
if (ret == 1)
intel_connector->base.epoch_counter++;
@ -5658,7 +5700,7 @@ intel_dp_detect(struct drm_connector *connector,
* with EDID on it
*/
status = connector_status_disconnected;
goto out;
goto out_unset_edid;
}
/*
@ -5687,7 +5729,7 @@ intel_dp_detect(struct drm_connector *connector,
intel_dp_check_device_service_irq(intel_dp);
out:
out_unset_edid:
if (status != connector_status_connected && !intel_dp->is_mst)
intel_dp_unset_edid(intel_dp);
@ -5696,6 +5738,9 @@ intel_dp_detect(struct drm_connector *connector,
status,
intel_dp->dpcd,
intel_dp->downstream_ports);
out_vdd_off:
intel_pps_vdd_off(intel_dp);
return status;
}
@ -6054,7 +6099,9 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd)
u8 dpcd[DP_RECEIVER_CAP_SIZE];
if (dig_port->base.type == INTEL_OUTPUT_EDP &&
(long_hpd || !intel_pps_have_panel_power_or_vdd(intel_dp))) {
(long_hpd ||
intel_runtime_pm_suspended(&i915->runtime_pm) ||
!intel_pps_have_panel_power_or_vdd(intel_dp))) {
/*
* vdd off can generate a long/short pulse on eDP which
* would require vdd on to handle it, and thus we
@ -6087,6 +6134,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd)
if (long_hpd) {
intel_dp->reset_link_params = true;
intel_dp_invalidate_source_oui(intel_dp);
return IRQ_NONE;
}
@ -6372,6 +6421,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
out_vdd_off:
intel_pps_vdd_off_sync(intel_dp);
intel_bios_fini_panel(&intel_connector->panel);
return false;
}
@ -6411,6 +6461,7 @@ bool
intel_dp_init_connector(struct intel_digital_port *dig_port,
struct intel_connector *intel_connector)
{
struct intel_display *display = to_intel_display(dig_port);
struct drm_connector *connector = &intel_connector->base;
struct intel_dp *intel_dp = &dig_port->dp;
struct intel_encoder *intel_encoder = &dig_port->base;
@ -6436,10 +6487,11 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
if (_intel_dp_is_port_edp(dev_priv, intel_encoder->devdata, port)) {
/*
* Currently we don't support eDP on TypeC ports, although in
* theory it could work on TypeC legacy ports.
* Currently we don't support eDP on TypeC ports for DISPLAY_VER < 30,
* although in theory it could work on TypeC legacy ports.
*/
drm_WARN_ON(dev, intel_encoder_is_tc(intel_encoder));
drm_WARN_ON(dev, intel_encoder_is_tc(intel_encoder) &&
DISPLAY_VER(dev_priv) < 30);
type = DRM_MODE_CONNECTOR_eDP;
intel_encoder->type = INTEL_OUTPUT_EDP;
@ -6473,7 +6525,8 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
if (!HAS_GMCH(dev_priv) && DISPLAY_VER(dev_priv) < 12)
connector->interlace_allowed = true;
intel_connector->polled = DRM_CONNECTOR_POLL_HPD;
if (type != DRM_MODE_CONNECTOR_eDP)
intel_connector->polled = DRM_CONNECTOR_POLL_HPD;
intel_connector->base.polled = intel_connector->polled;
intel_connector_attach_encoder(intel_connector, intel_encoder);
@ -6499,7 +6552,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
intel_dp_add_properties(intel_dp, connector);
if (is_hdcp_supported(dev_priv, port) && !intel_dp_is_edp(intel_dp)) {
if (is_hdcp_supported(display, port) && !intel_dp_is_edp(intel_dp)) {
int ret = intel_dp_hdcp_init(dig_port, intel_connector);
if (ret)
drm_dbg_kms(&dev_priv->drm,

View File

@ -54,6 +54,7 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp,
int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
struct drm_modeset_acquire_ctx *ctx,
u8 *pipe_mask);
void intel_dp_flush_connector_commits(struct intel_connector *connector);
void intel_dp_link_check(struct intel_encoder *encoder);
void intel_dp_check_link_state(struct intel_dp *intel_dp);
void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode);
@ -188,6 +189,7 @@ void intel_dp_check_frl_training(struct intel_dp *intel_dp);
void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_dp_invalidate_source_oui(struct intel_dp *intel_dp);
void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
int intel_dp_output_bpp(enum intel_output_format output_format, int bpp);

View File

@ -58,7 +58,7 @@ static
int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
u8 *an)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_display *display = to_intel_display(dig_port);
u8 aksv[DRM_HDCP_KSV_LEN] = {};
ssize_t dpcd_ret;
@ -66,7 +66,7 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
dpcd_ret = drm_dp_dpcd_write(&dig_port->dp.aux, DP_AUX_HDCP_AN,
an, DRM_HDCP_AN_LEN);
if (dpcd_ret != DRM_HDCP_AN_LEN) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"Failed to write An over DP/AUX (%zd)\n",
dpcd_ret);
return dpcd_ret >= 0 ? -EIO : dpcd_ret;
@ -82,7 +82,7 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
dpcd_ret = drm_dp_dpcd_write(&dig_port->dp.aux, DP_AUX_HDCP_AKSV,
aksv, DRM_HDCP_KSV_LEN);
if (dpcd_ret != DRM_HDCP_KSV_LEN) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"Failed to write Aksv over DP/AUX (%zd)\n",
dpcd_ret);
return dpcd_ret >= 0 ? -EIO : dpcd_ret;
@ -93,13 +93,13 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
static int intel_dp_hdcp_read_bksv(struct intel_digital_port *dig_port,
u8 *bksv)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
DRM_HDCP_KSV_LEN);
if (ret != DRM_HDCP_KSV_LEN) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"Read Bksv from DP/AUX failed (%zd)\n", ret);
return ret >= 0 ? -EIO : ret;
}
@ -109,7 +109,7 @@ static int intel_dp_hdcp_read_bksv(struct intel_digital_port *dig_port,
static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *dig_port,
u8 *bstatus)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
/*
@ -120,7 +120,7 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *dig_port,
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BINFO,
bstatus, DRM_HDCP_BSTATUS_LEN);
if (ret != DRM_HDCP_BSTATUS_LEN) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"Read bstatus from DP/AUX failed (%zd)\n", ret);
return ret >= 0 ? -EIO : ret;
}
@ -129,7 +129,7 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *dig_port,
static
int intel_dp_hdcp_read_bcaps(struct drm_dp_aux *aux,
struct drm_i915_private *i915,
struct intel_display *display,
u8 *bcaps)
{
ssize_t ret;
@ -137,7 +137,7 @@ int intel_dp_hdcp_read_bcaps(struct drm_dp_aux *aux,
ret = drm_dp_dpcd_read(aux, DP_AUX_HDCP_BCAPS,
bcaps, 1);
if (ret != 1) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"Read bcaps from DP/AUX failed (%zd)\n", ret);
return ret >= 0 ? -EIO : ret;
}
@ -149,11 +149,11 @@ static
int intel_dp_hdcp_repeater_present(struct intel_digital_port *dig_port,
bool *repeater_present)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
u8 bcaps;
ret = intel_dp_hdcp_read_bcaps(&dig_port->dp.aux, i915, &bcaps);
ret = intel_dp_hdcp_read_bcaps(&dig_port->dp.aux, display, &bcaps);
if (ret)
return ret;
@ -165,13 +165,14 @@ static
int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *dig_port,
u8 *ri_prime)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME,
ri_prime, DRM_HDCP_RI_LEN);
if (ret != DRM_HDCP_RI_LEN) {
drm_dbg_kms(&i915->drm, "Read Ri' from DP/AUX failed (%zd)\n",
drm_dbg_kms(display->drm,
"Read Ri' from DP/AUX failed (%zd)\n",
ret);
return ret >= 0 ? -EIO : ret;
}
@ -182,14 +183,14 @@ static
int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *dig_port,
bool *ksv_ready)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
u8 bstatus;
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
&bstatus, 1);
if (ret != 1) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"Read bstatus from DP/AUX failed (%zd)\n", ret);
return ret >= 0 ? -EIO : ret;
}
@ -201,7 +202,7 @@ static
int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *dig_port,
int num_downstream, u8 *ksv_fifo)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
int i;
@ -213,7 +214,7 @@ int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *dig_port,
ksv_fifo + i * DRM_HDCP_KSV_LEN,
len);
if (ret != len) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"Read ksv[%d] from DP/AUX failed (%zd)\n",
i, ret);
return ret >= 0 ? -EIO : ret;
@ -226,7 +227,7 @@ static
int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *dig_port,
int i, u32 *part)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
@ -236,7 +237,7 @@ int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *dig_port,
DP_AUX_HDCP_V_PRIME(i), part,
DRM_HDCP_V_PRIME_PART_LEN);
if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
return ret >= 0 ? -EIO : ret;
}
@ -256,14 +257,14 @@ static
bool intel_dp_hdcp_check_link(struct intel_digital_port *dig_port,
struct intel_connector *connector)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
u8 bstatus;
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
&bstatus, 1);
if (ret != 1) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"Read bstatus from DP/AUX failed (%zd)\n", ret);
return false;
}
@ -275,11 +276,11 @@ static
int intel_dp_hdcp_get_capability(struct intel_digital_port *dig_port,
bool *hdcp_capable)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
u8 bcaps;
ret = intel_dp_hdcp_read_bcaps(&dig_port->dp.aux, i915, &bcaps);
ret = intel_dp_hdcp_read_bcaps(&dig_port->dp.aux, display, &bcaps);
if (ret)
return ret;
@ -342,7 +343,7 @@ static int
intel_dp_hdcp2_read_rx_status(struct intel_connector *connector,
u8 *rx_status)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct drm_dp_aux *aux = &dig_port->dp.aux;
ssize_t ret;
@ -351,7 +352,7 @@ intel_dp_hdcp2_read_rx_status(struct intel_connector *connector,
DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
HDCP_2_2_DP_RXSTATUS_LEN);
if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"Read bstatus from DP/AUX failed (%zd)\n", ret);
return ret >= 0 ? -EIO : ret;
}
@ -397,7 +398,7 @@ static ssize_t
intel_dp_hdcp2_wait_for_msg(struct intel_connector *connector,
const struct hdcp2_dp_msg_data *hdcp2_msg_data)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct intel_dp *dp = &dig_port->dp;
struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
@ -430,7 +431,7 @@ intel_dp_hdcp2_wait_for_msg(struct intel_connector *connector,
}
if (ret)
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"msg_id %d, ret %d, timeout(mSec): %d\n",
hdcp2_msg_data->msg_id, ret, timeout);
@ -514,8 +515,8 @@ static
int intel_dp_hdcp2_read_msg(struct intel_connector *connector,
u8 msg_id, void *buf, size_t size)
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct drm_dp_aux *aux = &dig_port->dp.aux;
struct intel_dp *dp = &dig_port->dp;
struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
@ -568,7 +569,7 @@ int intel_dp_hdcp2_read_msg(struct intel_connector *connector,
ret = drm_dp_dpcd_read(aux, offset,
(void *)byte, len);
if (ret < 0) {
drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
drm_dbg_kms(display->drm, "msg_id %d, ret %zd\n",
msg_id, ret);
return ret;
}
@ -581,7 +582,8 @@ int intel_dp_hdcp2_read_msg(struct intel_connector *connector,
if (hdcp2_msg_data->msg_read_timeout > 0) {
msg_expired = ktime_after(ktime_get_raw(), msg_end);
if (msg_expired) {
drm_dbg_kms(&i915->drm, "msg_id %d, entire msg read timeout(mSec): %d\n",
drm_dbg_kms(display->drm,
"msg_id %d, entire msg read timeout(mSec): %d\n",
msg_id, hdcp2_msg_data->msg_read_timeout);
return -ETIMEDOUT;
}
@ -696,7 +698,7 @@ int intel_dp_hdcp_get_remote_capability(struct intel_connector *connector,
bool *hdcp_capable,
bool *hdcp2_capable)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
struct drm_dp_aux *aux;
u8 bcaps;
int ret;
@ -709,10 +711,10 @@ int intel_dp_hdcp_get_remote_capability(struct intel_connector *connector,
aux = &connector->port->aux;
ret = _intel_dp_hdcp2_get_capability(aux, hdcp2_capable);
if (ret)
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"HDCP2 DPCD capability read failed err: %d\n", ret);
ret = intel_dp_hdcp_read_bcaps(aux, i915, &bcaps);
ret = intel_dp_hdcp_read_bcaps(aux, display, &bcaps);
if (ret)
return ret;
@ -745,8 +747,8 @@ static int
intel_dp_mst_toggle_hdcp_stream_select(struct intel_connector *connector,
bool enable)
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
int ret;
@ -754,7 +756,7 @@ intel_dp_mst_toggle_hdcp_stream_select(struct intel_connector *connector,
hdcp->stream_transcoder, enable,
TRANS_DDI_HDCP_SELECT);
if (ret)
drm_err(&i915->drm, "%s HDCP stream select failed (%d)\n",
drm_err(display->drm, "%s HDCP stream select failed (%d)\n",
enable ? "Enable" : "Disable", ret);
return ret;
}
@ -763,8 +765,8 @@ static int
intel_dp_mst_hdcp_stream_encryption(struct intel_connector *connector,
bool enable)
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
enum port port = dig_port->base.port;
enum transcoder cpu_transcoder = hdcp->stream_transcoder;
@ -780,11 +782,11 @@ intel_dp_mst_hdcp_stream_encryption(struct intel_connector *connector,
return -EINVAL;
/* Wait for encryption confirmation */
if (intel_de_wait(i915, HDCP_STATUS(i915, cpu_transcoder, port),
if (intel_de_wait(display, HDCP_STATUS(display, cpu_transcoder, port),
stream_enc_status, enable ? stream_enc_status : 0,
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
drm_err(&i915->drm, "Timed out waiting for transcoder: %s stream encryption %s\n",
transcoder_name(cpu_transcoder), enable ? "enabled" : "disabled");
drm_err(display->drm, "Timed out waiting for transcoder: %s stream encryption %s\n",
transcoder_name(cpu_transcoder), str_enabled_disabled(enable));
return -ETIMEDOUT;
}
@ -795,8 +797,8 @@ static int
intel_dp_mst_hdcp2_stream_encryption(struct intel_connector *connector,
bool enable)
{
struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct hdcp_port_data *data = &dig_port->hdcp_port_data;
struct intel_hdcp *hdcp = &connector->hdcp;
enum transcoder cpu_transcoder = hdcp->stream_transcoder;
@ -804,8 +806,8 @@ intel_dp_mst_hdcp2_stream_encryption(struct intel_connector *connector,
enum port port = dig_port->base.port;
int ret;
drm_WARN_ON(&i915->drm, enable &&
!!(intel_de_read(i915, HDCP2_AUTH_STREAM(i915, cpu_transcoder, port))
drm_WARN_ON(display->drm, enable &&
!!(intel_de_read(display, HDCP2_AUTH_STREAM(display, cpu_transcoder, port))
& AUTH_STREAM_TYPE) != data->streams[0].stream_type);
ret = intel_dp_mst_toggle_hdcp_stream_select(connector, enable);
@ -813,12 +815,12 @@ intel_dp_mst_hdcp2_stream_encryption(struct intel_connector *connector,
return ret;
/* Wait for encryption confirmation */
if (intel_de_wait(i915, HDCP2_STREAM_STATUS(i915, cpu_transcoder, pipe),
if (intel_de_wait(display, HDCP2_STREAM_STATUS(display, cpu_transcoder, pipe),
STREAM_ENCRYPTION_STATUS,
enable ? STREAM_ENCRYPTION_STATUS : 0,
HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
drm_err(&i915->drm, "Timed out waiting for transcoder: %s stream encryption %s\n",
transcoder_name(cpu_transcoder), enable ? "enabled" : "disabled");
drm_err(display->drm, "Timed out waiting for transcoder: %s stream encryption %s\n",
transcoder_name(cpu_transcoder), str_enabled_disabled(enable));
return -ETIMEDOUT;
}
@ -873,13 +875,12 @@ static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
int intel_dp_hdcp_init(struct intel_digital_port *dig_port,
struct intel_connector *intel_connector)
{
struct drm_device *dev = intel_connector->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_display *display = to_intel_display(dig_port);
struct intel_encoder *intel_encoder = &dig_port->base;
enum port port = intel_encoder->port;
struct intel_dp *intel_dp = &dig_port->dp;
if (!is_hdcp_supported(dev_priv, port))
if (!is_hdcp_supported(display, port))
return 0;
if (intel_connector->mst_port)

View File

@ -153,7 +153,7 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec
{
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
int num_joined_pipes = crtc_state->joiner_pipes;
int num_joined_pipes = intel_crtc_num_joined_pipes(crtc_state);
return intel_dp_dsc_get_slice_count(connector,
adjusted_mode->clock,
@ -1573,6 +1573,8 @@ intel_dp_mst_detect(struct drm_connector *connector,
if (!intel_display_driver_check_access(i915))
return connector->status;
intel_dp_flush_connector_commits(intel_connector);
return drm_dp_mst_detect_port(connector, ctx, &intel_dp->mst_mgr,
intel_connector->port);
}

View File

@ -219,8 +219,10 @@ static const struct bxt_dpio_phy_info glk_dpio_phy_info[] = {
};
static const struct bxt_dpio_phy_info *
bxt_get_phy_list(struct drm_i915_private *dev_priv, int *count)
bxt_get_phy_list(struct intel_display *display, int *count)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (IS_GEMINILAKE(dev_priv)) {
*count = ARRAY_SIZE(glk_dpio_phy_info);
return glk_dpio_phy_info;
@ -231,22 +233,22 @@ bxt_get_phy_list(struct drm_i915_private *dev_priv, int *count)
}
static const struct bxt_dpio_phy_info *
bxt_get_phy_info(struct drm_i915_private *dev_priv, enum dpio_phy phy)
bxt_get_phy_info(struct intel_display *display, enum dpio_phy phy)
{
int count;
const struct bxt_dpio_phy_info *phy_list =
bxt_get_phy_list(dev_priv, &count);
bxt_get_phy_list(display, &count);
return &phy_list[phy];
}
void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
void bxt_port_to_phy_channel(struct intel_display *display, enum port port,
enum dpio_phy *phy, enum dpio_channel *ch)
{
const struct bxt_dpio_phy_info *phy_info, *phys;
int i, count;
phys = bxt_get_phy_list(dev_priv, &count);
phys = bxt_get_phy_list(display, &count);
for (i = 0; i < count; i++) {
phy_info = &phys[i];
@ -265,7 +267,7 @@ void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
}
}
drm_WARN(&dev_priv->drm, 1, "PHY not found for PORT %c",
drm_WARN(display->drm, 1, "PHY not found for PORT %c",
port_name(port));
*phy = DPIO_PHY0;
*ch = DPIO_CH0;
@ -275,16 +277,16 @@ void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
* Like intel_de_rmw() but reads from a single per-lane register and
* writes to the group register to write the same value to all the lanes.
*/
static u32 bxt_dpio_phy_rmw_grp(struct drm_i915_private *i915,
static u32 bxt_dpio_phy_rmw_grp(struct intel_display *display,
i915_reg_t reg_single,
i915_reg_t reg_group,
u32 clear, u32 set)
{
u32 old, val;
old = intel_de_read(i915, reg_single);
old = intel_de_read(display, reg_single);
val = (old & ~clear) | set;
intel_de_write(i915, reg_group, val);
intel_de_write(display, reg_group, val);
return old;
}
@ -292,30 +294,30 @@ static u32 bxt_dpio_phy_rmw_grp(struct drm_i915_private *i915,
void bxt_dpio_phy_set_signal_levels(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
const struct intel_ddi_buf_trans *trans;
enum dpio_channel ch;
enum dpio_phy phy;
int lane, n_entries;
trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans))
if (drm_WARN_ON_ONCE(display->drm, !trans))
return;
bxt_port_to_phy_channel(dev_priv, encoder->port, &phy, &ch);
bxt_port_to_phy_channel(display, encoder->port, &phy, &ch);
/*
* While we write to the group register to program all lanes at once we
* can read only lane registers and we pick lanes 0/1 for that.
*/
bxt_dpio_phy_rmw_grp(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch),
bxt_dpio_phy_rmw_grp(display, BXT_PORT_PCS_DW10_LN01(phy, ch),
BXT_PORT_PCS_DW10_GRP(phy, ch),
TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT, 0);
for (lane = 0; lane < crtc_state->lane_count; lane++) {
int level = intel_ddi_level(encoder, crtc_state, lane);
intel_de_rmw(dev_priv, BXT_PORT_TX_DW2_LN(phy, ch, lane),
intel_de_rmw(display, BXT_PORT_TX_DW2_LN(phy, ch, lane),
MARGIN_000_MASK | UNIQ_TRANS_SCALE_MASK,
MARGIN_000(trans->entries[level].bxt.margin) |
UNIQ_TRANS_SCALE(trans->entries[level].bxt.scale));
@ -325,50 +327,50 @@ void bxt_dpio_phy_set_signal_levels(struct intel_encoder *encoder,
int level = intel_ddi_level(encoder, crtc_state, lane);
u32 val;
intel_de_rmw(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, lane),
intel_de_rmw(display, BXT_PORT_TX_DW3_LN(phy, ch, lane),
SCALE_DCOMP_METHOD,
trans->entries[level].bxt.enable ?
SCALE_DCOMP_METHOD : 0);
val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, lane));
val = intel_de_read(display, BXT_PORT_TX_DW3_LN(phy, ch, lane));
if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
drm_err(&dev_priv->drm,
drm_err(display->drm,
"Disabled scaling while ouniqetrangenmethod was set");
}
for (lane = 0; lane < crtc_state->lane_count; lane++) {
int level = intel_ddi_level(encoder, crtc_state, lane);
intel_de_rmw(dev_priv, BXT_PORT_TX_DW4_LN(phy, ch, lane),
intel_de_rmw(display, BXT_PORT_TX_DW4_LN(phy, ch, lane),
DE_EMPHASIS_MASK,
DE_EMPHASIS(trans->entries[level].bxt.deemphasis));
}
bxt_dpio_phy_rmw_grp(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch),
bxt_dpio_phy_rmw_grp(display, BXT_PORT_PCS_DW10_LN01(phy, ch),
BXT_PORT_PCS_DW10_GRP(phy, ch),
0, TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
}
bool bxt_dpio_phy_is_enabled(struct drm_i915_private *dev_priv,
bool bxt_dpio_phy_is_enabled(struct intel_display *display,
enum dpio_phy phy)
{
const struct bxt_dpio_phy_info *phy_info;
phy_info = bxt_get_phy_info(dev_priv, phy);
phy_info = bxt_get_phy_info(display, phy);
if (!(intel_de_read(dev_priv, BXT_P_CR_GT_DISP_PWRON) & phy_info->pwron_mask))
if (!(intel_de_read(display, BXT_P_CR_GT_DISP_PWRON) & phy_info->pwron_mask))
return false;
if ((intel_de_read(dev_priv, BXT_PORT_CL1CM_DW0(phy)) &
if ((intel_de_read(display, BXT_PORT_CL1CM_DW0(phy)) &
(PHY_POWER_GOOD | PHY_RESERVED)) != PHY_POWER_GOOD) {
drm_dbg(&dev_priv->drm,
drm_dbg(display->drm,
"DDI PHY %d powered, but power hasn't settled\n", phy);
return false;
}
if (!(intel_de_read(dev_priv, BXT_PHY_CTL_FAMILY(phy)) & COMMON_RESET_DIS)) {
drm_dbg(&dev_priv->drm,
if (!(intel_de_read(display, BXT_PHY_CTL_FAMILY(phy)) & COMMON_RESET_DIS)) {
drm_dbg(display->drm,
"DDI PHY %d powered, but still in reset\n", phy);
return false;
@ -377,47 +379,44 @@ bool bxt_dpio_phy_is_enabled(struct drm_i915_private *dev_priv,
return true;
}
static u32 bxt_get_grc(struct drm_i915_private *dev_priv, enum dpio_phy phy)
static u32 bxt_get_grc(struct intel_display *display, enum dpio_phy phy)
{
u32 val = intel_de_read(dev_priv, BXT_PORT_REF_DW6(phy));
u32 val = intel_de_read(display, BXT_PORT_REF_DW6(phy));
return REG_FIELD_GET(GRC_CODE_MASK, val);
}
static void bxt_phy_wait_grc_done(struct drm_i915_private *dev_priv,
static void bxt_phy_wait_grc_done(struct intel_display *display,
enum dpio_phy phy)
{
if (intel_de_wait_for_set(dev_priv, BXT_PORT_REF_DW3(phy),
GRC_DONE, 10))
drm_err(&dev_priv->drm, "timeout waiting for PHY%d GRC\n",
phy);
if (intel_de_wait_for_set(display, BXT_PORT_REF_DW3(phy), GRC_DONE, 10))
drm_err(display->drm, "timeout waiting for PHY%d GRC\n", phy);
}
static void _bxt_dpio_phy_init(struct drm_i915_private *dev_priv,
enum dpio_phy phy)
static void _bxt_dpio_phy_init(struct intel_display *display, enum dpio_phy phy)
{
const struct bxt_dpio_phy_info *phy_info;
u32 val;
phy_info = bxt_get_phy_info(dev_priv, phy);
phy_info = bxt_get_phy_info(display, phy);
if (bxt_dpio_phy_is_enabled(dev_priv, phy)) {
if (bxt_dpio_phy_is_enabled(display, phy)) {
/* Still read out the GRC value for state verification */
if (phy_info->rcomp_phy != -1)
dev_priv->display.state.bxt_phy_grc = bxt_get_grc(dev_priv, phy);
display->state.bxt_phy_grc = bxt_get_grc(display, phy);
if (bxt_dpio_phy_verify_state(dev_priv, phy)) {
drm_dbg(&dev_priv->drm, "DDI PHY %d already enabled, "
if (bxt_dpio_phy_verify_state(display, phy)) {
drm_dbg(display->drm, "DDI PHY %d already enabled, "
"won't reprogram it\n", phy);
return;
}
drm_dbg(&dev_priv->drm,
drm_dbg(display->drm,
"DDI PHY %d enabled with invalid state, "
"force reprogramming it\n", phy);
}
intel_de_rmw(dev_priv, BXT_P_CR_GT_DISP_PWRON, 0, phy_info->pwron_mask);
intel_de_rmw(display, BXT_P_CR_GT_DISP_PWRON, 0, phy_info->pwron_mask);
/*
* The PHY registers start out inaccessible and respond to reads with
@ -427,92 +426,91 @@ static void _bxt_dpio_phy_init(struct drm_i915_private *dev_priv,
* The flag should get set in 100us according to the HW team, but
* use 1ms due to occasional timeouts observed with that.
*/
if (intel_de_wait_fw(dev_priv, BXT_PORT_CL1CM_DW0(phy),
if (intel_de_wait_fw(display, BXT_PORT_CL1CM_DW0(phy),
PHY_RESERVED | PHY_POWER_GOOD, PHY_POWER_GOOD, 1))
drm_err(&dev_priv->drm, "timeout during PHY%d power on\n",
drm_err(display->drm, "timeout during PHY%d power on\n",
phy);
/* Program PLL Rcomp code offset */
intel_de_rmw(dev_priv, BXT_PORT_CL1CM_DW9(phy),
intel_de_rmw(display, BXT_PORT_CL1CM_DW9(phy),
IREF0RC_OFFSET_MASK, IREF0RC_OFFSET(0xE4));
intel_de_rmw(dev_priv, BXT_PORT_CL1CM_DW10(phy),
intel_de_rmw(display, BXT_PORT_CL1CM_DW10(phy),
IREF1RC_OFFSET_MASK, IREF1RC_OFFSET(0xE4));
/* Program power gating */
intel_de_rmw(dev_priv, BXT_PORT_CL1CM_DW28(phy), 0,
intel_de_rmw(display, BXT_PORT_CL1CM_DW28(phy), 0,
OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN | SUS_CLK_CONFIG);
if (phy_info->dual_channel)
intel_de_rmw(dev_priv, BXT_PORT_CL2CM_DW6(phy), 0,
intel_de_rmw(display, BXT_PORT_CL2CM_DW6(phy), 0,
DW6_OLDO_DYN_PWR_DOWN_EN);
if (phy_info->rcomp_phy != -1) {
u32 grc_code;
bxt_phy_wait_grc_done(dev_priv, phy_info->rcomp_phy);
bxt_phy_wait_grc_done(display, phy_info->rcomp_phy);
/*
* PHY0 isn't connected to an RCOMP resistor so copy over
* the corresponding calibrated value from PHY1, and disable
* the automatic calibration on PHY0.
*/
val = bxt_get_grc(dev_priv, phy_info->rcomp_phy);
dev_priv->display.state.bxt_phy_grc = val;
val = bxt_get_grc(display, phy_info->rcomp_phy);
display->state.bxt_phy_grc = val;
grc_code = GRC_CODE_FAST(val) |
GRC_CODE_SLOW(val) |
GRC_CODE_NOM(val);
intel_de_write(dev_priv, BXT_PORT_REF_DW6(phy), grc_code);
intel_de_rmw(dev_priv, BXT_PORT_REF_DW8(phy),
intel_de_write(display, BXT_PORT_REF_DW6(phy), grc_code);
intel_de_rmw(display, BXT_PORT_REF_DW8(phy),
0, GRC_DIS | GRC_RDY_OVRD);
}
if (phy_info->reset_delay)
udelay(phy_info->reset_delay);
intel_de_rmw(dev_priv, BXT_PHY_CTL_FAMILY(phy), 0, COMMON_RESET_DIS);
intel_de_rmw(display, BXT_PHY_CTL_FAMILY(phy), 0, COMMON_RESET_DIS);
}
void bxt_dpio_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy)
void bxt_dpio_phy_uninit(struct intel_display *display, enum dpio_phy phy)
{
const struct bxt_dpio_phy_info *phy_info;
phy_info = bxt_get_phy_info(dev_priv, phy);
phy_info = bxt_get_phy_info(display, phy);
intel_de_rmw(dev_priv, BXT_PHY_CTL_FAMILY(phy), COMMON_RESET_DIS, 0);
intel_de_rmw(display, BXT_PHY_CTL_FAMILY(phy), COMMON_RESET_DIS, 0);
intel_de_rmw(dev_priv, BXT_P_CR_GT_DISP_PWRON, phy_info->pwron_mask, 0);
intel_de_rmw(display, BXT_P_CR_GT_DISP_PWRON, phy_info->pwron_mask, 0);
}
void bxt_dpio_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy)
void bxt_dpio_phy_init(struct intel_display *display, enum dpio_phy phy)
{
const struct bxt_dpio_phy_info *phy_info =
bxt_get_phy_info(dev_priv, phy);
const struct bxt_dpio_phy_info *phy_info = bxt_get_phy_info(display, phy);
enum dpio_phy rcomp_phy = phy_info->rcomp_phy;
bool was_enabled;
lockdep_assert_held(&dev_priv->display.power.domains.lock);
lockdep_assert_held(&display->power.domains.lock);
was_enabled = true;
if (rcomp_phy != -1)
was_enabled = bxt_dpio_phy_is_enabled(dev_priv, rcomp_phy);
was_enabled = bxt_dpio_phy_is_enabled(display, rcomp_phy);
/*
* We need to copy the GRC calibration value from rcomp_phy,
* so make sure it's powered up.
*/
if (!was_enabled)
_bxt_dpio_phy_init(dev_priv, rcomp_phy);
_bxt_dpio_phy_init(display, rcomp_phy);
_bxt_dpio_phy_init(dev_priv, phy);
_bxt_dpio_phy_init(display, phy);
if (!was_enabled)
bxt_dpio_phy_uninit(dev_priv, rcomp_phy);
bxt_dpio_phy_uninit(display, rcomp_phy);
}
static bool __printf(6, 7)
__phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy,
__phy_reg_verify_state(struct intel_display *display, enum dpio_phy phy,
i915_reg_t reg, u32 mask, u32 expected,
const char *reg_fmt, ...)
{
@ -520,7 +518,7 @@ __phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy,
va_list args;
u32 val;
val = intel_de_read(dev_priv, reg);
val = intel_de_read(display, reg);
if ((val & mask) == expected)
return true;
@ -528,7 +526,7 @@ __phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy,
vaf.fmt = reg_fmt;
vaf.va = &args;
drm_dbg(&dev_priv->drm, "DDI PHY %d reg %pV [%08x] state mismatch: "
drm_dbg(display->drm, "DDI PHY %d reg %pV [%08x] state mismatch: "
"current %08x, expected %08x (mask %08x)\n",
phy, &vaf, reg.reg, val, (val & ~mask) | expected,
mask);
@ -538,20 +536,20 @@ __phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy,
return false;
}
bool bxt_dpio_phy_verify_state(struct drm_i915_private *dev_priv,
bool bxt_dpio_phy_verify_state(struct intel_display *display,
enum dpio_phy phy)
{
const struct bxt_dpio_phy_info *phy_info;
u32 mask;
bool ok;
phy_info = bxt_get_phy_info(dev_priv, phy);
phy_info = bxt_get_phy_info(display, phy);
#define _CHK(reg, mask, exp, fmt, ...) \
__phy_reg_verify_state(dev_priv, phy, reg, mask, exp, fmt, \
__phy_reg_verify_state(display, phy, reg, mask, exp, fmt, \
## __VA_ARGS__)
if (!bxt_dpio_phy_is_enabled(dev_priv, phy))
if (!bxt_dpio_phy_is_enabled(display, phy))
return false;
ok = true;
@ -575,7 +573,7 @@ bool bxt_dpio_phy_verify_state(struct drm_i915_private *dev_priv,
"BXT_PORT_CL2CM_DW6(%d)", phy);
if (phy_info->rcomp_phy != -1) {
u32 grc_code = dev_priv->display.state.bxt_phy_grc;
u32 grc_code = display->state.bxt_phy_grc;
grc_code = GRC_CODE_FAST(grc_code) |
GRC_CODE_SLOW(grc_code) |
@ -614,20 +612,20 @@ bxt_dpio_phy_calc_lane_lat_optim_mask(u8 lane_count)
void bxt_dpio_phy_set_lane_optim_mask(struct intel_encoder *encoder,
u8 lane_lat_optim_mask)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
enum port port = encoder->port;
enum dpio_phy phy;
enum dpio_channel ch;
int lane;
bxt_port_to_phy_channel(dev_priv, port, &phy, &ch);
bxt_port_to_phy_channel(display, port, &phy, &ch);
for (lane = 0; lane < 4; lane++) {
/*
* Note that on CHV this flag is called UPAR, but has
* the same function.
*/
intel_de_rmw(dev_priv, BXT_PORT_TX_DW14_LN(phy, ch, lane),
intel_de_rmw(display, BXT_PORT_TX_DW14_LN(phy, ch, lane),
LATENCY_OPTIM,
lane_lat_optim_mask & BIT(lane) ? LATENCY_OPTIM : 0);
}
@ -636,18 +634,18 @@ void bxt_dpio_phy_set_lane_optim_mask(struct intel_encoder *encoder,
u8
bxt_dpio_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
enum port port = encoder->port;
enum dpio_phy phy;
enum dpio_channel ch;
int lane;
u8 mask;
bxt_port_to_phy_channel(dev_priv, port, &phy, &ch);
bxt_port_to_phy_channel(display, port, &phy, &ch);
mask = 0;
for (lane = 0; lane < 4; lane++) {
u32 val = intel_de_read(dev_priv,
u32 val = intel_de_read(display,
BXT_PORT_TX_DW14_LN(phy, ch, lane));
if (val & LATENCY_OPTIM)

View File

@ -10,9 +10,9 @@
enum pipe;
enum port;
struct drm_i915_private;
struct intel_crtc_state;
struct intel_digital_port;
struct intel_display;
struct intel_encoder;
enum dpio_channel {
@ -27,15 +27,15 @@ enum dpio_phy {
};
#ifdef I915
void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
void bxt_port_to_phy_channel(struct intel_display *display, enum port port,
enum dpio_phy *phy, enum dpio_channel *ch);
void bxt_dpio_phy_set_signal_levels(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
void bxt_dpio_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy);
void bxt_dpio_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy);
bool bxt_dpio_phy_is_enabled(struct drm_i915_private *dev_priv,
void bxt_dpio_phy_init(struct intel_display *display, enum dpio_phy phy);
void bxt_dpio_phy_uninit(struct intel_display *display, enum dpio_phy phy);
bool bxt_dpio_phy_is_enabled(struct intel_display *display,
enum dpio_phy phy);
bool bxt_dpio_phy_verify_state(struct drm_i915_private *dev_priv,
bool bxt_dpio_phy_verify_state(struct intel_display *display,
enum dpio_phy phy);
u8 bxt_dpio_phy_calc_lane_lat_optim_mask(u8 lane_count);
void bxt_dpio_phy_set_lane_optim_mask(struct intel_encoder *encoder,
@ -73,7 +73,7 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
void vlv_phy_reset_lanes(struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state);
#else
static inline void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
static inline void bxt_port_to_phy_channel(struct intel_display *display, enum port port,
enum dpio_phy *phy, enum dpio_channel *ch)
{
}
@ -81,18 +81,18 @@ static inline void bxt_dpio_phy_set_signal_levels(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
}
static inline void bxt_dpio_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy)
static inline void bxt_dpio_phy_init(struct intel_display *display, enum dpio_phy phy)
{
}
static inline void bxt_dpio_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy)
static inline void bxt_dpio_phy_uninit(struct intel_display *display, enum dpio_phy phy)
{
}
static inline bool bxt_dpio_phy_is_enabled(struct drm_i915_private *dev_priv,
static inline bool bxt_dpio_phy_is_enabled(struct intel_display *display,
enum dpio_phy phy)
{
return false;
}
static inline bool bxt_dpio_phy_verify_state(struct drm_i915_private *dev_priv,
static inline bool bxt_dpio_phy_verify_state(struct intel_display *display,
enum dpio_phy phy)
{
return true;

View File

@ -1003,6 +1003,7 @@ static u32 i9xx_dpll(const struct intel_crtc_state *crtc_state,
const struct dpll *clock,
const struct dpll *reduced_clock)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dpll;
@ -1061,7 +1062,7 @@ static u32 i9xx_dpll(const struct intel_crtc_state *crtc_state,
if (crtc_state->sdvo_tv_clock)
dpll |= PLL_REF_INPUT_TVCLKINBC;
else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
intel_panel_use_ssc(dev_priv))
intel_panel_use_ssc(display))
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
else
dpll |= PLL_REF_INPUT_DREFCLK;
@ -1095,6 +1096,7 @@ static u32 i8xx_dpll(const struct intel_crtc_state *crtc_state,
const struct dpll *clock,
const struct dpll *reduced_clock)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dpll;
@ -1131,7 +1133,7 @@ static u32 i8xx_dpll(const struct intel_crtc_state *crtc_state,
dpll |= DPLL_DVO_2X_MODE;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
intel_panel_use_ssc(dev_priv))
intel_panel_use_ssc(display))
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
else
dpll |= PLL_REF_INPUT_DREFCLK;
@ -1237,11 +1239,12 @@ static int mtl_crtc_compute_clock(struct intel_atomic_state *state,
static int ilk_fb_cb_factor(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
((intel_panel_use_ssc(i915) && i915->display.vbt.lvds_ssc_freq == 100000) ||
((intel_panel_use_ssc(display) && i915->display.vbt.lvds_ssc_freq == 100000) ||
(HAS_PCH_IBX(i915) && intel_is_dual_link_lvds(i915))))
return 25;
@ -1271,6 +1274,7 @@ static u32 ilk_dpll(const struct intel_crtc_state *crtc_state,
const struct dpll *clock,
const struct dpll *reduced_clock)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dpll;
@ -1332,7 +1336,7 @@ static u32 ilk_dpll(const struct intel_crtc_state *crtc_state,
WARN_ON(reduced_clock->p2 != clock->p2);
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
intel_panel_use_ssc(dev_priv))
intel_panel_use_ssc(display))
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
else
dpll |= PLL_REF_INPUT_DREFCLK;
@ -1356,6 +1360,7 @@ static void ilk_compute_dpll(struct intel_crtc_state *crtc_state,
static int ilk_crtc_compute_clock(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
@ -1368,7 +1373,7 @@ static int ilk_crtc_compute_clock(struct intel_atomic_state *state,
return 0;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
if (intel_panel_use_ssc(dev_priv)) {
if (intel_panel_use_ssc(display)) {
drm_dbg_kms(&dev_priv->drm,
"using SSC reference clock of %d kHz\n",
dev_priv->display.vbt.lvds_ssc_freq);
@ -1532,6 +1537,7 @@ static int vlv_crtc_compute_clock(struct intel_atomic_state *state,
static int g4x_crtc_compute_clock(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
@ -1539,7 +1545,7 @@ static int g4x_crtc_compute_clock(struct intel_atomic_state *state,
int refclk = 96000;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
if (intel_panel_use_ssc(dev_priv)) {
if (intel_panel_use_ssc(display)) {
refclk = dev_priv->display.vbt.lvds_ssc_freq;
drm_dbg_kms(&dev_priv->drm,
"using SSC reference clock of %d kHz\n",
@ -1581,6 +1587,7 @@ static int g4x_crtc_compute_clock(struct intel_atomic_state *state,
static int pnv_crtc_compute_clock(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
@ -1588,7 +1595,7 @@ static int pnv_crtc_compute_clock(struct intel_atomic_state *state,
int refclk = 96000;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
if (intel_panel_use_ssc(dev_priv)) {
if (intel_panel_use_ssc(display)) {
refclk = dev_priv->display.vbt.lvds_ssc_freq;
drm_dbg_kms(&dev_priv->drm,
"using SSC reference clock of %d kHz\n",
@ -1619,6 +1626,7 @@ static int pnv_crtc_compute_clock(struct intel_atomic_state *state,
static int i9xx_crtc_compute_clock(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
@ -1626,7 +1634,7 @@ static int i9xx_crtc_compute_clock(struct intel_atomic_state *state,
int refclk = 96000;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
if (intel_panel_use_ssc(dev_priv)) {
if (intel_panel_use_ssc(display)) {
refclk = dev_priv->display.vbt.lvds_ssc_freq;
drm_dbg_kms(&dev_priv->drm,
"using SSC reference clock of %d kHz\n",
@ -1659,6 +1667,7 @@ static int i9xx_crtc_compute_clock(struct intel_atomic_state *state,
static int i8xx_crtc_compute_clock(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
@ -1666,7 +1675,7 @@ static int i8xx_crtc_compute_clock(struct intel_atomic_state *state,
int refclk = 48000;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
if (intel_panel_use_ssc(dev_priv)) {
if (intel_panel_use_ssc(display)) {
refclk = dev_priv->display.vbt.lvds_ssc_freq;
drm_dbg_kms(&dev_priv->drm,
"using SSC reference clock of %d kHz\n",
@ -2322,12 +2331,13 @@ void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe)
static void assert_pll(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state)
{
struct intel_display *display = &dev_priv->display;
bool cur_state;
cur_state = intel_de_read(dev_priv, DPLL(dev_priv, pipe)) & DPLL_VCO_ENABLE;
I915_STATE_WARN(dev_priv, cur_state != state,
"PLL state assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
cur_state = intel_de_read(display, DPLL(display, pipe)) & DPLL_VCO_ENABLE;
INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
"PLL state assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
}
void assert_pll_enabled(struct drm_i915_private *i915, enum pipe pipe)

View File

@ -173,18 +173,19 @@ void assert_shared_dpll(struct drm_i915_private *i915,
struct intel_shared_dpll *pll,
bool state)
{
struct intel_display *display = &i915->display;
bool cur_state;
struct intel_dpll_hw_state hw_state;
if (drm_WARN(&i915->drm, !pll,
if (drm_WARN(display->drm, !pll,
"asserting DPLL %s with no DPLL\n", str_on_off(state)))
return;
cur_state = intel_dpll_get_hw_state(i915, pll, &hw_state);
I915_STATE_WARN(i915, cur_state != state,
"%s assertion failure (expected %s, current %s)\n",
pll->info->name, str_on_off(state),
str_on_off(cur_state));
INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
"%s assertion failure (expected %s, current %s)\n",
pll->info->name, str_on_off(state),
str_on_off(cur_state));
}
static enum tc_port icl_pll_id_to_tc_port(enum intel_dpll_id id)
@ -545,14 +546,15 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *i915,
static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *i915)
{
struct intel_display *display = &i915->display;
u32 val;
bool enabled;
val = intel_de_read(i915, PCH_DREF_CONTROL);
val = intel_de_read(display, PCH_DREF_CONTROL);
enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
DREF_SUPERSPREAD_SOURCE_MASK));
I915_STATE_WARN(i915, !enabled,
"PCH refclk assertion failure, should be active but is disabled\n");
INTEL_DISPLAY_STATE_WARN(display, !enabled,
"PCH refclk assertion failure, should be active but is disabled\n");
}
static void ibx_pch_dpll_enable(struct drm_i915_private *i915,
@ -2035,13 +2037,14 @@ static void bxt_ddi_pll_enable(struct drm_i915_private *i915,
struct intel_shared_dpll *pll,
const struct intel_dpll_hw_state *dpll_hw_state)
{
struct intel_display *display = &i915->display;
const struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt;
enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
enum dpio_phy phy;
enum dpio_channel ch;
u32 temp;
bxt_port_to_phy_channel(i915, port, &phy, &ch);
bxt_port_to_phy_channel(display, port, &phy, &ch);
/* Non-SSC reference */
intel_de_rmw(i915, BXT_PORT_PLL_ENABLE(port), 0, PORT_PLL_REF_SEL);
@ -2157,6 +2160,7 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *i915,
struct intel_shared_dpll *pll,
struct intel_dpll_hw_state *dpll_hw_state)
{
struct intel_display *display = &i915->display;
struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt;
enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
intel_wakeref_t wakeref;
@ -2165,7 +2169,7 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *i915,
u32 val;
bool ret;
bxt_port_to_phy_channel(i915, port, &phy, &ch);
bxt_port_to_phy_channel(display, port, &phy, &ch);
wakeref = intel_display_power_get_if_enabled(i915,
POWER_DOMAIN_DISPLAY_CORE);
@ -4619,6 +4623,7 @@ verify_single_dpll_state(struct drm_i915_private *i915,
struct intel_crtc *crtc,
const struct intel_crtc_state *new_crtc_state)
{
struct intel_display *display = &i915->display;
struct intel_dpll_hw_state dpll_hw_state = {};
u8 pipe_mask;
bool active;
@ -4626,22 +4631,22 @@ verify_single_dpll_state(struct drm_i915_private *i915,
active = intel_dpll_get_hw_state(i915, pll, &dpll_hw_state);
if (!pll->info->always_on) {
I915_STATE_WARN(i915, !pll->on && pll->active_mask,
"%s: pll in active use but not on in sw tracking\n",
pll->info->name);
I915_STATE_WARN(i915, pll->on && !pll->active_mask,
"%s: pll is on but not used by any active pipe\n",
pll->info->name);
I915_STATE_WARN(i915, pll->on != active,
"%s: pll on state mismatch (expected %i, found %i)\n",
pll->info->name, pll->on, active);
INTEL_DISPLAY_STATE_WARN(display, !pll->on && pll->active_mask,
"%s: pll in active use but not on in sw tracking\n",
pll->info->name);
INTEL_DISPLAY_STATE_WARN(display, pll->on && !pll->active_mask,
"%s: pll is on but not used by any active pipe\n",
pll->info->name);
INTEL_DISPLAY_STATE_WARN(display, pll->on != active,
"%s: pll on state mismatch (expected %i, found %i)\n",
pll->info->name, pll->on, active);
}
if (!crtc) {
I915_STATE_WARN(i915,
pll->active_mask & ~pll->state.pipe_mask,
"%s: more active pll users than references: 0x%x vs 0x%x\n",
pll->info->name, pll->active_mask, pll->state.pipe_mask);
INTEL_DISPLAY_STATE_WARN(display,
pll->active_mask & ~pll->state.pipe_mask,
"%s: more active pll users than references: 0x%x vs 0x%x\n",
pll->info->name, pll->active_mask, pll->state.pipe_mask);
return;
}
@ -4649,23 +4654,23 @@ verify_single_dpll_state(struct drm_i915_private *i915,
pipe_mask = BIT(crtc->pipe);
if (new_crtc_state->hw.active)
I915_STATE_WARN(i915, !(pll->active_mask & pipe_mask),
"%s: pll active mismatch (expected pipe %c in active mask 0x%x)\n",
pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
INTEL_DISPLAY_STATE_WARN(display, !(pll->active_mask & pipe_mask),
"%s: pll active mismatch (expected pipe %c in active mask 0x%x)\n",
pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
else
I915_STATE_WARN(i915, pll->active_mask & pipe_mask,
"%s: pll active mismatch (didn't expect pipe %c in active mask 0x%x)\n",
pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
INTEL_DISPLAY_STATE_WARN(display, pll->active_mask & pipe_mask,
"%s: pll active mismatch (didn't expect pipe %c in active mask 0x%x)\n",
pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
I915_STATE_WARN(i915, !(pll->state.pipe_mask & pipe_mask),
"%s: pll enabled crtcs mismatch (expected 0x%x in 0x%x)\n",
pll->info->name, pipe_mask, pll->state.pipe_mask);
INTEL_DISPLAY_STATE_WARN(display, !(pll->state.pipe_mask & pipe_mask),
"%s: pll enabled crtcs mismatch (expected 0x%x in 0x%x)\n",
pll->info->name, pipe_mask, pll->state.pipe_mask);
I915_STATE_WARN(i915,
pll->on && memcmp(&pll->state.hw_state, &dpll_hw_state,
sizeof(dpll_hw_state)),
"%s: pll hw state mismatch\n",
pll->info->name);
INTEL_DISPLAY_STATE_WARN(display,
pll->on && memcmp(&pll->state.hw_state, &dpll_hw_state,
sizeof(dpll_hw_state)),
"%s: pll hw state mismatch\n",
pll->info->name);
}
static bool has_alt_port_dpll(const struct intel_shared_dpll *old_pll,
@ -4678,6 +4683,7 @@ static bool has_alt_port_dpll(const struct intel_shared_dpll *old_pll,
void intel_shared_dpll_state_verify(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
@ -4693,16 +4699,16 @@ void intel_shared_dpll_state_verify(struct intel_atomic_state *state,
u8 pipe_mask = BIT(crtc->pipe);
struct intel_shared_dpll *pll = old_crtc_state->shared_dpll;
I915_STATE_WARN(i915, pll->active_mask & pipe_mask,
"%s: pll active mismatch (didn't expect pipe %c in active mask (0x%x))\n",
pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
INTEL_DISPLAY_STATE_WARN(display, pll->active_mask & pipe_mask,
"%s: pll active mismatch (didn't expect pipe %c in active mask (0x%x))\n",
pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
/* TC ports have both MG/TC and TBT PLL referenced simultaneously */
I915_STATE_WARN(i915, !has_alt_port_dpll(old_crtc_state->shared_dpll,
new_crtc_state->shared_dpll) &&
pll->state.pipe_mask & pipe_mask,
"%s: pll enabled crtcs mismatch (found pipe %c in enabled mask (0x%x))\n",
pll->info->name, pipe_name(crtc->pipe), pll->state.pipe_mask);
INTEL_DISPLAY_STATE_WARN(display, !has_alt_port_dpll(old_crtc_state->shared_dpll,
new_crtc_state->shared_dpll) &&
pll->state.pipe_mask & pipe_mask,
"%s: pll enabled crtcs mismatch (found pipe %c in enabled mask (0x%x))\n",
pll->info->name, pipe_name(crtc->pipe), pll->state.pipe_mask);
}
}

View File

@ -323,6 +323,7 @@ enum {
static void icl_native_gpio_set_value(struct drm_i915_private *dev_priv,
int gpio, bool value)
{
struct intel_display *display = &dev_priv->display;
int index;
if (drm_WARN_ON(&dev_priv->drm, DISPLAY_VER(dev_priv) == 11 && gpio >= MIPI_RESET_2))
@ -367,7 +368,7 @@ static void icl_native_gpio_set_value(struct drm_i915_private *dev_priv,
case MIPI_AVEE_EN_2:
index = gpio == MIPI_AVEE_EN_1 ? 1 : 2;
intel_de_rmw(dev_priv, GPIO(dev_priv, index),
intel_de_rmw(display, GPIO(display, index),
GPIO_CLOCK_VAL_OUT,
GPIO_CLOCK_DIR_MASK | GPIO_CLOCK_DIR_OUT |
GPIO_CLOCK_VAL_MASK | (value ? GPIO_CLOCK_VAL_OUT : 0));
@ -376,7 +377,7 @@ static void icl_native_gpio_set_value(struct drm_i915_private *dev_priv,
case MIPI_VIO_EN_2:
index = gpio == MIPI_VIO_EN_1 ? 1 : 2;
intel_de_rmw(dev_priv, GPIO(dev_priv, index),
intel_de_rmw(display, GPIO(display, index),
GPIO_DATA_VAL_OUT,
GPIO_DATA_DIR_MASK | GPIO_DATA_DIR_OUT |
GPIO_DATA_VAL_MASK | (value ? GPIO_DATA_VAL_OUT : 0));

View File

@ -417,6 +417,7 @@ static bool intel_dvo_init_dev(struct drm_i915_private *dev_priv,
struct intel_dvo *intel_dvo,
const struct intel_dvo_device *dvo)
{
struct intel_display *display = &dev_priv->display;
struct i2c_adapter *i2c;
u32 dpll[I915_MAX_PIPES];
enum pipe pipe;
@ -428,7 +429,7 @@ static bool intel_dvo_init_dev(struct drm_i915_private *dev_priv,
* special cases, but otherwise default to what's defined
* in the spec.
*/
if (intel_gmbus_is_valid_pin(dev_priv, dvo->gpio))
if (intel_gmbus_is_valid_pin(display, dvo->gpio))
gpio = dvo->gpio;
else if (dvo->type == INTEL_DVO_CHIP_LVDS)
gpio = GMBUS_PIN_SSC;
@ -440,7 +441,7 @@ static bool intel_dvo_init_dev(struct drm_i915_private *dev_priv,
* It appears that everything is on GPIOE except for panels
* on i830 laptops, which are on GPIOB (DVOA).
*/
i2c = intel_gmbus_get_adapter(dev_priv, gpio);
i2c = intel_gmbus_get_adapter(display, gpio);
intel_dvo->dev = *dvo;
@ -489,6 +490,7 @@ static bool intel_dvo_probe(struct drm_i915_private *i915,
void intel_dvo_init(struct drm_i915_private *i915)
{
struct intel_display *display = &i915->display;
struct intel_connector *connector;
struct intel_encoder *encoder;
struct intel_dvo *intel_dvo;
@ -549,7 +551,7 @@ void intel_dvo_init(struct drm_i915_private *i915)
drm_connector_init_with_ddc(&i915->drm, &connector->base,
&intel_dvo_connector_funcs,
intel_dvo_connector_type(&intel_dvo->dev),
intel_gmbus_get_adapter(i915, GMBUS_PIN_DPC));
intel_gmbus_get_adapter(display, GMBUS_PIN_DPC));
drm_connector_helper_add(&connector->base,
&intel_dvo_connector_helper_funcs);

View File

@ -349,7 +349,7 @@ static const struct intel_modifier_desc intel_modifiers[] = {
.plane_caps = INTEL_PLANE_CAP_TILING_Y,
}, {
.modifier = I915_FORMAT_MOD_X_TILED,
.display_ver = DISPLAY_VER_ALL,
.display_ver = { 0, 29 },
.plane_caps = INTEL_PLANE_CAP_TILING_X,
}, {
.modifier = DRM_FORMAT_MOD_LINEAR,

View File

@ -1347,7 +1347,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
/* Wa_14016291713 */
if ((IS_DISPLAY_VER(display, 12, 13) ||
IS_DISPLAY_VER_STEP(i915, IP_VER(14, 0), STEP_A0, STEP_C0)) &&
IS_DISPLAY_VERx100_STEP(i915, 1400, STEP_A0, STEP_C0)) &&
crtc_state->has_psr && !crtc_state->has_panel_replay) {
plane_state->no_fbc_reason = "PSR1 enabled (Wa_14016291713)";
return 0;

View File

@ -26,9 +26,10 @@ struct intel_fdi_funcs {
static void assert_fdi_tx(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state)
{
struct intel_display *display = &dev_priv->display;
bool cur_state;
if (HAS_DDI(dev_priv)) {
if (HAS_DDI(display)) {
/*
* DDI does not have a specific FDI_TX register.
*
@ -36,14 +37,14 @@ static void assert_fdi_tx(struct drm_i915_private *dev_priv,
* so pipe->transcoder cast is fine here.
*/
enum transcoder cpu_transcoder = (enum transcoder)pipe;
cur_state = intel_de_read(dev_priv,
TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)) & TRANS_DDI_FUNC_ENABLE;
cur_state = intel_de_read(display,
TRANS_DDI_FUNC_CTL(display, cpu_transcoder)) & TRANS_DDI_FUNC_ENABLE;
} else {
cur_state = intel_de_read(dev_priv, FDI_TX_CTL(pipe)) & FDI_TX_ENABLE;
cur_state = intel_de_read(display, FDI_TX_CTL(pipe)) & FDI_TX_ENABLE;
}
I915_STATE_WARN(dev_priv, cur_state != state,
"FDI TX state assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
"FDI TX state assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
}
void assert_fdi_tx_enabled(struct drm_i915_private *i915, enum pipe pipe)
@ -59,12 +60,13 @@ void assert_fdi_tx_disabled(struct drm_i915_private *i915, enum pipe pipe)
static void assert_fdi_rx(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state)
{
struct intel_display *display = &dev_priv->display;
bool cur_state;
cur_state = intel_de_read(dev_priv, FDI_RX_CTL(pipe)) & FDI_RX_ENABLE;
I915_STATE_WARN(dev_priv, cur_state != state,
"FDI RX state assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
cur_state = intel_de_read(display, FDI_RX_CTL(pipe)) & FDI_RX_ENABLE;
INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
"FDI RX state assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
}
void assert_fdi_rx_enabled(struct drm_i915_private *i915, enum pipe pipe)
@ -80,6 +82,7 @@ void assert_fdi_rx_disabled(struct drm_i915_private *i915, enum pipe pipe)
void assert_fdi_tx_pll_enabled(struct drm_i915_private *i915,
enum pipe pipe)
{
struct intel_display *display = &i915->display;
bool cur_state;
/* ILK FDI PLL is always enabled */
@ -87,23 +90,24 @@ void assert_fdi_tx_pll_enabled(struct drm_i915_private *i915,
return;
/* On Haswell, DDI ports are responsible for the FDI PLL setup */
if (HAS_DDI(i915))
if (HAS_DDI(display))
return;
cur_state = intel_de_read(i915, FDI_TX_CTL(pipe)) & FDI_TX_PLL_ENABLE;
I915_STATE_WARN(i915, !cur_state,
"FDI TX PLL assertion failure, should be active but is disabled\n");
cur_state = intel_de_read(display, FDI_TX_CTL(pipe)) & FDI_TX_PLL_ENABLE;
INTEL_DISPLAY_STATE_WARN(display, !cur_state,
"FDI TX PLL assertion failure, should be active but is disabled\n");
}
static void assert_fdi_rx_pll(struct drm_i915_private *i915,
enum pipe pipe, bool state)
{
struct intel_display *display = &i915->display;
bool cur_state;
cur_state = intel_de_read(i915, FDI_RX_CTL(pipe)) & FDI_RX_PLL_ENABLE;
I915_STATE_WARN(i915, cur_state != state,
"FDI RX PLL assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
cur_state = intel_de_read(display, FDI_RX_CTL(pipe)) & FDI_RX_PLL_ENABLE;
INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
"FDI RX PLL assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
}
void assert_fdi_rx_pll_enabled(struct drm_i915_private *i915, enum pipe pipe)

View File

@ -192,35 +192,15 @@ static void ivb_set_fifo_underrun_reporting(struct drm_device *dev,
}
}
static u32
icl_pipe_status_underrun_mask(struct drm_i915_private *dev_priv)
{
u32 mask = PIPE_STATUS_UNDERRUN;
if (DISPLAY_VER(dev_priv) >= 13)
mask |= PIPE_STATUS_SOFT_UNDERRUN_XELPD |
PIPE_STATUS_HARD_UNDERRUN_XELPD |
PIPE_STATUS_PORT_UNDERRUN_XELPD;
return mask;
}
static void bdw_set_fifo_underrun_reporting(struct drm_device *dev,
enum pipe pipe, bool enable)
{
struct drm_i915_private *dev_priv = to_i915(dev);
u32 mask = gen8_de_pipe_underrun_mask(dev_priv);
if (enable) {
if (DISPLAY_VER(dev_priv) >= 11)
intel_de_write(dev_priv,
ICL_PIPESTATUS(dev_priv, pipe),
icl_pipe_status_underrun_mask(dev_priv));
bdw_enable_pipe_irq(dev_priv, pipe, mask);
} else {
bdw_disable_pipe_irq(dev_priv, pipe, mask);
}
if (enable)
bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN);
else
bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN);
}
static void ibx_set_fifo_underrun_reporting(struct drm_device *dev,
@ -404,7 +384,6 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
{
struct intel_display *display = &dev_priv->display;
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
u32 underruns = 0;
/* We may be called too early in init, thanks BIOS! */
if (crtc == NULL)
@ -415,37 +394,10 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
crtc->cpu_fifo_underrun_disabled)
return;
/*
* Starting with display version 11, the PIPE_STAT register records
* whether an underrun has happened, and on XELPD+, it will also record
* whether the underrun was soft/hard and whether it was triggered by
* the downstream port logic. We should clear these bits (which use
* write-1-to-clear logic) too.
*
* Note that although the IIR gives us the same underrun and soft/hard
* information, PIPE_STAT is the only place we can find out whether
* the underrun was caused by the downstream port.
*/
if (DISPLAY_VER(dev_priv) >= 11) {
underruns = intel_de_read(dev_priv,
ICL_PIPESTATUS(dev_priv, pipe)) &
icl_pipe_status_underrun_mask(dev_priv);
intel_de_write(dev_priv, ICL_PIPESTATUS(dev_priv, pipe),
underruns);
}
if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) {
trace_intel_cpu_fifo_underrun(display, pipe);
if (DISPLAY_VER(dev_priv) >= 11)
drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun: %s%s%s%s\n",
pipe_name(pipe),
underruns & PIPE_STATUS_SOFT_UNDERRUN_XELPD ? "soft," : "",
underruns & PIPE_STATUS_HARD_UNDERRUN_XELPD ? "hard," : "",
underruns & PIPE_STATUS_PORT_UNDERRUN_XELPD ? "port," : "",
underruns & PIPE_STATUS_UNDERRUN ? "transcoder," : "");
else
drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
}
intel_fbc_handle_fifo_underrun_irq(&dev_priv->display);

View File

@ -48,7 +48,7 @@ struct intel_gmbus {
u32 reg0;
i915_reg_t gpio_reg;
struct i2c_algo_bit_data bit_algo;
struct drm_i915_private *i915;
struct intel_display *display;
};
enum gmbus_gpio {
@ -149,9 +149,10 @@ static const struct gmbus_pin gmbus_pins_mtp[] = {
[GMBUS_PIN_12_TC4_ICP] = { "tc4", GPIOM },
};
static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *i915,
static const struct gmbus_pin *get_gmbus_pin(struct intel_display *display,
unsigned int pin)
{
struct drm_i915_private *i915 = to_i915(display->drm);
const struct gmbus_pin *pins;
size_t size;
@ -173,7 +174,7 @@ static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *i915,
} else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) {
pins = gmbus_pins_bxt;
size = ARRAY_SIZE(gmbus_pins_bxt);
} else if (DISPLAY_VER(i915) == 9) {
} else if (DISPLAY_VER(display) == 9) {
pins = gmbus_pins_skl;
size = ARRAY_SIZE(gmbus_pins_skl);
} else if (IS_BROADWELL(i915)) {
@ -190,9 +191,9 @@ static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *i915,
return &pins[pin];
}
bool intel_gmbus_is_valid_pin(struct drm_i915_private *i915, unsigned int pin)
bool intel_gmbus_is_valid_pin(struct intel_display *display, unsigned int pin)
{
return get_gmbus_pin(i915, pin);
return get_gmbus_pin(display, pin);
}
/* Intel GPIO access functions */
@ -206,42 +207,45 @@ to_intel_gmbus(struct i2c_adapter *i2c)
}
void
intel_gmbus_reset(struct drm_i915_private *i915)
intel_gmbus_reset(struct intel_display *display)
{
intel_de_write(i915, GMBUS0(i915), 0);
intel_de_write(i915, GMBUS4(i915), 0);
intel_de_write(display, GMBUS0(display), 0);
intel_de_write(display, GMBUS4(display), 0);
}
static void pnv_gmbus_clock_gating(struct drm_i915_private *i915,
static void pnv_gmbus_clock_gating(struct intel_display *display,
bool enable)
{
/* When using bit bashing for I2C, this bit needs to be set to 1 */
intel_de_rmw(i915, DSPCLK_GATE_D(i915), PNV_GMBUSUNIT_CLOCK_GATE_DISABLE,
intel_de_rmw(display, DSPCLK_GATE_D(display),
PNV_GMBUSUNIT_CLOCK_GATE_DISABLE,
!enable ? PNV_GMBUSUNIT_CLOCK_GATE_DISABLE : 0);
}
static void pch_gmbus_clock_gating(struct drm_i915_private *i915,
static void pch_gmbus_clock_gating(struct intel_display *display,
bool enable)
{
intel_de_rmw(i915, SOUTH_DSPCLK_GATE_D, PCH_GMBUSUNIT_CLOCK_GATE_DISABLE,
intel_de_rmw(display, SOUTH_DSPCLK_GATE_D,
PCH_GMBUSUNIT_CLOCK_GATE_DISABLE,
!enable ? PCH_GMBUSUNIT_CLOCK_GATE_DISABLE : 0);
}
static void bxt_gmbus_clock_gating(struct drm_i915_private *i915,
static void bxt_gmbus_clock_gating(struct intel_display *display,
bool enable)
{
intel_de_rmw(i915, GEN9_CLKGATE_DIS_4, BXT_GMBUS_GATING_DIS,
intel_de_rmw(display, GEN9_CLKGATE_DIS_4, BXT_GMBUS_GATING_DIS,
!enable ? BXT_GMBUS_GATING_DIS : 0);
}
static u32 get_reserved(struct intel_gmbus *bus)
{
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
struct drm_i915_private *i915 = to_i915(display->drm);
u32 reserved = 0;
/* On most chips, these bits must be preserved in software. */
if (!IS_I830(i915) && !IS_I845G(i915))
reserved = intel_de_read_notrace(i915, bus->gpio_reg) &
reserved = intel_de_read_notrace(display, bus->gpio_reg) &
(GPIO_DATA_PULLUP_DISABLE | GPIO_CLOCK_PULLUP_DISABLE);
return reserved;
@ -250,31 +254,31 @@ static u32 get_reserved(struct intel_gmbus *bus)
static int get_clock(void *data)
{
struct intel_gmbus *bus = data;
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
u32 reserved = get_reserved(bus);
intel_de_write_notrace(i915, bus->gpio_reg, reserved | GPIO_CLOCK_DIR_MASK);
intel_de_write_notrace(i915, bus->gpio_reg, reserved);
intel_de_write_notrace(display, bus->gpio_reg, reserved | GPIO_CLOCK_DIR_MASK);
intel_de_write_notrace(display, bus->gpio_reg, reserved);
return (intel_de_read_notrace(i915, bus->gpio_reg) & GPIO_CLOCK_VAL_IN) != 0;
return (intel_de_read_notrace(display, bus->gpio_reg) & GPIO_CLOCK_VAL_IN) != 0;
}
static int get_data(void *data)
{
struct intel_gmbus *bus = data;
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
u32 reserved = get_reserved(bus);
intel_de_write_notrace(i915, bus->gpio_reg, reserved | GPIO_DATA_DIR_MASK);
intel_de_write_notrace(i915, bus->gpio_reg, reserved);
intel_de_write_notrace(display, bus->gpio_reg, reserved | GPIO_DATA_DIR_MASK);
intel_de_write_notrace(display, bus->gpio_reg, reserved);
return (intel_de_read_notrace(i915, bus->gpio_reg) & GPIO_DATA_VAL_IN) != 0;
return (intel_de_read_notrace(display, bus->gpio_reg) & GPIO_DATA_VAL_IN) != 0;
}
static void set_clock(void *data, int state_high)
{
struct intel_gmbus *bus = data;
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
u32 reserved = get_reserved(bus);
u32 clock_bits;
@ -284,14 +288,14 @@ static void set_clock(void *data, int state_high)
clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
GPIO_CLOCK_VAL_MASK;
intel_de_write_notrace(i915, bus->gpio_reg, reserved | clock_bits);
intel_de_posting_read(i915, bus->gpio_reg);
intel_de_write_notrace(display, bus->gpio_reg, reserved | clock_bits);
intel_de_posting_read(display, bus->gpio_reg);
}
static void set_data(void *data, int state_high)
{
struct intel_gmbus *bus = data;
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
u32 reserved = get_reserved(bus);
u32 data_bits;
@ -301,20 +305,21 @@ static void set_data(void *data, int state_high)
data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
GPIO_DATA_VAL_MASK;
intel_de_write_notrace(i915, bus->gpio_reg, reserved | data_bits);
intel_de_posting_read(i915, bus->gpio_reg);
intel_de_write_notrace(display, bus->gpio_reg, reserved | data_bits);
intel_de_posting_read(display, bus->gpio_reg);
}
static int
intel_gpio_pre_xfer(struct i2c_adapter *adapter)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
struct drm_i915_private *i915 = to_i915(display->drm);
intel_gmbus_reset(i915);
intel_gmbus_reset(display);
if (IS_PINEVIEW(i915))
pnv_gmbus_clock_gating(i915, false);
pnv_gmbus_clock_gating(display, false);
set_data(bus, 1);
set_clock(bus, 1);
@ -326,13 +331,14 @@ static void
intel_gpio_post_xfer(struct i2c_adapter *adapter)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
struct drm_i915_private *i915 = to_i915(display->drm);
set_data(bus, 1);
set_clock(bus, 1);
if (IS_PINEVIEW(i915))
pnv_gmbus_clock_gating(i915, true);
pnv_gmbus_clock_gating(display, true);
}
static void
@ -355,16 +361,17 @@ intel_gpio_setup(struct intel_gmbus *bus, i915_reg_t gpio_reg)
algo->data = bus;
}
static bool has_gmbus_irq(struct drm_i915_private *i915)
static bool has_gmbus_irq(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
/*
* encoder->shutdown() may want to use GMBUS
* after irqs have already been disabled.
*/
return HAS_GMBUS_IRQ(i915) && intel_irqs_enabled(i915);
return HAS_GMBUS_IRQ(display) && intel_irqs_enabled(i915);
}
static int gmbus_wait(struct drm_i915_private *i915, u32 status, u32 irq_en)
static int gmbus_wait(struct intel_display *display, u32 status, u32 irq_en)
{
DEFINE_WAIT(wait);
u32 gmbus2;
@ -374,21 +381,21 @@ static int gmbus_wait(struct drm_i915_private *i915, u32 status, u32 irq_en)
* we also need to check for NAKs besides the hw ready/idle signal, we
* need to wake up periodically and check that ourselves.
*/
if (!has_gmbus_irq(i915))
if (!has_gmbus_irq(display))
irq_en = 0;
add_wait_queue(&i915->display.gmbus.wait_queue, &wait);
intel_de_write_fw(i915, GMBUS4(i915), irq_en);
add_wait_queue(&display->gmbus.wait_queue, &wait);
intel_de_write_fw(display, GMBUS4(display), irq_en);
status |= GMBUS_SATOER;
ret = wait_for_us((gmbus2 = intel_de_read_fw(i915, GMBUS2(i915))) & status,
ret = wait_for_us((gmbus2 = intel_de_read_fw(display, GMBUS2(display))) & status,
2);
if (ret)
ret = wait_for((gmbus2 = intel_de_read_fw(i915, GMBUS2(i915))) & status,
ret = wait_for((gmbus2 = intel_de_read_fw(display, GMBUS2(display))) & status,
50);
intel_de_write_fw(i915, GMBUS4(i915), 0);
remove_wait_queue(&i915->display.gmbus.wait_queue, &wait);
intel_de_write_fw(display, GMBUS4(display), 0);
remove_wait_queue(&display->gmbus.wait_queue, &wait);
if (gmbus2 & GMBUS_SATOER)
return -ENXIO;
@ -397,7 +404,7 @@ static int gmbus_wait(struct drm_i915_private *i915, u32 status, u32 irq_en)
}
static int
gmbus_wait_idle(struct drm_i915_private *i915)
gmbus_wait_idle(struct intel_display *display)
{
DEFINE_WAIT(wait);
u32 irq_enable;
@ -405,33 +412,33 @@ gmbus_wait_idle(struct drm_i915_private *i915)
/* Important: The hw handles only the first bit, so set only one! */
irq_enable = 0;
if (has_gmbus_irq(i915))
if (has_gmbus_irq(display))
irq_enable = GMBUS_IDLE_EN;
add_wait_queue(&i915->display.gmbus.wait_queue, &wait);
intel_de_write_fw(i915, GMBUS4(i915), irq_enable);
add_wait_queue(&display->gmbus.wait_queue, &wait);
intel_de_write_fw(display, GMBUS4(display), irq_enable);
ret = intel_de_wait_fw(i915, GMBUS2(i915), GMBUS_ACTIVE, 0, 10);
ret = intel_de_wait_fw(display, GMBUS2(display), GMBUS_ACTIVE, 0, 10);
intel_de_write_fw(i915, GMBUS4(i915), 0);
remove_wait_queue(&i915->display.gmbus.wait_queue, &wait);
intel_de_write_fw(display, GMBUS4(display), 0);
remove_wait_queue(&display->gmbus.wait_queue, &wait);
return ret;
}
static unsigned int gmbus_max_xfer_size(struct drm_i915_private *i915)
static unsigned int gmbus_max_xfer_size(struct intel_display *display)
{
return DISPLAY_VER(i915) >= 9 ? GEN9_GMBUS_BYTE_COUNT_MAX :
return DISPLAY_VER(display) >= 9 ? GEN9_GMBUS_BYTE_COUNT_MAX :
GMBUS_BYTE_COUNT_MAX;
}
static int
gmbus_xfer_read_chunk(struct drm_i915_private *i915,
gmbus_xfer_read_chunk(struct intel_display *display,
unsigned short addr, u8 *buf, unsigned int len,
u32 gmbus0_reg, u32 gmbus1_index)
{
unsigned int size = len;
bool burst_read = len > gmbus_max_xfer_size(i915);
bool burst_read = len > gmbus_max_xfer_size(display);
bool extra_byte_added = false;
if (burst_read) {
@ -444,21 +451,21 @@ gmbus_xfer_read_chunk(struct drm_i915_private *i915,
len++;
}
size = len % 256 + 256;
intel_de_write_fw(i915, GMBUS0(i915),
intel_de_write_fw(display, GMBUS0(display),
gmbus0_reg | GMBUS_BYTE_CNT_OVERRIDE);
}
intel_de_write_fw(i915, GMBUS1(i915),
intel_de_write_fw(display, GMBUS1(display),
gmbus1_index | GMBUS_CYCLE_WAIT | (size << GMBUS_BYTE_COUNT_SHIFT) | (addr << GMBUS_SLAVE_ADDR_SHIFT) | GMBUS_SLAVE_READ | GMBUS_SW_RDY);
while (len) {
int ret;
u32 val, loop = 0;
ret = gmbus_wait(i915, GMBUS_HW_RDY, GMBUS_HW_RDY_EN);
ret = gmbus_wait(display, GMBUS_HW_RDY, GMBUS_HW_RDY_EN);
if (ret)
return ret;
val = intel_de_read_fw(i915, GMBUS3(i915));
val = intel_de_read_fw(display, GMBUS3(display));
do {
if (extra_byte_added && len == 1)
break;
@ -469,7 +476,7 @@ gmbus_xfer_read_chunk(struct drm_i915_private *i915,
if (burst_read && len == size - 4)
/* Reset the override bit */
intel_de_write_fw(i915, GMBUS0(i915), gmbus0_reg);
intel_de_write_fw(display, GMBUS0(display), gmbus0_reg);
}
return 0;
@ -486,9 +493,10 @@ gmbus_xfer_read_chunk(struct drm_i915_private *i915,
#define INTEL_GMBUS_BURST_READ_MAX_LEN 767U
static int
gmbus_xfer_read(struct drm_i915_private *i915, struct i2c_msg *msg,
gmbus_xfer_read(struct intel_display *display, struct i2c_msg *msg,
u32 gmbus0_reg, u32 gmbus1_index)
{
struct drm_i915_private *i915 = to_i915(display->drm);
u8 *buf = msg->buf;
unsigned int rx_size = msg->len;
unsigned int len;
@ -498,9 +506,9 @@ gmbus_xfer_read(struct drm_i915_private *i915, struct i2c_msg *msg,
if (HAS_GMBUS_BURST_READ(i915))
len = min(rx_size, INTEL_GMBUS_BURST_READ_MAX_LEN);
else
len = min(rx_size, gmbus_max_xfer_size(i915));
len = min(rx_size, gmbus_max_xfer_size(display));
ret = gmbus_xfer_read_chunk(i915, msg->addr, buf, len,
ret = gmbus_xfer_read_chunk(display, msg->addr, buf, len,
gmbus0_reg, gmbus1_index);
if (ret)
return ret;
@ -513,7 +521,7 @@ gmbus_xfer_read(struct drm_i915_private *i915, struct i2c_msg *msg,
}
static int
gmbus_xfer_write_chunk(struct drm_i915_private *i915,
gmbus_xfer_write_chunk(struct intel_display *display,
unsigned short addr, u8 *buf, unsigned int len,
u32 gmbus1_index)
{
@ -526,8 +534,8 @@ gmbus_xfer_write_chunk(struct drm_i915_private *i915,
len -= 1;
}
intel_de_write_fw(i915, GMBUS3(i915), val);
intel_de_write_fw(i915, GMBUS1(i915),
intel_de_write_fw(display, GMBUS3(display), val);
intel_de_write_fw(display, GMBUS1(display),
gmbus1_index | GMBUS_CYCLE_WAIT | (chunk_size << GMBUS_BYTE_COUNT_SHIFT) | (addr << GMBUS_SLAVE_ADDR_SHIFT) | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
while (len) {
int ret;
@ -537,9 +545,9 @@ gmbus_xfer_write_chunk(struct drm_i915_private *i915,
val |= *buf++ << (8 * loop);
} while (--len && ++loop < 4);
intel_de_write_fw(i915, GMBUS3(i915), val);
intel_de_write_fw(display, GMBUS3(display), val);
ret = gmbus_wait(i915, GMBUS_HW_RDY, GMBUS_HW_RDY_EN);
ret = gmbus_wait(display, GMBUS_HW_RDY, GMBUS_HW_RDY_EN);
if (ret)
return ret;
}
@ -548,7 +556,7 @@ gmbus_xfer_write_chunk(struct drm_i915_private *i915,
}
static int
gmbus_xfer_write(struct drm_i915_private *i915, struct i2c_msg *msg,
gmbus_xfer_write(struct intel_display *display, struct i2c_msg *msg,
u32 gmbus1_index)
{
u8 *buf = msg->buf;
@ -557,9 +565,9 @@ gmbus_xfer_write(struct drm_i915_private *i915, struct i2c_msg *msg,
int ret;
do {
len = min(tx_size, gmbus_max_xfer_size(i915));
len = min(tx_size, gmbus_max_xfer_size(display));
ret = gmbus_xfer_write_chunk(i915, msg->addr, buf, len,
ret = gmbus_xfer_write_chunk(display, msg->addr, buf, len,
gmbus1_index);
if (ret)
return ret;
@ -586,7 +594,7 @@ gmbus_is_index_xfer(struct i2c_msg *msgs, int i, int num)
}
static int
gmbus_index_xfer(struct drm_i915_private *i915, struct i2c_msg *msgs,
gmbus_index_xfer(struct intel_display *display, struct i2c_msg *msgs,
u32 gmbus0_reg)
{
u32 gmbus1_index = 0;
@ -602,17 +610,17 @@ gmbus_index_xfer(struct drm_i915_private *i915, struct i2c_msg *msgs,
/* GMBUS5 holds 16-bit index */
if (gmbus5)
intel_de_write_fw(i915, GMBUS5(i915), gmbus5);
intel_de_write_fw(display, GMBUS5(display), gmbus5);
if (msgs[1].flags & I2C_M_RD)
ret = gmbus_xfer_read(i915, &msgs[1], gmbus0_reg,
ret = gmbus_xfer_read(display, &msgs[1], gmbus0_reg,
gmbus1_index);
else
ret = gmbus_xfer_write(i915, &msgs[1], gmbus1_index);
ret = gmbus_xfer_write(display, &msgs[1], gmbus1_index);
/* Clear GMBUS5 after each index transfer */
if (gmbus5)
intel_de_write_fw(i915, GMBUS5(i915), 0);
intel_de_write_fw(display, GMBUS5(display), 0);
return ret;
}
@ -622,34 +630,35 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
u32 gmbus0_source)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
struct drm_i915_private *i915 = to_i915(display->drm);
int i = 0, inc, try = 0;
int ret = 0;
/* Display WA #0868: skl,bxt,kbl,cfl,glk */
if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
bxt_gmbus_clock_gating(i915, false);
bxt_gmbus_clock_gating(display, false);
else if (HAS_PCH_SPT(i915) || HAS_PCH_CNP(i915))
pch_gmbus_clock_gating(i915, false);
pch_gmbus_clock_gating(display, false);
retry:
intel_de_write_fw(i915, GMBUS0(i915), gmbus0_source | bus->reg0);
intel_de_write_fw(display, GMBUS0(display), gmbus0_source | bus->reg0);
for (; i < num; i += inc) {
inc = 1;
if (gmbus_is_index_xfer(msgs, i, num)) {
ret = gmbus_index_xfer(i915, &msgs[i],
ret = gmbus_index_xfer(display, &msgs[i],
gmbus0_source | bus->reg0);
inc = 2; /* an index transmission is two msgs */
} else if (msgs[i].flags & I2C_M_RD) {
ret = gmbus_xfer_read(i915, &msgs[i],
ret = gmbus_xfer_read(display, &msgs[i],
gmbus0_source | bus->reg0, 0);
} else {
ret = gmbus_xfer_write(i915, &msgs[i], 0);
ret = gmbus_xfer_write(display, &msgs[i], 0);
}
if (!ret)
ret = gmbus_wait(i915,
ret = gmbus_wait(display,
GMBUS_HW_WAIT_PHASE, GMBUS_HW_WAIT_EN);
if (ret == -ETIMEDOUT)
goto timeout;
@ -661,19 +670,19 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
* a STOP on the very first cycle. To simplify the code we
* unconditionally generate the STOP condition with an additional gmbus
* cycle. */
intel_de_write_fw(i915, GMBUS1(i915), GMBUS_CYCLE_STOP | GMBUS_SW_RDY);
intel_de_write_fw(display, GMBUS1(display), GMBUS_CYCLE_STOP | GMBUS_SW_RDY);
/* Mark the GMBUS interface as disabled after waiting for idle.
* We will re-enable it at the start of the next xfer,
* till then let it sleep.
*/
if (gmbus_wait_idle(i915)) {
drm_dbg_kms(&i915->drm,
if (gmbus_wait_idle(display)) {
drm_dbg_kms(display->drm,
"GMBUS [%s] timed out waiting for idle\n",
adapter->name);
ret = -ETIMEDOUT;
}
intel_de_write_fw(i915, GMBUS0(i915), 0);
intel_de_write_fw(display, GMBUS0(display), 0);
ret = ret ?: i;
goto out;
@ -692,8 +701,8 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
* it's slow responding and only answers on the 2nd retry.
*/
ret = -ENXIO;
if (gmbus_wait_idle(i915)) {
drm_dbg_kms(&i915->drm,
if (gmbus_wait_idle(display)) {
drm_dbg_kms(display->drm,
"GMBUS [%s] timed out after NAK\n",
adapter->name);
ret = -ETIMEDOUT;
@ -703,11 +712,11 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
* of resetting the GMBUS controller and so clearing the
* BUS_ERROR raised by the target's NAK.
*/
intel_de_write_fw(i915, GMBUS1(i915), GMBUS_SW_CLR_INT);
intel_de_write_fw(i915, GMBUS1(i915), 0);
intel_de_write_fw(i915, GMBUS0(i915), 0);
intel_de_write_fw(display, GMBUS1(display), GMBUS_SW_CLR_INT);
intel_de_write_fw(display, GMBUS1(display), 0);
intel_de_write_fw(display, GMBUS0(display), 0);
drm_dbg_kms(&i915->drm, "GMBUS [%s] NAK for addr: %04x %c(%d)\n",
drm_dbg_kms(display->drm, "GMBUS [%s] NAK for addr: %04x %c(%d)\n",
adapter->name, msgs[i].addr,
(msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
@ -718,7 +727,7 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
* drm_do_probe_ddc_edid, which bails out on the first -ENXIO.
*/
if (ret == -ENXIO && i == 0 && try++ == 0) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"GMBUS [%s] NAK on first message, retry\n",
adapter->name);
goto retry;
@ -727,10 +736,10 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
goto out;
timeout:
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"GMBUS [%s] timed out, falling back to bit banging on pin %d\n",
bus->adapter.name, bus->reg0 & 0xff);
intel_de_write_fw(i915, GMBUS0(i915), 0);
intel_de_write_fw(display, GMBUS0(display), 0);
/*
* Hardware may not support GMBUS over these pins? Try GPIO bitbanging
@ -741,9 +750,9 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
out:
/* Display WA #0868: skl,bxt,kbl,cfl,glk */
if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
bxt_gmbus_clock_gating(i915, true);
bxt_gmbus_clock_gating(display, true);
else if (HAS_PCH_SPT(i915) || HAS_PCH_CNP(i915))
pch_gmbus_clock_gating(i915, true);
pch_gmbus_clock_gating(display, true);
return ret;
}
@ -752,7 +761,8 @@ static int
gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
struct drm_i915_private *i915 = to_i915(display->drm);
intel_wakeref_t wakeref;
int ret;
@ -776,7 +786,8 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
int intel_gmbus_output_aksv(struct i2c_adapter *adapter)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
struct drm_i915_private *i915 = to_i915(display->drm);
u8 cmd = DRM_HDCP_DDC_AKSV;
u8 buf[DRM_HDCP_KSV_LEN] = {};
struct i2c_msg msgs[] = {
@ -797,7 +808,7 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter)
int ret;
wakeref = intel_display_power_get(i915, POWER_DOMAIN_GMBUS);
mutex_lock(&i915->display.gmbus.mutex);
mutex_lock(&display->gmbus.mutex);
/*
* In order to output Aksv to the receiver, use an indexed write to
@ -806,7 +817,7 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter)
*/
ret = do_gmbus_xfer(adapter, msgs, ARRAY_SIZE(msgs), GMBUS_AKSV_SELECT);
mutex_unlock(&i915->display.gmbus.mutex);
mutex_unlock(&display->gmbus.mutex);
intel_display_power_put(i915, POWER_DOMAIN_GMBUS, wakeref);
return ret;
@ -830,27 +841,27 @@ static void gmbus_lock_bus(struct i2c_adapter *adapter,
unsigned int flags)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
mutex_lock(&i915->display.gmbus.mutex);
mutex_lock(&display->gmbus.mutex);
}
static int gmbus_trylock_bus(struct i2c_adapter *adapter,
unsigned int flags)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
return mutex_trylock(&i915->display.gmbus.mutex);
return mutex_trylock(&display->gmbus.mutex);
}
static void gmbus_unlock_bus(struct i2c_adapter *adapter,
unsigned int flags)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
mutex_unlock(&i915->display.gmbus.mutex);
mutex_unlock(&display->gmbus.mutex);
}
static const struct i2c_lock_operations gmbus_lock_ops = {
@ -861,31 +872,32 @@ static const struct i2c_lock_operations gmbus_lock_ops = {
/**
* intel_gmbus_setup - instantiate all Intel i2c GMBuses
* @i915: i915 device private
* @display: display device
*/
int intel_gmbus_setup(struct drm_i915_private *i915)
int intel_gmbus_setup(struct intel_display *display)
{
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
struct drm_i915_private *i915 = to_i915(display->drm);
struct pci_dev *pdev = to_pci_dev(display->drm->dev);
unsigned int pin;
int ret;
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
i915->display.gmbus.mmio_base = VLV_DISPLAY_BASE;
else if (!HAS_GMCH(i915))
display->gmbus.mmio_base = VLV_DISPLAY_BASE;
else if (!HAS_GMCH(display))
/*
* Broxton uses the same PCH offsets for South Display Engine,
* even though it doesn't have a PCH.
*/
i915->display.gmbus.mmio_base = PCH_DISPLAY_BASE;
display->gmbus.mmio_base = PCH_DISPLAY_BASE;
mutex_init(&i915->display.gmbus.mutex);
init_waitqueue_head(&i915->display.gmbus.wait_queue);
mutex_init(&display->gmbus.mutex);
init_waitqueue_head(&display->gmbus.wait_queue);
for (pin = 0; pin < ARRAY_SIZE(i915->display.gmbus.bus); pin++) {
for (pin = 0; pin < ARRAY_SIZE(display->gmbus.bus); pin++) {
const struct gmbus_pin *gmbus_pin;
struct intel_gmbus *bus;
gmbus_pin = get_gmbus_pin(i915, pin);
gmbus_pin = get_gmbus_pin(display, pin);
if (!gmbus_pin)
continue;
@ -901,7 +913,7 @@ int intel_gmbus_setup(struct drm_i915_private *i915)
"i915 gmbus %s", gmbus_pin->name);
bus->adapter.dev.parent = &pdev->dev;
bus->i915 = i915;
bus->display = display;
bus->adapter.algo = &gmbus_algorithm;
bus->adapter.lock_ops = &gmbus_lock_ops;
@ -919,7 +931,7 @@ int intel_gmbus_setup(struct drm_i915_private *i915)
if (IS_I830(i915))
bus->force_bit = 1;
intel_gpio_setup(bus, GPIO(i915, gmbus_pin->gpio));
intel_gpio_setup(bus, GPIO(display, gmbus_pin->gpio));
ret = i2c_add_adapter(&bus->adapter);
if (ret) {
@ -927,43 +939,43 @@ int intel_gmbus_setup(struct drm_i915_private *i915)
goto err;
}
i915->display.gmbus.bus[pin] = bus;
display->gmbus.bus[pin] = bus;
}
intel_gmbus_reset(i915);
intel_gmbus_reset(display);
return 0;
err:
intel_gmbus_teardown(i915);
intel_gmbus_teardown(display);
return ret;
}
struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *i915,
struct i2c_adapter *intel_gmbus_get_adapter(struct intel_display *display,
unsigned int pin)
{
if (drm_WARN_ON(&i915->drm, pin >= ARRAY_SIZE(i915->display.gmbus.bus) ||
!i915->display.gmbus.bus[pin]))
if (drm_WARN_ON(display->drm, pin >= ARRAY_SIZE(display->gmbus.bus) ||
!display->gmbus.bus[pin]))
return NULL;
return &i915->display.gmbus.bus[pin]->adapter;
return &display->gmbus.bus[pin]->adapter;
}
void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
struct drm_i915_private *i915 = bus->i915;
struct intel_display *display = bus->display;
mutex_lock(&i915->display.gmbus.mutex);
mutex_lock(&display->gmbus.mutex);
bus->force_bit += force_bit ? 1 : -1;
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"%sabling bit-banging on %s. force bit now %d\n",
force_bit ? "en" : "dis", adapter->name,
bus->force_bit);
mutex_unlock(&i915->display.gmbus.mutex);
mutex_unlock(&display->gmbus.mutex);
}
bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
@ -973,25 +985,25 @@ bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
return bus->force_bit;
}
void intel_gmbus_teardown(struct drm_i915_private *i915)
void intel_gmbus_teardown(struct intel_display *display)
{
unsigned int pin;
for (pin = 0; pin < ARRAY_SIZE(i915->display.gmbus.bus); pin++) {
for (pin = 0; pin < ARRAY_SIZE(display->gmbus.bus); pin++) {
struct intel_gmbus *bus;
bus = i915->display.gmbus.bus[pin];
bus = display->gmbus.bus[pin];
if (!bus)
continue;
i2c_del_adapter(&bus->adapter);
kfree(bus);
i915->display.gmbus.bus[pin] = NULL;
display->gmbus.bus[pin] = NULL;
}
}
void intel_gmbus_irq_handler(struct drm_i915_private *i915)
void intel_gmbus_irq_handler(struct intel_display *display)
{
wake_up_all(&i915->display.gmbus.wait_queue);
wake_up_all(&display->gmbus.wait_queue);
}

View File

@ -8,8 +8,8 @@
#include <linux/types.h>
struct drm_i915_private;
struct i2c_adapter;
struct intel_display;
#define GMBUS_PIN_DISABLED 0
#define GMBUS_PIN_SSC 1
@ -34,18 +34,17 @@ struct i2c_adapter;
#define GMBUS_NUM_PINS 15 /* including 0 */
int intel_gmbus_setup(struct drm_i915_private *dev_priv);
void intel_gmbus_teardown(struct drm_i915_private *dev_priv);
bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv,
unsigned int pin);
int intel_gmbus_setup(struct intel_display *display);
void intel_gmbus_teardown(struct intel_display *display);
bool intel_gmbus_is_valid_pin(struct intel_display *display, unsigned int pin);
int intel_gmbus_output_aksv(struct i2c_adapter *adapter);
struct i2c_adapter *
intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, unsigned int pin);
intel_gmbus_get_adapter(struct intel_display *display, unsigned int pin);
void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter);
void intel_gmbus_reset(struct drm_i915_private *dev_priv);
void intel_gmbus_reset(struct intel_display *display);
void intel_gmbus_irq_handler(struct drm_i915_private *i915);
void intel_gmbus_irq_handler(struct intel_display *display);
#endif /* __INTEL_GMBUS_H__ */

View File

@ -8,9 +8,9 @@
#include "i915_reg_defs.h"
#define GMBUS_MMIO_BASE(__i915) ((__i915)->display.gmbus.mmio_base)
#define __GMBUS_MMIO_BASE(__display) ((__display)->gmbus.mmio_base)
#define GPIO(__i915, gpio) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x5010 + 4 * (gpio))
#define GPIO(__display, gpio) _MMIO(__GMBUS_MMIO_BASE(__display) + 0x5010 + 4 * (gpio))
#define GPIO_CLOCK_DIR_MASK (1 << 0)
#define GPIO_CLOCK_DIR_IN (0 << 1)
#define GPIO_CLOCK_DIR_OUT (1 << 1)
@ -27,7 +27,7 @@
#define GPIO_DATA_PULLUP_DISABLE (1 << 13)
/* clock/port select */
#define GMBUS0(__i915) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x5100)
#define GMBUS0(__display) _MMIO(__GMBUS_MMIO_BASE(__display) + 0x5100)
#define GMBUS_AKSV_SELECT (1 << 11)
#define GMBUS_RATE_100KHZ (0 << 8)
#define GMBUS_RATE_50KHZ (1 << 8)
@ -37,7 +37,7 @@
#define GMBUS_BYTE_CNT_OVERRIDE (1 << 6)
/* command/status */
#define GMBUS1(__i915) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x5104)
#define GMBUS1(__display) _MMIO(__GMBUS_MMIO_BASE(__display) + 0x5104)
#define GMBUS_SW_CLR_INT (1 << 31)
#define GMBUS_SW_RDY (1 << 30)
#define GMBUS_ENT (1 << 29) /* enable timeout */
@ -54,7 +54,7 @@
#define GMBUS_SLAVE_WRITE (0 << 0)
/* status */
#define GMBUS2(__i915) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x5108)
#define GMBUS2(__display) _MMIO(__GMBUS_MMIO_BASE(__display) + 0x5108)
#define GMBUS_INUSE (1 << 15)
#define GMBUS_HW_WAIT_PHASE (1 << 14)
#define GMBUS_STALL_TIMEOUT (1 << 13)
@ -64,10 +64,10 @@
#define GMBUS_ACTIVE (1 << 9)
/* data buffer bytes 3-0 */
#define GMBUS3(__i915) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x510c)
#define GMBUS3(__display) _MMIO(__GMBUS_MMIO_BASE(__display) + 0x510c)
/* interrupt mask (Pineview+) */
#define GMBUS4(__i915) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x5110)
#define GMBUS4(__display) _MMIO(__GMBUS_MMIO_BASE(__display) + 0x5110)
#define GMBUS_SLAVE_TIMEOUT_EN (1 << 4)
#define GMBUS_NAK_EN (1 << 3)
#define GMBUS_IDLE_EN (1 << 2)
@ -75,7 +75,7 @@
#define GMBUS_HW_RDY_EN (1 << 0)
/* byte index */
#define GMBUS5(__i915) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x5120)
#define GMBUS5(__display) _MMIO(__GMBUS_MMIO_BASE(__display) + 0x5120)
#define GMBUS_2BYTE_INDEX_EN (1 << 31)
#endif /* __INTEL_GMBUS_REGS_H__ */

View File

@ -43,11 +43,11 @@ intel_hdcp_disable_hdcp_line_rekeying(struct intel_encoder *encoder,
return;
if (DISPLAY_VER(display) >= 14) {
if (IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_D0, STEP_FOREVER))
if (IS_DISPLAY_VERx100_STEP(display, 1400, STEP_D0, STEP_FOREVER))
intel_de_rmw(display, MTL_CHICKEN_TRANS(hdcp->cpu_transcoder),
0, HDCP_LINE_REKEY_DISABLE);
else if (IS_DISPLAY_VER_STEP(display, IP_VER(14, 1), STEP_B0, STEP_FOREVER) ||
IS_DISPLAY_VER_STEP(display, IP_VER(20, 0), STEP_B0, STEP_FOREVER))
else if (IS_DISPLAY_VERx100_STEP(display, 1401, STEP_B0, STEP_FOREVER) ||
IS_DISPLAY_VERx100_STEP(display, 2000, STEP_B0, STEP_FOREVER))
intel_de_rmw(display,
TRANS_DDI_FUNC_CTL(display, hdcp->cpu_transcoder),
0, TRANS_DDI_HDCP_LINE_REKEY_DISABLE);
@ -1192,10 +1192,10 @@ static void intel_hdcp_prop_work(struct work_struct *work)
drm_connector_put(&connector->base);
}
bool is_hdcp_supported(struct drm_i915_private *i915, enum port port)
bool is_hdcp_supported(struct intel_display *display, enum port port)
{
return DISPLAY_RUNTIME_INFO(i915)->has_hdcp &&
(DISPLAY_VER(i915) >= 12 || port < PORT_E);
return DISPLAY_RUNTIME_INFO(display)->has_hdcp &&
(DISPLAY_VER(display) >= 12 || port < PORT_E);
}
static int
@ -2301,9 +2301,9 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
return 0;
}
static bool is_hdcp2_supported(struct drm_i915_private *i915)
static bool is_hdcp2_supported(struct intel_display *display)
{
struct intel_display *display = to_intel_display(&i915->drm);
struct drm_i915_private *i915 = to_i915(display->drm);
if (intel_hdcp_gsc_cs_required(display))
return true;
@ -2317,12 +2317,11 @@ static bool is_hdcp2_supported(struct drm_i915_private *i915)
IS_COMETLAKE(i915));
}
void intel_hdcp_component_init(struct drm_i915_private *i915)
void intel_hdcp_component_init(struct intel_display *display)
{
struct intel_display *display = to_intel_display(&i915->drm);
int ret;
if (!is_hdcp2_supported(i915))
if (!is_hdcp2_supported(display))
return;
mutex_lock(&display->hdcp.hdcp_mutex);
@ -2367,19 +2366,18 @@ int intel_hdcp_init(struct intel_connector *connector,
struct intel_digital_port *dig_port,
const struct intel_hdcp_shim *shim)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
struct intel_hdcp *hdcp = &connector->hdcp;
int ret;
if (!shim)
return -EINVAL;
if (is_hdcp2_supported(i915))
if (is_hdcp2_supported(display))
intel_hdcp2_init(connector, dig_port, shim);
ret =
drm_connector_attach_content_protection_property(&connector->base,
hdcp->hdcp2_supported);
ret = drm_connector_attach_content_protection_property(&connector->base,
hdcp->hdcp2_supported);
if (ret) {
hdcp->hdcp2_supported = false;
kfree(dig_port->hdcp_port_data.streams);
@ -2432,7 +2430,7 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state,
hdcp->stream_transcoder = INVALID_TRANSCODER;
}
if (DISPLAY_VER(i915) >= 12)
if (DISPLAY_VER(display) >= 12)
dig_port->hdcp_port_data.hdcp_transcoder =
intel_get_hdcp_transcoder(hdcp->cpu_transcoder);
@ -2583,10 +2581,8 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
_intel_hdcp_enable(state, encoder, crtc_state, conn_state);
}
void intel_hdcp_component_fini(struct drm_i915_private *i915)
void intel_hdcp_component_fini(struct intel_display *display)
{
struct intel_display *display = to_intel_display(&i915->drm);
mutex_lock(&display->hdcp.hdcp_mutex);
if (!display->hdcp.comp_added) {
mutex_unlock(&display->hdcp.hdcp_mutex);

View File

@ -12,13 +12,13 @@
struct drm_connector;
struct drm_connector_state;
struct drm_i915_private;
struct intel_atomic_state;
struct intel_connector;
struct intel_crtc_state;
struct intel_digital_port;
struct intel_display;
struct intel_encoder;
struct intel_hdcp_shim;
struct intel_digital_port;
enum port;
enum transcoder;
@ -37,14 +37,14 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
bool is_hdcp_supported(struct drm_i915_private *i915, enum port port);
bool is_hdcp_supported(struct intel_display *display, enum port port);
bool intel_hdcp_get_capability(struct intel_connector *connector);
bool intel_hdcp2_get_capability(struct intel_connector *connector);
void intel_hdcp_get_remote_capability(struct intel_connector *connector,
bool *hdcp_capable,
bool *hdcp2_capable);
void intel_hdcp_component_init(struct drm_i915_private *i915);
void intel_hdcp_component_fini(struct drm_i915_private *i915);
void intel_hdcp_component_init(struct intel_display *display);
void intel_hdcp_component_fini(struct intel_display *display);
void intel_hdcp_cleanup(struct intel_connector *connector);
void intel_hdcp_handle_cp_irq(struct intel_connector *connector);

View File

@ -62,6 +62,7 @@
#include "intel_hdmi.h"
#include "intel_lspcon.h"
#include "intel_panel.h"
#include "intel_pfit.h"
#include "intel_snps_phy.h"
static void
@ -1211,6 +1212,30 @@ static void vlv_set_infoframes(struct intel_encoder *encoder,
&crtc_state->infoframes.hdmi);
}
void intel_hdmi_fastset_infoframes(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(encoder);
i915_reg_t reg = HSW_TVIDEO_DIP_CTL(display,
crtc_state->cpu_transcoder);
u32 val = intel_de_read(display, reg);
if ((crtc_state->infoframes.enable &
intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_DRM)) == 0 &&
(val & VIDEO_DIP_ENABLE_DRM_GLK) == 0)
return;
val &= ~(VIDEO_DIP_ENABLE_DRM_GLK);
intel_de_write(display, reg, val);
intel_de_posting_read(display, reg);
intel_write_infoframe(encoder, crtc_state,
HDMI_INFOFRAME_TYPE_DRM,
&crtc_state->infoframes.drm);
}
static void hsw_set_infoframes(struct intel_encoder *encoder,
bool enable,
const struct intel_crtc_state *crtc_state,
@ -2917,7 +2942,6 @@ static struct intel_encoder *
get_encoder_by_ddc_pin(struct intel_encoder *encoder, u8 ddc_pin)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_encoder *other;
for_each_intel_encoder(display->drm, other) {
@ -2931,7 +2955,7 @@ get_encoder_by_ddc_pin(struct intel_encoder *encoder, u8 ddc_pin)
connector = enc_to_dig_port(other)->hdmi.attached_connector;
if (connector && connector->base.ddc == intel_gmbus_get_adapter(i915, ddc_pin))
if (connector && connector->base.ddc == intel_gmbus_get_adapter(display, ddc_pin))
return other;
}
@ -2941,7 +2965,6 @@ get_encoder_by_ddc_pin(struct intel_encoder *encoder, u8 ddc_pin)
static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_encoder *other;
const char *source;
u8 ddc_pin;
@ -2954,7 +2977,7 @@ static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder)
source = "platform default";
}
if (!intel_gmbus_is_valid_pin(i915, ddc_pin)) {
if (!intel_gmbus_is_valid_pin(display, ddc_pin)) {
drm_dbg_kms(display->drm,
"[ENCODER:%d:%s] Invalid DDC pin %d\n",
encoder->base.base.id, encoder->base.name, ddc_pin);
@ -3027,7 +3050,6 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port,
struct intel_hdmi *intel_hdmi = &dig_port->hdmi;
struct intel_encoder *intel_encoder = &dig_port->base;
struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
enum port port = intel_encoder->port;
struct cec_connector_info conn_info;
u8 ddc_pin;
@ -3052,7 +3074,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port,
drm_connector_init_with_ddc(dev, connector,
&intel_hdmi_connector_funcs,
DRM_MODE_CONNECTOR_HDMIA,
intel_gmbus_get_adapter(dev_priv, ddc_pin));
intel_gmbus_get_adapter(display, ddc_pin));
drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
@ -3077,7 +3099,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port,
intel_connector_attach_encoder(intel_connector, intel_encoder);
intel_hdmi->attached_connector = intel_connector;
if (is_hdcp_supported(dev_priv, port)) {
if (is_hdcp_supported(display, port)) {
int ret = intel_hdcp_init(intel_connector, dig_port,
&intel_hdmi_hdcp_shim);
if (ret)

View File

@ -42,6 +42,9 @@ u32 intel_hdmi_infoframes_enabled(struct intel_encoder *encoder,
u32 intel_hdmi_infoframe_enable(unsigned int type);
void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state);
void intel_hdmi_fastset_infoframes(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
void intel_read_infoframe(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
enum hdmi_infoframe_type type,

View File

@ -556,6 +556,7 @@ void xelpdp_pica_irq_handler(struct drm_i915_private *i915, u32 iir)
void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
{
struct intel_display *display = &dev_priv->display;
u32 ddi_hotplug_trigger = pch_iir & SDE_DDI_HOTPLUG_MASK_ICP;
u32 tc_hotplug_trigger = pch_iir & SDE_TC_HOTPLUG_MASK_ICP;
u32 pin_mask = 0, long_mask = 0;
@ -589,11 +590,12 @@ void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
if (pch_iir & SDE_GMBUS_ICP)
intel_gmbus_irq_handler(dev_priv);
intel_gmbus_irq_handler(display);
}
void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
{
struct intel_display *display = &dev_priv->display;
u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT &
~SDE_PORTE_HOTPLUG_SPT;
u32 hotplug2_trigger = pch_iir & SDE_PORTE_HOTPLUG_SPT;
@ -625,7 +627,7 @@ void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
if (pch_iir & SDE_GMBUS_CPT)
intel_gmbus_irq_handler(dev_priv);
intel_gmbus_irq_handler(display);
}
void ilk_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_trigger)

View File

@ -52,6 +52,7 @@
#include "intel_lvds.h"
#include "intel_lvds_regs.h"
#include "intel_panel.h"
#include "intel_pfit.h"
#include "intel_pps_regs.h"
/* Private structure for the integrated LVDS support */
@ -900,7 +901,7 @@ void intel_lvds_init(struct drm_i915_private *i915)
drm_connector_init_with_ddc(&i915->drm, &connector->base,
&intel_lvds_connector_funcs,
DRM_MODE_CONNECTOR_LVDS,
intel_gmbus_get_adapter(i915, ddc_pin));
intel_gmbus_get_adapter(display, ddc_pin));
drm_encoder_init(&i915->drm, &encoder->base, &intel_lvds_enc_funcs,
DRM_MODE_ENCODER_LVDS, "LVDS");

View File

@ -27,6 +27,7 @@ static void intel_connector_verify_state(const struct intel_crtc_state *crtc_sta
const struct drm_connector_state *conn_state)
{
struct intel_connector *connector = to_intel_connector(conn_state->connector);
struct intel_display *display = to_intel_display(connector);
struct drm_i915_private *i915 = to_i915(connector->base.dev);
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]\n",
@ -35,29 +36,29 @@ static void intel_connector_verify_state(const struct intel_crtc_state *crtc_sta
if (connector->get_hw_state(connector)) {
struct intel_encoder *encoder = intel_attached_encoder(connector);
I915_STATE_WARN(i915, !crtc_state,
"connector enabled without attached crtc\n");
INTEL_DISPLAY_STATE_WARN(display, !crtc_state,
"connector enabled without attached crtc\n");
if (!crtc_state)
return;
I915_STATE_WARN(i915, !crtc_state->hw.active,
"connector is active, but attached crtc isn't\n");
INTEL_DISPLAY_STATE_WARN(display, !crtc_state->hw.active,
"connector is active, but attached crtc isn't\n");
if (!encoder || encoder->type == INTEL_OUTPUT_DP_MST)
return;
I915_STATE_WARN(i915,
conn_state->best_encoder != &encoder->base,
"atomic encoder doesn't match attached encoder\n");
INTEL_DISPLAY_STATE_WARN(display,
conn_state->best_encoder != &encoder->base,
"atomic encoder doesn't match attached encoder\n");
I915_STATE_WARN(i915, conn_state->crtc != encoder->base.crtc,
"attached encoder crtc differs from connector crtc\n");
INTEL_DISPLAY_STATE_WARN(display, conn_state->crtc != encoder->base.crtc,
"attached encoder crtc differs from connector crtc\n");
} else {
I915_STATE_WARN(i915, crtc_state && crtc_state->hw.active,
"attached crtc is active, but connector isn't\n");
I915_STATE_WARN(i915, !crtc_state && conn_state->best_encoder,
"best encoder set without crtc!\n");
INTEL_DISPLAY_STATE_WARN(display, crtc_state && crtc_state->hw.active,
"attached crtc is active, but connector isn't\n");
INTEL_DISPLAY_STATE_WARN(display, !crtc_state && conn_state->best_encoder,
"best encoder set without crtc!\n");
}
}
@ -65,6 +66,7 @@ static void
verify_connector_state(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
struct drm_connector *connector;
const struct drm_connector_state *new_conn_state;
int i;
@ -81,8 +83,8 @@ verify_connector_state(struct intel_atomic_state *state,
intel_connector_verify_state(crtc_state, new_conn_state);
I915_STATE_WARN(to_i915(connector->dev), new_conn_state->best_encoder != encoder,
"connector's atomic encoder doesn't match legacy encoder\n");
INTEL_DISPLAY_STATE_WARN(display, new_conn_state->best_encoder != encoder,
"connector's atomic encoder doesn't match legacy encoder\n");
}
}
@ -109,6 +111,7 @@ static void intel_pipe_config_sanity_check(const struct intel_crtc_state *crtc_s
static void
verify_encoder_state(struct intel_atomic_state *state)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *i915 = to_i915(state->base.dev);
struct intel_encoder *encoder;
struct drm_connector *connector;
@ -134,25 +137,25 @@ verify_encoder_state(struct intel_atomic_state *state)
found = true;
enabled = true;
I915_STATE_WARN(i915,
new_conn_state->crtc != encoder->base.crtc,
"connector's crtc doesn't match encoder crtc\n");
INTEL_DISPLAY_STATE_WARN(display,
new_conn_state->crtc != encoder->base.crtc,
"connector's crtc doesn't match encoder crtc\n");
}
if (!found)
continue;
I915_STATE_WARN(i915, !!encoder->base.crtc != enabled,
"encoder's enabled state mismatch (expected %i, found %i)\n",
!!encoder->base.crtc, enabled);
INTEL_DISPLAY_STATE_WARN(display, !!encoder->base.crtc != enabled,
"encoder's enabled state mismatch (expected %i, found %i)\n",
!!encoder->base.crtc, enabled);
if (!encoder->base.crtc) {
bool active;
active = encoder->get_hw_state(encoder, &pipe);
I915_STATE_WARN(i915, active,
"encoder detached but still enabled on pipe %c.\n",
pipe_name(pipe));
INTEL_DISPLAY_STATE_WARN(display, active,
"encoder detached but still enabled on pipe %c.\n",
pipe_name(pipe));
}
}
}
@ -161,8 +164,8 @@ static void
verify_crtc_state(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *i915 = to_i915(display->drm);
const struct intel_crtc_state *sw_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct intel_crtc_state *hw_crtc_state;
@ -173,7 +176,7 @@ verify_crtc_state(struct intel_atomic_state *state,
if (!hw_crtc_state)
return;
drm_dbg_kms(&i915->drm, "[CRTC:%d:%s]\n", crtc->base.base.id,
drm_dbg_kms(display->drm, "[CRTC:%d:%s]\n", crtc->base.base.id,
crtc->base.name);
hw_crtc_state->hw.enable = sw_crtc_state->hw.enable;
@ -184,30 +187,30 @@ verify_crtc_state(struct intel_atomic_state *state,
if (IS_I830(i915) && hw_crtc_state->hw.active)
hw_crtc_state->hw.active = sw_crtc_state->hw.active;
I915_STATE_WARN(i915,
sw_crtc_state->hw.active != hw_crtc_state->hw.active,
"crtc active state doesn't match with hw state (expected %i, found %i)\n",
sw_crtc_state->hw.active, hw_crtc_state->hw.active);
INTEL_DISPLAY_STATE_WARN(display,
sw_crtc_state->hw.active != hw_crtc_state->hw.active,
"crtc active state doesn't match with hw state (expected %i, found %i)\n",
sw_crtc_state->hw.active, hw_crtc_state->hw.active);
I915_STATE_WARN(i915, crtc->active != sw_crtc_state->hw.active,
"transitional active state does not match atomic hw state (expected %i, found %i)\n",
sw_crtc_state->hw.active, crtc->active);
INTEL_DISPLAY_STATE_WARN(display, crtc->active != sw_crtc_state->hw.active,
"transitional active state does not match atomic hw state (expected %i, found %i)\n",
sw_crtc_state->hw.active, crtc->active);
primary_crtc = intel_primary_crtc(sw_crtc_state);
for_each_encoder_on_crtc(dev, &primary_crtc->base, encoder) {
for_each_encoder_on_crtc(display->drm, &primary_crtc->base, encoder) {
enum pipe pipe;
bool active;
active = encoder->get_hw_state(encoder, &pipe);
I915_STATE_WARN(i915, active != sw_crtc_state->hw.active,
"[ENCODER:%i] active %i with crtc active %i\n",
encoder->base.base.id, active,
sw_crtc_state->hw.active);
INTEL_DISPLAY_STATE_WARN(display, active != sw_crtc_state->hw.active,
"[ENCODER:%i] active %i with crtc active %i\n",
encoder->base.base.id, active,
sw_crtc_state->hw.active);
I915_STATE_WARN(i915, active && primary_crtc->pipe != pipe,
"Encoder connected to wrong pipe %c\n",
pipe_name(pipe));
INTEL_DISPLAY_STATE_WARN(display, active && primary_crtc->pipe != pipe,
"Encoder connected to wrong pipe %c\n",
pipe_name(pipe));
if (active)
intel_encoder_get_config(encoder, hw_crtc_state);
@ -220,7 +223,7 @@ verify_crtc_state(struct intel_atomic_state *state,
if (!intel_pipe_config_compare(sw_crtc_state,
hw_crtc_state, false)) {
I915_STATE_WARN(i915, 1, "pipe state doesn't match!\n");
INTEL_DISPLAY_STATE_WARN(display, 1, "pipe state doesn't match!\n");
intel_crtc_state_dump(hw_crtc_state, NULL, "hw state");
intel_crtc_state_dump(sw_crtc_state, NULL, "sw state");
}

View File

@ -33,22 +33,19 @@
#include <drm/drm_edid.h>
#include "i915_reg.h"
#include "i915_drv.h"
#include "intel_backlight.h"
#include "intel_connector.h"
#include "intel_de.h"
#include "intel_display_core.h"
#include "intel_display_driver.h"
#include "intel_display_types.h"
#include "intel_drrs.h"
#include "intel_lvds_regs.h"
#include "intel_panel.h"
#include "intel_quirks.h"
#include "intel_vrr.h"
bool intel_panel_use_ssc(struct drm_i915_private *i915)
bool intel_panel_use_ssc(struct intel_display *display)
{
struct intel_display *display = &i915->display;
if (display->params.panel_use_ssc >= 0)
return display->params.panel_use_ssc != 0;
return display->vbt.lvds_use_ssc &&
@ -252,7 +249,7 @@ int intel_panel_compute_config(struct intel_connector *connector,
static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connector)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
const struct drm_display_mode *preferred_mode =
intel_panel_preferred_fixed_mode(connector);
struct drm_display_mode *mode, *next;
@ -261,7 +258,7 @@ static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connect
if (!is_alt_fixed_mode(mode, preferred_mode))
continue;
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"[CONNECTOR:%d:%s] using alternate EDID fixed mode: " DRM_MODE_FMT "\n",
connector->base.base.id, connector->base.name,
DRM_MODE_ARG(mode));
@ -272,7 +269,7 @@ static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connect
static void intel_panel_add_edid_preferred_mode(struct intel_connector *connector)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
struct drm_display_mode *scan, *fixed_mode = NULL;
if (list_empty(&connector->base.probed_modes))
@ -290,7 +287,7 @@ static void intel_panel_add_edid_preferred_mode(struct intel_connector *connecto
fixed_mode = list_first_entry(&connector->base.probed_modes,
typeof(*fixed_mode), head);
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"[CONNECTOR:%d:%s] using %s EDID fixed mode: " DRM_MODE_FMT "\n",
connector->base.base.id, connector->base.name,
fixed_mode->type & DRM_MODE_TYPE_PREFERRED ? "preferred" : "first",
@ -303,16 +300,16 @@ static void intel_panel_add_edid_preferred_mode(struct intel_connector *connecto
static void intel_panel_destroy_probed_modes(struct intel_connector *connector)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
struct drm_display_mode *mode, *next;
list_for_each_entry_safe(mode, next, &connector->base.probed_modes, head) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[CONNECTOR:%d:%s] not using EDID mode: " DRM_MODE_FMT "\n",
connector->base.base.id, connector->base.name,
DRM_MODE_ARG(mode));
list_del(&mode->head);
drm_mode_destroy(&i915->drm, mode);
drm_mode_destroy(display->drm, mode);
}
}
@ -329,7 +326,7 @@ static void intel_panel_add_fixed_mode(struct intel_connector *connector,
struct drm_display_mode *fixed_mode,
const char *type)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
struct drm_display_info *info = &connector->base.display_info;
if (!fixed_mode)
@ -340,7 +337,7 @@ static void intel_panel_add_fixed_mode(struct intel_connector *connector,
info->width_mm = fixed_mode->width_mm;
info->height_mm = fixed_mode->height_mm;
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] using %s fixed mode: " DRM_MODE_FMT "\n",
drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] using %s fixed mode: " DRM_MODE_FMT "\n",
connector->base.base.id, connector->base.name, type,
DRM_MODE_ARG(fixed_mode));
@ -349,7 +346,7 @@ static void intel_panel_add_fixed_mode(struct intel_connector *connector,
void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
const struct drm_display_mode *mode;
mode = connector->panel.vbt.lfp_vbt_mode;
@ -357,13 +354,13 @@ void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector)
return;
intel_panel_add_fixed_mode(connector,
drm_mode_duplicate(&i915->drm, mode),
drm_mode_duplicate(display->drm, mode),
"VBT LFP");
}
void intel_panel_add_vbt_sdvo_fixed_mode(struct intel_connector *connector)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
const struct drm_display_mode *mode;
mode = connector->panel.vbt.sdvo_lvds_vbt_mode;
@ -371,7 +368,7 @@ void intel_panel_add_vbt_sdvo_fixed_mode(struct intel_connector *connector)
return;
intel_panel_add_fixed_mode(connector,
drm_mode_duplicate(&i915->drm, mode),
drm_mode_duplicate(display->drm, mode),
"VBT SDVO");
}
@ -383,301 +380,6 @@ void intel_panel_add_encoder_fixed_mode(struct intel_connector *connector,
"current (BIOS)");
}
/* adjusted_mode has been preset to be the panel's fixed mode */
static int pch_panel_fitting(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
int x, y, width, height;
/* Native modes don't need fitting */
if (adjusted_mode->crtc_hdisplay == pipe_src_w &&
adjusted_mode->crtc_vdisplay == pipe_src_h &&
crtc_state->output_format != INTEL_OUTPUT_FORMAT_YCBCR420)
return 0;
switch (conn_state->scaling_mode) {
case DRM_MODE_SCALE_CENTER:
width = pipe_src_w;
height = pipe_src_h;
x = (adjusted_mode->crtc_hdisplay - width + 1)/2;
y = (adjusted_mode->crtc_vdisplay - height + 1)/2;
break;
case DRM_MODE_SCALE_ASPECT:
/* Scale but preserve the aspect ratio */
{
u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;
if (scaled_width > scaled_height) { /* pillar */
width = scaled_height / pipe_src_h;
if (width & 1)
width++;
x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
y = 0;
height = adjusted_mode->crtc_vdisplay;
} else if (scaled_width < scaled_height) { /* letter */
height = scaled_width / pipe_src_w;
if (height & 1)
height++;
y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
x = 0;
width = adjusted_mode->crtc_hdisplay;
} else {
x = y = 0;
width = adjusted_mode->crtc_hdisplay;
height = adjusted_mode->crtc_vdisplay;
}
}
break;
case DRM_MODE_SCALE_NONE:
WARN_ON(adjusted_mode->crtc_hdisplay != pipe_src_w);
WARN_ON(adjusted_mode->crtc_vdisplay != pipe_src_h);
fallthrough;
case DRM_MODE_SCALE_FULLSCREEN:
x = y = 0;
width = adjusted_mode->crtc_hdisplay;
height = adjusted_mode->crtc_vdisplay;
break;
default:
MISSING_CASE(conn_state->scaling_mode);
return -EINVAL;
}
drm_rect_init(&crtc_state->pch_pfit.dst,
x, y, width, height);
crtc_state->pch_pfit.enabled = true;
return 0;
}
static void
centre_horizontally(struct drm_display_mode *adjusted_mode,
int width)
{
u32 border, sync_pos, blank_width, sync_width;
/* keep the hsync and hblank widths constant */
sync_width = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
sync_pos = (blank_width - sync_width + 1) / 2;
border = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
border += border & 1; /* make the border even */
adjusted_mode->crtc_hdisplay = width;
adjusted_mode->crtc_hblank_start = width + border;
adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width;
adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos;
adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + sync_width;
}
static void
centre_vertically(struct drm_display_mode *adjusted_mode,
int height)
{
u32 border, sync_pos, blank_width, sync_width;
/* keep the vsync and vblank widths constant */
sync_width = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start;
sync_pos = (blank_width - sync_width + 1) / 2;
border = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
adjusted_mode->crtc_vdisplay = height;
adjusted_mode->crtc_vblank_start = height + border;
adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vblank_start + blank_width;
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vblank_start + sync_pos;
adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + sync_width;
}
static u32 panel_fitter_scaling(u32 source, u32 target)
{
/*
* Floating point operation is not supported. So the FACTOR
* is defined, which can avoid the floating point computation
* when calculating the panel ratio.
*/
#define ACCURACY 12
#define FACTOR (1 << ACCURACY)
u32 ratio = source * FACTOR / target;
return (FACTOR * ratio + FACTOR/2) / FACTOR;
}
static void i965_scale_aspect(struct intel_crtc_state *crtc_state,
u32 *pfit_control)
{
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;
/* 965+ is easy, it does everything in hw */
if (scaled_width > scaled_height)
*pfit_control |= PFIT_ENABLE |
PFIT_SCALING_PILLAR;
else if (scaled_width < scaled_height)
*pfit_control |= PFIT_ENABLE |
PFIT_SCALING_LETTER;
else if (adjusted_mode->crtc_hdisplay != pipe_src_w)
*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
}
static void i9xx_scale_aspect(struct intel_crtc_state *crtc_state,
u32 *pfit_control, u32 *pfit_pgm_ratios,
u32 *border)
{
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;
u32 bits;
/*
* For earlier chips we have to calculate the scaling
* ratio by hand and program it into the
* PFIT_PGM_RATIO register
*/
if (scaled_width > scaled_height) { /* pillar */
centre_horizontally(adjusted_mode,
scaled_height / pipe_src_h);
*border = LVDS_BORDER_ENABLE;
if (pipe_src_h != adjusted_mode->crtc_vdisplay) {
bits = panel_fitter_scaling(pipe_src_h,
adjusted_mode->crtc_vdisplay);
*pfit_pgm_ratios |= (PFIT_HORIZ_SCALE(bits) |
PFIT_VERT_SCALE(bits));
*pfit_control |= (PFIT_ENABLE |
PFIT_VERT_INTERP_BILINEAR |
PFIT_HORIZ_INTERP_BILINEAR);
}
} else if (scaled_width < scaled_height) { /* letter */
centre_vertically(adjusted_mode,
scaled_width / pipe_src_w);
*border = LVDS_BORDER_ENABLE;
if (pipe_src_w != adjusted_mode->crtc_hdisplay) {
bits = panel_fitter_scaling(pipe_src_w,
adjusted_mode->crtc_hdisplay);
*pfit_pgm_ratios |= (PFIT_HORIZ_SCALE(bits) |
PFIT_VERT_SCALE(bits));
*pfit_control |= (PFIT_ENABLE |
PFIT_VERT_INTERP_BILINEAR |
PFIT_HORIZ_INTERP_BILINEAR);
}
} else {
/* Aspects match, Let hw scale both directions */
*pfit_control |= (PFIT_ENABLE |
PFIT_VERT_AUTO_SCALE |
PFIT_HORIZ_AUTO_SCALE |
PFIT_VERT_INTERP_BILINEAR |
PFIT_HORIZ_INTERP_BILINEAR);
}
}
static int gmch_panel_fitting(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
/* Native modes don't need fitting */
if (adjusted_mode->crtc_hdisplay == pipe_src_w &&
adjusted_mode->crtc_vdisplay == pipe_src_h)
goto out;
switch (conn_state->scaling_mode) {
case DRM_MODE_SCALE_CENTER:
/*
* For centered modes, we have to calculate border widths &
* heights and modify the values programmed into the CRTC.
*/
centre_horizontally(adjusted_mode, pipe_src_w);
centre_vertically(adjusted_mode, pipe_src_h);
border = LVDS_BORDER_ENABLE;
break;
case DRM_MODE_SCALE_ASPECT:
/* Scale but preserve the aspect ratio */
if (DISPLAY_VER(dev_priv) >= 4)
i965_scale_aspect(crtc_state, &pfit_control);
else
i9xx_scale_aspect(crtc_state, &pfit_control,
&pfit_pgm_ratios, &border);
break;
case DRM_MODE_SCALE_FULLSCREEN:
/*
* Full scaling, even if it changes the aspect ratio.
* Fortunately this is all done for us in hw.
*/
if (pipe_src_h != adjusted_mode->crtc_vdisplay ||
pipe_src_w != adjusted_mode->crtc_hdisplay) {
pfit_control |= PFIT_ENABLE;
if (DISPLAY_VER(dev_priv) >= 4)
pfit_control |= PFIT_SCALING_AUTO;
else
pfit_control |= (PFIT_VERT_AUTO_SCALE |
PFIT_VERT_INTERP_BILINEAR |
PFIT_HORIZ_AUTO_SCALE |
PFIT_HORIZ_INTERP_BILINEAR);
}
break;
default:
MISSING_CASE(conn_state->scaling_mode);
return -EINVAL;
}
/* 965+ wants fuzzy fitting */
/* FIXME: handle multiple panels by failing gracefully */
if (DISPLAY_VER(dev_priv) >= 4)
pfit_control |= PFIT_PIPE(crtc->pipe) | PFIT_FILTER_FUZZY;
out:
if ((pfit_control & PFIT_ENABLE) == 0) {
pfit_control = 0;
pfit_pgm_ratios = 0;
}
/* Make sure pre-965 set dither correctly for 18bpp panels. */
if (DISPLAY_VER(dev_priv) < 4 && crtc_state->pipe_bpp == 18)
pfit_control |= PFIT_PANEL_8TO6_DITHER_ENABLE;
crtc_state->gmch_pfit.control = pfit_control;
crtc_state->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
crtc_state->gmch_pfit.lvds_border_bits = border;
return 0;
}
int intel_panel_fitting(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
if (HAS_GMCH(i915))
return gmch_panel_fitting(crtc_state, conn_state);
else
return pch_panel_fitting(crtc_state, conn_state);
}
enum drm_connector_status
intel_panel_detect(struct drm_connector *connector, bool force)
{

View File

@ -14,9 +14,9 @@ struct drm_connector;
struct drm_connector_state;
struct drm_display_mode;
struct drm_edid;
struct drm_i915_private;
struct intel_connector;
struct intel_crtc_state;
struct intel_display;
struct intel_encoder;
void intel_panel_init_alloc(struct intel_connector *connector);
@ -25,7 +25,7 @@ int intel_panel_init(struct intel_connector *connector,
void intel_panel_fini(struct intel_connector *connector);
enum drm_connector_status
intel_panel_detect(struct drm_connector *connector, bool force);
bool intel_panel_use_ssc(struct drm_i915_private *i915);
bool intel_panel_use_ssc(struct intel_display *display);
const struct drm_display_mode *
intel_panel_preferred_fixed_mode(struct intel_connector *connector);
const struct drm_display_mode *
@ -42,8 +42,6 @@ enum drrs_type intel_panel_drrs_type(struct intel_connector *connector);
enum drm_mode_status
intel_panel_mode_valid(struct intel_connector *connector,
const struct drm_display_mode *mode);
int intel_panel_fitting(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
int intel_panel_compute_config(struct intel_connector *connector,
struct drm_display_mode *adjusted_mode);
void intel_panel_add_edid_fixed_modes(struct intel_connector *connector,

View File

@ -39,58 +39,61 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe, enum port port,
i915_reg_t dp_reg)
{
struct intel_display *display = &dev_priv->display;
enum pipe port_pipe;
bool state;
state = g4x_dp_port_enabled(dev_priv, dp_reg, port, &port_pipe);
I915_STATE_WARN(dev_priv, state && port_pipe == pipe,
"PCH DP %c enabled on transcoder %c, should be disabled\n",
port_name(port), pipe_name(pipe));
INTEL_DISPLAY_STATE_WARN(display, state && port_pipe == pipe,
"PCH DP %c enabled on transcoder %c, should be disabled\n",
port_name(port), pipe_name(pipe));
I915_STATE_WARN(dev_priv,
HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B,
"IBX PCH DP %c still using transcoder B\n",
port_name(port));
INTEL_DISPLAY_STATE_WARN(display,
HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B,
"IBX PCH DP %c still using transcoder B\n",
port_name(port));
}
static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe, enum port port,
i915_reg_t hdmi_reg)
{
struct intel_display *display = &dev_priv->display;
enum pipe port_pipe;
bool state;
state = intel_sdvo_port_enabled(dev_priv, hdmi_reg, &port_pipe);
I915_STATE_WARN(dev_priv, state && port_pipe == pipe,
"PCH HDMI %c enabled on transcoder %c, should be disabled\n",
port_name(port), pipe_name(pipe));
INTEL_DISPLAY_STATE_WARN(display, state && port_pipe == pipe,
"PCH HDMI %c enabled on transcoder %c, should be disabled\n",
port_name(port), pipe_name(pipe));
I915_STATE_WARN(dev_priv,
HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B,
"IBX PCH HDMI %c still using transcoder B\n",
port_name(port));
INTEL_DISPLAY_STATE_WARN(display,
HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B,
"IBX PCH HDMI %c still using transcoder B\n",
port_name(port));
}
static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
struct intel_display *display = &dev_priv->display;
enum pipe port_pipe;
assert_pch_dp_disabled(dev_priv, pipe, PORT_B, PCH_DP_B);
assert_pch_dp_disabled(dev_priv, pipe, PORT_C, PCH_DP_C);
assert_pch_dp_disabled(dev_priv, pipe, PORT_D, PCH_DP_D);
I915_STATE_WARN(dev_priv,
intel_crt_port_enabled(dev_priv, PCH_ADPA, &port_pipe) && port_pipe == pipe,
"PCH VGA enabled on transcoder %c, should be disabled\n",
pipe_name(pipe));
INTEL_DISPLAY_STATE_WARN(display,
intel_crt_port_enabled(display, PCH_ADPA, &port_pipe) && port_pipe == pipe,
"PCH VGA enabled on transcoder %c, should be disabled\n",
pipe_name(pipe));
I915_STATE_WARN(dev_priv,
intel_lvds_port_enabled(dev_priv, PCH_LVDS, &port_pipe) && port_pipe == pipe,
"PCH LVDS enabled on transcoder %c, should be disabled\n",
pipe_name(pipe));
INTEL_DISPLAY_STATE_WARN(display,
intel_lvds_port_enabled(dev_priv, PCH_LVDS, &port_pipe) && port_pipe == pipe,
"PCH LVDS enabled on transcoder %c, should be disabled\n",
pipe_name(pipe));
/* PCH SDVOB multiplex with HDMIB */
assert_pch_hdmi_disabled(dev_priv, pipe, PORT_B, PCH_HDMIB);
@ -101,14 +104,15 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
struct intel_display *display = &dev_priv->display;
u32 val;
bool enabled;
val = intel_de_read(dev_priv, PCH_TRANSCONF(pipe));
val = intel_de_read(display, PCH_TRANSCONF(pipe));
enabled = !!(val & TRANS_ENABLE);
I915_STATE_WARN(dev_priv, enabled,
"transcoder assertion failed, should be off on pipe %c but is still active\n",
pipe_name(pipe));
INTEL_DISPLAY_STATE_WARN(display, enabled,
"transcoder assertion failed, should be off on pipe %c but is still active\n",
pipe_name(pipe));
}
static void ibx_sanitize_pch_hdmi_port(struct drm_i915_private *dev_priv,

View File

@ -491,6 +491,7 @@ static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv)
static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv)
{
struct intel_display *display = &dev_priv->display;
struct intel_encoder *encoder;
struct intel_shared_dpll *pll;
int i;
@ -572,11 +573,11 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv)
if (has_panel) {
final |= DREF_SSC_SOURCE_ENABLE;
if (intel_panel_use_ssc(dev_priv) && can_ssc)
if (intel_panel_use_ssc(display) && can_ssc)
final |= DREF_SSC1_ENABLE;
if (has_cpu_edp) {
if (intel_panel_use_ssc(dev_priv) && can_ssc)
if (intel_panel_use_ssc(display) && can_ssc)
final |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
else
final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
@ -604,7 +605,7 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv)
val |= DREF_SSC_SOURCE_ENABLE;
/* SSC must be turned on before enabling the CPU output */
if (intel_panel_use_ssc(dev_priv) && can_ssc) {
if (intel_panel_use_ssc(display) && can_ssc) {
drm_dbg_kms(&dev_priv->drm, "Using SSC on panel\n");
val |= DREF_SSC1_ENABLE;
} else {
@ -620,7 +621,7 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv)
/* Enable CPU source on CPU attached eDP */
if (has_cpu_edp) {
if (intel_panel_use_ssc(dev_priv) && can_ssc) {
if (intel_panel_use_ssc(display) && can_ssc) {
drm_dbg_kms(&dev_priv->drm,
"Using SSC on eDP\n");
val |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;

View File

@ -0,0 +1,554 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2024 Intel Corporation
*/
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_display_core.h"
#include "intel_display_driver.h"
#include "intel_display_types.h"
#include "intel_lvds_regs.h"
#include "intel_pfit.h"
static int intel_pch_pfit_check_dst_window(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
const struct drm_rect *dst = &crtc_state->pch_pfit.dst;
int width = drm_rect_width(dst);
int height = drm_rect_height(dst);
int x = dst->x1;
int y = dst->y1;
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE &&
(y & 1 || height & 1)) {
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] pfit window (" DRM_RECT_FMT ") misaligned for interlaced output\n",
crtc->base.base.id, crtc->base.name, DRM_RECT_ARG(dst));
return -EINVAL;
}
/*
* "Restriction : When pipe scaling is enabled, the scaled
* output must equal the pipe active area, so Pipe active
* size = (2 * PF window position) + PF window size."
*
* The vertical direction seems more forgiving than the
* horizontal direction, but still has some issues so
* let's follow the same hard rule for both.
*/
if (adjusted_mode->crtc_hdisplay != 2 * x + width ||
adjusted_mode->crtc_vdisplay != 2 * y + height) {
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] pfit window (" DRM_RECT_FMT ") not centered\n",
crtc->base.base.id, crtc->base.name, DRM_RECT_ARG(dst));
return -EINVAL;
}
/*
* "Restriction : The X position must not be programmed
* to be 1 (28:16=0 0000 0000 0001b)."
*/
if (x == 1) {
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] pfit window (" DRM_RECT_FMT ") badly positioned\n",
crtc->base.base.id, crtc->base.name, DRM_RECT_ARG(dst));
return -EINVAL;
}
return 0;
}
static int intel_pch_pfit_check_src_size(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
int max_src_w, max_src_h;
if (DISPLAY_VER(display) >= 8) {
max_src_w = 4096;
max_src_h = 4096;
} else if (DISPLAY_VER(display) >= 7) {
/*
* PF0 7x5 capable
* PF1 3x3 capable (could be switched to 7x5
* mode on HSW when PF2 unused)
* PF2 3x3 capable
*
* This assumes we use a 1:1 mapping between pipe and PF.
*/
max_src_w = crtc->pipe == PIPE_A ? 4096 : 2048;
max_src_h = 4096;
} else {
max_src_w = 4096;
max_src_h = 4096;
}
if (pipe_src_w > max_src_w || pipe_src_h > max_src_h) {
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] source size (%dx%d) exceeds pfit max (%dx%d)\n",
crtc->base.base.id, crtc->base.name,
pipe_src_w, pipe_src_h, max_src_w, max_src_h);
return -EINVAL;
}
return 0;
}
static int intel_pch_pfit_check_scaling(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_rect *dst = &crtc_state->pch_pfit.dst;
int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
int hscale, vscale, max_scale = 0x12000; /* 1.125 */
struct drm_rect src;
drm_rect_init(&src, 0, 0, pipe_src_w << 16, pipe_src_h << 16);
hscale = drm_rect_calc_hscale(&src, dst, 0, max_scale);
if (hscale < 0) {
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] pfit horizontal downscaling (%d->%d) exceeds max (0x%x)\n",
crtc->base.base.id, crtc->base.name,
pipe_src_w, drm_rect_width(dst),
max_scale);
return hscale;
}
vscale = drm_rect_calc_vscale(&src, dst, 0, max_scale);
if (vscale < 0) {
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] pfit vertical downscaling (%d->%d) exceeds max (0x%x)\n",
crtc->base.base.id, crtc->base.name,
pipe_src_h, drm_rect_height(dst),
max_scale);
return vscale;
}
return 0;
}
static int intel_pch_pfit_check_timings(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
if (adjusted_mode->crtc_vdisplay < 7) {
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] vertical active (%d) below minimum (%d) for pfit\n",
crtc->base.base.id, crtc->base.name,
adjusted_mode->crtc_vdisplay, 7);
return -EINVAL;
}
return 0;
}
static int intel_pch_pfit_check_cloning(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
/*
* The panel fitter is in the pipe and thus would affect every
* cloned output. The relevant properties (scaling mode, TV
* margins) are per-connector so we'd have to make sure each
* output sets them up identically. Seems like a very niche use
* case so let's just reject cloning entirely when pfit is used.
*/
if (crtc_state->uapi.encoder_mask &&
!is_power_of_2(crtc_state->uapi.encoder_mask)) {
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] no pfit when cloning\n",
crtc->base.base.id, crtc->base.name);
return -EINVAL;
}
return 0;
}
/* adjusted_mode has been preset to be the panel's fixed mode */
static int pch_panel_fitting(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(crtc_state);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
int ret, x, y, width, height;
/* Native modes don't need fitting */
if (adjusted_mode->crtc_hdisplay == pipe_src_w &&
adjusted_mode->crtc_vdisplay == pipe_src_h &&
crtc_state->output_format != INTEL_OUTPUT_FORMAT_YCBCR420)
return 0;
switch (conn_state->scaling_mode) {
case DRM_MODE_SCALE_CENTER:
width = pipe_src_w;
height = pipe_src_h;
x = (adjusted_mode->crtc_hdisplay - width + 1)/2;
y = (adjusted_mode->crtc_vdisplay - height + 1)/2;
break;
case DRM_MODE_SCALE_ASPECT:
/* Scale but preserve the aspect ratio */
{
u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;
if (scaled_width > scaled_height) { /* pillar */
width = scaled_height / pipe_src_h;
if (width & 1)
width++;
x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
y = 0;
height = adjusted_mode->crtc_vdisplay;
} else if (scaled_width < scaled_height) { /* letter */
height = scaled_width / pipe_src_w;
if (height & 1)
height++;
y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
x = 0;
width = adjusted_mode->crtc_hdisplay;
} else {
x = y = 0;
width = adjusted_mode->crtc_hdisplay;
height = adjusted_mode->crtc_vdisplay;
}
}
break;
case DRM_MODE_SCALE_NONE:
WARN_ON(adjusted_mode->crtc_hdisplay != pipe_src_w);
WARN_ON(adjusted_mode->crtc_vdisplay != pipe_src_h);
fallthrough;
case DRM_MODE_SCALE_FULLSCREEN:
x = y = 0;
width = adjusted_mode->crtc_hdisplay;
height = adjusted_mode->crtc_vdisplay;
break;
default:
MISSING_CASE(conn_state->scaling_mode);
return -EINVAL;
}
drm_rect_init(&crtc_state->pch_pfit.dst,
x, y, width, height);
crtc_state->pch_pfit.enabled = true;
/*
* SKL+ have unified scalers for pipes/planes so the
* checks are done in a single place for all scalers.
*/
if (DISPLAY_VER(display) >= 9)
return 0;
ret = intel_pch_pfit_check_dst_window(crtc_state);
if (ret)
return ret;
ret = intel_pch_pfit_check_src_size(crtc_state);
if (ret)
return ret;
ret = intel_pch_pfit_check_scaling(crtc_state);
if (ret)
return ret;
ret = intel_pch_pfit_check_timings(crtc_state);
if (ret)
return ret;
ret = intel_pch_pfit_check_cloning(crtc_state);
if (ret)
return ret;
return 0;
}
static void
centre_horizontally(struct drm_display_mode *adjusted_mode,
int width)
{
u32 border, sync_pos, blank_width, sync_width;
/* keep the hsync and hblank widths constant */
sync_width = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
sync_pos = (blank_width - sync_width + 1) / 2;
border = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
border += border & 1; /* make the border even */
adjusted_mode->crtc_hdisplay = width;
adjusted_mode->crtc_hblank_start = width + border;
adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width;
adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos;
adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + sync_width;
}
static void
centre_vertically(struct drm_display_mode *adjusted_mode,
int height)
{
u32 border, sync_pos, blank_width, sync_width;
/* keep the vsync and vblank widths constant */
sync_width = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start;
sync_pos = (blank_width - sync_width + 1) / 2;
border = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
adjusted_mode->crtc_vdisplay = height;
adjusted_mode->crtc_vblank_start = height + border;
adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vblank_start + blank_width;
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vblank_start + sync_pos;
adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + sync_width;
}
static u32 panel_fitter_scaling(u32 source, u32 target)
{
/*
* Floating point operation is not supported. So the FACTOR
* is defined, which can avoid the floating point computation
* when calculating the panel ratio.
*/
#define ACCURACY 12
#define FACTOR (1 << ACCURACY)
u32 ratio = source * FACTOR / target;
return (FACTOR * ratio + FACTOR/2) / FACTOR;
}
static void i965_scale_aspect(struct intel_crtc_state *crtc_state,
u32 *pfit_control)
{
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;
/* 965+ is easy, it does everything in hw */
if (scaled_width > scaled_height)
*pfit_control |= PFIT_ENABLE |
PFIT_SCALING_PILLAR;
else if (scaled_width < scaled_height)
*pfit_control |= PFIT_ENABLE |
PFIT_SCALING_LETTER;
else if (adjusted_mode->crtc_hdisplay != pipe_src_w)
*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
}
static void i9xx_scale_aspect(struct intel_crtc_state *crtc_state,
u32 *pfit_control, u32 *pfit_pgm_ratios,
u32 *border)
{
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;
u32 bits;
/*
* For earlier chips we have to calculate the scaling
* ratio by hand and program it into the
* PFIT_PGM_RATIO register
*/
if (scaled_width > scaled_height) { /* pillar */
centre_horizontally(adjusted_mode,
scaled_height / pipe_src_h);
*border = LVDS_BORDER_ENABLE;
if (pipe_src_h != adjusted_mode->crtc_vdisplay) {
bits = panel_fitter_scaling(pipe_src_h,
adjusted_mode->crtc_vdisplay);
*pfit_pgm_ratios |= (PFIT_HORIZ_SCALE(bits) |
PFIT_VERT_SCALE(bits));
*pfit_control |= (PFIT_ENABLE |
PFIT_VERT_INTERP_BILINEAR |
PFIT_HORIZ_INTERP_BILINEAR);
}
} else if (scaled_width < scaled_height) { /* letter */
centre_vertically(adjusted_mode,
scaled_width / pipe_src_w);
*border = LVDS_BORDER_ENABLE;
if (pipe_src_w != adjusted_mode->crtc_hdisplay) {
bits = panel_fitter_scaling(pipe_src_w,
adjusted_mode->crtc_hdisplay);
*pfit_pgm_ratios |= (PFIT_HORIZ_SCALE(bits) |
PFIT_VERT_SCALE(bits));
*pfit_control |= (PFIT_ENABLE |
PFIT_VERT_INTERP_BILINEAR |
PFIT_HORIZ_INTERP_BILINEAR);
}
} else {
/* Aspects match, Let hw scale both directions */
*pfit_control |= (PFIT_ENABLE |
PFIT_VERT_AUTO_SCALE |
PFIT_HORIZ_AUTO_SCALE |
PFIT_VERT_INTERP_BILINEAR |
PFIT_HORIZ_INTERP_BILINEAR);
}
}
static int intel_gmch_pfit_check_timings(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
int min;
if (DISPLAY_VER(display) >= 4)
min = 3;
else
min = 2;
if (adjusted_mode->crtc_hdisplay < min) {
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] horizontal active (%d) below minimum (%d) for pfit\n",
crtc->base.base.id, crtc->base.name,
adjusted_mode->crtc_hdisplay, min);
return -EINVAL;
}
if (adjusted_mode->crtc_vdisplay < min) {
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] vertical active (%d) below minimum (%d) for pfit\n",
crtc->base.base.id, crtc->base.name,
adjusted_mode->crtc_vdisplay, min);
return -EINVAL;
}
return 0;
}
static int gmch_panel_fitting(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
/* Native modes don't need fitting */
if (adjusted_mode->crtc_hdisplay == pipe_src_w &&
adjusted_mode->crtc_vdisplay == pipe_src_h)
goto out;
/*
* TODO: implement downscaling for i965+. Need to account
* for downscaling in intel_crtc_compute_pixel_rate().
*/
if (adjusted_mode->crtc_hdisplay < pipe_src_w) {
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] pfit horizontal downscaling (%d->%d) not supported\n",
crtc->base.base.id, crtc->base.name,
pipe_src_w, adjusted_mode->crtc_hdisplay);
return -EINVAL;
}
if (adjusted_mode->crtc_vdisplay < pipe_src_h) {
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] pfit vertical downscaling (%d->%d) not supported\n",
crtc->base.base.id, crtc->base.name,
pipe_src_h, adjusted_mode->crtc_vdisplay);
return -EINVAL;
}
switch (conn_state->scaling_mode) {
case DRM_MODE_SCALE_CENTER:
/*
* For centered modes, we have to calculate border widths &
* heights and modify the values programmed into the CRTC.
*/
centre_horizontally(adjusted_mode, pipe_src_w);
centre_vertically(adjusted_mode, pipe_src_h);
border = LVDS_BORDER_ENABLE;
break;
case DRM_MODE_SCALE_ASPECT:
/* Scale but preserve the aspect ratio */
if (DISPLAY_VER(display) >= 4)
i965_scale_aspect(crtc_state, &pfit_control);
else
i9xx_scale_aspect(crtc_state, &pfit_control,
&pfit_pgm_ratios, &border);
break;
case DRM_MODE_SCALE_FULLSCREEN:
/*
* Full scaling, even if it changes the aspect ratio.
* Fortunately this is all done for us in hw.
*/
if (pipe_src_h != adjusted_mode->crtc_vdisplay ||
pipe_src_w != adjusted_mode->crtc_hdisplay) {
pfit_control |= PFIT_ENABLE;
if (DISPLAY_VER(display) >= 4)
pfit_control |= PFIT_SCALING_AUTO;
else
pfit_control |= (PFIT_VERT_AUTO_SCALE |
PFIT_VERT_INTERP_BILINEAR |
PFIT_HORIZ_AUTO_SCALE |
PFIT_HORIZ_INTERP_BILINEAR);
}
break;
default:
MISSING_CASE(conn_state->scaling_mode);
return -EINVAL;
}
/* 965+ wants fuzzy fitting */
/* FIXME: handle multiple panels by failing gracefully */
if (DISPLAY_VER(display) >= 4)
pfit_control |= PFIT_PIPE(crtc->pipe) | PFIT_FILTER_FUZZY;
out:
if ((pfit_control & PFIT_ENABLE) == 0) {
pfit_control = 0;
pfit_pgm_ratios = 0;
}
/* Make sure pre-965 set dither correctly for 18bpp panels. */
if (DISPLAY_VER(display) < 4 && crtc_state->pipe_bpp == 18)
pfit_control |= PFIT_PANEL_8TO6_DITHER_ENABLE;
crtc_state->gmch_pfit.control = pfit_control;
crtc_state->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
crtc_state->gmch_pfit.lvds_border_bits = border;
if ((pfit_control & PFIT_ENABLE) == 0)
return 0;
return intel_gmch_pfit_check_timings(crtc_state);
}
int intel_panel_fitting(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(crtc_state);
if (HAS_GMCH(display))
return gmch_panel_fitting(crtc_state, conn_state);
else
return pch_panel_fitting(crtc_state, conn_state);
}

View File

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2024 Intel Corporation
*/
#ifndef __INTEL_PFIT_H__
#define __INTEL_PFIT_H__
struct drm_connector_state;
struct intel_crtc_state;
int intel_panel_fitting(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
#endif /* __INTEL_PFIT_H__ */

View File

@ -92,7 +92,7 @@ int intel_pmdemand_init(struct drm_i915_private *i915)
&pmdemand_state->base,
&intel_pmdemand_funcs);
if (IS_DISPLAY_VER_STEP(i915, IP_VER(14, 0), STEP_A0, STEP_C0))
if (IS_DISPLAY_VERx100_STEP(i915, 1400, STEP_A0, STEP_C0))
/* Wa_14016740474 */
intel_de_rmw(i915, XELPD_CHICKEN_DCPR_3, 0, DMD_RSP_TIMEOUT_DISABLE);
@ -258,6 +258,7 @@ intel_pmdemand_connector_needs_update(struct intel_atomic_state *state)
static bool intel_pmdemand_needs_update(struct intel_atomic_state *state)
{
struct intel_display *display = to_intel_display(state);
const struct intel_bw_state *new_bw_state, *old_bw_state;
const struct intel_cdclk_state *new_cdclk_state, *old_cdclk_state;
const struct intel_crtc_state *new_crtc_state, *old_crtc_state;
@ -274,12 +275,16 @@ static bool intel_pmdemand_needs_update(struct intel_atomic_state *state)
new_dbuf_state = intel_atomic_get_new_dbuf_state(state);
old_dbuf_state = intel_atomic_get_old_dbuf_state(state);
if (new_dbuf_state &&
(new_dbuf_state->active_pipes !=
old_dbuf_state->active_pipes ||
new_dbuf_state->enabled_slices !=
old_dbuf_state->enabled_slices))
new_dbuf_state->active_pipes != old_dbuf_state->active_pipes)
return true;
if (DISPLAY_VER(display) < 30) {
if (new_dbuf_state &&
new_dbuf_state->enabled_slices !=
old_dbuf_state->enabled_slices)
return true;
}
new_cdclk_state = intel_atomic_get_new_cdclk_state(state);
old_cdclk_state = intel_atomic_get_old_cdclk_state(state);
if (new_cdclk_state &&
@ -327,10 +332,15 @@ int intel_pmdemand_atomic_check(struct intel_atomic_state *state)
if (IS_ERR(new_dbuf_state))
return PTR_ERR(new_dbuf_state);
new_pmdemand_state->params.active_pipes =
min_t(u8, hweight8(new_dbuf_state->active_pipes), 3);
new_pmdemand_state->params.active_dbufs =
min_t(u8, hweight8(new_dbuf_state->enabled_slices), 3);
if (DISPLAY_VER(i915) < 30) {
new_pmdemand_state->params.active_dbufs =
min_t(u8, hweight8(new_dbuf_state->enabled_slices), 3);
new_pmdemand_state->params.active_pipes =
min_t(u8, hweight8(new_dbuf_state->active_pipes), 3);
} else {
new_pmdemand_state->params.active_pipes =
min_t(u8, hweight8(new_dbuf_state->active_pipes), INTEL_NUM_PIPES(i915));
}
new_cdclk_state = intel_atomic_get_cdclk_state(state);
if (IS_ERR(new_cdclk_state))
@ -395,27 +405,32 @@ intel_pmdemand_init_pmdemand_params(struct drm_i915_private *i915,
reg2 = intel_de_read(i915, XELPDP_INITIATE_PMDEMAND_REQUEST(1));
/* Set 1*/
pmdemand_state->params.qclk_gv_bw =
REG_FIELD_GET(XELPDP_PMDEMAND_QCLK_GV_BW_MASK, reg1);
pmdemand_state->params.voltage_index =
REG_FIELD_GET(XELPDP_PMDEMAND_VOLTAGE_INDEX_MASK, reg1);
pmdemand_state->params.qclk_gv_index =
REG_FIELD_GET(XELPDP_PMDEMAND_QCLK_GV_INDEX_MASK, reg1);
pmdemand_state->params.active_pipes =
REG_FIELD_GET(XELPDP_PMDEMAND_PIPES_MASK, reg1);
pmdemand_state->params.active_dbufs =
REG_FIELD_GET(XELPDP_PMDEMAND_DBUFS_MASK, reg1);
pmdemand_state->params.active_phys =
REG_FIELD_GET(XELPDP_PMDEMAND_PHYS_MASK, reg1);
/* Set 2*/
pmdemand_state->params.cdclk_freq_mhz =
REG_FIELD_GET(XELPDP_PMDEMAND_CDCLK_FREQ_MASK, reg2);
pmdemand_state->params.ddiclk_max =
REG_FIELD_GET(XELPDP_PMDEMAND_DDICLK_FREQ_MASK, reg2);
pmdemand_state->params.scalers =
REG_FIELD_GET(XELPDP_PMDEMAND_SCALERS_MASK, reg2);
if (DISPLAY_VER(i915) >= 30) {
pmdemand_state->params.active_pipes =
REG_FIELD_GET(XE3_PMDEMAND_PIPES_MASK, reg1);
} else {
pmdemand_state->params.active_pipes =
REG_FIELD_GET(XELPDP_PMDEMAND_PIPES_MASK, reg1);
pmdemand_state->params.active_dbufs =
REG_FIELD_GET(XELPDP_PMDEMAND_DBUFS_MASK, reg1);
pmdemand_state->params.scalers =
REG_FIELD_GET(XELPDP_PMDEMAND_SCALERS_MASK, reg2);
}
unlock:
mutex_unlock(&i915->display.pmdemand.lock);
@ -442,6 +457,10 @@ void intel_pmdemand_program_dbuf(struct drm_i915_private *i915,
{
u32 dbufs = min_t(u32, hweight8(dbuf_slices), 3);
/* PM Demand only tracks active dbufs on pre-Xe3 platforms */
if (DISPLAY_VER(i915) >= 30)
return;
mutex_lock(&i915->display.pmdemand.lock);
if (drm_WARN_ON(&i915->drm,
!intel_pmdemand_check_prev_transaction(i915)))
@ -460,7 +479,8 @@ void intel_pmdemand_program_dbuf(struct drm_i915_private *i915,
}
static void
intel_pmdemand_update_params(const struct intel_pmdemand_state *new,
intel_pmdemand_update_params(struct intel_display *display,
const struct intel_pmdemand_state *new,
const struct intel_pmdemand_state *old,
u32 *reg1, u32 *reg2, bool serialized)
{
@ -495,16 +515,22 @@ intel_pmdemand_update_params(const struct intel_pmdemand_state *new,
update_reg(reg1, qclk_gv_bw, XELPDP_PMDEMAND_QCLK_GV_BW_MASK);
update_reg(reg1, voltage_index, XELPDP_PMDEMAND_VOLTAGE_INDEX_MASK);
update_reg(reg1, qclk_gv_index, XELPDP_PMDEMAND_QCLK_GV_INDEX_MASK);
update_reg(reg1, active_pipes, XELPDP_PMDEMAND_PIPES_MASK);
update_reg(reg1, active_dbufs, XELPDP_PMDEMAND_DBUFS_MASK);
update_reg(reg1, active_phys, XELPDP_PMDEMAND_PHYS_MASK);
/* Set 2*/
update_reg(reg2, cdclk_freq_mhz, XELPDP_PMDEMAND_CDCLK_FREQ_MASK);
update_reg(reg2, ddiclk_max, XELPDP_PMDEMAND_DDICLK_FREQ_MASK);
update_reg(reg2, scalers, XELPDP_PMDEMAND_SCALERS_MASK);
update_reg(reg2, plls, XELPDP_PMDEMAND_PLLS_MASK);
if (DISPLAY_VER(display) >= 30) {
update_reg(reg1, active_pipes, XE3_PMDEMAND_PIPES_MASK);
} else {
update_reg(reg1, active_pipes, XELPDP_PMDEMAND_PIPES_MASK);
update_reg(reg1, active_dbufs, XELPDP_PMDEMAND_DBUFS_MASK);
update_reg(reg2, scalers, XELPDP_PMDEMAND_SCALERS_MASK);
}
#undef update_reg
}
@ -514,6 +540,7 @@ intel_pmdemand_program_params(struct drm_i915_private *i915,
const struct intel_pmdemand_state *old,
bool serialized)
{
struct intel_display *display = &i915->display;
bool changed = false;
u32 reg1, mod_reg1;
u32 reg2, mod_reg2;
@ -529,7 +556,7 @@ intel_pmdemand_program_params(struct drm_i915_private *i915,
reg2 = intel_de_read(i915, XELPDP_INITIATE_PMDEMAND_REQUEST(1));
mod_reg2 = reg2;
intel_pmdemand_update_params(new, old, &mod_reg1, &mod_reg2,
intel_pmdemand_update_params(display, new, old, &mod_reg1, &mod_reg2,
serialized);
if (reg1 != mod_reg1) {

View File

@ -20,14 +20,14 @@ struct pmdemand_params {
u8 voltage_index;
u8 qclk_gv_index;
u8 active_pipes;
u8 active_dbufs;
u8 active_dbufs; /* pre-Xe3 only */
/* Total number of non type C active phys from active_phys_mask */
u8 active_phys;
u8 plls;
u16 cdclk_freq_mhz;
/* max from ddi_clocks[] */
u16 ddiclk_max;
u8 scalers;
u8 scalers; /* pre-Xe3 only */
};
struct intel_pmdemand_state {

View File

@ -29,10 +29,9 @@ static void pps_init_registers(struct intel_dp *intel_dp, bool force_disable_vdd
static const char *pps_name(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_pps *pps = &intel_dp->pps;
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
if (display->platform.valleyview || display->platform.cherryview) {
switch (pps->vlv_pps_pipe) {
case INVALID_PIPE:
/*
@ -122,7 +121,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
DP |= DP_PORT_WIDTH(1);
DP |= DP_LINK_TRAIN_PAT_1;
if (IS_CHERRYVIEW(dev_priv))
if (display->platform.cherryview)
DP |= DP_PIPE_SEL_CHV(pipe);
else
DP |= DP_PIPE_SEL(pipe);
@ -134,7 +133,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
* So enable temporarily it if it's not already enabled.
*/
if (!pll_enabled) {
release_cl_override = IS_CHERRYVIEW(dev_priv) &&
release_cl_override = display->platform.cherryview &&
!chv_phy_powergate_ch(dev_priv, phy, ch, true);
if (vlv_force_pll_on(dev_priv, pipe, vlv_get_dpll(dev_priv))) {
@ -356,10 +355,10 @@ static int intel_num_pps(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
if (display->platform.valleyview || display->platform.cherryview)
return 2;
if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
if (display->platform.geminilake || display->platform.broxton)
return 2;
if (INTEL_PCH_TYPE(i915) >= PCH_MTL)
@ -406,11 +405,10 @@ pps_initial_setup(struct intel_dp *intel_dp)
struct intel_display *display = to_intel_display(intel_dp);
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct intel_connector *connector = intel_dp->attached_connector;
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
lockdep_assert_held(&display->pps.mutex);
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
if (display->platform.valleyview || display->platform.cherryview) {
vlv_initial_power_sequencer_setup(intel_dp);
return true;
}
@ -509,9 +507,9 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp,
memset(regs, 0, sizeof(*regs));
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
if (display->platform.valleyview || display->platform.cherryview)
pps_idx = vlv_power_sequencer_pipe(intel_dp);
else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
else if (display->platform.geminilake || display->platform.broxton)
pps_idx = bxt_power_sequencer_idx(intel_dp);
else
pps_idx = intel_dp->pps.pps_idx;
@ -522,7 +520,7 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp,
regs->pp_off = PP_OFF_DELAYS(display, pps_idx);
/* Cycle delay moved from PP_DIVISOR to PP_CONTROL */
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv) ||
if (display->platform.geminilake || display->platform.broxton ||
INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
regs->pp_div = INVALID_MMIO_REG;
else
@ -552,11 +550,10 @@ _pp_stat_reg(struct intel_dp *intel_dp)
static bool edp_have_panel_power(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *dev_priv = to_i915(display->drm);
lockdep_assert_held(&display->pps.mutex);
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
if ((display->platform.valleyview || display->platform.cherryview) &&
intel_dp->pps.vlv_pps_pipe == INVALID_PIPE)
return false;
@ -566,11 +563,10 @@ static bool edp_have_panel_power(struct intel_dp *intel_dp)
static bool edp_have_panel_vdd(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *dev_priv = to_i915(display->drm);
lockdep_assert_held(&display->pps.mutex);
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
if ((display->platform.valleyview || display->platform.cherryview) &&
intel_dp->pps.vlv_pps_pipe == INVALID_PIPE)
return false;
@ -801,7 +797,8 @@ bool intel_pps_vdd_on_unlocked(struct intel_dp *intel_dp)
}
/*
* Must be paired with intel_pps_off().
* Must be paired with intel_pps_vdd_off() or - to disable
* both VDD and panel power - intel_pps_off().
* Nested calls to these functions are not allowed since
* we drop the lock. Caller must use some higher level
* locking to prevent nested calls from other threads.
@ -809,7 +806,6 @@ bool intel_pps_vdd_on_unlocked(struct intel_dp *intel_dp)
void intel_pps_vdd_on(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *i915 = to_i915(display->drm);
intel_wakeref_t wakeref;
bool vdd;
@ -819,10 +815,10 @@ void intel_pps_vdd_on(struct intel_dp *intel_dp)
vdd = false;
with_intel_pps_lock(intel_dp, wakeref)
vdd = intel_pps_vdd_on_unlocked(intel_dp);
I915_STATE_WARN(i915, !vdd, "[ENCODER:%d:%s] %s VDD already requested on\n",
dp_to_dig_port(intel_dp)->base.base.base.id,
dp_to_dig_port(intel_dp)->base.base.name,
pps_name(intel_dp));
INTEL_DISPLAY_STATE_WARN(display, !vdd, "[ENCODER:%d:%s] %s VDD already requested on\n",
dp_to_dig_port(intel_dp)->base.base.base.id,
dp_to_dig_port(intel_dp)->base.base.name,
pps_name(intel_dp));
}
static void intel_pps_vdd_off_sync_unlocked(struct intel_dp *intel_dp)
@ -861,8 +857,10 @@ static void intel_pps_vdd_off_sync_unlocked(struct intel_dp *intel_dp)
intel_de_read(display, pp_stat_reg),
intel_de_read(display, pp_ctrl_reg));
if ((pp & PANEL_POWER_ON) == 0)
if ((pp & PANEL_POWER_ON) == 0) {
intel_dp->pps.panel_power_off_time = ktime_get_boottime();
intel_dp_invalidate_source_oui(intel_dp);
}
intel_display_power_put(dev_priv,
intel_aux_power_domain(dig_port),
@ -929,18 +927,17 @@ static void edp_panel_vdd_schedule_off(struct intel_dp *intel_dp)
void intel_pps_vdd_off_unlocked(struct intel_dp *intel_dp, bool sync)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *dev_priv = to_i915(display->drm);
lockdep_assert_held(&display->pps.mutex);
if (!intel_dp_is_edp(intel_dp))
return;
I915_STATE_WARN(dev_priv, !intel_dp->pps.want_panel_vdd,
"[ENCODER:%d:%s] %s VDD not forced on",
dp_to_dig_port(intel_dp)->base.base.base.id,
dp_to_dig_port(intel_dp)->base.base.name,
pps_name(intel_dp));
INTEL_DISPLAY_STATE_WARN(display, !intel_dp->pps.want_panel_vdd,
"[ENCODER:%d:%s] %s VDD not forced on",
dp_to_dig_port(intel_dp)->base.base.base.id,
dp_to_dig_port(intel_dp)->base.base.name,
pps_name(intel_dp));
intel_dp->pps.want_panel_vdd = false;
@ -950,10 +947,20 @@ void intel_pps_vdd_off_unlocked(struct intel_dp *intel_dp, bool sync)
edp_panel_vdd_schedule_off(intel_dp);
}
void intel_pps_vdd_off(struct intel_dp *intel_dp)
{
intel_wakeref_t wakeref;
if (!intel_dp_is_edp(intel_dp))
return;
with_intel_pps_lock(intel_dp, wakeref)
intel_pps_vdd_off_unlocked(intel_dp, false);
}
void intel_pps_on_unlocked(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 pp;
i915_reg_t pp_ctrl_reg;
@ -978,7 +985,7 @@ void intel_pps_on_unlocked(struct intel_dp *intel_dp)
pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
pp = ilk_get_pp_control(intel_dp);
if (IS_IRONLAKE(dev_priv)) {
if (display->platform.ironlake) {
/* ILK workaround: disable reset around power sequence */
pp &= ~PANEL_POWER_RESET;
intel_de_write(display, pp_ctrl_reg, pp);
@ -994,7 +1001,7 @@ void intel_pps_on_unlocked(struct intel_dp *intel_dp)
0, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
pp |= PANEL_POWER_ON;
if (!IS_IRONLAKE(dev_priv))
if (!display->platform.ironlake)
pp |= PANEL_POWER_RESET;
intel_de_write(display, pp_ctrl_reg, pp);
@ -1007,7 +1014,7 @@ void intel_pps_on_unlocked(struct intel_dp *intel_dp)
intel_de_rmw(display, SOUTH_DSPCLK_GATE_D,
PCH_DPLSUNIT_CLOCK_GATE_DISABLE, 0);
if (IS_IRONLAKE(dev_priv)) {
if (display->platform.ironlake) {
pp |= PANEL_POWER_RESET; /* restore panel reset bit */
intel_de_write(display, pp_ctrl_reg, pp);
intel_de_posting_read(display, pp_ctrl_reg);
@ -1063,6 +1070,8 @@ void intel_pps_off_unlocked(struct intel_dp *intel_dp)
wait_panel_off(intel_dp);
intel_dp->pps.panel_power_off_time = ktime_get_boottime();
intel_dp_invalidate_source_oui(intel_dp);
/* We got a reference when we enabled the VDD. */
intel_display_power_put(dev_priv,
intel_aux_power_domain(dig_port),
@ -1148,7 +1157,7 @@ void intel_pps_backlight_power(struct intel_connector *connector, bool enable)
return;
drm_dbg_kms(display->drm, "panel power control backlight %s\n",
enable ? "enable" : "disable");
str_enable_disable(enable));
if (enable)
intel_pps_backlight_on(intel_dp);
@ -1627,7 +1636,7 @@ static void pps_init_registers(struct intel_dp *intel_dp, bool force_disable_vdd
/* Haswell doesn't have any port selection bits for the panel
* power sequencer any more. */
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
if (display->platform.valleyview || display->platform.cherryview) {
port_sel = PANEL_PORT_SELECT_VLV(port);
} else if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) {
switch (port) {
@ -1674,7 +1683,6 @@ static void pps_init_registers(struct intel_dp *intel_dp, bool force_disable_vdd
void intel_pps_encoder_reset(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *i915 = to_i915(display->drm);
intel_wakeref_t wakeref;
if (!intel_dp_is_edp(intel_dp))
@ -1685,7 +1693,7 @@ void intel_pps_encoder_reset(struct intel_dp *intel_dp)
* Reinit the power sequencer also on the resume path, in case
* BIOS did something nasty with it.
*/
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
if (display->platform.valleyview || display->platform.cherryview)
vlv_initial_power_sequencer_setup(intel_dp);
pps_init_delays(intel_dp);
@ -1721,11 +1729,10 @@ bool intel_pps_init(struct intel_dp *intel_dp)
static void pps_init_late(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct intel_connector *connector = intel_dp->attached_connector;
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
if (display->platform.valleyview || display->platform.cherryview)
return;
if (intel_num_pps(display) < 2)
@ -1783,9 +1790,9 @@ void intel_pps_setup(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (HAS_PCH_SPLIT(i915) || IS_GEMINILAKE(i915) || IS_BROXTON(i915))
if (HAS_PCH_SPLIT(i915) || display->platform.geminilake || display->platform.broxton)
display->pps.mmio_base = PCH_PPS_BASE;
else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
else if (display->platform.valleyview || display->platform.cherryview)
display->pps.mmio_base = VLV_PPS_BASE;
else
display->pps.mmio_base = PPS_BASE;
@ -1857,7 +1864,7 @@ void assert_pps_unlocked(struct intel_display *display, enum pipe pipe)
MISSING_CASE(port_sel);
break;
}
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
} else if (display->platform.valleyview || display->platform.cherryview) {
/* presumably write lock depends on pipe, not port select */
pp_reg = PP_CONTROL(display, pipe);
panel_pipe = pipe;
@ -1878,7 +1885,7 @@ void assert_pps_unlocked(struct intel_display *display, enum pipe pipe)
((val & PANEL_UNLOCK_MASK) == PANEL_UNLOCK_REGS))
locked = false;
I915_STATE_WARN(dev_priv, panel_pipe == pipe && locked,
"panel assertion failure, pipe %c regs locked\n",
pipe_name(pipe));
INTEL_DISPLAY_STATE_WARN(display, panel_pipe == pipe && locked,
"panel assertion failure, pipe %c regs locked\n",
pipe_name(pipe));
}

View File

@ -34,6 +34,7 @@ void intel_pps_off_unlocked(struct intel_dp *intel_dp);
void intel_pps_check_power_unlocked(struct intel_dp *intel_dp);
void intel_pps_vdd_on(struct intel_dp *intel_dp);
void intel_pps_vdd_off(struct intel_dp *intel_dp);
void intel_pps_on(struct intel_dp *intel_dp);
void intel_pps_off(struct intel_dp *intel_dp);
void intel_pps_vdd_off_sync(struct intel_dp *intel_dp);

View File

@ -233,7 +233,9 @@ static bool psr_global_enabled(struct intel_dp *intel_dp)
switch (intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK) {
case I915_PSR_DEBUG_DEFAULT:
if (display->params.enable_psr == -1)
return connector->panel.vbt.psr.enable;
return intel_dp_is_edp(intel_dp) ?
connector->panel.vbt.psr.enable :
true;
return display->params.enable_psr;
case I915_PSR_DEBUG_DISABLE:
return false;
@ -1451,11 +1453,15 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false;
}
if (DISPLAY_VER(display) >= 12) {
if (DISPLAY_VER(display) >= 20) {
psr_max_h = crtc_hdisplay;
psr_max_v = crtc_vdisplay;
max_bpp = crtc_state->pipe_bpp;
} else if (IS_DISPLAY_VER(display, 12, 14)) {
psr_max_h = 5120;
psr_max_v = 3200;
max_bpp = 30;
} else if (DISPLAY_VER(display) >= 10) {
} else if (IS_DISPLAY_VER(display, 10, 11)) {
psr_max_h = 4096;
psr_max_v = 2304;
max_bpp = 24;
@ -1912,14 +1918,14 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
* cause issues if non-supported panels are used.
*/
if (!intel_dp->psr.panel_replay_enabled &&
(IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_A0, STEP_B0) ||
(IS_DISPLAY_VERx100_STEP(display, 1400, STEP_A0, STEP_B0) ||
IS_ALDERLAKE_P(dev_priv)))
intel_de_rmw(display, hsw_chicken_trans_reg(dev_priv, cpu_transcoder),
0, ADLP_1_BASED_X_GRANULARITY);
/* Wa_16012604467:adlp,mtl[a0,b0] */
if (!intel_dp->psr.panel_replay_enabled &&
IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_A0, STEP_B0))
IS_DISPLAY_VERx100_STEP(display, 1400, STEP_A0, STEP_B0))
intel_de_rmw(display,
MTL_CLKGATE_DIS_TRANS(display, cpu_transcoder),
0,
@ -2007,6 +2013,15 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
intel_dp->psr.enabled = true;
intel_dp->psr.paused = false;
/*
* Link_ok is sticky and set here on PSR enable. We can assume link
* training is complete as we never continue to PSR enable with
* untrained link. Link_ok is kept as set until first short pulse
* interrupt. This is targeted to workaround panels stating bad link
* after PSR is enabled.
*/
intel_dp->psr.link_ok = true;
intel_psr_activate(intel_dp);
}
@ -2104,7 +2119,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
if (intel_dp->psr.sel_update_enabled) {
/* Wa_16012604467:adlp,mtl[a0,b0] */
if (!intel_dp->psr.panel_replay_enabled &&
IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_A0, STEP_B0))
IS_DISPLAY_VERx100_STEP(display, 1400, STEP_A0, STEP_B0))
intel_de_rmw(display,
MTL_CLKGATE_DIS_TRANS(display, cpu_transcoder),
MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS, 0);
@ -2166,6 +2181,8 @@ void intel_psr_disable(struct intel_dp *intel_dp,
intel_psr_disable_locked(intel_dp);
intel_dp->psr.link_ok = false;
mutex_unlock(&intel_dp->psr.lock);
cancel_work_sync(&intel_dp->psr.work);
cancel_delayed_work_sync(&intel_dp->psr.dc3co_work);
@ -2559,7 +2576,7 @@ intel_psr_apply_su_area_workarounds(struct intel_crtc_state *crtc_state)
/* Wa_14014971492 */
if (!crtc_state->has_panel_replay &&
((IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_A0, STEP_B0) ||
((IS_DISPLAY_VERx100_STEP(display, 1400, STEP_A0, STEP_B0) ||
IS_ALDERLAKE_P(i915) || IS_TIGERLAKE(i915))) &&
crtc_state->splitter.enable)
crtc_state->psr2_su_area.y1 = 0;
@ -3456,6 +3473,8 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp)
mutex_lock(&psr->lock);
psr->link_ok = false;
if (!psr->enabled)
goto exit;
@ -3515,6 +3534,33 @@ bool intel_psr_enabled(struct intel_dp *intel_dp)
return ret;
}
/**
* intel_psr_link_ok - return psr->link_ok
* @intel_dp: struct intel_dp
*
* We are seeing unexpected link re-trainings with some panels. This is caused
* by panel stating bad link status after PSR is enabled. Code checking link
* status can call this to ensure it can ignore bad link status stated by the
* panel I.e. if panel is stating bad link and intel_psr_link_ok is stating link
* is ok caller should rely on latter.
*
* Return value of link_ok
*/
bool intel_psr_link_ok(struct intel_dp *intel_dp)
{
bool ret;
if ((!CAN_PSR(intel_dp) && !CAN_PANEL_REPLAY(intel_dp)) ||
!intel_dp_is_edp(intel_dp))
return false;
mutex_lock(&intel_dp->psr.lock);
ret = intel_dp->psr.link_ok;
mutex_unlock(&intel_dp->psr.lock);
return ret;
}
/**
* intel_psr_lock - grab PSR lock
* @crtc_state: the crtc state

View File

@ -59,6 +59,7 @@ void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_st
void intel_psr_pause(struct intel_dp *intel_dp);
void intel_psr_resume(struct intel_dp *intel_dp);
bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state);
bool intel_psr_link_ok(struct intel_dp *intel_dp);
void intel_psr_lock(const struct intel_crtc_state *crtc_state);
void intel_psr_unlock(const struct intel_crtc_state *crtc_state);

View File

@ -298,7 +298,7 @@
#define _PORT_ALPM_CTL_B 0x16fc2c
#define PORT_ALPM_CTL(port) _MMIO_PORT(port, _PORT_ALPM_CTL_A, _PORT_ALPM_CTL_B)
#define PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE REG_BIT(31)
#define PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK REG_GENMASK(23, 20)
#define PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK REG_GENMASK(25, 20)
#define PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(val) REG_FIELD_PREP(PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK, val)
#define PORT_ALPM_CTL_MAX_PHY_SWING_HOLD_MASK REG_GENMASK(19, 16)
#define PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(val) REG_FIELD_PREP(PORT_ALPM_CTL_MAX_PHY_SWING_HOLD_MASK, val)

View File

@ -2082,10 +2082,10 @@ intel_sdvo_get_edid(struct drm_connector *connector)
static const struct drm_edid *
intel_sdvo_get_analog_edid(struct drm_connector *connector)
{
struct drm_i915_private *i915 = to_i915(connector->dev);
struct intel_display *display = to_intel_display(connector->dev);
struct i2c_adapter *ddc;
ddc = intel_gmbus_get_adapter(i915, i915->display.vbt.crt_ddc_pin);
ddc = intel_gmbus_get_adapter(display, display->vbt.crt_ddc_pin);
if (!ddc)
return NULL;
@ -2638,6 +2638,7 @@ intel_sdvo_select_ddc_bus(struct intel_sdvo *sdvo,
static void
intel_sdvo_select_i2c_bus(struct intel_sdvo *sdvo)
{
struct intel_display *display = to_intel_display(&sdvo->base);
struct drm_i915_private *dev_priv = to_i915(sdvo->base.base.dev);
const struct sdvo_device_mapping *mapping;
u8 pin;
@ -2648,7 +2649,7 @@ intel_sdvo_select_i2c_bus(struct intel_sdvo *sdvo)
mapping = &dev_priv->display.vbt.sdvo_mappings[1];
if (mapping->initialized &&
intel_gmbus_is_valid_pin(dev_priv, mapping->i2c_pin))
intel_gmbus_is_valid_pin(display, mapping->i2c_pin))
pin = mapping->i2c_pin;
else
pin = GMBUS_PIN_DPB;
@ -2657,7 +2658,7 @@ intel_sdvo_select_i2c_bus(struct intel_sdvo *sdvo)
sdvo->base.base.base.id, sdvo->base.base.name,
pin, sdvo->target_addr);
sdvo->i2c = intel_gmbus_get_adapter(dev_priv, pin);
sdvo->i2c = intel_gmbus_get_adapter(display, pin);
/*
* With gmbus we should be able to drive sdvo i2c at 2MHz, but somehow

View File

@ -1997,6 +1997,7 @@ int intel_snps_phy_check_hdmi_link_rate(int clock)
void intel_mpllb_state_verify(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
@ -2019,11 +2020,11 @@ void intel_mpllb_state_verify(struct intel_atomic_state *state,
intel_mpllb_readout_hw_state(encoder, &mpllb_hw_state);
#define MPLLB_CHECK(__name) \
I915_STATE_WARN(i915, mpllb_sw_state->__name != mpllb_hw_state.__name, \
"[CRTC:%d:%s] mismatch in MPLLB: %s (expected 0x%08x, found 0x%08x)", \
crtc->base.base.id, crtc->base.name, \
__stringify(__name), \
mpllb_sw_state->__name, mpllb_hw_state.__name)
INTEL_DISPLAY_STATE_WARN(display, mpllb_sw_state->__name != mpllb_hw_state.__name, \
"[CRTC:%d:%s] mismatch in MPLLB: %s (expected 0x%08x, found 0x%08x)", \
crtc->base.base.id, crtc->base.name, \
__stringify(__name), \
mpllb_sw_state->__name, mpllb_hw_state.__name)
MPLLB_CHECK(mpllb_cp);
MPLLB_CHECK(mpllb_div);

View File

@ -1005,7 +1005,7 @@ xelpdp_tc_phy_wait_for_tcss_power(struct intel_tc_port *tc, bool enabled)
if (wait_for(xelpdp_tc_phy_tcss_power_is_enabled(tc) == enabled, 5)) {
drm_dbg_kms(&i915->drm,
"Port %s: timeout waiting for TCSS power to get %s\n",
enabled ? "enabled" : "disabled",
str_enabled_disabled(enabled),
tc->port_name);
return false;
}

View File

@ -1093,7 +1093,6 @@ intel_tv_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode;
struct drm_display_mode mode = {};
@ -1167,7 +1166,7 @@ intel_tv_get_config(struct intel_encoder *encoder,
adjusted_mode->crtc_clock /= 2;
/* pixel counter doesn't work on i965gm TV output */
if (IS_I965GM(dev_priv))
if (display->platform.i965gm)
pipe_config->mode_flags |=
I915_MODE_FLAG_USE_SCANLINE_COUNTER;
}
@ -1197,7 +1196,6 @@ intel_tv_compute_config(struct intel_encoder *encoder,
struct intel_atomic_state *state =
to_intel_atomic_state(pipe_config->uapi.state);
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_tv_connector_state *tv_conn_state =
to_intel_tv_connector_state(conn_state);
const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
@ -1349,7 +1347,7 @@ intel_tv_compute_config(struct intel_encoder *encoder,
adjusted_mode->name[0] = '\0';
/* pixel counter doesn't work on i965gm TV output */
if (IS_I965GM(dev_priv))
if (display->platform.i965gm)
pipe_config->mode_flags |=
I915_MODE_FLAG_USE_SCANLINE_COUNTER;
@ -1525,7 +1523,7 @@ static void intel_tv_pre_enable(struct intel_atomic_state *state,
tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
/* Enable two fixes for the chips that need them. */
if (IS_I915GM(dev_priv))
if (display->platform.i915gm)
tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
set_tv_mode_timings(display, tv_mode, burst_ena);
@ -1627,7 +1625,7 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
* The TV sense state should be cleared to zero on cantiga platform. Otherwise
* the TV is misdetected. This is hardware requirement.
*/
if (IS_GM45(dev_priv))
if (display->platform.gm45)
tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);

View File

@ -195,7 +195,6 @@ static u32 __intel_get_crtc_scanline_from_timestamp(struct intel_crtc *crtc)
int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
/*
* The scanline counter increments at the leading edge of hsync.
@ -225,7 +224,7 @@ int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state)
*/
if (DISPLAY_VER(display) == 2)
return -1;
else if (HAS_DDI(i915) && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
else if (HAS_DDI(display) && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
return 2;
else
return 1;
@ -327,14 +326,13 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,
const struct drm_display_mode *mode)
{
struct intel_display *display = to_intel_display(_crtc->dev);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_crtc *crtc = to_intel_crtc(_crtc);
enum pipe pipe = crtc->pipe;
int position;
int vbl_start, vbl_end, hsync_start, htotal, vtotal;
unsigned long irqflags;
bool use_scanline_counter = DISPLAY_VER(display) >= 5 ||
IS_G4X(dev_priv) || DISPLAY_VER(display) == 2 ||
display->platform.g4x || DISPLAY_VER(display) == 2 ||
crtc->mode_flags & I915_MODE_FLAG_USE_SCANLINE_COUNTER;
if (drm_WARN_ON(display->drm, !mode->crtc_clock)) {
@ -603,14 +601,15 @@ void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state,
const struct intel_crtc_state *new_crtc_state,
struct intel_vblank_evade_ctx *evade)
{
struct intel_display *display = to_intel_display(new_crtc_state);
struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
const struct intel_crtc_state *crtc_state;
const struct drm_display_mode *adjusted_mode;
evade->crtc = crtc;
evade->need_vlv_dsi_wa = (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) &&
evade->need_vlv_dsi_wa = (display->platform.valleyview ||
display->platform.cherryview) &&
intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
/*

View File

@ -16,9 +16,7 @@
static i915_reg_t intel_vga_cntrl_reg(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
if (display->platform.valleyview || display->platform.cherryview)
return VLV_VGACNTRL;
else if (DISPLAY_VER(display) >= 5)
return CPU_VGACNTRL;

View File

@ -56,6 +56,11 @@ bool intel_vrr_is_in_range(struct intel_connector *connector, int vrefresh)
vrefresh <= info->monitor_range.max_vfreq;
}
bool intel_vrr_possible(const struct intel_crtc_state *crtc_state)
{
return crtc_state->vrr.flipline;
}
void
intel_vrr_check_modeset(struct intel_atomic_state *state)
{
@ -239,11 +244,16 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
(crtc_state->hw.adjusted_mode.crtc_vtotal -
crtc_state->hw.adjusted_mode.vsync_end);
}
}
void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
if (!intel_vrr_possible(crtc_state))
return;
/*
* For XE_LPD+, we use guardband and pipeline override
* is deprecated.
*/
if (DISPLAY_VER(display) >= 13) {
crtc_state->vrr.guardband =
crtc_state->vrr.vmin + 1 - adjusted_mode->crtc_vblank_start;
@ -281,7 +291,7 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
intel_de_rmw(display, CHICKEN_TRANS(cpu_transcoder),
0, PIPE_VBLANK_WITH_DELAY);
if (!crtc_state->vrr.flipline) {
if (!intel_vrr_possible(crtc_state)) {
intel_de_write(display,
TRANS_VRR_CTL(display, cpu_transcoder), 0);
return;

View File

@ -15,9 +15,11 @@ struct intel_crtc_state;
bool intel_vrr_is_capable(struct intel_connector *connector);
bool intel_vrr_is_in_range(struct intel_connector *connector, int vrefresh);
bool intel_vrr_possible(const struct intel_crtc_state *crtc_state);
void intel_vrr_check_modeset(struct intel_atomic_state *state);
void intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state);
void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state);
void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state);
void intel_vrr_enable(const struct intel_crtc_state *crtc_state);
void intel_vrr_send_push(const struct intel_crtc_state *crtc_state);

View File

@ -272,7 +272,6 @@ int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
to_intel_plane(plane_state->uapi.plane);
struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
struct drm_framebuffer *fb = plane_state->hw.fb;
int ret;
bool force_detach = !fb || !plane_state->uapi.visible;
bool need_scaler = false;
@ -281,72 +280,16 @@ int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
fb && intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
need_scaler = true;
ret = skl_update_scaler(crtc_state, force_detach,
drm_plane_index(&intel_plane->base),
&plane_state->scaler_id,
drm_rect_width(&plane_state->uapi.src) >> 16,
drm_rect_height(&plane_state->uapi.src) >> 16,
drm_rect_width(&plane_state->uapi.dst),
drm_rect_height(&plane_state->uapi.dst),
fb ? fb->format : NULL,
fb ? fb->modifier : 0,
need_scaler);
if (ret || plane_state->scaler_id < 0)
return ret;
/* check colorkey */
if (plane_state->ckey.flags) {
drm_dbg_kms(&dev_priv->drm,
"[PLANE:%d:%s] scaling with color key not allowed",
intel_plane->base.base.id,
intel_plane->base.name);
return -EINVAL;
}
/* Check src format */
switch (fb->format->format) {
case DRM_FORMAT_RGB565:
case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ABGR8888:
case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_XRGB2101010:
case DRM_FORMAT_XBGR2101010:
case DRM_FORMAT_ARGB2101010:
case DRM_FORMAT_ABGR2101010:
case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
case DRM_FORMAT_NV12:
case DRM_FORMAT_XYUV8888:
case DRM_FORMAT_P010:
case DRM_FORMAT_P012:
case DRM_FORMAT_P016:
case DRM_FORMAT_Y210:
case DRM_FORMAT_Y212:
case DRM_FORMAT_Y216:
case DRM_FORMAT_XVYU2101010:
case DRM_FORMAT_XVYU12_16161616:
case DRM_FORMAT_XVYU16161616:
break;
case DRM_FORMAT_XBGR16161616F:
case DRM_FORMAT_ABGR16161616F:
case DRM_FORMAT_XRGB16161616F:
case DRM_FORMAT_ARGB16161616F:
if (DISPLAY_VER(dev_priv) >= 11)
break;
fallthrough;
default:
drm_dbg_kms(&dev_priv->drm,
"[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n",
intel_plane->base.base.id, intel_plane->base.name,
fb->base.id, fb->format->format);
return -EINVAL;
}
return 0;
return skl_update_scaler(crtc_state, force_detach,
drm_plane_index(&intel_plane->base),
&plane_state->scaler_id,
drm_rect_width(&plane_state->uapi.src) >> 16,
drm_rect_height(&plane_state->uapi.src) >> 16,
drm_rect_width(&plane_state->uapi.dst),
drm_rect_height(&plane_state->uapi.dst),
fb ? fb->format : NULL,
fb ? fb->modifier : 0,
need_scaler);
}
static int intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state,

View File

@ -431,6 +431,16 @@ static int icl_plane_min_width(const struct drm_framebuffer *fb,
}
}
static int xe3_plane_max_width(const struct drm_framebuffer *fb,
int color_plane,
unsigned int rotation)
{
if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
return 4096;
else
return 6144;
}
static int icl_hdr_plane_max_width(const struct drm_framebuffer *fb,
int color_plane,
unsigned int rotation)
@ -1567,17 +1577,22 @@ skl_plane_async_flip(struct intel_dsb *dsb,
struct intel_display *display = to_intel_display(plane->base.dev);
enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe;
u32 plane_ctl = plane_state->ctl;
u32 plane_ctl = plane_state->ctl, plane_surf;
plane_ctl |= skl_plane_ctl_crtc(crtc_state);
plane_surf = skl_plane_surf(plane_state, 0);
if (async_flip)
plane_ctl |= PLANE_CTL_ASYNC_FLIP;
if (async_flip) {
if (DISPLAY_VER(display) >= 30)
plane_surf |= PLANE_SURF_ASYNC_UPDATE;
else
plane_ctl |= PLANE_CTL_ASYNC_FLIP;
}
intel_de_write_dsb(display, dsb, PLANE_CTL(pipe, plane_id),
plane_ctl);
intel_de_write_dsb(display, dsb, PLANE_SURF(pipe, plane_id),
skl_plane_surf(plane_state, 0));
plane_surf);
}
static bool intel_format_is_p01x(u32 format)
@ -2584,7 +2599,11 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
intel_fbc_add_plane(skl_plane_fbc(dev_priv, pipe, plane_id), plane);
if (DISPLAY_VER(dev_priv) >= 11) {
if (DISPLAY_VER(dev_priv) >= 30) {
plane->max_width = xe3_plane_max_width;
plane->max_height = icl_plane_max_height;
plane->min_cdclk = icl_plane_min_cdclk;
} else if (DISPLAY_VER(dev_priv) >= 11) {
plane->min_width = icl_plane_min_width;
if (icl_is_hdr_plane(dev_priv, plane_id))
plane->max_width = icl_hdr_plane_max_width;

View File

@ -159,6 +159,7 @@
_PLANE_SURF_2_A, _PLANE_SURF_2_B)
#define PLANE_SURF_ADDR_MASK REG_GENMASK(31, 12)
#define PLANE_SURF_DECRYPT REG_BIT(2)
#define PLANE_SURF_ASYNC_UPDATE REG_BIT(0)
#define _PLANE_KEYMAX_1_A 0x701a0
#define _PLANE_KEYMAX_2_A 0x702a0

View File

@ -718,7 +718,7 @@ static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
int width, const struct drm_format_info *format,
u64 modifier, unsigned int rotation,
u32 plane_pixel_rate, struct skl_wm_params *wp,
int color_plane);
int color_plane, unsigned int pan_x);
static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
struct intel_plane *plane,
@ -765,7 +765,7 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
drm_format_info(DRM_FORMAT_ARGB8888),
DRM_FORMAT_MOD_LINEAR,
DRM_MODE_ROTATE_0,
crtc_state->pixel_rate, &wp, 0);
crtc_state->pixel_rate, &wp, 0, 0);
drm_WARN_ON(&i915->drm, ret);
for (level = 0; level < i915->display.wm.num_levels; level++) {
@ -1742,7 +1742,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
int width, const struct drm_format_info *format,
u64 modifier, unsigned int rotation,
u32 plane_pixel_rate, struct skl_wm_params *wp,
int color_plane)
int color_plane, unsigned int pan_x)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
@ -1803,7 +1803,9 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
wp->y_min_scanlines,
wp->dbuf_block_size);
if (DISPLAY_VER(i915) >= 10)
if (DISPLAY_VER(i915) >= 30)
interm_pbpl += (pan_x != 0);
else if (DISPLAY_VER(i915) >= 10)
interm_pbpl++;
wp->plane_blocks_per_line = div_fixed16(interm_pbpl,
@ -1845,7 +1847,8 @@ skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state,
fb->format, fb->modifier,
plane_state->hw.rotation,
intel_plane_pixel_rate(crtc_state, plane_state),
wp, color_plane);
wp, color_plane,
plane_state->uapi.src.x1);
}
static bool skl_wm_has_lines(struct drm_i915_private *i915, int level)
@ -1909,7 +1912,10 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
}
}
blocks = fixed16_to_u32_round_up(selected_result) + 1;
blocks = fixed16_to_u32_round_up(selected_result);
if (DISPLAY_VER(i915) < 30)
blocks++;
/*
* Lets have blocks at minimum equivalent to plane_blocks_per_line
* as there will be at minimum one line for lines configuration. This
@ -3527,7 +3533,7 @@ static void intel_mbus_dbox_update(struct intel_atomic_state *state)
for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, new_dbuf_state->active_pipes) {
u32 pipe_val = val;
if (DISPLAY_VER_FULL(i915) == IP_VER(14, 0)) {
if (DISPLAY_VERx100(i915) == 1400) {
if (xelpdp_is_only_pipe_per_dbuf_bank(crtc->pipe,
new_dbuf_state->active_pipes))
pipe_val |= MBUS_DBOX_BW_8CREDITS_MTL;

View File

@ -44,6 +44,7 @@
#include "intel_dsi_vbt.h"
#include "intel_fifo_underrun.h"
#include "intel_panel.h"
#include "intel_pfit.h"
#include "skl_scaler.h"
#include "vlv_dsi.h"
#include "vlv_dsi_pll.h"

View File

@ -592,15 +592,16 @@ void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
static void assert_dsi_pll(struct drm_i915_private *i915, bool state)
{
struct intel_display *display = &i915->display;
bool cur_state;
vlv_cck_get(i915);
cur_state = vlv_cck_read(i915, CCK_REG_DSI_PLL_CONTROL) & DSI_PLL_VCO_EN;
vlv_cck_put(i915);
I915_STATE_WARN(i915, cur_state != state,
"DSI PLL state assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
"DSI PLL state assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
}
void assert_dsi_pll_enabled(struct drm_i915_private *i915)

View File

@ -399,7 +399,8 @@ static void emit_batch(struct i915_vma * const vma,
batch_add(&cmds, MI_LOAD_REGISTER_IMM(2));
batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_0_GEN7));
batch_add(&cmds, 0xffff0000 |
((IS_IVB_GT1(i915) || IS_VALLEYVIEW(i915)) ?
(((IS_IVYBRIDGE(i915) && INTEL_INFO(i915)->gt == 1) ||
IS_VALLEYVIEW(i915)) ?
HIZ_RAW_STALL_OPT_DISABLE :
0));
batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_1));

View File

@ -185,7 +185,7 @@ int intel_gt_init_hw(struct intel_gt *gt)
if (IS_HASWELL(i915))
intel_uncore_write(uncore,
HSW_MI_PREDICATE_RESULT_2,
IS_HASWELL_GT3(i915) ?
INTEL_INFO(i915)->gt == 3 ?
LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED);
/* Apply the GT workarounds... */

View File

@ -452,10 +452,10 @@ void gen8_gt_irq_reset(struct intel_gt *gt)
{
struct intel_uncore *uncore = gt->uncore;
gen3_irq_reset(uncore, GEN8_GT_IRQ_REGS(0));
gen3_irq_reset(uncore, GEN8_GT_IRQ_REGS(1));
gen3_irq_reset(uncore, GEN8_GT_IRQ_REGS(2));
gen3_irq_reset(uncore, GEN8_GT_IRQ_REGS(3));
gen2_irq_reset(uncore, GEN8_GT_IRQ_REGS(0));
gen2_irq_reset(uncore, GEN8_GT_IRQ_REGS(1));
gen2_irq_reset(uncore, GEN8_GT_IRQ_REGS(2));
gen2_irq_reset(uncore, GEN8_GT_IRQ_REGS(3));
}
void gen8_gt_irq_postinstall(struct intel_gt *gt)
@ -476,14 +476,14 @@ void gen8_gt_irq_postinstall(struct intel_gt *gt)
gt->pm_ier = 0x0;
gt->pm_imr = ~gt->pm_ier;
gen3_irq_init(uncore, GEN8_GT_IRQ_REGS(0), ~gt_interrupts[0], gt_interrupts[0]);
gen3_irq_init(uncore, GEN8_GT_IRQ_REGS(1), ~gt_interrupts[1], gt_interrupts[1]);
gen2_irq_init(uncore, GEN8_GT_IRQ_REGS(0), ~gt_interrupts[0], gt_interrupts[0]);
gen2_irq_init(uncore, GEN8_GT_IRQ_REGS(1), ~gt_interrupts[1], gt_interrupts[1]);
/*
* RPS interrupts will get enabled/disabled on demand when RPS itself
* is enabled/disabled. Same wil be the case for GuC interrupts.
*/
gen3_irq_init(uncore, GEN8_GT_IRQ_REGS(2), gt->pm_imr, gt->pm_ier);
gen3_irq_init(uncore, GEN8_GT_IRQ_REGS(3), ~gt_interrupts[3], gt_interrupts[3]);
gen2_irq_init(uncore, GEN8_GT_IRQ_REGS(2), gt->pm_imr, gt->pm_ier);
gen2_irq_init(uncore, GEN8_GT_IRQ_REGS(3), ~gt_interrupts[3], gt_interrupts[3]);
}
static void gen5_gt_update_irq(struct intel_gt *gt,
@ -514,9 +514,9 @@ void gen5_gt_irq_reset(struct intel_gt *gt)
{
struct intel_uncore *uncore = gt->uncore;
gen3_irq_reset(uncore, GT_IRQ_REGS);
gen2_irq_reset(uncore, GT_IRQ_REGS);
if (GRAPHICS_VER(gt->i915) >= 6)
gen3_irq_reset(uncore, GEN6_PM_IRQ_REGS);
gen2_irq_reset(uncore, GEN6_PM_IRQ_REGS);
}
void gen5_gt_irq_postinstall(struct intel_gt *gt)
@ -538,7 +538,7 @@ void gen5_gt_irq_postinstall(struct intel_gt *gt)
else
gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT;
gen3_irq_init(uncore, GT_IRQ_REGS, gt->gt_imr, gt_irqs);
gen2_irq_init(uncore, GT_IRQ_REGS, gt->gt_imr, gt_irqs);
if (GRAPHICS_VER(gt->i915) >= 6) {
/*
@ -551,6 +551,6 @@ void gen5_gt_irq_postinstall(struct intel_gt *gt)
}
gt->pm_imr = 0xffffffff;
gen3_irq_init(uncore, GEN6_PM_IRQ_REGS, gt->pm_imr, pm_irqs);
gen2_irq_init(uncore, GEN6_PM_IRQ_REGS, gt->pm_imr, pm_irqs);
}
}

View File

@ -820,8 +820,10 @@ static bool ctx_needs_runalone(const struct intel_context *ce)
bool ctx_is_protected = false;
/*
* On MTL and newer platforms, protected contexts require setting
* the LRC run-alone bit or else the encryption will not happen.
* Wa_14019159160 - Case 2.
* On some platforms, protected contexts require setting
* the LRC run-alone bit or else the encryption/decryption will not happen.
* NOTE: Case 2 only applies to PXP use-case of said workaround.
*/
if (GRAPHICS_VER_FULL(ce->engine->i915) >= IP_VER(12, 70) &&
(ce->engine->class == COMPUTE_CLASS || ce->engine->class == RENDER_CLASS)) {
@ -850,6 +852,7 @@ static void init_common_regs(u32 * const regs,
if (GRAPHICS_VER(engine->i915) < 11)
ctl |= _MASKED_BIT_DISABLE(CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT |
CTX_CTRL_RS_CTX_ENABLE);
/* Wa_14019159160 - Case 2.*/
if (ctx_needs_runalone(ce))
ctl |= _MASKED_BIT_ENABLE(GEN12_CTX_CTRL_RUNALONE_MODE);
regs[CTX_CONTEXT_CONTROL] = ctl;

View File

@ -418,7 +418,7 @@ static void bdw_ctx_workarounds_init(struct intel_engine_cs *engine,
/* WaForceContextSaveRestoreNonCoherent:bdw */
HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
/* WaDisableFenceDestinationToSLM:bdw (pre-prod) */
(IS_BROADWELL_GT3(i915) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
(INTEL_INFO(i915)->gt == 3 ? HDC_FENCE_DEST_SLM_DISABLE : 0));
}
static void chv_ctx_workarounds_init(struct intel_engine_cs *engine,
@ -2546,7 +2546,7 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
GEN7_FF_DS_SCHED_HW);
/* WaDisablePSDDualDispatchEnable:ivb */
if (IS_IVB_GT1(i915))
if (INTEL_INFO(i915)->gt == 1)
wa_masked_en(wal,
GEN7_HALF_SLICE_CHICKEN1,
GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE);

View File

@ -32,6 +32,8 @@
*
*/
#include <drm/display/drm_dp.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "gvt.h"
@ -568,7 +570,7 @@ static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num,
memcpy(port->dpcd->data, dpcd_fix_data, DPCD_HEADER_SIZE);
port->dpcd->data_valid = true;
port->dpcd->data[DPCD_SINK_COUNT] = 0x1;
port->dpcd->data[DP_SINK_COUNT] = 0x1;
port->type = type;
port->id = resolution;
port->vrefresh_k = GVT_DEFAULT_REFRESH_RATE * MSEC_PER_SEC;

View File

@ -59,52 +59,10 @@ struct intel_vgpu;
#define INTEL_GVT_MAX_UEVENT_VARS 3
/* DPCD start */
#define DPCD_SIZE 0x700
/* DPCD */
#define DP_SET_POWER 0x600
#define DP_SET_POWER_D0 0x1
#define AUX_NATIVE_WRITE 0x8
#define AUX_NATIVE_READ 0x9
#define AUX_NATIVE_REPLY_MASK (0x3 << 4)
#define AUX_NATIVE_REPLY_ACK (0x0 << 4)
#define AUX_NATIVE_REPLY_NAK (0x1 << 4)
#define AUX_NATIVE_REPLY_DEFER (0x2 << 4)
#define AUX_BURST_SIZE 20
/* DPCD addresses */
#define DPCD_REV 0x000
#define DPCD_MAX_LINK_RATE 0x001
#define DPCD_MAX_LANE_COUNT 0x002
#define DPCD_TRAINING_PATTERN_SET 0x102
#define DPCD_SINK_COUNT 0x200
#define DPCD_LANE0_1_STATUS 0x202
#define DPCD_LANE2_3_STATUS 0x203
#define DPCD_LANE_ALIGN_STATUS_UPDATED 0x204
#define DPCD_SINK_STATUS 0x205
/* link training */
#define DPCD_TRAINING_PATTERN_SET_MASK 0x03
#define DPCD_LINK_TRAINING_DISABLED 0x00
#define DPCD_TRAINING_PATTERN_1 0x01
#define DPCD_TRAINING_PATTERN_2 0x02
#define DPCD_CP_READY_MASK (1 << 6)
/* lane status */
#define DPCD_LANES_CR_DONE 0x11
#define DPCD_LANES_EQ_DONE 0x22
#define DPCD_SYMBOL_LOCKED 0x44
#define DPCD_INTERLANE_ALIGN_DONE 0x01
#define DPCD_SINK_IN_SYNC 0x03
/* DPCD end */
#define SBI_RESPONSE_MASK 0x3
#define SBI_RESPONSE_SHIFT 0x1
#define SBI_STAT_MASK 0x1

View File

@ -32,6 +32,8 @@
*
*/
#include <drm/display/drm_dp.h>
#include "display/intel_dp_aux_regs.h"
#include "display/intel_gmbus_regs.h"
#include "gvt.h"
@ -504,13 +506,13 @@ void intel_gvt_i2c_handle_aux_ch_write(struct intel_vgpu *vgpu,
}
/* Always set the wanted value for vms. */
ret_msg_size = (((op & 0x1) == GVT_AUX_I2C_READ) ? 2 : 1);
ret_msg_size = (((op & 0x1) == DP_AUX_I2C_READ) ? 2 : 1);
vgpu_vreg(vgpu, offset) =
DP_AUX_CH_CTL_DONE |
DP_AUX_CH_CTL_MESSAGE_SIZE(ret_msg_size);
if (msg_length == 3) {
if (!(op & GVT_AUX_I2C_MOT)) {
if (!(op & DP_AUX_I2C_MOT)) {
/* stop */
intel_vgpu_init_i2c_edid(vgpu);
} else {
@ -530,7 +532,7 @@ void intel_gvt_i2c_handle_aux_ch_write(struct intel_vgpu *vgpu,
i2c_edid->edid_available = true;
}
}
} else if ((op & 0x1) == GVT_AUX_I2C_WRITE) {
} else if ((op & 0x1) == DP_AUX_I2C_WRITE) {
/* TODO
* We only support EDID reading from I2C_over_AUX. And
* we do not expect the index mode to be used. Right now
@ -538,7 +540,7 @@ void intel_gvt_i2c_handle_aux_ch_write(struct intel_vgpu *vgpu,
* support the gfx driver to do EDID access.
*/
} else {
if (drm_WARN_ON(&i915->drm, (op & 0x1) != GVT_AUX_I2C_READ))
if (drm_WARN_ON(&i915->drm, (op & 0x1) != DP_AUX_I2C_READ))
return;
if (drm_WARN_ON(&i915->drm, msg_length != 4))
return;
@ -553,7 +555,7 @@ void intel_gvt_i2c_handle_aux_ch_write(struct intel_vgpu *vgpu,
* ACK of I2C_WRITE
* returned byte if it is READ
*/
aux_data_for_write |= GVT_AUX_I2C_REPLY_ACK << 24;
aux_data_for_write |= DP_AUX_I2C_REPLY_ACK << 24;
vgpu_vreg(vgpu, offset + 4) = aux_data_for_write;
}

View File

@ -42,14 +42,6 @@ struct intel_vgpu;
#define EDID_SIZE 128
#define EDID_ADDR 0x50 /* Linux hvm EDID addr */
#define GVT_AUX_NATIVE_WRITE 0x8
#define GVT_AUX_NATIVE_READ 0x9
#define GVT_AUX_I2C_WRITE 0x0
#define GVT_AUX_I2C_READ 0x1
#define GVT_AUX_I2C_STATUS 0x2
#define GVT_AUX_I2C_MOT 0x4
#define GVT_AUX_I2C_REPLY_ACK 0x0
struct intel_vgpu_edid_data {
bool data_valid;
unsigned char edid_block[EDID_SIZE];

View File

@ -36,6 +36,8 @@
*/
#include <drm/display/drm_dp.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "gvt.h"
@ -1129,29 +1131,36 @@ static int dp_aux_ch_ctl_trans_done(struct intel_vgpu *vgpu, u32 value,
static void dp_aux_ch_ctl_link_training(struct intel_vgpu_dpcd_data *dpcd,
u8 t)
{
if ((t & DPCD_TRAINING_PATTERN_SET_MASK) == DPCD_TRAINING_PATTERN_1) {
if ((t & DP_TRAINING_PATTERN_MASK) == DP_TRAINING_PATTERN_1) {
/* training pattern 1 for CR */
/* set LANE0_CR_DONE, LANE1_CR_DONE */
dpcd->data[DPCD_LANE0_1_STATUS] |= DPCD_LANES_CR_DONE;
dpcd->data[DP_LANE0_1_STATUS] |= DP_LANE_CR_DONE |
DP_LANE_CR_DONE << 4;
/* set LANE2_CR_DONE, LANE3_CR_DONE */
dpcd->data[DPCD_LANE2_3_STATUS] |= DPCD_LANES_CR_DONE;
} else if ((t & DPCD_TRAINING_PATTERN_SET_MASK) ==
DPCD_TRAINING_PATTERN_2) {
dpcd->data[DP_LANE2_3_STATUS] |= DP_LANE_CR_DONE |
DP_LANE_CR_DONE << 4;
} else if ((t & DP_TRAINING_PATTERN_MASK) ==
DP_TRAINING_PATTERN_2) {
/* training pattern 2 for EQ */
/* Set CHANNEL_EQ_DONE and SYMBOL_LOCKED for Lane0_1 */
dpcd->data[DPCD_LANE0_1_STATUS] |= DPCD_LANES_EQ_DONE;
dpcd->data[DPCD_LANE0_1_STATUS] |= DPCD_SYMBOL_LOCKED;
dpcd->data[DP_LANE0_1_STATUS] |= DP_LANE_CHANNEL_EQ_DONE |
DP_LANE_CHANNEL_EQ_DONE << 4;
dpcd->data[DP_LANE0_1_STATUS] |= DP_LANE_SYMBOL_LOCKED |
DP_LANE_SYMBOL_LOCKED << 4;
/* Set CHANNEL_EQ_DONE and SYMBOL_LOCKED for Lane2_3 */
dpcd->data[DPCD_LANE2_3_STATUS] |= DPCD_LANES_EQ_DONE;
dpcd->data[DPCD_LANE2_3_STATUS] |= DPCD_SYMBOL_LOCKED;
dpcd->data[DP_LANE2_3_STATUS] |= DP_LANE_CHANNEL_EQ_DONE |
DP_LANE_CHANNEL_EQ_DONE << 4;
dpcd->data[DP_LANE2_3_STATUS] |= DP_LANE_SYMBOL_LOCKED |
DP_LANE_SYMBOL_LOCKED << 4;
/* set INTERLANE_ALIGN_DONE */
dpcd->data[DPCD_LANE_ALIGN_STATUS_UPDATED] |=
DPCD_INTERLANE_ALIGN_DONE;
} else if ((t & DPCD_TRAINING_PATTERN_SET_MASK) ==
DPCD_LINK_TRAINING_DISABLED) {
dpcd->data[DP_LANE_ALIGN_STATUS_UPDATED] |=
DP_INTERLANE_ALIGN_DONE;
} else if ((t & DP_TRAINING_PATTERN_MASK) ==
DP_TRAINING_PATTERN_DISABLE) {
/* finish link training */
/* set sink status as synchronized */
dpcd->data[DPCD_SINK_STATUS] = DPCD_SINK_IN_SYNC;
dpcd->data[DP_SINK_STATUS] = DP_RECEIVE_PORT_0_STATUS |
DP_RECEIVE_PORT_1_STATUS;
}
}
@ -1206,7 +1215,7 @@ static int dp_aux_ch_ctl_mmio_write(struct intel_vgpu *vgpu,
len = msg & 0xff;
op = ctrl >> 4;
if (op == GVT_AUX_NATIVE_WRITE) {
if (op == DP_AUX_NATIVE_WRITE) {
int t;
u8 buf[16];
@ -1252,7 +1261,7 @@ static int dp_aux_ch_ctl_mmio_write(struct intel_vgpu *vgpu,
dpcd->data[p] = buf[t];
/* check for link training */
if (p == DPCD_TRAINING_PATTERN_SET)
if (p == DP_TRAINING_PATTERN_SET)
dp_aux_ch_ctl_link_training(dpcd,
buf[t]);
}
@ -1265,7 +1274,7 @@ static int dp_aux_ch_ctl_mmio_write(struct intel_vgpu *vgpu,
return 0;
}
if (op == GVT_AUX_NATIVE_READ) {
if (op == DP_AUX_NATIVE_READ) {
int idx, i, ret = 0;
if ((addr + len + 1) >= DPCD_SIZE) {

View File

@ -212,7 +212,7 @@ active_fence_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
struct i915_active_fence *active =
container_of(cb, typeof(*active), cb);
return cmpxchg(__active_fence_slot(active), fence, NULL) == fence;
return try_cmpxchg(__active_fence_slot(active), &fence, NULL);
}
static void

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