Merge tag 'drm-intel-next-2022-09-16-1' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
drm/i915 feature pull #2 for v6.1: Features and functionality: - More Meteorlake platform enabling (Radhakrishna, Imre, Madhumitha) - Allow seamless M/N changes on eDP panels that support it (Ville) - Switch DSC debugfs from output bpp to input bpc (Swati) Refactoring and cleanups: - Clocking and DPLL refactoring and cleanups to support seamless M/N (Ville) - Plenty of VBT definition and parsing updates and cleanups (Ville) - Extract SKL watermark code to a separate file, and clean up (Ville) - Clean up IPC interfaces and debugfs (Jani) - Continue moving display data under drm_i915_private display sub-struct (Jani) - Display quirk handling refactoring and abstractions (Jani) - Stop using implicit dev_priv in gmbus registers (Jani) - BUG_ON() removals and conversions to drm_WARN_ON() and BUILD_BUG_ON() (Jani) - Use drm_dp_phy_name() for logging (Jani) - Use REG_BIT() macros for CDCLK registers (Stan) - Move display and media IP versions to runtime info (Radhakrishna) Fixes: - Fix DP MST suspend to avoid use-after-free (Andrzej) - Fix HPD suspend to avoid use-after-free for fbdev (Andrzej) - Fix various PSR issues regarding selective update and damage clips (Jouni) - Fix runtime pm wakerefs for driver remove and release (Mitul Golani) - Fix conditions for filtering fixed modes for panels (Ville) - Fix TV encoder clock computation (Ville) - Fix dvo mode_valid hook return type (Nathan Huckleberry) Merges: - Backmerge drm-next to sync the DP MST atomic changes (Jani) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/87o7vfr064.fsf@intel.com
This commit is contained in:
commit
47cd3af67d
@ -258,7 +258,8 @@ i915-y += \
|
||||
display/intel_vga.o \
|
||||
display/i9xx_plane.o \
|
||||
display/skl_scaler.o \
|
||||
display/skl_universal_plane.o
|
||||
display/skl_universal_plane.o \
|
||||
display/skl_watermark.o
|
||||
i915-$(CONFIG_ACPI) += \
|
||||
display/intel_acpi.o \
|
||||
display/intel_opregion.o
|
||||
|
@ -202,7 +202,7 @@ bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
|
||||
* Should measure whether using a lower cdclk w/o IPS
|
||||
*/
|
||||
if (IS_BROADWELL(i915) &&
|
||||
crtc_state->pixel_rate > i915->max_cdclk_freq * 95 / 100)
|
||||
crtc_state->pixel_rate > i915->display.cdclk.max_cdclk_freq * 95 / 100)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -125,7 +125,7 @@ static struct intel_fbc *i9xx_plane_fbc(struct drm_i915_private *dev_priv,
|
||||
enum i9xx_plane_id i9xx_plane)
|
||||
{
|
||||
if (i9xx_plane_has_fbc(dev_priv, i9xx_plane))
|
||||
return dev_priv->fbc[INTEL_FBC_A];
|
||||
return dev_priv->display.fbc[INTEL_FBC_A];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1630,6 +1630,8 @@ static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
|
||||
/* FIXME: initialize from VBT */
|
||||
vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST;
|
||||
|
||||
vdsc_cfg->pic_height = crtc_state->hw.adjusted_mode.crtc_vdisplay;
|
||||
|
||||
ret = intel_dsc_compute_params(crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -62,9 +62,9 @@ int intel_digital_connector_atomic_get_property(struct drm_connector *connector,
|
||||
struct intel_digital_connector_state *intel_conn_state =
|
||||
to_intel_digital_connector_state(state);
|
||||
|
||||
if (property == dev_priv->force_audio_property)
|
||||
if (property == dev_priv->display.properties.force_audio)
|
||||
*val = intel_conn_state->force_audio;
|
||||
else if (property == dev_priv->broadcast_rgb_property)
|
||||
else if (property == dev_priv->display.properties.broadcast_rgb)
|
||||
*val = intel_conn_state->broadcast_rgb;
|
||||
else {
|
||||
drm_dbg_atomic(&dev_priv->drm,
|
||||
@ -95,12 +95,12 @@ int intel_digital_connector_atomic_set_property(struct drm_connector *connector,
|
||||
struct intel_digital_connector_state *intel_conn_state =
|
||||
to_intel_digital_connector_state(state);
|
||||
|
||||
if (property == dev_priv->force_audio_property) {
|
||||
if (property == dev_priv->display.properties.force_audio) {
|
||||
intel_conn_state->force_audio = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (property == dev_priv->broadcast_rgb_property) {
|
||||
if (property == dev_priv->display.properties.broadcast_rgb) {
|
||||
intel_conn_state->broadcast_rgb = val;
|
||||
return 0;
|
||||
}
|
||||
|
@ -42,9 +42,9 @@
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_fb.h"
|
||||
#include "intel_fb_pin.h"
|
||||
#include "intel_pm.h"
|
||||
#include "intel_sprite.h"
|
||||
#include "skl_scaler.h"
|
||||
#include "skl_watermark.h"
|
||||
|
||||
static void intel_plane_state_reset(struct intel_plane_state *plane_state,
|
||||
struct intel_plane *plane)
|
||||
|
@ -532,7 +532,7 @@ static unsigned int calc_hblank_early_prog(struct intel_encoder *encoder,
|
||||
h_total = crtc_state->hw.adjusted_mode.crtc_htotal;
|
||||
pixel_clk = crtc_state->hw.adjusted_mode.crtc_clock;
|
||||
vdsc_bpp = crtc_state->dsc.compressed_bpp;
|
||||
cdclk = i915->cdclk.hw.cdclk;
|
||||
cdclk = i915->display.cdclk.hw.cdclk;
|
||||
/* fec= 0.972261, using rounding multiplier of 1000000 */
|
||||
fec_coeff = 972261;
|
||||
link_clk = crtc_state->port_clock;
|
||||
@ -971,7 +971,7 @@ void intel_audio_cdclk_change_post(struct drm_i915_private *i915)
|
||||
struct aud_ts_cdclk_m_n aud_ts;
|
||||
|
||||
if (DISPLAY_VER(i915) >= 13) {
|
||||
get_aud_ts_cdclk_m_n(i915->cdclk.hw.ref, i915->cdclk.hw.cdclk, &aud_ts);
|
||||
get_aud_ts_cdclk_m_n(i915->display.cdclk.hw.ref, i915->display.cdclk.hw.cdclk, &aud_ts);
|
||||
|
||||
intel_de_write(i915, AUD_TS_CDCLK_N, aud_ts.n);
|
||||
intel_de_write(i915, AUD_TS_CDCLK_M, aud_ts.m | AUD_TS_CDCLK_M_EN);
|
||||
@ -1119,7 +1119,7 @@ static int i915_audio_component_get_cdclk_freq(struct device *kdev)
|
||||
if (drm_WARN_ON_ONCE(&dev_priv->drm, !HAS_DDI(dev_priv)))
|
||||
return -ENODEV;
|
||||
|
||||
return dev_priv->cdclk.hw.cdclk;
|
||||
return dev_priv->display.cdclk.hw.cdclk;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "intel_panel.h"
|
||||
#include "intel_pci_config.h"
|
||||
#include "intel_pps.h"
|
||||
#include "intel_quirks.h"
|
||||
|
||||
/**
|
||||
* scale - scale values from one range to another
|
||||
@ -88,7 +89,7 @@ u32 intel_backlight_invert_pwm_level(struct intel_connector *connector, u32 val)
|
||||
return val;
|
||||
|
||||
if (dev_priv->params.invert_brightness > 0 ||
|
||||
dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
|
||||
intel_has_quirk(dev_priv, QUIRK_INVERT_BRIGHTNESS)) {
|
||||
return panel->backlight.pwm_level_max - val + panel->backlight.pwm_level_min;
|
||||
}
|
||||
|
||||
@ -128,7 +129,7 @@ u32 intel_backlight_level_from_pwm(struct intel_connector *connector, u32 val)
|
||||
panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0);
|
||||
|
||||
if (dev_priv->params.invert_brightness > 0 ||
|
||||
(dev_priv->params.invert_brightness == 0 && dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS))
|
||||
(dev_priv->params.invert_brightness == 0 && intel_has_quirk(dev_priv, QUIRK_INVERT_BRIGHTNESS)))
|
||||
val = panel->backlight.pwm_level_max - (val - panel->backlight.pwm_level_min);
|
||||
|
||||
return scale(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max,
|
||||
@ -305,7 +306,7 @@ void intel_backlight_set_acpi(const struct drm_connector_state *conn_state,
|
||||
if (!panel->backlight.present || !conn_state->crtc)
|
||||
return;
|
||||
|
||||
mutex_lock(&dev_priv->backlight_lock);
|
||||
mutex_lock(&dev_priv->display.backlight.lock);
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0);
|
||||
|
||||
@ -321,7 +322,7 @@ void intel_backlight_set_acpi(const struct drm_connector_state *conn_state,
|
||||
if (panel->backlight.enabled)
|
||||
intel_panel_actually_set_backlight(conn_state, hw_level);
|
||||
|
||||
mutex_unlock(&dev_priv->backlight_lock);
|
||||
mutex_unlock(&dev_priv->display.backlight.lock);
|
||||
}
|
||||
|
||||
static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level)
|
||||
@ -465,14 +466,14 @@ void intel_backlight_disable(const struct drm_connector_state *old_conn_state)
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&dev_priv->backlight_lock);
|
||||
mutex_lock(&dev_priv->display.backlight.lock);
|
||||
|
||||
if (panel->backlight.device)
|
||||
panel->backlight.device->props.power = FB_BLANK_POWERDOWN;
|
||||
panel->backlight.enabled = false;
|
||||
panel->backlight.funcs->disable(old_conn_state, 0);
|
||||
|
||||
mutex_unlock(&dev_priv->backlight_lock);
|
||||
mutex_unlock(&dev_priv->display.backlight.lock);
|
||||
}
|
||||
|
||||
static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
|
||||
@ -815,11 +816,11 @@ void intel_backlight_enable(const struct intel_crtc_state *crtc_state,
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "pipe %c\n", pipe_name(pipe));
|
||||
|
||||
mutex_lock(&dev_priv->backlight_lock);
|
||||
mutex_lock(&dev_priv->display.backlight.lock);
|
||||
|
||||
__intel_backlight_enable(crtc_state, conn_state);
|
||||
|
||||
mutex_unlock(&dev_priv->backlight_lock);
|
||||
mutex_unlock(&dev_priv->display.backlight.lock);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
|
||||
@ -829,12 +830,12 @@ static u32 intel_panel_get_backlight(struct intel_connector *connector)
|
||||
struct intel_panel *panel = &connector->panel;
|
||||
u32 val = 0;
|
||||
|
||||
mutex_lock(&dev_priv->backlight_lock);
|
||||
mutex_lock(&dev_priv->display.backlight.lock);
|
||||
|
||||
if (panel->backlight.enabled)
|
||||
val = panel->backlight.funcs->get(connector, intel_connector_get_pipe(connector));
|
||||
|
||||
mutex_unlock(&dev_priv->backlight_lock);
|
||||
mutex_unlock(&dev_priv->display.backlight.lock);
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "get backlight PWM = %d\n", val);
|
||||
return val;
|
||||
@ -862,7 +863,7 @@ static void intel_panel_set_backlight(const struct drm_connector_state *conn_sta
|
||||
if (!panel->backlight.present)
|
||||
return;
|
||||
|
||||
mutex_lock(&dev_priv->backlight_lock);
|
||||
mutex_lock(&dev_priv->display.backlight.lock);
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0);
|
||||
|
||||
@ -872,7 +873,7 @@ static void intel_panel_set_backlight(const struct drm_connector_state *conn_sta
|
||||
if (panel->backlight.enabled)
|
||||
intel_panel_actually_set_backlight(conn_state, hw_level);
|
||||
|
||||
mutex_unlock(&dev_priv->backlight_lock);
|
||||
mutex_unlock(&dev_priv->display.backlight.lock);
|
||||
}
|
||||
|
||||
static int intel_backlight_device_update_status(struct backlight_device *bd)
|
||||
@ -1113,7 +1114,7 @@ static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
|
||||
if (IS_PINEVIEW(dev_priv))
|
||||
clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
|
||||
else
|
||||
clock = KHz(dev_priv->cdclk.hw.cdclk);
|
||||
clock = KHz(dev_priv->display.cdclk.hw.cdclk);
|
||||
|
||||
return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32);
|
||||
}
|
||||
@ -1131,7 +1132,7 @@ static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
|
||||
if (IS_G4X(dev_priv))
|
||||
clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq);
|
||||
else
|
||||
clock = KHz(dev_priv->cdclk.hw.cdclk);
|
||||
clock = KHz(dev_priv->display.cdclk.hw.cdclk);
|
||||
|
||||
return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128);
|
||||
}
|
||||
@ -1591,11 +1592,11 @@ void intel_backlight_update(struct intel_atomic_state *state,
|
||||
if (!panel->backlight.present)
|
||||
return;
|
||||
|
||||
mutex_lock(&dev_priv->backlight_lock);
|
||||
mutex_lock(&dev_priv->display.backlight.lock);
|
||||
if (!panel->backlight.enabled)
|
||||
__intel_backlight_enable(crtc_state, conn_state);
|
||||
|
||||
mutex_unlock(&dev_priv->backlight_lock);
|
||||
mutex_unlock(&dev_priv->display.backlight.lock);
|
||||
}
|
||||
|
||||
int intel_backlight_setup(struct intel_connector *connector, enum pipe pipe)
|
||||
@ -1605,7 +1606,7 @@ int intel_backlight_setup(struct intel_connector *connector, enum pipe pipe)
|
||||
int ret;
|
||||
|
||||
if (!connector->panel.vbt.backlight.present) {
|
||||
if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
|
||||
if (intel_has_quirk(dev_priv, QUIRK_BACKLIGHT_PRESENT)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"no backlight present per VBT, but present per quirk\n");
|
||||
} else {
|
||||
@ -1620,9 +1621,9 @@ int intel_backlight_setup(struct intel_connector *connector, enum pipe pipe)
|
||||
return -ENODEV;
|
||||
|
||||
/* set level and max in panel struct */
|
||||
mutex_lock(&dev_priv->backlight_lock);
|
||||
mutex_lock(&dev_priv->display.backlight.lock);
|
||||
ret = panel->backlight.funcs->setup(connector, pipe);
|
||||
mutex_unlock(&dev_priv->backlight_lock);
|
||||
mutex_unlock(&dev_priv->display.backlight.lock);
|
||||
|
||||
if (ret) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
@ -1777,7 +1778,7 @@ void intel_backlight_init_funcs(struct intel_panel *panel)
|
||||
if (intel_dp_aux_init_backlight_funcs(connector) == 0)
|
||||
return;
|
||||
|
||||
if (!(dev_priv->quirks & QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK))
|
||||
if (!intel_has_quirk(dev_priv, QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK))
|
||||
connector->panel.backlight.power = intel_pps_backlight_power;
|
||||
}
|
||||
|
||||
|
@ -135,18 +135,6 @@ static u32 raw_block_offset(const void *bdb, enum bdb_block_id section_id)
|
||||
return block - bdb;
|
||||
}
|
||||
|
||||
/* size of the block excluding the header */
|
||||
static u32 raw_block_size(const void *bdb, enum bdb_block_id section_id)
|
||||
{
|
||||
const void *block;
|
||||
|
||||
block = find_raw_section(bdb, section_id);
|
||||
if (!block)
|
||||
return 0;
|
||||
|
||||
return get_blocksize(block);
|
||||
}
|
||||
|
||||
struct bdb_block_entry {
|
||||
struct list_head node;
|
||||
enum bdb_block_id section_id;
|
||||
@ -159,7 +147,7 @@ find_section(struct drm_i915_private *i915,
|
||||
{
|
||||
struct bdb_block_entry *entry;
|
||||
|
||||
list_for_each_entry(entry, &i915->vbt.bdb_blocks, node) {
|
||||
list_for_each_entry(entry, &i915->display.vbt.bdb_blocks, node) {
|
||||
if (entry->section_id == section_id)
|
||||
return entry->data + 3;
|
||||
}
|
||||
@ -231,9 +219,14 @@ static bool validate_lfp_data_ptrs(const void *bdb,
|
||||
{
|
||||
int fp_timing_size, dvo_timing_size, panel_pnp_id_size, panel_name_size;
|
||||
int data_block_size, lfp_data_size;
|
||||
const void *data_block;
|
||||
int i;
|
||||
|
||||
data_block_size = raw_block_size(bdb, BDB_LVDS_LFP_DATA);
|
||||
data_block = find_raw_section(bdb, BDB_LVDS_LFP_DATA);
|
||||
if (!data_block)
|
||||
return false;
|
||||
|
||||
data_block_size = get_blocksize(data_block);
|
||||
if (data_block_size == 0)
|
||||
return false;
|
||||
|
||||
@ -261,21 +254,6 @@ static bool validate_lfp_data_ptrs(const void *bdb,
|
||||
if (16 * lfp_data_size > data_block_size)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Except for vlv/chv machines all real VBTs seem to have 6
|
||||
* unaccounted bytes in the fp_timing table. And it doesn't
|
||||
* appear to be a really intentional hole as the fp_timing
|
||||
* 0xffff terminator is always within those 6 missing bytes.
|
||||
*/
|
||||
if (fp_timing_size + dvo_timing_size + panel_pnp_id_size != lfp_data_size &&
|
||||
fp_timing_size + 6 + dvo_timing_size + panel_pnp_id_size != lfp_data_size)
|
||||
return false;
|
||||
|
||||
if (ptrs->ptr[0].fp_timing.offset + fp_timing_size > ptrs->ptr[0].dvo_timing.offset ||
|
||||
ptrs->ptr[0].dvo_timing.offset + dvo_timing_size != ptrs->ptr[0].panel_pnp_id.offset ||
|
||||
ptrs->ptr[0].panel_pnp_id.offset + panel_pnp_id_size != lfp_data_size)
|
||||
return false;
|
||||
|
||||
/* make sure the table entries have uniform size */
|
||||
for (i = 1; i < 16; i++) {
|
||||
if (ptrs->ptr[i].fp_timing.table_size != fp_timing_size ||
|
||||
@ -289,6 +267,23 @@ static bool validate_lfp_data_ptrs(const void *bdb,
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Except for vlv/chv machines all real VBTs seem to have 6
|
||||
* unaccounted bytes in the fp_timing table. And it doesn't
|
||||
* appear to be a really intentional hole as the fp_timing
|
||||
* 0xffff terminator is always within those 6 missing bytes.
|
||||
*/
|
||||
if (fp_timing_size + 6 + dvo_timing_size + panel_pnp_id_size == lfp_data_size)
|
||||
fp_timing_size += 6;
|
||||
|
||||
if (fp_timing_size + dvo_timing_size + panel_pnp_id_size != lfp_data_size)
|
||||
return false;
|
||||
|
||||
if (ptrs->ptr[0].fp_timing.offset + fp_timing_size != ptrs->ptr[0].dvo_timing.offset ||
|
||||
ptrs->ptr[0].dvo_timing.offset + dvo_timing_size != ptrs->ptr[0].panel_pnp_id.offset ||
|
||||
ptrs->ptr[0].panel_pnp_id.offset + panel_pnp_id_size != lfp_data_size)
|
||||
return false;
|
||||
|
||||
/* make sure the tables fit inside the data block */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (ptrs->ptr[i].fp_timing.offset + fp_timing_size > data_block_size ||
|
||||
@ -300,6 +295,15 @@ static bool validate_lfp_data_ptrs(const void *bdb,
|
||||
if (ptrs->panel_name.offset + 16 * panel_name_size > data_block_size)
|
||||
return false;
|
||||
|
||||
/* make sure fp_timing terminators are present at expected locations */
|
||||
for (i = 0; i < 16; i++) {
|
||||
const u16 *t = data_block + ptrs->ptr[i].fp_timing.offset +
|
||||
fp_timing_size - 2;
|
||||
|
||||
if (*t != 0xffff)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -333,18 +337,6 @@ static bool fixup_lfp_data_ptrs(const void *bdb, void *ptrs_block)
|
||||
return validate_lfp_data_ptrs(bdb, ptrs);
|
||||
}
|
||||
|
||||
static const void *find_fp_timing_terminator(const u8 *data, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size - 1; i++) {
|
||||
if (data[i] == 0xff && data[i+1] == 0xff)
|
||||
return &data[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int make_lfp_data_ptr(struct lvds_lfp_data_ptr_table *table,
|
||||
int table_size, int total_size)
|
||||
{
|
||||
@ -368,11 +360,22 @@ static void next_lfp_data_ptr(struct lvds_lfp_data_ptr_table *next,
|
||||
static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
|
||||
const void *bdb)
|
||||
{
|
||||
int i, size, table_size, block_size, offset;
|
||||
const void *t0, *t1, *block;
|
||||
int i, size, table_size, block_size, offset, fp_timing_size;
|
||||
struct bdb_lvds_lfp_data_ptrs *ptrs;
|
||||
const void *block;
|
||||
void *ptrs_block;
|
||||
|
||||
/*
|
||||
* The hardcoded fp_timing_size is only valid for
|
||||
* modernish VBTs. All older VBTs definitely should
|
||||
* include block 41 and thus we don't need to
|
||||
* generate one.
|
||||
*/
|
||||
if (i915->display.vbt.version < 155)
|
||||
return NULL;
|
||||
|
||||
fp_timing_size = 38;
|
||||
|
||||
block = find_raw_section(bdb, BDB_LVDS_LFP_DATA);
|
||||
if (!block)
|
||||
return NULL;
|
||||
@ -381,17 +384,8 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
|
||||
|
||||
block_size = get_blocksize(block);
|
||||
|
||||
size = block_size;
|
||||
t0 = find_fp_timing_terminator(block, size);
|
||||
if (!t0)
|
||||
return NULL;
|
||||
|
||||
size -= t0 - block - 2;
|
||||
t1 = find_fp_timing_terminator(t0 + 2, size);
|
||||
if (!t1)
|
||||
return NULL;
|
||||
|
||||
size = t1 - t0;
|
||||
size = fp_timing_size + sizeof(struct lvds_dvo_timing) +
|
||||
sizeof(struct lvds_pnp_id);
|
||||
if (size * 16 > block_size)
|
||||
return NULL;
|
||||
|
||||
@ -409,7 +403,7 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
|
||||
table_size = sizeof(struct lvds_dvo_timing);
|
||||
size = make_lfp_data_ptr(&ptrs->ptr[0].dvo_timing, table_size, size);
|
||||
|
||||
table_size = t0 - block + 2;
|
||||
table_size = fp_timing_size;
|
||||
size = make_lfp_data_ptr(&ptrs->ptr[0].fp_timing, table_size, size);
|
||||
|
||||
if (ptrs->ptr[0].fp_timing.table_size)
|
||||
@ -424,14 +418,14 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = t1 - t0;
|
||||
size = fp_timing_size + sizeof(struct lvds_dvo_timing) +
|
||||
sizeof(struct lvds_pnp_id);
|
||||
for (i = 1; i < 16; i++) {
|
||||
next_lfp_data_ptr(&ptrs->ptr[i].fp_timing, &ptrs->ptr[i-1].fp_timing, size);
|
||||
next_lfp_data_ptr(&ptrs->ptr[i].dvo_timing, &ptrs->ptr[i-1].dvo_timing, size);
|
||||
next_lfp_data_ptr(&ptrs->ptr[i].panel_pnp_id, &ptrs->ptr[i-1].panel_pnp_id, size);
|
||||
}
|
||||
|
||||
size = t1 - t0;
|
||||
table_size = sizeof(struct lvds_lfp_panel_name);
|
||||
|
||||
if (16 * (size + table_size) <= block_size) {
|
||||
@ -479,6 +473,13 @@ init_bdb_block(struct drm_i915_private *i915,
|
||||
|
||||
block_size = get_blocksize(block);
|
||||
|
||||
/*
|
||||
* Version number and new block size are considered
|
||||
* part of the header for MIPI sequenece block v3+.
|
||||
*/
|
||||
if (section_id == BDB_MIPI_SEQUENCE && *(const u8 *)block >= 3)
|
||||
block_size += 5;
|
||||
|
||||
entry = kzalloc(struct_size(entry, data, max(min_size, block_size) + 3),
|
||||
GFP_KERNEL);
|
||||
if (!entry) {
|
||||
@ -501,7 +502,7 @@ init_bdb_block(struct drm_i915_private *i915,
|
||||
return;
|
||||
}
|
||||
|
||||
list_add_tail(&entry->node, &i915->vbt.bdb_blocks);
|
||||
list_add_tail(&entry->node, &i915->display.vbt.bdb_blocks);
|
||||
}
|
||||
|
||||
static void init_bdb_blocks(struct drm_i915_private *i915,
|
||||
@ -604,6 +605,19 @@ get_lfp_data_tail(const struct bdb_lvds_lfp_data *data,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void dump_pnp_id(struct drm_i915_private *i915,
|
||||
const struct lvds_pnp_id *pnp_id,
|
||||
const char *name)
|
||||
{
|
||||
u16 mfg_name = be16_to_cpu((__force __be16)pnp_id->mfg_name);
|
||||
char vend[4];
|
||||
|
||||
drm_dbg_kms(&i915->drm, "%s PNPID mfg: %s (0x%x), prod: %u, serial: %u, week: %d, year: %d\n",
|
||||
name, drm_edid_decode_mfg_id(mfg_name, vend),
|
||||
pnp_id->mfg_name, pnp_id->product_code, pnp_id->serial,
|
||||
pnp_id->mfg_week, pnp_id->mfg_year + 1990);
|
||||
}
|
||||
|
||||
static int opregion_get_panel_type(struct drm_i915_private *i915,
|
||||
const struct intel_bios_encoder_data *devdata,
|
||||
const struct edid *edid)
|
||||
@ -655,6 +669,8 @@ static int pnpid_get_panel_type(struct drm_i915_private *i915,
|
||||
edid_id_nodate.mfg_week = 0;
|
||||
edid_id_nodate.mfg_year = 0;
|
||||
|
||||
dump_pnp_id(i915, edid_id, "EDID");
|
||||
|
||||
ptrs = find_section(i915, BDB_LVDS_LFP_DATA_PTRS);
|
||||
if (!ptrs)
|
||||
return -1;
|
||||
@ -861,6 +877,7 @@ parse_lfp_data(struct drm_i915_private *i915,
|
||||
const struct bdb_lvds_lfp_data *data;
|
||||
const struct bdb_lvds_lfp_data_tail *tail;
|
||||
const struct bdb_lvds_lfp_data_ptrs *ptrs;
|
||||
const struct lvds_pnp_id *pnp_id;
|
||||
int panel_type = panel->vbt.panel_type;
|
||||
|
||||
ptrs = find_section(i915, BDB_LVDS_LFP_DATA_PTRS);
|
||||
@ -874,11 +891,18 @@ parse_lfp_data(struct drm_i915_private *i915,
|
||||
if (!panel->vbt.lfp_lvds_vbt_mode)
|
||||
parse_lfp_panel_dtd(i915, panel, data, ptrs);
|
||||
|
||||
pnp_id = get_lvds_pnp_id(data, ptrs, panel_type);
|
||||
dump_pnp_id(i915, pnp_id, "Panel");
|
||||
|
||||
tail = get_lfp_data_tail(data, ptrs);
|
||||
if (!tail)
|
||||
return;
|
||||
|
||||
if (i915->vbt.version >= 188) {
|
||||
drm_dbg_kms(&i915->drm, "Panel name: %.*s\n",
|
||||
(int)sizeof(tail->panel_name[0].name),
|
||||
tail->panel_name[panel_type].name);
|
||||
|
||||
if (i915->display.vbt.version >= 188) {
|
||||
panel->vbt.seamless_drrs_min_refresh_rate =
|
||||
tail->seamless_drrs_min_refresh_rate[panel_type];
|
||||
drm_dbg_kms(&i915->drm,
|
||||
@ -904,7 +928,7 @@ parse_generic_dtd(struct drm_i915_private *i915,
|
||||
* first on VBT >= 229, but still fall back to trying the old LFP
|
||||
* block if that fails.
|
||||
*/
|
||||
if (i915->vbt.version < 229)
|
||||
if (i915->display.vbt.version < 229)
|
||||
return;
|
||||
|
||||
generic_dtd = find_section(i915, BDB_GENERIC_DTD);
|
||||
@ -1008,12 +1032,12 @@ parse_lfp_backlight(struct drm_i915_private *i915,
|
||||
}
|
||||
|
||||
panel->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI;
|
||||
if (i915->vbt.version >= 191) {
|
||||
if (i915->display.vbt.version >= 191) {
|
||||
size_t exp_size;
|
||||
|
||||
if (i915->vbt.version >= 236)
|
||||
if (i915->display.vbt.version >= 236)
|
||||
exp_size = sizeof(struct bdb_lfp_backlight_data);
|
||||
else if (i915->vbt.version >= 234)
|
||||
else if (i915->display.vbt.version >= 234)
|
||||
exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234;
|
||||
else
|
||||
exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191;
|
||||
@ -1030,14 +1054,14 @@ parse_lfp_backlight(struct drm_i915_private *i915,
|
||||
panel->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
|
||||
panel->vbt.backlight.active_low_pwm = entry->active_low_pwm;
|
||||
|
||||
if (i915->vbt.version >= 234) {
|
||||
if (i915->display.vbt.version >= 234) {
|
||||
u16 min_level;
|
||||
bool scale;
|
||||
|
||||
level = backlight_data->brightness_level[panel_type].level;
|
||||
min_level = backlight_data->brightness_min_level[panel_type].level;
|
||||
|
||||
if (i915->vbt.version >= 236)
|
||||
if (i915->display.vbt.version >= 236)
|
||||
scale = backlight_data->brightness_precision_bits[panel_type] == 16;
|
||||
else
|
||||
scale = level > 255;
|
||||
@ -1134,37 +1158,37 @@ parse_general_features(struct drm_i915_private *i915)
|
||||
if (!general)
|
||||
return;
|
||||
|
||||
i915->vbt.int_tv_support = general->int_tv_support;
|
||||
i915->display.vbt.int_tv_support = general->int_tv_support;
|
||||
/* int_crt_support can't be trusted on earlier platforms */
|
||||
if (i915->vbt.version >= 155 &&
|
||||
if (i915->display.vbt.version >= 155 &&
|
||||
(HAS_DDI(i915) || IS_VALLEYVIEW(i915)))
|
||||
i915->vbt.int_crt_support = general->int_crt_support;
|
||||
i915->vbt.lvds_use_ssc = general->enable_ssc;
|
||||
i915->vbt.lvds_ssc_freq =
|
||||
i915->display.vbt.int_crt_support = general->int_crt_support;
|
||||
i915->display.vbt.lvds_use_ssc = general->enable_ssc;
|
||||
i915->display.vbt.lvds_ssc_freq =
|
||||
intel_bios_ssc_frequency(i915, general->ssc_freq);
|
||||
i915->vbt.display_clock_mode = general->display_clock_mode;
|
||||
i915->vbt.fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted;
|
||||
if (i915->vbt.version >= 181) {
|
||||
i915->vbt.orientation = general->rotate_180 ?
|
||||
i915->display.vbt.display_clock_mode = general->display_clock_mode;
|
||||
i915->display.vbt.fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted;
|
||||
if (i915->display.vbt.version >= 181) {
|
||||
i915->display.vbt.orientation = general->rotate_180 ?
|
||||
DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP :
|
||||
DRM_MODE_PANEL_ORIENTATION_NORMAL;
|
||||
} else {
|
||||
i915->vbt.orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
|
||||
i915->display.vbt.orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
|
||||
}
|
||||
|
||||
if (i915->vbt.version >= 249 && general->afc_startup_config) {
|
||||
i915->vbt.override_afc_startup = true;
|
||||
i915->vbt.override_afc_startup_val = general->afc_startup_config == 0x1 ? 0x0 : 0x7;
|
||||
if (i915->display.vbt.version >= 249 && general->afc_startup_config) {
|
||||
i915->display.vbt.override_afc_startup = true;
|
||||
i915->display.vbt.override_afc_startup_val = general->afc_startup_config == 0x1 ? 0x0 : 0x7;
|
||||
}
|
||||
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d fdi_rx_polarity_inverted %d\n",
|
||||
i915->vbt.int_tv_support,
|
||||
i915->vbt.int_crt_support,
|
||||
i915->vbt.lvds_use_ssc,
|
||||
i915->vbt.lvds_ssc_freq,
|
||||
i915->vbt.display_clock_mode,
|
||||
i915->vbt.fdi_rx_polarity_inverted);
|
||||
i915->display.vbt.int_tv_support,
|
||||
i915->display.vbt.int_crt_support,
|
||||
i915->display.vbt.lvds_use_ssc,
|
||||
i915->display.vbt.lvds_ssc_freq,
|
||||
i915->display.vbt.display_clock_mode,
|
||||
i915->display.vbt.fdi_rx_polarity_inverted);
|
||||
}
|
||||
|
||||
static const struct child_device_config *
|
||||
@ -1190,7 +1214,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *i915)
|
||||
return;
|
||||
}
|
||||
|
||||
list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
|
||||
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node) {
|
||||
child = &devdata->child;
|
||||
|
||||
if (child->slave_addr != SLAVE_ADDR1 &&
|
||||
@ -1214,7 +1238,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *i915)
|
||||
child->slave_addr,
|
||||
(child->dvo_port == DEVICE_PORT_DVOB) ?
|
||||
"SDVOB" : "SDVOC");
|
||||
mapping = &i915->vbt.sdvo_mappings[child->dvo_port - 1];
|
||||
mapping = &i915->display.vbt.sdvo_mappings[child->dvo_port - 1];
|
||||
if (!mapping->initialized) {
|
||||
mapping->dvo_port = child->dvo_port;
|
||||
mapping->slave_addr = child->slave_addr;
|
||||
@ -1265,7 +1289,7 @@ parse_driver_features(struct drm_i915_private *i915)
|
||||
* interpretation, but real world VBTs seem to.
|
||||
*/
|
||||
if (driver->lvds_config != BDB_DRIVER_FEATURE_INT_LVDS)
|
||||
i915->vbt.int_lvds_support = 0;
|
||||
i915->display.vbt.int_lvds_support = 0;
|
||||
} else {
|
||||
/*
|
||||
* FIXME it's not clear which BDB version has the LVDS config
|
||||
@ -1278,10 +1302,10 @@ parse_driver_features(struct drm_i915_private *i915)
|
||||
* in the wild with the bits correctly populated. Version
|
||||
* 108 (on i85x) does not have the bits correctly populated.
|
||||
*/
|
||||
if (i915->vbt.version >= 134 &&
|
||||
if (i915->display.vbt.version >= 134 &&
|
||||
driver->lvds_config != BDB_DRIVER_FEATURE_INT_LVDS &&
|
||||
driver->lvds_config != BDB_DRIVER_FEATURE_INT_SDVO_LVDS)
|
||||
i915->vbt.int_lvds_support = 0;
|
||||
i915->display.vbt.int_lvds_support = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1295,7 +1319,7 @@ parse_panel_driver_features(struct drm_i915_private *i915,
|
||||
if (!driver)
|
||||
return;
|
||||
|
||||
if (i915->vbt.version < 228) {
|
||||
if (i915->display.vbt.version < 228) {
|
||||
drm_dbg_kms(&i915->drm, "DRRS State Enabled:%d\n",
|
||||
driver->drrs_enabled);
|
||||
/*
|
||||
@ -1328,7 +1352,7 @@ parse_power_conservation_features(struct drm_i915_private *i915,
|
||||
|
||||
panel->vbt.vrr = true; /* matches Windows behaviour */
|
||||
|
||||
if (i915->vbt.version < 228)
|
||||
if (i915->display.vbt.version < 228)
|
||||
return;
|
||||
|
||||
power = find_section(i915, BDB_LFP_POWER);
|
||||
@ -1354,10 +1378,10 @@ parse_power_conservation_features(struct drm_i915_private *i915,
|
||||
panel->vbt.drrs_type = DRRS_TYPE_NONE;
|
||||
}
|
||||
|
||||
if (i915->vbt.version >= 232)
|
||||
if (i915->display.vbt.version >= 232)
|
||||
panel->vbt.edp.hobl = panel_bool(power->hobl, panel_type);
|
||||
|
||||
if (i915->vbt.version >= 233)
|
||||
if (i915->display.vbt.version >= 233)
|
||||
panel->vbt.vrr = panel_bool(power->vrr_feature_enabled,
|
||||
panel_type);
|
||||
}
|
||||
@ -1393,7 +1417,7 @@ parse_edp(struct drm_i915_private *i915,
|
||||
|
||||
panel->vbt.edp.pps = *edp_pps;
|
||||
|
||||
if (i915->vbt.version >= 224) {
|
||||
if (i915->display.vbt.version >= 224) {
|
||||
panel->vbt.edp.rate =
|
||||
edp->edp_fast_link_training_rate[panel_type] * 20;
|
||||
} else {
|
||||
@ -1472,7 +1496,7 @@ parse_edp(struct drm_i915_private *i915,
|
||||
break;
|
||||
}
|
||||
|
||||
if (i915->vbt.version >= 173) {
|
||||
if (i915->display.vbt.version >= 173) {
|
||||
u8 vswing;
|
||||
|
||||
/* Don't read from VBT if module parameter has valid value*/
|
||||
@ -1488,7 +1512,7 @@ parse_edp(struct drm_i915_private *i915,
|
||||
panel->vbt.edp.drrs_msa_timing_delay =
|
||||
panel_bits(edp->sdrrs_msa_timing_delay, panel_type, 2);
|
||||
|
||||
if (i915->vbt.version >= 244)
|
||||
if (i915->display.vbt.version >= 244)
|
||||
panel->vbt.edp.max_link_rate =
|
||||
edp->edp_max_port_link_rate[panel_type] * 20;
|
||||
}
|
||||
@ -1520,7 +1544,7 @@ parse_psr(struct drm_i915_private *i915,
|
||||
* New psr options 0=500us, 1=100us, 2=2500us, 3=0us
|
||||
* Old decimal value is wake up time in multiples of 100 us.
|
||||
*/
|
||||
if (i915->vbt.version >= 205 &&
|
||||
if (i915->display.vbt.version >= 205 &&
|
||||
(DISPLAY_VER(i915) >= 9 && !IS_BROXTON(i915))) {
|
||||
switch (psr_table->tp1_wakeup_time) {
|
||||
case 0:
|
||||
@ -1566,7 +1590,7 @@ parse_psr(struct drm_i915_private *i915,
|
||||
panel->vbt.psr.tp2_tp3_wakeup_time_us = psr_table->tp2_tp3_wakeup_time * 100;
|
||||
}
|
||||
|
||||
if (i915->vbt.version >= 226) {
|
||||
if (i915->display.vbt.version >= 226) {
|
||||
u32 wakeup_time = psr->psr2_tp2_tp3_wakeup_time;
|
||||
|
||||
wakeup_time = panel_bits(wakeup_time, panel_type, 2);
|
||||
@ -1598,7 +1622,7 @@ static void parse_dsi_backlight_ports(struct drm_i915_private *i915,
|
||||
{
|
||||
enum port port_bc = DISPLAY_VER(i915) >= 11 ? PORT_B : PORT_C;
|
||||
|
||||
if (!panel->vbt.dsi.config->dual_link || i915->vbt.version < 197) {
|
||||
if (!panel->vbt.dsi.config->dual_link || i915->display.vbt.version < 197) {
|
||||
panel->vbt.dsi.bl_ports = BIT(port);
|
||||
if (panel->vbt.dsi.config->cabc_supported)
|
||||
panel->vbt.dsi.cabc_ports = BIT(port);
|
||||
@ -2053,7 +2077,7 @@ parse_compression_parameters(struct drm_i915_private *i915)
|
||||
u16 block_size;
|
||||
int index;
|
||||
|
||||
if (i915->vbt.version < 198)
|
||||
if (i915->display.vbt.version < 198)
|
||||
return;
|
||||
|
||||
params = find_section(i915, BDB_COMPRESSION_PARAMETERS);
|
||||
@ -2073,7 +2097,7 @@ parse_compression_parameters(struct drm_i915_private *i915)
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
|
||||
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node) {
|
||||
child = &devdata->child;
|
||||
|
||||
if (!child->compression_enable)
|
||||
@ -2207,7 +2231,7 @@ static enum port get_port_by_ddc_pin(struct drm_i915_private *i915, u8 ddc_pin)
|
||||
return PORT_NONE;
|
||||
|
||||
for_each_port(port) {
|
||||
devdata = i915->vbt.ports[port];
|
||||
devdata = i915->display.vbt.ports[port];
|
||||
|
||||
if (devdata && ddc_pin == devdata->child.ddc_pin)
|
||||
return port;
|
||||
@ -2256,7 +2280,7 @@ static void sanitize_ddc_pin(struct intel_bios_encoder_data *devdata,
|
||||
* there are real machines (eg. Asrock B250M-HDV) where VBT has both
|
||||
* port A and port E with the same AUX ch and we must pick port E :(
|
||||
*/
|
||||
child = &i915->vbt.ports[p]->child;
|
||||
child = &i915->display.vbt.ports[p]->child;
|
||||
|
||||
child->device_type &= ~DEVICE_TYPE_TMDS_DVI_SIGNALING;
|
||||
child->device_type |= DEVICE_TYPE_NOT_HDMI_OUTPUT;
|
||||
@ -2273,7 +2297,7 @@ static enum port get_port_by_aux_ch(struct drm_i915_private *i915, u8 aux_ch)
|
||||
return PORT_NONE;
|
||||
|
||||
for_each_port(port) {
|
||||
devdata = i915->vbt.ports[port];
|
||||
devdata = i915->display.vbt.ports[port];
|
||||
|
||||
if (devdata && aux_ch == devdata->child.aux_channel)
|
||||
return port;
|
||||
@ -2308,7 +2332,7 @@ static void sanitize_aux_ch(struct intel_bios_encoder_data *devdata,
|
||||
* there are real machines (eg. Asrock B250M-HDV) where VBT has both
|
||||
* port A and port E with the same AUX ch and we must pick port E :(
|
||||
*/
|
||||
child = &i915->vbt.ports[p]->child;
|
||||
child = &i915->display.vbt.ports[p]->child;
|
||||
|
||||
child->device_type &= ~DEVICE_TYPE_DISPLAYPORT_OUTPUT;
|
||||
child->aux_channel = 0;
|
||||
@ -2482,15 +2506,23 @@ static int parse_bdb_216_dp_max_link_rate(const int vbt_max_link_rate)
|
||||
|
||||
static int _intel_bios_dp_max_link_rate(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
if (!devdata || devdata->i915->vbt.version < 216)
|
||||
if (!devdata || devdata->i915->display.vbt.version < 216)
|
||||
return 0;
|
||||
|
||||
if (devdata->i915->vbt.version >= 230)
|
||||
if (devdata->i915->display.vbt.version >= 230)
|
||||
return parse_bdb_230_dp_max_link_rate(devdata->child.dp_max_link_rate);
|
||||
else
|
||||
return parse_bdb_216_dp_max_link_rate(devdata->child.dp_max_link_rate);
|
||||
}
|
||||
|
||||
static int _intel_bios_dp_max_lane_count(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
if (!devdata || devdata->i915->display.vbt.version < 244)
|
||||
return 0;
|
||||
|
||||
return devdata->child.dp_max_lane_count + 1;
|
||||
}
|
||||
|
||||
static void sanitize_device_type(struct intel_bios_encoder_data *devdata,
|
||||
enum port port)
|
||||
{
|
||||
@ -2546,7 +2578,7 @@ intel_bios_encoder_supports_edp(const struct intel_bios_encoder_data *devdata)
|
||||
|
||||
static int _intel_bios_hdmi_level_shift(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
if (!devdata || devdata->i915->vbt.version < 158)
|
||||
if (!devdata || devdata->i915->display.vbt.version < 158)
|
||||
return -1;
|
||||
|
||||
return devdata->child.hdmi_level_shifter_value;
|
||||
@ -2554,7 +2586,7 @@ static int _intel_bios_hdmi_level_shift(const struct intel_bios_encoder_data *de
|
||||
|
||||
static int _intel_bios_max_tmds_clock(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
if (!devdata || devdata->i915->vbt.version < 204)
|
||||
if (!devdata || devdata->i915->display.vbt.version < 204)
|
||||
return 0;
|
||||
|
||||
switch (devdata->child.hdmi_max_data_rate) {
|
||||
@ -2663,7 +2695,7 @@ static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
|
||||
return;
|
||||
}
|
||||
|
||||
if (i915->vbt.ports[port]) {
|
||||
if (i915->display.vbt.ports[port]) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"More than one child device for port %c in VBT, using the first.\n",
|
||||
port_name(port));
|
||||
@ -2678,7 +2710,7 @@ static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
|
||||
if (intel_bios_encoder_supports_dp(devdata))
|
||||
sanitize_aux_ch(devdata, port);
|
||||
|
||||
i915->vbt.ports[port] = devdata;
|
||||
i915->display.vbt.ports[port] = devdata;
|
||||
}
|
||||
|
||||
static bool has_ddi_port_info(struct drm_i915_private *i915)
|
||||
@ -2694,12 +2726,12 @@ static void parse_ddi_ports(struct drm_i915_private *i915)
|
||||
if (!has_ddi_port_info(i915))
|
||||
return;
|
||||
|
||||
list_for_each_entry(devdata, &i915->vbt.display_devices, node)
|
||||
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node)
|
||||
parse_ddi_port(devdata);
|
||||
|
||||
for_each_port(port) {
|
||||
if (i915->vbt.ports[port])
|
||||
print_ddi_port(i915->vbt.ports[port], port);
|
||||
if (i915->display.vbt.ports[port])
|
||||
print_ddi_port(i915->display.vbt.ports[port], port);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2732,33 +2764,33 @@ parse_general_definitions(struct drm_i915_private *i915)
|
||||
bus_pin = defs->crt_ddc_gmbus_pin;
|
||||
drm_dbg_kms(&i915->drm, "crt_ddc_bus_pin: %d\n", bus_pin);
|
||||
if (intel_gmbus_is_valid_pin(i915, bus_pin))
|
||||
i915->vbt.crt_ddc_pin = bus_pin;
|
||||
i915->display.vbt.crt_ddc_pin = bus_pin;
|
||||
|
||||
if (i915->vbt.version < 106) {
|
||||
if (i915->display.vbt.version < 106) {
|
||||
expected_size = 22;
|
||||
} else if (i915->vbt.version < 111) {
|
||||
} else if (i915->display.vbt.version < 111) {
|
||||
expected_size = 27;
|
||||
} else if (i915->vbt.version < 195) {
|
||||
} else if (i915->display.vbt.version < 195) {
|
||||
expected_size = LEGACY_CHILD_DEVICE_CONFIG_SIZE;
|
||||
} else if (i915->vbt.version == 195) {
|
||||
} else if (i915->display.vbt.version == 195) {
|
||||
expected_size = 37;
|
||||
} else if (i915->vbt.version <= 215) {
|
||||
} else if (i915->display.vbt.version <= 215) {
|
||||
expected_size = 38;
|
||||
} else if (i915->vbt.version <= 237) {
|
||||
} else if (i915->display.vbt.version <= 237) {
|
||||
expected_size = 39;
|
||||
} else {
|
||||
expected_size = sizeof(*child);
|
||||
BUILD_BUG_ON(sizeof(*child) < 39);
|
||||
drm_dbg(&i915->drm,
|
||||
"Expected child device config size for VBT version %u not known; assuming %u\n",
|
||||
i915->vbt.version, expected_size);
|
||||
i915->display.vbt.version, expected_size);
|
||||
}
|
||||
|
||||
/* Flag an error for unexpected size, but continue anyway. */
|
||||
if (defs->child_dev_size != expected_size)
|
||||
drm_err(&i915->drm,
|
||||
"Unexpected child device config size %u (expected %u for VBT version %u)\n",
|
||||
defs->child_dev_size, expected_size, i915->vbt.version);
|
||||
defs->child_dev_size, expected_size, i915->display.vbt.version);
|
||||
|
||||
/* The legacy sized child device config is the minimum we need. */
|
||||
if (defs->child_dev_size < LEGACY_CHILD_DEVICE_CONFIG_SIZE) {
|
||||
@ -2794,10 +2826,10 @@ parse_general_definitions(struct drm_i915_private *i915)
|
||||
memcpy(&devdata->child, child,
|
||||
min_t(size_t, defs->child_dev_size, sizeof(*child)));
|
||||
|
||||
list_add_tail(&devdata->node, &i915->vbt.display_devices);
|
||||
list_add_tail(&devdata->node, &i915->display.vbt.display_devices);
|
||||
}
|
||||
|
||||
if (list_empty(&i915->vbt.display_devices))
|
||||
if (list_empty(&i915->display.vbt.display_devices))
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"no child dev is parsed from VBT\n");
|
||||
}
|
||||
@ -2806,25 +2838,25 @@ parse_general_definitions(struct drm_i915_private *i915)
|
||||
static void
|
||||
init_vbt_defaults(struct drm_i915_private *i915)
|
||||
{
|
||||
i915->vbt.crt_ddc_pin = GMBUS_PIN_VGADDC;
|
||||
i915->display.vbt.crt_ddc_pin = GMBUS_PIN_VGADDC;
|
||||
|
||||
/* general features */
|
||||
i915->vbt.int_tv_support = 1;
|
||||
i915->vbt.int_crt_support = 1;
|
||||
i915->display.vbt.int_tv_support = 1;
|
||||
i915->display.vbt.int_crt_support = 1;
|
||||
|
||||
/* driver features */
|
||||
i915->vbt.int_lvds_support = 1;
|
||||
i915->display.vbt.int_lvds_support = 1;
|
||||
|
||||
/* Default to using SSC */
|
||||
i915->vbt.lvds_use_ssc = 1;
|
||||
i915->display.vbt.lvds_use_ssc = 1;
|
||||
/*
|
||||
* Core/SandyBridge/IvyBridge use alternative (120MHz) reference
|
||||
* clock for LVDS.
|
||||
*/
|
||||
i915->vbt.lvds_ssc_freq = intel_bios_ssc_frequency(i915,
|
||||
!HAS_PCH_SPLIT(i915));
|
||||
i915->display.vbt.lvds_ssc_freq = intel_bios_ssc_frequency(i915,
|
||||
!HAS_PCH_SPLIT(i915));
|
||||
drm_dbg_kms(&i915->drm, "Set default to SSC at %d kHz\n",
|
||||
i915->vbt.lvds_ssc_freq);
|
||||
i915->display.vbt.lvds_ssc_freq);
|
||||
}
|
||||
|
||||
/* Common defaults which may be overridden by VBT. */
|
||||
@ -2885,7 +2917,7 @@ init_vbt_missing_defaults(struct drm_i915_private *i915)
|
||||
if (port == PORT_A)
|
||||
child->device_type |= DEVICE_TYPE_INTERNAL_CONNECTOR;
|
||||
|
||||
list_add_tail(&devdata->node, &i915->vbt.display_devices);
|
||||
list_add_tail(&devdata->node, &i915->display.vbt.display_devices);
|
||||
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"Generating default VBT child device with type 0x04%x on port %c\n",
|
||||
@ -2893,7 +2925,7 @@ init_vbt_missing_defaults(struct drm_i915_private *i915)
|
||||
}
|
||||
|
||||
/* Bypass some minimum baseline VBT version checks */
|
||||
i915->vbt.version = 155;
|
||||
i915->display.vbt.version = 155;
|
||||
}
|
||||
|
||||
static const struct bdb_header *get_bdb_header(const struct vbt_header *vbt)
|
||||
@ -3080,12 +3112,12 @@ err_unmap_oprom:
|
||||
*/
|
||||
void intel_bios_init(struct drm_i915_private *i915)
|
||||
{
|
||||
const struct vbt_header *vbt = i915->opregion.vbt;
|
||||
const struct vbt_header *vbt = i915->display.opregion.vbt;
|
||||
struct vbt_header *oprom_vbt = NULL;
|
||||
const struct bdb_header *bdb;
|
||||
|
||||
INIT_LIST_HEAD(&i915->vbt.display_devices);
|
||||
INIT_LIST_HEAD(&i915->vbt.bdb_blocks);
|
||||
INIT_LIST_HEAD(&i915->display.vbt.display_devices);
|
||||
INIT_LIST_HEAD(&i915->display.vbt.bdb_blocks);
|
||||
|
||||
if (!HAS_DISPLAY(i915)) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
@ -3113,11 +3145,11 @@ void intel_bios_init(struct drm_i915_private *i915)
|
||||
goto out;
|
||||
|
||||
bdb = get_bdb_header(vbt);
|
||||
i915->vbt.version = bdb->version;
|
||||
i915->display.vbt.version = bdb->version;
|
||||
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"VBT signature \"%.*s\", BDB version %d\n",
|
||||
(int)sizeof(vbt->signature), vbt->signature, i915->vbt.version);
|
||||
(int)sizeof(vbt->signature), vbt->signature, i915->display.vbt.version);
|
||||
|
||||
init_bdb_blocks(i915, bdb);
|
||||
|
||||
@ -3174,13 +3206,13 @@ void intel_bios_driver_remove(struct drm_i915_private *i915)
|
||||
struct intel_bios_encoder_data *devdata, *nd;
|
||||
struct bdb_block_entry *entry, *ne;
|
||||
|
||||
list_for_each_entry_safe(devdata, nd, &i915->vbt.display_devices, node) {
|
||||
list_for_each_entry_safe(devdata, nd, &i915->display.vbt.display_devices, node) {
|
||||
list_del(&devdata->node);
|
||||
kfree(devdata->dsc);
|
||||
kfree(devdata);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(entry, ne, &i915->vbt.bdb_blocks, node) {
|
||||
list_for_each_entry_safe(entry, ne, &i915->display.vbt.bdb_blocks, node) {
|
||||
list_del(&entry->node);
|
||||
kfree(entry);
|
||||
}
|
||||
@ -3214,13 +3246,13 @@ bool intel_bios_is_tv_present(struct drm_i915_private *i915)
|
||||
const struct intel_bios_encoder_data *devdata;
|
||||
const struct child_device_config *child;
|
||||
|
||||
if (!i915->vbt.int_tv_support)
|
||||
if (!i915->display.vbt.int_tv_support)
|
||||
return false;
|
||||
|
||||
if (list_empty(&i915->vbt.display_devices))
|
||||
if (list_empty(&i915->display.vbt.display_devices))
|
||||
return true;
|
||||
|
||||
list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
|
||||
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node) {
|
||||
child = &devdata->child;
|
||||
|
||||
/*
|
||||
@ -3257,10 +3289,10 @@ bool intel_bios_is_lvds_present(struct drm_i915_private *i915, u8 *i2c_pin)
|
||||
const struct intel_bios_encoder_data *devdata;
|
||||
const struct child_device_config *child;
|
||||
|
||||
if (list_empty(&i915->vbt.display_devices))
|
||||
if (list_empty(&i915->display.vbt.display_devices))
|
||||
return true;
|
||||
|
||||
list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
|
||||
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node) {
|
||||
child = &devdata->child;
|
||||
|
||||
/* If the device type is not LFP, continue.
|
||||
@ -3287,7 +3319,7 @@ bool intel_bios_is_lvds_present(struct drm_i915_private *i915, u8 *i2c_pin)
|
||||
* additional data. Trust that if the VBT was written into
|
||||
* the OpRegion then they have validated the LVDS's existence.
|
||||
*/
|
||||
if (i915->opregion.vbt)
|
||||
if (i915->display.opregion.vbt)
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3306,7 +3338,7 @@ bool intel_bios_is_port_present(struct drm_i915_private *i915, enum port port)
|
||||
if (WARN_ON(!has_ddi_port_info(i915)))
|
||||
return true;
|
||||
|
||||
return i915->vbt.ports[port];
|
||||
return i915->display.vbt.ports[port];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3366,7 +3398,7 @@ bool intel_bios_is_dsi_present(struct drm_i915_private *i915,
|
||||
const struct child_device_config *child;
|
||||
u8 dvo_port;
|
||||
|
||||
list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
|
||||
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node) {
|
||||
child = &devdata->child;
|
||||
|
||||
if (!(child->device_type & DEVICE_TYPE_MIPI_OUTPUT))
|
||||
@ -3465,7 +3497,7 @@ bool intel_bios_get_dsc_params(struct intel_encoder *encoder,
|
||||
const struct intel_bios_encoder_data *devdata;
|
||||
const struct child_device_config *child;
|
||||
|
||||
list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
|
||||
list_for_each_entry(devdata, &i915->display.vbt.display_devices, node) {
|
||||
child = &devdata->child;
|
||||
|
||||
if (!(child->device_type & DEVICE_TYPE_MIPI_OUTPUT))
|
||||
@ -3496,7 +3528,7 @@ bool
|
||||
intel_bios_is_port_hpd_inverted(const struct drm_i915_private *i915,
|
||||
enum port port)
|
||||
{
|
||||
const struct intel_bios_encoder_data *devdata = i915->vbt.ports[port];
|
||||
const struct intel_bios_encoder_data *devdata = i915->display.vbt.ports[port];
|
||||
|
||||
if (drm_WARN_ON_ONCE(&i915->drm,
|
||||
!IS_GEMINILAKE(i915) && !IS_BROXTON(i915)))
|
||||
@ -3516,7 +3548,7 @@ bool
|
||||
intel_bios_is_lspcon_present(const struct drm_i915_private *i915,
|
||||
enum port port)
|
||||
{
|
||||
const struct intel_bios_encoder_data *devdata = i915->vbt.ports[port];
|
||||
const struct intel_bios_encoder_data *devdata = i915->display.vbt.ports[port];
|
||||
|
||||
return HAS_LSPCON(i915) && devdata && devdata->child.lspcon;
|
||||
}
|
||||
@ -3532,7 +3564,7 @@ bool
|
||||
intel_bios_is_lane_reversal_needed(const struct drm_i915_private *i915,
|
||||
enum port port)
|
||||
{
|
||||
const struct intel_bios_encoder_data *devdata = i915->vbt.ports[port];
|
||||
const struct intel_bios_encoder_data *devdata = i915->display.vbt.ports[port];
|
||||
|
||||
return devdata && devdata->child.lane_reversal;
|
||||
}
|
||||
@ -3540,7 +3572,7 @@ intel_bios_is_lane_reversal_needed(const struct drm_i915_private *i915,
|
||||
enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *i915,
|
||||
enum port port)
|
||||
{
|
||||
const struct intel_bios_encoder_data *devdata = i915->vbt.ports[port];
|
||||
const struct intel_bios_encoder_data *devdata = i915->display.vbt.ports[port];
|
||||
enum aux_ch aux_ch;
|
||||
|
||||
if (!devdata || !devdata->child.aux_channel) {
|
||||
@ -3634,7 +3666,7 @@ enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *i915,
|
||||
int intel_bios_max_tmds_clock(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
const struct intel_bios_encoder_data *devdata = i915->vbt.ports[encoder->port];
|
||||
const struct intel_bios_encoder_data *devdata = i915->display.vbt.ports[encoder->port];
|
||||
|
||||
return _intel_bios_max_tmds_clock(devdata);
|
||||
}
|
||||
@ -3643,14 +3675,14 @@ int intel_bios_max_tmds_clock(struct intel_encoder *encoder)
|
||||
int intel_bios_hdmi_level_shift(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
const struct intel_bios_encoder_data *devdata = i915->vbt.ports[encoder->port];
|
||||
const struct intel_bios_encoder_data *devdata = i915->display.vbt.ports[encoder->port];
|
||||
|
||||
return _intel_bios_hdmi_level_shift(devdata);
|
||||
}
|
||||
|
||||
int intel_bios_encoder_dp_boost_level(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
if (!devdata || devdata->i915->vbt.version < 196 || !devdata->child.iboost)
|
||||
if (!devdata || devdata->i915->display.vbt.version < 196 || !devdata->child.iboost)
|
||||
return 0;
|
||||
|
||||
return translate_iboost(devdata->child.dp_iboost_level);
|
||||
@ -3658,7 +3690,7 @@ int intel_bios_encoder_dp_boost_level(const struct intel_bios_encoder_data *devd
|
||||
|
||||
int intel_bios_encoder_hdmi_boost_level(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
if (!devdata || devdata->i915->vbt.version < 196 || !devdata->child.iboost)
|
||||
if (!devdata || devdata->i915->display.vbt.version < 196 || !devdata->child.iboost)
|
||||
return 0;
|
||||
|
||||
return translate_iboost(devdata->child.hdmi_iboost_level);
|
||||
@ -3667,15 +3699,23 @@ int intel_bios_encoder_hdmi_boost_level(const struct intel_bios_encoder_data *de
|
||||
int intel_bios_dp_max_link_rate(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
const struct intel_bios_encoder_data *devdata = i915->vbt.ports[encoder->port];
|
||||
const struct intel_bios_encoder_data *devdata = i915->display.vbt.ports[encoder->port];
|
||||
|
||||
return _intel_bios_dp_max_link_rate(devdata);
|
||||
}
|
||||
|
||||
int intel_bios_dp_max_lane_count(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
const struct intel_bios_encoder_data *devdata = i915->display.vbt.ports[encoder->port];
|
||||
|
||||
return _intel_bios_dp_max_lane_count(devdata);
|
||||
}
|
||||
|
||||
int intel_bios_alternate_ddc_pin(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
const struct intel_bios_encoder_data *devdata = i915->vbt.ports[encoder->port];
|
||||
const struct intel_bios_encoder_data *devdata = i915->display.vbt.ports[encoder->port];
|
||||
|
||||
if (!devdata || !devdata->child.ddc_pin)
|
||||
return 0;
|
||||
@ -3685,16 +3725,16 @@ int intel_bios_alternate_ddc_pin(struct intel_encoder *encoder)
|
||||
|
||||
bool intel_bios_encoder_supports_typec_usb(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
return devdata->i915->vbt.version >= 195 && devdata->child.dp_usb_type_c;
|
||||
return devdata->i915->display.vbt.version >= 195 && devdata->child.dp_usb_type_c;
|
||||
}
|
||||
|
||||
bool intel_bios_encoder_supports_tbt(const struct intel_bios_encoder_data *devdata)
|
||||
{
|
||||
return devdata->i915->vbt.version >= 209 && devdata->child.tbt;
|
||||
return devdata->i915->display.vbt.version >= 209 && devdata->child.tbt;
|
||||
}
|
||||
|
||||
const struct intel_bios_encoder_data *
|
||||
intel_bios_encoder_data_lookup(struct drm_i915_private *i915, enum port port)
|
||||
{
|
||||
return i915->vbt.ports[port];
|
||||
return i915->display.vbt.ports[port];
|
||||
}
|
||||
|
@ -258,6 +258,7 @@ bool intel_bios_get_dsc_params(struct intel_encoder *encoder,
|
||||
int intel_bios_max_tmds_clock(struct intel_encoder *encoder);
|
||||
int intel_bios_hdmi_level_shift(struct intel_encoder *encoder);
|
||||
int intel_bios_dp_max_link_rate(struct intel_encoder *encoder);
|
||||
int intel_bios_dp_max_lane_count(struct intel_encoder *encoder);
|
||||
int intel_bios_alternate_ddc_pin(struct intel_encoder *encoder);
|
||||
bool intel_bios_port_supports_typec_usb(struct drm_i915_private *i915, enum port port);
|
||||
bool intel_bios_port_supports_tbt(struct drm_i915_private *i915, enum port port);
|
||||
|
@ -5,15 +5,17 @@
|
||||
|
||||
#include <drm/drm_atomic_state_helper.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_atomic.h"
|
||||
#include "intel_bw.h"
|
||||
#include "intel_cdclk.h"
|
||||
#include "intel_display_core.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "skl_watermark.h"
|
||||
#include "intel_mchbar_regs.h"
|
||||
#include "intel_pcode.h"
|
||||
#include "intel_pm.h"
|
||||
|
||||
/* Parameters for Qclk Geyserville (QGV) */
|
||||
struct intel_qgv_point {
|
||||
@ -137,6 +139,42 @@ int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtl_read_qgv_point_info(struct drm_i915_private *dev_priv,
|
||||
struct intel_qgv_point *sp, int point)
|
||||
{
|
||||
u32 val, val2;
|
||||
u16 dclk;
|
||||
|
||||
val = intel_uncore_read(&dev_priv->uncore,
|
||||
MTL_MEM_SS_INFO_QGV_POINT_LOW(point));
|
||||
val2 = intel_uncore_read(&dev_priv->uncore,
|
||||
MTL_MEM_SS_INFO_QGV_POINT_HIGH(point));
|
||||
dclk = REG_FIELD_GET(MTL_DCLK_MASK, val);
|
||||
sp->dclk = DIV_ROUND_UP((16667 * dclk), 1000);
|
||||
sp->t_rp = REG_FIELD_GET(MTL_TRP_MASK, val);
|
||||
sp->t_rcd = REG_FIELD_GET(MTL_TRCD_MASK, val);
|
||||
|
||||
sp->t_rdpre = REG_FIELD_GET(MTL_TRDPRE_MASK, val2);
|
||||
sp->t_ras = REG_FIELD_GET(MTL_TRAS_MASK, val2);
|
||||
|
||||
sp->t_rc = sp->t_rp + sp->t_ras;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_read_qgv_point_info(struct drm_i915_private *dev_priv,
|
||||
struct intel_qgv_point *sp,
|
||||
int point)
|
||||
{
|
||||
if (DISPLAY_VER(dev_priv) >= 14)
|
||||
return mtl_read_qgv_point_info(dev_priv, sp, point);
|
||||
else if (IS_DG1(dev_priv))
|
||||
return dg1_mchbar_read_qgv_point_info(dev_priv, sp, point);
|
||||
else
|
||||
return icl_pcode_read_qgv_point_info(dev_priv, sp, point);
|
||||
}
|
||||
|
||||
static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
|
||||
struct intel_qgv_info *qi,
|
||||
bool is_y_tile)
|
||||
@ -218,11 +256,7 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
|
||||
for (i = 0; i < qi->num_points; i++) {
|
||||
struct intel_qgv_point *sp = &qi->points[i];
|
||||
|
||||
if (IS_DG1(dev_priv))
|
||||
ret = dg1_mchbar_read_qgv_point_info(dev_priv, sp, i);
|
||||
else
|
||||
ret = icl_pcode_read_qgv_point_info(dev_priv, sp, i);
|
||||
|
||||
ret = intel_read_qgv_point_info(dev_priv, sp, i);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -324,7 +358,7 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
|
||||
int ipqdepth, ipqdepthpch = 16;
|
||||
int dclk_max;
|
||||
int maxdebw;
|
||||
int num_groups = ARRAY_SIZE(dev_priv->max_bw);
|
||||
int num_groups = ARRAY_SIZE(dev_priv->display.bw.max);
|
||||
int i, ret;
|
||||
|
||||
ret = icl_get_qgv_points(dev_priv, &qi, is_y_tile);
|
||||
@ -340,7 +374,7 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
|
||||
qi.deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2);
|
||||
|
||||
for (i = 0; i < num_groups; i++) {
|
||||
struct intel_bw_info *bi = &dev_priv->max_bw[i];
|
||||
struct intel_bw_info *bi = &dev_priv->display.bw.max[i];
|
||||
int clpchgroup;
|
||||
int j;
|
||||
|
||||
@ -395,7 +429,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
|
||||
int dclk_max;
|
||||
int maxdebw, peakbw;
|
||||
int clperchgroup;
|
||||
int num_groups = ARRAY_SIZE(dev_priv->max_bw);
|
||||
int num_groups = ARRAY_SIZE(dev_priv->display.bw.max);
|
||||
int i, ret;
|
||||
|
||||
ret = icl_get_qgv_points(dev_priv, &qi, is_y_tile);
|
||||
@ -431,7 +465,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
|
||||
clperchgroup = 4 * DIV_ROUND_UP(8, num_channels) * qi.deinterleave;
|
||||
|
||||
for (i = 0; i < num_groups; i++) {
|
||||
struct intel_bw_info *bi = &dev_priv->max_bw[i];
|
||||
struct intel_bw_info *bi = &dev_priv->display.bw.max[i];
|
||||
struct intel_bw_info *bi_next;
|
||||
int clpchgroup;
|
||||
int j;
|
||||
@ -439,7 +473,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
|
||||
clpchgroup = (sa->deburst * qi.deinterleave / num_channels) << i;
|
||||
|
||||
if (i < num_groups - 1) {
|
||||
bi_next = &dev_priv->max_bw[i + 1];
|
||||
bi_next = &dev_priv->display.bw.max[i + 1];
|
||||
|
||||
if (clpchgroup < clperchgroup)
|
||||
bi_next->num_planes = (ipqdepth - clpchgroup) /
|
||||
@ -500,7 +534,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
|
||||
static void dg2_get_bw_info(struct drm_i915_private *i915)
|
||||
{
|
||||
unsigned int deratedbw = IS_DG2_G11(i915) ? 38000 : 50000;
|
||||
int num_groups = ARRAY_SIZE(i915->max_bw);
|
||||
int num_groups = ARRAY_SIZE(i915->display.bw.max);
|
||||
int i;
|
||||
|
||||
/*
|
||||
@ -511,7 +545,7 @@ static void dg2_get_bw_info(struct drm_i915_private *i915)
|
||||
* whereas DG2-G11 platforms have 38 GB/s.
|
||||
*/
|
||||
for (i = 0; i < num_groups; i++) {
|
||||
struct intel_bw_info *bi = &i915->max_bw[i];
|
||||
struct intel_bw_info *bi = &i915->display.bw.max[i];
|
||||
|
||||
bi->num_planes = 1;
|
||||
/* Need only one dummy QGV point per group */
|
||||
@ -532,9 +566,9 @@ static unsigned int icl_max_bw(struct drm_i915_private *dev_priv,
|
||||
*/
|
||||
num_planes = max(1, num_planes);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev_priv->max_bw); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(dev_priv->display.bw.max); i++) {
|
||||
const struct intel_bw_info *bi =
|
||||
&dev_priv->max_bw[i];
|
||||
&dev_priv->display.bw.max[i];
|
||||
|
||||
/*
|
||||
* Pcode will not expose all QGV points when
|
||||
@ -560,9 +594,9 @@ static unsigned int tgl_max_bw(struct drm_i915_private *dev_priv,
|
||||
*/
|
||||
num_planes = max(1, num_planes);
|
||||
|
||||
for (i = ARRAY_SIZE(dev_priv->max_bw) - 1; i >= 0; i--) {
|
||||
for (i = ARRAY_SIZE(dev_priv->display.bw.max) - 1; i >= 0; i--) {
|
||||
const struct intel_bw_info *bi =
|
||||
&dev_priv->max_bw[i];
|
||||
&dev_priv->display.bw.max[i];
|
||||
|
||||
/*
|
||||
* Pcode will not expose all QGV points when
|
||||
@ -575,14 +609,14 @@ static unsigned int tgl_max_bw(struct drm_i915_private *dev_priv,
|
||||
return bi->deratedbw[qgv_point];
|
||||
}
|
||||
|
||||
return dev_priv->max_bw[0].deratedbw[qgv_point];
|
||||
return dev_priv->display.bw.max[0].deratedbw[qgv_point];
|
||||
}
|
||||
|
||||
static unsigned int adl_psf_bw(struct drm_i915_private *dev_priv,
|
||||
int psf_gv_point)
|
||||
{
|
||||
const struct intel_bw_info *bi =
|
||||
&dev_priv->max_bw[0];
|
||||
&dev_priv->display.bw.max[0];
|
||||
|
||||
return bi->psf_bw[psf_gv_point];
|
||||
}
|
||||
@ -703,7 +737,7 @@ intel_atomic_get_old_bw_state(struct intel_atomic_state *state)
|
||||
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
||||
struct intel_global_state *bw_state;
|
||||
|
||||
bw_state = intel_atomic_get_old_global_obj_state(state, &dev_priv->bw_obj);
|
||||
bw_state = intel_atomic_get_old_global_obj_state(state, &dev_priv->display.bw.obj);
|
||||
|
||||
return to_intel_bw_state(bw_state);
|
||||
}
|
||||
@ -714,7 +748,7 @@ intel_atomic_get_new_bw_state(struct intel_atomic_state *state)
|
||||
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
||||
struct intel_global_state *bw_state;
|
||||
|
||||
bw_state = intel_atomic_get_new_global_obj_state(state, &dev_priv->bw_obj);
|
||||
bw_state = intel_atomic_get_new_global_obj_state(state, &dev_priv->display.bw.obj);
|
||||
|
||||
return to_intel_bw_state(bw_state);
|
||||
}
|
||||
@ -725,7 +759,7 @@ intel_atomic_get_bw_state(struct intel_atomic_state *state)
|
||||
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
||||
struct intel_global_state *bw_state;
|
||||
|
||||
bw_state = intel_atomic_get_global_obj_state(state, &dev_priv->bw_obj);
|
||||
bw_state = intel_atomic_get_global_obj_state(state, &dev_priv->display.bw.obj);
|
||||
if (IS_ERR(bw_state))
|
||||
return ERR_CAST(bw_state);
|
||||
|
||||
@ -932,8 +966,8 @@ int intel_bw_calc_min_cdclk(struct intel_atomic_state *state,
|
||||
|
||||
static u16 icl_qgv_points_mask(struct drm_i915_private *i915)
|
||||
{
|
||||
unsigned int num_psf_gv_points = i915->max_bw[0].num_psf_gv_points;
|
||||
unsigned int num_qgv_points = i915->max_bw[0].num_qgv_points;
|
||||
unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points;
|
||||
unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points;
|
||||
u16 qgv_points = 0, psf_points = 0;
|
||||
|
||||
/*
|
||||
@ -1006,8 +1040,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
|
||||
int i, ret;
|
||||
u16 qgv_points = 0, psf_points = 0;
|
||||
unsigned int max_bw_point = 0, max_bw = 0;
|
||||
unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points;
|
||||
unsigned int num_psf_gv_points = dev_priv->max_bw[0].num_psf_gv_points;
|
||||
unsigned int num_qgv_points = dev_priv->display.bw.max[0].num_qgv_points;
|
||||
unsigned int num_psf_gv_points = dev_priv->display.bw.max[0].num_psf_gv_points;
|
||||
bool changed = false;
|
||||
|
||||
/* FIXME earlier gens need some checks too */
|
||||
@ -1162,7 +1196,7 @@ int intel_bw_init(struct drm_i915_private *dev_priv)
|
||||
if (!state)
|
||||
return -ENOMEM;
|
||||
|
||||
intel_atomic_global_obj_init(dev_priv, &dev_priv->bw_obj,
|
||||
intel_atomic_global_obj_init(dev_priv, &dev_priv->display.bw.obj,
|
||||
&state->base, &intel_bw_funcs);
|
||||
|
||||
return 0;
|
||||
|
@ -548,7 +548,7 @@ static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
|
||||
else
|
||||
default_credits = PFI_CREDIT(8);
|
||||
|
||||
if (dev_priv->cdclk.hw.cdclk >= dev_priv->czclk_freq) {
|
||||
if (dev_priv->display.cdclk.hw.cdclk >= dev_priv->czclk_freq) {
|
||||
/* CHV suggested value is 31 or 63 */
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
credits = PFI_CREDIT_63;
|
||||
@ -1026,7 +1026,7 @@ static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
|
||||
if (intel_de_wait_for_set(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 5))
|
||||
drm_err(&dev_priv->drm, "DPLL0 not locked\n");
|
||||
|
||||
dev_priv->cdclk.hw.vco = vco;
|
||||
dev_priv->display.cdclk.hw.vco = vco;
|
||||
|
||||
/* We'll want to keep using the current vco from now on. */
|
||||
skl_set_preferred_cdclk_vco(dev_priv, vco);
|
||||
@ -1040,7 +1040,7 @@ static void skl_dpll0_disable(struct drm_i915_private *dev_priv)
|
||||
if (intel_de_wait_for_clear(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 1))
|
||||
drm_err(&dev_priv->drm, "Couldn't disable DPLL0\n");
|
||||
|
||||
dev_priv->cdclk.hw.vco = 0;
|
||||
dev_priv->display.cdclk.hw.vco = 0;
|
||||
}
|
||||
|
||||
static u32 skl_cdclk_freq_sel(struct drm_i915_private *dev_priv,
|
||||
@ -1049,7 +1049,7 @@ static u32 skl_cdclk_freq_sel(struct drm_i915_private *dev_priv,
|
||||
switch (cdclk) {
|
||||
default:
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
cdclk != dev_priv->cdclk.hw.bypass);
|
||||
cdclk != dev_priv->display.cdclk.hw.bypass);
|
||||
drm_WARN_ON(&dev_priv->drm, vco != 0);
|
||||
fallthrough;
|
||||
case 308571:
|
||||
@ -1098,13 +1098,13 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
|
||||
|
||||
freq_select = skl_cdclk_freq_sel(dev_priv, cdclk, vco);
|
||||
|
||||
if (dev_priv->cdclk.hw.vco != 0 &&
|
||||
dev_priv->cdclk.hw.vco != vco)
|
||||
if (dev_priv->display.cdclk.hw.vco != 0 &&
|
||||
dev_priv->display.cdclk.hw.vco != vco)
|
||||
skl_dpll0_disable(dev_priv);
|
||||
|
||||
cdclk_ctl = intel_de_read(dev_priv, CDCLK_CTL);
|
||||
|
||||
if (dev_priv->cdclk.hw.vco != vco) {
|
||||
if (dev_priv->display.cdclk.hw.vco != vco) {
|
||||
/* Wa Display #1183: skl,kbl,cfl */
|
||||
cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK);
|
||||
cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk);
|
||||
@ -1116,7 +1116,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
|
||||
intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);
|
||||
intel_de_posting_read(dev_priv, CDCLK_CTL);
|
||||
|
||||
if (dev_priv->cdclk.hw.vco != vco)
|
||||
if (dev_priv->display.cdclk.hw.vco != vco)
|
||||
skl_dpll0_enable(dev_priv, vco);
|
||||
|
||||
/* Wa Display #1183: skl,kbl,cfl */
|
||||
@ -1151,11 +1151,11 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
|
||||
goto sanitize;
|
||||
|
||||
intel_update_cdclk(dev_priv);
|
||||
intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "Current CDCLK");
|
||||
intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "Current CDCLK");
|
||||
|
||||
/* Is PLL enabled and locked ? */
|
||||
if (dev_priv->cdclk.hw.vco == 0 ||
|
||||
dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass)
|
||||
if (dev_priv->display.cdclk.hw.vco == 0 ||
|
||||
dev_priv->display.cdclk.hw.cdclk == dev_priv->display.cdclk.hw.bypass)
|
||||
goto sanitize;
|
||||
|
||||
/* DPLL okay; verify the cdclock
|
||||
@ -1166,7 +1166,7 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
|
||||
*/
|
||||
cdctl = intel_de_read(dev_priv, CDCLK_CTL);
|
||||
expected = (cdctl & CDCLK_FREQ_SEL_MASK) |
|
||||
skl_cdclk_decimal(dev_priv->cdclk.hw.cdclk);
|
||||
skl_cdclk_decimal(dev_priv->display.cdclk.hw.cdclk);
|
||||
if (cdctl == expected)
|
||||
/* All well; nothing to sanitize */
|
||||
return;
|
||||
@ -1175,9 +1175,9 @@ sanitize:
|
||||
drm_dbg_kms(&dev_priv->drm, "Sanitizing cdclk programmed by pre-os\n");
|
||||
|
||||
/* force cdclk programming */
|
||||
dev_priv->cdclk.hw.cdclk = 0;
|
||||
dev_priv->display.cdclk.hw.cdclk = 0;
|
||||
/* force full PLL disable + enable */
|
||||
dev_priv->cdclk.hw.vco = -1;
|
||||
dev_priv->display.cdclk.hw.vco = -1;
|
||||
}
|
||||
|
||||
static void skl_cdclk_init_hw(struct drm_i915_private *dev_priv)
|
||||
@ -1186,19 +1186,19 @@ static void skl_cdclk_init_hw(struct drm_i915_private *dev_priv)
|
||||
|
||||
skl_sanitize_cdclk(dev_priv);
|
||||
|
||||
if (dev_priv->cdclk.hw.cdclk != 0 &&
|
||||
dev_priv->cdclk.hw.vco != 0) {
|
||||
if (dev_priv->display.cdclk.hw.cdclk != 0 &&
|
||||
dev_priv->display.cdclk.hw.vco != 0) {
|
||||
/*
|
||||
* Use the current vco as our initial
|
||||
* guess as to what the preferred vco is.
|
||||
*/
|
||||
if (dev_priv->skl_preferred_vco_freq == 0)
|
||||
skl_set_preferred_cdclk_vco(dev_priv,
|
||||
dev_priv->cdclk.hw.vco);
|
||||
dev_priv->display.cdclk.hw.vco);
|
||||
return;
|
||||
}
|
||||
|
||||
cdclk_config = dev_priv->cdclk.hw;
|
||||
cdclk_config = dev_priv->display.cdclk.hw;
|
||||
|
||||
cdclk_config.vco = dev_priv->skl_preferred_vco_freq;
|
||||
if (cdclk_config.vco == 0)
|
||||
@ -1211,7 +1211,7 @@ static void skl_cdclk_init_hw(struct drm_i915_private *dev_priv)
|
||||
|
||||
static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_cdclk_config cdclk_config = dev_priv->cdclk.hw;
|
||||
struct intel_cdclk_config cdclk_config = dev_priv->display.cdclk.hw;
|
||||
|
||||
cdclk_config.cdclk = cdclk_config.bypass;
|
||||
cdclk_config.vco = 0;
|
||||
@ -1352,35 +1352,35 @@ static const struct intel_cdclk_vals dg2_cdclk_table[] = {
|
||||
|
||||
static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
|
||||
{
|
||||
const struct intel_cdclk_vals *table = dev_priv->cdclk.table;
|
||||
const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table;
|
||||
int i;
|
||||
|
||||
for (i = 0; table[i].refclk; i++)
|
||||
if (table[i].refclk == dev_priv->cdclk.hw.ref &&
|
||||
if (table[i].refclk == dev_priv->display.cdclk.hw.ref &&
|
||||
table[i].cdclk >= min_cdclk)
|
||||
return table[i].cdclk;
|
||||
|
||||
drm_WARN(&dev_priv->drm, 1,
|
||||
"Cannot satisfy minimum cdclk %d with refclk %u\n",
|
||||
min_cdclk, dev_priv->cdclk.hw.ref);
|
||||
min_cdclk, dev_priv->display.cdclk.hw.ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bxt_calc_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
|
||||
{
|
||||
const struct intel_cdclk_vals *table = dev_priv->cdclk.table;
|
||||
const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table;
|
||||
int i;
|
||||
|
||||
if (cdclk == dev_priv->cdclk.hw.bypass)
|
||||
if (cdclk == dev_priv->display.cdclk.hw.bypass)
|
||||
return 0;
|
||||
|
||||
for (i = 0; table[i].refclk; i++)
|
||||
if (table[i].refclk == dev_priv->cdclk.hw.ref &&
|
||||
if (table[i].refclk == dev_priv->display.cdclk.hw.ref &&
|
||||
table[i].cdclk == cdclk)
|
||||
return dev_priv->cdclk.hw.ref * table[i].ratio;
|
||||
return dev_priv->display.cdclk.hw.ref * table[i].ratio;
|
||||
|
||||
drm_WARN(&dev_priv->drm, 1, "cdclk %d not valid for refclk %u\n",
|
||||
cdclk, dev_priv->cdclk.hw.ref);
|
||||
cdclk, dev_priv->display.cdclk.hw.ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1554,12 +1554,12 @@ static void bxt_de_pll_disable(struct drm_i915_private *dev_priv)
|
||||
BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
|
||||
drm_err(&dev_priv->drm, "timeout waiting for DE PLL unlock\n");
|
||||
|
||||
dev_priv->cdclk.hw.vco = 0;
|
||||
dev_priv->display.cdclk.hw.vco = 0;
|
||||
}
|
||||
|
||||
static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)
|
||||
{
|
||||
int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk.hw.ref);
|
||||
int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->display.cdclk.hw.ref);
|
||||
|
||||
intel_de_rmw(dev_priv, BXT_DE_PLL_CTL,
|
||||
BXT_DE_PLL_RATIO_MASK, BXT_DE_PLL_RATIO(ratio));
|
||||
@ -1571,7 +1571,7 @@ static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)
|
||||
BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
|
||||
drm_err(&dev_priv->drm, "timeout waiting for DE PLL lock\n");
|
||||
|
||||
dev_priv->cdclk.hw.vco = vco;
|
||||
dev_priv->display.cdclk.hw.vco = vco;
|
||||
}
|
||||
|
||||
static void icl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
|
||||
@ -1583,12 +1583,12 @@ static void icl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
|
||||
if (intel_de_wait_for_clear(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
|
||||
drm_err(&dev_priv->drm, "timeout waiting for CDCLK PLL unlock\n");
|
||||
|
||||
dev_priv->cdclk.hw.vco = 0;
|
||||
dev_priv->display.cdclk.hw.vco = 0;
|
||||
}
|
||||
|
||||
static void icl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)
|
||||
{
|
||||
int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk.hw.ref);
|
||||
int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->display.cdclk.hw.ref);
|
||||
u32 val;
|
||||
|
||||
val = ICL_CDCLK_PLL_RATIO(ratio);
|
||||
@ -1601,12 +1601,12 @@ static void icl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)
|
||||
if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
|
||||
drm_err(&dev_priv->drm, "timeout waiting for CDCLK PLL lock\n");
|
||||
|
||||
dev_priv->cdclk.hw.vco = vco;
|
||||
dev_priv->display.cdclk.hw.vco = vco;
|
||||
}
|
||||
|
||||
static void adlp_cdclk_pll_crawl(struct drm_i915_private *dev_priv, int vco)
|
||||
{
|
||||
int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk.hw.ref);
|
||||
int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->display.cdclk.hw.ref);
|
||||
u32 val;
|
||||
|
||||
/* Write PLL ratio without disabling */
|
||||
@ -1625,7 +1625,7 @@ static void adlp_cdclk_pll_crawl(struct drm_i915_private *dev_priv, int vco)
|
||||
val &= ~BXT_DE_PLL_FREQ_REQ;
|
||||
intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
|
||||
|
||||
dev_priv->cdclk.hw.vco = vco;
|
||||
dev_priv->display.cdclk.hw.vco = vco;
|
||||
}
|
||||
|
||||
static u32 bxt_cdclk_cd2x_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
|
||||
@ -1655,7 +1655,7 @@ static u32 bxt_cdclk_cd2x_div_sel(struct drm_i915_private *dev_priv,
|
||||
switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
|
||||
default:
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
cdclk != dev_priv->cdclk.hw.bypass);
|
||||
cdclk != dev_priv->display.cdclk.hw.bypass);
|
||||
drm_WARN_ON(&dev_priv->drm, vco != 0);
|
||||
fallthrough;
|
||||
case 2:
|
||||
@ -1672,19 +1672,19 @@ static u32 bxt_cdclk_cd2x_div_sel(struct drm_i915_private *dev_priv,
|
||||
static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv,
|
||||
int cdclk)
|
||||
{
|
||||
const struct intel_cdclk_vals *table = dev_priv->cdclk.table;
|
||||
const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table;
|
||||
int i;
|
||||
|
||||
if (cdclk == dev_priv->cdclk.hw.bypass)
|
||||
if (cdclk == dev_priv->display.cdclk.hw.bypass)
|
||||
return 0;
|
||||
|
||||
for (i = 0; table[i].refclk; i++)
|
||||
if (table[i].refclk == dev_priv->cdclk.hw.ref &&
|
||||
if (table[i].refclk == dev_priv->display.cdclk.hw.ref &&
|
||||
table[i].cdclk == cdclk)
|
||||
return table[i].waveform;
|
||||
|
||||
drm_WARN(&dev_priv->drm, 1, "cdclk %d not valid for refclk %u\n",
|
||||
cdclk, dev_priv->cdclk.hw.ref);
|
||||
cdclk, dev_priv->display.cdclk.hw.ref);
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
@ -1721,22 +1721,22 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
|
||||
return;
|
||||
}
|
||||
|
||||
if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->cdclk.hw.vco > 0 && vco > 0) {
|
||||
if (dev_priv->cdclk.hw.vco != vco)
|
||||
if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) {
|
||||
if (dev_priv->display.cdclk.hw.vco != vco)
|
||||
adlp_cdclk_pll_crawl(dev_priv, vco);
|
||||
} else if (DISPLAY_VER(dev_priv) >= 11) {
|
||||
if (dev_priv->cdclk.hw.vco != 0 &&
|
||||
dev_priv->cdclk.hw.vco != vco)
|
||||
if (dev_priv->display.cdclk.hw.vco != 0 &&
|
||||
dev_priv->display.cdclk.hw.vco != vco)
|
||||
icl_cdclk_pll_disable(dev_priv);
|
||||
|
||||
if (dev_priv->cdclk.hw.vco != vco)
|
||||
if (dev_priv->display.cdclk.hw.vco != vco)
|
||||
icl_cdclk_pll_enable(dev_priv, vco);
|
||||
} else {
|
||||
if (dev_priv->cdclk.hw.vco != 0 &&
|
||||
dev_priv->cdclk.hw.vco != vco)
|
||||
if (dev_priv->display.cdclk.hw.vco != 0 &&
|
||||
dev_priv->display.cdclk.hw.vco != vco)
|
||||
bxt_de_pll_disable(dev_priv);
|
||||
|
||||
if (dev_priv->cdclk.hw.vco != vco)
|
||||
if (dev_priv->display.cdclk.hw.vco != vco)
|
||||
bxt_de_pll_enable(dev_priv, vco);
|
||||
}
|
||||
|
||||
@ -1803,7 +1803,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
|
||||
* Can't read out the voltage level :(
|
||||
* Let's just assume everything is as expected.
|
||||
*/
|
||||
dev_priv->cdclk.hw.voltage_level = cdclk_config->voltage_level;
|
||||
dev_priv->display.cdclk.hw.voltage_level = cdclk_config->voltage_level;
|
||||
}
|
||||
|
||||
static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
|
||||
@ -1812,10 +1812,10 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
|
||||
int cdclk, clock, vco;
|
||||
|
||||
intel_update_cdclk(dev_priv);
|
||||
intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "Current CDCLK");
|
||||
intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "Current CDCLK");
|
||||
|
||||
if (dev_priv->cdclk.hw.vco == 0 ||
|
||||
dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass)
|
||||
if (dev_priv->display.cdclk.hw.vco == 0 ||
|
||||
dev_priv->display.cdclk.hw.cdclk == dev_priv->display.cdclk.hw.bypass)
|
||||
goto sanitize;
|
||||
|
||||
/* DPLL okay; verify the cdclock
|
||||
@ -1833,32 +1833,32 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
|
||||
cdctl &= ~bxt_cdclk_cd2x_pipe(dev_priv, INVALID_PIPE);
|
||||
|
||||
/* Make sure this is a legal cdclk value for the platform */
|
||||
cdclk = bxt_calc_cdclk(dev_priv, dev_priv->cdclk.hw.cdclk);
|
||||
if (cdclk != dev_priv->cdclk.hw.cdclk)
|
||||
cdclk = bxt_calc_cdclk(dev_priv, dev_priv->display.cdclk.hw.cdclk);
|
||||
if (cdclk != dev_priv->display.cdclk.hw.cdclk)
|
||||
goto sanitize;
|
||||
|
||||
/* Make sure the VCO is correct for the cdclk */
|
||||
vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk);
|
||||
if (vco != dev_priv->cdclk.hw.vco)
|
||||
if (vco != dev_priv->display.cdclk.hw.vco)
|
||||
goto sanitize;
|
||||
|
||||
expected = skl_cdclk_decimal(cdclk);
|
||||
|
||||
/* Figure out what CD2X divider we should be using for this cdclk */
|
||||
if (has_cdclk_squasher(dev_priv))
|
||||
clock = dev_priv->cdclk.hw.vco / 2;
|
||||
clock = dev_priv->display.cdclk.hw.vco / 2;
|
||||
else
|
||||
clock = dev_priv->cdclk.hw.cdclk;
|
||||
clock = dev_priv->display.cdclk.hw.cdclk;
|
||||
|
||||
expected |= bxt_cdclk_cd2x_div_sel(dev_priv, clock,
|
||||
dev_priv->cdclk.hw.vco);
|
||||
dev_priv->display.cdclk.hw.vco);
|
||||
|
||||
/*
|
||||
* Disable SSA Precharge when CD clock frequency < 500 MHz,
|
||||
* enable otherwise.
|
||||
*/
|
||||
if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
|
||||
dev_priv->cdclk.hw.cdclk >= 500000)
|
||||
dev_priv->display.cdclk.hw.cdclk >= 500000)
|
||||
expected |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
|
||||
|
||||
if (cdctl == expected)
|
||||
@ -1869,10 +1869,10 @@ sanitize:
|
||||
drm_dbg_kms(&dev_priv->drm, "Sanitizing cdclk programmed by pre-os\n");
|
||||
|
||||
/* force cdclk programming */
|
||||
dev_priv->cdclk.hw.cdclk = 0;
|
||||
dev_priv->display.cdclk.hw.cdclk = 0;
|
||||
|
||||
/* force full PLL disable + enable */
|
||||
dev_priv->cdclk.hw.vco = -1;
|
||||
dev_priv->display.cdclk.hw.vco = -1;
|
||||
}
|
||||
|
||||
static void bxt_cdclk_init_hw(struct drm_i915_private *dev_priv)
|
||||
@ -1881,11 +1881,11 @@ static void bxt_cdclk_init_hw(struct drm_i915_private *dev_priv)
|
||||
|
||||
bxt_sanitize_cdclk(dev_priv);
|
||||
|
||||
if (dev_priv->cdclk.hw.cdclk != 0 &&
|
||||
dev_priv->cdclk.hw.vco != 0)
|
||||
if (dev_priv->display.cdclk.hw.cdclk != 0 &&
|
||||
dev_priv->display.cdclk.hw.vco != 0)
|
||||
return;
|
||||
|
||||
cdclk_config = dev_priv->cdclk.hw;
|
||||
cdclk_config = dev_priv->display.cdclk.hw;
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
@ -1902,7 +1902,7 @@ static void bxt_cdclk_init_hw(struct drm_i915_private *dev_priv)
|
||||
|
||||
static void bxt_cdclk_uninit_hw(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_cdclk_config cdclk_config = dev_priv->cdclk.hw;
|
||||
struct intel_cdclk_config cdclk_config = dev_priv->display.cdclk.hw;
|
||||
|
||||
cdclk_config.cdclk = cdclk_config.bypass;
|
||||
cdclk_config.vco = 0;
|
||||
@ -1916,7 +1916,7 @@ static void bxt_cdclk_uninit_hw(struct drm_i915_private *dev_priv)
|
||||
* intel_cdclk_init_hw - Initialize CDCLK hardware
|
||||
* @i915: i915 device
|
||||
*
|
||||
* Initialize CDCLK. This consists mainly of initializing dev_priv->cdclk.hw and
|
||||
* Initialize CDCLK. This consists mainly of initializing dev_priv->display.cdclk.hw and
|
||||
* sanitizing the state of the hardware if needed. This is generally done only
|
||||
* during the display core initialization sequence, after which the DMC will
|
||||
* take care of turning CDCLK off/on as needed.
|
||||
@ -2077,7 +2077,7 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv,
|
||||
{
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
if (!intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_config))
|
||||
if (!intel_cdclk_changed(&dev_priv->display.cdclk.hw, cdclk_config))
|
||||
return;
|
||||
|
||||
if (drm_WARN_ON_ONCE(&dev_priv->drm, !dev_priv->display.funcs.cdclk->set_cdclk))
|
||||
@ -2124,9 +2124,9 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv,
|
||||
intel_audio_cdclk_change_post(dev_priv);
|
||||
|
||||
if (drm_WARN(&dev_priv->drm,
|
||||
intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_config),
|
||||
intel_cdclk_changed(&dev_priv->display.cdclk.hw, cdclk_config),
|
||||
"cdclk state doesn't match!\n")) {
|
||||
intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "[hw state]");
|
||||
intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "[hw state]");
|
||||
intel_cdclk_dump_config(dev_priv, cdclk_config, "[sw state]");
|
||||
}
|
||||
}
|
||||
@ -2315,7 +2315,7 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
|
||||
*/
|
||||
min_cdclk = max_t(int, min_cdclk,
|
||||
min_t(int, crtc_state->pixel_rate,
|
||||
dev_priv->max_cdclk_freq));
|
||||
dev_priv->display.cdclk.max_cdclk_freq));
|
||||
}
|
||||
|
||||
return min_cdclk;
|
||||
@ -2368,10 +2368,10 @@ static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
|
||||
for_each_pipe(dev_priv, pipe)
|
||||
min_cdclk = max(cdclk_state->min_cdclk[pipe], min_cdclk);
|
||||
|
||||
if (min_cdclk > dev_priv->max_cdclk_freq) {
|
||||
if (min_cdclk > dev_priv->display.cdclk.max_cdclk_freq) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"required cdclk (%d kHz) exceeds max (%d kHz)\n",
|
||||
min_cdclk, dev_priv->max_cdclk_freq);
|
||||
min_cdclk, dev_priv->display.cdclk.max_cdclk_freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -2643,7 +2643,7 @@ intel_atomic_get_cdclk_state(struct intel_atomic_state *state)
|
||||
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
||||
struct intel_global_state *cdclk_state;
|
||||
|
||||
cdclk_state = intel_atomic_get_global_obj_state(state, &dev_priv->cdclk.obj);
|
||||
cdclk_state = intel_atomic_get_global_obj_state(state, &dev_priv->display.cdclk.obj);
|
||||
if (IS_ERR(cdclk_state))
|
||||
return ERR_CAST(cdclk_state);
|
||||
|
||||
@ -2693,7 +2693,7 @@ int intel_cdclk_init(struct drm_i915_private *dev_priv)
|
||||
if (!cdclk_state)
|
||||
return -ENOMEM;
|
||||
|
||||
intel_atomic_global_obj_init(dev_priv, &dev_priv->cdclk.obj,
|
||||
intel_atomic_global_obj_init(dev_priv, &dev_priv->display.cdclk.obj,
|
||||
&cdclk_state->base, &intel_cdclk_funcs);
|
||||
|
||||
return 0;
|
||||
@ -2799,7 +2799,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
|
||||
|
||||
static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
int max_cdclk_freq = dev_priv->max_cdclk_freq;
|
||||
int max_cdclk_freq = dev_priv->display.cdclk.max_cdclk_freq;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 10)
|
||||
return 2 * max_cdclk_freq;
|
||||
@ -2825,19 +2825,19 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
|
||||
void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (IS_JSL_EHL(dev_priv)) {
|
||||
if (dev_priv->cdclk.hw.ref == 24000)
|
||||
dev_priv->max_cdclk_freq = 552000;
|
||||
if (dev_priv->display.cdclk.hw.ref == 24000)
|
||||
dev_priv->display.cdclk.max_cdclk_freq = 552000;
|
||||
else
|
||||
dev_priv->max_cdclk_freq = 556800;
|
||||
dev_priv->display.cdclk.max_cdclk_freq = 556800;
|
||||
} else if (DISPLAY_VER(dev_priv) >= 11) {
|
||||
if (dev_priv->cdclk.hw.ref == 24000)
|
||||
dev_priv->max_cdclk_freq = 648000;
|
||||
if (dev_priv->display.cdclk.hw.ref == 24000)
|
||||
dev_priv->display.cdclk.max_cdclk_freq = 648000;
|
||||
else
|
||||
dev_priv->max_cdclk_freq = 652800;
|
||||
dev_priv->display.cdclk.max_cdclk_freq = 652800;
|
||||
} else if (IS_GEMINILAKE(dev_priv)) {
|
||||
dev_priv->max_cdclk_freq = 316800;
|
||||
dev_priv->display.cdclk.max_cdclk_freq = 316800;
|
||||
} else if (IS_BROXTON(dev_priv)) {
|
||||
dev_priv->max_cdclk_freq = 624000;
|
||||
dev_priv->display.cdclk.max_cdclk_freq = 624000;
|
||||
} else if (DISPLAY_VER(dev_priv) == 9) {
|
||||
u32 limit = intel_de_read(dev_priv, SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;
|
||||
int max_cdclk, vco;
|
||||
@ -2859,7 +2859,7 @@ void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
|
||||
else
|
||||
max_cdclk = 308571;
|
||||
|
||||
dev_priv->max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco);
|
||||
dev_priv->display.cdclk.max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco);
|
||||
} else if (IS_BROADWELL(dev_priv)) {
|
||||
/*
|
||||
* FIXME with extra cooling we can allow
|
||||
@ -2868,26 +2868,26 @@ void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
|
||||
* available? PCI ID, VTB, something else?
|
||||
*/
|
||||
if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT)
|
||||
dev_priv->max_cdclk_freq = 450000;
|
||||
dev_priv->display.cdclk.max_cdclk_freq = 450000;
|
||||
else if (IS_BDW_ULX(dev_priv))
|
||||
dev_priv->max_cdclk_freq = 450000;
|
||||
dev_priv->display.cdclk.max_cdclk_freq = 450000;
|
||||
else if (IS_BDW_ULT(dev_priv))
|
||||
dev_priv->max_cdclk_freq = 540000;
|
||||
dev_priv->display.cdclk.max_cdclk_freq = 540000;
|
||||
else
|
||||
dev_priv->max_cdclk_freq = 675000;
|
||||
dev_priv->display.cdclk.max_cdclk_freq = 675000;
|
||||
} else if (IS_CHERRYVIEW(dev_priv)) {
|
||||
dev_priv->max_cdclk_freq = 320000;
|
||||
dev_priv->display.cdclk.max_cdclk_freq = 320000;
|
||||
} else if (IS_VALLEYVIEW(dev_priv)) {
|
||||
dev_priv->max_cdclk_freq = 400000;
|
||||
dev_priv->display.cdclk.max_cdclk_freq = 400000;
|
||||
} else {
|
||||
/* otherwise assume cdclk is fixed */
|
||||
dev_priv->max_cdclk_freq = dev_priv->cdclk.hw.cdclk;
|
||||
dev_priv->display.cdclk.max_cdclk_freq = dev_priv->display.cdclk.hw.cdclk;
|
||||
}
|
||||
|
||||
dev_priv->max_dotclk_freq = intel_compute_max_dotclk(dev_priv);
|
||||
|
||||
drm_dbg(&dev_priv->drm, "Max CD clock rate: %d kHz\n",
|
||||
dev_priv->max_cdclk_freq);
|
||||
dev_priv->display.cdclk.max_cdclk_freq);
|
||||
|
||||
drm_dbg(&dev_priv->drm, "Max dotclock rate: %d kHz\n",
|
||||
dev_priv->max_dotclk_freq);
|
||||
@ -2901,7 +2901,7 @@ void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
|
||||
*/
|
||||
void intel_update_cdclk(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
intel_cdclk_get_cdclk(dev_priv, &dev_priv->cdclk.hw);
|
||||
intel_cdclk_get_cdclk(dev_priv, &dev_priv->display.cdclk.hw);
|
||||
|
||||
/*
|
||||
* 9:0 CMBUS [sic] CDCLK frequency (cdfreq):
|
||||
@ -2911,7 +2911,7 @@ void intel_update_cdclk(struct drm_i915_private *dev_priv)
|
||||
*/
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
||||
intel_de_write(dev_priv, GMBUSFREQ_VLV,
|
||||
DIV_ROUND_UP(dev_priv->cdclk.hw.cdclk, 1000));
|
||||
DIV_ROUND_UP(dev_priv->display.cdclk.hw.cdclk, 1000));
|
||||
}
|
||||
|
||||
static int dg1_rawclk(struct drm_i915_private *dev_priv)
|
||||
@ -3195,32 +3195,32 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (IS_DG2(dev_priv)) {
|
||||
dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
|
||||
dev_priv->cdclk.table = dg2_cdclk_table;
|
||||
dev_priv->display.cdclk.table = dg2_cdclk_table;
|
||||
} else if (IS_ALDERLAKE_P(dev_priv)) {
|
||||
dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
|
||||
/* Wa_22011320316:adl-p[a0] */
|
||||
if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))
|
||||
dev_priv->cdclk.table = adlp_a_step_cdclk_table;
|
||||
dev_priv->display.cdclk.table = adlp_a_step_cdclk_table;
|
||||
else
|
||||
dev_priv->cdclk.table = adlp_cdclk_table;
|
||||
dev_priv->display.cdclk.table = adlp_cdclk_table;
|
||||
} else if (IS_ROCKETLAKE(dev_priv)) {
|
||||
dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
|
||||
dev_priv->cdclk.table = rkl_cdclk_table;
|
||||
dev_priv->display.cdclk.table = rkl_cdclk_table;
|
||||
} else if (DISPLAY_VER(dev_priv) >= 12) {
|
||||
dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
|
||||
dev_priv->cdclk.table = icl_cdclk_table;
|
||||
dev_priv->display.cdclk.table = icl_cdclk_table;
|
||||
} else if (IS_JSL_EHL(dev_priv)) {
|
||||
dev_priv->display.funcs.cdclk = &ehl_cdclk_funcs;
|
||||
dev_priv->cdclk.table = icl_cdclk_table;
|
||||
dev_priv->display.cdclk.table = icl_cdclk_table;
|
||||
} else if (DISPLAY_VER(dev_priv) >= 11) {
|
||||
dev_priv->display.funcs.cdclk = &icl_cdclk_funcs;
|
||||
dev_priv->cdclk.table = icl_cdclk_table;
|
||||
dev_priv->display.cdclk.table = icl_cdclk_table;
|
||||
} else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
|
||||
dev_priv->display.funcs.cdclk = &bxt_cdclk_funcs;
|
||||
if (IS_GEMINILAKE(dev_priv))
|
||||
dev_priv->cdclk.table = glk_cdclk_table;
|
||||
dev_priv->display.cdclk.table = glk_cdclk_table;
|
||||
else
|
||||
dev_priv->cdclk.table = bxt_cdclk_table;
|
||||
dev_priv->display.cdclk.table = bxt_cdclk_table;
|
||||
} else if (DISPLAY_VER(dev_priv) == 9) {
|
||||
dev_priv->display.funcs.cdclk = &skl_cdclk_funcs;
|
||||
} else if (IS_BROADWELL(dev_priv)) {
|
||||
|
@ -77,9 +77,9 @@ intel_atomic_get_cdclk_state(struct intel_atomic_state *state);
|
||||
|
||||
#define to_intel_cdclk_state(x) container_of((x), struct intel_cdclk_state, base)
|
||||
#define intel_atomic_get_old_cdclk_state(state) \
|
||||
to_intel_cdclk_state(intel_atomic_get_old_global_obj_state(state, &to_i915(state->base.dev)->cdclk.obj))
|
||||
to_intel_cdclk_state(intel_atomic_get_old_global_obj_state(state, &to_i915(state->base.dev)->display.cdclk.obj))
|
||||
#define intel_atomic_get_new_cdclk_state(state) \
|
||||
to_intel_cdclk_state(intel_atomic_get_new_global_obj_state(state, &to_i915(state->base.dev)->cdclk.obj))
|
||||
to_intel_cdclk_state(intel_atomic_get_new_global_obj_state(state, &to_i915(state->base.dev)->display.cdclk.obj))
|
||||
|
||||
int intel_cdclk_init(struct drm_i915_private *dev_priv);
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dpll.h"
|
||||
#include "intel_dsb.h"
|
||||
#include "vlv_dsi_pll.h"
|
||||
|
||||
struct intel_color_funcs {
|
||||
|
@ -229,7 +229,7 @@ intel_attach_force_audio_property(struct drm_connector *connector)
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_property *prop;
|
||||
|
||||
prop = dev_priv->force_audio_property;
|
||||
prop = dev_priv->display.properties.force_audio;
|
||||
if (prop == NULL) {
|
||||
prop = drm_property_create_enum(dev, 0,
|
||||
"audio",
|
||||
@ -238,7 +238,7 @@ intel_attach_force_audio_property(struct drm_connector *connector)
|
||||
if (prop == NULL)
|
||||
return;
|
||||
|
||||
dev_priv->force_audio_property = prop;
|
||||
dev_priv->display.properties.force_audio = prop;
|
||||
}
|
||||
drm_object_attach_property(&connector->base, prop, 0);
|
||||
}
|
||||
@ -256,7 +256,7 @@ intel_attach_broadcast_rgb_property(struct drm_connector *connector)
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_property *prop;
|
||||
|
||||
prop = dev_priv->broadcast_rgb_property;
|
||||
prop = dev_priv->display.properties.broadcast_rgb;
|
||||
if (prop == NULL) {
|
||||
prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
|
||||
"Broadcast RGB",
|
||||
@ -265,7 +265,7 @@ intel_attach_broadcast_rgb_property(struct drm_connector *connector)
|
||||
if (prop == NULL)
|
||||
return;
|
||||
|
||||
dev_priv->broadcast_rgb_property = prop;
|
||||
dev_priv->display.properties.broadcast_rgb = prop;
|
||||
}
|
||||
|
||||
drm_object_attach_property(&connector->base, prop, 0);
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "intel_gmbus.h"
|
||||
#include "intel_hotplug.h"
|
||||
#include "intel_pch_display.h"
|
||||
#include "intel_pch_refclk.h"
|
||||
|
||||
/* Here's the desired hotplug mode */
|
||||
#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \
|
||||
@ -444,6 +445,8 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder,
|
||||
/* FDI must always be 2.7 GHz */
|
||||
pipe_config->port_clock = 135000 * 2;
|
||||
|
||||
adjusted_mode->crtc_clock = lpt_iclkip(pipe_config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -643,9 +646,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
|
||||
struct i2c_adapter *i2c;
|
||||
bool ret = false;
|
||||
|
||||
BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG);
|
||||
|
||||
i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin);
|
||||
i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->display.vbt.crt_ddc_pin);
|
||||
edid = intel_crt_get_edid(connector, i2c);
|
||||
|
||||
if (edid) {
|
||||
@ -931,7 +932,7 @@ static int intel_crt_get_modes(struct drm_connector *connector)
|
||||
wakeref = intel_display_power_get(dev_priv,
|
||||
intel_encoder->power_domain);
|
||||
|
||||
i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin);
|
||||
i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->display.vbt.crt_ddc_pin);
|
||||
ret = intel_crt_ddc_get_modes(connector, i2c);
|
||||
if (ret || !IS_G4X(dev_priv))
|
||||
goto out;
|
||||
@ -1110,8 +1111,8 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
|
||||
u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT |
|
||||
FDI_RX_LINK_REVERSAL_OVERRIDE;
|
||||
|
||||
dev_priv->fdi_rx_config = intel_de_read(dev_priv,
|
||||
FDI_RX_CTL(PIPE_A)) & fdi_config;
|
||||
dev_priv->display.fdi.rx_config = intel_de_read(dev_priv,
|
||||
FDI_RX_CTL(PIPE_A)) & fdi_config;
|
||||
}
|
||||
|
||||
intel_crt_reset(&crt->base.base);
|
||||
|
@ -19,9 +19,9 @@
|
||||
#include "intel_fb.h"
|
||||
#include "intel_fb_pin.h"
|
||||
#include "intel_frontbuffer.h"
|
||||
#include "intel_pm.h"
|
||||
#include "intel_psr.h"
|
||||
#include "intel_sprite.h"
|
||||
#include "skl_watermark.h"
|
||||
|
||||
/* Cursor formats */
|
||||
static const u32 intel_cursor_formats[] = {
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "intel_lspcon.h"
|
||||
#include "intel_pps.h"
|
||||
#include "intel_psr.h"
|
||||
#include "intel_quirks.h"
|
||||
#include "intel_snps_phy.h"
|
||||
#include "intel_sprite.h"
|
||||
#include "intel_tc.h"
|
||||
@ -323,28 +324,6 @@ static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv,
|
||||
}
|
||||
}
|
||||
|
||||
int intel_crtc_dotclock(const struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
int dotclock;
|
||||
|
||||
if (intel_crtc_has_dp_encoder(pipe_config))
|
||||
dotclock = intel_dotclock_calculate(pipe_config->port_clock,
|
||||
&pipe_config->dp_m_n);
|
||||
else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp > 24)
|
||||
dotclock = pipe_config->port_clock * 24 / pipe_config->pipe_bpp;
|
||||
else
|
||||
dotclock = pipe_config->port_clock;
|
||||
|
||||
if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
|
||||
!intel_crtc_has_dp_encoder(pipe_config))
|
||||
dotclock *= 2;
|
||||
|
||||
if (pipe_config->pixel_multiplier)
|
||||
dotclock /= pipe_config->pixel_multiplier;
|
||||
|
||||
return dotclock;
|
||||
}
|
||||
|
||||
static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
/* CRT dotclock is determined via other means */
|
||||
@ -631,7 +610,7 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
|
||||
|
||||
intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), ctl);
|
||||
|
||||
if (dev_priv->quirks & QUIRK_INCREASE_DDI_DISABLED_TIME &&
|
||||
if (intel_has_quirk(dev_priv, QUIRK_INCREASE_DDI_DISABLED_TIME) &&
|
||||
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Quirk Increase DDI disabled time\n");
|
||||
|
@ -91,6 +91,7 @@
|
||||
#include "intel_dmc.h"
|
||||
#include "intel_dp_link_training.h"
|
||||
#include "intel_dpt.h"
|
||||
#include "intel_dsb.h"
|
||||
#include "intel_fbc.h"
|
||||
#include "intel_fbdev.h"
|
||||
#include "intel_fdi.h"
|
||||
@ -117,6 +118,7 @@
|
||||
#include "i9xx_plane.h"
|
||||
#include "skl_scaler.h"
|
||||
#include "skl_universal_plane.h"
|
||||
#include "skl_watermark.h"
|
||||
#include "vlv_dsi.h"
|
||||
#include "vlv_dsi_pll.h"
|
||||
#include "vlv_dsi_regs.h"
|
||||
@ -618,7 +620,10 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)
|
||||
if (!IS_I830(dev_priv))
|
||||
val &= ~PIPECONF_ENABLE;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 12)
|
||||
if (DISPLAY_VER(dev_priv) >= 14)
|
||||
intel_de_rmw(dev_priv, MTL_CHICKEN_TRANS(cpu_transcoder),
|
||||
FECSTALL_DIS_DPTSTREAM_DPTTG, 0);
|
||||
else if (DISPLAY_VER(dev_priv) >= 12)
|
||||
intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder),
|
||||
FECSTALL_DIS_DPTSTREAM_DPTTG, 0);
|
||||
|
||||
@ -1838,7 +1843,9 @@ 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 *dev_priv = to_i915(crtc->base.dev);
|
||||
i915_reg_t reg = CHICKEN_TRANS(crtc_state->cpu_transcoder);
|
||||
enum transcoder transcoder = crtc_state->cpu_transcoder;
|
||||
i915_reg_t reg = DISPLAY_VER(dev_priv) >= 14 ? MTL_CHICKEN_TRANS(transcoder) :
|
||||
CHICKEN_TRANS(transcoder);
|
||||
u32 val;
|
||||
|
||||
val = intel_de_read(dev_priv, reg);
|
||||
@ -2658,7 +2665,7 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
|
||||
intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
|
||||
|
||||
if (DISPLAY_VER(i915) < 4) {
|
||||
clock_limit = i915->max_cdclk_freq * 9 / 10;
|
||||
clock_limit = i915->display.cdclk.max_cdclk_freq * 9 / 10;
|
||||
|
||||
/*
|
||||
* Enable double wide mode when the dot clock
|
||||
@ -2690,6 +2697,10 @@ static int intel_crtc_compute_config(struct intel_atomic_state *state,
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
int ret;
|
||||
|
||||
ret = intel_dpll_crtc_compute_clock(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = intel_crtc_compute_pipe_src(crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -2716,19 +2727,11 @@ intel_reduce_m_n_ratio(u32 *num, u32 *den)
|
||||
}
|
||||
}
|
||||
|
||||
static void compute_m_n(unsigned int m, unsigned int n,
|
||||
u32 *ret_m, u32 *ret_n,
|
||||
bool constant_n)
|
||||
static void compute_m_n(u32 *ret_m, u32 *ret_n,
|
||||
u32 m, u32 n, u32 constant_n)
|
||||
{
|
||||
/*
|
||||
* Several DP dongles in particular seem to be fussy about
|
||||
* too large link M/N values. Give N value as 0x8000 that
|
||||
* should be acceptable by specific devices. 0x8000 is the
|
||||
* specified fixed N value for asynchronous clock mode,
|
||||
* which the devices expect also in synchronous clock mode.
|
||||
*/
|
||||
if (constant_n)
|
||||
*ret_n = DP_LINK_CONSTANT_N_VALUE;
|
||||
*ret_n = constant_n;
|
||||
else
|
||||
*ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX);
|
||||
|
||||
@ -2740,22 +2743,28 @@ void
|
||||
intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
|
||||
int pixel_clock, int link_clock,
|
||||
struct intel_link_m_n *m_n,
|
||||
bool constant_n, bool fec_enable)
|
||||
bool fec_enable)
|
||||
{
|
||||
u32 data_clock = bits_per_pixel * pixel_clock;
|
||||
|
||||
if (fec_enable)
|
||||
data_clock = intel_dp_mode_to_fec_clock(data_clock);
|
||||
|
||||
/*
|
||||
* Windows/BIOS uses fixed M/N values always. Follow suit.
|
||||
*
|
||||
* Also several DP dongles in particular seem to be fussy
|
||||
* about too large link M/N values. Presumably the 20bit
|
||||
* value used by Windows/BIOS is acceptable to everyone.
|
||||
*/
|
||||
m_n->tu = 64;
|
||||
compute_m_n(data_clock,
|
||||
link_clock * nlanes * 8,
|
||||
&m_n->data_m, &m_n->data_n,
|
||||
constant_n);
|
||||
compute_m_n(&m_n->data_m, &m_n->data_n,
|
||||
data_clock, link_clock * nlanes * 8,
|
||||
0x8000000);
|
||||
|
||||
compute_m_n(pixel_clock, link_clock,
|
||||
&m_n->link_m, &m_n->link_n,
|
||||
constant_n);
|
||||
compute_m_n(&m_n->link_m, &m_n->link_n,
|
||||
pixel_clock, link_clock,
|
||||
0x80000);
|
||||
}
|
||||
|
||||
static void intel_panel_sanitize_ssc(struct drm_i915_private *dev_priv)
|
||||
@ -2771,12 +2780,12 @@ static void intel_panel_sanitize_ssc(struct drm_i915_private *dev_priv)
|
||||
PCH_DREF_CONTROL) &
|
||||
DREF_SSC1_ENABLE;
|
||||
|
||||
if (dev_priv->vbt.lvds_use_ssc != bios_lvds_use_ssc) {
|
||||
if (dev_priv->display.vbt.lvds_use_ssc != bios_lvds_use_ssc) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"SSC %s by BIOS, overriding VBT which says %s\n",
|
||||
str_enabled_disabled(bios_lvds_use_ssc),
|
||||
str_enabled_disabled(dev_priv->vbt.lvds_use_ssc));
|
||||
dev_priv->vbt.lvds_use_ssc = bios_lvds_use_ssc;
|
||||
str_enabled_disabled(dev_priv->display.vbt.lvds_use_ssc));
|
||||
dev_priv->display.vbt.lvds_use_ssc = bios_lvds_use_ssc;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4124,7 +4133,9 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
|
||||
}
|
||||
|
||||
if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
|
||||
tmp = intel_de_read(dev_priv, CHICKEN_TRANS(pipe_config->cpu_transcoder));
|
||||
tmp = intel_de_read(dev_priv, DISPLAY_VER(dev_priv) >= 14 ?
|
||||
MTL_CHICKEN_TRANS(pipe_config->cpu_transcoder) :
|
||||
CHICKEN_TRANS(pipe_config->cpu_transcoder));
|
||||
|
||||
pipe_config->framestart_delay = REG_FIELD_GET(HSW_FRAME_START_DELAY_MASK, tmp) + 1;
|
||||
} else {
|
||||
@ -4372,7 +4383,7 @@ static int i9xx_pll_refclk(struct drm_device *dev,
|
||||
u32 dpll = pipe_config->dpll_hw_state.dpll;
|
||||
|
||||
if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN)
|
||||
return dev_priv->vbt.lvds_ssc_freq;
|
||||
return dev_priv->display.vbt.lvds_ssc_freq;
|
||||
else if (HAS_PCH_SPLIT(dev_priv))
|
||||
return 120000;
|
||||
else if (DISPLAY_VER(dev_priv) != 2)
|
||||
@ -4490,7 +4501,31 @@ int intel_dotclock_calculate(int link_freq,
|
||||
if (!m_n->link_n)
|
||||
return 0;
|
||||
|
||||
return div_u64(mul_u32_u32(m_n->link_m, link_freq), m_n->link_n);
|
||||
return DIV_ROUND_UP_ULL(mul_u32_u32(m_n->link_m, link_freq),
|
||||
m_n->link_n);
|
||||
}
|
||||
|
||||
int intel_crtc_dotclock(const struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
int dotclock;
|
||||
|
||||
if (intel_crtc_has_dp_encoder(pipe_config))
|
||||
dotclock = intel_dotclock_calculate(pipe_config->port_clock,
|
||||
&pipe_config->dp_m_n);
|
||||
else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp > 24)
|
||||
dotclock = DIV_ROUND_CLOSEST(pipe_config->port_clock * 24,
|
||||
pipe_config->pipe_bpp);
|
||||
else
|
||||
dotclock = pipe_config->port_clock;
|
||||
|
||||
if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
|
||||
!intel_crtc_has_dp_encoder(pipe_config))
|
||||
dotclock *= 2;
|
||||
|
||||
if (pipe_config->pixel_multiplier)
|
||||
dotclock /= pipe_config->pixel_multiplier;
|
||||
|
||||
return dotclock;
|
||||
}
|
||||
|
||||
/* Returns the currently programmed mode of the given encoder. */
|
||||
@ -4751,7 +4786,7 @@ static u16 skl_linetime_wm(const struct intel_crtc_state *crtc_state)
|
||||
|
||||
/* Display WA #1135: BXT:ALL GLK:ALL */
|
||||
if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
|
||||
dev_priv->ipc_enabled)
|
||||
skl_watermark_ipc_enabled(dev_priv))
|
||||
linetime_wm /= 2;
|
||||
|
||||
return min(linetime_wm, 0x1ff);
|
||||
@ -4797,10 +4832,6 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
|
||||
crtc_state->update_wm_post = true;
|
||||
|
||||
if (mode_changed) {
|
||||
ret = intel_dpll_crtc_compute_clock(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = intel_dpll_crtc_get_shared_dpll(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -5364,47 +5395,15 @@ bool intel_fuzzy_clock_check(int clock1, int clock2)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
intel_compare_m_n(unsigned int m, unsigned int n,
|
||||
unsigned int m2, unsigned int n2,
|
||||
bool exact)
|
||||
{
|
||||
if (m == m2 && n == n2)
|
||||
return true;
|
||||
|
||||
if (exact || !m || !n || !m2 || !n2)
|
||||
return false;
|
||||
|
||||
BUILD_BUG_ON(DATA_LINK_M_N_MASK > INT_MAX);
|
||||
|
||||
if (n > n2) {
|
||||
while (n > n2) {
|
||||
m2 <<= 1;
|
||||
n2 <<= 1;
|
||||
}
|
||||
} else if (n < n2) {
|
||||
while (n < n2) {
|
||||
m <<= 1;
|
||||
n <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (n != n2)
|
||||
return false;
|
||||
|
||||
return intel_fuzzy_clock_check(m, m2);
|
||||
}
|
||||
|
||||
static bool
|
||||
intel_compare_link_m_n(const struct intel_link_m_n *m_n,
|
||||
const struct intel_link_m_n *m2_n2,
|
||||
bool exact)
|
||||
const struct intel_link_m_n *m2_n2)
|
||||
{
|
||||
return m_n->tu == m2_n2->tu &&
|
||||
intel_compare_m_n(m_n->data_m, m_n->data_n,
|
||||
m2_n2->data_m, m2_n2->data_n, exact) &&
|
||||
intel_compare_m_n(m_n->link_m, m_n->link_n,
|
||||
m2_n2->link_m, m2_n2->link_n, exact);
|
||||
m_n->data_m == m2_n2->data_m &&
|
||||
m_n->data_n == m2_n2->data_n &&
|
||||
m_n->link_m == m2_n2->link_m &&
|
||||
m_n->link_n == m2_n2->link_n;
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -5598,8 +5597,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
|
||||
#define PIPE_CONF_CHECK_M_N(name) do { \
|
||||
if (!intel_compare_link_m_n(¤t_config->name, \
|
||||
&pipe_config->name,\
|
||||
!fastset)) { \
|
||||
&pipe_config->name)) { \
|
||||
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
||||
"(expected tu %i data %i/%i link %i/%i, " \
|
||||
"found tu %i, data %i/%i link %i/%i)", \
|
||||
@ -5646,9 +5644,9 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
*/
|
||||
#define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) do { \
|
||||
if (!intel_compare_link_m_n(¤t_config->name, \
|
||||
&pipe_config->name, !fastset) && \
|
||||
&pipe_config->name) && \
|
||||
!intel_compare_link_m_n(¤t_config->alt_name, \
|
||||
&pipe_config->name, !fastset)) { \
|
||||
&pipe_config->name)) { \
|
||||
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
||||
"(expected tu %i data %i/%i link %i/%i, " \
|
||||
"or tu %i data %i/%i link %i/%i, " \
|
||||
@ -5683,16 +5681,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PIPE_CONF_CHECK_CLOCK_FUZZY(name) do { \
|
||||
if (!intel_fuzzy_clock_check(current_config->name, pipe_config->name)) { \
|
||||
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
||||
"(expected %i, found %i)", \
|
||||
current_config->name, \
|
||||
pipe_config->name); \
|
||||
ret = false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PIPE_CONF_CHECK_INFOFRAME(name) do { \
|
||||
if (!intel_compare_infoframe(¤t_config->infoframes.name, \
|
||||
&pipe_config->infoframes.name)) { \
|
||||
@ -5748,8 +5736,9 @@ 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 (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) {
|
||||
PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2);
|
||||
if (HAS_DOUBLE_BUFFERED_M_N(dev_priv)) {
|
||||
if (!fastset || !pipe_config->seamless_m_n)
|
||||
PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2);
|
||||
} else {
|
||||
PIPE_CONF_CHECK_M_N(dp_m_n);
|
||||
PIPE_CONF_CHECK_M_N(dp_m2_n2);
|
||||
@ -5811,7 +5800,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
PIPE_CONF_CHECK_RECT(pch_pfit.dst);
|
||||
|
||||
PIPE_CONF_CHECK_I(scaler_state.scaler_id);
|
||||
PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);
|
||||
PIPE_CONF_CHECK_I(pixel_rate);
|
||||
|
||||
PIPE_CONF_CHECK_X(gamma_mode);
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
@ -5881,9 +5870,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
if (IS_G4X(dev_priv) || DISPLAY_VER(dev_priv) >= 5)
|
||||
PIPE_CONF_CHECK_I(pipe_bpp);
|
||||
|
||||
PIPE_CONF_CHECK_CLOCK_FUZZY(hw.pipe_mode.crtc_clock);
|
||||
PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
|
||||
PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
|
||||
if (!fastset || !pipe_config->seamless_m_n) {
|
||||
PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_clock);
|
||||
PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_clock);
|
||||
}
|
||||
PIPE_CONF_CHECK_I(port_clock);
|
||||
|
||||
PIPE_CONF_CHECK_I(min_voltage_level);
|
||||
|
||||
@ -5925,7 +5916,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
||||
#undef PIPE_CONF_CHECK_BOOL_INCOMPLETE
|
||||
#undef PIPE_CONF_CHECK_P
|
||||
#undef PIPE_CONF_CHECK_FLAGS
|
||||
#undef PIPE_CONF_CHECK_CLOCK_FUZZY
|
||||
#undef PIPE_CONF_CHECK_COLOR_LUT
|
||||
#undef PIPE_CONF_CHECK_TIMINGS
|
||||
#undef PIPE_CONF_CHECK_RECT
|
||||
@ -6047,20 +6037,6 @@ void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state)
|
||||
}
|
||||
}
|
||||
|
||||
static void intel_modeset_clear_plls(struct intel_atomic_state *state)
|
||||
{
|
||||
struct intel_crtc_state *new_crtc_state;
|
||||
struct intel_crtc *crtc;
|
||||
int i;
|
||||
|
||||
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
|
||||
if (!intel_crtc_needs_modeset(new_crtc_state))
|
||||
continue;
|
||||
|
||||
intel_release_shared_dplls(state, crtc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This implements the workaround described in the "notes" section of the mode
|
||||
* set sequence documentation. When going from no pipes or single pipe to
|
||||
@ -6161,23 +6137,6 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta
|
||||
new_crtc_state->update_pipe = true;
|
||||
}
|
||||
|
||||
static void intel_crtc_copy_fastset(const struct intel_crtc_state *old_crtc_state,
|
||||
struct intel_crtc_state *new_crtc_state)
|
||||
{
|
||||
/*
|
||||
* If we're not doing the full modeset we want to
|
||||
* keep the current M/N values as they may be
|
||||
* sufficiently different to the computed values
|
||||
* to cause problems.
|
||||
*
|
||||
* FIXME: should really copy more fuzzy state here
|
||||
*/
|
||||
new_crtc_state->fdi_m_n = old_crtc_state->fdi_m_n;
|
||||
new_crtc_state->dp_m_n = old_crtc_state->dp_m_n;
|
||||
new_crtc_state->dp_m2_n2 = old_crtc_state->dp_m2_n2;
|
||||
new_crtc_state->has_drrs = old_crtc_state->has_drrs;
|
||||
}
|
||||
|
||||
static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc,
|
||||
u8 plane_ids_mask)
|
||||
@ -6834,9 +6793,11 @@ static int intel_atomic_check(struct drm_device *dev,
|
||||
if (!intel_crtc_needs_modeset(new_crtc_state))
|
||||
continue;
|
||||
|
||||
ret = intel_modeset_pipe_config_late(state, crtc);
|
||||
if (ret)
|
||||
goto fail;
|
||||
if (new_crtc_state->hw.enable) {
|
||||
ret = intel_modeset_pipe_config_late(state, crtc);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
intel_crtc_check_fastset(old_crtc_state, new_crtc_state);
|
||||
}
|
||||
@ -6887,15 +6848,12 @@ static int intel_atomic_check(struct drm_device *dev,
|
||||
|
||||
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
if (intel_crtc_needs_modeset(new_crtc_state)) {
|
||||
any_ms = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!new_crtc_state->update_pipe)
|
||||
if (!intel_crtc_needs_modeset(new_crtc_state))
|
||||
continue;
|
||||
|
||||
intel_crtc_copy_fastset(old_crtc_state, new_crtc_state);
|
||||
any_ms = true;
|
||||
|
||||
intel_release_shared_dplls(state, crtc);
|
||||
}
|
||||
|
||||
if (any_ms && !check_digital_port_conflicts(state)) {
|
||||
@ -6936,8 +6894,6 @@ static int intel_atomic_check(struct drm_device *dev,
|
||||
ret = intel_modeset_calc_cdclk(state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
intel_modeset_clear_plls(state);
|
||||
}
|
||||
|
||||
ret = intel_atomic_check_crtcs(state);
|
||||
@ -7056,6 +7012,10 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state,
|
||||
if (DISPLAY_VER(dev_priv) >= 9 ||
|
||||
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
|
||||
hsw_set_linetime_wm(new_crtc_state);
|
||||
|
||||
if (new_crtc_state->seamless_m_n)
|
||||
intel_cpu_transcoder_set_m1_n1(crtc, new_crtc_state->cpu_transcoder,
|
||||
&new_crtc_state->dp_m_n);
|
||||
}
|
||||
|
||||
static void commit_pipe_pre_planes(struct intel_atomic_state *state,
|
||||
@ -7408,7 +7368,7 @@ static void intel_atomic_helper_free_state(struct drm_i915_private *dev_priv)
|
||||
struct intel_atomic_state *state, *next;
|
||||
struct llist_node *freed;
|
||||
|
||||
freed = llist_del_all(&dev_priv->atomic_helper.free_list);
|
||||
freed = llist_del_all(&dev_priv->display.atomic_helper.free_list);
|
||||
llist_for_each_entry_safe(state, next, freed, freed)
|
||||
drm_atomic_state_put(&state->base);
|
||||
}
|
||||
@ -7416,7 +7376,7 @@ static void intel_atomic_helper_free_state(struct drm_i915_private *dev_priv)
|
||||
static void intel_atomic_helper_free_state_worker(struct work_struct *work)
|
||||
{
|
||||
struct drm_i915_private *dev_priv =
|
||||
container_of(work, typeof(*dev_priv), atomic_helper.free_work);
|
||||
container_of(work, typeof(*dev_priv), display.atomic_helper.free_work);
|
||||
|
||||
intel_atomic_helper_free_state(dev_priv);
|
||||
}
|
||||
@ -7709,7 +7669,7 @@ intel_atomic_commit_ready(struct i915_sw_fence *fence,
|
||||
case FENCE_FREE:
|
||||
{
|
||||
struct intel_atomic_helper *helper =
|
||||
&to_i915(state->base.dev)->atomic_helper;
|
||||
&to_i915(state->base.dev)->display.atomic_helper;
|
||||
|
||||
if (llist_add(&state->freed, &helper->free_list))
|
||||
schedule_work(&helper->free_work);
|
||||
@ -7812,12 +7772,12 @@ static int intel_atomic_commit(struct drm_device *dev,
|
||||
|
||||
i915_sw_fence_commit(&state->commit_ready);
|
||||
if (nonblock && state->modeset) {
|
||||
queue_work(dev_priv->modeset_wq, &state->base.commit_work);
|
||||
queue_work(dev_priv->display.wq.modeset, &state->base.commit_work);
|
||||
} else if (nonblock) {
|
||||
queue_work(dev_priv->flip_wq, &state->base.commit_work);
|
||||
queue_work(dev_priv->display.wq.flip, &state->base.commit_work);
|
||||
} else {
|
||||
if (state->modeset)
|
||||
flush_workqueue(dev_priv->modeset_wq);
|
||||
flush_workqueue(dev_priv->display.wq.modeset);
|
||||
intel_atomic_commit_tail(state);
|
||||
}
|
||||
|
||||
@ -7923,7 +7883,7 @@ static bool intel_ddi_crt_present(struct drm_i915_private *dev_priv)
|
||||
if (intel_de_read(dev_priv, DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES)
|
||||
return false;
|
||||
|
||||
if (!dev_priv->vbt.int_crt_support)
|
||||
if (!dev_priv->display.vbt.int_crt_support)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -8058,7 +8018,7 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
|
||||
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
|
||||
bool has_edp, has_port;
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv) && dev_priv->vbt.int_crt_support)
|
||||
if (IS_VALLEYVIEW(dev_priv) && dev_priv->display.vbt.int_crt_support)
|
||||
intel_crt_init(dev_priv);
|
||||
|
||||
/*
|
||||
@ -8394,11 +8354,11 @@ void intel_modeset_init_hw(struct drm_i915_private *i915)
|
||||
if (!HAS_DISPLAY(i915))
|
||||
return;
|
||||
|
||||
cdclk_state = to_intel_cdclk_state(i915->cdclk.obj.state);
|
||||
cdclk_state = to_intel_cdclk_state(i915->display.cdclk.obj.state);
|
||||
|
||||
intel_update_cdclk(i915);
|
||||
intel_cdclk_dump_config(i915, &i915->cdclk.hw, "Current CDCLK");
|
||||
cdclk_state->logical = cdclk_state->actual = i915->cdclk.hw;
|
||||
intel_cdclk_dump_config(i915, &i915->display.cdclk.hw, "Current CDCLK");
|
||||
cdclk_state->logical = cdclk_state->actual = i915->display.cdclk.hw;
|
||||
}
|
||||
|
||||
static int sanitize_watermarks_add_affected(struct drm_atomic_state *state)
|
||||
@ -8686,9 +8646,9 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
|
||||
|
||||
intel_dmc_ucode_init(i915);
|
||||
|
||||
i915->modeset_wq = alloc_ordered_workqueue("i915_modeset", 0);
|
||||
i915->flip_wq = alloc_workqueue("i915_flip", WQ_HIGHPRI |
|
||||
WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE);
|
||||
i915->display.wq.modeset = alloc_ordered_workqueue("i915_modeset", 0);
|
||||
i915->display.wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI |
|
||||
WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE);
|
||||
|
||||
intel_mode_config_init(i915);
|
||||
|
||||
@ -8704,8 +8664,8 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
|
||||
if (ret)
|
||||
goto cleanup_vga_client_pw_domain_dmc;
|
||||
|
||||
init_llist_head(&i915->atomic_helper.free_list);
|
||||
INIT_WORK(&i915->atomic_helper.free_work,
|
||||
init_llist_head(&i915->display.atomic_helper.free_list);
|
||||
INIT_WORK(&i915->display.atomic_helper.free_work,
|
||||
intel_atomic_helper_free_state_worker);
|
||||
|
||||
intel_init_quirks(i915);
|
||||
@ -8765,7 +8725,7 @@ int intel_modeset_init_nogem(struct drm_i915_private *i915)
|
||||
|
||||
intel_hdcp_component_init(i915);
|
||||
|
||||
if (i915->max_cdclk_freq == 0)
|
||||
if (i915->display.cdclk.max_cdclk_freq == 0)
|
||||
intel_update_max_cdclk(i915);
|
||||
|
||||
/*
|
||||
@ -8829,7 +8789,7 @@ int intel_modeset_init(struct drm_i915_private *i915)
|
||||
intel_hpd_init(i915);
|
||||
intel_hpd_poll_disable(i915);
|
||||
|
||||
intel_init_ipc(i915);
|
||||
skl_watermark_ipc_init(i915);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -8960,7 +8920,7 @@ void intel_display_resume(struct drm_device *dev)
|
||||
if (!ret)
|
||||
ret = __intel_display_resume(i915, state, &ctx);
|
||||
|
||||
intel_enable_ipc(i915);
|
||||
skl_watermark_ipc_update(i915);
|
||||
drm_modeset_drop_locks(&ctx);
|
||||
drm_modeset_acquire_fini(&ctx);
|
||||
|
||||
@ -8995,11 +8955,18 @@ void intel_modeset_driver_remove(struct drm_i915_private *i915)
|
||||
if (!HAS_DISPLAY(i915))
|
||||
return;
|
||||
|
||||
flush_workqueue(i915->flip_wq);
|
||||
flush_workqueue(i915->modeset_wq);
|
||||
flush_workqueue(i915->display.wq.flip);
|
||||
flush_workqueue(i915->display.wq.modeset);
|
||||
|
||||
flush_work(&i915->atomic_helper.free_work);
|
||||
drm_WARN_ON(&i915->drm, !llist_empty(&i915->atomic_helper.free_list));
|
||||
flush_work(&i915->display.atomic_helper.free_work);
|
||||
drm_WARN_ON(&i915->drm, !llist_empty(&i915->display.atomic_helper.free_list));
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/* part #2: call after irq uninstall */
|
||||
@ -9014,13 +8981,6 @@ void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915)
|
||||
*/
|
||||
intel_hpd_poll_fini(i915);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/* poll work can call into fbdev, hence clean that up afterwards */
|
||||
intel_fbdev_fini(i915);
|
||||
|
||||
@ -9037,8 +8997,8 @@ void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915)
|
||||
|
||||
intel_gmbus_teardown(i915);
|
||||
|
||||
destroy_workqueue(i915->flip_wq);
|
||||
destroy_workqueue(i915->modeset_wq);
|
||||
destroy_workqueue(i915->display.wq.flip);
|
||||
destroy_workqueue(i915->display.wq.modeset);
|
||||
|
||||
intel_fbc_cleanup(i915);
|
||||
}
|
||||
|
@ -547,7 +547,7 @@ u8 intel_calc_active_pipes(struct intel_atomic_state *state,
|
||||
void intel_link_compute_m_n(u16 bpp, int nlanes,
|
||||
int pixel_clock, int link_clock,
|
||||
struct intel_link_m_n *m_n,
|
||||
bool constant_n, bool fec_enable);
|
||||
bool fec_enable);
|
||||
u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
|
||||
u32 pixel_format, u64 modifier);
|
||||
enum drm_mode_status
|
||||
|
@ -6,22 +6,35 @@
|
||||
#ifndef __INTEL_DISPLAY_CORE_H__
|
||||
#define __INTEL_DISPLAY_CORE_H__
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/llist.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include <drm/drm_connector.h>
|
||||
|
||||
#include "intel_cdclk.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_dmc.h"
|
||||
#include "intel_dpll_mgr.h"
|
||||
#include "intel_fbc.h"
|
||||
#include "intel_global_state.h"
|
||||
#include "intel_gmbus.h"
|
||||
#include "intel_opregion.h"
|
||||
#include "intel_pm_types.h"
|
||||
|
||||
struct drm_i915_private;
|
||||
struct drm_property;
|
||||
struct i915_audio_component;
|
||||
struct i915_hdcp_comp_master;
|
||||
struct intel_atomic_state;
|
||||
struct intel_audio_funcs;
|
||||
struct intel_bios_encoder_data;
|
||||
struct intel_cdclk_funcs;
|
||||
struct intel_cdclk_vals;
|
||||
struct intel_color_funcs;
|
||||
struct intel_crtc;
|
||||
struct intel_crtc_state;
|
||||
@ -33,6 +46,12 @@ struct intel_hotplug_funcs;
|
||||
struct intel_initial_plane_config;
|
||||
struct intel_overlay;
|
||||
|
||||
/* Amount of SAGV/QGV points, BSpec precisely defines this */
|
||||
#define I915_NUM_QGV_POINTS 8
|
||||
|
||||
/* Amount of PSF GV points, BSpec precisely defines this */
|
||||
#define I915_NUM_PSF_GV_POINTS 3
|
||||
|
||||
struct intel_display_funcs {
|
||||
/*
|
||||
* Returns the active state of the crtc, and if the crtc is active,
|
||||
@ -103,6 +122,17 @@ struct intel_dpll {
|
||||
} ref_clks;
|
||||
};
|
||||
|
||||
struct intel_frontbuffer_tracking {
|
||||
spinlock_t lock;
|
||||
|
||||
/*
|
||||
* Tracking bits for delayed frontbuffer flushing du to gpu activity or
|
||||
* scheduled flips.
|
||||
*/
|
||||
unsigned busy_bits;
|
||||
unsigned flip_bits;
|
||||
};
|
||||
|
||||
struct intel_hotplug {
|
||||
struct delayed_work hotplug_work;
|
||||
|
||||
@ -142,6 +172,39 @@ struct intel_hotplug {
|
||||
struct workqueue_struct *dp_wq;
|
||||
};
|
||||
|
||||
struct intel_vbt_data {
|
||||
/* bdb version */
|
||||
u16 version;
|
||||
|
||||
/* Feature bits */
|
||||
unsigned int int_tv_support:1;
|
||||
unsigned int int_crt_support:1;
|
||||
unsigned int lvds_use_ssc:1;
|
||||
unsigned int int_lvds_support:1;
|
||||
unsigned int display_clock_mode:1;
|
||||
unsigned int fdi_rx_polarity_inverted:1;
|
||||
int lvds_ssc_freq;
|
||||
enum drm_panel_orientation orientation;
|
||||
|
||||
bool override_afc_startup;
|
||||
u8 override_afc_startup_val;
|
||||
|
||||
int crt_ddc_pin;
|
||||
|
||||
struct list_head display_devices;
|
||||
struct list_head bdb_blocks;
|
||||
|
||||
struct intel_bios_encoder_data *ports[I915_MAX_PORTS]; /* Non-NULL if port present. */
|
||||
struct sdvo_device_mapping {
|
||||
u8 initialized;
|
||||
u8 dvo_port;
|
||||
u8 slave_addr;
|
||||
u8 dvo_wiring;
|
||||
u8 i2c_pin;
|
||||
u8 ddc_pin;
|
||||
} sdvo_mappings[2];
|
||||
};
|
||||
|
||||
struct intel_wm {
|
||||
/*
|
||||
* Raw watermark latency values:
|
||||
@ -176,6 +239,8 @@ struct intel_wm {
|
||||
* crtc_state->wm.need_postvbl_update.
|
||||
*/
|
||||
struct mutex wm_mutex;
|
||||
|
||||
bool ipc_enabled;
|
||||
};
|
||||
|
||||
struct intel_display {
|
||||
@ -207,12 +272,65 @@ struct intel_display {
|
||||
} funcs;
|
||||
|
||||
/* Grouping using anonymous structs. Keep sorted. */
|
||||
struct intel_atomic_helper {
|
||||
struct llist_head free_list;
|
||||
struct work_struct free_work;
|
||||
} atomic_helper;
|
||||
|
||||
struct {
|
||||
/* backlight registers and fields in struct intel_panel */
|
||||
struct mutex lock;
|
||||
} backlight;
|
||||
|
||||
struct {
|
||||
struct intel_global_obj obj;
|
||||
|
||||
struct intel_bw_info {
|
||||
/* for each QGV point */
|
||||
unsigned int deratedbw[I915_NUM_QGV_POINTS];
|
||||
/* for each PSF GV point */
|
||||
unsigned int psf_bw[I915_NUM_PSF_GV_POINTS];
|
||||
u8 num_qgv_points;
|
||||
u8 num_psf_gv_points;
|
||||
u8 num_planes;
|
||||
} max[6];
|
||||
} bw;
|
||||
|
||||
struct {
|
||||
/* The current hardware cdclk configuration */
|
||||
struct intel_cdclk_config hw;
|
||||
|
||||
/* cdclk, divider, and ratio table from bspec */
|
||||
const struct intel_cdclk_vals *table;
|
||||
|
||||
struct intel_global_obj obj;
|
||||
|
||||
unsigned int max_cdclk_freq;
|
||||
} cdclk;
|
||||
|
||||
struct {
|
||||
/* The current hardware dbuf configuration */
|
||||
u8 enabled_slices;
|
||||
|
||||
struct intel_global_obj obj;
|
||||
} dbuf;
|
||||
|
||||
struct {
|
||||
/* VLV/CHV/BXT/GLK DSI MMIO register base address */
|
||||
u32 mmio_base;
|
||||
} dsi;
|
||||
|
||||
struct {
|
||||
/* list of fbdev register on this device */
|
||||
struct intel_fbdev *fbdev;
|
||||
struct work_struct suspend_work;
|
||||
} fbdev;
|
||||
|
||||
struct {
|
||||
unsigned int pll_freq;
|
||||
u32 rx_config;
|
||||
} fdi;
|
||||
|
||||
struct {
|
||||
/*
|
||||
* Base address of where the gmbus and gpio blocks are located
|
||||
@ -231,6 +349,24 @@ struct intel_display {
|
||||
wait_queue_head_t wait_queue;
|
||||
} gmbus;
|
||||
|
||||
struct {
|
||||
struct i915_hdcp_comp_master *master;
|
||||
bool comp_added;
|
||||
|
||||
/* Mutex to protect the above hdcp component related values. */
|
||||
struct mutex comp_mutex;
|
||||
} hdcp;
|
||||
|
||||
struct {
|
||||
struct i915_power_domains domains;
|
||||
|
||||
/* Shadow for DISPLAY_PHY_CONTROL which can't be safely read */
|
||||
u32 chv_phy_control;
|
||||
|
||||
/* perform PHY state sanity checks? */
|
||||
bool chv_phy_assert[2];
|
||||
} power;
|
||||
|
||||
struct {
|
||||
u32 mmio_base;
|
||||
|
||||
@ -238,6 +374,15 @@ struct intel_display {
|
||||
struct mutex mutex;
|
||||
} pps;
|
||||
|
||||
struct {
|
||||
struct drm_property *broadcast_rgb;
|
||||
struct drm_property *force_audio;
|
||||
} properties;
|
||||
|
||||
struct {
|
||||
unsigned long mask;
|
||||
} quirks;
|
||||
|
||||
struct {
|
||||
enum {
|
||||
I915_SAGV_UNKNOWN = 0,
|
||||
@ -249,12 +394,24 @@ struct intel_display {
|
||||
u32 block_time_us;
|
||||
} sagv;
|
||||
|
||||
struct {
|
||||
/* ordered wq for modesets */
|
||||
struct workqueue_struct *modeset;
|
||||
|
||||
/* unbound hipri wq for page flips/plane updates */
|
||||
struct workqueue_struct *flip;
|
||||
} wq;
|
||||
|
||||
/* Grouping using named structs. Keep sorted. */
|
||||
struct intel_audio audio;
|
||||
struct intel_dmc dmc;
|
||||
struct intel_dpll dpll;
|
||||
struct intel_fbc *fbc[I915_MAX_FBCS];
|
||||
struct intel_frontbuffer_tracking fb_tracking;
|
||||
struct intel_hotplug hotplug;
|
||||
struct intel_opregion opregion;
|
||||
struct intel_overlay *overlay;
|
||||
struct intel_vbt_data vbt;
|
||||
struct intel_wm wm;
|
||||
};
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "intel_pm.h"
|
||||
#include "intel_psr.h"
|
||||
#include "intel_sprite.h"
|
||||
#include "skl_watermark.h"
|
||||
|
||||
static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node)
|
||||
{
|
||||
@ -37,10 +38,10 @@ static int i915_frontbuffer_tracking(struct seq_file *m, void *unused)
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
|
||||
seq_printf(m, "FB tracking busy bits: 0x%08x\n",
|
||||
dev_priv->fb_tracking.busy_bits);
|
||||
dev_priv->display.fb_tracking.busy_bits);
|
||||
|
||||
seq_printf(m, "FB tracking flip bits: 0x%08x\n",
|
||||
dev_priv->fb_tracking.flip_bits);
|
||||
dev_priv->display.fb_tracking.flip_bits);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -103,7 +104,8 @@ static int i915_sr_status(struct seq_file *m, void *unused)
|
||||
|
||||
static int i915_opregion(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct intel_opregion *opregion = &node_to_i915(m->private)->opregion;
|
||||
struct drm_i915_private *i915 = node_to_i915(m->private);
|
||||
struct intel_opregion *opregion = &i915->display.opregion;
|
||||
|
||||
if (opregion->header)
|
||||
seq_write(m, opregion->header, OPREGION_SIZE);
|
||||
@ -113,7 +115,8 @@ static int i915_opregion(struct seq_file *m, void *unused)
|
||||
|
||||
static int i915_vbt(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct intel_opregion *opregion = &node_to_i915(m->private)->opregion;
|
||||
struct drm_i915_private *i915 = node_to_i915(m->private);
|
||||
struct intel_opregion *opregion = &i915->display.opregion;
|
||||
|
||||
if (opregion->vbt)
|
||||
seq_write(m, opregion->vbt, opregion->vbt_size);
|
||||
@ -980,58 +983,6 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_ipc_status_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
|
||||
seq_printf(m, "Isochronous Priority Control: %s\n",
|
||||
str_yes_no(dev_priv->ipc_enabled));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_ipc_status_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = inode->i_private;
|
||||
|
||||
if (!HAS_IPC(dev_priv))
|
||||
return -ENODEV;
|
||||
|
||||
return single_open(file, i915_ipc_status_show, dev_priv);
|
||||
}
|
||||
|
||||
static ssize_t i915_ipc_status_write(struct file *file, const char __user *ubuf,
|
||||
size_t len, loff_t *offp)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
intel_wakeref_t wakeref;
|
||||
bool enable;
|
||||
int ret;
|
||||
|
||||
ret = kstrtobool_from_user(ubuf, len, &enable);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) {
|
||||
if (!dev_priv->ipc_enabled && enable)
|
||||
drm_info(&dev_priv->drm,
|
||||
"Enabling IPC: WM will be proper only after next commit\n");
|
||||
dev_priv->ipc_enabled = enable;
|
||||
intel_enable_ipc(dev_priv);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct file_operations i915_ipc_status_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = i915_ipc_status_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = i915_ipc_status_write
|
||||
};
|
||||
|
||||
static int i915_ddb_info(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
@ -1908,7 +1859,6 @@ static const struct {
|
||||
{"i915_dp_test_active", &i915_displayport_test_active_fops},
|
||||
{"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops},
|
||||
{"i915_hpd_short_storm_ctl", &i915_hpd_short_storm_ctl_fops},
|
||||
{"i915_ipc_status", &i915_ipc_status_fops},
|
||||
{"i915_drrs_ctl", &i915_drrs_ctl_fops},
|
||||
{"i915_edp_psr_debug", &i915_edp_psr_debug_fops},
|
||||
};
|
||||
@ -1932,6 +1882,7 @@ void intel_display_debugfs_register(struct drm_i915_private *i915)
|
||||
|
||||
intel_dmc_debugfs_register(i915);
|
||||
intel_fbc_debugfs_register(i915);
|
||||
skl_watermark_ipc_debugfs_register(i915);
|
||||
}
|
||||
|
||||
static int i915_panel_show(struct seq_file *m, void *data)
|
||||
@ -2138,7 +2089,7 @@ static const struct file_operations i915_dsc_fec_support_fops = {
|
||||
.write = i915_dsc_fec_support_write
|
||||
};
|
||||
|
||||
static int i915_dsc_bpp_show(struct seq_file *m, void *data)
|
||||
static int i915_dsc_bpc_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_connector *connector = m->private;
|
||||
struct drm_device *dev = connector->dev;
|
||||
@ -2161,14 +2112,14 @@ static int i915_dsc_bpp_show(struct seq_file *m, void *data)
|
||||
}
|
||||
|
||||
crtc_state = to_intel_crtc_state(crtc->state);
|
||||
seq_printf(m, "Compressed_BPP: %d\n", crtc_state->dsc.compressed_bpp);
|
||||
seq_printf(m, "Input_BPC: %d\n", crtc_state->dsc.config.bits_per_component);
|
||||
|
||||
out: drm_modeset_unlock(&dev->mode_config.connection_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t i915_dsc_bpp_write(struct file *file,
|
||||
static ssize_t i915_dsc_bpc_write(struct file *file,
|
||||
const char __user *ubuf,
|
||||
size_t len, loff_t *offp)
|
||||
{
|
||||
@ -2176,33 +2127,32 @@ static ssize_t i915_dsc_bpp_write(struct file *file,
|
||||
((struct seq_file *)file->private_data)->private;
|
||||
struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
int dsc_bpp = 0;
|
||||
int dsc_bpc = 0;
|
||||
int ret;
|
||||
|
||||
ret = kstrtoint_from_user(ubuf, len, 0, &dsc_bpp);
|
||||
ret = kstrtoint_from_user(ubuf, len, 0, &dsc_bpc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
intel_dp->force_dsc_bpp = dsc_bpp;
|
||||
intel_dp->force_dsc_bpc = dsc_bpc;
|
||||
*offp += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int i915_dsc_bpp_open(struct inode *inode,
|
||||
static int i915_dsc_bpc_open(struct inode *inode,
|
||||
struct file *file)
|
||||
{
|
||||
return single_open(file, i915_dsc_bpp_show,
|
||||
inode->i_private);
|
||||
return single_open(file, i915_dsc_bpc_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations i915_dsc_bpp_fops = {
|
||||
static const struct file_operations i915_dsc_bpc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = i915_dsc_bpp_open,
|
||||
.open = i915_dsc_bpc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = i915_dsc_bpp_write
|
||||
.write = i915_dsc_bpc_write
|
||||
};
|
||||
|
||||
/*
|
||||
@ -2272,8 +2222,8 @@ void intel_connector_debugfs_add(struct intel_connector *intel_connector)
|
||||
debugfs_create_file("i915_dsc_fec_support", 0644, root,
|
||||
connector, &i915_dsc_fec_support_fops);
|
||||
|
||||
debugfs_create_file("i915_dsc_bpp", 0644, root,
|
||||
connector, &i915_dsc_bpp_fops);
|
||||
debugfs_create_file("i915_dsc_bpc", 0644, root,
|
||||
connector, &i915_dsc_bpc_fops);
|
||||
}
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_DSI ||
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include "intel_mchbar_regs.h"
|
||||
#include "intel_pch_refclk.h"
|
||||
#include "intel_pcode.h"
|
||||
#include "intel_pm.h"
|
||||
#include "intel_snps_phy.h"
|
||||
#include "skl_watermark.h"
|
||||
#include "vlv_sideband.h"
|
||||
|
||||
#define for_each_power_domain_well(__dev_priv, __power_well, __domain) \
|
||||
@ -244,7 +244,7 @@ bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
|
||||
struct i915_power_domains *power_domains;
|
||||
bool ret;
|
||||
|
||||
power_domains = &dev_priv->power_domains;
|
||||
power_domains = &dev_priv->display.power.domains;
|
||||
|
||||
mutex_lock(&power_domains->lock);
|
||||
ret = __intel_display_power_is_enabled(dev_priv, domain);
|
||||
@ -292,7 +292,7 @@ void intel_display_power_set_target_dc_state(struct drm_i915_private *dev_priv,
|
||||
{
|
||||
struct i915_power_well *power_well;
|
||||
bool dc_off_enabled;
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
|
||||
mutex_lock(&power_domains->lock);
|
||||
power_well = lookup_power_well(dev_priv, SKL_DISP_DC_OFF);
|
||||
@ -340,7 +340,7 @@ assert_async_put_domain_masks_disjoint(struct i915_power_domains *power_domains)
|
||||
{
|
||||
struct drm_i915_private *i915 = container_of(power_domains,
|
||||
struct drm_i915_private,
|
||||
power_domains);
|
||||
display.power.domains);
|
||||
|
||||
return !drm_WARN_ON(&i915->drm,
|
||||
bitmap_intersects(power_domains->async_put_domains[0].bits,
|
||||
@ -353,7 +353,7 @@ __async_put_domains_state_ok(struct i915_power_domains *power_domains)
|
||||
{
|
||||
struct drm_i915_private *i915 = container_of(power_domains,
|
||||
struct drm_i915_private,
|
||||
power_domains);
|
||||
display.power.domains);
|
||||
struct intel_power_domain_mask async_put_mask;
|
||||
enum intel_display_power_domain domain;
|
||||
bool err = false;
|
||||
@ -376,7 +376,7 @@ static void print_power_domains(struct i915_power_domains *power_domains,
|
||||
{
|
||||
struct drm_i915_private *i915 = container_of(power_domains,
|
||||
struct drm_i915_private,
|
||||
power_domains);
|
||||
display.power.domains);
|
||||
enum intel_display_power_domain domain;
|
||||
|
||||
drm_dbg(&i915->drm, "%s (%d):\n", prefix, bitmap_weight(mask->bits, POWER_DOMAIN_NUM));
|
||||
@ -391,7 +391,7 @@ print_async_put_domains_state(struct i915_power_domains *power_domains)
|
||||
{
|
||||
struct drm_i915_private *i915 = container_of(power_domains,
|
||||
struct drm_i915_private,
|
||||
power_domains);
|
||||
display.power.domains);
|
||||
|
||||
drm_dbg(&i915->drm, "async_put_wakeref %u\n",
|
||||
power_domains->async_put_wakeref);
|
||||
@ -446,7 +446,7 @@ static bool
|
||||
intel_display_power_grab_async_put_ref(struct drm_i915_private *dev_priv,
|
||||
enum intel_display_power_domain domain)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
struct intel_power_domain_mask async_put_mask;
|
||||
bool ret = false;
|
||||
|
||||
@ -475,7 +475,7 @@ static void
|
||||
__intel_display_power_get_domain(struct drm_i915_private *dev_priv,
|
||||
enum intel_display_power_domain domain)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
struct i915_power_well *power_well;
|
||||
|
||||
if (intel_display_power_grab_async_put_ref(dev_priv, domain))
|
||||
@ -502,7 +502,7 @@ __intel_display_power_get_domain(struct drm_i915_private *dev_priv,
|
||||
intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv,
|
||||
enum intel_display_power_domain domain)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
intel_wakeref_t wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
|
||||
|
||||
mutex_lock(&power_domains->lock);
|
||||
@ -528,7 +528,7 @@ intel_wakeref_t
|
||||
intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv,
|
||||
enum intel_display_power_domain domain)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
intel_wakeref_t wakeref;
|
||||
bool is_enabled;
|
||||
|
||||
@ -564,7 +564,7 @@ __intel_display_power_put_domain(struct drm_i915_private *dev_priv,
|
||||
const char *name = intel_display_power_domain_str(domain);
|
||||
struct intel_power_domain_mask async_put_mask;
|
||||
|
||||
power_domains = &dev_priv->power_domains;
|
||||
power_domains = &dev_priv->display.power.domains;
|
||||
|
||||
drm_WARN(&dev_priv->drm, !power_domains->domain_use_count[domain],
|
||||
"Use count on domain %s is already zero\n",
|
||||
@ -584,7 +584,7 @@ __intel_display_power_put_domain(struct drm_i915_private *dev_priv,
|
||||
static void __intel_display_power_put(struct drm_i915_private *dev_priv,
|
||||
enum intel_display_power_domain domain)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
|
||||
mutex_lock(&power_domains->lock);
|
||||
__intel_display_power_put_domain(dev_priv, domain);
|
||||
@ -597,7 +597,7 @@ queue_async_put_domains_work(struct i915_power_domains *power_domains,
|
||||
{
|
||||
struct drm_i915_private *i915 = container_of(power_domains,
|
||||
struct drm_i915_private,
|
||||
power_domains);
|
||||
display.power.domains);
|
||||
drm_WARN_ON(&i915->drm, power_domains->async_put_wakeref);
|
||||
power_domains->async_put_wakeref = wakeref;
|
||||
drm_WARN_ON(&i915->drm, !queue_delayed_work(system_unbound_wq,
|
||||
@ -611,7 +611,7 @@ release_async_put_domains(struct i915_power_domains *power_domains,
|
||||
{
|
||||
struct drm_i915_private *dev_priv =
|
||||
container_of(power_domains, struct drm_i915_private,
|
||||
power_domains);
|
||||
display.power.domains);
|
||||
struct intel_runtime_pm *rpm = &dev_priv->runtime_pm;
|
||||
enum intel_display_power_domain domain;
|
||||
intel_wakeref_t wakeref;
|
||||
@ -638,8 +638,8 @@ intel_display_power_put_async_work(struct work_struct *work)
|
||||
{
|
||||
struct drm_i915_private *dev_priv =
|
||||
container_of(work, struct drm_i915_private,
|
||||
power_domains.async_put_work.work);
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
display.power.domains.async_put_work.work);
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
struct intel_runtime_pm *rpm = &dev_priv->runtime_pm;
|
||||
intel_wakeref_t new_work_wakeref = intel_runtime_pm_get_raw(rpm);
|
||||
intel_wakeref_t old_work_wakeref = 0;
|
||||
@ -699,7 +699,7 @@ void __intel_display_power_put_async(struct drm_i915_private *i915,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &i915->power_domains;
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
struct intel_runtime_pm *rpm = &i915->runtime_pm;
|
||||
intel_wakeref_t work_wakeref = intel_runtime_pm_get_raw(rpm);
|
||||
|
||||
@ -747,7 +747,7 @@ out_verify:
|
||||
*/
|
||||
void intel_display_power_flush_work(struct drm_i915_private *i915)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &i915->power_domains;
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
struct intel_power_domain_mask async_put_mask;
|
||||
intel_wakeref_t work_wakeref;
|
||||
|
||||
@ -780,7 +780,7 @@ out_verify:
|
||||
static void
|
||||
intel_display_power_flush_work_sync(struct drm_i915_private *i915)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &i915->power_domains;
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
|
||||
intel_display_power_flush_work(i915);
|
||||
cancel_delayed_work_sync(&power_domains->async_put_work);
|
||||
@ -977,7 +977,7 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
|
||||
*/
|
||||
int intel_power_domains_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
|
||||
dev_priv->params.disable_power_well =
|
||||
sanitize_disable_power_well_option(dev_priv,
|
||||
@ -1004,12 +1004,12 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
|
||||
*/
|
||||
void intel_power_domains_cleanup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
intel_display_power_map_cleanup(&dev_priv->power_domains);
|
||||
intel_display_power_map_cleanup(&dev_priv->display.power.domains);
|
||||
}
|
||||
|
||||
static void intel_power_domains_sync_hw(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
struct i915_power_well *power_well;
|
||||
|
||||
mutex_lock(&power_domains->lock);
|
||||
@ -1038,7 +1038,7 @@ static void gen9_dbuf_slice_set(struct drm_i915_private *dev_priv,
|
||||
void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv,
|
||||
u8 req_slices)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
u8 slice_mask = INTEL_INFO(dev_priv)->display.dbuf.slice_mask;
|
||||
enum dbuf_slice slice;
|
||||
|
||||
@ -1061,14 +1061,14 @@ void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv,
|
||||
for_each_dbuf_slice(dev_priv, slice)
|
||||
gen9_dbuf_slice_set(dev_priv, slice, req_slices & BIT(slice));
|
||||
|
||||
dev_priv->dbuf.enabled_slices = req_slices;
|
||||
dev_priv->display.dbuf.enabled_slices = req_slices;
|
||||
|
||||
mutex_unlock(&power_domains->lock);
|
||||
}
|
||||
|
||||
static void gen9_dbuf_enable(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
dev_priv->dbuf.enabled_slices =
|
||||
dev_priv->display.dbuf.enabled_slices =
|
||||
intel_enabled_dbuf_slices_mask(dev_priv);
|
||||
|
||||
/*
|
||||
@ -1076,7 +1076,7 @@ static void gen9_dbuf_enable(struct drm_i915_private *dev_priv)
|
||||
* figure out later which slices we have and what we need.
|
||||
*/
|
||||
gen9_dbuf_slices_update(dev_priv, BIT(DBUF_S1) |
|
||||
dev_priv->dbuf.enabled_slices);
|
||||
dev_priv->display.dbuf.enabled_slices);
|
||||
}
|
||||
|
||||
static void gen9_dbuf_disable(struct drm_i915_private *dev_priv)
|
||||
@ -1310,7 +1310,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
|
||||
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
|
||||
|
||||
intel_update_cdclk(dev_priv);
|
||||
intel_cdclk_dump_config(dev_priv, &dev_priv->cdclk.hw, "Current CDCLK");
|
||||
intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "Current CDCLK");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1398,7 +1398,7 @@ static void intel_pch_reset_handshake(struct drm_i915_private *dev_priv,
|
||||
static void skl_display_core_init(struct drm_i915_private *dev_priv,
|
||||
bool resume)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
struct i915_power_well *well;
|
||||
|
||||
gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
|
||||
@ -1430,7 +1430,7 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv,
|
||||
|
||||
static void skl_display_core_uninit(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
struct i915_power_well *well;
|
||||
|
||||
if (!HAS_DISPLAY(dev_priv))
|
||||
@ -1464,7 +1464,7 @@ static void skl_display_core_uninit(struct drm_i915_private *dev_priv)
|
||||
|
||||
static void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
struct i915_power_well *well;
|
||||
|
||||
gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
|
||||
@ -1498,7 +1498,7 @@ static void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume
|
||||
|
||||
static void bxt_display_core_uninit(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
struct i915_power_well *well;
|
||||
|
||||
if (!HAS_DISPLAY(dev_priv))
|
||||
@ -1607,7 +1607,7 @@ static void tgl_bw_buddy_init(struct drm_i915_private *dev_priv)
|
||||
static void icl_display_core_init(struct drm_i915_private *dev_priv,
|
||||
bool resume)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
struct i915_power_well *well;
|
||||
u32 val;
|
||||
|
||||
@ -1674,7 +1674,7 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
|
||||
|
||||
static void icl_display_core_uninit(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
struct i915_power_well *well;
|
||||
|
||||
if (!HAS_DISPLAY(dev_priv))
|
||||
@ -1719,7 +1719,7 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv)
|
||||
* power well state and lane status to reconstruct the
|
||||
* expected initial value.
|
||||
*/
|
||||
dev_priv->chv_phy_control =
|
||||
dev_priv->display.power.chv_phy_control =
|
||||
PHY_LDO_SEQ_DELAY(PHY_LDO_DELAY_600NS, DPIO_PHY0) |
|
||||
PHY_LDO_SEQ_DELAY(PHY_LDO_DELAY_600NS, DPIO_PHY1) |
|
||||
PHY_CH_POWER_MODE(PHY_CH_DEEP_PSR, DPIO_PHY0, DPIO_CH0) |
|
||||
@ -1741,27 +1741,27 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv)
|
||||
if (mask == 0xf)
|
||||
mask = 0x0;
|
||||
else
|
||||
dev_priv->chv_phy_control |=
|
||||
dev_priv->display.power.chv_phy_control |=
|
||||
PHY_CH_POWER_DOWN_OVRD_EN(DPIO_PHY0, DPIO_CH0);
|
||||
|
||||
dev_priv->chv_phy_control |=
|
||||
dev_priv->display.power.chv_phy_control |=
|
||||
PHY_CH_POWER_DOWN_OVRD(mask, DPIO_PHY0, DPIO_CH0);
|
||||
|
||||
mask = (status & DPLL_PORTC_READY_MASK) >> 4;
|
||||
if (mask == 0xf)
|
||||
mask = 0x0;
|
||||
else
|
||||
dev_priv->chv_phy_control |=
|
||||
dev_priv->display.power.chv_phy_control |=
|
||||
PHY_CH_POWER_DOWN_OVRD_EN(DPIO_PHY0, DPIO_CH1);
|
||||
|
||||
dev_priv->chv_phy_control |=
|
||||
dev_priv->display.power.chv_phy_control |=
|
||||
PHY_CH_POWER_DOWN_OVRD(mask, DPIO_PHY0, DPIO_CH1);
|
||||
|
||||
dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(DPIO_PHY0);
|
||||
dev_priv->display.power.chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(DPIO_PHY0);
|
||||
|
||||
dev_priv->chv_phy_assert[DPIO_PHY0] = false;
|
||||
dev_priv->display.power.chv_phy_assert[DPIO_PHY0] = false;
|
||||
} else {
|
||||
dev_priv->chv_phy_assert[DPIO_PHY0] = true;
|
||||
dev_priv->display.power.chv_phy_assert[DPIO_PHY0] = true;
|
||||
}
|
||||
|
||||
if (intel_power_well_is_enabled(dev_priv, cmn_d)) {
|
||||
@ -1773,21 +1773,21 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv)
|
||||
if (mask == 0xf)
|
||||
mask = 0x0;
|
||||
else
|
||||
dev_priv->chv_phy_control |=
|
||||
dev_priv->display.power.chv_phy_control |=
|
||||
PHY_CH_POWER_DOWN_OVRD_EN(DPIO_PHY1, DPIO_CH0);
|
||||
|
||||
dev_priv->chv_phy_control |=
|
||||
dev_priv->display.power.chv_phy_control |=
|
||||
PHY_CH_POWER_DOWN_OVRD(mask, DPIO_PHY1, DPIO_CH0);
|
||||
|
||||
dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(DPIO_PHY1);
|
||||
dev_priv->display.power.chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(DPIO_PHY1);
|
||||
|
||||
dev_priv->chv_phy_assert[DPIO_PHY1] = false;
|
||||
dev_priv->display.power.chv_phy_assert[DPIO_PHY1] = false;
|
||||
} else {
|
||||
dev_priv->chv_phy_assert[DPIO_PHY1] = true;
|
||||
dev_priv->display.power.chv_phy_assert[DPIO_PHY1] = true;
|
||||
}
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "Initial PHY_CONTROL=0x%08x\n",
|
||||
dev_priv->chv_phy_control);
|
||||
dev_priv->display.power.chv_phy_control);
|
||||
|
||||
/* Defer application of initial phy_control to enabling the powerwell */
|
||||
}
|
||||
@ -1871,7 +1871,7 @@ static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv);
|
||||
*/
|
||||
void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &i915->power_domains;
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
|
||||
power_domains->initializing = true;
|
||||
|
||||
@ -1912,8 +1912,8 @@ void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume)
|
||||
/* Disable power support if the user asked so. */
|
||||
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);
|
||||
i915->display.power.domains.disable_wakeref = intel_display_power_get(i915,
|
||||
POWER_DOMAIN_INIT);
|
||||
}
|
||||
intel_power_domains_sync_hw(i915);
|
||||
|
||||
@ -1934,12 +1934,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.init_wakeref);
|
||||
fetch_and_zero(&i915->display.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(i915, POWER_DOMAIN_INIT,
|
||||
fetch_and_zero(&i915->power_domains.disable_wakeref));
|
||||
fetch_and_zero(&i915->display.power.domains.disable_wakeref));
|
||||
|
||||
intel_display_power_flush_work_sync(i915);
|
||||
|
||||
@ -1961,7 +1961,7 @@ void intel_power_domains_driver_remove(struct drm_i915_private *i915)
|
||||
*/
|
||||
void intel_power_domains_sanitize_state(struct drm_i915_private *i915)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &i915->power_domains;
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
struct i915_power_well *power_well;
|
||||
|
||||
mutex_lock(&power_domains->lock);
|
||||
@ -1995,7 +1995,7 @@ void intel_power_domains_sanitize_state(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.init_wakeref);
|
||||
fetch_and_zero(&i915->display.power.domains.init_wakeref);
|
||||
|
||||
intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref);
|
||||
intel_power_domains_verify_state(i915);
|
||||
@ -2010,7 +2010,7 @@ void intel_power_domains_enable(struct drm_i915_private *i915)
|
||||
*/
|
||||
void intel_power_domains_disable(struct drm_i915_private *i915)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &i915->power_domains;
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
|
||||
drm_WARN_ON(&i915->drm, power_domains->init_wakeref);
|
||||
power_domains->init_wakeref =
|
||||
@ -2033,7 +2033,7 @@ void intel_power_domains_disable(struct drm_i915_private *i915)
|
||||
void intel_power_domains_suspend(struct drm_i915_private *i915,
|
||||
enum i915_drm_suspend_mode suspend_mode)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &i915->power_domains;
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
intel_wakeref_t wakeref __maybe_unused =
|
||||
fetch_and_zero(&power_domains->init_wakeref);
|
||||
|
||||
@ -2060,7 +2060,7 @@ void intel_power_domains_suspend(struct drm_i915_private *i915,
|
||||
*/
|
||||
if (!i915->params.disable_power_well)
|
||||
intel_display_power_put(i915, POWER_DOMAIN_INIT,
|
||||
fetch_and_zero(&i915->power_domains.disable_wakeref));
|
||||
fetch_and_zero(&i915->display.power.domains.disable_wakeref));
|
||||
|
||||
intel_display_power_flush_work(i915);
|
||||
intel_power_domains_verify_state(i915);
|
||||
@ -2087,7 +2087,7 @@ void intel_power_domains_suspend(struct drm_i915_private *i915,
|
||||
*/
|
||||
void intel_power_domains_resume(struct drm_i915_private *i915)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &i915->power_domains;
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
|
||||
if (power_domains->display_core_suspended) {
|
||||
intel_power_domains_init_hw(i915, true);
|
||||
@ -2105,7 +2105,7 @@ void intel_power_domains_resume(struct drm_i915_private *i915)
|
||||
|
||||
static void intel_power_domains_dump_info(struct drm_i915_private *i915)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &i915->power_domains;
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
struct i915_power_well *power_well;
|
||||
|
||||
for_each_power_well(i915, power_well) {
|
||||
@ -2133,7 +2133,7 @@ static void intel_power_domains_dump_info(struct drm_i915_private *i915)
|
||||
*/
|
||||
static void intel_power_domains_verify_state(struct drm_i915_private *i915)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &i915->power_domains;
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
struct i915_power_well *power_well;
|
||||
bool dump_domain_info;
|
||||
|
||||
@ -2259,7 +2259,7 @@ void intel_display_power_resume(struct drm_i915_private *i915)
|
||||
|
||||
void intel_display_power_debug(struct drm_i915_private *i915, struct seq_file *m)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &i915->power_domains;
|
||||
struct i915_power_domains *power_domains = &i915->display.power.domains;
|
||||
int i;
|
||||
|
||||
mutex_lock(&power_domains->lock);
|
||||
|
@ -1350,6 +1350,117 @@ static const struct i915_power_well_desc_list xelpd_power_wells[] = {
|
||||
I915_PW_DESCRIPTORS(xelpd_power_wells_main),
|
||||
};
|
||||
|
||||
/*
|
||||
* MTL is based on XELPD power domains with the exception of power gating for:
|
||||
* - DDI_IO (moved to PLL logic)
|
||||
* - AUX and AUX_IO functionality and register access for USBC1-4 (PICA always-on)
|
||||
*/
|
||||
#define XELPDP_PW_2_POWER_DOMAINS \
|
||||
XELPD_PW_B_POWER_DOMAINS, \
|
||||
XELPD_PW_C_POWER_DOMAINS, \
|
||||
XELPD_PW_D_POWER_DOMAINS, \
|
||||
POWER_DOMAIN_AUDIO_PLAYBACK, \
|
||||
POWER_DOMAIN_VGA, \
|
||||
POWER_DOMAIN_PORT_DDI_LANES_TC1, \
|
||||
POWER_DOMAIN_PORT_DDI_LANES_TC2, \
|
||||
POWER_DOMAIN_PORT_DDI_LANES_TC3, \
|
||||
POWER_DOMAIN_PORT_DDI_LANES_TC4
|
||||
|
||||
I915_DECL_PW_DOMAINS(xelpdp_pwdoms_pw_2,
|
||||
XELPDP_PW_2_POWER_DOMAINS,
|
||||
POWER_DOMAIN_INIT);
|
||||
|
||||
I915_DECL_PW_DOMAINS(xelpdp_pwdoms_dc_off,
|
||||
XELPDP_PW_2_POWER_DOMAINS,
|
||||
POWER_DOMAIN_AUDIO_MMIO,
|
||||
POWER_DOMAIN_MODESET,
|
||||
POWER_DOMAIN_AUX_A,
|
||||
POWER_DOMAIN_AUX_B,
|
||||
POWER_DOMAIN_INIT);
|
||||
|
||||
I915_DECL_PW_DOMAINS(xelpdp_pwdoms_aux_tc1,
|
||||
POWER_DOMAIN_AUX_USBC1,
|
||||
POWER_DOMAIN_AUX_TBT1);
|
||||
|
||||
I915_DECL_PW_DOMAINS(xelpdp_pwdoms_aux_tc2,
|
||||
POWER_DOMAIN_AUX_USBC2,
|
||||
POWER_DOMAIN_AUX_TBT2);
|
||||
|
||||
I915_DECL_PW_DOMAINS(xelpdp_pwdoms_aux_tc3,
|
||||
POWER_DOMAIN_AUX_USBC3,
|
||||
POWER_DOMAIN_AUX_TBT3);
|
||||
|
||||
I915_DECL_PW_DOMAINS(xelpdp_pwdoms_aux_tc4,
|
||||
POWER_DOMAIN_AUX_USBC4,
|
||||
POWER_DOMAIN_AUX_TBT4);
|
||||
|
||||
static const struct i915_power_well_desc xelpdp_power_wells_main[] = {
|
||||
{
|
||||
.instances = &I915_PW_INSTANCES(
|
||||
I915_PW("DC_off", &xelpdp_pwdoms_dc_off,
|
||||
.id = SKL_DISP_DC_OFF),
|
||||
),
|
||||
.ops = &gen9_dc_off_power_well_ops,
|
||||
}, {
|
||||
.instances = &I915_PW_INSTANCES(
|
||||
I915_PW("PW_2", &xelpdp_pwdoms_pw_2,
|
||||
.hsw.idx = ICL_PW_CTL_IDX_PW_2,
|
||||
.id = SKL_DISP_PW_2),
|
||||
),
|
||||
.ops = &hsw_power_well_ops,
|
||||
.has_vga = true,
|
||||
.has_fuses = true,
|
||||
}, {
|
||||
.instances = &I915_PW_INSTANCES(
|
||||
I915_PW("PW_A", &xelpd_pwdoms_pw_a,
|
||||
.hsw.idx = XELPD_PW_CTL_IDX_PW_A),
|
||||
),
|
||||
.ops = &hsw_power_well_ops,
|
||||
.irq_pipe_mask = BIT(PIPE_A),
|
||||
.has_fuses = true,
|
||||
}, {
|
||||
.instances = &I915_PW_INSTANCES(
|
||||
I915_PW("PW_B", &xelpd_pwdoms_pw_b,
|
||||
.hsw.idx = XELPD_PW_CTL_IDX_PW_B),
|
||||
),
|
||||
.ops = &hsw_power_well_ops,
|
||||
.irq_pipe_mask = BIT(PIPE_B),
|
||||
.has_fuses = true,
|
||||
}, {
|
||||
.instances = &I915_PW_INSTANCES(
|
||||
I915_PW("PW_C", &xelpd_pwdoms_pw_c,
|
||||
.hsw.idx = XELPD_PW_CTL_IDX_PW_C),
|
||||
),
|
||||
.ops = &hsw_power_well_ops,
|
||||
.irq_pipe_mask = BIT(PIPE_C),
|
||||
.has_fuses = true,
|
||||
}, {
|
||||
.instances = &I915_PW_INSTANCES(
|
||||
I915_PW("PW_D", &xelpd_pwdoms_pw_d,
|
||||
.hsw.idx = XELPD_PW_CTL_IDX_PW_D),
|
||||
),
|
||||
.ops = &hsw_power_well_ops,
|
||||
.irq_pipe_mask = BIT(PIPE_D),
|
||||
.has_fuses = true,
|
||||
}, {
|
||||
.instances = &I915_PW_INSTANCES(
|
||||
I915_PW("AUX_A", &icl_pwdoms_aux_a, .xelpdp.aux_ch = AUX_CH_A),
|
||||
I915_PW("AUX_B", &icl_pwdoms_aux_b, .xelpdp.aux_ch = AUX_CH_B),
|
||||
I915_PW("AUX_TC1", &xelpdp_pwdoms_aux_tc1, .xelpdp.aux_ch = AUX_CH_USBC1),
|
||||
I915_PW("AUX_TC2", &xelpdp_pwdoms_aux_tc2, .xelpdp.aux_ch = AUX_CH_USBC2),
|
||||
I915_PW("AUX_TC3", &xelpdp_pwdoms_aux_tc3, .xelpdp.aux_ch = AUX_CH_USBC3),
|
||||
I915_PW("AUX_TC4", &xelpdp_pwdoms_aux_tc4, .xelpdp.aux_ch = AUX_CH_USBC4),
|
||||
),
|
||||
.ops = &xelpdp_aux_power_well_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct i915_power_well_desc_list xelpdp_power_wells[] = {
|
||||
I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
|
||||
I915_PW_DESCRIPTORS(icl_power_wells_pw_1),
|
||||
I915_PW_DESCRIPTORS(xelpdp_power_wells_main),
|
||||
};
|
||||
|
||||
static void init_power_well_domains(const struct i915_power_well_instance *inst,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
@ -1388,7 +1499,7 @@ __set_power_wells(struct i915_power_domains *power_domains,
|
||||
{
|
||||
struct drm_i915_private *i915 = container_of(power_domains,
|
||||
struct drm_i915_private,
|
||||
power_domains);
|
||||
display.power.domains);
|
||||
u64 power_well_ids = 0;
|
||||
const struct i915_power_well_desc_list *desc_list;
|
||||
const struct i915_power_well_desc *desc;
|
||||
@ -1447,7 +1558,7 @@ 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,
|
||||
power_domains);
|
||||
display.power.domains);
|
||||
/*
|
||||
* The enabling order will be from lower to higher indexed wells,
|
||||
* the disabling order is reversed.
|
||||
@ -1457,7 +1568,9 @@ int intel_display_power_map_init(struct i915_power_domains *power_domains)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(i915) >= 13)
|
||||
if (DISPLAY_VER(i915) >= 14)
|
||||
return set_power_wells(power_domains, xelpdp_power_wells);
|
||||
else if (DISPLAY_VER(i915) >= 13)
|
||||
return set_power_wells(power_domains, xelpd_power_wells);
|
||||
else if (IS_DG1(i915))
|
||||
return set_power_wells(power_domains, dg1_power_wells);
|
||||
|
@ -17,10 +17,10 @@
|
||||
#include "intel_dpll.h"
|
||||
#include "intel_hotplug.h"
|
||||
#include "intel_pcode.h"
|
||||
#include "intel_pm.h"
|
||||
#include "intel_pps.h"
|
||||
#include "intel_tc.h"
|
||||
#include "intel_vga.h"
|
||||
#include "skl_watermark.h"
|
||||
#include "vlv_sideband.h"
|
||||
#include "vlv_sideband_reg.h"
|
||||
|
||||
@ -85,7 +85,7 @@ lookup_power_well(struct drm_i915_private *i915,
|
||||
drm_WARN(&i915->drm, 1,
|
||||
"Power well %d not defined for this platform\n",
|
||||
power_well_id);
|
||||
return &i915->power_domains.power_wells[0];
|
||||
return &i915->display.power.domains.power_wells[0];
|
||||
}
|
||||
|
||||
void intel_power_well_enable(struct drm_i915_private *i915,
|
||||
@ -946,7 +946,7 @@ static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv,
|
||||
static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u8 hw_enabled_dbuf_slices = intel_enabled_dbuf_slices_mask(dev_priv);
|
||||
u8 enabled_dbuf_slices = dev_priv->dbuf.enabled_slices;
|
||||
u8 enabled_dbuf_slices = dev_priv->display.dbuf.enabled_slices;
|
||||
|
||||
drm_WARN(&dev_priv->drm,
|
||||
hw_enabled_dbuf_slices != enabled_dbuf_slices,
|
||||
@ -972,7 +972,7 @@ void gen9_disable_dc_states(struct drm_i915_private *dev_priv)
|
||||
intel_cdclk_get_cdclk(dev_priv, &cdclk_config);
|
||||
/* Can't read out voltage_level so can't use intel_cdclk_changed() */
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
intel_cdclk_needs_modeset(&dev_priv->cdclk.hw,
|
||||
intel_cdclk_needs_modeset(&dev_priv->display.cdclk.hw,
|
||||
&cdclk_config));
|
||||
|
||||
gen9_assert_dbuf_enabled(dev_priv);
|
||||
@ -1157,10 +1157,10 @@ static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv)
|
||||
* (and never recovering) in this case. intel_dsi_post_disable() will
|
||||
* clear it when we turn off the display.
|
||||
*/
|
||||
val = intel_de_read(dev_priv, DSPCLK_GATE_D);
|
||||
val = intel_de_read(dev_priv, DSPCLK_GATE_D(dev_priv));
|
||||
val &= DPOUNIT_CLOCK_GATE_DISABLE;
|
||||
val |= VRHUNIT_CLOCK_GATE_DISABLE;
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D, val);
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D(dev_priv), val);
|
||||
|
||||
/*
|
||||
* Disable trickle feed and enable pnd deadline calculation
|
||||
@ -1208,7 +1208,7 @@ static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)
|
||||
* During driver initialization/resume we can avoid restoring the
|
||||
* part of the HW/SW state that will be inited anyway explicitly.
|
||||
*/
|
||||
if (dev_priv->power_domains.initializing)
|
||||
if (dev_priv->display.power.domains.initializing)
|
||||
return;
|
||||
|
||||
intel_hpd_init(dev_priv);
|
||||
@ -1303,7 +1303,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
|
||||
lookup_power_well(dev_priv, VLV_DISP_PW_DPIO_CMN_BC);
|
||||
struct i915_power_well *cmn_d =
|
||||
lookup_power_well(dev_priv, CHV_DISP_PW_DPIO_CMN_D);
|
||||
u32 phy_control = dev_priv->chv_phy_control;
|
||||
u32 phy_control = dev_priv->display.power.chv_phy_control;
|
||||
u32 phy_status = 0;
|
||||
u32 phy_status_mask = 0xffffffff;
|
||||
|
||||
@ -1314,7 +1314,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
|
||||
* reset (ie. the power well has been disabled at
|
||||
* least once).
|
||||
*/
|
||||
if (!dev_priv->chv_phy_assert[DPIO_PHY0])
|
||||
if (!dev_priv->display.power.chv_phy_assert[DPIO_PHY0])
|
||||
phy_status_mask &= ~(PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH0) |
|
||||
PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH0, 0) |
|
||||
PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH0, 1) |
|
||||
@ -1322,7 +1322,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
|
||||
PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 0) |
|
||||
PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 1));
|
||||
|
||||
if (!dev_priv->chv_phy_assert[DPIO_PHY1])
|
||||
if (!dev_priv->display.power.chv_phy_assert[DPIO_PHY1])
|
||||
phy_status_mask &= ~(PHY_STATUS_CMN_LDO(DPIO_PHY1, DPIO_CH0) |
|
||||
PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 0) |
|
||||
PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 1));
|
||||
@ -1398,7 +1398,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
|
||||
drm_err(&dev_priv->drm,
|
||||
"Unexpected PHY_STATUS 0x%08x, expected 0x%08x (PHY_CONTROL=0x%08x)\n",
|
||||
intel_de_read(dev_priv, DISPLAY_PHY_STATUS) & phy_status_mask,
|
||||
phy_status, dev_priv->chv_phy_control);
|
||||
phy_status, dev_priv->display.power.chv_phy_control);
|
||||
}
|
||||
|
||||
#undef BITS_SET
|
||||
@ -1458,13 +1458,13 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
|
||||
|
||||
vlv_dpio_put(dev_priv);
|
||||
|
||||
dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(phy);
|
||||
dev_priv->display.power.chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(phy);
|
||||
intel_de_write(dev_priv, DISPLAY_PHY_CONTROL,
|
||||
dev_priv->chv_phy_control);
|
||||
dev_priv->display.power.chv_phy_control);
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Enabled DPIO PHY%d (PHY_CONTROL=0x%08x)\n",
|
||||
phy, dev_priv->chv_phy_control);
|
||||
phy, dev_priv->display.power.chv_phy_control);
|
||||
|
||||
assert_chv_phy_status(dev_priv);
|
||||
}
|
||||
@ -1488,18 +1488,18 @@ static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
|
||||
assert_pll_disabled(dev_priv, PIPE_C);
|
||||
}
|
||||
|
||||
dev_priv->chv_phy_control &= ~PHY_COM_LANE_RESET_DEASSERT(phy);
|
||||
dev_priv->display.power.chv_phy_control &= ~PHY_COM_LANE_RESET_DEASSERT(phy);
|
||||
intel_de_write(dev_priv, DISPLAY_PHY_CONTROL,
|
||||
dev_priv->chv_phy_control);
|
||||
dev_priv->display.power.chv_phy_control);
|
||||
|
||||
vlv_set_power_well(dev_priv, power_well, false);
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Disabled DPIO PHY%d (PHY_CONTROL=0x%08x)\n",
|
||||
phy, dev_priv->chv_phy_control);
|
||||
phy, dev_priv->display.power.chv_phy_control);
|
||||
|
||||
/* PHY is fully reset now, so we can enable the PHY state asserts */
|
||||
dev_priv->chv_phy_assert[phy] = true;
|
||||
dev_priv->display.power.chv_phy_assert[phy] = true;
|
||||
|
||||
assert_chv_phy_status(dev_priv);
|
||||
}
|
||||
@ -1517,7 +1517,7 @@ static void assert_chv_phy_powergate(struct drm_i915_private *dev_priv, enum dpi
|
||||
* reset (ie. the power well has been disabled at
|
||||
* least once).
|
||||
*/
|
||||
if (!dev_priv->chv_phy_assert[phy])
|
||||
if (!dev_priv->display.power.chv_phy_assert[phy])
|
||||
return;
|
||||
|
||||
if (ch == DPIO_CH0)
|
||||
@ -1571,27 +1571,27 @@ static void assert_chv_phy_powergate(struct drm_i915_private *dev_priv, enum dpi
|
||||
bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
|
||||
enum dpio_channel ch, bool override)
|
||||
{
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
bool was_override;
|
||||
|
||||
mutex_lock(&power_domains->lock);
|
||||
|
||||
was_override = dev_priv->chv_phy_control & PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
|
||||
was_override = dev_priv->display.power.chv_phy_control & PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
|
||||
|
||||
if (override == was_override)
|
||||
goto out;
|
||||
|
||||
if (override)
|
||||
dev_priv->chv_phy_control |= PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
|
||||
dev_priv->display.power.chv_phy_control |= PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
|
||||
else
|
||||
dev_priv->chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
|
||||
dev_priv->display.power.chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
|
||||
|
||||
intel_de_write(dev_priv, DISPLAY_PHY_CONTROL,
|
||||
dev_priv->chv_phy_control);
|
||||
dev_priv->display.power.chv_phy_control);
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Power gating DPIO PHY%d CH%d (DPIO_PHY_CONTROL=0x%08x)\n",
|
||||
phy, ch, dev_priv->chv_phy_control);
|
||||
phy, ch, dev_priv->display.power.chv_phy_control);
|
||||
|
||||
assert_chv_phy_status(dev_priv);
|
||||
|
||||
@ -1605,26 +1605,26 @@ void chv_phy_powergate_lanes(struct intel_encoder *encoder,
|
||||
bool override, unsigned int mask)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct i915_power_domains *power_domains = &dev_priv->power_domains;
|
||||
struct i915_power_domains *power_domains = &dev_priv->display.power.domains;
|
||||
enum dpio_phy phy = vlv_dig_port_to_phy(enc_to_dig_port(encoder));
|
||||
enum dpio_channel ch = vlv_dig_port_to_channel(enc_to_dig_port(encoder));
|
||||
|
||||
mutex_lock(&power_domains->lock);
|
||||
|
||||
dev_priv->chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD(0xf, phy, ch);
|
||||
dev_priv->chv_phy_control |= PHY_CH_POWER_DOWN_OVRD(mask, phy, ch);
|
||||
dev_priv->display.power.chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD(0xf, phy, ch);
|
||||
dev_priv->display.power.chv_phy_control |= PHY_CH_POWER_DOWN_OVRD(mask, phy, ch);
|
||||
|
||||
if (override)
|
||||
dev_priv->chv_phy_control |= PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
|
||||
dev_priv->display.power.chv_phy_control |= PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
|
||||
else
|
||||
dev_priv->chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
|
||||
dev_priv->display.power.chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
|
||||
|
||||
intel_de_write(dev_priv, DISPLAY_PHY_CONTROL,
|
||||
dev_priv->chv_phy_control);
|
||||
dev_priv->display.power.chv_phy_control);
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Power gating DPIO PHY%d CH%d lanes 0x%x (PHY_CONTROL=0x%08x)\n",
|
||||
phy, ch, mask, dev_priv->chv_phy_control);
|
||||
phy, ch, mask, dev_priv->display.power.chv_phy_control);
|
||||
|
||||
assert_chv_phy_status(dev_priv);
|
||||
|
||||
@ -1702,7 +1702,7 @@ static void chv_pipe_power_well_sync_hw(struct drm_i915_private *dev_priv,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
intel_de_write(dev_priv, DISPLAY_PHY_CONTROL,
|
||||
dev_priv->chv_phy_control);
|
||||
dev_priv->display.power.chv_phy_control);
|
||||
}
|
||||
|
||||
static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv,
|
||||
@ -1798,6 +1798,43 @@ tgl_tc_cold_off_power_well_is_enabled(struct drm_i915_private *dev_priv,
|
||||
return intel_power_well_refcount(power_well);
|
||||
}
|
||||
|
||||
static void xelpdp_aux_power_well_enable(struct drm_i915_private *dev_priv,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;
|
||||
|
||||
intel_de_rmw(dev_priv, XELPDP_DP_AUX_CH_CTL(aux_ch),
|
||||
XELPDP_DP_AUX_CH_CTL_POWER_REQUEST,
|
||||
XELPDP_DP_AUX_CH_CTL_POWER_REQUEST);
|
||||
|
||||
/*
|
||||
* The power status flag cannot be used to determine whether aux
|
||||
* power wells have finished powering up. Instead we're
|
||||
* expected to just wait a fixed 600us after raising the request
|
||||
* bit.
|
||||
*/
|
||||
usleep_range(600, 1200);
|
||||
}
|
||||
|
||||
static void xelpdp_aux_power_well_disable(struct drm_i915_private *dev_priv,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;
|
||||
|
||||
intel_de_rmw(dev_priv, XELPDP_DP_AUX_CH_CTL(aux_ch),
|
||||
XELPDP_DP_AUX_CH_CTL_POWER_REQUEST,
|
||||
0);
|
||||
usleep_range(10, 30);
|
||||
}
|
||||
|
||||
static bool xelpdp_aux_power_well_enabled(struct drm_i915_private *dev_priv,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;
|
||||
|
||||
return intel_de_read(dev_priv, XELPDP_DP_AUX_CH_CTL(aux_ch)) &
|
||||
XELPDP_DP_AUX_CH_CTL_POWER_STATUS;
|
||||
}
|
||||
|
||||
const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
|
||||
.sync_hw = i9xx_power_well_sync_hw_noop,
|
||||
@ -1911,3 +1948,10 @@ const struct i915_power_well_ops tgl_tc_cold_off_ops = {
|
||||
.disable = tgl_tc_cold_off_power_well_disable,
|
||||
.is_enabled = tgl_tc_cold_off_power_well_is_enabled,
|
||||
};
|
||||
|
||||
const struct i915_power_well_ops xelpdp_aux_power_well_ops = {
|
||||
.sync_hw = i9xx_power_well_sync_hw_noop,
|
||||
.enable = xelpdp_aux_power_well_enable,
|
||||
.disable = xelpdp_aux_power_well_disable,
|
||||
.is_enabled = xelpdp_aux_power_well_enabled,
|
||||
};
|
||||
|
@ -14,15 +14,15 @@ struct drm_i915_private;
|
||||
struct i915_power_well;
|
||||
|
||||
#define for_each_power_well(__dev_priv, __power_well) \
|
||||
for ((__power_well) = (__dev_priv)->power_domains.power_wells; \
|
||||
(__power_well) - (__dev_priv)->power_domains.power_wells < \
|
||||
(__dev_priv)->power_domains.power_well_count; \
|
||||
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; \
|
||||
(__power_well)++)
|
||||
|
||||
#define for_each_power_well_reverse(__dev_priv, __power_well) \
|
||||
for ((__power_well) = (__dev_priv)->power_domains.power_wells + \
|
||||
(__dev_priv)->power_domains.power_well_count - 1; \
|
||||
(__power_well) - (__dev_priv)->power_domains.power_wells >= 0; \
|
||||
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; \
|
||||
(__power_well)--)
|
||||
|
||||
/*
|
||||
@ -80,6 +80,9 @@ struct i915_power_well_instance {
|
||||
*/
|
||||
u8 idx;
|
||||
} hsw;
|
||||
struct {
|
||||
u8 aux_ch;
|
||||
} xelpdp;
|
||||
};
|
||||
};
|
||||
|
||||
@ -169,5 +172,6 @@ extern const struct i915_power_well_ops vlv_dpio_power_well_ops;
|
||||
extern const struct i915_power_well_ops icl_aux_power_well_ops;
|
||||
extern const struct i915_power_well_ops icl_ddi_power_well_ops;
|
||||
extern const struct i915_power_well_ops tgl_tc_cold_off_ops;
|
||||
extern const struct i915_power_well_ops xelpdp_aux_power_well_ops;
|
||||
|
||||
#endif
|
||||
|
@ -1130,6 +1130,7 @@ struct intel_crtc_state {
|
||||
/* m2_n2 for eDP downclock */
|
||||
struct intel_link_m_n dp_m2_n2;
|
||||
bool has_drrs;
|
||||
bool seamless_m_n;
|
||||
|
||||
/* PSR is supported but might not be enabled due the lack of enabled planes */
|
||||
bool has_psr;
|
||||
@ -1712,7 +1713,7 @@ struct intel_dp {
|
||||
|
||||
/* Display stream compression testing */
|
||||
bool force_dsc_en;
|
||||
int force_dsc_bpp;
|
||||
int force_dsc_bpc;
|
||||
|
||||
bool hobl_failed;
|
||||
bool hobl_active;
|
||||
|
@ -286,11 +286,22 @@ static int intel_dp_max_common_rate(struct intel_dp *intel_dp)
|
||||
return intel_dp_common_rate(intel_dp, intel_dp->num_common_rates - 1);
|
||||
}
|
||||
|
||||
static int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port)
|
||||
{
|
||||
int vbt_max_lanes = intel_bios_dp_max_lane_count(&dig_port->base);
|
||||
int max_lanes = dig_port->max_lanes;
|
||||
|
||||
if (vbt_max_lanes)
|
||||
max_lanes = min(max_lanes, vbt_max_lanes);
|
||||
|
||||
return max_lanes;
|
||||
}
|
||||
|
||||
/* Theoretical max between source and sink */
|
||||
static int intel_dp_max_common_lane_count(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
int source_max = dig_port->max_lanes;
|
||||
int source_max = intel_dp_max_source_lane_count(dig_port);
|
||||
int sink_max = intel_dp->max_sink_lane_count;
|
||||
int fia_max = intel_tc_port_fia_max_lane_count(dig_port);
|
||||
int lttpr_max = drm_dp_lttpr_max_lane_count(intel_dp->lttpr_common_caps);
|
||||
@ -389,23 +400,13 @@ static int dg2_max_source_rate(struct intel_dp *intel_dp)
|
||||
return intel_dp_is_edp(intel_dp) ? 810000 : 1350000;
|
||||
}
|
||||
|
||||
static bool is_low_voltage_sku(struct drm_i915_private *i915, enum phy phy)
|
||||
{
|
||||
u32 voltage;
|
||||
|
||||
voltage = intel_de_read(i915, ICL_PORT_COMP_DW3(phy)) & VOLTAGE_INFO_MASK;
|
||||
|
||||
return voltage == VOLTAGE_INFO_0_85V;
|
||||
}
|
||||
|
||||
static int icl_max_source_rate(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
|
||||
enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
|
||||
|
||||
if (intel_phy_is_combo(dev_priv, phy) &&
|
||||
(is_low_voltage_sku(dev_priv, phy) || !intel_dp_is_edp(intel_dp)))
|
||||
if (intel_phy_is_combo(dev_priv, phy) && !intel_dp_is_edp(intel_dp))
|
||||
return 540000;
|
||||
|
||||
return 810000;
|
||||
@ -413,23 +414,7 @@ static int icl_max_source_rate(struct intel_dp *intel_dp)
|
||||
|
||||
static int ehl_max_source_rate(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
|
||||
enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
|
||||
|
||||
if (intel_dp_is_edp(intel_dp) || is_low_voltage_sku(dev_priv, phy))
|
||||
return 540000;
|
||||
|
||||
return 810000;
|
||||
}
|
||||
|
||||
static int dg1_max_source_rate(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
|
||||
enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
|
||||
|
||||
if (intel_phy_is_combo(i915, phy) && is_low_voltage_sku(i915, phy))
|
||||
if (intel_dp_is_edp(intel_dp))
|
||||
return 540000;
|
||||
|
||||
return 810000;
|
||||
@ -491,7 +476,7 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
|
||||
max_rate = dg2_max_source_rate(intel_dp);
|
||||
else if (IS_ALDERLAKE_P(dev_priv) || IS_ALDERLAKE_S(dev_priv) ||
|
||||
IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
|
||||
max_rate = dg1_max_source_rate(intel_dp);
|
||||
max_rate = 810000;
|
||||
else if (IS_JSL_EHL(dev_priv))
|
||||
max_rate = ehl_max_source_rate(intel_dp);
|
||||
else
|
||||
@ -720,7 +705,7 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
|
||||
|
||||
if (bigjoiner) {
|
||||
u32 max_bpp_bigjoiner =
|
||||
i915->max_cdclk_freq * 48 /
|
||||
i915->display.cdclk.max_cdclk_freq * 48 /
|
||||
intel_dp_mode_to_fec_clock(mode_clock);
|
||||
|
||||
bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
|
||||
@ -1312,21 +1297,45 @@ intel_dp_adjust_compliance_config(struct intel_dp *intel_dp,
|
||||
}
|
||||
}
|
||||
|
||||
static bool has_seamless_m_n(struct intel_connector *connector)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
|
||||
/*
|
||||
* Seamless M/N reprogramming only implemented
|
||||
* for BDW+ double buffered M/N registers so far.
|
||||
*/
|
||||
return HAS_DOUBLE_BUFFERED_M_N(i915) &&
|
||||
intel_panel_drrs_type(connector) == DRRS_TYPE_SEAMLESS;
|
||||
}
|
||||
|
||||
static int intel_dp_mode_clock(const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_connector *connector = to_intel_connector(conn_state->connector);
|
||||
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
|
||||
|
||||
/* FIXME a bit of a mess wrt clock vs. crtc_clock */
|
||||
if (has_seamless_m_n(connector))
|
||||
return intel_panel_highest_mode(connector, adjusted_mode)->clock;
|
||||
else
|
||||
return adjusted_mode->crtc_clock;
|
||||
}
|
||||
|
||||
/* Optimize link config in order: max bpp, min clock, min lanes */
|
||||
static int
|
||||
intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
const struct drm_connector_state *conn_state,
|
||||
const struct link_config_limits *limits)
|
||||
{
|
||||
struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
|
||||
int bpp, i, lane_count;
|
||||
int bpp, i, lane_count, clock = intel_dp_mode_clock(pipe_config, conn_state);
|
||||
int mode_rate, link_rate, link_avail;
|
||||
|
||||
for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) {
|
||||
int output_bpp = intel_dp_output_bpp(pipe_config->output_format, bpp);
|
||||
|
||||
mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
|
||||
output_bpp);
|
||||
mode_rate = intel_dp_link_required(clock, output_bpp);
|
||||
|
||||
for (i = 0; i < intel_dp->num_common_rates; i++) {
|
||||
link_rate = intel_dp_common_rate(intel_dp, i);
|
||||
@ -1406,6 +1415,7 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder,
|
||||
* DP_DSC_RC_BUF_SIZE for this.
|
||||
*/
|
||||
vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST;
|
||||
vdsc_cfg->pic_height = crtc_state->hw.adjusted_mode.crtc_vdisplay;
|
||||
|
||||
/*
|
||||
* Slice Height of 8 works for all currently available panels. So start
|
||||
@ -1474,6 +1484,11 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
||||
|
||||
pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc);
|
||||
|
||||
if (intel_dp->force_dsc_bpc) {
|
||||
pipe_bpp = intel_dp->force_dsc_bpc * 3;
|
||||
drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d", pipe_bpp);
|
||||
}
|
||||
|
||||
/* Min Input BPC for ICL+ is 8 */
|
||||
if (pipe_bpp < 8 * 3) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
@ -1525,28 +1540,12 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
||||
pipe_config->dsc.slice_count = dsc_dp_slice_count;
|
||||
}
|
||||
|
||||
/* As of today we support DSC for only RGB */
|
||||
if (intel_dp->force_dsc_bpp) {
|
||||
if (intel_dp->force_dsc_bpp >= 8 &&
|
||||
intel_dp->force_dsc_bpp < pipe_bpp) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"DSC BPP forced to %d",
|
||||
intel_dp->force_dsc_bpp);
|
||||
pipe_config->dsc.compressed_bpp =
|
||||
intel_dp->force_dsc_bpp;
|
||||
} else {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Invalid DSC BPP %d",
|
||||
intel_dp->force_dsc_bpp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* VDSC engine operates at 1 Pixel per clock, so if peak pixel rate
|
||||
* is greater than the maximum Cdclock and if slice count is even
|
||||
* then we need to use 2 VDSC instances.
|
||||
*/
|
||||
if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq ||
|
||||
if (adjusted_mode->crtc_clock > dev_priv->display.cdclk.max_cdclk_freq ||
|
||||
pipe_config->bigjoiner_pipes) {
|
||||
if (pipe_config->dsc.slice_count < 2) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
@ -1636,7 +1635,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
|
||||
* Optimize for slow and wide for everything, because there are some
|
||||
* eDP 1.3 and 1.4 panels don't work well with fast and narrow.
|
||||
*/
|
||||
ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits);
|
||||
ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, conn_state, &limits);
|
||||
|
||||
if (ret || joiner_needs_dsc || intel_dp->force_dsc_en) {
|
||||
drm_dbg_kms(&i915->drm, "Try DSC (fallback=%s, joiner=%s, force=%s)\n",
|
||||
@ -1879,8 +1878,7 @@ intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
|
||||
static bool cpu_transcoder_has_drrs(struct drm_i915_private *i915,
|
||||
enum transcoder cpu_transcoder)
|
||||
{
|
||||
/* M1/N1 is double buffered */
|
||||
if (DISPLAY_VER(i915) >= 9 || IS_BROADWELL(i915))
|
||||
if (HAS_DOUBLE_BUFFERED_M_N(i915))
|
||||
return true;
|
||||
|
||||
return intel_cpu_transcoder_has_m2_n2(i915, cpu_transcoder);
|
||||
@ -1918,13 +1916,16 @@ static bool can_enable_drrs(struct intel_connector *connector,
|
||||
static void
|
||||
intel_dp_drrs_compute_config(struct intel_connector *connector,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
int output_bpp, bool constant_n)
|
||||
int output_bpp)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
const struct drm_display_mode *downclock_mode =
|
||||
intel_panel_downclock_mode(connector, &pipe_config->hw.adjusted_mode);
|
||||
int pixel_clock;
|
||||
|
||||
if (has_seamless_m_n(connector))
|
||||
pipe_config->seamless_m_n = true;
|
||||
|
||||
if (!can_enable_drrs(connector, pipe_config, downclock_mode)) {
|
||||
if (intel_cpu_transcoder_has_m2_n2(i915, pipe_config->cpu_transcoder))
|
||||
intel_zero_m_n(&pipe_config->dp_m2_n2);
|
||||
@ -1942,7 +1943,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector,
|
||||
|
||||
intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock,
|
||||
pipe_config->port_clock, &pipe_config->dp_m2_n2,
|
||||
constant_n, pipe_config->fec_enable);
|
||||
pipe_config->fec_enable);
|
||||
|
||||
/* FIXME: abstract this better */
|
||||
if (pipe_config->splitter.enable)
|
||||
@ -2017,7 +2018,6 @@ intel_dp_compute_config(struct intel_encoder *encoder,
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
const struct drm_display_mode *fixed_mode;
|
||||
struct intel_connector *connector = intel_dp->attached_connector;
|
||||
bool constant_n = drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_CONSTANT_N);
|
||||
int ret = 0, output_bpp;
|
||||
|
||||
if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && encoder->port != PORT_A)
|
||||
@ -2096,7 +2096,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
|
||||
adjusted_mode->crtc_clock,
|
||||
pipe_config->port_clock,
|
||||
&pipe_config->dp_m_n,
|
||||
constant_n, pipe_config->fec_enable);
|
||||
pipe_config->fec_enable);
|
||||
|
||||
/* FIXME: abstract this better */
|
||||
if (pipe_config->splitter.enable)
|
||||
@ -2107,8 +2107,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
|
||||
|
||||
intel_vrr_compute_config(pipe_config, conn_state);
|
||||
intel_psr_compute_config(intel_dp, pipe_config, conn_state);
|
||||
intel_dp_drrs_compute_config(connector, pipe_config,
|
||||
output_bpp, constant_n);
|
||||
intel_dp_drrs_compute_config(connector, pipe_config, output_bpp);
|
||||
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
|
||||
intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state);
|
||||
|
||||
@ -5202,7 +5201,7 @@ intel_edp_add_properties(struct intel_dp *intel_dp)
|
||||
return;
|
||||
|
||||
drm_connector_set_panel_orientation_with_quirk(&connector->base,
|
||||
i915->vbt.orientation,
|
||||
i915->display.vbt.orientation,
|
||||
fixed_mode->hdisplay,
|
||||
fixed_mode->vdisplay);
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ static u32 ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
|
||||
* divide by 2000 and use that
|
||||
*/
|
||||
if (dig_port->aux_ch == AUX_CH_A)
|
||||
freq = dev_priv->cdclk.hw.cdclk;
|
||||
freq = dev_priv->display.cdclk.hw.cdclk;
|
||||
else
|
||||
freq = RUNTIME_INFO(dev_priv)->rawclk_freq;
|
||||
return DIV_ROUND_CLOSEST(freq, 2000);
|
||||
@ -150,6 +150,7 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp,
|
||||
u32 unused)
|
||||
{
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
|
||||
u32 ret;
|
||||
|
||||
/*
|
||||
@ -170,6 +171,13 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp,
|
||||
if (intel_tc_port_in_tbt_alt_mode(dig_port))
|
||||
ret |= DP_AUX_CH_CTL_TBT_IO;
|
||||
|
||||
/*
|
||||
* Power request bit is already set during aux power well enable.
|
||||
* Preserve the bit across aux transactions.
|
||||
*/
|
||||
if (DISPLAY_VER(i915) >= 14)
|
||||
ret |= XELPDP_DP_AUX_CH_CTL_POWER_REQUEST;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -629,6 +637,46 @@ static i915_reg_t tgl_aux_data_reg(struct intel_dp *intel_dp, int index)
|
||||
}
|
||||
}
|
||||
|
||||
static i915_reg_t xelpdp_aux_ctl_reg(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
enum aux_ch aux_ch = dig_port->aux_ch;
|
||||
|
||||
switch (aux_ch) {
|
||||
case AUX_CH_A:
|
||||
case AUX_CH_B:
|
||||
case AUX_CH_USBC1:
|
||||
case AUX_CH_USBC2:
|
||||
case AUX_CH_USBC3:
|
||||
case AUX_CH_USBC4:
|
||||
return XELPDP_DP_AUX_CH_CTL(aux_ch);
|
||||
default:
|
||||
MISSING_CASE(aux_ch);
|
||||
return XELPDP_DP_AUX_CH_CTL(AUX_CH_A);
|
||||
}
|
||||
}
|
||||
|
||||
static i915_reg_t xelpdp_aux_data_reg(struct intel_dp *intel_dp, int index)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
enum aux_ch aux_ch = dig_port->aux_ch;
|
||||
|
||||
switch (aux_ch) {
|
||||
case AUX_CH_A:
|
||||
case AUX_CH_B:
|
||||
case AUX_CH_USBC1:
|
||||
case AUX_CH_USBC2:
|
||||
case AUX_CH_USBC3:
|
||||
case AUX_CH_USBC4:
|
||||
return XELPDP_DP_AUX_CH_DATA(aux_ch, index);
|
||||
default:
|
||||
MISSING_CASE(aux_ch);
|
||||
return XELPDP_DP_AUX_CH_DATA(AUX_CH_A, index);
|
||||
}
|
||||
}
|
||||
|
||||
void intel_dp_aux_fini(struct intel_dp *intel_dp)
|
||||
{
|
||||
if (cpu_latency_qos_request_active(&intel_dp->pm_qos))
|
||||
@ -644,7 +692,10 @@ void intel_dp_aux_init(struct intel_dp *intel_dp)
|
||||
struct intel_encoder *encoder = &dig_port->base;
|
||||
enum aux_ch aux_ch = dig_port->aux_ch;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 12) {
|
||||
if (DISPLAY_VER(dev_priv) >= 14) {
|
||||
intel_dp->aux_ch_ctl_reg = xelpdp_aux_ctl_reg;
|
||||
intel_dp->aux_ch_data_reg = xelpdp_aux_data_reg;
|
||||
} else if (DISPLAY_VER(dev_priv) >= 12) {
|
||||
intel_dp->aux_ch_ctl_reg = tgl_aux_ctl_reg;
|
||||
intel_dp->aux_ch_data_reg = tgl_aux_data_reg;
|
||||
} else if (DISPLAY_VER(dev_priv) >= 9) {
|
||||
|
@ -37,17 +37,6 @@ static void intel_dp_reset_lttpr_count(struct intel_dp *intel_dp)
|
||||
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV] = 0;
|
||||
}
|
||||
|
||||
static const char *intel_dp_phy_name(enum drm_dp_phy dp_phy,
|
||||
char *buf, size_t buf_size)
|
||||
{
|
||||
if (dp_phy == DP_PHY_DPRX)
|
||||
snprintf(buf, buf_size, "DPRX");
|
||||
else
|
||||
snprintf(buf, buf_size, "LTTPR %d", dp_phy - DP_PHY_LTTPR1 + 1);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static u8 *intel_dp_lttpr_phy_caps(struct intel_dp *intel_dp,
|
||||
enum drm_dp_phy dp_phy)
|
||||
{
|
||||
@ -60,20 +49,19 @@ static void intel_dp_read_lttpr_phy_caps(struct intel_dp *intel_dp,
|
||||
{
|
||||
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
|
||||
u8 *phy_caps = intel_dp_lttpr_phy_caps(intel_dp, dp_phy);
|
||||
char phy_name[10];
|
||||
|
||||
intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name));
|
||||
|
||||
if (drm_dp_read_lttpr_phy_caps(&intel_dp->aux, dpcd, dp_phy, phy_caps) < 0) {
|
||||
drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
|
||||
"[ENCODER:%d:%s][%s] failed to read the PHY caps\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy));
|
||||
return;
|
||||
}
|
||||
|
||||
drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
|
||||
"[ENCODER:%d:%s][%s] PHY capabilities: %*ph\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name,
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy),
|
||||
(int)sizeof(intel_dp->lttpr_phy_caps[0]),
|
||||
phy_caps);
|
||||
}
|
||||
@ -423,14 +411,13 @@ intel_dp_get_adjust_train(struct intel_dp *intel_dp,
|
||||
{
|
||||
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
char phy_name[10];
|
||||
int lane;
|
||||
|
||||
if (intel_dp_is_uhbr(crtc_state)) {
|
||||
drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s][%s] 128b/132b, lanes: %d, "
|
||||
"TX FFE request: " TRAIN_REQ_FMT "\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name)),
|
||||
drm_dp_phy_name(dp_phy),
|
||||
crtc_state->lane_count,
|
||||
TRAIN_REQ_TX_FFE_ARGS(link_status));
|
||||
} else {
|
||||
@ -438,7 +425,7 @@ intel_dp_get_adjust_train(struct intel_dp *intel_dp,
|
||||
"vswing request: " TRAIN_REQ_FMT ", "
|
||||
"pre-emphasis request: " TRAIN_REQ_FMT "\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name)),
|
||||
drm_dp_phy_name(dp_phy),
|
||||
crtc_state->lane_count,
|
||||
TRAIN_REQ_VSWING_ARGS(link_status),
|
||||
TRAIN_REQ_PREEMPH_ARGS(link_status));
|
||||
@ -503,13 +490,12 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
|
||||
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
u8 train_pat = intel_dp_training_pattern_symbol(dp_train_pat);
|
||||
char phy_name[10];
|
||||
|
||||
if (train_pat != DP_TRAINING_PATTERN_DISABLE)
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] Using DP training pattern TPS%c\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name)),
|
||||
drm_dp_phy_name(dp_phy),
|
||||
dp_training_pattern_name(train_pat));
|
||||
|
||||
intel_dp->set_link_train(intel_dp, crtc_state, dp_train_pat);
|
||||
@ -546,13 +532,12 @@ void intel_dp_set_signal_levels(struct intel_dp *intel_dp,
|
||||
{
|
||||
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
char phy_name[10];
|
||||
|
||||
if (intel_dp_is_uhbr(crtc_state)) {
|
||||
drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s][%s] 128b/132b, lanes: %d, "
|
||||
"TX FFE presets: " TRAIN_SET_FMT "\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name)),
|
||||
drm_dp_phy_name(dp_phy),
|
||||
crtc_state->lane_count,
|
||||
TRAIN_SET_TX_FFE_ARGS(intel_dp->train_set));
|
||||
} else {
|
||||
@ -560,7 +545,7 @@ void intel_dp_set_signal_levels(struct intel_dp *intel_dp,
|
||||
"vswing levels: " TRAIN_SET_FMT ", "
|
||||
"pre-emphasis levels: " TRAIN_SET_FMT "\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name)),
|
||||
drm_dp_phy_name(dp_phy),
|
||||
crtc_state->lane_count,
|
||||
TRAIN_SET_VSWING_ARGS(intel_dp->train_set),
|
||||
TRAIN_SET_PREEMPH_ARGS(intel_dp->train_set));
|
||||
@ -671,6 +656,28 @@ intel_dp_prepare_link_train(struct intel_dp *intel_dp,
|
||||
intel_dp_compute_rate(intel_dp, crtc_state->port_clock,
|
||||
&link_bw, &rate_select);
|
||||
|
||||
/*
|
||||
* WaEdpLinkRateDataReload
|
||||
*
|
||||
* Parade PS8461E MUX (used on varius TGL+ laptops) needs
|
||||
* to snoop the link rates reported by the sink when we
|
||||
* use LINK_RATE_SET in order to operate in jitter cleaning
|
||||
* mode (as opposed to redriver mode). Unfortunately it
|
||||
* loses track of the snooped link rates when powered down,
|
||||
* so we need to make it re-snoop often. Without this high
|
||||
* link rates are not stable.
|
||||
*/
|
||||
if (!link_bw) {
|
||||
struct intel_connector *connector = intel_dp->attached_connector;
|
||||
__le16 sink_rates[DP_MAX_SUPPORTED_RATES];
|
||||
|
||||
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] Reloading eDP link rates\n",
|
||||
connector->base.base.id, connector->base.name);
|
||||
|
||||
drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES,
|
||||
sink_rates, sizeof(sink_rates));
|
||||
}
|
||||
|
||||
if (link_bw)
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[ENCODER:%d:%s] Using LINK_BW_SET value %02x\n",
|
||||
@ -732,12 +739,11 @@ intel_dp_dump_link_status(struct intel_dp *intel_dp, enum drm_dp_phy dp_phy,
|
||||
{
|
||||
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
char phy_name[10];
|
||||
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] ln0_1:0x%x ln2_3:0x%x align:0x%x sink:0x%x adj_req0_1:0x%x adj_req2_3:0x%x\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name)),
|
||||
drm_dp_phy_name(dp_phy),
|
||||
link_status[0], link_status[1], link_status[2],
|
||||
link_status[3], link_status[4], link_status[5]);
|
||||
}
|
||||
@ -757,21 +763,19 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
|
||||
int voltage_tries, cr_tries, max_cr_tries;
|
||||
u8 link_status[DP_LINK_STATUS_SIZE];
|
||||
bool max_vswing_reached = false;
|
||||
char phy_name[10];
|
||||
int delay_us;
|
||||
|
||||
delay_us = drm_dp_read_clock_recovery_delay(&intel_dp->aux,
|
||||
intel_dp->dpcd, dp_phy,
|
||||
intel_dp_is_uhbr(crtc_state));
|
||||
|
||||
intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name));
|
||||
|
||||
/* clock recovery */
|
||||
if (!intel_dp_reset_link_train(intel_dp, crtc_state, dp_phy,
|
||||
DP_TRAINING_PATTERN_1 |
|
||||
DP_LINK_SCRAMBLING_DISABLE)) {
|
||||
drm_err(&i915->drm, "[ENCODER:%d:%s][%s] Failed to enable link training\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -795,14 +799,16 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
|
||||
if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, dp_phy,
|
||||
link_status) < 0) {
|
||||
drm_err(&i915->drm, "[ENCODER:%d:%s][%s] Failed to get link status\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (drm_dp_clock_recovery_ok(link_status, crtc_state->lane_count)) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] Clock recovery OK\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -810,7 +816,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
|
||||
intel_dp_dump_link_status(intel_dp, dp_phy, link_status);
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] Same voltage tried 5 times\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -818,7 +825,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
|
||||
intel_dp_dump_link_status(intel_dp, dp_phy, link_status);
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] Max Voltage Swing reached\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -828,7 +836,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
|
||||
if (!intel_dp_update_link_train(intel_dp, crtc_state, dp_phy)) {
|
||||
drm_err(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] Failed to update link training\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -846,7 +855,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp,
|
||||
intel_dp_dump_link_status(intel_dp, dp_phy, link_status);
|
||||
drm_err(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] Failed clock recovery %d times, giving up!\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name, max_cr_tries);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy), max_cr_tries);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -924,15 +934,12 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp,
|
||||
u32 training_pattern;
|
||||
u8 link_status[DP_LINK_STATUS_SIZE];
|
||||
bool channel_eq = false;
|
||||
char phy_name[10];
|
||||
int delay_us;
|
||||
|
||||
delay_us = drm_dp_read_channel_eq_delay(&intel_dp->aux,
|
||||
intel_dp->dpcd, dp_phy,
|
||||
intel_dp_is_uhbr(crtc_state));
|
||||
|
||||
intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name));
|
||||
|
||||
training_pattern = intel_dp_training_pattern(intel_dp, crtc_state, dp_phy);
|
||||
/* Scrambling is disabled for TPS2/3 and enabled for TPS4 */
|
||||
if (training_pattern != DP_TRAINING_PATTERN_4)
|
||||
@ -944,7 +951,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp,
|
||||
drm_err(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] Failed to start channel equalization\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
phy_name);
|
||||
drm_dp_phy_name(dp_phy));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -955,7 +962,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp,
|
||||
link_status) < 0) {
|
||||
drm_err(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] Failed to get link status\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -966,7 +974,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp,
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] Clock recovery check failed, cannot "
|
||||
"continue channel equalization\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -975,7 +984,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp,
|
||||
channel_eq = true;
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] Channel EQ done. DP Training successful\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -985,7 +995,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp,
|
||||
if (!intel_dp_update_link_train(intel_dp, crtc_state, dp_phy)) {
|
||||
drm_err(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] Failed to update link training\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -995,7 +1006,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp,
|
||||
intel_dp_dump_link_status(intel_dp, dp_phy, link_status);
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[ENCODER:%d:%s][%s] Channel equalization failed 5 times\n",
|
||||
encoder->base.base.id, encoder->base.name, phy_name);
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
drm_dp_phy_name(dp_phy));
|
||||
}
|
||||
|
||||
return channel_eq;
|
||||
@ -1070,7 +1082,6 @@ intel_dp_link_train_phy(struct intel_dp *intel_dp,
|
||||
{
|
||||
struct intel_connector *connector = intel_dp->attached_connector;
|
||||
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
|
||||
char phy_name[10];
|
||||
bool ret = false;
|
||||
|
||||
if (!intel_dp_link_training_clock_recovery(intel_dp, crtc_state, dp_phy))
|
||||
@ -1086,7 +1097,7 @@ out:
|
||||
"[CONNECTOR:%d:%s][ENCODER:%d:%s][%s] Link Training %s at link rate = %d, lane count = %d\n",
|
||||
connector->base.base.id, connector->base.name,
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name)),
|
||||
drm_dp_phy_name(dp_phy),
|
||||
ret ? "passed" : "failed",
|
||||
crtc_state->port_clock, crtc_state->lane_count);
|
||||
|
||||
|
@ -58,7 +58,6 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&crtc_state->hw.adjusted_mode;
|
||||
bool constant_n = drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_CONSTANT_N);
|
||||
int bpp, slots = -EINVAL;
|
||||
|
||||
mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr);
|
||||
@ -100,7 +99,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
|
||||
adjusted_mode->crtc_clock,
|
||||
crtc_state->port_clock,
|
||||
&crtc_state->dp_m_n,
|
||||
constant_n, crtc_state->fec_enable);
|
||||
crtc_state->fec_enable);
|
||||
crtc_state->dp_m_n.tu = slots;
|
||||
|
||||
return 0;
|
||||
@ -566,7 +565,10 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
|
||||
drm_dp_add_payload_part2(&intel_dp->mst_mgr, &state->base,
|
||||
drm_atomic_get_mst_payload_state(mst_state, connector->port));
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 12 && pipe_config->fec_enable)
|
||||
if (DISPLAY_VER(dev_priv) >= 14 && pipe_config->fec_enable)
|
||||
intel_de_rmw(dev_priv, MTL_CHICKEN_TRANS(trans), 0,
|
||||
FECSTALL_DIS_DPTSTREAM_DPTTG);
|
||||
else if (DISPLAY_VER(dev_priv) >= 12 && pipe_config->fec_enable)
|
||||
intel_de_rmw(dev_priv, CHICKEN_TRANS(trans), 0,
|
||||
FECSTALL_DIS_DPTSTREAM_DPTTG);
|
||||
|
||||
|
@ -484,7 +484,7 @@ void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy)
|
||||
enum dpio_phy rcomp_phy = phy_info->rcomp_phy;
|
||||
bool was_enabled;
|
||||
|
||||
lockdep_assert_held(&dev_priv->power_domains.lock);
|
||||
lockdep_assert_held(&dev_priv->display.power.domains.lock);
|
||||
|
||||
was_enabled = true;
|
||||
if (rcomp_phy != -1)
|
||||
|
@ -938,12 +938,25 @@ static int hsw_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
struct intel_encoder *encoder =
|
||||
intel_get_crtc_new_encoder(state, crtc_state);
|
||||
int ret;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) < 11 &&
|
||||
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
|
||||
return 0;
|
||||
|
||||
return intel_compute_shared_dplls(state, crtc, encoder);
|
||||
ret = intel_compute_shared_dplls(state, crtc, encoder);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* FIXME this is a mess */
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
|
||||
return 0;
|
||||
|
||||
/* CRT dotclock is determined via other means */
|
||||
if (!crtc_state->has_pch_encoder)
|
||||
crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hsw_crtc_get_shared_dpll(struct intel_atomic_state *state,
|
||||
@ -969,8 +982,15 @@ static int dg2_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
struct intel_encoder *encoder =
|
||||
intel_get_crtc_new_encoder(state, crtc_state);
|
||||
int ret;
|
||||
|
||||
return intel_mpllb_calc_state(crtc_state, encoder);
|
||||
ret = intel_mpllb_calc_state(crtc_state, encoder);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ilk_needs_fb_cb_tune(const struct dpll *dpll, int factor)
|
||||
@ -991,7 +1011,7 @@ static void ilk_update_pll_dividers(struct intel_crtc_state *crtc_state,
|
||||
factor = 21;
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
|
||||
if ((intel_panel_use_ssc(dev_priv) &&
|
||||
dev_priv->vbt.lvds_ssc_freq == 100000) ||
|
||||
dev_priv->display.vbt.lvds_ssc_freq == 100000) ||
|
||||
(HAS_PCH_IBX(dev_priv) &&
|
||||
intel_is_dual_link_lvds(dev_priv)))
|
||||
factor = 25;
|
||||
@ -1096,6 +1116,7 @@ static int ilk_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
const struct intel_limit *limit;
|
||||
int refclk = 120000;
|
||||
int ret;
|
||||
|
||||
/* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
|
||||
if (!crtc_state->has_pch_encoder)
|
||||
@ -1105,8 +1126,8 @@ static int ilk_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
if (intel_panel_use_ssc(dev_priv)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"using SSC reference clock of %d kHz\n",
|
||||
dev_priv->vbt.lvds_ssc_freq);
|
||||
refclk = dev_priv->vbt.lvds_ssc_freq;
|
||||
dev_priv->display.vbt.lvds_ssc_freq);
|
||||
refclk = dev_priv->display.vbt.lvds_ssc_freq;
|
||||
}
|
||||
|
||||
if (intel_is_dual_link_lvds(dev_priv)) {
|
||||
@ -1132,7 +1153,14 @@ static int ilk_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
ilk_compute_dpll(crtc_state, &crtc_state->dpll,
|
||||
&crtc_state->dpll);
|
||||
|
||||
return intel_compute_shared_dplls(state, crtc, NULL);
|
||||
ret = intel_compute_shared_dplls(state, crtc, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
crtc_state->port_clock = crtc_state->dpll.dot;
|
||||
crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ilk_crtc_get_shared_dpll(struct intel_atomic_state *state,
|
||||
@ -1198,6 +1226,13 @@ static int chv_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
|
||||
chv_compute_dpll(crtc_state);
|
||||
|
||||
/* FIXME this is a mess */
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
|
||||
return 0;
|
||||
|
||||
crtc_state->port_clock = crtc_state->dpll.dot;
|
||||
crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1217,6 +1252,13 @@ static int vlv_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
|
||||
vlv_compute_dpll(crtc_state);
|
||||
|
||||
/* FIXME this is a mess */
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
|
||||
return 0;
|
||||
|
||||
crtc_state->port_clock = crtc_state->dpll.dot;
|
||||
crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1231,7 +1273,7 @@ static int g4x_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
|
||||
if (intel_panel_use_ssc(dev_priv)) {
|
||||
refclk = dev_priv->vbt.lvds_ssc_freq;
|
||||
refclk = dev_priv->display.vbt.lvds_ssc_freq;
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"using SSC reference clock of %d kHz\n",
|
||||
refclk);
|
||||
@ -1259,6 +1301,11 @@ static int g4x_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
i9xx_compute_dpll(crtc_state, &crtc_state->dpll,
|
||||
&crtc_state->dpll);
|
||||
|
||||
crtc_state->port_clock = crtc_state->dpll.dot;
|
||||
/* FIXME this is a mess */
|
||||
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_TVOUT))
|
||||
crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1273,7 +1320,7 @@ static int pnv_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
|
||||
if (intel_panel_use_ssc(dev_priv)) {
|
||||
refclk = dev_priv->vbt.lvds_ssc_freq;
|
||||
refclk = dev_priv->display.vbt.lvds_ssc_freq;
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"using SSC reference clock of %d kHz\n",
|
||||
refclk);
|
||||
@ -1292,6 +1339,9 @@ static int pnv_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
i9xx_compute_dpll(crtc_state, &crtc_state->dpll,
|
||||
&crtc_state->dpll);
|
||||
|
||||
crtc_state->port_clock = crtc_state->dpll.dot;
|
||||
crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1306,7 +1356,7 @@ static int i9xx_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
|
||||
if (intel_panel_use_ssc(dev_priv)) {
|
||||
refclk = dev_priv->vbt.lvds_ssc_freq;
|
||||
refclk = dev_priv->display.vbt.lvds_ssc_freq;
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"using SSC reference clock of %d kHz\n",
|
||||
refclk);
|
||||
@ -1325,6 +1375,11 @@ static int i9xx_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
i9xx_compute_dpll(crtc_state, &crtc_state->dpll,
|
||||
&crtc_state->dpll);
|
||||
|
||||
crtc_state->port_clock = crtc_state->dpll.dot;
|
||||
/* FIXME this is a mess */
|
||||
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_TVOUT))
|
||||
crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1339,7 +1394,7 @@ static int i8xx_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
|
||||
if (intel_panel_use_ssc(dev_priv)) {
|
||||
refclk = dev_priv->vbt.lvds_ssc_freq;
|
||||
refclk = dev_priv->display.vbt.lvds_ssc_freq;
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"using SSC reference clock of %d kHz\n",
|
||||
refclk);
|
||||
@ -1360,6 +1415,9 @@ static int i8xx_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
i8xx_compute_dpll(crtc_state, &crtc_state->dpll,
|
||||
&crtc_state->dpll);
|
||||
|
||||
crtc_state->port_clock = crtc_state->dpll.dot;
|
||||
crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1411,9 +1469,6 @@ int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state,
|
||||
|
||||
drm_WARN_ON(&i915->drm, !intel_crtc_needs_modeset(crtc_state));
|
||||
|
||||
if (drm_WARN_ON(&i915->drm, crtc_state->shared_dpll))
|
||||
return 0;
|
||||
|
||||
memset(&crtc_state->dpll_hw_state, 0,
|
||||
sizeof(crtc_state->dpll_hw_state));
|
||||
|
||||
@ -1439,11 +1494,9 @@ int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state,
|
||||
int ret;
|
||||
|
||||
drm_WARN_ON(&i915->drm, !intel_crtc_needs_modeset(crtc_state));
|
||||
drm_WARN_ON(&i915->drm, !crtc_state->hw.enable && crtc_state->shared_dpll);
|
||||
|
||||
if (drm_WARN_ON(&i915->drm, crtc_state->shared_dpll))
|
||||
return 0;
|
||||
|
||||
if (!crtc_state->hw.enable)
|
||||
if (!crtc_state->hw.enable || crtc_state->shared_dpll)
|
||||
return 0;
|
||||
|
||||
if (!i915->display.funcs.dpll->crtc_get_shared_dpll)
|
||||
|
@ -905,37 +905,6 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */,
|
||||
*r2_out = best.r2;
|
||||
}
|
||||
|
||||
static int
|
||||
hsw_ddi_wrpll_compute_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
unsigned int p, n2, r2;
|
||||
|
||||
hsw_ddi_calculate_wrpll(crtc_state->port_clock * 1000, &r2, &n2, &p);
|
||||
|
||||
crtc_state->dpll_hw_state.wrpll =
|
||||
WRPLL_PLL_ENABLE | WRPLL_REF_LCPLL |
|
||||
WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
|
||||
WRPLL_DIVIDER_POST(p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct intel_shared_dpll *
|
||||
hsw_ddi_wrpll_get_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
|
||||
return intel_find_shared_dpll(state, crtc,
|
||||
&crtc_state->dpll_hw_state,
|
||||
BIT(DPLL_ID_WRPLL2) |
|
||||
BIT(DPLL_ID_WRPLL1));
|
||||
}
|
||||
|
||||
static int hsw_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
@ -976,6 +945,41 @@ static int hsw_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
|
||||
return (refclk * n / 10) / (p * r) * 2;
|
||||
}
|
||||
|
||||
static int
|
||||
hsw_ddi_wrpll_compute_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
unsigned int p, n2, r2;
|
||||
|
||||
hsw_ddi_calculate_wrpll(crtc_state->port_clock * 1000, &r2, &n2, &p);
|
||||
|
||||
crtc_state->dpll_hw_state.wrpll =
|
||||
WRPLL_PLL_ENABLE | WRPLL_REF_LCPLL |
|
||||
WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
|
||||
WRPLL_DIVIDER_POST(p);
|
||||
|
||||
crtc_state->port_clock = hsw_ddi_wrpll_get_freq(i915, NULL,
|
||||
&crtc_state->dpll_hw_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct intel_shared_dpll *
|
||||
hsw_ddi_wrpll_get_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
|
||||
return intel_find_shared_dpll(state, crtc,
|
||||
&crtc_state->dpll_hw_state,
|
||||
BIT(DPLL_ID_WRPLL2) |
|
||||
BIT(DPLL_ID_WRPLL1));
|
||||
}
|
||||
|
||||
static int
|
||||
hsw_ddi_lcpll_compute_dpll(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
@ -1618,43 +1622,6 @@ skip_remaining_dividers:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
||||
struct skl_wrpll_params wrpll_params = {};
|
||||
u32 ctrl1, cfgcr1, cfgcr2;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* See comment in intel_dpll_hw_state to understand why we always use 0
|
||||
* as the DPLL id in this function.
|
||||
*/
|
||||
ctrl1 = DPLL_CTRL1_OVERRIDE(0);
|
||||
|
||||
ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
|
||||
|
||||
ret = skl_ddi_calculate_wrpll(crtc_state->port_clock * 1000,
|
||||
i915->display.dpll.ref_clks.nssc, &wrpll_params);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
|
||||
DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
|
||||
wrpll_params.dco_integer;
|
||||
|
||||
cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
|
||||
DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
|
||||
DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
|
||||
DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
|
||||
wrpll_params.central_freq;
|
||||
|
||||
crtc_state->dpll_hw_state.ctrl1 = ctrl1;
|
||||
crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
|
||||
crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
@ -1726,6 +1693,46 @@ static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
|
||||
return dco_freq / (p0 * p1 * p2 * 5);
|
||||
}
|
||||
|
||||
static int skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
||||
struct skl_wrpll_params wrpll_params = {};
|
||||
u32 ctrl1, cfgcr1, cfgcr2;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* See comment in intel_dpll_hw_state to understand why we always use 0
|
||||
* as the DPLL id in this function.
|
||||
*/
|
||||
ctrl1 = DPLL_CTRL1_OVERRIDE(0);
|
||||
|
||||
ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
|
||||
|
||||
ret = skl_ddi_calculate_wrpll(crtc_state->port_clock * 1000,
|
||||
i915->display.dpll.ref_clks.nssc, &wrpll_params);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
|
||||
DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
|
||||
wrpll_params.dco_integer;
|
||||
|
||||
cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
|
||||
DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
|
||||
DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
|
||||
DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
|
||||
wrpll_params.central_freq;
|
||||
|
||||
crtc_state->dpll_hw_state.ctrl1 = ctrl1;
|
||||
crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
|
||||
crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
|
||||
|
||||
crtc_state->port_clock = skl_ddi_wrpll_get_freq(i915, NULL,
|
||||
&crtc_state->dpll_hw_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
skl_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
@ -1858,7 +1865,7 @@ static int skl_ddi_pll_get_freq(struct drm_i915_private *i915,
|
||||
static void skl_update_dpll_ref_clks(struct drm_i915_private *i915)
|
||||
{
|
||||
/* No SSC ref */
|
||||
i915->display.dpll.ref_clks.nssc = i915->cdclk.hw.ref;
|
||||
i915->display.dpll.ref_clks.nssc = i915->display.cdclk.hw.ref;
|
||||
}
|
||||
|
||||
static void skl_dump_hw_state(struct drm_i915_private *dev_priv,
|
||||
@ -2245,26 +2252,6 @@ static int bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bxt_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct dpll clk_div = {};
|
||||
|
||||
bxt_ddi_dp_pll_dividers(crtc_state, &clk_div);
|
||||
|
||||
return bxt_ddi_set_dpll_hw_state(crtc_state, &clk_div);
|
||||
}
|
||||
|
||||
static int
|
||||
bxt_ddi_hdmi_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct dpll clk_div = {};
|
||||
|
||||
bxt_ddi_hdmi_pll_dividers(crtc_state, &clk_div);
|
||||
|
||||
return bxt_ddi_set_dpll_hw_state(crtc_state, &clk_div);
|
||||
}
|
||||
|
||||
static int bxt_ddi_pll_get_freq(struct drm_i915_private *i915,
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *pll_state)
|
||||
@ -2282,6 +2269,35 @@ static int bxt_ddi_pll_get_freq(struct drm_i915_private *i915,
|
||||
return chv_calc_dpll_params(i915->display.dpll.ref_clks.nssc, &clock);
|
||||
}
|
||||
|
||||
static int
|
||||
bxt_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct dpll clk_div = {};
|
||||
|
||||
bxt_ddi_dp_pll_dividers(crtc_state, &clk_div);
|
||||
|
||||
return bxt_ddi_set_dpll_hw_state(crtc_state, &clk_div);
|
||||
}
|
||||
|
||||
static int
|
||||
bxt_ddi_hdmi_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
||||
struct dpll clk_div = {};
|
||||
int ret;
|
||||
|
||||
bxt_ddi_hdmi_pll_dividers(crtc_state, &clk_div);
|
||||
|
||||
ret = bxt_ddi_set_dpll_hw_state(crtc_state, &clk_div);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
crtc_state->port_clock = bxt_ddi_pll_get_freq(i915, NULL,
|
||||
&crtc_state->dpll_hw_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bxt_compute_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc,
|
||||
struct intel_encoder *encoder)
|
||||
@ -2769,8 +2785,8 @@ static void icl_calc_dpll_state(struct drm_i915_private *i915,
|
||||
else
|
||||
pll_state->cfgcr1 |= DPLL_CFGCR1_CENTRAL_FREQ_8400;
|
||||
|
||||
if (i915->vbt.override_afc_startup)
|
||||
pll_state->div0 = TGL_DPLL0_DIV0_AFC_STARTUP(i915->vbt.override_afc_startup_val);
|
||||
if (i915->display.vbt.override_afc_startup)
|
||||
pll_state->div0 = TGL_DPLL0_DIV0_AFC_STARTUP(i915->display.vbt.override_afc_startup_val);
|
||||
}
|
||||
|
||||
static int icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
|
||||
@ -2965,8 +2981,8 @@ static int icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
|
||||
DKL_PLL_DIV0_PROP_COEFF(prop_coeff) |
|
||||
DKL_PLL_DIV0_FBPREDIV(m1div) |
|
||||
DKL_PLL_DIV0_FBDIV_INT(m2div_int);
|
||||
if (dev_priv->vbt.override_afc_startup) {
|
||||
u8 val = dev_priv->vbt.override_afc_startup_val;
|
||||
if (dev_priv->display.vbt.override_afc_startup) {
|
||||
u8 val = dev_priv->display.vbt.override_afc_startup_val;
|
||||
|
||||
pll_state->mg_pll_div0 |= DKL_PLL_DIV0_AFC_STARTUP(val);
|
||||
}
|
||||
@ -3197,6 +3213,12 @@ static int icl_compute_combo_phy_dpll(struct intel_atomic_state *state,
|
||||
|
||||
icl_calc_dpll_state(dev_priv, &pll_params, &port_dpll->hw_state);
|
||||
|
||||
/* this is mainly for the fastset check */
|
||||
icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_DEFAULT);
|
||||
|
||||
crtc_state->port_clock = icl_ddi_combo_pll_get_freq(dev_priv, NULL,
|
||||
&port_dpll->hw_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3282,6 +3304,12 @@ static int icl_compute_tc_phy_dplls(struct intel_atomic_state *state,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* this is mainly for the fastset check */
|
||||
icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_MG_PHY);
|
||||
|
||||
crtc_state->port_clock = icl_ddi_mg_pll_get_freq(dev_priv, NULL,
|
||||
&port_dpll->hw_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3502,7 +3530,7 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv,
|
||||
|
||||
hw_state->mg_pll_div0 = intel_de_read(dev_priv, DKL_PLL_DIV0(tc_port));
|
||||
val = DKL_PLL_DIV0_MASK;
|
||||
if (dev_priv->vbt.override_afc_startup)
|
||||
if (dev_priv->display.vbt.override_afc_startup)
|
||||
val |= DKL_PLL_DIV0_AFC_STARTUP_MASK;
|
||||
hw_state->mg_pll_div0 &= val;
|
||||
|
||||
@ -3566,7 +3594,7 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv,
|
||||
TGL_DPLL_CFGCR0(id));
|
||||
hw_state->cfgcr1 = intel_de_read(dev_priv,
|
||||
TGL_DPLL_CFGCR1(id));
|
||||
if (dev_priv->vbt.override_afc_startup) {
|
||||
if (dev_priv->display.vbt.override_afc_startup) {
|
||||
hw_state->div0 = intel_de_read(dev_priv, TGL_DPLL0_DIV0(id));
|
||||
hw_state->div0 &= TGL_DPLL0_DIV0_AFC_STARTUP_MASK;
|
||||
}
|
||||
@ -3638,9 +3666,9 @@ static void icl_dpll_write(struct drm_i915_private *dev_priv,
|
||||
|
||||
intel_de_write(dev_priv, cfgcr0_reg, hw_state->cfgcr0);
|
||||
intel_de_write(dev_priv, cfgcr1_reg, hw_state->cfgcr1);
|
||||
drm_WARN_ON_ONCE(&dev_priv->drm, dev_priv->vbt.override_afc_startup &&
|
||||
drm_WARN_ON_ONCE(&dev_priv->drm, dev_priv->display.vbt.override_afc_startup &&
|
||||
!i915_mmio_reg_valid(div0_reg));
|
||||
if (dev_priv->vbt.override_afc_startup &&
|
||||
if (dev_priv->display.vbt.override_afc_startup &&
|
||||
i915_mmio_reg_valid(div0_reg))
|
||||
intel_de_rmw(dev_priv, div0_reg, TGL_DPLL0_DIV0_AFC_STARTUP_MASK,
|
||||
hw_state->div0);
|
||||
@ -3732,7 +3760,7 @@ static void dkl_pll_write(struct drm_i915_private *dev_priv,
|
||||
intel_de_write(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), val);
|
||||
|
||||
val = DKL_PLL_DIV0_MASK;
|
||||
if (dev_priv->vbt.override_afc_startup)
|
||||
if (dev_priv->display.vbt.override_afc_startup)
|
||||
val |= DKL_PLL_DIV0_AFC_STARTUP_MASK;
|
||||
intel_de_rmw(dev_priv, DKL_PLL_DIV0(tc_port), val,
|
||||
hw_state->mg_pll_div0);
|
||||
@ -3967,7 +3995,7 @@ static void mg_pll_disable(struct drm_i915_private *dev_priv,
|
||||
static void icl_update_dpll_ref_clks(struct drm_i915_private *i915)
|
||||
{
|
||||
/* No SSC ref */
|
||||
i915->display.dpll.ref_clks.nssc = i915->cdclk.hw.ref;
|
||||
i915->display.dpll.ref_clks.nssc = i915->display.cdclk.hw.ref;
|
||||
}
|
||||
|
||||
static void icl_dump_hw_state(struct drm_i915_private *dev_priv,
|
||||
@ -4199,6 +4227,10 @@ void intel_shared_dpll_init(struct drm_i915_private *dev_priv)
|
||||
dpll_info = dpll_mgr->dpll_info;
|
||||
|
||||
for (i = 0; dpll_info[i].name; i++) {
|
||||
if (drm_WARN_ON(&dev_priv->drm,
|
||||
i >= ARRAY_SIZE(dev_priv->display.dpll.shared_dplls)))
|
||||
break;
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, i != dpll_info[i].id);
|
||||
dev_priv->display.dpll.shared_dplls[i].info = &dpll_info[i];
|
||||
}
|
||||
@ -4206,8 +4238,6 @@ void intel_shared_dpll_init(struct drm_i915_private *dev_priv)
|
||||
dev_priv->display.dpll.mgr = dpll_mgr;
|
||||
dev_priv->display.dpll.num_shared_dpll = i;
|
||||
mutex_init(&dev_priv->display.dpll.lock);
|
||||
|
||||
BUG_ON(dev_priv->display.dpll.num_shared_dpll > I915_NUM_PLLS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9,6 +9,36 @@
|
||||
#include "i915_drv.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dsb.h"
|
||||
|
||||
struct i915_vma;
|
||||
|
||||
enum dsb_id {
|
||||
INVALID_DSB = -1,
|
||||
DSB1,
|
||||
DSB2,
|
||||
DSB3,
|
||||
MAX_DSB_PER_PIPE
|
||||
};
|
||||
|
||||
struct intel_dsb {
|
||||
enum dsb_id id;
|
||||
u32 *cmd_buf;
|
||||
struct i915_vma *vma;
|
||||
|
||||
/*
|
||||
* free_pos will point the first free entry position
|
||||
* and help in calculating tail of command buffer.
|
||||
*/
|
||||
int free_pos;
|
||||
|
||||
/*
|
||||
* ins_start_offset will help to store start address of the dsb
|
||||
* instuction and help in identifying the batch of auto-increment
|
||||
* register.
|
||||
*/
|
||||
u32 ins_start_offset;
|
||||
};
|
||||
|
||||
#define DSB_BUF_SIZE (2 * PAGE_SIZE)
|
||||
|
||||
|
@ -11,34 +11,6 @@
|
||||
#include "i915_reg_defs.h"
|
||||
|
||||
struct intel_crtc_state;
|
||||
struct i915_vma;
|
||||
|
||||
enum dsb_id {
|
||||
INVALID_DSB = -1,
|
||||
DSB1,
|
||||
DSB2,
|
||||
DSB3,
|
||||
MAX_DSB_PER_PIPE
|
||||
};
|
||||
|
||||
struct intel_dsb {
|
||||
enum dsb_id id;
|
||||
u32 *cmd_buf;
|
||||
struct i915_vma *vma;
|
||||
|
||||
/*
|
||||
* free_pos will point the first free entry position
|
||||
* and help in calculating tail of command buffer.
|
||||
*/
|
||||
int free_pos;
|
||||
|
||||
/*
|
||||
* ins_start_offset will help to store start address of the dsb
|
||||
* instuction and help in identifying the batch of auto-increment
|
||||
* register.
|
||||
*/
|
||||
u32 ins_start_offset;
|
||||
};
|
||||
|
||||
void intel_dsb_prepare(struct intel_crtc_state *crtc_state);
|
||||
void intel_dsb_cleanup(struct intel_crtc_state *crtc_state);
|
||||
|
@ -106,7 +106,7 @@ intel_dsi_get_panel_orientation(struct intel_connector *connector)
|
||||
if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
|
||||
return orientation;
|
||||
|
||||
orientation = dev_priv->vbt.orientation;
|
||||
orientation = dev_priv->display.vbt.orientation;
|
||||
if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
|
||||
return orientation;
|
||||
|
||||
|
@ -75,8 +75,8 @@ struct intel_dvo_dev_ops {
|
||||
*
|
||||
* \return MODE_OK if the mode is valid, or another MODE_* otherwise.
|
||||
*/
|
||||
int (*mode_valid)(struct intel_dvo_device *dvo,
|
||||
struct drm_display_mode *mode);
|
||||
enum drm_mode_status (*mode_valid)(struct intel_dvo_device *dvo,
|
||||
struct drm_display_mode *mode);
|
||||
|
||||
/*
|
||||
* Callback for preparing mode changes on an output
|
||||
|
@ -59,7 +59,7 @@
|
||||
|
||||
#define for_each_intel_fbc(__dev_priv, __fbc, __fbc_id) \
|
||||
for_each_fbc_id((__dev_priv), (__fbc_id)) \
|
||||
for_each_if((__fbc) = (__dev_priv)->fbc[(__fbc_id)])
|
||||
for_each_if((__fbc) = (__dev_priv)->display.fbc[(__fbc_id)])
|
||||
|
||||
struct intel_fbc_funcs {
|
||||
void (*activate)(struct intel_fbc *fbc);
|
||||
@ -1720,7 +1720,7 @@ void intel_fbc_init(struct drm_i915_private *i915)
|
||||
i915->params.enable_fbc);
|
||||
|
||||
for_each_fbc_id(i915, fbc_id)
|
||||
i915->fbc[fbc_id] = intel_fbc_create(i915, fbc_id);
|
||||
i915->display.fbc[fbc_id] = intel_fbc_create(i915, fbc_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1840,7 +1840,7 @@ void intel_fbc_debugfs_register(struct drm_i915_private *i915)
|
||||
struct drm_minor *minor = i915->drm.primary;
|
||||
struct intel_fbc *fbc;
|
||||
|
||||
fbc = i915->fbc[INTEL_FBC_A];
|
||||
fbc = i915->display.fbc[INTEL_FBC_A];
|
||||
if (fbc)
|
||||
intel_fbc_debugfs_add(fbc, minor->debugfs_root);
|
||||
}
|
||||
|
@ -210,6 +210,12 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
||||
struct drm_i915_gem_object *obj;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ifbdev->hpd_lock);
|
||||
ret = ifbdev->hpd_suspended ? -EAGAIN : 0;
|
||||
mutex_unlock(&ifbdev->hpd_lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (intel_fb &&
|
||||
(sizes->fb_width > intel_fb->base.width ||
|
||||
sizes->fb_height > intel_fb->base.height)) {
|
||||
@ -573,7 +579,8 @@ void intel_fbdev_unregister(struct drm_i915_private *dev_priv)
|
||||
if (!ifbdev)
|
||||
return;
|
||||
|
||||
cancel_work_sync(&dev_priv->display.fbdev.suspend_work);
|
||||
intel_fbdev_set_suspend(&dev_priv->drm, FBINFO_STATE_SUSPENDED, true);
|
||||
|
||||
if (!current_is_async())
|
||||
intel_fbdev_sync(ifbdev);
|
||||
|
||||
@ -618,7 +625,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
|
||||
struct fb_info *info;
|
||||
|
||||
if (!ifbdev || !ifbdev->vma)
|
||||
return;
|
||||
goto set_suspend;
|
||||
|
||||
info = ifbdev->helper.fbdev;
|
||||
|
||||
@ -661,6 +668,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
|
||||
drm_fb_helper_set_suspend(&ifbdev->helper, state);
|
||||
console_unlock();
|
||||
|
||||
set_suspend:
|
||||
intel_fbdev_hpd_set_suspend(dev_priv, state);
|
||||
}
|
||||
|
||||
|
@ -210,14 +210,14 @@ void intel_fdi_pll_freq_update(struct drm_i915_private *i915)
|
||||
u32 fdi_pll_clk =
|
||||
intel_de_read(i915, FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK;
|
||||
|
||||
i915->fdi_pll_freq = (fdi_pll_clk + 2) * 10000;
|
||||
i915->display.fdi.pll_freq = (fdi_pll_clk + 2) * 10000;
|
||||
} else if (IS_SANDYBRIDGE(i915) || IS_IVYBRIDGE(i915)) {
|
||||
i915->fdi_pll_freq = 270000;
|
||||
i915->display.fdi.pll_freq = 270000;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
drm_dbg(&i915->drm, "FDI PLL freq=%d\n", i915->fdi_pll_freq);
|
||||
drm_dbg(&i915->drm, "FDI PLL freq=%d\n", i915->display.fdi.pll_freq);
|
||||
}
|
||||
|
||||
int intel_fdi_link_freq(struct drm_i915_private *i915,
|
||||
@ -226,7 +226,7 @@ int intel_fdi_link_freq(struct drm_i915_private *i915,
|
||||
if (HAS_DDI(i915))
|
||||
return pipe_config->port_clock; /* SPLL */
|
||||
else
|
||||
return i915->fdi_pll_freq;
|
||||
return i915->display.fdi.pll_freq;
|
||||
}
|
||||
|
||||
int ilk_fdi_compute_config(struct intel_crtc *crtc,
|
||||
@ -256,7 +256,7 @@ retry:
|
||||
pipe_config->fdi_lanes = lane;
|
||||
|
||||
intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
|
||||
link_bw, &pipe_config->fdi_m_n, false, false);
|
||||
link_bw, &pipe_config->fdi_m_n, false);
|
||||
|
||||
ret = ilk_check_fdi_lanes(dev, crtc->pipe, pipe_config);
|
||||
if (ret == -EDEADLK)
|
||||
@ -789,7 +789,7 @@ void hsw_fdi_link_train(struct intel_encoder *encoder,
|
||||
FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2) | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
|
||||
|
||||
/* Enable the PCH Receiver FDI PLL */
|
||||
rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
|
||||
rx_ctl_val = dev_priv->display.fdi.rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
|
||||
FDI_RX_PLL_ENABLE |
|
||||
FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
|
||||
intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
|
||||
|
@ -81,9 +81,9 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
|
||||
enum fb_op_origin origin)
|
||||
{
|
||||
/* Delay flushing when rings are still busy.*/
|
||||
spin_lock(&i915->fb_tracking.lock);
|
||||
frontbuffer_bits &= ~i915->fb_tracking.busy_bits;
|
||||
spin_unlock(&i915->fb_tracking.lock);
|
||||
spin_lock(&i915->display.fb_tracking.lock);
|
||||
frontbuffer_bits &= ~i915->display.fb_tracking.busy_bits;
|
||||
spin_unlock(&i915->display.fb_tracking.lock);
|
||||
|
||||
if (!frontbuffer_bits)
|
||||
return;
|
||||
@ -111,11 +111,11 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
|
||||
void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
|
||||
unsigned frontbuffer_bits)
|
||||
{
|
||||
spin_lock(&i915->fb_tracking.lock);
|
||||
i915->fb_tracking.flip_bits |= frontbuffer_bits;
|
||||
spin_lock(&i915->display.fb_tracking.lock);
|
||||
i915->display.fb_tracking.flip_bits |= frontbuffer_bits;
|
||||
/* Remove stale busy bits due to the old buffer. */
|
||||
i915->fb_tracking.busy_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&i915->fb_tracking.lock);
|
||||
i915->display.fb_tracking.busy_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&i915->display.fb_tracking.lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -131,11 +131,11 @@ void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
|
||||
void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
|
||||
unsigned frontbuffer_bits)
|
||||
{
|
||||
spin_lock(&i915->fb_tracking.lock);
|
||||
spin_lock(&i915->display.fb_tracking.lock);
|
||||
/* Mask any cancelled flips. */
|
||||
frontbuffer_bits &= i915->fb_tracking.flip_bits;
|
||||
i915->fb_tracking.flip_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&i915->fb_tracking.lock);
|
||||
frontbuffer_bits &= i915->display.fb_tracking.flip_bits;
|
||||
i915->display.fb_tracking.flip_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&i915->display.fb_tracking.lock);
|
||||
|
||||
if (frontbuffer_bits)
|
||||
frontbuffer_flush(i915, frontbuffer_bits, ORIGIN_FLIP);
|
||||
@ -155,10 +155,10 @@ void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
|
||||
void intel_frontbuffer_flip(struct drm_i915_private *i915,
|
||||
unsigned frontbuffer_bits)
|
||||
{
|
||||
spin_lock(&i915->fb_tracking.lock);
|
||||
spin_lock(&i915->display.fb_tracking.lock);
|
||||
/* Remove stale busy bits due to the old buffer. */
|
||||
i915->fb_tracking.busy_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&i915->fb_tracking.lock);
|
||||
i915->display.fb_tracking.busy_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&i915->display.fb_tracking.lock);
|
||||
|
||||
frontbuffer_flush(i915, frontbuffer_bits, ORIGIN_FLIP);
|
||||
}
|
||||
@ -170,10 +170,10 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
|
||||
struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
|
||||
|
||||
if (origin == ORIGIN_CS) {
|
||||
spin_lock(&i915->fb_tracking.lock);
|
||||
i915->fb_tracking.busy_bits |= frontbuffer_bits;
|
||||
i915->fb_tracking.flip_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&i915->fb_tracking.lock);
|
||||
spin_lock(&i915->display.fb_tracking.lock);
|
||||
i915->display.fb_tracking.busy_bits |= frontbuffer_bits;
|
||||
i915->display.fb_tracking.flip_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&i915->display.fb_tracking.lock);
|
||||
}
|
||||
|
||||
trace_intel_frontbuffer_invalidate(frontbuffer_bits, origin);
|
||||
@ -191,11 +191,11 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
|
||||
struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
|
||||
|
||||
if (origin == ORIGIN_CS) {
|
||||
spin_lock(&i915->fb_tracking.lock);
|
||||
spin_lock(&i915->display.fb_tracking.lock);
|
||||
/* Filter out new bits since rendering started. */
|
||||
frontbuffer_bits &= i915->fb_tracking.busy_bits;
|
||||
i915->fb_tracking.busy_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&i915->fb_tracking.lock);
|
||||
frontbuffer_bits &= i915->display.fb_tracking.busy_bits;
|
||||
i915->display.fb_tracking.busy_bits &= ~frontbuffer_bits;
|
||||
spin_unlock(&i915->display.fb_tracking.lock);
|
||||
}
|
||||
|
||||
if (frontbuffer_bits)
|
||||
@ -221,7 +221,7 @@ static void frontbuffer_retire(struct i915_active *ref)
|
||||
}
|
||||
|
||||
static void frontbuffer_release(struct kref *ref)
|
||||
__releases(&to_i915(front->obj->base.dev)->fb_tracking.lock)
|
||||
__releases(&to_i915(front->obj->base.dev)->display.fb_tracking.lock)
|
||||
{
|
||||
struct intel_frontbuffer *front =
|
||||
container_of(ref, typeof(*front), ref);
|
||||
@ -238,7 +238,7 @@ static void frontbuffer_release(struct kref *ref)
|
||||
spin_unlock(&obj->vma.lock);
|
||||
|
||||
RCU_INIT_POINTER(obj->frontbuffer, NULL);
|
||||
spin_unlock(&to_i915(obj->base.dev)->fb_tracking.lock);
|
||||
spin_unlock(&to_i915(obj->base.dev)->display.fb_tracking.lock);
|
||||
|
||||
i915_active_fini(&front->write);
|
||||
|
||||
@ -268,7 +268,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj)
|
||||
frontbuffer_retire,
|
||||
I915_ACTIVE_RETIRE_SLEEPS);
|
||||
|
||||
spin_lock(&i915->fb_tracking.lock);
|
||||
spin_lock(&i915->display.fb_tracking.lock);
|
||||
if (rcu_access_pointer(obj->frontbuffer)) {
|
||||
kfree(front);
|
||||
front = rcu_dereference_protected(obj->frontbuffer, true);
|
||||
@ -277,7 +277,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj)
|
||||
i915_gem_object_get(obj);
|
||||
rcu_assign_pointer(obj->frontbuffer, front);
|
||||
}
|
||||
spin_unlock(&i915->fb_tracking.lock);
|
||||
spin_unlock(&i915->display.fb_tracking.lock);
|
||||
|
||||
return front;
|
||||
}
|
||||
@ -286,7 +286,7 @@ void intel_frontbuffer_put(struct intel_frontbuffer *front)
|
||||
{
|
||||
kref_put_lock(&front->ref,
|
||||
frontbuffer_release,
|
||||
&to_i915(front->obj->base.dev)->fb_tracking.lock);
|
||||
&to_i915(front->obj->base.dev)->display.fb_tracking.lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_gmbus.h"
|
||||
#include "intel_gmbus_regs.h"
|
||||
|
||||
struct intel_gmbus {
|
||||
struct i2c_adapter adapter;
|
||||
@ -45,7 +46,7 @@ struct intel_gmbus {
|
||||
u32 reg0;
|
||||
i915_reg_t gpio_reg;
|
||||
struct i2c_algo_bit_data bit_algo;
|
||||
struct drm_i915_private *dev_priv;
|
||||
struct drm_i915_private *i915;
|
||||
};
|
||||
|
||||
struct gmbus_pin {
|
||||
@ -116,6 +117,18 @@ static const struct gmbus_pin gmbus_pins_dg2[] = {
|
||||
[GMBUS_PIN_9_TC1_ICP] = { "tc1", GPIOJ },
|
||||
};
|
||||
|
||||
static const struct gmbus_pin gmbus_pins_mtp[] = {
|
||||
[GMBUS_PIN_1_BXT] = { "dpa", GPIOB },
|
||||
[GMBUS_PIN_2_BXT] = { "dpb", GPIOC },
|
||||
[GMBUS_PIN_3_BXT] = { "dpc", GPIOD },
|
||||
[GMBUS_PIN_4_CNP] = { "dpd", GPIOE },
|
||||
[GMBUS_PIN_5_MTP] = { "dpe", GPIOF },
|
||||
[GMBUS_PIN_9_TC1_ICP] = { "tc1", GPIOJ },
|
||||
[GMBUS_PIN_10_TC2_ICP] = { "tc2", GPIOK },
|
||||
[GMBUS_PIN_11_TC3_ICP] = { "tc3", GPIOL },
|
||||
[GMBUS_PIN_12_TC4_ICP] = { "tc4", GPIOM },
|
||||
};
|
||||
|
||||
static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *i915,
|
||||
unsigned int pin)
|
||||
{
|
||||
@ -128,6 +141,9 @@ static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *i915,
|
||||
} else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) {
|
||||
pins = gmbus_pins_dg1;
|
||||
size = ARRAY_SIZE(gmbus_pins_dg1);
|
||||
} else if (INTEL_PCH_TYPE(i915) >= PCH_MTP) {
|
||||
pins = gmbus_pins_mtp;
|
||||
size = ARRAY_SIZE(gmbus_pins_mtp);
|
||||
} else if (INTEL_PCH_TYPE(i915) >= PCH_ICP) {
|
||||
pins = gmbus_pins_icp;
|
||||
size = ARRAY_SIZE(gmbus_pins_icp);
|
||||
@ -170,55 +186,55 @@ to_intel_gmbus(struct i2c_adapter *i2c)
|
||||
}
|
||||
|
||||
void
|
||||
intel_gmbus_reset(struct drm_i915_private *dev_priv)
|
||||
intel_gmbus_reset(struct drm_i915_private *i915)
|
||||
{
|
||||
intel_de_write(dev_priv, GMBUS0, 0);
|
||||
intel_de_write(dev_priv, GMBUS4, 0);
|
||||
intel_de_write(i915, GMBUS0(i915), 0);
|
||||
intel_de_write(i915, GMBUS4(i915), 0);
|
||||
}
|
||||
|
||||
static void pnv_gmbus_clock_gating(struct drm_i915_private *dev_priv,
|
||||
static void pnv_gmbus_clock_gating(struct drm_i915_private *i915,
|
||||
bool enable)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* When using bit bashing for I2C, this bit needs to be set to 1 */
|
||||
val = intel_de_read(dev_priv, DSPCLK_GATE_D);
|
||||
val = intel_de_read(i915, DSPCLK_GATE_D(i915));
|
||||
if (!enable)
|
||||
val |= PNV_GMBUSUNIT_CLOCK_GATE_DISABLE;
|
||||
else
|
||||
val &= ~PNV_GMBUSUNIT_CLOCK_GATE_DISABLE;
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D, val);
|
||||
intel_de_write(i915, DSPCLK_GATE_D(i915), val);
|
||||
}
|
||||
|
||||
static void pch_gmbus_clock_gating(struct drm_i915_private *dev_priv,
|
||||
static void pch_gmbus_clock_gating(struct drm_i915_private *i915,
|
||||
bool enable)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = intel_de_read(dev_priv, SOUTH_DSPCLK_GATE_D);
|
||||
val = intel_de_read(i915, SOUTH_DSPCLK_GATE_D);
|
||||
if (!enable)
|
||||
val |= PCH_GMBUSUNIT_CLOCK_GATE_DISABLE;
|
||||
else
|
||||
val &= ~PCH_GMBUSUNIT_CLOCK_GATE_DISABLE;
|
||||
intel_de_write(dev_priv, SOUTH_DSPCLK_GATE_D, val);
|
||||
intel_de_write(i915, SOUTH_DSPCLK_GATE_D, val);
|
||||
}
|
||||
|
||||
static void bxt_gmbus_clock_gating(struct drm_i915_private *dev_priv,
|
||||
static void bxt_gmbus_clock_gating(struct drm_i915_private *i915,
|
||||
bool enable)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = intel_de_read(dev_priv, GEN9_CLKGATE_DIS_4);
|
||||
val = intel_de_read(i915, GEN9_CLKGATE_DIS_4);
|
||||
if (!enable)
|
||||
val |= BXT_GMBUS_GATING_DIS;
|
||||
else
|
||||
val &= ~BXT_GMBUS_GATING_DIS;
|
||||
intel_de_write(dev_priv, GEN9_CLKGATE_DIS_4, val);
|
||||
intel_de_write(i915, GEN9_CLKGATE_DIS_4, val);
|
||||
}
|
||||
|
||||
static u32 get_reserved(struct intel_gmbus *bus)
|
||||
{
|
||||
struct drm_i915_private *i915 = bus->dev_priv;
|
||||
struct drm_i915_private *i915 = bus->i915;
|
||||
struct intel_uncore *uncore = &i915->uncore;
|
||||
u32 reserved = 0;
|
||||
|
||||
@ -234,7 +250,7 @@ static u32 get_reserved(struct intel_gmbus *bus)
|
||||
static int get_clock(void *data)
|
||||
{
|
||||
struct intel_gmbus *bus = data;
|
||||
struct intel_uncore *uncore = &bus->dev_priv->uncore;
|
||||
struct intel_uncore *uncore = &bus->i915->uncore;
|
||||
u32 reserved = get_reserved(bus);
|
||||
|
||||
intel_uncore_write_notrace(uncore,
|
||||
@ -249,7 +265,7 @@ static int get_clock(void *data)
|
||||
static int get_data(void *data)
|
||||
{
|
||||
struct intel_gmbus *bus = data;
|
||||
struct intel_uncore *uncore = &bus->dev_priv->uncore;
|
||||
struct intel_uncore *uncore = &bus->i915->uncore;
|
||||
u32 reserved = get_reserved(bus);
|
||||
|
||||
intel_uncore_write_notrace(uncore,
|
||||
@ -264,7 +280,7 @@ static int get_data(void *data)
|
||||
static void set_clock(void *data, int state_high)
|
||||
{
|
||||
struct intel_gmbus *bus = data;
|
||||
struct intel_uncore *uncore = &bus->dev_priv->uncore;
|
||||
struct intel_uncore *uncore = &bus->i915->uncore;
|
||||
u32 reserved = get_reserved(bus);
|
||||
u32 clock_bits;
|
||||
|
||||
@ -283,7 +299,7 @@ static void set_clock(void *data, int state_high)
|
||||
static void set_data(void *data, int state_high)
|
||||
{
|
||||
struct intel_gmbus *bus = data;
|
||||
struct intel_uncore *uncore = &bus->dev_priv->uncore;
|
||||
struct intel_uncore *uncore = &bus->i915->uncore;
|
||||
u32 reserved = get_reserved(bus);
|
||||
u32 data_bits;
|
||||
|
||||
@ -301,12 +317,12 @@ static int
|
||||
intel_gpio_pre_xfer(struct i2c_adapter *adapter)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct drm_i915_private *dev_priv = bus->dev_priv;
|
||||
struct drm_i915_private *i915 = bus->i915;
|
||||
|
||||
intel_gmbus_reset(dev_priv);
|
||||
intel_gmbus_reset(i915);
|
||||
|
||||
if (IS_PINEVIEW(dev_priv))
|
||||
pnv_gmbus_clock_gating(dev_priv, false);
|
||||
if (IS_PINEVIEW(i915))
|
||||
pnv_gmbus_clock_gating(i915, false);
|
||||
|
||||
set_data(bus, 1);
|
||||
set_clock(bus, 1);
|
||||
@ -318,13 +334,13 @@ static void
|
||||
intel_gpio_post_xfer(struct i2c_adapter *adapter)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct drm_i915_private *dev_priv = bus->dev_priv;
|
||||
struct drm_i915_private *i915 = bus->i915;
|
||||
|
||||
set_data(bus, 1);
|
||||
set_clock(bus, 1);
|
||||
|
||||
if (IS_PINEVIEW(dev_priv))
|
||||
pnv_gmbus_clock_gating(dev_priv, true);
|
||||
if (IS_PINEVIEW(i915))
|
||||
pnv_gmbus_clock_gating(i915, true);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -356,7 +372,7 @@ static bool has_gmbus_irq(struct drm_i915_private *i915)
|
||||
return HAS_GMBUS_IRQ(i915) && intel_irqs_enabled(i915);
|
||||
}
|
||||
|
||||
static int gmbus_wait(struct drm_i915_private *dev_priv, u32 status, u32 irq_en)
|
||||
static int gmbus_wait(struct drm_i915_private *i915, u32 status, u32 irq_en)
|
||||
{
|
||||
DEFINE_WAIT(wait);
|
||||
u32 gmbus2;
|
||||
@ -366,21 +382,21 @@ static int gmbus_wait(struct drm_i915_private *dev_priv, u32 status, u32 irq_en)
|
||||
* we also need to check for NAKs besides the hw ready/idle signal, we
|
||||
* need to wake up periodically and check that ourselves.
|
||||
*/
|
||||
if (!has_gmbus_irq(dev_priv))
|
||||
if (!has_gmbus_irq(i915))
|
||||
irq_en = 0;
|
||||
|
||||
add_wait_queue(&dev_priv->display.gmbus.wait_queue, &wait);
|
||||
intel_de_write_fw(dev_priv, GMBUS4, irq_en);
|
||||
add_wait_queue(&i915->display.gmbus.wait_queue, &wait);
|
||||
intel_de_write_fw(i915, GMBUS4(i915), irq_en);
|
||||
|
||||
status |= GMBUS_SATOER;
|
||||
ret = wait_for_us((gmbus2 = intel_de_read_fw(dev_priv, GMBUS2)) & status,
|
||||
ret = wait_for_us((gmbus2 = intel_de_read_fw(i915, GMBUS2(i915))) & status,
|
||||
2);
|
||||
if (ret)
|
||||
ret = wait_for((gmbus2 = intel_de_read_fw(dev_priv, GMBUS2)) & status,
|
||||
ret = wait_for((gmbus2 = intel_de_read_fw(i915, GMBUS2(i915))) & status,
|
||||
50);
|
||||
|
||||
intel_de_write_fw(dev_priv, GMBUS4, 0);
|
||||
remove_wait_queue(&dev_priv->display.gmbus.wait_queue, &wait);
|
||||
intel_de_write_fw(i915, GMBUS4(i915), 0);
|
||||
remove_wait_queue(&i915->display.gmbus.wait_queue, &wait);
|
||||
|
||||
if (gmbus2 & GMBUS_SATOER)
|
||||
return -ENXIO;
|
||||
@ -389,7 +405,7 @@ static int gmbus_wait(struct drm_i915_private *dev_priv, u32 status, u32 irq_en)
|
||||
}
|
||||
|
||||
static int
|
||||
gmbus_wait_idle(struct drm_i915_private *dev_priv)
|
||||
gmbus_wait_idle(struct drm_i915_private *i915)
|
||||
{
|
||||
DEFINE_WAIT(wait);
|
||||
u32 irq_enable;
|
||||
@ -397,35 +413,35 @@ gmbus_wait_idle(struct drm_i915_private *dev_priv)
|
||||
|
||||
/* Important: The hw handles only the first bit, so set only one! */
|
||||
irq_enable = 0;
|
||||
if (has_gmbus_irq(dev_priv))
|
||||
if (has_gmbus_irq(i915))
|
||||
irq_enable = GMBUS_IDLE_EN;
|
||||
|
||||
add_wait_queue(&dev_priv->display.gmbus.wait_queue, &wait);
|
||||
intel_de_write_fw(dev_priv, GMBUS4, irq_enable);
|
||||
add_wait_queue(&i915->display.gmbus.wait_queue, &wait);
|
||||
intel_de_write_fw(i915, GMBUS4(i915), irq_enable);
|
||||
|
||||
ret = intel_wait_for_register_fw(&dev_priv->uncore,
|
||||
GMBUS2, GMBUS_ACTIVE, 0,
|
||||
ret = intel_wait_for_register_fw(&i915->uncore,
|
||||
GMBUS2(i915), GMBUS_ACTIVE, 0,
|
||||
10);
|
||||
|
||||
intel_de_write_fw(dev_priv, GMBUS4, 0);
|
||||
remove_wait_queue(&dev_priv->display.gmbus.wait_queue, &wait);
|
||||
intel_de_write_fw(i915, GMBUS4(i915), 0);
|
||||
remove_wait_queue(&i915->display.gmbus.wait_queue, &wait);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int gmbus_max_xfer_size(struct drm_i915_private *dev_priv)
|
||||
static unsigned int gmbus_max_xfer_size(struct drm_i915_private *i915)
|
||||
{
|
||||
return DISPLAY_VER(dev_priv) >= 9 ? GEN9_GMBUS_BYTE_COUNT_MAX :
|
||||
return DISPLAY_VER(i915) >= 9 ? GEN9_GMBUS_BYTE_COUNT_MAX :
|
||||
GMBUS_BYTE_COUNT_MAX;
|
||||
}
|
||||
|
||||
static int
|
||||
gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
|
||||
gmbus_xfer_read_chunk(struct drm_i915_private *i915,
|
||||
unsigned short addr, u8 *buf, unsigned int len,
|
||||
u32 gmbus0_reg, u32 gmbus1_index)
|
||||
{
|
||||
unsigned int size = len;
|
||||
bool burst_read = len > gmbus_max_xfer_size(dev_priv);
|
||||
bool burst_read = len > gmbus_max_xfer_size(i915);
|
||||
bool extra_byte_added = false;
|
||||
|
||||
if (burst_read) {
|
||||
@ -438,21 +454,21 @@ gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
|
||||
len++;
|
||||
}
|
||||
size = len % 256 + 256;
|
||||
intel_de_write_fw(dev_priv, GMBUS0,
|
||||
intel_de_write_fw(i915, GMBUS0(i915),
|
||||
gmbus0_reg | GMBUS_BYTE_CNT_OVERRIDE);
|
||||
}
|
||||
|
||||
intel_de_write_fw(dev_priv, GMBUS1,
|
||||
intel_de_write_fw(i915, GMBUS1(i915),
|
||||
gmbus1_index | GMBUS_CYCLE_WAIT | (size << GMBUS_BYTE_COUNT_SHIFT) | (addr << GMBUS_SLAVE_ADDR_SHIFT) | GMBUS_SLAVE_READ | GMBUS_SW_RDY);
|
||||
while (len) {
|
||||
int ret;
|
||||
u32 val, loop = 0;
|
||||
|
||||
ret = gmbus_wait(dev_priv, GMBUS_HW_RDY, GMBUS_HW_RDY_EN);
|
||||
ret = gmbus_wait(i915, GMBUS_HW_RDY, GMBUS_HW_RDY_EN);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val = intel_de_read_fw(dev_priv, GMBUS3);
|
||||
val = intel_de_read_fw(i915, GMBUS3(i915));
|
||||
do {
|
||||
if (extra_byte_added && len == 1)
|
||||
break;
|
||||
@ -463,7 +479,7 @@ gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
|
||||
|
||||
if (burst_read && len == size - 4)
|
||||
/* Reset the override bit */
|
||||
intel_de_write_fw(dev_priv, GMBUS0, gmbus0_reg);
|
||||
intel_de_write_fw(i915, GMBUS0(i915), gmbus0_reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -480,7 +496,7 @@ gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
|
||||
#define INTEL_GMBUS_BURST_READ_MAX_LEN 767U
|
||||
|
||||
static int
|
||||
gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
|
||||
gmbus_xfer_read(struct drm_i915_private *i915, struct i2c_msg *msg,
|
||||
u32 gmbus0_reg, u32 gmbus1_index)
|
||||
{
|
||||
u8 *buf = msg->buf;
|
||||
@ -489,12 +505,12 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
|
||||
int ret;
|
||||
|
||||
do {
|
||||
if (HAS_GMBUS_BURST_READ(dev_priv))
|
||||
if (HAS_GMBUS_BURST_READ(i915))
|
||||
len = min(rx_size, INTEL_GMBUS_BURST_READ_MAX_LEN);
|
||||
else
|
||||
len = min(rx_size, gmbus_max_xfer_size(dev_priv));
|
||||
len = min(rx_size, gmbus_max_xfer_size(i915));
|
||||
|
||||
ret = gmbus_xfer_read_chunk(dev_priv, msg->addr, buf, len,
|
||||
ret = gmbus_xfer_read_chunk(i915, msg->addr, buf, len,
|
||||
gmbus0_reg, gmbus1_index);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -507,7 +523,7 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
|
||||
}
|
||||
|
||||
static int
|
||||
gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
|
||||
gmbus_xfer_write_chunk(struct drm_i915_private *i915,
|
||||
unsigned short addr, u8 *buf, unsigned int len,
|
||||
u32 gmbus1_index)
|
||||
{
|
||||
@ -520,8 +536,8 @@ gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
intel_de_write_fw(dev_priv, GMBUS3, val);
|
||||
intel_de_write_fw(dev_priv, GMBUS1,
|
||||
intel_de_write_fw(i915, GMBUS3(i915), val);
|
||||
intel_de_write_fw(i915, GMBUS1(i915),
|
||||
gmbus1_index | GMBUS_CYCLE_WAIT | (chunk_size << GMBUS_BYTE_COUNT_SHIFT) | (addr << GMBUS_SLAVE_ADDR_SHIFT) | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
|
||||
while (len) {
|
||||
int ret;
|
||||
@ -531,9 +547,9 @@ gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
|
||||
val |= *buf++ << (8 * loop);
|
||||
} while (--len && ++loop < 4);
|
||||
|
||||
intel_de_write_fw(dev_priv, GMBUS3, val);
|
||||
intel_de_write_fw(i915, GMBUS3(i915), val);
|
||||
|
||||
ret = gmbus_wait(dev_priv, GMBUS_HW_RDY, GMBUS_HW_RDY_EN);
|
||||
ret = gmbus_wait(i915, GMBUS_HW_RDY, GMBUS_HW_RDY_EN);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -542,7 +558,7 @@ gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
|
||||
}
|
||||
|
||||
static int
|
||||
gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
|
||||
gmbus_xfer_write(struct drm_i915_private *i915, struct i2c_msg *msg,
|
||||
u32 gmbus1_index)
|
||||
{
|
||||
u8 *buf = msg->buf;
|
||||
@ -551,9 +567,9 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
|
||||
int ret;
|
||||
|
||||
do {
|
||||
len = min(tx_size, gmbus_max_xfer_size(dev_priv));
|
||||
len = min(tx_size, gmbus_max_xfer_size(i915));
|
||||
|
||||
ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len,
|
||||
ret = gmbus_xfer_write_chunk(i915, msg->addr, buf, len,
|
||||
gmbus1_index);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -580,7 +596,7 @@ gmbus_is_index_xfer(struct i2c_msg *msgs, int i, int num)
|
||||
}
|
||||
|
||||
static int
|
||||
gmbus_index_xfer(struct drm_i915_private *dev_priv, struct i2c_msg *msgs,
|
||||
gmbus_index_xfer(struct drm_i915_private *i915, struct i2c_msg *msgs,
|
||||
u32 gmbus0_reg)
|
||||
{
|
||||
u32 gmbus1_index = 0;
|
||||
@ -596,17 +612,17 @@ gmbus_index_xfer(struct drm_i915_private *dev_priv, struct i2c_msg *msgs,
|
||||
|
||||
/* GMBUS5 holds 16-bit index */
|
||||
if (gmbus5)
|
||||
intel_de_write_fw(dev_priv, GMBUS5, gmbus5);
|
||||
intel_de_write_fw(i915, GMBUS5(i915), gmbus5);
|
||||
|
||||
if (msgs[1].flags & I2C_M_RD)
|
||||
ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus0_reg,
|
||||
ret = gmbus_xfer_read(i915, &msgs[1], gmbus0_reg,
|
||||
gmbus1_index);
|
||||
else
|
||||
ret = gmbus_xfer_write(dev_priv, &msgs[1], gmbus1_index);
|
||||
ret = gmbus_xfer_write(i915, &msgs[1], gmbus1_index);
|
||||
|
||||
/* Clear GMBUS5 after each index transfer */
|
||||
if (gmbus5)
|
||||
intel_de_write_fw(dev_priv, GMBUS5, 0);
|
||||
intel_de_write_fw(i915, GMBUS5(i915), 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -616,34 +632,34 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
|
||||
u32 gmbus0_source)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct drm_i915_private *dev_priv = bus->dev_priv;
|
||||
struct drm_i915_private *i915 = bus->i915;
|
||||
int i = 0, inc, try = 0;
|
||||
int ret = 0;
|
||||
|
||||
/* Display WA #0868: skl,bxt,kbl,cfl,glk */
|
||||
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
|
||||
bxt_gmbus_clock_gating(dev_priv, false);
|
||||
else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_CNP(dev_priv))
|
||||
pch_gmbus_clock_gating(dev_priv, false);
|
||||
if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
|
||||
bxt_gmbus_clock_gating(i915, false);
|
||||
else if (HAS_PCH_SPT(i915) || HAS_PCH_CNP(i915))
|
||||
pch_gmbus_clock_gating(i915, false);
|
||||
|
||||
retry:
|
||||
intel_de_write_fw(dev_priv, GMBUS0, gmbus0_source | bus->reg0);
|
||||
intel_de_write_fw(i915, GMBUS0(i915), gmbus0_source | bus->reg0);
|
||||
|
||||
for (; i < num; i += inc) {
|
||||
inc = 1;
|
||||
if (gmbus_is_index_xfer(msgs, i, num)) {
|
||||
ret = gmbus_index_xfer(dev_priv, &msgs[i],
|
||||
ret = gmbus_index_xfer(i915, &msgs[i],
|
||||
gmbus0_source | bus->reg0);
|
||||
inc = 2; /* an index transmission is two msgs */
|
||||
} else if (msgs[i].flags & I2C_M_RD) {
|
||||
ret = gmbus_xfer_read(dev_priv, &msgs[i],
|
||||
ret = gmbus_xfer_read(i915, &msgs[i],
|
||||
gmbus0_source | bus->reg0, 0);
|
||||
} else {
|
||||
ret = gmbus_xfer_write(dev_priv, &msgs[i], 0);
|
||||
ret = gmbus_xfer_write(i915, &msgs[i], 0);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
ret = gmbus_wait(dev_priv,
|
||||
ret = gmbus_wait(i915,
|
||||
GMBUS_HW_WAIT_PHASE, GMBUS_HW_WAIT_EN);
|
||||
if (ret == -ETIMEDOUT)
|
||||
goto timeout;
|
||||
@ -655,19 +671,19 @@ retry:
|
||||
* a STOP on the very first cycle. To simplify the code we
|
||||
* unconditionally generate the STOP condition with an additional gmbus
|
||||
* cycle. */
|
||||
intel_de_write_fw(dev_priv, GMBUS1, GMBUS_CYCLE_STOP | GMBUS_SW_RDY);
|
||||
intel_de_write_fw(i915, GMBUS1(i915), GMBUS_CYCLE_STOP | GMBUS_SW_RDY);
|
||||
|
||||
/* Mark the GMBUS interface as disabled after waiting for idle.
|
||||
* We will re-enable it at the start of the next xfer,
|
||||
* till then let it sleep.
|
||||
*/
|
||||
if (gmbus_wait_idle(dev_priv)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
if (gmbus_wait_idle(i915)) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"GMBUS [%s] timed out waiting for idle\n",
|
||||
adapter->name);
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
intel_de_write_fw(dev_priv, GMBUS0, 0);
|
||||
intel_de_write_fw(i915, GMBUS0(i915), 0);
|
||||
ret = ret ?: i;
|
||||
goto out;
|
||||
|
||||
@ -686,8 +702,8 @@ clear_err:
|
||||
* it's slow responding and only answers on the 2nd retry.
|
||||
*/
|
||||
ret = -ENXIO;
|
||||
if (gmbus_wait_idle(dev_priv)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
if (gmbus_wait_idle(i915)) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"GMBUS [%s] timed out after NAK\n",
|
||||
adapter->name);
|
||||
ret = -ETIMEDOUT;
|
||||
@ -697,11 +713,11 @@ clear_err:
|
||||
* of resetting the GMBUS controller and so clearing the
|
||||
* BUS_ERROR raised by the slave's NAK.
|
||||
*/
|
||||
intel_de_write_fw(dev_priv, GMBUS1, GMBUS_SW_CLR_INT);
|
||||
intel_de_write_fw(dev_priv, GMBUS1, 0);
|
||||
intel_de_write_fw(dev_priv, GMBUS0, 0);
|
||||
intel_de_write_fw(i915, GMBUS1(i915), GMBUS_SW_CLR_INT);
|
||||
intel_de_write_fw(i915, GMBUS1(i915), 0);
|
||||
intel_de_write_fw(i915, GMBUS0(i915), 0);
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "GMBUS [%s] NAK for addr: %04x %c(%d)\n",
|
||||
drm_dbg_kms(&i915->drm, "GMBUS [%s] NAK for addr: %04x %c(%d)\n",
|
||||
adapter->name, msgs[i].addr,
|
||||
(msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
|
||||
|
||||
@ -712,7 +728,7 @@ clear_err:
|
||||
* drm_do_probe_ddc_edid, which bails out on the first -ENXIO.
|
||||
*/
|
||||
if (ret == -ENXIO && i == 0 && try++ == 0) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"GMBUS [%s] NAK on first message, retry\n",
|
||||
adapter->name);
|
||||
goto retry;
|
||||
@ -721,10 +737,10 @@ clear_err:
|
||||
goto out;
|
||||
|
||||
timeout:
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"GMBUS [%s] timed out, falling back to bit banging on pin %d\n",
|
||||
bus->adapter.name, bus->reg0 & 0xff);
|
||||
intel_de_write_fw(dev_priv, GMBUS0, 0);
|
||||
intel_de_write_fw(i915, GMBUS0(i915), 0);
|
||||
|
||||
/*
|
||||
* Hardware may not support GMBUS over these pins? Try GPIO bitbanging
|
||||
@ -734,10 +750,10 @@ timeout:
|
||||
|
||||
out:
|
||||
/* Display WA #0868: skl,bxt,kbl,cfl,glk */
|
||||
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
|
||||
bxt_gmbus_clock_gating(dev_priv, true);
|
||||
else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_CNP(dev_priv))
|
||||
pch_gmbus_clock_gating(dev_priv, true);
|
||||
if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
|
||||
bxt_gmbus_clock_gating(i915, true);
|
||||
else if (HAS_PCH_SPT(i915) || HAS_PCH_CNP(i915))
|
||||
pch_gmbus_clock_gating(i915, true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -746,11 +762,11 @@ static int
|
||||
gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct drm_i915_private *dev_priv = bus->dev_priv;
|
||||
struct drm_i915_private *i915 = bus->i915;
|
||||
intel_wakeref_t wakeref;
|
||||
int ret;
|
||||
|
||||
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
|
||||
wakeref = intel_display_power_get(i915, POWER_DOMAIN_GMBUS);
|
||||
|
||||
if (bus->force_bit) {
|
||||
ret = i2c_bit_algo.master_xfer(adapter, msgs, num);
|
||||
@ -762,7 +778,7 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
|
||||
bus->force_bit |= GMBUS_FORCE_BIT_RETRY;
|
||||
}
|
||||
|
||||
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
|
||||
intel_display_power_put(i915, POWER_DOMAIN_GMBUS, wakeref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -770,7 +786,7 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
|
||||
int intel_gmbus_output_aksv(struct i2c_adapter *adapter)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct drm_i915_private *dev_priv = bus->dev_priv;
|
||||
struct drm_i915_private *i915 = bus->i915;
|
||||
u8 cmd = DRM_HDCP_DDC_AKSV;
|
||||
u8 buf[DRM_HDCP_KSV_LEN] = { 0 };
|
||||
struct i2c_msg msgs[] = {
|
||||
@ -790,8 +806,8 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter)
|
||||
intel_wakeref_t wakeref;
|
||||
int ret;
|
||||
|
||||
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
|
||||
mutex_lock(&dev_priv->display.gmbus.mutex);
|
||||
wakeref = intel_display_power_get(i915, POWER_DOMAIN_GMBUS);
|
||||
mutex_lock(&i915->display.gmbus.mutex);
|
||||
|
||||
/*
|
||||
* In order to output Aksv to the receiver, use an indexed write to
|
||||
@ -800,8 +816,8 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter)
|
||||
*/
|
||||
ret = do_gmbus_xfer(adapter, msgs, ARRAY_SIZE(msgs), GMBUS_AKSV_SELECT);
|
||||
|
||||
mutex_unlock(&dev_priv->display.gmbus.mutex);
|
||||
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
|
||||
mutex_unlock(&i915->display.gmbus.mutex);
|
||||
intel_display_power_put(i915, POWER_DOMAIN_GMBUS, wakeref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -824,27 +840,27 @@ static void gmbus_lock_bus(struct i2c_adapter *adapter,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct drm_i915_private *dev_priv = bus->dev_priv;
|
||||
struct drm_i915_private *i915 = bus->i915;
|
||||
|
||||
mutex_lock(&dev_priv->display.gmbus.mutex);
|
||||
mutex_lock(&i915->display.gmbus.mutex);
|
||||
}
|
||||
|
||||
static int gmbus_trylock_bus(struct i2c_adapter *adapter,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct drm_i915_private *dev_priv = bus->dev_priv;
|
||||
struct drm_i915_private *i915 = bus->i915;
|
||||
|
||||
return mutex_trylock(&dev_priv->display.gmbus.mutex);
|
||||
return mutex_trylock(&i915->display.gmbus.mutex);
|
||||
}
|
||||
|
||||
static void gmbus_unlock_bus(struct i2c_adapter *adapter,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct drm_i915_private *dev_priv = bus->dev_priv;
|
||||
struct drm_i915_private *i915 = bus->i915;
|
||||
|
||||
mutex_unlock(&dev_priv->display.gmbus.mutex);
|
||||
mutex_unlock(&i915->display.gmbus.mutex);
|
||||
}
|
||||
|
||||
static const struct i2c_lock_operations gmbus_lock_ops = {
|
||||
@ -855,31 +871,31 @@ static const struct i2c_lock_operations gmbus_lock_ops = {
|
||||
|
||||
/**
|
||||
* intel_gmbus_setup - instantiate all Intel i2c GMBuses
|
||||
* @dev_priv: i915 device private
|
||||
* @i915: i915 device private
|
||||
*/
|
||||
int intel_gmbus_setup(struct drm_i915_private *dev_priv)
|
||||
int intel_gmbus_setup(struct drm_i915_private *i915)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
|
||||
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
|
||||
unsigned int pin;
|
||||
int ret;
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
||||
dev_priv->display.gmbus.mmio_base = VLV_DISPLAY_BASE;
|
||||
else if (!HAS_GMCH(dev_priv))
|
||||
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
|
||||
i915->display.gmbus.mmio_base = VLV_DISPLAY_BASE;
|
||||
else if (!HAS_GMCH(i915))
|
||||
/*
|
||||
* Broxton uses the same PCH offsets for South Display Engine,
|
||||
* even though it doesn't have a PCH.
|
||||
*/
|
||||
dev_priv->display.gmbus.mmio_base = PCH_DISPLAY_BASE;
|
||||
i915->display.gmbus.mmio_base = PCH_DISPLAY_BASE;
|
||||
|
||||
mutex_init(&dev_priv->display.gmbus.mutex);
|
||||
init_waitqueue_head(&dev_priv->display.gmbus.wait_queue);
|
||||
mutex_init(&i915->display.gmbus.mutex);
|
||||
init_waitqueue_head(&i915->display.gmbus.wait_queue);
|
||||
|
||||
for (pin = 0; pin < ARRAY_SIZE(dev_priv->display.gmbus.bus); pin++) {
|
||||
for (pin = 0; pin < ARRAY_SIZE(i915->display.gmbus.bus); pin++) {
|
||||
const struct gmbus_pin *gmbus_pin;
|
||||
struct intel_gmbus *bus;
|
||||
|
||||
gmbus_pin = get_gmbus_pin(dev_priv, pin);
|
||||
gmbus_pin = get_gmbus_pin(i915, pin);
|
||||
if (!gmbus_pin)
|
||||
continue;
|
||||
|
||||
@ -896,7 +912,7 @@ int intel_gmbus_setup(struct drm_i915_private *dev_priv)
|
||||
"i915 gmbus %s", gmbus_pin->name);
|
||||
|
||||
bus->adapter.dev.parent = &pdev->dev;
|
||||
bus->dev_priv = dev_priv;
|
||||
bus->i915 = i915;
|
||||
|
||||
bus->adapter.algo = &gmbus_algorithm;
|
||||
bus->adapter.lock_ops = &gmbus_lock_ops;
|
||||
@ -911,10 +927,10 @@ int intel_gmbus_setup(struct drm_i915_private *dev_priv)
|
||||
bus->reg0 = pin | GMBUS_RATE_100KHZ;
|
||||
|
||||
/* gmbus seems to be broken on i830 */
|
||||
if (IS_I830(dev_priv))
|
||||
if (IS_I830(i915))
|
||||
bus->force_bit = 1;
|
||||
|
||||
intel_gpio_setup(bus, GPIO(gmbus_pin->gpio));
|
||||
intel_gpio_setup(bus, GPIO(i915, gmbus_pin->gpio));
|
||||
|
||||
ret = i2c_add_adapter(&bus->adapter);
|
||||
if (ret) {
|
||||
@ -922,43 +938,43 @@ int intel_gmbus_setup(struct drm_i915_private *dev_priv)
|
||||
goto err;
|
||||
}
|
||||
|
||||
dev_priv->display.gmbus.bus[pin] = bus;
|
||||
i915->display.gmbus.bus[pin] = bus;
|
||||
}
|
||||
|
||||
intel_gmbus_reset(dev_priv);
|
||||
intel_gmbus_reset(i915);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
intel_gmbus_teardown(dev_priv);
|
||||
intel_gmbus_teardown(i915);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv,
|
||||
struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *i915,
|
||||
unsigned int pin)
|
||||
{
|
||||
if (drm_WARN_ON(&dev_priv->drm, pin >= ARRAY_SIZE(dev_priv->display.gmbus.bus) ||
|
||||
!dev_priv->display.gmbus.bus[pin]))
|
||||
if (drm_WARN_ON(&i915->drm, pin >= ARRAY_SIZE(i915->display.gmbus.bus) ||
|
||||
!i915->display.gmbus.bus[pin]))
|
||||
return NULL;
|
||||
|
||||
return &dev_priv->display.gmbus.bus[pin]->adapter;
|
||||
return &i915->display.gmbus.bus[pin]->adapter;
|
||||
}
|
||||
|
||||
void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
|
||||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct drm_i915_private *dev_priv = bus->dev_priv;
|
||||
struct drm_i915_private *i915 = bus->i915;
|
||||
|
||||
mutex_lock(&dev_priv->display.gmbus.mutex);
|
||||
mutex_lock(&i915->display.gmbus.mutex);
|
||||
|
||||
bus->force_bit += force_bit ? 1 : -1;
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"%sabling bit-banging on %s. force bit now %d\n",
|
||||
force_bit ? "en" : "dis", adapter->name,
|
||||
bus->force_bit);
|
||||
|
||||
mutex_unlock(&dev_priv->display.gmbus.mutex);
|
||||
mutex_unlock(&i915->display.gmbus.mutex);
|
||||
}
|
||||
|
||||
bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
|
||||
@ -968,20 +984,20 @@ bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
|
||||
return bus->force_bit;
|
||||
}
|
||||
|
||||
void intel_gmbus_teardown(struct drm_i915_private *dev_priv)
|
||||
void intel_gmbus_teardown(struct drm_i915_private *i915)
|
||||
{
|
||||
unsigned int pin;
|
||||
|
||||
for (pin = 0; pin < ARRAY_SIZE(dev_priv->display.gmbus.bus); pin++) {
|
||||
for (pin = 0; pin < ARRAY_SIZE(i915->display.gmbus.bus); pin++) {
|
||||
struct intel_gmbus *bus;
|
||||
|
||||
bus = dev_priv->display.gmbus.bus[pin];
|
||||
bus = i915->display.gmbus.bus[pin];
|
||||
if (!bus)
|
||||
continue;
|
||||
|
||||
i2c_del_adapter(&bus->adapter);
|
||||
|
||||
kfree(bus);
|
||||
dev_priv->display.gmbus.bus[pin] = NULL;
|
||||
i915->display.gmbus.bus[pin] = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ struct i2c_adapter;
|
||||
#define GMBUS_PIN_2_BXT 2
|
||||
#define GMBUS_PIN_3_BXT 3
|
||||
#define GMBUS_PIN_4_CNP 4
|
||||
#define GMBUS_PIN_5_MTP 5
|
||||
#define GMBUS_PIN_9_TC1_ICP 9
|
||||
#define GMBUS_PIN_10_TC2_ICP 10
|
||||
#define GMBUS_PIN_11_TC3_ICP 11
|
||||
|
81
drivers/gpu/drm/i915/display/intel_gmbus_regs.h
Normal file
81
drivers/gpu/drm/i915/display/intel_gmbus_regs.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_GMBUS_REGS_H__
|
||||
#define __INTEL_GMBUS_REGS_H__
|
||||
|
||||
#include "i915_reg_defs.h"
|
||||
|
||||
#define GMBUS_MMIO_BASE(__i915) ((__i915)->display.gmbus.mmio_base)
|
||||
|
||||
#define GPIO(__i915, gpio) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x5010 + 4 * (gpio))
|
||||
#define GPIO_CLOCK_DIR_MASK (1 << 0)
|
||||
#define GPIO_CLOCK_DIR_IN (0 << 1)
|
||||
#define GPIO_CLOCK_DIR_OUT (1 << 1)
|
||||
#define GPIO_CLOCK_VAL_MASK (1 << 2)
|
||||
#define GPIO_CLOCK_VAL_OUT (1 << 3)
|
||||
#define GPIO_CLOCK_VAL_IN (1 << 4)
|
||||
#define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
|
||||
#define GPIO_DATA_DIR_MASK (1 << 8)
|
||||
#define GPIO_DATA_DIR_IN (0 << 9)
|
||||
#define GPIO_DATA_DIR_OUT (1 << 9)
|
||||
#define GPIO_DATA_VAL_MASK (1 << 10)
|
||||
#define GPIO_DATA_VAL_OUT (1 << 11)
|
||||
#define GPIO_DATA_VAL_IN (1 << 12)
|
||||
#define GPIO_DATA_PULLUP_DISABLE (1 << 13)
|
||||
|
||||
/* clock/port select */
|
||||
#define GMBUS0(__i915) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x5100)
|
||||
#define GMBUS_AKSV_SELECT (1 << 11)
|
||||
#define GMBUS_RATE_100KHZ (0 << 8)
|
||||
#define GMBUS_RATE_50KHZ (1 << 8)
|
||||
#define GMBUS_RATE_400KHZ (2 << 8) /* reserved on Pineview */
|
||||
#define GMBUS_RATE_1MHZ (3 << 8) /* reserved on Pineview */
|
||||
#define GMBUS_HOLD_EXT (1 << 7) /* 300ns hold time, rsvd on Pineview */
|
||||
#define GMBUS_BYTE_CNT_OVERRIDE (1 << 6)
|
||||
|
||||
/* command/status */
|
||||
#define GMBUS1(__i915) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x5104)
|
||||
#define GMBUS_SW_CLR_INT (1 << 31)
|
||||
#define GMBUS_SW_RDY (1 << 30)
|
||||
#define GMBUS_ENT (1 << 29) /* enable timeout */
|
||||
#define GMBUS_CYCLE_NONE (0 << 25)
|
||||
#define GMBUS_CYCLE_WAIT (1 << 25)
|
||||
#define GMBUS_CYCLE_INDEX (2 << 25)
|
||||
#define GMBUS_CYCLE_STOP (4 << 25)
|
||||
#define GMBUS_BYTE_COUNT_SHIFT 16
|
||||
#define GMBUS_BYTE_COUNT_MAX 256U
|
||||
#define GEN9_GMBUS_BYTE_COUNT_MAX 511U
|
||||
#define GMBUS_SLAVE_INDEX_SHIFT 8
|
||||
#define GMBUS_SLAVE_ADDR_SHIFT 1
|
||||
#define GMBUS_SLAVE_READ (1 << 0)
|
||||
#define GMBUS_SLAVE_WRITE (0 << 0)
|
||||
|
||||
/* status */
|
||||
#define GMBUS2(__i915) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x5108)
|
||||
#define GMBUS_INUSE (1 << 15)
|
||||
#define GMBUS_HW_WAIT_PHASE (1 << 14)
|
||||
#define GMBUS_STALL_TIMEOUT (1 << 13)
|
||||
#define GMBUS_INT (1 << 12)
|
||||
#define GMBUS_HW_RDY (1 << 11)
|
||||
#define GMBUS_SATOER (1 << 10)
|
||||
#define GMBUS_ACTIVE (1 << 9)
|
||||
|
||||
/* data buffer bytes 3-0 */
|
||||
#define GMBUS3(__i915) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x510c)
|
||||
|
||||
/* interrupt mask (Pineview+) */
|
||||
#define GMBUS4(__i915) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x5110)
|
||||
#define GMBUS_SLAVE_TIMEOUT_EN (1 << 4)
|
||||
#define GMBUS_NAK_EN (1 << 3)
|
||||
#define GMBUS_IDLE_EN (1 << 2)
|
||||
#define GMBUS_HW_WAIT_EN (1 << 1)
|
||||
#define GMBUS_HW_RDY_EN (1 << 0)
|
||||
|
||||
/* byte index */
|
||||
#define GMBUS5(__i915) _MMIO(GMBUS_MMIO_BASE(__i915) + 0x5120)
|
||||
#define GMBUS_2BYTE_INDEX_EN (1 << 31)
|
||||
|
||||
#endif /* __INTEL_GMBUS_REGS_H__ */
|
@ -210,12 +210,12 @@ bool intel_hdcp2_capable(struct intel_connector *connector)
|
||||
return false;
|
||||
|
||||
/* MEI interface is solid */
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
if (!dev_priv->hdcp_comp_added || !dev_priv->hdcp_master) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
if (!dev_priv->display.hdcp.comp_added || !dev_priv->display.hdcp.master) {
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return false;
|
||||
}
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
/* Sink's capability for HDCP2.2 */
|
||||
hdcp->shim->hdcp_2_2_capable(dig_port, &capable);
|
||||
@ -1146,11 +1146,11 @@ hdcp2_prepare_ake_init(struct intel_connector *connector,
|
||||
struct i915_hdcp_comp_master *comp;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
comp = dev_priv->hdcp_master;
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
comp = dev_priv->display.hdcp.master;
|
||||
|
||||
if (!comp || !comp->ops) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1158,7 +1158,7 @@ hdcp2_prepare_ake_init(struct intel_connector *connector,
|
||||
if (ret)
|
||||
drm_dbg_kms(&dev_priv->drm, "Prepare_ake_init failed. %d\n",
|
||||
ret);
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1176,11 +1176,11 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector,
|
||||
struct i915_hdcp_comp_master *comp;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
comp = dev_priv->hdcp_master;
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
comp = dev_priv->display.hdcp.master;
|
||||
|
||||
if (!comp || !comp->ops) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1190,7 +1190,7 @@ hdcp2_verify_rx_cert_prepare_km(struct intel_connector *connector,
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(&dev_priv->drm, "Verify rx_cert failed. %d\n",
|
||||
ret);
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1204,18 +1204,18 @@ static int hdcp2_verify_hprime(struct intel_connector *connector,
|
||||
struct i915_hdcp_comp_master *comp;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
comp = dev_priv->hdcp_master;
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
comp = dev_priv->display.hdcp.master;
|
||||
|
||||
if (!comp || !comp->ops) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = comp->ops->verify_hprime(comp->mei_dev, data, rx_hprime);
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(&dev_priv->drm, "Verify hprime failed. %d\n", ret);
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1230,11 +1230,11 @@ hdcp2_store_pairing_info(struct intel_connector *connector,
|
||||
struct i915_hdcp_comp_master *comp;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
comp = dev_priv->hdcp_master;
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
comp = dev_priv->display.hdcp.master;
|
||||
|
||||
if (!comp || !comp->ops) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1242,7 +1242,7 @@ hdcp2_store_pairing_info(struct intel_connector *connector,
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(&dev_priv->drm, "Store pairing info failed. %d\n",
|
||||
ret);
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1257,11 +1257,11 @@ hdcp2_prepare_lc_init(struct intel_connector *connector,
|
||||
struct i915_hdcp_comp_master *comp;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
comp = dev_priv->hdcp_master;
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
comp = dev_priv->display.hdcp.master;
|
||||
|
||||
if (!comp || !comp->ops) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1269,7 +1269,7 @@ hdcp2_prepare_lc_init(struct intel_connector *connector,
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(&dev_priv->drm, "Prepare lc_init failed. %d\n",
|
||||
ret);
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1284,11 +1284,11 @@ hdcp2_verify_lprime(struct intel_connector *connector,
|
||||
struct i915_hdcp_comp_master *comp;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
comp = dev_priv->hdcp_master;
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
comp = dev_priv->display.hdcp.master;
|
||||
|
||||
if (!comp || !comp->ops) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1296,7 +1296,7 @@ hdcp2_verify_lprime(struct intel_connector *connector,
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(&dev_priv->drm, "Verify L_Prime failed. %d\n",
|
||||
ret);
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1310,11 +1310,11 @@ static int hdcp2_prepare_skey(struct intel_connector *connector,
|
||||
struct i915_hdcp_comp_master *comp;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
comp = dev_priv->hdcp_master;
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
comp = dev_priv->display.hdcp.master;
|
||||
|
||||
if (!comp || !comp->ops) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1322,7 +1322,7 @@ static int hdcp2_prepare_skey(struct intel_connector *connector,
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(&dev_priv->drm, "Get session key failed. %d\n",
|
||||
ret);
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1339,11 +1339,11 @@ hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector,
|
||||
struct i915_hdcp_comp_master *comp;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
comp = dev_priv->hdcp_master;
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
comp = dev_priv->display.hdcp.master;
|
||||
|
||||
if (!comp || !comp->ops) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1353,7 +1353,7 @@ hdcp2_verify_rep_topology_prepare_ack(struct intel_connector *connector,
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Verify rep topology failed. %d\n", ret);
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1368,18 +1368,18 @@ hdcp2_verify_mprime(struct intel_connector *connector,
|
||||
struct i915_hdcp_comp_master *comp;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
comp = dev_priv->hdcp_master;
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
comp = dev_priv->display.hdcp.master;
|
||||
|
||||
if (!comp || !comp->ops) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = comp->ops->verify_mprime(comp->mei_dev, data, stream_ready);
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(&dev_priv->drm, "Verify mprime failed. %d\n", ret);
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1392,11 +1392,11 @@ static int hdcp2_authenticate_port(struct intel_connector *connector)
|
||||
struct i915_hdcp_comp_master *comp;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
comp = dev_priv->hdcp_master;
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
comp = dev_priv->display.hdcp.master;
|
||||
|
||||
if (!comp || !comp->ops) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1404,7 +1404,7 @@ static int hdcp2_authenticate_port(struct intel_connector *connector)
|
||||
if (ret < 0)
|
||||
drm_dbg_kms(&dev_priv->drm, "Enable hdcp auth failed. %d\n",
|
||||
ret);
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1416,17 +1416,17 @@ static int hdcp2_close_mei_session(struct intel_connector *connector)
|
||||
struct i915_hdcp_comp_master *comp;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
comp = dev_priv->hdcp_master;
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
comp = dev_priv->display.hdcp.master;
|
||||
|
||||
if (!comp || !comp->ops) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = comp->ops->close_hdcp_session(comp->mei_dev,
|
||||
&dig_port->hdcp_port_data);
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -2144,10 +2144,10 @@ static int i915_hdcp_component_bind(struct device *i915_kdev,
|
||||
struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev);
|
||||
|
||||
drm_dbg(&dev_priv->drm, "I915 HDCP comp bind\n");
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
dev_priv->hdcp_master = (struct i915_hdcp_comp_master *)data;
|
||||
dev_priv->hdcp_master->mei_dev = mei_kdev;
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
dev_priv->display.hdcp.master = (struct i915_hdcp_comp_master *)data;
|
||||
dev_priv->display.hdcp.master->mei_dev = mei_kdev;
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2158,9 +2158,9 @@ static void i915_hdcp_component_unbind(struct device *i915_kdev,
|
||||
struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev);
|
||||
|
||||
drm_dbg(&dev_priv->drm, "I915 HDCP comp unbind\n");
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
dev_priv->hdcp_master = NULL;
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
dev_priv->display.hdcp.master = NULL;
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
}
|
||||
|
||||
static const struct component_ops i915_hdcp_component_ops = {
|
||||
@ -2251,19 +2251,19 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
|
||||
if (!is_hdcp2_supported(dev_priv))
|
||||
return;
|
||||
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
drm_WARN_ON(&dev_priv->drm, dev_priv->hdcp_comp_added);
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
drm_WARN_ON(&dev_priv->drm, dev_priv->display.hdcp.comp_added);
|
||||
|
||||
dev_priv->hdcp_comp_added = true;
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
dev_priv->display.hdcp.comp_added = true;
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
ret = component_add_typed(dev_priv->drm.dev, &i915_hdcp_component_ops,
|
||||
I915_COMPONENT_HDCP);
|
||||
if (ret < 0) {
|
||||
drm_dbg_kms(&dev_priv->drm, "Failed at component add(%d)\n",
|
||||
ret);
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
dev_priv->hdcp_comp_added = false;
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
dev_priv->display.hdcp.comp_added = false;
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2476,14 +2476,14 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
|
||||
|
||||
void intel_hdcp_component_fini(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
mutex_lock(&dev_priv->hdcp_comp_mutex);
|
||||
if (!dev_priv->hdcp_comp_added) {
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_lock(&dev_priv->display.hdcp.comp_mutex);
|
||||
if (!dev_priv->display.hdcp.comp_added) {
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
dev_priv->hdcp_comp_added = false;
|
||||
mutex_unlock(&dev_priv->hdcp_comp_mutex);
|
||||
dev_priv->display.hdcp.comp_added = false;
|
||||
mutex_unlock(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
component_del(dev_priv->drm.dev, &i915_hdcp_component_ops);
|
||||
}
|
||||
|
@ -1892,7 +1892,7 @@ int intel_hdmi_tmds_clock(int clock, int bpc, bool ycbcr420_output)
|
||||
* 1.5x for 12bpc
|
||||
* 1.25x for 10bpc
|
||||
*/
|
||||
return clock * bpc / 8;
|
||||
return DIV_ROUND_CLOSEST(clock * bpc, 8);
|
||||
}
|
||||
|
||||
static bool intel_hdmi_source_bpc_possible(struct drm_i915_private *i915, int bpc)
|
||||
|
@ -837,12 +837,12 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
|
||||
|
||||
/* Skip init on machines we know falsely report LVDS */
|
||||
if (dmi_check_system(intel_no_lvds)) {
|
||||
drm_WARN(dev, !dev_priv->vbt.int_lvds_support,
|
||||
drm_WARN(dev, !dev_priv->display.vbt.int_lvds_support,
|
||||
"Useless DMI match. Internal LVDS support disabled by VBT\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dev_priv->vbt.int_lvds_support) {
|
||||
if (!dev_priv->display.vbt.int_lvds_support) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Internal LVDS support disabled by VBT\n");
|
||||
return;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "intel_modeset_setup.h"
|
||||
#include "intel_pch_display.h"
|
||||
#include "intel_pm.h"
|
||||
#include "skl_watermark.h"
|
||||
|
||||
static void intel_crtc_disable_noatomic(struct intel_crtc *crtc,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
@ -30,11 +31,11 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc,
|
||||
struct intel_encoder *encoder;
|
||||
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
||||
struct intel_bw_state *bw_state =
|
||||
to_intel_bw_state(i915->bw_obj.state);
|
||||
to_intel_bw_state(i915->display.bw.obj.state);
|
||||
struct intel_cdclk_state *cdclk_state =
|
||||
to_intel_cdclk_state(i915->cdclk.obj.state);
|
||||
to_intel_cdclk_state(i915->display.cdclk.obj.state);
|
||||
struct intel_dbuf_state *dbuf_state =
|
||||
to_intel_dbuf_state(i915->dbuf.obj.state);
|
||||
to_intel_dbuf_state(i915->display.dbuf.obj.state);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
to_intel_crtc_state(crtc->base.state);
|
||||
struct intel_plane *plane;
|
||||
@ -415,9 +416,9 @@ static void readout_plane_state(struct drm_i915_private *i915)
|
||||
static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
|
||||
{
|
||||
struct intel_cdclk_state *cdclk_state =
|
||||
to_intel_cdclk_state(i915->cdclk.obj.state);
|
||||
to_intel_cdclk_state(i915->display.cdclk.obj.state);
|
||||
struct intel_dbuf_state *dbuf_state =
|
||||
to_intel_dbuf_state(i915->dbuf.obj.state);
|
||||
to_intel_dbuf_state(i915->display.dbuf.obj.state);
|
||||
enum pipe pipe;
|
||||
struct intel_crtc *crtc;
|
||||
struct intel_encoder *encoder;
|
||||
@ -535,7 +536,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
|
||||
|
||||
for_each_intel_crtc(&i915->drm, crtc) {
|
||||
struct intel_bw_state *bw_state =
|
||||
to_intel_bw_state(i915->bw_obj.state);
|
||||
to_intel_bw_state(i915->display.bw.obj.state);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
to_intel_crtc_state(crtc->base.state);
|
||||
struct intel_plane *plane;
|
||||
|
@ -15,8 +15,8 @@
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_fdi.h"
|
||||
#include "intel_modeset_verify.h"
|
||||
#include "intel_pm.h"
|
||||
#include "intel_snps_phy.h"
|
||||
#include "skl_watermark.h"
|
||||
|
||||
/*
|
||||
* Cross check the actual hw state with our own modeset state tracking (and its
|
||||
@ -94,10 +94,10 @@ static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv,
|
||||
|
||||
/*
|
||||
* FDI already provided one idea for the dotclock.
|
||||
* Yell if the encoder disagrees.
|
||||
* Yell if the encoder disagrees. Allow for slight
|
||||
* rounding differences.
|
||||
*/
|
||||
drm_WARN(&dev_priv->drm,
|
||||
!intel_fuzzy_clock_check(fdi_dotclock, dotclock),
|
||||
drm_WARN(&dev_priv->drm, abs(fdi_dotclock - dotclock) > 1,
|
||||
"FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n",
|
||||
fdi_dotclock, dotclock);
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ struct opregion_asle_ext {
|
||||
|
||||
static int check_swsci_function(struct drm_i915_private *i915, u32 function)
|
||||
{
|
||||
struct opregion_swsci *swsci = i915->opregion.swsci;
|
||||
struct opregion_swsci *swsci = i915->display.opregion.swsci;
|
||||
u32 main_function, sub_function;
|
||||
|
||||
if (!swsci)
|
||||
@ -265,11 +265,11 @@ static int check_swsci_function(struct drm_i915_private *i915, u32 function)
|
||||
|
||||
/* Check if we can call the function. See swsci_setup for details. */
|
||||
if (main_function == SWSCI_SBCB) {
|
||||
if ((i915->opregion.swsci_sbcb_sub_functions &
|
||||
if ((i915->display.opregion.swsci_sbcb_sub_functions &
|
||||
(1 << sub_function)) == 0)
|
||||
return -EINVAL;
|
||||
} else if (main_function == SWSCI_GBDA) {
|
||||
if ((i915->opregion.swsci_gbda_sub_functions &
|
||||
if ((i915->display.opregion.swsci_gbda_sub_functions &
|
||||
(1 << sub_function)) == 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -280,7 +280,7 @@ static int check_swsci_function(struct drm_i915_private *i915, u32 function)
|
||||
static int swsci(struct drm_i915_private *dev_priv,
|
||||
u32 function, u32 parm, u32 *parm_out)
|
||||
{
|
||||
struct opregion_swsci *swsci = dev_priv->opregion.swsci;
|
||||
struct opregion_swsci *swsci = dev_priv->display.opregion.swsci;
|
||||
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
|
||||
u32 scic, dslp;
|
||||
u16 swsci_val;
|
||||
@ -462,7 +462,7 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp)
|
||||
{
|
||||
struct intel_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct opregion_asle *asle = dev_priv->opregion.asle;
|
||||
struct opregion_asle *asle = dev_priv->display.opregion.asle;
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
|
||||
drm_dbg(&dev_priv->drm, "bclp = 0x%08x\n", bclp);
|
||||
@ -586,8 +586,8 @@ static void asle_work(struct work_struct *work)
|
||||
struct intel_opregion *opregion =
|
||||
container_of(work, struct intel_opregion, asle_work);
|
||||
struct drm_i915_private *dev_priv =
|
||||
container_of(opregion, struct drm_i915_private, opregion);
|
||||
struct opregion_asle *asle = dev_priv->opregion.asle;
|
||||
container_of(opregion, struct drm_i915_private, display.opregion);
|
||||
struct opregion_asle *asle = dev_priv->display.opregion.asle;
|
||||
u32 aslc_stat = 0;
|
||||
u32 aslc_req;
|
||||
|
||||
@ -635,8 +635,8 @@ static void asle_work(struct work_struct *work)
|
||||
|
||||
void intel_opregion_asle_intr(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (dev_priv->opregion.asle)
|
||||
schedule_work(&dev_priv->opregion.asle_work);
|
||||
if (dev_priv->display.opregion.asle)
|
||||
schedule_work(&dev_priv->display.opregion.asle_work);
|
||||
}
|
||||
|
||||
#define ACPI_EV_DISPLAY_SWITCH (1<<0)
|
||||
@ -692,7 +692,7 @@ static void set_did(struct intel_opregion *opregion, int i, u32 val)
|
||||
|
||||
static void intel_didl_outputs(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_opregion *opregion = &dev_priv->opregion;
|
||||
struct intel_opregion *opregion = &dev_priv->display.opregion;
|
||||
struct intel_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
int i = 0, max_outputs;
|
||||
@ -731,7 +731,7 @@ static void intel_didl_outputs(struct drm_i915_private *dev_priv)
|
||||
|
||||
static void intel_setup_cadls(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_opregion *opregion = &dev_priv->opregion;
|
||||
struct intel_opregion *opregion = &dev_priv->display.opregion;
|
||||
struct intel_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
int i = 0;
|
||||
@ -761,7 +761,7 @@ static void intel_setup_cadls(struct drm_i915_private *dev_priv)
|
||||
|
||||
static void swsci_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_opregion *opregion = &dev_priv->opregion;
|
||||
struct intel_opregion *opregion = &dev_priv->display.opregion;
|
||||
bool requested_callbacks = false;
|
||||
u32 tmp;
|
||||
|
||||
@ -839,7 +839,7 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = {
|
||||
|
||||
static int intel_load_vbt_firmware(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_opregion *opregion = &dev_priv->opregion;
|
||||
struct intel_opregion *opregion = &dev_priv->display.opregion;
|
||||
const struct firmware *fw = NULL;
|
||||
const char *name = dev_priv->params.vbt_firmware;
|
||||
int ret;
|
||||
@ -879,7 +879,7 @@ static int intel_load_vbt_firmware(struct drm_i915_private *dev_priv)
|
||||
|
||||
int intel_opregion_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_opregion *opregion = &dev_priv->opregion;
|
||||
struct intel_opregion *opregion = &dev_priv->display.opregion;
|
||||
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
|
||||
u32 asls, mboxes;
|
||||
char buf[sizeof(OPREGION_SIGNATURE)];
|
||||
@ -1106,7 +1106,7 @@ struct edid *intel_opregion_get_edid(struct intel_connector *intel_connector)
|
||||
{
|
||||
struct drm_connector *connector = &intel_connector->base;
|
||||
struct drm_i915_private *i915 = to_i915(connector->dev);
|
||||
struct intel_opregion *opregion = &i915->opregion;
|
||||
struct intel_opregion *opregion = &i915->display.opregion;
|
||||
const void *in_edid;
|
||||
const struct edid *edid;
|
||||
struct edid *new_edid;
|
||||
@ -1141,7 +1141,7 @@ struct edid *intel_opregion_get_edid(struct intel_connector *intel_connector)
|
||||
|
||||
bool intel_opregion_headless_sku(struct drm_i915_private *i915)
|
||||
{
|
||||
struct intel_opregion *opregion = &i915->opregion;
|
||||
struct intel_opregion *opregion = &i915->display.opregion;
|
||||
struct opregion_header *header = opregion->header;
|
||||
|
||||
if (!header || header->over.major < 2 ||
|
||||
@ -1153,7 +1153,7 @@ bool intel_opregion_headless_sku(struct drm_i915_private *i915)
|
||||
|
||||
void intel_opregion_register(struct drm_i915_private *i915)
|
||||
{
|
||||
struct intel_opregion *opregion = &i915->opregion;
|
||||
struct intel_opregion *opregion = &i915->display.opregion;
|
||||
|
||||
if (!opregion->header)
|
||||
return;
|
||||
@ -1169,7 +1169,7 @@ void intel_opregion_register(struct drm_i915_private *i915)
|
||||
|
||||
void intel_opregion_resume(struct drm_i915_private *i915)
|
||||
{
|
||||
struct intel_opregion *opregion = &i915->opregion;
|
||||
struct intel_opregion *opregion = &i915->display.opregion;
|
||||
|
||||
if (!opregion->header)
|
||||
return;
|
||||
@ -1200,7 +1200,7 @@ void intel_opregion_resume(struct drm_i915_private *i915)
|
||||
|
||||
void intel_opregion_suspend(struct drm_i915_private *i915, pci_power_t state)
|
||||
{
|
||||
struct intel_opregion *opregion = &i915->opregion;
|
||||
struct intel_opregion *opregion = &i915->display.opregion;
|
||||
|
||||
if (!opregion->header)
|
||||
return;
|
||||
@ -1210,7 +1210,7 @@ void intel_opregion_suspend(struct drm_i915_private *i915, pci_power_t state)
|
||||
if (opregion->asle)
|
||||
opregion->asle->ardy = ASLE_ARDY_NOT_READY;
|
||||
|
||||
cancel_work_sync(&i915->opregion.asle_work);
|
||||
cancel_work_sync(&i915->display.opregion.asle_work);
|
||||
|
||||
if (opregion->acpi)
|
||||
opregion->acpi->drdy = 0;
|
||||
@ -1218,7 +1218,7 @@ void intel_opregion_suspend(struct drm_i915_private *i915, pci_power_t state)
|
||||
|
||||
void intel_opregion_unregister(struct drm_i915_private *i915)
|
||||
{
|
||||
struct intel_opregion *opregion = &i915->opregion;
|
||||
struct intel_opregion *opregion = &i915->display.opregion;
|
||||
|
||||
intel_opregion_suspend(i915, PCI_D1);
|
||||
|
||||
|
@ -211,9 +211,9 @@ static void i830_overlay_clock_gating(struct drm_i915_private *dev_priv,
|
||||
|
||||
/* WA_OVERLAY_CLKGATE:alm */
|
||||
if (enable)
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D, 0);
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D(dev_priv), 0);
|
||||
else
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D,
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D(dev_priv),
|
||||
OVRUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
/* WA_DISABLE_L2CACHE_CLOCK_GATING:alm */
|
||||
|
@ -37,13 +37,14 @@
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_drrs.h"
|
||||
#include "intel_panel.h"
|
||||
#include "intel_quirks.h"
|
||||
|
||||
bool intel_panel_use_ssc(struct drm_i915_private *i915)
|
||||
{
|
||||
if (i915->params.panel_use_ssc >= 0)
|
||||
return i915->params.panel_use_ssc != 0;
|
||||
return i915->vbt.lvds_use_ssc
|
||||
&& !(i915->quirks & QUIRK_LVDS_SSC_DISABLE);
|
||||
return i915->display.vbt.lvds_use_ssc &&
|
||||
!intel_has_quirk(i915, QUIRK_LVDS_SSC_DISABLE);
|
||||
}
|
||||
|
||||
const struct drm_display_mode *
|
||||
@ -81,15 +82,14 @@ static bool is_alt_drrs_mode(const struct drm_display_mode *mode,
|
||||
mode->clock != preferred_mode->clock;
|
||||
}
|
||||
|
||||
static bool is_alt_vrr_mode(const struct drm_display_mode *mode,
|
||||
const struct drm_display_mode *preferred_mode)
|
||||
static bool is_alt_fixed_mode(const struct drm_display_mode *mode,
|
||||
const struct drm_display_mode *preferred_mode)
|
||||
{
|
||||
return drm_mode_match(mode, preferred_mode,
|
||||
DRM_MODE_MATCH_FLAGS |
|
||||
DRM_MODE_MATCH_3D_FLAGS) &&
|
||||
mode->hdisplay == preferred_mode->hdisplay &&
|
||||
mode->vdisplay == preferred_mode->vdisplay &&
|
||||
mode->clock != preferred_mode->clock;
|
||||
mode->vdisplay == preferred_mode->vdisplay;
|
||||
}
|
||||
|
||||
const struct drm_display_mode *
|
||||
@ -114,6 +114,21 @@ intel_panel_downclock_mode(struct intel_connector *connector,
|
||||
return best_mode;
|
||||
}
|
||||
|
||||
const struct drm_display_mode *
|
||||
intel_panel_highest_mode(struct intel_connector *connector,
|
||||
const struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
const struct drm_display_mode *fixed_mode, *best_mode = adjusted_mode;
|
||||
|
||||
/* pick the fixed_mode that has the highest clock */
|
||||
list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) {
|
||||
if (fixed_mode->clock > best_mode->clock)
|
||||
best_mode = fixed_mode;
|
||||
}
|
||||
|
||||
return best_mode;
|
||||
}
|
||||
|
||||
int intel_panel_get_modes(struct intel_connector *connector)
|
||||
{
|
||||
const struct drm_display_mode *fixed_mode;
|
||||
@ -172,19 +187,7 @@ int intel_panel_compute_config(struct intel_connector *connector,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_alt_fixed_mode(const struct drm_display_mode *mode,
|
||||
const struct drm_display_mode *preferred_mode,
|
||||
bool has_vrr)
|
||||
{
|
||||
/* is_alt_drrs_mode() is a subset of is_alt_vrr_mode() */
|
||||
if (has_vrr)
|
||||
return is_alt_vrr_mode(mode, preferred_mode);
|
||||
else
|
||||
return is_alt_drrs_mode(mode, preferred_mode);
|
||||
}
|
||||
|
||||
static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connector,
|
||||
bool has_vrr)
|
||||
static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connector)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
|
||||
const struct drm_display_mode *preferred_mode =
|
||||
@ -192,7 +195,7 @@ static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connect
|
||||
struct drm_display_mode *mode, *next;
|
||||
|
||||
list_for_each_entry_safe(mode, next, &connector->base.probed_modes, head) {
|
||||
if (!is_alt_fixed_mode(mode, preferred_mode, has_vrr))
|
||||
if (!is_alt_fixed_mode(mode, preferred_mode))
|
||||
continue;
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
@ -255,7 +258,7 @@ void intel_panel_add_edid_fixed_modes(struct intel_connector *connector,
|
||||
{
|
||||
intel_panel_add_edid_preferred_mode(connector);
|
||||
if (intel_panel_preferred_fixed_mode(connector) && (has_drrs || has_vrr))
|
||||
intel_panel_add_edid_alt_fixed_modes(connector, has_vrr);
|
||||
intel_panel_add_edid_alt_fixed_modes(connector);
|
||||
intel_panel_destroy_probed_modes(connector);
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,9 @@ intel_panel_fixed_mode(struct intel_connector *connector,
|
||||
const struct drm_display_mode *
|
||||
intel_panel_downclock_mode(struct intel_connector *connector,
|
||||
const struct drm_display_mode *adjusted_mode);
|
||||
const struct drm_display_mode *
|
||||
intel_panel_highest_mode(struct intel_connector *connector,
|
||||
const struct drm_display_mode *adjusted_mode);
|
||||
int intel_panel_get_modes(struct intel_connector *connector);
|
||||
enum drrs_type intel_panel_drrs_type(struct intel_connector *connector);
|
||||
enum drm_mode_status
|
||||
|
@ -167,6 +167,15 @@ static void lpt_compute_iclkip(struct iclkip_params *p, int clock)
|
||||
}
|
||||
}
|
||||
|
||||
int lpt_iclkip(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct iclkip_params p;
|
||||
|
||||
lpt_compute_iclkip(&p, crtc_state->hw.adjusted_mode.crtc_clock);
|
||||
|
||||
return lpt_iclkip_freq(&p);
|
||||
}
|
||||
|
||||
/* Program iCLKIP clock to the desired frequency */
|
||||
void lpt_program_iclkip(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
@ -179,6 +188,7 @@ void lpt_program_iclkip(const struct intel_crtc_state *crtc_state)
|
||||
lpt_disable_iclkip(dev_priv);
|
||||
|
||||
lpt_compute_iclkip(&p, clock);
|
||||
drm_WARN_ON(&dev_priv->drm, lpt_iclkip_freq(&p) != clock);
|
||||
|
||||
/* This should not happen with any sane values */
|
||||
drm_WARN_ON(&dev_priv->drm, SBI_SSCDIVINTPHASE_DIVSEL(p.divsel) &
|
||||
@ -514,7 +524,7 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv)
|
||||
}
|
||||
|
||||
if (HAS_PCH_IBX(dev_priv)) {
|
||||
has_ck505 = dev_priv->vbt.display_clock_mode;
|
||||
has_ck505 = dev_priv->display.vbt.display_clock_mode;
|
||||
can_ssc = has_ck505;
|
||||
} else {
|
||||
has_ck505 = false;
|
||||
@ -654,7 +664,7 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv)
|
||||
}
|
||||
}
|
||||
|
||||
BUG_ON(val != final);
|
||||
drm_WARN_ON(&dev_priv->drm, val != final);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -14,6 +14,7 @@ struct intel_crtc_state;
|
||||
void lpt_program_iclkip(const struct intel_crtc_state *crtc_state);
|
||||
void lpt_disable_iclkip(struct drm_i915_private *dev_priv);
|
||||
int lpt_get_iclkip(struct drm_i915_private *dev_priv);
|
||||
int lpt_iclkip(const struct intel_crtc_state *crtc_state);
|
||||
|
||||
void intel_init_pch_refclk(struct drm_i915_private *dev_priv);
|
||||
void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "intel_dpll.h"
|
||||
#include "intel_lvds.h"
|
||||
#include "intel_pps.h"
|
||||
#include "intel_quirks.h"
|
||||
|
||||
static void vlv_steal_power_sequencer(struct drm_i915_private *dev_priv,
|
||||
enum pipe pipe);
|
||||
@ -1202,7 +1203,7 @@ static void pps_init_delays_vbt(struct intel_dp *intel_dp,
|
||||
* just fails to power back on. Increasing the delay to 800ms
|
||||
* seems sufficient to avoid this problem.
|
||||
*/
|
||||
if (dev_priv->quirks & QUIRK_INCREASE_T12_DELAY) {
|
||||
if (intel_has_quirk(dev_priv, QUIRK_INCREASE_T12_DELAY)) {
|
||||
vbt->t11_t12 = max_t(u16, vbt->t11_t12, 1300 * 10);
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Increasing T12 panel delay as per the quirk to %d\n",
|
||||
|
@ -805,13 +805,14 @@ static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_dp *intel_d
|
||||
hblank_total = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
|
||||
hblank_ns = div_u64(1000000ULL * hblank_total, adjusted_mode->crtc_clock);
|
||||
|
||||
/* From spec: (72 / number of lanes) * 1000 / symbol clock frequency MHz */
|
||||
req_ns = (72 / crtc_state->lane_count) * 1000 / (crtc_state->port_clock / 1000);
|
||||
/* From spec: ((60 / number of lanes) + 11) * 1000 / symbol clock frequency MHz */
|
||||
req_ns = ((60 / crtc_state->lane_count) + 11) * 1000 / (crtc_state->port_clock / 1000);
|
||||
|
||||
if ((hblank_ns - req_ns) > 100)
|
||||
return true;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) < 13 || intel_dp->edp_dpcd[0] < DP_EDP_14b)
|
||||
/* Not supported <13 / Wa_22012279113:adl-p */
|
||||
if (DISPLAY_VER(dev_priv) <= 13 || intel_dp->edp_dpcd[0] < DP_EDP_14b)
|
||||
return false;
|
||||
|
||||
crtc_state->req_psr2_sdp_prior_scanline = true;
|
||||
@ -1721,8 +1722,6 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
|
||||
new_plane_state, i) {
|
||||
struct drm_rect src, damaged_area = { .x1 = 0, .y1 = -1,
|
||||
.x2 = INT_MAX };
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
struct drm_rect clip;
|
||||
|
||||
if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc)
|
||||
continue;
|
||||
@ -1767,22 +1766,18 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
|
||||
continue;
|
||||
}
|
||||
|
||||
drm_rect_fp_to_int(&src, &new_plane_state->uapi.src);
|
||||
src = drm_plane_state_src(&new_plane_state->uapi);
|
||||
drm_rect_fp_to_int(&src, &src);
|
||||
|
||||
drm_atomic_helper_damage_iter_init(&iter,
|
||||
&old_plane_state->uapi,
|
||||
&new_plane_state->uapi);
|
||||
drm_atomic_for_each_plane_damage(&iter, &clip) {
|
||||
if (drm_rect_intersect(&clip, &src))
|
||||
clip_area_update(&damaged_area, &clip,
|
||||
&crtc_state->pipe_src);
|
||||
}
|
||||
|
||||
if (damaged_area.y1 == -1)
|
||||
if (!drm_atomic_helper_damage_merged(&old_plane_state->uapi,
|
||||
&new_plane_state->uapi, &damaged_area))
|
||||
continue;
|
||||
|
||||
damaged_area.y1 += new_plane_state->uapi.dst.y1 - src.y1;
|
||||
damaged_area.y2 += new_plane_state->uapi.dst.y1 - src.y1;
|
||||
damaged_area.x1 += new_plane_state->uapi.dst.x1 - src.x1;
|
||||
damaged_area.x2 += new_plane_state->uapi.dst.x1 - src.x1;
|
||||
|
||||
clip_area_update(&pipe_clip, &damaged_area, &crtc_state->pipe_src);
|
||||
}
|
||||
|
||||
|
@ -9,12 +9,17 @@
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_quirks.h"
|
||||
|
||||
static void intel_set_quirk(struct drm_i915_private *i915, enum intel_quirk_id quirk)
|
||||
{
|
||||
i915->display.quirks.mask |= BIT(quirk);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some machines (Lenovo U160) do not work with SSC on LVDS for some reason
|
||||
*/
|
||||
static void quirk_ssc_force_disable(struct drm_i915_private *i915)
|
||||
{
|
||||
i915->quirks |= QUIRK_LVDS_SSC_DISABLE;
|
||||
intel_set_quirk(i915, QUIRK_LVDS_SSC_DISABLE);
|
||||
drm_info(&i915->drm, "applying lvds SSC disable quirk\n");
|
||||
}
|
||||
|
||||
@ -24,14 +29,14 @@ static void quirk_ssc_force_disable(struct drm_i915_private *i915)
|
||||
*/
|
||||
static void quirk_invert_brightness(struct drm_i915_private *i915)
|
||||
{
|
||||
i915->quirks |= QUIRK_INVERT_BRIGHTNESS;
|
||||
intel_set_quirk(i915, QUIRK_INVERT_BRIGHTNESS);
|
||||
drm_info(&i915->drm, "applying inverted panel brightness quirk\n");
|
||||
}
|
||||
|
||||
/* Some VBT's incorrectly indicate no backlight is present */
|
||||
static void quirk_backlight_present(struct drm_i915_private *i915)
|
||||
{
|
||||
i915->quirks |= QUIRK_BACKLIGHT_PRESENT;
|
||||
intel_set_quirk(i915, QUIRK_BACKLIGHT_PRESENT);
|
||||
drm_info(&i915->drm, "applying backlight present quirk\n");
|
||||
}
|
||||
|
||||
@ -40,7 +45,7 @@ static void quirk_backlight_present(struct drm_i915_private *i915)
|
||||
*/
|
||||
static void quirk_increase_t12_delay(struct drm_i915_private *i915)
|
||||
{
|
||||
i915->quirks |= QUIRK_INCREASE_T12_DELAY;
|
||||
intel_set_quirk(i915, QUIRK_INCREASE_T12_DELAY);
|
||||
drm_info(&i915->drm, "Applying T12 delay quirk\n");
|
||||
}
|
||||
|
||||
@ -50,13 +55,13 @@ static void quirk_increase_t12_delay(struct drm_i915_private *i915)
|
||||
*/
|
||||
static void quirk_increase_ddi_disabled_time(struct drm_i915_private *i915)
|
||||
{
|
||||
i915->quirks |= QUIRK_INCREASE_DDI_DISABLED_TIME;
|
||||
intel_set_quirk(i915, QUIRK_INCREASE_DDI_DISABLED_TIME);
|
||||
drm_info(&i915->drm, "Applying Increase DDI Disabled quirk\n");
|
||||
}
|
||||
|
||||
static void quirk_no_pps_backlight_power_hook(struct drm_i915_private *i915)
|
||||
{
|
||||
i915->quirks |= QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK;
|
||||
intel_set_quirk(i915, QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK);
|
||||
drm_info(&i915->drm, "Applying no pps backlight power quirk\n");
|
||||
}
|
||||
|
||||
@ -216,3 +221,8 @@ void intel_init_quirks(struct drm_i915_private *i915)
|
||||
intel_dmi_quirks[i].hook(i915);
|
||||
}
|
||||
}
|
||||
|
||||
bool intel_has_quirk(struct drm_i915_private *i915, enum intel_quirk_id quirk)
|
||||
{
|
||||
return i915->display.quirks.mask & BIT(quirk);
|
||||
}
|
||||
|
@ -6,8 +6,20 @@
|
||||
#ifndef __INTEL_QUIRKS_H__
|
||||
#define __INTEL_QUIRKS_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct drm_i915_private;
|
||||
|
||||
void intel_init_quirks(struct drm_i915_private *dev_priv);
|
||||
enum intel_quirk_id {
|
||||
QUIRK_BACKLIGHT_PRESENT,
|
||||
QUIRK_INCREASE_DDI_DISABLED_TIME,
|
||||
QUIRK_INCREASE_T12_DELAY,
|
||||
QUIRK_INVERT_BRIGHTNESS,
|
||||
QUIRK_LVDS_SSC_DISABLE,
|
||||
QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK,
|
||||
};
|
||||
|
||||
void intel_init_quirks(struct drm_i915_private *i915);
|
||||
bool intel_has_quirk(struct drm_i915_private *i915, enum intel_quirk_id quirk);
|
||||
|
||||
#endif /* __INTEL_QUIRKS_H__ */
|
||||
|
@ -2016,7 +2016,7 @@ intel_sdvo_get_analog_edid(struct drm_connector *connector)
|
||||
|
||||
return drm_get_edid(connector,
|
||||
intel_gmbus_get_adapter(dev_priv,
|
||||
dev_priv->vbt.crt_ddc_pin));
|
||||
dev_priv->display.vbt.crt_ddc_pin));
|
||||
}
|
||||
|
||||
static enum drm_connector_status
|
||||
@ -2581,9 +2581,9 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,
|
||||
struct sdvo_device_mapping *mapping;
|
||||
|
||||
if (sdvo->port == PORT_B)
|
||||
mapping = &dev_priv->vbt.sdvo_mappings[0];
|
||||
mapping = &dev_priv->display.vbt.sdvo_mappings[0];
|
||||
else
|
||||
mapping = &dev_priv->vbt.sdvo_mappings[1];
|
||||
mapping = &dev_priv->display.vbt.sdvo_mappings[1];
|
||||
|
||||
if (mapping->initialized)
|
||||
sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4);
|
||||
@ -2599,9 +2599,9 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv,
|
||||
u8 pin;
|
||||
|
||||
if (sdvo->port == PORT_B)
|
||||
mapping = &dev_priv->vbt.sdvo_mappings[0];
|
||||
mapping = &dev_priv->display.vbt.sdvo_mappings[0];
|
||||
else
|
||||
mapping = &dev_priv->vbt.sdvo_mappings[1];
|
||||
mapping = &dev_priv->display.vbt.sdvo_mappings[1];
|
||||
|
||||
if (mapping->initialized &&
|
||||
intel_gmbus_is_valid_pin(dev_priv, mapping->i2c_pin))
|
||||
@ -2639,11 +2639,11 @@ intel_sdvo_get_slave_addr(struct drm_i915_private *dev_priv,
|
||||
struct sdvo_device_mapping *my_mapping, *other_mapping;
|
||||
|
||||
if (sdvo->port == PORT_B) {
|
||||
my_mapping = &dev_priv->vbt.sdvo_mappings[0];
|
||||
other_mapping = &dev_priv->vbt.sdvo_mappings[1];
|
||||
my_mapping = &dev_priv->display.vbt.sdvo_mappings[0];
|
||||
other_mapping = &dev_priv->display.vbt.sdvo_mappings[1];
|
||||
} else {
|
||||
my_mapping = &dev_priv->vbt.sdvo_mappings[1];
|
||||
other_mapping = &dev_priv->vbt.sdvo_mappings[0];
|
||||
my_mapping = &dev_priv->display.vbt.sdvo_mappings[1];
|
||||
other_mapping = &dev_priv->display.vbt.sdvo_mappings[0];
|
||||
}
|
||||
|
||||
/* If the BIOS described our SDVO device, take advantage of it. */
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dpll.h"
|
||||
#include "intel_hotplug.h"
|
||||
#include "intel_tv.h"
|
||||
|
||||
@ -982,10 +983,10 @@ intel_tv_mode_vdisplay(const struct tv_mode *tv_mode)
|
||||
|
||||
static void
|
||||
intel_tv_mode_to_mode(struct drm_display_mode *mode,
|
||||
const struct tv_mode *tv_mode)
|
||||
const struct tv_mode *tv_mode,
|
||||
int clock)
|
||||
{
|
||||
mode->clock = tv_mode->clock /
|
||||
(tv_mode->oversample >> !tv_mode->progressive);
|
||||
mode->clock = clock / (tv_mode->oversample >> !tv_mode->progressive);
|
||||
|
||||
/*
|
||||
* tv_mode horizontal timings:
|
||||
@ -1143,7 +1144,7 @@ intel_tv_get_config(struct intel_encoder *encoder,
|
||||
xsize = tmp >> 16;
|
||||
ysize = tmp & 0xffff;
|
||||
|
||||
intel_tv_mode_to_mode(&mode, &tv_mode);
|
||||
intel_tv_mode_to_mode(&mode, &tv_mode, pipe_config->port_clock);
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "TV mode: " DRM_MODE_FMT "\n",
|
||||
DRM_MODE_ARG(&mode));
|
||||
@ -1184,6 +1185,9 @@ intel_tv_compute_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_atomic_state *state =
|
||||
to_intel_atomic_state(pipe_config->uapi.state);
|
||||
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_tv_connector_state *tv_conn_state =
|
||||
to_intel_tv_connector_state(conn_state);
|
||||
@ -1192,6 +1196,7 @@ intel_tv_compute_config(struct intel_encoder *encoder,
|
||||
&pipe_config->hw.adjusted_mode;
|
||||
int hdisplay = adjusted_mode->crtc_hdisplay;
|
||||
int vdisplay = adjusted_mode->crtc_vdisplay;
|
||||
int ret;
|
||||
|
||||
if (!tv_mode)
|
||||
return -EINVAL;
|
||||
@ -1206,7 +1211,13 @@ intel_tv_compute_config(struct intel_encoder *encoder,
|
||||
|
||||
pipe_config->port_clock = tv_mode->clock;
|
||||
|
||||
intel_tv_mode_to_mode(adjusted_mode, tv_mode);
|
||||
ret = intel_dpll_crtc_compute_clock(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pipe_config->clock_set = true;
|
||||
|
||||
intel_tv_mode_to_mode(adjusted_mode, tv_mode, pipe_config->port_clock);
|
||||
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
||||
|
||||
if (intel_tv_source_too_wide(dev_priv, hdisplay) ||
|
||||
@ -1804,7 +1815,7 @@ intel_tv_get_modes(struct drm_connector *connector)
|
||||
* about the actual timings of the mode. We
|
||||
* do ignore the margins though.
|
||||
*/
|
||||
intel_tv_mode_to_mode(mode, tv_mode);
|
||||
intel_tv_mode_to_mode(mode, tv_mode, tv_mode->clock);
|
||||
if (count == 0) {
|
||||
drm_dbg_kms(&dev_priv->drm, "TV mode: " DRM_MODE_FMT "\n",
|
||||
DRM_MODE_ARG(mode));
|
||||
|
@ -75,6 +75,20 @@ struct bdb_header {
|
||||
u16 bdb_size;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* BDB version number dependencies are documented as:
|
||||
*
|
||||
* <start>+
|
||||
* indicates the field was introduced in version <start>
|
||||
* and is still valid
|
||||
*
|
||||
* <start>-<end>
|
||||
* indicates the field was introduced in version <start>
|
||||
* and obsoleted in version <end>+1.
|
||||
*
|
||||
* ??? indicates the specific version number is unknown
|
||||
*/
|
||||
|
||||
/*
|
||||
* There are several types of BIOS data blocks (BDBs), each block has
|
||||
* an ID and size in the first 3 bytes (ID in first, size in next 2).
|
||||
@ -144,12 +158,12 @@ struct bdb_general_features {
|
||||
/* bits 3 */
|
||||
u8 disable_smooth_vision:1;
|
||||
u8 single_dvi:1;
|
||||
u8 rotate_180:1; /* 181 */
|
||||
u8 rotate_180:1; /* 181+ */
|
||||
u8 fdi_rx_polarity_inverted:1;
|
||||
u8 vbios_extended_mode:1; /* 160 */
|
||||
u8 copy_ilfp_dtd_to_sdvo_lvds_dtd:1; /* 160 */
|
||||
u8 panel_best_fit_timing:1; /* 160 */
|
||||
u8 ignore_strap_state:1; /* 160 */
|
||||
u8 vbios_extended_mode:1; /* 160+ */
|
||||
u8 copy_ilfp_dtd_to_sdvo_lvds_dtd:1; /* 160+ */
|
||||
u8 panel_best_fit_timing:1; /* 160+ */
|
||||
u8 ignore_strap_state:1; /* 160+ */
|
||||
|
||||
/* bits 4 */
|
||||
u8 legacy_monitor_detect;
|
||||
@ -164,11 +178,11 @@ struct bdb_general_features {
|
||||
u8 rsvd11:2; /* finish byte */
|
||||
|
||||
/* bits 6 */
|
||||
u8 tc_hpd_retry_timeout:7; /* 242 */
|
||||
u8 tc_hpd_retry_timeout:7; /* 242+ */
|
||||
u8 rsvd12:1;
|
||||
|
||||
/* bits 7 */
|
||||
u8 afc_startup_config:2;/* 249 */
|
||||
u8 afc_startup_config:2; /* 249+ */
|
||||
u8 rsvd13:6;
|
||||
} __packed;
|
||||
|
||||
@ -183,6 +197,15 @@ struct bdb_general_features {
|
||||
#define GPIO_PIN_ADD_DDC_I2C 0x06 /* "ADDCARD DDC/I2C GPIO pins" */
|
||||
|
||||
/* Device handle */
|
||||
#define DEVICE_HANDLE_CRT 0x0001
|
||||
#define DEVICE_HANDLE_EFP1 0x0004
|
||||
#define DEVICE_HANDLE_EFP2 0x0040
|
||||
#define DEVICE_HANDLE_EFP3 0x0020
|
||||
#define DEVICE_HANDLE_EFP4 0x0010 /* 194+ */
|
||||
#define DEVICE_HANDLE_EFP5 0x0002 /* 215+ */
|
||||
#define DEVICE_HANDLE_EFP6 0x0001 /* 217+ */
|
||||
#define DEVICE_HANDLE_EFP7 0x0100 /* 217+ */
|
||||
#define DEVICE_HANDLE_EFP8 0x0200 /* 217+ */
|
||||
#define DEVICE_HANDLE_LFP1 0x0008
|
||||
#define DEVICE_HANDLE_LFP2 0x0080
|
||||
|
||||
@ -275,27 +298,27 @@ struct bdb_general_features {
|
||||
#define DVO_PORT_DPC 8
|
||||
#define DVO_PORT_DPD 9
|
||||
#define DVO_PORT_DPA 10
|
||||
#define DVO_PORT_DPE 11 /* 193 */
|
||||
#define DVO_PORT_HDMIE 12 /* 193 */
|
||||
#define DVO_PORT_DPE 11 /* 193+ */
|
||||
#define DVO_PORT_HDMIE 12 /* 193+ */
|
||||
#define DVO_PORT_DPF 13 /* N/A */
|
||||
#define DVO_PORT_HDMIF 14 /* N/A */
|
||||
#define DVO_PORT_DPG 15 /* 217 */
|
||||
#define DVO_PORT_HDMIG 16 /* 217 */
|
||||
#define DVO_PORT_DPH 17 /* 217 */
|
||||
#define DVO_PORT_HDMIH 18 /* 217 */
|
||||
#define DVO_PORT_DPI 19 /* 217 */
|
||||
#define DVO_PORT_HDMII 20 /* 217 */
|
||||
#define DVO_PORT_MIPIA 21 /* 171 */
|
||||
#define DVO_PORT_MIPIB 22 /* 171 */
|
||||
#define DVO_PORT_MIPIC 23 /* 171 */
|
||||
#define DVO_PORT_MIPID 24 /* 171 */
|
||||
#define DVO_PORT_DPG 15 /* 217+ */
|
||||
#define DVO_PORT_HDMIG 16 /* 217+ */
|
||||
#define DVO_PORT_DPH 17 /* 217+ */
|
||||
#define DVO_PORT_HDMIH 18 /* 217+ */
|
||||
#define DVO_PORT_DPI 19 /* 217+ */
|
||||
#define DVO_PORT_HDMII 20 /* 217+ */
|
||||
#define DVO_PORT_MIPIA 21 /* 171+ */
|
||||
#define DVO_PORT_MIPIB 22 /* 171+ */
|
||||
#define DVO_PORT_MIPIC 23 /* 171+ */
|
||||
#define DVO_PORT_MIPID 24 /* 171+ */
|
||||
|
||||
#define HDMI_MAX_DATA_RATE_PLATFORM 0 /* 204 */
|
||||
#define HDMI_MAX_DATA_RATE_297 1 /* 204 */
|
||||
#define HDMI_MAX_DATA_RATE_165 2 /* 204 */
|
||||
#define HDMI_MAX_DATA_RATE_594 3 /* 249 */
|
||||
#define HDMI_MAX_DATA_RATE_340 4 /* 249 */
|
||||
#define HDMI_MAX_DATA_RATE_300 5 /* 249 */
|
||||
#define HDMI_MAX_DATA_RATE_PLATFORM 0 /* 204+ */
|
||||
#define HDMI_MAX_DATA_RATE_297 1 /* 204+ */
|
||||
#define HDMI_MAX_DATA_RATE_165 2 /* 204+ */
|
||||
#define HDMI_MAX_DATA_RATE_594 3 /* 249+ */
|
||||
#define HDMI_MAX_DATA_RATE_340 4 /* 249+ */
|
||||
#define HDMI_MAX_DATA_RATE_300 5 /* 249+ */
|
||||
|
||||
#define LEGACY_CHILD_DEVICE_CONFIG_SIZE 33
|
||||
|
||||
@ -362,10 +385,10 @@ enum vbt_gmbus_ddi {
|
||||
* basically any of the fields to ensure the correct interpretation for the BDB
|
||||
* version in question.
|
||||
*
|
||||
* When we copy the child device configs to dev_priv->vbt.child_dev, we reserve
|
||||
* space for the full structure below, and initialize the tail not actually
|
||||
* present in VBT to zeros. Accessing those fields is fine, as long as the
|
||||
* default zero is taken into account, again according to the BDB version.
|
||||
* When we copy the child device configs to dev_priv->display.vbt.child_dev, we
|
||||
* reserve space for the full structure below, and initialize the tail not
|
||||
* actually present in VBT to zeros. Accessing those fields is fine, as long as
|
||||
* the default zero is taken into account, again according to the BDB version.
|
||||
*
|
||||
* BDB versions 155 and below are considered legacy, and version 155 seems to be
|
||||
* a baseline for some of the VBT documentation. When adding new fields, please
|
||||
@ -379,20 +402,30 @@ struct child_device_config {
|
||||
u8 device_id[10]; /* ascii string */
|
||||
struct {
|
||||
u8 i2c_speed;
|
||||
u8 dp_onboard_redriver; /* 158 */
|
||||
u8 dp_ondock_redriver; /* 158 */
|
||||
u8 hdmi_level_shifter_value:5; /* 169 */
|
||||
u8 hdmi_max_data_rate:3; /* 204 */
|
||||
u16 dtd_buf_ptr; /* 161 */
|
||||
u8 edidless_efp:1; /* 161 */
|
||||
u8 compression_enable:1; /* 198 */
|
||||
u8 compression_method_cps:1; /* 198 */
|
||||
u8 ganged_edp:1; /* 202 */
|
||||
u8 reserved0:4;
|
||||
u8 compression_structure_index:4; /* 198 */
|
||||
u8 reserved1:4;
|
||||
u8 slave_port; /* 202 */
|
||||
u8 reserved2;
|
||||
u8 dp_onboard_redriver_preemph:3; /* 158+ */
|
||||
u8 dp_onboard_redriver_vswing:3; /* 158+ */
|
||||
u8 dp_onboard_redriver_present:1; /* 158+ */
|
||||
u8 reserved0:1;
|
||||
u8 dp_ondock_redriver_preemph:3; /* 158+ */
|
||||
u8 dp_ondock_redriver_vswing:3; /* 158+ */
|
||||
u8 dp_ondock_redriver_present:1; /* 158+ */
|
||||
u8 reserved1:1;
|
||||
u8 hdmi_level_shifter_value:5; /* 158+ */
|
||||
u8 hdmi_max_data_rate:3; /* 204+ */
|
||||
u16 dtd_buf_ptr; /* 161+ */
|
||||
u8 edidless_efp:1; /* 161+ */
|
||||
u8 compression_enable:1; /* 198+ */
|
||||
u8 compression_method_cps:1; /* 198+ */
|
||||
u8 ganged_edp:1; /* 202+ */
|
||||
u8 lttpr_non_transparent:1; /* 235+ */
|
||||
u8 disable_compression_for_ext_disp:1; /* 251+ */
|
||||
u8 reserved2:2;
|
||||
u8 compression_structure_index:4; /* 198+ */
|
||||
u8 reserved3:4;
|
||||
u8 hdmi_max_frl_rate:4; /* 237+ */
|
||||
u8 hdmi_max_frl_rate_valid:1; /* 237+ */
|
||||
u8 reserved4:3; /* 237+ */
|
||||
u8 reserved5;
|
||||
} __packed;
|
||||
} __packed;
|
||||
|
||||
@ -412,16 +445,16 @@ struct child_device_config {
|
||||
u8 ddc2_pin;
|
||||
} __packed;
|
||||
struct {
|
||||
u8 efp_routed:1; /* 158 */
|
||||
u8 lane_reversal:1; /* 184 */
|
||||
u8 lspcon:1; /* 192 */
|
||||
u8 iboost:1; /* 196 */
|
||||
u8 hpd_invert:1; /* 196 */
|
||||
u8 use_vbt_vswing:1; /* 218 */
|
||||
u8 flag_reserved:2;
|
||||
u8 hdmi_support:1; /* 158 */
|
||||
u8 dp_support:1; /* 158 */
|
||||
u8 tmds_support:1; /* 158 */
|
||||
u8 efp_routed:1; /* 158+ */
|
||||
u8 lane_reversal:1; /* 184+ */
|
||||
u8 lspcon:1; /* 192+ */
|
||||
u8 iboost:1; /* 196+ */
|
||||
u8 hpd_invert:1; /* 196+ */
|
||||
u8 use_vbt_vswing:1; /* 218+ */
|
||||
u8 dp_max_lane_count:2; /* 244+ */
|
||||
u8 hdmi_support:1; /* 158+ */
|
||||
u8 dp_support:1; /* 158+ */
|
||||
u8 tmds_support:1; /* 158+ */
|
||||
u8 support_reserved:5;
|
||||
u8 aux_channel;
|
||||
u8 dongle_detect;
|
||||
@ -429,7 +462,7 @@ struct child_device_config {
|
||||
} __packed;
|
||||
|
||||
u8 pipe_cap:2;
|
||||
u8 sdvo_stall:1; /* 158 */
|
||||
u8 sdvo_stall:1; /* 158+ */
|
||||
u8 hpd_status:2;
|
||||
u8 integrated_encoder:1;
|
||||
u8 capabilities_reserved:2;
|
||||
@ -437,21 +470,21 @@ struct child_device_config {
|
||||
|
||||
union {
|
||||
u8 dvo2_wiring;
|
||||
u8 mipi_bridge_type; /* 171 */
|
||||
u8 mipi_bridge_type; /* 171+ */
|
||||
} __packed;
|
||||
|
||||
u16 extended_type;
|
||||
u8 dvo_function;
|
||||
u8 dp_usb_type_c:1; /* 195 */
|
||||
u8 tbt:1; /* 209 */
|
||||
u8 flags2_reserved:2; /* 195 */
|
||||
u8 dp_port_trace_length:4; /* 209 */
|
||||
u8 dp_gpio_index; /* 195 */
|
||||
u16 dp_gpio_pin_num; /* 195 */
|
||||
u8 dp_iboost_level:4; /* 196 */
|
||||
u8 hdmi_iboost_level:4; /* 196 */
|
||||
u8 dp_max_link_rate:3; /* 216/230 GLK+ */
|
||||
u8 dp_max_link_rate_reserved:5; /* 216/230 */
|
||||
u8 dp_usb_type_c:1; /* 195+ */
|
||||
u8 tbt:1; /* 209+ */
|
||||
u8 flags2_reserved:2; /* 195+ */
|
||||
u8 dp_port_trace_length:4; /* 209+ */
|
||||
u8 dp_gpio_index; /* 195+ */
|
||||
u16 dp_gpio_pin_num; /* 195+ */
|
||||
u8 dp_iboost_level:4; /* 196+ */
|
||||
u8 hdmi_iboost_level:4; /* 196+ */
|
||||
u8 dp_max_link_rate:3; /* 216+ */
|
||||
u8 dp_max_link_rate_reserved:5; /* 216+ */
|
||||
} __packed;
|
||||
|
||||
struct bdb_general_definitions {
|
||||
@ -459,7 +492,7 @@ struct bdb_general_definitions {
|
||||
u8 crt_ddc_gmbus_pin;
|
||||
|
||||
/* DPMS bits */
|
||||
u8 dpms_acpi:1;
|
||||
u8 dpms_non_acpi:1;
|
||||
u8 skip_boot_crt_detect:1;
|
||||
u8 dpms_aim:1;
|
||||
u8 rsvd1:5; /* finish byte */
|
||||
@ -488,25 +521,25 @@ struct bdb_general_definitions {
|
||||
|
||||
struct psr_table {
|
||||
/* Feature bits */
|
||||
u8 full_link:1;
|
||||
u8 require_aux_to_wakeup:1;
|
||||
u8 full_link:1; /* 165+ */
|
||||
u8 require_aux_to_wakeup:1; /* 165+ */
|
||||
u8 feature_bits_rsvd:6;
|
||||
|
||||
/* Wait times */
|
||||
u8 idle_frames:4;
|
||||
u8 lines_to_wait:3;
|
||||
u8 idle_frames:4; /* 165+ */
|
||||
u8 lines_to_wait:3; /* 165+ */
|
||||
u8 wait_times_rsvd:1;
|
||||
|
||||
/* TP wake up time in multiple of 100 */
|
||||
u16 tp1_wakeup_time;
|
||||
u16 tp2_tp3_wakeup_time;
|
||||
u16 tp1_wakeup_time; /* 165+ */
|
||||
u16 tp2_tp3_wakeup_time; /* 165+ */
|
||||
} __packed;
|
||||
|
||||
struct bdb_psr {
|
||||
struct psr_table psr_table[16];
|
||||
|
||||
/* PSR2 TP2/TP3 wakeup time for 16 panels */
|
||||
u32 psr2_tp2_tp3_wakeup_time;
|
||||
u32 psr2_tp2_tp3_wakeup_time; /* 226+ */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
@ -519,9 +552,10 @@ struct bdb_psr {
|
||||
#define BDB_DRIVER_FEATURE_INT_SDVO_LVDS 3
|
||||
|
||||
struct bdb_driver_features {
|
||||
/* Driver bits */
|
||||
u8 boot_dev_algorithm:1;
|
||||
u8 block_display_switch:1;
|
||||
u8 allow_display_switch:1;
|
||||
u8 allow_display_switch_dvd:1;
|
||||
u8 allow_display_switch_dos:1;
|
||||
u8 hotplug_dvo:1;
|
||||
u8 dual_view_zoom:1;
|
||||
u8 int15h_hook:1;
|
||||
@ -533,6 +567,7 @@ struct bdb_driver_features {
|
||||
u8 boot_mode_bpp;
|
||||
u8 boot_mode_refresh;
|
||||
|
||||
/* Extended Driver Bits 1 */
|
||||
u16 enable_lfp_primary:1;
|
||||
u16 selective_mode_pruning:1;
|
||||
u16 dual_frequency:1;
|
||||
@ -548,29 +583,40 @@ struct bdb_driver_features {
|
||||
u16 tv_hotplug:1;
|
||||
u16 hdmi_config:2;
|
||||
|
||||
u8 static_display:1;
|
||||
u8 reserved2:7;
|
||||
/* Driver Flags 1 */
|
||||
u8 static_display:1; /* 163+ */
|
||||
u8 embedded_platform:1; /* 163+ */
|
||||
u8 display_subsystem_enable:1; /* 163+ */
|
||||
u8 reserved0:5;
|
||||
|
||||
u16 legacy_crt_max_x;
|
||||
u16 legacy_crt_max_y;
|
||||
u8 legacy_crt_max_refresh;
|
||||
|
||||
u8 hdmi_termination;
|
||||
u8 custom_vbt_version;
|
||||
/* Driver features data block */
|
||||
u16 rmpm_enabled:1;
|
||||
u16 s2ddt_enabled:1;
|
||||
u16 dpst_enabled:1;
|
||||
u16 bltclt_enabled:1;
|
||||
u16 adb_enabled:1;
|
||||
u16 drrs_enabled:1;
|
||||
u16 grs_enabled:1;
|
||||
u16 gpmt_enabled:1;
|
||||
u16 tbt_enabled:1;
|
||||
u16 psr_enabled:1;
|
||||
u16 ips_enabled:1;
|
||||
u16 reserved3:1;
|
||||
u16 dmrrs_enabled:1;
|
||||
u16 reserved4:2;
|
||||
/* Extended Driver Bits 2 */
|
||||
u8 hdmi_termination:1;
|
||||
u8 cea861d_hdmi_support:1;
|
||||
u8 self_refresh_enable:1;
|
||||
u8 reserved1:5;
|
||||
|
||||
u8 custom_vbt_version; /* 155+ */
|
||||
|
||||
/* Driver Feature Flags */
|
||||
u16 rmpm_enabled:1; /* 165+ */
|
||||
u16 s2ddt_enabled:1; /* 165+ */
|
||||
u16 dpst_enabled:1; /* 165-227 */
|
||||
u16 bltclt_enabled:1; /* 165+ */
|
||||
u16 adb_enabled:1; /* 165-227 */
|
||||
u16 drrs_enabled:1; /* 165-227 */
|
||||
u16 grs_enabled:1; /* 165+ */
|
||||
u16 gpmt_enabled:1; /* 165+ */
|
||||
u16 tbt_enabled:1; /* 165+ */
|
||||
u16 psr_enabled:1; /* 165-227 */
|
||||
u16 ips_enabled:1; /* 165+ */
|
||||
u16 dpfs_enabled:1; /* 165+ */
|
||||
u16 dmrrs_enabled:1; /* 174-227 */
|
||||
u16 adt_enabled:1; /* ???-228 */
|
||||
u16 hpd_wake:1; /* 201-240 */
|
||||
u16 pc_feature_valid:1;
|
||||
} __packed;
|
||||
|
||||
@ -657,7 +703,7 @@ struct bdb_sdvo_panel_dtds {
|
||||
|
||||
|
||||
struct edp_fast_link_params {
|
||||
u8 rate:4;
|
||||
u8 rate:4; /* ???-223 */
|
||||
u8 lanes:4;
|
||||
u8 preemphasis:4;
|
||||
u8 vswing:4;
|
||||
@ -690,18 +736,18 @@ struct bdb_edp {
|
||||
u32 sdrrs_msa_timing_delay;
|
||||
|
||||
/* ith bit indicates enabled/disabled for (i+1)th panel */
|
||||
u16 edp_s3d_feature; /* 162 */
|
||||
u16 edp_t3_optimization; /* 165 */
|
||||
u64 edp_vswing_preemph; /* 173 */
|
||||
u16 fast_link_training; /* 182 */
|
||||
u16 dpcd_600h_write_required; /* 185 */
|
||||
struct edp_pwm_delays pwm_delays[16]; /* 186 */
|
||||
u16 full_link_params_provided; /* 199 */
|
||||
struct edp_full_link_params full_link_params[16]; /* 199 */
|
||||
u16 apical_enable; /* 203 */
|
||||
struct edp_apical_params apical_params[16]; /* 203 */
|
||||
u16 edp_fast_link_training_rate[16]; /* 224 */
|
||||
u16 edp_max_port_link_rate[16]; /* 244 */
|
||||
u16 edp_s3d_feature; /* 162+ */
|
||||
u16 edp_t3_optimization; /* 165+ */
|
||||
u64 edp_vswing_preemph; /* 173+ */
|
||||
u16 fast_link_training; /* 182+ */
|
||||
u16 dpcd_600h_write_required; /* 185+ */
|
||||
struct edp_pwm_delays pwm_delays[16]; /* 186+ */
|
||||
u16 full_link_params_provided; /* 199+ */
|
||||
struct edp_full_link_params full_link_params[16]; /* 199+ */
|
||||
u16 apical_enable; /* 203+ */
|
||||
struct edp_apical_params apical_params[16]; /* 203+ */
|
||||
u16 edp_fast_link_training_rate[16]; /* 224+ */
|
||||
u16 edp_max_port_link_rate[16]; /* 244+ */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
@ -710,14 +756,14 @@ struct bdb_edp {
|
||||
|
||||
struct bdb_lvds_options {
|
||||
u8 panel_type;
|
||||
u8 panel_type2; /* 212 */
|
||||
u8 panel_type2; /* 212+ */
|
||||
/* LVDS capabilities, stored in a dword */
|
||||
u8 pfit_mode:2;
|
||||
u8 pfit_text_mode_enhanced:1;
|
||||
u8 pfit_gfx_mode_enhanced:1;
|
||||
u8 pfit_ratio_auto:1;
|
||||
u8 pixel_dither:1;
|
||||
u8 lvds_edid:1;
|
||||
u8 lvds_edid:1; /* ???-240 */
|
||||
u8 rsvd2:1;
|
||||
u8 rsvd4;
|
||||
/* LVDS Panel channel bits stored here */
|
||||
@ -731,11 +777,11 @@ struct bdb_lvds_options {
|
||||
/* LVDS panel type bits stored here */
|
||||
u32 dps_panel_type_bits;
|
||||
/* LVDS backlight control type bits stored here */
|
||||
u32 blt_control_type_bits;
|
||||
u32 blt_control_type_bits; /* ???-240 */
|
||||
|
||||
u16 lcdvcc_s0_enable; /* 200 */
|
||||
u32 rotation; /* 228 */
|
||||
u32 position; /* 240 */
|
||||
u16 lcdvcc_s0_enable; /* 200+ */
|
||||
u32 rotation; /* 228+ */
|
||||
u32 position; /* 240+ */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
@ -756,7 +802,7 @@ struct lvds_lfp_data_ptr {
|
||||
struct bdb_lvds_lfp_data_ptrs {
|
||||
u8 lvds_entries;
|
||||
struct lvds_lfp_data_ptr ptr[16];
|
||||
struct lvds_lfp_data_ptr_table panel_name; /* 156-163? */
|
||||
struct lvds_lfp_data_ptr_table panel_name; /* (156-163?)+ */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
@ -808,20 +854,20 @@ struct lvds_lfp_panel_name {
|
||||
} __packed;
|
||||
|
||||
struct lvds_lfp_black_border {
|
||||
u8 top; /* 227 */
|
||||
u8 bottom; /* 227 */
|
||||
u8 left; /* 238 */
|
||||
u8 right; /* 238 */
|
||||
u8 top; /* 227+ */
|
||||
u8 bottom; /* 227+ */
|
||||
u8 left; /* 238+ */
|
||||
u8 right; /* 238+ */
|
||||
} __packed;
|
||||
|
||||
struct bdb_lvds_lfp_data_tail {
|
||||
struct lvds_lfp_panel_name panel_name[16]; /* 156-163? */
|
||||
u16 scaling_enable; /* 187 */
|
||||
u8 seamless_drrs_min_refresh_rate[16]; /* 188 */
|
||||
u8 pixel_overlap_count[16]; /* 208 */
|
||||
struct lvds_lfp_black_border black_border[16]; /* 227 */
|
||||
u16 dual_lfp_port_sync_enable; /* 231 */
|
||||
u16 gpu_dithering_for_banding_artifacts; /* 245 */
|
||||
struct lvds_lfp_panel_name panel_name[16]; /* (156-163?)+ */
|
||||
u16 scaling_enable; /* 187+ */
|
||||
u8 seamless_drrs_min_refresh_rate[16]; /* 188+ */
|
||||
u8 pixel_overlap_count[16]; /* 208+ */
|
||||
struct lvds_lfp_black_border black_border[16]; /* 227+ */
|
||||
u16 dual_lfp_port_sync_enable; /* 231+ */
|
||||
u16 gpu_dithering_for_banding_artifacts; /* 245+ */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
@ -836,7 +882,7 @@ struct lfp_backlight_data_entry {
|
||||
u8 active_low_pwm:1;
|
||||
u8 obsolete1:5;
|
||||
u16 pwm_freq_hz;
|
||||
u8 min_brightness; /* Obsolete from 234+ */
|
||||
u8 min_brightness; /* ???-233 */
|
||||
u8 obsolete2;
|
||||
u8 obsolete3;
|
||||
} __packed;
|
||||
@ -859,7 +905,7 @@ struct lfp_brightness_level {
|
||||
struct bdb_lfp_backlight_data {
|
||||
u8 entry_size;
|
||||
struct lfp_backlight_data_entry data[16];
|
||||
u8 level[16]; /* Obsolete from 234+ */
|
||||
u8 level[16]; /* ???-233 */
|
||||
struct lfp_backlight_control_method backlight_control[16];
|
||||
struct lfp_brightness_level brightness_level[16]; /* 234+ */
|
||||
struct lfp_brightness_level brightness_min_level[16]; /* 234+ */
|
||||
@ -874,8 +920,8 @@ struct lfp_power_features {
|
||||
u8 reserved1:1;
|
||||
u8 power_conservation_pref:3;
|
||||
u8 reserved2:1;
|
||||
u8 lace_enabled_status:1;
|
||||
u8 lace_support:1;
|
||||
u8 lace_enabled_status:1; /* 210+ */
|
||||
u8 lace_support:1; /* 210+ */
|
||||
u8 als_enable:1;
|
||||
} __packed;
|
||||
|
||||
@ -895,24 +941,24 @@ struct aggressiveness_profile2_entry {
|
||||
} __packed;
|
||||
|
||||
struct bdb_lfp_power {
|
||||
struct lfp_power_features features;
|
||||
struct lfp_power_features features; /* ???-227 */
|
||||
struct als_data_entry als[5];
|
||||
u8 lace_aggressiveness_profile:3;
|
||||
u8 lace_aggressiveness_profile:3; /* 210-227 */
|
||||
u8 reserved1:5;
|
||||
u16 dpst;
|
||||
u16 psr;
|
||||
u16 drrs;
|
||||
u16 lace_support;
|
||||
u16 adt;
|
||||
u16 dmrrs;
|
||||
u16 adb;
|
||||
u16 lace_enabled_status;
|
||||
struct aggressiveness_profile_entry aggressiveness[16];
|
||||
u16 hobl; /* 232+ */
|
||||
u16 vrr_feature_enabled; /* 233+ */
|
||||
u16 elp; /* 247+ */
|
||||
u16 opst; /* 247+ */
|
||||
struct aggressiveness_profile2_entry aggressiveness2[16]; /* 247+ */
|
||||
u16 dpst; /* 228+ */
|
||||
u16 psr; /* 228+ */
|
||||
u16 drrs; /* 228+ */
|
||||
u16 lace_support; /* 228+ */
|
||||
u16 adt; /* 228+ */
|
||||
u16 dmrrs; /* 228+ */
|
||||
u16 adb; /* 228+ */
|
||||
u16 lace_enabled_status; /* 228+ */
|
||||
struct aggressiveness_profile_entry aggressiveness[16]; /* 228+ */
|
||||
u16 hobl; /* 232+ */
|
||||
u16 vrr_feature_enabled; /* 233+ */
|
||||
u16 elp; /* 247+ */
|
||||
u16 opst; /* 247+ */
|
||||
struct aggressiveness_profile2_entry aggressiveness2[16]; /* 247+ */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
@ -922,10 +968,10 @@ struct bdb_lfp_power {
|
||||
#define MAX_MIPI_CONFIGURATIONS 6
|
||||
|
||||
struct bdb_mipi_config {
|
||||
struct mipi_config config[MAX_MIPI_CONFIGURATIONS]; /* 175 */
|
||||
struct mipi_pps_data pps[MAX_MIPI_CONFIGURATIONS]; /* 177 */
|
||||
struct edp_pwm_delays pwm_delays[MAX_MIPI_CONFIGURATIONS]; /* 186 */
|
||||
u8 pmic_i2c_bus_number[MAX_MIPI_CONFIGURATIONS]; /* 190 */
|
||||
struct mipi_config config[MAX_MIPI_CONFIGURATIONS]; /* 175+ */
|
||||
struct mipi_pps_data pps[MAX_MIPI_CONFIGURATIONS]; /* 177+ */
|
||||
struct edp_pwm_delays pwm_delays[MAX_MIPI_CONFIGURATIONS]; /* 186+ */
|
||||
u8 pmic_i2c_bus_number[MAX_MIPI_CONFIGURATIONS]; /* 190+ */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
|
@ -460,7 +460,6 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
|
||||
u8 i = 0;
|
||||
|
||||
vdsc_cfg->pic_width = pipe_config->hw.adjusted_mode.crtc_hdisplay;
|
||||
vdsc_cfg->pic_height = pipe_config->hw.adjusted_mode.crtc_vdisplay;
|
||||
vdsc_cfg->slice_width = DIV_ROUND_UP(vdsc_cfg->pic_width,
|
||||
pipe_config->dsc.slice_count);
|
||||
|
||||
|
@ -14,11 +14,11 @@
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_fb.h"
|
||||
#include "intel_fbc.h"
|
||||
#include "intel_pm.h"
|
||||
#include "intel_psr.h"
|
||||
#include "intel_sprite.h"
|
||||
#include "skl_scaler.h"
|
||||
#include "skl_universal_plane.h"
|
||||
#include "skl_watermark.h"
|
||||
#include "pxp/intel_pxp.h"
|
||||
|
||||
static const u32 skl_plane_formats[] = {
|
||||
@ -1940,7 +1940,7 @@ static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv,
|
||||
enum intel_fbc_id fbc_id = skl_fbc_id_for_pipe(pipe);
|
||||
|
||||
if (skl_plane_has_fbc(dev_priv, fbc_id, plane_id))
|
||||
return dev_priv->fbc[fbc_id];
|
||||
return dev_priv->display.fbc[fbc_id];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
3562
drivers/gpu/drm/i915/display/skl_watermark.c
Normal file
3562
drivers/gpu/drm/i915/display/skl_watermark.c
Normal file
File diff suppressed because it is too large
Load Diff
80
drivers/gpu/drm/i915/display/skl_watermark.h
Normal file
80
drivers/gpu/drm/i915/display/skl_watermark.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __SKL_WATERMARK_H__
|
||||
#define __SKL_WATERMARK_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "intel_display.h"
|
||||
#include "intel_global_state.h"
|
||||
#include "intel_pm_types.h"
|
||||
|
||||
struct drm_i915_private;
|
||||
struct intel_atomic_state;
|
||||
struct intel_bw_state;
|
||||
struct intel_crtc;
|
||||
struct intel_crtc_state;
|
||||
struct intel_plane;
|
||||
|
||||
u8 intel_enabled_dbuf_slices_mask(struct drm_i915_private *i915);
|
||||
|
||||
void intel_sagv_pre_plane_update(struct intel_atomic_state *state);
|
||||
void intel_sagv_post_plane_update(struct intel_atomic_state *state);
|
||||
bool intel_can_enable_sagv(struct drm_i915_private *i915,
|
||||
const struct intel_bw_state *bw_state);
|
||||
|
||||
u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *i915,
|
||||
const struct skl_ddb_entry *entry);
|
||||
|
||||
void skl_write_plane_wm(struct intel_plane *plane,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void skl_write_cursor_wm(struct intel_plane *plane,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
|
||||
bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
|
||||
const struct skl_ddb_entry *entries,
|
||||
int num_entries, int ignore_idx);
|
||||
|
||||
void skl_wm_get_hw_state(struct drm_i915_private *i915);
|
||||
void skl_wm_sanitize(struct drm_i915_private *i915);
|
||||
|
||||
void intel_wm_state_verify(struct intel_crtc *crtc,
|
||||
struct intel_crtc_state *new_crtc_state);
|
||||
|
||||
void skl_watermark_ipc_init(struct drm_i915_private *i915);
|
||||
void skl_watermark_ipc_update(struct drm_i915_private *i915);
|
||||
bool skl_watermark_ipc_enabled(struct drm_i915_private *i915);
|
||||
void skl_watermark_ipc_debugfs_register(struct drm_i915_private *i915);
|
||||
|
||||
void skl_wm_init(struct drm_i915_private *i915);
|
||||
|
||||
struct intel_dbuf_state {
|
||||
struct intel_global_state base;
|
||||
|
||||
struct skl_ddb_entry ddb[I915_MAX_PIPES];
|
||||
unsigned int weight[I915_MAX_PIPES];
|
||||
u8 slices[I915_MAX_PIPES];
|
||||
u8 enabled_slices;
|
||||
u8 active_pipes;
|
||||
bool joined_mbus;
|
||||
};
|
||||
|
||||
struct intel_dbuf_state *
|
||||
intel_atomic_get_dbuf_state(struct intel_atomic_state *state);
|
||||
|
||||
#define to_intel_dbuf_state(x) container_of((x), struct intel_dbuf_state, base)
|
||||
#define intel_atomic_get_old_dbuf_state(state) \
|
||||
to_intel_dbuf_state(intel_atomic_get_old_global_obj_state(state, &to_i915(state->base.dev)->display.dbuf.obj))
|
||||
#define intel_atomic_get_new_dbuf_state(state) \
|
||||
to_intel_dbuf_state(intel_atomic_get_new_global_obj_state(state, &to_i915(state->base.dev)->display.dbuf.obj))
|
||||
|
||||
int intel_dbuf_init(struct drm_i915_private *i915);
|
||||
void intel_dbuf_pre_plane_update(struct intel_atomic_state *state);
|
||||
void intel_dbuf_post_plane_update(struct intel_atomic_state *state);
|
||||
void intel_mbus_dbox_update(struct intel_atomic_state *state);
|
||||
|
||||
#endif /* __SKL_WATERMARK_H__ */
|
||||
|
@ -822,9 +822,9 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state,
|
||||
u32 val;
|
||||
|
||||
/* Disable DPOunit clock gating, can stall pipe */
|
||||
val = intel_de_read(dev_priv, DSPCLK_GATE_D);
|
||||
val = intel_de_read(dev_priv, DSPCLK_GATE_D(dev_priv));
|
||||
val |= DPOUNIT_CLOCK_GATE_DISABLE;
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D, val);
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D(dev_priv), val);
|
||||
}
|
||||
|
||||
if (!IS_GEMINILAKE(dev_priv))
|
||||
@ -998,9 +998,9 @@ static void intel_dsi_post_disable(struct intel_atomic_state *state,
|
||||
|
||||
vlv_dsi_pll_disable(encoder);
|
||||
|
||||
val = intel_de_read(dev_priv, DSPCLK_GATE_D);
|
||||
val = intel_de_read(dev_priv, DSPCLK_GATE_D(dev_priv));
|
||||
val &= ~DPOUNIT_CLOCK_GATE_DISABLE;
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D, val);
|
||||
intel_de_write(dev_priv, DSPCLK_GATE_D(dev_priv), val);
|
||||
}
|
||||
|
||||
/* Assert reset */
|
||||
@ -1277,13 +1277,12 @@ static void intel_dsi_get_config(struct intel_encoder *encoder,
|
||||
pclk = vlv_dsi_get_pclk(encoder, pipe_config);
|
||||
}
|
||||
|
||||
if (intel_dsi->dual_link)
|
||||
pclk *= 2;
|
||||
pipe_config->port_clock = pclk;
|
||||
|
||||
if (pclk) {
|
||||
pipe_config->hw.adjusted_mode.crtc_clock = pclk;
|
||||
pipe_config->port_clock = pclk;
|
||||
}
|
||||
/* FIXME definitely not right for burst/cmd mode/pixel overlap */
|
||||
pipe_config->hw.adjusted_mode.crtc_clock = pclk;
|
||||
if (intel_dsi->dual_link)
|
||||
pipe_config->hw.adjusted_mode.crtc_clock *= 2;
|
||||
}
|
||||
|
||||
/* return txclkesc cycles in terms of divider and duration in us */
|
||||
@ -1872,9 +1871,9 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
|
||||
return;
|
||||
|
||||
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
|
||||
dev_priv->mipi_mmio_base = BXT_MIPI_BASE;
|
||||
dev_priv->display.dsi.mmio_base = BXT_MIPI_BASE;
|
||||
else
|
||||
dev_priv->mipi_mmio_base = VLV_MIPI_BASE;
|
||||
dev_priv->display.dsi.mmio_base = VLV_MIPI_BASE;
|
||||
|
||||
intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
|
||||
if (!intel_dsi)
|
||||
|
@ -113,6 +113,61 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vlv_dsi_pclk(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *config)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
|
||||
u32 dsi_clock;
|
||||
u32 pll_ctl, pll_div;
|
||||
u32 m = 0, p = 0, n;
|
||||
int refclk = IS_CHERRYVIEW(dev_priv) ? 100000 : 25000;
|
||||
int i;
|
||||
|
||||
pll_ctl = config->dsi_pll.ctrl;
|
||||
pll_div = config->dsi_pll.div;
|
||||
|
||||
/* mask out other bits and extract the P1 divisor */
|
||||
pll_ctl &= DSI_PLL_P1_POST_DIV_MASK;
|
||||
pll_ctl = pll_ctl >> (DSI_PLL_P1_POST_DIV_SHIFT - 2);
|
||||
|
||||
/* N1 divisor */
|
||||
n = (pll_div & DSI_PLL_N1_DIV_MASK) >> DSI_PLL_N1_DIV_SHIFT;
|
||||
n = 1 << n; /* register has log2(N1) */
|
||||
|
||||
/* mask out the other bits and extract the M1 divisor */
|
||||
pll_div &= DSI_PLL_M1_DIV_MASK;
|
||||
pll_div = pll_div >> DSI_PLL_M1_DIV_SHIFT;
|
||||
|
||||
while (pll_ctl) {
|
||||
pll_ctl = pll_ctl >> 1;
|
||||
p++;
|
||||
}
|
||||
p--;
|
||||
|
||||
if (!p) {
|
||||
drm_err(&dev_priv->drm, "wrong P1 divisor\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lfsr_converts); i++) {
|
||||
if (lfsr_converts[i] == pll_div)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(lfsr_converts)) {
|
||||
drm_err(&dev_priv->drm, "wrong m_seed programmed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
m = i + 62;
|
||||
|
||||
dsi_clock = (m * refclk) / (p * n);
|
||||
|
||||
return DIV_ROUND_CLOSEST(dsi_clock * intel_dsi->lane_count, bpp);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: The muxing and gating is hard coded for now. Need to add support for
|
||||
* sharing PLLs with two DSI outputs.
|
||||
@ -122,8 +177,7 @@ int vlv_dsi_pll_compute(struct intel_encoder *encoder,
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
int ret;
|
||||
u32 dsi_clk;
|
||||
int pclk, dsi_clk, ret;
|
||||
|
||||
dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
|
||||
intel_dsi->lane_count);
|
||||
@ -145,6 +199,14 @@ int vlv_dsi_pll_compute(struct intel_encoder *encoder,
|
||||
drm_dbg_kms(&dev_priv->drm, "dsi pll div %08x, ctrl %08x\n",
|
||||
config->dsi_pll.div, config->dsi_pll.ctrl);
|
||||
|
||||
pclk = vlv_dsi_pclk(encoder, config);
|
||||
config->port_clock = pclk;
|
||||
|
||||
/* FIXME definitely not right for burst/cmd mode/pixel overlap */
|
||||
config->hw.adjusted_mode.crtc_clock = pclk;
|
||||
if (intel_dsi->dual_link)
|
||||
config->hw.adjusted_mode.crtc_clock *= 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -262,13 +324,7 @@ u32 vlv_dsi_get_pclk(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *config)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
|
||||
u32 dsi_clock, pclk;
|
||||
u32 pll_ctl, pll_div;
|
||||
u32 m = 0, p = 0, n;
|
||||
int refclk = IS_CHERRYVIEW(dev_priv) ? 100000 : 25000;
|
||||
int i;
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "\n");
|
||||
|
||||
@ -280,65 +336,31 @@ u32 vlv_dsi_get_pclk(struct intel_encoder *encoder,
|
||||
config->dsi_pll.ctrl = pll_ctl & ~DSI_PLL_LOCK;
|
||||
config->dsi_pll.div = pll_div;
|
||||
|
||||
/* mask out other bits and extract the P1 divisor */
|
||||
pll_ctl &= DSI_PLL_P1_POST_DIV_MASK;
|
||||
pll_ctl = pll_ctl >> (DSI_PLL_P1_POST_DIV_SHIFT - 2);
|
||||
return vlv_dsi_pclk(encoder, config);
|
||||
}
|
||||
|
||||
/* N1 divisor */
|
||||
n = (pll_div & DSI_PLL_N1_DIV_MASK) >> DSI_PLL_N1_DIV_SHIFT;
|
||||
n = 1 << n; /* register has log2(N1) */
|
||||
static int bxt_dsi_pclk(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *config)
|
||||
{
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
|
||||
u32 dsi_ratio, dsi_clk;
|
||||
|
||||
/* mask out the other bits and extract the M1 divisor */
|
||||
pll_div &= DSI_PLL_M1_DIV_MASK;
|
||||
pll_div = pll_div >> DSI_PLL_M1_DIV_SHIFT;
|
||||
dsi_ratio = config->dsi_pll.ctrl & BXT_DSI_PLL_RATIO_MASK;
|
||||
dsi_clk = (dsi_ratio * BXT_REF_CLOCK_KHZ) / 2;
|
||||
|
||||
while (pll_ctl) {
|
||||
pll_ctl = pll_ctl >> 1;
|
||||
p++;
|
||||
}
|
||||
p--;
|
||||
|
||||
if (!p) {
|
||||
drm_err(&dev_priv->drm, "wrong P1 divisor\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lfsr_converts); i++) {
|
||||
if (lfsr_converts[i] == pll_div)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(lfsr_converts)) {
|
||||
drm_err(&dev_priv->drm, "wrong m_seed programmed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
m = i + 62;
|
||||
|
||||
dsi_clock = (m * refclk) / (p * n);
|
||||
|
||||
pclk = DIV_ROUND_CLOSEST(dsi_clock * intel_dsi->lane_count, bpp);
|
||||
|
||||
return pclk;
|
||||
return DIV_ROUND_CLOSEST(dsi_clk * intel_dsi->lane_count, bpp);
|
||||
}
|
||||
|
||||
u32 bxt_dsi_get_pclk(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *config)
|
||||
{
|
||||
u32 pclk;
|
||||
u32 dsi_clk;
|
||||
u32 dsi_ratio;
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
|
||||
u32 pclk;
|
||||
|
||||
config->dsi_pll.ctrl = intel_de_read(dev_priv, BXT_DSI_PLL_CTL);
|
||||
|
||||
dsi_ratio = config->dsi_pll.ctrl & BXT_DSI_PLL_RATIO_MASK;
|
||||
|
||||
dsi_clk = (dsi_ratio * BXT_REF_CLOCK_KHZ) / 2;
|
||||
|
||||
pclk = DIV_ROUND_CLOSEST(dsi_clk * intel_dsi->lane_count, bpp);
|
||||
pclk = bxt_dsi_pclk(encoder, config);
|
||||
|
||||
drm_dbg(&dev_priv->drm, "Calculated pclk=%u\n", pclk);
|
||||
return pclk;
|
||||
@ -463,6 +485,7 @@ int bxt_dsi_pll_compute(struct intel_encoder *encoder,
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
u8 dsi_ratio, dsi_ratio_min, dsi_ratio_max;
|
||||
u32 dsi_clk;
|
||||
int pclk;
|
||||
|
||||
dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
|
||||
intel_dsi->lane_count);
|
||||
@ -502,6 +525,14 @@ int bxt_dsi_pll_compute(struct intel_encoder *encoder,
|
||||
if (IS_BROXTON(dev_priv) && dsi_ratio <= 50)
|
||||
config->dsi_pll.ctrl |= BXT_DSI_PLL_PVD_RATIO_1;
|
||||
|
||||
pclk = bxt_dsi_pclk(encoder, config);
|
||||
config->port_clock = pclk;
|
||||
|
||||
/* FIXME definitely not right for burst/cmd mode/pixel overlap */
|
||||
config->hw.adjusted_mode.crtc_clock = pclk;
|
||||
if (intel_dsi->dual_link)
|
||||
config->hw.adjusted_mode.crtc_clock *= 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
#define VLV_MIPI_BASE VLV_DISPLAY_BASE
|
||||
#define BXT_MIPI_BASE 0x60000
|
||||
|
||||
#define _MIPI_MMIO_BASE(__i915) ((__i915)->display.dsi.mmio_base)
|
||||
|
||||
#define _MIPI_PORT(port, a, c) (((port) == PORT_A) ? a : c) /* ports A and C only */
|
||||
#define _MMIO_MIPI(port, a, c) _MMIO(_MIPI_PORT(port, a, c))
|
||||
|
||||
@ -96,8 +98,8 @@
|
||||
|
||||
/* MIPI DSI Controller and D-PHY registers */
|
||||
|
||||
#define _MIPIA_DEVICE_READY (dev_priv->mipi_mmio_base + 0xb000)
|
||||
#define _MIPIC_DEVICE_READY (dev_priv->mipi_mmio_base + 0xb800)
|
||||
#define _MIPIA_DEVICE_READY (_MIPI_MMIO_BASE(dev_priv) + 0xb000)
|
||||
#define _MIPIC_DEVICE_READY (_MIPI_MMIO_BASE(dev_priv) + 0xb800)
|
||||
#define MIPI_DEVICE_READY(port) _MMIO_MIPI(port, _MIPIA_DEVICE_READY, _MIPIC_DEVICE_READY)
|
||||
#define BUS_POSSESSION (1 << 3) /* set to give bus to receiver */
|
||||
#define ULPS_STATE_MASK (3 << 1)
|
||||
@ -106,11 +108,11 @@
|
||||
#define ULPS_STATE_NORMAL_OPERATION (0 << 1)
|
||||
#define DEVICE_READY (1 << 0)
|
||||
|
||||
#define _MIPIA_INTR_STAT (dev_priv->mipi_mmio_base + 0xb004)
|
||||
#define _MIPIC_INTR_STAT (dev_priv->mipi_mmio_base + 0xb804)
|
||||
#define _MIPIA_INTR_STAT (_MIPI_MMIO_BASE(dev_priv) + 0xb004)
|
||||
#define _MIPIC_INTR_STAT (_MIPI_MMIO_BASE(dev_priv) + 0xb804)
|
||||
#define MIPI_INTR_STAT(port) _MMIO_MIPI(port, _MIPIA_INTR_STAT, _MIPIC_INTR_STAT)
|
||||
#define _MIPIA_INTR_EN (dev_priv->mipi_mmio_base + 0xb008)
|
||||
#define _MIPIC_INTR_EN (dev_priv->mipi_mmio_base + 0xb808)
|
||||
#define _MIPIA_INTR_EN (_MIPI_MMIO_BASE(dev_priv) + 0xb008)
|
||||
#define _MIPIC_INTR_EN (_MIPI_MMIO_BASE(dev_priv) + 0xb808)
|
||||
#define MIPI_INTR_EN(port) _MMIO_MIPI(port, _MIPIA_INTR_EN, _MIPIC_INTR_EN)
|
||||
#define TEARING_EFFECT (1 << 31)
|
||||
#define SPL_PKT_SENT_INTERRUPT (1 << 30)
|
||||
@ -145,8 +147,8 @@
|
||||
#define RXSOT_SYNC_ERROR (1 << 1)
|
||||
#define RXSOT_ERROR (1 << 0)
|
||||
|
||||
#define _MIPIA_DSI_FUNC_PRG (dev_priv->mipi_mmio_base + 0xb00c)
|
||||
#define _MIPIC_DSI_FUNC_PRG (dev_priv->mipi_mmio_base + 0xb80c)
|
||||
#define _MIPIA_DSI_FUNC_PRG (_MIPI_MMIO_BASE(dev_priv) + 0xb00c)
|
||||
#define _MIPIC_DSI_FUNC_PRG (_MIPI_MMIO_BASE(dev_priv) + 0xb80c)
|
||||
#define MIPI_DSI_FUNC_PRG(port) _MMIO_MIPI(port, _MIPIA_DSI_FUNC_PRG, _MIPIC_DSI_FUNC_PRG)
|
||||
#define CMD_MODE_DATA_WIDTH_MASK (7 << 13)
|
||||
#define CMD_MODE_NOT_SUPPORTED (0 << 13)
|
||||
@ -168,76 +170,76 @@
|
||||
#define DATA_LANES_PRG_REG_SHIFT 0
|
||||
#define DATA_LANES_PRG_REG_MASK (7 << 0)
|
||||
|
||||
#define _MIPIA_HS_TX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb010)
|
||||
#define _MIPIC_HS_TX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb810)
|
||||
#define _MIPIA_HS_TX_TIMEOUT (_MIPI_MMIO_BASE(dev_priv) + 0xb010)
|
||||
#define _MIPIC_HS_TX_TIMEOUT (_MIPI_MMIO_BASE(dev_priv) + 0xb810)
|
||||
#define MIPI_HS_TX_TIMEOUT(port) _MMIO_MIPI(port, _MIPIA_HS_TX_TIMEOUT, _MIPIC_HS_TX_TIMEOUT)
|
||||
#define HIGH_SPEED_TX_TIMEOUT_COUNTER_MASK 0xffffff
|
||||
|
||||
#define _MIPIA_LP_RX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb014)
|
||||
#define _MIPIC_LP_RX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb814)
|
||||
#define _MIPIA_LP_RX_TIMEOUT (_MIPI_MMIO_BASE(dev_priv) + 0xb014)
|
||||
#define _MIPIC_LP_RX_TIMEOUT (_MIPI_MMIO_BASE(dev_priv) + 0xb814)
|
||||
#define MIPI_LP_RX_TIMEOUT(port) _MMIO_MIPI(port, _MIPIA_LP_RX_TIMEOUT, _MIPIC_LP_RX_TIMEOUT)
|
||||
#define LOW_POWER_RX_TIMEOUT_COUNTER_MASK 0xffffff
|
||||
|
||||
#define _MIPIA_TURN_AROUND_TIMEOUT (dev_priv->mipi_mmio_base + 0xb018)
|
||||
#define _MIPIC_TURN_AROUND_TIMEOUT (dev_priv->mipi_mmio_base + 0xb818)
|
||||
#define _MIPIA_TURN_AROUND_TIMEOUT (_MIPI_MMIO_BASE(dev_priv) + 0xb018)
|
||||
#define _MIPIC_TURN_AROUND_TIMEOUT (_MIPI_MMIO_BASE(dev_priv) + 0xb818)
|
||||
#define MIPI_TURN_AROUND_TIMEOUT(port) _MMIO_MIPI(port, _MIPIA_TURN_AROUND_TIMEOUT, _MIPIC_TURN_AROUND_TIMEOUT)
|
||||
#define TURN_AROUND_TIMEOUT_MASK 0x3f
|
||||
|
||||
#define _MIPIA_DEVICE_RESET_TIMER (dev_priv->mipi_mmio_base + 0xb01c)
|
||||
#define _MIPIC_DEVICE_RESET_TIMER (dev_priv->mipi_mmio_base + 0xb81c)
|
||||
#define _MIPIA_DEVICE_RESET_TIMER (_MIPI_MMIO_BASE(dev_priv) + 0xb01c)
|
||||
#define _MIPIC_DEVICE_RESET_TIMER (_MIPI_MMIO_BASE(dev_priv) + 0xb81c)
|
||||
#define MIPI_DEVICE_RESET_TIMER(port) _MMIO_MIPI(port, _MIPIA_DEVICE_RESET_TIMER, _MIPIC_DEVICE_RESET_TIMER)
|
||||
#define DEVICE_RESET_TIMER_MASK 0xffff
|
||||
|
||||
#define _MIPIA_DPI_RESOLUTION (dev_priv->mipi_mmio_base + 0xb020)
|
||||
#define _MIPIC_DPI_RESOLUTION (dev_priv->mipi_mmio_base + 0xb820)
|
||||
#define _MIPIA_DPI_RESOLUTION (_MIPI_MMIO_BASE(dev_priv) + 0xb020)
|
||||
#define _MIPIC_DPI_RESOLUTION (_MIPI_MMIO_BASE(dev_priv) + 0xb820)
|
||||
#define MIPI_DPI_RESOLUTION(port) _MMIO_MIPI(port, _MIPIA_DPI_RESOLUTION, _MIPIC_DPI_RESOLUTION)
|
||||
#define VERTICAL_ADDRESS_SHIFT 16
|
||||
#define VERTICAL_ADDRESS_MASK (0xffff << 16)
|
||||
#define HORIZONTAL_ADDRESS_SHIFT 0
|
||||
#define HORIZONTAL_ADDRESS_MASK 0xffff
|
||||
|
||||
#define _MIPIA_DBI_FIFO_THROTTLE (dev_priv->mipi_mmio_base + 0xb024)
|
||||
#define _MIPIC_DBI_FIFO_THROTTLE (dev_priv->mipi_mmio_base + 0xb824)
|
||||
#define _MIPIA_DBI_FIFO_THROTTLE (_MIPI_MMIO_BASE(dev_priv) + 0xb024)
|
||||
#define _MIPIC_DBI_FIFO_THROTTLE (_MIPI_MMIO_BASE(dev_priv) + 0xb824)
|
||||
#define MIPI_DBI_FIFO_THROTTLE(port) _MMIO_MIPI(port, _MIPIA_DBI_FIFO_THROTTLE, _MIPIC_DBI_FIFO_THROTTLE)
|
||||
#define DBI_FIFO_EMPTY_HALF (0 << 0)
|
||||
#define DBI_FIFO_EMPTY_QUARTER (1 << 0)
|
||||
#define DBI_FIFO_EMPTY_7_LOCATIONS (2 << 0)
|
||||
|
||||
/* regs below are bits 15:0 */
|
||||
#define _MIPIA_HSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb028)
|
||||
#define _MIPIC_HSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb828)
|
||||
#define _MIPIA_HSYNC_PADDING_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb028)
|
||||
#define _MIPIC_HSYNC_PADDING_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb828)
|
||||
#define MIPI_HSYNC_PADDING_COUNT(port) _MMIO_MIPI(port, _MIPIA_HSYNC_PADDING_COUNT, _MIPIC_HSYNC_PADDING_COUNT)
|
||||
|
||||
#define _MIPIA_HBP_COUNT (dev_priv->mipi_mmio_base + 0xb02c)
|
||||
#define _MIPIC_HBP_COUNT (dev_priv->mipi_mmio_base + 0xb82c)
|
||||
#define _MIPIA_HBP_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb02c)
|
||||
#define _MIPIC_HBP_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb82c)
|
||||
#define MIPI_HBP_COUNT(port) _MMIO_MIPI(port, _MIPIA_HBP_COUNT, _MIPIC_HBP_COUNT)
|
||||
|
||||
#define _MIPIA_HFP_COUNT (dev_priv->mipi_mmio_base + 0xb030)
|
||||
#define _MIPIC_HFP_COUNT (dev_priv->mipi_mmio_base + 0xb830)
|
||||
#define _MIPIA_HFP_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb030)
|
||||
#define _MIPIC_HFP_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb830)
|
||||
#define MIPI_HFP_COUNT(port) _MMIO_MIPI(port, _MIPIA_HFP_COUNT, _MIPIC_HFP_COUNT)
|
||||
|
||||
#define _MIPIA_HACTIVE_AREA_COUNT (dev_priv->mipi_mmio_base + 0xb034)
|
||||
#define _MIPIC_HACTIVE_AREA_COUNT (dev_priv->mipi_mmio_base + 0xb834)
|
||||
#define _MIPIA_HACTIVE_AREA_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb034)
|
||||
#define _MIPIC_HACTIVE_AREA_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb834)
|
||||
#define MIPI_HACTIVE_AREA_COUNT(port) _MMIO_MIPI(port, _MIPIA_HACTIVE_AREA_COUNT, _MIPIC_HACTIVE_AREA_COUNT)
|
||||
|
||||
#define _MIPIA_VSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb038)
|
||||
#define _MIPIC_VSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb838)
|
||||
#define _MIPIA_VSYNC_PADDING_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb038)
|
||||
#define _MIPIC_VSYNC_PADDING_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb838)
|
||||
#define MIPI_VSYNC_PADDING_COUNT(port) _MMIO_MIPI(port, _MIPIA_VSYNC_PADDING_COUNT, _MIPIC_VSYNC_PADDING_COUNT)
|
||||
|
||||
#define _MIPIA_VBP_COUNT (dev_priv->mipi_mmio_base + 0xb03c)
|
||||
#define _MIPIC_VBP_COUNT (dev_priv->mipi_mmio_base + 0xb83c)
|
||||
#define _MIPIA_VBP_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb03c)
|
||||
#define _MIPIC_VBP_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb83c)
|
||||
#define MIPI_VBP_COUNT(port) _MMIO_MIPI(port, _MIPIA_VBP_COUNT, _MIPIC_VBP_COUNT)
|
||||
|
||||
#define _MIPIA_VFP_COUNT (dev_priv->mipi_mmio_base + 0xb040)
|
||||
#define _MIPIC_VFP_COUNT (dev_priv->mipi_mmio_base + 0xb840)
|
||||
#define _MIPIA_VFP_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb040)
|
||||
#define _MIPIC_VFP_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb840)
|
||||
#define MIPI_VFP_COUNT(port) _MMIO_MIPI(port, _MIPIA_VFP_COUNT, _MIPIC_VFP_COUNT)
|
||||
|
||||
#define _MIPIA_HIGH_LOW_SWITCH_COUNT (dev_priv->mipi_mmio_base + 0xb044)
|
||||
#define _MIPIC_HIGH_LOW_SWITCH_COUNT (dev_priv->mipi_mmio_base + 0xb844)
|
||||
#define _MIPIA_HIGH_LOW_SWITCH_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb044)
|
||||
#define _MIPIC_HIGH_LOW_SWITCH_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb844)
|
||||
#define MIPI_HIGH_LOW_SWITCH_COUNT(port) _MMIO_MIPI(port, _MIPIA_HIGH_LOW_SWITCH_COUNT, _MIPIC_HIGH_LOW_SWITCH_COUNT)
|
||||
|
||||
#define _MIPIA_DPI_CONTROL (dev_priv->mipi_mmio_base + 0xb048)
|
||||
#define _MIPIC_DPI_CONTROL (dev_priv->mipi_mmio_base + 0xb848)
|
||||
#define _MIPIA_DPI_CONTROL (_MIPI_MMIO_BASE(dev_priv) + 0xb048)
|
||||
#define _MIPIC_DPI_CONTROL (_MIPI_MMIO_BASE(dev_priv) + 0xb848)
|
||||
#define MIPI_DPI_CONTROL(port) _MMIO_MIPI(port, _MIPIA_DPI_CONTROL, _MIPIC_DPI_CONTROL)
|
||||
#define DPI_LP_MODE (1 << 6)
|
||||
#define BACKLIGHT_OFF (1 << 5)
|
||||
@ -247,27 +249,27 @@
|
||||
#define TURN_ON (1 << 1)
|
||||
#define SHUTDOWN (1 << 0)
|
||||
|
||||
#define _MIPIA_DPI_DATA (dev_priv->mipi_mmio_base + 0xb04c)
|
||||
#define _MIPIC_DPI_DATA (dev_priv->mipi_mmio_base + 0xb84c)
|
||||
#define _MIPIA_DPI_DATA (_MIPI_MMIO_BASE(dev_priv) + 0xb04c)
|
||||
#define _MIPIC_DPI_DATA (_MIPI_MMIO_BASE(dev_priv) + 0xb84c)
|
||||
#define MIPI_DPI_DATA(port) _MMIO_MIPI(port, _MIPIA_DPI_DATA, _MIPIC_DPI_DATA)
|
||||
#define COMMAND_BYTE_SHIFT 0
|
||||
#define COMMAND_BYTE_MASK (0x3f << 0)
|
||||
|
||||
#define _MIPIA_INIT_COUNT (dev_priv->mipi_mmio_base + 0xb050)
|
||||
#define _MIPIC_INIT_COUNT (dev_priv->mipi_mmio_base + 0xb850)
|
||||
#define _MIPIA_INIT_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb050)
|
||||
#define _MIPIC_INIT_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb850)
|
||||
#define MIPI_INIT_COUNT(port) _MMIO_MIPI(port, _MIPIA_INIT_COUNT, _MIPIC_INIT_COUNT)
|
||||
#define MASTER_INIT_TIMER_SHIFT 0
|
||||
#define MASTER_INIT_TIMER_MASK (0xffff << 0)
|
||||
|
||||
#define _MIPIA_MAX_RETURN_PKT_SIZE (dev_priv->mipi_mmio_base + 0xb054)
|
||||
#define _MIPIC_MAX_RETURN_PKT_SIZE (dev_priv->mipi_mmio_base + 0xb854)
|
||||
#define _MIPIA_MAX_RETURN_PKT_SIZE (_MIPI_MMIO_BASE(dev_priv) + 0xb054)
|
||||
#define _MIPIC_MAX_RETURN_PKT_SIZE (_MIPI_MMIO_BASE(dev_priv) + 0xb854)
|
||||
#define MIPI_MAX_RETURN_PKT_SIZE(port) _MMIO_MIPI(port, \
|
||||
_MIPIA_MAX_RETURN_PKT_SIZE, _MIPIC_MAX_RETURN_PKT_SIZE)
|
||||
#define MAX_RETURN_PKT_SIZE_SHIFT 0
|
||||
#define MAX_RETURN_PKT_SIZE_MASK (0x3ff << 0)
|
||||
|
||||
#define _MIPIA_VIDEO_MODE_FORMAT (dev_priv->mipi_mmio_base + 0xb058)
|
||||
#define _MIPIC_VIDEO_MODE_FORMAT (dev_priv->mipi_mmio_base + 0xb858)
|
||||
#define _MIPIA_VIDEO_MODE_FORMAT (_MIPI_MMIO_BASE(dev_priv) + 0xb058)
|
||||
#define _MIPIC_VIDEO_MODE_FORMAT (_MIPI_MMIO_BASE(dev_priv) + 0xb858)
|
||||
#define MIPI_VIDEO_MODE_FORMAT(port) _MMIO_MIPI(port, _MIPIA_VIDEO_MODE_FORMAT, _MIPIC_VIDEO_MODE_FORMAT)
|
||||
#define RANDOM_DPI_DISPLAY_RESOLUTION (1 << 4)
|
||||
#define DISABLE_VIDEO_BTA (1 << 3)
|
||||
@ -276,8 +278,8 @@
|
||||
#define VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS (2 << 0)
|
||||
#define VIDEO_MODE_BURST (3 << 0)
|
||||
|
||||
#define _MIPIA_EOT_DISABLE (dev_priv->mipi_mmio_base + 0xb05c)
|
||||
#define _MIPIC_EOT_DISABLE (dev_priv->mipi_mmio_base + 0xb85c)
|
||||
#define _MIPIA_EOT_DISABLE (_MIPI_MMIO_BASE(dev_priv) + 0xb05c)
|
||||
#define _MIPIC_EOT_DISABLE (_MIPI_MMIO_BASE(dev_priv) + 0xb85c)
|
||||
#define MIPI_EOT_DISABLE(port) _MMIO_MIPI(port, _MIPIA_EOT_DISABLE, _MIPIC_EOT_DISABLE)
|
||||
#define BXT_DEFEATURE_DPI_FIFO_CTR (1 << 9)
|
||||
#define BXT_DPHY_DEFEATURE_EN (1 << 8)
|
||||
@ -290,35 +292,35 @@
|
||||
#define CLOCKSTOP (1 << 1)
|
||||
#define EOT_DISABLE (1 << 0)
|
||||
|
||||
#define _MIPIA_LP_BYTECLK (dev_priv->mipi_mmio_base + 0xb060)
|
||||
#define _MIPIC_LP_BYTECLK (dev_priv->mipi_mmio_base + 0xb860)
|
||||
#define _MIPIA_LP_BYTECLK (_MIPI_MMIO_BASE(dev_priv) + 0xb060)
|
||||
#define _MIPIC_LP_BYTECLK (_MIPI_MMIO_BASE(dev_priv) + 0xb860)
|
||||
#define MIPI_LP_BYTECLK(port) _MMIO_MIPI(port, _MIPIA_LP_BYTECLK, _MIPIC_LP_BYTECLK)
|
||||
#define LP_BYTECLK_SHIFT 0
|
||||
#define LP_BYTECLK_MASK (0xffff << 0)
|
||||
|
||||
#define _MIPIA_TLPX_TIME_COUNT (dev_priv->mipi_mmio_base + 0xb0a4)
|
||||
#define _MIPIC_TLPX_TIME_COUNT (dev_priv->mipi_mmio_base + 0xb8a4)
|
||||
#define _MIPIA_TLPX_TIME_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb0a4)
|
||||
#define _MIPIC_TLPX_TIME_COUNT (_MIPI_MMIO_BASE(dev_priv) + 0xb8a4)
|
||||
#define MIPI_TLPX_TIME_COUNT(port) _MMIO_MIPI(port, _MIPIA_TLPX_TIME_COUNT, _MIPIC_TLPX_TIME_COUNT)
|
||||
|
||||
#define _MIPIA_CLK_LANE_TIMING (dev_priv->mipi_mmio_base + 0xb098)
|
||||
#define _MIPIC_CLK_LANE_TIMING (dev_priv->mipi_mmio_base + 0xb898)
|
||||
#define _MIPIA_CLK_LANE_TIMING (_MIPI_MMIO_BASE(dev_priv) + 0xb098)
|
||||
#define _MIPIC_CLK_LANE_TIMING (_MIPI_MMIO_BASE(dev_priv) + 0xb898)
|
||||
#define MIPI_CLK_LANE_TIMING(port) _MMIO_MIPI(port, _MIPIA_CLK_LANE_TIMING, _MIPIC_CLK_LANE_TIMING)
|
||||
|
||||
/* bits 31:0 */
|
||||
#define _MIPIA_LP_GEN_DATA (dev_priv->mipi_mmio_base + 0xb064)
|
||||
#define _MIPIC_LP_GEN_DATA (dev_priv->mipi_mmio_base + 0xb864)
|
||||
#define _MIPIA_LP_GEN_DATA (_MIPI_MMIO_BASE(dev_priv) + 0xb064)
|
||||
#define _MIPIC_LP_GEN_DATA (_MIPI_MMIO_BASE(dev_priv) + 0xb864)
|
||||
#define MIPI_LP_GEN_DATA(port) _MMIO_MIPI(port, _MIPIA_LP_GEN_DATA, _MIPIC_LP_GEN_DATA)
|
||||
|
||||
/* bits 31:0 */
|
||||
#define _MIPIA_HS_GEN_DATA (dev_priv->mipi_mmio_base + 0xb068)
|
||||
#define _MIPIC_HS_GEN_DATA (dev_priv->mipi_mmio_base + 0xb868)
|
||||
#define _MIPIA_HS_GEN_DATA (_MIPI_MMIO_BASE(dev_priv) + 0xb068)
|
||||
#define _MIPIC_HS_GEN_DATA (_MIPI_MMIO_BASE(dev_priv) + 0xb868)
|
||||
#define MIPI_HS_GEN_DATA(port) _MMIO_MIPI(port, _MIPIA_HS_GEN_DATA, _MIPIC_HS_GEN_DATA)
|
||||
|
||||
#define _MIPIA_LP_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb06c)
|
||||
#define _MIPIC_LP_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb86c)
|
||||
#define _MIPIA_LP_GEN_CTRL (_MIPI_MMIO_BASE(dev_priv) + 0xb06c)
|
||||
#define _MIPIC_LP_GEN_CTRL (_MIPI_MMIO_BASE(dev_priv) + 0xb86c)
|
||||
#define MIPI_LP_GEN_CTRL(port) _MMIO_MIPI(port, _MIPIA_LP_GEN_CTRL, _MIPIC_LP_GEN_CTRL)
|
||||
#define _MIPIA_HS_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb070)
|
||||
#define _MIPIC_HS_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb870)
|
||||
#define _MIPIA_HS_GEN_CTRL (_MIPI_MMIO_BASE(dev_priv) + 0xb070)
|
||||
#define _MIPIC_HS_GEN_CTRL (_MIPI_MMIO_BASE(dev_priv) + 0xb870)
|
||||
#define MIPI_HS_GEN_CTRL(port) _MMIO_MIPI(port, _MIPIA_HS_GEN_CTRL, _MIPIC_HS_GEN_CTRL)
|
||||
#define LONG_PACKET_WORD_COUNT_SHIFT 8
|
||||
#define LONG_PACKET_WORD_COUNT_MASK (0xffff << 8)
|
||||
@ -330,8 +332,8 @@
|
||||
#define DATA_TYPE_MASK (0x3f << 0)
|
||||
/* data type values, see include/video/mipi_display.h */
|
||||
|
||||
#define _MIPIA_GEN_FIFO_STAT (dev_priv->mipi_mmio_base + 0xb074)
|
||||
#define _MIPIC_GEN_FIFO_STAT (dev_priv->mipi_mmio_base + 0xb874)
|
||||
#define _MIPIA_GEN_FIFO_STAT (_MIPI_MMIO_BASE(dev_priv) + 0xb074)
|
||||
#define _MIPIC_GEN_FIFO_STAT (_MIPI_MMIO_BASE(dev_priv) + 0xb874)
|
||||
#define MIPI_GEN_FIFO_STAT(port) _MMIO_MIPI(port, _MIPIA_GEN_FIFO_STAT, _MIPIC_GEN_FIFO_STAT)
|
||||
#define DPI_FIFO_EMPTY (1 << 28)
|
||||
#define DBI_FIFO_EMPTY (1 << 27)
|
||||
@ -348,15 +350,15 @@
|
||||
#define HS_DATA_FIFO_HALF_EMPTY (1 << 1)
|
||||
#define HS_DATA_FIFO_FULL (1 << 0)
|
||||
|
||||
#define _MIPIA_HS_LS_DBI_ENABLE (dev_priv->mipi_mmio_base + 0xb078)
|
||||
#define _MIPIC_HS_LS_DBI_ENABLE (dev_priv->mipi_mmio_base + 0xb878)
|
||||
#define _MIPIA_HS_LS_DBI_ENABLE (_MIPI_MMIO_BASE(dev_priv) + 0xb078)
|
||||
#define _MIPIC_HS_LS_DBI_ENABLE (_MIPI_MMIO_BASE(dev_priv) + 0xb878)
|
||||
#define MIPI_HS_LP_DBI_ENABLE(port) _MMIO_MIPI(port, _MIPIA_HS_LS_DBI_ENABLE, _MIPIC_HS_LS_DBI_ENABLE)
|
||||
#define DBI_HS_LP_MODE_MASK (1 << 0)
|
||||
#define DBI_LP_MODE (1 << 0)
|
||||
#define DBI_HS_MODE (0 << 0)
|
||||
|
||||
#define _MIPIA_DPHY_PARAM (dev_priv->mipi_mmio_base + 0xb080)
|
||||
#define _MIPIC_DPHY_PARAM (dev_priv->mipi_mmio_base + 0xb880)
|
||||
#define _MIPIA_DPHY_PARAM (_MIPI_MMIO_BASE(dev_priv) + 0xb080)
|
||||
#define _MIPIC_DPHY_PARAM (_MIPI_MMIO_BASE(dev_priv) + 0xb880)
|
||||
#define MIPI_DPHY_PARAM(port) _MMIO_MIPI(port, _MIPIA_DPHY_PARAM, _MIPIC_DPHY_PARAM)
|
||||
#define EXIT_ZERO_COUNT_SHIFT 24
|
||||
#define EXIT_ZERO_COUNT_MASK (0x3f << 24)
|
||||
@ -367,34 +369,34 @@
|
||||
#define PREPARE_COUNT_SHIFT 0
|
||||
#define PREPARE_COUNT_MASK (0x3f << 0)
|
||||
|
||||
#define _MIPIA_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb084)
|
||||
#define _MIPIC_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb884)
|
||||
#define _MIPIA_DBI_BW_CTRL (_MIPI_MMIO_BASE(dev_priv) + 0xb084)
|
||||
#define _MIPIC_DBI_BW_CTRL (_MIPI_MMIO_BASE(dev_priv) + 0xb884)
|
||||
#define MIPI_DBI_BW_CTRL(port) _MMIO_MIPI(port, _MIPIA_DBI_BW_CTRL, _MIPIC_DBI_BW_CTRL)
|
||||
|
||||
#define _MIPIA_CLK_LANE_SWITCH_TIME_CNT (dev_priv->mipi_mmio_base + 0xb088)
|
||||
#define _MIPIC_CLK_LANE_SWITCH_TIME_CNT (dev_priv->mipi_mmio_base + 0xb888)
|
||||
#define _MIPIA_CLK_LANE_SWITCH_TIME_CNT (_MIPI_MMIO_BASE(dev_priv) + 0xb088)
|
||||
#define _MIPIC_CLK_LANE_SWITCH_TIME_CNT (_MIPI_MMIO_BASE(dev_priv) + 0xb888)
|
||||
#define MIPI_CLK_LANE_SWITCH_TIME_CNT(port) _MMIO_MIPI(port, _MIPIA_CLK_LANE_SWITCH_TIME_CNT, _MIPIC_CLK_LANE_SWITCH_TIME_CNT)
|
||||
#define LP_HS_SSW_CNT_SHIFT 16
|
||||
#define LP_HS_SSW_CNT_MASK (0xffff << 16)
|
||||
#define HS_LP_PWR_SW_CNT_SHIFT 0
|
||||
#define HS_LP_PWR_SW_CNT_MASK (0xffff << 0)
|
||||
|
||||
#define _MIPIA_STOP_STATE_STALL (dev_priv->mipi_mmio_base + 0xb08c)
|
||||
#define _MIPIC_STOP_STATE_STALL (dev_priv->mipi_mmio_base + 0xb88c)
|
||||
#define _MIPIA_STOP_STATE_STALL (_MIPI_MMIO_BASE(dev_priv) + 0xb08c)
|
||||
#define _MIPIC_STOP_STATE_STALL (_MIPI_MMIO_BASE(dev_priv) + 0xb88c)
|
||||
#define MIPI_STOP_STATE_STALL(port) _MMIO_MIPI(port, _MIPIA_STOP_STATE_STALL, _MIPIC_STOP_STATE_STALL)
|
||||
#define STOP_STATE_STALL_COUNTER_SHIFT 0
|
||||
#define STOP_STATE_STALL_COUNTER_MASK (0xff << 0)
|
||||
|
||||
#define _MIPIA_INTR_STAT_REG_1 (dev_priv->mipi_mmio_base + 0xb090)
|
||||
#define _MIPIC_INTR_STAT_REG_1 (dev_priv->mipi_mmio_base + 0xb890)
|
||||
#define _MIPIA_INTR_STAT_REG_1 (_MIPI_MMIO_BASE(dev_priv) + 0xb090)
|
||||
#define _MIPIC_INTR_STAT_REG_1 (_MIPI_MMIO_BASE(dev_priv) + 0xb890)
|
||||
#define MIPI_INTR_STAT_REG_1(port) _MMIO_MIPI(port, _MIPIA_INTR_STAT_REG_1, _MIPIC_INTR_STAT_REG_1)
|
||||
#define _MIPIA_INTR_EN_REG_1 (dev_priv->mipi_mmio_base + 0xb094)
|
||||
#define _MIPIC_INTR_EN_REG_1 (dev_priv->mipi_mmio_base + 0xb894)
|
||||
#define _MIPIA_INTR_EN_REG_1 (_MIPI_MMIO_BASE(dev_priv) + 0xb094)
|
||||
#define _MIPIC_INTR_EN_REG_1 (_MIPI_MMIO_BASE(dev_priv) + 0xb894)
|
||||
#define MIPI_INTR_EN_REG_1(port) _MMIO_MIPI(port, _MIPIA_INTR_EN_REG_1, _MIPIC_INTR_EN_REG_1)
|
||||
#define RX_CONTENTION_DETECTED (1 << 0)
|
||||
|
||||
/* XXX: only pipe A ?!? */
|
||||
#define MIPIA_DBI_TYPEC_CTRL (dev_priv->mipi_mmio_base + 0xb100)
|
||||
#define MIPIA_DBI_TYPEC_CTRL (_MIPI_MMIO_BASE(dev_priv) + 0xb100)
|
||||
#define DBI_TYPEC_ENABLE (1 << 31)
|
||||
#define DBI_TYPEC_WIP (1 << 30)
|
||||
#define DBI_TYPEC_OPTION_SHIFT 28
|
||||
@ -407,8 +409,8 @@
|
||||
|
||||
/* MIPI adapter registers */
|
||||
|
||||
#define _MIPIA_CTRL (dev_priv->mipi_mmio_base + 0xb104)
|
||||
#define _MIPIC_CTRL (dev_priv->mipi_mmio_base + 0xb904)
|
||||
#define _MIPIA_CTRL (_MIPI_MMIO_BASE(dev_priv) + 0xb104)
|
||||
#define _MIPIC_CTRL (_MIPI_MMIO_BASE(dev_priv) + 0xb904)
|
||||
#define MIPI_CTRL(port) _MMIO_MIPI(port, _MIPIA_CTRL, _MIPIC_CTRL)
|
||||
#define ESCAPE_CLOCK_DIVIDER_SHIFT 5 /* A only */
|
||||
#define ESCAPE_CLOCK_DIVIDER_MASK (3 << 5)
|
||||
@ -440,21 +442,21 @@
|
||||
#define GLK_MIPIIO_PORT_POWERED (1 << 1) /* RO */
|
||||
#define GLK_MIPIIO_ENABLE (1 << 0)
|
||||
|
||||
#define _MIPIA_DATA_ADDRESS (dev_priv->mipi_mmio_base + 0xb108)
|
||||
#define _MIPIC_DATA_ADDRESS (dev_priv->mipi_mmio_base + 0xb908)
|
||||
#define _MIPIA_DATA_ADDRESS (_MIPI_MMIO_BASE(dev_priv) + 0xb108)
|
||||
#define _MIPIC_DATA_ADDRESS (_MIPI_MMIO_BASE(dev_priv) + 0xb908)
|
||||
#define MIPI_DATA_ADDRESS(port) _MMIO_MIPI(port, _MIPIA_DATA_ADDRESS, _MIPIC_DATA_ADDRESS)
|
||||
#define DATA_MEM_ADDRESS_SHIFT 5
|
||||
#define DATA_MEM_ADDRESS_MASK (0x7ffffff << 5)
|
||||
#define DATA_VALID (1 << 0)
|
||||
|
||||
#define _MIPIA_DATA_LENGTH (dev_priv->mipi_mmio_base + 0xb10c)
|
||||
#define _MIPIC_DATA_LENGTH (dev_priv->mipi_mmio_base + 0xb90c)
|
||||
#define _MIPIA_DATA_LENGTH (_MIPI_MMIO_BASE(dev_priv) + 0xb10c)
|
||||
#define _MIPIC_DATA_LENGTH (_MIPI_MMIO_BASE(dev_priv) + 0xb90c)
|
||||
#define MIPI_DATA_LENGTH(port) _MMIO_MIPI(port, _MIPIA_DATA_LENGTH, _MIPIC_DATA_LENGTH)
|
||||
#define DATA_LENGTH_SHIFT 0
|
||||
#define DATA_LENGTH_MASK (0xfffff << 0)
|
||||
|
||||
#define _MIPIA_COMMAND_ADDRESS (dev_priv->mipi_mmio_base + 0xb110)
|
||||
#define _MIPIC_COMMAND_ADDRESS (dev_priv->mipi_mmio_base + 0xb910)
|
||||
#define _MIPIA_COMMAND_ADDRESS (_MIPI_MMIO_BASE(dev_priv) + 0xb110)
|
||||
#define _MIPIC_COMMAND_ADDRESS (_MIPI_MMIO_BASE(dev_priv) + 0xb910)
|
||||
#define MIPI_COMMAND_ADDRESS(port) _MMIO_MIPI(port, _MIPIA_COMMAND_ADDRESS, _MIPIC_COMMAND_ADDRESS)
|
||||
#define COMMAND_MEM_ADDRESS_SHIFT 5
|
||||
#define COMMAND_MEM_ADDRESS_MASK (0x7ffffff << 5)
|
||||
@ -462,18 +464,18 @@
|
||||
#define MEMORY_WRITE_DATA_FROM_PIPE_RENDERING (1 << 1)
|
||||
#define COMMAND_VALID (1 << 0)
|
||||
|
||||
#define _MIPIA_COMMAND_LENGTH (dev_priv->mipi_mmio_base + 0xb114)
|
||||
#define _MIPIC_COMMAND_LENGTH (dev_priv->mipi_mmio_base + 0xb914)
|
||||
#define _MIPIA_COMMAND_LENGTH (_MIPI_MMIO_BASE(dev_priv) + 0xb114)
|
||||
#define _MIPIC_COMMAND_LENGTH (_MIPI_MMIO_BASE(dev_priv) + 0xb914)
|
||||
#define MIPI_COMMAND_LENGTH(port) _MMIO_MIPI(port, _MIPIA_COMMAND_LENGTH, _MIPIC_COMMAND_LENGTH)
|
||||
#define COMMAND_LENGTH_SHIFT(n) (8 * (n)) /* n: 0...3 */
|
||||
#define COMMAND_LENGTH_MASK(n) (0xff << (8 * (n)))
|
||||
|
||||
#define _MIPIA_READ_DATA_RETURN0 (dev_priv->mipi_mmio_base + 0xb118)
|
||||
#define _MIPIC_READ_DATA_RETURN0 (dev_priv->mipi_mmio_base + 0xb918)
|
||||
#define _MIPIA_READ_DATA_RETURN0 (_MIPI_MMIO_BASE(dev_priv) + 0xb118)
|
||||
#define _MIPIC_READ_DATA_RETURN0 (_MIPI_MMIO_BASE(dev_priv) + 0xb918)
|
||||
#define MIPI_READ_DATA_RETURN(port, n) _MMIO(_MIPI(port, _MIPIA_READ_DATA_RETURN0, _MIPIC_READ_DATA_RETURN0) + 4 * (n)) /* n: 0...7 */
|
||||
|
||||
#define _MIPIA_READ_DATA_VALID (dev_priv->mipi_mmio_base + 0xb138)
|
||||
#define _MIPIC_READ_DATA_VALID (dev_priv->mipi_mmio_base + 0xb938)
|
||||
#define _MIPIA_READ_DATA_VALID (_MIPI_MMIO_BASE(dev_priv) + 0xb138)
|
||||
#define _MIPIC_READ_DATA_VALID (_MIPI_MMIO_BASE(dev_priv) + 0xb938)
|
||||
#define MIPI_READ_DATA_VALID(port) _MMIO_MIPI(port, _MIPIA_READ_DATA_VALID, _MIPIC_READ_DATA_VALID)
|
||||
#define READ_DATA_VALID(n) (1 << (n))
|
||||
|
||||
|
@ -504,8 +504,8 @@ void intel_gt_pm_frequency_dump(struct intel_gt *gt, struct drm_printer *p)
|
||||
drm_puts(p, "no P-state info available\n");
|
||||
}
|
||||
|
||||
drm_printf(p, "Current CD clock frequency: %d kHz\n", i915->cdclk.hw.cdclk);
|
||||
drm_printf(p, "Max CD clock frequency: %d kHz\n", i915->max_cdclk_freq);
|
||||
drm_printf(p, "Current CD clock frequency: %d kHz\n", i915->display.cdclk.hw.cdclk);
|
||||
drm_printf(p, "Max CD clock frequency: %d kHz\n", i915->display.cdclk.max_cdclk_freq);
|
||||
drm_printf(p, "Max pixel clock frequency: %d kHz\n", i915->max_dotclk_freq);
|
||||
|
||||
intel_runtime_pm_put(uncore->rpm, wakeref);
|
||||
|
@ -32,9 +32,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "display/intel_gmbus_regs.h"
|
||||
#include "gvt.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "gvt.h"
|
||||
|
||||
#define GMBUS1_TOTAL_BYTES_SHIFT 16
|
||||
#define GMBUS1_TOTAL_BYTES_MASK 0x1ff
|
||||
|
@ -492,7 +492,7 @@ static int i915_runtime_pm_status(struct seq_file *m, void *unused)
|
||||
seq_puts(m, "Runtime power management not supported\n");
|
||||
|
||||
seq_printf(m, "Runtime power status: %s\n",
|
||||
str_enabled_disabled(!dev_priv->power_domains.init_wakeref));
|
||||
str_enabled_disabled(!dev_priv->display.power.domains.init_wakeref));
|
||||
|
||||
seq_printf(m, "GPU idle: %s\n", str_yes_no(!to_gt(dev_priv)->awake));
|
||||
seq_printf(m, "IRQs disabled: %s\n",
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "display/intel_pps.h"
|
||||
#include "display/intel_sprite.h"
|
||||
#include "display/intel_vga.h"
|
||||
#include "display/skl_watermark.h"
|
||||
|
||||
#include "gem/i915_gem_context.h"
|
||||
#include "gem/i915_gem_create.h"
|
||||
@ -343,7 +344,7 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
|
||||
|
||||
spin_lock_init(&dev_priv->irq_lock);
|
||||
spin_lock_init(&dev_priv->gpu_error.lock);
|
||||
mutex_init(&dev_priv->backlight_lock);
|
||||
mutex_init(&dev_priv->display.backlight.lock);
|
||||
|
||||
mutex_init(&dev_priv->sb_lock);
|
||||
cpu_latency_qos_add_request(&dev_priv->sb_qos, PM_QOS_DEFAULT_VALUE);
|
||||
@ -351,7 +352,7 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
|
||||
mutex_init(&dev_priv->display.audio.mutex);
|
||||
mutex_init(&dev_priv->display.wm.wm_mutex);
|
||||
mutex_init(&dev_priv->display.pps.mutex);
|
||||
mutex_init(&dev_priv->hdcp_comp_mutex);
|
||||
mutex_init(&dev_priv->display.hdcp.comp_mutex);
|
||||
|
||||
i915_memcpy_init_early(dev_priv);
|
||||
intel_runtime_pm_init_early(&dev_priv->runtime_pm);
|
||||
@ -986,7 +987,9 @@ out_fini:
|
||||
|
||||
void i915_driver_remove(struct drm_i915_private *i915)
|
||||
{
|
||||
disable_rpm_wakeref_asserts(&i915->runtime_pm);
|
||||
intel_wakeref_t wakeref;
|
||||
|
||||
wakeref = intel_runtime_pm_get(&i915->runtime_pm);
|
||||
|
||||
i915_driver_unregister(i915);
|
||||
|
||||
@ -1010,18 +1013,19 @@ void i915_driver_remove(struct drm_i915_private *i915)
|
||||
|
||||
i915_driver_hw_remove(i915);
|
||||
|
||||
enable_rpm_wakeref_asserts(&i915->runtime_pm);
|
||||
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
|
||||
}
|
||||
|
||||
static void i915_driver_release(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_runtime_pm *rpm = &dev_priv->runtime_pm;
|
||||
intel_wakeref_t wakeref;
|
||||
|
||||
if (!dev_priv->do_release)
|
||||
return;
|
||||
|
||||
disable_rpm_wakeref_asserts(rpm);
|
||||
wakeref = intel_runtime_pm_get(rpm);
|
||||
|
||||
i915_gem_driver_release(dev_priv);
|
||||
|
||||
@ -1032,7 +1036,8 @@ static void i915_driver_release(struct drm_device *dev)
|
||||
|
||||
i915_driver_mmio_release(dev_priv);
|
||||
|
||||
enable_rpm_wakeref_asserts(rpm);
|
||||
intel_runtime_pm_put(rpm, wakeref);
|
||||
|
||||
intel_runtime_pm_driver_release(rpm);
|
||||
|
||||
i915_driver_late_release(dev_priv);
|
||||
@ -1751,7 +1756,7 @@ static int intel_runtime_resume(struct device *kdev)
|
||||
intel_hpd_poll_disable(dev_priv);
|
||||
}
|
||||
|
||||
intel_enable_ipc(dev_priv);
|
||||
skl_watermark_ipc_update(dev_priv);
|
||||
|
||||
enable_rpm_wakeref_asserts(rpm);
|
||||
|
||||
|
@ -34,18 +34,10 @@
|
||||
|
||||
#include <linux/pm_qos.h>
|
||||
|
||||
#include <drm/drm_connector.h>
|
||||
#include <drm/ttm/ttm_device.h>
|
||||
|
||||
#include "display/intel_cdclk.h"
|
||||
#include "display/intel_display.h"
|
||||
#include "display/intel_display_core.h"
|
||||
#include "display/intel_display_power.h"
|
||||
#include "display/intel_dsb.h"
|
||||
#include "display/intel_fbc.h"
|
||||
#include "display/intel_frontbuffer.h"
|
||||
#include "display/intel_global_state.h"
|
||||
#include "display/intel_opregion.h"
|
||||
|
||||
#include "gem/i915_gem_context_types.h"
|
||||
#include "gem/i915_gem_lmem.h"
|
||||
@ -76,9 +68,6 @@
|
||||
struct drm_i915_clock_gating_funcs;
|
||||
struct drm_i915_gem_object;
|
||||
struct drm_i915_private;
|
||||
struct intel_cdclk_config;
|
||||
struct intel_cdclk_state;
|
||||
struct intel_cdclk_vals;
|
||||
struct intel_connector;
|
||||
struct intel_dp;
|
||||
struct intel_encoder;
|
||||
@ -96,26 +85,10 @@ struct vlv_s0ix_state;
|
||||
I915_GEM_DOMAIN_INSTRUCTION | \
|
||||
I915_GEM_DOMAIN_VERTEX)
|
||||
|
||||
struct sdvo_device_mapping {
|
||||
u8 initialized;
|
||||
u8 dvo_port;
|
||||
u8 slave_addr;
|
||||
u8 dvo_wiring;
|
||||
u8 i2c_pin;
|
||||
u8 ddc_pin;
|
||||
};
|
||||
|
||||
#define I915_COLOR_UNEVICTABLE (-1) /* a non-vma sharing the address space */
|
||||
|
||||
#define GEM_QUIRK_PIN_SWIZZLED_PAGES BIT(0)
|
||||
|
||||
#define QUIRK_LVDS_SSC_DISABLE (1<<1)
|
||||
#define QUIRK_INVERT_BRIGHTNESS (1<<2)
|
||||
#define QUIRK_BACKLIGHT_PRESENT (1<<3)
|
||||
#define QUIRK_INCREASE_T12_DELAY (1<<6)
|
||||
#define QUIRK_INCREASE_DDI_DISABLED_TIME (1<<7)
|
||||
#define QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK (1<<8)
|
||||
|
||||
struct i915_suspend_saved_registers {
|
||||
u32 saveDSPARB;
|
||||
u32 saveSWF0[16];
|
||||
@ -204,51 +177,8 @@ i915_fence_timeout(const struct drm_i915_private *i915)
|
||||
return i915_fence_context_timeout(i915, U64_MAX);
|
||||
}
|
||||
|
||||
/* Amount of SAGV/QGV points, BSpec precisely defines this */
|
||||
#define I915_NUM_QGV_POINTS 8
|
||||
|
||||
#define HAS_HW_SAGV_WM(i915) (DISPLAY_VER(i915) >= 13 && !IS_DGFX(i915))
|
||||
|
||||
/* Amount of PSF GV points, BSpec precisely defines this */
|
||||
#define I915_NUM_PSF_GV_POINTS 3
|
||||
|
||||
struct intel_vbt_data {
|
||||
/* bdb version */
|
||||
u16 version;
|
||||
|
||||
/* Feature bits */
|
||||
unsigned int int_tv_support:1;
|
||||
unsigned int int_crt_support:1;
|
||||
unsigned int lvds_use_ssc:1;
|
||||
unsigned int int_lvds_support:1;
|
||||
unsigned int display_clock_mode:1;
|
||||
unsigned int fdi_rx_polarity_inverted:1;
|
||||
int lvds_ssc_freq;
|
||||
enum drm_panel_orientation orientation;
|
||||
|
||||
bool override_afc_startup;
|
||||
u8 override_afc_startup_val;
|
||||
|
||||
int crt_ddc_pin;
|
||||
|
||||
struct list_head display_devices;
|
||||
struct list_head bdb_blocks;
|
||||
|
||||
struct intel_bios_encoder_data *ports[I915_MAX_PORTS]; /* Non-NULL if port present. */
|
||||
struct sdvo_device_mapping sdvo_mappings[2];
|
||||
};
|
||||
|
||||
struct i915_frontbuffer_tracking {
|
||||
spinlock_t lock;
|
||||
|
||||
/*
|
||||
* Tracking bits for delayed frontbuffer flushing du to gpu activity or
|
||||
* scheduled flips.
|
||||
*/
|
||||
unsigned busy_bits;
|
||||
unsigned flip_bits;
|
||||
};
|
||||
|
||||
struct i915_virtual_gpu {
|
||||
struct mutex lock; /* serialises sending of g2v_notify command pkts */
|
||||
bool active;
|
||||
@ -311,9 +241,6 @@ struct drm_i915_private {
|
||||
|
||||
struct intel_wopcm wopcm;
|
||||
|
||||
/* MMIO base address for MIPI regs */
|
||||
u32 mipi_mmio_base;
|
||||
|
||||
struct pci_dev *bridge_dev;
|
||||
|
||||
struct rb_root uabi_engines;
|
||||
@ -337,41 +264,15 @@ struct drm_i915_private {
|
||||
};
|
||||
u32 pipestat_irq_mask[I915_MAX_PIPES];
|
||||
|
||||
struct intel_fbc *fbc[I915_MAX_FBCS];
|
||||
struct intel_opregion opregion;
|
||||
struct intel_vbt_data vbt;
|
||||
|
||||
bool preserve_bios_swizzle;
|
||||
|
||||
/* backlight registers and fields in struct intel_panel */
|
||||
struct mutex backlight_lock;
|
||||
|
||||
unsigned int fsb_freq, mem_freq, is_ddr3;
|
||||
unsigned int skl_preferred_vco_freq;
|
||||
unsigned int max_cdclk_freq;
|
||||
|
||||
unsigned int max_dotclk_freq;
|
||||
unsigned int hpll_freq;
|
||||
unsigned int fdi_pll_freq;
|
||||
unsigned int czclk_freq;
|
||||
|
||||
struct {
|
||||
/* The current hardware cdclk configuration */
|
||||
struct intel_cdclk_config hw;
|
||||
|
||||
/* cdclk, divider, and ratio table from bspec */
|
||||
const struct intel_cdclk_vals *table;
|
||||
|
||||
struct intel_global_obj obj;
|
||||
} cdclk;
|
||||
|
||||
struct {
|
||||
/* The current hardware dbuf configuration */
|
||||
u8 enabled_slices;
|
||||
|
||||
struct intel_global_obj obj;
|
||||
} dbuf;
|
||||
|
||||
/**
|
||||
* wq - Driver workqueue for GEM.
|
||||
*
|
||||
@ -381,11 +282,6 @@ struct drm_i915_private {
|
||||
*/
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
/* ordered wq for modesets */
|
||||
struct workqueue_struct *modeset_wq;
|
||||
/* unbound hipri wq for page flips/plane updates */
|
||||
struct workqueue_struct *flip_wq;
|
||||
|
||||
/* pm private clock gating functions */
|
||||
const struct drm_i915_clock_gating_funcs *clock_gating_funcs;
|
||||
|
||||
@ -394,7 +290,6 @@ struct drm_i915_private {
|
||||
unsigned short pch_id;
|
||||
|
||||
unsigned long gem_quirks;
|
||||
unsigned long quirks;
|
||||
|
||||
struct drm_atomic_state *modeset_restore_state;
|
||||
struct drm_modeset_acquire_ctx reset_ctx;
|
||||
@ -405,13 +300,6 @@ struct drm_i915_private {
|
||||
|
||||
struct list_head global_obj_list;
|
||||
|
||||
struct i915_frontbuffer_tracking fb_tracking;
|
||||
|
||||
struct intel_atomic_helper {
|
||||
struct llist_head free_list;
|
||||
struct work_struct free_work;
|
||||
} atomic_helper;
|
||||
|
||||
bool mchbar_need_disable;
|
||||
|
||||
struct intel_l3_parity l3_parity;
|
||||
@ -430,17 +318,8 @@ struct drm_i915_private {
|
||||
*/
|
||||
u32 edram_size_mb;
|
||||
|
||||
struct i915_power_domains power_domains;
|
||||
|
||||
struct i915_gpu_error gpu_error;
|
||||
|
||||
struct drm_property *broadcast_rgb_property;
|
||||
struct drm_property *force_audio_property;
|
||||
|
||||
u32 fdi_rx_config;
|
||||
|
||||
/* Shadow for DISPLAY_PHY_CONTROL which can't be safely read */
|
||||
u32 chv_phy_control;
|
||||
/*
|
||||
* Shadows for CHV DPLL_MD regs to keep the state
|
||||
* checker somewhat working in the presence hardware
|
||||
@ -470,18 +349,6 @@ struct drm_i915_private {
|
||||
u8 num_psf_gv_points;
|
||||
} dram_info;
|
||||
|
||||
struct intel_bw_info {
|
||||
/* for each QGV point */
|
||||
unsigned int deratedbw[I915_NUM_QGV_POINTS];
|
||||
/* for each PSF GV point */
|
||||
unsigned int psf_bw[I915_NUM_PSF_GV_POINTS];
|
||||
u8 num_qgv_points;
|
||||
u8 num_psf_gv_points;
|
||||
u8 num_planes;
|
||||
} max_bw[6];
|
||||
|
||||
struct intel_global_obj bw_obj;
|
||||
|
||||
struct intel_runtime_pm runtime_pm;
|
||||
|
||||
struct i915_perf perf;
|
||||
@ -524,16 +391,11 @@ struct drm_i915_private {
|
||||
|
||||
bool irq_enabled;
|
||||
|
||||
union {
|
||||
/* perform PHY state sanity checks? */
|
||||
bool chv_phy_assert[2];
|
||||
|
||||
/*
|
||||
* DG2: Mask of PHYs that were not calibrated by the firmware
|
||||
* and should not be used.
|
||||
*/
|
||||
u8 snps_phy_failed_calibration;
|
||||
};
|
||||
/*
|
||||
* DG2: Mask of PHYs that were not calibrated by the firmware
|
||||
* and should not be used.
|
||||
*/
|
||||
u8 snps_phy_failed_calibration;
|
||||
|
||||
bool ipc_enabled;
|
||||
|
||||
@ -541,12 +403,6 @@ struct drm_i915_private {
|
||||
|
||||
struct i915_drm_clients clients;
|
||||
|
||||
struct i915_hdcp_comp_master *hdcp_master;
|
||||
bool hdcp_comp_added;
|
||||
|
||||
/* Mutex to protect the above hdcp component related values. */
|
||||
struct mutex hdcp_comp_mutex;
|
||||
|
||||
/* The TTM device structure. */
|
||||
struct ttm_device bdev;
|
||||
|
||||
@ -605,8 +461,6 @@ static inline struct intel_gt *to_gt(struct drm_i915_private *i915)
|
||||
(engine__) && (engine__)->uabi_class == (class__); \
|
||||
(engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))
|
||||
|
||||
#define I915_GTT_OFFSET_NONE ((u32)-1)
|
||||
|
||||
#define INTEL_INFO(dev_priv) (&(dev_priv)->__info)
|
||||
#define RUNTIME_INFO(dev_priv) (&(dev_priv)->__runtime)
|
||||
#define DRIVER_CAPS(dev_priv) (&(dev_priv)->caps)
|
||||
@ -615,19 +469,19 @@ static inline struct intel_gt *to_gt(struct drm_i915_private *i915)
|
||||
|
||||
#define IP_VER(ver, rel) ((ver) << 8 | (rel))
|
||||
|
||||
#define GRAPHICS_VER(i915) (RUNTIME_INFO(i915)->graphics.ver)
|
||||
#define GRAPHICS_VER_FULL(i915) IP_VER(RUNTIME_INFO(i915)->graphics.ver, \
|
||||
RUNTIME_INFO(i915)->graphics.rel)
|
||||
#define GRAPHICS_VER(i915) (RUNTIME_INFO(i915)->graphics.ip.ver)
|
||||
#define GRAPHICS_VER_FULL(i915) IP_VER(RUNTIME_INFO(i915)->graphics.ip.ver, \
|
||||
RUNTIME_INFO(i915)->graphics.ip.rel)
|
||||
#define IS_GRAPHICS_VER(i915, from, until) \
|
||||
(GRAPHICS_VER(i915) >= (from) && GRAPHICS_VER(i915) <= (until))
|
||||
|
||||
#define MEDIA_VER(i915) (INTEL_INFO(i915)->media.ver)
|
||||
#define MEDIA_VER_FULL(i915) IP_VER(INTEL_INFO(i915)->media.ver, \
|
||||
INTEL_INFO(i915)->media.rel)
|
||||
#define MEDIA_VER(i915) (RUNTIME_INFO(i915)->media.ip.ver)
|
||||
#define MEDIA_VER_FULL(i915) IP_VER(RUNTIME_INFO(i915)->media.ip.ver, \
|
||||
RUNTIME_INFO(i915)->media.ip.rel)
|
||||
#define IS_MEDIA_VER(i915, from, until) \
|
||||
(MEDIA_VER(i915) >= (from) && MEDIA_VER(i915) <= (until))
|
||||
|
||||
#define DISPLAY_VER(i915) (INTEL_INFO(i915)->display.ver)
|
||||
#define DISPLAY_VER(i915) (RUNTIME_INFO(i915)->display.ip.ver)
|
||||
#define IS_DISPLAY_VER(i915, from, until) \
|
||||
(DISPLAY_VER(i915) >= (from) && DISPLAY_VER(i915) <= (until))
|
||||
|
||||
@ -1016,6 +870,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
|
||||
#define HAS_DP_MST(dev_priv) (INTEL_INFO(dev_priv)->display.has_dp_mst)
|
||||
#define HAS_DP20(dev_priv) (IS_DG2(dev_priv) || DISPLAY_VER(dev_priv) >= 14)
|
||||
|
||||
#define HAS_DOUBLE_BUFFERED_M_N(dev_priv) (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
|
||||
|
||||
#define HAS_CDCLK_CRAWL(dev_priv) (INTEL_INFO(dev_priv)->display.has_cdclk_crawl)
|
||||
#define HAS_DDI(dev_priv) (INTEL_INFO(dev_priv)->display.has_ddi)
|
||||
#define HAS_FPGA_DBG_UNCLAIMED(dev_priv) (INTEL_INFO(dev_priv)->display.has_fpga_dbg)
|
||||
@ -1122,79 +978,6 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
|
||||
|
||||
#define HAS_ONE_EU_PER_FUSE_BIT(i915) (INTEL_INFO(i915)->has_one_eu_per_fuse_bit)
|
||||
|
||||
/* i915_gem.c */
|
||||
void i915_gem_init_early(struct drm_i915_private *dev_priv);
|
||||
void i915_gem_cleanup_early(struct drm_i915_private *dev_priv);
|
||||
|
||||
static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
|
||||
{
|
||||
/*
|
||||
* A single pass should suffice to release all the freed objects (along
|
||||
* most call paths) , but be a little more paranoid in that freeing
|
||||
* the objects does take a little amount of time, during which the rcu
|
||||
* callbacks could have added new objects into the freed list, and
|
||||
* armed the work again.
|
||||
*/
|
||||
while (atomic_read(&i915->mm.free_count)) {
|
||||
flush_work(&i915->mm.free_work);
|
||||
flush_delayed_work(&i915->bdev.wq);
|
||||
rcu_barrier();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void i915_gem_drain_workqueue(struct drm_i915_private *i915)
|
||||
{
|
||||
/*
|
||||
* Similar to objects above (see i915_gem_drain_freed-objects), in
|
||||
* general we have workers that are armed by RCU and then rearm
|
||||
* themselves in their callbacks. To be paranoid, we need to
|
||||
* drain the workqueue a second time after waiting for the RCU
|
||||
* grace period so that we catch work queued via RCU from the first
|
||||
* pass. As neither drain_workqueue() nor flush_workqueue() report
|
||||
* a result, we make an assumption that we only don't require more
|
||||
* than 3 passes to catch all _recursive_ RCU delayed work.
|
||||
*
|
||||
*/
|
||||
int pass = 3;
|
||||
do {
|
||||
flush_workqueue(i915->wq);
|
||||
rcu_barrier();
|
||||
i915_gem_drain_freed_objects(i915);
|
||||
} while (--pass);
|
||||
drain_workqueue(i915->wq);
|
||||
}
|
||||
|
||||
struct i915_vma * __must_check
|
||||
i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object *obj,
|
||||
struct i915_gem_ww_ctx *ww,
|
||||
const struct i915_gtt_view *view,
|
||||
u64 size, u64 alignment, u64 flags);
|
||||
|
||||
struct i915_vma * __must_check
|
||||
i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
|
||||
const struct i915_gtt_view *view,
|
||||
u64 size, u64 alignment, u64 flags);
|
||||
|
||||
int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
|
||||
unsigned long flags);
|
||||
#define I915_GEM_OBJECT_UNBIND_ACTIVE BIT(0)
|
||||
#define I915_GEM_OBJECT_UNBIND_BARRIER BIT(1)
|
||||
#define I915_GEM_OBJECT_UNBIND_TEST BIT(2)
|
||||
#define I915_GEM_OBJECT_UNBIND_VM_TRYLOCK BIT(3)
|
||||
#define I915_GEM_OBJECT_UNBIND_ASYNC BIT(4)
|
||||
|
||||
void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv);
|
||||
|
||||
int __must_check i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno);
|
||||
|
||||
int __must_check i915_gem_init(struct drm_i915_private *dev_priv);
|
||||
void i915_gem_driver_register(struct drm_i915_private *i915);
|
||||
void i915_gem_driver_unregister(struct drm_i915_private *i915);
|
||||
void i915_gem_driver_remove(struct drm_i915_private *dev_priv);
|
||||
void i915_gem_driver_release(struct drm_i915_private *dev_priv);
|
||||
|
||||
int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file);
|
||||
|
||||
/* intel_device_info.c */
|
||||
static inline struct intel_device_info *
|
||||
mkwrite_device_info(struct drm_i915_private *dev_priv)
|
||||
|
@ -1089,6 +1089,43 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* A single pass should suffice to release all the freed objects (along most
|
||||
* call paths), but be a little more paranoid in that freeing the objects does
|
||||
* take a little amount of time, during which the rcu callbacks could have added
|
||||
* new objects into the freed list, and armed the work again.
|
||||
*/
|
||||
void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
|
||||
{
|
||||
while (atomic_read(&i915->mm.free_count)) {
|
||||
flush_work(&i915->mm.free_work);
|
||||
flush_delayed_work(&i915->bdev.wq);
|
||||
rcu_barrier();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Similar to objects above (see i915_gem_drain_freed-objects), in general we
|
||||
* have workers that are armed by RCU and then rearm themselves in their
|
||||
* callbacks. To be paranoid, we need to drain the workqueue a second time after
|
||||
* waiting for the RCU grace period so that we catch work queued via RCU from
|
||||
* the first pass. As neither drain_workqueue() nor flush_workqueue() report a
|
||||
* result, we make an assumption that we only don't require more than 3 passes
|
||||
* to catch all _recursive_ RCU delayed work.
|
||||
*/
|
||||
void i915_gem_drain_workqueue(struct drm_i915_private *i915)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
flush_workqueue(i915->wq);
|
||||
rcu_barrier();
|
||||
i915_gem_drain_freed_objects(i915);
|
||||
}
|
||||
|
||||
drain_workqueue(i915->wq);
|
||||
}
|
||||
|
||||
int i915_gem_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
int ret;
|
||||
@ -1216,7 +1253,7 @@ void i915_gem_init_early(struct drm_i915_private *dev_priv)
|
||||
i915_gem_init__mm(dev_priv);
|
||||
i915_gem_init__contexts(dev_priv);
|
||||
|
||||
spin_lock_init(&dev_priv->fb_tracking.lock);
|
||||
spin_lock_init(&dev_priv->display.fb_tracking.lock);
|
||||
}
|
||||
|
||||
void i915_gem_cleanup_early(struct drm_i915_private *dev_priv)
|
||||
|
@ -26,12 +26,55 @@
|
||||
#define __I915_GEM_H__
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <drm/drm_drv.h>
|
||||
|
||||
#include "i915_utils.h"
|
||||
|
||||
struct drm_file;
|
||||
struct drm_i915_gem_object;
|
||||
struct drm_i915_private;
|
||||
struct i915_gem_ww_ctx;
|
||||
struct i915_gtt_view;
|
||||
struct i915_vma;
|
||||
|
||||
void i915_gem_init_early(struct drm_i915_private *i915);
|
||||
void i915_gem_cleanup_early(struct drm_i915_private *i915);
|
||||
|
||||
void i915_gem_drain_freed_objects(struct drm_i915_private *i915);
|
||||
void i915_gem_drain_workqueue(struct drm_i915_private *i915);
|
||||
|
||||
struct i915_vma * __must_check
|
||||
i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object *obj,
|
||||
struct i915_gem_ww_ctx *ww,
|
||||
const struct i915_gtt_view *view,
|
||||
u64 size, u64 alignment, u64 flags);
|
||||
|
||||
struct i915_vma * __must_check
|
||||
i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
|
||||
const struct i915_gtt_view *view,
|
||||
u64 size, u64 alignment, u64 flags);
|
||||
|
||||
int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
|
||||
unsigned long flags);
|
||||
#define I915_GEM_OBJECT_UNBIND_ACTIVE BIT(0)
|
||||
#define I915_GEM_OBJECT_UNBIND_BARRIER BIT(1)
|
||||
#define I915_GEM_OBJECT_UNBIND_TEST BIT(2)
|
||||
#define I915_GEM_OBJECT_UNBIND_VM_TRYLOCK BIT(3)
|
||||
#define I915_GEM_OBJECT_UNBIND_ASYNC BIT(4)
|
||||
|
||||
void i915_gem_runtime_suspend(struct drm_i915_private *i915);
|
||||
|
||||
int __must_check i915_gem_init(struct drm_i915_private *i915);
|
||||
void i915_gem_driver_register(struct drm_i915_private *i915);
|
||||
void i915_gem_driver_unregister(struct drm_i915_private *i915);
|
||||
void i915_gem_driver_remove(struct drm_i915_private *i915);
|
||||
void i915_gem_driver_release(struct drm_i915_private *i915);
|
||||
|
||||
int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file);
|
||||
|
||||
/* FIXME: All of the below belong somewhere else. */
|
||||
|
||||
#ifdef CONFIG_DRM_I915_DEBUG_GEM
|
||||
|
||||
|
@ -595,7 +595,7 @@ void i915_disable_pipestat(struct drm_i915_private *dev_priv,
|
||||
|
||||
static bool i915_has_asle(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
if (!dev_priv->opregion.asle)
|
||||
if (!dev_priv->display.opregion.asle)
|
||||
return false;
|
||||
|
||||
return IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv);
|
||||
|
@ -37,9 +37,9 @@
|
||||
|
||||
#define PLATFORM(x) .platform = (x)
|
||||
#define GEN(x) \
|
||||
.__runtime.graphics.ver = (x), \
|
||||
.media.ver = (x), \
|
||||
.display.ver = (x)
|
||||
.__runtime.graphics.ip.ver = (x), \
|
||||
.__runtime.media.ip.ver = (x), \
|
||||
.__runtime.display.ip.ver = (x)
|
||||
|
||||
#define I845_PIPE_OFFSETS \
|
||||
.display.pipe_offsets = { \
|
||||
@ -743,7 +743,7 @@ static const struct intel_device_info bxt_info = {
|
||||
static const struct intel_device_info glk_info = {
|
||||
GEN9_LP_FEATURES,
|
||||
PLATFORM(INTEL_GEMINILAKE),
|
||||
.display.ver = 10,
|
||||
.__runtime.display.ip.ver = 10,
|
||||
.display.dbuf.size = 1024 - 4, /* 4 blocks for bypass path allocation */
|
||||
GLK_COLORS,
|
||||
};
|
||||
@ -922,7 +922,7 @@ static const struct intel_device_info rkl_info = {
|
||||
static const struct intel_device_info dg1_info = {
|
||||
GEN12_FEATURES,
|
||||
DGFX_FEATURES,
|
||||
.__runtime.graphics.rel = 10,
|
||||
.__runtime.graphics.ip.rel = 10,
|
||||
PLATFORM(INTEL_DG1),
|
||||
.__runtime.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),
|
||||
.require_force_probe = 1,
|
||||
@ -965,7 +965,7 @@ static const struct intel_device_info adl_s_info = {
|
||||
.display.has_hotplug = 1, \
|
||||
.display.has_ipc = 1, \
|
||||
.display.has_psr = 1, \
|
||||
.display.ver = 13, \
|
||||
.__runtime.display.ip.ver = 13, \
|
||||
.__runtime.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), \
|
||||
.display.pipe_offsets = { \
|
||||
[TRANSCODER_A] = PIPE_A_OFFSET, \
|
||||
@ -1009,8 +1009,8 @@ static const struct intel_device_info adl_p_info = {
|
||||
I915_GTT_PAGE_SIZE_2M
|
||||
|
||||
#define XE_HP_FEATURES \
|
||||
.__runtime.graphics.ver = 12, \
|
||||
.__runtime.graphics.rel = 50, \
|
||||
.__runtime.graphics.ip.ver = 12, \
|
||||
.__runtime.graphics.ip.rel = 50, \
|
||||
XE_HP_PAGE_SIZES, \
|
||||
.dma_mask_size = 46, \
|
||||
.has_3d_pipeline = 1, \
|
||||
@ -1030,8 +1030,8 @@ static const struct intel_device_info adl_p_info = {
|
||||
.__runtime.ppgtt_type = INTEL_PPGTT_FULL
|
||||
|
||||
#define XE_HPM_FEATURES \
|
||||
.media.ver = 12, \
|
||||
.media.rel = 50
|
||||
.__runtime.media.ip.ver = 12, \
|
||||
.__runtime.media.ip.rel = 50
|
||||
|
||||
__maybe_unused
|
||||
static const struct intel_device_info xehpsdv_info = {
|
||||
@ -1056,8 +1056,8 @@ static const struct intel_device_info xehpsdv_info = {
|
||||
XE_HP_FEATURES, \
|
||||
XE_HPM_FEATURES, \
|
||||
DGFX_FEATURES, \
|
||||
.__runtime.graphics.rel = 55, \
|
||||
.media.rel = 55, \
|
||||
.__runtime.graphics.ip.rel = 55, \
|
||||
.__runtime.media.ip.rel = 55, \
|
||||
PLATFORM(INTEL_DG2), \
|
||||
.has_4tile = 1, \
|
||||
.has_64k_pages = 1, \
|
||||
@ -1100,8 +1100,8 @@ static const struct intel_device_info pvc_info = {
|
||||
XE_HPC_FEATURES,
|
||||
XE_HPM_FEATURES,
|
||||
DGFX_FEATURES,
|
||||
.__runtime.graphics.rel = 60,
|
||||
.media.rel = 60,
|
||||
.__runtime.graphics.ip.rel = 60,
|
||||
.__runtime.media.ip.rel = 60,
|
||||
PLATFORM(INTEL_PONTEVECCHIO),
|
||||
.display = { 0 },
|
||||
.has_flat_ccs = 0,
|
||||
@ -1114,7 +1114,7 @@ static const struct intel_device_info pvc_info = {
|
||||
|
||||
#define XE_LPDP_FEATURES \
|
||||
XE_LPD_FEATURES, \
|
||||
.display.ver = 14, \
|
||||
.__runtime.display.ip.ver = 14, \
|
||||
.display.has_cdclk_crawl = 1, \
|
||||
.__runtime.fbc_mask = BIT(INTEL_FBC_A) | BIT(INTEL_FBC_B)
|
||||
|
||||
@ -1136,9 +1136,9 @@ static const struct intel_device_info mtl_info = {
|
||||
* Real graphics IP version will be obtained from hardware GMD_ID
|
||||
* register. Value provided here is just for sanity checking.
|
||||
*/
|
||||
.__runtime.graphics.ver = 12,
|
||||
.__runtime.graphics.rel = 70,
|
||||
.media.ver = 13,
|
||||
.__runtime.graphics.ip.ver = 12,
|
||||
.__runtime.graphics.ip.rel = 70,
|
||||
.__runtime.media.ip.ver = 13,
|
||||
PLATFORM(INTEL_METEORLAKE),
|
||||
.display.has_modular_fia = 1,
|
||||
.extra_gt_list = xelpmp_extra_gt,
|
||||
@ -1295,7 +1295,7 @@ bool i915_pci_resource_valid(struct pci_dev *pdev, int bar)
|
||||
|
||||
static bool intel_mmio_bar_valid(struct pci_dev *pdev, struct intel_device_info *intel_info)
|
||||
{
|
||||
int gttmmaddr_bar = intel_info->__runtime.graphics.ver == 2 ? GEN2_GTTMMADR_BAR : GTTMMADR_BAR;
|
||||
int gttmmaddr_bar = intel_info->__runtime.graphics.ip.ver == 2 ? GEN2_GTTMMADR_BAR : GTTMMADR_BAR;
|
||||
|
||||
return i915_pci_resource_valid(pdev, gttmmaddr_bar);
|
||||
}
|
||||
|
@ -1376,7 +1376,8 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
|
||||
{
|
||||
struct i915_perf *perf = stream->perf;
|
||||
|
||||
BUG_ON(stream != perf->exclusive_stream);
|
||||
if (WARN_ON(stream != perf->exclusive_stream))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Unset exclusive_stream first, it will be checked while disabling
|
||||
|
@ -1125,8 +1125,12 @@
|
||||
#define MBUS_DBOX_REGULATE_B2B_TRANSACTIONS_EN REG_BIT(16) /* tgl+ */
|
||||
#define MBUS_DBOX_BW_CREDIT_MASK REG_GENMASK(15, 14)
|
||||
#define MBUS_DBOX_BW_CREDIT(x) REG_FIELD_PREP(MBUS_DBOX_BW_CREDIT_MASK, x)
|
||||
#define MBUS_DBOX_BW_4CREDITS_MTL REG_FIELD_PREP(MBUS_DBOX_BW_CREDIT_MASK, 0x2)
|
||||
#define MBUS_DBOX_BW_8CREDITS_MTL REG_FIELD_PREP(MBUS_DBOX_BW_CREDIT_MASK, 0x3)
|
||||
#define MBUS_DBOX_B_CREDIT_MASK REG_GENMASK(12, 8)
|
||||
#define MBUS_DBOX_B_CREDIT(x) REG_FIELD_PREP(MBUS_DBOX_B_CREDIT_MASK, x)
|
||||
#define MBUS_DBOX_I_CREDIT_MASK REG_GENMASK(7, 5)
|
||||
#define MBUS_DBOX_I_CREDIT(x) REG_FIELD_PREP(MBUS_DBOX_I_CREDIT_MASK, x)
|
||||
#define MBUS_DBOX_A_CREDIT_MASK REG_GENMASK(3, 0)
|
||||
#define MBUS_DBOX_A_CREDIT(x) REG_FIELD_PREP(MBUS_DBOX_A_CREDIT_MASK, x)
|
||||
|
||||
@ -1461,69 +1465,6 @@
|
||||
#define FBC_REND_NUKE REG_BIT(2)
|
||||
#define FBC_REND_CACHE_CLEAN REG_BIT(1)
|
||||
|
||||
/*
|
||||
* GPIO regs
|
||||
*/
|
||||
#define GPIO(gpio) _MMIO(dev_priv->display.gmbus.mmio_base + 0x5010 + \
|
||||
4 * (gpio))
|
||||
|
||||
# define GPIO_CLOCK_DIR_MASK (1 << 0)
|
||||
# define GPIO_CLOCK_DIR_IN (0 << 1)
|
||||
# define GPIO_CLOCK_DIR_OUT (1 << 1)
|
||||
# define GPIO_CLOCK_VAL_MASK (1 << 2)
|
||||
# define GPIO_CLOCK_VAL_OUT (1 << 3)
|
||||
# define GPIO_CLOCK_VAL_IN (1 << 4)
|
||||
# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
|
||||
# define GPIO_DATA_DIR_MASK (1 << 8)
|
||||
# define GPIO_DATA_DIR_IN (0 << 9)
|
||||
# define GPIO_DATA_DIR_OUT (1 << 9)
|
||||
# define GPIO_DATA_VAL_MASK (1 << 10)
|
||||
# define GPIO_DATA_VAL_OUT (1 << 11)
|
||||
# define GPIO_DATA_VAL_IN (1 << 12)
|
||||
# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
|
||||
|
||||
#define GMBUS0 _MMIO(dev_priv->display.gmbus.mmio_base + 0x5100) /* clock/port select */
|
||||
#define GMBUS_AKSV_SELECT (1 << 11)
|
||||
#define GMBUS_RATE_100KHZ (0 << 8)
|
||||
#define GMBUS_RATE_50KHZ (1 << 8)
|
||||
#define GMBUS_RATE_400KHZ (2 << 8) /* reserved on Pineview */
|
||||
#define GMBUS_RATE_1MHZ (3 << 8) /* reserved on Pineview */
|
||||
#define GMBUS_HOLD_EXT (1 << 7) /* 300ns hold time, rsvd on Pineview */
|
||||
#define GMBUS_BYTE_CNT_OVERRIDE (1 << 6)
|
||||
|
||||
#define GMBUS1 _MMIO(dev_priv->display.gmbus.mmio_base + 0x5104) /* command/status */
|
||||
#define GMBUS_SW_CLR_INT (1 << 31)
|
||||
#define GMBUS_SW_RDY (1 << 30)
|
||||
#define GMBUS_ENT (1 << 29) /* enable timeout */
|
||||
#define GMBUS_CYCLE_NONE (0 << 25)
|
||||
#define GMBUS_CYCLE_WAIT (1 << 25)
|
||||
#define GMBUS_CYCLE_INDEX (2 << 25)
|
||||
#define GMBUS_CYCLE_STOP (4 << 25)
|
||||
#define GMBUS_BYTE_COUNT_SHIFT 16
|
||||
#define GMBUS_BYTE_COUNT_MAX 256U
|
||||
#define GEN9_GMBUS_BYTE_COUNT_MAX 511U
|
||||
#define GMBUS_SLAVE_INDEX_SHIFT 8
|
||||
#define GMBUS_SLAVE_ADDR_SHIFT 1
|
||||
#define GMBUS_SLAVE_READ (1 << 0)
|
||||
#define GMBUS_SLAVE_WRITE (0 << 0)
|
||||
#define GMBUS2 _MMIO(dev_priv->display.gmbus.mmio_base + 0x5108) /* status */
|
||||
#define GMBUS_INUSE (1 << 15)
|
||||
#define GMBUS_HW_WAIT_PHASE (1 << 14)
|
||||
#define GMBUS_STALL_TIMEOUT (1 << 13)
|
||||
#define GMBUS_INT (1 << 12)
|
||||
#define GMBUS_HW_RDY (1 << 11)
|
||||
#define GMBUS_SATOER (1 << 10)
|
||||
#define GMBUS_ACTIVE (1 << 9)
|
||||
#define GMBUS3 _MMIO(dev_priv->display.gmbus.mmio_base + 0x510c) /* data buffer bytes 3-0 */
|
||||
#define GMBUS4 _MMIO(dev_priv->display.gmbus.mmio_base + 0x5110) /* interrupt mask (Pineview+) */
|
||||
#define GMBUS_SLAVE_TIMEOUT_EN (1 << 4)
|
||||
#define GMBUS_NAK_EN (1 << 3)
|
||||
#define GMBUS_IDLE_EN (1 << 2)
|
||||
#define GMBUS_HW_WAIT_EN (1 << 1)
|
||||
#define GMBUS_HW_RDY_EN (1 << 0)
|
||||
#define GMBUS5 _MMIO(dev_priv->display.gmbus.mmio_base + 0x5120) /* byte index */
|
||||
#define GMBUS_2BYTE_INDEX_EN (1 << 31)
|
||||
|
||||
/*
|
||||
* Clock control & power management
|
||||
*/
|
||||
@ -1700,7 +1641,7 @@
|
||||
#define DSTATE_PLL_D3_OFF (1 << 3)
|
||||
#define DSTATE_GFX_CLOCK_GATING (1 << 1)
|
||||
#define DSTATE_DOT_CLOCK_GATING (1 << 0)
|
||||
#define DSPCLK_GATE_D _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x6200)
|
||||
#define DSPCLK_GATE_D(__i915) _MMIO(DISPLAY_MMIO_BASE(__i915) + 0x6200)
|
||||
# define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */
|
||||
# define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */
|
||||
# define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */
|
||||
@ -3514,6 +3455,34 @@
|
||||
#define DP_AUX_CH_CTL(aux_ch) _MMIO_PORT(aux_ch, _DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL)
|
||||
#define DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PORT(aux_ch, _DPA_AUX_CH_DATA1, _DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
|
||||
|
||||
#define _XELPDP_USBC1_AUX_CH_CTL 0x16F210
|
||||
#define _XELPDP_USBC2_AUX_CH_CTL 0x16F410
|
||||
#define _XELPDP_USBC3_AUX_CH_CTL 0x16F610
|
||||
#define _XELPDP_USBC4_AUX_CH_CTL 0x16F810
|
||||
|
||||
#define XELPDP_DP_AUX_CH_CTL(aux_ch) _MMIO(_PICK(aux_ch, \
|
||||
_DPA_AUX_CH_CTL, \
|
||||
_DPB_AUX_CH_CTL, \
|
||||
0, /* port/aux_ch C is non-existent */ \
|
||||
_XELPDP_USBC1_AUX_CH_CTL, \
|
||||
_XELPDP_USBC2_AUX_CH_CTL, \
|
||||
_XELPDP_USBC3_AUX_CH_CTL, \
|
||||
_XELPDP_USBC4_AUX_CH_CTL))
|
||||
|
||||
#define _XELPDP_USBC1_AUX_CH_DATA1 0x16F214
|
||||
#define _XELPDP_USBC2_AUX_CH_DATA1 0x16F414
|
||||
#define _XELPDP_USBC3_AUX_CH_DATA1 0x16F614
|
||||
#define _XELPDP_USBC4_AUX_CH_DATA1 0x16F814
|
||||
|
||||
#define XELPDP_DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PICK(aux_ch, \
|
||||
_DPA_AUX_CH_DATA1, \
|
||||
_DPB_AUX_CH_DATA1, \
|
||||
0, /* port/aux_ch C is non-existent */ \
|
||||
_XELPDP_USBC1_AUX_CH_DATA1, \
|
||||
_XELPDP_USBC2_AUX_CH_DATA1, \
|
||||
_XELPDP_USBC3_AUX_CH_DATA1, \
|
||||
_XELPDP_USBC4_AUX_CH_DATA1) + (i) * 4)
|
||||
|
||||
#define DP_AUX_CH_CTL_SEND_BUSY (1 << 31)
|
||||
#define DP_AUX_CH_CTL_DONE (1 << 30)
|
||||
#define DP_AUX_CH_CTL_INTERRUPT (1 << 29)
|
||||
@ -3526,6 +3495,8 @@
|
||||
#define DP_AUX_CH_CTL_RECEIVE_ERROR (1 << 25)
|
||||
#define DP_AUX_CH_CTL_MESSAGE_SIZE_MASK (0x1f << 20)
|
||||
#define DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT 20
|
||||
#define XELPDP_DP_AUX_CH_CTL_POWER_REQUEST REG_BIT(19)
|
||||
#define XELPDP_DP_AUX_CH_CTL_POWER_STATUS REG_BIT(18)
|
||||
#define DP_AUX_CH_CTL_PRECHARGE_2US_MASK (0xf << 16)
|
||||
#define DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT 16
|
||||
#define DP_AUX_CH_CTL_AUX_AKSV_SELECT (1 << 15)
|
||||
@ -5757,6 +5728,13 @@
|
||||
[TRANSCODER_B] = _CHICKEN_TRANS_B, \
|
||||
[TRANSCODER_C] = _CHICKEN_TRANS_C, \
|
||||
[TRANSCODER_D] = _CHICKEN_TRANS_D))
|
||||
|
||||
#define _MTL_CHICKEN_TRANS_A 0x604e0
|
||||
#define _MTL_CHICKEN_TRANS_B 0x614e0
|
||||
#define MTL_CHICKEN_TRANS(trans) _MMIO_TRANS((trans), \
|
||||
_MTL_CHICKEN_TRANS_A, \
|
||||
_MTL_CHICKEN_TRANS_B)
|
||||
|
||||
#define HSW_FRAME_START_DELAY_MASK REG_GENMASK(28, 27)
|
||||
#define HSW_FRAME_START_DELAY(x) REG_FIELD_PREP(HSW_FRAME_START_DELAY_MASK, x)
|
||||
#define VSC_DATA_SEL_SOFTWARE_CONTROL REG_BIT(25) /* GLK */
|
||||
@ -6614,10 +6592,10 @@
|
||||
#define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) + 245)
|
||||
#define BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ 0x18
|
||||
#define GEN9_PCODE_READ_MEM_LATENCY 0x6
|
||||
#define GEN9_MEM_LATENCY_LEVEL_MASK 0xFF
|
||||
#define GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT 8
|
||||
#define GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT 16
|
||||
#define GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT 24
|
||||
#define GEN9_MEM_LATENCY_LEVEL_3_7_MASK REG_GENMASK(31, 24)
|
||||
#define GEN9_MEM_LATENCY_LEVEL_2_6_MASK REG_GENMASK(23, 16)
|
||||
#define GEN9_MEM_LATENCY_LEVEL_1_5_MASK REG_GENMASK(15, 8)
|
||||
#define GEN9_MEM_LATENCY_LEVEL_0_4_MASK REG_GENMASK(7, 0)
|
||||
#define SKL_PCODE_LOAD_HDCP_KEYS 0x5
|
||||
#define SKL_PCODE_CDCLK_CONTROL 0x7
|
||||
#define SKL_CDCLK_PREPARE_FOR_CHANGE 0x3
|
||||
@ -7140,16 +7118,16 @@ enum skl_power_gate {
|
||||
|
||||
/* CDCLK_CTL */
|
||||
#define CDCLK_CTL _MMIO(0x46000)
|
||||
#define CDCLK_FREQ_SEL_MASK (3 << 26)
|
||||
#define CDCLK_FREQ_450_432 (0 << 26)
|
||||
#define CDCLK_FREQ_540 (1 << 26)
|
||||
#define CDCLK_FREQ_337_308 (2 << 26)
|
||||
#define CDCLK_FREQ_675_617 (3 << 26)
|
||||
#define BXT_CDCLK_CD2X_DIV_SEL_MASK (3 << 22)
|
||||
#define BXT_CDCLK_CD2X_DIV_SEL_1 (0 << 22)
|
||||
#define BXT_CDCLK_CD2X_DIV_SEL_1_5 (1 << 22)
|
||||
#define BXT_CDCLK_CD2X_DIV_SEL_2 (2 << 22)
|
||||
#define BXT_CDCLK_CD2X_DIV_SEL_4 (3 << 22)
|
||||
#define CDCLK_FREQ_SEL_MASK REG_GENMASK(27, 26)
|
||||
#define CDCLK_FREQ_450_432 REG_FIELD_PREP(CDCLK_FREQ_SEL_MASK, 0)
|
||||
#define CDCLK_FREQ_540 REG_FIELD_PREP(CDCLK_FREQ_SEL_MASK, 1)
|
||||
#define CDCLK_FREQ_337_308 REG_FIELD_PREP(CDCLK_FREQ_SEL_MASK, 2)
|
||||
#define CDCLK_FREQ_675_617 REG_FIELD_PREP(CDCLK_FREQ_SEL_MASK, 3)
|
||||
#define BXT_CDCLK_CD2X_DIV_SEL_MASK REG_GENMASK(23, 22)
|
||||
#define BXT_CDCLK_CD2X_DIV_SEL_1 REG_FIELD_PREP(BXT_CDCLK_CD2X_DIV_SEL_MASK, 0)
|
||||
#define BXT_CDCLK_CD2X_DIV_SEL_1_5 REG_FIELD_PREP(BXT_CDCLK_CD2X_DIV_SEL_MASK, 1)
|
||||
#define BXT_CDCLK_CD2X_DIV_SEL_2 REG_FIELD_PREP(BXT_CDCLK_CD2X_DIV_SEL_MASK, 2)
|
||||
#define BXT_CDCLK_CD2X_DIV_SEL_4 REG_FIELD_PREP(BXT_CDCLK_CD2X_DIV_SEL_MASK, 3)
|
||||
#define BXT_CDCLK_CD2X_PIPE(pipe) ((pipe) << 20)
|
||||
#define CDCLK_DIVMUX_CD_OVERRIDE (1 << 19)
|
||||
#define BXT_CDCLK_CD2X_PIPE_NONE BXT_CDCLK_CD2X_PIPE(3)
|
||||
@ -8361,4 +8339,21 @@ enum skl_power_gate {
|
||||
#define MTL_LATENCY_LEVEL_EVEN_MASK REG_GENMASK(12, 0)
|
||||
#define MTL_LATENCY_LEVEL_ODD_MASK REG_GENMASK(28, 16)
|
||||
|
||||
#define MTL_LATENCY_SAGV _MMIO(0x4578b)
|
||||
#define MTL_LATENCY_QCLK_SAGV REG_GENMASK(12, 0)
|
||||
|
||||
#define MTL_MEM_SS_INFO_GLOBAL _MMIO(0x45700)
|
||||
#define MTL_N_OF_ENABLED_QGV_POINTS_MASK REG_GENMASK(11, 8)
|
||||
#define MTL_N_OF_POPULATED_CH_MASK REG_GENMASK(7, 4)
|
||||
#define MTL_DDR_TYPE_MASK REG_GENMASK(3, 0)
|
||||
|
||||
#define MTL_MEM_SS_INFO_QGV_POINT_LOW(point) _MMIO(0x45710 + (point) * 2)
|
||||
#define MTL_TRCD_MASK REG_GENMASK(31, 24)
|
||||
#define MTL_TRP_MASK REG_GENMASK(23, 16)
|
||||
#define MTL_DCLK_MASK REG_GENMASK(15, 0)
|
||||
|
||||
#define MTL_MEM_SS_INFO_QGV_POINT_HIGH(point) _MMIO(0x45714 + (point) * 2)
|
||||
#define MTL_TRAS_MASK REG_GENMASK(16, 8)
|
||||
#define MTL_TRDPRE_MASK REG_GENMASK(7, 0)
|
||||
|
||||
#endif /* _I915_REG_H_ */
|
||||
|
@ -241,8 +241,6 @@ void __i915_sw_fence_init(struct i915_sw_fence *fence,
|
||||
const char *name,
|
||||
struct lock_class_key *key)
|
||||
{
|
||||
BUG_ON(!fn);
|
||||
|
||||
__init_waitqueue_head(&fence->wait, name, key);
|
||||
fence->fn = fn;
|
||||
#ifdef CONFIG_DRM_I915_SW_FENCE_CHECK_DAG
|
||||
|
@ -48,11 +48,15 @@ void __i915_sw_fence_init(struct i915_sw_fence *fence,
|
||||
do { \
|
||||
static struct lock_class_key __key; \
|
||||
\
|
||||
BUILD_BUG_ON((fn) == NULL); \
|
||||
__i915_sw_fence_init((fence), (fn), #fence, &__key); \
|
||||
} while (0)
|
||||
#else
|
||||
#define i915_sw_fence_init(fence, fn) \
|
||||
__i915_sw_fence_init((fence), (fn), NULL, NULL)
|
||||
do { \
|
||||
BUILD_BUG_ON((fn) == NULL); \
|
||||
__i915_sw_fence_init((fence), (fn), NULL, NULL); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
void i915_sw_fence_reinit(struct i915_sw_fence *fence);
|
||||
|
@ -92,21 +92,29 @@ void intel_device_info_print(const struct intel_device_info *info,
|
||||
const struct intel_runtime_info *runtime,
|
||||
struct drm_printer *p)
|
||||
{
|
||||
if (runtime->graphics.rel)
|
||||
drm_printf(p, "graphics version: %u.%02u\n", runtime->graphics.ver,
|
||||
runtime->graphics.rel);
|
||||
if (runtime->graphics.ip.rel)
|
||||
drm_printf(p, "graphics version: %u.%02u\n",
|
||||
runtime->graphics.ip.ver,
|
||||
runtime->graphics.ip.rel);
|
||||
else
|
||||
drm_printf(p, "graphics version: %u\n", runtime->graphics.ver);
|
||||
drm_printf(p, "graphics version: %u\n",
|
||||
runtime->graphics.ip.ver);
|
||||
|
||||
if (info->media.rel)
|
||||
drm_printf(p, "media version: %u.%02u\n", info->media.ver, info->media.rel);
|
||||
if (runtime->media.ip.rel)
|
||||
drm_printf(p, "media version: %u.%02u\n",
|
||||
runtime->media.ip.ver,
|
||||
runtime->media.ip.rel);
|
||||
else
|
||||
drm_printf(p, "media version: %u\n", info->media.ver);
|
||||
drm_printf(p, "media version: %u\n",
|
||||
runtime->media.ip.ver);
|
||||
|
||||
if (info->display.rel)
|
||||
drm_printf(p, "display version: %u.%02u\n", info->display.ver, info->display.rel);
|
||||
if (runtime->display.ip.rel)
|
||||
drm_printf(p, "display version: %u.%02u\n",
|
||||
runtime->display.ip.ver,
|
||||
runtime->display.ip.rel);
|
||||
else
|
||||
drm_printf(p, "display version: %u\n", info->display.ver);
|
||||
drm_printf(p, "display version: %u\n",
|
||||
runtime->display.ip.ver);
|
||||
|
||||
drm_printf(p, "gt: %d\n", info->gt);
|
||||
drm_printf(p, "memory-regions: %x\n", runtime->memory_regions);
|
||||
|
@ -201,7 +201,15 @@ struct ip_version {
|
||||
};
|
||||
|
||||
struct intel_runtime_info {
|
||||
struct ip_version graphics;
|
||||
struct {
|
||||
struct ip_version ip;
|
||||
} graphics;
|
||||
struct {
|
||||
struct ip_version ip;
|
||||
} media;
|
||||
struct {
|
||||
struct ip_version ip;
|
||||
} display;
|
||||
|
||||
/*
|
||||
* Platform mask is used for optimizing or-ed IS_PLATFORM calls into
|
||||
@ -247,8 +255,6 @@ struct intel_runtime_info {
|
||||
};
|
||||
|
||||
struct intel_device_info {
|
||||
struct ip_version media;
|
||||
|
||||
enum intel_platform platform;
|
||||
|
||||
unsigned int dma_mask_size; /* available DMA address bits */
|
||||
@ -262,9 +268,6 @@ struct intel_device_info {
|
||||
#undef DEFINE_FLAG
|
||||
|
||||
struct {
|
||||
u8 ver;
|
||||
u8 rel;
|
||||
|
||||
u8 abox_mask;
|
||||
|
||||
struct {
|
||||
|
@ -466,6 +466,43 @@ static int gen12_get_dram_info(struct drm_i915_private *i915)
|
||||
return icl_pcode_read_mem_global_info(i915);
|
||||
}
|
||||
|
||||
static int xelpdp_get_dram_info(struct drm_i915_private *i915)
|
||||
{
|
||||
u32 val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_GLOBAL);
|
||||
struct dram_info *dram_info = &i915->dram_info;
|
||||
|
||||
val = REG_FIELD_GET(MTL_DDR_TYPE_MASK, val);
|
||||
switch (val) {
|
||||
case 0:
|
||||
dram_info->type = INTEL_DRAM_DDR4;
|
||||
break;
|
||||
case 1:
|
||||
dram_info->type = INTEL_DRAM_DDR5;
|
||||
break;
|
||||
case 2:
|
||||
dram_info->type = INTEL_DRAM_LPDDR5;
|
||||
break;
|
||||
case 3:
|
||||
dram_info->type = INTEL_DRAM_LPDDR4;
|
||||
break;
|
||||
case 4:
|
||||
dram_info->type = INTEL_DRAM_DDR3;
|
||||
break;
|
||||
case 5:
|
||||
dram_info->type = INTEL_DRAM_LPDDR3;
|
||||
break;
|
||||
default:
|
||||
MISSING_CASE(val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dram_info->num_channels = REG_FIELD_GET(MTL_N_OF_POPULATED_CH_MASK, val);
|
||||
dram_info->num_qgv_points = REG_FIELD_GET(MTL_N_OF_ENABLED_QGV_POINTS_MASK, val);
|
||||
/* PSF GV points not supported in D14+ */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void intel_dram_detect(struct drm_i915_private *i915)
|
||||
{
|
||||
struct dram_info *dram_info = &i915->dram_info;
|
||||
@ -480,7 +517,9 @@ void intel_dram_detect(struct drm_i915_private *i915)
|
||||
*/
|
||||
dram_info->wm_lv_0_adjust_needed = !IS_GEN9_LP(i915);
|
||||
|
||||
if (GRAPHICS_VER(i915) >= 12)
|
||||
if (DISPLAY_VER(i915) >= 14)
|
||||
ret = xelpdp_get_dram_info(i915);
|
||||
else if (GRAPHICS_VER(i915) >= 12)
|
||||
ret = gen12_get_dram_info(i915);
|
||||
else if (GRAPHICS_VER(i915) >= 11)
|
||||
ret = gen11_get_dram_info(i915);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,22 +8,9 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "display/intel_display.h"
|
||||
#include "display/intel_global_state.h"
|
||||
|
||||
#include "i915_drv.h"
|
||||
|
||||
struct drm_device;
|
||||
struct drm_i915_private;
|
||||
struct i915_request;
|
||||
struct intel_atomic_state;
|
||||
struct intel_bw_state;
|
||||
struct intel_crtc;
|
||||
struct intel_crtc_state;
|
||||
struct intel_plane;
|
||||
struct skl_ddb_entry;
|
||||
struct skl_pipe_wm;
|
||||
struct skl_wm_level;
|
||||
struct intel_plane_state;
|
||||
|
||||
void intel_init_clock_gating(struct drm_i915_private *dev_priv);
|
||||
void intel_suspend_hw(struct drm_i915_private *dev_priv);
|
||||
@ -34,56 +21,14 @@ void intel_pm_setup(struct drm_i915_private *dev_priv);
|
||||
void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv);
|
||||
void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv);
|
||||
void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv);
|
||||
void skl_wm_get_hw_state(struct drm_i915_private *dev_priv);
|
||||
void intel_wm_state_verify(struct intel_crtc *crtc,
|
||||
struct intel_crtc_state *new_crtc_state);
|
||||
u8 intel_enabled_dbuf_slices_mask(struct drm_i915_private *dev_priv);
|
||||
void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv);
|
||||
u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *dev_priv,
|
||||
const struct skl_ddb_entry *entry);
|
||||
void g4x_wm_sanitize(struct drm_i915_private *dev_priv);
|
||||
void vlv_wm_sanitize(struct drm_i915_private *dev_priv);
|
||||
void skl_wm_sanitize(struct drm_i915_private *dev_priv);
|
||||
bool intel_can_enable_sagv(struct drm_i915_private *dev_priv,
|
||||
const struct intel_bw_state *bw_state);
|
||||
void intel_sagv_pre_plane_update(struct intel_atomic_state *state);
|
||||
void intel_sagv_post_plane_update(struct intel_atomic_state *state);
|
||||
bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
|
||||
const struct skl_ddb_entry *entries,
|
||||
int num_entries, int ignore_idx);
|
||||
void skl_write_plane_wm(struct intel_plane *plane,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void skl_write_cursor_wm(struct intel_plane *plane,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
bool ilk_disable_lp_wm(struct drm_i915_private *dev_priv);
|
||||
void intel_init_ipc(struct drm_i915_private *dev_priv);
|
||||
void intel_enable_ipc(struct drm_i915_private *dev_priv);
|
||||
bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state);
|
||||
void intel_print_wm_latency(struct drm_i915_private *dev_priv,
|
||||
const char *name, const u16 wm[]);
|
||||
|
||||
bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable);
|
||||
|
||||
struct intel_dbuf_state {
|
||||
struct intel_global_state base;
|
||||
|
||||
struct skl_ddb_entry ddb[I915_MAX_PIPES];
|
||||
unsigned int weight[I915_MAX_PIPES];
|
||||
u8 slices[I915_MAX_PIPES];
|
||||
u8 enabled_slices;
|
||||
u8 active_pipes;
|
||||
bool joined_mbus;
|
||||
};
|
||||
|
||||
struct intel_dbuf_state *
|
||||
intel_atomic_get_dbuf_state(struct intel_atomic_state *state);
|
||||
|
||||
#define to_intel_dbuf_state(x) container_of((x), struct intel_dbuf_state, base)
|
||||
#define intel_atomic_get_old_dbuf_state(state) \
|
||||
to_intel_dbuf_state(intel_atomic_get_old_global_obj_state(state, &to_i915(state->base.dev)->dbuf.obj))
|
||||
#define intel_atomic_get_new_dbuf_state(state) \
|
||||
to_intel_dbuf_state(intel_atomic_get_new_global_obj_state(state, &to_i915(state->base.dev)->dbuf.obj))
|
||||
|
||||
int intel_dbuf_init(struct drm_i915_private *dev_priv);
|
||||
void intel_dbuf_pre_plane_update(struct intel_atomic_state *state);
|
||||
void intel_dbuf_post_plane_update(struct intel_atomic_state *state);
|
||||
void intel_mbus_dbox_update(struct intel_atomic_state *state);
|
||||
|
||||
#endif /* __INTEL_PM_H__ */
|
||||
|
@ -173,7 +173,7 @@ struct drm_i915_private *mock_gem_device(void)
|
||||
/* Using the global GTT may ask questions about KMS users, so prepare */
|
||||
drm_mode_config_init(&i915->drm);
|
||||
|
||||
RUNTIME_INFO(i915)->graphics.ver = -1;
|
||||
RUNTIME_INFO(i915)->graphics.ip.ver = -1;
|
||||
|
||||
RUNTIME_INFO(i915)->page_sizes =
|
||||
I915_GTT_PAGE_SIZE_4K |
|
||||
|
Loading…
x
Reference in New Issue
Block a user