summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-12-14 11:07:56 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2020-12-14 11:07:56 -0800
commit1d36dffa5d887715dacca0f717f4519b7be5e498 (patch)
treea68f7c00dbb3036a67806ed6c6b8cc61c3cff60d /drivers/gpu/drm/i915/display
parent2c85ebc57b3e1817b6ce1a6b703928e113a90442 (diff)
parentb10733527bfd864605c33ab2e9a886eec317ec39 (diff)
downloadlinux-1d36dffa5d887715dacca0f717f4519b7be5e498.tar.gz
linux-1d36dffa5d887715dacca0f717f4519b7be5e498.tar.bz2
linux-1d36dffa5d887715dacca0f717f4519b7be5e498.zip
Merge tag 'drm-next-2020-12-11' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie: "Not a huge amount of big things here, AMD has support for a few new HW variants (vangogh, green sardine, dimgrey cavefish), Intel has some more DG1 enablement. We have a few big reworks of the TTM layers and interfaces, GEM and atomic internal API reworks cross tree. fbdev is marked orphaned in here as well to reflect the current reality. core: - documentation updates - deprecate DRM_FORMAT_MOD_NONE - atomic crtc enable/disable rework - GEM convert drivers to gem object functions - remove SCATTER_LIST_MAX_SEGMENT sched: - avoid infinite waits ttm: - remove AGP support - don't modify caching for swapout - ttm pinning rework - major TTM reworks - new backend allocator - multihop support vram-helper: - top down BO placement fix - TTM changes - GEM object support displayport: - DP 2.0 DPCD prep work - DP MST extended DPCD caps fbdev: - mark as orphaned amdgpu: - Initial Vangogh support - Green Sardine support - Dimgrey Cavefish support - SG display support for renoir - SMU7 improvements - gfx9+ modiifier support - CI BACO fixes radeon: - expose voltage via hwmon on SUMO amdkfd: - fix unique id handling i915: - more DG1 enablement - bigjoiner support - integer scaling filter support - async flip support - ICL+ DSI command mode - Improve display shutdown - Display refactoring - eLLC machine fbdev loading fix - dma scatterlist fixes - TGL hang fixes - eLLC display buffer caching on SKL+ - MOCS PTE seeting for gen9+ msm: - Shutdown hook - GPU cooling device support - DSI 7nm and 10nm phy/pll updates - sm8150/sm2850 DPU support - GEM locking re-work - LLCC system cache support aspeed: - sysfs output config support ast: - LUT fix - new display mode gma500: - remove 2d framebuffer accel panfrost: - move gpu reset to a worker exynos: - new HDMI mode support mediatek: - MT8167 support - yaml bindings - MIPI DSI phy code moved etnaviv: - new perf counter - more lockdep annotation hibmc: - i2c DDC support ingenic: - pixel clock reset fix - reserved memory support - allow both DMA channels at once - different pixel format support - 30/24/8-bit palette modes tilcdc: - don't keep vblank irq enabled vc4: - new maintainer added - DSI registration fix virtio: - blob resource support - host visible and cross-device support - uuid api support" * tag 'drm-next-2020-12-11' of git://anongit.freedesktop.org/drm/drm: (1754 commits) drm/amdgpu: Initialise drm_gem_object_funcs for imported BOs drm/amdgpu: fix size calculation with stolen vga memory drm/amdgpu: remove amdgpu_ttm_late_init and amdgpu_bo_late_init drm/amdgpu: free the pre-OS console framebuffer after the first modeset drm/amdgpu: enable runtime pm using BACO on CI dGPUs drm/amdgpu/cik: enable BACO reset on Bonaire drm/amd/pm: update smu10.h WORKLOAD_PPLIB setting for raven drm/amd/pm: remove one unsupported smu function for vangogh drm/amd/display: setup system context for APUs drm/amd/display: add S/G support for Vangogh drm/amdkfd: Fix leak in dmabuf import drm/amdgpu: use AMDGPU_NUM_VMID when possible drm/amdgpu: fix sdma instance fw version and feature version init drm/amd/pm: update driver if version for dimgrey_cavefish drm/amd/display: 3.2.115 drm/amd/display: [FW Promotion] Release 0.0.45 drm/amd/display: Revert DCN2.1 dram_clock_change_latency update drm/amd/display: Enable gpu_vm_support for dcn3.01 drm/amd/display: Fixed the audio noise during mode switching with HDCP mode on drm/amd/display: Add wm table for Renoir ...
Diffstat (limited to 'drivers/gpu/drm/i915/display')
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi.c79
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic.c10
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.c138
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.h9
-rw-r--r--drivers/gpu/drm/i915/display/intel_bios.c58
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.c52
-rw-r--r--drivers/gpu/drm/i915/display/intel_color.c124
-rw-r--r--drivers/gpu/drm/i915/display/intel_combo_phy.c13
-rw-r--r--drivers/gpu/drm/i915/display/intel_csr.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c1009
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.h11
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c1689
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.h43
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_debugfs.c39
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.c116
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h140
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c798
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.h23
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.c554
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.h17
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_mst.c40
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpio_phy.c23
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpio_phy.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.c221
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.h28
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsi.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsi.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbc.c7
-rw-r--r--drivers/gpu/drm/i915/display/intel_gmbus.c15
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp.c89
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdmi.c20
-rw-r--r--drivers/gpu/drm/i915/display/intel_hotplug.c64
-rw-r--r--drivers/gpu/drm/i915/display/intel_hotplug.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_lspcon.c97
-rw-r--r--drivers/gpu/drm/i915/display/intel_lspcon.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_lvds.c10
-rw-r--r--drivers/gpu/drm/i915/display/intel_opregion.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c249
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.h14
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite.c235
-rw-r--r--drivers/gpu/drm/i915/display/intel_tc.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_vbt_defs.h13
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc.c201
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc.h6
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi.c8
48 files changed, 4499 insertions, 1811 deletions
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 520715b7d5b5..a9439b415603 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -205,6 +205,32 @@ static int dsi_send_pkt_payld(struct intel_dsi_host *host,
return 0;
}
+void icl_dsi_frame_update(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);
+ u32 tmp, mode_flags;
+ enum port port;
+
+ mode_flags = crtc_state->mode_flags;
+
+ /*
+ * case 1 also covers dual link
+ * In case of dual link, frame update should be set on
+ * DSI_0
+ */
+ if (mode_flags & I915_MODE_FLAG_DSI_USE_TE0)
+ port = PORT_A;
+ else if (mode_flags & I915_MODE_FLAG_DSI_USE_TE1)
+ port = PORT_B;
+ else
+ return;
+
+ tmp = intel_de_read(dev_priv, DSI_CMD_FRMCTL(port));
+ tmp |= DSI_FRAME_UPDATE_REQUEST;
+ intel_de_write(dev_priv, DSI_CMD_FRMCTL(port), tmp);
+}
+
static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -429,7 +455,7 @@ static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder)
intel_de_write(dev_priv, ICL_PORT_TX_DW2_GRP(phy), tmp);
/* For EHL, TGL, set latency optimization for PCS_DW1 lanes */
- if (IS_ELKHARTLAKE(dev_priv) || (INTEL_GEN(dev_priv) >= 12)) {
+ if (IS_JSL_EHL(dev_priv) || (INTEL_GEN(dev_priv) >= 12)) {
tmp = intel_de_read(dev_priv,
ICL_PORT_PCS_DW1_AUX(phy));
tmp &= ~LATENCY_OPTIM_MASK;
@@ -586,7 +612,7 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
}
}
- if (IS_ELKHARTLAKE(dev_priv)) {
+ if (IS_JSL_EHL(dev_priv)) {
for_each_dsi_phy(phy, intel_dsi->phys) {
tmp = intel_de_read(dev_priv, ICL_DPHY_CHKN(phy));
tmp |= ICL_DPHY_CHKN_AFE_OVER_PPI_STRAP;
@@ -1447,6 +1473,18 @@ static bool gen11_dsi_is_periodic_cmd_mode(struct intel_dsi *intel_dsi)
return (val & DSI_PERIODIC_FRAME_UPDATE_ENABLE);
}
+static void gen11_dsi_get_cmd_mode_config(struct intel_dsi *intel_dsi,
+ struct intel_crtc_state *pipe_config)
+{
+ if (intel_dsi->ports == (BIT(PORT_B) | BIT(PORT_A)))
+ pipe_config->mode_flags |= I915_MODE_FLAG_DSI_USE_TE1 |
+ I915_MODE_FLAG_DSI_USE_TE0;
+ else if (intel_dsi->ports == BIT(PORT_B))
+ pipe_config->mode_flags |= I915_MODE_FLAG_DSI_USE_TE1;
+ else
+ pipe_config->mode_flags |= I915_MODE_FLAG_DSI_USE_TE0;
+}
+
static void gen11_dsi_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
@@ -1454,11 +1492,10 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
- intel_dsc_get_config(encoder, pipe_config);
-
/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
pipe_config->port_clock = intel_dpll_get_freq(i915,
- pipe_config->shared_dpll);
+ pipe_config->shared_dpll,
+ &pipe_config->dpll_hw_state);
pipe_config->hw.adjusted_mode.crtc_clock = intel_dsi->pclk;
if (intel_dsi->dual_link)
@@ -1468,6 +1505,10 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI);
pipe_config->pipe_bpp = bdw_get_pipemisc_bpp(crtc);
+ /* Get the details on which TE should be enabled */
+ if (is_cmd_mode(intel_dsi))
+ gen11_dsi_get_cmd_mode_config(intel_dsi, pipe_config);
+
if (gen11_dsi_is_periodic_cmd_mode(intel_dsi))
pipe_config->mode_flags |= I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE;
}
@@ -1562,18 +1603,8 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,
* receive TE from the slave if
* dual link is enabled
*/
- if (is_cmd_mode(intel_dsi)) {
- if (intel_dsi->ports == (BIT(PORT_B) | BIT(PORT_A)))
- pipe_config->mode_flags |=
- I915_MODE_FLAG_DSI_USE_TE1 |
- I915_MODE_FLAG_DSI_USE_TE0;
- else if (intel_dsi->ports == BIT(PORT_B))
- pipe_config->mode_flags |=
- I915_MODE_FLAG_DSI_USE_TE1;
- else
- pipe_config->mode_flags |=
- I915_MODE_FLAG_DSI_USE_TE0;
- }
+ if (is_cmd_mode(intel_dsi))
+ gen11_dsi_get_cmd_mode_config(intel_dsi, pipe_config);
return 0;
}
@@ -1636,6 +1667,19 @@ out:
return ret;
}
+static bool gen11_dsi_initial_fastset_check(struct intel_encoder *encoder,
+ struct intel_crtc_state *crtc_state)
+{
+ if (crtc_state->dsc.compression_enable) {
+ drm_dbg_kms(encoder->base.dev, "Forcing full modeset due to DSC being enabled\n");
+ crtc_state->uapi.mode_changed = true;
+
+ return false;
+ }
+
+ return true;
+}
+
static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder)
{
intel_encoder_destroy(encoder);
@@ -1891,6 +1935,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
encoder->update_pipe = intel_panel_update_backlight;
encoder->compute_config = gen11_dsi_compute_config;
encoder->get_hw_state = gen11_dsi_get_hw_state;
+ encoder->initial_fastset_check = gen11_dsi_initial_fastset_check;
encoder->type = INTEL_OUTPUT_DSI;
encoder->cloneable = 0;
encoder->pipe_mask = ~0;
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 86be032bcf96..e00fdc47c0eb 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -133,7 +133,6 @@ int intel_digital_connector_atomic_check(struct drm_connector *conn,
struct drm_crtc_state *crtc_state;
intel_hdcp_atomic_check(conn, old_state, new_state);
- intel_psr_atomic_check(conn, old_state, new_state);
if (!new_state->crtc)
return 0;
@@ -270,14 +269,15 @@ void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
intel_crtc_put_color_blobs(crtc_state);
}
-void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state)
+void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state,
+ const struct intel_crtc_state *from_crtc_state)
{
drm_property_replace_blob(&crtc_state->hw.degamma_lut,
- crtc_state->uapi.degamma_lut);
+ from_crtc_state->uapi.degamma_lut);
drm_property_replace_blob(&crtc_state->hw.gamma_lut,
- crtc_state->uapi.gamma_lut);
+ from_crtc_state->uapi.gamma_lut);
drm_property_replace_blob(&crtc_state->hw.ctm,
- crtc_state->uapi.ctm);
+ from_crtc_state->uapi.ctm);
}
/**
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
index 285de07011dc..62a3365ed5e6 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic.h
@@ -43,7 +43,8 @@ struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
void intel_crtc_destroy_state(struct drm_crtc *crtc,
struct drm_crtc_state *state);
void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state);
-void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state);
+void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state,
+ const struct intel_crtc_state *from_crtc_state);
struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
void intel_atomic_state_free(struct drm_atomic_state *state);
void intel_atomic_state_clear(struct drm_atomic_state *state);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 79032701873a..7e9f84b00859 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -247,11 +247,19 @@ static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
}
void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
- const struct intel_plane_state *from_plane_state)
+ const struct intel_plane_state *from_plane_state,
+ struct intel_crtc *crtc)
{
intel_plane_clear_hw_state(plane_state);
- plane_state->hw.crtc = from_plane_state->uapi.crtc;
+ /*
+ * For the bigjoiner slave uapi.crtc will point at
+ * the master crtc. So we explicitly assign the right
+ * slave crtc to hw.crtc. uapi.crtc!=NULL simply indicates
+ * the plane is logically enabled on the uapi level.
+ */
+ plane_state->hw.crtc = from_plane_state->uapi.crtc ? &crtc->base : NULL;
+
plane_state->hw.fb = from_plane_state->uapi.fb;
if (plane_state->hw.fb)
drm_framebuffer_get(plane_state->hw.fb);
@@ -262,6 +270,22 @@ void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
plane_state->hw.rotation = from_plane_state->uapi.rotation;
plane_state->hw.color_encoding = from_plane_state->uapi.color_encoding;
plane_state->hw.color_range = from_plane_state->uapi.color_range;
+ plane_state->hw.scaling_filter = from_plane_state->uapi.scaling_filter;
+
+ plane_state->uapi.src = drm_plane_state_src(&from_plane_state->uapi);
+ plane_state->uapi.dst = drm_plane_state_dest(&from_plane_state->uapi);
+}
+
+void intel_plane_copy_hw_state(struct intel_plane_state *plane_state,
+ const struct intel_plane_state *from_plane_state)
+{
+ intel_plane_clear_hw_state(plane_state);
+
+ memcpy(&plane_state->hw, &from_plane_state->hw,
+ sizeof(plane_state->hw));
+
+ if (plane_state->hw.fb)
+ drm_framebuffer_get(plane_state->hw.fb);
}
void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
@@ -318,15 +342,16 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
old_plane_state, new_plane_state);
}
-static struct intel_crtc *
-get_crtc_from_states(const struct intel_plane_state *old_plane_state,
- const struct intel_plane_state *new_plane_state)
+static struct intel_plane *
+intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id)
{
- if (new_plane_state->uapi.crtc)
- return to_intel_crtc(new_plane_state->uapi.crtc);
+ struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ struct intel_plane *plane;
- if (old_plane_state->uapi.crtc)
- return to_intel_crtc(old_plane_state->uapi.crtc);
+ for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
+ if (plane->id == plane_id)
+ return plane;
+ }
return NULL;
}
@@ -334,23 +359,37 @@ get_crtc_from_states(const struct intel_plane_state *old_plane_state,
int intel_plane_atomic_check(struct intel_atomic_state *state,
struct intel_plane *plane)
{
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
struct intel_plane_state *new_plane_state =
intel_atomic_get_new_plane_state(state, plane);
const struct intel_plane_state *old_plane_state =
intel_atomic_get_old_plane_state(state, plane);
- struct intel_crtc *crtc =
- get_crtc_from_states(old_plane_state, new_plane_state);
- const struct intel_crtc_state *old_crtc_state;
- struct intel_crtc_state *new_crtc_state;
+ const struct intel_plane_state *new_master_plane_state;
+ struct intel_crtc *crtc = intel_get_crtc_for_pipe(i915, plane->pipe);
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
+ struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
+
+ if (new_crtc_state && new_crtc_state->bigjoiner_slave) {
+ struct intel_plane *master_plane =
+ intel_crtc_get_plane(new_crtc_state->bigjoiner_linked_crtc,
+ plane->id);
+
+ new_master_plane_state =
+ intel_atomic_get_new_plane_state(state, master_plane);
+ } else {
+ new_master_plane_state = new_plane_state;
+ }
+
+ intel_plane_copy_uapi_to_hw_state(new_plane_state,
+ new_master_plane_state,
+ crtc);
- intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
new_plane_state->uapi.visible = false;
- if (!crtc)
+ if (!new_crtc_state)
return 0;
- old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
- new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
-
return intel_plane_atomic_check_with_state(old_crtc_state,
new_crtc_state,
old_plane_state,
@@ -408,7 +447,11 @@ void intel_update_plane(struct intel_plane *plane,
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
trace_intel_update_plane(&plane->base, crtc);
- plane->update_plane(plane, crtc_state, plane_state);
+
+ if (crtc_state->uapi.async_flip && plane->async_flip)
+ plane->async_flip(plane, crtc_state, plane_state);
+ else
+ plane->update_plane(plane, crtc_state, plane_state);
}
void intel_disable_plane(struct intel_plane *plane,
@@ -474,6 +517,63 @@ void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
}
}
+int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
+ struct intel_crtc_state *crtc_state,
+ int min_scale, int max_scale,
+ bool can_position)
+{
+ struct drm_framebuffer *fb = plane_state->hw.fb;
+ struct drm_rect *src = &plane_state->uapi.src;
+ struct drm_rect *dst = &plane_state->uapi.dst;
+ unsigned int rotation = plane_state->hw.rotation;
+ struct drm_rect clip = {};
+ int hscale, vscale;
+
+ if (!fb) {
+ plane_state->uapi.visible = false;
+ return 0;
+ }
+
+ drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
+
+ /* Check scaling */
+ hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
+ vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
+ if (hscale < 0 || vscale < 0) {
+ DRM_DEBUG_KMS("Invalid scaling of plane\n");
+ drm_rect_debug_print("src: ", src, true);
+ drm_rect_debug_print("dst: ", dst, false);
+ return -ERANGE;
+ }
+
+ if (crtc_state->hw.enable) {
+ clip.x2 = crtc_state->pipe_src_w;
+ clip.y2 = crtc_state->pipe_src_h;
+ }
+
+ /* right side of the image is on the slave crtc, adjust dst to match */
+ if (crtc_state->bigjoiner_slave)
+ drm_rect_translate(dst, -crtc_state->pipe_src_w, 0);
+
+ /*
+ * FIXME: This might need further adjustment for seamless scaling
+ * with phase information, for the 2p2 and 2p1 scenarios.
+ */
+ plane_state->uapi.visible = drm_rect_clip_scaled(src, dst, &clip);
+
+ drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
+
+ if (!can_position && plane_state->uapi.visible &&
+ !drm_rect_equals(dst, &clip)) {
+ DRM_DEBUG_KMS("Plane must cover entire CRTC\n");
+ drm_rect_debug_print("dst: ", dst, false);
+ drm_rect_debug_print("clip: ", &clip, false);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
.prepare_fb = intel_prepare_plane_fb,
.cleanup_fb = intel_cleanup_plane_fb,
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index 59dd1fbb02ea..5c78a087ed86 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -24,7 +24,10 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
- const struct intel_plane_state *from_plane_state);
+ const struct intel_plane_state *from_plane_state,
+ struct intel_crtc *crtc);
+void intel_plane_copy_hw_state(struct intel_plane_state *plane_state,
+ const struct intel_plane_state *from_plane_state);
void intel_update_plane(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
@@ -52,6 +55,10 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
int intel_plane_calc_min_cdclk(struct intel_atomic_state *state,
struct intel_plane *plane,
bool *need_cdclk_calc);
+int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
+ struct intel_crtc_state *crtc_state,
+ int min_scale, int max_scale,
+ bool can_position);
void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state);
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index 4716484af62d..4cc949b228f2 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -425,6 +425,7 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv,
const struct bdb_lfp_backlight_data *backlight_data;
const struct lfp_backlight_data_entry *entry;
int panel_type = dev_priv->vbt.panel_type;
+ u16 level;
backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
if (!backlight_data)
@@ -459,14 +460,39 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv,
dev_priv->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
dev_priv->vbt.backlight.active_low_pwm = entry->active_low_pwm;
- dev_priv->vbt.backlight.min_brightness = entry->min_brightness;
+
+ if (bdb->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 (bdb->version >= 236)
+ scale = backlight_data->brightness_precision_bits[panel_type] == 16;
+ else
+ scale = level > 255;
+
+ if (scale)
+ min_level = min_level / 255;
+
+ if (min_level > 255) {
+ drm_warn(&dev_priv->drm, "Brightness min level > 255\n");
+ level = 255;
+ }
+ dev_priv->vbt.backlight.min_brightness = min_level;
+ } else {
+ level = backlight_data->level[panel_type];
+ dev_priv->vbt.backlight.min_brightness = entry->min_brightness;
+ }
+
drm_dbg_kms(&dev_priv->drm,
"VBT backlight PWM modulation frequency %u Hz, "
"active %s, min brightness %u, level %u, controller %u\n",
dev_priv->vbt.backlight.pwm_freq_hz,
dev_priv->vbt.backlight.active_low_pwm ? "low" : "high",
dev_priv->vbt.backlight.min_brightness,
- backlight_data->level[panel_type],
+ level,
dev_priv->vbt.backlight.controller);
}
@@ -1602,7 +1628,9 @@ static u8 map_ddc_pin(struct drm_i915_private *dev_priv, u8 vbt_pin)
const u8 *ddc_pin_map;
int n_entries;
- if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) {
+ if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) {
+ return vbt_pin;
+ } else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) {
ddc_pin_map = icp_ddc_pin_map;
n_entries = ARRAY_SIZE(icp_ddc_pin_map);
} else if (HAS_PCH_CNP(dev_priv)) {
@@ -1660,20 +1688,18 @@ static enum port dvo_port_to_port(struct drm_i915_private *dev_priv,
[PORT_I] = { DVO_PORT_HDMII, DVO_PORT_DPI, -1 },
};
/*
- * Bspec lists the ports as A, B, C, D - however internally in our
- * driver we keep them as PORT_A, PORT_B, PORT_D and PORT_E so the
- * registers in Display Engine match the right offsets. Apply the
- * mapping here to translate from VBT to internal convention.
+ * RKL VBT uses PHY based mapping. Combo PHYs A,B,C,D
+ * map to DDI A,B,TC1,TC2 respectively.
*