[Intel-xe] [PATCH v2 5/6] drm/i915/display: Handle GMD_ID identification in display code
Matt Roper
matthew.d.roper at intel.com
Tue May 23 14:43:38 UTC 2023
On Tue, May 23, 2023 at 04:02:46PM +0300, Jani Nikula wrote:
> On Mon, 22 May 2023, Matt Roper <matthew.d.roper at intel.com> wrote:
> > For platforms with GMD_ID support (i.e., everything MTL and beyond),
> > identification of the display IP present should be based on the contents
> > of the GMD_ID register rather than a PCI devid match.
> >
> > Note that since GMD_ID readout requires access to the PCI BAR, a slight
> > change to the driver init sequence is needed --- pci_enable_device() is
> > now called before i915_driver_create().
> >
> > v2:
> > - Fix use of uninitialized i915 pointer in error path if
> > pci_enable_device() fails before the i915 device is created. (lkp)
> > - Use drm_device parameter to intel_display_device_probe. This goes
> > against i915 conventions, but since the primary goal here is to make
> > it easy to call this function from other drivers (like Xe) and since
> > we don't need anything from the i915 structure, this seems like an
> > exception where drm_device is a more natural fit.
> >
> > Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
> > ---
> > .../drm/i915/display/intel_display_device.c | 64 +++++++++++++++++--
> > .../drm/i915/display/intel_display_device.h | 5 +-
> > drivers/gpu/drm/i915/i915_driver.c | 17 +++--
> > drivers/gpu/drm/i915/intel_device_info.c | 12 ++--
> > 4 files changed, 81 insertions(+), 17 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c
> > index 3c5941c8788d..6605487c3890 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_device.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_device.c
> > @@ -6,7 +6,10 @@
> > #include <drm/i915_pciids.h>
> > #include <drm/drm_color_mgmt.h>
> > #include <linux/mod_devicetable.h>
> > +#include <linux/pci.h>
> >
> > +#include "i915_drv.h"
> > +#include "i915_reg.h"
> > #include "intel_display_device.h"
> > #include "intel_display_power.h"
> > #include "intel_display_reg_defs.h"
> > @@ -692,18 +695,69 @@ static const struct pci_device_id intel_display_ids[] = {
> > INTEL_RPLP_IDS(&xe_lpd_display),
> > INTEL_DG2_IDS(&xe_hpd_display),
> >
> > - /* FIXME: Replace this with a GMD_ID lookup */
> > - INTEL_MTL_IDS(&xe_lpdp_display),
> > + /*
> > + * Do not add any GMD_ID-based platforms to this list. They will
> > + * be probed automatically based on the IP version reported by
> > + * the hardware.
> > + */
> > };
> >
> > +struct {
> > + u16 ver;
> > + u16 rel;
> > + const struct intel_display_device_info *display;
> > +} gmdid_display_map[] = {
> > + { 14, 0, &xe_lpdp_display },
> > +};
> > +
> > +static const struct intel_display_device_info *
> > +probe_gmdid_display(struct drm_device *drm, u16 *ver, u16 *rel, u16 *step)
>
> Please always prefer struct drm_i915_private * over struct drm_device *.
>
> > +{
> > + struct pci_dev *pdev = to_pci_dev(drm->dev);
> > + void __iomem *addr;
> > + u32 val;
> > + int i;
> > +
> > + addr = pci_iomap_range(pdev, 0, i915_mmio_reg_offset(GMD_ID_DISPLAY), sizeof(u32));
> > + if (!addr) {
> > + drm_err(drm, "Cannot map MMIO BAR to read display GMD_ID\n");
> > + return &no_display;
> > + }
> > +
> > + val = ioread32(addr);
> > + pci_iounmap(pdev, addr);
> > +
> > + if (val == 0)
> > + /* Platform doesn't have display */
> > + return &no_display;
> > +
> > + *ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val);
> > + *rel = REG_FIELD_GET(GMD_ID_RELEASE_MASK, val);
> > + *step = REG_FIELD_GET(GMD_ID_STEP, val);
> > +
> > + for (i = 0; i < ARRAY_SIZE(gmdid_display_map); i++)
> > + if (*ver == gmdid_display_map[i].ver &&
> > + *rel == gmdid_display_map[i].rel)
> > + return gmdid_display_map[i].display;
> > +
> > + drm_err(drm, "Unrecognized display IP version %d.%02d; disabling display.\n",
> > + *ver, *rel);
> > + return &no_display;
> > +}
> > +
> > const struct intel_display_device_info *
> > -intel_display_device_probe(u16 pci_devid)
> > +intel_display_device_probe(struct drm_device *drm, bool has_gmdid,
> > + u16 *gmdid_ver, u16 *gmdid_rel, u16 *gmdid_step)
>
> Ditto.
I was a bit torn on this one. Although we usually use drm_i915_private
in i915 code, in this case it seems like it adds a needless dependency
on i915 types and leads to more complications when calling this from
non-i915 code (like Xe). What we really need here is just 'struct
pci_dev' to obtain the device ID and map the BAR, but drm_device
lets us also use the drm_err() calls.
But for now I can just put this back to drm_i915_private; we can revisit
this later once we have more driver restructuring to move away from
drm_i915_private in a more global manner.
Matt
>
> > {
> > + struct pci_dev *pdev = to_pci_dev(drm->dev);
> > int i;
> >
> > + if (has_gmdid)
> > + return probe_gmdid_display(drm, gmdid_ver, gmdid_rel, gmdid_step);
> > +
> > for (i = 0; i < ARRAY_SIZE(intel_display_ids); i++) {
> > - if (intel_display_ids[i].device == pci_devid)
> > - return (struct intel_display_device_info *)intel_display_ids[i].driver_data;
> > + if (intel_display_ids[i].device == pdev->device)
> > + return (const struct intel_display_device_info *)intel_display_ids[i].driver_data;
> > }
> >
> > return &no_display;
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
> > index 1f7d08b3ad6b..2a14943313ad 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_device.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_device.h
> > @@ -80,7 +80,10 @@ struct intel_display_device_info {
> > } color;
> > };
> >
> > +struct drm_device;
> > +
>
> Please keep forward declarations near the top of the file, right after
> includes.
>
> > const struct intel_display_device_info *
> > -intel_display_device_probe(u16 pci_devid);
> > +intel_display_device_probe(struct drm_device *drm, bool has_gmdid,
> > + u16 *ver, u16 *rel, u16 *step);
> >
> > #endif
> > diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
> > index 522733a89946..37532e55327d 100644
> > --- a/drivers/gpu/drm/i915/i915_driver.c
> > +++ b/drivers/gpu/drm/i915/i915_driver.c
> > @@ -754,13 +754,17 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> > struct drm_i915_private *i915;
> > int ret;
> >
> > - i915 = i915_driver_create(pdev, ent);
> > - if (IS_ERR(i915))
> > - return PTR_ERR(i915);
> > -
> > ret = pci_enable_device(pdev);
> > - if (ret)
> > - goto out_fini;
> > + if (ret) {
> > + pr_err("Failed to enable graphics device: %pe\n", ERR_PTR(ret));
> > + return ret;
> > + }
> > +
> > + i915 = i915_driver_create(pdev, ent);
> > + if (IS_ERR(i915)) {
> > + ret = PTR_ERR(i915);
> > + goto out_pci_disable;
> > + }
> >
> > ret = i915_driver_early_probe(i915);
> > if (ret < 0)
> > @@ -843,7 +847,6 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> > i915_driver_late_release(i915);
> > out_pci_disable:
> > pci_disable_device(pdev);
> > -out_fini:
> > i915_probe_error(i915, "Device initialization failed (%d)\n", ret);
> > return ret;
> > }
> > diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c
> > index e1507ae59f2d..85105639d55d 100644
> > --- a/drivers/gpu/drm/i915/intel_device_info.c
> > +++ b/drivers/gpu/drm/i915/intel_device_info.c
> > @@ -345,7 +345,6 @@ static void ip_ver_read(struct drm_i915_private *i915, u32 offset, struct intel_
> > static void intel_ipver_early_init(struct drm_i915_private *i915)
> > {
> > struct intel_runtime_info *runtime = RUNTIME_INFO(i915);
> > - struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(i915);
> >
> > if (!HAS_GMD_ID(i915)) {
> > drm_WARN_ON(&i915->drm, RUNTIME_INFO(i915)->graphics.ip.ver > 12);
> > @@ -366,8 +365,6 @@ static void intel_ipver_early_init(struct drm_i915_private *i915)
> > RUNTIME_INFO(i915)->graphics.ip.ver = 12;
> > RUNTIME_INFO(i915)->graphics.ip.rel = 70;
> > }
> > - ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_DISPLAY),
> > - (struct intel_ip_version *)&display_runtime->ip);
> > ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_MEDIA),
> > &runtime->media.ip);
> > }
> > @@ -574,6 +571,7 @@ void intel_device_info_driver_create(struct drm_i915_private *i915,
> > {
> > struct intel_device_info *info;
> > struct intel_runtime_info *runtime;
> > + u16 ver, rel, step;
> >
> > /* Setup the write-once "constant" device info */
> > info = mkwrite_device_info(i915);
> > @@ -584,8 +582,14 @@ void intel_device_info_driver_create(struct drm_i915_private *i915,
> > memcpy(runtime, &INTEL_INFO(i915)->__runtime, sizeof(*runtime));
> >
> > /* Probe display support */
> > - info->display = intel_display_device_probe(device_id);
> > + info->display = intel_display_device_probe(&i915->drm, info->has_gmd_id,
> > + &ver, &rel, &step);
> > *DISPLAY_RUNTIME_INFO(i915) = DISPLAY_INFO(i915)->__runtime_defaults;
> > + if (info->has_gmd_id) {
> > + DISPLAY_RUNTIME_INFO(i915)->ip.ver = ver;
> > + DISPLAY_RUNTIME_INFO(i915)->ip.rel = rel;
> > + DISPLAY_RUNTIME_INFO(i915)->ip.step = step;
> > + }
>
> The division of initialization responsibilities between here and
> intel_display_device_probe() is perhaps a bit odd?
>
> Nothing that can't be fixed later though, I guess.
>
> BR,
> Jani.
>
> >
> > runtime->device_id = device_id;
> > }
>
> --
> Jani Nikula, Intel Open Source Graphics Center
--
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation
More information about the Intel-xe
mailing list