drm/i915: Read graphics/media/display arch version from hw
authorMatt Roper <matthew.d.roper@intel.com>
Fri, 16 Sep 2022 01:46:46 +0000 (18:46 -0700)
committerRadhakrishna Sripada <radhakrishna.sripada@intel.com>
Sat, 24 Sep 2022 00:37:15 +0000 (17:37 -0700)
Going forward, the hardware teams no longer consider new platforms to
have a "generation" in the way we've defined it for past platforms.
Instead, each IP block (graphics, media, display) will have their own
architecture major.minor versions and stepping ID's which should be read
directly from a register in the MMIO space.

Bspec: 63361, 64111

v2:
  - Move the IP version readout to intel_device_info.c
  - Convert the macro into a function

v3:
  - Move subplatform init to runtime early init
  - Cache runtime ver, release info to compare with hardware values.
  - Use IP_VER for snaity check(MattR)

v4:
  - Minor doccumentation changes.
  - Normalize HAS_GMD_ID macro value.(JaniN)

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220916014648.1310346-2-radhakrishna.sripada@intel.com
drivers/gpu/drm/i915/gt/intel_gt_regs.h
drivers/gpu/drm/i915/i915_driver.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_pci.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_device_info.c
drivers/gpu/drm/i915/intel_device_info.h

index 94f9ddcfb3a551638a96f152a64e905b31175e07..94a0606859227a37441bb0fee5c07cadbd887bc6 100644 (file)
@@ -39,6 +39,9 @@
 #define FORCEWAKE_ACK_RENDER_GEN9              _MMIO(0xd84)
 #define FORCEWAKE_ACK_MEDIA_GEN9               _MMIO(0xd88)
 
+#define GMD_ID_GRAPHICS                                _MMIO(0xd8c)
+#define GMD_ID_MEDIA                           _MMIO(MTL_MEDIA_GSI_BASE + 0xd8c)
+
 #define MCFG_MCR_SELECTOR                      _MMIO(0xfd0)
 #define SF_MCR_SELECTOR                                _MMIO(0xfd8)
 #define GEN8_MCR_SELECTOR                      _MMIO(0xfdc)
index 3e1d2a10e9da8813f5debb3a9d9b9d80049739cd..f1e06758db19c3cf5f9dfaec2bdf96899b93c4a4 100644 (file)
@@ -324,7 +324,8 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
        if (i915_inject_probe_failure(dev_priv))
                return -ENODEV;
 
-       intel_device_info_subplatform_init(dev_priv);
+       intel_device_info_runtime_init_early(dev_priv);
+
        intel_step_init(dev_priv);
 
        intel_uncore_mmio_debug_init_early(&dev_priv->mmio_debug);
index cc6ca550d8eb50231abf07522cbc77fa3e3c795c..e18b66b8640b86b09cae07d9f6f64e6b7fab8297 100644 (file)
@@ -930,6 +930,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 
 #define HAS_GMCH(dev_priv) (INTEL_INFO(dev_priv)->display.has_gmch)
 
+#define HAS_GMD_ID(i915)       (INTEL_INFO(i915)->has_gmd_id)
+
 #define HAS_LSPCON(dev_priv) (IS_DISPLAY_VER(dev_priv, 9, 10))
 
 #define HAS_L3_CCS_READ(i915) (INTEL_INFO(i915)->has_l3_ccs_read)
index 1576cbcf2254350d255f99d816593ace54a2c384..6b563461b3149fd228eabfcf10e69dd9f1e0c1f7 100644 (file)
@@ -1128,6 +1128,7 @@ static const struct intel_device_info mtl_info = {
        PLATFORM(INTEL_METEORLAKE),
        .display.has_modular_fia = 1,
        .has_flat_ccs = 0,
+       .has_gmd_id = 1,
        .has_snoop = 1,
        .__runtime.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
        .__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
index 3053c175cf9b2e5f0556c554b7559153e763578b..a4f0129c3f6f7e1ec50325c8fdfcd96fc7aa801e 100644 (file)
 #define ICL_DSSM_CDCLK_PLL_REFCLK_19_2MHz      (1 << 29)
 #define ICL_DSSM_CDCLK_PLL_REFCLK_38_4MHz      (2 << 29)
 
+#define GMD_ID_DISPLAY                         _MMIO(0x510a0)
+#define   GMD_ID_ARCH_MASK                     REG_GENMASK(31, 22)
+#define   GMD_ID_RELEASE_MASK                  REG_GENMASK(21, 14)
+#define   GMD_ID_STEP                          REG_GENMASK(5, 0)
+
 /*GEN11 chicken */
 #define _PIPEA_CHICKEN                         0x70038
 #define _PIPEB_CHICKEN                         0x71038
@@ -8356,4 +8361,6 @@ enum skl_power_gate {
 #define   MTL_TRAS_MASK                        REG_GENMASK(16, 8)
 #define   MTL_TRDPRE_MASK              REG_GENMASK(7, 0)
 
+#define MTL_MEDIA_GSI_BASE             0x380000
+
 #endif /* _I915_REG_H_ */
index 1434dc33cf49aeb095feec300821f5c037bd8723..2018eaaa45f59846d5c956c263a48f8244872aa6 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "display/intel_cdclk.h"
 #include "display/intel_de.h"
+#include "gt/intel_gt_regs.h"
 #include "intel_device_info.h"
 #include "i915_drv.h"
 #include "i915_utils.h"
@@ -231,7 +232,7 @@ static bool find_devid(u16 id, const u16 *p, unsigned int num)
        return false;
 }
 
-void intel_device_info_subplatform_init(struct drm_i915_private *i915)
+static void intel_device_info_subplatform_init(struct drm_i915_private *i915)
 {
        const struct intel_device_info *info = INTEL_INFO(i915);
        const struct intel_runtime_info *rinfo = RUNTIME_INFO(i915);
@@ -288,6 +289,70 @@ void intel_device_info_subplatform_init(struct drm_i915_private *i915)
        RUNTIME_INFO(i915)->platform_mask[pi] |= mask;
 }
 
+static void ip_ver_read(struct drm_i915_private *i915, u32 offset, struct ip_version *ip)
+{
+       struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
+       void __iomem *addr;
+       u32 val;
+       u8 expected_ver = ip->ver;
+       u8 expected_rel = ip->rel;
+
+       addr = pci_iomap_range(pdev, 0, offset, sizeof(u32));
+       if (drm_WARN_ON(&i915->drm, !addr))
+               return;
+
+       val = ioread32(addr);
+       pci_iounmap(pdev, addr);
+
+       ip->ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val);
+       ip->rel = REG_FIELD_GET(GMD_ID_RELEASE_MASK, val);
+       ip->step = REG_FIELD_GET(GMD_ID_STEP, val);
+
+       /* Sanity check against expected versions from device info */
+       if (IP_VER(ip->ver, ip->rel) < IP_VER(expected_ver, expected_rel))
+               drm_dbg(&i915->drm,
+                       "Hardware reports GMD IP version %u.%u (REG[0x%x] = 0x%08x) but minimum expected is %u.%u\n",
+                       ip->ver, ip->rel, offset, val, expected_ver, expected_rel);
+}
+
+/*
+ * Setup the graphics version for the current device.  This must be done before
+ * any code that performs checks on GRAPHICS_VER or DISPLAY_VER, so this
+ * function should be called very early in the driver initialization sequence.
+ *
+ * Regular MMIO access is not yet setup at the point this function is called so
+ * we peek at the appropriate MMIO offset directly.  The GMD_ID register is
+ * part of an 'always on' power well by design, so we don't need to worry about
+ * forcewake while reading it.
+ */
+static void intel_ipver_early_init(struct drm_i915_private *i915)
+{
+       struct intel_runtime_info *runtime = RUNTIME_INFO(i915);
+
+       if (!HAS_GMD_ID(i915))
+               return;
+
+       ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_GRAPHICS),
+                   &runtime->graphics.ip);
+       ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_DISPLAY),
+                   &runtime->display.ip);
+       ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_MEDIA),
+                   &runtime->media.ip);
+}
+
+/**
+ * intel_device_info_runtime_init_early - initialize early runtime info
+ * @i915: the i915 device
+ *
+ * Determine early intel_device_info fields at runtime. This function needs
+ * to be called before the MMIO has been setup.
+ */
+void intel_device_info_runtime_init_early(struct drm_i915_private *i915)
+{
+       intel_ipver_early_init(i915);
+       intel_device_info_subplatform_init(i915);
+}
+
 /**
  * intel_device_info_runtime_init - initialize runtime info
  * @dev_priv: the i915 device
index b6b971606727c06ad98d59be238ed5dd8d1c0fcb..8e494c59f9a188d189f0bf49634fb2d1707b13b1 100644 (file)
@@ -152,6 +152,7 @@ enum intel_ppgtt_type {
        func(has_4tile); \
        func(has_flat_ccs); \
        func(has_global_mocs); \
+       func(has_gmd_id); \
        func(has_gt_uc); \
        func(has_heci_pxp); \
        func(has_heci_gscfi); \
@@ -196,9 +197,14 @@ enum intel_ppgtt_type {
 struct ip_version {
        u8 ver;
        u8 rel;
+       u8 step;
 };
 
 struct intel_runtime_info {
+       /*
+        * Single "graphics" IP version that represents
+        * render, compute and copy behavior.
+        */
        struct {
                struct ip_version ip;
        } graphics;
@@ -304,7 +310,7 @@ struct intel_driver_caps {
 
 const char *intel_platform_name(enum intel_platform platform);
 
-void intel_device_info_subplatform_init(struct drm_i915_private *dev_priv);
+void intel_device_info_runtime_init_early(struct drm_i915_private *dev_priv);
 void intel_device_info_runtime_init(struct drm_i915_private *dev_priv);
 
 void intel_device_info_print(const struct intel_device_info *info,