Commit d53b8e19 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-2022-05-06' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

drm/i915 feature pull #2 for v5.19:

Features and functionality:
- Add first set of DG2 PCI IDs for "motherboard down" designs (Matt Roper)
- Add initial RPL-P PCI IDs as ADL-P subplatform (Matt Atwood)

Refactoring and cleanups:
- Power well refactoring and cleanup (Imre)
- GVT-g refactor and mdev API cleanup (Christoph, Jason, Zhi)
- DPLL refactoring and cleanup (Ville)
- VBT panel specific data parsing cleanup (Ville)
- Use drm_mode_init() for on-stack modes (Ville)

Fixes:
- Fix PSR state pipe A/B confusion by clearing more state on disable (José)
- Fix FIFO underruns caused by not taking DRAM channel into account (Vinod)
- Fix FBC flicker on display 11+ by enabling a workaround (José)
- Fix VBT seamless DRRS min refresh rate check (Ville)
- Fix panel type assumption on bogus VBT data (Ville)
- Fix panel data parsing for VBT that misses panel data pointers block (Ville)
- Fix spurious AUX timeout/hotplug handling on LTTPR links (Imre)

Merges:
- Backmerge drm-next (Jani)
- GVT changes (Jani)
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/87bkwbkkdo.fsf@intel.com
parents 98bcaafd 949665a6
......@@ -105,6 +105,7 @@ structure to represent a mediated device's driver::
struct mdev_driver {
int (*probe) (struct mdev_device *dev);
void (*remove) (struct mdev_device *dev);
struct attribute_group **supported_type_groups;
struct device_driver driver;
};
......@@ -119,33 +120,15 @@ to register and unregister itself with the core driver:
extern void mdev_unregister_driver(struct mdev_driver *drv);
The mediated bus driver is responsible for adding mediated devices to the VFIO
group when devices are bound to the driver and removing mediated devices from
the VFIO when devices are unbound from the driver.
Physical Device Driver Interface
--------------------------------
The physical device driver interface provides the mdev_parent_ops[3] structure
to define the APIs to manage work in the mediated core driver that is related
to the physical device.
The structures in the mdev_parent_ops structure are as follows:
* dev_attr_groups: attributes of the parent device
* mdev_attr_groups: attributes of the mediated device
* supported_config: attributes to define supported configurations
* device_driver: device driver to bind for mediated device instances
The mdev_parent_ops also still has various functions pointers. Theses exist
for historical reasons only and shall not be used for new drivers.
The mediated bus driver's probe function should create a vfio_device on top of
the mdev_device and connect it to an appropriate implementation of
vfio_device_ops.
When a driver wants to add the GUID creation sysfs to an existing device it has
probe'd to then it should call::
extern int mdev_register_device(struct device *dev,
const struct mdev_parent_ops *ops);
struct mdev_driver *mdev_driver);
This will provide the 'mdev_supported_types/XX/create' files which can then be
used to trigger the creation of a mdev_device. The created mdev_device will be
......
......@@ -558,6 +558,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = {
INTEL_ADLP_IDS(&gen11_early_ops),
INTEL_ADLN_IDS(&gen11_early_ops),
INTEL_RPLS_IDS(&gen11_early_ops),
INTEL_RPLP_IDS(&gen11_early_ops),
};
struct resource intel_graphics_stolen_res __ro_after_init = DEFINE_RES_MEM(0, 0);
......
......@@ -106,40 +106,30 @@ config DRM_I915_USERPTR
If in doubt, say "Y".
config DRM_I915_GVT
bool "Enable Intel GVT-g graphics virtualization host support"
bool
config DRM_I915_GVT_KVMGT
tristate "Enable KVM host support Intel GVT-g graphics virtualization"
depends on DRM_I915
depends on X86
depends on 64BIT
default n
depends on KVM
depends on VFIO_MDEV
select DRM_I915_GVT
select KVM_EXTERNAL_WRITE_TRACKING
help
Choose this option if you want to enable Intel GVT-g graphics
virtualization technology host support with integrated graphics.
With GVT-g, it's possible to have one integrated graphics
device shared by multiple VMs under different hypervisors.
Note that at least one hypervisor like Xen or KVM is required for
this driver to work, and it only supports newer device from
Broadwell+. For further information and setup guide, you can
visit: http://01.org/igvt-g.
device shared by multiple VMs under KVM.
Now it's just a stub to support the modifications of i915 for
GVT device model. It requires at least one MPT modules for Xen/KVM
and other components of GVT device model to work. Use it under
you own risk.
Note that this driver only supports newer device from Broadwell on.
For further information and setup guide, you can visit:
http://01.org/igvt-g.
If in doubt, say "N".
config DRM_I915_GVT_KVMGT
tristate "Enable KVM/VFIO support for Intel GVT-g"
depends on DRM_I915_GVT
depends on KVM
depends on VFIO_MDEV
select KVM_EXTERNAL_WRITE_TRACKING
default n
help
Choose this option if you want to enable KVMGT support for
Intel GVT-g.
config DRM_I915_PXP
bool "Enable Intel PXP support"
depends on DRM_I915
......
......@@ -223,6 +223,7 @@ i915-y += \
display/intel_cursor.o \
display/intel_display.o \
display/intel_display_power.o \
display/intel_display_power_map.o \
display/intel_display_power_well.o \
display/intel_dmc.o \
display/intel_dpio_phy.o \
......@@ -331,13 +332,13 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \
# virtual gpu code
i915-y += i915_vgpu.o
ifeq ($(CONFIG_DRM_I915_GVT),y)
i915-y += intel_gvt.o
i915-$(CONFIG_DRM_I915_GVT) += \
intel_gvt.o \
intel_gvt_mmio_table.o
include $(src)/gvt/Makefile
endif
obj-$(CONFIG_DRM_I915) += i915.o
obj-$(CONFIG_DRM_I915_GVT_KVMGT) += gvt/kvmgt.o
obj-$(CONFIG_DRM_I915_GVT_KVMGT) += kvmgt.o
# header test
......
......@@ -13,6 +13,7 @@
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_power.h"
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_dp_link_training.h"
......@@ -1375,7 +1376,7 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
dig_port->max_lanes = 4;
intel_encoder->type = INTEL_OUTPUT_DP;
intel_encoder->power_domain = intel_port_to_power_domain(port);
intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port);
if (IS_CHERRYVIEW(dev_priv)) {
if (port == PORT_D)
intel_encoder->pipe_mask = BIT(PIPE_C);
......
......@@ -10,6 +10,7 @@
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_power.h"
#include "intel_display_types.h"
#include "intel_dpio_phy.h"
#include "intel_fifo_underrun.h"
......@@ -574,7 +575,7 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv,
intel_encoder->shutdown = intel_hdmi_encoder_shutdown;
intel_encoder->type = INTEL_OUTPUT_HDMI;
intel_encoder->power_domain = intel_port_to_power_domain(port);
intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port);
intel_encoder->port = port;
if (IS_CHERRYVIEW(dev_priv)) {
if (port == PORT_D)
......
......@@ -400,8 +400,8 @@ static void get_dsi_io_power_domains(struct drm_i915_private *dev_priv,
intel_dsi->io_wakeref[port] =
intel_display_power_get(dev_priv,
port == PORT_A ?
POWER_DOMAIN_PORT_DDI_A_IO :
POWER_DOMAIN_PORT_DDI_B_IO);
POWER_DOMAIN_PORT_DDI_IO_A :
POWER_DOMAIN_PORT_DDI_IO_B);
}
}
......@@ -1426,8 +1426,8 @@ static void gen11_dsi_disable_io_power(struct intel_encoder *encoder)
wakeref = fetch_and_zero(&intel_dsi->io_wakeref[port]);
intel_display_power_put(dev_priv,
port == PORT_A ?
POWER_DOMAIN_PORT_DDI_A_IO :
POWER_DOMAIN_PORT_DDI_B_IO,
POWER_DOMAIN_PORT_DDI_IO_A :
POWER_DOMAIN_PORT_DDI_IO_B,
wakeref);
}
......
This diff is collapsed.
......@@ -40,6 +40,7 @@
#include "intel_ddi.h"
#include "intel_ddi_buf_trans.h"
#include "intel_de.h"
#include "intel_display_power.h"
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_dp_link_training.h"
......@@ -4364,7 +4365,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->get_power_domains = intel_ddi_get_power_domains;
encoder->type = INTEL_OUTPUT_DDI;
encoder->power_domain = intel_port_to_power_domain(port);
encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port);
encoder->port = port;
encoder->cloneable = 0;
encoder->pipe_mask = ~0;
......@@ -4492,8 +4493,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
}
drm_WARN_ON(&dev_priv->drm, port > PORT_I);
dig_port->ddi_io_power_domain = POWER_DOMAIN_PORT_DDI_A_IO +
port - PORT_A;
dig_port->ddi_io_power_domain = intel_display_power_ddi_io_domain(dev_priv, port);
if (init_dp) {
if (!intel_ddi_init_dp_connector(dig_port))
......
......@@ -1673,7 +1673,9 @@ void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
encoder->get_buf_trans = skl_get_buf_trans;
} else if (IS_BROADWELL(i915)) {
encoder->get_buf_trans = bdw_get_buf_trans;
} else {
} else if (IS_HASWELL(i915)) {
encoder->get_buf_trans = hsw_get_buf_trans;
} else {
MISSING_CASE(INTEL_INFO(i915)->platform);
}
}
......@@ -635,11 +635,9 @@ void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc,
void i9xx_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config);
int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);
enum intel_display_power_domain intel_port_to_power_domain(enum port port);
enum intel_display_power_domain intel_port_to_power_domain(struct intel_digital_port *dig_port);
enum intel_display_power_domain
intel_aux_power_domain(struct intel_digital_port *dig_port);
enum intel_display_power_domain
intel_legacy_aux_to_power_domain(enum aux_ch aux_ch);
void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state);
void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state);
......
......@@ -8,8 +8,10 @@
#include "intel_runtime_pm.h"
enum aux_ch;
enum dpio_channel;
enum dpio_phy;
enum port;
struct drm_i915_private;
struct i915_power_well;
struct intel_encoder;
......@@ -25,10 +27,10 @@ enum intel_display_power_domain {
POWER_DOMAIN_PIPE_B,
POWER_DOMAIN_PIPE_C,
POWER_DOMAIN_PIPE_D,
POWER_DOMAIN_PIPE_A_PANEL_FITTER,
POWER_DOMAIN_PIPE_B_PANEL_FITTER,
POWER_DOMAIN_PIPE_C_PANEL_FITTER,
POWER_DOMAIN_PIPE_D_PANEL_FITTER,
POWER_DOMAIN_PIPE_PANEL_FITTER_A,
POWER_DOMAIN_PIPE_PANEL_FITTER_B,
POWER_DOMAIN_PIPE_PANEL_FITTER_C,
POWER_DOMAIN_PIPE_PANEL_FITTER_D,
POWER_DOMAIN_TRANSCODER_A,
POWER_DOMAIN_TRANSCODER_B,
POWER_DOMAIN_TRANSCODER_C,
......@@ -40,46 +42,34 @@ enum intel_display_power_domain {
/* VDSC/joining for eDP/DSI transcoder (ICL) or pipe A (TGL) */
POWER_DOMAIN_TRANSCODER_VDSC_PW2,
POWER_DOMAIN_PORT_DDI_A_LANES,
POWER_DOMAIN_PORT_DDI_B_LANES,
POWER_DOMAIN_PORT_DDI_C_LANES,
POWER_DOMAIN_PORT_DDI_D_LANES,
POWER_DOMAIN_PORT_DDI_E_LANES,
POWER_DOMAIN_PORT_DDI_F_LANES,
POWER_DOMAIN_PORT_DDI_G_LANES,
POWER_DOMAIN_PORT_DDI_H_LANES,
POWER_DOMAIN_PORT_DDI_I_LANES,
POWER_DOMAIN_PORT_DDI_LANES_TC1 = POWER_DOMAIN_PORT_DDI_D_LANES, /* tgl+ */
POWER_DOMAIN_PORT_DDI_LANES_A,
POWER_DOMAIN_PORT_DDI_LANES_B,
POWER_DOMAIN_PORT_DDI_LANES_C,
POWER_DOMAIN_PORT_DDI_LANES_D,
POWER_DOMAIN_PORT_DDI_LANES_E,
POWER_DOMAIN_PORT_DDI_LANES_F,
POWER_DOMAIN_PORT_DDI_LANES_TC1,
POWER_DOMAIN_PORT_DDI_LANES_TC2,
POWER_DOMAIN_PORT_DDI_LANES_TC3,
POWER_DOMAIN_PORT_DDI_LANES_TC4,
POWER_DOMAIN_PORT_DDI_LANES_TC5,
POWER_DOMAIN_PORT_DDI_LANES_TC6,
POWER_DOMAIN_PORT_DDI_LANES_D_XELPD = POWER_DOMAIN_PORT_DDI_LANES_TC5, /* XELPD */
POWER_DOMAIN_PORT_DDI_LANES_E_XELPD,
POWER_DOMAIN_PORT_DDI_A_IO,
POWER_DOMAIN_PORT_DDI_B_IO,
POWER_DOMAIN_PORT_DDI_C_IO,
POWER_DOMAIN_PORT_DDI_D_IO,
POWER_DOMAIN_PORT_DDI_E_IO,
POWER_DOMAIN_PORT_DDI_F_IO,
POWER_DOMAIN_PORT_DDI_G_IO,
POWER_DOMAIN_PORT_DDI_H_IO,
POWER_DOMAIN_PORT_DDI_I_IO,
POWER_DOMAIN_PORT_DDI_IO_A,
POWER_DOMAIN_PORT_DDI_IO_B,
POWER_DOMAIN_PORT_DDI_IO_C,
POWER_DOMAIN_PORT_DDI_IO_D,
POWER_DOMAIN_PORT_DDI_IO_E,
POWER_DOMAIN_PORT_DDI_IO_F,
POWER_DOMAIN_PORT_DDI_IO_TC1 = POWER_DOMAIN_PORT_DDI_D_IO, /* tgl+ */
POWER_DOMAIN_PORT_DDI_IO_TC1,
POWER_DOMAIN_PORT_DDI_IO_TC2,
POWER_DOMAIN_PORT_DDI_IO_TC3,
POWER_DOMAIN_PORT_DDI_IO_TC4,
POWER_DOMAIN_PORT_DDI_IO_TC5,
POWER_DOMAIN_PORT_DDI_IO_TC6,
POWER_DOMAIN_PORT_DDI_IO_D_XELPD = POWER_DOMAIN_PORT_DDI_IO_TC5, /* XELPD */
POWER_DOMAIN_PORT_DDI_IO_E_XELPD,
POWER_DOMAIN_PORT_DSI,
POWER_DOMAIN_PORT_CRT,
POWER_DOMAIN_PORT_OTHER,
......@@ -92,30 +82,17 @@ enum intel_display_power_domain {
POWER_DOMAIN_AUX_D,
POWER_DOMAIN_AUX_E,
POWER_DOMAIN_AUX_F,
POWER_DOMAIN_AUX_G,
POWER_DOMAIN_AUX_H,
POWER_DOMAIN_AUX_I,
POWER_DOMAIN_AUX_USBC1 = POWER_DOMAIN_AUX_D, /* tgl+ */
POWER_DOMAIN_AUX_USBC1,
POWER_DOMAIN_AUX_USBC2,
POWER_DOMAIN_AUX_USBC3,
POWER_DOMAIN_AUX_USBC4,
POWER_DOMAIN_AUX_USBC5,
POWER_DOMAIN_AUX_USBC6,
POWER_DOMAIN_AUX_D_XELPD = POWER_DOMAIN_AUX_USBC5, /* XELPD */
POWER_DOMAIN_AUX_E_XELPD,
POWER_DOMAIN_AUX_IO_A,
POWER_DOMAIN_AUX_C_TBT,
POWER_DOMAIN_AUX_D_TBT,
POWER_DOMAIN_AUX_E_TBT,
POWER_DOMAIN_AUX_F_TBT,
POWER_DOMAIN_AUX_G_TBT,
POWER_DOMAIN_AUX_H_TBT,
POWER_DOMAIN_AUX_I_TBT,
POWER_DOMAIN_AUX_TBT1 = POWER_DOMAIN_AUX_D_TBT, /* tgl+ */
POWER_DOMAIN_AUX_TBT1,
POWER_DOMAIN_AUX_TBT2,
POWER_DOMAIN_AUX_TBT3,
POWER_DOMAIN_AUX_TBT4,
......@@ -130,15 +107,20 @@ enum intel_display_power_domain {
POWER_DOMAIN_INIT,
POWER_DOMAIN_NUM,
POWER_DOMAIN_INVALID = POWER_DOMAIN_NUM,
};
#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
#define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \
((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER)
((pipe) + POWER_DOMAIN_PIPE_PANEL_FITTER_A)
#define POWER_DOMAIN_TRANSCODER(tran) \
((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \
(tran) + POWER_DOMAIN_TRANSCODER_A)
struct intel_power_domain_mask {
DECLARE_BITMAP(bits, POWER_DOMAIN_NUM);
};
struct i915_power_domains {
/*
* Power wells needed for initialization at driver init and suspend
......@@ -156,41 +138,21 @@ struct i915_power_domains {
struct delayed_work async_put_work;
intel_wakeref_t async_put_wakeref;
u64 async_put_domains[2];
struct intel_power_domain_mask async_put_domains[2];
struct i915_power_well *power_wells;
};
struct intel_display_power_domain_set {
u64 mask;
struct intel_power_domain_mask mask;
#ifdef CONFIG_DRM_I915_DEBUG_RUNTIME_PM
intel_wakeref_t wakerefs[POWER_DOMAIN_NUM];
#endif
};
#define for_each_power_domain(domain, mask) \
for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
for_each_if(BIT_ULL(domain) & (mask))
#define for_each_power_well(__dev_priv, __power_well) \
for ((__power_well) = (__dev_priv)->power_domains.power_wells; \
(__power_well) - (__dev_priv)->power_domains.power_wells < \
(__dev_priv)->power_domains.power_well_count; \
(__power_well)++)
#define for_each_power_well_reverse(__dev_priv, __power_well) \
for ((__power_well) = (__dev_priv)->power_domains.power_wells + \
(__dev_priv)->power_domains.power_well_count - 1; \
(__power_well) - (__dev_priv)->power_domains.power_wells >= 0; \
(__power_well)--)
#define for_each_power_domain_well(__dev_priv, __power_well, __domain_mask) \
for_each_power_well(__dev_priv, __power_well) \
for_each_if((__power_well)->desc->domains & (__domain_mask))
#define for_each_power_domain_well_reverse(__dev_priv, __power_well, __domain_mask) \
for_each_power_well_reverse(__dev_priv, __power_well) \
for_each_if((__power_well)->desc->domains & (__domain_mask))
#define for_each_power_domain(__domain, __mask) \
for ((__domain) = 0; (__domain) < POWER_DOMAIN_NUM; (__domain)++) \
for_each_if(test_bit((__domain), (__mask)->bits))
int intel_power_domains_init(struct drm_i915_private *dev_priv);
void intel_power_domains_cleanup(struct drm_i915_private *dev_priv);
......@@ -271,17 +233,26 @@ intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915,
void
intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set,
u64 mask);
struct intel_power_domain_mask *mask);
static inline void
intel_display_power_put_all_in_set(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set)
{
intel_display_power_put_mask_in_set(i915, power_domain_set, power_domain_set->mask);
intel_display_power_put_mask_in_set(i915, power_domain_set, &power_domain_set->mask);
}
void intel_display_power_debug(struct drm_i915_private *i915, struct seq_file *m);
enum intel_display_power_domain
intel_display_power_ddi_lanes_domain(struct drm_i915_private *i915, enum port port);
enum intel_display_power_domain
intel_display_power_ddi_io_domain(struct drm_i915_private *i915, enum port port);
enum intel_display_power_domain
intel_display_power_legacy_aux_domain(struct drm_i915_private *i915, enum aux_ch aux_ch);
enum intel_display_power_domain
intel_display_power_tbt_aux_domain(struct drm_i915_private *i915, enum aux_ch aux_ch);
/*
* FIXME: We should probably switch this to a 0-based scheme to be consistent
* with how we now name/number DBUF_CTL instances.
......@@ -305,9 +276,4 @@ void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv,
for ((wf) = intel_display_power_get_if_enabled((i915), (domain)); (wf); \
intel_display_power_put_async((i915), (domain), (wf)), (wf) = 0)
void chv_phy_powergate_lanes(struct intel_encoder *encoder,
bool override, unsigned int mask);
bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
enum dpio_channel ch, bool override);
#endif /* __INTEL_DISPLAY_POWER_H__ */
This diff is collapsed.
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2022 Intel Corporation
*/
#ifndef __INTEL_DISPLAY_POWER_MAP_H__
#define __INTEL_DISPLAY_POWER_MAP_H__
struct i915_power_domains;
int intel_display_power_map_init(struct i915_power_domains *power_domains);
void intel_display_power_map_cleanup(struct i915_power_domains *power_domains);
#endif
......@@ -8,10 +8,23 @@
#include <linux/types.h>
#include "intel_display.h"
#include "intel_display_power.h"
struct drm_i915_private;
struct i915_power_well;
#define for_each_power_well(__dev_priv, __power_well) \
for ((__power_well) = (__dev_priv)->power_domains.power_wells; \
(__power_well) - (__dev_priv)->power_domains.power_wells < \
(__dev_priv)->power_domains.power_well_count; \
(__power_well)++)
#define for_each_power_well_reverse(__dev_priv, __power_well) \
for ((__power_well) = (__dev_priv)->power_domains.power_wells + \
(__dev_priv)->power_domains.power_well_count - 1; \
(__power_well) - (__dev_priv)->power_domains.power_wells >= 0; \
(__power_well)--)
/*
* i915_power_well_id:
*
......@@ -20,7 +33,7 @@ struct i915_power_well;
* wells must be assigned DISP_PW_ID_NONE.
*/
enum i915_power_well_id {
DISP_PW_ID_NONE,
DISP_PW_ID_NONE = 0, /* must be kept zero */
VLV_DISP_PW_DISP2D,
BXT_DISP_PW_DPIO_CMN_A,
......@@ -36,45 +49,13 @@ enum i915_power_well_id {
TGL_DISP_PW_TC_COLD_OFF,
};
struct i915_power_well_regs {
i915_reg_t bios;
i915_reg_t driver;
i915_reg_t kvmr;
i915_reg_t debug;
};
struct i915_power_well_ops {
const struct i915_power_well_regs *regs;
/*
* Synchronize the well's hw state to match the current sw state, for
* example enable/disable it based on the current refcount. Called
* during driver init and resume time, possibly after first calling
* the enable/disable handlers.
*/
void (*sync_hw)(struct drm_i915_private *i915,
struct i915_power_well *power_well);
/*
* Enable the well and resources that depend on it (for example
* interrupts located on the well). Called after the 0->1 refcount
* transition.
*/
void (*enable)(struct drm_i915_private *i915,
struct i915_power_well *power_well);
/*
* Disable the well and resources that depend on it. Called after
* the 1->0 refcount transition.
*/
void (*disable)(struct drm_i915_private *i915,
struct i915_power_well *power_well);
/* Returns the hw enabled state. */
bool (*is_enabled)(struct drm_i915_private *i915,
struct i915_power_well *power_well);
};
struct i915_power_well_desc {
struct i915_power_well_instance {
const char *name;
bool always_on;
u64 domains;
const struct i915_power_domain_list {
const enum intel_display_power_domain *list;
u8 count;
} *domain_list;
/* unique identifier for this power well */
enum i915_power_well_id id;
/*
......@@ -98,33 +79,45 @@ struct i915_power_well_desc {
* constrol/status registers.
*/
u8 idx;
/* Mask of pipes whose IRQ logic is backed by the pw */
u8 irq_pipe_mask;
/*
* Instead of waiting for the status bit to ack enables,
* just wait a specific amount of time and then consider
* the well enabled.
*/
u16 fixed_enable_delay;
/* The pw is backing the VGA functionality */
bool has_vga:1;
bool has_fuses:1;
/*
* The pw is for an ICL+ TypeC PHY port in
* Thunderbolt mode.
*/
bool is_tc_tbt:1;
} hsw;
};
};
struct i915_power_well_desc {
const struct i915_power_well_ops *ops;
const struct i915_power_well_instance_list {
const struct i915_power_well_instance *list;
u8 count;
} *instances;
/* Mask of pipes whose IRQ logic is backed by the pw */
u16 irq_pipe_mask:4;
u16 always_on:1;
/*
* Instead of waiting for the status bit to ack enables,
* just wait a specific amount of time and then consider
* the well enabled.
*/
u16 fixed_enable_delay:1;
/* The pw is backing the VGA functionality */
u16 has_vga:1;
u16 has_fuses:1;
/*
* The pw is for an ICL+ TypeC PHY port in
* Thunderbolt mode.
*/
u16 is_tc_tbt:1;
};
struct i915_power_well {
const struct i915_power_well_desc *desc;
struct intel_power_domain_mask domains;
/* power well enable/disable usage count */
int count;
/* cached hw enabled state */
bool hw_enabled;
/* index into desc->instances->list */
u8 instance_idx;
};
struct i915_power_well *lookup_power_well(struct drm_i915_private *i915,
......@@ -147,7 +140,34 @@ bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
enum i915_power_well_id power_well_id);
bool intel_power_well_is_always_on(struct i915_power_well *power_well);
const char *intel_power_well_name(struct i915_power_well *power_well);
u64 intel_power_well_domains(struct i915_power_well *power_well);
struct intel_power_domain_mask *intel_power_well_domains(struct i915_power_well *power_well);
int intel_power_well_refcount(struct i915_power_well *power_well);
void chv_phy_powergate_lanes(struct intel_encoder *encoder,
bool override, unsigned int mask);
bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
enum dpio_channel ch, bool override);
void gen9_enable_dc5(struct drm_i915_private *dev_priv);
void skl_enable_dc6(struct drm_i915_private *dev_priv);
void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv);
void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state);
void gen9_disable_dc_states(struct drm_i915_private *dev_priv);
void bxt_enable_dc9(struct drm_i915_private *dev_priv);
void bxt_disable_dc9(struct drm_i915_private *dev_priv);
extern const struct i915_power_well_ops i9xx_always_on_power_well_ops;
extern const struct i915_power_well_ops chv_pipe_power_well_ops;
extern const struct i915_power_well_ops chv_dpio_cmn_power_well_ops;
extern const struct i915_power_well_ops i830_pipes_power_well_ops;
extern const struct i915_power_well_ops hsw_power_well_ops;
extern const struct i915_power_well_ops gen9_dc_off_power_well_ops;
extern const struct i915_power_well_ops bxt_dpio_cmn_power_well_ops;
extern const struct i915_power_well_ops vlv_display_power_well_ops;
extern const struct i915_power_well_ops vlv_dpio_cmn_power_well_ops;
extern const struct i915_power_well_ops vlv_dpio_power_well_ops;
extern const struct i915_power_well_ops icl_aux_power_well_ops;
extern const struct i915_power_well_ops icl_ddi_power_well_ops;
extern const struct i915_power_well_ops tgl_tc_cold_off_ops;
#endif
......@@ -82,19 +82,8 @@ static bool intel_dp_read_lttpr_common_caps(struct intel_dp *intel_dp,
const u8 dpcd[DP_RECEIVER_CAP_SIZE])
{
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
int ret;
if (intel_dp_is_edp(intel_dp))
return false;
/*
* Detecting LTTPRs must be avoided on platforms with an AUX timeout
* period < 3.2ms. (see DP Standard v2.0, 2.11.2, 3.6.6.1).
*/
if (DISPLAY_VER(i915) < 10 || IS_GEMINILAKE(i915))
return false;
ret = drm_dp_read_lttpr_common_caps(&intel_dp->aux, dpcd,
intel_dp->lttpr_common_caps);
if (ret < 0)
......@@ -197,13 +186,25 @@ static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEI
*/
int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp)
{
u8 dpcd[DP_RECEIVER_CAP_SIZE];
int lttpr_count;
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int lttpr_count = 0;
if (drm_dp_read_dpcd_caps(&intel_dp->aux, dpcd))
return -EIO;
/*
* Detecting LTTPRs must be avoided on platforms with an AUX timeout
* period < 3.2ms. (see DP Standard v2.0, 2.11.2, 3.6.6.1).
*/
if (!intel_dp_is_edp(intel_dp) &&
(DISPLAY_VER(i915) >= 10 && !IS_GEMINILAKE(i915))) {
u8 dpcd[DP_RECEIVER_CAP_SIZE];
if (drm_dp_dpcd_probe(&intel_dp->aux, DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV))
return -EIO;
lttpr_count = intel_dp_init_lttpr(intel_dp, dpcd);
if (drm_dp_read_dpcd_caps(&intel_dp->aux, dpcd))
return -EIO;
lttpr_count = intel_dp_init_lttpr(intel_dp, dpcd);
}
/*
* The DPTX shall read the DPRX caps after LTTPR detection, so re-read
......
......@@ -24,6 +24,7 @@
#include "intel_ddi.h"
#include "intel_ddi_buf_trans.h"
#include "intel_de.h"
#include "intel_display_power_well.h"
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_dpio_phy.h"
......
This diff is collapsed.
......@@ -10,12 +10,16 @@
struct dpll;
struct drm_i915_private;
struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
enum pipe;
void intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv);
int intel_dpll_crtc_compute_clock(struct intel_crtc_state *crtc_state);
int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state,
struct intel_crtc *crtc);
int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state,
struct intel_crtc *crtc);
int vlv_calc_dpll_params(int refclk, struct dpll *clock);
int pnv_calc_dpll_params(int refclk, struct dpll *clock);
int i9xx_calc_dpll_params(int refclk, struct dpll *clock);
......
......@@ -37,7 +37,6 @@
__a > __b ? (__a - __b) : (__b - __a); })
enum tc_port;
struct drm_device;
struct drm_i915_private;
struct intel_atomic_state;
struct intel_crtc;
......@@ -337,9 +336,9 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
bool state);
#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
bool intel_reserve_shared_dplls(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_encoder *encoder);
int intel_reserve_shared_dplls(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_encoder *encoder);
void intel_release_shared_dplls(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void icl_set_active_port_dpll(struct intel_crtc_state *crtc_state,
......@@ -356,7 +355,7 @@ bool intel_dpll_get_hw_state(struct drm_i915_private *i915,
void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state);
void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state);
void intel_shared_dpll_swap_state(struct intel_atomic_state *state);
void intel_shared_dpll_init(struct drm_device *dev);
void intel_shared_dpll_init(struct drm_i915_private *dev_priv);
void intel_dpll_update_ref_clks(struct drm_i915_private *dev_priv);
void intel_dpll_readout_hw_state(struct drm_i915_private *dev_priv);
void intel_dpll_sanitize_state(struct drm_i915_private *dev_priv);
......
......@@ -811,6 +811,14 @@ static void intel_fbc_program_cfb(struct intel_fbc *fbc)
fbc->funcs->program_cfb(fbc);
}
static void intel_fbc_program_workarounds(struct intel_fbc *fbc)
{
/* Wa_22014263786:icl,jsl,tgl,dg1,rkl,adls,dg2,adlp */
if (DISPLAY_VER(fbc->i915) >= 11)
intel_de_rmw(fbc->i915, ILK_DPFC_CHICKEN(fbc->id), 0,
DPFC_CHICKEN_FORCE_SLB_INVALIDATION);
}
static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc)
{
struct drm_i915_private *i915 = fbc->i915;
......@@ -1086,7 +1094,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
*/
if (DISPLAY_VER(i915) >= 12 && crtc_state->has_psr2) {
plane_state->no_fbc_reason = "PSR2 enabled";
return false;
return 0;
}
if (!pixel_format_is_valid(plane_state)) {
......@@ -1112,7 +1120,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
if (plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE &&
fb->format->has_alpha) {
plane_state->no_fbc_reason = "per-pixel alpha not supported";
return false;
return 0;
}
if (!intel_fbc_hw_tracking_covers_screen(plane_state)) {
......@@ -1128,7 +1136,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
if (DISPLAY_VER(i915) >= 9 &&
plane_state->view.color_plane[0].y & 3) {
plane_state->no_fbc_reason = "plane start Y offset misaligned";
return false;
return 0;
}
/* Wa_22010751166: icl, ehl, tgl, dg1, rkl */
......@@ -1136,7 +1144,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
(plane_state->view.color_plane[0].y +
(drm_rect_height(&plane_state->uapi.src) >> 16)) & 3) {
plane_state->no_fbc_reason = "plane end Y offset misaligned";
return false;
return 0;
}
/* WaFbcExceedCdClockThreshold:hsw,bdw */
......@@ -1462,6 +1470,7 @@ static void __intel_fbc_enable(struct intel_atomic_state *state,
intel_fbc_update_state(state, crtc, plane);
intel_fbc_program_workarounds(fbc);
intel_fbc_program_cfb(fbc);
}
......
......@@ -75,13 +75,17 @@ const struct drm_display_mode *
intel_panel_downclock_mode(struct intel_connector *connector,
const struct drm_display_mode *adjusted_mode)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
const struct drm_display_mode *fixed_mode, *best_mode = NULL;
int vrefresh = drm_mode_vrefresh(adjusted_mode);
int min_vrefresh = i915->vbt.seamless_drrs_min_refresh_rate;
int max_vrefresh = drm_mode_vrefresh(adjusted_mode);
/* pick the fixed_mode with the lowest refresh rate */
list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) {
if (drm_mode_vrefresh(fixed_mode) < vrefresh) {
vrefresh = drm_mode_vrefresh(fixed_mode);
int vrefresh = drm_mode_vrefresh(fixed_mode);
if (vrefresh >= min_vrefresh && vrefresh < max_vrefresh) {
max_vrefresh = vrefresh;
best_mode = fixed_mode;
}
}
......
......@@ -6,6 +6,7 @@
#include "g4x_dp.h"
#include "i915_drv.h"
#include "intel_de.h"
#include "intel_display_power_well.h"
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_dpll.h"
......
......@@ -1353,6 +1353,9 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, 0);
intel_dp->psr.enabled = false;
intel_dp->psr.psr2_enabled = false;
intel_dp->psr.psr2_sel_fetch_enabled = false;
intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
}
/**
......
......@@ -6,6 +6,7 @@
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_display.h"
#include "intel_display_power_map.h"
#include "intel_display_types.h"
#include "intel_dp_mst.h"
#include "intel_tc.h"
......@@ -61,10 +62,12 @@ bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port)
static enum intel_display_power_domain
tc_cold_get_power_domain(struct intel_digital_port *dig_port, enum tc_port_mode mode)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
if (mode == TC_PORT_TBT_ALT || !intel_tc_cold_requires_aux_pw(dig_port))
return POWER_DOMAIN_TC_COLD_OFF;
return intel_legacy_aux_to_power_domain(dig_port->aux_ch);
return intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch);
}
static intel_wakeref_t
......
......@@ -735,7 +735,7 @@ struct lvds_lfp_data_ptr {
} __packed;
struct bdb_lvds_lfp_data_ptrs {
u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
u8 lvds_entries;
struct lvds_lfp_data_ptr ptr[16];
struct lvds_lfp_data_ptr_table panel_name; /* 156-163? */
} __packed;
......@@ -769,6 +769,11 @@ struct lvds_pnp_id {
u8 mfg_year;
} __packed;
/*
* For reference only. fp_timing has variable size so
* the data must be accessed using the data table pointers.
* Do not use this directly!
*/
struct lvds_lfp_data_entry {
struct lvds_fp_timing fp_timing;
struct lvds_dvo_timing dvo_timing;
......@@ -783,6 +788,23 @@ struct lvds_lfp_panel_name {
u8 name[13];
} __packed;
struct lvds_lfp_black_border {
u8 top; /* 227 */
u8 bottom; /* 227 */
u8 left; /* 238 */
u8 right; /* 238 */
} __packed;
struct bdb_lvds_lfp_data_tail {
struct lvds_lfp_panel_name panel_name[16]; /* 156-163? */
u16 scaling_enable; /* 187 */
u8 seamless_drrs_min_refresh_rate[16]; /* 188 */
u8 pixel_overlap_count[16]; /* 208 */
struct lvds_lfp_black_border black_border[16]; /* 227 */
u16 dual_lfp_port_sync_enable; /* 231 */
u16 gpu_dithering_for_banding_artifacts; /* 245 */
} __packed;
/*
* Block 43 - LFP Backlight Control Data Block
*/
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -72,7 +72,6 @@ struct intel_gvt_mmio_info {
const struct intel_engine_cs *
intel_gvt_render_mmio_to_engine(struct intel_gvt *gvt, unsigned int reg);
unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt);
bool intel_gvt_match_device(struct intel_gvt *gvt, unsigned long device);
int intel_gvt_setup_mmio_info(struct intel_gvt *gvt);
void intel_gvt_clean_mmio_info(struct intel_gvt *gvt);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment