From 70418a68713c13da3f36c388087d0220b456a430 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 11 Aug 2021 10:48:57 +0530 Subject: drm/i915/display: Fix the 12 BPC bits for PIPE_MISC reg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Till DISPLAY12 the PIPE_MISC bits 5-7 are used to set the Dithering BPC, with valid values of 6, 8, 10 BPC. For ADLP+ these bits are used to set the PORT OUTPUT BPC, with valid values of: 6, 8, 10, 12 BPC, and need to be programmed whether dithering is enabled or not. This patch: -corrects the bits 5-7 for PIPE MISC register for 12 BPC. -renames the bits and mask to have generic names for these bits for dithering bpc and port output bpc. v3: Added a note for MIPI DSI which uses the PIPE_MISC for readout for pipe_bpp. (Uma Shankar) v2: Added 'display' to the subject and fixes tag. (Uma Shankar) Fixes: 756f85cffef2 ("drm/i915/bdw: Broadwell has PIPEMISC") Cc: Paulo Zanoni (v1) Cc: Ville Syrjälä Cc: Daniel Vetter Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: intel-gfx@lists.freedesktop.org Cc: # v3.13+ Signed-off-by: Ankit Nautiyal Reviewed-by: Uma Shankar Signed-off-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20210811051857.109723-1-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 34 ++++++++++++++++++++-------- drivers/gpu/drm/i915/i915_reg.h | 16 +++++++++---- 2 files changed, 35 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 122f091e0a1e..58f51854bb79 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5835,16 +5835,18 @@ static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state) switch (crtc_state->pipe_bpp) { case 18: - val |= PIPEMISC_DITHER_6_BPC; + val |= PIPEMISC_6_BPC; break; case 24: - val |= PIPEMISC_DITHER_8_BPC; + val |= PIPEMISC_8_BPC; break; case 30: - val |= PIPEMISC_DITHER_10_BPC; + val |= PIPEMISC_10_BPC; break; case 36: - val |= PIPEMISC_DITHER_12_BPC; + /* Port output 12BPC defined for ADLP+ */ + if (DISPLAY_VER(dev_priv) > 12) + val |= PIPEMISC_12_BPC_ADLP; break; default: MISSING_CASE(crtc_state->pipe_bpp); @@ -5897,15 +5899,27 @@ int bdw_get_pipemisc_bpp(struct intel_crtc *crtc) tmp = intel_de_read(dev_priv, PIPEMISC(crtc->pipe)); - switch (tmp & PIPEMISC_DITHER_BPC_MASK) { - case PIPEMISC_DITHER_6_BPC: + switch (tmp & PIPEMISC_BPC_MASK) { + case PIPEMISC_6_BPC: return 18; - case PIPEMISC_DITHER_8_BPC: + case PIPEMISC_8_BPC: return 24; - case PIPEMISC_DITHER_10_BPC: + case PIPEMISC_10_BPC: return 30; - case PIPEMISC_DITHER_12_BPC: - return 36; + /* + * PORT OUTPUT 12 BPC defined for ADLP+. + * + * TODO: + * For previous platforms with DSI interface, bits 5:7 + * are used for storing pipe_bpp irrespective of dithering. + * Since the value of 12 BPC is not defined for these bits + * on older platforms, need to find a workaround for 12 BPC + * MIPI DSI HW readout. + */ + case PIPEMISC_12_BPC_ADLP: + if (DISPLAY_VER(dev_priv) > 12) + return 36; + fallthrough; default: MISSING_CASE(tmp); return 0; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 680acccef26b..c9a62a248e49 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6163,11 +6163,17 @@ enum { #define PIPEMISC_HDR_MODE_PRECISION (1 << 23) /* icl+ */ #define PIPEMISC_OUTPUT_COLORSPACE_YUV (1 << 11) #define PIPEMISC_PIXEL_ROUNDING_TRUNC REG_BIT(8) /* tgl+ */ -#define PIPEMISC_DITHER_BPC_MASK (7 << 5) -#define PIPEMISC_DITHER_8_BPC (0 << 5) -#define PIPEMISC_DITHER_10_BPC (1 << 5) -#define PIPEMISC_DITHER_6_BPC (2 << 5) -#define PIPEMISC_DITHER_12_BPC (3 << 5) +/* + * For Display < 13, Bits 5-7 of PIPE MISC represent DITHER BPC with + * valid values of: 6, 8, 10 BPC. + * ADLP+, the bits 5-7 represent PORT OUTPUT BPC with valid values of: + * 6, 8, 10, 12 BPC. + */ +#define PIPEMISC_BPC_MASK (7 << 5) +#define PIPEMISC_8_BPC (0 << 5) +#define PIPEMISC_10_BPC (1 << 5) +#define PIPEMISC_6_BPC (2 << 5) +#define PIPEMISC_12_BPC_ADLP (4 << 5) /* adlp+ */ #define PIPEMISC_DITHER_ENABLE (1 << 4) #define PIPEMISC_DITHER_TYPE_MASK (3 << 2) #define PIPEMISC_DITHER_TYPE_SP (0 << 2) -- cgit v1.2.3 From 01da701b77d498ed2625483c58bd73000e2767e3 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Thu, 5 Aug 2021 09:36:47 -0700 Subject: drm/i915/dg2: Configure PCON in DP pre-enable path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the functions to configure HDMI2.1 pcon for DG2, before DP link training. Signed-off-by: Ankit Nautiyal Signed-off-by: Matt Roper Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210805163647.801064-10-matthew.d.roper@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index d8162951b78f..e932fd0fe7e2 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2402,6 +2402,7 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state, if (!is_mst) intel_dp_set_power(intel_dp, DP_SET_POWER_D0); + intel_dp_configure_protocol_converter(intel_dp, crtc_state); intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true); /* * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit @@ -2409,6 +2410,8 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state, * training */ intel_dp_sink_set_fec_ready(intel_dp, crtc_state); + intel_dp_check_frl_training(intel_dp); + intel_dp_pcon_dsc_configure(intel_dp, crtc_state); /* * 5.h Follow DisplayPort specification training sequence (see notes for -- cgit v1.2.3 From c5589bb5dccb0c5cb74910da93663f489589f3ce Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Fri, 6 Aug 2021 10:41:30 -0700 Subject: drm/i915: Only access SFC_DONE when media domain is not fused off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SFC_DONE register lives within the corresponding VD0/VD2/VD4/VD6 forcewake domain and is not accessible if the vdbox in that domain is fused off and the forcewake is not initialized. This mistake went unnoticed because until recently we were using the wrong register offset for the SFC_DONE register; once the register offset was corrected, we started hitting errors like <4> [544.989065] i915 0000:cc:00.0: Uninitialized forcewake domain(s) 0x80 accessed at 0x1ce000 on parts with fused-off vdbox engines. Fixes: e50dbdbfd9fb ("drm/i915/tgl: Add SFC instdone to error state") Fixes: 82929a2140eb ("drm/i915: Correct SFC_DONE register offset") Cc: Daniele Ceraolo Spurio Cc: Mika Kuoppala Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20210806174130.1058960-1-matthew.d.roper@intel.com Reviewed-by: José Roberto de Souza --- drivers/gpu/drm/i915/i915_gpu_error.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 35c97c39f125..966664610c8c 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -727,9 +727,18 @@ static void err_print_gt(struct drm_i915_error_state_buf *m, if (GRAPHICS_VER(m->i915) >= 12) { int i; - for (i = 0; i < GEN12_SFC_DONE_MAX; i++) + for (i = 0; i < GEN12_SFC_DONE_MAX; i++) { + /* + * SFC_DONE resides in the VD forcewake domain, so it + * only exists if the corresponding VCS engine is + * present. + */ + if (!HAS_ENGINE(gt->_gt, _VCS(i * 2))) + continue; + err_printf(m, " SFC_DONE[%d]: 0x%08x\n", i, gt->sfc_done[i]); + } err_printf(m, " GAM_DONE: 0x%08x\n", gt->gam_done); } @@ -1581,6 +1590,14 @@ static void gt_record_regs(struct intel_gt_coredump *gt) if (GRAPHICS_VER(i915) >= 12) { for (i = 0; i < GEN12_SFC_DONE_MAX; i++) { + /* + * SFC_DONE resides in the VD forcewake domain, so it + * only exists if the corresponding VCS engine is + * present. + */ + if (!HAS_ENGINE(gt->_gt, _VCS(i * 2))) + continue; + gt->sfc_done[i] = intel_uncore_read(uncore, GEN12_SFC_DONE(i)); } -- cgit v1.2.3 From 8b46cc6577f4bbef7e5909bb926da31d705f350f Mon Sep 17 00:00:00 2001 From: Anshuman Gupta Date: Tue, 10 Aug 2021 17:01:12 +0530 Subject: drm/i915: Tweaked Wa_14010685332 for all PCHs dispcnlunit1_cp_xosc_clkreq clock observed to be active on TGL-H platform despite Wa_14010685332 original sequence, thus blocks entry to deeper s0ix state. The Tweaked Wa_14010685332 sequence fixes this issue, therefore use tweaked Wa_14010685332 sequence for every PCH since PCH_CNP. v2: - removed RKL from comment and simplified condition. [Rodrigo] Fixes: b896898c7369 ("drm/i915: Tweaked Wa_14010685332 for PCHs used on gen11 platforms") Cc: Matt Roper Cc: Rodrigo Vivi Cc: Imre Deak Signed-off-by: Anshuman Gupta Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20210810113112.31739-2-anshuman.gupta@intel.com --- drivers/gpu/drm/i915/display/intel_display_power.c | 16 ++++++++-------- drivers/gpu/drm/i915/i915_irq.c | 21 --------------------- 2 files changed, 8 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 5da293369f30..cce1a926fcc1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -6329,13 +6329,13 @@ void intel_display_power_suspend_late(struct drm_i915_private *i915) if (DISPLAY_VER(i915) >= 11 || IS_GEMINILAKE(i915) || IS_BROXTON(i915)) { bxt_enable_dc9(i915); - /* Tweaked Wa_14010685332:icp,jsp,mcc */ - if (INTEL_PCH_TYPE(i915) >= PCH_ICP && INTEL_PCH_TYPE(i915) <= PCH_MCC) - intel_de_rmw(i915, SOUTH_CHICKEN1, - SBCLK_RUN_REFCLK_DIS, SBCLK_RUN_REFCLK_DIS); } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { hsw_enable_pc8(i915); } + + /* Tweaked Wa_14010685332:cnp,icp,jsp,mcc,tgp,adp */ + if (INTEL_PCH_TYPE(i915) >= PCH_CNP && INTEL_PCH_TYPE(i915) < PCH_DG1) + intel_de_rmw(i915, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, SBCLK_RUN_REFCLK_DIS); } void intel_display_power_resume_early(struct drm_i915_private *i915) @@ -6344,13 +6344,13 @@ void intel_display_power_resume_early(struct drm_i915_private *i915) IS_BROXTON(i915)) { gen9_sanitize_dc_state(i915); bxt_disable_dc9(i915); - /* Tweaked Wa_14010685332:icp,jsp,mcc */ - if (INTEL_PCH_TYPE(i915) >= PCH_ICP && INTEL_PCH_TYPE(i915) <= PCH_MCC) - intel_de_rmw(i915, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0); - } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { hsw_disable_pc8(i915); } + + /* Tweaked Wa_14010685332:cnp,icp,jsp,mcc,tgp,adp */ + if (INTEL_PCH_TYPE(i915) >= PCH_CNP && INTEL_PCH_TYPE(i915) < PCH_DG1) + intel_de_rmw(i915, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0); } void intel_display_power_suspend(struct drm_i915_private *i915) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 1b9ee92b6ee7..94c6bb087193 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3079,24 +3079,6 @@ static void valleyview_irq_reset(struct drm_i915_private *dev_priv) spin_unlock_irq(&dev_priv->irq_lock); } -static void cnp_display_clock_wa(struct drm_i915_private *dev_priv) -{ - struct intel_uncore *uncore = &dev_priv->uncore; - - /* - * Wa_14010685332:cnp/cmp,tgp,adp - * TODO: Clarify which platforms this applies to - * TODO: Figure out if this workaround can be applied in the s0ix suspend/resume handlers as - * on earlier platforms and whether the workaround is also needed for runtime suspend/resume - */ - if (INTEL_PCH_TYPE(dev_priv) == PCH_CNP || - (INTEL_PCH_TYPE(dev_priv) >= PCH_TGP && INTEL_PCH_TYPE(dev_priv) < PCH_DG1)) { - intel_uncore_rmw(uncore, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, - SBCLK_RUN_REFCLK_DIS); - intel_uncore_rmw(uncore, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0); - } -} - static void gen8_display_irq_reset(struct drm_i915_private *dev_priv) { struct intel_uncore *uncore = &dev_priv->uncore; @@ -3130,7 +3112,6 @@ static void gen8_irq_reset(struct drm_i915_private *dev_priv) if (HAS_PCH_SPLIT(dev_priv)) ibx_irq_reset(dev_priv); - cnp_display_clock_wa(dev_priv); } static void gen11_display_irq_reset(struct drm_i915_private *dev_priv) @@ -3174,8 +3155,6 @@ static void gen11_display_irq_reset(struct drm_i915_private *dev_priv) if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) GEN3_IRQ_RESET(uncore, SDE); - - cnp_display_clock_wa(dev_priv); } static void gen11_irq_reset(struct drm_i915_private *dev_priv) -- cgit v1.2.3 From 55285e21f04517939480966164a33898c34b2af2 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 9 Aug 2021 16:31:46 +0300 Subject: fbdev/efifb: Release PCI device's runtime PM ref during FB destroy Atm the EFI FB platform driver gets a runtime PM reference for the associated GFX PCI device during probing the EFI FB platform device and releases it only when the platform device gets unbound. When fbcon switches to the FB provided by the PCI device's driver (for instance i915/drmfb), the EFI FB will get only unregistered without the EFI FB platform device getting unbound, keeping the runtime PM reference acquired during the platform device probing. This reference will prevent the PCI driver from runtime suspending the device. Fix this by releasing the RPM reference from the EFI FB's destroy hook, called when the FB gets unregistered. While at it assert that pm_runtime_get_sync() didn't fail. v2: - Move pm_runtime_get_sync() before register_framebuffer() to avoid its race wrt. efifb_destroy()->pm_runtime_put(). (Daniel) - Assert that pm_runtime_get_sync() didn't fail. - Clarify commit message wrt. platform/PCI device/driver and driver removal vs. device unbinding. Fixes: a6c0fd3d5a8b ("efifb: Ensure graphics device for efifb stays at PCI D0") Cc: Kai-Heng Feng Cc: Daniel Vetter Reviewed-by: Daniel Vetter (v1) Acked-by: Alex Deucher Acked-by: Kai-Heng Feng Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20210809133146.2478382-1-imre.deak@intel.com --- drivers/video/fbdev/efifb.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index 8ea8f079cde2..edca3703b964 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -47,6 +47,8 @@ static bool use_bgrt = true; static bool request_mem_succeeded = false; static u64 mem_flags = EFI_MEMORY_WC | EFI_MEMORY_UC; +static struct pci_dev *efifb_pci_dev; /* dev with BAR covering the efifb */ + static struct fb_var_screeninfo efifb_defined = { .activate = FB_ACTIVATE_NOW, .height = -1, @@ -243,6 +245,9 @@ static inline void efifb_show_boot_graphics(struct fb_info *info) {} static void efifb_destroy(struct fb_info *info) { + if (efifb_pci_dev) + pm_runtime_put(&efifb_pci_dev->dev); + if (info->screen_base) { if (mem_flags & (EFI_MEMORY_UC | EFI_MEMORY_WC)) iounmap(info->screen_base); @@ -333,7 +338,6 @@ ATTRIBUTE_GROUPS(efifb); static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */ -static struct pci_dev *efifb_pci_dev; /* dev with BAR covering the efifb */ static struct resource *bar_resource; static u64 bar_offset; @@ -569,17 +573,22 @@ static int efifb_probe(struct platform_device *dev) pr_err("efifb: cannot allocate colormap\n"); goto err_groups; } + + if (efifb_pci_dev) + WARN_ON(pm_runtime_get_sync(&efifb_pci_dev->dev) < 0); + err = register_framebuffer(info); if (err < 0) { pr_err("efifb: cannot register framebuffer\n"); - goto err_fb_dealoc; + goto err_put_rpm_ref; } fb_info(info, "%s frame buffer device\n", info->fix.id); - if (efifb_pci_dev) - pm_runtime_get_sync(&efifb_pci_dev->dev); return 0; -err_fb_dealoc: +err_put_rpm_ref: + if (efifb_pci_dev) + pm_runtime_put(&efifb_pci_dev->dev); + fb_dealloc_cmap(&info->cmap); err_groups: sysfs_remove_groups(&dev->dev.kobj, efifb_groups); @@ -603,8 +612,6 @@ static int efifb_remove(struct platform_device *pdev) unregister_framebuffer(info); sysfs_remove_groups(&pdev->dev.kobj, efifb_groups); framebuffer_release(info); - if (efifb_pci_dev) - pm_runtime_put(&efifb_pci_dev->dev); return 0; } -- cgit v1.2.3 From f6864b27d6d324771d979694de7ca455afbad32a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 12 Aug 2021 16:23:54 +0300 Subject: drm/i915/edp: fix eDP MSO pipe sanity checks for ADL-P MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ADL-P supports stream splitter on pipe B in addition to pipe A. Update the sanity check in intel_ddi_mso_get_config() to reflect this, and remove the check in intel_ddi_mso_configure() as redundant with encoder->pipe_mask. Abstract the splitter pipe mask to a single point of truth while at it to avoid similar mistakes in the future. Fixes: 7bc188cc2c8c ("drm/i915/adl_p: enable MSO on pipe B") Cc: Uma Shankar Cc: Ville Syrjälä Cc: Swati Sharma Reviewed-by: Swati Sharma Tested-by: Swati Sharma Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210812132354.10885-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index e932fd0fe7e2..eb9aa871f87b 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2251,6 +2251,15 @@ static void intel_ddi_power_up_lanes(struct intel_encoder *encoder, } } +/* Splitter enable for eDP MSO is limited to certain pipes. */ +static u8 intel_ddi_splitter_pipe_mask(struct drm_i915_private *i915) +{ + if (IS_ALDERLAKE_P(i915)) + return BIT(PIPE_A) | BIT(PIPE_B); + else + return BIT(PIPE_A); +} + static void intel_ddi_mso_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { @@ -2268,8 +2277,7 @@ static void intel_ddi_mso_get_config(struct intel_encoder *encoder, if (!pipe_config->splitter.enable) return; - /* Splitter enable is supported for pipe A only. */ - if (drm_WARN_ON(&i915->drm, pipe != PIPE_A)) { + if (drm_WARN_ON(&i915->drm, !(intel_ddi_splitter_pipe_mask(i915) & BIT(pipe)))) { pipe_config->splitter.enable = false; return; } @@ -2301,10 +2309,6 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) return; if (crtc_state->splitter.enable) { - /* Splitter enable is supported for pipe A only. */ - if (drm_WARN_ON(&i915->drm, pipe != PIPE_A)) - return; - dss1 |= SPLITTER_ENABLE; dss1 |= OVERLAP_PIXELS(crtc_state->splitter.pixel_overlap); if (crtc_state->splitter.link_count == 2) @@ -4666,12 +4670,8 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) dig_port->hpd_pulse = intel_dp_hpd_pulse; - /* Splitter enable for eDP MSO is limited to certain pipes. */ - if (dig_port->dp.mso_link_count) { - encoder->pipe_mask = BIT(PIPE_A); - if (IS_ALDERLAKE_P(dev_priv)) - encoder->pipe_mask |= BIT(PIPE_B); - } + if (dig_port->dp.mso_link_count) + encoder->pipe_mask = intel_ddi_splitter_pipe_mask(dev_priv); } /* In theory we don't need the encoder->type check, but leave it just in -- cgit v1.2.3 From 5918241f607616c0cd9565f575f4cd955fa435e0 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 13 Aug 2021 14:56:10 +0300 Subject: drm/i915/mst: use intel_de_rmw() to simplify VC payload alloc set/clear Less is more, fewer lines to wonder about. Cc: Manasi Navare Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210813115610.20010-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 8d13d7b26a25..9859c0334ebc 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -396,7 +396,6 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, to_intel_connector(old_conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); bool last_mst_stream; - u32 val; intel_dp->active_mst_links--; last_mst_stream = intel_dp->active_mst_links == 0; @@ -412,12 +411,8 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, clear_act_sent(encoder, old_crtc_state); - val = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(old_crtc_state->cpu_transcoder)); - val &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC; - intel_de_write(dev_priv, - TRANS_DDI_FUNC_CTL(old_crtc_state->cpu_transcoder), - val); + intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(old_crtc_state->cpu_transcoder), + TRANS_DDI_DP_VC_PAYLOAD_ALLOC, 0); wait_for_act_sent(encoder, old_crtc_state); -- cgit v1.2.3 From 0707570248b8b13008d0fca7cc4f6e1848f0d64f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 13 Aug 2021 14:51:49 +0300 Subject: drm/i915/dp: pass crtc_state to intel_ddi_dp_level() Needed in the future. Cc: Manasi Navare Cc: Matt Roper Reviewed-by: Matt Roper Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210813115151.19290-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index eb9aa871f87b..74b44be5a321 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1371,7 +1371,8 @@ static int translate_signal_level(struct intel_dp *intel_dp, return 0; } -static int intel_ddi_dp_level(struct intel_dp *intel_dp) +static int intel_ddi_dp_level(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { u8 train_set = intel_dp->train_set[0]; u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | @@ -1385,7 +1386,7 @@ dg2_set_signal_levels(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - int level = intel_ddi_dp_level(intel_dp); + int level = intel_ddi_dp_level(intel_dp, crtc_state); intel_snps_phy_ddi_vswing_sequence(encoder, level); } @@ -1395,7 +1396,7 @@ tgl_set_signal_levels(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - int level = intel_ddi_dp_level(intel_dp); + int level = intel_ddi_dp_level(intel_dp, crtc_state); tgl_ddi_vswing_sequence(encoder, crtc_state, level); } @@ -1405,7 +1406,7 @@ icl_set_signal_levels(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - int level = intel_ddi_dp_level(intel_dp); + int level = intel_ddi_dp_level(intel_dp, crtc_state); icl_ddi_vswing_sequence(encoder, crtc_state, level); } @@ -1415,7 +1416,7 @@ bxt_set_signal_levels(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - int level = intel_ddi_dp_level(intel_dp); + int level = intel_ddi_dp_level(intel_dp, crtc_state); bxt_ddi_vswing_sequence(encoder, crtc_state, level); } @@ -1426,7 +1427,7 @@ hsw_set_signal_levels(struct intel_dp *intel_dp, { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - int level = intel_ddi_dp_level(intel_dp); + int level = intel_ddi_dp_level(intel_dp, crtc_state); enum port port = encoder->port; u32 signal_levels; @@ -2332,7 +2333,7 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state, enum phy phy = intel_port_to_phy(dev_priv, encoder->port); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); - int level = intel_ddi_dp_level(intel_dp); + int level = intel_ddi_dp_level(intel_dp, crtc_state); intel_dp_set_link_params(intel_dp, crtc_state->port_clock, crtc_state->lane_count); @@ -2445,7 +2446,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, enum phy phy = intel_port_to_phy(dev_priv, encoder->port); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); - int level = intel_ddi_dp_level(intel_dp); + int level = intel_ddi_dp_level(intel_dp, crtc_state); intel_dp_set_link_params(intel_dp, crtc_state->port_clock, @@ -2588,7 +2589,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, enum phy phy = intel_port_to_phy(dev_priv, port); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); - int level = intel_ddi_dp_level(intel_dp); + int level = intel_ddi_dp_level(intel_dp, crtc_state); if (DISPLAY_VER(dev_priv) < 11) drm_WARN_ON(&dev_priv->drm, -- cgit v1.2.3 From 3b4da8315addfe4661f3c25ea8a83097d965c67a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 13 Aug 2021 14:51:50 +0300 Subject: drm/i915/dg2: use existing mechanisms for SNPS PHY translations We use encoder->get_buf_trans() in many places, for example intel_ddi_dp_voltage_max(), and the hook was set to some old platform's function for DG2 SNPS PHY. Convert SNPS PHY to use the same translation mechanisms as everything else. Cc: Manasi Navare Cc: Matt Roper Reviewed-by: Matt Roper Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210813115151.19290-2-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 6 +-- drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c | 31 ++++++++++- drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h | 7 +++ drivers/gpu/drm/i915/display/intel_snps_phy.c | 61 ++++++---------------- drivers/gpu/drm/i915/display/intel_snps_phy.h | 3 +- 5 files changed, 59 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 74b44be5a321..1ef7a65feb66 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1388,7 +1388,7 @@ dg2_set_signal_levels(struct intel_dp *intel_dp, struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; int level = intel_ddi_dp_level(intel_dp, crtc_state); - intel_snps_phy_ddi_vswing_sequence(encoder, level); + intel_snps_phy_ddi_vswing_sequence(encoder, crtc_state, level); } static void @@ -2392,7 +2392,7 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state, */ /* 5.e Configure voltage swing and related IO settings */ - intel_snps_phy_ddi_vswing_sequence(encoder, level); + intel_snps_phy_ddi_vswing_sequence(encoder, crtc_state, level); /* * 5.f Configure and enable DDI_BUF_CTL @@ -3061,7 +3061,7 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state, connector->base.id, connector->name); if (IS_DG2(dev_priv)) - intel_snps_phy_ddi_vswing_sequence(encoder, U32_MAX); + intel_snps_phy_ddi_vswing_sequence(encoder, crtc_state, level); else if (DISPLAY_VER(dev_priv) >= 12) tgl_ddi_vswing_sequence(encoder, crtc_state, level); else if (DISPLAY_VER(dev_priv) == 11) diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c index ba2c08f1a797..ebb39624bfc9 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c @@ -983,6 +983,25 @@ static const struct intel_ddi_buf_trans adlp_dkl_phy_ddi_translations_dp_hbr2_hb .num_entries = ARRAY_SIZE(_adlp_dkl_phy_ddi_translations_dp_hbr2_hbr3), }; +static const union intel_ddi_buf_trans_entry _dg2_snps_translations[] = { + { .snps = { 26, 0, 0 } }, /* VS 0, pre-emph 0 */ + { .snps = { 33, 0, 6 } }, /* VS 0, pre-emph 1 */ + { .snps = { 38, 0, 12 } }, /* VS 0, pre-emph 2 */ + { .snps = { 43, 0, 19 } }, /* VS 0, pre-emph 3 */ + { .snps = { 39, 0, 0 } }, /* VS 1, pre-emph 0 */ + { .snps = { 44, 0, 8 } }, /* VS 1, pre-emph 1 */ + { .snps = { 47, 0, 15 } }, /* VS 1, pre-emph 2 */ + { .snps = { 52, 0, 0 } }, /* VS 2, pre-emph 0 */ + { .snps = { 51, 0, 10 } }, /* VS 2, pre-emph 1 */ + { .snps = { 62, 0, 0 } }, /* VS 3, pre-emph 0 */ +}; + +static const struct intel_ddi_buf_trans dg2_snps_translations = { + .entries = _dg2_snps_translations, + .num_entries = ARRAY_SIZE(_dg2_snps_translations), + .hdmi_default_entry = ARRAY_SIZE(_dg2_snps_translations) - 1, +}; + bool is_hobl_buf_trans(const struct intel_ddi_buf_trans *table) { return table == &tgl_combo_phy_ddi_translations_edp_hbr2_hobl; @@ -1563,6 +1582,14 @@ adlp_get_dkl_buf_trans(struct intel_encoder *encoder, return adlp_get_dkl_buf_trans_dp(encoder, crtc_state, n_entries); } +static const struct intel_ddi_buf_trans * +dg2_get_snps_buf_trans(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + int *n_entries) +{ + return intel_get_buf_trans(&dg2_snps_translations, n_entries); +} + int intel_ddi_hdmi_num_entries(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, int *default_entry) @@ -1588,7 +1615,9 @@ void intel_ddi_buf_trans_init(struct intel_encoder *encoder) struct drm_i915_private *i915 = to_i915(encoder->base.dev); enum phy phy = intel_port_to_phy(i915, encoder->port); - if (IS_ALDERLAKE_P(i915)) { + if (IS_DG2(i915)) { + encoder->get_buf_trans = dg2_get_snps_buf_trans; + } else if (IS_ALDERLAKE_P(i915)) { if (intel_phy_is_combo(i915, phy)) encoder->get_buf_trans = adlp_get_combo_buf_trans; else diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h index 2acd720f9d4f..94d338287f61 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h @@ -45,12 +45,19 @@ struct tgl_dkl_phy_ddi_buf_trans { u32 dkl_de_emphasis_control; }; +struct dg2_snps_phy_buf_trans { + u8 snps_vswing; + u8 snps_pre_cursor; + u8 snps_post_cursor; +}; + union intel_ddi_buf_trans_entry { struct hsw_ddi_buf_trans hsw; struct bxt_ddi_buf_trans bxt; struct icl_ddi_buf_trans icl; struct icl_mg_phy_ddi_buf_trans mg; struct tgl_dkl_phy_ddi_buf_trans dkl; + struct dg2_snps_phy_buf_trans snps; }; struct intel_ddi_buf_trans { diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c index 18b52b64af95..d81f71296297 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c @@ -5,6 +5,7 @@ #include +#include "intel_ddi_buf_trans.h" #include "intel_de.h" #include "intel_display_types.h" #include "intel_snps_phy.h" @@ -50,58 +51,30 @@ void intel_snps_phy_update_psr_power_state(struct drm_i915_private *dev_priv, SNPS_PHY_TX_REQ_LN_DIS_PWR_STATE_PSR, val); } -static const u32 dg2_ddi_translations[] = { - /* VS 0, pre-emph 0 */ - REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 26), - - /* VS 0, pre-emph 1 */ - REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 33) | - REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 6), - - /* VS 0, pre-emph 2 */ - REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 38) | - REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 12), - - /* VS 0, pre-emph 3 */ - REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 43) | - REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 19), - - /* VS 1, pre-emph 0 */ - REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 39), - - /* VS 1, pre-emph 1 */ - REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 44) | - REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 8), - - /* VS 1, pre-emph 2 */ - REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 47) | - REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 15), - - /* VS 2, pre-emph 0 */ - REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 52), - - /* VS 2, pre-emph 1 */ - REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 51) | - REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 10), - - /* VS 3, pre-emph 0 */ - REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 62), -}; - void intel_snps_phy_ddi_vswing_sequence(struct intel_encoder *encoder, - u32 level) + const struct intel_crtc_state *crtc_state, + int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + const struct intel_ddi_buf_trans *ddi_translations; enum phy phy = intel_port_to_phy(dev_priv, encoder->port); int n_entries, ln; - n_entries = ARRAY_SIZE(dg2_ddi_translations); - if (level >= n_entries) + ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) + return; + if (drm_WARN_ON_ONCE(&dev_priv->drm, level < 0 || level >= n_entries)) level = n_entries - 1; - for (ln = 0; ln < 4; ln++) - intel_de_write(dev_priv, SNPS_PHY_TX_EQ(ln, phy), - dg2_ddi_translations[level]); + for (ln = 0; ln < 4; ln++) { + u32 val = 0; + + val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, ddi_translations->entries[level].snps.snps_vswing); + val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_PRE, ddi_translations->entries[level].snps.snps_pre_cursor); + val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, ddi_translations->entries[level].snps.snps_post_cursor); + + intel_de_write(dev_priv, SNPS_PHY_TX_EQ(ln, phy), val); + } } /* diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.h b/drivers/gpu/drm/i915/display/intel_snps_phy.h index 6261ff88ef5c..a68547a6fee5 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.h +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.h @@ -30,6 +30,7 @@ int intel_mpllb_calc_port_clock(struct intel_encoder *encoder, int intel_snps_phy_check_hdmi_link_rate(int clock); void intel_snps_phy_ddi_vswing_sequence(struct intel_encoder *encoder, - u32 level); + const struct intel_crtc_state *crtc_state, + int level); #endif /* __INTEL_SNPS_PHY_H__ */ -- cgit v1.2.3 From 2817efaeb608421d8f6fe7939826c35a852644e9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 13 Aug 2021 14:51:51 +0300 Subject: drm/i915/dg2: add SNPS PHY translations for UHBR link rates UHBR link rates use different tx equalization settings. Using this will require changes in the link training code too. Bspec: 53920 Cc: Manasi Navare Cc: Matt Roper Reviewed-by: Matt Roper Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210813115151.19290-3-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c index ebb39624bfc9..796dd04eae01 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c @@ -1002,6 +1002,30 @@ static const struct intel_ddi_buf_trans dg2_snps_translations = { .hdmi_default_entry = ARRAY_SIZE(_dg2_snps_translations) - 1, }; +static const union intel_ddi_buf_trans_entry _dg2_snps_translations_uhbr[] = { + { .snps = { 62, 0, 0 } }, /* preset 0 */ + { .snps = { 56, 0, 6 } }, /* preset 1 */ + { .snps = { 51, 0, 11 } }, /* preset 2 */ + { .snps = { 48, 0, 14 } }, /* preset 3 */ + { .snps = { 43, 0, 19 } }, /* preset 4 */ + { .snps = { 59, 3, 0 } }, /* preset 5 */ + { .snps = { 53, 3, 6 } }, /* preset 6 */ + { .snps = { 49, 3, 10 } }, /* preset 7 */ + { .snps = { 45, 3, 14 } }, /* preset 8 */ + { .snps = { 42, 3, 17 } }, /* preset 9 */ + { .snps = { 56, 6, 0 } }, /* preset 10 */ + { .snps = { 50, 6, 6 } }, /* preset 11 */ + { .snps = { 47, 6, 9 } }, /* preset 12 */ + { .snps = { 42, 6, 14 } }, /* preset 13 */ + { .snps = { 46, 8, 8 } }, /* preset 14 */ + { .snps = { 56, 3, 3 } }, /* preset 15 */ +}; + +static const struct intel_ddi_buf_trans dg2_snps_translations_uhbr = { + .entries = _dg2_snps_translations_uhbr, + .num_entries = ARRAY_SIZE(_dg2_snps_translations_uhbr), +}; + bool is_hobl_buf_trans(const struct intel_ddi_buf_trans *table) { return table == &tgl_combo_phy_ddi_translations_edp_hbr2_hobl; @@ -1587,7 +1611,10 @@ dg2_get_snps_buf_trans(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, int *n_entries) { - return intel_get_buf_trans(&dg2_snps_translations, n_entries); + if (crtc_state->port_clock > 1000000) + return intel_get_buf_trans(&dg2_snps_translations_uhbr, n_entries); + else + return intel_get_buf_trans(&dg2_snps_translations, n_entries); } int intel_ddi_hdmi_num_entries(struct intel_encoder *encoder, -- cgit v1.2.3 From d8959fb33890ba1956c142e83398e89812450ffc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 16 Aug 2021 10:17:37 +0300 Subject: drm/i915/dp: remove superfluous EXPORT_SYMBOL() The symbol isn't needed outside of i915.ko. Fixes: b30edfd8d0b4 ("drm/i915: Switch to LTTPR non-transparent mode link training") Fixes: 264613b406eb ("drm/i915: Disable LTTPR support when the DPCD rev < 1.4") Cc: Imre Deak Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210816071737.2917-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 08bceae40aa8..053a3c2f7267 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -206,7 +206,6 @@ int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp) return lttpr_count; } -EXPORT_SYMBOL(intel_dp_init_lttpr_and_dprx_caps); static u8 dp_voltage_max(u8 preemph) { -- cgit v1.2.3 From 7b24b79bf5f9492a63a09d5752af3c155f45f793 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Sat, 14 Aug 2021 18:43:45 -0700 Subject: drm/i915/display: Fix sel fetch plane offset calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit skl_calc_main_surface_offset() is used to calculate an aligned plane surface address considering the inner framebuffer x and y offset. It can not be used by selective fetch functions becase there is no PLANE_SEL_FETCH_SURF. So the PLANE_SEL_FETCH_OFFSET.y should only be PLANE_OFFSET.y + damaged_area_within_plane.y1. This fixes glitches seen in fbcon caused by typing something in the terminal. BSpec: 55229 Reviewed-by: Gwan-gyeong Mun Cc: Gwan-gyeong Mun Cc: Ville Syrjälä Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210815014346.373945-1-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 1b0daf649e82..cade37f67f33 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1487,8 +1487,8 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum pipe pipe = plane->pipe; const struct drm_rect *clip; - u32 val, offset; - int ret, x, y; + u32 val; + int x, y; if (!crtc_state->enable_psr2_sel_fetch) return; @@ -1508,10 +1508,6 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, /* TODO: consider auxiliary surfaces */ x = plane_state->uapi.src.x1 >> 16; y = (plane_state->uapi.src.y1 >> 16) + clip->y1; - ret = skl_calc_main_surface_offset(plane_state, &x, &y, &offset); - if (ret) - drm_warn_once(&dev_priv->drm, "skl_calc_main_surface_offset() returned %i\n", - ret); val = y << 16 | x; intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_OFFSET(pipe, plane->id), val); -- cgit v1.2.3 From bbaafe536c840d962870d33572d3d5f9051550f3 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Sat, 14 Aug 2021 18:43:46 -0700 Subject: drm/i915: Nuke ORIGIN_GTT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no users of it, so no need to keep handling for it. Reviewed-by: Gwan-gyeong Mun Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210815014346.373945-2-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 10 +--------- drivers/gpu/drm/i915/display/intel_frontbuffer.h | 3 +-- 2 files changed, 2 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index ddfc17e21668..e4d412d395c3 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1129,7 +1129,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, if (!HAS_FBC(dev_priv)) return; - if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP) + if (origin == ORIGIN_FLIP) return; mutex_lock(&fbc->lock); @@ -1150,14 +1150,6 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, if (!HAS_FBC(dev_priv)) return; - /* - * GTT tracking does not nuke the entire cfb - * so don't clear busy_bits set for some other - * reason. - */ - if (origin == ORIGIN_GTT) - return; - mutex_lock(&fbc->lock); fbc->busy_bits &= ~frontbuffer_bits; diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.h b/drivers/gpu/drm/i915/display/intel_frontbuffer.h index 6d41f5394425..4b977c1e4d52 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.h +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.h @@ -33,8 +33,7 @@ struct drm_i915_private; enum fb_op_origin { - ORIGIN_GTT, - ORIGIN_CPU, + ORIGIN_CPU = 0, ORIGIN_CS, ORIGIN_FLIP, ORIGIN_DIRTYFB, -- cgit v1.2.3 From dab1b47e57e053b2a02c22ead8e7449f79961335 Mon Sep 17 00:00:00 2001 From: Lee Shawn C Date: Tue, 6 Jul 2021 23:25:41 +0800 Subject: drm/i915/dp: return proper DPRX link training result After DPRX link training, intel_dp_link_train_phy() did not return the training result properly. If link training failed, i915 driver would not run into link train fallback function. And no hotplug uevent would be received by user space application. Fixes: b30edfd8d0b4 ("drm/i915: Switch to LTTPR non-transparent mode link training") Cc: Ville Syrjala Cc: Imre Deak Cc: Jani Nikula Cc: Cooper Chiou Cc: William Tseng Signed-off-by: Lee Shawn C Reviewed-by: Imre Deak Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20210706152541.25021-1-shawn.c.lee@intel.com --- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 053a3c2f7267..508a514c5e37 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -848,7 +848,7 @@ intel_dp_link_train_all_phys(struct intel_dp *intel_dp, } if (ret) - intel_dp_link_train_phy(intel_dp, crtc_state, DP_PHY_DPRX); + ret = intel_dp_link_train_phy(intel_dp, crtc_state, DP_PHY_DPRX); if (intel_dp->set_idle_link_train) intel_dp->set_idle_link_train(intel_dp, crtc_state); -- cgit v1.2.3 From c00e14cd4d3fbc5469d6e367371f9e4786a08c03 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Mon, 16 Aug 2021 13:41:12 -0700 Subject: drm/i915/adl_p: Also disable underrun recovery with MSO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One of the cases that the bspec lists for when underrun recovery must be disabled is "COG;" that note actually refers to eDP multi-segmented operation (MSO). Let's ensure the this additional restriction is honored by the driver. Bspec: 50351 Cc: Ville Syrjälä Fixes: ba3b049f4774 ("drm/i915/adl_p: Allow underrun recovery when possible") Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20210816204112.2960624-1-matthew.d.roper@intel.com Reviewed-by: José Roberto de Souza --- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a257e5dc381c..134a6acbd8fb 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2226,6 +2226,9 @@ static bool underrun_recovery_supported(const struct intel_crtc_state *crtc_stat if (crtc_state->has_psr2) return false; + if (crtc_state->splitter.enable) + return false; + return true; } -- cgit v1.2.3 From 9e6dcf33eda91f49a6adac984115875773d11fba Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Aug 2021 13:11:05 +0300 Subject: drm/i915/irq: reduce inlines to reduce header dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Presumably if the compiler is smart, it does not generate an extra function call to the update functions that are now static. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/594f628740717cda5ef407a26ea03129c22ddc12.1629281426.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 50 ++++++++++++++++++++++++++++++++-------- drivers/gpu/drm/i915/i915_irq.h | 51 ++++++++--------------------------------- 2 files changed, 50 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9bc4f4a8e12e..58a452c3f086 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -359,9 +359,8 @@ void i915_hotplug_interrupt_update(struct drm_i915_private *dev_priv, * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */ -void ilk_update_display_irq(struct drm_i915_private *dev_priv, - u32 interrupt_mask, - u32 enabled_irq_mask) +static void ilk_update_display_irq(struct drm_i915_private *dev_priv, + u32 interrupt_mask, u32 enabled_irq_mask) { u32 new_val; @@ -380,6 +379,16 @@ void ilk_update_display_irq(struct drm_i915_private *dev_priv, } } +void ilk_enable_display_irq(struct drm_i915_private *i915, u32 bits) +{ + ilk_update_display_irq(i915, bits, bits); +} + +void ilk_disable_display_irq(struct drm_i915_private *i915, u32 bits) +{ + ilk_update_display_irq(i915, bits, 0); +} + /** * bdw_update_port_irq - update DE port interrupt * @dev_priv: driver private @@ -419,10 +428,9 @@ static void bdw_update_port_irq(struct drm_i915_private *dev_priv, * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */ -void bdw_update_pipe_irq(struct drm_i915_private *dev_priv, - enum pipe pipe, - u32 interrupt_mask, - u32 enabled_irq_mask) +static void bdw_update_pipe_irq(struct drm_i915_private *dev_priv, + enum pipe pipe, u32 interrupt_mask, + u32 enabled_irq_mask) { u32 new_val; @@ -444,15 +452,27 @@ void bdw_update_pipe_irq(struct drm_i915_private *dev_priv, } } +void bdw_enable_pipe_irq(struct drm_i915_private *i915, + enum pipe pipe, u32 bits) +{ + bdw_update_pipe_irq(i915, pipe, bits, bits); +} + +void bdw_disable_pipe_irq(struct drm_i915_private *i915, + enum pipe pipe, u32 bits) +{ + bdw_update_pipe_irq(i915, pipe, bits, 0); +} + /** * ibx_display_interrupt_update - update SDEIMR * @dev_priv: driver private * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */ -void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, - u32 interrupt_mask, - u32 enabled_irq_mask) +static void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, + u32 interrupt_mask, + u32 enabled_irq_mask) { u32 sdeimr = intel_uncore_read(&dev_priv->uncore, SDEIMR); sdeimr &= ~interrupt_mask; @@ -469,6 +489,16 @@ void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, intel_uncore_posting_read(&dev_priv->uncore, SDEIMR); } +void ibx_enable_display_interrupt(struct drm_i915_private *i915, u32 bits) +{ + ibx_display_interrupt_update(i915, bits, bits); +} + +void ibx_disable_display_interrupt(struct drm_i915_private *i915, u32 bits) +{ + ibx_display_interrupt_update(i915, bits, 0); +} + u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv, enum pipe pipe) { diff --git a/drivers/gpu/drm/i915/i915_irq.h b/drivers/gpu/drm/i915/i915_irq.h index e43b6734f21b..0eb90d271fa7 100644 --- a/drivers/gpu/drm/i915/i915_irq.h +++ b/drivers/gpu/drm/i915/i915_irq.h @@ -9,9 +9,9 @@ #include #include -#include "display/intel_display.h" #include "i915_reg.h" +enum pipe; struct drm_crtc; struct drm_device; struct drm_display_mode; @@ -40,46 +40,15 @@ void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv); void i915_hotplug_interrupt_update(struct drm_i915_private *dev_priv, u32 mask, u32 bits); -void ilk_update_display_irq(struct drm_i915_private *dev_priv, - u32 interrupt_mask, - u32 enabled_irq_mask); -static inline void -ilk_enable_display_irq(struct drm_i915_private *dev_priv, u32 bits) -{ - ilk_update_display_irq(dev_priv, bits, bits); -} -static inline void -ilk_disable_display_irq(struct drm_i915_private *dev_priv, u32 bits) -{ - ilk_update_display_irq(dev_priv, bits, 0); -} -void bdw_update_pipe_irq(struct drm_i915_private *dev_priv, - enum pipe pipe, - u32 interrupt_mask, - u32 enabled_irq_mask); -static inline void bdw_enable_pipe_irq(struct drm_i915_private *dev_priv, - enum pipe pipe, u32 bits) -{ - bdw_update_pipe_irq(dev_priv, pipe, bits, bits); -} -static inline void bdw_disable_pipe_irq(struct drm_i915_private *dev_priv, - enum pipe pipe, u32 bits) -{ - bdw_update_pipe_irq(dev_priv, pipe, bits, 0); -} -void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, - u32 interrupt_mask, - u32 enabled_irq_mask); -static inline void -ibx_enable_display_interrupt(struct drm_i915_private *dev_priv, u32 bits) -{ - ibx_display_interrupt_update(dev_priv, bits, bits); -} -static inline void -ibx_disable_display_interrupt(struct drm_i915_private *dev_priv, u32 bits) -{ - ibx_display_interrupt_update(dev_priv, bits, 0); -} + +void ilk_enable_display_irq(struct drm_i915_private *i915, u32 bits); +void ilk_disable_display_irq(struct drm_i915_private *i915, u32 bits); + +void bdw_enable_pipe_irq(struct drm_i915_private *i915, enum pipe pipe, u32 bits); +void bdw_disable_pipe_irq(struct drm_i915_private *i915, enum pipe pipe, u32 bits); + +void ibx_enable_display_interrupt(struct drm_i915_private *i915, u32 bits); +void ibx_disable_display_interrupt(struct drm_i915_private *i915, u32 bits); void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, u32 mask); void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, u32 mask); -- cgit v1.2.3 From 4b5777af5bb17398c7764c8f3b66f344b5a5cb6f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Aug 2021 13:11:06 +0300 Subject: drm/i915: intel_runtime_pm.h does not actually need intel_display.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce includes. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/289a6837379c4422395c3ac2b36a6c2a44110227.1629281426.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_runtime_pm.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.h b/drivers/gpu/drm/i915/intel_runtime_pm.h index 183ea2b187fe..47a85fab4130 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.h +++ b/drivers/gpu/drm/i915/intel_runtime_pm.h @@ -8,8 +8,6 @@ #include -#include "display/intel_display.h" - #include "intel_wakeref.h" #include "i915_utils.h" -- cgit v1.2.3 From 8e6b13a7b298edec16fb05aca0200ad400c9d1ea Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Aug 2021 13:11:07 +0300 Subject: drm/i915/pm: use forward declaration to remove an include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fewer includes the better. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/dcb426e4c6497f9ee3356c5f4fd4aaabd6295262.1629281426.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_pm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h index 91f23b7f0af2..941b3ae555c8 100644 --- a/drivers/gpu/drm/i915/intel_pm.h +++ b/drivers/gpu/drm/i915/intel_pm.h @@ -8,7 +8,6 @@ #include -#include "display/intel_bw.h" #include "display/intel_display.h" #include "display/intel_global_state.h" @@ -19,6 +18,7 @@ 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; -- cgit v1.2.3 From 3c6a4a02c92af14a0325ede88bdbccc0ccd19241 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Aug 2021 13:11:08 +0300 Subject: drm/i915/panel: move intel_panel_use_ssc() out of headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no performance reason to have it as static inline; move it out of intel_display_types.h to reduce clutter and dependency on i915_drv.h. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/6f2c05005e4fa43a5572b02b3f41363725ffdb4f.1629281426.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 1 + drivers/gpu/drm/i915/display/intel_display_types.h | 8 -------- drivers/gpu/drm/i915/display/intel_panel.c | 8 ++++++++ drivers/gpu/drm/i915/display/intel_panel.h | 1 + 4 files changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 134a6acbd8fb..2bf41e690f6d 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -92,6 +92,7 @@ #include "intel_hdcp.h" #include "intel_hotplug.h" #include "intel_overlay.h" +#include "intel_panel.h" #include "intel_pipe_crc.h" #include "intel_pm.h" #include "intel_pps.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 6beeeeba1bed..7b5d7b1ae501 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -2035,14 +2035,6 @@ to_intel_frontbuffer(struct drm_framebuffer *fb) return fb ? to_intel_framebuffer(fb)->frontbuffer : NULL; } -static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) -{ - if (dev_priv->params.panel_use_ssc >= 0) - return dev_priv->params.panel_use_ssc != 0; - return dev_priv->vbt.lvds_use_ssc - && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE); -} - static inline u32 i9xx_dpll_compute_fp(struct dpll *dpll) { return dpll->n << 16 | dpll->m1 << 8 | dpll->m2; diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index 7d7a60b4d2de..074a55f20bcd 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -41,6 +41,14 @@ #include "intel_dsi_dcs_backlight.h" #include "intel_panel.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); +} + void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode) diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_panel.h index 1d340f77bffc..d638c2b47c92 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.h +++ b/drivers/gpu/drm/i915/display/intel_panel.h @@ -25,6 +25,7 @@ int intel_panel_init(struct intel_panel *panel, void intel_panel_fini(struct intel_panel *panel); enum drm_connector_status intel_panel_detect(struct drm_connector *connector, bool force); +bool intel_panel_use_ssc(struct drm_i915_private *i915); void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode); int intel_pch_panel_fitting(struct intel_crtc_state *crtc_state, -- cgit v1.2.3 From 63aef47b3eb52447716b2f2cf69eaca338e3576e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 Aug 2021 13:11:09 +0300 Subject: drm/i915/fdi: move intel_fdi_link_freq() to intel_fdi.[ch] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no performance reason to have it as static inline; move it out of intel_display_types.h to reduce clutter and dependency on i915_drv.h. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/8c9bb23d92878deb1ecc75427ec6648bd3505816.1629281426.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 9 --------- drivers/gpu/drm/i915/display/intel_fdi.c | 9 +++++++++ drivers/gpu/drm/i915/display/intel_fdi.h | 4 ++++ 3 files changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 7b5d7b1ae501..c2725d07b930 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -2040,15 +2040,6 @@ static inline u32 i9xx_dpll_compute_fp(struct dpll *dpll) return dpll->n << 16 | dpll->m1 << 8 | dpll->m2; } -static inline u32 intel_fdi_link_freq(struct drm_i915_private *dev_priv, - const struct intel_crtc_state *pipe_config) -{ - if (HAS_DDI(dev_priv)) - return pipe_config->port_clock; /* SPLL */ - else - return dev_priv->fdi_pll_freq; -} - static inline bool is_ccs_modifier(u64 modifier) { return modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS || diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index e10b9cd8e86e..970a57369b05 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -95,6 +95,15 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, } } +u32 intel_fdi_link_freq(struct drm_i915_private *i915, + const struct intel_crtc_state *pipe_config) +{ + if (HAS_DDI(i915)) + return pipe_config->port_clock; /* SPLL */ + else + return i915->fdi_pll_freq; +} + int ilk_fdi_compute_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { diff --git a/drivers/gpu/drm/i915/display/intel_fdi.h b/drivers/gpu/drm/i915/display/intel_fdi.h index af01d2c173a8..fd63a6a53fca 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.h +++ b/drivers/gpu/drm/i915/display/intel_fdi.h @@ -6,12 +6,16 @@ #ifndef _INTEL_FDI_H_ #define _INTEL_FDI_H_ +#include + struct drm_i915_private; struct intel_crtc; struct intel_crtc_state; struct intel_encoder; #define I915_DISPLAY_CONFIG_RETRY 1 +u32 intel_fdi_link_freq(struct drm_i915_private *i915, + const struct intel_crtc_state *pipe_config); int ilk_fdi_compute_config(struct intel_crtc *intel_crtc, struct intel_crtc_state *pipe_config); void intel_fdi_normal_train(struct intel_crtc *crtc); -- cgit v1.2.3 From faca22fd5061c80ac9f5fd36dbcb174336cfbd33 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 2 Jul 2021 23:45:56 +0300 Subject: drm/i915/fbc: Rewrite the FBC tiling check a bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Write the tiling check in a nicer form. No functional changes due to Y-tile scanout being a gen9+ feature. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210702204603.596-2-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index e4d412d395c3..c4552e8395a0 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -675,11 +675,9 @@ static bool tiling_is_valid(struct drm_i915_private *dev_priv, { switch (modifier) { case DRM_FORMAT_MOD_LINEAR: - if (DISPLAY_VER(dev_priv) >= 9) - return true; - return false; - case I915_FORMAT_MOD_X_TILED: case I915_FORMAT_MOD_Y_TILED: + return DISPLAY_VER(dev_priv) >= 9; + case I915_FORMAT_MOD_X_TILED: return true; default: return false; -- cgit v1.2.3 From 287d00d4131e8134bc442db0863b289d86bdae8b Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 2 Jul 2021 23:45:57 +0300 Subject: drm/i915/fbc: Extract intel_fbc_update() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull the fbc enable vs. disable stuff into a small helper so we don't have to have it pollute the higher level modeset code. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210702204603.596-3-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 5 +---- drivers/gpu/drm/i915/display/intel_fbc.c | 26 ++++++++++++++++++++++++-- drivers/gpu/drm/i915/display/intel_fbc.h | 2 +- 3 files changed, 26 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 2bf41e690f6d..a7cba75babd3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -10405,10 +10405,7 @@ static void intel_update_crtc(struct intel_atomic_state *state, intel_encoders_update_pipe(state, crtc); } - if (new_crtc_state->update_pipe && !new_crtc_state->enable_fbc) - intel_fbc_disable(crtc); - else - intel_fbc_enable(state, crtc); + intel_fbc_update(state, crtc); /* Perform vblank evasion around commit operation */ intel_pipe_update_start(new_crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index c4552e8395a0..49b8c061bfa8 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1236,8 +1236,8 @@ out: * intel_fbc_enable multiple times for the same pipe without an * intel_fbc_disable in the middle, as long as it is deactivated. */ -void intel_fbc_enable(struct intel_atomic_state *state, - struct intel_crtc *crtc) +static void intel_fbc_enable(struct intel_atomic_state *state, + struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_plane *plane = to_intel_plane(crtc->base.primary); @@ -1312,6 +1312,28 @@ void intel_fbc_disable(struct intel_crtc *crtc) mutex_unlock(&fbc->lock); } +/** + * intel_fbc_update: enable/disable FBC on the CRTC + * @state: atomic state + * @crtc: the CRTC + * + * This function checks if the given CRTC was chosen for FBC, then enables it if + * possible. Notice that it doesn't activate FBC. It is valid to call + * intel_fbc_update multiple times for the same pipe without an + * intel_fbc_disable in the middle. + */ +void intel_fbc_update(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + const struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + + if (crtc_state->update_pipe && !crtc_state->enable_fbc) + intel_fbc_disable(crtc); + else + intel_fbc_enable(state, crtc); +} + /** * intel_fbc_global_disable - globally disable FBC * @dev_priv: i915 device instance diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h index 6dc1edefe81b..b97d908738e6 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.h +++ b/drivers/gpu/drm/i915/display/intel_fbc.h @@ -24,7 +24,7 @@ bool intel_fbc_pre_update(struct intel_atomic_state *state, void intel_fbc_post_update(struct intel_atomic_state *state, struct intel_crtc *crtc); void intel_fbc_init(struct drm_i915_private *dev_priv); -void intel_fbc_enable(struct intel_atomic_state *state, +void intel_fbc_update(struct intel_atomic_state *state, struct intel_crtc *crtc); void intel_fbc_disable(struct intel_crtc *crtc); void intel_fbc_global_disable(struct drm_i915_private *dev_priv); -- cgit v1.2.3 From cd4891e4f78b1ed77e86500d9dc69262b25b56e4 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 2 Jul 2021 23:45:58 +0300 Subject: drm/i915/fbc: Move the "recompress on activate" to a central place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On ILK+ we current do a nuke right after activating FBC. If my memory isn't playing tricks on me this is actially required if FBC didn't stay disabled for a full frame. In that case the deactivate+reactivate may not invalidate the cfb. I'd have to double chekc to be sure though. So let's keep the nuke, and just extend it backwards to cover all the platforms by doing it a bit higher up. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210702204603.596-4-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 49b8c061bfa8..579edde10eb7 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -232,16 +232,16 @@ static void i965_fbc_recompress(struct drm_i915_private *dev_priv) /* This function forces a CFB recompression through the nuke operation. */ static void snb_fbc_recompress(struct drm_i915_private *dev_priv) { - struct intel_fbc *fbc = &dev_priv->fbc; - - trace_intel_fbc_nuke(fbc->crtc); - intel_de_write(dev_priv, MSG_FBC_REND_STATE, FBC_REND_NUKE); intel_de_posting_read(dev_priv, MSG_FBC_REND_STATE); } static void intel_fbc_recompress(struct drm_i915_private *dev_priv) { + struct intel_fbc *fbc = &dev_priv->fbc; + + trace_intel_fbc_nuke(fbc->crtc); + if (DISPLAY_VER(dev_priv) >= 6) snb_fbc_recompress(dev_priv); else if (DISPLAY_VER(dev_priv) >= 4) @@ -280,8 +280,6 @@ static void ilk_fbc_activate(struct drm_i915_private *dev_priv) params->fence_y_offset); /* enable it... */ intel_de_write(dev_priv, ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); - - intel_fbc_recompress(dev_priv); } static void ilk_fbc_deactivate(struct drm_i915_private *dev_priv) @@ -339,8 +337,6 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv) dpfc_ctl |= FBC_CTL_FALSE_COLOR; intel_de_write(dev_priv, ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); - - intel_fbc_recompress(dev_priv); } static bool intel_fbc_hw_is_active(struct drm_i915_private *dev_priv) @@ -402,6 +398,12 @@ bool intel_fbc_is_active(struct drm_i915_private *dev_priv) return dev_priv->fbc.active; } +static void intel_fbc_activate(struct drm_i915_private *dev_priv) +{ + intel_fbc_hw_activate(dev_priv); + intel_fbc_recompress(dev_priv); +} + static void intel_fbc_deactivate(struct drm_i915_private *dev_priv, const char *reason) { @@ -1088,7 +1090,7 @@ static void __intel_fbc_post_update(struct intel_crtc *crtc) return; if (!fbc->busy_bits) - intel_fbc_hw_activate(dev_priv); + intel_fbc_activate(dev_priv); else intel_fbc_deactivate(dev_priv, "frontbuffer write"); } -- cgit v1.2.3 From 2670ff5c72870646c5dd086f63887ab411ed44ee Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 2 Jul 2021 23:45:59 +0300 Subject: drm/i915/fbc: Polish the skl+ FBC stride override handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Polish the FBC stride override stuff: - just call it override_cfb_stride since it'll be used on more gens later - Use REG_BIT() & co. for the registers and give everything CHICKEN_ prefix since glk+ will have a different register for this - Use intel_de_rmw() for the RMW Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210702204603.596-5-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_fbc.c | 27 ++++++++++++++------------- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- drivers/gpu/drm/i915/i915_reg.h | 5 +++-- 3 files changed, 19 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 579edde10eb7..b1c1a23c36be 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -306,14 +306,15 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv) /* Display WA #0529: skl, kbl, bxt. */ if (DISPLAY_VER(dev_priv) == 9) { - u32 val = intel_de_read(dev_priv, CHICKEN_MISC_4); + u32 val = 0; - val &= ~(FBC_STRIDE_OVERRIDE | FBC_STRIDE_MASK); + if (params->override_cfb_stride) + val |= CHICKEN_FBC_STRIDE_OVERRIDE | + CHICKEN_FBC_STRIDE(params->override_cfb_stride); - if (params->gen9_wa_cfb_stride) - val |= FBC_STRIDE_OVERRIDE | params->gen9_wa_cfb_stride; - - intel_de_write(dev_priv, CHICKEN_MISC_4, val); + intel_de_rmw(dev_priv, CHICKEN_MISC_4, + CHICKEN_FBC_STRIDE_OVERRIDE | + CHICKEN_FBC_STRIDE_MASK, val); } dpfc_ctl = 0; @@ -749,7 +750,7 @@ static bool intel_fbc_cfb_size_changed(struct drm_i915_private *dev_priv) fbc->compressed_fb.size * fbc->limit; } -static u16 intel_fbc_gen9_wa_cfb_stride(struct drm_i915_private *dev_priv) +static u16 intel_fbc_override_cfb_stride(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_state_cache *cache = &fbc->state_cache; @@ -761,11 +762,11 @@ static u16 intel_fbc_gen9_wa_cfb_stride(struct drm_i915_private *dev_priv) return 0; } -static bool intel_fbc_gen9_wa_cfb_stride_changed(struct drm_i915_private *dev_priv) +static bool intel_fbc_override_cfb_stride_changed(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; - return fbc->params.gen9_wa_cfb_stride != intel_fbc_gen9_wa_cfb_stride(dev_priv); + return fbc->params.override_cfb_stride != intel_fbc_override_cfb_stride(dev_priv); } static bool intel_fbc_can_enable(struct drm_i915_private *dev_priv) @@ -950,7 +951,7 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc, params->cfb_size = intel_fbc_calculate_cfb_size(dev_priv, cache); - params->gen9_wa_cfb_stride = cache->gen9_wa_cfb_stride; + params->override_cfb_stride = cache->override_cfb_stride; params->plane_visible = cache->plane.visible; } @@ -984,7 +985,7 @@ static bool intel_fbc_can_flip_nuke(const struct intel_crtc_state *crtc_state) if (params->cfb_size != intel_fbc_calculate_cfb_size(dev_priv, cache)) return false; - if (params->gen9_wa_cfb_stride != cache->gen9_wa_cfb_stride) + if (params->override_cfb_stride != cache->override_cfb_stride) return false; return true; @@ -1258,7 +1259,7 @@ static void intel_fbc_enable(struct intel_atomic_state *state, if (fbc->crtc) { if (fbc->crtc != crtc || (!intel_fbc_cfb_size_changed(dev_priv) && - !intel_fbc_gen9_wa_cfb_stride_changed(dev_priv))) + !intel_fbc_override_cfb_stride_changed(dev_priv))) goto out; __intel_fbc_disable(dev_priv); @@ -1280,7 +1281,7 @@ static void intel_fbc_enable(struct intel_atomic_state *state, goto out; } - cache->gen9_wa_cfb_stride = intel_fbc_gen9_wa_cfb_stride(dev_priv); + cache->override_cfb_stride = intel_fbc_override_cfb_stride(dev_priv); drm_dbg_kms(&dev_priv->drm, "Enabling FBC on pipe %c\n", pipe_name(crtc->pipe)); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 005b1cec7007..0a2b63072ff5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -454,7 +454,7 @@ struct intel_fbc { } fb; unsigned int fence_y_offset; - u16 gen9_wa_cfb_stride; + u16 override_cfb_stride; u16 interval; s8 fence_id; bool psr2_active; @@ -481,7 +481,7 @@ struct intel_fbc { int cfb_size; unsigned int fence_y_offset; - u16 gen9_wa_cfb_stride; + u16 override_cfb_stride; u16 interval; s8 fence_id; bool plane_visible; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 664970f2bc62..ce518ecd77cf 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8176,8 +8176,9 @@ enum { #define GLK_CL0_PWR_DOWN (1 << 10) #define CHICKEN_MISC_4 _MMIO(0x4208c) -#define FBC_STRIDE_OVERRIDE (1 << 13) -#define FBC_STRIDE_MASK 0x1FFF +#define CHICKEN_FBC_STRIDE_OVERRIDE REG_BIT(13) +#define CHICKEN_FBC_STRIDE_MASK REG_GENMASK(12, 0) +#define CHICKEN_FBC_STRIDE(x) REG_FIELD_PREP(CHICKEN_FBC_STRIDE_MASK, (x)) #define _CHICKEN_PIPESL_1_A 0x420b0 #define _CHICKEN_PIPESL_1_B 0x420b4 -- cgit v1.2.3 From d7f213c131adf0bec8b731553eb82990cdac265d Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Fri, 20 Aug 2021 15:52:59 +0800 Subject: drm/i915/dp: Use max params for panels < eDP 1.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Users reported that after commit 2bbd6dba84d4 ("drm/i915: Try to use fast+narrow link on eDP again and fall back to the old max strategy on failure"), the screen starts to have wobbly effect. Commit a5c936add6a2 ("drm/i915/dp: Use slow and wide link training for everything") doesn't help either, that means the affected eDP 1.2 panels only work with max params. So use max params for panels < eDP 1.4 as Windows does to solve the issue. v3: - Do the eDP rev check in intel_edp_init_dpcd() v2: - Check eDP 1.4 instead of DPCD 1.1 to apply max params Cc: stable@vger.kernel.org Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/3714 Fixes: 2bbd6dba84d4 ("drm/i915: Try to use fast+narrow link on eDP again and fall back to the old max strategy on failure") Fixes: a5c936add6a2 ("drm/i915/dp: Use slow and wide link training for everything") Suggested-by: Ville Syrjälä Signed-off-by: Kai-Heng Feng Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210820075301.693099-1-kai.heng.feng@canonical.com --- drivers/gpu/drm/i915/display/intel_dp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 75d4ebc66941..e0dbd35ae7bc 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2445,11 +2445,14 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp) */ if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV, intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd)) == - sizeof(intel_dp->edp_dpcd)) + sizeof(intel_dp->edp_dpcd)) { drm_dbg_kms(&dev_priv->drm, "eDP DPCD: %*ph\n", (int)sizeof(intel_dp->edp_dpcd), intel_dp->edp_dpcd); + intel_dp->use_max_params = intel_dp->edp_dpcd[0] < DP_EDP_14; + } + /* * This has to be called after intel_dp->edp_dpcd is filled, PSR checks * for SET_POWER_CAPABLE bit in intel_dp->edp_dpcd[1] -- cgit v1.2.3 From f5b21c2e3da4594140b916dfed0e007d3fe8267c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 19:18:06 +0300 Subject: drm/i915/dp: use actual link rate values in struct link_config_limits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MST code uses actual link rates in the limits struct, while the DP code in general uses indexes to the ->common_rates[] array. Fix the confusion by using actual link rate values everywhere. This is a better abstraction than some obscure index. Rename the struct members while at it to ensure all the places are covered. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/d70ab7261abacd367d3a6a47102575eb88a55cd4.1629735412.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 30 ++++++++++++++++------------- drivers/gpu/drm/i915/display/intel_dp.h | 2 +- drivers/gpu/drm/i915/display/intel_dp_mst.c | 6 +++--- 3 files changed, 21 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index e0dbd35ae7bc..b21dac19ae76 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1044,7 +1044,8 @@ intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, intel_dp->num_common_rates, intel_dp->compliance.test_link_rate); if (index >= 0) - limits->min_clock = limits->max_clock = index; + limits->min_rate = limits->max_rate = + intel_dp->compliance.test_link_rate; limits->min_lane_count = limits->max_lane_count = intel_dp->compliance.test_lane_count; } @@ -1058,8 +1059,8 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, const struct link_config_limits *limits) { struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; - int bpp, clock, lane_count; - int mode_rate, link_clock, link_avail; + int bpp, i, lane_count; + 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); @@ -1067,18 +1068,22 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, output_bpp); - for (clock = limits->min_clock; clock <= limits->max_clock; clock++) { + for (i = 0; i < intel_dp->num_common_rates; i++) { + link_rate = intel_dp->common_rates[i]; + if (link_rate < limits->min_rate || + link_rate > limits->max_rate) + continue; + for (lane_count = limits->min_lane_count; lane_count <= limits->max_lane_count; lane_count <<= 1) { - link_clock = intel_dp->common_rates[clock]; - link_avail = intel_dp_max_data_rate(link_clock, + link_avail = intel_dp_max_data_rate(link_rate, lane_count); if (mode_rate <= link_avail) { pipe_config->lane_count = lane_count; pipe_config->pipe_bpp = bpp; - pipe_config->port_clock = link_clock; + pipe_config->port_clock = link_rate; return 0; } @@ -1212,7 +1217,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, * with DSC enabled for the requested mode. */ pipe_config->pipe_bpp = pipe_bpp; - pipe_config->port_clock = intel_dp->common_rates[limits->max_clock]; + pipe_config->port_clock = limits->max_rate; pipe_config->lane_count = limits->max_lane_count; if (intel_dp_is_edp(intel_dp)) { @@ -1321,8 +1326,8 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, /* No common link rates between source and sink */ drm_WARN_ON(encoder->base.dev, common_len <= 0); - limits.min_clock = 0; - limits.max_clock = common_len - 1; + limits.min_rate = intel_dp->common_rates[0]; + limits.max_rate = intel_dp->common_rates[common_len - 1]; limits.min_lane_count = 1; limits.max_lane_count = intel_dp_max_lane_count(intel_dp); @@ -1340,15 +1345,14 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, * values correspond to the native resolution of the panel. */ limits.min_lane_count = limits.max_lane_count; - limits.min_clock = limits.max_clock; + limits.min_rate = limits.max_rate; } intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits); drm_dbg_kms(&i915->drm, "DP link computation with max lane count %i " "max rate %d max bpp %d pixel clock %iKHz\n", - limits.max_lane_count, - intel_dp->common_rates[limits.max_clock], + limits.max_lane_count, limits.max_rate, limits.max_bpp, adjusted_mode->crtc_clock); if ((adjusted_mode->crtc_clock > i915->max_dotclk_freq || diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 680631b5b437..1345d588fc6d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -26,7 +26,7 @@ struct intel_dp; struct intel_encoder; struct link_config_limits { - int min_clock, max_clock; + int min_rate, max_rate; int min_lane_count, max_lane_count; int min_bpp, max_bpp; }; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 9859c0334ebc..d104441344c0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -61,7 +61,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, int bpp, slots = -EINVAL; crtc_state->lane_count = limits->max_lane_count; - crtc_state->port_clock = limits->max_clock; + crtc_state->port_clock = limits->max_rate; for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) { crtc_state->pipe_bpp = bpp; @@ -131,8 +131,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, * for MST we always configure max link bw - the spec doesn't * seem to suggest we should do otherwise. */ - limits.min_clock = - limits.max_clock = intel_dp_max_link_rate(intel_dp); + limits.min_rate = + limits.max_rate = intel_dp_max_link_rate(intel_dp); limits.min_lane_count = limits.max_lane_count = intel_dp_max_lane_count(intel_dp); -- cgit v1.2.3 From 9ab29e1501595975b89692207b22b59b9308e9eb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 19:18:07 +0300 Subject: drm/i915/dp: read sink UHBR rates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See if sink supports DP 2.0 128b/132b channel encoding, and update sink rates accordingly. FIXME: Also take LTTPR 128b/132b into account. v2: Add build-time check for ->sink_rates size (Ville) Reviewed-by: Manasi Navare Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/089d807e887d308c52c84cf58dfb6777de18872d.1629735412.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index b21dac19ae76..3a701728e47e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -141,6 +141,26 @@ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp) intel_dp->sink_rates[i] = dp_rates[i]; } + /* + * Sink rates for 128b/132b. If set, sink should support all 8b/10b + * rates and 10 Gbps. + */ + if (intel_dp->dpcd[DP_MAIN_LINK_CHANNEL_CODING] & DP_CAP_ANSI_128B132B) { + u8 uhbr_rates = 0; + + BUILD_BUG_ON(ARRAY_SIZE(intel_dp->sink_rates) < ARRAY_SIZE(dp_rates) + 3); + + drm_dp_dpcd_readb(&intel_dp->aux, + DP_128B132B_SUPPORTED_LINK_RATES, &uhbr_rates); + + if (uhbr_rates & DP_UHBR10) + intel_dp->sink_rates[i++] = 1000000; + if (uhbr_rates & DP_UHBR13_5) + intel_dp->sink_rates[i++] = 1350000; + if (uhbr_rates & DP_UHBR20) + intel_dp->sink_rates[i++] = 2000000; + } + intel_dp->num_sink_rates = i; } -- cgit v1.2.3 From 59821ed9c4a63de051042d71526d7bb4eac0617b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 19:18:08 +0300 Subject: drm/i915/dg2: add TRANS_DP2_CTL register definition This register controls the DP 2.0 datapath. Bspec: 69967 Reviewed-by: Manasi Navare Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/0d3529df4501c5dd8ad1da0b6dbaabcfa97510b4.1629735412.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ce518ecd77cf..9498852c14dd 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9097,6 +9097,15 @@ enum { #define TRANS_DP_HSYNC_ACTIVE_LOW 0 #define TRANS_DP_SYNC_MASK (3 << 3) +#define _TRANS_DP2_CTL_A 0x600a0 +#define _TRANS_DP2_CTL_B 0x610a0 +#define _TRANS_DP2_CTL_C 0x620a0 +#define _TRANS_DP2_CTL_D 0x630a0 +#define TRANS_DP2_CTL(trans) _MMIO_TRANS(trans, _TRANS_DP2_CTL_A, _TRANS_DP2_CTL_B) +#define TRANS_DP2_128B132B_CHANNEL_CODING REG_BIT(31) +#define TRANS_DP2_PANEL_REPLAY_ENABLE REG_BIT(30) +#define TRANS_DP2_DEBUG_ENABLE REG_BIT(23) + /* SNB eDP training params */ /* SNB A-stepping */ #define EDP_LINK_TRAIN_400MV_0DB_SNB_A (0x38 << 22) -- cgit v1.2.3 From 1db18260f15315e206469391d5b5e3427be55ad3 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 19:18:10 +0300 Subject: drm/i915/dg2: add TRANS_DP2_VFREQHIGH and TRANS_DP2_VFREQLOW Add the registers for specifying the lower and higher 24 bits of the DP 2.0 pixel clock frequency in Hz. Bspec: 53326 Reviewed-by: Manasi Navare Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/9047f10318a30bc03ce8516ee3f5512437a95663.1629735412.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 9498852c14dd..d5177c7655b3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9106,6 +9106,20 @@ enum { #define TRANS_DP2_PANEL_REPLAY_ENABLE REG_BIT(30) #define TRANS_DP2_DEBUG_ENABLE REG_BIT(23) +#define _TRANS_DP2_VFREQHIGH_A 0x600a4 +#define _TRANS_DP2_VFREQHIGH_B 0x610a4 +#define _TRANS_DP2_VFREQHIGH_C 0x620a4 +#define _TRANS_DP2_VFREQHIGH_D 0x630a4 +#define TRANS_DP2_VFREQHIGH(trans) _MMIO_TRANS(trans, _TRANS_DP2_VFREQHIGH_A, _TRANS_DP2_VFREQHIGH_B) +#define TRANS_DP2_VFREQ_PIXEL_CLOCK_MASK REG_GENMASK(31, 8) +#define TRANS_DP2_VFREQ_PIXEL_CLOCK(clk_hz) REG_FIELD_PREP(TRANS_DP2_VFREQ_PIXEL_CLOCK_MASK, (clk_hz)) + +#define _TRANS_DP2_VFREQLOW_A 0x600a8 +#define _TRANS_DP2_VFREQLOW_B 0x610a8 +#define _TRANS_DP2_VFREQLOW_C 0x620a8 +#define _TRANS_DP2_VFREQLOW_D 0x630a8 +#define TRANS_DP2_VFREQLOW(trans) _MMIO_TRANS(trans, _TRANS_DP2_VFREQLOW_A, _TRANS_DP2_VFREQLOW_B) + /* SNB eDP training params */ /* SNB A-stepping */ #define EDP_LINK_TRAIN_400MV_0DB_SNB_A (0x38 << 22) -- cgit v1.2.3 From e752d1f9c14a61b0996bdbcaf024ef587c6af9d8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 19:18:11 +0300 Subject: drm/i915/dg2: add DG2 UHBR source rates DG2 supports DP 2.0 UHBR and 128b/132b channel encoding. Bspec: 53657, 54034 Acked-by: Manasi Navare Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/8f82b7eb76f20f1c4ddd2cc7d1bb31e2173c55a6.1629735412.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 3a701728e47e..1a0eb4c4d666 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -242,6 +242,11 @@ bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp) encoder->port != PORT_A); } +static int dg2_max_source_rate(struct intel_dp *intel_dp) +{ + return intel_dp_is_edp(intel_dp) ? 810000 : 1350000; +} + static int icl_max_source_rate(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); @@ -268,7 +273,8 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp) { /* The values must be in increasing order */ static const int icl_rates[] = { - 162000, 216000, 270000, 324000, 432000, 540000, 648000, 810000 + 162000, 216000, 270000, 324000, 432000, 540000, 648000, 810000, + 1000000, 1350000, }; static const int bxt_rates[] = { 162000, 216000, 243000, 270000, 324000, 432000, 540000 @@ -295,6 +301,8 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp) if (DISPLAY_VER(dev_priv) >= 11) { source_rates = icl_rates; size = ARRAY_SIZE(icl_rates); + if (IS_DG2(dev_priv)) + max_rate = dg2_max_source_rate(intel_dp); if (IS_JSL_EHL(dev_priv)) max_rate = ehl_max_source_rate(intel_dp); else -- cgit v1.2.3 From 48efd014f0ea898b0975e77156acb752047d4449 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 19:18:12 +0300 Subject: drm/i915/dp: add max data rate calculation for UHBR rates DP 2.0 UHBR link rates always use 128b/132b channel encoding, which has a different data bandwidth efficiency from 8b/10b. The computation is slightly convoluted due to the units we use; this is all explained in the added comment. v2: Clarified comment (Manasi) Reviewed-by: Manasi Navare Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/8afd8d97a04c2d86c2dcadfed9f8e1f84272a13c.1629735412.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 52 +++++++++++++++++++++++++++++---- drivers/gpu/drm/i915/display/intel_dp.h | 2 +- 2 files changed, 47 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 1a0eb4c4d666..7e5d9b959c1d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -212,6 +212,10 @@ int intel_dp_max_lane_count(struct intel_dp *intel_dp) return intel_dp->max_link_lane_count; } +/* + * The required data bandwidth for a mode with given pixel clock and bpp. This + * is the required net bandwidth independent of the data bandwidth efficiency. + */ int intel_dp_link_required(int pixel_clock, int bpp) { @@ -219,16 +223,52 @@ intel_dp_link_required(int pixel_clock, int bpp) return DIV_ROUND_UP(pixel_clock * bpp, 8); } +/* + * Given a link rate and lanes, get the data bandwidth. + * + * Data bandwidth is the actual payload rate, which depends on the data + * bandwidth efficiency and the link rate. + * + * For 8b/10b channel encoding, SST and non-FEC, the data bandwidth efficiency + * is 80%. For example, for a 1.62 Gbps link, 1.62*10^9 bps * 0.80 * (1/8) = + * 162000 kBps. With 8-bit symbols, we have 162000 kHz symbol clock. Just by + * coincidence, the port clock in kHz matches the data bandwidth in kBps, and + * they equal the link bit rate in Gbps multiplied by 100000. (Note that this no + * longer holds for data bandwidth as soon as FEC or MST is taken into account!) + * + * For 128b/132b channel encoding, the data bandwidth efficiency is 96.71%. For + * example, for a 10 Gbps link, 10*10^9 bps * 0.9671 * (1/8) = 1208875 + * kBps. With 32-bit symbols, we have 312500 kHz symbol clock. The value 1000000 + * does not match the symbol clock, the port clock (not even if you think in + * terms of a byte clock), nor the data bandwidth. It only matches the link bit + * rate in units of 10000 bps. + */ int -intel_dp_max_data_rate(int max_link_clock, int max_lanes) +intel_dp_max_data_rate(int max_link_rate, int max_lanes) { - /* max_link_clock is the link symbol clock (LS_Clk) in kHz and not the - * link rate that is generally expressed in Gbps. Since, 8 bits of data - * is transmitted every LS_Clk per lane, there is no need to account for - * the channel encoding that is done in the PHY layer here. + if (max_link_rate >= 1000000) { + /* + * UHBR rates always use 128b/132b channel encoding, and have + * 97.71% data bandwidth efficiency. Consider max_link_rate the + * link bit rate in units of 10000 bps. + */ + int max_link_rate_kbps = max_link_rate * 10; + + max_link_rate_kbps = DIV_ROUND_CLOSEST_ULL(max_link_rate_kbps * 9671, 10000); + max_link_rate = max_link_rate_kbps / 8; + } + + /* + * Lower than UHBR rates always use 8b/10b channel encoding, and have + * 80% data bandwidth efficiency for SST non-FEC. However, this turns + * out to be a nop by coincidence, and can be skipped: + * + * int max_link_rate_kbps = max_link_rate * 10; + * max_link_rate_kbps = DIV_ROUND_CLOSEST_ULL(max_link_rate_kbps * 8, 10); + * max_link_rate = max_link_rate_kbps / 8; */ - return max_link_clock * max_lanes; + return max_link_rate * max_lanes; } bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp) diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 1345d588fc6d..ae0f776bffab 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -88,7 +88,7 @@ bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp); bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp); int intel_dp_link_required(int pixel_clock, int bpp); -int intel_dp_max_data_rate(int max_link_clock, int max_lanes); +int intel_dp_max_data_rate(int max_link_rate, int max_lanes); bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp); bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); -- cgit v1.2.3 From b6dfa416172939edaa46a5a647457b94c6d94119 Mon Sep 17 00:00:00 2001 From: Swati Sharma Date: Thu, 12 Aug 2021 18:41:07 +0530 Subject: drm/i915/dp: Drop redundant debug print MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_dp_dpcd_read/write already has debug error message. Drop redundant error messages which gives false status even if correct value is read in drm_dp_dpcd_read(). v2: -Added fixes tag (Ankit) v3: -Fixed build error (CI) Fixes: 9488a030ac91 ("drm/i915: Add support for enabling link status and recovery") Cc: Ankit Nautiyal Cc: Imre Deak Cc: Jani Nikula Cc: José Roberto de Souza Cc: Manasi Navare Cc: Sean Paul Cc: Uma Shankar Cc: Ville Syrjälä Cc: # v5.12+ Reviewed-by: Jani Nikula Signed-off-by: Swati Sharma Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210812131107.5531-1-swati2.sharma@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 7e5d9b959c1d..fd4f7e82e420 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3917,23 +3917,18 @@ static void intel_dp_check_device_service_irq(struct intel_dp *intel_dp) static void intel_dp_check_link_service_irq(struct intel_dp *intel_dp) { - struct drm_i915_private *i915 = dp_to_i915(intel_dp); u8 val; if (intel_dp->dpcd[DP_DPCD_REV] < 0x11) return; if (drm_dp_dpcd_readb(&intel_dp->aux, - DP_LINK_SERVICE_IRQ_VECTOR_ESI0, &val) != 1 || !val) { - drm_dbg_kms(&i915->drm, "Error in reading link service irq vector\n"); + DP_LINK_SERVICE_IRQ_VECTOR_ESI0, &val) != 1 || !val) return; - } if (drm_dp_dpcd_writeb(&intel_dp->aux, - DP_LINK_SERVICE_IRQ_VECTOR_ESI0, val) != 1) { - drm_dbg_kms(&i915->drm, "Error in writing link service irq vector\n"); + DP_LINK_SERVICE_IRQ_VECTOR_ESI0, val) != 1) return; - } if (val & HDMI_LINK_STATUS_CHANGED) intel_dp_handle_hdmi_link_status_change(intel_dp); -- cgit v1.2.3 From cb6baa20c5f3ec3da9a5f1ad127fbf3da0774ade Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 12:36:45 +0300 Subject: drm/i915/fdi: make intel_fdi_link_freq() return int MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The unsigned doesn't help us here. Cc: Ville Syrjälä Suggested-by: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210823093645.10464-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_fdi.c | 2 +- drivers/gpu/drm/i915/display/intel_fdi.h | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 970a57369b05..13f8ba4c9188 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -95,7 +95,7 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, } } -u32 intel_fdi_link_freq(struct drm_i915_private *i915, +int intel_fdi_link_freq(struct drm_i915_private *i915, const struct intel_crtc_state *pipe_config) { if (HAS_DDI(i915)) diff --git a/drivers/gpu/drm/i915/display/intel_fdi.h b/drivers/gpu/drm/i915/display/intel_fdi.h index fd63a6a53fca..2c8ffd9ceaed 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.h +++ b/drivers/gpu/drm/i915/display/intel_fdi.h @@ -6,15 +6,13 @@ #ifndef _INTEL_FDI_H_ #define _INTEL_FDI_H_ -#include - struct drm_i915_private; struct intel_crtc; struct intel_crtc_state; struct intel_encoder; #define I915_DISPLAY_CONFIG_RETRY 1 -u32 intel_fdi_link_freq(struct drm_i915_private *i915, +int intel_fdi_link_freq(struct drm_i915_private *i915, const struct intel_crtc_state *pipe_config); int ilk_fdi_compute_config(struct intel_crtc *intel_crtc, struct intel_crtc_state *pipe_config); -- cgit v1.2.3 From dc6d6158a6e8b11a11544a541583296d9323050f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 15:25:31 +0300 Subject: drm/i915/display: split out dpt out of intel_display.c Let's try to reduce the size of intel_display.c, not increase it. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/934a2a0db05e835f6843befef6082e2034f23b3a.1629721467.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/display/intel_display.c | 220 +------------------------ drivers/gpu/drm/i915/display/intel_dpt.c | 229 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dpt.h | 19 +++ 4 files changed, 250 insertions(+), 219 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_dpt.c create mode 100644 drivers/gpu/drm/i915/display/intel_dpt.h (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 642a5b5a1b81..fd997dfa5e32 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -212,6 +212,7 @@ i915-y += \ display/intel_dpio_phy.o \ display/intel_dpll.o \ display/intel_dpll_mgr.o \ + display/intel_dpt.o \ display/intel_dsb.o \ display/intel_fb.o \ display/intel_fbc.o \ diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a7cba75babd3..eea9553845b2 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -84,6 +84,7 @@ #include "intel_display_types.h" #include "intel_dmc.h" #include "intel_dp_link_training.h" +#include "intel_dpt.h" #include "intel_fbc.h" #include "intel_fdi.h" #include "intel_fbdev.h" @@ -127,182 +128,6 @@ static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state); static void intel_modeset_setup_hw_state(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx); -struct i915_dpt { - struct i915_address_space vm; - - struct drm_i915_gem_object *obj; - struct i915_vma *vma; - void __iomem *iomem; -}; - -#define i915_is_dpt(vm) ((vm)->is_dpt) - -static inline struct i915_dpt * -i915_vm_to_dpt(struct i915_address_space *vm) -{ - BUILD_BUG_ON(offsetof(struct i915_dpt, vm)); - GEM_BUG_ON(!i915_is_dpt(vm)); - return container_of(vm, struct i915_dpt, vm); -} - -#define dpt_total_entries(dpt) ((dpt)->vm.total >> PAGE_SHIFT) - -static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte) -{ - writeq(pte, addr); -} - -static void dpt_insert_page(struct i915_address_space *vm, - dma_addr_t addr, - u64 offset, - enum i915_cache_level level, - u32 flags) -{ - struct i915_dpt *dpt = i915_vm_to_dpt(vm); - gen8_pte_t __iomem *base = dpt->iomem; - - gen8_set_pte(base + offset / I915_GTT_PAGE_SIZE, - vm->pte_encode(addr, level, flags)); -} - -static void dpt_insert_entries(struct i915_address_space *vm, - struct i915_vma *vma, - enum i915_cache_level level, - u32 flags) -{ - struct i915_dpt *dpt = i915_vm_to_dpt(vm); - gen8_pte_t __iomem *base = dpt->iomem; - const gen8_pte_t pte_encode = vm->pte_encode(0, level, flags); - struct sgt_iter sgt_iter; - dma_addr_t addr; - int i; - - /* - * Note that we ignore PTE_READ_ONLY here. The caller must be careful - * not to allow the user to override access to a read only page. - */ - - i = vma->node.start / I915_GTT_PAGE_SIZE; - for_each_sgt_daddr(addr, sgt_iter, vma->pages) - gen8_set_pte(&base[i++], pte_encode | addr); -} - -static void dpt_clear_range(struct i915_address_space *vm, - u64 start, u64 length) -{ -} - -static void dpt_bind_vma(struct i915_address_space *vm, - struct i915_vm_pt_stash *stash, - struct i915_vma *vma, - enum i915_cache_level cache_level, - u32 flags) -{ - struct drm_i915_gem_object *obj = vma->obj; - u32 pte_flags; - - /* Applicable to VLV (gen8+ do not support RO in the GGTT) */ - pte_flags = 0; - if (vma->vm->has_read_only && i915_gem_object_is_readonly(obj)) - pte_flags |= PTE_READ_ONLY; - if (i915_gem_object_is_lmem(obj)) - pte_flags |= PTE_LM; - - vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags); - - vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; - - /* - * Without aliasing PPGTT there's no difference between - * GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally - * upgrade to both bound if we bind either to avoid double-binding. - */ - atomic_or(I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND, &vma->flags); -} - -static void dpt_unbind_vma(struct i915_address_space *vm, struct i915_vma *vma) -{ - vm->clear_range(vm, vma->node.start, vma->size); -} - -static void dpt_cleanup(struct i915_address_space *vm) -{ - struct i915_dpt *dpt = i915_vm_to_dpt(vm); - - i915_gem_object_put(dpt->obj); -} - -static struct i915_address_space * -intel_dpt_create(struct intel_framebuffer *fb) -{ - struct drm_gem_object *obj = &intel_fb_obj(&fb->base)->base; - struct drm_i915_private *i915 = to_i915(obj->dev); - struct drm_i915_gem_object *dpt_obj; - struct i915_address_space *vm; - struct i915_dpt *dpt; - size_t size; - int ret; - - if (intel_fb_needs_pot_stride_remap(fb)) - size = intel_remapped_info_size(&fb->remapped_view.gtt.remapped); - else - size = DIV_ROUND_UP_ULL(obj->size, I915_GTT_PAGE_SIZE); - - size = round_up(size * sizeof(gen8_pte_t), I915_GTT_PAGE_SIZE); - - if (HAS_LMEM(i915)) - dpt_obj = i915_gem_object_create_lmem(i915, size, 0); - else - dpt_obj = i915_gem_object_create_stolen(i915, size); - if (IS_ERR(dpt_obj)) - return ERR_CAST(dpt_obj); - - ret = i915_gem_object_set_cache_level(dpt_obj, I915_CACHE_NONE); - if (ret) { - i915_gem_object_put(dpt_obj); - return ERR_PTR(ret); - } - - dpt = kzalloc(sizeof(*dpt), GFP_KERNEL); - if (!dpt) { - i915_gem_object_put(dpt_obj); - return ERR_PTR(-ENOMEM); - } - - vm = &dpt->vm; - - vm->gt = &i915->gt; - vm->i915 = i915; - vm->dma = i915->drm.dev; - vm->total = (size / sizeof(gen8_pte_t)) * I915_GTT_PAGE_SIZE; - vm->is_dpt = true; - - i915_address_space_init(vm, VM_CLASS_DPT); - - vm->insert_page = dpt_insert_page; - vm->clear_range = dpt_clear_range; - vm->insert_entries = dpt_insert_entries; - vm->cleanup = dpt_cleanup; - - vm->vma_ops.bind_vma = dpt_bind_vma; - vm->vma_ops.unbind_vma = dpt_unbind_vma; - vm->vma_ops.set_pages = ggtt_set_pages; - vm->vma_ops.clear_pages = clear_pages; - - vm->pte_encode = gen8_ggtt_pte_encode; - - dpt->obj = dpt_obj; - - return &dpt->vm; -} - -static void intel_dpt_destroy(struct i915_address_space *vm) -{ - struct i915_dpt *dpt = i915_vm_to_dpt(vm); - - i915_vm_close(&dpt->vm); -} - /* returns HPLL frequency in kHz */ int vlv_get_hpll_vco(struct drm_i915_private *dev_priv) { @@ -1880,49 +1705,6 @@ static void intel_plane_disable_noatomic(struct intel_crtc *crtc, intel_wait_for_vblank(dev_priv, crtc->pipe); } -static struct i915_vma *intel_dpt_pin(struct i915_address_space *vm) -{ - struct drm_i915_private *i915 = vm->i915; - struct i915_dpt *dpt = i915_vm_to_dpt(vm); - intel_wakeref_t wakeref; - struct i915_vma *vma; - void __iomem *iomem; - - wakeref = intel_runtime_pm_get(&i915->runtime_pm); - atomic_inc(&i915->gpu_error.pending_fb_pin); - - vma = i915_gem_object_ggtt_pin(dpt->obj, NULL, 0, 4096, - HAS_LMEM(i915) ? 0 : PIN_MAPPABLE); - if (IS_ERR(vma)) - goto err; - - iomem = i915_vma_pin_iomap(vma); - i915_vma_unpin(vma); - if (IS_ERR(iomem)) { - vma = iomem; - goto err; - } - - dpt->vma = vma; - dpt->iomem = iomem; - - i915_vma_get(vma); - -err: - atomic_dec(&i915->gpu_error.pending_fb_pin); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); - - return vma; -} - -static void intel_dpt_unpin(struct i915_address_space *vm) -{ - struct i915_dpt *dpt = i915_vm_to_dpt(vm); - - i915_vma_unpin_iomap(dpt->vma); - i915_vma_put(dpt->vma); -} - static bool intel_reuse_initial_plane_obj(struct drm_i915_private *i915, const struct intel_initial_plane_config *plane_config, diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c new file mode 100644 index 000000000000..22acd945a9e4 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2021 Intel Corporation + */ + +#include "i915_drv.h" +#include "intel_display_types.h" +#include "intel_dpt.h" +#include "intel_fb.h" +#include "gt/gen8_ppgtt.h" + +struct i915_dpt { + struct i915_address_space vm; + + struct drm_i915_gem_object *obj; + struct i915_vma *vma; + void __iomem *iomem; +}; + +#define i915_is_dpt(vm) ((vm)->is_dpt) + +static inline struct i915_dpt * +i915_vm_to_dpt(struct i915_address_space *vm) +{ + BUILD_BUG_ON(offsetof(struct i915_dpt, vm)); + GEM_BUG_ON(!i915_is_dpt(vm)); + return container_of(vm, struct i915_dpt, vm); +} + +#define dpt_total_entries(dpt) ((dpt)->vm.total >> PAGE_SHIFT) + +static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte) +{ + writeq(pte, addr); +} + +static void dpt_insert_page(struct i915_address_space *vm, + dma_addr_t addr, + u64 offset, + enum i915_cache_level level, + u32 flags) +{ + struct i915_dpt *dpt = i915_vm_to_dpt(vm); + gen8_pte_t __iomem *base = dpt->iomem; + + gen8_set_pte(base + offset / I915_GTT_PAGE_SIZE, + vm->pte_encode(addr, level, flags)); +} + +static void dpt_insert_entries(struct i915_address_space *vm, + struct i915_vma *vma, + enum i915_cache_level level, + u32 flags) +{ + struct i915_dpt *dpt = i915_vm_to_dpt(vm); + gen8_pte_t __iomem *base = dpt->iomem; + const gen8_pte_t pte_encode = vm->pte_encode(0, level, flags); + struct sgt_iter sgt_iter; + dma_addr_t addr; + int i; + + /* + * Note that we ignore PTE_READ_ONLY here. The caller must be careful + * not to allow the user to override access to a read only page. + */ + + i = vma->node.start / I915_GTT_PAGE_SIZE; + for_each_sgt_daddr(addr, sgt_iter, vma->pages) + gen8_set_pte(&base[i++], pte_encode | addr); +} + +static void dpt_clear_range(struct i915_address_space *vm, + u64 start, u64 length) +{ +} + +static void dpt_bind_vma(struct i915_address_space *vm, + struct i915_vm_pt_stash *stash, + struct i915_vma *vma, + enum i915_cache_level cache_level, + u32 flags) +{ + struct drm_i915_gem_object *obj = vma->obj; + u32 pte_flags; + + /* Applicable to VLV (gen8+ do not support RO in the GGTT) */ + pte_flags = 0; + if (vma->vm->has_read_only && i915_gem_object_is_readonly(obj)) + pte_flags |= PTE_READ_ONLY; + if (i915_gem_object_is_lmem(obj)) + pte_flags |= PTE_LM; + + vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags); + + vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; + + /* + * Without aliasing PPGTT there's no difference between + * GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally + * upgrade to both bound if we bind either to avoid double-binding. + */ + atomic_or(I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND, &vma->flags); +} + +static void dpt_unbind_vma(struct i915_address_space *vm, struct i915_vma *vma) +{ + vm->clear_range(vm, vma->node.start, vma->size); +} + +static void dpt_cleanup(struct i915_address_space *vm) +{ + struct i915_dpt *dpt = i915_vm_to_dpt(vm); + + i915_gem_object_put(dpt->obj); +} + +struct i915_vma *intel_dpt_pin(struct i915_address_space *vm) +{ + struct drm_i915_private *i915 = vm->i915; + struct i915_dpt *dpt = i915_vm_to_dpt(vm); + intel_wakeref_t wakeref; + struct i915_vma *vma; + void __iomem *iomem; + + wakeref = intel_runtime_pm_get(&i915->runtime_pm); + atomic_inc(&i915->gpu_error.pending_fb_pin); + + vma = i915_gem_object_ggtt_pin(dpt->obj, NULL, 0, 4096, + HAS_LMEM(i915) ? 0 : PIN_MAPPABLE); + if (IS_ERR(vma)) + goto err; + + iomem = i915_vma_pin_iomap(vma); + i915_vma_unpin(vma); + if (IS_ERR(iomem)) { + vma = iomem; + goto err; + } + + dpt->vma = vma; + dpt->iomem = iomem; + + i915_vma_get(vma); + +err: + atomic_dec(&i915->gpu_error.pending_fb_pin); + intel_runtime_pm_put(&i915->runtime_pm, wakeref); + + return vma; +} + +void intel_dpt_unpin(struct i915_address_space *vm) +{ + struct i915_dpt *dpt = i915_vm_to_dpt(vm); + + i915_vma_unpin_iomap(dpt->vma); + i915_vma_put(dpt->vma); +} + +struct i915_address_space * +intel_dpt_create(struct intel_framebuffer *fb) +{ + struct drm_gem_object *obj = &intel_fb_obj(&fb->base)->base; + struct drm_i915_private *i915 = to_i915(obj->dev); + struct drm_i915_gem_object *dpt_obj; + struct i915_address_space *vm; + struct i915_dpt *dpt; + size_t size; + int ret; + + if (intel_fb_needs_pot_stride_remap(fb)) + size = intel_remapped_info_size(&fb->remapped_view.gtt.remapped); + else + size = DIV_ROUND_UP_ULL(obj->size, I915_GTT_PAGE_SIZE); + + size = round_up(size * sizeof(gen8_pte_t), I915_GTT_PAGE_SIZE); + + if (HAS_LMEM(i915)) + dpt_obj = i915_gem_object_create_lmem(i915, size, 0); + else + dpt_obj = i915_gem_object_create_stolen(i915, size); + if (IS_ERR(dpt_obj)) + return ERR_CAST(dpt_obj); + + ret = i915_gem_object_set_cache_level(dpt_obj, I915_CACHE_NONE); + if (ret) { + i915_gem_object_put(dpt_obj); + return ERR_PTR(ret); + } + + dpt = kzalloc(sizeof(*dpt), GFP_KERNEL); + if (!dpt) { + i915_gem_object_put(dpt_obj); + return ERR_PTR(-ENOMEM); + } + + vm = &dpt->vm; + + vm->gt = &i915->gt; + vm->i915 = i915; + vm->dma = i915->drm.dev; + vm->total = (size / sizeof(gen8_pte_t)) * I915_GTT_PAGE_SIZE; + vm->is_dpt = true; + + i915_address_space_init(vm, VM_CLASS_DPT); + + vm->insert_page = dpt_insert_page; + vm->clear_range = dpt_clear_range; + vm->insert_entries = dpt_insert_entries; + vm->cleanup = dpt_cleanup; + + vm->vma_ops.bind_vma = dpt_bind_vma; + vm->vma_ops.unbind_vma = dpt_unbind_vma; + vm->vma_ops.set_pages = ggtt_set_pages; + vm->vma_ops.clear_pages = clear_pages; + + vm->pte_encode = gen8_ggtt_pte_encode; + + dpt->obj = dpt_obj; + + return &dpt->vm; +} + +void intel_dpt_destroy(struct i915_address_space *vm) +{ + struct i915_dpt *dpt = i915_vm_to_dpt(vm); + + i915_vm_close(&dpt->vm); +} diff --git a/drivers/gpu/drm/i915/display/intel_dpt.h b/drivers/gpu/drm/i915/display/intel_dpt.h new file mode 100644 index 000000000000..45142b8f849f --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_dpt.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2021 Intel Corporation + */ + +#ifndef __INTEL_DPT_H__ +#define __INTEL_DPT_H__ + +struct i915_address_space; +struct i915_vma; +struct intel_framebuffer; + +void intel_dpt_destroy(struct i915_address_space *vm); +struct i915_vma *intel_dpt_pin(struct i915_address_space *vm); +void intel_dpt_unpin(struct i915_address_space *vm); +struct i915_address_space * +intel_dpt_create(struct intel_framebuffer *fb); + +#endif /* __INTEL_DPT_H__ */ -- cgit v1.2.3 From af182a236a142965fc6de7e48fd1c92a3607f5bd Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 15:25:32 +0300 Subject: drm/i915: add HAS_ASYNC_FLIPS feature macro This will be needed in multiple places soon. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/08bf0f72435a4f9acb0ef31b82ca312b048c6bf6.1629721467.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 9 ++------- drivers/gpu/drm/i915/i915_drv.h | 2 ++ 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index eea9553845b2..d93a2d675ae2 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -977,11 +977,6 @@ static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_pr return 0; } -static bool has_async_flips(struct drm_i915_private *i915) -{ - return DISPLAY_VER(i915) >= 5; -} - unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, int color_plane) { @@ -1015,7 +1010,7 @@ unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, case DRM_FORMAT_MOD_LINEAR: return intel_linear_alignment(dev_priv); case I915_FORMAT_MOD_X_TILED: - if (has_async_flips(dev_priv)) + if (HAS_ASYNC_FLIPS(dev_priv)) return 256 * 1024; return 0; case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: @@ -12161,7 +12156,7 @@ static void intel_mode_config_init(struct drm_i915_private *i915) mode_config->funcs = &intel_mode_funcs; - mode_config->async_page_flip = has_async_flips(i915); + mode_config->async_page_flip = HAS_ASYNC_FLIPS(i915); /* * Maximum framebuffer dimensions, chosen to match diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0a2b63072ff5..106f218cec2b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1721,6 +1721,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define HAS_VRR(i915) (GRAPHICS_VER(i915) >= 12) +#define HAS_ASYNC_FLIPS(i915) (DISPLAY_VER(i915) >= 5) + /* Only valid when HAS_DISPLAY() is true */ #define INTEL_DISPLAY_ENABLED(dev_priv) \ (drm_WARN_ON(&(dev_priv)->drm, !HAS_DISPLAY(dev_priv)), !(dev_priv)->params.disable_display) -- cgit v1.2.3 From d36168832755112573b926efe3b9d5213504f265 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 15:25:33 +0300 Subject: drm/i915/fb: move intel_tile_width_bytes() to intel_fb.c Split out fb related stuff from intel_display.c to intel_fb.c. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/35c3ade81a54fea890cf92e21b778c38ab78cd04.1629721467.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 54 ---------------------------- drivers/gpu/drm/i915/display/intel_display.h | 1 - drivers/gpu/drm/i915/display/intel_fb.c | 54 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_fb.h | 1 + 4 files changed, 55 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d93a2d675ae2..6118bd782b57 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -879,60 +879,6 @@ intel_format_info_is_yuv_semiplanar(const struct drm_format_info *info, info->num_planes == (is_ccs_modifier(modifier) ? 4 : 2); } -unsigned int -intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane) -{ - struct drm_i915_private *dev_priv = to_i915(fb->dev); - unsigned int cpp = fb->format->cpp[color_plane]; - - switch (fb->modifier) { - case DRM_FORMAT_MOD_LINEAR: - return intel_tile_size(dev_priv); - case I915_FORMAT_MOD_X_TILED: - if (DISPLAY_VER(dev_priv) == 2) - return 128; - else - return 512; - case I915_FORMAT_MOD_Y_TILED_CCS: - if (is_ccs_plane(fb, color_plane)) - return 128; - fallthrough; - case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: - case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: - case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: - if (is_ccs_plane(fb, color_plane)) - return 64; - fallthrough; - case I915_FORMAT_MOD_Y_TILED: - if (DISPLAY_VER(dev_priv) == 2 || HAS_128_BYTE_Y_TILING(dev_priv)) - return 128; - else - return 512; - case I915_FORMAT_MOD_Yf_TILED_CCS: - if (is_ccs_plane(fb, color_plane)) - return 128; - fallthrough; - case I915_FORMAT_MOD_Yf_TILED: - switch (cpp) { - case 1: - return 64; - case 2: - case 4: - return 128; - case 8: - case 16: - return 256; - default: - MISSING_CASE(cpp); - return cpp; - } - break; - default: - MISSING_CASE(fb->modifier); - return cpp; - } -} - unsigned int intel_fb_align_height(const struct drm_framebuffer *fb, int color_plane, unsigned int height) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 284936f0ddab..e04394c8a9ad 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -632,7 +632,6 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state, unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, int color_plane); -unsigned int intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane); void intel_display_driver_register(struct drm_i915_private *i915); void intel_display_driver_unregister(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index c60a81a81c09..870c1366e7e6 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -79,6 +79,60 @@ unsigned int intel_tile_size(const struct drm_i915_private *i915) return DISPLAY_VER(i915) == 2 ? 2048 : 4096; } +unsigned int +intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane) +{ + struct drm_i915_private *dev_priv = to_i915(fb->dev); + unsigned int cpp = fb->format->cpp[color_plane]; + + switch (fb->modifier) { + case DRM_FORMAT_MOD_LINEAR: + return intel_tile_size(dev_priv); + case I915_FORMAT_MOD_X_TILED: + if (DISPLAY_VER(dev_priv) == 2) + return 128; + else + return 512; + case I915_FORMAT_MOD_Y_TILED_CCS: + if (is_ccs_plane(fb, color_plane)) + return 128; + fallthrough; + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: + case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: + if (is_ccs_plane(fb, color_plane)) + return 64; + fallthrough; + case I915_FORMAT_MOD_Y_TILED: + if (DISPLAY_VER(dev_priv) == 2 || HAS_128_BYTE_Y_TILING(dev_priv)) + return 128; + else + return 512; + case I915_FORMAT_MOD_Yf_TILED_CCS: + if (is_ccs_plane(fb, color_plane)) + return 128; + fallthrough; + case I915_FORMAT_MOD_Yf_TILED: + switch (cpp) { + case 1: + return 64; + case 2: + case 4: + return 128; + case 8: + case 16: + return 256; + default: + MISSING_CASE(cpp); + return cpp; + } + break; + default: + MISSING_CASE(fb->modifier); + return cpp; + } +} + unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane) { if (is_gen12_ccs_plane(fb, color_plane)) diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index 739d1b91754b..4768360401ae 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -28,6 +28,7 @@ int skl_ccs_to_main_plane(const struct drm_framebuffer *fb, int ccs_plane); int skl_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane); unsigned int intel_tile_size(const struct drm_i915_private *i915); +unsigned int intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane); unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane); unsigned int intel_tile_row_size(const struct drm_framebuffer *fb, int color_plane); -- cgit v1.2.3 From b8db261187439c42d18036d661a95e68de76550e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 15:25:34 +0300 Subject: drm/i915/fb: move intel_fb_align_height() to intel_fb.c Split out fb related stuff from intel_display.c to intel_fb.c. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/7c97d29eeff676b510eafd242e2a6d7c8ed4a3a6.1629721467.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 9 --------- drivers/gpu/drm/i915/display/intel_display.h | 2 -- drivers/gpu/drm/i915/display/intel_fb.c | 9 +++++++++ drivers/gpu/drm/i915/display/intel_fb.h | 3 ++- drivers/gpu/drm/i915/display/intel_fbdev.c | 1 + 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 6118bd782b57..ddc6bd436b01 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -879,15 +879,6 @@ intel_format_info_is_yuv_semiplanar(const struct drm_format_info *info, info->num_planes == (is_ccs_modifier(modifier) ? 4 : 2); } -unsigned int -intel_fb_align_height(const struct drm_framebuffer *fb, - int color_plane, unsigned int height) -{ - unsigned int tile_height = intel_tile_height(fb, color_plane); - - return ALIGN(height, tile_height); -} - unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info) { unsigned int size = 0; diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index e04394c8a9ad..695b874adacc 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -548,8 +548,6 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv); unsigned int intel_fb_xy_to_linear(int x, int y, const struct intel_plane_state *state, int plane); -unsigned int intel_fb_align_height(const struct drm_framebuffer *fb, - int color_plane, unsigned int height); void intel_add_fb_offsets(int *x, int *y, const struct intel_plane_state *state, int plane); unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info); diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 870c1366e7e6..9e722cc1a7fd 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -163,6 +163,15 @@ unsigned int intel_tile_row_size(const struct drm_framebuffer *fb, int color_pla return fb->pitches[color_plane] * tile_height; } +unsigned int +intel_fb_align_height(const struct drm_framebuffer *fb, + int color_plane, unsigned int height) +{ + unsigned int tile_height = intel_tile_height(fb, color_plane); + + return ALIGN(height, tile_height); +} + unsigned int intel_cursor_alignment(const struct drm_i915_private *i915) { if (IS_I830(i915)) diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index 4768360401ae..f3d677cd6b6e 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -31,7 +31,8 @@ unsigned int intel_tile_size(const struct drm_i915_private *i915); unsigned int intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane); unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane); unsigned int intel_tile_row_size(const struct drm_framebuffer *fb, int color_plane); - +unsigned int intel_fb_align_height(const struct drm_framebuffer *fb, + int color_plane, unsigned int height); unsigned int intel_cursor_alignment(const struct drm_i915_private *i915); void intel_fb_plane_get_subsampling(int *hsub, int *vsub, diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index df05d285f0bd..60d3ded27047 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -45,6 +45,7 @@ #include "i915_drv.h" #include "intel_display_types.h" +#include "intel_fb.h" #include "intel_fbdev.h" #include "intel_frontbuffer.h" -- cgit v1.2.3 From 1c8d9adfc3ad7e5472fbed2163897c13ad67620b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 15:25:35 +0300 Subject: drm/i915/fb: move intel_surf_alignment() to intel_fb.c Split out fb related stuff from intel_display.c to intel_fb.c. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/0b894be3a6acff5fe917b686771a084a6c2aa535.1629721467.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 64 ---------------------------- drivers/gpu/drm/i915/display/intel_display.h | 3 -- drivers/gpu/drm/i915/display/intel_fb.c | 64 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_fb.h | 2 + 4 files changed, 66 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ddc6bd436b01..a9e3ac07b207 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -901,70 +901,6 @@ unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info return size; } -static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_priv) -{ - if (DISPLAY_VER(dev_priv) >= 9) - return 256 * 1024; - else if (IS_I965G(dev_priv) || IS_I965GM(dev_priv) || - IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - return 128 * 1024; - else if (DISPLAY_VER(dev_priv) >= 4) - return 4 * 1024; - else - return 0; -} - -unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, - int color_plane) -{ - struct drm_i915_private *dev_priv = to_i915(fb->dev); - - if (intel_fb_uses_dpt(fb)) - return 512 * 4096; - - /* AUX_DIST needs only 4K alignment */ - if (is_ccs_plane(fb, color_plane)) - return 4096; - - if (is_semiplanar_uv_plane(fb, color_plane)) { - /* - * TODO: cross-check wrt. the bspec stride in bytes * 64 bytes - * alignment for linear UV planes on all platforms. - */ - if (DISPLAY_VER(dev_priv) >= 12) { - if (fb->modifier == DRM_FORMAT_MOD_LINEAR) - return intel_linear_alignment(dev_priv); - - return intel_tile_row_size(fb, color_plane); - } - - return 4096; - } - - drm_WARN_ON(&dev_priv->drm, color_plane != 0); - - switch (fb->modifier) { - case DRM_FORMAT_MOD_LINEAR: - return intel_linear_alignment(dev_priv); - case I915_FORMAT_MOD_X_TILED: - if (HAS_ASYNC_FLIPS(dev_priv)) - return 256 * 1024; - return 0; - case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: - case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: - case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: - return 16 * 1024; - case I915_FORMAT_MOD_Y_TILED_CCS: - case I915_FORMAT_MOD_Yf_TILED_CCS: - case I915_FORMAT_MOD_Y_TILED: - case I915_FORMAT_MOD_Yf_TILED: - return 1 * 1024 * 1024; - default: - MISSING_CASE(fb->modifier); - return 0; - } -} - static bool intel_plane_uses_fence(const struct intel_plane_state *plane_state) { struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 695b874adacc..4719ffc97fce 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -628,9 +628,6 @@ struct intel_encoder * intel_get_crtc_new_encoder(const struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state); -unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, - int color_plane); - void intel_display_driver_register(struct drm_i915_private *i915); void intel_display_driver_unregister(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 9e722cc1a7fd..e24ee2a28ebf 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -184,6 +184,70 @@ unsigned int intel_cursor_alignment(const struct drm_i915_private *i915) return 4 * 1024; } +static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_priv) +{ + if (DISPLAY_VER(dev_priv) >= 9) + return 256 * 1024; + else if (IS_I965G(dev_priv) || IS_I965GM(dev_priv) || + IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + return 128 * 1024; + else if (DISPLAY_VER(dev_priv) >= 4) + return 4 * 1024; + else + return 0; +} + +unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, + int color_plane) +{ + struct drm_i915_private *dev_priv = to_i915(fb->dev); + + if (intel_fb_uses_dpt(fb)) + return 512 * 4096; + + /* AUX_DIST needs only 4K alignment */ + if (is_ccs_plane(fb, color_plane)) + return 4096; + + if (is_semiplanar_uv_plane(fb, color_plane)) { + /* + * TODO: cross-check wrt. the bspec stride in bytes * 64 bytes + * alignment for linear UV planes on all platforms. + */ + if (DISPLAY_VER(dev_priv) >= 12) { + if (fb->modifier == DRM_FORMAT_MOD_LINEAR) + return intel_linear_alignment(dev_priv); + + return intel_tile_row_size(fb, color_plane); + } + + return 4096; + } + + drm_WARN_ON(&dev_priv->drm, color_plane != 0); + + switch (fb->modifier) { + case DRM_FORMAT_MOD_LINEAR: + return intel_linear_alignment(dev_priv); + case I915_FORMAT_MOD_X_TILED: + if (HAS_ASYNC_FLIPS(dev_priv)) + return 256 * 1024; + return 0; + case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: + return 16 * 1024; + case I915_FORMAT_MOD_Y_TILED_CCS: + case I915_FORMAT_MOD_Yf_TILED_CCS: + case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Yf_TILED: + return 1 * 1024 * 1024; + default: + MISSING_CASE(fb->modifier); + return 0; + } +} + void intel_fb_plane_get_subsampling(int *hsub, int *vsub, const struct drm_framebuffer *fb, int color_plane) diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index f3d677cd6b6e..0b0a83139462 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -34,6 +34,8 @@ unsigned int intel_tile_row_size(const struct drm_framebuffer *fb, int color_pla unsigned int intel_fb_align_height(const struct drm_framebuffer *fb, int color_plane, unsigned int height); unsigned int intel_cursor_alignment(const struct drm_i915_private *i915); +unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, + int color_plane); void intel_fb_plane_get_subsampling(int *hsub, int *vsub, const struct drm_framebuffer *fb, -- cgit v1.2.3 From 705d4feeb269e22c4850ad66e2210b737b553236 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 23 Aug 2021 15:25:36 +0300 Subject: drm/i915/fb: move user framebuffer stuff to intel_fb.c Split out fb related stuff from intel_display.c to intel_fb.c. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/76b61738857619c1cce6e4306d14da19ee3bbf08.1629721467.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 355 --------------------------- drivers/gpu/drm/i915/display/intel_fb.c | 354 ++++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_fb.h | 14 +- 3 files changed, 366 insertions(+), 357 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a9e3ac07b207..794690c0dba5 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -112,9 +112,6 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, static void ilk_pch_clock_get(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config); -static int intel_framebuffer_init(struct intel_framebuffer *ifb, - struct drm_i915_gem_object *obj, - struct drm_mode_fb_cmd2 *mode_cmd); static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state); static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state); static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_state, @@ -1134,22 +1131,6 @@ void intel_add_fb_offsets(int *x, int *y, *y += state->view.color_plane[color_plane].y; } -static unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier) -{ - switch (fb_modifier) { - case I915_FORMAT_MOD_X_TILED: - return I915_TILING_X; - case I915_FORMAT_MOD_Y_TILED: - case I915_FORMAT_MOD_Y_TILED_CCS: - case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: - case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: - case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: - return I915_TILING_Y; - default: - return I915_TILING_NONE; - } -} - /* * From the Sky Lake PRM: * "The Color Control Surface (CCS) contains the compression status of @@ -1280,12 +1261,6 @@ intel_get_format_info(const struct drm_mode_fb_cmd2 *cmd) } } -static int gen12_ccs_aux_stride(struct drm_framebuffer *fb, int ccs_plane) -{ - return DIV_ROUND_UP(fb->pitches[skl_ccs_to_main_plane(fb, ccs_plane)], - 512) * 64; -} - u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv, u32 pixel_format, u64 modifier) { @@ -1310,71 +1285,6 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv, DRM_MODE_ROTATE_0); } -static -u32 intel_fb_max_stride(struct drm_i915_private *dev_priv, - u32 pixel_format, u64 modifier) -{ - /* - * Arbitrary limit for gen4+ chosen to match the - * render engine max stride. - * - * The new CCS hash mode makes remapping impossible - */ - if (DISPLAY_VER(dev_priv) < 4 || is_ccs_modifier(modifier) || - intel_modifier_uses_dpt(dev_priv, modifier)) - return intel_plane_fb_max_stride(dev_priv, pixel_format, modifier); - else if (DISPLAY_VER(dev_priv) >= 7) - return 256 * 1024; - else - return 128 * 1024; -} - -static u32 -intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane) -{ - struct drm_i915_private *dev_priv = to_i915(fb->dev); - u32 tile_width; - - if (is_surface_linear(fb, color_plane)) { - u32 max_stride = intel_plane_fb_max_stride(dev_priv, - fb->format->format, - fb->modifier); - - /* - * To make remapping with linear generally feasible - * we need the stride to be page aligned. - */ - if (fb->pitches[color_plane] > max_stride && - !is_ccs_modifier(fb->modifier)) - return intel_tile_size(dev_priv); - else - return 64; - } - - tile_width = intel_tile_width_bytes(fb, color_plane); - if (is_ccs_modifier(fb->modifier)) { - /* - * Display WA #0531: skl,bxt,kbl,glk - * - * Render decompression and plane width > 3840 - * combined with horizontal panning requires the - * plane stride to be a multiple of 4. We'll just - * require the entire fb to accommodate that to avoid - * potential runtime errors at plane configuration time. - */ - if ((DISPLAY_VER(dev_priv) == 9 || IS_GEMINILAKE(dev_priv)) && - color_plane == 0 && fb->width > 3840) - tile_width *= 4; - /* - * The main surface pitch must be padded to a multiple of four - * tile widths. - */ - else if (DISPLAY_VER(dev_priv) >= 12) - tile_width *= 4; - } - return tile_width; -} - static struct i915_vma * initial_plane_vma(struct drm_i915_private *i915, struct intel_initial_plane_config *plane_config) @@ -6182,28 +6092,6 @@ static const struct drm_display_mode load_detect_mode = { 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), }; -struct drm_framebuffer * -intel_framebuffer_create(struct drm_i915_gem_object *obj, - struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct intel_framebuffer *intel_fb; - int ret; - - intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); - if (!intel_fb) - return ERR_PTR(-ENOMEM); - - ret = intel_framebuffer_init(intel_fb, obj, mode_cmd); - if (ret) - goto err; - - return &intel_fb->base; - -err: - kfree(intel_fb); - return ERR_PTR(ret); -} - static int intel_modeset_disable_planes(struct drm_atomic_state *state, struct drm_crtc *crtc) { @@ -11356,249 +11244,6 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv) drm_helper_move_panel_connectors_to_head(&dev_priv->drm); } -static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) -{ - struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - - drm_framebuffer_cleanup(fb); - - if (intel_fb_uses_dpt(fb)) - intel_dpt_destroy(intel_fb->dpt_vm); - - intel_frontbuffer_put(intel_fb->frontbuffer); - - kfree(intel_fb); -} - -static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, - struct drm_file *file, - unsigned int *handle) -{ - struct drm_i915_gem_object *obj = intel_fb_obj(fb); - struct drm_i915_private *i915 = to_i915(obj->base.dev); - - if (i915_gem_object_is_userptr(obj)) { - drm_dbg(&i915->drm, - "attempting to use a userptr for a framebuffer, denied\n"); - return -EINVAL; - } - - return drm_gem_handle_create(file, &obj->base, handle); -} - -static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, - struct drm_file *file, - unsigned flags, unsigned color, - struct drm_clip_rect *clips, - unsigned num_clips) -{ - struct drm_i915_gem_object *obj = intel_fb_obj(fb); - - i915_gem_object_flush_if_display(obj); - intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB); - - return 0; -} - -static const struct drm_framebuffer_funcs intel_fb_funcs = { - .destroy = intel_user_framebuffer_destroy, - .create_handle = intel_user_framebuffer_create_handle, - .dirty = intel_user_framebuffer_dirty, -}; - -static int intel_framebuffer_init(struct intel_framebuffer *intel_fb, - struct drm_i915_gem_object *obj, - struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct drm_i915_private *dev_priv = to_i915(obj->base.dev); - struct drm_framebuffer *fb = &intel_fb->base; - u32 max_stride; - unsigned int tiling, stride; - int ret = -EINVAL; - int i; - - intel_fb->frontbuffer = intel_frontbuffer_get(obj); - if (!intel_fb->frontbuffer) - return -ENOMEM; - - i915_gem_object_lock(obj, NULL); - tiling = i915_gem_object_get_tiling(obj); - stride = i915_gem_object_get_stride(obj); - i915_gem_object_unlock(obj); - - if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) { - /* - * If there's a fence, enforce that - * the fb modifier and tiling mode match. - */ - if (tiling != I915_TILING_NONE && - tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) { - drm_dbg_kms(&dev_priv->drm, - "tiling_mode doesn't match fb modifier\n"); - goto err; - } - } else { - if (tiling == I915_TILING_X) { - mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED; - } else if (tiling == I915_TILING_Y) { - drm_dbg_kms(&dev_priv->drm, - "No Y tiling for legacy addfb\n"); - goto err; - } - } - - if (!drm_any_plane_has_format(&dev_priv->drm, - mode_cmd->pixel_format, - mode_cmd->modifier[0])) { - drm_dbg_kms(&dev_priv->drm, - "unsupported pixel format %p4cc / modifier 0x%llx\n", - &mode_cmd->pixel_format, mode_cmd->modifier[0]); - goto err; - } - - /* - * gen2/3 display engine uses the fence if present, - * so the tiling mode must match the fb modifier exactly. - */ - if (DISPLAY_VER(dev_priv) < 4 && - tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) { - drm_dbg_kms(&dev_priv->drm, - "tiling_mode must match fb modifier exactly on gen2/3\n"); - goto err; - } - - max_stride = intel_fb_max_stride(dev_priv, mode_cmd->pixel_format, - mode_cmd->modifier[0]); - if (mode_cmd->pitches[0] > max_stride) { - drm_dbg_kms(&dev_priv->drm, - "%s pitch (%u) must be at most %d\n", - mode_cmd->modifier[0] != DRM_FORMAT_MOD_LINEAR ? - "tiled" : "linear", - mode_cmd->pitches[0], max_stride); - goto err; - } - - /* - * If there's a fence, enforce that - * the fb pitch and fence stride match. - */ - if (tiling != I915_TILING_NONE && mode_cmd->pitches[0] != stride) { - drm_dbg_kms(&dev_priv->drm, - "pitch (%d) must match tiling stride (%d)\n", - mode_cmd->pitches[0], stride); - goto err; - } - - /* FIXME need to adjust LINOFF/TILEOFF accordingly. */ - if (mode_cmd->offsets[0] != 0) { - drm_dbg_kms(&dev_priv->drm, - "plane 0 offset (0x%08x) must be 0\n", - mode_cmd->offsets[0]); - goto err; - } - - drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd); - - for (i = 0; i < fb->format->num_planes; i++) { - u32 stride_alignment; - - if (mode_cmd->handles[i] != mode_cmd->handles[0]) { - drm_dbg_kms(&dev_priv->drm, "bad plane %d handle\n", - i); - goto err; - } - - stride_alignment = intel_fb_stride_alignment(fb, i); - if (fb->pitches[i] & (stride_alignment - 1)) { - drm_dbg_kms(&dev_priv->drm, - "plane %d pitch (%d) must be at least %u byte aligned\n", - i, fb->pitches[i], stride_alignment); - goto err; - } - - if (is_gen12_ccs_plane(fb, i) && !is_gen12_ccs_cc_plane(fb, i)) { - int ccs_aux_stride = gen12_ccs_aux_stride(fb, i); - - if (fb->pitches[i] != ccs_aux_stride) { - drm_dbg_kms(&dev_priv->drm, - "ccs aux plane %d pitch (%d) must be %d\n", - i, - fb->pitches[i], ccs_aux_stride); - goto err; - } - } - - /* TODO: Add POT stride remapping support for CCS formats as well. */ - if (IS_ALDERLAKE_P(dev_priv) && - mode_cmd->modifier[i] != DRM_FORMAT_MOD_LINEAR && - !intel_fb_needs_pot_stride_remap(intel_fb) && - !is_power_of_2(mode_cmd->pitches[i])) { - drm_dbg_kms(&dev_priv->drm, - "plane %d pitch (%d) must be power of two for tiled buffers\n", - i, mode_cmd->pitches[i]); - goto err; - } - - fb->obj[i] = &obj->base; - } - - ret = intel_fill_fb_info(dev_priv, intel_fb); - if (ret) - goto err; - - if (intel_fb_uses_dpt(fb)) { - struct i915_address_space *vm; - - vm = intel_dpt_create(intel_fb); - if (IS_ERR(vm)) { - ret = PTR_ERR(vm); - goto err; - } - - intel_fb->dpt_vm = vm; - } - - ret = drm_framebuffer_init(&dev_priv->drm, fb, &intel_fb_funcs); - if (ret) { - drm_err(&dev_priv->drm, "framebuffer init failed %d\n", ret); - goto err; - } - - return 0; - -err: - intel_frontbuffer_put(intel_fb->frontbuffer); - return ret; -} - -static struct drm_framebuffer * -intel_user_framebuffer_create(struct drm_device *dev, - struct drm_file *filp, - const struct drm_mode_fb_cmd2 *user_mode_cmd) -{ - struct drm_framebuffer *fb; - struct drm_i915_gem_object *obj; - struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd; - struct drm_i915_private *i915; - - obj = i915_gem_object_lookup(filp, mode_cmd.handles[0]); - if (!obj) - return ERR_PTR(-ENOENT); - - /* object is backed with LMEM for discrete */ - i915 = to_i915(obj->base.dev); - if (HAS_LMEM(i915) && !i915_gem_object_can_migrate(obj, INTEL_REGION_LMEM)) { - /* object is "remote", not in local memory */ - i915_gem_object_put(obj); - return ERR_PTR(-EREMOTE); - } - - fb = intel_framebuffer_create(obj, &mode_cmd); - i915_gem_object_put(obj); - - return fb; -} - static enum drm_mode_status intel_mode_valid(struct drm_device *dev, const struct drm_display_mode *mode) diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index e24ee2a28ebf..e4b8602ec0cd 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -4,9 +4,11 @@ */ #include +#include #include "intel_display.h" #include "intel_display_types.h" +#include "intel_dpt.h" #include "intel_fb.h" #define check_array_bounds(i915, a, i) drm_WARN_ON(&(i915)->drm, (i) >= ARRAY_SIZE(a)) @@ -61,6 +63,12 @@ int skl_ccs_to_main_plane(const struct drm_framebuffer *fb, int ccs_plane) return ccs_plane - fb->format->num_planes / 2; } +static int gen12_ccs_aux_stride(struct drm_framebuffer *fb, int ccs_plane) +{ + return DIV_ROUND_UP(fb->pitches[skl_ccs_to_main_plane(fb, ccs_plane)], + 512) * 64; +} + int skl_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane) { struct drm_i915_private *i915 = to_i915(fb->dev); @@ -172,6 +180,22 @@ intel_fb_align_height(const struct drm_framebuffer *fb, return ALIGN(height, tile_height); } +static unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier) +{ + switch (fb_modifier) { + case I915_FORMAT_MOD_X_TILED: + return I915_TILING_X; + case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Y_TILED_CCS: + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: + case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: + return I915_TILING_Y; + default: + return I915_TILING_NONE; + } +} + unsigned int intel_cursor_alignment(const struct drm_i915_private *i915) { if (IS_I830(i915)) @@ -1045,6 +1069,71 @@ void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotatio *view = fb->normal_view; } +static +u32 intel_fb_max_stride(struct drm_i915_private *dev_priv, + u32 pixel_format, u64 modifier) +{ + /* + * Arbitrary limit for gen4+ chosen to match the + * render engine max stride. + * + * The new CCS hash mode makes remapping impossible + */ + if (DISPLAY_VER(dev_priv) < 4 || is_ccs_modifier(modifier) || + intel_modifier_uses_dpt(dev_priv, modifier)) + return intel_plane_fb_max_stride(dev_priv, pixel_format, modifier); + else if (DISPLAY_VER(dev_priv) >= 7) + return 256 * 1024; + else + return 128 * 1024; +} + +static u32 +intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane) +{ + struct drm_i915_private *dev_priv = to_i915(fb->dev); + u32 tile_width; + + if (is_surface_linear(fb, color_plane)) { + u32 max_stride = intel_plane_fb_max_stride(dev_priv, + fb->format->format, + fb->modifier); + + /* + * To make remapping with linear generally feasible + * we need the stride to be page aligned. + */ + if (fb->pitches[color_plane] > max_stride && + !is_ccs_modifier(fb->modifier)) + return intel_tile_size(dev_priv); + else + return 64; + } + + tile_width = intel_tile_width_bytes(fb, color_plane); + if (is_ccs_modifier(fb->modifier)) { + /* + * Display WA #0531: skl,bxt,kbl,glk + * + * Render decompression and plane width > 3840 + * combined with horizontal panning requires the + * plane stride to be a multiple of 4. We'll just + * require the entire fb to accommodate that to avoid + * potential runtime errors at plane configuration time. + */ + if ((DISPLAY_VER(dev_priv) == 9 || IS_GEMINILAKE(dev_priv)) && + color_plane == 0 && fb->width > 3840) + tile_width *= 4; + /* + * The main surface pitch must be padded to a multiple of four + * tile widths. + */ + else if (DISPLAY_VER(dev_priv) >= 12) + tile_width *= 4; + } + return tile_width; +} + static int intel_plane_check_stride(const struct intel_plane_state *plane_state) { struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); @@ -1108,3 +1197,268 @@ int intel_plane_compute_gtt(struct intel_plane_state *plane_state) return intel_plane_check_stride(plane_state); } + +static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) +{ + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); + + drm_framebuffer_cleanup(fb); + + if (intel_fb_uses_dpt(fb)) + intel_dpt_destroy(intel_fb->dpt_vm); + + intel_frontbuffer_put(intel_fb->frontbuffer); + + kfree(intel_fb); +} + +static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, + struct drm_file *file, + unsigned int *handle) +{ + struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct drm_i915_private *i915 = to_i915(obj->base.dev); + + if (i915_gem_object_is_userptr(obj)) { + drm_dbg(&i915->drm, + "attempting to use a userptr for a framebuffer, denied\n"); + return -EINVAL; + } + + return drm_gem_handle_create(file, &obj->base, handle); +} + +static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, + struct drm_file *file, + unsigned int flags, unsigned int color, + struct drm_clip_rect *clips, + unsigned int num_clips) +{ + struct drm_i915_gem_object *obj = intel_fb_obj(fb); + + i915_gem_object_flush_if_display(obj); + intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB); + + return 0; +} + +static const struct drm_framebuffer_funcs intel_fb_funcs = { + .destroy = intel_user_framebuffer_destroy, + .create_handle = intel_user_framebuffer_create_handle, + .dirty = intel_user_framebuffer_dirty, +}; + +int intel_framebuffer_init(struct intel_framebuffer *intel_fb, + struct drm_i915_gem_object *obj, + struct drm_mode_fb_cmd2 *mode_cmd) +{ + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); + struct drm_framebuffer *fb = &intel_fb->base; + u32 max_stride; + unsigned int tiling, stride; + int ret = -EINVAL; + int i; + + intel_fb->frontbuffer = intel_frontbuffer_get(obj); + if (!intel_fb->frontbuffer) + return -ENOMEM; + + i915_gem_object_lock(obj, NULL); + tiling = i915_gem_object_get_tiling(obj); + stride = i915_gem_object_get_stride(obj); + i915_gem_object_unlock(obj); + + if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) { + /* + * If there's a fence, enforce that + * the fb modifier and tiling mode match. + */ + if (tiling != I915_TILING_NONE && + tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) { + drm_dbg_kms(&dev_priv->drm, + "tiling_mode doesn't match fb modifier\n"); + goto err; + } + } else { + if (tiling == I915_TILING_X) { + mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED; + } else if (tiling == I915_TILING_Y) { + drm_dbg_kms(&dev_priv->drm, + "No Y tiling for legacy addfb\n"); + goto err; + } + } + + if (!drm_any_plane_has_format(&dev_priv->drm, + mode_cmd->pixel_format, + mode_cmd->modifier[0])) { + drm_dbg_kms(&dev_priv->drm, + "unsupported pixel format %p4cc / modifier 0x%llx\n", + &mode_cmd->pixel_format, mode_cmd->modifier[0]); + goto err; + } + + /* + * gen2/3 display engine uses the fence if present, + * so the tiling mode must match the fb modifier exactly. + */ + if (DISPLAY_VER(dev_priv) < 4 && + tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) { + drm_dbg_kms(&dev_priv->drm, + "tiling_mode must match fb modifier exactly on gen2/3\n"); + goto err; + } + + max_stride = intel_fb_max_stride(dev_priv, mode_cmd->pixel_format, + mode_cmd->modifier[0]); + if (mode_cmd->pitches[0] > max_stride) { + drm_dbg_kms(&dev_priv->drm, + "%s pitch (%u) must be at most %d\n", + mode_cmd->modifier[0] != DRM_FORMAT_MOD_LINEAR ? + "tiled" : "linear", + mode_cmd->pitches[0], max_stride); + goto err; + } + + /* + * If there's a fence, enforce that + * the fb pitch and fence stride match. + */ + if (tiling != I915_TILING_NONE && mode_cmd->pitches[0] != stride) { + drm_dbg_kms(&dev_priv->drm, + "pitch (%d) must match tiling stride (%d)\n", + mode_cmd->pitches[0], stride); + goto err; + } + + /* FIXME need to adjust LINOFF/TILEOFF accordingly. */ + if (mode_cmd->offsets[0] != 0) { + drm_dbg_kms(&dev_priv->drm, + "plane 0 offset (0x%08x) must be 0\n", + mode_cmd->offsets[0]); + goto err; + } + + drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd); + + for (i = 0; i < fb->format->num_planes; i++) { + u32 stride_alignment; + + if (mode_cmd->handles[i] != mode_cmd->handles[0]) { + drm_dbg_kms(&dev_priv->drm, "bad plane %d handle\n", + i); + goto err; + } + + stride_alignment = intel_fb_stride_alignment(fb, i); + if (fb->pitches[i] & (stride_alignment - 1)) { + drm_dbg_kms(&dev_priv->drm, + "plane %d pitch (%d) must be at least %u byte aligned\n", + i, fb->pitches[i], stride_alignment); + goto err; + } + + if (is_gen12_ccs_plane(fb, i) && !is_gen12_ccs_cc_plane(fb, i)) { + int ccs_aux_stride = gen12_ccs_aux_stride(fb, i); + + if (fb->pitches[i] != ccs_aux_stride) { + drm_dbg_kms(&dev_priv->drm, + "ccs aux plane %d pitch (%d) must be %d\n", + i, + fb->pitches[i], ccs_aux_stride); + goto err; + } + } + + /* TODO: Add POT stride remapping support for CCS formats as well. */ + if (IS_ALDERLAKE_P(dev_priv) && + mode_cmd->modifier[i] != DRM_FORMAT_MOD_LINEAR && + !intel_fb_needs_pot_stride_remap(intel_fb) && + !is_power_of_2(mode_cmd->pitches[i])) { + drm_dbg_kms(&dev_priv->drm, + "plane %d pitch (%d) must be power of two for tiled buffers\n", + i, mode_cmd->pitches[i]); + goto err; + } + + fb->obj[i] = &obj->base; + } + + ret = intel_fill_fb_info(dev_priv, intel_fb); + if (ret) + goto err; + + if (intel_fb_uses_dpt(fb)) { + struct i915_address_space *vm; + + vm = intel_dpt_create(intel_fb); + if (IS_ERR(vm)) { + ret = PTR_ERR(vm); + goto err; + } + + intel_fb->dpt_vm = vm; + } + + ret = drm_framebuffer_init(&dev_priv->drm, fb, &intel_fb_funcs); + if (ret) { + drm_err(&dev_priv->drm, "framebuffer init failed %d\n", ret); + goto err; + } + + return 0; + +err: + intel_frontbuffer_put(intel_fb->frontbuffer); + return ret; +} + +struct drm_framebuffer * +intel_user_framebuffer_create(struct drm_device *dev, + struct drm_file *filp, + const struct drm_mode_fb_cmd2 *user_mode_cmd) +{ + struct drm_framebuffer *fb; + struct drm_i915_gem_object *obj; + struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd; + struct drm_i915_private *i915; + + obj = i915_gem_object_lookup(filp, mode_cmd.handles[0]); + if (!obj) + return ERR_PTR(-ENOENT); + + /* object is backed with LMEM for discrete */ + i915 = to_i915(obj->base.dev); + if (HAS_LMEM(i915) && !i915_gem_object_can_migrate(obj, INTEL_REGION_LMEM)) { + /* object is "remote", not in local memory */ + i915_gem_object_put(obj); + return ERR_PTR(-EREMOTE); + } + + fb = intel_framebuffer_create(obj, &mode_cmd); + i915_gem_object_put(obj); + + return fb; +} + +struct drm_framebuffer * +intel_framebuffer_create(struct drm_i915_gem_object *obj, + struct drm_mode_fb_cmd2 *mode_cmd) +{ + struct intel_framebuffer *intel_fb; + int ret; + + intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); + if (!intel_fb) + return ERR_PTR(-ENOMEM); + + ret = intel_framebuffer_init(intel_fb, obj, mode_cmd); + if (ret) + goto err; + + return &intel_fb->base; + +err: + kfree(intel_fb); + return ERR_PTR(ret); +} diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index 0b0a83139462..1cbdd84502bd 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -8,10 +8,12 @@ #include +struct drm_device; +struct drm_file; struct drm_framebuffer; - +struct drm_i915_gem_object; struct drm_i915_private; - +struct drm_mode_fb_cmd2; struct intel_fb_view; struct intel_framebuffer; struct intel_plane_state; @@ -57,4 +59,12 @@ void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotatio struct intel_fb_view *view); int intel_plane_compute_gtt(struct intel_plane_state *plane_state); +int intel_framebuffer_init(struct intel_framebuffer *ifb, + struct drm_i915_gem_object *obj, + struct drm_mode_fb_cmd2 *mode_cmd); +struct drm_framebuffer * +intel_user_framebuffer_create(struct drm_device *dev, + struct drm_file *filp, + const struct drm_mode_fb_cmd2 *user_mode_cmd); + #endif /* __INTEL_FB_H__ */ -- cgit v1.2.3 From 6b9376504cb486ffdf93ee1a98c5ce0d02699857 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 12 Jul 2021 19:18:14 +0300 Subject: drm/i915: Silence __iomem sparse warn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't care about __iomem mismatch when dealing with error pointers. Silence it with ERR_CAST(). drivers/gpu/drm/i915/display/intel_dpt.c:136:21: warning: incorrect type in assignment (different address spaces) drivers/gpu/drm/i915/display/intel_dpt.c:136:21: expected struct i915_vma *[assigned] vma drivers/gpu/drm/i915/display/intel_dpt.c:136:21: got void [noderef] __iomem *[assigned] iomem v2: The code moved into intel_dpt.c Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210712161815.24776-1-ville.syrjala@linux.intel.com Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/display/intel_dpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index 22acd945a9e4..de62bd77b15e 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -133,7 +133,7 @@ struct i915_vma *intel_dpt_pin(struct i915_address_space *vm) iomem = i915_vma_pin_iomap(vma); i915_vma_unpin(vma); if (IS_ERR(iomem)) { - vma = iomem; + vma = ERR_CAST(iomem); goto err; } -- cgit v1.2.3 From 35a17f93e03a1f69f7a869c90f6f5c3ba75228e3 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:18 +0300 Subject: drm/i915: Set output_types to EDP for vlv/chv DPLL forcing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we enable the DPLL for the PPS kick, let's tell the DPLL code we're dealing with an eDP output. This shouldn't really matter, but it's more consistent with the way the DPLL is configured when we're actually enabling the eDP port for real. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dpll.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 14515e62c05e..939a1a6e5c1e 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -1780,6 +1780,7 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, pipe_config->cpu_transcoder = (enum transcoder)pipe; pipe_config->pixel_multiplier = 1; pipe_config->dpll = *dpll; + pipe_config->output_types = BIT(INTEL_OUTPUT_EDP); if (IS_CHERRYVIEW(dev_priv)) { chv_compute_dpll(crtc, pipe_config); -- cgit v1.2.3 From 6501e6bb1458c2e61b0158625518c19bef9c7dce Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:19 +0300 Subject: drm/i915: Clean up gen2 DPLL readout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current gen2 DPLL readout code: * assumes i845/i865 have LVDS which is not true * assumes only pipe B can drive LVDS (true, but makes the code appear a bit magical) * hard to parse in general Clean it up by checking for i85x (the only gen2 platform with LVDS) and reusing intel_lvds_port_enabled(). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-3-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 794690c0dba5..13a92a3acb73 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6319,7 +6319,6 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - enum pipe pipe = crtc->pipe; u32 dpll = pipe_config->dpll_hw_state.dpll; u32 fp; struct dpll clock; @@ -6369,11 +6368,13 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, else port_clock = i9xx_calc_dpll_params(refclk, &clock); } else { - u32 lvds = IS_I830(dev_priv) ? 0 : intel_de_read(dev_priv, - LVDS); - bool is_lvds = (pipe == 1) && (lvds & LVDS_PORT_EN); + enum pipe lvds_pipe; + + if (IS_I85X(dev_priv) && + intel_lvds_port_enabled(dev_priv, LVDS, &lvds_pipe) && + lvds_pipe == crtc->pipe) { + u32 lvds = intel_de_read(dev_priv, LVDS); - if (is_lvds) { clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> DPLL_FPA01_P1_POST_DIV_SHIFT); -- cgit v1.2.3 From b294425e9091239330dcb9d3aa3ac160ca05d0e7 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:20 +0300 Subject: drm/i915: Extract ilk_update_pll_dividers() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the PCH dpll code match the gmch code by splitting the FP register handling out from ilk_compute_dpll(). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-4-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dpll.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 939a1a6e5c1e..e2ca6f2108d1 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -948,12 +948,12 @@ static bool ilk_needs_fb_cb_tune(struct dpll *dpll, int factor) } -static void ilk_compute_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state, - struct dpll *reduced_clock) +static void ilk_update_pll_dividers(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state, + struct dpll *reduced_clock) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - u32 dpll, fp, fp2; + u32 fp, fp2 = 0; int factor; /* Enable autotuning of the PLL clock (if permissible) */ @@ -978,10 +978,21 @@ static void ilk_compute_dpll(struct intel_crtc *crtc, if (reduced_clock->m < factor * reduced_clock->n) fp2 |= FP_CB_TUNE; - } else { - fp2 = fp; } + crtc_state->dpll_hw_state.fp0 = fp; + crtc_state->dpll_hw_state.fp1 = reduced_clock ? fp2 : fp; +} + +static void ilk_compute_dpll(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state, + struct dpll *reduced_clock) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + u32 dpll; + + ilk_update_pll_dividers(crtc, crtc_state, reduced_clock); + dpll = 0; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) @@ -1046,8 +1057,6 @@ static void ilk_compute_dpll(struct intel_crtc *crtc, dpll |= DPLL_VCO_ENABLE; crtc_state->dpll_hw_state.dpll = dpll; - crtc_state->dpll_hw_state.fp0 = fp; - crtc_state->dpll_hw_state.fp1 = fp2; } static int ilk_crtc_compute_clock(struct intel_crtc *crtc, -- cgit v1.2.3 From 24951b5813c1d070f283bd9a0d97a76cd3f8ac54 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:21 +0300 Subject: drm/i915: Constify struct dpll all over MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lots of places don't need to modify the DPLL params, so make them const. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-5-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_types.h | 5 -- drivers/gpu/drm/i915/display/intel_dpll.c | 58 +++++++++++++--------- drivers/gpu/drm/i915/display/intel_dpll.h | 1 + 3 files changed, 36 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index c2725d07b930..c7bcf9183447 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -2035,11 +2035,6 @@ to_intel_frontbuffer(struct drm_framebuffer *fb) return fb ? to_intel_framebuffer(fb)->frontbuffer : NULL; } -static inline u32 i9xx_dpll_compute_fp(struct dpll *dpll) -{ - return dpll->n << 16 | dpll->m1 << 8 | dpll->m2; -} - static inline bool is_ccs_modifier(u64 modifier) { return modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS || diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index e2ca6f2108d1..0e9141f62f45 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -309,7 +309,7 @@ int pnv_calc_dpll_params(int refclk, struct dpll *clock) return clock->dot; } -static u32 i9xx_dpll_compute_m(struct dpll *dpll) +static u32 i9xx_dpll_compute_m(const struct dpll *dpll) { return 5 * (dpll->m1 + 2) + (dpll->m2 + 2); } @@ -428,7 +428,8 @@ i9xx_select_p2_div(const struct intel_limit *limit, static bool i9xx_find_best_dpll(const struct intel_limit *limit, struct intel_crtc_state *crtc_state, - int target, int refclk, struct dpll *match_clock, + int target, int refclk, + const struct dpll *match_clock, struct dpll *best_clock) { struct drm_device *dev = crtc_state->uapi.crtc->dev; @@ -486,7 +487,8 @@ i9xx_find_best_dpll(const struct intel_limit *limit, static bool pnv_find_best_dpll(const struct intel_limit *limit, struct intel_crtc_state *crtc_state, - int target, int refclk, struct dpll *match_clock, + int target, int refclk, + const struct dpll *match_clock, struct dpll *best_clock) { struct drm_device *dev = crtc_state->uapi.crtc->dev; @@ -542,7 +544,8 @@ pnv_find_best_dpll(const struct intel_limit *limit, static bool g4x_find_best_dpll(const struct intel_limit *limit, struct intel_crtc_state *crtc_state, - int target, int refclk, struct dpll *match_clock, + int target, int refclk, + const struct dpll *match_clock, struct dpll *best_clock) { struct drm_device *dev = crtc_state->uapi.crtc->dev; @@ -636,7 +639,8 @@ static bool vlv_PLL_is_optimal(struct drm_device *dev, int target_freq, static bool vlv_find_best_dpll(const struct intel_limit *limit, struct intel_crtc_state *crtc_state, - int target, int refclk, struct dpll *match_clock, + int target, int refclk, + const struct dpll *match_clock, struct dpll *best_clock) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -696,7 +700,8 @@ vlv_find_best_dpll(const struct intel_limit *limit, static bool chv_find_best_dpll(const struct intel_limit *limit, struct intel_crtc_state *crtc_state, - int target, int refclk, struct dpll *match_clock, + int target, int refclk, + const struct dpll *match_clock, struct dpll *best_clock) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -763,24 +768,30 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, NULL, best_clock); } -static u32 pnv_dpll_compute_fp(struct dpll *dpll) +u32 i9xx_dpll_compute_fp(const struct dpll *dpll) +{ + return dpll->n << 16 | dpll->m1 << 8 | dpll->m2; +} + +static u32 pnv_dpll_compute_fp(const struct dpll *dpll) { return (1 << dpll->n) << 16 | dpll->m2; } static void i9xx_update_pll_dividers(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, - struct dpll *reduced_clock) + const struct dpll *reduced_clock) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct dpll *clock = &crtc_state->dpll; u32 fp, fp2 = 0; if (IS_PINEVIEW(dev_priv)) { - fp = pnv_dpll_compute_fp(&crtc_state->dpll); + fp = pnv_dpll_compute_fp(clock); if (reduced_clock) fp2 = pnv_dpll_compute_fp(reduced_clock); } else { - fp = i9xx_dpll_compute_fp(&crtc_state->dpll); + fp = i9xx_dpll_compute_fp(clock); if (reduced_clock) fp2 = i9xx_dpll_compute_fp(reduced_clock); } @@ -797,11 +808,11 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc, static void i9xx_compute_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, - struct dpll *reduced_clock) + const struct dpll *reduced_clock) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct dpll *clock = &crtc_state->dpll; u32 dpll; - struct dpll *clock = &crtc_state->dpll; i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock); @@ -870,12 +881,12 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, static void i8xx_compute_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, - struct dpll *reduced_clock) + const struct dpll *reduced_clock) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); + const struct dpll *clock = &crtc_state->dpll; u32 dpll; - struct dpll *clock = &crtc_state->dpll; i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock); @@ -942,17 +953,17 @@ static int hsw_crtc_compute_clock(struct intel_crtc *crtc, return 0; } -static bool ilk_needs_fb_cb_tune(struct dpll *dpll, int factor) +static bool ilk_needs_fb_cb_tune(const struct dpll *dpll, int factor) { return i9xx_dpll_compute_m(dpll) < factor * dpll->n; } - static void ilk_update_pll_dividers(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, - struct dpll *reduced_clock) + const struct dpll *reduced_clock) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct dpll *clock = &crtc_state->dpll; u32 fp, fp2 = 0; int factor; @@ -968,9 +979,9 @@ static void ilk_update_pll_dividers(struct intel_crtc *crtc, factor = 20; } - fp = i9xx_dpll_compute_fp(&crtc_state->dpll); + fp = i9xx_dpll_compute_fp(clock); - if (ilk_needs_fb_cb_tune(&crtc_state->dpll, factor)) + if (ilk_needs_fb_cb_tune(clock, factor)) fp |= FP_CB_TUNE; if (reduced_clock) { @@ -986,9 +997,10 @@ static void ilk_update_pll_dividers(struct intel_crtc *crtc, static void ilk_compute_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, - struct dpll *reduced_clock) + const struct dpll *reduced_clock) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct dpll *clock = &crtc_state->dpll; u32 dpll; ilk_update_pll_dividers(crtc, crtc_state, reduced_clock); @@ -1029,11 +1041,11 @@ static void ilk_compute_dpll(struct intel_crtc *crtc, dpll |= DPLL_SDVO_HIGH_SPEED; /* compute bitmask from p1 value */ - dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; + dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; /* also FPA1 */ - dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; + dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; - switch (crtc_state->dpll.p2) { + switch (clock->p2) { case 5: dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; break; diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h b/drivers/gpu/drm/i915/display/intel_dpll.h index 88247027fd5a..e2f845902abf 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.h +++ b/drivers/gpu/drm/i915/display/intel_dpll.h @@ -18,6 +18,7 @@ void intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv); int vlv_calc_dpll_params(int refclk, struct dpll *clock); int pnv_calc_dpll_params(int refclk, struct dpll *clock); int i9xx_calc_dpll_params(int refclk, struct dpll *clock); +u32 i9xx_dpll_compute_fp(const struct dpll *dpll); void vlv_compute_dpll(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config); void chv_compute_dpll(struct intel_crtc *crtc, -- cgit v1.2.3 From 6205372b4b6dab7fc000a00c7703c68fe4cf5c8b Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:22 +0300 Subject: drm/i915: Clean dpll calling convention MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop passing both the crtc and its state to the DPLL functions. The state alone is enough. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-6-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 12 +-- drivers/gpu/drm/i915/display/intel_dpll.c | 142 +++++++++++++-------------- drivers/gpu/drm/i915/display/intel_dpll.h | 21 ++-- drivers/gpu/drm/i915/i915_drv.h | 3 +- 4 files changed, 82 insertions(+), 96 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 13a92a3acb73..e288afa9667d 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3577,11 +3577,11 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, intel_encoders_pre_pll_enable(state, crtc); if (IS_CHERRYVIEW(dev_priv)) { - chv_prepare_pll(crtc, new_crtc_state); - chv_enable_pll(crtc, new_crtc_state); + chv_prepare_pll(new_crtc_state); + chv_enable_pll(new_crtc_state); } else { - vlv_prepare_pll(crtc, new_crtc_state); - vlv_enable_pll(crtc, new_crtc_state); + vlv_prepare_pll(new_crtc_state); + vlv_enable_pll(new_crtc_state); } intel_encoders_pre_enable(state, crtc); @@ -3640,7 +3640,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, intel_encoders_pre_enable(state, crtc); - i9xx_enable_pll(crtc, new_crtc_state); + i9xx_enable_pll(new_crtc_state); i9xx_pfit_enable(new_crtc_state); @@ -6906,7 +6906,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state, dev_priv->display.crtc_compute_clock && !crtc_state->bigjoiner_slave && !drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll)) { - ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state); + ret = dev_priv->display.crtc_compute_clock(crtc_state); if (ret) return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 0e9141f62f45..75de70251530 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -778,10 +778,10 @@ static u32 pnv_dpll_compute_fp(const struct dpll *dpll) return (1 << dpll->n) << 16 | dpll->m2; } -static void i9xx_update_pll_dividers(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state, +static void i9xx_update_pll_dividers(struct intel_crtc_state *crtc_state, const struct dpll *reduced_clock) { + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct dpll *clock = &crtc_state->dpll; u32 fp, fp2 = 0; @@ -806,15 +806,15 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc, } } -static void i9xx_compute_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state, +static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state, const struct dpll *reduced_clock) { + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct dpll *clock = &crtc_state->dpll; u32 dpll; - i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock); + i9xx_update_pll_dividers(crtc_state, reduced_clock); dpll = DPLL_VGA_MODE_DIS; @@ -879,16 +879,15 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, } } -static void i8xx_compute_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state, +static void i8xx_compute_dpll(struct intel_crtc_state *crtc_state, const struct dpll *reduced_clock) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct dpll *clock = &crtc_state->dpll; u32 dpll; - i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock); + i9xx_update_pll_dividers(crtc_state, reduced_clock); dpll = DPLL_VGA_MODE_DIS; @@ -929,9 +928,9 @@ static void i8xx_compute_dpll(struct intel_crtc *crtc, crtc_state->dpll_hw_state.dpll = dpll; } -static int hsw_crtc_compute_clock(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) +static int hsw_crtc_compute_clock(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); struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state); @@ -958,10 +957,10 @@ static bool ilk_needs_fb_cb_tune(const struct dpll *dpll, int factor) return i9xx_dpll_compute_m(dpll) < factor * dpll->n; } -static void ilk_update_pll_dividers(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state, +static void ilk_update_pll_dividers(struct intel_crtc_state *crtc_state, const struct dpll *reduced_clock) { + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct dpll *clock = &crtc_state->dpll; u32 fp, fp2 = 0; @@ -995,15 +994,15 @@ static void ilk_update_pll_dividers(struct intel_crtc *crtc, crtc_state->dpll_hw_state.fp1 = reduced_clock ? fp2 : fp; } -static void ilk_compute_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state, +static void ilk_compute_dpll(struct intel_crtc_state *crtc_state, const struct dpll *reduced_clock) { + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct dpll *clock = &crtc_state->dpll; u32 dpll; - ilk_update_pll_dividers(crtc, crtc_state, reduced_clock); + ilk_update_pll_dividers(crtc_state, reduced_clock); dpll = 0; @@ -1071,9 +1070,9 @@ static void ilk_compute_dpll(struct intel_crtc *crtc, crtc_state->dpll_hw_state.dpll = dpll; } -static int ilk_crtc_compute_clock(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) +static int ilk_crtc_compute_clock(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); struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state); @@ -1118,7 +1117,7 @@ static int ilk_crtc_compute_clock(struct intel_crtc *crtc, return -EINVAL; } - ilk_compute_dpll(crtc, crtc_state, NULL); + ilk_compute_dpll(crtc_state, NULL); if (!intel_reserve_shared_dplls(state, crtc, NULL)) { drm_dbg_kms(&dev_priv->drm, @@ -1130,9 +1129,10 @@ static int ilk_crtc_compute_clock(struct intel_crtc *crtc, return 0; } -void vlv_compute_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config) +void vlv_compute_dpll(struct intel_crtc_state *pipe_config) { + struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + pipe_config->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV | DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; if (crtc->pipe != PIPE_A) @@ -1147,9 +1147,10 @@ void vlv_compute_dpll(struct intel_crtc *crtc, (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; } -void chv_compute_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config) +void chv_compute_dpll(struct intel_crtc_state *pipe_config) { + struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + pipe_config->dpll_hw_state.dpll = DPLL_SSC_REF_CLK_CHV | DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; if (crtc->pipe != PIPE_A) @@ -1163,8 +1164,7 @@ void chv_compute_dpll(struct intel_crtc *crtc, (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; } -static int chv_crtc_compute_clock(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) +static int chv_crtc_compute_clock(struct intel_crtc_state *crtc_state) { int refclk = 100000; const struct intel_limit *limit = &intel_limits_chv; @@ -1180,13 +1180,12 @@ static int chv_crtc_compute_clock(struct intel_crtc *crtc, return -EINVAL; } - chv_compute_dpll(crtc, crtc_state); + chv_compute_dpll(crtc_state); return 0; } -static int vlv_crtc_compute_clock(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) +static int vlv_crtc_compute_clock(struct intel_crtc_state *crtc_state) { int refclk = 100000; const struct intel_limit *limit = &intel_limits_vlv; @@ -1202,14 +1201,14 @@ static int vlv_crtc_compute_clock(struct intel_crtc *crtc, return -EINVAL; } - vlv_compute_dpll(crtc, crtc_state); + vlv_compute_dpll(crtc_state); return 0; } -static int g4x_crtc_compute_clock(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) +static int g4x_crtc_compute_clock(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); const struct intel_limit *limit; int refclk = 96000; @@ -1247,16 +1246,15 @@ static int g4x_crtc_compute_clock(struct intel_crtc *crtc, return -EINVAL; } - i9xx_compute_dpll(crtc, crtc_state, NULL); + i9xx_compute_dpll(crtc_state, NULL); return 0; } -static int pnv_crtc_compute_clock(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) +static int pnv_crtc_compute_clock(struct intel_crtc_state *crtc_state) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct intel_limit *limit; int refclk = 96000; @@ -1284,16 +1282,15 @@ static int pnv_crtc_compute_clock(struct intel_crtc *crtc, return -EINVAL; } - i9xx_compute_dpll(crtc, crtc_state, NULL); + i9xx_compute_dpll(crtc_state, NULL); return 0; } -static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) +static int i9xx_crtc_compute_clock(struct intel_crtc_state *crtc_state) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct intel_limit *limit; int refclk = 96000; @@ -1321,16 +1318,15 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, return -EINVAL; } - i9xx_compute_dpll(crtc, crtc_state, NULL); + i9xx_compute_dpll(crtc_state, NULL); return 0; } -static int i8xx_crtc_compute_clock(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state) +static int i8xx_crtc_compute_clock(struct intel_crtc_state *crtc_state) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct intel_limit *limit; int refclk = 48000; @@ -1360,7 +1356,7 @@ static int i8xx_crtc_compute_clock(struct intel_crtc *crtc, return -EINVAL; } - i8xx_compute_dpll(crtc, crtc_state, NULL); + i8xx_compute_dpll(crtc_state, NULL); return 0; } @@ -1394,9 +1390,9 @@ static bool i9xx_has_pps(struct drm_i915_private *dev_priv) return IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv); } -void i9xx_enable_pll(struct intel_crtc *crtc, - const struct intel_crtc_state *crtc_state) +void i9xx_enable_pll(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 = DPLL(crtc->pipe); u32 dpll = crtc_state->dpll_hw_state.dpll; @@ -1469,9 +1465,9 @@ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val); } -static void _vlv_enable_pll(struct intel_crtc *crtc, - const struct intel_crtc_state *pipe_config) +static void _vlv_enable_pll(const struct intel_crtc_state *pipe_config) { + struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; @@ -1483,9 +1479,9 @@ static void _vlv_enable_pll(struct intel_crtc *crtc, drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe); } -void vlv_enable_pll(struct intel_crtc *crtc, - const struct intel_crtc_state *pipe_config) +void vlv_enable_pll(const struct intel_crtc_state *pipe_config) { + struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; @@ -1495,7 +1491,7 @@ void vlv_enable_pll(struct intel_crtc *crtc, assert_panel_unlocked(dev_priv, pipe); if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) - _vlv_enable_pll(crtc, pipe_config); + _vlv_enable_pll(pipe_config); intel_de_write(dev_priv, DPLL_MD(pipe), pipe_config->dpll_hw_state.dpll_md); @@ -1503,9 +1499,9 @@ void vlv_enable_pll(struct intel_crtc *crtc, } -static void _chv_enable_pll(struct intel_crtc *crtc, - const struct intel_crtc_state *pipe_config) +static void _chv_enable_pll(const struct intel_crtc_state *pipe_config) { + struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; enum dpio_channel port = vlv_pipe_to_channel(pipe); @@ -1533,9 +1529,9 @@ static void _chv_enable_pll(struct intel_crtc *crtc, drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe); } -void chv_enable_pll(struct intel_crtc *crtc, - const struct intel_crtc_state *pipe_config) +void chv_enable_pll(const struct intel_crtc_state *pipe_config) { + struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; @@ -1545,7 +1541,7 @@ void chv_enable_pll(struct intel_crtc *crtc, assert_panel_unlocked(dev_priv, pipe); if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) - _chv_enable_pll(crtc, pipe_config); + _chv_enable_pll(pipe_config); if (pipe != PIPE_A) { /* @@ -1574,11 +1570,10 @@ void chv_enable_pll(struct intel_crtc *crtc, } } -void vlv_prepare_pll(struct intel_crtc *crtc, - const struct intel_crtc_state *pipe_config) +void vlv_prepare_pll(const struct intel_crtc_state *pipe_config) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; u32 mdiv; u32 bestn, bestm1, bestm2, bestp1, bestp2; @@ -1673,11 +1668,10 @@ void vlv_prepare_pll(struct intel_crtc *crtc, vlv_dpio_put(dev_priv); } -void chv_prepare_pll(struct intel_crtc *crtc, - const struct intel_crtc_state *pipe_config) +void chv_prepare_pll(const struct intel_crtc_state *pipe_config) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; enum dpio_channel port = vlv_pipe_to_channel(pipe); u32 loopfilter, tribuf_calcntr; @@ -1804,13 +1798,13 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, pipe_config->output_types = BIT(INTEL_OUTPUT_EDP); if (IS_CHERRYVIEW(dev_priv)) { - chv_compute_dpll(crtc, pipe_config); - chv_prepare_pll(crtc, pipe_config); - chv_enable_pll(crtc, pipe_config); + chv_compute_dpll(pipe_config); + chv_prepare_pll(pipe_config); + chv_enable_pll(pipe_config); } else { - vlv_compute_dpll(crtc, pipe_config); - vlv_prepare_pll(crtc, pipe_config); - vlv_enable_pll(crtc, pipe_config); + vlv_compute_dpll(pipe_config); + vlv_prepare_pll(pipe_config); + vlv_enable_pll(pipe_config); } kfree(pipe_config); diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h b/drivers/gpu/drm/i915/display/intel_dpll.h index e2f845902abf..29f31075cdf0 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.h +++ b/drivers/gpu/drm/i915/display/intel_dpll.h @@ -19,27 +19,20 @@ int vlv_calc_dpll_params(int refclk, struct dpll *clock); int pnv_calc_dpll_params(int refclk, struct dpll *clock); int i9xx_calc_dpll_params(int refclk, struct dpll *clock); u32 i9xx_dpll_compute_fp(const struct dpll *dpll); -void vlv_compute_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config); -void chv_compute_dpll(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config); +void vlv_compute_dpll(struct intel_crtc_state *crtc_state); +void chv_compute_dpll(struct intel_crtc_state *crtc_state); int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, const struct dpll *dpll); void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe); -void i9xx_enable_pll(struct intel_crtc *crtc, - const struct intel_crtc_state *crtc_state); -void vlv_enable_pll(struct intel_crtc *crtc, - const struct intel_crtc_state *pipe_config); -void chv_enable_pll(struct intel_crtc *crtc, - const struct intel_crtc_state *pipe_config); +void i9xx_enable_pll(const struct intel_crtc_state *crtc_state); +void vlv_enable_pll(const struct intel_crtc_state *crtc_state); +void chv_enable_pll(const struct intel_crtc_state *crtc_state); void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe); void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe); void i9xx_disable_pll(const struct intel_crtc_state *crtc_state); -void vlv_prepare_pll(struct intel_crtc *crtc, - const struct intel_crtc_state *pipe_config); -void chv_prepare_pll(struct intel_crtc *crtc, - const struct intel_crtc_state *pipe_config); +void vlv_prepare_pll(const struct intel_crtc_state *crtc_state); +void chv_prepare_pll(const struct intel_crtc_state *crtc_state); bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, struct dpll *best_clock); int chv_calc_dpll_params(int refclk, struct dpll *pll_clock); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 106f218cec2b..f64ba566fe8c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -352,8 +352,7 @@ struct drm_i915_display_funcs { struct intel_crtc_state *); void (*get_initial_plane_config)(struct intel_crtc *, struct intel_initial_plane_config *); - int (*crtc_compute_clock)(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state); + int (*crtc_compute_clock)(struct intel_crtc_state *crtc_state); void (*crtc_enable)(struct intel_atomic_state *state, struct intel_crtc *crtc); void (*crtc_disable)(struct intel_atomic_state *state, -- cgit v1.2.3 From 8a3b3df3975791100346255a56abe6c46adefcb5 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:23 +0300 Subject: drm/i915: Clean up variable names in old dpll functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit s/pipe_config/crtc_state/ in the DPLL code. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-7-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dpll.c | 151 +++++++++++++++--------------- 1 file changed, 76 insertions(+), 75 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 75de70251530..846f8e053b74 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -1129,39 +1129,39 @@ static int ilk_crtc_compute_clock(struct intel_crtc_state *crtc_state) return 0; } -void vlv_compute_dpll(struct intel_crtc_state *pipe_config) +void vlv_compute_dpll(struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - pipe_config->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV | + crtc_state->dpll_hw_state.dpll = DPLL_INTEGRATED_REF_CLK_VLV | DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; if (crtc->pipe != PIPE_A) - pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; + crtc_state->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; /* DPLL not used with DSI, but still need the rest set up */ - if (!intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DSI)) - pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE | + if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) + crtc_state->dpll_hw_state.dpll |= DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV; - pipe_config->dpll_hw_state.dpll_md = - (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; + crtc_state->dpll_hw_state.dpll_md = + (crtc_state->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; } -void chv_compute_dpll(struct intel_crtc_state *pipe_config) +void chv_compute_dpll(struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - pipe_config->dpll_hw_state.dpll = DPLL_SSC_REF_CLK_CHV | + crtc_state->dpll_hw_state.dpll = DPLL_SSC_REF_CLK_CHV | DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; if (crtc->pipe != PIPE_A) - pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; + crtc_state->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; /* DPLL not used with DSI, but still need the rest set up */ - if (!intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DSI)) - pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE; + if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) + crtc_state->dpll_hw_state.dpll |= DPLL_VCO_ENABLE; - pipe_config->dpll_hw_state.dpll_md = - (pipe_config->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; + crtc_state->dpll_hw_state.dpll_md = + (crtc_state->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; } static int chv_crtc_compute_clock(struct intel_crtc_state *crtc_state) @@ -1465,13 +1465,13 @@ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val); } -static void _vlv_enable_pll(const struct intel_crtc_state *pipe_config) +static void _vlv_enable_pll(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - intel_de_write(dev_priv, DPLL(pipe), pipe_config->dpll_hw_state.dpll); + intel_de_write(dev_priv, DPLL(pipe), crtc_state->dpll_hw_state.dpll); intel_de_posting_read(dev_priv, DPLL(pipe)); udelay(150); @@ -1479,29 +1479,29 @@ static void _vlv_enable_pll(const struct intel_crtc_state *pipe_config) drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe); } -void vlv_enable_pll(const struct intel_crtc_state *pipe_config) +void vlv_enable_pll(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder); + assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ assert_panel_unlocked(dev_priv, pipe); - if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) - _vlv_enable_pll(pipe_config); + if (crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) + _vlv_enable_pll(crtc_state); intel_de_write(dev_priv, DPLL_MD(pipe), - pipe_config->dpll_hw_state.dpll_md); + crtc_state->dpll_hw_state.dpll_md); intel_de_posting_read(dev_priv, DPLL_MD(pipe)); } -static void _chv_enable_pll(const struct intel_crtc_state *pipe_config) +static void _chv_enable_pll(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; enum dpio_channel port = vlv_pipe_to_channel(pipe); @@ -1522,26 +1522,26 @@ static void _chv_enable_pll(const struct intel_crtc_state *pipe_config) udelay(1); /* Enable PLL */ - intel_de_write(dev_priv, DPLL(pipe), pipe_config->dpll_hw_state.dpll); + intel_de_write(dev_priv, DPLL(pipe), crtc_state->dpll_hw_state.dpll); /* Check PLL is locked */ if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1)) drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe); } -void chv_enable_pll(const struct intel_crtc_state *pipe_config) +void chv_enable_pll(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder); + assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ assert_panel_unlocked(dev_priv, pipe); - if (pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) - _chv_enable_pll(pipe_config); + if (crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) + _chv_enable_pll(crtc_state); if (pipe != PIPE_A) { /* @@ -1552,9 +1552,9 @@ void chv_enable_pll(const struct intel_crtc_state *pipe_config) */ intel_de_write(dev_priv, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe)); intel_de_write(dev_priv, DPLL_MD(PIPE_B), - pipe_config->dpll_hw_state.dpll_md); + crtc_state->dpll_hw_state.dpll_md); intel_de_write(dev_priv, CBR4_VLV, 0); - dev_priv->chv_dpll_md[pipe] = pipe_config->dpll_hw_state.dpll_md; + dev_priv->chv_dpll_md[pipe] = crtc_state->dpll_hw_state.dpll_md; /* * DPLLB VGA mode also seems to cause problems. @@ -1565,14 +1565,14 @@ void chv_enable_pll(const struct intel_crtc_state *pipe_config) DPLL_VGA_MODE_DIS) == 0); } else { intel_de_write(dev_priv, DPLL_MD(pipe), - pipe_config->dpll_hw_state.dpll_md); + crtc_state->dpll_hw_state.dpll_md); intel_de_posting_read(dev_priv, DPLL_MD(pipe)); } } -void vlv_prepare_pll(const struct intel_crtc_state *pipe_config) +void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; u32 mdiv; @@ -1581,19 +1581,20 @@ void vlv_prepare_pll(const struct intel_crtc_state *pipe_config) /* Enable Refclk */ intel_de_write(dev_priv, DPLL(pipe), - pipe_config->dpll_hw_state.dpll & ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV)); + crtc_state->dpll_hw_state.dpll & + ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV)); /* No need to actually set up the DPLL with DSI */ - if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0) + if ((crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0) return; vlv_dpio_get(dev_priv); - bestn = pipe_config->dpll.n; - bestm1 = pipe_config->dpll.m1; - bestm2 = pipe_config->dpll.m2; - bestp1 = pipe_config->dpll.p1; - bestp2 = pipe_config->dpll.p2; + bestn = crtc_state->dpll.n; + bestm1 = crtc_state->dpll.m1; + bestm2 = crtc_state->dpll.m2; + bestp1 = crtc_state->dpll.p1; + bestp2 = crtc_state->dpll.p2; /* See eDP HDMI DPIO driver vbios notes doc */ @@ -1630,16 +1631,16 @@ void vlv_prepare_pll(const struct intel_crtc_state *pipe_config) vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW3(pipe), mdiv); /* Set HBR and RBR LPF coefficients */ - if (pipe_config->port_clock == 162000 || - intel_crtc_has_type(pipe_config, INTEL_OUTPUT_ANALOG) || - intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) + if (crtc_state->port_clock == 162000 || + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG) || + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe), 0x009f0003); else vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe), 0x00d0000f); - if (intel_crtc_has_dp_encoder(pipe_config)) { + if (intel_crtc_has_dp_encoder(crtc_state)) { /* Use SSC source */ if (pipe == PIPE_A) vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe), @@ -1659,7 +1660,7 @@ void vlv_prepare_pll(const struct intel_crtc_state *pipe_config) coreclk = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW7(pipe)); coreclk = (coreclk & 0x0000ff00) | 0x01c00000; - if (intel_crtc_has_dp_encoder(pipe_config)) + if (intel_crtc_has_dp_encoder(crtc_state)) coreclk |= 0x01000000; vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk); @@ -1668,9 +1669,9 @@ void vlv_prepare_pll(const struct intel_crtc_state *pipe_config) vlv_dpio_put(dev_priv); } -void chv_prepare_pll(const struct intel_crtc_state *pipe_config) +void chv_prepare_pll(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; enum dpio_channel port = vlv_pipe_to_channel(pipe); @@ -1681,19 +1682,19 @@ void chv_prepare_pll(const struct intel_crtc_state *pipe_config) /* Enable Refclk and SSC */ intel_de_write(dev_priv, DPLL(pipe), - pipe_config->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE); + crtc_state->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE); /* No need to actually set up the DPLL with DSI */ - if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0) + if ((crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0) return; - bestn = pipe_config->dpll.n; - bestm2_frac = pipe_config->dpll.m2 & 0x3fffff; - bestm1 = pipe_config->dpll.m1; - bestm2 = pipe_config->dpll.m2 >> 22; - bestp1 = pipe_config->dpll.p1; - bestp2 = pipe_config->dpll.p2; - vco = pipe_config->dpll.vco; + bestn = crtc_state->dpll.n; + bestm2_frac = crtc_state->dpll.m2 & 0x3fffff; + bestm1 = crtc_state->dpll.m1; + bestm2 = crtc_state->dpll.m2 >> 22; + bestp1 = crtc_state->dpll.p1; + bestp2 = crtc_state->dpll.p2; + vco = crtc_state->dpll.vco; dpio_val = 0; loopfilter = 0; @@ -1786,28 +1787,28 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, const struct dpll *dpll) { struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); - struct intel_crtc_state *pipe_config; + struct intel_crtc_state *crtc_state; - pipe_config = intel_crtc_state_alloc(crtc); - if (!pipe_config) + crtc_state = intel_crtc_state_alloc(crtc); + if (!crtc_state) return -ENOMEM; - pipe_config->cpu_transcoder = (enum transcoder)pipe; - pipe_config->pixel_multiplier = 1; - pipe_config->dpll = *dpll; - pipe_config->output_types = BIT(INTEL_OUTPUT_EDP); + crtc_state->cpu_transcoder = (enum transcoder)pipe; + crtc_state->pixel_multiplier = 1; + crtc_state->dpll = *dpll; + crtc_state->output_types = BIT(INTEL_OUTPUT_EDP); if (IS_CHERRYVIEW(dev_priv)) { - chv_compute_dpll(pipe_config); - chv_prepare_pll(pipe_config); - chv_enable_pll(pipe_config); + chv_compute_dpll(crtc_state); + chv_prepare_pll(crtc_state); + chv_enable_pll(crtc_state); } else { - vlv_compute_dpll(pipe_config); - vlv_prepare_pll(pipe_config); - vlv_enable_pll(pipe_config); + vlv_compute_dpll(crtc_state); + vlv_prepare_pll(crtc_state); + vlv_enable_pll(crtc_state); } - kfree(pipe_config); + kfree(crtc_state); return 0; } -- cgit v1.2.3 From 510e890e8222443bbfc74083cb8e0797665fcaaa Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:24 +0300 Subject: drm/i915: Remove the 'reg' local variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Get rid of the local 'reg' variable for the DPLL control register in i9xx_enable_pll(). We have other registers in there too so this is just making things more confusing. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-8-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dpll.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 846f8e053b74..37e02168b81c 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -1394,30 +1394,30 @@ void i9xx_enable_pll(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 = DPLL(crtc->pipe); u32 dpll = crtc_state->dpll_hw_state.dpll; + enum pipe pipe = crtc->pipe; int i; assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ if (i9xx_has_pps(dev_priv)) - assert_panel_unlocked(dev_priv, crtc->pipe); + assert_panel_unlocked(dev_priv, pipe); /* * Apparently we need to have VGA mode enabled prior to changing * the P1/P2 dividers. Otherwise the DPLL will keep using the old * dividers, even though the register value does change. */ - intel_de_write(dev_priv, reg, dpll & ~DPLL_VGA_MODE_DIS); - intel_de_write(dev_priv, reg, dpll); + intel_de_write(dev_priv, DPLL(pipe), dpll & ~DPLL_VGA_MODE_DIS); + intel_de_write(dev_priv, DPLL(pipe), dpll); /* Wait for the clocks to stabilize. */ - intel_de_posting_read(dev_priv, reg); + intel_de_posting_read(dev_priv, DPLL(pipe)); udelay(150); if (DISPLAY_VER(dev_priv) >= 4) { - intel_de_write(dev_priv, DPLL_MD(crtc->pipe), + intel_de_write(dev_priv, DPLL_MD(pipe), crtc_state->dpll_hw_state.dpll_md); } else { /* The pixel multiplier can only be updated once the @@ -1425,13 +1425,13 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state) * * So write it again. */ - intel_de_write(dev_priv, reg, dpll); + intel_de_write(dev_priv, DPLL(pipe), dpll); } /* We do this three times for luck */ for (i = 0; i < 3; i++) { - intel_de_write(dev_priv, reg, dpll); - intel_de_posting_read(dev_priv, reg); + intel_de_write(dev_priv, DPLL(pipe), dpll); + intel_de_posting_read(dev_priv, DPLL(pipe)); udelay(150); /* wait for warmup */ } } -- cgit v1.2.3 From 98b27e79898b5f5a15734525c7a31f67f7a9766a Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:25 +0300 Subject: drm/i915: Program DPLL P1 dividers consistently MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On g4x and pch the DPLL has two P1 dividers (for refresh rate switching). Program the FPx1 P1 divider consistently to the reduced clock P1 divider if available, otherwise just program it to the same value as the FPx0 P1 divider. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-9-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dpll.c | 80 ++++++++++++++++--------------- 1 file changed, 41 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 37e02168b81c..09a57ce86676 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -779,42 +779,34 @@ static u32 pnv_dpll_compute_fp(const struct dpll *dpll) } static void i9xx_update_pll_dividers(struct intel_crtc_state *crtc_state, + const struct dpll *clock, const struct dpll *reduced_clock) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - const struct dpll *clock = &crtc_state->dpll; - u32 fp, fp2 = 0; + u32 fp, fp2; if (IS_PINEVIEW(dev_priv)) { fp = pnv_dpll_compute_fp(clock); - if (reduced_clock) - fp2 = pnv_dpll_compute_fp(reduced_clock); + fp2 = pnv_dpll_compute_fp(reduced_clock); } else { fp = i9xx_dpll_compute_fp(clock); - if (reduced_clock) - fp2 = i9xx_dpll_compute_fp(reduced_clock); + fp2 = i9xx_dpll_compute_fp(reduced_clock); } crtc_state->dpll_hw_state.fp0 = fp; - - if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && - reduced_clock) { - crtc_state->dpll_hw_state.fp1 = fp2; - } else { - crtc_state->dpll_hw_state.fp1 = fp; - } + crtc_state->dpll_hw_state.fp1 = fp2; } static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state, + const struct dpll *clock, const struct dpll *reduced_clock) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - const struct dpll *clock = &crtc_state->dpll; u32 dpll; - i9xx_update_pll_dividers(crtc_state, reduced_clock); + i9xx_update_pll_dividers(crtc_state, clock, reduced_clock); dpll = DPLL_VGA_MODE_DIS; @@ -837,13 +829,17 @@ static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state, dpll |= DPLL_SDVO_HIGH_SPEED; /* compute bitmask from p1 value */ - if (IS_PINEVIEW(dev_priv)) + if (IS_G4X(dev_priv)) { + dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; + dpll |= (1 << (reduced_clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; + } else if (IS_PINEVIEW(dev_priv)) { dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW; - else { + WARN_ON(reduced_clock->p1 != clock->p1); + } else { dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; - if (IS_G4X(dev_priv) && reduced_clock) - dpll |= (1 << (reduced_clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; + WARN_ON(reduced_clock->p1 != clock->p1); } + switch (clock->p2) { case 5: dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; @@ -858,6 +854,8 @@ static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state, dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; break; } + WARN_ON(reduced_clock->p2 != clock->p2); + if (DISPLAY_VER(dev_priv) >= 4) dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); @@ -880,14 +878,14 @@ static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state, } static void i8xx_compute_dpll(struct intel_crtc_state *crtc_state, + const struct dpll *clock, const struct dpll *reduced_clock) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - const struct dpll *clock = &crtc_state->dpll; u32 dpll; - i9xx_update_pll_dividers(crtc_state, reduced_clock); + i9xx_update_pll_dividers(crtc_state, clock, reduced_clock); dpll = DPLL_VGA_MODE_DIS; @@ -901,6 +899,8 @@ static void i8xx_compute_dpll(struct intel_crtc_state *crtc_state, if (clock->p2 == 4) dpll |= PLL_P2_DIVIDE_BY_4; } + WARN_ON(reduced_clock->p1 != clock->p1); + WARN_ON(reduced_clock->p2 != clock->p2); /* * Bspec: @@ -958,12 +958,12 @@ static bool ilk_needs_fb_cb_tune(const struct dpll *dpll, int factor) } static void ilk_update_pll_dividers(struct intel_crtc_state *crtc_state, + const struct dpll *clock, const struct dpll *reduced_clock) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - const struct dpll *clock = &crtc_state->dpll; - u32 fp, fp2 = 0; + u32 fp, fp2; int factor; /* Enable autotuning of the PLL clock (if permissible) */ @@ -979,30 +979,26 @@ static void ilk_update_pll_dividers(struct intel_crtc_state *crtc_state, } fp = i9xx_dpll_compute_fp(clock); - if (ilk_needs_fb_cb_tune(clock, factor)) fp |= FP_CB_TUNE; - if (reduced_clock) { - fp2 = i9xx_dpll_compute_fp(reduced_clock); - - if (reduced_clock->m < factor * reduced_clock->n) - fp2 |= FP_CB_TUNE; - } + fp2 = i9xx_dpll_compute_fp(reduced_clock); + if (reduced_clock->m < factor * reduced_clock->n) + fp2 |= FP_CB_TUNE; crtc_state->dpll_hw_state.fp0 = fp; - crtc_state->dpll_hw_state.fp1 = reduced_clock ? fp2 : fp; + crtc_state->dpll_hw_state.fp1 = fp2; } static void ilk_compute_dpll(struct intel_crtc_state *crtc_state, + const struct dpll *clock, const struct dpll *reduced_clock) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - const struct dpll *clock = &crtc_state->dpll; u32 dpll; - ilk_update_pll_dividers(crtc_state, reduced_clock); + ilk_update_pll_dividers(crtc_state, clock, reduced_clock); dpll = 0; @@ -1042,7 +1038,7 @@ static void ilk_compute_dpll(struct intel_crtc_state *crtc_state, /* compute bitmask from p1 value */ dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; /* also FPA1 */ - dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; + dpll |= (1 << (reduced_clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; switch (clock->p2) { case 5: @@ -1058,6 +1054,7 @@ static void ilk_compute_dpll(struct intel_crtc_state *crtc_state, dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; break; } + WARN_ON(reduced_clock->p2 != clock->p2); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && intel_panel_use_ssc(dev_priv)) @@ -1117,7 +1114,8 @@ static int ilk_crtc_compute_clock(struct intel_crtc_state *crtc_state) return -EINVAL; } - ilk_compute_dpll(crtc_state, NULL); + ilk_compute_dpll(crtc_state, &crtc_state->dpll, + &crtc_state->dpll); if (!intel_reserve_shared_dplls(state, crtc, NULL)) { drm_dbg_kms(&dev_priv->drm, @@ -1246,7 +1244,8 @@ static int g4x_crtc_compute_clock(struct intel_crtc_state *crtc_state) return -EINVAL; } - i9xx_compute_dpll(crtc_state, NULL); + i9xx_compute_dpll(crtc_state, &crtc_state->dpll, + &crtc_state->dpll); return 0; } @@ -1282,7 +1281,8 @@ static int pnv_crtc_compute_clock(struct intel_crtc_state *crtc_state) return -EINVAL; } - i9xx_compute_dpll(crtc_state, NULL); + i9xx_compute_dpll(crtc_state, &crtc_state->dpll, + &crtc_state->dpll); return 0; } @@ -1318,7 +1318,8 @@ static int i9xx_crtc_compute_clock(struct intel_crtc_state *crtc_state) return -EINVAL; } - i9xx_compute_dpll(crtc_state, NULL); + i9xx_compute_dpll(crtc_state, &crtc_state->dpll, + &crtc_state->dpll); return 0; } @@ -1356,7 +1357,8 @@ static int i8xx_crtc_compute_clock(struct intel_crtc_state *crtc_state) return -EINVAL; } - i8xx_compute_dpll(crtc_state, NULL); + i8xx_compute_dpll(crtc_state, &crtc_state->dpll, + &crtc_state->dpll); return 0; } -- cgit v1.2.3 From a338847abc8e2872c8ec9215567d10c3ca3afcc0 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:26 +0300 Subject: drm/i915: Call {vlv,chv}_prepare_pll() from {vlv,chv}_enable_pll() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We always call the vlv/chv prepare_pll() just before enable_pll(). Move the calls into the enable_pll() funcs. We can also consolidate the DPLL_VCO_ENABLE checks while at it. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-10-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 7 +- drivers/gpu/drm/i915/display/intel_dpll.c | 245 +++++++++++++-------------- drivers/gpu/drm/i915/display/intel_dpll.h | 9 +- 3 files changed, 125 insertions(+), 136 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e288afa9667d..2d137cffa858 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3576,13 +3576,10 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, intel_encoders_pre_pll_enable(state, crtc); - if (IS_CHERRYVIEW(dev_priv)) { - chv_prepare_pll(new_crtc_state); + if (IS_CHERRYVIEW(dev_priv)) chv_enable_pll(new_crtc_state); - } else { - vlv_prepare_pll(new_crtc_state); + else vlv_enable_pll(new_crtc_state); - } intel_encoders_pre_enable(state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 09a57ce86676..13d99f3e4d75 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -1467,112 +1467,7 @@ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, vlv_dpio_write(dev_priv, pipe, VLV_REF_DW13, reg_val); } -static void _vlv_enable_pll(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); - enum pipe pipe = crtc->pipe; - - intel_de_write(dev_priv, DPLL(pipe), crtc_state->dpll_hw_state.dpll); - intel_de_posting_read(dev_priv, DPLL(pipe)); - udelay(150); - - if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1)) - drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe); -} - -void vlv_enable_pll(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); - enum pipe pipe = crtc->pipe; - - assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder); - - /* PLL is protected by panel, make sure we can write it */ - assert_panel_unlocked(dev_priv, pipe); - - if (crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) - _vlv_enable_pll(crtc_state); - - intel_de_write(dev_priv, DPLL_MD(pipe), - crtc_state->dpll_hw_state.dpll_md); - intel_de_posting_read(dev_priv, DPLL_MD(pipe)); -} - - -static void _chv_enable_pll(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); - enum pipe pipe = crtc->pipe; - enum dpio_channel port = vlv_pipe_to_channel(pipe); - u32 tmp; - - vlv_dpio_get(dev_priv); - - /* Enable back the 10bit clock to display controller */ - tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)); - tmp |= DPIO_DCLKP_EN; - vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp); - - vlv_dpio_put(dev_priv); - - /* - * Need to wait > 100ns between dclkp clock enable bit and PLL enable. - */ - udelay(1); - - /* Enable PLL */ - intel_de_write(dev_priv, DPLL(pipe), crtc_state->dpll_hw_state.dpll); - - /* Check PLL is locked */ - if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1)) - drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe); -} - -void chv_enable_pll(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); - enum pipe pipe = crtc->pipe; - - assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder); - - /* PLL is protected by panel, make sure we can write it */ - assert_panel_unlocked(dev_priv, pipe); - - if (crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) - _chv_enable_pll(crtc_state); - - if (pipe != PIPE_A) { - /* - * WaPixelRepeatModeFixForC0:chv - * - * DPLLCMD is AWOL. Use chicken bits to propagate - * the value from DPLLBMD to either pipe B or C. - */ - intel_de_write(dev_priv, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe)); - intel_de_write(dev_priv, DPLL_MD(PIPE_B), - crtc_state->dpll_hw_state.dpll_md); - intel_de_write(dev_priv, CBR4_VLV, 0); - dev_priv->chv_dpll_md[pipe] = crtc_state->dpll_hw_state.dpll_md; - - /* - * DPLLB VGA mode also seems to cause problems. - * We should always have it disabled. - */ - drm_WARN_ON(&dev_priv->drm, - (intel_de_read(dev_priv, DPLL(PIPE_B)) & - DPLL_VGA_MODE_DIS) == 0); - } else { - intel_de_write(dev_priv, DPLL_MD(pipe), - crtc_state->dpll_hw_state.dpll_md); - intel_de_posting_read(dev_priv, DPLL_MD(pipe)); - } -} - -void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) +static void vlv_prepare_pll(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); @@ -1581,15 +1476,6 @@ void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) u32 bestn, bestm1, bestm2, bestp1, bestp2; u32 coreclk, reg_val; - /* Enable Refclk */ - intel_de_write(dev_priv, DPLL(pipe), - crtc_state->dpll_hw_state.dpll & - ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV)); - - /* No need to actually set up the DPLL with DSI */ - if ((crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0) - return; - vlv_dpio_get(dev_priv); bestn = crtc_state->dpll.n; @@ -1671,7 +1557,47 @@ void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) vlv_dpio_put(dev_priv); } -void chv_prepare_pll(const struct intel_crtc_state *crtc_state) +static void _vlv_enable_pll(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); + enum pipe pipe = crtc->pipe; + + intel_de_write(dev_priv, DPLL(pipe), crtc_state->dpll_hw_state.dpll); + intel_de_posting_read(dev_priv, DPLL(pipe)); + udelay(150); + + if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1)) + drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe); +} + +void vlv_enable_pll(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); + enum pipe pipe = crtc->pipe; + + assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder); + + /* PLL is protected by panel, make sure we can write it */ + assert_panel_unlocked(dev_priv, pipe); + + /* Enable Refclk */ + intel_de_write(dev_priv, DPLL(pipe), + crtc_state->dpll_hw_state.dpll & + ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV)); + + if (crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) { + vlv_prepare_pll(crtc_state); + _vlv_enable_pll(crtc_state); + } + + intel_de_write(dev_priv, DPLL_MD(pipe), + crtc_state->dpll_hw_state.dpll_md); + intel_de_posting_read(dev_priv, DPLL_MD(pipe)); +} + +static void chv_prepare_pll(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); @@ -1682,14 +1608,6 @@ void chv_prepare_pll(const struct intel_crtc_state *crtc_state) u32 dpio_val; int vco; - /* Enable Refclk and SSC */ - intel_de_write(dev_priv, DPLL(pipe), - crtc_state->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE); - - /* No need to actually set up the DPLL with DSI */ - if ((crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0) - return; - bestn = crtc_state->dpll.n; bestm2_frac = crtc_state->dpll.m2 & 0x3fffff; bestm1 = crtc_state->dpll.m1; @@ -1775,6 +1693,83 @@ void chv_prepare_pll(const struct intel_crtc_state *crtc_state) vlv_dpio_put(dev_priv); } +static void _chv_enable_pll(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); + enum pipe pipe = crtc->pipe; + enum dpio_channel port = vlv_pipe_to_channel(pipe); + u32 tmp; + + vlv_dpio_get(dev_priv); + + /* Enable back the 10bit clock to display controller */ + tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)); + tmp |= DPIO_DCLKP_EN; + vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp); + + vlv_dpio_put(dev_priv); + + /* + * Need to wait > 100ns between dclkp clock enable bit and PLL enable. + */ + udelay(1); + + /* Enable PLL */ + intel_de_write(dev_priv, DPLL(pipe), crtc_state->dpll_hw_state.dpll); + + /* Check PLL is locked */ + if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1)) + drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe); +} + +void chv_enable_pll(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); + enum pipe pipe = crtc->pipe; + + assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder); + + /* PLL is protected by panel, make sure we can write it */ + assert_panel_unlocked(dev_priv, pipe); + + /* Enable Refclk and SSC */ + intel_de_write(dev_priv, DPLL(pipe), + crtc_state->dpll_hw_state.dpll & ~DPLL_VCO_ENABLE); + + if (crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) { + chv_prepare_pll(crtc_state); + _chv_enable_pll(crtc_state); + } + + if (pipe != PIPE_A) { + /* + * WaPixelRepeatModeFixForC0:chv + * + * DPLLCMD is AWOL. Use chicken bits to propagate + * the value from DPLLBMD to either pipe B or C. + */ + intel_de_write(dev_priv, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe)); + intel_de_write(dev_priv, DPLL_MD(PIPE_B), + crtc_state->dpll_hw_state.dpll_md); + intel_de_write(dev_priv, CBR4_VLV, 0); + dev_priv->chv_dpll_md[pipe] = crtc_state->dpll_hw_state.dpll_md; + + /* + * DPLLB VGA mode also seems to cause problems. + * We should always have it disabled. + */ + drm_WARN_ON(&dev_priv->drm, + (intel_de_read(dev_priv, DPLL(PIPE_B)) & + DPLL_VGA_MODE_DIS) == 0); + } else { + intel_de_write(dev_priv, DPLL_MD(pipe), + crtc_state->dpll_hw_state.dpll_md); + intel_de_posting_read(dev_priv, DPLL_MD(pipe)); + } +} + /** * vlv_force_pll_on - forcibly enable just the PLL * @dev_priv: i915 private structure @@ -1802,11 +1797,9 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, if (IS_CHERRYVIEW(dev_priv)) { chv_compute_dpll(crtc_state); - chv_prepare_pll(crtc_state); chv_enable_pll(crtc_state); } else { vlv_compute_dpll(crtc_state); - vlv_prepare_pll(crtc_state); vlv_enable_pll(crtc_state); } diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h b/drivers/gpu/drm/i915/display/intel_dpll.h index 29f31075cdf0..db396b3e1141 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.h +++ b/drivers/gpu/drm/i915/display/intel_dpll.h @@ -25,14 +25,13 @@ void chv_compute_dpll(struct intel_crtc_state *crtc_state); int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, const struct dpll *dpll); void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe); -void i9xx_enable_pll(const struct intel_crtc_state *crtc_state); -void vlv_enable_pll(const struct intel_crtc_state *crtc_state); + void chv_enable_pll(const struct intel_crtc_state *crtc_state); -void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe); void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe); +void vlv_enable_pll(const struct intel_crtc_state *crtc_state); +void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe); +void i9xx_enable_pll(const struct intel_crtc_state *crtc_state); void i9xx_disable_pll(const struct intel_crtc_state *crtc_state); -void vlv_prepare_pll(const struct intel_crtc_state *crtc_state); -void chv_prepare_pll(const struct intel_crtc_state *crtc_state); bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, struct dpll *best_clock); int chv_calc_dpll_params(int refclk, struct dpll *pll_clock); -- cgit v1.2.3 From 7b43cd70b56d5d708cfaea272ed62f88a482214f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:27 +0300 Subject: drm/i915: Reuse ilk_needs_fb_cb_tune() for the reduced clock as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use ilk_needs_fb_cb_tune() for reduced_clock instead of hand rolling it. Also ilk_needs_fb_cb_tune() can just use the precomputed M value instead of calculating it again. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-11-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dpll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 13d99f3e4d75..381f6eabeb01 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -954,7 +954,7 @@ static int hsw_crtc_compute_clock(struct intel_crtc_state *crtc_state) static bool ilk_needs_fb_cb_tune(const struct dpll *dpll, int factor) { - return i9xx_dpll_compute_m(dpll) < factor * dpll->n; + return dpll->m < factor * dpll->n; } static void ilk_update_pll_dividers(struct intel_crtc_state *crtc_state, @@ -983,7 +983,7 @@ static void ilk_update_pll_dividers(struct intel_crtc_state *crtc_state, fp |= FP_CB_TUNE; fp2 = i9xx_dpll_compute_fp(reduced_clock); - if (reduced_clock->m < factor * reduced_clock->n) + if (ilk_needs_fb_cb_tune(reduced_clock, factor)) fp2 |= FP_CB_TUNE; crtc_state->dpll_hw_state.fp0 = fp; -- cgit v1.2.3 From 62d66b2183861ccdb5b8d9166d9a133489523a31 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:28 +0300 Subject: drm/i915: Fold i9xx_set_pll_dividers() into i9xx_enable_pll() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Can't think of a good reason why we'd need to program the FP dividers so early. Let's just do it when programming the rest of the DPLL. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-12-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 13 ------------- drivers/gpu/drm/i915/display/intel_dpll.c | 3 +++ 2 files changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 2d137cffa858..9babdf1b09c4 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3598,17 +3598,6 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, intel_encoders_enable(state, crtc); } -static void i9xx_set_pll_dividers(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); - - intel_de_write(dev_priv, FP0(crtc->pipe), - crtc_state->dpll_hw_state.fp0); - intel_de_write(dev_priv, FP1(crtc->pipe), - crtc_state->dpll_hw_state.fp1); -} - static void i9xx_crtc_enable(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -3620,8 +3609,6 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, if (drm_WARN_ON(&dev_priv->drm, crtc->active)) return; - i9xx_set_pll_dividers(new_crtc_state); - if (intel_crtc_has_dp_encoder(new_crtc_state)) intel_dp_set_m_n(new_crtc_state, M1_N1); diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 381f6eabeb01..210f91f4a576 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -1406,6 +1406,9 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state) if (i9xx_has_pps(dev_priv)) assert_panel_unlocked(dev_priv, pipe); + intel_de_write(dev_priv, FP0(pipe), crtc_state->dpll_hw_state.fp0); + intel_de_write(dev_priv, FP1(pipe), crtc_state->dpll_hw_state.fp1); + /* * Apparently we need to have VGA mode enabled prior to changing * the P1/P2 dividers. Otherwise the DPLL will keep using the old -- cgit v1.2.3 From 0bae0872f80a04252b7f35a316613a53b439e6fc Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:29 +0300 Subject: drm/i915: Fold ibx_pch_dpll_prepare() into ibx_pch_dpll_enable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the FP divider programming into ibx_pch_dpll_enable(). No reason that I can see why these would have to be programmed this early. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-13-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 5c91d125a337..075a657624ae 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -451,15 +451,6 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv, return val & DPLL_VCO_ENABLE; } -static void ibx_pch_dpll_prepare(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll) -{ - const enum intel_dpll_id id = pll->info->id; - - intel_de_write(dev_priv, PCH_FP0(id), pll->state.hw_state.fp0); - intel_de_write(dev_priv, PCH_FP1(id), pll->state.hw_state.fp1); -} - static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) { u32 val; @@ -481,6 +472,9 @@ static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv, /* PCH refclock must be enabled first */ ibx_assert_pch_refclk_enabled(dev_priv); + intel_de_write(dev_priv, PCH_FP0(id), pll->state.hw_state.fp0); + intel_de_write(dev_priv, PCH_FP1(id), pll->state.hw_state.fp1); + intel_de_write(dev_priv, PCH_DPLL(id), pll->state.hw_state.dpll); /* Wait for the clocks to stabilize. */ @@ -558,7 +552,6 @@ static void ibx_dump_hw_state(struct drm_i915_private *dev_priv, } static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = { - .prepare = ibx_pch_dpll_prepare, .enable = ibx_pch_dpll_enable, .disable = ibx_pch_dpll_disable, .get_hw_state = ibx_pch_dpll_get_hw_state, -- cgit v1.2.3 From 76a04cd9af1e0cd9043b3904faa3ee3dc600799e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 15 Jul 2021 12:35:30 +0300 Subject: drm/i915: Nuke intel_prepare_shared_dpll() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_prepare_shared_dpll() is now useless, so get rid of it. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210715093530.31711-14-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 3 --- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 28 --------------------------- drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 11 ----------- 3 files changed, 42 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9babdf1b09c4..fe5ad599c218 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2921,9 +2921,6 @@ static void ilk_crtc_enable(struct intel_atomic_state *state, intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false); - if (new_crtc_state->has_pch_encoder) - intel_prepare_shared_dpll(new_crtc_state); - if (intel_crtc_has_dp_encoder(new_crtc_state)) intel_dp_set_m_n(new_crtc_state, M1_N1); diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 075a657624ae..055992d099c7 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -184,34 +184,6 @@ intel_tc_pll_enable_reg(struct drm_i915_private *i915, return MG_PLL_ENABLE(tc_port); } -/** - * intel_prepare_shared_dpll - call a dpll's prepare hook - * @crtc_state: CRTC, and its state, which has a shared dpll - * - * This calls the PLL's prepare hook if it has one and if the PLL is not - * already enabled. The prepare hook is platform specific. - */ -void intel_prepare_shared_dpll(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); - struct intel_shared_dpll *pll = crtc_state->shared_dpll; - - if (drm_WARN_ON(&dev_priv->drm, pll == NULL)) - return; - - mutex_lock(&dev_priv->dpll.lock); - drm_WARN_ON(&dev_priv->drm, !pll->state.pipe_mask); - if (!pll->active_mask) { - drm_dbg(&dev_priv->drm, "setting up %s\n", pll->info->name); - drm_WARN_ON(&dev_priv->drm, pll->on); - assert_shared_dpll_disabled(dev_priv, pll); - - pll->info->funcs->prepare(dev_priv, pll); - } - mutex_unlock(&dev_priv->dpll.lock); -} - /** * intel_enable_shared_dpll - enable a CRTC's shared DPLL * @crtc_state: CRTC, and its state, which has a shared DPLL diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h index 30e0aa5ca109..2f59d863be4c 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -255,16 +255,6 @@ struct intel_shared_dpll_state { * struct intel_shared_dpll_funcs - platform specific hooks for managing DPLLs */ struct intel_shared_dpll_funcs { - /** - * @prepare: - * - * Optional hook to perform operations prior to enabling the PLL. - * Called from intel_prepare_shared_dpll() function unless the PLL - * is already enabled. - */ - void (*prepare)(struct drm_i915_private *dev_priv, - struct intel_shared_dpll *pll); - /** * @enable: * @@ -404,7 +394,6 @@ int intel_dpll_get_freq(struct drm_i915_private *i915, bool intel_dpll_get_hw_state(struct drm_i915_private *i915, struct intel_shared_dpll *pll, struct intel_dpll_hw_state *hw_state); -void intel_prepare_shared_dpll(const struct intel_crtc_state *crtc_state); void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state); void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state); void intel_shared_dpll_swap_state(struct intel_atomic_state *state); -- cgit v1.2.3 From d3252e1a3b2bd93ad76ae381d8f1a4e4c0ea54cc Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Fri, 20 Aug 2021 15:57:10 -0700 Subject: drm/i915/dg2: Memory latency values from pcode must be doubled The memory latency values returned by pcode on DG2 are in units of "2 usec" rather than 1 usec on all other platforms. I.e., we need to double the value returned by pcode to obtain the true latency value. The bspec wording here was a bit ambiguous as to whether it wanted us to multiply or divide the pcode value by two, but we confirmed offline with the hardware team that we need to double the value the pcode gives us; this change is intended to support a larger range of potential latency values. Bspec: 49326 Signed-off-by: Matt Roper Reviewed-by: Harish Chegondi Link: https://patchwork.freedesktop.org/patch/msgid/20210820225710.401136-1-matthew.d.roper@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 65bc3709f54c..cfc41f8fa74a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2859,6 +2859,7 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv, u32 val; int ret, i; int level, max_level = ilk_wm_max_level(dev_priv); + int mult = IS_DG2(dev_priv) ? 2 : 1; /* read the first set of memory latencies[0:3] */ val = 0; /* data0 to be programmed to 0 for first set */ @@ -2872,13 +2873,13 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv, return; } - wm[0] = val & GEN9_MEM_LATENCY_LEVEL_MASK; - wm[1] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) & - GEN9_MEM_LATENCY_LEVEL_MASK; - wm[2] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) & - GEN9_MEM_LATENCY_LEVEL_MASK; - wm[3] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & - GEN9_MEM_LATENCY_LEVEL_MASK; + wm[0] = (val & GEN9_MEM_LATENCY_LEVEL_MASK) * mult; + wm[1] = ((val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) & + GEN9_MEM_LATENCY_LEVEL_MASK) * mult; + wm[2] = ((val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) & + GEN9_MEM_LATENCY_LEVEL_MASK) * mult; + wm[3] = ((val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & + GEN9_MEM_LATENCY_LEVEL_MASK) * mult; /* read the second set of memory latencies[4:7] */ val = 1; /* data0 to be programmed to 1 for second set */ @@ -2891,13 +2892,13 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv, return; } - wm[4] = val & GEN9_MEM_LATENCY_LEVEL_MASK; - wm[5] = (val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) & - GEN9_MEM_LATENCY_LEVEL_MASK; - wm[6] = (val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) & - GEN9_MEM_LATENCY_LEVEL_MASK; - wm[7] = (val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & - GEN9_MEM_LATENCY_LEVEL_MASK; + wm[4] = (val & GEN9_MEM_LATENCY_LEVEL_MASK) * mult; + wm[5] = ((val >> GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT) & + GEN9_MEM_LATENCY_LEVEL_MASK) * mult; + wm[6] = ((val >> GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT) & + GEN9_MEM_LATENCY_LEVEL_MASK) * mult; + wm[7] = ((val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & + GEN9_MEM_LATENCY_LEVEL_MASK) * mult; /* * If a level n (n > 1) has a 0us latency, all levels m (m >= n) -- cgit v1.2.3 From 6cc42fbeb150ff33b17cbf108713ca4be23994d8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Aug 2021 14:06:50 +0300 Subject: drm/i915/backlight: extract backlight code to a separate file In a long overdue refactoring, split out backlight code to new intel_backlight.[ch]. Simple code movement, leave renames for follow-up work. No functional changes. Cc: Lyude Paul Reviewed-by: Lyude Paul Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/97d310848f03061473b9b2328e2c5c4dcf263cfa.1629888677.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/display/g4x_dp.c | 2 +- drivers/gpu/drm/i915/display/icl_dsi.c | 1 + drivers/gpu/drm/i915/display/intel_backlight.c | 1778 ++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_backlight.h | 51 + drivers/gpu/drm/i915/display/intel_connector.c | 4 +- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 1 + .../gpu/drm/i915/display/intel_dp_aux_backlight.c | 2 +- drivers/gpu/drm/i915/display/intel_lvds.c | 1 + drivers/gpu/drm/i915/display/intel_opregion.c | 3 +- drivers/gpu/drm/i915/display/intel_panel.c | 1767 +------------------ drivers/gpu/drm/i915/display/intel_panel.h | 34 +- drivers/gpu/drm/i915/display/vlv_dsi.c | 1 + 14 files changed, 1843 insertions(+), 1805 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_backlight.c create mode 100644 drivers/gpu/drm/i915/display/intel_backlight.h (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index fd997dfa5e32..23612c3a1922 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -249,6 +249,7 @@ i915-y += \ display/g4x_dp.o \ display/g4x_hdmi.o \ display/icl_dsi.o \ + display/intel_backlight.o \ display/intel_crt.o \ display/intel_ddi.o \ display/intel_ddi_buf_trans.o \ diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index de0f358184aa..29c0eca647e3 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -7,6 +7,7 @@ #include "g4x_dp.h" #include "intel_audio.h" +#include "intel_backlight.h" #include "intel_connector.h" #include "intel_de.h" #include "intel_display_types.h" @@ -16,7 +17,6 @@ #include "intel_fifo_underrun.h" #include "intel_hdmi.h" #include "intel_hotplug.h" -#include "intel_panel.h" #include "intel_pps.h" #include "intel_sideband.h" diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 43ec7fcd3f5d..9aaa9f2ee601 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -29,6 +29,7 @@ #include #include "intel_atomic.h" +#include "intel_backlight.h" #include "intel_combo_phy.h" #include "intel_connector.h" #include "intel_crtc.h" diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c new file mode 100644 index 000000000000..4b0086ee4851 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -0,0 +1,1778 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2021 Intel Corporation + */ + +#include +#include + +#include "intel_backlight.h" +#include "intel_connector.h" +#include "intel_de.h" +#include "intel_display_types.h" +#include "intel_dp_aux_backlight.h" +#include "intel_dsi_dcs_backlight.h" +#include "intel_panel.h" + +/** + * scale - scale values from one range to another + * @source_val: value in range [@source_min..@source_max] + * @source_min: minimum legal value for @source_val + * @source_max: maximum legal value for @source_val + * @target_min: corresponding target value for @source_min + * @target_max: corresponding target value for @source_max + * + * Return @source_val in range [@source_min..@source_max] scaled to range + * [@target_min..@target_max]. + */ +static u32 scale(u32 source_val, + u32 source_min, u32 source_max, + u32 target_min, u32 target_max) +{ + u64 target_val; + + WARN_ON(source_min > source_max); + WARN_ON(target_min > target_max); + + /* defensive */ + source_val = clamp(source_val, source_min, source_max); + + /* avoid overflows */ + target_val = mul_u32_u32(source_val - source_min, + target_max - target_min); + target_val = DIV_ROUND_CLOSEST_ULL(target_val, source_max - source_min); + target_val += target_min; + + return target_val; +} + +/* + * Scale user_level in range [0..user_max] to [0..hw_max], clamping the result + * to [hw_min..hw_max]. + */ +static u32 clamp_user_to_hw(struct intel_connector *connector, + u32 user_level, u32 user_max) +{ + struct intel_panel *panel = &connector->panel; + u32 hw_level; + + hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max); + hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max); + + return hw_level; +} + +/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */ +static u32 scale_hw_to_user(struct intel_connector *connector, + u32 hw_level, u32 user_max) +{ + struct intel_panel *panel = &connector->panel; + + return scale(hw_level, panel->backlight.min, panel->backlight.max, + 0, user_max); +} + +u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 val) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + + drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0); + + if (dev_priv->params.invert_brightness < 0) + return val; + + if (dev_priv->params.invert_brightness > 0 || + dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { + return panel->backlight.pwm_level_max - val + panel->backlight.pwm_level_min; + } + + return val; +} + +void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 val) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + + drm_dbg_kms(&i915->drm, "set backlight PWM = %d\n", val); + panel->backlight.pwm_funcs->set(conn_state, val); +} + +u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 val) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + + drm_WARN_ON_ONCE(&dev_priv->drm, + panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0); + + val = scale(val, panel->backlight.min, panel->backlight.max, + panel->backlight.pwm_level_min, panel->backlight.pwm_level_max); + + return intel_panel_invert_pwm_level(connector, val); +} + +u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + + drm_WARN_ON_ONCE(&dev_priv->drm, + 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)) + 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, + panel->backlight.min, panel->backlight.max); +} + +static u32 lpt_get_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + + return intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK; +} + +static u32 pch_get_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + + return intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; +} + +static u32 i9xx_get_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 val; + + val = intel_de_read(dev_priv, BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; + if (DISPLAY_VER(dev_priv) < 4) + val >>= 1; + + if (panel->backlight.combination_mode) { + u8 lbpc; + + pci_read_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, &lbpc); + val *= lbpc; + } + + return val; +} + +static u32 vlv_get_backlight(struct intel_connector *connector, enum pipe pipe) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + + if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B)) + return 0; + + return intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK; +} + +static u32 bxt_get_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + + return intel_de_read(dev_priv, + BXT_BLC_PWM_DUTY(panel->backlight.controller)); +} + +static u32 ext_pwm_get_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct intel_panel *panel = &connector->panel; + struct pwm_state state; + + pwm_get_state(panel->backlight.pwm, &state); + return pwm_get_relative_duty_cycle(&state, 100); +} + +static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + + u32 val = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK; + intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, val | level); +} + +static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + u32 tmp; + + tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; + intel_de_write(dev_priv, BLC_PWM_CPU_CTL, tmp | level); +} + +static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 tmp, mask; + + drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0); + + if (panel->backlight.combination_mode) { + u8 lbpc; + + lbpc = level * 0xfe / panel->backlight.pwm_level_max + 1; + level /= lbpc; + pci_write_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, lbpc); + } + + if (DISPLAY_VER(dev_priv) == 4) { + mask = BACKLIGHT_DUTY_CYCLE_MASK; + } else { + level <<= 1; + mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV; + } + + tmp = intel_de_read(dev_priv, BLC_PWM_CTL) & ~mask; + intel_de_write(dev_priv, BLC_PWM_CTL, tmp | level); +} + +static void vlv_set_backlight(const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe; + u32 tmp; + + tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK; + intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), tmp | level); +} + +static void bxt_set_backlight(const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + + intel_de_write(dev_priv, + BXT_BLC_PWM_DUTY(panel->backlight.controller), level); +} + +static void ext_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel; + + pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100); + pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); +} + +static void +intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + + drm_dbg_kms(&i915->drm, "set backlight level = %d\n", level); + + panel->backlight.funcs->set(conn_state, level); +} + +/* set backlight brightness to level in range [0..max], assuming hw min is + * respected. + */ +void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, + u32 user_level, u32 user_max) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 hw_level; + + /* + * Lack of crtc may occur during driver init because + * connection_mutex isn't held across the entire backlight + * setup + modeset readout, and the BIOS can issue the + * requests at any time. + */ + if (!panel->backlight.present || !conn_state->crtc) + return; + + mutex_lock(&dev_priv->backlight_lock); + + drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0); + + hw_level = clamp_user_to_hw(connector, user_level, user_max); + panel->backlight.level = hw_level; + + if (panel->backlight.device) + panel->backlight.device->props.brightness = + scale_hw_to_user(connector, + panel->backlight.level, + panel->backlight.device->props.max_brightness); + + if (panel->backlight.enabled) + intel_panel_actually_set_backlight(conn_state, hw_level); + + mutex_unlock(&dev_priv->backlight_lock); +} + +static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + u32 tmp; + + intel_panel_set_pwm_level(old_conn_state, level); + + /* + * Although we don't support or enable CPU PWM with LPT/SPT based + * systems, it may have been enabled prior to loading the + * driver. Disable to avoid warnings on LCPLL disable. + * + * This needs rework if we need to add support for CPU PWM on PCH split + * platforms. + */ + tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); + if (tmp & BLM_PWM_ENABLE) { + drm_dbg_kms(&dev_priv->drm, + "cpu backlight was enabled, disabling\n"); + intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, + tmp & ~BLM_PWM_ENABLE); + } + + tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); + intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); +} + +static void pch_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +{ + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + u32 tmp; + + intel_panel_set_pwm_level(old_conn_state, val); + + tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); + intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); + + tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); + intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); +} + +static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +{ + intel_panel_set_pwm_level(old_conn_state, val); +} + +static void i965_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +{ + struct drm_i915_private *dev_priv = to_i915(old_conn_state->connector->dev); + u32 tmp; + + intel_panel_set_pwm_level(old_conn_state, val); + + tmp = intel_de_read(dev_priv, BLC_PWM_CTL2); + intel_de_write(dev_priv, BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE); +} + +static void vlv_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +{ + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + enum pipe pipe = to_intel_crtc(old_conn_state->crtc)->pipe; + u32 tmp; + + intel_panel_set_pwm_level(old_conn_state, val); + + tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); + intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), + tmp & ~BLM_PWM_ENABLE); +} + +static void bxt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +{ + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 tmp; + + intel_panel_set_pwm_level(old_conn_state, val); + + tmp = intel_de_read(dev_priv, + BXT_BLC_PWM_CTL(panel->backlight.controller)); + intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), + tmp & ~BXT_BLC_PWM_ENABLE); + + if (panel->backlight.controller == 1) { + val = intel_de_read(dev_priv, UTIL_PIN_CTL); + val &= ~UTIL_PIN_ENABLE; + intel_de_write(dev_priv, UTIL_PIN_CTL, val); + } +} + +static void cnp_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) +{ + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 tmp; + + intel_panel_set_pwm_level(old_conn_state, val); + + tmp = intel_de_read(dev_priv, + BXT_BLC_PWM_CTL(panel->backlight.controller)); + intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), + tmp & ~BXT_BLC_PWM_ENABLE); +} + +static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); + struct intel_panel *panel = &connector->panel; + + panel->backlight.pwm_state.enabled = false; + pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); +} + +void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state) +{ + struct intel_connector *connector = to_intel_connector(old_conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + + if (!panel->backlight.present) + return; + + /* + * Do not disable backlight on the vga_switcheroo path. When switching + * away from i915, the other client may depend on i915 to handle the + * backlight. This will leave the backlight on unnecessarily when + * another client is not activated. + */ + if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) { + drm_dbg_kms(&dev_priv->drm, + "Skipping backlight disable on vga switch\n"); + return; + } + + mutex_lock(&dev_priv->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); +} + +static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 pch_ctl1, pch_ctl2, schicken; + + pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); + if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { + drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n"); + pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; + intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1); + } + + if (HAS_PCH_LPT(dev_priv)) { + schicken = intel_de_read(dev_priv, SOUTH_CHICKEN2); + if (panel->backlight.alternate_pwm_increment) + schicken |= LPT_PWM_GRANULARITY; + else + schicken &= ~LPT_PWM_GRANULARITY; + intel_de_write(dev_priv, SOUTH_CHICKEN2, schicken); + } else { + schicken = intel_de_read(dev_priv, SOUTH_CHICKEN1); + if (panel->backlight.alternate_pwm_increment) + schicken |= SPT_PWM_GRANULARITY; + else + schicken &= ~SPT_PWM_GRANULARITY; + intel_de_write(dev_priv, SOUTH_CHICKEN1, schicken); + } + + pch_ctl2 = panel->backlight.pwm_level_max << 16; + intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2); + + pch_ctl1 = 0; + if (panel->backlight.active_low_pwm) + pch_ctl1 |= BLM_PCH_POLARITY; + + /* After LPT, override is the default. */ + if (HAS_PCH_LPT(dev_priv)) + pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE; + + intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1); + intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1); + intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, + pch_ctl1 | BLM_PCH_PWM_ENABLE); + + /* This won't stick until the above enable. */ + intel_panel_set_pwm_level(conn_state, level); +} + +static void pch_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + u32 cpu_ctl2, pch_ctl1, pch_ctl2; + + cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); + if (cpu_ctl2 & BLM_PWM_ENABLE) { + drm_dbg_kms(&dev_priv->drm, "cpu backlight already enabled\n"); + cpu_ctl2 &= ~BLM_PWM_ENABLE; + intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2); + } + + pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); + if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { + drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n"); + pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; + intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1); + } + + if (cpu_transcoder == TRANSCODER_EDP) + cpu_ctl2 = BLM_TRANSCODER_EDP; + else + cpu_ctl2 = BLM_PIPE(cpu_transcoder); + intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2); + intel_de_posting_read(dev_priv, BLC_PWM_CPU_CTL2); + intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE); + + /* This won't stick until the above enable. */ + intel_panel_set_pwm_level(conn_state, level); + + pch_ctl2 = panel->backlight.pwm_level_max << 16; + intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2); + + pch_ctl1 = 0; + if (panel->backlight.active_low_pwm) + pch_ctl1 |= BLM_PCH_POLARITY; + + intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1); + intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1); + intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, + pch_ctl1 | BLM_PCH_PWM_ENABLE); +} + +static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 ctl, freq; + + ctl = intel_de_read(dev_priv, BLC_PWM_CTL); + if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) { + drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); + intel_de_write(dev_priv, BLC_PWM_CTL, 0); + } + + freq = panel->backlight.pwm_level_max; + if (panel->backlight.combination_mode) + freq /= 0xff; + + ctl = freq << 17; + if (panel->backlight.combination_mode) + ctl |= BLM_LEGACY_MODE; + if (IS_PINEVIEW(dev_priv) && panel->backlight.active_low_pwm) + ctl |= BLM_POLARITY_PNV; + + intel_de_write(dev_priv, BLC_PWM_CTL, ctl); + intel_de_posting_read(dev_priv, BLC_PWM_CTL); + + /* XXX: combine this into above write? */ + intel_panel_set_pwm_level(conn_state, level); + + /* + * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is + * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2 + * that has backlight. + */ + if (DISPLAY_VER(dev_priv) == 2) + intel_de_write(dev_priv, BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE); +} + +static void i965_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe; + u32 ctl, ctl2, freq; + + ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2); + if (ctl2 & BLM_PWM_ENABLE) { + drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); + ctl2 &= ~BLM_PWM_ENABLE; + intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2); + } + + freq = panel->backlight.pwm_level_max; + if (panel->backlight.combination_mode) + freq /= 0xff; + + ctl = freq << 16; + intel_de_write(dev_priv, BLC_PWM_CTL, ctl); + + ctl2 = BLM_PIPE(pipe); + if (panel->backlight.combination_mode) + ctl2 |= BLM_COMBINATION_MODE; + if (panel->backlight.active_low_pwm) + ctl2 |= BLM_POLARITY_I965; + intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2); + intel_de_posting_read(dev_priv, BLC_PWM_CTL2); + intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE); + + intel_panel_set_pwm_level(conn_state, level); +} + +static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; + u32 ctl, ctl2; + + ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); + if (ctl2 & BLM_PWM_ENABLE) { + drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); + ctl2 &= ~BLM_PWM_ENABLE; + intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2); + } + + ctl = panel->backlight.pwm_level_max << 16; + intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), ctl); + + /* XXX: combine this into above write? */ + intel_panel_set_pwm_level(conn_state, level); + + ctl2 = 0; + if (panel->backlight.active_low_pwm) + ctl2 |= BLM_POLARITY_I965; + intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2); + intel_de_posting_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); + intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), + ctl2 | BLM_PWM_ENABLE); +} + +static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; + u32 pwm_ctl, val; + + /* Controller 1 uses the utility pin. */ + if (panel->backlight.controller == 1) { + val = intel_de_read(dev_priv, UTIL_PIN_CTL); + if (val & UTIL_PIN_ENABLE) { + drm_dbg_kms(&dev_priv->drm, + "util pin already enabled\n"); + val &= ~UTIL_PIN_ENABLE; + intel_de_write(dev_priv, UTIL_PIN_CTL, val); + } + + val = 0; + if (panel->backlight.util_pin_active_low) + val |= UTIL_PIN_POLARITY; + intel_de_write(dev_priv, UTIL_PIN_CTL, + val | UTIL_PIN_PIPE(pipe) | UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE); + } + + pwm_ctl = intel_de_read(dev_priv, + BXT_BLC_PWM_CTL(panel->backlight.controller)); + if (pwm_ctl & BXT_BLC_PWM_ENABLE) { + drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); + pwm_ctl &= ~BXT_BLC_PWM_ENABLE; + intel_de_write(dev_priv, + BXT_BLC_PWM_CTL(panel->backlight.controller), + pwm_ctl); + } + + intel_de_write(dev_priv, + BXT_BLC_PWM_FREQ(panel->backlight.controller), + panel->backlight.pwm_level_max); + + intel_panel_set_pwm_level(conn_state, level); + + pwm_ctl = 0; + if (panel->backlight.active_low_pwm) + pwm_ctl |= BXT_BLC_PWM_POLARITY; + + intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), + pwm_ctl); + intel_de_posting_read(dev_priv, + BXT_BLC_PWM_CTL(panel->backlight.controller)); + intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), + pwm_ctl | BXT_BLC_PWM_ENABLE); +} + +static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 pwm_ctl; + + pwm_ctl = intel_de_read(dev_priv, + BXT_BLC_PWM_CTL(panel->backlight.controller)); + if (pwm_ctl & BXT_BLC_PWM_ENABLE) { + drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); + pwm_ctl &= ~BXT_BLC_PWM_ENABLE; + intel_de_write(dev_priv, + BXT_BLC_PWM_CTL(panel->backlight.controller), + pwm_ctl); + } + + intel_de_write(dev_priv, + BXT_BLC_PWM_FREQ(panel->backlight.controller), + panel->backlight.pwm_level_max); + + intel_panel_set_pwm_level(conn_state, level); + + pwm_ctl = 0; + if (panel->backlight.active_low_pwm) + pwm_ctl |= BXT_BLC_PWM_POLARITY; + + intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), + pwm_ctl); + intel_de_posting_read(dev_priv, + BXT_BLC_PWM_CTL(panel->backlight.controller)); + intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), + pwm_ctl | BXT_BLC_PWM_ENABLE); +} + +static void ext_pwm_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct intel_panel *panel = &connector->panel; + + pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100); + panel->backlight.pwm_state.enabled = true; + pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); +} + +static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct intel_panel *panel = &connector->panel; + + WARN_ON(panel->backlight.max == 0); + + if (panel->backlight.level <= panel->backlight.min) { + panel->backlight.level = panel->backlight.max; + if (panel->backlight.device) + panel->backlight.device->props.brightness = + scale_hw_to_user(connector, + panel->backlight.level, + panel->backlight.device->props.max_brightness); + } + + panel->backlight.funcs->enable(crtc_state, conn_state, panel->backlight.level); + panel->backlight.enabled = true; + if (panel->backlight.device) + panel->backlight.device->props.power = FB_BLANK_UNBLANK; +} + +void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; + + if (!panel->backlight.present) + return; + + drm_dbg_kms(&dev_priv->drm, "pipe %c\n", pipe_name(pipe)); + + mutex_lock(&dev_priv->backlight_lock); + + __intel_panel_enable_backlight(crtc_state, conn_state); + + mutex_unlock(&dev_priv->backlight_lock); +} + +#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) +static u32 intel_panel_get_backlight(struct intel_connector *connector) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 val = 0; + + mutex_lock(&dev_priv->backlight_lock); + + if (panel->backlight.enabled) + val = panel->backlight.funcs->get(connector, intel_connector_get_pipe(connector)); + + mutex_unlock(&dev_priv->backlight_lock); + + drm_dbg_kms(&dev_priv->drm, "get backlight PWM = %d\n", val); + return val; +} + +/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */ +static u32 scale_user_to_hw(struct intel_connector *connector, + u32 user_level, u32 user_max) +{ + struct intel_panel *panel = &connector->panel; + + return scale(user_level, 0, user_max, + panel->backlight.min, panel->backlight.max); +} + +/* set backlight brightness to level in range [0..max], scaling wrt hw min */ +static void intel_panel_set_backlight(const struct drm_connector_state *conn_state, + u32 user_level, u32 user_max) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 hw_level; + + if (!panel->backlight.present) + return; + + mutex_lock(&dev_priv->backlight_lock); + + drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0); + + hw_level = scale_user_to_hw(connector, user_level, user_max); + panel->backlight.level = hw_level; + + if (panel->backlight.enabled) + intel_panel_actually_set_backlight(conn_state, hw_level); + + mutex_unlock(&dev_priv->backlight_lock); +} + +static int intel_backlight_device_update_status(struct backlight_device *bd) +{ + struct intel_connector *connector = bl_get_data(bd); + struct intel_panel *panel = &connector->panel; + struct drm_device *dev = connector->base.dev; + + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n", + bd->props.brightness, bd->props.max_brightness); + intel_panel_set_backlight(connector->base.state, bd->props.brightness, + bd->props.max_brightness); + + /* + * Allow flipping bl_power as a sub-state of enabled. Sadly the + * backlight class device does not make it easy to differentiate + * between callbacks for brightness and bl_power, so our backlight_power + * callback needs to take this into account. + */ + if (panel->backlight.enabled) { + if (panel->backlight.power) { + bool enable = bd->props.power == FB_BLANK_UNBLANK && + bd->props.brightness != 0; + panel->backlight.power(connector, enable); + } + } else { + bd->props.power = FB_BLANK_POWERDOWN; + } + + drm_modeset_unlock(&dev->mode_config.connection_mutex); + return 0; +} + +static int intel_backlight_device_get_brightness(struct backlight_device *bd) +{ + struct intel_connector *connector = bl_get_data(bd); + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + intel_wakeref_t wakeref; + int ret = 0; + + with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) { + u32 hw_level; + + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + + hw_level = intel_panel_get_backlight(connector); + ret = scale_hw_to_user(connector, + hw_level, bd->props.max_brightness); + + drm_modeset_unlock(&dev->mode_config.connection_mutex); + } + + return ret; +} + +static const struct backlight_ops intel_backlight_device_ops = { + .update_status = intel_backlight_device_update_status, + .get_brightness = intel_backlight_device_get_brightness, +}; + +int intel_backlight_device_register(struct intel_connector *connector) +{ + struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + struct backlight_properties props; + struct backlight_device *bd; + const char *name; + int ret = 0; + + if (WARN_ON(panel->backlight.device)) + return -ENODEV; + + if (!panel->backlight.present) + return 0; + + WARN_ON(panel->backlight.max == 0); + + memset(&props, 0, sizeof(props)); + props.type = BACKLIGHT_RAW; + + /* + * Note: Everything should work even if the backlight device max + * presented to the userspace is arbitrarily chosen. + */ + props.max_brightness = panel->backlight.max; + props.brightness = scale_hw_to_user(connector, + panel->backlight.level, + props.max_brightness); + + if (panel->backlight.enabled) + props.power = FB_BLANK_UNBLANK; + else + props.power = FB_BLANK_POWERDOWN; + + name = kstrdup("intel_backlight", GFP_KERNEL); + if (!name) + return -ENOMEM; + + bd = backlight_device_register(name, connector->base.kdev, connector, + &intel_backlight_device_ops, &props); + + /* + * Using the same name independent of the drm device or connector + * prevents registration of multiple backlight devices in the + * driver. However, we need to use the default name for backward + * compatibility. Use unique names for subsequent backlight devices as a + * fallback when the default name already exists. + */ + if (IS_ERR(bd) && PTR_ERR(bd) == -EEXIST) { + kfree(name); + name = kasprintf(GFP_KERNEL, "card%d-%s-backlight", + i915->drm.primary->index, connector->base.name); + if (!name) + return -ENOMEM; + + bd = backlight_device_register(name, connector->base.kdev, connector, + &intel_backlight_device_ops, &props); + } + + if (IS_ERR(bd)) { + drm_err(&i915->drm, + "[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n", + connector->base.base.id, connector->base.name, name, PTR_ERR(bd)); + ret = PTR_ERR(bd); + goto out; + } + + panel->backlight.device = bd; + + drm_dbg_kms(&i915->drm, + "[CONNECTOR:%d:%s] backlight device %s registered\n", + connector->base.base.id, connector->base.name, name); + +out: + kfree(name); + + return ret; +} + +void intel_backlight_device_unregister(struct intel_connector *connector) +{ + struct intel_panel *panel = &connector->panel; + + if (panel->backlight.device) { + backlight_device_unregister(panel->backlight.device); + panel->backlight.device = NULL; + } +} +#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ + +/* + * CNP: PWM clock frequency is 19.2 MHz or 24 MHz. + * PWM increment = 1 + */ +static u32 cnp_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + + return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq), + pwm_freq_hz); +} + +/* + * BXT: PWM clock frequency = 19.2 MHz. + */ +static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +{ + return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz); +} + +/* + * SPT: This value represents the period of the PWM stream in clock periods + * multiplied by 16 (default increment) or 128 (alternate increment selected in + * SCHICKEN_1 bit 0). PWM clock is 24 MHz. + */ +static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +{ + struct intel_panel *panel = &connector->panel; + u32 mul; + + if (panel->backlight.alternate_pwm_increment) + mul = 128; + else + mul = 16; + + return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul); +} + +/* + * LPT: This value represents the period of the PWM stream in clock periods + * multiplied by 128 (default increment) or 16 (alternate increment, selected in + * LPT SOUTH_CHICKEN2 register bit 5). + */ +static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 mul, clock; + + if (panel->backlight.alternate_pwm_increment) + mul = 16; + else + mul = 128; + + if (HAS_PCH_LPT_H(dev_priv)) + clock = MHz(135); /* LPT:H */ + else + clock = MHz(24); /* LPT:LP */ + + return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul); +} + +/* + * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH + * display raw clocks multiplied by 128. + */ +static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + + return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq), + pwm_freq_hz * 128); +} + +/* + * Gen2: This field determines the number of time base events (display core + * clock frequency/32) in total for a complete cycle of modulated backlight + * control. + * + * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock) + * divided by 32. + */ +static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + int clock; + + if (IS_PINEVIEW(dev_priv)) + clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq); + else + clock = KHz(dev_priv->cdclk.hw.cdclk); + + return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32); +} + +/* + * Gen4: This value represents the period of the PWM stream in display core + * clocks ([DevCTG] HRAW clocks) multiplied by 128. + * + */ +static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + int clock; + + if (IS_G4X(dev_priv)) + clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq); + else + clock = KHz(dev_priv->cdclk.hw.cdclk); + + return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128); +} + +/* + * VLV: This value represents the period of the PWM stream in display core + * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks + * multiplied by 16. CHV uses a 19.2MHz S0IX clock. + */ +static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + int mul, clock; + + if ((intel_de_read(dev_priv, CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) { + if (IS_CHERRYVIEW(dev_priv)) + clock = KHz(19200); + else + clock = MHz(25); + mul = 16; + } else { + clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq); + mul = 128; + } + + return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul); +} + +static u16 get_vbt_pwm_freq(struct drm_i915_private *dev_priv) +{ + u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz; + + if (pwm_freq_hz) { + drm_dbg_kms(&dev_priv->drm, + "VBT defined backlight frequency %u Hz\n", + pwm_freq_hz); + } else { + pwm_freq_hz = 200; + drm_dbg_kms(&dev_priv->drm, + "default backlight frequency %u Hz\n", + pwm_freq_hz); + } + + return pwm_freq_hz; +} + +static u32 get_backlight_max_vbt(struct intel_connector *connector) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv); + u32 pwm; + + if (!panel->backlight.pwm_funcs->hz_to_pwm) { + drm_dbg_kms(&dev_priv->drm, + "backlight frequency conversion not supported\n"); + return 0; + } + + pwm = panel->backlight.pwm_funcs->hz_to_pwm(connector, pwm_freq_hz); + if (!pwm) { + drm_dbg_kms(&dev_priv->drm, + "backlight frequency conversion failed\n"); + return 0; + } + + return pwm; +} + +/* + * Note: The setup hooks can't assume pipe is set! + */ +static u32 get_backlight_min_vbt(struct intel_connector *connector) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + int min; + + drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0); + + /* + * XXX: If the vbt value is 255, it makes min equal to max, which leads + * to problems. There are such machines out there. Either our + * interpretation is wrong or the vbt has bogus data. Or both. Safeguard + * against this by letting the minimum be at most (arbitrarily chosen) + * 25% of the max. + */ + min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64); + if (min != dev_priv->vbt.backlight.min_brightness) { + drm_dbg_kms(&dev_priv->drm, + "clamping VBT min backlight %d/255 to %d/255\n", + dev_priv->vbt.backlight.min_brightness, min); + } + + /* vbt value is a coefficient in range [0..255] */ + return scale(min, 0, 255, 0, panel->backlight.pwm_level_max); +} + +static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 cpu_ctl2, pch_ctl1, pch_ctl2, val; + bool alt, cpu_mode; + + if (HAS_PCH_LPT(dev_priv)) + alt = intel_de_read(dev_priv, SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY; + else + alt = intel_de_read(dev_priv, SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY; + panel->backlight.alternate_pwm_increment = alt; + + pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); + panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; + + pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2); + panel->backlight.pwm_level_max = pch_ctl2 >> 16; + + cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); + + if (!panel->backlight.pwm_level_max) + panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); + + if (!panel->backlight.pwm_level_max) + return -ENODEV; + + panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); + + panel->backlight.pwm_enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE; + + cpu_mode = panel->backlight.pwm_enabled && HAS_PCH_LPT(dev_priv) && + !(pch_ctl1 & BLM_PCH_OVERRIDE_ENABLE) && + (cpu_ctl2 & BLM_PWM_ENABLE); + + if (cpu_mode) { + val = pch_get_backlight(connector, unused); + + drm_dbg_kms(&dev_priv->drm, + "CPU backlight register was enabled, switching to PCH override\n"); + + /* Write converted CPU PWM value to PCH override register */ + lpt_set_backlight(connector->base.state, val); + intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, + pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE); + + intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, + cpu_ctl2 & ~BLM_PWM_ENABLE); + } + + return 0; +} + +static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 cpu_ctl2, pch_ctl1, pch_ctl2; + + pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); + panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; + + pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2); + panel->backlight.pwm_level_max = pch_ctl2 >> 16; + + if (!panel->backlight.pwm_level_max) + panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); + + if (!panel->backlight.pwm_level_max) + return -ENODEV; + + panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); + + cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); + panel->backlight.pwm_enabled = (cpu_ctl2 & BLM_PWM_ENABLE) && + (pch_ctl1 & BLM_PCH_PWM_ENABLE); + + return 0; +} + +static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 ctl, val; + + ctl = intel_de_read(dev_priv, BLC_PWM_CTL); + + if (DISPLAY_VER(dev_priv) == 2 || IS_I915GM(dev_priv) || IS_I945GM(dev_priv)) + panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE; + + if (IS_PINEVIEW(dev_priv)) + panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV; + + panel->backlight.pwm_level_max = ctl >> 17; + + if (!panel->backlight.pwm_level_max) { + panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); + panel->backlight.pwm_level_max >>= 1; + } + + if (!panel->backlight.pwm_level_max) + return -ENODEV; + + if (panel->backlight.combination_mode) + panel->backlight.pwm_level_max *= 0xff; + + panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); + + val = i9xx_get_backlight(connector, unused); + val = intel_panel_invert_pwm_level(connector, val); + val = clamp(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max); + + panel->backlight.pwm_enabled = val != 0; + + return 0; +} + +static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 ctl, ctl2; + + ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2); + panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE; + panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; + + ctl = intel_de_read(dev_priv, BLC_PWM_CTL); + panel->backlight.pwm_level_max = ctl >> 16; + + if (!panel->backlight.pwm_level_max) + panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); + + if (!panel->backlight.pwm_level_max) + return -ENODEV; + + if (panel->backlight.combination_mode) + panel->backlight.pwm_level_max *= 0xff; + + panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); + + panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE; + + return 0; +} + +static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 ctl, ctl2; + + if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B)) + return -ENODEV; + + ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); + panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; + + ctl = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)); + panel->backlight.pwm_level_max = ctl >> 16; + + if (!panel->backlight.pwm_level_max) + panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); + + if (!panel->backlight.pwm_level_max) + return -ENODEV; + + panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); + + panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE; + + return 0; +} + +static int +bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 pwm_ctl, val; + + panel->backlight.controller = dev_priv->vbt.backlight.controller; + + pwm_ctl = intel_de_read(dev_priv, + BXT_BLC_PWM_CTL(panel->backlight.controller)); + + /* Controller 1 uses the utility pin. */ + if (panel->backlight.controller == 1) { + val = intel_de_read(dev_priv, UTIL_PIN_CTL); + panel->backlight.util_pin_active_low = + val & UTIL_PIN_POLARITY; + } + + panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY; + panel->backlight.pwm_level_max = + intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller)); + + if (!panel->backlight.pwm_level_max) + panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); + + if (!panel->backlight.pwm_level_max) + return -ENODEV; + + panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); + + panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE; + + return 0; +} + +static int +cnp_setup_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + u32 pwm_ctl; + + /* + * CNP has the BXT implementation of backlight, but with only one + * controller. TODO: ICP has multiple controllers but we only use + * controller 0 for now. + */ + panel->backlight.controller = 0; + + pwm_ctl = intel_de_read(dev_priv, + BXT_BLC_PWM_CTL(panel->backlight.controller)); + + panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY; + panel->backlight.pwm_level_max = + intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller)); + + if (!panel->backlight.pwm_level_max) + panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); + + if (!panel->backlight.pwm_level_max) + return -ENODEV; + + panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); + + panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE; + + return 0; +} + +static int ext_pwm_setup_backlight(struct intel_connector *connector, + enum pipe pipe) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_panel *panel = &connector->panel; + const char *desc; + u32 level; + + /* Get the right PWM chip for DSI backlight according to VBT */ + if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) { + panel->backlight.pwm = pwm_get(dev->dev, "pwm_pmic_backlight"); + desc = "PMIC"; + } else { + panel->backlight.pwm = pwm_get(dev->dev, "pwm_soc_backlight"); + desc = "SoC"; + } + + if (IS_ERR(panel->backlight.pwm)) { + drm_err(&dev_priv->drm, "Failed to get the %s PWM chip\n", + desc); + panel->backlight.pwm = NULL; + return -ENODEV; + } + + panel->backlight.pwm_level_max = 100; /* 100% */ + panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); + + if (pwm_is_enabled(panel->backlight.pwm)) { + /* PWM is already enabled, use existing settings */ + pwm_get_state(panel->backlight.pwm, &panel->backlight.pwm_state); + + level = pwm_get_relative_duty_cycle(&panel->backlight.pwm_state, + 100); + level = intel_panel_invert_pwm_level(connector, level); + panel->backlight.pwm_enabled = true; + + drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n", + NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period, + get_vbt_pwm_freq(dev_priv), level); + } else { + /* Set period from VBT frequency, leave other settings at 0. */ + panel->backlight.pwm_state.period = + NSEC_PER_SEC / get_vbt_pwm_freq(dev_priv); + } + + drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n", + desc); + return 0; +} + +static void intel_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct intel_panel *panel = &connector->panel; + + panel->backlight.pwm_funcs->set(conn_state, + intel_panel_invert_pwm_level(connector, level)); +} + +static u32 intel_pwm_get_backlight(struct intel_connector *connector, enum pipe pipe) +{ + struct intel_panel *panel = &connector->panel; + + return intel_panel_invert_pwm_level(connector, + panel->backlight.pwm_funcs->get(connector, pipe)); +} + +static void intel_pwm_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct intel_panel *panel = &connector->panel; + + panel->backlight.pwm_funcs->enable(crtc_state, conn_state, + intel_panel_invert_pwm_level(connector, level)); +} + +static void intel_pwm_disable_backlight(const struct drm_connector_state *conn_state, u32 level) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct intel_panel *panel = &connector->panel; + + panel->backlight.pwm_funcs->disable(conn_state, + intel_panel_invert_pwm_level(connector, level)); +} + +static int intel_pwm_setup_backlight(struct intel_connector *connector, enum pipe pipe) +{ + struct intel_panel *panel = &connector->panel; + int ret = panel->backlight.pwm_funcs->setup(connector, pipe); + + if (ret < 0) + return ret; + + panel->backlight.min = panel->backlight.pwm_level_min; + panel->backlight.max = panel->backlight.pwm_level_max; + panel->backlight.level = intel_pwm_get_backlight(connector, pipe); + panel->backlight.enabled = panel->backlight.pwm_enabled; + + return 0; +} + +void intel_panel_update_backlight(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) +{ + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; + + if (!panel->backlight.present) + return; + + mutex_lock(&dev_priv->backlight_lock); + if (!panel->backlight.enabled) + __intel_panel_enable_backlight(crtc_state, conn_state); + + mutex_unlock(&dev_priv->backlight_lock); +} + +int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) +{ + struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_connector *intel_connector = to_intel_connector(connector); + struct intel_panel *panel = &intel_connector->panel; + int ret; + + if (!dev_priv->vbt.backlight.present) { + if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) { + drm_dbg_kms(&dev_priv->drm, + "no backlight present per VBT, but present per quirk\n"); + } else { + drm_dbg_kms(&dev_priv->drm, + "no backlight present per VBT\n"); + return 0; + } + } + + /* ensure intel_panel has been initialized first */ + if (drm_WARN_ON(&dev_priv->drm, !panel->backlight.funcs)) + return -ENODEV; + + /* set level and max in panel struct */ + mutex_lock(&dev_priv->backlight_lock); + ret = panel->backlight.funcs->setup(intel_connector, pipe); + mutex_unlock(&dev_priv->backlight_lock); + + if (ret) { + drm_dbg_kms(&dev_priv->drm, + "failed to setup backlight for connector %s\n", + connector->name); + return ret; + } + + panel->backlight.present = true; + + drm_dbg_kms(&dev_priv->drm, + "Connector %s backlight initialized, %s, brightness %u/%u\n", + connector->name, + enableddisabled(panel->backlight.enabled), + panel->backlight.level, panel->backlight.max); + + return 0; +} + +void intel_panel_destroy_backlight(struct intel_panel *panel) +{ + /* dispose of the pwm */ + if (panel->backlight.pwm) + pwm_put(panel->backlight.pwm); + + panel->backlight.present = false; +} + +static const struct intel_panel_bl_funcs bxt_pwm_funcs = { + .setup = bxt_setup_backlight, + .enable = bxt_enable_backlight, + .disable = bxt_disable_backlight, + .set = bxt_set_backlight, + .get = bxt_get_backlight, + .hz_to_pwm = bxt_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs cnp_pwm_funcs = { + .setup = cnp_setup_backlight, + .enable = cnp_enable_backlight, + .disable = cnp_disable_backlight, + .set = bxt_set_backlight, + .get = bxt_get_backlight, + .hz_to_pwm = cnp_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs lpt_pwm_funcs = { + .setup = lpt_setup_backlight, + .enable = lpt_enable_backlight, + .disable = lpt_disable_backlight, + .set = lpt_set_backlight, + .get = lpt_get_backlight, + .hz_to_pwm = lpt_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs spt_pwm_funcs = { + .setup = lpt_setup_backlight, + .enable = lpt_enable_backlight, + .disable = lpt_disable_backlight, + .set = lpt_set_backlight, + .get = lpt_get_backlight, + .hz_to_pwm = spt_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs pch_pwm_funcs = { + .setup = pch_setup_backlight, + .enable = pch_enable_backlight, + .disable = pch_disable_backlight, + .set = pch_set_backlight, + .get = pch_get_backlight, + .hz_to_pwm = pch_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs ext_pwm_funcs = { + .setup = ext_pwm_setup_backlight, + .enable = ext_pwm_enable_backlight, + .disable = ext_pwm_disable_backlight, + .set = ext_pwm_set_backlight, + .get = ext_pwm_get_backlight, +}; + +static const struct intel_panel_bl_funcs vlv_pwm_funcs = { + .setup = vlv_setup_backlight, + .enable = vlv_enable_backlight, + .disable = vlv_disable_backlight, + .set = vlv_set_backlight, + .get = vlv_get_backlight, + .hz_to_pwm = vlv_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs i965_pwm_funcs = { + .setup = i965_setup_backlight, + .enable = i965_enable_backlight, + .disable = i965_disable_backlight, + .set = i9xx_set_backlight, + .get = i9xx_get_backlight, + .hz_to_pwm = i965_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs i9xx_pwm_funcs = { + .setup = i9xx_setup_backlight, + .enable = i9xx_enable_backlight, + .disable = i9xx_disable_backlight, + .set = i9xx_set_backlight, + .get = i9xx_get_backlight, + .hz_to_pwm = i9xx_hz_to_pwm, +}; + +static const struct intel_panel_bl_funcs pwm_bl_funcs = { + .setup = intel_pwm_setup_backlight, + .enable = intel_pwm_enable_backlight, + .disable = intel_pwm_disable_backlight, + .set = intel_pwm_set_backlight, + .get = intel_pwm_get_backlight, +}; + +/* Set up chip specific backlight functions */ +void +intel_panel_init_backlight_funcs(struct intel_panel *panel) +{ + struct intel_connector *connector = + container_of(panel, struct intel_connector, panel); + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + + if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI && + intel_dsi_dcs_init_backlight_funcs(connector) == 0) + return; + + if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + panel->backlight.pwm_funcs = &bxt_pwm_funcs; + } else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) { + panel->backlight.pwm_funcs = &cnp_pwm_funcs; + } else if (INTEL_PCH_TYPE(dev_priv) >= PCH_LPT) { + if (HAS_PCH_LPT(dev_priv)) + panel->backlight.pwm_funcs = &lpt_pwm_funcs; + else + panel->backlight.pwm_funcs = &spt_pwm_funcs; + } else if (HAS_PCH_SPLIT(dev_priv)) { + panel->backlight.pwm_funcs = &pch_pwm_funcs; + } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) { + panel->backlight.pwm_funcs = &ext_pwm_funcs; + } else { + panel->backlight.pwm_funcs = &vlv_pwm_funcs; + } + } else if (DISPLAY_VER(dev_priv) == 4) { + panel->backlight.pwm_funcs = &i965_pwm_funcs; + } else { + panel->backlight.pwm_funcs = &i9xx_pwm_funcs; + } + + if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP && + intel_dp_aux_init_backlight_funcs(connector) == 0) + return; + + /* We're using a standard PWM backlight interface */ + panel->backlight.funcs = &pwm_bl_funcs; +} diff --git a/drivers/gpu/drm/i915/display/intel_backlight.h b/drivers/gpu/drm/i915/display/intel_backlight.h new file mode 100644 index 000000000000..282020cb47d5 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_backlight.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2021 Intel Corporation + */ + +#ifndef __INTEL_BACKLIGHT_H__ +#define __INTEL_BACKLIGHT_H__ + +#include + +struct drm_connector; +struct drm_connector_state; +struct intel_atomic_state; +struct intel_connector; +struct intel_crtc_state; +struct intel_encoder; +struct intel_panel; +enum pipe; + +void intel_panel_init_backlight_funcs(struct intel_panel *panel); +void intel_panel_destroy_backlight(struct intel_panel *panel); +void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, + u32 level, u32 max); +int intel_panel_setup_backlight(struct drm_connector *connector, + enum pipe pipe); +void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +void intel_panel_update_backlight(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state); +void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 level); +u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 level); +u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 level); +u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val); + +#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) +int intel_backlight_device_register(struct intel_connector *connector); +void intel_backlight_device_unregister(struct intel_connector *connector); +#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */ +static inline int intel_backlight_device_register(struct intel_connector *connector) +{ + return 0; +} +static inline void intel_backlight_device_unregister(struct intel_connector *connector) +{ +} +#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ + +#endif /* __INTEL_BACKLIGHT_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c index 9bed1ccecea0..4f49d782eca2 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.c +++ b/drivers/gpu/drm/i915/display/intel_connector.c @@ -29,13 +29,13 @@ #include #include -#include "display/intel_panel.h" - #include "i915_drv.h" +#include "intel_backlight.h" #include "intel_connector.h" #include "intel_display_debugfs.h" #include "intel_display_types.h" #include "intel_hdcp.h" +#include "intel_panel.h" int intel_connector_init(struct intel_connector *connector) { diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 1ef7a65feb66..dbd38beece3f 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -29,6 +29,7 @@ #include "i915_drv.h" #include "intel_audio.h" +#include "intel_backlight.h" #include "intel_combo_phy.h" #include "intel_connector.h" #include "intel_crtc.h" @@ -48,7 +49,6 @@ #include "intel_hdmi.h" #include "intel_hotplug.h" #include "intel_lspcon.h" -#include "intel_panel.h" #include "intel_pps.h" #include "intel_psr.h" #include "intel_snps_phy.h" diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index fd4f7e82e420..71be9f92133e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -44,6 +44,7 @@ #include "i915_drv.h" #include "intel_atomic.h" #include "intel_audio.h" +#include "intel_backlight.h" #include "intel_connector.h" #include "intel_ddi.h" #include "intel_de.h" diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index 6ac568617ef3..d026b9420403 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -34,9 +34,9 @@ * for some reason. */ +#include "intel_backlight.h" #include "intel_display_types.h" #include "intel_dp_aux_backlight.h" -#include "intel_panel.h" /* TODO: * Implement HDR, right now we just implement the bare minimum to bring us back into SDR mode so we diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index e0381b0fce91..8f5741ebd58d 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -40,6 +40,7 @@ #include "i915_drv.h" #include "intel_atomic.h" +#include "intel_backlight.h" #include "intel_connector.h" #include "intel_de.h" #include "intel_display_types.h" diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index 3855fba70980..3a7a8598d1ec 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -30,10 +30,9 @@ #include #include -#include "display/intel_panel.h" - #include "i915_drv.h" #include "intel_acpi.h" +#include "intel_backlight.h" #include "intel_display_types.h" #include "intel_opregion.h" diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index 074a55f20bcd..083eb774c4bb 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -28,17 +28,13 @@ * Chris Wilson */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include -#include #include +#include "intel_backlight.h" #include "intel_connector.h" #include "intel_de.h" #include "intel_display_types.h" -#include "intel_dp_aux_backlight.h" -#include "intel_dsi_dcs_backlight.h" #include "intel_panel.h" bool intel_panel_use_ssc(struct drm_i915_private *i915) @@ -464,1767 +460,6 @@ out: return 0; } -/** - * scale - scale values from one range to another - * @source_val: value in range [@source_min..@source_max] - * @source_min: minimum legal value for @source_val - * @source_max: maximum legal value for @source_val - * @target_min: corresponding target value for @source_min - * @target_max: corresponding target value for @source_max - * - * Return @source_val in range [@source_min..@source_max] scaled to range - * [@target_min..@target_max]. - */ -static u32 scale(u32 source_val, - u32 source_min, u32 source_max, - u32 target_min, u32 target_max) -{ - u64 target_val; - - WARN_ON(source_min > source_max); - WARN_ON(target_min > target_max); - - /* defensive */ - source_val = clamp(source_val, source_min, source_max); - - /* avoid overflows */ - target_val = mul_u32_u32(source_val - source_min, - target_max - target_min); - target_val = DIV_ROUND_CLOSEST_ULL(target_val, source_max - source_min); - target_val += target_min; - - return target_val; -} - -/* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result - * to [hw_min..hw_max]. */ -static u32 clamp_user_to_hw(struct intel_connector *connector, - u32 user_level, u32 user_max) -{ - struct intel_panel *panel = &connector->panel; - u32 hw_level; - - hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max); - hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max); - - return hw_level; -} - -/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */ -static u32 scale_hw_to_user(struct intel_connector *connector, - u32 hw_level, u32 user_max) -{ - struct intel_panel *panel = &connector->panel; - - return scale(hw_level, panel->backlight.min, panel->backlight.max, - 0, user_max); -} - -u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 val) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - - drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0); - - if (dev_priv->params.invert_brightness < 0) - return val; - - if (dev_priv->params.invert_brightness > 0 || - dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { - return panel->backlight.pwm_level_max - val + panel->backlight.pwm_level_min; - } - - return val; -} - -void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 val) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - - drm_dbg_kms(&i915->drm, "set backlight PWM = %d\n", val); - panel->backlight.pwm_funcs->set(conn_state, val); -} - -u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 val) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - - drm_WARN_ON_ONCE(&dev_priv->drm, - panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0); - - val = scale(val, panel->backlight.min, panel->backlight.max, - panel->backlight.pwm_level_min, panel->backlight.pwm_level_max); - - return intel_panel_invert_pwm_level(connector, val); -} - -u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - - drm_WARN_ON_ONCE(&dev_priv->drm, - 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)) - 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, - panel->backlight.min, panel->backlight.max); -} - -static u32 lpt_get_backlight(struct intel_connector *connector, enum pipe unused) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - - return intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK; -} - -static u32 pch_get_backlight(struct intel_connector *connector, enum pipe unused) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - - return intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; -} - -static u32 i9xx_get_backlight(struct intel_connector *connector, enum pipe unused) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 val; - - val = intel_de_read(dev_priv, BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; - if (DISPLAY_VER(dev_priv) < 4) - val >>= 1; - - if (panel->backlight.combination_mode) { - u8 lbpc; - - pci_read_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, &lbpc); - val *= lbpc; - } - - return val; -} - -static u32 vlv_get_backlight(struct intel_connector *connector, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - - if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B)) - return 0; - - return intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK; -} - -static u32 bxt_get_backlight(struct intel_connector *connector, enum pipe unused) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - - return intel_de_read(dev_priv, - BXT_BLC_PWM_DUTY(panel->backlight.controller)); -} - -static u32 ext_pwm_get_backlight(struct intel_connector *connector, enum pipe unused) -{ - struct intel_panel *panel = &connector->panel; - struct pwm_state state; - - pwm_get_state(panel->backlight.pwm, &state); - return pwm_get_relative_duty_cycle(&state, 100); -} - -static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - - u32 val = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK; - intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, val | level); -} - -static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - u32 tmp; - - tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; - intel_de_write(dev_priv, BLC_PWM_CPU_CTL, tmp | level); -} - -static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 tmp, mask; - - drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0); - - if (panel->backlight.combination_mode) { - u8 lbpc; - - lbpc = level * 0xfe / panel->backlight.pwm_level_max + 1; - level /= lbpc; - pci_write_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, lbpc); - } - - if (DISPLAY_VER(dev_priv) == 4) { - mask = BACKLIGHT_DUTY_CYCLE_MASK; - } else { - level <<= 1; - mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV; - } - - tmp = intel_de_read(dev_priv, BLC_PWM_CTL) & ~mask; - intel_de_write(dev_priv, BLC_PWM_CTL, tmp | level); -} - -static void vlv_set_backlight(const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe; - u32 tmp; - - tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK; - intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), tmp | level); -} - -static void bxt_set_backlight(const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - - intel_de_write(dev_priv, - BXT_BLC_PWM_DUTY(panel->backlight.controller), level); -} - -static void ext_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel; - - pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100); - pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); -} - -static void -intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - - drm_dbg_kms(&i915->drm, "set backlight level = %d\n", level); - - panel->backlight.funcs->set(conn_state, level); -} - -/* set backlight brightness to level in range [0..max], assuming hw min is - * respected. - */ -void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, - u32 user_level, u32 user_max) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 hw_level; - - /* - * Lack of crtc may occur during driver init because - * connection_mutex isn't held across the entire backlight - * setup + modeset readout, and the BIOS can issue the - * requests at any time. - */ - if (!panel->backlight.present || !conn_state->crtc) - return; - - mutex_lock(&dev_priv->backlight_lock); - - drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0); - - hw_level = clamp_user_to_hw(connector, user_level, user_max); - panel->backlight.level = hw_level; - - if (panel->backlight.device) - panel->backlight.device->props.brightness = - scale_hw_to_user(connector, - panel->backlight.level, - panel->backlight.device->props.max_brightness); - - if (panel->backlight.enabled) - intel_panel_actually_set_backlight(conn_state, hw_level); - - mutex_unlock(&dev_priv->backlight_lock); -} - -static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - u32 tmp; - - intel_panel_set_pwm_level(old_conn_state, level); - - /* - * Although we don't support or enable CPU PWM with LPT/SPT based - * systems, it may have been enabled prior to loading the - * driver. Disable to avoid warnings on LCPLL disable. - * - * This needs rework if we need to add support for CPU PWM on PCH split - * platforms. - */ - tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); - if (tmp & BLM_PWM_ENABLE) { - drm_dbg_kms(&dev_priv->drm, - "cpu backlight was enabled, disabling\n"); - intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, - tmp & ~BLM_PWM_ENABLE); - } - - tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); - intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); -} - -static void pch_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) -{ - struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - u32 tmp; - - intel_panel_set_pwm_level(old_conn_state, val); - - tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); - intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); - - tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); - intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); -} - -static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) -{ - intel_panel_set_pwm_level(old_conn_state, val); -} - -static void i965_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) -{ - struct drm_i915_private *dev_priv = to_i915(old_conn_state->connector->dev); - u32 tmp; - - intel_panel_set_pwm_level(old_conn_state, val); - - tmp = intel_de_read(dev_priv, BLC_PWM_CTL2); - intel_de_write(dev_priv, BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE); -} - -static void vlv_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) -{ - struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - enum pipe pipe = to_intel_crtc(old_conn_state->crtc)->pipe; - u32 tmp; - - intel_panel_set_pwm_level(old_conn_state, val); - - tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); - intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), - tmp & ~BLM_PWM_ENABLE); -} - -static void bxt_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) -{ - struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 tmp; - - intel_panel_set_pwm_level(old_conn_state, val); - - tmp = intel_de_read(dev_priv, - BXT_BLC_PWM_CTL(panel->backlight.controller)); - intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), - tmp & ~BXT_BLC_PWM_ENABLE); - - if (panel->backlight.controller == 1) { - val = intel_de_read(dev_priv, UTIL_PIN_CTL); - val &= ~UTIL_PIN_ENABLE; - intel_de_write(dev_priv, UTIL_PIN_CTL, val); - } -} - -static void cnp_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) -{ - struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 tmp; - - intel_panel_set_pwm_level(old_conn_state, val); - - tmp = intel_de_read(dev_priv, - BXT_BLC_PWM_CTL(panel->backlight.controller)); - intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), - tmp & ~BXT_BLC_PWM_ENABLE); -} - -static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct intel_panel *panel = &connector->panel; - - panel->backlight.pwm_state.enabled = false; - pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); -} - -void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state) -{ - struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - - if (!panel->backlight.present) - return; - - /* - * Do not disable backlight on the vga_switcheroo path. When switching - * away from i915, the other client may depend on i915 to handle the - * backlight. This will leave the backlight on unnecessarily when - * another client is not activated. - */ - if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) { - drm_dbg_kms(&dev_priv->drm, - "Skipping backlight disable on vga switch\n"); - return; - } - - mutex_lock(&dev_priv->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); -} - -static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 pch_ctl1, pch_ctl2, schicken; - - pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); - if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { - drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n"); - pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; - intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1); - } - - if (HAS_PCH_LPT(dev_priv)) { - schicken = intel_de_read(dev_priv, SOUTH_CHICKEN2); - if (panel->backlight.alternate_pwm_increment) - schicken |= LPT_PWM_GRANULARITY; - else - schicken &= ~LPT_PWM_GRANULARITY; - intel_de_write(dev_priv, SOUTH_CHICKEN2, schicken); - } else { - schicken = intel_de_read(dev_priv, SOUTH_CHICKEN1); - if (panel->backlight.alternate_pwm_increment) - schicken |= SPT_PWM_GRANULARITY; - else - schicken &= ~SPT_PWM_GRANULARITY; - intel_de_write(dev_priv, SOUTH_CHICKEN1, schicken); - } - - pch_ctl2 = panel->backlight.pwm_level_max << 16; - intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2); - - pch_ctl1 = 0; - if (panel->backlight.active_low_pwm) - pch_ctl1 |= BLM_PCH_POLARITY; - - /* After LPT, override is the default. */ - if (HAS_PCH_LPT(dev_priv)) - pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE; - - intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1); - intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1); - intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, - pch_ctl1 | BLM_PCH_PWM_ENABLE); - - /* This won't stick until the above enable. */ - intel_panel_set_pwm_level(conn_state, level); -} - -static void pch_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - u32 cpu_ctl2, pch_ctl1, pch_ctl2; - - cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); - if (cpu_ctl2 & BLM_PWM_ENABLE) { - drm_dbg_kms(&dev_priv->drm, "cpu backlight already enabled\n"); - cpu_ctl2 &= ~BLM_PWM_ENABLE; - intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2); - } - - pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); - if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { - drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n"); - pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; - intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1); - } - - if (cpu_transcoder == TRANSCODER_EDP) - cpu_ctl2 = BLM_TRANSCODER_EDP; - else - cpu_ctl2 = BLM_PIPE(cpu_transcoder); - intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2); - intel_de_posting_read(dev_priv, BLC_PWM_CPU_CTL2); - intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE); - - /* This won't stick until the above enable. */ - intel_panel_set_pwm_level(conn_state, level); - - pch_ctl2 = panel->backlight.pwm_level_max << 16; - intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2); - - pch_ctl1 = 0; - if (panel->backlight.active_low_pwm) - pch_ctl1 |= BLM_PCH_POLARITY; - - intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, pch_ctl1); - intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1); - intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, - pch_ctl1 | BLM_PCH_PWM_ENABLE); -} - -static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 ctl, freq; - - ctl = intel_de_read(dev_priv, BLC_PWM_CTL); - if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) { - drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); - intel_de_write(dev_priv, BLC_PWM_CTL, 0); - } - - freq = panel->backlight.pwm_level_max; - if (panel->backlight.combination_mode) - freq /= 0xff; - - ctl = freq << 17; - if (panel->backlight.combination_mode) - ctl |= BLM_LEGACY_MODE; - if (IS_PINEVIEW(dev_priv) && panel->backlight.active_low_pwm) - ctl |= BLM_POLARITY_PNV; - - intel_de_write(dev_priv, BLC_PWM_CTL, ctl); - intel_de_posting_read(dev_priv, BLC_PWM_CTL); - - /* XXX: combine this into above write? */ - intel_panel_set_pwm_level(conn_state, level); - - /* - * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is - * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2 - * that has backlight. - */ - if (DISPLAY_VER(dev_priv) == 2) - intel_de_write(dev_priv, BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE); -} - -static void i965_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe; - u32 ctl, ctl2, freq; - - ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2); - if (ctl2 & BLM_PWM_ENABLE) { - drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); - ctl2 &= ~BLM_PWM_ENABLE; - intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2); - } - - freq = panel->backlight.pwm_level_max; - if (panel->backlight.combination_mode) - freq /= 0xff; - - ctl = freq << 16; - intel_de_write(dev_priv, BLC_PWM_CTL, ctl); - - ctl2 = BLM_PIPE(pipe); - if (panel->backlight.combination_mode) - ctl2 |= BLM_COMBINATION_MODE; - if (panel->backlight.active_low_pwm) - ctl2 |= BLM_POLARITY_I965; - intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2); - intel_de_posting_read(dev_priv, BLC_PWM_CTL2); - intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE); - - intel_panel_set_pwm_level(conn_state, level); -} - -static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; - u32 ctl, ctl2; - - ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); - if (ctl2 & BLM_PWM_ENABLE) { - drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); - ctl2 &= ~BLM_PWM_ENABLE; - intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2); - } - - ctl = panel->backlight.pwm_level_max << 16; - intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), ctl); - - /* XXX: combine this into above write? */ - intel_panel_set_pwm_level(conn_state, level); - - ctl2 = 0; - if (panel->backlight.active_low_pwm) - ctl2 |= BLM_POLARITY_I965; - intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), ctl2); - intel_de_posting_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); - intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), - ctl2 | BLM_PWM_ENABLE); -} - -static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; - u32 pwm_ctl, val; - - /* Controller 1 uses the utility pin. */ - if (panel->backlight.controller == 1) { - val = intel_de_read(dev_priv, UTIL_PIN_CTL); - if (val & UTIL_PIN_ENABLE) { - drm_dbg_kms(&dev_priv->drm, - "util pin already enabled\n"); - val &= ~UTIL_PIN_ENABLE; - intel_de_write(dev_priv, UTIL_PIN_CTL, val); - } - - val = 0; - if (panel->backlight.util_pin_active_low) - val |= UTIL_PIN_POLARITY; - intel_de_write(dev_priv, UTIL_PIN_CTL, - val | UTIL_PIN_PIPE(pipe) | UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE); - } - - pwm_ctl = intel_de_read(dev_priv, - BXT_BLC_PWM_CTL(panel->backlight.controller)); - if (pwm_ctl & BXT_BLC_PWM_ENABLE) { - drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); - pwm_ctl &= ~BXT_BLC_PWM_ENABLE; - intel_de_write(dev_priv, - BXT_BLC_PWM_CTL(panel->backlight.controller), - pwm_ctl); - } - - intel_de_write(dev_priv, - BXT_BLC_PWM_FREQ(panel->backlight.controller), - panel->backlight.pwm_level_max); - - intel_panel_set_pwm_level(conn_state, level); - - pwm_ctl = 0; - if (panel->backlight.active_low_pwm) - pwm_ctl |= BXT_BLC_PWM_POLARITY; - - intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), - pwm_ctl); - intel_de_posting_read(dev_priv, - BXT_BLC_PWM_CTL(panel->backlight.controller)); - intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), - pwm_ctl | BXT_BLC_PWM_ENABLE); -} - -static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 pwm_ctl; - - pwm_ctl = intel_de_read(dev_priv, - BXT_BLC_PWM_CTL(panel->backlight.controller)); - if (pwm_ctl & BXT_BLC_PWM_ENABLE) { - drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n"); - pwm_ctl &= ~BXT_BLC_PWM_ENABLE; - intel_de_write(dev_priv, - BXT_BLC_PWM_CTL(panel->backlight.controller), - pwm_ctl); - } - - intel_de_write(dev_priv, - BXT_BLC_PWM_FREQ(panel->backlight.controller), - panel->backlight.pwm_level_max); - - intel_panel_set_pwm_level(conn_state, level); - - pwm_ctl = 0; - if (panel->backlight.active_low_pwm) - pwm_ctl |= BXT_BLC_PWM_POLARITY; - - intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), - pwm_ctl); - intel_de_posting_read(dev_priv, - BXT_BLC_PWM_CTL(panel->backlight.controller)); - intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller), - pwm_ctl | BXT_BLC_PWM_ENABLE); -} - -static void ext_pwm_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct intel_panel *panel = &connector->panel; - - pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100); - panel->backlight.pwm_state.enabled = true; - pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); -} - -static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct intel_panel *panel = &connector->panel; - - WARN_ON(panel->backlight.max == 0); - - if (panel->backlight.level <= panel->backlight.min) { - panel->backlight.level = panel->backlight.max; - if (panel->backlight.device) - panel->backlight.device->props.brightness = - scale_hw_to_user(connector, - panel->backlight.level, - panel->backlight.device->props.max_brightness); - } - - panel->backlight.funcs->enable(crtc_state, conn_state, panel->backlight.level); - panel->backlight.enabled = true; - if (panel->backlight.device) - panel->backlight.device->props.power = FB_BLANK_UNBLANK; -} - -void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; - - if (!panel->backlight.present) - return; - - drm_dbg_kms(&dev_priv->drm, "pipe %c\n", pipe_name(pipe)); - - mutex_lock(&dev_priv->backlight_lock); - - __intel_panel_enable_backlight(crtc_state, conn_state); - - mutex_unlock(&dev_priv->backlight_lock); -} - -#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) -static u32 intel_panel_get_backlight(struct intel_connector *connector) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 val = 0; - - mutex_lock(&dev_priv->backlight_lock); - - if (panel->backlight.enabled) - val = panel->backlight.funcs->get(connector, intel_connector_get_pipe(connector)); - - mutex_unlock(&dev_priv->backlight_lock); - - drm_dbg_kms(&dev_priv->drm, "get backlight PWM = %d\n", val); - return val; -} - -/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */ -static u32 scale_user_to_hw(struct intel_connector *connector, - u32 user_level, u32 user_max) -{ - struct intel_panel *panel = &connector->panel; - - return scale(user_level, 0, user_max, - panel->backlight.min, panel->backlight.max); -} - -/* set backlight brightness to level in range [0..max], scaling wrt hw min */ -static void intel_panel_set_backlight(const struct drm_connector_state *conn_state, - u32 user_level, u32 user_max) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 hw_level; - - if (!panel->backlight.present) - return; - - mutex_lock(&dev_priv->backlight_lock); - - drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0); - - hw_level = scale_user_to_hw(connector, user_level, user_max); - panel->backlight.level = hw_level; - - if (panel->backlight.enabled) - intel_panel_actually_set_backlight(conn_state, hw_level); - - mutex_unlock(&dev_priv->backlight_lock); -} - -static int intel_backlight_device_update_status(struct backlight_device *bd) -{ - struct intel_connector *connector = bl_get_data(bd); - struct intel_panel *panel = &connector->panel; - struct drm_device *dev = connector->base.dev; - - drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); - DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n", - bd->props.brightness, bd->props.max_brightness); - intel_panel_set_backlight(connector->base.state, bd->props.brightness, - bd->props.max_brightness); - - /* - * Allow flipping bl_power as a sub-state of enabled. Sadly the - * backlight class device does not make it easy to to differentiate - * between callbacks for brightness and bl_power, so our backlight_power - * callback needs to take this into account. - */ - if (panel->backlight.enabled) { - if (panel->backlight.power) { - bool enable = bd->props.power == FB_BLANK_UNBLANK && - bd->props.brightness != 0; - panel->backlight.power(connector, enable); - } - } else { - bd->props.power = FB_BLANK_POWERDOWN; - } - - drm_modeset_unlock(&dev->mode_config.connection_mutex); - return 0; -} - -static int intel_backlight_device_get_brightness(struct backlight_device *bd) -{ - struct intel_connector *connector = bl_get_data(bd); - struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - intel_wakeref_t wakeref; - int ret = 0; - - with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) { - u32 hw_level; - - drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); - - hw_level = intel_panel_get_backlight(connector); - ret = scale_hw_to_user(connector, - hw_level, bd->props.max_brightness); - - drm_modeset_unlock(&dev->mode_config.connection_mutex); - } - - return ret; -} - -static const struct backlight_ops intel_backlight_device_ops = { - .update_status = intel_backlight_device_update_status, - .get_brightness = intel_backlight_device_get_brightness, -}; - -int intel_backlight_device_register(struct intel_connector *connector) -{ - struct drm_i915_private *i915 = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - struct backlight_properties props; - struct backlight_device *bd; - const char *name; - int ret = 0; - - if (WARN_ON(panel->backlight.device)) - return -ENODEV; - - if (!panel->backlight.present) - return 0; - - WARN_ON(panel->backlight.max == 0); - - memset(&props, 0, sizeof(props)); - props.type = BACKLIGHT_RAW; - - /* - * Note: Everything should work even if the backlight device max - * presented to the userspace is arbitrarily chosen. - */ - props.max_brightness = panel->backlight.max; - props.brightness = scale_hw_to_user(connector, - panel->backlight.level, - props.max_brightness); - - if (panel->backlight.enabled) - props.power = FB_BLANK_UNBLANK; - else - props.power = FB_BLANK_POWERDOWN; - - name = kstrdup("intel_backlight", GFP_KERNEL); - if (!name) - return -ENOMEM; - - bd = backlight_device_register(name, connector->base.kdev, connector, - &intel_backlight_device_ops, &props); - - /* - * Using the same name independent of the drm device or connector - * prevents registration of multiple backlight devices in the - * driver. However, we need to use the default name for backward - * compatibility. Use unique names for subsequent backlight devices as a - * fallback when the default name already exists. - */ - if (IS_ERR(bd) && PTR_ERR(bd) == -EEXIST) { - kfree(name); - name = kasprintf(GFP_KERNEL, "card%d-%s-backlight", - i915->drm.primary->index, connector->base.name); - if (!name) - return -ENOMEM; - - bd = backlight_device_register(name, connector->base.kdev, connector, - &intel_backlight_device_ops, &props); - } - - if (IS_ERR(bd)) { - drm_err(&i915->drm, - "[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n", - connector->base.base.id, connector->base.name, name, PTR_ERR(bd)); - ret = PTR_ERR(bd); - goto out; - } - - panel->backlight.device = bd; - - drm_dbg_kms(&i915->drm, - "[CONNECTOR:%d:%s] backlight device %s registered\n", - connector->base.base.id, connector->base.name, name); - -out: - kfree(name); - - return ret; -} - -void intel_backlight_device_unregister(struct intel_connector *connector) -{ - struct intel_panel *panel = &connector->panel; - - if (panel->backlight.device) { - backlight_device_unregister(panel->backlight.device); - panel->backlight.device = NULL; - } -} -#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ - -/* - * CNP: PWM clock frequency is 19.2 MHz or 24 MHz. - * PWM increment = 1 - */ -static u32 cnp_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - - return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq), - pwm_freq_hz); -} - -/* - * BXT: PWM clock frequency = 19.2 MHz. - */ -static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) -{ - return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz); -} - -/* - * SPT: This value represents the period of the PWM stream in clock periods - * multiplied by 16 (default increment) or 128 (alternate increment selected in - * SCHICKEN_1 bit 0). PWM clock is 24 MHz. - */ -static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) -{ - struct intel_panel *panel = &connector->panel; - u32 mul; - - if (panel->backlight.alternate_pwm_increment) - mul = 128; - else - mul = 16; - - return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul); -} - -/* - * LPT: This value represents the period of the PWM stream in clock periods - * multiplied by 128 (default increment) or 16 (alternate increment, selected in - * LPT SOUTH_CHICKEN2 register bit 5). - */ -static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 mul, clock; - - if (panel->backlight.alternate_pwm_increment) - mul = 16; - else - mul = 128; - - if (HAS_PCH_LPT_H(dev_priv)) - clock = MHz(135); /* LPT:H */ - else - clock = MHz(24); /* LPT:LP */ - - return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul); -} - -/* - * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH - * display raw clocks multiplied by 128. - */ -static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - - return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq), - pwm_freq_hz * 128); -} - -/* - * Gen2: This field determines the number of time base events (display core - * clock frequency/32) in total for a complete cycle of modulated backlight - * control. - * - * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock) - * divided by 32. - */ -static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - int clock; - - if (IS_PINEVIEW(dev_priv)) - clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq); - else - clock = KHz(dev_priv->cdclk.hw.cdclk); - - return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32); -} - -/* - * Gen4: This value represents the period of the PWM stream in display core - * clocks ([DevCTG] HRAW clocks) multiplied by 128. - * - */ -static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - int clock; - - if (IS_G4X(dev_priv)) - clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq); - else - clock = KHz(dev_priv->cdclk.hw.cdclk); - - return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128); -} - -/* - * VLV: This value represents the period of the PWM stream in display core - * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks - * multiplied by 16. CHV uses a 19.2MHz S0IX clock. - */ -static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - int mul, clock; - - if ((intel_de_read(dev_priv, CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) { - if (IS_CHERRYVIEW(dev_priv)) - clock = KHz(19200); - else - clock = MHz(25); - mul = 16; - } else { - clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq); - mul = 128; - } - - return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul); -} - -static u16 get_vbt_pwm_freq(struct drm_i915_private *dev_priv) -{ - u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz; - - if (pwm_freq_hz) { - drm_dbg_kms(&dev_priv->drm, - "VBT defined backlight frequency %u Hz\n", - pwm_freq_hz); - } else { - pwm_freq_hz = 200; - drm_dbg_kms(&dev_priv->drm, - "default backlight frequency %u Hz\n", - pwm_freq_hz); - } - - return pwm_freq_hz; -} - -static u32 get_backlight_max_vbt(struct intel_connector *connector) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv); - u32 pwm; - - if (!panel->backlight.pwm_funcs->hz_to_pwm) { - drm_dbg_kms(&dev_priv->drm, - "backlight frequency conversion not supported\n"); - return 0; - } - - pwm = panel->backlight.pwm_funcs->hz_to_pwm(connector, pwm_freq_hz); - if (!pwm) { - drm_dbg_kms(&dev_priv->drm, - "backlight frequency conversion failed\n"); - return 0; - } - - return pwm; -} - -/* - * Note: The setup hooks can't assume pipe is set! - */ -static u32 get_backlight_min_vbt(struct intel_connector *connector) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - int min; - - drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0); - - /* - * XXX: If the vbt value is 255, it makes min equal to max, which leads - * to problems. There are such machines out there. Either our - * interpretation is wrong or the vbt has bogus data. Or both. Safeguard - * against this by letting the minimum be at most (arbitrarily chosen) - * 25% of the max. - */ - min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64); - if (min != dev_priv->vbt.backlight.min_brightness) { - drm_dbg_kms(&dev_priv->drm, - "clamping VBT min backlight %d/255 to %d/255\n", - dev_priv->vbt.backlight.min_brightness, min); - } - - /* vbt value is a coefficient in range [0..255] */ - return scale(min, 0, 255, 0, panel->backlight.pwm_level_max); -} - -static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 cpu_ctl2, pch_ctl1, pch_ctl2, val; - bool alt, cpu_mode; - - if (HAS_PCH_LPT(dev_priv)) - alt = intel_de_read(dev_priv, SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY; - else - alt = intel_de_read(dev_priv, SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY; - panel->backlight.alternate_pwm_increment = alt; - - pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); - panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; - - pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2); - panel->backlight.pwm_level_max = pch_ctl2 >> 16; - - cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); - - if (!panel->backlight.pwm_level_max) - panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); - - if (!panel->backlight.pwm_level_max) - return -ENODEV; - - panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); - - panel->backlight.pwm_enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE; - - cpu_mode = panel->backlight.pwm_enabled && HAS_PCH_LPT(dev_priv) && - !(pch_ctl1 & BLM_PCH_OVERRIDE_ENABLE) && - (cpu_ctl2 & BLM_PWM_ENABLE); - - if (cpu_mode) { - val = pch_get_backlight(connector, unused); - - drm_dbg_kms(&dev_priv->drm, - "CPU backlight register was enabled, switching to PCH override\n"); - - /* Write converted CPU PWM value to PCH override register */ - lpt_set_backlight(connector->base.state, val); - intel_de_write(dev_priv, BLC_PWM_PCH_CTL1, - pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE); - - intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, - cpu_ctl2 & ~BLM_PWM_ENABLE); - } - - return 0; -} - -static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 cpu_ctl2, pch_ctl1, pch_ctl2; - - pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1); - panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; - - pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2); - panel->backlight.pwm_level_max = pch_ctl2 >> 16; - - if (!panel->backlight.pwm_level_max) - panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); - - if (!panel->backlight.pwm_level_max) - return -ENODEV; - - panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); - - cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); - panel->backlight.pwm_enabled = (cpu_ctl2 & BLM_PWM_ENABLE) && - (pch_ctl1 & BLM_PCH_PWM_ENABLE); - - return 0; -} - -static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 ctl, val; - - ctl = intel_de_read(dev_priv, BLC_PWM_CTL); - - if (DISPLAY_VER(dev_priv) == 2 || IS_I915GM(dev_priv) || IS_I945GM(dev_priv)) - panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE; - - if (IS_PINEVIEW(dev_priv)) - panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV; - - panel->backlight.pwm_level_max = ctl >> 17; - - if (!panel->backlight.pwm_level_max) { - panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); - panel->backlight.pwm_level_max >>= 1; - } - - if (!panel->backlight.pwm_level_max) - return -ENODEV; - - if (panel->backlight.combination_mode) - panel->backlight.pwm_level_max *= 0xff; - - panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); - - val = i9xx_get_backlight(connector, unused); - val = intel_panel_invert_pwm_level(connector, val); - val = clamp(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max); - - panel->backlight.pwm_enabled = val != 0; - - return 0; -} - -static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 ctl, ctl2; - - ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2); - panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE; - panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; - - ctl = intel_de_read(dev_priv, BLC_PWM_CTL); - panel->backlight.pwm_level_max = ctl >> 16; - - if (!panel->backlight.pwm_level_max) - panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); - - if (!panel->backlight.pwm_level_max) - return -ENODEV; - - if (panel->backlight.combination_mode) - panel->backlight.pwm_level_max *= 0xff; - - panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); - - panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE; - - return 0; -} - -static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 ctl, ctl2; - - if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B)) - return -ENODEV; - - ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); - panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; - - ctl = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)); - panel->backlight.pwm_level_max = ctl >> 16; - - if (!panel->backlight.pwm_level_max) - panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); - - if (!panel->backlight.pwm_level_max) - return -ENODEV; - - panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); - - panel->backlight.pwm_enabled = ctl2 & BLM_PWM_ENABLE; - - return 0; -} - -static int -bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 pwm_ctl, val; - - panel->backlight.controller = dev_priv->vbt.backlight.controller; - - pwm_ctl = intel_de_read(dev_priv, - BXT_BLC_PWM_CTL(panel->backlight.controller)); - - /* Controller 1 uses the utility pin. */ - if (panel->backlight.controller == 1) { - val = intel_de_read(dev_priv, UTIL_PIN_CTL); - panel->backlight.util_pin_active_low = - val & UTIL_PIN_POLARITY; - } - - panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY; - panel->backlight.pwm_level_max = - intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller)); - - if (!panel->backlight.pwm_level_max) - panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); - - if (!panel->backlight.pwm_level_max) - return -ENODEV; - - panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); - - panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE; - - return 0; -} - -static int -cnp_setup_backlight(struct intel_connector *connector, enum pipe unused) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - u32 pwm_ctl; - - /* - * CNP has the BXT implementation of backlight, but with only one - * controller. TODO: ICP has multiple controllers but we only use - * controller 0 for now. - */ - panel->backlight.controller = 0; - - pwm_ctl = intel_de_read(dev_priv, - BXT_BLC_PWM_CTL(panel->backlight.controller)); - - panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY; - panel->backlight.pwm_level_max = - intel_de_read(dev_priv, BXT_BLC_PWM_FREQ(panel->backlight.controller)); - - if (!panel->backlight.pwm_level_max) - panel->backlight.pwm_level_max = get_backlight_max_vbt(connector); - - if (!panel->backlight.pwm_level_max) - return -ENODEV; - - panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); - - panel->backlight.pwm_enabled = pwm_ctl & BXT_BLC_PWM_ENABLE; - - return 0; -} - -static int ext_pwm_setup_backlight(struct intel_connector *connector, - enum pipe pipe) -{ - struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_panel *panel = &connector->panel; - const char *desc; - u32 level; - - /* Get the right PWM chip for DSI backlight according to VBT */ - if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) { - panel->backlight.pwm = pwm_get(dev->dev, "pwm_pmic_backlight"); - desc = "PMIC"; - } else { - panel->backlight.pwm = pwm_get(dev->dev, "pwm_soc_backlight"); - desc = "SoC"; - } - - if (IS_ERR(panel->backlight.pwm)) { - drm_err(&dev_priv->drm, "Failed to get the %s PWM chip\n", - desc); - panel->backlight.pwm = NULL; - return -ENODEV; - } - - panel->backlight.pwm_level_max = 100; /* 100% */ - panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); - - if (pwm_is_enabled(panel->backlight.pwm)) { - /* PWM is already enabled, use existing settings */ - pwm_get_state(panel->backlight.pwm, &panel->backlight.pwm_state); - - level = pwm_get_relative_duty_cycle(&panel->backlight.pwm_state, - 100); - level = intel_panel_invert_pwm_level(connector, level); - panel->backlight.pwm_enabled = true; - - drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n", - NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period, - get_vbt_pwm_freq(dev_priv), level); - } else { - /* Set period from VBT frequency, leave other settings at 0. */ - panel->backlight.pwm_state.period = - NSEC_PER_SEC / get_vbt_pwm_freq(dev_priv); - } - - drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n", - desc); - return 0; -} - -static void intel_pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct intel_panel *panel = &connector->panel; - - panel->backlight.pwm_funcs->set(conn_state, - intel_panel_invert_pwm_level(connector, level)); -} - -static u32 intel_pwm_get_backlight(struct intel_connector *connector, enum pipe pipe) -{ - struct intel_panel *panel = &connector->panel; - - return intel_panel_invert_pwm_level(connector, - panel->backlight.pwm_funcs->get(connector, pipe)); -} - -static void intel_pwm_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct intel_panel *panel = &connector->panel; - - panel->backlight.pwm_funcs->enable(crtc_state, conn_state, - intel_panel_invert_pwm_level(connector, level)); -} - -static void intel_pwm_disable_backlight(const struct drm_connector_state *conn_state, u32 level) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct intel_panel *panel = &connector->panel; - - panel->backlight.pwm_funcs->disable(conn_state, - intel_panel_invert_pwm_level(connector, level)); -} - -static int intel_pwm_setup_backlight(struct intel_connector *connector, enum pipe pipe) -{ - struct intel_panel *panel = &connector->panel; - int ret = panel->backlight.pwm_funcs->setup(connector, pipe); - - if (ret < 0) - return ret; - - panel->backlight.min = panel->backlight.pwm_level_min; - panel->backlight.max = panel->backlight.pwm_level_max; - panel->backlight.level = intel_pwm_get_backlight(connector, pipe); - panel->backlight.enabled = panel->backlight.pwm_enabled; - - return 0; -} - -void intel_panel_update_backlight(struct intel_atomic_state *state, - struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) -{ - struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct intel_panel *panel = &connector->panel; - - if (!panel->backlight.present) - return; - - mutex_lock(&dev_priv->backlight_lock); - if (!panel->backlight.enabled) - __intel_panel_enable_backlight(crtc_state, conn_state); - - mutex_unlock(&dev_priv->backlight_lock); -} - -int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = to_i915(connector->dev); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_panel *panel = &intel_connector->panel; - int ret; - - if (!dev_priv->vbt.backlight.present) { - if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) { - drm_dbg_kms(&dev_priv->drm, - "no backlight present per VBT, but present per quirk\n"); - } else { - drm_dbg_kms(&dev_priv->drm, - "no backlight present per VBT\n"); - return 0; - } - } - - /* ensure intel_panel has been initialized first */ - if (drm_WARN_ON(&dev_priv->drm, !panel->backlight.funcs)) - return -ENODEV; - - /* set level and max in panel struct */ - mutex_lock(&dev_priv->backlight_lock); - ret = panel->backlight.funcs->setup(intel_connector, pipe); - mutex_unlock(&dev_priv->backlight_lock); - - if (ret) { - drm_dbg_kms(&dev_priv->drm, - "failed to setup backlight for connector %s\n", - connector->name); - return ret; - } - - panel->backlight.present = true; - - drm_dbg_kms(&dev_priv->drm, - "Connector %s backlight initialized, %s, brightness %u/%u\n", - connector->name, - enableddisabled(panel->backlight.enabled), - panel->backlight.level, panel->backlight.max); - - return 0; -} - -static void intel_panel_destroy_backlight(struct intel_panel *panel) -{ - /* dispose of the pwm */ - if (panel->backlight.pwm) - pwm_put(panel->backlight.pwm); - - panel->backlight.present = false; -} - -static const struct intel_panel_bl_funcs bxt_pwm_funcs = { - .setup = bxt_setup_backlight, - .enable = bxt_enable_backlight, - .disable = bxt_disable_backlight, - .set = bxt_set_backlight, - .get = bxt_get_backlight, - .hz_to_pwm = bxt_hz_to_pwm, -}; - -static const struct intel_panel_bl_funcs cnp_pwm_funcs = { - .setup = cnp_setup_backlight, - .enable = cnp_enable_backlight, - .disable = cnp_disable_backlight, - .set = bxt_set_backlight, - .get = bxt_get_backlight, - .hz_to_pwm = cnp_hz_to_pwm, -}; - -static const struct intel_panel_bl_funcs lpt_pwm_funcs = { - .setup = lpt_setup_backlight, - .enable = lpt_enable_backlight, - .disable = lpt_disable_backlight, - .set = lpt_set_backlight, - .get = lpt_get_backlight, - .hz_to_pwm = lpt_hz_to_pwm, -}; - -static const struct intel_panel_bl_funcs spt_pwm_funcs = { - .setup = lpt_setup_backlight, - .enable = lpt_enable_backlight, - .disable = lpt_disable_backlight, - .set = lpt_set_backlight, - .get = lpt_get_backlight, - .hz_to_pwm = spt_hz_to_pwm, -}; - -static const struct intel_panel_bl_funcs pch_pwm_funcs = { - .setup = pch_setup_backlight, - .enable = pch_enable_backlight, - .disable = pch_disable_backlight, - .set = pch_set_backlight, - .get = pch_get_backlight, - .hz_to_pwm = pch_hz_to_pwm, -}; - -static const struct intel_panel_bl_funcs ext_pwm_funcs = { - .setup = ext_pwm_setup_backlight, - .enable = ext_pwm_enable_backlight, - .disable = ext_pwm_disable_backlight, - .set = ext_pwm_set_backlight, - .get = ext_pwm_get_backlight, -}; - -static const struct intel_panel_bl_funcs vlv_pwm_funcs = { - .setup = vlv_setup_backlight, - .enable = vlv_enable_backlight, - .disable = vlv_disable_backlight, - .set = vlv_set_backlight, - .get = vlv_get_backlight, - .hz_to_pwm = vlv_hz_to_pwm, -}; - -static const struct intel_panel_bl_funcs i965_pwm_funcs = { - .setup = i965_setup_backlight, - .enable = i965_enable_backlight, - .disable = i965_disable_backlight, - .set = i9xx_set_backlight, - .get = i9xx_get_backlight, - .hz_to_pwm = i965_hz_to_pwm, -}; - -static const struct intel_panel_bl_funcs i9xx_pwm_funcs = { - .setup = i9xx_setup_backlight, - .enable = i9xx_enable_backlight, - .disable = i9xx_disable_backlight, - .set = i9xx_set_backlight, - .get = i9xx_get_backlight, - .hz_to_pwm = i9xx_hz_to_pwm, -}; - -static const struct intel_panel_bl_funcs pwm_bl_funcs = { - .setup = intel_pwm_setup_backlight, - .enable = intel_pwm_enable_backlight, - .disable = intel_pwm_disable_backlight, - .set = intel_pwm_set_backlight, - .get = intel_pwm_get_backlight, -}; - -/* Set up chip specific backlight functions */ -static void -intel_panel_init_backlight_funcs(struct intel_panel *panel) -{ - struct intel_connector *connector = - container_of(panel, struct intel_connector, panel); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - - if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI && - intel_dsi_dcs_init_backlight_funcs(connector) == 0) - return; - - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { - panel->backlight.pwm_funcs = &bxt_pwm_funcs; - } else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) { - panel->backlight.pwm_funcs = &cnp_pwm_funcs; - } else if (INTEL_PCH_TYPE(dev_priv) >= PCH_LPT) { - if (HAS_PCH_LPT(dev_priv)) - panel->backlight.pwm_funcs = &lpt_pwm_funcs; - else - panel->backlight.pwm_funcs = &spt_pwm_funcs; - } else if (HAS_PCH_SPLIT(dev_priv)) { - panel->backlight.pwm_funcs = &pch_pwm_funcs; - } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) { - panel->backlight.pwm_funcs = &ext_pwm_funcs; - } else { - panel->backlight.pwm_funcs = &vlv_pwm_funcs; - } - } else if (DISPLAY_VER(dev_priv) == 4) { - panel->backlight.pwm_funcs = &i965_pwm_funcs; - } else { - panel->backlight.pwm_funcs = &i9xx_pwm_funcs; - } - - if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP && - intel_dp_aux_init_backlight_funcs(connector) == 0) - return; - - /* We're using a standard PWM backlight interface */ - panel->backlight.funcs = &pwm_bl_funcs; -} - enum drm_connector_status intel_panel_detect(struct drm_connector *connector, bool force) { diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_panel.h index d638c2b47c92..19ffa6175cab 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.h +++ b/drivers/gpu/drm/i915/display/intel_panel.h @@ -8,15 +8,13 @@ #include -#include "intel_display.h" - +enum drm_connector_status; struct drm_connector; struct drm_connector_state; struct drm_display_mode; +struct drm_i915_private; struct intel_connector; -struct intel_crtc; struct intel_crtc_state; -struct intel_encoder; struct intel_panel; int intel_panel_init(struct intel_panel *panel, @@ -32,17 +30,6 @@ int intel_pch_panel_fitting(struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); int intel_gmch_panel_fitting(struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); -void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, - u32 level, u32 max); -int intel_panel_setup_backlight(struct drm_connector *connector, - enum pipe pipe); -void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); -void intel_panel_update_backlight(struct intel_atomic_state *state, - struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); -void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state); struct drm_display_mode * intel_panel_edid_downclock_mode(struct intel_connector *connector, const struct drm_display_mode *fixed_mode); @@ -50,22 +37,5 @@ struct drm_display_mode * intel_panel_edid_fixed_mode(struct intel_connector *connector); struct drm_display_mode * intel_panel_vbt_fixed_mode(struct intel_connector *connector); -void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 level); -u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 level); -u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 level); -u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val); - -#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) -int intel_backlight_device_register(struct intel_connector *connector); -void intel_backlight_device_unregister(struct intel_connector *connector); -#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */ -static inline int intel_backlight_device_register(struct intel_connector *connector) -{ - return 0; -} -static inline void intel_backlight_device_unregister(struct intel_connector *connector) -{ -} -#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ #endif /* __INTEL_PANEL_H__ */ diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index 0ee4ff341e25..b27738df447d 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -32,6 +32,7 @@ #include "i915_drv.h" #include "intel_atomic.h" +#include "intel_backlight.h" #include "intel_connector.h" #include "intel_crtc.h" #include "intel_de.h" -- cgit v1.2.3 From c0a52f8bd755732284d5c08aefe0d3dd3291f64a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Aug 2021 14:06:51 +0300 Subject: drm/i915/backlight: mass rename functions to have intel_backlight_ prefix Follow the usual naming conventions. As a drive-by cleanup, also pass intel_connector instead of drm_connector to intel_backlight_setup(). No functional changes. Cc: Lyude Paul Reviewed-by: Lyude Paul Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/ea1c22370210abdd4f5547af73c71b902061ea50.1629888677.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/g4x_dp.c | 2 +- drivers/gpu/drm/i915/display/icl_dsi.c | 8 +- drivers/gpu/drm/i915/display/intel_backlight.c | 94 +++++++++++----------- drivers/gpu/drm/i915/display/intel_backlight.h | 37 ++++----- drivers/gpu/drm/i915/display/intel_ddi.c | 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 6 +- .../gpu/drm/i915/display/intel_dp_aux_backlight.c | 10 +-- drivers/gpu/drm/i915/display/intel_lvds.c | 10 +-- drivers/gpu/drm/i915/display/intel_opregion.c | 2 +- drivers/gpu/drm/i915/display/intel_panel.c | 4 +- drivers/gpu/drm/i915/display/vlv_dsi.c | 8 +- 11 files changed, 91 insertions(+), 92 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 29c0eca647e3..9577f6843f79 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -1334,7 +1334,7 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv, intel_encoder->get_config = intel_dp_get_config; intel_encoder->sync_state = intel_dp_sync_state; intel_encoder->initial_fastset_check = intel_dp_initial_fastset_check; - intel_encoder->update_pipe = intel_panel_update_backlight; + intel_encoder->update_pipe = intel_backlight_update; intel_encoder->suspend = intel_dp_encoder_suspend; intel_encoder->shutdown = intel_dp_encoder_shutdown; if (IS_CHERRYVIEW(dev_priv)) { diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 9aaa9f2ee601..6de268c98884 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1288,7 +1288,7 @@ static void gen11_dsi_enable(struct intel_atomic_state *state, gen11_dsi_enable_transcoder(encoder); /* step7: enable backlight */ - intel_panel_enable_backlight(crtc_state, conn_state); + intel_backlight_enable(crtc_state, conn_state); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON); intel_crtc_vblank_on(crtc_state); @@ -1441,7 +1441,7 @@ static void gen11_dsi_disable(struct intel_atomic_state *state, /* step1: turn off backlight */ intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); - intel_panel_disable_backlight(old_conn_state); + intel_backlight_disable(old_conn_state); /* step2d,e: disable transcoder and wait */ gen11_dsi_disable_transcoder(encoder); @@ -2009,7 +2009,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) encoder->port = port; encoder->get_config = gen11_dsi_get_config; encoder->sync_state = gen11_dsi_sync_state; - encoder->update_pipe = intel_panel_update_backlight; + encoder->update_pipe = intel_backlight_update; 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; @@ -2043,7 +2043,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) } intel_panel_init(&intel_connector->panel, fixed_mode, NULL); - intel_panel_setup_backlight(connector, INVALID_PIPE); + intel_backlight_setup(intel_connector, INVALID_PIPE); if (dev_priv->vbt.dsi.config->dual_link) intel_dsi->ports = BIT(PORT_A) | BIT(PORT_B); diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index 4b0086ee4851..9523411cddd8 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -72,7 +72,7 @@ static u32 scale_hw_to_user(struct intel_connector *connector, 0, user_max); } -u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 val) +u32 intel_backlight_invert_pwm_level(struct intel_connector *connector, u32 val) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; @@ -90,7 +90,7 @@ u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 val) return val; } -void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 val) +void intel_backlight_set_pwm_level(const struct drm_connector_state *conn_state, u32 val) { struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *i915 = to_i915(connector->base.dev); @@ -100,7 +100,7 @@ void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 panel->backlight.pwm_funcs->set(conn_state, val); } -u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 val) +u32 intel_backlight_level_to_pwm(struct intel_connector *connector, u32 val) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; @@ -111,10 +111,10 @@ u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 va val = scale(val, panel->backlight.min, panel->backlight.max, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max); - return intel_panel_invert_pwm_level(connector, val); + return intel_backlight_invert_pwm_level(connector, val); } -u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val) +u32 intel_backlight_level_from_pwm(struct intel_connector *connector, u32 val) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; @@ -283,8 +283,8 @@ intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, /* set backlight brightness to level in range [0..max], assuming hw min is * respected. */ -void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, - u32 user_level, u32 user_max) +void intel_backlight_set_acpi(const struct drm_connector_state *conn_state, + u32 user_level, u32 user_max) { struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); @@ -325,7 +325,7 @@ static void lpt_disable_backlight(const struct drm_connector_state *old_conn_sta struct drm_i915_private *dev_priv = to_i915(connector->base.dev); u32 tmp; - intel_panel_set_pwm_level(old_conn_state, level); + intel_backlight_set_pwm_level(old_conn_state, level); /* * Although we don't support or enable CPU PWM with LPT/SPT based @@ -353,7 +353,7 @@ static void pch_disable_backlight(const struct drm_connector_state *old_conn_sta struct drm_i915_private *dev_priv = to_i915(connector->base.dev); u32 tmp; - intel_panel_set_pwm_level(old_conn_state, val); + intel_backlight_set_pwm_level(old_conn_state, val); tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2); intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); @@ -364,7 +364,7 @@ static void pch_disable_backlight(const struct drm_connector_state *old_conn_sta static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) { - intel_panel_set_pwm_level(old_conn_state, val); + intel_backlight_set_pwm_level(old_conn_state, val); } static void i965_disable_backlight(const struct drm_connector_state *old_conn_state, u32 val) @@ -372,7 +372,7 @@ static void i965_disable_backlight(const struct drm_connector_state *old_conn_st struct drm_i915_private *dev_priv = to_i915(old_conn_state->connector->dev); u32 tmp; - intel_panel_set_pwm_level(old_conn_state, val); + intel_backlight_set_pwm_level(old_conn_state, val); tmp = intel_de_read(dev_priv, BLC_PWM_CTL2); intel_de_write(dev_priv, BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE); @@ -385,7 +385,7 @@ static void vlv_disable_backlight(const struct drm_connector_state *old_conn_sta enum pipe pipe = to_intel_crtc(old_conn_state->crtc)->pipe; u32 tmp; - intel_panel_set_pwm_level(old_conn_state, val); + intel_backlight_set_pwm_level(old_conn_state, val); tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)); intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe), @@ -399,7 +399,7 @@ static void bxt_disable_backlight(const struct drm_connector_state *old_conn_sta struct intel_panel *panel = &connector->panel; u32 tmp; - intel_panel_set_pwm_level(old_conn_state, val); + intel_backlight_set_pwm_level(old_conn_state, val); tmp = intel_de_read(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)); @@ -420,7 +420,7 @@ static void cnp_disable_backlight(const struct drm_connector_state *old_conn_sta struct intel_panel *panel = &connector->panel; u32 tmp; - intel_panel_set_pwm_level(old_conn_state, val); + intel_backlight_set_pwm_level(old_conn_state, val); tmp = intel_de_read(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)); @@ -437,7 +437,7 @@ static void ext_pwm_disable_backlight(const struct drm_connector_state *old_conn pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); } -void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state) +void intel_backlight_disable(const struct drm_connector_state *old_conn_state) { struct intel_connector *connector = to_intel_connector(old_conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); @@ -516,7 +516,7 @@ static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state, pch_ctl1 | BLM_PCH_PWM_ENABLE); /* This won't stick until the above enable. */ - intel_panel_set_pwm_level(conn_state, level); + intel_backlight_set_pwm_level(conn_state, level); } static void pch_enable_backlight(const struct intel_crtc_state *crtc_state, @@ -551,7 +551,7 @@ static void pch_enable_backlight(const struct intel_crtc_state *crtc_state, intel_de_write(dev_priv, BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE); /* This won't stick until the above enable. */ - intel_panel_set_pwm_level(conn_state, level); + intel_backlight_set_pwm_level(conn_state, level); pch_ctl2 = panel->backlight.pwm_level_max << 16; intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, pch_ctl2); @@ -594,7 +594,7 @@ static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state, intel_de_posting_read(dev_priv, BLC_PWM_CTL); /* XXX: combine this into above write? */ - intel_panel_set_pwm_level(conn_state, level); + intel_backlight_set_pwm_level(conn_state, level); /* * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is @@ -637,7 +637,7 @@ static void i965_enable_backlight(const struct intel_crtc_state *crtc_state, intel_de_posting_read(dev_priv, BLC_PWM_CTL2); intel_de_write(dev_priv, BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE); - intel_panel_set_pwm_level(conn_state, level); + intel_backlight_set_pwm_level(conn_state, level); } static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state, @@ -660,7 +660,7 @@ static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state, intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe), ctl); /* XXX: combine this into above write? */ - intel_panel_set_pwm_level(conn_state, level); + intel_backlight_set_pwm_level(conn_state, level); ctl2 = 0; if (panel->backlight.active_low_pwm) @@ -711,7 +711,7 @@ static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state, BXT_BLC_PWM_FREQ(panel->backlight.controller), panel->backlight.pwm_level_max); - intel_panel_set_pwm_level(conn_state, level); + intel_backlight_set_pwm_level(conn_state, level); pwm_ctl = 0; if (panel->backlight.active_low_pwm) @@ -747,7 +747,7 @@ static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state, BXT_BLC_PWM_FREQ(panel->backlight.controller), panel->backlight.pwm_level_max); - intel_panel_set_pwm_level(conn_state, level); + intel_backlight_set_pwm_level(conn_state, level); pwm_ctl = 0; if (panel->backlight.active_low_pwm) @@ -772,8 +772,8 @@ static void ext_pwm_enable_backlight(const struct intel_crtc_state *crtc_state, pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state); } -static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) +static void __intel_backlight_enable(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { struct intel_connector *connector = to_intel_connector(conn_state->connector); struct intel_panel *panel = &connector->panel; @@ -795,8 +795,8 @@ static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_s panel->backlight.device->props.power = FB_BLANK_UNBLANK; } -void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) +void intel_backlight_enable(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); @@ -810,7 +810,7 @@ void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, mutex_lock(&dev_priv->backlight_lock); - __intel_panel_enable_backlight(crtc_state, conn_state); + __intel_backlight_enable(crtc_state, conn_state); mutex_unlock(&dev_priv->backlight_lock); } @@ -1335,7 +1335,7 @@ static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unu panel->backlight.pwm_level_min = get_backlight_min_vbt(connector); val = i9xx_get_backlight(connector, unused); - val = intel_panel_invert_pwm_level(connector, val); + val = intel_backlight_invert_pwm_level(connector, val); val = clamp(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max); panel->backlight.pwm_enabled = val != 0; @@ -1504,7 +1504,7 @@ static int ext_pwm_setup_backlight(struct intel_connector *connector, level = pwm_get_relative_duty_cycle(&panel->backlight.pwm_state, 100); - level = intel_panel_invert_pwm_level(connector, level); + level = intel_backlight_invert_pwm_level(connector, level); panel->backlight.pwm_enabled = true; drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n", @@ -1527,14 +1527,14 @@ static void intel_pwm_set_backlight(const struct drm_connector_state *conn_state struct intel_panel *panel = &connector->panel; panel->backlight.pwm_funcs->set(conn_state, - intel_panel_invert_pwm_level(connector, level)); + intel_backlight_invert_pwm_level(connector, level)); } static u32 intel_pwm_get_backlight(struct intel_connector *connector, enum pipe pipe) { struct intel_panel *panel = &connector->panel; - return intel_panel_invert_pwm_level(connector, + return intel_backlight_invert_pwm_level(connector, panel->backlight.pwm_funcs->get(connector, pipe)); } @@ -1545,7 +1545,7 @@ static void intel_pwm_enable_backlight(const struct intel_crtc_state *crtc_state struct intel_panel *panel = &connector->panel; panel->backlight.pwm_funcs->enable(crtc_state, conn_state, - intel_panel_invert_pwm_level(connector, level)); + intel_backlight_invert_pwm_level(connector, level)); } static void intel_pwm_disable_backlight(const struct drm_connector_state *conn_state, u32 level) @@ -1554,7 +1554,7 @@ static void intel_pwm_disable_backlight(const struct drm_connector_state *conn_s struct intel_panel *panel = &connector->panel; panel->backlight.pwm_funcs->disable(conn_state, - intel_panel_invert_pwm_level(connector, level)); + intel_backlight_invert_pwm_level(connector, level)); } static int intel_pwm_setup_backlight(struct intel_connector *connector, enum pipe pipe) @@ -1573,10 +1573,10 @@ static int intel_pwm_setup_backlight(struct intel_connector *connector, enum pip return 0; } -void intel_panel_update_backlight(struct intel_atomic_state *state, - struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) +void intel_backlight_update(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(connector->base.dev); @@ -1587,16 +1587,15 @@ void intel_panel_update_backlight(struct intel_atomic_state *state, mutex_lock(&dev_priv->backlight_lock); if (!panel->backlight.enabled) - __intel_panel_enable_backlight(crtc_state, conn_state); + __intel_backlight_enable(crtc_state, conn_state); mutex_unlock(&dev_priv->backlight_lock); } -int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) +int intel_backlight_setup(struct intel_connector *connector, enum pipe pipe) { - struct drm_i915_private *dev_priv = to_i915(connector->dev); - struct intel_connector *intel_connector = to_intel_connector(connector); - struct intel_panel *panel = &intel_connector->panel; + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_panel *panel = &connector->panel; int ret; if (!dev_priv->vbt.backlight.present) { @@ -1616,13 +1615,13 @@ int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) /* set level and max in panel struct */ mutex_lock(&dev_priv->backlight_lock); - ret = panel->backlight.funcs->setup(intel_connector, pipe); + ret = panel->backlight.funcs->setup(connector, pipe); mutex_unlock(&dev_priv->backlight_lock); if (ret) { drm_dbg_kms(&dev_priv->drm, "failed to setup backlight for connector %s\n", - connector->name); + connector->base.name); return ret; } @@ -1630,14 +1629,14 @@ int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) drm_dbg_kms(&dev_priv->drm, "Connector %s backlight initialized, %s, brightness %u/%u\n", - connector->name, + connector->base.name, enableddisabled(panel->backlight.enabled), panel->backlight.level, panel->backlight.max); return 0; } -void intel_panel_destroy_backlight(struct intel_panel *panel) +void intel_backlight_destroy(struct intel_panel *panel) { /* dispose of the pwm */ if (panel->backlight.pwm) @@ -1735,8 +1734,7 @@ static const struct intel_panel_bl_funcs pwm_bl_funcs = { }; /* Set up chip specific backlight functions */ -void -intel_panel_init_backlight_funcs(struct intel_panel *panel) +void intel_backlight_init_funcs(struct intel_panel *panel) { struct intel_connector *connector = container_of(panel, struct intel_connector, panel); diff --git a/drivers/gpu/drm/i915/display/intel_backlight.h b/drivers/gpu/drm/i915/display/intel_backlight.h index 282020cb47d5..339643f63897 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.h +++ b/drivers/gpu/drm/i915/display/intel_backlight.h @@ -8,7 +8,6 @@ #include -struct drm_connector; struct drm_connector_state; struct intel_atomic_state; struct intel_connector; @@ -17,23 +16,25 @@ struct intel_encoder; struct intel_panel; enum pipe; -void intel_panel_init_backlight_funcs(struct intel_panel *panel); -void intel_panel_destroy_backlight(struct intel_panel *panel); -void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, - u32 level, u32 max); -int intel_panel_setup_backlight(struct drm_connector *connector, - enum pipe pipe); -void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); -void intel_panel_update_backlight(struct intel_atomic_state *state, - struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); -void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state); -void intel_panel_set_pwm_level(const struct drm_connector_state *conn_state, u32 level); -u32 intel_panel_invert_pwm_level(struct intel_connector *connector, u32 level); -u32 intel_panel_backlight_level_to_pwm(struct intel_connector *connector, u32 level); -u32 intel_panel_backlight_level_from_pwm(struct intel_connector *connector, u32 val); +void intel_backlight_init_funcs(struct intel_panel *panel); +int intel_backlight_setup(struct intel_connector *connector, enum pipe pipe); +void intel_backlight_destroy(struct intel_panel *panel); + +void intel_backlight_enable(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +void intel_backlight_update(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +void intel_backlight_disable(const struct drm_connector_state *old_conn_state); + +void intel_backlight_set_acpi(const struct drm_connector_state *conn_state, + u32 level, u32 max); +void intel_backlight_set_pwm_level(const struct drm_connector_state *conn_state, + u32 level); +u32 intel_backlight_invert_pwm_level(struct intel_connector *connector, u32 level); +u32 intel_backlight_level_to_pwm(struct intel_connector *connector, u32 level); +u32 intel_backlight_level_from_pwm(struct intel_connector *connector, u32 val); #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) int intel_backlight_device_register(struct intel_connector *connector); diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index dbd38beece3f..837021408b83 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3234,7 +3234,7 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state, intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); intel_edp_drrs_update(intel_dp, crtc_state); - intel_panel_update_backlight(state, encoder, crtc_state, conn_state); + intel_backlight_update(state, encoder, crtc_state, conn_state); } void intel_ddi_update_pipe(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 71be9f92133e..d43e2850233f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1852,7 +1852,7 @@ void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state, drm_dbg_kms(&i915->drm, "\n"); - intel_panel_enable_backlight(crtc_state, conn_state); + intel_backlight_enable(crtc_state, conn_state); intel_pps_backlight_on(intel_dp); } @@ -1868,7 +1868,7 @@ void intel_edp_backlight_off(const struct drm_connector_state *old_conn_state) drm_dbg_kms(&i915->drm, "\n"); intel_pps_backlight_off(intel_dp); - intel_panel_disable_backlight(old_conn_state); + intel_backlight_disable(old_conn_state); } static bool downstream_hpd_needs_d0(struct intel_dp *intel_dp) @@ -5303,7 +5303,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); if (!(dev_priv->quirks & QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK)) intel_connector->panel.backlight.power = intel_pps_backlight_power; - intel_panel_setup_backlight(connector, pipe); + intel_backlight_setup(intel_connector, pipe); if (fixed_mode) { drm_connector_set_panel_orientation_with_quirk(connector, diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index d026b9420403..569d17b4d00f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -146,7 +146,7 @@ intel_dp_aux_hdr_get_backlight(struct intel_connector *connector, enum pipe pipe if (!panel->backlight.edp.intel.sdr_uses_aux) { u32 pwm_level = panel->backlight.pwm_funcs->get(connector, pipe); - return intel_panel_backlight_level_from_pwm(connector, pwm_level); + return intel_backlight_level_from_pwm(connector, pwm_level); } /* Assume 100% brightness if backlight controls aren't enabled yet */ @@ -187,9 +187,9 @@ intel_dp_aux_hdr_set_backlight(const struct drm_connector_state *conn_state, u32 if (panel->backlight.edp.intel.sdr_uses_aux) { intel_dp_aux_hdr_set_aux_backlight(conn_state, level); } else { - const u32 pwm_level = intel_panel_backlight_level_to_pwm(connector, level); + const u32 pwm_level = intel_backlight_level_to_pwm(connector, level); - intel_panel_set_pwm_level(conn_state, pwm_level); + intel_backlight_set_pwm_level(conn_state, pwm_level); } } @@ -215,7 +215,7 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state, ctrl |= INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE; intel_dp_aux_hdr_set_aux_backlight(conn_state, level); } else { - u32 pwm_level = intel_panel_backlight_level_to_pwm(connector, level); + u32 pwm_level = intel_backlight_level_to_pwm(connector, level); panel->backlight.pwm_funcs->enable(crtc_state, conn_state, pwm_level); @@ -238,7 +238,7 @@ intel_dp_aux_hdr_disable_backlight(const struct drm_connector_state *conn_state, return; /* Note we want the actual pwm_level to be 0, regardless of pwm_min */ - panel->backlight.pwm_funcs->disable(conn_state, intel_panel_invert_pwm_level(connector, 0)); + panel->backlight.pwm_funcs->disable(conn_state, intel_backlight_invert_pwm_level(connector, 0)); } static int diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 8f5741ebd58d..df8238fefdd8 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -324,7 +324,7 @@ static void intel_enable_lvds(struct intel_atomic_state *state, drm_err(&dev_priv->drm, "timed out waiting for panel to power on\n"); - intel_panel_enable_backlight(pipe_config, conn_state); + intel_backlight_enable(pipe_config, conn_state); } static void intel_disable_lvds(struct intel_atomic_state *state, @@ -352,7 +352,7 @@ static void gmch_disable_lvds(struct intel_atomic_state *state, const struct drm_connector_state *old_conn_state) { - intel_panel_disable_backlight(old_conn_state); + intel_backlight_disable(old_conn_state); intel_disable_lvds(state, encoder, old_crtc_state, old_conn_state); } @@ -362,7 +362,7 @@ static void pch_disable_lvds(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - intel_panel_disable_backlight(old_conn_state); + intel_backlight_disable(old_conn_state); } static void pch_post_disable_lvds(struct intel_atomic_state *state, @@ -907,7 +907,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) } intel_encoder->get_hw_state = intel_lvds_get_hw_state; intel_encoder->get_config = intel_lvds_get_config; - intel_encoder->update_pipe = intel_panel_update_backlight; + intel_encoder->update_pipe = intel_backlight_update; intel_encoder->shutdown = intel_lvds_shutdown; intel_connector->get_hw_state = intel_connector_get_hw_state; @@ -1000,7 +1000,7 @@ out: mutex_unlock(&dev->mode_config.mutex); intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); - intel_panel_setup_backlight(connector, INVALID_PIPE); + intel_backlight_setup(intel_connector, INVALID_PIPE); lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder); drm_dbg_kms(&dev_priv->drm, "detected %s-link lvds configuration\n", diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index 3a7a8598d1ec..0065111593a6 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -449,7 +449,7 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp) bclp); drm_connector_list_iter_begin(dev, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) - intel_panel_set_backlight_acpi(connector->base.state, bclp, 255); + intel_backlight_set_acpi(connector->base.state, bclp, 255); drm_connector_list_iter_end(&conn_iter); asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID; diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index 083eb774c4bb..fb5684ddbc19 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -475,7 +475,7 @@ int intel_panel_init(struct intel_panel *panel, struct drm_display_mode *fixed_mode, struct drm_display_mode *downclock_mode) { - intel_panel_init_backlight_funcs(panel); + intel_backlight_init_funcs(panel); panel->fixed_mode = fixed_mode; panel->downclock_mode = downclock_mode; @@ -488,7 +488,7 @@ void intel_panel_fini(struct intel_panel *panel) struct intel_connector *intel_connector = container_of(panel, struct intel_connector, panel); - intel_panel_destroy_backlight(panel); + intel_backlight_destroy(panel); if (panel->fixed_mode) drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode); diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index b27738df447d..76910c4b20e0 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -884,7 +884,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, intel_dsi_port_enable(encoder, pipe_config); } - intel_panel_enable_backlight(pipe_config, conn_state); + intel_backlight_enable(pipe_config, conn_state); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON); } @@ -914,7 +914,7 @@ static void intel_dsi_disable(struct intel_atomic_state *state, drm_dbg_kms(&i915->drm, "\n"); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); - intel_panel_disable_backlight(old_conn_state); + intel_backlight_disable(old_conn_state); /* * According to the spec we should send SHUTDOWN before @@ -1877,7 +1877,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) intel_encoder->post_disable = intel_dsi_post_disable; intel_encoder->get_hw_state = intel_dsi_get_hw_state; intel_encoder->get_config = intel_dsi_get_config; - intel_encoder->update_pipe = intel_panel_update_backlight; + intel_encoder->update_pipe = intel_backlight_update; intel_encoder->shutdown = intel_dsi_shutdown; intel_connector->get_hw_state = intel_connector_get_hw_state; @@ -1965,7 +1965,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) } intel_panel_init(&intel_connector->panel, fixed_mode, NULL); - intel_panel_setup_backlight(connector, INVALID_PIPE); + intel_backlight_setup(intel_connector, INVALID_PIPE); vlv_dsi_add_properties(intel_connector); -- cgit v1.2.3 From 4b93f49d0853ad19b51ca35118ec10b7e65e0532 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Aug 2021 14:06:52 +0300 Subject: drm/i915/panel: mass rename functions to have intel_panel_ prefix Follow the usual naming conventions. Also pull HAS_GMCH() check to intel_panel_fitting(). No functional changes. Cc: Lyude Paul Reviewed-by: Lyude Paul Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/9ff6e42e377bdb0c9349f50d9ea79671059633c7.1629888677.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 4 ++-- drivers/gpu/drm/i915/display/intel_dp.c | 9 +++------ drivers/gpu/drm/i915/display/intel_dvo.c | 2 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 2 +- drivers/gpu/drm/i915/display/intel_lvds.c | 7 ++----- drivers/gpu/drm/i915/display/intel_panel.c | 25 ++++++++++++++++++------- drivers/gpu/drm/i915/display/intel_panel.h | 8 +++----- drivers/gpu/drm/i915/display/vlv_dsi.c | 7 ++----- 8 files changed, 32 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 6de268c98884..5a5e3689d027 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1652,9 +1652,9 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder, int ret; pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; - intel_fixed_panel_mode(fixed_mode, adjusted_mode); + intel_panel_fixed_mode(fixed_mode, adjusted_mode); - ret = intel_pch_panel_fitting(pipe_config, conn_state); + ret = intel_panel_fitting(pipe_config, conn_state); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index d43e2850233f..7f8e8865048f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1738,7 +1738,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, adjusted_mode); if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) { - ret = intel_pch_panel_fitting(pipe_config, conn_state); + ret = intel_panel_fitting(pipe_config, conn_state); if (ret) return ret; } @@ -1751,13 +1751,10 @@ intel_dp_compute_config(struct intel_encoder *encoder, pipe_config->has_audio = intel_conn_state->force_audio == HDMI_AUDIO_ON; if (intel_dp_is_edp(intel_dp) && intel_connector->panel.fixed_mode) { - intel_fixed_panel_mode(intel_connector->panel.fixed_mode, + intel_panel_fixed_mode(intel_connector->panel.fixed_mode, adjusted_mode); - if (HAS_GMCH(dev_priv)) - ret = intel_gmch_panel_fitting(pipe_config, conn_state); - else - ret = intel_pch_panel_fitting(pipe_config, conn_state); + ret = intel_panel_fitting(pipe_config, conn_state); if (ret) return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c index 77419f8c05e9..86c903e9df60 100644 --- a/drivers/gpu/drm/i915/display/intel_dvo.c +++ b/drivers/gpu/drm/i915/display/intel_dvo.c @@ -265,7 +265,7 @@ static int intel_dvo_compute_config(struct intel_encoder *encoder, * of the original mode. */ if (fixed_mode) - intel_fixed_panel_mode(fixed_mode, adjusted_mode); + intel_panel_fixed_mode(fixed_mode, adjusted_mode); if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) return -EINVAL; diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index b04685bb6439..1bc33766ed39 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2210,7 +2210,7 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder, return ret; if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) { - ret = intel_pch_panel_fitting(pipe_config, conn_state); + ret = intel_panel_fitting(pipe_config, conn_state); if (ret) return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index df8238fefdd8..e9fb402708a7 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -442,7 +442,7 @@ static int intel_lvds_compute_config(struct intel_encoder *intel_encoder, * with the panel scaling set up to source from the H/VDisplay * of the original mode. */ - intel_fixed_panel_mode(intel_connector->panel.fixed_mode, + intel_panel_fixed_mode(intel_connector->panel.fixed_mode, adjusted_mode); if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) @@ -451,10 +451,7 @@ static int intel_lvds_compute_config(struct intel_encoder *intel_encoder, if (HAS_PCH_SPLIT(dev_priv)) pipe_config->has_pch_encoder = true; - if (HAS_GMCH(dev_priv)) - ret = intel_gmch_panel_fitting(pipe_config, conn_state); - else - ret = intel_pch_panel_fitting(pipe_config, conn_state); + ret = intel_panel_fitting(pipe_config, conn_state); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index fb5684ddbc19..4804b6b86798 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -45,9 +45,8 @@ bool intel_panel_use_ssc(struct drm_i915_private *i915) && !(i915->quirks & QUIRK_LVDS_SSC_DISABLE); } -void -intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, - struct drm_display_mode *adjusted_mode) +void intel_panel_fixed_mode(const struct drm_display_mode *fixed_mode, + struct drm_display_mode *adjusted_mode) { drm_mode_copy(adjusted_mode, fixed_mode); @@ -179,8 +178,8 @@ intel_panel_vbt_fixed_mode(struct intel_connector *connector) } /* adjusted_mode has been preset to be the panel's fixed mode */ -int intel_pch_panel_fitting(struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) +static int pch_panel_fitting(struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; @@ -385,8 +384,8 @@ static void i9xx_scale_aspect(struct intel_crtc_state *crtc_state, } } -int intel_gmch_panel_fitting(struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) +static int gmch_panel_fitting(struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -460,6 +459,18 @@ out: return 0; } +int intel_panel_fitting(struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + + if (HAS_GMCH(i915)) + return gmch_panel_fitting(crtc_state, conn_state); + else + return pch_panel_fitting(crtc_state, conn_state); +} + enum drm_connector_status intel_panel_detect(struct drm_connector *connector, bool force) { diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_panel.h index 19ffa6175cab..f6af1a98290c 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.h +++ b/drivers/gpu/drm/i915/display/intel_panel.h @@ -24,12 +24,10 @@ void intel_panel_fini(struct intel_panel *panel); enum drm_connector_status intel_panel_detect(struct drm_connector *connector, bool force); bool intel_panel_use_ssc(struct drm_i915_private *i915); -void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, +void intel_panel_fixed_mode(const struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode); -int intel_pch_panel_fitting(struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); -int intel_gmch_panel_fitting(struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); +int intel_panel_fitting(struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); struct drm_display_mode * intel_panel_edid_downclock_mode(struct intel_connector *connector, const struct drm_display_mode *fixed_mode); diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index 76910c4b20e0..b0a2b6b96799 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -279,12 +279,9 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder, pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; if (fixed_mode) { - intel_fixed_panel_mode(fixed_mode, adjusted_mode); + intel_panel_fixed_mode(fixed_mode, adjusted_mode); - if (HAS_GMCH(dev_priv)) - ret = intel_gmch_panel_fitting(pipe_config, conn_state); - else - ret = intel_pch_panel_fitting(pipe_config, conn_state); + ret = intel_panel_fitting(pipe_config, conn_state); if (ret) return ret; } -- cgit v1.2.3 From 3a8e7fd66e8b1ea3ac49a013134d96686af03cf6 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Aug 2021 17:58:11 +0300 Subject: drm/i915/snps: constify struct intel_mpllb_state arrays harder The tables should be const arrays of const pointers, not just arrays of const pointers. Cc: Matt Roper Reviewed-by: Matt Roper Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210825145811.4227-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_snps_phy.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c index d81f71296297..58ec2467ad66 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c @@ -171,7 +171,7 @@ static const struct intel_mpllb_state dg2_dp_hbr3_100 = { REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1), }; -static const struct intel_mpllb_state *dg2_dp_100_tables[] = { +static const struct intel_mpllb_state * const dg2_dp_100_tables[] = { &dg2_dp_rbr_100, &dg2_dp_hbr1_100, &dg2_dp_hbr2_100, @@ -284,7 +284,7 @@ static const struct intel_mpllb_state dg2_dp_hbr3_38_4 = { REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 61440), }; -static const struct intel_mpllb_state *dg2_dp_38_4_tables[] = { +static const struct intel_mpllb_state * const dg2_dp_38_4_tables[] = { &dg2_dp_rbr_38_4, &dg2_dp_hbr1_38_4, &dg2_dp_hbr2_38_4, @@ -421,7 +421,7 @@ static const struct intel_mpllb_state dg2_edp_r432 = { REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 65752), }; -static const struct intel_mpllb_state *dg2_edp_tables[] = { +static const struct intel_mpllb_state * const dg2_edp_tables[] = { &dg2_dp_rbr_100, &dg2_edp_r216, &dg2_edp_r243, @@ -584,7 +584,7 @@ static const struct intel_mpllb_state dg2_hdmi_594 = { REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1), }; -static const struct intel_mpllb_state *dg2_hdmi_tables[] = { +static const struct intel_mpllb_state * const dg2_hdmi_tables[] = { &dg2_hdmi_25_175, &dg2_hdmi_27_0, &dg2_hdmi_74_25, @@ -593,7 +593,7 @@ static const struct intel_mpllb_state *dg2_hdmi_tables[] = { NULL, }; -static const struct intel_mpllb_state ** +static const struct intel_mpllb_state * const * intel_mpllb_tables_get(struct intel_crtc_state *crtc_state, struct intel_encoder *encoder) { @@ -627,7 +627,7 @@ intel_mpllb_tables_get(struct intel_crtc_state *crtc_state, int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state, struct intel_encoder *encoder) { - const struct intel_mpllb_state **tables; + const struct intel_mpllb_state * const *tables; int i; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { @@ -823,7 +823,7 @@ void intel_mpllb_readout_hw_state(struct intel_encoder *encoder, int intel_snps_phy_check_hdmi_link_rate(int clock) { - const struct intel_mpllb_state **tables = dg2_hdmi_tables; + const struct intel_mpllb_state * const *tables = dg2_hdmi_tables; int i; for (i = 0; tables[i]; i++) { -- cgit v1.2.3 From 0ce298258200f11e5c94067b56d45b4d76277bb2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Aug 2021 18:47:48 +0300 Subject: drm/i915/fdi: move intel_update_fdi_pll_freq to intel_fdi.c Move FDI related functions to intel_fdi.c. Rename to have intel_fdi prefix while at it. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/da1609dfce4623f8ec86254aea6c2c8679b6a37f.1629906431.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 18 +----------------- drivers/gpu/drm/i915/display/intel_fdi.c | 16 ++++++++++++++++ drivers/gpu/drm/i915/display/intel_fdi.h | 1 + 3 files changed, 18 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index fe5ad599c218..a25cad621f81 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -11546,22 +11546,6 @@ fail: drm_modeset_acquire_fini(&ctx); } -static void intel_update_fdi_pll_freq(struct drm_i915_private *dev_priv) -{ - if (IS_IRONLAKE(dev_priv)) { - u32 fdi_pll_clk = - intel_de_read(dev_priv, FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK; - - dev_priv->fdi_pll_freq = (fdi_pll_clk + 2) * 10000; - } else if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) { - dev_priv->fdi_pll_freq = 270000; - } else { - return; - } - - drm_dbg(&dev_priv->drm, "FDI PLL freq=%d\n", dev_priv->fdi_pll_freq); -} - static int intel_initial_commit(struct drm_device *dev) { struct drm_atomic_state *state = NULL; @@ -11815,7 +11799,7 @@ int intel_modeset_init_nogem(struct drm_i915_private *i915) intel_plane_possible_crtcs_init(i915); intel_shared_dpll_init(dev); - intel_update_fdi_pll_freq(i915); + intel_fdi_pll_freq_update(i915); intel_update_czclk(i915); intel_modeset_init_hw(i915); diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 13f8ba4c9188..88a78dafd54d 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -95,6 +95,22 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, } } +void intel_fdi_pll_freq_update(struct drm_i915_private *i915) +{ + if (IS_IRONLAKE(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; + } else if (IS_SANDYBRIDGE(i915) || IS_IVYBRIDGE(i915)) { + i915->fdi_pll_freq = 270000; + } else { + return; + } + + drm_dbg(&i915->drm, "FDI PLL freq=%d\n", i915->fdi_pll_freq); +} + int intel_fdi_link_freq(struct drm_i915_private *i915, const struct intel_crtc_state *pipe_config) { diff --git a/drivers/gpu/drm/i915/display/intel_fdi.h b/drivers/gpu/drm/i915/display/intel_fdi.h index 2c8ffd9ceaed..cda9a32c25ba 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.h +++ b/drivers/gpu/drm/i915/display/intel_fdi.h @@ -23,5 +23,6 @@ void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state); void intel_fdi_init_hook(struct drm_i915_private *dev_priv); void hsw_fdi_link_train(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); +void intel_fdi_pll_freq_update(struct drm_i915_private *i915); #endif -- cgit v1.2.3 From f18362cd280d1343fafc1a08df7a4ecfbad0760d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Aug 2021 18:47:49 +0300 Subject: drm/i915/fdi: move fdi bc bifurcation functions to intel_fdi.c Move FDI related functions to intel_fdi.c. Don't bother with renaming as we'll make the functions static shortly. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/fd8afe4876f0b0762a9c69e01762a8dba31349e5.1629906431.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 49 ---------------------------- drivers/gpu/drm/i915/display/intel_fdi.c | 49 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_fdi.h | 1 + 3 files changed, 50 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a25cad621f81..c6552d980d4f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2010,55 +2010,6 @@ static void ilk_pch_transcoder_set_timings(const struct intel_crtc_state *crtc_s intel_de_read(dev_priv, VSYNCSHIFT(cpu_transcoder))); } -static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool enable) -{ - u32 temp; - - temp = intel_de_read(dev_priv, SOUTH_CHICKEN1); - if (!!(temp & FDI_BC_BIFURCATION_SELECT) == enable) - return; - - drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, FDI_RX_CTL(PIPE_B)) & - FDI_RX_ENABLE); - drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, FDI_RX_CTL(PIPE_C)) & - FDI_RX_ENABLE); - - temp &= ~FDI_BC_BIFURCATION_SELECT; - if (enable) - temp |= FDI_BC_BIFURCATION_SELECT; - - drm_dbg_kms(&dev_priv->drm, "%sabling fdi C rx\n", - enable ? "en" : "dis"); - intel_de_write(dev_priv, SOUTH_CHICKEN1, temp); - intel_de_posting_read(dev_priv, SOUTH_CHICKEN1); -} - -static void ivb_update_fdi_bc_bifurcation(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); - - switch (crtc->pipe) { - case PIPE_A: - break; - case PIPE_B: - if (crtc_state->fdi_lanes > 2) - cpt_set_fdi_bc_bifurcation(dev_priv, false); - else - cpt_set_fdi_bc_bifurcation(dev_priv, true); - - break; - case PIPE_C: - cpt_set_fdi_bc_bifurcation(dev_priv, true); - - break; - default: - BUG(); - } -} - /* * Finds the encoder associated with the given CRTC. This can only be * used when we know that the CRTC isn't feeding multiple encoders! diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 88a78dafd54d..f8ffd5c032ae 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -170,6 +170,55 @@ retry: return ret; } +static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool enable) +{ + u32 temp; + + temp = intel_de_read(dev_priv, SOUTH_CHICKEN1); + if (!!(temp & FDI_BC_BIFURCATION_SELECT) == enable) + return; + + drm_WARN_ON(&dev_priv->drm, + intel_de_read(dev_priv, FDI_RX_CTL(PIPE_B)) & + FDI_RX_ENABLE); + drm_WARN_ON(&dev_priv->drm, + intel_de_read(dev_priv, FDI_RX_CTL(PIPE_C)) & + FDI_RX_ENABLE); + + temp &= ~FDI_BC_BIFURCATION_SELECT; + if (enable) + temp |= FDI_BC_BIFURCATION_SELECT; + + drm_dbg_kms(&dev_priv->drm, "%sabling fdi C rx\n", + enable ? "en" : "dis"); + intel_de_write(dev_priv, SOUTH_CHICKEN1, temp); + intel_de_posting_read(dev_priv, SOUTH_CHICKEN1); +} + +void ivb_update_fdi_bc_bifurcation(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); + + switch (crtc->pipe) { + case PIPE_A: + break; + case PIPE_B: + if (crtc_state->fdi_lanes > 2) + cpt_set_fdi_bc_bifurcation(dev_priv, false); + else + cpt_set_fdi_bc_bifurcation(dev_priv, true); + + break; + case PIPE_C: + cpt_set_fdi_bc_bifurcation(dev_priv, true); + + break; + default: + BUG(); + } +} + void intel_fdi_normal_train(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; diff --git a/drivers/gpu/drm/i915/display/intel_fdi.h b/drivers/gpu/drm/i915/display/intel_fdi.h index cda9a32c25ba..135802e4da68 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.h +++ b/drivers/gpu/drm/i915/display/intel_fdi.h @@ -16,6 +16,7 @@ int intel_fdi_link_freq(struct drm_i915_private *i915, const struct intel_crtc_state *pipe_config); int ilk_fdi_compute_config(struct intel_crtc *intel_crtc, struct intel_crtc_state *pipe_config); +void ivb_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_state); void intel_fdi_normal_train(struct intel_crtc *crtc); void ilk_fdi_disable(struct intel_crtc *crtc); void ilk_fdi_pll_disable(struct intel_crtc *intel_crtc); -- cgit v1.2.3 From 12b2c3016d68b649e5d67530655c505bed7948aa Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Aug 2021 18:47:50 +0300 Subject: drm/i915/fdi: move more FDI stuff to FDI link train hooks Accept slight duplication in the fdi link train hooks in exchange for simplification in ilk_pch_enable(). This lets us make ivb_update_fdi_bc_bifurcation() static again, now in intel_fdi.c. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/7984e670c6bb092d213d90f838d526d594d4a690.1629906431.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 8 -------- drivers/gpu/drm/i915/display/intel_fdi.c | 25 ++++++++++++++++++++++++- drivers/gpu/drm/i915/display/intel_fdi.h | 1 - 3 files changed, 24 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index c6552d980d4f..b907c43a115c 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2059,14 +2059,6 @@ static void ilk_pch_enable(const struct intel_atomic_state *state, assert_pch_transcoder_disabled(dev_priv, pipe); - if (IS_IVYBRIDGE(dev_priv)) - ivb_update_fdi_bc_bifurcation(crtc_state); - - /* Write the TU size bits before fdi link training, so that error - * detection works. */ - intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe), - intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK); - /* For PCH output, training FDI link */ dev_priv->display.fdi_link_train(crtc, crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index f8ffd5c032ae..f5e42985084a 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -195,7 +195,7 @@ static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool e intel_de_posting_read(dev_priv, SOUTH_CHICKEN1); } -void ivb_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_state) +static void ivb_update_fdi_bc_bifurcation(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); @@ -270,6 +270,13 @@ static void ilk_fdi_link_train(struct intel_crtc *crtc, i915_reg_t reg; u32 temp, tries; + /* + * Write the TU size bits before fdi link training, so that error + * detection works. + */ + intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe), + intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK); + /* FDI needs bits from pipe first */ assert_pipe_enabled(dev_priv, crtc_state->cpu_transcoder); @@ -373,6 +380,13 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc, i915_reg_t reg; u32 temp, i, retry; + /* + * Write the TU size bits before fdi link training, so that error + * detection works. + */ + intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe), + intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK); + /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit for train result */ reg = FDI_RX_IMR(pipe); @@ -510,6 +524,15 @@ static void ivb_manual_fdi_link_train(struct intel_crtc *crtc, i915_reg_t reg; u32 temp, i, j; + ivb_update_fdi_bc_bifurcation(crtc_state); + + /* + * Write the TU size bits before fdi link training, so that error + * detection works. + */ + intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe), + intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK); + /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit for train result */ reg = FDI_RX_IMR(pipe); diff --git a/drivers/gpu/drm/i915/display/intel_fdi.h b/drivers/gpu/drm/i915/display/intel_fdi.h index 135802e4da68..cda9a32c25ba 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.h +++ b/drivers/gpu/drm/i915/display/intel_fdi.h @@ -16,7 +16,6 @@ int intel_fdi_link_freq(struct drm_i915_private *i915, const struct intel_crtc_state *pipe_config); int ilk_fdi_compute_config(struct intel_crtc *intel_crtc, struct intel_crtc_state *pipe_config); -void ivb_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_state); void intel_fdi_normal_train(struct intel_crtc *crtc); void ilk_fdi_disable(struct intel_crtc *crtc); void ilk_fdi_pll_disable(struct intel_crtc *intel_crtc); -- cgit v1.2.3 From e2cf6afcdacf937b67f362a623254dac32e7c509 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Aug 2021 18:47:51 +0300 Subject: drm/i915/fdi: move fdi mphy reset and programming to intel_fdi.c This fairly detailed stuff that really has no place in intel_display.c. Combine the calls into one to avoid exposing both. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/b0037775480380e5d73d0b112da478d6f0ea30fe.1629906431.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 102 +-------------------------- drivers/gpu/drm/i915/display/intel_fdi.c | 100 ++++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_fdi.h | 1 + 3 files changed, 103 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b907c43a115c..4d35f3b087d7 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4897,102 +4897,6 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) BUG_ON(val != final); } -static void lpt_reset_fdi_mphy(struct drm_i915_private *dev_priv) -{ - u32 tmp; - - tmp = intel_de_read(dev_priv, SOUTH_CHICKEN2); - tmp |= FDI_MPHY_IOSFSB_RESET_CTL; - intel_de_write(dev_priv, SOUTH_CHICKEN2, tmp); - - if (wait_for_us(intel_de_read(dev_priv, SOUTH_CHICKEN2) & - FDI_MPHY_IOSFSB_RESET_STATUS, 100)) - drm_err(&dev_priv->drm, "FDI mPHY reset assert timeout\n"); - - tmp = intel_de_read(dev_priv, SOUTH_CHICKEN2); - tmp &= ~FDI_MPHY_IOSFSB_RESET_CTL; - intel_de_write(dev_priv, SOUTH_CHICKEN2, tmp); - - if (wait_for_us((intel_de_read(dev_priv, SOUTH_CHICKEN2) & - FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100)) - drm_err(&dev_priv->drm, "FDI mPHY reset de-assert timeout\n"); -} - -/* WaMPhyProgramming:hsw */ -static void lpt_program_fdi_mphy(struct drm_i915_private *dev_priv) -{ - u32 tmp; - - tmp = intel_sbi_read(dev_priv, 0x8008, SBI_MPHY); - tmp &= ~(0xFF << 24); - tmp |= (0x12 << 24); - intel_sbi_write(dev_priv, 0x8008, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x2008, SBI_MPHY); - tmp |= (1 << 11); - intel_sbi_write(dev_priv, 0x2008, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x2108, SBI_MPHY); - tmp |= (1 << 11); - intel_sbi_write(dev_priv, 0x2108, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x206C, SBI_MPHY); - tmp |= (1 << 24) | (1 << 21) | (1 << 18); - intel_sbi_write(dev_priv, 0x206C, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x216C, SBI_MPHY); - tmp |= (1 << 24) | (1 << 21) | (1 << 18); - intel_sbi_write(dev_priv, 0x216C, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x2080, SBI_MPHY); - tmp &= ~(7 << 13); - tmp |= (5 << 13); - intel_sbi_write(dev_priv, 0x2080, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x2180, SBI_MPHY); - tmp &= ~(7 << 13); - tmp |= (5 << 13); - intel_sbi_write(dev_priv, 0x2180, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x208C, SBI_MPHY); - tmp &= ~0xFF; - tmp |= 0x1C; - intel_sbi_write(dev_priv, 0x208C, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x218C, SBI_MPHY); - tmp &= ~0xFF; - tmp |= 0x1C; - intel_sbi_write(dev_priv, 0x218C, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x2098, SBI_MPHY); - tmp &= ~(0xFF << 16); - tmp |= (0x1C << 16); - intel_sbi_write(dev_priv, 0x2098, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x2198, SBI_MPHY); - tmp &= ~(0xFF << 16); - tmp |= (0x1C << 16); - intel_sbi_write(dev_priv, 0x2198, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x20C4, SBI_MPHY); - tmp |= (1 << 27); - intel_sbi_write(dev_priv, 0x20C4, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x21C4, SBI_MPHY); - tmp |= (1 << 27); - intel_sbi_write(dev_priv, 0x21C4, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x20EC, SBI_MPHY); - tmp &= ~(0xF << 28); - tmp |= (4 << 28); - intel_sbi_write(dev_priv, 0x20EC, tmp, SBI_MPHY); - - tmp = intel_sbi_read(dev_priv, 0x21EC, SBI_MPHY); - tmp &= ~(0xF << 28); - tmp |= (4 << 28); - intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY); -} - /* Implements 3 different sequences from BSpec chapter "Display iCLK * Programming" based on the parameters passed: * - Sequence to enable CLKOUT_DP @@ -5025,10 +4929,8 @@ static void lpt_enable_clkout_dp(struct drm_i915_private *dev_priv, tmp &= ~SBI_SSCCTL_PATHALT; intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); - if (with_fdi) { - lpt_reset_fdi_mphy(dev_priv); - lpt_program_fdi_mphy(dev_priv); - } + if (with_fdi) + lpt_fdi_program_mphy(dev_priv); } reg = HAS_PCH_LPT_LP(dev_priv) ? SBI_GEN0 : SBI_DBUFF0; diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index f5e42985084a..cc83a6532a71 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -2,11 +2,13 @@ /* * Copyright © 2020 Intel Corporation */ + #include "intel_atomic.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_types.h" #include "intel_fdi.h" +#include "intel_sideband.h" /* units of 100MHz */ static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state) @@ -904,6 +906,104 @@ void ilk_fdi_disable(struct intel_crtc *crtc) udelay(100); } +static void lpt_fdi_reset_mphy(struct drm_i915_private *dev_priv) +{ + u32 tmp; + + tmp = intel_de_read(dev_priv, SOUTH_CHICKEN2); + tmp |= FDI_MPHY_IOSFSB_RESET_CTL; + intel_de_write(dev_priv, SOUTH_CHICKEN2, tmp); + + if (wait_for_us(intel_de_read(dev_priv, SOUTH_CHICKEN2) & + FDI_MPHY_IOSFSB_RESET_STATUS, 100)) + drm_err(&dev_priv->drm, "FDI mPHY reset assert timeout\n"); + + tmp = intel_de_read(dev_priv, SOUTH_CHICKEN2); + tmp &= ~FDI_MPHY_IOSFSB_RESET_CTL; + intel_de_write(dev_priv, SOUTH_CHICKEN2, tmp); + + if (wait_for_us((intel_de_read(dev_priv, SOUTH_CHICKEN2) & + FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100)) + drm_err(&dev_priv->drm, "FDI mPHY reset de-assert timeout\n"); +} + +/* WaMPhyProgramming:hsw */ +void lpt_fdi_program_mphy(struct drm_i915_private *dev_priv) +{ + u32 tmp; + + lpt_fdi_reset_mphy(dev_priv); + + tmp = intel_sbi_read(dev_priv, 0x8008, SBI_MPHY); + tmp &= ~(0xFF << 24); + tmp |= (0x12 << 24); + intel_sbi_write(dev_priv, 0x8008, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x2008, SBI_MPHY); + tmp |= (1 << 11); + intel_sbi_write(dev_priv, 0x2008, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x2108, SBI_MPHY); + tmp |= (1 << 11); + intel_sbi_write(dev_priv, 0x2108, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x206C, SBI_MPHY); + tmp |= (1 << 24) | (1 << 21) | (1 << 18); + intel_sbi_write(dev_priv, 0x206C, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x216C, SBI_MPHY); + tmp |= (1 << 24) | (1 << 21) | (1 << 18); + intel_sbi_write(dev_priv, 0x216C, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x2080, SBI_MPHY); + tmp &= ~(7 << 13); + tmp |= (5 << 13); + intel_sbi_write(dev_priv, 0x2080, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x2180, SBI_MPHY); + tmp &= ~(7 << 13); + tmp |= (5 << 13); + intel_sbi_write(dev_priv, 0x2180, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x208C, SBI_MPHY); + tmp &= ~0xFF; + tmp |= 0x1C; + intel_sbi_write(dev_priv, 0x208C, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x218C, SBI_MPHY); + tmp &= ~0xFF; + tmp |= 0x1C; + intel_sbi_write(dev_priv, 0x218C, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x2098, SBI_MPHY); + tmp &= ~(0xFF << 16); + tmp |= (0x1C << 16); + intel_sbi_write(dev_priv, 0x2098, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x2198, SBI_MPHY); + tmp &= ~(0xFF << 16); + tmp |= (0x1C << 16); + intel_sbi_write(dev_priv, 0x2198, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x20C4, SBI_MPHY); + tmp |= (1 << 27); + intel_sbi_write(dev_priv, 0x20C4, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x21C4, SBI_MPHY); + tmp |= (1 << 27); + intel_sbi_write(dev_priv, 0x21C4, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x20EC, SBI_MPHY); + tmp &= ~(0xF << 28); + tmp |= (4 << 28); + intel_sbi_write(dev_priv, 0x20EC, tmp, SBI_MPHY); + + tmp = intel_sbi_read(dev_priv, 0x21EC, SBI_MPHY); + tmp &= ~(0xF << 28); + tmp |= (4 << 28); + intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY); +} + void intel_fdi_init_hook(struct drm_i915_private *dev_priv) { diff --git a/drivers/gpu/drm/i915/display/intel_fdi.h b/drivers/gpu/drm/i915/display/intel_fdi.h index cda9a32c25ba..60acf2133145 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.h +++ b/drivers/gpu/drm/i915/display/intel_fdi.h @@ -24,5 +24,6 @@ void intel_fdi_init_hook(struct drm_i915_private *dev_priv); void hsw_fdi_link_train(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); void intel_fdi_pll_freq_update(struct drm_i915_private *i915); +void lpt_fdi_program_mphy(struct drm_i915_private *i915); #endif -- cgit v1.2.3 From 9716846039eff1264de8868e9ed3f74a34b5b724 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 25 Aug 2021 18:47:52 +0300 Subject: drm/i915/fdi: convert BUG()'s to MISSING_CASE() These shouldn't happen, but in the off chance they do, we'll want a warning rather than panic. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/b86132ac63f43f79e51eb63f948beccba85bf449.1629906431.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_fdi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index cc83a6532a71..fc09b781f15f 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -93,7 +93,8 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, } return 0; default: - BUG(); + MISSING_CASE(pipe); + return 0; } } @@ -217,7 +218,7 @@ static void ivb_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_st break; default: - BUG(); + MISSING_CASE(crtc->pipe); } } -- cgit v1.2.3 From fa3217c4948700d0d4e85c5fad41fe27d663a507 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 Aug 2021 17:18:30 +0300 Subject: drm/i915: remove unused i915->active_pipes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently the last reader of i915->active_pipes was removed with commit ef79d62b5ce5 ("drm/i915: Encapsulate dbuf state handling harder"), and now it's only ever written to. Remove it completely. Cc: Stanislav Lisovskiy Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210826141830.889-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 4 +--- drivers/gpu/drm/i915/i915_drv.h | 6 ------ 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 4d35f3b087d7..5560d2f4c352 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3724,7 +3724,6 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc, intel_display_power_put_all_in_set(dev_priv, &crtc->enabled_power_domains); - dev_priv->active_pipes &= ~BIT(pipe); cdclk_state->min_cdclk[pipe] = 0; cdclk_state->min_voltage_level[pipe] = 0; cdclk_state->active_pipes &= ~BIT(pipe); @@ -12180,8 +12179,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) enableddisabled(crtc_state->hw.active)); } - dev_priv->active_pipes = cdclk_state->active_pipes = - dbuf_state->active_pipes = active_pipes; + cdclk_state->active_pipes = dbuf_state->active_pipes = active_pipes; readout_plane_state(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f64ba566fe8c..033031169d74 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1015,12 +1015,6 @@ struct drm_i915_private { struct list_head global_obj_list; - /* - * For reading active_pipes holding any crtc lock is - * sufficient, for writing must hold all of them. - */ - u8 active_pipes; - struct i915_wa_list gt_wa_list; struct i915_frontbuffer_tracking fb_tracking; -- cgit v1.2.3 From 45cbbe50ccb10452c9369c2e58f0fdee90abae0b Mon Sep 17 00:00:00 2001 From: Animesh Manna Date: Fri, 27 Aug 2021 13:38:43 +0300 Subject: drm/i915/dg2: UHBR tables added for pll programming UHBR modes has higher link rate and added new values for programming mpll of SNPS phy. No change in sequence, only the pll parameters are different for UHBR modes. Reviewed-by: Jani Nikula Signed-off-by: Animesh Manna Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210827103843.527-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_snps_phy.c | 147 ++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 4 + 2 files changed, 151 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c index 58ec2467ad66..2405f70d82de 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c @@ -171,11 +171,81 @@ static const struct intel_mpllb_state dg2_dp_hbr3_100 = { REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1), }; +static const struct intel_mpllb_state dg2_dp_uhbr10_100 = { + .clock = 1000000, + .ref_control = + REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3), + .mpllb_cp = + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 21) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127), + .mpllb_div = + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_CLK_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_MULTIPLIER, 8) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_WORD_DIV2_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_DP2_MODE, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2), + .mpllb_div2 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 368), + .mpllb_fracn1 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1), + + /* + * SSC will be enabled, DP UHBR has a minimum SSC requirement. + */ + .mpllb_sscen = + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 58982), + .mpllb_sscstep = + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 76101), +}; + +static const struct intel_mpllb_state dg2_dp_uhbr13_100 = { + .clock = 1350000, + .ref_control = + REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3), + .mpllb_cp = + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 45) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127), + .mpllb_div = + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_CLK_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_MULTIPLIER, 8) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_WORD_DIV2_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_DP2_MODE, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 3), + .mpllb_div2 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 508), + .mpllb_fracn1 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1), + + /* + * SSC will be enabled, DP UHBR has a minimum SSC requirement. + */ + .mpllb_sscen = + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 79626), + .mpllb_sscstep = + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 102737), +}; + static const struct intel_mpllb_state * const dg2_dp_100_tables[] = { &dg2_dp_rbr_100, &dg2_dp_hbr1_100, &dg2_dp_hbr2_100, &dg2_dp_hbr3_100, + &dg2_dp_uhbr10_100, + &dg2_dp_uhbr13_100, NULL, }; @@ -284,11 +354,88 @@ static const struct intel_mpllb_state dg2_dp_hbr3_38_4 = { REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 61440), }; +static const struct intel_mpllb_state dg2_dp_uhbr10_38_4 = { + .clock = 1000000, + .ref_control = + REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1), + .mpllb_cp = + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 26) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127), + .mpllb_div = + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_CLK_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_MULTIPLIER, 8) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_WORD_DIV2_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_DP2_MODE, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2), + .mpllb_div2 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 488), + .mpllb_fracn1 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 3), + .mpllb_fracn2 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 27306), + + /* + * SSC will be enabled, DP UHBR has a minimum SSC requirement. + */ + .mpllb_sscen = + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 76800), + .mpllb_sscstep = + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 129024), +}; + +static const struct intel_mpllb_state dg2_dp_uhbr13_38_4 = { + .clock = 1350000, + .ref_control = + REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1), + .mpllb_cp = + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 56) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127), + .mpllb_div = + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_CLK_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV_MULTIPLIER, 8) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_WORD_DIV2_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_DP2_MODE, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 3), + .mpllb_div2 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 670), + .mpllb_fracn1 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1), + .mpllb_fracn2 = + REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 36864), + + /* + * SSC will be enabled, DP UHBR has a minimum SSC requirement. + */ + .mpllb_sscen = + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) | + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 103680), + .mpllb_sscstep = + REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 174182), +}; + static const struct intel_mpllb_state * const dg2_dp_38_4_tables[] = { &dg2_dp_rbr_38_4, &dg2_dp_hbr1_38_4, &dg2_dp_hbr2_38_4, &dg2_dp_hbr3_38_4, + &dg2_dp_uhbr10_38_4, + &dg2_dp_uhbr13_38_4, NULL, }; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d5177c7655b3..26c9825e0b89 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2237,10 +2237,14 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define SNPS_PHY_MPLLB_DIV(phy) _MMIO_SNPS(phy, 0x168004) #define SNPS_PHY_MPLLB_FORCE_EN REG_BIT(31) +#define SNPS_PHY_MPLLB_DIV_CLK_EN REG_BIT(30) #define SNPS_PHY_MPLLB_DIV5_CLK_EN REG_BIT(29) #define SNPS_PHY_MPLLB_V2I REG_GENMASK(27, 26) #define SNPS_PHY_MPLLB_FREQ_VCO REG_GENMASK(25, 24) +#define SNPS_PHY_MPLLB_DIV_MULTIPLIER REG_GENMASK(23, 16) #define SNPS_PHY_MPLLB_PMIX_EN REG_BIT(10) +#define SNPS_PHY_MPLLB_DP2_MODE REG_BIT(9) +#define SNPS_PHY_MPLLB_WORD_DIV2_EN REG_BIT(8) #define SNPS_PHY_MPLLB_TX_CLK_DIV REG_GENMASK(7, 5) #define SNPS_PHY_MPLLB_FRACN1(phy) _MMIO_SNPS(phy, 0x168008) -- cgit v1.2.3 From ad26451a790209318c25a8a5ab9a36fc47dc7bba Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Fri, 27 Aug 2021 10:42:51 -0700 Subject: drm/i915/display: Drop PSR support from HSW and BDW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At this point is sure that HSW and BDW will never have PSR enabled by default, so here dropping it from device info and cleaning up code. v2: - enable psr support for display 9 Reviewed-by: Rodrigo Vivi Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210827174253.51122-1-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 97 +++++--------------------------- drivers/gpu/drm/i915/i915_drv.h | 2 - drivers/gpu/drm/i915/i915_irq.c | 16 ------ drivers/gpu/drm/i915/i915_pci.c | 4 +- drivers/gpu/drm/i915/i915_reg.h | 21 ++----- 5 files changed, 20 insertions(+), 120 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index cade37f67f33..3f6fb7d67f84 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -364,41 +364,6 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) } } -static void hsw_psr_setup_aux(struct intel_dp *intel_dp) -{ - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - u32 aux_clock_divider, aux_ctl; - int i; - static const u8 aux_msg[] = { - [0] = DP_AUX_NATIVE_WRITE << 4, - [1] = DP_SET_POWER >> 8, - [2] = DP_SET_POWER & 0xff, - [3] = 1 - 1, - [4] = DP_SET_POWER_D0, - }; - u32 psr_aux_mask = EDP_PSR_AUX_CTL_TIME_OUT_MASK | - EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK | - EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK | - EDP_PSR_AUX_CTL_BIT_CLOCK_2X_MASK; - - BUILD_BUG_ON(sizeof(aux_msg) > 20); - for (i = 0; i < sizeof(aux_msg); i += 4) - intel_de_write(dev_priv, - EDP_PSR_AUX_DATA(intel_dp->psr.transcoder, i >> 2), - intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i)); - - aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0); - - /* Start with bits set for DDI_AUX_CTL register */ - aux_ctl = intel_dp->get_aux_send_ctl(intel_dp, sizeof(aux_msg), - aux_clock_divider); - - /* Select only valid bits for SRD_AUX_CTL */ - aux_ctl &= psr_aux_mask; - intel_de_write(dev_priv, EDP_PSR_AUX_CTL(intel_dp->psr.transcoder), - aux_ctl); -} - static void intel_psr_enable_sink(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -621,9 +586,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) static bool transcoder_has_psr2(struct drm_i915_private *dev_priv, enum transcoder trans) { - if (DISPLAY_VER(dev_priv) < 9) - return false; - else if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(dev_priv) >= 12) return trans == TRANSCODER_A; else return trans == TRANSCODER_EDP; @@ -1114,12 +1077,6 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp) enum transcoder cpu_transcoder = intel_dp->psr.transcoder; u32 mask; - /* Only HSW and BDW have PSR AUX registers that need to be setup. SKL+ - * use hardcoded values PSR AUX transactions - */ - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - hsw_psr_setup_aux(intel_dp); - if (intel_dp->psr.psr2_enabled && DISPLAY_VER(dev_priv) == 9) { i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder); u32 chicken = intel_de_read(dev_priv, reg); @@ -1460,23 +1417,16 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - if (DISPLAY_VER(dev_priv) >= 9) - /* - * Display WA #0884: skl+ - * This documented WA for bxt can be safely applied - * broadly so we can force HW tracking to exit PSR - * instead of disabling and re-enabling. - * Workaround tells us to write 0 to CUR_SURFLIVE_A, - * but it makes more sense write to the current active - * pipe. - */ - intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0); - else - /* - * A write to CURSURFLIVE do not cause HW tracking to exit PSR - * on older gens so doing the manual exit instead. - */ - intel_psr_exit(intel_dp); + /* + * Display WA #0884: skl+ + * This documented WA for bxt can be safely applied + * broadly so we can force HW tracking to exit PSR + * instead of disabling and re-enabling. + * Workaround tells us to write 0 to CUR_SURFLIVE_A, + * but it makes more sense write to the current active + * pipe. + */ + intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0); } void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, @@ -1744,7 +1694,6 @@ void intel_psr_update(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct intel_psr *psr = &intel_dp->psr; bool enable, psr2_enable; @@ -1761,15 +1710,6 @@ void intel_psr_update(struct intel_dp *intel_dp, /* Force a PSR exit when enabling CRC to avoid CRC timeouts */ if (crtc_state->crc_enabled && psr->enabled) psr_force_hw_tracking_exit(intel_dp); - else if (DISPLAY_VER(dev_priv) < 9 && psr->enabled) { - /* - * Activate PSR again after a force exit when enabling - * CRC in older gens - */ - if (!intel_dp->psr.active && - !intel_dp->psr.busy_frontbuffer_bits) - schedule_work(&intel_dp->psr.work); - } goto unlock; } @@ -2182,23 +2122,12 @@ void intel_psr_init(struct intel_dp *intel_dp) intel_dp->psr.source_support = true; - if (IS_HASWELL(dev_priv)) - /* - * HSW don't have PSR registers on the same space as transcoder - * so set this to a value that when subtract to the register - * in transcoder space results in the right offset for HSW - */ - dev_priv->hsw_psr_mmio_adjust = _SRD_CTL_EDP - _HSW_EDP_PSR_BASE; - if (dev_priv->params.enable_psr == -1) - if (DISPLAY_VER(dev_priv) < 9 || !dev_priv->vbt.psr.enable) + if (!dev_priv->vbt.psr.enable) dev_priv->params.enable_psr = 0; /* Set link_standby x link_off defaults */ - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - /* HSW and BDW require workarounds that we don't implement. */ - intel_dp->psr.link_standby = false; - else if (DISPLAY_VER(dev_priv) < 12) + if (DISPLAY_VER(dev_priv) < 12) /* For new platforms up to TGL let's respect VBT back again */ intel_dp->psr.link_standby = dev_priv->vbt.psr.full_link; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 033031169d74..be2392bbcecc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -885,8 +885,6 @@ struct drm_i915_private { */ u32 gpio_mmio_base; - u32 hsw_psr_mmio_adjust; - /* MMIO base address for MIPI regs */ u32 mipi_mmio_base; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 58a452c3f086..0a1681384c84 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2123,22 +2123,6 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv, if (de_iir & DE_ERR_INT_IVB) ivb_err_int_handler(dev_priv); - if (de_iir & DE_EDP_PSR_INT_HSW) { - struct intel_encoder *encoder; - - for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - - u32 psr_iir = intel_uncore_read(&dev_priv->uncore, - EDP_PSR_IIR); - - intel_psr_irq_handler(intel_dp, psr_iir); - intel_uncore_write(&dev_priv->uncore, - EDP_PSR_IIR, psr_iir); - break; - } - } - if (de_iir & DE_AUX_CHANNEL_A_IVB) dp_aux_irq_handler(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 1bbd09ad5287..52c04369559f 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -537,8 +537,6 @@ static const struct intel_device_info vlv_info = { BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP), \ .display.has_ddi = 1, \ .display.has_fpga_dbg = 1, \ - .display.has_psr = 1, \ - .display.has_psr_hw_tracking = 1, \ .display.has_dp_mst = 1, \ .has_rc6p = 0 /* RC6p removed-by HSW */, \ HSW_PIPE_OFFSETS, \ @@ -642,6 +640,8 @@ static const struct intel_device_info chv_info = { .has_gt_uc = 1, \ .display.has_hdcp = 1, \ .display.has_ipc = 1, \ + .display.has_psr = 1, \ + .display.has_psr_hw_tracking = 1, \ .dbuf.size = 896 - 4, /* 4 blocks for bypass path allocation */ \ .dbuf.slice_mask = BIT(DBUF_S1) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 26c9825e0b89..a0c8110d4ca0 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4513,11 +4513,9 @@ enum { * HSW PSR registers are relative to DDIA(_DDI_BUF_CTL_A + 0x800) with just one * instance of it */ -#define _HSW_EDP_PSR_BASE 0x64800 #define _SRD_CTL_A 0x60800 #define _SRD_CTL_EDP 0x6f800 -#define _PSR_ADJ(tran, reg) (_TRANS2(tran, reg) - dev_priv->hsw_psr_mmio_adjust) -#define EDP_PSR_CTL(tran) _MMIO(_PSR_ADJ(tran, _SRD_CTL_A)) +#define EDP_PSR_CTL(tran) _MMIO(_TRANS2(tran, _SRD_CTL_A)) #define EDP_PSR_ENABLE (1 << 31) #define BDW_PSR_SINGLE_FRAME (1 << 30) #define EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK (1 << 29) /* SW can't modify */ @@ -4561,22 +4559,13 @@ enum { #define EDP_PSR_POST_EXIT(trans) (0x2 << _EDP_PSR_TRANS_SHIFT(trans)) #define EDP_PSR_PRE_ENTRY(trans) (0x1 << _EDP_PSR_TRANS_SHIFT(trans)) -#define _SRD_AUX_CTL_A 0x60810 -#define _SRD_AUX_CTL_EDP 0x6f810 -#define EDP_PSR_AUX_CTL(tran) _MMIO(_PSR_ADJ(tran, _SRD_AUX_CTL_A)) -#define EDP_PSR_AUX_CTL_TIME_OUT_MASK (3 << 26) -#define EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK (0x1f << 20) -#define EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK (0xf << 16) -#define EDP_PSR_AUX_CTL_ERROR_INTERRUPT (1 << 11) -#define EDP_PSR_AUX_CTL_BIT_CLOCK_2X_MASK (0x7ff) - #define _SRD_AUX_DATA_A 0x60814 #define _SRD_AUX_DATA_EDP 0x6f814 -#define EDP_PSR_AUX_DATA(tran, i) _MMIO(_PSR_ADJ(tran, _SRD_AUX_DATA_A) + (i) + 4) /* 5 registers */ +#define EDP_PSR_AUX_DATA(tran, i) _MMIO(_TRANS2(tran, _SRD_AUX_DATA_A) + (i) + 4) /* 5 registers */ #define _SRD_STATUS_A 0x60840 #define _SRD_STATUS_EDP 0x6f840 -#define EDP_PSR_STATUS(tran) _MMIO(_PSR_ADJ(tran, _SRD_STATUS_A)) +#define EDP_PSR_STATUS(tran) _MMIO(_TRANS2(tran, _SRD_STATUS_A)) #define EDP_PSR_STATUS_STATE_MASK (7 << 29) #define EDP_PSR_STATUS_STATE_SHIFT 29 #define EDP_PSR_STATUS_STATE_IDLE (0 << 29) @@ -4603,13 +4592,13 @@ enum { #define _SRD_PERF_CNT_A 0x60844 #define _SRD_PERF_CNT_EDP 0x6f844 -#define EDP_PSR_PERF_CNT(tran) _MMIO(_PSR_ADJ(tran, _SRD_PERF_CNT_A)) +#define EDP_PSR_PERF_CNT(tran) _MMIO(_TRANS2(tran, _SRD_PERF_CNT_A)) #define EDP_PSR_PERF_CNT_MASK 0xffffff /* PSR_MASK on SKL+ */ #define _SRD_DEBUG_A 0x60860 #define _SRD_DEBUG_EDP 0x6f860 -#define EDP_PSR_DEBUG(tran) _MMIO(_PSR_ADJ(tran, _SRD_DEBUG_A)) +#define EDP_PSR_DEBUG(tran) _MMIO(_TRANS2(tran, _SRD_DEBUG_A)) #define EDP_PSR_DEBUG_MASK_MAX_SLEEP (1 << 28) #define EDP_PSR_DEBUG_MASK_LPSP (1 << 27) #define EDP_PSR_DEBUG_MASK_MEMUP (1 << 26) -- cgit v1.2.3 From a1b63119ee839c8ff622407aab25c9723943638a Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Fri, 27 Aug 2021 10:42:52 -0700 Subject: drm/i915/display: Move DRRS code its own file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_dp.c is a 5k lines monster, so moving DRRS out of it to reduce some lines from it. Reviewed-by: Rodrigo Vivi Cc: Jani Nikula Cc: Rodrigo Vivi Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210827174253.51122-2-jose.souza@intel.com --- Documentation/gpu/i915.rst | 14 +- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/display/intel_ddi.c | 1 + .../gpu/drm/i915/display/intel_display_debugfs.c | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 467 +------------------- drivers/gpu/drm/i915/display/intel_dp.h | 11 - drivers/gpu/drm/i915/display/intel_drrs.c | 477 +++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_drrs.h | 32 ++ drivers/gpu/drm/i915/display/intel_frontbuffer.c | 1 + 9 files changed, 521 insertions(+), 484 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.c create mode 100644 drivers/gpu/drm/i915/display/intel_drrs.h (limited to 'drivers') diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst index 204ebdaadb45..03021dfa0dd8 100644 --- a/Documentation/gpu/i915.rst +++ b/Documentation/gpu/i915.rst @@ -183,25 +183,25 @@ Frame Buffer Compression (FBC) Display Refresh Rate Switching (DRRS) ------------------------------------- -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c :doc: Display Refresh Rate Switching (DRRS) -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c :functions: intel_dp_set_drrs_state -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c :functions: intel_edp_drrs_enable -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c :functions: intel_edp_drrs_disable -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c :functions: intel_edp_drrs_invalidate -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c :functions: intel_edp_drrs_flush -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c +.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c :functions: intel_dp_drrs_init DPIO diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 23612c3a1922..c36c8a4f0716 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -213,6 +213,7 @@ i915-y += \ display/intel_dpll.o \ display/intel_dpll_mgr.o \ display/intel_dpt.o \ + display/intel_drrs.o \ display/intel_dsb.o \ display/intel_fb.o \ display/intel_fbc.o \ diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 837021408b83..263bebabf2bc 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -41,6 +41,7 @@ #include "intel_dp_link_training.h" #include "intel_dp_mst.h" #include "intel_dpio_phy.h" +#include "intel_drrs.h" #include "intel_dsi.h" #include "intel_fdi.h" #include "intel_fifo_underrun.h" diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 8fdacb252bb1..b136a0fc0963 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -13,6 +13,7 @@ #include "intel_display_types.h" #include "intel_dmc.h" #include "intel_dp.h" +#include "intel_drrs.h" #include "intel_fbc.h" #include "intel_hdcp.h" #include "intel_hdmi.h" diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 7f8e8865048f..e6f548ee1a45 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -56,6 +56,7 @@ #include "intel_dp_mst.h" #include "intel_dpio_phy.h" #include "intel_dpll.h" +#include "intel_drrs.h" #include "intel_fifo_underrun.h" #include "intel_hdcp.h" #include "intel_hdmi.h" @@ -1676,46 +1677,6 @@ intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp, intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA); } -static void -intel_dp_drrs_compute_config(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - int output_bpp, bool constant_n) -{ - struct intel_connector *intel_connector = intel_dp->attached_connector; - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - int pixel_clock; - - if (pipe_config->vrr.enable) - return; - - /* - * DRRS and PSR can't be enable together, so giving preference to PSR - * as it allows more power-savings by complete shutting down display, - * so to guarantee this, intel_dp_drrs_compute_config() must be called - * after intel_psr_compute_config(). - */ - if (pipe_config->has_psr) - return; - - if (!intel_connector->panel.downclock_mode || - dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT) - return; - - pipe_config->has_drrs = true; - - pixel_clock = intel_connector->panel.downclock_mode->clock; - if (pipe_config->splitter.enable) - pixel_clock /= pipe_config->splitter.link_count; - - 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); - - /* FIXME: abstract this better */ - if (pipe_config->splitter.enable) - pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count; -} - int intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, @@ -4783,432 +4744,6 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect drm_connector_attach_vrr_capable_property(connector); } -/** - * intel_dp_set_drrs_state - program registers for RR switch to take effect - * @dev_priv: i915 device - * @crtc_state: a pointer to the active intel_crtc_state - * @refresh_rate: RR to be programmed - * - * This function gets called when refresh rate (RR) has to be changed from - * one frequency to another. Switches can be between high and low RR - * supported by the panel or to any other RR based on media playback (in - * this case, RR value needs to be passed from user space). - * - * The caller of this function needs to take a lock on dev_priv->drrs. - */ -static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv, - const struct intel_crtc_state *crtc_state, - int refresh_rate) -{ - struct intel_dp *intel_dp = dev_priv->drrs.dp; - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - enum drrs_refresh_rate_type index = DRRS_HIGH_RR; - - if (refresh_rate <= 0) { - drm_dbg_kms(&dev_priv->drm, - "Refresh rate should be positive non-zero.\n"); - return; - } - - if (intel_dp == NULL) { - drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n"); - return; - } - - if (!crtc) { - drm_dbg_kms(&dev_priv->drm, - "DRRS: intel_crtc not initialized\n"); - return; - } - - if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) { - drm_dbg_kms(&dev_priv->drm, "Only Seamless DRRS supported.\n"); - return; - } - - if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) == - refresh_rate) - index = DRRS_LOW_RR; - - if (index == dev_priv->drrs.refresh_rate_type) { - drm_dbg_kms(&dev_priv->drm, - "DRRS requested for previously set RR...ignoring\n"); - return; - } - - if (!crtc_state->hw.active) { - drm_dbg_kms(&dev_priv->drm, - "eDP encoder disabled. CRTC not Active\n"); - return; - } - - if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) { - switch (index) { - case DRRS_HIGH_RR: - intel_dp_set_m_n(crtc_state, M1_N1); - break; - case DRRS_LOW_RR: - intel_dp_set_m_n(crtc_state, M2_N2); - break; - case DRRS_MAX_RR: - default: - drm_err(&dev_priv->drm, - "Unsupported refreshrate type\n"); - } - } else if (DISPLAY_VER(dev_priv) > 6) { - i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder); - u32 val; - - val = intel_de_read(dev_priv, reg); - if (index > DRRS_HIGH_RR) { - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV; - else - val |= PIPECONF_EDP_RR_MODE_SWITCH; - } else { - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV; - else - val &= ~PIPECONF_EDP_RR_MODE_SWITCH; - } - intel_de_write(dev_priv, reg, val); - } - - dev_priv->drrs.refresh_rate_type = index; - - drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n", - refresh_rate); -} - -static void -intel_edp_drrs_enable_locked(struct intel_dp *intel_dp) -{ - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - - dev_priv->drrs.busy_frontbuffer_bits = 0; - dev_priv->drrs.dp = intel_dp; -} - -/** - * intel_edp_drrs_enable - init drrs struct if supported - * @intel_dp: DP struct - * @crtc_state: A pointer to the active crtc state. - * - * Initializes frontbuffer_bits and drrs.dp - */ -void intel_edp_drrs_enable(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - - if (!crtc_state->has_drrs) - return; - - drm_dbg_kms(&dev_priv->drm, "Enabling DRRS\n"); - - mutex_lock(&dev_priv->drrs.mutex); - - if (dev_priv->drrs.dp) { - drm_warn(&dev_priv->drm, "DRRS already enabled\n"); - goto unlock; - } - - intel_edp_drrs_enable_locked(intel_dp); - -unlock: - mutex_unlock(&dev_priv->drrs.mutex); -} - -static void -intel_edp_drrs_disable_locked(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - - if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) { - int refresh; - - refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode); - intel_dp_set_drrs_state(dev_priv, crtc_state, refresh); - } - - dev_priv->drrs.dp = NULL; -} - -/** - * intel_edp_drrs_disable - Disable DRRS - * @intel_dp: DP struct - * @old_crtc_state: Pointer to old crtc_state. - * - */ -void intel_edp_drrs_disable(struct intel_dp *intel_dp, - const struct intel_crtc_state *old_crtc_state) -{ - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - - if (!old_crtc_state->has_drrs) - return; - - mutex_lock(&dev_priv->drrs.mutex); - if (!dev_priv->drrs.dp) { - mutex_unlock(&dev_priv->drrs.mutex); - return; - } - - intel_edp_drrs_disable_locked(intel_dp, old_crtc_state); - mutex_unlock(&dev_priv->drrs.mutex); - - cancel_delayed_work_sync(&dev_priv->drrs.work); -} - -/** - * intel_edp_drrs_update - Update DRRS state - * @intel_dp: Intel DP - * @crtc_state: new CRTC state - * - * This function will update DRRS states, disabling or enabling DRRS when - * executing fastsets. For full modeset, intel_edp_drrs_disable() and - * intel_edp_drrs_enable() should be called instead. - */ -void -intel_edp_drrs_update(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - - if (dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT) - return; - - mutex_lock(&dev_priv->drrs.mutex); - - /* New state matches current one? */ - if (crtc_state->has_drrs == !!dev_priv->drrs.dp) - goto unlock; - - if (crtc_state->has_drrs) - intel_edp_drrs_enable_locked(intel_dp); - else - intel_edp_drrs_disable_locked(intel_dp, crtc_state); - -unlock: - mutex_unlock(&dev_priv->drrs.mutex); -} - -static void intel_edp_drrs_downclock_work(struct work_struct *work) -{ - struct drm_i915_private *dev_priv = - container_of(work, typeof(*dev_priv), drrs.work.work); - struct intel_dp *intel_dp; - - mutex_lock(&dev_priv->drrs.mutex); - - intel_dp = dev_priv->drrs.dp; - - if (!intel_dp) - goto unlock; - - /* - * The delayed work can race with an invalidate hence we need to - * recheck. - */ - - if (dev_priv->drrs.busy_frontbuffer_bits) - goto unlock; - - if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) { - struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc; - - intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, - drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode)); - } - -unlock: - mutex_unlock(&dev_priv->drrs.mutex); -} - -/** - * intel_edp_drrs_invalidate - Disable Idleness DRRS - * @dev_priv: i915 device - * @frontbuffer_bits: frontbuffer plane tracking bits - * - * This function gets called everytime rendering on the given planes start. - * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR). - * - * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. - */ -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits) -{ - struct intel_dp *intel_dp; - struct drm_crtc *crtc; - enum pipe pipe; - - if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED) - return; - - cancel_delayed_work(&dev_priv->drrs.work); - - mutex_lock(&dev_priv->drrs.mutex); - - intel_dp = dev_priv->drrs.dp; - if (!intel_dp) { - mutex_unlock(&dev_priv->drrs.mutex); - return; - } - - crtc = dp_to_dig_port(intel_dp)->base.base.crtc; - pipe = to_intel_crtc(crtc)->pipe; - - frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); - dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits; - - /* invalidate means busy screen hence upclock */ - if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) - intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, - drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); - - mutex_unlock(&dev_priv->drrs.mutex); -} - -/** - * intel_edp_drrs_flush - Restart Idleness DRRS - * @dev_priv: i915 device - * @frontbuffer_bits: frontbuffer plane tracking bits - * - * This function gets called every time rendering on the given planes has - * completed or flip on a crtc is completed. So DRRS should be upclocked - * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again, - * if no other planes are dirty. - * - * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. - */ -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits) -{ - struct intel_dp *intel_dp; - struct drm_crtc *crtc; - enum pipe pipe; - - if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED) - return; - - cancel_delayed_work(&dev_priv->drrs.work); - - mutex_lock(&dev_priv->drrs.mutex); - - intel_dp = dev_priv->drrs.dp; - if (!intel_dp) { - mutex_unlock(&dev_priv->drrs.mutex); - return; - } - - crtc = dp_to_dig_port(intel_dp)->base.base.crtc; - pipe = to_intel_crtc(crtc)->pipe; - - frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); - dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits; - - /* flush means busy screen hence upclock */ - if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) - intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, - drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); - - /* - * flush also means no more activity hence schedule downclock, if all - * other fbs are quiescent too - */ - if (!dev_priv->drrs.busy_frontbuffer_bits) - schedule_delayed_work(&dev_priv->drrs.work, - msecs_to_jiffies(1000)); - mutex_unlock(&dev_priv->drrs.mutex); -} - -/** - * DOC: Display Refresh Rate Switching (DRRS) - * - * Display Refresh Rate Switching (DRRS) is a power conservation feature - * which enables swtching between low and high refresh rates, - * dynamically, based on the usage scenario. This feature is applicable - * for internal panels. - * - * Indication that the panel supports DRRS is given by the panel EDID, which - * would list multiple refresh rates for one resolution. - * - * DRRS is of 2 types - static and seamless. - * Static DRRS involves changing refresh rate (RR) by doing a full modeset - * (may appear as a blink on screen) and is used in dock-undock scenario. - * Seamless DRRS involves changing RR without any visual effect to the user - * and can be used during normal system usage. This is done by programming - * certain registers. - * - * Support for static/seamless DRRS may be indicated in the VBT based on - * inputs from the panel spec. - * - * DRRS saves power by switching to low RR based on usage scenarios. - * - * The implementation is based on frontbuffer tracking implementation. When - * there is a disturbance on the screen triggered by user activity or a periodic - * system activity, DRRS is disabled (RR is changed to high RR). When there is - * no movement on screen, after a timeout of 1 second, a switch to low RR is - * made. - * - * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate() - * and intel_edp_drrs_flush() are called. - * - * DRRS can be further extended to support other internal panels and also - * the scenario of video playback wherein RR is set based on the rate - * requested by userspace. - */ - -/** - * intel_dp_drrs_init - Init basic DRRS work and mutex. - * @connector: eDP connector - * @fixed_mode: preferred mode of panel - * - * This function is called only once at driver load to initialize basic - * DRRS stuff. - * - * Returns: - * Downclock mode if panel supports it, else return NULL. - * DRRS support is determined by the presence of downclock mode (apart - * from VBT setting). - */ -static struct drm_display_mode * -intel_dp_drrs_init(struct intel_connector *connector, - struct drm_display_mode *fixed_mode) -{ - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - struct drm_display_mode *downclock_mode = NULL; - - INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work); - mutex_init(&dev_priv->drrs.mutex); - - if (DISPLAY_VER(dev_priv) <= 6) { - drm_dbg_kms(&dev_priv->drm, - "DRRS supported for Gen7 and above\n"); - return NULL; - } - - if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) { - drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n"); - return NULL; - } - - downclock_mode = intel_panel_edid_downclock_mode(connector, fixed_mode); - if (!downclock_mode) { - drm_dbg_kms(&dev_priv->drm, - "Downclock mode is not found. DRRS not supported\n"); - return NULL; - } - - dev_priv->drrs.type = dev_priv->vbt.drrs_type; - - dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR; - drm_dbg_kms(&dev_priv->drm, - "seamless DRRS supported for eDP panel.\n"); - return downclock_mode; -} - static bool intel_edp_init_connector(struct intel_dp *intel_dp, struct intel_connector *intel_connector) { diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index ae0f776bffab..a28fff286c21 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -70,17 +70,6 @@ int intel_dp_max_link_rate(struct intel_dp *intel_dp); int intel_dp_max_lane_count(struct intel_dp *intel_dp); int intel_dp_rate_select(struct intel_dp *intel_dp, int rate); -void intel_edp_drrs_enable(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); -void intel_edp_drrs_disable(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); -void intel_edp_drrs_update(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits); -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits); - void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, u8 *link_bw, u8 *rate_select); bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c new file mode 100644 index 000000000000..be9b6d4482f0 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_drrs.c @@ -0,0 +1,477 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2021 Intel Corporation + */ + +#include "i915_drv.h" +#include "intel_atomic.h" +#include "intel_de.h" +#include "intel_display_types.h" +#include "intel_drrs.h" +#include "intel_panel.h" + +/** + * DOC: Display Refresh Rate Switching (DRRS) + * + * Display Refresh Rate Switching (DRRS) is a power conservation feature + * which enables swtching between low and high refresh rates, + * dynamically, based on the usage scenario. This feature is applicable + * for internal panels. + * + * Indication that the panel supports DRRS is given by the panel EDID, which + * would list multiple refresh rates for one resolution. + * + * DRRS is of 2 types - static and seamless. + * Static DRRS involves changing refresh rate (RR) by doing a full modeset + * (may appear as a blink on screen) and is used in dock-undock scenario. + * Seamless DRRS involves changing RR without any visual effect to the user + * and can be used during normal system usage. This is done by programming + * certain registers. + * + * Support for static/seamless DRRS may be indicated in the VBT based on + * inputs from the panel spec. + * + * DRRS saves power by switching to low RR based on usage scenarios. + * + * The implementation is based on frontbuffer tracking implementation. When + * there is a disturbance on the screen triggered by user activity or a periodic + * system activity, DRRS is disabled (RR is changed to high RR). When there is + * no movement on screen, after a timeout of 1 second, a switch to low RR is + * made. + * + * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate() + * and intel_edp_drrs_flush() are called. + * + * DRRS can be further extended to support other internal panels and also + * the scenario of video playback wherein RR is set based on the rate + * requested by userspace. + */ + +void +intel_dp_drrs_compute_config(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + int output_bpp, bool constant_n) +{ + struct intel_connector *intel_connector = intel_dp->attached_connector; + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + int pixel_clock; + + if (pipe_config->vrr.enable) + return; + + /* + * DRRS and PSR can't be enable together, so giving preference to PSR + * as it allows more power-savings by complete shutting down display, + * so to guarantee this, intel_dp_drrs_compute_config() must be called + * after intel_psr_compute_config(). + */ + if (pipe_config->has_psr) + return; + + if (!intel_connector->panel.downclock_mode || + dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT) + return; + + pipe_config->has_drrs = true; + + pixel_clock = intel_connector->panel.downclock_mode->clock; + if (pipe_config->splitter.enable) + pixel_clock /= pipe_config->splitter.link_count; + + 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); + + /* FIXME: abstract this better */ + if (pipe_config->splitter.enable) + pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count; +} + +/** + * intel_dp_set_drrs_state - program registers for RR switch to take effect + * @dev_priv: i915 device + * @crtc_state: a pointer to the active intel_crtc_state + * @refresh_rate: RR to be programmed + * + * This function gets called when refresh rate (RR) has to be changed from + * one frequency to another. Switches can be between high and low RR + * supported by the panel or to any other RR based on media playback (in + * this case, RR value needs to be passed from user space). + * + * The caller of this function needs to take a lock on dev_priv->drrs. + */ +static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv, + const struct intel_crtc_state *crtc_state, + int refresh_rate) +{ + struct intel_dp *intel_dp = dev_priv->drrs.dp; + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + enum drrs_refresh_rate_type index = DRRS_HIGH_RR; + + if (refresh_rate <= 0) { + drm_dbg_kms(&dev_priv->drm, + "Refresh rate should be positive non-zero.\n"); + return; + } + + if (intel_dp == NULL) { + drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n"); + return; + } + + if (!crtc) { + drm_dbg_kms(&dev_priv->drm, + "DRRS: intel_crtc not initialized\n"); + return; + } + + if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) { + drm_dbg_kms(&dev_priv->drm, "Only Seamless DRRS supported.\n"); + return; + } + + if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) == + refresh_rate) + index = DRRS_LOW_RR; + + if (index == dev_priv->drrs.refresh_rate_type) { + drm_dbg_kms(&dev_priv->drm, + "DRRS requested for previously set RR...ignoring\n"); + return; + } + + if (!crtc_state->hw.active) { + drm_dbg_kms(&dev_priv->drm, + "eDP encoder disabled. CRTC not Active\n"); + return; + } + + if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) { + switch (index) { + case DRRS_HIGH_RR: + intel_dp_set_m_n(crtc_state, M1_N1); + break; + case DRRS_LOW_RR: + intel_dp_set_m_n(crtc_state, M2_N2); + break; + case DRRS_MAX_RR: + default: + drm_err(&dev_priv->drm, + "Unsupported refreshrate type\n"); + } + } else if (DISPLAY_VER(dev_priv) > 6) { + i915_reg_t reg = PIPECONF(crtc_state->cpu_transcoder); + u32 val; + + val = intel_de_read(dev_priv, reg); + if (index > DRRS_HIGH_RR) { + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV; + else + val |= PIPECONF_EDP_RR_MODE_SWITCH; + } else { + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + val &= ~PIPECONF_EDP_RR_MODE_SWITCH_VLV; + else + val &= ~PIPECONF_EDP_RR_MODE_SWITCH; + } + intel_de_write(dev_priv, reg, val); + } + + dev_priv->drrs.refresh_rate_type = index; + + drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n", + refresh_rate); +} + +static void +intel_edp_drrs_enable_locked(struct intel_dp *intel_dp) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + + dev_priv->drrs.busy_frontbuffer_bits = 0; + dev_priv->drrs.dp = intel_dp; +} + +/** + * intel_edp_drrs_enable - init drrs struct if supported + * @intel_dp: DP struct + * @crtc_state: A pointer to the active crtc state. + * + * Initializes frontbuffer_bits and drrs.dp + */ +void intel_edp_drrs_enable(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + + if (!crtc_state->has_drrs) + return; + + drm_dbg_kms(&dev_priv->drm, "Enabling DRRS\n"); + + mutex_lock(&dev_priv->drrs.mutex); + + if (dev_priv->drrs.dp) { + drm_warn(&dev_priv->drm, "DRRS already enabled\n"); + goto unlock; + } + + intel_edp_drrs_enable_locked(intel_dp); + +unlock: + mutex_unlock(&dev_priv->drrs.mutex); +} + +static void +intel_edp_drrs_disable_locked(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + + if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) { + int refresh; + + refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode); + intel_dp_set_drrs_state(dev_priv, crtc_state, refresh); + } + + dev_priv->drrs.dp = NULL; +} + +/** + * intel_edp_drrs_disable - Disable DRRS + * @intel_dp: DP struct + * @old_crtc_state: Pointer to old crtc_state. + * + */ +void intel_edp_drrs_disable(struct intel_dp *intel_dp, + const struct intel_crtc_state *old_crtc_state) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + + if (!old_crtc_state->has_drrs) + return; + + mutex_lock(&dev_priv->drrs.mutex); + if (!dev_priv->drrs.dp) { + mutex_unlock(&dev_priv->drrs.mutex); + return; + } + + intel_edp_drrs_disable_locked(intel_dp, old_crtc_state); + mutex_unlock(&dev_priv->drrs.mutex); + + cancel_delayed_work_sync(&dev_priv->drrs.work); +} + +/** + * intel_edp_drrs_update - Update DRRS state + * @intel_dp: Intel DP + * @crtc_state: new CRTC state + * + * This function will update DRRS states, disabling or enabling DRRS when + * executing fastsets. For full modeset, intel_edp_drrs_disable() and + * intel_edp_drrs_enable() should be called instead. + */ +void +intel_edp_drrs_update(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + + if (dev_priv->drrs.type != SEAMLESS_DRRS_SUPPORT) + return; + + mutex_lock(&dev_priv->drrs.mutex); + + /* New state matches current one? */ + if (crtc_state->has_drrs == !!dev_priv->drrs.dp) + goto unlock; + + if (crtc_state->has_drrs) + intel_edp_drrs_enable_locked(intel_dp); + else + intel_edp_drrs_disable_locked(intel_dp, crtc_state); + +unlock: + mutex_unlock(&dev_priv->drrs.mutex); +} + +static void intel_edp_drrs_downclock_work(struct work_struct *work) +{ + struct drm_i915_private *dev_priv = + container_of(work, typeof(*dev_priv), drrs.work.work); + struct intel_dp *intel_dp; + + mutex_lock(&dev_priv->drrs.mutex); + + intel_dp = dev_priv->drrs.dp; + + if (!intel_dp) + goto unlock; + + /* + * The delayed work can race with an invalidate hence we need to + * recheck. + */ + + if (dev_priv->drrs.busy_frontbuffer_bits) + goto unlock; + + if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) { + struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc; + + intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, + drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode)); + } + +unlock: + mutex_unlock(&dev_priv->drrs.mutex); +} + +/** + * intel_edp_drrs_invalidate - Disable Idleness DRRS + * @dev_priv: i915 device + * @frontbuffer_bits: frontbuffer plane tracking bits + * + * This function gets called everytime rendering on the given planes start. + * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR). + * + * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. + */ +void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits) +{ + struct intel_dp *intel_dp; + struct drm_crtc *crtc; + enum pipe pipe; + + if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED) + return; + + cancel_delayed_work(&dev_priv->drrs.work); + + mutex_lock(&dev_priv->drrs.mutex); + + intel_dp = dev_priv->drrs.dp; + if (!intel_dp) { + mutex_unlock(&dev_priv->drrs.mutex); + return; + } + + crtc = dp_to_dig_port(intel_dp)->base.base.crtc; + pipe = to_intel_crtc(crtc)->pipe; + + frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); + dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits; + + /* invalidate means busy screen hence upclock */ + if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) + intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, + drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); + + mutex_unlock(&dev_priv->drrs.mutex); +} + +/** + * intel_edp_drrs_flush - Restart Idleness DRRS + * @dev_priv: i915 device + * @frontbuffer_bits: frontbuffer plane tracking bits + * + * This function gets called every time rendering on the given planes has + * completed or flip on a crtc is completed. So DRRS should be upclocked + * (LOW_RR -> HIGH_RR). And also Idleness detection should be started again, + * if no other planes are dirty. + * + * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. + */ +void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits) +{ + struct intel_dp *intel_dp; + struct drm_crtc *crtc; + enum pipe pipe; + + if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED) + return; + + cancel_delayed_work(&dev_priv->drrs.work); + + mutex_lock(&dev_priv->drrs.mutex); + + intel_dp = dev_priv->drrs.dp; + if (!intel_dp) { + mutex_unlock(&dev_priv->drrs.mutex); + return; + } + + crtc = dp_to_dig_port(intel_dp)->base.base.crtc; + pipe = to_intel_crtc(crtc)->pipe; + + frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); + dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits; + + /* flush means busy screen hence upclock */ + if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) + intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, + drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); + + /* + * flush also means no more activity hence schedule downclock, if all + * other fbs are quiescent too + */ + if (!dev_priv->drrs.busy_frontbuffer_bits) + schedule_delayed_work(&dev_priv->drrs.work, + msecs_to_jiffies(1000)); + mutex_unlock(&dev_priv->drrs.mutex); +} + +/** + * intel_dp_drrs_init - Init basic DRRS work and mutex. + * @connector: eDP connector + * @fixed_mode: preferred mode of panel + * + * This function is called only once at driver load to initialize basic + * DRRS stuff. + * + * Returns: + * Downclock mode if panel supports it, else return NULL. + * DRRS support is determined by the presence of downclock mode (apart + * from VBT setting). + */ +struct drm_display_mode * +intel_dp_drrs_init(struct intel_connector *connector, + struct drm_display_mode *fixed_mode) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_display_mode *downclock_mode = NULL; + + INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work); + mutex_init(&dev_priv->drrs.mutex); + + if (DISPLAY_VER(dev_priv) <= 6) { + drm_dbg_kms(&dev_priv->drm, + "DRRS supported for Gen7 and above\n"); + return NULL; + } + + if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) { + drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n"); + return NULL; + } + + downclock_mode = intel_panel_edid_downclock_mode(connector, fixed_mode); + if (!downclock_mode) { + drm_dbg_kms(&dev_priv->drm, + "Downclock mode is not found. DRRS not supported\n"); + return NULL; + } + + dev_priv->drrs.type = dev_priv->vbt.drrs_type; + + dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR; + drm_dbg_kms(&dev_priv->drm, + "seamless DRRS supported for eDP panel.\n"); + return downclock_mode; +} diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h new file mode 100644 index 000000000000..ffa175b4cf4f --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_drrs.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2021 Intel Corporation + */ + +#ifndef __INTEL_DRRS_H__ +#define __INTEL_DRRS_H__ + +#include + +struct drm_i915_private; +struct intel_crtc_state; +struct intel_connector; +struct intel_dp; + +void intel_edp_drrs_enable(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +void intel_edp_drrs_disable(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +void intel_edp_drrs_update(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits); +void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits); +void intel_dp_drrs_compute_config(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + int output_bpp, bool constant_n); +struct drm_display_mode *intel_dp_drrs_init(struct intel_connector *connector, + struct drm_display_mode *fixed_mode); + +#endif /* __INTEL_DRRS_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index 8e75debcce1a..e4834d84ce5e 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -62,6 +62,7 @@ #include "intel_display_types.h" #include "intel_fbc.h" #include "intel_frontbuffer.h" +#include "intel_drrs.h" #include "intel_psr.h" /** -- cgit v1.2.3 From 3a3dd5342f32ddf6c41b17c1c9e125ffab92be70 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Fri, 27 Aug 2021 10:42:53 -0700 Subject: drm/i915/display: Renaming DRRS functions to intel_drrs_*() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We had a mix of intel_edp_drrs_*(), intel_dp_drrs_*() and intel_dp_set_drrs_state(), so properly renaming all functions to keep the same pattern. While at it, also dropping intel_dp_set_drrs_state from the documentation as it is a static function. v3: - dropping documentation style comment in static function (intel_drrs_set_state) Reviewed-by: Rodrigo Vivi Cc: Jani Nikula Cc: Rodrigo Vivi Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210827174253.51122-3-jose.souza@intel.com --- Documentation/gpu/i915.rst | 13 +-- drivers/gpu/drm/i915/display/intel_ddi.c | 6 +- .../gpu/drm/i915/display/intel_display_debugfs.c | 6 +- drivers/gpu/drm/i915/display/intel_dp.c | 6 +- drivers/gpu/drm/i915/display/intel_drrs.c | 103 +++++++++------------ drivers/gpu/drm/i915/display/intel_drrs.h | 30 +++--- drivers/gpu/drm/i915/display/intel_frontbuffer.c | 4 +- 7 files changed, 75 insertions(+), 93 deletions(-) (limited to 'drivers') diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst index 03021dfa0dd8..101dde3eb1ea 100644 --- a/Documentation/gpu/i915.rst +++ b/Documentation/gpu/i915.rst @@ -187,22 +187,19 @@ Display Refresh Rate Switching (DRRS) :doc: Display Refresh Rate Switching (DRRS) .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :functions: intel_dp_set_drrs_state + :functions: intel_drrs_enable .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :functions: intel_edp_drrs_enable + :functions: intel_drrs_disable .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :functions: intel_edp_drrs_disable + :functions: intel_drrs_invalidate .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :functions: intel_edp_drrs_invalidate + :functions: intel_drrs_flush .. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :functions: intel_edp_drrs_flush - -.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c - :functions: intel_dp_drrs_init + :functions: intel_drrs_init DPIO ---- diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 263bebabf2bc..23ef291f7b30 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3015,7 +3015,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state, if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink) intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); - intel_edp_drrs_enable(intel_dp, crtc_state); + intel_drrs_enable(intel_dp, crtc_state); if (crtc_state->has_audio) intel_audio_codec_enable(encoder, crtc_state, conn_state); @@ -3203,7 +3203,7 @@ static void intel_pre_disable_ddi(struct intel_atomic_state *state, return; intel_dp = enc_to_intel_dp(encoder); - intel_edp_drrs_disable(intel_dp, old_crtc_state); + intel_drrs_disable(intel_dp, old_crtc_state); intel_psr_disable(intel_dp, old_crtc_state); } @@ -3233,7 +3233,7 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state, intel_psr_update(intel_dp, crtc_state, conn_state); intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); - intel_edp_drrs_update(intel_dp, crtc_state); + intel_drrs_update(intel_dp, crtc_state); intel_backlight_update(state, encoder, crtc_state, conn_state); } diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index b136a0fc0963..ca819f9e353d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -2045,11 +2045,9 @@ static int i915_drrs_ctl_set(void *data, u64 val) intel_dp = enc_to_intel_dp(encoder); if (val) - intel_edp_drrs_enable(intel_dp, - crtc_state); + intel_drrs_enable(intel_dp, crtc_state); else - intel_edp_drrs_disable(intel_dp, - crtc_state); + intel_drrs_disable(intel_dp, crtc_state); } drm_connector_list_iter_end(&conn_iter); diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index e6f548ee1a45..64e8151d13a4 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1782,8 +1782,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, intel_vrr_compute_config(pipe_config, conn_state); intel_psr_compute_config(intel_dp, pipe_config); - intel_dp_drrs_compute_config(intel_dp, pipe_config, output_bpp, - constant_n); + intel_drrs_compute_config(intel_dp, pipe_config, output_bpp, + constant_n); intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state); intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state); @@ -4802,7 +4802,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, fixed_mode = intel_panel_edid_fixed_mode(intel_connector); if (fixed_mode) - downclock_mode = intel_dp_drrs_init(intel_connector, fixed_mode); + downclock_mode = intel_drrs_init(intel_connector, fixed_mode); /* multiply the mode clock and horizontal timings for MSO */ intel_edp_mso_mode_fixup(intel_connector, fixed_mode); diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c index be9b6d4482f0..a2b65eca1441 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.c +++ b/drivers/gpu/drm/i915/display/intel_drrs.c @@ -39,8 +39,8 @@ * no movement on screen, after a timeout of 1 second, a switch to low RR is * made. * - * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate() - * and intel_edp_drrs_flush() are called. + * For integration with frontbuffer tracking code, intel_drrs_invalidate() + * and intel_drrs_flush() are called. * * DRRS can be further extended to support other internal panels and also * the scenario of video playback wherein RR is set based on the rate @@ -48,9 +48,9 @@ */ void -intel_dp_drrs_compute_config(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - int output_bpp, bool constant_n) +intel_drrs_compute_config(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + int output_bpp, bool constant_n) { struct intel_connector *intel_connector = intel_dp->attached_connector; struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -62,7 +62,7 @@ intel_dp_drrs_compute_config(struct intel_dp *intel_dp, /* * DRRS and PSR can't be enable together, so giving preference to PSR * as it allows more power-savings by complete shutting down display, - * so to guarantee this, intel_dp_drrs_compute_config() must be called + * so to guarantee this, intel_drrs_compute_config() must be called * after intel_psr_compute_config(). */ if (pipe_config->has_psr) @@ -87,22 +87,9 @@ intel_dp_drrs_compute_config(struct intel_dp *intel_dp, pipe_config->dp_m2_n2.gmch_m *= pipe_config->splitter.link_count; } -/** - * intel_dp_set_drrs_state - program registers for RR switch to take effect - * @dev_priv: i915 device - * @crtc_state: a pointer to the active intel_crtc_state - * @refresh_rate: RR to be programmed - * - * This function gets called when refresh rate (RR) has to be changed from - * one frequency to another. Switches can be between high and low RR - * supported by the panel or to any other RR based on media playback (in - * this case, RR value needs to be passed from user space). - * - * The caller of this function needs to take a lock on dev_priv->drrs. - */ -static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv, - const struct intel_crtc_state *crtc_state, - int refresh_rate) +static void intel_drrs_set_state(struct drm_i915_private *dev_priv, + const struct intel_crtc_state *crtc_state, + int refresh_rate) { struct intel_dp *intel_dp = dev_priv->drrs.dp; struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -185,7 +172,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv, } static void -intel_edp_drrs_enable_locked(struct intel_dp *intel_dp) +intel_drrs_enable_locked(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -194,14 +181,14 @@ intel_edp_drrs_enable_locked(struct intel_dp *intel_dp) } /** - * intel_edp_drrs_enable - init drrs struct if supported + * intel_drrs_enable - init drrs struct if supported * @intel_dp: DP struct * @crtc_state: A pointer to the active crtc state. * * Initializes frontbuffer_bits and drrs.dp */ -void intel_edp_drrs_enable(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) +void intel_drrs_enable(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -217,15 +204,15 @@ void intel_edp_drrs_enable(struct intel_dp *intel_dp, goto unlock; } - intel_edp_drrs_enable_locked(intel_dp); + intel_drrs_enable_locked(intel_dp); unlock: mutex_unlock(&dev_priv->drrs.mutex); } static void -intel_edp_drrs_disable_locked(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) +intel_drrs_disable_locked(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -233,20 +220,20 @@ intel_edp_drrs_disable_locked(struct intel_dp *intel_dp, int refresh; refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode); - intel_dp_set_drrs_state(dev_priv, crtc_state, refresh); + intel_drrs_set_state(dev_priv, crtc_state, refresh); } dev_priv->drrs.dp = NULL; } /** - * intel_edp_drrs_disable - Disable DRRS + * intel_drrs_disable - Disable DRRS * @intel_dp: DP struct * @old_crtc_state: Pointer to old crtc_state. * */ -void intel_edp_drrs_disable(struct intel_dp *intel_dp, - const struct intel_crtc_state *old_crtc_state) +void intel_drrs_disable(struct intel_dp *intel_dp, + const struct intel_crtc_state *old_crtc_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -259,24 +246,24 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp, return; } - intel_edp_drrs_disable_locked(intel_dp, old_crtc_state); + intel_drrs_disable_locked(intel_dp, old_crtc_state); mutex_unlock(&dev_priv->drrs.mutex); cancel_delayed_work_sync(&dev_priv->drrs.work); } /** - * intel_edp_drrs_update - Update DRRS state + * intel_drrs_update - Update DRRS state * @intel_dp: Intel DP * @crtc_state: new CRTC state * * This function will update DRRS states, disabling or enabling DRRS when - * executing fastsets. For full modeset, intel_edp_drrs_disable() and - * intel_edp_drrs_enable() should be called instead. + * executing fastsets. For full modeset, intel_drrs_disable() and + * intel_drrs_enable() should be called instead. */ void -intel_edp_drrs_update(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) +intel_drrs_update(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -290,15 +277,15 @@ intel_edp_drrs_update(struct intel_dp *intel_dp, goto unlock; if (crtc_state->has_drrs) - intel_edp_drrs_enable_locked(intel_dp); + intel_drrs_enable_locked(intel_dp); else - intel_edp_drrs_disable_locked(intel_dp, crtc_state); + intel_drrs_disable_locked(intel_dp, crtc_state); unlock: mutex_unlock(&dev_priv->drrs.mutex); } -static void intel_edp_drrs_downclock_work(struct work_struct *work) +static void intel_drrs_downclock_work(struct work_struct *work) { struct drm_i915_private *dev_priv = container_of(work, typeof(*dev_priv), drrs.work.work); @@ -322,8 +309,8 @@ static void intel_edp_drrs_downclock_work(struct work_struct *work) if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) { struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc; - intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, - drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode)); + intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config, + drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode)); } unlock: @@ -331,7 +318,7 @@ unlock: } /** - * intel_edp_drrs_invalidate - Disable Idleness DRRS + * intel_drrs_invalidate - Disable Idleness DRRS * @dev_priv: i915 device * @frontbuffer_bits: frontbuffer plane tracking bits * @@ -340,8 +327,8 @@ unlock: * * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. */ -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits) +void intel_drrs_invalidate(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits) { struct intel_dp *intel_dp; struct drm_crtc *crtc; @@ -368,14 +355,14 @@ void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, /* invalidate means busy screen hence upclock */ if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) - intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, - drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); + intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config, + drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); mutex_unlock(&dev_priv->drrs.mutex); } /** - * intel_edp_drrs_flush - Restart Idleness DRRS + * intel_drrs_flush - Restart Idleness DRRS * @dev_priv: i915 device * @frontbuffer_bits: frontbuffer plane tracking bits * @@ -386,8 +373,8 @@ void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, * * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. */ -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits) +void intel_drrs_flush(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits) { struct intel_dp *intel_dp; struct drm_crtc *crtc; @@ -414,8 +401,8 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, /* flush means busy screen hence upclock */ if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) - intel_dp_set_drrs_state(dev_priv, to_intel_crtc(crtc)->config, - drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); + intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config, + drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); /* * flush also means no more activity hence schedule downclock, if all @@ -428,7 +415,7 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, } /** - * intel_dp_drrs_init - Init basic DRRS work and mutex. + * intel_drrs_init - Init basic DRRS work and mutex. * @connector: eDP connector * @fixed_mode: preferred mode of panel * @@ -441,13 +428,13 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, * from VBT setting). */ struct drm_display_mode * -intel_dp_drrs_init(struct intel_connector *connector, - struct drm_display_mode *fixed_mode) +intel_drrs_init(struct intel_connector *connector, + struct drm_display_mode *fixed_mode) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct drm_display_mode *downclock_mode = NULL; - INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work); + INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_drrs_downclock_work); mutex_init(&dev_priv->drrs.mutex); if (DISPLAY_VER(dev_priv) <= 6) { diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h index ffa175b4cf4f..73be7e9a4369 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.h +++ b/drivers/gpu/drm/i915/display/intel_drrs.h @@ -13,20 +13,20 @@ struct intel_crtc_state; struct intel_connector; struct intel_dp; -void intel_edp_drrs_enable(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); -void intel_edp_drrs_disable(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); -void intel_edp_drrs_update(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits); -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits); -void intel_dp_drrs_compute_config(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - int output_bpp, bool constant_n); -struct drm_display_mode *intel_dp_drrs_init(struct intel_connector *connector, - struct drm_display_mode *fixed_mode); +void intel_drrs_enable(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +void intel_drrs_disable(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +void intel_drrs_update(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +void intel_drrs_invalidate(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits); +void intel_drrs_flush(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits); +void intel_drrs_compute_config(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + int output_bpp, bool constant_n); +struct drm_display_mode *intel_drrs_init(struct intel_connector *connector, + struct drm_display_mode *fixed_mode); #endif /* __INTEL_DRRS_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index e4834d84ce5e..0492446cd04a 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -92,7 +92,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915, trace_intel_frontbuffer_flush(frontbuffer_bits, origin); might_sleep(); - intel_edp_drrs_flush(i915, frontbuffer_bits); + intel_drrs_flush(i915, frontbuffer_bits); intel_psr_flush(i915, frontbuffer_bits, origin); intel_fbc_flush(i915, frontbuffer_bits, origin); } @@ -181,7 +181,7 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front, might_sleep(); intel_psr_invalidate(i915, frontbuffer_bits, origin); - intel_edp_drrs_invalidate(i915, frontbuffer_bits); + intel_drrs_invalidate(i915, frontbuffer_bits); intel_fbc_invalidate(i915, frontbuffer_bits, origin); } -- cgit v1.2.3 From f7a8f9afe52bca9be5f73465d14145e70c4f5d9f Mon Sep 17 00:00:00 2001 From: Vandita Kulkarni Date: Thu, 5 Aug 2021 15:49:37 +0530 Subject: drm/i915/display: Update small joiner ram size Xelpd supports larger small joiner ram. Signed-off-by: Vandita Kulkarni Reviewed-by: Manasi Navare Link: https://patchwork.freedesktop.org/patch/msgid/20210805101937.14664-1-vandita.kulkarni@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 64e8151d13a4..4f2fd33529ca 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -531,7 +531,9 @@ u32 intel_dp_mode_to_fec_clock(u32 mode_clock) static int small_joiner_ram_size_bits(struct drm_i915_private *i915) { - if (DISPLAY_VER(i915) >= 11) + if (DISPLAY_VER(i915) >= 13) + return 17280 * 8; + else if (DISPLAY_VER(i915) >= 11) return 7680 * 8; else return 6144 * 8; -- cgit v1.2.3 From f87c46c43175d382f3f1e4d067be529a84c6fb7c Mon Sep 17 00:00:00 2001 From: Vandita Kulkarni Date: Thu, 26 Aug 2021 11:18:10 +0530 Subject: drm/i915/dsi/xelpd: Add WA to program LP to HS wakeup guardband Wa_16012360555 SW will have to program the "LP to HS Wakeup Guardband" field to account for the repeaters on the HS Request/Ready PPI signaling between the Display engine and the DPHY. v2: Fix build issue. v3: Align to new naming (Jani) Signed-off-by: Vandita Kulkarni Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210826054811.10572-2-vandita.kulkarni@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 23 +++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 8 ++++++++ 2 files changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 5a5e3689d027..a1e35180d5dd 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1271,6 +1271,26 @@ static void icl_apply_kvmr_pipe_a_wa(struct intel_encoder *encoder, IGNORE_KVMR_PIPE_A, enable ? IGNORE_KVMR_PIPE_A : 0); } + +/* + * Wa_16012360555:adl-p + * SW will have to program the "LP to HS Wakeup Guardband" + * to account for the repeaters on the HS Request/Ready + * PPI signaling between the Display engine and the DPHY. + */ +static void adlp_set_lp_hs_wakeup_gb(struct intel_encoder *encoder) +{ + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); + enum port port; + + if (DISPLAY_VER(i915) == 13) { + for_each_dsi_port(port, intel_dsi->ports) + intel_de_rmw(i915, TGL_DSI_CHKN_REG(port), + TGL_DSI_CHKN_LSHS_GB, 0x4); + } +} + static void gen11_dsi_enable(struct intel_atomic_state *state, struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, @@ -1284,6 +1304,9 @@ static void gen11_dsi_enable(struct intel_atomic_state *state, /* Wa_1409054076:icl,jsl,ehl */ icl_apply_kvmr_pipe_a_wa(encoder, crtc->pipe, true); + /* Wa_16012360555:adl-p */ + adlp_set_lp_hs_wakeup_gb(encoder); + /* step6d: enable dsi transcoder */ gen11_dsi_enable_transcoder(encoder); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a0c8110d4ca0..bd63760207b0 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -11628,6 +11628,14 @@ enum skl_power_gate { _ICL_DSI_IO_MODECTL_1) #define COMBO_PHY_MODE_DSI (1 << 0) +/* TGL DSI Chicken register */ +#define _TGL_DSI_CHKN_REG_0 0x6B0C0 +#define _TGL_DSI_CHKN_REG_1 0x6B8C0 +#define TGL_DSI_CHKN_REG(port) _MMIO_PORT(port, \ + _TGL_DSI_CHKN_REG_0, \ + _TGL_DSI_CHKN_REG_1) +#define TGL_DSI_CHKN_LSHS_GB REG_GENMASK(15, 12) + /* Display Stream Splitter Control */ #define DSS_CTL1 _MMIO(0x67400) #define SPLITTER_ENABLE (1 << 31) -- cgit v1.2.3 From 19ba2e8e2744fb39958a8581ed9dfdd1a322349c Mon Sep 17 00:00:00 2001 From: Vandita Kulkarni Date: Thu, 26 Aug 2021 11:18:11 +0530 Subject: drm/i915/dsi/xelpd: Enable mipi dsi support. Enable MIPI DSI support on ADL-P platform. The esc clock changes, WA changes are taken care in the previous patches. As per the Bspec the seq remains to be same as TGL. Signed-off-by: Vandita Kulkarni Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210826054811.10572-3-vandita.kulkarni@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 5560d2f4c352..1f447ba776c7 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -10853,6 +10853,7 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv) intel_ddi_init(dev_priv, PORT_TC2); intel_ddi_init(dev_priv, PORT_TC3); intel_ddi_init(dev_priv, PORT_TC4); + icl_dsi_init(dev_priv); } else if (IS_ALDERLAKE_S(dev_priv)) { intel_ddi_init(dev_priv, PORT_A); intel_ddi_init(dev_priv, PORT_TC1); -- cgit v1.2.3 From 802fd9613e1959942357d418c36b6ac01755c749 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Sep 2021 14:28:15 +0300 Subject: drm/i915/dp: fix DG2 max source rate check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Accidentally dropped the else in a rebase fail, causing the DG2 max rate to be overwritten later in the if ladder. Fixes: e752d1f9c14a ("drm/i915/dg2: add DG2 UHBR source rates") Cc: Manasi Navare Cc: Ville Syrjälä Reviewed-by: Imre Deak Reviewed-by: Manasi Navare Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210901112815.16498-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 4f2fd33529ca..81b7097c6ff1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -345,7 +345,7 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp) size = ARRAY_SIZE(icl_rates); if (IS_DG2(dev_priv)) max_rate = dg2_max_source_rate(intel_dp); - if (IS_JSL_EHL(dev_priv)) + else if (IS_JSL_EHL(dev_priv)) max_rate = ehl_max_source_rate(intel_dp); else max_rate = icl_max_source_rate(intel_dp); -- cgit v1.2.3 From 3a5f9281cfce3c332ea3d5aeb947da2a7177e02b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Aug 2021 15:53:40 +0300 Subject: drm/i915/debugfs: clean up LPSP status Clean up the LPSP status printout. No functional changes. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/c7c2db4e1434ed9a3545f2561a03dc593db5e674.1630327990.git.jani.nikula@intel.com --- .../gpu/drm/i915/display/intel_display_debugfs.c | 37 +++++++--------------- 1 file changed, 11 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index ca819f9e353d..a501c02da510 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -1324,9 +1324,6 @@ static int i915_drrs_status(struct seq_file *m, void *unused) return 0; } -#define LPSP_STATUS(COND) (COND ? seq_puts(m, "LPSP: enabled\n") : \ - seq_puts(m, "LPSP: disabled\n")) - static bool intel_lpsp_power_well_enabled(struct drm_i915_private *i915, enum i915_power_well_id power_well_id) @@ -1345,32 +1342,20 @@ intel_lpsp_power_well_enabled(struct drm_i915_private *i915, static int i915_lpsp_status(struct seq_file *m, void *unused) { struct drm_i915_private *i915 = node_to_i915(m->private); - - if (DISPLAY_VER(i915) >= 13) { - LPSP_STATUS(!intel_lpsp_power_well_enabled(i915, - SKL_DISP_PW_2)); + bool lpsp_enabled = false; + + if (DISPLAY_VER(i915) >= 13 || IS_DISPLAY_VER(i915, 9, 10)) { + lpsp_enabled = !intel_lpsp_power_well_enabled(i915, SKL_DISP_PW_2); + } else if (IS_DISPLAY_VER(i915, 11, 12)) { + lpsp_enabled = !intel_lpsp_power_well_enabled(i915, ICL_DISP_PW_3); + } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { + lpsp_enabled = !intel_lpsp_power_well_enabled(i915, HSW_DISP_PW_GLOBAL); + } else { + seq_puts(m, "LPSP: not supported\n"); return 0; } - switch (DISPLAY_VER(i915)) { - case 12: - case 11: - LPSP_STATUS(!intel_lpsp_power_well_enabled(i915, ICL_DISP_PW_3)); - break; - case 10: - case 9: - LPSP_STATUS(!intel_lpsp_power_well_enabled(i915, SKL_DISP_PW_2)); - break; - default: - /* - * Apart from HASWELL/BROADWELL other legacy platform doesn't - * support lpsp. - */ - if (IS_HASWELL(i915) || IS_BROADWELL(i915)) - LPSP_STATUS(!intel_lpsp_power_well_enabled(i915, HSW_DISP_PW_GLOBAL)); - else - seq_puts(m, "LPSP: not supported\n"); - } + seq_printf(m, "LPSP: %s\n", enableddisabled(lpsp_enabled)); return 0; } -- cgit v1.2.3 From 344c32783044e75be56cbc6e34719cb0852f0af9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Aug 2021 15:53:41 +0300 Subject: drm/i915/debugfs: clean up LPSP capable Clean up the LPSP capability printout. No functional changes. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/097390f12da8de57c9d52ad675309d0422dec8fb.1630327990.git.jani.nikula@intel.com --- .../gpu/drm/i915/display/intel_display_debugfs.c | 44 +++++++++------------- 1 file changed, 17 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index a501c02da510..68f4ba8c46e7 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -2224,14 +2224,12 @@ static int i915_psr_status_show(struct seq_file *m, void *data) } DEFINE_SHOW_ATTRIBUTE(i915_psr_status); -#define LPSP_CAPABLE(COND) (COND ? seq_puts(m, "LPSP: capable\n") : \ - seq_puts(m, "LPSP: incapable\n")) - static int i915_lpsp_capability_show(struct seq_file *m, void *data) { struct drm_connector *connector = m->private; struct drm_i915_private *i915 = to_i915(connector->dev); struct intel_encoder *encoder; + bool lpsp_capable = false; encoder = intel_attached_encoder(to_intel_connector(connector)); if (!encoder) @@ -2240,35 +2238,27 @@ static int i915_lpsp_capability_show(struct seq_file *m, void *data) if (connector->status != connector_status_connected) return -ENODEV; - if (DISPLAY_VER(i915) >= 13) { - LPSP_CAPABLE(encoder->port <= PORT_B); - return 0; - } - - switch (DISPLAY_VER(i915)) { - case 12: + if (DISPLAY_VER(i915) >= 13) + lpsp_capable = encoder->port <= PORT_B; + else if (DISPLAY_VER(i915) >= 12) /* * Actually TGL can drive LPSP on port till DDI_C * but there is no physical connected DDI_C on TGL sku's, * even driver is not initilizing DDI_C port for gen12. */ - LPSP_CAPABLE(encoder->port <= PORT_B); - break; - case 11: - LPSP_CAPABLE(connector->connector_type == DRM_MODE_CONNECTOR_DSI || - connector->connector_type == DRM_MODE_CONNECTOR_eDP); - break; - case 10: - case 9: - LPSP_CAPABLE(encoder->port == PORT_A && - (connector->connector_type == DRM_MODE_CONNECTOR_DSI || - connector->connector_type == DRM_MODE_CONNECTOR_eDP || - connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort)); - break; - default: - if (IS_HASWELL(i915) || IS_BROADWELL(i915)) - LPSP_CAPABLE(connector->connector_type == DRM_MODE_CONNECTOR_eDP); - } + lpsp_capable = encoder->port <= PORT_B; + else if (DISPLAY_VER(i915) == 11) + lpsp_capable = (connector->connector_type == DRM_MODE_CONNECTOR_DSI || + connector->connector_type == DRM_MODE_CONNECTOR_eDP); + else if (IS_DISPLAY_VER(i915, 9, 10)) + lpsp_capable = (encoder->port == PORT_A && + (connector->connector_type == DRM_MODE_CONNECTOR_DSI || + connector->connector_type == DRM_MODE_CONNECTOR_eDP || + connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort)); + else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) + lpsp_capable = connector->connector_type == DRM_MODE_CONNECTOR_eDP; + + seq_printf(m, "LPSP: %s\n", lpsp_capable ? "capable" : "incapable"); return 0; } -- cgit v1.2.3 From 6fd5a7c92eae512c6760391731ed1b4a9de1c4a6 Mon Sep 17 00:00:00 2001 From: Matt Atwood Date: Wed, 1 Sep 2021 21:33:58 +0530 Subject: drm/i915/dp: Fix eDP max rate for display 11+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_dp_set_source_rates() calls intel_dp_is_edp(), which is unsafe to use before intel_encoder->type is set. This causes incorrect max source rate to be used for display 11+. On EHL and JSL, HBR3 is used instead of HBR2, and on the other affected platforms, HBR2 is used instead of HBR3. Move intel_dp_set_source_rates() to after intel_encoder->type is set. Add comment to intel_dp_is_edp() describing unsafe usages. Cleanup intel_dp_init_connector() while at it. Note: The same change was originally added as commit 680c45c767f6 ("drm/i915/dp: Correctly advertise HBR3 for GEN11+"), but later reverted due to issues in CI in commit d3913019602e ("Revert "drm/i915/dp: Correctly advertise HBR3 for GEN11+""). Cc: Uma Shankar Cc: Imre Deak Cc: Ville Syrjälä Signed-off-by: Matt Atwood Signed-off-by: José Roberto de Souza Signed-off-by: Jani Nikula Signed-off-by: Animesh Manna Reviewed-by: Imre Deak Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20210901160402.24816-2-animesh.manna@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 81b7097c6ff1..322ffe7a75e3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -102,6 +102,8 @@ static const u8 valid_dsc_slicecount[] = {1, 2, 4}; * * If a CPU or PCH DP output is attached to an eDP panel, this function * will return true, and false otherwise. + * + * This function is not safe to use prior to encoder type being set. */ bool intel_dp_is_edp(struct intel_dp *intel_dp) { @@ -4899,8 +4901,6 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, intel_encoder->base.name)) return false; - intel_dp_set_source_rates(intel_dp); - intel_dp->reset_link_params = true; intel_dp->pps.pps_pipe = INVALID_PIPE; intel_dp->pps.active_pipe = INVALID_PIPE; @@ -4916,28 +4916,22 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, */ drm_WARN_ON(dev, intel_phy_is_tc(dev_priv, phy)); type = DRM_MODE_CONNECTOR_eDP; + intel_encoder->type = INTEL_OUTPUT_EDP; + + /* eDP only on port B and/or C on vlv/chv */ + if (drm_WARN_ON(dev, (IS_VALLEYVIEW(dev_priv) || + IS_CHERRYVIEW(dev_priv)) && + port != PORT_B && port != PORT_C)) + return false; } else { type = DRM_MODE_CONNECTOR_DisplayPort; } + intel_dp_set_source_rates(intel_dp); + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp); - /* - * For eDP we always set the encoder type to INTEL_OUTPUT_EDP, but - * for DP the encoder type can be set by the caller to - * INTEL_OUTPUT_UNKNOWN for DDI, so don't rewrite it. - */ - if (type == DRM_MODE_CONNECTOR_eDP) - intel_encoder->type = INTEL_OUTPUT_EDP; - - /* eDP only on port B and/or C on vlv/chv */ - if (drm_WARN_ON(dev, (IS_VALLEYVIEW(dev_priv) || - IS_CHERRYVIEW(dev_priv)) && - intel_dp_is_edp(intel_dp) && - port != PORT_B && port != PORT_C)) - return false; - drm_dbg_kms(&dev_priv->drm, "Adding %s connector on [ENCODER:%d:%s]\n", type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP", -- cgit v1.2.3 From 533140cb51ed42e97f1429d14ee2c8a93e5c10b1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Sep 2021 21:33:59 +0530 Subject: drm/i915/dp: fix TGL and ICL max source rates Combo phy is limited to 5.4 GHz on low-voltage SKUs. Combo phy DP is limited to 5.4 GHz, while combo phy eDP can do 8.1 GHz. Bspec: 20584, 20598, 49180, 49201 Cc: Imre Deak Signed-off-by: Jani Nikula Signed-off-by: Animesh Manna Reviewed-by: Imre Deak Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20210901160402.24816-3-animesh.manna@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 322ffe7a75e3..025ba35a2583 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -291,6 +291,15 @@ 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); @@ -298,7 +307,7 @@ static int icl_max_source_rate(struct intel_dp *intel_dp) enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port); if (intel_phy_is_combo(dev_priv, phy) && - !intel_dp_is_edp(intel_dp)) + (is_low_voltage_sku(dev_priv, phy) || !intel_dp_is_edp(intel_dp))) return 540000; return 810000; -- cgit v1.2.3 From 8ee8167771da66558cd71c8b59afd2a47160333f Mon Sep 17 00:00:00 2001 From: Animesh Manna Date: Wed, 1 Sep 2021 21:34:00 +0530 Subject: drm/i915/dp: fix EHL/JSL max source rates calculation Only higher voltage sku can support HBR3 so a condition check added in max source rate calculation for ehl/jsl. Bspec: 32247, 20598 Cc: Jani Nikula Cc: Imre Deak Signed-off-by: Animesh Manna Reviewed-by: Imre Deak Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20210901160402.24816-4-animesh.manna@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 025ba35a2583..5aabd8ec1015 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -315,7 +315,11 @@ static int icl_max_source_rate(struct intel_dp *intel_dp) static int ehl_max_source_rate(struct intel_dp *intel_dp) { - if (intel_dp_is_edp(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; -- cgit v1.2.3 From bc41f059a080e487c235b539f1e5cdbf605aba9f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Sep 2021 21:34:01 +0530 Subject: drm/i915/dp: fix DG1 and RKL max source rates Combo phy is limited to 5.4 GHz on low-voltage SKUs, but both eDP and DP can do 8.1 GHz on combo phy. Bspec: 49182, 49205, 49202 Cc: Imre Deak Signed-off-by: Jani Nikula Signed-off-by: Animesh Manna Reviewed-by: Imre Deak Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20210901160402.24816-5-animesh.manna@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 5aabd8ec1015..3fe1158706d5 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -325,6 +325,18 @@ static int ehl_max_source_rate(struct intel_dp *intel_dp) 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)) + return 540000; + + return 810000; +} + static void intel_dp_set_source_rates(struct intel_dp *intel_dp) { @@ -360,6 +372,8 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp) size = ARRAY_SIZE(icl_rates); if (IS_DG2(dev_priv)) max_rate = dg2_max_source_rate(intel_dp); + else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) + max_rate = dg1_max_source_rate(intel_dp); else if (IS_JSL_EHL(dev_priv)) max_rate = ehl_max_source_rate(intel_dp); else -- cgit v1.2.3 From 555ae26d51854503a80e77a781e25e32fcdc5c7c Mon Sep 17 00:00:00 2001 From: Animesh Manna Date: Wed, 1 Sep 2021 21:34:02 +0530 Subject: drm/i915/dp: fix for ADL_P/S dp/edp max source rates Added HBR3 support for ADL_P and ADL_S platform. Bspec: 53597, 53720, 49185, 55409 Cc: Jani Nikula Cc: Imre Deak Signed-off-by: Animesh Manna Reviewed-by: Imre Deak Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20210901160402.24816-6-animesh.manna@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 3fe1158706d5..d28bd8c4a8a5 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -372,7 +372,8 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp) size = ARRAY_SIZE(icl_rates); if (IS_DG2(dev_priv)) max_rate = dg2_max_source_rate(intel_dp); - else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) + 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); else if (IS_JSL_EHL(dev_priv)) max_rate = ehl_max_source_rate(intel_dp); -- cgit v1.2.3 From a9a56e7628d117c29c9b029342acc0748691680e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Sep 2021 19:09:59 +0300 Subject: drm/i915/bios: use hdmi level shift directly from child data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid extra caching of the data. Cc: José Roberto de Souza Reviewed-by: Ankit Nautiyal Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/ef22e40b01eab571ff0dc2bfffabb906d0151fb4.1630512523.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 26 +++++++++++++++----------- drivers/gpu/drm/i915/i915_drv.h | 4 ---- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index e86e6ed2d3bf..afb5fcd9dd0c 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -1868,6 +1868,14 @@ intel_bios_encoder_supports_edp(const struct intel_bios_encoder_data *devdata) devdata->child.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR; } +static int _intel_bios_hdmi_level_shift(const struct intel_bios_encoder_data *devdata) +{ + if (!devdata || devdata->i915->vbt.version < 158) + return -1; + + return devdata->child.hdmi_level_shifter_value; +} + static bool is_port_valid(struct drm_i915_private *i915, enum port port) { /* @@ -1887,7 +1895,7 @@ static void parse_ddi_port(struct drm_i915_private *i915, const struct child_device_config *child = &devdata->child; struct ddi_vbt_port_info *info; bool is_dvi, is_hdmi, is_dp, is_edp, is_crt, supports_typec_usb, supports_tbt; - int dp_boost_level, hdmi_boost_level; + int dp_boost_level, hdmi_boost_level, hdmi_level_shift; enum port port; port = dvo_port_to_port(i915, child->dvo_port); @@ -1949,15 +1957,11 @@ static void parse_ddi_port(struct drm_i915_private *i915, sanitize_aux_ch(i915, port); } - if (i915->vbt.version >= 158) { - /* The VBT HDMI level shift values match the table we have. */ - u8 hdmi_level_shift = child->hdmi_level_shifter_value; + hdmi_level_shift = _intel_bios_hdmi_level_shift(devdata); + if (hdmi_level_shift >= 0) { drm_dbg_kms(&i915->drm, "Port %c VBT HDMI level shift: %d\n", - port_name(port), - hdmi_level_shift); - info->hdmi_level_shift = hdmi_level_shift; - info->hdmi_level_shift_set = true; + port_name(port), hdmi_level_shift); } if (i915->vbt.version >= 204) { @@ -2950,13 +2954,13 @@ int intel_bios_max_tmds_clock(struct intel_encoder *encoder) return i915->vbt.ddi_port_info[encoder->port].max_tmds_clock; } +/* This is an index in the HDMI/DVI DDI buffer translation table, or -1 */ int intel_bios_hdmi_level_shift(struct intel_encoder *encoder) { struct drm_i915_private *i915 = to_i915(encoder->base.dev); - const struct ddi_vbt_port_info *info = - &i915->vbt.ddi_port_info[encoder->port]; + const struct intel_bios_encoder_data *devdata = i915->vbt.ddi_port_info[encoder->port].devdata; - return info->hdmi_level_shift_set ? info->hdmi_level_shift : -1; + return _intel_bios_hdmi_level_shift(devdata); } int intel_bios_encoder_dp_boost_level(const struct intel_bios_encoder_data *devdata) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index be2392bbcecc..67a9f07550d4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -641,10 +641,6 @@ struct ddi_vbt_port_info { int max_tmds_clock; - /* This is an index in the HDMI/DVI DDI buffer translation table. */ - u8 hdmi_level_shift; - u8 hdmi_level_shift_set:1; - u8 alternate_aux_channel; u8 alternate_ddc_pin; -- cgit v1.2.3 From 6ba699814537cfb41022805af111625013ce85eb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Sep 2021 19:10:00 +0300 Subject: drm/i915/bios: use max tmds clock directly from child data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid extra caching of the data. Cc: José Roberto de Souza Reviewed-by: Ankit Nautiyal Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/451082780a8befb2b27919439c901a2159ce173f.1630512523.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 52 +++++++++++++++---------------- drivers/gpu/drm/i915/i915_drv.h | 2 -- 2 files changed, 26 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index afb5fcd9dd0c..253a528ba61a 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -1876,6 +1876,24 @@ static int _intel_bios_hdmi_level_shift(const struct intel_bios_encoder_data *de return devdata->child.hdmi_level_shifter_value; } +static int _intel_bios_max_tmds_clock(const struct intel_bios_encoder_data *devdata) +{ + if (!devdata || devdata->i915->vbt.version < 204) + return 0; + + switch (devdata->child.hdmi_max_data_rate) { + default: + MISSING_CASE(devdata->child.hdmi_max_data_rate); + fallthrough; + case HDMI_MAX_DATA_RATE_PLATFORM: + return 0; + case HDMI_MAX_DATA_RATE_297: + return 297000; + case HDMI_MAX_DATA_RATE_165: + return 165000; + } +} + static bool is_port_valid(struct drm_i915_private *i915, enum port port) { /* @@ -1895,7 +1913,7 @@ static void parse_ddi_port(struct drm_i915_private *i915, const struct child_device_config *child = &devdata->child; struct ddi_vbt_port_info *info; bool is_dvi, is_hdmi, is_dp, is_edp, is_crt, supports_typec_usb, supports_tbt; - int dp_boost_level, hdmi_boost_level, hdmi_level_shift; + int dp_boost_level, hdmi_boost_level, hdmi_level_shift, max_tmds_clock; enum port port; port = dvo_port_to_port(i915, child->dvo_port); @@ -1964,30 +1982,11 @@ static void parse_ddi_port(struct drm_i915_private *i915, port_name(port), hdmi_level_shift); } - if (i915->vbt.version >= 204) { - int max_tmds_clock; - - switch (child->hdmi_max_data_rate) { - default: - MISSING_CASE(child->hdmi_max_data_rate); - fallthrough; - case HDMI_MAX_DATA_RATE_PLATFORM: - max_tmds_clock = 0; - break; - case HDMI_MAX_DATA_RATE_297: - max_tmds_clock = 297000; - break; - case HDMI_MAX_DATA_RATE_165: - max_tmds_clock = 165000; - break; - } - - if (max_tmds_clock) - drm_dbg_kms(&i915->drm, - "Port %c VBT HDMI max TMDS clock: %d kHz\n", - port_name(port), max_tmds_clock); - info->max_tmds_clock = max_tmds_clock; - } + max_tmds_clock = _intel_bios_max_tmds_clock(devdata); + if (max_tmds_clock) + drm_dbg_kms(&i915->drm, + "Port %c VBT HDMI max TMDS clock: %d kHz\n", + port_name(port), max_tmds_clock); /* I_boost config for SKL and above */ dp_boost_level = intel_bios_encoder_dp_boost_level(devdata); @@ -2950,8 +2949,9 @@ 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.ddi_port_info[encoder->port].devdata; - return i915->vbt.ddi_port_info[encoder->port].max_tmds_clock; + return _intel_bios_max_tmds_clock(devdata); } /* This is an index in the HDMI/DVI DDI buffer translation table, or -1 */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 67a9f07550d4..8b4a31265978 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -639,8 +639,6 @@ struct ddi_vbt_port_info { /* Non-NULL if port present. */ struct intel_bios_encoder_data *devdata; - int max_tmds_clock; - u8 alternate_aux_channel; u8 alternate_ddc_pin; -- cgit v1.2.3 From 72337aac0045ed3171710f6d1e42cae136ebef2e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Sep 2021 19:10:01 +0300 Subject: drm/i915/bios: use dp max link rate directly from child data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid extra caching of the data. Cc: José Roberto de Souza Reviewed-by: Ankit Nautiyal Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/5593ce81f6670dc33cf18fa284f8237c875ef404.1630512523.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 28 +++++++++++++++++----------- drivers/gpu/drm/i915/i915_drv.h | 2 -- 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 253a528ba61a..10b2beddc121 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -1815,6 +1815,17 @@ 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) + return 0; + + if (devdata->i915->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 void sanitize_device_type(struct intel_bios_encoder_data *devdata, enum port port) { @@ -1913,7 +1924,7 @@ static void parse_ddi_port(struct drm_i915_private *i915, const struct child_device_config *child = &devdata->child; struct ddi_vbt_port_info *info; bool is_dvi, is_hdmi, is_dp, is_edp, is_crt, supports_typec_usb, supports_tbt; - int dp_boost_level, hdmi_boost_level, hdmi_level_shift, max_tmds_clock; + int dp_boost_level, dp_max_link_rate, hdmi_boost_level, hdmi_level_shift, max_tmds_clock; enum port port; port = dvo_port_to_port(i915, child->dvo_port); @@ -2001,17 +2012,11 @@ static void parse_ddi_port(struct drm_i915_private *i915, "Port %c VBT HDMI boost level: %d\n", port_name(port), hdmi_boost_level); - /* DP max link rate for GLK+ */ - if (i915->vbt.version >= 216) { - if (i915->vbt.version >= 230) - info->dp_max_link_rate = parse_bdb_230_dp_max_link_rate(child->dp_max_link_rate); - else - info->dp_max_link_rate = parse_bdb_216_dp_max_link_rate(child->dp_max_link_rate); - + dp_max_link_rate = _intel_bios_dp_max_link_rate(devdata); + if (dp_max_link_rate) drm_dbg_kms(&i915->drm, "Port %c VBT DP max link rate: %d\n", - port_name(port), info->dp_max_link_rate); - } + port_name(port), dp_max_link_rate); info->devdata = devdata; } @@ -2982,8 +2987,9 @@ 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.ddi_port_info[encoder->port].devdata; - return i915->vbt.ddi_port_info[encoder->port].dp_max_link_rate; + return _intel_bios_dp_max_link_rate(devdata); } int intel_bios_alternate_ddc_pin(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8b4a31265978..586b5368d4fc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -641,8 +641,6 @@ struct ddi_vbt_port_info { u8 alternate_aux_channel; u8 alternate_ddc_pin; - - int dp_max_link_rate; /* 0 for not limited by VBT */ }; enum psr_lines_to_wait { -- cgit v1.2.3 From 11182986b4559978e6e2459da7059566af8356ca Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Sep 2021 19:10:02 +0300 Subject: drm/i915/bios: use alternate aux channel directly from child data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid extra caching of the data. v2: Check for !info->devdata in intel_bios_port_aux_ch() (Ankit) Cc: José Roberto de Souza Cc: Ankit Nautiyal Reviewed-by: Ankit Nautiyal Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/b1b9f0032b353c3279b4546d6acdb696fe0b6136.1630512523.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 26 ++++++++++++-------------- drivers/gpu/drm/i915/i915_drv.h | 1 - 2 files changed, 12 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 10b2beddc121..69d7da66f168 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -1565,28 +1565,29 @@ static enum port get_port_by_aux_ch(struct drm_i915_private *i915, u8 aux_ch) for_each_port(port) { info = &i915->vbt.ddi_port_info[port]; - if (info->devdata && aux_ch == info->alternate_aux_channel) + if (info->devdata && aux_ch == info->devdata->child.aux_channel) return port; } return PORT_NONE; } -static void sanitize_aux_ch(struct drm_i915_private *i915, +static void sanitize_aux_ch(struct intel_bios_encoder_data *devdata, enum port port) { - struct ddi_vbt_port_info *info = &i915->vbt.ddi_port_info[port]; + struct drm_i915_private *i915 = devdata->i915; + struct ddi_vbt_port_info *info; struct child_device_config *child; enum port p; - p = get_port_by_aux_ch(i915, info->alternate_aux_channel); + p = get_port_by_aux_ch(i915, devdata->child.aux_channel); if (p == PORT_NONE) return; drm_dbg_kms(&i915->drm, "port %c trying to use the same AUX CH (0x%x) as port %c, " "disabling port %c DP support\n", - port_name(port), info->alternate_aux_channel, + port_name(port), devdata->child.aux_channel, port_name(p), port_name(p)); /* @@ -1602,7 +1603,7 @@ static void sanitize_aux_ch(struct drm_i915_private *i915, child = &info->devdata->child; child->device_type &= ~DEVICE_TYPE_DISPLAYPORT_OUTPUT; - info->alternate_aux_channel = 0; + child->aux_channel = 0; } static const u8 cnp_ddc_pin_map[] = { @@ -1980,11 +1981,8 @@ static void parse_ddi_port(struct drm_i915_private *i915, } } - if (is_dp) { - info->alternate_aux_channel = child->aux_channel; - - sanitize_aux_ch(i915, port); - } + if (is_dp) + sanitize_aux_ch(devdata, port); hdmi_level_shift = _intel_bios_hdmi_level_shift(devdata); if (hdmi_level_shift >= 0) { @@ -2863,7 +2861,7 @@ enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *i915, &i915->vbt.ddi_port_info[port]; enum aux_ch aux_ch; - if (!info->alternate_aux_channel) { + if (!info->devdata || !info->devdata->child.aux_channel) { aux_ch = (enum aux_ch)port; drm_dbg_kms(&i915->drm, @@ -2879,7 +2877,7 @@ enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *i915, * ADL-S VBT uses PHY based mapping. Combo PHYs A,B,C,D,E * map to DDI A,TC1,TC2,TC3,TC4 respectively. */ - switch (info->alternate_aux_channel) { + switch (info->devdata->child.aux_channel) { case DP_AUX_A: aux_ch = AUX_CH_A; break; @@ -2940,7 +2938,7 @@ enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *i915, aux_ch = AUX_CH_I; break; default: - MISSING_CASE(info->alternate_aux_channel); + MISSING_CASE(info->devdata->child.aux_channel); aux_ch = AUX_CH_A; break; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 586b5368d4fc..032d59119407 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -639,7 +639,6 @@ struct ddi_vbt_port_info { /* Non-NULL if port present. */ struct intel_bios_encoder_data *devdata; - u8 alternate_aux_channel; u8 alternate_ddc_pin; }; -- cgit v1.2.3 From 9e1dbc1a84bdf1c0d4a03737c3e8007c4c43910a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Sep 2021 19:10:03 +0300 Subject: drm/i915/bios: move ddc pin mapping code next to ddc pin sanitize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move code around to avoid a forward declaration in the future. Cc: José Roberto de Souza Reviewed-by: Ankit Nautiyal Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/8c5f723e0b2d8ffd6f47068edf710947b45843be.1630512523.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 154 +++++++++++++++--------------- 1 file changed, 77 insertions(+), 77 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 69d7da66f168..b4113506b3b8 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -1501,6 +1501,83 @@ static u8 translate_iboost(u8 val) return mapping[val]; } +static const u8 cnp_ddc_pin_map[] = { + [0] = 0, /* N/A */ + [DDC_BUS_DDI_B] = GMBUS_PIN_1_BXT, + [DDC_BUS_DDI_C] = GMBUS_PIN_2_BXT, + [DDC_BUS_DDI_D] = GMBUS_PIN_4_CNP, /* sic */ + [DDC_BUS_DDI_F] = GMBUS_PIN_3_BXT, /* sic */ +}; + +static const u8 icp_ddc_pin_map[] = { + [ICL_DDC_BUS_DDI_A] = GMBUS_PIN_1_BXT, + [ICL_DDC_BUS_DDI_B] = GMBUS_PIN_2_BXT, + [TGL_DDC_BUS_DDI_C] = GMBUS_PIN_3_BXT, + [ICL_DDC_BUS_PORT_1] = GMBUS_PIN_9_TC1_ICP, + [ICL_DDC_BUS_PORT_2] = GMBUS_PIN_10_TC2_ICP, + [ICL_DDC_BUS_PORT_3] = GMBUS_PIN_11_TC3_ICP, + [ICL_DDC_BUS_PORT_4] = GMBUS_PIN_12_TC4_ICP, + [TGL_DDC_BUS_PORT_5] = GMBUS_PIN_13_TC5_TGP, + [TGL_DDC_BUS_PORT_6] = GMBUS_PIN_14_TC6_TGP, +}; + +static const u8 rkl_pch_tgp_ddc_pin_map[] = { + [ICL_DDC_BUS_DDI_A] = GMBUS_PIN_1_BXT, + [ICL_DDC_BUS_DDI_B] = GMBUS_PIN_2_BXT, + [RKL_DDC_BUS_DDI_D] = GMBUS_PIN_9_TC1_ICP, + [RKL_DDC_BUS_DDI_E] = GMBUS_PIN_10_TC2_ICP, +}; + +static const u8 adls_ddc_pin_map[] = { + [ICL_DDC_BUS_DDI_A] = GMBUS_PIN_1_BXT, + [ADLS_DDC_BUS_PORT_TC1] = GMBUS_PIN_9_TC1_ICP, + [ADLS_DDC_BUS_PORT_TC2] = GMBUS_PIN_10_TC2_ICP, + [ADLS_DDC_BUS_PORT_TC3] = GMBUS_PIN_11_TC3_ICP, + [ADLS_DDC_BUS_PORT_TC4] = GMBUS_PIN_12_TC4_ICP, +}; + +static const u8 gen9bc_tgp_ddc_pin_map[] = { + [DDC_BUS_DDI_B] = GMBUS_PIN_2_BXT, + [DDC_BUS_DDI_C] = GMBUS_PIN_9_TC1_ICP, + [DDC_BUS_DDI_D] = GMBUS_PIN_10_TC2_ICP, +}; + +static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin) +{ + const u8 *ddc_pin_map; + int n_entries; + + if (IS_ALDERLAKE_S(i915)) { + ddc_pin_map = adls_ddc_pin_map; + n_entries = ARRAY_SIZE(adls_ddc_pin_map); + } else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) { + return vbt_pin; + } else if (IS_ROCKETLAKE(i915) && INTEL_PCH_TYPE(i915) == PCH_TGP) { + ddc_pin_map = rkl_pch_tgp_ddc_pin_map; + n_entries = ARRAY_SIZE(rkl_pch_tgp_ddc_pin_map); + } else if (HAS_PCH_TGP(i915) && DISPLAY_VER(i915) == 9) { + ddc_pin_map = gen9bc_tgp_ddc_pin_map; + n_entries = ARRAY_SIZE(gen9bc_tgp_ddc_pin_map); + } else if (INTEL_PCH_TYPE(i915) >= PCH_ICP) { + ddc_pin_map = icp_ddc_pin_map; + n_entries = ARRAY_SIZE(icp_ddc_pin_map); + } else if (HAS_PCH_CNP(i915)) { + ddc_pin_map = cnp_ddc_pin_map; + n_entries = ARRAY_SIZE(cnp_ddc_pin_map); + } else { + /* Assuming direct map */ + return vbt_pin; + } + + if (vbt_pin < n_entries && ddc_pin_map[vbt_pin] != 0) + return ddc_pin_map[vbt_pin]; + + drm_dbg_kms(&i915->drm, + "Ignoring alternate pin: VBT claims DDC pin %d, which is not valid for this platform\n", + vbt_pin); + return 0; +} + static enum port get_port_by_ddc_pin(struct drm_i915_private *i915, u8 ddc_pin) { const struct ddi_vbt_port_info *info; @@ -1606,83 +1683,6 @@ static void sanitize_aux_ch(struct intel_bios_encoder_data *devdata, child->aux_channel = 0; } -static const u8 cnp_ddc_pin_map[] = { - [0] = 0, /* N/A */ - [DDC_BUS_DDI_B] = GMBUS_PIN_1_BXT, - [DDC_BUS_DDI_C] = GMBUS_PIN_2_BXT, - [DDC_BUS_DDI_D] = GMBUS_PIN_4_CNP, /* sic */ - [DDC_BUS_DDI_F] = GMBUS_PIN_3_BXT, /* sic */ -}; - -static const u8 icp_ddc_pin_map[] = { - [ICL_DDC_BUS_DDI_A] = GMBUS_PIN_1_BXT, - [ICL_DDC_BUS_DDI_B] = GMBUS_PIN_2_BXT, - [TGL_DDC_BUS_DDI_C] = GMBUS_PIN_3_BXT, - [ICL_DDC_BUS_PORT_1] = GMBUS_PIN_9_TC1_ICP, - [ICL_DDC_BUS_PORT_2] = GMBUS_PIN_10_TC2_ICP, - [ICL_DDC_BUS_PORT_3] = GMBUS_PIN_11_TC3_ICP, - [ICL_DDC_BUS_PORT_4] = GMBUS_PIN_12_TC4_ICP, - [TGL_DDC_BUS_PORT_5] = GMBUS_PIN_13_TC5_TGP, - [TGL_DDC_BUS_PORT_6] = GMBUS_PIN_14_TC6_TGP, -}; - -static const u8 rkl_pch_tgp_ddc_pin_map[] = { - [ICL_DDC_BUS_DDI_A] = GMBUS_PIN_1_BXT, - [ICL_DDC_BUS_DDI_B] = GMBUS_PIN_2_BXT, - [RKL_DDC_BUS_DDI_D] = GMBUS_PIN_9_TC1_ICP, - [RKL_DDC_BUS_DDI_E] = GMBUS_PIN_10_TC2_ICP, -}; - -static const u8 adls_ddc_pin_map[] = { - [ICL_DDC_BUS_DDI_A] = GMBUS_PIN_1_BXT, - [ADLS_DDC_BUS_PORT_TC1] = GMBUS_PIN_9_TC1_ICP, - [ADLS_DDC_BUS_PORT_TC2] = GMBUS_PIN_10_TC2_ICP, - [ADLS_DDC_BUS_PORT_TC3] = GMBUS_PIN_11_TC3_ICP, - [ADLS_DDC_BUS_PORT_TC4] = GMBUS_PIN_12_TC4_ICP, -}; - -static const u8 gen9bc_tgp_ddc_pin_map[] = { - [DDC_BUS_DDI_B] = GMBUS_PIN_2_BXT, - [DDC_BUS_DDI_C] = GMBUS_PIN_9_TC1_ICP, - [DDC_BUS_DDI_D] = GMBUS_PIN_10_TC2_ICP, -}; - -static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin) -{ - const u8 *ddc_pin_map; - int n_entries; - - if (IS_ALDERLAKE_S(i915)) { - ddc_pin_map = adls_ddc_pin_map; - n_entries = ARRAY_SIZE(adls_ddc_pin_map); - } else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) { - return vbt_pin; - } else if (IS_ROCKETLAKE(i915) && INTEL_PCH_TYPE(i915) == PCH_TGP) { - ddc_pin_map = rkl_pch_tgp_ddc_pin_map; - n_entries = ARRAY_SIZE(rkl_pch_tgp_ddc_pin_map); - } else if (HAS_PCH_TGP(i915) && DISPLAY_VER(i915) == 9) { - ddc_pin_map = gen9bc_tgp_ddc_pin_map; - n_entries = ARRAY_SIZE(gen9bc_tgp_ddc_pin_map); - } else if (INTEL_PCH_TYPE(i915) >= PCH_ICP) { - ddc_pin_map = icp_ddc_pin_map; - n_entries = ARRAY_SIZE(icp_ddc_pin_map); - } else if (HAS_PCH_CNP(i915)) { - ddc_pin_map = cnp_ddc_pin_map; - n_entries = ARRAY_SIZE(cnp_ddc_pin_map); - } else { - /* Assuming direct map */ - return vbt_pin; - } - - if (vbt_pin < n_entries && ddc_pin_map[vbt_pin] != 0) - return ddc_pin_map[vbt_pin]; - - drm_dbg_kms(&i915->drm, - "Ignoring alternate pin: VBT claims DDC pin %d, which is not valid for this platform\n", - vbt_pin); - return 0; -} - static enum port __dvo_port_to_port(int n_ports, int n_dvo, const int port_mapping[][3], u8 dvo_port) { -- cgit v1.2.3 From dab8477b032b31d07cf6ed5a07d47709c265b4bc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Sep 2021 19:10:04 +0300 Subject: drm/i915/bios: use ddc pin directly from child data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid extra caching of the data. This is slightly more subtle than one would think. For one thing, we explicitly ignore 0 value in child device ddc pin; this is specified as N/A and does not warrant a warning. For another, we start looking for ddc pin collisions in sanitize using unmapped pin numbering. v2: Check !devdata in intel_bios_alternate_ddc_pin() Cc: José Roberto de Souza Reviewed-by: Ankit Nautiyal Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/e1dbf7cbdd2191439e760ab9098242dcec5fbb2e.1630512523.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 49 ++++++++++++++++++------------- drivers/gpu/drm/i915/i915_drv.h | 2 -- 2 files changed, 28 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index b4113506b3b8..0c16a848a6e4 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -1589,28 +1589,43 @@ static enum port get_port_by_ddc_pin(struct drm_i915_private *i915, u8 ddc_pin) for_each_port(port) { info = &i915->vbt.ddi_port_info[port]; - if (info->devdata && ddc_pin == info->alternate_ddc_pin) + if (info->devdata && ddc_pin == info->devdata->child.ddc_pin) return port; } return PORT_NONE; } -static void sanitize_ddc_pin(struct drm_i915_private *i915, +static void sanitize_ddc_pin(struct intel_bios_encoder_data *devdata, enum port port) { - struct ddi_vbt_port_info *info = &i915->vbt.ddi_port_info[port]; + struct drm_i915_private *i915 = devdata->i915; + struct ddi_vbt_port_info *info; struct child_device_config *child; + u8 mapped_ddc_pin; enum port p; - p = get_port_by_ddc_pin(i915, info->alternate_ddc_pin); + if (!devdata->child.ddc_pin) + return; + + mapped_ddc_pin = map_ddc_pin(i915, devdata->child.ddc_pin); + if (!intel_gmbus_is_valid_pin(i915, mapped_ddc_pin)) { + drm_dbg_kms(&i915->drm, + "Port %c has invalid DDC pin %d, " + "sticking to defaults\n", + port_name(port), mapped_ddc_pin); + devdata->child.ddc_pin = 0; + return; + } + + p = get_port_by_ddc_pin(i915, devdata->child.ddc_pin); if (p == PORT_NONE) return; drm_dbg_kms(&i915->drm, "port %c trying to use the same DDC pin (0x%x) as port %c, " "disabling port %c DVI/HDMI support\n", - port_name(port), info->alternate_ddc_pin, + port_name(port), mapped_ddc_pin, port_name(p), port_name(p)); /* @@ -1628,7 +1643,7 @@ static void sanitize_ddc_pin(struct drm_i915_private *i915, child->device_type &= ~DEVICE_TYPE_TMDS_DVI_SIGNALING; child->device_type |= DEVICE_TYPE_NOT_HDMI_OUTPUT; - info->alternate_ddc_pin = 0; + child->ddc_pin = 0; } static enum port get_port_by_aux_ch(struct drm_i915_private *i915, u8 aux_ch) @@ -1966,20 +1981,8 @@ static void parse_ddi_port(struct drm_i915_private *i915, supports_typec_usb, supports_tbt, devdata->dsc != NULL); - if (is_dvi) { - u8 ddc_pin; - - ddc_pin = map_ddc_pin(i915, child->ddc_pin); - if (intel_gmbus_is_valid_pin(i915, ddc_pin)) { - info->alternate_ddc_pin = ddc_pin; - sanitize_ddc_pin(i915, port); - } else { - drm_dbg_kms(&i915->drm, - "Port %c has invalid DDC pin %d, " - "sticking to defaults\n", - port_name(port), ddc_pin); - } - } + if (is_dvi) + sanitize_ddc_pin(devdata, port); if (is_dp) sanitize_aux_ch(devdata, port); @@ -2993,8 +2996,12 @@ int intel_bios_dp_max_link_rate(struct intel_encoder *encoder) 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.ddi_port_info[encoder->port].devdata; + + if (!devdata || !devdata->child.ddc_pin) + return 0; - return i915->vbt.ddi_port_info[encoder->port].alternate_ddc_pin; + return map_ddc_pin(i915, devdata->child.ddc_pin); } bool intel_bios_encoder_supports_typec_usb(const struct intel_bios_encoder_data *devdata) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 032d59119407..744181cbe21c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -638,8 +638,6 @@ i915_fence_timeout(const struct drm_i915_private *i915) struct ddi_vbt_port_info { /* Non-NULL if port present. */ struct intel_bios_encoder_data *devdata; - - u8 alternate_ddc_pin; }; enum psr_lines_to_wait { -- cgit v1.2.3 From 5a449e5864ef7d05be7054299fce223856ba98a9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Sep 2021 19:10:05 +0300 Subject: drm/i915/bios: get rid of vbt ddi_port_info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can finally remove the extra caching in ddi_port_info. Good riddance. v2: Rebased Cc: José Roberto de Souza Reviewed-by: Ankit Nautiyal Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/f56e864d10bb3cbe616288450d92b56325d1df12.1630512523.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 63 ++++++++++++------------------- drivers/gpu/drm/i915/i915_drv.h | 7 +--- 2 files changed, 25 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 0c16a848a6e4..052f27c0fb0c 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -1580,16 +1580,16 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin) static enum port get_port_by_ddc_pin(struct drm_i915_private *i915, u8 ddc_pin) { - const struct ddi_vbt_port_info *info; + const struct intel_bios_encoder_data *devdata; enum port port; if (!ddc_pin) return PORT_NONE; for_each_port(port) { - info = &i915->vbt.ddi_port_info[port]; + devdata = i915->vbt.ports[port]; - if (info->devdata && ddc_pin == info->devdata->child.ddc_pin) + if (devdata && ddc_pin == devdata->child.ddc_pin) return port; } @@ -1600,7 +1600,6 @@ static void sanitize_ddc_pin(struct intel_bios_encoder_data *devdata, enum port port) { struct drm_i915_private *i915 = devdata->i915; - struct ddi_vbt_port_info *info; struct child_device_config *child; u8 mapped_ddc_pin; enum port p; @@ -1637,8 +1636,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 :( */ - info = &i915->vbt.ddi_port_info[p]; - child = &info->devdata->child; + child = &i915->vbt.ports[p]->child; child->device_type &= ~DEVICE_TYPE_TMDS_DVI_SIGNALING; child->device_type |= DEVICE_TYPE_NOT_HDMI_OUTPUT; @@ -1648,16 +1646,16 @@ static void sanitize_ddc_pin(struct intel_bios_encoder_data *devdata, static enum port get_port_by_aux_ch(struct drm_i915_private *i915, u8 aux_ch) { - const struct ddi_vbt_port_info *info; + const struct intel_bios_encoder_data *devdata; enum port port; if (!aux_ch) return PORT_NONE; for_each_port(port) { - info = &i915->vbt.ddi_port_info[port]; + devdata = i915->vbt.ports[port]; - if (info->devdata && aux_ch == info->devdata->child.aux_channel) + if (devdata && aux_ch == devdata->child.aux_channel) return port; } @@ -1668,7 +1666,6 @@ static void sanitize_aux_ch(struct intel_bios_encoder_data *devdata, enum port port) { struct drm_i915_private *i915 = devdata->i915; - struct ddi_vbt_port_info *info; struct child_device_config *child; enum port p; @@ -1691,8 +1688,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 :( */ - info = &i915->vbt.ddi_port_info[p]; - child = &info->devdata->child; + child = &i915->vbt.ports[p]->child; child->device_type &= ~DEVICE_TYPE_DISPLAYPORT_OUTPUT; child->aux_channel = 0; @@ -1938,7 +1934,6 @@ static void parse_ddi_port(struct drm_i915_private *i915, struct intel_bios_encoder_data *devdata) { const struct child_device_config *child = &devdata->child; - struct ddi_vbt_port_info *info; bool is_dvi, is_hdmi, is_dp, is_edp, is_crt, supports_typec_usb, supports_tbt; int dp_boost_level, dp_max_link_rate, hdmi_boost_level, hdmi_level_shift, max_tmds_clock; enum port port; @@ -1954,9 +1949,7 @@ static void parse_ddi_port(struct drm_i915_private *i915, return; } - info = &i915->vbt.ddi_port_info[port]; - - if (info->devdata) { + if (i915->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)); @@ -2019,7 +2012,7 @@ static void parse_ddi_port(struct drm_i915_private *i915, "Port %c VBT DP max link rate: %d\n", port_name(port), dp_max_link_rate); - info->devdata = devdata; + i915->vbt.ports[port] = devdata; } static void parse_ddi_ports(struct drm_i915_private *i915) @@ -2557,12 +2550,8 @@ bool intel_bios_is_port_present(struct drm_i915_private *i915, enum port port) [PORT_F] = { DVO_PORT_DPF, DVO_PORT_HDMIF, }, }; - if (HAS_DDI(i915)) { - const struct ddi_vbt_port_info *port_info = - &i915->vbt.ddi_port_info[port]; - - return port_info->devdata; - } + if (HAS_DDI(i915)) + return i915->vbt.ports[port]; /* FIXME maybe deal with port A as well? */ if (drm_WARN_ON(&i915->drm, @@ -2813,8 +2802,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.ddi_port_info[port].devdata; + const struct intel_bios_encoder_data *devdata = i915->vbt.ports[port]; if (drm_WARN_ON_ONCE(&i915->drm, !IS_GEMINILAKE(i915) && !IS_BROXTON(i915))) @@ -2834,8 +2822,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.ddi_port_info[port].devdata; + const struct intel_bios_encoder_data *devdata = i915->vbt.ports[port]; return HAS_LSPCON(i915) && devdata && devdata->child.lspcon; } @@ -2851,8 +2838,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.ddi_port_info[port].devdata; + const struct intel_bios_encoder_data *devdata = i915->vbt.ports[port]; return devdata && devdata->child.lane_reversal; } @@ -2860,11 +2846,10 @@ 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 ddi_vbt_port_info *info = - &i915->vbt.ddi_port_info[port]; + const struct intel_bios_encoder_data *devdata = i915->vbt.ports[port]; enum aux_ch aux_ch; - if (!info->devdata || !info->devdata->child.aux_channel) { + if (!devdata || !devdata->child.aux_channel) { aux_ch = (enum aux_ch)port; drm_dbg_kms(&i915->drm, @@ -2880,7 +2865,7 @@ enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *i915, * ADL-S VBT uses PHY based mapping. Combo PHYs A,B,C,D,E * map to DDI A,TC1,TC2,TC3,TC4 respectively. */ - switch (info->devdata->child.aux_channel) { + switch (devdata->child.aux_channel) { case DP_AUX_A: aux_ch = AUX_CH_A; break; @@ -2941,7 +2926,7 @@ enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *i915, aux_ch = AUX_CH_I; break; default: - MISSING_CASE(info->devdata->child.aux_channel); + MISSING_CASE(devdata->child.aux_channel); aux_ch = AUX_CH_A; break; } @@ -2955,7 +2940,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.ddi_port_info[encoder->port].devdata; + const struct intel_bios_encoder_data *devdata = i915->vbt.ports[encoder->port]; return _intel_bios_max_tmds_clock(devdata); } @@ -2964,7 +2949,7 @@ 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.ddi_port_info[encoder->port].devdata; + const struct intel_bios_encoder_data *devdata = i915->vbt.ports[encoder->port]; return _intel_bios_hdmi_level_shift(devdata); } @@ -2988,7 +2973,7 @@ 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.ddi_port_info[encoder->port].devdata; + const struct intel_bios_encoder_data *devdata = i915->vbt.ports[encoder->port]; return _intel_bios_dp_max_link_rate(devdata); } @@ -2996,7 +2981,7 @@ int intel_bios_dp_max_link_rate(struct intel_encoder *encoder) 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.ddi_port_info[encoder->port].devdata; + const struct intel_bios_encoder_data *devdata = i915->vbt.ports[encoder->port]; if (!devdata || !devdata->child.ddc_pin) return 0; @@ -3017,5 +3002,5 @@ bool intel_bios_encoder_supports_tbt(const struct intel_bios_encoder_data *devda const struct intel_bios_encoder_data * intel_bios_encoder_data_lookup(struct drm_i915_private *i915, enum port port) { - return i915->vbt.ddi_port_info[port].devdata; + return i915->vbt.ports[port]; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 744181cbe21c..309a483d1722 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -635,11 +635,6 @@ i915_fence_timeout(const struct drm_i915_private *i915) /* Amount of PSF GV points, BSpec precisely defines this */ #define I915_NUM_PSF_GV_POINTS 3 -struct ddi_vbt_port_info { - /* Non-NULL if port present. */ - struct intel_bios_encoder_data *devdata; -}; - enum psr_lines_to_wait { PSR_0_LINES_TO_WAIT = 0, PSR_1_LINE_TO_WAIT, @@ -720,7 +715,7 @@ struct intel_vbt_data { struct list_head display_devices; - struct ddi_vbt_port_info ddi_port_info[I915_MAX_PORTS]; + struct intel_bios_encoder_data *ports[I915_MAX_PORTS]; /* Non-NULL if port present. */ struct sdvo_device_mapping sdvo_mappings[2]; }; -- cgit v1.2.3 From c7c4dfb6fe704ae3cce1a8f438db75b1a0a9061f Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Fri, 3 Sep 2021 15:10:34 -0700 Subject: drm/i915/display: Some code improvements and code style fixes for DRRS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It started as a code style fix for the lines above 100 col but it turned out to simplifications to intel_drrs_set_state(). Now it receives the desired refresh rate type, high or low. v3: - Fixed the mode refesh rate debug message Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Reviewed-by: Gwan-gyeong Mun Link: https://patchwork.freedesktop.org/patch/msgid/20210903221036.34770-1-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_drrs.c | 58 +++++++++++-------------------- 1 file changed, 20 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c index a2b65eca1441..fa0411341a0d 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.c +++ b/drivers/gpu/drm/i915/display/intel_drrs.c @@ -89,19 +89,13 @@ intel_drrs_compute_config(struct intel_dp *intel_dp, static void intel_drrs_set_state(struct drm_i915_private *dev_priv, const struct intel_crtc_state *crtc_state, - int refresh_rate) + enum drrs_refresh_rate_type refresh_type) { struct intel_dp *intel_dp = dev_priv->drrs.dp; struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - enum drrs_refresh_rate_type index = DRRS_HIGH_RR; + struct drm_display_mode *mode; - if (refresh_rate <= 0) { - drm_dbg_kms(&dev_priv->drm, - "Refresh rate should be positive non-zero.\n"); - return; - } - - if (intel_dp == NULL) { + if (!intel_dp) { drm_dbg_kms(&dev_priv->drm, "DRRS not supported.\n"); return; } @@ -117,15 +111,8 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv, return; } - if (drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode) == - refresh_rate) - index = DRRS_LOW_RR; - - if (index == dev_priv->drrs.refresh_rate_type) { - drm_dbg_kms(&dev_priv->drm, - "DRRS requested for previously set RR...ignoring\n"); + if (refresh_type == dev_priv->drrs.refresh_rate_type) return; - } if (!crtc_state->hw.active) { drm_dbg_kms(&dev_priv->drm, @@ -134,7 +121,7 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv, } if (DISPLAY_VER(dev_priv) >= 8 && !IS_CHERRYVIEW(dev_priv)) { - switch (index) { + switch (refresh_type) { case DRRS_HIGH_RR: intel_dp_set_m_n(crtc_state, M1_N1); break; @@ -151,7 +138,7 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv, u32 val; val = intel_de_read(dev_priv, reg); - if (index > DRRS_HIGH_RR) { + if (refresh_type == DRRS_LOW_RR) { if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV; else @@ -165,10 +152,14 @@ static void intel_drrs_set_state(struct drm_i915_private *dev_priv, intel_de_write(dev_priv, reg, val); } - dev_priv->drrs.refresh_rate_type = index; + dev_priv->drrs.refresh_rate_type = refresh_type; + if (refresh_type == DRRS_LOW_RR) + mode = intel_dp->attached_connector->panel.downclock_mode; + else + mode = intel_dp->attached_connector->panel.fixed_mode; drm_dbg_kms(&dev_priv->drm, "eDP Refresh Rate set to : %dHz\n", - refresh_rate); + drm_mode_vrefresh(mode)); } static void @@ -216,13 +207,7 @@ intel_drrs_disable_locked(struct intel_dp *intel_dp, { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) { - int refresh; - - refresh = drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode); - intel_drrs_set_state(dev_priv, crtc_state, refresh); - } - + intel_drrs_set_state(dev_priv, crtc_state, DRRS_HIGH_RR); dev_priv->drrs.dp = NULL; } @@ -290,6 +275,7 @@ static void intel_drrs_downclock_work(struct work_struct *work) struct drm_i915_private *dev_priv = container_of(work, typeof(*dev_priv), drrs.work.work); struct intel_dp *intel_dp; + struct drm_crtc *crtc; mutex_lock(&dev_priv->drrs.mutex); @@ -306,12 +292,8 @@ static void intel_drrs_downclock_work(struct work_struct *work) if (dev_priv->drrs.busy_frontbuffer_bits) goto unlock; - if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) { - struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc; - - intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config, - drm_mode_vrefresh(intel_dp->attached_connector->panel.downclock_mode)); - } + crtc = dp_to_dig_port(intel_dp)->base.base.crtc; + intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config, DRRS_LOW_RR); unlock: mutex_unlock(&dev_priv->drrs.mutex); @@ -354,9 +336,9 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv, dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits; /* invalidate means busy screen hence upclock */ - if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) + if (frontbuffer_bits) intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config, - drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); + DRRS_HIGH_RR); mutex_unlock(&dev_priv->drrs.mutex); } @@ -400,9 +382,9 @@ void intel_drrs_flush(struct drm_i915_private *dev_priv, dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits; /* flush means busy screen hence upclock */ - if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) + if (frontbuffer_bits) intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config, - drm_mode_vrefresh(intel_dp->attached_connector->panel.fixed_mode)); + DRRS_HIGH_RR); /* * flush also means no more activity hence schedule downclock, if all -- cgit v1.2.3 From 6bd58b70af2f982344789f3f13c8decd42dc10dd Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Fri, 3 Sep 2021 15:10:35 -0700 Subject: drm/i915/display: Share code between intel_drrs_flush and intel_drrs_invalidate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both functions are pretty much equal, with minor changes that can be handled by a single parameter. v3: - not scheduling work from invalidate operations Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Reviewed-by: Gwan-gyeong Mun Link: https://patchwork.freedesktop.org/patch/msgid/20210903221036.34770-2-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_drrs.c | 82 ++++++++++++------------------- 1 file changed, 32 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c index fa0411341a0d..15e5f91cf331 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.c +++ b/drivers/gpu/drm/i915/display/intel_drrs.c @@ -299,18 +299,9 @@ unlock: mutex_unlock(&dev_priv->drrs.mutex); } -/** - * intel_drrs_invalidate - Disable Idleness DRRS - * @dev_priv: i915 device - * @frontbuffer_bits: frontbuffer plane tracking bits - * - * This function gets called everytime rendering on the given planes start. - * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR). - * - * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. - */ -void intel_drrs_invalidate(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits) +static void intel_drrs_frontbuffer_update(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits, + bool invalidate) { struct intel_dp *intel_dp; struct drm_crtc *crtc; @@ -333,16 +324,42 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv, pipe = to_intel_crtc(crtc)->pipe; frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); - dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits; + if (invalidate) + dev_priv->drrs.busy_frontbuffer_bits |= frontbuffer_bits; + else + dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits; - /* invalidate means busy screen hence upclock */ + /* flush/invalidate means busy screen hence upclock */ if (frontbuffer_bits) intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config, DRRS_HIGH_RR); + /* + * flush also means no more activity hence schedule downclock, if all + * other fbs are quiescent too + */ + if (!invalidate && !dev_priv->drrs.busy_frontbuffer_bits) + schedule_delayed_work(&dev_priv->drrs.work, + msecs_to_jiffies(1000)); mutex_unlock(&dev_priv->drrs.mutex); } +/** + * intel_drrs_invalidate - Disable Idleness DRRS + * @dev_priv: i915 device + * @frontbuffer_bits: frontbuffer plane tracking bits + * + * This function gets called everytime rendering on the given planes start. + * Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR). + * + * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. + */ +void intel_drrs_invalidate(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits) +{ + intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, true); +} + /** * intel_drrs_flush - Restart Idleness DRRS * @dev_priv: i915 device @@ -358,42 +375,7 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv, void intel_drrs_flush(struct drm_i915_private *dev_priv, unsigned int frontbuffer_bits) { - struct intel_dp *intel_dp; - struct drm_crtc *crtc; - enum pipe pipe; - - if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED) - return; - - cancel_delayed_work(&dev_priv->drrs.work); - - mutex_lock(&dev_priv->drrs.mutex); - - intel_dp = dev_priv->drrs.dp; - if (!intel_dp) { - mutex_unlock(&dev_priv->drrs.mutex); - return; - } - - crtc = dp_to_dig_port(intel_dp)->base.base.crtc; - pipe = to_intel_crtc(crtc)->pipe; - - frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe); - dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits; - - /* flush means busy screen hence upclock */ - if (frontbuffer_bits) - intel_drrs_set_state(dev_priv, to_intel_crtc(crtc)->config, - DRRS_HIGH_RR); - - /* - * flush also means no more activity hence schedule downclock, if all - * other fbs are quiescent too - */ - if (!dev_priv->drrs.busy_frontbuffer_bits) - schedule_delayed_work(&dev_priv->drrs.work, - msecs_to_jiffies(1000)); - mutex_unlock(&dev_priv->drrs.mutex); + intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, false); } /** -- cgit v1.2.3 From 0f3692b5e4c4d3baeb202d8e8d8846dafb525851 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Fri, 3 Sep 2021 15:10:36 -0700 Subject: drm/i915/display: Prepare DRRS for frontbuffer rendering drop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Frontbuffer rendering will be dropped for modern platforms but before that we to prepare DRRS for it. intel_drrs_flush and intel_drrs_invalidate will not be called for platforms that will not support frontbuffer rendering so DRRS needs another way to be notified about to page flips so it can change between high and low refresh rates as needed. Reviewed-by: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210903221036.34770-3-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 2 ++ drivers/gpu/drm/i915/display/intel_drrs.c | 9 +++++++++ drivers/gpu/drm/i915/display/intel_drrs.h | 4 ++++ 3 files changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 1f447ba776c7..134c792e1dbd 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -52,6 +52,7 @@ #include "display/intel_dp_mst.h" #include "display/intel_dpll.h" #include "display/intel_dpll_mgr.h" +#include "display/intel_drrs.h" #include "display/intel_dsi.h" #include "display/intel_dvo.h" #include "display/intel_fb.h" @@ -2379,6 +2380,7 @@ static void intel_post_plane_update(struct intel_atomic_state *state, hsw_enable_ips(new_crtc_state); intel_fbc_post_update(state, crtc); + intel_drrs_page_flip(state, crtc); if (needs_nv12_wa(old_crtc_state) && !needs_nv12_wa(new_crtc_state)) diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c index 15e5f91cf331..c1439fcb5a95 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.c +++ b/drivers/gpu/drm/i915/display/intel_drrs.c @@ -378,6 +378,15 @@ void intel_drrs_flush(struct drm_i915_private *dev_priv, intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, false); } +void intel_drrs_page_flip(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + unsigned int frontbuffer_bits = INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe); + + intel_drrs_frontbuffer_update(dev_priv, frontbuffer_bits, false); +} + /** * intel_drrs_init - Init basic DRRS work and mutex. * @connector: eDP connector diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h index 73be7e9a4369..9ec9c447211a 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.h +++ b/drivers/gpu/drm/i915/display/intel_drrs.h @@ -9,6 +9,8 @@ #include struct drm_i915_private; +struct intel_atomic_state; +struct intel_crtc; struct intel_crtc_state; struct intel_connector; struct intel_dp; @@ -23,6 +25,8 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv, unsigned int frontbuffer_bits); void intel_drrs_flush(struct drm_i915_private *dev_priv, unsigned int frontbuffer_bits); +void intel_drrs_page_flip(struct intel_atomic_state *state, + struct intel_crtc *crtc); void intel_drrs_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, int output_bpp, bool constant_n); -- cgit v1.2.3 From 43315f86a3a59255463d14042f2974d134710d9c Mon Sep 17 00:00:00 2001 From: Lee Shawn C Date: Wed, 8 Sep 2021 19:56:03 +0800 Subject: drm/i915/dsi: wait for header and payload credit available Driver should wait for free header or payload buffer in FIFO. It would be good to wait a while for HW to release credit before give it up to write to HW. Without sending initailize command sets completely. It would caused MIPI display can't light up properly. Cc: Ville Syrjala Cc: Jani Nikula Cc: Vandita Kulkarni Cc: Cooper Chiou Cc: William Tseng Signed-off-by: Lee Shawn C Reviewed-by: Vandita Kulkarni Signed-off-by: Vandita Kulkarni Link: https://patchwork.freedesktop.org/patch/msgid/20210908115607.9633-2-shawn.c.lee@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 40 ++++++++++++++++------------------ 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index a1e35180d5dd..44289003b709 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -55,20 +55,28 @@ static int payload_credits_available(struct drm_i915_private *dev_priv, >> FREE_PLOAD_CREDIT_SHIFT; } -static void wait_for_header_credits(struct drm_i915_private *dev_priv, - enum transcoder dsi_trans) +static bool wait_for_header_credits(struct drm_i915_private *dev_priv, + enum transcoder dsi_trans, int hdr_credit) { if (wait_for_us(header_credits_available(dev_priv, dsi_trans) >= - MAX_HEADER_CREDIT, 100)) + hdr_credit, 100)) { drm_err(&dev_priv->drm, "DSI header credits not released\n"); + return false; + } + + return true; } -static void wait_for_payload_credits(struct drm_i915_private *dev_priv, - enum transcoder dsi_trans) +static bool wait_for_payload_credits(struct drm_i915_private *dev_priv, + enum transcoder dsi_trans, int payld_credit) { if (wait_for_us(payload_credits_available(dev_priv, dsi_trans) >= - MAX_PLOAD_CREDIT, 100)) + payld_credit, 100)) { drm_err(&dev_priv->drm, "DSI payload credits not released\n"); + return false; + } + + return true; } static enum transcoder dsi_port_to_transcoder(enum port port) @@ -91,8 +99,8 @@ static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder) /* wait for header/payload credits to be released */ for_each_dsi_port(port, intel_dsi->ports) { dsi_trans = dsi_port_to_transcoder(port); - wait_for_header_credits(dev_priv, dsi_trans); - wait_for_payload_credits(dev_priv, dsi_trans); + wait_for_header_credits(dev_priv, dsi_trans, MAX_HEADER_CREDIT); + wait_for_payload_credits(dev_priv, dsi_trans, MAX_PLOAD_CREDIT); } /* send nop DCS command */ @@ -109,7 +117,7 @@ static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder) /* wait for header credits to be released */ for_each_dsi_port(port, intel_dsi->ports) { dsi_trans = dsi_port_to_transcoder(port); - wait_for_header_credits(dev_priv, dsi_trans); + wait_for_header_credits(dev_priv, dsi_trans, MAX_HEADER_CREDIT); } /* wait for LP TX in progress bit to be cleared */ @@ -127,18 +135,13 @@ static bool add_payld_to_queue(struct intel_dsi_host *host, const u8 *data, struct intel_dsi *intel_dsi = host->intel_dsi; struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); enum transcoder dsi_trans = dsi_port_to_transcoder(host->port); - int free_credits; int i, j; for (i = 0; i < len; i += 4) { u32 tmp = 0; - free_credits = payload_credits_available(dev_priv, dsi_trans); - if (free_credits < 1) { - drm_err(&dev_priv->drm, - "Payload credit not available\n"); + if (!wait_for_payload_credits(dev_priv, dsi_trans, 1)) return false; - } for (j = 0; j < min_t(u32, len - i, 4); j++) tmp |= *data++ << 8 * j; @@ -156,15 +159,10 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host, struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); enum transcoder dsi_trans = dsi_port_to_transcoder(host->port); u32 tmp; - int free_credits; /* check if header credit available */ - free_credits = header_credits_available(dev_priv, dsi_trans); - if (free_credits < 1) { - drm_err(&dev_priv->drm, - "send pkt header failed, not enough hdr credits\n"); + if (!wait_for_header_credits(dev_priv, dsi_trans, 1)) return -1; - } tmp = intel_de_read(dev_priv, DSI_CMD_TXHDR(dsi_trans)); -- cgit v1.2.3 From 5ebd50d3948ee596db02399a09b4561ed82aee57 Mon Sep 17 00:00:00 2001 From: Lee Shawn C Date: Wed, 8 Sep 2021 19:56:04 +0800 Subject: drm/i915/dsi: refine send MIPI DCS command sequence According to chapter "Sending Commands to the Panel" in bspec #29738 and #49188. If driver try to send DCS long pakcet, we have to program TX payload register at first. And configure TX header HW register later. DSC long packet would not be sent properly if we don't follow this sequence. Cc: Ville Syrjala Cc: Jani Nikula Cc: Vandita Kulkarni Cc: Cooper Chiou Cc: William Tseng Signed-off-by: Lee Shawn C Reviewed-by: Vandita Kulkarni Signed-off-by: Vandita Kulkarni Link: https://patchwork.freedesktop.org/patch/msgid/20210908115607.9633-3-shawn.c.lee@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 44289003b709..060bc8fb0d30 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1831,11 +1831,6 @@ static ssize_t gen11_dsi_host_transfer(struct mipi_dsi_host *host, if (msg->flags & MIPI_DSI_MSG_USE_LPM) enable_lpdt = true; - /* send packet header */ - ret = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt); - if (ret < 0) - return ret; - /* only long packet contains payload */ if (mipi_dsi_packet_format_is_long(msg->type)) { ret = dsi_send_pkt_payld(intel_dsi_host, dsi_pkt); @@ -1843,6 +1838,11 @@ static ssize_t gen11_dsi_host_transfer(struct mipi_dsi_host *host, return ret; } + /* send packet header */ + ret = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt); + if (ret < 0) + return ret; + //TODO: add payload receive code if needed ret = sizeof(dsi_pkt.header) + dsi_pkt.payload_length; -- cgit v1.2.3 From fe01883fdcefd09c7ceb91874c2f74ae074163d6 Mon Sep 17 00:00:00 2001 From: Lee Shawn C Date: Wed, 8 Sep 2021 19:56:05 +0800 Subject: drm/i915: Get proper min cdclk if vDSC enabled VDSC engine can process only 1 pixel per Cd clock. In case VDSC is used and max slice count == 1, max supported pixel clock should be 100% of CD clock. Then do min_cdclk and pixel clock comparison to get proper min cdclk. v2: - Check for dsc enable and slice count ==1 then allow to double confirm min cdclk value. Cc: Ville Syrjala Cc: Jani Nikula Cc: Vandita Kulkarni Cc: Cooper Chiou Cc: William Tseng Signed-off-by: Lee Shawn C Reviewed-by: Vandita Kulkarni Acked-by: Jani Nikula Signed-off-by: Vandita Kulkarni Link: https://patchwork.freedesktop.org/patch/msgid/20210908115607.9633-4-shawn.c.lee@intel.com --- drivers/gpu/drm/i915/display/intel_cdclk.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 34fa4130d5c4..9aec17b33819 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2139,6 +2139,16 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) /* Account for additional needs from the planes */ min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk); + /* + * VDSC engine can process only 1 pixel per Cd clock. + * In case VDSC is used and max slice count == 1, + * max supported pixel clock should be 100% of CD clock. + * Then do min_cdclk and pixel clock comparison to get cdclk. + */ + if (crtc_state->dsc.compression_enable && + crtc_state->dsc.slice_count == 1) + min_cdclk = max(min_cdclk, (int)crtc_state->pixel_rate); + /* * HACK. Currently for TGL platforms we calculate * min_cdclk initially based on pixel_rate divided -- cgit v1.2.3 From 84d3d71fe3630c757580dc0c4b7d1c141785fbcc Mon Sep 17 00:00:00 2001 From: Lee Shawn C Date: Wed, 8 Sep 2021 19:56:06 +0800 Subject: drm/i915/dsi: Retrieve max brightness level from VBT So far, DCS backlight driver hardcode (0xFF) for max brightness level. MIPI DCS spec allow max 0xFFFF for set_display_brightness (51h) command. And VBT brightness precision bits can support 8 ~ 16 bits. We should set correct precision bits in VBT that meet panel's request. Driver can refer to this setting then configure max brightness level in DCS backlight driver properly. v2: modify variable name brightness_precision_bits instead of max_brightness_level. v3: fix checkpatch warning. Cc: Ville Syrjala Cc: Jani Nikula Cc: Vandita Kulkarni Cc: Cooper Chiou Cc: William Tseng Signed-off-by: Lee Shawn C Reviewed-by: Jani Nikula Signed-off-by: Vandita Kulkarni Link: https://patchwork.freedesktop.org/patch/msgid/20210908115607.9633-5-shawn.c.lee@intel.com --- drivers/gpu/drm/i915/display/intel_bios.c | 3 +++ drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c | 10 ++++++++-- drivers/gpu/drm/i915/i915_drv.h | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 052f27c0fb0c..3c25926092de 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -483,6 +483,9 @@ parse_lfp_backlight(struct drm_i915_private *i915, level = 255; } i915->vbt.backlight.min_brightness = min_level; + + i915->vbt.backlight.brightness_precision_bits = + backlight_data->brightness_precision_bits[panel_type]; } else { level = backlight_data->level[panel_type]; i915->vbt.backlight.min_brightness = entry->min_brightness; diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c index 584c14c4cbd0..567c086602d5 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c @@ -147,10 +147,16 @@ static void dcs_enable_backlight(const struct intel_crtc_state *crtc_state, static int dcs_setup_backlight(struct intel_connector *connector, enum pipe unused) { + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_panel *panel = &connector->panel; - panel->backlight.max = PANEL_PWM_MAX_VALUE; - panel->backlight.level = PANEL_PWM_MAX_VALUE; + if (dev_priv->vbt.backlight.brightness_precision_bits > 8) + panel->backlight.max = (1 << dev_priv->vbt.backlight.brightness_precision_bits) - 1; + else + panel->backlight.max = PANEL_PWM_MAX_VALUE; + + panel->backlight.level = panel->backlight.max; return 0; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 309a483d1722..a8129153d1db 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -689,6 +689,7 @@ struct intel_vbt_data { struct { u16 pwm_freq_hz; + u16 brightness_precision_bits; bool present; bool active_low_pwm; u8 min_brightness; /* min_brightness/255 of max */ -- cgit v1.2.3 From ddb8cd4eee01049f34194affaf7d027bfa400e2c Mon Sep 17 00:00:00 2001 From: Lee Shawn C Date: Wed, 8 Sep 2021 19:56:07 +0800 Subject: drm/i915/dsi: Read/write proper brightness value via MIPI DCS command Driver has to swap the endian before send brightness level value to tcon. v2: Use __be16 instead of u16 to fix sparse warning. v3: Send one or two bytes brightness value depend on the precision. v4: get data length of brightness value more easily. Reported-by: kernel test robot Cc: Ville Syrjala Cc: Jani Nikula Cc: Vandita Kulkarni Cc: Cooper Chiou Cc: William Tseng Signed-off-by: Lee Shawn C Reviewed-by: Jani Nikula Signed-off-by: Vandita Kulkarni Link: https://patchwork.freedesktop.org/patch/msgid/20210908115607.9633-6-shawn.c.lee@intel.com --- .../gpu/drm/i915/display/intel_dsi_dcs_backlight.c | 23 +++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c index 567c086602d5..f61ed82e8867 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c @@ -47,33 +47,42 @@ static u32 dcs_get_backlight(struct intel_connector *connector, enum pipe unused { struct intel_encoder *encoder = intel_attached_encoder(connector); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); + struct intel_panel *panel = &connector->panel; struct mipi_dsi_device *dsi_device; - u8 data = 0; + u8 data[2] = {}; enum port port; + size_t len = panel->backlight.max > U8_MAX ? 2 : 1; - /* FIXME: Need to take care of 16 bit brightness level */ for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) { dsi_device = intel_dsi->dsi_hosts[port]->device; mipi_dsi_dcs_read(dsi_device, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, - &data, sizeof(data)); + &data, len); break; } - return data; + return (data[1] << 8) | data[0]; } static void dcs_set_backlight(const struct drm_connector_state *conn_state, u32 level) { struct intel_dsi *intel_dsi = enc_to_intel_dsi(to_intel_encoder(conn_state->best_encoder)); + struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel; struct mipi_dsi_device *dsi_device; - u8 data = level; + u8 data[2] = {}; enum port port; + size_t len = panel->backlight.max > U8_MAX ? 2 : 1; + + if (len == 1) { + data[0] = level; + } else { + data[0] = level >> 8; + data[1] = level; + } - /* FIXME: Need to take care of 16 bit brightness level */ for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) { dsi_device = intel_dsi->dsi_hosts[port]->device; mipi_dsi_dcs_write(dsi_device, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, - &data, sizeof(data)); + &data, len); } } -- cgit v1.2.3 From 58cfa3297aa0779e18b7cbb5e6c6301f97c5f776 Mon Sep 17 00:00:00 2001 From: Juston Li Date: Thu, 19 Aug 2021 11:48:33 -0700 Subject: drm/i915/hdcp: update cp_irq_count_cached in intel_dp_hdcp2_read_msg() Update cp_irq_count_cached when reading messages rather than when writing a message to make sure the value is up to date and not stale from a previously handled CP_IRQ. AKE flow doesn't always respond to a read with a ACK write msg. E.g. AKE_Send_Pairing_Info will "timeout" because we received a CP_IRQ for reading AKE_Send_H_Prime but no write occurred between that and reading AKE_Send_Pairing_Info so cp_irq_count_cached is stale causing the wait to return right away rather than waiting for a new CP_IRQ. Signed-off-by: Juston Li Acked-by: Anshuman Gupta Reviewed-by: Ramalingam C Tested-by: Suraj K Signed-off-by: Anshuman Gupta Link: https://patchwork.freedesktop.org/patch/msgid/20210819184835.1181323-2-juston.li@intel.com --- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c index d697d169e8c1..1d0096654776 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -446,8 +446,6 @@ static int intel_dp_hdcp2_write_msg(struct intel_digital_port *dig_port, void *buf, size_t size) { - struct intel_dp *dp = &dig_port->dp; - struct intel_hdcp *hdcp = &dp->attached_connector->hdcp; unsigned int offset; u8 *byte = buf; ssize_t ret, bytes_to_write, len; @@ -463,8 +461,6 @@ int intel_dp_hdcp2_write_msg(struct intel_digital_port *dig_port, bytes_to_write = size - 1; byte++; - hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count); - while (bytes_to_write) { len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ? DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write; @@ -530,6 +526,8 @@ int intel_dp_hdcp2_read_msg(struct intel_digital_port *dig_port, u8 msg_id, void *buf, size_t size) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_dp *dp = &dig_port->dp; + struct intel_hdcp *hdcp = &dp->attached_connector->hdcp; unsigned int offset; u8 *byte = buf; ssize_t ret, bytes_to_recv, len; @@ -546,6 +544,8 @@ int intel_dp_hdcp2_read_msg(struct intel_digital_port *dig_port, if (ret < 0) return ret; + hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count); + if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) { ret = get_receiver_id_list_size(dig_port); if (ret < 0) -- cgit v1.2.3 From 0f317ebb5f7cb2b1d9a538c9795962fabd6e180e Mon Sep 17 00:00:00 2001 From: Juston Li Date: Thu, 19 Aug 2021 11:48:34 -0700 Subject: drm/i915/hdcp: read RxInfo once when reading RepeaterAuth_Send_ReceiverID_List When reading RepeaterAuth_Send_ReceiverID_List, RxInfo is read by itself once to retrieve the DEVICE_COUNT to calculate the size of the ReceiverID list then read a second time as a part of reading ReceiverID list. On some MST docking stations, RxInfo can only be read after the RxStatus READY bit is set otherwise the read will return -EIO. The spec states that the READY bit should be cleared as soon as RxInfo has been read. In this case, the first RxInfo read succeeds but after the READY bit is cleared, the second read fails. Fix it by reading RxInfo once and storing it before reading the rest of RepeaterAuth_Send_ReceiverID_List once we know the size. Modify get_receiver_id_list_size() to read and store RxInfo in the message buffer and also parse DEVICE_COUNT so we know the size of RepeaterAuth_Send_ReceiverID_List. Afterwards, retrieve the rest of the message at the offset for seq_num_V. Changes in v5: - Don't change the offset define for Send_ReceiverID_List When reading, update message offset to account for RxInfo being read Changes in v4: - rebase and edit commit message Changes in v3: - remove comment Changes in v2: - remove unnecessary moving of drm_i915_private from patch 1 Signed-off-by: Juston Li Reviewed-by: Ramalingam C Reviewed-by: Anshuman Gupta Tested-by: Suraj K Signed-off-by: Anshuman Gupta Link: https://patchwork.freedesktop.org/patch/msgid/20210819184835.1181323-3-juston.li@intel.com --- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 31 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c index 1d0096654776..fbfb3c4d16bb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -496,11 +496,10 @@ get_rxinfo_hdcp_1_dev_downstream(struct intel_digital_port *dig_port, bool *hdcp } static -ssize_t get_receiver_id_list_size(struct intel_digital_port *dig_port) +ssize_t get_receiver_id_list_rx_info(struct intel_digital_port *dig_port, u32 *dev_cnt, u8 *byte) { - u8 rx_info[HDCP_2_2_RXINFO_LEN]; - u32 dev_cnt; ssize_t ret; + u8 *rx_info = byte; ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_HDCP_2_2_REG_RXINFO_OFFSET, @@ -508,15 +507,11 @@ ssize_t get_receiver_id_list_size(struct intel_digital_port *dig_port) if (ret != HDCP_2_2_RXINFO_LEN) return ret >= 0 ? -EIO : ret; - dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 | + *dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 | HDCP_2_2_DEV_COUNT_LO(rx_info[1])); - if (dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT) - dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT; - - ret = sizeof(struct hdcp2_rep_send_receiverid_list) - - HDCP_2_2_RECEIVER_IDS_MAX_LEN + - (dev_cnt * HDCP_2_2_RECEIVER_ID_LEN); + if (*dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT) + *dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT; return ret; } @@ -534,6 +529,7 @@ int intel_dp_hdcp2_read_msg(struct intel_digital_port *dig_port, const struct hdcp2_dp_msg_data *hdcp2_msg_data; ktime_t msg_end = ktime_set(0, 0); bool msg_expired; + u32 dev_cnt; hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id); if (!hdcp2_msg_data) @@ -546,17 +542,22 @@ int intel_dp_hdcp2_read_msg(struct intel_digital_port *dig_port, hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count); + /* DP adaptation msgs has no msg_id */ + byte++; + if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) { - ret = get_receiver_id_list_size(dig_port); + ret = get_receiver_id_list_rx_info(dig_port, &dev_cnt, byte); if (ret < 0) return ret; - size = ret; + byte += ret; + size = sizeof(struct hdcp2_rep_send_receiverid_list) - + HDCP_2_2_RXINFO_LEN - HDCP_2_2_RECEIVER_IDS_MAX_LEN + + (dev_cnt * HDCP_2_2_RECEIVER_ID_LEN); + offset += HDCP_2_2_RXINFO_LEN; } - bytes_to_recv = size - 1; - /* DP adaptation msgs has no msg_id */ - byte++; + bytes_to_recv = size - 1; while (bytes_to_recv) { len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ? -- cgit v1.2.3 From 3e31d057431a4638f891db303044f761809adb86 Mon Sep 17 00:00:00 2001 From: Juston Li Date: Thu, 19 Aug 2021 11:48:35 -0700 Subject: drm/i915/hdcp: reuse rx_info for mst stream type1 capability check On some MST docking stations, rx_info can only be read after RepeaterAuth_Send_ReceiverID_List and the RxStatus READY bit is set otherwise the read will return -EIO. This behavior causes the mst stream type1 capability test to fail to read rx_info and determine if the topology supports type1 and fallback to type0. To fix this, check for type1 capability when we receive rx_info within the AKE flow when we read RepeaterAuth_Send_ReceiverID_List instead of an explicit read just for type1 capability checking. This does require moving where we set stream_types to after hdcp2_authenticate_sink() when we get rx_info but this occurs before we do hdcp2_propagate_stream_management_info. Also, legacy HDCP 2.0/2.1 are not type 1 capable either so check for that as well. Changes since v5: - rename intel_set_stream_types() to intel_hdcp_prepare_streams() (Anshuman) Changes since v4: - move topology_type1_capable to intel_digital_port and rename it as hdcp_mst_type1_capable (Anshuman) - make a helper function intel_set_stream_types() to set stream types in hdcp2_authenticate_and_encrypt() (Anshuman) - break on failure to set stream types and retry instead of returning - remove no longer used declaration for streams_type1_capable() Changes since v2: - Remove no longer used variables in _intel_hdcp2_enable() Signed-off-by: Juston Li Reviewed-by: Ramalingam C Reviewed-by: Anshuman Gupta Tested-by: Suraj K Signed-off-by: Anshuman Gupta Link: https://patchwork.freedesktop.org/patch/msgid/20210819184835.1181323-4-juston.li@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 6 +- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 39 ------------- drivers/gpu/drm/i915/display/intel_hdcp.c | 64 ++++++++++++---------- 3 files changed, 38 insertions(+), 71 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index c7bcf9183447..e9e806d90eec 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -428,10 +428,6 @@ struct intel_hdcp_shim { int (*hdcp_2_2_capable)(struct intel_digital_port *dig_port, bool *capable); - /* Detects whether a HDCP 1.4 sink connected in MST topology */ - int (*streams_type1_capable)(struct intel_connector *connector, - bool *capable); - /* Write HDCP2.2 messages */ int (*write_2_2_msg)(struct intel_digital_port *dig_port, void *buf, size_t size); @@ -1684,6 +1680,8 @@ struct intel_digital_port { bool hdcp_auth_status; /* HDCP port data need to pass to security f/w */ struct hdcp_port_data hdcp_port_data; + /* Whether the MST topology supports HDCP Type 1 Content */ + bool hdcp_mst_type1_capable; void (*write_infoframe)(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c index fbfb3c4d16bb..540a669e01dd 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c @@ -478,23 +478,6 @@ int intel_dp_hdcp2_write_msg(struct intel_digital_port *dig_port, return size; } -static int -get_rxinfo_hdcp_1_dev_downstream(struct intel_digital_port *dig_port, bool *hdcp_1_x) -{ - u8 rx_info[HDCP_2_2_RXINFO_LEN]; - int ret; - - ret = drm_dp_dpcd_read(&dig_port->dp.aux, - DP_HDCP_2_2_REG_RXINFO_OFFSET, - (void *)rx_info, HDCP_2_2_RXINFO_LEN); - - if (ret != HDCP_2_2_RXINFO_LEN) - return ret >= 0 ? -EIO : ret; - - *hdcp_1_x = HDCP_2_2_HDCP1_DEVICE_CONNECTED(rx_info[1]) ? true : false; - return 0; -} - static ssize_t get_receiver_id_list_rx_info(struct intel_digital_port *dig_port, u32 *dev_cnt, u8 *byte) { @@ -665,27 +648,6 @@ int intel_dp_hdcp2_capable(struct intel_digital_port *dig_port, return 0; } -static -int intel_dp_mst_streams_type1_capable(struct intel_connector *connector, - bool *capable) -{ - struct intel_digital_port *dig_port = intel_attached_dig_port(connector); - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - int ret; - bool hdcp_1_x; - - ret = get_rxinfo_hdcp_1_dev_downstream(dig_port, &hdcp_1_x); - if (ret) { - drm_dbg_kms(&i915->drm, - "[%s:%d] failed to read RxInfo ret=%d\n", - connector->base.name, connector->base.base.id, ret); - return ret; - } - - *capable = !hdcp_1_x; - return 0; -} - static const struct intel_hdcp_shim intel_dp_hdcp_shim = { .write_an_aksv = intel_dp_hdcp_write_an_aksv, .read_bksv = intel_dp_hdcp_read_bksv, @@ -834,7 +796,6 @@ static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = { .stream_2_2_encryption = intel_dp_mst_hdcp2_stream_encryption, .check_2_2_link = intel_dp_mst_hdcp2_check_link, .hdcp_2_2_capable = intel_dp_hdcp2_capable, - .streams_type1_capable = intel_dp_mst_streams_type1_capable, .protocol = HDCP_PROTOCOL_DP, }; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index ebc2e32aec0b..9b9fd9d13043 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -33,21 +33,6 @@ static int intel_conn_to_vcpi(struct intel_connector *connector) return connector->port ? connector->port->vcpi.vcpi : 0; } -static bool -intel_streams_type1_capable(struct intel_connector *connector) -{ - const struct intel_hdcp_shim *shim = connector->hdcp.shim; - bool capable = false; - - if (!shim) - return capable; - - if (shim->streams_type1_capable) - shim->streams_type1_capable(connector, &capable); - - return capable; -} - /* * intel_hdcp_required_content_stream selects the most highest common possible HDCP * content_type for all streams in DP MST topology because security f/w doesn't @@ -86,7 +71,7 @@ intel_hdcp_required_content_stream(struct intel_digital_port *dig_port) if (conn_dig_port != dig_port) continue; - if (!enforce_type0 && !intel_streams_type1_capable(connector)) + if (!enforce_type0 && !dig_port->hdcp_mst_type1_capable) enforce_type0 = true; data->streams[data->k].stream_id = intel_conn_to_vcpi(connector); @@ -112,6 +97,25 @@ intel_hdcp_required_content_stream(struct intel_digital_port *dig_port) return 0; } +static int intel_hdcp_prepare_streams(struct intel_connector *connector) +{ + struct intel_digital_port *dig_port = intel_attached_dig_port(connector); + struct hdcp_port_data *data = &dig_port->hdcp_port_data; + struct intel_hdcp *hdcp = &connector->hdcp; + int ret; + + if (!intel_encoder_is_mst(intel_attached_encoder(connector))) { + data->k = 1; + data->streams[0].stream_type = hdcp->content_type; + } else { + ret = intel_hdcp_required_content_stream(dig_port); + if (ret) + return ret; + } + + return 0; +} + static bool intel_hdcp_is_ksv_valid(u8 *ksv) { @@ -1632,6 +1636,14 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) return -EINVAL; } + /* + * MST topology is not Type 1 capable if it contains a downstream + * device that is only HDCP 1.x or Legacy HDCP 2.0/2.1 compliant. + */ + dig_port->hdcp_mst_type1_capable = + !HDCP_2_2_HDCP1_DEVICE_CONNECTED(rx_info[1]) && + !HDCP_2_2_HDCP_2_0_REP_CONNECTED(rx_info[1]); + /* Converting and Storing the seq_num_v to local variable as DWORD */ seq_num_v = drm_hdcp_be24_to_cpu((const u8 *)msgs.recvid_list.seq_num_v); @@ -1876,6 +1888,14 @@ static int hdcp2_authenticate_and_encrypt(struct intel_connector *connector) for (i = 0; i < tries && !dig_port->hdcp_auth_status; i++) { ret = hdcp2_authenticate_sink(connector); if (!ret) { + ret = intel_hdcp_prepare_streams(connector); + if (ret) { + drm_dbg_kms(&i915->drm, + "Prepare streams failed.(%d)\n", + ret); + break; + } + ret = hdcp2_propagate_stream_management_info(connector); if (ret) { drm_dbg_kms(&i915->drm, @@ -1921,9 +1941,7 @@ static int hdcp2_authenticate_and_encrypt(struct intel_connector *connector) static int _intel_hdcp2_enable(struct intel_connector *connector) { - struct intel_digital_port *dig_port = intel_attached_dig_port(connector); struct drm_i915_private *i915 = to_i915(connector->base.dev); - struct hdcp_port_data *data = &dig_port->hdcp_port_data; struct intel_hdcp *hdcp = &connector->hdcp; int ret; @@ -1931,16 +1949,6 @@ static int _intel_hdcp2_enable(struct intel_connector *connector) connector->base.name, connector->base.base.id, hdcp->content_type); - /* Stream which requires encryption */ - if (!intel_encoder_is_mst(intel_attached_encoder(connector))) { - data->k = 1; - data->streams[0].stream_type = hdcp->content_type; - } else { - ret = intel_hdcp_required_content_stream(dig_port); - if (ret) - return ret; - } - ret = hdcp2_authenticate_and_encrypt(connector); if (ret) { drm_dbg_kms(&i915->drm, "HDCP2 Type%d Enabling Failed. (%d)\n", -- cgit v1.2.3 From a481d0e80eabbc3fed666103744aeaf47f63e708 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Tue, 17 Aug 2021 23:51:58 +0200 Subject: drm/i915: Associate ACPI connector nodes with connector entries (v2) On Intel platforms we know that the ACPI connector device node order will follow the order the driver (i915) decides. The decision is made using the custom Intel ACPI OpRegion (intel_opregion.c), though the driver does not actually know that the values it sends to ACPI there are used for associating a device node for the connectors, and assigning address for them. In reality that custom Intel ACPI OpRegion actually violates ACPI specification (we supply dynamic information to objects that are defined static, for example _ADR), however, it makes assigning correct connector node for a connector entry straightforward (it's one-on-one mapping). Changes in v2 (Hans de goede): - Take a reference on the fwnode which we assign to the connector, for ACPI nodes this is a no-op but in the future we may see software-fwnodes assigned to connectors which are ref-counted. Signed-off-by: Heikki Krogerus Tested-by: Heikki Krogerus Signed-off-by: Hans de Goede Reviewed-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20210817215201.795062-6-hdegoede@redhat.com --- drivers/gpu/drm/i915/display/intel_acpi.c | 46 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_acpi.h | 3 ++ drivers/gpu/drm/i915/display/intel_display.c | 1 + 3 files changed, 50 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c index 7cfe91fc05f2..72cac55c0f0f 100644 --- a/drivers/gpu/drm/i915/display/intel_acpi.c +++ b/drivers/gpu/drm/i915/display/intel_acpi.c @@ -282,3 +282,49 @@ void intel_acpi_device_id_update(struct drm_i915_private *dev_priv) } drm_connector_list_iter_end(&conn_iter); } + +/* NOTE: The connector order must be final before this is called. */ +void intel_acpi_assign_connector_fwnodes(struct drm_i915_private *i915) +{ + struct drm_connector_list_iter conn_iter; + struct drm_device *drm_dev = &i915->drm; + struct fwnode_handle *fwnode = NULL; + struct drm_connector *connector; + struct acpi_device *adev; + + drm_connector_list_iter_begin(drm_dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + /* Always getting the next, even when the last was not used. */ + fwnode = device_get_next_child_node(drm_dev->dev, fwnode); + if (!fwnode) + break; + + switch (connector->connector_type) { + case DRM_MODE_CONNECTOR_LVDS: + case DRM_MODE_CONNECTOR_eDP: + case DRM_MODE_CONNECTOR_DSI: + /* + * Integrated displays have a specific address 0x1f on + * most Intel platforms, but not on all of them. + */ + adev = acpi_find_child_device(ACPI_COMPANION(drm_dev->dev), + 0x1f, 0); + if (adev) { + connector->fwnode = + fwnode_handle_get(acpi_fwnode_handle(adev)); + break; + } + fallthrough; + default: + connector->fwnode = fwnode_handle_get(fwnode); + break; + } + } + drm_connector_list_iter_end(&conn_iter); + /* + * device_get_next_child_node() takes a reference on the fwnode, if + * we stopped iterating because we are out of connectors we need to + * put this, otherwise fwnode is NULL and the put is a no-op. + */ + fwnode_handle_put(fwnode); +} diff --git a/drivers/gpu/drm/i915/display/intel_acpi.h b/drivers/gpu/drm/i915/display/intel_acpi.h index 9f197401c313..4a760a2baed9 100644 --- a/drivers/gpu/drm/i915/display/intel_acpi.h +++ b/drivers/gpu/drm/i915/display/intel_acpi.h @@ -13,6 +13,7 @@ void intel_register_dsm_handler(void); void intel_unregister_dsm_handler(void); void intel_dsm_get_bios_data_funcs_supported(struct drm_i915_private *i915); void intel_acpi_device_id_update(struct drm_i915_private *i915); +void intel_acpi_assign_connector_fwnodes(struct drm_i915_private *i915); #else static inline void intel_register_dsm_handler(void) { return; } static inline void intel_unregister_dsm_handler(void) { return; } @@ -20,6 +21,8 @@ static inline void intel_dsm_get_bios_data_funcs_supported(struct drm_i915_private *i915) { return; } static inline void intel_acpi_device_id_update(struct drm_i915_private *i915) { return; } +static inline +void intel_acpi_assign_connector_fwnodes(struct drm_i915_private *i915) { return; } #endif /* CONFIG_ACPI */ #endif /* __INTEL_ACPI_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 134c792e1dbd..a7ca38613f89 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -11670,6 +11670,7 @@ int intel_modeset_init_nogem(struct drm_i915_private *i915) drm_modeset_lock_all(dev); intel_modeset_setup_hw_state(dev, dev->mode_config.acquire_ctx); + intel_acpi_assign_connector_fwnodes(i915); drm_modeset_unlock_all(dev); for_each_intel_crtc(dev, crtc) { -- cgit v1.2.3 From 4e79e12f5b5a00910fd7246bd02f23713babb1d1 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 17 Aug 2021 23:51:59 +0200 Subject: drm/i915/dp: Add support for out-of-bound hotplug events On some Cherry Trail devices, DisplayPort over Type-C is supported through a USB-PD microcontroller (e.g. a fusb302) + a mux to switch the superspeed datalines between USB-3 and DP (e.g. a pi3usb30532). The kernel in this case does the PD/alt-mode negotiation itself, rather then everything being handled in firmware. So the kernel itself picks an alt-mode, tells the Type-C "dongle" to switch to DP mode and sets the mux accordingly. In this setup the HPD pin is not connected, so the i915 driver needs to respond to a software event and scan the DP port for changes manually. This commit adds support for this. Together with the recent addition of DP alt-mode support to the Type-C subsystem this makes DP over Type-C work on these devices. Tested-by: Heikki Krogerus Signed-off-by: Hans de Goede Reviewed-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20210817215201.795062-7-hdegoede@redhat.com --- drivers/gpu/drm/i915/display/intel_dp.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index d28bd8c4a8a5..161c33b2c869 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4651,6 +4651,17 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn, return intel_modeset_synced_crtcs(state, conn); } +static void intel_dp_oob_hotplug_event(struct drm_connector *connector) +{ + struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector)); + struct drm_i915_private *i915 = to_i915(connector->dev); + + spin_lock_irq(&i915->irq_lock); + i915->hotplug.event_bits |= BIT(encoder->hpd_pin); + spin_unlock_irq(&i915->irq_lock); + queue_delayed_work(system_wq, &i915->hotplug.hotplug_work, 0); +} + static const struct drm_connector_funcs intel_dp_connector_funcs = { .force = intel_dp_force, .fill_modes = drm_helper_probe_single_connector_modes, @@ -4661,6 +4672,7 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = { .destroy = intel_connector_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, .atomic_duplicate_state = intel_digital_connector_duplicate_state, + .oob_hotplug_event = intel_dp_oob_hotplug_event, }; static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { -- cgit v1.2.3 From 37eab1fe61412d9f1dfc57c2f69a3f927b1c6c76 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 31 Aug 2021 17:17:32 +0300 Subject: drm/edid: abstract OUI conversion to 24-bit int Replace the open coded OUI conversion from three bytes to a 24-bit int, as we'll be adding one more user shortly. No functional changes. Side note: CTA-861 format has the OUI bytes in reverse order. Reviewed-by: Uma Shankar Acked-by: Maxime Ripard Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/2f43032d5f001510c7eed059321ceeb76d07a606.1630419362.git.jani.nikula@intel.com --- drivers/gpu/drm/drm_edid.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 6325877c5fd6..92974b1478bc 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -49,6 +49,11 @@ (((edid)->version > (maj)) || \ ((edid)->version == (maj) && (edid)->revision > (min))) +static int oui(u8 first, u8 second, u8 third) +{ + return (first << 16) | (second << 8) | third; +} + #define EDID_EST_TIMINGS 16 #define EDID_STD_TIMINGS 8 #define EDID_DETAILED_TIMINGS 4 @@ -4113,32 +4118,24 @@ cea_db_offsets(const u8 *cea, int *start, int *end) static bool cea_db_is_hdmi_vsdb(const u8 *db) { - int hdmi_id; - if (cea_db_tag(db) != VENDOR_BLOCK) return false; if (cea_db_payload_len(db) < 5) return false; - hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16); - - return hdmi_id == HDMI_IEEE_OUI; + return oui(db[3], db[2], db[1]) == HDMI_IEEE_OUI; } static bool cea_db_is_hdmi_forum_vsdb(const u8 *db) { - unsigned int oui; - if (cea_db_tag(db) != VENDOR_BLOCK) return false; if (cea_db_payload_len(db) < 7) return false; - oui = db[3] << 16 | db[2] << 8 | db[1]; - - return oui == HDMI_FORUM_IEEE_OUI; + return oui(db[3], db[2], db[1]) == HDMI_FORUM_IEEE_OUI; } static bool cea_db_is_vcdb(const u8 *db) -- cgit v1.2.3 From 18a9cbbe55801694b34328f6313d38c8f657966b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 31 Aug 2021 17:17:33 +0300 Subject: drm/edid: parse the DisplayID v2.0 VESA vendor block for MSO The VESA Organization Vendor-Specific Data Block, defined in VESA DisplayID Standard v2.0, specifies the eDP Multi-SST Operation (MSO) stream count and segment pixel overlap. DisplayID v1.3 has Appendix B: DisplayID as an EDID Extension, describing how DisplayID sections may be embedded in EDID extension blocks. DisplayID v2.0 does not have such a section, perhaps implying that DisplayID v2.0 data should not be included in EDID extensions, but rather in a "pure" DisplayID structure at its own DDC address pair A4h/A5h, as described in VESA E-DDC Standard v1.3 chapter 3. However, in practice, displays out in the field have embedded DisplayID v2.0 data blocks in EDID extensions, including, in particular, some eDP MSO displays, where a pure DisplayID structure is not available at all. Parse the MSO data from the DisplayID data block. Do it as part of drm_add_display_info(), extending it to parse also DisplayID data to avoid requiring extra calls to update the information. v2: Check for VESA OUI (Ville) Reviewed-by: Uma Shankar Acked-by: Maxime Ripard Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/73ca2887e7b37880690f5c9ba4594c9cd1170669.1630419362.git.jani.nikula@intel.com --- drivers/gpu/drm/drm_edid.c | 72 +++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 12 ++++++++ include/drm/drm_displayid.h | 13 ++++++++ 3 files changed, 97 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 92974b1478bc..c45c225267ca 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -28,6 +28,7 @@ * DEALINGS IN THE SOFTWARE. */ +#include #include #include #include @@ -5145,6 +5146,71 @@ void drm_get_monitor_range(struct drm_connector *connector, info->monitor_range.max_vfreq); } +static void drm_parse_vesa_mso_data(struct drm_connector *connector, + const struct displayid_block *block) +{ + struct displayid_vesa_vendor_specific_block *vesa = + (struct displayid_vesa_vendor_specific_block *)block; + struct drm_display_info *info = &connector->display_info; + + if (block->num_bytes < 3) { + drm_dbg_kms(connector->dev, "Unexpected vendor block size %u\n", + block->num_bytes); + return; + } + + if (oui(vesa->oui[0], vesa->oui[1], vesa->oui[2]) != VESA_IEEE_OUI) + return; + + if (sizeof(*vesa) != sizeof(*block) + block->num_bytes) { + drm_dbg_kms(connector->dev, "Unexpected VESA vendor block size\n"); + return; + } + + switch (FIELD_GET(DISPLAYID_VESA_MSO_MODE, vesa->mso)) { + default: + drm_dbg_kms(connector->dev, "Reserved MSO mode value\n"); + fallthrough; + case 0: + info->mso_stream_count = 0; + break; + case 1: + info->mso_stream_count = 2; /* 2 or 4 links */ + break; + case 2: + info->mso_stream_count = 4; /* 4 links */ + break; + } + + if (!info->mso_stream_count) { + info->mso_pixel_overlap = 0; + return; + } + + info->mso_pixel_overlap = FIELD_GET(DISPLAYID_VESA_MSO_OVERLAP, vesa->mso); + if (info->mso_pixel_overlap > 8) { + drm_dbg_kms(connector->dev, "Reserved MSO pixel overlap value %u\n", + info->mso_pixel_overlap); + info->mso_pixel_overlap = 8; + } + + drm_dbg_kms(connector->dev, "MSO stream count %u, pixel overlap %u\n", + info->mso_stream_count, info->mso_pixel_overlap); +} + +static void drm_update_mso(struct drm_connector *connector, const struct edid *edid) +{ + const struct displayid_block *block; + struct displayid_iter iter; + + displayid_iter_edid_begin(edid, &iter); + displayid_iter_for_each(block, &iter) { + if (block->tag == DATA_BLOCK_2_VENDOR_SPECIFIC) + drm_parse_vesa_mso_data(connector, block); + } + displayid_iter_end(&iter); +} + /* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset * all of the values which would have been set from EDID */ @@ -5168,6 +5234,9 @@ drm_reset_display_info(struct drm_connector *connector) info->non_desktop = 0; memset(&info->monitor_range, 0, sizeof(info->monitor_range)); + + info->mso_stream_count = 0; + info->mso_pixel_overlap = 0; } u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid) @@ -5246,6 +5315,9 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422) info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; + + drm_update_mso(connector, edid); + return quirks; } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 79fa34e5ccdb..379746d3266f 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -590,6 +590,18 @@ struct drm_display_info { * @monitor_range: Frequency range supported by monitor range descriptor */ struct drm_monitor_range_info monitor_range; + + /** + * @mso_stream_count: eDP Multi-SST Operation (MSO) stream count from + * the DisplayID VESA vendor block. 0 for conventional Single-Stream + * Transport (SST), or 2 or 4 MSO streams. + */ + u8 mso_stream_count; + + /** + * @mso_pixel_overlap: eDP MSO segment pixel overlap, 0-8 pixels. + */ + u8 mso_pixel_overlap; }; int drm_display_info_set_bus_formats(struct drm_display_info *info, diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h index 79771091771a..7ffbd9f7bfc7 100644 --- a/include/drm/drm_displayid.h +++ b/include/drm/drm_displayid.h @@ -23,9 +23,12 @@ #define DRM_DISPLAYID_H #include +#include struct edid; +#define VESA_IEEE_OUI 0x3a0292 + /* DisplayID Structure versions */ #define DISPLAY_ID_STRUCTURE_VER_12 0x12 #define DISPLAY_ID_STRUCTURE_VER_20 0x20 @@ -126,6 +129,16 @@ struct displayid_detailed_timing_block { struct displayid_detailed_timings_1 timings[]; }; +#define DISPLAYID_VESA_MSO_OVERLAP GENMASK(3, 0) +#define DISPLAYID_VESA_MSO_MODE GENMASK(6, 5) + +struct displayid_vesa_vendor_specific_block { + struct displayid_block base; + u8 oui[3]; + u8 data_structure_type; + u8 mso; +} __packed; + /* DisplayID iteration */ struct displayid_iter { const struct edid *edid; -- cgit v1.2.3 From 948b0ae65b7f1699438dc7235f347b3282b3e022 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 31 Aug 2021 17:17:34 +0300 Subject: drm/i915/edp: postpone MSO init until after EDID read MSO will require segment pixel overlap information from the EDID. Postpone MSO init until after we've read and cached the EDID. Reviewed-by: Uma Shankar Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/7a360fca01be0f971337b3635f4e4752922ffebe.1630419362.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 161c33b2c869..9015ed76d5fd 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2568,8 +2568,6 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp) */ intel_edp_init_source_oui(intel_dp, true); - intel_edp_mso_init(intel_dp); - return true; } @@ -4848,6 +4846,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, if (fixed_mode) downclock_mode = intel_drrs_init(intel_connector, fixed_mode); + /* MSO requires information from the EDID */ + intel_edp_mso_init(intel_dp); + /* multiply the mode clock and horizontal timings for MSO */ intel_edp_mso_mode_fixup(intel_connector, fixed_mode); intel_edp_mso_mode_fixup(intel_connector, downclock_mode); -- cgit v1.2.3 From 185667c2986bf431d7a37968d51f94b09e48ca0e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 31 Aug 2021 17:17:35 +0300 Subject: drm/i915/edp: use MSO pixel overlap from DisplayID data Now that we have MSO pixel overlap in display info, use it. Reviewed-by: Uma Shankar Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/87d8d80ba205eb2ecb50f613219e0a821a842616.1630419362.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 9015ed76d5fd..2db606ad59a2 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2452,6 +2452,8 @@ static void intel_edp_mso_mode_fixup(struct intel_connector *connector, static void intel_edp_mso_init(struct intel_dp *intel_dp) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct intel_connector *connector = intel_dp->attached_connector; + struct drm_display_info *info = &connector->base.display_info; u8 mso; if (intel_dp->edp_dpcd[0] < DP_EDP_14) @@ -2470,8 +2472,9 @@ static void intel_edp_mso_init(struct intel_dp *intel_dp) } if (mso) { - drm_dbg_kms(&i915->drm, "Sink MSO %ux%u configuration\n", - mso, drm_dp_max_lane_count(intel_dp->dpcd) / mso); + drm_dbg_kms(&i915->drm, "Sink MSO %ux%u configuration, pixel overlap %u\n", + mso, drm_dp_max_lane_count(intel_dp->dpcd) / mso, + info->mso_pixel_overlap); if (!HAS_MSO(i915)) { drm_err(&i915->drm, "No source MSO support, disabling\n"); mso = 0; @@ -2479,7 +2482,7 @@ static void intel_edp_mso_init(struct intel_dp *intel_dp) } intel_dp->mso_link_count = mso; - intel_dp->mso_pixel_overlap = 0; /* FIXME: read from DisplayID v2.0 */ + intel_dp->mso_pixel_overlap = mso ? info->mso_pixel_overlap : 0; } static bool -- cgit v1.2.3 From e0ccf1d6f1ef46456ff6d3744afb6a105a516817 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 13 Sep 2021 17:44:27 +0300 Subject: drm/i915: Extract intel_dp_need_bigjoiner() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suck the "do we need bigjoiner?" checks into a helper instead of duplicating them in two differentt places. v2: s/use/need/ (Jani) Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210913144440.23008-4-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 2db606ad59a2..3e7236b07773 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -805,6 +805,17 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector, return MODE_OK; } +static bool intel_dp_need_bigjoiner(struct intel_dp *intel_dp, + int hdisplay, int clock) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + + if (!intel_dp_can_bigjoiner(intel_dp)) + return false; + + return clock > i915->max_dotclk_freq || hdisplay > 5120; +} + static enum drm_mode_status intel_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) @@ -840,8 +851,7 @@ intel_dp_mode_valid(struct drm_connector *connector, if (mode->clock < 10000) return MODE_CLOCK_LOW; - if ((target_clock > max_dotclk || mode->hdisplay > 5120) && - intel_dp_can_bigjoiner(intel_dp)) { + if (intel_dp_need_bigjoiner(intel_dp, mode->hdisplay, target_clock)) { bigjoiner = true; max_dotclk *= 2; } @@ -1457,9 +1467,8 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, limits.max_lane_count, limits.max_rate, limits.max_bpp, adjusted_mode->crtc_clock); - if ((adjusted_mode->crtc_clock > i915->max_dotclk_freq || - adjusted_mode->crtc_hdisplay > 5120) && - intel_dp_can_bigjoiner(intel_dp)) + if (intel_dp_need_bigjoiner(intel_dp, adjusted_mode->crtc_hdisplay, + adjusted_mode->crtc_clock)) pipe_config->bigjoiner = true; /* -- cgit v1.2.3 From 555ec52127f9f09cae798ae66c82d017144743f0 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 13 Sep 2021 17:44:28 +0300 Subject: drm/i915: Flatten hsw_crtc_compute_clock() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hsw_crtc_compute_clock() has become spaghetti. Flatten it a bit to make it at least semi-legible. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210913144440.23008-5-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dpll.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 210f91f4a576..ace9157a1c30 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -937,16 +937,18 @@ static int hsw_crtc_compute_clock(struct intel_crtc_state *crtc_state) struct intel_encoder *encoder = intel_get_crtc_new_encoder(state, crtc_state); - if (IS_DG2(dev_priv)) { + if (IS_DG2(dev_priv)) return intel_mpllb_calc_state(crtc_state, encoder); - } else if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) || - DISPLAY_VER(dev_priv) >= 11) { - if (!intel_reserve_shared_dplls(state, crtc, encoder)) { - drm_dbg_kms(&dev_priv->drm, - "failed to find PLL for pipe %c\n", - pipe_name(crtc->pipe)); - return -EINVAL; - } + + if (DISPLAY_VER(dev_priv) < 11 && + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) + return 0; + + if (!intel_reserve_shared_dplls(state, crtc, encoder)) { + drm_dbg_kms(&dev_priv->drm, + "failed to find PLL for pipe %c\n", + pipe_name(crtc->pipe)); + return -EINVAL; } return 0; -- cgit v1.2.3 From 8c66081b0b32a5fca6791ee09ccf0e6ef35acce4 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 13 Sep 2021 17:44:29 +0300 Subject: drm/i915: s/pipe/transcoder/ when dealing with PIPECONF/TRANSCONF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PIPECONF becamse TRANSCONF when HSW introduced the EDP transcoder. Bigjoiner is making life even more confusing by introducing a N:1 relationship between pipes and transcoders. In that case we only enable/configure the transcoder corresponding to the master pipe. Let's do some renames to make it clear we're dealing with the transcoder rather than pipe when it comes to PIPECONF/TRANSCONF. I decided to leave the _cpu_ part out from the function/macro names since the PCH transcoder related stuff already has a _pch_ in their name. So shouldn't be possible to confuse them. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210913144440.23008-6-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/g4x_dp.c | 4 ++-- drivers/gpu/drm/i915/display/intel_crt.c | 4 ++-- drivers/gpu/drm/i915/display/intel_ddi.c | 4 ++-- drivers/gpu/drm/i915/display/intel_display.c | 28 ++++++++++++++-------------- drivers/gpu/drm/i915/display/intel_display.h | 12 ++++++------ drivers/gpu/drm/i915/display/intel_dp_mst.c | 4 ++-- drivers/gpu/drm/i915/display/intel_dpll.c | 12 ++++++------ drivers/gpu/drm/i915/display/intel_fdi.c | 2 +- drivers/gpu/drm/i915/display/intel_tv.c | 2 +- 9 files changed, 36 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 9577f6843f79..8e0620ae2ed1 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -211,7 +211,7 @@ static void ilk_edp_pll_on(struct intel_dp *intel_dp, struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder); + assert_transcoder_disabled(dev_priv, pipe_config->cpu_transcoder); assert_dp_port_disabled(intel_dp); assert_edp_pll_disabled(dev_priv); @@ -251,7 +251,7 @@ static void ilk_edp_pll_off(struct intel_dp *intel_dp, struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - assert_pipe_disabled(dev_priv, old_crtc_state->cpu_transcoder); + assert_transcoder_disabled(dev_priv, old_crtc_state->cpu_transcoder); assert_dp_port_disabled(intel_dp); assert_edp_pll_enabled(dev_priv); diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index 408f82b0dc7d..1c161eeed82f 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -251,7 +251,7 @@ static void hsw_post_disable_crt(struct intel_atomic_state *state, intel_crtc_vblank_off(old_crtc_state); - intel_disable_pipe(old_crtc_state); + intel_disable_transcoder(old_crtc_state); intel_ddi_disable_transcoder_func(old_crtc_state); @@ -314,7 +314,7 @@ static void hsw_enable_crt(struct intel_atomic_state *state, intel_ddi_enable_transcoder_func(encoder, crtc_state); - intel_enable_pipe(crtc_state); + intel_enable_transcoder(crtc_state); lpt_pch_enable(crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 23ef291f7b30..c7e12b09106f 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2867,7 +2867,7 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state, if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) { intel_crtc_vblank_off(old_crtc_state); - intel_disable_pipe(old_crtc_state); + intel_disable_transcoder(old_crtc_state); intel_vrr_disable(old_crtc_state); @@ -3138,7 +3138,7 @@ static void intel_enable_ddi(struct intel_atomic_state *state, intel_vrr_enable(encoder, crtc_state); - intel_enable_pipe(crtc_state); + intel_enable_transcoder(crtc_state); intel_crtc_vblank_on(crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a7ca38613f89..bc59fba02386 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -120,7 +120,7 @@ static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_sta const struct intel_link_m_n *m2_n2); static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state); static void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state); -static void hsw_set_pipeconf(const struct intel_crtc_state *crtc_state); +static void hsw_set_transconf(const struct intel_crtc_state *crtc_state); static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state); static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state); static void intel_modeset_setup_hw_state(struct drm_device *dev, @@ -448,8 +448,8 @@ void assert_panel_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe) pipe_name(pipe)); } -void assert_pipe(struct drm_i915_private *dev_priv, - enum transcoder cpu_transcoder, bool state) +void assert_transcoder(struct drm_i915_private *dev_priv, + enum transcoder cpu_transcoder, bool state) { bool cur_state; enum intel_display_power_domain power_domain; @@ -766,7 +766,7 @@ enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc) return crtc->pipe; } -void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state) +void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state) { struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -827,7 +827,7 @@ void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state) intel_wait_for_pipe_scanline_moving(crtc); } -void intel_disable_pipe(const struct intel_crtc_state *old_crtc_state) +void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state) { struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -2905,7 +2905,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state, if (dev_priv->display.initial_watermarks) dev_priv->display.initial_watermarks(state, crtc); - intel_enable_pipe(new_crtc_state); + intel_enable_transcoder(new_crtc_state); if (new_crtc_state->has_pch_encoder) ilk_pch_enable(state, new_crtc_state); @@ -3084,7 +3084,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, } if (!transcoder_is_dsi(cpu_transcoder)) - hsw_set_pipeconf(new_crtc_state); + hsw_set_transconf(new_crtc_state); crtc->active = true; @@ -3179,7 +3179,7 @@ static void ilk_crtc_disable(struct intel_atomic_state *state, intel_crtc_vblank_off(old_crtc_state); - intel_disable_pipe(old_crtc_state); + intel_disable_transcoder(old_crtc_state); ilk_pfit_disable(old_crtc_state); @@ -3241,7 +3241,7 @@ static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) */ drm_WARN_ON(&dev_priv->drm, intel_de_read(dev_priv, PFIT_CONTROL) & PFIT_ENABLE); - assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder); + assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder); intel_de_write(dev_priv, PFIT_PGM_RATIOS, crtc_state->gmch_pfit.pgm_ratios); @@ -3533,7 +3533,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, intel_disable_primary_plane(new_crtc_state); dev_priv->display.initial_watermarks(state, crtc); - intel_enable_pipe(new_crtc_state); + intel_enable_transcoder(new_crtc_state); intel_crtc_vblank_on(new_crtc_state); @@ -3579,7 +3579,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, dev_priv->display.initial_watermarks(state, crtc); else intel_update_watermarks(crtc); - intel_enable_pipe(new_crtc_state); + intel_enable_transcoder(new_crtc_state); intel_crtc_vblank_on(new_crtc_state); @@ -3598,7 +3598,7 @@ static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state) if (!old_crtc_state->gmch_pfit.control) return; - assert_pipe_disabled(dev_priv, old_crtc_state->cpu_transcoder); + assert_transcoder_disabled(dev_priv, old_crtc_state->cpu_transcoder); drm_dbg_kms(&dev_priv->drm, "disabling pfit, current: 0x%08x\n", intel_de_read(dev_priv, PFIT_CONTROL)); @@ -3624,7 +3624,7 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, intel_crtc_vblank_off(old_crtc_state); - intel_disable_pipe(old_crtc_state); + intel_disable_transcoder(old_crtc_state); i9xx_pfit_disable(old_crtc_state); @@ -5194,7 +5194,7 @@ static void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state) intel_de_posting_read(dev_priv, PIPECONF(pipe)); } -static void hsw_set_pipeconf(const struct intel_crtc_state *crtc_state) +static void hsw_set_transconf(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); diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 4719ffc97fce..d425ee77aad7 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -531,8 +531,8 @@ enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port); bool is_trans_port_sync_mode(const struct intel_crtc_state *state); void intel_plane_destroy(struct drm_plane *plane); -void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state); -void intel_disable_pipe(const struct intel_crtc_state *old_crtc_state); +void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state); +void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state); void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc); @@ -657,10 +657,10 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, enum pipe pipe, bool state); #define assert_fdi_rx_pll_enabled(d, p) assert_fdi_rx_pll(d, p, true) #define assert_fdi_rx_pll_disabled(d, p) assert_fdi_rx_pll(d, p, false) -void assert_pipe(struct drm_i915_private *dev_priv, - enum transcoder cpu_transcoder, bool state); -#define assert_pipe_enabled(d, t) assert_pipe(d, t, true) -#define assert_pipe_disabled(d, t) assert_pipe(d, t, false) +void assert_transcoder(struct drm_i915_private *dev_priv, + enum transcoder cpu_transcoder, bool state); +#define assert_transcoder_enabled(d, t) assert_transcoder(d, t, true) +#define assert_transcoder_disabled(d, t) assert_transcoder(d, t, false) /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and * WARN_ON()) for hw state sanity checks to check for unexpected conditions diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index d104441344c0..f7a0470b1f1c 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -405,7 +405,7 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, intel_crtc_vblank_off(old_crtc_state); - intel_disable_pipe(old_crtc_state); + intel_disable_transcoder(old_crtc_state); drm_dp_update_payload_part2(&intel_dp->mst_mgr); @@ -566,7 +566,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, intel_de_rmw(dev_priv, CHICKEN_TRANS(trans), 0, FECSTALL_DIS_DPTSTREAM_DPTTG); - intel_enable_pipe(pipe_config); + intel_enable_transcoder(pipe_config); intel_crtc_vblank_on(pipe_config); diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index ace9157a1c30..487d8721ecf8 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -1402,7 +1402,7 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state) enum pipe pipe = crtc->pipe; int i; - assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder); + assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ if (i9xx_has_pps(dev_priv)) @@ -1582,7 +1582,7 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state) struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder); + assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ assert_panel_unlocked(dev_priv, pipe); @@ -1734,7 +1734,7 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state) struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; - assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder); + assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ assert_panel_unlocked(dev_priv, pipe); @@ -1818,7 +1818,7 @@ void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) u32 val; /* Make sure the pipe isn't still relying on us */ - assert_pipe_disabled(dev_priv, (enum transcoder)pipe); + assert_transcoder_disabled(dev_priv, (enum transcoder)pipe); val = DPLL_INTEGRATED_REF_CLK_VLV | DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; @@ -1835,7 +1835,7 @@ void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) u32 val; /* Make sure the pipe isn't still relying on us */ - assert_pipe_disabled(dev_priv, (enum transcoder)pipe); + assert_transcoder_disabled(dev_priv, (enum transcoder)pipe); val = DPLL_SSC_REF_CLK_CHV | DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; @@ -1866,7 +1866,7 @@ void i9xx_disable_pll(const struct intel_crtc_state *crtc_state) return; /* Make sure the pipe isn't still relying on us */ - assert_pipe_disabled(dev_priv, crtc_state->cpu_transcoder); + assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder); intel_de_write(dev_priv, DPLL(pipe), DPLL_VGA_MODE_DIS); intel_de_posting_read(dev_priv, DPLL(pipe)); diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index fc09b781f15f..96ff12ad0873 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -281,7 +281,7 @@ static void ilk_fdi_link_train(struct intel_crtc *crtc, intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK); /* FDI needs bits from pipe first */ - assert_pipe_enabled(dev_priv, crtc_state->cpu_transcoder); + assert_transcoder_enabled(dev_priv, crtc_state->cpu_transcoder); /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit for train result */ diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c index d02f09f7e750..88a398df9621 100644 --- a/drivers/gpu/drm/i915/display/intel_tv.c +++ b/drivers/gpu/drm/i915/display/intel_tv.c @@ -1529,7 +1529,7 @@ static void intel_tv_pre_enable(struct intel_atomic_state *state, intel_de_write(dev_priv, TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); - assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder); + assert_transcoder_disabled(dev_priv, pipe_config->cpu_transcoder); /* Filter ctl must be set before TV_WIN_SIZE */ tv_filter_ctl = TV_AUTO_SCALE; -- cgit v1.2.3 From c98e3d15b5820778ea7f9d93531ffb1c91c0108f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 13 Sep 2021 17:44:30 +0300 Subject: drm/i915: Introduce with_intel_display_power_if_enabled() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the _if_enabled() counterpart to with_intel_display_power(). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210913144440.23008-7-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_power.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 978531841fa3..0612e4b6e3c8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -410,6 +410,10 @@ void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv, for ((wf) = intel_display_power_get((i915), (domain)); (wf); \ intel_display_power_put_async((i915), (domain), (wf)), (wf) = 0) +#define with_intel_display_power_if_enabled(i915, domain, wf) \ + for ((wf) = intel_display_power_get_if_enabled((i915), (domain)); (wf); \ + intel_display_power_put_async((i915), (domain), (wf)), (wf) = 0) + void chv_phy_powergate_lanes(struct intel_encoder *encoder, bool override, unsigned int mask); bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy, -- cgit v1.2.3 From 32f6734c724335a4f03b83a1a39f189d66ad5d27 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 13 Sep 2021 17:44:31 +0300 Subject: drm/i915: Adjust intel_dsc_power_domain() calling convention MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the crtc+cpu_transcoder rather than the crtc state to intel_dsc_power_domain(). This should allow us to reuse it during readout as well. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210913144440.23008-8-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 6 +-- drivers/gpu/drm/i915/display/intel_vdsc.c | 77 +++++++++++++--------------- drivers/gpu/drm/i915/display/intel_vdsc.h | 6 ++- 3 files changed, 44 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index bc59fba02386..3163a7213741 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3426,16 +3426,16 @@ static u64 get_crtc_power_domains(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); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; struct drm_encoder *encoder; enum pipe pipe = crtc->pipe; u64 mask; - enum transcoder transcoder = crtc_state->cpu_transcoder; if (!crtc_state->hw.active) return 0; mask = BIT_ULL(POWER_DOMAIN_PIPE(pipe)); - mask |= BIT_ULL(POWER_DOMAIN_TRANSCODER(transcoder)); + mask |= BIT_ULL(POWER_DOMAIN_TRANSCODER(cpu_transcoder)); if (crtc_state->pch_pfit.enabled || crtc_state->pch_pfit.force_thru) mask |= BIT_ULL(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe)); @@ -3454,7 +3454,7 @@ static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state) mask |= BIT_ULL(POWER_DOMAIN_DISPLAY_CORE); if (crtc_state->dsc.compression_enable) - mask |= BIT_ULL(intel_dsc_power_domain(crtc_state)); + mask |= BIT_ULL(intel_dsc_power_domain(crtc, cpu_transcoder)); return mask; } diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index df3286aa6999..2275f99ce9d7 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -357,11 +357,9 @@ bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state) return false; } -static bool is_pipe_dsc(const struct intel_crtc_state *crtc_state) +static bool is_pipe_dsc(struct intel_crtc *crtc, enum transcoder cpu_transcoder) { - const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - const struct drm_i915_private *i915 = to_i915(crtc->base.dev); - enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + struct drm_i915_private *i915 = to_i915(crtc->base.dev); if (DISPLAY_VER(i915) >= 12) return true; @@ -547,9 +545,8 @@ int intel_dsc_compute_params(struct intel_encoder *encoder, } enum intel_display_power_domain -intel_dsc_power_domain(const struct intel_crtc_state *crtc_state) +intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; @@ -566,7 +563,7 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state) */ if (DISPLAY_VER(i915) == 12 && !IS_ROCKETLAKE(i915) && pipe == PIPE_A) return POWER_DOMAIN_TRANSCODER_VDSC_PW2; - else if (is_pipe_dsc(crtc_state)) + else if (is_pipe_dsc(crtc, cpu_transcoder)) return POWER_DOMAIN_PIPE(pipe); else return POWER_DOMAIN_TRANSCODER_VDSC_PW2; @@ -577,6 +574,7 @@ static void intel_dsc_pps_configure(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); const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum pipe pipe = crtc->pipe; u32 pps_val = 0; u32 rc_buf_thresh_dword[4]; @@ -601,7 +599,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) if (vdsc_cfg->vbr_enable) pps_val |= DSC_VBR_ENABLE; drm_info(&dev_priv->drm, "PPS0 = 0x%08x\n", pps_val); - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_0, pps_val); /* @@ -625,7 +623,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) pps_val = 0; pps_val |= DSC_BPP(vdsc_cfg->bits_per_pixel); drm_info(&dev_priv->drm, "PPS1 = 0x%08x\n", pps_val); - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_1, pps_val); /* @@ -650,7 +648,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) pps_val |= DSC_PIC_HEIGHT(vdsc_cfg->pic_height) | DSC_PIC_WIDTH(vdsc_cfg->pic_width / num_vdsc_instances); drm_info(&dev_priv->drm, "PPS2 = 0x%08x\n", pps_val); - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_2, pps_val); /* @@ -675,7 +673,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) pps_val |= DSC_SLICE_HEIGHT(vdsc_cfg->slice_height) | DSC_SLICE_WIDTH(vdsc_cfg->slice_width); drm_info(&dev_priv->drm, "PPS3 = 0x%08x\n", pps_val); - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_3, pps_val); /* @@ -700,7 +698,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) pps_val |= DSC_INITIAL_XMIT_DELAY(vdsc_cfg->initial_xmit_delay) | DSC_INITIAL_DEC_DELAY(vdsc_cfg->initial_dec_delay); drm_info(&dev_priv->drm, "PPS4 = 0x%08x\n", pps_val); - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_4, pps_val); /* @@ -725,7 +723,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) pps_val |= DSC_SCALE_INC_INT(vdsc_cfg->scale_increment_interval) | DSC_SCALE_DEC_INT(vdsc_cfg->scale_decrement_interval); drm_info(&dev_priv->drm, "PPS5 = 0x%08x\n", pps_val); - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_5, pps_val); /* @@ -752,7 +750,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) DSC_FLATNESS_MIN_QP(vdsc_cfg->flatness_min_qp) | DSC_FLATNESS_MAX_QP(vdsc_cfg->flatness_max_qp); drm_info(&dev_priv->drm, "PPS6 = 0x%08x\n", pps_val); - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_6, pps_val); /* @@ -777,7 +775,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) pps_val |= DSC_SLICE_BPG_OFFSET(vdsc_cfg->slice_bpg_offset) | DSC_NFL_BPG_OFFSET(vdsc_cfg->nfl_bpg_offset); drm_info(&dev_priv->drm, "PPS7 = 0x%08x\n", pps_val); - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_7, pps_val); /* @@ -802,7 +800,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) pps_val |= DSC_FINAL_OFFSET(vdsc_cfg->final_offset) | DSC_INITIAL_OFFSET(vdsc_cfg->initial_offset); drm_info(&dev_priv->drm, "PPS8 = 0x%08x\n", pps_val); - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_8, pps_val); /* @@ -827,7 +825,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) pps_val |= DSC_RC_MODEL_SIZE(vdsc_cfg->rc_model_size) | DSC_RC_EDGE_FACTOR(DSC_RC_EDGE_FACTOR_CONST); drm_info(&dev_priv->drm, "PPS9 = 0x%08x\n", pps_val); - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_9, pps_val); /* @@ -854,7 +852,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) DSC_RC_TARGET_OFF_HIGH(DSC_RC_TGT_OFFSET_HI_CONST) | DSC_RC_TARGET_OFF_LOW(DSC_RC_TGT_OFFSET_LO_CONST); drm_info(&dev_priv->drm, "PPS10 = 0x%08x\n", pps_val); - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_10, pps_val); /* @@ -882,7 +880,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) DSC_SLICE_ROW_PER_FRAME(vdsc_cfg->pic_height / vdsc_cfg->slice_height); drm_info(&dev_priv->drm, "PPS16 = 0x%08x\n", pps_val); - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_16, pps_val); /* @@ -911,7 +909,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) drm_info(&dev_priv->drm, " RC_BUF_THRESH%d = 0x%08x\n", i, rc_buf_thresh_dword[i / 4]); } - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_0, rc_buf_thresh_dword[0]); intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_0_UDW, @@ -968,7 +966,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) drm_info(&dev_priv->drm, " RC_RANGE_PARAM_%d = 0x%08x\n", i, rc_range_params_dword[i / 2]); } - if (!is_pipe_dsc(crtc_state)) { + if (!is_pipe_dsc(crtc, cpu_transcoder)) { intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_0, rc_range_params_dword[0]); intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_0_UDW, @@ -1095,18 +1093,16 @@ static void intel_dsc_dp_pps_write(struct intel_encoder *encoder, sizeof(dp_dsc_pps_sdp)); } -static i915_reg_t dss_ctl1_reg(const struct intel_crtc_state *crtc_state) +static i915_reg_t dss_ctl1_reg(struct intel_crtc *crtc, enum transcoder cpu_transcoder) { - enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; - - return is_pipe_dsc(crtc_state) ? ICL_PIPE_DSS_CTL1(pipe) : DSS_CTL1; + return is_pipe_dsc(crtc, cpu_transcoder) ? + ICL_PIPE_DSS_CTL1(crtc->pipe) : DSS_CTL1; } -static i915_reg_t dss_ctl2_reg(const struct intel_crtc_state *crtc_state) +static i915_reg_t dss_ctl2_reg(struct intel_crtc *crtc, enum transcoder cpu_transcoder) { - enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; - - return is_pipe_dsc(crtc_state) ? ICL_PIPE_DSS_CTL2(pipe) : DSS_CTL2; + return is_pipe_dsc(crtc, cpu_transcoder) ? + ICL_PIPE_DSS_CTL2(crtc->pipe) : DSS_CTL2; } static struct intel_crtc * @@ -1142,7 +1138,7 @@ void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state) else dss_ctl1_val |= UNCOMPRESSED_JOINER_MASTER; - intel_de_write(dev_priv, dss_ctl1_reg(crtc_state), dss_ctl1_val); + intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val); } } @@ -1176,8 +1172,8 @@ void intel_dsc_enable(struct intel_encoder *encoder, if (!crtc_state->bigjoiner_slave) dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE; } - intel_de_write(dev_priv, dss_ctl1_reg(crtc_state), dss_ctl1_val); - intel_de_write(dev_priv, dss_ctl2_reg(crtc_state), dss_ctl2_val); + intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val); + intel_de_write(dev_priv, dss_ctl2_reg(crtc, crtc_state->cpu_transcoder), dss_ctl2_val); } void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state) @@ -1188,8 +1184,8 @@ void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state) /* Disable only if either of them is enabled */ if (old_crtc_state->dsc.compression_enable || old_crtc_state->bigjoiner) { - intel_de_write(dev_priv, dss_ctl1_reg(old_crtc_state), 0); - intel_de_write(dev_priv, dss_ctl2_reg(old_crtc_state), 0); + intel_de_write(dev_priv, dss_ctl1_reg(crtc, old_crtc_state->cpu_transcoder), 0); + intel_de_write(dev_priv, dss_ctl2_reg(crtc, old_crtc_state->cpu_transcoder), 0); } } @@ -1199,7 +1195,7 @@ void intel_uncompressed_joiner_get_config(struct intel_crtc_state *crtc_state) struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 dss_ctl1; - dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc_state)); + dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder)); if (dss_ctl1 & UNCOMPRESSED_JOINER_MASTER) { crtc_state->bigjoiner = true; crtc_state->bigjoiner_linked_crtc = intel_dsc_get_bigjoiner_secondary(crtc); @@ -1214,9 +1210,10 @@ void intel_uncompressed_joiner_get_config(struct intel_crtc_state *crtc_state) void intel_dsc_get_config(struct intel_crtc_state *crtc_state) { - struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum pipe pipe = crtc->pipe; enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; @@ -1225,14 +1222,14 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state) if (!intel_dsc_source_support(crtc_state)) return; - power_domain = intel_dsc_power_domain(crtc_state); + power_domain = intel_dsc_power_domain(crtc, cpu_transcoder); wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); if (!wakeref) return; - dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc_state)); - dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg(crtc_state)); + dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc, cpu_transcoder)); + dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg(crtc, cpu_transcoder)); crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE; if (!crtc_state->dsc.compression_enable) @@ -1256,7 +1253,7 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state) /* FIXME: add more state readout as needed */ /* PPS1 */ - if (!is_pipe_dsc(crtc_state)) + if (!is_pipe_dsc(crtc, cpu_transcoder)) val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1); else val = intel_de_read(dev_priv, diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h index dfb1fd38deb4..0c5d80a572da 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.h +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h @@ -8,8 +8,10 @@ #include -struct intel_encoder; +enum transcoder; +struct intel_crtc; struct intel_crtc_state; +struct intel_encoder; bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state); void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state); @@ -21,7 +23,7 @@ int intel_dsc_compute_params(struct intel_encoder *encoder, void intel_uncompressed_joiner_get_config(struct intel_crtc_state *crtc_state); void intel_dsc_get_config(struct intel_crtc_state *crtc_state); enum intel_display_power_domain -intel_dsc_power_domain(const struct intel_crtc_state *crtc_state); +intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder); struct intel_crtc *intel_dsc_get_bigjoiner_secondary(const struct intel_crtc *primary_crtc); #endif /* __INTEL_VDSC_H__ */ -- cgit v1.2.3 From 262d88baad8d8a7c13124fb9807db399b3e595f4 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 13 Sep 2021 17:44:32 +0300 Subject: drm/i915: Extract hsw_panel_transcoders() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract the "panel transcoder" bitmask into a helper. We'll have a couple of uses for this later. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210913144440.23008-9-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3163a7213741..f6c0c595f631 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5599,21 +5599,27 @@ out: return ret; } +static u8 hsw_panel_transcoders(struct drm_i915_private *i915) +{ + u8 panel_transcoder_mask = BIT(TRANSCODER_EDP); + + if (DISPLAY_VER(i915) >= 11) + panel_transcoder_mask |= BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1); + + return panel_transcoder_mask; +} + static bool hsw_get_transcoder_state(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config, struct intel_display_power_domain_set *power_domain_set) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - unsigned long panel_transcoder_mask = BIT(TRANSCODER_EDP); + u8 panel_transcoder_mask = hsw_panel_transcoders(dev_priv); unsigned long enabled_panel_transcoders = 0; enum transcoder panel_transcoder; u32 tmp; - if (DISPLAY_VER(dev_priv) >= 11) - panel_transcoder_mask |= - BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1); - /* * The pipe->transcoder mapping is fixed with the exception of the eDP * and DSI transcoders handled below. -- cgit v1.2.3 From f6d66fc8cf5f673ea76407be84dc17dbb3eda108 Mon Sep 17 00:00:00 2001 From: Radhakrishna Sripada Date: Tue, 14 Sep 2021 15:07:44 -0700 Subject: drm/i915: Update memory bandwidth parameters Earlier while calculating derated bw we would use 90% of the calculated bw. Starting ADL-P we use a non standard derating. Updating the formulae to reflect the same. Bspec: 64631 v2: Use the new derating value only for ADL-P(MattR) Fixes: 4d32fe2f14a7 ("drm/i915/adl_p: Update memory bandwidth parameters") Cc: Matt Roper Signed-off-by: Radhakrishna Sripada Reviewed-by: Matt Roper Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20210914220744.16042-1-radhakrishna.sripada@intel.com --- drivers/gpu/drm/i915/display/intel_bw.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index e91e0e0191fb..4b94256d7319 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -222,31 +222,42 @@ static int icl_sagv_max_dclk(const struct intel_qgv_info *qi) struct intel_sa_info { u16 displayrtids; - u8 deburst, deprogbwlimit; + u8 deburst, deprogbwlimit, derating; }; static const struct intel_sa_info icl_sa_info = { .deburst = 8, .deprogbwlimit = 25, /* GB/s */ .displayrtids = 128, + .derating = 10, }; static const struct intel_sa_info tgl_sa_info = { .deburst = 16, .deprogbwlimit = 34, /* GB/s */ .displayrtids = 256, + .derating = 10, }; static const struct intel_sa_info rkl_sa_info = { .deburst = 16, .deprogbwlimit = 20, /* GB/s */ .displayrtids = 128, + .derating = 10, }; static const struct intel_sa_info adls_sa_info = { .deburst = 16, .deprogbwlimit = 38, /* GB/s */ .displayrtids = 256, + .derating = 10, +}; + +static const struct intel_sa_info adlp_sa_info = { + .deburst = 16, + .deprogbwlimit = 38, /* GB/s */ + .displayrtids = 256, + .derating = 20, }; static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa) @@ -302,7 +313,7 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel bw = icl_calc_bw(sp->dclk, clpchgroup * 32 * num_channels, ct); bi->deratedbw[j] = min(maxdebw, - bw * 9 / 10); /* 90% */ + bw * (100 - sa->derating) / 100); drm_dbg_kms(&dev_priv->drm, "BW%d / QGV %d: num_planes=%d deratedbw=%u\n", @@ -400,7 +411,9 @@ void intel_bw_init_hw(struct drm_i915_private *dev_priv) if (IS_DG2(dev_priv)) dg2_get_bw_info(dev_priv); - else if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv)) + else if (IS_ALDERLAKE_P(dev_priv)) + icl_get_bw_info(dev_priv, &adlp_sa_info); + else if (IS_ALDERLAKE_S(dev_priv)) icl_get_bw_info(dev_priv, &adls_sa_info); else if (IS_ROCKETLAKE(dev_priv)) icl_get_bw_info(dev_priv, &rkl_sa_info); -- cgit v1.2.3 From 064b877dff4252ced91a1c8b1f129073f2991f6e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Aug 2021 12:48:05 -0700 Subject: drm/i915: Free all DMC payloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Free all the DMC payloads, not just DMC_MAIN. unreferenced object 0xffff88ff32d4d800 (size 1024): comm "kworker/1:5", pid 701, jiffies 4294904239 (age 109.736s) hex dump (first 32 bytes): 40 40 00 0c 03 00 00 00 00 00 00 00 00 00 00 00 @@.............. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<00000000ba9d0d95>] dmc_load_work_fn+0x34d/0x510 [i915] [<000000001049fcab>] process_one_work+0x261/0x550 [<00000000eeb995ac>] worker_thread+0x49/0x3c0 [<0000000021031dc3>] kthread+0x10b/0x140 [<000000004a0f69ee>] ret_from_fork+0x1f/0x30 unreferenced object 0xffff88ff0bde4000 (size 1024): comm "kworker/0:3", pid 708, jiffies 4294904469 (age 108.816s) hex dump (first 32 bytes): 40 40 00 0c 01 00 00 00 00 00 00 00 00 00 00 00 @@.............. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<00000000ba9d0d95>] dmc_load_work_fn+0x34d/0x510 [i915] [<000000001049fcab>] process_one_work+0x261/0x550 [<00000000eeb995ac>] worker_thread+0x49/0x3c0 [<0000000021031dc3>] kthread+0x10b/0x140 [<000000004a0f69ee>] ret_from_fork+0x1f/0x30 Fixes: 3d5928a168a9 ("drm/i915/xelpd: Pipe A DMC plugging") Cc: Anusha Srivatsa Cc: José Roberto de Souza Signed-off-by: Chris Wilson Signed-off-by: Lucas De Marchi Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210809194805.3793060-1-lucas.demarchi@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 3c3c6cb5c0df..b3c8e1c450ef 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -805,11 +805,14 @@ void intel_dmc_ucode_resume(struct drm_i915_private *dev_priv) */ void intel_dmc_ucode_fini(struct drm_i915_private *dev_priv) { + int id; + if (!HAS_DMC(dev_priv)) return; intel_dmc_ucode_suspend(dev_priv); drm_WARN_ON(&dev_priv->drm, dev_priv->dmc.wakeref); - kfree(dev_priv->dmc.dmc_info[DMC_FW_MAIN].payload); + for (id = 0; id < DMC_FW_MAX; id++) + kfree(dev_priv->dmc.dmc_info[id].payload); } -- cgit v1.2.3 From 259d71992e57c637aa0a5d3f4f7b9f689c186191 Mon Sep 17 00:00:00 2001 From: Anusha Srivatsa Date: Tue, 14 Sep 2021 14:57:32 -0700 Subject: drm/i915/dmc: Update to DMC v2.12 The release notes mentions that this version- 1. Fix for unblock indication to punit. 2. Robustness fix for DC6/6v abort scenarios. Cc: Imre Deak > Signed-off-by: Anusha Srivatsa Reviewed-by: Imre Deak Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20210914215732.67135-2-anusha.srivatsa@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index b3c8e1c450ef..b0268552b286 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -45,8 +45,8 @@ #define GEN12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE -#define ADLP_DMC_PATH DMC_PATH(adlp, 2, 10) -#define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(2, 10) +#define ADLP_DMC_PATH DMC_PATH(adlp, 2, 12) +#define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(2, 12) MODULE_FIRMWARE(ADLP_DMC_PATH); #define ADLS_DMC_PATH DMC_PATH(adls, 2, 01) -- cgit v1.2.3 From 72fe6ca84f080a01218d9208e2fa8ce8baaec548 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 14 Sep 2021 14:25:03 -0700 Subject: drm/i915/display/adlp: Fix PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the SU_REGION_START begins at 0, the SU_REGION_END should be number of lines - 1. BSpec: 50424 Reviewed-by: Gwan-gyeong Mun Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210914212507.177511-1-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 3f6fb7d67f84..36816abb3bcc 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1501,7 +1501,7 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, if (IS_ALDERLAKE_P(dev_priv)) { val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1); - val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2); + val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2 - 1); } else { drm_WARN_ON(crtc_state->uapi.crtc->dev, clip->y1 % 4 || clip->y2 % 4); -- cgit v1.2.3 From ce0eacbbd922b91ce28523b167ef848d0f76f908 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 14 Sep 2021 14:25:04 -0700 Subject: drm/i915/display: Wait at least 2 frames before selective update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BSpec states that the minimum number of frames before selective update is 2, so making sure this minimum limit is fulfilled. BSpec: 50422 Reviewed-by: Gwan-gyeong Mun Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210914212507.177511-2-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 36816abb3bcc..567c7ceef8db 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -510,7 +510,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) if (DISPLAY_VER(dev_priv) >= 10 && DISPLAY_VER(dev_priv) <= 12) val |= EDP_Y_COORDINATE_ENABLE; - val |= EDP_PSR2_FRAME_BEFORE_SU(intel_dp->psr.sink_sync_latency + 1); + val |= EDP_PSR2_FRAME_BEFORE_SU(max_t(u8, intel_dp->psr.sink_sync_latency + 1, 2)); val |= intel_psr2_get_tp_time(intel_dp); /* Wa_22012278275:adl-p */ -- cgit v1.2.3 From 1f3a11c341ab211d6ba55ef3d58026b7b5319945 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 14 Sep 2021 14:25:05 -0700 Subject: drm/i915/display: Workaround cursor left overs with PSR2 selective fetch enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not sure why but when moving the cursor fast it causes some artifacts of the cursor to be left in the cursor path, adding some pixels above the cursor to the damaged area fixes the issue, so leaving this as a workaround until proper fix is found. This is reproducile on TGL and ADL-P. Cc: Gwan-gyeong Mun Reviewed-by: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210914212507.177511-3-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 567c7ceef8db..f8fa30e50e70 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1543,6 +1543,28 @@ static void intel_psr2_sel_fetch_pipe_alignment(const struct intel_crtc_state *c drm_warn(&dev_priv->drm, "Missing PSR2 sel fetch alignment with DSC\n"); } +/* + * FIXME: Not sure why but when moving the cursor fast it causes some artifacts + * of the cursor to be left in the cursor path, adding some pixels above the + * cursor to the damaged area fixes the issue. + */ +static void cursor_area_workaround(const struct intel_plane_state *new_plane_state, + struct drm_rect *damaged_area, + struct drm_rect *pipe_clip) +{ + const struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane); + int height; + + if (plane->id != PLANE_CURSOR) + return; + + height = drm_rect_height(&new_plane_state->uapi.dst) / 2; + damaged_area->y1 -= height; + damaged_area->y1 = max(damaged_area->y1, 0); + + clip_area_update(pipe_clip, damaged_area); +} + int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -1611,6 +1633,9 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, damaged_area.y2 = new_plane_state->uapi.dst.y2; clip_area_update(&pipe_clip, &damaged_area); } + + cursor_area_workaround(new_plane_state, &damaged_area, + &pipe_clip); continue; } else if (new_plane_state->uapi.alpha != old_plane_state->uapi.alpha || (!num_clips && -- cgit v1.2.3 From af7ea1e22afc7ce7773b2e4562df4370c8c711ea Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 14 Sep 2021 14:25:06 -0700 Subject: drm/i915/display/psr: Use drm damage helpers to calculate plane damaged area MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_atomic_helper_damage_iter_init() + drm_atomic_for_each_plane_damage() returns the full plane area in case no damaged area was set by userspace or it was discarted by driver. This is important to fix the rendering of userspace applications that does frontbuffer rendering and notify driver about dirty areas but do not set any dirty clips. With this we don't need to worry about to check and mark the whole area as damaged in page flips. Another important change here is the move of drm_atomic_add_affected_planes() call, it needs to called late otherwise the area of all the planes would be added to pipe_clip and not saving power. Cc: Daniel Vetter Cc: Gwan-gyeong Mun Reviewed-by: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210914212507.177511-4-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 37 +++++++++++--------------------- 1 file changed, 13 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index f8fa30e50e70..5a1535e11e6b 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -22,6 +22,7 @@ */ #include +#include #include "display/intel_dp.h" @@ -1578,10 +1579,6 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, if (!crtc_state->enable_psr2_sel_fetch) return 0; - ret = drm_atomic_add_affected_planes(&state->base, &crtc->base); - if (ret) - return ret; - /* * Calculate minimal selective fetch area of each plane and calculate * the pipe damaged area. @@ -1591,8 +1588,8 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { struct drm_rect src, damaged_area = { .y1 = -1 }; - struct drm_mode_rect *damaged_clips; - u32 num_clips, j; + struct drm_atomic_helper_damage_iter iter; + struct drm_rect clip; if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc) continue; @@ -1612,8 +1609,6 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, break; } - num_clips = drm_plane_get_damage_clips_count(&new_plane_state->uapi); - /* * If visibility or plane moved, mark the whole plane area as * damaged as it needs to be complete redraw in the new and old @@ -1637,14 +1632,8 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, cursor_area_workaround(new_plane_state, &damaged_area, &pipe_clip); continue; - } else if (new_plane_state->uapi.alpha != old_plane_state->uapi.alpha || - (!num_clips && - new_plane_state->uapi.fb != old_plane_state->uapi.fb)) { - /* - * If the plane don't have damaged areas but the - * framebuffer changed or alpha changed, mark the whole - * plane area as damaged. - */ + } else if (new_plane_state->uapi.alpha != old_plane_state->uapi.alpha) { + /* If alpha changed mark the whole plane area as damaged */ damaged_area.y1 = new_plane_state->uapi.dst.y1; damaged_area.y2 = new_plane_state->uapi.dst.y2; clip_area_update(&pipe_clip, &damaged_area); @@ -1652,15 +1641,11 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, } drm_rect_fp_to_int(&src, &new_plane_state->uapi.src); - damaged_clips = drm_plane_get_damage_clips(&new_plane_state->uapi); - for (j = 0; j < num_clips; j++) { - struct drm_rect clip; - - clip.x1 = damaged_clips[j].x1; - clip.y1 = damaged_clips[j].y1; - clip.x2 = damaged_clips[j].x2; - clip.y2 = damaged_clips[j].y2; + 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); } @@ -1676,6 +1661,10 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, if (full_update) goto skip_sel_fetch_set_loop; + ret = drm_atomic_add_affected_planes(&state->base, &crtc->base); + if (ret) + return ret; + intel_psr2_sel_fetch_pipe_alignment(crtc_state, &pipe_clip); /* -- cgit v1.2.3 From 641dd82ffa9daad38f630d9f4a36e4875fd4e0c6 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 14 Sep 2021 14:25:07 -0700 Subject: drm/i915/display/adlp: Add new PSR2 workarounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wa_16014451276 fixes the starting coordinate for PSR2 selective updates. CHICKEN_TRANS definition of the workaround bit has a wrong name based on workaround definition and HSD. Wa_14014971508 allows the screen to continue to be updated when coming back from DC5/DC6 and SF_SINGLE_FULL_FRAME bit is not kept set in PSR2_MAN_TRK_CTL. Wa_16012604467 fixes underruns when exiting PSR2 when it is in one of its internal states. Wa_14014971508 is still in pending status in BSpec but by the time this is reviewed and ready to be merged it will be finalized. v2: - renamed register to ADLP_1_BASED_X_GRANULARITY - added comment about all ADL-P supported panels being 1 based X granularity BSpec: 54369 BSpec: 50054 Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Reviewed-by: Gwan-gyeong Mun Link: https://patchwork.freedesktop.org/patch/msgid/20210914212507.177511-5-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 27 ++++++++++++++++++++++++++- drivers/gpu/drm/i915/i915_reg.h | 4 ++++ 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 5a1535e11e6b..c1894b056d6c 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1087,6 +1087,16 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp) intel_de_write(dev_priv, reg, chicken); } + /* + * Wa_16014451276:adlp + * All supported adlp panels have 1-based X granularity, this may + * cause issues if non-supported panels are used. + */ + if (IS_ALDERLAKE_P(dev_priv) && + intel_dp->psr.psr2_enabled) + intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder), 0, + ADLP_1_BASED_X_GRANULARITY); + /* * Per Spec: Avoid continuous PSR exit by masking MEMUP and HPD also * mask LPSP to avoid dependency on other drivers that might block @@ -1132,6 +1142,11 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp) TRANS_SET_CONTEXT_LATENCY(intel_dp->psr.transcoder), TRANS_SET_CONTEXT_LATENCY_MASK, TRANS_SET_CONTEXT_LATENCY_VALUE(1)); + + /* Wa_16012604467:adlp */ + if (IS_ALDERLAKE_P(dev_priv) && intel_dp->psr.psr2_enabled) + intel_de_rmw(dev_priv, CLKGATE_DIS_MISC, 0, + CLKGATE_DIS_MISC_DMASC_GATING_DIS); } static bool psr_interrupt_error_check(struct intel_dp *intel_dp) @@ -1321,6 +1336,11 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) TRANS_SET_CONTEXT_LATENCY(intel_dp->psr.transcoder), TRANS_SET_CONTEXT_LATENCY_MASK, 0); + /* Wa_16012604467:adlp */ + if (IS_ALDERLAKE_P(dev_priv) && intel_dp->psr.psr2_enabled) + intel_de_rmw(dev_priv, CLKGATE_DIS_MISC, + CLKGATE_DIS_MISC_DMASC_GATING_DIS, 0); + intel_snps_phy_update_psr_power_state(dev_priv, phy, false); /* Disable PSR on Sink */ @@ -1489,8 +1509,13 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, u32 val = PSR2_MAN_TRK_CTL_ENABLE; if (full_update) { + /* + * Wa_14014971508:adlp + * SINGLE_FULL_FRAME bit is not hold in register so can not be + * restored by DMC, so using CONTINUOS_FULL_FRAME to mimic that + */ if (IS_ALDERLAKE_P(dev_priv)) - val |= ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME; + val |= ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME; else val |= PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index bd63760207b0..67351ed5ab5b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8205,6 +8205,7 @@ enum { #define VSC_DATA_SEL_SOFTWARE_CONTROL REG_BIT(25) /* GLK */ #define FECSTALL_DIS_DPTSTREAM_DPTTG REG_BIT(23) #define DDI_TRAINING_OVERRIDE_ENABLE REG_BIT(19) +#define ADLP_1_BASED_X_GRANULARITY REG_BIT(18) #define DDI_TRAINING_OVERRIDE_VALUE REG_BIT(18) #define DDIE_TRAINING_OVERRIDE_ENABLE REG_BIT(17) /* CHICKEN_TRANS_A only */ #define DDIE_TRAINING_OVERRIDE_VALUE REG_BIT(16) /* CHICKEN_TRANS_A only */ @@ -12759,4 +12760,7 @@ enum skl_power_gate { #define CLKREQ_POLICY _MMIO(0x101038) #define CLKREQ_POLICY_MEM_UP_OVRD REG_BIT(1) +#define CLKGATE_DIS_MISC _MMIO(0x46534) +#define CLKGATE_DIS_MISC_DMASC_GATING_DIS REG_BIT(21) + #endif /* _I915_REG_H_ */ -- cgit v1.2.3 From 054ce0bce22eeb714c6cc3808869a326d0611792 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 9 Sep 2021 15:51:53 +0300 Subject: drm/dp: add DP 2.0 UHBR link rate and bw code conversions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bw code equals link_rate / 0.27 Gbps only for 8b/10b link rates. Handle DP 2.0 UHBR rates as special cases, though this is not pretty. Cc: dri-devel@lists.freedesktop.org Reviewed-by: Ville Syrjälä Acked-by: Maxime Ripard Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/cab4edda8834d6b4db610fabb5e1f1f18ae33c2c.1631191763.git.jani.nikula@intel.com --- drivers/gpu/drm/drm_dp_helper.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 6d0f2c447f3b..9b2a2961fca8 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -207,15 +207,33 @@ EXPORT_SYMBOL(drm_dp_lttpr_link_train_channel_eq_delay); u8 drm_dp_link_rate_to_bw_code(int link_rate) { - /* Spec says link_bw = link_rate / 0.27Gbps */ - return link_rate / 27000; + switch (link_rate) { + case 1000000: + return DP_LINK_BW_10; + case 1350000: + return DP_LINK_BW_13_5; + case 2000000: + return DP_LINK_BW_20; + default: + /* Spec says link_bw = link_rate / 0.27Gbps */ + return link_rate / 27000; + } } EXPORT_SYMBOL(drm_dp_link_rate_to_bw_code); int drm_dp_bw_code_to_link_rate(u8 link_bw) { - /* Spec says link_rate = link_bw * 0.27Gbps */ - return link_bw * 27000; + switch (link_bw) { + case DP_LINK_BW_10: + return 1000000; + case DP_LINK_BW_13_5: + return 1350000; + case DP_LINK_BW_20: + return 2000000; + default: + /* Spec says link_rate = link_bw * 0.27Gbps */ + return link_bw * 27000; + } } EXPORT_SYMBOL(drm_dp_bw_code_to_link_rate); -- cgit v1.2.3 From fc8a2b1e0f91368872424e9e3a8473344c350299 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 9 Sep 2021 15:51:54 +0300 Subject: drm/dp: use more of the extended receiver cap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend the use of extended receiver cap at 0x2200 to cover MAIN_LINK_CHANNEL_CODING_CAP in 0x2206, in case an implementation hides the DP 2.0 128b/132b channel encoding cap. v2: Extend to DP_RECEIVER_CAP_SIZE (Ville) Cc: Lyude Paul Cc: dri-devel@lists.freedesktop.org Cc: Manasi Navare Cc: Ville Syrjälä Reviewed-by: Lyude Paul Acked-by: Maxime Ripard Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/649051cb896821147feee91aab1f2abc523c1353.1631191763.git.jani.nikula@intel.com --- drivers/gpu/drm/drm_dp_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 9b2a2961fca8..2e74b02ed96b 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -608,7 +608,7 @@ static u8 drm_dp_downstream_port_count(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) static int drm_dp_read_extended_dpcd_caps(struct drm_dp_aux *aux, u8 dpcd[DP_RECEIVER_CAP_SIZE]) { - u8 dpcd_ext[6]; + u8 dpcd_ext[DP_RECEIVER_CAP_SIZE]; int ret; /* -- cgit v1.2.3 From c78b4a85721f3905ba9baeac4e0bb99a36211d9b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 9 Sep 2021 15:51:56 +0300 Subject: drm/dp: add helper for extracting adjust 128b/132b TX FFE preset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DP 2.0 128b/132b channel coding uses TX FFE presets instead of vswing and pre-emphasis. Cc: dri-devel@lists.freedesktop.org Reviewed-by: Ville Syrjälä Acked-by: Maxime Ripard Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/4ba129c51aeb01a5f210de7026abe704a554a178.1631191763.git.jani.nikula@intel.com --- drivers/gpu/drm/drm_dp_helper.c | 14 ++++++++++++++ include/drm/drm_dp_helper.h | 2 ++ 2 files changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 2e74b02ed96b..4d0d1e8e51fa 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -130,6 +130,20 @@ u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SI } EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis); +/* DP 2.0 128b/132b */ +u8 drm_dp_get_adjust_tx_ffe_preset(const u8 link_status[DP_LINK_STATUS_SIZE], + int lane) +{ + int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); + int s = ((lane & 1) ? + DP_ADJUST_TX_FFE_PRESET_LANE1_SHIFT : + DP_ADJUST_TX_FFE_PRESET_LANE0_SHIFT); + u8 l = dp_link_status(link_status, i); + + return (l >> s) & 0xf; +} +EXPORT_SYMBOL(drm_dp_get_adjust_tx_ffe_preset); + u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZE], unsigned int lane) { diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index f3a61341011d..3ee0b3ffb8a5 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -1494,6 +1494,8 @@ u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE], int lane); u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE], int lane); +u8 drm_dp_get_adjust_tx_ffe_preset(const u8 link_status[DP_LINK_STATUS_SIZE], + int lane); u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZE], unsigned int lane); -- cgit v1.2.3 From 7bb97db8d32983b3525912a219f11c5140f282e7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 9 Sep 2021 15:51:57 +0300 Subject: drm/i915/dg2: add DG2+ TRANS_DDI_FUNC_CTL DP 2.0 128b/132b mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unfortunately, the DP 2.0 128b/132b DDI mode selection in the register conflicts with FDI. Since we have to deal with both meanings in the same code, for different platforms, clarify the macro name so we don't forget. Bspec: 50493 Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/260e4da302d47ae50122eb8d517be6ac3ccb15f2.1631191763.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 6 +++--- drivers/gpu/drm/i915/i915_reg.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index c7e12b09106f..cb8f303265a7 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -489,7 +489,7 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, if (crtc_state->hdmi_high_tmds_clock_ratio) temp |= TRANS_DDI_HIGH_TMDS_CHAR_RATE; } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) { - temp |= TRANS_DDI_MODE_SELECT_FDI; + temp |= TRANS_DDI_MODE_SELECT_FDI_OR_128B132B; temp |= (crtc_state->fdi_lanes - 1) << 1; } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { temp |= TRANS_DDI_MODE_SELECT_DP_MST; @@ -679,7 +679,7 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) ret = false; break; - case TRANS_DDI_MODE_SELECT_FDI: + case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B: ret = type == DRM_MODE_CONNECTOR_VGA; break; @@ -3558,7 +3558,7 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); pipe_config->lane_count = 4; break; - case TRANS_DDI_MODE_SELECT_FDI: + case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B: pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); break; case TRANS_DDI_MODE_SELECT_DP_SST: diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 67351ed5ab5b..61d29068925c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10173,7 +10173,7 @@ enum skl_power_gate { #define TRANS_DDI_MODE_SELECT_DVI (1 << 24) #define TRANS_DDI_MODE_SELECT_DP_SST (2 << 24) #define TRANS_DDI_MODE_SELECT_DP_MST (3 << 24) -#define TRANS_DDI_MODE_SELECT_FDI (4 << 24) +#define TRANS_DDI_MODE_SELECT_FDI_OR_128B132B (4 << 24) #define TRANS_DDI_BPC_MASK (7 << 20) #define TRANS_DDI_BPC_8 (0 << 20) #define TRANS_DDI_BPC_10 (1 << 20) -- cgit v1.2.3 From 4e718a0e4053249c0ff5df60f8f3799fce1a1981 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 9 Sep 2021 15:51:58 +0300 Subject: drm/i915/dp: add helper for checking for UHBR link rate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Helpful abstraction to avoid duplication. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/fe9a222ad900da797c989de9f7fa13928d2c9861.1631191763.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 6 ++++++ drivers/gpu/drm/i915/display/intel_dp.h | 1 + 2 files changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 3e7236b07773..7559911c140a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -115,6 +115,12 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp) static void intel_dp_unset_edid(struct intel_dp *intel_dp); static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc); +/* Is link rate UHBR and thus 128b/132b? */ +bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state) +{ + return crtc_state->port_clock >= 1000000; +} + /* update sink rates from dpcd */ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp) { diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index a28fff286c21..94b568704b22 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -58,6 +58,7 @@ int intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state); bool intel_dp_is_edp(struct intel_dp *intel_dp); +bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state); bool intel_dp_is_port_edp(struct drm_i915_private *dev_priv, enum port port); enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd); -- cgit v1.2.3 From 078397bbad2d70cef41771322801b73b39daddb3 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 9 Sep 2021 15:51:59 +0300 Subject: drm/i915/dp: use 128b/132b TPS2 for UHBR+ link rates 128b/132b channel encoding has separate TPS1 and TPS2, although the DPCD register values coincide with 8b/10b TPS1 and TPS2 values. Use 128b/132b TPS2 for channel equalization. v2: Use intel_dp_is_uhbr Reviewed-by: Manasi Navare # v1 Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/723b29223dc570c8b63c3c6fe5fb772d9db06c0d.1631191763.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 508a514c5e37..36b35239da83 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -602,9 +602,9 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, } /* - * Pick training pattern for channel equalization. Training pattern 4 for HBR3 - * or for 1.4 devices that support it, training Pattern 3 for HBR2 - * or 1.2 devices that support it, Training Pattern 2 otherwise. + * Pick Training Pattern Sequence (TPS) for channel equalization. 128b/132b TPS2 + * for UHBR+, TPS4 for HBR3 or for 1.4 devices that support it, TPS3 for HBR2 or + * 1.2 devices that support it, TPS2 otherwise. */ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, @@ -612,6 +612,10 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp, { bool source_tps3, sink_tps3, source_tps4, sink_tps4; + /* UHBR+ use separate 128b/132b TPS2 */ + if (intel_dp_is_uhbr(crtc_state)) + return DP_TRAINING_PATTERN_2; + /* * Intel platforms that support HBR3 also support TPS4. It is mandatory * for all downstream devices that support HBR3. There are no known eDP -- cgit v1.2.3 From 6114f71b3953407148158476b81c5eb082ef142b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 9 Sep 2021 15:52:00 +0300 Subject: drm/i915/dp: select 128b/132b channel encoding for UHBR rates UHBR rates and 128b/132b channel encoding go hand in hand. v2: Fix check for >= UHBR rates using intel_dp_is_uhbr() (Ville) Reviewed-by: Manasi Navare Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/b4ffd0187b306c0abaa08b89ed35c993ad8145c7.1631191763.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 36b35239da83..4f116cd32846 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -495,7 +495,8 @@ intel_dp_prepare_link_train(struct intel_dp *intel_dp, &rate_select, 1); link_config[0] = crtc_state->vrr.enable ? DP_MSA_TIMING_PAR_IGNORE_EN : 0; - link_config[1] = DP_SET_ANSI_8B10B; + link_config[1] = intel_dp_is_uhbr(crtc_state) ? + DP_SET_ANSI_128B132B : DP_SET_ANSI_8B10B; drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2); intel_dp->DP |= DP_PORT_EN; -- cgit v1.2.3 From 79ac2b1bc9b9a1bc17b52263d940be075aa55982 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 9 Sep 2021 15:52:01 +0300 Subject: drm/i915/dg2: configure TRANS_DP2_CTL for DP 2.0 Set the DP 2.0 128b/132b channel encoding for UHBR rates. v2: Fix UHBR port clock check, use intel_dp_is_uhbr() Bspec: 54128 Reviewed-by: Manasi Navare Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/c88b08d80a96d1229ae941b296590633be4d8711.1631191763.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index cb8f303265a7..91ee32ffba97 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -408,6 +408,20 @@ static u32 bdw_trans_port_sync_master_select(enum transcoder master_transcoder) return master_transcoder + 1; } +static void +intel_ddi_config_transcoder_dp2(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + u32 val = 0; + + if (intel_dp_is_uhbr(crtc_state)) + val = TRANS_DP2_128B132B_CHANNEL_CODING; + + intel_de_write(i915, TRANS_DP2_CTL(cpu_transcoder), val); +} + /* * Returns the TRANS_DDI_FUNC_CTL value based on CRTC state. * @@ -2376,7 +2390,8 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state, */ intel_ddi_enable_pipe_clock(encoder, crtc_state); - /* 5.b Not relevant to i915 for now */ + /* 5.b Configure transcoder for DP 2.0 128b/132b */ + intel_ddi_config_transcoder_dp2(encoder, crtc_state); /* * 5.c Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST -- cgit v1.2.3 From 1d713917248080b1fe2289677f8a92ad1293b1a5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 9 Sep 2021 15:52:02 +0300 Subject: drm/i915/dp: add HAS_DP20 macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's abstract the DP 2.0 feature. Initially just DG2. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/3746e700641bc17eff270569387fe869707d92ed.1631191763.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a8129153d1db..b9fd54f24f95 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1641,6 +1641,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define HAS_IPS(dev_priv) (IS_HSW_ULT(dev_priv) || IS_BROADWELL(dev_priv)) #define HAS_DP_MST(dev_priv) (INTEL_INFO(dev_priv)->display.has_dp_mst) +#define HAS_DP20(dev_priv) (IS_DG2(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) -- cgit v1.2.3 From 652135940ee20e2aaa4c628d13b3fb2b53770cab Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 9 Sep 2021 15:52:03 +0300 Subject: drm/i915/dg2: use 128b/132b transcoder DDI mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 128b/132b has a separate transcoder DDI mode, which also requires the MST transport select to be set. Note that we'll use DP MST also for single-stream 128b/132b. Having the FDI and 128b/132b modes share the register mode value complicates things a bit. v2: - Use HAS_DP20 abstraction for 128b/132b mode (Ville) - Use intel_dp_is_uhbr() helper Bspec: 50493 Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/279bfbd979e0256fae13a5231e07e2f4fb665c07.1631191763.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 91ee32ffba97..bba0ab99836b 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -506,7 +506,10 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, temp |= TRANS_DDI_MODE_SELECT_FDI_OR_128B132B; temp |= (crtc_state->fdi_lanes - 1) << 1; } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { - temp |= TRANS_DDI_MODE_SELECT_DP_MST; + if (intel_dp_is_uhbr(crtc_state)) + temp |= TRANS_DDI_MODE_SELECT_FDI_OR_128B132B; + else + temp |= TRANS_DDI_MODE_SELECT_DP_MST; temp |= DDI_PORT_WIDTH(crtc_state->lane_count); if (DISPLAY_VER(dev_priv) >= 12) { @@ -694,7 +697,12 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) break; case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B: - ret = type == DRM_MODE_CONNECTOR_VGA; + if (HAS_DP20(dev_priv)) + /* 128b/132b */ + ret = false; + else + /* FDI */ + ret = type == DRM_MODE_CONNECTOR_VGA; break; default: @@ -781,8 +789,9 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, if ((tmp & port_mask) != ddi_select) continue; - if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == - TRANS_DDI_MODE_SELECT_DP_MST) + if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST || + (HAS_DP20(dev_priv) && + (tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B)) mst_pipe_mask |= BIT(p); *pipe_mask |= BIT(p); @@ -3573,9 +3582,6 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); pipe_config->lane_count = 4; break; - case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B: - pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); - break; case TRANS_DDI_MODE_SELECT_DP_SST: if (encoder->type == INTEL_OUTPUT_EDP) pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); @@ -3604,6 +3610,13 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, pipe_config->infoframes.enable |= intel_hdmi_infoframes_enabled(encoder, pipe_config); break; + case TRANS_DDI_MODE_SELECT_FDI_OR_128B132B: + if (!HAS_DP20(dev_priv)) { + /* FDI */ + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); + break; + } + fallthrough; /* 128b/132b */ case TRANS_DDI_MODE_SELECT_DP_MST: pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); pipe_config->lane_count = -- cgit v1.2.3 From e01163e82b708535ae1bfca67730516578b237be Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 9 Sep 2021 15:52:04 +0300 Subject: drm/i915/dg2: configure TRANS_DP2_VFREQ{HIGH,LOW} for 128b/132b MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's a new register pair for 128b/132b mode where you need to set the pixel clock in Hz. v2: Fix UHBR rate check, use intel_dp_is_uhbr() helper Bspec: 54128 Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/a2902cc188973f022f282f2a77e693afdecefb5a.1631191763.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index f7a0470b1f1c..fd0a31bc3dcd 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -550,6 +550,17 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, clear_act_sent(encoder, pipe_config); + if (intel_dp_is_uhbr(pipe_config)) { + const struct drm_display_mode *adjusted_mode = + &pipe_config->hw.adjusted_mode; + u64 crtc_clock_hz = KHz(adjusted_mode->crtc_clock); + + intel_de_write(dev_priv, TRANS_DP2_VFREQHIGH(pipe_config->cpu_transcoder), + TRANS_DP2_VFREQ_PIXEL_CLOCK(crtc_clock_hz >> 24)); + intel_de_write(dev_priv, TRANS_DP2_VFREQLOW(pipe_config->cpu_transcoder), + TRANS_DP2_VFREQ_PIXEL_CLOCK(crtc_clock_hz & 0xffffff)); + } + intel_ddi_enable_transcoder_func(encoder, pipe_config); intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(trans), 0, -- cgit v1.2.3 From e6e0edfdbbab30fcfe5e40c051190f556a527925 Mon Sep 17 00:00:00 2001 From: Tejas Upadhyay Date: Tue, 7 Sep 2021 17:06:58 +0530 Subject: drm/i915/display: Add HDR mode helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add helper function with returns if HDR mode in on Signed-off-by: Tejas Upadhyay Link: https://patchwork.freedesktop.org/patch/msgid/20210907113658.1351456-1-tejaskumarx.surendrakumar.upadhyay@intel.com [vsyrjala: fix up alignment to match codingstyle] Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_display.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index f6c0c595f631..21ca15f69d2c 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -183,6 +183,12 @@ static void intel_update_czclk(struct drm_i915_private *dev_priv) dev_priv->czclk_freq); } +static bool is_hdr_mode(const struct intel_crtc_state *crtc_state) +{ + return (crtc_state->active_planes & + ~(icl_hdr_plane_mask() | BIT(PLANE_CURSOR))) == 0; +} + /* WA Display #0827: Gen9:all */ static void skl_wa_827(struct drm_i915_private *dev_priv, enum pipe pipe, bool enable) @@ -5258,9 +5264,7 @@ static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state) val |= PIPEMISC_YUV420_ENABLE | PIPEMISC_YUV420_MODE_FULL_BLEND; - if (DISPLAY_VER(dev_priv) >= 11 && - (crtc_state->active_planes & ~(icl_hdr_plane_mask() | - BIT(PLANE_CURSOR))) == 0) + if (DISPLAY_VER(dev_priv) >= 11 && is_hdr_mode(crtc_state)) val |= PIPEMISC_HDR_MODE_PRECISION; if (DISPLAY_VER(dev_priv) >= 12) -- cgit v1.2.3 From 5a623ff81d6f85015b8000e910dd8ee27edee819 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 14 May 2021 15:57:38 +0300 Subject: drm/i915: s/crtc_state/new_crtc_state/ etc. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_plane_atomic_calc_changes() deals with both the old and new crtc/plane states. Make the variable names reflect that more clearly. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210514125751.17075-2-ville.syrjala@linux.intel.com Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_display.c | 38 ++++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 21ca15f69d2c..23b1e0ccc72d 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6362,27 +6362,27 @@ static bool needs_scaling(const struct intel_plane_state *state) } int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state, - struct intel_crtc_state *crtc_state, + struct intel_crtc_state *new_crtc_state, const struct intel_plane_state *old_plane_state, - struct intel_plane_state *plane_state) + struct intel_plane_state *new_plane_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); + struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); + struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - bool mode_changed = intel_crtc_needs_modeset(crtc_state); + bool mode_changed = intel_crtc_needs_modeset(new_crtc_state); bool was_crtc_enabled = old_crtc_state->hw.active; - bool is_crtc_enabled = crtc_state->hw.active; + bool is_crtc_enabled = new_crtc_state->hw.active; bool turn_off, turn_on, visible, was_visible; int ret; if (DISPLAY_VER(dev_priv) >= 9 && plane->id != PLANE_CURSOR) { - ret = skl_update_scaler_plane(crtc_state, plane_state); + ret = skl_update_scaler_plane(new_crtc_state, new_plane_state); if (ret) return ret; } was_visible = old_plane_state->uapi.visible; - visible = plane_state->uapi.visible; + visible = new_plane_state->uapi.visible; if (!was_crtc_enabled && drm_WARN_ON(&dev_priv->drm, was_visible)) was_visible = false; @@ -6398,7 +6398,7 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat * only combine the results from all planes in the current place? */ if (!is_crtc_enabled) { - intel_plane_set_invisible(crtc_state, plane_state); + intel_plane_set_invisible(new_crtc_state, new_plane_state); visible = false; } @@ -6417,28 +6417,28 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat if (turn_on) { if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) - crtc_state->update_wm_pre = true; + new_crtc_state->update_wm_pre = true; /* must disable cxsr around plane enable/disable */ if (plane->id != PLANE_CURSOR) - crtc_state->disable_cxsr = true; + new_crtc_state->disable_cxsr = true; } else if (turn_off) { if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) - crtc_state->update_wm_post = true; + new_crtc_state->update_wm_post = true; /* must disable cxsr around plane enable/disable */ if (plane->id != PLANE_CURSOR) - crtc_state->disable_cxsr = true; - } else if (intel_wm_need_update(old_plane_state, plane_state)) { + new_crtc_state->disable_cxsr = true; + } else if (intel_wm_need_update(old_plane_state, new_plane_state)) { if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) { /* FIXME bollocks */ - crtc_state->update_wm_pre = true; - crtc_state->update_wm_post = true; + new_crtc_state->update_wm_pre = true; + new_crtc_state->update_wm_post = true; } } if (visible || was_visible) - crtc_state->fb_bits |= plane->frontbuffer_bit; + new_crtc_state->fb_bits |= plane->frontbuffer_bit; /* * ILK/SNB DVSACNTR/Sprite Enable @@ -6477,8 +6477,8 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) && (turn_on || (!needs_scaling(old_plane_state) && - needs_scaling(plane_state)))) - crtc_state->disable_lp_wm = true; + needs_scaling(new_plane_state)))) + new_crtc_state->disable_lp_wm = true; return 0; } -- cgit v1.2.3 From 8f27dbf0987ad5941f969456fa6f65850866ba2e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 14 May 2021 15:57:40 +0300 Subject: drm/i915: Use u8 consistently for active_planes bitmask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Be consistent in that active_planes bitmask fits in a u8. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210514125751.17075-4-ville.syrjala@linux.intel.com Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/intel_pm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index cfc41f8fa74a..9452f5af070d 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1708,7 +1708,7 @@ static int vlv_compute_fifo(struct intel_crtc_state *crtc_state) const struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2]; struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state; - unsigned int active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); + u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); int num_active_planes = hweight8(active_planes); const int fifo_size = 511; int fifo_extra, fifo_left = fifo_size; @@ -1900,8 +1900,8 @@ static int vlv_compute_pipe_wm(struct intel_atomic_state *state, struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal; const struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state; - int num_active_planes = hweight8(crtc_state->active_planes & - ~BIT(PLANE_CURSOR)); + u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); + int num_active_planes = hweight8(active_planes); bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->uapi); const struct intel_plane_state *old_plane_state; const struct intel_plane_state *new_plane_state; -- cgit v1.2.3 From 0cf771b5d02244d2b2515cb17d967e19bf33e83f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 14 May 2021 15:57:39 +0300 Subject: drm/i915: Fix g4x cxsr enable condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The intention was to check whether the primary plane is enabled without any sprites planes being enabled. Instead we ended up checking whether just any one of the planes is enabled. g4x isn't vlv/chv and cxsr only works with the primary plane. Fix the check to examine the bitmask of active planes rather than the number of bits set in said bitmask. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210514125751.17075-3-ville.syrjala@linux.intel.com Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/intel_pm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9452f5af070d..456bc6e16fc9 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1376,8 +1376,7 @@ static int g4x_compute_pipe_wm(struct intel_atomic_state *state, struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct g4x_wm_state *wm_state = &crtc_state->wm.g4x.optimal; - int num_active_planes = hweight8(crtc_state->active_planes & - ~BIT(PLANE_CURSOR)); + u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR); const struct g4x_pipe_wm *raw; const struct intel_plane_state *old_plane_state; const struct intel_plane_state *new_plane_state; @@ -1417,7 +1416,7 @@ static int g4x_compute_pipe_wm(struct intel_atomic_state *state, wm_state->sr.cursor = raw->plane[PLANE_CURSOR]; wm_state->sr.fbc = raw->fbc; - wm_state->cxsr = num_active_planes == BIT(PLANE_PRIMARY); + wm_state->cxsr = active_planes == BIT(PLANE_PRIMARY); level = G4X_WM_LEVEL_HPLL; if (!g4x_raw_crtc_wm_is_valid(crtc_state, level)) -- cgit v1.2.3 From 52913626cf9abc7d0117fdeac6d3013b230d1d83 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 14 May 2021 15:57:41 +0300 Subject: drm/i915: Apply WaUse32BppForSRWM to elk as well as ctg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The w/a database lists this for both ctg and elk. So let's apply it to elk as well. And add the w/a name. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210514125751.17075-5-ville.syrjala@linux.intel.com Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/intel_pm.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 456bc6e16fc9..74fd6aa7afc7 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1152,17 +1152,13 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state, cpp = plane_state->hw.fb->format->cpp[0]; /* - * Not 100% sure which way ELK should go here as the - * spec only says CL/CTG should assume 32bpp and BW - * doesn't need to. But as these things followed the - * mobile vs. desktop lines on gen3 as well, let's - * assume ELK doesn't need this. + * WaUse32BppForSRWM:ctg,elk * - * The spec also fails to list such a restriction for - * the HPLL watermark, which seems a little strange. + * The spec fails to list this restriction for the + * HPLL watermark, which seems a little strange. * Let's use 32bpp for the HPLL watermark as well. */ - if (IS_GM45(dev_priv) && plane->id == PLANE_PRIMARY && + if (plane->id == PLANE_PRIMARY && level != G4X_WM_LEVEL_NORMAL) cpp = max(cpp, 4u); -- cgit v1.2.3 From aad24cc4bd563200e9536b044bdde1550b00103b Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 6 Sep 2021 21:27:10 +0300 Subject: drm/i915: Use tile block based dimensions for CCS origin x, y check The tile size for all surface types is 4 kbyte (or 2 kbyte on old platforms), with the exception of the TGL/ADL CCS surface where the tile size is 64 bytes. To be able to remap CCS FBs the CCS surface tile needs to be defined as 4 kbyte as well (the granularity of GTT pages in a remapped view). The only place using the dimension of the 64 byte CCS area is the initial check for the main vs. CCS plane origin coordinate match. To prepare for adding support for remapping CCS FBs let's call the 64 byte CCS area a 'tile block' and add a helper to retrieve the dimensions for it. No functional change. Cc: Juha-Pekka Heikkila Signed-off-by: Imre Deak Reviewed-by: Juha-Pekka Heikkila Link: https://patchwork.freedesktop.org/patch/msgid/20210906182715.3915100-2-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_fb.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index e4b8602ec0cd..0cf568a9cb1c 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -143,14 +143,14 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane) unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane) { - if (is_gen12_ccs_plane(fb, color_plane)) - return 1; - return intel_tile_size(to_i915(fb->dev)) / intel_tile_width_bytes(fb, color_plane); } -/* Return the tile dimensions in pixel units */ +/* + * Return the tile dimensions in pixel units, based on the (2 or 4 kbyte) GTT + * page tile size. + */ static void intel_tile_dims(const struct drm_framebuffer *fb, int color_plane, unsigned int *tile_width, unsigned int *tile_height) @@ -162,6 +162,21 @@ static void intel_tile_dims(const struct drm_framebuffer *fb, int color_plane, *tile_height = intel_tile_height(fb, color_plane); } +/* + * Return the tile dimensions in pixel units, based on the tile block size. + * The block covers the full GTT page sized tile on all tiled surfaces and + * it's a 64 byte portion of the tile on TGL+ CCS surfaces. + */ +static void intel_tile_block_dims(const struct drm_framebuffer *fb, int color_plane, + unsigned int *tile_width, + unsigned int *tile_height) +{ + intel_tile_dims(fb, color_plane, tile_width, tile_height); + + if (is_gen12_ccs_plane(fb, color_plane)) + *tile_height = 1; +} + unsigned int intel_tile_row_size(const struct drm_framebuffer *fb, int color_plane) { unsigned int tile_width, tile_height; @@ -567,7 +582,12 @@ static int intel_fb_check_ccs_xy(const struct drm_framebuffer *fb, int ccs_plane if (!is_ccs_plane(fb, ccs_plane) || is_gen12_ccs_cc_plane(fb, ccs_plane)) return 0; - intel_tile_dims(fb, ccs_plane, &tile_width, &tile_height); + /* + * While all the tile dimensions are based on a 2k or 4k GTT page size + * here the main and CCS coordinates must match only within a (64 byte + * on TGL+) block inside the tile. + */ + intel_tile_block_dims(fb, ccs_plane, &tile_width, &tile_height); intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs_plane); tile_width *= hsub; -- cgit v1.2.3 From 9814948e3cfea1771b9f816fb75cae1db4526bd2 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 6 Sep 2021 21:27:11 +0300 Subject: drm/i915/adlp: Require always a power-of-two sized CCS surface stride At the moment CCS FB strides must be power-of-two sized, but a follow-up change will add support remapping these FBs, allowing the FB passed in by userspace to have a non-POT sized stride. For these remapped FBs we can only remap the main surface, not the CCS surface. This means that userspace has to always generate the CCS surface aligning to the POT stride padded main surface (by setting up the CCS AUX pagetables accordingly). Adjust the CCS surface stride check to enforce this. No functional change. v2: - Fix the gen12_ccs_aux_stride() is not static sparse warning. Cc: Juha-Pekka Heikkila Signed-off-by: Imre Deak Reviewed-by: Juha-Pekka Heikkila Link: https://patchwork.freedesktop.org/patch/msgid/20210906182715.3915100-3-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_fb.c | 34 +++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 0cf568a9cb1c..a0db67e85c71 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -63,10 +63,36 @@ int skl_ccs_to_main_plane(const struct drm_framebuffer *fb, int ccs_plane) return ccs_plane - fb->format->num_planes / 2; } -static int gen12_ccs_aux_stride(struct drm_framebuffer *fb, int ccs_plane) +static unsigned int gen12_aligned_scanout_stride(const struct intel_framebuffer *fb, + int color_plane) { - return DIV_ROUND_UP(fb->pitches[skl_ccs_to_main_plane(fb, ccs_plane)], - 512) * 64; + struct drm_i915_private *i915 = to_i915(fb->base.dev); + unsigned int stride = fb->base.pitches[color_plane]; + + if (IS_ALDERLAKE_P(i915)) + return roundup_pow_of_two(max(stride, + 8u * intel_tile_width_bytes(&fb->base, color_plane))); + + return stride; +} + +static unsigned int gen12_ccs_aux_stride(struct intel_framebuffer *fb, int ccs_plane) +{ + struct drm_i915_private *i915 = to_i915(fb->base.dev); + int main_plane = skl_ccs_to_main_plane(&fb->base, ccs_plane); + unsigned int main_stride = fb->base.pitches[main_plane]; + unsigned int main_tile_width = intel_tile_width_bytes(&fb->base, main_plane); + + /* + * On ADL-P the AUX stride must align with a power-of-two aligned main + * surface stride. The stride of the allocated main surface object can + * be less than this POT stride, which is then autopadded to the POT + * size. + */ + if (IS_ALDERLAKE_P(i915)) + main_stride = gen12_aligned_scanout_stride(fb, main_plane); + + return DIV_ROUND_UP(main_stride, 4 * main_tile_width) * 64; } int skl_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane) @@ -1379,7 +1405,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, } if (is_gen12_ccs_plane(fb, i) && !is_gen12_ccs_cc_plane(fb, i)) { - int ccs_aux_stride = gen12_ccs_aux_stride(fb, i); + int ccs_aux_stride = gen12_ccs_aux_stride(intel_fb, i); if (fb->pitches[i] != ccs_aux_stride) { drm_dbg_kms(&dev_priv->drm, -- cgit v1.2.3 From 92dff6c79b16cad7f197fb5cd4756cf8db9ff777 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 6 Sep 2021 21:27:12 +0300 Subject: drm/i915/adlp: Assert that VMAs in DPT start at 0 Atm the DPT object can accommodate only one VMA, so the VMA offset will be always 0. Add an assert for this. Cc: Juha-Pekka Heikkila Signed-off-by: Imre Deak Reviewed-by: Juha-Pekka Heikkila Link: https://patchwork.freedesktop.org/patch/msgid/20210906182715.3915100-4-imre.deak@intel.com --- drivers/gpu/drm/i915/display/skl_universal_plane.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 724e7b04f3b6..f50282b60de4 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -993,6 +993,11 @@ static u32 skl_surf_address(const struct intel_plane_state *plane_state, u32 offset = plane_state->view.color_plane[color_plane].offset; if (intel_fb_uses_dpt(fb)) { + /* + * The DPT object contains only one vma, so the VMA's offset + * within the DPT is always 0. + */ + WARN_ON(plane_state->dpt_vma->node.start); WARN_ON(offset & 0x1fffff); return offset >> 9; } else { -- cgit v1.2.3 From 929dd111dcf8395e72635e0e7a4e502a6bb6b3d0 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 6 Sep 2021 21:27:13 +0300 Subject: drm/i915: Follow a new->old platform check order in intel_fb_stride_alignment Follow the usual new->old order in intel_fb_stride_alignment() platform check ladder. Cc: Juha-Pekka Heikkila Signed-off-by: Imre Deak Reviewed-by: Juha-Pekka Heikkila Link: https://patchwork.freedesktop.org/patch/msgid/20210906182715.3915100-5-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_fb.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index a0db67e85c71..479c76c7958c 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1158,6 +1158,12 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane) tile_width = intel_tile_width_bytes(fb, color_plane); if (is_ccs_modifier(fb->modifier)) { + /* + * On TGL the surface stride must be 4 tile aligned, mapped by + * one 64 byte cacheline on the CCS AUX surface. + */ + if (DISPLAY_VER(dev_priv) >= 12) + tile_width *= 4; /* * Display WA #0531: skl,bxt,kbl,glk * @@ -1167,14 +1173,8 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane) * require the entire fb to accommodate that to avoid * potential runtime errors at plane configuration time. */ - if ((DISPLAY_VER(dev_priv) == 9 || IS_GEMINILAKE(dev_priv)) && - color_plane == 0 && fb->width > 3840) - tile_width *= 4; - /* - * The main surface pitch must be padded to a multiple of four - * tile widths. - */ - else if (DISPLAY_VER(dev_priv) >= 12) + else if ((DISPLAY_VER(dev_priv) == 9 || IS_GEMINILAKE(dev_priv)) && + color_plane == 0 && fb->width > 3840) tile_width *= 4; } return tile_width; -- cgit v1.2.3 From 3d1adc3d64cfc544044feeca9c892599199f9616 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 6 Sep 2021 21:27:14 +0300 Subject: drm/i915/adlp: Add support for remapping CCS FBs Add support for remapping CCS FBs on ADL-P to remove the restriction of the power-of-two sized stride and the 2MB surface offset alignment for these FBs. We can only remap the tiles on the main surface, not the tiles on the CCS surface, so userspace has to generate the CCS surface aligning to the POT size padded main surface stride (by programming the AUX pagetable accordingly). For the required AUX pagetable setup, this requires that either the main surface stride is 8 tiles or that the stride is 16 tiles aligned (= 64 kbytes, the area mapped by one AUX PTE). v2: - Init intel_remapped_info::plane_alignment only for remapped views and do this from intel_fb_view_init(). Cc: Juha-Pekka Heikkila Signed-off-by: Imre Deak Reviewed-by: Juha-Pekka Heikkila Link: https://patchwork.freedesktop.org/patch/msgid/20210906182715.3915100-6-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 5 +- drivers/gpu/drm/i915/display/intel_display_types.h | 2 - drivers/gpu/drm/i915/display/intel_fb.c | 93 +++++++++++++--------- drivers/gpu/drm/i915/gt/intel_ggtt.c | 29 ++++++- drivers/gpu/drm/i915/i915_vma_types.h | 7 +- 5 files changed, 89 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 23b1e0ccc72d..49d99915b440 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -899,8 +899,11 @@ unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info unsigned int size = 0; int i; - for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) + for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) { + if (rem_info->plane_alignment) + size = ALIGN(size, rem_info->plane_alignment); size += rem_info->plane[i].dst_stride * rem_info->plane[i].height; + } return size; } diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index e9e806d90eec..73930c24d7fb 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -103,8 +103,6 @@ struct intel_fb_view { * in the rotated and remapped GTT view all no-CCS formats (up to 2 * color planes) are supported. * - * TODO: add support for CCS formats in the remapped GTT view. - * * The view information shared by all FB color planes in the FB, * like dst x/y and src/dst width, is stored separately in * intel_plane_state. diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 479c76c7958c..fa1f375e696b 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -357,15 +357,29 @@ void intel_fb_plane_get_subsampling(int *hsub, int *vsub, static void intel_fb_plane_dims(const struct intel_framebuffer *fb, int color_plane, int *w, int *h) { + struct drm_i915_private *i915 = to_i915(fb->base.dev); int main_plane = is_ccs_plane(&fb->base, color_plane) ? skl_ccs_to_main_plane(&fb->base, color_plane) : 0; + unsigned int main_width = fb->base.width; + unsigned int main_height = fb->base.height; int main_hsub, main_vsub; int hsub, vsub; + /* + * On ADL-P the CCS AUX surface layout always aligns with the + * power-of-two aligned main surface stride. The main surface + * stride in the allocated FB object may not be power-of-two + * sized, in which case it is auto-padded to the POT size. + */ + if (IS_ALDERLAKE_P(i915) && is_ccs_plane(&fb->base, color_plane)) + main_width = gen12_aligned_scanout_stride(fb, 0) / + fb->base.format->cpp[0]; + intel_fb_plane_get_subsampling(&main_hsub, &main_vsub, &fb->base, main_plane); intel_fb_plane_get_subsampling(&hsub, &vsub, &fb->base, color_plane); - *w = fb->base.width / main_hsub / hsub; - *h = fb->base.height / main_vsub / vsub; + + *w = main_width / main_hsub / hsub; + *h = main_height / main_vsub / vsub; } static u32 intel_adjust_tile_offset(int *x, int *y, @@ -547,17 +561,8 @@ static int intel_fb_offset_to_xy(int *x, int *y, unsigned int height; u32 alignment; - /* - * All DPT color planes must be 512*4k aligned (the amount mapped by a - * single DPT page). For ADL_P CCS FBs this only works by requiring - * the allocated offsets to be 2MB aligned. Once supoort to remap - * such FBs is added we can remove this requirement, as then all the - * planes can be remapped to an aligned offset. - */ - if (IS_ALDERLAKE_P(i915) && is_ccs_modifier(fb->modifier)) - alignment = 512 * 4096; - else if (DISPLAY_VER(i915) >= 12 && - is_semiplanar_uv_plane(fb, color_plane)) + if (DISPLAY_VER(i915) >= 12 && + is_semiplanar_uv_plane(fb, color_plane)) alignment = intel_tile_row_size(fb, color_plane); else if (fb->modifier != DRM_FORMAT_MOD_LINEAR) alignment = intel_tile_size(i915); @@ -688,8 +693,7 @@ bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb) { struct drm_i915_private *i915 = to_i915(fb->base.dev); - return IS_ALDERLAKE_P(i915) && fb->base.modifier != DRM_FORMAT_MOD_LINEAR && - !is_ccs_modifier(fb->base.modifier); + return IS_ALDERLAKE_P(i915) && fb->base.modifier != DRM_FORMAT_MOD_LINEAR; } static int intel_fb_pitch(const struct intel_framebuffer *fb, int color_plane, unsigned int rotation) @@ -809,14 +813,16 @@ static unsigned int plane_view_dst_stride_tiles(const struct intel_framebuffer *fb, int color_plane, unsigned int pitch_tiles) { - if (intel_fb_needs_pot_stride_remap(fb)) + if (intel_fb_needs_pot_stride_remap(fb)) { + unsigned int min_stride = is_ccs_plane(&fb->base, color_plane) ? 2 : 8; /* * ADL_P, the only platform needing a POT stride has a minimum - * of 8 stride tiles. + * of 8 main surface and 2 CCS AUX stride tiles. */ - return roundup_pow_of_two(max(pitch_tiles, 8u)); - else + return roundup_pow_of_two(max(pitch_tiles, min_stride)); + } else { return pitch_tiles; + } } static unsigned int @@ -852,7 +858,7 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p unsigned int tile_height = dims->tile_height; unsigned int tile_size = intel_tile_size(i915); struct drm_rect r; - u32 size; + u32 size = 0; assign_chk_ovf(i915, remap_info->offset, obj_offset); assign_chk_ovf(i915, remap_info->src_stride, plane_view_src_stride_tiles(fb, color_plane, dims)); @@ -877,7 +883,7 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p color_plane_info->stride = remap_info->dst_stride * tile_height; - size = remap_info->dst_stride * remap_info->width; + size += remap_info->dst_stride * remap_info->width; /* rotate the tile dimensions to match the GTT view */ swap(tile_width, tile_height); @@ -886,6 +892,14 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p check_array_bounds(i915, view->gtt.remapped.plane, color_plane); + if (view->gtt.remapped.plane_alignment) { + unsigned int aligned_offset = ALIGN(gtt_offset, + view->gtt.remapped.plane_alignment); + + size += aligned_offset - gtt_offset; + gtt_offset = aligned_offset; + } + assign_chk_ovf(i915, remap_info->dst_stride, plane_view_dst_stride_tiles(fb, color_plane, remap_info->width)); @@ -895,7 +909,7 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p color_plane_info->stride = remap_info->dst_stride * tile_width * fb->base.format->cpp[color_plane]; - size = remap_info->dst_stride * remap_info->height; + size += remap_info->dst_stride * remap_info->height; } /* @@ -942,10 +956,14 @@ calc_plane_normal_size(const struct intel_framebuffer *fb, int color_plane, return tiles; } -static void intel_fb_view_init(struct intel_fb_view *view, enum i915_ggtt_view_type view_type) +static void intel_fb_view_init(struct drm_i915_private *i915, struct intel_fb_view *view, + enum i915_ggtt_view_type view_type) { memset(view, 0, sizeof(*view)); view->gtt.type = view_type; + + if (view_type == I915_GGTT_VIEW_REMAPPED && IS_ALDERLAKE_P(i915)) + view->gtt.remapped.plane_alignment = SZ_2M / PAGE_SIZE; } bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb) @@ -966,16 +984,16 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer * int i, num_planes = fb->base.format->num_planes; unsigned int tile_size = intel_tile_size(i915); - intel_fb_view_init(&fb->normal_view, I915_GGTT_VIEW_NORMAL); + intel_fb_view_init(i915, &fb->normal_view, I915_GGTT_VIEW_NORMAL); drm_WARN_ON(&i915->drm, intel_fb_supports_90_270_rotation(fb) && intel_fb_needs_pot_stride_remap(fb)); if (intel_fb_supports_90_270_rotation(fb)) - intel_fb_view_init(&fb->rotated_view, I915_GGTT_VIEW_ROTATED); + intel_fb_view_init(i915, &fb->rotated_view, I915_GGTT_VIEW_ROTATED); if (intel_fb_needs_pot_stride_remap(fb)) - intel_fb_view_init(&fb->remapped_view, I915_GGTT_VIEW_REMAPPED); + intel_fb_view_init(i915, &fb->remapped_view, I915_GGTT_VIEW_REMAPPED); for (i = 0; i < num_planes; i++) { struct fb_plane_view_dims view_dims; @@ -1053,7 +1071,7 @@ static void intel_plane_remap_gtt(struct intel_plane_state *plane_state) unsigned int src_w, src_h; u32 gtt_offset = 0; - intel_fb_view_init(&plane_state->view, + intel_fb_view_init(i915, &plane_state->view, drm_rotation_90_or_270(rotation) ? I915_GGTT_VIEW_ROTATED : I915_GGTT_VIEW_REMAPPED); @@ -1158,11 +1176,19 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane) tile_width = intel_tile_width_bytes(fb, color_plane); if (is_ccs_modifier(fb->modifier)) { + /* + * On ADL-P the stride must be either 8 tiles or a stride + * that is aligned to 16 tiles, required by the 16 tiles = + * 64 kbyte CCS AUX PTE granularity, allowing CCS FBs to be + * remapped. + */ + if (IS_ALDERLAKE_P(dev_priv)) + tile_width *= fb->pitches[0] <= tile_width * 8 ? 8 : 16; /* * On TGL the surface stride must be 4 tile aligned, mapped by * one 64 byte cacheline on the CCS AUX surface. */ - if (DISPLAY_VER(dev_priv) >= 12) + else if (DISPLAY_VER(dev_priv) >= 12) tile_width *= 4; /* * Display WA #0531: skl,bxt,kbl,glk @@ -1416,17 +1442,6 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, } } - /* TODO: Add POT stride remapping support for CCS formats as well. */ - if (IS_ALDERLAKE_P(dev_priv) && - mode_cmd->modifier[i] != DRM_FORMAT_MOD_LINEAR && - !intel_fb_needs_pot_stride_remap(intel_fb) && - !is_power_of_2(mode_cmd->pitches[i])) { - drm_dbg_kms(&dev_priv->drm, - "plane %d pitch (%d) must be power of two for tiled buffers\n", - i, mode_cmd->pitches[i]); - goto err; - } - fb->obj[i] = &obj->base; } diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index de3ac58fceec..cbd0e1010a46 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -1373,13 +1373,28 @@ err_st_alloc: } static struct scatterlist * -remap_pages(struct drm_i915_gem_object *obj, unsigned int offset, +remap_pages(struct drm_i915_gem_object *obj, + unsigned int offset, unsigned int alignment_pad, unsigned int width, unsigned int height, unsigned int src_stride, unsigned int dst_stride, struct sg_table *st, struct scatterlist *sg) { unsigned int row; + if (alignment_pad) { + st->nents++; + + /* + * The DE ignores the PTEs for the padding tiles, the sg entry + * here is just a convenience to indicate how many padding PTEs + * to insert at this spot. + */ + sg_set_page(sg, NULL, alignment_pad * 4096, 0); + sg_dma_address(sg) = 0; + sg_dma_len(sg) = alignment_pad * 4096; + sg = sg_next(sg); + } + for (row = 0; row < height; row++) { unsigned int left = width * I915_GTT_PAGE_SIZE; @@ -1439,6 +1454,7 @@ intel_remap_pages(struct intel_remapped_info *rem_info, struct drm_i915_private *i915 = to_i915(obj->base.dev); struct sg_table *st; struct scatterlist *sg; + unsigned int gtt_offset = 0; int ret = -ENOMEM; int i; @@ -1455,10 +1471,19 @@ intel_remap_pages(struct intel_remapped_info *rem_info, sg = st->sgl; for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) { - sg = remap_pages(obj, rem_info->plane[i].offset, + unsigned int alignment_pad = 0; + + if (rem_info->plane_alignment) + alignment_pad = ALIGN(gtt_offset, rem_info->plane_alignment) - gtt_offset; + + sg = remap_pages(obj, + rem_info->plane[i].offset, alignment_pad, rem_info->plane[i].width, rem_info->plane[i].height, rem_info->plane[i].src_stride, rem_info->plane[i].dst_stride, st, sg); + + gtt_offset += alignment_pad + + rem_info->plane[i].dst_stride * rem_info->plane[i].height; } i915_sg_trim(st); diff --git a/drivers/gpu/drm/i915/i915_vma_types.h b/drivers/gpu/drm/i915/i915_vma_types.h index 995b502d7e5d..80e93bf00f2e 100644 --- a/drivers/gpu/drm/i915/i915_vma_types.h +++ b/drivers/gpu/drm/i915/i915_vma_types.h @@ -105,8 +105,9 @@ struct intel_remapped_plane_info { } __packed; struct intel_remapped_info { - struct intel_remapped_plane_info plane[2]; - u32 unused_mbz; + struct intel_remapped_plane_info plane[4]; + /* in gtt pages */ + u32 plane_alignment; } __packed; struct intel_rotation_info { @@ -129,7 +130,7 @@ static inline void assert_i915_gem_gtt_types(void) { BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 2 * sizeof(u32) + 8 * sizeof(u16)); BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int)); - BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 3 * sizeof(u32) + 8 * sizeof(u16)); + BUILD_BUG_ON(sizeof(struct intel_remapped_info) != 5 * sizeof(u32) + 16 * sizeof(u16)); /* Check that rotation/remapped shares offsets for simplicity */ BUILD_BUG_ON(offsetof(struct intel_remapped_info, plane[0]) != -- cgit v1.2.3 From 27493cb8747e8389a70a053445daf6a5c7888c3c Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Wed, 22 Sep 2021 14:52:40 -0700 Subject: drm/i915/display/dmc: Set DC_STATE_DEBUG_MASK_CORES after firmware load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Specification asks for DC_STATE_DEBUG_MASK_CORES to be set for all platforms that supports DMC, not only for geminilake and broxton. While at is also taking the oportunity to simply the code. BSpec: 7402 BSpec: 49436 Reviewed-by: Imre Deak Cc: Imre Deak Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210922215242.66683-1-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index b0268552b286..2dc9d632969d 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -255,20 +255,10 @@ intel_get_stepping_info(struct drm_i915_private *i915, static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv) { - u32 val, mask; - - mask = DC_STATE_DEBUG_MASK_MEMORY_UP; - - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) - mask |= DC_STATE_DEBUG_MASK_CORES; - /* The below bit doesn't need to be cleared ever afterwards */ - val = intel_de_read(dev_priv, DC_STATE_DEBUG); - if ((val & mask) != mask) { - val |= mask; - intel_de_write(dev_priv, DC_STATE_DEBUG, val); - intel_de_posting_read(dev_priv, DC_STATE_DEBUG); - } + intel_de_rmw(dev_priv, DC_STATE_DEBUG, 0, + DC_STATE_DEBUG_MASK_CORES | DC_STATE_DEBUG_MASK_MEMORY_UP); + intel_de_posting_read(dev_priv, DC_STATE_DEBUG); } /** -- cgit v1.2.3 From 73262db68c27ed25452ffd3b57e051e1791de713 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Wed, 22 Sep 2021 14:52:41 -0700 Subject: drm/i915/display: Match PSR2 selective fetch sequences with specification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were not completely following the selective fetch programming sequence, here some things we were doing wrong: - not programming plane selective fetch a PSR2_MAN_TRK_CTL registers when doing a modeset - programming PSR2_MAN_TRK_CTL out of vblank With this changes the last remainig underrun found in Alderlake-P is fixed. Bspec: 55229 Tested-by: Gwan-gyeong Mun Reviewed-by: Gwan-gyeong Mun Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210922215242.66683-2-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_cursor.c | 4 ++- drivers/gpu/drm/i915/display/intel_display.c | 12 ++++---- drivers/gpu/drm/i915/display/intel_psr.c | 33 ++++++++++++++++------ drivers/gpu/drm/i915/display/intel_psr.h | 2 ++ drivers/gpu/drm/i915/display/skl_universal_plane.c | 4 +-- 5 files changed, 36 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index c7618fef0143..901ad3a4c8c3 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -536,8 +536,10 @@ static void i9xx_update_cursor(struct intel_plane *plane, if (DISPLAY_VER(dev_priv) >= 9) skl_write_cursor_wm(plane, crtc_state); - if (!intel_crtc_needs_modeset(crtc_state)) + if (plane_state) intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, 0); + else + intel_psr2_disable_plane_sel_fetch(plane, crtc_state); if (plane->cursor.base != base || plane->cursor.size != fbc_ctl || diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 49d99915b440..ac33bb935e9b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6819,11 +6819,9 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state, } - if (!mode_changed) { - ret = intel_psr2_sel_fetch_update(state, crtc); - if (ret) - return ret; - } + ret = intel_psr2_sel_fetch_update(state, crtc); + if (ret) + return ret; return 0; } @@ -9716,10 +9714,10 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state, if (new_crtc_state->update_pipe) intel_pipe_fastset(old_crtc_state, new_crtc_state); - - intel_psr2_program_trans_man_trk_ctl(new_crtc_state); } + intel_psr2_program_trans_man_trk_ctl(new_crtc_state); + if (dev_priv->display.atomic_update_watermarks) dev_priv->display.atomic_update_watermarks(state, crtc); } diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index c1894b056d6c..868e5205dd09 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -561,15 +561,16 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) val |= EDP_PSR2_SU_SDP_SCANLINE; if (intel_dp->psr.psr2_sel_fetch_enabled) { + u32 tmp; + /* Wa_1408330847 */ if (IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) intel_de_rmw(dev_priv, CHICKEN_PAR1_1, DIS_RAM_BYPASS_PSR2_MAN_TRACK, DIS_RAM_BYPASS_PSR2_MAN_TRACK); - intel_de_write(dev_priv, - PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), - PSR2_MAN_TRK_CTL_ENABLE); + tmp = intel_de_read(dev_priv, PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder)); + drm_WARN_ON(&dev_priv->drm, !(tmp & PSR2_MAN_TRK_CTL_ENABLE)); } else if (HAS_PSR2_SEL_FETCH(dev_priv)) { intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), 0); @@ -1450,6 +1451,18 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp) intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0); } +void intel_psr2_disable_plane_sel_fetch(struct intel_plane *plane, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + enum pipe pipe = plane->pipe; + + if (!crtc_state->enable_psr2_sel_fetch) + return; + + intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id), 0); +} + void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, @@ -1464,11 +1477,11 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, if (!crtc_state->enable_psr2_sel_fetch) return; - val = plane_state ? plane_state->ctl : 0; - val &= plane->id == PLANE_CURSOR ? val : PLANE_SEL_FETCH_CTL_ENABLE; - intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id), val); - if (!val || plane->id == PLANE_CURSOR) + if (plane->id == PLANE_CURSOR) { + intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id), + plane_state->ctl); return; + } clip = &plane_state->psr2_sel_fetch_area; @@ -1487,14 +1500,16 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, val = (drm_rect_height(clip) - 1) << 16; val |= (drm_rect_width(&plane_state->uapi.src) >> 16) - 1; intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_SIZE(pipe, plane->id), val); + + intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id), + PLANE_SEL_FETCH_CTL_ENABLE); } void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); - if (!HAS_PSR2_SEL_FETCH(dev_priv) || - !crtc_state->enable_psr2_sel_fetch) + if (!crtc_state->enable_psr2_sel_fetch) return; intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(crtc_state->cpu_transcoder), diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index 641521b101c8..e502964697c6 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -51,6 +51,8 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, int color_plane); +void intel_psr2_disable_plane_sel_fetch(struct intel_plane *plane, + const struct intel_crtc_state *crtc_state); void intel_psr_pause(struct intel_dp *intel_dp); void intel_psr_resume(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index f50282b60de4..91f1be7174e5 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -656,6 +656,7 @@ skl_disable_plane(struct intel_plane *plane, skl_write_plane_wm(plane, crtc_state); + intel_psr2_disable_plane_sel_fetch(plane, crtc_state); intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0); intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0); @@ -1101,8 +1102,7 @@ skl_program_plane(struct intel_plane *plane, (plane_state->view.color_plane[1].y << 16) | plane_state->view.color_plane[1].x); - if (!drm_atomic_crtc_needs_modeset(&crtc_state->uapi)) - intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, color_plane); + intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, color_plane); /* * Enable the scaler before the plane so that we don't -- cgit v1.2.3 From 9ce5884e5139037445d0efcf37aeba21008011ad Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Wed, 22 Sep 2021 14:52:42 -0700 Subject: drm/i915/display: Only keep PSR enabled if there is active planes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PSR always had a requirement to only be enabled if there is active planes but not following that never caused any issues. But that changes in Alderlake-P, leaving PSR enabled without active planes causes transcoder/port underruns. Similar behavior was fixed during the pipe disable sequence by commit 84030adb9e27 ("drm/i915/display: Disable audio, DRRS and PSR before planes"). intel_dp_compute_psr_vsc_sdp() had to move from intel_psr_enable_locked() to intel_psr_compute_config() because we need to be able to disable/enable PSR from atomic states without connector and encoder state. Reviewed-by: Gwan-gyeong Mun Cc: Ville Syrjälä Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210922215242.66683-3-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 2 - drivers/gpu/drm/i915/display/intel_display.c | 14 ++- drivers/gpu/drm/i915/display/intel_display_types.h | 3 +- drivers/gpu/drm/i915/display/intel_dp.c | 6 +- drivers/gpu/drm/i915/display/intel_dp.h | 2 +- drivers/gpu/drm/i915/display/intel_psr.c | 140 ++++++++++++--------- drivers/gpu/drm/i915/display/intel_psr.h | 11 +- 7 files changed, 98 insertions(+), 80 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index bba0ab99836b..a4667741d354 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3034,7 +3034,6 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state, intel_dp_stop_link_train(intel_dp, crtc_state); intel_edp_backlight_on(crtc_state, conn_state); - intel_psr_enable(intel_dp, crtc_state, conn_state); if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink) intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); @@ -3255,7 +3254,6 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state, intel_ddi_set_dp_msa(crtc_state, conn_state); - intel_psr_update(intel_dp, crtc_state, conn_state); intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); intel_drrs_update(intel_dp, crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ac33bb935e9b..f27c294beb92 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8098,10 +8098,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, if (bp_gamma) PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, hw.gamma_lut, bp_gamma); - PIPE_CONF_CHECK_BOOL(has_psr); - PIPE_CONF_CHECK_BOOL(has_psr2); - PIPE_CONF_CHECK_BOOL(enable_psr2_sel_fetch); - PIPE_CONF_CHECK_I(dc3co_exitline); + if (current_config->active_planes) { + PIPE_CONF_CHECK_BOOL(has_psr); + PIPE_CONF_CHECK_BOOL(has_psr2); + PIPE_CONF_CHECK_BOOL(enable_psr2_sel_fetch); + PIPE_CONF_CHECK_I(dc3co_exitline); + } } PIPE_CONF_CHECK_BOOL(double_wide); @@ -8158,7 +8160,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_I(min_voltage_level); } - if (fastset && (current_config->has_psr || pipe_config->has_psr)) + if (current_config->has_psr || pipe_config->has_psr) PIPE_CONF_CHECK_X_WITH_MASK(infoframes.enable, ~intel_hdmi_infoframe_enable(DP_SDP_VSC)); else @@ -10212,6 +10214,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_encoders_update_prepare(state); intel_dbuf_pre_plane_update(state); + intel_psr_pre_plane_update(state); for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { if (new_crtc_state->uapi.async_flip) @@ -10275,6 +10278,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) } intel_dbuf_post_plane_update(state); + intel_psr_post_plane_update(state); for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { intel_post_plane_update(state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 73930c24d7fb..9413ebae15f5 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1054,12 +1054,14 @@ struct intel_crtc_state { struct intel_link_m_n dp_m2_n2; bool has_drrs; + /* PSR is supported but might not be enabled due the lack of enabled planes */ bool has_psr; bool has_psr2; bool enable_psr2_sel_fetch; bool req_psr2_sdp_prior_scanline; u32 dc3co_exitline; u16 su_y_granularity; + struct drm_dp_vsc_sdp psr_vsc; /* * Frequence the dpll for the port should run at. Differs from the @@ -1523,7 +1525,6 @@ struct intel_psr { u32 dc3co_exitline; u32 dc3co_exit_delay; struct delayed_work dc3co_work; - struct drm_dp_vsc_sdp vsc; }; struct intel_dp { diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 7559911c140a..378008873e03 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1674,7 +1674,7 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp, { vsc->sdp_type = DP_SDP_VSC; - if (intel_dp->psr.psr2_enabled) { + if (crtc_state->has_psr2) { if (intel_dp->psr.colorimetry_support && intel_dp_needs_vsc_sdp(crtc_state, conn_state)) { /* [PSR2, +Colorimetry] */ @@ -1828,7 +1828,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, g4x_dp_set_clock(encoder, pipe_config); intel_vrr_compute_config(pipe_config, conn_state); - intel_psr_compute_config(intel_dp, pipe_config); + intel_psr_compute_config(intel_dp, pipe_config, conn_state); intel_drrs_compute_config(intel_dp, pipe_config, output_bpp, constant_n); intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state); @@ -2888,7 +2888,7 @@ static void intel_write_dp_sdp(struct intel_encoder *encoder, void intel_write_dp_vsc_sdp(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, - struct drm_dp_vsc_sdp *vsc) + const struct drm_dp_vsc_sdp *vsc) { struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 94b568704b22..3343c2591680 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -88,7 +88,7 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp, struct drm_dp_vsc_sdp *vsc); void intel_write_dp_vsc_sdp(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, - struct drm_dp_vsc_sdp *vsc); + const struct drm_dp_vsc_sdp *vsc); void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 868e5205dd09..19a96d3c4acf 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -950,7 +950,8 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, } void intel_psr_compute_config(struct intel_dp *intel_dp, - struct intel_crtc_state *crtc_state) + struct intel_crtc_state *crtc_state, + struct drm_connector_state *conn_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); const struct drm_display_mode *adjusted_mode = @@ -1002,7 +1003,10 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, crtc_state->has_psr = true; crtc_state->has_psr2 = intel_psr2_config_valid(intel_dp, crtc_state); + crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC); + intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state, conn_state, + &crtc_state->psr_vsc); } void intel_psr_get_config(struct intel_encoder *encoder, @@ -1182,8 +1186,7 @@ static bool psr_interrupt_error_check(struct intel_dp *intel_dp) } static void intel_psr_enable_locked(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) + const struct intel_crtc_state *crtc_state) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -1210,9 +1213,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp, drm_dbg_kms(&dev_priv->drm, "Enabling PSR%s\n", intel_dp->psr.psr2_enabled ? "2" : "1"); - intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state, conn_state, - &intel_dp->psr.vsc); - intel_write_dp_vsc_sdp(encoder, crtc_state, &intel_dp->psr.vsc); + intel_write_dp_vsc_sdp(encoder, crtc_state, &crtc_state->psr_vsc); intel_snps_phy_update_psr_power_state(dev_priv, phy, true); intel_psr_enable_sink(intel_dp); intel_psr_enable_source(intel_dp); @@ -1222,33 +1223,6 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp, intel_psr_activate(intel_dp); } -/** - * intel_psr_enable - Enable PSR - * @intel_dp: Intel DP - * @crtc_state: new CRTC state - * @conn_state: new CONNECTOR state - * - * This function can only be called after the pipe is fully trained and enabled. - */ -void intel_psr_enable(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) -{ - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - - if (!CAN_PSR(intel_dp)) - return; - - if (!crtc_state->has_psr) - return; - - drm_WARN_ON(&dev_priv->drm, dev_priv->drrs.dp); - - mutex_lock(&intel_dp->psr.lock); - intel_psr_enable_locked(intel_dp, crtc_state, conn_state); - mutex_unlock(&intel_dp->psr.lock); -} - static void intel_psr_exit(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -1734,48 +1708,92 @@ skip_sel_fetch_set_loop: return 0; } -/** - * intel_psr_update - Update PSR state - * @intel_dp: Intel DP - * @crtc_state: new CRTC state - * @conn_state: new CONNECTOR state - * - * This functions will update PSR states, disabling, enabling or switching PSR - * version when executing fastsets. For full modeset, intel_psr_disable() and - * intel_psr_enable() should be called instead. - */ -void intel_psr_update(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state) +static void _intel_psr_pre_plane_update(const struct intel_atomic_state *state, + const struct intel_crtc_state *crtc_state) { - struct intel_psr *psr = &intel_dp->psr; - bool enable, psr2_enable; + struct intel_encoder *encoder; - if (!CAN_PSR(intel_dp)) + for_each_intel_encoder_mask_with_psr(state->base.dev, encoder, + crtc_state->uapi.encoder_mask) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + struct intel_psr *psr = &intel_dp->psr; + bool needs_to_disable = false; + + mutex_lock(&psr->lock); + + /* + * Reasons to disable: + * - PSR disabled in new state + * - All planes will go inactive + * - Changing between PSR versions + */ + needs_to_disable |= !crtc_state->has_psr; + needs_to_disable |= !crtc_state->active_planes; + needs_to_disable |= crtc_state->has_psr2 != psr->psr2_enabled; + + if (psr->enabled && needs_to_disable) + intel_psr_disable_locked(intel_dp); + + mutex_unlock(&psr->lock); + } +} + +void intel_psr_pre_plane_update(const struct intel_atomic_state *state) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state; + struct intel_crtc *crtc; + int i; + + if (!HAS_PSR(dev_priv)) return; - mutex_lock(&intel_dp->psr.lock); + for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) + _intel_psr_pre_plane_update(state, crtc_state); +} - enable = crtc_state->has_psr; - psr2_enable = crtc_state->has_psr2; +static void _intel_psr_post_plane_update(const struct intel_atomic_state *state, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_encoder *encoder; + + if (!crtc_state->has_psr) + return; + + for_each_intel_encoder_mask_with_psr(state->base.dev, encoder, + crtc_state->uapi.encoder_mask) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + struct intel_psr *psr = &intel_dp->psr; + + mutex_lock(&psr->lock); + + drm_WARN_ON(&dev_priv->drm, psr->enabled && !crtc_state->active_planes); + + /* Only enable if there is active planes */ + if (!psr->enabled && crtc_state->active_planes) + intel_psr_enable_locked(intel_dp, crtc_state); - if (enable == psr->enabled && psr2_enable == psr->psr2_enabled && - crtc_state->enable_psr2_sel_fetch == psr->psr2_sel_fetch_enabled) { /* Force a PSR exit when enabling CRC to avoid CRC timeouts */ if (crtc_state->crc_enabled && psr->enabled) psr_force_hw_tracking_exit(intel_dp); - goto unlock; + mutex_unlock(&psr->lock); } +} - if (psr->enabled) - intel_psr_disable_locked(intel_dp); +void intel_psr_post_plane_update(const struct intel_atomic_state *state) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state; + struct intel_crtc *crtc; + int i; - if (enable) - intel_psr_enable_locked(intel_dp, crtc_state, conn_state); + if (!HAS_PSR(dev_priv)) + return; -unlock: - mutex_unlock(&intel_dp->psr.lock); + for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) + _intel_psr_post_plane_update(state, crtc_state); } /** diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index e502964697c6..facffbacd357 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -20,14 +20,10 @@ struct intel_plane; struct intel_encoder; void intel_psr_init_dpcd(struct intel_dp *intel_dp); -void intel_psr_enable(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); +void intel_psr_pre_plane_update(const struct intel_atomic_state *state); +void intel_psr_post_plane_update(const struct intel_atomic_state *state); void intel_psr_disable(struct intel_dp *intel_dp, const struct intel_crtc_state *old_crtc_state); -void intel_psr_update(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); int intel_psr_debug_set(struct intel_dp *intel_dp, u64 value); void intel_psr_invalidate(struct drm_i915_private *dev_priv, unsigned frontbuffer_bits, @@ -37,7 +33,8 @@ void intel_psr_flush(struct drm_i915_private *dev_priv, enum fb_op_origin origin); void intel_psr_init(struct intel_dp *intel_dp); void intel_psr_compute_config(struct intel_dp *intel_dp, - struct intel_crtc_state *crtc_state); + struct intel_crtc_state *crtc_state, + struct drm_connector_state *conn_state); void intel_psr_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config); void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir); -- cgit v1.2.3 From ab98ebb9a99aa0a9970d973fb7511e33f774f797 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 14 May 2021 15:57:42 +0300 Subject: drm/i915: Fix HPLL watermark readout for g4x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If HPLL watermarks are already enabled, let's not mark them as disabled by forgetting to bump 'level' before we call g4x_raw_plane_wm_set(). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210514125751.17075-6-ville.syrjala@linux.intel.com Reviewed-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/intel_pm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 74fd6aa7afc7..97b68bbbc689 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6828,7 +6828,8 @@ void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) for_each_plane_id_on_crtc(crtc, plane_id) raw->plane[plane_id] = active->wm.plane[plane_id]; - if (++level > max_level) + level = G4X_WM_LEVEL_SR; + if (level > max_level) goto out; raw = &crtc_state->wm.g4x.raw[level]; @@ -6837,7 +6838,8 @@ void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) raw->plane[PLANE_SPRITE0] = 0; raw->fbc = active->sr.fbc; - if (++level > max_level) + level = G4X_WM_LEVEL_HPLL; + if (level > max_level) goto out; raw = &crtc_state->wm.g4x.raw[level]; @@ -6846,6 +6848,7 @@ void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) raw->plane[PLANE_SPRITE0] = 0; raw->fbc = active->hpll.fbc; + level++; out: for_each_plane_id_on_crtc(crtc, plane_id) g4x_raw_plane_wm_set(crtc_state, level, -- cgit v1.2.3 From bdc1a2d2a32cea5748f2b31bcf7eb865dd8a9fcf Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 23 Sep 2021 07:21:51 +0300 Subject: drm/i915/fbc: Rework cfb stride/size calculations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code to calculate the cfb stride/size is a bit of mess. The cfb size is getting calculated based purely on the plane stride and plane height. That doesn't account for extra alignment we want for the cfb stride. The gen9 override stride OTOH is just calculated based on the plane width, and it does try to make things more aligned but any extra alignment added there is not considered in the cfb size calculations. So not at all convinced this is working as intended. Additionally the compression limit handling is split between the cfb allocation code and g4x_dpfc_ctl_limit() (for the 16bpp case), which is just confusing. Let's streamline the whole thing: - Start with the plane stride, convert that into cfb stride (cfb is always 4 bytes per pixel). All the calculations will assume 1:1 compression limit since that will give us the max values, and we don't yet know how much stolen memory we will be able to allocate - Align the cfb stride to 512 bytes on modern platforms. This guarantees the 4 line segment will be 512 byte aligned regardles of the final compression limit we choose later. The 512 byte alignment for the segment is required by at least some of the platforms, and just doing it always seems like the easiest option - Figure out if we need to use the override stride or not. For X-tiled it's never needed since the plane stride is already 512 byte aligned, for Y-tiled it will be needed if the plane stride is not a multiple of 512 bytes, and for linear it's apparently always needed because the hardware miscalculates the cfb stride as PLANE_STRIDE*512 instead of the PLANE_STRIDE*64 that it use with linear. - The cfb size will be calculated based on the aligned cfb stride to guarantee we actually reserved enough stolen memory and the FBC hw won't end up scribbling over whatever else is allocated in stolen - The compression limit handling we just do fully in the cfb allocation code to make things less confusing v2: Write the min cfb segment stride calculation in a more explicit way to make it clear what is going on v3: Remeber to update fbc->limit when changing to 16bpp Reviewed-by: Uma Shankar #v2 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210923042151.19052-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 180 +++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_drv.h | 4 +- 2 files changed, 123 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index b1c1a23c36be..e3934424040b 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -62,19 +62,76 @@ static void intel_fbc_get_plane_source_size(const struct intel_fbc_state_cache * *height = cache->plane.src_h; } -static int intel_fbc_calculate_cfb_size(struct drm_i915_private *dev_priv, - const struct intel_fbc_state_cache *cache) +/* plane stride in pixels */ +static unsigned int intel_fbc_plane_stride(const struct intel_plane_state *plane_state) { - int lines; + const struct drm_framebuffer *fb = plane_state->hw.fb; + unsigned int stride; + + stride = plane_state->view.color_plane[0].stride; + if (!drm_rotation_90_or_270(plane_state->hw.rotation)) + stride /= fb->format->cpp[0]; + + return stride; +} + +/* plane stride based cfb stride in bytes, assuming 1:1 compression limit */ +static unsigned int _intel_fbc_cfb_stride(const struct intel_fbc_state_cache *cache) +{ + unsigned int cpp = 4; /* FBC always 4 bytes per pixel */ + + return cache->fb.stride * cpp; +} + +/* minimum acceptable cfb stride in bytes, assuming 1:1 compression limit */ +static unsigned int skl_fbc_min_cfb_stride(const struct intel_fbc_state_cache *cache) +{ + unsigned int limit = 4; /* 1:4 compression limit is the worst case */ + unsigned int cpp = 4; /* FBC always 4 bytes per pixel */ + unsigned int height = 4; /* FBC segment is 4 lines */ + unsigned int stride; + + /* minimum segment stride we can use */ + stride = cache->plane.src_w * cpp * height / limit; + + /* + * At least some of the platforms require each 4 line segment to + * be 512 byte aligned. Just do it always for simplicity. + */ + stride = ALIGN(stride, 512); + + /* convert back to single line equivalent with 1:1 compression limit */ + return stride * limit / height; +} + +/* properly aligned cfb stride in bytes, assuming 1:1 compression limit */ +static unsigned int intel_fbc_cfb_stride(struct drm_i915_private *i915, + const struct intel_fbc_state_cache *cache) +{ + unsigned int stride = _intel_fbc_cfb_stride(cache); + + /* + * At least some of the platforms require each 4 line segment to + * be 512 byte aligned. Aligning each line to 512 bytes guarantees + * that regardless of the compression limit we choose later. + */ + if (DISPLAY_VER(i915) == 9) + return max(ALIGN(stride, 512), skl_fbc_min_cfb_stride(cache)); + else + return stride; +} + +static unsigned int intel_fbc_cfb_size(struct drm_i915_private *dev_priv, + const struct intel_fbc_state_cache *cache) +{ + int lines = cache->plane.src_h; - intel_fbc_get_plane_source_size(cache, NULL, &lines); if (DISPLAY_VER(dev_priv) == 7) lines = min(lines, 2048); else if (DISPLAY_VER(dev_priv) >= 8) lines = min(lines, 2560); - /* Hardware needs the full buffer stride, not just the active area. */ - return lines * cache->fb.stride; + return lines * intel_fbc_cfb_stride(dev_priv, cache); } static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv) @@ -150,15 +207,9 @@ static bool i8xx_fbc_is_active(struct drm_i915_private *dev_priv) static u32 g4x_dpfc_ctl_limit(struct drm_i915_private *i915) { - const struct intel_fbc_reg_params *params = &i915->fbc.params; - int limit = i915->fbc.limit; - - if (params->fb.format->cpp[0] == 2) - limit <<= 1; - - switch (limit) { + switch (i915->fbc.limit) { default: - MISSING_CASE(limit); + MISSING_CASE(i915->fbc.limit); fallthrough; case 1: return DPFC_CTL_LIMIT_1X; @@ -301,7 +352,8 @@ static bool ilk_fbc_is_active(struct drm_i915_private *dev_priv) static void gen7_fbc_activate(struct drm_i915_private *dev_priv) { - struct intel_fbc_reg_params *params = &dev_priv->fbc.params; + struct intel_fbc *fbc = &dev_priv->fbc; + const struct intel_fbc_reg_params *params = &fbc->params; u32 dpfc_ctl; /* Display WA #0529: skl, kbl, bxt. */ @@ -310,7 +362,7 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv) if (params->override_cfb_stride) val |= CHICKEN_FBC_STRIDE_OVERRIDE | - CHICKEN_FBC_STRIDE(params->override_cfb_stride); + CHICKEN_FBC_STRIDE(params->override_cfb_stride / fbc->limit); intel_de_rmw(dev_priv, CHICKEN_MISC_4, CHICKEN_FBC_STRIDE_OVERRIDE | @@ -443,7 +495,12 @@ static u64 intel_fbc_stolen_end(struct drm_i915_private *dev_priv) return min(end, intel_fbc_cfb_base_max(dev_priv)); } -static int intel_fbc_max_limit(struct drm_i915_private *dev_priv, int fb_cpp) +static int intel_fbc_min_limit(int fb_cpp) +{ + return fb_cpp == 2 ? 2 : 1; +} + +static int intel_fbc_max_limit(struct drm_i915_private *dev_priv) { /* * FIXME: FBC1 can have arbitrary cfb stride, @@ -457,16 +514,17 @@ static int intel_fbc_max_limit(struct drm_i915_private *dev_priv, int fb_cpp) return 1; /* FBC2 can only do 1:1, 1:2, 1:4 */ - return fb_cpp == 2 ? 2 : 4; + return 4; } static int find_compression_limit(struct drm_i915_private *dev_priv, - unsigned int size, - unsigned int fb_cpp) + unsigned int size, int min_limit) { struct intel_fbc *fbc = &dev_priv->fbc; u64 end = intel_fbc_stolen_end(dev_priv); - int ret, limit = 1; + int ret, limit = min_limit; + + size /= limit; /* Try to over-allocate to reduce reallocations and fragmentation. */ ret = i915_gem_stolen_insert_node_in_range(dev_priv, &fbc->compressed_fb, @@ -474,7 +532,7 @@ static int find_compression_limit(struct drm_i915_private *dev_priv, if (ret == 0) return limit; - for (; limit <= intel_fbc_max_limit(dev_priv, fb_cpp); limit <<= 1) { + for (; limit <= intel_fbc_max_limit(dev_priv); limit <<= 1) { ret = i915_gem_stolen_insert_node_in_range(dev_priv, &fbc->compressed_fb, size >>= 1, 4096, 0, end); if (ret == 0) @@ -485,7 +543,7 @@ static int find_compression_limit(struct drm_i915_private *dev_priv, } static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv, - unsigned int size, unsigned int fb_cpp) + unsigned int size, int min_limit) { struct intel_fbc *fbc = &dev_priv->fbc; int ret; @@ -502,13 +560,12 @@ static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv, goto err; } - ret = find_compression_limit(dev_priv, size, fb_cpp); + ret = find_compression_limit(dev_priv, size, min_limit); if (!ret) goto err_llb; - else if (ret > 1) { + else if (ret > min_limit) drm_info_once(&dev_priv->drm, "Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n"); - } fbc->limit = ret; @@ -719,11 +776,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, cache->fb.format = fb->format; cache->fb.modifier = fb->modifier; - - /* FIXME is this correct? */ - cache->fb.stride = plane_state->view.color_plane[0].stride; - if (drm_rotation_90_or_270(plane_state->hw.rotation)) - cache->fb.stride *= fb->format->cpp[0]; + cache->fb.stride = intel_fbc_plane_stride(plane_state); /* FBC1 compression interval: arbitrary choice of 1 second */ cache->interval = drm_mode_vrefresh(&crtc_state->hw.adjusted_mode); @@ -746,27 +799,29 @@ static bool intel_fbc_cfb_size_changed(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; - return intel_fbc_calculate_cfb_size(dev_priv, &fbc->state_cache) > + return intel_fbc_cfb_size(dev_priv, &fbc->state_cache) > fbc->compressed_fb.size * fbc->limit; } -static u16 intel_fbc_override_cfb_stride(struct drm_i915_private *dev_priv) +static u16 intel_fbc_override_cfb_stride(struct drm_i915_private *dev_priv, + const struct intel_fbc_state_cache *cache) { - struct intel_fbc *fbc = &dev_priv->fbc; - struct intel_fbc_state_cache *cache = &fbc->state_cache; - - if ((DISPLAY_VER(dev_priv) == 9) && - cache->fb.modifier != I915_FORMAT_MOD_X_TILED) - return DIV_ROUND_UP(cache->plane.src_w, 32 * fbc->limit) * 8; - else - return 0; -} + unsigned int stride = _intel_fbc_cfb_stride(cache); + unsigned int stride_aligned = intel_fbc_cfb_stride(dev_priv, cache); -static bool intel_fbc_override_cfb_stride_changed(struct drm_i915_private *dev_priv) -{ - struct intel_fbc *fbc = &dev_priv->fbc; + /* + * Override stride in 64 byte units per 4 line segment. + * + * Gen9 hw miscalculates cfb stride for linear as + * PLANE_STRIDE*512 instead of PLANE_STRIDE*64, so + * we always need to use the override there. + */ + if (stride != stride_aligned || + (DISPLAY_VER(dev_priv) == 9 && + cache->fb.modifier == DRM_FORMAT_MOD_LINEAR)) + return stride_aligned * 4 / 64; - return fbc->params.override_cfb_stride != intel_fbc_override_cfb_stride(dev_priv); + return 0; } static bool intel_fbc_can_enable(struct drm_i915_private *dev_priv) @@ -861,7 +916,8 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) return false; } - if (!stride_is_valid(dev_priv, cache->fb.modifier, cache->fb.stride)) { + if (!stride_is_valid(dev_priv, cache->fb.modifier, + cache->fb.stride * cache->fb.format->cpp[0])) { fbc->no_fbc_reason = "framebuffer stride not supported"; return false; } @@ -949,9 +1005,9 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc, params->fb.modifier = cache->fb.modifier; params->fb.stride = cache->fb.stride; - params->cfb_size = intel_fbc_calculate_cfb_size(dev_priv, cache); - - params->override_cfb_stride = cache->override_cfb_stride; + params->cfb_stride = intel_fbc_cfb_stride(dev_priv, cache); + params->cfb_size = intel_fbc_cfb_size(dev_priv, cache); + params->override_cfb_stride = intel_fbc_override_cfb_stride(dev_priv, cache); params->plane_visible = cache->plane.visible; } @@ -982,10 +1038,13 @@ static bool intel_fbc_can_flip_nuke(const struct intel_crtc_state *crtc_state) if (params->fb.stride != cache->fb.stride) return false; - if (params->cfb_size != intel_fbc_calculate_cfb_size(dev_priv, cache)) + if (params->cfb_stride != intel_fbc_cfb_stride(dev_priv, cache)) return false; - if (params->override_cfb_stride != cache->override_cfb_stride) + if (params->cfb_size != intel_fbc_cfb_size(dev_priv, cache)) + return false; + + if (params->override_cfb_stride != intel_fbc_override_cfb_stride(dev_priv, cache)) return false; return true; @@ -1250,16 +1309,22 @@ static void intel_fbc_enable(struct intel_atomic_state *state, intel_atomic_get_new_plane_state(state, plane); struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_state_cache *cache = &fbc->state_cache; + int min_limit; if (!plane->has_fbc || !plane_state) return; + min_limit = intel_fbc_min_limit(plane_state->hw.fb ? + plane_state->hw.fb->format->cpp[0] : 0); + mutex_lock(&fbc->lock); if (fbc->crtc) { - if (fbc->crtc != crtc || - (!intel_fbc_cfb_size_changed(dev_priv) && - !intel_fbc_override_cfb_stride_changed(dev_priv))) + if (fbc->crtc != crtc) + goto out; + + if (fbc->limit >= min_limit && + !intel_fbc_cfb_size_changed(dev_priv)) goto out; __intel_fbc_disable(dev_priv); @@ -1274,15 +1339,12 @@ static void intel_fbc_enable(struct intel_atomic_state *state, goto out; if (intel_fbc_alloc_cfb(dev_priv, - intel_fbc_calculate_cfb_size(dev_priv, cache), - plane_state->hw.fb->format->cpp[0])) { + intel_fbc_cfb_size(dev_priv, cache), min_limit)) { cache->plane.visible = false; fbc->no_fbc_reason = "not enough stolen memory"; goto out; } - cache->override_cfb_stride = intel_fbc_override_cfb_stride(dev_priv); - drm_dbg_kms(&dev_priv->drm, "Enabling FBC on pipe %c\n", pipe_name(crtc->pipe)); fbc->no_fbc_reason = "FBC enabled but not active yet\n"; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b9fd54f24f95..004c12a22295 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -453,7 +453,6 @@ struct intel_fbc { } fb; unsigned int fence_y_offset; - u16 override_cfb_stride; u16 interval; s8 fence_id; bool psr2_active; @@ -478,7 +477,8 @@ struct intel_fbc { u64 modifier; } fb; - int cfb_size; + unsigned int cfb_stride; + unsigned int cfb_size; unsigned int fence_y_offset; u16 override_cfb_stride; u16 interval; -- cgit v1.2.3 From 2f051f6774bb8c6807b2287e6ca482089bd92364 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 21 Sep 2021 18:25:15 +0300 Subject: drm/i915/fbc: Align FBC segments to 512B on glk+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply the same 512 byte FBC segment alignment to glk+ as we use on skl+. The only real difference is that we now have a dedicated register for the FBC override stride. Not 100% sure which platforms really need the 512B alignment, but it's easiest to just do it on everything. Also the hardware no longer seems to misclaculate the CFB stride for linear, so we can omit the use of the override stride for linear unless the stride is misaligned. Reviewed-by: Juha-Pekka Heikkila Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210921152517.803-3-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 14 +++++++++++--- drivers/gpu/drm/i915/i915_reg.h | 4 ++++ 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index e3934424040b..eeb97305e767 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -115,7 +115,7 @@ static unsigned int intel_fbc_cfb_stride(struct drm_i915_private *i915, * be 512 byte aligned. Aligning each line to 512 bytes guarantees * that regardless of the compression limit we choose later. */ - if (DISPLAY_VER(i915) == 9) + if (DISPLAY_VER(i915) >= 9) return max(ALIGN(stride, 512), skl_fbc_min_cfb_stride(cache)); else return stride; @@ -356,10 +356,18 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv) const struct intel_fbc_reg_params *params = &fbc->params; u32 dpfc_ctl; - /* Display WA #0529: skl, kbl, bxt. */ - if (DISPLAY_VER(dev_priv) == 9) { + if (DISPLAY_VER(dev_priv) >= 10) { + u32 val = 0; + + if (params->override_cfb_stride) + val |= FBC_STRIDE_OVERRIDE | + FBC_STRIDE(params->override_cfb_stride / fbc->limit); + + intel_de_write(dev_priv, GLK_FBC_STRIDE, val); + } else if (DISPLAY_VER(dev_priv) == 9) { u32 val = 0; + /* Display WA #0529: skl, kbl, bxt. */ if (params->override_cfb_stride) val |= CHICKEN_FBC_STRIDE_OVERRIDE | CHICKEN_FBC_STRIDE(params->override_cfb_stride / fbc->limit); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 61d29068925c..24017d38c6f6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3360,6 +3360,10 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define ILK_DPFC_DISABLE_DUMMY0 (1 << 8) #define ILK_DPFC_CHICKEN_COMP_DUMMY_PIXEL (1 << 14) #define ILK_DPFC_NUKE_ON_ANY_MODIFICATION (1 << 23) +#define GLK_FBC_STRIDE _MMIO(0x43228) +#define FBC_STRIDE_OVERRIDE REG_BIT(15) +#define FBC_STRIDE_MASK REG_GENMASK(14, 0) +#define FBC_STRIDE(x) REG_FIELD_PREP(FBC_STRIDE_MASK, (x)) #define ILK_FBC_RT_BASE _MMIO(0x2128) #define ILK_FBC_RT_VALID (1 << 0) #define SNB_FBC_FRONT_BUFFER (1 << 1) -- cgit v1.2.3 From 5f524aea39d9e2a74c063f340a77516e454badce Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 21 Sep 2021 21:12:45 +0300 Subject: drm/i915/fbc: Implement Wa_16011863758 for icl+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's some kind of weird corner cases in FBC which requires FBC segments to be separated by at least one extra cacheline. Make sure that is present. v2: Respin to fit in with skl_fbc_min_cfb_stride() v3: Make it build Reviewed-by: Juha-Pekka Heikkila #v1 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210921181245.15091-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index eeb97305e767..37ebed8d228d 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -84,7 +84,8 @@ static unsigned int _intel_fbc_cfb_stride(const struct intel_fbc_state_cache *ca } /* minimum acceptable cfb stride in bytes, assuming 1:1 compression limit */ -static unsigned int skl_fbc_min_cfb_stride(const struct intel_fbc_state_cache *cache) +static unsigned int skl_fbc_min_cfb_stride(struct drm_i915_private *i915, + const struct intel_fbc_state_cache *cache) { unsigned int limit = 4; /* 1:4 compression limit is the worst case */ unsigned int cpp = 4; /* FBC always 4 bytes per pixel */ @@ -94,6 +95,13 @@ static unsigned int skl_fbc_min_cfb_stride(const struct intel_fbc_state_cache *c /* minimum segment stride we can use */ stride = cache->plane.src_w * cpp * height / limit; + /* + * Wa_16011863758: icl+ + * Avoid some hardware segment address miscalculation. + */ + if (DISPLAY_VER(i915) >= 11) + stride += 64; + /* * At least some of the platforms require each 4 line segment to * be 512 byte aligned. Just do it always for simplicity. @@ -116,7 +124,7 @@ static unsigned int intel_fbc_cfb_stride(struct drm_i915_private *i915, * that regardless of the compression limit we choose later. */ if (DISPLAY_VER(i915) >= 9) - return max(ALIGN(stride, 512), skl_fbc_min_cfb_stride(cache)); + return max(ALIGN(stride, 512), skl_fbc_min_cfb_stride(i915, cache)); else return stride; } -- cgit v1.2.3 From 09bbdd8730dce85db1d945961dbf0ea4066eb6d6 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 21 Sep 2021 18:25:17 +0300 Subject: drm/i915/fbc: Allow higher compression limits on FBC1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On FBC1 we can specify an arbitrary cfb stride. The hw will simply throw away any compressed line that would exceed the specified limit and keep using the uncompressed data instead. Thus we can allow arbitrary compression limits. The one thing we have to keep in mind though is that the cfb stride is specified in units of 32B (gen2) or 64B (gen3+). Fortunately X-tile is already 128B (gen2) or 512B (gen3+) wide so as long as we limit outselves to the same 4x compression limit that FBC2 has we are guaranteed to have a sufficiently aligned cfb stride. Reviewed-by: Juha-Pekka Heikkila Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210921152517.803-5-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_fbc.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 37ebed8d228d..46f62fdf9eee 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -164,15 +164,13 @@ static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv) static void i8xx_fbc_activate(struct drm_i915_private *dev_priv) { - struct intel_fbc_reg_params *params = &dev_priv->fbc.params; + struct intel_fbc *fbc = &dev_priv->fbc; + const struct intel_fbc_reg_params *params = &fbc->params; int cfb_pitch; int i; u32 fbc_ctl; - /* Note: fbc.limit == 1 for i8xx */ - cfb_pitch = params->cfb_size / FBC_LL_SIZE; - if (params->fb.stride < cfb_pitch) - cfb_pitch = params->fb.stride; + cfb_pitch = params->cfb_stride / fbc->limit; /* FBC_CTL wants 32B or 64B units */ if (DISPLAY_VER(dev_priv) == 2) @@ -518,18 +516,14 @@ static int intel_fbc_min_limit(int fb_cpp) static int intel_fbc_max_limit(struct drm_i915_private *dev_priv) { - /* - * FIXME: FBC1 can have arbitrary cfb stride, - * so we could support different compression ratios. - */ - if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) - return 1; - /* WaFbcOnly1to1Ratio:ctg */ if (IS_G4X(dev_priv)) return 1; - /* FBC2 can only do 1:1, 1:2, 1:4 */ + /* + * FBC2 can only do 1:1, 1:2, 1:4, we limit + * FBC1 to the same out of convenience. + */ return 4; } -- cgit v1.2.3 From c6b40ee330fe09b332715bb7ec1467e4fcbe2e65 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Mon, 6 Sep 2021 12:12:59 +0800 Subject: drm/i915/audio: Use BIOS provided value for RKL HDA link Commit 989634fb49ad ("drm/i915/audio: set HDA link parameters in driver") makes HDMI audio on Lenovo P350 disappear. So in addition to TGL, extend the logic to RKL to use BIOS provided value to fix the regression. Fixes: 989634fb49ad ("drm/i915/audio: set HDA link parameters in driver") Reviewed-by: Kai Vehmanen Signed-off-by: Kai-Heng Feng Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210906041300.508458-1-kai.heng.feng@canonical.com --- drivers/gpu/drm/i915/display/intel_audio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 532237588511..4e0f96bf6158 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -1308,8 +1308,9 @@ static void i915_audio_component_init(struct drm_i915_private *dev_priv) else aud_freq = aud_freq_init; - /* use BIOS provided value for TGL unless it is a known bad value */ - if (IS_TIGERLAKE(dev_priv) && aud_freq_init != AUD_FREQ_TGL_BROKEN) + /* use BIOS provided value for TGL and RKL unless it is a known bad value */ + if ((IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv)) && + aud_freq_init != AUD_FREQ_TGL_BROKEN) aud_freq = aud_freq_init; drm_dbg_kms(&dev_priv->drm, "use AUD_FREQ_CNTRL of 0x%x (init value 0x%x)\n", -- cgit v1.2.3 From 2a764b7c708a796e6b45c39f12b962371278ca05 Mon Sep 17 00:00:00 2001 From: Vandita Kulkarni Date: Wed, 15 Sep 2021 11:13:38 +0530 Subject: drm/i915/display: Fix the dsc check while selecting min_cdclk The right parameter that selects second dsc engine is dsc_split. Hence use dsc_split instead of slice_count while selecting the cdclk in order to accommodate 1ppc limitaion of vdsc. Fixes: fe01883fdcef ("drm/i915: Get proper min cdclk if vDSC enabled") Suggested-by: Jani Nikula Signed-off-by: Vandita Kulkarni Reviewed-by: Jani Nikula Signed-off-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20210915054338.29869-1-vandita.kulkarni@intel.com --- drivers/gpu/drm/i915/display/intel_cdclk.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 9aec17b33819..3a1cdb3937aa 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2140,13 +2140,11 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk); /* - * VDSC engine can process only 1 pixel per Cd clock. - * In case VDSC is used and max slice count == 1, - * max supported pixel clock should be 100% of CD clock. - * Then do min_cdclk and pixel clock comparison to get cdclk. + * When we decide to use only one VDSC engine, since + * each VDSC operates with 1 ppc throughput, pixel clock + * cannot be higher than the VDSC clock (cdclk) */ - if (crtc_state->dsc.compression_enable && - crtc_state->dsc.slice_count == 1) + if (crtc_state->dsc.compression_enable && !crtc_state->dsc.dsc_split) min_cdclk = max(min_cdclk, (int)crtc_state->pixel_rate); /* -- cgit v1.2.3 From 5716c8c6f4b6a985acaf83a19d89131c113f7aeb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:45 +0300 Subject: drm/i915/uncore: split the fw get function into separate vfunc constify it while here. drop the put function since it was never overloaded and always has done the same thing, no point in indirecting it for show. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/41c3e1896162fc08e22e40b00642791365a8c00e.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_uncore.c | 70 +++++++++++++++++++++---------------- drivers/gpu/drm/i915/intel_uncore.h | 7 ++-- 2 files changed, 43 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 6b38bc2811c1..2dac69d92c1b 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -36,6 +36,12 @@ #define __raw_posting_read(...) ((void)__raw_uncore_read32(__VA_ARGS__)) +static void +fw_domains_get(struct intel_uncore *uncore, enum forcewake_domains fw_domains) +{ + uncore->fw_get_funcs->force_wake_get(uncore, fw_domains); +} + void intel_uncore_mmio_debug_init_early(struct intel_uncore_mmio_debug *mmio_debug) { @@ -248,7 +254,7 @@ fw_domain_put(const struct intel_uncore_forcewake_domain *d) } static void -fw_domains_get(struct intel_uncore *uncore, enum forcewake_domains fw_domains) +fw_domains_get_normal(struct intel_uncore *uncore, enum forcewake_domains fw_domains) { struct intel_uncore_forcewake_domain *d; unsigned int tmp; @@ -396,7 +402,7 @@ intel_uncore_fw_release_timer(struct hrtimer *timer) GEM_BUG_ON(!domain->wake_count); if (--domain->wake_count == 0) - uncore->funcs.force_wake_put(uncore, domain->mask); + fw_domains_put(uncore, domain->mask); spin_unlock_irqrestore(&uncore->lock, irqflags); @@ -454,7 +460,7 @@ intel_uncore_forcewake_reset(struct intel_uncore *uncore) fw = uncore->fw_domains_active; if (fw) - uncore->funcs.force_wake_put(uncore, fw); + fw_domains_put(uncore, fw); fw_domains_reset(uncore, uncore->fw_domains); assert_forcewakes_inactive(uncore); @@ -562,7 +568,7 @@ static void forcewake_early_sanitize(struct intel_uncore *uncore, intel_uncore_forcewake_reset(uncore); if (restore_forcewake) { spin_lock_irq(&uncore->lock); - uncore->funcs.force_wake_get(uncore, restore_forcewake); + fw_domains_get(uncore, restore_forcewake); if (intel_uncore_has_fifo(uncore)) uncore->fifo_count = fifo_free_entries(uncore); @@ -623,7 +629,7 @@ static void __intel_uncore_forcewake_get(struct intel_uncore *uncore, } if (fw_domains) - uncore->funcs.force_wake_get(uncore, fw_domains); + fw_domains_get(uncore, fw_domains); } /** @@ -644,7 +650,7 @@ void intel_uncore_forcewake_get(struct intel_uncore *uncore, { unsigned long irqflags; - if (!uncore->funcs.force_wake_get) + if (!uncore->fw_get_funcs) return; assert_rpm_wakelock_held(uncore->rpm); @@ -711,7 +717,7 @@ void intel_uncore_forcewake_get__locked(struct intel_uncore *uncore, { lockdep_assert_held(&uncore->lock); - if (!uncore->funcs.force_wake_get) + if (!uncore->fw_get_funcs) return; __intel_uncore_forcewake_get(uncore, fw_domains); @@ -733,7 +739,7 @@ static void __intel_uncore_forcewake_put(struct intel_uncore *uncore, continue; } - uncore->funcs.force_wake_put(uncore, domain->mask); + fw_domains_put(uncore, domain->mask); } } @@ -750,7 +756,7 @@ void intel_uncore_forcewake_put(struct intel_uncore *uncore, { unsigned long irqflags; - if (!uncore->funcs.force_wake_put) + if (!uncore->fw_get_funcs) return; spin_lock_irqsave(&uncore->lock, irqflags); @@ -769,7 +775,7 @@ void intel_uncore_forcewake_flush(struct intel_uncore *uncore, struct intel_uncore_forcewake_domain *domain; unsigned int tmp; - if (!uncore->funcs.force_wake_put) + if (!uncore->fw_get_funcs) return; fw_domains &= uncore->fw_domains; @@ -793,7 +799,7 @@ void intel_uncore_forcewake_put__locked(struct intel_uncore *uncore, { lockdep_assert_held(&uncore->lock); - if (!uncore->funcs.force_wake_put) + if (!uncore->fw_get_funcs) return; __intel_uncore_forcewake_put(uncore, fw_domains); @@ -801,7 +807,7 @@ void intel_uncore_forcewake_put__locked(struct intel_uncore *uncore, void assert_forcewakes_inactive(struct intel_uncore *uncore) { - if (!uncore->funcs.force_wake_get) + if (!uncore->fw_get_funcs) return; drm_WARN(&uncore->i915->drm, uncore->fw_domains_active, @@ -818,7 +824,7 @@ void assert_forcewakes_active(struct intel_uncore *uncore, if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)) return; - if (!uncore->funcs.force_wake_get) + if (!uncore->fw_get_funcs) return; spin_lock_irq(&uncore->lock); @@ -1605,7 +1611,7 @@ static noinline void ___force_wake_auto(struct intel_uncore *uncore, for_each_fw_domain_masked(domain, fw_domains, uncore, tmp) fw_domain_arm_timer(domain); - uncore->funcs.force_wake_get(uncore, fw_domains); + fw_domains_get(uncore, fw_domains); } static inline void __force_wake_auto(struct intel_uncore *uncore, @@ -1866,6 +1872,18 @@ static void intel_uncore_fw_domains_fini(struct intel_uncore *uncore) fw_domain_fini(uncore, d->id); } +static const struct intel_uncore_fw_get uncore_get_fallback = { + .force_wake_get = fw_domains_get_with_fallback +}; + +static const struct intel_uncore_fw_get uncore_get_normal = { + .force_wake_get = fw_domains_get_normal, +}; + +static const struct intel_uncore_fw_get uncore_get_thread_status = { + .force_wake_get = fw_domains_get_with_thread_status +}; + static int intel_uncore_fw_domains_init(struct intel_uncore *uncore) { struct drm_i915_private *i915 = uncore->i915; @@ -1881,8 +1899,7 @@ static int intel_uncore_fw_domains_init(struct intel_uncore *uncore) intel_engine_mask_t emask = INTEL_INFO(i915)->platform_engine_mask; int i; - uncore->funcs.force_wake_get = fw_domains_get_with_fallback; - uncore->funcs.force_wake_put = fw_domains_put; + uncore->fw_get_funcs = &uncore_get_fallback; fw_domain_init(uncore, FW_DOMAIN_ID_RENDER, FORCEWAKE_RENDER_GEN9, FORCEWAKE_ACK_RENDER_GEN9); @@ -1907,8 +1924,7 @@ static int intel_uncore_fw_domains_init(struct intel_uncore *uncore) FORCEWAKE_ACK_MEDIA_VEBOX_GEN11(i)); } } else if (IS_GRAPHICS_VER(i915, 9, 10)) { - uncore->funcs.force_wake_get = fw_domains_get_with_fallback; - uncore->funcs.force_wake_put = fw_domains_put; + uncore->fw_get_funcs = &uncore_get_fallback; fw_domain_init(uncore, FW_DOMAIN_ID_RENDER, FORCEWAKE_RENDER_GEN9, FORCEWAKE_ACK_RENDER_GEN9); @@ -1918,16 +1934,13 @@ static int intel_uncore_fw_domains_init(struct intel_uncore *uncore) fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA, FORCEWAKE_MEDIA_GEN9, FORCEWAKE_ACK_MEDIA_GEN9); } else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) { - uncore->funcs.force_wake_get = fw_domains_get; - uncore->funcs.force_wake_put = fw_domains_put; + uncore->fw_get_funcs = &uncore_get_normal; fw_domain_init(uncore, FW_DOMAIN_ID_RENDER, FORCEWAKE_VLV, FORCEWAKE_ACK_VLV); fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA, FORCEWAKE_MEDIA_VLV, FORCEWAKE_ACK_MEDIA_VLV); } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { - uncore->funcs.force_wake_get = - fw_domains_get_with_thread_status; - uncore->funcs.force_wake_put = fw_domains_put; + uncore->fw_get_funcs = &uncore_get_thread_status; fw_domain_init(uncore, FW_DOMAIN_ID_RENDER, FORCEWAKE_MT, FORCEWAKE_ACK_HSW); } else if (IS_IVYBRIDGE(i915)) { @@ -1942,9 +1955,7 @@ static int intel_uncore_fw_domains_init(struct intel_uncore *uncore) * (correctly) interpreted by the test below as MT * forcewake being disabled. */ - uncore->funcs.force_wake_get = - fw_domains_get_with_thread_status; - uncore->funcs.force_wake_put = fw_domains_put; + uncore->fw_get_funcs = &uncore_get_thread_status; /* We need to init first for ECOBUS access and then * determine later if we want to reinit, in case of MT access is @@ -1975,9 +1986,7 @@ static int intel_uncore_fw_domains_init(struct intel_uncore *uncore) FORCEWAKE, FORCEWAKE_ACK); } } else if (GRAPHICS_VER(i915) == 6) { - uncore->funcs.force_wake_get = - fw_domains_get_with_thread_status; - uncore->funcs.force_wake_put = fw_domains_put; + uncore->fw_get_funcs = &uncore_get_thread_status; fw_domain_init(uncore, FW_DOMAIN_ID_RENDER, FORCEWAKE, FORCEWAKE_ACK); } @@ -2186,8 +2195,7 @@ int intel_uncore_init_mmio(struct intel_uncore *uncore) } /* make sure fw funcs are set if and only if we have fw*/ - GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->funcs.force_wake_get); - GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->funcs.force_wake_put); + GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->fw_get_funcs); GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->funcs.read_fw_domains); GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->funcs.write_fw_domains); diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 3c0b0a8b5250..1a7448f5f16f 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -84,12 +84,12 @@ enum forcewake_domains { FORCEWAKE_ALL = BIT(FW_DOMAIN_ID_COUNT) - 1, }; -struct intel_uncore_funcs { +struct intel_uncore_fw_get { void (*force_wake_get)(struct intel_uncore *uncore, enum forcewake_domains domains); - void (*force_wake_put)(struct intel_uncore *uncore, - enum forcewake_domains domains); +}; +struct intel_uncore_funcs { enum forcewake_domains (*read_fw_domains)(struct intel_uncore *uncore, i915_reg_t r); enum forcewake_domains (*write_fw_domains)(struct intel_uncore *uncore, @@ -137,6 +137,7 @@ struct intel_uncore { unsigned int fw_domains_table_entries; struct notifier_block pmic_bus_access_nb; + const struct intel_uncore_fw_get *fw_get_funcs; struct intel_uncore_funcs funcs; unsigned int fifo_count; -- cgit v1.2.3 From 758b2fc26640c3641fb145cf61bc79a255dae5ea Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:46 +0300 Subject: drm/i915/pm: drop get_fifo_size vfunc. The i845_update_wm code was always calling the i845 variant, and the i9xx_update_wm had only a choice between i830 and i9xx paths, hardly worth the vfunc overhead. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/07523b1e46cd10adb2991ed4d2619b542a48c1ce.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/intel_pm.c | 20 +++++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 004c12a22295..92850f591c82 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -330,8 +330,6 @@ struct drm_i915_display_funcs { const struct intel_cdclk_config *cdclk_config, enum pipe pipe); int (*bw_calc_min_cdclk)(struct intel_atomic_state *state); - int (*get_fifo_size)(struct drm_i915_private *dev_priv, - enum i9xx_plane_id i9xx_plane); int (*compute_pipe_wm)(struct intel_atomic_state *state, struct intel_crtc *crtc); int (*compute_intermediate_wm)(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 97b68bbbc689..0e0309733c79 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2342,7 +2342,10 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc) else wm_info = &i830_a_wm_info; - fifo_size = dev_priv->display.get_fifo_size(dev_priv, PLANE_A); + if (DISPLAY_VER(dev_priv) == 2) + fifo_size = i830_get_fifo_size(dev_priv, PLANE_A); + else + fifo_size = i9xx_get_fifo_size(dev_priv, PLANE_A); crtc = intel_get_crtc_for_plane(dev_priv, PLANE_A); if (intel_crtc_active(crtc)) { const struct drm_display_mode *pipe_mode = @@ -2369,7 +2372,10 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc) if (DISPLAY_VER(dev_priv) == 2) wm_info = &i830_bc_wm_info; - fifo_size = dev_priv->display.get_fifo_size(dev_priv, PLANE_B); + if (DISPLAY_VER(dev_priv) == 2) + fifo_size = i830_get_fifo_size(dev_priv, PLANE_B); + else + fifo_size = i9xx_get_fifo_size(dev_priv, PLANE_B); crtc = intel_get_crtc_for_plane(dev_priv, PLANE_B); if (intel_crtc_active(crtc)) { const struct drm_display_mode *pipe_mode = @@ -2485,7 +2491,7 @@ static void i845_update_wm(struct intel_crtc *unused_crtc) pipe_mode = &crtc->config->hw.pipe_mode; planea_wm = intel_calculate_wm(pipe_mode->crtc_clock, &i845_wm_info, - dev_priv->display.get_fifo_size(dev_priv, PLANE_A), + i845_get_fifo_size(dev_priv, PLANE_A), 4, pessimal_latency_ns); fwater_lo = intel_uncore_read(&dev_priv->uncore, FW_BLC) & ~0xfff; fwater_lo |= (3<<8) | planea_wm; @@ -8052,15 +8058,11 @@ void intel_init_pm(struct drm_i915_private *dev_priv) dev_priv->display.update_wm = i965_update_wm; } else if (DISPLAY_VER(dev_priv) == 3) { dev_priv->display.update_wm = i9xx_update_wm; - dev_priv->display.get_fifo_size = i9xx_get_fifo_size; } else if (DISPLAY_VER(dev_priv) == 2) { - if (INTEL_NUM_PIPES(dev_priv) == 1) { + if (INTEL_NUM_PIPES(dev_priv) == 1) dev_priv->display.update_wm = i845_update_wm; - dev_priv->display.get_fifo_size = i845_get_fifo_size; - } else { + else dev_priv->display.update_wm = i9xx_update_wm; - dev_priv->display.get_fifo_size = i830_get_fifo_size; - } } else { drm_err(&dev_priv->drm, "unexpected fall-through in %s\n", __func__); -- cgit v1.2.3 From ef9c66a0aea5c2f42a7cee721e61949c745c927b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:47 +0300 Subject: drm/i915: make update_wm take a dev_priv. The crtc was never being used here. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/70438bface47fa683cda8a9e95d0556fca448172.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 10 +++++----- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_pm.c | 20 +++++++------------- drivers/gpu/drm/i915/intel_pm.h | 2 +- 4 files changed, 14 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index f27c294beb92..566a7d2feb1a 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2383,7 +2383,7 @@ static void intel_post_plane_update(struct intel_atomic_state *state, intel_frontbuffer_flip(dev_priv, new_crtc_state->fb_bits); if (new_crtc_state->update_wm_post && new_crtc_state->hw.active) - intel_update_watermarks(crtc); + intel_update_watermarks(dev_priv); if (hsw_post_update_enable_ips(old_crtc_state, new_crtc_state)) hsw_enable_ips(new_crtc_state); @@ -2540,7 +2540,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, if (dev_priv->display.initial_watermarks) dev_priv->display.initial_watermarks(state, crtc); else if (new_crtc_state->update_wm_pre) - intel_update_watermarks(crtc); + intel_update_watermarks(dev_priv); } /* @@ -3587,7 +3587,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, if (dev_priv->display.initial_watermarks) dev_priv->display.initial_watermarks(state, crtc); else - intel_update_watermarks(crtc); + intel_update_watermarks(dev_priv); intel_enable_transcoder(new_crtc_state); intel_crtc_vblank_on(new_crtc_state); @@ -3654,7 +3654,7 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); if (!dev_priv->display.initial_watermarks) - intel_update_watermarks(crtc); + intel_update_watermarks(dev_priv); /* clock the pipe down to 640x480@60 to potentially save power */ if (IS_I830(dev_priv)) @@ -3730,7 +3730,7 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc, encoder->base.crtc = NULL; intel_fbc_disable(crtc); - intel_update_watermarks(crtc); + intel_update_watermarks(dev_priv); intel_disable_shared_dpll(crtc_state); intel_display_power_put_all_in_set(dev_priv, &crtc->enabled_power_domains); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 92850f591c82..97bfeadaab94 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -341,7 +341,7 @@ struct drm_i915_display_funcs { void (*optimize_watermarks)(struct intel_atomic_state *state, struct intel_crtc *crtc); int (*compute_global_watermarks)(struct intel_atomic_state *state); - void (*update_wm)(struct intel_crtc *crtc); + void (*update_wm)(struct drm_i915_private *dev_priv); int (*modeset_calc_cdclk)(struct intel_cdclk_state *state); u8 (*calc_voltage_level)(int cdclk); /* Returns the active state of the crtc, and if the crtc is active, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0e0309733c79..226f456cde3a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -881,9 +881,8 @@ static struct intel_crtc *single_enabled_crtc(struct drm_i915_private *dev_priv) return enabled; } -static void pnv_update_wm(struct intel_crtc *unused_crtc) +static void pnv_update_wm(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev); struct intel_crtc *crtc; const struct cxsr_latency *latency; u32 reg; @@ -2248,9 +2247,8 @@ static void vlv_optimize_watermarks(struct intel_atomic_state *state, mutex_unlock(&dev_priv->wm.wm_mutex); } -static void i965_update_wm(struct intel_crtc *unused_crtc) +static void i965_update_wm(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev); struct intel_crtc *crtc; int srwm = 1; int cursor_sr = 16; @@ -2324,9 +2322,8 @@ static void i965_update_wm(struct intel_crtc *unused_crtc) #undef FW_WM -static void i9xx_update_wm(struct intel_crtc *unused_crtc) +static void i9xx_update_wm(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev); const struct intel_watermark_params *wm_info; u32 fwater_lo; u32 fwater_hi; @@ -2476,9 +2473,8 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc) intel_set_memory_cxsr(dev_priv, true); } -static void i845_update_wm(struct intel_crtc *unused_crtc) +static void i845_update_wm(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev); struct intel_crtc *crtc; const struct drm_display_mode *pipe_mode; u32 fwater_lo; @@ -7136,7 +7132,7 @@ void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv) /** * intel_update_watermarks - update FIFO watermark values based on current modes - * @crtc: the #intel_crtc on which to compute the WM + * @dev_priv: i915 device * * Calculate watermark values for the various WM regs based on current mode * and plane configuration. @@ -7167,12 +7163,10 @@ void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv) * We don't use the sprite, so we can ignore that. And on Crestline we have * to set the non-SR watermarks to 8. */ -void intel_update_watermarks(struct intel_crtc *crtc) +void intel_update_watermarks(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - if (dev_priv->display.update_wm) - dev_priv->display.update_wm(crtc); + dev_priv->display.update_wm(dev_priv); } void intel_enable_ipc(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h index 941b3ae555c8..99bce0b4f5fb 100644 --- a/drivers/gpu/drm/i915/intel_pm.h +++ b/drivers/gpu/drm/i915/intel_pm.h @@ -29,7 +29,7 @@ struct skl_wm_level; void intel_init_clock_gating(struct drm_i915_private *dev_priv); void intel_suspend_hw(struct drm_i915_private *dev_priv); int ilk_wm_max_level(const struct drm_i915_private *dev_priv); -void intel_update_watermarks(struct intel_crtc *crtc); +void intel_update_watermarks(struct drm_i915_private *dev_priv); void intel_init_pm(struct drm_i915_private *dev_priv); void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv); void intel_pm_setup(struct drm_i915_private *dev_priv); -- cgit v1.2.3 From 02a1a6351e439638cb04852eb57c129b60ce36b5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:48 +0300 Subject: drm/i915/wm: provide wrappers around watermark vfuncs calls (v3) This moves one wrapper from the pm->display side, and creates wrappers for all the others, this should simplify things later. One thing to note is that the code checks the existence of some of these ptrs, so the wrappers are a bit complicated by that. Suggested by Jani. v2: fixup warnings in wrong place error. v3 by Jani: fix intel_compute_global_watermarks() return value check Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/ee2760c45896568c9dd9114a575509619bd44ef2.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 185 ++++++++++++++++++--------- drivers/gpu/drm/i915/intel_pm.c | 39 ------ drivers/gpu/drm/i915/intel_pm.h | 1 - 3 files changed, 123 insertions(+), 102 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 566a7d2feb1a..9af433a7cbf1 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -126,6 +126,101 @@ static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state); static void intel_modeset_setup_hw_state(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx); +/** + * intel_update_watermarks - update FIFO watermark values based on current modes + * @dev_priv: i915 device + * + * Calculate watermark values for the various WM regs based on current mode + * and plane configuration. + * + * There are several cases to deal with here: + * - normal (i.e. non-self-refresh) + * - self-refresh (SR) mode + * - lines are large relative to FIFO size (buffer can hold up to 2) + * - lines are small relative to FIFO size (buffer can hold more than 2 + * lines), so need to account for TLB latency + * + * The normal calculation is: + * watermark = dotclock * bytes per pixel * latency + * where latency is platform & configuration dependent (we assume pessimal + * values here). + * + * The SR calculation is: + * watermark = (trunc(latency/line time)+1) * surface width * + * bytes per pixel + * where + * line time = htotal / dotclock + * surface width = hdisplay for normal plane and 64 for cursor + * and latency is assumed to be high, as above. + * + * The final value programmed to the register should always be rounded up, + * and include an extra 2 entries to account for clock crossings. + * + * We don't use the sprite, so we can ignore that. And on Crestline we have + * to set the non-SR watermarks to 8. + */ +static void intel_update_watermarks(struct drm_i915_private *dev_priv) +{ + if (dev_priv->display.update_wm) + dev_priv->display.update_wm(dev_priv); +} + +static int intel_compute_pipe_wm(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + if (dev_priv->display.compute_pipe_wm) + return dev_priv->display.compute_pipe_wm(state, crtc); + return 0; +} + +static int intel_compute_intermediate_wm(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + if (!dev_priv->display.compute_intermediate_wm) + return 0; + if (drm_WARN_ON(&dev_priv->drm, + !dev_priv->display.compute_pipe_wm)) + return 0; + return dev_priv->display.compute_intermediate_wm(state, crtc); +} + +static bool intel_initial_watermarks(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + if (dev_priv->display.initial_watermarks) { + dev_priv->display.initial_watermarks(state, crtc); + return true; + } + return false; +} + +static void intel_atomic_update_watermarks(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + if (dev_priv->display.atomic_update_watermarks) + dev_priv->display.atomic_update_watermarks(state, crtc); +} + +static void intel_optimize_watermarks(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + if (dev_priv->display.optimize_watermarks) + dev_priv->display.optimize_watermarks(state, crtc); +} + +static int intel_compute_global_watermarks(struct intel_atomic_state *state) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + if (dev_priv->display.compute_global_watermarks) + return dev_priv->display.compute_global_watermarks(state); + return 0; +} + /* returns HPLL frequency in kHz */ int vlv_get_hpll_vco(struct drm_i915_private *dev_priv) { @@ -2537,10 +2632,9 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, * we'll continue to update watermarks the old way, if flags tell * us to. */ - if (dev_priv->display.initial_watermarks) - dev_priv->display.initial_watermarks(state, crtc); - else if (new_crtc_state->update_wm_pre) - intel_update_watermarks(dev_priv); + if (!intel_initial_watermarks(state, crtc)) + if (new_crtc_state->update_wm_pre) + intel_update_watermarks(dev_priv); } /* @@ -2912,8 +3006,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state, /* update DSPCNTR to configure gamma for pipe bottom color */ intel_disable_primary_plane(new_crtc_state); - if (dev_priv->display.initial_watermarks) - dev_priv->display.initial_watermarks(state, crtc); + intel_initial_watermarks(state, crtc); intel_enable_transcoder(new_crtc_state); if (new_crtc_state->has_pch_encoder) @@ -3123,8 +3216,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, if (DISPLAY_VER(dev_priv) >= 11) icl_set_pipe_chicken(new_crtc_state); - if (dev_priv->display.initial_watermarks) - dev_priv->display.initial_watermarks(state, crtc); + intel_initial_watermarks(state, crtc); if (DISPLAY_VER(dev_priv) >= 11) { const struct intel_dbuf_state *dbuf_state = @@ -3541,7 +3633,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, /* update DSPCNTR to configure gamma for pipe bottom color */ intel_disable_primary_plane(new_crtc_state); - dev_priv->display.initial_watermarks(state, crtc); + intel_initial_watermarks(state, crtc); intel_enable_transcoder(new_crtc_state); intel_crtc_vblank_on(new_crtc_state); @@ -3584,9 +3676,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, /* update DSPCNTR to configure gamma for pipe bottom color */ intel_disable_primary_plane(new_crtc_state); - if (dev_priv->display.initial_watermarks) - dev_priv->display.initial_watermarks(state, crtc); - else + if (!intel_initial_watermarks(state, crtc)) intel_update_watermarks(dev_priv); intel_enable_transcoder(new_crtc_state); @@ -6765,32 +6855,23 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state, return ret; } - if (dev_priv->display.compute_pipe_wm) { - ret = dev_priv->display.compute_pipe_wm(state, crtc); - if (ret) { - drm_dbg_kms(&dev_priv->drm, - "Target pipe watermarks are invalid\n"); - return ret; - } - + ret = intel_compute_pipe_wm(state, crtc); + if (ret) { + drm_dbg_kms(&dev_priv->drm, + "Target pipe watermarks are invalid\n"); + return ret; } - if (dev_priv->display.compute_intermediate_wm) { - if (drm_WARN_ON(&dev_priv->drm, - !dev_priv->display.compute_pipe_wm)) - return 0; - - /* - * Calculate 'intermediate' watermarks that satisfy both the - * old state and the new state. We can program these - * immediately. - */ - ret = dev_priv->display.compute_intermediate_wm(state, crtc); - if (ret) { - drm_dbg_kms(&dev_priv->drm, - "No valid intermediate pipe watermarks are possible\n"); - return ret; - } + /* + * Calculate 'intermediate' watermarks that satisfy both the + * old state and the new state. We can program these + * immediately. + */ + ret = intel_compute_intermediate_wm(state, crtc); + if (ret) { + drm_dbg_kms(&dev_priv->drm, + "No valid intermediate pipe watermarks are possible\n"); + return ret; } if (DISPLAY_VER(dev_priv) >= 9) { @@ -8883,23 +8964,6 @@ static int intel_modeset_checks(struct intel_atomic_state *state) return 0; } -/* - * Handle calculation of various watermark data at the end of the atomic check - * phase. The code here should be run after the per-crtc and per-plane 'check' - * handlers to ensure that all derived state has been updated. - */ -static int calc_watermark_data(struct intel_atomic_state *state) -{ - struct drm_device *dev = state->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - - /* Is there platform-specific watermark information to calculate? */ - if (dev_priv->display.compute_global_watermarks) - return dev_priv->display.compute_global_watermarks(state); - - return 0; -} - static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_state, struct intel_crtc_state *new_crtc_state) { @@ -9546,7 +9610,7 @@ static int intel_atomic_check(struct drm_device *dev, goto fail; intel_fbc_choose_crtc(dev_priv, state); - ret = calc_watermark_data(state); + ret = intel_compute_global_watermarks(state); if (ret) goto fail; @@ -9720,8 +9784,7 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state, intel_psr2_program_trans_man_trk_ctl(new_crtc_state); - if (dev_priv->display.atomic_update_watermarks) - dev_priv->display.atomic_update_watermarks(state, crtc); + intel_atomic_update_watermarks(state, crtc); } static void commit_pipe_post_planes(struct intel_atomic_state *state, @@ -9848,9 +9911,8 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state, /* FIXME unify this for all platforms */ if (!new_crtc_state->hw.active && - !HAS_GMCH(dev_priv) && - dev_priv->display.initial_watermarks) - dev_priv->display.initial_watermarks(state, crtc); + !HAS_GMCH(dev_priv)) + intel_initial_watermarks(state, crtc); } static void intel_commit_modeset_disables(struct intel_atomic_state *state) @@ -10273,8 +10335,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) if (DISPLAY_VER(dev_priv) == 2 && planes_enabling(old_crtc_state, new_crtc_state)) intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true); - if (dev_priv->display.optimize_watermarks) - dev_priv->display.optimize_watermarks(state, crtc); + intel_optimize_watermarks(state, crtc); } intel_dbuf_post_plane_update(state); @@ -11376,7 +11437,7 @@ retry: /* Write calculated watermark values back */ for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) { crtc_state->wm.need_postvbl_update = true; - dev_priv->display.optimize_watermarks(intel_state, crtc); + intel_optimize_watermarks(intel_state, crtc); to_intel_crtc_state(crtc->base.state)->wm = crtc_state->wm; } diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 226f456cde3a..11c9df62391d 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7130,45 +7130,6 @@ void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv) !(intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) & DISP_FBC_WM_DIS); } -/** - * intel_update_watermarks - update FIFO watermark values based on current modes - * @dev_priv: i915 device - * - * Calculate watermark values for the various WM regs based on current mode - * and plane configuration. - * - * There are several cases to deal with here: - * - normal (i.e. non-self-refresh) - * - self-refresh (SR) mode - * - lines are large relative to FIFO size (buffer can hold up to 2) - * - lines are small relative to FIFO size (buffer can hold more than 2 - * lines), so need to account for TLB latency - * - * The normal calculation is: - * watermark = dotclock * bytes per pixel * latency - * where latency is platform & configuration dependent (we assume pessimal - * values here). - * - * The SR calculation is: - * watermark = (trunc(latency/line time)+1) * surface width * - * bytes per pixel - * where - * line time = htotal / dotclock - * surface width = hdisplay for normal plane and 64 for cursor - * and latency is assumed to be high, as above. - * - * The final value programmed to the register should always be rounded up, - * and include an extra 2 entries to account for clock crossings. - * - * We don't use the sprite, so we can ignore that. And on Crestline we have - * to set the non-SR watermarks to 8. - */ -void intel_update_watermarks(struct drm_i915_private *dev_priv) -{ - if (dev_priv->display.update_wm) - dev_priv->display.update_wm(dev_priv); -} - void intel_enable_ipc(struct drm_i915_private *dev_priv) { u32 val; diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h index 99bce0b4f5fb..990cdcaf85ce 100644 --- a/drivers/gpu/drm/i915/intel_pm.h +++ b/drivers/gpu/drm/i915/intel_pm.h @@ -29,7 +29,6 @@ struct skl_wm_level; void intel_init_clock_gating(struct drm_i915_private *dev_priv); void intel_suspend_hw(struct drm_i915_private *dev_priv); int ilk_wm_max_level(const struct drm_i915_private *dev_priv); -void intel_update_watermarks(struct drm_i915_private *dev_priv); void intel_init_pm(struct drm_i915_private *dev_priv); void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv); void intel_pm_setup(struct drm_i915_private *dev_priv); -- cgit v1.2.3 From 44892ffafa5abfb90598ebad18656f9db61592bf Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:49 +0300 Subject: drm/i915: add wrappers around cdclk vtable funcs. This adds wrappers around all the vtable callers so they are in one place. Suggested by Jani. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/c3dd7aaad039e76acde9dda7211468907aa657c0.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_cdclk.c | 47 ++++++++++++++++++---- drivers/gpu/drm/i915/display/intel_cdclk.h | 4 +- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/i915/display/intel_display_power.c | 2 +- 4 files changed, 44 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 3a1cdb3937aa..ff01fe9be35c 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -59,6 +59,37 @@ * dividers can be programmed correctly. */ +void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv, + struct intel_cdclk_config *cdclk_config) +{ + dev_priv->display.get_cdclk(dev_priv, cdclk_config); +} + +int intel_cdclk_bw_calc_min_cdclk(struct intel_atomic_state *state) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + return dev_priv->display.bw_calc_min_cdclk(state); +} + +static void intel_cdclk_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe) +{ + dev_priv->display.set_cdclk(dev_priv, cdclk_config, pipe); +} + +static int intel_cdclk_modeset_calc_cdclk(struct drm_i915_private *dev_priv, + struct intel_cdclk_state *cdclk_config) +{ + return dev_priv->display.modeset_calc_cdclk(cdclk_config); +} + +static u8 intel_cdclk_calc_voltage_level(struct drm_i915_private *dev_priv, + int cdclk) +{ + return dev_priv->display.calc_voltage_level(cdclk); +} + static void fixed_133mhz_get_cdclk(struct drm_i915_private *dev_priv, struct intel_cdclk_config *cdclk_config) { @@ -1466,7 +1497,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv, * at least what the CDCLK frequency requires. */ cdclk_config->voltage_level = - dev_priv->display.calc_voltage_level(cdclk_config->cdclk); + intel_cdclk_calc_voltage_level(dev_priv, cdclk_config->cdclk); } static void bxt_de_pll_disable(struct drm_i915_private *dev_priv) @@ -1777,7 +1808,7 @@ static void bxt_cdclk_init_hw(struct drm_i915_private *dev_priv) cdclk_config.cdclk = bxt_calc_cdclk(dev_priv, 0); cdclk_config.vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk_config.cdclk); cdclk_config.voltage_level = - dev_priv->display.calc_voltage_level(cdclk_config.cdclk); + intel_cdclk_calc_voltage_level(dev_priv, cdclk_config.cdclk); bxt_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE); } @@ -1789,7 +1820,7 @@ static void bxt_cdclk_uninit_hw(struct drm_i915_private *dev_priv) cdclk_config.cdclk = cdclk_config.bypass; cdclk_config.vco = 0; cdclk_config.voltage_level = - dev_priv->display.calc_voltage_level(cdclk_config.cdclk); + intel_cdclk_calc_voltage_level(dev_priv, cdclk_config.cdclk); bxt_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE); } @@ -1956,7 +1987,7 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv, &dev_priv->gmbus_mutex); } - dev_priv->display.set_cdclk(dev_priv, cdclk_config, pipe); + intel_cdclk_set_cdclk(dev_priv, cdclk_config, pipe); for_each_intel_dp(&dev_priv->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -2422,7 +2453,7 @@ static int bxt_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state) cdclk_state->logical.cdclk = cdclk; cdclk_state->logical.voltage_level = max_t(int, min_voltage_level, - dev_priv->display.calc_voltage_level(cdclk)); + intel_cdclk_calc_voltage_level(dev_priv, cdclk)); if (!cdclk_state->active_pipes) { cdclk = bxt_calc_cdclk(dev_priv, cdclk_state->force_min_cdclk); @@ -2431,7 +2462,7 @@ static int bxt_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state) cdclk_state->actual.vco = vco; cdclk_state->actual.cdclk = cdclk; cdclk_state->actual.voltage_level = - dev_priv->display.calc_voltage_level(cdclk); + intel_cdclk_calc_voltage_level(dev_priv, cdclk); } else { cdclk_state->actual = cdclk_state->logical; } @@ -2523,7 +2554,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) new_cdclk_state->active_pipes = intel_calc_active_pipes(state, old_cdclk_state->active_pipes); - ret = dev_priv->display.modeset_calc_cdclk(new_cdclk_state); + ret = intel_cdclk_modeset_calc_cdclk(dev_priv, new_cdclk_state); if (ret) return ret; @@ -2703,7 +2734,7 @@ void intel_update_max_cdclk(struct drm_i915_private *dev_priv) */ void intel_update_cdclk(struct drm_i915_private *dev_priv) { - dev_priv->display.get_cdclk(dev_priv, &dev_priv->cdclk.hw); + intel_cdclk_get_cdclk(dev_priv, &dev_priv->cdclk.hw); /* * 9:0 CMBUS [sic] CDCLK frequency (cdfreq): diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h index b34eb00fb327..309b3f394e24 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.h +++ b/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -68,7 +68,9 @@ void intel_set_cdclk_post_plane_update(struct intel_atomic_state *state); void intel_dump_cdclk_config(const struct intel_cdclk_config *cdclk_config, const char *context); int intel_modeset_calc_cdclk(struct intel_atomic_state *state); - +void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv, + struct intel_cdclk_config *cdclk_config); +int intel_cdclk_bw_calc_min_cdclk(struct intel_atomic_state *state); struct intel_cdclk_state * intel_atomic_get_cdclk_state(struct intel_atomic_state *state); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9af433a7cbf1..5cb6ccdf744a 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -9159,7 +9159,7 @@ static int intel_atomic_check_cdclk(struct intel_atomic_state *state, old_cdclk_state->force_min_cdclk != new_cdclk_state->force_min_cdclk) *need_cdclk_calc = true; - ret = dev_priv->display.bw_calc_min_cdclk(state); + ret = intel_cdclk_bw_calc_min_cdclk(state); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index cce1a926fcc1..a274e2b33e91 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1195,7 +1195,7 @@ static void gen9_disable_dc_states(struct drm_i915_private *dev_priv) if (!HAS_DISPLAY(dev_priv)) return; - dev_priv->display.get_cdclk(dev_priv, &cdclk_config); + 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, -- cgit v1.2.3 From 4360a2b54fd7e6c7ff66869b2fbb55cac7a9c325 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:50 +0300 Subject: drm/i915/display: add intel_fdi_link_train wrapper. This wraps the fdi link training vfunc to make it clearer. Suggested by Jani. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1bb978bcb6f16fbdaf08f2800a179b774525b59e.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/i915/display/intel_fdi.c | 8 ++++++++ drivers/gpu/drm/i915/display/intel_fdi.h | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 5cb6ccdf744a..d7319d5fb4d4 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2165,7 +2165,7 @@ static void ilk_pch_enable(const struct intel_atomic_state *state, assert_pch_transcoder_disabled(dev_priv, pipe); /* For PCH output, training FDI link */ - dev_priv->display.fdi_link_train(crtc, crtc_state); + intel_fdi_link_train(crtc, crtc_state); /* We need to program the right clock selection before writing the pixel * mutliplier into the DPLL. */ diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 96ff12ad0873..d20669e53663 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -10,6 +10,14 @@ #include "intel_fdi.h" #include "intel_sideband.h" +void intel_fdi_link_train(struct intel_crtc *crtc, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + + dev_priv->display.fdi_link_train(crtc, crtc_state); +} + /* units of 100MHz */ static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state) { diff --git a/drivers/gpu/drm/i915/display/intel_fdi.h b/drivers/gpu/drm/i915/display/intel_fdi.h index 60acf2133145..61cb216a09f5 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.h +++ b/drivers/gpu/drm/i915/display/intel_fdi.h @@ -26,4 +26,6 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, void intel_fdi_pll_freq_update(struct drm_i915_private *i915); void lpt_fdi_program_mphy(struct drm_i915_private *i915); +void intel_fdi_link_train(struct intel_crtc *crtc, + const struct intel_crtc_state *crtc_state); #endif -- cgit v1.2.3 From 46d8e4a1da52460912392f51fcda2326be7217a2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:51 +0300 Subject: drm/i915: split clock gating init from display vtable This function is only used inside intel_pm.c Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/95d626a7329ab5779804762894e304e12c6dbe1f.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 9 +++++++- drivers/gpu/drm/i915/intel_pm.c | 48 ++++++++++++++++++++--------------------- 2 files changed, 32 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 97bfeadaab94..bbb28b854f46 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -323,6 +323,11 @@ struct intel_crtc; struct intel_limit; struct dpll; +/* functions used internal in intel_pm.c */ +struct drm_i915_clock_gating_funcs { + void (*init_clock_gating)(struct drm_i915_private *dev_priv); +}; + struct drm_i915_display_funcs { void (*get_cdclk)(struct drm_i915_private *dev_priv, struct intel_cdclk_config *cdclk_config); @@ -365,7 +370,6 @@ struct drm_i915_display_funcs { const struct drm_connector_state *old_conn_state); void (*fdi_link_train)(struct intel_crtc *crtc, const struct intel_crtc_state *crtc_state); - void (*init_clock_gating)(struct drm_i915_private *dev_priv); void (*hpd_irq_setup)(struct drm_i915_private *dev_priv); /* clock updates for mode set */ /* cursor updates */ @@ -954,6 +958,9 @@ struct drm_i915_private { /* unbound hipri wq for page flips/plane updates */ struct workqueue_struct *flip_wq; + /* pm private clock gating functions */ + struct drm_i915_clock_gating_funcs clock_gating_funcs; + /* Display functions */ struct drm_i915_display_funcs display; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 11c9df62391d..34d6faee8969 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7869,7 +7869,7 @@ static void i830_init_clock_gating(struct drm_i915_private *dev_priv) void intel_init_clock_gating(struct drm_i915_private *dev_priv) { - dev_priv->display.init_clock_gating(dev_priv); + dev_priv->clock_gating_funcs.init_clock_gating(dev_priv); } void intel_suspend_hw(struct drm_i915_private *dev_priv) @@ -7896,52 +7896,52 @@ static void nop_init_clock_gating(struct drm_i915_private *dev_priv) void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) { if (IS_ALDERLAKE_P(dev_priv)) - dev_priv->display.init_clock_gating = adlp_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = adlp_init_clock_gating; else if (IS_DG1(dev_priv)) - dev_priv->display.init_clock_gating = dg1_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = dg1_init_clock_gating; else if (GRAPHICS_VER(dev_priv) == 12) - dev_priv->display.init_clock_gating = gen12lp_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = gen12lp_init_clock_gating; else if (GRAPHICS_VER(dev_priv) == 11) - dev_priv->display.init_clock_gating = icl_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = icl_init_clock_gating; else if (IS_COFFEELAKE(dev_priv) || IS_COMETLAKE(dev_priv)) - dev_priv->display.init_clock_gating = cfl_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = cfl_init_clock_gating; else if (IS_SKYLAKE(dev_priv)) - dev_priv->display.init_clock_gating = skl_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = skl_init_clock_gating; else if (IS_KABYLAKE(dev_priv)) - dev_priv->display.init_clock_gating = kbl_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = kbl_init_clock_gating; else if (IS_BROXTON(dev_priv)) - dev_priv->display.init_clock_gating = bxt_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = bxt_init_clock_gating; else if (IS_GEMINILAKE(dev_priv)) - dev_priv->display.init_clock_gating = glk_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = glk_init_clock_gating; else if (IS_BROADWELL(dev_priv)) - dev_priv->display.init_clock_gating = bdw_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = bdw_init_clock_gating; else if (IS_CHERRYVIEW(dev_priv)) - dev_priv->display.init_clock_gating = chv_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = chv_init_clock_gating; else if (IS_HASWELL(dev_priv)) - dev_priv->display.init_clock_gating = hsw_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = hsw_init_clock_gating; else if (IS_IVYBRIDGE(dev_priv)) - dev_priv->display.init_clock_gating = ivb_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = ivb_init_clock_gating; else if (IS_VALLEYVIEW(dev_priv)) - dev_priv->display.init_clock_gating = vlv_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = vlv_init_clock_gating; else if (GRAPHICS_VER(dev_priv) == 6) - dev_priv->display.init_clock_gating = gen6_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = gen6_init_clock_gating; else if (GRAPHICS_VER(dev_priv) == 5) - dev_priv->display.init_clock_gating = ilk_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = ilk_init_clock_gating; else if (IS_G4X(dev_priv)) - dev_priv->display.init_clock_gating = g4x_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = g4x_init_clock_gating; else if (IS_I965GM(dev_priv)) - dev_priv->display.init_clock_gating = i965gm_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = i965gm_init_clock_gating; else if (IS_I965G(dev_priv)) - dev_priv->display.init_clock_gating = i965g_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = i965g_init_clock_gating; else if (GRAPHICS_VER(dev_priv) == 3) - dev_priv->display.init_clock_gating = gen3_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = gen3_init_clock_gating; else if (IS_I85X(dev_priv) || IS_I865G(dev_priv)) - dev_priv->display.init_clock_gating = i85x_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = i85x_init_clock_gating; else if (GRAPHICS_VER(dev_priv) == 2) - dev_priv->display.init_clock_gating = i830_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = i830_init_clock_gating; else { MISSING_CASE(INTEL_DEVID(dev_priv)); - dev_priv->display.init_clock_gating = nop_init_clock_gating; + dev_priv->clock_gating_funcs.init_clock_gating = nop_init_clock_gating; } } -- cgit v1.2.3 From 27057882f62efdf110ed08282982b2d4a23382a9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:52 +0300 Subject: drm/i915: split watermark vfuncs from display vtable. These are the watermark api between display and pm. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/7130356324ef3de59b4e913f025d7dce822157ee.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 34 +++++++++++------------ drivers/gpu/drm/i915/i915_drv.h | 24 +++++++++++------ drivers/gpu/drm/i915/intel_pm.c | 40 ++++++++++++++-------------- 3 files changed, 53 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d7319d5fb4d4..6475435b8316 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -161,16 +161,16 @@ static void intel_modeset_setup_hw_state(struct drm_device *dev, */ static void intel_update_watermarks(struct drm_i915_private *dev_priv) { - if (dev_priv->display.update_wm) - dev_priv->display.update_wm(dev_priv); + if (dev_priv->wm_disp.update_wm) + dev_priv->wm_disp.update_wm(dev_priv); } static int intel_compute_pipe_wm(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->display.compute_pipe_wm) - return dev_priv->display.compute_pipe_wm(state, crtc); + if (dev_priv->wm_disp.compute_pipe_wm) + return dev_priv->wm_disp.compute_pipe_wm(state, crtc); return 0; } @@ -178,20 +178,20 @@ static int intel_compute_intermediate_wm(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (!dev_priv->display.compute_intermediate_wm) + if (!dev_priv->wm_disp.compute_intermediate_wm) return 0; if (drm_WARN_ON(&dev_priv->drm, - !dev_priv->display.compute_pipe_wm)) + !dev_priv->wm_disp.compute_pipe_wm)) return 0; - return dev_priv->display.compute_intermediate_wm(state, crtc); + return dev_priv->wm_disp.compute_intermediate_wm(state, crtc); } static bool intel_initial_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->display.initial_watermarks) { - dev_priv->display.initial_watermarks(state, crtc); + if (dev_priv->wm_disp.initial_watermarks) { + dev_priv->wm_disp.initial_watermarks(state, crtc); return true; } return false; @@ -201,23 +201,23 @@ static void intel_atomic_update_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->display.atomic_update_watermarks) - dev_priv->display.atomic_update_watermarks(state, crtc); + if (dev_priv->wm_disp.atomic_update_watermarks) + dev_priv->wm_disp.atomic_update_watermarks(state, crtc); } static void intel_optimize_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->display.optimize_watermarks) - dev_priv->display.optimize_watermarks(state, crtc); + if (dev_priv->wm_disp.optimize_watermarks) + dev_priv->wm_disp.optimize_watermarks(state, crtc); } static int intel_compute_global_watermarks(struct intel_atomic_state *state) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->display.compute_global_watermarks) - return dev_priv->display.compute_global_watermarks(state); + if (dev_priv->wm_disp.compute_global_watermarks) + return dev_priv->wm_disp.compute_global_watermarks(state); return 0; } @@ -3743,7 +3743,7 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, if (DISPLAY_VER(dev_priv) != 2) intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); - if (!dev_priv->display.initial_watermarks) + if (!dev_priv->wm_disp.initial_watermarks) intel_update_watermarks(dev_priv); /* clock the pipe down to 640x480@60 to potentially save power */ @@ -11404,7 +11404,7 @@ static void sanitize_watermarks(struct drm_i915_private *dev_priv) int i; /* Only supported on platforms that use atomic watermark design */ - if (!dev_priv->display.optimize_watermarks) + if (!dev_priv->wm_disp.optimize_watermarks) return; state = drm_atomic_state_alloc(&dev_priv->drm); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bbb28b854f46..d1a0e110ac4f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -328,13 +328,10 @@ struct drm_i915_clock_gating_funcs { void (*init_clock_gating)(struct drm_i915_private *dev_priv); }; -struct drm_i915_display_funcs { - void (*get_cdclk)(struct drm_i915_private *dev_priv, - struct intel_cdclk_config *cdclk_config); - void (*set_cdclk)(struct drm_i915_private *dev_priv, - const struct intel_cdclk_config *cdclk_config, - enum pipe pipe); - int (*bw_calc_min_cdclk)(struct intel_atomic_state *state); +/* functions used for watermark calcs for display. */ +struct drm_i915_wm_disp_funcs { + /* update_wm is for legacy wm management */ + void (*update_wm)(struct drm_i915_private *dev_priv); int (*compute_pipe_wm)(struct intel_atomic_state *state, struct intel_crtc *crtc); int (*compute_intermediate_wm)(struct intel_atomic_state *state, @@ -346,7 +343,15 @@ struct drm_i915_display_funcs { void (*optimize_watermarks)(struct intel_atomic_state *state, struct intel_crtc *crtc); int (*compute_global_watermarks)(struct intel_atomic_state *state); - void (*update_wm)(struct drm_i915_private *dev_priv); +}; + +struct drm_i915_display_funcs { + void (*get_cdclk)(struct drm_i915_private *dev_priv, + struct intel_cdclk_config *cdclk_config); + void (*set_cdclk)(struct drm_i915_private *dev_priv, + const struct intel_cdclk_config *cdclk_config, + enum pipe pipe); + int (*bw_calc_min_cdclk)(struct intel_atomic_state *state); int (*modeset_calc_cdclk)(struct intel_cdclk_state *state); u8 (*calc_voltage_level)(int cdclk); /* Returns the active state of the crtc, and if the crtc is active, @@ -961,6 +966,9 @@ struct drm_i915_private { /* pm private clock gating functions */ struct drm_i915_clock_gating_funcs clock_gating_funcs; + /* pm display functions */ + struct drm_i915_wm_disp_funcs wm_disp; + /* Display functions */ struct drm_i915_display_funcs display; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 34d6faee8969..b37888781ec9 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7960,7 +7960,7 @@ void intel_init_pm(struct drm_i915_private *dev_priv) /* For FIFO watermark updates */ if (DISPLAY_VER(dev_priv) >= 9) { skl_setup_wm_latency(dev_priv); - dev_priv->display.compute_global_watermarks = skl_compute_wm; + dev_priv->wm_disp.compute_global_watermarks = skl_compute_wm; } else if (HAS_PCH_SPLIT(dev_priv)) { ilk_setup_wm_latency(dev_priv); @@ -7968,12 +7968,12 @@ void intel_init_pm(struct drm_i915_private *dev_priv) dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) || (DISPLAY_VER(dev_priv) != 5 && dev_priv->wm.pri_latency[0] && dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { - dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm; - dev_priv->display.compute_intermediate_wm = + dev_priv->wm_disp.compute_pipe_wm = ilk_compute_pipe_wm; + dev_priv->wm_disp.compute_intermediate_wm = ilk_compute_intermediate_wm; - dev_priv->display.initial_watermarks = + dev_priv->wm_disp.initial_watermarks = ilk_initial_watermarks; - dev_priv->display.optimize_watermarks = + dev_priv->wm_disp.optimize_watermarks = ilk_optimize_watermarks; } else { drm_dbg_kms(&dev_priv->drm, @@ -7982,17 +7982,17 @@ void intel_init_pm(struct drm_i915_private *dev_priv) } } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { vlv_setup_wm_latency(dev_priv); - dev_priv->display.compute_pipe_wm = vlv_compute_pipe_wm; - dev_priv->display.compute_intermediate_wm = vlv_compute_intermediate_wm; - dev_priv->display.initial_watermarks = vlv_initial_watermarks; - dev_priv->display.optimize_watermarks = vlv_optimize_watermarks; - dev_priv->display.atomic_update_watermarks = vlv_atomic_update_fifo; + dev_priv->wm_disp.compute_pipe_wm = vlv_compute_pipe_wm; + dev_priv->wm_disp.compute_intermediate_wm = vlv_compute_intermediate_wm; + dev_priv->wm_disp.initial_watermarks = vlv_initial_watermarks; + dev_priv->wm_disp.optimize_watermarks = vlv_optimize_watermarks; + dev_priv->wm_disp.atomic_update_watermarks = vlv_atomic_update_fifo; } else if (IS_G4X(dev_priv)) { g4x_setup_wm_latency(dev_priv); - dev_priv->display.compute_pipe_wm = g4x_compute_pipe_wm; - dev_priv->display.compute_intermediate_wm = g4x_compute_intermediate_wm; - dev_priv->display.initial_watermarks = g4x_initial_watermarks; - dev_priv->display.optimize_watermarks = g4x_optimize_watermarks; + dev_priv->wm_disp.compute_pipe_wm = g4x_compute_pipe_wm; + dev_priv->wm_disp.compute_intermediate_wm = g4x_compute_intermediate_wm; + dev_priv->wm_disp.initial_watermarks = g4x_initial_watermarks; + dev_priv->wm_disp.optimize_watermarks = g4x_optimize_watermarks; } else if (IS_PINEVIEW(dev_priv)) { if (!intel_get_cxsr_latency(!IS_MOBILE(dev_priv), dev_priv->is_ddr3, @@ -8006,18 +8006,18 @@ void intel_init_pm(struct drm_i915_private *dev_priv) dev_priv->fsb_freq, dev_priv->mem_freq); /* Disable CxSR and never update its watermark again */ intel_set_memory_cxsr(dev_priv, false); - dev_priv->display.update_wm = NULL; + dev_priv->wm_disp.update_wm = NULL; } else - dev_priv->display.update_wm = pnv_update_wm; + dev_priv->wm_disp.update_wm = pnv_update_wm; } else if (DISPLAY_VER(dev_priv) == 4) { - dev_priv->display.update_wm = i965_update_wm; + dev_priv->wm_disp.update_wm = i965_update_wm; } else if (DISPLAY_VER(dev_priv) == 3) { - dev_priv->display.update_wm = i9xx_update_wm; + dev_priv->wm_disp.update_wm = i9xx_update_wm; } else if (DISPLAY_VER(dev_priv) == 2) { if (INTEL_NUM_PIPES(dev_priv) == 1) - dev_priv->display.update_wm = i845_update_wm; + dev_priv->wm_disp.update_wm = i845_update_wm; else - dev_priv->display.update_wm = i9xx_update_wm; + dev_priv->wm_disp.update_wm = i9xx_update_wm; } else { drm_err(&dev_priv->drm, "unexpected fall-through in %s\n", __func__); -- cgit v1.2.3 From 082800ab52d64cdb754c5d89361e737cdc44ffba Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:53 +0300 Subject: drm/i915: split color functions from display vtable These are only used internally in the color module Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/084a31362f1621d2f556069bb2bc47d362a63823.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_color.c | 64 +++++++++++++++--------------- drivers/gpu/drm/i915/i915_drv.h | 39 ++++++++++-------- 2 files changed, 54 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index afcb4bf3826c..ed79075158dd 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -1137,14 +1137,14 @@ void intel_color_load_luts(const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); - dev_priv->display.load_luts(crtc_state); + dev_priv->color_funcs.load_luts(crtc_state); } void intel_color_commit(const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); - dev_priv->display.color_commit(crtc_state); + dev_priv->color_funcs.color_commit(crtc_state); } static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state) @@ -1200,15 +1200,15 @@ int intel_color_check(struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); - return dev_priv->display.color_check(crtc_state); + return dev_priv->color_funcs.color_check(crtc_state); } void intel_color_get_config(struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); - if (dev_priv->display.read_luts) - dev_priv->display.read_luts(crtc_state); + if (dev_priv->color_funcs.read_luts) + dev_priv->color_funcs.read_luts(crtc_state); } static bool need_plane_update(struct intel_plane *plane, @@ -2101,51 +2101,51 @@ void intel_color_init(struct intel_crtc *crtc) if (HAS_GMCH(dev_priv)) { if (IS_CHERRYVIEW(dev_priv)) { - dev_priv->display.color_check = chv_color_check; - dev_priv->display.color_commit = i9xx_color_commit; - dev_priv->display.load_luts = chv_load_luts; - dev_priv->display.read_luts = chv_read_luts; + dev_priv->color_funcs.color_check = chv_color_check; + dev_priv->color_funcs.color_commit = i9xx_color_commit; + dev_priv->color_funcs.load_luts = chv_load_luts; + dev_priv->color_funcs.read_luts = chv_read_luts; } else if (DISPLAY_VER(dev_priv) >= 4) { - dev_priv->display.color_check = i9xx_color_check; - dev_priv->display.color_commit = i9xx_color_commit; - dev_priv->display.load_luts = i965_load_luts; - dev_priv->display.read_luts = i965_read_luts; + dev_priv->color_funcs.color_check = i9xx_color_check; + dev_priv->color_funcs.color_commit = i9xx_color_commit; + dev_priv->color_funcs.load_luts = i965_load_luts; + dev_priv->color_funcs.read_luts = i965_read_luts; } else { - dev_priv->display.color_check = i9xx_color_check; - dev_priv->display.color_commit = i9xx_color_commit; - dev_priv->display.load_luts = i9xx_load_luts; - dev_priv->display.read_luts = i9xx_read_luts; + dev_priv->color_funcs.color_check = i9xx_color_check; + dev_priv->color_funcs.color_commit = i9xx_color_commit; + dev_priv->color_funcs.load_luts = i9xx_load_luts; + dev_priv->color_funcs.read_luts = i9xx_read_luts; } } else { if (DISPLAY_VER(dev_priv) >= 11) - dev_priv->display.color_check = icl_color_check; + dev_priv->color_funcs.color_check = icl_color_check; else if (DISPLAY_VER(dev_priv) >= 10) - dev_priv->display.color_check = glk_color_check; + dev_priv->color_funcs.color_check = glk_color_check; else if (DISPLAY_VER(dev_priv) >= 7) - dev_priv->display.color_check = ivb_color_check; + dev_priv->color_funcs.color_check = ivb_color_check; else - dev_priv->display.color_check = ilk_color_check; + dev_priv->color_funcs.color_check = ilk_color_check; if (DISPLAY_VER(dev_priv) >= 9) - dev_priv->display.color_commit = skl_color_commit; + dev_priv->color_funcs.color_commit = skl_color_commit; else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) - dev_priv->display.color_commit = hsw_color_commit; + dev_priv->color_funcs.color_commit = hsw_color_commit; else - dev_priv->display.color_commit = ilk_color_commit; + dev_priv->color_funcs.color_commit = ilk_color_commit; if (DISPLAY_VER(dev_priv) >= 11) { - dev_priv->display.load_luts = icl_load_luts; - dev_priv->display.read_luts = icl_read_luts; + dev_priv->color_funcs.load_luts = icl_load_luts; + dev_priv->color_funcs.read_luts = icl_read_luts; } else if (DISPLAY_VER(dev_priv) == 10) { - dev_priv->display.load_luts = glk_load_luts; - dev_priv->display.read_luts = glk_read_luts; + dev_priv->color_funcs.load_luts = glk_load_luts; + dev_priv->color_funcs.read_luts = glk_read_luts; } else if (DISPLAY_VER(dev_priv) >= 8) { - dev_priv->display.load_luts = bdw_load_luts; + dev_priv->color_funcs.load_luts = bdw_load_luts; } else if (DISPLAY_VER(dev_priv) >= 7) { - dev_priv->display.load_luts = ivb_load_luts; + dev_priv->color_funcs.load_luts = ivb_load_luts; } else { - dev_priv->display.load_luts = ilk_load_luts; - dev_priv->display.read_luts = ilk_read_luts; + dev_priv->color_funcs.load_luts = ilk_load_luts; + dev_priv->color_funcs.read_luts = ilk_read_luts; } } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d1a0e110ac4f..65f5b2128708 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -345,6 +345,25 @@ struct drm_i915_wm_disp_funcs { int (*compute_global_watermarks)(struct intel_atomic_state *state); }; +struct intel_color_funcs { + int (*color_check)(struct intel_crtc_state *crtc_state); + /* + * Program double buffered color management registers during + * vblank evasion. The registers should then latch during the + * next vblank start, alongside any other double buffered registers + * involved with the same commit. + */ + void (*color_commit)(const struct intel_crtc_state *crtc_state); + /* + * Load LUTs (and other single buffered color management + * registers). Will (hopefully) be called during the vblank + * following the latching of any double buffered registers + * involved with the same commit. + */ + void (*load_luts)(const struct intel_crtc_state *crtc_state); + void (*read_luts)(struct intel_crtc_state *crtc_state); +}; + struct drm_i915_display_funcs { void (*get_cdclk)(struct drm_i915_private *dev_priv, struct intel_cdclk_config *cdclk_config); @@ -381,23 +400,6 @@ struct drm_i915_display_funcs { /* render clock increase/decrease */ /* display clock increase/decrease */ /* pll clock increase/decrease */ - - int (*color_check)(struct intel_crtc_state *crtc_state); - /* - * Program double buffered color management registers during - * vblank evasion. The registers should then latch during the - * next vblank start, alongside any other double buffered registers - * involved with the same commit. - */ - void (*color_commit)(const struct intel_crtc_state *crtc_state); - /* - * Load LUTs (and other single buffered color management - * registers). Will (hopefully) be called during the vblank - * following the latching of any double buffered registers - * involved with the same commit. - */ - void (*load_luts)(const struct intel_crtc_state *crtc_state); - void (*read_luts)(struct intel_crtc_state *crtc_state); }; @@ -972,6 +974,9 @@ struct drm_i915_private { /* Display functions */ struct drm_i915_display_funcs display; + /* Display internal color functions */ + struct intel_color_funcs color_funcs; + /* PCH chipset type */ enum intel_pch pch_type; unsigned short pch_id; -- cgit v1.2.3 From 7b75709ac8b566a386b1aa5642287ce6d4a78bd9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:54 +0300 Subject: drm/i915: split audio functions from display vtable These are only used internally in the audio code Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/d12257cc7685a9b52618f7da444ba1fc8848b4db.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_audio.c | 24 ++++++++++++------------ drivers/gpu/drm/i915/i915_drv.h | 19 +++++++++++++------ 2 files changed, 25 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 4e0f96bf6158..bf96d1529775 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -848,8 +848,8 @@ void intel_audio_codec_enable(struct intel_encoder *encoder, connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2; - if (dev_priv->display.audio_codec_enable) - dev_priv->display.audio_codec_enable(encoder, + if (dev_priv->audio_funcs.audio_codec_enable) + dev_priv->audio_funcs.audio_codec_enable(encoder, crtc_state, conn_state); @@ -893,8 +893,8 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, enum port port = encoder->port; enum pipe pipe = crtc->pipe; - if (dev_priv->display.audio_codec_disable) - dev_priv->display.audio_codec_disable(encoder, + if (dev_priv->audio_funcs.audio_codec_disable) + dev_priv->audio_funcs.audio_codec_disable(encoder, old_crtc_state, old_conn_state); @@ -922,17 +922,17 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, void intel_init_audio_hooks(struct drm_i915_private *dev_priv) { if (IS_G4X(dev_priv)) { - dev_priv->display.audio_codec_enable = g4x_audio_codec_enable; - dev_priv->display.audio_codec_disable = g4x_audio_codec_disable; + dev_priv->audio_funcs.audio_codec_enable = g4x_audio_codec_enable; + dev_priv->audio_funcs.audio_codec_disable = g4x_audio_codec_disable; } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - dev_priv->display.audio_codec_enable = ilk_audio_codec_enable; - dev_priv->display.audio_codec_disable = ilk_audio_codec_disable; + dev_priv->audio_funcs.audio_codec_enable = ilk_audio_codec_enable; + dev_priv->audio_funcs.audio_codec_disable = ilk_audio_codec_disable; } else if (IS_HASWELL(dev_priv) || DISPLAY_VER(dev_priv) >= 8) { - dev_priv->display.audio_codec_enable = hsw_audio_codec_enable; - dev_priv->display.audio_codec_disable = hsw_audio_codec_disable; + dev_priv->audio_funcs.audio_codec_enable = hsw_audio_codec_enable; + dev_priv->audio_funcs.audio_codec_disable = hsw_audio_codec_disable; } else if (HAS_PCH_SPLIT(dev_priv)) { - dev_priv->display.audio_codec_enable = ilk_audio_codec_enable; - dev_priv->display.audio_codec_disable = ilk_audio_codec_disable; + dev_priv->audio_funcs.audio_codec_enable = ilk_audio_codec_enable; + dev_priv->audio_funcs.audio_codec_disable = ilk_audio_codec_disable; } } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 65f5b2128708..8f81c2bd2899 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -364,6 +364,15 @@ struct intel_color_funcs { void (*read_luts)(struct intel_crtc_state *crtc_state); }; +struct intel_audio_funcs { + void (*audio_codec_enable)(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); + void (*audio_codec_disable)(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state); +}; + struct drm_i915_display_funcs { void (*get_cdclk)(struct drm_i915_private *dev_priv, struct intel_cdclk_config *cdclk_config); @@ -386,12 +395,7 @@ struct drm_i915_display_funcs { struct intel_crtc *crtc); void (*commit_modeset_enables)(struct intel_atomic_state *state); void (*commit_modeset_disables)(struct intel_atomic_state *state); - void (*audio_codec_enable)(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); - void (*audio_codec_disable)(struct intel_encoder *encoder, - const struct intel_crtc_state *old_crtc_state, - const struct drm_connector_state *old_conn_state); + void (*fdi_link_train)(struct intel_crtc *crtc, const struct intel_crtc_state *crtc_state); void (*hpd_irq_setup)(struct drm_i915_private *dev_priv); @@ -977,6 +981,9 @@ struct drm_i915_private { /* Display internal color functions */ struct intel_color_funcs color_funcs; + /* Display internal audio functions */ + struct intel_audio_funcs audio_funcs; + /* PCH chipset type */ enum intel_pch pch_type; unsigned short pch_id; -- cgit v1.2.3 From 89ac34c14d7e48bf8066e35a9b4886208c06c4d8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:55 +0300 Subject: drm/i915: split cdclk functions from display vtable. This moves all the cdclk related functions into their own vtable. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/591b7b6a79c4ab644a161ae00b7d630b3ef16434.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_cdclk.c | 142 ++++++++++++++--------------- drivers/gpu/drm/i915/i915_drv.h | 8 +- 2 files changed, 78 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index ff01fe9be35c..cf0a865df596 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -62,32 +62,32 @@ void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv, struct intel_cdclk_config *cdclk_config) { - dev_priv->display.get_cdclk(dev_priv, cdclk_config); + dev_priv->cdclk_funcs.get_cdclk(dev_priv, cdclk_config); } int intel_cdclk_bw_calc_min_cdclk(struct intel_atomic_state *state) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - return dev_priv->display.bw_calc_min_cdclk(state); + return dev_priv->cdclk_funcs.bw_calc_min_cdclk(state); } static void intel_cdclk_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { - dev_priv->display.set_cdclk(dev_priv, cdclk_config, pipe); + dev_priv->cdclk_funcs.set_cdclk(dev_priv, cdclk_config, pipe); } static int intel_cdclk_modeset_calc_cdclk(struct drm_i915_private *dev_priv, struct intel_cdclk_state *cdclk_config) { - return dev_priv->display.modeset_calc_cdclk(cdclk_config); + return dev_priv->cdclk_funcs.modeset_calc_cdclk(cdclk_config); } static u8 intel_cdclk_calc_voltage_level(struct drm_i915_private *dev_priv, int cdclk) { - return dev_priv->display.calc_voltage_level(cdclk); + return dev_priv->cdclk_funcs.calc_voltage_level(cdclk); } static void fixed_133mhz_get_cdclk(struct drm_i915_private *dev_priv, @@ -1963,7 +1963,7 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv, if (!intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_config)) return; - if (drm_WARN_ON_ONCE(&dev_priv->drm, !dev_priv->display.set_cdclk)) + if (drm_WARN_ON_ONCE(&dev_priv->drm, !dev_priv->cdclk_funcs.set_cdclk)) return; intel_dump_cdclk_config(cdclk_config, "Changing CDCLK to"); @@ -2891,119 +2891,119 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) { if (IS_DG2(dev_priv)) { - dev_priv->display.set_cdclk = bxt_set_cdclk; - dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->display.calc_voltage_level = tgl_calc_voltage_level; + dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; + dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; + dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; + dev_priv->cdclk_funcs.calc_voltage_level = tgl_calc_voltage_level; dev_priv->cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { - dev_priv->display.set_cdclk = bxt_set_cdclk; - dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->display.calc_voltage_level = tgl_calc_voltage_level; + dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; + dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; + dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; + dev_priv->cdclk_funcs.calc_voltage_level = tgl_calc_voltage_level; /* 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; else dev_priv->cdclk.table = adlp_cdclk_table; } else if (IS_ROCKETLAKE(dev_priv)) { - dev_priv->display.set_cdclk = bxt_set_cdclk; - dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->display.calc_voltage_level = tgl_calc_voltage_level; + dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; + dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; + dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; + dev_priv->cdclk_funcs.calc_voltage_level = tgl_calc_voltage_level; dev_priv->cdclk.table = rkl_cdclk_table; } else if (DISPLAY_VER(dev_priv) >= 12) { - dev_priv->display.set_cdclk = bxt_set_cdclk; - dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->display.calc_voltage_level = tgl_calc_voltage_level; + dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; + dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; + dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; + dev_priv->cdclk_funcs.calc_voltage_level = tgl_calc_voltage_level; dev_priv->cdclk.table = icl_cdclk_table; } else if (IS_JSL_EHL(dev_priv)) { - dev_priv->display.set_cdclk = bxt_set_cdclk; - dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->display.calc_voltage_level = ehl_calc_voltage_level; + dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; + dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; + dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; + dev_priv->cdclk_funcs.calc_voltage_level = ehl_calc_voltage_level; dev_priv->cdclk.table = icl_cdclk_table; } else if (DISPLAY_VER(dev_priv) >= 11) { - dev_priv->display.set_cdclk = bxt_set_cdclk; - dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->display.calc_voltage_level = icl_calc_voltage_level; + dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; + dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; + dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; + dev_priv->cdclk_funcs.calc_voltage_level = icl_calc_voltage_level; dev_priv->cdclk.table = icl_cdclk_table; } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { - dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->display.set_cdclk = bxt_set_cdclk; - dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->display.calc_voltage_level = bxt_calc_voltage_level; + dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; + dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; + dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; + dev_priv->cdclk_funcs.calc_voltage_level = bxt_calc_voltage_level; if (IS_GEMINILAKE(dev_priv)) dev_priv->cdclk.table = glk_cdclk_table; else dev_priv->cdclk.table = bxt_cdclk_table; } else if (DISPLAY_VER(dev_priv) == 9) { - dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->display.set_cdclk = skl_set_cdclk; - dev_priv->display.modeset_calc_cdclk = skl_modeset_calc_cdclk; + dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; + dev_priv->cdclk_funcs.set_cdclk = skl_set_cdclk; + dev_priv->cdclk_funcs.modeset_calc_cdclk = skl_modeset_calc_cdclk; } else if (IS_BROADWELL(dev_priv)) { - dev_priv->display.bw_calc_min_cdclk = intel_bw_calc_min_cdclk; - dev_priv->display.set_cdclk = bdw_set_cdclk; - dev_priv->display.modeset_calc_cdclk = bdw_modeset_calc_cdclk; + dev_priv->cdclk_funcs.bw_calc_min_cdclk = intel_bw_calc_min_cdclk; + dev_priv->cdclk_funcs.set_cdclk = bdw_set_cdclk; + dev_priv->cdclk_funcs.modeset_calc_cdclk = bdw_modeset_calc_cdclk; } else if (IS_CHERRYVIEW(dev_priv)) { - dev_priv->display.bw_calc_min_cdclk = intel_bw_calc_min_cdclk; - dev_priv->display.set_cdclk = chv_set_cdclk; - dev_priv->display.modeset_calc_cdclk = vlv_modeset_calc_cdclk; + dev_priv->cdclk_funcs.bw_calc_min_cdclk = intel_bw_calc_min_cdclk; + dev_priv->cdclk_funcs.set_cdclk = chv_set_cdclk; + dev_priv->cdclk_funcs.modeset_calc_cdclk = vlv_modeset_calc_cdclk; } else if (IS_VALLEYVIEW(dev_priv)) { - dev_priv->display.bw_calc_min_cdclk = intel_bw_calc_min_cdclk; - dev_priv->display.set_cdclk = vlv_set_cdclk; - dev_priv->display.modeset_calc_cdclk = vlv_modeset_calc_cdclk; + dev_priv->cdclk_funcs.bw_calc_min_cdclk = intel_bw_calc_min_cdclk; + dev_priv->cdclk_funcs.set_cdclk = vlv_set_cdclk; + dev_priv->cdclk_funcs.modeset_calc_cdclk = vlv_modeset_calc_cdclk; } else { - dev_priv->display.bw_calc_min_cdclk = intel_bw_calc_min_cdclk; - dev_priv->display.modeset_calc_cdclk = fixed_modeset_calc_cdclk; + dev_priv->cdclk_funcs.bw_calc_min_cdclk = intel_bw_calc_min_cdclk; + dev_priv->cdclk_funcs.modeset_calc_cdclk = fixed_modeset_calc_cdclk; } if (DISPLAY_VER(dev_priv) >= 10 || IS_BROXTON(dev_priv)) - dev_priv->display.get_cdclk = bxt_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = bxt_get_cdclk; else if (DISPLAY_VER(dev_priv) == 9) - dev_priv->display.get_cdclk = skl_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = skl_get_cdclk; else if (IS_BROADWELL(dev_priv)) - dev_priv->display.get_cdclk = bdw_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = bdw_get_cdclk; else if (IS_HASWELL(dev_priv)) - dev_priv->display.get_cdclk = hsw_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = hsw_get_cdclk; else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - dev_priv->display.get_cdclk = vlv_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = vlv_get_cdclk; else if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) - dev_priv->display.get_cdclk = fixed_400mhz_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = fixed_400mhz_get_cdclk; else if (IS_IRONLAKE(dev_priv)) - dev_priv->display.get_cdclk = fixed_450mhz_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = fixed_450mhz_get_cdclk; else if (IS_GM45(dev_priv)) - dev_priv->display.get_cdclk = gm45_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = gm45_get_cdclk; else if (IS_G45(dev_priv)) - dev_priv->display.get_cdclk = g33_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = g33_get_cdclk; else if (IS_I965GM(dev_priv)) - dev_priv->display.get_cdclk = i965gm_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = i965gm_get_cdclk; else if (IS_I965G(dev_priv)) - dev_priv->display.get_cdclk = fixed_400mhz_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = fixed_400mhz_get_cdclk; else if (IS_PINEVIEW(dev_priv)) - dev_priv->display.get_cdclk = pnv_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = pnv_get_cdclk; else if (IS_G33(dev_priv)) - dev_priv->display.get_cdclk = g33_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = g33_get_cdclk; else if (IS_I945GM(dev_priv)) - dev_priv->display.get_cdclk = i945gm_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = i945gm_get_cdclk; else if (IS_I945G(dev_priv)) - dev_priv->display.get_cdclk = fixed_400mhz_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = fixed_400mhz_get_cdclk; else if (IS_I915GM(dev_priv)) - dev_priv->display.get_cdclk = i915gm_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = i915gm_get_cdclk; else if (IS_I915G(dev_priv)) - dev_priv->display.get_cdclk = fixed_333mhz_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = fixed_333mhz_get_cdclk; else if (IS_I865G(dev_priv)) - dev_priv->display.get_cdclk = fixed_266mhz_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = fixed_266mhz_get_cdclk; else if (IS_I85X(dev_priv)) - dev_priv->display.get_cdclk = i85x_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = i85x_get_cdclk; else if (IS_I845G(dev_priv)) - dev_priv->display.get_cdclk = fixed_200mhz_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = fixed_200mhz_get_cdclk; else if (IS_I830(dev_priv)) - dev_priv->display.get_cdclk = fixed_133mhz_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = fixed_133mhz_get_cdclk; - if (drm_WARN(&dev_priv->drm, !dev_priv->display.get_cdclk, + if (drm_WARN(&dev_priv->drm, !dev_priv->cdclk_funcs.get_cdclk, "Unknown platform. Assuming 133 MHz CDCLK\n")) - dev_priv->display.get_cdclk = fixed_133mhz_get_cdclk; + dev_priv->cdclk_funcs.get_cdclk = fixed_133mhz_get_cdclk; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8f81c2bd2899..6da19391ea0d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -373,7 +373,7 @@ struct intel_audio_funcs { const struct drm_connector_state *old_conn_state); }; -struct drm_i915_display_funcs { +struct intel_cdclk_funcs { void (*get_cdclk)(struct drm_i915_private *dev_priv, struct intel_cdclk_config *cdclk_config); void (*set_cdclk)(struct drm_i915_private *dev_priv, @@ -382,6 +382,9 @@ struct drm_i915_display_funcs { int (*bw_calc_min_cdclk)(struct intel_atomic_state *state); int (*modeset_calc_cdclk)(struct intel_cdclk_state *state); u8 (*calc_voltage_level)(int cdclk); +}; + +struct drm_i915_display_funcs { /* Returns the active state of the crtc, and if the crtc is active, * fills out the pipe-config with the hw state. */ bool (*get_pipe_config)(struct intel_crtc *, @@ -984,6 +987,9 @@ struct drm_i915_private { /* Display internal audio functions */ struct intel_audio_funcs audio_funcs; + /* Display CDCLK functions */ + struct intel_cdclk_funcs cdclk_funcs; + /* PCH chipset type */ enum intel_pch pch_type; unsigned short pch_id; -- cgit v1.2.3 From de1677c5e32ace87ca69861dc32115e824af3278 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:56 +0300 Subject: drm/i915: split irq hotplug function from display vtable This provide a service from irq to display, so make it separate Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/05f533064709764dff8bcfef6a58f9a8482dc5bb.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_hotplug.c | 4 ++-- drivers/gpu/drm/i915/i915_drv.h | 9 ++++++++- drivers/gpu/drm/i915/i915_irq.c | 14 +++++++------- 3 files changed, 17 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index 47c85ac97c87..05f76aba4f8a 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -215,8 +215,8 @@ intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv) static void intel_hpd_irq_setup(struct drm_i915_private *i915) { - if (i915->display_irqs_enabled && i915->display.hpd_irq_setup) - i915->display.hpd_irq_setup(i915); + if (i915->display_irqs_enabled && i915->hotplug_funcs.hpd_irq_setup) + i915->hotplug_funcs.hpd_irq_setup(i915); } static void intel_hpd_irq_storm_reenable_work(struct work_struct *work) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6da19391ea0d..58db1e2789e2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -384,6 +384,10 @@ struct intel_cdclk_funcs { u8 (*calc_voltage_level)(int cdclk); }; +struct intel_hotplug_funcs { + void (*hpd_irq_setup)(struct drm_i915_private *dev_priv); +}; + struct drm_i915_display_funcs { /* Returns the active state of the crtc, and if the crtc is active, * fills out the pipe-config with the hw state. */ @@ -401,7 +405,7 @@ struct drm_i915_display_funcs { void (*fdi_link_train)(struct intel_crtc *crtc, const struct intel_crtc_state *crtc_state); - void (*hpd_irq_setup)(struct drm_i915_private *dev_priv); + /* clock updates for mode set */ /* cursor updates */ /* render clock increase/decrease */ @@ -978,6 +982,9 @@ struct drm_i915_private { /* pm display functions */ struct drm_i915_wm_disp_funcs wm_disp; + /* irq display functions */ + struct intel_hotplug_funcs hotplug_funcs; + /* Display functions */ struct drm_i915_display_funcs display; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0a1681384c84..c35065f8f429 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -4395,20 +4395,20 @@ void intel_irq_init(struct drm_i915_private *dev_priv) if (HAS_GMCH(dev_priv)) { if (I915_HAS_HOTPLUG(dev_priv)) - dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; + dev_priv->hotplug_funcs.hpd_irq_setup = i915_hpd_irq_setup; } else { if (HAS_PCH_DG1(dev_priv)) - dev_priv->display.hpd_irq_setup = dg1_hpd_irq_setup; + dev_priv->hotplug_funcs.hpd_irq_setup = dg1_hpd_irq_setup; else if (DISPLAY_VER(dev_priv) >= 11) - dev_priv->display.hpd_irq_setup = gen11_hpd_irq_setup; + dev_priv->hotplug_funcs.hpd_irq_setup = gen11_hpd_irq_setup; else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) - dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup; + dev_priv->hotplug_funcs.hpd_irq_setup = bxt_hpd_irq_setup; else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) - dev_priv->display.hpd_irq_setup = icp_hpd_irq_setup; + dev_priv->hotplug_funcs.hpd_irq_setup = icp_hpd_irq_setup; else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT) - dev_priv->display.hpd_irq_setup = spt_hpd_irq_setup; + dev_priv->hotplug_funcs.hpd_irq_setup = spt_hpd_irq_setup; else - dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup; + dev_priv->hotplug_funcs.hpd_irq_setup = ilk_hpd_irq_setup; } } -- cgit v1.2.3 From 5c8c179bcaf6dbbc3381ae8afbb6dc5978d4f234 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:57 +0300 Subject: drm/i915: split fdi link training from display vtable. It may make sense to merge this with display again later, however the fdi use of the vtable is limited to only a few generations. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/7af7359b6cec33bd2d32152893d9a1e8f8cf7f21.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_fdi.c | 8 ++++---- drivers/gpu/drm/i915/i915_drv.h | 11 ++++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index d20669e53663..f828bebe8962 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -15,7 +15,7 @@ void intel_fdi_link_train(struct intel_crtc *crtc, { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - dev_priv->display.fdi_link_train(crtc, crtc_state); + dev_priv->fdi_funcs.fdi_link_train(crtc, crtc_state); } /* units of 100MHz */ @@ -1017,11 +1017,11 @@ void intel_fdi_init_hook(struct drm_i915_private *dev_priv) { if (IS_IRONLAKE(dev_priv)) { - dev_priv->display.fdi_link_train = ilk_fdi_link_train; + dev_priv->fdi_funcs.fdi_link_train = ilk_fdi_link_train; } else if (IS_SANDYBRIDGE(dev_priv)) { - dev_priv->display.fdi_link_train = gen6_fdi_link_train; + dev_priv->fdi_funcs.fdi_link_train = gen6_fdi_link_train; } else if (IS_IVYBRIDGE(dev_priv)) { /* FIXME: detect B0+ stepping and use auto training */ - dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train; + dev_priv->fdi_funcs.fdi_link_train = ivb_manual_fdi_link_train; } } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 58db1e2789e2..c51142ffef54 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -388,6 +388,11 @@ struct intel_hotplug_funcs { void (*hpd_irq_setup)(struct drm_i915_private *dev_priv); }; +struct intel_fdi_funcs { + void (*fdi_link_train)(struct intel_crtc *crtc, + const struct intel_crtc_state *crtc_state); +}; + struct drm_i915_display_funcs { /* Returns the active state of the crtc, and if the crtc is active, * fills out the pipe-config with the hw state. */ @@ -403,9 +408,6 @@ struct drm_i915_display_funcs { void (*commit_modeset_enables)(struct intel_atomic_state *state); void (*commit_modeset_disables)(struct intel_atomic_state *state); - void (*fdi_link_train)(struct intel_crtc *crtc, - const struct intel_crtc_state *crtc_state); - /* clock updates for mode set */ /* cursor updates */ /* render clock increase/decrease */ @@ -985,6 +987,9 @@ struct drm_i915_private { /* irq display functions */ struct intel_hotplug_funcs hotplug_funcs; + /* fdi display functions */ + struct intel_fdi_funcs fdi_funcs; + /* Display functions */ struct drm_i915_display_funcs display; -- cgit v1.2.3 From 903f3806f3e83b6590a7ed6846fb206ec505457f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:58 +0300 Subject: drm/i915: split the dpll clock compute out from display vtable. this single function might be possible to merge later, but for now it's simple to just split it out. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/ba570aa10b694b2e8640e0c58430fd0053c306b7.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 6 +++--- drivers/gpu/drm/i915/display/intel_dpll.c | 16 ++++++++-------- drivers/gpu/drm/i915/i915_drv.h | 8 +++++++- 3 files changed, 18 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 6475435b8316..146281bfec59 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6833,10 +6833,10 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state, crtc_state->update_wm_post = true; if (mode_changed && crtc_state->hw.enable && - dev_priv->display.crtc_compute_clock && + dev_priv->dpll_funcs.crtc_compute_clock && !crtc_state->bigjoiner_slave && !drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll)) { - ret = dev_priv->display.crtc_compute_clock(crtc_state); + ret = dev_priv->dpll_funcs.crtc_compute_clock(crtc_state); if (ret) return ret; } @@ -8863,7 +8863,7 @@ static void intel_modeset_clear_plls(struct intel_atomic_state *state) struct intel_crtc *crtc; int i; - if (!dev_priv->display.crtc_compute_clock) + if (!dev_priv->dpll_funcs.crtc_compute_clock) return; for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 487d8721ecf8..7811f19acb6a 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -1369,21 +1369,21 @@ void intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv) { if (DISPLAY_VER(dev_priv) >= 9 || HAS_DDI(dev_priv)) - dev_priv->display.crtc_compute_clock = hsw_crtc_compute_clock; + dev_priv->dpll_funcs.crtc_compute_clock = hsw_crtc_compute_clock; else if (HAS_PCH_SPLIT(dev_priv)) - dev_priv->display.crtc_compute_clock = ilk_crtc_compute_clock; + dev_priv->dpll_funcs.crtc_compute_clock = ilk_crtc_compute_clock; else if (IS_CHERRYVIEW(dev_priv)) - dev_priv->display.crtc_compute_clock = chv_crtc_compute_clock; + dev_priv->dpll_funcs.crtc_compute_clock = chv_crtc_compute_clock; else if (IS_VALLEYVIEW(dev_priv)) - dev_priv->display.crtc_compute_clock = vlv_crtc_compute_clock; + dev_priv->dpll_funcs.crtc_compute_clock = vlv_crtc_compute_clock; else if (IS_G4X(dev_priv)) - dev_priv->display.crtc_compute_clock = g4x_crtc_compute_clock; + dev_priv->dpll_funcs.crtc_compute_clock = g4x_crtc_compute_clock; else if (IS_PINEVIEW(dev_priv)) - dev_priv->display.crtc_compute_clock = pnv_crtc_compute_clock; + dev_priv->dpll_funcs.crtc_compute_clock = pnv_crtc_compute_clock; else if (DISPLAY_VER(dev_priv) != 2) - dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock; + dev_priv->dpll_funcs.crtc_compute_clock = i9xx_crtc_compute_clock; else - dev_priv->display.crtc_compute_clock = i8xx_crtc_compute_clock; + dev_priv->dpll_funcs.crtc_compute_clock = i8xx_crtc_compute_clock; } static bool i9xx_has_pps(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c51142ffef54..ed2d8b61fe4d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -393,6 +393,10 @@ struct intel_fdi_funcs { const struct intel_crtc_state *crtc_state); }; +struct intel_dpll_funcs { + int (*crtc_compute_clock)(struct intel_crtc_state *crtc_state); +}; + struct drm_i915_display_funcs { /* Returns the active state of the crtc, and if the crtc is active, * fills out the pipe-config with the hw state. */ @@ -400,7 +404,6 @@ struct drm_i915_display_funcs { struct intel_crtc_state *); void (*get_initial_plane_config)(struct intel_crtc *, struct intel_initial_plane_config *); - int (*crtc_compute_clock)(struct intel_crtc_state *crtc_state); void (*crtc_enable)(struct intel_atomic_state *state, struct intel_crtc *crtc); void (*crtc_disable)(struct intel_atomic_state *state, @@ -990,6 +993,9 @@ struct drm_i915_private { /* fdi display functions */ struct intel_fdi_funcs fdi_funcs; + /* display pll funcs */ + struct intel_dpll_funcs dpll_funcs; + /* Display functions */ struct drm_i915_display_funcs display; -- cgit v1.2.3 From 1c55b1e063d0ecd466a6163c37af528bd0ab3f2b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:57:59 +0300 Subject: drm/i915: constify fdi link training vtable Put the vtable into ro memory. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/ec4687956f9b98024fea55b2f0ed1e192e244ff1.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_fdi.c | 20 ++++++++++++++++---- drivers/gpu/drm/i915/i915_drv.h | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index f828bebe8962..af01d1fa761e 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -15,7 +15,7 @@ void intel_fdi_link_train(struct intel_crtc *crtc, { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - dev_priv->fdi_funcs.fdi_link_train(crtc, crtc_state); + dev_priv->fdi_funcs->fdi_link_train(crtc, crtc_state); } /* units of 100MHz */ @@ -1013,15 +1013,27 @@ void lpt_fdi_program_mphy(struct drm_i915_private *dev_priv) intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY); } +static const struct intel_fdi_funcs ilk_funcs = { + .fdi_link_train = ilk_fdi_link_train, +}; + +static const struct intel_fdi_funcs gen6_funcs = { + .fdi_link_train = gen6_fdi_link_train, +}; + +static const struct intel_fdi_funcs ivb_funcs = { + .fdi_link_train = ivb_manual_fdi_link_train, +}; + void intel_fdi_init_hook(struct drm_i915_private *dev_priv) { if (IS_IRONLAKE(dev_priv)) { - dev_priv->fdi_funcs.fdi_link_train = ilk_fdi_link_train; + dev_priv->fdi_funcs = &ilk_funcs; } else if (IS_SANDYBRIDGE(dev_priv)) { - dev_priv->fdi_funcs.fdi_link_train = gen6_fdi_link_train; + dev_priv->fdi_funcs = &gen6_funcs; } else if (IS_IVYBRIDGE(dev_priv)) { /* FIXME: detect B0+ stepping and use auto training */ - dev_priv->fdi_funcs.fdi_link_train = ivb_manual_fdi_link_train; + dev_priv->fdi_funcs = &ivb_funcs; } } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ed2d8b61fe4d..e01fe2199e23 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -991,7 +991,7 @@ struct drm_i915_private { struct intel_hotplug_funcs hotplug_funcs; /* fdi display functions */ - struct intel_fdi_funcs fdi_funcs; + const struct intel_fdi_funcs *fdi_funcs; /* display pll funcs */ struct intel_dpll_funcs dpll_funcs; -- cgit v1.2.3 From cd030c7c11a4afbcc99da4af535d4336e5540767 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:58:00 +0300 Subject: drm/i915: constify hotplug function vtable. Use a macro to avoid mistakes, this type of macro is only used in a couple of places. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/af229c1e8ec894f177b344ab77b90e32c33428de.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_hotplug.c | 4 ++-- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_irq.c | 28 +++++++++++++++++++++------- 3 files changed, 24 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index 05f76aba4f8a..3c1cec953b42 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -215,8 +215,8 @@ intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv) static void intel_hpd_irq_setup(struct drm_i915_private *i915) { - if (i915->display_irqs_enabled && i915->hotplug_funcs.hpd_irq_setup) - i915->hotplug_funcs.hpd_irq_setup(i915); + if (i915->display_irqs_enabled && i915->hotplug_funcs->hpd_irq_setup) + i915->hotplug_funcs->hpd_irq_setup(i915); } static void intel_hpd_irq_storm_reenable_work(struct work_struct *work) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e01fe2199e23..6dcd5153d756 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -988,7 +988,7 @@ struct drm_i915_private { struct drm_i915_wm_disp_funcs wm_disp; /* irq display functions */ - struct intel_hotplug_funcs hotplug_funcs; + const struct intel_hotplug_funcs *hotplug_funcs; /* fdi display functions */ const struct intel_fdi_funcs *fdi_funcs; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c35065f8f429..77680bca46ee 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -4345,6 +4345,20 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) return ret; } +#define HPD_FUNCS(platform) \ +static const struct intel_hotplug_funcs platform##_hpd_funcs = { \ + .hpd_irq_setup = platform##_hpd_irq_setup, \ +} + +HPD_FUNCS(i915); +HPD_FUNCS(dg1); +HPD_FUNCS(gen11); +HPD_FUNCS(bxt); +HPD_FUNCS(icp); +HPD_FUNCS(spt); +HPD_FUNCS(ilk); +#undef HPD_FUNCS + /** * intel_irq_init - initializes irq support * @dev_priv: i915 device instance @@ -4395,20 +4409,20 @@ void intel_irq_init(struct drm_i915_private *dev_priv) if (HAS_GMCH(dev_priv)) { if (I915_HAS_HOTPLUG(dev_priv)) - dev_priv->hotplug_funcs.hpd_irq_setup = i915_hpd_irq_setup; + dev_priv->hotplug_funcs = &i915_hpd_funcs; } else { if (HAS_PCH_DG1(dev_priv)) - dev_priv->hotplug_funcs.hpd_irq_setup = dg1_hpd_irq_setup; + dev_priv->hotplug_funcs = &dg1_hpd_funcs; else if (DISPLAY_VER(dev_priv) >= 11) - dev_priv->hotplug_funcs.hpd_irq_setup = gen11_hpd_irq_setup; + dev_priv->hotplug_funcs = &gen11_hpd_funcs; else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) - dev_priv->hotplug_funcs.hpd_irq_setup = bxt_hpd_irq_setup; + dev_priv->hotplug_funcs = &bxt_hpd_funcs; else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) - dev_priv->hotplug_funcs.hpd_irq_setup = icp_hpd_irq_setup; + dev_priv->hotplug_funcs = &icp_hpd_funcs; else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT) - dev_priv->hotplug_funcs.hpd_irq_setup = spt_hpd_irq_setup; + dev_priv->hotplug_funcs = &spt_hpd_funcs; else - dev_priv->hotplug_funcs.hpd_irq_setup = ilk_hpd_irq_setup; + dev_priv->hotplug_funcs = &ilk_hpd_funcs; } } -- cgit v1.2.3 From c6d27046552e830e64cefb2539dec789186833ec Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:58:01 +0300 Subject: drm/i915: constify color function vtable. This clarifies quite well what functions get used on what platforms instead of having to decipher the old tree. v2: fixed IVB mistake (Jani) Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/49e46e61206d4fdcf08fb5dc1978da3fce702134.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_color.c | 138 +++++++++++++++++++---------- drivers/gpu/drm/i915/i915_drv.h | 2 +- 2 files changed, 93 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index ed79075158dd..f5923f1c38bd 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -1137,14 +1137,14 @@ void intel_color_load_luts(const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); - dev_priv->color_funcs.load_luts(crtc_state); + dev_priv->color_funcs->load_luts(crtc_state); } void intel_color_commit(const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); - dev_priv->color_funcs.color_commit(crtc_state); + dev_priv->color_funcs->color_commit(crtc_state); } static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state) @@ -1200,15 +1200,15 @@ int intel_color_check(struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); - return dev_priv->color_funcs.color_check(crtc_state); + return dev_priv->color_funcs->color_check(crtc_state); } void intel_color_get_config(struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); - if (dev_priv->color_funcs.read_luts) - dev_priv->color_funcs.read_luts(crtc_state); + if (dev_priv->color_funcs->read_luts) + dev_priv->color_funcs->read_luts(crtc_state); } static bool need_plane_update(struct intel_plane *plane, @@ -2092,6 +2092,76 @@ static void icl_read_luts(struct intel_crtc_state *crtc_state) } } +static const struct intel_color_funcs chv_color_funcs = { + .color_check = chv_color_check, + .color_commit = i9xx_color_commit, + .load_luts = chv_load_luts, + .read_luts = chv_read_luts, +}; + +static const struct intel_color_funcs i965_color_funcs = { + .color_check = i9xx_color_check, + .color_commit = i9xx_color_commit, + .load_luts = i965_load_luts, + .read_luts = i965_read_luts, +}; + +static const struct intel_color_funcs i9xx_color_funcs = { + .color_check = i9xx_color_check, + .color_commit = i9xx_color_commit, + .load_luts = i9xx_load_luts, + .read_luts = i9xx_read_luts, +}; + +static const struct intel_color_funcs icl_color_funcs = { + .color_check = icl_color_check, + .color_commit = skl_color_commit, + .load_luts = icl_load_luts, + .read_luts = icl_read_luts, +}; + +static const struct intel_color_funcs glk_color_funcs = { + .color_check = glk_color_check, + .color_commit = skl_color_commit, + .load_luts = glk_load_luts, + .read_luts = glk_read_luts, +}; + +static const struct intel_color_funcs skl_color_funcs = { + .color_check = ivb_color_check, + .color_commit = skl_color_commit, + .load_luts = bdw_load_luts, + .read_luts = NULL, +}; + +static const struct intel_color_funcs bdw_color_funcs = { + .color_check = ivb_color_check, + .color_commit = hsw_color_commit, + .load_luts = bdw_load_luts, + .read_luts = NULL, +}; + +static const struct intel_color_funcs hsw_color_funcs = { + .color_check = ivb_color_check, + .color_commit = hsw_color_commit, + .load_luts = ivb_load_luts, + .read_luts = NULL, +}; + +static const struct intel_color_funcs ivb_color_funcs = { + .color_check = ivb_color_check, + .color_commit = ilk_color_commit, + .load_luts = ivb_load_luts, + .read_luts = NULL, +}; + +static const struct intel_color_funcs ilk_color_funcs = { + .color_check = ilk_color_check, + .color_commit = ilk_color_commit, + .load_luts = ilk_load_luts, + .read_luts = ilk_read_luts, +}; + void intel_color_init(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -2101,52 +2171,28 @@ void intel_color_init(struct intel_crtc *crtc) if (HAS_GMCH(dev_priv)) { if (IS_CHERRYVIEW(dev_priv)) { - dev_priv->color_funcs.color_check = chv_color_check; - dev_priv->color_funcs.color_commit = i9xx_color_commit; - dev_priv->color_funcs.load_luts = chv_load_luts; - dev_priv->color_funcs.read_luts = chv_read_luts; + dev_priv->color_funcs = &chv_color_funcs; } else if (DISPLAY_VER(dev_priv) >= 4) { - dev_priv->color_funcs.color_check = i9xx_color_check; - dev_priv->color_funcs.color_commit = i9xx_color_commit; - dev_priv->color_funcs.load_luts = i965_load_luts; - dev_priv->color_funcs.read_luts = i965_read_luts; + dev_priv->color_funcs = &i965_color_funcs; } else { - dev_priv->color_funcs.color_check = i9xx_color_check; - dev_priv->color_funcs.color_commit = i9xx_color_commit; - dev_priv->color_funcs.load_luts = i9xx_load_luts; - dev_priv->color_funcs.read_luts = i9xx_read_luts; + dev_priv->color_funcs = &i9xx_color_funcs; } } else { if (DISPLAY_VER(dev_priv) >= 11) - dev_priv->color_funcs.color_check = icl_color_check; - else if (DISPLAY_VER(dev_priv) >= 10) - dev_priv->color_funcs.color_check = glk_color_check; - else if (DISPLAY_VER(dev_priv) >= 7) - dev_priv->color_funcs.color_check = ivb_color_check; - else - dev_priv->color_funcs.color_check = ilk_color_check; - - if (DISPLAY_VER(dev_priv) >= 9) - dev_priv->color_funcs.color_commit = skl_color_commit; - else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) - dev_priv->color_funcs.color_commit = hsw_color_commit; - else - dev_priv->color_funcs.color_commit = ilk_color_commit; - - if (DISPLAY_VER(dev_priv) >= 11) { - dev_priv->color_funcs.load_luts = icl_load_luts; - dev_priv->color_funcs.read_luts = icl_read_luts; - } else if (DISPLAY_VER(dev_priv) == 10) { - dev_priv->color_funcs.load_luts = glk_load_luts; - dev_priv->color_funcs.read_luts = glk_read_luts; - } else if (DISPLAY_VER(dev_priv) >= 8) { - dev_priv->color_funcs.load_luts = bdw_load_luts; - } else if (DISPLAY_VER(dev_priv) >= 7) { - dev_priv->color_funcs.load_luts = ivb_load_luts; - } else { - dev_priv->color_funcs.load_luts = ilk_load_luts; - dev_priv->color_funcs.read_luts = ilk_read_luts; - } + dev_priv->color_funcs = &icl_color_funcs; + else if (DISPLAY_VER(dev_priv) == 10) + dev_priv->color_funcs = &glk_color_funcs; + else if (DISPLAY_VER(dev_priv) == 9) + dev_priv->color_funcs = &skl_color_funcs; + else if (DISPLAY_VER(dev_priv) == 8) + dev_priv->color_funcs = &bdw_color_funcs; + else if (DISPLAY_VER(dev_priv) == 7) { + if (IS_HASWELL(dev_priv)) + dev_priv->color_funcs = &hsw_color_funcs; + else + dev_priv->color_funcs = &ivb_color_funcs; + } else + dev_priv->color_funcs = &ilk_color_funcs; } drm_crtc_enable_color_mgmt(&crtc->base, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6dcd5153d756..996855d498ec 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1000,7 +1000,7 @@ struct drm_i915_private { struct drm_i915_display_funcs display; /* Display internal color functions */ - struct intel_color_funcs color_funcs; + const struct intel_color_funcs *color_funcs; /* Display internal audio functions */ struct intel_audio_funcs audio_funcs; -- cgit v1.2.3 From 0a108bca94a8280ddfe2a87ad6b4173db6f0a454 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:58:02 +0300 Subject: drm/i915: constify the audio function vtable Move the functions into read-only tables. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/5a481307a5daab40a506c3b9a64b0b37e01a1a41.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_audio.c | 43 +++++++++++++++++++----------- drivers/gpu/drm/i915/i915_drv.h | 2 +- 2 files changed, 28 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index bf96d1529775..03e8c05a74f6 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -848,10 +848,10 @@ void intel_audio_codec_enable(struct intel_encoder *encoder, connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2; - if (dev_priv->audio_funcs.audio_codec_enable) - dev_priv->audio_funcs.audio_codec_enable(encoder, - crtc_state, - conn_state); + if (dev_priv->audio_funcs) + dev_priv->audio_funcs->audio_codec_enable(encoder, + crtc_state, + conn_state); mutex_lock(&dev_priv->av_mutex); encoder->audio_connector = connector; @@ -893,10 +893,10 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, enum port port = encoder->port; enum pipe pipe = crtc->pipe; - if (dev_priv->audio_funcs.audio_codec_disable) - dev_priv->audio_funcs.audio_codec_disable(encoder, - old_crtc_state, - old_conn_state); + if (dev_priv->audio_funcs) + dev_priv->audio_funcs->audio_codec_disable(encoder, + old_crtc_state, + old_conn_state); mutex_lock(&dev_priv->av_mutex); encoder->audio_connector = NULL; @@ -915,6 +915,21 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, intel_lpe_audio_notify(dev_priv, pipe, port, NULL, 0, false); } +static const struct intel_audio_funcs g4x_audio_funcs = { + .audio_codec_enable = g4x_audio_codec_enable, + .audio_codec_disable = g4x_audio_codec_disable, +}; + +static const struct intel_audio_funcs ilk_audio_funcs = { + .audio_codec_enable = ilk_audio_codec_enable, + .audio_codec_disable = ilk_audio_codec_disable, +}; + +static const struct intel_audio_funcs hsw_audio_funcs = { + .audio_codec_enable = hsw_audio_codec_enable, + .audio_codec_disable = hsw_audio_codec_disable, +}; + /** * intel_init_audio_hooks - Set up chip specific audio hooks * @dev_priv: device private @@ -922,17 +937,13 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, void intel_init_audio_hooks(struct drm_i915_private *dev_priv) { if (IS_G4X(dev_priv)) { - dev_priv->audio_funcs.audio_codec_enable = g4x_audio_codec_enable; - dev_priv->audio_funcs.audio_codec_disable = g4x_audio_codec_disable; + dev_priv->audio_funcs = &g4x_audio_funcs; } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - dev_priv->audio_funcs.audio_codec_enable = ilk_audio_codec_enable; - dev_priv->audio_funcs.audio_codec_disable = ilk_audio_codec_disable; + dev_priv->audio_funcs = &ilk_audio_funcs; } else if (IS_HASWELL(dev_priv) || DISPLAY_VER(dev_priv) >= 8) { - dev_priv->audio_funcs.audio_codec_enable = hsw_audio_codec_enable; - dev_priv->audio_funcs.audio_codec_disable = hsw_audio_codec_disable; + dev_priv->audio_funcs = &hsw_audio_funcs; } else if (HAS_PCH_SPLIT(dev_priv)) { - dev_priv->audio_funcs.audio_codec_enable = ilk_audio_codec_enable; - dev_priv->audio_funcs.audio_codec_disable = ilk_audio_codec_disable; + dev_priv->audio_funcs = &ilk_audio_funcs; } } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 996855d498ec..c3ec5271869e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1003,7 +1003,7 @@ struct drm_i915_private { const struct intel_color_funcs *color_funcs; /* Display internal audio functions */ - struct intel_audio_funcs audio_funcs; + const struct intel_audio_funcs *audio_funcs; /* Display CDCLK functions */ struct intel_cdclk_funcs cdclk_funcs; -- cgit v1.2.3 From a73477f8813cc9feedb7227cb9a382ef35212100 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:58:03 +0300 Subject: drm/i915: constify the dpll clock vtable Most the dpll vtable into read-only memory. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/0414a27317de3f335a8453a29486b746aa6862e7.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 6 ++-- drivers/gpu/drm/i915/display/intel_dpll.c | 48 +++++++++++++++++++++++----- drivers/gpu/drm/i915/i915_drv.h | 2 +- 3 files changed, 44 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 146281bfec59..9c72f1c5e96f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6833,10 +6833,10 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state, crtc_state->update_wm_post = true; if (mode_changed && crtc_state->hw.enable && - dev_priv->dpll_funcs.crtc_compute_clock && + dev_priv->dpll_funcs && !crtc_state->bigjoiner_slave && !drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll)) { - ret = dev_priv->dpll_funcs.crtc_compute_clock(crtc_state); + ret = dev_priv->dpll_funcs->crtc_compute_clock(crtc_state); if (ret) return ret; } @@ -8863,7 +8863,7 @@ static void intel_modeset_clear_plls(struct intel_atomic_state *state) struct intel_crtc *crtc; int i; - if (!dev_priv->dpll_funcs.crtc_compute_clock) + if (!dev_priv->dpll_funcs) return; for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 7811f19acb6a..784e3ee658b5 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -1365,25 +1365,57 @@ static int i8xx_crtc_compute_clock(struct intel_crtc_state *crtc_state) return 0; } +static const struct intel_dpll_funcs hsw_dpll_funcs = { + .crtc_compute_clock = hsw_crtc_compute_clock, +}; + +static const struct intel_dpll_funcs ilk_dpll_funcs = { + .crtc_compute_clock = ilk_crtc_compute_clock, +}; + +static const struct intel_dpll_funcs chv_dpll_funcs = { + .crtc_compute_clock = chv_crtc_compute_clock, +}; + +static const struct intel_dpll_funcs vlv_dpll_funcs = { + .crtc_compute_clock = vlv_crtc_compute_clock, +}; + +static const struct intel_dpll_funcs g4x_dpll_funcs = { + .crtc_compute_clock = g4x_crtc_compute_clock, +}; + +static const struct intel_dpll_funcs pnv_dpll_funcs = { + .crtc_compute_clock = pnv_crtc_compute_clock, +}; + +static const struct intel_dpll_funcs i9xx_dpll_funcs = { + .crtc_compute_clock = i9xx_crtc_compute_clock, +}; + +static const struct intel_dpll_funcs i8xx_dpll_funcs = { + .crtc_compute_clock = i8xx_crtc_compute_clock, +}; + void intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv) { if (DISPLAY_VER(dev_priv) >= 9 || HAS_DDI(dev_priv)) - dev_priv->dpll_funcs.crtc_compute_clock = hsw_crtc_compute_clock; + dev_priv->dpll_funcs = &hsw_dpll_funcs; else if (HAS_PCH_SPLIT(dev_priv)) - dev_priv->dpll_funcs.crtc_compute_clock = ilk_crtc_compute_clock; + dev_priv->dpll_funcs = &ilk_dpll_funcs; else if (IS_CHERRYVIEW(dev_priv)) - dev_priv->dpll_funcs.crtc_compute_clock = chv_crtc_compute_clock; + dev_priv->dpll_funcs = &chv_dpll_funcs; else if (IS_VALLEYVIEW(dev_priv)) - dev_priv->dpll_funcs.crtc_compute_clock = vlv_crtc_compute_clock; + dev_priv->dpll_funcs = &vlv_dpll_funcs; else if (IS_G4X(dev_priv)) - dev_priv->dpll_funcs.crtc_compute_clock = g4x_crtc_compute_clock; + dev_priv->dpll_funcs = &g4x_dpll_funcs; else if (IS_PINEVIEW(dev_priv)) - dev_priv->dpll_funcs.crtc_compute_clock = pnv_crtc_compute_clock; + dev_priv->dpll_funcs = &pnv_dpll_funcs; else if (DISPLAY_VER(dev_priv) != 2) - dev_priv->dpll_funcs.crtc_compute_clock = i9xx_crtc_compute_clock; + dev_priv->dpll_funcs = &i9xx_dpll_funcs; else - dev_priv->dpll_funcs.crtc_compute_clock = i8xx_crtc_compute_clock; + dev_priv->dpll_funcs = &i8xx_dpll_funcs; } static bool i9xx_has_pps(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c3ec5271869e..cb72e2fe5417 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -994,7 +994,7 @@ struct drm_i915_private { const struct intel_fdi_funcs *fdi_funcs; /* display pll funcs */ - struct intel_dpll_funcs dpll_funcs; + const struct intel_dpll_funcs *dpll_funcs; /* Display functions */ struct drm_i915_display_funcs display; -- cgit v1.2.3 From 6b4cd9cba6208bd879e05ad7171f95bf9389bc98 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:58:04 +0300 Subject: drm/i915: constify the cdclk vtable This is a bit of a twisty one since each platform is slightly different, so might take some more review care. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/75e0139b28cca9ceff77de72c3ef737c101255ba.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_cdclk.c | 300 ++++++++++++++++++++--------- drivers/gpu/drm/i915/i915_drv.h | 2 +- 2 files changed, 206 insertions(+), 96 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index cf0a865df596..ecb28e8f1eb6 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -62,32 +62,32 @@ void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv, struct intel_cdclk_config *cdclk_config) { - dev_priv->cdclk_funcs.get_cdclk(dev_priv, cdclk_config); + dev_priv->cdclk_funcs->get_cdclk(dev_priv, cdclk_config); } int intel_cdclk_bw_calc_min_cdclk(struct intel_atomic_state *state) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - return dev_priv->cdclk_funcs.bw_calc_min_cdclk(state); + return dev_priv->cdclk_funcs->bw_calc_min_cdclk(state); } static void intel_cdclk_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { - dev_priv->cdclk_funcs.set_cdclk(dev_priv, cdclk_config, pipe); + dev_priv->cdclk_funcs->set_cdclk(dev_priv, cdclk_config, pipe); } static int intel_cdclk_modeset_calc_cdclk(struct drm_i915_private *dev_priv, struct intel_cdclk_state *cdclk_config) { - return dev_priv->cdclk_funcs.modeset_calc_cdclk(cdclk_config); + return dev_priv->cdclk_funcs->modeset_calc_cdclk(cdclk_config); } static u8 intel_cdclk_calc_voltage_level(struct drm_i915_private *dev_priv, int cdclk) { - return dev_priv->cdclk_funcs.calc_voltage_level(cdclk); + return dev_priv->cdclk_funcs->calc_voltage_level(cdclk); } static void fixed_133mhz_get_cdclk(struct drm_i915_private *dev_priv, @@ -1963,7 +1963,7 @@ static void intel_set_cdclk(struct drm_i915_private *dev_priv, if (!intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_config)) return; - if (drm_WARN_ON_ONCE(&dev_priv->drm, !dev_priv->cdclk_funcs.set_cdclk)) + if (drm_WARN_ON_ONCE(&dev_priv->drm, !dev_priv->cdclk_funcs->set_cdclk)) return; intel_dump_cdclk_config(cdclk_config, "Changing CDCLK to"); @@ -2884,6 +2884,157 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) return freq; } +static struct intel_cdclk_funcs tgl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .bw_calc_min_cdclk = skl_bw_calc_min_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = tgl_calc_voltage_level, +}; + +static struct intel_cdclk_funcs ehl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .bw_calc_min_cdclk = skl_bw_calc_min_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = ehl_calc_voltage_level, +}; + +static struct intel_cdclk_funcs icl_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .bw_calc_min_cdclk = skl_bw_calc_min_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = icl_calc_voltage_level, +}; + +static struct intel_cdclk_funcs bxt_cdclk_funcs = { + .get_cdclk = bxt_get_cdclk, + .set_cdclk = bxt_set_cdclk, + .bw_calc_min_cdclk = skl_bw_calc_min_cdclk, + .modeset_calc_cdclk = bxt_modeset_calc_cdclk, + .calc_voltage_level = bxt_calc_voltage_level, +}; + +static struct intel_cdclk_funcs skl_cdclk_funcs = { + .get_cdclk = skl_get_cdclk, + .set_cdclk = skl_set_cdclk, + .bw_calc_min_cdclk = skl_bw_calc_min_cdclk, + .modeset_calc_cdclk = skl_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs bdw_cdclk_funcs = { + .get_cdclk = bdw_get_cdclk, + .set_cdclk = bdw_set_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = bdw_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs chv_cdclk_funcs = { + .get_cdclk = vlv_get_cdclk, + .set_cdclk = chv_set_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = vlv_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs vlv_cdclk_funcs = { + .get_cdclk = vlv_get_cdclk, + .set_cdclk = vlv_set_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = vlv_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs hsw_cdclk_funcs = { + .get_cdclk = hsw_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +/* SNB, IVB, 965G, 945G */ +static struct intel_cdclk_funcs fixed_400mhz_cdclk_funcs = { + .get_cdclk = fixed_400mhz_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs ilk_cdclk_funcs = { + .get_cdclk = fixed_450mhz_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs gm45_cdclk_funcs = { + .get_cdclk = gm45_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +/* G45 uses G33 */ + +static struct intel_cdclk_funcs i965gm_cdclk_funcs = { + .get_cdclk = i965gm_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +/* i965G uses fixed 400 */ + +static struct intel_cdclk_funcs pnv_cdclk_funcs = { + .get_cdclk = pnv_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs g33_cdclk_funcs = { + .get_cdclk = g33_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs i945gm_cdclk_funcs = { + .get_cdclk = i945gm_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +/* i945G uses fixed 400 */ + +static struct intel_cdclk_funcs i915gm_cdclk_funcs = { + .get_cdclk = i915gm_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs i915g_cdclk_funcs = { + .get_cdclk = fixed_333mhz_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs i865g_cdclk_funcs = { + .get_cdclk = fixed_266mhz_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs i85x_cdclk_funcs = { + .get_cdclk = i85x_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs i845g_cdclk_funcs = { + .get_cdclk = fixed_200mhz_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + +static struct intel_cdclk_funcs i830_cdclk_funcs = { + .get_cdclk = fixed_133mhz_get_cdclk, + .bw_calc_min_cdclk = intel_bw_calc_min_cdclk, + .modeset_calc_cdclk = fixed_modeset_calc_cdclk, +}; + /** * intel_init_cdclk_hooks - Initialize CDCLK related modesetting hooks * @dev_priv: i915 device @@ -2891,119 +3042,78 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv) void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) { if (IS_DG2(dev_priv)) { - dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; - dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->cdclk_funcs.calc_voltage_level = tgl_calc_voltage_level; + dev_priv->cdclk_funcs = &tgl_cdclk_funcs; dev_priv->cdclk.table = dg2_cdclk_table; } else if (IS_ALDERLAKE_P(dev_priv)) { - dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; - dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->cdclk_funcs.calc_voltage_level = tgl_calc_voltage_level; + dev_priv->cdclk_funcs = &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; else dev_priv->cdclk.table = adlp_cdclk_table; } else if (IS_ROCKETLAKE(dev_priv)) { - dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; - dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->cdclk_funcs.calc_voltage_level = tgl_calc_voltage_level; + dev_priv->cdclk_funcs = &tgl_cdclk_funcs; dev_priv->cdclk.table = rkl_cdclk_table; } else if (DISPLAY_VER(dev_priv) >= 12) { - dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; - dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->cdclk_funcs.calc_voltage_level = tgl_calc_voltage_level; + dev_priv->cdclk_funcs = &tgl_cdclk_funcs; dev_priv->cdclk.table = icl_cdclk_table; } else if (IS_JSL_EHL(dev_priv)) { - dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; - dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->cdclk_funcs.calc_voltage_level = ehl_calc_voltage_level; + dev_priv->cdclk_funcs = &ehl_cdclk_funcs; dev_priv->cdclk.table = icl_cdclk_table; } else if (DISPLAY_VER(dev_priv) >= 11) { - dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; - dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->cdclk_funcs.calc_voltage_level = icl_calc_voltage_level; + dev_priv->cdclk_funcs = &icl_cdclk_funcs; dev_priv->cdclk.table = icl_cdclk_table; } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { - dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->cdclk_funcs.set_cdclk = bxt_set_cdclk; - dev_priv->cdclk_funcs.modeset_calc_cdclk = bxt_modeset_calc_cdclk; - dev_priv->cdclk_funcs.calc_voltage_level = bxt_calc_voltage_level; + dev_priv->cdclk_funcs = &bxt_cdclk_funcs; if (IS_GEMINILAKE(dev_priv)) dev_priv->cdclk.table = glk_cdclk_table; else dev_priv->cdclk.table = bxt_cdclk_table; } else if (DISPLAY_VER(dev_priv) == 9) { - dev_priv->cdclk_funcs.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; - dev_priv->cdclk_funcs.set_cdclk = skl_set_cdclk; - dev_priv->cdclk_funcs.modeset_calc_cdclk = skl_modeset_calc_cdclk; + dev_priv->cdclk_funcs = &skl_cdclk_funcs; } else if (IS_BROADWELL(dev_priv)) { - dev_priv->cdclk_funcs.bw_calc_min_cdclk = intel_bw_calc_min_cdclk; - dev_priv->cdclk_funcs.set_cdclk = bdw_set_cdclk; - dev_priv->cdclk_funcs.modeset_calc_cdclk = bdw_modeset_calc_cdclk; + dev_priv->cdclk_funcs = &bdw_cdclk_funcs; + } else if (IS_HASWELL(dev_priv)) { + dev_priv->cdclk_funcs = &hsw_cdclk_funcs; } else if (IS_CHERRYVIEW(dev_priv)) { - dev_priv->cdclk_funcs.bw_calc_min_cdclk = intel_bw_calc_min_cdclk; - dev_priv->cdclk_funcs.set_cdclk = chv_set_cdclk; - dev_priv->cdclk_funcs.modeset_calc_cdclk = vlv_modeset_calc_cdclk; + dev_priv->cdclk_funcs = &chv_cdclk_funcs; } else if (IS_VALLEYVIEW(dev_priv)) { - dev_priv->cdclk_funcs.bw_calc_min_cdclk = intel_bw_calc_min_cdclk; - dev_priv->cdclk_funcs.set_cdclk = vlv_set_cdclk; - dev_priv->cdclk_funcs.modeset_calc_cdclk = vlv_modeset_calc_cdclk; - } else { - dev_priv->cdclk_funcs.bw_calc_min_cdclk = intel_bw_calc_min_cdclk; - dev_priv->cdclk_funcs.modeset_calc_cdclk = fixed_modeset_calc_cdclk; + dev_priv->cdclk_funcs = &vlv_cdclk_funcs; + } else if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) { + dev_priv->cdclk_funcs = &fixed_400mhz_cdclk_funcs; + } else if (IS_IRONLAKE(dev_priv)) { + dev_priv->cdclk_funcs = &ilk_cdclk_funcs; + } else if (IS_GM45(dev_priv)) { + dev_priv->cdclk_funcs = &gm45_cdclk_funcs; + } else if (IS_G45(dev_priv)) { + dev_priv->cdclk_funcs = &g33_cdclk_funcs; + } else if (IS_I965GM(dev_priv)) { + dev_priv->cdclk_funcs = &i965gm_cdclk_funcs; + } else if (IS_I965G(dev_priv)) { + dev_priv->cdclk_funcs = &fixed_400mhz_cdclk_funcs; + } else if (IS_PINEVIEW(dev_priv)) { + dev_priv->cdclk_funcs = &pnv_cdclk_funcs; + } else if (IS_G33(dev_priv)) { + dev_priv->cdclk_funcs = &g33_cdclk_funcs; + } else if (IS_I945GM(dev_priv)) { + dev_priv->cdclk_funcs = &i945gm_cdclk_funcs; + } else if (IS_I945G(dev_priv)) { + dev_priv->cdclk_funcs = &fixed_400mhz_cdclk_funcs; + } else if (IS_I915GM(dev_priv)) { + dev_priv->cdclk_funcs = &i915gm_cdclk_funcs; + } else if (IS_I915G(dev_priv)) { + dev_priv->cdclk_funcs = &i915g_cdclk_funcs; + } else if (IS_I865G(dev_priv)) { + dev_priv->cdclk_funcs = &i865g_cdclk_funcs; + } else if (IS_I85X(dev_priv)) { + dev_priv->cdclk_funcs = &i85x_cdclk_funcs; + } else if (IS_I845G(dev_priv)) { + dev_priv->cdclk_funcs = &i845g_cdclk_funcs; + } else if (IS_I830(dev_priv)) { + dev_priv->cdclk_funcs = &i830_cdclk_funcs; } - if (DISPLAY_VER(dev_priv) >= 10 || IS_BROXTON(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = bxt_get_cdclk; - else if (DISPLAY_VER(dev_priv) == 9) - dev_priv->cdclk_funcs.get_cdclk = skl_get_cdclk; - else if (IS_BROADWELL(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = bdw_get_cdclk; - else if (IS_HASWELL(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = hsw_get_cdclk; - else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = vlv_get_cdclk; - else if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = fixed_400mhz_get_cdclk; - else if (IS_IRONLAKE(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = fixed_450mhz_get_cdclk; - else if (IS_GM45(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = gm45_get_cdclk; - else if (IS_G45(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = g33_get_cdclk; - else if (IS_I965GM(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = i965gm_get_cdclk; - else if (IS_I965G(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = fixed_400mhz_get_cdclk; - else if (IS_PINEVIEW(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = pnv_get_cdclk; - else if (IS_G33(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = g33_get_cdclk; - else if (IS_I945GM(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = i945gm_get_cdclk; - else if (IS_I945G(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = fixed_400mhz_get_cdclk; - else if (IS_I915GM(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = i915gm_get_cdclk; - else if (IS_I915G(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = fixed_333mhz_get_cdclk; - else if (IS_I865G(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = fixed_266mhz_get_cdclk; - else if (IS_I85X(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = i85x_get_cdclk; - else if (IS_I845G(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = fixed_200mhz_get_cdclk; - else if (IS_I830(dev_priv)) - dev_priv->cdclk_funcs.get_cdclk = fixed_133mhz_get_cdclk; - - if (drm_WARN(&dev_priv->drm, !dev_priv->cdclk_funcs.get_cdclk, - "Unknown platform. Assuming 133 MHz CDCLK\n")) - dev_priv->cdclk_funcs.get_cdclk = fixed_133mhz_get_cdclk; + if (drm_WARN(&dev_priv->drm, !dev_priv->cdclk_funcs, + "Unknown platform. Assuming i830\n")) + dev_priv->cdclk_funcs = &i830_cdclk_funcs; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cb72e2fe5417..67638b4327f9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1006,7 +1006,7 @@ struct drm_i915_private { const struct intel_audio_funcs *audio_funcs; /* Display CDCLK functions */ - struct intel_cdclk_funcs cdclk_funcs; + const struct intel_cdclk_funcs *cdclk_funcs; /* PCH chipset type */ enum intel_pch pch_type; -- cgit v1.2.3 From cbc7617af0c194c35eebd08ca03dc98e2e8cfcb5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:58:05 +0300 Subject: drm/i915: drop unused function ptr and comments. There was some excess comments and an unused vtbl ptr. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/573a9366d33e2b7bd7b8215af614f03f3e562926.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 67638b4327f9..9c768ec57ce4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -409,13 +409,6 @@ struct drm_i915_display_funcs { void (*crtc_disable)(struct intel_atomic_state *state, struct intel_crtc *crtc); void (*commit_modeset_enables)(struct intel_atomic_state *state); - void (*commit_modeset_disables)(struct intel_atomic_state *state); - - /* clock updates for mode set */ - /* cursor updates */ - /* render clock increase/decrease */ - /* display clock increase/decrease */ - /* pll clock increase/decrease */ }; -- cgit v1.2.3 From d28c2f5c2383bddc0a277a9a8455dd2920a9b9ab Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:58:06 +0300 Subject: drm/i915: constify display function vtable Make nice clear tables instead of having things in two places. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/d0f7e2c792dc40804555d26b6ede62f4bd2f23d6.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 81 +++++++++++++++++----------- drivers/gpu/drm/i915/i915_drv.h | 2 +- 2 files changed, 52 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9c72f1c5e96f..e7ac92994abf 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3797,7 +3797,7 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc, drm_WARN_ON(&dev_priv->drm, IS_ERR(temp_crtc_state) || ret); - dev_priv->display.crtc_disable(to_intel_atomic_state(state), crtc); + dev_priv->display->crtc_disable(to_intel_atomic_state(state), crtc); drm_atomic_state_put(state); @@ -6006,7 +6006,7 @@ static bool intel_crtc_get_pipe_config(struct intel_crtc_state *crtc_state) struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); - if (!i915->display.get_pipe_config(crtc, crtc_state)) + if (!i915->display->get_pipe_config(crtc, crtc_state)) return false; crtc_state->hw.active = true; @@ -9816,7 +9816,7 @@ static void intel_enable_crtc(struct intel_atomic_state *state, intel_crtc_update_active_timings(new_crtc_state); - dev_priv->display.crtc_enable(state, crtc); + dev_priv->display->crtc_enable(state, crtc); if (new_crtc_state->bigjoiner_slave) return; @@ -9904,7 +9904,7 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state, */ intel_crtc_disable_pipe_crc(crtc); - dev_priv->display.crtc_disable(state, crtc); + dev_priv->display->crtc_disable(state, crtc); crtc->active = false; intel_fbc_disable(crtc); intel_disable_shared_dpll(old_crtc_state); @@ -10284,7 +10284,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) } /* Now enable the clocks, plane, pipe, and connectors that we set up. */ - dev_priv->display.commit_modeset_enables(state); + dev_priv->display->commit_modeset_enables(state); if (state->modeset) { intel_encoders_update_complete(state); @@ -11288,6 +11288,46 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { .atomic_state_free = intel_atomic_state_free, }; +static const struct drm_i915_display_funcs skl_display_funcs = { + .get_pipe_config = hsw_get_pipe_config, + .crtc_enable = hsw_crtc_enable, + .crtc_disable = hsw_crtc_disable, + .commit_modeset_enables = skl_commit_modeset_enables, + .get_initial_plane_config = skl_get_initial_plane_config, +}; + +static const struct drm_i915_display_funcs ddi_display_funcs = { + .get_pipe_config = hsw_get_pipe_config, + .crtc_enable = hsw_crtc_enable, + .crtc_disable = hsw_crtc_disable, + .commit_modeset_enables = intel_commit_modeset_enables, + .get_initial_plane_config = i9xx_get_initial_plane_config, +}; + +static const struct drm_i915_display_funcs pch_split_display_funcs = { + .get_pipe_config = ilk_get_pipe_config, + .crtc_enable = ilk_crtc_enable, + .crtc_disable = ilk_crtc_disable, + .commit_modeset_enables = intel_commit_modeset_enables, + .get_initial_plane_config = i9xx_get_initial_plane_config, +}; + +static const struct drm_i915_display_funcs vlv_display_funcs = { + .get_pipe_config = i9xx_get_pipe_config, + .crtc_enable = valleyview_crtc_enable, + .crtc_disable = i9xx_crtc_disable, + .commit_modeset_enables = intel_commit_modeset_enables, + .get_initial_plane_config = i9xx_get_initial_plane_config, +}; + +static const struct drm_i915_display_funcs i9xx_display_funcs = { + .get_pipe_config = i9xx_get_pipe_config, + .crtc_enable = i9xx_crtc_enable, + .crtc_disable = i9xx_crtc_disable, + .commit_modeset_enables = intel_commit_modeset_enables, + .get_initial_plane_config = i9xx_get_initial_plane_config, +}; + /** * intel_init_display_hooks - initialize the display modesetting hooks * @dev_priv: device private @@ -11303,38 +11343,19 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) intel_dpll_init_clock_hook(dev_priv); if (DISPLAY_VER(dev_priv) >= 9) { - dev_priv->display.get_pipe_config = hsw_get_pipe_config; - dev_priv->display.crtc_enable = hsw_crtc_enable; - dev_priv->display.crtc_disable = hsw_crtc_disable; + dev_priv->display = &skl_display_funcs; } else if (HAS_DDI(dev_priv)) { - dev_priv->display.get_pipe_config = hsw_get_pipe_config; - dev_priv->display.crtc_enable = hsw_crtc_enable; - dev_priv->display.crtc_disable = hsw_crtc_disable; + dev_priv->display = &ddi_display_funcs; } else if (HAS_PCH_SPLIT(dev_priv)) { - dev_priv->display.get_pipe_config = ilk_get_pipe_config; - dev_priv->display.crtc_enable = ilk_crtc_enable; - dev_priv->display.crtc_disable = ilk_crtc_disable; + dev_priv->display = &pch_split_display_funcs; } else if (IS_CHERRYVIEW(dev_priv) || IS_VALLEYVIEW(dev_priv)) { - dev_priv->display.get_pipe_config = i9xx_get_pipe_config; - dev_priv->display.crtc_enable = valleyview_crtc_enable; - dev_priv->display.crtc_disable = i9xx_crtc_disable; + dev_priv->display = &vlv_display_funcs; } else { - dev_priv->display.get_pipe_config = i9xx_get_pipe_config; - dev_priv->display.crtc_enable = i9xx_crtc_enable; - dev_priv->display.crtc_disable = i9xx_crtc_disable; + dev_priv->display = &i9xx_display_funcs; } intel_fdi_init_hook(dev_priv); - - if (DISPLAY_VER(dev_priv) >= 9) { - dev_priv->display.commit_modeset_enables = skl_commit_modeset_enables; - dev_priv->display.get_initial_plane_config = skl_get_initial_plane_config; - } else { - dev_priv->display.commit_modeset_enables = intel_commit_modeset_enables; - dev_priv->display.get_initial_plane_config = i9xx_get_initial_plane_config; - } - } void intel_modeset_init_hw(struct drm_i915_private *i915) @@ -11762,7 +11783,7 @@ int intel_modeset_init_nogem(struct drm_i915_private *i915) * can even allow for smooth boot transitions if the BIOS * fb is large enough for the active pipe configuration. */ - i915->display.get_initial_plane_config(crtc, &plane_config); + i915->display->get_initial_plane_config(crtc, &plane_config); /* * If the fb is shared between multiple heads, we'll diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9c768ec57ce4..dd0d996972f5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -990,7 +990,7 @@ struct drm_i915_private { const struct intel_dpll_funcs *dpll_funcs; /* Display functions */ - struct drm_i915_display_funcs display; + const struct drm_i915_display_funcs *display; /* Display internal color functions */ const struct intel_color_funcs *color_funcs; -- cgit v1.2.3 From eba4b7960f22f57750711aded092afd2b95d3b33 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:58:07 +0300 Subject: drm/i915: constify clock gating init vtable. I used a macro to avoid making any really silly mistakes here. Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/7c97f7e5ab0eae3c4cd7ce8344254356c34f3ad6.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_pm.c | 78 ++++++++++++++++++++++++++++------------- 2 files changed, 55 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index dd0d996972f5..4e28645c73c6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -975,7 +975,7 @@ struct drm_i915_private { struct workqueue_struct *flip_wq; /* pm private clock gating functions */ - struct drm_i915_clock_gating_funcs clock_gating_funcs; + const struct drm_i915_clock_gating_funcs *clock_gating_funcs; /* pm display functions */ struct drm_i915_wm_disp_funcs wm_disp; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b37888781ec9..08e0195edeb7 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7869,7 +7869,7 @@ static void i830_init_clock_gating(struct drm_i915_private *dev_priv) void intel_init_clock_gating(struct drm_i915_private *dev_priv) { - dev_priv->clock_gating_funcs.init_clock_gating(dev_priv); + dev_priv->clock_gating_funcs->init_clock_gating(dev_priv); } void intel_suspend_hw(struct drm_i915_private *dev_priv) @@ -7884,6 +7884,36 @@ static void nop_init_clock_gating(struct drm_i915_private *dev_priv) "No clock gating settings or workarounds applied.\n"); } +#define CG_FUNCS(platform) \ +static const struct drm_i915_clock_gating_funcs platform##_clock_gating_funcs = { \ + .init_clock_gating = platform##_init_clock_gating, \ +} + +CG_FUNCS(adlp); +CG_FUNCS(dg1); +CG_FUNCS(gen12lp); +CG_FUNCS(icl); +CG_FUNCS(cfl); +CG_FUNCS(skl); +CG_FUNCS(kbl); +CG_FUNCS(bxt); +CG_FUNCS(glk); +CG_FUNCS(bdw); +CG_FUNCS(chv); +CG_FUNCS(hsw); +CG_FUNCS(ivb); +CG_FUNCS(vlv); +CG_FUNCS(gen6); +CG_FUNCS(ilk); +CG_FUNCS(g4x); +CG_FUNCS(i965gm); +CG_FUNCS(i965g); +CG_FUNCS(gen3); +CG_FUNCS(i85x); +CG_FUNCS(i830); +CG_FUNCS(nop); +#undef CG_FUNCS + /** * intel_init_clock_gating_hooks - setup the clock gating hooks * @dev_priv: device private @@ -7896,52 +7926,52 @@ static void nop_init_clock_gating(struct drm_i915_private *dev_priv) void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) { if (IS_ALDERLAKE_P(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = adlp_init_clock_gating; + dev_priv->clock_gating_funcs = &adlp_clock_gating_funcs; else if (IS_DG1(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = dg1_init_clock_gating; + dev_priv->clock_gating_funcs = &dg1_clock_gating_funcs; else if (GRAPHICS_VER(dev_priv) == 12) - dev_priv->clock_gating_funcs.init_clock_gating = gen12lp_init_clock_gating; + dev_priv->clock_gating_funcs = &gen12lp_clock_gating_funcs; else if (GRAPHICS_VER(dev_priv) == 11) - dev_priv->clock_gating_funcs.init_clock_gating = icl_init_clock_gating; + dev_priv->clock_gating_funcs = &icl_clock_gating_funcs; else if (IS_COFFEELAKE(dev_priv) || IS_COMETLAKE(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = cfl_init_clock_gating; + dev_priv->clock_gating_funcs = &cfl_clock_gating_funcs; else if (IS_SKYLAKE(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = skl_init_clock_gating; + dev_priv->clock_gating_funcs = &skl_clock_gating_funcs; else if (IS_KABYLAKE(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = kbl_init_clock_gating; + dev_priv->clock_gating_funcs = &kbl_clock_gating_funcs; else if (IS_BROXTON(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = bxt_init_clock_gating; + dev_priv->clock_gating_funcs = &bxt_clock_gating_funcs; else if (IS_GEMINILAKE(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = glk_init_clock_gating; + dev_priv->clock_gating_funcs = &glk_clock_gating_funcs; else if (IS_BROADWELL(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = bdw_init_clock_gating; + dev_priv->clock_gating_funcs = &bdw_clock_gating_funcs; else if (IS_CHERRYVIEW(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = chv_init_clock_gating; + dev_priv->clock_gating_funcs = &chv_clock_gating_funcs; else if (IS_HASWELL(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = hsw_init_clock_gating; + dev_priv->clock_gating_funcs = &hsw_clock_gating_funcs; else if (IS_IVYBRIDGE(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = ivb_init_clock_gating; + dev_priv->clock_gating_funcs = &ivb_clock_gating_funcs; else if (IS_VALLEYVIEW(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = vlv_init_clock_gating; + dev_priv->clock_gating_funcs = &vlv_clock_gating_funcs; else if (GRAPHICS_VER(dev_priv) == 6) - dev_priv->clock_gating_funcs.init_clock_gating = gen6_init_clock_gating; + dev_priv->clock_gating_funcs = &gen6_clock_gating_funcs; else if (GRAPHICS_VER(dev_priv) == 5) - dev_priv->clock_gating_funcs.init_clock_gating = ilk_init_clock_gating; + dev_priv->clock_gating_funcs = &ilk_clock_gating_funcs; else if (IS_G4X(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = g4x_init_clock_gating; + dev_priv->clock_gating_funcs = &g4x_clock_gating_funcs; else if (IS_I965GM(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = i965gm_init_clock_gating; + dev_priv->clock_gating_funcs = &i965gm_clock_gating_funcs; else if (IS_I965G(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = i965g_init_clock_gating; + dev_priv->clock_gating_funcs = &i965g_clock_gating_funcs; else if (GRAPHICS_VER(dev_priv) == 3) - dev_priv->clock_gating_funcs.init_clock_gating = gen3_init_clock_gating; + dev_priv->clock_gating_funcs = &gen3_clock_gating_funcs; else if (IS_I85X(dev_priv) || IS_I865G(dev_priv)) - dev_priv->clock_gating_funcs.init_clock_gating = i85x_init_clock_gating; + dev_priv->clock_gating_funcs = &i85x_clock_gating_funcs; else if (GRAPHICS_VER(dev_priv) == 2) - dev_priv->clock_gating_funcs.init_clock_gating = i830_init_clock_gating; + dev_priv->clock_gating_funcs = &i830_clock_gating_funcs; else { MISSING_CASE(INTEL_DEVID(dev_priv)); - dev_priv->clock_gating_funcs.init_clock_gating = nop_init_clock_gating; + dev_priv->clock_gating_funcs = &nop_clock_gating_funcs; } } -- cgit v1.2.3 From dde98a573c0a00a1501f087f89ee61ce93d416df Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 29 Sep 2021 01:58:08 +0300 Subject: drm/i915: constify display wm vtable Use a nop table for the cases where CxSR doesn't init properly. v2: use a nop table (Jani) Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/bb0658d14afd02cca692cd58223800f68f4ff4ce.1632869550.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 34 ++++++------ drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_pm.c | 80 ++++++++++++++++++++-------- 3 files changed, 75 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e7ac92994abf..9e407760e51f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -161,16 +161,16 @@ static void intel_modeset_setup_hw_state(struct drm_device *dev, */ static void intel_update_watermarks(struct drm_i915_private *dev_priv) { - if (dev_priv->wm_disp.update_wm) - dev_priv->wm_disp.update_wm(dev_priv); + if (dev_priv->wm_disp->update_wm) + dev_priv->wm_disp->update_wm(dev_priv); } static int intel_compute_pipe_wm(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->wm_disp.compute_pipe_wm) - return dev_priv->wm_disp.compute_pipe_wm(state, crtc); + if (dev_priv->wm_disp->compute_pipe_wm) + return dev_priv->wm_disp->compute_pipe_wm(state, crtc); return 0; } @@ -178,20 +178,20 @@ static int intel_compute_intermediate_wm(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (!dev_priv->wm_disp.compute_intermediate_wm) + if (!dev_priv->wm_disp->compute_intermediate_wm) return 0; if (drm_WARN_ON(&dev_priv->drm, - !dev_priv->wm_disp.compute_pipe_wm)) + !dev_priv->wm_disp->compute_pipe_wm)) return 0; - return dev_priv->wm_disp.compute_intermediate_wm(state, crtc); + return dev_priv->wm_disp->compute_intermediate_wm(state, crtc); } static bool intel_initial_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->wm_disp.initial_watermarks) { - dev_priv->wm_disp.initial_watermarks(state, crtc); + if (dev_priv->wm_disp->initial_watermarks) { + dev_priv->wm_disp->initial_watermarks(state, crtc); return true; } return false; @@ -201,23 +201,23 @@ static void intel_atomic_update_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->wm_disp.atomic_update_watermarks) - dev_priv->wm_disp.atomic_update_watermarks(state, crtc); + if (dev_priv->wm_disp->atomic_update_watermarks) + dev_priv->wm_disp->atomic_update_watermarks(state, crtc); } static void intel_optimize_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->wm_disp.optimize_watermarks) - dev_priv->wm_disp.optimize_watermarks(state, crtc); + if (dev_priv->wm_disp->optimize_watermarks) + dev_priv->wm_disp->optimize_watermarks(state, crtc); } static int intel_compute_global_watermarks(struct intel_atomic_state *state) { struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->wm_disp.compute_global_watermarks) - return dev_priv->wm_disp.compute_global_watermarks(state); + if (dev_priv->wm_disp->compute_global_watermarks) + return dev_priv->wm_disp->compute_global_watermarks(state); return 0; } @@ -3743,7 +3743,7 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, if (DISPLAY_VER(dev_priv) != 2) intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); - if (!dev_priv->wm_disp.initial_watermarks) + if (!dev_priv->wm_disp->initial_watermarks) intel_update_watermarks(dev_priv); /* clock the pipe down to 640x480@60 to potentially save power */ @@ -11425,7 +11425,7 @@ static void sanitize_watermarks(struct drm_i915_private *dev_priv) int i; /* Only supported on platforms that use atomic watermark design */ - if (!dev_priv->wm_disp.optimize_watermarks) + if (!dev_priv->wm_disp->optimize_watermarks) return; state = drm_atomic_state_alloc(&dev_priv->drm); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4e28645c73c6..133dadecafdb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -978,7 +978,7 @@ struct drm_i915_private { const struct drm_i915_clock_gating_funcs *clock_gating_funcs; /* pm display functions */ - struct drm_i915_wm_disp_funcs wm_disp; + const struct drm_i915_wm_disp_funcs *wm_disp; /* irq display functions */ const struct intel_hotplug_funcs *hotplug_funcs; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 08e0195edeb7..ef5f73934dab 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7975,6 +7975,51 @@ void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) } } +static const struct drm_i915_wm_disp_funcs skl_wm_funcs = { + .compute_global_watermarks = skl_compute_wm, +}; + +static const struct drm_i915_wm_disp_funcs ilk_wm_funcs = { + .compute_pipe_wm = ilk_compute_pipe_wm, + .compute_intermediate_wm = ilk_compute_intermediate_wm, + .initial_watermarks = ilk_initial_watermarks, + .optimize_watermarks = ilk_optimize_watermarks, +}; + +static const struct drm_i915_wm_disp_funcs vlv_wm_funcs = { + .compute_pipe_wm = vlv_compute_pipe_wm, + .compute_intermediate_wm = vlv_compute_intermediate_wm, + .initial_watermarks = vlv_initial_watermarks, + .optimize_watermarks = vlv_optimize_watermarks, + .atomic_update_watermarks = vlv_atomic_update_fifo, +}; + +static const struct drm_i915_wm_disp_funcs g4x_wm_funcs = { + .compute_pipe_wm = g4x_compute_pipe_wm, + .compute_intermediate_wm = g4x_compute_intermediate_wm, + .initial_watermarks = g4x_initial_watermarks, + .optimize_watermarks = g4x_optimize_watermarks, +}; + +static const struct drm_i915_wm_disp_funcs pnv_wm_funcs = { + .update_wm = pnv_update_wm, +}; + +static const struct drm_i915_wm_disp_funcs i965_wm_funcs = { + .update_wm = i965_update_wm, +}; + +static const struct drm_i915_wm_disp_funcs i9xx_wm_funcs = { + .update_wm = i9xx_update_wm, +}; + +static const struct drm_i915_wm_disp_funcs i845_wm_funcs = { + .update_wm = i845_update_wm, +}; + +static const struct drm_i915_wm_disp_funcs nop_funcs = { +}; + /* Set up chip specific power management-related functions */ void intel_init_pm(struct drm_i915_private *dev_priv) { @@ -7990,7 +8035,7 @@ void intel_init_pm(struct drm_i915_private *dev_priv) /* For FIFO watermark updates */ if (DISPLAY_VER(dev_priv) >= 9) { skl_setup_wm_latency(dev_priv); - dev_priv->wm_disp.compute_global_watermarks = skl_compute_wm; + dev_priv->wm_disp = &skl_wm_funcs; } else if (HAS_PCH_SPLIT(dev_priv)) { ilk_setup_wm_latency(dev_priv); @@ -7998,31 +8043,19 @@ void intel_init_pm(struct drm_i915_private *dev_priv) dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) || (DISPLAY_VER(dev_priv) != 5 && dev_priv->wm.pri_latency[0] && dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { - dev_priv->wm_disp.compute_pipe_wm = ilk_compute_pipe_wm; - dev_priv->wm_disp.compute_intermediate_wm = - ilk_compute_intermediate_wm; - dev_priv->wm_disp.initial_watermarks = - ilk_initial_watermarks; - dev_priv->wm_disp.optimize_watermarks = - ilk_optimize_watermarks; + dev_priv->wm_disp = &ilk_wm_funcs; } else { drm_dbg_kms(&dev_priv->drm, "Failed to read display plane latency. " "Disable CxSR\n"); + dev_priv->wm_disp = &nop_funcs; } } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { vlv_setup_wm_latency(dev_priv); - dev_priv->wm_disp.compute_pipe_wm = vlv_compute_pipe_wm; - dev_priv->wm_disp.compute_intermediate_wm = vlv_compute_intermediate_wm; - dev_priv->wm_disp.initial_watermarks = vlv_initial_watermarks; - dev_priv->wm_disp.optimize_watermarks = vlv_optimize_watermarks; - dev_priv->wm_disp.atomic_update_watermarks = vlv_atomic_update_fifo; + dev_priv->wm_disp = &vlv_wm_funcs; } else if (IS_G4X(dev_priv)) { g4x_setup_wm_latency(dev_priv); - dev_priv->wm_disp.compute_pipe_wm = g4x_compute_pipe_wm; - dev_priv->wm_disp.compute_intermediate_wm = g4x_compute_intermediate_wm; - dev_priv->wm_disp.initial_watermarks = g4x_initial_watermarks; - dev_priv->wm_disp.optimize_watermarks = g4x_optimize_watermarks; + dev_priv->wm_disp = &g4x_wm_funcs; } else if (IS_PINEVIEW(dev_priv)) { if (!intel_get_cxsr_latency(!IS_MOBILE(dev_priv), dev_priv->is_ddr3, @@ -8036,21 +8069,22 @@ void intel_init_pm(struct drm_i915_private *dev_priv) dev_priv->fsb_freq, dev_priv->mem_freq); /* Disable CxSR and never update its watermark again */ intel_set_memory_cxsr(dev_priv, false); - dev_priv->wm_disp.update_wm = NULL; + dev_priv->wm_disp = &nop_funcs; } else - dev_priv->wm_disp.update_wm = pnv_update_wm; + dev_priv->wm_disp = &pnv_wm_funcs; } else if (DISPLAY_VER(dev_priv) == 4) { - dev_priv->wm_disp.update_wm = i965_update_wm; + dev_priv->wm_disp = &i965_wm_funcs; } else if (DISPLAY_VER(dev_priv) == 3) { - dev_priv->wm_disp.update_wm = i9xx_update_wm; + dev_priv->wm_disp = &i9xx_wm_funcs; } else if (DISPLAY_VER(dev_priv) == 2) { if (INTEL_NUM_PIPES(dev_priv) == 1) - dev_priv->wm_disp.update_wm = i845_update_wm; + dev_priv->wm_disp = &i845_wm_funcs; else - dev_priv->wm_disp.update_wm = i9xx_update_wm; + dev_priv->wm_disp = &i9xx_wm_funcs; } else { drm_err(&dev_priv->drm, "unexpected fall-through in %s\n", __func__); + dev_priv->wm_disp = &nop_funcs; } } -- cgit v1.2.3 From 11408ea52786c2ae802b4cae32597fffe440147e Mon Sep 17 00:00:00 2001 From: Tejas Upadhyay Date: Wed, 29 Sep 2021 10:54:42 +0530 Subject: drm/i915/gen11: Disable cursor clock gating in HDR mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Display underrun in HDR mode when cursor is enabled. RTL fix will be implemented CLKGATE_DIS_PSL_A bit 28-46520h. As per W/A 1604331009, Disable cursor clock gating in HDR mode. Bspec : 33451 Changes since V6: - Address checkpatch warnings - Bit ordering Changes since V5: - replace intel_de_read with intel_de_rmw - Jani Changes since V4: - Added WA needed check - Ville - Replace BIT with REG_BIT - Ville - Add WA enable/disable support back which was added in V1 - Ville Changes since V3: - Disable WA when not in HDR mode or cursor plane not active - Ville - Extract required args from crtc_state - Ville - Create HDR mode API using bdw_set_pipemisc ref - Ville - Tested with HDR video as well full setmode, WA applies and disables Changes since V2: - Made it general gen11 WA - Removed WA needed check - Added cursor plane active check - Once WA enable, software will not disable Changes since V1: - Modified way CLKGATE_DIS_PSL bit 28 was modified Reviewed-by: Ville Syrjälä Signed-off-by: Tejas Upadhyay Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20210929052442.2543054-1-tejaskumarx.surendrakumar.upadhyay@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 32 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 1 + 2 files changed, 33 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9e407760e51f..5e4440ac44a8 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -309,6 +309,15 @@ icl_wa_scalerclkgating(struct drm_i915_private *dev_priv, enum pipe pipe, intel_de_read(dev_priv, CLKGATE_DIS_PSL(pipe)) & ~DPFR_GATING_DIS); } +/* Wa_1604331009:icl,jsl,ehl */ +static void +icl_wa_cursorclkgating(struct drm_i915_private *dev_priv, enum pipe pipe, + bool enable) +{ + intel_de_rmw(dev_priv, CLKGATE_DIS_PSL(pipe), CURSOR_GATING_DIS, + enable ? CURSOR_GATING_DIS : 0); +} + static bool is_trans_port_sync_slave(const struct intel_crtc_state *crtc_state) { @@ -2451,6 +2460,19 @@ static bool needs_scalerclk_wa(const struct intel_crtc_state *crtc_state) return false; } +static bool needs_cursorclk_wa(const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + + /* Wa_1604331009:icl,jsl,ehl */ + if (is_hdr_mode(crtc_state) && + crtc_state->active_planes & BIT(PLANE_CURSOR) && + DISPLAY_VER(dev_priv) == 11) + return true; + + return false; +} + static bool planes_enabling(const struct intel_crtc_state *old_crtc_state, const struct intel_crtc_state *new_crtc_state) { @@ -2493,6 +2515,11 @@ static void intel_post_plane_update(struct intel_atomic_state *state, if (needs_scalerclk_wa(old_crtc_state) && !needs_scalerclk_wa(new_crtc_state)) icl_wa_scalerclkgating(dev_priv, pipe, false); + + if (needs_cursorclk_wa(old_crtc_state) && + !needs_cursorclk_wa(new_crtc_state)) + icl_wa_cursorclkgating(dev_priv, pipe, false); + } static void intel_crtc_enable_flip_done(struct intel_atomic_state *state, @@ -2589,6 +2616,11 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, needs_scalerclk_wa(new_crtc_state)) icl_wa_scalerclkgating(dev_priv, pipe, true); + /* Wa_1604331009:icl,jsl,ehl */ + if (!needs_cursorclk_wa(old_crtc_state) && + needs_cursorclk_wa(new_crtc_state)) + icl_wa_cursorclkgating(dev_priv, pipe, true); + /* * Vblank time updates from the shadow to live plane control register * are blocked if the memory self-refresh mode is active at that diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 24017d38c6f6..c78337ab4f7b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4239,6 +4239,7 @@ enum { #define DUPS1_GATING_DIS (1 << 15) #define DUPS2_GATING_DIS (1 << 19) #define DUPS3_GATING_DIS (1 << 23) +#define CURSOR_GATING_DIS REG_BIT(28) #define DPF_GATING_DIS (1 << 10) #define DPF_RAM_GATING_DIS (1 << 9) #define DPFR_GATING_DIS (1 << 8) -- cgit v1.2.3 From 7194dc998dfffca096c30b3cd39625158608992d Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 29 Sep 2021 16:28:27 +0300 Subject: drm/i915/tc: Fix TypeC port init/resume time sanitization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Atm during driver loading and system resume TypeC ports are accessed before their HW/SW state is synced. Move the TypeC port sanitization to the encoder's sync_state hook to fix this. v2: Handle the encoder disabled case in gen11_dsi_sync_state() as well (Jose, Jani) Fixes: f9e76a6e68d3 ("drm/i915: Add an encoder hook to sanitize its state during init/resume") Cc: José Roberto de Souza Cc: Ville Syrjälä Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210929132833.2253961-1-imre.deak@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 10 ++++++++-- drivers/gpu/drm/i915/display/intel_ddi.c | 8 +++++++- drivers/gpu/drm/i915/display/intel_display.c | 20 +++++--------------- 3 files changed, 20 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 060bc8fb0d30..bd210166b079 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1599,8 +1599,14 @@ static void gen11_dsi_sync_state(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc); - enum pipe pipe = intel_crtc->pipe; + struct intel_crtc *intel_crtc; + enum pipe pipe; + + if (!crtc_state) + return; + + intel_crtc = to_intel_crtc(crtc_state->uapi.crtc); + pipe = intel_crtc->pipe; /* wa verify 1409054076:icl,jsl,ehl */ if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B && diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index a4667741d354..04572ce6630f 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3838,7 +3838,13 @@ void hsw_ddi_get_config(struct intel_encoder *encoder, static void intel_ddi_sync_state(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - if (intel_crtc_has_dp_encoder(crtc_state)) + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + enum phy phy = intel_port_to_phy(i915, encoder->port); + + if (intel_phy_is_tc(i915, phy)) + intel_tc_port_sanitize(enc_to_dig_port(encoder)); + + if (crtc_state && intel_crtc_has_dp_encoder(crtc_state)) intel_dp_sync_state(encoder, crtc_state); } diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 5e4440ac44a8..1a2b2b3ce56e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -12317,18 +12317,16 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) readout_plane_state(dev_priv); for_each_intel_encoder(dev, encoder) { + struct intel_crtc_state *crtc_state = NULL; + pipe = 0; if (encoder->get_hw_state(encoder, &pipe)) { - struct intel_crtc_state *crtc_state; - crtc = intel_get_crtc_for_pipe(dev_priv, pipe); crtc_state = to_intel_crtc_state(crtc->base.state); encoder->base.crtc = &crtc->base; intel_encoder_get_config(encoder, crtc_state); - if (encoder->sync_state) - encoder->sync_state(encoder, crtc_state); /* read out to slave crtc as well for bigjoiner */ if (crtc_state->bigjoiner) { @@ -12343,6 +12341,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) encoder->base.crtc = NULL; } + if (encoder->sync_state) + encoder->sync_state(encoder, crtc_state); + drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] hw state readout: %s, pipe %c\n", encoder->base.base.id, encoder->base.name, @@ -12625,17 +12626,6 @@ intel_modeset_setup_hw_state(struct drm_device *dev, intel_modeset_readout_hw_state(dev); /* HW state is read out, now we need to sanitize this mess. */ - - /* Sanitize the TypeC port mode upfront, encoders depend on this */ - for_each_intel_encoder(dev, encoder) { - enum phy phy = intel_port_to_phy(dev_priv, encoder->port); - - /* We need to sanitize only the MST primary port. */ - if (encoder->type != INTEL_OUTPUT_DP_MST && - intel_phy_is_tc(dev_priv, phy)) - intel_tc_port_sanitize(enc_to_dig_port(encoder)); - } - get_encoder_power_domains(dev_priv); if (HAS_PCH_IBX(dev_priv)) -- cgit v1.2.3 From 4f7dad584fdce914d698233179a1188481789884 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 21 Sep 2021 03:23:02 +0300 Subject: drm/i915/adlp/tc: Fix PHY connected check for Thunderbolt mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On ADL-P the PHY ready (aka status complete on other platforms) flag is always set, besides when a DP-alt, legacy sink is connected also when a TBT sink is connected or nothing is connected. So assume the PHY to be connected when both the TBT live status and PHY ready flags are set. Cc: José Roberto de Souza Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210921002313.1132357-3-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 3ffece568ed9..7dc3696085c7 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -509,6 +509,10 @@ static bool icl_tc_phy_is_connected(struct intel_digital_port *dig_port) return dig_port->tc_mode == TC_PORT_TBT_ALT; } + /* On ADL-P the PHY complete flag is set in TBT mode as well. */ + if (IS_ALDERLAKE_P(i915) && dig_port->tc_mode == TC_PORT_TBT_ALT) + return true; + if (!tc_phy_is_owned(dig_port)) { drm_dbg_kms(&i915->drm, "Port %s: PHY not owned\n", dig_port->tc_port_name); -- cgit v1.2.3 From 62e1e308ffd7a867ef82375f3cff7f8789ce6721 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 21 Sep 2021 03:23:03 +0300 Subject: drm/i915/tc: Remove waiting for PHY complete during releasing ownership MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Waiting for the PHY complete flag to clear when releasing the PHY ownership was add in commit ddec362724f9 ("drm/i915: Wait for TypeC PHY complete flag to clear in safe mode") This isn't required by the spec, the vague idea was to make the handshake with the firmware more robust, without actual evidence for when it would be needed. Checking this again, the flag doesn't clear on ICL until after the PHY's PLL is disabled and the flag is permanently set on ADL-P. To avoid the spurious timeout messages in dmesg, just remove this wait. Cc: José Roberto de Souza Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210921002313.1132357-4-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 7dc3696085c7..0d3555437b0b 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -339,11 +339,6 @@ static bool icl_tc_phy_take_ownership(struct intel_digital_port *dig_port, intel_uncore_write(uncore, PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia), val); - if (!take && wait_for(!tc_phy_status_complete(dig_port), 10)) - drm_dbg_kms(&i915->drm, - "Port %s: PHY complete clear timed out\n", - dig_port->tc_port_name); - return true; } -- cgit v1.2.3 From 30e114ef4b1620bd6768952279b53ea24e232efb Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 29 Sep 2021 16:28:28 +0300 Subject: drm/i915/tc: Check for DP-alt, legacy sinks before taking PHY ownership MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On ADL-P the PHY ready/complete flag is always set even in TBT-alt mode. To avoid taking the PHY ownership and the following spurious "PHY sudden disconnect" messages on this platform when connecting the PHY in TBT mode, check if there is any DP-alt or legacy sink connected before taking the ownership. v2: (Jose) - Fix debug message clarifying that a TBT sink can be connected. - Add comments describing the PHY complete HW flag semantic differences between adl-p and other platforms. Cc: José Roberto de Souza Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210929132833.2253961-2-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 0d3555437b0b..4e5ff823a3a3 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -270,6 +270,14 @@ static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port) return icl_tc_port_live_status_mask(dig_port); } +/* + * Return the PHY status complete flag indicating that display can acquire the + * PHY ownership. The IOM firmware sets this flag when a DP-alt or legacy sink + * is connected and it's ready to switch the ownership to display. The flag + * will be left cleared when a TBT-alt sink is connected, where the PHY is + * owned by the TBT subsystem and so switching the ownership to display is not + * required. + */ static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); @@ -288,6 +296,13 @@ static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port) return val & DP_PHY_MODE_STATUS_COMPLETED(dig_port->tc_phy_fia_idx); } +/* + * Return the PHY status complete flag indicating that display can acquire the + * PHY ownership. The IOM firmware sets this flag when it's ready to switch + * the ownership to display, regardless of what sink is connected (TBT-alt, + * DP-alt, legacy or nothing). For TBT-alt sinks the PHY is owned by the TBT + * subsystem and so switching the ownership to display is not required. + */ static bool adl_tc_phy_status_complete(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); @@ -424,6 +439,7 @@ static void icl_tc_phy_connect(struct intel_digital_port *dig_port, int required_lanes) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + u32 live_status_mask; int max_lanes; if (!tc_phy_status_complete(dig_port)) { @@ -432,6 +448,13 @@ static void icl_tc_phy_connect(struct intel_digital_port *dig_port, goto out_set_tbt_alt_mode; } + live_status_mask = tc_port_live_status_mask(dig_port); + if (!(live_status_mask & (BIT(TC_PORT_DP_ALT) | BIT(TC_PORT_LEGACY)))) { + drm_dbg_kms(&i915->drm, "Port %s: PHY ownership not required (live status %02x)\n", + dig_port->tc_port_name, live_status_mask); + goto out_set_tbt_alt_mode; + } + if (!tc_phy_take_ownership(dig_port, true) && !drm_WARN_ON(&i915->drm, dig_port->tc_legacy_port)) goto out_set_tbt_alt_mode; -- cgit v1.2.3 From 11a8970865b49c2a1e714ea3ba910d05fdde6944 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 21 Sep 2021 03:23:05 +0300 Subject: drm/i915/tc: Add/use helpers to retrieve TypeC port properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of directly accessing the TypeC port internal struct members, add/use helpers to retrieve the corresponding properties. No functional change. Cc: José Roberto de Souza Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210921002313.1132357-6-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 31 ++++++++-------------- drivers/gpu/drm/i915/display/intel_display.c | 6 +---- drivers/gpu/drm/i915/display/intel_display_power.c | 4 +-- drivers/gpu/drm/i915/display/intel_dp_aux.c | 6 +---- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 5 ++-- drivers/gpu/drm/i915/display/intel_tc.c | 24 +++++++++++++++++ drivers/gpu/drm/i915/display/intel_tc.h | 4 +++ 7 files changed, 46 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 04572ce6630f..0fe77854b455 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -288,7 +288,7 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, if (IS_ALDERLAKE_P(i915) && intel_phy_is_tc(i915, phy)) { intel_dp->DP |= ddi_buf_phy_link_rate(crtc_state->port_clock); - if (dig_port->tc_mode != TC_PORT_TBT_ALT) + if (!intel_tc_port_in_tbt_alt_mode(dig_port)) intel_dp->DP |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; } } @@ -885,8 +885,7 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder, dig_port = enc_to_dig_port(encoder); - if (!intel_phy_is_tc(dev_priv, phy) || - dig_port->tc_mode != TC_PORT_TBT_ALT) { + if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); @@ -1180,7 +1179,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int n_entries, ln; u32 val; - if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT) + if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder))) return; ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); @@ -1317,7 +1316,7 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, u32 val, dpcnt_mask, dpcnt_val; int n_entries, ln; - if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT) + if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder))) return; ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); @@ -2084,7 +2083,7 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port, u8 width; if (!intel_phy_is_tc(dev_priv, phy) || - dig_port->tc_mode == TC_PORT_TBT_ALT) + intel_tc_port_in_tbt_alt_mode(dig_port)) return; if (DISPLAY_VER(dev_priv) >= 12) { @@ -2109,7 +2108,7 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port, switch (pin_assignment) { case 0x0: drm_WARN_ON(&dev_priv->drm, - dig_port->tc_mode != TC_PORT_LEGACY); + !intel_tc_port_in_legacy_mode(dig_port)); if (width == 1) { ln1 |= MG_DP_MODE_CFG_DP_X1_MODE; } else { @@ -2354,7 +2353,6 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state, { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - enum phy phy = intel_port_to_phy(dev_priv, encoder->port); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); int level = intel_ddi_dp_level(intel_dp, crtc_state); @@ -2378,8 +2376,7 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_enable_clock(encoder, crtc_state); /* 4. Enable IO power */ - if (!intel_phy_is_tc(dev_priv, phy) || - dig_port->tc_mode != TC_PORT_TBT_ALT) + if (!intel_tc_port_in_tbt_alt_mode(dig_port)) dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); @@ -2468,7 +2465,6 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - enum phy phy = intel_port_to_phy(dev_priv, encoder->port); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); int level = intel_ddi_dp_level(intel_dp, crtc_state); @@ -2505,8 +2501,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_enable_clock(encoder, crtc_state); /* 5. If IO power is controlled through PWR_WELL_CTL, Enable IO Power */ - if (!intel_phy_is_tc(dev_priv, phy) || - dig_port->tc_mode != TC_PORT_TBT_ALT) { + if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); @@ -2611,7 +2606,6 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; - enum phy phy = intel_port_to_phy(dev_priv, port); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); int level = intel_ddi_dp_level(intel_dp, crtc_state); @@ -2630,8 +2624,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_enable_clock(encoder, crtc_state); - if (!intel_phy_is_tc(dev_priv, phy) || - dig_port->tc_mode != TC_PORT_TBT_ALT) { + if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); @@ -2801,7 +2794,6 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, struct intel_dp *intel_dp = &dig_port->dp; bool is_mst = intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST); - enum phy phy = intel_port_to_phy(dev_priv, encoder->port); if (!is_mst) intel_dp_set_infoframes(encoder, false, @@ -2844,8 +2836,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, intel_pps_vdd_on(intel_dp); intel_pps_off(intel_dp); - if (!intel_phy_is_tc(dev_priv, phy) || - dig_port->tc_mode != TC_PORT_TBT_ALT) + if (!intel_tc_port_in_tbt_alt_mode(dig_port)) intel_display_power_put(dev_priv, dig_port->ddi_io_power_domain, fetch_and_zero(&dig_port->ddi_io_wakeref)); @@ -3320,7 +3311,7 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, intel_ddi_main_link_aux_domain(dig_port)); } - if (is_tc_port && dig_port->tc_mode != TC_PORT_TBT_ALT) + if (is_tc_port && !intel_tc_port_in_tbt_alt_mode(dig_port)) /* * Program the lane count for static/dynamic connections on * Type-C ports. Skip this step for TBT. diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 1a2b2b3ce56e..4ce80ca7751f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3494,11 +3494,7 @@ enum intel_display_power_domain intel_port_to_power_domain(enum port port) enum intel_display_power_domain intel_aux_power_domain(struct intel_digital_port *dig_port) { - 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_tc(dev_priv, phy) && - dig_port->tc_mode == TC_PORT_TBT_ALT) { + if (intel_tc_port_in_tbt_alt_mode(dig_port)) { switch (dig_port->aux_ch) { case AUX_CH_C: return POWER_DOMAIN_AUX_C_TBT; diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index a274e2b33e91..2410c1a617ea 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -560,7 +560,7 @@ static void icl_tc_port_assert_ref_held(struct drm_i915_private *dev_priv, if (drm_WARN_ON(&dev_priv->drm, !dig_port)) return; - if (DISPLAY_VER(dev_priv) == 11 && dig_port->tc_legacy_port) + if (DISPLAY_VER(dev_priv) == 11 && intel_tc_cold_requires_aux_pw(dig_port)) return; drm_WARN_ON(&dev_priv->drm, !intel_tc_port_ref_held(dig_port)); @@ -629,7 +629,7 @@ icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv, * exit sequence. */ timeout_expected = is_tbt || intel_tc_cold_requires_aux_pw(dig_port); - if (DISPLAY_VER(dev_priv) == 11 && dig_port->tc_legacy_port) + if (DISPLAY_VER(dev_priv) == 11 && intel_tc_cold_requires_aux_pw(dig_port)) icl_tc_cold_exit(dev_priv); hsw_wait_for_power_well_enable(dev_priv, power_well, timeout_expected); diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c index f483f479dd0b..5fbb767fcd63 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c @@ -150,9 +150,6 @@ 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); - enum phy phy = intel_port_to_phy(i915, dig_port->base.port); u32 ret; /* @@ -170,8 +167,7 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp, DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) | DP_AUX_CH_CTL_SYNC_PULSE_SKL(32); - if (intel_phy_is_tc(i915, phy) && - dig_port->tc_mode == TC_PORT_TBT_ALT) + if (intel_tc_port_in_tbt_alt_mode(dig_port)) ret |= DP_AUX_CH_CTL_TBT_IO; return ret; diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 055992d099c7..0a7e04db04be 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -26,6 +26,7 @@ #include "intel_dpio_phy.h" #include "intel_dpll.h" #include "intel_dpll_mgr.h" +#include "intel_tc.h" /** * DOC: Display PLLs @@ -3101,8 +3102,8 @@ static void icl_update_active_dpll(struct intel_atomic_state *state, enc_to_dig_port(encoder); if (primary_port && - (primary_port->tc_mode == TC_PORT_DP_ALT || - primary_port->tc_mode == TC_PORT_LEGACY)) + (intel_tc_port_in_dp_alt_mode(primary_port) || + intel_tc_port_in_legacy_mode(primary_port))) port_dpll_id = ICL_PORT_DPLL_MG_PHY; icl_set_active_port_dpll(crtc_state, port_dpll_id); diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 4e5ff823a3a3..f9242056693e 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -23,6 +23,30 @@ static const char *tc_port_mode_name(enum tc_port_mode mode) return names[mode]; } +static bool intel_tc_port_in_mode(struct intel_digital_port *dig_port, + enum tc_port_mode mode) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + enum phy phy = intel_port_to_phy(i915, dig_port->base.port); + + return intel_phy_is_tc(i915, phy) && dig_port->tc_mode == mode; +} + +bool intel_tc_port_in_tbt_alt_mode(struct intel_digital_port *dig_port) +{ + return intel_tc_port_in_mode(dig_port, TC_PORT_TBT_ALT); +} + +bool intel_tc_port_in_dp_alt_mode(struct intel_digital_port *dig_port) +{ + return intel_tc_port_in_mode(dig_port, TC_PORT_DP_ALT); +} + +bool intel_tc_port_in_legacy_mode(struct intel_digital_port *dig_port) +{ + return intel_tc_port_in_mode(dig_port, TC_PORT_LEGACY); +} + static enum intel_display_power_domain tc_cold_get_power_domain(struct intel_digital_port *dig_port) { diff --git a/drivers/gpu/drm/i915/display/intel_tc.h b/drivers/gpu/drm/i915/display/intel_tc.h index 0c881f645e27..0fdcddb4fc87 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.h +++ b/drivers/gpu/drm/i915/display/intel_tc.h @@ -12,6 +12,10 @@ struct intel_digital_port; struct intel_encoder; +bool intel_tc_port_in_tbt_alt_mode(struct intel_digital_port *dig_port); +bool intel_tc_port_in_dp_alt_mode(struct intel_digital_port *dig_port); +bool intel_tc_port_in_legacy_mode(struct intel_digital_port *dig_port); + bool intel_tc_port_connected(struct intel_encoder *encoder); void intel_tc_port_disconnect_phy(struct intel_digital_port *dig_port); -- cgit v1.2.3 From 675d23c14821fbaef3df5cbad94b42ec2e3a858a Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 21 Sep 2021 03:23:06 +0300 Subject: drm/i915/tc: Don't keep legacy TypeC ports in connected state w/o a sink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A follow-up patch will disconnect/reconnect PHYs around AUX transfers and modeset enable/disables. To prepare for that and make things consistent for all TypeC modes stop connecting the PHY in legacy mode without a sink being connected. This was done before since in legacy mode the PHY is dedicated to display usage, so there was no point in disconnecting it. However after the follow-up changes the TC-cold blocking power domains will be held as long as the PHY is in the connected state, so we'll need to disconnect/re-connect the PHY in all TypeC modes to allow for power saving. Cc: José Roberto de Souza Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210921002313.1132357-7-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index f9242056693e..6d0a1b376767 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -527,8 +527,6 @@ static void icl_tc_phy_disconnect(struct intel_digital_port *dig_port) { switch (dig_port->tc_mode) { case TC_PORT_LEGACY: - /* Nothing to do, we never disconnect from legacy mode */ - break; case TC_PORT_DP_ALT: tc_phy_take_ownership(dig_port, false); dig_port->tc_mode = TC_PORT_TBT_ALT; @@ -596,9 +594,7 @@ intel_tc_port_get_target_mode(struct intel_digital_port *dig_port) if (live_status_mask) return fls(live_status_mask) - 1; - return tc_phy_status_complete(dig_port) && - dig_port->tc_legacy_port ? TC_PORT_LEGACY : - TC_PORT_TBT_ALT; + return TC_PORT_TBT_ALT; } static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port, @@ -659,14 +655,8 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port) "Port %s: PHY disconnected with %d active link(s)\n", dig_port->tc_port_name, active_links); intel_tc_port_link_init_refcount(dig_port, active_links); - - goto out; } - if (dig_port->tc_legacy_port) - icl_tc_phy_connect(dig_port, 1); - -out: drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n", dig_port->tc_port_name, tc_port_mode_name(dig_port->tc_mode)); -- cgit v1.2.3 From 64851a32c463e5412561de67764d6fdc074bd193 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 29 Sep 2021 16:28:29 +0300 Subject: drm/i915/tc: Add a mode for the TypeC PHY's disconnected state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A follow-up change will start to disconnect/re-connect PHYs around AUX transfers and modeset enable/disables. To prepare for that add a new TypeC PHY disconnected mode, to help tracking the TC-cold blocking power domain status (no power domain in disconnected state, mode dependent power domain in connected state). v2: Move the !disconnected mode and phy-owned asserts in __intel_tc_port_lock() later in the patchset, when the asserts will hold. (Jose) Cc: José Roberto de Souza Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210929132833.2253961-3-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.h | 1 + drivers/gpu/drm/i915/display/intel_tc.c | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index d425ee77aad7..87b96fed5e0b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -270,6 +270,7 @@ enum tc_port { }; enum tc_port_mode { + TC_PORT_DISCONNECTED, TC_PORT_TBT_ALT, TC_PORT_DP_ALT, TC_PORT_LEGACY, diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 6d0a1b376767..62a3070abf0a 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -12,13 +12,14 @@ static const char *tc_port_mode_name(enum tc_port_mode mode) { static const char * const names[] = { + [TC_PORT_DISCONNECTED] = "disconnected", [TC_PORT_TBT_ALT] = "tbt-alt", [TC_PORT_DP_ALT] = "dp-alt", [TC_PORT_LEGACY] = "legacy", }; if (WARN_ON(mode >= ARRAY_SIZE(names))) - mode = TC_PORT_TBT_ALT; + mode = TC_PORT_DISCONNECTED; return names[mode]; } @@ -529,10 +530,11 @@ static void icl_tc_phy_disconnect(struct intel_digital_port *dig_port) case TC_PORT_LEGACY: case TC_PORT_DP_ALT: tc_phy_take_ownership(dig_port, false); - dig_port->tc_mode = TC_PORT_TBT_ALT; - break; + fallthrough; case TC_PORT_TBT_ALT: - /* Nothing to do, we stay in TBT-alt mode */ + dig_port->tc_mode = TC_PORT_DISCONNECTED; + fallthrough; + case TC_PORT_DISCONNECTED: break; default: MISSING_CASE(dig_port->tc_mode); @@ -637,31 +639,34 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_encoder *encoder = &dig_port->base; - intel_wakeref_t tc_cold_wref; int active_links = 0; mutex_lock(&dig_port->tc_lock); - tc_cold_wref = tc_cold_block(dig_port); - dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port); if (dig_port->dp.is_mst) active_links = intel_dp_mst_encoder_active_links(dig_port); else if (encoder->base.crtc) active_links = to_intel_crtc(encoder->base.crtc)->active; + drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED); if (active_links) { + intel_wakeref_t tc_cold_wref = tc_cold_block(dig_port); + + dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port); + if (!icl_tc_phy_is_connected(dig_port)) drm_dbg_kms(&i915->drm, "Port %s: PHY disconnected with %d active link(s)\n", dig_port->tc_port_name, active_links); intel_tc_port_link_init_refcount(dig_port, active_links); + + tc_cold_unblock(dig_port, tc_cold_wref); } drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n", dig_port->tc_port_name, tc_port_mode_name(dig_port->tc_mode)); - tc_cold_unblock(dig_port, tc_cold_wref); mutex_unlock(&dig_port->tc_lock); } @@ -832,6 +837,7 @@ void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) mutex_init(&dig_port->tc_lock); dig_port->tc_legacy_port = is_legacy; + dig_port->tc_mode = TC_PORT_DISCONNECTED; dig_port->tc_link_refcount = 0; tc_port_load_fia_params(i915, dig_port); } -- cgit v1.2.3 From d0bc677056bd9de6eb731dd8bff889a5fe36e381 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 29 Sep 2021 16:28:30 +0300 Subject: drm/i915/tc: Refactor TC-cold block/unblock helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A follow-up change will select the TC-cold blocking power domain based on the TypeC mode, prepare for that here. Also bring intel_tc_cold_requires_aux_pw() earlier to its logical place for readability. No functional change. v2: Add code comment about IOM reg accesses in TCCOLD. (Jose) Cc: José Roberto de Souza Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210929132833.2253961-4-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 2 + drivers/gpu/drm/i915/display/intel_tc.c | 68 +++++++++++++--------- 2 files changed, 44 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 9413ebae15f5..f41fdc376a51 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1662,8 +1662,10 @@ struct intel_digital_port { enum intel_display_power_domain ddi_io_power_domain; intel_wakeref_t ddi_io_wakeref; intel_wakeref_t aux_wakeref; + struct mutex tc_lock; /* protects the TypeC port mode */ intel_wakeref_t tc_lock_wakeref; + enum intel_display_power_domain tc_lock_power_domain; int tc_link_refcount; bool tc_legacy_port:1; char tc_port_name[8]; diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 62a3070abf0a..69c917fce03e 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -48,8 +48,16 @@ bool intel_tc_port_in_legacy_mode(struct intel_digital_port *dig_port) return intel_tc_port_in_mode(dig_port, TC_PORT_LEGACY); } +bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + + return (DISPLAY_VER(i915) == 11 && dig_port->tc_legacy_port) || + IS_ALDERLAKE_P(i915); +} + static enum intel_display_power_domain -tc_cold_get_power_domain(struct intel_digital_port *dig_port) +tc_cold_get_power_domain(struct intel_digital_port *dig_port, enum tc_port_mode mode) { if (intel_tc_cold_requires_aux_pw(dig_port)) return intel_legacy_aux_to_power_domain(dig_port->aux_ch); @@ -58,23 +66,30 @@ tc_cold_get_power_domain(struct intel_digital_port *dig_port) } static intel_wakeref_t -tc_cold_block(struct intel_digital_port *dig_port) +tc_cold_block_in_mode(struct intel_digital_port *dig_port, enum tc_port_mode mode, + enum intel_display_power_domain *domain) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - enum intel_display_power_domain domain; if (DISPLAY_VER(i915) == 11 && !dig_port->tc_legacy_port) return 0; - domain = tc_cold_get_power_domain(dig_port); - return intel_display_power_get(i915, domain); + *domain = tc_cold_get_power_domain(dig_port, mode); + + return intel_display_power_get(i915, *domain); +} + +static intel_wakeref_t +tc_cold_block(struct intel_digital_port *dig_port, enum intel_display_power_domain *domain) +{ + return tc_cold_block_in_mode(dig_port, dig_port->tc_mode, domain); } static void -tc_cold_unblock(struct intel_digital_port *dig_port, intel_wakeref_t wakeref) +tc_cold_unblock(struct intel_digital_port *dig_port, enum intel_display_power_domain domain, + intel_wakeref_t wakeref) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - enum intel_display_power_domain domain; /* * wakeref == -1, means some error happened saving save_depot_stack but @@ -84,8 +99,7 @@ tc_cold_unblock(struct intel_digital_port *dig_port, intel_wakeref_t wakeref) if (wakeref == 0) return; - domain = tc_cold_get_power_domain(dig_port); - intel_display_power_put_async(i915, domain, wakeref); + intel_display_power_put(i915, domain, wakeref); } static void @@ -98,7 +112,8 @@ assert_tc_cold_blocked(struct intel_digital_port *dig_port) return; enabled = intel_display_power_is_enabled(i915, - tc_cold_get_power_domain(dig_port)); + tc_cold_get_power_domain(dig_port, + dig_port->tc_mode)); drm_WARN_ON(&i915->drm, !enabled); } @@ -269,6 +284,11 @@ static u32 adl_tc_port_live_status_mask(struct intel_digital_port *dig_port) struct intel_uncore *uncore = &i915->uncore; u32 val, mask = 0; + /* + * On ADL-P HW/FW will wake from TCCOLD to complete the read access of + * registers in IOM. Note that this doesn't apply to PHY and FIA + * registers. + */ val = intel_uncore_read(uncore, TCSS_DDI_STATUS(tc_port)); if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT) mask |= BIT(TC_PORT_DP_ALT); @@ -650,7 +670,8 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port) drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED); if (active_links) { - intel_wakeref_t tc_cold_wref = tc_cold_block(dig_port); + enum intel_display_power_domain domain; + intel_wakeref_t tc_cold_wref = tc_cold_block(dig_port, &domain); dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port); @@ -660,7 +681,7 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port) dig_port->tc_port_name, active_links); intel_tc_port_link_init_refcount(dig_port, active_links); - tc_cold_unblock(dig_port, tc_cold_wref); + tc_cold_unblock(dig_port, domain, tc_cold_wref); } drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n", @@ -689,15 +710,16 @@ bool intel_tc_port_connected(struct intel_encoder *encoder) { struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_connected; + enum intel_display_power_domain domain; intel_wakeref_t tc_cold_wref; intel_tc_port_lock(dig_port); - tc_cold_wref = tc_cold_block(dig_port); + tc_cold_wref = tc_cold_block(dig_port, &domain); is_connected = tc_port_live_status_mask(dig_port) & BIT(dig_port->tc_mode); - tc_cold_unblock(dig_port, tc_cold_wref); + tc_cold_unblock(dig_port, domain, tc_cold_wref); intel_tc_port_unlock(dig_port); return is_connected; @@ -714,15 +736,16 @@ static void __intel_tc_port_lock(struct intel_digital_port *dig_port, mutex_lock(&dig_port->tc_lock); if (!dig_port->tc_link_refcount) { + enum intel_display_power_domain domain; intel_wakeref_t tc_cold_wref; - tc_cold_wref = tc_cold_block(dig_port); + tc_cold_wref = tc_cold_block(dig_port, &domain); if (force_disconnect || intel_tc_port_needs_reset(dig_port)) intel_tc_port_reset_mode(dig_port, required_lanes, force_disconnect); - tc_cold_unblock(dig_port, tc_cold_wref); + tc_cold_unblock(dig_port, domain, tc_cold_wref); } drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref); @@ -787,6 +810,7 @@ void intel_tc_port_put_link(struct intel_digital_port *dig_port) static bool tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig_port) { + enum intel_display_power_domain domain; intel_wakeref_t wakeref; u32 val; @@ -794,9 +818,9 @@ tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig return false; mutex_lock(&dig_port->tc_lock); - wakeref = tc_cold_block(dig_port); + wakeref = tc_cold_block(dig_port, &domain); val = intel_uncore_read(&i915->uncore, PORT_TX_DFLEXDPSP(FIA1)); - tc_cold_unblock(dig_port, wakeref); + tc_cold_unblock(dig_port, domain, wakeref); mutex_unlock(&dig_port->tc_lock); drm_WARN_ON(&i915->drm, val == 0xffffffff); @@ -841,11 +865,3 @@ void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) dig_port->tc_link_refcount = 0; tc_port_load_fia_params(i915, dig_port); } - -bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port) -{ - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - - return (DISPLAY_VER(i915) == 11 && dig_port->tc_legacy_port) || - IS_ALDERLAKE_P(i915); -} -- cgit v1.2.3 From 8e8289a00e6360e0b340db05b7e16dfb5e7be067 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 29 Sep 2021 16:28:31 +0300 Subject: drm/i915/tc: Avoid using legacy AUX PW in TBT mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For the ADL-P TBT mode the spec doesn't require blocking TC-cold by using the legacy AUX power domain. To avoid the timeouts that this would cause during PHY disconnect/reconnect sequences (which will be more frequent after a follow-up change) use the TC_COLD_OFF power domain in TBT mode on all platforms. On TGL this power domain blocks TC-cold via a PUNIT command, while on other platforms the domain just takes a runtime PM reference. If the HPD live status indicates that the port mode needs to be reset - for instance after switching from TBT to a DP-alt sink - still take the AUX domain, since the IOM firmware handshake requires this. v2: Rebased on v2 of the previous patch. Cc: José Roberto de Souza Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210929132833.2253961-5-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 55 +++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 69c917fce03e..2df4d0beb636 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -59,10 +59,10 @@ bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port) static enum intel_display_power_domain tc_cold_get_power_domain(struct intel_digital_port *dig_port, enum tc_port_mode mode) { - if (intel_tc_cold_requires_aux_pw(dig_port)) - return intel_legacy_aux_to_power_domain(dig_port->aux_ch); - else + if (mode == TC_PORT_TBT_ALT || !intel_tc_cold_requires_aux_pw(dig_port)) return POWER_DOMAIN_TC_COLD_OFF; + + return intel_legacy_aux_to_power_domain(dig_port->aux_ch); } static intel_wakeref_t @@ -645,6 +645,36 @@ static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port, tc_port_mode_name(dig_port->tc_mode)); } +static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port) +{ + return intel_tc_port_get_target_mode(dig_port) != dig_port->tc_mode; +} + +static void intel_tc_port_update_mode(struct intel_digital_port *dig_port, + int required_lanes, bool force_disconnect) +{ + enum intel_display_power_domain domain; + intel_wakeref_t wref; + bool needs_reset = force_disconnect; + + if (!needs_reset) { + /* Get power domain required to check the hotplug live status. */ + wref = tc_cold_block(dig_port, &domain); + needs_reset = intel_tc_port_needs_reset(dig_port); + tc_cold_unblock(dig_port, domain, wref); + } + + if (!needs_reset) + return; + + /* Get power domain required for resetting the mode. */ + wref = tc_cold_block_in_mode(dig_port, TC_PORT_DISCONNECTED, &domain); + + intel_tc_port_reset_mode(dig_port, required_lanes, force_disconnect); + + tc_cold_unblock(dig_port, domain, wref); +} + static void intel_tc_port_link_init_refcount(struct intel_digital_port *dig_port, int refcount) @@ -691,11 +721,6 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port) mutex_unlock(&dig_port->tc_lock); } -static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port) -{ - return intel_tc_port_get_target_mode(dig_port) != dig_port->tc_mode; -} - /* * The type-C ports are different because even when they are connected, they may * not be available/usable by the graphics driver: see the comment on @@ -735,18 +760,10 @@ static void __intel_tc_port_lock(struct intel_digital_port *dig_port, mutex_lock(&dig_port->tc_lock); - if (!dig_port->tc_link_refcount) { - enum intel_display_power_domain domain; - intel_wakeref_t tc_cold_wref; - - tc_cold_wref = tc_cold_block(dig_port, &domain); - if (force_disconnect || intel_tc_port_needs_reset(dig_port)) - intel_tc_port_reset_mode(dig_port, required_lanes, - force_disconnect); - - tc_cold_unblock(dig_port, domain, tc_cold_wref); - } + if (!dig_port->tc_link_refcount) + intel_tc_port_update_mode(dig_port, required_lanes, + force_disconnect); drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref); dig_port->tc_lock_wakeref = wakeref; -- cgit v1.2.3 From 38c393462d01d2746f9f91c1a6482fded2b1b8bb Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 21 Sep 2021 03:23:10 +0300 Subject: drm/i915/icl/tc: Remove the ICL special casing during TC-cold blocking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While a TypeC port mode is locked a DISPLAY_CORE power domain reference is held, which implies a runtime PM ref. By removing the ICL !legacy port special casing, a TC_COLD_OFF power domain reference will be taken for such ports, which also translates to a runtime PM ref on that platform. A follow-up change will stop holding the DISPLAY_CORE power domain while the port is locked. Cc: José Roberto de Souza Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210921002313.1132357-11-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 2df4d0beb636..9367770de5d7 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -71,9 +71,6 @@ tc_cold_block_in_mode(struct intel_digital_port *dig_port, enum tc_port_mode mod { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - if (DISPLAY_VER(i915) == 11 && !dig_port->tc_legacy_port) - return 0; - *domain = tc_cold_get_power_domain(dig_port, mode); return intel_display_power_get(i915, *domain); @@ -108,9 +105,6 @@ assert_tc_cold_blocked(struct intel_digital_port *dig_port) struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); bool enabled; - if (DISPLAY_VER(i915) == 11 && !dig_port->tc_legacy_port) - return; - enabled = intel_display_power_is_enabled(i915, tc_cold_get_power_domain(dig_port, dig_port->tc_mode)); -- cgit v1.2.3 From 3e0abc7661c82266d3a3f27fbbadcc74cc4997e1 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 29 Sep 2021 16:28:32 +0300 Subject: drm/i915/tc: Fix TypeC PHY connect/disconnect logic on ADL-P MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far TC-cold was blocked only for the duration of TypeC mode resets. The DP-alt and legacy modes require TC-cold to be blocked also whenever the port is in use (AUX transfers, enable modeset), and this was ensured by the held PHY ownership flag. On ADL-P this doesn't work, since the PHY ownership flag is in a register backed by the PW#2 power well. Whenever this power well is disabled the ownership flag is cleared by the HW under the driver. The only way to cleanly release and re-acquire the PHY ownership flag and also allow for power saving (by disabling the display power wells and reaching DC5/6 states) is to hold the TC-cold blocking power domains while the PHY is connected and disconnect/reconnect the PHY on-demand around AUX transfers and modeset enable/disables. Let's do that, disconnecting a PHY with a 1 sec delay after it becomes idle. For consistency do this on all platforms and TypeC modes. v2: Add tc_mode!=disconnected and phy_is_owned asserts to __intel_tc_port_lock(). Cc: José Roberto de Souza Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210929132833.2253961-6-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 7 +- drivers/gpu/drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_tc.c | 81 ++++++++++++++-------- drivers/gpu/drm/i915/display/intel_tc.h | 2 +- 4 files changed, 59 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 0fe77854b455..51d07e9af9f3 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4017,8 +4017,11 @@ static void intel_ddi_encoder_destroy(struct drm_encoder *encoder) { struct drm_i915_private *i915 = to_i915(encoder->dev); struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder)); + enum phy phy = intel_port_to_phy(i915, dig_port->base.port); intel_dp_encoder_flush_work(encoder); + if (intel_phy_is_tc(i915, phy)) + intel_tc_port_flush_work(dig_port); intel_display_power_flush_work(i915); drm_encoder_cleanup(encoder); @@ -4443,7 +4446,7 @@ static void intel_ddi_encoder_suspend(struct intel_encoder *encoder) if (!intel_phy_is_tc(i915, phy)) return; - intel_tc_port_disconnect_phy(dig_port); + intel_tc_port_flush_work(dig_port); } static void intel_ddi_encoder_shutdown(struct intel_encoder *encoder) @@ -4458,7 +4461,7 @@ static void intel_ddi_encoder_shutdown(struct intel_encoder *encoder) if (!intel_phy_is_tc(i915, phy)) return; - intel_tc_port_disconnect_phy(dig_port); + intel_tc_port_flush_work(dig_port); } #define port_tc_name(port) ((port) - PORT_TC1 + '1') diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index f41fdc376a51..632391197937 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1666,6 +1666,7 @@ struct intel_digital_port { struct mutex tc_lock; /* protects the TypeC port mode */ intel_wakeref_t tc_lock_wakeref; enum intel_display_power_domain tc_lock_power_domain; + struct delayed_work tc_disconnect_phy_work; int tc_link_refcount; bool tc_legacy_port:1; char tc_port_name[8]; diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 9367770de5d7..66cb321a4488 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -666,6 +666,13 @@ static void intel_tc_port_update_mode(struct intel_digital_port *dig_port, intel_tc_port_reset_mode(dig_port, required_lanes, force_disconnect); + /* Get power domain matching the new mode after reset. */ + tc_cold_unblock(dig_port, dig_port->tc_lock_power_domain, + fetch_and_zero(&dig_port->tc_lock_wakeref)); + if (dig_port->tc_mode != TC_PORT_DISCONNECTED) + dig_port->tc_lock_wakeref = tc_cold_block(dig_port, + &dig_port->tc_lock_power_domain); + tc_cold_unblock(dig_port, domain, wref); } @@ -693,6 +700,7 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port) active_links = to_intel_crtc(encoder->base.crtc)->active; drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED); + drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref); if (active_links) { enum intel_display_power_domain domain; intel_wakeref_t tc_cold_wref = tc_cold_block(dig_port, &domain); @@ -705,6 +713,9 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port) dig_port->tc_port_name, active_links); intel_tc_port_link_init_refcount(dig_port, active_links); + dig_port->tc_lock_wakeref = tc_cold_block(dig_port, + &dig_port->tc_lock_power_domain); + tc_cold_unblock(dig_port, domain, tc_cold_wref); } @@ -745,56 +756,67 @@ bool intel_tc_port_connected(struct intel_encoder *encoder) } static void __intel_tc_port_lock(struct intel_digital_port *dig_port, - int required_lanes, bool force_disconnect) + int required_lanes) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - intel_wakeref_t wakeref; - - wakeref = intel_display_power_get(i915, POWER_DOMAIN_DISPLAY_CORE); mutex_lock(&dig_port->tc_lock); + cancel_delayed_work(&dig_port->tc_disconnect_phy_work); if (!dig_port->tc_link_refcount) intel_tc_port_update_mode(dig_port, required_lanes, - force_disconnect); + false); - drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref); - dig_port->tc_lock_wakeref = wakeref; + drm_WARN_ON(&i915->drm, dig_port->tc_mode == TC_PORT_DISCONNECTED); + drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_TBT_ALT && + !tc_phy_is_owned(dig_port)); } void intel_tc_port_lock(struct intel_digital_port *dig_port) { - __intel_tc_port_lock(dig_port, 1, false); + __intel_tc_port_lock(dig_port, 1); } -void intel_tc_port_unlock(struct intel_digital_port *dig_port) +/** + * intel_tc_port_disconnect_phy_work: disconnect TypeC PHY from display port + * @dig_port: digital port + * + * Disconnect the given digital port from its TypeC PHY (handing back the + * control of the PHY to the TypeC subsystem). This will happen in a delayed + * manner after each aux transactions and modeset disables. + */ +static void intel_tc_port_disconnect_phy_work(struct work_struct *work) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - intel_wakeref_t wakeref = fetch_and_zero(&dig_port->tc_lock_wakeref); + struct intel_digital_port *dig_port = + container_of(work, struct intel_digital_port, tc_disconnect_phy_work.work); - mutex_unlock(&dig_port->tc_lock); + mutex_lock(&dig_port->tc_lock); - intel_display_power_put_async(i915, POWER_DOMAIN_DISPLAY_CORE, - wakeref); + if (!dig_port->tc_link_refcount) + intel_tc_port_update_mode(dig_port, 1, true); + + mutex_unlock(&dig_port->tc_lock); } /** - * intel_tc_port_disconnect_phy: disconnect TypeC PHY from display port + * intel_tc_port_flush_work: flush the work disconnecting the PHY * @dig_port: digital port * - * Disconnect the given digital port from its TypeC PHY (handing back the - * control of the PHY to the TypeC subsystem). The only purpose of this - * function is to force the disconnect even with a TypeC display output still - * plugged to the TypeC connector, which is required by the TypeC firmwares - * during system suspend and shutdown. Otherwise - during the unplug event - * handling - the PHY ownership is released automatically by - * intel_tc_port_reset_mode(), when calling this function is not required. + * Flush the delayed work disconnecting an idle PHY. */ -void intel_tc_port_disconnect_phy(struct intel_digital_port *dig_port) +void intel_tc_port_flush_work(struct intel_digital_port *dig_port) { - __intel_tc_port_lock(dig_port, 1, true); - intel_tc_port_unlock(dig_port); + flush_delayed_work(&dig_port->tc_disconnect_phy_work); +} + +void intel_tc_port_unlock(struct intel_digital_port *dig_port) +{ + if (!dig_port->tc_link_refcount && dig_port->tc_mode != TC_PORT_DISCONNECTED) + queue_delayed_work(system_unbound_wq, &dig_port->tc_disconnect_phy_work, + msecs_to_jiffies(1000)); + + mutex_unlock(&dig_port->tc_lock); } bool intel_tc_port_ref_held(struct intel_digital_port *dig_port) @@ -806,16 +828,16 @@ bool intel_tc_port_ref_held(struct intel_digital_port *dig_port) void intel_tc_port_get_link(struct intel_digital_port *dig_port, int required_lanes) { - __intel_tc_port_lock(dig_port, required_lanes, false); + __intel_tc_port_lock(dig_port, required_lanes); dig_port->tc_link_refcount++; intel_tc_port_unlock(dig_port); } void intel_tc_port_put_link(struct intel_digital_port *dig_port) { - mutex_lock(&dig_port->tc_lock); - dig_port->tc_link_refcount--; - mutex_unlock(&dig_port->tc_lock); + intel_tc_port_lock(dig_port); + --dig_port->tc_link_refcount; + intel_tc_port_unlock(dig_port); } static bool @@ -871,6 +893,7 @@ void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) "%c/TC#%d", port_name(port), tc_port + 1); mutex_init(&dig_port->tc_lock); + INIT_DELAYED_WORK(&dig_port->tc_disconnect_phy_work, intel_tc_port_disconnect_phy_work); dig_port->tc_legacy_port = is_legacy; dig_port->tc_mode = TC_PORT_DISCONNECTED; dig_port->tc_link_refcount = 0; diff --git a/drivers/gpu/drm/i915/display/intel_tc.h b/drivers/gpu/drm/i915/display/intel_tc.h index 0fdcddb4fc87..6b47b29f551c 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.h +++ b/drivers/gpu/drm/i915/display/intel_tc.h @@ -17,7 +17,6 @@ bool intel_tc_port_in_dp_alt_mode(struct intel_digital_port *dig_port); bool intel_tc_port_in_legacy_mode(struct intel_digital_port *dig_port); bool intel_tc_port_connected(struct intel_encoder *encoder); -void intel_tc_port_disconnect_phy(struct intel_digital_port *dig_port); u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port); u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port); @@ -28,6 +27,7 @@ void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port, void intel_tc_port_sanitize(struct intel_digital_port *dig_port); void intel_tc_port_lock(struct intel_digital_port *dig_port); void intel_tc_port_unlock(struct intel_digital_port *dig_port); +void intel_tc_port_flush_work(struct intel_digital_port *dig_port); void intel_tc_port_get_link(struct intel_digital_port *dig_port, int required_lanes); void intel_tc_port_put_link(struct intel_digital_port *dig_port); -- cgit v1.2.3 From ff67c4c0dd67b6dbb78a0d045100dd2f9dee88b0 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 21 Sep 2021 03:23:12 +0300 Subject: drm/i915/tc: Drop extra TC cold blocking from intel_tc_port_connected() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the previous patch the driver holds a power domain blocking TC-cold whenever the port is locked, so we can remove the extra blocking around the lock/unlock sequence. Cc: José Roberto de Souza Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210921002313.1132357-13-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 66cb321a4488..4a14db604cba 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -740,16 +740,12 @@ bool intel_tc_port_connected(struct intel_encoder *encoder) { struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_connected; - enum intel_display_power_domain domain; - intel_wakeref_t tc_cold_wref; intel_tc_port_lock(dig_port); - tc_cold_wref = tc_cold_block(dig_port, &domain); is_connected = tc_port_live_status_mask(dig_port) & BIT(dig_port->tc_mode); - tc_cold_unblock(dig_port, domain, tc_cold_wref); intel_tc_port_unlock(dig_port); return is_connected; -- cgit v1.2.3 From b58a88682093b3438dad66f2c3d3a4d0a20ee1e8 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 29 Sep 2021 16:28:33 +0300 Subject: drm/i915/tc: Fix system hang on ADL-P during TypeC PHY disconnect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PHY ownership release->AUX PW disable steps during a modeset disable->PHY disconnect sequence can hang the system if the PHY disconnect happens after disabling the PHY's PLL. The spec doesn't require a specific order for these two steps, so this issue is still being root caused by HW/FW teams. Until that is found, let's make sure the disconnect happens before the PLL is disabled, and do this on all platforms for consistency. v2: Add a TODO comment to remove the w/a once the issue is root caused/fixed. (Jose) Cc: José Roberto de Souza Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210929132833.2253961-7-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 4a14db604cba..40faa18947c9 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -834,6 +834,14 @@ void intel_tc_port_put_link(struct intel_digital_port *dig_port) intel_tc_port_lock(dig_port); --dig_port->tc_link_refcount; intel_tc_port_unlock(dig_port); + + /* + * Disconnecting the PHY after the PHY's PLL gets disabled may + * hang the system on ADL-P, so disconnect the PHY here synchronously. + * TODO: remove this once the root cause of the ordering requirement + * is found/fixed. + */ + intel_tc_port_flush_work(dig_port); } static bool -- cgit v1.2.3 From 082436068c19316d5153229fd1b48dceccd0efee Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 23 Sep 2021 23:01:04 +0300 Subject: drm/i915: Extract intel_panel_mode_valid() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract intel_panel_mode_valid() from the eDP code to a generic helper. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210923200109.4459-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 8 +++----- drivers/gpu/drm/i915/display/intel_panel.c | 18 ++++++++++++++++++ drivers/gpu/drm/i915/display/intel_panel.h | 3 +++ 3 files changed, 24 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 378008873e03..2b8b495fc2a9 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -845,11 +845,9 @@ intel_dp_mode_valid(struct drm_connector *connector, return MODE_H_ILLEGAL; if (intel_dp_is_edp(intel_dp) && fixed_mode) { - if (mode->hdisplay != fixed_mode->hdisplay) - return MODE_PANEL; - - if (mode->vdisplay != fixed_mode->vdisplay) - return MODE_PANEL; + status = intel_panel_mode_valid(intel_connector, mode); + if (status != MODE_OK) + return status; target_clock = fixed_mode->clock; } diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index 4804b6b86798..8a364bb1ce41 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -482,6 +482,24 @@ intel_panel_detect(struct drm_connector *connector, bool force) return connector_status_connected; } +enum drm_mode_status +intel_panel_mode_valid(struct intel_connector *connector, + const struct drm_display_mode *mode) +{ + const struct drm_display_mode *fixed_mode = connector->panel.fixed_mode; + + if (!fixed_mode) + return MODE_OK; + + if (mode->hdisplay != fixed_mode->hdisplay) + return MODE_PANEL; + + if (mode->vdisplay != fixed_mode->vdisplay) + return MODE_PANEL; + + return MODE_OK; +} + int intel_panel_init(struct intel_panel *panel, struct drm_display_mode *fixed_mode, struct drm_display_mode *downclock_mode) diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_panel.h index f6af1a98290c..71bad6d546fa 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.h +++ b/drivers/gpu/drm/i915/display/intel_panel.h @@ -26,6 +26,9 @@ intel_panel_detect(struct drm_connector *connector, bool force); bool intel_panel_use_ssc(struct drm_i915_private *i915); void intel_panel_fixed_mode(const struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode); +enum drm_mode_status +intel_panel_mode_valid(struct intel_connector *connector, + const struct drm_display_mode *mode); int intel_panel_fitting(struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); struct drm_display_mode * -- cgit v1.2.3 From 8a567b1102270bd1bbbd6686cfe859aa891648b9 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 23 Sep 2021 23:01:05 +0300 Subject: drm/i915: Use intel_panel_mode_valid() for DSI/LVDS/(s)DVO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All fixed mode panels should behave the same way when it comes to mode filtering. Reuse the intel_panel_mode_valid() for all of them. This changes the behaviour to match what we do for eDP, ie. reject anything that doesn't exactly match the fixed mode dimensions. Users can still manually provide different sized modes which will be handled by the panel fitter just as before. The difference is that we can no longer report funny modes in the connector's mode list. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210923200109.4459-3-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dsi.c | 11 +++++++---- drivers/gpu/drm/i915/display/intel_dvo.c | 14 ++++++++------ drivers/gpu/drm/i915/display/intel_lvds.c | 10 ++++++---- drivers/gpu/drm/i915/display/intel_sdvo.c | 12 ++++-------- 4 files changed, 25 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c index f453ceb8d149..6f1171112a3a 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi.c +++ b/drivers/gpu/drm/i915/display/intel_dsi.c @@ -5,6 +5,7 @@ #include #include "intel_dsi.h" +#include "intel_panel.h" int intel_dsi_bitrate(const struct intel_dsi *intel_dsi) { @@ -67,10 +68,12 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector, return MODE_NO_DBLESCAN; if (fixed_mode) { - if (mode->hdisplay > fixed_mode->hdisplay) - return MODE_PANEL; - if (mode->vdisplay > fixed_mode->vdisplay) - return MODE_PANEL; + enum drm_mode_status status; + + status = intel_panel_mode_valid(intel_connector, mode); + if (status != MODE_OK) + return status; + if (fixed_mode->clock > max_dotclk) return MODE_CLOCK_HIGH; } diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c index 86c903e9df60..f8fdc0386fd4 100644 --- a/drivers/gpu/drm/i915/display/intel_dvo.c +++ b/drivers/gpu/drm/i915/display/intel_dvo.c @@ -223,9 +223,10 @@ static enum drm_mode_status intel_dvo_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct intel_dvo *intel_dvo = intel_attached_dvo(to_intel_connector(connector)); + struct intel_connector *intel_connector = to_intel_connector(connector); + struct intel_dvo *intel_dvo = intel_attached_dvo(intel_connector); const struct drm_display_mode *fixed_mode = - to_intel_connector(connector)->panel.fixed_mode; + intel_connector->panel.fixed_mode; int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; int target_clock = mode->clock; @@ -235,10 +236,11 @@ intel_dvo_mode_valid(struct drm_connector *connector, /* XXX: Validate clock range */ if (fixed_mode) { - if (mode->hdisplay > fixed_mode->hdisplay) - return MODE_PANEL; - if (mode->vdisplay > fixed_mode->vdisplay) - return MODE_PANEL; + enum drm_mode_status status; + + status = intel_panel_mode_valid(intel_connector, mode); + if (status != MODE_OK) + return status; target_clock = fixed_mode->clock; } diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index e9fb402708a7..37e81bc71f7c 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -389,13 +389,15 @@ intel_lvds_mode_valid(struct drm_connector *connector, struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; int max_pixclk = to_i915(connector->dev)->max_dotclk_freq; + enum drm_mode_status status; if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; - if (mode->hdisplay > fixed_mode->hdisplay) - return MODE_PANEL; - if (mode->vdisplay > fixed_mode->vdisplay) - return MODE_PANEL; + + status = intel_panel_mode_valid(intel_connector, mode); + if (status != MODE_OK) + return status; + if (fixed_mode->clock > max_pixclk) return MODE_CLOCK_HIGH; diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index 6cb27599ea03..fe0ea1db4cf1 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -1873,7 +1873,6 @@ intel_sdvo_mode_valid(struct drm_connector *connector, if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; - if (clock > max_dotclk) return MODE_CLOCK_HIGH; @@ -1890,14 +1889,11 @@ intel_sdvo_mode_valid(struct drm_connector *connector, return MODE_CLOCK_HIGH; if (IS_LVDS(intel_sdvo_connector)) { - const struct drm_display_mode *fixed_mode = - intel_sdvo_connector->base.panel.fixed_mode; - - if (mode->hdisplay > fixed_mode->hdisplay) - return MODE_PANEL; + enum drm_mode_status status; - if (mode->vdisplay > fixed_mode->vdisplay) - return MODE_PANEL; + status = intel_panel_mode_valid(&intel_sdvo_connector->base, mode); + if (status != MODE_OK) + return status; } return MODE_OK; -- cgit v1.2.3 From 00fc3787d277299c39a7c35290e79375c6de9f24 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 23 Sep 2021 23:01:06 +0300 Subject: drm/i915: Reject modes that don't match fixed_mode vrefresh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using a fixed mode we won't change the refresh rate ever. So filter out all modes that don't match the fixed_mode's refresh rate. I'm going to declare the "rounded to nearest Hz refresh rates must match" approach good enough for now. Note that we could start supporting multiple refresh rates with panels that can do it, but that would mean replacing the single fixed mode concept with a list of fixed modes. Then we could look for the closest match to the user's requested refresh rate and use that. But all of that would be a fair bit of work so we'll leave it for later. References: https://gitlab.freedesktop.org/drm/intel/-/issues/2939 References: https://gitlab.freedesktop.org/drm/intel/-/issues/3969 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210923200109.4459-4-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_panel.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index 8a364bb1ce41..b2ad0f065218 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -497,6 +497,9 @@ intel_panel_mode_valid(struct intel_connector *connector, if (mode->vdisplay != fixed_mode->vdisplay) return MODE_PANEL; + if (drm_mode_vrefresh(mode) != drm_mode_vrefresh(fixed_mode)) + return MODE_PANEL; + return MODE_OK; } -- cgit v1.2.3 From cff4c2c645cbb3e95d7aec9afb1a803dd2668ec7 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 27 Sep 2021 21:52:07 +0300 Subject: drm/i915: Introduce intel_panel_compute_config() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's introduce a compute_config() helper for fixed mode panels. For now all it does is the fixed_mode->adjusted_mode copy. Note that with sDVO we have to ask the external encoder chip to spit out our actual display timings for us, so the fixed_mode to adjusted_mode copy done by intel_panel_compute_config() is redundant, but we still want to use it to do other checks for us later. We'll be fine so long as we only call it before intel_sdvo_get_preferred_input_mode() overwrites adjusted_mode with the timings from the encoder. v2: Use intel_panel_compute_config() with sDVO Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210927185207.13620-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/icl_dsi.c | 7 ++++--- drivers/gpu/drm/i915/display/intel_dp.c | 5 +++-- drivers/gpu/drm/i915/display/intel_dvo.c | 10 ++++++++-- drivers/gpu/drm/i915/display/intel_lvds.c | 5 +++-- drivers/gpu/drm/i915/display/intel_panel.c | 11 +++++++++-- drivers/gpu/drm/i915/display/intel_panel.h | 2 ++ drivers/gpu/drm/i915/display/intel_sdvo.c | 7 +++++++ drivers/gpu/drm/i915/display/vlv_dsi.c | 4 +++- 8 files changed, 39 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index bd210166b079..c196993f0d68 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1672,14 +1672,15 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder, struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi, base); struct intel_connector *intel_connector = intel_dsi->attached_connector; - const struct drm_display_mode *fixed_mode = - intel_connector->panel.fixed_mode; struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; int ret; pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; - intel_panel_fixed_mode(fixed_mode, adjusted_mode); + + ret = intel_panel_compute_config(intel_connector, adjusted_mode); + if (ret) + return ret; ret = intel_panel_fitting(pipe_config, conn_state); if (ret) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 2b8b495fc2a9..b5cd188ca520 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1757,8 +1757,9 @@ intel_dp_compute_config(struct intel_encoder *encoder, pipe_config->has_audio = intel_conn_state->force_audio == HDMI_AUDIO_ON; if (intel_dp_is_edp(intel_dp) && intel_connector->panel.fixed_mode) { - intel_panel_fixed_mode(intel_connector->panel.fixed_mode, - adjusted_mode); + ret = intel_panel_compute_config(intel_connector, adjusted_mode); + if (ret) + return ret; ret = intel_panel_fitting(pipe_config, conn_state); if (ret) diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c index f8fdc0386fd4..2eeb209afc64 100644 --- a/drivers/gpu/drm/i915/display/intel_dvo.c +++ b/drivers/gpu/drm/i915/display/intel_dvo.c @@ -256,6 +256,7 @@ static int intel_dvo_compute_config(struct intel_encoder *encoder, struct drm_connector_state *conn_state) { struct intel_dvo *intel_dvo = enc_to_dvo(encoder); + struct intel_connector *connector = to_intel_connector(conn_state->connector); const struct drm_display_mode *fixed_mode = intel_dvo->attached_connector->panel.fixed_mode; struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; @@ -266,8 +267,13 @@ static int intel_dvo_compute_config(struct intel_encoder *encoder, * with the panel scaling set up to source from the H/VDisplay * of the original mode. */ - if (fixed_mode) - intel_panel_fixed_mode(fixed_mode, adjusted_mode); + if (fixed_mode) { + int ret; + + ret = intel_panel_compute_config(connector, adjusted_mode); + if (ret) + return ret; + } if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) return -EINVAL; diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 37e81bc71f7c..130e6ea61e11 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -444,8 +444,9 @@ static int intel_lvds_compute_config(struct intel_encoder *intel_encoder, * with the panel scaling set up to source from the H/VDisplay * of the original mode. */ - intel_panel_fixed_mode(intel_connector->panel.fixed_mode, - adjusted_mode); + ret = intel_panel_compute_config(intel_connector, adjusted_mode); + if (ret) + return ret; if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) return -EINVAL; diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index b2ad0f065218..77c1ca387de0 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -45,12 +45,19 @@ bool intel_panel_use_ssc(struct drm_i915_private *i915) && !(i915->quirks & QUIRK_LVDS_SSC_DISABLE); } -void intel_panel_fixed_mode(const struct drm_display_mode *fixed_mode, - struct drm_display_mode *adjusted_mode) +int intel_panel_compute_config(struct intel_connector *connector, + struct drm_display_mode *adjusted_mode) { + const struct drm_display_mode *fixed_mode = connector->panel.fixed_mode; + + if (!fixed_mode) + return 0; + drm_mode_copy(adjusted_mode, fixed_mode); drm_mode_set_crtcinfo(adjusted_mode, 0); + + return 0; } static bool is_downclock_mode(const struct drm_display_mode *downclock_mode, diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_panel.h index 71bad6d546fa..d50b3f7e9e58 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.h +++ b/drivers/gpu/drm/i915/display/intel_panel.h @@ -31,6 +31,8 @@ intel_panel_mode_valid(struct intel_connector *connector, const struct drm_display_mode *mode); int intel_panel_fitting(struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); +int intel_panel_compute_config(struct intel_connector *connector, + struct drm_display_mode *adjusted_mode); struct drm_display_mode * intel_panel_edid_downclock_mode(struct intel_connector *connector, const struct drm_display_mode *fixed_mode); diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index fe0ea1db4cf1..2dc6c3742ba2 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -1335,6 +1335,13 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder, adjusted_mode); pipe_config->sdvo_tv_clock = true; } else if (IS_LVDS(intel_sdvo_connector)) { + int ret; + + ret = intel_panel_compute_config(&intel_sdvo_connector->base, + adjusted_mode); + if (ret) + return ret; + if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, intel_sdvo_connector->base.panel.fixed_mode)) return -EINVAL; diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index b0a2b6b96799..260e852245e9 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -279,7 +279,9 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder, pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; if (fixed_mode) { - intel_panel_fixed_mode(fixed_mode, adjusted_mode); + ret = intel_panel_compute_config(intel_connector, adjusted_mode); + if (ret) + return ret; ret = intel_panel_fitting(pipe_config, conn_state); if (ret) -- cgit v1.2.3 From f5b8c316092f2501ca32ac32f5c6303e2c58ef50 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 29 Sep 2021 21:45:36 +0300 Subject: drm/i915: Reject user modes that don't match fixed mode's refresh rate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using a panel with a fixed mode we don't change the refresh rate of the display. Reject any user requested mode which doesn't match that fixed refresh rate. Unfortunately when Xorg sees the scaling_mode property on the connecor it likes to automagically cook up modes whose refresh rate is a fair bit off from the fixed refresh rate we use. So we have to give it some extra latitude so that we don't start to reject all of it. v2: sDVO now uses intel_panel_compute_config() too v3: Add a debug message to inform the user what happened References: https://gitlab.freedesktop.org/drm/intel/-/issues/2939 References: https://gitlab.freedesktop.org/drm/intel/-/issues/3969 Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210929184536.8332-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_panel.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index 77c1ca387de0..a0c8e43db5eb 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -53,6 +53,21 @@ int intel_panel_compute_config(struct intel_connector *connector, if (!fixed_mode) return 0; + /* + * We don't want to lie too much to the user about the refresh + * rate they're going to get. But we have to allow a bit of latitude + * for Xorg since it likes to automagically cook up modes with slightly + * off refresh rates. + */ + if (abs(drm_mode_vrefresh(adjusted_mode) - drm_mode_vrefresh(fixed_mode)) > 1) { + drm_dbg_kms(connector->base.dev, + "[CONNECTOR:%d:%s] Requested mode vrefresh (%d Hz) does not match fixed mode vrefresh (%d Hz)\n", + connector->base.base.id, connector->base.name, + drm_mode_vrefresh(adjusted_mode), drm_mode_vrefresh(fixed_mode)); + + return -EINVAL; + } + drm_mode_copy(adjusted_mode, fixed_mode); drm_mode_set_crtcinfo(adjusted_mode, 0); -- cgit v1.2.3 From 7eadfbfe0f3bf5aad18133b7d1856778e1896b9f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 23 Sep 2021 23:01:09 +0300 Subject: drm/i915: Drop pointless fixed_mode checks from dsi code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't support dsi displays without a fixed mode, so drop all the pointless checks. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210923200109.4459-7-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dsi.c | 15 +++++------- drivers/gpu/drm/i915/display/vlv_dsi.c | 41 +++++++++++++------------------- 2 files changed, 23 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c index 6f1171112a3a..6b0301ba046e 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi.c +++ b/drivers/gpu/drm/i915/display/intel_dsi.c @@ -61,22 +61,19 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector, struct intel_connector *intel_connector = to_intel_connector(connector); const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; + enum drm_mode_status status; drm_dbg_kms(&dev_priv->drm, "\n"); if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; - if (fixed_mode) { - enum drm_mode_status status; + status = intel_panel_mode_valid(intel_connector, mode); + if (status != MODE_OK) + return status; - status = intel_panel_mode_valid(intel_connector, mode); - if (status != MODE_OK) - return status; - - if (fixed_mode->clock > max_dotclk) - return MODE_CLOCK_HIGH; - } + if (fixed_mode->clock > max_dotclk) + return MODE_CLOCK_HIGH; return intel_mode_valid_max_plane_size(dev_priv, mode, false); } diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index 260e852245e9..081b772bfe10 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -271,22 +271,19 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder, struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi, base); struct intel_connector *intel_connector = intel_dsi->attached_connector; - const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; int ret; drm_dbg_kms(&dev_priv->drm, "\n"); pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; - if (fixed_mode) { - ret = intel_panel_compute_config(intel_connector, adjusted_mode); - if (ret) - return ret; + ret = intel_panel_compute_config(intel_connector, adjusted_mode); + if (ret) + return ret; - ret = intel_panel_fitting(pipe_config, conn_state); - if (ret) - return ret; - } + ret = intel_panel_fitting(pipe_config, conn_state); + if (ret) + return ret; if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) return -EINVAL; @@ -1633,25 +1630,21 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = { static void vlv_dsi_add_properties(struct intel_connector *connector) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + u32 allowed_scalers; - if (connector->panel.fixed_mode) { - u32 allowed_scalers; - - allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT) | BIT(DRM_MODE_SCALE_FULLSCREEN); - if (!HAS_GMCH(dev_priv)) - allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER); + allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT) | BIT(DRM_MODE_SCALE_FULLSCREEN); + if (!HAS_GMCH(dev_priv)) + allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER); - drm_connector_attach_scaling_mode_property(&connector->base, - allowed_scalers); + drm_connector_attach_scaling_mode_property(&connector->base, + allowed_scalers); - connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT; + connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT; - drm_connector_set_panel_orientation_with_quirk( - &connector->base, - intel_dsi_get_panel_orientation(connector), - connector->panel.fixed_mode->hdisplay, - connector->panel.fixed_mode->vdisplay); - } + drm_connector_set_panel_orientation_with_quirk(&connector->base, + intel_dsi_get_panel_orientation(connector), + connector->panel.fixed_mode->hdisplay, + connector->panel.fixed_mode->vdisplay); } #define NS_KHZ_RATIO 1000000 -- cgit v1.2.3 From 1e39da5a200b7ffe2a157e95b33005cacc351cf1 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 29 Sep 2021 19:24:04 +0300 Subject: drm/i915: Enable TPS3/4 on all platforms that support them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop using HBR2/3 support as a proxy for TPS3/4 support. The two are no longer 1:1 in the hardware, arguably they never were due to HSW ULX which does support TPS3 while being limited to HBR1. In more recent times GLK gained support for TPS4 while being limited to HBR2. And on CNL+ some ports support HBR3 while others are limited to HBR2, but all ports support TPS4. v2: s/INTEL_GEN/DISPLAY_VER/ Reviewed-by: Manasi Navare Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210929162404.6717-1-ville.syrjala@linux.intel.com Acked-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp.c | 12 +++------ drivers/gpu/drm/i915/display/intel_dp.h | 4 +-- .../gpu/drm/i915/display/intel_dp_link_training.c | 30 +++++++++++----------- drivers/gpu/drm/i915/display/intel_psr.c | 2 +- 4 files changed, 22 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index b5cd188ca520..8f5a935b72b6 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -927,18 +927,14 @@ intel_dp_mode_valid(struct drm_connector *connector, return intel_mode_valid_max_plane_size(dev_priv, mode, bigjoiner); } -bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp) +bool intel_dp_source_supports_tps3(struct drm_i915_private *i915) { - int max_rate = intel_dp->source_rates[intel_dp->num_source_rates - 1]; - - return max_rate >= 540000; + return DISPLAY_VER(i915) >= 9 || IS_BROADWELL(i915) || IS_HASWELL(i915); } -bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp) +bool intel_dp_source_supports_tps4(struct drm_i915_private *i915) { - int max_rate = intel_dp->source_rates[intel_dp->num_source_rates - 1]; - - return max_rate >= 810000; + return DISPLAY_VER(i915) >= 10; } static void snprintf_int_array(char *str, size_t len, diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 3343c2591680..ce229026dc91 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -73,8 +73,8 @@ int intel_dp_rate_select(struct intel_dp *intel_dp, int rate); void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, u8 *link_bw, u8 *rate_select); -bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); -bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp); +bool intel_dp_source_supports_tps3(struct drm_i915_private *i915); +bool intel_dp_source_supports_tps4(struct drm_i915_private *i915); bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp); int intel_dp_link_required(int pixel_clock, int bpp); diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 4f116cd32846..449499a5c4c1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -611,6 +611,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, enum drm_dp_phy dp_phy) { + struct drm_i915_private *i915 = dp_to_i915(intel_dp); bool source_tps3, sink_tps3, source_tps4, sink_tps4; /* UHBR+ use separate 128b/132b TPS2 */ @@ -618,41 +619,40 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp, return DP_TRAINING_PATTERN_2; /* - * Intel platforms that support HBR3 also support TPS4. It is mandatory - * for all downstream devices that support HBR3. There are no known eDP - * panels that support TPS4 as of Feb 2018 as per VESA eDP_v1.4b_E1 - * specification. + * TPS4 support is mandatory for all downstream devices that + * support HBR3. There are no known eDP panels that support + * TPS4 as of Feb 2018 as per VESA eDP_v1.4b_E1 specification. * LTTPRs must support TPS4. */ - source_tps4 = intel_dp_source_supports_hbr3(intel_dp); + source_tps4 = intel_dp_source_supports_tps4(i915); sink_tps4 = dp_phy != DP_PHY_DPRX || drm_dp_tps4_supported(intel_dp->dpcd); if (source_tps4 && sink_tps4) { return DP_TRAINING_PATTERN_4; } else if (crtc_state->port_clock == 810000) { if (!source_tps4) - drm_dbg_kms(&dp_to_i915(intel_dp)->drm, - "8.1 Gbps link rate without source HBR3/TPS4 support\n"); + drm_dbg_kms(&i915->drm, + "8.1 Gbps link rate without source TPS4 support\n"); if (!sink_tps4) - drm_dbg_kms(&dp_to_i915(intel_dp)->drm, + drm_dbg_kms(&i915->drm, "8.1 Gbps link rate without sink TPS4 support\n"); } + /* - * Intel platforms that support HBR2 also support TPS3. TPS3 support is - * also mandatory for downstream devices that support HBR2. However, not - * all sinks follow the spec. + * TPS3 support is mandatory for downstream devices that + * support HBR2. However, not all sinks follow the spec. */ - source_tps3 = intel_dp_source_supports_hbr2(intel_dp); + source_tps3 = intel_dp_source_supports_tps3(i915); sink_tps3 = dp_phy != DP_PHY_DPRX || drm_dp_tps3_supported(intel_dp->dpcd); if (source_tps3 && sink_tps3) { return DP_TRAINING_PATTERN_3; } else if (crtc_state->port_clock >= 540000) { if (!source_tps3) - drm_dbg_kms(&dp_to_i915(intel_dp)->drm, - ">=5.4/6.48 Gbps link rate without source HBR2/TPS3 support\n"); + drm_dbg_kms(&i915->drm, + ">=5.4/6.48 Gbps link rate without source TPS3 support\n"); if (!sink_tps3) - drm_dbg_kms(&dp_to_i915(intel_dp)->drm, + drm_dbg_kms(&i915->drm, ">=5.4/6.48 Gbps link rate without sink TPS3 support\n"); } diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 19a96d3c4acf..f489bf9ca096 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -426,7 +426,7 @@ static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp) val |= EDP_PSR_TP2_TP3_TIME_2500us; check_tp3_sel: - if (intel_dp_source_supports_hbr2(intel_dp) && + if (intel_dp_source_supports_tps3(dev_priv) && drm_dp_tps3_supported(intel_dp->dpcd)) val |= EDP_PSR_TP1_TP3_SEL; else -- cgit v1.2.3 From 2709abc8d14a1e67d8ecc81abc33d7119fe3dabc Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 24 Sep 2021 17:13:30 +0300 Subject: drm/i915/fbc: Allow FBC with Yf tiling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FBC+Yf tiling seems to work just fine, and unlike with linear the hardware does appear to correctly calculate the CFB stride with using the override stride on both cfl and glk. So no need for any additional tweaks. Cc: Uma Shankar #v2 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210924141330.1515-1-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/display/intel_fbc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 46f62fdf9eee..687431faf02f 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -746,6 +746,7 @@ static bool tiling_is_valid(struct drm_i915_private *dev_priv, switch (modifier) { case DRM_FORMAT_MOD_LINEAR: case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Yf_TILED: return DISPLAY_VER(dev_priv) >= 9; case I915_FORMAT_MOD_X_TILED: return true; -- cgit v1.2.3 From a471a526bc38347ab9fa6b07f399e2172d88536e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 13 Sep 2021 17:44:33 +0300 Subject: drm/i915: Pimp HSW+ transcoder state readout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adjust the HSW+ transcoder state readout to just read through all the possible transcoders for the pipe, and stuff the results in a bitmask. We can conveniently cross check the bitmask for invalid combinations of enabled transcoders, and later we can easily extend the bitmask readout to handle the bigjoiner case. One slight change in behaviour is that we no longer read out the AONOFF->force_pfit.pfit bit for all the enabled "panel transcoders". But having more than one enabled would anyway be illegal so no big loss. Also the AONOFF selection should only ever be used on HSW, which only has the EDP transcoder an no DSI transcoders. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210913144440.23008-10-ville.syrjala@linux.intel.com Reviewed-by: Manasi Navare --- drivers/gpu/drm/i915/display/intel_display.c | 130 +++++++++++++++++++-------- 1 file changed, 95 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 4ce80ca7751f..d731c12da718 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5724,6 +5724,21 @@ out: return ret; } +static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv, + enum transcoder cpu_transcoder) +{ + enum intel_display_power_domain power_domain; + intel_wakeref_t wakeref; + u32 tmp = 0; + + power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); + + with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) + tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); + + return tmp & TRANS_DDI_FUNC_ENABLE; +} + static u8 hsw_panel_transcoders(struct drm_i915_private *i915) { u8 panel_transcoder_mask = BIT(TRANSCODER_EDP); @@ -5734,55 +5749,39 @@ static u8 hsw_panel_transcoders(struct drm_i915_private *i915) return panel_transcoder_mask; } -static bool hsw_get_transcoder_state(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config, - struct intel_display_power_domain_set *power_domain_set) +static u8 hsw_enabled_transcoders(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); u8 panel_transcoder_mask = hsw_panel_transcoders(dev_priv); - unsigned long enabled_panel_transcoders = 0; - enum transcoder panel_transcoder; - u32 tmp; - - /* - * The pipe->transcoder mapping is fixed with the exception of the eDP - * and DSI transcoders handled below. - */ - pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; + enum transcoder cpu_transcoder; + u8 enabled_transcoders = 0; /* * XXX: Do intel_display_power_get_if_enabled before reading this (for * consistency and less surprising code; it's in always on power). */ - for_each_cpu_transcoder_masked(dev_priv, panel_transcoder, + for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, panel_transcoder_mask) { - bool force_thru = false; + enum intel_display_power_domain power_domain; + intel_wakeref_t wakeref; enum pipe trans_pipe; + u32 tmp = 0; - tmp = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(panel_transcoder)); - if (!(tmp & TRANS_DDI_FUNC_ENABLE)) - continue; + power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); + with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) + tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)); - /* - * Log all enabled ones, only use the first one. - * - * FIXME: This won't work for two separate DSI displays. - */ - enabled_panel_transcoders |= BIT(panel_transcoder); - if (enabled_panel_transcoders != BIT(panel_transcoder)) + if (!(tmp & TRANS_DDI_FUNC_ENABLE)) continue; switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { default: drm_WARN(dev, 1, "unknown pipe linked to transcoder %s\n", - transcoder_name(panel_transcoder)); + transcoder_name(cpu_transcoder)); fallthrough; case TRANS_DDI_EDP_INPUT_A_ONOFF: - force_thru = true; - fallthrough; case TRANS_DDI_EDP_INPUT_A_ON: trans_pipe = PIPE_A; break; @@ -5797,22 +5796,83 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, break; } - if (trans_pipe == crtc->pipe) { - pipe_config->cpu_transcoder = panel_transcoder; - pipe_config->pch_pfit.force_thru = force_thru; - } + if (trans_pipe == crtc->pipe) + enabled_transcoders |= BIT(cpu_transcoder); } + cpu_transcoder = (enum transcoder) crtc->pipe; + if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder)) + enabled_transcoders |= BIT(cpu_transcoder); + + return enabled_transcoders; +} + +static bool has_edp_transcoders(u8 enabled_transcoders) +{ + return enabled_transcoders & BIT(TRANSCODER_EDP); +} + +static bool has_dsi_transcoders(u8 enabled_transcoders) +{ + return enabled_transcoders & (BIT(TRANSCODER_DSI_0) | + BIT(TRANSCODER_DSI_1)); +} + +static bool has_pipe_transcoders(u8 enabled_transcoders) +{ + return enabled_transcoders & ~(BIT(TRANSCODER_EDP) | + BIT(TRANSCODER_DSI_0) | + BIT(TRANSCODER_DSI_1)); +} + +static void assert_enabled_transcoders(struct drm_i915_private *i915, + u8 enabled_transcoders) +{ + /* Only one type of transcoder please */ + drm_WARN_ON(&i915->drm, + has_edp_transcoders(enabled_transcoders) + + has_dsi_transcoders(enabled_transcoders) + + has_pipe_transcoders(enabled_transcoders) > 1); + + /* Only DSI transcoders can be ganged */ + drm_WARN_ON(&i915->drm, + !has_dsi_transcoders(enabled_transcoders) && + !is_power_of_2(enabled_transcoders)); +} + +static bool hsw_get_transcoder_state(struct intel_crtc *crtc, + struct intel_crtc_state *pipe_config, + struct intel_display_power_domain_set *power_domain_set) +{ + struct drm_device *dev = crtc->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + unsigned long enabled_transcoders; + u32 tmp; + + enabled_transcoders = hsw_enabled_transcoders(crtc); + if (!enabled_transcoders) + return false; + + assert_enabled_transcoders(dev_priv, enabled_transcoders); + /* - * Valid combos: none, eDP, DSI0, DSI1, DSI0+DSI1 + * With the exception of DSI we should only ever have + * a single enabled transcoder. With DSI let's just + * pick the first one. */ - drm_WARN_ON(dev, (enabled_panel_transcoders & BIT(TRANSCODER_EDP)) && - enabled_panel_transcoders != BIT(TRANSCODER_EDP)); + pipe_config->cpu_transcoder = ffs(enabled_transcoders) - 1; if (!intel_display_power_get_in_set_if_enabled(dev_priv, power_domain_set, POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder))) return false; + if (hsw_panel_transcoders(dev_priv) & BIT(pipe_config->cpu_transcoder)) { + tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder)); + + if ((tmp & TRANS_DDI_EDP_INPUT_MASK) == TRANS_DDI_EDP_INPUT_A_ONOFF) + pipe_config->pch_pfit.force_thru = true; + } + tmp = intel_de_read(dev_priv, PIPECONF(pipe_config->cpu_transcoder)); return tmp & PIPECONF_ENABLE; -- cgit v1.2.3 From ef46972ac8518caf8c8409b750f4728ba8b820ea Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 13 Sep 2021 17:44:34 +0300 Subject: drm/i915: Configure TRANSCONF just the once with bigjoiner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's not configure the single transcoder's TRANSCONF multiple times with bigjoiner. No real harm I suppose but since we already have the bigjoiner if statement directly above might as well suck this in there and skip the redundant programming. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210913144440.23008-11-ville.syrjala@linux.intel.com Reviewed-by: Manasi Navare --- drivers/gpu/drm/i915/display/intel_display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d731c12da718..a4453dd1bb51 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3215,10 +3215,9 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, &new_crtc_state->fdi_m_n, NULL); hsw_set_frame_start_delay(new_crtc_state); - } - if (!transcoder_is_dsi(cpu_transcoder)) hsw_set_transconf(new_crtc_state); + } crtc->active = true; -- cgit v1.2.3 From f0b6b01b3efe74afd2de59c894105e13b121a01e Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 29 Sep 2021 10:59:50 +0200 Subject: drm/i915: Add ww context to intel_dpt_pin, v2. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure i915_vma_pin_iomap and vma_unpin are done with dpt->obj lock held. I don't think there's much of a point in merging intel_dpt_pin() with intel_pin_fb_obj_dpt(), they touch different objects. Changes since v1: - Fix using the wrong pointer to retrieve error code (Julia) Signed-off-by: Maarten Lankhorst Reported-by: kernel test robot Reported-by: Julia Lawall Reviewed-by: Thomas Hellström Link: https://patchwork.freedesktop.org/patch/msgid/20210929085950.3063191-1-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/display/intel_dpt.c | 40 ++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index de62bd77b15e..8f7b1f7534a4 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -121,32 +121,42 @@ struct i915_vma *intel_dpt_pin(struct i915_address_space *vm) intel_wakeref_t wakeref; struct i915_vma *vma; void __iomem *iomem; + struct i915_gem_ww_ctx ww; + int err; wakeref = intel_runtime_pm_get(&i915->runtime_pm); atomic_inc(&i915->gpu_error.pending_fb_pin); - vma = i915_gem_object_ggtt_pin(dpt->obj, NULL, 0, 4096, - HAS_LMEM(i915) ? 0 : PIN_MAPPABLE); - if (IS_ERR(vma)) - goto err; + for_i915_gem_ww(&ww, err, true) { + err = i915_gem_object_lock(dpt->obj, &ww); + if (err) + continue; - iomem = i915_vma_pin_iomap(vma); - i915_vma_unpin(vma); - if (IS_ERR(iomem)) { - vma = ERR_CAST(iomem); - goto err; - } + vma = i915_gem_object_ggtt_pin_ww(dpt->obj, &ww, NULL, 0, 4096, + HAS_LMEM(i915) ? 0 : PIN_MAPPABLE); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + continue; + } + + iomem = i915_vma_pin_iomap(vma); + i915_vma_unpin(vma); - dpt->vma = vma; - dpt->iomem = iomem; + if (IS_ERR(iomem)) { + err = PTR_ERR(iomem); + continue; + } - i915_vma_get(vma); + dpt->vma = vma; + dpt->iomem = iomem; + + i915_vma_get(vma); + } -err: atomic_dec(&i915->gpu_error.pending_fb_pin); intel_runtime_pm_put(&i915->runtime_pm, wakeref); - return vma; + return err ? ERR_PTR(err) : vma; } void intel_dpt_unpin(struct i915_address_space *vm) -- cgit v1.2.3 From 4378daf5d04eed59724e6d0e74755e17dce2e105 Mon Sep 17 00:00:00 2001 From: Lukasz Majczak Date: Thu, 30 Sep 2021 15:46:06 +0200 Subject: drm/i915/bdb: Fix version check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With patch "drm/i915/vbt: Fix backlight parsing for VBT 234+" the size of bdb_lfp_backlight_data structure has been increased, causing if-statement in the parse_lfp_backlight function that comapres this structure size to the one retrieved from BDB, always to fail for older revisions. This patch calculates expected size of the structure for a given BDB version and compares it with the value gathered from BDB. Tested on Chromebook Pixelbook (Nocturne) (reports bdb->version = 221) Fixes: d381baad29b4 ("drm/i915/vbt: Fix backlight parsing for VBT 234+") Tested-by: Lukasz Majczak Signed-off-by: Lukasz Majczak Reviewed-by: José Roberto de Souza Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210930134606.227234-1-lma@semihalf.com --- drivers/gpu/drm/i915/display/intel_bios.c | 22 ++++++++++++++++------ drivers/gpu/drm/i915/display/intel_vbt_defs.h | 5 +++++ 2 files changed, 21 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 3c25926092de..f9776ca85de3 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -451,13 +451,23 @@ parse_lfp_backlight(struct drm_i915_private *i915, } i915->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI; - if (bdb->version >= 191 && - get_blocksize(backlight_data) >= sizeof(*backlight_data)) { - const struct lfp_backlight_control_method *method; + if (bdb->version >= 191) { + size_t exp_size; - method = &backlight_data->backlight_control[panel_type]; - i915->vbt.backlight.type = method->type; - i915->vbt.backlight.controller = method->controller; + if (bdb->version >= 236) + exp_size = sizeof(struct bdb_lfp_backlight_data); + else if (bdb->version >= 234) + exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234; + else + exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191; + + if (get_blocksize(backlight_data) >= exp_size) { + const struct lfp_backlight_control_method *method; + + method = &backlight_data->backlight_control[panel_type]; + i915->vbt.backlight.type = method->type; + i915->vbt.backlight.controller = method->controller; + } } i915->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz; diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h index 330077c2e588..a2108a8f544d 100644 --- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h +++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h @@ -814,6 +814,11 @@ struct lfp_brightness_level { u16 reserved; } __packed; +#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \ + offsetof(struct bdb_lfp_backlight_data, brightness_level) +#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \ + offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits) + struct bdb_lfp_backlight_data { u8 entry_size; struct lfp_backlight_data_entry data[16]; -- cgit v1.2.3 From 1e9ae61d172f92863c84e5745cc59d485f92bdea Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 30 Sep 2021 16:43:07 +0300 Subject: drm/i915: Clear leftover DP vswing/preemphasis values before modeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we clear the leftover vswing/preemphasis values only at the start of link training. That means the initial vswing programming performed during modeset is going to use stale values left over from the previous link training sequence, and then at the start of link training we're going to reset the levels back to 0. Seems much better to make sure we start with level 0 from the get go. Additionally if LTTPRs are present the leftover vswing/preemphasis values are those of the last link in the chain, so not the values that our PHY is even using after a successful link training sequence. So let's make sure everything is cleared up before we start programming anything. Suggested-by: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210930134310.31669-1-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_dp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 8f5a935b72b6..74a657ae131a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1835,6 +1835,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, void intel_dp_set_link_params(struct intel_dp *intel_dp, int link_rate, int lane_count) { + memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); intel_dp->link_trained = false; intel_dp->link_rate = link_rate; intel_dp->lane_count = lane_count; -- cgit v1.2.3 From 9f620f1dde3e3e984837163d7930dc4b2abffe82 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 30 Sep 2021 16:43:08 +0300 Subject: drm/i915: Call intel_ddi_init_dp_buf_reg() earlier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I want intel_dp->DP to be fully populated by the time the initial vswing programming happens. To that end move the intel_ddi_init_dp_buf_reg() call to an earlier spot. Additionally we don't want intel_ddi_init_dp_buf_reg() to set DDI_BUF_CTL_ENABLE since the port should only get enabled at the start of link training (see intel_ddi_prepare_link_retrain()). So any earlier write to the register should not set the enable bit. Cc: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210930134310.31669-2-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_ddi.c | 44 +++++++++++++++----------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 51d07e9af9f3..65e59f16879d 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -282,9 +282,10 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, struct intel_digital_port *dig_port = enc_to_dig_port(encoder); enum phy phy = intel_port_to_phy(i915, encoder->port); + /* DDI_BUF_CTL_ENABLE will be set by intel_ddi_prepare_link_retrain() later */ intel_dp->DP = dig_port->saved_port_bits | - DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0); - intel_dp->DP |= DDI_PORT_WIDTH(crtc_state->lane_count); + DDI_PORT_WIDTH(crtc_state->lane_count) | + DDI_BUF_TRANS_SELECT(0); if (IS_ALDERLAKE_P(i915) && intel_phy_is_tc(i915, phy)) { intel_dp->DP |= ddi_buf_phy_link_rate(crtc_state->port_clock); @@ -2360,6 +2361,12 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_dp_set_link_params(intel_dp, crtc_state->port_clock, crtc_state->lane_count); + /* + * We only configure what the register value will be here. Actual + * enabling happens during link training farther down. + */ + intel_ddi_init_dp_buf_reg(encoder, crtc_state); + /* * 1. Enable Power Wells * @@ -2416,16 +2423,6 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state, /* 5.e Configure voltage swing and related IO settings */ intel_snps_phy_ddi_vswing_sequence(encoder, crtc_state, level); - /* - * 5.f Configure and enable DDI_BUF_CTL - * 5.g Wait for DDI_BUF_CTL DDI Idle Status = 0b (Not Idle), timeout - * after 1200 us. - * - * We only configure what the register value will be here. Actual - * enabling happens during link training farther down. - */ - intel_ddi_init_dp_buf_reg(encoder, crtc_state); - if (!is_mst) intel_dp_set_power(intel_dp, DP_SET_POWER_D0); @@ -2473,6 +2470,12 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, crtc_state->port_clock, crtc_state->lane_count); + /* + * We only configure what the register value will be here. Actual + * enabling happens during link training farther down. + */ + intel_ddi_init_dp_buf_reg(encoder, crtc_state); + /* * 1. Enable Power Wells * @@ -2554,16 +2557,6 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, */ intel_ddi_mso_configure(crtc_state); - /* - * 7.g Configure and enable DDI_BUF_CTL - * 7.h Wait for DDI_BUF_CTL DDI Idle Status = 0b (Not Idle), timeout - * after 500 us. - * - * We only configure what the register value will be here. Actual - * enabling happens during link training farther down. - */ - intel_ddi_init_dp_buf_reg(encoder, crtc_state); - if (!is_mst) intel_dp_set_power(intel_dp, DP_SET_POWER_D0); @@ -2620,6 +2613,12 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, crtc_state->port_clock, crtc_state->lane_count); + /* + * We only configure what the register value will be here. Actual + * enabling happens during link training farther down. + */ + intel_ddi_init_dp_buf_reg(encoder, crtc_state); + intel_pps_on(intel_dp); intel_ddi_enable_clock(encoder, crtc_state); @@ -2641,7 +2640,6 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_power_up_lanes(encoder, crtc_state); - intel_ddi_init_dp_buf_reg(encoder, crtc_state); if (!is_mst) intel_dp_set_power(intel_dp, DP_SET_POWER_D0); intel_dp_configure_protocol_converter(intel_dp, crtc_state); -- cgit v1.2.3 From 8a1ec3f3275479292613273a7be2ac87f2a7f6e6 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 30 Sep 2021 16:43:09 +0300 Subject: drm/i915: Remove DP_PORT_EN stuff from link training code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting DP_PORT_EN in intel_dp->DP is already handled by intel_dp_enable_port() so there is no point in setting it also from the link training code. For DDI platforms a bit with that name doesn't even exist. The counterpart is DDI_BUF_CTL_ENABLE, which is already set up by intel_ddi_prepare_link_retrain(). Fortunately it is the same bit so there was no harm in doing this from the platform independent code as well. But it's just confusing when platform independent code sets platform specific bits in intel_dp->DP. Just get rid of it. Cc: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210930134310.31669-3-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 449499a5c4c1..053ed9302cda 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -499,8 +499,6 @@ intel_dp_prepare_link_train(struct intel_dp *intel_dp, DP_SET_ANSI_128B132B : DP_SET_ANSI_8B10B; drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2); - intel_dp->DP |= DP_PORT_EN; - return true; } -- cgit v1.2.3 From cbf02c50ea7cdce229cb80218a8ab2ee2b1b9c92 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 30 Sep 2021 16:43:10 +0300 Subject: drm/i915: Nuke local copies/pointers of intel_dp->DP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Get rid of the local copies and pointers of intel_dp->DP and instead just poke at it directly. Makes it much easier to see where it actually gets used/modified. Cc: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210930134310.31669-4-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/display/g4x_dp.c | 45 ++++++++++++++++------------------- 1 file changed, 20 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 8e0620ae2ed1..69a2e5ad2317 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -426,7 +426,6 @@ intel_dp_link_down(struct intel_encoder *encoder, struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); enum port port = encoder->port; - u32 DP = intel_dp->DP; if (drm_WARN_ON(&dev_priv->drm, (intel_de_read(dev_priv, intel_dp->output_reg) & @@ -437,17 +436,17 @@ intel_dp_link_down(struct intel_encoder *encoder, if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) || (HAS_PCH_CPT(dev_priv) && port != PORT_A)) { - DP &= ~DP_LINK_TRAIN_MASK_CPT; - DP |= DP_LINK_TRAIN_PAT_IDLE_CPT; + intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT; + intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE_CPT; } else { - DP &= ~DP_LINK_TRAIN_MASK; - DP |= DP_LINK_TRAIN_PAT_IDLE; + intel_dp->DP &= ~DP_LINK_TRAIN_MASK; + intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE; } - intel_de_write(dev_priv, intel_dp->output_reg, DP); + intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP); intel_de_posting_read(dev_priv, intel_dp->output_reg); - DP &= ~(DP_PORT_EN | DP_AUDIO_OUTPUT_ENABLE); - intel_de_write(dev_priv, intel_dp->output_reg, DP); + intel_dp->DP &= ~(DP_PORT_EN | DP_AUDIO_OUTPUT_ENABLE); + intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP); intel_de_posting_read(dev_priv, intel_dp->output_reg); /* @@ -464,14 +463,14 @@ intel_dp_link_down(struct intel_encoder *encoder, intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false); /* always enable with pattern 1 (as per spec) */ - DP &= ~(DP_PIPE_SEL_MASK | DP_LINK_TRAIN_MASK); - DP |= DP_PORT_EN | DP_PIPE_SEL(PIPE_A) | + intel_dp->DP &= ~(DP_PIPE_SEL_MASK | DP_LINK_TRAIN_MASK); + intel_dp->DP |= DP_PORT_EN | DP_PIPE_SEL(PIPE_A) | DP_LINK_TRAIN_PAT_1; - intel_de_write(dev_priv, intel_dp->output_reg, DP); + intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP); intel_de_posting_read(dev_priv, intel_dp->output_reg); - DP &= ~DP_PORT_EN; - intel_de_write(dev_priv, intel_dp->output_reg, DP); + intel_dp->DP &= ~DP_PORT_EN; + intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP); intel_de_posting_read(dev_priv, intel_dp->output_reg); intel_wait_for_vblank_if_active(dev_priv, PIPE_A); @@ -481,8 +480,6 @@ intel_dp_link_down(struct intel_encoder *encoder, msleep(intel_dp->pps.panel_power_down_delay); - intel_dp->DP = DP; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { intel_wakeref_t wakeref; @@ -582,19 +579,18 @@ cpt_set_link_train(struct intel_dp *intel_dp, u8 dp_train_pat) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - u32 *DP = &intel_dp->DP; - *DP &= ~DP_LINK_TRAIN_MASK_CPT; + intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT; switch (intel_dp_training_pattern_symbol(dp_train_pat)) { case DP_TRAINING_PATTERN_DISABLE: - *DP |= DP_LINK_TRAIN_OFF_CPT; + intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; break; case DP_TRAINING_PATTERN_1: - *DP |= DP_LINK_TRAIN_PAT_1_CPT; + intel_dp->DP |= DP_LINK_TRAIN_PAT_1_CPT; break; case DP_TRAINING_PATTERN_2: - *DP |= DP_LINK_TRAIN_PAT_2_CPT; + intel_dp->DP |= DP_LINK_TRAIN_PAT_2_CPT; break; default: MISSING_CASE(intel_dp_training_pattern_symbol(dp_train_pat)); @@ -611,19 +607,18 @@ g4x_set_link_train(struct intel_dp *intel_dp, u8 dp_train_pat) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - u32 *DP = &intel_dp->DP; - *DP &= ~DP_LINK_TRAIN_MASK; + intel_dp->DP &= ~DP_LINK_TRAIN_MASK; switch (intel_dp_training_pattern_symbol(dp_train_pat)) { case DP_TRAINING_PATTERN_DISABLE: - *DP |= DP_LINK_TRAIN_OFF; + intel_dp->DP |= DP_LINK_TRAIN_OFF; break; case DP_TRAINING_PATTERN_1: - *DP |= DP_LINK_TRAIN_PAT_1; + intel_dp->DP |= DP_LINK_TRAIN_PAT_1; break; case DP_TRAINING_PATTERN_2: - *DP |= DP_LINK_TRAIN_PAT_2; + intel_dp->DP |= DP_LINK_TRAIN_PAT_2; break; default: MISSING_CASE(intel_dp_training_pattern_symbol(dp_train_pat)); -- cgit v1.2.3 From e505d76404b16646a05ba63ce5b14c1b3e2f52af Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 27 Sep 2021 21:24:47 +0300 Subject: drm/i915: s/ddi_translations/trans/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "ddi_translations" is a bit too long, let's shorten it to just "trans". Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210927182455.27119-2-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_ddi.c | 92 +-- drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c | 628 ++++++++++----------- drivers/gpu/drm/i915/display/intel_snps_phy.c | 12 +- 3 files changed, 366 insertions(+), 366 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 65e59f16879d..51cd0420e00e 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -104,10 +104,10 @@ void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder, u32 iboost_bit = 0; int i, n_entries; enum port port = encoder->port; - const struct intel_ddi_buf_trans *ddi_translations; + const struct intel_ddi_buf_trans *trans; - ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) + trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; /* If we're boosting the current, set bit 31 of trans1 */ @@ -117,9 +117,9 @@ void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder, for (i = 0; i < n_entries; i++) { intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, i), - ddi_translations->entries[i].hsw.trans1 | iboost_bit); + trans->entries[i].hsw.trans1 | iboost_bit); intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, i), - ddi_translations->entries[i].hsw.trans2); + trans->entries[i].hsw.trans2); } } @@ -136,10 +136,10 @@ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, u32 iboost_bit = 0; int n_entries; enum port port = encoder->port; - const struct intel_ddi_buf_trans *ddi_translations; + const struct intel_ddi_buf_trans *trans; - ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) + trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) level = n_entries - 1; @@ -151,9 +151,9 @@ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, /* Entry 9 is for HDMI: */ intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, 9), - ddi_translations->entries[level].hsw.trans1 | iboost_bit); + trans->entries[level].hsw.trans1 | iboost_bit); intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, 9), - ddi_translations->entries[level].hsw.trans2); + trans->entries[level].hsw.trans2); } void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, @@ -971,16 +971,16 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, iboost = intel_bios_encoder_dp_boost_level(encoder->devdata); if (iboost == 0) { - const struct intel_ddi_buf_trans *ddi_translations; + const struct intel_ddi_buf_trans *trans; int n_entries; - ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) + trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) level = n_entries - 1; - iboost = ddi_translations->entries[level].hsw.i_boost; + iboost = trans->entries[level].hsw.i_boost; } /* Make sure that the requested I_boost is valid */ @@ -1000,21 +1000,21 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder, int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - const struct intel_ddi_buf_trans *ddi_translations; + const struct intel_ddi_buf_trans *trans; enum port port = encoder->port; int n_entries; - ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) + trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) level = n_entries - 1; bxt_ddi_phy_set_signal_level(dev_priv, port, - ddi_translations->entries[level].bxt.margin, - ddi_translations->entries[level].bxt.scale, - ddi_translations->entries[level].bxt.enable, - ddi_translations->entries[level].bxt.deemphasis); + trans->entries[level].bxt.margin, + trans->entries[level].bxt.scale, + trans->entries[level].bxt.enable, + trans->entries[level].bxt.deemphasis); } static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp, @@ -1051,13 +1051,13 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - const struct intel_ddi_buf_trans *ddi_translations; + const struct intel_ddi_buf_trans *trans; enum phy phy = intel_port_to_phy(dev_priv, encoder->port); int n_entries, ln; u32 val; - ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) + trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) level = n_entries - 1; @@ -1066,7 +1066,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, struct intel_dp *intel_dp = enc_to_intel_dp(encoder); val = EDP4K2K_MODE_OVRD_EN | EDP4K2K_MODE_OVRD_OPTIMIZED; - intel_dp->hobl_active = is_hobl_buf_trans(ddi_translations); + intel_dp->hobl_active = is_hobl_buf_trans(trans); intel_de_rmw(dev_priv, ICL_PORT_CL_DW10(phy), val, intel_dp->hobl_active ? val : 0); } @@ -1084,8 +1084,8 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, val = intel_de_read(dev_priv, ICL_PORT_TX_DW2_LN0(phy)); val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK | RCOMP_SCALAR_MASK); - val |= SWING_SEL_UPPER(ddi_translations->entries[level].icl.dw2_swing_sel); - val |= SWING_SEL_LOWER(ddi_translations->entries[level].icl.dw2_swing_sel); + val |= SWING_SEL_UPPER(trans->entries[level].icl.dw2_swing_sel); + val |= SWING_SEL_LOWER(trans->entries[level].icl.dw2_swing_sel); /* Program Rcomp scalar for every table entry */ val |= RCOMP_SCALAR(0x98); intel_de_write(dev_priv, ICL_PORT_TX_DW2_GRP(phy), val); @@ -1096,16 +1096,16 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, val = intel_de_read(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy)); val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK | CURSOR_COEFF_MASK); - val |= POST_CURSOR_1(ddi_translations->entries[level].icl.dw4_post_cursor_1); - val |= POST_CURSOR_2(ddi_translations->entries[level].icl.dw4_post_cursor_2); - val |= CURSOR_COEFF(ddi_translations->entries[level].icl.dw4_cursor_coeff); + val |= POST_CURSOR_1(trans->entries[level].icl.dw4_post_cursor_1); + val |= POST_CURSOR_2(trans->entries[level].icl.dw4_post_cursor_2); + val |= CURSOR_COEFF(trans->entries[level].icl.dw4_cursor_coeff); intel_de_write(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), val); } /* Program PORT_TX_DW7 */ val = intel_de_read(dev_priv, ICL_PORT_TX_DW7_LN0(phy)); val &= ~N_SCALAR_MASK; - val |= N_SCALAR(ddi_translations->entries[level].icl.dw7_n_scalar); + val |= N_SCALAR(trans->entries[level].icl.dw7_n_scalar); intel_de_write(dev_priv, ICL_PORT_TX_DW7_GRP(phy), val); } @@ -1176,15 +1176,15 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); - const struct intel_ddi_buf_trans *ddi_translations; + const struct intel_ddi_buf_trans *trans; int n_entries, ln; u32 val; if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder))) return; - ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) + trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) level = n_entries - 1; @@ -1205,13 +1205,13 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, val = intel_de_read(dev_priv, MG_TX1_SWINGCTRL(ln, tc_port)); val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK; val |= CRI_TXDEEMPH_OVERRIDE_17_12( - ddi_translations->entries[level].mg.cri_txdeemph_override_17_12); + trans->entries[level].mg.cri_txdeemph_override_17_12); intel_de_write(dev_priv, MG_TX1_SWINGCTRL(ln, tc_port), val); val = intel_de_read(dev_priv, MG_TX2_SWINGCTRL(ln, tc_port)); val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK; val |= CRI_TXDEEMPH_OVERRIDE_17_12( - ddi_translations->entries[level].mg.cri_txdeemph_override_17_12); + trans->entries[level].mg.cri_txdeemph_override_17_12); intel_de_write(dev_priv, MG_TX2_SWINGCTRL(ln, tc_port), val); } @@ -1221,9 +1221,9 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK | CRI_TXDEEMPH_OVERRIDE_5_0_MASK); val |= CRI_TXDEEMPH_OVERRIDE_5_0( - ddi_translations->entries[level].mg.cri_txdeemph_override_5_0) | + trans->entries[level].mg.cri_txdeemph_override_5_0) | CRI_TXDEEMPH_OVERRIDE_11_6( - ddi_translations->entries[level].mg.cri_txdeemph_override_11_6) | + trans->entries[level].mg.cri_txdeemph_override_11_6) | CRI_TXDEEMPH_OVERRIDE_EN; intel_de_write(dev_priv, MG_TX1_DRVCTRL(ln, tc_port), val); @@ -1231,9 +1231,9 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK | CRI_TXDEEMPH_OVERRIDE_5_0_MASK); val |= CRI_TXDEEMPH_OVERRIDE_5_0( - ddi_translations->entries[level].mg.cri_txdeemph_override_5_0) | + trans->entries[level].mg.cri_txdeemph_override_5_0) | CRI_TXDEEMPH_OVERRIDE_11_6( - ddi_translations->entries[level].mg.cri_txdeemph_override_11_6) | + trans->entries[level].mg.cri_txdeemph_override_11_6) | CRI_TXDEEMPH_OVERRIDE_EN; intel_de_write(dev_priv, MG_TX2_DRVCTRL(ln, tc_port), val); @@ -1313,15 +1313,15 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); - const struct intel_ddi_buf_trans *ddi_translations; + const struct intel_ddi_buf_trans *trans; u32 val, dpcnt_mask, dpcnt_val; int n_entries, ln; if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder))) return; - ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) + trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) level = n_entries - 1; @@ -1329,9 +1329,9 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, dpcnt_mask = (DKL_TX_PRESHOOT_COEFF_MASK | DKL_TX_DE_EMPAHSIS_COEFF_MASK | DKL_TX_VSWING_CONTROL_MASK); - dpcnt_val = DKL_TX_VSWING_CONTROL(ddi_translations->entries[level].dkl.dkl_vswing_control); - dpcnt_val |= DKL_TX_DE_EMPHASIS_COEFF(ddi_translations->entries[level].dkl.dkl_de_emphasis_control); - dpcnt_val |= DKL_TX_PRESHOOT_COEFF(ddi_translations->entries[level].dkl.dkl_preshoot_control); + dpcnt_val = DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.dkl_vswing_control); + dpcnt_val |= DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.dkl_de_emphasis_control); + dpcnt_val |= DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.dkl_preshoot_control); for (ln = 0; ln < 2; ln++) { intel_de_write(dev_priv, HIP_INDEX_REG(tc_port), diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c index 796dd04eae01..449daba7afb3 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c @@ -13,7 +13,7 @@ * them for both DP and FDI transports, allowing those ports to * automatically adapt to HDMI connections as well */ -static const union intel_ddi_buf_trans_entry _hsw_ddi_translations_dp[] = { +static const union intel_ddi_buf_trans_entry _hsw_trans_dp[] = { { .hsw = { 0x00FFFFFF, 0x0006000E, 0x0 } }, { .hsw = { 0x00D75FFF, 0x0005000A, 0x0 } }, { .hsw = { 0x00C30FFF, 0x00040006, 0x0 } }, @@ -25,12 +25,12 @@ static const union intel_ddi_buf_trans_entry _hsw_ddi_translations_dp[] = { { .hsw = { 0x80D75FFF, 0x000B0000, 0x0 } }, }; -static const struct intel_ddi_buf_trans hsw_ddi_translations_dp = { - .entries = _hsw_ddi_translations_dp, - .num_entries = ARRAY_SIZE(_hsw_ddi_translations_dp), +static const struct intel_ddi_buf_trans hsw_trans_dp = { + .entries = _hsw_trans_dp, + .num_entries = ARRAY_SIZE(_hsw_trans_dp), }; -static const union intel_ddi_buf_trans_entry _hsw_ddi_translations_fdi[] = { +static const union intel_ddi_buf_trans_entry _hsw_trans_fdi[] = { { .hsw = { 0x00FFFFFF, 0x0007000E, 0x0 } }, { .hsw = { 0x00D75FFF, 0x000F000A, 0x0 } }, { .hsw = { 0x00C30FFF, 0x00060006, 0x0 } }, @@ -42,12 +42,12 @@ static const union intel_ddi_buf_trans_entry _hsw_ddi_translations_fdi[] = { { .hsw = { 0x00D75FFF, 0x001E0000, 0x0 } }, }; -static const struct intel_ddi_buf_trans hsw_ddi_translations_fdi = { - .entries = _hsw_ddi_translations_fdi, - .num_entries = ARRAY_SIZE(_hsw_ddi_translations_fdi), +static const struct intel_ddi_buf_trans hsw_trans_fdi = { + .entries = _hsw_trans_fdi, + .num_entries = ARRAY_SIZE(_hsw_trans_fdi), }; -static const union intel_ddi_buf_trans_entry _hsw_ddi_translations_hdmi[] = { +static const union intel_ddi_buf_trans_entry _hsw_trans_hdmi[] = { /* Idx NT mV d T mV d db */ { .hsw = { 0x00FFFFFF, 0x0006000E, 0x0 } }, /* 0: 400 400 0 */ { .hsw = { 0x00E79FFF, 0x000E000C, 0x0 } }, /* 1: 400 500 2 */ @@ -63,13 +63,13 @@ static const union intel_ddi_buf_trans_entry _hsw_ddi_translations_hdmi[] = { { .hsw = { 0x80FFFFFF, 0x00030002, 0x0 } }, /* 11: 1000 1000 0 */ }; -static const struct intel_ddi_buf_trans hsw_ddi_translations_hdmi = { - .entries = _hsw_ddi_translations_hdmi, - .num_entries = ARRAY_SIZE(_hsw_ddi_translations_hdmi), +static const struct intel_ddi_buf_trans hsw_trans_hdmi = { + .entries = _hsw_trans_hdmi, + .num_entries = ARRAY_SIZE(_hsw_trans_hdmi), .hdmi_default_entry = 6, }; -static const union intel_ddi_buf_trans_entry _bdw_ddi_translations_edp[] = { +static const union intel_ddi_buf_trans_entry _bdw_trans_edp[] = { { .hsw = { 0x00FFFFFF, 0x00000012, 0x0 } }, { .hsw = { 0x00EBAFFF, 0x00020011, 0x0 } }, { .hsw = { 0x00C71FFF, 0x0006000F, 0x0 } }, @@ -81,12 +81,12 @@ static const union intel_ddi_buf_trans_entry _bdw_ddi_translations_edp[] = { { .hsw = { 0x00DB6FFF, 0x000A000C, 0x0 } }, }; -static const struct intel_ddi_buf_trans bdw_ddi_translations_edp = { - .entries = _bdw_ddi_translations_edp, - .num_entries = ARRAY_SIZE(_bdw_ddi_translations_edp), +static const struct intel_ddi_buf_trans bdw_trans_edp = { + .entries = _bdw_trans_edp, + .num_entries = ARRAY_SIZE(_bdw_trans_edp), }; -static const union intel_ddi_buf_trans_entry _bdw_ddi_translations_dp[] = { +static const union intel_ddi_buf_trans_entry _bdw_trans_dp[] = { { .hsw = { 0x00FFFFFF, 0x0007000E, 0x0 } }, { .hsw = { 0x00D75FFF, 0x000E000A, 0x0 } }, { .hsw = { 0x00BEFFFF, 0x00140006, 0x0 } }, @@ -98,12 +98,12 @@ static const union intel_ddi_buf_trans_entry _bdw_ddi_translations_dp[] = { { .hsw = { 0x80D75FFF, 0x001B0002, 0x0 } }, }; -static const struct intel_ddi_buf_trans bdw_ddi_translations_dp = { - .entries = _bdw_ddi_translations_dp, - .num_entries = ARRAY_SIZE(_bdw_ddi_translations_dp), +static const struct intel_ddi_buf_trans bdw_trans_dp = { + .entries = _bdw_trans_dp, + .num_entries = ARRAY_SIZE(_bdw_trans_dp), }; -static const union intel_ddi_buf_trans_entry _bdw_ddi_translations_fdi[] = { +static const union intel_ddi_buf_trans_entry _bdw_trans_fdi[] = { { .hsw = { 0x00FFFFFF, 0x0001000E, 0x0 } }, { .hsw = { 0x00D75FFF, 0x0004000A, 0x0 } }, { .hsw = { 0x00C30FFF, 0x00070006, 0x0 } }, @@ -115,12 +115,12 @@ static const union intel_ddi_buf_trans_entry _bdw_ddi_translations_fdi[] = { { .hsw = { 0x00D75FFF, 0x000C0000, 0x0 } }, }; -static const struct intel_ddi_buf_trans bdw_ddi_translations_fdi = { - .entries = _bdw_ddi_translations_fdi, - .num_entries = ARRAY_SIZE(_bdw_ddi_translations_fdi), +static const struct intel_ddi_buf_trans bdw_trans_fdi = { + .entries = _bdw_trans_fdi, + .num_entries = ARRAY_SIZE(_bdw_trans_fdi), }; -static const union intel_ddi_buf_trans_entry _bdw_ddi_translations_hdmi[] = { +static const union intel_ddi_buf_trans_entry _bdw_trans_hdmi[] = { /* Idx NT mV d T mV df db */ { .hsw = { 0x00FFFFFF, 0x0007000E, 0x0 } }, /* 0: 400 400 0 */ { .hsw = { 0x00D75FFF, 0x000E000A, 0x0 } }, /* 1: 400 600 3.5 */ @@ -134,14 +134,14 @@ static const union intel_ddi_buf_trans_entry _bdw_ddi_translations_hdmi[] = { { .hsw = { 0x80FFFFFF, 0x001B0002, 0x0 } }, /* 9: 1000 1000 0 */ }; -static const struct intel_ddi_buf_trans bdw_ddi_translations_hdmi = { - .entries = _bdw_ddi_translations_hdmi, - .num_entries = ARRAY_SIZE(_bdw_ddi_translations_hdmi), +static const struct intel_ddi_buf_trans bdw_trans_hdmi = { + .entries = _bdw_trans_hdmi, + .num_entries = ARRAY_SIZE(_bdw_trans_hdmi), .hdmi_default_entry = 7, }; /* Skylake H and S */ -static const union intel_ddi_buf_trans_entry _skl_ddi_translations_dp[] = { +static const union intel_ddi_buf_trans_entry _skl_trans_dp[] = { { .hsw = { 0x00002016, 0x000000A0, 0x0 } }, { .hsw = { 0x00005012, 0x0000009B, 0x0 } }, { .hsw = { 0x00007011, 0x00000088, 0x0 } }, @@ -153,13 +153,13 @@ static const union intel_ddi_buf_trans_entry _skl_ddi_translations_dp[] = { { .hsw = { 0x80005012, 0x000000C0, 0x1 } }, }; -static const struct intel_ddi_buf_trans skl_ddi_translations_dp = { - .entries = _skl_ddi_translations_dp, - .num_entries = ARRAY_SIZE(_skl_ddi_translations_dp), +static const struct intel_ddi_buf_trans skl_trans_dp = { + .entries = _skl_trans_dp, + .num_entries = ARRAY_SIZE(_skl_trans_dp), }; /* Skylake U */ -static const union intel_ddi_buf_trans_entry _skl_u_ddi_translations_dp[] = { +static const union intel_ddi_buf_trans_entry _skl_u_trans_dp[] = { { .hsw = { 0x0000201B, 0x000000A2, 0x0 } }, { .hsw = { 0x00005012, 0x00000088, 0x0 } }, { .hsw = { 0x80007011, 0x000000CD, 0x1 } }, @@ -171,13 +171,13 @@ static const union intel_ddi_buf_trans_entry _skl_u_ddi_translations_dp[] = { { .hsw = { 0x80005012, 0x000000C0, 0x1 } }, }; -static const struct intel_ddi_buf_trans skl_u_ddi_translations_dp = { - .entries = _skl_u_ddi_translations_dp, - .num_entries = ARRAY_SIZE(_skl_u_ddi_translations_dp), +static const struct intel_ddi_buf_trans skl_u_trans_dp = { + .entries = _skl_u_trans_dp, + .num_entries = ARRAY_SIZE(_skl_u_trans_dp), }; /* Skylake Y */ -static const union intel_ddi_buf_trans_entry _skl_y_ddi_translations_dp[] = { +static const union intel_ddi_buf_trans_entry _skl_y_trans_dp[] = { { .hsw = { 0x00000018, 0x000000A2, 0x0 } }, { .hsw = { 0x00005012, 0x00000088, 0x0 } }, { .hsw = { 0x80007011, 0x000000CD, 0x3 } }, @@ -189,13 +189,13 @@ static const union intel_ddi_buf_trans_entry _skl_y_ddi_translations_dp[] = { { .hsw = { 0x80005012, 0x000000C0, 0x3 } }, }; -static const struct intel_ddi_buf_trans skl_y_ddi_translations_dp = { - .entries = _skl_y_ddi_translations_dp, - .num_entries = ARRAY_SIZE(_skl_y_ddi_translations_dp), +static const struct intel_ddi_buf_trans skl_y_trans_dp = { + .entries = _skl_y_trans_dp, + .num_entries = ARRAY_SIZE(_skl_y_trans_dp), }; /* Kabylake H and S */ -static const union intel_ddi_buf_trans_entry _kbl_ddi_translations_dp[] = { +static const union intel_ddi_buf_trans_entry _kbl_trans_dp[] = { { .hsw = { 0x00002016, 0x000000A0, 0x0 } }, { .hsw = { 0x00005012, 0x0000009B, 0x0 } }, { .hsw = { 0x00007011, 0x00000088, 0x0 } }, @@ -207,13 +207,13 @@ static const union intel_ddi_buf_trans_entry _kbl_ddi_translations_dp[] = { { .hsw = { 0x80005012, 0x000000C0, 0x1 } }, }; -static const struct intel_ddi_buf_trans kbl_ddi_translations_dp = { - .entries = _kbl_ddi_translations_dp, - .num_entries = ARRAY_SIZE(_kbl_ddi_translations_dp), +static const struct intel_ddi_buf_trans kbl_trans_dp = { + .entries = _kbl_trans_dp, + .num_entries = ARRAY_SIZE(_kbl_trans_dp), }; /* Kabylake U */ -static const union intel_ddi_buf_trans_entry _kbl_u_ddi_translations_dp[] = { +static const union intel_ddi_buf_trans_entry _kbl_u_trans_dp[] = { { .hsw = { 0x0000201B, 0x000000A1, 0x0 } }, { .hsw = { 0x00005012, 0x00000088, 0x0 } }, { .hsw = { 0x80007011, 0x000000CD, 0x3 } }, @@ -225,13 +225,13 @@ static const union intel_ddi_buf_trans_entry _kbl_u_ddi_translations_dp[] = { { .hsw = { 0x80005012, 0x000000C0, 0x3 } }, }; -static const struct intel_ddi_buf_trans kbl_u_ddi_translations_dp = { - .entries = _kbl_u_ddi_translations_dp, - .num_entries = ARRAY_SIZE(_kbl_u_ddi_translations_dp), +static const struct intel_ddi_buf_trans kbl_u_trans_dp = { + .entries = _kbl_u_trans_dp, + .num_entries = ARRAY_SIZE(_kbl_u_trans_dp), }; /* Kabylake Y */ -static const union intel_ddi_buf_trans_entry _kbl_y_ddi_translations_dp[] = { +static const union intel_ddi_buf_trans_entry _kbl_y_trans_dp[] = { { .hsw = { 0x00001017, 0x000000A1, 0x0 } }, { .hsw = { 0x00005012, 0x00000088, 0x0 } }, { .hsw = { 0x80007011, 0x000000CD, 0x3 } }, @@ -243,16 +243,16 @@ static const union intel_ddi_buf_trans_entry _kbl_y_ddi_translations_dp[] = { { .hsw = { 0x80005012, 0x000000C0, 0x3 } }, }; -static const struct intel_ddi_buf_trans kbl_y_ddi_translations_dp = { - .entries = _kbl_y_ddi_translations_dp, - .num_entries = ARRAY_SIZE(_kbl_y_ddi_translations_dp), +static const struct intel_ddi_buf_trans kbl_y_trans_dp = { + .entries = _kbl_y_trans_dp, + .num_entries = ARRAY_SIZE(_kbl_y_trans_dp), }; /* * Skylake/Kabylake H and S * eDP 1.4 low vswing translation parameters */ -static const union intel_ddi_buf_trans_entry _skl_ddi_translations_edp[] = { +static const union intel_ddi_buf_trans_entry _skl_trans_edp[] = { { .hsw = { 0x00000018, 0x000000A8, 0x0 } }, { .hsw = { 0x00004013, 0x000000A9, 0x0 } }, { .hsw = { 0x00007011, 0x000000A2, 0x0 } }, @@ -265,16 +265,16 @@ static const union intel_ddi_buf_trans_entry _skl_ddi_translations_edp[] = { { .hsw = { 0x00000018, 0x000000DF, 0x0 } }, }; -static const struct intel_ddi_buf_trans skl_ddi_translations_edp = { - .entries = _skl_ddi_translations_edp, - .num_entries = ARRAY_SIZE(_skl_ddi_translations_edp), +static const struct intel_ddi_buf_trans skl_trans_edp = { + .entries = _skl_trans_edp, + .num_entries = ARRAY_SIZE(_skl_trans_edp), }; /* * Skylake/Kabylake U * eDP 1.4 low vswing translation parameters */ -static const union intel_ddi_buf_trans_entry _skl_u_ddi_translations_edp[] = { +static const union intel_ddi_buf_trans_entry _skl_u_trans_edp[] = { { .hsw = { 0x00000018, 0x000000A8, 0x0 } }, { .hsw = { 0x00004013, 0x000000A9, 0x0 } }, { .hsw = { 0x00007011, 0x000000A2, 0x0 } }, @@ -287,16 +287,16 @@ static const union intel_ddi_buf_trans_entry _skl_u_ddi_translations_edp[] = { { .hsw = { 0x00000018, 0x000000DF, 0x0 } }, }; -static const struct intel_ddi_buf_trans skl_u_ddi_translations_edp = { - .entries = _skl_u_ddi_translations_edp, - .num_entries = ARRAY_SIZE(_skl_u_ddi_translations_edp), +static const struct intel_ddi_buf_trans skl_u_trans_edp = { + .entries = _skl_u_trans_edp, + .num_entries = ARRAY_SIZE(_skl_u_trans_edp), }; /* * Skylake/Kabylake Y * eDP 1.4 low vswing translation parameters */ -static const union intel_ddi_buf_trans_entry _skl_y_ddi_translations_edp[] = { +static const union intel_ddi_buf_trans_entry _skl_y_trans_edp[] = { { .hsw = { 0x00000018, 0x000000A8, 0x0 } }, { .hsw = { 0x00004013, 0x000000AB, 0x0 } }, { .hsw = { 0x00007011, 0x000000A4, 0x0 } }, @@ -309,13 +309,13 @@ static const union intel_ddi_buf_trans_entry _skl_y_ddi_translations_edp[] = { { .hsw = { 0x00000018, 0x0000008A, 0x0 } }, }; -static const struct intel_ddi_buf_trans skl_y_ddi_translations_edp = { - .entries = _skl_y_ddi_translations_edp, - .num_entries = ARRAY_SIZE(_skl_y_ddi_translations_edp), +static const struct intel_ddi_buf_trans skl_y_trans_edp = { + .entries = _skl_y_trans_edp, + .num_entries = ARRAY_SIZE(_skl_y_trans_edp), }; /* Skylake/Kabylake U, H and S */ -static const union intel_ddi_buf_trans_entry _skl_ddi_translations_hdmi[] = { +static const union intel_ddi_buf_trans_entry _skl_trans_hdmi[] = { { .hsw = { 0x00000018, 0x000000AC, 0x0 } }, { .hsw = { 0x00005012, 0x0000009D, 0x0 } }, { .hsw = { 0x00007011, 0x00000088, 0x0 } }, @@ -329,14 +329,14 @@ static const union intel_ddi_buf_trans_entry _skl_ddi_translations_hdmi[] = { { .hsw = { 0x80000018, 0x000000C0, 0x1 } }, }; -static const struct intel_ddi_buf_trans skl_ddi_translations_hdmi = { - .entries = _skl_ddi_translations_hdmi, - .num_entries = ARRAY_SIZE(_skl_ddi_translations_hdmi), +static const struct intel_ddi_buf_trans skl_trans_hdmi = { + .entries = _skl_trans_hdmi, + .num_entries = ARRAY_SIZE(_skl_trans_hdmi), .hdmi_default_entry = 8, }; /* Skylake/Kabylake Y */ -static const union intel_ddi_buf_trans_entry _skl_y_ddi_translations_hdmi[] = { +static const union intel_ddi_buf_trans_entry _skl_y_trans_hdmi[] = { { .hsw = { 0x00000018, 0x000000A1, 0x0 } }, { .hsw = { 0x00005012, 0x000000DF, 0x0 } }, { .hsw = { 0x80007011, 0x000000CB, 0x3 } }, @@ -350,13 +350,13 @@ static const union intel_ddi_buf_trans_entry _skl_y_ddi_translations_hdmi[] = { { .hsw = { 0x80000018, 0x000000C0, 0x3 } }, }; -static const struct intel_ddi_buf_trans skl_y_ddi_translations_hdmi = { - .entries = _skl_y_ddi_translations_hdmi, - .num_entries = ARRAY_SIZE(_skl_y_ddi_translations_hdmi), +static const struct intel_ddi_buf_trans skl_y_trans_hdmi = { + .entries = _skl_y_trans_hdmi, + .num_entries = ARRAY_SIZE(_skl_y_trans_hdmi), .hdmi_default_entry = 8, }; -static const union intel_ddi_buf_trans_entry _bxt_ddi_translations_dp[] = { +static const union intel_ddi_buf_trans_entry _bxt_trans_dp[] = { /* Idx NT mV diff db */ { .bxt = { 52, 0x9A, 0, 128, } }, /* 0: 400 0 */ { .bxt = { 78, 0x9A, 0, 85, } }, /* 1: 400 3.5 */ @@ -370,12 +370,12 @@ static const union intel_ddi_buf_trans_entry _bxt_ddi_translations_dp[] = { { .bxt = { 154, 0x9A, 1, 128, } }, /* 9: 1200 0 */ }; -static const struct intel_ddi_buf_trans bxt_ddi_translations_dp = { - .entries = _bxt_ddi_translations_dp, - .num_entries = ARRAY_SIZE(_bxt_ddi_translations_dp), +static const struct intel_ddi_buf_trans bxt_trans_dp = { + .entries = _bxt_trans_dp, + .num_entries = ARRAY_SIZE(_bxt_trans_dp), }; -static const union intel_ddi_buf_trans_entry _bxt_ddi_translations_edp[] = { +static const union intel_ddi_buf_trans_entry _bxt_trans_edp[] = { /* Idx NT mV diff db */ { .bxt = { 26, 0, 0, 128, } }, /* 0: 200 0 */ { .bxt = { 38, 0, 0, 112, } }, /* 1: 200 1.5 */ @@ -389,15 +389,15 @@ static const union intel_ddi_buf_trans_entry _bxt_ddi_translations_edp[] = { { .bxt = { 48, 0, 0, 128, } }, /* 9: 300 0 */ }; -static const struct intel_ddi_buf_trans bxt_ddi_translations_edp = { - .entries = _bxt_ddi_translations_edp, - .num_entries = ARRAY_SIZE(_bxt_ddi_translations_edp), +static const struct intel_ddi_buf_trans bxt_trans_edp = { + .entries = _bxt_trans_edp, + .num_entries = ARRAY_SIZE(_bxt_trans_edp), }; /* BSpec has 2 recommended values - entries 0 and 8. * Using the entry with higher vswing. */ -static const union intel_ddi_buf_trans_entry _bxt_ddi_translations_hdmi[] = { +static const union intel_ddi_buf_trans_entry _bxt_trans_hdmi[] = { /* Idx NT mV diff db */ { .bxt = { 52, 0x9A, 0, 128, } }, /* 0: 400 0 */ { .bxt = { 52, 0x9A, 0, 85, } }, /* 1: 400 3.5 */ @@ -411,14 +411,14 @@ static const union intel_ddi_buf_trans_entry _bxt_ddi_translations_hdmi[] = { { .bxt = { 154, 0x9A, 1, 128, } }, /* 9: 1200 0 */ }; -static const struct intel_ddi_buf_trans bxt_ddi_translations_hdmi = { - .entries = _bxt_ddi_translations_hdmi, - .num_entries = ARRAY_SIZE(_bxt_ddi_translations_hdmi), - .hdmi_default_entry = ARRAY_SIZE(_bxt_ddi_translations_hdmi) - 1, +static const struct intel_ddi_buf_trans bxt_trans_hdmi = { + .entries = _bxt_trans_hdmi, + .num_entries = ARRAY_SIZE(_bxt_trans_hdmi), + .hdmi_default_entry = ARRAY_SIZE(_bxt_trans_hdmi) - 1, }; -/* icl_combo_phy_ddi_translations */ -static const union intel_ddi_buf_trans_entry _icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3[] = { +/* icl_combo_phy_trans */ +static const union intel_ddi_buf_trans_entry _icl_combo_phy_trans_dp_hbr2_edp_hbr3[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */ @@ -432,12 +432,12 @@ static const union intel_ddi_buf_trans_entry _icl_combo_phy_ddi_translations_dp_ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3 = { - .entries = _icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3, - .num_entries = ARRAY_SIZE(_icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3), +static const struct intel_ddi_buf_trans icl_combo_phy_trans_dp_hbr2_edp_hbr3 = { + .entries = _icl_combo_phy_trans_dp_hbr2_edp_hbr3, + .num_entries = ARRAY_SIZE(_icl_combo_phy_trans_dp_hbr2_edp_hbr3), }; -static const union intel_ddi_buf_trans_entry _icl_combo_phy_ddi_translations_edp_hbr2[] = { +static const union intel_ddi_buf_trans_entry _icl_combo_phy_trans_edp_hbr2[] = { /* NT mV Trans mV db */ { .icl = { 0x0, 0x7F, 0x3F, 0x00, 0x00 } }, /* 200 200 0.0 */ { .icl = { 0x8, 0x7F, 0x38, 0x00, 0x07 } }, /* 200 250 1.9 */ @@ -451,12 +451,12 @@ static const union intel_ddi_buf_trans_entry _icl_combo_phy_ddi_translations_edp { .icl = { 0x9, 0x7F, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ }; -static const struct intel_ddi_buf_trans icl_combo_phy_ddi_translations_edp_hbr2 = { - .entries = _icl_combo_phy_ddi_translations_edp_hbr2, - .num_entries = ARRAY_SIZE(_icl_combo_phy_ddi_translations_edp_hbr2), +static const struct intel_ddi_buf_trans icl_combo_phy_trans_edp_hbr2 = { + .entries = _icl_combo_phy_trans_edp_hbr2, + .num_entries = ARRAY_SIZE(_icl_combo_phy_trans_edp_hbr2), }; -static const union intel_ddi_buf_trans_entry _icl_combo_phy_ddi_translations_hdmi[] = { +static const union intel_ddi_buf_trans_entry _icl_combo_phy_trans_hdmi[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x60, 0x3F, 0x00, 0x00 } }, /* 450 450 0.0 */ { .icl = { 0xB, 0x73, 0x36, 0x00, 0x09 } }, /* 450 650 3.2 */ @@ -467,13 +467,13 @@ static const union intel_ddi_buf_trans_entry _icl_combo_phy_ddi_translations_hdm { .icl = { 0x6, 0x7F, 0x35, 0x00, 0x0A } }, /* 600 850 3.0 */ }; -static const struct intel_ddi_buf_trans icl_combo_phy_ddi_translations_hdmi = { - .entries = _icl_combo_phy_ddi_translations_hdmi, - .num_entries = ARRAY_SIZE(_icl_combo_phy_ddi_translations_hdmi), - .hdmi_default_entry = ARRAY_SIZE(_icl_combo_phy_ddi_translations_hdmi) - 1, +static const struct intel_ddi_buf_trans icl_combo_phy_trans_hdmi = { + .entries = _icl_combo_phy_trans_hdmi, + .num_entries = ARRAY_SIZE(_icl_combo_phy_trans_hdmi), + .hdmi_default_entry = ARRAY_SIZE(_icl_combo_phy_trans_hdmi) - 1, }; -static const union intel_ddi_buf_trans_entry _ehl_combo_phy_ddi_translations_dp[] = { +static const union intel_ddi_buf_trans_entry _ehl_combo_phy_trans_dp[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x33, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x47, 0x36, 0x00, 0x09 } }, /* 350 500 3.1 */ @@ -487,12 +487,12 @@ static const union intel_ddi_buf_trans_entry _ehl_combo_phy_ddi_translations_dp[ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans ehl_combo_phy_ddi_translations_dp = { - .entries = _ehl_combo_phy_ddi_translations_dp, - .num_entries = ARRAY_SIZE(_ehl_combo_phy_ddi_translations_dp), +static const struct intel_ddi_buf_trans ehl_combo_phy_trans_dp = { + .entries = _ehl_combo_phy_trans_dp, + .num_entries = ARRAY_SIZE(_ehl_combo_phy_trans_dp), }; -static const union intel_ddi_buf_trans_entry _ehl_combo_phy_ddi_translations_edp_hbr2[] = { +static const union intel_ddi_buf_trans_entry _ehl_combo_phy_trans_edp_hbr2[] = { /* NT mV Trans mV db */ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 200 200 0.0 */ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 200 250 1.9 */ @@ -506,12 +506,12 @@ static const union intel_ddi_buf_trans_entry _ehl_combo_phy_ddi_translations_edp { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ }; -static const struct intel_ddi_buf_trans ehl_combo_phy_ddi_translations_edp_hbr2 = { - .entries = _ehl_combo_phy_ddi_translations_edp_hbr2, - .num_entries = ARRAY_SIZE(_ehl_combo_phy_ddi_translations_edp_hbr2), +static const struct intel_ddi_buf_trans ehl_combo_phy_trans_edp_hbr2 = { + .entries = _ehl_combo_phy_trans_edp_hbr2, + .num_entries = ARRAY_SIZE(_ehl_combo_phy_trans_edp_hbr2), }; -static const union intel_ddi_buf_trans_entry _jsl_combo_phy_ddi_translations_edp_hbr[] = { +static const union intel_ddi_buf_trans_entry _jsl_combo_phy_trans_edp_hbr[] = { /* NT mV Trans mV db */ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 200 200 0.0 */ { .icl = { 0x8, 0x7F, 0x38, 0x00, 0x07 } }, /* 200 250 1.9 */ @@ -525,12 +525,12 @@ static const union intel_ddi_buf_trans_entry _jsl_combo_phy_ddi_translations_edp { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ }; -static const struct intel_ddi_buf_trans jsl_combo_phy_ddi_translations_edp_hbr = { - .entries = _jsl_combo_phy_ddi_translations_edp_hbr, - .num_entries = ARRAY_SIZE(_jsl_combo_phy_ddi_translations_edp_hbr), +static const struct intel_ddi_buf_trans jsl_combo_phy_trans_edp_hbr = { + .entries = _jsl_combo_phy_trans_edp_hbr, + .num_entries = ARRAY_SIZE(_jsl_combo_phy_trans_edp_hbr), }; -static const union intel_ddi_buf_trans_entry _jsl_combo_phy_ddi_translations_edp_hbr2[] = { +static const union intel_ddi_buf_trans_entry _jsl_combo_phy_trans_edp_hbr2[] = { /* NT mV Trans mV db */ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 200 200 0.0 */ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 200 250 1.9 */ @@ -544,12 +544,12 @@ static const union intel_ddi_buf_trans_entry _jsl_combo_phy_ddi_translations_edp { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ }; -static const struct intel_ddi_buf_trans jsl_combo_phy_ddi_translations_edp_hbr2 = { - .entries = _jsl_combo_phy_ddi_translations_edp_hbr2, - .num_entries = ARRAY_SIZE(_jsl_combo_phy_ddi_translations_edp_hbr2), +static const struct intel_ddi_buf_trans jsl_combo_phy_trans_edp_hbr2 = { + .entries = _jsl_combo_phy_trans_edp_hbr2, + .num_entries = ARRAY_SIZE(_jsl_combo_phy_trans_edp_hbr2), }; -static const union intel_ddi_buf_trans_entry _dg1_combo_phy_ddi_translations_dp_rbr_hbr[] = { +static const union intel_ddi_buf_trans_entry _dg1_combo_phy_trans_dp_rbr_hbr[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x32, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x48, 0x35, 0x00, 0x0A } }, /* 350 500 3.1 */ @@ -563,12 +563,12 @@ static const union intel_ddi_buf_trans_entry _dg1_combo_phy_ddi_translations_dp_ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans dg1_combo_phy_ddi_translations_dp_rbr_hbr = { - .entries = _dg1_combo_phy_ddi_translations_dp_rbr_hbr, - .num_entries = ARRAY_SIZE(_dg1_combo_phy_ddi_translations_dp_rbr_hbr), +static const struct intel_ddi_buf_trans dg1_combo_phy_trans_dp_rbr_hbr = { + .entries = _dg1_combo_phy_trans_dp_rbr_hbr, + .num_entries = ARRAY_SIZE(_dg1_combo_phy_trans_dp_rbr_hbr), }; -static const union intel_ddi_buf_trans_entry _dg1_combo_phy_ddi_translations_dp_hbr2_hbr3[] = { +static const union intel_ddi_buf_trans_entry _dg1_combo_phy_trans_dp_hbr2_hbr3[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x32, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x48, 0x35, 0x00, 0x0A } }, /* 350 500 3.1 */ @@ -582,12 +582,12 @@ static const union intel_ddi_buf_trans_entry _dg1_combo_phy_ddi_translations_dp_ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans dg1_combo_phy_ddi_translations_dp_hbr2_hbr3 = { - .entries = _dg1_combo_phy_ddi_translations_dp_hbr2_hbr3, - .num_entries = ARRAY_SIZE(_dg1_combo_phy_ddi_translations_dp_hbr2_hbr3), +static const struct intel_ddi_buf_trans dg1_combo_phy_trans_dp_hbr2_hbr3 = { + .entries = _dg1_combo_phy_trans_dp_hbr2_hbr3, + .num_entries = ARRAY_SIZE(_dg1_combo_phy_trans_dp_hbr2_hbr3), }; -static const union intel_ddi_buf_trans_entry _icl_mg_phy_ddi_translations_rbr_hbr[] = { +static const union intel_ddi_buf_trans_entry _icl_mg_phy_trans_rbr_hbr[] = { /* Voltage swing pre-emphasis */ { .mg = { 0x18, 0x00, 0x00 } }, /* 0 0 */ { .mg = { 0x1D, 0x00, 0x05 } }, /* 0 1 */ @@ -601,12 +601,12 @@ static const union intel_ddi_buf_trans_entry _icl_mg_phy_ddi_translations_rbr_hb { .mg = { 0x3F, 0x00, 0x00 } }, /* 3 0 */ }; -static const struct intel_ddi_buf_trans icl_mg_phy_ddi_translations_rbr_hbr = { - .entries = _icl_mg_phy_ddi_translations_rbr_hbr, - .num_entries = ARRAY_SIZE(_icl_mg_phy_ddi_translations_rbr_hbr), +static const struct intel_ddi_buf_trans icl_mg_phy_trans_rbr_hbr = { + .entries = _icl_mg_phy_trans_rbr_hbr, + .num_entries = ARRAY_SIZE(_icl_mg_phy_trans_rbr_hbr), }; -static const union intel_ddi_buf_trans_entry _icl_mg_phy_ddi_translations_hbr2_hbr3[] = { +static const union intel_ddi_buf_trans_entry _icl_mg_phy_trans_hbr2_hbr3[] = { /* Voltage swing pre-emphasis */ { .mg = { 0x18, 0x00, 0x00 } }, /* 0 0 */ { .mg = { 0x1D, 0x00, 0x05 } }, /* 0 1 */ @@ -620,12 +620,12 @@ static const union intel_ddi_buf_trans_entry _icl_mg_phy_ddi_translations_hbr2_h { .mg = { 0x3F, 0x00, 0x00 } }, /* 3 0 */ }; -static const struct intel_ddi_buf_trans icl_mg_phy_ddi_translations_hbr2_hbr3 = { - .entries = _icl_mg_phy_ddi_translations_hbr2_hbr3, - .num_entries = ARRAY_SIZE(_icl_mg_phy_ddi_translations_hbr2_hbr3), +static const struct intel_ddi_buf_trans icl_mg_phy_trans_hbr2_hbr3 = { + .entries = _icl_mg_phy_trans_hbr2_hbr3, + .num_entries = ARRAY_SIZE(_icl_mg_phy_trans_hbr2_hbr3), }; -static const union intel_ddi_buf_trans_entry _icl_mg_phy_ddi_translations_hdmi[] = { +static const union intel_ddi_buf_trans_entry _icl_mg_phy_trans_hdmi[] = { /* HDMI Preset VS Pre-emph */ { .mg = { 0x1A, 0x0, 0x0 } }, /* 1 400mV 0dB */ { .mg = { 0x20, 0x0, 0x0 } }, /* 2 500mV 0dB */ @@ -639,13 +639,13 @@ static const union intel_ddi_buf_trans_entry _icl_mg_phy_ddi_translations_hdmi[] { .mg = { 0x36, 0x0, 0x9 } }, /* 10 Full -3 dB */ }; -static const struct intel_ddi_buf_trans icl_mg_phy_ddi_translations_hdmi = { - .entries = _icl_mg_phy_ddi_translations_hdmi, - .num_entries = ARRAY_SIZE(_icl_mg_phy_ddi_translations_hdmi), - .hdmi_default_entry = ARRAY_SIZE(_icl_mg_phy_ddi_translations_hdmi) - 1, +static const struct intel_ddi_buf_trans icl_mg_phy_trans_hdmi = { + .entries = _icl_mg_phy_trans_hdmi, + .num_entries = ARRAY_SIZE(_icl_mg_phy_trans_hdmi), + .hdmi_default_entry = ARRAY_SIZE(_icl_mg_phy_trans_hdmi) - 1, }; -static const union intel_ddi_buf_trans_entry _tgl_dkl_phy_ddi_translations_dp_hbr[] = { +static const union intel_ddi_buf_trans_entry _tgl_dkl_phy_trans_dp_hbr[] = { /* VS pre-emp Non-trans mV Pre-emph dB */ { .dkl = { 0x7, 0x0, 0x00 } }, /* 0 0 400mV 0 dB */ { .dkl = { 0x5, 0x0, 0x05 } }, /* 0 1 400mV 3.5 dB */ @@ -659,12 +659,12 @@ static const union intel_ddi_buf_trans_entry _tgl_dkl_phy_ddi_translations_dp_hb { .dkl = { 0x0, 0x0, 0x00 } }, /* 3 0 1200mV 0 dB HDMI default */ }; -static const struct intel_ddi_buf_trans tgl_dkl_phy_ddi_translations_dp_hbr = { - .entries = _tgl_dkl_phy_ddi_translations_dp_hbr, - .num_entries = ARRAY_SIZE(_tgl_dkl_phy_ddi_translations_dp_hbr), +static const struct intel_ddi_buf_trans tgl_dkl_phy_trans_dp_hbr = { + .entries = _tgl_dkl_phy_trans_dp_hbr, + .num_entries = ARRAY_SIZE(_tgl_dkl_phy_trans_dp_hbr), }; -static const union intel_ddi_buf_trans_entry _tgl_dkl_phy_ddi_translations_dp_hbr2[] = { +static const union intel_ddi_buf_trans_entry _tgl_dkl_phy_trans_dp_hbr2[] = { /* VS pre-emp Non-trans mV Pre-emph dB */ { .dkl = { 0x7, 0x0, 0x00 } }, /* 0 0 400mV 0 dB */ { .dkl = { 0x5, 0x0, 0x05 } }, /* 0 1 400mV 3.5 dB */ @@ -678,12 +678,12 @@ static const union intel_ddi_buf_trans_entry _tgl_dkl_phy_ddi_translations_dp_hb { .dkl = { 0x0, 0x0, 0x00 } }, /* 3 0 1200mV 0 dB HDMI default */ }; -static const struct intel_ddi_buf_trans tgl_dkl_phy_ddi_translations_dp_hbr2 = { - .entries = _tgl_dkl_phy_ddi_translations_dp_hbr2, - .num_entries = ARRAY_SIZE(_tgl_dkl_phy_ddi_translations_dp_hbr2), +static const struct intel_ddi_buf_trans tgl_dkl_phy_trans_dp_hbr2 = { + .entries = _tgl_dkl_phy_trans_dp_hbr2, + .num_entries = ARRAY_SIZE(_tgl_dkl_phy_trans_dp_hbr2), }; -static const union intel_ddi_buf_trans_entry _tgl_dkl_phy_ddi_translations_hdmi[] = { +static const union intel_ddi_buf_trans_entry _tgl_dkl_phy_trans_hdmi[] = { /* HDMI Preset VS Pre-emph */ { .dkl = { 0x7, 0x0, 0x0 } }, /* 1 400mV 0dB */ { .dkl = { 0x6, 0x0, 0x0 } }, /* 2 500mV 0dB */ @@ -697,13 +697,13 @@ static const union intel_ddi_buf_trans_entry _tgl_dkl_phy_ddi_translations_hdmi[ { .dkl = { 0x0, 0x0, 0xA } }, /* 10 Full -3 dB */ }; -static const struct intel_ddi_buf_trans tgl_dkl_phy_ddi_translations_hdmi = { - .entries = _tgl_dkl_phy_ddi_translations_hdmi, - .num_entries = ARRAY_SIZE(_tgl_dkl_phy_ddi_translations_hdmi), - .hdmi_default_entry = ARRAY_SIZE(_tgl_dkl_phy_ddi_translations_hdmi) - 1, +static const struct intel_ddi_buf_trans tgl_dkl_phy_trans_hdmi = { + .entries = _tgl_dkl_phy_trans_hdmi, + .num_entries = ARRAY_SIZE(_tgl_dkl_phy_trans_hdmi), + .hdmi_default_entry = ARRAY_SIZE(_tgl_dkl_phy_trans_hdmi) - 1, }; -static const union intel_ddi_buf_trans_entry _tgl_combo_phy_ddi_translations_dp_hbr[] = { +static const union intel_ddi_buf_trans_entry _tgl_combo_phy_trans_dp_hbr[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x32, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */ @@ -717,12 +717,12 @@ static const union intel_ddi_buf_trans_entry _tgl_combo_phy_ddi_translations_dp_ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans tgl_combo_phy_ddi_translations_dp_hbr = { - .entries = _tgl_combo_phy_ddi_translations_dp_hbr, - .num_entries = ARRAY_SIZE(_tgl_combo_phy_ddi_translations_dp_hbr), +static const struct intel_ddi_buf_trans tgl_combo_phy_trans_dp_hbr = { + .entries = _tgl_combo_phy_trans_dp_hbr, + .num_entries = ARRAY_SIZE(_tgl_combo_phy_trans_dp_hbr), }; -static const union intel_ddi_buf_trans_entry _tgl_combo_phy_ddi_translations_dp_hbr2[] = { +static const union intel_ddi_buf_trans_entry _tgl_combo_phy_trans_dp_hbr2[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */ @@ -736,12 +736,12 @@ static const union intel_ddi_buf_trans_entry _tgl_combo_phy_ddi_translations_dp_ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans tgl_combo_phy_ddi_translations_dp_hbr2 = { - .entries = _tgl_combo_phy_ddi_translations_dp_hbr2, - .num_entries = ARRAY_SIZE(_tgl_combo_phy_ddi_translations_dp_hbr2), +static const struct intel_ddi_buf_trans tgl_combo_phy_trans_dp_hbr2 = { + .entries = _tgl_combo_phy_trans_dp_hbr2, + .num_entries = ARRAY_SIZE(_tgl_combo_phy_trans_dp_hbr2), }; -static const union intel_ddi_buf_trans_entry _tgl_uy_combo_phy_ddi_translations_dp_hbr2[] = { +static const union intel_ddi_buf_trans_entry _tgl_uy_combo_phy_trans_dp_hbr2[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x4F, 0x36, 0x00, 0x09 } }, /* 350 500 3.1 */ @@ -755,16 +755,16 @@ static const union intel_ddi_buf_trans_entry _tgl_uy_combo_phy_ddi_translations_ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans tgl_uy_combo_phy_ddi_translations_dp_hbr2 = { - .entries = _tgl_uy_combo_phy_ddi_translations_dp_hbr2, - .num_entries = ARRAY_SIZE(_tgl_uy_combo_phy_ddi_translations_dp_hbr2), +static const struct intel_ddi_buf_trans tgl_uy_combo_phy_trans_dp_hbr2 = { + .entries = _tgl_uy_combo_phy_trans_dp_hbr2, + .num_entries = ARRAY_SIZE(_tgl_uy_combo_phy_trans_dp_hbr2), }; /* * Cloned the HOBL entry to comply with the voltage and pre-emphasis entries * that DisplayPort specification requires */ -static const union intel_ddi_buf_trans_entry _tgl_combo_phy_ddi_translations_edp_hbr2_hobl[] = { +static const union intel_ddi_buf_trans_entry _tgl_combo_phy_trans_edp_hbr2_hobl[] = { /* VS pre-emp */ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 0 0 */ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 0 1 */ @@ -777,12 +777,12 @@ static const union intel_ddi_buf_trans_entry _tgl_combo_phy_ddi_translations_edp { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 2 1 */ }; -static const struct intel_ddi_buf_trans tgl_combo_phy_ddi_translations_edp_hbr2_hobl = { - .entries = _tgl_combo_phy_ddi_translations_edp_hbr2_hobl, - .num_entries = ARRAY_SIZE(_tgl_combo_phy_ddi_translations_edp_hbr2_hobl), +static const struct intel_ddi_buf_trans tgl_combo_phy_trans_edp_hbr2_hobl = { + .entries = _tgl_combo_phy_trans_edp_hbr2_hobl, + .num_entries = ARRAY_SIZE(_tgl_combo_phy_trans_edp_hbr2_hobl), }; -static const union intel_ddi_buf_trans_entry _rkl_combo_phy_ddi_translations_dp_hbr[] = { +static const union intel_ddi_buf_trans_entry _rkl_combo_phy_trans_dp_hbr[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x2F, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */ @@ -796,12 +796,12 @@ static const union intel_ddi_buf_trans_entry _rkl_combo_phy_ddi_translations_dp_ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans rkl_combo_phy_ddi_translations_dp_hbr = { - .entries = _rkl_combo_phy_ddi_translations_dp_hbr, - .num_entries = ARRAY_SIZE(_rkl_combo_phy_ddi_translations_dp_hbr), +static const struct intel_ddi_buf_trans rkl_combo_phy_trans_dp_hbr = { + .entries = _rkl_combo_phy_trans_dp_hbr, + .num_entries = ARRAY_SIZE(_rkl_combo_phy_trans_dp_hbr), }; -static const union intel_ddi_buf_trans_entry _rkl_combo_phy_ddi_translations_dp_hbr2_hbr3[] = { +static const union intel_ddi_buf_trans_entry _rkl_combo_phy_trans_dp_hbr2_hbr3[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x50, 0x38, 0x00, 0x07 } }, /* 350 500 3.1 */ @@ -815,12 +815,12 @@ static const union intel_ddi_buf_trans_entry _rkl_combo_phy_ddi_translations_dp_ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans rkl_combo_phy_ddi_translations_dp_hbr2_hbr3 = { - .entries = _rkl_combo_phy_ddi_translations_dp_hbr2_hbr3, - .num_entries = ARRAY_SIZE(_rkl_combo_phy_ddi_translations_dp_hbr2_hbr3), +static const struct intel_ddi_buf_trans rkl_combo_phy_trans_dp_hbr2_hbr3 = { + .entries = _rkl_combo_phy_trans_dp_hbr2_hbr3, + .num_entries = ARRAY_SIZE(_rkl_combo_phy_trans_dp_hbr2_hbr3), }; -static const union intel_ddi_buf_trans_entry _adls_combo_phy_ddi_translations_dp_hbr2_hbr3[] = { +static const union intel_ddi_buf_trans_entry _adls_combo_phy_trans_dp_hbr2_hbr3[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */ @@ -834,12 +834,12 @@ static const union intel_ddi_buf_trans_entry _adls_combo_phy_ddi_translations_dp { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans adls_combo_phy_ddi_translations_dp_hbr2_hbr3 = { - .entries = _adls_combo_phy_ddi_translations_dp_hbr2_hbr3, - .num_entries = ARRAY_SIZE(_adls_combo_phy_ddi_translations_dp_hbr2_hbr3), +static const struct intel_ddi_buf_trans adls_combo_phy_trans_dp_hbr2_hbr3 = { + .entries = _adls_combo_phy_trans_dp_hbr2_hbr3, + .num_entries = ARRAY_SIZE(_adls_combo_phy_trans_dp_hbr2_hbr3), }; -static const union intel_ddi_buf_trans_entry _adls_combo_phy_ddi_translations_edp_hbr2[] = { +static const union intel_ddi_buf_trans_entry _adls_combo_phy_trans_edp_hbr2[] = { /* NT mV Trans mV db */ { .icl = { 0x9, 0x73, 0x3D, 0x00, 0x02 } }, /* 200 200 0.0 */ { .icl = { 0x9, 0x7A, 0x3C, 0x00, 0x03 } }, /* 200 250 1.9 */ @@ -853,12 +853,12 @@ static const union intel_ddi_buf_trans_entry _adls_combo_phy_ddi_translations_ed { .icl = { 0x4, 0x6C, 0x3A, 0x00, 0x05 } }, /* 350 350 0.0 */ }; -static const struct intel_ddi_buf_trans adls_combo_phy_ddi_translations_edp_hbr2 = { - .entries = _adls_combo_phy_ddi_translations_edp_hbr2, - .num_entries = ARRAY_SIZE(_adls_combo_phy_ddi_translations_edp_hbr2), +static const struct intel_ddi_buf_trans adls_combo_phy_trans_edp_hbr2 = { + .entries = _adls_combo_phy_trans_edp_hbr2, + .num_entries = ARRAY_SIZE(_adls_combo_phy_trans_edp_hbr2), }; -static const union intel_ddi_buf_trans_entry _adls_combo_phy_ddi_translations_edp_hbr3[] = { +static const union intel_ddi_buf_trans_entry _adls_combo_phy_trans_edp_hbr3[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */ @@ -872,12 +872,12 @@ static const union intel_ddi_buf_trans_entry _adls_combo_phy_ddi_translations_ed { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans adls_combo_phy_ddi_translations_edp_hbr3 = { - .entries = _adls_combo_phy_ddi_translations_edp_hbr3, - .num_entries = ARRAY_SIZE(_adls_combo_phy_ddi_translations_edp_hbr3), +static const struct intel_ddi_buf_trans adls_combo_phy_trans_edp_hbr3 = { + .entries = _adls_combo_phy_trans_edp_hbr3, + .num_entries = ARRAY_SIZE(_adls_combo_phy_trans_edp_hbr3), }; -static const union intel_ddi_buf_trans_entry _adlp_combo_phy_ddi_translations_hdmi[] = { +static const union intel_ddi_buf_trans_entry _adlp_combo_phy_trans_hdmi[] = { /* NT mV Trans mV db */ { .icl = { 0x6, 0x60, 0x3F, 0x00, 0x00 } }, /* 400 400 0.0 */ { .icl = { 0x6, 0x68, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */ @@ -891,13 +891,13 @@ static const union intel_ddi_buf_trans_entry _adlp_combo_phy_ddi_translations_hd { .icl = { 0xB, 0x7F, 0x33, 0x00, 0x0C } }, /* Full Red -3.0 */ }; -static const struct intel_ddi_buf_trans adlp_combo_phy_ddi_translations_hdmi = { - .entries = _adlp_combo_phy_ddi_translations_hdmi, - .num_entries = ARRAY_SIZE(_adlp_combo_phy_ddi_translations_hdmi), - .hdmi_default_entry = ARRAY_SIZE(_adlp_combo_phy_ddi_translations_hdmi) - 1, +static const struct intel_ddi_buf_trans adlp_combo_phy_trans_hdmi = { + .entries = _adlp_combo_phy_trans_hdmi, + .num_entries = ARRAY_SIZE(_adlp_combo_phy_trans_hdmi), + .hdmi_default_entry = ARRAY_SIZE(_adlp_combo_phy_trans_hdmi) - 1, }; -static const union intel_ddi_buf_trans_entry _adlp_combo_phy_ddi_translations_dp_hbr[] = { +static const union intel_ddi_buf_trans_entry _adlp_combo_phy_trans_dp_hbr[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */ @@ -911,12 +911,12 @@ static const union intel_ddi_buf_trans_entry _adlp_combo_phy_ddi_translations_dp { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans adlp_combo_phy_ddi_translations_dp_hbr = { - .entries = _adlp_combo_phy_ddi_translations_dp_hbr, - .num_entries = ARRAY_SIZE(_adlp_combo_phy_ddi_translations_dp_hbr), +static const struct intel_ddi_buf_trans adlp_combo_phy_trans_dp_hbr = { + .entries = _adlp_combo_phy_trans_dp_hbr, + .num_entries = ARRAY_SIZE(_adlp_combo_phy_trans_dp_hbr), }; -static const union intel_ddi_buf_trans_entry _adlp_combo_phy_ddi_translations_dp_hbr2_hbr3[] = { +static const union intel_ddi_buf_trans_entry _adlp_combo_phy_trans_dp_hbr2_hbr3[] = { /* NT mV Trans mV db */ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */ @@ -930,22 +930,22 @@ static const union intel_ddi_buf_trans_entry _adlp_combo_phy_ddi_translations_dp { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ }; -static const struct intel_ddi_buf_trans adlp_combo_phy_ddi_translations_dp_hbr2_hbr3 = { - .entries = _adlp_combo_phy_ddi_translations_dp_hbr2_hbr3, - .num_entries = ARRAY_SIZE(_adlp_combo_phy_ddi_translations_dp_hbr2_hbr3), +static const struct intel_ddi_buf_trans adlp_combo_phy_trans_dp_hbr2_hbr3 = { + .entries = _adlp_combo_phy_trans_dp_hbr2_hbr3, + .num_entries = ARRAY_SIZE(_adlp_combo_phy_trans_dp_hbr2_hbr3), }; -static const struct intel_ddi_buf_trans adlp_combo_phy_ddi_translations_edp_hbr3 = { - .entries = _icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3, - .num_entries = ARRAY_SIZE(_icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3), +static const struct intel_ddi_buf_trans adlp_combo_phy_trans_edp_hbr3 = { + .entries = _icl_combo_phy_trans_dp_hbr2_edp_hbr3, + .num_entries = ARRAY_SIZE(_icl_combo_phy_trans_dp_hbr2_edp_hbr3), }; -static const struct intel_ddi_buf_trans adlp_combo_phy_ddi_translations_edp_up_to_hbr2 = { - .entries = _icl_combo_phy_ddi_translations_edp_hbr2, - .num_entries = ARRAY_SIZE(_icl_combo_phy_ddi_translations_edp_hbr2), +static const struct intel_ddi_buf_trans adlp_combo_phy_trans_edp_up_to_hbr2 = { + .entries = _icl_combo_phy_trans_edp_hbr2, + .num_entries = ARRAY_SIZE(_icl_combo_phy_trans_edp_hbr2), }; -static const union intel_ddi_buf_trans_entry _adlp_dkl_phy_ddi_translations_dp_hbr[] = { +static const union intel_ddi_buf_trans_entry _adlp_dkl_phy_trans_dp_hbr[] = { /* VS pre-emp Non-trans mV Pre-emph dB */ { .dkl = { 0x7, 0x0, 0x01 } }, /* 0 0 400mV 0 dB */ { .dkl = { 0x5, 0x0, 0x06 } }, /* 0 1 400mV 3.5 dB */ @@ -959,12 +959,12 @@ static const union intel_ddi_buf_trans_entry _adlp_dkl_phy_ddi_translations_dp_h { .dkl = { 0x0, 0x0, 0x00 } }, /* 3 0 1200mV 0 dB */ }; -static const struct intel_ddi_buf_trans adlp_dkl_phy_ddi_translations_dp_hbr = { - .entries = _adlp_dkl_phy_ddi_translations_dp_hbr, - .num_entries = ARRAY_SIZE(_adlp_dkl_phy_ddi_translations_dp_hbr), +static const struct intel_ddi_buf_trans adlp_dkl_phy_trans_dp_hbr = { + .entries = _adlp_dkl_phy_trans_dp_hbr, + .num_entries = ARRAY_SIZE(_adlp_dkl_phy_trans_dp_hbr), }; -static const union intel_ddi_buf_trans_entry _adlp_dkl_phy_ddi_translations_dp_hbr2_hbr3[] = { +static const union intel_ddi_buf_trans_entry _adlp_dkl_phy_trans_dp_hbr2_hbr3[] = { /* VS pre-emp Non-trans mV Pre-emph dB */ { .dkl = { 0x7, 0x0, 0x00 } }, /* 0 0 400mV 0 dB */ { .dkl = { 0x5, 0x0, 0x04 } }, /* 0 1 400mV 3.5 dB */ @@ -978,12 +978,12 @@ static const union intel_ddi_buf_trans_entry _adlp_dkl_phy_ddi_translations_dp_h { .dkl = { 0x0, 0x0, 0x00 } }, /* 3 0 1200mV 0 dB */ }; -static const struct intel_ddi_buf_trans adlp_dkl_phy_ddi_translations_dp_hbr2_hbr3 = { - .entries = _adlp_dkl_phy_ddi_translations_dp_hbr2_hbr3, - .num_entries = ARRAY_SIZE(_adlp_dkl_phy_ddi_translations_dp_hbr2_hbr3), +static const struct intel_ddi_buf_trans adlp_dkl_phy_trans_dp_hbr2_hbr3 = { + .entries = _adlp_dkl_phy_trans_dp_hbr2_hbr3, + .num_entries = ARRAY_SIZE(_adlp_dkl_phy_trans_dp_hbr2_hbr3), }; -static const union intel_ddi_buf_trans_entry _dg2_snps_translations[] = { +static const union intel_ddi_buf_trans_entry _dg2_snps_trans[] = { { .snps = { 26, 0, 0 } }, /* VS 0, pre-emph 0 */ { .snps = { 33, 0, 6 } }, /* VS 0, pre-emph 1 */ { .snps = { 38, 0, 12 } }, /* VS 0, pre-emph 2 */ @@ -996,13 +996,13 @@ static const union intel_ddi_buf_trans_entry _dg2_snps_translations[] = { { .snps = { 62, 0, 0 } }, /* VS 3, pre-emph 0 */ }; -static const struct intel_ddi_buf_trans dg2_snps_translations = { - .entries = _dg2_snps_translations, - .num_entries = ARRAY_SIZE(_dg2_snps_translations), - .hdmi_default_entry = ARRAY_SIZE(_dg2_snps_translations) - 1, +static const struct intel_ddi_buf_trans dg2_snps_trans = { + .entries = _dg2_snps_trans, + .num_entries = ARRAY_SIZE(_dg2_snps_trans), + .hdmi_default_entry = ARRAY_SIZE(_dg2_snps_trans) - 1, }; -static const union intel_ddi_buf_trans_entry _dg2_snps_translations_uhbr[] = { +static const union intel_ddi_buf_trans_entry _dg2_snps_trans_uhbr[] = { { .snps = { 62, 0, 0 } }, /* preset 0 */ { .snps = { 56, 0, 6 } }, /* preset 1 */ { .snps = { 51, 0, 11 } }, /* preset 2 */ @@ -1021,21 +1021,21 @@ static const union intel_ddi_buf_trans_entry _dg2_snps_translations_uhbr[] = { { .snps = { 56, 3, 3 } }, /* preset 15 */ }; -static const struct intel_ddi_buf_trans dg2_snps_translations_uhbr = { - .entries = _dg2_snps_translations_uhbr, - .num_entries = ARRAY_SIZE(_dg2_snps_translations_uhbr), +static const struct intel_ddi_buf_trans dg2_snps_trans_uhbr = { + .entries = _dg2_snps_trans_uhbr, + .num_entries = ARRAY_SIZE(_dg2_snps_trans_uhbr), }; bool is_hobl_buf_trans(const struct intel_ddi_buf_trans *table) { - return table == &tgl_combo_phy_ddi_translations_edp_hbr2_hobl; + return table == &tgl_combo_phy_trans_edp_hbr2_hobl; } static const struct intel_ddi_buf_trans * -intel_get_buf_trans(const struct intel_ddi_buf_trans *ddi_translations, int *num_entries) +intel_get_buf_trans(const struct intel_ddi_buf_trans *trans, int *num_entries) { - *num_entries = ddi_translations->num_entries; - return ddi_translations; + *num_entries = trans->num_entries; + return trans; } static const struct intel_ddi_buf_trans * @@ -1044,11 +1044,11 @@ hsw_get_buf_trans(struct intel_encoder *encoder, int *n_entries) { if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) - return intel_get_buf_trans(&hsw_ddi_translations_fdi, n_entries); + return intel_get_buf_trans(&hsw_trans_fdi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&hsw_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&hsw_trans_hdmi, n_entries); else - return intel_get_buf_trans(&hsw_ddi_translations_dp, n_entries); + return intel_get_buf_trans(&hsw_trans_dp, n_entries); } static const struct intel_ddi_buf_trans * @@ -1059,14 +1059,14 @@ bdw_get_buf_trans(struct intel_encoder *encoder, struct drm_i915_private *i915 = to_i915(encoder->base.dev); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) - return intel_get_buf_trans(&bdw_ddi_translations_fdi, n_entries); + return intel_get_buf_trans(&bdw_trans_fdi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&bdw_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&bdw_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && i915->vbt.edp.low_vswing) - return intel_get_buf_trans(&bdw_ddi_translations_edp, n_entries); + return intel_get_buf_trans(&bdw_trans_edp, n_entries); else - return intel_get_buf_trans(&bdw_ddi_translations_dp, n_entries); + return intel_get_buf_trans(&bdw_trans_dp, n_entries); } static int skl_buf_trans_num_entries(enum port port, int n_entries) @@ -1080,12 +1080,12 @@ static int skl_buf_trans_num_entries(enum port port, int n_entries) static const struct intel_ddi_buf_trans * _skl_get_buf_trans_dp(struct intel_encoder *encoder, - const struct intel_ddi_buf_trans *ddi_translations, + const struct intel_ddi_buf_trans *trans, int *n_entries) { - ddi_translations = intel_get_buf_trans(ddi_translations, n_entries); + trans = intel_get_buf_trans(trans, n_entries); *n_entries = skl_buf_trans_num_entries(encoder->port, *n_entries); - return ddi_translations; + return trans; } static const struct intel_ddi_buf_trans * @@ -1096,12 +1096,12 @@ skl_y_get_buf_trans(struct intel_encoder *encoder, struct drm_i915_private *i915 = to_i915(encoder->base.dev); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&skl_y_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&skl_y_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && i915->vbt.edp.low_vswing) - return _skl_get_buf_trans_dp(encoder, &skl_y_ddi_translations_edp, n_entries); + return _skl_get_buf_trans_dp(encoder, &skl_y_trans_edp, n_entries); else - return _skl_get_buf_trans_dp(encoder, &skl_y_ddi_translations_dp, n_entries); + return _skl_get_buf_trans_dp(encoder, &skl_y_trans_dp, n_entries); } static const struct intel_ddi_buf_trans * @@ -1112,12 +1112,12 @@ skl_u_get_buf_trans(struct intel_encoder *encoder, struct drm_i915_private *i915 = to_i915(encoder->base.dev); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&skl_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&skl_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && i915->vbt.edp.low_vswing) - return _skl_get_buf_trans_dp(encoder, &skl_u_ddi_translations_edp, n_entries); + return _skl_get_buf_trans_dp(encoder, &skl_u_trans_edp, n_entries); else - return _skl_get_buf_trans_dp(encoder, &skl_u_ddi_translations_dp, n_entries); + return _skl_get_buf_trans_dp(encoder, &skl_u_trans_dp, n_entries); } static const struct intel_ddi_buf_trans * @@ -1128,12 +1128,12 @@ skl_get_buf_trans(struct intel_encoder *encoder, struct drm_i915_private *i915 = to_i915(encoder->base.dev); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&skl_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&skl_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && i915->vbt.edp.low_vswing) - return _skl_get_buf_trans_dp(encoder, &skl_ddi_translations_edp, n_entries); + return _skl_get_buf_trans_dp(encoder, &skl_trans_edp, n_entries); else - return _skl_get_buf_trans_dp(encoder, &skl_ddi_translations_dp, n_entries); + return _skl_get_buf_trans_dp(encoder, &skl_trans_dp, n_entries); } static const struct intel_ddi_buf_trans * @@ -1144,12 +1144,12 @@ kbl_y_get_buf_trans(struct intel_encoder *encoder, struct drm_i915_private *i915 = to_i915(encoder->base.dev); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&skl_y_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&skl_y_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && i915->vbt.edp.low_vswing) - return _skl_get_buf_trans_dp(encoder, &skl_y_ddi_translations_edp, n_entries); + return _skl_get_buf_trans_dp(encoder, &skl_y_trans_edp, n_entries); else - return _skl_get_buf_trans_dp(encoder, &kbl_y_ddi_translations_dp, n_entries); + return _skl_get_buf_trans_dp(encoder, &kbl_y_trans_dp, n_entries); } static const struct intel_ddi_buf_trans * @@ -1160,12 +1160,12 @@ kbl_u_get_buf_trans(struct intel_encoder *encoder, struct drm_i915_private *i915 = to_i915(encoder->base.dev); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&skl_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&skl_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && i915->vbt.edp.low_vswing) - return _skl_get_buf_trans_dp(encoder, &skl_u_ddi_translations_edp, n_entries); + return _skl_get_buf_trans_dp(encoder, &skl_u_trans_edp, n_entries); else - return _skl_get_buf_trans_dp(encoder, &kbl_u_ddi_translations_dp, n_entries); + return _skl_get_buf_trans_dp(encoder, &kbl_u_trans_dp, n_entries); } static const struct intel_ddi_buf_trans * @@ -1176,12 +1176,12 @@ kbl_get_buf_trans(struct intel_encoder *encoder, struct drm_i915_private *i915 = to_i915(encoder->base.dev); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&skl_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&skl_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && i915->vbt.edp.low_vswing) - return _skl_get_buf_trans_dp(encoder, &skl_ddi_translations_edp, n_entries); + return _skl_get_buf_trans_dp(encoder, &skl_trans_edp, n_entries); else - return _skl_get_buf_trans_dp(encoder, &kbl_ddi_translations_dp, n_entries); + return _skl_get_buf_trans_dp(encoder, &kbl_trans_dp, n_entries); } static const struct intel_ddi_buf_trans * @@ -1192,12 +1192,12 @@ bxt_get_buf_trans(struct intel_encoder *encoder, struct drm_i915_private *i915 = to_i915(encoder->base.dev); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&bxt_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&bxt_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && i915->vbt.edp.low_vswing) - return intel_get_buf_trans(&bxt_ddi_translations_edp, n_entries); + return intel_get_buf_trans(&bxt_trans_edp, n_entries); else - return intel_get_buf_trans(&bxt_ddi_translations_dp, n_entries); + return intel_get_buf_trans(&bxt_trans_dp, n_entries); } static const struct intel_ddi_buf_trans * @@ -1205,7 +1205,7 @@ icl_get_combo_buf_trans_dp(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, int *n_entries) { - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3, + return intel_get_buf_trans(&icl_combo_phy_trans_dp_hbr2_edp_hbr3, n_entries); } @@ -1217,10 +1217,10 @@ icl_get_combo_buf_trans_edp(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); if (crtc_state->port_clock > 540000) { - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3, + return intel_get_buf_trans(&icl_combo_phy_trans_dp_hbr2_edp_hbr3, n_entries); } else if (dev_priv->vbt.edp.low_vswing) { - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2, + return intel_get_buf_trans(&icl_combo_phy_trans_edp_hbr2, n_entries); } @@ -1233,7 +1233,7 @@ icl_get_combo_buf_trans(struct intel_encoder *encoder, int *n_entries) { if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&icl_combo_phy_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) return icl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries); else @@ -1246,10 +1246,10 @@ icl_get_mg_buf_trans_dp(struct intel_encoder *encoder, int *n_entries) { if (crtc_state->port_clock > 270000) { - return intel_get_buf_trans(&icl_mg_phy_ddi_translations_hbr2_hbr3, + return intel_get_buf_trans(&icl_mg_phy_trans_hbr2_hbr3, n_entries); } else { - return intel_get_buf_trans(&icl_mg_phy_ddi_translations_rbr_hbr, + return intel_get_buf_trans(&icl_mg_phy_trans_rbr_hbr, n_entries); } } @@ -1260,7 +1260,7 @@ icl_get_mg_buf_trans(struct intel_encoder *encoder, int *n_entries) { if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&icl_mg_phy_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&icl_mg_phy_trans_hdmi, n_entries); else return icl_get_mg_buf_trans_dp(encoder, crtc_state, n_entries); } @@ -1271,9 +1271,9 @@ ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int *n_entries) { if (crtc_state->port_clock > 270000) - return intel_get_buf_trans(&ehl_combo_phy_ddi_translations_edp_hbr2, n_entries); + return intel_get_buf_trans(&ehl_combo_phy_trans_edp_hbr2, n_entries); else - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2, n_entries); + return intel_get_buf_trans(&icl_combo_phy_trans_edp_hbr2, n_entries); } static const struct intel_ddi_buf_trans * @@ -1284,12 +1284,12 @@ ehl_get_combo_buf_trans(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&icl_combo_phy_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && dev_priv->vbt.edp.low_vswing) return ehl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries); else - return intel_get_buf_trans(&ehl_combo_phy_ddi_translations_dp, n_entries); + return intel_get_buf_trans(&ehl_combo_phy_trans_dp, n_entries); } static const struct intel_ddi_buf_trans * @@ -1298,9 +1298,9 @@ jsl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int *n_entries) { if (crtc_state->port_clock > 270000) - return intel_get_buf_trans(&jsl_combo_phy_ddi_translations_edp_hbr2, n_entries); + return intel_get_buf_trans(&jsl_combo_phy_trans_edp_hbr2, n_entries); else - return intel_get_buf_trans(&jsl_combo_phy_ddi_translations_edp_hbr, n_entries); + return intel_get_buf_trans(&jsl_combo_phy_trans_edp_hbr, n_entries); } static const struct intel_ddi_buf_trans * @@ -1311,12 +1311,12 @@ jsl_get_combo_buf_trans(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&icl_combo_phy_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) && dev_priv->vbt.edp.low_vswing) return jsl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries); else - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3, n_entries); + return intel_get_buf_trans(&icl_combo_phy_trans_dp_hbr2_edp_hbr3, n_entries); } static const struct intel_ddi_buf_trans * @@ -1328,14 +1328,14 @@ tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder, if (crtc_state->port_clock > 270000) { if (IS_TGL_U(dev_priv) || IS_TGL_Y(dev_priv)) { - return intel_get_buf_trans(&tgl_uy_combo_phy_ddi_translations_dp_hbr2, + return intel_get_buf_trans(&tgl_uy_combo_phy_trans_dp_hbr2, n_entries); } else { - return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_dp_hbr2, + return intel_get_buf_trans(&tgl_combo_phy_trans_dp_hbr2, n_entries); } } else { - return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_dp_hbr, + return intel_get_buf_trans(&tgl_combo_phy_trans_dp_hbr, n_entries); } } @@ -1349,13 +1349,13 @@ tgl_get_combo_buf_trans_edp(struct intel_encoder *encoder, struct intel_dp *intel_dp = enc_to_intel_dp(encoder); if (crtc_state->port_clock > 540000) { - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3, + return intel_get_buf_trans(&icl_combo_phy_trans_dp_hbr2_edp_hbr3, n_entries); } else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed) { - return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_edp_hbr2_hobl, + return intel_get_buf_trans(&tgl_combo_phy_trans_edp_hbr2_hobl, n_entries); } else if (dev_priv->vbt.edp.low_vswing) { - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2, + return intel_get_buf_trans(&icl_combo_phy_trans_edp_hbr2, n_entries); } @@ -1368,7 +1368,7 @@ tgl_get_combo_buf_trans(struct intel_encoder *encoder, int *n_entries) { if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&icl_combo_phy_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) return tgl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries); else @@ -1381,10 +1381,10 @@ dg1_get_combo_buf_trans_dp(struct intel_encoder *encoder, int *n_entries) { if (crtc_state->port_clock > 270000) - return intel_get_buf_trans(&dg1_combo_phy_ddi_translations_dp_hbr2_hbr3, + return intel_get_buf_trans(&dg1_combo_phy_trans_dp_hbr2_hbr3, n_entries); else - return intel_get_buf_trans(&dg1_combo_phy_ddi_translations_dp_rbr_hbr, + return intel_get_buf_trans(&dg1_combo_phy_trans_dp_rbr_hbr, n_entries); } @@ -1397,13 +1397,13 @@ dg1_get_combo_buf_trans_edp(struct intel_encoder *encoder, struct intel_dp *intel_dp = enc_to_intel_dp(encoder); if (crtc_state->port_clock > 540000) - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3, + return intel_get_buf_trans(&icl_combo_phy_trans_dp_hbr2_edp_hbr3, n_entries); else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed) - return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_edp_hbr2_hobl, + return intel_get_buf_trans(&tgl_combo_phy_trans_edp_hbr2_hobl, n_entries); else if (dev_priv->vbt.edp.low_vswing) - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2, + return intel_get_buf_trans(&icl_combo_phy_trans_edp_hbr2, n_entries); else return dg1_get_combo_buf_trans_dp(encoder, crtc_state, n_entries); @@ -1415,7 +1415,7 @@ dg1_get_combo_buf_trans(struct intel_encoder *encoder, int *n_entries) { if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&icl_combo_phy_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) return dg1_get_combo_buf_trans_edp(encoder, crtc_state, n_entries); else @@ -1428,9 +1428,9 @@ rkl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int *n_entries) { if (crtc_state->port_clock > 270000) - return intel_get_buf_trans(&rkl_combo_phy_ddi_translations_dp_hbr2_hbr3, n_entries); + return intel_get_buf_trans(&rkl_combo_phy_trans_dp_hbr2_hbr3, n_entries); else - return intel_get_buf_trans(&rkl_combo_phy_ddi_translations_dp_hbr, n_entries); + return intel_get_buf_trans(&rkl_combo_phy_trans_dp_hbr, n_entries); } static const struct intel_ddi_buf_trans * @@ -1442,13 +1442,13 @@ rkl_get_combo_buf_trans_edp(struct intel_encoder *encoder, struct intel_dp *intel_dp = enc_to_intel_dp(encoder); if (crtc_state->port_clock > 540000) { - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3, + return intel_get_buf_trans(&icl_combo_phy_trans_dp_hbr2_edp_hbr3, n_entries); } else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed) { - return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_edp_hbr2_hobl, + return intel_get_buf_trans(&tgl_combo_phy_trans_edp_hbr2_hobl, n_entries); } else if (dev_priv->vbt.edp.low_vswing) { - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2, + return intel_get_buf_trans(&icl_combo_phy_trans_edp_hbr2, n_entries); } @@ -1461,7 +1461,7 @@ rkl_get_combo_buf_trans(struct intel_encoder *encoder, int *n_entries) { if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&icl_combo_phy_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) return rkl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries); else @@ -1474,9 +1474,9 @@ adls_get_combo_buf_trans_dp(struct intel_encoder *encoder, int *n_entries) { if (crtc_state->port_clock > 270000) - return intel_get_buf_trans(&adls_combo_phy_ddi_translations_dp_hbr2_hbr3, n_entries); + return intel_get_buf_trans(&adls_combo_phy_trans_dp_hbr2_hbr3, n_entries); else - return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_dp_hbr, n_entries); + return intel_get_buf_trans(&tgl_combo_phy_trans_dp_hbr, n_entries); } static const struct intel_ddi_buf_trans * @@ -1488,11 +1488,11 @@ adls_get_combo_buf_trans_edp(struct intel_encoder *encoder, struct intel_dp *intel_dp = enc_to_intel_dp(encoder); if (crtc_state->port_clock > 540000) - return intel_get_buf_trans(&adls_combo_phy_ddi_translations_edp_hbr3, n_entries); + return intel_get_buf_trans(&adls_combo_phy_trans_edp_hbr3, n_entries); else if (i915->vbt.edp.hobl && !intel_dp->hobl_failed) - return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_edp_hbr2_hobl, n_entries); + return intel_get_buf_trans(&tgl_combo_phy_trans_edp_hbr2_hobl, n_entries); else if (i915->vbt.edp.low_vswing) - return intel_get_buf_trans(&adls_combo_phy_ddi_translations_edp_hbr2, n_entries); + return intel_get_buf_trans(&adls_combo_phy_trans_edp_hbr2, n_entries); else return adls_get_combo_buf_trans_dp(encoder, crtc_state, n_entries); } @@ -1503,7 +1503,7 @@ adls_get_combo_buf_trans(struct intel_encoder *encoder, int *n_entries) { if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&icl_combo_phy_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) return adls_get_combo_buf_trans_edp(encoder, crtc_state, n_entries); else @@ -1516,9 +1516,9 @@ adlp_get_combo_buf_trans_dp(struct intel_encoder *encoder, int *n_entries) { if (crtc_state->port_clock > 270000) - return intel_get_buf_trans(&adlp_combo_phy_ddi_translations_dp_hbr2_hbr3, n_entries); + return intel_get_buf_trans(&adlp_combo_phy_trans_dp_hbr2_hbr3, n_entries); else - return intel_get_buf_trans(&adlp_combo_phy_ddi_translations_dp_hbr, n_entries); + return intel_get_buf_trans(&adlp_combo_phy_trans_dp_hbr, n_entries); } static const struct intel_ddi_buf_trans * @@ -1530,13 +1530,13 @@ adlp_get_combo_buf_trans_edp(struct intel_encoder *encoder, struct intel_dp *intel_dp = enc_to_intel_dp(encoder); if (crtc_state->port_clock > 540000) { - return intel_get_buf_trans(&adlp_combo_phy_ddi_translations_edp_hbr3, + return intel_get_buf_trans(&adlp_combo_phy_trans_edp_hbr3, n_entries); } else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed) { - return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_edp_hbr2_hobl, + return intel_get_buf_trans(&tgl_combo_phy_trans_edp_hbr2_hobl, n_entries); } else if (dev_priv->vbt.edp.low_vswing) { - return intel_get_buf_trans(&adlp_combo_phy_ddi_translations_edp_up_to_hbr2, + return intel_get_buf_trans(&adlp_combo_phy_trans_edp_up_to_hbr2, n_entries); } @@ -1549,7 +1549,7 @@ adlp_get_combo_buf_trans(struct intel_encoder *encoder, int *n_entries) { if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&adlp_combo_phy_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&adlp_combo_phy_trans_hdmi, n_entries); else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) return adlp_get_combo_buf_trans_edp(encoder, crtc_state, n_entries); else @@ -1562,10 +1562,10 @@ tgl_get_dkl_buf_trans_dp(struct intel_encoder *encoder, int *n_entries) { if (crtc_state->port_clock > 270000) { - return intel_get_buf_trans(&tgl_dkl_phy_ddi_translations_dp_hbr2, + return intel_get_buf_trans(&tgl_dkl_phy_trans_dp_hbr2, n_entries); } else { - return intel_get_buf_trans(&tgl_dkl_phy_ddi_translations_dp_hbr, + return intel_get_buf_trans(&tgl_dkl_phy_trans_dp_hbr, n_entries); } } @@ -1576,7 +1576,7 @@ tgl_get_dkl_buf_trans(struct intel_encoder *encoder, int *n_entries) { if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&tgl_dkl_phy_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&tgl_dkl_phy_trans_hdmi, n_entries); else return tgl_get_dkl_buf_trans_dp(encoder, crtc_state, n_entries); } @@ -1587,10 +1587,10 @@ adlp_get_dkl_buf_trans_dp(struct intel_encoder *encoder, int *n_entries) { if (crtc_state->port_clock > 270000) { - return intel_get_buf_trans(&adlp_dkl_phy_ddi_translations_dp_hbr2_hbr3, + return intel_get_buf_trans(&adlp_dkl_phy_trans_dp_hbr2_hbr3, n_entries); } else { - return intel_get_buf_trans(&adlp_dkl_phy_ddi_translations_dp_hbr, + return intel_get_buf_trans(&adlp_dkl_phy_trans_dp_hbr, n_entries); } } @@ -1601,7 +1601,7 @@ adlp_get_dkl_buf_trans(struct intel_encoder *encoder, int *n_entries) { if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_get_buf_trans(&tgl_dkl_phy_ddi_translations_hdmi, n_entries); + return intel_get_buf_trans(&tgl_dkl_phy_trans_hdmi, n_entries); else return adlp_get_dkl_buf_trans_dp(encoder, crtc_state, n_entries); } @@ -1612,9 +1612,9 @@ dg2_get_snps_buf_trans(struct intel_encoder *encoder, int *n_entries) { if (crtc_state->port_clock > 1000000) - return intel_get_buf_trans(&dg2_snps_translations_uhbr, n_entries); + return intel_get_buf_trans(&dg2_snps_trans_uhbr, n_entries); else - return intel_get_buf_trans(&dg2_snps_translations, n_entries); + return intel_get_buf_trans(&dg2_snps_trans, n_entries); } int intel_ddi_hdmi_num_entries(struct intel_encoder *encoder, @@ -1622,17 +1622,17 @@ int intel_ddi_hdmi_num_entries(struct intel_encoder *encoder, int *default_entry) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - const struct intel_ddi_buf_trans *ddi_translations; + const struct intel_ddi_buf_trans *trans; int n_entries; - ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON(&dev_priv->drm, !ddi_translations)) { + if (drm_WARN_ON(&dev_priv->drm, !trans)) { *default_entry = 0; return 0; } - *default_entry = ddi_translations->hdmi_default_entry; + *default_entry = trans->hdmi_default_entry; return n_entries; } diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c index 2405f70d82de..3734e349f91d 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c @@ -56,12 +56,12 @@ void intel_snps_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - const struct intel_ddi_buf_trans *ddi_translations; + const struct intel_ddi_buf_trans *trans; enum phy phy = intel_port_to_phy(dev_priv, encoder->port); int n_entries, ln; - ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) + trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; if (drm_WARN_ON_ONCE(&dev_priv->drm, level < 0 || level >= n_entries)) level = n_entries - 1; @@ -69,9 +69,9 @@ void intel_snps_phy_ddi_vswing_sequence(struct intel_encoder *encoder, for (ln = 0; ln < 4; ln++) { u32 val = 0; - val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, ddi_translations->entries[level].snps.snps_vswing); - val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_PRE, ddi_translations->entries[level].snps.snps_pre_cursor); - val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, ddi_translations->entries[level].snps.snps_post_cursor); + val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, trans->entries[level].snps.snps_vswing); + val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_PRE, trans->entries[level].snps.snps_pre_cursor); + val |= REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, trans->entries[level].snps.snps_post_cursor); intel_de_write(dev_priv, SNPS_PHY_TX_EQ(ln, phy), val); } -- cgit v1.2.3 From ac220f5f754b1d2f4a69428f515c3f1b10d1fad0 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Wed, 29 Sep 2021 17:14:01 -0700 Subject: drm/i915/display/psr: Handle plane and pipe restrictions at every page flip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PSR2 selective is not supported over rotated and scaled planes. We had the rotation check in intel_psr2_sel_fetch_config_valid() but that code path is only execute when a modeset is needed and those plane parameters can change without a modeset. Pipe selective fetch restrictions are also needed, it could be added in intel_psr_compute_config() but pippe scaling is computed after it is executed, so leaving as is for now. There is no much loss in this approach as it would cause selective fetch to not enabled as for alderlake-P and newer will cause it to switch to PSR1 that will have the same power-savings as do full pipe fetch. Also need to check those restricions in the second for_each_oldnew_intel_plane_in_state() loop because the state could only have a plane that is not affected by those restricitons but the damaged area intersect with planes that has those restrictions, so a full pipe fetch is required. v2: - also handling pipe restrictions BSpec: 55229 Reviewed-by: Gwan-gyeong Mun # v1 Cc: Ville Syrjälä Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210930001409.254817-1-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 65 ++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index f489bf9ca096..3cdd193ddb13 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -720,11 +720,7 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp, static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { - struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - struct intel_plane_state *plane_state; - struct intel_plane *plane; - int i; if (!dev_priv->params.enable_psr2_sel_fetch && intel_dp->psr.debug != I915_PSR_DEBUG_ENABLE_SEL_FETCH) { @@ -739,14 +735,6 @@ static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp, return false; } - for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - if (plane_state->uapi.rotation != DRM_MODE_ROTATE_0) { - drm_dbg_kms(&dev_priv->drm, - "PSR2 sel fetch not enabled, plane rotated\n"); - return false; - } - } - /* Wa_14010254185 Wa_14010103792 */ if (IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_C0)) { drm_dbg_kms(&dev_priv->drm, @@ -1580,6 +1568,41 @@ static void cursor_area_workaround(const struct intel_plane_state *new_plane_sta clip_area_update(pipe_clip, damaged_area); } +/* + * TODO: Not clear how to handle planes with negative position, + * also planes are not updated if they have a negative X + * position so for now doing a full update in this cases + * + * Plane scaling and rotation is not supported by selective fetch and both + * properties can change without a modeset, so need to be check at every + * atomic commmit. + */ +static bool psr2_sel_fetch_plane_state_supported(const struct intel_plane_state *plane_state) +{ + if (plane_state->uapi.dst.y1 < 0 || + plane_state->uapi.dst.x1 < 0 || + plane_state->scaler_id >= 0 || + plane_state->uapi.rotation != DRM_MODE_ROTATE_0) + return false; + + return true; +} + +/* + * Check for pipe properties that is not supported by selective fetch. + * + * TODO: pipe scaling causes a modeset but skl_update_scaler_crtc() is executed + * after intel_psr_compute_config(), so for now keeping PSR2 selective fetch + * enabled and going to the full update path. + */ +static bool psr2_sel_fetch_pipe_state_supported(const struct intel_crtc_state *crtc_state) +{ + if (crtc_state->scaler_state.scaler_id >= 0) + return false; + + return true; +} + int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -1593,6 +1616,11 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, if (!crtc_state->enable_psr2_sel_fetch) return 0; + if (!psr2_sel_fetch_pipe_state_supported(crtc_state)) { + full_update = true; + goto skip_sel_fetch_set_loop; + } + /* * Calculate minimal selective fetch area of each plane and calculate * the pipe damaged area. @@ -1612,13 +1640,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, !old_plane_state->uapi.visible) continue; - /* - * TODO: Not clear how to handle planes with negative position, - * also planes are not updated if they have a negative X - * position so for now doing a full update in this cases - */ - if (new_plane_state->uapi.dst.y1 < 0 || - new_plane_state->uapi.dst.x1 < 0) { + if (!psr2_sel_fetch_plane_state_supported(new_plane_state)) { full_update = true; break; } @@ -1697,6 +1719,11 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, if (!drm_rect_intersect(&inter, &new_plane_state->uapi.dst)) continue; + if (!psr2_sel_fetch_plane_state_supported(new_plane_state)) { + full_update = true; + break; + } + sel_fetch_area = &new_plane_state->psr2_sel_fetch_area; sel_fetch_area->y1 = inter.y1 - new_plane_state->uapi.dst.y1; sel_fetch_area->y2 = inter.y2 - new_plane_state->uapi.dst.y1; -- cgit v1.2.3 From 1f61f0655b95d5b89589390e6f83c4a61d9b1e8d Mon Sep 17 00:00:00 2001 From: Gwan-gyeong Mun Date: Wed, 29 Sep 2021 17:14:02 -0700 Subject: drm/i915/display/psr: Do full fetch when handling multi-planar formats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are still missing the PSR2 selective fetch handling of multi-planar formats but until proper handle is added we can workaround it by doing full frames fetch when state has such formats. Cc: Ville Syrjälä Signed-off-by: Gwan-gyeong Mun Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210930001409.254817-2-jose.souza@intel.com Signed-off-by: José Roberto de Souza --- drivers/gpu/drm/i915/display/intel_psr.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 3cdd193ddb13..ba1739b5895a 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1573,6 +1573,9 @@ static void cursor_area_workaround(const struct intel_plane_state *new_plane_sta * also planes are not updated if they have a negative X * position so for now doing a full update in this cases * + * TODO: We are missing multi-planar formats handling, until it is + * implemented it will send full frame updates. + * * Plane scaling and rotation is not supported by selective fetch and both * properties can change without a modeset, so need to be check at every * atomic commmit. @@ -1582,6 +1585,7 @@ static bool psr2_sel_fetch_plane_state_supported(const struct intel_plane_state if (plane_state->uapi.dst.y1 < 0 || plane_state->uapi.dst.x1 < 0 || plane_state->scaler_id >= 0 || + plane_state->hw.fb->format->num_planes > 1 || plane_state->uapi.rotation != DRM_MODE_ROTATE_0) return false; -- cgit v1.2.3 From 5da579cff38d64d024c1b99bafa3347c0d5fc107 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Wed, 29 Sep 2021 17:14:03 -0700 Subject: drm/i915/display: Drop unnecessary frontbuffer flushes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This unnecessary flushes are hurting power-savings are it causes features like PSR, FBC and DRRS to disable it self to handle frontbuffer rendering, below some explanation of why each removed call is not necessary. The flush in intel_prepare_plane_fb() is not required as framebuffer will be flipped and power-saving features do the proper flip handling in hardware. intel_find_initial_plane_obj() flush is not required because it is only executed during driver load and at this point the power-saving features are not even enabled. And the last one intelfb_create(), is also not required as at this point the fbdev was just allocated, userspace will draw on it what will trigger frontbuffer invalidates and flushes later on. Cc: Ville Syrjälä Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210930001409.254817-3-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 3 --- drivers/gpu/drm/i915/display/intel_fbdev.c | 2 -- 2 files changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a4453dd1bb51..1ce1d46dca5b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1711,8 +1711,6 @@ valid_fb: plane_state->uapi.crtc = &crtc->base; intel_plane_copy_uapi_to_hw_state(plane_state, plane_state, crtc); - intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB); - atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits); } @@ -10814,7 +10812,6 @@ intel_prepare_plane_fb(struct drm_plane *_plane, return ret; i915_gem_object_wait_priority(obj, 0, &attr); - i915_gem_object_flush_frontbuffer(obj, ORIGIN_DIRTYFB); if (!new_plane_state->uapi.fence) { /* implicit fencing */ struct dma_fence *fence; diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 60d3ded27047..53484267b2a4 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -230,8 +230,6 @@ static int intelfb_create(struct drm_fb_helper *helper, goto out_unlock; } - intel_frontbuffer_flush(to_frontbuffer(ifbdev), ORIGIN_DIRTYFB); - info = drm_fb_helper_alloc_fbi(helper); if (IS_ERR(info)) { drm_err(&dev_priv->drm, "Failed to allocate fb_info\n"); -- cgit v1.2.3 From 34ac6b651f39e63da8d0ae0edd2db32fbb1bc02c Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Wed, 29 Sep 2021 17:14:04 -0700 Subject: drm/i915/display: Handle frontbuffer rendering when PSR2 selective fetch is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When PSR2 selective fetch is enabled writes to CURSURFLIVE alone do not causes the panel to be updated when doing frontbuffer rendering. From what I was able to figure from experiments the writes to CURSURFLIVE takes PSR2 from deep sleep but panel is not updated because PSR2_MAN_TRK_CTL has no start and end region set. As we don't have the dirt area from current flush and invalidate API and even if we did userspace could do several draws to frontbuffer and we would need a way to append all the damaged areas of all the draws that need to be part of next frame. So here only programing PSR2_MAN_TRK_CTL to do a single full frame fetch. It is a safe approach as if scanout is in the visible area the single full frame will only be visible for hardware in the next frame because of the double buffering, and if scanout is in vblank area it will be draw in the current frame. No need to disable PSR and wait a few miliseconds to enable it again. Cc: Gwan-gyeong Mun Cc: Ville Syrjälä Signed-off-by: José Roberto de Souza Reviewed-by: Gwan-gyeong Mun Link: https://patchwork.freedesktop.org/patch/msgid/20210930001409.254817-4-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index ba1739b5895a..9a5259bbebab 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1397,10 +1397,22 @@ unlock: mutex_unlock(&psr->lock); } +static inline u32 man_trk_ctl_single_full_frame_bit_get(struct drm_i915_private *dev_priv) +{ + return IS_ALDERLAKE_P(dev_priv) ? + ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME : + PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME; +} + static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + if (intel_dp->psr.psr2_sel_fetch_enabled) + intel_de_rmw(dev_priv, + PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), 0, + man_trk_ctl_single_full_frame_bit_get(dev_priv)); + /* * Display WA #0884: skl+ * This documented WA for bxt can be safely applied @@ -1409,6 +1421,10 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp) * Workaround tells us to write 0 to CUR_SURFLIVE_A, * but it makes more sense write to the current active * pipe. + * + * This workaround do not exist for platforms with display 10 or newer + * but testing proved that it works for up display 13, for newer + * than that testing will be needed. */ intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0); } -- cgit v1.2.3 From ef39826c12b409010b8fb29fc47e2586cd2635ee Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Wed, 29 Sep 2021 17:14:05 -0700 Subject: drm/i915/display: Fix glitches when moving cursor with PSR2 selective fetch enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Legacy cursor APIs are handled by intel_legacy_cursor_update(), that calls drm_atomic_helper_update_plane() when going through the slow/atomic path to update cursor, what was the case for PSR2 selective fetch. drm_atomic_helper_update_plane() sets drm_atomic_state->legacy_cursor_update to true when updating the cursor plane, to allow several cursor updates to happen within the same frame, as userspace does that. If drivers waited for a vblank increment at the end of every cursor movement that would cause a visible lag in the cursor. But this optimization do not properly work with PSR2 selective fetch dirt area calculation, for example if within a single frame the cursor had 3 moves the final dirt area programmed to PSR2_MAN_TRK_CTL would be based in the second movement as old state and third movement as new state, not updating the area where cursor was in the first state. So here switching back to the fast path approach in intel_legacy_cursor_update() and handling cursor movements as frontbuffer rendering(psr_force_hw_tracking_exit()), that is not the most optimal for power-savings but is the solution that we have until mailbox style updates is implemented. Also removing the cursor workaround as not it is properly undestand the issue and is know that it will never cover all the cases. Cc: Ville Syrjälä Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Acked-by: Ville Syrjälä Reviewed-by: Gwan-gyeong Mun Link: https://patchwork.freedesktop.org/patch/msgid/20210930001409.254817-5-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_cursor.c | 5 +- drivers/gpu/drm/i915/display/intel_fbc.c | 4 +- drivers/gpu/drm/i915/display/intel_frontbuffer.h | 1 + drivers/gpu/drm/i915/display/intel_psr.c | 59 ++++++------------------ 4 files changed, 20 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 901ad3a4c8c3..f6dcb5aa63f6 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -639,8 +639,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane, * FIXME bigjoiner fastpath would be good */ if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state) || - crtc_state->update_pipe || crtc_state->bigjoiner || - crtc_state->enable_psr2_sel_fetch) + crtc_state->update_pipe || crtc_state->bigjoiner) goto slow; /* @@ -698,7 +697,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane, goto out_free; intel_frontbuffer_flush(to_intel_frontbuffer(new_plane_state->hw.fb), - ORIGIN_FLIP); + ORIGIN_CURSOR_UPDATE); intel_frontbuffer_track(to_intel_frontbuffer(old_plane_state->hw.fb), to_intel_frontbuffer(new_plane_state->hw.fb), plane->frontbuffer_bit); diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 687431faf02f..1f66de77a6b1 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1200,7 +1200,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, if (!HAS_FBC(dev_priv)) return; - if (origin == ORIGIN_FLIP) + if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE) return; mutex_lock(&fbc->lock); @@ -1225,7 +1225,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, fbc->busy_bits &= ~frontbuffer_bits; - if (origin == ORIGIN_FLIP) + if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE) goto out; if (!fbc->busy_bits && fbc->crtc && diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.h b/drivers/gpu/drm/i915/display/intel_frontbuffer.h index 4b977c1e4d52..a88441edc8f9 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.h +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.h @@ -37,6 +37,7 @@ enum fb_op_origin { ORIGIN_CS, ORIGIN_FLIP, ORIGIN_DIRTYFB, + ORIGIN_CURSOR_UPDATE, }; struct intel_frontbuffer { diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 9a5259bbebab..eddf4138b6a8 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1562,28 +1562,6 @@ static void intel_psr2_sel_fetch_pipe_alignment(const struct intel_crtc_state *c drm_warn(&dev_priv->drm, "Missing PSR2 sel fetch alignment with DSC\n"); } -/* - * FIXME: Not sure why but when moving the cursor fast it causes some artifacts - * of the cursor to be left in the cursor path, adding some pixels above the - * cursor to the damaged area fixes the issue. - */ -static void cursor_area_workaround(const struct intel_plane_state *new_plane_state, - struct drm_rect *damaged_area, - struct drm_rect *pipe_clip) -{ - const struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane); - int height; - - if (plane->id != PLANE_CURSOR) - return; - - height = drm_rect_height(&new_plane_state->uapi.dst) / 2; - damaged_area->y1 -= height; - damaged_area->y1 = max(damaged_area->y1, 0); - - clip_area_update(pipe_clip, damaged_area); -} - /* * TODO: Not clear how to handle planes with negative position, * also planes are not updated if they have a negative X @@ -1684,9 +1662,6 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, damaged_area.y2 = new_plane_state->uapi.dst.y2; clip_area_update(&pipe_clip, &damaged_area); } - - cursor_area_workaround(new_plane_state, &damaged_area, - &pipe_clip); continue; } else if (new_plane_state->uapi.alpha != old_plane_state->uapi.alpha) { /* If alpha changed mark the whole plane area as damaged */ @@ -2120,20 +2095,16 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv, /* * When we will be completely rely on PSR2 S/W tracking in future, * intel_psr_flush() will invalidate and flush the PSR for ORIGIN_FLIP - * event also therefore tgl_dc3co_flush() require to be changed + * event also therefore tgl_dc3co_flush_locked() require to be changed * accordingly in future. */ static void -tgl_dc3co_flush(struct intel_dp *intel_dp, unsigned int frontbuffer_bits, - enum fb_op_origin origin) +tgl_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits, + enum fb_op_origin origin) { - mutex_lock(&intel_dp->psr.lock); - - if (!intel_dp->psr.dc3co_exitline) - goto unlock; - - if (!intel_dp->psr.psr2_enabled || !intel_dp->psr.active) - goto unlock; + if (!intel_dp->psr.dc3co_exitline || !intel_dp->psr.psr2_enabled || + !intel_dp->psr.active) + return; /* * At every frontbuffer flush flip event modified delay of delayed work, @@ -2141,14 +2112,11 @@ tgl_dc3co_flush(struct intel_dp *intel_dp, unsigned int frontbuffer_bits, */ if (!(frontbuffer_bits & INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe))) - goto unlock; + return; tgl_psr2_enable_dc3co(intel_dp); mod_delayed_work(system_wq, &intel_dp->psr.dc3co_work, intel_dp->psr.dc3co_exit_delay); - -unlock: - mutex_unlock(&intel_dp->psr.lock); } /** @@ -2173,11 +2141,6 @@ void intel_psr_flush(struct drm_i915_private *dev_priv, unsigned int pipe_frontbuffer_bits = frontbuffer_bits; struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - if (origin == ORIGIN_FLIP) { - tgl_dc3co_flush(intel_dp, frontbuffer_bits, origin); - continue; - } - mutex_lock(&intel_dp->psr.lock); if (!intel_dp->psr.enabled) { mutex_unlock(&intel_dp->psr.lock); @@ -2198,6 +2161,14 @@ void intel_psr_flush(struct drm_i915_private *dev_priv, continue; } + if (origin == ORIGIN_FLIP || + (origin == ORIGIN_CURSOR_UPDATE && + !intel_dp->psr.psr2_sel_fetch_enabled)) { + tgl_dc3co_flush_locked(intel_dp, frontbuffer_bits, origin); + mutex_unlock(&intel_dp->psr.lock); + continue; + } + /* By definition flush = invalidate + flush */ if (pipe_frontbuffer_bits) psr_force_hw_tracking_exit(intel_dp); -- cgit v1.2.3 From 1163649a047995c77527023f192d00ae1971965b Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Wed, 29 Sep 2021 17:14:06 -0700 Subject: drm/i915/display/adlp: Optimize PSR2 power-savings in corner cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Wa_14014971508 is required to fix scanout when a feature that i915 do not support is enabled and this feature is not planned to be enabled for adlp. Keeping this workaround enabled can badly hurt power-savings when a full frame fetch is required(see psr2_sel_fetch_plane_state_supported() and psr2_sel_fetch_pipe_state_supported()). Here a example that could badly hurt power-savings, userspace does a page flip to a rotated plane, so CONTINUOS_FULL_FRAME set. But then for a whole 30 seconds nothing in the screen requires updates but because CONTINUOS_FULL_FRAME is set, it will not go into DC5/DC6. Reverting Wa_14014971508 fixes that, as only a single frame will be sent and then display can go to DC5/DC6 for those 30 seconds of idleness. BSpec: 54369 Cc: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Reviewed-by: Gwan-gyeong Mun Link: https://patchwork.freedesktop.org/patch/msgid/20210930001409.254817-6-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index eddf4138b6a8..05b9b103a98f 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1503,15 +1503,10 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, if (full_update) { /* - * Wa_14014971508:adlp - * SINGLE_FULL_FRAME bit is not hold in register so can not be - * restored by DMC, so using CONTINUOS_FULL_FRAME to mimic that + * Not applying Wa_14014971508:adlp as we do not support the + * feature that requires this workaround. */ - if (IS_ALDERLAKE_P(dev_priv)) - val |= ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME; - else - val |= PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME; - + val |= man_trk_ctl_single_full_frame_bit_get(dev_priv); goto exit; } -- cgit v1.2.3 From de572e881b9d7f19da74981dd320699ea796e5a3 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Wed, 29 Sep 2021 17:14:07 -0700 Subject: drm/i915/display/adlp: Allow PSR2 to be enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With all the recent fixes PSR2 is properly working in Alderlake-P but due to some issues that don't have software workarounds it will not be supported in display steppings older than B0. Even with this patch PSR2 will no be enabled by default in ADL-P, it still requires enable_psr2_sel_fetch to be set to true, what some of our tests does. Cc: Gwan-gyeong Mun Reviewed-by: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210930001409.254817-7-jose.souza@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 05b9b103a98f..7a205fd5023b 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -830,12 +830,8 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, return false; } - /* - * We are missing the implementation of some workarounds to enabled PSR2 - * in Alderlake_P, until ready PSR2 should be kept disabled. - */ - if (IS_ALDERLAKE_P(dev_priv)) { - drm_dbg_kms(&dev_priv->drm, "PSR2 is missing the implementation of workarounds\n"); + if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) { + drm_dbg_kms(&dev_priv->drm, "PSR2 not completely functional in this stepping\n"); return false; } -- cgit v1.2.3 From 7f6002e58025cf001e4be34306731f2f8f893638 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Wed, 29 Sep 2021 17:14:08 -0700 Subject: drm/i915/display: Enable PSR2 selective fetch by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With all the past fixes now this feature is functional and can be enabled by default in desktop enviroments that uses compositor. Cc: Gwan-gyeong Mun Cc: Ville Syrjälä Reviewed-by: Gwan-gyeong Mun Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20210930001409.254817-8-jose.souza@intel.com --- drivers/gpu/drm/i915/i915_params.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index f27eceb82c0f..8d725b64592d 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -55,7 +55,7 @@ struct drm_printer; param(int, enable_fbc, -1, 0600) \ param(int, enable_psr, -1, 0600) \ param(bool, psr_safest_params, false, 0400) \ - param(bool, enable_psr2_sel_fetch, false, 0400) \ + param(bool, enable_psr2_sel_fetch, true, 0400) \ param(int, disable_power_well, -1, 0400) \ param(int, enable_ips, 1, 0600) \ param(int, invert_brightness, 0, 0600) \ -- cgit v1.2.3 From e04a911f436619fff2e57470a50fd2b2436eb6eb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Sep 2021 12:22:58 +0300 Subject: drm/i915/fdi: move fdi modeset asserts to intel_fdi.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep the functionality and the assert code together. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/427d27eb4e5daca208d496d6c2ffc91ed90ba714.1632992608.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 72 ---------------------- drivers/gpu/drm/i915/display/intel_display.h | 4 -- drivers/gpu/drm/i915/display/intel_fdi.c | 91 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_fdi.h | 10 +++ drivers/gpu/drm/i915/display/intel_lvds.c | 1 + 5 files changed, 102 insertions(+), 76 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 1ce1d46dca5b..05e42903bde0 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -428,78 +428,6 @@ void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state) onoff(state), onoff(cur_state)); } -static void assert_fdi_tx(struct drm_i915_private *dev_priv, - enum pipe pipe, bool state) -{ - bool cur_state; - - if (HAS_DDI(dev_priv)) { - /* - * DDI does not have a specific FDI_TX register. - * - * FDI is never fed from EDP transcoder - * so pipe->transcoder cast is fine here. - */ - enum transcoder cpu_transcoder = (enum transcoder)pipe; - u32 val = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(cpu_transcoder)); - cur_state = !!(val & TRANS_DDI_FUNC_ENABLE); - } else { - u32 val = intel_de_read(dev_priv, FDI_TX_CTL(pipe)); - cur_state = !!(val & FDI_TX_ENABLE); - } - I915_STATE_WARN(cur_state != state, - "FDI TX state assertion failure (expected %s, current %s)\n", - onoff(state), onoff(cur_state)); -} -#define assert_fdi_tx_enabled(d, p) assert_fdi_tx(d, p, true) -#define assert_fdi_tx_disabled(d, p) assert_fdi_tx(d, p, false) - -static void assert_fdi_rx(struct drm_i915_private *dev_priv, - enum pipe pipe, bool state) -{ - u32 val; - bool cur_state; - - val = intel_de_read(dev_priv, FDI_RX_CTL(pipe)); - cur_state = !!(val & FDI_RX_ENABLE); - I915_STATE_WARN(cur_state != state, - "FDI RX state assertion failure (expected %s, current %s)\n", - onoff(state), onoff(cur_state)); -} -#define assert_fdi_rx_enabled(d, p) assert_fdi_rx(d, p, true) -#define assert_fdi_rx_disabled(d, p) assert_fdi_rx(d, p, false) - -static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - u32 val; - - /* ILK FDI PLL is always enabled */ - if (IS_IRONLAKE(dev_priv)) - return; - - /* On Haswell, DDI ports are responsible for the FDI PLL setup */ - if (HAS_DDI(dev_priv)) - return; - - val = intel_de_read(dev_priv, FDI_TX_CTL(pipe)); - I915_STATE_WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n"); -} - -void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, - enum pipe pipe, bool state) -{ - u32 val; - bool cur_state; - - val = intel_de_read(dev_priv, FDI_RX_CTL(pipe)); - cur_state = !!(val & FDI_RX_PLL_ENABLE); - I915_STATE_WARN(cur_state != state, - "FDI RX PLL assertion failure (expected %s, current %s)\n", - onoff(state), onoff(cur_state)); -} - void assert_panel_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe) { i915_reg_t pp_reg; diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 87b96fed5e0b..8cb3bb33cbe0 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -654,10 +654,6 @@ void assert_pll(struct drm_i915_private *dev_priv, void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state); #define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true) #define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false) -void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, - enum pipe pipe, bool state); -#define assert_fdi_rx_pll_enabled(d, p) assert_fdi_rx_pll(d, p, true) -#define assert_fdi_rx_pll_disabled(d, p) assert_fdi_rx_pll(d, p, false) void assert_transcoder(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder, bool state); #define assert_transcoder_enabled(d, t) assert_transcoder(d, t, true) diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index af01d1fa761e..02d3294bad7b 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -10,6 +10,97 @@ #include "intel_fdi.h" #include "intel_sideband.h" +static void assert_fdi_tx(struct drm_i915_private *dev_priv, + enum pipe pipe, bool state) +{ + bool cur_state; + + if (HAS_DDI(dev_priv)) { + /* + * DDI does not have a specific FDI_TX register. + * + * FDI is never fed from EDP transcoder + * so pipe->transcoder cast is fine here. + */ + enum transcoder cpu_transcoder = (enum transcoder)pipe; + cur_state = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)) & TRANS_DDI_FUNC_ENABLE; + } else { + cur_state = intel_de_read(dev_priv, FDI_TX_CTL(pipe)) & FDI_TX_ENABLE; + } + I915_STATE_WARN(cur_state != state, + "FDI TX state assertion failure (expected %s, current %s)\n", + onoff(state), onoff(cur_state)); +} + +void assert_fdi_tx_enabled(struct drm_i915_private *i915, enum pipe pipe) +{ + assert_fdi_tx(i915, pipe, true); +} + +void assert_fdi_tx_disabled(struct drm_i915_private *i915, enum pipe pipe) +{ + assert_fdi_tx(i915, pipe, false); +} + +static void assert_fdi_rx(struct drm_i915_private *dev_priv, + enum pipe pipe, bool state) +{ + bool cur_state; + + cur_state = intel_de_read(dev_priv, FDI_RX_CTL(pipe)) & FDI_RX_ENABLE; + I915_STATE_WARN(cur_state != state, + "FDI RX state assertion failure (expected %s, current %s)\n", + onoff(state), onoff(cur_state)); +} + +void assert_fdi_rx_enabled(struct drm_i915_private *i915, enum pipe pipe) +{ + assert_fdi_rx(i915, pipe, true); +} + +void assert_fdi_rx_disabled(struct drm_i915_private *i915, enum pipe pipe) +{ + assert_fdi_rx(i915, pipe, false); +} + +void assert_fdi_tx_pll_enabled(struct drm_i915_private *i915, + enum pipe pipe) +{ + bool cur_state; + + /* ILK FDI PLL is always enabled */ + if (IS_IRONLAKE(i915)) + return; + + /* On Haswell, DDI ports are responsible for the FDI PLL setup */ + if (HAS_DDI(i915)) + return; + + cur_state = intel_de_read(i915, FDI_TX_CTL(pipe)) & FDI_TX_PLL_ENABLE; + I915_STATE_WARN(!cur_state, "FDI TX PLL assertion failure, should be active but is disabled\n"); +} + +static void assert_fdi_rx_pll(struct drm_i915_private *i915, + enum pipe pipe, bool state) +{ + bool cur_state; + + cur_state = intel_de_read(i915, FDI_RX_CTL(pipe)) & FDI_RX_PLL_ENABLE; + I915_STATE_WARN(cur_state != state, + "FDI RX PLL assertion failure (expected %s, current %s)\n", + onoff(state), onoff(cur_state)); +} + +void assert_fdi_rx_pll_enabled(struct drm_i915_private *i915, enum pipe pipe) +{ + assert_fdi_rx_pll(i915, pipe, true); +} + +void assert_fdi_rx_pll_disabled(struct drm_i915_private *i915, enum pipe pipe) +{ + assert_fdi_rx_pll(i915, pipe, false); +} + void intel_fdi_link_train(struct intel_crtc *crtc, const struct intel_crtc_state *crtc_state) { diff --git a/drivers/gpu/drm/i915/display/intel_fdi.h b/drivers/gpu/drm/i915/display/intel_fdi.h index 61cb216a09f5..d557fc603d7d 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.h +++ b/drivers/gpu/drm/i915/display/intel_fdi.h @@ -6,6 +6,7 @@ #ifndef _INTEL_FDI_H_ #define _INTEL_FDI_H_ +enum pipe; struct drm_i915_private; struct intel_crtc; struct intel_crtc_state; @@ -28,4 +29,13 @@ void lpt_fdi_program_mphy(struct drm_i915_private *i915); void intel_fdi_link_train(struct intel_crtc *crtc, const struct intel_crtc_state *crtc_state); + +void assert_fdi_tx_enabled(struct drm_i915_private *i915, enum pipe pipe); +void assert_fdi_tx_disabled(struct drm_i915_private *i915, enum pipe pipe); +void assert_fdi_rx_enabled(struct drm_i915_private *i915, enum pipe pipe); +void assert_fdi_rx_disabled(struct drm_i915_private *i915, enum pipe pipe); +void assert_fdi_tx_pll_enabled(struct drm_i915_private *i915, enum pipe pipe); +void assert_fdi_rx_pll_enabled(struct drm_i915_private *i915, enum pipe pipe); +void assert_fdi_rx_pll_disabled(struct drm_i915_private *i915, enum pipe pipe); + #endif diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 130e6ea61e11..6155eb0c0a5c 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -44,6 +44,7 @@ #include "intel_connector.h" #include "intel_de.h" #include "intel_display_types.h" +#include "intel_fdi.h" #include "intel_gmbus.h" #include "intel_lvds.h" #include "intel_panel.h" -- cgit v1.2.3 From aa0813b1ba31c345fb745bc8ece6e5b7cbfca71b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Sep 2021 12:22:59 +0300 Subject: drm/i915/pps: move pps (panel) modeset asserts to intel_pps.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move assert_panel_unlocked() to intel_pps.c and rename assert_pps_unlocked(). Keep the functionality and the assert code together. There's still a bit of a split between the eDP PPS usage in intel_pps.c and all the other PPS usage, and assert_pps_unlocked() is arguably more related to the latter. However, intel_pps.c is the best fit for anything touching the PPS registers. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/a9b77692a145891789eefb0447e082cfc22aaa85.1632992608.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 60 +--------------------------- drivers/gpu/drm/i915/display/intel_display.h | 2 - drivers/gpu/drm/i915/display/intel_dpll.c | 13 +++--- drivers/gpu/drm/i915/display/intel_pps.c | 59 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_pps.h | 3 ++ 5 files changed, 71 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 05e42903bde0..34201e71593b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -428,64 +428,6 @@ void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state) onoff(state), onoff(cur_state)); } -void assert_panel_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe) -{ - i915_reg_t pp_reg; - u32 val; - enum pipe panel_pipe = INVALID_PIPE; - bool locked = true; - - if (drm_WARN_ON(&dev_priv->drm, HAS_DDI(dev_priv))) - return; - - if (HAS_PCH_SPLIT(dev_priv)) { - u32 port_sel; - - pp_reg = PP_CONTROL(0); - port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK; - - switch (port_sel) { - case PANEL_PORT_SELECT_LVDS: - intel_lvds_port_enabled(dev_priv, PCH_LVDS, &panel_pipe); - break; - case PANEL_PORT_SELECT_DPA: - g4x_dp_port_enabled(dev_priv, DP_A, PORT_A, &panel_pipe); - break; - case PANEL_PORT_SELECT_DPC: - g4x_dp_port_enabled(dev_priv, PCH_DP_C, PORT_C, &panel_pipe); - break; - case PANEL_PORT_SELECT_DPD: - g4x_dp_port_enabled(dev_priv, PCH_DP_D, PORT_D, &panel_pipe); - break; - default: - MISSING_CASE(port_sel); - break; - } - } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - /* presumably write lock depends on pipe, not port select */ - pp_reg = PP_CONTROL(pipe); - panel_pipe = pipe; - } else { - u32 port_sel; - - pp_reg = PP_CONTROL(0); - port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK; - - drm_WARN_ON(&dev_priv->drm, - port_sel != PANEL_PORT_SELECT_LVDS); - intel_lvds_port_enabled(dev_priv, LVDS, &panel_pipe); - } - - val = intel_de_read(dev_priv, pp_reg); - if (!(val & PANEL_POWER_ON) || - ((val & PANEL_UNLOCK_MASK) == PANEL_UNLOCK_REGS)) - locked = false; - - I915_STATE_WARN(panel_pipe == pipe && locked, - "panel assertion failure, pipe %c regs locked\n", - pipe_name(pipe)); -} - void assert_transcoder(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder, bool state) { @@ -2128,7 +2070,7 @@ static void ilk_pch_enable(const struct intel_atomic_state *state, intel_enable_shared_dpll(crtc_state); /* set transcoder timing, panel must allow it */ - assert_panel_unlocked(dev_priv, pipe); + assert_pps_unlocked(dev_priv, pipe); ilk_pch_transcoder_set_timings(crtc_state, pipe); intel_fdi_normal_train(crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 8cb3bb33cbe0..5306d119b2c0 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -645,8 +645,6 @@ void intel_init_pch_refclk(struct drm_i915_private *dev_priv); int intel_modeset_all_pipes(struct intel_atomic_state *state); /* modesetting asserts */ -void assert_panel_unlocked(struct drm_i915_private *dev_priv, - enum pipe pipe); void assert_pll(struct drm_i915_private *dev_priv, enum pipe pipe, bool state); #define assert_pll_enabled(d, p) assert_pll(d, p, true) diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 784e3ee658b5..66784204f6f7 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -2,16 +2,19 @@ /* * Copyright © 2020 Intel Corporation */ + #include + #include "intel_crtc.h" #include "intel_de.h" -#include "intel_display_types.h" #include "intel_display.h" +#include "intel_display_types.h" #include "intel_dpll.h" #include "intel_lvds.h" #include "intel_panel.h" +#include "intel_pps.h" #include "intel_sideband.h" -#include "display/intel_snps_phy.h" +#include "intel_snps_phy.h" struct intel_limit { struct { @@ -1438,7 +1441,7 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state) /* PLL is protected by panel, make sure we can write it */ if (i9xx_has_pps(dev_priv)) - assert_panel_unlocked(dev_priv, pipe); + assert_pps_unlocked(dev_priv, pipe); intel_de_write(dev_priv, FP0(pipe), crtc_state->dpll_hw_state.fp0); intel_de_write(dev_priv, FP1(pipe), crtc_state->dpll_hw_state.fp1); @@ -1617,7 +1620,7 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state) assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ - assert_panel_unlocked(dev_priv, pipe); + assert_pps_unlocked(dev_priv, pipe); /* Enable Refclk */ intel_de_write(dev_priv, DPLL(pipe), @@ -1769,7 +1772,7 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state) assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ - assert_panel_unlocked(dev_priv, pipe); + assert_pps_unlocked(dev_priv, pipe); /* Enable Refclk and SSC */ intel_de_write(dev_priv, DPLL(pipe), diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index a36ec4a818ff..e9c679bb1b2e 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -9,6 +9,7 @@ #include "intel_display_types.h" #include "intel_dp.h" #include "intel_dpll.h" +#include "intel_lvds.h" #include "intel_pps.h" static void vlv_steal_power_sequencer(struct drm_i915_private *dev_priv, @@ -1408,3 +1409,61 @@ void intel_pps_setup(struct drm_i915_private *i915) else i915->pps_mmio_base = PPS_BASE; } + +void assert_pps_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe) +{ + i915_reg_t pp_reg; + u32 val; + enum pipe panel_pipe = INVALID_PIPE; + bool locked = true; + + if (drm_WARN_ON(&dev_priv->drm, HAS_DDI(dev_priv))) + return; + + if (HAS_PCH_SPLIT(dev_priv)) { + u32 port_sel; + + pp_reg = PP_CONTROL(0); + port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK; + + switch (port_sel) { + case PANEL_PORT_SELECT_LVDS: + intel_lvds_port_enabled(dev_priv, PCH_LVDS, &panel_pipe); + break; + case PANEL_PORT_SELECT_DPA: + g4x_dp_port_enabled(dev_priv, DP_A, PORT_A, &panel_pipe); + break; + case PANEL_PORT_SELECT_DPC: + g4x_dp_port_enabled(dev_priv, PCH_DP_C, PORT_C, &panel_pipe); + break; + case PANEL_PORT_SELECT_DPD: + g4x_dp_port_enabled(dev_priv, PCH_DP_D, PORT_D, &panel_pipe); + break; + default: + MISSING_CASE(port_sel); + break; + } + } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + /* presumably write lock depends on pipe, not port select */ + pp_reg = PP_CONTROL(pipe); + panel_pipe = pipe; + } else { + u32 port_sel; + + pp_reg = PP_CONTROL(0); + port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK; + + drm_WARN_ON(&dev_priv->drm, + port_sel != PANEL_PORT_SELECT_LVDS); + intel_lvds_port_enabled(dev_priv, LVDS, &panel_pipe); + } + + val = intel_de_read(dev_priv, pp_reg); + if (!(val & PANEL_POWER_ON) || + ((val & PANEL_UNLOCK_MASK) == PANEL_UNLOCK_REGS)) + locked = false; + + I915_STATE_WARN(panel_pipe == pipe && locked, + "panel assertion failure, pipe %c regs locked\n", + pipe_name(pipe)); +} diff --git a/drivers/gpu/drm/i915/display/intel_pps.h b/drivers/gpu/drm/i915/display/intel_pps.h index fbbcca782e7b..fbb47f6f453e 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.h +++ b/drivers/gpu/drm/i915/display/intel_pps.h @@ -10,6 +10,7 @@ #include "intel_wakeref.h" +enum pipe; struct drm_i915_private; struct intel_connector; struct intel_crtc_state; @@ -49,4 +50,6 @@ void vlv_pps_init(struct intel_encoder *encoder, void intel_pps_unlock_regs_wa(struct drm_i915_private *i915); void intel_pps_setup(struct drm_i915_private *i915); +void assert_pps_unlocked(struct drm_i915_private *i915, enum pipe pipe); + #endif /* __INTEL_PPS_H__ */ -- cgit v1.2.3 From 80e77e30a2126a5d8b5765795c31ee636a660736 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Sep 2021 12:23:00 +0300 Subject: drm/i915/dpll: move dpll modeset asserts to intel_dpll.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep the functionality and the assert code together. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/0229659fb8af6c91c774408c6f7bb8c4ff8735e3.1632992608.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_color.c | 1 + drivers/gpu/drm/i915/display/intel_display.c | 14 -------------- drivers/gpu/drm/i915/display/intel_display.h | 4 ---- drivers/gpu/drm/i915/display/intel_display_power.c | 3 ++- drivers/gpu/drm/i915/display/intel_dpll.c | 22 ++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dpll.h | 3 +++ drivers/gpu/drm/i915/display/intel_lvds.c | 1 + 7 files changed, 29 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index f5923f1c38bd..34463aeec25c 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -25,6 +25,7 @@ #include "intel_color.h" #include "intel_de.h" #include "intel_display_types.h" +#include "intel_dpll.h" #define CTM_COEFF_SIGN (1ULL << 63) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 34201e71593b..9d2b6bd94d36 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -398,20 +398,6 @@ intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state) } } -/* Only for pre-ILK configs */ -void assert_pll(struct drm_i915_private *dev_priv, - enum pipe pipe, bool state) -{ - u32 val; - bool cur_state; - - val = intel_de_read(dev_priv, DPLL(pipe)); - cur_state = !!(val & DPLL_VCO_ENABLE); - I915_STATE_WARN(cur_state != state, - "PLL state assertion failure (expected %s, current %s)\n", - onoff(state), onoff(cur_state)); -} - /* XXX: the dsi pll is shared between MIPI DSI ports */ void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state) { diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 5306d119b2c0..b3ccec541aa0 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -645,10 +645,6 @@ void intel_init_pch_refclk(struct drm_i915_private *dev_priv); int intel_modeset_all_pipes(struct intel_atomic_state *state); /* modesetting asserts */ -void assert_pll(struct drm_i915_private *dev_priv, - enum pipe pipe, bool state); -#define assert_pll_enabled(d, p) assert_pll(d, p, true) -#define assert_pll_disabled(d, p) assert_pll(d, p, false) void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state); #define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true) #define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 2410c1a617ea..06e9879aedd7 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -9,11 +9,12 @@ #include "i915_irq.h" #include "intel_cdclk.h" #include "intel_combo_phy.h" -#include "intel_display_power.h" #include "intel_de.h" +#include "intel_display_power.h" #include "intel_display_types.h" #include "intel_dmc.h" #include "intel_dpio_phy.h" +#include "intel_dpll.h" #include "intel_hotplug.h" #include "intel_pm.h" #include "intel_pps.h" diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 66784204f6f7..b84ed4a1bd95 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -1923,3 +1923,25 @@ void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe) else vlv_disable_pll(dev_priv, pipe); } + +/* Only for pre-ILK configs */ +static void assert_pll(struct drm_i915_private *dev_priv, + enum pipe pipe, bool state) +{ + bool cur_state; + + cur_state = intel_de_read(dev_priv, DPLL(pipe)) & DPLL_VCO_ENABLE; + I915_STATE_WARN(cur_state != state, + "PLL state assertion failure (expected %s, current %s)\n", + onoff(state), onoff(cur_state)); +} + +void assert_pll_enabled(struct drm_i915_private *i915, enum pipe pipe) +{ + assert_pll(i915, pipe, true); +} + +void assert_pll_disabled(struct drm_i915_private *i915, enum pipe pipe) +{ + assert_pll(i915, pipe, false); +} diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h b/drivers/gpu/drm/i915/display/intel_dpll.h index db396b3e1141..1af0ac43cca4 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.h +++ b/drivers/gpu/drm/i915/display/intel_dpll.h @@ -36,4 +36,7 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, struct dpll *best_clock); int chv_calc_dpll_params(int refclk, struct dpll *pll_clock); +void assert_pll_enabled(struct drm_i915_private *i915, enum pipe pipe); +void assert_pll_disabled(struct drm_i915_private *i915, enum pipe pipe); + #endif diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 6155eb0c0a5c..9fced37bed70 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -44,6 +44,7 @@ #include "intel_connector.h" #include "intel_de.h" #include "intel_display_types.h" +#include "intel_dpll.h" #include "intel_fdi.h" #include "intel_gmbus.h" #include "intel_lvds.h" -- cgit v1.2.3 From e365e4aaa5cc4f7048c73603d7e58accda0ddd3a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Sep 2021 12:23:01 +0300 Subject: drm/i915/dsi: move dsi pll modeset asserts to vlv_dsi_pll.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep the functionality and the assert code together. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/0a5fa9b8d4d4615d4e6503b6bb33541c0bccffbb.1632992608.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_color.c | 1 + drivers/gpu/drm/i915/display/intel_display.c | 16 ---------------- drivers/gpu/drm/i915/display/intel_display.h | 3 --- drivers/gpu/drm/i915/display/intel_dsi.h | 3 +++ drivers/gpu/drm/i915/display/vlv_dsi_pll.c | 23 +++++++++++++++++++++++ 5 files changed, 27 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 34463aeec25c..5359b7305a78 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -26,6 +26,7 @@ #include "intel_de.h" #include "intel_display_types.h" #include "intel_dpll.h" +#include "intel_dsi.h" #define CTM_COEFF_SIGN (1ULL << 63) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9d2b6bd94d36..4e9a6c9c2deb 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -398,22 +398,6 @@ intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state) } } -/* XXX: the dsi pll is shared between MIPI DSI ports */ -void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state) -{ - u32 val; - bool cur_state; - - vlv_cck_get(dev_priv); - val = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL); - vlv_cck_put(dev_priv); - - cur_state = val & DSI_PLL_VCO_EN; - I915_STATE_WARN(cur_state != state, - "DSI PLL state assertion failure (expected %s, current %s)\n", - onoff(state), onoff(cur_state)); -} - void assert_transcoder(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder, bool state) { diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index b3ccec541aa0..3028072c2cf3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -645,9 +645,6 @@ void intel_init_pch_refclk(struct drm_i915_private *dev_priv); int intel_modeset_all_pipes(struct intel_atomic_state *state); /* modesetting asserts */ -void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state); -#define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true) -#define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false) void assert_transcoder(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder, bool state); #define assert_transcoder_enabled(d, t) assert_transcoder(d, t, true) diff --git a/drivers/gpu/drm/i915/display/intel_dsi.h b/drivers/gpu/drm/i915/display/intel_dsi.h index 50d6da0b2419..fbc40ffdc02e 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi.h +++ b/drivers/gpu/drm/i915/display/intel_dsi.h @@ -207,6 +207,9 @@ u32 bxt_dsi_get_pclk(struct intel_encoder *encoder, struct intel_crtc_state *config); void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port); +void assert_dsi_pll_enabled(struct drm_i915_private *i915); +void assert_dsi_pll_disabled(struct drm_i915_private *i915); + /* intel_dsi_vbt.c */ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id); void intel_dsi_vbt_gpio_init(struct intel_dsi *intel_dsi, bool panel_is_on); diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c index 90185b219447..0078973cd219 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c @@ -568,3 +568,26 @@ void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) } intel_de_write(dev_priv, MIPI_EOT_DISABLE(port), CLOCKSTOP); } + +static void assert_dsi_pll(struct drm_i915_private *i915, bool state) +{ + bool cur_state; + + vlv_cck_get(i915); + cur_state = vlv_cck_read(i915, CCK_REG_DSI_PLL_CONTROL) & DSI_PLL_VCO_EN; + vlv_cck_put(i915); + + I915_STATE_WARN(cur_state != state, + "DSI PLL state assertion failure (expected %s, current %s)\n", + onoff(state), onoff(cur_state)); +} + +void assert_dsi_pll_enabled(struct drm_i915_private *i915) +{ + assert_dsi_pll(i915, true); +} + +void assert_dsi_pll_disabled(struct drm_i915_private *i915) +{ + assert_dsi_pll(i915, false); +} -- cgit v1.2.3 From 3e2947cd894506c8c0c6cb6ffb704e121e934ae8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Sep 2021 14:24:31 +0300 Subject: drm/i915/dsi: pass struct mipi_dsi_packet pointer, not the entire struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass a const pointer instead of passing 32 bytes of struct mipi_dsi_packet by value. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/c67d2fa0d97bf336a321497775b9717d85d44a51.1633000838.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index c196993f0d68..11ef40230e8f 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -153,7 +153,8 @@ static bool add_payld_to_queue(struct intel_dsi_host *host, const u8 *data, } static int dsi_send_pkt_hdr(struct intel_dsi_host *host, - struct mipi_dsi_packet pkt, bool enable_lpdt) + const struct mipi_dsi_packet *packet, + bool enable_lpdt) { struct intel_dsi *intel_dsi = host->intel_dsi; struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); @@ -166,7 +167,7 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host, tmp = intel_de_read(dev_priv, DSI_CMD_TXHDR(dsi_trans)); - if (pkt.payload) + if (packet->payload) tmp |= PAYLOAD_PRESENT; else tmp &= ~PAYLOAD_PRESENT; @@ -177,30 +178,29 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host, tmp |= LP_DATA_TRANSFER; tmp &= ~(PARAM_WC_MASK | VC_MASK | DT_MASK); - tmp |= ((pkt.header[0] & VC_MASK) << VC_SHIFT); - tmp |= ((pkt.header[0] & DT_MASK) << DT_SHIFT); - tmp |= (pkt.header[1] << PARAM_WC_LOWER_SHIFT); - tmp |= (pkt.header[2] << PARAM_WC_UPPER_SHIFT); + tmp |= ((packet->header[0] & VC_MASK) << VC_SHIFT); + tmp |= ((packet->header[0] & DT_MASK) << DT_SHIFT); + tmp |= (packet->header[1] << PARAM_WC_LOWER_SHIFT); + tmp |= (packet->header[2] << PARAM_WC_UPPER_SHIFT); intel_de_write(dev_priv, DSI_CMD_TXHDR(dsi_trans), tmp); return 0; } static int dsi_send_pkt_payld(struct intel_dsi_host *host, - struct mipi_dsi_packet pkt) + const struct mipi_dsi_packet *packet) { struct intel_dsi *intel_dsi = host->intel_dsi; struct drm_i915_private *i915 = to_i915(intel_dsi->base.base.dev); /* payload queue can accept *256 bytes*, check limit */ - if (pkt.payload_length > MAX_PLOAD_CREDIT * 4) { + if (packet->payload_length > MAX_PLOAD_CREDIT * 4) { drm_err(&i915->drm, "payload size exceeds max queue limit\n"); return -1; } /* load data into command payload queue */ - if (!add_payld_to_queue(host, pkt.payload, - pkt.payload_length)) { + if (!add_payld_to_queue(host, packet->payload, packet->payload_length)) { drm_err(&i915->drm, "adding payload to queue failed\n"); return -1; } @@ -1840,13 +1840,13 @@ static ssize_t gen11_dsi_host_transfer(struct mipi_dsi_host *host, /* only long packet contains payload */ if (mipi_dsi_packet_format_is_long(msg->type)) { - ret = dsi_send_pkt_payld(intel_dsi_host, dsi_pkt); + ret = dsi_send_pkt_payld(intel_dsi_host, &dsi_pkt); if (ret < 0) return ret; } /* send packet header */ - ret = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt); + ret = dsi_send_pkt_hdr(intel_dsi_host, &dsi_pkt, enable_lpdt); if (ret < 0) return ret; -- cgit v1.2.3 From 207ea507a1478dcc7085ce74e15dfc62b67ec11b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Sep 2021 14:24:32 +0300 Subject: drm/i915/dsi: fuse dsi_send_pkt_payld() and add_payld_to_queue() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Having two functions for this seems like excess duplication and parameter juggling. Merge them together. While at it, drop the extra error message, as wait_for_payload_credits() already prints an error, and switch from incidental -EPERM (i.e. -1) to actual error codes. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/f74f7462a36e76070db6b4c01616d0eb663b9938.1633000838.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 43 ++++++++++++---------------------- 1 file changed, 15 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 11ef40230e8f..0daa90058ee3 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -129,27 +129,35 @@ static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder) } } -static bool add_payld_to_queue(struct intel_dsi_host *host, const u8 *data, - u32 len) +static int dsi_send_pkt_payld(struct intel_dsi_host *host, + const struct mipi_dsi_packet *packet) { struct intel_dsi *intel_dsi = host->intel_dsi; - struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); + struct drm_i915_private *i915 = to_i915(intel_dsi->base.base.dev); enum transcoder dsi_trans = dsi_port_to_transcoder(host->port); + const u8 *data = packet->payload; + u32 len = packet->payload_length; int i, j; + /* payload queue can accept *256 bytes*, check limit */ + if (len > MAX_PLOAD_CREDIT * 4) { + drm_err(&i915->drm, "payload size exceeds max queue limit\n"); + return -EINVAL; + } + for (i = 0; i < len; i += 4) { u32 tmp = 0; - if (!wait_for_payload_credits(dev_priv, dsi_trans, 1)) - return false; + if (!wait_for_payload_credits(i915, dsi_trans, 1)) + return -EBUSY; for (j = 0; j < min_t(u32, len - i, 4); j++) tmp |= *data++ << 8 * j; - intel_de_write(dev_priv, DSI_CMD_TXPYLD(dsi_trans), tmp); + intel_de_write(i915, DSI_CMD_TXPYLD(dsi_trans), tmp); } - return true; + return 0; } static int dsi_send_pkt_hdr(struct intel_dsi_host *host, @@ -187,27 +195,6 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host, return 0; } -static int dsi_send_pkt_payld(struct intel_dsi_host *host, - const struct mipi_dsi_packet *packet) -{ - struct intel_dsi *intel_dsi = host->intel_dsi; - struct drm_i915_private *i915 = to_i915(intel_dsi->base.base.dev); - - /* payload queue can accept *256 bytes*, check limit */ - if (packet->payload_length > MAX_PLOAD_CREDIT * 4) { - drm_err(&i915->drm, "payload size exceeds max queue limit\n"); - return -1; - } - - /* load data into command payload queue */ - if (!add_payld_to_queue(host, packet->payload, packet->payload_length)) { - drm_err(&i915->drm, "adding payload to queue failed\n"); - return -1; - } - - return 0; -} - void icl_dsi_frame_update(struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); -- cgit v1.2.3 From b90acd0987c81e4c8d7b4e7995ff3cecd16b2122 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Sep 2021 14:24:33 +0300 Subject: drm/i915/dsi: return -EBUSY instead of -1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid using the incidental -EPERM. Also remove useless comment. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/37df1edc6d3745997cec2dfe41520d9f704e14b4.1633000838.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 0daa90058ee3..9ee62707ec72 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -169,9 +169,8 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host, enum transcoder dsi_trans = dsi_port_to_transcoder(host->port); u32 tmp; - /* check if header credit available */ if (!wait_for_header_credits(dev_priv, dsi_trans, 1)) - return -1; + return -EBUSY; tmp = intel_de_read(dev_priv, DSI_CMD_TXHDR(dsi_trans)); -- cgit v1.2.3 From 0743019d540d18e7a5db220bf4c4b95650aa8c9e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Sep 2021 14:24:34 +0300 Subject: drm/i915/hdmi: return -EINVAL instead of -1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid using the incidental -EPERM. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/8acf7ffe9222d23c7f47dbd95ff1f737221ff72c.1633000838.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 1bc33766ed39..468a107aaabc 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -1703,7 +1703,7 @@ int intel_hdmi_hdcp2_read_msg(struct intel_digital_port *dig_port, drm_dbg_kms(&i915->drm, "msg_sz(%zd) is more than exp size(%zu)\n", ret, size); - return -1; + return -EINVAL; } offset = HDCP_2_2_HDMI_REG_RD_MSG_OFFSET; -- cgit v1.2.3 From 5e9a0200dad83f8620af04c733cd7f93bb0efb8c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Sep 2021 14:24:35 +0300 Subject: drm/i915/drv: return -EIO instead of -1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid using the incidental -EPERM. Return the -EIO directly from i915_get_bridge_dev() instead of converting return values later. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1ee72c31963d8be98490cd78f7c1182ba4f54c13.1633000838.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 59fb4c710c8c..d9f208802ae0 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -97,7 +97,7 @@ static int i915_get_bridge_dev(struct drm_i915_private *dev_priv) pci_get_domain_bus_and_slot(domain, 0, PCI_DEVFN(0, 0)); if (!dev_priv->bridge_dev) { drm_err(&dev_priv->drm, "bridge device not found\n"); - return -1; + return -EIO; } return 0; } @@ -409,8 +409,9 @@ static int i915_driver_mmio_probe(struct drm_i915_private *dev_priv) if (i915_inject_probe_failure(dev_priv)) return -ENODEV; - if (i915_get_bridge_dev(dev_priv)) - return -EIO; + ret = i915_get_bridge_dev(dev_priv); + if (ret < 0) + return ret; ret = intel_uncore_init_mmio(&dev_priv->uncore); if (ret < 0) -- cgit v1.2.3 From 7d8de8cabbba77eb35cdf075ab76a4b994a926ec Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Sep 2021 14:24:36 +0300 Subject: drm/i915/dram: return -EINVAL instead of -1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid using the incidental -EPERM. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/e2f79220ed2558f615c051e2533275a5dae1a04f.1633000838.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dram.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dram.c b/drivers/gpu/drm/i915/intel_dram.c index 91866520c173..30a0cab5eff4 100644 --- a/drivers/gpu/drm/i915/intel_dram.c +++ b/drivers/gpu/drm/i915/intel_dram.c @@ -444,7 +444,7 @@ static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv) break; default: MISSING_CASE(val & 0xf); - return -1; + return -EINVAL; } } else { switch (val & 0xf) { @@ -462,7 +462,7 @@ static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv) break; default: MISSING_CASE(val & 0xf); - return -1; + return -EINVAL; } } -- cgit v1.2.3 From a23299bb9a49f08e0609b6136b3ee1da5ed486e5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Sep 2021 12:32:29 +0300 Subject: drm/i915/fdi: use -EAGAIN instead of local special return value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using standard -EAGAIN should be perfectly fine instead of using a special case value. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210930093229.28598-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 11 +++++------ drivers/gpu/drm/i915/display/intel_fdi.c | 2 +- drivers/gpu/drm/i915/display/intel_fdi.h | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 4e9a6c9c2deb..5f8f233f0e3c 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7555,12 +7555,7 @@ encoder_retry: ret = intel_crtc_compute_config(to_intel_crtc(crtc), pipe_config); if (ret == -EDEADLK) return ret; - if (ret < 0) { - drm_dbg_kms(&i915->drm, "CRTC fixup failed\n"); - return ret; - } - - if (ret == I915_DISPLAY_CONFIG_RETRY) { + if (ret == -EAGAIN) { if (drm_WARN(&i915->drm, !retry, "loop in pipe configuration computation\n")) return -EINVAL; @@ -7569,6 +7564,10 @@ encoder_retry: retry = false; goto encoder_retry; } + if (ret < 0) { + drm_dbg_kms(&i915->drm, "CRTC fixup failed\n"); + return ret; + } /* Dithering seems to not pass-through bits correctly when it should, so * only enable it on 6bpc panels and when its not a compliance diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 02d3294bad7b..51d6f810e69b 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -267,7 +267,7 @@ retry: } if (needs_recompute) - return I915_DISPLAY_CONFIG_RETRY; + return -EAGAIN; return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_fdi.h b/drivers/gpu/drm/i915/display/intel_fdi.h index d557fc603d7d..640d6585c137 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.h +++ b/drivers/gpu/drm/i915/display/intel_fdi.h @@ -12,7 +12,6 @@ struct intel_crtc; struct intel_crtc_state; struct intel_encoder; -#define I915_DISPLAY_CONFIG_RETRY 1 int intel_fdi_link_freq(struct drm_i915_private *i915, const struct intel_crtc_state *pipe_config); int ilk_fdi_compute_config(struct intel_crtc *intel_crtc, -- cgit v1.2.3 From 7ceb751b615900086eed1d65955933923f127d99 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 21 Sep 2021 14:02:44 +0300 Subject: drm/i915/hdmi: convert intel_hdmi_to_dev to intel_hdmi_to_i915 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prefer i915 over drm pointer. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210921110244.8666-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_hdmi.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 468a107aaabc..d2e61f6c6e08 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -53,21 +53,20 @@ #include "intel_panel.h" #include "intel_snps_phy.h" -static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi) +static struct drm_i915_private *intel_hdmi_to_i915(struct intel_hdmi *intel_hdmi) { - return hdmi_to_dig_port(intel_hdmi)->base.base.dev; + return to_i915(hdmi_to_dig_port(intel_hdmi)->base.base.dev); } static void assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi) { - struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi); - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = intel_hdmi_to_i915(intel_hdmi); u32 enabled_bits; enabled_bits = HAS_DDI(dev_priv) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE; - drm_WARN(dev, + drm_WARN(&dev_priv->drm, intel_de_read(dev_priv, intel_hdmi->hdmi_reg) & enabled_bits, "HDMI port enabled, expecting disabled\n"); } @@ -1246,7 +1245,7 @@ static void hsw_set_infoframes(struct intel_encoder *encoder, void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable) { - struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi)); + struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); struct i2c_adapter *adapter = intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); @@ -1830,7 +1829,7 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, int clock, bool respect_downstream_limits, bool has_hdmi_sink) { - struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi)); + struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); if (clock < 25000) return MODE_CLOCK_LOW; @@ -1946,8 +1945,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector)); - struct drm_device *dev = intel_hdmi_to_dev(hdmi); - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); enum drm_mode_status status; int clock = mode->clock; int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; -- cgit v1.2.3 From 5ec2b4f77e77b747b69afe10a261850a3d3b8e1c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Aug 2021 15:53:42 +0300 Subject: drm/i915/debugfs: register LPSP capability on all platforms The debugfs file shows it's not capable, don't duplicate the info. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/939453050a5a5175a12a08f16542c1b40bd726dc.1630327990.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 68f4ba8c46e7..455283b1a36b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -2485,14 +2485,11 @@ int intel_connector_debugfs_add(struct drm_connector *connector) connector, &i915_dsc_bpp_fops); } - /* Legacy panels doesn't lpsp on any platform */ - if ((DISPLAY_VER(dev_priv) >= 9 || IS_HASWELL(dev_priv) || - IS_BROADWELL(dev_priv)) && - (connector->connector_type == DRM_MODE_CONNECTOR_DSI || - connector->connector_type == DRM_MODE_CONNECTOR_eDP || - connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort || - connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || - connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) + if (connector->connector_type == DRM_MODE_CONNECTOR_DSI || + connector->connector_type == DRM_MODE_CONNECTOR_eDP || + connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort || + connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || + connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) debugfs_create_file("i915_lpsp_capability", 0444, root, connector, &i915_lpsp_capability_fops); -- cgit v1.2.3 From fd71fc38da7d5d59e12657c8f2696cda7abd9dda Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Aug 2021 15:53:43 +0300 Subject: drm/i915/display: stop returning errors from debugfs registration Failures to register debugfs should be ignored anyway, so stop propagating errors altogether for clarity and simplicity. No functional changes. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/346562ccef2282ccdbdea54409fab1d2b48f313c.1630327990.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 19 +++++-------------- drivers/gpu/drm/i915/display/intel_display_debugfs.h | 8 ++++---- 2 files changed, 9 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 455283b1a36b..c4a2ead24b58 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -2442,17 +2442,15 @@ static const struct file_operations i915_dsc_bpp_fops = { * * Cleanup will be done by drm_connector_unregister() through a call to * drm_debugfs_connector_remove(). - * - * Returns 0 on success, negative error codes on error. */ -int intel_connector_debugfs_add(struct drm_connector *connector) +void intel_connector_debugfs_add(struct drm_connector *connector) { struct dentry *root = connector->debugfs_entry; struct drm_i915_private *dev_priv = to_i915(connector->dev); /* The connector must have been registered beforehands. */ if (!root) - return -ENODEV; + return; if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { debugfs_create_file("i915_panel_timings", S_IRUGO, root, @@ -2492,23 +2490,16 @@ int intel_connector_debugfs_add(struct drm_connector *connector) connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) debugfs_create_file("i915_lpsp_capability", 0444, root, connector, &i915_lpsp_capability_fops); - - return 0; } /** * intel_crtc_debugfs_add - add i915 specific crtc debugfs files * @crtc: pointer to a drm_crtc * - * Returns 0 on success, negative error codes on error. - * * Failure to add debugfs entries should generally be ignored. */ -int intel_crtc_debugfs_add(struct drm_crtc *crtc) +void intel_crtc_debugfs_add(struct drm_crtc *crtc) { - if (!crtc->debugfs_entry) - return -ENODEV; - - crtc_updates_add(crtc); - return 0; + if (crtc->debugfs_entry) + crtc_updates_add(crtc); } diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.h b/drivers/gpu/drm/i915/display/intel_display_debugfs.h index 557901f3eb90..c72e35ecba1f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.h +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.h @@ -12,12 +12,12 @@ struct drm_i915_private; #ifdef CONFIG_DEBUG_FS void intel_display_debugfs_register(struct drm_i915_private *i915); -int intel_connector_debugfs_add(struct drm_connector *connector); -int intel_crtc_debugfs_add(struct drm_crtc *crtc); +void intel_connector_debugfs_add(struct drm_connector *connector); +void intel_crtc_debugfs_add(struct drm_crtc *crtc); #else static inline void intel_display_debugfs_register(struct drm_i915_private *i915) {} -static inline int intel_connector_debugfs_add(struct drm_connector *connector) { return 0; } -static inline int intel_crtc_debugfs_add(struct drm_crtc *crtc) { return 0; } +static inline void intel_connector_debugfs_add(struct drm_connector *connector) {} +static inline void intel_crtc_debugfs_add(struct drm_crtc *crtc) {} #endif #endif /* __INTEL_DISPLAY_DEBUGFS_H__ */ -- cgit v1.2.3 From 0f26c8e23ab33fb85a09695771041f5a6a608939 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 Aug 2021 17:02:22 +0300 Subject: drm/i915/debugfs: pass intel_connector to intel_connector_debugfs_add() Prefer the intel_ types. No functional changes. v2: Fix build. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210830140222.12228-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_connector.c | 2 +- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 3 ++- drivers/gpu/drm/i915/display/intel_display_debugfs.h | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c index 4f49d782eca2..c65f95a9a1ec 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.c +++ b/drivers/gpu/drm/i915/display/intel_connector.c @@ -124,7 +124,7 @@ int intel_connector_register(struct drm_connector *connector) goto err_backlight; } - intel_connector_debugfs_add(connector); + intel_connector_debugfs_add(intel_connector); return 0; diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index c4a2ead24b58..309d74fd86ce 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -2443,8 +2443,9 @@ static const struct file_operations i915_dsc_bpp_fops = { * Cleanup will be done by drm_connector_unregister() through a call to * drm_debugfs_connector_remove(). */ -void intel_connector_debugfs_add(struct drm_connector *connector) +void intel_connector_debugfs_add(struct intel_connector *intel_connector) { + struct drm_connector *connector = &intel_connector->base; struct dentry *root = connector->debugfs_entry; struct drm_i915_private *dev_priv = to_i915(connector->dev); diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.h b/drivers/gpu/drm/i915/display/intel_display_debugfs.h index c72e35ecba1f..d3a79c07c384 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.h +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.h @@ -6,17 +6,17 @@ #ifndef __INTEL_DISPLAY_DEBUGFS_H__ #define __INTEL_DISPLAY_DEBUGFS_H__ -struct drm_connector; struct drm_crtc; struct drm_i915_private; +struct intel_connector; #ifdef CONFIG_DEBUG_FS void intel_display_debugfs_register(struct drm_i915_private *i915); -void intel_connector_debugfs_add(struct drm_connector *connector); +void intel_connector_debugfs_add(struct intel_connector *connector); void intel_crtc_debugfs_add(struct drm_crtc *crtc); #else static inline void intel_display_debugfs_register(struct drm_i915_private *i915) {} -static inline void intel_connector_debugfs_add(struct drm_connector *connector) {} +static inline void intel_connector_debugfs_add(struct intel_connector *connector) {} static inline void intel_crtc_debugfs_add(struct drm_crtc *crtc) {} #endif -- cgit v1.2.3 From 048a57fc0d6ab76174eebe7e0c993a370bf516c1 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 30 Sep 2021 13:41:31 +0300 Subject: drm/i915: Use standard form -EDEADLK check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unify how we check for -EDEADLK vs. other errors from crtc vs. encoder compute_config() calls. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210930104133.30854-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 5f8f233f0e3c..59bb346aa36e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7537,11 +7537,10 @@ encoder_retry: ret = encoder->compute_config(encoder, pipe_config, connector_state); + if (ret == -EDEADLK) + return ret; if (ret < 0) { - if (ret != -EDEADLK) - drm_dbg_kms(&i915->drm, - "Encoder config failure: %d\n", - ret); + drm_dbg_kms(&i915->drm, "Encoder config failure: %d\n", ret); return ret; } } -- cgit v1.2.3 From 0fb00cc28e1ed1e9052f3231acfd085471d0397b Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 30 Sep 2021 13:41:32 +0300 Subject: drm/i915: Adjust intel_crtc_compute_config() debug message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "CRTC fixup failed" is probably leftovers from pre-atomic days when there was an actual fixup() function. Let's unify the debug messages between encoder vs. crtc compute_config() calls. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210930104133.30854-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 59bb346aa36e..27c65c8dc181 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7564,7 +7564,7 @@ encoder_retry: goto encoder_retry; } if (ret < 0) { - drm_dbg_kms(&i915->drm, "CRTC fixup failed\n"); + drm_dbg_kms(&i915->drm, "CRTC config failure: %d\n", ret); return ret; } -- cgit v1.2.3 From ab953f099fd7d0c28d3e35dcd008651aad57db6f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 30 Sep 2021 13:41:33 +0300 Subject: drm/i915: Move WaPruneModeWithIncorrectHsyncOffset into intel_mode_valid() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check for the zero length front porch already in intel_mode_valid() so that we get the same validation for both get_modes() and setcrtc()/etc. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210930104133.30854-3-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 27c65c8dc181..583153435ac3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -4046,13 +4046,6 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, } } - /* Cantiga+ cannot handle modes with a hsync front porch of 0. - * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw. - */ - if ((DISPLAY_VER(dev_priv) > 4 || IS_G4X(dev_priv)) && - pipe_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay) - return -EINVAL; - intel_crtc_compute_pixel_rate(pipe_config); if (pipe_config->has_pch_encoder) @@ -11159,6 +11152,14 @@ intel_mode_valid(struct drm_device *dev, return MODE_V_ILLEGAL; } + /* + * Cantiga+ cannot handle modes with a hsync front porch of 0. + * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw. + */ + if ((DISPLAY_VER(dev_priv) > 4 || IS_G4X(dev_priv)) && + mode->hsync_start == mode->hdisplay) + return MODE_H_ILLEGAL; + return MODE_OK; } -- cgit v1.2.3 From f22f4e5be89c4296d76eaa9ba83dda46bdf11134 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 28 Sep 2021 21:51:05 +0300 Subject: drm/i915: Stop force enabling pipe bottom color gammma/csc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While sanitizing the hardware state we're currently forcing the pipe bottom color legacy csc/gamma bits on. That is not a good idea as BIOSen are likely to leave gabage in the LUTs and so doing this causes ugly visual glitches if and when the planes covering the background get disabled. This was exactly the case on this Dell Precision 5560 tgl laptop. On icl+ we don't normally even use these legacy bits anymore and instead use their GAMMA_MODE counterparts. On earlier platforms the bits are used, but we still shouldn't force them on without knowing what's in the LUT. So two options, get rid of the whole thing, or do what intel_color_commit() does to make sure the bottom color state matches whatever out hardware readout produced. I chose the latter since it'll match what happens on older platforms when the primary plane gets turned off. In fact let's just call intel_color_commit(). It'll also do some CSC programming but since we don't have readout for that it'll actually just set to all zeros. So in the unlikely case of CSC actually being enabld by the BIOS we'll end up with all black until the first atomic commit happens. Still not totally sure what we should do about color management features here in general. Probably the safest thing would be to force everything off exactly at the same time when we disable the primary plane as there is no guarantees that whatever the LUTs/CSCs contain make any sense whatsoever without the specific pixel data in the BIOS fb. And if we preserve the primary plane then we should disable the color management features exactly when the primary plane fb contents first changes since the new content assumes more or less no transformations. But of course synchronizing front buffer rendering with anything else is a bit hard... Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/3534 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210928185105.3030-1-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/display/intel_display.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 583153435ac3..873b6b0c0581 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -11996,13 +11996,8 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc, intel_plane_disable_noatomic(crtc, plane); } - /* - * Disable any background color set by the BIOS, but enable the - * gamma and CSC to match how we program our planes. - */ - if (DISPLAY_VER(dev_priv) >= 9) - intel_de_write(dev_priv, SKL_BOTTOM_COLOR(crtc->pipe), - SKL_BOTTOM_COLOR_GAMMA_ENABLE | SKL_BOTTOM_COLOR_CSC_ENABLE); + /* Disable any background color/etc. set by the BIOS */ + intel_color_commit(crtc_state); } /* Adjust the state of the output pipe according to whether we -- cgit v1.2.3 From 5def925dbb60bcdd8ce6f860d80abc749dd5e1ef Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 4 Oct 2021 10:31:33 +1000 Subject: drm/i915: fix regression with uncore refactoring. This was causing infinite recursion on snb/ivb. Fixes: 5716c8c6f4b6 ("drm/i915/uncore: split the fw get function into separate vfunc") Signed-off-by: Dave Airlie Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20211004003133.2279446-1-airlied@gmail.com --- drivers/gpu/drm/i915/intel_uncore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 2dac69d92c1b..f1b816ebcdf6 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -346,7 +346,7 @@ static void __gen6_gt_wait_for_thread_c0(struct intel_uncore *uncore) static void fw_domains_get_with_thread_status(struct intel_uncore *uncore, enum forcewake_domains fw_domains) { - fw_domains_get(uncore, fw_domains); + fw_domains_get_normal(uncore, fw_domains); /* WaRsForcewakeWaitTC0:snb,ivb,hsw,bdw,vlv */ __gen6_gt_wait_for_thread_c0(uncore); -- cgit v1.2.3 From 7d4fed884484d6631fba759905f0dce308ddb8a4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 1 Oct 2021 13:03:16 +0300 Subject: drm/i915/reg: add AUD_TCA_DP_2DOT0_CTRL registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For controlling the audio SDP split. Bspec: 63837 Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20211001100316.26441-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c78337ab4f7b..c6e883bd4850 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9733,6 +9733,11 @@ enum { #define AUDIO_CP_READY(trans) ((1 << 1) << ((trans) * 4)) #define AUDIO_ELD_VALID(trans) ((1 << 0) << ((trans) * 4)) +#define _AUD_TCA_DP_2DOT0_CTRL 0x650bc +#define _AUD_TCB_DP_2DOT0_CTRL 0x651bc +#define AUD_DP_2DOT0_CTRL(trans) _MMIO_TRANS(trans, _AUD_TCA_DP_2DOT0_CTRL, _AUD_TCB_DP_2DOT0_CTRL) +#define AUD_ENABLE_SDP_SPLIT REG_BIT(31) + #define HSW_AUD_CHICKENBIT _MMIO(0x65f10) #define SKL_AUD_CODEC_WAKE_SIGNAL (1 << 15) -- cgit v1.2.3 From f6e3be98654ed1895b105ed0ddf67665ed83dda4 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Oct 2021 19:08:26 +0300 Subject: drm/i915: Fix DP clock recovery "voltage_tries" handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DP spec says: "If the receiver keeps the same value in the ADJUST_REQUEST_LANEx_y register(s) while the LANEx_CR_DONE bits remain unset, the transmitter must loop four times with the same voltage swing. On the fifth time, the transmitter must down-shift to the lower bit rate and must repeat the CR-lock training sequence as described below." Lets fix the code to follow that instead of terminating after five times of transmitting the same signal levels. The text in spec feels a little bit ambiguous still, but this is my best guess at its meaning. As a bonus this also gets rid of the train_set[0] stuff which would not work for per-lane drive settings anyway. Cc: Imre Deak CC: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211001160826.17080-1-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- .../gpu/drm/i915/display/intel_dp_link_training.c | 29 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 053ed9302cda..73a823f1ec22 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -511,6 +511,25 @@ static void intel_dp_link_training_clock_recovery_delay(struct intel_dp *intel_d drm_dp_lttpr_link_train_clock_recovery_delay(); } +static bool intel_dp_adjust_request_changed(int lane_count, + const u8 old_link_status[DP_LINK_STATUS_SIZE], + const u8 new_link_status[DP_LINK_STATUS_SIZE]) +{ + int lane; + + for (lane = 0; lane < lane_count; lane++) { + u8 old = drm_dp_get_adjust_request_voltage(old_link_status, lane) | + drm_dp_get_adjust_request_pre_emphasis(old_link_status, lane); + u8 new = drm_dp_get_adjust_request_voltage(new_link_status, lane) | + drm_dp_get_adjust_request_pre_emphasis(new_link_status, lane); + + if (old != new) + return true; + } + + return false; +} + /* * Perform the link training clock recovery phase on the given DP PHY using * training pattern 1. @@ -521,7 +540,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, enum drm_dp_phy dp_phy) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); - u8 voltage; + u8 old_link_status[DP_LINK_STATUS_SIZE] = {}; int voltage_tries, cr_tries, max_cr_tries; bool max_vswing_reached = false; @@ -574,8 +593,6 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, return false; } - voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; - /* Update training set as requested by target */ intel_dp_get_adjust_train(intel_dp, crtc_state, dp_phy, link_status); @@ -585,12 +602,14 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, return false; } - if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == - voltage) + if (!intel_dp_adjust_request_changed(crtc_state->lane_count, + old_link_status, link_status)) ++voltage_tries; else voltage_tries = 1; + memcpy(old_link_status, link_status, sizeof(link_status)); + if (intel_dp_link_max_vswing_reached(intel_dp, crtc_state)) max_vswing_reached = true; -- cgit v1.2.3 From f820693bc2381d73d2769d8b7cc16210f21244a8 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Oct 2021 16:00:58 +0300 Subject: drm/i915: Introduce has_iboost() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suck the "do we have iboost?" platform checks into a small helper. Cc: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211001130107.1746-2-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_ddi.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 51cd0420e00e..f6429114ce7c 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -92,6 +92,11 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder, return level; } +static bool has_iboost(struct drm_i915_private *i915) +{ + return DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915); +} + /* * Starting with Haswell, DDI port buffers must be programmed with correct * values in advance. This function programs the correct values for @@ -111,7 +116,7 @@ void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder, return; /* If we're boosting the current, set bit 31 of trans1 */ - if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv) && + if (has_iboost(dev_priv) && intel_bios_encoder_dp_boost_level(encoder->devdata)) iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; @@ -145,7 +150,7 @@ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, level = n_entries - 1; /* If we're boosting the current, set bit 31 of trans1 */ - if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv) && + if (has_iboost(dev_priv) && intel_bios_encoder_hdmi_boost_level(encoder->devdata)) iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; @@ -1463,7 +1468,7 @@ hsw_set_signal_levels(struct intel_dp *intel_dp, intel_dp->DP &= ~DDI_BUF_EMP_MASK; intel_dp->DP |= signal_levels; - if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) + if (has_iboost(dev_priv)) skl_ddi_set_iboost(encoder, crtc_state, level); intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); @@ -3084,7 +3089,7 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state, else hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state, level); - if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) + if (has_iboost(dev_priv)) skl_ddi_set_iboost(encoder, crtc_state, level); /* Display WA #1143: skl,kbl,cfl */ -- cgit v1.2.3 From 5bafd85dd77080730ca7115ba6b5c4ef88493b6b Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Oct 2021 16:00:59 +0300 Subject: drm/i915: Introduce has_buf_trans_select() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a small helper to determine if DDI_BUF_CTL uses the DDI_BUF_TRANS_SELECT field, and whether we have the accompanying DDI_BUF_TRANS table in the hardware. Cc: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211001130107.1746-3-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_ddi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index f6429114ce7c..dbcf4ddd0f3b 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -92,6 +92,11 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder, return level; } +static bool has_buf_trans_select(struct drm_i915_private *i915) +{ + return DISPLAY_VER(i915) < 10 && !IS_BROXTON(i915); +} + static bool has_iboost(struct drm_i915_private *i915) { return DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915); @@ -2640,7 +2645,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, icl_ddi_vswing_sequence(encoder, crtc_state, level); else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) bxt_ddi_vswing_sequence(encoder, crtc_state, level); - else + + if (has_buf_trans_select(dev_priv)) hsw_prepare_dp_ddi_buffers(encoder, crtc_state); intel_ddi_power_up_lanes(encoder, crtc_state); @@ -3086,7 +3092,8 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state, icl_ddi_vswing_sequence(encoder, crtc_state, level); else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) bxt_ddi_vswing_sequence(encoder, crtc_state, level); - else + + if (has_buf_trans_select(dev_priv)) hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state, level); if (has_iboost(dev_priv)) -- cgit v1.2.3 From e722ab8b69689cff49f50fcc7c55065615180f4e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Oct 2021 16:01:00 +0300 Subject: drm/i915: Generalize .set_signal_levels() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently .set_signal_levels() is only used by encoders in DP mode. For most modern platforms there is no essential difference between DP and HDMI, and both codepaths just end up calling the same function under the hood. Let's get remove the need for that extra indirection by moving .set_signal_levels() into the encoder from intel_dp. Since we already plumb the crtc_state/etc. into .set_signal_levels() the code will do the right thing for both DP and HDMI. HSW/BDW/SKL are the only platforms that need a bit of care on account of having to preload the hardware buf_trans register with the full set of values. So we must still remember to call hsw_prepare_{dp,hdmi}_ddi_buffers() to do said preloading, and .set_signal_levels() will just end up selecting the correct entry for DP, and also setting up the iboost magic for both DP and HDMI. Note that previously on HSW/BDW/SKL we did write to DDI_BUF_CTL to select the correct entry until link training started, now that we call .set_signal_levels() already from hsw_ddi_pre_enable_dp() that is no longer the case. But it's all safe now that the intel_ddi_init_dp_buf_reg() call was hoisted up and it no longer sets up the DDI_BUF_CTL_ENABLE bit (that is still deferred until link training). v2: Rebase due to has_{iboost,buf_trans_select}() Add some notes about the DDI_BUF_CTL situation on HSW/BDW/SKL (Imre) Reviewed-by: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211001130107.1746-4-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/g4x_dp.c | 33 ++++--- drivers/gpu/drm/i915/display/intel_ddi.c | 104 ++++++++++----------- drivers/gpu/drm/i915/display/intel_display_types.h | 5 +- .../gpu/drm/i915/display/intel_dp_link_training.c | 5 +- 4 files changed, 71 insertions(+), 76 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 69a2e5ad2317..60ae2ba52006 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -808,10 +808,10 @@ static u8 intel_dp_preemph_max_3(struct intel_dp *intel_dp) return DP_TRAIN_PRE_EMPH_LEVEL_3; } -static void vlv_set_signal_levels(struct intel_dp *intel_dp, +static void vlv_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); unsigned long demph_reg_value, preemph_reg_value, uniqtranscale_reg_value; u8 train_set = intel_dp->train_set[0]; @@ -894,10 +894,10 @@ static void vlv_set_signal_levels(struct intel_dp *intel_dp, uniqtranscale_reg_value, 0); } -static void chv_set_signal_levels(struct intel_dp *intel_dp, +static void chv_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); u32 deemph_reg_value, margin_reg_value; bool uniq_trans_scale = false; u8 train_set = intel_dp->train_set[0]; @@ -1015,10 +1015,11 @@ static u32 g4x_signal_levels(u8 train_set) } static void -g4x_set_signal_levels(struct intel_dp *intel_dp, +g4x_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); u8 train_set = intel_dp->train_set[0]; u32 signal_levels; @@ -1062,10 +1063,11 @@ static u32 snb_cpu_edp_signal_levels(u8 train_set) } static void -snb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp, +snb_cpu_edp_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); u8 train_set = intel_dp->train_set[0]; u32 signal_levels; @@ -1113,10 +1115,11 @@ static u32 ivb_cpu_edp_signal_levels(u8 train_set) } static void -ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp, +ivb_cpu_edp_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); u8 train_set = intel_dp->train_set[0]; u32 signal_levels; @@ -1359,15 +1362,15 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv, dig_port->dp.set_link_train = g4x_set_link_train; if (IS_CHERRYVIEW(dev_priv)) - dig_port->dp.set_signal_levels = chv_set_signal_levels; + intel_encoder->set_signal_levels = chv_set_signal_levels; else if (IS_VALLEYVIEW(dev_priv)) - dig_port->dp.set_signal_levels = vlv_set_signal_levels; + intel_encoder->set_signal_levels = vlv_set_signal_levels; else if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) - dig_port->dp.set_signal_levels = ivb_cpu_edp_set_signal_levels; + intel_encoder->set_signal_levels = ivb_cpu_edp_set_signal_levels; else if (IS_SANDYBRIDGE(dev_priv) && port == PORT_A) - dig_port->dp.set_signal_levels = snb_cpu_edp_set_signal_levels; + intel_encoder->set_signal_levels = snb_cpu_edp_set_signal_levels; else - dig_port->dp.set_signal_levels = g4x_set_signal_levels; + intel_encoder->set_signal_levels = g4x_set_signal_levels; if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) || (HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) { diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index dbcf4ddd0f3b..ad7fe84b6d75 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -139,10 +139,10 @@ void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder, * HDMI/DVI use cases. */ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - int level) + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + int level = intel_ddi_hdmi_level(encoder, crtc_state); u32 iboost_bit = 0; int n_entries; enum port port = encoder->port; @@ -1405,8 +1405,7 @@ static int translate_signal_level(struct intel_dp *intel_dp, return 0; } -static int intel_ddi_dp_level(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) +static int intel_ddi_dp_level(struct intel_dp *intel_dp) { u8 train_set = intel_dp->train_set[0]; u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | @@ -1415,56 +1414,68 @@ static int intel_ddi_dp_level(struct intel_dp *intel_dp, return translate_signal_level(intel_dp, signal_levels); } +static int intel_ddi_level(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) + return intel_ddi_hdmi_level(encoder, crtc_state); + else + return intel_ddi_dp_level(enc_to_intel_dp(encoder)); +} + static void -dg2_set_signal_levels(struct intel_dp *intel_dp, +dg2_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - int level = intel_ddi_dp_level(intel_dp, crtc_state); + int level = intel_ddi_level(encoder, crtc_state); intel_snps_phy_ddi_vswing_sequence(encoder, crtc_state, level); } static void -tgl_set_signal_levels(struct intel_dp *intel_dp, +tgl_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - int level = intel_ddi_dp_level(intel_dp, crtc_state); + int level = intel_ddi_level(encoder, crtc_state); tgl_ddi_vswing_sequence(encoder, crtc_state, level); } static void -icl_set_signal_levels(struct intel_dp *intel_dp, +icl_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - int level = intel_ddi_dp_level(intel_dp, crtc_state); + int level = intel_ddi_level(encoder, crtc_state); icl_ddi_vswing_sequence(encoder, crtc_state, level); } static void -bxt_set_signal_levels(struct intel_dp *intel_dp, +bxt_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - int level = intel_ddi_dp_level(intel_dp, crtc_state); + int level = intel_ddi_level(encoder, crtc_state); bxt_ddi_vswing_sequence(encoder, crtc_state, level); } static void -hsw_set_signal_levels(struct intel_dp *intel_dp, +hsw_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - int level = intel_ddi_dp_level(intel_dp, crtc_state); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + int level = intel_ddi_level(encoder, crtc_state); enum port port = encoder->port; u32 signal_levels; + if (has_iboost(dev_priv)) + skl_ddi_set_iboost(encoder, crtc_state, level); + + /* HDMI ignores the rest */ + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) + return; + signal_levels = DDI_BUF_TRANS_SELECT(level); drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n", @@ -1473,9 +1484,6 @@ hsw_set_signal_levels(struct intel_dp *intel_dp, intel_dp->DP &= ~DDI_BUF_EMP_MASK; intel_dp->DP |= signal_levels; - if (has_iboost(dev_priv)) - skl_ddi_set_iboost(encoder, crtc_state, level); - intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); } @@ -2366,7 +2374,6 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); - int level = intel_ddi_dp_level(intel_dp, crtc_state); intel_dp_set_link_params(intel_dp, crtc_state->port_clock, crtc_state->lane_count); @@ -2431,7 +2438,7 @@ static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state, */ /* 5.e Configure voltage swing and related IO settings */ - intel_snps_phy_ddi_vswing_sequence(encoder, crtc_state, level); + encoder->set_signal_levels(encoder, crtc_state); if (!is_mst) intel_dp_set_power(intel_dp, DP_SET_POWER_D0); @@ -2474,7 +2481,6 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); - int level = intel_ddi_dp_level(intel_dp, crtc_state); intel_dp_set_link_params(intel_dp, crtc_state->port_clock, @@ -2554,7 +2560,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, */ /* 7.e Configure voltage swing and related IO settings */ - tgl_ddi_vswing_sequence(encoder, crtc_state, level); + encoder->set_signal_levels(encoder, crtc_state); /* * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up @@ -2611,7 +2617,6 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, enum port port = encoder->port; struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); - int level = intel_ddi_dp_level(intel_dp, crtc_state); if (DISPLAY_VER(dev_priv) < 11) drm_WARN_ON(&dev_priv->drm, @@ -2641,14 +2646,11 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, icl_program_mg_dp_mode(dig_port, crtc_state); - if (DISPLAY_VER(dev_priv) >= 11) - icl_ddi_vswing_sequence(encoder, crtc_state, level); - else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) - bxt_ddi_vswing_sequence(encoder, crtc_state, level); - if (has_buf_trans_select(dev_priv)) hsw_prepare_dp_ddi_buffers(encoder, crtc_state); + encoder->set_signal_levels(encoder, crtc_state); + intel_ddi_power_up_lanes(encoder, crtc_state); if (!is_mst) @@ -3074,7 +3076,6 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct drm_connector *connector = conn_state->connector; - int level = intel_ddi_hdmi_level(encoder, crtc_state); enum port port = encoder->port; if (!intel_hdmi_handle_sink_scrambling(encoder, connector, @@ -3084,20 +3085,10 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state, "[CONNECTOR:%d:%s] Failed to configure sink scrambling/TMDS bit clock ratio\n", connector->base.id, connector->name); - if (IS_DG2(dev_priv)) - intel_snps_phy_ddi_vswing_sequence(encoder, crtc_state, level); - else if (DISPLAY_VER(dev_priv) >= 12) - tgl_ddi_vswing_sequence(encoder, crtc_state, level); - else if (DISPLAY_VER(dev_priv) == 11) - icl_ddi_vswing_sequence(encoder, crtc_state, level); - else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) - bxt_ddi_vswing_sequence(encoder, crtc_state, level); - if (has_buf_trans_select(dev_priv)) - hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state, level); + hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state); - if (has_iboost(dev_priv)) - skl_ddi_set_iboost(encoder, crtc_state, level); + encoder->set_signal_levels(encoder, crtc_state); /* Display WA #1143: skl,kbl,cfl */ if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) { @@ -4057,7 +4048,6 @@ static const struct drm_encoder_funcs intel_ddi_funcs = { static struct intel_connector * intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) { - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); struct intel_connector *connector; enum port port = dig_port->base.port; @@ -4070,17 +4060,6 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) dig_port->dp.set_link_train = intel_ddi_set_link_train; dig_port->dp.set_idle_link_train = intel_ddi_set_idle_link_train; - if (IS_DG2(dev_priv)) - dig_port->dp.set_signal_levels = dg2_set_signal_levels; - else if (DISPLAY_VER(dev_priv) >= 12) - dig_port->dp.set_signal_levels = tgl_set_signal_levels; - else if (DISPLAY_VER(dev_priv) >= 11) - dig_port->dp.set_signal_levels = icl_set_signal_levels; - else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) - dig_port->dp.set_signal_levels = bxt_set_signal_levels; - else - dig_port->dp.set_signal_levels = hsw_set_signal_levels; - dig_port->dp.voltage_max = intel_ddi_dp_voltage_max; dig_port->dp.preemph_max = intel_ddi_dp_preemph_max; @@ -4652,6 +4631,17 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) encoder->get_config = hsw_ddi_get_config; } + if (IS_DG2(dev_priv)) + encoder->set_signal_levels = dg2_set_signal_levels; + else if (DISPLAY_VER(dev_priv) >= 12) + encoder->set_signal_levels = tgl_set_signal_levels; + else if (DISPLAY_VER(dev_priv) >= 11) + encoder->set_signal_levels = icl_set_signal_levels; + else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + encoder->set_signal_levels = bxt_set_signal_levels; + else + encoder->set_signal_levels = hsw_set_signal_levels; + intel_ddi_buf_trans_init(encoder); if (DISPLAY_VER(dev_priv) >= 13) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 632391197937..a811e13720bf 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -269,6 +269,9 @@ struct intel_encoder { const struct intel_ddi_buf_trans *(*get_buf_trans)(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, int *n_entries); + void (*set_signal_levels)(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state); + enum hpd_pin hpd_pin; enum intel_display_power_domain power_domain; /* for communication with audio component; protected by av_mutex */ @@ -1601,8 +1604,6 @@ struct intel_dp { u8 dp_train_pat); void (*set_idle_link_train)(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); - void (*set_signal_levels)(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); u8 (*preemph_max)(struct intel_dp *intel_dp); u8 (*voltage_max)(struct intel_dp *intel_dp, diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 73a823f1ec22..cc4d8b3a2264 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -398,7 +398,8 @@ void intel_dp_set_signal_levels(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, enum drm_dp_phy dp_phy) { - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u8 train_set = intel_dp->train_set[0]; char phy_name[10]; @@ -412,7 +413,7 @@ void intel_dp_set_signal_levels(struct intel_dp *intel_dp, intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name))); if (intel_dp_phy_is_downstream_of_source(intel_dp, dp_phy)) - intel_dp->set_signal_levels(intel_dp, crtc_state); + encoder->set_signal_levels(encoder, crtc_state); } static bool -- cgit v1.2.3 From 193299ad9d8579ba1f468e32870c9a52688f0872 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Oct 2021 16:01:01 +0300 Subject: drm/i915: Nuke useless .set_signal_levels() wrappers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that .set_signal_levels() is used for HDMI as well, we can remove the extra level of indirection and just plug the correct stuff straight into .set_signal_levels(). Reviewed-by: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211001130107.1746-5-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 119 +++++++------------------- drivers/gpu/drm/i915/display/intel_ddi.h | 6 +- drivers/gpu/drm/i915/display/intel_snps_phy.c | 7 +- drivers/gpu/drm/i915/display/intel_snps_phy.h | 5 +- 4 files changed, 39 insertions(+), 98 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index ad7fe84b6d75..accdf456b1d0 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1005,11 +1005,11 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, _skl_ddi_set_iboost(dev_priv, PORT_E, iboost); } -static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - int level) +static void bxt_set_signal_levels(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + int level = intel_ddi_level(encoder, crtc_state); const struct intel_ddi_buf_trans *trans; enum port port = encoder->port; int n_entries; @@ -1057,10 +1057,10 @@ static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp) } static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - int level) + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + int level = intel_ddi_level(encoder, crtc_state); const struct intel_ddi_buf_trans *trans; enum phy phy = intel_port_to_phy(dev_priv, encoder->port); int n_entries, ln; @@ -1119,9 +1119,8 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, intel_de_write(dev_priv, ICL_PORT_TX_DW7_GRP(phy), val); } -static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - int level) +static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum phy phy = intel_port_to_phy(dev_priv, encoder->port); @@ -1172,7 +1171,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); /* 5. Program swing and de-emphasis */ - icl_ddi_combo_vswing_program(encoder, crtc_state, level); + icl_ddi_combo_vswing_program(encoder, crtc_state); /* 6. Set training enable to trigger update */ val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy)); @@ -1180,12 +1179,12 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); } -static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - int level) +static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); + int level = intel_ddi_level(encoder, crtc_state); const struct intel_ddi_buf_trans *trans; int n_entries, ln; u32 val; @@ -1303,26 +1302,12 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, } } -static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - int level) -{ - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - enum phy phy = intel_port_to_phy(dev_priv, encoder->port); - - if (intel_phy_is_combo(dev_priv, phy)) - icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level); - else - icl_mg_phy_ddi_vswing_sequence(encoder, crtc_state, level); -} - -static void -tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - int level) +static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); + int level = intel_ddi_level(encoder, crtc_state); const struct intel_ddi_buf_trans *trans; u32 val, dpcnt_mask, dpcnt_val; int n_entries, ln; @@ -1374,19 +1359,6 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, } } -static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - int level) -{ - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - enum phy phy = intel_port_to_phy(dev_priv, encoder->port); - - if (intel_phy_is_combo(dev_priv, phy)) - icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level); - else - tgl_dkl_phy_ddi_vswing_sequence(encoder, crtc_state, level); -} - static int translate_signal_level(struct intel_dp *intel_dp, u8 signal_levels) { @@ -1414,8 +1386,8 @@ static int intel_ddi_dp_level(struct intel_dp *intel_dp) return translate_signal_level(intel_dp, signal_levels); } -static int intel_ddi_level(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) +int intel_ddi_level(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) return intel_ddi_hdmi_level(encoder, crtc_state); @@ -1423,42 +1395,6 @@ static int intel_ddi_level(struct intel_encoder *encoder, return intel_ddi_dp_level(enc_to_intel_dp(encoder)); } -static void -dg2_set_signal_levels(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) -{ - int level = intel_ddi_level(encoder, crtc_state); - - intel_snps_phy_ddi_vswing_sequence(encoder, crtc_state, level); -} - -static void -tgl_set_signal_levels(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) -{ - int level = intel_ddi_level(encoder, crtc_state); - - tgl_ddi_vswing_sequence(encoder, crtc_state, level); -} - -static void -icl_set_signal_levels(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) -{ - int level = intel_ddi_level(encoder, crtc_state); - - icl_ddi_vswing_sequence(encoder, crtc_state, level); -} - -static void -bxt_set_signal_levels(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) -{ - int level = intel_ddi_level(encoder, crtc_state); - - bxt_ddi_vswing_sequence(encoder, crtc_state, level); -} - static void hsw_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) @@ -4631,16 +4567,23 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) encoder->get_config = hsw_ddi_get_config; } - if (IS_DG2(dev_priv)) - encoder->set_signal_levels = dg2_set_signal_levels; - else if (DISPLAY_VER(dev_priv) >= 12) - encoder->set_signal_levels = tgl_set_signal_levels; - else if (DISPLAY_VER(dev_priv) >= 11) - encoder->set_signal_levels = icl_set_signal_levels; - else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (IS_DG2(dev_priv)) { + encoder->set_signal_levels = intel_snps_phy_set_signal_levels; + } else if (DISPLAY_VER(dev_priv) >= 12) { + if (intel_phy_is_combo(dev_priv, phy)) + encoder->set_signal_levels = icl_combo_phy_set_signal_levels; + else + encoder->set_signal_levels = tgl_dkl_phy_set_signal_levels; + } else if (DISPLAY_VER(dev_priv) >= 11) { + if (intel_phy_is_combo(dev_priv, phy)) + encoder->set_signal_levels = icl_combo_phy_set_signal_levels; + else + encoder->set_signal_levels = icl_mg_phy_set_signal_levels; + } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { encoder->set_signal_levels = bxt_set_signal_levels; - else + } else { encoder->set_signal_levels = hsw_set_signal_levels; + } intel_ddi_buf_trans_init(encoder); diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h index 7d448485d887..d6947c06a455 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.h +++ b/drivers/gpu/drm/i915/display/intel_ddi.h @@ -59,13 +59,11 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, bool state); void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv, struct intel_crtc_state *crtc_state); -u32 bxt_signal_levels(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); -u32 ddi_signal_levels(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder, enum transcoder cpu_transcoder, bool enable, u32 hdcp_mask); void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder); +int intel_ddi_level(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state); #endif /* __INTEL_DDI_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c index 3734e349f91d..f59cc320ce9c 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c @@ -5,6 +5,7 @@ #include +#include "intel_ddi.h" #include "intel_ddi_buf_trans.h" #include "intel_de.h" #include "intel_display_types.h" @@ -51,13 +52,13 @@ void intel_snps_phy_update_psr_power_state(struct drm_i915_private *dev_priv, SNPS_PHY_TX_REQ_LN_DIS_PWR_STATE_PSR, val); } -void intel_snps_phy_ddi_vswing_sequence(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - int level) +void intel_snps_phy_set_signal_levels(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); const struct intel_ddi_buf_trans *trans; enum phy phy = intel_port_to_phy(dev_priv, encoder->port); + int level = intel_ddi_level(encoder, crtc_state); int n_entries, ln; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.h b/drivers/gpu/drm/i915/display/intel_snps_phy.h index a68547a6fee5..11dcd6deb070 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.h +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.h @@ -29,8 +29,7 @@ int intel_mpllb_calc_port_clock(struct intel_encoder *encoder, const struct intel_mpllb_state *pll_state); int intel_snps_phy_check_hdmi_link_rate(int clock); -void intel_snps_phy_ddi_vswing_sequence(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - int level); +void intel_snps_phy_set_signal_levels(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state); #endif /* __INTEL_SNPS_PHY_H__ */ -- cgit v1.2.3 From 5f5ada0bae454aababf83b9fde3ae6b8df73afe1 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Oct 2021 16:01:02 +0300 Subject: drm/i915: De-wrapper bxt_ddi_phy_set_signal_levels() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert bxt_ddi_phy_set_signal_levels() to act as the full .set_signal_levels() hook instead of going through a pointless wrapper. Reviewed-by: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211001130107.1746-6-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 24 +-------------------- drivers/gpu/drm/i915/display/intel_dpio_phy.c | 30 +++++++++++++++++++-------- drivers/gpu/drm/i915/display/intel_dpio_phy.h | 5 ++--- 3 files changed, 24 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index accdf456b1d0..e6dd8ca36e44 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1005,28 +1005,6 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, _skl_ddi_set_iboost(dev_priv, PORT_E, iboost); } -static void bxt_set_signal_levels(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - int level = intel_ddi_level(encoder, crtc_state); - const struct intel_ddi_buf_trans *trans; - enum port port = encoder->port; - int n_entries; - - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) - return; - if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) - level = n_entries - 1; - - bxt_ddi_phy_set_signal_level(dev_priv, port, - trans->entries[level].bxt.margin, - trans->entries[level].bxt.scale, - trans->entries[level].bxt.enable, - trans->entries[level].bxt.deemphasis); -} - static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { @@ -4580,7 +4558,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) else encoder->set_signal_levels = icl_mg_phy_set_signal_levels; } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { - encoder->set_signal_levels = bxt_set_signal_levels; + encoder->set_signal_levels = bxt_ddi_phy_set_signal_levels; } else { encoder->set_signal_levels = hsw_set_signal_levels; } diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c index 48507ed79950..4d604e4cfa5d 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c @@ -23,6 +23,8 @@ #include "display/intel_dp.h" +#include "intel_ddi.h" +#include "intel_ddi_buf_trans.h" #include "intel_de.h" #include "intel_display_types.h" #include "intel_dpio_phy.h" @@ -266,15 +268,24 @@ void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port, *ch = DPIO_CH0; } -void bxt_ddi_phy_set_signal_level(struct drm_i915_private *dev_priv, - enum port port, u32 margin, u32 scale, - u32 enable, u32 deemphasis) +void bxt_ddi_phy_set_signal_levels(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { - u32 val; - enum dpio_phy phy; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + int level = intel_ddi_level(encoder, crtc_state); + const struct intel_ddi_buf_trans *trans; enum dpio_channel ch; + enum dpio_phy phy; + int n_entries; + u32 val; - bxt_port_to_phy_channel(dev_priv, port, &phy, &ch); + trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + return; + if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) + level = n_entries - 1; + + bxt_port_to_phy_channel(dev_priv, encoder->port, &phy, &ch); /* * While we write to the group register to program all lanes at once we @@ -286,12 +297,13 @@ void bxt_ddi_phy_set_signal_level(struct drm_i915_private *dev_priv, val = intel_de_read(dev_priv, BXT_PORT_TX_DW2_LN0(phy, ch)); val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE); - val |= margin << MARGIN_000_SHIFT | scale << UNIQ_TRANS_SCALE_SHIFT; + val |= trans->entries[level].bxt.margin << MARGIN_000_SHIFT | + trans->entries[level].bxt.scale << UNIQ_TRANS_SCALE_SHIFT; intel_de_write(dev_priv, BXT_PORT_TX_DW2_GRP(phy, ch), val); val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN0(phy, ch)); val &= ~SCALE_DCOMP_METHOD; - if (enable) + if (trans->entries[level].bxt.enable) val |= SCALE_DCOMP_METHOD; if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD)) @@ -302,7 +314,7 @@ void bxt_ddi_phy_set_signal_level(struct drm_i915_private *dev_priv, val = intel_de_read(dev_priv, BXT_PORT_TX_DW4_LN0(phy, ch)); val &= ~DE_EMPHASIS; - val |= deemphasis << DEEMPH_SHIFT; + val |= trans->entries[level].bxt.deemphasis << DEEMPH_SHIFT; intel_de_write(dev_priv, BXT_PORT_TX_DW4_GRP(phy, ch), val); val = intel_de_read(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch)); diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.h b/drivers/gpu/drm/i915/display/intel_dpio_phy.h index 6473440e7457..9c3d008e8e1a 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.h +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.h @@ -17,9 +17,8 @@ struct intel_encoder; void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port, enum dpio_phy *phy, enum dpio_channel *ch); -void bxt_ddi_phy_set_signal_level(struct drm_i915_private *dev_priv, - enum port port, u32 margin, u32 scale, - u32 enable, u32 deemphasis); +void bxt_ddi_phy_set_signal_levels(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state); void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy); void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy); bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, -- cgit v1.2.3 From 2c63e0f92e2fe3400ebfec7952f9dcbff6a583a9 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Oct 2021 16:01:03 +0300 Subject: drm/i915: Hoover the level>=n_entries WARN into intel_ddi_level() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers of intel_ddi_level() duplicate the check+WARN to make sure the returned level is actually present in the appropriate buf_trans table. Let's push that stuff into intel_ddi_level() so the callers don't have to worry about it. Reviewed-by: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211001130107.1746-7-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 27 +++++++++++++++------------ drivers/gpu/drm/i915/display/intel_dpio_phy.c | 2 -- drivers/gpu/drm/i915/display/intel_snps_phy.c | 2 -- 3 files changed, 15 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index e6dd8ca36e44..2b192694f484 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -151,8 +151,6 @@ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; - if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) - level = n_entries - 1; /* If we're boosting the current, set bit 31 of trans1 */ if (has_iboost(dev_priv) && @@ -987,8 +985,6 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; - if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) - level = n_entries - 1; iboost = trans->entries[level].hsw.i_boost; } @@ -1047,8 +1043,6 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; - if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) - level = n_entries - 1; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -1173,8 +1167,6 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; - if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) - level = n_entries - 1; /* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */ for (ln = 0; ln < 2; ln++) { @@ -1296,8 +1288,6 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; - if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) - level = n_entries - 1; dpcnt_mask = (DKL_TX_PRESHOOT_COEFF_MASK | DKL_TX_DE_EMPAHSIS_COEFF_MASK | @@ -1367,10 +1357,23 @@ static int intel_ddi_dp_level(struct intel_dp *intel_dp) int intel_ddi_level(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + const struct intel_ddi_buf_trans *trans; + int level, n_entries; + + trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + if (drm_WARN_ON_ONCE(&i915->drm, !trans)) + return 0; + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return intel_ddi_hdmi_level(encoder, crtc_state); + level = intel_ddi_hdmi_level(encoder, crtc_state); else - return intel_ddi_dp_level(enc_to_intel_dp(encoder)); + level = intel_ddi_dp_level(enc_to_intel_dp(encoder)); + + if (drm_WARN_ON_ONCE(&i915->drm, level >= n_entries)) + level = n_entries - 1; + + return level; } static void diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c index 4d604e4cfa5d..96650369164d 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c @@ -282,8 +282,6 @@ void bxt_ddi_phy_set_signal_levels(struct intel_encoder *encoder, trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; - if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) - level = n_entries - 1; bxt_port_to_phy_channel(dev_priv, encoder->port, &phy, &ch); diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c index f59cc320ce9c..7a9771dbb63f 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c @@ -64,8 +64,6 @@ void intel_snps_phy_set_signal_levels(struct intel_encoder *encoder, trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) return; - if (drm_WARN_ON_ONCE(&dev_priv->drm, level < 0 || level >= n_entries)) - level = n_entries - 1; for (ln = 0; ln < 4; ln++) { u32 val = 0; -- cgit v1.2.3 From 3e022c1f0a5fcdc0192fc497c63efdadd8c5b3c4 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Oct 2021 16:01:04 +0300 Subject: drm/i915: Nuke intel_ddi_hdmi_num_entries() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since intel_ddi_level() now looks at the buf_trans table there's no point in having intel_ddi_hdmi_num_entries() around. Just roll the necessary bits of locic into intel_ddi_hdmi_level()/intel_ddi_level(). Reviewed-by: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211001130107.1746-8-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 17 +++++------------ drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c | 20 -------------------- drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h | 4 ---- 3 files changed, 5 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 2b192694f484..4e9a6f30f524 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -74,20 +74,13 @@ static const u8 index_to_dp_signal_levels[] = { }; static int intel_ddi_hdmi_level(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) + const struct intel_ddi_buf_trans *trans) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - int n_entries, level, default_entry; + int level; - n_entries = intel_ddi_hdmi_num_entries(encoder, crtc_state, &default_entry); - if (n_entries == 0) - return 0; level = intel_bios_hdmi_level_shift(encoder); if (level < 0) - level = default_entry; - - if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries)) - level = n_entries - 1; + level = trans->hdmi_default_entry; return level; } @@ -142,7 +135,7 @@ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - int level = intel_ddi_hdmi_level(encoder, crtc_state); + int level = intel_ddi_level(encoder, crtc_state); u32 iboost_bit = 0; int n_entries; enum port port = encoder->port; @@ -1366,7 +1359,7 @@ int intel_ddi_level(struct intel_encoder *encoder, return 0; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - level = intel_ddi_hdmi_level(encoder, crtc_state); + level = intel_ddi_hdmi_level(encoder, trans); else level = intel_ddi_dp_level(enc_to_intel_dp(encoder)); diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c index 449daba7afb3..a2d39131ea53 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c @@ -1617,26 +1617,6 @@ dg2_get_snps_buf_trans(struct intel_encoder *encoder, return intel_get_buf_trans(&dg2_snps_trans, n_entries); } -int intel_ddi_hdmi_num_entries(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - int *default_entry) -{ - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - const struct intel_ddi_buf_trans *trans; - int n_entries; - - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - - if (drm_WARN_ON(&dev_priv->drm, !trans)) { - *default_entry = 0; - return 0; - } - - *default_entry = trans->hdmi_default_entry; - - return n_entries; -} - void intel_ddi_buf_trans_init(struct intel_encoder *encoder) { struct drm_i915_private *i915 = to_i915(encoder->base.dev); diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h index 94d338287f61..6cdb8e9073c7 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h @@ -68,10 +68,6 @@ struct intel_ddi_buf_trans { bool is_hobl_buf_trans(const struct intel_ddi_buf_trans *table); -int intel_ddi_hdmi_num_entries(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - int *default_entry); - void intel_ddi_buf_trans_init(struct intel_encoder *encoder); #endif -- cgit v1.2.3 From d0920a45574c15a8fc00ccdff65da3b801438757 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Oct 2021 16:01:05 +0300 Subject: drm/i915: Pass the lane to intel_ddi_level() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to have per-lane drive settings we need intel_ddi_level() to accept the lane as a parameter. That is, the eventual goal is to call intel_ddi_level() once for each lane. For now we just pass in a hardcoded 0 and use the same settings for every lane. Ie. no change in behaviour yet. Reviewed-by: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211001130107.1746-9-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 19 ++++++++++--------- drivers/gpu/drm/i915/display/intel_ddi.h | 3 ++- drivers/gpu/drm/i915/display/intel_dpio_phy.c | 2 +- drivers/gpu/drm/i915/display/intel_snps_phy.c | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 4e9a6f30f524..0d4cf7fa8720 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -135,7 +135,7 @@ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - int level = intel_ddi_level(encoder, crtc_state); + int level = intel_ddi_level(encoder, crtc_state, 0); u32 iboost_bit = 0; int n_entries; enum port port = encoder->port; @@ -1027,7 +1027,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - int level = intel_ddi_level(encoder, crtc_state); + int level = intel_ddi_level(encoder, crtc_state, 0); const struct intel_ddi_buf_trans *trans; enum phy phy = intel_port_to_phy(dev_priv, encoder->port); int n_entries, ln; @@ -1149,7 +1149,7 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); - int level = intel_ddi_level(encoder, crtc_state); + int level = intel_ddi_level(encoder, crtc_state, 0); const struct intel_ddi_buf_trans *trans; int n_entries, ln; u32 val; @@ -1270,7 +1270,7 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); - int level = intel_ddi_level(encoder, crtc_state); + int level = intel_ddi_level(encoder, crtc_state, 0); const struct intel_ddi_buf_trans *trans; u32 val, dpcnt_mask, dpcnt_val; int n_entries, ln; @@ -1338,9 +1338,9 @@ static int translate_signal_level(struct intel_dp *intel_dp, return 0; } -static int intel_ddi_dp_level(struct intel_dp *intel_dp) +static int intel_ddi_dp_level(struct intel_dp *intel_dp, int lane) { - u8 train_set = intel_dp->train_set[0]; + u8 train_set = intel_dp->train_set[lane]; u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | DP_TRAIN_PRE_EMPHASIS_MASK); @@ -1348,7 +1348,8 @@ static int intel_ddi_dp_level(struct intel_dp *intel_dp) } int intel_ddi_level(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) + const struct intel_crtc_state *crtc_state, + int lane) { struct drm_i915_private *i915 = to_i915(encoder->base.dev); const struct intel_ddi_buf_trans *trans; @@ -1361,7 +1362,7 @@ int intel_ddi_level(struct intel_encoder *encoder, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) level = intel_ddi_hdmi_level(encoder, trans); else - level = intel_ddi_dp_level(enc_to_intel_dp(encoder)); + level = intel_ddi_dp_level(enc_to_intel_dp(encoder), lane); if (drm_WARN_ON_ONCE(&i915->drm, level >= n_entries)) level = n_entries - 1; @@ -1375,7 +1376,7 @@ hsw_set_signal_levels(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - int level = intel_ddi_level(encoder, crtc_state); + int level = intel_ddi_level(encoder, crtc_state, 0); enum port port = encoder->port; u32 signal_levels; diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h index d6947c06a455..d6971717ef9c 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.h +++ b/drivers/gpu/drm/i915/display/intel_ddi.h @@ -64,6 +64,7 @@ int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder, bool enable, u32 hdcp_mask); void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder); int intel_ddi_level(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state); + const struct intel_crtc_state *crtc_state, + int lane); #endif /* __INTEL_DDI_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c index 96650369164d..5a2eccb12fe4 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c @@ -272,7 +272,7 @@ void bxt_ddi_phy_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - int level = intel_ddi_level(encoder, crtc_state); + int level = intel_ddi_level(encoder, crtc_state, 0); const struct intel_ddi_buf_trans *trans; enum dpio_channel ch; enum dpio_phy phy; diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c index 7a9771dbb63f..b18f08c851dc 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c @@ -58,7 +58,7 @@ void intel_snps_phy_set_signal_levels(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); const struct intel_ddi_buf_trans *trans; enum phy phy = intel_port_to_phy(dev_priv, encoder->port); - int level = intel_ddi_level(encoder, crtc_state); + int level = intel_ddi_level(encoder, crtc_state, 0); int n_entries, ln; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); -- cgit v1.2.3 From c6921d484d3f986f3bed3372ac22574b42e2589f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Oct 2021 16:01:06 +0300 Subject: drm/i915: Prepare link training for per-lane drive settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adjust the link training code to accommodate per-lane drive settings, if supported by the platform. Actually enabling this will involve some changes to each platform's .set_signal_level() implementation, so for the moment all supported platforms will keep using the current codepath that just uses the same drive settings for all the lanes. v2: Fix min() vs. max() fumble v3: Compact the debug print to a single line Reviewed-by: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211001130107.1746-10-ville.syrjala@linux.intel.com --- .../gpu/drm/i915/display/intel_dp_link_training.c | 78 +++++++++++++++++----- 1 file changed, 60 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index cc4d8b3a2264..6e54de5db183 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -301,21 +301,33 @@ static u8 intel_dp_phy_preemph_max(struct intel_dp *intel_dp, return preemph_max; } -void -intel_dp_get_adjust_train(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state, - enum drm_dp_phy dp_phy, - const u8 link_status[DP_LINK_STATUS_SIZE]) +static bool has_per_lane_signal_levels(struct intel_dp *intel_dp, + enum drm_dp_phy dp_phy) +{ + return false; +} + +static u8 intel_dp_get_lane_adjust_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy, + const u8 link_status[DP_LINK_STATUS_SIZE], + int lane) { u8 v = 0; u8 p = 0; - int lane; u8 voltage_max; u8 preemph_max; - for (lane = 0; lane < crtc_state->lane_count; lane++) { - v = max(v, drm_dp_get_adjust_request_voltage(link_status, lane)); - p = max(p, drm_dp_get_adjust_request_pre_emphasis(link_status, lane)); + if (has_per_lane_signal_levels(intel_dp, dp_phy)) { + lane = min(lane, crtc_state->lane_count - 1); + + v = drm_dp_get_adjust_request_voltage(link_status, lane); + p = drm_dp_get_adjust_request_pre_emphasis(link_status, lane); + } else { + for (lane = 0; lane < crtc_state->lane_count; lane++) { + v = max(v, drm_dp_get_adjust_request_voltage(link_status, lane)); + p = max(p, drm_dp_get_adjust_request_pre_emphasis(link_status, lane)); + } } preemph_max = intel_dp_phy_preemph_max(intel_dp, dp_phy); @@ -328,8 +340,21 @@ intel_dp_get_adjust_train(struct intel_dp *intel_dp, if (v >= voltage_max) v = voltage_max | DP_TRAIN_MAX_SWING_REACHED; + return v | p; +} + +void +intel_dp_get_adjust_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy, + const u8 link_status[DP_LINK_STATUS_SIZE]) +{ + int lane; + for (lane = 0; lane < 4; lane++) - intel_dp->train_set[lane] = v | p; + intel_dp->train_set[lane] = + intel_dp_get_lane_adjust_train(intel_dp, crtc_state, + dp_phy, link_status, lane); } static int intel_dp_training_pattern_set_reg(struct intel_dp *intel_dp, @@ -394,22 +419,39 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, intel_dp->set_link_train(intel_dp, crtc_state, dp_train_pat); } +#define TRAIN_SET_FMT "%d%s/%d%s/%d%s/%d%s" +#define _TRAIN_SET_VSWING_ARGS(train_set) \ + ((train_set) & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT, \ + (train_set) & DP_TRAIN_MAX_SWING_REACHED ? "(max)" : "" +#define TRAIN_SET_VSWING_ARGS(train_set) \ + _TRAIN_SET_VSWING_ARGS((train_set)[0]), \ + _TRAIN_SET_VSWING_ARGS((train_set)[1]), \ + _TRAIN_SET_VSWING_ARGS((train_set)[2]), \ + _TRAIN_SET_VSWING_ARGS((train_set)[3]) +#define _TRAIN_SET_PREEMPH_ARGS(train_set) \ + ((train_set) & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT, \ + (train_set) & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ? "(max)" : "" +#define TRAIN_SET_PREEMPH_ARGS(train_set) \ + _TRAIN_SET_PREEMPH_ARGS((train_set)[0]), \ + _TRAIN_SET_PREEMPH_ARGS((train_set)[1]), \ + _TRAIN_SET_PREEMPH_ARGS((train_set)[2]), \ + _TRAIN_SET_PREEMPH_ARGS((train_set)[3]) + void intel_dp_set_signal_levels(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, enum drm_dp_phy dp_phy) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - u8 train_set = intel_dp->train_set[0]; char phy_name[10]; - drm_dbg_kms(&dev_priv->drm, "Using vswing level %d%s, pre-emphasis level %d%s, at %s\n", - train_set & DP_TRAIN_VOLTAGE_SWING_MASK, - train_set & DP_TRAIN_MAX_SWING_REACHED ? " (max)" : "", - (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) >> - DP_TRAIN_PRE_EMPHASIS_SHIFT, - train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ? - " (max)" : "", + drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] lanes: %d, " + "vswing levels: " TRAIN_SET_FMT ", " + "pre-emphasis levels: " TRAIN_SET_FMT ", at %s\n", + encoder->base.base.id, encoder->base.name, + crtc_state->lane_count, + TRAIN_SET_VSWING_ARGS(intel_dp->train_set), + TRAIN_SET_PREEMPH_ARGS(intel_dp->train_set), intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name))); if (intel_dp_phy_is_downstream_of_source(intel_dp, dp_phy)) -- cgit v1.2.3 From 104c1b3d6fb6a794babd5e2ffd6a5183b5a3d6c7 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 1 Oct 2021 16:01:07 +0300 Subject: drm/i915: Allow per-lane drive settings with LTTPRs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LTTPRs should support per-lane drive settings I think, and even if they don't they should implement their own fallback logic to determine suitable common drive settings to use for all the lanes. v2: Actually check the correct thing Reviewed-by: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20211001130107.1746-11-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 6e54de5db183..c052ce14894d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -304,7 +304,7 @@ static u8 intel_dp_phy_preemph_max(struct intel_dp *intel_dp, static bool has_per_lane_signal_levels(struct intel_dp *intel_dp, enum drm_dp_phy dp_phy) { - return false; + return !intel_dp_phy_is_downstream_of_source(intel_dp, dp_phy); } static u8 intel_dp_get_lane_adjust_train(struct intel_dp *intel_dp, -- cgit v1.2.3