mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
Merge branch 'for-linux-next' of https://gitlab.freedesktop.org/drm/i915/kernel
# Conflicts: # drivers/gpu/drm/i915/display/intel_dp_mst.c # drivers/gpu/drm/i915/display/intel_dsb.c
This commit is contained in:
commit
e069bb813f
@ -390,3 +390,26 @@ void drm_print_regset32(struct drm_printer *p, struct debugfs_regset32 *regset)
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_print_regset32);
|
||||
|
||||
/**
|
||||
* drm_print_hex_dump - print a hex dump to a &drm_printer stream
|
||||
* @p: The &drm_printer
|
||||
* @prefix: Prefix for each line, may be NULL for no prefix
|
||||
* @buf: Buffer to dump
|
||||
* @len: Length of buffer
|
||||
*
|
||||
* Print hex dump to &drm_printer, with 16 space-separated hex bytes per line,
|
||||
* optionally with a prefix on each line. No separator is added after prefix.
|
||||
*/
|
||||
void drm_print_hex_dump(struct drm_printer *p, const char *prefix,
|
||||
const u8 *buf, size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i += 16) {
|
||||
int bytes_per_line = min(16, len - i);
|
||||
|
||||
drm_printf(p, "%s%*ph\n", prefix ?: "", bytes_per_line, buf + i);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_print_hex_dump);
|
||||
|
@ -30,11 +30,11 @@ i915-y += \
|
||||
i915_params.o \
|
||||
i915_pci.o \
|
||||
i915_scatterlist.o \
|
||||
i915_suspend.o \
|
||||
i915_switcheroo.o \
|
||||
i915_sysfs.o \
|
||||
i915_utils.o \
|
||||
intel_clock_gating.o \
|
||||
intel_cpu_info.o \
|
||||
intel_device_info.o \
|
||||
intel_memory_region.o \
|
||||
intel_pcode.o \
|
||||
@ -43,6 +43,7 @@ i915-y += \
|
||||
intel_sbi.o \
|
||||
intel_step.o \
|
||||
intel_uncore.o \
|
||||
intel_uncore_trace.o \
|
||||
intel_wakeref.o \
|
||||
vlv_sideband.o \
|
||||
vlv_suspend.o
|
||||
@ -220,6 +221,7 @@ i915-$(CONFIG_HWMON) += \
|
||||
i915-y += \
|
||||
display/hsw_ips.o \
|
||||
display/i9xx_plane.o \
|
||||
display/i9xx_display_sr.o \
|
||||
display/i9xx_wm.o \
|
||||
display/intel_alpm.o \
|
||||
display/intel_atomic.o \
|
||||
@ -236,6 +238,7 @@ i915-y += \
|
||||
display/intel_crtc_state_dump.o \
|
||||
display/intel_cursor.o \
|
||||
display/intel_display.o \
|
||||
display/intel_display_conversion.o \
|
||||
display/intel_display_driver.o \
|
||||
display/intel_display_irq.o \
|
||||
display/intel_display_params.o \
|
||||
|
@ -26,7 +26,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dvo_dev.h"
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <linux/string_helpers.h>
|
||||
|
||||
#include "g4x_dp.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_audio.h"
|
||||
#include "intel_backlight.h"
|
||||
@ -55,8 +56,8 @@ const struct dpll *vlv_get_dpll(struct drm_i915_private *i915)
|
||||
return IS_CHERRYVIEW(i915) ? &chv_dpll[0] : &vlv_dpll[0];
|
||||
}
|
||||
|
||||
void g4x_dp_set_clock(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
static void g4x_dp_set_clock(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
const struct dpll *divisor = NULL;
|
||||
@ -1223,6 +1224,25 @@ static bool ilk_digital_port_connected(struct intel_encoder *encoder)
|
||||
return intel_de_read(display, DEISR) & bit;
|
||||
}
|
||||
|
||||
static int g4x_dp_compute_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
int ret;
|
||||
|
||||
if (HAS_PCH_SPLIT(i915) && encoder->port != PORT_A)
|
||||
crtc_state->has_pch_encoder = true;
|
||||
|
||||
ret = intel_dp_compute_config(encoder, crtc_state, conn_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
g4x_dp_set_clock(encoder, crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void g4x_dp_suspend_complete(struct intel_encoder *encoder)
|
||||
{
|
||||
/*
|
||||
@ -1307,7 +1327,7 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
|
||||
intel_encoder_link_check_init(intel_encoder, intel_dp_link_check);
|
||||
|
||||
intel_encoder->hotplug = intel_dp_hotplug;
|
||||
intel_encoder->compute_config = intel_dp_compute_config;
|
||||
intel_encoder->compute_config = g4x_dp_compute_config;
|
||||
intel_encoder->get_hw_state = intel_dp_get_hw_state;
|
||||
intel_encoder->get_config = intel_dp_get_config;
|
||||
intel_encoder->sync_state = intel_dp_sync_state;
|
||||
|
@ -19,8 +19,6 @@ struct intel_encoder;
|
||||
|
||||
#ifdef I915
|
||||
const struct dpll *vlv_get_dpll(struct drm_i915_private *i915);
|
||||
void g4x_dp_set_clock(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config);
|
||||
bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t dp_reg, enum port port,
|
||||
enum pipe *pipe);
|
||||
@ -31,10 +29,6 @@ static inline const struct dpll *vlv_get_dpll(struct drm_i915_private *i915)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline void g4x_dp_set_clock(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
}
|
||||
static inline bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t dp_reg, int port,
|
||||
enum pipe *pipe)
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "g4x_hdmi.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_audio.h"
|
||||
|
@ -185,10 +185,12 @@ void hsw_ips_post_update(struct intel_atomic_state *state,
|
||||
/* IPS only exists on ULT machines and is tied to pipe A. */
|
||||
bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
|
||||
{
|
||||
return HAS_IPS(to_i915(crtc->base.dev)) && crtc->pipe == PIPE_A;
|
||||
struct intel_display *display = to_intel_display(crtc);
|
||||
|
||||
return HAS_IPS(display) && crtc->pipe == PIPE_A;
|
||||
}
|
||||
|
||||
bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
|
||||
static 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);
|
||||
@ -218,6 +220,20 @@ bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
|
||||
return true;
|
||||
}
|
||||
|
||||
int hsw_ips_min_cdclk(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
||||
|
||||
if (!IS_BROADWELL(i915))
|
||||
return 0;
|
||||
|
||||
if (!hsw_crtc_state_ips_capable(crtc_state))
|
||||
return 0;
|
||||
|
||||
/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
|
||||
return DIV_ROUND_UP(crtc_state->pixel_rate * 100, 95);
|
||||
}
|
||||
|
||||
int hsw_ips_compute_config(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
|
@ -19,7 +19,7 @@ bool hsw_ips_pre_update(struct intel_atomic_state *state,
|
||||
void hsw_ips_post_update(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
bool hsw_crtc_supports_ips(struct intel_crtc *crtc);
|
||||
bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state);
|
||||
int hsw_ips_min_cdclk(const struct intel_crtc_state *crtc_state);
|
||||
int hsw_ips_compute_config(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
void hsw_ips_get_config(struct intel_crtc_state *crtc_state);
|
||||
@ -42,9 +42,9 @@ static inline bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
|
||||
static inline int hsw_ips_min_cdclk(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
static inline int hsw_ips_compute_config(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
|
97
drivers/gpu/drm/i915/display/i9xx_display_sr.c
Normal file
97
drivers/gpu/drm/i915/display/i9xx_display_sr.c
Normal file
@ -0,0 +1,97 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright © 2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <drm/drm_device.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i9xx_display_sr.h"
|
||||
#include "i9xx_wm_regs.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_gmbus.h"
|
||||
#include "intel_pci_config.h"
|
||||
|
||||
static void i9xx_display_save_swf(struct intel_display *display)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Scratch space */
|
||||
if (DISPLAY_VER(display) == 2 && display->platform.mobile) {
|
||||
for (i = 0; i < 7; i++) {
|
||||
display->restore.saveSWF0[i] = intel_de_read(display, SWF0(display, i));
|
||||
display->restore.saveSWF1[i] = intel_de_read(display, SWF1(display, i));
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
display->restore.saveSWF3[i] = intel_de_read(display, SWF3(display, i));
|
||||
} else if (DISPLAY_VER(display) == 2) {
|
||||
for (i = 0; i < 7; i++)
|
||||
display->restore.saveSWF1[i] = intel_de_read(display, SWF1(display, i));
|
||||
} else if (HAS_GMCH(display)) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
display->restore.saveSWF0[i] = intel_de_read(display, SWF0(display, i));
|
||||
display->restore.saveSWF1[i] = intel_de_read(display, SWF1(display, i));
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
display->restore.saveSWF3[i] = intel_de_read(display, SWF3(display, i));
|
||||
}
|
||||
}
|
||||
|
||||
static void i9xx_display_restore_swf(struct intel_display *display)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Scratch space */
|
||||
if (DISPLAY_VER(display) == 2 && display->platform.mobile) {
|
||||
for (i = 0; i < 7; i++) {
|
||||
intel_de_write(display, SWF0(display, i), display->restore.saveSWF0[i]);
|
||||
intel_de_write(display, SWF1(display, i), display->restore.saveSWF1[i]);
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
intel_de_write(display, SWF3(display, i), display->restore.saveSWF3[i]);
|
||||
} else if (DISPLAY_VER(display) == 2) {
|
||||
for (i = 0; i < 7; i++)
|
||||
intel_de_write(display, SWF1(display, i), display->restore.saveSWF1[i]);
|
||||
} else if (HAS_GMCH(display)) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
intel_de_write(display, SWF0(display, i), display->restore.saveSWF0[i]);
|
||||
intel_de_write(display, SWF1(display, i), display->restore.saveSWF1[i]);
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
intel_de_write(display, SWF3(display, i), display->restore.saveSWF3[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void i9xx_display_sr_save(struct intel_display *display)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(display->drm->dev);
|
||||
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
/* Display arbitration control */
|
||||
if (DISPLAY_VER(display) <= 4)
|
||||
display->restore.saveDSPARB = intel_de_read(display, DSPARB(display));
|
||||
|
||||
if (DISPLAY_VER(display) == 4)
|
||||
pci_read_config_word(pdev, GCDGMBUS, &display->restore.saveGCDGMBUS);
|
||||
|
||||
i9xx_display_save_swf(display);
|
||||
}
|
||||
|
||||
void i9xx_display_sr_restore(struct intel_display *display)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(display->drm->dev);
|
||||
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
i9xx_display_restore_swf(display);
|
||||
|
||||
if (DISPLAY_VER(display) == 4)
|
||||
pci_write_config_word(pdev, GCDGMBUS, display->restore.saveGCDGMBUS);
|
||||
|
||||
/* Display arbitration */
|
||||
if (DISPLAY_VER(display) <= 4)
|
||||
intel_de_write(display, DSPARB(display), display->restore.saveDSPARB);
|
||||
}
|
14
drivers/gpu/drm/i915/display/i9xx_display_sr.h
Normal file
14
drivers/gpu/drm/i915/display/i9xx_display_sr.h
Normal file
@ -0,0 +1,14 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __I9XX_DISPLAY_SR_H__
|
||||
#define __I9XX_DISPLAY_SR_H__
|
||||
|
||||
struct intel_display;
|
||||
|
||||
void i9xx_display_sr_save(struct intel_display *display);
|
||||
void i9xx_display_sr_restore(struct intel_display *display);
|
||||
|
||||
#endif
|
@ -8,6 +8,7 @@
|
||||
#include <drm/drm_blend.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i9xx_plane.h"
|
||||
#include "i9xx_plane_regs.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i9xx_wm.h"
|
||||
#include "i9xx_wm_regs.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_bo.h"
|
||||
#include "intel_display.h"
|
||||
|
257
drivers/gpu/drm/i915/display/i9xx_wm_regs.h
Normal file
257
drivers/gpu/drm/i915/display/i9xx_wm_regs.h
Normal file
@ -0,0 +1,257 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright © 2024 Intel Corporation */
|
||||
|
||||
#ifndef __I9XX_WM_REGS_H__
|
||||
#define __I9XX_WM_REGS_H__
|
||||
|
||||
#include "intel_display_reg_defs.h"
|
||||
|
||||
#define DSPARB(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x70030)
|
||||
#define DSPARB_CSTART_MASK (0x7f << 7)
|
||||
#define DSPARB_CSTART_SHIFT 7
|
||||
#define DSPARB_BSTART_MASK (0x7f)
|
||||
#define DSPARB_BSTART_SHIFT 0
|
||||
#define DSPARB_BEND_SHIFT 9 /* on 855 */
|
||||
#define DSPARB_AEND_SHIFT 0
|
||||
#define DSPARB_SPRITEA_SHIFT_VLV 0
|
||||
#define DSPARB_SPRITEA_MASK_VLV (0xff << 0)
|
||||
#define DSPARB_SPRITEB_SHIFT_VLV 8
|
||||
#define DSPARB_SPRITEB_MASK_VLV (0xff << 8)
|
||||
#define DSPARB_SPRITEC_SHIFT_VLV 16
|
||||
#define DSPARB_SPRITEC_MASK_VLV (0xff << 16)
|
||||
#define DSPARB_SPRITED_SHIFT_VLV 24
|
||||
#define DSPARB_SPRITED_MASK_VLV (0xff << 24)
|
||||
#define DSPARB2 _MMIO(VLV_DISPLAY_BASE + 0x70060) /* vlv/chv */
|
||||
#define DSPARB_SPRITEA_HI_SHIFT_VLV 0
|
||||
#define DSPARB_SPRITEA_HI_MASK_VLV (0x1 << 0)
|
||||
#define DSPARB_SPRITEB_HI_SHIFT_VLV 4
|
||||
#define DSPARB_SPRITEB_HI_MASK_VLV (0x1 << 4)
|
||||
#define DSPARB_SPRITEC_HI_SHIFT_VLV 8
|
||||
#define DSPARB_SPRITEC_HI_MASK_VLV (0x1 << 8)
|
||||
#define DSPARB_SPRITED_HI_SHIFT_VLV 12
|
||||
#define DSPARB_SPRITED_HI_MASK_VLV (0x1 << 12)
|
||||
#define DSPARB_SPRITEE_HI_SHIFT_VLV 16
|
||||
#define DSPARB_SPRITEE_HI_MASK_VLV (0x1 << 16)
|
||||
#define DSPARB_SPRITEF_HI_SHIFT_VLV 20
|
||||
#define DSPARB_SPRITEF_HI_MASK_VLV (0x1 << 20)
|
||||
#define DSPARB3 _MMIO(VLV_DISPLAY_BASE + 0x7006c) /* chv */
|
||||
#define DSPARB_SPRITEE_SHIFT_VLV 0
|
||||
#define DSPARB_SPRITEE_MASK_VLV (0xff << 0)
|
||||
#define DSPARB_SPRITEF_SHIFT_VLV 8
|
||||
#define DSPARB_SPRITEF_MASK_VLV (0xff << 8)
|
||||
|
||||
/* pnv/gen4/g4x/vlv/chv */
|
||||
#define DSPFW1(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x70034)
|
||||
#define DSPFW_SR_SHIFT 23
|
||||
#define DSPFW_SR_MASK (0x1ff << 23)
|
||||
#define DSPFW_CURSORB_SHIFT 16
|
||||
#define DSPFW_CURSORB_MASK (0x3f << 16)
|
||||
#define DSPFW_PLANEB_SHIFT 8
|
||||
#define DSPFW_PLANEB_MASK (0x7f << 8)
|
||||
#define DSPFW_PLANEB_MASK_VLV (0xff << 8) /* vlv/chv */
|
||||
#define DSPFW_PLANEA_SHIFT 0
|
||||
#define DSPFW_PLANEA_MASK (0x7f << 0)
|
||||
#define DSPFW_PLANEA_MASK_VLV (0xff << 0) /* vlv/chv */
|
||||
#define DSPFW2(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x70038)
|
||||
#define DSPFW_FBC_SR_EN (1 << 31) /* g4x */
|
||||
#define DSPFW_FBC_SR_SHIFT 28
|
||||
#define DSPFW_FBC_SR_MASK (0x7 << 28) /* g4x */
|
||||
#define DSPFW_FBC_HPLL_SR_SHIFT 24
|
||||
#define DSPFW_FBC_HPLL_SR_MASK (0xf << 24) /* g4x */
|
||||
#define DSPFW_SPRITEB_SHIFT (16)
|
||||
#define DSPFW_SPRITEB_MASK (0x7f << 16) /* g4x */
|
||||
#define DSPFW_SPRITEB_MASK_VLV (0xff << 16) /* vlv/chv */
|
||||
#define DSPFW_CURSORA_SHIFT 8
|
||||
#define DSPFW_CURSORA_MASK (0x3f << 8)
|
||||
#define DSPFW_PLANEC_OLD_SHIFT 0
|
||||
#define DSPFW_PLANEC_OLD_MASK (0x7f << 0) /* pre-gen4 sprite C */
|
||||
#define DSPFW_SPRITEA_SHIFT 0
|
||||
#define DSPFW_SPRITEA_MASK (0x7f << 0) /* g4x */
|
||||
#define DSPFW_SPRITEA_MASK_VLV (0xff << 0) /* vlv/chv */
|
||||
#define DSPFW3(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x7003c)
|
||||
#define DSPFW_HPLL_SR_EN (1 << 31)
|
||||
#define PINEVIEW_SELF_REFRESH_EN (1 << 30)
|
||||
#define DSPFW_CURSOR_SR_SHIFT 24
|
||||
#define DSPFW_CURSOR_SR_MASK (0x3f << 24)
|
||||
#define DSPFW_HPLL_CURSOR_SHIFT 16
|
||||
#define DSPFW_HPLL_CURSOR_MASK (0x3f << 16)
|
||||
#define DSPFW_HPLL_SR_SHIFT 0
|
||||
#define DSPFW_HPLL_SR_MASK (0x1ff << 0)
|
||||
|
||||
/* vlv/chv */
|
||||
#define DSPFW4 _MMIO(VLV_DISPLAY_BASE + 0x70070)
|
||||
#define DSPFW_SPRITEB_WM1_SHIFT 16
|
||||
#define DSPFW_SPRITEB_WM1_MASK (0xff << 16)
|
||||
#define DSPFW_CURSORA_WM1_SHIFT 8
|
||||
#define DSPFW_CURSORA_WM1_MASK (0x3f << 8)
|
||||
#define DSPFW_SPRITEA_WM1_SHIFT 0
|
||||
#define DSPFW_SPRITEA_WM1_MASK (0xff << 0)
|
||||
#define DSPFW5 _MMIO(VLV_DISPLAY_BASE + 0x70074)
|
||||
#define DSPFW_PLANEB_WM1_SHIFT 24
|
||||
#define DSPFW_PLANEB_WM1_MASK (0xff << 24)
|
||||
#define DSPFW_PLANEA_WM1_SHIFT 16
|
||||
#define DSPFW_PLANEA_WM1_MASK (0xff << 16)
|
||||
#define DSPFW_CURSORB_WM1_SHIFT 8
|
||||
#define DSPFW_CURSORB_WM1_MASK (0x3f << 8)
|
||||
#define DSPFW_CURSOR_SR_WM1_SHIFT 0
|
||||
#define DSPFW_CURSOR_SR_WM1_MASK (0x3f << 0)
|
||||
#define DSPFW6 _MMIO(VLV_DISPLAY_BASE + 0x70078)
|
||||
#define DSPFW_SR_WM1_SHIFT 0
|
||||
#define DSPFW_SR_WM1_MASK (0x1ff << 0)
|
||||
#define DSPFW7 _MMIO(VLV_DISPLAY_BASE + 0x7007c)
|
||||
#define DSPFW7_CHV _MMIO(VLV_DISPLAY_BASE + 0x700b4) /* wtf #1? */
|
||||
#define DSPFW_SPRITED_WM1_SHIFT 24
|
||||
#define DSPFW_SPRITED_WM1_MASK (0xff << 24)
|
||||
#define DSPFW_SPRITED_SHIFT 16
|
||||
#define DSPFW_SPRITED_MASK_VLV (0xff << 16)
|
||||
#define DSPFW_SPRITEC_WM1_SHIFT 8
|
||||
#define DSPFW_SPRITEC_WM1_MASK (0xff << 8)
|
||||
#define DSPFW_SPRITEC_SHIFT 0
|
||||
#define DSPFW_SPRITEC_MASK_VLV (0xff << 0)
|
||||
#define DSPFW8_CHV _MMIO(VLV_DISPLAY_BASE + 0x700b8)
|
||||
#define DSPFW_SPRITEF_WM1_SHIFT 24
|
||||
#define DSPFW_SPRITEF_WM1_MASK (0xff << 24)
|
||||
#define DSPFW_SPRITEF_SHIFT 16
|
||||
#define DSPFW_SPRITEF_MASK_VLV (0xff << 16)
|
||||
#define DSPFW_SPRITEE_WM1_SHIFT 8
|
||||
#define DSPFW_SPRITEE_WM1_MASK (0xff << 8)
|
||||
#define DSPFW_SPRITEE_SHIFT 0
|
||||
#define DSPFW_SPRITEE_MASK_VLV (0xff << 0)
|
||||
#define DSPFW9_CHV _MMIO(VLV_DISPLAY_BASE + 0x7007c) /* wtf #2? */
|
||||
#define DSPFW_PLANEC_WM1_SHIFT 24
|
||||
#define DSPFW_PLANEC_WM1_MASK (0xff << 24)
|
||||
#define DSPFW_PLANEC_SHIFT 16
|
||||
#define DSPFW_PLANEC_MASK_VLV (0xff << 16)
|
||||
#define DSPFW_CURSORC_WM1_SHIFT 8
|
||||
#define DSPFW_CURSORC_WM1_MASK (0x3f << 16)
|
||||
#define DSPFW_CURSORC_SHIFT 0
|
||||
#define DSPFW_CURSORC_MASK (0x3f << 0)
|
||||
|
||||
/* vlv/chv high order bits */
|
||||
#define DSPHOWM _MMIO(VLV_DISPLAY_BASE + 0x70064)
|
||||
#define DSPFW_SR_HI_SHIFT 24
|
||||
#define DSPFW_SR_HI_MASK (3 << 24) /* 2 bits for chv, 1 for vlv */
|
||||
#define DSPFW_SPRITEF_HI_SHIFT 23
|
||||
#define DSPFW_SPRITEF_HI_MASK (1 << 23)
|
||||
#define DSPFW_SPRITEE_HI_SHIFT 22
|
||||
#define DSPFW_SPRITEE_HI_MASK (1 << 22)
|
||||
#define DSPFW_PLANEC_HI_SHIFT 21
|
||||
#define DSPFW_PLANEC_HI_MASK (1 << 21)
|
||||
#define DSPFW_SPRITED_HI_SHIFT 20
|
||||
#define DSPFW_SPRITED_HI_MASK (1 << 20)
|
||||
#define DSPFW_SPRITEC_HI_SHIFT 16
|
||||
#define DSPFW_SPRITEC_HI_MASK (1 << 16)
|
||||
#define DSPFW_PLANEB_HI_SHIFT 12
|
||||
#define DSPFW_PLANEB_HI_MASK (1 << 12)
|
||||
#define DSPFW_SPRITEB_HI_SHIFT 8
|
||||
#define DSPFW_SPRITEB_HI_MASK (1 << 8)
|
||||
#define DSPFW_SPRITEA_HI_SHIFT 4
|
||||
#define DSPFW_SPRITEA_HI_MASK (1 << 4)
|
||||
#define DSPFW_PLANEA_HI_SHIFT 0
|
||||
#define DSPFW_PLANEA_HI_MASK (1 << 0)
|
||||
#define DSPHOWM1 _MMIO(VLV_DISPLAY_BASE + 0x70068)
|
||||
#define DSPFW_SR_WM1_HI_SHIFT 24
|
||||
#define DSPFW_SR_WM1_HI_MASK (3 << 24) /* 2 bits for chv, 1 for vlv */
|
||||
#define DSPFW_SPRITEF_WM1_HI_SHIFT 23
|
||||
#define DSPFW_SPRITEF_WM1_HI_MASK (1 << 23)
|
||||
#define DSPFW_SPRITEE_WM1_HI_SHIFT 22
|
||||
#define DSPFW_SPRITEE_WM1_HI_MASK (1 << 22)
|
||||
#define DSPFW_PLANEC_WM1_HI_SHIFT 21
|
||||
#define DSPFW_PLANEC_WM1_HI_MASK (1 << 21)
|
||||
#define DSPFW_SPRITED_WM1_HI_SHIFT 20
|
||||
#define DSPFW_SPRITED_WM1_HI_MASK (1 << 20)
|
||||
#define DSPFW_SPRITEC_WM1_HI_SHIFT 16
|
||||
#define DSPFW_SPRITEC_WM1_HI_MASK (1 << 16)
|
||||
#define DSPFW_PLANEB_WM1_HI_SHIFT 12
|
||||
#define DSPFW_PLANEB_WM1_HI_MASK (1 << 12)
|
||||
#define DSPFW_SPRITEB_WM1_HI_SHIFT 8
|
||||
#define DSPFW_SPRITEB_WM1_HI_MASK (1 << 8)
|
||||
#define DSPFW_SPRITEA_WM1_HI_SHIFT 4
|
||||
#define DSPFW_SPRITEA_WM1_HI_MASK (1 << 4)
|
||||
#define DSPFW_PLANEA_WM1_HI_SHIFT 0
|
||||
#define DSPFW_PLANEA_WM1_HI_MASK (1 << 0)
|
||||
|
||||
/* drain latency register values*/
|
||||
#define VLV_DDL(pipe) _MMIO(VLV_DISPLAY_BASE + 0x70050 + 4 * (pipe))
|
||||
#define DDL_CURSOR_SHIFT 24
|
||||
#define DDL_SPRITE_SHIFT(sprite) (8 + 8 * (sprite))
|
||||
#define DDL_PLANE_SHIFT 0
|
||||
#define DDL_PRECISION_HIGH (1 << 7)
|
||||
#define DDL_PRECISION_LOW (0 << 7)
|
||||
#define DRAIN_LATENCY_MASK 0x7f
|
||||
|
||||
/* FIFO watermark sizes etc */
|
||||
#define G4X_FIFO_LINE_SIZE 64
|
||||
#define I915_FIFO_LINE_SIZE 64
|
||||
#define I830_FIFO_LINE_SIZE 32
|
||||
|
||||
#define VALLEYVIEW_FIFO_SIZE 255
|
||||
#define G4X_FIFO_SIZE 127
|
||||
#define I965_FIFO_SIZE 512
|
||||
#define I945_FIFO_SIZE 127
|
||||
#define I915_FIFO_SIZE 95
|
||||
#define I855GM_FIFO_SIZE 127 /* In cachelines */
|
||||
#define I830_FIFO_SIZE 95
|
||||
|
||||
#define VALLEYVIEW_MAX_WM 0xff
|
||||
#define G4X_MAX_WM 0x3f
|
||||
#define I915_MAX_WM 0x3f
|
||||
|
||||
#define PINEVIEW_DISPLAY_FIFO 512 /* in 64byte unit */
|
||||
#define PINEVIEW_FIFO_LINE_SIZE 64
|
||||
#define PINEVIEW_MAX_WM 0x1ff
|
||||
#define PINEVIEW_DFT_WM 0x3f
|
||||
#define PINEVIEW_DFT_HPLLOFF_WM 0
|
||||
#define PINEVIEW_GUARD_WM 10
|
||||
#define PINEVIEW_CURSOR_FIFO 64
|
||||
#define PINEVIEW_CURSOR_MAX_WM 0x3f
|
||||
#define PINEVIEW_CURSOR_DFT_WM 0
|
||||
#define PINEVIEW_CURSOR_GUARD_WM 5
|
||||
|
||||
#define VALLEYVIEW_CURSOR_MAX_WM 64
|
||||
#define I965_CURSOR_FIFO 64
|
||||
#define I965_CURSOR_MAX_WM 32
|
||||
#define I965_CURSOR_DFT_WM 8
|
||||
|
||||
/* define the Watermark register on Ironlake */
|
||||
#define _WM0_PIPEA_ILK 0x45100
|
||||
#define _WM0_PIPEB_ILK 0x45104
|
||||
#define _WM0_PIPEC_IVB 0x45200
|
||||
#define WM0_PIPE_ILK(pipe) _MMIO_BASE_PIPE3(0, (pipe), _WM0_PIPEA_ILK, \
|
||||
_WM0_PIPEB_ILK, _WM0_PIPEC_IVB)
|
||||
#define WM0_PIPE_PRIMARY_MASK REG_GENMASK(31, 16)
|
||||
#define WM0_PIPE_SPRITE_MASK REG_GENMASK(15, 8)
|
||||
#define WM0_PIPE_CURSOR_MASK REG_GENMASK(7, 0)
|
||||
#define WM0_PIPE_PRIMARY(x) REG_FIELD_PREP(WM0_PIPE_PRIMARY_MASK, (x))
|
||||
#define WM0_PIPE_SPRITE(x) REG_FIELD_PREP(WM0_PIPE_SPRITE_MASK, (x))
|
||||
#define WM0_PIPE_CURSOR(x) REG_FIELD_PREP(WM0_PIPE_CURSOR_MASK, (x))
|
||||
#define WM1_LP_ILK _MMIO(0x45108)
|
||||
#define WM2_LP_ILK _MMIO(0x4510c)
|
||||
#define WM3_LP_ILK _MMIO(0x45110)
|
||||
#define WM_LP_ENABLE REG_BIT(31)
|
||||
#define WM_LP_LATENCY_MASK REG_GENMASK(30, 24)
|
||||
#define WM_LP_FBC_MASK_BDW REG_GENMASK(23, 19)
|
||||
#define WM_LP_FBC_MASK_ILK REG_GENMASK(23, 20)
|
||||
#define WM_LP_PRIMARY_MASK REG_GENMASK(18, 8)
|
||||
#define WM_LP_CURSOR_MASK REG_GENMASK(7, 0)
|
||||
#define WM_LP_LATENCY(x) REG_FIELD_PREP(WM_LP_LATENCY_MASK, (x))
|
||||
#define WM_LP_FBC_BDW(x) REG_FIELD_PREP(WM_LP_FBC_MASK_BDW, (x))
|
||||
#define WM_LP_FBC_ILK(x) REG_FIELD_PREP(WM_LP_FBC_MASK_ILK, (x))
|
||||
#define WM_LP_PRIMARY(x) REG_FIELD_PREP(WM_LP_PRIMARY_MASK, (x))
|
||||
#define WM_LP_CURSOR(x) REG_FIELD_PREP(WM_LP_CURSOR_MASK, (x))
|
||||
#define WM1S_LP_ILK _MMIO(0x45120)
|
||||
#define WM2S_LP_IVB _MMIO(0x45124)
|
||||
#define WM3S_LP_IVB _MMIO(0x45128)
|
||||
#define WM_LP_SPRITE_ENABLE REG_BIT(31) /* ilk/snb WM1S only */
|
||||
#define WM_LP_SPRITE_MASK REG_GENMASK(10, 0)
|
||||
#define WM_LP_SPRITE(x) REG_FIELD_PREP(WM_LP_SPRITE_MASK, (x))
|
||||
|
||||
#define WM_MISC _MMIO(0x45260)
|
||||
#define WM_MISC_DATA_PARTITION_5_6 (1 << 0)
|
||||
|
||||
#define WM_DBG _MMIO(0x45280)
|
||||
#define WM_DBG_DISALLOW_MULTIPLE_LP (1 << 0)
|
||||
#define WM_DBG_DISALLOW_MAXFIFO (1 << 1)
|
||||
#define WM_DBG_DISALLOW_SPRITE (1 << 2)
|
||||
|
||||
#endif /* __I9XX_WM_REGS_H__ */
|
@ -31,6 +31,7 @@
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "icl_dsi.h"
|
||||
#include "icl_dsi_regs.h"
|
||||
@ -1602,7 +1603,9 @@ static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
|
||||
|
||||
/* FIXME: split only when necessary */
|
||||
if (crtc_state->dsc.slice_count > 1)
|
||||
crtc_state->dsc.dsc_split = true;
|
||||
crtc_state->dsc.num_streams = 2;
|
||||
else
|
||||
crtc_state->dsc.num_streams = 1;
|
||||
|
||||
/* FIXME: initialize from VBT */
|
||||
vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST;
|
||||
|
@ -9,8 +9,9 @@
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_acpi.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_types.h"
|
||||
|
||||
#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <drm/drm_gem.h>
|
||||
#include <drm/drm_gem_atomic_helper.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_config.h"
|
||||
#include "i9xx_plane_regs.h"
|
||||
#include "intel_atomic_plane.h"
|
||||
@ -207,17 +208,6 @@ unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
|
||||
fb->format->cpp[color_plane];
|
||||
}
|
||||
|
||||
static bool
|
||||
use_min_ddb(const struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane *plane)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(plane->base.dev);
|
||||
|
||||
return DISPLAY_VER(i915) >= 13 &&
|
||||
crtc_state->uapi.async_flip &&
|
||||
plane->async_flip;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
intel_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state,
|
||||
@ -225,8 +215,8 @@ intel_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
|
||||
{
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
int width, height;
|
||||
unsigned int rel_data_rate;
|
||||
int width, height;
|
||||
|
||||
if (plane->id == PLANE_CURSOR)
|
||||
return 0;
|
||||
@ -234,14 +224,6 @@ intel_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
|
||||
if (!plane_state->uapi.visible)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We calculate extra ddb based on ratio plane rate/total data rate
|
||||
* in case, in some cases we should not allocate extra ddb for the plane,
|
||||
* so do not count its data rate, if this is the case.
|
||||
*/
|
||||
if (use_min_ddb(crtc_state, plane))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Src coordinates are already rotated by 270 degrees for
|
||||
* the 90/270 degree plane rotation cases (to match the
|
||||
@ -256,7 +238,11 @@ intel_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
|
||||
height /= 2;
|
||||
}
|
||||
|
||||
rel_data_rate = width * height * fb->format->cpp[color_plane];
|
||||
rel_data_rate =
|
||||
skl_plane_relative_data_rate(crtc_state, plane, width, height,
|
||||
fb->format->cpp[color_plane]);
|
||||
if (!rel_data_rate)
|
||||
return 0;
|
||||
|
||||
return intel_adjusted_rate(&plane_state->uapi.src,
|
||||
&plane_state->uapi.dst,
|
||||
|
@ -681,12 +681,11 @@ static void ibx_audio_codec_enable(struct intel_encoder *encoder,
|
||||
|
||||
void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
enum transcoder trans = crtc_state->cpu_transcoder;
|
||||
|
||||
if (HAS_DP20(i915))
|
||||
intel_de_rmw(i915, AUD_DP_2DOT0_CTRL(trans), AUD_ENABLE_SDP_SPLIT,
|
||||
if (HAS_DP20(display))
|
||||
intel_de_rmw(display, AUD_DP_2DOT0_CTRL(trans), AUD_ENABLE_SDP_SPLIT,
|
||||
crtc_state->sdp_split_enable ? AUD_ENABLE_SDP_SPLIT : 0);
|
||||
}
|
||||
|
||||
@ -981,6 +980,53 @@ static void glk_force_audio_cdclk(struct drm_i915_private *i915,
|
||||
drm_modeset_acquire_fini(&ctx);
|
||||
}
|
||||
|
||||
int intel_audio_min_cdclk(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
int min_cdclk = 0;
|
||||
|
||||
if (!crtc_state->has_audio)
|
||||
return 0;
|
||||
|
||||
/* BSpec says "Do not use DisplayPort with CDCLK less than 432 MHz,
|
||||
* audio enabled, port width x4, and link rate HBR2 (5.4 GHz), or else
|
||||
* there may be audio corruption or screen corruption." This cdclk
|
||||
* restriction for GLK is 316.8 MHz.
|
||||
*/
|
||||
if (intel_crtc_has_dp_encoder(crtc_state) &&
|
||||
crtc_state->port_clock >= 540000 &&
|
||||
crtc_state->lane_count == 4) {
|
||||
if (DISPLAY_VER(display) == 10) {
|
||||
/* Display WA #1145: glk */
|
||||
min_cdclk = max(min_cdclk, 316800);
|
||||
} else if (DISPLAY_VER(display) == 9 || IS_BROADWELL(dev_priv)) {
|
||||
/* Display WA #1144: skl,bxt */
|
||||
min_cdclk = max(min_cdclk, 432000);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* According to BSpec, "The CD clock frequency must be at least twice
|
||||
* the frequency of the Azalia BCLK." and BCLK is 96 MHz by default.
|
||||
*/
|
||||
if (DISPLAY_VER(display) >= 9)
|
||||
min_cdclk = max(min_cdclk, 2 * 96000);
|
||||
|
||||
/*
|
||||
* "For DP audio configuration, cdclk frequency shall be set to
|
||||
* meet the following requirements:
|
||||
* DP Link Frequency(MHz) | Cdclk frequency(MHz)
|
||||
* 270 | 320 or higher
|
||||
* 162 | 200 or higher"
|
||||
*/
|
||||
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
|
||||
intel_crtc_has_dp_encoder(crtc_state))
|
||||
min_cdclk = max(min_cdclk, crtc_state->port_clock);
|
||||
|
||||
return min_cdclk;
|
||||
}
|
||||
|
||||
static unsigned long i915_audio_component_get_power(struct device *kdev)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(kdev);
|
||||
|
@ -27,6 +27,7 @@ void intel_audio_codec_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state);
|
||||
void intel_audio_cdclk_change_pre(struct drm_i915_private *dev_priv);
|
||||
void intel_audio_cdclk_change_post(struct drm_i915_private *dev_priv);
|
||||
int intel_audio_min_cdclk(const struct intel_crtc_state *crtc_state);
|
||||
void intel_audio_init(struct drm_i915_private *dev_priv);
|
||||
void intel_audio_register(struct drm_i915_private *i915);
|
||||
void intel_audio_deinit(struct drm_i915_private *dev_priv);
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <acpi/video.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_backlight.h"
|
||||
#include "intel_backlight_regs.h"
|
||||
|
@ -1402,12 +1402,21 @@ parse_power_conservation_features(struct intel_display *display,
|
||||
panel_type);
|
||||
}
|
||||
|
||||
static void vbt_edp_to_pps_delays(struct intel_pps_delays *pps,
|
||||
const struct edp_power_seq *edp_pps)
|
||||
{
|
||||
pps->power_up = edp_pps->t1_t3;
|
||||
pps->backlight_on = edp_pps->t8;
|
||||
pps->backlight_off = edp_pps->t9;
|
||||
pps->power_down = edp_pps->t10;
|
||||
pps->power_cycle = edp_pps->t11_t12;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_edp(struct intel_display *display,
|
||||
struct intel_panel *panel)
|
||||
{
|
||||
const struct bdb_edp *edp;
|
||||
const struct edp_power_seq *edp_pps;
|
||||
const struct edp_fast_link_params *edp_link_params;
|
||||
int panel_type = panel->vbt.panel_type;
|
||||
|
||||
@ -1428,10 +1437,10 @@ parse_edp(struct intel_display *display,
|
||||
}
|
||||
|
||||
/* Get the eDP sequencing and link info */
|
||||
edp_pps = &edp->power_seqs[panel_type];
|
||||
edp_link_params = &edp->fast_link_params[panel_type];
|
||||
|
||||
panel->vbt.edp.pps = *edp_pps;
|
||||
vbt_edp_to_pps_delays(&panel->vbt.edp.pps,
|
||||
&edp->power_seqs[panel_type]);
|
||||
|
||||
if (display->vbt.version >= 224) {
|
||||
panel->vbt.edp.rate =
|
||||
|
@ -50,14 +50,6 @@ enum intel_backlight_type {
|
||||
INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE,
|
||||
};
|
||||
|
||||
struct edp_power_seq {
|
||||
u16 t1_t3;
|
||||
u16 t8;
|
||||
u16 t9;
|
||||
u16 t10;
|
||||
u16 t11_t12;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* MIPI Sequence Block definitions
|
||||
*
|
||||
|
@ -1256,7 +1256,7 @@ int intel_bw_min_cdclk(struct drm_i915_private *i915,
|
||||
min_cdclk = intel_bw_dbuf_min_cdclk(i915, bw_state);
|
||||
|
||||
for_each_pipe(i915, pipe)
|
||||
min_cdclk = max(bw_state->min_cdclk[pipe], min_cdclk);
|
||||
min_cdclk = max(min_cdclk, bw_state->min_cdclk[pipe]);
|
||||
|
||||
return min_cdclk;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "soc/intel_dram.h"
|
||||
|
||||
#include "hsw_ips.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_atomic_plane.h"
|
||||
@ -37,7 +38,6 @@
|
||||
#include "intel_cdclk.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_mchbar_regs.h"
|
||||
#include "intel_pci_config.h"
|
||||
@ -46,6 +46,7 @@
|
||||
#include "intel_vdsc.h"
|
||||
#include "skl_watermark.h"
|
||||
#include "skl_watermark_regs.h"
|
||||
#include "vlv_dsi.h"
|
||||
#include "vlv_sideband.h"
|
||||
|
||||
/**
|
||||
@ -2761,23 +2762,34 @@ intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)
|
||||
"Post changing CDCLK to");
|
||||
}
|
||||
|
||||
/* pixels per CDCLK */
|
||||
static int intel_cdclk_ppc(struct intel_display *display, bool double_wide)
|
||||
{
|
||||
return DISPLAY_VER(display) >= 10 || double_wide ? 2 : 1;
|
||||
}
|
||||
|
||||
/* max pixel rate as % of CDCLK (not accounting for PPC) */
|
||||
static int intel_cdclk_guardband(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
if (DISPLAY_VER(display) >= 9 ||
|
||||
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
|
||||
return 100;
|
||||
else if (IS_CHERRYVIEW(dev_priv))
|
||||
return 95;
|
||||
else
|
||||
return 90;
|
||||
}
|
||||
|
||||
static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
int ppc = intel_cdclk_ppc(display, crtc_state->double_wide);
|
||||
int guardband = intel_cdclk_guardband(display);
|
||||
int pixel_rate = crtc_state->pixel_rate;
|
||||
|
||||
if (DISPLAY_VER(display) >= 10)
|
||||
return DIV_ROUND_UP(pixel_rate, 2);
|
||||
else if (DISPLAY_VER(display) == 9 ||
|
||||
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
|
||||
return pixel_rate;
|
||||
else if (IS_CHERRYVIEW(dev_priv))
|
||||
return DIV_ROUND_UP(pixel_rate * 100, 95);
|
||||
else if (crtc_state->double_wide)
|
||||
return DIV_ROUND_UP(pixel_rate * 100, 90 * 2);
|
||||
else
|
||||
return DIV_ROUND_UP(pixel_rate * 100, 90);
|
||||
return DIV_ROUND_UP(pixel_rate * 100, guardband * ppc);
|
||||
}
|
||||
|
||||
static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state)
|
||||
@ -2788,127 +2800,24 @@ static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state)
|
||||
int min_cdclk = 0;
|
||||
|
||||
for_each_intel_plane_on_crtc(display->drm, crtc, plane)
|
||||
min_cdclk = max(crtc_state->min_cdclk[plane->id], min_cdclk);
|
||||
|
||||
return min_cdclk;
|
||||
}
|
||||
|
||||
static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct intel_display *display = to_intel_display(crtc);
|
||||
int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
|
||||
int min_cdclk = 0;
|
||||
|
||||
/*
|
||||
* When we decide to use only one VDSC engine, since
|
||||
* each VDSC operates with 1 ppc throughput, pixel clock
|
||||
* cannot be higher than the VDSC clock (cdclk)
|
||||
* If there 2 VDSC engines, then pixel clock can't be higher than
|
||||
* VDSC clock(cdclk) * 2 and so on.
|
||||
*/
|
||||
min_cdclk = max_t(int, min_cdclk,
|
||||
DIV_ROUND_UP(crtc_state->pixel_rate, num_vdsc_instances));
|
||||
|
||||
if (crtc_state->joiner_pipes) {
|
||||
int pixel_clock = intel_dp_mode_to_fec_clock(crtc_state->hw.adjusted_mode.clock);
|
||||
|
||||
/*
|
||||
* According to Bigjoiner bw check:
|
||||
* compressed_bpp <= PPC * CDCLK * Big joiner Interface bits / Pixel clock
|
||||
*
|
||||
* We have already computed compressed_bpp, so now compute the min CDCLK that
|
||||
* is required to support this compressed_bpp.
|
||||
*
|
||||
* => CDCLK >= compressed_bpp * Pixel clock / (PPC * Bigjoiner Interface bits)
|
||||
*
|
||||
* Since PPC = 2 with bigjoiner
|
||||
* => CDCLK >= compressed_bpp * Pixel clock / 2 * Bigjoiner Interface bits
|
||||
*/
|
||||
int bigjoiner_interface_bits = DISPLAY_VER(display) >= 14 ? 36 : 24;
|
||||
int min_cdclk_bj =
|
||||
(fxp_q4_to_int_roundup(crtc_state->dsc.compressed_bpp_x16) *
|
||||
pixel_clock) / (2 * bigjoiner_interface_bits);
|
||||
|
||||
min_cdclk = max(min_cdclk, min_cdclk_bj);
|
||||
}
|
||||
min_cdclk = max(min_cdclk, crtc_state->min_cdclk[plane->id]);
|
||||
|
||||
return min_cdclk;
|
||||
}
|
||||
|
||||
int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
int min_cdclk;
|
||||
|
||||
if (!crtc_state->hw.enable)
|
||||
return 0;
|
||||
|
||||
min_cdclk = intel_pixel_rate_to_cdclk(crtc_state);
|
||||
|
||||
/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
|
||||
if (IS_BROADWELL(dev_priv) && hsw_crtc_state_ips_capable(crtc_state))
|
||||
min_cdclk = DIV_ROUND_UP(min_cdclk * 100, 95);
|
||||
|
||||
/* BSpec says "Do not use DisplayPort with CDCLK less than 432 MHz,
|
||||
* audio enabled, port width x4, and link rate HBR2 (5.4 GHz), or else
|
||||
* there may be audio corruption or screen corruption." This cdclk
|
||||
* restriction for GLK is 316.8 MHz.
|
||||
*/
|
||||
if (intel_crtc_has_dp_encoder(crtc_state) &&
|
||||
crtc_state->has_audio &&
|
||||
crtc_state->port_clock >= 540000 &&
|
||||
crtc_state->lane_count == 4) {
|
||||
if (DISPLAY_VER(display) == 10) {
|
||||
/* Display WA #1145: glk */
|
||||
min_cdclk = max(316800, min_cdclk);
|
||||
} else if (DISPLAY_VER(display) == 9 || IS_BROADWELL(dev_priv)) {
|
||||
/* Display WA #1144: skl,bxt */
|
||||
min_cdclk = max(432000, min_cdclk);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* According to BSpec, "The CD clock frequency must be at least twice
|
||||
* the frequency of the Azalia BCLK." and BCLK is 96 MHz by default.
|
||||
*/
|
||||
if (crtc_state->has_audio && DISPLAY_VER(display) >= 9)
|
||||
min_cdclk = max(2 * 96000, min_cdclk);
|
||||
|
||||
/*
|
||||
* "For DP audio configuration, cdclk frequency shall be set to
|
||||
* meet the following requirements:
|
||||
* DP Link Frequency(MHz) | Cdclk frequency(MHz)
|
||||
* 270 | 320 or higher
|
||||
* 162 | 200 or higher"
|
||||
*/
|
||||
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
|
||||
intel_crtc_has_dp_encoder(crtc_state) && crtc_state->has_audio)
|
||||
min_cdclk = max(crtc_state->port_clock, min_cdclk);
|
||||
|
||||
/*
|
||||
* On Valleyview some DSI panels lose (v|h)sync when the clock is lower
|
||||
* than 320000KHz.
|
||||
*/
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) &&
|
||||
IS_VALLEYVIEW(dev_priv))
|
||||
min_cdclk = max(320000, min_cdclk);
|
||||
|
||||
/*
|
||||
* On Geminilake once the CDCLK gets as low as 79200
|
||||
* picture gets unstable, despite that values are
|
||||
* correct for DSI PLL and DE PLL.
|
||||
*/
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) &&
|
||||
IS_GEMINILAKE(dev_priv))
|
||||
min_cdclk = max(158400, min_cdclk);
|
||||
|
||||
/* Account for additional needs from the planes */
|
||||
min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk);
|
||||
|
||||
if (crtc_state->dsc.compression_enable)
|
||||
min_cdclk = max(min_cdclk, intel_vdsc_min_cdclk(crtc_state));
|
||||
min_cdclk = max(min_cdclk, hsw_ips_min_cdclk(crtc_state));
|
||||
min_cdclk = max(min_cdclk, intel_audio_min_cdclk(crtc_state));
|
||||
min_cdclk = max(min_cdclk, vlv_dsi_min_cdclk(crtc_state));
|
||||
min_cdclk = max(min_cdclk, intel_planes_min_cdclk(crtc_state));
|
||||
min_cdclk = max(min_cdclk, intel_vdsc_min_cdclk(crtc_state));
|
||||
|
||||
return min_cdclk;
|
||||
}
|
||||
@ -2960,7 +2869,7 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state)
|
||||
min_cdclk = max(cdclk_state->force_min_cdclk,
|
||||
cdclk_state->bw_min_cdclk);
|
||||
for_each_pipe(display, pipe)
|
||||
min_cdclk = max(cdclk_state->min_cdclk[pipe], min_cdclk);
|
||||
min_cdclk = max(min_cdclk, cdclk_state->min_cdclk[pipe]);
|
||||
|
||||
/*
|
||||
* Avoid glk_force_audio_cdclk() causing excessive screen
|
||||
@ -2972,7 +2881,7 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state)
|
||||
*/
|
||||
if (IS_GEMINILAKE(dev_priv) && cdclk_state->active_pipes &&
|
||||
!is_power_of_2(cdclk_state->active_pipes))
|
||||
min_cdclk = max(2 * 96000, min_cdclk);
|
||||
min_cdclk = max(min_cdclk, 2 * 96000);
|
||||
|
||||
if (min_cdclk > display->cdclk.max_cdclk_freq) {
|
||||
drm_dbg_kms(display->drm,
|
||||
@ -3028,8 +2937,8 @@ static int bxt_compute_min_voltage_level(struct intel_atomic_state *state)
|
||||
|
||||
min_voltage_level = 0;
|
||||
for_each_pipe(display, pipe)
|
||||
min_voltage_level = max(cdclk_state->min_voltage_level[pipe],
|
||||
min_voltage_level);
|
||||
min_voltage_level = max(min_voltage_level,
|
||||
cdclk_state->min_voltage_level[pipe]);
|
||||
|
||||
return min_voltage_level;
|
||||
}
|
||||
@ -3452,20 +3361,11 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
|
||||
|
||||
static int intel_compute_max_dotclk(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
int ppc = intel_cdclk_ppc(display, HAS_DOUBLE_WIDE(display));
|
||||
int guardband = intel_cdclk_guardband(display);
|
||||
int max_cdclk_freq = display->cdclk.max_cdclk_freq;
|
||||
|
||||
if (DISPLAY_VER(display) >= 10)
|
||||
return 2 * max_cdclk_freq;
|
||||
else if (DISPLAY_VER(display) == 9 ||
|
||||
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
|
||||
return max_cdclk_freq;
|
||||
else if (IS_CHERRYVIEW(dev_priv))
|
||||
return max_cdclk_freq*95/100;
|
||||
else if (DISPLAY_VER(display) < 4)
|
||||
return 2*max_cdclk_freq*90/100;
|
||||
else
|
||||
return max_cdclk_freq*90/100;
|
||||
return ppc * max_cdclk_freq * guardband / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,6 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i9xx_plane_regs.h"
|
||||
#include "intel_color.h"
|
||||
#include "intel_color_regs.h"
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Copyright © 2018 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_combo_phy.h"
|
||||
#include "intel_combo_phy_regs.h"
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "i915_reg.h"
|
||||
#include "intel_connector.h"
|
||||
#include "intel_crt.h"
|
||||
#include "intel_crt_regs.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_ddi.h"
|
||||
#include "intel_ddi_buf_trans.h"
|
||||
@ -55,18 +56,23 @@
|
||||
#include "intel_pch_refclk.h"
|
||||
|
||||
/* Here's the desired hotplug mode */
|
||||
#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \
|
||||
#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_ENABLE | \
|
||||
ADPA_CRT_HOTPLUG_PERIOD_128 | \
|
||||
ADPA_CRT_HOTPLUG_WARMUP_10MS | \
|
||||
ADPA_CRT_HOTPLUG_SAMPLE_4S | \
|
||||
ADPA_CRT_HOTPLUG_VOLTAGE_50 | \
|
||||
ADPA_CRT_HOTPLUG_VOLREF_325MV | \
|
||||
ADPA_CRT_HOTPLUG_ENABLE)
|
||||
ADPA_CRT_HOTPLUG_VOLREF_325MV)
|
||||
#define ADPA_HOTPLUG_MASK (ADPA_CRT_HOTPLUG_MONITOR_MASK | \
|
||||
ADPA_CRT_HOTPLUG_ENABLE | \
|
||||
ADPA_CRT_HOTPLUG_PERIOD_MASK | \
|
||||
ADPA_CRT_HOTPLUG_WARMUP_MASK | \
|
||||
ADPA_CRT_HOTPLUG_SAMPLE_MASK | \
|
||||
ADPA_CRT_HOTPLUG_VOLTAGE_MASK | \
|
||||
ADPA_CRT_HOTPLUG_VOLREF_MASK | \
|
||||
ADPA_CRT_HOTPLUG_FORCE_TRIGGER)
|
||||
|
||||
struct intel_crt {
|
||||
struct intel_encoder base;
|
||||
/* DPMS state is stored in the connector, which we need in the
|
||||
* encoder's enable/disable callbacks */
|
||||
struct intel_connector *connector;
|
||||
bool force_hotplug_required;
|
||||
i915_reg_t adpa_reg;
|
||||
};
|
||||
@ -91,9 +97,9 @@ bool intel_crt_port_enabled(struct intel_display *display,
|
||||
|
||||
/* asserts want to know the pipe even if the port is disabled */
|
||||
if (HAS_PCH_CPT(dev_priv))
|
||||
*pipe = (val & ADPA_PIPE_SEL_MASK_CPT) >> ADPA_PIPE_SEL_SHIFT_CPT;
|
||||
*pipe = REG_FIELD_GET(ADPA_PIPE_SEL_MASK_CPT, val);
|
||||
else
|
||||
*pipe = (val & ADPA_PIPE_SEL_MASK) >> ADPA_PIPE_SEL_SHIFT;
|
||||
*pipe = REG_FIELD_GET(ADPA_PIPE_SEL_MASK, val);
|
||||
|
||||
return val & ADPA_DAC_ENABLE;
|
||||
}
|
||||
@ -141,27 +147,27 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder)
|
||||
}
|
||||
|
||||
static void intel_crt_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
|
||||
crtc_state->output_types |= BIT(INTEL_OUTPUT_ANALOG);
|
||||
|
||||
pipe_config->hw.adjusted_mode.flags |= intel_crt_get_flags(encoder);
|
||||
crtc_state->hw.adjusted_mode.flags |= intel_crt_get_flags(encoder);
|
||||
|
||||
pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
|
||||
crtc_state->hw.adjusted_mode.crtc_clock = crtc_state->port_clock;
|
||||
}
|
||||
|
||||
static void hsw_crt_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
lpt_pch_get_config(pipe_config);
|
||||
lpt_pch_get_config(crtc_state);
|
||||
|
||||
hsw_ddi_get_config(encoder, pipe_config);
|
||||
hsw_ddi_get_config(encoder, crtc_state);
|
||||
|
||||
pipe_config->hw.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
|
||||
DRM_MODE_FLAG_NHSYNC |
|
||||
DRM_MODE_FLAG_PVSYNC |
|
||||
DRM_MODE_FLAG_NVSYNC);
|
||||
pipe_config->hw.adjusted_mode.flags |= intel_crt_get_flags(encoder);
|
||||
crtc_state->hw.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
|
||||
DRM_MODE_FLAG_NHSYNC |
|
||||
DRM_MODE_FLAG_PVSYNC |
|
||||
DRM_MODE_FLAG_NVSYNC);
|
||||
crtc_state->hw.adjusted_mode.flags |= intel_crt_get_flags(encoder);
|
||||
}
|
||||
|
||||
/* Note: The caller is required to filter out dpms modes not supported by the
|
||||
@ -244,7 +250,7 @@ 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 intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
|
||||
drm_WARN_ON(display->drm, !old_crtc_state->has_pch_encoder);
|
||||
@ -257,7 +263,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_display *display = to_intel_display(encoder);
|
||||
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
|
||||
@ -287,7 +293,7 @@ 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 intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
|
||||
drm_WARN_ON(display->drm, !crtc_state->has_pch_encoder);
|
||||
@ -300,7 +306,7 @@ 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 intel_display *display = to_intel_display(encoder);
|
||||
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;
|
||||
@ -319,7 +325,7 @@ 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 intel_display *display = to_intel_display(encoder);
|
||||
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;
|
||||
@ -355,8 +361,7 @@ 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);
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
int max_dotclk = display->cdclk.max_dotclk_freq;
|
||||
enum drm_mode_status status;
|
||||
int max_clock;
|
||||
@ -399,48 +404,48 @@ intel_crt_mode_valid(struct drm_connector *connector,
|
||||
}
|
||||
|
||||
static int intel_crt_compute_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct drm_display_mode *adjusted_mode =
|
||||
&pipe_config->hw.adjusted_mode;
|
||||
&crtc_state->hw.adjusted_mode;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
return -EINVAL;
|
||||
|
||||
pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
|
||||
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
|
||||
crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB;
|
||||
crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pch_crt_compute_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct drm_display_mode *adjusted_mode =
|
||||
&pipe_config->hw.adjusted_mode;
|
||||
&crtc_state->hw.adjusted_mode;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
return -EINVAL;
|
||||
|
||||
pipe_config->has_pch_encoder = true;
|
||||
if (!intel_fdi_compute_pipe_bpp(pipe_config))
|
||||
crtc_state->has_pch_encoder = true;
|
||||
if (!intel_fdi_compute_pipe_bpp(crtc_state))
|
||||
return -EINVAL;
|
||||
|
||||
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
|
||||
crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hsw_crt_compute_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
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;
|
||||
&crtc_state->hw.adjusted_mode;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
return -EINVAL;
|
||||
@ -450,30 +455,30 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder,
|
||||
adjusted_mode->crtc_hblank_start > 4096)
|
||||
return -EINVAL;
|
||||
|
||||
pipe_config->has_pch_encoder = true;
|
||||
if (!intel_fdi_compute_pipe_bpp(pipe_config))
|
||||
crtc_state->has_pch_encoder = true;
|
||||
if (!intel_fdi_compute_pipe_bpp(crtc_state))
|
||||
return -EINVAL;
|
||||
|
||||
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
|
||||
crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB;
|
||||
|
||||
/* LPT FDI RX only supports 8bpc. */
|
||||
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) {
|
||||
if (crtc_state->bw_constrained && crtc_state->pipe_bpp < 24) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"LPT only supports 24bpp\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pipe_config->pipe_bpp = 24;
|
||||
crtc_state->pipe_bpp = 24;
|
||||
}
|
||||
|
||||
/* FDI must always be 2.7 GHz */
|
||||
pipe_config->port_clock = 135000 * 2;
|
||||
crtc_state->port_clock = 135000 * 2;
|
||||
|
||||
pipe_config->enhanced_framing = true;
|
||||
crtc_state->enhanced_framing = true;
|
||||
|
||||
adjusted_mode->crtc_clock = lpt_iclkip(pipe_config);
|
||||
adjusted_mode->crtc_clock = lpt_iclkip(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -481,9 +486,8 @@ 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);
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
u32 adpa;
|
||||
bool ret;
|
||||
|
||||
@ -532,9 +536,8 @@ 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);
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
bool reenable_hpd;
|
||||
u32 adpa;
|
||||
bool ret;
|
||||
@ -588,8 +591,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);
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
u32 stat;
|
||||
bool ret = false;
|
||||
int i, tries = 0;
|
||||
@ -856,7 +858,7 @@ intel_crt_detect(struct drm_connector *connector,
|
||||
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;
|
||||
struct intel_encoder *encoder = &crt->base;
|
||||
struct drm_atomic_state *state;
|
||||
intel_wakeref_t wakeref;
|
||||
int status;
|
||||
@ -865,15 +867,14 @@ intel_crt_detect(struct drm_connector *connector,
|
||||
connector->base.id, connector->name,
|
||||
force);
|
||||
|
||||
if (!intel_display_device_enabled(dev_priv))
|
||||
if (!intel_display_device_enabled(display))
|
||||
return connector_status_disconnected;
|
||||
|
||||
if (!intel_display_driver_check_access(dev_priv))
|
||||
if (!intel_display_driver_check_access(display))
|
||||
return connector->status;
|
||||
|
||||
if (display->params.load_detect_test) {
|
||||
wakeref = intel_display_power_get(dev_priv,
|
||||
intel_encoder->power_domain);
|
||||
wakeref = intel_display_power_get(dev_priv, encoder->power_domain);
|
||||
goto load_detect;
|
||||
}
|
||||
|
||||
@ -881,8 +882,7 @@ intel_crt_detect(struct drm_connector *connector,
|
||||
if (dmi_check_system(intel_spurious_crt_detect))
|
||||
return connector_status_disconnected;
|
||||
|
||||
wakeref = intel_display_power_get(dev_priv,
|
||||
intel_encoder->power_domain);
|
||||
wakeref = intel_display_power_get(dev_priv, encoder->power_domain);
|
||||
|
||||
if (I915_HAS_HOTPLUG(display)) {
|
||||
/* We can not rely on the HPD pin always being correctly wired
|
||||
@ -939,7 +939,7 @@ intel_crt_detect(struct drm_connector *connector,
|
||||
}
|
||||
|
||||
out:
|
||||
intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
|
||||
intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -947,19 +947,17 @@ 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 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;
|
||||
struct intel_encoder *encoder = &crt->base;
|
||||
intel_wakeref_t wakeref;
|
||||
struct i2c_adapter *ddc;
|
||||
int ret;
|
||||
|
||||
if (!intel_display_driver_check_access(dev_priv))
|
||||
if (!intel_display_driver_check_access(display))
|
||||
return drm_edid_connector_add_modes(connector);
|
||||
|
||||
wakeref = intel_display_power_get(dev_priv,
|
||||
intel_encoder->power_domain);
|
||||
wakeref = intel_display_power_get(dev_priv, encoder->power_domain);
|
||||
|
||||
ret = intel_crt_ddc_get_modes(connector, connector->ddc);
|
||||
if (ret || !IS_G4X(dev_priv))
|
||||
@ -970,7 +968,7 @@ static int intel_crt_get_modes(struct drm_connector *connector)
|
||||
ret = intel_crt_ddc_get_modes(connector, ddc);
|
||||
|
||||
out:
|
||||
intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
|
||||
intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -984,7 +982,7 @@ void intel_crt_reset(struct drm_encoder *encoder)
|
||||
u32 adpa;
|
||||
|
||||
adpa = intel_de_read(display, crt->adpa_reg);
|
||||
adpa &= ~ADPA_CRT_HOTPLUG_MASK;
|
||||
adpa &= ~ADPA_HOTPLUG_MASK;
|
||||
adpa |= ADPA_HOTPLUG_BITS;
|
||||
intel_de_write(display, crt->adpa_reg, adpa);
|
||||
intel_de_posting_read(display, crt->adpa_reg);
|
||||
@ -1022,9 +1020,8 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
|
||||
void intel_crt_init(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct drm_connector *connector;
|
||||
struct intel_connector *connector;
|
||||
struct intel_crt *crt;
|
||||
struct intel_connector *intel_connector;
|
||||
i915_reg_t adpa_reg;
|
||||
u8 ddc_pin;
|
||||
u32 adpa;
|
||||
@ -1047,7 +1044,9 @@ void intel_crt_init(struct intel_display *display)
|
||||
* it and see what happens.
|
||||
*/
|
||||
intel_de_write(display, adpa_reg,
|
||||
adpa | ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
|
||||
adpa | ADPA_DAC_ENABLE |
|
||||
ADPA_HSYNC_CNTL_DISABLE |
|
||||
ADPA_VSYNC_CNTL_DISABLE);
|
||||
if ((intel_de_read(display, adpa_reg) & ADPA_DAC_ENABLE) == 0)
|
||||
return;
|
||||
intel_de_write(display, adpa_reg, adpa);
|
||||
@ -1057,17 +1056,15 @@ void intel_crt_init(struct intel_display *display)
|
||||
if (!crt)
|
||||
return;
|
||||
|
||||
intel_connector = intel_connector_alloc();
|
||||
if (!intel_connector) {
|
||||
connector = intel_connector_alloc();
|
||||
if (!connector) {
|
||||
kfree(crt);
|
||||
return;
|
||||
}
|
||||
|
||||
ddc_pin = display->vbt.crt_ddc_pin;
|
||||
|
||||
connector = &intel_connector->base;
|
||||
crt->connector = intel_connector;
|
||||
drm_connector_init_with_ddc(display->drm, connector,
|
||||
drm_connector_init_with_ddc(display->drm, &connector->base,
|
||||
&intel_crt_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VGA,
|
||||
intel_gmbus_get_adapter(display, ddc_pin));
|
||||
@ -1075,7 +1072,7 @@ void intel_crt_init(struct intel_display *display)
|
||||
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);
|
||||
intel_connector_attach_encoder(connector, &crt->base);
|
||||
|
||||
crt->base.type = INTEL_OUTPUT_ANALOG;
|
||||
crt->base.cloneable = BIT(INTEL_OUTPUT_DVO) | BIT(INTEL_OUTPUT_HDMI);
|
||||
@ -1085,7 +1082,7 @@ void intel_crt_init(struct intel_display *display)
|
||||
crt->base.pipe_mask = ~0;
|
||||
|
||||
if (DISPLAY_VER(display) != 2)
|
||||
connector->interlace_allowed = true;
|
||||
connector->base.interlace_allowed = true;
|
||||
|
||||
crt->adpa_reg = adpa_reg;
|
||||
|
||||
@ -1095,11 +1092,11 @@ void intel_crt_init(struct intel_display *display)
|
||||
!dmi_check_system(intel_spurious_crt_detect)) {
|
||||
crt->base.hpd_pin = HPD_CRT;
|
||||
crt->base.hotplug = intel_encoder_hotplug;
|
||||
intel_connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
} else {
|
||||
intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
}
|
||||
intel_connector->base.polled = intel_connector->polled;
|
||||
connector->base.polled = connector->polled;
|
||||
|
||||
if (HAS_DDI(display)) {
|
||||
assert_port_valid(dev_priv, PORT_E);
|
||||
@ -1132,9 +1129,9 @@ void intel_crt_init(struct intel_display *display)
|
||||
crt->base.get_hw_state = intel_crt_get_hw_state;
|
||||
crt->base.enable = intel_enable_crt;
|
||||
}
|
||||
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
||||
connector->get_hw_state = intel_connector_get_hw_state;
|
||||
|
||||
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
|
||||
drm_connector_helper_add(&connector->base, &intel_crt_connector_helper_funcs);
|
||||
|
||||
/*
|
||||
* TODO: find a proper way to discover whether we need to set the the
|
||||
|
50
drivers/gpu/drm/i915/display/intel_crt_regs.h
Normal file
50
drivers/gpu/drm/i915/display/intel_crt_regs.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_CRT_REGS_H__
|
||||
#define __INTEL_CRT_REGS_H__
|
||||
|
||||
#include "intel_display_reg_defs.h"
|
||||
|
||||
#define ADPA _MMIO(0x61100)
|
||||
#define PCH_ADPA _MMIO(0xe1100)
|
||||
#define VLV_ADPA _MMIO(VLV_DISPLAY_BASE + 0x61100)
|
||||
#define ADPA_DAC_ENABLE REG_BIT(31)
|
||||
#define ADPA_PIPE_SEL_MASK REG_BIT(30)
|
||||
#define ADPA_PIPE_SEL(pipe) REG_FIELD_PREP(ADPA_PIPE_SEL_MASK, (pipe))
|
||||
#define ADPA_PIPE_SEL_MASK_CPT REG_GENMASK(30, 29)
|
||||
#define ADPA_PIPE_SEL_CPT(pipe) REG_FIELD_PREP(ADPA_PIPE_SEL_MASK_CPT, (pipe))
|
||||
#define ADPA_CRT_HOTPLUG_MONITOR_MASK REG_GENMASK(25, 24)
|
||||
#define ADPA_CRT_HOTPLUG_MONITOR_NONE REG_FIELD_PREP(ADPA_CRT_HOTPLUG_MONITOR_MASK, 0)
|
||||
#define ADPA_CRT_HOTPLUG_MONITOR_COLOR REG_FIELD_PREP(ADPA_CRT_HOTPLUG_MONITOR_MASK, 3)
|
||||
#define ADPA_CRT_HOTPLUG_MONITOR_MONO REG_FIELD_PREP(ADPA_CRT_HOTPLUG_MONITOR_MASK, 2)
|
||||
#define ADPA_CRT_HOTPLUG_ENABLE REG_BIT(23)
|
||||
#define ADPA_CRT_HOTPLUG_PERIOD_MASK REG_BIT(22)
|
||||
#define ADPA_CRT_HOTPLUG_PERIOD_64 REG_FIELD_PREP(ADPA_CRT_HOTPLUG_PERIOD_MASK, 0)
|
||||
#define ADPA_CRT_HOTPLUG_PERIOD_128 REG_FIELD_PREP(ADPA_CRT_HOTPLUG_PERIOD_MASK, 1)
|
||||
#define ADPA_CRT_HOTPLUG_WARMUP_MASK REG_BIT(21)
|
||||
#define ADPA_CRT_HOTPLUG_WARMUP_5MS REG_FIELD_PREP(ADPA_CRT_HOTPLUG_WARMUP_MASK, 0)
|
||||
#define ADPA_CRT_HOTPLUG_WARMUP_10MS REG_FIELD_PREP(ADPA_CRT_HOTPLUG_WARMUP_MASK, 1)
|
||||
#define ADPA_CRT_HOTPLUG_SAMPLE_MASK REG_BIT(20)
|
||||
#define ADPA_CRT_HOTPLUG_SAMPLE_2S REG_FIELD_PREP(ADPA_CRT_HOTPLUG_SAMPLE_MASK, 0)
|
||||
#define ADPA_CRT_HOTPLUG_SAMPLE_4S REG_FIELD_PREP(ADPA_CRT_HOTPLUG_SAMPLE_MASK, 1)
|
||||
#define ADPA_CRT_HOTPLUG_VOLTAGE_MASK REG_GENMASK(19, 18)
|
||||
#define ADPA_CRT_HOTPLUG_VOLTAGE_40 REG_FIELD_PREP(ADPA_CRT_HOTPLUG_VOLTAGE_MASK, 0)
|
||||
#define ADPA_CRT_HOTPLUG_VOLTAGE_50 REG_FIELD_PREP(ADPA_CRT_HOTPLUG_VOLTAGE_MASK, 1)
|
||||
#define ADPA_CRT_HOTPLUG_VOLTAGE_60 REG_FIELD_PREP(ADPA_CRT_HOTPLUG_VOLTAGE_MASK, 2)
|
||||
#define ADPA_CRT_HOTPLUG_VOLTAGE_70 REG_FIELD_PREP(ADPA_CRT_HOTPLUG_VOLTAGE_MASK, 3)
|
||||
#define ADPA_CRT_HOTPLUG_VOLREF_MASK REG_BIT(17)
|
||||
#define ADPA_CRT_HOTPLUG_VOLREF_325MV REG_FIELD_PREP(ADPA_CRT_HOTPLUG_VOLREF_MASK, 0)
|
||||
#define ADPA_CRT_HOTPLUG_VOLREF_475MV REG_FIELD_PREP(ADPA_CRT_HOTPLUG_VOLREF_MASK, 1)
|
||||
#define ADPA_CRT_HOTPLUG_FORCE_TRIGGER REG_BIT(16)
|
||||
#define ADPA_USE_VGA_HVPOLARITY REG_BIT(15)
|
||||
#define ADPA_HSYNC_CNTL_DISABLE REG_BIT(11)
|
||||
#define ADPA_VSYNC_CNTL_DISABLE REG_BIT(10)
|
||||
#define ADPA_VSYNC_ACTIVE_HIGH REG_BIT(4)
|
||||
#define ADPA_HSYNC_ACTIVE_HIGH REG_BIT(3)
|
||||
|
||||
#define _VGA_MSR_WRITE _MMIO(0x3c2)
|
||||
|
||||
#endif /* __INTEL_CRT_REGS_H__ */
|
@ -12,6 +12,7 @@
|
||||
#include <drm/drm_vblank.h>
|
||||
#include <drm/drm_vblank_work.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_vgpu.h"
|
||||
#include "i9xx_plane.h"
|
||||
#include "icl_dsi.h"
|
||||
|
@ -50,16 +50,6 @@ intel_dump_infoframe(struct drm_i915_private *i915,
|
||||
hdmi_infoframe_log(KERN_DEBUG, i915->drm.dev, frame);
|
||||
}
|
||||
|
||||
static void
|
||||
intel_dump_buffer(const char *prefix, const u8 *buf, size_t len)
|
||||
{
|
||||
if (!drm_debug_enabled(DRM_UT_KMS))
|
||||
return;
|
||||
|
||||
print_hex_dump(KERN_DEBUG, prefix, DUMP_PREFIX_NONE,
|
||||
16, 0, buf, len, false);
|
||||
}
|
||||
|
||||
#define OUTPUT_TYPE(x) [INTEL_OUTPUT_ ## x] = #x
|
||||
|
||||
static const char * const output_type_str[] = {
|
||||
@ -293,8 +283,8 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
|
||||
drm_dp_as_sdp_log(&p, &pipe_config->infoframes.as_sdp);
|
||||
|
||||
if (pipe_config->has_audio)
|
||||
intel_dump_buffer("ELD: ", pipe_config->eld,
|
||||
drm_eld_size(pipe_config->eld));
|
||||
drm_print_hex_dump(&p, "ELD: ", pipe_config->eld,
|
||||
drm_eld_size(pipe_config->eld));
|
||||
|
||||
drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, pipeline full: %d, guardband: %d flipline: %d, vmin vblank: %d, vmax vblank: %d\n",
|
||||
str_yes_no(pipe_config->vrr.enable),
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_atomic_plane.h"
|
||||
@ -619,7 +620,6 @@ static void skl_write_cursor_wm(struct intel_dsb *dsb,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane->base.dev);
|
||||
struct drm_i915_private *i915 = to_i915(plane->base.dev);
|
||||
enum plane_id plane_id = plane->id;
|
||||
enum pipe pipe = plane->pipe;
|
||||
const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
|
||||
@ -627,14 +627,14 @@ static void skl_write_cursor_wm(struct intel_dsb *dsb,
|
||||
&crtc_state->wm.skl.plane_ddb[plane_id];
|
||||
int level;
|
||||
|
||||
for (level = 0; level < i915->display.wm.num_levels; level++)
|
||||
for (level = 0; level < display->wm.num_levels; level++)
|
||||
intel_de_write_dsb(display, dsb, CUR_WM(pipe, level),
|
||||
skl_cursor_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level)));
|
||||
|
||||
intel_de_write_dsb(display, dsb, CUR_WM_TRANS(pipe),
|
||||
skl_cursor_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id)));
|
||||
|
||||
if (HAS_HW_SAGV_WM(i915)) {
|
||||
if (HAS_HW_SAGV_WM(display)) {
|
||||
const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
|
||||
|
||||
intel_de_write_dsb(display, dsb, CUR_WM_SAGV(pipe),
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include <linux/log2.h>
|
||||
#include <linux/math64.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_cx0_phy.h"
|
||||
#include "intel_cx0_phy_regs.h"
|
||||
@ -2115,14 +2117,6 @@ static void intel_c10_pll_program(struct intel_display *display,
|
||||
0, C10_VDR_CTRL_MSGBUS_ACCESS,
|
||||
MB_WRITE_COMMITTED);
|
||||
|
||||
/* Custom width needs to be programmed to 0 for both the phy lanes */
|
||||
intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CUSTOM_WIDTH,
|
||||
C10_VDR_CUSTOM_WIDTH_MASK, C10_VDR_CUSTOM_WIDTH_8_10,
|
||||
MB_WRITE_COMMITTED);
|
||||
intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
|
||||
0, C10_VDR_CTRL_UPDATE_CFG,
|
||||
MB_WRITE_COMMITTED);
|
||||
|
||||
/* Program the pll values only for the master lane */
|
||||
for (i = 0; i < ARRAY_SIZE(pll_state->pll); i++)
|
||||
intel_cx0_write(encoder, INTEL_CX0_LANE0, PHY_C10_VDR_PLL(i),
|
||||
@ -2132,6 +2126,10 @@ static void intel_c10_pll_program(struct intel_display *display,
|
||||
intel_cx0_write(encoder, INTEL_CX0_LANE0, PHY_C10_VDR_CMN(0), pll_state->cmn, MB_WRITE_COMMITTED);
|
||||
intel_cx0_write(encoder, INTEL_CX0_LANE0, PHY_C10_VDR_TX(0), pll_state->tx, MB_WRITE_COMMITTED);
|
||||
|
||||
/* Custom width needs to be programmed to 0 for both the phy lanes */
|
||||
intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CUSTOM_WIDTH,
|
||||
C10_VDR_CUSTOM_WIDTH_MASK, C10_VDR_CUSTOM_WIDTH_8_10,
|
||||
MB_WRITE_COMMITTED);
|
||||
intel_cx0_rmw(encoder, INTEL_CX0_LANE0, PHY_C10_VDR_CONTROL(1),
|
||||
0, C10_VDR_CTRL_MASTER_LANE | C10_VDR_CTRL_UPDATE_CFG,
|
||||
MB_WRITE_COMMITTED);
|
||||
@ -2987,7 +2985,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
bool lane_reversal = dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
|
||||
bool lane_reversal = dig_port->lane_reversal;
|
||||
u8 maxpclk_lane = lane_reversal ? INTEL_CX0_LANE1 :
|
||||
INTEL_CX0_LANE0;
|
||||
intel_wakeref_t wakeref = intel_cx0_phy_transaction_begin(encoder);
|
||||
|
@ -9,6 +9,11 @@
|
||||
#include "i915_reg_defs.h"
|
||||
#include "intel_display_limits.h"
|
||||
|
||||
/* DDI Buffer Control */
|
||||
#define _DDI_CLK_VALFREQ_A 0x64030
|
||||
#define _DDI_CLK_VALFREQ_B 0x64130
|
||||
#define DDI_CLK_VALFREQ(port) _MMIO_PORT(port, _DDI_CLK_VALFREQ_A, _DDI_CLK_VALFREQ_B)
|
||||
|
||||
/*
|
||||
* Wrapper macro to convert from port number to the index used in some of the
|
||||
* registers. For Display version 20 and above it converts the port number to a
|
||||
|
@ -335,10 +335,14 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder,
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
|
||||
/* DDI_BUF_CTL_ENABLE will be set by intel_ddi_prepare_link_retrain() later */
|
||||
intel_dp->DP = dig_port->saved_port_bits |
|
||||
DDI_PORT_WIDTH(crtc_state->lane_count) |
|
||||
intel_dp->DP = DDI_PORT_WIDTH(crtc_state->lane_count) |
|
||||
DDI_BUF_TRANS_SELECT(0);
|
||||
|
||||
if (dig_port->lane_reversal)
|
||||
intel_dp->DP |= DDI_BUF_PORT_REVERSAL;
|
||||
if (dig_port->ddi_a_4_lanes)
|
||||
intel_dp->DP |= DDI_A_4_LANES;
|
||||
|
||||
if (DISPLAY_VER(i915) >= 14) {
|
||||
if (intel_dp_is_uhbr(crtc_state))
|
||||
intel_dp->DP |= DDI_BUF_PORT_DATA_40BIT;
|
||||
@ -455,17 +459,20 @@ static u32 bdw_trans_port_sync_master_select(enum transcoder master_transcoder)
|
||||
}
|
||||
|
||||
static void
|
||||
intel_ddi_config_transcoder_dp2(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
intel_ddi_config_transcoder_dp2(const struct intel_crtc_state *crtc_state,
|
||||
bool enable)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
u32 val = 0;
|
||||
|
||||
if (intel_dp_is_uhbr(crtc_state))
|
||||
if (!HAS_DP20(display))
|
||||
return;
|
||||
|
||||
if (enable && intel_dp_is_uhbr(crtc_state))
|
||||
val = TRANS_DP2_128B132B_CHANNEL_CODING;
|
||||
|
||||
intel_de_write(i915, TRANS_DP2_CTL(cpu_transcoder), val);
|
||||
intel_de_write(display, TRANS_DP2_CTL(cpu_transcoder), val);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -617,9 +624,10 @@ void intel_ddi_enable_transcoder_func(struct intel_encoder *encoder,
|
||||
|
||||
/*
|
||||
* Same as intel_ddi_enable_transcoder_func(), but it does not set the enable
|
||||
* bit.
|
||||
* bit for the DDI function and enables the DP2 configuration. Called for all
|
||||
* transcoder types.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
intel_ddi_config_transcoder_func(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
@ -628,12 +636,20 @@ intel_ddi_config_transcoder_func(struct intel_encoder *encoder,
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
u32 ctl;
|
||||
|
||||
intel_ddi_config_transcoder_dp2(crtc_state, true);
|
||||
|
||||
ctl = intel_ddi_transcoder_func_reg_val_get(encoder, crtc_state);
|
||||
ctl &= ~TRANS_DDI_FUNC_ENABLE;
|
||||
intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder),
|
||||
ctl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable the DDI function and port syncing.
|
||||
* For SST, pre-TGL MST, TGL+ MST-slave transcoders: deselect the DDI port,
|
||||
* SST/MST mode and disable the DP2 configuration. For TGL+ MST-master
|
||||
* transcoders these are done later in intel_ddi_post_disable_dp().
|
||||
*/
|
||||
void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
@ -670,6 +686,9 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
|
||||
intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder),
|
||||
ctl);
|
||||
|
||||
if (intel_dp_mst_is_slave_trans(crtc_state))
|
||||
intel_ddi_config_transcoder_dp2(crtc_state, false);
|
||||
|
||||
if (intel_has_quirk(display, QUIRK_INCREASE_DDI_DISABLED_TIME) &&
|
||||
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
|
||||
drm_dbg_kms(display->drm, "Quirk Increase DDI disabled time\n");
|
||||
@ -700,15 +719,15 @@ int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder,
|
||||
|
||||
bool intel_ddi_connector_get_hw_state(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(intel_connector);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_encoder *encoder = intel_attached_encoder(intel_connector);
|
||||
int type = intel_connector->base.connector_type;
|
||||
enum port port = encoder->port;
|
||||
enum transcoder cpu_transcoder;
|
||||
intel_wakeref_t wakeref;
|
||||
enum pipe pipe = 0;
|
||||
u32 tmp;
|
||||
u32 ddi_mode;
|
||||
bool ret;
|
||||
|
||||
wakeref = intel_display_power_get_if_enabled(dev_priv,
|
||||
@ -716,6 +735,7 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
|
||||
if (!wakeref)
|
||||
return false;
|
||||
|
||||
/* Note: This returns false for DP MST primary encoders. */
|
||||
if (!encoder->get_hw_state(encoder, &pipe)) {
|
||||
ret = false;
|
||||
goto out;
|
||||
@ -726,38 +746,28 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
|
||||
else
|
||||
cpu_transcoder = (enum transcoder) pipe;
|
||||
|
||||
tmp = intel_de_read(dev_priv,
|
||||
TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
|
||||
ddi_mode = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)) &
|
||||
TRANS_DDI_MODE_SELECT_MASK;
|
||||
|
||||
switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
|
||||
case TRANS_DDI_MODE_SELECT_HDMI:
|
||||
case TRANS_DDI_MODE_SELECT_DVI:
|
||||
if (ddi_mode == TRANS_DDI_MODE_SELECT_HDMI ||
|
||||
ddi_mode == TRANS_DDI_MODE_SELECT_DVI) {
|
||||
ret = type == DRM_MODE_CONNECTOR_HDMIA;
|
||||
break;
|
||||
|
||||
case TRANS_DDI_MODE_SELECT_DP_SST:
|
||||
} else if (ddi_mode == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B && !HAS_DP20(display)) {
|
||||
ret = type == DRM_MODE_CONNECTOR_VGA;
|
||||
} else if (ddi_mode == TRANS_DDI_MODE_SELECT_DP_SST) {
|
||||
ret = type == DRM_MODE_CONNECTOR_eDP ||
|
||||
type == DRM_MODE_CONNECTOR_DisplayPort;
|
||||
break;
|
||||
|
||||
case TRANS_DDI_MODE_SELECT_DP_MST:
|
||||
/* if the transcoder is in MST state then
|
||||
* connector isn't connected */
|
||||
type == DRM_MODE_CONNECTOR_DisplayPort;
|
||||
} else if (ddi_mode == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B && HAS_DP20(display)) {
|
||||
/*
|
||||
* encoder->get_hw_state() should have bailed out on MST. This
|
||||
* must be SST and non-eDP.
|
||||
*/
|
||||
ret = type == DRM_MODE_CONNECTOR_DisplayPort;
|
||||
} else if (drm_WARN_ON(display->drm, ddi_mode == TRANS_DDI_MODE_SELECT_DP_MST)) {
|
||||
/* encoder->get_hw_state() should have bailed out on MST. */
|
||||
ret = false;
|
||||
break;
|
||||
|
||||
case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B:
|
||||
if (HAS_DP20(dev_priv))
|
||||
/* 128b/132b */
|
||||
ret = false;
|
||||
else
|
||||
/* FDI */
|
||||
ret = type == DRM_MODE_CONNECTOR_VGA;
|
||||
break;
|
||||
|
||||
default:
|
||||
} else {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
@ -769,8 +779,8 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
|
||||
static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
|
||||
u8 *pipe_mask, bool *is_dp_mst)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
enum port port = encoder->port;
|
||||
intel_wakeref_t wakeref;
|
||||
enum pipe p;
|
||||
@ -815,7 +825,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
|
||||
mst_pipe_mask = 0;
|
||||
for_each_pipe(dev_priv, p) {
|
||||
enum transcoder cpu_transcoder = (enum transcoder)p;
|
||||
unsigned int port_mask, ddi_select;
|
||||
u32 port_mask, ddi_select, ddi_mode;
|
||||
intel_wakeref_t trans_wakeref;
|
||||
|
||||
trans_wakeref = intel_display_power_get_if_enabled(dev_priv,
|
||||
@ -839,9 +849,10 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
|
||||
if ((tmp & port_mask) != ddi_select)
|
||||
continue;
|
||||
|
||||
if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST ||
|
||||
(HAS_DP20(dev_priv) &&
|
||||
(tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B))
|
||||
ddi_mode = tmp & TRANS_DDI_MODE_SELECT_MASK;
|
||||
|
||||
if (ddi_mode == TRANS_DDI_MODE_SELECT_DP_MST ||
|
||||
(ddi_mode == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B && HAS_DP20(display)))
|
||||
mst_pipe_mask |= BIT(p);
|
||||
|
||||
*pipe_mask |= BIT(p);
|
||||
@ -2196,8 +2207,8 @@ i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder,
|
||||
return DP_TP_CTL(encoder->port);
|
||||
}
|
||||
|
||||
i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
static i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
|
||||
@ -2208,6 +2219,25 @@ i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder,
|
||||
return DP_TP_STATUS(encoder->port);
|
||||
}
|
||||
|
||||
void intel_ddi_clear_act_sent(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
||||
intel_de_write(display, dp_tp_status_reg(encoder, crtc_state),
|
||||
DP_TP_STATUS_ACT_SENT);
|
||||
}
|
||||
|
||||
void intel_ddi_wait_for_act_sent(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
||||
if (intel_de_wait_for_set(display, dp_tp_status_reg(encoder, crtc_state),
|
||||
DP_TP_STATUS_ACT_SENT, 1))
|
||||
drm_err(display->drm, "Timed out waiting for ACT sent\n");
|
||||
}
|
||||
|
||||
static void intel_dp_sink_set_msa_timing_par_ignore_state(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
bool enable)
|
||||
@ -2376,12 +2406,10 @@ static void intel_ddi_power_up_lanes(struct intel_encoder *encoder,
|
||||
|
||||
if (intel_encoder_is_combo(encoder)) {
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
bool lane_reversal =
|
||||
dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
|
||||
|
||||
intel_combo_phy_power_up_lanes(i915, phy, false,
|
||||
crtc_state->lane_count,
|
||||
lane_reversal);
|
||||
dig_port->lane_reversal);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2521,7 +2549,7 @@ static void mtl_port_buf_ctl_program(struct intel_encoder *encoder,
|
||||
else
|
||||
val |= XELPDP_PORT_BUF_PORT_DATA_10BIT;
|
||||
|
||||
if (dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL)
|
||||
if (dig_port->lane_reversal)
|
||||
val |= XELPDP_PORT_REVERSAL;
|
||||
|
||||
intel_de_write(i915, XELPDP_PORT_BUF_CTL1(i915, port), val);
|
||||
@ -2583,10 +2611,6 @@ static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state,
|
||||
|
||||
/*
|
||||
* 6.b If DP v2.0/128b mode - Configure TRANS_DP2_CTL register settings.
|
||||
*/
|
||||
intel_ddi_config_transcoder_dp2(encoder, crtc_state);
|
||||
|
||||
/*
|
||||
* 6.c Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST
|
||||
* Transport Select
|
||||
*/
|
||||
@ -2721,9 +2745,6 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
|
||||
*/
|
||||
intel_ddi_enable_transcoder_clock(encoder, crtc_state);
|
||||
|
||||
if (HAS_DP20(dev_priv))
|
||||
intel_ddi_config_transcoder_dp2(encoder, crtc_state);
|
||||
|
||||
/*
|
||||
* 7.b Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST
|
||||
* Transport Select
|
||||
@ -2862,9 +2883,9 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
||||
if (HAS_DP20(dev_priv))
|
||||
if (HAS_DP20(display))
|
||||
intel_dp_128b132b_sdp_crc16(enc_to_intel_dp(encoder),
|
||||
crtc_state);
|
||||
|
||||
@ -2872,9 +2893,9 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state,
|
||||
if (crtc_state->has_panel_replay)
|
||||
intel_psr_enable_sink(enc_to_intel_dp(encoder), crtc_state);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 14)
|
||||
if (DISPLAY_VER(display) >= 14)
|
||||
mtl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
|
||||
else if (DISPLAY_VER(dev_priv) >= 12)
|
||||
else if (DISPLAY_VER(display) >= 12)
|
||||
tgl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
|
||||
else
|
||||
hsw_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
|
||||
@ -2911,6 +2932,24 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
|
||||
crtc_state, conn_state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: Also called from the ->pre_enable of the first active MST stream
|
||||
* encoder on its primary encoder.
|
||||
*
|
||||
* When called from DP MST code:
|
||||
*
|
||||
* - conn_state will be NULL
|
||||
*
|
||||
* - encoder will be the primary encoder (i.e. mst->primary)
|
||||
*
|
||||
* - the main connector associated with this port won't be active or linked to a
|
||||
* crtc
|
||||
*
|
||||
* - crtc_state will be the state of the first stream to be activated on this
|
||||
* port, and it may not be the same stream that will be deactivated last, but
|
||||
* each stream should have a state that is identical when it comes to the DP
|
||||
* link parameteres
|
||||
*/
|
||||
static void intel_ddi_pre_enable(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
@ -2920,19 +2959,6 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state,
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
||||
/*
|
||||
* When called from DP MST code:
|
||||
* - conn_state will be NULL
|
||||
* - encoder will be the main encoder (ie. mst->primary)
|
||||
* - the main connector associated with this port
|
||||
* won't be active or linked to a crtc
|
||||
* - crtc_state will be the state of the first stream to
|
||||
* be activated on this port, and it may not be the same
|
||||
* stream that will be deactivated last, but each stream
|
||||
* should have a state that is identical when it comes to
|
||||
* the DP link parameteres
|
||||
*/
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, crtc_state->has_pch_encoder);
|
||||
|
||||
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
|
||||
@ -3088,6 +3114,8 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
|
||||
|
||||
intel_dp_sink_set_fec_ready(intel_dp, old_crtc_state, false);
|
||||
|
||||
intel_ddi_config_transcoder_dp2(old_crtc_state, false);
|
||||
|
||||
/*
|
||||
* From TGL spec: "If single stream or multi-stream master transcoder:
|
||||
* Configure Transcoder Clock select to direct no clock to the
|
||||
@ -3180,6 +3208,11 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: Also called from the ->post_disable of the last active MST stream
|
||||
* encoder on its primary encoder. See also the comment for
|
||||
* intel_ddi_pre_enable().
|
||||
*/
|
||||
static void intel_ddi_post_disable(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *old_crtc_state,
|
||||
@ -3210,6 +3243,11 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
|
||||
old_conn_state);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: Also called from the ->post_pll_disable of the last active MST stream
|
||||
* encoder on its primary encoder. See also the comment for
|
||||
* intel_ddi_pre_enable().
|
||||
*/
|
||||
static void intel_ddi_post_pll_disable(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *old_crtc_state,
|
||||
@ -3260,7 +3298,7 @@ static void trans_port_sync_stop_link_train(struct intel_atomic_state *state,
|
||||
crtc_state);
|
||||
}
|
||||
|
||||
static void intel_enable_ddi_dp(struct intel_atomic_state *state,
|
||||
static void intel_ddi_enable_dp(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state)
|
||||
@ -3282,18 +3320,8 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
|
||||
trans_port_sync_stop_link_train(state, encoder, crtc_state);
|
||||
}
|
||||
|
||||
/* FIXME bad home for this function */
|
||||
i915_reg_t hsw_chicken_trans_reg(struct drm_i915_private *i915,
|
||||
enum transcoder cpu_transcoder)
|
||||
{
|
||||
return DISPLAY_VER(i915) >= 14 ?
|
||||
MTL_CHICKEN_TRANS(cpu_transcoder) :
|
||||
CHICKEN_TRANS(cpu_transcoder);
|
||||
}
|
||||
|
||||
static i915_reg_t
|
||||
gen9_chicken_trans_reg_by_port(struct drm_i915_private *dev_priv,
|
||||
enum port port)
|
||||
gen9_chicken_trans_reg_by_port(struct intel_display *display, enum port port)
|
||||
{
|
||||
static const enum transcoder trans[] = {
|
||||
[PORT_A] = TRANSCODER_EDP,
|
||||
@ -3303,19 +3331,20 @@ gen9_chicken_trans_reg_by_port(struct drm_i915_private *dev_priv,
|
||||
[PORT_E] = TRANSCODER_A,
|
||||
};
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, DISPLAY_VER(dev_priv) < 9);
|
||||
drm_WARN_ON(display->drm, DISPLAY_VER(display) < 9);
|
||||
|
||||
if (drm_WARN_ON(&dev_priv->drm, port < PORT_A || port > PORT_E))
|
||||
if (drm_WARN_ON(display->drm, port < PORT_A || port > PORT_E))
|
||||
port = PORT_A;
|
||||
|
||||
return CHICKEN_TRANS(trans[port]);
|
||||
return CHICKEN_TRANS(display, trans[port]);
|
||||
}
|
||||
|
||||
static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
|
||||
static void intel_ddi_enable_hdmi(struct intel_atomic_state *state,
|
||||
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);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
struct drm_connector *connector = conn_state->connector;
|
||||
@ -3346,7 +3375,7 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
|
||||
* the bits affect a specific DDI port rather than
|
||||
* a specific transcoder.
|
||||
*/
|
||||
i915_reg_t reg = gen9_chicken_trans_reg_by_port(dev_priv, port);
|
||||
i915_reg_t reg = gen9_chicken_trans_reg_by_port(display, port);
|
||||
u32 val;
|
||||
|
||||
val = intel_de_read(dev_priv, reg);
|
||||
@ -3386,14 +3415,20 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
|
||||
* is filled with lane count, already set in the crtc_state.
|
||||
* The same is required to be filled in PORT_BUF_CTL for C10/20 Phy.
|
||||
*/
|
||||
buf_ctl = dig_port->saved_port_bits | DDI_BUF_CTL_ENABLE;
|
||||
buf_ctl = DDI_BUF_CTL_ENABLE;
|
||||
|
||||
if (dig_port->lane_reversal)
|
||||
buf_ctl |= DDI_BUF_PORT_REVERSAL;
|
||||
if (dig_port->ddi_a_4_lanes)
|
||||
buf_ctl |= DDI_A_4_LANES;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 14) {
|
||||
u8 lane_count = mtl_get_port_width(crtc_state->lane_count);
|
||||
u32 port_buf = 0;
|
||||
|
||||
port_buf |= XELPDP_PORT_WIDTH(lane_count);
|
||||
|
||||
if (dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL)
|
||||
if (dig_port->lane_reversal)
|
||||
port_buf |= XELPDP_PORT_REVERSAL;
|
||||
|
||||
intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(dev_priv, port),
|
||||
@ -3413,7 +3448,7 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
|
||||
intel_wait_ddi_buf_active(encoder);
|
||||
}
|
||||
|
||||
static void intel_enable_ddi(struct intel_atomic_state *state,
|
||||
static void intel_ddi_enable(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state)
|
||||
@ -3439,15 +3474,15 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
|
||||
}
|
||||
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
|
||||
intel_enable_ddi_hdmi(state, encoder, crtc_state, conn_state);
|
||||
intel_ddi_enable_hdmi(state, encoder, crtc_state, conn_state);
|
||||
else
|
||||
intel_enable_ddi_dp(state, encoder, crtc_state, conn_state);
|
||||
intel_ddi_enable_dp(state, encoder, crtc_state, conn_state);
|
||||
|
||||
intel_hdcp_enable(state, encoder, crtc_state, conn_state);
|
||||
|
||||
}
|
||||
|
||||
static void intel_disable_ddi_dp(struct intel_atomic_state *state,
|
||||
static void intel_ddi_disable_dp(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *old_crtc_state,
|
||||
const struct drm_connector_state *old_conn_state)
|
||||
@ -3468,7 +3503,7 @@ static void intel_disable_ddi_dp(struct intel_atomic_state *state,
|
||||
false);
|
||||
}
|
||||
|
||||
static void intel_disable_ddi_hdmi(struct intel_atomic_state *state,
|
||||
static void intel_ddi_disable_hdmi(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *old_crtc_state,
|
||||
const struct drm_connector_state *old_conn_state)
|
||||
@ -3483,7 +3518,7 @@ static void intel_disable_ddi_hdmi(struct intel_atomic_state *state,
|
||||
connector->base.id, connector->name);
|
||||
}
|
||||
|
||||
static void intel_disable_ddi(struct intel_atomic_state *state,
|
||||
static void intel_ddi_disable(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *old_crtc_state,
|
||||
const struct drm_connector_state *old_conn_state)
|
||||
@ -3493,10 +3528,10 @@ static void intel_disable_ddi(struct intel_atomic_state *state,
|
||||
intel_hdcp_disable(to_intel_connector(old_conn_state->connector));
|
||||
|
||||
if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
|
||||
intel_disable_ddi_hdmi(state, encoder, old_crtc_state,
|
||||
intel_ddi_disable_hdmi(state, encoder, old_crtc_state,
|
||||
old_conn_state);
|
||||
else
|
||||
intel_disable_ddi_dp(state, encoder, old_crtc_state,
|
||||
intel_ddi_disable_dp(state, encoder, old_crtc_state,
|
||||
old_conn_state);
|
||||
}
|
||||
|
||||
@ -3556,6 +3591,11 @@ void intel_ddi_update_active_dpll(struct intel_atomic_state *state,
|
||||
intel_update_active_dpll(state, pipe_crtc, encoder);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: Also called from the ->pre_pll_enable of the first active MST stream
|
||||
* encoder on its primary encoder. See also the comment for
|
||||
* intel_ddi_pre_enable().
|
||||
*/
|
||||
static void
|
||||
intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
@ -3868,29 +3908,136 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
|
||||
crtc_state->sync_mode_slaves_mask);
|
||||
}
|
||||
|
||||
static void intel_ddi_read_func_ctl_dvi(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
u32 ddi_func_ctl)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
||||
crtc_state->output_types |= BIT(INTEL_OUTPUT_HDMI);
|
||||
if (DISPLAY_VER(display) >= 14)
|
||||
crtc_state->lane_count =
|
||||
((ddi_func_ctl & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
|
||||
else
|
||||
crtc_state->lane_count = 4;
|
||||
}
|
||||
|
||||
static void intel_ddi_read_func_ctl_hdmi(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
u32 ddi_func_ctl)
|
||||
{
|
||||
crtc_state->has_hdmi_sink = true;
|
||||
|
||||
crtc_state->infoframes.enable |=
|
||||
intel_hdmi_infoframes_enabled(encoder, crtc_state);
|
||||
|
||||
if (crtc_state->infoframes.enable)
|
||||
crtc_state->has_infoframe = true;
|
||||
|
||||
if (ddi_func_ctl & TRANS_DDI_HDMI_SCRAMBLING)
|
||||
crtc_state->hdmi_scrambling = true;
|
||||
if (ddi_func_ctl & TRANS_DDI_HIGH_TMDS_CHAR_RATE)
|
||||
crtc_state->hdmi_high_tmds_clock_ratio = true;
|
||||
|
||||
intel_ddi_read_func_ctl_dvi(encoder, crtc_state, ddi_func_ctl);
|
||||
}
|
||||
|
||||
static void intel_ddi_read_func_ctl_fdi(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
u32 ddi_func_ctl)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
||||
crtc_state->output_types |= BIT(INTEL_OUTPUT_ANALOG);
|
||||
crtc_state->enhanced_framing =
|
||||
intel_de_read(display, dp_tp_ctl_reg(encoder, crtc_state)) &
|
||||
DP_TP_CTL_ENHANCED_FRAME_ENABLE;
|
||||
}
|
||||
|
||||
static void intel_ddi_read_func_ctl_dp_sst(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
u32 ddi_func_ctl)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
|
||||
if (encoder->type == INTEL_OUTPUT_EDP)
|
||||
crtc_state->output_types |= BIT(INTEL_OUTPUT_EDP);
|
||||
else
|
||||
crtc_state->output_types |= BIT(INTEL_OUTPUT_DP);
|
||||
crtc_state->lane_count =
|
||||
((ddi_func_ctl & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
|
||||
|
||||
intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder, &crtc_state->dp_m_n);
|
||||
intel_cpu_transcoder_get_m2_n2(crtc, cpu_transcoder, &crtc_state->dp_m2_n2);
|
||||
|
||||
crtc_state->enhanced_framing =
|
||||
intel_de_read(display, dp_tp_ctl_reg(encoder, crtc_state)) &
|
||||
DP_TP_CTL_ENHANCED_FRAME_ENABLE;
|
||||
|
||||
if (DISPLAY_VER(display) >= 11)
|
||||
crtc_state->fec_enable =
|
||||
intel_de_read(display,
|
||||
dp_tp_ctl_reg(encoder, crtc_state)) & DP_TP_CTL_FEC_ENABLE;
|
||||
|
||||
if (dig_port->lspcon.active && intel_dp_has_hdmi_sink(&dig_port->dp))
|
||||
crtc_state->infoframes.enable |=
|
||||
intel_lspcon_infoframes_enabled(encoder, crtc_state);
|
||||
else
|
||||
crtc_state->infoframes.enable |=
|
||||
intel_hdmi_infoframes_enabled(encoder, crtc_state);
|
||||
}
|
||||
|
||||
static void intel_ddi_read_func_ctl_dp_mst(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
u32 ddi_func_ctl)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
|
||||
crtc_state->output_types |= BIT(INTEL_OUTPUT_DP_MST);
|
||||
crtc_state->lane_count =
|
||||
((ddi_func_ctl & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
|
||||
|
||||
if (DISPLAY_VER(display) >= 12)
|
||||
crtc_state->mst_master_transcoder =
|
||||
REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, ddi_func_ctl);
|
||||
|
||||
intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder, &crtc_state->dp_m_n);
|
||||
|
||||
if (DISPLAY_VER(display) >= 11)
|
||||
crtc_state->fec_enable =
|
||||
intel_de_read(display,
|
||||
dp_tp_ctl_reg(encoder, crtc_state)) & DP_TP_CTL_FEC_ENABLE;
|
||||
|
||||
crtc_state->infoframes.enable |=
|
||||
intel_hdmi_infoframes_enabled(encoder, crtc_state);
|
||||
}
|
||||
|
||||
static void intel_ddi_read_func_ctl(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 intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
|
||||
enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
u32 temp, flags = 0;
|
||||
u32 ddi_func_ctl, ddi_mode, flags = 0;
|
||||
|
||||
temp = intel_de_read(dev_priv,
|
||||
TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
|
||||
if (temp & TRANS_DDI_PHSYNC)
|
||||
ddi_func_ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
|
||||
if (ddi_func_ctl & TRANS_DDI_PHSYNC)
|
||||
flags |= DRM_MODE_FLAG_PHSYNC;
|
||||
else
|
||||
flags |= DRM_MODE_FLAG_NHSYNC;
|
||||
if (temp & TRANS_DDI_PVSYNC)
|
||||
if (ddi_func_ctl & TRANS_DDI_PVSYNC)
|
||||
flags |= DRM_MODE_FLAG_PVSYNC;
|
||||
else
|
||||
flags |= DRM_MODE_FLAG_NVSYNC;
|
||||
|
||||
pipe_config->hw.adjusted_mode.flags |= flags;
|
||||
|
||||
switch (temp & TRANS_DDI_BPC_MASK) {
|
||||
switch (ddi_func_ctl & TRANS_DDI_BPC_MASK) {
|
||||
case TRANS_DDI_BPC_6:
|
||||
pipe_config->pipe_bpp = 18;
|
||||
break;
|
||||
@ -3907,93 +4054,27 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
|
||||
break;
|
||||
}
|
||||
|
||||
switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
|
||||
case TRANS_DDI_MODE_SELECT_HDMI:
|
||||
pipe_config->has_hdmi_sink = true;
|
||||
ddi_mode = ddi_func_ctl & TRANS_DDI_MODE_SELECT_MASK;
|
||||
|
||||
pipe_config->infoframes.enable |=
|
||||
intel_hdmi_infoframes_enabled(encoder, pipe_config);
|
||||
|
||||
if (pipe_config->infoframes.enable)
|
||||
pipe_config->has_infoframe = true;
|
||||
|
||||
if (temp & TRANS_DDI_HDMI_SCRAMBLING)
|
||||
pipe_config->hdmi_scrambling = true;
|
||||
if (temp & TRANS_DDI_HIGH_TMDS_CHAR_RATE)
|
||||
pipe_config->hdmi_high_tmds_clock_ratio = true;
|
||||
fallthrough;
|
||||
case TRANS_DDI_MODE_SELECT_DVI:
|
||||
pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI);
|
||||
if (DISPLAY_VER(dev_priv) >= 14)
|
||||
pipe_config->lane_count =
|
||||
((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
|
||||
else
|
||||
pipe_config->lane_count = 4;
|
||||
break;
|
||||
case TRANS_DDI_MODE_SELECT_DP_SST:
|
||||
if (encoder->type == INTEL_OUTPUT_EDP)
|
||||
pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
|
||||
else
|
||||
pipe_config->output_types |= BIT(INTEL_OUTPUT_DP);
|
||||
pipe_config->lane_count =
|
||||
((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
|
||||
|
||||
intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder,
|
||||
&pipe_config->dp_m_n);
|
||||
intel_cpu_transcoder_get_m2_n2(crtc, cpu_transcoder,
|
||||
&pipe_config->dp_m2_n2);
|
||||
|
||||
pipe_config->enhanced_framing =
|
||||
intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, pipe_config)) &
|
||||
DP_TP_CTL_ENHANCED_FRAME_ENABLE;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 11)
|
||||
pipe_config->fec_enable =
|
||||
intel_de_read(dev_priv,
|
||||
dp_tp_ctl_reg(encoder, pipe_config)) & DP_TP_CTL_FEC_ENABLE;
|
||||
|
||||
if (dig_port->lspcon.active && intel_dp_has_hdmi_sink(&dig_port->dp))
|
||||
pipe_config->infoframes.enable |=
|
||||
intel_lspcon_infoframes_enabled(encoder, pipe_config);
|
||||
else
|
||||
pipe_config->infoframes.enable |=
|
||||
intel_hdmi_infoframes_enabled(encoder, pipe_config);
|
||||
break;
|
||||
case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B:
|
||||
if (!HAS_DP20(dev_priv)) {
|
||||
/* FDI */
|
||||
pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
|
||||
pipe_config->enhanced_framing =
|
||||
intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, pipe_config)) &
|
||||
DP_TP_CTL_ENHANCED_FRAME_ENABLE;
|
||||
break;
|
||||
}
|
||||
fallthrough; /* 128b/132b */
|
||||
case TRANS_DDI_MODE_SELECT_DP_MST:
|
||||
pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
|
||||
pipe_config->lane_count =
|
||||
((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 12)
|
||||
pipe_config->mst_master_transcoder =
|
||||
REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, temp);
|
||||
|
||||
intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder,
|
||||
&pipe_config->dp_m_n);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 11)
|
||||
pipe_config->fec_enable =
|
||||
intel_de_read(dev_priv,
|
||||
dp_tp_ctl_reg(encoder, pipe_config)) & DP_TP_CTL_FEC_ENABLE;
|
||||
|
||||
pipe_config->infoframes.enable |=
|
||||
intel_hdmi_infoframes_enabled(encoder, pipe_config);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (ddi_mode == TRANS_DDI_MODE_SELECT_HDMI) {
|
||||
intel_ddi_read_func_ctl_hdmi(encoder, pipe_config, ddi_func_ctl);
|
||||
} else if (ddi_mode == TRANS_DDI_MODE_SELECT_DVI) {
|
||||
intel_ddi_read_func_ctl_dvi(encoder, pipe_config, ddi_func_ctl);
|
||||
} else if (ddi_mode == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B && !HAS_DP20(display)) {
|
||||
intel_ddi_read_func_ctl_fdi(encoder, pipe_config, ddi_func_ctl);
|
||||
} else if (ddi_mode == TRANS_DDI_MODE_SELECT_DP_SST) {
|
||||
intel_ddi_read_func_ctl_dp_sst(encoder, pipe_config, ddi_func_ctl);
|
||||
} else if (ddi_mode == TRANS_DDI_MODE_SELECT_DP_MST ||
|
||||
(ddi_mode == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B && HAS_DP20(display))) {
|
||||
intel_ddi_read_func_ctl_dp_mst(encoder, pipe_config, ddi_func_ctl);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: Also called from the ->get_config of the MST stream encoders on their
|
||||
* primary encoder, via the platform specific hooks here. See also the comment
|
||||
* for intel_ddi_pre_enable().
|
||||
*/
|
||||
static void intel_ddi_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
@ -4690,7 +4771,7 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port)
|
||||
if (dig_port->base.port != PORT_A)
|
||||
return false;
|
||||
|
||||
if (dig_port->saved_port_bits & DDI_A_4_LANES)
|
||||
if (dig_port->ddi_a_4_lanes)
|
||||
return false;
|
||||
|
||||
/* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only
|
||||
@ -4728,7 +4809,7 @@ intel_ddi_max_lanes(struct intel_digital_port *dig_port)
|
||||
if (intel_ddi_a_force_4_lanes(dig_port)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Forcing DDI_A_4_LANES for port A\n");
|
||||
dig_port->saved_port_bits |= DDI_A_4_LANES;
|
||||
dig_port->ddi_a_4_lanes = true;
|
||||
max_lanes = 4;
|
||||
}
|
||||
|
||||
@ -4907,6 +4988,7 @@ void intel_ddi_init(struct intel_display *display,
|
||||
bool init_hdmi, init_dp;
|
||||
enum port port;
|
||||
enum phy phy;
|
||||
u32 ddi_buf_ctl;
|
||||
|
||||
port = intel_bios_encoder_port(devdata);
|
||||
if (port == PORT_NONE)
|
||||
@ -5030,10 +5112,10 @@ void intel_ddi_init(struct intel_display *display,
|
||||
encoder->compute_output_type = intel_ddi_compute_output_type;
|
||||
encoder->compute_config = intel_ddi_compute_config;
|
||||
encoder->compute_config_late = intel_ddi_compute_config_late;
|
||||
encoder->enable = intel_enable_ddi;
|
||||
encoder->enable = intel_ddi_enable;
|
||||
encoder->pre_pll_enable = intel_ddi_pre_pll_enable;
|
||||
encoder->pre_enable = intel_ddi_pre_enable;
|
||||
encoder->disable = intel_disable_ddi;
|
||||
encoder->disable = intel_ddi_disable;
|
||||
encoder->post_pll_disable = intel_ddi_post_pll_disable;
|
||||
encoder->post_disable = intel_ddi_post_disable;
|
||||
encoder->update_pipe = intel_ddi_update_pipe;
|
||||
@ -5156,17 +5238,12 @@ void intel_ddi_init(struct intel_display *display,
|
||||
else
|
||||
encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 11)
|
||||
dig_port->saved_port_bits =
|
||||
intel_de_read(dev_priv, DDI_BUF_CTL(port))
|
||||
& DDI_BUF_PORT_REVERSAL;
|
||||
else
|
||||
dig_port->saved_port_bits =
|
||||
intel_de_read(dev_priv, DDI_BUF_CTL(port))
|
||||
& (DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES);
|
||||
ddi_buf_ctl = intel_de_read(dev_priv, DDI_BUF_CTL(port));
|
||||
|
||||
if (intel_bios_encoder_lane_reversal(devdata))
|
||||
dig_port->saved_port_bits |= DDI_BUF_PORT_REVERSAL;
|
||||
dig_port->lane_reversal = intel_bios_encoder_lane_reversal(devdata) ||
|
||||
ddi_buf_ctl & DDI_BUF_PORT_REVERSAL;
|
||||
|
||||
dig_port->ddi_a_4_lanes = DISPLAY_VER(dev_priv) < 11 && ddi_buf_ctl & DDI_A_4_LANES;
|
||||
|
||||
dig_port->dp.output_reg = INVALID_MMIO_REG;
|
||||
dig_port->max_lanes = intel_ddi_max_lanes(dig_port);
|
||||
|
@ -26,10 +26,12 @@ enum transcoder;
|
||||
|
||||
i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
i915_reg_t hsw_chicken_trans_reg(struct drm_i915_private *i915,
|
||||
enum transcoder cpu_transcoder);
|
||||
|
||||
void intel_ddi_clear_act_sent(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_ddi_wait_for_act_sent(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
|
||||
void intel_ddi_fdi_post_disable(struct intel_atomic_state *state,
|
||||
struct intel_encoder *intel_encoder,
|
||||
const struct intel_crtc_state *old_crtc_state,
|
||||
@ -57,6 +59,8 @@ void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
|
||||
void intel_ddi_init(struct intel_display *display,
|
||||
const struct intel_bios_encoder_data *devdata);
|
||||
bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe);
|
||||
void intel_ddi_config_transcoder_func(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_ddi_enable_transcoder_func(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state);
|
||||
|
@ -1687,18 +1687,24 @@ dg2_get_snps_buf_trans(struct intel_encoder *encoder,
|
||||
}
|
||||
|
||||
static const struct intel_ddi_buf_trans *
|
||||
mtl_get_cx0_buf_trans(struct intel_encoder *encoder,
|
||||
mtl_get_c10_buf_trans(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries)
|
||||
{
|
||||
if (intel_crtc_has_dp_encoder(crtc_state) && crtc_state->port_clock >= 1000000)
|
||||
return intel_get_buf_trans(&mtl_c10_trans_dp14, n_entries);
|
||||
}
|
||||
|
||||
static const struct intel_ddi_buf_trans *
|
||||
mtl_get_c20_buf_trans(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries)
|
||||
{
|
||||
if (intel_crtc_has_dp_encoder(crtc_state) && intel_dp_is_uhbr(crtc_state))
|
||||
return intel_get_buf_trans(&mtl_c20_trans_uhbr, n_entries);
|
||||
else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && !(intel_encoder_is_c10phy(encoder)))
|
||||
else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
|
||||
return intel_get_buf_trans(&mtl_c20_trans_hdmi, n_entries);
|
||||
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);
|
||||
return intel_get_buf_trans(&mtl_c20_trans_dp14, n_entries);
|
||||
}
|
||||
|
||||
void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
|
||||
@ -1706,7 +1712,10 @@ void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
|
||||
if (DISPLAY_VER(i915) >= 14) {
|
||||
encoder->get_buf_trans = mtl_get_cx0_buf_trans;
|
||||
if (intel_encoder_is_c10phy(encoder))
|
||||
encoder->get_buf_trans = mtl_get_c10_buf_trans;
|
||||
else
|
||||
encoder->get_buf_trans = mtl_get_c20_buf_trans;
|
||||
} else if (IS_DG2(i915)) {
|
||||
encoder->get_buf_trans = dg2_get_snps_buf_trans;
|
||||
} else if (IS_ALDERLAKE_P(i915)) {
|
||||
|
@ -6,14 +6,16 @@
|
||||
#ifndef __INTEL_DE_H__
|
||||
#define __INTEL_DE_H__
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_trace.h"
|
||||
#include "intel_display_conversion.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_dmc_wl.h"
|
||||
#include "intel_dsb.h"
|
||||
#include "intel_uncore.h"
|
||||
#include "intel_uncore_trace.h"
|
||||
|
||||
static inline struct intel_uncore *__to_uncore(struct intel_display *display)
|
||||
{
|
||||
return &to_i915(display->drm)->uncore;
|
||||
return to_intel_uncore(display->drm);
|
||||
}
|
||||
|
||||
static inline u32
|
||||
@ -117,6 +119,16 @@ __intel_de_wait_for_register_nowl(struct intel_display *display,
|
||||
value, timeout);
|
||||
}
|
||||
|
||||
static inline int
|
||||
__intel_de_wait_for_register_atomic_nowl(struct intel_display *display,
|
||||
i915_reg_t reg,
|
||||
u32 mask, u32 value,
|
||||
unsigned int fast_timeout_us)
|
||||
{
|
||||
return __intel_wait_for_register(__to_uncore(display), reg, mask,
|
||||
value, fast_timeout_us, 0, NULL);
|
||||
}
|
||||
|
||||
static inline int
|
||||
intel_de_wait(struct intel_display *display, i915_reg_t reg,
|
||||
u32 mask, u32 value, unsigned int timeout)
|
||||
|
@ -511,6 +511,7 @@ void vlv_wait_port_ready(struct intel_display *display,
|
||||
|
||||
void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state)
|
||||
{
|
||||
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 *dev_priv = to_i915(crtc->base.dev);
|
||||
enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
|
||||
@ -554,8 +555,7 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state)
|
||||
if (DISPLAY_VER(dev_priv) == 14)
|
||||
set |= DP_FEC_BS_JITTER_WA;
|
||||
|
||||
intel_de_rmw(dev_priv,
|
||||
hsw_chicken_trans_reg(dev_priv, cpu_transcoder),
|
||||
intel_de_rmw(display, CHICKEN_TRANS(display, cpu_transcoder),
|
||||
clear, set);
|
||||
}
|
||||
|
||||
@ -591,6 +591,7 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state)
|
||||
|
||||
void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(old_crtc_state);
|
||||
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
|
||||
@ -628,7 +629,7 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)
|
||||
intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 12)
|
||||
intel_de_rmw(dev_priv, hsw_chicken_trans_reg(dev_priv, cpu_transcoder),
|
||||
intel_de_rmw(display, CHICKEN_TRANS(display, cpu_transcoder),
|
||||
FECSTALL_DIS_DPTSTREAM_DPTTG, 0);
|
||||
|
||||
if ((val & TRANSCONF_ENABLE) == 0)
|
||||
@ -1744,10 +1745,9 @@ static void hsw_set_linetime_wm(const struct intel_crtc_state *crtc_state)
|
||||
|
||||
static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
|
||||
intel_de_rmw(i915, hsw_chicken_trans_reg(i915, crtc_state->cpu_transcoder),
|
||||
intel_de_rmw(display, CHICKEN_TRANS(display, crtc_state->cpu_transcoder),
|
||||
HSW_FRAME_START_DELAY_MASK,
|
||||
HSW_FRAME_START_DELAY(crtc_state->framestart_delay - 1));
|
||||
}
|
||||
@ -2371,7 +2371,7 @@ static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
|
||||
const struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
|
||||
/* GDG double wide on either pipe, otherwise pipe A only */
|
||||
return DISPLAY_VER(dev_priv) < 4 &&
|
||||
return HAS_DOUBLE_WIDE(dev_priv) &&
|
||||
(crtc->pipe == PIPE_A || IS_I915G(dev_priv));
|
||||
}
|
||||
|
||||
@ -3137,9 +3137,14 @@ bdw_get_pipe_misc_output_format(struct intel_crtc *crtc)
|
||||
tmp = intel_de_read(dev_priv, PIPE_MISC(crtc->pipe));
|
||||
|
||||
if (tmp & PIPE_MISC_YUV420_ENABLE) {
|
||||
/* We support 4:2:0 in full blend mode only */
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
(tmp & PIPE_MISC_YUV420_MODE_FULL_BLEND) == 0);
|
||||
/*
|
||||
* We support 4:2:0 in full blend mode only.
|
||||
* For xe3_lpd+ this is implied in YUV420 Enable bit.
|
||||
* Ensure the same for prior platforms in YUV420 Mode bit.
|
||||
*/
|
||||
if (DISPLAY_VER(dev_priv) < 30)
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
(tmp & PIPE_MISC_YUV420_MODE_FULL_BLEND) == 0);
|
||||
|
||||
return INTEL_OUTPUT_FORMAT_YCBCR420;
|
||||
} else if (tmp & PIPE_MISC_OUTPUT_COLORSPACE_YUV) {
|
||||
@ -3207,7 +3212,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
|
||||
|
||||
intel_color_get_config(pipe_config);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) < 4)
|
||||
if (HAS_DOUBLE_WIDE(dev_priv))
|
||||
pipe_config->double_wide = tmp & TRANSCONF_DOUBLE_WIDE;
|
||||
|
||||
intel_get_transcoder_timings(crtc, pipe_config);
|
||||
@ -3388,8 +3393,8 @@ static void bdw_set_pipe_misc(struct intel_dsb *dsb,
|
||||
val |= PIPE_MISC_OUTPUT_COLORSPACE_YUV;
|
||||
|
||||
if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
|
||||
val |= PIPE_MISC_YUV420_ENABLE |
|
||||
PIPE_MISC_YUV420_MODE_FULL_BLEND;
|
||||
val |= DISPLAY_VER(display) >= 30 ? PIPE_MISC_YUV420_ENABLE :
|
||||
PIPE_MISC_YUV420_ENABLE | PIPE_MISC_YUV420_MODE_FULL_BLEND;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 11 && is_hdr_mode(crtc_state))
|
||||
val |= PIPE_MISC_HDR_MODE_PRECISION;
|
||||
@ -3746,12 +3751,13 @@ static u8 fixup_ultrajoiner_secondary_pipes(u8 ultrajoiner_primary_pipes,
|
||||
static void enabled_ultrajoiner_pipes(struct drm_i915_private *i915,
|
||||
u8 *primary_pipes, u8 *secondary_pipes)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
*primary_pipes = 0;
|
||||
*secondary_pipes = 0;
|
||||
|
||||
if (!HAS_ULTRAJOINER(i915))
|
||||
if (!HAS_ULTRAJOINER(display))
|
||||
return;
|
||||
|
||||
for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc,
|
||||
@ -4111,6 +4117,7 @@ static void intel_joiner_get_config(struct intel_crtc_state *crtc_state)
|
||||
static bool hsw_get_pipe_config(struct intel_crtc *crtc,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
bool active;
|
||||
u32 tmp;
|
||||
@ -4187,7 +4194,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
|
||||
}
|
||||
|
||||
if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
|
||||
tmp = intel_de_read(dev_priv, hsw_chicken_trans_reg(dev_priv, pipe_config->cpu_transcoder));
|
||||
tmp = intel_de_read(display, CHICKEN_TRANS(display, pipe_config->cpu_transcoder));
|
||||
|
||||
pipe_config->framestart_delay = REG_FIELD_GET(HSW_FRAME_START_DELAY_MASK, tmp) + 1;
|
||||
} else {
|
||||
@ -4545,6 +4552,7 @@ static int hsw_compute_linetime_wm(struct intel_atomic_state *state,
|
||||
static int intel_crtc_atomic_check(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
@ -4581,12 +4589,12 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = intel_atomic_setup_scalers(dev_priv, crtc, crtc_state);
|
||||
ret = intel_atomic_setup_scalers(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (HAS_IPS(dev_priv)) {
|
||||
if (HAS_IPS(display)) {
|
||||
ret = hsw_ips_compute_config(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -5208,7 +5216,7 @@ pipe_config_dp_vsc_sdp_mismatch(struct drm_printer *p, bool fastset,
|
||||
const struct drm_dp_vsc_sdp *a,
|
||||
const struct drm_dp_vsc_sdp *b)
|
||||
{
|
||||
pipe_config_mismatch(p, fastset, crtc, name, "dp sdp");
|
||||
pipe_config_mismatch(p, fastset, crtc, name, "dp vsc sdp");
|
||||
|
||||
drm_printf(p, "expected:\n");
|
||||
drm_dp_vsc_sdp_log(p, a);
|
||||
@ -5217,27 +5225,18 @@ pipe_config_dp_vsc_sdp_mismatch(struct drm_printer *p, bool fastset,
|
||||
}
|
||||
|
||||
static void
|
||||
pipe_config_dp_as_sdp_mismatch(struct drm_i915_private *i915,
|
||||
bool fastset, const char *name,
|
||||
pipe_config_dp_as_sdp_mismatch(struct drm_printer *p, bool fastset,
|
||||
const struct intel_crtc *crtc,
|
||||
const char *name,
|
||||
const struct drm_dp_as_sdp *a,
|
||||
const struct drm_dp_as_sdp *b)
|
||||
{
|
||||
struct drm_printer p;
|
||||
pipe_config_mismatch(p, fastset, crtc, name, "dp as sdp");
|
||||
|
||||
if (fastset) {
|
||||
p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, NULL);
|
||||
|
||||
drm_printf(&p, "fastset requirement not met in %s dp sdp\n", name);
|
||||
} else {
|
||||
p = drm_err_printer(&i915->drm, NULL);
|
||||
|
||||
drm_printf(&p, "mismatch in %s dp sdp\n", name);
|
||||
}
|
||||
|
||||
drm_printf(&p, "expected:\n");
|
||||
drm_dp_as_sdp_log(&p, a);
|
||||
drm_printf(&p, "found:\n");
|
||||
drm_dp_as_sdp_log(&p, b);
|
||||
drm_printf(p, "expected:\n");
|
||||
drm_dp_as_sdp_log(p, a);
|
||||
drm_printf(p, "found:\n");
|
||||
drm_dp_as_sdp_log(p, b);
|
||||
}
|
||||
|
||||
/* Returns the length up to and including the last differing byte */
|
||||
@ -5260,26 +5259,13 @@ pipe_config_buffer_mismatch(struct drm_printer *p, bool fastset,
|
||||
const char *name,
|
||||
const u8 *a, const u8 *b, size_t len)
|
||||
{
|
||||
const char *loglevel;
|
||||
|
||||
if (fastset) {
|
||||
if (!drm_debug_enabled(DRM_UT_KMS))
|
||||
return;
|
||||
|
||||
loglevel = KERN_DEBUG;
|
||||
} else {
|
||||
loglevel = KERN_ERR;
|
||||
}
|
||||
|
||||
pipe_config_mismatch(p, fastset, crtc, name, "buffer");
|
||||
|
||||
/* only dump up to the last difference */
|
||||
len = memcmp_diff_len(a, b, len);
|
||||
|
||||
print_hex_dump(loglevel, "expected: ", DUMP_PREFIX_NONE,
|
||||
16, 0, a, len, false);
|
||||
print_hex_dump(loglevel, "found: ", DUMP_PREFIX_NONE,
|
||||
16, 0, b, len, false);
|
||||
drm_print_hex_dump(p, "expected: ", a, len);
|
||||
drm_print_hex_dump(p, "found: ", b, len);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -5322,6 +5308,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
const struct intel_crtc_state *pipe_config,
|
||||
bool fastset)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(current_config);
|
||||
struct drm_i915_private *dev_priv = to_i915(current_config->uapi.crtc->dev);
|
||||
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
|
||||
struct drm_printer p;
|
||||
@ -5498,7 +5485,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
#define PIPE_CONF_CHECK_DP_AS_SDP(name) do { \
|
||||
if (!intel_compare_dp_as_sdp(¤t_config->infoframes.name, \
|
||||
&pipe_config->infoframes.name)) { \
|
||||
pipe_config_dp_as_sdp_mismatch(dev_priv, fastset, __stringify(name), \
|
||||
pipe_config_dp_as_sdp_mismatch(&p, fastset, crtc, __stringify(name), \
|
||||
¤t_config->infoframes.name, \
|
||||
&pipe_config->infoframes.name); \
|
||||
ret = false; \
|
||||
@ -5562,7 +5549,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
PIPE_CONF_CHECK_I(lane_count);
|
||||
PIPE_CONF_CHECK_X(lane_lat_optim_mask);
|
||||
|
||||
if (HAS_DOUBLE_BUFFERED_M_N(dev_priv)) {
|
||||
if (HAS_DOUBLE_BUFFERED_M_N(display)) {
|
||||
if (!fastset || !pipe_config->update_m_n)
|
||||
PIPE_CONF_CHECK_M_N(dp_m_n);
|
||||
} else {
|
||||
@ -5743,7 +5730,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
PIPE_CONF_CHECK_I(dsc.config.nsl_bpg_offset);
|
||||
|
||||
PIPE_CONF_CHECK_BOOL(dsc.compression_enable);
|
||||
PIPE_CONF_CHECK_BOOL(dsc.dsc_split);
|
||||
PIPE_CONF_CHECK_I(dsc.num_streams);
|
||||
PIPE_CONF_CHECK_I(dsc.compressed_bpp_x16);
|
||||
|
||||
PIPE_CONF_CHECK_BOOL(splitter.enable);
|
||||
@ -6797,6 +6784,7 @@ static int intel_atomic_check_config_and_link(struct intel_atomic_state *state)
|
||||
int intel_atomic_check(struct drm_device *dev,
|
||||
struct drm_atomic_state *_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_atomic_state *state = to_intel_atomic_state(_state);
|
||||
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
|
||||
@ -6804,7 +6792,7 @@ int intel_atomic_check(struct drm_device *dev,
|
||||
int ret, i;
|
||||
bool any_ms = false;
|
||||
|
||||
if (!intel_display_driver_check_access(dev_priv))
|
||||
if (!intel_display_driver_check_access(display))
|
||||
return -ENODEV;
|
||||
|
||||
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
||||
@ -7572,7 +7560,7 @@ static void intel_atomic_dsb_cleanup(struct intel_crtc_state *crtc_state)
|
||||
static void intel_atomic_cleanup_work(struct work_struct *work)
|
||||
{
|
||||
struct intel_atomic_state *state =
|
||||
container_of(work, struct intel_atomic_state, base.commit_work);
|
||||
container_of(work, struct intel_atomic_state, cleanup_work);
|
||||
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
||||
struct intel_crtc_state *old_crtc_state;
|
||||
struct intel_crtc *crtc;
|
||||
@ -7822,6 +7810,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
|
||||
/* Now enable the clocks, plane, pipe, and connectors that we set up. */
|
||||
dev_priv->display.funcs.display->commit_modeset_enables(state);
|
||||
|
||||
intel_program_dpkgc_latency(state);
|
||||
|
||||
if (state->modeset)
|
||||
intel_set_cdclk_post_plane_update(state);
|
||||
|
||||
@ -7927,8 +7917,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
|
||||
* schedule point (cond_resched()) here anyway to keep latencies
|
||||
* down.
|
||||
*/
|
||||
INIT_WORK(&state->base.commit_work, intel_atomic_cleanup_work);
|
||||
queue_work(system_highpri_wq, &state->base.commit_work);
|
||||
INIT_WORK(&state->cleanup_work, intel_atomic_cleanup_work);
|
||||
queue_work(dev_priv->display.wq.cleanup, &state->cleanup_work);
|
||||
}
|
||||
|
||||
static void intel_atomic_commit_work(struct work_struct *work)
|
||||
@ -8166,7 +8156,7 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv)
|
||||
intel_lvds_init(dev_priv);
|
||||
intel_crt_init(display);
|
||||
|
||||
dpd_is_edp = intel_dp_is_port_edp(dev_priv, PORT_D);
|
||||
dpd_is_edp = intel_dp_is_port_edp(display, PORT_D);
|
||||
|
||||
if (ilk_has_edp_a(dev_priv))
|
||||
g4x_dp_init(dev_priv, DP_A, PORT_A);
|
||||
@ -8212,14 +8202,14 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv)
|
||||
* trust the port type the VBT declares as we've seen at least
|
||||
* HDMI ports that the VBT claim are DP or eDP.
|
||||
*/
|
||||
has_edp = intel_dp_is_port_edp(dev_priv, PORT_B);
|
||||
has_edp = intel_dp_is_port_edp(display, PORT_B);
|
||||
has_port = intel_bios_is_port_present(display, PORT_B);
|
||||
if (intel_de_read(dev_priv, VLV_DP_B) & DP_DETECTED || has_port)
|
||||
has_edp &= g4x_dp_init(dev_priv, VLV_DP_B, PORT_B);
|
||||
if ((intel_de_read(dev_priv, VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp)
|
||||
g4x_hdmi_init(dev_priv, VLV_HDMIB, PORT_B);
|
||||
|
||||
has_edp = intel_dp_is_port_edp(dev_priv, PORT_C);
|
||||
has_edp = intel_dp_is_port_edp(display, PORT_C);
|
||||
has_port = intel_bios_is_port_present(display, PORT_C);
|
||||
if (intel_de_read(dev_priv, VLV_DP_C) & DP_DETECTED || has_port)
|
||||
has_edp &= g4x_dp_init(dev_priv, VLV_DP_C, PORT_C);
|
||||
@ -8308,11 +8298,12 @@ void intel_setup_outputs(struct drm_i915_private *dev_priv)
|
||||
|
||||
static int max_dotclock(struct drm_i915_private *i915)
|
||||
{
|
||||
int max_dotclock = i915->display.cdclk.max_dotclk_freq;
|
||||
struct intel_display *display = &i915->display;
|
||||
int max_dotclock = display->cdclk.max_dotclk_freq;
|
||||
|
||||
if (HAS_ULTRAJOINER(i915))
|
||||
if (HAS_ULTRAJOINER(display))
|
||||
max_dotclock *= 4;
|
||||
else if (HAS_UNCOMPRESSED_JOINER(i915) || HAS_BIGJOINER(i915))
|
||||
else if (HAS_UNCOMPRESSED_JOINER(display) || HAS_BIGJOINER(display))
|
||||
max_dotclock *= 2;
|
||||
|
||||
return max_dotclock;
|
||||
|
@ -238,9 +238,6 @@ enum phy_fia {
|
||||
for ((__phy) = PHY_A; (__phy) < I915_MAX_PHYS; (__phy)++) \
|
||||
for_each_if((__phys_mask) & BIT(__phy))
|
||||
|
||||
#define for_each_crtc(dev, crtc) \
|
||||
list_for_each_entry(crtc, &(dev)->mode_config.crtc_list, head)
|
||||
|
||||
#define for_each_intel_plane(dev, intel_plane) \
|
||||
list_for_each_entry(intel_plane, \
|
||||
&(dev)->mode_config.plane_list, \
|
||||
|
14
drivers/gpu/drm/i915/display/intel_display_conversion.c
Normal file
14
drivers/gpu/drm/i915/display/intel_display_conversion.c
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/* Copyright © 2024 Intel Corporation */
|
||||
|
||||
#include "i915_drv.h"
|
||||
|
||||
struct intel_display *__i915_to_display(struct drm_i915_private *i915)
|
||||
{
|
||||
return &i915->display;
|
||||
}
|
||||
|
||||
struct intel_display *__drm_to_display(struct drm_device *drm)
|
||||
{
|
||||
return __i915_to_display(to_i915(drm));
|
||||
}
|
@ -8,14 +8,20 @@
|
||||
#ifndef __INTEL_DISPLAY_CONVERSION__
|
||||
#define __INTEL_DISPLAY_CONVERSION__
|
||||
|
||||
struct drm_device;
|
||||
struct drm_i915_private;
|
||||
struct intel_display;
|
||||
|
||||
struct intel_display *__i915_to_display(struct drm_i915_private *i915);
|
||||
struct intel_display *__drm_to_display(struct drm_device *drm);
|
||||
/*
|
||||
* Transitional macro to optionally convert struct drm_i915_private * to struct
|
||||
* intel_display *, also accepting the latter.
|
||||
*/
|
||||
#define __to_intel_display(p) \
|
||||
_Generic(p, \
|
||||
const struct drm_i915_private *: (&((const struct drm_i915_private *)(p))->display), \
|
||||
struct drm_i915_private *: (&((struct drm_i915_private *)(p))->display), \
|
||||
const struct drm_i915_private *: __i915_to_display((struct drm_i915_private *)(p)), \
|
||||
struct drm_i915_private *: __i915_to_display((struct drm_i915_private *)(p)), \
|
||||
const struct intel_display *: (p), \
|
||||
struct intel_display *: (p))
|
||||
|
||||
|
@ -453,7 +453,14 @@ struct intel_display {
|
||||
} ips;
|
||||
|
||||
struct {
|
||||
bool display_irqs_enabled;
|
||||
/*
|
||||
* Most platforms treat the display irq block as an always-on
|
||||
* power domain. vlv/chv can disable it at runtime and need
|
||||
* special care to avoid writing any of the display block
|
||||
* registers outside of the power domain. We defer setting up
|
||||
* the display irqs in this case to the runtime pm.
|
||||
*/
|
||||
bool vlv_display_irqs_enabled;
|
||||
|
||||
/* For i915gm/i945gm vblank irq workaround */
|
||||
u8 vblank_enabled;
|
||||
@ -505,6 +512,11 @@ struct intel_display {
|
||||
/* restore state for suspend/resume and display reset */
|
||||
struct drm_atomic_state *modeset_state;
|
||||
struct drm_modeset_acquire_ctx reset_ctx;
|
||||
u32 saveDSPARB;
|
||||
u32 saveSWF0[16];
|
||||
u32 saveSWF1[16];
|
||||
u32 saveSWF3[3];
|
||||
u16 saveGCDGMBUS;
|
||||
} restore;
|
||||
|
||||
struct {
|
||||
@ -542,6 +554,9 @@ struct intel_display {
|
||||
|
||||
/* unbound hipri wq for page flips/plane updates */
|
||||
struct workqueue_struct *flip;
|
||||
|
||||
/* hipri wq for commit cleanups */
|
||||
struct workqueue_struct *cleanup;
|
||||
} wq;
|
||||
|
||||
/* Grouping using named structs. Keep sorted. */
|
||||
|
@ -11,8 +11,10 @@
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "hsw_ips.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_irq.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i9xx_wm_regs.h"
|
||||
#include "intel_alpm.h"
|
||||
#include "intel_bo.h"
|
||||
#include "intel_crtc.h"
|
||||
@ -730,11 +732,12 @@ static bool
|
||||
intel_lpsp_power_well_enabled(struct drm_i915_private *i915,
|
||||
enum i915_power_well_id power_well_id)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
intel_wakeref_t wakeref;
|
||||
bool is_enabled;
|
||||
|
||||
wakeref = intel_runtime_pm_get(&i915->runtime_pm);
|
||||
is_enabled = intel_display_power_well_is_enabled(i915,
|
||||
is_enabled = intel_display_power_well_is_enabled(display,
|
||||
power_well_id);
|
||||
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
|
||||
|
||||
@ -1012,6 +1015,8 @@ static int i915_dsc_fec_support_show(struct seq_file *m, void *data)
|
||||
DP_DSC_YCbCr444)));
|
||||
seq_printf(m, "DSC_Sink_BPP_Precision: %d\n",
|
||||
drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd));
|
||||
seq_printf(m, "DSC_Sink_Max_Slice_Count: %d\n",
|
||||
drm_dp_dsc_sink_max_slice_count((connector->dp.dsc_dpcd), intel_dp_is_edp(intel_dp)));
|
||||
seq_printf(m, "Force_DSC_Enable: %s\n",
|
||||
str_yes_no(intel_dp->force_dsc_en));
|
||||
if (!intel_dp_is_edp(intel_dp))
|
||||
@ -1331,7 +1336,7 @@ static ssize_t i915_joiner_write(struct file *file,
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct intel_connector *connector = m->private;
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
int force_joined_pipes = 0;
|
||||
int ret;
|
||||
|
||||
@ -1349,7 +1354,7 @@ static ssize_t i915_joiner_write(struct file *file,
|
||||
connector->force_joined_pipes = force_joined_pipes;
|
||||
break;
|
||||
case 4:
|
||||
if (HAS_ULTRAJOINER(i915)) {
|
||||
if (HAS_ULTRAJOINER(display)) {
|
||||
connector->force_joined_pipes = force_joined_pipes;
|
||||
break;
|
||||
}
|
||||
|
@ -7,9 +7,10 @@
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_file.h>
|
||||
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_debugfs_params.h"
|
||||
#include "i915_drv.h"
|
||||
#include "intel_display_params.h"
|
||||
|
||||
/* int param */
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "intel_display_params.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_reg_defs.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_fbc.h"
|
||||
#include "intel_step.h"
|
||||
|
||||
@ -252,6 +253,7 @@ static const struct intel_display_device_info no_display = {};
|
||||
|
||||
static const struct platform_desc i830_desc = {
|
||||
PLATFORM(i830),
|
||||
PLATFORM_GROUP(mobile),
|
||||
.info = &(const struct intel_display_device_info) {
|
||||
I830_DISPLAY,
|
||||
|
||||
@ -270,6 +272,7 @@ static const struct platform_desc i845_desc = {
|
||||
|
||||
static const struct platform_desc i85x_desc = {
|
||||
PLATFORM(i85x),
|
||||
PLATFORM_GROUP(mobile),
|
||||
.info = &(const struct intel_display_device_info) {
|
||||
I830_DISPLAY,
|
||||
|
||||
@ -312,6 +315,7 @@ static const struct platform_desc i915g_desc = {
|
||||
|
||||
static const struct platform_desc i915gm_desc = {
|
||||
PLATFORM(i915gm),
|
||||
PLATFORM_GROUP(mobile),
|
||||
.info = &(const struct intel_display_device_info) {
|
||||
GEN3_DISPLAY,
|
||||
I9XX_COLORS,
|
||||
@ -336,6 +340,7 @@ static const struct platform_desc i945g_desc = {
|
||||
|
||||
static const struct platform_desc i945gm_desc = {
|
||||
PLATFORM(i915gm),
|
||||
PLATFORM_GROUP(mobile),
|
||||
.info = &(const struct intel_display_device_info) {
|
||||
GEN3_DISPLAY,
|
||||
I9XX_COLORS,
|
||||
@ -357,13 +362,21 @@ static const struct platform_desc g33_desc = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct platform_desc pnv_desc = {
|
||||
static const struct intel_display_device_info pnv_display = {
|
||||
GEN3_DISPLAY,
|
||||
I9XX_COLORS,
|
||||
.has_hotplug = 1,
|
||||
};
|
||||
|
||||
static const struct platform_desc pnv_g_desc = {
|
||||
PLATFORM(pineview),
|
||||
.info = &(const struct intel_display_device_info) {
|
||||
GEN3_DISPLAY,
|
||||
I9XX_COLORS,
|
||||
.has_hotplug = 1,
|
||||
},
|
||||
.info = &pnv_display,
|
||||
};
|
||||
|
||||
static const struct platform_desc pnv_m_desc = {
|
||||
PLATFORM(pineview),
|
||||
PLATFORM_GROUP(mobile),
|
||||
.info = &pnv_display,
|
||||
};
|
||||
|
||||
#define GEN4_DISPLAY \
|
||||
@ -390,6 +403,7 @@ static const struct platform_desc i965g_desc = {
|
||||
|
||||
static const struct platform_desc i965gm_desc = {
|
||||
PLATFORM(i965gm),
|
||||
PLATFORM_GROUP(mobile),
|
||||
.info = &(const struct intel_display_device_info) {
|
||||
GEN4_DISPLAY,
|
||||
.has_overlay = 1,
|
||||
@ -413,6 +427,7 @@ static const struct platform_desc g45_desc = {
|
||||
static const struct platform_desc gm45_desc = {
|
||||
PLATFORM(gm45),
|
||||
PLATFORM_GROUP(g4x),
|
||||
PLATFORM_GROUP(mobile),
|
||||
.info = &(const struct intel_display_device_info) {
|
||||
GEN4_DISPLAY,
|
||||
.supports_tv = 1,
|
||||
@ -443,6 +458,7 @@ static const struct platform_desc ilk_d_desc = {
|
||||
|
||||
static const struct platform_desc ilk_m_desc = {
|
||||
PLATFORM(ironlake),
|
||||
PLATFORM_GROUP(mobile),
|
||||
.info = &(const struct intel_display_device_info) {
|
||||
ILK_DISPLAY,
|
||||
|
||||
@ -450,38 +466,54 @@ static const struct platform_desc ilk_m_desc = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct platform_desc snb_desc = {
|
||||
PLATFORM(sandybridge),
|
||||
.info = &(const struct intel_display_device_info) {
|
||||
.has_hotplug = 1,
|
||||
I9XX_PIPE_OFFSETS,
|
||||
I9XX_CURSOR_OFFSETS,
|
||||
ILK_COLORS,
|
||||
static const struct intel_display_device_info snb_display = {
|
||||
.has_hotplug = 1,
|
||||
I9XX_PIPE_OFFSETS,
|
||||
I9XX_CURSOR_OFFSETS,
|
||||
ILK_COLORS,
|
||||
|
||||
.__runtime_defaults.ip.ver = 6,
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
},
|
||||
.__runtime_defaults.ip.ver = 6,
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
};
|
||||
|
||||
static const struct platform_desc ivb_desc = {
|
||||
PLATFORM(ivybridge),
|
||||
.info = &(const struct intel_display_device_info) {
|
||||
.has_hotplug = 1,
|
||||
IVB_PIPE_OFFSETS,
|
||||
IVB_CURSOR_OFFSETS,
|
||||
IVB_COLORS,
|
||||
static const struct platform_desc snb_d_desc = {
|
||||
PLATFORM(sandybridge),
|
||||
.info = &snb_display,
|
||||
};
|
||||
|
||||
.__runtime_defaults.ip.ver = 7,
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
},
|
||||
static const struct platform_desc snb_m_desc = {
|
||||
PLATFORM(sandybridge),
|
||||
PLATFORM_GROUP(mobile),
|
||||
.info = &snb_display,
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info ivb_display = {
|
||||
.has_hotplug = 1,
|
||||
IVB_PIPE_OFFSETS,
|
||||
IVB_CURSOR_OFFSETS,
|
||||
IVB_COLORS,
|
||||
|
||||
.__runtime_defaults.ip.ver = 7,
|
||||
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
|
||||
.__runtime_defaults.cpu_transcoder_mask =
|
||||
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
|
||||
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
|
||||
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
|
||||
};
|
||||
|
||||
static const struct platform_desc ivb_d_desc = {
|
||||
PLATFORM(ivybridge),
|
||||
.info = &ivb_display,
|
||||
};
|
||||
|
||||
static const struct platform_desc ivb_m_desc = {
|
||||
PLATFORM(ivybridge),
|
||||
PLATFORM_GROUP(mobile),
|
||||
.info = &ivb_display,
|
||||
};
|
||||
|
||||
static const struct platform_desc vlv_desc = {
|
||||
@ -1011,6 +1043,7 @@ static const enum intel_step dg1_steppings[] = {
|
||||
|
||||
static const struct platform_desc dg1_desc = {
|
||||
PLATFORM(dg1),
|
||||
PLATFORM_GROUP(dgfx),
|
||||
.info = &(const struct intel_display_device_info) {
|
||||
XE_D_DISPLAY,
|
||||
|
||||
@ -1238,6 +1271,7 @@ static const enum intel_step dg2_g12_steppings[] = {
|
||||
|
||||
static const struct platform_desc dg2_desc = {
|
||||
PLATFORM(dg2),
|
||||
PLATFORM_GROUP(dgfx),
|
||||
.subplatforms = (const struct subplatform_desc[]) {
|
||||
{
|
||||
SUBPLATFORM(dg2, g10),
|
||||
@ -1338,6 +1372,7 @@ static const struct platform_desc lnl_desc = {
|
||||
|
||||
static const struct platform_desc bmg_desc = {
|
||||
PLATFORM(battlemage),
|
||||
PLATFORM_GROUP(dgfx),
|
||||
};
|
||||
|
||||
static const struct platform_desc ptl_desc = {
|
||||
@ -1381,11 +1416,14 @@ static const struct {
|
||||
INTEL_I965GM_IDS(INTEL_DISPLAY_DEVICE, &i965gm_desc),
|
||||
INTEL_GM45_IDS(INTEL_DISPLAY_DEVICE, &gm45_desc),
|
||||
INTEL_G45_IDS(INTEL_DISPLAY_DEVICE, &g45_desc),
|
||||
INTEL_PNV_IDS(INTEL_DISPLAY_DEVICE, &pnv_desc),
|
||||
INTEL_PNV_G_IDS(INTEL_DISPLAY_DEVICE, &pnv_g_desc),
|
||||
INTEL_PNV_M_IDS(INTEL_DISPLAY_DEVICE, &pnv_m_desc),
|
||||
INTEL_ILK_D_IDS(INTEL_DISPLAY_DEVICE, &ilk_d_desc),
|
||||
INTEL_ILK_M_IDS(INTEL_DISPLAY_DEVICE, &ilk_m_desc),
|
||||
INTEL_SNB_IDS(INTEL_DISPLAY_DEVICE, &snb_desc),
|
||||
INTEL_IVB_IDS(INTEL_DISPLAY_DEVICE, &ivb_desc),
|
||||
INTEL_SNB_D_IDS(INTEL_DISPLAY_DEVICE, &snb_d_desc),
|
||||
INTEL_SNB_M_IDS(INTEL_DISPLAY_DEVICE, &snb_m_desc),
|
||||
INTEL_IVB_D_IDS(INTEL_DISPLAY_DEVICE, &ivb_d_desc),
|
||||
INTEL_IVB_M_IDS(INTEL_DISPLAY_DEVICE, &ivb_m_desc),
|
||||
INTEL_HSW_IDS(INTEL_DISPLAY_DEVICE, &hsw_desc),
|
||||
INTEL_VLV_IDS(INTEL_DISPLAY_DEVICE, &vlv_desc),
|
||||
INTEL_BDW_IDS(INTEL_DISPLAY_DEVICE, &bdw_desc),
|
||||
@ -1429,9 +1467,9 @@ static const struct {
|
||||
};
|
||||
|
||||
static const struct intel_display_device_info *
|
||||
probe_gmdid_display(struct drm_i915_private *i915, struct intel_display_ip_ver *ip_ver)
|
||||
probe_gmdid_display(struct intel_display *display, struct intel_display_ip_ver *ip_ver)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
|
||||
struct pci_dev *pdev = to_pci_dev(display->drm->dev);
|
||||
struct intel_display_ip_ver gmd_id;
|
||||
void __iomem *addr;
|
||||
u32 val;
|
||||
@ -1439,7 +1477,8 @@ probe_gmdid_display(struct drm_i915_private *i915, struct intel_display_ip_ver *
|
||||
|
||||
addr = pci_iomap_range(pdev, 0, i915_mmio_reg_offset(GMD_ID_DISPLAY), sizeof(u32));
|
||||
if (!addr) {
|
||||
drm_err(&i915->drm, "Cannot map MMIO BAR to read display GMD_ID\n");
|
||||
drm_err(display->drm,
|
||||
"Cannot map MMIO BAR to read display GMD_ID\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1447,7 +1486,7 @@ probe_gmdid_display(struct drm_i915_private *i915, struct intel_display_ip_ver *
|
||||
pci_iounmap(pdev, addr);
|
||||
|
||||
if (val == 0) {
|
||||
drm_dbg_kms(&i915->drm, "Device doesn't have display\n");
|
||||
drm_dbg_kms(display->drm, "Device doesn't have display\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1463,7 +1502,8 @@ probe_gmdid_display(struct drm_i915_private *i915, struct intel_display_ip_ver *
|
||||
}
|
||||
}
|
||||
|
||||
drm_err(&i915->drm, "Unrecognized display IP version %d.%02d; disabling display.\n",
|
||||
drm_err(display->drm,
|
||||
"Unrecognized display IP version %d.%02d; disabling display.\n",
|
||||
gmd_id.ver, gmd_id.rel);
|
||||
return NULL;
|
||||
}
|
||||
@ -1564,10 +1604,9 @@ static void display_platforms_or(struct intel_display_platforms *dst,
|
||||
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 *intel_display_device_probe(struct pci_dev *pdev)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
|
||||
struct intel_display *display = to_intel_display(pdev);
|
||||
const struct intel_display_device_info *info;
|
||||
struct intel_display_ip_ver ip_ver = {};
|
||||
const struct platform_desc *desc;
|
||||
@ -1575,55 +1614,56 @@ void intel_display_device_probe(struct drm_i915_private *i915)
|
||||
enum intel_step step;
|
||||
|
||||
/* Add drm device backpointer as early as possible. */
|
||||
i915->display.drm = &i915->drm;
|
||||
display->drm = pci_get_drvdata(pdev);
|
||||
|
||||
intel_display_params_copy(&i915->display.params);
|
||||
intel_display_params_copy(&display->params);
|
||||
|
||||
if (has_no_display(pdev)) {
|
||||
drm_dbg_kms(&i915->drm, "Device doesn't have display\n");
|
||||
drm_dbg_kms(display->drm, "Device doesn't have display\n");
|
||||
goto no_display;
|
||||
}
|
||||
|
||||
desc = find_platform_desc(pdev);
|
||||
if (!desc) {
|
||||
drm_dbg_kms(&i915->drm, "Unknown device ID %04x; disabling display.\n",
|
||||
drm_dbg_kms(display->drm,
|
||||
"Unknown device ID %04x; disabling display.\n",
|
||||
pdev->device);
|
||||
goto no_display;
|
||||
}
|
||||
|
||||
info = desc->info;
|
||||
if (!info)
|
||||
info = probe_gmdid_display(i915, &ip_ver);
|
||||
info = probe_gmdid_display(display, &ip_ver);
|
||||
if (!info)
|
||||
goto no_display;
|
||||
|
||||
DISPLAY_INFO(i915) = info;
|
||||
DISPLAY_INFO(display) = info;
|
||||
|
||||
memcpy(DISPLAY_RUNTIME_INFO(i915),
|
||||
&DISPLAY_INFO(i915)->__runtime_defaults,
|
||||
sizeof(*DISPLAY_RUNTIME_INFO(i915)));
|
||||
memcpy(DISPLAY_RUNTIME_INFO(display),
|
||||
&DISPLAY_INFO(display)->__runtime_defaults,
|
||||
sizeof(*DISPLAY_RUNTIME_INFO(display)));
|
||||
|
||||
drm_WARN_ON(&i915->drm, !desc->name ||
|
||||
drm_WARN_ON(display->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->name ||
|
||||
drm_WARN_ON(display->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,
|
||||
drm_WARN_ON(display->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) {
|
||||
DISPLAY_RUNTIME_INFO(i915)->ip = ip_ver;
|
||||
DISPLAY_RUNTIME_INFO(display)->ip = ip_ver;
|
||||
step = STEP_A0 + ip_ver.step;
|
||||
if (step > STEP_FUTURE) {
|
||||
drm_dbg_kms(display->drm, "Using future display stepping\n");
|
||||
@ -1634,29 +1674,32 @@ void intel_display_device_probe(struct drm_i915_private *i915)
|
||||
subdesc ? &subdesc->step_info : NULL);
|
||||
}
|
||||
|
||||
DISPLAY_RUNTIME_INFO(i915)->step = step;
|
||||
DISPLAY_RUNTIME_INFO(display)->step = step;
|
||||
|
||||
drm_info(&i915->drm, "Found %s%s%s (device ID %04x) display version %u.%02u stepping %s\n",
|
||||
drm_info(display->drm, "Found %s%s%s (device ID %04x) %s display version %u.%02u stepping %s\n",
|
||||
desc->name, subdesc ? "/" : "", subdesc ? subdesc->name : "",
|
||||
pdev->device, DISPLAY_RUNTIME_INFO(i915)->ip.ver,
|
||||
DISPLAY_RUNTIME_INFO(i915)->ip.rel,
|
||||
pdev->device, display->platform.dgfx ? "discrete" : "integrated",
|
||||
DISPLAY_RUNTIME_INFO(display)->ip.ver,
|
||||
DISPLAY_RUNTIME_INFO(display)->ip.rel,
|
||||
step != STEP_NONE ? intel_step_name(step) : "N/A");
|
||||
|
||||
return;
|
||||
return display;
|
||||
|
||||
no_display:
|
||||
DISPLAY_INFO(i915) = &no_display;
|
||||
DISPLAY_INFO(display) = &no_display;
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
void intel_display_device_remove(struct drm_i915_private *i915)
|
||||
void intel_display_device_remove(struct intel_display *display)
|
||||
{
|
||||
intel_display_params_free(&i915->display.params);
|
||||
intel_display_params_free(&display->params);
|
||||
}
|
||||
|
||||
static void __intel_display_device_info_runtime_init(struct drm_i915_private *i915)
|
||||
static void __intel_display_device_info_runtime_init(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(i915);
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(display);
|
||||
enum pipe pipe;
|
||||
|
||||
BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->pipe_mask) < I915_MAX_PIPES);
|
||||
@ -1664,35 +1707,35 @@ static void __intel_display_device_info_runtime_init(struct drm_i915_private *i9
|
||||
BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->port_mask) < I915_MAX_PORTS);
|
||||
|
||||
/* This covers both ULT and ULX */
|
||||
if (IS_HASWELL_ULT(i915) || IS_BROADWELL_ULT(i915))
|
||||
if (display->platform.haswell_ult || display->platform.broadwell_ult)
|
||||
display_runtime->port_mask &= ~BIT(PORT_D);
|
||||
|
||||
if (IS_ICL_WITH_PORT_F(i915))
|
||||
if (display->platform.icelake_port_f)
|
||||
display_runtime->port_mask |= BIT(PORT_F);
|
||||
|
||||
/* Wa_14011765242: adl-s A0,A1 */
|
||||
if (IS_ALDERLAKE_S(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_A2))
|
||||
for_each_pipe(i915, pipe)
|
||||
if (display->platform.alderlake_s && IS_DISPLAY_STEP(display, STEP_A0, STEP_A2))
|
||||
for_each_pipe(display, pipe)
|
||||
display_runtime->num_scalers[pipe] = 0;
|
||||
else if (DISPLAY_VER(i915) >= 11) {
|
||||
for_each_pipe(i915, pipe)
|
||||
else if (DISPLAY_VER(display) >= 11) {
|
||||
for_each_pipe(display, pipe)
|
||||
display_runtime->num_scalers[pipe] = 2;
|
||||
} else if (DISPLAY_VER(i915) >= 9) {
|
||||
} else if (DISPLAY_VER(display) >= 9) {
|
||||
display_runtime->num_scalers[PIPE_A] = 2;
|
||||
display_runtime->num_scalers[PIPE_B] = 2;
|
||||
display_runtime->num_scalers[PIPE_C] = 1;
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(i915) >= 13 || HAS_D12_PLANE_MINIMIZATION(i915))
|
||||
for_each_pipe(i915, pipe)
|
||||
if (DISPLAY_VER(display) >= 13 || HAS_D12_PLANE_MINIMIZATION(display))
|
||||
for_each_pipe(display, pipe)
|
||||
display_runtime->num_sprites[pipe] = 4;
|
||||
else if (DISPLAY_VER(i915) >= 11)
|
||||
for_each_pipe(i915, pipe)
|
||||
else if (DISPLAY_VER(display) >= 11)
|
||||
for_each_pipe(display, pipe)
|
||||
display_runtime->num_sprites[pipe] = 6;
|
||||
else if (DISPLAY_VER(i915) == 10)
|
||||
for_each_pipe(i915, pipe)
|
||||
else if (DISPLAY_VER(display) == 10)
|
||||
for_each_pipe(display, pipe)
|
||||
display_runtime->num_sprites[pipe] = 3;
|
||||
else if (IS_BROXTON(i915)) {
|
||||
else if (display->platform.broxton) {
|
||||
/*
|
||||
* Skylake and Broxton currently don't expose the topmost plane as its
|
||||
* use is exclusive with the legacy cursor and we only want to expose
|
||||
@ -1705,23 +1748,23 @@ static void __intel_display_device_info_runtime_init(struct drm_i915_private *i9
|
||||
display_runtime->num_sprites[PIPE_A] = 2;
|
||||
display_runtime->num_sprites[PIPE_B] = 2;
|
||||
display_runtime->num_sprites[PIPE_C] = 1;
|
||||
} else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
|
||||
for_each_pipe(i915, pipe)
|
||||
} else if (display->platform.valleyview || display->platform.cherryview) {
|
||||
for_each_pipe(display, pipe)
|
||||
display_runtime->num_sprites[pipe] = 2;
|
||||
} else if (DISPLAY_VER(i915) >= 5 || IS_G4X(i915)) {
|
||||
for_each_pipe(i915, pipe)
|
||||
} else if (DISPLAY_VER(display) >= 5 || display->platform.g4x) {
|
||||
for_each_pipe(display, pipe)
|
||||
display_runtime->num_sprites[pipe] = 1;
|
||||
}
|
||||
|
||||
if ((IS_DGFX(i915) || DISPLAY_VER(i915) >= 14) &&
|
||||
!(intel_de_read(i915, GU_CNTL_PROTECTED) & DEPRESENT)) {
|
||||
drm_info(&i915->drm, "Display not present, disabling\n");
|
||||
if ((display->platform.dgfx || DISPLAY_VER(display) >= 14) &&
|
||||
!(intel_de_read(display, GU_CNTL_PROTECTED) & DEPRESENT)) {
|
||||
drm_info(display->drm, "Display not present, disabling\n");
|
||||
goto display_fused_off;
|
||||
}
|
||||
|
||||
if (IS_DISPLAY_VER(i915, 7, 8) && HAS_PCH_SPLIT(i915)) {
|
||||
u32 fuse_strap = intel_de_read(i915, FUSE_STRAP);
|
||||
u32 sfuse_strap = intel_de_read(i915, SFUSE_STRAP);
|
||||
if (IS_DISPLAY_VER(display, 7, 8) && HAS_PCH_SPLIT(i915)) {
|
||||
u32 fuse_strap = intel_de_read(display, FUSE_STRAP);
|
||||
u32 sfuse_strap = intel_de_read(display, SFUSE_STRAP);
|
||||
|
||||
/*
|
||||
* SFUSE_STRAP is supposed to have a bit signalling the display
|
||||
@ -1736,16 +1779,16 @@ static void __intel_display_device_info_runtime_init(struct drm_i915_private *i9
|
||||
sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
|
||||
(HAS_PCH_CPT(i915) &&
|
||||
!(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
|
||||
drm_info(&i915->drm,
|
||||
drm_info(display->drm,
|
||||
"Display fused off, disabling\n");
|
||||
goto display_fused_off;
|
||||
} else if (fuse_strap & IVB_PIPE_C_DISABLE) {
|
||||
drm_info(&i915->drm, "PipeC fused off\n");
|
||||
drm_info(display->drm, "PipeC fused off\n");
|
||||
display_runtime->pipe_mask &= ~BIT(PIPE_C);
|
||||
display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
|
||||
}
|
||||
} else if (DISPLAY_VER(i915) >= 9) {
|
||||
u32 dfsm = intel_de_read(i915, SKL_DFSM);
|
||||
} else if (DISPLAY_VER(display) >= 9) {
|
||||
u32 dfsm = intel_de_read(display, SKL_DFSM);
|
||||
|
||||
if (dfsm & SKL_DFSM_PIPE_A_DISABLE) {
|
||||
display_runtime->pipe_mask &= ~BIT(PIPE_A);
|
||||
@ -1763,7 +1806,7 @@ static void __intel_display_device_info_runtime_init(struct drm_i915_private *i9
|
||||
display_runtime->fbc_mask &= ~BIT(INTEL_FBC_C);
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(i915) >= 12 &&
|
||||
if (DISPLAY_VER(display) >= 12 &&
|
||||
(dfsm & TGL_DFSM_PIPE_D_DISABLE)) {
|
||||
display_runtime->pipe_mask &= ~BIT(PIPE_D);
|
||||
display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_D);
|
||||
@ -1776,15 +1819,15 @@ 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 (IS_DG2(i915) || DISPLAY_VER(i915) < 13) {
|
||||
if (display->platform.dg2 || DISPLAY_VER(display) < 13) {
|
||||
if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE)
|
||||
display_runtime->fbc_mask = 0;
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(i915) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE))
|
||||
if (DISPLAY_VER(display) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE))
|
||||
display_runtime->has_dmc = 0;
|
||||
|
||||
if (IS_DISPLAY_VER(i915, 10, 12) &&
|
||||
if (IS_DISPLAY_VER(display, 10, 12) &&
|
||||
(dfsm & GLK_DFSM_DISPLAY_DSC_DISABLE))
|
||||
display_runtime->has_dsc = 0;
|
||||
|
||||
@ -1793,8 +1836,8 @@ static void __intel_display_device_info_runtime_init(struct drm_i915_private *i9
|
||||
display_runtime->has_dbuf_overlap_detection = false;
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(i915) >= 20) {
|
||||
u32 cap = intel_de_read(i915, XE2LPD_DE_CAP);
|
||||
if (DISPLAY_VER(display) >= 20) {
|
||||
u32 cap = intel_de_read(display, XE2LPD_DE_CAP);
|
||||
|
||||
if (REG_FIELD_GET(XE2LPD_DE_CAP_DSC_MASK, cap) ==
|
||||
XE2LPD_DE_CAP_DSC_REMOVED)
|
||||
@ -1802,18 +1845,19 @@ static void __intel_display_device_info_runtime_init(struct drm_i915_private *i9
|
||||
|
||||
if (REG_FIELD_GET(XE2LPD_DE_CAP_SCALER_MASK, cap) ==
|
||||
XE2LPD_DE_CAP_SCALER_SINGLE) {
|
||||
for_each_pipe(i915, pipe)
|
||||
for_each_pipe(display, pipe)
|
||||
if (display_runtime->num_scalers[pipe])
|
||||
display_runtime->num_scalers[pipe] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(i915) >= 30)
|
||||
if (DISPLAY_VER(display) >= 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);
|
||||
drm_dbg_kms(display->drm, "rawclk rate: %d kHz\n",
|
||||
display_runtime->rawclk_freq);
|
||||
|
||||
return;
|
||||
|
||||
@ -1821,21 +1865,21 @@ static void __intel_display_device_info_runtime_init(struct drm_i915_private *i9
|
||||
memset(display_runtime, 0, sizeof(*display_runtime));
|
||||
}
|
||||
|
||||
void intel_display_device_info_runtime_init(struct drm_i915_private *i915)
|
||||
void intel_display_device_info_runtime_init(struct intel_display *display)
|
||||
{
|
||||
if (HAS_DISPLAY(i915))
|
||||
__intel_display_device_info_runtime_init(i915);
|
||||
if (HAS_DISPLAY(display))
|
||||
__intel_display_device_info_runtime_init(display);
|
||||
|
||||
/* Display may have been disabled by runtime init */
|
||||
if (!HAS_DISPLAY(i915)) {
|
||||
i915->drm.driver_features &= ~(DRIVER_MODESET | DRIVER_ATOMIC);
|
||||
i915->display.info.__device_info = &no_display;
|
||||
if (!HAS_DISPLAY(display)) {
|
||||
display->drm->driver_features &= ~(DRIVER_MODESET | DRIVER_ATOMIC);
|
||||
display->info.__device_info = &no_display;
|
||||
}
|
||||
|
||||
/* Disable nuclear pageflip by default on pre-g4x */
|
||||
if (!i915->display.params.nuclear_pageflip &&
|
||||
DISPLAY_VER(i915) < 5 && !IS_G4X(i915))
|
||||
i915->drm.driver_features &= ~DRIVER_ATOMIC;
|
||||
if (!display->params.nuclear_pageflip &&
|
||||
DISPLAY_VER(display) < 5 && !display->platform.g4x)
|
||||
display->drm->driver_features &= ~DRIVER_ATOMIC;
|
||||
}
|
||||
|
||||
void intel_display_device_info_print(const struct intel_display_device_info *info,
|
||||
@ -1872,10 +1916,8 @@ void intel_display_device_info_print(const struct intel_display_device_info *inf
|
||||
* Disabling display means taking over the display hardware, putting it to
|
||||
* sleep, and preventing connectors from being connected via any means.
|
||||
*/
|
||||
bool intel_display_device_enabled(struct drm_i915_private *i915)
|
||||
bool intel_display_device_enabled(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
|
||||
/* Only valid when HAS_DISPLAY() is true */
|
||||
drm_WARN_ON(display->drm, !HAS_DISPLAY(display));
|
||||
|
||||
|
@ -12,8 +12,9 @@
|
||||
#include "intel_display_conversion.h"
|
||||
#include "intel_display_limits.h"
|
||||
|
||||
struct drm_i915_private;
|
||||
struct drm_printer;
|
||||
struct intel_display;
|
||||
struct pci_dev;
|
||||
|
||||
/*
|
||||
* Display platforms and subplatforms. Keep platforms in display version based
|
||||
@ -21,6 +22,10 @@ struct drm_printer;
|
||||
* platform.
|
||||
*/
|
||||
#define INTEL_DISPLAY_PLATFORMS(func) \
|
||||
/* Platform group aliases */ \
|
||||
func(g4x) /* g45 and gm45 */ \
|
||||
func(mobile) /* mobile platforms */ \
|
||||
func(dgfx) /* discrete graphics */ \
|
||||
/* Display ver 2 */ \
|
||||
func(i830) \
|
||||
func(i845g) \
|
||||
@ -38,7 +43,6 @@ struct drm_printer;
|
||||
func(i965gm) \
|
||||
func(g45) \
|
||||
func(gm45) \
|
||||
func(g4x) /* group alias for g45 and gm45 */ \
|
||||
/* Display ver 5 */ \
|
||||
func(ironlake) \
|
||||
/* Display ver 6 */ \
|
||||
@ -136,61 +140,64 @@ struct intel_display_platforms {
|
||||
func(overlay_needs_physical); \
|
||||
func(supports_tv);
|
||||
|
||||
#define HAS_4TILE(i915) (IS_DG2(i915) || DISPLAY_VER(i915) >= 14)
|
||||
#define HAS_ASYNC_FLIPS(i915) (DISPLAY_VER(i915) >= 5)
|
||||
#define HAS_BIGJOINER(i915) (DISPLAY_VER(i915) >= 11 && HAS_DSC(i915))
|
||||
#define HAS_CDCLK_CRAWL(i915) (DISPLAY_INFO(i915)->has_cdclk_crawl)
|
||||
#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)
|
||||
#define HAS_DOUBLE_BUFFERED_M_N(i915) (DISPLAY_VER(i915) >= 9 || IS_BROADWELL(i915))
|
||||
#define HAS_DP_MST(i915) (DISPLAY_INFO(i915)->has_dp_mst)
|
||||
#define HAS_DP20(i915) (IS_DG2(i915) || DISPLAY_VER(i915) >= 14)
|
||||
#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)
|
||||
#define HAS_GMBUS_IRQ(i915) (DISPLAY_VER(i915) >= 4)
|
||||
#define HAS_GMBUS_BURST_READ(i915) (DISPLAY_VER(i915) >= 10 || IS_KABYLAKE(i915))
|
||||
#define HAS_GMCH(i915) (DISPLAY_INFO(i915)->has_gmch)
|
||||
#define HAS_HW_SAGV_WM(i915) (DISPLAY_VER(i915) >= 13 && !IS_DGFX(i915))
|
||||
#define HAS_IPC(i915) (DISPLAY_INFO(i915)->has_ipc)
|
||||
#define HAS_IPS(i915) (IS_HASWELL_ULT(i915) || IS_BROADWELL(i915))
|
||||
#define HAS_LRR(i915) (DISPLAY_VER(i915) >= 12)
|
||||
#define HAS_LSPCON(i915) (IS_DISPLAY_VER(i915, 9, 10))
|
||||
#define HAS_MBUS_JOINING(i915) (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14)
|
||||
#define HAS_MSO(i915) (DISPLAY_VER(i915) >= 12)
|
||||
#define HAS_OVERLAY(i915) (DISPLAY_INFO(i915)->has_overlay)
|
||||
#define HAS_PSR(i915) (DISPLAY_INFO(i915)->has_psr)
|
||||
#define HAS_PSR_HW_TRACKING(i915) (DISPLAY_INFO(i915)->has_psr_hw_tracking)
|
||||
#define HAS_PSR2_SEL_FETCH(i915) (DISPLAY_VER(i915) >= 12)
|
||||
#define HAS_SAGV(i915) (DISPLAY_VER(i915) >= 9 && !IS_BROXTON(i915) && !IS_GEMINILAKE(i915))
|
||||
#define HAS_TRANSCODER(i915, trans) ((DISPLAY_RUNTIME_INFO(i915)->cpu_transcoder_mask & \
|
||||
BIT(trans)) != 0)
|
||||
#define HAS_UNCOMPRESSED_JOINER(i915) (DISPLAY_VER(i915) >= 13)
|
||||
#define HAS_ULTRAJOINER(i915) ((DISPLAY_VER(i915) >= 20 || \
|
||||
(IS_DGFX(i915) && DISPLAY_VER(i915) == 14)) && \
|
||||
HAS_DSC(i915))
|
||||
#define HAS_VRR(i915) (DISPLAY_VER(i915) >= 11)
|
||||
#define HAS_AS_SDP(i915) (DISPLAY_VER(i915) >= 13)
|
||||
#define HAS_CMRR(i915) (DISPLAY_VER(i915) >= 20)
|
||||
#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)
|
||||
#define SUPPORTS_TV(i915) (DISPLAY_INFO(i915)->supports_tv)
|
||||
#define HAS_4TILE(__display) ((__display)->platform.dg2 || DISPLAY_VER(__display) >= 14)
|
||||
#define HAS_ASYNC_FLIPS(__display) (DISPLAY_VER(__display) >= 5)
|
||||
#define HAS_BIGJOINER(__display) (DISPLAY_VER(__display) >= 11 && HAS_DSC(__display))
|
||||
#define HAS_CDCLK_CRAWL(__display) (DISPLAY_INFO(__display)->has_cdclk_crawl)
|
||||
#define HAS_CDCLK_SQUASH(__display) (DISPLAY_INFO(__display)->has_cdclk_squash)
|
||||
#define HAS_CUR_FBC(__display) (!HAS_GMCH(__display) && IS_DISPLAY_VER(__display, 7, 13))
|
||||
#define HAS_D12_PLANE_MINIMIZATION(__display) ((__display)->platform.rocketlake || (__display)->platform.alderlake_s)
|
||||
#define HAS_DBUF_OVERLAP_DETECTION(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dbuf_overlap_detection)
|
||||
#define HAS_DDI(__display) (DISPLAY_INFO(__display)->has_ddi)
|
||||
#define HAS_DISPLAY(__display) (DISPLAY_RUNTIME_INFO(__display)->pipe_mask != 0)
|
||||
#define HAS_DMC(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dmc)
|
||||
#define HAS_DMC_WAKELOCK(__display) (DISPLAY_VER(__display) >= 20)
|
||||
#define HAS_DOUBLE_BUFFERED_M_N(__display) (DISPLAY_VER(__display) >= 9 || (__display)->platform.broadwell)
|
||||
#define HAS_DOUBLE_WIDE(__display) (DISPLAY_VER(__display) < 4)
|
||||
#define HAS_DP_MST(__display) (DISPLAY_INFO(__display)->has_dp_mst)
|
||||
#define HAS_DP20(__display) ((__display)->platform.dg2 || DISPLAY_VER(__display) >= 14)
|
||||
#define HAS_DPT(__display) (DISPLAY_VER(__display) >= 13)
|
||||
#define HAS_DSB(__display) (DISPLAY_INFO(__display)->has_dsb)
|
||||
#define HAS_DSC(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dsc)
|
||||
#define HAS_DSC_MST(__display) (DISPLAY_VER(__display) >= 12 && HAS_DSC(__display))
|
||||
#define HAS_FBC(__display) (DISPLAY_RUNTIME_INFO(__display)->fbc_mask != 0)
|
||||
#define HAS_FPGA_DBG_UNCLAIMED(__display) (DISPLAY_INFO(__display)->has_fpga_dbg)
|
||||
#define HAS_FW_BLC(__display) (DISPLAY_VER(__display) >= 3)
|
||||
#define HAS_GMBUS_IRQ(__display) (DISPLAY_VER(__display) >= 4)
|
||||
#define HAS_GMBUS_BURST_READ(__display) (DISPLAY_VER(__display) >= 10 || (__display)->platform.kabylake)
|
||||
#define HAS_GMCH(__display) (DISPLAY_INFO(__display)->has_gmch)
|
||||
#define HAS_HW_SAGV_WM(__display) (DISPLAY_VER(__display) >= 13 && !(__display)->platform.dgfx)
|
||||
#define HAS_IPC(__display) (DISPLAY_INFO(__display)->has_ipc)
|
||||
#define HAS_IPS(__display) ((__display)->platform.haswell_ult || (__display)->platform.broadwell)
|
||||
#define HAS_LRR(__display) (DISPLAY_VER(__display) >= 12)
|
||||
#define HAS_LSPCON(__display) (IS_DISPLAY_VER(__display, 9, 10))
|
||||
#define HAS_MBUS_JOINING(__display) ((__display)->platform.alderlake_p || DISPLAY_VER(__display) >= 14)
|
||||
#define HAS_MSO(__display) (DISPLAY_VER(__display) >= 12)
|
||||
#define HAS_OVERLAY(__display) (DISPLAY_INFO(__display)->has_overlay)
|
||||
#define HAS_PSR(__display) (DISPLAY_INFO(__display)->has_psr)
|
||||
#define HAS_PSR_HW_TRACKING(__display) (DISPLAY_INFO(__display)->has_psr_hw_tracking)
|
||||
#define HAS_PSR2_SEL_FETCH(__display) (DISPLAY_VER(__display) >= 12)
|
||||
#define HAS_SAGV(__display) (DISPLAY_VER(__display) >= 9 && \
|
||||
!(__display)->platform.broxton && !(__display)->platform.geminilake)
|
||||
#define HAS_TRANSCODER(__display, trans) ((DISPLAY_RUNTIME_INFO(__display)->cpu_transcoder_mask & \
|
||||
BIT(trans)) != 0)
|
||||
#define HAS_UNCOMPRESSED_JOINER(__display) (DISPLAY_VER(__display) >= 13)
|
||||
#define HAS_ULTRAJOINER(__display) ((DISPLAY_VER(__display) >= 20 || \
|
||||
((__display)->platform.dgfx && DISPLAY_VER(__display) == 14)) && \
|
||||
HAS_DSC(__display))
|
||||
#define HAS_VRR(__display) (DISPLAY_VER(__display) >= 11)
|
||||
#define HAS_AS_SDP(__display) (DISPLAY_VER(__display) >= 13)
|
||||
#define HAS_CMRR(__display) (DISPLAY_VER(__display) >= 20)
|
||||
#define INTEL_NUM_PIPES(__display) (hweight8(DISPLAY_RUNTIME_INFO(__display)->pipe_mask))
|
||||
#define I915_HAS_HOTPLUG(__display) (DISPLAY_INFO(__display)->has_hotplug)
|
||||
#define OVERLAY_NEEDS_PHYSICAL(__display) (DISPLAY_INFO(__display)->overlay_needs_physical)
|
||||
#define SUPPORTS_TV(__display) (DISPLAY_INFO(__display)->supports_tv)
|
||||
|
||||
/* Check that device has a display IP version within the specific range. */
|
||||
#define IS_DISPLAY_VERx100(__i915, from, until) ( \
|
||||
#define IS_DISPLAY_VERx100(__display, from, until) ( \
|
||||
BUILD_BUG_ON_ZERO((from) < 200) + \
|
||||
(DISPLAY_VERx100(__i915) >= (from) && \
|
||||
DISPLAY_VERx100(__i915) <= (until)))
|
||||
(DISPLAY_VERx100(__display) >= (from) && \
|
||||
DISPLAY_VERx100(__display) <= (until)))
|
||||
|
||||
/*
|
||||
* Check if a device has a specific IP version as well as a stepping within the
|
||||
@ -201,30 +208,30 @@ struct intel_display_platforms {
|
||||
* hardware fix is present and the software workaround is no longer necessary.
|
||||
* E.g.,
|
||||
*
|
||||
* IS_DISPLAY_VERx100_STEP(i915, 1400, STEP_A0, STEP_B2)
|
||||
* IS_DISPLAY_VERx100_STEP(i915, 1400, STEP_C0, STEP_FOREVER)
|
||||
* IS_DISPLAY_VERx100_STEP(display, 1400, STEP_A0, STEP_B2)
|
||||
* IS_DISPLAY_VERx100_STEP(display, 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_VERx100_STEP(__i915, ipver, from, until) \
|
||||
(IS_DISPLAY_VERx100((__i915), (ipver), (ipver)) && \
|
||||
IS_DISPLAY_STEP((__i915), (from), (until)))
|
||||
#define IS_DISPLAY_VERx100_STEP(__display, ipver, from, until) \
|
||||
(IS_DISPLAY_VERx100((__display), (ipver), (ipver)) && \
|
||||
IS_DISPLAY_STEP((__display), (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_INFO(__display) (__to_intel_display(__display)->info.__device_info)
|
||||
#define DISPLAY_RUNTIME_INFO(__display) (&__to_intel_display(__display)->info.__runtime_info)
|
||||
|
||||
#define DISPLAY_VER(i915) (DISPLAY_RUNTIME_INFO(i915)->ip.ver)
|
||||
#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))
|
||||
#define DISPLAY_VER(__display) (DISPLAY_RUNTIME_INFO(__display)->ip.ver)
|
||||
#define DISPLAY_VERx100(__display) (DISPLAY_RUNTIME_INFO(__display)->ip.ver * 100 + \
|
||||
DISPLAY_RUNTIME_INFO(__display)->ip.rel)
|
||||
#define IS_DISPLAY_VER(__display, from, until) \
|
||||
(DISPLAY_VER(__display) >= (from) && DISPLAY_VER(__display) <= (until))
|
||||
|
||||
#define INTEL_DISPLAY_STEP(__i915) (DISPLAY_RUNTIME_INFO(__i915)->step)
|
||||
#define INTEL_DISPLAY_STEP(__display) (DISPLAY_RUNTIME_INFO(__display)->step)
|
||||
|
||||
#define IS_DISPLAY_STEP(__i915, since, until) \
|
||||
(drm_WARN_ON(__to_intel_display(__i915)->drm, INTEL_DISPLAY_STEP(__i915) == STEP_NONE), \
|
||||
INTEL_DISPLAY_STEP(__i915) >= (since) && INTEL_DISPLAY_STEP(__i915) < (until))
|
||||
#define IS_DISPLAY_STEP(__display, since, until) \
|
||||
(drm_WARN_ON(__to_intel_display(__display)->drm, INTEL_DISPLAY_STEP(__display) == STEP_NONE), \
|
||||
INTEL_DISPLAY_STEP(__display) >= (since) && INTEL_DISPLAY_STEP(__display) < (until))
|
||||
|
||||
struct intel_display_runtime_info {
|
||||
struct intel_display_ip_ver {
|
||||
@ -283,10 +290,10 @@ struct intel_display_device_info {
|
||||
} color;
|
||||
};
|
||||
|
||||
bool intel_display_device_enabled(struct drm_i915_private *i915);
|
||||
void intel_display_device_probe(struct drm_i915_private *i915);
|
||||
void intel_display_device_remove(struct drm_i915_private *i915);
|
||||
void intel_display_device_info_runtime_init(struct drm_i915_private *i915);
|
||||
bool intel_display_device_enabled(struct intel_display *display);
|
||||
struct intel_display *intel_display_device_probe(struct pci_dev *pdev);
|
||||
void intel_display_device_remove(struct intel_display *display);
|
||||
void intel_display_device_info_runtime_init(struct intel_display *display);
|
||||
|
||||
void intel_display_device_info_print(const struct intel_display_device_info *info,
|
||||
const struct intel_display_runtime_info *runtime,
|
||||
|
@ -80,12 +80,12 @@ bool intel_display_driver_probe_defer(struct pci_dev *pdev)
|
||||
return false;
|
||||
}
|
||||
|
||||
void intel_display_driver_init_hw(struct drm_i915_private *i915)
|
||||
void intel_display_driver_init_hw(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct intel_cdclk_state *cdclk_state;
|
||||
|
||||
if (!HAS_DISPLAY(i915))
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
cdclk_state = to_intel_cdclk_state(display->cdclk.obj.state);
|
||||
@ -112,12 +112,12 @@ static const struct drm_mode_config_helper_funcs intel_mode_config_funcs = {
|
||||
.atomic_commit_setup = drm_dp_mst_atomic_setup_commit,
|
||||
};
|
||||
|
||||
static void intel_mode_config_init(struct drm_i915_private *i915)
|
||||
static void intel_mode_config_init(struct intel_display *display)
|
||||
{
|
||||
struct drm_mode_config *mode_config = &i915->drm.mode_config;
|
||||
struct drm_mode_config *mode_config = &display->drm->mode_config;
|
||||
|
||||
drm_mode_config_init(&i915->drm);
|
||||
INIT_LIST_HEAD(&i915->display.global.obj_list);
|
||||
drm_mode_config_init(display->drm);
|
||||
INIT_LIST_HEAD(&display->global.obj_list);
|
||||
|
||||
mode_config->min_width = 0;
|
||||
mode_config->min_height = 0;
|
||||
@ -128,19 +128,19 @@ static void intel_mode_config_init(struct drm_i915_private *i915)
|
||||
mode_config->funcs = &intel_mode_funcs;
|
||||
mode_config->helper_private = &intel_mode_config_funcs;
|
||||
|
||||
mode_config->async_page_flip = HAS_ASYNC_FLIPS(i915);
|
||||
mode_config->async_page_flip = HAS_ASYNC_FLIPS(display);
|
||||
|
||||
/*
|
||||
* Maximum framebuffer dimensions, chosen to match
|
||||
* the maximum render engine surface size on gen4+.
|
||||
*/
|
||||
if (DISPLAY_VER(i915) >= 7) {
|
||||
if (DISPLAY_VER(display) >= 7) {
|
||||
mode_config->max_width = 16384;
|
||||
mode_config->max_height = 16384;
|
||||
} else if (DISPLAY_VER(i915) >= 4) {
|
||||
} else if (DISPLAY_VER(display) >= 4) {
|
||||
mode_config->max_width = 8192;
|
||||
mode_config->max_height = 8192;
|
||||
} else if (DISPLAY_VER(i915) == 3) {
|
||||
} else if (DISPLAY_VER(display) == 3) {
|
||||
mode_config->max_width = 4096;
|
||||
mode_config->max_height = 4096;
|
||||
} else {
|
||||
@ -148,11 +148,11 @@ static void intel_mode_config_init(struct drm_i915_private *i915)
|
||||
mode_config->max_height = 2048;
|
||||
}
|
||||
|
||||
if (IS_I845G(i915) || IS_I865G(i915)) {
|
||||
mode_config->cursor_width = IS_I845G(i915) ? 64 : 512;
|
||||
if (display->platform.i845g || display->platform.i865g) {
|
||||
mode_config->cursor_width = display->platform.i845g ? 64 : 512;
|
||||
mode_config->cursor_height = 1023;
|
||||
} else if (IS_I830(i915) || IS_I85X(i915) ||
|
||||
IS_I915G(i915) || IS_I915GM(i915)) {
|
||||
} else if (display->platform.i830 || display->platform.i85x ||
|
||||
display->platform.i915g || display->platform.i915gm) {
|
||||
mode_config->cursor_width = 64;
|
||||
mode_config->cursor_height = 64;
|
||||
} else {
|
||||
@ -161,18 +161,19 @@ static void intel_mode_config_init(struct drm_i915_private *i915)
|
||||
}
|
||||
}
|
||||
|
||||
static void intel_mode_config_cleanup(struct drm_i915_private *i915)
|
||||
static void intel_mode_config_cleanup(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
intel_atomic_global_obj_cleanup(i915);
|
||||
drm_mode_config_cleanup(&i915->drm);
|
||||
drm_mode_config_cleanup(display->drm);
|
||||
}
|
||||
|
||||
static void intel_plane_possible_crtcs_init(struct drm_i915_private *dev_priv)
|
||||
static void intel_plane_possible_crtcs_init(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct intel_plane *plane;
|
||||
|
||||
for_each_intel_plane(&dev_priv->drm, plane) {
|
||||
for_each_intel_plane(display->drm, plane) {
|
||||
struct intel_crtc *crtc = intel_crtc_for_pipe(display,
|
||||
plane->pipe);
|
||||
|
||||
@ -180,41 +181,43 @@ static void intel_plane_possible_crtcs_init(struct drm_i915_private *dev_priv)
|
||||
}
|
||||
}
|
||||
|
||||
void intel_display_driver_early_probe(struct drm_i915_private *i915)
|
||||
void intel_display_driver_early_probe(struct intel_display *display)
|
||||
{
|
||||
if (!HAS_DISPLAY(i915))
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
spin_lock_init(&i915->display.fb_tracking.lock);
|
||||
mutex_init(&i915->display.backlight.lock);
|
||||
mutex_init(&i915->display.audio.mutex);
|
||||
mutex_init(&i915->display.wm.wm_mutex);
|
||||
mutex_init(&i915->display.pps.mutex);
|
||||
mutex_init(&i915->display.hdcp.hdcp_mutex);
|
||||
spin_lock_init(&display->fb_tracking.lock);
|
||||
mutex_init(&display->backlight.lock);
|
||||
mutex_init(&display->audio.mutex);
|
||||
mutex_init(&display->wm.wm_mutex);
|
||||
mutex_init(&display->pps.mutex);
|
||||
mutex_init(&display->hdcp.hdcp_mutex);
|
||||
|
||||
intel_display_irq_init(i915);
|
||||
intel_dkl_phy_init(i915);
|
||||
intel_color_init_hooks(&i915->display);
|
||||
intel_init_cdclk_hooks(&i915->display);
|
||||
intel_color_init_hooks(display);
|
||||
intel_init_cdclk_hooks(display);
|
||||
intel_audio_hooks_init(i915);
|
||||
intel_dpll_init_clock_hook(i915);
|
||||
intel_init_display_hooks(i915);
|
||||
intel_fdi_init_hook(i915);
|
||||
intel_dmc_wl_init(&i915->display);
|
||||
intel_dmc_wl_init(display);
|
||||
}
|
||||
|
||||
/* part #1: call before irq install */
|
||||
int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
|
||||
int intel_display_driver_probe_noirq(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
int ret;
|
||||
|
||||
if (i915_inject_probe_failure(i915))
|
||||
return -ENODEV;
|
||||
|
||||
if (HAS_DISPLAY(i915)) {
|
||||
ret = drm_vblank_init(&i915->drm,
|
||||
INTEL_NUM_PIPES(i915));
|
||||
if (HAS_DISPLAY(display)) {
|
||||
ret = drm_vblank_init(display->drm,
|
||||
INTEL_NUM_PIPES(display));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -226,24 +229,25 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
|
||||
goto cleanup_bios;
|
||||
|
||||
/* FIXME: completely on the wrong abstraction layer */
|
||||
ret = intel_power_domains_init(i915);
|
||||
ret = intel_power_domains_init(display);
|
||||
if (ret < 0)
|
||||
goto cleanup_vga;
|
||||
|
||||
intel_pmdemand_init_early(i915);
|
||||
|
||||
intel_power_domains_init_hw(i915, false);
|
||||
intel_power_domains_init_hw(display, false);
|
||||
|
||||
if (!HAS_DISPLAY(i915))
|
||||
if (!HAS_DISPLAY(display))
|
||||
return 0;
|
||||
|
||||
intel_dmc_init(display);
|
||||
|
||||
i915->display.wq.modeset = alloc_ordered_workqueue("i915_modeset", 0);
|
||||
i915->display.wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI |
|
||||
display->wq.modeset = alloc_ordered_workqueue("i915_modeset", 0);
|
||||
display->wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI |
|
||||
WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE);
|
||||
display->wq.cleanup = alloc_workqueue("i915_cleanup", WQ_HIGHPRI, 0);
|
||||
|
||||
intel_mode_config_init(i915);
|
||||
intel_mode_config_init(display);
|
||||
|
||||
ret = intel_cdclk_init(display);
|
||||
if (ret)
|
||||
@ -273,7 +277,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
|
||||
|
||||
cleanup_vga_client_pw_domain_dmc:
|
||||
intel_dmc_fini(display);
|
||||
intel_power_domains_driver_remove(i915);
|
||||
intel_power_domains_driver_remove(display);
|
||||
cleanup_vga:
|
||||
intel_vga_unregister(display);
|
||||
cleanup_bios:
|
||||
@ -282,7 +286,7 @@ int intel_display_driver_probe_noirq(struct drm_i915_private *i915)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void set_display_access(struct drm_i915_private *i915,
|
||||
static void set_display_access(struct intel_display *display,
|
||||
bool any_task_allowed,
|
||||
struct task_struct *allowed_task)
|
||||
{
|
||||
@ -290,20 +294,20 @@ static void set_display_access(struct drm_i915_private *i915,
|
||||
int err;
|
||||
|
||||
intel_modeset_lock_ctx_retry(&ctx, NULL, 0, err) {
|
||||
err = drm_modeset_lock_all_ctx(&i915->drm, &ctx);
|
||||
err = drm_modeset_lock_all_ctx(display->drm, &ctx);
|
||||
if (err)
|
||||
continue;
|
||||
|
||||
i915->display.access.any_task_allowed = any_task_allowed;
|
||||
i915->display.access.allowed_task = allowed_task;
|
||||
display->access.any_task_allowed = any_task_allowed;
|
||||
display->access.allowed_task = allowed_task;
|
||||
}
|
||||
|
||||
drm_WARN_ON(&i915->drm, err);
|
||||
drm_WARN_ON(display->drm, err);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_display_driver_enable_user_access - Enable display HW access for all threads
|
||||
* @i915: i915 device instance
|
||||
* @display: display device instance
|
||||
*
|
||||
* Enable the display HW access for all threads. Examples for such accesses
|
||||
* are modeset commits and connector probing.
|
||||
@ -311,16 +315,18 @@ static void set_display_access(struct drm_i915_private *i915,
|
||||
* This function should be called during driver loading and system resume once
|
||||
* all the HW initialization steps are done.
|
||||
*/
|
||||
void intel_display_driver_enable_user_access(struct drm_i915_private *i915)
|
||||
void intel_display_driver_enable_user_access(struct intel_display *display)
|
||||
{
|
||||
set_display_access(i915, true, NULL);
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
set_display_access(display, true, NULL);
|
||||
|
||||
intel_hpd_enable_detection_work(i915);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_display_driver_disable_user_access - Disable display HW access for user threads
|
||||
* @i915: i915 device instance
|
||||
* @display: display device instance
|
||||
*
|
||||
* Disable the display HW access for user threads. Examples for such accesses
|
||||
* are modeset commits and connector probing. For the current thread the
|
||||
@ -335,16 +341,18 @@ void intel_display_driver_enable_user_access(struct drm_i915_private *i915)
|
||||
* This function should be called during driver loading/unloading and system
|
||||
* suspend/shutdown before starting the HW init/deinit programming.
|
||||
*/
|
||||
void intel_display_driver_disable_user_access(struct drm_i915_private *i915)
|
||||
void intel_display_driver_disable_user_access(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
intel_hpd_disable_detection_work(i915);
|
||||
|
||||
set_display_access(i915, false, current);
|
||||
set_display_access(display, false, current);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_display_driver_suspend_access - Suspend display HW access for all threads
|
||||
* @i915: i915 device instance
|
||||
* @display: display device instance
|
||||
*
|
||||
* Disable the display HW access for all threads. Examples for such accesses
|
||||
* are modeset commits and connector probing. This call should be either
|
||||
@ -354,14 +362,14 @@ void intel_display_driver_disable_user_access(struct drm_i915_private *i915)
|
||||
* This function should be called during driver unloading and system
|
||||
* suspend/shutdown after completing the HW deinit programming.
|
||||
*/
|
||||
void intel_display_driver_suspend_access(struct drm_i915_private *i915)
|
||||
void intel_display_driver_suspend_access(struct intel_display *display)
|
||||
{
|
||||
set_display_access(i915, false, NULL);
|
||||
set_display_access(display, false, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_display_driver_resume_access - Resume display HW access for the resume thread
|
||||
* @i915: i915 device instance
|
||||
* @display: display device instance
|
||||
*
|
||||
* Enable the display HW access for the current resume thread, keeping the
|
||||
* access disabled for all other (user) threads. Examples for such accesses
|
||||
@ -373,14 +381,14 @@ void intel_display_driver_suspend_access(struct drm_i915_private *i915)
|
||||
* This function should be called during system resume before starting the HW
|
||||
* init steps.
|
||||
*/
|
||||
void intel_display_driver_resume_access(struct drm_i915_private *i915)
|
||||
void intel_display_driver_resume_access(struct intel_display *display)
|
||||
{
|
||||
set_display_access(i915, false, current);
|
||||
set_display_access(display, false, current);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_display_driver_check_access - Check if the current thread has disaplay HW access
|
||||
* @i915: i915 device instance
|
||||
* @display: display device instance
|
||||
*
|
||||
* Check whether the current thread has display HW access, print a debug
|
||||
* message if it doesn't. Such accesses are modeset commits and connector
|
||||
@ -389,26 +397,26 @@ void intel_display_driver_resume_access(struct drm_i915_private *i915)
|
||||
* Returns %true if the current thread has display HW access, %false
|
||||
* otherwise.
|
||||
*/
|
||||
bool intel_display_driver_check_access(struct drm_i915_private *i915)
|
||||
bool intel_display_driver_check_access(struct intel_display *display)
|
||||
{
|
||||
char comm[TASK_COMM_LEN];
|
||||
char current_task[TASK_COMM_LEN + 16];
|
||||
char allowed_task[TASK_COMM_LEN + 16] = "none";
|
||||
|
||||
if (i915->display.access.any_task_allowed ||
|
||||
i915->display.access.allowed_task == current)
|
||||
if (display->access.any_task_allowed ||
|
||||
display->access.allowed_task == current)
|
||||
return true;
|
||||
|
||||
snprintf(current_task, sizeof(current_task), "%s[%d]",
|
||||
get_task_comm(comm, current),
|
||||
task_pid_vnr(current));
|
||||
|
||||
if (i915->display.access.allowed_task)
|
||||
if (display->access.allowed_task)
|
||||
snprintf(allowed_task, sizeof(allowed_task), "%s[%d]",
|
||||
get_task_comm(comm, i915->display.access.allowed_task),
|
||||
task_pid_vnr(i915->display.access.allowed_task));
|
||||
get_task_comm(comm, display->access.allowed_task),
|
||||
task_pid_vnr(display->access.allowed_task));
|
||||
|
||||
drm_dbg_kms(&i915->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"Reject display access from task %s (allowed to %s)\n",
|
||||
current_task, allowed_task);
|
||||
|
||||
@ -416,14 +424,13 @@ bool intel_display_driver_check_access(struct drm_i915_private *i915)
|
||||
}
|
||||
|
||||
/* part #2: call after irq install, but before gem init */
|
||||
int intel_display_driver_probe_nogem(struct drm_i915_private *i915)
|
||||
int intel_display_driver_probe_nogem(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct drm_device *dev = display->drm;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
enum pipe pipe;
|
||||
int ret;
|
||||
|
||||
if (!HAS_DISPLAY(i915))
|
||||
if (!HAS_DISPLAY(display))
|
||||
return 0;
|
||||
|
||||
intel_wm_init(i915);
|
||||
@ -434,22 +441,22 @@ int intel_display_driver_probe_nogem(struct drm_i915_private *i915)
|
||||
|
||||
intel_gmbus_setup(display);
|
||||
|
||||
drm_dbg_kms(&i915->drm, "%d display pipe%s available.\n",
|
||||
INTEL_NUM_PIPES(i915),
|
||||
INTEL_NUM_PIPES(i915) > 1 ? "s" : "");
|
||||
drm_dbg_kms(display->drm, "%d display pipe%s available.\n",
|
||||
INTEL_NUM_PIPES(display),
|
||||
INTEL_NUM_PIPES(display) > 1 ? "s" : "");
|
||||
|
||||
for_each_pipe(i915, pipe) {
|
||||
for_each_pipe(display, pipe) {
|
||||
ret = intel_crtc_init(i915, pipe);
|
||||
if (ret)
|
||||
goto err_mode_config;
|
||||
}
|
||||
|
||||
intel_plane_possible_crtcs_init(i915);
|
||||
intel_plane_possible_crtcs_init(display);
|
||||
intel_shared_dpll_init(i915);
|
||||
intel_fdi_pll_freq_update(i915);
|
||||
|
||||
intel_update_czclk(i915);
|
||||
intel_display_driver_init_hw(i915);
|
||||
intel_display_driver_init_hw(display);
|
||||
intel_dpll_update_ref_clks(i915);
|
||||
|
||||
if (display->cdclk.max_cdclk_freq == 0)
|
||||
@ -465,21 +472,21 @@ int intel_display_driver_probe_nogem(struct drm_i915_private *i915)
|
||||
if (ret)
|
||||
goto err_hdcp;
|
||||
|
||||
intel_display_driver_disable_user_access(i915);
|
||||
intel_display_driver_disable_user_access(display);
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
intel_modeset_setup_hw_state(i915, dev->mode_config.acquire_ctx);
|
||||
drm_modeset_lock_all(display->drm);
|
||||
intel_modeset_setup_hw_state(i915, display->drm->mode_config.acquire_ctx);
|
||||
intel_acpi_assign_connector_fwnodes(display);
|
||||
drm_modeset_unlock_all(dev);
|
||||
drm_modeset_unlock_all(display->drm);
|
||||
|
||||
intel_initial_plane_config(i915);
|
||||
intel_initial_plane_config(display);
|
||||
|
||||
/*
|
||||
* Make sure hardware watermarks really match the state we read out.
|
||||
* Note that we need to do this after reconstructing the BIOS fb's
|
||||
* since the watermark calculation done here will use pstate->fb.
|
||||
*/
|
||||
if (!HAS_GMCH(i915))
|
||||
if (!HAS_GMCH(display))
|
||||
ilk_wm_sanitize(i915);
|
||||
|
||||
return 0;
|
||||
@ -487,18 +494,18 @@ int intel_display_driver_probe_nogem(struct drm_i915_private *i915)
|
||||
err_hdcp:
|
||||
intel_hdcp_component_fini(display);
|
||||
err_mode_config:
|
||||
intel_mode_config_cleanup(i915);
|
||||
intel_mode_config_cleanup(display);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* part #3: call after gem init */
|
||||
int intel_display_driver_probe(struct drm_i915_private *i915)
|
||||
int intel_display_driver_probe(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
int ret;
|
||||
|
||||
if (!HAS_DISPLAY(i915))
|
||||
if (!HAS_DISPLAY(display))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@ -514,11 +521,11 @@ int intel_display_driver_probe(struct drm_i915_private *i915)
|
||||
* are already calculated and there is no assert_plane warnings
|
||||
* during bootup.
|
||||
*/
|
||||
ret = intel_initial_commit(&i915->drm);
|
||||
ret = intel_initial_commit(display->drm);
|
||||
if (ret)
|
||||
drm_dbg_kms(&i915->drm, "Initial modeset failed, %d\n", ret);
|
||||
drm_dbg_kms(display->drm, "Initial modeset failed, %d\n", ret);
|
||||
|
||||
intel_overlay_setup(i915);
|
||||
intel_overlay_setup(display);
|
||||
|
||||
/* Only enable hotplug handling once the fbdev is fully set up. */
|
||||
intel_hpd_init(i915);
|
||||
@ -528,13 +535,13 @@ int intel_display_driver_probe(struct drm_i915_private *i915)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void intel_display_driver_register(struct drm_i915_private *i915)
|
||||
void intel_display_driver_register(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct drm_printer p = drm_dbg_printer(&i915->drm, DRM_UT_KMS,
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct drm_printer p = drm_dbg_printer(display->drm, DRM_UT_KMS,
|
||||
"i915 display info:");
|
||||
|
||||
if (!HAS_DISPLAY(i915))
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
/* Must be done after probing outputs */
|
||||
@ -543,7 +550,7 @@ void intel_display_driver_register(struct drm_i915_private *i915)
|
||||
|
||||
intel_audio_init(i915);
|
||||
|
||||
intel_display_driver_enable_user_access(i915);
|
||||
intel_display_driver_enable_user_access(display);
|
||||
|
||||
intel_audio_register(i915);
|
||||
|
||||
@ -554,41 +561,42 @@ void intel_display_driver_register(struct drm_i915_private *i915)
|
||||
* fbdev configuration, for which we use the
|
||||
* fbdev->async_cookie.
|
||||
*/
|
||||
drm_kms_helper_poll_init(&i915->drm);
|
||||
drm_kms_helper_poll_init(display->drm);
|
||||
intel_hpd_poll_disable(i915);
|
||||
|
||||
intel_fbdev_setup(i915);
|
||||
|
||||
intel_display_device_info_print(DISPLAY_INFO(i915),
|
||||
DISPLAY_RUNTIME_INFO(i915), &p);
|
||||
intel_display_device_info_print(DISPLAY_INFO(display),
|
||||
DISPLAY_RUNTIME_INFO(display), &p);
|
||||
}
|
||||
|
||||
/* part #1: call before irq uninstall */
|
||||
void intel_display_driver_remove(struct drm_i915_private *i915)
|
||||
void intel_display_driver_remove(struct intel_display *display)
|
||||
{
|
||||
if (!HAS_DISPLAY(i915))
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
flush_workqueue(i915->display.wq.flip);
|
||||
flush_workqueue(i915->display.wq.modeset);
|
||||
flush_workqueue(display->wq.flip);
|
||||
flush_workqueue(display->wq.modeset);
|
||||
flush_workqueue(display->wq.cleanup);
|
||||
|
||||
/*
|
||||
* MST topology needs to be suspended so we don't have any calls to
|
||||
* fbdev after it's finalized. MST will be destroyed later as part of
|
||||
* drm_mode_config_cleanup()
|
||||
*/
|
||||
intel_dp_mst_suspend(i915);
|
||||
intel_dp_mst_suspend(display);
|
||||
}
|
||||
|
||||
/* part #2: call after irq uninstall */
|
||||
void intel_display_driver_remove_noirq(struct drm_i915_private *i915)
|
||||
void intel_display_driver_remove_noirq(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
if (!HAS_DISPLAY(i915))
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
intel_display_driver_suspend_access(i915);
|
||||
intel_display_driver_suspend_access(display);
|
||||
|
||||
/*
|
||||
* Due to the hpd irq storm handling the hotplug work can re-arm the
|
||||
@ -603,55 +611,54 @@ void intel_display_driver_remove_noirq(struct drm_i915_private *i915)
|
||||
|
||||
intel_hdcp_component_fini(display);
|
||||
|
||||
intel_mode_config_cleanup(i915);
|
||||
intel_mode_config_cleanup(display);
|
||||
|
||||
intel_dp_tunnel_mgr_cleanup(display);
|
||||
|
||||
intel_overlay_cleanup(i915);
|
||||
intel_overlay_cleanup(display);
|
||||
|
||||
intel_gmbus_teardown(display);
|
||||
|
||||
destroy_workqueue(i915->display.wq.flip);
|
||||
destroy_workqueue(i915->display.wq.modeset);
|
||||
destroy_workqueue(display->wq.flip);
|
||||
destroy_workqueue(display->wq.modeset);
|
||||
destroy_workqueue(display->wq.cleanup);
|
||||
|
||||
intel_fbc_cleanup(&i915->display);
|
||||
intel_fbc_cleanup(display);
|
||||
}
|
||||
|
||||
/* part #3: call after gem init */
|
||||
void intel_display_driver_remove_nogem(struct drm_i915_private *i915)
|
||||
void intel_display_driver_remove_nogem(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
|
||||
intel_dmc_fini(display);
|
||||
|
||||
intel_power_domains_driver_remove(i915);
|
||||
intel_power_domains_driver_remove(display);
|
||||
|
||||
intel_vga_unregister(display);
|
||||
|
||||
intel_bios_driver_remove(display);
|
||||
}
|
||||
|
||||
void intel_display_driver_unregister(struct drm_i915_private *i915)
|
||||
void intel_display_driver_unregister(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
if (!HAS_DISPLAY(i915))
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
drm_client_dev_unregister(&i915->drm);
|
||||
drm_client_dev_unregister(display->drm);
|
||||
|
||||
/*
|
||||
* After flushing the fbdev (incl. a late async config which
|
||||
* will have delayed queuing of a hotplug event), then flush
|
||||
* the hotplug events.
|
||||
*/
|
||||
drm_kms_helper_poll_fini(&i915->drm);
|
||||
drm_kms_helper_poll_fini(display->drm);
|
||||
|
||||
intel_display_driver_disable_user_access(i915);
|
||||
intel_display_driver_disable_user_access(display);
|
||||
|
||||
intel_audio_deinit(i915);
|
||||
|
||||
drm_atomic_helper_shutdown(&i915->drm);
|
||||
drm_atomic_helper_shutdown(display->drm);
|
||||
|
||||
acpi_video_unregister();
|
||||
intel_opregion_unregister(display);
|
||||
@ -661,30 +668,36 @@ void intel_display_driver_unregister(struct drm_i915_private *i915)
|
||||
* turn all crtc's off, but do not adjust state
|
||||
* This has to be paired with a call to intel_modeset_setup_hw_state.
|
||||
*/
|
||||
int intel_display_driver_suspend(struct drm_i915_private *i915)
|
||||
int intel_display_driver_suspend(struct intel_display *display)
|
||||
{
|
||||
struct drm_atomic_state *state;
|
||||
int ret;
|
||||
|
||||
if (!HAS_DISPLAY(i915))
|
||||
if (!HAS_DISPLAY(display))
|
||||
return 0;
|
||||
|
||||
state = drm_atomic_helper_suspend(&i915->drm);
|
||||
state = drm_atomic_helper_suspend(display->drm);
|
||||
ret = PTR_ERR_OR_ZERO(state);
|
||||
if (ret)
|
||||
drm_err(&i915->drm, "Suspending crtc's failed with %i\n",
|
||||
drm_err(display->drm, "Suspending crtc's failed with %i\n",
|
||||
ret);
|
||||
else
|
||||
i915->display.restore.modeset_state = state;
|
||||
display->restore.modeset_state = state;
|
||||
|
||||
/* ensure all DPT VMAs have been unpinned for intel_dpt_suspend() */
|
||||
flush_workqueue(display->wq.cleanup);
|
||||
|
||||
intel_dp_mst_suspend(display);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
__intel_display_driver_resume(struct drm_i915_private *i915,
|
||||
__intel_display_driver_resume(struct intel_display *display,
|
||||
struct drm_atomic_state *state,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_crtc *crtc;
|
||||
int ret, i;
|
||||
@ -710,33 +723,37 @@ __intel_display_driver_resume(struct drm_i915_private *i915,
|
||||
}
|
||||
|
||||
/* ignore any reset values/BIOS leftovers in the WM registers */
|
||||
if (!HAS_GMCH(i915))
|
||||
if (!HAS_GMCH(display))
|
||||
to_intel_atomic_state(state)->skip_intermediate_wm = true;
|
||||
|
||||
ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
|
||||
|
||||
drm_WARN_ON(&i915->drm, ret == -EDEADLK);
|
||||
drm_WARN_ON(display->drm, ret == -EDEADLK);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void intel_display_driver_resume(struct drm_i915_private *i915)
|
||||
void intel_display_driver_resume(struct intel_display *display)
|
||||
{
|
||||
struct drm_atomic_state *state = i915->display.restore.modeset_state;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct drm_atomic_state *state = display->restore.modeset_state;
|
||||
struct drm_modeset_acquire_ctx ctx;
|
||||
int ret;
|
||||
|
||||
if (!HAS_DISPLAY(i915))
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
i915->display.restore.modeset_state = NULL;
|
||||
/* MST sideband requires HPD interrupts enabled */
|
||||
intel_dp_mst_resume(display);
|
||||
|
||||
display->restore.modeset_state = NULL;
|
||||
if (state)
|
||||
state->acquire_ctx = &ctx;
|
||||
|
||||
drm_modeset_acquire_init(&ctx, 0);
|
||||
|
||||
while (1) {
|
||||
ret = drm_modeset_lock_all_ctx(&i915->drm, &ctx);
|
||||
ret = drm_modeset_lock_all_ctx(display->drm, &ctx);
|
||||
if (ret != -EDEADLK)
|
||||
break;
|
||||
|
||||
@ -744,14 +761,14 @@ void intel_display_driver_resume(struct drm_i915_private *i915)
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
ret = __intel_display_driver_resume(i915, state, &ctx);
|
||||
ret = __intel_display_driver_resume(display, state, &ctx);
|
||||
|
||||
skl_watermark_ipc_update(i915);
|
||||
drm_modeset_drop_locks(&ctx);
|
||||
drm_modeset_acquire_fini(&ctx);
|
||||
|
||||
if (ret)
|
||||
drm_err(&i915->drm,
|
||||
drm_err(display->drm,
|
||||
"Restoring old state failed with %i\n", ret);
|
||||
if (state)
|
||||
drm_atomic_state_put(state);
|
||||
|
@ -9,34 +9,34 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
struct drm_atomic_state;
|
||||
struct drm_i915_private;
|
||||
struct drm_modeset_acquire_ctx;
|
||||
struct intel_display;
|
||||
struct pci_dev;
|
||||
|
||||
bool intel_display_driver_probe_defer(struct pci_dev *pdev);
|
||||
void intel_display_driver_init_hw(struct drm_i915_private *i915);
|
||||
void intel_display_driver_early_probe(struct drm_i915_private *i915);
|
||||
int intel_display_driver_probe_noirq(struct drm_i915_private *i915);
|
||||
int intel_display_driver_probe_nogem(struct drm_i915_private *i915);
|
||||
int intel_display_driver_probe(struct drm_i915_private *i915);
|
||||
void intel_display_driver_register(struct drm_i915_private *i915);
|
||||
void intel_display_driver_remove(struct drm_i915_private *i915);
|
||||
void intel_display_driver_remove_noirq(struct drm_i915_private *i915);
|
||||
void intel_display_driver_remove_nogem(struct drm_i915_private *i915);
|
||||
void intel_display_driver_unregister(struct drm_i915_private *i915);
|
||||
int intel_display_driver_suspend(struct drm_i915_private *i915);
|
||||
void intel_display_driver_resume(struct drm_i915_private *i915);
|
||||
void intel_display_driver_init_hw(struct intel_display *display);
|
||||
void intel_display_driver_early_probe(struct intel_display *display);
|
||||
int intel_display_driver_probe_noirq(struct intel_display *display);
|
||||
int intel_display_driver_probe_nogem(struct intel_display *display);
|
||||
int intel_display_driver_probe(struct intel_display *display);
|
||||
void intel_display_driver_register(struct intel_display *display);
|
||||
void intel_display_driver_remove(struct intel_display *display);
|
||||
void intel_display_driver_remove_noirq(struct intel_display *display);
|
||||
void intel_display_driver_remove_nogem(struct intel_display *display);
|
||||
void intel_display_driver_unregister(struct intel_display *display);
|
||||
int intel_display_driver_suspend(struct intel_display *display);
|
||||
void intel_display_driver_resume(struct intel_display *display);
|
||||
|
||||
/* interface for intel_display_reset.c */
|
||||
int __intel_display_driver_resume(struct drm_i915_private *i915,
|
||||
int __intel_display_driver_resume(struct intel_display *display,
|
||||
struct drm_atomic_state *state,
|
||||
struct drm_modeset_acquire_ctx *ctx);
|
||||
|
||||
void intel_display_driver_enable_user_access(struct drm_i915_private *i915);
|
||||
void intel_display_driver_disable_user_access(struct drm_i915_private *i915);
|
||||
void intel_display_driver_suspend_access(struct drm_i915_private *i915);
|
||||
void intel_display_driver_resume_access(struct drm_i915_private *i915);
|
||||
bool intel_display_driver_check_access(struct drm_i915_private *i915);
|
||||
void intel_display_driver_enable_user_access(struct intel_display *display);
|
||||
void intel_display_driver_disable_user_access(struct intel_display *display);
|
||||
void intel_display_driver_suspend_access(struct intel_display *display);
|
||||
void intel_display_driver_resume_access(struct intel_display *display);
|
||||
bool intel_display_driver_check_access(struct intel_display *display);
|
||||
|
||||
#endif /* __INTEL_DISPLAY_DRIVER_H__ */
|
||||
|
||||
|
@ -434,7 +434,8 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
|
||||
|
||||
spin_lock(&dev_priv->irq_lock);
|
||||
|
||||
if (!dev_priv->display.irq.display_irqs_enabled) {
|
||||
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
|
||||
!dev_priv->display.irq.vlv_display_irqs_enabled) {
|
||||
spin_unlock(&dev_priv->irq_lock);
|
||||
return;
|
||||
}
|
||||
@ -843,7 +844,9 @@ static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv)
|
||||
|
||||
static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (DISPLAY_VER(dev_priv) >= 14)
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
|
||||
if (DISPLAY_VER(display) >= 14)
|
||||
return MTL_PIPEDMC_ATS_FAULT |
|
||||
MTL_PLANE_ATS_FAULT |
|
||||
GEN12_PIPEDMC_FAULT |
|
||||
@ -853,7 +856,7 @@ static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv)
|
||||
GEN9_PIPE_PLANE3_FAULT |
|
||||
GEN9_PIPE_PLANE2_FAULT |
|
||||
GEN9_PIPE_PLANE1_FAULT;
|
||||
if (DISPLAY_VER(dev_priv) >= 13 || HAS_D12_PLANE_MINIMIZATION(dev_priv))
|
||||
if (DISPLAY_VER(display) >= 13 || HAS_D12_PLANE_MINIMIZATION(display))
|
||||
return GEN12_PIPEDMC_FAULT |
|
||||
GEN9_PIPE_CURSOR_FAULT |
|
||||
GEN11_PIPE_PLANE5_FAULT |
|
||||
@ -861,7 +864,7 @@ static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv)
|
||||
GEN9_PIPE_PLANE3_FAULT |
|
||||
GEN9_PIPE_PLANE2_FAULT |
|
||||
GEN9_PIPE_PLANE1_FAULT;
|
||||
else if (DISPLAY_VER(dev_priv) == 12)
|
||||
else if (DISPLAY_VER(display) == 12)
|
||||
return GEN12_PIPEDMC_FAULT |
|
||||
GEN9_PIPE_CURSOR_FAULT |
|
||||
GEN11_PIPE_PLANE7_FAULT |
|
||||
@ -871,7 +874,7 @@ static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv)
|
||||
GEN9_PIPE_PLANE3_FAULT |
|
||||
GEN9_PIPE_PLANE2_FAULT |
|
||||
GEN9_PIPE_PLANE1_FAULT;
|
||||
else if (DISPLAY_VER(dev_priv) == 11)
|
||||
else if (DISPLAY_VER(display) == 11)
|
||||
return GEN9_PIPE_CURSOR_FAULT |
|
||||
GEN11_PIPE_PLANE7_FAULT |
|
||||
GEN11_PIPE_PLANE6_FAULT |
|
||||
@ -880,7 +883,7 @@ static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv)
|
||||
GEN9_PIPE_PLANE3_FAULT |
|
||||
GEN9_PIPE_PLANE2_FAULT |
|
||||
GEN9_PIPE_PLANE1_FAULT;
|
||||
else if (DISPLAY_VER(dev_priv) >= 9)
|
||||
else if (DISPLAY_VER(display) >= 9)
|
||||
return GEN9_PIPE_CURSOR_FAULT |
|
||||
GEN9_PIPE_PLANE4_FAULT |
|
||||
GEN9_PIPE_PLANE3_FAULT |
|
||||
@ -1420,7 +1423,6 @@ 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);
|
||||
int vblank_wa_num_pipes = READ_ONCE(display->irq.vblank_wa_num_pipes);
|
||||
|
||||
/*
|
||||
@ -1429,7 +1431,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_wa_num_pipes ? DC_STATE_DISABLE :
|
||||
intel_display_power_set_target_dc_state(display, vblank_wa_num_pipes ? DC_STATE_DISABLE :
|
||||
DC_STATE_EN_UPTO_DC6);
|
||||
}
|
||||
|
||||
@ -1479,7 +1481,7 @@ void bdw_disable_vblank(struct drm_crtc *_crtc)
|
||||
schedule_work(&display->irq.vblank_dc_work);
|
||||
}
|
||||
|
||||
void vlv_display_irq_reset(struct drm_i915_private *dev_priv)
|
||||
static void _vlv_display_irq_reset(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_uncore *uncore = &dev_priv->uncore;
|
||||
|
||||
@ -1497,6 +1499,12 @@ void vlv_display_irq_reset(struct drm_i915_private *dev_priv)
|
||||
dev_priv->irq_mask = ~0u;
|
||||
}
|
||||
|
||||
void vlv_display_irq_reset(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (dev_priv->display.irq.vlv_display_irqs_enabled)
|
||||
_vlv_display_irq_reset(dev_priv);
|
||||
}
|
||||
|
||||
void i9xx_display_irq_reset(struct drm_i915_private *i915)
|
||||
{
|
||||
if (I915_HAS_HOTPLUG(i915)) {
|
||||
@ -1516,6 +1524,9 @@ void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv)
|
||||
u32 enable_mask;
|
||||
enum pipe pipe;
|
||||
|
||||
if (!dev_priv->display.irq.vlv_display_irqs_enabled)
|
||||
return;
|
||||
|
||||
pipestat_mask = PIPE_CRC_DONE_INTERRUPT_STATUS;
|
||||
|
||||
i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS);
|
||||
@ -1688,13 +1699,13 @@ void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
lockdep_assert_held(&dev_priv->irq_lock);
|
||||
|
||||
if (dev_priv->display.irq.display_irqs_enabled)
|
||||
if (dev_priv->display.irq.vlv_display_irqs_enabled)
|
||||
return;
|
||||
|
||||
dev_priv->display.irq.display_irqs_enabled = true;
|
||||
dev_priv->display.irq.vlv_display_irqs_enabled = true;
|
||||
|
||||
if (intel_irqs_enabled(dev_priv)) {
|
||||
vlv_display_irq_reset(dev_priv);
|
||||
_vlv_display_irq_reset(dev_priv);
|
||||
vlv_display_irq_postinstall(dev_priv);
|
||||
}
|
||||
}
|
||||
@ -1703,13 +1714,13 @@ void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
lockdep_assert_held(&dev_priv->irq_lock);
|
||||
|
||||
if (!dev_priv->display.irq.display_irqs_enabled)
|
||||
if (!dev_priv->display.irq.vlv_display_irqs_enabled)
|
||||
return;
|
||||
|
||||
dev_priv->display.irq.display_irqs_enabled = false;
|
||||
dev_priv->display.irq.vlv_display_irqs_enabled = false;
|
||||
|
||||
if (intel_irqs_enabled(dev_priv))
|
||||
vlv_display_irq_reset(dev_priv);
|
||||
_vlv_display_irq_reset(dev_priv);
|
||||
}
|
||||
|
||||
void ilk_de_irq_postinstall(struct drm_i915_private *i915)
|
||||
@ -1902,17 +1913,6 @@ void intel_display_irq_init(struct drm_i915_private *i915)
|
||||
{
|
||||
i915->drm.vblank_disable_immediate = true;
|
||||
|
||||
/*
|
||||
* Most platforms treat the display irq block as an always-on power
|
||||
* domain. vlv/chv can disable it at runtime and need special care to
|
||||
* avoid writing any of the display block registers outside of the power
|
||||
* domain. We defer setting up the display irqs in this case to the
|
||||
* runtime pm.
|
||||
*/
|
||||
i915->display.irq.display_irqs_enabled = true;
|
||||
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
|
||||
i915->display.irq.display_irqs_enabled = false;
|
||||
|
||||
intel_hotplug_irq_init(i915);
|
||||
|
||||
INIT_WORK(&i915->display.irq.vblank_dc_work,
|
||||
|
@ -3,8 +3,13 @@
|
||||
* Copyright © 2023 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string_choices.h>
|
||||
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "intel_display_params.h"
|
||||
#include "i915_drv.h"
|
||||
|
||||
#define intel_display_param_named(name, T, perm, desc) \
|
||||
module_param_named(name, intel_display_modparams.name, T, perm); \
|
||||
@ -123,10 +128,10 @@ 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,
|
||||
intel_display_param_named_unsafe(enable_dmc_wl, int, 0400,
|
||||
"Enable DMC wakelock "
|
||||
"(0=disabled, 1=enabled) "
|
||||
"Default: 0");
|
||||
"(-1=use per-chip default, 0=disabled, 1=enabled) "
|
||||
"Default: -1");
|
||||
|
||||
__maybe_unused
|
||||
static void _param_print_bool(struct drm_printer *p, const char *driver_name,
|
||||
|
@ -47,7 +47,7 @@ struct drm_printer;
|
||||
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) \
|
||||
param(int, enable_dmc_wl, -1, 0400) \
|
||||
|
||||
#define MEMBER(T, member, ...) T member;
|
||||
struct intel_display_params {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,7 @@ enum aux_ch;
|
||||
enum port;
|
||||
struct drm_i915_private;
|
||||
struct i915_power_well;
|
||||
struct intel_display;
|
||||
struct intel_encoder;
|
||||
struct seq_file;
|
||||
|
||||
@ -166,21 +167,21 @@ struct intel_display_power_domain_set {
|
||||
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);
|
||||
void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume);
|
||||
void intel_power_domains_driver_remove(struct drm_i915_private *dev_priv);
|
||||
void intel_power_domains_enable(struct drm_i915_private *dev_priv);
|
||||
void intel_power_domains_disable(struct drm_i915_private *dev_priv);
|
||||
void intel_power_domains_suspend(struct drm_i915_private *dev_priv, bool s2idle);
|
||||
void intel_power_domains_resume(struct drm_i915_private *dev_priv);
|
||||
void intel_power_domains_sanitize_state(struct drm_i915_private *dev_priv);
|
||||
int intel_power_domains_init(struct intel_display *display);
|
||||
void intel_power_domains_cleanup(struct intel_display *display);
|
||||
void intel_power_domains_init_hw(struct intel_display *display, bool resume);
|
||||
void intel_power_domains_driver_remove(struct intel_display *display);
|
||||
void intel_power_domains_enable(struct intel_display *display);
|
||||
void intel_power_domains_disable(struct intel_display *display);
|
||||
void intel_power_domains_suspend(struct intel_display *display, bool s2idle);
|
||||
void intel_power_domains_resume(struct intel_display *display);
|
||||
void intel_power_domains_sanitize_state(struct intel_display *display);
|
||||
|
||||
void intel_display_power_suspend_late(struct drm_i915_private *i915);
|
||||
void intel_display_power_resume_early(struct drm_i915_private *i915);
|
||||
void intel_display_power_suspend(struct drm_i915_private *i915);
|
||||
void intel_display_power_resume(struct drm_i915_private *i915);
|
||||
void intel_display_power_set_target_dc_state(struct drm_i915_private *dev_priv,
|
||||
void intel_display_power_suspend_late(struct intel_display *display, bool s2idle);
|
||||
void intel_display_power_resume_early(struct intel_display *display);
|
||||
void intel_display_power_suspend(struct intel_display *display);
|
||||
void intel_display_power_resume(struct intel_display *display);
|
||||
void intel_display_power_set_target_dc_state(struct intel_display *display,
|
||||
u32 state);
|
||||
|
||||
bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
|
||||
|
@ -3,14 +3,12 @@
|
||||
* Copyright © 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
|
||||
#include "vlv_sideband_reg.h"
|
||||
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_power_map.h"
|
||||
#include "intel_display_power_well.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "vlv_sideband_reg.h"
|
||||
|
||||
#define __LIST_INLINE_ELEMS(__elem_type, ...) \
|
||||
((__elem_type[]) { __VA_ARGS__ })
|
||||
@ -1752,9 +1750,9 @@ __set_power_wells(struct i915_power_domains *power_domains,
|
||||
const struct i915_power_well_desc_list *power_well_descs,
|
||||
int power_well_descs_sz)
|
||||
{
|
||||
struct drm_i915_private *i915 = container_of(power_domains,
|
||||
struct drm_i915_private,
|
||||
display.power.domains);
|
||||
struct intel_display *display = container_of(power_domains,
|
||||
struct intel_display,
|
||||
power.domains);
|
||||
u64 power_well_ids = 0;
|
||||
const struct i915_power_well_desc_list *desc_list;
|
||||
const struct i915_power_well_desc *desc;
|
||||
@ -1778,7 +1776,7 @@ __set_power_wells(struct i915_power_domains *power_domains,
|
||||
enum i915_power_well_id id = inst->id;
|
||||
|
||||
pw->desc = desc;
|
||||
drm_WARN_ON(&i915->drm,
|
||||
drm_WARN_ON(display->drm,
|
||||
overflows_type(inst - desc->instances->list, pw->instance_idx));
|
||||
pw->instance_idx = inst - desc->instances->list;
|
||||
|
||||
@ -1789,8 +1787,8 @@ __set_power_wells(struct i915_power_domains *power_domains,
|
||||
if (id == DISP_PW_ID_NONE)
|
||||
continue;
|
||||
|
||||
drm_WARN_ON(&i915->drm, id >= sizeof(power_well_ids) * 8);
|
||||
drm_WARN_ON(&i915->drm, power_well_ids & BIT_ULL(id));
|
||||
drm_WARN_ON(display->drm, id >= sizeof(power_well_ids) * 8);
|
||||
drm_WARN_ON(display->drm, power_well_ids & BIT_ULL(id));
|
||||
power_well_ids |= BIT_ULL(id);
|
||||
}
|
||||
|
||||
@ -1811,53 +1809,53 @@ __set_power_wells(struct i915_power_domains *power_domains,
|
||||
*/
|
||||
int intel_display_power_map_init(struct i915_power_domains *power_domains)
|
||||
{
|
||||
struct drm_i915_private *i915 = container_of(power_domains,
|
||||
struct drm_i915_private,
|
||||
display.power.domains);
|
||||
struct intel_display *display = container_of(power_domains,
|
||||
struct intel_display,
|
||||
power.domains);
|
||||
/*
|
||||
* The enabling order will be from lower to higher indexed wells,
|
||||
* the disabling order is reversed.
|
||||
*/
|
||||
if (!HAS_DISPLAY(i915)) {
|
||||
if (!HAS_DISPLAY(display)) {
|
||||
power_domains->power_well_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(i915) >= 30)
|
||||
if (DISPLAY_VER(display) >= 30)
|
||||
return set_power_wells(power_domains, xe3lpd_power_wells);
|
||||
else if (DISPLAY_VER(i915) >= 20)
|
||||
else if (DISPLAY_VER(display) >= 20)
|
||||
return set_power_wells(power_domains, xe2lpd_power_wells);
|
||||
else if (DISPLAY_VER(i915) >= 14)
|
||||
else if (DISPLAY_VER(display) >= 14)
|
||||
return set_power_wells(power_domains, xelpdp_power_wells);
|
||||
else if (IS_DG2(i915))
|
||||
else if (display->platform.dg2)
|
||||
return set_power_wells(power_domains, xehpd_power_wells);
|
||||
else if (DISPLAY_VER(i915) >= 13)
|
||||
else if (DISPLAY_VER(display) >= 13)
|
||||
return set_power_wells(power_domains, xelpd_power_wells);
|
||||
else if (IS_DG1(i915))
|
||||
else if (display->platform.dg1)
|
||||
return set_power_wells(power_domains, dg1_power_wells);
|
||||
else if (IS_ALDERLAKE_S(i915))
|
||||
else if (display->platform.alderlake_s)
|
||||
return set_power_wells(power_domains, adls_power_wells);
|
||||
else if (IS_ROCKETLAKE(i915))
|
||||
else if (display->platform.rocketlake)
|
||||
return set_power_wells(power_domains, rkl_power_wells);
|
||||
else if (DISPLAY_VER(i915) == 12)
|
||||
else if (DISPLAY_VER(display) == 12)
|
||||
return set_power_wells(power_domains, tgl_power_wells);
|
||||
else if (DISPLAY_VER(i915) == 11)
|
||||
else if (DISPLAY_VER(display) == 11)
|
||||
return set_power_wells(power_domains, icl_power_wells);
|
||||
else if (IS_GEMINILAKE(i915))
|
||||
else if (display->platform.geminilake)
|
||||
return set_power_wells(power_domains, glk_power_wells);
|
||||
else if (IS_BROXTON(i915))
|
||||
else if (display->platform.broxton)
|
||||
return set_power_wells(power_domains, bxt_power_wells);
|
||||
else if (DISPLAY_VER(i915) == 9)
|
||||
else if (DISPLAY_VER(display) == 9)
|
||||
return set_power_wells(power_domains, skl_power_wells);
|
||||
else if (IS_CHERRYVIEW(i915))
|
||||
else if (display->platform.cherryview)
|
||||
return set_power_wells(power_domains, chv_power_wells);
|
||||
else if (IS_BROADWELL(i915))
|
||||
else if (display->platform.broadwell)
|
||||
return set_power_wells(power_domains, bdw_power_wells);
|
||||
else if (IS_HASWELL(i915))
|
||||
else if (display->platform.haswell)
|
||||
return set_power_wells(power_domains, hsw_power_wells);
|
||||
else if (IS_VALLEYVIEW(i915))
|
||||
else if (display->platform.valleyview)
|
||||
return set_power_wells(power_domains, vlv_power_wells);
|
||||
else if (IS_I830(i915))
|
||||
else if (display->platform.i830)
|
||||
return set_power_wells(power_domains, i830_power_wells);
|
||||
else
|
||||
return set_power_wells(power_domains, i9xx_power_wells);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,21 +10,20 @@
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_dpio_phy.h"
|
||||
|
||||
struct drm_i915_private;
|
||||
struct i915_power_well_ops;
|
||||
struct intel_display;
|
||||
struct intel_encoder;
|
||||
|
||||
#define for_each_power_well(__dev_priv, __power_well) \
|
||||
for ((__power_well) = (__dev_priv)->display.power.domains.power_wells; \
|
||||
(__power_well) - (__dev_priv)->display.power.domains.power_wells < \
|
||||
(__dev_priv)->display.power.domains.power_well_count; \
|
||||
#define for_each_power_well(___display, __power_well) \
|
||||
for ((__power_well) = (___display)->power.domains.power_wells; \
|
||||
(__power_well) - (___display)->power.domains.power_wells < \
|
||||
(___display)->power.domains.power_well_count; \
|
||||
(__power_well)++)
|
||||
|
||||
#define for_each_power_well_reverse(__dev_priv, __power_well) \
|
||||
for ((__power_well) = (__dev_priv)->display.power.domains.power_wells + \
|
||||
(__dev_priv)->display.power.domains.power_well_count - 1; \
|
||||
(__power_well) - (__dev_priv)->display.power.domains.power_wells >= 0; \
|
||||
#define for_each_power_well_reverse(___display, __power_well) \
|
||||
for ((__power_well) = (___display)->power.domains.power_wells + \
|
||||
(___display)->power.domains.power_well_count - 1; \
|
||||
(__power_well) - (___display)->power.domains.power_wells >= 0; \
|
||||
(__power_well)--)
|
||||
|
||||
/*
|
||||
@ -127,23 +126,23 @@ struct i915_power_well {
|
||||
u8 instance_idx;
|
||||
};
|
||||
|
||||
struct i915_power_well *lookup_power_well(struct drm_i915_private *i915,
|
||||
struct i915_power_well *lookup_power_well(struct intel_display *display,
|
||||
enum i915_power_well_id id);
|
||||
|
||||
void intel_power_well_enable(struct drm_i915_private *i915,
|
||||
void intel_power_well_enable(struct intel_display *display,
|
||||
struct i915_power_well *power_well);
|
||||
void intel_power_well_disable(struct drm_i915_private *i915,
|
||||
void intel_power_well_disable(struct intel_display *display,
|
||||
struct i915_power_well *power_well);
|
||||
void intel_power_well_sync_hw(struct drm_i915_private *i915,
|
||||
void intel_power_well_sync_hw(struct intel_display *display,
|
||||
struct i915_power_well *power_well);
|
||||
void intel_power_well_get(struct drm_i915_private *i915,
|
||||
void intel_power_well_get(struct intel_display *display,
|
||||
struct i915_power_well *power_well);
|
||||
void intel_power_well_put(struct drm_i915_private *i915,
|
||||
void intel_power_well_put(struct intel_display *display,
|
||||
struct i915_power_well *power_well);
|
||||
bool intel_power_well_is_enabled(struct drm_i915_private *i915,
|
||||
bool intel_power_well_is_enabled(struct intel_display *display,
|
||||
struct i915_power_well *power_well);
|
||||
bool intel_power_well_is_enabled_cached(struct i915_power_well *power_well);
|
||||
bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
|
||||
bool intel_display_power_well_is_enabled(struct intel_display *display,
|
||||
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);
|
||||
@ -152,7 +151,7 @@ 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,
|
||||
bool chv_phy_powergate_ch(struct intel_display *display, enum dpio_phy phy,
|
||||
enum dpio_channel ch, bool override);
|
||||
|
||||
void gen9_enable_dc5(struct intel_display *display);
|
||||
|
@ -114,11 +114,11 @@ void intel_display_reset_finish(struct drm_i915_private *i915)
|
||||
* so need a full re-initialization.
|
||||
*/
|
||||
intel_pps_unlock_regs_wa(display);
|
||||
intel_display_driver_init_hw(i915);
|
||||
intel_display_driver_init_hw(display);
|
||||
intel_clock_gating_init(i915);
|
||||
intel_hpd_init(i915);
|
||||
|
||||
ret = __intel_display_driver_resume(i915, state, ctx);
|
||||
ret = __intel_display_driver_resume(display, state, ctx);
|
||||
if (ret)
|
||||
drm_err(&i915->drm,
|
||||
"Restoring old state failed with %i\n", ret);
|
||||
|
@ -3,7 +3,9 @@
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include <drm/drm_drv.h>
|
||||
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_device.h"
|
||||
#include "intel_display_params.h"
|
||||
#include "intel_display_snapshot.h"
|
||||
|
@ -14,8 +14,8 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_limits.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_vblank.h"
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "i915_vma_types.h"
|
||||
#include "intel_bios.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_conversion.h"
|
||||
#include "intel_display_limits.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_dpll_mgr.h"
|
||||
@ -301,6 +302,15 @@ struct intel_panel_bl_funcs {
|
||||
u32 (*hz_to_pwm)(struct intel_connector *connector, u32 hz);
|
||||
};
|
||||
|
||||
/* in 100us units */
|
||||
struct intel_pps_delays {
|
||||
u16 power_up; /* eDP: T1+T3, LVDS: T1+T2 */
|
||||
u16 backlight_on; /* eDP: T8, LVDS: T5 */
|
||||
u16 backlight_off; /* eDP: T9, LVDS: T6/TX */
|
||||
u16 power_down; /* eDP: T10, LVDS: T3 */
|
||||
u16 power_cycle; /* eDP: T11+T12, LVDS: T7+T4 */
|
||||
};
|
||||
|
||||
enum drrs_type {
|
||||
DRRS_TYPE_NONE,
|
||||
DRRS_TYPE_STATIC,
|
||||
@ -328,7 +338,7 @@ struct intel_vbt_panel_data {
|
||||
int preemphasis;
|
||||
int vswing;
|
||||
int bpp;
|
||||
struct edp_power_seq pps;
|
||||
struct intel_pps_delays pps;
|
||||
u8 drrs_msa_timing_delay;
|
||||
bool low_vswing;
|
||||
bool hobl;
|
||||
@ -587,6 +597,8 @@ struct intel_atomic_state {
|
||||
bool skip_intermediate_wm;
|
||||
|
||||
bool rps_interactive;
|
||||
|
||||
struct work_struct cleanup_work;
|
||||
};
|
||||
|
||||
struct intel_plane_state {
|
||||
@ -697,8 +709,8 @@ struct intel_initial_plane_config {
|
||||
};
|
||||
|
||||
struct intel_scaler {
|
||||
int in_use;
|
||||
u32 mode;
|
||||
bool in_use;
|
||||
};
|
||||
|
||||
struct intel_crtc_scaler_state {
|
||||
@ -769,6 +781,7 @@ struct skl_wm_level {
|
||||
u8 lines;
|
||||
bool enable;
|
||||
bool ignore_lines;
|
||||
bool auto_min_alloc_wm_enable;
|
||||
bool can_sagv;
|
||||
};
|
||||
|
||||
@ -863,6 +876,13 @@ struct intel_crtc_wm_state {
|
||||
struct skl_ddb_entry plane_ddb[I915_MAX_PLANES];
|
||||
/* pre-icl: for planar Y */
|
||||
struct skl_ddb_entry plane_ddb_y[I915_MAX_PLANES];
|
||||
|
||||
/*
|
||||
* xe3: Minimum amount of display blocks and minimum
|
||||
* sagv allocation required for async flip
|
||||
*/
|
||||
u16 plane_min_ddb[I915_MAX_PLANES];
|
||||
u16 plane_interim_ddb[I915_MAX_PLANES];
|
||||
} skl;
|
||||
|
||||
struct {
|
||||
@ -1235,7 +1255,7 @@ struct intel_crtc_state {
|
||||
/* Display Stream compression state */
|
||||
struct {
|
||||
bool compression_enable;
|
||||
bool dsc_split;
|
||||
int num_streams;
|
||||
/* Compressed Bpp in U6.4 format (first 4 bits for fractional part) */
|
||||
u16 compressed_bpp_x16;
|
||||
u8 slice_count;
|
||||
@ -1568,8 +1588,8 @@ struct intel_pps {
|
||||
* requiring a reinitialization. Only relevant on BXT+.
|
||||
*/
|
||||
bool bxt_pps_reset;
|
||||
struct edp_power_seq pps_delays;
|
||||
struct edp_power_seq bios_pps_delays;
|
||||
struct intel_pps_delays pps_delays;
|
||||
struct intel_pps_delays bios_pps_delays;
|
||||
};
|
||||
|
||||
struct intel_psr {
|
||||
@ -1803,11 +1823,13 @@ struct intel_lspcon {
|
||||
|
||||
struct intel_digital_port {
|
||||
struct intel_encoder base;
|
||||
u32 saved_port_bits;
|
||||
struct intel_dp dp;
|
||||
struct intel_hdmi hdmi;
|
||||
struct intel_lspcon lspcon;
|
||||
enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool);
|
||||
|
||||
bool lane_reversal;
|
||||
bool ddi_a_4_lanes;
|
||||
bool release_cl2_override;
|
||||
u8 max_lanes;
|
||||
/* Used for DP and ICL+ TypeC/DP and TypeC/HDMI ports. */
|
||||
@ -2086,7 +2108,7 @@ to_intel_frontbuffer(struct drm_framebuffer *fb)
|
||||
* intel_display pointer.
|
||||
*/
|
||||
#define __drm_device_to_intel_display(p) \
|
||||
((p) ? &to_i915(p)->display : NULL)
|
||||
((p) ? __drm_to_display(p) : NULL)
|
||||
#define __device_to_intel_display(p) \
|
||||
__drm_device_to_intel_display(dev_get_drvdata(p))
|
||||
#define __pci_dev_to_intel_display(p) \
|
||||
|
@ -638,8 +638,6 @@ void intel_dmc_disable_program(struct intel_display *display)
|
||||
pipedmc_clock_gating_wa(display, true);
|
||||
disable_all_event_handlers(display);
|
||||
pipedmc_clock_gating_wa(display, false);
|
||||
|
||||
intel_dmc_wl_disable(display);
|
||||
}
|
||||
|
||||
void assert_dmc_loaded(struct intel_display *display)
|
||||
@ -1146,8 +1144,6 @@ void intel_dmc_suspend(struct intel_display *display)
|
||||
if (dmc)
|
||||
flush_work(&dmc->work);
|
||||
|
||||
intel_dmc_wl_disable(display);
|
||||
|
||||
/* Drop the reference held in case DMC isn't loaded. */
|
||||
if (!intel_dmc_has_payload(display))
|
||||
intel_dmc_runtime_pm_put(display);
|
||||
|
@ -5,6 +5,10 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_dmc.h"
|
||||
#include "intel_dmc_regs.h"
|
||||
@ -39,7 +43,11 @@
|
||||
* potential future use.
|
||||
*/
|
||||
|
||||
#define DMC_WAKELOCK_CTL_TIMEOUT 5
|
||||
/*
|
||||
* Define DMC_WAKELOCK_CTL_TIMEOUT_US in microseconds because we use the
|
||||
* atomic variant of waiting MMIO.
|
||||
*/
|
||||
#define DMC_WAKELOCK_CTL_TIMEOUT_US 5000
|
||||
#define DMC_WAKELOCK_HOLD_TIME 50
|
||||
|
||||
struct intel_dmc_wl_range {
|
||||
@ -47,8 +55,90 @@ struct intel_dmc_wl_range {
|
||||
u32 end;
|
||||
};
|
||||
|
||||
static struct intel_dmc_wl_range lnl_wl_range[] = {
|
||||
static struct intel_dmc_wl_range powered_off_ranges[] = {
|
||||
{ .start = 0x60000, .end = 0x7ffff },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct intel_dmc_wl_range xe3lpd_dc5_dc6_dmc_ranges[] = {
|
||||
{ .start = 0x45500 }, /* DC_STATE_SEL */
|
||||
{ .start = 0x457a0, .end = 0x457b0 }, /* DC*_RESIDENCY_COUNTER */
|
||||
{ .start = 0x45504 }, /* DC_STATE_EN */
|
||||
{ .start = 0x45400, .end = 0x4540c }, /* PWR_WELL_CTL_* */
|
||||
{ .start = 0x454f0 }, /* RETENTION_CTRL */
|
||||
|
||||
/* DBUF_CTL_* */
|
||||
{ .start = 0x44300 },
|
||||
{ .start = 0x44304 },
|
||||
{ .start = 0x44f00 },
|
||||
{ .start = 0x44f04 },
|
||||
{ .start = 0x44fe8 },
|
||||
{ .start = 0x45008 },
|
||||
|
||||
{ .start = 0x46070 }, /* CDCLK_PLL_ENABLE */
|
||||
{ .start = 0x46000 }, /* CDCLK_CTL */
|
||||
{ .start = 0x46008 }, /* CDCLK_SQUASH_CTL */
|
||||
|
||||
/* TRANS_CMTG_CTL_* */
|
||||
{ .start = 0x6fa88 },
|
||||
{ .start = 0x6fb88 },
|
||||
|
||||
{ .start = 0x46430 }, /* CHICKEN_DCPR_1 */
|
||||
{ .start = 0x46434 }, /* CHICKEN_DCPR_2 */
|
||||
{ .start = 0x454a0 }, /* CHICKEN_DCPR_4 */
|
||||
{ .start = 0x42084 }, /* CHICKEN_MISC_2 */
|
||||
{ .start = 0x42088 }, /* CHICKEN_MISC_3 */
|
||||
{ .start = 0x46160 }, /* CMTG_CLK_SEL */
|
||||
{ .start = 0x8f000, .end = 0x8ffff }, /* Main DMC registers */
|
||||
|
||||
{},
|
||||
};
|
||||
|
||||
static struct intel_dmc_wl_range xe3lpd_dc3co_dmc_ranges[] = {
|
||||
{ .start = 0x454a0 }, /* CHICKEN_DCPR_4 */
|
||||
|
||||
{ .start = 0x45504 }, /* DC_STATE_EN */
|
||||
|
||||
/* DBUF_CTL_* */
|
||||
{ .start = 0x44300 },
|
||||
{ .start = 0x44304 },
|
||||
{ .start = 0x44f00 },
|
||||
{ .start = 0x44f04 },
|
||||
{ .start = 0x44fe8 },
|
||||
{ .start = 0x45008 },
|
||||
|
||||
{ .start = 0x46070 }, /* CDCLK_PLL_ENABLE */
|
||||
{ .start = 0x46000 }, /* CDCLK_CTL */
|
||||
{ .start = 0x46008 }, /* CDCLK_SQUASH_CTL */
|
||||
{ .start = 0x8f000, .end = 0x8ffff }, /* Main DMC registers */
|
||||
|
||||
/* Scanline registers */
|
||||
{ .start = 0x70000 },
|
||||
{ .start = 0x70004 },
|
||||
{ .start = 0x70014 },
|
||||
{ .start = 0x70018 },
|
||||
{ .start = 0x71000 },
|
||||
{ .start = 0x71004 },
|
||||
{ .start = 0x71014 },
|
||||
{ .start = 0x71018 },
|
||||
{ .start = 0x72000 },
|
||||
{ .start = 0x72004 },
|
||||
{ .start = 0x72014 },
|
||||
{ .start = 0x72018 },
|
||||
{ .start = 0x73000 },
|
||||
{ .start = 0x73004 },
|
||||
{ .start = 0x73014 },
|
||||
{ .start = 0x73018 },
|
||||
{ .start = 0x7b000 },
|
||||
{ .start = 0x7b004 },
|
||||
{ .start = 0x7b014 },
|
||||
{ .start = 0x7b018 },
|
||||
{ .start = 0x7c000 },
|
||||
{ .start = 0x7c004 },
|
||||
{ .start = 0x7c014 },
|
||||
{ .start = 0x7c018 },
|
||||
|
||||
{},
|
||||
};
|
||||
|
||||
static void __intel_dmc_wl_release(struct intel_display *display)
|
||||
@ -72,15 +162,18 @@ static void intel_dmc_wl_work(struct work_struct *work)
|
||||
|
||||
spin_lock_irqsave(&wl->lock, flags);
|
||||
|
||||
/* Bail out if refcount reached zero while waiting for the spinlock */
|
||||
if (!refcount_read(&wl->refcount))
|
||||
/*
|
||||
* Bail out if refcount became non-zero while waiting for the spinlock,
|
||||
* meaning that the lock is now taken again.
|
||||
*/
|
||||
if (refcount_read(&wl->refcount))
|
||||
goto out_unlock;
|
||||
|
||||
__intel_de_rmw_nowl(display, DMC_WAKELOCK1_CTL, DMC_WAKELOCK_CTL_REQ, 0);
|
||||
|
||||
if (__intel_de_wait_for_register_nowl(display, DMC_WAKELOCK1_CTL,
|
||||
DMC_WAKELOCK_CTL_ACK, 0,
|
||||
DMC_WAKELOCK_CTL_TIMEOUT)) {
|
||||
if (__intel_de_wait_for_register_atomic_nowl(display, DMC_WAKELOCK1_CTL,
|
||||
DMC_WAKELOCK_CTL_ACK, 0,
|
||||
DMC_WAKELOCK_CTL_TIMEOUT_US)) {
|
||||
WARN_RATELIMIT(1, "DMC wakelock release timed out");
|
||||
goto out_unlock;
|
||||
}
|
||||
@ -91,38 +184,110 @@ static void intel_dmc_wl_work(struct work_struct *work)
|
||||
spin_unlock_irqrestore(&wl->lock, flags);
|
||||
}
|
||||
|
||||
static bool intel_dmc_wl_check_range(u32 address)
|
||||
static void __intel_dmc_wl_take(struct intel_display *display)
|
||||
{
|
||||
int i;
|
||||
bool wl_needed = false;
|
||||
struct intel_dmc_wl *wl = &display->wl;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lnl_wl_range); i++) {
|
||||
if (address >= lnl_wl_range[i].start &&
|
||||
address <= lnl_wl_range[i].end) {
|
||||
wl_needed = true;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Only try to take the wakelock if it's not marked as taken
|
||||
* yet. It may be already taken at this point if we have
|
||||
* already released the last reference, but the work has not
|
||||
* run yet.
|
||||
*/
|
||||
if (wl->taken)
|
||||
return;
|
||||
|
||||
__intel_de_rmw_nowl(display, DMC_WAKELOCK1_CTL, 0,
|
||||
DMC_WAKELOCK_CTL_REQ);
|
||||
|
||||
/*
|
||||
* We need to use the atomic variant of the waiting routine
|
||||
* because the DMC wakelock is also taken in atomic context.
|
||||
*/
|
||||
if (__intel_de_wait_for_register_atomic_nowl(display, DMC_WAKELOCK1_CTL,
|
||||
DMC_WAKELOCK_CTL_ACK,
|
||||
DMC_WAKELOCK_CTL_ACK,
|
||||
DMC_WAKELOCK_CTL_TIMEOUT_US)) {
|
||||
WARN_RATELIMIT(1, "DMC wakelock ack timed out");
|
||||
return;
|
||||
}
|
||||
|
||||
return wl_needed;
|
||||
wl->taken = true;
|
||||
}
|
||||
|
||||
static bool intel_dmc_wl_reg_in_range(i915_reg_t reg,
|
||||
const struct intel_dmc_wl_range ranges[])
|
||||
{
|
||||
u32 offset = i915_mmio_reg_offset(reg);
|
||||
|
||||
for (int i = 0; ranges[i].start; i++) {
|
||||
u32 end = ranges[i].end ?: ranges[i].start;
|
||||
|
||||
if (ranges[i].start <= offset && offset <= end)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool intel_dmc_wl_check_range(i915_reg_t reg, u32 dc_state)
|
||||
{
|
||||
const struct intel_dmc_wl_range *ranges;
|
||||
|
||||
/*
|
||||
* Check that the offset is in one of the ranges for which
|
||||
* registers are powered off during DC states.
|
||||
*/
|
||||
if (intel_dmc_wl_reg_in_range(reg, powered_off_ranges))
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Check that the offset is for a register that is touched by
|
||||
* the DMC and requires a DC exit for proper access.
|
||||
*/
|
||||
switch (dc_state) {
|
||||
case DC_STATE_EN_DC3CO:
|
||||
ranges = xe3lpd_dc3co_dmc_ranges;
|
||||
break;
|
||||
case DC_STATE_EN_UPTO_DC5:
|
||||
case DC_STATE_EN_UPTO_DC6:
|
||||
ranges = xe3lpd_dc5_dc6_dmc_ranges;
|
||||
break;
|
||||
default:
|
||||
ranges = NULL;
|
||||
}
|
||||
|
||||
if (ranges && intel_dmc_wl_reg_in_range(reg, ranges))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool __intel_dmc_wl_supported(struct intel_display *display)
|
||||
{
|
||||
if (DISPLAY_VER(display) < 20 ||
|
||||
!intel_dmc_has_payload(display) ||
|
||||
!display->params.enable_dmc_wl)
|
||||
return false;
|
||||
return display->params.enable_dmc_wl && intel_dmc_has_payload(display);
|
||||
}
|
||||
|
||||
return true;
|
||||
static void intel_dmc_wl_sanitize_param(struct intel_display *display)
|
||||
{
|
||||
if (!HAS_DMC_WAKELOCK(display))
|
||||
display->params.enable_dmc_wl = 0;
|
||||
else if (display->params.enable_dmc_wl >= 0)
|
||||
display->params.enable_dmc_wl = !!display->params.enable_dmc_wl;
|
||||
else
|
||||
display->params.enable_dmc_wl = DISPLAY_VER(display) >= 30;
|
||||
|
||||
drm_dbg_kms(display->drm, "Sanitized enable_dmc_wl value: %d\n",
|
||||
display->params.enable_dmc_wl);
|
||||
}
|
||||
|
||||
void intel_dmc_wl_init(struct intel_display *display)
|
||||
{
|
||||
struct intel_dmc_wl *wl = &display->wl;
|
||||
|
||||
/* don't call __intel_dmc_wl_supported(), DMC is not loaded yet */
|
||||
if (DISPLAY_VER(display) < 20 || !display->params.enable_dmc_wl)
|
||||
intel_dmc_wl_sanitize_param(display);
|
||||
|
||||
if (!display->params.enable_dmc_wl)
|
||||
return;
|
||||
|
||||
INIT_DELAYED_WORK(&wl->work, intel_dmc_wl_work);
|
||||
@ -130,7 +295,8 @@ void intel_dmc_wl_init(struct intel_display *display)
|
||||
refcount_set(&wl->refcount, 0);
|
||||
}
|
||||
|
||||
void intel_dmc_wl_enable(struct intel_display *display)
|
||||
/* Must only be called as part of enabling dynamic DC states. */
|
||||
void intel_dmc_wl_enable(struct intel_display *display, u32 dc_state)
|
||||
{
|
||||
struct intel_dmc_wl *wl = &display->wl;
|
||||
unsigned long flags;
|
||||
@ -140,7 +306,9 @@ void intel_dmc_wl_enable(struct intel_display *display)
|
||||
|
||||
spin_lock_irqsave(&wl->lock, flags);
|
||||
|
||||
if (wl->enabled)
|
||||
wl->dc_state = dc_state;
|
||||
|
||||
if (drm_WARN_ON(display->drm, wl->enabled))
|
||||
goto out_unlock;
|
||||
|
||||
/*
|
||||
@ -151,12 +319,29 @@ void intel_dmc_wl_enable(struct intel_display *display)
|
||||
__intel_de_rmw_nowl(display, DMC_WAKELOCK_CFG, 0, DMC_WAKELOCK_CFG_ENABLE);
|
||||
|
||||
wl->enabled = true;
|
||||
wl->taken = false;
|
||||
|
||||
/*
|
||||
* This would be racy in the following scenario:
|
||||
*
|
||||
* 1. Function A calls intel_dmc_wl_get();
|
||||
* 2. Some function calls intel_dmc_wl_disable();
|
||||
* 3. Some function calls intel_dmc_wl_enable();
|
||||
* 4. Concurrently with (3), function A performs the MMIO in between
|
||||
* setting DMC_WAKELOCK_CFG_ENABLE and asserting the lock with
|
||||
* __intel_dmc_wl_take().
|
||||
*
|
||||
* TODO: Check with the hardware team whether it is safe to assert the
|
||||
* hardware lock before enabling to avoid such a scenario. Otherwise, we
|
||||
* would need to deal with it via software synchronization.
|
||||
*/
|
||||
if (refcount_read(&wl->refcount))
|
||||
__intel_dmc_wl_take(display);
|
||||
|
||||
out_unlock:
|
||||
spin_unlock_irqrestore(&wl->lock, flags);
|
||||
}
|
||||
|
||||
/* Must only be called as part of disabling dynamic DC states. */
|
||||
void intel_dmc_wl_disable(struct intel_display *display)
|
||||
{
|
||||
struct intel_dmc_wl *wl = &display->wl;
|
||||
@ -165,24 +350,44 @@ void intel_dmc_wl_disable(struct intel_display *display)
|
||||
if (!__intel_dmc_wl_supported(display))
|
||||
return;
|
||||
|
||||
flush_delayed_work(&wl->work);
|
||||
intel_dmc_wl_flush_release_work(display);
|
||||
|
||||
spin_lock_irqsave(&wl->lock, flags);
|
||||
|
||||
if (!wl->enabled)
|
||||
if (drm_WARN_ON(display->drm, !wl->enabled))
|
||||
goto out_unlock;
|
||||
|
||||
/* Disable wakelock in DMC */
|
||||
__intel_de_rmw_nowl(display, DMC_WAKELOCK_CFG, DMC_WAKELOCK_CFG_ENABLE, 0);
|
||||
|
||||
refcount_set(&wl->refcount, 0);
|
||||
wl->enabled = false;
|
||||
|
||||
/*
|
||||
* The spec is not explicit about the expectation of existing
|
||||
* lock users at the moment of disabling, but it does say that we must
|
||||
* clear DMC_WAKELOCK_CTL_REQ, which gives us a clue that it is okay to
|
||||
* disable with existing lock users.
|
||||
*
|
||||
* TODO: Get the correct expectation from the hardware team.
|
||||
*/
|
||||
__intel_de_rmw_nowl(display, DMC_WAKELOCK1_CTL, DMC_WAKELOCK_CTL_REQ, 0);
|
||||
|
||||
wl->taken = false;
|
||||
|
||||
out_unlock:
|
||||
spin_unlock_irqrestore(&wl->lock, flags);
|
||||
}
|
||||
|
||||
void intel_dmc_wl_flush_release_work(struct intel_display *display)
|
||||
{
|
||||
struct intel_dmc_wl *wl = &display->wl;
|
||||
|
||||
if (!__intel_dmc_wl_supported(display))
|
||||
return;
|
||||
|
||||
flush_delayed_work(&wl->work);
|
||||
}
|
||||
|
||||
void intel_dmc_wl_get(struct intel_display *display, i915_reg_t reg)
|
||||
{
|
||||
struct intel_dmc_wl *wl = &display->wl;
|
||||
@ -191,14 +396,17 @@ void intel_dmc_wl_get(struct intel_display *display, i915_reg_t reg)
|
||||
if (!__intel_dmc_wl_supported(display))
|
||||
return;
|
||||
|
||||
if (!intel_dmc_wl_check_range(reg.reg))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&wl->lock, flags);
|
||||
|
||||
if (!wl->enabled)
|
||||
if (i915_mmio_reg_valid(reg) && !intel_dmc_wl_check_range(reg, wl->dc_state))
|
||||
goto out_unlock;
|
||||
|
||||
if (!wl->enabled) {
|
||||
if (!refcount_inc_not_zero(&wl->refcount))
|
||||
refcount_set(&wl->refcount, 1);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
cancel_delayed_work(&wl->work);
|
||||
|
||||
if (refcount_inc_not_zero(&wl->refcount))
|
||||
@ -206,26 +414,7 @@ void intel_dmc_wl_get(struct intel_display *display, i915_reg_t reg)
|
||||
|
||||
refcount_set(&wl->refcount, 1);
|
||||
|
||||
/*
|
||||
* Only try to take the wakelock if it's not marked as taken
|
||||
* yet. It may be already taken at this point if we have
|
||||
* already released the last reference, but the work has not
|
||||
* run yet.
|
||||
*/
|
||||
if (!wl->taken) {
|
||||
__intel_de_rmw_nowl(display, DMC_WAKELOCK1_CTL, 0,
|
||||
DMC_WAKELOCK_CTL_REQ);
|
||||
|
||||
if (__intel_de_wait_for_register_nowl(display, DMC_WAKELOCK1_CTL,
|
||||
DMC_WAKELOCK_CTL_ACK,
|
||||
DMC_WAKELOCK_CTL_ACK,
|
||||
DMC_WAKELOCK_CTL_TIMEOUT)) {
|
||||
WARN_RATELIMIT(1, "DMC wakelock ack timed out");
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
wl->taken = true;
|
||||
}
|
||||
__intel_dmc_wl_take(display);
|
||||
|
||||
out_unlock:
|
||||
spin_unlock_irqrestore(&wl->lock, flags);
|
||||
@ -239,12 +428,9 @@ void intel_dmc_wl_put(struct intel_display *display, i915_reg_t reg)
|
||||
if (!__intel_dmc_wl_supported(display))
|
||||
return;
|
||||
|
||||
if (!intel_dmc_wl_check_range(reg.reg))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&wl->lock, flags);
|
||||
|
||||
if (!wl->enabled)
|
||||
if (i915_mmio_reg_valid(reg) && !intel_dmc_wl_check_range(reg, wl->dc_state))
|
||||
goto out_unlock;
|
||||
|
||||
if (WARN_RATELIMIT(!refcount_read(&wl->refcount),
|
||||
@ -252,6 +438,9 @@ void intel_dmc_wl_put(struct intel_display *display, i915_reg_t reg)
|
||||
goto out_unlock;
|
||||
|
||||
if (refcount_dec_and_test(&wl->refcount)) {
|
||||
if (!wl->enabled)
|
||||
goto out_unlock;
|
||||
|
||||
__intel_dmc_wl_release(display);
|
||||
|
||||
goto out_unlock;
|
||||
@ -260,3 +449,13 @@ void intel_dmc_wl_put(struct intel_display *display, i915_reg_t reg)
|
||||
out_unlock:
|
||||
spin_unlock_irqrestore(&wl->lock, flags);
|
||||
}
|
||||
|
||||
void intel_dmc_wl_get_noreg(struct intel_display *display)
|
||||
{
|
||||
intel_dmc_wl_get(display, INVALID_MMIO_REG);
|
||||
}
|
||||
|
||||
void intel_dmc_wl_put_noreg(struct intel_display *display)
|
||||
{
|
||||
intel_dmc_wl_put(display, INVALID_MMIO_REG);
|
||||
}
|
||||
|
@ -15,17 +15,27 @@
|
||||
struct intel_display;
|
||||
|
||||
struct intel_dmc_wl {
|
||||
spinlock_t lock; /* protects enabled, taken and refcount */
|
||||
spinlock_t lock; /* protects enabled, taken, dc_state and refcount */
|
||||
bool enabled;
|
||||
bool taken;
|
||||
refcount_t refcount;
|
||||
/*
|
||||
* We are keeping a copy of the enabled DC state because
|
||||
* intel_display.power.domains is protected by a mutex and we do
|
||||
* not want call mutex_lock() in atomic context, where some of
|
||||
* the tracked MMIO operations happen.
|
||||
*/
|
||||
u32 dc_state;
|
||||
struct delayed_work work;
|
||||
};
|
||||
|
||||
void intel_dmc_wl_init(struct intel_display *display);
|
||||
void intel_dmc_wl_enable(struct intel_display *display);
|
||||
void intel_dmc_wl_enable(struct intel_display *display, u32 dc_state);
|
||||
void intel_dmc_wl_disable(struct intel_display *display);
|
||||
void intel_dmc_wl_flush_release_work(struct intel_display *display);
|
||||
void intel_dmc_wl_get(struct intel_display *display, i915_reg_t reg);
|
||||
void intel_dmc_wl_put(struct intel_display *display, i915_reg_t reg);
|
||||
void intel_dmc_wl_get_noreg(struct intel_display *display);
|
||||
void intel_dmc_wl_put_noreg(struct intel_display *display);
|
||||
|
||||
#endif /* __INTEL_WAKELOCK_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,14 +12,14 @@ enum intel_output_format;
|
||||
enum pipe;
|
||||
enum port;
|
||||
struct drm_connector_state;
|
||||
struct drm_encoder;
|
||||
struct drm_i915_private;
|
||||
struct drm_modeset_acquire_ctx;
|
||||
struct drm_dp_vsc_sdp;
|
||||
struct drm_encoder;
|
||||
struct drm_modeset_acquire_ctx;
|
||||
struct intel_atomic_state;
|
||||
struct intel_connector;
|
||||
struct intel_crtc_state;
|
||||
struct intel_digital_port;
|
||||
struct intel_display;
|
||||
struct intel_dp;
|
||||
struct intel_encoder;
|
||||
|
||||
@ -87,15 +87,15 @@ bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state);
|
||||
bool intel_dp_has_dsc(const struct intel_connector *connector);
|
||||
int intel_dp_link_symbol_size(int rate);
|
||||
int intel_dp_link_symbol_clock(int rate);
|
||||
bool intel_dp_is_port_edp(struct drm_i915_private *dev_priv, enum port port);
|
||||
bool intel_dp_is_port_edp(struct intel_display *display, enum port port);
|
||||
enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *dig_port,
|
||||
bool long_hpd);
|
||||
void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state);
|
||||
void intel_edp_backlight_off(const struct drm_connector_state *conn_state);
|
||||
void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp);
|
||||
void intel_dp_mst_suspend(struct drm_i915_private *dev_priv);
|
||||
void intel_dp_mst_resume(struct drm_i915_private *dev_priv);
|
||||
void intel_dp_mst_suspend(struct intel_display *display);
|
||||
void intel_dp_mst_resume(struct intel_display *display);
|
||||
int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port);
|
||||
int intel_dp_max_link_rate(struct intel_dp *intel_dp);
|
||||
int intel_dp_max_lane_count(struct intel_dp *intel_dp);
|
||||
@ -112,15 +112,15 @@ void intel_dp_reset_link_params(struct intel_dp *intel_dp);
|
||||
|
||||
void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
|
||||
u8 *link_bw, u8 *rate_select);
|
||||
bool intel_dp_source_supports_tps3(struct drm_i915_private *i915);
|
||||
bool intel_dp_source_supports_tps4(struct drm_i915_private *i915);
|
||||
bool intel_dp_source_supports_tps3(struct intel_display *display);
|
||||
bool intel_dp_source_supports_tps4(struct intel_display *display);
|
||||
|
||||
int intel_dp_link_required(int pixel_clock, int bpp);
|
||||
int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16,
|
||||
int bw_overhead);
|
||||
int intel_dp_max_link_data_rate(struct intel_dp *intel_dp,
|
||||
int max_dprx_rate, int max_dprx_lanes);
|
||||
bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915,
|
||||
bool intel_dp_joiner_needs_dsc(struct intel_display *display,
|
||||
int num_joined_pipes);
|
||||
bool intel_dp_has_joiner(struct intel_dp *intel_dp);
|
||||
bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,
|
||||
@ -137,7 +137,7 @@ bool intel_digital_port_connected(struct intel_encoder *encoder);
|
||||
bool intel_digital_port_connected_locked(struct intel_encoder *encoder);
|
||||
int intel_dp_dsc_compute_max_bpp(const struct intel_connector *connector,
|
||||
u8 dsc_max_bpc);
|
||||
u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
|
||||
u16 intel_dp_dsc_get_max_compressed_bpp(struct intel_display *display,
|
||||
u32 link_clock, u32 lane_count,
|
||||
u32 mode_clock, u32 mode_hdisplay,
|
||||
int num_joined_pipes,
|
||||
@ -173,7 +173,7 @@ bool intel_dp_supports_fec(struct intel_dp *intel_dp,
|
||||
bool intel_dp_supports_dsc(const struct intel_connector *connector,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
|
||||
u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, u32 pipe_bpp);
|
||||
u32 intel_dp_dsc_nearest_valid_bpp(struct intel_display *display, u32 bpp, u32 pipe_bpp);
|
||||
|
||||
void intel_ddi_update_pipe(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
@ -193,11 +193,11 @@ 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);
|
||||
|
||||
bool
|
||||
intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
bool dsc,
|
||||
struct link_config_limits *limits);
|
||||
bool intel_dp_compute_config_limits(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
bool respect_downstream_limits,
|
||||
bool dsc,
|
||||
struct link_config_limits *limits);
|
||||
|
||||
void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, struct intel_connector *connector);
|
||||
bool intel_dp_has_gamut_metadata_dip(struct intel_encoder *encoder);
|
||||
|
@ -5,8 +5,6 @@
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_trace.h"
|
||||
#include "intel_bios.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
@ -15,6 +13,7 @@
|
||||
#include "intel_pps.h"
|
||||
#include "intel_quirks.h"
|
||||
#include "intel_tc.h"
|
||||
#include "intel_uncore_trace.h"
|
||||
|
||||
#define AUX_CH_NAME_BUFSIZE 6
|
||||
|
||||
|
@ -34,8 +34,9 @@
|
||||
* for some reason.
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_backlight.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_dp_aux_backlight.h"
|
||||
|
@ -25,7 +25,8 @@
|
||||
|
||||
#include <drm/display/drm_dp_helper.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_dp_link_training.h"
|
||||
@ -221,7 +222,6 @@ static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEI
|
||||
int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER_CAP_SIZE])
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
if (intel_dp_is_edp(intel_dp))
|
||||
return 0;
|
||||
@ -230,7 +230,7 @@ int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER_CAP_S
|
||||
* 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(display) >= 10 && !IS_GEMINILAKE(i915))
|
||||
if (DISPLAY_VER(display) >= 10 && !display->platform.geminilake)
|
||||
if (drm_dp_dpcd_probe(&intel_dp->aux,
|
||||
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV))
|
||||
return -EIO;
|
||||
@ -262,7 +262,6 @@ int intel_dp_read_dprx_caps(struct intel_dp *intel_dp, u8 dpcd[DP_RECEIVER_CAP_S
|
||||
int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
int lttpr_count = 0;
|
||||
|
||||
/*
|
||||
@ -270,7 +269,7 @@ int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp)
|
||||
* period < 3.2ms. (see DP Standard v2.0, 2.11.2, 3.6.6.1).
|
||||
*/
|
||||
if (!intel_dp_is_edp(intel_dp) &&
|
||||
(DISPLAY_VER(display) >= 10 && !IS_GEMINILAKE(i915))) {
|
||||
(DISPLAY_VER(display) >= 10 && !display->platform.geminilake)) {
|
||||
u8 dpcd[DP_RECEIVER_CAP_SIZE];
|
||||
int err = intel_dp_read_dprx_caps(intel_dp, dpcd);
|
||||
|
||||
@ -391,10 +390,9 @@ static bool has_per_lane_signal_levels(struct intel_dp *intel_dp,
|
||||
enum drm_dp_phy dp_phy)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
return !intel_dp_phy_is_downstream_of_source(intel_dp, dp_phy) ||
|
||||
DISPLAY_VER(display) >= 10 || IS_BROXTON(i915);
|
||||
DISPLAY_VER(display) >= 10 || display->platform.broxton;
|
||||
}
|
||||
|
||||
/* 128b/132b */
|
||||
@ -898,7 +896,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
|
||||
|
||||
voltage_tries = 1;
|
||||
for (cr_tries = 0; cr_tries < max_cr_tries; ++cr_tries) {
|
||||
usleep_range(delay_us, 2 * delay_us);
|
||||
fsleep(delay_us);
|
||||
|
||||
if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, dp_phy,
|
||||
link_status) < 0) {
|
||||
@ -959,7 +957,6 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp,
|
||||
enum drm_dp_phy dp_phy)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
bool source_tps3, sink_tps3, source_tps4, sink_tps4;
|
||||
|
||||
/* UHBR+ use separate 128b/132b TPS2 */
|
||||
@ -972,7 +969,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp,
|
||||
* TPS4 as of Feb 2018 as per VESA eDP_v1.4b_E1 specification.
|
||||
* LTTPRs must support TPS4.
|
||||
*/
|
||||
source_tps4 = intel_dp_source_supports_tps4(i915);
|
||||
source_tps4 = intel_dp_source_supports_tps4(display);
|
||||
sink_tps4 = dp_phy != DP_PHY_DPRX ||
|
||||
drm_dp_tps4_supported(intel_dp->dpcd);
|
||||
if (source_tps4 && sink_tps4) {
|
||||
@ -990,7 +987,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp,
|
||||
* TPS3 support is mandatory for downstream devices that
|
||||
* support HBR2. However, not all sinks follow the spec.
|
||||
*/
|
||||
source_tps3 = intel_dp_source_supports_tps3(i915);
|
||||
source_tps3 = intel_dp_source_supports_tps3(display);
|
||||
sink_tps3 = dp_phy != DP_PHY_DPRX ||
|
||||
drm_dp_tps3_supported(intel_dp->dpcd);
|
||||
if (source_tps3 && sink_tps3) {
|
||||
@ -1040,7 +1037,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp,
|
||||
}
|
||||
|
||||
for (tries = 0; tries < 5; tries++) {
|
||||
usleep_range(delay_us, 2 * delay_us);
|
||||
fsleep(delay_us);
|
||||
|
||||
if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, dp_phy,
|
||||
link_status) < 0) {
|
||||
@ -1414,16 +1411,10 @@ intel_dp_128b132b_lane_eq(struct intel_dp *intel_dp,
|
||||
}
|
||||
|
||||
/* Time budget for the LANEx_EQ_DONE Sequence */
|
||||
deadline = jiffies + msecs_to_jiffies_timeout(400);
|
||||
deadline = jiffies + msecs_to_jiffies_timeout(450);
|
||||
|
||||
for (try = 0; try < max_tries; try++) {
|
||||
usleep_range(delay_us, 2 * delay_us);
|
||||
|
||||
/*
|
||||
* The delay may get updated. The transmitter shall read the
|
||||
* delay before link status during link training.
|
||||
*/
|
||||
delay_us = drm_dp_128b132b_read_aux_rd_interval(&intel_dp->aux);
|
||||
fsleep(delay_us);
|
||||
|
||||
if (drm_dp_dpcd_read_link_status(&intel_dp->aux, link_status) < 0) {
|
||||
lt_err(intel_dp, DP_PHY_DPRX, "Failed to read link status\n");
|
||||
@ -1451,8 +1442,15 @@ intel_dp_128b132b_lane_eq(struct intel_dp *intel_dp,
|
||||
if (time_after(jiffies, deadline))
|
||||
timeout = true; /* try one last time after deadline */
|
||||
|
||||
/* Update signal levels and training set as requested. */
|
||||
/*
|
||||
* During LT, Tx shall read AUX_RD_INTERVAL just before writing the new FFE
|
||||
* presets.
|
||||
*/
|
||||
delay_us = drm_dp_128b132b_read_aux_rd_interval(&intel_dp->aux);
|
||||
|
||||
intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX, link_status);
|
||||
|
||||
/* Update signal levels and training set as requested. */
|
||||
if (!intel_dp_update_link_train(intel_dp, crtc_state, DP_PHY_DPRX)) {
|
||||
lt_err(intel_dp, DP_PHY_DPRX, "Failed to update TX FFE settings\n");
|
||||
return false;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,6 @@
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_ddi.h"
|
||||
#include "intel_de.h"
|
||||
|
@ -3,11 +3,10 @@
|
||||
* Copyright © 2023 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
|
||||
#include <drm/display/drm_dp_tunnel.h>
|
||||
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_limits.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "bxt_dpio_phy_regs.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_ddi.h"
|
||||
#include "intel_ddi_buf_trans.h"
|
||||
@ -855,6 +856,7 @@ void chv_data_lane_soft_reset(struct intel_encoder *encoder,
|
||||
void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_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);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
@ -871,7 +873,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
|
||||
*/
|
||||
if (ch == DPIO_CH0 && pipe == PIPE_B)
|
||||
dig_port->release_cl2_override =
|
||||
!chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, true);
|
||||
!chv_phy_powergate_ch(display, DPIO_PHY0, DPIO_CH1, true);
|
||||
|
||||
chv_phy_powergate_lanes(encoder, true, lane_mask);
|
||||
|
||||
@ -1013,11 +1015,11 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
|
||||
|
||||
void chv_phy_release_cl2_override(struct intel_encoder *encoder)
|
||||
{
|
||||
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);
|
||||
|
||||
if (dig_port->release_cl2_override) {
|
||||
chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, false);
|
||||
chv_phy_powergate_ch(display, DPIO_PHY0, DPIO_CH1, false);
|
||||
dig_port->release_cl2_override = false;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string_helpers.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_crtc.h"
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/string_helpers.h>
|
||||
|
||||
#include "bxt_dpio_phy_regs.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
|
@ -205,7 +205,7 @@ void intel_dpt_resume(struct drm_i915_private *i915)
|
||||
struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb);
|
||||
|
||||
if (fb->dpt_vm)
|
||||
i915_ggtt_resume_vm(fb->dpt_vm);
|
||||
i915_ggtt_resume_vm(fb->dpt_vm, true);
|
||||
}
|
||||
mutex_unlock(&i915->drm.mode_config.fb_lock);
|
||||
}
|
||||
@ -233,7 +233,7 @@ void intel_dpt_suspend(struct drm_i915_private *i915)
|
||||
struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb);
|
||||
|
||||
if (fb->dpt_vm)
|
||||
i915_ggtt_suspend_vm(fb->dpt_vm);
|
||||
i915_ggtt_suspend_vm(fb->dpt_vm, true);
|
||||
}
|
||||
|
||||
mutex_unlock(&i915->drm.mode_config.fb_lock);
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Copyright © 2023 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
|
@ -68,7 +68,9 @@ const char *intel_drrs_type_str(enum drrs_type drrs_type)
|
||||
bool intel_cpu_transcoder_has_drrs(struct drm_i915_private *i915,
|
||||
enum transcoder cpu_transcoder)
|
||||
{
|
||||
if (HAS_DOUBLE_BUFFERED_M_N(i915))
|
||||
struct intel_display *display = &i915->display;
|
||||
|
||||
if (HAS_DOUBLE_BUFFERED_M_N(display))
|
||||
return true;
|
||||
|
||||
return intel_cpu_transcoder_has_m2_n2(i915, cpu_transcoder);
|
||||
|
@ -256,15 +256,6 @@ static bool intel_dsb_prev_ins_is_write(struct intel_dsb *dsb,
|
||||
return prev_opcode == opcode && prev_reg == i915_mmio_reg_offset(reg);
|
||||
}
|
||||
|
||||
static bool intel_dsb_prev_ins_is_mmio_write(struct intel_dsb *dsb, i915_reg_t reg)
|
||||
{
|
||||
/* only full byte-enables can be converted to indexed writes */
|
||||
return intel_dsb_prev_ins_is_write(dsb,
|
||||
DSB_OPCODE_MMIO_WRITE << DSB_OPCODE_SHIFT |
|
||||
DSB_BYTE_EN << DSB_BYTE_EN_SHIFT,
|
||||
reg);
|
||||
}
|
||||
|
||||
static bool intel_dsb_prev_ins_is_indexed_write(struct intel_dsb *dsb, i915_reg_t reg)
|
||||
{
|
||||
return intel_dsb_prev_ins_is_write(dsb,
|
||||
@ -273,7 +264,7 @@ static bool intel_dsb_prev_ins_is_indexed_write(struct intel_dsb *dsb, i915_reg_
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dsb_reg_write_indexed() - Emit register wriite to the DSB context
|
||||
* intel_dsb_reg_write_indexed() - Emit indexed register write to the DSB context
|
||||
* @dsb: DSB context
|
||||
* @reg: register address.
|
||||
* @val: value.
|
||||
@ -304,44 +295,23 @@ void intel_dsb_reg_write_indexed(struct intel_dsb *dsb,
|
||||
* we are writing odd no of dwords, Zeros will be added in the end for
|
||||
* padding.
|
||||
*/
|
||||
if (!intel_dsb_prev_ins_is_mmio_write(dsb, reg) &&
|
||||
!intel_dsb_prev_ins_is_indexed_write(dsb, reg)) {
|
||||
intel_dsb_emit(dsb, val,
|
||||
(DSB_OPCODE_MMIO_WRITE << DSB_OPCODE_SHIFT) |
|
||||
(DSB_BYTE_EN << DSB_BYTE_EN_SHIFT) |
|
||||
if (!intel_dsb_prev_ins_is_indexed_write(dsb, reg))
|
||||
intel_dsb_emit(dsb, 0, /* count */
|
||||
(DSB_OPCODE_INDEXED_WRITE << DSB_OPCODE_SHIFT) |
|
||||
i915_mmio_reg_offset(reg));
|
||||
} else {
|
||||
if (!assert_dsb_has_room(dsb))
|
||||
return;
|
||||
|
||||
/* convert to indexed write? */
|
||||
if (intel_dsb_prev_ins_is_mmio_write(dsb, reg)) {
|
||||
u32 prev_val = dsb->ins[0];
|
||||
if (!assert_dsb_has_room(dsb))
|
||||
return;
|
||||
|
||||
dsb->ins[0] = 1; /* count */
|
||||
dsb->ins[1] = (DSB_OPCODE_INDEXED_WRITE << DSB_OPCODE_SHIFT) |
|
||||
i915_mmio_reg_offset(reg);
|
||||
/* Update the count */
|
||||
dsb->ins[0]++;
|
||||
intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 0,
|
||||
dsb->ins[0]);
|
||||
|
||||
intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 0,
|
||||
dsb->ins[0]);
|
||||
intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 1,
|
||||
dsb->ins[1]);
|
||||
intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 2,
|
||||
prev_val);
|
||||
|
||||
dsb->free_pos++;
|
||||
}
|
||||
|
||||
intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos++, val);
|
||||
/* Update the count */
|
||||
dsb->ins[0]++;
|
||||
intel_dsb_buffer_write(&dsb->dsb_buf, dsb->ins_start_offset + 0,
|
||||
dsb->ins[0]);
|
||||
|
||||
/* if number of data words is odd, then the last dword should be 0.*/
|
||||
if (dsb->free_pos & 0x1)
|
||||
intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos, 0);
|
||||
}
|
||||
intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos++, val);
|
||||
/* if number of data words is odd, then the last dword should be 0.*/
|
||||
if (dsb->free_pos & 0x1)
|
||||
intel_dsb_buffer_write(&dsb->dsb_buf, dsb->free_pos, 0);
|
||||
}
|
||||
|
||||
void intel_dsb_reg_write(struct intel_dsb *dsb,
|
||||
|
@ -745,6 +745,23 @@ void intel_dsi_log_params(struct intel_dsi *intel_dsi)
|
||||
str_enabled_disabled(!(intel_dsi->video_frmt_cfg_bits & DISABLE_VIDEO_BTA)));
|
||||
}
|
||||
|
||||
static enum mipi_dsi_pixel_format vbt_to_dsi_pixel_format(unsigned int format)
|
||||
{
|
||||
switch (format) {
|
||||
case PIXEL_FORMAT_RGB888:
|
||||
return MIPI_DSI_FMT_RGB888;
|
||||
case PIXEL_FORMAT_RGB666_LOOSELY_PACKED:
|
||||
return MIPI_DSI_FMT_RGB666;
|
||||
case PIXEL_FORMAT_RGB666:
|
||||
return MIPI_DSI_FMT_RGB666_PACKED;
|
||||
case PIXEL_FORMAT_RGB565:
|
||||
return MIPI_DSI_FMT_RGB565;
|
||||
default:
|
||||
MISSING_CASE(format);
|
||||
return MIPI_DSI_FMT_RGB666;
|
||||
}
|
||||
}
|
||||
|
||||
bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
|
||||
{
|
||||
struct drm_device *dev = intel_dsi->base.base.dev;
|
||||
@ -762,8 +779,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
|
||||
intel_dsi->clock_stop = mipi_config->enable_clk_stop ? 1 : 0;
|
||||
intel_dsi->lane_count = mipi_config->lane_cnt + 1;
|
||||
intel_dsi->pixel_format =
|
||||
pixel_format_from_register_bits(
|
||||
mipi_config->videomode_color_format << 7);
|
||||
vbt_to_dsi_pixel_format(mipi_config->videomode_color_format);
|
||||
|
||||
intel_dsi->dual_link = mipi_config->dual_link;
|
||||
intel_dsi->pixel_overlap = mipi_config->pixel_overlap;
|
||||
|
@ -318,6 +318,7 @@ static void intel_dvo_pre_enable(struct intel_atomic_state *state,
|
||||
static enum drm_connector_status
|
||||
intel_dvo_detect(struct drm_connector *_connector, bool force)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(_connector->dev);
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
|
||||
@ -325,10 +326,10 @@ intel_dvo_detect(struct drm_connector *_connector, bool force)
|
||||
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]\n",
|
||||
connector->base.base.id, connector->base.name);
|
||||
|
||||
if (!intel_display_device_enabled(i915))
|
||||
if (!intel_display_device_enabled(display))
|
||||
return connector_status_disconnected;
|
||||
|
||||
if (!intel_display_driver_check_access(i915))
|
||||
if (!intel_display_driver_check_access(display))
|
||||
return connector->base.status;
|
||||
|
||||
return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev);
|
||||
@ -336,11 +337,11 @@ intel_dvo_detect(struct drm_connector *_connector, bool force)
|
||||
|
||||
static int intel_dvo_get_modes(struct drm_connector *_connector)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(_connector->dev);
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
int num_modes;
|
||||
|
||||
if (!intel_display_driver_check_access(i915))
|
||||
if (!intel_display_driver_check_access(display))
|
||||
return drm_edid_connector_add_modes(&connector->base);
|
||||
|
||||
/*
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <drm/drm_fixed.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_crtc.h"
|
||||
|
@ -496,14 +496,13 @@ static int
|
||||
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;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
if (HAS_GMBUS_BURST_READ(i915))
|
||||
if (HAS_GMBUS_BURST_READ(display))
|
||||
len = min(rx_size, INTEL_GMBUS_BURST_READ_MAX_LEN);
|
||||
else
|
||||
len = min(rx_size, gmbus_max_xfer_size(display));
|
||||
|
@ -31,27 +31,33 @@
|
||||
#define KEY_LOAD_TRIES 5
|
||||
#define HDCP2_LC_RETRY_CNT 3
|
||||
|
||||
/* WA: 16022217614 */
|
||||
static void
|
||||
intel_hdcp_disable_hdcp_line_rekeying(struct intel_encoder *encoder,
|
||||
struct intel_hdcp *hdcp)
|
||||
intel_hdcp_adjust_hdcp_line_rekeying(struct intel_encoder *encoder,
|
||||
struct intel_hdcp *hdcp,
|
||||
bool enable)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
i915_reg_t rekey_reg;
|
||||
u32 rekey_bit = 0;
|
||||
|
||||
/* Here we assume HDMI is in TMDS mode of operation */
|
||||
if (encoder->type != INTEL_OUTPUT_HDMI)
|
||||
return;
|
||||
|
||||
if (DISPLAY_VER(display) >= 14) {
|
||||
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_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);
|
||||
if (DISPLAY_VER(display) >= 30) {
|
||||
rekey_reg = TRANS_DDI_FUNC_CTL(display, hdcp->cpu_transcoder);
|
||||
rekey_bit = XE3_TRANS_DDI_HDCP_LINE_REKEY_DISABLE;
|
||||
} else if (IS_DISPLAY_VERx100_STEP(display, 1401, STEP_B0, STEP_FOREVER) ||
|
||||
IS_DISPLAY_VERx100_STEP(display, 2000, STEP_B0, STEP_FOREVER)) {
|
||||
rekey_reg = TRANS_DDI_FUNC_CTL(display, hdcp->cpu_transcoder);
|
||||
rekey_bit = TRANS_DDI_HDCP_LINE_REKEY_DISABLE;
|
||||
} else if (IS_DISPLAY_VERx100_STEP(display, 1400, STEP_D0, STEP_FOREVER)) {
|
||||
rekey_reg = CHICKEN_TRANS(display, hdcp->cpu_transcoder);
|
||||
rekey_bit = HDCP_LINE_REKEY_DISABLE;
|
||||
}
|
||||
|
||||
if (rekey_bit)
|
||||
intel_de_rmw(display, rekey_reg, rekey_bit, enable ? 0 : rekey_bit);
|
||||
}
|
||||
|
||||
static int intel_conn_to_vcpi(struct intel_atomic_state *state,
|
||||
@ -343,7 +349,7 @@ static bool hdcp_key_loadable(struct intel_display *display)
|
||||
|
||||
/* PG1 (power well #1) needs to be enabled */
|
||||
with_intel_runtime_pm(&i915->runtime_pm, wakeref)
|
||||
enabled = intel_display_power_well_is_enabled(i915, id);
|
||||
enabled = intel_display_power_well_is_enabled(display, id);
|
||||
|
||||
/*
|
||||
* Another req for hdcp key loadability is enabled state of pll for
|
||||
@ -1048,6 +1054,8 @@ static int intel_hdcp1_enable(struct intel_connector *connector)
|
||||
return ret;
|
||||
}
|
||||
|
||||
intel_hdcp_adjust_hdcp_line_rekeying(connector->encoder, hdcp, true);
|
||||
|
||||
/* Incase of authentication failures, HDCP spec expects reauth. */
|
||||
for (i = 0; i < tries; i++) {
|
||||
ret = intel_hdcp_auth(connector);
|
||||
@ -2069,7 +2077,7 @@ static int _intel_hdcp2_enable(struct intel_atomic_state *state,
|
||||
connector->base.base.id, connector->base.name,
|
||||
hdcp->content_type);
|
||||
|
||||
intel_hdcp_disable_hdcp_line_rekeying(connector->encoder, hdcp);
|
||||
intel_hdcp_adjust_hdcp_line_rekeying(connector->encoder, hdcp, false);
|
||||
|
||||
ret = hdcp2_authenticate_and_encrypt(state, connector);
|
||||
if (ret) {
|
||||
|
@ -1600,14 +1600,12 @@ static
|
||||
bool intel_hdmi_hdcp_check_link(struct intel_digital_port *dig_port,
|
||||
struct intel_connector *connector)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dig_port);
|
||||
int retry;
|
||||
|
||||
for (retry = 0; retry < 3; retry++)
|
||||
if (intel_hdmi_hdcp_check_link_once(dig_port, connector))
|
||||
return true;
|
||||
|
||||
drm_err(display->drm, "Link check failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2556,10 +2554,10 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
|
||||
drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n",
|
||||
connector->base.id, connector->name);
|
||||
|
||||
if (!intel_display_device_enabled(dev_priv))
|
||||
if (!intel_display_device_enabled(display))
|
||||
return connector_status_disconnected;
|
||||
|
||||
if (!intel_display_driver_check_access(dev_priv))
|
||||
if (!intel_display_driver_check_access(display))
|
||||
return connector->status;
|
||||
|
||||
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
|
||||
@ -2586,12 +2584,11 @@ static void
|
||||
intel_hdmi_force(struct drm_connector *connector)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
struct drm_i915_private *i915 = to_i915(connector->dev);
|
||||
|
||||
drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n",
|
||||
connector->base.id, connector->name);
|
||||
|
||||
if (!intel_display_driver_check_access(i915))
|
||||
if (!intel_display_driver_check_access(display))
|
||||
return;
|
||||
|
||||
intel_hdmi_unset_edid(connector);
|
||||
|
@ -813,8 +813,10 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
|
||||
*/
|
||||
void intel_hpd_poll_enable(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
|
||||
if (!HAS_DISPLAY(dev_priv) ||
|
||||
!intel_display_device_enabled(dev_priv))
|
||||
!intel_display_device_enabled(display))
|
||||
return;
|
||||
|
||||
WRITE_ONCE(dev_priv->display.hotplug.poll_enabled, true);
|
||||
|
@ -1457,7 +1457,11 @@ void intel_hpd_enable_detection(struct intel_encoder *encoder)
|
||||
|
||||
void intel_hpd_irq_setup(struct drm_i915_private *i915)
|
||||
{
|
||||
if (i915->display.irq.display_irqs_enabled && i915->display.funcs.hotplug)
|
||||
if ((IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) &&
|
||||
!i915->display.irq.vlv_display_irqs_enabled)
|
||||
return;
|
||||
|
||||
if (i915->display.funcs.hotplug)
|
||||
i915->display.funcs.hotplug->hpd_irq_setup(i915);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,8 @@
|
||||
* Copyright © 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include <drm/drm_device.h>
|
||||
|
||||
#include "intel_de.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_hti.h"
|
||||
|
@ -5,10 +5,9 @@
|
||||
|
||||
#include <drm/drm_fixed.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp_mst.h"
|
||||
#include "intel_dp_tunnel.h"
|
||||
|
@ -7,9 +7,9 @@
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_atomic_uapi.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_load_detect.h"
|
||||
|
||||
|
@ -29,11 +29,12 @@
|
||||
#include <drm/drm_edid.h>
|
||||
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_lspcon.h"
|
||||
#include "intel_hdmi.h"
|
||||
#include "intel_lspcon.h"
|
||||
|
||||
/* LSPCON OUI Vendor ID(signatures) */
|
||||
#define LSPCON_VENDOR_PARADE_OUI 0x001CF8
|
||||
|
@ -57,12 +57,7 @@
|
||||
|
||||
/* Private structure for the integrated LVDS support */
|
||||
struct intel_lvds_pps {
|
||||
/* 100us units */
|
||||
int t1_t2;
|
||||
int t3;
|
||||
int t4;
|
||||
int t5;
|
||||
int tx;
|
||||
struct intel_pps_delays delays;
|
||||
|
||||
int divider;
|
||||
|
||||
@ -168,12 +163,12 @@ static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv,
|
||||
|
||||
val = intel_de_read(dev_priv, PP_ON_DELAYS(dev_priv, 0));
|
||||
pps->port = REG_FIELD_GET(PANEL_PORT_SELECT_MASK, val);
|
||||
pps->t1_t2 = REG_FIELD_GET(PANEL_POWER_UP_DELAY_MASK, val);
|
||||
pps->t5 = REG_FIELD_GET(PANEL_LIGHT_ON_DELAY_MASK, val);
|
||||
pps->delays.power_up = REG_FIELD_GET(PANEL_POWER_UP_DELAY_MASK, val);
|
||||
pps->delays.backlight_on = REG_FIELD_GET(PANEL_LIGHT_ON_DELAY_MASK, val);
|
||||
|
||||
val = intel_de_read(dev_priv, PP_OFF_DELAYS(dev_priv, 0));
|
||||
pps->t3 = REG_FIELD_GET(PANEL_POWER_DOWN_DELAY_MASK, val);
|
||||
pps->tx = REG_FIELD_GET(PANEL_LIGHT_OFF_DELAY_MASK, val);
|
||||
pps->delays.power_down = REG_FIELD_GET(PANEL_POWER_DOWN_DELAY_MASK, val);
|
||||
pps->delays.backlight_off = REG_FIELD_GET(PANEL_LIGHT_OFF_DELAY_MASK, val);
|
||||
|
||||
val = intel_de_read(dev_priv, PP_DIVISOR(dev_priv, 0));
|
||||
pps->divider = REG_FIELD_GET(PP_REFERENCE_DIVIDER_MASK, val);
|
||||
@ -186,25 +181,30 @@ static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv,
|
||||
if (val)
|
||||
val--;
|
||||
/* Convert from 100ms to 100us units */
|
||||
pps->t4 = val * 1000;
|
||||
pps->delays.power_cycle = val * 1000;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) < 5 &&
|
||||
pps->t1_t2 == 0 && pps->t5 == 0 && pps->t3 == 0 && pps->tx == 0) {
|
||||
pps->delays.power_up == 0 &&
|
||||
pps->delays.backlight_on == 0 &&
|
||||
pps->delays.power_down == 0 &&
|
||||
pps->delays.backlight_off == 0) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Panel power timings uninitialized, "
|
||||
"setting defaults\n");
|
||||
/* Set T2 to 40ms and T5 to 200ms in 100 usec units */
|
||||
pps->t1_t2 = 40 * 10;
|
||||
pps->t5 = 200 * 10;
|
||||
pps->delays.power_up = 40 * 10;
|
||||
pps->delays.backlight_on = 200 * 10;
|
||||
/* Set T3 to 35ms and Tx to 200ms in 100 usec units */
|
||||
pps->t3 = 35 * 10;
|
||||
pps->tx = 200 * 10;
|
||||
pps->delays.power_down = 35 * 10;
|
||||
pps->delays.backlight_off = 200 * 10;
|
||||
}
|
||||
|
||||
drm_dbg(&dev_priv->drm, "LVDS PPS:t1+t2 %d t3 %d t4 %d t5 %d tx %d "
|
||||
drm_dbg(&dev_priv->drm, "LVDS PPS:power_up %d power_down %d power_cycle %d backlight_on %d backlight_off %d "
|
||||
"divider %d port %d powerdown_on_reset %d\n",
|
||||
pps->t1_t2, pps->t3, pps->t4, pps->t5, pps->tx,
|
||||
pps->divider, pps->port, pps->powerdown_on_reset);
|
||||
pps->delays.power_up, pps->delays.power_down,
|
||||
pps->delays.power_cycle, pps->delays.backlight_on,
|
||||
pps->delays.backlight_off, pps->divider,
|
||||
pps->port, pps->powerdown_on_reset);
|
||||
}
|
||||
|
||||
static void intel_lvds_pps_init_hw(struct drm_i915_private *dev_priv,
|
||||
@ -221,16 +221,17 @@ static void intel_lvds_pps_init_hw(struct drm_i915_private *dev_priv,
|
||||
|
||||
intel_de_write(dev_priv, PP_ON_DELAYS(dev_priv, 0),
|
||||
REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, pps->port) |
|
||||
REG_FIELD_PREP(PANEL_POWER_UP_DELAY_MASK, pps->t1_t2) |
|
||||
REG_FIELD_PREP(PANEL_LIGHT_ON_DELAY_MASK, pps->t5));
|
||||
REG_FIELD_PREP(PANEL_POWER_UP_DELAY_MASK, pps->delays.power_up) |
|
||||
REG_FIELD_PREP(PANEL_LIGHT_ON_DELAY_MASK, pps->delays.backlight_on));
|
||||
|
||||
intel_de_write(dev_priv, PP_OFF_DELAYS(dev_priv, 0),
|
||||
REG_FIELD_PREP(PANEL_POWER_DOWN_DELAY_MASK, pps->t3) |
|
||||
REG_FIELD_PREP(PANEL_LIGHT_OFF_DELAY_MASK, pps->tx));
|
||||
REG_FIELD_PREP(PANEL_POWER_DOWN_DELAY_MASK, pps->delays.power_down) |
|
||||
REG_FIELD_PREP(PANEL_LIGHT_OFF_DELAY_MASK, pps->delays.backlight_off));
|
||||
|
||||
intel_de_write(dev_priv, PP_DIVISOR(dev_priv, 0),
|
||||
REG_FIELD_PREP(PP_REFERENCE_DIVIDER_MASK, pps->divider) |
|
||||
REG_FIELD_PREP(PANEL_POWER_CYCLE_DELAY_MASK, DIV_ROUND_UP(pps->t4, 1000) + 1));
|
||||
REG_FIELD_PREP(PANEL_POWER_CYCLE_DELAY_MASK,
|
||||
DIV_ROUND_UP(pps->delays.power_cycle, 1000) + 1));
|
||||
}
|
||||
|
||||
static void intel_pre_enable_lvds(struct intel_atomic_state *state,
|
||||
|
@ -1024,5 +1024,5 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915,
|
||||
|
||||
intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref);
|
||||
|
||||
intel_power_domains_sanitize_state(i915);
|
||||
intel_power_domains_sanitize_state(display);
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ struct overlay_registers {
|
||||
};
|
||||
|
||||
struct intel_overlay {
|
||||
struct drm_i915_private *i915;
|
||||
struct intel_display *display;
|
||||
struct intel_context *context;
|
||||
struct intel_crtc *crtc;
|
||||
struct i915_vma *vma;
|
||||
@ -205,17 +205,17 @@ struct intel_overlay {
|
||||
void (*flip_complete)(struct intel_overlay *ovl);
|
||||
};
|
||||
|
||||
static void i830_overlay_clock_gating(struct drm_i915_private *dev_priv,
|
||||
static void i830_overlay_clock_gating(struct intel_display *display,
|
||||
bool enable)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
|
||||
struct pci_dev *pdev = to_pci_dev(display->drm->dev);
|
||||
u8 val;
|
||||
|
||||
/* WA_OVERLAY_CLKGATE:alm */
|
||||
if (enable)
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D(dev_priv), 0);
|
||||
intel_de_write(display, DSPCLK_GATE_D(display), 0);
|
||||
else
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D(dev_priv),
|
||||
intel_de_write(display, DSPCLK_GATE_D(display),
|
||||
OVRUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
/* WA_DISABLE_L2CACHE_CLOCK_GATING:alm */
|
||||
@ -253,11 +253,11 @@ alloc_request(struct intel_overlay *overlay, void (*fn)(struct intel_overlay *))
|
||||
/* overlay needs to be disable in OCMD reg */
|
||||
static int intel_overlay_on(struct intel_overlay *overlay)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
struct intel_display *display = overlay->display;
|
||||
struct i915_request *rq;
|
||||
u32 *cs;
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, overlay->active);
|
||||
drm_WARN_ON(display->drm, overlay->active);
|
||||
|
||||
rq = alloc_request(overlay, NULL);
|
||||
if (IS_ERR(rq))
|
||||
@ -271,8 +271,8 @@ static int intel_overlay_on(struct intel_overlay *overlay)
|
||||
|
||||
overlay->active = true;
|
||||
|
||||
if (IS_I830(dev_priv))
|
||||
i830_overlay_clock_gating(dev_priv, false);
|
||||
if (display->platform.i830)
|
||||
i830_overlay_clock_gating(display, false);
|
||||
|
||||
*cs++ = MI_OVERLAY_FLIP | MI_OVERLAY_ON;
|
||||
*cs++ = overlay->flip_addr | OFC_UPDATE;
|
||||
@ -288,10 +288,12 @@ static int intel_overlay_on(struct intel_overlay *overlay)
|
||||
static void intel_overlay_flip_prepare(struct intel_overlay *overlay,
|
||||
struct i915_vma *vma)
|
||||
{
|
||||
struct intel_display *display = overlay->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
enum pipe pipe = overlay->crtc->pipe;
|
||||
struct intel_frontbuffer *frontbuffer = NULL;
|
||||
|
||||
drm_WARN_ON(&overlay->i915->drm, overlay->old_vma);
|
||||
drm_WARN_ON(display->drm, overlay->old_vma);
|
||||
|
||||
if (vma)
|
||||
frontbuffer = intel_frontbuffer_get(intel_bo_to_drm_bo(vma->obj));
|
||||
@ -303,8 +305,7 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay,
|
||||
intel_frontbuffer_put(overlay->frontbuffer);
|
||||
overlay->frontbuffer = frontbuffer;
|
||||
|
||||
intel_frontbuffer_flip_prepare(overlay->i915,
|
||||
INTEL_FRONTBUFFER_OVERLAY(pipe));
|
||||
intel_frontbuffer_flip_prepare(i915, INTEL_FRONTBUFFER_OVERLAY(pipe));
|
||||
|
||||
overlay->old_vma = overlay->vma;
|
||||
if (vma)
|
||||
@ -318,20 +319,20 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
|
||||
struct i915_vma *vma,
|
||||
bool load_polyphase_filter)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
struct intel_display *display = overlay->display;
|
||||
struct i915_request *rq;
|
||||
u32 flip_addr = overlay->flip_addr;
|
||||
u32 tmp, *cs;
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, !overlay->active);
|
||||
drm_WARN_ON(display->drm, !overlay->active);
|
||||
|
||||
if (load_polyphase_filter)
|
||||
flip_addr |= OFC_UPDATE;
|
||||
|
||||
/* check for underruns */
|
||||
tmp = intel_de_read(dev_priv, DOVSTA);
|
||||
tmp = intel_de_read(display, DOVSTA);
|
||||
if (tmp & (1 << 17))
|
||||
drm_dbg(&dev_priv->drm, "overlay underrun, DOVSTA: %x\n", tmp);
|
||||
drm_dbg(display->drm, "overlay underrun, DOVSTA: %x\n", tmp);
|
||||
|
||||
rq = alloc_request(overlay, NULL);
|
||||
if (IS_ERR(rq))
|
||||
@ -355,14 +356,15 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
|
||||
|
||||
static void intel_overlay_release_old_vma(struct intel_overlay *overlay)
|
||||
{
|
||||
struct intel_display *display = overlay->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct i915_vma *vma;
|
||||
|
||||
vma = fetch_and_zero(&overlay->old_vma);
|
||||
if (drm_WARN_ON(&overlay->i915->drm, !vma))
|
||||
if (drm_WARN_ON(display->drm, !vma))
|
||||
return;
|
||||
|
||||
intel_frontbuffer_flip_complete(overlay->i915,
|
||||
INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
|
||||
intel_frontbuffer_flip_complete(i915, INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
|
||||
|
||||
i915_vma_unpin(vma);
|
||||
i915_vma_put(vma);
|
||||
@ -376,7 +378,7 @@ intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
|
||||
|
||||
static void intel_overlay_off_tail(struct intel_overlay *overlay)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
struct intel_display *display = overlay->display;
|
||||
|
||||
intel_overlay_release_old_vma(overlay);
|
||||
|
||||
@ -384,8 +386,8 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay)
|
||||
overlay->crtc = NULL;
|
||||
overlay->active = false;
|
||||
|
||||
if (IS_I830(dev_priv))
|
||||
i830_overlay_clock_gating(dev_priv, true);
|
||||
if (display->platform.i830)
|
||||
i830_overlay_clock_gating(display, true);
|
||||
}
|
||||
|
||||
static void intel_overlay_last_flip_retire(struct i915_active *active)
|
||||
@ -400,10 +402,11 @@ static void intel_overlay_last_flip_retire(struct i915_active *active)
|
||||
/* overlay needs to be disabled in OCMD reg */
|
||||
static int intel_overlay_off(struct intel_overlay *overlay)
|
||||
{
|
||||
struct intel_display *display = overlay->display;
|
||||
struct i915_request *rq;
|
||||
u32 *cs, flip_addr = overlay->flip_addr;
|
||||
|
||||
drm_WARN_ON(&overlay->i915->drm, !overlay->active);
|
||||
drm_WARN_ON(display->drm, !overlay->active);
|
||||
|
||||
/* According to intel docs the overlay hw may hang (when switching
|
||||
* off) without loading the filter coeffs. It is however unclear whether
|
||||
@ -452,7 +455,7 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
|
||||
*/
|
||||
static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
struct intel_display *display = overlay->display;
|
||||
struct i915_request *rq;
|
||||
u32 *cs;
|
||||
|
||||
@ -463,7 +466,7 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
|
||||
if (!overlay->old_vma)
|
||||
return 0;
|
||||
|
||||
if (!(intel_de_read(dev_priv, GEN2_ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT)) {
|
||||
if (!(intel_de_read(display, GEN2_ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT)) {
|
||||
intel_overlay_release_old_vid_tail(overlay);
|
||||
return 0;
|
||||
}
|
||||
@ -487,9 +490,9 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
|
||||
return i915_active_wait(&overlay->last_flip);
|
||||
}
|
||||
|
||||
void intel_overlay_reset(struct drm_i915_private *dev_priv)
|
||||
void intel_overlay_reset(struct intel_display *display)
|
||||
{
|
||||
struct intel_overlay *overlay = dev_priv->display.overlay;
|
||||
struct intel_overlay *overlay = display->overlay;
|
||||
|
||||
if (!overlay)
|
||||
return;
|
||||
@ -550,11 +553,11 @@ static int uv_vsubsampling(u32 format)
|
||||
}
|
||||
}
|
||||
|
||||
static u32 calc_swidthsw(struct drm_i915_private *dev_priv, u32 offset, u32 width)
|
||||
static u32 calc_swidthsw(struct intel_display *display, u32 offset, u32 width)
|
||||
{
|
||||
u32 sw;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) == 2)
|
||||
if (DISPLAY_VER(display) == 2)
|
||||
sw = ALIGN((offset & 31) + width, 32);
|
||||
else
|
||||
sw = ALIGN((offset & 63) + width, 64);
|
||||
@ -789,16 +792,17 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
||||
struct drm_i915_gem_object *new_bo,
|
||||
struct drm_intel_overlay_put_image *params)
|
||||
{
|
||||
struct intel_display *display = overlay->display;
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct overlay_registers __iomem *regs = overlay->regs;
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
u32 swidth, swidthsw, sheight, ostride;
|
||||
enum pipe pipe = overlay->crtc->pipe;
|
||||
bool scale_changed = false;
|
||||
struct i915_vma *vma;
|
||||
int ret, tmp_width;
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex));
|
||||
drm_WARN_ON(display->drm,
|
||||
!drm_modeset_is_locked(&display->drm->mode_config.connection_mutex));
|
||||
|
||||
ret = intel_overlay_release_old_vid(overlay);
|
||||
if (ret != 0)
|
||||
@ -824,7 +828,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
||||
oconfig |= OCONF_CC_OUT_8BIT;
|
||||
if (crtc_state->gamma_enable)
|
||||
oconfig |= OCONF_GAMMA2_ENABLE;
|
||||
if (DISPLAY_VER(dev_priv) == 4)
|
||||
if (DISPLAY_VER(display) == 4)
|
||||
oconfig |= OCONF_CSC_MODE_BT709;
|
||||
oconfig |= pipe == 0 ?
|
||||
OCONF_PIPE_A : OCONF_PIPE_B;
|
||||
@ -845,7 +849,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
||||
tmp_width = params->src_width;
|
||||
|
||||
swidth = params->src_width;
|
||||
swidthsw = calc_swidthsw(dev_priv, params->offset_Y, tmp_width);
|
||||
swidthsw = calc_swidthsw(display, params->offset_Y, tmp_width);
|
||||
sheight = params->src_height;
|
||||
iowrite32(i915_ggtt_offset(vma) + params->offset_Y, ®s->OBUF_0Y);
|
||||
ostride = params->stride_Y;
|
||||
@ -858,9 +862,9 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
||||
swidth |= (params->src_width / uv_hscale) << 16;
|
||||
sheight |= (params->src_height / uv_vscale) << 16;
|
||||
|
||||
tmp_U = calc_swidthsw(dev_priv, params->offset_U,
|
||||
tmp_U = calc_swidthsw(display, params->offset_U,
|
||||
params->src_width / uv_hscale);
|
||||
tmp_V = calc_swidthsw(dev_priv, params->offset_V,
|
||||
tmp_V = calc_swidthsw(display, params->offset_V,
|
||||
params->src_width / uv_hscale);
|
||||
swidthsw |= max(tmp_U, tmp_V) << 16;
|
||||
|
||||
@ -899,11 +903,11 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
||||
|
||||
int intel_overlay_switch_off(struct intel_overlay *overlay)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
struct intel_display *display = overlay->display;
|
||||
int ret;
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex));
|
||||
drm_WARN_ON(display->drm,
|
||||
!drm_modeset_is_locked(&display->drm->mode_config.connection_mutex));
|
||||
|
||||
ret = intel_overlay_recover_from_interrupt(overlay);
|
||||
if (ret != 0)
|
||||
@ -936,26 +940,24 @@ static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
|
||||
|
||||
static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = overlay->i915;
|
||||
struct intel_display *display = overlay->display;
|
||||
u32 ratio;
|
||||
|
||||
/* XXX: This is not the same logic as in the xorg driver, but more in
|
||||
* line with the intel documentation for the i965
|
||||
*/
|
||||
if (DISPLAY_VER(dev_priv) >= 4) {
|
||||
u32 tmp = intel_de_read(dev_priv, PFIT_PGM_RATIOS(dev_priv));
|
||||
if (DISPLAY_VER(display) >= 4) {
|
||||
u32 tmp = intel_de_read(display, PFIT_PGM_RATIOS(display));
|
||||
|
||||
/* on i965 use the PGM reg to read out the autoscaler values */
|
||||
ratio = REG_FIELD_GET(PFIT_VERT_SCALE_MASK_965, tmp);
|
||||
} else {
|
||||
u32 tmp;
|
||||
|
||||
if (intel_de_read(dev_priv, PFIT_CONTROL(dev_priv)) & PFIT_VERT_AUTO_SCALE)
|
||||
tmp = intel_de_read(dev_priv,
|
||||
PFIT_AUTO_RATIOS(dev_priv));
|
||||
if (intel_de_read(display, PFIT_CONTROL(display)) & PFIT_VERT_AUTO_SCALE)
|
||||
tmp = intel_de_read(display, PFIT_AUTO_RATIOS(display));
|
||||
else
|
||||
tmp = intel_de_read(dev_priv,
|
||||
PFIT_PGM_RATIOS(dev_priv));
|
||||
tmp = intel_de_read(display, PFIT_PGM_RATIOS(display));
|
||||
|
||||
ratio = REG_FIELD_GET(PFIT_VERT_SCALE_MASK, tmp);
|
||||
}
|
||||
@ -1000,7 +1002,7 @@ static int check_overlay_scaling(struct drm_intel_overlay_put_image *rec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_overlay_src(struct drm_i915_private *dev_priv,
|
||||
static int check_overlay_src(struct intel_display *display,
|
||||
struct drm_intel_overlay_put_image *rec,
|
||||
struct drm_i915_gem_object *new_bo)
|
||||
{
|
||||
@ -1011,7 +1013,7 @@ static int check_overlay_src(struct drm_i915_private *dev_priv,
|
||||
u32 tmp;
|
||||
|
||||
/* check src dimensions */
|
||||
if (IS_I845G(dev_priv) || IS_I830(dev_priv)) {
|
||||
if (display->platform.i845g || display->platform.i830) {
|
||||
if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
|
||||
rec->src_width > IMAGE_MAX_WIDTH_LEGACY)
|
||||
return -EINVAL;
|
||||
@ -1063,14 +1065,14 @@ static int check_overlay_src(struct drm_i915_private *dev_priv,
|
||||
return -EINVAL;
|
||||
|
||||
/* stride checking */
|
||||
if (IS_I830(dev_priv) || IS_I845G(dev_priv))
|
||||
if (display->platform.i830 || display->platform.i845g)
|
||||
stride_mask = 255;
|
||||
else
|
||||
stride_mask = 63;
|
||||
|
||||
if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
|
||||
return -EINVAL;
|
||||
if (DISPLAY_VER(dev_priv) == 4 && rec->stride_Y < 512)
|
||||
if (DISPLAY_VER(display) == 4 && rec->stride_Y < 512)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
|
||||
@ -1114,17 +1116,17 @@ static int check_overlay_src(struct drm_i915_private *dev_priv,
|
||||
int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dev);
|
||||
struct drm_intel_overlay_put_image *params = data;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_overlay *overlay;
|
||||
struct drm_crtc *drmmode_crtc;
|
||||
struct intel_crtc *crtc;
|
||||
struct drm_i915_gem_object *new_bo;
|
||||
int ret;
|
||||
|
||||
overlay = dev_priv->display.overlay;
|
||||
overlay = display->overlay;
|
||||
if (!overlay) {
|
||||
drm_dbg(&dev_priv->drm, "userspace bug: no overlay\n");
|
||||
drm_dbg(display->drm, "userspace bug: no overlay\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -1148,7 +1150,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
if (i915_gem_object_is_tiled(new_bo)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"buffer used for overlay image can not be tiled\n");
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
@ -1197,7 +1199,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = check_overlay_src(dev_priv, params, new_bo);
|
||||
ret = check_overlay_src(display, params, new_bo);
|
||||
if (ret != 0)
|
||||
goto out_unlock;
|
||||
|
||||
@ -1277,14 +1279,14 @@ static int check_gamma(struct drm_intel_overlay_attrs *attrs)
|
||||
int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dev);
|
||||
struct drm_intel_overlay_attrs *attrs = data;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_overlay *overlay;
|
||||
int ret;
|
||||
|
||||
overlay = dev_priv->display.overlay;
|
||||
overlay = display->overlay;
|
||||
if (!overlay) {
|
||||
drm_dbg(&dev_priv->drm, "userspace bug: no overlay\n");
|
||||
drm_dbg(display->drm, "userspace bug: no overlay\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -1297,13 +1299,13 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
|
||||
attrs->contrast = overlay->contrast;
|
||||
attrs->saturation = overlay->saturation;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) != 2) {
|
||||
attrs->gamma0 = intel_de_read(dev_priv, OGAMC0);
|
||||
attrs->gamma1 = intel_de_read(dev_priv, OGAMC1);
|
||||
attrs->gamma2 = intel_de_read(dev_priv, OGAMC2);
|
||||
attrs->gamma3 = intel_de_read(dev_priv, OGAMC3);
|
||||
attrs->gamma4 = intel_de_read(dev_priv, OGAMC4);
|
||||
attrs->gamma5 = intel_de_read(dev_priv, OGAMC5);
|
||||
if (DISPLAY_VER(display) != 2) {
|
||||
attrs->gamma0 = intel_de_read(display, OGAMC0);
|
||||
attrs->gamma1 = intel_de_read(display, OGAMC1);
|
||||
attrs->gamma2 = intel_de_read(display, OGAMC2);
|
||||
attrs->gamma3 = intel_de_read(display, OGAMC3);
|
||||
attrs->gamma4 = intel_de_read(display, OGAMC4);
|
||||
attrs->gamma5 = intel_de_read(display, OGAMC5);
|
||||
}
|
||||
} else {
|
||||
if (attrs->brightness < -128 || attrs->brightness > 127)
|
||||
@ -1321,7 +1323,7 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
|
||||
update_reg_attrs(overlay, overlay->regs);
|
||||
|
||||
if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
|
||||
if (DISPLAY_VER(dev_priv) == 2)
|
||||
if (DISPLAY_VER(display) == 2)
|
||||
goto out_unlock;
|
||||
|
||||
if (overlay->active) {
|
||||
@ -1333,12 +1335,12 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
intel_de_write(dev_priv, OGAMC0, attrs->gamma0);
|
||||
intel_de_write(dev_priv, OGAMC1, attrs->gamma1);
|
||||
intel_de_write(dev_priv, OGAMC2, attrs->gamma2);
|
||||
intel_de_write(dev_priv, OGAMC3, attrs->gamma3);
|
||||
intel_de_write(dev_priv, OGAMC4, attrs->gamma4);
|
||||
intel_de_write(dev_priv, OGAMC5, attrs->gamma5);
|
||||
intel_de_write(display, OGAMC0, attrs->gamma0);
|
||||
intel_de_write(display, OGAMC1, attrs->gamma1);
|
||||
intel_de_write(display, OGAMC2, attrs->gamma2);
|
||||
intel_de_write(display, OGAMC3, attrs->gamma3);
|
||||
intel_de_write(display, OGAMC4, attrs->gamma4);
|
||||
intel_de_write(display, OGAMC5, attrs->gamma5);
|
||||
}
|
||||
}
|
||||
overlay->color_key_enabled = (attrs->flags & I915_OVERLAY_DISABLE_DEST_COLORKEY) == 0;
|
||||
@ -1352,12 +1354,13 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
static int get_registers(struct intel_overlay *overlay, bool use_phys)
|
||||
{
|
||||
struct drm_i915_private *i915 = overlay->i915;
|
||||
struct intel_display *display = overlay->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct drm_i915_gem_object *obj = ERR_PTR(-ENODEV);
|
||||
struct i915_vma *vma;
|
||||
int err;
|
||||
|
||||
if (!IS_METEORLAKE(i915)) /* Wa_22018444074 */
|
||||
if (!display->platform.meteorlake) /* Wa_22018444074 */
|
||||
obj = i915_gem_object_create_stolen(i915, PAGE_SIZE);
|
||||
if (IS_ERR(obj))
|
||||
obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
|
||||
@ -1390,13 +1393,14 @@ static int get_registers(struct intel_overlay *overlay, bool use_phys)
|
||||
return err;
|
||||
}
|
||||
|
||||
void intel_overlay_setup(struct drm_i915_private *dev_priv)
|
||||
void intel_overlay_setup(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_overlay *overlay;
|
||||
struct intel_engine_cs *engine;
|
||||
int ret;
|
||||
|
||||
if (!HAS_OVERLAY(dev_priv))
|
||||
if (!HAS_OVERLAY(display))
|
||||
return;
|
||||
|
||||
engine = to_gt(dev_priv)->engine[RCS0];
|
||||
@ -1407,7 +1411,7 @@ void intel_overlay_setup(struct drm_i915_private *dev_priv)
|
||||
if (!overlay)
|
||||
return;
|
||||
|
||||
overlay->i915 = dev_priv;
|
||||
overlay->display = display;
|
||||
overlay->context = engine->kernel_context;
|
||||
overlay->color_key = 0x0101fe;
|
||||
overlay->color_key_enabled = true;
|
||||
@ -1418,7 +1422,7 @@ void intel_overlay_setup(struct drm_i915_private *dev_priv)
|
||||
i915_active_init(&overlay->last_flip,
|
||||
NULL, intel_overlay_last_flip_retire, 0);
|
||||
|
||||
ret = get_registers(overlay, OVERLAY_NEEDS_PHYSICAL(dev_priv));
|
||||
ret = get_registers(overlay, OVERLAY_NEEDS_PHYSICAL(display));
|
||||
if (ret)
|
||||
goto out_free;
|
||||
|
||||
@ -1426,19 +1430,24 @@ void intel_overlay_setup(struct drm_i915_private *dev_priv)
|
||||
update_polyphase_filter(overlay->regs);
|
||||
update_reg_attrs(overlay, overlay->regs);
|
||||
|
||||
dev_priv->display.overlay = overlay;
|
||||
drm_info(&dev_priv->drm, "Initialized overlay support.\n");
|
||||
display->overlay = overlay;
|
||||
drm_info(display->drm, "Initialized overlay support.\n");
|
||||
return;
|
||||
|
||||
out_free:
|
||||
kfree(overlay);
|
||||
}
|
||||
|
||||
void intel_overlay_cleanup(struct drm_i915_private *dev_priv)
|
||||
bool intel_overlay_available(struct intel_display *display)
|
||||
{
|
||||
return display->overlay;
|
||||
}
|
||||
|
||||
void intel_overlay_cleanup(struct intel_display *display)
|
||||
{
|
||||
struct intel_overlay *overlay;
|
||||
|
||||
overlay = fetch_and_zero(&dev_priv->display.overlay);
|
||||
overlay = fetch_and_zero(&display->overlay);
|
||||
if (!overlay)
|
||||
return;
|
||||
|
||||
@ -1447,7 +1456,7 @@ void intel_overlay_cleanup(struct drm_i915_private *dev_priv)
|
||||
* Furthermore modesetting teardown happens beforehand so the
|
||||
* hardware should be off already.
|
||||
*/
|
||||
drm_WARN_ON(&dev_priv->drm, overlay->active);
|
||||
drm_WARN_ON(display->drm, overlay->active);
|
||||
|
||||
i915_gem_object_put(overlay->reg_bo);
|
||||
i915_active_fini(&overlay->last_flip);
|
||||
@ -1467,8 +1476,7 @@ struct intel_overlay_snapshot {
|
||||
struct intel_overlay_snapshot *
|
||||
intel_overlay_snapshot_capture(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_overlay *overlay = dev_priv->display.overlay;
|
||||
struct intel_overlay *overlay = display->overlay;
|
||||
struct intel_overlay_snapshot *error;
|
||||
|
||||
if (!overlay || !overlay->active)
|
||||
@ -1478,8 +1486,8 @@ intel_overlay_snapshot_capture(struct intel_display *display)
|
||||
if (error == NULL)
|
||||
return NULL;
|
||||
|
||||
error->dovsta = intel_de_read(dev_priv, DOVSTA);
|
||||
error->isr = intel_de_read(dev_priv, GEN2_ISR);
|
||||
error->dovsta = intel_de_read(display, DOVSTA);
|
||||
error->isr = intel_de_read(display, GEN2_ISR);
|
||||
error->base = overlay->flip_addr;
|
||||
|
||||
memcpy_fromio(&error->regs, overlay->regs, sizeof(error->regs));
|
||||
|
@ -17,19 +17,24 @@ struct intel_overlay;
|
||||
struct intel_overlay_snapshot;
|
||||
|
||||
#ifdef I915
|
||||
void intel_overlay_setup(struct drm_i915_private *dev_priv);
|
||||
void intel_overlay_cleanup(struct drm_i915_private *dev_priv);
|
||||
void intel_overlay_setup(struct intel_display *display);
|
||||
bool intel_overlay_available(struct intel_display *display);
|
||||
void intel_overlay_cleanup(struct intel_display *display);
|
||||
int intel_overlay_switch_off(struct intel_overlay *overlay);
|
||||
int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
void intel_overlay_reset(struct drm_i915_private *dev_priv);
|
||||
void intel_overlay_reset(struct intel_display *display);
|
||||
#else
|
||||
static inline void intel_overlay_setup(struct drm_i915_private *dev_priv)
|
||||
static inline void intel_overlay_setup(struct intel_display *display)
|
||||
{
|
||||
}
|
||||
static inline void intel_overlay_cleanup(struct drm_i915_private *dev_priv)
|
||||
static inline bool intel_overlay_available(struct intel_display *display)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline void intel_overlay_cleanup(struct intel_display *display)
|
||||
{
|
||||
}
|
||||
static inline int intel_overlay_switch_off(struct intel_overlay *overlay)
|
||||
@ -37,7 +42,7 @@ static inline int intel_overlay_switch_off(struct intel_overlay *overlay)
|
||||
return 0;
|
||||
}
|
||||
static inline int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -46,7 +51,7 @@ static inline int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void intel_overlay_reset(struct drm_i915_private *dev_priv)
|
||||
static inline void intel_overlay_reset(struct intel_display *display)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
#include <drm/drm_edid.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_backlight.h"
|
||||
#include "intel_connector.h"
|
||||
#include "intel_display_core.h"
|
||||
@ -383,12 +382,12 @@ void intel_panel_add_encoder_fixed_mode(struct intel_connector *connector,
|
||||
enum drm_connector_status
|
||||
intel_panel_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(connector->dev);
|
||||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
|
||||
if (!intel_display_device_enabled(i915))
|
||||
if (!intel_display_device_enabled(display))
|
||||
return connector_status_disconnected;
|
||||
|
||||
if (!intel_display_driver_check_access(i915))
|
||||
if (!intel_display_driver_check_access(display))
|
||||
return connector->status;
|
||||
|
||||
return connector_status_connected;
|
||||
|
@ -4,8 +4,10 @@
|
||||
*/
|
||||
|
||||
#include "g4x_dp.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_crt.h"
|
||||
#include "intel_crt_regs.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dpll.h"
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Copyright © 2021 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
@ -108,13 +109,13 @@ void lpt_disable_iclkip(struct drm_i915_private *dev_priv)
|
||||
|
||||
intel_de_write(dev_priv, PIXCLK_GATE, PIXCLK_GATE_GATE);
|
||||
|
||||
mutex_lock(&dev_priv->sb_lock);
|
||||
intel_sbi_lock(dev_priv);
|
||||
|
||||
temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
|
||||
temp |= SBI_SSCCTL_DISABLE;
|
||||
intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK);
|
||||
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
intel_sbi_unlock(dev_priv);
|
||||
}
|
||||
|
||||
struct iclkip_params {
|
||||
@ -195,7 +196,7 @@ void lpt_program_iclkip(const struct intel_crtc_state *crtc_state)
|
||||
"iCLKIP clock: found settings for %dKHz refresh rate: auxdiv=%x, divsel=%x, phasedir=%x, phaseinc=%x\n",
|
||||
clock, p.auxdiv, p.divsel, p.phasedir, p.phaseinc);
|
||||
|
||||
mutex_lock(&dev_priv->sb_lock);
|
||||
intel_sbi_lock(dev_priv);
|
||||
|
||||
/* Program SSCDIVINTPHASE6 */
|
||||
temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK);
|
||||
@ -218,7 +219,7 @@ void lpt_program_iclkip(const struct intel_crtc_state *crtc_state)
|
||||
temp &= ~SBI_SSCCTL_DISABLE;
|
||||
intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK);
|
||||
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
intel_sbi_unlock(dev_priv);
|
||||
|
||||
/* Wait for initialization time */
|
||||
udelay(24);
|
||||
@ -236,11 +237,11 @@ int lpt_get_iclkip(struct drm_i915_private *dev_priv)
|
||||
|
||||
iclkip_params_init(&p);
|
||||
|
||||
mutex_lock(&dev_priv->sb_lock);
|
||||
intel_sbi_lock(dev_priv);
|
||||
|
||||
temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
|
||||
if (temp & SBI_SSCCTL_DISABLE) {
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
intel_sbi_unlock(dev_priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -254,7 +255,7 @@ int lpt_get_iclkip(struct drm_i915_private *dev_priv)
|
||||
p.auxdiv = (temp & SBI_SSCAUXDIV_FINALDIV2SEL_MASK) >>
|
||||
SBI_SSCAUXDIV_FINALDIV2SEL_SHIFT;
|
||||
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
intel_sbi_unlock(dev_priv);
|
||||
|
||||
p.desired_divisor = (p.divsel + 2) * p.iclk_pi_range + p.phaseinc;
|
||||
|
||||
@ -279,7 +280,7 @@ static void lpt_enable_clkout_dp(struct drm_i915_private *dev_priv,
|
||||
with_fdi, "LP PCH doesn't have FDI\n"))
|
||||
with_fdi = false;
|
||||
|
||||
mutex_lock(&dev_priv->sb_lock);
|
||||
intel_sbi_lock(dev_priv);
|
||||
|
||||
tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK);
|
||||
tmp &= ~SBI_SSCCTL_DISABLE;
|
||||
@ -302,7 +303,7 @@ static void lpt_enable_clkout_dp(struct drm_i915_private *dev_priv,
|
||||
tmp |= SBI_GEN0_CFG_BUFFENABLE_DISABLE;
|
||||
intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK);
|
||||
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
intel_sbi_unlock(dev_priv);
|
||||
}
|
||||
|
||||
/* Sequence to disable CLKOUT_DP */
|
||||
@ -310,7 +311,7 @@ void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u32 reg, tmp;
|
||||
|
||||
mutex_lock(&dev_priv->sb_lock);
|
||||
intel_sbi_lock(dev_priv);
|
||||
|
||||
reg = HAS_PCH_LPT_LP(dev_priv) ? SBI_GEN0 : SBI_DBUFF0;
|
||||
tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK);
|
||||
@ -328,7 +329,7 @@ void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv)
|
||||
intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK);
|
||||
}
|
||||
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
intel_sbi_unlock(dev_priv);
|
||||
}
|
||||
|
||||
#define BEND_IDX(steps) ((50 + (steps)) / 5)
|
||||
@ -374,7 +375,7 @@ static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps)
|
||||
if (drm_WARN_ON(&dev_priv->drm, idx >= ARRAY_SIZE(sscdivintphase)))
|
||||
return;
|
||||
|
||||
mutex_lock(&dev_priv->sb_lock);
|
||||
intel_sbi_lock(dev_priv);
|
||||
|
||||
if (steps % 10 != 0)
|
||||
tmp = 0xAAAAAAAB;
|
||||
@ -387,7 +388,7 @@ static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps)
|
||||
tmp |= sscdivintphase[idx];
|
||||
intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE, tmp, SBI_ICLK);
|
||||
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
intel_sbi_unlock(dev_priv);
|
||||
}
|
||||
|
||||
#undef BEND_IDX
|
||||
|
@ -3,8 +3,8 @@
|
||||
* Copyright © 2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_types.h"
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_irq.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_atomic.h"
|
||||
|
@ -20,10 +20,10 @@ intel_reuse_initial_plane_obj(struct intel_crtc *this,
|
||||
struct drm_framebuffer **fb,
|
||||
struct i915_vma **vma)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(this->base.dev);
|
||||
struct intel_display *display = to_intel_display(this);
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
for_each_intel_crtc(&i915->drm, crtc) {
|
||||
for_each_intel_crtc(display->drm, crtc) {
|
||||
struct intel_plane *plane =
|
||||
to_intel_plane(crtc->base.primary);
|
||||
const struct intel_plane_state *plane_state =
|
||||
@ -48,9 +48,10 @@ intel_reuse_initial_plane_obj(struct intel_crtc *this,
|
||||
}
|
||||
|
||||
static bool
|
||||
initial_plane_phys_lmem(struct drm_i915_private *i915,
|
||||
initial_plane_phys_lmem(struct intel_display *display,
|
||||
struct intel_initial_plane_config *plane_config)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
gen8_pte_t __iomem *gte = to_gt(i915)->ggtt->gsm;
|
||||
struct intel_memory_region *mem;
|
||||
dma_addr_t dma_addr;
|
||||
@ -63,7 +64,7 @@ initial_plane_phys_lmem(struct drm_i915_private *i915,
|
||||
|
||||
pte = ioread64(gte);
|
||||
if (!(pte & GEN12_GGTT_PTE_LM)) {
|
||||
drm_err(&i915->drm,
|
||||
drm_err(display->drm,
|
||||
"Initial plane programming missing PTE_LM bit\n");
|
||||
return false;
|
||||
}
|
||||
@ -75,7 +76,7 @@ initial_plane_phys_lmem(struct drm_i915_private *i915,
|
||||
else
|
||||
mem = i915->mm.stolen_region;
|
||||
if (!mem) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"Initial plane memory region not initialized\n");
|
||||
return false;
|
||||
}
|
||||
@ -85,13 +86,13 @@ initial_plane_phys_lmem(struct drm_i915_private *i915,
|
||||
* ever be placed in the stolen portion.
|
||||
*/
|
||||
if (dma_addr < mem->region.start || dma_addr > mem->region.end) {
|
||||
drm_err(&i915->drm,
|
||||
drm_err(display->drm,
|
||||
"Initial plane programming using invalid range, dma_addr=%pa (%s [%pa-%pa])\n",
|
||||
&dma_addr, mem->region.name, &mem->region.start, &mem->region.end);
|
||||
return false;
|
||||
}
|
||||
|
||||
drm_dbg(&i915->drm,
|
||||
drm_dbg(display->drm,
|
||||
"Using dma_addr=%pa, based on initial plane programming\n",
|
||||
&dma_addr);
|
||||
|
||||
@ -102,9 +103,10 @@ initial_plane_phys_lmem(struct drm_i915_private *i915,
|
||||
}
|
||||
|
||||
static bool
|
||||
initial_plane_phys_smem(struct drm_i915_private *i915,
|
||||
initial_plane_phys_smem(struct intel_display *display,
|
||||
struct intel_initial_plane_config *plane_config)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct intel_memory_region *mem;
|
||||
u32 base;
|
||||
|
||||
@ -112,7 +114,7 @@ initial_plane_phys_smem(struct drm_i915_private *i915,
|
||||
|
||||
mem = i915->mm.stolen_region;
|
||||
if (!mem) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"Initial plane memory region not initialized\n");
|
||||
return false;
|
||||
}
|
||||
@ -125,19 +127,22 @@ initial_plane_phys_smem(struct drm_i915_private *i915,
|
||||
}
|
||||
|
||||
static bool
|
||||
initial_plane_phys(struct drm_i915_private *i915,
|
||||
initial_plane_phys(struct intel_display *display,
|
||||
struct intel_initial_plane_config *plane_config)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
if (IS_DGFX(i915) || HAS_LMEMBAR_SMEM_STOLEN(i915))
|
||||
return initial_plane_phys_lmem(i915, plane_config);
|
||||
return initial_plane_phys_lmem(display, plane_config);
|
||||
else
|
||||
return initial_plane_phys_smem(i915, plane_config);
|
||||
return initial_plane_phys_smem(display, plane_config);
|
||||
}
|
||||
|
||||
static struct i915_vma *
|
||||
initial_plane_vma(struct drm_i915_private *i915,
|
||||
initial_plane_vma(struct intel_display *display,
|
||||
struct intel_initial_plane_config *plane_config)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct intel_memory_region *mem;
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct drm_mm_node orig_mm = {};
|
||||
@ -149,7 +154,7 @@ initial_plane_vma(struct drm_i915_private *i915,
|
||||
if (plane_config->size == 0)
|
||||
return NULL;
|
||||
|
||||
if (!initial_plane_phys(i915, plane_config))
|
||||
if (!initial_plane_phys(display, plane_config))
|
||||
return NULL;
|
||||
|
||||
phys_base = plane_config->phys_base;
|
||||
@ -168,7 +173,7 @@ initial_plane_vma(struct drm_i915_private *i915,
|
||||
if (IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) &&
|
||||
mem == i915->mm.stolen_region &&
|
||||
size * 2 > i915->dsm.usable_size) {
|
||||
drm_dbg_kms(&i915->drm, "Initial FB size exceeds half of stolen, discarding\n");
|
||||
drm_dbg_kms(display->drm, "Initial FB size exceeds half of stolen, discarding\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -176,7 +181,7 @@ initial_plane_vma(struct drm_i915_private *i915,
|
||||
I915_BO_ALLOC_USER |
|
||||
I915_BO_PREALLOC);
|
||||
if (IS_ERR(obj)) {
|
||||
drm_dbg_kms(&i915->drm, "Failed to preallocate initial FB in %s\n",
|
||||
drm_dbg_kms(display->drm, "Failed to preallocate initial FB in %s\n",
|
||||
mem->region.name);
|
||||
return NULL;
|
||||
}
|
||||
@ -254,7 +259,7 @@ initial_plane_vma(struct drm_i915_private *i915,
|
||||
if (drm_mm_node_allocated(&orig_mm))
|
||||
drm_mm_remove_node(&orig_mm);
|
||||
|
||||
drm_dbg_kms(&i915->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"Initial plane fb bound to 0x%x in the ggtt (original 0x%x)\n",
|
||||
i915_ggtt_offset(vma), plane_config->base);
|
||||
|
||||
@ -271,8 +276,7 @@ static bool
|
||||
intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
|
||||
struct intel_initial_plane_config *plane_config)
|
||||
{
|
||||
struct drm_device *dev = crtc->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_display *display = to_intel_display(crtc);
|
||||
struct drm_mode_fb_cmd2 mode_cmd = {};
|
||||
struct drm_framebuffer *fb = &plane_config->fb->base;
|
||||
struct i915_vma *vma;
|
||||
@ -284,13 +288,13 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
|
||||
case I915_FORMAT_MOD_4_TILED:
|
||||
break;
|
||||
default:
|
||||
drm_dbg(&dev_priv->drm,
|
||||
drm_dbg(display->drm,
|
||||
"Unsupported modifier for initial FB: 0x%llx\n",
|
||||
fb->modifier);
|
||||
return false;
|
||||
}
|
||||
|
||||
vma = initial_plane_vma(dev_priv, plane_config);
|
||||
vma = initial_plane_vma(display, plane_config);
|
||||
if (!vma)
|
||||
return false;
|
||||
|
||||
@ -303,7 +307,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
|
||||
|
||||
if (intel_framebuffer_init(to_intel_framebuffer(fb),
|
||||
intel_bo_to_drm_bo(vma->obj), &mode_cmd)) {
|
||||
drm_dbg_kms(&dev_priv->drm, "intel fb init failed\n");
|
||||
drm_dbg_kms(display->drm, "intel fb init failed\n");
|
||||
goto err_vma;
|
||||
}
|
||||
|
||||
@ -410,12 +414,12 @@ static void plane_config_fini(struct intel_initial_plane_config *plane_config)
|
||||
i915_vma_put(plane_config->vma);
|
||||
}
|
||||
|
||||
void intel_initial_plane_config(struct drm_i915_private *i915)
|
||||
void intel_initial_plane_config(struct intel_display *display)
|
||||
{
|
||||
struct intel_initial_plane_config plane_configs[I915_MAX_PIPES] = {};
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
for_each_intel_crtc(&i915->drm, crtc) {
|
||||
for_each_intel_crtc(display->drm, crtc) {
|
||||
struct intel_initial_plane_config *plane_config =
|
||||
&plane_configs[crtc->pipe];
|
||||
|
||||
@ -429,7 +433,7 @@ void intel_initial_plane_config(struct drm_i915_private *i915)
|
||||
* can even allow for smooth boot transitions if the BIOS
|
||||
* fb is large enough for the active pipe configuration.
|
||||
*/
|
||||
i915->display.funcs.display->get_initial_plane_config(crtc, plane_config);
|
||||
display->funcs.display->get_initial_plane_config(crtc, plane_config);
|
||||
|
||||
/*
|
||||
* If the fb is shared between multiple heads, we'll
|
||||
@ -437,7 +441,7 @@ void intel_initial_plane_config(struct drm_i915_private *i915)
|
||||
*/
|
||||
intel_find_initial_plane_obj(crtc, plane_configs);
|
||||
|
||||
if (i915->display.funcs.display->fixup_initial_plane_config(crtc, plane_config))
|
||||
if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config))
|
||||
intel_crtc_wait_for_next_vblank(crtc);
|
||||
|
||||
plane_config_fini(plane_config);
|
||||
|
@ -6,8 +6,8 @@
|
||||
#ifndef __INTEL_PLANE_INITIAL_H__
|
||||
#define __INTEL_PLANE_INITIAL_H__
|
||||
|
||||
struct drm_i915_private;
|
||||
struct intel_display;
|
||||
|
||||
void intel_initial_plane_config(struct drm_i915_private *i915);
|
||||
void intel_initial_plane_config(struct intel_display *display);
|
||||
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user