diff options
| author | Dave Airlie <airlied@redhat.com> | 2025-06-23 10:49:25 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2025-06-23 10:49:27 +1000 |
| commit | 36c52fb703e90388285963fc8f03cf60f76cbe4c (patch) | |
| tree | ad4ac082742408d54a7a165d9fb006d06f8d064a /drivers/gpu/drm/i915/soc/intel_dram.c | |
| parent | 9356b50af547e872d9191754c72c83ff6be3b97c (diff) | |
| parent | b2f7e30d2e4a34fcee8111d713bef4f29dc23c77 (diff) | |
Merge tag 'drm-intel-next-2025-06-18' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next
drm/i915 feature pull for v6.17:
Features and functionality:
- Add support for DSC fractional link bpp on DP MST (Imre)
- Add support for simultaneous Panel Replay and Adaptive Sync (Jouni)
- Add support for PTL+ double buffered LUT registers (Chaitanya, Ville)
- Add PIPEDMC event handling in preparation for flip queue (Ville)
Refactoring and cleanups:
- Rename lots of DPLL interfaces to unify them (Suraj)
- Allocate struct intel_display dynamically (Jani)
- Abstract VLV IOSF sideband better (Jani)
- Use str_true_false() helper (Yumeng Fang)
- Refactor DSB code in preparation for flip queue (Ville)
- Use drm_modeset_lock_assert_held() instead of open coding (Luca)
- Remove unused arg from skl_scaler_get_filter_select() (Luca)
- Split out a separate display register header (Jani)
- Abstract DRAM detection better (Jani)
- Convert LPT/WPT SBI sideband to struct intel_display (Jani)
Fixes:
- Fix DSI HS command dispatch with forced pipeline flush (Gareth Yu)
- Fix BMG and LNL+ DP adaptive sync SDP programming (Ankit)
- Fix error path for xe display workqueue allocation (Haoxiang Li)
- Disable DP AUX access probe where not required (Imre)
- Fix DKL PHY access if the port is invalid (Luca)
- Fix PSR2_SU_STATUS access on ADL+ (Jouni)
- Add sanity checks for porch and sync on BXT/GLK DSI (Ville)
DRM core changes:
- Change AUX DPCD access probe address (Imre)
- Refactor EDID quirks, amd make them available to drivers (Imre)
- Add quirk for DPCD access probe (Imre)
- Add DPCD definitions for Panel Replay capabilities (Jouni)
Merges:
- Backmerges to sync with v6.15-rcs and v6.16-rc1 (Jani)
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Jani Nikula <jani.nikula@intel.com>
Link: https://lore.kernel.org/r/fff9f231850ed410bd81b53de43eff0b98240d31@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/soc/intel_dram.c')
| -rw-r--r-- | drivers/gpu/drm/i915/soc/intel_dram.c | 87 |
1 files changed, 54 insertions, 33 deletions
diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c index eee5c4f45a43..59032c939d0f 100644 --- a/drivers/gpu/drm/i915/soc/intel_dram.c +++ b/drivers/gpu/drm/i915/soc/intel_dram.c @@ -5,12 +5,16 @@ #include <linux/string_helpers.h> +#include <drm/drm_managed.h> + +#include "../display/intel_display_core.h" /* FIXME */ + #include "i915_drv.h" #include "i915_reg.h" #include "intel_dram.h" #include "intel_mchbar_regs.h" #include "intel_pcode.h" -#include "vlv_sideband.h" +#include "vlv_iosf_sb.h" struct dram_dimm_info { u16 size; @@ -97,9 +101,9 @@ static unsigned int chv_mem_freq(struct drm_i915_private *i915) { u32 val; - vlv_iosf_sb_get(i915, BIT(VLV_IOSF_SB_CCK)); - val = vlv_cck_read(i915, CCK_FUSE_REG); - vlv_iosf_sb_put(i915, BIT(VLV_IOSF_SB_CCK)); + vlv_iosf_sb_get(&i915->drm, BIT(VLV_IOSF_SB_CCK)); + val = vlv_iosf_sb_read(&i915->drm, VLV_IOSF_SB_CCK, CCK_FUSE_REG); + vlv_iosf_sb_put(&i915->drm, BIT(VLV_IOSF_SB_CCK)); switch ((val >> 2) & 0x7) { case 3: @@ -113,9 +117,9 @@ static unsigned int vlv_mem_freq(struct drm_i915_private *i915) { u32 val; - vlv_iosf_sb_get(i915, BIT(VLV_IOSF_SB_PUNIT)); - val = vlv_punit_read(i915, PUNIT_REG_GPU_FREQ_STS); - vlv_iosf_sb_put(i915, BIT(VLV_IOSF_SB_PUNIT)); + vlv_iosf_sb_get(&i915->drm, BIT(VLV_IOSF_SB_PUNIT)); + val = vlv_iosf_sb_read(&i915->drm, VLV_IOSF_SB_PUNIT, PUNIT_REG_GPU_FREQ_STS); + vlv_iosf_sb_put(&i915->drm, BIT(VLV_IOSF_SB_PUNIT)); switch ((val >> 6) & 3) { case 0: @@ -381,9 +385,8 @@ intel_is_dram_symmetric(const struct dram_channel_info *ch0, } static int -skl_dram_get_channels_info(struct drm_i915_private *i915) +skl_dram_get_channels_info(struct drm_i915_private *i915, struct dram_info *dram_info) { - struct dram_info *dram_info = &i915->dram_info; struct dram_channel_info ch0 = {}, ch1 = {}; u32 val; int ret; @@ -444,14 +447,13 @@ skl_get_dram_type(struct drm_i915_private *i915) } static int -skl_get_dram_info(struct drm_i915_private *i915) +skl_get_dram_info(struct drm_i915_private *i915, struct dram_info *dram_info) { - struct dram_info *dram_info = &i915->dram_info; int ret; dram_info->type = skl_get_dram_type(i915); - ret = skl_dram_get_channels_info(i915); + ret = skl_dram_get_channels_info(i915, dram_info); if (ret) return ret; @@ -536,9 +538,8 @@ static void bxt_get_dimm_info(struct dram_dimm_info *dimm, u32 val) dimm->size = bxt_get_dimm_size(val) * intel_dimm_num_devices(dimm); } -static int bxt_get_dram_info(struct drm_i915_private *i915) +static int bxt_get_dram_info(struct drm_i915_private *i915, struct dram_info *dram_info) { - struct dram_info *dram_info = &i915->dram_info; u32 val; u8 valid_ranks = 0; int i; @@ -583,9 +584,9 @@ static int bxt_get_dram_info(struct drm_i915_private *i915) return 0; } -static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv) +static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv, + struct dram_info *dram_info) { - struct dram_info *dram_info = &dev_priv->dram_info; u32 val = 0; int ret; @@ -645,27 +646,26 @@ static int icl_pcode_read_mem_global_info(struct drm_i915_private *dev_priv) return 0; } -static int gen11_get_dram_info(struct drm_i915_private *i915) +static int gen11_get_dram_info(struct drm_i915_private *i915, struct dram_info *dram_info) { - int ret = skl_get_dram_info(i915); + int ret = skl_get_dram_info(i915, dram_info); if (ret) return ret; - return icl_pcode_read_mem_global_info(i915); + return icl_pcode_read_mem_global_info(i915, dram_info); } -static int gen12_get_dram_info(struct drm_i915_private *i915) +static int gen12_get_dram_info(struct drm_i915_private *i915, struct dram_info *dram_info) { - i915->dram_info.wm_lv_0_adjust_needed = false; + dram_info->wm_lv_0_adjust_needed = false; - return icl_pcode_read_mem_global_info(i915); + return icl_pcode_read_mem_global_info(i915, dram_info); } -static int xelpdp_get_dram_info(struct drm_i915_private *i915) +static int xelpdp_get_dram_info(struct drm_i915_private *i915, struct dram_info *dram_info) { u32 val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_GLOBAL); - struct dram_info *dram_info = &i915->dram_info; switch (REG_FIELD_GET(MTL_DDR_TYPE_MASK, val)) { case 0: @@ -706,16 +706,22 @@ static int xelpdp_get_dram_info(struct drm_i915_private *i915) return 0; } -void intel_dram_detect(struct drm_i915_private *i915) +int intel_dram_detect(struct drm_i915_private *i915) { - struct dram_info *dram_info = &i915->dram_info; + struct dram_info *dram_info; int ret; detect_fsb_freq(i915); detect_mem_freq(i915); if (GRAPHICS_VER(i915) < 9 || IS_DG2(i915) || !HAS_DISPLAY(i915)) - return; + return 0; + + dram_info = drmm_kzalloc(&i915->drm, sizeof(*dram_info), GFP_KERNEL); + if (!dram_info) + return -ENOMEM; + + i915->dram_info = dram_info; /* * Assume level 0 watermark latency adjustment is needed until proven @@ -724,21 +730,22 @@ void intel_dram_detect(struct drm_i915_private *i915) dram_info->wm_lv_0_adjust_needed = !IS_BROXTON(i915) && !IS_GEMINILAKE(i915); if (DISPLAY_VER(i915) >= 14) - ret = xelpdp_get_dram_info(i915); + ret = xelpdp_get_dram_info(i915, dram_info); else if (GRAPHICS_VER(i915) >= 12) - ret = gen12_get_dram_info(i915); + ret = gen12_get_dram_info(i915, dram_info); else if (GRAPHICS_VER(i915) >= 11) - ret = gen11_get_dram_info(i915); + ret = gen11_get_dram_info(i915, dram_info); else if (IS_BROXTON(i915) || IS_GEMINILAKE(i915)) - ret = bxt_get_dram_info(i915); + ret = bxt_get_dram_info(i915, dram_info); else - ret = skl_get_dram_info(i915); + ret = skl_get_dram_info(i915, dram_info); drm_dbg_kms(&i915->drm, "DRAM type: %s\n", intel_dram_type_str(dram_info->type)); + /* TODO: Do we want to abort probe on dram detection failures? */ if (ret) - return; + return 0; drm_dbg_kms(&i915->drm, "Num qgv points %u\n", dram_info->num_qgv_points); @@ -746,6 +753,20 @@ void intel_dram_detect(struct drm_i915_private *i915) drm_dbg_kms(&i915->drm, "Watermark level 0 adjustment needed: %s\n", str_yes_no(dram_info->wm_lv_0_adjust_needed)); + + return 0; +} + +/* + * Returns NULL for platforms that don't have dram info. Avoid overzealous NULL + * checks, and prefer not dereferencing on platforms that shouldn't look at dram + * info, to catch accidental and incorrect dram info checks. + */ +const struct dram_info *intel_dram_info(struct drm_device *drm) +{ + struct drm_i915_private *i915 = to_i915(drm); + + return i915->dram_info; } static u32 gen9_edram_size_mb(struct drm_i915_private *i915, u32 cap) |