Commit ca765c73 authored by Daniel Vetter's avatar Daniel Vetter

Merge tag 'drm-intel-next-2021-01-04' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

- Display hotplug fix for gen2/gen3 (Chris)
- Remove trailing semicolon (Tom)
- Suppress display warnings for old ifwi presend on our CI (Chris)
- OA/Perf related workaround (Lionel)
- Replace I915_READ/WRITE per new uncore and display read/write functions (Jani)
- PSR improvements (Jose)
- HDR and other color changes on LSPCON (Uma, Ville)
- FBC fixes for TGL (Uma)
- Record plane update times for debugging (Chris)
- Refactor panel backlight control functions (Dave)
- Display power improvements (Imre)
- Add VRR register definition (Manasi)
- Atomic modeset improvements for bigjoiner pipes (Ville)
- Switch off the scanout during driver unregister (Chris)
- Clean-up DP's FEW enable (Manasi)
- Fix VDSCP slice count (Manasi)
- Fix and clean up around rc_model_size for DSC (Jani)
- Remove Type-C noisy debug warn message (Sean)
- Display HPD code clean-up (Ville)
- Refactor Intel Display (Dave)
- Start adding support for Intel's eDP backlight controls (Lyude)
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210104211018.GA1094707@intel.com
parents e240cc76 b3304591
......@@ -49,6 +49,33 @@ void drm_dsc_dp_pps_header_init(struct dp_sdp_header *pps_header)
}
EXPORT_SYMBOL(drm_dsc_dp_pps_header_init);
/**
* drm_dsc_dp_rc_buffer_size - get rc buffer size in bytes
* @rc_buffer_block_size: block size code, according to DPCD offset 62h
* @rc_buffer_size: number of blocks - 1, according to DPCD offset 63h
*
* return:
* buffer size in bytes, or 0 on invalid input
*/
int drm_dsc_dp_rc_buffer_size(u8 rc_buffer_block_size, u8 rc_buffer_size)
{
int size = 1024 * (rc_buffer_size + 1);
switch (rc_buffer_block_size) {
case DP_DSC_RC_BUF_BLK_SIZE_1:
return 1 * size;
case DP_DSC_RC_BUF_BLK_SIZE_4:
return 4 * size;
case DP_DSC_RC_BUF_BLK_SIZE_16:
return 16 * size;
case DP_DSC_RC_BUF_BLK_SIZE_64:
return 64 * size;
default:
return 0;
}
}
EXPORT_SYMBOL(drm_dsc_dp_rc_buffer_size);
/**
* drm_dsc_pps_payload_pack() - Populates the DSC PPS
*
......@@ -186,8 +213,7 @@ void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_payload,
pps_payload->flatness_max_qp = dsc_cfg->flatness_max_qp;
/* PPS 38, 39 */
pps_payload->rc_model_size =
cpu_to_be16(DSC_RC_MODEL_SIZE_CONST);
pps_payload->rc_model_size = cpu_to_be16(dsc_cfg->rc_model_size);
/* PPS 40 */
pps_payload->rc_edge_factor = DSC_RC_EDGE_FACTOR_CONST;
......
......@@ -197,6 +197,7 @@ i915-y += \
display/intel_combo_phy.o \
display/intel_connector.o \
display/intel_csr.o \
display/intel_cursor.o \
display/intel_display.o \
display/intel_display_power.o \
display/intel_dpio_phy.o \
......@@ -214,7 +215,8 @@ i915-y += \
display/intel_quirks.o \
display/intel_sprite.o \
display/intel_tc.o \
display/intel_vga.o
display/intel_vga.o \
display/i9xx_plane.o
i915-$(CONFIG_ACPI) += \
display/intel_acpi.o \
display/intel_opregion.o
......
This diff is collapsed.
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2020 Intel Corporation
*/
#ifndef _I9XX_PLANE_H_
#define _I9XX_PLANE_H_
#include <linux/types.h>
enum pipe;
struct drm_i915_private;
struct intel_plane;
struct intel_plane_state;
unsigned int i9xx_plane_max_stride(struct intel_plane *plane,
u32 pixel_format, u64 modifier,
unsigned int rotation);
int i9xx_check_plane_surface(struct intel_plane_state *plane_state);
struct intel_plane *
intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe);
#endif
......@@ -1535,6 +1535,9 @@ static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
vdsc_cfg->convert_rgb = true;
/* FIXME: initialize from VBT */
vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST;
ret = intel_dsc_compute_params(encoder, crtc_state);
if (ret)
return ret;
......@@ -1616,10 +1619,6 @@ static void gen11_dsi_get_power_domains(struct intel_encoder *encoder,
get_dsi_io_power_domains(i915,
enc_to_intel_dsi(encoder));
if (crtc_state->dsc.compression_enable)
intel_display_power_get(i915,
intel_dsc_power_domain(crtc_state));
}
static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
......
......@@ -312,10 +312,13 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
int ret;
intel_plane_set_invisible(new_crtc_state, new_plane_state);
new_crtc_state->enabled_planes &= ~BIT(plane->id);
if (!new_plane_state->hw.crtc && !old_plane_state->hw.crtc)
return 0;
new_crtc_state->enabled_planes |= BIT(plane->id);
ret = plane->check_plane(new_crtc_state, new_plane_state);
if (ret)
return ret;
......
......@@ -2555,16 +2555,11 @@ static void fill_dsc(struct intel_crtc_state *crtc_state,
crtc_state->dsc.slice_count);
/*
* FIXME: Use VBT rc_buffer_block_size and rc_buffer_size for the
* implementation specific physical rate buffer size. Currently we use
* the required rate buffer model size calculated in
* drm_dsc_compute_rc_parameters() according to VESA DSC Annex E.
*
* The VBT rc_buffer_block_size and rc_buffer_size definitions
* correspond to DP 1.4 DPCD offsets 0x62 and 0x63. The DP DSC
* implementation should also use the DPCD (or perhaps VBT for eDP)
* provided value for the buffer size.
* correspond to DP 1.4 DPCD offsets 0x62 and 0x63.
*/
vdsc_cfg->rc_model_size = drm_dsc_dp_rc_buffer_size(dsc->rc_buffer_block_size,
dsc->rc_buffer_size);
/* FIXME: DSI spec says bpc + 1 for this one */
vdsc_cfg->line_buf_depth = VBT_DSC_LINE_BUFFER_DEPTH(dsc->line_buffer_depth);
......
......@@ -2415,8 +2415,7 @@ static int intel_modeset_all_pipes(struct intel_atomic_state *state)
if (ret)
return ret;
ret = drm_atomic_add_affected_planes(&state->base,
&crtc->base);
ret = intel_atomic_add_affected_planes(state, crtc);
if (ret)
return ret;
......@@ -2710,8 +2709,8 @@ static int dg1_rawclk(struct drm_i915_private *dev_priv)
* DG1 always uses a 38.4 MHz rawclk. The bspec tells us
* "Program Numerator=2, Denominator=4, Divider=37 decimal."
*/
I915_WRITE(PCH_RAWCLK_FREQ,
CNP_RAWCLK_DEN(4) | CNP_RAWCLK_DIV(37) | ICP_RAWCLK_NUM(2));
intel_de_write(dev_priv, PCH_RAWCLK_FREQ,
CNP_RAWCLK_DEN(4) | CNP_RAWCLK_DIV(37) | ICP_RAWCLK_NUM(2));
return 38400;
}
......
......@@ -427,10 +427,22 @@ static void icl_combo_phys_uninit(struct drm_i915_private *dev_priv)
u32 val;
if (phy == PHY_A &&
!icl_combo_phy_verify_state(dev_priv, phy))
drm_warn(&dev_priv->drm,
"Combo PHY %c HW state changed unexpectedly\n",
phy_name(phy));
!icl_combo_phy_verify_state(dev_priv, phy)) {
if (IS_TIGERLAKE(dev_priv) || IS_DG1(dev_priv)) {
/*
* A known problem with old ifwi:
* https://gitlab.freedesktop.org/drm/intel/-/issues/2411
* Suppress the warning for CI. Remove ASAP!
*/
drm_dbg_kms(&dev_priv->drm,
"Combo PHY %c HW state changed unexpectedly\n",
phy_name(phy));
} else {
drm_warn(&dev_priv->drm,
"Combo PHY %c HW state changed unexpectedly\n",
phy_name(phy));
}
}
if (!has_phy_misc(dev_priv, phy))
goto skip_phy_misc;
......
......@@ -279,24 +279,17 @@ intel_attach_aspect_ratio_property(struct drm_connector *connector)
}
void
intel_attach_colorspace_property(struct drm_connector *connector)
intel_attach_hdmi_colorspace_property(struct drm_connector *connector)
{
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_HDMIA:
case DRM_MODE_CONNECTOR_HDMIB:
if (drm_mode_create_hdmi_colorspace_property(connector))
return;
break;
case DRM_MODE_CONNECTOR_DisplayPort:
case DRM_MODE_CONNECTOR_eDP:
if (drm_mode_create_dp_colorspace_property(connector))
return;
break;
default:
MISSING_CASE(connector->connector_type);
return;
}
if (!drm_mode_create_hdmi_colorspace_property(connector))
drm_object_attach_property(&connector->base,
connector->colorspace_property, 0);
}
drm_object_attach_property(&connector->base,
connector->colorspace_property, 0);
void
intel_attach_dp_colorspace_property(struct drm_connector *connector)
{
if (!drm_mode_create_dp_colorspace_property(connector))
drm_object_attach_property(&connector->base,
connector->colorspace_property, 0);
}
......@@ -30,6 +30,7 @@ int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter);
void intel_attach_force_audio_property(struct drm_connector *connector);
void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
void intel_attach_aspect_ratio_property(struct drm_connector *connector);
void intel_attach_colorspace_property(struct drm_connector *connector);
void intel_attach_hdmi_colorspace_property(struct drm_connector *connector);
void intel_attach_dp_colorspace_property(struct drm_connector *connector);
#endif /* __INTEL_CONNECTOR_H__ */
This diff is collapsed.
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2020 Intel Corporation
*/
#ifndef _INTEL_CURSOR_H_
#define _INTEL_CURSOR_H_
enum pipe;
struct drm_i915_private;
struct intel_plane;
struct intel_plane *
intel_cursor_plane_create(struct drm_i915_private *dev_priv,
enum pipe pipe);
#endif
......@@ -2285,18 +2285,23 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
dig_port = enc_to_dig_port(encoder);
if (!intel_phy_is_tc(dev_priv, phy) ||
dig_port->tc_mode != TC_PORT_TBT_ALT)
intel_display_power_get(dev_priv,
dig_port->ddi_io_power_domain);
dig_port->tc_mode != TC_PORT_TBT_ALT) {
drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref);
dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,
dig_port->ddi_io_power_domain);
}
/*
* AUX power is only needed for (e)DP mode, and for HDMI mode on TC
* ports.
*/
if (intel_crtc_has_dp_encoder(crtc_state) ||
intel_phy_is_tc(dev_priv, phy))
intel_display_power_get(dev_priv,
intel_ddi_main_link_aux_domain(dig_port));
intel_phy_is_tc(dev_priv, phy)) {
drm_WARN_ON(&dev_priv->drm, dig_port->aux_wakeref);
dig_port->aux_wakeref =
intel_display_power_get(dev_priv,
intel_ddi_main_link_aux_domain(dig_port));
}
}
void intel_ddi_enable_pipe_clock(struct intel_encoder *encoder,
......@@ -3507,12 +3512,6 @@ static void intel_ddi_enable_fec(struct intel_encoder *encoder,
val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
val |= DP_TP_CTL_FEC_ENABLE;
intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
if (intel_de_wait_for_set(dev_priv,
dp_tp_status_reg(encoder, crtc_state),
DP_TP_STATUS_FEC_ENABLE_LIVE, 1))
drm_err(&dev_priv->drm,
"Timed out waiting for FEC Enable Status\n");
}
static void intel_ddi_disable_fec_state(struct intel_encoder *encoder,
......@@ -3577,9 +3576,11 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
/* 5. If IO power is controlled through PWR_WELL_CTL, Enable IO Power */
if (!intel_phy_is_tc(dev_priv, phy) ||
dig_port->tc_mode != TC_PORT_TBT_ALT)
intel_display_power_get(dev_priv,
dig_port->ddi_io_power_domain);
dig_port->tc_mode != TC_PORT_TBT_ALT) {
drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref);
dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,
dig_port->ddi_io_power_domain);
}
/* 6. Program DP_MODE */
icl_program_mg_dp_mode(dig_port, crtc_state);
......@@ -3702,9 +3703,11 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
intel_ddi_clk_select(encoder, crtc_state);
if (!intel_phy_is_tc(dev_priv, phy) ||
dig_port->tc_mode != TC_PORT_TBT_ALT)
intel_display_power_get(dev_priv,
dig_port->ddi_io_power_domain);
dig_port->tc_mode != TC_PORT_TBT_ALT) {
drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref);
dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,
dig_port->ddi_io_power_domain);
}
icl_program_mg_dp_mode(dig_port, crtc_state);
......@@ -3782,7 +3785,9 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
intel_ddi_clk_select(encoder, crtc_state);
intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref);
dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,
dig_port->ddi_io_power_domain);
icl_program_mg_dp_mode(dig_port, crtc_state);
......@@ -3940,8 +3945,9 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
if (!intel_phy_is_tc(dev_priv, phy) ||
dig_port->tc_mode != TC_PORT_TBT_ALT)
intel_display_power_put_unchecked(dev_priv,
dig_port->ddi_io_power_domain);
intel_display_power_put(dev_priv,
dig_port->ddi_io_power_domain,
fetch_and_zero(&dig_port->ddi_io_wakeref));
intel_ddi_clk_disable(encoder);
}
......@@ -3962,8 +3968,9 @@ static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state,
intel_disable_ddi_buf(encoder, old_crtc_state);
intel_display_power_put_unchecked(dev_priv,
dig_port->ddi_io_power_domain);
intel_display_power_put(dev_priv,
dig_port->ddi_io_power_domain,
fetch_and_zero(&dig_port->ddi_io_wakeref));
intel_ddi_clk_disable(encoder);
......@@ -4036,8 +4043,9 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
icl_unmap_plls_to_ports(encoder);
if (intel_crtc_has_dp_encoder(old_crtc_state) || is_tc_port)
intel_display_power_put_unchecked(dev_priv,
intel_ddi_main_link_aux_domain(dig_port));
intel_display_power_put(dev_priv,
intel_ddi_main_link_aux_domain(dig_port),
fetch_and_zero(&dig_port->aux_wakeref));
if (is_tc_port)
intel_tc_port_put_link(dig_port);
......@@ -4122,6 +4130,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
enum port port = encoder->port;
if (port == PORT_A && INTEL_GEN(dev_priv) < 9)
......@@ -4129,7 +4138,10 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
intel_edp_backlight_on(crtc_state, conn_state);
intel_psr_enable(intel_dp, crtc_state, conn_state);
intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink)
intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
intel_edp_drrs_enable(intel_dp, crtc_state);
if (crtc_state->has_audio)
......@@ -4372,9 +4384,12 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
if (is_tc_port)
intel_tc_port_get_link(dig_port, crtc_state->lane_count);
if (intel_crtc_has_dp_encoder(crtc_state) || is_tc_port)
intel_display_power_get(dev_priv,
intel_ddi_main_link_aux_domain(dig_port));
if (intel_crtc_has_dp_encoder(crtc_state) || is_tc_port) {
drm_WARN_ON(&dev_priv->drm, dig_port->aux_wakeref);
dig_port->aux_wakeref =
intel_display_power_get(dev_priv,
intel_ddi_main_link_aux_domain(dig_port));
}
if (is_tc_port && dig_port->tc_mode != TC_PORT_TBT_ALT)
/*
......@@ -4587,6 +4602,7 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crtc *intel_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;
temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
......@@ -4661,9 +4677,12 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
pipe_config->fec_enable);
}
pipe_config->infoframes.enable |=
intel_hdmi_infoframes_enabled(encoder, pipe_config);
if (dig_port->lspcon.active && dig_port->dp.has_hdmi_sink)
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_DP_MST:
pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
......
......@@ -499,6 +499,8 @@ enum phy_fia {
((connector) = to_intel_connector((__state)->base.connectors[__i].ptr), \
(new_connector_state) = to_intel_digital_connector_state((__state)->base.connectors[__i].new_state), 1))
int intel_atomic_add_affected_planes(struct intel_atomic_state *state,
struct intel_crtc *crtc);
u8 intel_calc_active_pipes(struct intel_atomic_state *state,
u8 active_pipes);
void intel_link_compute_m_n(u16 bpp, int nlanes,
......@@ -628,11 +630,7 @@ u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state);
u32 skl_plane_stride(const struct intel_plane_state *plane_state,
int plane);
int skl_check_plane_surface(struct intel_plane_state *plane_state);
int i9xx_check_plane_surface(struct intel_plane_state *plane_state);
int skl_format_to_fourcc(int format, bool rgb_order, bool alpha);
unsigned int i9xx_plane_max_stride(struct intel_plane *plane,
u32 pixel_format, u64 modifier,
unsigned int rotation);
int bdw_get_pipemisc_bpp(struct intel_crtc *crtc);
unsigned int intel_plane_fence_y_offset(const struct intel_plane_state *plane_state);
......@@ -645,6 +643,13 @@ bool
intel_format_info_is_yuv_semiplanar(const struct drm_format_info *info,
uint64_t modifier);
int intel_plane_compute_gtt(struct intel_plane_state *plane_state);
u32 intel_plane_compute_aligned_offset(int *x, int *y,
const struct intel_plane_state *state,
int color_plane);
int intel_plane_pin_fb(struct intel_plane_state *plane_state);
void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state);
/* modesetting */
void intel_modeset_init_hw(struct drm_i915_private *i915);
int intel_modeset_init_noirq(struct drm_i915_private *i915);
......
......@@ -18,6 +18,7 @@
#include "intel_pm.h"
#include "intel_psr.h"
#include "intel_sideband.h"
#include "intel_sprite.h"
static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node)
{
......@@ -865,6 +866,110 @@ static void intel_scaler_info(struct seq_file *m, struct intel_crtc *crtc)
}
}
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_VBLANK_EVADE)
static void crtc_updates_info(struct seq_file *m,
struct intel_crtc *crtc,
const char *hdr)
{
u64 count;
int row;
count = 0;
for (row = 0; row < ARRAY_SIZE(crtc->debug.vbl.times); row++)
count += crtc->debug.vbl.times[row];
seq_printf(m, "%sUpdates: %llu\n", hdr, count);
if (!count)
return;
for (row = 0; row < ARRAY_SIZE(crtc->debug.vbl.times); row++) {
char columns[80] = " |";
unsigned int x;
if (row & 1) {
const char *units;
if (row > 10) {
x = 1000000;
units = "ms";
} else {
x = 1000;
units = "us";
}
snprintf(columns, sizeof(columns), "%4ld%s |",
DIV_ROUND_CLOSEST(BIT(row + 9), x), units);
}
if (crtc->debug.vbl.times[row]) {
x = ilog2(crtc->debug.vbl.times[row]);
memset(columns + 8, '*', x);
columns[8 + x] = '\0';
}
seq_printf(m, "%s%s\n", hdr, columns);
}
seq_printf(m, "%sMin update: %lluns\n",
hdr, crtc->debug.vbl.min);
seq_printf(m, "%sMax update: %lluns\n",
hdr, crtc->debug.vbl.max);
seq_printf(m, "%sAverage update: %lluns\n",
hdr, div64_u64(crtc->debug.vbl.sum, count));
seq_printf(m, "%sOverruns > %uus: %u\n",
hdr, VBLANK_EVASION_TIME_US, crtc->debug.vbl.over);
}
static int crtc_updates_show(struct seq_file *m, void *data)
{
crtc_updates_info(m, m->private, "");
return 0;
}
static int crtc_updates_open(struct inode *inode, struct file *file)
{
return single_open(file, crtc_updates_show, inode->i_private);
}
static ssize_t crtc_updates_write(struct file *file,
const char __user *ubuf,
size_t len, loff_t *offp)
{
struct seq_file *m = file->private_data;
struct intel_crtc *crtc = m->private;
/* May race with an update. Meh. */
memset(&crtc->debug.vbl, 0, sizeof(crtc->debug.vbl));
return len;
}
static const struct file_operations crtc_updates_fops = {
.owner = THIS_MODULE,
.open = crtc_updates_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.write = crtc_updates_write
};
static void crtc_updates_add(struct drm_crtc *crtc)
{
debugfs_create_file("i915_update_info", 0644, crtc->debugfs_entry,
to_intel_crtc(crtc), &crtc_updates_fops);
}
#else
static void crtc_updates_info(struct seq_file *m,
struct intel_crtc *crtc,
const char *hdr)
{
}
static void crtc_updates_add(struct drm_crtc *crtc)
{
}
#endif
static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
......@@ -907,6 +1012,8 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
seq_printf(m, "\tunderrun reporting: cpu=%s pch=%s\n",
yesno(!crtc->cpu_fifo_underrun_disabled),
yesno(!crtc->pch_fifo_underrun_disabled));
crtc_updates_info(m, crtc, "\t");
}
static int i915_display_info(struct seq_file *m, void *unused)
......@@ -2278,3 +2385,20 @@ int intel_connector_debugfs_add(struct drm_connector *connector)
return 0;
}
/**
* intel_crtc_debugfs_add - add i915 specific crtc debugfs files
* @crtc: pointer to a drm_crtc
*
* Returns 0 on success, negative error codes on error.
*
* Failure to add debugfs entries should generally be ignored.
*/
int intel_crtc_debugfs_add(struct drm_crtc *crtc)
{
if (!crtc->debugfs_entry)
return -ENODEV;
crtc_updates_add(crtc);
return 0;
}
......@@ -7,14 +7,17 @@
#define __INTEL_DISPLAY_DEBUGFS_H__
struct drm_connector;
struct drm_crtc;
struct drm_i915_private;
#ifdef CONFIG_DEBUG_FS
void intel_display_debugfs_register(struct drm_i915_private *i915);
int intel_connector_debugfs_add(struct drm_connector *connector);
int intel_crtc_debugfs_add(struct drm_crtc *crtc);
#else
static inline void intel_display_debugfs_register(struct drm_i915_private *i915) {}
static inline int intel_connector_debugfs_add(struct drm_connector *connector) { return 0; }
static inline int intel_crtc_debugfs_add(struct drm_crtc *crtc) { return 0; }
#endif
#endif /* __INTEL_DISPLAY_DEBUGFS_H__ */
......@@ -2184,26 +2184,6 @@ static void __intel_display_power_put(struct drm_i915_private *dev_priv,
mutex_unlock(&power_domains->lock);
}
/**
* intel_display_power_put_unchecked - release an unchecked power domain reference
* @dev_priv: i915 device instance
* @domain: power domain to reference
*
* This function drops the power domain reference obtained by
* intel_display_power_get() and might power down the corresponding hardware
* block right away if this is the last reference.
*
* This function exists only for historical reasons and should be avoided in
* new code, as the correctness of its use cannot be checked. Always use
* intel_display_power_put() instead.
*/
void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain)
{
__intel_display_power_put(dev_priv, domain);
intel_runtime_pm_put_unchecked(&dev_priv->runtime_pm);
}
static void
queue_async_put_domains_work(struct i915_power_domains *power_domains,
intel_wakeref_t wakeref)
......@@ -2410,8 +2390,85 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
__intel_display_power_put(dev_priv, domain);
intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
}
#else
/**
* intel_display_power_put_unchecked - release an unchecked power domain reference
* @dev_priv: i915 device instance
* @domain: power domain to reference
*
* This function drops the power domain reference obtained by
* intel_display_power_get() and might power down the corresponding hardware
* block right away if this is the last reference.
*
* This function is only for the power domain code's internal use to suppress wakeref
* tracking when the correspondig debug kconfig option is disabled, should not
* be used otherwise.
*/
void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain)
{
__intel_display_power_put(dev_priv, domain);
intel_runtime_pm_put_unchecked(&dev_priv->runtime_pm);
}
#endif
void
intel_display_power_get_in_set(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set,
enum intel_display_power_domain domain)
{
intel_wakeref_t __maybe_unused wf;
drm_WARN_ON(&i915->drm, power_domain_set->mask & BIT_ULL(domain));
wf = intel_display_power_get(i915, domain);
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
power_domain_set->wakerefs[domain] = wf;
#endif
power_domain_set->mask |= BIT_ULL(domain);
}
bool
intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set,
enum intel_display_power_domain domain)
{
intel_wakeref_t wf;
drm_WARN_ON(&i915->drm, power_domain_set->mask & BIT_ULL(domain));
wf = intel_display_power_get_if_enabled(i915, domain);
if (!wf)
return false;
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
power_domain_set->wakerefs[domain] = wf;
#endif
power_domain_set->mask |= BIT_ULL(domain);
return true;
}
void
intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set,
u64 mask)
{
enum intel_display_power_domain domain;
drm_WARN_ON(&i915->drm, mask & ~power_domain_set->mask);
for_each_power_domain(domain, mask) {
intel_wakeref_t __maybe_unused wf = -1;
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
wf = fetch_and_zero(&power_domain_set->wakerefs[domain]);
#endif
intel_display_power_put(i915, domain, wf);
power_domain_set->mask &= ~BIT_ULL(domain);
}
}
#define I830_PIPES_POWER_DOMAINS ( \
BIT_ULL(POWER_DOMAIN_PIPE_A) | \
BIT_ULL(POWER_DOMAIN_PIPE_B) | \
......@@ -5601,12 +5658,16 @@ void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume)
* resources powered until display HW readout is complete. We drop
* this reference in intel_power_domains_enable().
*/
power_domains->wakeref =
drm_WARN_ON(&i915->drm, power_domains->init_wakeref);
power_domains->init_wakeref =
intel_display_power_get(i915, POWER_DOMAIN_INIT);
/* Disable power support if the user asked so. */
if (!i915->params.disable_power_well)
intel_display_power_get(i915, POWER_DOMAIN_INIT);
if (!i915->params.disable_power_well) {
drm_WARN_ON(&i915->drm, power_domains->disable_wakeref);
i915->power_domains.disable_wakeref = intel_display_power_get(i915,
POWER_DOMAIN_INIT);
}
intel_power_domains_sync_hw(i915);
power_domains->initializing = false;
......@@ -5626,11 +5687,12 @@ void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume)
void intel_power_domains_driver_remove(struct drm_i915_private *i915)
{
intel_wakeref_t wakeref __maybe_unused =
fetch_and_zero(&i915->power_domains.wakeref);
fetch_and_zero(&i915->power_domains.init_wakeref);
/* Remove the refcount we took to keep power well support disabled. */
if (!i915->params.disable_power_well)
intel_display_power_put_unchecked(i915, POWER_DOMAIN_INIT);
intel_display_power_put(i915, POWER_DOMAIN_INIT,
fetch_and_zero(&i915->power_domains.disable_wakeref));
intel_display_power_flush_work_sync(i915);
......@@ -5655,7 +5717,7 @@ void intel_power_domains_driver_remove(struct drm_i915_private *i915)
void intel_power_domains_enable(struct drm_i915_private *i915)
{
intel_wakeref_t wakeref __maybe_unused =
fetch_and_zero(&i915->power_domains.wakeref);
fetch_and_zero(&i915->power_domains.init_wakeref);
intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref);
intel_power_domains_verify_state(i915);
......@@ -5672,8 +5734,8 @@ void intel_power_domains_disable(struct drm_i915_private *i915)
{
struct i915_power_domains *power_domains = &i915->power_domains;
drm_WARN_ON(&i915->drm, power_domains->wakeref);
power_domains->wakeref =
drm_WARN_ON(&i915->drm, power_domains->init_wakeref);
power_domains->init_wakeref =
intel_display_power_get(i915, POWER_DOMAIN_INIT);
intel_power_domains_verify_state(i915);
......@@ -5695,7 +5757,7 @@ void intel_power_domains_suspend(struct drm_i915_private *i915,
{
struct i915_power_domains *power_domains = &i915->power_domains;
intel_wakeref_t wakeref __maybe_unused =
fetch_and_zero(&power_domains->wakeref);
fetch_and_zero(&power_domains->init_wakeref);
intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref);
......@@ -5719,7 +5781,8 @@ void intel_power_domains_suspend(struct drm_i915_private *i915,
* power wells if power domains must be deinitialized for suspend.
*/
if (!i915->params.disable_power_well)
intel_display_power_put_unchecked(i915, POWER_DOMAIN_INIT);
intel_display_power_put(i915, POWER_DOMAIN_INIT,
fetch_and_zero(&i915->power_domains.disable_wakeref));
intel_display_power_flush_work(i915);
intel_power_domains_verify_state(i915);
......@@ -5754,8 +5817,8 @@ void intel_power_domains_resume(struct drm_i915_private *i915)
intel_power_domains_init_hw(i915, true);
power_domains->display_core_suspended = false;
} else {
drm_WARN_ON(&i915->drm, power_domains->wakeref);
power_domains->wakeref =
drm_WARN_ON(&i915->drm, power_domains->init_wakeref);
power_domains->init_wakeref =
intel_display_power_get(i915, POWER_DOMAIN_INIT);
}
......
......@@ -212,7 +212,8 @@ struct i915_power_domains {
bool display_core_suspended;
int power_well_count;
intel_wakeref_t wakeref;
intel_wakeref_t init_wakeref;
intel_wakeref_t disable_wakeref;
struct mutex lock;
int domain_use_count[POWER_DOMAIN_NUM];
......@@ -224,6 +225,13 @@ struct i915_power_domains {
struct i915_power_well *power_wells;
};
struct intel_display_power_domain_set {
u64 mask;
#ifdef CONFIG_DRM_I915_DEBUG_RUNTIME_PM
intel_wakeref_t wakerefs[POWER_DOMAIN_NUM];
#endif
};
#define for_each_power_domain(domain, mask) \
for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
for_each_if(BIT_ULL(domain) & (mask))
......@@ -279,8 +287,6 @@ intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv,
intel_wakeref_t
intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain);
void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain);
void __intel_display_power_put_async(struct drm_i915_private *i915,
enum intel_display_power_domain domain,
intel_wakeref_t wakeref);
......@@ -297,6 +303,9 @@ intel_display_power_put_async(struct drm_i915_private *i915,
__intel_display_power_put_async(i915, domain, wakeref);
}
#else
void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain);
static inline void
intel_display_power_put(struct drm_i915_private *i915,
enum intel_display_power_domain domain,
......@@ -314,6 +323,28 @@ intel_display_power_put_async(struct drm_i915_private *i915,
}
#endif
void
intel_display_power_get_in_set(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set,
enum intel_display_power_domain domain);
bool
intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set,
enum intel_display_power_domain domain);
void
intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set,
u64 mask);
static inline void
intel_display_power_put_all_in_set(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set)
{
intel_display_power_put_mask_in_set(i915, power_domain_set, power_domain_set->mask);
}
enum dbuf_slice {
DBUF_S1,
DBUF_S2,
......
......@@ -225,6 +225,17 @@ struct intel_encoder {
const struct drm_connector *audio_connector;
};
struct intel_panel_bl_funcs {
/* Connector and platform specific backlight functions */
int (*setup)(struct intel_connector *connector, enum pipe pipe);
u32 (*get)(struct intel_connector *connector);
void (*set)(const struct drm_connector_state *conn_state, u32 level);
void (*disable)(const struct drm_connector_state *conn_state, u32 level);
void (*enable)(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state, u32 level);
u32 (*hz_to_pwm)(struct intel_connector *connector, u32 hz);
};
struct intel_panel {
struct drm_display_mode *fixed_mode;
struct drm_display_mode *downclock_mode;
......@@ -251,14 +262,7 @@ struct intel_panel {
struct backlight_device *device;
/* Connector and platform specific backlight functions */
int (*setup)(struct intel_connector *connector, enum pipe pipe);
u32 (*get)(struct intel_connector *connector);
void (*set)(const struct drm_connector_state *conn_state, u32 level);
void (*disable)(const struct drm_connector_state *conn_state);
void (*enable)(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
u32 (*hz_to_pwm)(struct intel_connector *connector, u32 hz);
const struct intel_panel_bl_funcs *funcs;
void (*power)(struct intel_connector *, bool enable);
} backlight;
};
......@@ -604,6 +608,8 @@ struct intel_plane_state {
u32 planar_slave;
struct drm_intel_sprite_colorkey ckey;
struct drm_rect psr2_sel_fetch_area;
};
struct intel_initial_plane_config {
......@@ -1047,7 +1053,10 @@ struct intel_crtc_state {
u32 cgm_mode;
};
/* bitmask of visible planes (enum plane_id) */
/* bitmask of logically enabled planes (enum plane_id) */
u8 enabled_planes;
/* bitmask of actually visible planes (enum plane_id) */
u8 active_planes;
u8 nv12_planes;
u8 c8_planes;
......@@ -1160,7 +1169,7 @@ struct intel_crtc {
/* I915_MODE_FLAG_* */
u8 mode_flags;
unsigned long long enabled_power_domains;
struct intel_display_power_domain_set enabled_power_domains;
struct intel_overlay *overlay;
struct intel_crtc_state *config;
......@@ -1186,6 +1195,15 @@ struct intel_crtc {
ktime_t start_vbl_time;
int min_vbl, max_vbl;
int scanline_start;
#ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE
struct {
u64 min;
u64 max;
u64 sum;
unsigned int over;
unsigned int times[17]; /* [1us, 16ms] */
} vbl;
#endif
} debug;
/* scalers available on this crtc */
......@@ -1375,6 +1393,7 @@ struct intel_dp {
unsigned long last_power_on;
unsigned long last_backlight_off;
ktime_t panel_power_off_time;
intel_wakeref_t vdd_wakeref;
/*
* Pipe whose power sequencer is currently locked into
......@@ -1444,6 +1463,9 @@ struct intel_dp {
bool rgb_to_ycbcr;
} dfp;
/* To control wakeup latency, e.g. for irq-driven dp aux transfers. */
struct pm_qos_request pm_qos;
/* Display stream compression testing */
bool force_dsc_en;
......@@ -1460,6 +1482,7 @@ enum lspcon_vendor {
struct intel_lspcon {
bool active;
bool hdr_supported;
enum drm_lspcon_mode mode;
enum lspcon_vendor vendor;
};
......@@ -1476,6 +1499,8 @@ struct intel_digital_port {
/* Used for DP and ICL+ TypeC/DP and TypeC/HDMI ports. */
enum aux_ch aux_ch;
enum intel_display_power_domain ddi_io_power_domain;
intel_wakeref_t ddi_io_wakeref;
intel_wakeref_t aux_wakeref;
struct mutex tc_lock; /* protects the TypeC port mode */
intel_wakeref_t tc_lock_wakeref;
int tc_link_refcount;
......@@ -1765,6 +1790,12 @@ intel_crtc_has_dp_encoder(const struct intel_crtc_state *crtc_state)
(1 << INTEL_OUTPUT_EDP));
}
static inline bool
intel_crtc_needs_modeset(const struct intel_crtc_state *crtc_state)
{
return drm_atomic_crtc_needs_modeset(&crtc_state->uapi);
}
static inline void
intel_wait_for_vblank(struct drm_i915_private *dev_priv, enum pipe pipe)
{
......@@ -1787,4 +1818,10 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
return i915_ggtt_offset(state->vma);
}
static inline struct intel_frontbuffer *
to_intel_frontbuffer(struct drm_framebuffer *fb)
{
return fb ? to_intel_framebuffer(fb)->frontbuffer : NULL;
}
#endif /* __INTEL_DISPLAY_TYPES_H__ */
......@@ -1512,7 +1512,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
* lowest possible wakeup latency and so prevent the cpu from going into
* deep sleep states.
*/
cpu_latency_qos_update_request(&i915->pm_qos, 0);
cpu_latency_qos_update_request(&intel_dp->pm_qos, 0);
intel_dp_check_edp(intel_dp);
......@@ -1645,7 +1645,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
ret = recv_bytes;
out:
cpu_latency_qos_update_request(&i915->pm_qos, PM_QOS_DEFAULT_VALUE);
cpu_latency_qos_update_request(&intel_dp->pm_qos, PM_QOS_DEFAULT_VALUE);
if (vdd)
edp_panel_vdd_off(intel_dp, false);
......@@ -1921,6 +1921,9 @@ static i915_reg_t tgl_aux_data_reg(struct intel_dp *intel_dp, int index)
static void
intel_dp_aux_fini(struct intel_dp *intel_dp)
{
if (cpu_latency_qos_request_active(&intel_dp->pm_qos))
cpu_latency_qos_remove_request(&intel_dp->pm_qos);
kfree(intel_dp->aux.name);
}
......@@ -1973,6 +1976,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp)
encoder->base.name);
intel_dp->aux.transfer = intel_dp_aux_transfer;
cpu_latency_qos_add_request(&intel_dp->pm_qos, PM_QOS_DEFAULT_VALUE);
}
bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
......@@ -2312,6 +2316,14 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder,
u8 line_buf_depth;
int ret;
/*
* RC_MODEL_SIZE is currently a constant across all configurations.
*
* FIXME: Look into using sink defined DPCD DP_DSC_RC_BUF_BLK_SIZE and
* DP_DSC_RC_BUF_SIZE for this.
*/
vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST;
ret = intel_dsc_compute_params(encoder, crtc_state);
if (ret)
return ret;
......@@ -3117,8 +3129,9 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
if (edp_have_panel_vdd(intel_dp))
return need_to_disable;
intel_display_power_get(dev_priv,
intel_aux_power_domain(dig_port));
drm_WARN_ON(&dev_priv->drm, intel_dp->vdd_wakeref);
intel_dp->vdd_wakeref = intel_display_power_get(dev_priv,
intel_aux_power_domain(dig_port));
drm_dbg_kms(&dev_priv->drm, "Turning [ENCODER:%d:%s] VDD on\n",
dig_port->base.base.base.id,
......@@ -3211,8 +3224,9 @@ static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp)
if ((pp & PANEL_POWER_ON) == 0)
intel_dp->panel_power_off_time = ktime_get_boottime();
intel_display_power_put_unchecked(dev_priv,
intel_aux_power_domain(dig_port));
intel_display_power_put(dev_priv,
intel_aux_power_domain(dig_port),
fetch_and_zero(&intel_dp->vdd_wakeref));
}
static void edp_panel_vdd_work(struct work_struct *__work)
......@@ -3364,7 +3378,9 @@ static void edp_panel_off(struct intel_dp *intel_dp)
intel_dp->panel_power_off_time = ktime_get_boottime();
/* We got a reference when we enabled the VDD. */
intel_display_power_put_unchecked(dev_priv, intel_aux_power_domain(dig_port));
intel_display_power_put(dev_priv,
intel_aux_power_domain(dig_port),
fetch_and_zero(&intel_dp->vdd_wakeref));
}
void intel_edp_panel_off(struct intel_dp *intel_dp)
......@@ -3602,6 +3618,29 @@ void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
enable ? "enable" : "disable");
}
static void
intel_edp_init_source_oui(struct intel_dp *intel_dp, bool careful)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 oui[] = { 0x00, 0xaa, 0x01 };
u8 buf[3] = { 0 };
/*
* During driver init, we want to be careful and avoid changing the source OUI if it's
* already set to what we want, so as to avoid clearing any state by accident
*/
if (careful) {
if (drm_dp_dpcd_read(&intel_dp->aux, DP_SOURCE_OUI, buf, sizeof(buf)) < 0)
drm_err(&i915->drm, "Failed to read source OUI\n");
if (memcmp(oui, buf, sizeof(oui)) == 0)
return;
}
if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) < 0)
drm_err(&i915->drm, "Failed to write source OUI\n");
}
/* If the device supports it, try to set the power state appropriately */
void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode)
{
......@@ -3623,6 +3662,10 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode)
lspcon_resume(dp_to_dig_port(intel_dp));
/* Write the source OUI as early as possible */
if (intel_dp_is_edp(intel_dp))
intel_edp_init_source_oui(intel_dp, false);
/*
* When turning on, we need to retry for 1ms to give the sink
* time to wake up.
......@@ -5197,6 +5240,12 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)
if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
intel_dp_get_dsc_sink_cap(intel_dp);
/*
* If needed, program our source OUI so we can make various Intel-specific AUX services
* available (such as HDR backlight controls)
*/
intel_edp_init_source_oui(intel_dp, true);
return true;
}
......@@ -7177,6 +7226,8 @@ intel_dp_connector_register(struct drm_connector *connector)
{
struct drm_i915_private *i915 = to_i915(connector->dev);
struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector));
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct intel_lspcon *lspcon = &dig_port->lspcon;
int ret;
ret = intel_connector_register(connector);
......@@ -7190,6 +7241,22 @@ intel_dp_connector_register(struct drm_connector *connector)
ret = drm_dp_aux_register(&intel_dp->aux);
if (!ret)
drm_dp_cec_register_connector(&intel_dp->aux, connector);
if (!intel_bios_is_lspcon_present(i915, dig_port->base.port))
return ret;
/*
* ToDo: Clean this up to handle lspcon init and resume more
* efficiently and streamlined.
*/
if (lspcon_init(dig_port)) {
lspcon_detect_hdr_capability(lspcon);
if (lspcon->hdr_supported)
drm_object_attach_property(&connector->base,
connector->dev->mode_config.hdr_output_metadata_property,
0);
}
return ret;
}
......@@ -7279,7 +7346,9 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
*/
drm_dbg_kms(&dev_priv->drm,
"VDD left on by BIOS, adjusting state tracking\n");
intel_display_power_get(dev_priv, intel_aux_power_domain(dig_port));
drm_WARN_ON(&dev_priv->drm, intel_dp->vdd_wakeref);
intel_dp->vdd_wakeref = intel_display_power_get(dev_priv,
intel_aux_power_domain(dig_port));
edp_panel_vdd_schedule_off(intel_dp);
}
......@@ -7578,7 +7647,13 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
else if (INTEL_GEN(dev_priv) >= 5)
drm_connector_attach_max_bpc_property(connector, 6, 12);
intel_attach_colorspace_property(connector);
/* Register HDMI colorspace for case of lspcon */
if (intel_bios_is_lspcon_present(dev_priv, port)) {
drm_connector_attach_content_type_property(connector);
intel_attach_hdmi_colorspace_property(connector);
} else {
intel_attach_dp_colorspace_property(connector);
}
if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 11)
drm_object_attach_property(&connector->base,
......
......@@ -77,7 +77,7 @@ static void dcs_set_backlight(const struct drm_connector_state *conn_state, u32
}
}
static void dcs_disable_backlight(const struct drm_connector_state *conn_state)
static void dcs_disable_backlight(const struct drm_connector_state *conn_state, u32 level)
{
struct intel_dsi *intel_dsi = enc_to_intel_dsi(to_intel_encoder(conn_state->best_encoder));
struct mipi_dsi_device *dsi_device;
......@@ -111,10 +111,9 @@ static void dcs_disable_backlight(const struct drm_connector_state *conn_state)
}
static void dcs_enable_backlight(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
const struct drm_connector_state *conn_state, u32 level)
{
struct intel_dsi *intel_dsi = enc_to_intel_dsi(to_intel_encoder(conn_state->best_encoder));
struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel;
struct mipi_dsi_device *dsi_device;
enum port port;
......@@ -142,7 +141,7 @@ static void dcs_enable_backlight(const struct intel_crtc_state *crtc_state,
&cabc, sizeof(cabc));
}
dcs_set_backlight(conn_state, panel->backlight.level);
dcs_set_backlight(conn_state, level);
}
static int dcs_setup_backlight(struct intel_connector *connector,
......@@ -156,6 +155,14 @@ static int dcs_setup_backlight(struct intel_connector *connector,
return 0;
}
static const struct intel_panel_bl_funcs dcs_bl_funcs = {
.setup = dcs_setup_backlight,
.enable = dcs_enable_backlight,
.disable = dcs_disable_backlight,
.set = dcs_set_backlight,
.get = dcs_get_backlight,
};
int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector)
{
struct drm_device *dev = intel_connector->base.dev;
......@@ -169,11 +176,7 @@ int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector)
if (drm_WARN_ON(dev, encoder->type != INTEL_OUTPUT_DSI))
return -EINVAL;
panel->backlight.setup = dcs_setup_backlight;
panel->backlight.enable = dcs_enable_backlight;
panel->backlight.disable = dcs_disable_backlight;
panel->backlight.set = dcs_set_backlight;
panel->backlight.get = dcs_get_backlight;
panel->backlight.funcs = &dcs_bl_funcs;
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -262,7 +262,7 @@ static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port)
mask |= BIT(TC_PORT_LEGACY);
/* The sink can be connected only in a single mode. */
if (!drm_WARN_ON(&i915->drm, hweight32(mask) > 1))
if (!drm_WARN_ON_ONCE(&i915->drm, hweight32(mask) > 1))
tc_port_fixup_legacy_flag(dig_port, mask);
return mask;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment