Commit c2c70752 authored by Matt Roper's avatar Matt Roper Committed by Radhakrishna Sripada

drm/i915: Read graphics/media/display arch version from hw

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: default avatarMatt Roper <matthew.d.roper@intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: default avatarRadhakrishna Sripada <radhakrishna.sripada@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220916014648.1310346-2-radhakrishna.sripada@intel.com
parent 958349ff
...@@ -39,6 +39,9 @@ ...@@ -39,6 +39,9 @@
#define FORCEWAKE_ACK_RENDER_GEN9 _MMIO(0xd84) #define FORCEWAKE_ACK_RENDER_GEN9 _MMIO(0xd84)
#define FORCEWAKE_ACK_MEDIA_GEN9 _MMIO(0xd88) #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 MCFG_MCR_SELECTOR _MMIO(0xfd0)
#define SF_MCR_SELECTOR _MMIO(0xfd8) #define SF_MCR_SELECTOR _MMIO(0xfd8)
#define GEN8_MCR_SELECTOR _MMIO(0xfdc) #define GEN8_MCR_SELECTOR _MMIO(0xfdc)
......
...@@ -324,7 +324,8 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv) ...@@ -324,7 +324,8 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
if (i915_inject_probe_failure(dev_priv)) if (i915_inject_probe_failure(dev_priv))
return -ENODEV; return -ENODEV;
intel_device_info_subplatform_init(dev_priv); intel_device_info_runtime_init_early(dev_priv);
intel_step_init(dev_priv); intel_step_init(dev_priv);
intel_uncore_mmio_debug_init_early(&dev_priv->mmio_debug); intel_uncore_mmio_debug_init_early(&dev_priv->mmio_debug);
......
...@@ -930,6 +930,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, ...@@ -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_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_LSPCON(dev_priv) (IS_DISPLAY_VER(dev_priv, 9, 10))
#define HAS_L3_CCS_READ(i915) (INTEL_INFO(i915)->has_l3_ccs_read) #define HAS_L3_CCS_READ(i915) (INTEL_INFO(i915)->has_l3_ccs_read)
......
...@@ -1128,6 +1128,7 @@ static const struct intel_device_info mtl_info = { ...@@ -1128,6 +1128,7 @@ static const struct intel_device_info mtl_info = {
PLATFORM(INTEL_METEORLAKE), PLATFORM(INTEL_METEORLAKE),
.display.has_modular_fia = 1, .display.has_modular_fia = 1,
.has_flat_ccs = 0, .has_flat_ccs = 0,
.has_gmd_id = 1,
.has_snoop = 1, .has_snoop = 1,
.__runtime.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM, .__runtime.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0), .__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
......
...@@ -5839,6 +5839,11 @@ ...@@ -5839,6 +5839,11 @@
#define ICL_DSSM_CDCLK_PLL_REFCLK_19_2MHz (1 << 29) #define ICL_DSSM_CDCLK_PLL_REFCLK_19_2MHz (1 << 29)
#define ICL_DSSM_CDCLK_PLL_REFCLK_38_4MHz (2 << 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 */ /*GEN11 chicken */
#define _PIPEA_CHICKEN 0x70038 #define _PIPEA_CHICKEN 0x70038
#define _PIPEB_CHICKEN 0x71038 #define _PIPEB_CHICKEN 0x71038
...@@ -8356,4 +8361,6 @@ enum skl_power_gate { ...@@ -8356,4 +8361,6 @@ enum skl_power_gate {
#define MTL_TRAS_MASK REG_GENMASK(16, 8) #define MTL_TRAS_MASK REG_GENMASK(16, 8)
#define MTL_TRDPRE_MASK REG_GENMASK(7, 0) #define MTL_TRDPRE_MASK REG_GENMASK(7, 0)
#define MTL_MEDIA_GSI_BASE 0x380000
#endif /* _I915_REG_H_ */ #endif /* _I915_REG_H_ */
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "display/intel_cdclk.h" #include "display/intel_cdclk.h"
#include "display/intel_de.h" #include "display/intel_de.h"
#include "gt/intel_gt_regs.h"
#include "intel_device_info.h" #include "intel_device_info.h"
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_utils.h" #include "i915_utils.h"
...@@ -231,7 +232,7 @@ static bool find_devid(u16 id, const u16 *p, unsigned int num) ...@@ -231,7 +232,7 @@ static bool find_devid(u16 id, const u16 *p, unsigned int num)
return false; 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_device_info *info = INTEL_INFO(i915);
const struct intel_runtime_info *rinfo = RUNTIME_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) ...@@ -288,6 +289,70 @@ void intel_device_info_subplatform_init(struct drm_i915_private *i915)
RUNTIME_INFO(i915)->platform_mask[pi] |= mask; 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 * intel_device_info_runtime_init - initialize runtime info
* @dev_priv: the i915 device * @dev_priv: the i915 device
......
...@@ -152,6 +152,7 @@ enum intel_ppgtt_type { ...@@ -152,6 +152,7 @@ enum intel_ppgtt_type {
func(has_4tile); \ func(has_4tile); \
func(has_flat_ccs); \ func(has_flat_ccs); \
func(has_global_mocs); \ func(has_global_mocs); \
func(has_gmd_id); \
func(has_gt_uc); \ func(has_gt_uc); \
func(has_heci_pxp); \ func(has_heci_pxp); \
func(has_heci_gscfi); \ func(has_heci_gscfi); \
...@@ -196,9 +197,14 @@ enum intel_ppgtt_type { ...@@ -196,9 +197,14 @@ enum intel_ppgtt_type {
struct ip_version { struct ip_version {
u8 ver; u8 ver;
u8 rel; u8 rel;
u8 step;
}; };
struct intel_runtime_info { struct intel_runtime_info {
/*
* Single "graphics" IP version that represents
* render, compute and copy behavior.
*/
struct { struct {
struct ip_version ip; struct ip_version ip;
} graphics; } graphics;
...@@ -304,7 +310,7 @@ struct intel_driver_caps { ...@@ -304,7 +310,7 @@ struct intel_driver_caps {
const char *intel_platform_name(enum intel_platform platform); 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_runtime_init(struct drm_i915_private *dev_priv);
void intel_device_info_print(const struct intel_device_info *info, void intel_device_info_print(const struct intel_device_info *info,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment