Merge tag 'drm-intel-next-fixes-2018-10-18' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
- Fix GPU hang on MacBook2,1 when booting in EFI mode (Bugzilla #105637) - Fix garbled console on Y tiled BIOS framebuffer configs (Bugzilla #108264) - Fix black screen on certain eDP panels eg. Dell XPS 9350 (Bugzilla #107489 and #105338) - MST fixes that Rodrigo dropped from drm-intel-fixes and bunch of Icelake fixes - Then assorted proactive code fixes caught by CI or developers Signed-off-by: Dave Airlie <airlied@redhat.com> From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20181018165725.GA2281@jlahtine-desk.ger.corp.intel.com
This commit is contained in:
commit
f2bfc71aee
|
@ -4189,7 +4189,7 @@ i915_drop_caches_set(void *data, u64 val)
|
|||
I915_WAIT_LOCKED,
|
||||
MAX_SCHEDULE_TIMEOUT);
|
||||
|
||||
if (val & DROP_RESET_SEQNO) {
|
||||
if (ret == 0 && val & DROP_RESET_SEQNO) {
|
||||
intel_runtime_pm_get(i915);
|
||||
ret = i915_gem_set_global_seqno(&i915->drm, 1);
|
||||
intel_runtime_pm_put(i915);
|
||||
|
|
|
@ -1127,11 +1127,7 @@ i915_gem_shmem_pread(struct drm_i915_gem_object *obj,
|
|||
offset = offset_in_page(args->offset);
|
||||
for (idx = args->offset >> PAGE_SHIFT; remain; idx++) {
|
||||
struct page *page = i915_gem_object_get_page(obj, idx);
|
||||
int length;
|
||||
|
||||
length = remain;
|
||||
if (offset + length > PAGE_SIZE)
|
||||
length = PAGE_SIZE - offset;
|
||||
unsigned int length = min_t(u64, remain, PAGE_SIZE - offset);
|
||||
|
||||
ret = shmem_pread(page, offset, length, user_data,
|
||||
page_to_phys(page) & obj_do_bit17_swizzling,
|
||||
|
@ -1575,11 +1571,7 @@ i915_gem_shmem_pwrite(struct drm_i915_gem_object *obj,
|
|||
offset = offset_in_page(args->offset);
|
||||
for (idx = args->offset >> PAGE_SHIFT; remain; idx++) {
|
||||
struct page *page = i915_gem_object_get_page(obj, idx);
|
||||
int length;
|
||||
|
||||
length = remain;
|
||||
if (offset + length > PAGE_SIZE)
|
||||
length = PAGE_SIZE - offset;
|
||||
unsigned int length = min_t(u64, remain, PAGE_SIZE - offset);
|
||||
|
||||
ret = shmem_pwrite(page, offset, length, user_data,
|
||||
page_to_phys(page) & obj_do_bit17_swizzling,
|
||||
|
|
|
@ -9339,6 +9339,9 @@ enum skl_power_gate {
|
|||
#define DPCLKA_CFGCR0_ICL _MMIO(0x164280)
|
||||
#define DPCLKA_CFGCR0_DDI_CLK_OFF(port) (1 << ((port) == PORT_F ? 23 : \
|
||||
(port) + 10))
|
||||
#define ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(port) (1 << ((port) + 10))
|
||||
#define ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port) (1 << ((tc_port) == PORT_TC4 ? \
|
||||
21 : (tc_port) + 12))
|
||||
#define DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port) ((port) == PORT_F ? 21 : \
|
||||
(port) * 2)
|
||||
#define DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port) (3 << DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port))
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
|
||||
#define I915_CSR_ICL "i915/icl_dmc_ver1_07.bin"
|
||||
MODULE_FIRMWARE(I915_CSR_ICL);
|
||||
#define ICL_CSR_VERSION_REQUIRED CSR_VERSION(1, 7)
|
||||
|
||||
#define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin"
|
||||
|
|
|
@ -916,7 +916,7 @@ static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port por
|
|||
level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
|
||||
|
||||
if (IS_ICELAKE(dev_priv)) {
|
||||
if (port == PORT_A || port == PORT_B)
|
||||
if (intel_port_is_combophy(dev_priv, port))
|
||||
icl_get_combo_buf_trans(dev_priv, port,
|
||||
INTEL_OUTPUT_HDMI, &n_entries);
|
||||
else
|
||||
|
@ -1535,7 +1535,7 @@ static void icl_ddi_clock_get(struct intel_encoder *encoder,
|
|||
uint32_t pll_id;
|
||||
|
||||
pll_id = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll);
|
||||
if (port == PORT_A || port == PORT_B) {
|
||||
if (intel_port_is_combophy(dev_priv, port)) {
|
||||
if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI))
|
||||
link_clock = cnl_calc_wrpll_link(dev_priv, pll_id);
|
||||
else
|
||||
|
@ -2235,7 +2235,7 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
|
|||
int n_entries;
|
||||
|
||||
if (IS_ICELAKE(dev_priv)) {
|
||||
if (port == PORT_A || port == PORT_B)
|
||||
if (intel_port_is_combophy(dev_priv, port))
|
||||
icl_get_combo_buf_trans(dev_priv, port, encoder->type,
|
||||
&n_entries);
|
||||
else
|
||||
|
@ -2669,9 +2669,10 @@ static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
|
|||
u32 level,
|
||||
enum intel_output_type type)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
enum port port = encoder->port;
|
||||
|
||||
if (port == PORT_A || port == PORT_B)
|
||||
if (intel_port_is_combophy(dev_priv, port))
|
||||
icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
|
||||
else
|
||||
icl_mg_phy_ddi_vswing_sequence(encoder, link_clock, level);
|
||||
|
@ -2732,6 +2733,21 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
|
|||
return DDI_BUF_TRANS_SELECT(level);
|
||||
}
|
||||
|
||||
static inline
|
||||
uint32_t icl_dpclka_cfgcr0_clk_off(struct drm_i915_private *dev_priv,
|
||||
enum port port)
|
||||
{
|
||||
if (intel_port_is_combophy(dev_priv, port)) {
|
||||
return ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(port);
|
||||
} else if (intel_port_is_tc(dev_priv, port)) {
|
||||
enum tc_port tc_port = intel_port_to_tc(dev_priv, port);
|
||||
|
||||
return ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void icl_map_plls_to_ports(struct drm_crtc *crtc,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
struct drm_atomic_state *old_state)
|
||||
|
@ -2755,16 +2771,16 @@ void icl_map_plls_to_ports(struct drm_crtc *crtc,
|
|||
mutex_lock(&dev_priv->dpll_lock);
|
||||
|
||||
val = I915_READ(DPCLKA_CFGCR0_ICL);
|
||||
WARN_ON((val & DPCLKA_CFGCR0_DDI_CLK_OFF(port)) == 0);
|
||||
WARN_ON((val & icl_dpclka_cfgcr0_clk_off(dev_priv, port)) == 0);
|
||||
|
||||
if (port == PORT_A || port == PORT_B) {
|
||||
if (intel_port_is_combophy(dev_priv, port)) {
|
||||
val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
|
||||
val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port);
|
||||
I915_WRITE(DPCLKA_CFGCR0_ICL, val);
|
||||
POSTING_READ(DPCLKA_CFGCR0_ICL);
|
||||
}
|
||||
|
||||
val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port);
|
||||
val &= ~icl_dpclka_cfgcr0_clk_off(dev_priv, port);
|
||||
I915_WRITE(DPCLKA_CFGCR0_ICL, val);
|
||||
|
||||
mutex_unlock(&dev_priv->dpll_lock);
|
||||
|
@ -2792,7 +2808,7 @@ void icl_unmap_plls_to_ports(struct drm_crtc *crtc,
|
|||
mutex_lock(&dev_priv->dpll_lock);
|
||||
I915_WRITE(DPCLKA_CFGCR0_ICL,
|
||||
I915_READ(DPCLKA_CFGCR0_ICL) |
|
||||
DPCLKA_CFGCR0_DDI_CLK_OFF(port));
|
||||
icl_dpclka_cfgcr0_clk_off(dev_priv, port));
|
||||
mutex_unlock(&dev_priv->dpll_lock);
|
||||
}
|
||||
}
|
||||
|
@ -2810,7 +2826,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
|
|||
mutex_lock(&dev_priv->dpll_lock);
|
||||
|
||||
if (IS_ICELAKE(dev_priv)) {
|
||||
if (port >= PORT_C)
|
||||
if (!intel_port_is_combophy(dev_priv, port))
|
||||
I915_WRITE(DDI_CLK_SEL(port),
|
||||
icl_pll_to_ddi_pll_sel(encoder, pll));
|
||||
} else if (IS_CANNONLAKE(dev_priv)) {
|
||||
|
@ -2852,7 +2868,7 @@ static void intel_ddi_clk_disable(struct intel_encoder *encoder)
|
|||
enum port port = encoder->port;
|
||||
|
||||
if (IS_ICELAKE(dev_priv)) {
|
||||
if (port >= PORT_C)
|
||||
if (!intel_port_is_combophy(dev_priv, port))
|
||||
I915_WRITE(DDI_CLK_SEL(port), DDI_CLK_SEL_NONE);
|
||||
} else if (IS_CANNONLAKE(dev_priv)) {
|
||||
I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) |
|
||||
|
|
|
@ -2722,6 +2722,17 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
|
|||
if (size_aligned * 2 > dev_priv->stolen_usable_size)
|
||||
return false;
|
||||
|
||||
switch (fb->modifier) {
|
||||
case DRM_FORMAT_MOD_LINEAR:
|
||||
case I915_FORMAT_MOD_X_TILED:
|
||||
case I915_FORMAT_MOD_Y_TILED:
|
||||
break;
|
||||
default:
|
||||
DRM_DEBUG_DRIVER("Unsupported modifier for initial FB: 0x%llx\n",
|
||||
fb->modifier);
|
||||
return false;
|
||||
}
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
obj = i915_gem_object_create_stolen_for_preallocated(dev_priv,
|
||||
base_aligned,
|
||||
|
@ -2731,8 +2742,17 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
|
|||
if (!obj)
|
||||
return false;
|
||||
|
||||
if (plane_config->tiling == I915_TILING_X)
|
||||
obj->tiling_and_stride = fb->pitches[0] | I915_TILING_X;
|
||||
switch (plane_config->tiling) {
|
||||
case I915_TILING_NONE:
|
||||
break;
|
||||
case I915_TILING_X:
|
||||
case I915_TILING_Y:
|
||||
obj->tiling_and_stride = fb->pitches[0] | plane_config->tiling;
|
||||
break;
|
||||
default:
|
||||
MISSING_CASE(plane_config->tiling);
|
||||
return false;
|
||||
}
|
||||
|
||||
mode_cmd.pixel_format = fb->format->format;
|
||||
mode_cmd.width = fb->width;
|
||||
|
@ -2764,20 +2784,33 @@ intel_set_plane_visible(struct intel_crtc_state *crtc_state,
|
|||
|
||||
plane_state->base.visible = visible;
|
||||
|
||||
/* FIXME pre-g4x don't work like this */
|
||||
if (visible) {
|
||||
if (visible)
|
||||
crtc_state->base.plane_mask |= drm_plane_mask(&plane->base);
|
||||
crtc_state->active_planes |= BIT(plane->id);
|
||||
} else {
|
||||
else
|
||||
crtc_state->base.plane_mask &= ~drm_plane_mask(&plane->base);
|
||||
crtc_state->active_planes &= ~BIT(plane->id);
|
||||
}
|
||||
|
||||
DRM_DEBUG_KMS("%s active planes 0x%x\n",
|
||||
crtc_state->base.crtc->name,
|
||||
crtc_state->active_planes);
|
||||
}
|
||||
|
||||
static void fixup_active_planes(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
|
||||
struct drm_plane *plane;
|
||||
|
||||
/*
|
||||
* Active_planes aliases if multiple "primary" or cursor planes
|
||||
* have been used on the same (or wrong) pipe. plane_mask uses
|
||||
* unique ids, hence we can use that to reconstruct active_planes.
|
||||
*/
|
||||
crtc_state->active_planes = 0;
|
||||
|
||||
drm_for_each_plane_mask(plane, &dev_priv->drm,
|
||||
crtc_state->base.plane_mask)
|
||||
crtc_state->active_planes |= BIT(to_intel_plane(plane)->id);
|
||||
}
|
||||
|
||||
static void intel_plane_disable_noatomic(struct intel_crtc *crtc,
|
||||
struct intel_plane *plane)
|
||||
{
|
||||
|
@ -2787,6 +2820,7 @@ static void intel_plane_disable_noatomic(struct intel_crtc *crtc,
|
|||
to_intel_plane_state(plane->base.state);
|
||||
|
||||
intel_set_plane_visible(crtc_state, plane_state, false);
|
||||
fixup_active_planes(crtc_state);
|
||||
|
||||
if (plane->id == PLANE_PRIMARY)
|
||||
intel_pre_disable_primary_noatomic(&crtc->base);
|
||||
|
@ -2805,7 +2839,6 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
|
|||
struct drm_i915_gem_object *obj;
|
||||
struct drm_plane *primary = intel_crtc->base.primary;
|
||||
struct drm_plane_state *plane_state = primary->state;
|
||||
struct drm_crtc_state *crtc_state = intel_crtc->base.state;
|
||||
struct intel_plane *intel_plane = to_intel_plane(primary);
|
||||
struct intel_plane_state *intel_state =
|
||||
to_intel_plane_state(plane_state);
|
||||
|
@ -2900,10 +2933,6 @@ valid_fb:
|
|||
plane_state->fb = fb;
|
||||
plane_state->crtc = &intel_crtc->base;
|
||||
|
||||
intel_set_plane_visible(to_intel_crtc_state(crtc_state),
|
||||
to_intel_plane_state(plane_state),
|
||||
true);
|
||||
|
||||
atomic_or(to_intel_plane(primary)->frontbuffer_bit,
|
||||
&obj->frontbuffer_bits);
|
||||
}
|
||||
|
@ -3151,6 +3180,10 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
|
|||
plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
|
||||
plane_state->color_plane[1].stride = intel_fb_pitch(fb, 1, rotation);
|
||||
|
||||
ret = intel_plane_check_stride(plane_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!plane_state->base.visible)
|
||||
return 0;
|
||||
|
||||
|
@ -3286,10 +3319,15 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
|
|||
int src_x = plane_state->base.src.x1 >> 16;
|
||||
int src_y = plane_state->base.src.y1 >> 16;
|
||||
u32 offset;
|
||||
int ret;
|
||||
|
||||
intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation);
|
||||
plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
|
||||
|
||||
ret = intel_plane_check_stride(plane_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
|
||||
|
||||
if (INTEL_GEN(dev_priv) >= 4)
|
||||
|
@ -5923,6 +5961,17 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
|
|||
I915_WRITE(BCLRPAT(crtc->pipe), 0);
|
||||
}
|
||||
|
||||
bool intel_port_is_combophy(struct drm_i915_private *dev_priv, enum port port)
|
||||
{
|
||||
if (port == PORT_NONE)
|
||||
return false;
|
||||
|
||||
if (IS_ICELAKE(dev_priv))
|
||||
return port <= PORT_B;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool intel_port_is_tc(struct drm_i915_private *dev_priv, enum port port)
|
||||
{
|
||||
if (IS_ICELAKE(dev_priv))
|
||||
|
@ -8847,6 +8896,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
|
|||
fb->modifier = I915_FORMAT_MOD_X_TILED;
|
||||
break;
|
||||
case PLANE_CTL_TILED_Y:
|
||||
plane_config->tiling = I915_TILING_Y;
|
||||
if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
|
||||
fb->modifier = I915_FORMAT_MOD_Y_TILED_CCS;
|
||||
else
|
||||
|
@ -9683,10 +9733,15 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
|
|||
unsigned int rotation = plane_state->base.rotation;
|
||||
int src_x, src_y;
|
||||
u32 offset;
|
||||
int ret;
|
||||
|
||||
intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation);
|
||||
plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
|
||||
|
||||
ret = intel_plane_check_stride(plane_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
src_x = plane_state->base.src_x >> 16;
|
||||
src_y = plane_state->base.src_y >> 16;
|
||||
|
||||
|
@ -15436,17 +15491,6 @@ void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|||
POSTING_READ(DPLL(pipe));
|
||||
}
|
||||
|
||||
static bool intel_plane_mapping_ok(struct intel_crtc *crtc,
|
||||
struct intel_plane *plane)
|
||||
{
|
||||
enum pipe pipe;
|
||||
|
||||
if (!plane->get_hw_state(plane, &pipe))
|
||||
return true;
|
||||
|
||||
return pipe == crtc->pipe;
|
||||
}
|
||||
|
||||
static void
|
||||
intel_sanitize_plane_mapping(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
|
@ -15458,13 +15502,20 @@ intel_sanitize_plane_mapping(struct drm_i915_private *dev_priv)
|
|||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
struct intel_plane *plane =
|
||||
to_intel_plane(crtc->base.primary);
|
||||
struct intel_crtc *plane_crtc;
|
||||
enum pipe pipe;
|
||||
|
||||
if (intel_plane_mapping_ok(crtc, plane))
|
||||
if (!plane->get_hw_state(plane, &pipe))
|
||||
continue;
|
||||
|
||||
if (pipe == crtc->pipe)
|
||||
continue;
|
||||
|
||||
DRM_DEBUG_KMS("%s attached to the wrong pipe, disabling plane\n",
|
||||
plane->base.name);
|
||||
intel_plane_disable_noatomic(crtc, plane);
|
||||
|
||||
plane_crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
|
||||
intel_plane_disable_noatomic(plane_crtc, plane);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15512,13 +15563,9 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
|
|||
I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
|
||||
}
|
||||
|
||||
/* restore vblank interrupts to correct state */
|
||||
drm_crtc_vblank_reset(&crtc->base);
|
||||
if (crtc->active) {
|
||||
struct intel_plane *plane;
|
||||
|
||||
drm_crtc_vblank_on(&crtc->base);
|
||||
|
||||
/* Disable everything but the primary plane */
|
||||
for_each_intel_plane_on_crtc(dev, crtc, plane) {
|
||||
const struct intel_plane_state *plane_state =
|
||||
|
@ -15636,23 +15683,32 @@ void i915_redisable_vga(struct drm_i915_private *dev_priv)
|
|||
}
|
||||
|
||||
/* FIXME read out full plane state for all planes */
|
||||
static void readout_plane_state(struct intel_crtc *crtc)
|
||||
static void readout_plane_state(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
to_intel_crtc_state(crtc->base.state);
|
||||
struct intel_plane *plane;
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
|
||||
for_each_intel_plane(&dev_priv->drm, plane) {
|
||||
struct intel_plane_state *plane_state =
|
||||
to_intel_plane_state(plane->base.state);
|
||||
enum pipe pipe;
|
||||
struct intel_crtc_state *crtc_state;
|
||||
enum pipe pipe = PIPE_A;
|
||||
bool visible;
|
||||
|
||||
visible = plane->get_hw_state(plane, &pipe);
|
||||
|
||||
crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
|
||||
crtc_state = to_intel_crtc_state(crtc->base.state);
|
||||
|
||||
intel_set_plane_visible(crtc_state, plane_state, visible);
|
||||
}
|
||||
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
struct intel_crtc_state *crtc_state =
|
||||
to_intel_crtc_state(crtc->base.state);
|
||||
|
||||
fixup_active_planes(crtc_state);
|
||||
}
|
||||
}
|
||||
|
||||
static void intel_modeset_readout_hw_state(struct drm_device *dev)
|
||||
|
@ -15684,13 +15740,13 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
|
|||
if (crtc_state->base.active)
|
||||
dev_priv->active_crtcs |= 1 << crtc->pipe;
|
||||
|
||||
readout_plane_state(crtc);
|
||||
|
||||
DRM_DEBUG_KMS("[CRTC:%d:%s] hw state readout: %s\n",
|
||||
crtc->base.base.id, crtc->base.name,
|
||||
enableddisabled(crtc_state->base.active));
|
||||
}
|
||||
|
||||
readout_plane_state(dev_priv);
|
||||
|
||||
for (i = 0; i < dev_priv->num_shared_dpll; i++) {
|
||||
struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
|
||||
|
||||
|
@ -15860,7 +15916,6 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
|
|||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
enum pipe pipe;
|
||||
struct intel_crtc *crtc;
|
||||
struct intel_encoder *encoder;
|
||||
int i;
|
||||
|
@ -15873,15 +15928,23 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
|
|||
/* HW state is read out, now we need to sanitize this mess. */
|
||||
get_encoder_power_domains(dev_priv);
|
||||
|
||||
intel_sanitize_plane_mapping(dev_priv);
|
||||
/*
|
||||
* intel_sanitize_plane_mapping() may need to do vblank
|
||||
* waits, so we need vblank interrupts restored beforehand.
|
||||
*/
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
drm_crtc_vblank_reset(&crtc->base);
|
||||
|
||||
for_each_intel_encoder(dev, encoder) {
|
||||
intel_sanitize_encoder(encoder);
|
||||
if (crtc->active)
|
||||
drm_crtc_vblank_on(&crtc->base);
|
||||
}
|
||||
|
||||
for_each_pipe(dev_priv, pipe) {
|
||||
crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
|
||||
intel_sanitize_plane_mapping(dev_priv);
|
||||
|
||||
for_each_intel_encoder(dev, encoder)
|
||||
intel_sanitize_encoder(encoder);
|
||||
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
intel_sanitize_crtc(crtc, ctx);
|
||||
intel_dump_pipe_config(crtc, crtc->config,
|
||||
"[setup_hw_state]");
|
||||
|
|
|
@ -557,6 +557,22 @@ static bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp,
|
||||
int link_rate,
|
||||
uint8_t lane_count)
|
||||
{
|
||||
const struct drm_display_mode *fixed_mode =
|
||||
intel_dp->attached_connector->panel.fixed_mode;
|
||||
int mode_rate, max_rate;
|
||||
|
||||
mode_rate = intel_dp_link_required(fixed_mode->clock, 18);
|
||||
max_rate = intel_dp_max_data_rate(link_rate, lane_count);
|
||||
if (mode_rate > max_rate)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
|
||||
int link_rate, uint8_t lane_count)
|
||||
{
|
||||
|
@ -566,9 +582,23 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
|
|||
intel_dp->num_common_rates,
|
||||
link_rate);
|
||||
if (index > 0) {
|
||||
if (intel_dp_is_edp(intel_dp) &&
|
||||
!intel_dp_can_link_train_fallback_for_edp(intel_dp,
|
||||
intel_dp->common_rates[index - 1],
|
||||
lane_count)) {
|
||||
DRM_DEBUG_KMS("Retrying Link training for eDP with same parameters\n");
|
||||
return 0;
|
||||
}
|
||||
intel_dp->max_link_rate = intel_dp->common_rates[index - 1];
|
||||
intel_dp->max_link_lane_count = lane_count;
|
||||
} else if (lane_count > 1) {
|
||||
if (intel_dp_is_edp(intel_dp) &&
|
||||
!intel_dp_can_link_train_fallback_for_edp(intel_dp,
|
||||
intel_dp_max_common_rate(intel_dp),
|
||||
lane_count >> 1)) {
|
||||
DRM_DEBUG_KMS("Retrying Link training for eDP with same parameters\n");
|
||||
return 0;
|
||||
}
|
||||
intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
|
||||
intel_dp->max_link_lane_count = lane_count >> 1;
|
||||
} else {
|
||||
|
@ -3704,7 +3734,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
|
|||
uint32_t signal_levels, mask = 0;
|
||||
uint8_t train_set = intel_dp->train_set[0];
|
||||
|
||||
if (IS_GEN9_LP(dev_priv) || IS_CANNONLAKE(dev_priv)) {
|
||||
if (IS_GEN9_LP(dev_priv) || INTEL_GEN(dev_priv) >= 10) {
|
||||
signal_levels = bxt_signal_levels(intel_dp);
|
||||
} else if (HAS_DDI(dev_priv)) {
|
||||
signal_levels = ddi_signal_levels(intel_dp);
|
||||
|
|
|
@ -367,22 +367,14 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
|
|||
return;
|
||||
|
||||
failure_handling:
|
||||
/* Dont fallback and prune modes if its eDP */
|
||||
if (!intel_dp_is_edp(intel_dp)) {
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
|
||||
intel_connector->base.base.id,
|
||||
intel_connector->base.name,
|
||||
intel_dp->link_rate, intel_dp->lane_count);
|
||||
if (!intel_dp_get_link_train_fallback_values(intel_dp,
|
||||
intel_dp->link_rate,
|
||||
intel_dp->lane_count))
|
||||
/* Schedule a Hotplug Uevent to userspace to start modeset */
|
||||
schedule_work(&intel_connector->modeset_retry_work);
|
||||
} else {
|
||||
DRM_ERROR("[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
|
||||
intel_connector->base.base.id,
|
||||
intel_connector->base.name,
|
||||
intel_dp->link_rate, intel_dp->lane_count);
|
||||
}
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
|
||||
intel_connector->base.base.id,
|
||||
intel_connector->base.name,
|
||||
intel_dp->link_rate, intel_dp->lane_count);
|
||||
if (!intel_dp_get_link_train_fallback_values(intel_dp,
|
||||
intel_dp->link_rate,
|
||||
intel_dp->lane_count))
|
||||
/* Schedule a Hotplug Uevent to userspace to start modeset */
|
||||
schedule_work(&intel_connector->modeset_retry_work);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -38,11 +38,11 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
|
|||
struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
|
||||
struct intel_digital_port *intel_dig_port = intel_mst->primary;
|
||||
struct intel_dp *intel_dp = &intel_dig_port->dp;
|
||||
struct intel_connector *connector =
|
||||
to_intel_connector(conn_state->connector);
|
||||
struct drm_connector *connector = conn_state->connector;
|
||||
void *port = to_intel_connector(connector)->port;
|
||||
struct drm_atomic_state *state = pipe_config->base.state;
|
||||
int bpp;
|
||||
int lane_count, slots;
|
||||
int lane_count, slots = 0;
|
||||
const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
|
||||
int mst_pbn;
|
||||
bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
|
||||
|
@ -70,17 +70,23 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
|
|||
|
||||
pipe_config->port_clock = intel_dp_max_link_rate(intel_dp);
|
||||
|
||||
if (drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, connector->port))
|
||||
if (drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, port))
|
||||
pipe_config->has_audio = true;
|
||||
|
||||
mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp);
|
||||
pipe_config->pbn = mst_pbn;
|
||||
|
||||
slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr,
|
||||
connector->port, mst_pbn);
|
||||
if (slots < 0) {
|
||||
DRM_DEBUG_KMS("failed finding vcpi slots:%d\n", slots);
|
||||
return false;
|
||||
/* Zombie connectors can't have VCPI slots */
|
||||
if (READ_ONCE(connector->registered)) {
|
||||
slots = drm_dp_atomic_find_vcpi_slots(state,
|
||||
&intel_dp->mst_mgr,
|
||||
port,
|
||||
mst_pbn);
|
||||
if (slots < 0) {
|
||||
DRM_DEBUG_KMS("failed finding vcpi slots:%d\n",
|
||||
slots);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
intel_link_compute_m_n(bpp, lane_count,
|
||||
|
@ -307,9 +313,8 @@ static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
|
|||
struct edid *edid;
|
||||
int ret;
|
||||
|
||||
if (!intel_dp) {
|
||||
if (!READ_ONCE(connector->registered))
|
||||
return intel_connector_update_modes(connector, NULL);
|
||||
}
|
||||
|
||||
edid = drm_dp_mst_get_edid(connector, &intel_dp->mst_mgr, intel_connector->port);
|
||||
ret = intel_connector_update_modes(connector, edid);
|
||||
|
@ -324,9 +329,10 @@ intel_dp_mst_detect(struct drm_connector *connector, bool force)
|
|||
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||
struct intel_dp *intel_dp = intel_connector->mst_port;
|
||||
|
||||
if (!intel_dp)
|
||||
if (!READ_ONCE(connector->registered))
|
||||
return connector_status_disconnected;
|
||||
return drm_dp_mst_detect_port(connector, &intel_dp->mst_mgr, intel_connector->port);
|
||||
return drm_dp_mst_detect_port(connector, &intel_dp->mst_mgr,
|
||||
intel_connector->port);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -366,7 +372,7 @@ intel_dp_mst_mode_valid(struct drm_connector *connector,
|
|||
int bpp = 24; /* MST uses fixed bpp */
|
||||
int max_rate, mode_rate, max_lanes, max_link_clock;
|
||||
|
||||
if (!intel_dp)
|
||||
if (!READ_ONCE(connector->registered))
|
||||
return MODE_ERROR;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
|
@ -398,8 +404,6 @@ static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *c
|
|||
struct intel_dp *intel_dp = intel_connector->mst_port;
|
||||
struct intel_crtc *crtc = to_intel_crtc(state->crtc);
|
||||
|
||||
if (!intel_dp)
|
||||
return NULL;
|
||||
return &intel_dp->mst_encoders[crtc->pipe]->base.base;
|
||||
}
|
||||
|
||||
|
@ -499,7 +503,6 @@ static void intel_dp_register_mst_connector(struct drm_connector *connector)
|
|||
static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name);
|
||||
|
@ -508,10 +511,6 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
|||
if (dev_priv->fbdev)
|
||||
drm_fb_helper_remove_one_connector(&dev_priv->fbdev->helper,
|
||||
connector);
|
||||
/* prevent race with the check in ->detect */
|
||||
drm_modeset_lock(&connector->dev->mode_config.connection_mutex, NULL);
|
||||
intel_connector->mst_port = NULL;
|
||||
drm_modeset_unlock(&connector->dev->mode_config.connection_mutex);
|
||||
|
||||
drm_connector_put(connector);
|
||||
}
|
||||
|
|
|
@ -1517,6 +1517,7 @@ void intel_connector_attach_encoder(struct intel_connector *connector,
|
|||
struct intel_encoder *encoder);
|
||||
struct drm_display_mode *
|
||||
intel_encoder_current_mode(struct intel_encoder *encoder);
|
||||
bool intel_port_is_combophy(struct drm_i915_private *dev_priv, enum port port);
|
||||
bool intel_port_is_tc(struct drm_i915_private *dev_priv, enum port port);
|
||||
enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv,
|
||||
enum port port);
|
||||
|
@ -2140,6 +2141,7 @@ unsigned int skl_plane_max_stride(struct intel_plane *plane,
|
|||
unsigned int rotation);
|
||||
int skl_plane_check(struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane_state *plane_state);
|
||||
int intel_plane_check_stride(const struct intel_plane_state *plane_state);
|
||||
int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state);
|
||||
int chv_plane_check_rotation(const struct intel_plane_state *plane_state);
|
||||
|
||||
|
|
|
@ -230,6 +230,28 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
|
|||
#endif
|
||||
}
|
||||
|
||||
int intel_plane_check_stride(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
|
||||
const struct drm_framebuffer *fb = plane_state->base.fb;
|
||||
unsigned int rotation = plane_state->base.rotation;
|
||||
u32 stride, max_stride;
|
||||
|
||||
/* FIXME other color planes? */
|
||||
stride = plane_state->color_plane[0].stride;
|
||||
max_stride = plane->max_stride(plane, fb->format->format,
|
||||
fb->modifier, rotation);
|
||||
|
||||
if (stride > max_stride) {
|
||||
DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
|
||||
fb->base.id, stride,
|
||||
plane->base.base.id, plane->base.name, max_stride);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
|
||||
{
|
||||
const struct drm_framebuffer *fb = plane_state->base.fb;
|
||||
|
|
|
@ -501,6 +501,8 @@ static bool assert_mmap_offset(struct drm_i915_private *i915,
|
|||
|
||||
static void disable_retire_worker(struct drm_i915_private *i915)
|
||||
{
|
||||
i915_gem_shrinker_unregister(i915);
|
||||
|
||||
mutex_lock(&i915->drm.struct_mutex);
|
||||
if (!i915->gt.active_requests++) {
|
||||
intel_runtime_pm_get(i915);
|
||||
|
@ -613,6 +615,7 @@ out_park:
|
|||
else
|
||||
queue_delayed_work(i915->wq, &i915->gt.idle_work, 0);
|
||||
mutex_unlock(&i915->drm.struct_mutex);
|
||||
i915_gem_shrinker_register(i915);
|
||||
return err;
|
||||
err_obj:
|
||||
i915_gem_object_put(obj);
|
||||
|
|
Loading…
Reference in New Issue