mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 08:02:27 +02:00
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:
commit
bf99ceb6e0
|
|
@ -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)
|
||||
-------------------------------
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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); \
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
554
drivers/gpu/drm/i915/display/intel_pfit.c
Normal file
554
drivers/gpu/drm/i915/display/intel_pfit.c
Normal 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);
|
||||
}
|
||||
15
drivers/gpu/drm/i915/display/intel_pfit.h
Normal file
15
drivers/gpu/drm/i915/display/intel_pfit.h
Normal 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__ */
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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... */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue
Block a user