Commit fad3dad8 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-2024-04-17-1' of...

Merge tag 'drm-intel-next-2024-04-17-1' of https://anongit.freedesktop.org/git/drm/drm-intel into drm-next

Core Changes (DRM):

- Fix documentation of DP tunnel functions (Imre)
- DP MST read sideband messaging cap (Jani)
- Preparation patches for Adaptive Sync SDP Support for DP (Mitul)

Driver Changes:

i915 core (non-display):
- Documentation improvements (Nirmoy)
- Add includes for BUG_ON/BUILD_BUG_ON in i915_memcpy.c (Joonas)
- Do not print 'pxp init failed with 0' when it succeed (Jose)
- Clean-up, including removal of dead code for unsupported platforms (Lucas)
- Adding new DG2 PCI ID (Ravi)

{i915,xe} display:
- Spelling fix (Colin Ian)
- Document CDCLK components (Gustavo)
- Lunar Lake display enabling, including cdclk and other refactors (Gustavo, Bala)
- BIOS/VBT/opregion related refactor (Jani, Ville, RK)
- Save a few bytes of memory using {kstrdup,kfree}_const variant (Christophe)
- Digital port related refactor/clean-up (Ville)
- Fix 2s boot time regression on DP panel replay init (Animesh)
- Remove redundant drm_rect_visible() overlay use (Arthur)
- DSC HW state readout fixes (Imre)
- Remove duplication on audio enable/disable on SDVO and g4x+ DP (Ville)
- Disable AuxCCS framebuffers if built for Xe (Juha-Pekka)
- Fix DSI init order (Ville)
- DRRS related refactor and fixes (Bhanuprakash)
- Fix DSB vblank waits with VRR (Ville)
- General improvements on register name and use of REG_BIT (Ville)
- Some display power well related improvements (Ville)
- FBC changes for better w/a handling (Ville)
- Make crtc disable more atomic (Ville)
- Fix hwmon locking inversion in sysfs getter (Janusz)
- Increase DP idle pattern wait timeout to 2ms (Shekhar)
- PSR related fixes and improvents (Jouni)
- Start using container_of_const() for some extra const safety (Ville)
- Use drm_printer more on display code (Ville)
- Fix Jasper Lake boot freeze (Jonathon)
- Update Pipe src size check in skl_update_scaler (Ankit)
- Enable MST mode for 128b/132b single-stream sideband (Jani)
- Pass encoder around more for port/phy checks (Jani)
- Some initial work to make display code more independent from i915 (Jani)
- Pre-populate the cursor physical dma address (Ville)
- Do not bump min backlight brightness to max on enable (Gareth)
- Fix MTL supported DP rates - removal of UHBR13.5 (Arun)
- Fix the computation for compressed_bpp for DISPLAY < 1 (Ankit)
- Bigjoiner modeset sequence redesign and MST support (Ville)
- Enable Adaptive Sync SDP Support for DP (Mitul)
- Implemnt vblank sycnhronized mbus joining changes (Ville, Stanislav)
- HDCP related fixes (Suraj)
- Fix i915_display_info debugfs when connectors are not active (Ville)
- Clean up on Xe compat layer (Jani)
- Add jitter WAs for MST/FEC/DSC links (Imre)
- DMC wakelock implementation (Luca)
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCAAdFiEEbSBwaO7dZQkcLOKj+mJfZA7rE8oFAmYfzQEACgkQ+mJfZA7r
# E8qYvAf/T8KrEewHOWz7NOaKcFRCNYaF4QTdVOfgHUYBX5NPDF/xzwFdHCL8QWQu
# bwKwE2b94VEyruG3DYwTMd8GNcDxrsOrmU0IZe3PVkm+BvHLTmrOqL6BlCd85zXF
# 02IuE+LCaWREmmpLMcsDMxsaaq8yp+cw9/F0jJDrH6LiyfxFriefxyZYpGYjRCuv
# 8GP1fHXLFV2yys4rveR/+y9xIhgy82mVcg3/Kfk0+er7gALkY6Vc0N38wedET9MZ
# ZPfVidBeaTkIKcCDFKnFzGjG+9rNQ7NFrXyS7Hl97VolGt2l03qGGPNW1PouDiUx
# 7Y8CJOc+1k9wyBMKl0a/NQBRAqSZBQ==
# =JvZN
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 17 Apr 2024 23:22:09 AEST
# gpg:                using RSA key 6D207068EEDD65091C2CE2A3FA625F640EEB13CA
# gpg: Good signature from "Rodrigo Vivi <rodrigo.vivi@intel.com>" [unknown]
# gpg:                 aka "Rodrigo Vivi <rodrigo.vivi@gmail.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6D20 7068 EEDD 6509 1C2C  E2A3 FA62 5F64 0EEB 13CA
From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Zh_Q72gYKMMbge9A@intel.com
parents 34633158 700c3401
......@@ -204,6 +204,15 @@ DMC Firmware Support
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dmc.c
:internal:
DMC wakelock support
--------------------
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dmc_wl.c
:doc: DMC wakelock support
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dmc_wl.c
:internal:
Video BIOS Table (VBT)
----------------------
......
......@@ -93,12 +93,11 @@ struct drm_i915_gem_timeline_fence {
* Multiple VA mappings can be created to the same section of the object
* (aliasing).
*
* The @start, @offset and @length must be 4K page aligned. However the DG2
* and XEHPSDV has 64K page size for device local memory and has compact page
* table. On those platforms, for binding device local-memory objects, the
* @start, @offset and @length must be 64K aligned. Also, UMDs should not mix
* the local memory 64K page and the system memory 4K page bindings in the same
* 2M range.
* The @start, @offset and @length must be 4K page aligned. However the DG2 has
* 64K page size for device local memory and has compact page table. On that
* platform, for binding device local-memory objects, the @start, @offset and
* @length must be 64K aligned. Also, UMDs should not mix the local memory 64K
* page and the system memory 4K page bindings in the same 2M range.
*
* Error code -EINVAL will be returned if @start, @offset and @length are not
* properly aligned. In version 1 (See I915_PARAM_VM_BIND_VERSION), error code
......
......@@ -2948,6 +2948,43 @@ void drm_dp_vsc_sdp_log(struct drm_printer *p, const struct drm_dp_vsc_sdp *vsc)
}
EXPORT_SYMBOL(drm_dp_vsc_sdp_log);
void drm_dp_as_sdp_log(struct drm_printer *p, const struct drm_dp_as_sdp *as_sdp)
{
drm_printf(p, "DP SDP: AS_SDP, revision %u, length %u\n",
as_sdp->revision, as_sdp->length);
drm_printf(p, " vtotal: %d\n", as_sdp->vtotal);
drm_printf(p, " target_rr: %d\n", as_sdp->target_rr);
drm_printf(p, " duration_incr_ms: %d\n", as_sdp->duration_incr_ms);
drm_printf(p, " duration_decr_ms: %d\n", as_sdp->duration_decr_ms);
drm_printf(p, " operation_mode: %d\n", as_sdp->mode);
}
EXPORT_SYMBOL(drm_dp_as_sdp_log);
/**
* drm_dp_as_sdp_supported() - check if adaptive sync sdp is supported
* @aux: DisplayPort AUX channel
* @dpcd: DisplayPort configuration data
*
* Returns true if adaptive sync sdp is supported, else returns false
*/
bool drm_dp_as_sdp_supported(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
{
u8 rx_feature;
if (dpcd[DP_DPCD_REV] < DP_DPCD_REV_13)
return false;
if (drm_dp_dpcd_readb(aux, DP_DPRX_FEATURE_ENUMERATION_LIST_CONT_1,
&rx_feature) != 1) {
drm_dbg_dp(aux->drm_dev,
"Failed to read DP_DPRX_FEATURE_ENUMERATION_LIST_CONT_1\n");
return false;
}
return (rx_feature & DP_ADAPTIVE_SYNC_SDP_SUPPORTED);
}
EXPORT_SYMBOL(drm_dp_as_sdp_supported);
/**
* drm_dp_vsc_sdp_supported() - check if vsc sdp is supported
* @aux: DisplayPort AUX channel
......
......@@ -3608,24 +3608,30 @@ fixed20_12 drm_dp_get_vc_payload_bw(const struct drm_dp_mst_topology_mgr *mgr,
EXPORT_SYMBOL(drm_dp_get_vc_payload_bw);
/**
* drm_dp_read_mst_cap() - check whether or not a sink supports MST
* drm_dp_read_mst_cap() - Read the sink's MST mode capability
* @aux: The DP AUX channel to use
* @dpcd: A cached copy of the DPCD capabilities for this sink
*
* Returns: %True if the sink supports MST, %false otherwise
* Returns: enum drm_dp_mst_mode to indicate MST mode capability
*/
bool drm_dp_read_mst_cap(struct drm_dp_aux *aux,
const u8 dpcd[DP_RECEIVER_CAP_SIZE])
enum drm_dp_mst_mode drm_dp_read_mst_cap(struct drm_dp_aux *aux,
const u8 dpcd[DP_RECEIVER_CAP_SIZE])
{
u8 mstm_cap;
if (dpcd[DP_DPCD_REV] < DP_DPCD_REV_12)
return false;
return DRM_DP_SST;
if (drm_dp_dpcd_readb(aux, DP_MSTM_CAP, &mstm_cap) != 1)
return false;
return DRM_DP_SST;
if (mstm_cap & DP_MST_CAP)
return DRM_DP_MST;
if (mstm_cap & DP_SINGLE_STREAM_SIDEBAND_MSG)
return DRM_DP_SST_SIDEBAND_MSG;
return mstm_cap & DP_MST_CAP;
return DRM_DP_SST;
}
EXPORT_SYMBOL(drm_dp_read_mst_cap);
......
......@@ -436,8 +436,8 @@ EXPORT_SYMBOL(drm_dp_tunnel_get);
/**
* drm_dp_tunnel_put - Put a reference for a DP tunnel
* @tunnel - Tunnel object
* @tracker - Debug tracker for the reference
* @tunnel: Tunnel object
* @tracker: Debug tracker for the reference
*
* Put a reference for @tunnel along with its debug *@tracker, which
* was obtained with drm_dp_tunnel_get().
......@@ -1170,7 +1170,7 @@ int drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw)
EXPORT_SYMBOL(drm_dp_tunnel_alloc_bw);
/**
* drm_dp_tunnel_atomic_get_allocated_bw - Get the BW allocated for a DP tunnel
* drm_dp_tunnel_get_allocated_bw - Get the BW allocated for a DP tunnel
* @tunnel: Tunnel object
*
* Get the current BW allocated for @tunnel. After the tunnel is created /
......@@ -1892,6 +1892,7 @@ static void destroy_mgr(struct drm_dp_tunnel_mgr *mgr)
/**
* drm_dp_tunnel_mgr_create - Create a DP tunnel manager
* @dev: DRM device object
* @max_group_count: Maximum number of tunnel groups
*
* Creates a DP tunnel manager for @dev.
*
......
......@@ -32,11 +32,6 @@ endif
# Enable -Werror in CI and development
subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror
# Fine grained warnings disable
CFLAGS_i915_pci.o = -Wno-override-init
CFLAGS_display/intel_display_device.o = -Wno-override-init
CFLAGS_display/intel_fbdev.o = -Wno-override-init
# Support compiling the display code separately for both i915 and xe
# drivers. Define I915 when building i915.
subdir-ccflags-y += -DI915
......@@ -270,6 +265,7 @@ i915-y += \
display/intel_display_rps.o \
display/intel_display_wa.o \
display/intel_dmc.o \
display/intel_dmc_wl.o \
display/intel_dpio_phy.o \
display/intel_dpll.o \
display/intel_dpll_mgr.o \
......
......@@ -1616,8 +1616,7 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,
struct drm_connector_state *conn_state)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
base);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
struct intel_connector *intel_connector = intel_dsi->attached_connector;
struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode;
......
......@@ -62,7 +62,7 @@ int intel_digital_connector_atomic_get_property(struct drm_connector *connector,
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_digital_connector_state *intel_conn_state =
const struct intel_digital_connector_state *intel_conn_state =
to_intel_digital_connector_state(state);
if (property == dev_priv->display.properties.force_audio)
......
......@@ -761,8 +761,8 @@ static void __intel_backlight_enable(const struct intel_crtc_state *crtc_state,
WARN_ON(panel->backlight.max == 0);
if (panel->backlight.level <= panel->backlight.min) {
panel->backlight.level = panel->backlight.max;
if (panel->backlight.level < panel->backlight.min) {
panel->backlight.level = panel->backlight.min;
if (panel->backlight.device)
panel->backlight.device->props.brightness =
scale_hw_to_user(connector,
......@@ -949,7 +949,7 @@ int intel_backlight_device_register(struct intel_connector *connector)
else
props.power = FB_BLANK_POWERDOWN;
name = kstrdup("intel_backlight", GFP_KERNEL);
name = kstrdup_const("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(name);
kfree_const(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(name);
kfree_const(name);
return ret;
}
......
......@@ -25,6 +25,8 @@
*
*/
#include <linux/firmware.h>
#include <drm/display/drm_dp_helper.h>
#include <drm/display/drm_dsc_helper.h>
#include <drm/drm_edid.h>
......@@ -2730,6 +2732,57 @@ static void parse_ddi_ports(struct drm_i915_private *i915)
print_ddi_port(devdata);
}
static int child_device_expected_size(u16 version)
{
BUILD_BUG_ON(sizeof(struct child_device_config) < 40);
if (version > 256)
return -ENOENT;
else if (version >= 256)
return 40;
else if (version >= 216)
return 39;
else if (version >= 196)
return 38;
else if (version >= 195)
return 37;
else if (version >= 111)
return LEGACY_CHILD_DEVICE_CONFIG_SIZE;
else if (version >= 106)
return 27;
else
return 22;
}
static bool child_device_size_valid(struct drm_i915_private *i915, int size)
{
int expected_size;
expected_size = child_device_expected_size(i915->display.vbt.version);
if (expected_size < 0) {
expected_size = sizeof(struct child_device_config);
drm_dbg(&i915->drm,
"Expected child device config size for VBT version %u not known; assuming %d\n",
i915->display.vbt.version, expected_size);
}
/* Flag an error for unexpected size, but continue anyway. */
if (size != expected_size)
drm_err(&i915->drm,
"Unexpected child device config size %d (expected %d for VBT version %u)\n",
size, expected_size, i915->display.vbt.version);
/* The legacy sized child device config is the minimum we need. */
if (size < LEGACY_CHILD_DEVICE_CONFIG_SIZE) {
drm_dbg_kms(&i915->drm,
"Child device config size %d is too small.\n",
size);
return false;
}
return true;
}
static void
parse_general_definitions(struct drm_i915_private *i915)
{
......@@ -2737,7 +2790,6 @@ parse_general_definitions(struct drm_i915_private *i915)
struct intel_bios_encoder_data *devdata;
const struct child_device_config *child;
int i, child_device_num;
u8 expected_size;
u16 block_size;
int bus_pin;
......@@ -2761,39 +2813,8 @@ parse_general_definitions(struct drm_i915_private *i915)
if (intel_gmbus_is_valid_pin(i915, bus_pin))
i915->display.vbt.crt_ddc_pin = bus_pin;
if (i915->display.vbt.version < 106) {
expected_size = 22;
} else if (i915->display.vbt.version < 111) {
expected_size = 27;
} else if (i915->display.vbt.version < 195) {
expected_size = LEGACY_CHILD_DEVICE_CONFIG_SIZE;
} else if (i915->display.vbt.version == 195) {
expected_size = 37;
} else if (i915->display.vbt.version <= 215) {
expected_size = 38;
} else if (i915->display.vbt.version <= 250) {
expected_size = 39;
} else {
expected_size = sizeof(*child);
BUILD_BUG_ON(sizeof(*child) < 39);
drm_dbg(&i915->drm,
"Expected child device config size for VBT version %u not known; assuming %u\n",
i915->display.vbt.version, expected_size);
}
/* Flag an error for unexpected size, but continue anyway. */
if (defs->child_dev_size != expected_size)
drm_err(&i915->drm,
"Unexpected child device config size %u (expected %u for VBT version %u)\n",
defs->child_dev_size, expected_size, i915->display.vbt.version);
/* The legacy sized child device config is the minimum we need. */
if (defs->child_dev_size < LEGACY_CHILD_DEVICE_CONFIG_SIZE) {
drm_dbg_kms(&i915->drm,
"Child device config size %u is too small.\n",
defs->child_dev_size);
if (!child_device_size_valid(i915, defs->child_dev_size))
return;
}
/* get the number of child device */
child_device_num = (block_size - sizeof(*defs)) / defs->child_dev_size;
......@@ -2869,9 +2890,8 @@ init_vbt_panel_defaults(struct intel_panel *panel)
static void
init_vbt_missing_defaults(struct drm_i915_private *i915)
{
unsigned int ports = DISPLAY_RUNTIME_INFO(i915)->port_mask;
enum port port;
int ports = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) |
BIT(PORT_D) | BIT(PORT_E) | BIT(PORT_F);
if (!HAS_DDI(i915) && !IS_CHERRYVIEW(i915))
return;
......@@ -2981,6 +3001,43 @@ bool intel_bios_is_valid_vbt(struct drm_i915_private *i915,
return vbt;
}
static struct vbt_header *firmware_get_vbt(struct drm_i915_private *i915,
size_t *size)
{
struct vbt_header *vbt = NULL;
const struct firmware *fw = NULL;
const char *name = i915->display.params.vbt_firmware;
int ret;
if (!name || !*name)
return NULL;
ret = request_firmware(&fw, name, i915->drm.dev);
if (ret) {
drm_err(&i915->drm,
"Requesting VBT firmware \"%s\" failed (%d)\n",
name, ret);
return NULL;
}
if (intel_bios_is_valid_vbt(i915, fw->data, fw->size)) {
vbt = kmemdup(fw->data, fw->size, GFP_KERNEL);
if (vbt) {
drm_dbg_kms(&i915->drm,
"Found valid VBT firmware \"%s\"\n", name);
if (size)
*size = fw->size;
}
} else {
drm_dbg_kms(&i915->drm, "Invalid VBT firmware \"%s\"\n",
name);
}
release_firmware(fw);
return vbt;
}
static u32 intel_spi_read(struct intel_uncore *uncore, u32 offset)
{
intel_uncore_write(uncore, PRIMARY_SPI_ADDRESS, offset);
......@@ -2988,7 +3045,8 @@ static u32 intel_spi_read(struct intel_uncore *uncore, u32 offset)
return intel_uncore_read(uncore, PRIMARY_SPI_TRIGGER);
}
static struct vbt_header *spi_oprom_get_vbt(struct drm_i915_private *i915)
static struct vbt_header *spi_oprom_get_vbt(struct drm_i915_private *i915,
size_t *size)
{
u32 count, data, found, store = 0;
u32 static_region, oprom_offset;
......@@ -3031,6 +3089,9 @@ static struct vbt_header *spi_oprom_get_vbt(struct drm_i915_private *i915)
drm_dbg_kms(&i915->drm, "Found valid VBT in SPI flash\n");
if (size)
*size = vbt_size;
return (struct vbt_header *)vbt;
err_free_vbt:
......@@ -3039,7 +3100,8 @@ static struct vbt_header *spi_oprom_get_vbt(struct drm_i915_private *i915)
return NULL;
}
static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915)
static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915,
size_t *sizep)
{
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
void __iomem *p = NULL, *oprom;
......@@ -3088,6 +3150,9 @@ static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915)
pci_unmap_rom(pdev, oprom);
if (sizep)
*sizep = vbt_size;
drm_dbg_kms(&i915->drm, "Found valid VBT in PCI ROM\n");
return vbt;
......@@ -3100,6 +3165,32 @@ static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915)
return NULL;
}
static const struct vbt_header *intel_bios_get_vbt(struct drm_i915_private *i915,
size_t *sizep)
{
const struct vbt_header *vbt = NULL;
intel_wakeref_t wakeref;
vbt = firmware_get_vbt(i915, sizep);
if (!vbt)
vbt = intel_opregion_get_vbt(i915, sizep);
/*
* If the OpRegion does not have VBT, look in SPI flash
* through MMIO or PCI mapping
*/
if (!vbt && IS_DGFX(i915))
with_intel_runtime_pm(&i915->runtime_pm, wakeref)
vbt = spi_oprom_get_vbt(i915, sizep);
if (!vbt)
with_intel_runtime_pm(&i915->runtime_pm, wakeref)
vbt = oprom_get_vbt(i915, sizep);
return vbt;
}
/**
* intel_bios_init - find VBT and initialize settings from the BIOS
* @i915: i915 device instance
......@@ -3111,7 +3202,6 @@ static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915)
void intel_bios_init(struct drm_i915_private *i915)
{
const struct vbt_header *vbt;
struct vbt_header *oprom_vbt = NULL;
const struct bdb_header *bdb;
INIT_LIST_HEAD(&i915->display.vbt.display_devices);
......@@ -3125,21 +3215,7 @@ void intel_bios_init(struct drm_i915_private *i915)
init_vbt_defaults(i915);
vbt = intel_opregion_get_vbt(i915, NULL);
/*
* If the OpRegion does not have VBT, look in SPI flash through MMIO or
* PCI mapping
*/
if (!vbt && IS_DGFX(i915)) {
oprom_vbt = spi_oprom_get_vbt(i915);
vbt = oprom_vbt;
}
if (!vbt) {
oprom_vbt = oprom_get_vbt(i915);
vbt = oprom_vbt;
}
vbt = intel_bios_get_vbt(i915, NULL);
if (!vbt)
goto out;
......@@ -3172,7 +3248,7 @@ void intel_bios_init(struct drm_i915_private *i915)
parse_sdvo_device_mapping(i915);
parse_ddi_ports(i915);
kfree(oprom_vbt);
kfree(vbt);
}
static void intel_bios_init_panel(struct drm_i915_private *i915,
......@@ -3344,8 +3420,7 @@ bool intel_bios_is_lvds_present(struct drm_i915_private *i915, u8 *i2c_pin)
* additional data. Trust that if the VBT was written into
* the OpRegion then they have validated the LVDS's existence.
*/
if (intel_opregion_get_vbt(i915, NULL))
return true;
return intel_opregion_vbt_present(i915);
}
return false;
......@@ -3706,13 +3781,12 @@ static int intel_bios_vbt_show(struct seq_file *m, void *unused)
const void *vbt;
size_t vbt_size;
/*
* FIXME: VBT might originate from other places than opregion, and then
* this would be incorrect.
*/
vbt = intel_opregion_get_vbt(i915, &vbt_size);
if (vbt)
vbt = intel_bios_get_vbt(i915, &vbt_size);
if (vbt) {
seq_write(m, vbt, vbt_size);
kfree(vbt);
}
return 0;
}
......
......@@ -52,7 +52,8 @@ struct intel_bw_state {
u8 num_active_planes[I915_MAX_PIPES];
};
#define to_intel_bw_state(x) container_of((x), struct intel_bw_state, base)
#define to_intel_bw_state(global_state) \
container_of_const((global_state), struct intel_bw_state, base)
struct intel_bw_state *
intel_atomic_get_old_bw_state(struct intel_atomic_state *state);
......
This diff is collapsed.
......@@ -18,6 +18,8 @@ struct intel_crtc_state;
struct intel_cdclk_config {
unsigned int cdclk, vco, ref, bypass;
u8 voltage_level;
/* This field is only valid for Xe2LPD and above. */
bool joined_mbus;
};
struct intel_cdclk_state {
......@@ -51,6 +53,9 @@ struct intel_cdclk_state {
/* bitmask of active pipes */
u8 active_pipes;
/* update cdclk with pipes disabled */
bool disable_pipes;
};
int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state);
......@@ -60,8 +65,11 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv);
void intel_update_max_cdclk(struct drm_i915_private *dev_priv);
void intel_update_cdclk(struct drm_i915_private *dev_priv);
u32 intel_read_rawclk(struct drm_i915_private *dev_priv);
bool intel_cdclk_needs_modeset(const struct intel_cdclk_config *a,
bool intel_cdclk_clock_changed(const struct intel_cdclk_config *a,
const struct intel_cdclk_config *b);
int intel_mdclk_cdclk_ratio(struct drm_i915_private *i915,
const struct intel_cdclk_config *cdclk_config);
bool intel_cdclk_is_decreasing_later(struct intel_atomic_state *state);
void intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state);
void intel_set_cdclk_post_plane_update(struct intel_atomic_state *state);
void intel_cdclk_dump_config(struct drm_i915_private *i915,
......@@ -72,10 +80,13 @@ void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv,
struct intel_cdclk_config *cdclk_config);
int intel_cdclk_atomic_check(struct intel_atomic_state *state,
bool *need_cdclk_calc);
int intel_cdclk_state_set_joined_mbus(struct intel_atomic_state *state, bool joined_mbus);
struct intel_cdclk_state *
intel_atomic_get_cdclk_state(struct intel_atomic_state *state);
#define to_intel_cdclk_state(x) container_of((x), struct intel_cdclk_state, base)
#define to_intel_cdclk_state(global_state) \
container_of_const((global_state), struct intel_cdclk_state, base)
#define intel_atomic_get_old_cdclk_state(state) \
to_intel_cdclk_state(intel_atomic_get_old_global_obj_state(state, &to_i915(state->base.dev)->display.cdclk.obj))
#define intel_atomic_get_new_cdclk_state(state) \
......
......@@ -25,28 +25,26 @@
4 * (dw))
#define ICL_PORT_CL_DW5(phy) _MMIO(_ICL_PORT_CL_DW(5, phy))
#define CL_POWER_DOWN_ENABLE (1 << 4)
#define SUS_CLOCK_CONFIG (3 << 0)
#define CL_POWER_DOWN_ENABLE REG_BIT(4)
#define SUS_CLOCK_CONFIG REG_GENMASK(1, 0)
#define ICL_PORT_CL_DW10(phy) _MMIO(_ICL_PORT_CL_DW(10, phy))
#define PG_SEQ_DELAY_OVERRIDE_MASK (3 << 25)
#define PG_SEQ_DELAY_OVERRIDE_SHIFT 25
#define PG_SEQ_DELAY_OVERRIDE_ENABLE (1 << 24)
#define PWR_UP_ALL_LANES (0x0 << 4)
#define PWR_DOWN_LN_3_2_1 (0xe << 4)
#define PWR_DOWN_LN_3_2 (0xc << 4)
#define PWR_DOWN_LN_3 (0x8 << 4)
#define PWR_DOWN_LN_2_1_0 (0x7 << 4)
#define PWR_DOWN_LN_1_0 (0x3 << 4)
#define PWR_DOWN_LN_3_1 (0xa << 4)
#define PWR_DOWN_LN_3_1_0 (0xb << 4)
#define PWR_DOWN_LN_MASK (0xf << 4)
#define PWR_DOWN_LN_SHIFT 4
#define EDP4K2K_MODE_OVRD_EN (1 << 3)
#define EDP4K2K_MODE_OVRD_OPTIMIZED (1 << 2)
#define PG_SEQ_DELAY_OVERRIDE_MASK REG_GENMASK(26, 25)
#define PG_SEQ_DELAY_OVERRIDE_ENABLE REG_BIT(24)
#define PWR_DOWN_LN_MASK REG_GENMASK(7, 4)
#define PWR_UP_ALL_LANES REG_FIELD_PREP(PWR_DOWN_LN_MASK, 0x0)
#define PWR_DOWN_LN_3_2_1 REG_FIELD_PREP(PWR_DOWN_LN_MASK, 0xe)
#define PWR_DOWN_LN_3_2 REG_FIELD_PREP(PWR_DOWN_LN_MASK, 0xc)
#define PWR_DOWN_LN_3 REG_FIELD_PREP(PWR_DOWN_LN_MASK, 0x8)
#define PWR_DOWN_LN_2_1_0 REG_FIELD_PREP(PWR_DOWN_LN_MASK, 0x7)
#define PWR_DOWN_LN_1_0 REG_FIELD_PREP(PWR_DOWN_LN_MASK, 0x3)
#define PWR_DOWN_LN_3_1 REG_FIELD_PREP(PWR_DOWN_LN_MASK, 0xa)
#define PWR_DOWN_LN_3_1_0 REG_FIELD_PREP(PWR_DOWN_LN_MASK, 0xb)
#define EDP4K2K_MODE_OVRD_EN REG_BIT(3)
#define EDP4K2K_MODE_OVRD_OPTIMIZED REG_BIT(2)
#define ICL_PORT_CL_DW12(phy) _MMIO(_ICL_PORT_CL_DW(12, phy))
#define ICL_LANE_ENABLE_AUX (1 << 0)
#define ICL_LANE_ENABLE_AUX REG_BIT(0)
/* ICL Port COMP_DW registers */
#define _ICL_PORT_COMP 0x100
......@@ -54,24 +52,22 @@
_ICL_PORT_COMP + 4 * (dw))
#define ICL_PORT_COMP_DW0(phy) _MMIO(_ICL_PORT_COMP_DW(0, phy))
#define COMP_INIT (1 << 31)
#define COMP_INIT REG_BIT(31)
#define ICL_PORT_COMP_DW1(phy) _MMIO(_ICL_PORT_COMP_DW(1, phy))
#define ICL_PORT_COMP_DW3(phy) _MMIO(_ICL_PORT_COMP_DW(3, phy))
#define PROCESS_INFO_DOT_0 (0 << 26)
#define PROCESS_INFO_DOT_1 (1 << 26)
#define PROCESS_INFO_DOT_4 (2 << 26)
#define PROCESS_INFO_MASK (7 << 26)
#define PROCESS_INFO_SHIFT 26
#define VOLTAGE_INFO_0_85V (0 << 24)
#define VOLTAGE_INFO_0_95V (1 << 24)
#define VOLTAGE_INFO_1_05V (2 << 24)
#define VOLTAGE_INFO_MASK (3 << 24)
#define VOLTAGE_INFO_SHIFT 24
#define PROCESS_INFO_MASK REG_GENMASK(28, 26)
#define PROCESS_INFO_DOT_0 REG_FIELD_PREP(PROCESS_INFO_MASK, 0)
#define PROCESS_INFO_DOT_1 REG_FIELD_PREP(PROCESS_INFO_MASK, 1)
#define PROCESS_INFO_DOT_4 REG_FIELD_PREP(PROCESS_INFO_MASK, 2)
#define VOLTAGE_INFO_MASK REG_GENMASK(25, 24)
#define VOLTAGE_INFO_0_85V REG_FIELD_PREP(VOLTAGE_INFO_MASK, 0)
#define VOLTAGE_INFO_0_95V REG_FIELD_PREP(VOLTAGE_INFO_MASK, 1)
#define VOLTAGE_INFO_1_05V REG_FIELD_PREP(VOLTAGE_INFO_MASK, 2)
#define ICL_PORT_COMP_DW8(phy) _MMIO(_ICL_PORT_COMP_DW(8, phy))
#define IREFGEN (1 << 24)
#define IREFGEN REG_BIT(24)
#define ICL_PORT_COMP_DW9(phy) _MMIO(_ICL_PORT_COMP_DW(9, phy))
......@@ -92,9 +88,9 @@
#define ICL_PORT_PCS_DW1_LN(ln, phy) _MMIO(_ICL_PORT_PCS_DW_LN(1, ln, phy))
#define DCC_MODE_SELECT_MASK REG_GENMASK(21, 20)
#define RUN_DCC_ONCE REG_FIELD_PREP(DCC_MODE_SELECT_MASK, 0)
#define COMMON_KEEPER_EN (1 << 26)
#define LATENCY_OPTIM_MASK (0x3 << 2)
#define LATENCY_OPTIM_VAL(x) ((x) << 2)
#define COMMON_KEEPER_EN REG_BIT(26)
#define LATENCY_OPTIM_MASK REG_GENMASK(3, 2)
#define LATENCY_OPTIM_VAL(x) REG_FIELD_PREP(LATENCY_OPTIM_MASK, (x))
/* ICL Port TX registers */
#define _ICL_PORT_TX_AUX 0x380
......@@ -111,42 +107,49 @@
#define ICL_PORT_TX_DW2_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(2, phy))
#define ICL_PORT_TX_DW2_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(2, phy))
#define ICL_PORT_TX_DW2_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(2, ln, phy))
#define SWING_SEL_UPPER(x) (((x) >> 3) << 15)
#define SWING_SEL_UPPER_MASK (1 << 15)
#define SWING_SEL_LOWER(x) (((x) & 0x7) << 11)
#define SWING_SEL_LOWER_MASK (0x7 << 11)
#define FRC_LATENCY_OPTIM_MASK (0x7 << 8)
#define FRC_LATENCY_OPTIM_VAL(x) ((x) << 8)
#define RCOMP_SCALAR(x) ((x) << 0)
#define RCOMP_SCALAR_MASK (0xFF << 0)
#define SWING_SEL_UPPER_MASK REG_BIT(15)
#define SWING_SEL_UPPER(x) REG_FIELD_PREP(SWING_SEL_UPPER_MASK, (x) >> 3)
#define SWING_SEL_LOWER_MASK REG_GENMASK(13, 11)
#define SWING_SEL_LOWER(x) REG_FIELD_PREP(SWING_SEL_LOWER_MASK, (x) & 0x7)
#define FRC_LATENCY_OPTIM_MASK REG_GENMASK(10, 8)
#define FRC_LATENCY_OPTIM_VAL(x) REG_FIELD_PREP(FRC_LATENCY_OPTIM_MASK, (x))
#define RCOMP_SCALAR_MASK REG_GENMASK(7, 0)
#define RCOMP_SCALAR(x) REG_FIELD_PREP(RCOMP_SCALAR_MASK, (x))
#define ICL_PORT_TX_DW4_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(4, phy))
#define ICL_PORT_TX_DW4_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(4, phy))
#define ICL_PORT_TX_DW4_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(4, ln, phy))
#define LOADGEN_SELECT (1 << 31)
#define POST_CURSOR_1(x) ((x) << 12)
#define POST_CURSOR_1_MASK (0x3F << 12)
#define POST_CURSOR_2(x) ((x) << 6)
#define POST_CURSOR_2_MASK (0x3F << 6)
#define CURSOR_COEFF(x) ((x) << 0)
#define CURSOR_COEFF_MASK (0x3F << 0)
#define LOADGEN_SELECT REG_BIT(31)
#define POST_CURSOR_1_MASK REG_GENMASK(17, 12)
#define POST_CURSOR_1(x) REG_FIELD_PREP(POST_CURSOR_1_MASK, (x))
#define POST_CURSOR_2_MASK REG_GENMASK(11, 6)
#define POST_CURSOR_2(x) REG_FIELD_PREP(POST_CURSOR_2_MASK, (x))
#define CURSOR_COEFF_MASK REG_GENMASK(5, 0)
#define CURSOR_COEFF(x) REG_FIELD_PREP(CURSOR_COEFF_MASK, (x))
#define ICL_PORT_TX_DW5_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(5, phy))
#define ICL_PORT_TX_DW5_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(5, phy))
#define ICL_PORT_TX_DW5_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(5, ln, phy))
#define TX_TRAINING_EN (1 << 31)
#define TAP2_DISABLE (1 << 30)
#define TAP3_DISABLE (1 << 29)
#define SCALING_MODE_SEL(x) ((x) << 18)
#define SCALING_MODE_SEL_MASK (0x7 << 18)
#define RTERM_SELECT(x) ((x) << 3)
#define RTERM_SELECT_MASK (0x7 << 3)
#define TX_TRAINING_EN REG_BIT(31)
#define TAP2_DISABLE REG_BIT(30)
#define TAP3_DISABLE REG_BIT(29)
#define SCALING_MODE_SEL_MASK REG_GENMASK(20, 18)
#define SCALING_MODE_SEL(x) REG_FIELD_PREP(SCALING_MODE_SEL_MASK, (x))
#define RTERM_SELECT_MASK REG_GENMASK(5, 3)
#define RTERM_SELECT(x) REG_FIELD_PREP(RTERM_SELECT_MASK, (x))
#define ICL_PORT_TX_DW6_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(6, phy))
#define ICL_PORT_TX_DW6_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(6, phy))
#define ICL_PORT_TX_DW6_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(6, ln, phy))
#define O_FUNC_OVRD_EN REG_BIT(7)
#define O_LDO_REF_SEL_CRI REG_GENMASK(6, 1)
#define O_LDO_BYPASS_CRI REG_BIT(0)
#define ICL_PORT_TX_DW7_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(7, phy))
#define ICL_PORT_TX_DW7_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(7, phy))
#define ICL_PORT_TX_DW7_LN(ln, phy) _MMIO(_ICL_PORT_TX_DW_LN(7, ln, phy))
#define N_SCALAR(x) ((x) << 24)
#define N_SCALAR_MASK (0x7F << 24)
#define N_SCALAR_MASK REG_GENMASK(30, 24)
#define N_SCALAR(x) REG_FIELD_PREP(N_SCALAR_MASK, (x))
#define ICL_PORT_TX_DW8_AUX(phy) _MMIO(_ICL_PORT_TX_DW_AUX(8, phy))
#define ICL_PORT_TX_DW8_GRP(phy) _MMIO(_ICL_PORT_TX_DW_GRP(8, phy))
......
......@@ -348,7 +348,7 @@ intel_crt_mode_valid(struct drm_connector *connector,
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
int max_dotclk = dev_priv->max_dotclk_freq;
int max_dotclk = dev_priv->display.cdclk.max_dotclk_freq;
enum drm_mode_status status;
int max_clock;
......@@ -356,9 +356,6 @@ intel_crt_mode_valid(struct drm_connector *connector,
if (status != MODE_OK)
return status;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
if (mode->clock < 25000)
return MODE_CLOCK_LOW;
......
......@@ -509,6 +509,24 @@ static void i9xx_cursor_disable_sel_fetch_arm(struct intel_plane *plane,
intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id), 0);
}
static void wa_16021440873(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
u32 ctl = plane_state->ctl;
int et_y_position = drm_rect_height(&crtc_state->pipe_src) + 1;
enum pipe pipe = plane->pipe;
ctl &= ~MCURSOR_MODE_MASK;
ctl |= MCURSOR_MODE_64_2B;
intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id), ctl);
intel_de_write(dev_priv, PIPE_SRCSZ_ERLY_TPT(pipe),
PIPESRC_HEIGHT(et_y_position));
}
static void i9xx_cursor_update_sel_fetch_arm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
......@@ -529,7 +547,11 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_plane *plane,
intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id),
plane_state->ctl);
} else {
i9xx_cursor_disable_sel_fetch_arm(plane, crtc_state);
/* Wa_16021440873 */
if (crtc_state->enable_psr2_su_region_et)
wa_16021440873(plane, crtc_state, plane_state);
else
i9xx_cursor_disable_sel_fetch_arm(plane, crtc_state);
}
}
......
......@@ -11,7 +11,6 @@
#include <linux/bits.h>
enum icl_port_dpll_id;
enum phy;
struct drm_i915_private;
struct intel_atomic_state;
struct intel_c10pll_state;
......@@ -22,7 +21,7 @@ struct intel_crtc_state;
struct intel_encoder;
struct intel_hdmi;
bool intel_is_c10phy(struct drm_i915_private *dev_priv, enum phy phy);
bool intel_encoder_is_c10phy(struct intel_encoder *encoder);
void intel_mtl_pll_enable(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
void intel_mtl_pll_disable(struct intel_encoder *encoder);
......
This diff is collapsed.
......@@ -1691,14 +1691,11 @@ mtl_get_cx0_buf_trans(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
if (intel_crtc_has_dp_encoder(crtc_state) && crtc_state->port_clock >= 1000000)
return intel_get_buf_trans(&mtl_c20_trans_uhbr, n_entries);
else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && !(intel_is_c10phy(i915, phy)))
else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && !(intel_encoder_is_c10phy(encoder)))
return intel_get_buf_trans(&mtl_c20_trans_hdmi, n_entries);
else if (!intel_is_c10phy(i915, phy))
else if (!intel_encoder_is_c10phy(encoder))
return intel_get_buf_trans(&mtl_c20_trans_dp14, n_entries);
else
return intel_get_buf_trans(&mtl_c10_trans_dp14, n_entries);
......@@ -1707,14 +1704,13 @@ mtl_get_cx0_buf_trans(struct intel_encoder *encoder,
void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
if (DISPLAY_VER(i915) >= 14) {
encoder->get_buf_trans = mtl_get_cx0_buf_trans;
} else if (IS_DG2(i915)) {
encoder->get_buf_trans = dg2_get_snps_buf_trans;
} else if (IS_ALDERLAKE_P(i915)) {
if (intel_phy_is_combo(i915, phy))
if (intel_encoder_is_combo(encoder))
encoder->get_buf_trans = adlp_get_combo_buf_trans;
else
encoder->get_buf_trans = adlp_get_dkl_buf_trans;
......@@ -1725,16 +1721,16 @@ void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
} else if (IS_DG1(i915)) {
encoder->get_buf_trans = dg1_get_combo_buf_trans;
} else if (DISPLAY_VER(i915) >= 12) {
if (intel_phy_is_combo(i915, phy))
if (intel_encoder_is_combo(encoder))
encoder->get_buf_trans = tgl_get_combo_buf_trans;
else
encoder->get_buf_trans = tgl_get_dkl_buf_trans;
} else if (DISPLAY_VER(i915) == 11) {
if (IS_PLATFORM(i915, INTEL_JASPERLAKE))
if (IS_JASPERLAKE(i915))
encoder->get_buf_trans = jsl_get_combo_buf_trans;
else if (IS_PLATFORM(i915, INTEL_ELKHARTLAKE))
else if (IS_ELKHARTLAKE(i915))
encoder->get_buf_trans = ehl_get_combo_buf_trans;
else if (intel_phy_is_combo(i915, phy))
else if (intel_encoder_is_combo(encoder))
encoder->get_buf_trans = icl_get_combo_buf_trans;
else
encoder->get_buf_trans = icl_get_mg_buf_trans;
......
......@@ -13,76 +13,157 @@
static inline u32
intel_de_read(struct drm_i915_private *i915, i915_reg_t reg)
{
return intel_uncore_read(&i915->uncore, reg);
u32 val;
intel_dmc_wl_get(i915, reg);
val = intel_uncore_read(&i915->uncore, reg);
intel_dmc_wl_put(i915, reg);
return val;
}
static inline u8
intel_de_read8(struct drm_i915_private *i915, i915_reg_t reg)
{
return intel_uncore_read8(&i915->uncore, reg);
u8 val;
intel_dmc_wl_get(i915, reg);
val = intel_uncore_read8(&i915->uncore, reg);
intel_dmc_wl_put(i915, reg);
return val;
}
static inline u64
intel_de_read64_2x32(struct drm_i915_private *i915,
i915_reg_t lower_reg, i915_reg_t upper_reg)
{
return intel_uncore_read64_2x32(&i915->uncore, lower_reg, upper_reg);
u64 val;
intel_dmc_wl_get(i915, lower_reg);
intel_dmc_wl_get(i915, upper_reg);
val = intel_uncore_read64_2x32(&i915->uncore, lower_reg, upper_reg);
intel_dmc_wl_put(i915, upper_reg);
intel_dmc_wl_put(i915, lower_reg);
return val;
}
static inline void
intel_de_posting_read(struct drm_i915_private *i915, i915_reg_t reg)
{
intel_dmc_wl_get(i915, reg);
intel_uncore_posting_read(&i915->uncore, reg);
intel_dmc_wl_put(i915, reg);
}
static inline void
intel_de_write(struct drm_i915_private *i915, i915_reg_t reg, u32 val)
{
intel_dmc_wl_get(i915, reg);
intel_uncore_write(&i915->uncore, reg, val);
intel_dmc_wl_put(i915, reg);
}
static inline u32
intel_de_rmw(struct drm_i915_private *i915, i915_reg_t reg, u32 clear, u32 set)
__intel_de_rmw_nowl(struct drm_i915_private *i915, i915_reg_t reg,
u32 clear, u32 set)
{
return intel_uncore_rmw(&i915->uncore, reg, clear, set);
}
static inline u32
intel_de_rmw(struct drm_i915_private *i915, i915_reg_t reg, u32 clear, u32 set)
{
u32 val;
intel_dmc_wl_get(i915, reg);
val = __intel_de_rmw_nowl(i915, reg, clear, set);
intel_dmc_wl_put(i915, reg);
return val;
}
static inline int
__intel_wait_for_register_nowl(struct drm_i915_private *i915, i915_reg_t reg,
u32 mask, u32 value, unsigned int timeout)
{
return intel_wait_for_register(&i915->uncore, reg, mask,
value, timeout);
}
static inline int
intel_de_wait_for_register(struct drm_i915_private *i915, i915_reg_t reg,
u32 mask, u32 value, unsigned int timeout)
intel_de_wait(struct drm_i915_private *i915, i915_reg_t reg,
u32 mask, u32 value, unsigned int timeout)
{
return intel_wait_for_register(&i915->uncore, reg, mask, value, timeout);
int ret;
intel_dmc_wl_get(i915, reg);
ret = __intel_wait_for_register_nowl(i915, reg, mask, value, timeout);
intel_dmc_wl_put(i915, reg);
return ret;
}
static inline int
intel_de_wait_for_register_fw(struct drm_i915_private *i915, i915_reg_t reg,
u32 mask, u32 value, unsigned int timeout)
intel_de_wait_fw(struct drm_i915_private *i915, i915_reg_t reg,
u32 mask, u32 value, unsigned int timeout)
{
return intel_wait_for_register_fw(&i915->uncore, reg, mask, value, timeout);
int ret;
intel_dmc_wl_get(i915, reg);
ret = intel_wait_for_register_fw(&i915->uncore, reg, mask, value, timeout);
intel_dmc_wl_put(i915, reg);
return ret;
}
static inline int
__intel_de_wait_for_register(struct drm_i915_private *i915, 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 drm_i915_private *i915, i915_reg_t reg,
u32 mask, u32 value,
unsigned int fast_timeout_us,
unsigned int slow_timeout_ms, u32 *out_value)
{
return __intel_wait_for_register(&i915->uncore, reg, mask, value,
fast_timeout_us, slow_timeout_ms, out_value);
int ret;
intel_dmc_wl_get(i915, reg);
ret = __intel_wait_for_register(&i915->uncore, reg, mask, value,
fast_timeout_us, slow_timeout_ms, out_value);
intel_dmc_wl_put(i915, reg);
return ret;
}
static inline int
intel_de_wait_for_set(struct drm_i915_private *i915, i915_reg_t reg,
u32 mask, unsigned int timeout)
{
return intel_de_wait_for_register(i915, reg, mask, mask, timeout);
return intel_de_wait(i915, reg, mask, mask, timeout);
}
static inline int
intel_de_wait_for_clear(struct drm_i915_private *i915, i915_reg_t reg,
u32 mask, unsigned int timeout)
{
return intel_de_wait_for_register(i915, reg, mask, 0, timeout);
return intel_de_wait(i915, reg, mask, 0, timeout);
}
/*
......
......@@ -280,6 +280,12 @@ enum phy_fia {
base.head) \
for_each_if((pipe_mask) & BIT(intel_crtc->pipe))
#define for_each_intel_crtc_in_pipe_mask_reverse(dev, intel_crtc, pipe_mask) \
list_for_each_entry_reverse((intel_crtc), \
&(dev)->mode_config.crtc_list, \
base.head) \
for_each_if((pipe_mask) & BIT((intel_crtc)->pipe))
#define for_each_intel_encoder(dev, intel_encoder) \
list_for_each_entry(intel_encoder, \
&(dev)->mode_config.encoder_list, \
......@@ -344,6 +350,14 @@ enum phy_fia {
(__i)++) \
for_each_if(crtc)
#define for_each_new_intel_crtc_in_state_reverse(__state, crtc, new_crtc_state, __i) \
for ((__i) = (__state)->base.dev->mode_config.num_crtc - 1; \
(__i) >= 0 && \
((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
(new_crtc_state) = to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
(__i)--) \
for_each_if(crtc)
#define for_each_oldnew_intel_plane_in_state(__state, plane, old_plane_state, new_plane_state, __i) \
for ((__i) = 0; \
(__i) < (__state)->base.dev->mode_config.num_total_plane && \
......@@ -408,6 +422,7 @@ intel_cpu_transcoder_mode_valid(struct drm_i915_private *i915,
enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
bool is_trans_port_sync_master(const struct intel_crtc_state *state);
u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state);
bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state);
bool intel_crtc_is_bigjoiner_master(const struct intel_crtc_state *crtc_state);
u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state *crtc_state);
......@@ -448,6 +463,13 @@ bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy);
bool intel_phy_is_snps(struct drm_i915_private *dev_priv, enum phy phy);
enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv,
enum port port);
enum phy intel_encoder_to_phy(struct intel_encoder *encoder);
bool intel_encoder_is_combo(struct intel_encoder *encoder);
bool intel_encoder_is_snps(struct intel_encoder *encoder);
bool intel_encoder_is_tc(struct intel_encoder *encoder);
enum tc_port intel_encoder_to_tc(struct intel_encoder *encoder);
int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
......
......@@ -26,6 +26,7 @@
#include "intel_global_state.h"
#include "intel_gmbus.h"
#include "intel_opregion.h"
#include "intel_dmc_wl.h"
#include "intel_wm_types.h"
struct task_struct;
......@@ -345,6 +346,8 @@ struct intel_display {
struct intel_global_obj obj;
unsigned int max_cdclk_freq;
unsigned int max_dotclk_freq;
unsigned int skl_preferred_vco_freq;
} cdclk;
struct {
......@@ -445,6 +448,16 @@ struct intel_display {
bool false_color;
} ips;
struct {
bool display_irqs_enabled;
/* For i915gm/i945gm vblank irq workaround */
u8 vblank_enabled;
u32 de_irq_mask[I915_MAX_PIPES];
u32 pipestat_irq_mask[I915_MAX_PIPES];
} irq;
struct {
wait_queue_head_t waitqueue;
......@@ -534,6 +547,7 @@ struct intel_display {
struct intel_overlay *overlay;
struct intel_display_params params;
struct intel_vbt_data vbt;
struct intel_dmc_wl wl;
struct intel_wm wm;
};
......
......@@ -31,6 +31,7 @@
#include "intel_hdmi.h"
#include "intel_hotplug.h"
#include "intel_panel.h"
#include "intel_pps.h"
#include "intel_psr.h"
#include "intel_psr_regs.h"
#include "intel_wm.h"
......@@ -191,7 +192,7 @@ static void intel_hdcp_info(struct seq_file *m,
struct intel_connector *intel_connector,
bool remote_req)
{
bool hdcp_cap, hdcp2_cap;
bool hdcp_cap = false, hdcp2_cap = false;
if (!intel_connector->hdcp.shim) {
seq_puts(m, "No Connector Support");
......@@ -252,9 +253,6 @@ static void intel_connector_info(struct seq_file *m,
struct drm_connector *connector)
{
struct intel_connector *intel_connector = to_intel_connector(connector);
const struct drm_connector_state *conn_state = connector->state;
struct intel_encoder *encoder =
to_intel_encoder(conn_state->best_encoder);
const struct drm_display_mode *mode;
seq_printf(m, "[CONNECTOR:%d:%s]: status: %s\n",
......@@ -271,28 +269,23 @@ static void intel_connector_info(struct seq_file *m,
drm_get_subpixel_order_name(connector->display_info.subpixel_order));
seq_printf(m, "\tCEA rev: %d\n", connector->display_info.cea_rev);
if (!encoder)
return;
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DisplayPort:
case DRM_MODE_CONNECTOR_eDP:
if (encoder->type == INTEL_OUTPUT_DP_MST)
if (intel_connector->mst_port)
intel_dp_mst_info(m, intel_connector);
else
intel_dp_info(m, intel_connector);
break;
case DRM_MODE_CONNECTOR_HDMIA:
if (encoder->type == INTEL_OUTPUT_HDMI ||
encoder->type == INTEL_OUTPUT_DDI)
intel_hdmi_info(m, intel_connector);
intel_hdmi_info(m, intel_connector);
break;
default:
break;
}
seq_puts(m, "\tHDCP version: ");
if (intel_encoder_is_mst(encoder)) {
if (intel_connector->mst_port) {
intel_hdcp_info(m, intel_connector, true);
seq_puts(m, "\tMST Hub HDCP version: ");
}
......@@ -1103,27 +1096,6 @@ void intel_display_debugfs_register(struct drm_i915_private *i915)
intel_display_debugfs_params(i915);
}
static int i915_panel_show(struct seq_file *m, void *data)
{
struct intel_connector *connector = m->private;
struct intel_dp *intel_dp = intel_attached_dp(connector);
if (connector->base.status != connector_status_connected)
return -ENODEV;
seq_printf(m, "Panel power up delay: %d\n",
intel_dp->pps.panel_power_up_delay);
seq_printf(m, "Panel power down delay: %d\n",
intel_dp->pps.panel_power_down_delay);
seq_printf(m, "Backlight on delay: %d\n",
intel_dp->pps.backlight_on_delay);
seq_printf(m, "Backlight off delay: %d\n",
intel_dp->pps.backlight_off_delay);
return 0;
}
DEFINE_SHOW_ATTRIBUTE(i915_panel);
static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
{
struct intel_connector *connector = m->private;
......@@ -1402,20 +1374,6 @@ out: drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
return ret;
}
static int i915_bigjoiner_enable_show(struct seq_file *m, void *data)
{
struct intel_connector *connector = m->private;
struct drm_crtc *crtc;
crtc = connector->base.state->crtc;
if (connector->base.status != connector_status_connected || !crtc)
return -ENODEV;
seq_printf(m, "Bigjoiner enable: %d\n", connector->force_bigjoiner_enable);
return 0;
}
static ssize_t i915_dsc_output_format_write(struct file *file,
const char __user *ubuf,
size_t len, loff_t *offp)
......@@ -1437,30 +1395,6 @@ static ssize_t i915_dsc_output_format_write(struct file *file,
return len;
}
static ssize_t i915_bigjoiner_enable_write(struct file *file,
const char __user *ubuf,
size_t len, loff_t *offp)
{
struct seq_file *m = file->private_data;
struct intel_connector *connector = m->private;
struct drm_crtc *crtc;
bool bigjoiner_en = 0;
int ret;
crtc = connector->base.state->crtc;
if (connector->base.status != connector_status_connected || !crtc)
return -ENODEV;
ret = kstrtobool_from_user(ubuf, len, &bigjoiner_en);
if (ret < 0)
return ret;
connector->force_bigjoiner_enable = bigjoiner_en;
*offp += len;
return len;
}
static int i915_dsc_output_format_open(struct inode *inode,
struct file *file)
{
......@@ -1554,8 +1488,6 @@ static const struct file_operations i915_dsc_fractional_bpp_fops = {
.write = i915_dsc_fractional_bpp_write
};
DEFINE_SHOW_STORE_ATTRIBUTE(i915_bigjoiner_enable);
/*
* Returns the Current CRTC's bpc.
* Example usage: cat /sys/kernel/debug/dri/0/crtc-0/i915_current_bpc
......@@ -1608,12 +1540,9 @@ void intel_connector_debugfs_add(struct intel_connector *connector)
return;
intel_drrs_connector_debugfs_add(connector);
intel_pps_connector_debugfs_add(connector);
intel_psr_connector_debugfs_add(connector);
if (connector_type == DRM_MODE_CONNECTOR_eDP)
debugfs_create_file("i915_panel_timings", 0444, root,
connector, &i915_panel_fops);
if (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
connector_type == DRM_MODE_CONNECTOR_HDMIA ||
connector_type == DRM_MODE_CONNECTOR_HDMIB) {
......@@ -1640,8 +1569,8 @@ void intel_connector_debugfs_add(struct intel_connector *connector)
if (DISPLAY_VER(i915) >= 11 &&
(connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
connector_type == DRM_MODE_CONNECTOR_eDP)) {
debugfs_create_file("i915_bigjoiner_force_enable", 0644, root,
connector, &i915_bigjoiner_enable_fops);
debugfs_create_bool("i915_bigjoiner_force_enable", 0644, root,
&connector->force_bigjoiner_enable);
}
if (connector_type == DRM_MODE_CONNECTOR_DSI ||
......
......@@ -17,6 +17,9 @@
#include "intel_display_reg_defs.h"
#include "intel_fbc.h"
__diag_push();
__diag_ignore_all("-Woverride-init", "Allow field initialization overrides for display info");
static const struct intel_display_device_info no_display = {};
#define PIPE_A_OFFSET 0x70000
......@@ -768,6 +771,8 @@ static const struct intel_display_device_info xe2_lpd_display = {
BIT(INTEL_FBC_C) | BIT(INTEL_FBC_D),
};
__diag_pop();
/*
* Separate detection for no display cases to keep the display id array simple.
*
......
......@@ -47,6 +47,7 @@ struct drm_printer;
#define HAS_DPT(i915) (DISPLAY_VER(i915) >= 13)
#define HAS_DSB(i915) (DISPLAY_INFO(i915)->has_dsb)
#define HAS_DSC(__i915) (DISPLAY_RUNTIME_INFO(__i915)->has_dsc)
#define HAS_DSC_MST(__i915) (DISPLAY_VER(__i915) >= 12 && HAS_DSC(__i915))
#define HAS_FBC(i915) (DISPLAY_RUNTIME_INFO(i915)->fbc_mask != 0)
#define HAS_FPGA_DBG_UNCLAIMED(i915) (DISPLAY_INFO(i915)->has_fpga_dbg)
#define HAS_FW_BLC(i915) (DISPLAY_VER(i915) >= 3)
......@@ -68,6 +69,7 @@ struct drm_printer;
#define HAS_TRANSCODER(i915, trans) ((DISPLAY_RUNTIME_INFO(i915)->cpu_transcoder_mask & \
BIT(trans)) != 0)
#define HAS_VRR(i915) (DISPLAY_VER(i915) >= 11)
#define HAS_AS_SDP(i915) (DISPLAY_VER(i915) >= 13)
#define INTEL_NUM_PIPES(i915) (hweight8(DISPLAY_RUNTIME_INFO(i915)->pipe_mask))
#define I915_HAS_HOTPLUG(i915) (DISPLAY_INFO(i915)->has_hotplug)
#define OVERLAY_NEEDS_PHYSICAL(i915) (DISPLAY_INFO(i915)->overlay_needs_physical)
......
......@@ -198,6 +198,7 @@ void intel_display_driver_early_probe(struct drm_i915_private *i915)
intel_dpll_init_clock_hook(i915);
intel_init_display_hooks(i915);
intel_fdi_init_hook(i915);
intel_dmc_wl_init(i915);
}
/* part #1: call before irq install */
......
......@@ -116,6 +116,11 @@ intel_display_param_named_unsafe(enable_psr2_sel_fetch, bool, 0400,
"(0=disabled, 1=enabled) "
"Default: 1");
intel_display_param_named_unsafe(enable_dmc_wl, bool, 0400,
"Enable DMC wakelock "
"(0=disabled, 1=enabled) "
"Default: 0");
__maybe_unused
static void _param_print_bool(struct drm_printer *p, const char *driver_name,
const char *name, bool val)
......
......@@ -46,6 +46,7 @@ struct drm_i915_private;
param(int, enable_psr, -1, 0600) \
param(bool, psr_safest_params, false, 0400) \
param(bool, enable_psr2_sel_fetch, true, 0400) \
param(bool, enable_dmc_wl, false, 0400) \
#define MEMBER(T, member, ...) T member;
struct intel_display_params {
......
......@@ -10,20 +10,12 @@
static void gen11_display_wa_apply(struct drm_i915_private *i915)
{
/* Wa_1409120013 */
intel_de_write(i915, ILK_DPFC_CHICKEN(INTEL_FBC_A),
DPFC_CHICKEN_COMP_DUMMY_PIXEL);
/* Wa_14010594013 */
intel_de_rmw(i915, GEN8_CHICKEN_DCPR_1, 0, ICL_DELAY_PMRSP);
}
static void xe_d_display_wa_apply(struct drm_i915_private *i915)
{
/* Wa_1409120013 */
intel_de_write(i915, ILK_DPFC_CHICKEN(INTEL_FBC_A),
DPFC_CHICKEN_COMP_DUMMY_PIXEL);
/* Wa_14013723622 */
intel_de_rmw(i915, CLKREQ_POLICY, CLKREQ_POLICY_MEM_UP_OVRD, 0);
}
......
This diff is collapsed.
......@@ -97,4 +97,10 @@
#define TGL_DMC_DEBUG3 _MMIO(0x101090)
#define DG1_DMC_DEBUG3 _MMIO(0x13415c)
#define DMC_WAKELOCK_CFG _MMIO(0x8F1B0)
#define DMC_WAKELOCK_CFG_ENABLE REG_BIT(31)
#define DMC_WAKELOCK1_CTL _MMIO(0x8F140)
#define DMC_WAKELOCK_CTL_REQ REG_BIT(31)
#define DMC_WAKELOCK_CTL_ACK REG_BIT(15)
#endif /* __INTEL_DMC_REGS_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -20,5 +20,6 @@ enum aux_ch intel_dp_aux_ch(struct intel_encoder *encoder);
void intel_dp_aux_irq_handler(struct drm_i915_private *i915);
u32 intel_dp_aux_pack(const u8 *src, int src_bytes);
int intel_dp_aux_fw_sync_len(void);
#endif /* __INTEL_DP_AUX_H__ */
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.
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.
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