All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v10 0/5] Add driver for GSC controller
@ 2022-03-08 16:36 ` Alexander Usyskin
  0 siblings, 0 replies; 33+ messages in thread
From: Alexander Usyskin @ 2022-03-08 16:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Tvrtko Ursulin
  Cc: Tomas Winkler, Alexander Usyskin, Vitaly Lubart, intel-gfx, linux-kernel

GSC is a graphics system controller, it provides
a chassis controller for graphics discrete cards.

There are two MEI interfaces in GSC: HECI1 and HECI2.

This series includes instantiation of the auxiliary devices for HECI2
and mei-gsc auxiliary device driver that binds to the auxiliary device.

The prinicpal user of this interface is the
Intel Graphics System Controller Firmware Update Library (IGSC FU)
(https://github.com/intel/igsc)

In v2 the platform device was replaced by the auxiliary device.
v3 is the rebase over drm-tip to make public CI running.
In v4 the not needed debug prints and empty line were removed,
      'select' were replaced by 'depends on' in MEI Kconfig,
      the new include file now listed in the MAINTATINERS file. 
V5, rebase and add Greg KH Reviewed-by
V6, rebase and drop redundant assignments found by the kernel test
robot.
V7, add Greg KH Reviewed-by to the individual patches
V8, address Tvrtko comments for i915
V9, rebase and address more Tvrtko comments, use drm error printing
V10, rebase

Alexander Usyskin (2):
  mei: gsc: setup char driver alive in spite of firmware handshake
    failure
  mei: gsc: retrieve the firmware version

Tomas Winkler (3):
  drm/i915/gsc: add gsc as a mei auxiliary device
  mei: add support for graphics system controller (gsc) devices
  mei: gsc: add runtime pm handlers

 MAINTAINERS                              |   1 +
 drivers/gpu/drm/i915/Kconfig             |   1 +
 drivers/gpu/drm/i915/Makefile            |   3 +
 drivers/gpu/drm/i915/gt/intel_gsc.c      | 204 ++++++++++++++++++
 drivers/gpu/drm/i915/gt/intel_gsc.h      |  37 ++++
 drivers/gpu/drm/i915/gt/intel_gt.c       |   3 +
 drivers/gpu/drm/i915/gt/intel_gt.h       |   5 +
 drivers/gpu/drm/i915/gt/intel_gt_irq.c   |  13 ++
 drivers/gpu/drm/i915/gt/intel_gt_regs.h  |   1 +
 drivers/gpu/drm/i915/gt/intel_gt_types.h |   2 +
 drivers/gpu/drm/i915/i915_drv.h          |   8 +
 drivers/gpu/drm/i915/i915_pci.c          |   3 +-
 drivers/gpu/drm/i915/i915_reg.h          |   2 +
 drivers/gpu/drm/i915/intel_device_info.h |   2 +
 drivers/misc/mei/Kconfig                 |  14 ++
 drivers/misc/mei/Makefile                |   3 +
 drivers/misc/mei/bus-fixup.c             |  25 +++
 drivers/misc/mei/gsc-me.c                | 252 +++++++++++++++++++++++
 drivers/misc/mei/hw-me.c                 |  29 ++-
 drivers/misc/mei/hw-me.h                 |   2 +
 include/linux/mei_aux.h                  |  19 ++
 21 files changed, 626 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.c
 create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.h
 create mode 100644 drivers/misc/mei/gsc-me.c
 create mode 100644 include/linux/mei_aux.h

-- 
2.32.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [Intel-gfx] [PATCH v10 0/5] Add driver for GSC controller
@ 2022-03-08 16:36 ` Alexander Usyskin
  0 siblings, 0 replies; 33+ messages in thread
From: Alexander Usyskin @ 2022-03-08 16:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Tvrtko Ursulin
  Cc: linux-kernel, Tomas Winkler, Alexander Usyskin, Vitaly Lubart, intel-gfx

GSC is a graphics system controller, it provides
a chassis controller for graphics discrete cards.

There are two MEI interfaces in GSC: HECI1 and HECI2.

This series includes instantiation of the auxiliary devices for HECI2
and mei-gsc auxiliary device driver that binds to the auxiliary device.

The prinicpal user of this interface is the
Intel Graphics System Controller Firmware Update Library (IGSC FU)
(https://github.com/intel/igsc)

In v2 the platform device was replaced by the auxiliary device.
v3 is the rebase over drm-tip to make public CI running.
In v4 the not needed debug prints and empty line were removed,
      'select' were replaced by 'depends on' in MEI Kconfig,
      the new include file now listed in the MAINTATINERS file. 
V5, rebase and add Greg KH Reviewed-by
V6, rebase and drop redundant assignments found by the kernel test
robot.
V7, add Greg KH Reviewed-by to the individual patches
V8, address Tvrtko comments for i915
V9, rebase and address more Tvrtko comments, use drm error printing
V10, rebase

Alexander Usyskin (2):
  mei: gsc: setup char driver alive in spite of firmware handshake
    failure
  mei: gsc: retrieve the firmware version

Tomas Winkler (3):
  drm/i915/gsc: add gsc as a mei auxiliary device
  mei: add support for graphics system controller (gsc) devices
  mei: gsc: add runtime pm handlers

 MAINTAINERS                              |   1 +
 drivers/gpu/drm/i915/Kconfig             |   1 +
 drivers/gpu/drm/i915/Makefile            |   3 +
 drivers/gpu/drm/i915/gt/intel_gsc.c      | 204 ++++++++++++++++++
 drivers/gpu/drm/i915/gt/intel_gsc.h      |  37 ++++
 drivers/gpu/drm/i915/gt/intel_gt.c       |   3 +
 drivers/gpu/drm/i915/gt/intel_gt.h       |   5 +
 drivers/gpu/drm/i915/gt/intel_gt_irq.c   |  13 ++
 drivers/gpu/drm/i915/gt/intel_gt_regs.h  |   1 +
 drivers/gpu/drm/i915/gt/intel_gt_types.h |   2 +
 drivers/gpu/drm/i915/i915_drv.h          |   8 +
 drivers/gpu/drm/i915/i915_pci.c          |   3 +-
 drivers/gpu/drm/i915/i915_reg.h          |   2 +
 drivers/gpu/drm/i915/intel_device_info.h |   2 +
 drivers/misc/mei/Kconfig                 |  14 ++
 drivers/misc/mei/Makefile                |   3 +
 drivers/misc/mei/bus-fixup.c             |  25 +++
 drivers/misc/mei/gsc-me.c                | 252 +++++++++++++++++++++++
 drivers/misc/mei/hw-me.c                 |  29 ++-
 drivers/misc/mei/hw-me.h                 |   2 +
 include/linux/mei_aux.h                  |  19 ++
 21 files changed, 626 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.c
 create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.h
 create mode 100644 drivers/misc/mei/gsc-me.c
 create mode 100644 include/linux/mei_aux.h

-- 
2.32.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH v10 1/5] drm/i915/gsc: add gsc as a mei auxiliary device
  2022-03-08 16:36 ` [Intel-gfx] " Alexander Usyskin
@ 2022-03-08 16:36   ` Alexander Usyskin
  -1 siblings, 0 replies; 33+ messages in thread
From: Alexander Usyskin @ 2022-03-08 16:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Tvrtko Ursulin
  Cc: Tomas Winkler, Alexander Usyskin, Vitaly Lubart, intel-gfx,
	linux-kernel, Tvrtko Ursulin

From: Tomas Winkler <tomas.winkler@intel.com>

GSC is a graphics system controller, it provides
a chassis controller for graphics discrete cards.

There are two MEI interfaces in GSC: HECI1 and HECI2.

Both interfaces are on the BAR0 at offsets 0x00258000 and 0x00259000.
GSC is a GT Engine (class 4: instance 6). HECI1 interrupt is signaled
via bit 15 and HECI2 via bit 14 in the interrupt register.

This patch exports GSC as auxiliary device for mei driver to bind to
for HECI2 interface.

CC: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Vitaly Lubart <vitaly.lubart@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 MAINTAINERS                              |   1 +
 drivers/gpu/drm/i915/Kconfig             |   1 +
 drivers/gpu/drm/i915/Makefile            |   3 +
 drivers/gpu/drm/i915/gt/intel_gsc.c      | 204 +++++++++++++++++++++++
 drivers/gpu/drm/i915/gt/intel_gsc.h      |  37 ++++
 drivers/gpu/drm/i915/gt/intel_gt.c       |   3 +
 drivers/gpu/drm/i915/gt/intel_gt.h       |   5 +
 drivers/gpu/drm/i915/gt/intel_gt_irq.c   |  13 ++
 drivers/gpu/drm/i915/gt/intel_gt_regs.h  |   1 +
 drivers/gpu/drm/i915/gt/intel_gt_types.h |   2 +
 drivers/gpu/drm/i915/i915_drv.h          |   8 +
 drivers/gpu/drm/i915/i915_pci.c          |   3 +-
 drivers/gpu/drm/i915/i915_reg.h          |   2 +
 drivers/gpu/drm/i915/intel_device_info.h |   2 +
 include/linux/mei_aux.h                  |  19 +++
 15 files changed, 303 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.c
 create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.h
 create mode 100644 include/linux/mei_aux.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 2b1d296f92e9..d322e630d1d1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9822,6 +9822,7 @@ S:	Supported
 F:	Documentation/driver-api/mei/*
 F:	drivers/misc/mei/
 F:	drivers/watchdog/mei_wdt.c
+F:	include/linux/mei_aux.h
 F:	include/linux/mei_cl_bus.h
 F:	include/uapi/linux/mei.h
 F:	samples/mei/*
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 98c5450b8eac..2660a85175d9 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -30,6 +30,7 @@ config DRM_I915
 	select VMAP_PFN
 	select DRM_TTM
 	select DRM_BUDDY
+	select AUXILIARY_BUS
 	help
 	  Choose this option if you have a system that has "Intel Graphics
 	  Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 1a771ee5b1d0..9be7b13d8822 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -196,6 +196,9 @@ i915-y += gt/uc/intel_uc.o \
 	  gt/uc/intel_huc_debugfs.o \
 	  gt/uc/intel_huc_fw.o
 
+# graphics system controller (GSC) support
+i915-y += gt/intel_gsc.o
+
 # modesetting core code
 i915-y += \
 	display/hsw_ips.o \
diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.c b/drivers/gpu/drm/i915/gt/intel_gsc.c
new file mode 100644
index 000000000000..152804e7c41a
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/intel_gsc.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
+ */
+
+#include <linux/irq.h>
+#include <linux/mei_aux.h>
+#include "i915_reg.h"
+#include "i915_drv.h"
+#include "gt/intel_gt.h"
+#include "intel_gsc.h"
+
+#define GSC_BAR_LENGTH  0x00000FFC
+
+static void gsc_irq_mask(struct irq_data *d)
+{
+	/* generic irq handling */
+}
+
+static void gsc_irq_unmask(struct irq_data *d)
+{
+	/* generic irq handling */
+}
+
+static struct irq_chip gsc_irq_chip = {
+	.name = "gsc_irq_chip",
+	.irq_mask = gsc_irq_mask,
+	.irq_unmask = gsc_irq_unmask,
+};
+
+static int gsc_irq_init(int irq)
+{
+	irq_set_chip_and_handler_name(irq, &gsc_irq_chip,
+				      handle_simple_irq, "gsc_irq_handler");
+
+	return irq_set_chip_data(irq, NULL);
+}
+
+struct intel_gsc_def {
+	const char *name;
+	unsigned long bar;
+	size_t bar_size;
+};
+
+/* gscfi (graphics system controller firmware interface) resources */
+static const struct intel_gsc_def intel_gsc_def_dg1[] = {
+	{
+		/* HECI1 not yet implemented. */
+	},
+	{
+		.name = "mei-gscfi",
+		.bar = GSC_DG1_HECI2_BASE,
+		.bar_size = GSC_BAR_LENGTH,
+	}
+};
+
+static void intel_gsc_release_dev(struct device *dev)
+{
+	struct auxiliary_device *aux_dev = to_auxiliary_dev(dev);
+	struct mei_aux_device *adev = auxiliary_dev_to_mei_aux_dev(aux_dev);
+
+	kfree(adev);
+}
+
+static void intel_gsc_destroy_one(struct intel_gsc_intf *intf)
+{
+	if (intf->adev) {
+		auxiliary_device_delete(&intf->adev->aux_dev);
+		auxiliary_device_uninit(&intf->adev->aux_dev);
+		intf->adev = NULL;
+	}
+	if (intf->irq >= 0)
+		irq_free_desc(intf->irq);
+	intf->irq = -1;
+}
+
+static void intel_gsc_init_one(struct drm_i915_private *i915,
+			       struct intel_gsc_intf *intf,
+			       unsigned int intf_id)
+{
+	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
+	struct mei_aux_device *adev;
+	struct auxiliary_device *aux_dev;
+	const struct intel_gsc_def *def;
+	int ret;
+
+	intf->irq = -1;
+	intf->id = intf_id;
+
+	if (intf_id == 0 && !HAS_HECI_PXP(i915))
+		return;
+
+	def = &intel_gsc_def_dg1[intf_id];
+
+	if (!def->name) {
+		drm_warn_once(&i915->drm, "HECI%d is not implemented!\n", intf_id + 1);
+		return;
+	}
+
+	intf->irq = irq_alloc_desc(0);
+	if (intf->irq < 0) {
+		drm_err(&i915->drm, "gsc irq error %d\n", intf->irq);
+		return;
+	}
+
+	ret = gsc_irq_init(intf->irq);
+	if (ret < 0) {
+		drm_err(&i915->drm, "gsc irq init failed %d\n", ret);
+		goto fail;
+	}
+
+	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+	if (!adev)
+		goto fail;
+
+	adev->irq = intf->irq;
+	adev->bar.parent = &pdev->resource[0];
+	adev->bar.start = def->bar + pdev->resource[0].start;
+	adev->bar.end = adev->bar.start + def->bar_size - 1;
+	adev->bar.flags = IORESOURCE_MEM;
+	adev->bar.desc = IORES_DESC_NONE;
+
+	aux_dev = &adev->aux_dev;
+	aux_dev->name = def->name;
+	aux_dev->id = (pci_domain_nr(pdev->bus) << 16) |
+		      PCI_DEVID(pdev->bus->number, pdev->devfn);
+	aux_dev->dev.parent = &pdev->dev;
+	aux_dev->dev.release = intel_gsc_release_dev;
+
+	ret = auxiliary_device_init(aux_dev);
+	if (ret < 0) {
+		drm_err(&i915->drm, "gsc aux init failed %d\n", ret);
+		kfree(adev);
+		goto fail;
+	}
+
+	ret = auxiliary_device_add(aux_dev);
+	if (ret < 0) {
+		drm_err(&i915->drm, "gsc aux add failed %d\n", ret);
+		/* adev will be freed with the put_device() and .release sequence */
+		auxiliary_device_uninit(aux_dev);
+		goto fail;
+	}
+	intf->adev = adev;
+
+	return;
+fail:
+	intel_gsc_destroy_one(intf);
+}
+
+static void gsc_irq_handler(struct intel_gt *gt, unsigned int intf_id)
+{
+	int ret;
+
+	if (intf_id >= INTEL_GSC_NUM_INTERFACES) {
+		drm_warn_once(&gt->i915->drm, "GSC irq: intf_id %d is out of range", intf_id);
+		return;
+	}
+
+	if (!HAS_HECI_GSC(gt->i915)) {
+		drm_warn_once(&gt->i915->drm, "GSC irq: not supported");
+		return;
+	}
+
+	if (gt->gsc.intf[intf_id].irq < 0) {
+		drm_err_ratelimited(&gt->i915->drm, "GSC irq: irq not set");
+		return;
+	}
+
+	ret = generic_handle_irq(gt->gsc.intf[intf_id].irq);
+	if (ret)
+		drm_err_ratelimited(&gt->i915->drm, "error handling GSC irq: %d\n", ret);
+}
+
+void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir)
+{
+	if (iir & GSC_IRQ_INTF(0))
+		gsc_irq_handler(gt, 0);
+	if (iir & GSC_IRQ_INTF(1))
+		gsc_irq_handler(gt, 1);
+}
+
+void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private *i915)
+{
+	unsigned int i;
+
+	if (!HAS_HECI_GSC(i915))
+		return;
+
+	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
+		intel_gsc_init_one(i915, &gsc->intf[i], i);
+}
+
+void intel_gsc_fini(struct intel_gsc *gsc)
+{
+	struct intel_gt *gt = gsc_to_gt(gsc);
+	unsigned int i;
+
+	if (!HAS_HECI_GSC(gt->i915))
+		return;
+
+	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
+		intel_gsc_destroy_one(&gsc->intf[i]);
+}
diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.h b/drivers/gpu/drm/i915/gt/intel_gsc.h
new file mode 100644
index 000000000000..68582f912b21
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/intel_gsc.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
+ */
+#ifndef __INTEL_GSC_DEV_H__
+#define __INTEL_GSC_DEV_H__
+
+#include <linux/types.h>
+
+struct drm_i915_private;
+struct intel_gt;
+struct mei_aux_device;
+
+#define INTEL_GSC_NUM_INTERFACES 2
+/*
+ * The HECI1 bit corresponds to bit15 and HECI2 to bit14.
+ * The reason for this is to allow growth for more interfaces in the future.
+ */
+#define GSC_IRQ_INTF(_x)  BIT(15 - (_x))
+
+/**
+ * struct intel_gsc - graphics security controller
+ * @intf : gsc interface
+ */
+struct intel_gsc {
+	struct intel_gsc_intf {
+		struct mei_aux_device *adev;
+		int irq;
+		unsigned int id;
+	} intf[INTEL_GSC_NUM_INTERFACES];
+};
+
+void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private *dev_priv);
+void intel_gsc_fini(struct intel_gsc *gsc);
+void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir);
+
+#endif /* __INTEL_GSC_DEV_H__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
index 8a2483ccbfb9..fd83ab4b8849 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -444,6 +444,8 @@ void intel_gt_chipset_flush(struct intel_gt *gt)
 
 void intel_gt_driver_register(struct intel_gt *gt)
 {
+	intel_gsc_init(&gt->gsc, gt->i915);
+
 	intel_rps_driver_register(&gt->rps);
 
 	intel_gt_debugfs_register(gt);
@@ -766,6 +768,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
 	intel_wakeref_t wakeref;
 
 	intel_rps_driver_unregister(&gt->rps);
+	intel_gsc_fini(&gt->gsc);
 
 	intel_pxp_fini(&gt->pxp);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h
index 0f571c8ee22b..de779a505c21 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt.h
@@ -34,6 +34,11 @@ static inline struct intel_gt *huc_to_gt(struct intel_huc *huc)
 	return container_of(huc, struct intel_gt, uc.huc);
 }
 
+static inline struct intel_gt *gsc_to_gt(struct intel_gsc *gsc)
+{
+	return container_of(gsc, struct intel_gt, gsc);
+}
+
 void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915);
 void __intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915);
 int intel_gt_assign_ggtt(struct intel_gt *gt);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index e443ac4c8059..917b85d0c189 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -68,6 +68,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 instance,
 	if (instance == OTHER_KCR_INSTANCE)
 		return intel_pxp_irq_handler(&gt->pxp, iir);
 
+	if (instance == OTHER_GSC_INSTANCE)
+		return intel_gsc_irq_handler(gt, iir);
+
 	WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
 		  instance, iir);
 }
@@ -184,6 +187,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
 	intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE,	  0);
 	if (CCS_MASK(gt))
 		intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, 0);
+	if (HAS_HECI_GSC(gt->i915))
+		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE, 0);
 
 	/* Restore masks irqs on RCS, BCS, VCS and VECS engines. */
 	intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK,	~0);
@@ -201,6 +206,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
 		intel_uncore_write(uncore, GEN12_CCS0_CCS1_INTR_MASK, ~0);
 	if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3))
 		intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~0);
+	if (HAS_HECI_GSC(gt->i915))
+		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, ~0);
 
 	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0);
 	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
@@ -215,6 +222,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
 {
 	struct intel_uncore *uncore = gt->uncore;
 	u32 irqs = GT_RENDER_USER_INTERRUPT;
+	const u32 gsc_mask = GSC_IRQ_INTF(0) | GSC_IRQ_INTF(1);
 	u32 dmask;
 	u32 smask;
 
@@ -233,6 +241,9 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
 	intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE, dmask);
 	if (CCS_MASK(gt))
 		intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, smask);
+	if (HAS_HECI_GSC(gt->i915))
+		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE,
+				   gsc_mask);
 
 	/* Unmask irqs on RCS, BCS, VCS and VECS engines. */
 	intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK, ~smask);
@@ -250,6 +261,8 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
 		intel_uncore_write(uncore, GEN12_CCS0_CCS1_INTR_MASK, ~dmask);
 	if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3))
 		intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~dmask);
+	if (HAS_HECI_GSC(gt->i915))
+		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, 0);
 
 	/*
 	 * RPS interrupts will get enabled/disabled on demand when RPS itself
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index 19cd34f24263..a277fb480cc8 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1483,6 +1483,7 @@
 #define   OTHER_GUC_INSTANCE			0
 #define   OTHER_GTPM_INSTANCE			1
 #define   OTHER_KCR_INSTANCE			4
+#define   OTHER_GSC_INSTANCE			6
 
 #define GEN11_IIR_REG_SELECTOR(x)		_MMIO(0x190070 + ((x) * 4))
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index f20687796490..5556d55f76ea 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -16,6 +16,7 @@
 #include <linux/workqueue.h>
 
 #include "uc/intel_uc.h"
+#include "intel_gsc.h"
 
 #include "i915_vma.h"
 #include "intel_engine_types.h"
@@ -72,6 +73,7 @@ struct intel_gt {
 	struct i915_ggtt *ggtt;
 
 	struct intel_uc uc;
+	struct intel_gsc gsc;
 
 	struct mutex tlb_invalidate_lock;
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 943267393ecb..1c000c15493d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1327,6 +1327,14 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 
 #define HAS_DMC(dev_priv)	(INTEL_INFO(dev_priv)->display.has_dmc)
 
+#define HAS_HECI_PXP(dev_priv) \
+	(INTEL_INFO(dev_priv)->has_heci_pxp)
+
+#define HAS_HECI_GSCFI(dev_priv) \
+	(INTEL_INFO(dev_priv)->has_heci_gscfi)
+
+#define HAS_HECI_GSC(dev_priv) (HAS_HECI_PXP(dev_priv) || HAS_HECI_GSCFI(dev_priv))
+
 #define HAS_MSO(i915)		(DISPLAY_VER(i915) >= 12)
 
 #define HAS_RUNTIME_PM(dev_priv) (INTEL_INFO(dev_priv)->has_runtime_pm)
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 67b89769f577..a948f566bd3d 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -901,7 +901,8 @@ static const struct intel_device_info rkl_info = {
 	.has_llc = 0, \
 	.has_pxp = 0, \
 	.has_snoop = 1, \
-	.is_dgfx = 1
+	.is_dgfx = 1, \
+	.has_heci_gscfi = 1
 
 static const struct intel_device_info dg1_info = {
 	GEN12_FEATURES,
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 70484f6f2b8b..0ed305ff07a9 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -975,6 +975,8 @@
 #define GEN12_COMPUTE1_RING_BASE	0x1c000
 #define GEN12_COMPUTE2_RING_BASE	0x1e000
 #define GEN12_COMPUTE3_RING_BASE	0x26000
+#define GSC_DG1_HECI1_BASE	0x00258000
+#define GSC_DG1_HECI2_BASE	0x00259000
 #define BLT_RING_BASE		0x22000
 
 
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index f9b955810593..576d15a04c9e 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -141,6 +141,8 @@ enum intel_ppgtt_type {
 	func(has_flat_ccs); \
 	func(has_global_mocs); \
 	func(has_gt_uc); \
+	func(has_heci_pxp); \
+	func(has_heci_gscfi); \
 	func(has_guc_deprivilege); \
 	func(has_l3_dpf); \
 	func(has_llc); \
diff --git a/include/linux/mei_aux.h b/include/linux/mei_aux.h
new file mode 100644
index 000000000000..587f25128848
--- /dev/null
+++ b/include/linux/mei_aux.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022, Intel Corporation. All rights reserved.
+ */
+#ifndef _LINUX_MEI_AUX_H
+#define _LINUX_MEI_AUX_H
+
+#include <linux/auxiliary_bus.h>
+
+struct mei_aux_device {
+	struct auxiliary_device aux_dev;
+	int irq;
+	struct resource bar;
+};
+
+#define auxiliary_dev_to_mei_aux_dev(auxiliary_dev) \
+	container_of(auxiliary_dev, struct mei_aux_device, aux_dev)
+
+#endif /* _LINUX_MEI_AUX_H */
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Intel-gfx] [PATCH v10 1/5] drm/i915/gsc: add gsc as a mei auxiliary device
@ 2022-03-08 16:36   ` Alexander Usyskin
  0 siblings, 0 replies; 33+ messages in thread
From: Alexander Usyskin @ 2022-03-08 16:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Tvrtko Ursulin
  Cc: intel-gfx, Alexander Usyskin, linux-kernel, Tomas Winkler, Vitaly Lubart

From: Tomas Winkler <tomas.winkler@intel.com>

GSC is a graphics system controller, it provides
a chassis controller for graphics discrete cards.

There are two MEI interfaces in GSC: HECI1 and HECI2.

Both interfaces are on the BAR0 at offsets 0x00258000 and 0x00259000.
GSC is a GT Engine (class 4: instance 6). HECI1 interrupt is signaled
via bit 15 and HECI2 via bit 14 in the interrupt register.

This patch exports GSC as auxiliary device for mei driver to bind to
for HECI2 interface.

CC: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Vitaly Lubart <vitaly.lubart@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 MAINTAINERS                              |   1 +
 drivers/gpu/drm/i915/Kconfig             |   1 +
 drivers/gpu/drm/i915/Makefile            |   3 +
 drivers/gpu/drm/i915/gt/intel_gsc.c      | 204 +++++++++++++++++++++++
 drivers/gpu/drm/i915/gt/intel_gsc.h      |  37 ++++
 drivers/gpu/drm/i915/gt/intel_gt.c       |   3 +
 drivers/gpu/drm/i915/gt/intel_gt.h       |   5 +
 drivers/gpu/drm/i915/gt/intel_gt_irq.c   |  13 ++
 drivers/gpu/drm/i915/gt/intel_gt_regs.h  |   1 +
 drivers/gpu/drm/i915/gt/intel_gt_types.h |   2 +
 drivers/gpu/drm/i915/i915_drv.h          |   8 +
 drivers/gpu/drm/i915/i915_pci.c          |   3 +-
 drivers/gpu/drm/i915/i915_reg.h          |   2 +
 drivers/gpu/drm/i915/intel_device_info.h |   2 +
 include/linux/mei_aux.h                  |  19 +++
 15 files changed, 303 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.c
 create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.h
 create mode 100644 include/linux/mei_aux.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 2b1d296f92e9..d322e630d1d1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9822,6 +9822,7 @@ S:	Supported
 F:	Documentation/driver-api/mei/*
 F:	drivers/misc/mei/
 F:	drivers/watchdog/mei_wdt.c
+F:	include/linux/mei_aux.h
 F:	include/linux/mei_cl_bus.h
 F:	include/uapi/linux/mei.h
 F:	samples/mei/*
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 98c5450b8eac..2660a85175d9 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -30,6 +30,7 @@ config DRM_I915
 	select VMAP_PFN
 	select DRM_TTM
 	select DRM_BUDDY
+	select AUXILIARY_BUS
 	help
 	  Choose this option if you have a system that has "Intel Graphics
 	  Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 1a771ee5b1d0..9be7b13d8822 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -196,6 +196,9 @@ i915-y += gt/uc/intel_uc.o \
 	  gt/uc/intel_huc_debugfs.o \
 	  gt/uc/intel_huc_fw.o
 
+# graphics system controller (GSC) support
+i915-y += gt/intel_gsc.o
+
 # modesetting core code
 i915-y += \
 	display/hsw_ips.o \
diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.c b/drivers/gpu/drm/i915/gt/intel_gsc.c
new file mode 100644
index 000000000000..152804e7c41a
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/intel_gsc.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
+ */
+
+#include <linux/irq.h>
+#include <linux/mei_aux.h>
+#include "i915_reg.h"
+#include "i915_drv.h"
+#include "gt/intel_gt.h"
+#include "intel_gsc.h"
+
+#define GSC_BAR_LENGTH  0x00000FFC
+
+static void gsc_irq_mask(struct irq_data *d)
+{
+	/* generic irq handling */
+}
+
+static void gsc_irq_unmask(struct irq_data *d)
+{
+	/* generic irq handling */
+}
+
+static struct irq_chip gsc_irq_chip = {
+	.name = "gsc_irq_chip",
+	.irq_mask = gsc_irq_mask,
+	.irq_unmask = gsc_irq_unmask,
+};
+
+static int gsc_irq_init(int irq)
+{
+	irq_set_chip_and_handler_name(irq, &gsc_irq_chip,
+				      handle_simple_irq, "gsc_irq_handler");
+
+	return irq_set_chip_data(irq, NULL);
+}
+
+struct intel_gsc_def {
+	const char *name;
+	unsigned long bar;
+	size_t bar_size;
+};
+
+/* gscfi (graphics system controller firmware interface) resources */
+static const struct intel_gsc_def intel_gsc_def_dg1[] = {
+	{
+		/* HECI1 not yet implemented. */
+	},
+	{
+		.name = "mei-gscfi",
+		.bar = GSC_DG1_HECI2_BASE,
+		.bar_size = GSC_BAR_LENGTH,
+	}
+};
+
+static void intel_gsc_release_dev(struct device *dev)
+{
+	struct auxiliary_device *aux_dev = to_auxiliary_dev(dev);
+	struct mei_aux_device *adev = auxiliary_dev_to_mei_aux_dev(aux_dev);
+
+	kfree(adev);
+}
+
+static void intel_gsc_destroy_one(struct intel_gsc_intf *intf)
+{
+	if (intf->adev) {
+		auxiliary_device_delete(&intf->adev->aux_dev);
+		auxiliary_device_uninit(&intf->adev->aux_dev);
+		intf->adev = NULL;
+	}
+	if (intf->irq >= 0)
+		irq_free_desc(intf->irq);
+	intf->irq = -1;
+}
+
+static void intel_gsc_init_one(struct drm_i915_private *i915,
+			       struct intel_gsc_intf *intf,
+			       unsigned int intf_id)
+{
+	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
+	struct mei_aux_device *adev;
+	struct auxiliary_device *aux_dev;
+	const struct intel_gsc_def *def;
+	int ret;
+
+	intf->irq = -1;
+	intf->id = intf_id;
+
+	if (intf_id == 0 && !HAS_HECI_PXP(i915))
+		return;
+
+	def = &intel_gsc_def_dg1[intf_id];
+
+	if (!def->name) {
+		drm_warn_once(&i915->drm, "HECI%d is not implemented!\n", intf_id + 1);
+		return;
+	}
+
+	intf->irq = irq_alloc_desc(0);
+	if (intf->irq < 0) {
+		drm_err(&i915->drm, "gsc irq error %d\n", intf->irq);
+		return;
+	}
+
+	ret = gsc_irq_init(intf->irq);
+	if (ret < 0) {
+		drm_err(&i915->drm, "gsc irq init failed %d\n", ret);
+		goto fail;
+	}
+
+	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+	if (!adev)
+		goto fail;
+
+	adev->irq = intf->irq;
+	adev->bar.parent = &pdev->resource[0];
+	adev->bar.start = def->bar + pdev->resource[0].start;
+	adev->bar.end = adev->bar.start + def->bar_size - 1;
+	adev->bar.flags = IORESOURCE_MEM;
+	adev->bar.desc = IORES_DESC_NONE;
+
+	aux_dev = &adev->aux_dev;
+	aux_dev->name = def->name;
+	aux_dev->id = (pci_domain_nr(pdev->bus) << 16) |
+		      PCI_DEVID(pdev->bus->number, pdev->devfn);
+	aux_dev->dev.parent = &pdev->dev;
+	aux_dev->dev.release = intel_gsc_release_dev;
+
+	ret = auxiliary_device_init(aux_dev);
+	if (ret < 0) {
+		drm_err(&i915->drm, "gsc aux init failed %d\n", ret);
+		kfree(adev);
+		goto fail;
+	}
+
+	ret = auxiliary_device_add(aux_dev);
+	if (ret < 0) {
+		drm_err(&i915->drm, "gsc aux add failed %d\n", ret);
+		/* adev will be freed with the put_device() and .release sequence */
+		auxiliary_device_uninit(aux_dev);
+		goto fail;
+	}
+	intf->adev = adev;
+
+	return;
+fail:
+	intel_gsc_destroy_one(intf);
+}
+
+static void gsc_irq_handler(struct intel_gt *gt, unsigned int intf_id)
+{
+	int ret;
+
+	if (intf_id >= INTEL_GSC_NUM_INTERFACES) {
+		drm_warn_once(&gt->i915->drm, "GSC irq: intf_id %d is out of range", intf_id);
+		return;
+	}
+
+	if (!HAS_HECI_GSC(gt->i915)) {
+		drm_warn_once(&gt->i915->drm, "GSC irq: not supported");
+		return;
+	}
+
+	if (gt->gsc.intf[intf_id].irq < 0) {
+		drm_err_ratelimited(&gt->i915->drm, "GSC irq: irq not set");
+		return;
+	}
+
+	ret = generic_handle_irq(gt->gsc.intf[intf_id].irq);
+	if (ret)
+		drm_err_ratelimited(&gt->i915->drm, "error handling GSC irq: %d\n", ret);
+}
+
+void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir)
+{
+	if (iir & GSC_IRQ_INTF(0))
+		gsc_irq_handler(gt, 0);
+	if (iir & GSC_IRQ_INTF(1))
+		gsc_irq_handler(gt, 1);
+}
+
+void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private *i915)
+{
+	unsigned int i;
+
+	if (!HAS_HECI_GSC(i915))
+		return;
+
+	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
+		intel_gsc_init_one(i915, &gsc->intf[i], i);
+}
+
+void intel_gsc_fini(struct intel_gsc *gsc)
+{
+	struct intel_gt *gt = gsc_to_gt(gsc);
+	unsigned int i;
+
+	if (!HAS_HECI_GSC(gt->i915))
+		return;
+
+	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
+		intel_gsc_destroy_one(&gsc->intf[i]);
+}
diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.h b/drivers/gpu/drm/i915/gt/intel_gsc.h
new file mode 100644
index 000000000000..68582f912b21
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/intel_gsc.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
+ */
+#ifndef __INTEL_GSC_DEV_H__
+#define __INTEL_GSC_DEV_H__
+
+#include <linux/types.h>
+
+struct drm_i915_private;
+struct intel_gt;
+struct mei_aux_device;
+
+#define INTEL_GSC_NUM_INTERFACES 2
+/*
+ * The HECI1 bit corresponds to bit15 and HECI2 to bit14.
+ * The reason for this is to allow growth for more interfaces in the future.
+ */
+#define GSC_IRQ_INTF(_x)  BIT(15 - (_x))
+
+/**
+ * struct intel_gsc - graphics security controller
+ * @intf : gsc interface
+ */
+struct intel_gsc {
+	struct intel_gsc_intf {
+		struct mei_aux_device *adev;
+		int irq;
+		unsigned int id;
+	} intf[INTEL_GSC_NUM_INTERFACES];
+};
+
+void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private *dev_priv);
+void intel_gsc_fini(struct intel_gsc *gsc);
+void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir);
+
+#endif /* __INTEL_GSC_DEV_H__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
index 8a2483ccbfb9..fd83ab4b8849 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -444,6 +444,8 @@ void intel_gt_chipset_flush(struct intel_gt *gt)
 
 void intel_gt_driver_register(struct intel_gt *gt)
 {
+	intel_gsc_init(&gt->gsc, gt->i915);
+
 	intel_rps_driver_register(&gt->rps);
 
 	intel_gt_debugfs_register(gt);
@@ -766,6 +768,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
 	intel_wakeref_t wakeref;
 
 	intel_rps_driver_unregister(&gt->rps);
+	intel_gsc_fini(&gt->gsc);
 
 	intel_pxp_fini(&gt->pxp);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h
index 0f571c8ee22b..de779a505c21 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt.h
@@ -34,6 +34,11 @@ static inline struct intel_gt *huc_to_gt(struct intel_huc *huc)
 	return container_of(huc, struct intel_gt, uc.huc);
 }
 
+static inline struct intel_gt *gsc_to_gt(struct intel_gsc *gsc)
+{
+	return container_of(gsc, struct intel_gt, gsc);
+}
+
 void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915);
 void __intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915);
 int intel_gt_assign_ggtt(struct intel_gt *gt);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index e443ac4c8059..917b85d0c189 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -68,6 +68,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 instance,
 	if (instance == OTHER_KCR_INSTANCE)
 		return intel_pxp_irq_handler(&gt->pxp, iir);
 
+	if (instance == OTHER_GSC_INSTANCE)
+		return intel_gsc_irq_handler(gt, iir);
+
 	WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
 		  instance, iir);
 }
@@ -184,6 +187,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
 	intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE,	  0);
 	if (CCS_MASK(gt))
 		intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, 0);
+	if (HAS_HECI_GSC(gt->i915))
+		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE, 0);
 
 	/* Restore masks irqs on RCS, BCS, VCS and VECS engines. */
 	intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK,	~0);
@@ -201,6 +206,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
 		intel_uncore_write(uncore, GEN12_CCS0_CCS1_INTR_MASK, ~0);
 	if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3))
 		intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~0);
+	if (HAS_HECI_GSC(gt->i915))
+		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, ~0);
 
 	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0);
 	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
@@ -215,6 +222,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
 {
 	struct intel_uncore *uncore = gt->uncore;
 	u32 irqs = GT_RENDER_USER_INTERRUPT;
+	const u32 gsc_mask = GSC_IRQ_INTF(0) | GSC_IRQ_INTF(1);
 	u32 dmask;
 	u32 smask;
 
@@ -233,6 +241,9 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
 	intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE, dmask);
 	if (CCS_MASK(gt))
 		intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, smask);
+	if (HAS_HECI_GSC(gt->i915))
+		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE,
+				   gsc_mask);
 
 	/* Unmask irqs on RCS, BCS, VCS and VECS engines. */
 	intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK, ~smask);
@@ -250,6 +261,8 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
 		intel_uncore_write(uncore, GEN12_CCS0_CCS1_INTR_MASK, ~dmask);
 	if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3))
 		intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~dmask);
+	if (HAS_HECI_GSC(gt->i915))
+		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, 0);
 
 	/*
 	 * RPS interrupts will get enabled/disabled on demand when RPS itself
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index 19cd34f24263..a277fb480cc8 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1483,6 +1483,7 @@
 #define   OTHER_GUC_INSTANCE			0
 #define   OTHER_GTPM_INSTANCE			1
 #define   OTHER_KCR_INSTANCE			4
+#define   OTHER_GSC_INSTANCE			6
 
 #define GEN11_IIR_REG_SELECTOR(x)		_MMIO(0x190070 + ((x) * 4))
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index f20687796490..5556d55f76ea 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -16,6 +16,7 @@
 #include <linux/workqueue.h>
 
 #include "uc/intel_uc.h"
+#include "intel_gsc.h"
 
 #include "i915_vma.h"
 #include "intel_engine_types.h"
@@ -72,6 +73,7 @@ struct intel_gt {
 	struct i915_ggtt *ggtt;
 
 	struct intel_uc uc;
+	struct intel_gsc gsc;
 
 	struct mutex tlb_invalidate_lock;
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 943267393ecb..1c000c15493d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1327,6 +1327,14 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 
 #define HAS_DMC(dev_priv)	(INTEL_INFO(dev_priv)->display.has_dmc)
 
+#define HAS_HECI_PXP(dev_priv) \
+	(INTEL_INFO(dev_priv)->has_heci_pxp)
+
+#define HAS_HECI_GSCFI(dev_priv) \
+	(INTEL_INFO(dev_priv)->has_heci_gscfi)
+
+#define HAS_HECI_GSC(dev_priv) (HAS_HECI_PXP(dev_priv) || HAS_HECI_GSCFI(dev_priv))
+
 #define HAS_MSO(i915)		(DISPLAY_VER(i915) >= 12)
 
 #define HAS_RUNTIME_PM(dev_priv) (INTEL_INFO(dev_priv)->has_runtime_pm)
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 67b89769f577..a948f566bd3d 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -901,7 +901,8 @@ static const struct intel_device_info rkl_info = {
 	.has_llc = 0, \
 	.has_pxp = 0, \
 	.has_snoop = 1, \
-	.is_dgfx = 1
+	.is_dgfx = 1, \
+	.has_heci_gscfi = 1
 
 static const struct intel_device_info dg1_info = {
 	GEN12_FEATURES,
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 70484f6f2b8b..0ed305ff07a9 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -975,6 +975,8 @@
 #define GEN12_COMPUTE1_RING_BASE	0x1c000
 #define GEN12_COMPUTE2_RING_BASE	0x1e000
 #define GEN12_COMPUTE3_RING_BASE	0x26000
+#define GSC_DG1_HECI1_BASE	0x00258000
+#define GSC_DG1_HECI2_BASE	0x00259000
 #define BLT_RING_BASE		0x22000
 
 
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index f9b955810593..576d15a04c9e 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -141,6 +141,8 @@ enum intel_ppgtt_type {
 	func(has_flat_ccs); \
 	func(has_global_mocs); \
 	func(has_gt_uc); \
+	func(has_heci_pxp); \
+	func(has_heci_gscfi); \
 	func(has_guc_deprivilege); \
 	func(has_l3_dpf); \
 	func(has_llc); \
diff --git a/include/linux/mei_aux.h b/include/linux/mei_aux.h
new file mode 100644
index 000000000000..587f25128848
--- /dev/null
+++ b/include/linux/mei_aux.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022, Intel Corporation. All rights reserved.
+ */
+#ifndef _LINUX_MEI_AUX_H
+#define _LINUX_MEI_AUX_H
+
+#include <linux/auxiliary_bus.h>
+
+struct mei_aux_device {
+	struct auxiliary_device aux_dev;
+	int irq;
+	struct resource bar;
+};
+
+#define auxiliary_dev_to_mei_aux_dev(auxiliary_dev) \
+	container_of(auxiliary_dev, struct mei_aux_device, aux_dev)
+
+#endif /* _LINUX_MEI_AUX_H */
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v10 2/5] mei: add support for graphics system controller (gsc) devices
  2022-03-08 16:36 ` [Intel-gfx] " Alexander Usyskin
@ 2022-03-08 16:36   ` Alexander Usyskin
  -1 siblings, 0 replies; 33+ messages in thread
From: Alexander Usyskin @ 2022-03-08 16:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Tvrtko Ursulin
  Cc: Tomas Winkler, Alexander Usyskin, Vitaly Lubart, intel-gfx, linux-kernel

From: Tomas Winkler <tomas.winkler@intel.com>

GSC is a graphics system controller, based on CSE, it provides
a chassis controller for graphics discrete cards, as well as it
supports media protection on selected devices.

mei_gsc binds to a auxiliary devices exposed by Intel discrete
driver i915.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/Kconfig  |  14 +++
 drivers/misc/mei/Makefile |   3 +
 drivers/misc/mei/gsc-me.c | 186 ++++++++++++++++++++++++++++++++++++++
 drivers/misc/mei/hw-me.c  |  27 +++++-
 drivers/misc/mei/hw-me.h  |   2 +
 5 files changed, 230 insertions(+), 2 deletions(-)
 create mode 100644 drivers/misc/mei/gsc-me.c

diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index 0e0bcd0da852..d21486d69df2 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -46,6 +46,20 @@ config INTEL_MEI_TXE
 	  Supported SoCs:
 	  Intel Bay Trail
 
+config INTEL_MEI_GSC
+	tristate "Intel MEI GSC embedded device"
+	depends on INTEL_MEI
+	depends on INTEL_MEI_ME
+	depends on X86 && PCI
+	depends on DRM_I915
+	help
+	  Intel auxiliary driver for GSC devices embedded in Intel graphics devices.
+
+	  An MEI device here called GSC can be embedded in an
+	  Intel graphics devices, to support a range of chassis
+	  tasks such as graphics card firmware update and security
+	  tasks.
+
 source "drivers/misc/mei/hdcp/Kconfig"
 source "drivers/misc/mei/pxp/Kconfig"
 
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index d8e5165917f2..fb740d754900 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -18,6 +18,9 @@ obj-$(CONFIG_INTEL_MEI_ME) += mei-me.o
 mei-me-objs := pci-me.o
 mei-me-objs += hw-me.o
 
+obj-$(CONFIG_INTEL_MEI_GSC) += mei-gsc.o
+mei-gsc-objs := gsc-me.o
+
 obj-$(CONFIG_INTEL_MEI_TXE) += mei-txe.o
 mei-txe-objs := pci-txe.o
 mei-txe-objs += hw-txe.o
diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
new file mode 100644
index 000000000000..0afae70e0609
--- /dev/null
+++ b/drivers/misc/mei/gsc-me.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ */
+
+#include <linux/module.h>
+#include <linux/mei_aux.h>
+#include <linux/device.h>
+#include <linux/irqreturn.h>
+#include <linux/jiffies.h>
+#include <linux/ktime.h>
+#include <linux/delay.h>
+#include <linux/pm_runtime.h>
+
+#include "mei_dev.h"
+#include "hw-me.h"
+#include "hw-me-regs.h"
+
+#include "mei-trace.h"
+
+#define MEI_GSC_RPM_TIMEOUT 500
+
+static int mei_gsc_read_hfs(const struct mei_device *dev, int where, u32 *val)
+{
+	struct mei_me_hw *hw = to_me_hw(dev);
+
+	*val = ioread32(hw->mem_addr + where + 0xC00);
+
+	return 0;
+}
+
+static int mei_gsc_probe(struct auxiliary_device *aux_dev,
+			 const struct auxiliary_device_id *aux_dev_id)
+{
+	struct mei_aux_device *adev = auxiliary_dev_to_mei_aux_dev(aux_dev);
+	struct mei_device *dev;
+	struct mei_me_hw *hw;
+	struct device *device;
+	const struct mei_cfg *cfg;
+	int ret;
+
+	cfg = mei_me_get_cfg(aux_dev_id->driver_data);
+	if (!cfg)
+		return -ENODEV;
+
+	device = &aux_dev->dev;
+
+	dev = mei_me_dev_init(device, cfg);
+	if (IS_ERR(dev)) {
+		ret = PTR_ERR(dev);
+		goto err;
+	}
+
+	hw = to_me_hw(dev);
+	hw->mem_addr = devm_ioremap_resource(device, &adev->bar);
+	if (IS_ERR(hw->mem_addr)) {
+		dev_err(device, "mmio not mapped\n");
+		ret = PTR_ERR(hw->mem_addr);
+		goto err;
+	}
+
+	hw->irq = adev->irq;
+	hw->read_fws = mei_gsc_read_hfs;
+
+	dev_set_drvdata(&aux_dev->dev, dev);
+
+	ret = devm_request_threaded_irq(device, hw->irq,
+					mei_me_irq_quick_handler,
+					mei_me_irq_thread_handler,
+					IRQF_ONESHOT, KBUILD_MODNAME, dev);
+	if (ret) {
+		dev_err(device, "irq register failed %d\n", ret);
+		goto err;
+	}
+
+	pm_runtime_get_noresume(device);
+	pm_runtime_set_active(device);
+	pm_runtime_enable(device);
+
+	if (mei_start(dev)) {
+		dev_err(device, "init hw failure.\n");
+		ret = -ENODEV;
+		goto err;
+	}
+
+	pm_runtime_set_autosuspend_delay(device, MEI_GSC_RPM_TIMEOUT);
+	pm_runtime_use_autosuspend(device);
+
+	ret = mei_register(dev, device);
+	if (ret)
+		goto register_err;
+
+	pm_runtime_put_noidle(device);
+	return 0;
+
+register_err:
+	mei_stop(dev);
+
+err:
+	dev_err(device, "probe failed: %d\n", ret);
+	dev_set_drvdata(&aux_dev->dev, NULL);
+	return ret;
+}
+
+static void mei_gsc_remove(struct auxiliary_device *aux_dev)
+{
+	struct mei_device *dev;
+
+	dev = dev_get_drvdata(&aux_dev->dev);
+	if (!dev)
+		return;
+
+	mei_stop(dev);
+
+	mei_deregister(dev);
+
+	pm_runtime_disable(&aux_dev->dev);
+}
+
+static int __maybe_unused mei_gsc_pm_suspend(struct device *device)
+{
+	struct mei_device *dev = dev_get_drvdata(device);
+
+	if (!dev)
+		return -ENODEV;
+
+	mei_stop(dev);
+
+	mei_disable_interrupts(dev);
+
+	return 0;
+}
+
+static int __maybe_unused mei_gsc_pm_resume(struct device *device)
+{
+	struct mei_device *dev = dev_get_drvdata(device);
+	int err;
+
+	if (!dev)
+		return -ENODEV;
+
+	err = mei_restart(dev);
+	if (err)
+		return err;
+
+	/* Start timer if stopped in suspend */
+	schedule_delayed_work(&dev->timer_work, HZ);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(mei_gsc_pm_ops, mei_gsc_pm_suspend, mei_gsc_pm_resume);
+
+static const struct auxiliary_device_id mei_gsc_id_table[] = {
+	{
+		.name = "i915.mei-gsc",
+		.driver_data = MEI_ME_GSC_CFG,
+
+	},
+	{
+		.name = "i915.mei-gscfi",
+		.driver_data = MEI_ME_GSCFI_CFG,
+	},
+	{
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(auxiliary, mei_gsc_id_table);
+
+static struct auxiliary_driver mei_gsc_driver = {
+	.probe	= mei_gsc_probe,
+	.remove = mei_gsc_remove,
+	.driver = {
+		/* auxiliary_driver_register() sets .name to be the modname */
+		.pm = &mei_gsc_pm_ops,
+	},
+	.id_table = mei_gsc_id_table
+};
+module_auxiliary_driver(mei_gsc_driver);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_ALIAS("auxiliary:i915.mei-gsc");
+MODULE_ALIAS("auxiliary:i915.mei-gscfi");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index d3a6c0728645..9748d14849a1 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -1226,6 +1226,7 @@ irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id)
 	me_intr_disable(dev, hcsr);
 	return IRQ_WAKE_THREAD;
 }
+EXPORT_SYMBOL_GPL(mei_me_irq_quick_handler);
 
 /**
  * mei_me_irq_thread_handler - function called after ISR to handle the interrupt
@@ -1320,6 +1321,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
 	mutex_unlock(&dev->device_lock);
 	return IRQ_HANDLED;
 }
+EXPORT_SYMBOL_GPL(mei_me_irq_thread_handler);
 
 static const struct mei_hw_ops mei_me_hw_ops = {
 
@@ -1433,6 +1435,12 @@ static bool mei_me_fw_type_sps(const struct pci_dev *pdev)
 #define MEI_CFG_KIND_ITOUCH                     \
 	.kind = "itouch"
 
+#define MEI_CFG_TYPE_GSC                        \
+	.kind = "gsc"
+
+#define MEI_CFG_TYPE_GSCFI                      \
+	.kind = "gscfi"
+
 #define MEI_CFG_FW_SPS                          \
 	.quirk_probe = mei_me_fw_type_sps
 
@@ -1565,6 +1573,18 @@ static const struct mei_cfg mei_me_pch15_sps_cfg = {
 	MEI_CFG_FW_SPS,
 };
 
+/* Graphics System Controller */
+static const struct mei_cfg mei_me_gsc_cfg = {
+	MEI_CFG_TYPE_GSC,
+	MEI_CFG_PCH8_HFS,
+};
+
+/* Graphics System Controller Firmware Interface */
+static const struct mei_cfg mei_me_gscfi_cfg = {
+	MEI_CFG_TYPE_GSCFI,
+	MEI_CFG_PCH8_HFS,
+};
+
 /*
  * mei_cfg_list - A list of platform platform specific configurations.
  * Note: has to be synchronized with  enum mei_cfg_idx.
@@ -1585,6 +1605,8 @@ static const struct mei_cfg *const mei_cfg_list[] = {
 	[MEI_ME_PCH12_SPS_ITOUCH_CFG] = &mei_me_pch12_itouch_sps_cfg,
 	[MEI_ME_PCH15_CFG] = &mei_me_pch15_cfg,
 	[MEI_ME_PCH15_SPS_CFG] = &mei_me_pch15_sps_cfg,
+	[MEI_ME_GSC_CFG] = &mei_me_gsc_cfg,
+	[MEI_ME_GSCFI_CFG] = &mei_me_gscfi_cfg,
 };
 
 const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx)
@@ -1595,7 +1617,8 @@ const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx)
 		return NULL;
 
 	return mei_cfg_list[idx];
-};
+}
+EXPORT_SYMBOL_GPL(mei_me_get_cfg);
 
 /**
  * mei_me_dev_init - allocates and initializes the mei device structure
@@ -1630,4 +1653,4 @@ struct mei_device *mei_me_dev_init(struct device *parent,
 
 	return dev;
 }
-
+EXPORT_SYMBOL_GPL(mei_me_dev_init);
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
index 00a7132ac7a2..a071c645e905 100644
--- a/drivers/misc/mei/hw-me.h
+++ b/drivers/misc/mei/hw-me.h
@@ -112,6 +112,8 @@ enum mei_cfg_idx {
 	MEI_ME_PCH12_SPS_ITOUCH_CFG,
 	MEI_ME_PCH15_CFG,
 	MEI_ME_PCH15_SPS_CFG,
+	MEI_ME_GSC_CFG,
+	MEI_ME_GSCFI_CFG,
 	MEI_ME_NUM_CFG,
 };
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Intel-gfx] [PATCH v10 2/5] mei: add support for graphics system controller (gsc) devices
@ 2022-03-08 16:36   ` Alexander Usyskin
  0 siblings, 0 replies; 33+ messages in thread
From: Alexander Usyskin @ 2022-03-08 16:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Tvrtko Ursulin
  Cc: linux-kernel, Tomas Winkler, Alexander Usyskin, Vitaly Lubart, intel-gfx

From: Tomas Winkler <tomas.winkler@intel.com>

GSC is a graphics system controller, based on CSE, it provides
a chassis controller for graphics discrete cards, as well as it
supports media protection on selected devices.

mei_gsc binds to a auxiliary devices exposed by Intel discrete
driver i915.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/Kconfig  |  14 +++
 drivers/misc/mei/Makefile |   3 +
 drivers/misc/mei/gsc-me.c | 186 ++++++++++++++++++++++++++++++++++++++
 drivers/misc/mei/hw-me.c  |  27 +++++-
 drivers/misc/mei/hw-me.h  |   2 +
 5 files changed, 230 insertions(+), 2 deletions(-)
 create mode 100644 drivers/misc/mei/gsc-me.c

diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index 0e0bcd0da852..d21486d69df2 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -46,6 +46,20 @@ config INTEL_MEI_TXE
 	  Supported SoCs:
 	  Intel Bay Trail
 
+config INTEL_MEI_GSC
+	tristate "Intel MEI GSC embedded device"
+	depends on INTEL_MEI
+	depends on INTEL_MEI_ME
+	depends on X86 && PCI
+	depends on DRM_I915
+	help
+	  Intel auxiliary driver for GSC devices embedded in Intel graphics devices.
+
+	  An MEI device here called GSC can be embedded in an
+	  Intel graphics devices, to support a range of chassis
+	  tasks such as graphics card firmware update and security
+	  tasks.
+
 source "drivers/misc/mei/hdcp/Kconfig"
 source "drivers/misc/mei/pxp/Kconfig"
 
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index d8e5165917f2..fb740d754900 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -18,6 +18,9 @@ obj-$(CONFIG_INTEL_MEI_ME) += mei-me.o
 mei-me-objs := pci-me.o
 mei-me-objs += hw-me.o
 
+obj-$(CONFIG_INTEL_MEI_GSC) += mei-gsc.o
+mei-gsc-objs := gsc-me.o
+
 obj-$(CONFIG_INTEL_MEI_TXE) += mei-txe.o
 mei-txe-objs := pci-txe.o
 mei-txe-objs += hw-txe.o
diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
new file mode 100644
index 000000000000..0afae70e0609
--- /dev/null
+++ b/drivers/misc/mei/gsc-me.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ */
+
+#include <linux/module.h>
+#include <linux/mei_aux.h>
+#include <linux/device.h>
+#include <linux/irqreturn.h>
+#include <linux/jiffies.h>
+#include <linux/ktime.h>
+#include <linux/delay.h>
+#include <linux/pm_runtime.h>
+
+#include "mei_dev.h"
+#include "hw-me.h"
+#include "hw-me-regs.h"
+
+#include "mei-trace.h"
+
+#define MEI_GSC_RPM_TIMEOUT 500
+
+static int mei_gsc_read_hfs(const struct mei_device *dev, int where, u32 *val)
+{
+	struct mei_me_hw *hw = to_me_hw(dev);
+
+	*val = ioread32(hw->mem_addr + where + 0xC00);
+
+	return 0;
+}
+
+static int mei_gsc_probe(struct auxiliary_device *aux_dev,
+			 const struct auxiliary_device_id *aux_dev_id)
+{
+	struct mei_aux_device *adev = auxiliary_dev_to_mei_aux_dev(aux_dev);
+	struct mei_device *dev;
+	struct mei_me_hw *hw;
+	struct device *device;
+	const struct mei_cfg *cfg;
+	int ret;
+
+	cfg = mei_me_get_cfg(aux_dev_id->driver_data);
+	if (!cfg)
+		return -ENODEV;
+
+	device = &aux_dev->dev;
+
+	dev = mei_me_dev_init(device, cfg);
+	if (IS_ERR(dev)) {
+		ret = PTR_ERR(dev);
+		goto err;
+	}
+
+	hw = to_me_hw(dev);
+	hw->mem_addr = devm_ioremap_resource(device, &adev->bar);
+	if (IS_ERR(hw->mem_addr)) {
+		dev_err(device, "mmio not mapped\n");
+		ret = PTR_ERR(hw->mem_addr);
+		goto err;
+	}
+
+	hw->irq = adev->irq;
+	hw->read_fws = mei_gsc_read_hfs;
+
+	dev_set_drvdata(&aux_dev->dev, dev);
+
+	ret = devm_request_threaded_irq(device, hw->irq,
+					mei_me_irq_quick_handler,
+					mei_me_irq_thread_handler,
+					IRQF_ONESHOT, KBUILD_MODNAME, dev);
+	if (ret) {
+		dev_err(device, "irq register failed %d\n", ret);
+		goto err;
+	}
+
+	pm_runtime_get_noresume(device);
+	pm_runtime_set_active(device);
+	pm_runtime_enable(device);
+
+	if (mei_start(dev)) {
+		dev_err(device, "init hw failure.\n");
+		ret = -ENODEV;
+		goto err;
+	}
+
+	pm_runtime_set_autosuspend_delay(device, MEI_GSC_RPM_TIMEOUT);
+	pm_runtime_use_autosuspend(device);
+
+	ret = mei_register(dev, device);
+	if (ret)
+		goto register_err;
+
+	pm_runtime_put_noidle(device);
+	return 0;
+
+register_err:
+	mei_stop(dev);
+
+err:
+	dev_err(device, "probe failed: %d\n", ret);
+	dev_set_drvdata(&aux_dev->dev, NULL);
+	return ret;
+}
+
+static void mei_gsc_remove(struct auxiliary_device *aux_dev)
+{
+	struct mei_device *dev;
+
+	dev = dev_get_drvdata(&aux_dev->dev);
+	if (!dev)
+		return;
+
+	mei_stop(dev);
+
+	mei_deregister(dev);
+
+	pm_runtime_disable(&aux_dev->dev);
+}
+
+static int __maybe_unused mei_gsc_pm_suspend(struct device *device)
+{
+	struct mei_device *dev = dev_get_drvdata(device);
+
+	if (!dev)
+		return -ENODEV;
+
+	mei_stop(dev);
+
+	mei_disable_interrupts(dev);
+
+	return 0;
+}
+
+static int __maybe_unused mei_gsc_pm_resume(struct device *device)
+{
+	struct mei_device *dev = dev_get_drvdata(device);
+	int err;
+
+	if (!dev)
+		return -ENODEV;
+
+	err = mei_restart(dev);
+	if (err)
+		return err;
+
+	/* Start timer if stopped in suspend */
+	schedule_delayed_work(&dev->timer_work, HZ);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(mei_gsc_pm_ops, mei_gsc_pm_suspend, mei_gsc_pm_resume);
+
+static const struct auxiliary_device_id mei_gsc_id_table[] = {
+	{
+		.name = "i915.mei-gsc",
+		.driver_data = MEI_ME_GSC_CFG,
+
+	},
+	{
+		.name = "i915.mei-gscfi",
+		.driver_data = MEI_ME_GSCFI_CFG,
+	},
+	{
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(auxiliary, mei_gsc_id_table);
+
+static struct auxiliary_driver mei_gsc_driver = {
+	.probe	= mei_gsc_probe,
+	.remove = mei_gsc_remove,
+	.driver = {
+		/* auxiliary_driver_register() sets .name to be the modname */
+		.pm = &mei_gsc_pm_ops,
+	},
+	.id_table = mei_gsc_id_table
+};
+module_auxiliary_driver(mei_gsc_driver);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_ALIAS("auxiliary:i915.mei-gsc");
+MODULE_ALIAS("auxiliary:i915.mei-gscfi");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index d3a6c0728645..9748d14849a1 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -1226,6 +1226,7 @@ irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id)
 	me_intr_disable(dev, hcsr);
 	return IRQ_WAKE_THREAD;
 }
+EXPORT_SYMBOL_GPL(mei_me_irq_quick_handler);
 
 /**
  * mei_me_irq_thread_handler - function called after ISR to handle the interrupt
@@ -1320,6 +1321,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
 	mutex_unlock(&dev->device_lock);
 	return IRQ_HANDLED;
 }
+EXPORT_SYMBOL_GPL(mei_me_irq_thread_handler);
 
 static const struct mei_hw_ops mei_me_hw_ops = {
 
@@ -1433,6 +1435,12 @@ static bool mei_me_fw_type_sps(const struct pci_dev *pdev)
 #define MEI_CFG_KIND_ITOUCH                     \
 	.kind = "itouch"
 
+#define MEI_CFG_TYPE_GSC                        \
+	.kind = "gsc"
+
+#define MEI_CFG_TYPE_GSCFI                      \
+	.kind = "gscfi"
+
 #define MEI_CFG_FW_SPS                          \
 	.quirk_probe = mei_me_fw_type_sps
 
@@ -1565,6 +1573,18 @@ static const struct mei_cfg mei_me_pch15_sps_cfg = {
 	MEI_CFG_FW_SPS,
 };
 
+/* Graphics System Controller */
+static const struct mei_cfg mei_me_gsc_cfg = {
+	MEI_CFG_TYPE_GSC,
+	MEI_CFG_PCH8_HFS,
+};
+
+/* Graphics System Controller Firmware Interface */
+static const struct mei_cfg mei_me_gscfi_cfg = {
+	MEI_CFG_TYPE_GSCFI,
+	MEI_CFG_PCH8_HFS,
+};
+
 /*
  * mei_cfg_list - A list of platform platform specific configurations.
  * Note: has to be synchronized with  enum mei_cfg_idx.
@@ -1585,6 +1605,8 @@ static const struct mei_cfg *const mei_cfg_list[] = {
 	[MEI_ME_PCH12_SPS_ITOUCH_CFG] = &mei_me_pch12_itouch_sps_cfg,
 	[MEI_ME_PCH15_CFG] = &mei_me_pch15_cfg,
 	[MEI_ME_PCH15_SPS_CFG] = &mei_me_pch15_sps_cfg,
+	[MEI_ME_GSC_CFG] = &mei_me_gsc_cfg,
+	[MEI_ME_GSCFI_CFG] = &mei_me_gscfi_cfg,
 };
 
 const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx)
@@ -1595,7 +1617,8 @@ const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx)
 		return NULL;
 
 	return mei_cfg_list[idx];
-};
+}
+EXPORT_SYMBOL_GPL(mei_me_get_cfg);
 
 /**
  * mei_me_dev_init - allocates and initializes the mei device structure
@@ -1630,4 +1653,4 @@ struct mei_device *mei_me_dev_init(struct device *parent,
 
 	return dev;
 }
-
+EXPORT_SYMBOL_GPL(mei_me_dev_init);
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
index 00a7132ac7a2..a071c645e905 100644
--- a/drivers/misc/mei/hw-me.h
+++ b/drivers/misc/mei/hw-me.h
@@ -112,6 +112,8 @@ enum mei_cfg_idx {
 	MEI_ME_PCH12_SPS_ITOUCH_CFG,
 	MEI_ME_PCH15_CFG,
 	MEI_ME_PCH15_SPS_CFG,
+	MEI_ME_GSC_CFG,
+	MEI_ME_GSCFI_CFG,
 	MEI_ME_NUM_CFG,
 };
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v10 3/5] mei: gsc: setup char driver alive in spite of firmware handshake failure
  2022-03-08 16:36 ` [Intel-gfx] " Alexander Usyskin
@ 2022-03-08 16:36   ` Alexander Usyskin
  -1 siblings, 0 replies; 33+ messages in thread
From: Alexander Usyskin @ 2022-03-08 16:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Tvrtko Ursulin
  Cc: Tomas Winkler, Alexander Usyskin, Vitaly Lubart, intel-gfx, linux-kernel

Setup char device in spite of firmware handshake failure.
In order to provide host access to the firmware status registers and other
information required for the manufacturing process.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/gsc-me.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
index 0afae70e0609..cf427f6fdec9 100644
--- a/drivers/misc/mei/gsc-me.c
+++ b/drivers/misc/mei/gsc-me.c
@@ -79,11 +79,12 @@ static int mei_gsc_probe(struct auxiliary_device *aux_dev,
 	pm_runtime_set_active(device);
 	pm_runtime_enable(device);
 
-	if (mei_start(dev)) {
-		dev_err(device, "init hw failure.\n");
-		ret = -ENODEV;
-		goto err;
-	}
+	/* Continue to char device setup in spite of firmware handshake failure.
+	 * In order to provide access to the firmware status registers to the user
+	 * space via sysfs.
+	 */
+	if (mei_start(dev))
+		dev_warn(device, "init hw failure.\n");
 
 	pm_runtime_set_autosuspend_delay(device, MEI_GSC_RPM_TIMEOUT);
 	pm_runtime_use_autosuspend(device);
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Intel-gfx] [PATCH v10 3/5] mei: gsc: setup char driver alive in spite of firmware handshake failure
@ 2022-03-08 16:36   ` Alexander Usyskin
  0 siblings, 0 replies; 33+ messages in thread
From: Alexander Usyskin @ 2022-03-08 16:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Tvrtko Ursulin
  Cc: linux-kernel, Tomas Winkler, Alexander Usyskin, Vitaly Lubart, intel-gfx

Setup char device in spite of firmware handshake failure.
In order to provide host access to the firmware status registers and other
information required for the manufacturing process.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/gsc-me.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
index 0afae70e0609..cf427f6fdec9 100644
--- a/drivers/misc/mei/gsc-me.c
+++ b/drivers/misc/mei/gsc-me.c
@@ -79,11 +79,12 @@ static int mei_gsc_probe(struct auxiliary_device *aux_dev,
 	pm_runtime_set_active(device);
 	pm_runtime_enable(device);
 
-	if (mei_start(dev)) {
-		dev_err(device, "init hw failure.\n");
-		ret = -ENODEV;
-		goto err;
-	}
+	/* Continue to char device setup in spite of firmware handshake failure.
+	 * In order to provide access to the firmware status registers to the user
+	 * space via sysfs.
+	 */
+	if (mei_start(dev))
+		dev_warn(device, "init hw failure.\n");
 
 	pm_runtime_set_autosuspend_delay(device, MEI_GSC_RPM_TIMEOUT);
 	pm_runtime_use_autosuspend(device);
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v10 4/5] mei: gsc: add runtime pm handlers
  2022-03-08 16:36 ` [Intel-gfx] " Alexander Usyskin
@ 2022-03-08 16:36   ` Alexander Usyskin
  -1 siblings, 0 replies; 33+ messages in thread
From: Alexander Usyskin @ 2022-03-08 16:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Tvrtko Ursulin
  Cc: Tomas Winkler, Alexander Usyskin, Vitaly Lubart, intel-gfx, linux-kernel

From: Tomas Winkler <tomas.winkler@intel.com>

Implement runtime handlers for mei-gsc, to track
idle state of the device properly.

CC: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/gsc-me.c | 67 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
index cf427f6fdec9..dac482ddab51 100644
--- a/drivers/misc/mei/gsc-me.c
+++ b/drivers/misc/mei/gsc-me.c
@@ -152,7 +152,72 @@ static int __maybe_unused mei_gsc_pm_resume(struct device *device)
 	return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(mei_gsc_pm_ops, mei_gsc_pm_suspend, mei_gsc_pm_resume);
+static int __maybe_unused mei_gsc_pm_runtime_idle(struct device *device)
+{
+	struct mei_device *dev = dev_get_drvdata(device);
+
+	if (!dev)
+		return -ENODEV;
+	if (mei_write_is_idle(dev))
+		pm_runtime_autosuspend(device);
+
+	return -EBUSY;
+}
+
+static int  __maybe_unused mei_gsc_pm_runtime_suspend(struct device *device)
+{
+	struct mei_device *dev = dev_get_drvdata(device);
+	struct mei_me_hw *hw;
+	int ret;
+
+	if (!dev)
+		return -ENODEV;
+
+	mutex_lock(&dev->device_lock);
+
+	if (mei_write_is_idle(dev)) {
+		hw = to_me_hw(dev);
+		hw->pg_state = MEI_PG_ON;
+		ret = 0;
+	} else {
+		ret = -EAGAIN;
+	}
+
+	mutex_unlock(&dev->device_lock);
+
+	return ret;
+}
+
+static int __maybe_unused mei_gsc_pm_runtime_resume(struct device *device)
+{
+	struct mei_device *dev = dev_get_drvdata(device);
+	struct mei_me_hw *hw;
+	irqreturn_t irq_ret;
+
+	if (!dev)
+		return -ENODEV;
+
+	mutex_lock(&dev->device_lock);
+
+	hw = to_me_hw(dev);
+	hw->pg_state = MEI_PG_OFF;
+
+	mutex_unlock(&dev->device_lock);
+
+	irq_ret = mei_me_irq_thread_handler(1, dev);
+	if (irq_ret != IRQ_HANDLED)
+		dev_err(dev->dev, "thread handler fail %d\n", irq_ret);
+
+	return 0;
+}
+
+static const struct dev_pm_ops mei_gsc_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mei_gsc_pm_suspend,
+				mei_gsc_pm_resume)
+	SET_RUNTIME_PM_OPS(mei_gsc_pm_runtime_suspend,
+			   mei_gsc_pm_runtime_resume,
+			   mei_gsc_pm_runtime_idle)
+};
 
 static const struct auxiliary_device_id mei_gsc_id_table[] = {
 	{
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Intel-gfx] [PATCH v10 4/5] mei: gsc: add runtime pm handlers
@ 2022-03-08 16:36   ` Alexander Usyskin
  0 siblings, 0 replies; 33+ messages in thread
From: Alexander Usyskin @ 2022-03-08 16:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Tvrtko Ursulin
  Cc: linux-kernel, Tomas Winkler, Alexander Usyskin, Vitaly Lubart, intel-gfx

From: Tomas Winkler <tomas.winkler@intel.com>

Implement runtime handlers for mei-gsc, to track
idle state of the device properly.

CC: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/gsc-me.c | 67 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
index cf427f6fdec9..dac482ddab51 100644
--- a/drivers/misc/mei/gsc-me.c
+++ b/drivers/misc/mei/gsc-me.c
@@ -152,7 +152,72 @@ static int __maybe_unused mei_gsc_pm_resume(struct device *device)
 	return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(mei_gsc_pm_ops, mei_gsc_pm_suspend, mei_gsc_pm_resume);
+static int __maybe_unused mei_gsc_pm_runtime_idle(struct device *device)
+{
+	struct mei_device *dev = dev_get_drvdata(device);
+
+	if (!dev)
+		return -ENODEV;
+	if (mei_write_is_idle(dev))
+		pm_runtime_autosuspend(device);
+
+	return -EBUSY;
+}
+
+static int  __maybe_unused mei_gsc_pm_runtime_suspend(struct device *device)
+{
+	struct mei_device *dev = dev_get_drvdata(device);
+	struct mei_me_hw *hw;
+	int ret;
+
+	if (!dev)
+		return -ENODEV;
+
+	mutex_lock(&dev->device_lock);
+
+	if (mei_write_is_idle(dev)) {
+		hw = to_me_hw(dev);
+		hw->pg_state = MEI_PG_ON;
+		ret = 0;
+	} else {
+		ret = -EAGAIN;
+	}
+
+	mutex_unlock(&dev->device_lock);
+
+	return ret;
+}
+
+static int __maybe_unused mei_gsc_pm_runtime_resume(struct device *device)
+{
+	struct mei_device *dev = dev_get_drvdata(device);
+	struct mei_me_hw *hw;
+	irqreturn_t irq_ret;
+
+	if (!dev)
+		return -ENODEV;
+
+	mutex_lock(&dev->device_lock);
+
+	hw = to_me_hw(dev);
+	hw->pg_state = MEI_PG_OFF;
+
+	mutex_unlock(&dev->device_lock);
+
+	irq_ret = mei_me_irq_thread_handler(1, dev);
+	if (irq_ret != IRQ_HANDLED)
+		dev_err(dev->dev, "thread handler fail %d\n", irq_ret);
+
+	return 0;
+}
+
+static const struct dev_pm_ops mei_gsc_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mei_gsc_pm_suspend,
+				mei_gsc_pm_resume)
+	SET_RUNTIME_PM_OPS(mei_gsc_pm_runtime_suspend,
+			   mei_gsc_pm_runtime_resume,
+			   mei_gsc_pm_runtime_idle)
+};
 
 static const struct auxiliary_device_id mei_gsc_id_table[] = {
 	{
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v10 5/5] mei: gsc: retrieve the firmware version
  2022-03-08 16:36 ` [Intel-gfx] " Alexander Usyskin
@ 2022-03-08 16:36   ` Alexander Usyskin
  -1 siblings, 0 replies; 33+ messages in thread
From: Alexander Usyskin @ 2022-03-08 16:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Tvrtko Ursulin
  Cc: Tomas Winkler, Alexander Usyskin, Vitaly Lubart, intel-gfx,
	linux-kernel, Ashutosh Dixit

Add a hook to retrieve the firmware version of the
GSC devices to bus-fixup.
GSC has a different MKHI clients GUIDs but the same message structure
to retrieve the firmware version as MEI so mei_fwver() can be reused.

CC: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/bus-fixup.c | 25 +++++++++++++++++++++++++
 drivers/misc/mei/hw-me.c     |  2 ++
 2 files changed, 27 insertions(+)

diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c
index 67844089db21..59506ba6fc48 100644
--- a/drivers/misc/mei/bus-fixup.c
+++ b/drivers/misc/mei/bus-fixup.c
@@ -30,6 +30,12 @@ static const uuid_le mei_nfc_info_guid = MEI_UUID_NFC_INFO;
 #define MEI_UUID_MKHIF_FIX UUID_LE(0x55213584, 0x9a29, 0x4916, \
 			0xba, 0xdf, 0xf, 0xb7, 0xed, 0x68, 0x2a, 0xeb)
 
+#define MEI_UUID_IGSC_MKHI UUID_LE(0xE2C2AFA2, 0x3817, 0x4D19, \
+			0x9D, 0x95, 0x06, 0xB1, 0x6B, 0x58, 0x8A, 0x5D)
+
+#define MEI_UUID_IGSC_MKHI_FIX UUID_LE(0x46E0C1FB, 0xA546, 0x414F, \
+			0x91, 0x70, 0xB7, 0xF4, 0x6D, 0x57, 0xB4, 0xAD)
+
 #define MEI_UUID_HDCP UUID_LE(0xB638AB7E, 0x94E2, 0x4EA2, \
 			      0xA5, 0x52, 0xD1, 0xC5, 0x4B, 0x62, 0x7F, 0x04)
 
@@ -241,6 +247,23 @@ static void mei_mkhi_fix(struct mei_cl_device *cldev)
 	mei_cldev_disable(cldev);
 }
 
+static void mei_gsc_mkhi_ver(struct mei_cl_device *cldev)
+{
+	int ret;
+
+	/* No need to enable the client if nothing is needed from it */
+	if (!cldev->bus->fw_f_fw_ver_supported)
+		return;
+
+	ret = mei_cldev_enable(cldev);
+	if (ret)
+		return;
+
+	ret = mei_fwver(cldev);
+	if (ret < 0)
+		dev_err(&cldev->dev, "FW version command failed %d\n", ret);
+	mei_cldev_disable(cldev);
+}
 /**
  * mei_wd - wd client on the bus, change protocol version
  *   as the API has changed.
@@ -492,6 +515,8 @@ static struct mei_fixup {
 	MEI_FIXUP(MEI_UUID_NFC_HCI, mei_nfc),
 	MEI_FIXUP(MEI_UUID_WD, mei_wd),
 	MEI_FIXUP(MEI_UUID_MKHIF_FIX, mei_mkhi_fix),
+	MEI_FIXUP(MEI_UUID_IGSC_MKHI, mei_gsc_mkhi_ver),
+	MEI_FIXUP(MEI_UUID_IGSC_MKHI_FIX, mei_gsc_mkhi_ver),
 	MEI_FIXUP(MEI_UUID_HDCP, whitelist),
 	MEI_FIXUP(MEI_UUID_ANY, vt_support),
 	MEI_FIXUP(MEI_UUID_PAVP, whitelist),
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 9748d14849a1..7e77328142ff 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -1577,12 +1577,14 @@ static const struct mei_cfg mei_me_pch15_sps_cfg = {
 static const struct mei_cfg mei_me_gsc_cfg = {
 	MEI_CFG_TYPE_GSC,
 	MEI_CFG_PCH8_HFS,
+	MEI_CFG_FW_VER_SUPP,
 };
 
 /* Graphics System Controller Firmware Interface */
 static const struct mei_cfg mei_me_gscfi_cfg = {
 	MEI_CFG_TYPE_GSCFI,
 	MEI_CFG_PCH8_HFS,
+	MEI_CFG_FW_VER_SUPP,
 };
 
 /*
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Intel-gfx] [PATCH v10 5/5] mei: gsc: retrieve the firmware version
@ 2022-03-08 16:36   ` Alexander Usyskin
  0 siblings, 0 replies; 33+ messages in thread
From: Alexander Usyskin @ 2022-03-08 16:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	David Airlie, Daniel Vetter, Tvrtko Ursulin
  Cc: intel-gfx, Alexander Usyskin, linux-kernel, Tomas Winkler, Vitaly Lubart

Add a hook to retrieve the firmware version of the
GSC devices to bus-fixup.
GSC has a different MKHI clients GUIDs but the same message structure
to retrieve the firmware version as MEI so mei_fwver() can be reused.

CC: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/bus-fixup.c | 25 +++++++++++++++++++++++++
 drivers/misc/mei/hw-me.c     |  2 ++
 2 files changed, 27 insertions(+)

diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c
index 67844089db21..59506ba6fc48 100644
--- a/drivers/misc/mei/bus-fixup.c
+++ b/drivers/misc/mei/bus-fixup.c
@@ -30,6 +30,12 @@ static const uuid_le mei_nfc_info_guid = MEI_UUID_NFC_INFO;
 #define MEI_UUID_MKHIF_FIX UUID_LE(0x55213584, 0x9a29, 0x4916, \
 			0xba, 0xdf, 0xf, 0xb7, 0xed, 0x68, 0x2a, 0xeb)
 
+#define MEI_UUID_IGSC_MKHI UUID_LE(0xE2C2AFA2, 0x3817, 0x4D19, \
+			0x9D, 0x95, 0x06, 0xB1, 0x6B, 0x58, 0x8A, 0x5D)
+
+#define MEI_UUID_IGSC_MKHI_FIX UUID_LE(0x46E0C1FB, 0xA546, 0x414F, \
+			0x91, 0x70, 0xB7, 0xF4, 0x6D, 0x57, 0xB4, 0xAD)
+
 #define MEI_UUID_HDCP UUID_LE(0xB638AB7E, 0x94E2, 0x4EA2, \
 			      0xA5, 0x52, 0xD1, 0xC5, 0x4B, 0x62, 0x7F, 0x04)
 
@@ -241,6 +247,23 @@ static void mei_mkhi_fix(struct mei_cl_device *cldev)
 	mei_cldev_disable(cldev);
 }
 
+static void mei_gsc_mkhi_ver(struct mei_cl_device *cldev)
+{
+	int ret;
+
+	/* No need to enable the client if nothing is needed from it */
+	if (!cldev->bus->fw_f_fw_ver_supported)
+		return;
+
+	ret = mei_cldev_enable(cldev);
+	if (ret)
+		return;
+
+	ret = mei_fwver(cldev);
+	if (ret < 0)
+		dev_err(&cldev->dev, "FW version command failed %d\n", ret);
+	mei_cldev_disable(cldev);
+}
 /**
  * mei_wd - wd client on the bus, change protocol version
  *   as the API has changed.
@@ -492,6 +515,8 @@ static struct mei_fixup {
 	MEI_FIXUP(MEI_UUID_NFC_HCI, mei_nfc),
 	MEI_FIXUP(MEI_UUID_WD, mei_wd),
 	MEI_FIXUP(MEI_UUID_MKHIF_FIX, mei_mkhi_fix),
+	MEI_FIXUP(MEI_UUID_IGSC_MKHI, mei_gsc_mkhi_ver),
+	MEI_FIXUP(MEI_UUID_IGSC_MKHI_FIX, mei_gsc_mkhi_ver),
 	MEI_FIXUP(MEI_UUID_HDCP, whitelist),
 	MEI_FIXUP(MEI_UUID_ANY, vt_support),
 	MEI_FIXUP(MEI_UUID_PAVP, whitelist),
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 9748d14849a1..7e77328142ff 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -1577,12 +1577,14 @@ static const struct mei_cfg mei_me_pch15_sps_cfg = {
 static const struct mei_cfg mei_me_gsc_cfg = {
 	MEI_CFG_TYPE_GSC,
 	MEI_CFG_PCH8_HFS,
+	MEI_CFG_FW_VER_SUPP,
 };
 
 /* Graphics System Controller Firmware Interface */
 static const struct mei_cfg mei_me_gscfi_cfg = {
 	MEI_CFG_TYPE_GSCFI,
 	MEI_CFG_PCH8_HFS,
+	MEI_CFG_FW_VER_SUPP,
 };
 
 /*
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Add driver for GSC controller (rev10)
  2022-03-08 16:36 ` [Intel-gfx] " Alexander Usyskin
                   ` (5 preceding siblings ...)
  (?)
@ 2022-03-08 23:52 ` Patchwork
  -1 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2022-03-08 23:52 UTC (permalink / raw)
  To: Alexander Usyskin; +Cc: intel-gfx

== Series Details ==

Series: Add driver for GSC controller (rev10)
URL   : https://patchwork.freedesktop.org/series/98066/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
44fdb8f68777 drm/i915/gsc: add gsc as a mei auxiliary device
-:63: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#63: 
new file mode 100644

-:457: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'dev_priv' - possible side-effects?
#457: FILE: drivers/gpu/drm/i915/i915_drv.h:1336:
+#define HAS_HECI_GSC(dev_priv) (HAS_HECI_PXP(dev_priv) || HAS_HECI_GSCFI(dev_priv))

total: 0 errors, 1 warnings, 1 checks, 418 lines checked
0b4bf38bb00a mei: add support for graphics system controller (gsc) devices
-:56: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#56: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 289 lines checked
d9a701cdc237 mei: gsc: setup char driver alive in spite of firmware handshake failure
7ecb588c9d45 mei: gsc: add runtime pm handlers
7730f74cd2e4 mei: gsc: retrieve the firmware version



^ permalink raw reply	[flat|nested] 33+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for Add driver for GSC controller (rev10)
  2022-03-08 16:36 ` [Intel-gfx] " Alexander Usyskin
                   ` (6 preceding siblings ...)
  (?)
@ 2022-03-08 23:53 ` Patchwork
  -1 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2022-03-08 23:53 UTC (permalink / raw)
  To: Alexander Usyskin; +Cc: intel-gfx

== Series Details ==

Series: Add driver for GSC controller (rev10)
URL   : https://patchwork.freedesktop.org/series/98066/
State : warning

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.



^ permalink raw reply	[flat|nested] 33+ messages in thread

* [Intel-gfx] ✗ Fi.CI.BAT: failure for Add driver for GSC controller (rev10)
  2022-03-08 16:36 ` [Intel-gfx] " Alexander Usyskin
                   ` (7 preceding siblings ...)
  (?)
@ 2022-03-09  0:28 ` Patchwork
  -1 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2022-03-09  0:28 UTC (permalink / raw)
  To: Alexander Usyskin; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 12912 bytes --]

== Series Details ==

Series: Add driver for GSC controller (rev10)
URL   : https://patchwork.freedesktop.org/series/98066/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_11337 -> Patchwork_22514
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_22514 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_22514, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/index.html

Participating hosts (46 -> 44)
------------------------------

  Additional (3): fi-tgl-1115g4 fi-icl-u2 fi-pnv-d510 
  Missing    (5): shard-tglu fi-bsw-cyan fi-ctg-p8600 shard-rkl shard-dg1 

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_22514:

### IGT changes ###

#### Possible regressions ####

  * igt@i915_selftest@live@hangcheck:
    - fi-icl-u2:          NOTRUN -> [INCOMPLETE][1]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-icl-u2/igt@i915_selftest@live@hangcheck.html

  
#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * igt@kms_pipe_crc_basic@read-crc-pipe-a:
    - {bat-dg2-9}:        [PASS][2] -> [DMESG-WARN][3]
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11337/bat-dg2-9/igt@kms_pipe_crc_basic@read-crc-pipe-a.html
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/bat-dg2-9/igt@kms_pipe_crc_basic@read-crc-pipe-a.html

  
Known issues
------------

  Here are the changes found in Patchwork_22514 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_huc_copy@huc-copy:
    - fi-skl-6600u:       NOTRUN -> [SKIP][4] ([fdo#109271] / [i915#2190])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-skl-6600u/igt@gem_huc_copy@huc-copy.html
    - fi-pnv-d510:        NOTRUN -> [SKIP][5] ([fdo#109271]) +57 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-pnv-d510/igt@gem_huc_copy@huc-copy.html
    - fi-tgl-1115g4:      NOTRUN -> [SKIP][6] ([i915#2190])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-tgl-1115g4/igt@gem_huc_copy@huc-copy.html
    - fi-icl-u2:          NOTRUN -> [SKIP][7] ([i915#2190])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-icl-u2/igt@gem_huc_copy@huc-copy.html

  * igt@gem_lmem_swapping@basic:
    - fi-tgl-1115g4:      NOTRUN -> [SKIP][8] ([i915#4613]) +3 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-tgl-1115g4/igt@gem_lmem_swapping@basic.html

  * igt@gem_lmem_swapping@parallel-random-engines:
    - fi-icl-u2:          NOTRUN -> [SKIP][9] ([i915#4613]) +3 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-icl-u2/igt@gem_lmem_swapping@parallel-random-engines.html

  * igt@gem_lmem_swapping@verify-random:
    - fi-skl-6600u:       NOTRUN -> [SKIP][10] ([fdo#109271] / [i915#4613]) +3 similar issues
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-skl-6600u/igt@gem_lmem_swapping@verify-random.html

  * igt@i915_pm_backlight@basic-brightness:
    - fi-tgl-1115g4:      NOTRUN -> [SKIP][11] ([i915#1155])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-tgl-1115g4/igt@i915_pm_backlight@basic-brightness.html

  * igt@i915_pm_rpm@module-reload:
    - fi-tgl-1115g4:      NOTRUN -> [INCOMPLETE][12] ([i915#62])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-tgl-1115g4/igt@i915_pm_rpm@module-reload.html

  * igt@i915_selftest@live@gtt:
    - fi-bdw-5557u:       [PASS][13] -> [DMESG-FAIL][14] ([i915#3674])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11337/fi-bdw-5557u/igt@i915_selftest@live@gtt.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-bdw-5557u/igt@i915_selftest@live@gtt.html

  * igt@i915_selftest@live@hangcheck:
    - fi-ivb-3770:        [PASS][15] -> [INCOMPLETE][16] ([i915#3303])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11337/fi-ivb-3770/igt@i915_selftest@live@hangcheck.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-ivb-3770/igt@i915_selftest@live@hangcheck.html
    - bat-dg1-5:          [PASS][17] -> [DMESG-FAIL][18] ([i915#4494] / [i915#4957])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11337/bat-dg1-5/igt@i915_selftest@live@hangcheck.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/bat-dg1-5/igt@i915_selftest@live@hangcheck.html
    - fi-snb-2600:        [PASS][19] -> [INCOMPLETE][20] ([i915#3921])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11337/fi-snb-2600/igt@i915_selftest@live@hangcheck.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-snb-2600/igt@i915_selftest@live@hangcheck.html

  * igt@kms_chamelium@hdmi-hpd-fast:
    - fi-icl-u2:          NOTRUN -> [SKIP][21] ([fdo#111827]) +8 similar issues
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-icl-u2/igt@kms_chamelium@hdmi-hpd-fast.html

  * igt@kms_chamelium@vga-edid-read:
    - fi-skl-6600u:       NOTRUN -> [SKIP][22] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-skl-6600u/igt@kms_chamelium@vga-edid-read.html

  * igt@kms_chamelium@vga-hpd-fast:
    - fi-tgl-1115g4:      NOTRUN -> [SKIP][23] ([fdo#111827]) +8 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-tgl-1115g4/igt@kms_chamelium@vga-hpd-fast.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - fi-icl-u2:          NOTRUN -> [SKIP][24] ([fdo#109278]) +2 similar issues
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-icl-u2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
    - fi-tgl-1115g4:      NOTRUN -> [SKIP][25] ([i915#4103]) +1 similar issue
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-tgl-1115g4/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - fi-skl-6600u:       NOTRUN -> [SKIP][26] ([fdo#109271]) +21 similar issues
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-skl-6600u/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@kms_flip@basic-flip-vs-modeset@c-dp3:
    - fi-tgl-1115g4:      NOTRUN -> [DMESG-WARN][27] ([i915#4002]) +88 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-tgl-1115g4/igt@kms_flip@basic-flip-vs-modeset@c-dp3.html

  * igt@kms_force_connector_basic@force-load-detect:
    - fi-tgl-1115g4:      NOTRUN -> [SKIP][28] ([fdo#109285])
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-tgl-1115g4/igt@kms_force_connector_basic@force-load-detect.html
    - fi-icl-u2:          NOTRUN -> [SKIP][29] ([fdo#109285])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-icl-u2/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d:
    - fi-skl-6600u:       NOTRUN -> [SKIP][30] ([fdo#109271] / [i915#533])
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-skl-6600u/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d.html

  * igt@kms_pipe_crc_basic@read-crc-pipe-b:
    - fi-cfl-8109u:       [PASS][31] -> [DMESG-WARN][32] ([i915#295]) +11 similar issues
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11337/fi-cfl-8109u/igt@kms_pipe_crc_basic@read-crc-pipe-b.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-cfl-8109u/igt@kms_pipe_crc_basic@read-crc-pipe-b.html

  * igt@kms_psr@primary_mmap_gtt:
    - fi-tgl-1115g4:      NOTRUN -> [SKIP][33] ([fdo#110189]) +3 similar issues
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-tgl-1115g4/igt@kms_psr@primary_mmap_gtt.html

  * igt@prime_vgem@basic-userptr:
    - fi-icl-u2:          NOTRUN -> [SKIP][34] ([i915#3301])
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-icl-u2/igt@prime_vgem@basic-userptr.html
    - fi-tgl-1115g4:      NOTRUN -> [SKIP][35] ([i915#3301])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-tgl-1115g4/igt@prime_vgem@basic-userptr.html

  * igt@runner@aborted:
    - fi-icl-u2:          NOTRUN -> [FAIL][36] ([i915#2722] / [i915#4312])
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-icl-u2/igt@runner@aborted.html
    - fi-ivb-3770:        NOTRUN -> [FAIL][37] ([fdo#109271] / [i915#4312])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-ivb-3770/igt@runner@aborted.html
    - fi-tgl-1115g4:      NOTRUN -> [FAIL][38] ([i915#2722] / [i915#4312])
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-tgl-1115g4/igt@runner@aborted.html

  
#### Possible fixes ####

  * igt@gem_exec_suspend@basic-s3@smem:
    - fi-skl-6600u:       [INCOMPLETE][39] ([i915#4547]) -> [PASS][40]
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11337/fi-skl-6600u/igt@gem_exec_suspend@basic-s3@smem.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/fi-skl-6600u/igt@gem_exec_suspend@basic-s3@smem.html

  * igt@i915_selftest@live@requests:
    - {bat-rpls-2}:       [INCOMPLETE][41] -> [PASS][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11337/bat-rpls-2/igt@i915_selftest@live@requests.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/bat-rpls-2/igt@i915_selftest@live@requests.html

  * igt@kms_busy@basic@flip:
    - {bat-adlp-6}:       [DMESG-WARN][43] ([i915#3576]) -> [PASS][44]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11337/bat-adlp-6/igt@kms_busy@basic@flip.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/bat-adlp-6/igt@kms_busy@basic@flip.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
  [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
  [fdo#110189]: https://bugs.freedesktop.org/show_bug.cgi?id=110189
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1155]: https://gitlab.freedesktop.org/drm/intel/issues/1155
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#1759]: https://gitlab.freedesktop.org/drm/intel/issues/1759
  [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
  [i915#2722]: https://gitlab.freedesktop.org/drm/intel/issues/2722
  [i915#295]: https://gitlab.freedesktop.org/drm/intel/issues/295
  [i915#3301]: https://gitlab.freedesktop.org/drm/intel/issues/3301
  [i915#3303]: https://gitlab.freedesktop.org/drm/intel/issues/3303
  [i915#3576]: https://gitlab.freedesktop.org/drm/intel/issues/3576
  [i915#3674]: https://gitlab.freedesktop.org/drm/intel/issues/3674
  [i915#3921]: https://gitlab.freedesktop.org/drm/intel/issues/3921
  [i915#4002]: https://gitlab.freedesktop.org/drm/intel/issues/4002
  [i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#4494]: https://gitlab.freedesktop.org/drm/intel/issues/4494
  [i915#4547]: https://gitlab.freedesktop.org/drm/intel/issues/4547
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#4957]: https://gitlab.freedesktop.org/drm/intel/issues/4957
  [i915#4983]: https://gitlab.freedesktop.org/drm/intel/issues/4983
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533
  [i915#62]: https://gitlab.freedesktop.org/drm/intel/issues/62


Build changes
-------------

  * Linux: CI_DRM_11337 -> Patchwork_22514

  CI-20190529: 20190529
  CI_DRM_11337: 69f3f2cf125ccd5ad74d79202ba11aae6e21fb0f @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6368: 60e5ffca027b38398c279fba0f5a1b7517aa6061 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_22514: 7730f74cd2e4e47423d9600e85d3be77189143e2 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

7730f74cd2e4 mei: gsc: retrieve the firmware version
7ecb588c9d45 mei: gsc: add runtime pm handlers
d9a701cdc237 mei: gsc: setup char driver alive in spite of firmware handshake failure
0b4bf38bb00a mei: add support for graphics system controller (gsc) devices
44fdb8f68777 drm/i915/gsc: add gsc as a mei auxiliary device

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22514/index.html

[-- Attachment #2: Type: text/html, Size: 15297 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 1/5] drm/i915/gsc: add gsc as a mei auxiliary device
  2022-03-08 16:36   ` [Intel-gfx] " Alexander Usyskin
@ 2022-03-09 22:50     ` Ceraolo Spurio, Daniele
  -1 siblings, 0 replies; 33+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-03-09 22:50 UTC (permalink / raw)
  To: Alexander Usyskin, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: intel-gfx, linux-kernel, Tomas Winkler, Vitaly Lubart



On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> From: Tomas Winkler <tomas.winkler@intel.com>
>
> GSC is a graphics system controller, it provides
> a chassis controller for graphics discrete cards.
>
> There are two MEI interfaces in GSC: HECI1 and HECI2.
>
> Both interfaces are on the BAR0 at offsets 0x00258000 and 0x00259000.
> GSC is a GT Engine (class 4: instance 6). HECI1 interrupt is signaled
> via bit 15 and HECI2 via bit 14 in the interrupt register.
>
> This patch exports GSC as auxiliary device for mei driver to bind to
> for HECI2 interface.

Do we need a test for this? E.g. to catch the unlikely case where we 
stop exposing the GSC device. We are going to get some indirect coverage 
once we start making use of the PXP interface from within the kernel, 
would that be enough?

Also, IMO we need a line here to explain that we're adding the code for 
HECI1 as well because we plan to follow up with it soon.

>
> CC: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> Signed-off-by: Vitaly Lubart <vitaly.lubart@intel.com>
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> ---
>   MAINTAINERS                              |   1 +
>   drivers/gpu/drm/i915/Kconfig             |   1 +
>   drivers/gpu/drm/i915/Makefile            |   3 +
>   drivers/gpu/drm/i915/gt/intel_gsc.c      | 204 +++++++++++++++++++++++
>   drivers/gpu/drm/i915/gt/intel_gsc.h      |  37 ++++
>   drivers/gpu/drm/i915/gt/intel_gt.c       |   3 +
>   drivers/gpu/drm/i915/gt/intel_gt.h       |   5 +
>   drivers/gpu/drm/i915/gt/intel_gt_irq.c   |  13 ++
>   drivers/gpu/drm/i915/gt/intel_gt_regs.h  |   1 +
>   drivers/gpu/drm/i915/gt/intel_gt_types.h |   2 +
>   drivers/gpu/drm/i915/i915_drv.h          |   8 +
>   drivers/gpu/drm/i915/i915_pci.c          |   3 +-
>   drivers/gpu/drm/i915/i915_reg.h          |   2 +
>   drivers/gpu/drm/i915/intel_device_info.h |   2 +
>   include/linux/mei_aux.h                  |  19 +++
>   15 files changed, 303 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.c
>   create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.h
>   create mode 100644 include/linux/mei_aux.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 2b1d296f92e9..d322e630d1d1 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -9822,6 +9822,7 @@ S:	Supported
>   F:	Documentation/driver-api/mei/*
>   F:	drivers/misc/mei/
>   F:	drivers/watchdog/mei_wdt.c
> +F:	include/linux/mei_aux.h
>   F:	include/linux/mei_cl_bus.h
>   F:	include/uapi/linux/mei.h
>   F:	samples/mei/*
> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
> index 98c5450b8eac..2660a85175d9 100644
> --- a/drivers/gpu/drm/i915/Kconfig
> +++ b/drivers/gpu/drm/i915/Kconfig
> @@ -30,6 +30,7 @@ config DRM_I915
>   	select VMAP_PFN
>   	select DRM_TTM
>   	select DRM_BUDDY
> +	select AUXILIARY_BUS
>   	help
>   	  Choose this option if you have a system that has "Intel Graphics
>   	  Media Accelerator" or "HD Graphics" integrated graphics,
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 1a771ee5b1d0..9be7b13d8822 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -196,6 +196,9 @@ i915-y += gt/uc/intel_uc.o \
>   	  gt/uc/intel_huc_debugfs.o \
>   	  gt/uc/intel_huc_fw.o
>   
> +# graphics system controller (GSC) support
> +i915-y += gt/intel_gsc.o
> +
>   # modesetting core code
>   i915-y += \
>   	display/hsw_ips.o \
> diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.c b/drivers/gpu/drm/i915/gt/intel_gsc.c
> new file mode 100644
> index 000000000000..152804e7c41a
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/intel_gsc.c
> @@ -0,0 +1,204 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
> + */
> +
> +#include <linux/irq.h>
> +#include <linux/mei_aux.h>
> +#include "i915_reg.h"
> +#include "i915_drv.h"
> +#include "gt/intel_gt.h"
> +#include "intel_gsc.h"

A bit of inconsistency here because intel_gsc.h and intel_gt.h are both 
in the gt/ folder but you're only prefixing one with gt/. Also, we 
usually try to keep includes in alphabetical order, but overall not a 
blocker for me.

> +
> +#define GSC_BAR_LENGTH  0x00000FFC
> +
> +static void gsc_irq_mask(struct irq_data *d)
> +{
> +	/* generic irq handling */
> +}
> +
> +static void gsc_irq_unmask(struct irq_data *d)
> +{
> +	/* generic irq handling */
> +}
> +
> +static struct irq_chip gsc_irq_chip = {
> +	.name = "gsc_irq_chip",
> +	.irq_mask = gsc_irq_mask,
> +	.irq_unmask = gsc_irq_unmask,
> +};
> +
> +static int gsc_irq_init(int irq)
> +{
> +	irq_set_chip_and_handler_name(irq, &gsc_irq_chip,
> +				      handle_simple_irq, "gsc_irq_handler");
> +
> +	return irq_set_chip_data(irq, NULL);
> +}
> +
> +struct intel_gsc_def {
> +	const char *name;
> +	unsigned long bar;
> +	size_t bar_size;
> +};
> +
> +/* gscfi (graphics system controller firmware interface) resources */

Should this comment be moved down in the array? the array has sections 
for both pxp and gscfi resources, even if the former are not set. Or 
maybe expand to something like:

/* for DG1 we only need gscfi (....) resources */

> +static const struct intel_gsc_def intel_gsc_def_dg1[] = {
> +	{
> +		/* HECI1 not yet implemented. */
> +	},
> +	{
> +		.name = "mei-gscfi",
> +		.bar = GSC_DG1_HECI2_BASE,
> +		.bar_size = GSC_BAR_LENGTH,
> +	}
> +};
> +
> +static void intel_gsc_release_dev(struct device *dev)

We usually avoid the intel_* prefix for static functions. Same for other 
functions below.

> +{
> +	struct auxiliary_device *aux_dev = to_auxiliary_dev(dev);
> +	struct mei_aux_device *adev = auxiliary_dev_to_mei_aux_dev(aux_dev);
> +
> +	kfree(adev);
> +}
> +
> +static void intel_gsc_destroy_one(struct intel_gsc_intf *intf)
> +{
> +	if (intf->adev) {
> +		auxiliary_device_delete(&intf->adev->aux_dev);
> +		auxiliary_device_uninit(&intf->adev->aux_dev);
> +		intf->adev = NULL;
> +	}
> +	if (intf->irq >= 0)
> +		irq_free_desc(intf->irq);
> +	intf->irq = -1;
> +}
> +
> +static void intel_gsc_init_one(struct drm_i915_private *i915,
> +			       struct intel_gsc_intf *intf,
> +			       unsigned int intf_id)
> +{
> +	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
> +	struct mei_aux_device *adev;
> +	struct auxiliary_device *aux_dev;
> +	const struct intel_gsc_def *def;
> +	int ret;
> +
> +	intf->irq = -1;
> +	intf->id = intf_id;
> +
> +	if (intf_id == 0 && !HAS_HECI_PXP(i915))
> +		return;
> +
> +	def = &intel_gsc_def_dg1[intf_id];
> +
> +	if (!def->name) {
> +		drm_warn_once(&i915->drm, "HECI%d is not implemented!\n", intf_id + 1);
> +		return;
> +	}
> +
> +	intf->irq = irq_alloc_desc(0);
> +	if (intf->irq < 0) {
> +		drm_err(&i915->drm, "gsc irq error %d\n", intf->irq);
> +		return;
> +	}
> +
> +	ret = gsc_irq_init(intf->irq);
> +	if (ret < 0) {
> +		drm_err(&i915->drm, "gsc irq init failed %d\n", ret);
> +		goto fail;
> +	}
> +
> +	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
> +	if (!adev)
> +		goto fail;
> +
> +	adev->irq = intf->irq;
> +	adev->bar.parent = &pdev->resource[0];
> +	adev->bar.start = def->bar + pdev->resource[0].start;
> +	adev->bar.end = adev->bar.start + def->bar_size - 1;
> +	adev->bar.flags = IORESOURCE_MEM;
> +	adev->bar.desc = IORES_DESC_NONE;
> +
> +	aux_dev = &adev->aux_dev;
> +	aux_dev->name = def->name;
> +	aux_dev->id = (pci_domain_nr(pdev->bus) << 16) |
> +		      PCI_DEVID(pdev->bus->number, pdev->devfn);
> +	aux_dev->dev.parent = &pdev->dev;
> +	aux_dev->dev.release = intel_gsc_release_dev;
> +
> +	ret = auxiliary_device_init(aux_dev);
> +	if (ret < 0) {
> +		drm_err(&i915->drm, "gsc aux init failed %d\n", ret);
> +		kfree(adev);
> +		goto fail;
> +	}
> +
> +	ret = auxiliary_device_add(aux_dev);
> +	if (ret < 0) {
> +		drm_err(&i915->drm, "gsc aux add failed %d\n", ret);
> +		/* adev will be freed with the put_device() and .release sequence */
> +		auxiliary_device_uninit(aux_dev);
> +		goto fail;
> +	}
> +	intf->adev = adev;
> +
> +	return;
> +fail:
> +	intel_gsc_destroy_one(intf);
> +}
> +
> +static void gsc_irq_handler(struct intel_gt *gt, unsigned int intf_id)
> +{
> +	int ret;
> +
> +	if (intf_id >= INTEL_GSC_NUM_INTERFACES) {
> +		drm_warn_once(&gt->i915->drm, "GSC irq: intf_id %d is out of range", intf_id);
> +		return;
> +	}
> +
> +	if (!HAS_HECI_GSC(gt->i915)) {
> +		drm_warn_once(&gt->i915->drm, "GSC irq: not supported");
> +		return;
> +	}
> +
> +	if (gt->gsc.intf[intf_id].irq < 0) {
> +		drm_err_ratelimited(&gt->i915->drm, "GSC irq: irq not set");
> +		return;
> +	}
> +
> +	ret = generic_handle_irq(gt->gsc.intf[intf_id].irq);
> +	if (ret)
> +		drm_err_ratelimited(&gt->i915->drm, "error handling GSC irq: %d\n", ret);
> +}
> +
> +void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir)
> +{
> +	if (iir & GSC_IRQ_INTF(0))
> +		gsc_irq_handler(gt, 0);
> +	if (iir & GSC_IRQ_INTF(1))
> +		gsc_irq_handler(gt, 1);
> +}
> +
> +void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private *i915)
> +{
> +	unsigned int i;
> +
> +	if (!HAS_HECI_GSC(i915))
> +		return;
> +
> +	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
> +		intel_gsc_init_one(i915, &gsc->intf[i], i);
> +}
> +
> +void intel_gsc_fini(struct intel_gsc *gsc)
> +{
> +	struct intel_gt *gt = gsc_to_gt(gsc);
> +	unsigned int i;
> +
> +	if (!HAS_HECI_GSC(gt->i915))
> +		return;
> +
> +	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
> +		intel_gsc_destroy_one(&gsc->intf[i]);
> +}
> diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.h b/drivers/gpu/drm/i915/gt/intel_gsc.h
> new file mode 100644
> index 000000000000..68582f912b21
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/intel_gsc.h
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
> + */
> +#ifndef __INTEL_GSC_DEV_H__
> +#define __INTEL_GSC_DEV_H__
> +
> +#include <linux/types.h>
> +
> +struct drm_i915_private;
> +struct intel_gt;
> +struct mei_aux_device;
> +
> +#define INTEL_GSC_NUM_INTERFACES 2
> +/*
> + * The HECI1 bit corresponds to bit15 and HECI2 to bit14.
> + * The reason for this is to allow growth for more interfaces in the future.
> + */
> +#define GSC_IRQ_INTF(_x)  BIT(15 - (_x))
> +
> +/**
> + * struct intel_gsc - graphics security controller
> + * @intf : gsc interface
> + */
> +struct intel_gsc {
> +	struct intel_gsc_intf {
> +		struct mei_aux_device *adev;
> +		int irq;
> +		unsigned int id;
> +	} intf[INTEL_GSC_NUM_INTERFACES];
> +};
> +
> +void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private *dev_priv);
> +void intel_gsc_fini(struct intel_gsc *gsc);
> +void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir);
> +
> +#endif /* __INTEL_GSC_DEV_H__ */
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
> index 8a2483ccbfb9..fd83ab4b8849 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.c
> @@ -444,6 +444,8 @@ void intel_gt_chipset_flush(struct intel_gt *gt)
>   
>   void intel_gt_driver_register(struct intel_gt *gt)
>   {
> +	intel_gsc_init(&gt->gsc, gt->i915);
> +
>   	intel_rps_driver_register(&gt->rps);
>   
>   	intel_gt_debugfs_register(gt);
> @@ -766,6 +768,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
>   	intel_wakeref_t wakeref;
>   
>   	intel_rps_driver_unregister(&gt->rps);
> +	intel_gsc_fini(&gt->gsc);
>   
>   	intel_pxp_fini(&gt->pxp);
>   
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h
> index 0f571c8ee22b..de779a505c21 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.h
> @@ -34,6 +34,11 @@ static inline struct intel_gt *huc_to_gt(struct intel_huc *huc)
>   	return container_of(huc, struct intel_gt, uc.huc);
>   }
>   
> +static inline struct intel_gt *gsc_to_gt(struct intel_gsc *gsc)
> +{
> +	return container_of(gsc, struct intel_gt, gsc);
> +}
> +
>   void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915);
>   void __intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915);
>   int intel_gt_assign_ggtt(struct intel_gt *gt);
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> index e443ac4c8059..917b85d0c189 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> @@ -68,6 +68,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 instance,
>   	if (instance == OTHER_KCR_INSTANCE)
>   		return intel_pxp_irq_handler(&gt->pxp, iir);
>   
> +	if (instance == OTHER_GSC_INSTANCE)
> +		return intel_gsc_irq_handler(gt, iir);
> +
>   	WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
>   		  instance, iir);
>   }
> @@ -184,6 +187,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
>   	intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE,	  0);
>   	if (CCS_MASK(gt))
>   		intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, 0);
> +	if (HAS_HECI_GSC(gt->i915))
> +		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE, 0);
>   
>   	/* Restore masks irqs on RCS, BCS, VCS and VECS engines. */
>   	intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK,	~0);
> @@ -201,6 +206,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
>   		intel_uncore_write(uncore, GEN12_CCS0_CCS1_INTR_MASK, ~0);
>   	if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3))
>   		intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~0);
> +	if (HAS_HECI_GSC(gt->i915))
> +		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, ~0);
>   
>   	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0);
>   	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
> @@ -215,6 +222,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
>   {
>   	struct intel_uncore *uncore = gt->uncore;
>   	u32 irqs = GT_RENDER_USER_INTERRUPT;
> +	const u32 gsc_mask = GSC_IRQ_INTF(0) | GSC_IRQ_INTF(1);
>   	u32 dmask;
>   	u32 smask;
>   
> @@ -233,6 +241,9 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
>   	intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE, dmask);
>   	if (CCS_MASK(gt))
>   		intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, smask);
> +	if (HAS_HECI_GSC(gt->i915))
> +		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE,
> +				   gsc_mask);
>   
>   	/* Unmask irqs on RCS, BCS, VCS and VECS engines. */
>   	intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK, ~smask);
> @@ -250,6 +261,8 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
>   		intel_uncore_write(uncore, GEN12_CCS0_CCS1_INTR_MASK, ~dmask);
>   	if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3))
>   		intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~dmask);
> +	if (HAS_HECI_GSC(gt->i915))
> +		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, 0);

This should be ~gsc_mask, right?

>   
>   	/*
>   	 * RPS interrupts will get enabled/disabled on demand when RPS itself
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> index 19cd34f24263..a277fb480cc8 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> @@ -1483,6 +1483,7 @@
>   #define   OTHER_GUC_INSTANCE			0
>   #define   OTHER_GTPM_INSTANCE			1
>   #define   OTHER_KCR_INSTANCE			4
> +#define   OTHER_GSC_INSTANCE			6
>   
>   #define GEN11_IIR_REG_SELECTOR(x)		_MMIO(0x190070 + ((x) * 4))
>   
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> index f20687796490..5556d55f76ea 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> @@ -16,6 +16,7 @@
>   #include <linux/workqueue.h>
>   
>   #include "uc/intel_uc.h"
> +#include "intel_gsc.h"
>   
>   #include "i915_vma.h"
>   #include "intel_engine_types.h"
> @@ -72,6 +73,7 @@ struct intel_gt {
>   	struct i915_ggtt *ggtt;
>   
>   	struct intel_uc uc;
> +	struct intel_gsc gsc;
>   
>   	struct mutex tlb_invalidate_lock;
>   
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 943267393ecb..1c000c15493d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1327,6 +1327,14 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
>   
>   #define HAS_DMC(dev_priv)	(INTEL_INFO(dev_priv)->display.has_dmc)
>   
> +#define HAS_HECI_PXP(dev_priv) \
> +	(INTEL_INFO(dev_priv)->has_heci_pxp)
> +
> +#define HAS_HECI_GSCFI(dev_priv) \
> +	(INTEL_INFO(dev_priv)->has_heci_gscfi)
> +
> +#define HAS_HECI_GSC(dev_priv) (HAS_HECI_PXP(dev_priv) || HAS_HECI_GSCFI(dev_priv))
> +
>   #define HAS_MSO(i915)		(DISPLAY_VER(i915) >= 12)
>   
>   #define HAS_RUNTIME_PM(dev_priv) (INTEL_INFO(dev_priv)->has_runtime_pm)
> diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
> index 67b89769f577..a948f566bd3d 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -901,7 +901,8 @@ static const struct intel_device_info rkl_info = {
>   	.has_llc = 0, \
>   	.has_pxp = 0, \
>   	.has_snoop = 1, \
> -	.is_dgfx = 1
> +	.is_dgfx = 1, \
> +	.has_heci_gscfi = 1
>   
>   static const struct intel_device_info dg1_info = {
>   	GEN12_FEATURES,
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 70484f6f2b8b..0ed305ff07a9 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -975,6 +975,8 @@
>   #define GEN12_COMPUTE1_RING_BASE	0x1c000
>   #define GEN12_COMPUTE2_RING_BASE	0x1e000
>   #define GEN12_COMPUTE3_RING_BASE	0x26000
> +#define GSC_DG1_HECI1_BASE	0x00258000

Do we need the DG1 HECI1 base definition, considering we're not adding 
HECI1 support for DG1?
Also, we usually put the platform name (DG1) before the unit (GSC) in 
our defines, so DG1_GSC_HECI* would probably be more inline with the 
rest of the defs.

> +#define GSC_DG1_HECI2_BASE	0x00259000
>   #define BLT_RING_BASE		0x22000

IMO better to move the GSC defs to after the BLT, that way we don't 
separate it from the other RING_BASE definitions, given that the GSC is 
not a RING and its base is something different. Not a blocker.

Daniele

>   
>   
> diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
> index f9b955810593..576d15a04c9e 100644
> --- a/drivers/gpu/drm/i915/intel_device_info.h
> +++ b/drivers/gpu/drm/i915/intel_device_info.h
> @@ -141,6 +141,8 @@ enum intel_ppgtt_type {
>   	func(has_flat_ccs); \
>   	func(has_global_mocs); \
>   	func(has_gt_uc); \
> +	func(has_heci_pxp); \
> +	func(has_heci_gscfi); \
>   	func(has_guc_deprivilege); \
>   	func(has_l3_dpf); \
>   	func(has_llc); \
> diff --git a/include/linux/mei_aux.h b/include/linux/mei_aux.h
> new file mode 100644
> index 000000000000..587f25128848
> --- /dev/null
> +++ b/include/linux/mei_aux.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2022, Intel Corporation. All rights reserved.
> + */
> +#ifndef _LINUX_MEI_AUX_H
> +#define _LINUX_MEI_AUX_H
> +
> +#include <linux/auxiliary_bus.h>
> +
> +struct mei_aux_device {
> +	struct auxiliary_device aux_dev;
> +	int irq;
> +	struct resource bar;
> +};
> +
> +#define auxiliary_dev_to_mei_aux_dev(auxiliary_dev) \
> +	container_of(auxiliary_dev, struct mei_aux_device, aux_dev)
> +
> +#endif /* _LINUX_MEI_AUX_H */


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 1/5] drm/i915/gsc: add gsc as a mei auxiliary device
@ 2022-03-09 22:50     ` Ceraolo Spurio, Daniele
  0 siblings, 0 replies; 33+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-03-09 22:50 UTC (permalink / raw)
  To: Alexander Usyskin, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: intel-gfx, Tomas Winkler, linux-kernel, Vitaly Lubart



On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> From: Tomas Winkler <tomas.winkler@intel.com>
>
> GSC is a graphics system controller, it provides
> a chassis controller for graphics discrete cards.
>
> There are two MEI interfaces in GSC: HECI1 and HECI2.
>
> Both interfaces are on the BAR0 at offsets 0x00258000 and 0x00259000.
> GSC is a GT Engine (class 4: instance 6). HECI1 interrupt is signaled
> via bit 15 and HECI2 via bit 14 in the interrupt register.
>
> This patch exports GSC as auxiliary device for mei driver to bind to
> for HECI2 interface.

Do we need a test for this? E.g. to catch the unlikely case where we 
stop exposing the GSC device. We are going to get some indirect coverage 
once we start making use of the PXP interface from within the kernel, 
would that be enough?

Also, IMO we need a line here to explain that we're adding the code for 
HECI1 as well because we plan to follow up with it soon.

>
> CC: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> Signed-off-by: Vitaly Lubart <vitaly.lubart@intel.com>
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> ---
>   MAINTAINERS                              |   1 +
>   drivers/gpu/drm/i915/Kconfig             |   1 +
>   drivers/gpu/drm/i915/Makefile            |   3 +
>   drivers/gpu/drm/i915/gt/intel_gsc.c      | 204 +++++++++++++++++++++++
>   drivers/gpu/drm/i915/gt/intel_gsc.h      |  37 ++++
>   drivers/gpu/drm/i915/gt/intel_gt.c       |   3 +
>   drivers/gpu/drm/i915/gt/intel_gt.h       |   5 +
>   drivers/gpu/drm/i915/gt/intel_gt_irq.c   |  13 ++
>   drivers/gpu/drm/i915/gt/intel_gt_regs.h  |   1 +
>   drivers/gpu/drm/i915/gt/intel_gt_types.h |   2 +
>   drivers/gpu/drm/i915/i915_drv.h          |   8 +
>   drivers/gpu/drm/i915/i915_pci.c          |   3 +-
>   drivers/gpu/drm/i915/i915_reg.h          |   2 +
>   drivers/gpu/drm/i915/intel_device_info.h |   2 +
>   include/linux/mei_aux.h                  |  19 +++
>   15 files changed, 303 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.c
>   create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.h
>   create mode 100644 include/linux/mei_aux.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 2b1d296f92e9..d322e630d1d1 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -9822,6 +9822,7 @@ S:	Supported
>   F:	Documentation/driver-api/mei/*
>   F:	drivers/misc/mei/
>   F:	drivers/watchdog/mei_wdt.c
> +F:	include/linux/mei_aux.h
>   F:	include/linux/mei_cl_bus.h
>   F:	include/uapi/linux/mei.h
>   F:	samples/mei/*
> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
> index 98c5450b8eac..2660a85175d9 100644
> --- a/drivers/gpu/drm/i915/Kconfig
> +++ b/drivers/gpu/drm/i915/Kconfig
> @@ -30,6 +30,7 @@ config DRM_I915
>   	select VMAP_PFN
>   	select DRM_TTM
>   	select DRM_BUDDY
> +	select AUXILIARY_BUS
>   	help
>   	  Choose this option if you have a system that has "Intel Graphics
>   	  Media Accelerator" or "HD Graphics" integrated graphics,
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 1a771ee5b1d0..9be7b13d8822 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -196,6 +196,9 @@ i915-y += gt/uc/intel_uc.o \
>   	  gt/uc/intel_huc_debugfs.o \
>   	  gt/uc/intel_huc_fw.o
>   
> +# graphics system controller (GSC) support
> +i915-y += gt/intel_gsc.o
> +
>   # modesetting core code
>   i915-y += \
>   	display/hsw_ips.o \
> diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.c b/drivers/gpu/drm/i915/gt/intel_gsc.c
> new file mode 100644
> index 000000000000..152804e7c41a
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/intel_gsc.c
> @@ -0,0 +1,204 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
> + */
> +
> +#include <linux/irq.h>
> +#include <linux/mei_aux.h>
> +#include "i915_reg.h"
> +#include "i915_drv.h"
> +#include "gt/intel_gt.h"
> +#include "intel_gsc.h"

A bit of inconsistency here because intel_gsc.h and intel_gt.h are both 
in the gt/ folder but you're only prefixing one with gt/. Also, we 
usually try to keep includes in alphabetical order, but overall not a 
blocker for me.

> +
> +#define GSC_BAR_LENGTH  0x00000FFC
> +
> +static void gsc_irq_mask(struct irq_data *d)
> +{
> +	/* generic irq handling */
> +}
> +
> +static void gsc_irq_unmask(struct irq_data *d)
> +{
> +	/* generic irq handling */
> +}
> +
> +static struct irq_chip gsc_irq_chip = {
> +	.name = "gsc_irq_chip",
> +	.irq_mask = gsc_irq_mask,
> +	.irq_unmask = gsc_irq_unmask,
> +};
> +
> +static int gsc_irq_init(int irq)
> +{
> +	irq_set_chip_and_handler_name(irq, &gsc_irq_chip,
> +				      handle_simple_irq, "gsc_irq_handler");
> +
> +	return irq_set_chip_data(irq, NULL);
> +}
> +
> +struct intel_gsc_def {
> +	const char *name;
> +	unsigned long bar;
> +	size_t bar_size;
> +};
> +
> +/* gscfi (graphics system controller firmware interface) resources */

Should this comment be moved down in the array? the array has sections 
for both pxp and gscfi resources, even if the former are not set. Or 
maybe expand to something like:

/* for DG1 we only need gscfi (....) resources */

> +static const struct intel_gsc_def intel_gsc_def_dg1[] = {
> +	{
> +		/* HECI1 not yet implemented. */
> +	},
> +	{
> +		.name = "mei-gscfi",
> +		.bar = GSC_DG1_HECI2_BASE,
> +		.bar_size = GSC_BAR_LENGTH,
> +	}
> +};
> +
> +static void intel_gsc_release_dev(struct device *dev)

We usually avoid the intel_* prefix for static functions. Same for other 
functions below.

> +{
> +	struct auxiliary_device *aux_dev = to_auxiliary_dev(dev);
> +	struct mei_aux_device *adev = auxiliary_dev_to_mei_aux_dev(aux_dev);
> +
> +	kfree(adev);
> +}
> +
> +static void intel_gsc_destroy_one(struct intel_gsc_intf *intf)
> +{
> +	if (intf->adev) {
> +		auxiliary_device_delete(&intf->adev->aux_dev);
> +		auxiliary_device_uninit(&intf->adev->aux_dev);
> +		intf->adev = NULL;
> +	}
> +	if (intf->irq >= 0)
> +		irq_free_desc(intf->irq);
> +	intf->irq = -1;
> +}
> +
> +static void intel_gsc_init_one(struct drm_i915_private *i915,
> +			       struct intel_gsc_intf *intf,
> +			       unsigned int intf_id)
> +{
> +	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
> +	struct mei_aux_device *adev;
> +	struct auxiliary_device *aux_dev;
> +	const struct intel_gsc_def *def;
> +	int ret;
> +
> +	intf->irq = -1;
> +	intf->id = intf_id;
> +
> +	if (intf_id == 0 && !HAS_HECI_PXP(i915))
> +		return;
> +
> +	def = &intel_gsc_def_dg1[intf_id];
> +
> +	if (!def->name) {
> +		drm_warn_once(&i915->drm, "HECI%d is not implemented!\n", intf_id + 1);
> +		return;
> +	}
> +
> +	intf->irq = irq_alloc_desc(0);
> +	if (intf->irq < 0) {
> +		drm_err(&i915->drm, "gsc irq error %d\n", intf->irq);
> +		return;
> +	}
> +
> +	ret = gsc_irq_init(intf->irq);
> +	if (ret < 0) {
> +		drm_err(&i915->drm, "gsc irq init failed %d\n", ret);
> +		goto fail;
> +	}
> +
> +	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
> +	if (!adev)
> +		goto fail;
> +
> +	adev->irq = intf->irq;
> +	adev->bar.parent = &pdev->resource[0];
> +	adev->bar.start = def->bar + pdev->resource[0].start;
> +	adev->bar.end = adev->bar.start + def->bar_size - 1;
> +	adev->bar.flags = IORESOURCE_MEM;
> +	adev->bar.desc = IORES_DESC_NONE;
> +
> +	aux_dev = &adev->aux_dev;
> +	aux_dev->name = def->name;
> +	aux_dev->id = (pci_domain_nr(pdev->bus) << 16) |
> +		      PCI_DEVID(pdev->bus->number, pdev->devfn);
> +	aux_dev->dev.parent = &pdev->dev;
> +	aux_dev->dev.release = intel_gsc_release_dev;
> +
> +	ret = auxiliary_device_init(aux_dev);
> +	if (ret < 0) {
> +		drm_err(&i915->drm, "gsc aux init failed %d\n", ret);
> +		kfree(adev);
> +		goto fail;
> +	}
> +
> +	ret = auxiliary_device_add(aux_dev);
> +	if (ret < 0) {
> +		drm_err(&i915->drm, "gsc aux add failed %d\n", ret);
> +		/* adev will be freed with the put_device() and .release sequence */
> +		auxiliary_device_uninit(aux_dev);
> +		goto fail;
> +	}
> +	intf->adev = adev;
> +
> +	return;
> +fail:
> +	intel_gsc_destroy_one(intf);
> +}
> +
> +static void gsc_irq_handler(struct intel_gt *gt, unsigned int intf_id)
> +{
> +	int ret;
> +
> +	if (intf_id >= INTEL_GSC_NUM_INTERFACES) {
> +		drm_warn_once(&gt->i915->drm, "GSC irq: intf_id %d is out of range", intf_id);
> +		return;
> +	}
> +
> +	if (!HAS_HECI_GSC(gt->i915)) {
> +		drm_warn_once(&gt->i915->drm, "GSC irq: not supported");
> +		return;
> +	}
> +
> +	if (gt->gsc.intf[intf_id].irq < 0) {
> +		drm_err_ratelimited(&gt->i915->drm, "GSC irq: irq not set");
> +		return;
> +	}
> +
> +	ret = generic_handle_irq(gt->gsc.intf[intf_id].irq);
> +	if (ret)
> +		drm_err_ratelimited(&gt->i915->drm, "error handling GSC irq: %d\n", ret);
> +}
> +
> +void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir)
> +{
> +	if (iir & GSC_IRQ_INTF(0))
> +		gsc_irq_handler(gt, 0);
> +	if (iir & GSC_IRQ_INTF(1))
> +		gsc_irq_handler(gt, 1);
> +}
> +
> +void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private *i915)
> +{
> +	unsigned int i;
> +
> +	if (!HAS_HECI_GSC(i915))
> +		return;
> +
> +	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
> +		intel_gsc_init_one(i915, &gsc->intf[i], i);
> +}
> +
> +void intel_gsc_fini(struct intel_gsc *gsc)
> +{
> +	struct intel_gt *gt = gsc_to_gt(gsc);
> +	unsigned int i;
> +
> +	if (!HAS_HECI_GSC(gt->i915))
> +		return;
> +
> +	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
> +		intel_gsc_destroy_one(&gsc->intf[i]);
> +}
> diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.h b/drivers/gpu/drm/i915/gt/intel_gsc.h
> new file mode 100644
> index 000000000000..68582f912b21
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/intel_gsc.h
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
> + */
> +#ifndef __INTEL_GSC_DEV_H__
> +#define __INTEL_GSC_DEV_H__
> +
> +#include <linux/types.h>
> +
> +struct drm_i915_private;
> +struct intel_gt;
> +struct mei_aux_device;
> +
> +#define INTEL_GSC_NUM_INTERFACES 2
> +/*
> + * The HECI1 bit corresponds to bit15 and HECI2 to bit14.
> + * The reason for this is to allow growth for more interfaces in the future.
> + */
> +#define GSC_IRQ_INTF(_x)  BIT(15 - (_x))
> +
> +/**
> + * struct intel_gsc - graphics security controller
> + * @intf : gsc interface
> + */
> +struct intel_gsc {
> +	struct intel_gsc_intf {
> +		struct mei_aux_device *adev;
> +		int irq;
> +		unsigned int id;
> +	} intf[INTEL_GSC_NUM_INTERFACES];
> +};
> +
> +void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private *dev_priv);
> +void intel_gsc_fini(struct intel_gsc *gsc);
> +void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir);
> +
> +#endif /* __INTEL_GSC_DEV_H__ */
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
> index 8a2483ccbfb9..fd83ab4b8849 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.c
> @@ -444,6 +444,8 @@ void intel_gt_chipset_flush(struct intel_gt *gt)
>   
>   void intel_gt_driver_register(struct intel_gt *gt)
>   {
> +	intel_gsc_init(&gt->gsc, gt->i915);
> +
>   	intel_rps_driver_register(&gt->rps);
>   
>   	intel_gt_debugfs_register(gt);
> @@ -766,6 +768,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
>   	intel_wakeref_t wakeref;
>   
>   	intel_rps_driver_unregister(&gt->rps);
> +	intel_gsc_fini(&gt->gsc);
>   
>   	intel_pxp_fini(&gt->pxp);
>   
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h
> index 0f571c8ee22b..de779a505c21 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.h
> @@ -34,6 +34,11 @@ static inline struct intel_gt *huc_to_gt(struct intel_huc *huc)
>   	return container_of(huc, struct intel_gt, uc.huc);
>   }
>   
> +static inline struct intel_gt *gsc_to_gt(struct intel_gsc *gsc)
> +{
> +	return container_of(gsc, struct intel_gt, gsc);
> +}
> +
>   void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915);
>   void __intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915);
>   int intel_gt_assign_ggtt(struct intel_gt *gt);
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> index e443ac4c8059..917b85d0c189 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> @@ -68,6 +68,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 instance,
>   	if (instance == OTHER_KCR_INSTANCE)
>   		return intel_pxp_irq_handler(&gt->pxp, iir);
>   
> +	if (instance == OTHER_GSC_INSTANCE)
> +		return intel_gsc_irq_handler(gt, iir);
> +
>   	WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
>   		  instance, iir);
>   }
> @@ -184,6 +187,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
>   	intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE,	  0);
>   	if (CCS_MASK(gt))
>   		intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, 0);
> +	if (HAS_HECI_GSC(gt->i915))
> +		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE, 0);
>   
>   	/* Restore masks irqs on RCS, BCS, VCS and VECS engines. */
>   	intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK,	~0);
> @@ -201,6 +206,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
>   		intel_uncore_write(uncore, GEN12_CCS0_CCS1_INTR_MASK, ~0);
>   	if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3))
>   		intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~0);
> +	if (HAS_HECI_GSC(gt->i915))
> +		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, ~0);
>   
>   	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0);
>   	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
> @@ -215,6 +222,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
>   {
>   	struct intel_uncore *uncore = gt->uncore;
>   	u32 irqs = GT_RENDER_USER_INTERRUPT;
> +	const u32 gsc_mask = GSC_IRQ_INTF(0) | GSC_IRQ_INTF(1);
>   	u32 dmask;
>   	u32 smask;
>   
> @@ -233,6 +241,9 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
>   	intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE, dmask);
>   	if (CCS_MASK(gt))
>   		intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, smask);
> +	if (HAS_HECI_GSC(gt->i915))
> +		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE,
> +				   gsc_mask);
>   
>   	/* Unmask irqs on RCS, BCS, VCS and VECS engines. */
>   	intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK, ~smask);
> @@ -250,6 +261,8 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
>   		intel_uncore_write(uncore, GEN12_CCS0_CCS1_INTR_MASK, ~dmask);
>   	if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3))
>   		intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~dmask);
> +	if (HAS_HECI_GSC(gt->i915))
> +		intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, 0);

This should be ~gsc_mask, right?

>   
>   	/*
>   	 * RPS interrupts will get enabled/disabled on demand when RPS itself
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> index 19cd34f24263..a277fb480cc8 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> @@ -1483,6 +1483,7 @@
>   #define   OTHER_GUC_INSTANCE			0
>   #define   OTHER_GTPM_INSTANCE			1
>   #define   OTHER_KCR_INSTANCE			4
> +#define   OTHER_GSC_INSTANCE			6
>   
>   #define GEN11_IIR_REG_SELECTOR(x)		_MMIO(0x190070 + ((x) * 4))
>   
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> index f20687796490..5556d55f76ea 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> @@ -16,6 +16,7 @@
>   #include <linux/workqueue.h>
>   
>   #include "uc/intel_uc.h"
> +#include "intel_gsc.h"
>   
>   #include "i915_vma.h"
>   #include "intel_engine_types.h"
> @@ -72,6 +73,7 @@ struct intel_gt {
>   	struct i915_ggtt *ggtt;
>   
>   	struct intel_uc uc;
> +	struct intel_gsc gsc;
>   
>   	struct mutex tlb_invalidate_lock;
>   
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 943267393ecb..1c000c15493d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1327,6 +1327,14 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
>   
>   #define HAS_DMC(dev_priv)	(INTEL_INFO(dev_priv)->display.has_dmc)
>   
> +#define HAS_HECI_PXP(dev_priv) \
> +	(INTEL_INFO(dev_priv)->has_heci_pxp)
> +
> +#define HAS_HECI_GSCFI(dev_priv) \
> +	(INTEL_INFO(dev_priv)->has_heci_gscfi)
> +
> +#define HAS_HECI_GSC(dev_priv) (HAS_HECI_PXP(dev_priv) || HAS_HECI_GSCFI(dev_priv))
> +
>   #define HAS_MSO(i915)		(DISPLAY_VER(i915) >= 12)
>   
>   #define HAS_RUNTIME_PM(dev_priv) (INTEL_INFO(dev_priv)->has_runtime_pm)
> diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
> index 67b89769f577..a948f566bd3d 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -901,7 +901,8 @@ static const struct intel_device_info rkl_info = {
>   	.has_llc = 0, \
>   	.has_pxp = 0, \
>   	.has_snoop = 1, \
> -	.is_dgfx = 1
> +	.is_dgfx = 1, \
> +	.has_heci_gscfi = 1
>   
>   static const struct intel_device_info dg1_info = {
>   	GEN12_FEATURES,
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 70484f6f2b8b..0ed305ff07a9 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -975,6 +975,8 @@
>   #define GEN12_COMPUTE1_RING_BASE	0x1c000
>   #define GEN12_COMPUTE2_RING_BASE	0x1e000
>   #define GEN12_COMPUTE3_RING_BASE	0x26000
> +#define GSC_DG1_HECI1_BASE	0x00258000

Do we need the DG1 HECI1 base definition, considering we're not adding 
HECI1 support for DG1?
Also, we usually put the platform name (DG1) before the unit (GSC) in 
our defines, so DG1_GSC_HECI* would probably be more inline with the 
rest of the defs.

> +#define GSC_DG1_HECI2_BASE	0x00259000
>   #define BLT_RING_BASE		0x22000

IMO better to move the GSC defs to after the BLT, that way we don't 
separate it from the other RING_BASE definitions, given that the GSC is 
not a RING and its base is something different. Not a blocker.

Daniele

>   
>   
> diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
> index f9b955810593..576d15a04c9e 100644
> --- a/drivers/gpu/drm/i915/intel_device_info.h
> +++ b/drivers/gpu/drm/i915/intel_device_info.h
> @@ -141,6 +141,8 @@ enum intel_ppgtt_type {
>   	func(has_flat_ccs); \
>   	func(has_global_mocs); \
>   	func(has_gt_uc); \
> +	func(has_heci_pxp); \
> +	func(has_heci_gscfi); \
>   	func(has_guc_deprivilege); \
>   	func(has_l3_dpf); \
>   	func(has_llc); \
> diff --git a/include/linux/mei_aux.h b/include/linux/mei_aux.h
> new file mode 100644
> index 000000000000..587f25128848
> --- /dev/null
> +++ b/include/linux/mei_aux.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2022, Intel Corporation. All rights reserved.
> + */
> +#ifndef _LINUX_MEI_AUX_H
> +#define _LINUX_MEI_AUX_H
> +
> +#include <linux/auxiliary_bus.h>
> +
> +struct mei_aux_device {
> +	struct auxiliary_device aux_dev;
> +	int irq;
> +	struct resource bar;
> +};
> +
> +#define auxiliary_dev_to_mei_aux_dev(auxiliary_dev) \
> +	container_of(auxiliary_dev, struct mei_aux_device, aux_dev)
> +
> +#endif /* _LINUX_MEI_AUX_H */


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 2/5] mei: add support for graphics system controller (gsc) devices
  2022-03-08 16:36   ` [Intel-gfx] " Alexander Usyskin
@ 2022-03-10  0:24     ` Ceraolo Spurio, Daniele
  -1 siblings, 0 replies; 33+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-03-10  0:24 UTC (permalink / raw)
  To: Alexander Usyskin, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: linux-kernel, Tomas Winkler, Vitaly Lubart, intel-gfx


On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> From: Tomas Winkler <tomas.winkler@intel.com>
>
> GSC is a graphics system controller, based on CSE, it provides
> a chassis controller for graphics discrete cards, as well as it
> supports media protection on selected devices.
>
> mei_gsc binds to a auxiliary devices exposed by Intel discrete
> driver i915.
>
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> ---
>   drivers/misc/mei/Kconfig  |  14 +++
>   drivers/misc/mei/Makefile |   3 +
>   drivers/misc/mei/gsc-me.c | 186 ++++++++++++++++++++++++++++++++++++++
>   drivers/misc/mei/hw-me.c  |  27 +++++-
>   drivers/misc/mei/hw-me.h  |   2 +
>   5 files changed, 230 insertions(+), 2 deletions(-)
>   create mode 100644 drivers/misc/mei/gsc-me.c
>
> diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
> index 0e0bcd0da852..d21486d69df2 100644
> --- a/drivers/misc/mei/Kconfig
> +++ b/drivers/misc/mei/Kconfig
> @@ -46,6 +46,20 @@ config INTEL_MEI_TXE
>   	  Supported SoCs:
>   	  Intel Bay Trail
>   
> +config INTEL_MEI_GSC

On platforms with a GSC, INTEL_MEI_PXP depends on INTEL_MEI_GSC. Are you 
planning to add that dependency once the HECI1/PXP interface is exposed, 
or are you expecting i915 to check for both?

> +	tristate "Intel MEI GSC embedded device"
> +	depends on INTEL_MEI
> +	depends on INTEL_MEI_ME
> +	depends on X86 && PCI
> +	depends on DRM_I915
> +	help
> +	  Intel auxiliary driver for GSC devices embedded in Intel graphics devices.
> +
> +	  An MEI device here called GSC can be embedded in an
> +	  Intel graphics devices, to support a range of chassis
> +	  tasks such as graphics card firmware update and security
> +	  tasks.
> +
>   source "drivers/misc/mei/hdcp/Kconfig"
>   source "drivers/misc/mei/pxp/Kconfig"
>   
> diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
> index d8e5165917f2..fb740d754900 100644
> --- a/drivers/misc/mei/Makefile
> +++ b/drivers/misc/mei/Makefile
> @@ -18,6 +18,9 @@ obj-$(CONFIG_INTEL_MEI_ME) += mei-me.o
>   mei-me-objs := pci-me.o
>   mei-me-objs += hw-me.o
>   
> +obj-$(CONFIG_INTEL_MEI_GSC) += mei-gsc.o
> +mei-gsc-objs := gsc-me.o
> +
>   obj-$(CONFIG_INTEL_MEI_TXE) += mei-txe.o
>   mei-txe-objs := pci-txe.o
>   mei-txe-objs += hw-txe.o
> diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
> new file mode 100644
> index 000000000000..0afae70e0609
> --- /dev/null
> +++ b/drivers/misc/mei/gsc-me.c
> @@ -0,0 +1,186 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
> + *
> + * Intel Management Engine Interface (Intel MEI) Linux driver
> + */
> +
> +#include <linux/module.h>
> +#include <linux/mei_aux.h>
> +#include <linux/device.h>
> +#include <linux/irqreturn.h>
> +#include <linux/jiffies.h>
> +#include <linux/ktime.h>
> +#include <linux/delay.h>
> +#include <linux/pm_runtime.h>
> +
> +#include "mei_dev.h"
> +#include "hw-me.h"
> +#include "hw-me-regs.h"
> +
> +#include "mei-trace.h"
> +
> +#define MEI_GSC_RPM_TIMEOUT 500

MEI_ME_RPM_TIMEOUT already exists in hw-me.h with the same value. If 
you're not expecting them to diverge, we could just re-use the existing 
one. Not a blocker.

> +
> +static int mei_gsc_read_hfs(const struct mei_device *dev, int where, u32 *val)
> +{
> +	struct mei_me_hw *hw = to_me_hw(dev);
> +
> +	*val = ioread32(hw->mem_addr + where + 0xC00);
> +
> +	return 0;
> +}
> +
> +static int mei_gsc_probe(struct auxiliary_device *aux_dev,
> +			 const struct auxiliary_device_id *aux_dev_id)
> +{
> +	struct mei_aux_device *adev = auxiliary_dev_to_mei_aux_dev(aux_dev);
> +	struct mei_device *dev;

might be worth renaming this variable to mei_dev, to avoid confusion 
with "device" below. Not a blocker.

> +	struct mei_me_hw *hw;
> +	struct device *device;
> +	const struct mei_cfg *cfg;
> +	int ret;
> +
> +	cfg = mei_me_get_cfg(aux_dev_id->driver_data);
> +	if (!cfg)
> +		return -ENODEV;
> +
> +	device = &aux_dev->dev;
> +
> +	dev = mei_me_dev_init(device, cfg);
> +	if (IS_ERR(dev)) {
> +		ret = PTR_ERR(dev);
> +		goto err;
> +	}
> +
> +	hw = to_me_hw(dev);
> +	hw->mem_addr = devm_ioremap_resource(device, &adev->bar);
> +	if (IS_ERR(hw->mem_addr)) {
> +		dev_err(device, "mmio not mapped\n");
> +		ret = PTR_ERR(hw->mem_addr);
> +		goto err;
> +	}
> +
> +	hw->irq = adev->irq;
> +	hw->read_fws = mei_gsc_read_hfs;
> +
> +	dev_set_drvdata(&aux_dev->dev, dev);

you have a device = &aux_dev->dev earlier, so you can just use device here.

> +
> +	ret = devm_request_threaded_irq(device, hw->irq,
> +					mei_me_irq_quick_handler,
> +					mei_me_irq_thread_handler,
> +					IRQF_ONESHOT, KBUILD_MODNAME, dev);

If I'm understanding this correctly, you're tying the irq to the device 
allocated by i915, so if the probe fails below or the mei_gsc module is 
unloaded the irq is going to stick around. Probably better to clean it 
up explicitly, in case we get a spurious interrupt from the HW and i915 
propagates it (although that's a very unlikely scenario).

> +	if (ret) {
> +		dev_err(device, "irq register failed %d\n", ret);
> +		goto err;
> +	}
> +
> +	pm_runtime_get_noresume(device);
> +	pm_runtime_set_active(device);
> +	pm_runtime_enable(device);
> +
> +	if (mei_start(dev)) {
> +		dev_err(device, "init hw failure.\n");
> +		ret = -ENODEV;
> +		goto err;
> +	}
> +
> +	pm_runtime_set_autosuspend_delay(device, MEI_GSC_RPM_TIMEOUT);
> +	pm_runtime_use_autosuspend(device);
> +
> +	ret = mei_register(dev, device);
> +	if (ret)
> +		goto register_err;
> +
> +	pm_runtime_put_noidle(device);
> +	return 0;
> +
> +register_err:
> +	mei_stop(dev);
> +
> +err:
> +	dev_err(device, "probe failed: %d\n", ret);
> +	dev_set_drvdata(&aux_dev->dev, NULL);

can use device here as well instead of &aux_dev->dev

> +	return ret;
> +}
> +
> +static void mei_gsc_remove(struct auxiliary_device *aux_dev)
> +{
> +	struct mei_device *dev;
> +
> +	dev = dev_get_drvdata(&aux_dev->dev);
> +	if (!dev)
> +		return;
> +
> +	mei_stop(dev);
> +
> +	mei_deregister(dev);
> +
> +	pm_runtime_disable(&aux_dev->dev);
> +}
> +
> +static int __maybe_unused mei_gsc_pm_suspend(struct device *device)
> +{
> +	struct mei_device *dev = dev_get_drvdata(device);
> +
> +	if (!dev)
> +		return -ENODEV;
> +
> +	mei_stop(dev);
> +
> +	mei_disable_interrupts(dev);
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused mei_gsc_pm_resume(struct device *device)
> +{
> +	struct mei_device *dev = dev_get_drvdata(device);
> +	int err;
> +
> +	if (!dev)
> +		return -ENODEV;
> +
> +	err = mei_restart(dev);

Might be worth adding a comment to explain that the interrupts are 
enabled by the mei_restart and that's why we don't have a 
mei_interrupts_enable call to match the disable we have in the suspend.

Daniele

> +	if (err)
> +		return err;
> +
> +	/* Start timer if stopped in suspend */
> +	schedule_delayed_work(&dev->timer_work, HZ);
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(mei_gsc_pm_ops, mei_gsc_pm_suspend, mei_gsc_pm_resume);
> +
> +static const struct auxiliary_device_id mei_gsc_id_table[] = {
> +	{
> +		.name = "i915.mei-gsc",
> +		.driver_data = MEI_ME_GSC_CFG,
> +
> +	},
> +	{
> +		.name = "i915.mei-gscfi",
> +		.driver_data = MEI_ME_GSCFI_CFG,
> +	},
> +	{
> +		/* sentinel */
> +	}
> +};
> +MODULE_DEVICE_TABLE(auxiliary, mei_gsc_id_table);
> +
> +static struct auxiliary_driver mei_gsc_driver = {
> +	.probe	= mei_gsc_probe,
> +	.remove = mei_gsc_remove,
> +	.driver = {
> +		/* auxiliary_driver_register() sets .name to be the modname */
> +		.pm = &mei_gsc_pm_ops,
> +	},
> +	.id_table = mei_gsc_id_table
> +};
> +module_auxiliary_driver(mei_gsc_driver);
> +
> +MODULE_AUTHOR("Intel Corporation");
> +MODULE_ALIAS("auxiliary:i915.mei-gsc");
> +MODULE_ALIAS("auxiliary:i915.mei-gscfi");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
> index d3a6c0728645..9748d14849a1 100644
> --- a/drivers/misc/mei/hw-me.c
> +++ b/drivers/misc/mei/hw-me.c
> @@ -1226,6 +1226,7 @@ irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id)
>   	me_intr_disable(dev, hcsr);
>   	return IRQ_WAKE_THREAD;
>   }
> +EXPORT_SYMBOL_GPL(mei_me_irq_quick_handler);
>   
>   /**
>    * mei_me_irq_thread_handler - function called after ISR to handle the interrupt
> @@ -1320,6 +1321,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
>   	mutex_unlock(&dev->device_lock);
>   	return IRQ_HANDLED;
>   }
> +EXPORT_SYMBOL_GPL(mei_me_irq_thread_handler);
>   
>   static const struct mei_hw_ops mei_me_hw_ops = {
>   
> @@ -1433,6 +1435,12 @@ static bool mei_me_fw_type_sps(const struct pci_dev *pdev)
>   #define MEI_CFG_KIND_ITOUCH                     \
>   	.kind = "itouch"
>   
> +#define MEI_CFG_TYPE_GSC                        \
> +	.kind = "gsc"
> +
> +#define MEI_CFG_TYPE_GSCFI                      \
> +	.kind = "gscfi"
> +
>   #define MEI_CFG_FW_SPS                          \
>   	.quirk_probe = mei_me_fw_type_sps
>   
> @@ -1565,6 +1573,18 @@ static const struct mei_cfg mei_me_pch15_sps_cfg = {
>   	MEI_CFG_FW_SPS,
>   };
>   
> +/* Graphics System Controller */
> +static const struct mei_cfg mei_me_gsc_cfg = {
> +	MEI_CFG_TYPE_GSC,
> +	MEI_CFG_PCH8_HFS,
> +};
> +
> +/* Graphics System Controller Firmware Interface */
> +static const struct mei_cfg mei_me_gscfi_cfg = {
> +	MEI_CFG_TYPE_GSCFI,
> +	MEI_CFG_PCH8_HFS,
> +};
> +
>   /*
>    * mei_cfg_list - A list of platform platform specific configurations.
>    * Note: has to be synchronized with  enum mei_cfg_idx.
> @@ -1585,6 +1605,8 @@ static const struct mei_cfg *const mei_cfg_list[] = {
>   	[MEI_ME_PCH12_SPS_ITOUCH_CFG] = &mei_me_pch12_itouch_sps_cfg,
>   	[MEI_ME_PCH15_CFG] = &mei_me_pch15_cfg,
>   	[MEI_ME_PCH15_SPS_CFG] = &mei_me_pch15_sps_cfg,
> +	[MEI_ME_GSC_CFG] = &mei_me_gsc_cfg,
> +	[MEI_ME_GSCFI_CFG] = &mei_me_gscfi_cfg,
>   };
>   
>   const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx)
> @@ -1595,7 +1617,8 @@ const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx)
>   		return NULL;
>   
>   	return mei_cfg_list[idx];
> -};
> +}
> +EXPORT_SYMBOL_GPL(mei_me_get_cfg);
>   
>   /**
>    * mei_me_dev_init - allocates and initializes the mei device structure
> @@ -1630,4 +1653,4 @@ struct mei_device *mei_me_dev_init(struct device *parent,
>   
>   	return dev;
>   }
> -
> +EXPORT_SYMBOL_GPL(mei_me_dev_init);
> diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
> index 00a7132ac7a2..a071c645e905 100644
> --- a/drivers/misc/mei/hw-me.h
> +++ b/drivers/misc/mei/hw-me.h
> @@ -112,6 +112,8 @@ enum mei_cfg_idx {
>   	MEI_ME_PCH12_SPS_ITOUCH_CFG,
>   	MEI_ME_PCH15_CFG,
>   	MEI_ME_PCH15_SPS_CFG,
> +	MEI_ME_GSC_CFG,
> +	MEI_ME_GSCFI_CFG,
>   	MEI_ME_NUM_CFG,
>   };
>   


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 2/5] mei: add support for graphics system controller (gsc) devices
@ 2022-03-10  0:24     ` Ceraolo Spurio, Daniele
  0 siblings, 0 replies; 33+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-03-10  0:24 UTC (permalink / raw)
  To: Alexander Usyskin, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: Tomas Winkler, intel-gfx, linux-kernel, Vitaly Lubart


On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> From: Tomas Winkler <tomas.winkler@intel.com>
>
> GSC is a graphics system controller, based on CSE, it provides
> a chassis controller for graphics discrete cards, as well as it
> supports media protection on selected devices.
>
> mei_gsc binds to a auxiliary devices exposed by Intel discrete
> driver i915.
>
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> ---
>   drivers/misc/mei/Kconfig  |  14 +++
>   drivers/misc/mei/Makefile |   3 +
>   drivers/misc/mei/gsc-me.c | 186 ++++++++++++++++++++++++++++++++++++++
>   drivers/misc/mei/hw-me.c  |  27 +++++-
>   drivers/misc/mei/hw-me.h  |   2 +
>   5 files changed, 230 insertions(+), 2 deletions(-)
>   create mode 100644 drivers/misc/mei/gsc-me.c
>
> diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
> index 0e0bcd0da852..d21486d69df2 100644
> --- a/drivers/misc/mei/Kconfig
> +++ b/drivers/misc/mei/Kconfig
> @@ -46,6 +46,20 @@ config INTEL_MEI_TXE
>   	  Supported SoCs:
>   	  Intel Bay Trail
>   
> +config INTEL_MEI_GSC

On platforms with a GSC, INTEL_MEI_PXP depends on INTEL_MEI_GSC. Are you 
planning to add that dependency once the HECI1/PXP interface is exposed, 
or are you expecting i915 to check for both?

> +	tristate "Intel MEI GSC embedded device"
> +	depends on INTEL_MEI
> +	depends on INTEL_MEI_ME
> +	depends on X86 && PCI
> +	depends on DRM_I915
> +	help
> +	  Intel auxiliary driver for GSC devices embedded in Intel graphics devices.
> +
> +	  An MEI device here called GSC can be embedded in an
> +	  Intel graphics devices, to support a range of chassis
> +	  tasks such as graphics card firmware update and security
> +	  tasks.
> +
>   source "drivers/misc/mei/hdcp/Kconfig"
>   source "drivers/misc/mei/pxp/Kconfig"
>   
> diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
> index d8e5165917f2..fb740d754900 100644
> --- a/drivers/misc/mei/Makefile
> +++ b/drivers/misc/mei/Makefile
> @@ -18,6 +18,9 @@ obj-$(CONFIG_INTEL_MEI_ME) += mei-me.o
>   mei-me-objs := pci-me.o
>   mei-me-objs += hw-me.o
>   
> +obj-$(CONFIG_INTEL_MEI_GSC) += mei-gsc.o
> +mei-gsc-objs := gsc-me.o
> +
>   obj-$(CONFIG_INTEL_MEI_TXE) += mei-txe.o
>   mei-txe-objs := pci-txe.o
>   mei-txe-objs += hw-txe.o
> diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
> new file mode 100644
> index 000000000000..0afae70e0609
> --- /dev/null
> +++ b/drivers/misc/mei/gsc-me.c
> @@ -0,0 +1,186 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
> + *
> + * Intel Management Engine Interface (Intel MEI) Linux driver
> + */
> +
> +#include <linux/module.h>
> +#include <linux/mei_aux.h>
> +#include <linux/device.h>
> +#include <linux/irqreturn.h>
> +#include <linux/jiffies.h>
> +#include <linux/ktime.h>
> +#include <linux/delay.h>
> +#include <linux/pm_runtime.h>
> +
> +#include "mei_dev.h"
> +#include "hw-me.h"
> +#include "hw-me-regs.h"
> +
> +#include "mei-trace.h"
> +
> +#define MEI_GSC_RPM_TIMEOUT 500

MEI_ME_RPM_TIMEOUT already exists in hw-me.h with the same value. If 
you're not expecting them to diverge, we could just re-use the existing 
one. Not a blocker.

> +
> +static int mei_gsc_read_hfs(const struct mei_device *dev, int where, u32 *val)
> +{
> +	struct mei_me_hw *hw = to_me_hw(dev);
> +
> +	*val = ioread32(hw->mem_addr + where + 0xC00);
> +
> +	return 0;
> +}
> +
> +static int mei_gsc_probe(struct auxiliary_device *aux_dev,
> +			 const struct auxiliary_device_id *aux_dev_id)
> +{
> +	struct mei_aux_device *adev = auxiliary_dev_to_mei_aux_dev(aux_dev);
> +	struct mei_device *dev;

might be worth renaming this variable to mei_dev, to avoid confusion 
with "device" below. Not a blocker.

> +	struct mei_me_hw *hw;
> +	struct device *device;
> +	const struct mei_cfg *cfg;
> +	int ret;
> +
> +	cfg = mei_me_get_cfg(aux_dev_id->driver_data);
> +	if (!cfg)
> +		return -ENODEV;
> +
> +	device = &aux_dev->dev;
> +
> +	dev = mei_me_dev_init(device, cfg);
> +	if (IS_ERR(dev)) {
> +		ret = PTR_ERR(dev);
> +		goto err;
> +	}
> +
> +	hw = to_me_hw(dev);
> +	hw->mem_addr = devm_ioremap_resource(device, &adev->bar);
> +	if (IS_ERR(hw->mem_addr)) {
> +		dev_err(device, "mmio not mapped\n");
> +		ret = PTR_ERR(hw->mem_addr);
> +		goto err;
> +	}
> +
> +	hw->irq = adev->irq;
> +	hw->read_fws = mei_gsc_read_hfs;
> +
> +	dev_set_drvdata(&aux_dev->dev, dev);

you have a device = &aux_dev->dev earlier, so you can just use device here.

> +
> +	ret = devm_request_threaded_irq(device, hw->irq,
> +					mei_me_irq_quick_handler,
> +					mei_me_irq_thread_handler,
> +					IRQF_ONESHOT, KBUILD_MODNAME, dev);

If I'm understanding this correctly, you're tying the irq to the device 
allocated by i915, so if the probe fails below or the mei_gsc module is 
unloaded the irq is going to stick around. Probably better to clean it 
up explicitly, in case we get a spurious interrupt from the HW and i915 
propagates it (although that's a very unlikely scenario).

> +	if (ret) {
> +		dev_err(device, "irq register failed %d\n", ret);
> +		goto err;
> +	}
> +
> +	pm_runtime_get_noresume(device);
> +	pm_runtime_set_active(device);
> +	pm_runtime_enable(device);
> +
> +	if (mei_start(dev)) {
> +		dev_err(device, "init hw failure.\n");
> +		ret = -ENODEV;
> +		goto err;
> +	}
> +
> +	pm_runtime_set_autosuspend_delay(device, MEI_GSC_RPM_TIMEOUT);
> +	pm_runtime_use_autosuspend(device);
> +
> +	ret = mei_register(dev, device);
> +	if (ret)
> +		goto register_err;
> +
> +	pm_runtime_put_noidle(device);
> +	return 0;
> +
> +register_err:
> +	mei_stop(dev);
> +
> +err:
> +	dev_err(device, "probe failed: %d\n", ret);
> +	dev_set_drvdata(&aux_dev->dev, NULL);

can use device here as well instead of &aux_dev->dev

> +	return ret;
> +}
> +
> +static void mei_gsc_remove(struct auxiliary_device *aux_dev)
> +{
> +	struct mei_device *dev;
> +
> +	dev = dev_get_drvdata(&aux_dev->dev);
> +	if (!dev)
> +		return;
> +
> +	mei_stop(dev);
> +
> +	mei_deregister(dev);
> +
> +	pm_runtime_disable(&aux_dev->dev);
> +}
> +
> +static int __maybe_unused mei_gsc_pm_suspend(struct device *device)
> +{
> +	struct mei_device *dev = dev_get_drvdata(device);
> +
> +	if (!dev)
> +		return -ENODEV;
> +
> +	mei_stop(dev);
> +
> +	mei_disable_interrupts(dev);
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused mei_gsc_pm_resume(struct device *device)
> +{
> +	struct mei_device *dev = dev_get_drvdata(device);
> +	int err;
> +
> +	if (!dev)
> +		return -ENODEV;
> +
> +	err = mei_restart(dev);

Might be worth adding a comment to explain that the interrupts are 
enabled by the mei_restart and that's why we don't have a 
mei_interrupts_enable call to match the disable we have in the suspend.

Daniele

> +	if (err)
> +		return err;
> +
> +	/* Start timer if stopped in suspend */
> +	schedule_delayed_work(&dev->timer_work, HZ);
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(mei_gsc_pm_ops, mei_gsc_pm_suspend, mei_gsc_pm_resume);
> +
> +static const struct auxiliary_device_id mei_gsc_id_table[] = {
> +	{
> +		.name = "i915.mei-gsc",
> +		.driver_data = MEI_ME_GSC_CFG,
> +
> +	},
> +	{
> +		.name = "i915.mei-gscfi",
> +		.driver_data = MEI_ME_GSCFI_CFG,
> +	},
> +	{
> +		/* sentinel */
> +	}
> +};
> +MODULE_DEVICE_TABLE(auxiliary, mei_gsc_id_table);
> +
> +static struct auxiliary_driver mei_gsc_driver = {
> +	.probe	= mei_gsc_probe,
> +	.remove = mei_gsc_remove,
> +	.driver = {
> +		/* auxiliary_driver_register() sets .name to be the modname */
> +		.pm = &mei_gsc_pm_ops,
> +	},
> +	.id_table = mei_gsc_id_table
> +};
> +module_auxiliary_driver(mei_gsc_driver);
> +
> +MODULE_AUTHOR("Intel Corporation");
> +MODULE_ALIAS("auxiliary:i915.mei-gsc");
> +MODULE_ALIAS("auxiliary:i915.mei-gscfi");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
> index d3a6c0728645..9748d14849a1 100644
> --- a/drivers/misc/mei/hw-me.c
> +++ b/drivers/misc/mei/hw-me.c
> @@ -1226,6 +1226,7 @@ irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id)
>   	me_intr_disable(dev, hcsr);
>   	return IRQ_WAKE_THREAD;
>   }
> +EXPORT_SYMBOL_GPL(mei_me_irq_quick_handler);
>   
>   /**
>    * mei_me_irq_thread_handler - function called after ISR to handle the interrupt
> @@ -1320,6 +1321,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
>   	mutex_unlock(&dev->device_lock);
>   	return IRQ_HANDLED;
>   }
> +EXPORT_SYMBOL_GPL(mei_me_irq_thread_handler);
>   
>   static const struct mei_hw_ops mei_me_hw_ops = {
>   
> @@ -1433,6 +1435,12 @@ static bool mei_me_fw_type_sps(const struct pci_dev *pdev)
>   #define MEI_CFG_KIND_ITOUCH                     \
>   	.kind = "itouch"
>   
> +#define MEI_CFG_TYPE_GSC                        \
> +	.kind = "gsc"
> +
> +#define MEI_CFG_TYPE_GSCFI                      \
> +	.kind = "gscfi"
> +
>   #define MEI_CFG_FW_SPS                          \
>   	.quirk_probe = mei_me_fw_type_sps
>   
> @@ -1565,6 +1573,18 @@ static const struct mei_cfg mei_me_pch15_sps_cfg = {
>   	MEI_CFG_FW_SPS,
>   };
>   
> +/* Graphics System Controller */
> +static const struct mei_cfg mei_me_gsc_cfg = {
> +	MEI_CFG_TYPE_GSC,
> +	MEI_CFG_PCH8_HFS,
> +};
> +
> +/* Graphics System Controller Firmware Interface */
> +static const struct mei_cfg mei_me_gscfi_cfg = {
> +	MEI_CFG_TYPE_GSCFI,
> +	MEI_CFG_PCH8_HFS,
> +};
> +
>   /*
>    * mei_cfg_list - A list of platform platform specific configurations.
>    * Note: has to be synchronized with  enum mei_cfg_idx.
> @@ -1585,6 +1605,8 @@ static const struct mei_cfg *const mei_cfg_list[] = {
>   	[MEI_ME_PCH12_SPS_ITOUCH_CFG] = &mei_me_pch12_itouch_sps_cfg,
>   	[MEI_ME_PCH15_CFG] = &mei_me_pch15_cfg,
>   	[MEI_ME_PCH15_SPS_CFG] = &mei_me_pch15_sps_cfg,
> +	[MEI_ME_GSC_CFG] = &mei_me_gsc_cfg,
> +	[MEI_ME_GSCFI_CFG] = &mei_me_gscfi_cfg,
>   };
>   
>   const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx)
> @@ -1595,7 +1617,8 @@ const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx)
>   		return NULL;
>   
>   	return mei_cfg_list[idx];
> -};
> +}
> +EXPORT_SYMBOL_GPL(mei_me_get_cfg);
>   
>   /**
>    * mei_me_dev_init - allocates and initializes the mei device structure
> @@ -1630,4 +1653,4 @@ struct mei_device *mei_me_dev_init(struct device *parent,
>   
>   	return dev;
>   }
> -
> +EXPORT_SYMBOL_GPL(mei_me_dev_init);
> diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
> index 00a7132ac7a2..a071c645e905 100644
> --- a/drivers/misc/mei/hw-me.h
> +++ b/drivers/misc/mei/hw-me.h
> @@ -112,6 +112,8 @@ enum mei_cfg_idx {
>   	MEI_ME_PCH12_SPS_ITOUCH_CFG,
>   	MEI_ME_PCH15_CFG,
>   	MEI_ME_PCH15_SPS_CFG,
> +	MEI_ME_GSC_CFG,
> +	MEI_ME_GSCFI_CFG,
>   	MEI_ME_NUM_CFG,
>   };
>   


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 3/5] mei: gsc: setup char driver alive in spite of firmware handshake failure
  2022-03-08 16:36   ` [Intel-gfx] " Alexander Usyskin
@ 2022-03-10  0:28     ` Ceraolo Spurio, Daniele
  -1 siblings, 0 replies; 33+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-03-10  0:28 UTC (permalink / raw)
  To: Alexander Usyskin, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: linux-kernel, Tomas Winkler, Vitaly Lubart, intel-gfx



On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> Setup char device in spite of firmware handshake failure.
> In order to provide host access to the firmware status registers and other
> information required for the manufacturing process.

IMO this patch should be moved to after the patch that adds the logic to 
fetch the FW version, as that is interesting info for sysfs. Not a blocker.

>
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>

Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>

Daniele

> ---
>   drivers/misc/mei/gsc-me.c | 11 ++++++-----
>   1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
> index 0afae70e0609..cf427f6fdec9 100644
> --- a/drivers/misc/mei/gsc-me.c
> +++ b/drivers/misc/mei/gsc-me.c
> @@ -79,11 +79,12 @@ static int mei_gsc_probe(struct auxiliary_device *aux_dev,
>   	pm_runtime_set_active(device);
>   	pm_runtime_enable(device);
>   
> -	if (mei_start(dev)) {
> -		dev_err(device, "init hw failure.\n");
> -		ret = -ENODEV;
> -		goto err;
> -	}
> +	/* Continue to char device setup in spite of firmware handshake failure.
> +	 * In order to provide access to the firmware status registers to the user
> +	 * space via sysfs.
> +	 */
> +	if (mei_start(dev))
> +		dev_warn(device, "init hw failure.\n");
>   
>   	pm_runtime_set_autosuspend_delay(device, MEI_GSC_RPM_TIMEOUT);
>   	pm_runtime_use_autosuspend(device);


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 3/5] mei: gsc: setup char driver alive in spite of firmware handshake failure
@ 2022-03-10  0:28     ` Ceraolo Spurio, Daniele
  0 siblings, 0 replies; 33+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-03-10  0:28 UTC (permalink / raw)
  To: Alexander Usyskin, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: Tomas Winkler, intel-gfx, linux-kernel, Vitaly Lubart



On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> Setup char device in spite of firmware handshake failure.
> In order to provide host access to the firmware status registers and other
> information required for the manufacturing process.

IMO this patch should be moved to after the patch that adds the logic to 
fetch the FW version, as that is interesting info for sysfs. Not a blocker.

>
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>

Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>

Daniele

> ---
>   drivers/misc/mei/gsc-me.c | 11 ++++++-----
>   1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
> index 0afae70e0609..cf427f6fdec9 100644
> --- a/drivers/misc/mei/gsc-me.c
> +++ b/drivers/misc/mei/gsc-me.c
> @@ -79,11 +79,12 @@ static int mei_gsc_probe(struct auxiliary_device *aux_dev,
>   	pm_runtime_set_active(device);
>   	pm_runtime_enable(device);
>   
> -	if (mei_start(dev)) {
> -		dev_err(device, "init hw failure.\n");
> -		ret = -ENODEV;
> -		goto err;
> -	}
> +	/* Continue to char device setup in spite of firmware handshake failure.
> +	 * In order to provide access to the firmware status registers to the user
> +	 * space via sysfs.
> +	 */
> +	if (mei_start(dev))
> +		dev_warn(device, "init hw failure.\n");
>   
>   	pm_runtime_set_autosuspend_delay(device, MEI_GSC_RPM_TIMEOUT);
>   	pm_runtime_use_autosuspend(device);


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 5/5] mei: gsc: retrieve the firmware version
  2022-03-08 16:36   ` [Intel-gfx] " Alexander Usyskin
@ 2022-03-10  1:14     ` Ceraolo Spurio, Daniele
  -1 siblings, 0 replies; 33+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-03-10  1:14 UTC (permalink / raw)
  To: Alexander Usyskin, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: intel-gfx, linux-kernel, Tomas Winkler, Vitaly Lubart



On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> Add a hook to retrieve the firmware version of the
> GSC devices to bus-fixup.
> GSC has a different MKHI clients GUIDs but the same message structure
> to retrieve the firmware version as MEI so mei_fwver() can be reused.
>
> CC: Ashutosh Dixit <ashutosh.dixit@intel.com>
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> ---
>   drivers/misc/mei/bus-fixup.c | 25 +++++++++++++++++++++++++
>   drivers/misc/mei/hw-me.c     |  2 ++
>   2 files changed, 27 insertions(+)
>
> diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c
> index 67844089db21..59506ba6fc48 100644
> --- a/drivers/misc/mei/bus-fixup.c
> +++ b/drivers/misc/mei/bus-fixup.c
> @@ -30,6 +30,12 @@ static const uuid_le mei_nfc_info_guid = MEI_UUID_NFC_INFO;
>   #define MEI_UUID_MKHIF_FIX UUID_LE(0x55213584, 0x9a29, 0x4916, \
>   			0xba, 0xdf, 0xf, 0xb7, 0xed, 0x68, 0x2a, 0xeb)
>   
> +#define MEI_UUID_IGSC_MKHI UUID_LE(0xE2C2AFA2, 0x3817, 0x4D19, \
> +			0x9D, 0x95, 0x06, 0xB1, 0x6B, 0x58, 0x8A, 0x5D)
> +
> +#define MEI_UUID_IGSC_MKHI_FIX UUID_LE(0x46E0C1FB, 0xA546, 0x414F, \
> +			0x91, 0x70, 0xB7, 0xF4, 0x6D, 0x57, 0xB4, 0xAD)
> +

These matches what the HW is reporting as sub-devices got gscfi and gsc 
respectively. I think we could use a comment to make which matches what 
clearer, but anyway:

Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>

>   #define MEI_UUID_HDCP UUID_LE(0xB638AB7E, 0x94E2, 0x4EA2, \
>   			      0xA5, 0x52, 0xD1, 0xC5, 0x4B, 0x62, 0x7F, 0x04)
>   
> @@ -241,6 +247,23 @@ static void mei_mkhi_fix(struct mei_cl_device *cldev)
>   	mei_cldev_disable(cldev);
>   }
>   
> +static void mei_gsc_mkhi_ver(struct mei_cl_device *cldev)
> +{
> +	int ret;
> +
> +	/* No need to enable the client if nothing is needed from it */
> +	if (!cldev->bus->fw_f_fw_ver_supported)
> +		return;
> +
> +	ret = mei_cldev_enable(cldev);
> +	if (ret)
> +		return;
> +
> +	ret = mei_fwver(cldev);
> +	if (ret < 0)
> +		dev_err(&cldev->dev, "FW version command failed %d\n", ret);
> +	mei_cldev_disable(cldev);
> +}
>   /**
>    * mei_wd - wd client on the bus, change protocol version
>    *   as the API has changed.
> @@ -492,6 +515,8 @@ static struct mei_fixup {
>   	MEI_FIXUP(MEI_UUID_NFC_HCI, mei_nfc),
>   	MEI_FIXUP(MEI_UUID_WD, mei_wd),
>   	MEI_FIXUP(MEI_UUID_MKHIF_FIX, mei_mkhi_fix),
> +	MEI_FIXUP(MEI_UUID_IGSC_MKHI, mei_gsc_mkhi_ver),
> +	MEI_FIXUP(MEI_UUID_IGSC_MKHI_FIX, mei_gsc_mkhi_ver),
>   	MEI_FIXUP(MEI_UUID_HDCP, whitelist),
>   	MEI_FIXUP(MEI_UUID_ANY, vt_support),
>   	MEI_FIXUP(MEI_UUID_PAVP, whitelist),
> diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
> index 9748d14849a1..7e77328142ff 100644
> --- a/drivers/misc/mei/hw-me.c
> +++ b/drivers/misc/mei/hw-me.c
> @@ -1577,12 +1577,14 @@ static const struct mei_cfg mei_me_pch15_sps_cfg = {
>   static const struct mei_cfg mei_me_gsc_cfg = {
>   	MEI_CFG_TYPE_GSC,
>   	MEI_CFG_PCH8_HFS,
> +	MEI_CFG_FW_VER_SUPP,
>   };
>   
>   /* Graphics System Controller Firmware Interface */
>   static const struct mei_cfg mei_me_gscfi_cfg = {
>   	MEI_CFG_TYPE_GSCFI,
>   	MEI_CFG_PCH8_HFS,
> +	MEI_CFG_FW_VER_SUPP,
>   };
>   
>   /*


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 5/5] mei: gsc: retrieve the firmware version
@ 2022-03-10  1:14     ` Ceraolo Spurio, Daniele
  0 siblings, 0 replies; 33+ messages in thread
From: Ceraolo Spurio, Daniele @ 2022-03-10  1:14 UTC (permalink / raw)
  To: Alexander Usyskin, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: intel-gfx, Tomas Winkler, linux-kernel, Vitaly Lubart



On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> Add a hook to retrieve the firmware version of the
> GSC devices to bus-fixup.
> GSC has a different MKHI clients GUIDs but the same message structure
> to retrieve the firmware version as MEI so mei_fwver() can be reused.
>
> CC: Ashutosh Dixit <ashutosh.dixit@intel.com>
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> ---
>   drivers/misc/mei/bus-fixup.c | 25 +++++++++++++++++++++++++
>   drivers/misc/mei/hw-me.c     |  2 ++
>   2 files changed, 27 insertions(+)
>
> diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c
> index 67844089db21..59506ba6fc48 100644
> --- a/drivers/misc/mei/bus-fixup.c
> +++ b/drivers/misc/mei/bus-fixup.c
> @@ -30,6 +30,12 @@ static const uuid_le mei_nfc_info_guid = MEI_UUID_NFC_INFO;
>   #define MEI_UUID_MKHIF_FIX UUID_LE(0x55213584, 0x9a29, 0x4916, \
>   			0xba, 0xdf, 0xf, 0xb7, 0xed, 0x68, 0x2a, 0xeb)
>   
> +#define MEI_UUID_IGSC_MKHI UUID_LE(0xE2C2AFA2, 0x3817, 0x4D19, \
> +			0x9D, 0x95, 0x06, 0xB1, 0x6B, 0x58, 0x8A, 0x5D)
> +
> +#define MEI_UUID_IGSC_MKHI_FIX UUID_LE(0x46E0C1FB, 0xA546, 0x414F, \
> +			0x91, 0x70, 0xB7, 0xF4, 0x6D, 0x57, 0xB4, 0xAD)
> +

These matches what the HW is reporting as sub-devices got gscfi and gsc 
respectively. I think we could use a comment to make which matches what 
clearer, but anyway:

Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>

>   #define MEI_UUID_HDCP UUID_LE(0xB638AB7E, 0x94E2, 0x4EA2, \
>   			      0xA5, 0x52, 0xD1, 0xC5, 0x4B, 0x62, 0x7F, 0x04)
>   
> @@ -241,6 +247,23 @@ static void mei_mkhi_fix(struct mei_cl_device *cldev)
>   	mei_cldev_disable(cldev);
>   }
>   
> +static void mei_gsc_mkhi_ver(struct mei_cl_device *cldev)
> +{
> +	int ret;
> +
> +	/* No need to enable the client if nothing is needed from it */
> +	if (!cldev->bus->fw_f_fw_ver_supported)
> +		return;
> +
> +	ret = mei_cldev_enable(cldev);
> +	if (ret)
> +		return;
> +
> +	ret = mei_fwver(cldev);
> +	if (ret < 0)
> +		dev_err(&cldev->dev, "FW version command failed %d\n", ret);
> +	mei_cldev_disable(cldev);
> +}
>   /**
>    * mei_wd - wd client on the bus, change protocol version
>    *   as the API has changed.
> @@ -492,6 +515,8 @@ static struct mei_fixup {
>   	MEI_FIXUP(MEI_UUID_NFC_HCI, mei_nfc),
>   	MEI_FIXUP(MEI_UUID_WD, mei_wd),
>   	MEI_FIXUP(MEI_UUID_MKHIF_FIX, mei_mkhi_fix),
> +	MEI_FIXUP(MEI_UUID_IGSC_MKHI, mei_gsc_mkhi_ver),
> +	MEI_FIXUP(MEI_UUID_IGSC_MKHI_FIX, mei_gsc_mkhi_ver),
>   	MEI_FIXUP(MEI_UUID_HDCP, whitelist),
>   	MEI_FIXUP(MEI_UUID_ANY, vt_support),
>   	MEI_FIXUP(MEI_UUID_PAVP, whitelist),
> diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
> index 9748d14849a1..7e77328142ff 100644
> --- a/drivers/misc/mei/hw-me.c
> +++ b/drivers/misc/mei/hw-me.c
> @@ -1577,12 +1577,14 @@ static const struct mei_cfg mei_me_pch15_sps_cfg = {
>   static const struct mei_cfg mei_me_gsc_cfg = {
>   	MEI_CFG_TYPE_GSC,
>   	MEI_CFG_PCH8_HFS,
> +	MEI_CFG_FW_VER_SUPP,
>   };
>   
>   /* Graphics System Controller Firmware Interface */
>   static const struct mei_cfg mei_me_gscfi_cfg = {
>   	MEI_CFG_TYPE_GSCFI,
>   	MEI_CFG_PCH8_HFS,
> +	MEI_CFG_FW_VER_SUPP,
>   };
>   
>   /*


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 4/5] mei: gsc: add runtime pm handlers
  2022-03-08 16:36   ` [Intel-gfx] " Alexander Usyskin
@ 2022-03-10 19:03     ` Rodrigo Vivi
  -1 siblings, 0 replies; 33+ messages in thread
From: Rodrigo Vivi @ 2022-03-10 19:03 UTC (permalink / raw)
  To: Alexander Usyskin
  Cc: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, David Airlie,
	Daniel Vetter, Tvrtko Ursulin, linux-kernel, Tomas Winkler,
	Vitaly Lubart, intel-gfx

On Tue, Mar 08, 2022 at 06:36:53PM +0200, Alexander Usyskin wrote:
> From: Tomas Winkler <tomas.winkler@intel.com>
> 
> Implement runtime handlers for mei-gsc, to track
> idle state of the device properly.
> 
> CC: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> ---
>  drivers/misc/mei/gsc-me.c | 67 ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 66 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
> index cf427f6fdec9..dac482ddab51 100644
> --- a/drivers/misc/mei/gsc-me.c
> +++ b/drivers/misc/mei/gsc-me.c
> @@ -152,7 +152,72 @@ static int __maybe_unused mei_gsc_pm_resume(struct device *device)
>  	return 0;
>  }
>  
> -static SIMPLE_DEV_PM_OPS(mei_gsc_pm_ops, mei_gsc_pm_suspend, mei_gsc_pm_resume);
> +static int __maybe_unused mei_gsc_pm_runtime_idle(struct device *device)
> +{
> +	struct mei_device *dev = dev_get_drvdata(device);
> +
> +	if (!dev)
> +		return -ENODEV;
> +	if (mei_write_is_idle(dev))
> +		pm_runtime_autosuspend(device);

This is not needed. The _idle() callback is called right before the autosuspend.
so you just need to return -EBUSY if not idle.

But also I'm missing the call to enable the autosuspend and set the delay.

Is this flow really working and you are getting device suspended when not in use?
(Maybe it is just my ignorance on other flow types here)

> +
> +	return -EBUSY;
> +}
> +
> +static int  __maybe_unused mei_gsc_pm_runtime_suspend(struct device *device)
> +{
> +	struct mei_device *dev = dev_get_drvdata(device);
> +	struct mei_me_hw *hw;
> +	int ret;
> +
> +	if (!dev)
> +		return -ENODEV;
> +
> +	mutex_lock(&dev->device_lock);
> +
> +	if (mei_write_is_idle(dev)) {
> +		hw = to_me_hw(dev);
> +		hw->pg_state = MEI_PG_ON;
> +		ret = 0;
> +	} else {
> +		ret = -EAGAIN;
> +	}

probably not needed this here... but it would be good if you use
the runtime_pm{get,put} to protect your write operations as well...

> +
> +	mutex_unlock(&dev->device_lock);
> +
> +	return ret;
> +}
> +
> +static int __maybe_unused mei_gsc_pm_runtime_resume(struct device *device)
> +{
> +	struct mei_device *dev = dev_get_drvdata(device);
> +	struct mei_me_hw *hw;
> +	irqreturn_t irq_ret;
> +
> +	if (!dev)
> +		return -ENODEV;
> +
> +	mutex_lock(&dev->device_lock);
> +
> +	hw = to_me_hw(dev);
> +	hw->pg_state = MEI_PG_OFF;
> +
> +	mutex_unlock(&dev->device_lock);
> +
> +	irq_ret = mei_me_irq_thread_handler(1, dev);
> +	if (irq_ret != IRQ_HANDLED)
> +		dev_err(dev->dev, "thread handler fail %d\n", irq_ret);
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops mei_gsc_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(mei_gsc_pm_suspend,
> +				mei_gsc_pm_resume)
> +	SET_RUNTIME_PM_OPS(mei_gsc_pm_runtime_suspend,
> +			   mei_gsc_pm_runtime_resume,
> +			   mei_gsc_pm_runtime_idle)
> +};
>  
>  static const struct auxiliary_device_id mei_gsc_id_table[] = {
>  	{
> -- 
> 2.32.0
> 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 4/5] mei: gsc: add runtime pm handlers
@ 2022-03-10 19:03     ` Rodrigo Vivi
  0 siblings, 0 replies; 33+ messages in thread
From: Rodrigo Vivi @ 2022-03-10 19:03 UTC (permalink / raw)
  To: Alexander Usyskin
  Cc: David Airlie, Greg Kroah-Hartman, intel-gfx, linux-kernel,
	Tomas Winkler, Vitaly Lubart

On Tue, Mar 08, 2022 at 06:36:53PM +0200, Alexander Usyskin wrote:
> From: Tomas Winkler <tomas.winkler@intel.com>
> 
> Implement runtime handlers for mei-gsc, to track
> idle state of the device properly.
> 
> CC: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> ---
>  drivers/misc/mei/gsc-me.c | 67 ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 66 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
> index cf427f6fdec9..dac482ddab51 100644
> --- a/drivers/misc/mei/gsc-me.c
> +++ b/drivers/misc/mei/gsc-me.c
> @@ -152,7 +152,72 @@ static int __maybe_unused mei_gsc_pm_resume(struct device *device)
>  	return 0;
>  }
>  
> -static SIMPLE_DEV_PM_OPS(mei_gsc_pm_ops, mei_gsc_pm_suspend, mei_gsc_pm_resume);
> +static int __maybe_unused mei_gsc_pm_runtime_idle(struct device *device)
> +{
> +	struct mei_device *dev = dev_get_drvdata(device);
> +
> +	if (!dev)
> +		return -ENODEV;
> +	if (mei_write_is_idle(dev))
> +		pm_runtime_autosuspend(device);

This is not needed. The _idle() callback is called right before the autosuspend.
so you just need to return -EBUSY if not idle.

But also I'm missing the call to enable the autosuspend and set the delay.

Is this flow really working and you are getting device suspended when not in use?
(Maybe it is just my ignorance on other flow types here)

> +
> +	return -EBUSY;
> +}
> +
> +static int  __maybe_unused mei_gsc_pm_runtime_suspend(struct device *device)
> +{
> +	struct mei_device *dev = dev_get_drvdata(device);
> +	struct mei_me_hw *hw;
> +	int ret;
> +
> +	if (!dev)
> +		return -ENODEV;
> +
> +	mutex_lock(&dev->device_lock);
> +
> +	if (mei_write_is_idle(dev)) {
> +		hw = to_me_hw(dev);
> +		hw->pg_state = MEI_PG_ON;
> +		ret = 0;
> +	} else {
> +		ret = -EAGAIN;
> +	}

probably not needed this here... but it would be good if you use
the runtime_pm{get,put} to protect your write operations as well...

> +
> +	mutex_unlock(&dev->device_lock);
> +
> +	return ret;
> +}
> +
> +static int __maybe_unused mei_gsc_pm_runtime_resume(struct device *device)
> +{
> +	struct mei_device *dev = dev_get_drvdata(device);
> +	struct mei_me_hw *hw;
> +	irqreturn_t irq_ret;
> +
> +	if (!dev)
> +		return -ENODEV;
> +
> +	mutex_lock(&dev->device_lock);
> +
> +	hw = to_me_hw(dev);
> +	hw->pg_state = MEI_PG_OFF;
> +
> +	mutex_unlock(&dev->device_lock);
> +
> +	irq_ret = mei_me_irq_thread_handler(1, dev);
> +	if (irq_ret != IRQ_HANDLED)
> +		dev_err(dev->dev, "thread handler fail %d\n", irq_ret);
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops mei_gsc_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(mei_gsc_pm_suspend,
> +				mei_gsc_pm_resume)
> +	SET_RUNTIME_PM_OPS(mei_gsc_pm_runtime_suspend,
> +			   mei_gsc_pm_runtime_resume,
> +			   mei_gsc_pm_runtime_idle)
> +};
>  
>  static const struct auxiliary_device_id mei_gsc_id_table[] = {
>  	{
> -- 
> 2.32.0
> 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* RE: [Intel-gfx] [PATCH v10 1/5] drm/i915/gsc: add gsc as a mei auxiliary device
  2022-03-09 22:50     ` Ceraolo Spurio, Daniele
@ 2022-03-13 10:02       ` Usyskin, Alexander
  -1 siblings, 0 replies; 33+ messages in thread
From: Usyskin, Alexander @ 2022-03-13 10:02 UTC (permalink / raw)
  To: Ceraolo Spurio, Daniele, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Vivi, Rodrigo, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: intel-gfx, linux-kernel, Winkler, Tomas, Lubart, Vitaly


> -----Original Message-----
> From: Ceraolo Spurio, Daniele <daniele.ceraolospurio@intel.com>
> Sent: Thursday, March 10, 2022 00:50
> To: Usyskin, Alexander <alexander.usyskin@intel.com>; Greg Kroah-
> Hartman <gregkh@linuxfoundation.org>; Jani Nikula
> <jani.nikula@linux.intel.com>; Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com>; Vivi, Rodrigo <rodrigo.vivi@intel.com>;
> David Airlie <airlied@linux.ie>; Daniel Vetter <daniel@ffwll.ch>; Tvrtko
> Ursulin <tvrtko.ursulin@linux.intel.com>
> Cc: intel-gfx@lists.freedesktop.org; linux-kernel@vger.kernel.org; Winkler,
> Tomas <tomas.winkler@intel.com>; Lubart, Vitaly <vitaly.lubart@intel.com>
> Subject: Re: [Intel-gfx] [PATCH v10 1/5] drm/i915/gsc: add gsc as a mei
> auxiliary device
> 
> 
> 
> On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> > From: Tomas Winkler <tomas.winkler@intel.com>
> >
> > GSC is a graphics system controller, it provides
> > a chassis controller for graphics discrete cards.
> >
> > There are two MEI interfaces in GSC: HECI1 and HECI2.
> >
> > Both interfaces are on the BAR0 at offsets 0x00258000 and 0x00259000.
> > GSC is a GT Engine (class 4: instance 6). HECI1 interrupt is signaled
> > via bit 15 and HECI2 via bit 14 in the interrupt register.
> >
> > This patch exports GSC as auxiliary device for mei driver to bind to
> > for HECI2 interface.
> 
> Do we need a test for this? E.g. to catch the unlikely case where we
> stop exposing the GSC device. We are going to get some indirect coverage
> once we start making use of the PXP interface from within the kernel,
> would that be enough?
> 
The IGT tests checks that there is no dmesg errors in many error flows.
Do not think that we need special functional tests.

> Also, IMO we need a line here to explain that we're adding the code for
> HECI1 as well because we plan to follow up with it soon.
> 
Will add such line

> >
> > CC: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> > Signed-off-by: Vitaly Lubart <vitaly.lubart@intel.com>
> > Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> > Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> > ---
> >   MAINTAINERS                              |   1 +
> >   drivers/gpu/drm/i915/Kconfig             |   1 +
> >   drivers/gpu/drm/i915/Makefile            |   3 +
> >   drivers/gpu/drm/i915/gt/intel_gsc.c      | 204
> +++++++++++++++++++++++
> >   drivers/gpu/drm/i915/gt/intel_gsc.h      |  37 ++++
> >   drivers/gpu/drm/i915/gt/intel_gt.c       |   3 +
> >   drivers/gpu/drm/i915/gt/intel_gt.h       |   5 +
> >   drivers/gpu/drm/i915/gt/intel_gt_irq.c   |  13 ++
> >   drivers/gpu/drm/i915/gt/intel_gt_regs.h  |   1 +
> >   drivers/gpu/drm/i915/gt/intel_gt_types.h |   2 +
> >   drivers/gpu/drm/i915/i915_drv.h          |   8 +
> >   drivers/gpu/drm/i915/i915_pci.c          |   3 +-
> >   drivers/gpu/drm/i915/i915_reg.h          |   2 +
> >   drivers/gpu/drm/i915/intel_device_info.h |   2 +
> >   include/linux/mei_aux.h                  |  19 +++
> >   15 files changed, 303 insertions(+), 1 deletion(-)
> >   create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.c
> >   create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.h
> >   create mode 100644 include/linux/mei_aux.h
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 2b1d296f92e9..d322e630d1d1 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -9822,6 +9822,7 @@ S:	Supported
> >   F:	Documentation/driver-api/mei/*
> >   F:	drivers/misc/mei/
> >   F:	drivers/watchdog/mei_wdt.c
> > +F:	include/linux/mei_aux.h
> >   F:	include/linux/mei_cl_bus.h
> >   F:	include/uapi/linux/mei.h
> >   F:	samples/mei/*
> > diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
> > index 98c5450b8eac..2660a85175d9 100644
> > --- a/drivers/gpu/drm/i915/Kconfig
> > +++ b/drivers/gpu/drm/i915/Kconfig
> > @@ -30,6 +30,7 @@ config DRM_I915
> >   	select VMAP_PFN
> >   	select DRM_TTM
> >   	select DRM_BUDDY
> > +	select AUXILIARY_BUS
> >   	help
> >   	  Choose this option if you have a system that has "Intel Graphics
> >   	  Media Accelerator" or "HD Graphics" integrated graphics,
> > diff --git a/drivers/gpu/drm/i915/Makefile
> b/drivers/gpu/drm/i915/Makefile
> > index 1a771ee5b1d0..9be7b13d8822 100644
> > --- a/drivers/gpu/drm/i915/Makefile
> > +++ b/drivers/gpu/drm/i915/Makefile
> > @@ -196,6 +196,9 @@ i915-y += gt/uc/intel_uc.o \
> >   	  gt/uc/intel_huc_debugfs.o \
> >   	  gt/uc/intel_huc_fw.o
> >
> > +# graphics system controller (GSC) support
> > +i915-y += gt/intel_gsc.o
> > +
> >   # modesetting core code
> >   i915-y += \
> >   	display/hsw_ips.o \
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.c
> b/drivers/gpu/drm/i915/gt/intel_gsc.c
> > new file mode 100644
> > index 000000000000..152804e7c41a
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/gt/intel_gsc.c
> > @@ -0,0 +1,204 @@
> > +// SPDX-License-Identifier: MIT
> > +/*
> > + * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
> > + */
> > +
> > +#include <linux/irq.h>
> > +#include <linux/mei_aux.h>
> > +#include "i915_reg.h"
> > +#include "i915_drv.h"
> > +#include "gt/intel_gt.h"
> > +#include "intel_gsc.h"
> 
> A bit of inconsistency here because intel_gsc.h and intel_gt.h are both
> in the gt/ folder but you're only prefixing one with gt/. Also, we
> usually try to keep includes in alphabetical order, but overall not a
> blocker for me.
> 
Well set both to gt/ and reshuffle.

> > +
> > +#define GSC_BAR_LENGTH  0x00000FFC
> > +
> > +static void gsc_irq_mask(struct irq_data *d)
> > +{
> > +	/* generic irq handling */
> > +}
> > +
> > +static void gsc_irq_unmask(struct irq_data *d)
> > +{
> > +	/* generic irq handling */
> > +}
> > +
> > +static struct irq_chip gsc_irq_chip = {
> > +	.name = "gsc_irq_chip",
> > +	.irq_mask = gsc_irq_mask,
> > +	.irq_unmask = gsc_irq_unmask,
> > +};
> > +
> > +static int gsc_irq_init(int irq)
> > +{
> > +	irq_set_chip_and_handler_name(irq, &gsc_irq_chip,
> > +				      handle_simple_irq, "gsc_irq_handler");
> > +
> > +	return irq_set_chip_data(irq, NULL);
> > +}
> > +
> > +struct intel_gsc_def {
> > +	const char *name;
> > +	unsigned long bar;
> > +	size_t bar_size;
> > +};
> > +
> > +/* gscfi (graphics system controller firmware interface) resources */
> 
> Should this comment be moved down in the array? the array has sections
> for both pxp and gscfi resources, even if the former are not set. Or
> maybe expand to something like:
> 
> /* for DG1 we only need gscfi (....) resources */
> 
I'll change it to describe the array in whole

> > +static const struct intel_gsc_def intel_gsc_def_dg1[] = {
> > +	{
> > +		/* HECI1 not yet implemented. */
> > +	},
> > +	{
> > +		.name = "mei-gscfi",
> > +		.bar = GSC_DG1_HECI2_BASE,
> > +		.bar_size = GSC_BAR_LENGTH,
> > +	}
> > +};
> > +
> > +static void intel_gsc_release_dev(struct device *dev)
> 
> We usually avoid the intel_* prefix for static functions. Same for other
> functions below.
> 
Ok, will drop intel_ prefix from static

> > +{
> > +	struct auxiliary_device *aux_dev = to_auxiliary_dev(dev);
> > +	struct mei_aux_device *adev =
> auxiliary_dev_to_mei_aux_dev(aux_dev);
> > +
> > +	kfree(adev);
> > +}
> > +
> > +static void intel_gsc_destroy_one(struct intel_gsc_intf *intf)
> > +{
> > +	if (intf->adev) {
> > +		auxiliary_device_delete(&intf->adev->aux_dev);
> > +		auxiliary_device_uninit(&intf->adev->aux_dev);
> > +		intf->adev = NULL;
> > +	}
> > +	if (intf->irq >= 0)
> > +		irq_free_desc(intf->irq);
> > +	intf->irq = -1;
> > +}
> > +
> > +static void intel_gsc_init_one(struct drm_i915_private *i915,
> > +			       struct intel_gsc_intf *intf,
> > +			       unsigned int intf_id)
> > +{
> > +	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
> > +	struct mei_aux_device *adev;
> > +	struct auxiliary_device *aux_dev;
> > +	const struct intel_gsc_def *def;
> > +	int ret;
> > +
> > +	intf->irq = -1;
> > +	intf->id = intf_id;
> > +
> > +	if (intf_id == 0 && !HAS_HECI_PXP(i915))
> > +		return;
> > +
> > +	def = &intel_gsc_def_dg1[intf_id];
> > +
> > +	if (!def->name) {
> > +		drm_warn_once(&i915->drm, "HECI%d is not
> implemented!\n", intf_id + 1);
> > +		return;
> > +	}
> > +
> > +	intf->irq = irq_alloc_desc(0);
> > +	if (intf->irq < 0) {
> > +		drm_err(&i915->drm, "gsc irq error %d\n", intf->irq);
> > +		return;
> > +	}
> > +
> > +	ret = gsc_irq_init(intf->irq);
> > +	if (ret < 0) {
> > +		drm_err(&i915->drm, "gsc irq init failed %d\n", ret);
> > +		goto fail;
> > +	}
> > +
> > +	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
> > +	if (!adev)
> > +		goto fail;
> > +
> > +	adev->irq = intf->irq;
> > +	adev->bar.parent = &pdev->resource[0];
> > +	adev->bar.start = def->bar + pdev->resource[0].start;
> > +	adev->bar.end = adev->bar.start + def->bar_size - 1;
> > +	adev->bar.flags = IORESOURCE_MEM;
> > +	adev->bar.desc = IORES_DESC_NONE;
> > +
> > +	aux_dev = &adev->aux_dev;
> > +	aux_dev->name = def->name;
> > +	aux_dev->id = (pci_domain_nr(pdev->bus) << 16) |
> > +		      PCI_DEVID(pdev->bus->number, pdev->devfn);
> > +	aux_dev->dev.parent = &pdev->dev;
> > +	aux_dev->dev.release = intel_gsc_release_dev;
> > +
> > +	ret = auxiliary_device_init(aux_dev);
> > +	if (ret < 0) {
> > +		drm_err(&i915->drm, "gsc aux init failed %d\n", ret);
> > +		kfree(adev);
> > +		goto fail;
> > +	}
> > +
> > +	ret = auxiliary_device_add(aux_dev);
> > +	if (ret < 0) {
> > +		drm_err(&i915->drm, "gsc aux add failed %d\n", ret);
> > +		/* adev will be freed with the put_device() and .release
> sequence */
> > +		auxiliary_device_uninit(aux_dev);
> > +		goto fail;
> > +	}
> > +	intf->adev = adev;
> > +
> > +	return;
> > +fail:
> > +	intel_gsc_destroy_one(intf);
> > +}
> > +
> > +static void gsc_irq_handler(struct intel_gt *gt, unsigned int intf_id)
> > +{
> > +	int ret;
> > +
> > +	if (intf_id >= INTEL_GSC_NUM_INTERFACES) {
> > +		drm_warn_once(&gt->i915->drm, "GSC irq: intf_id %d is out
> of range", intf_id);
> > +		return;
> > +	}
> > +
> > +	if (!HAS_HECI_GSC(gt->i915)) {
> > +		drm_warn_once(&gt->i915->drm, "GSC irq: not supported");
> > +		return;
> > +	}
> > +
> > +	if (gt->gsc.intf[intf_id].irq < 0) {
> > +		drm_err_ratelimited(&gt->i915->drm, "GSC irq: irq not set");
> > +		return;
> > +	}
> > +
> > +	ret = generic_handle_irq(gt->gsc.intf[intf_id].irq);
> > +	if (ret)
> > +		drm_err_ratelimited(&gt->i915->drm, "error handling GSC
> irq: %d\n", ret);
> > +}
> > +
> > +void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir)
> > +{
> > +	if (iir & GSC_IRQ_INTF(0))
> > +		gsc_irq_handler(gt, 0);
> > +	if (iir & GSC_IRQ_INTF(1))
> > +		gsc_irq_handler(gt, 1);
> > +}
> > +
> > +void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private *i915)
> > +{
> > +	unsigned int i;
> > +
> > +	if (!HAS_HECI_GSC(i915))
> > +		return;
> > +
> > +	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
> > +		intel_gsc_init_one(i915, &gsc->intf[i], i);
> > +}
> > +
> > +void intel_gsc_fini(struct intel_gsc *gsc)
> > +{
> > +	struct intel_gt *gt = gsc_to_gt(gsc);
> > +	unsigned int i;
> > +
> > +	if (!HAS_HECI_GSC(gt->i915))
> > +		return;
> > +
> > +	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
> > +		intel_gsc_destroy_one(&gsc->intf[i]);
> > +}
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.h
> b/drivers/gpu/drm/i915/gt/intel_gsc.h
> > new file mode 100644
> > index 000000000000..68582f912b21
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/gt/intel_gsc.h
> > @@ -0,0 +1,37 @@
> > +/* SPDX-License-Identifier: MIT */
> > +/*
> > + * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
> > + */
> > +#ifndef __INTEL_GSC_DEV_H__
> > +#define __INTEL_GSC_DEV_H__
> > +
> > +#include <linux/types.h>
> > +
> > +struct drm_i915_private;
> > +struct intel_gt;
> > +struct mei_aux_device;
> > +
> > +#define INTEL_GSC_NUM_INTERFACES 2
> > +/*
> > + * The HECI1 bit corresponds to bit15 and HECI2 to bit14.
> > + * The reason for this is to allow growth for more interfaces in the future.
> > + */
> > +#define GSC_IRQ_INTF(_x)  BIT(15 - (_x))
> > +
> > +/**
> > + * struct intel_gsc - graphics security controller
> > + * @intf : gsc interface
> > + */
> > +struct intel_gsc {
> > +	struct intel_gsc_intf {
> > +		struct mei_aux_device *adev;
> > +		int irq;
> > +		unsigned int id;
> > +	} intf[INTEL_GSC_NUM_INTERFACES];
> > +};
> > +
> > +void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private
> *dev_priv);
> > +void intel_gsc_fini(struct intel_gsc *gsc);
> > +void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir);
> > +
> > +#endif /* __INTEL_GSC_DEV_H__ */
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c
> b/drivers/gpu/drm/i915/gt/intel_gt.c
> > index 8a2483ccbfb9..fd83ab4b8849 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt.c
> > @@ -444,6 +444,8 @@ void intel_gt_chipset_flush(struct intel_gt *gt)
> >
> >   void intel_gt_driver_register(struct intel_gt *gt)
> >   {
> > +	intel_gsc_init(&gt->gsc, gt->i915);
> > +
> >   	intel_rps_driver_register(&gt->rps);
> >
> >   	intel_gt_debugfs_register(gt);
> > @@ -766,6 +768,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
> >   	intel_wakeref_t wakeref;
> >
> >   	intel_rps_driver_unregister(&gt->rps);
> > +	intel_gsc_fini(&gt->gsc);
> >
> >   	intel_pxp_fini(&gt->pxp);
> >
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h
> b/drivers/gpu/drm/i915/gt/intel_gt.h
> > index 0f571c8ee22b..de779a505c21 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt.h
> > @@ -34,6 +34,11 @@ static inline struct intel_gt *huc_to_gt(struct
> intel_huc *huc)
> >   	return container_of(huc, struct intel_gt, uc.huc);
> >   }
> >
> > +static inline struct intel_gt *gsc_to_gt(struct intel_gsc *gsc)
> > +{
> > +	return container_of(gsc, struct intel_gt, gsc);
> > +}
> > +
> >   void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915);
> >   void __intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private
> *i915);
> >   int intel_gt_assign_ggtt(struct intel_gt *gt);
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> > index e443ac4c8059..917b85d0c189 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> > @@ -68,6 +68,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8
> instance,
> >   	if (instance == OTHER_KCR_INSTANCE)
> >   		return intel_pxp_irq_handler(&gt->pxp, iir);
> >
> > +	if (instance == OTHER_GSC_INSTANCE)
> > +		return intel_gsc_irq_handler(gt, iir);
> > +
> >   	WARN_ONCE(1, "unhandled other interrupt instance=0x%x,
> iir=0x%x\n",
> >   		  instance, iir);
> >   }
> > @@ -184,6 +187,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
> >   	intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE,	  0);
> >   	if (CCS_MASK(gt))
> >   		intel_uncore_write(uncore,
> GEN12_CCS_RSVD_INTR_ENABLE, 0);
> > +	if (HAS_HECI_GSC(gt->i915))
> > +		intel_uncore_write(uncore,
> GEN11_GUNIT_CSME_INTR_ENABLE, 0);
> >
> >   	/* Restore masks irqs on RCS, BCS, VCS and VECS engines. */
> >   	intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK,	~0);
> > @@ -201,6 +206,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
> >   		intel_uncore_write(uncore,
> GEN12_CCS0_CCS1_INTR_MASK, ~0);
> >   	if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3))
> >   		intel_uncore_write(uncore,
> GEN12_CCS2_CCS3_INTR_MASK, ~0);
> > +	if (HAS_HECI_GSC(gt->i915))
> > +		intel_uncore_write(uncore,
> GEN11_GUNIT_CSME_INTR_MASK, ~0);
> >
> >   	intel_uncore_write(uncore,
> GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0);
> >   	intel_uncore_write(uncore,
> GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
> > @@ -215,6 +222,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
> >   {
> >   	struct intel_uncore *uncore = gt->uncore;
> >   	u32 irqs = GT_RENDER_USER_INTERRUPT;
> > +	const u32 gsc_mask = GSC_IRQ_INTF(0) | GSC_IRQ_INTF(1);
> >   	u32 dmask;
> >   	u32 smask;
> >
> > @@ -233,6 +241,9 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
> >   	intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE,
> dmask);
> >   	if (CCS_MASK(gt))
> >   		intel_uncore_write(uncore,
> GEN12_CCS_RSVD_INTR_ENABLE, smask);
> > +	if (HAS_HECI_GSC(gt->i915))
> > +		intel_uncore_write(uncore,
> GEN11_GUNIT_CSME_INTR_ENABLE,
> > +				   gsc_mask);
> >
> >   	/* Unmask irqs on RCS, BCS, VCS and VECS engines. */
> >   	intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK,
> ~smask);
> > @@ -250,6 +261,8 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
> >   		intel_uncore_write(uncore,
> GEN12_CCS0_CCS1_INTR_MASK, ~dmask);
> >   	if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3))
> >   		intel_uncore_write(uncore,
> GEN12_CCS2_CCS3_INTR_MASK, ~dmask);
> > +	if (HAS_HECI_GSC(gt->i915))
> > +		intel_uncore_write(uncore,
> GEN11_GUNIT_CSME_INTR_MASK, 0);
> 
> This should be ~gsc_mask, right?
> 
Yes, sure, rebase fallout. Thanks for catching this!

> >
> >   	/*
> >   	 * RPS interrupts will get enabled/disabled on demand when RPS
> itself
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > index 19cd34f24263..a277fb480cc8 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > @@ -1483,6 +1483,7 @@
> >   #define   OTHER_GUC_INSTANCE			0
> >   #define   OTHER_GTPM_INSTANCE			1
> >   #define   OTHER_KCR_INSTANCE			4
> > +#define   OTHER_GSC_INSTANCE			6
> >
> >   #define GEN11_IIR_REG_SELECTOR(x)		_MMIO(0x190070 +
> ((x) * 4))
> >
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h
> b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> > index f20687796490..5556d55f76ea 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> > @@ -16,6 +16,7 @@
> >   #include <linux/workqueue.h>
> >
> >   #include "uc/intel_uc.h"
> > +#include "intel_gsc.h"
> >
> >   #include "i915_vma.h"
> >   #include "intel_engine_types.h"
> > @@ -72,6 +73,7 @@ struct intel_gt {
> >   	struct i915_ggtt *ggtt;
> >
> >   	struct intel_uc uc;
> > +	struct intel_gsc gsc;
> >
> >   	struct mutex tlb_invalidate_lock;
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> > index 943267393ecb..1c000c15493d 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1327,6 +1327,14 @@ IS_SUBPLATFORM(const struct
> drm_i915_private *i915,
> >
> >   #define HAS_DMC(dev_priv)	(INTEL_INFO(dev_priv)-
> >display.has_dmc)
> >
> > +#define HAS_HECI_PXP(dev_priv) \
> > +	(INTEL_INFO(dev_priv)->has_heci_pxp)
> > +
> > +#define HAS_HECI_GSCFI(dev_priv) \
> > +	(INTEL_INFO(dev_priv)->has_heci_gscfi)
> > +
> > +#define HAS_HECI_GSC(dev_priv) (HAS_HECI_PXP(dev_priv) ||
> HAS_HECI_GSCFI(dev_priv))
> > +
> >   #define HAS_MSO(i915)		(DISPLAY_VER(i915) >= 12)
> >
> >   #define HAS_RUNTIME_PM(dev_priv) (INTEL_INFO(dev_priv)-
> >has_runtime_pm)
> > diff --git a/drivers/gpu/drm/i915/i915_pci.c
> b/drivers/gpu/drm/i915/i915_pci.c
> > index 67b89769f577..a948f566bd3d 100644
> > --- a/drivers/gpu/drm/i915/i915_pci.c
> > +++ b/drivers/gpu/drm/i915/i915_pci.c
> > @@ -901,7 +901,8 @@ static const struct intel_device_info rkl_info = {
> >   	.has_llc = 0, \
> >   	.has_pxp = 0, \
> >   	.has_snoop = 1, \
> > -	.is_dgfx = 1
> > +	.is_dgfx = 1, \
> > +	.has_heci_gscfi = 1
> >
> >   static const struct intel_device_info dg1_info = {
> >   	GEN12_FEATURES,
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> > index 70484f6f2b8b..0ed305ff07a9 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -975,6 +975,8 @@
> >   #define GEN12_COMPUTE1_RING_BASE	0x1c000
> >   #define GEN12_COMPUTE2_RING_BASE	0x1e000
> >   #define GEN12_COMPUTE3_RING_BASE	0x26000
> > +#define GSC_DG1_HECI1_BASE	0x00258000
> 
> Do we need the DG1 HECI1 base definition, considering we're not adding
> HECI1 support for DG1?

There are other usages of this offset in follow up patches also when
MEI is not going to support this interface.

> Also, we usually put the platform name (DG1) before the unit (GSC) in
> our defines, so DG1_GSC_HECI* would probably be more inline with the
> rest of the defs.

Will rename as suggested

> 
> > +#define GSC_DG1_HECI2_BASE	0x00259000
> >   #define BLT_RING_BASE		0x22000
> 
> IMO better to move the GSC defs to after the BLT, that way we don't
> separate it from the other RING_BASE definitions, given that the GSC is
> not a RING and its base is something different. Not a blocker.
> 

Sure, will move as rebasing anyway

> Daniele
> 
> >
> >
> > diff --git a/drivers/gpu/drm/i915/intel_device_info.h
> b/drivers/gpu/drm/i915/intel_device_info.h
> > index f9b955810593..576d15a04c9e 100644
> > --- a/drivers/gpu/drm/i915/intel_device_info.h
> > +++ b/drivers/gpu/drm/i915/intel_device_info.h
> > @@ -141,6 +141,8 @@ enum intel_ppgtt_type {
> >   	func(has_flat_ccs); \
> >   	func(has_global_mocs); \
> >   	func(has_gt_uc); \
> > +	func(has_heci_pxp); \
> > +	func(has_heci_gscfi); \
> >   	func(has_guc_deprivilege); \
> >   	func(has_l3_dpf); \
> >   	func(has_llc); \
> > diff --git a/include/linux/mei_aux.h b/include/linux/mei_aux.h
> > new file mode 100644
> > index 000000000000..587f25128848
> > --- /dev/null
> > +++ b/include/linux/mei_aux.h
> > @@ -0,0 +1,19 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2022, Intel Corporation. All rights reserved.
> > + */
> > +#ifndef _LINUX_MEI_AUX_H
> > +#define _LINUX_MEI_AUX_H
> > +
> > +#include <linux/auxiliary_bus.h>
> > +
> > +struct mei_aux_device {
> > +	struct auxiliary_device aux_dev;
> > +	int irq;
> > +	struct resource bar;
> > +};
> > +
> > +#define auxiliary_dev_to_mei_aux_dev(auxiliary_dev) \
> > +	container_of(auxiliary_dev, struct mei_aux_device, aux_dev)
> > +
> > +#endif /* _LINUX_MEI_AUX_H */

-- 
Thanks,
Sasha



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 1/5] drm/i915/gsc: add gsc as a mei auxiliary device
@ 2022-03-13 10:02       ` Usyskin, Alexander
  0 siblings, 0 replies; 33+ messages in thread
From: Usyskin, Alexander @ 2022-03-13 10:02 UTC (permalink / raw)
  To: Ceraolo Spurio, Daniele, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Vivi, Rodrigo, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: intel-gfx, Winkler, Tomas, linux-kernel, Lubart, Vitaly


> -----Original Message-----
> From: Ceraolo Spurio, Daniele <daniele.ceraolospurio@intel.com>
> Sent: Thursday, March 10, 2022 00:50
> To: Usyskin, Alexander <alexander.usyskin@intel.com>; Greg Kroah-
> Hartman <gregkh@linuxfoundation.org>; Jani Nikula
> <jani.nikula@linux.intel.com>; Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com>; Vivi, Rodrigo <rodrigo.vivi@intel.com>;
> David Airlie <airlied@linux.ie>; Daniel Vetter <daniel@ffwll.ch>; Tvrtko
> Ursulin <tvrtko.ursulin@linux.intel.com>
> Cc: intel-gfx@lists.freedesktop.org; linux-kernel@vger.kernel.org; Winkler,
> Tomas <tomas.winkler@intel.com>; Lubart, Vitaly <vitaly.lubart@intel.com>
> Subject: Re: [Intel-gfx] [PATCH v10 1/5] drm/i915/gsc: add gsc as a mei
> auxiliary device
> 
> 
> 
> On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> > From: Tomas Winkler <tomas.winkler@intel.com>
> >
> > GSC is a graphics system controller, it provides
> > a chassis controller for graphics discrete cards.
> >
> > There are two MEI interfaces in GSC: HECI1 and HECI2.
> >
> > Both interfaces are on the BAR0 at offsets 0x00258000 and 0x00259000.
> > GSC is a GT Engine (class 4: instance 6). HECI1 interrupt is signaled
> > via bit 15 and HECI2 via bit 14 in the interrupt register.
> >
> > This patch exports GSC as auxiliary device for mei driver to bind to
> > for HECI2 interface.
> 
> Do we need a test for this? E.g. to catch the unlikely case where we
> stop exposing the GSC device. We are going to get some indirect coverage
> once we start making use of the PXP interface from within the kernel,
> would that be enough?
> 
The IGT tests checks that there is no dmesg errors in many error flows.
Do not think that we need special functional tests.

> Also, IMO we need a line here to explain that we're adding the code for
> HECI1 as well because we plan to follow up with it soon.
> 
Will add such line

> >
> > CC: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> > Signed-off-by: Vitaly Lubart <vitaly.lubart@intel.com>
> > Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> > Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> > ---
> >   MAINTAINERS                              |   1 +
> >   drivers/gpu/drm/i915/Kconfig             |   1 +
> >   drivers/gpu/drm/i915/Makefile            |   3 +
> >   drivers/gpu/drm/i915/gt/intel_gsc.c      | 204
> +++++++++++++++++++++++
> >   drivers/gpu/drm/i915/gt/intel_gsc.h      |  37 ++++
> >   drivers/gpu/drm/i915/gt/intel_gt.c       |   3 +
> >   drivers/gpu/drm/i915/gt/intel_gt.h       |   5 +
> >   drivers/gpu/drm/i915/gt/intel_gt_irq.c   |  13 ++
> >   drivers/gpu/drm/i915/gt/intel_gt_regs.h  |   1 +
> >   drivers/gpu/drm/i915/gt/intel_gt_types.h |   2 +
> >   drivers/gpu/drm/i915/i915_drv.h          |   8 +
> >   drivers/gpu/drm/i915/i915_pci.c          |   3 +-
> >   drivers/gpu/drm/i915/i915_reg.h          |   2 +
> >   drivers/gpu/drm/i915/intel_device_info.h |   2 +
> >   include/linux/mei_aux.h                  |  19 +++
> >   15 files changed, 303 insertions(+), 1 deletion(-)
> >   create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.c
> >   create mode 100644 drivers/gpu/drm/i915/gt/intel_gsc.h
> >   create mode 100644 include/linux/mei_aux.h
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 2b1d296f92e9..d322e630d1d1 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -9822,6 +9822,7 @@ S:	Supported
> >   F:	Documentation/driver-api/mei/*
> >   F:	drivers/misc/mei/
> >   F:	drivers/watchdog/mei_wdt.c
> > +F:	include/linux/mei_aux.h
> >   F:	include/linux/mei_cl_bus.h
> >   F:	include/uapi/linux/mei.h
> >   F:	samples/mei/*
> > diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
> > index 98c5450b8eac..2660a85175d9 100644
> > --- a/drivers/gpu/drm/i915/Kconfig
> > +++ b/drivers/gpu/drm/i915/Kconfig
> > @@ -30,6 +30,7 @@ config DRM_I915
> >   	select VMAP_PFN
> >   	select DRM_TTM
> >   	select DRM_BUDDY
> > +	select AUXILIARY_BUS
> >   	help
> >   	  Choose this option if you have a system that has "Intel Graphics
> >   	  Media Accelerator" or "HD Graphics" integrated graphics,
> > diff --git a/drivers/gpu/drm/i915/Makefile
> b/drivers/gpu/drm/i915/Makefile
> > index 1a771ee5b1d0..9be7b13d8822 100644
> > --- a/drivers/gpu/drm/i915/Makefile
> > +++ b/drivers/gpu/drm/i915/Makefile
> > @@ -196,6 +196,9 @@ i915-y += gt/uc/intel_uc.o \
> >   	  gt/uc/intel_huc_debugfs.o \
> >   	  gt/uc/intel_huc_fw.o
> >
> > +# graphics system controller (GSC) support
> > +i915-y += gt/intel_gsc.o
> > +
> >   # modesetting core code
> >   i915-y += \
> >   	display/hsw_ips.o \
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.c
> b/drivers/gpu/drm/i915/gt/intel_gsc.c
> > new file mode 100644
> > index 000000000000..152804e7c41a
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/gt/intel_gsc.c
> > @@ -0,0 +1,204 @@
> > +// SPDX-License-Identifier: MIT
> > +/*
> > + * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
> > + */
> > +
> > +#include <linux/irq.h>
> > +#include <linux/mei_aux.h>
> > +#include "i915_reg.h"
> > +#include "i915_drv.h"
> > +#include "gt/intel_gt.h"
> > +#include "intel_gsc.h"
> 
> A bit of inconsistency here because intel_gsc.h and intel_gt.h are both
> in the gt/ folder but you're only prefixing one with gt/. Also, we
> usually try to keep includes in alphabetical order, but overall not a
> blocker for me.
> 
Well set both to gt/ and reshuffle.

> > +
> > +#define GSC_BAR_LENGTH  0x00000FFC
> > +
> > +static void gsc_irq_mask(struct irq_data *d)
> > +{
> > +	/* generic irq handling */
> > +}
> > +
> > +static void gsc_irq_unmask(struct irq_data *d)
> > +{
> > +	/* generic irq handling */
> > +}
> > +
> > +static struct irq_chip gsc_irq_chip = {
> > +	.name = "gsc_irq_chip",
> > +	.irq_mask = gsc_irq_mask,
> > +	.irq_unmask = gsc_irq_unmask,
> > +};
> > +
> > +static int gsc_irq_init(int irq)
> > +{
> > +	irq_set_chip_and_handler_name(irq, &gsc_irq_chip,
> > +				      handle_simple_irq, "gsc_irq_handler");
> > +
> > +	return irq_set_chip_data(irq, NULL);
> > +}
> > +
> > +struct intel_gsc_def {
> > +	const char *name;
> > +	unsigned long bar;
> > +	size_t bar_size;
> > +};
> > +
> > +/* gscfi (graphics system controller firmware interface) resources */
> 
> Should this comment be moved down in the array? the array has sections
> for both pxp and gscfi resources, even if the former are not set. Or
> maybe expand to something like:
> 
> /* for DG1 we only need gscfi (....) resources */
> 
I'll change it to describe the array in whole

> > +static const struct intel_gsc_def intel_gsc_def_dg1[] = {
> > +	{
> > +		/* HECI1 not yet implemented. */
> > +	},
> > +	{
> > +		.name = "mei-gscfi",
> > +		.bar = GSC_DG1_HECI2_BASE,
> > +		.bar_size = GSC_BAR_LENGTH,
> > +	}
> > +};
> > +
> > +static void intel_gsc_release_dev(struct device *dev)
> 
> We usually avoid the intel_* prefix for static functions. Same for other
> functions below.
> 
Ok, will drop intel_ prefix from static

> > +{
> > +	struct auxiliary_device *aux_dev = to_auxiliary_dev(dev);
> > +	struct mei_aux_device *adev =
> auxiliary_dev_to_mei_aux_dev(aux_dev);
> > +
> > +	kfree(adev);
> > +}
> > +
> > +static void intel_gsc_destroy_one(struct intel_gsc_intf *intf)
> > +{
> > +	if (intf->adev) {
> > +		auxiliary_device_delete(&intf->adev->aux_dev);
> > +		auxiliary_device_uninit(&intf->adev->aux_dev);
> > +		intf->adev = NULL;
> > +	}
> > +	if (intf->irq >= 0)
> > +		irq_free_desc(intf->irq);
> > +	intf->irq = -1;
> > +}
> > +
> > +static void intel_gsc_init_one(struct drm_i915_private *i915,
> > +			       struct intel_gsc_intf *intf,
> > +			       unsigned int intf_id)
> > +{
> > +	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
> > +	struct mei_aux_device *adev;
> > +	struct auxiliary_device *aux_dev;
> > +	const struct intel_gsc_def *def;
> > +	int ret;
> > +
> > +	intf->irq = -1;
> > +	intf->id = intf_id;
> > +
> > +	if (intf_id == 0 && !HAS_HECI_PXP(i915))
> > +		return;
> > +
> > +	def = &intel_gsc_def_dg1[intf_id];
> > +
> > +	if (!def->name) {
> > +		drm_warn_once(&i915->drm, "HECI%d is not
> implemented!\n", intf_id + 1);
> > +		return;
> > +	}
> > +
> > +	intf->irq = irq_alloc_desc(0);
> > +	if (intf->irq < 0) {
> > +		drm_err(&i915->drm, "gsc irq error %d\n", intf->irq);
> > +		return;
> > +	}
> > +
> > +	ret = gsc_irq_init(intf->irq);
> > +	if (ret < 0) {
> > +		drm_err(&i915->drm, "gsc irq init failed %d\n", ret);
> > +		goto fail;
> > +	}
> > +
> > +	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
> > +	if (!adev)
> > +		goto fail;
> > +
> > +	adev->irq = intf->irq;
> > +	adev->bar.parent = &pdev->resource[0];
> > +	adev->bar.start = def->bar + pdev->resource[0].start;
> > +	adev->bar.end = adev->bar.start + def->bar_size - 1;
> > +	adev->bar.flags = IORESOURCE_MEM;
> > +	adev->bar.desc = IORES_DESC_NONE;
> > +
> > +	aux_dev = &adev->aux_dev;
> > +	aux_dev->name = def->name;
> > +	aux_dev->id = (pci_domain_nr(pdev->bus) << 16) |
> > +		      PCI_DEVID(pdev->bus->number, pdev->devfn);
> > +	aux_dev->dev.parent = &pdev->dev;
> > +	aux_dev->dev.release = intel_gsc_release_dev;
> > +
> > +	ret = auxiliary_device_init(aux_dev);
> > +	if (ret < 0) {
> > +		drm_err(&i915->drm, "gsc aux init failed %d\n", ret);
> > +		kfree(adev);
> > +		goto fail;
> > +	}
> > +
> > +	ret = auxiliary_device_add(aux_dev);
> > +	if (ret < 0) {
> > +		drm_err(&i915->drm, "gsc aux add failed %d\n", ret);
> > +		/* adev will be freed with the put_device() and .release
> sequence */
> > +		auxiliary_device_uninit(aux_dev);
> > +		goto fail;
> > +	}
> > +	intf->adev = adev;
> > +
> > +	return;
> > +fail:
> > +	intel_gsc_destroy_one(intf);
> > +}
> > +
> > +static void gsc_irq_handler(struct intel_gt *gt, unsigned int intf_id)
> > +{
> > +	int ret;
> > +
> > +	if (intf_id >= INTEL_GSC_NUM_INTERFACES) {
> > +		drm_warn_once(&gt->i915->drm, "GSC irq: intf_id %d is out
> of range", intf_id);
> > +		return;
> > +	}
> > +
> > +	if (!HAS_HECI_GSC(gt->i915)) {
> > +		drm_warn_once(&gt->i915->drm, "GSC irq: not supported");
> > +		return;
> > +	}
> > +
> > +	if (gt->gsc.intf[intf_id].irq < 0) {
> > +		drm_err_ratelimited(&gt->i915->drm, "GSC irq: irq not set");
> > +		return;
> > +	}
> > +
> > +	ret = generic_handle_irq(gt->gsc.intf[intf_id].irq);
> > +	if (ret)
> > +		drm_err_ratelimited(&gt->i915->drm, "error handling GSC
> irq: %d\n", ret);
> > +}
> > +
> > +void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir)
> > +{
> > +	if (iir & GSC_IRQ_INTF(0))
> > +		gsc_irq_handler(gt, 0);
> > +	if (iir & GSC_IRQ_INTF(1))
> > +		gsc_irq_handler(gt, 1);
> > +}
> > +
> > +void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private *i915)
> > +{
> > +	unsigned int i;
> > +
> > +	if (!HAS_HECI_GSC(i915))
> > +		return;
> > +
> > +	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
> > +		intel_gsc_init_one(i915, &gsc->intf[i], i);
> > +}
> > +
> > +void intel_gsc_fini(struct intel_gsc *gsc)
> > +{
> > +	struct intel_gt *gt = gsc_to_gt(gsc);
> > +	unsigned int i;
> > +
> > +	if (!HAS_HECI_GSC(gt->i915))
> > +		return;
> > +
> > +	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
> > +		intel_gsc_destroy_one(&gsc->intf[i]);
> > +}
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.h
> b/drivers/gpu/drm/i915/gt/intel_gsc.h
> > new file mode 100644
> > index 000000000000..68582f912b21
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/gt/intel_gsc.h
> > @@ -0,0 +1,37 @@
> > +/* SPDX-License-Identifier: MIT */
> > +/*
> > + * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
> > + */
> > +#ifndef __INTEL_GSC_DEV_H__
> > +#define __INTEL_GSC_DEV_H__
> > +
> > +#include <linux/types.h>
> > +
> > +struct drm_i915_private;
> > +struct intel_gt;
> > +struct mei_aux_device;
> > +
> > +#define INTEL_GSC_NUM_INTERFACES 2
> > +/*
> > + * The HECI1 bit corresponds to bit15 and HECI2 to bit14.
> > + * The reason for this is to allow growth for more interfaces in the future.
> > + */
> > +#define GSC_IRQ_INTF(_x)  BIT(15 - (_x))
> > +
> > +/**
> > + * struct intel_gsc - graphics security controller
> > + * @intf : gsc interface
> > + */
> > +struct intel_gsc {
> > +	struct intel_gsc_intf {
> > +		struct mei_aux_device *adev;
> > +		int irq;
> > +		unsigned int id;
> > +	} intf[INTEL_GSC_NUM_INTERFACES];
> > +};
> > +
> > +void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private
> *dev_priv);
> > +void intel_gsc_fini(struct intel_gsc *gsc);
> > +void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir);
> > +
> > +#endif /* __INTEL_GSC_DEV_H__ */
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c
> b/drivers/gpu/drm/i915/gt/intel_gt.c
> > index 8a2483ccbfb9..fd83ab4b8849 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt.c
> > @@ -444,6 +444,8 @@ void intel_gt_chipset_flush(struct intel_gt *gt)
> >
> >   void intel_gt_driver_register(struct intel_gt *gt)
> >   {
> > +	intel_gsc_init(&gt->gsc, gt->i915);
> > +
> >   	intel_rps_driver_register(&gt->rps);
> >
> >   	intel_gt_debugfs_register(gt);
> > @@ -766,6 +768,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
> >   	intel_wakeref_t wakeref;
> >
> >   	intel_rps_driver_unregister(&gt->rps);
> > +	intel_gsc_fini(&gt->gsc);
> >
> >   	intel_pxp_fini(&gt->pxp);
> >
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h
> b/drivers/gpu/drm/i915/gt/intel_gt.h
> > index 0f571c8ee22b..de779a505c21 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt.h
> > @@ -34,6 +34,11 @@ static inline struct intel_gt *huc_to_gt(struct
> intel_huc *huc)
> >   	return container_of(huc, struct intel_gt, uc.huc);
> >   }
> >
> > +static inline struct intel_gt *gsc_to_gt(struct intel_gsc *gsc)
> > +{
> > +	return container_of(gsc, struct intel_gt, gsc);
> > +}
> > +
> >   void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915);
> >   void __intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private
> *i915);
> >   int intel_gt_assign_ggtt(struct intel_gt *gt);
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> > index e443ac4c8059..917b85d0c189 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> > @@ -68,6 +68,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8
> instance,
> >   	if (instance == OTHER_KCR_INSTANCE)
> >   		return intel_pxp_irq_handler(&gt->pxp, iir);
> >
> > +	if (instance == OTHER_GSC_INSTANCE)
> > +		return intel_gsc_irq_handler(gt, iir);
> > +
> >   	WARN_ONCE(1, "unhandled other interrupt instance=0x%x,
> iir=0x%x\n",
> >   		  instance, iir);
> >   }
> > @@ -184,6 +187,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
> >   	intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE,	  0);
> >   	if (CCS_MASK(gt))
> >   		intel_uncore_write(uncore,
> GEN12_CCS_RSVD_INTR_ENABLE, 0);
> > +	if (HAS_HECI_GSC(gt->i915))
> > +		intel_uncore_write(uncore,
> GEN11_GUNIT_CSME_INTR_ENABLE, 0);
> >
> >   	/* Restore masks irqs on RCS, BCS, VCS and VECS engines. */
> >   	intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK,	~0);
> > @@ -201,6 +206,8 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
> >   		intel_uncore_write(uncore,
> GEN12_CCS0_CCS1_INTR_MASK, ~0);
> >   	if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3))
> >   		intel_uncore_write(uncore,
> GEN12_CCS2_CCS3_INTR_MASK, ~0);
> > +	if (HAS_HECI_GSC(gt->i915))
> > +		intel_uncore_write(uncore,
> GEN11_GUNIT_CSME_INTR_MASK, ~0);
> >
> >   	intel_uncore_write(uncore,
> GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0);
> >   	intel_uncore_write(uncore,
> GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
> > @@ -215,6 +222,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
> >   {
> >   	struct intel_uncore *uncore = gt->uncore;
> >   	u32 irqs = GT_RENDER_USER_INTERRUPT;
> > +	const u32 gsc_mask = GSC_IRQ_INTF(0) | GSC_IRQ_INTF(1);
> >   	u32 dmask;
> >   	u32 smask;
> >
> > @@ -233,6 +241,9 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
> >   	intel_uncore_write(uncore, GEN11_VCS_VECS_INTR_ENABLE,
> dmask);
> >   	if (CCS_MASK(gt))
> >   		intel_uncore_write(uncore,
> GEN12_CCS_RSVD_INTR_ENABLE, smask);
> > +	if (HAS_HECI_GSC(gt->i915))
> > +		intel_uncore_write(uncore,
> GEN11_GUNIT_CSME_INTR_ENABLE,
> > +				   gsc_mask);
> >
> >   	/* Unmask irqs on RCS, BCS, VCS and VECS engines. */
> >   	intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK,
> ~smask);
> > @@ -250,6 +261,8 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
> >   		intel_uncore_write(uncore,
> GEN12_CCS0_CCS1_INTR_MASK, ~dmask);
> >   	if (HAS_ENGINE(gt, CCS2) || HAS_ENGINE(gt, CCS3))
> >   		intel_uncore_write(uncore,
> GEN12_CCS2_CCS3_INTR_MASK, ~dmask);
> > +	if (HAS_HECI_GSC(gt->i915))
> > +		intel_uncore_write(uncore,
> GEN11_GUNIT_CSME_INTR_MASK, 0);
> 
> This should be ~gsc_mask, right?
> 
Yes, sure, rebase fallout. Thanks for catching this!

> >
> >   	/*
> >   	 * RPS interrupts will get enabled/disabled on demand when RPS
> itself
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > index 19cd34f24263..a277fb480cc8 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
> > @@ -1483,6 +1483,7 @@
> >   #define   OTHER_GUC_INSTANCE			0
> >   #define   OTHER_GTPM_INSTANCE			1
> >   #define   OTHER_KCR_INSTANCE			4
> > +#define   OTHER_GSC_INSTANCE			6
> >
> >   #define GEN11_IIR_REG_SELECTOR(x)		_MMIO(0x190070 +
> ((x) * 4))
> >
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h
> b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> > index f20687796490..5556d55f76ea 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> > @@ -16,6 +16,7 @@
> >   #include <linux/workqueue.h>
> >
> >   #include "uc/intel_uc.h"
> > +#include "intel_gsc.h"
> >
> >   #include "i915_vma.h"
> >   #include "intel_engine_types.h"
> > @@ -72,6 +73,7 @@ struct intel_gt {
> >   	struct i915_ggtt *ggtt;
> >
> >   	struct intel_uc uc;
> > +	struct intel_gsc gsc;
> >
> >   	struct mutex tlb_invalidate_lock;
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> > index 943267393ecb..1c000c15493d 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1327,6 +1327,14 @@ IS_SUBPLATFORM(const struct
> drm_i915_private *i915,
> >
> >   #define HAS_DMC(dev_priv)	(INTEL_INFO(dev_priv)-
> >display.has_dmc)
> >
> > +#define HAS_HECI_PXP(dev_priv) \
> > +	(INTEL_INFO(dev_priv)->has_heci_pxp)
> > +
> > +#define HAS_HECI_GSCFI(dev_priv) \
> > +	(INTEL_INFO(dev_priv)->has_heci_gscfi)
> > +
> > +#define HAS_HECI_GSC(dev_priv) (HAS_HECI_PXP(dev_priv) ||
> HAS_HECI_GSCFI(dev_priv))
> > +
> >   #define HAS_MSO(i915)		(DISPLAY_VER(i915) >= 12)
> >
> >   #define HAS_RUNTIME_PM(dev_priv) (INTEL_INFO(dev_priv)-
> >has_runtime_pm)
> > diff --git a/drivers/gpu/drm/i915/i915_pci.c
> b/drivers/gpu/drm/i915/i915_pci.c
> > index 67b89769f577..a948f566bd3d 100644
> > --- a/drivers/gpu/drm/i915/i915_pci.c
> > +++ b/drivers/gpu/drm/i915/i915_pci.c
> > @@ -901,7 +901,8 @@ static const struct intel_device_info rkl_info = {
> >   	.has_llc = 0, \
> >   	.has_pxp = 0, \
> >   	.has_snoop = 1, \
> > -	.is_dgfx = 1
> > +	.is_dgfx = 1, \
> > +	.has_heci_gscfi = 1
> >
> >   static const struct intel_device_info dg1_info = {
> >   	GEN12_FEATURES,
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> > index 70484f6f2b8b..0ed305ff07a9 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -975,6 +975,8 @@
> >   #define GEN12_COMPUTE1_RING_BASE	0x1c000
> >   #define GEN12_COMPUTE2_RING_BASE	0x1e000
> >   #define GEN12_COMPUTE3_RING_BASE	0x26000
> > +#define GSC_DG1_HECI1_BASE	0x00258000
> 
> Do we need the DG1 HECI1 base definition, considering we're not adding
> HECI1 support for DG1?

There are other usages of this offset in follow up patches also when
MEI is not going to support this interface.

> Also, we usually put the platform name (DG1) before the unit (GSC) in
> our defines, so DG1_GSC_HECI* would probably be more inline with the
> rest of the defs.

Will rename as suggested

> 
> > +#define GSC_DG1_HECI2_BASE	0x00259000
> >   #define BLT_RING_BASE		0x22000
> 
> IMO better to move the GSC defs to after the BLT, that way we don't
> separate it from the other RING_BASE definitions, given that the GSC is
> not a RING and its base is something different. Not a blocker.
> 

Sure, will move as rebasing anyway

> Daniele
> 
> >
> >
> > diff --git a/drivers/gpu/drm/i915/intel_device_info.h
> b/drivers/gpu/drm/i915/intel_device_info.h
> > index f9b955810593..576d15a04c9e 100644
> > --- a/drivers/gpu/drm/i915/intel_device_info.h
> > +++ b/drivers/gpu/drm/i915/intel_device_info.h
> > @@ -141,6 +141,8 @@ enum intel_ppgtt_type {
> >   	func(has_flat_ccs); \
> >   	func(has_global_mocs); \
> >   	func(has_gt_uc); \
> > +	func(has_heci_pxp); \
> > +	func(has_heci_gscfi); \
> >   	func(has_guc_deprivilege); \
> >   	func(has_l3_dpf); \
> >   	func(has_llc); \
> > diff --git a/include/linux/mei_aux.h b/include/linux/mei_aux.h
> > new file mode 100644
> > index 000000000000..587f25128848
> > --- /dev/null
> > +++ b/include/linux/mei_aux.h
> > @@ -0,0 +1,19 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2022, Intel Corporation. All rights reserved.
> > + */
> > +#ifndef _LINUX_MEI_AUX_H
> > +#define _LINUX_MEI_AUX_H
> > +
> > +#include <linux/auxiliary_bus.h>
> > +
> > +struct mei_aux_device {
> > +	struct auxiliary_device aux_dev;
> > +	int irq;
> > +	struct resource bar;
> > +};
> > +
> > +#define auxiliary_dev_to_mei_aux_dev(auxiliary_dev) \
> > +	container_of(auxiliary_dev, struct mei_aux_device, aux_dev)
> > +
> > +#endif /* _LINUX_MEI_AUX_H */

-- 
Thanks,
Sasha



^ permalink raw reply	[flat|nested] 33+ messages in thread

* RE: [Intel-gfx] [PATCH v10 2/5] mei: add support for graphics system controller (gsc) devices
  2022-03-10  0:24     ` Ceraolo Spurio, Daniele
@ 2022-03-13 11:23       ` Usyskin, Alexander
  -1 siblings, 0 replies; 33+ messages in thread
From: Usyskin, Alexander @ 2022-03-13 11:23 UTC (permalink / raw)
  To: Ceraolo Spurio, Daniele, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Vivi, Rodrigo, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: linux-kernel, Winkler, Tomas, Lubart, Vitaly, intel-gfx



> -----Original Message-----
> From: Ceraolo Spurio, Daniele <daniele.ceraolospurio@intel.com>
> Sent: Thursday, March 10, 2022 02:24
> To: Usyskin, Alexander <alexander.usyskin@intel.com>; Greg Kroah-
> Hartman <gregkh@linuxfoundation.org>; Jani Nikula
> <jani.nikula@linux.intel.com>; Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com>; Vivi, Rodrigo <rodrigo.vivi@intel.com>;
> David Airlie <airlied@linux.ie>; Daniel Vetter <daniel@ffwll.ch>; Tvrtko
> Ursulin <tvrtko.ursulin@linux.intel.com>
> Cc: linux-kernel@vger.kernel.org; Winkler, Tomas
> <tomas.winkler@intel.com>; Lubart, Vitaly <vitaly.lubart@intel.com>; intel-
> gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH v10 2/5] mei: add support for graphics system
> controller (gsc) devices
> 
> 
> On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> > From: Tomas Winkler <tomas.winkler@intel.com>
> >
> > GSC is a graphics system controller, based on CSE, it provides
> > a chassis controller for graphics discrete cards, as well as it
> > supports media protection on selected devices.
> >
> > mei_gsc binds to a auxiliary devices exposed by Intel discrete
> > driver i915.
> >
> > Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> > Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> > ---
> >   drivers/misc/mei/Kconfig  |  14 +++
> >   drivers/misc/mei/Makefile |   3 +
> >   drivers/misc/mei/gsc-me.c | 186
> ++++++++++++++++++++++++++++++++++++++
> >   drivers/misc/mei/hw-me.c  |  27 +++++-
> >   drivers/misc/mei/hw-me.h  |   2 +
> >   5 files changed, 230 insertions(+), 2 deletions(-)
> >   create mode 100644 drivers/misc/mei/gsc-me.c
> >
> > diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
> > index 0e0bcd0da852..d21486d69df2 100644
> > --- a/drivers/misc/mei/Kconfig
> > +++ b/drivers/misc/mei/Kconfig
> > @@ -46,6 +46,20 @@ config INTEL_MEI_TXE
> >   	  Supported SoCs:
> >   	  Intel Bay Trail
> >
> > +config INTEL_MEI_GSC
> 
> On platforms with a GSC, INTEL_MEI_PXP depends on INTEL_MEI_GSC. Are
> you
> planning to add that dependency once the HECI1/PXP interface is exposed,
> or are you expecting i915 to check for both?
> 

IMO  - add dependency to mei_pxp after HECI1/PXP is exposed.

> > +	tristate "Intel MEI GSC embedded device"
> > +	depends on INTEL_MEI
> > +	depends on INTEL_MEI_ME
> > +	depends on X86 && PCI
> > +	depends on DRM_I915
> > +	help
> > +	  Intel auxiliary driver for GSC devices embedded in Intel graphics
> devices.
> > +
> > +	  An MEI device here called GSC can be embedded in an
> > +	  Intel graphics devices, to support a range of chassis
> > +	  tasks such as graphics card firmware update and security
> > +	  tasks.
> > +
> >   source "drivers/misc/mei/hdcp/Kconfig"
> >   source "drivers/misc/mei/pxp/Kconfig"
> >
> > diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
> > index d8e5165917f2..fb740d754900 100644
> > --- a/drivers/misc/mei/Makefile
> > +++ b/drivers/misc/mei/Makefile
> > @@ -18,6 +18,9 @@ obj-$(CONFIG_INTEL_MEI_ME) += mei-me.o
> >   mei-me-objs := pci-me.o
> >   mei-me-objs += hw-me.o
> >
> > +obj-$(CONFIG_INTEL_MEI_GSC) += mei-gsc.o
> > +mei-gsc-objs := gsc-me.o
> > +
> >   obj-$(CONFIG_INTEL_MEI_TXE) += mei-txe.o
> >   mei-txe-objs := pci-txe.o
> >   mei-txe-objs += hw-txe.o
> > diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
> > new file mode 100644
> > index 000000000000..0afae70e0609
> > --- /dev/null
> > +++ b/drivers/misc/mei/gsc-me.c
> > @@ -0,0 +1,186 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
> > + *
> > + * Intel Management Engine Interface (Intel MEI) Linux driver
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/mei_aux.h>
> > +#include <linux/device.h>
> > +#include <linux/irqreturn.h>
> > +#include <linux/jiffies.h>
> > +#include <linux/ktime.h>
> > +#include <linux/delay.h>
> > +#include <linux/pm_runtime.h>
> > +
> > +#include "mei_dev.h"
> > +#include "hw-me.h"
> > +#include "hw-me-regs.h"
> > +
> > +#include "mei-trace.h"
> > +
> > +#define MEI_GSC_RPM_TIMEOUT 500
> 
> MEI_ME_RPM_TIMEOUT already exists in hw-me.h with the same value. If
> you're not expecting them to diverge, we could just re-use the existing
> one. Not a blocker.
> 

The GSC usecases somewhat different from CSME, so I prefer
to split this timeout, as GSC one may need tuning.

> > +
> > +static int mei_gsc_read_hfs(const struct mei_device *dev, int where, u32
> *val)
> > +{
> > +	struct mei_me_hw *hw = to_me_hw(dev);
> > +
> > +	*val = ioread32(hw->mem_addr + where + 0xC00);
> > +
> > +	return 0;
> > +}
> > +
> > +static int mei_gsc_probe(struct auxiliary_device *aux_dev,
> > +			 const struct auxiliary_device_id *aux_dev_id)
> > +{
> > +	struct mei_aux_device *adev =
> auxiliary_dev_to_mei_aux_dev(aux_dev);
> > +	struct mei_device *dev;
> 
> might be worth renaming this variable to mei_dev, to avoid confusion
> with "device" below. Not a blocker.
> 

Similar functions in MEI always name it dev, so prefer to leave it for consistency. 

> > +	struct mei_me_hw *hw;
> > +	struct device *device;
> > +	const struct mei_cfg *cfg;
> > +	int ret;
> > +
> > +	cfg = mei_me_get_cfg(aux_dev_id->driver_data);
> > +	if (!cfg)
> > +		return -ENODEV;
> > +
> > +	device = &aux_dev->dev;
> > +
> > +	dev = mei_me_dev_init(device, cfg);
> > +	if (IS_ERR(dev)) {
> > +		ret = PTR_ERR(dev);
> > +		goto err;
> > +	}
> > +
> > +	hw = to_me_hw(dev);
> > +	hw->mem_addr = devm_ioremap_resource(device, &adev->bar);
> > +	if (IS_ERR(hw->mem_addr)) {
> > +		dev_err(device, "mmio not mapped\n");
> > +		ret = PTR_ERR(hw->mem_addr);
> > +		goto err;
> > +	}
> > +
> > +	hw->irq = adev->irq;
> > +	hw->read_fws = mei_gsc_read_hfs;
> > +
> > +	dev_set_drvdata(&aux_dev->dev, dev);
> 
> you have a device = &aux_dev->dev earlier, so you can just use device here.
ok

> 
> > +
> > +	ret = devm_request_threaded_irq(device, hw->irq,
> > +					mei_me_irq_quick_handler,
> > +					mei_me_irq_thread_handler,
> > +					IRQF_ONESHOT,
> KBUILD_MODNAME, dev);
> 
> If I'm understanding this correctly, you're tying the irq to the device
> allocated by i915, so if the probe fails below or the mei_gsc module is
> unloaded the irq is going to stick around. Probably better to clean it
> up explicitly, in case we get a spurious interrupt from the HW and i915
> propagates it (although that's a very unlikely scenario).
> 
Yes, will add a cleanup

> > +	if (ret) {
> > +		dev_err(device, "irq register failed %d\n", ret);
> > +		goto err;
> > +	}
> > +
> > +	pm_runtime_get_noresume(device);
> > +	pm_runtime_set_active(device);
> > +	pm_runtime_enable(device);
> > +
> > +	if (mei_start(dev)) {
> > +		dev_err(device, "init hw failure.\n");
> > +		ret = -ENODEV;
> > +		goto err;
> > +	}
> > +
> > +	pm_runtime_set_autosuspend_delay(device,
> MEI_GSC_RPM_TIMEOUT);
> > +	pm_runtime_use_autosuspend(device);
> > +
> > +	ret = mei_register(dev, device);
> > +	if (ret)
> > +		goto register_err;
> > +
> > +	pm_runtime_put_noidle(device);
> > +	return 0;
> > +
> > +register_err:
> > +	mei_stop(dev);
> > +
> > +err:
> > +	dev_err(device, "probe failed: %d\n", ret);
> > +	dev_set_drvdata(&aux_dev->dev, NULL);
> 
> can use device here as well instead of &aux_dev->dev
ok

> 
> > +	return ret;
> > +}
> > +
> > +static void mei_gsc_remove(struct auxiliary_device *aux_dev)
> > +{
> > +	struct mei_device *dev;
> > +
> > +	dev = dev_get_drvdata(&aux_dev->dev);
> > +	if (!dev)
> > +		return;
> > +
> > +	mei_stop(dev);
> > +
> > +	mei_deregister(dev);
> > +
> > +	pm_runtime_disable(&aux_dev->dev);
> > +}
> > +
> > +static int __maybe_unused mei_gsc_pm_suspend(struct device *device)
> > +{
> > +	struct mei_device *dev = dev_get_drvdata(device);
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +
> > +	mei_stop(dev);
> > +
> > +	mei_disable_interrupts(dev);
> > +
> > +	return 0;
> > +}
> > +
> > +static int __maybe_unused mei_gsc_pm_resume(struct device *device)
> > +{
> > +	struct mei_device *dev = dev_get_drvdata(device);
> > +	int err;
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +
> > +	err = mei_restart(dev);
> 
> Might be worth adding a comment to explain that the interrupts are
> enabled by the mei_restart and that's why we don't have a
> mei_interrupts_enable call to match the disable we have in the suspend.
> 

We have same flow in pci-me, not sure that comment here is really helps.

> Daniele
> 
> > +	if (err)
> > +		return err;
> > +
> > +	/* Start timer if stopped in suspend */
> > +	schedule_delayed_work(&dev->timer_work, HZ);
> > +
> > +	return 0;
> > +}
> > +
> > +static SIMPLE_DEV_PM_OPS(mei_gsc_pm_ops, mei_gsc_pm_suspend,
> mei_gsc_pm_resume);
> > +
> > +static const struct auxiliary_device_id mei_gsc_id_table[] = {
> > +	{
> > +		.name = "i915.mei-gsc",
> > +		.driver_data = MEI_ME_GSC_CFG,
> > +
> > +	},
> > +	{
> > +		.name = "i915.mei-gscfi",
> > +		.driver_data = MEI_ME_GSCFI_CFG,
> > +	},
> > +	{
> > +		/* sentinel */
> > +	}
> > +};
> > +MODULE_DEVICE_TABLE(auxiliary, mei_gsc_id_table);
> > +
> > +static struct auxiliary_driver mei_gsc_driver = {
> > +	.probe	= mei_gsc_probe,
> > +	.remove = mei_gsc_remove,
> > +	.driver = {
> > +		/* auxiliary_driver_register() sets .name to be the modname
> */
> > +		.pm = &mei_gsc_pm_ops,
> > +	},
> > +	.id_table = mei_gsc_id_table
> > +};
> > +module_auxiliary_driver(mei_gsc_driver);
> > +
> > +MODULE_AUTHOR("Intel Corporation");
> > +MODULE_ALIAS("auxiliary:i915.mei-gsc");
> > +MODULE_ALIAS("auxiliary:i915.mei-gscfi");
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
> > index d3a6c0728645..9748d14849a1 100644
> > --- a/drivers/misc/mei/hw-me.c
> > +++ b/drivers/misc/mei/hw-me.c
> > @@ -1226,6 +1226,7 @@ irqreturn_t mei_me_irq_quick_handler(int irq,
> void *dev_id)
> >   	me_intr_disable(dev, hcsr);
> >   	return IRQ_WAKE_THREAD;
> >   }
> > +EXPORT_SYMBOL_GPL(mei_me_irq_quick_handler);
> >
> >   /**
> >    * mei_me_irq_thread_handler - function called after ISR to handle the
> interrupt
> > @@ -1320,6 +1321,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq,
> void *dev_id)
> >   	mutex_unlock(&dev->device_lock);
> >   	return IRQ_HANDLED;
> >   }
> > +EXPORT_SYMBOL_GPL(mei_me_irq_thread_handler);
> >
> >   static const struct mei_hw_ops mei_me_hw_ops = {
> >
> > @@ -1433,6 +1435,12 @@ static bool mei_me_fw_type_sps(const struct
> pci_dev *pdev)
> >   #define MEI_CFG_KIND_ITOUCH                     \
> >   	.kind = "itouch"
> >
> > +#define MEI_CFG_TYPE_GSC                        \
> > +	.kind = "gsc"
> > +
> > +#define MEI_CFG_TYPE_GSCFI                      \
> > +	.kind = "gscfi"
> > +
> >   #define MEI_CFG_FW_SPS                          \
> >   	.quirk_probe = mei_me_fw_type_sps
> >
> > @@ -1565,6 +1573,18 @@ static const struct mei_cfg
> mei_me_pch15_sps_cfg = {
> >   	MEI_CFG_FW_SPS,
> >   };
> >
> > +/* Graphics System Controller */
> > +static const struct mei_cfg mei_me_gsc_cfg = {
> > +	MEI_CFG_TYPE_GSC,
> > +	MEI_CFG_PCH8_HFS,
> > +};
> > +
> > +/* Graphics System Controller Firmware Interface */
> > +static const struct mei_cfg mei_me_gscfi_cfg = {
> > +	MEI_CFG_TYPE_GSCFI,
> > +	MEI_CFG_PCH8_HFS,
> > +};
> > +
> >   /*
> >    * mei_cfg_list - A list of platform platform specific configurations.
> >    * Note: has to be synchronized with  enum mei_cfg_idx.
> > @@ -1585,6 +1605,8 @@ static const struct mei_cfg *const mei_cfg_list[] =
> {
> >   	[MEI_ME_PCH12_SPS_ITOUCH_CFG] =
> &mei_me_pch12_itouch_sps_cfg,
> >   	[MEI_ME_PCH15_CFG] = &mei_me_pch15_cfg,
> >   	[MEI_ME_PCH15_SPS_CFG] = &mei_me_pch15_sps_cfg,
> > +	[MEI_ME_GSC_CFG] = &mei_me_gsc_cfg,
> > +	[MEI_ME_GSCFI_CFG] = &mei_me_gscfi_cfg,
> >   };
> >
> >   const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx)
> > @@ -1595,7 +1617,8 @@ const struct mei_cfg
> *mei_me_get_cfg(kernel_ulong_t idx)
> >   		return NULL;
> >
> >   	return mei_cfg_list[idx];
> > -};
> > +}
> > +EXPORT_SYMBOL_GPL(mei_me_get_cfg);
> >
> >   /**
> >    * mei_me_dev_init - allocates and initializes the mei device structure
> > @@ -1630,4 +1653,4 @@ struct mei_device *mei_me_dev_init(struct
> device *parent,
> >
> >   	return dev;
> >   }
> > -
> > +EXPORT_SYMBOL_GPL(mei_me_dev_init);
> > diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
> > index 00a7132ac7a2..a071c645e905 100644
> > --- a/drivers/misc/mei/hw-me.h
> > +++ b/drivers/misc/mei/hw-me.h
> > @@ -112,6 +112,8 @@ enum mei_cfg_idx {
> >   	MEI_ME_PCH12_SPS_ITOUCH_CFG,
> >   	MEI_ME_PCH15_CFG,
> >   	MEI_ME_PCH15_SPS_CFG,
> > +	MEI_ME_GSC_CFG,
> > +	MEI_ME_GSCFI_CFG,
> >   	MEI_ME_NUM_CFG,
> >   };
> >

-- 
Thanks,
Sasha



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 2/5] mei: add support for graphics system controller (gsc) devices
@ 2022-03-13 11:23       ` Usyskin, Alexander
  0 siblings, 0 replies; 33+ messages in thread
From: Usyskin, Alexander @ 2022-03-13 11:23 UTC (permalink / raw)
  To: Ceraolo Spurio, Daniele, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Vivi, Rodrigo, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: Winkler, Tomas, intel-gfx, linux-kernel, Lubart, Vitaly



> -----Original Message-----
> From: Ceraolo Spurio, Daniele <daniele.ceraolospurio@intel.com>
> Sent: Thursday, March 10, 2022 02:24
> To: Usyskin, Alexander <alexander.usyskin@intel.com>; Greg Kroah-
> Hartman <gregkh@linuxfoundation.org>; Jani Nikula
> <jani.nikula@linux.intel.com>; Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com>; Vivi, Rodrigo <rodrigo.vivi@intel.com>;
> David Airlie <airlied@linux.ie>; Daniel Vetter <daniel@ffwll.ch>; Tvrtko
> Ursulin <tvrtko.ursulin@linux.intel.com>
> Cc: linux-kernel@vger.kernel.org; Winkler, Tomas
> <tomas.winkler@intel.com>; Lubart, Vitaly <vitaly.lubart@intel.com>; intel-
> gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH v10 2/5] mei: add support for graphics system
> controller (gsc) devices
> 
> 
> On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> > From: Tomas Winkler <tomas.winkler@intel.com>
> >
> > GSC is a graphics system controller, based on CSE, it provides
> > a chassis controller for graphics discrete cards, as well as it
> > supports media protection on selected devices.
> >
> > mei_gsc binds to a auxiliary devices exposed by Intel discrete
> > driver i915.
> >
> > Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> > Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> > ---
> >   drivers/misc/mei/Kconfig  |  14 +++
> >   drivers/misc/mei/Makefile |   3 +
> >   drivers/misc/mei/gsc-me.c | 186
> ++++++++++++++++++++++++++++++++++++++
> >   drivers/misc/mei/hw-me.c  |  27 +++++-
> >   drivers/misc/mei/hw-me.h  |   2 +
> >   5 files changed, 230 insertions(+), 2 deletions(-)
> >   create mode 100644 drivers/misc/mei/gsc-me.c
> >
> > diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
> > index 0e0bcd0da852..d21486d69df2 100644
> > --- a/drivers/misc/mei/Kconfig
> > +++ b/drivers/misc/mei/Kconfig
> > @@ -46,6 +46,20 @@ config INTEL_MEI_TXE
> >   	  Supported SoCs:
> >   	  Intel Bay Trail
> >
> > +config INTEL_MEI_GSC
> 
> On platforms with a GSC, INTEL_MEI_PXP depends on INTEL_MEI_GSC. Are
> you
> planning to add that dependency once the HECI1/PXP interface is exposed,
> or are you expecting i915 to check for both?
> 

IMO  - add dependency to mei_pxp after HECI1/PXP is exposed.

> > +	tristate "Intel MEI GSC embedded device"
> > +	depends on INTEL_MEI
> > +	depends on INTEL_MEI_ME
> > +	depends on X86 && PCI
> > +	depends on DRM_I915
> > +	help
> > +	  Intel auxiliary driver for GSC devices embedded in Intel graphics
> devices.
> > +
> > +	  An MEI device here called GSC can be embedded in an
> > +	  Intel graphics devices, to support a range of chassis
> > +	  tasks such as graphics card firmware update and security
> > +	  tasks.
> > +
> >   source "drivers/misc/mei/hdcp/Kconfig"
> >   source "drivers/misc/mei/pxp/Kconfig"
> >
> > diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
> > index d8e5165917f2..fb740d754900 100644
> > --- a/drivers/misc/mei/Makefile
> > +++ b/drivers/misc/mei/Makefile
> > @@ -18,6 +18,9 @@ obj-$(CONFIG_INTEL_MEI_ME) += mei-me.o
> >   mei-me-objs := pci-me.o
> >   mei-me-objs += hw-me.o
> >
> > +obj-$(CONFIG_INTEL_MEI_GSC) += mei-gsc.o
> > +mei-gsc-objs := gsc-me.o
> > +
> >   obj-$(CONFIG_INTEL_MEI_TXE) += mei-txe.o
> >   mei-txe-objs := pci-txe.o
> >   mei-txe-objs += hw-txe.o
> > diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
> > new file mode 100644
> > index 000000000000..0afae70e0609
> > --- /dev/null
> > +++ b/drivers/misc/mei/gsc-me.c
> > @@ -0,0 +1,186 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
> > + *
> > + * Intel Management Engine Interface (Intel MEI) Linux driver
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/mei_aux.h>
> > +#include <linux/device.h>
> > +#include <linux/irqreturn.h>
> > +#include <linux/jiffies.h>
> > +#include <linux/ktime.h>
> > +#include <linux/delay.h>
> > +#include <linux/pm_runtime.h>
> > +
> > +#include "mei_dev.h"
> > +#include "hw-me.h"
> > +#include "hw-me-regs.h"
> > +
> > +#include "mei-trace.h"
> > +
> > +#define MEI_GSC_RPM_TIMEOUT 500
> 
> MEI_ME_RPM_TIMEOUT already exists in hw-me.h with the same value. If
> you're not expecting them to diverge, we could just re-use the existing
> one. Not a blocker.
> 

The GSC usecases somewhat different from CSME, so I prefer
to split this timeout, as GSC one may need tuning.

> > +
> > +static int mei_gsc_read_hfs(const struct mei_device *dev, int where, u32
> *val)
> > +{
> > +	struct mei_me_hw *hw = to_me_hw(dev);
> > +
> > +	*val = ioread32(hw->mem_addr + where + 0xC00);
> > +
> > +	return 0;
> > +}
> > +
> > +static int mei_gsc_probe(struct auxiliary_device *aux_dev,
> > +			 const struct auxiliary_device_id *aux_dev_id)
> > +{
> > +	struct mei_aux_device *adev =
> auxiliary_dev_to_mei_aux_dev(aux_dev);
> > +	struct mei_device *dev;
> 
> might be worth renaming this variable to mei_dev, to avoid confusion
> with "device" below. Not a blocker.
> 

Similar functions in MEI always name it dev, so prefer to leave it for consistency. 

> > +	struct mei_me_hw *hw;
> > +	struct device *device;
> > +	const struct mei_cfg *cfg;
> > +	int ret;
> > +
> > +	cfg = mei_me_get_cfg(aux_dev_id->driver_data);
> > +	if (!cfg)
> > +		return -ENODEV;
> > +
> > +	device = &aux_dev->dev;
> > +
> > +	dev = mei_me_dev_init(device, cfg);
> > +	if (IS_ERR(dev)) {
> > +		ret = PTR_ERR(dev);
> > +		goto err;
> > +	}
> > +
> > +	hw = to_me_hw(dev);
> > +	hw->mem_addr = devm_ioremap_resource(device, &adev->bar);
> > +	if (IS_ERR(hw->mem_addr)) {
> > +		dev_err(device, "mmio not mapped\n");
> > +		ret = PTR_ERR(hw->mem_addr);
> > +		goto err;
> > +	}
> > +
> > +	hw->irq = adev->irq;
> > +	hw->read_fws = mei_gsc_read_hfs;
> > +
> > +	dev_set_drvdata(&aux_dev->dev, dev);
> 
> you have a device = &aux_dev->dev earlier, so you can just use device here.
ok

> 
> > +
> > +	ret = devm_request_threaded_irq(device, hw->irq,
> > +					mei_me_irq_quick_handler,
> > +					mei_me_irq_thread_handler,
> > +					IRQF_ONESHOT,
> KBUILD_MODNAME, dev);
> 
> If I'm understanding this correctly, you're tying the irq to the device
> allocated by i915, so if the probe fails below or the mei_gsc module is
> unloaded the irq is going to stick around. Probably better to clean it
> up explicitly, in case we get a spurious interrupt from the HW and i915
> propagates it (although that's a very unlikely scenario).
> 
Yes, will add a cleanup

> > +	if (ret) {
> > +		dev_err(device, "irq register failed %d\n", ret);
> > +		goto err;
> > +	}
> > +
> > +	pm_runtime_get_noresume(device);
> > +	pm_runtime_set_active(device);
> > +	pm_runtime_enable(device);
> > +
> > +	if (mei_start(dev)) {
> > +		dev_err(device, "init hw failure.\n");
> > +		ret = -ENODEV;
> > +		goto err;
> > +	}
> > +
> > +	pm_runtime_set_autosuspend_delay(device,
> MEI_GSC_RPM_TIMEOUT);
> > +	pm_runtime_use_autosuspend(device);
> > +
> > +	ret = mei_register(dev, device);
> > +	if (ret)
> > +		goto register_err;
> > +
> > +	pm_runtime_put_noidle(device);
> > +	return 0;
> > +
> > +register_err:
> > +	mei_stop(dev);
> > +
> > +err:
> > +	dev_err(device, "probe failed: %d\n", ret);
> > +	dev_set_drvdata(&aux_dev->dev, NULL);
> 
> can use device here as well instead of &aux_dev->dev
ok

> 
> > +	return ret;
> > +}
> > +
> > +static void mei_gsc_remove(struct auxiliary_device *aux_dev)
> > +{
> > +	struct mei_device *dev;
> > +
> > +	dev = dev_get_drvdata(&aux_dev->dev);
> > +	if (!dev)
> > +		return;
> > +
> > +	mei_stop(dev);
> > +
> > +	mei_deregister(dev);
> > +
> > +	pm_runtime_disable(&aux_dev->dev);
> > +}
> > +
> > +static int __maybe_unused mei_gsc_pm_suspend(struct device *device)
> > +{
> > +	struct mei_device *dev = dev_get_drvdata(device);
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +
> > +	mei_stop(dev);
> > +
> > +	mei_disable_interrupts(dev);
> > +
> > +	return 0;
> > +}
> > +
> > +static int __maybe_unused mei_gsc_pm_resume(struct device *device)
> > +{
> > +	struct mei_device *dev = dev_get_drvdata(device);
> > +	int err;
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +
> > +	err = mei_restart(dev);
> 
> Might be worth adding a comment to explain that the interrupts are
> enabled by the mei_restart and that's why we don't have a
> mei_interrupts_enable call to match the disable we have in the suspend.
> 

We have same flow in pci-me, not sure that comment here is really helps.

> Daniele
> 
> > +	if (err)
> > +		return err;
> > +
> > +	/* Start timer if stopped in suspend */
> > +	schedule_delayed_work(&dev->timer_work, HZ);
> > +
> > +	return 0;
> > +}
> > +
> > +static SIMPLE_DEV_PM_OPS(mei_gsc_pm_ops, mei_gsc_pm_suspend,
> mei_gsc_pm_resume);
> > +
> > +static const struct auxiliary_device_id mei_gsc_id_table[] = {
> > +	{
> > +		.name = "i915.mei-gsc",
> > +		.driver_data = MEI_ME_GSC_CFG,
> > +
> > +	},
> > +	{
> > +		.name = "i915.mei-gscfi",
> > +		.driver_data = MEI_ME_GSCFI_CFG,
> > +	},
> > +	{
> > +		/* sentinel */
> > +	}
> > +};
> > +MODULE_DEVICE_TABLE(auxiliary, mei_gsc_id_table);
> > +
> > +static struct auxiliary_driver mei_gsc_driver = {
> > +	.probe	= mei_gsc_probe,
> > +	.remove = mei_gsc_remove,
> > +	.driver = {
> > +		/* auxiliary_driver_register() sets .name to be the modname
> */
> > +		.pm = &mei_gsc_pm_ops,
> > +	},
> > +	.id_table = mei_gsc_id_table
> > +};
> > +module_auxiliary_driver(mei_gsc_driver);
> > +
> > +MODULE_AUTHOR("Intel Corporation");
> > +MODULE_ALIAS("auxiliary:i915.mei-gsc");
> > +MODULE_ALIAS("auxiliary:i915.mei-gscfi");
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
> > index d3a6c0728645..9748d14849a1 100644
> > --- a/drivers/misc/mei/hw-me.c
> > +++ b/drivers/misc/mei/hw-me.c
> > @@ -1226,6 +1226,7 @@ irqreturn_t mei_me_irq_quick_handler(int irq,
> void *dev_id)
> >   	me_intr_disable(dev, hcsr);
> >   	return IRQ_WAKE_THREAD;
> >   }
> > +EXPORT_SYMBOL_GPL(mei_me_irq_quick_handler);
> >
> >   /**
> >    * mei_me_irq_thread_handler - function called after ISR to handle the
> interrupt
> > @@ -1320,6 +1321,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq,
> void *dev_id)
> >   	mutex_unlock(&dev->device_lock);
> >   	return IRQ_HANDLED;
> >   }
> > +EXPORT_SYMBOL_GPL(mei_me_irq_thread_handler);
> >
> >   static const struct mei_hw_ops mei_me_hw_ops = {
> >
> > @@ -1433,6 +1435,12 @@ static bool mei_me_fw_type_sps(const struct
> pci_dev *pdev)
> >   #define MEI_CFG_KIND_ITOUCH                     \
> >   	.kind = "itouch"
> >
> > +#define MEI_CFG_TYPE_GSC                        \
> > +	.kind = "gsc"
> > +
> > +#define MEI_CFG_TYPE_GSCFI                      \
> > +	.kind = "gscfi"
> > +
> >   #define MEI_CFG_FW_SPS                          \
> >   	.quirk_probe = mei_me_fw_type_sps
> >
> > @@ -1565,6 +1573,18 @@ static const struct mei_cfg
> mei_me_pch15_sps_cfg = {
> >   	MEI_CFG_FW_SPS,
> >   };
> >
> > +/* Graphics System Controller */
> > +static const struct mei_cfg mei_me_gsc_cfg = {
> > +	MEI_CFG_TYPE_GSC,
> > +	MEI_CFG_PCH8_HFS,
> > +};
> > +
> > +/* Graphics System Controller Firmware Interface */
> > +static const struct mei_cfg mei_me_gscfi_cfg = {
> > +	MEI_CFG_TYPE_GSCFI,
> > +	MEI_CFG_PCH8_HFS,
> > +};
> > +
> >   /*
> >    * mei_cfg_list - A list of platform platform specific configurations.
> >    * Note: has to be synchronized with  enum mei_cfg_idx.
> > @@ -1585,6 +1605,8 @@ static const struct mei_cfg *const mei_cfg_list[] =
> {
> >   	[MEI_ME_PCH12_SPS_ITOUCH_CFG] =
> &mei_me_pch12_itouch_sps_cfg,
> >   	[MEI_ME_PCH15_CFG] = &mei_me_pch15_cfg,
> >   	[MEI_ME_PCH15_SPS_CFG] = &mei_me_pch15_sps_cfg,
> > +	[MEI_ME_GSC_CFG] = &mei_me_gsc_cfg,
> > +	[MEI_ME_GSCFI_CFG] = &mei_me_gscfi_cfg,
> >   };
> >
> >   const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx)
> > @@ -1595,7 +1617,8 @@ const struct mei_cfg
> *mei_me_get_cfg(kernel_ulong_t idx)
> >   		return NULL;
> >
> >   	return mei_cfg_list[idx];
> > -};
> > +}
> > +EXPORT_SYMBOL_GPL(mei_me_get_cfg);
> >
> >   /**
> >    * mei_me_dev_init - allocates and initializes the mei device structure
> > @@ -1630,4 +1653,4 @@ struct mei_device *mei_me_dev_init(struct
> device *parent,
> >
> >   	return dev;
> >   }
> > -
> > +EXPORT_SYMBOL_GPL(mei_me_dev_init);
> > diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
> > index 00a7132ac7a2..a071c645e905 100644
> > --- a/drivers/misc/mei/hw-me.h
> > +++ b/drivers/misc/mei/hw-me.h
> > @@ -112,6 +112,8 @@ enum mei_cfg_idx {
> >   	MEI_ME_PCH12_SPS_ITOUCH_CFG,
> >   	MEI_ME_PCH15_CFG,
> >   	MEI_ME_PCH15_SPS_CFG,
> > +	MEI_ME_GSC_CFG,
> > +	MEI_ME_GSCFI_CFG,
> >   	MEI_ME_NUM_CFG,
> >   };
> >

-- 
Thanks,
Sasha



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 3/5] mei: gsc: setup char driver alive in spite of firmware handshake failure
  2022-03-10  0:28     ` Ceraolo Spurio, Daniele
@ 2022-03-13 12:12       ` Usyskin, Alexander
  -1 siblings, 0 replies; 33+ messages in thread
From: Usyskin, Alexander @ 2022-03-13 12:12 UTC (permalink / raw)
  To: Ceraolo Spurio, Daniele, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Vivi, Rodrigo, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: Winkler, Tomas, intel-gfx, linux-kernel, Lubart, Vitaly



> -----Original Message-----
> From: Ceraolo Spurio, Daniele <daniele.ceraolospurio@intel.com>
> Sent: Thursday, March 10, 2022 02:28
> To: Usyskin, Alexander <alexander.usyskin@intel.com>; Greg Kroah-
> Hartman <gregkh@linuxfoundation.org>; Jani Nikula
> <jani.nikula@linux.intel.com>; Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com>; Vivi, Rodrigo <rodrigo.vivi@intel.com>;
> David Airlie <airlied@linux.ie>; Daniel Vetter <daniel@ffwll.ch>; Tvrtko
> Ursulin <tvrtko.ursulin@linux.intel.com>
> Cc: linux-kernel@vger.kernel.org; Winkler, Tomas
> <tomas.winkler@intel.com>; Lubart, Vitaly <vitaly.lubart@intel.com>; intel-
> gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH v10 3/5] mei: gsc: setup char driver alive in
> spite of firmware handshake failure
> 
> 
> 
> On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> > Setup char device in spite of firmware handshake failure.
> > In order to provide host access to the firmware status registers and other
> > information required for the manufacturing process.
> 
> IMO this patch should be moved to after the patch that adds the logic to
> fetch the FW version, as that is interesting info for sysfs. Not a blocker.
> 

Actually, the FW version is filled only if there is an established channel with FW.
Firmware status registers are the crucial information for debug, and it filled
in previous patches.

-- 
Thanks,
Sasha


> >
> > Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> > Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> 
> Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> 
> Daniele
> 
> > ---
> >   drivers/misc/mei/gsc-me.c | 11 ++++++-----
> >   1 file changed, 6 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
> > index 0afae70e0609..cf427f6fdec9 100644
> > --- a/drivers/misc/mei/gsc-me.c
> > +++ b/drivers/misc/mei/gsc-me.c
> > @@ -79,11 +79,12 @@ static int mei_gsc_probe(struct auxiliary_device
> *aux_dev,
> >   	pm_runtime_set_active(device);
> >   	pm_runtime_enable(device);
> >
> > -	if (mei_start(dev)) {
> > -		dev_err(device, "init hw failure.\n");
> > -		ret = -ENODEV;
> > -		goto err;
> > -	}
> > +	/* Continue to char device setup in spite of firmware handshake
> failure.
> > +	 * In order to provide access to the firmware status registers to the
> user
> > +	 * space via sysfs.
> > +	 */
> > +	if (mei_start(dev))
> > +		dev_warn(device, "init hw failure.\n");
> >
> >   	pm_runtime_set_autosuspend_delay(device,
> MEI_GSC_RPM_TIMEOUT);
> >   	pm_runtime_use_autosuspend(device);


^ permalink raw reply	[flat|nested] 33+ messages in thread

* RE: [Intel-gfx] [PATCH v10 3/5] mei: gsc: setup char driver alive in spite of firmware handshake failure
@ 2022-03-13 12:12       ` Usyskin, Alexander
  0 siblings, 0 replies; 33+ messages in thread
From: Usyskin, Alexander @ 2022-03-13 12:12 UTC (permalink / raw)
  To: Ceraolo Spurio, Daniele, Greg Kroah-Hartman, Jani Nikula,
	Joonas Lahtinen, Vivi, Rodrigo, David Airlie, Daniel Vetter,
	Tvrtko Ursulin
  Cc: linux-kernel, Winkler, Tomas, Lubart, Vitaly, intel-gfx



> -----Original Message-----
> From: Ceraolo Spurio, Daniele <daniele.ceraolospurio@intel.com>
> Sent: Thursday, March 10, 2022 02:28
> To: Usyskin, Alexander <alexander.usyskin@intel.com>; Greg Kroah-
> Hartman <gregkh@linuxfoundation.org>; Jani Nikula
> <jani.nikula@linux.intel.com>; Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com>; Vivi, Rodrigo <rodrigo.vivi@intel.com>;
> David Airlie <airlied@linux.ie>; Daniel Vetter <daniel@ffwll.ch>; Tvrtko
> Ursulin <tvrtko.ursulin@linux.intel.com>
> Cc: linux-kernel@vger.kernel.org; Winkler, Tomas
> <tomas.winkler@intel.com>; Lubart, Vitaly <vitaly.lubart@intel.com>; intel-
> gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH v10 3/5] mei: gsc: setup char driver alive in
> spite of firmware handshake failure
> 
> 
> 
> On 3/8/2022 8:36 AM, Alexander Usyskin wrote:
> > Setup char device in spite of firmware handshake failure.
> > In order to provide host access to the firmware status registers and other
> > information required for the manufacturing process.
> 
> IMO this patch should be moved to after the patch that adds the logic to
> fetch the FW version, as that is interesting info for sysfs. Not a blocker.
> 

Actually, the FW version is filled only if there is an established channel with FW.
Firmware status registers are the crucial information for debug, and it filled
in previous patches.

-- 
Thanks,
Sasha


> >
> > Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> > Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> 
> Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> 
> Daniele
> 
> > ---
> >   drivers/misc/mei/gsc-me.c | 11 ++++++-----
> >   1 file changed, 6 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
> > index 0afae70e0609..cf427f6fdec9 100644
> > --- a/drivers/misc/mei/gsc-me.c
> > +++ b/drivers/misc/mei/gsc-me.c
> > @@ -79,11 +79,12 @@ static int mei_gsc_probe(struct auxiliary_device
> *aux_dev,
> >   	pm_runtime_set_active(device);
> >   	pm_runtime_enable(device);
> >
> > -	if (mei_start(dev)) {
> > -		dev_err(device, "init hw failure.\n");
> > -		ret = -ENODEV;
> > -		goto err;
> > -	}
> > +	/* Continue to char device setup in spite of firmware handshake
> failure.
> > +	 * In order to provide access to the firmware status registers to the
> user
> > +	 * space via sysfs.
> > +	 */
> > +	if (mei_start(dev))
> > +		dev_warn(device, "init hw failure.\n");
> >
> >   	pm_runtime_set_autosuspend_delay(device,
> MEI_GSC_RPM_TIMEOUT);
> >   	pm_runtime_use_autosuspend(device);


^ permalink raw reply	[flat|nested] 33+ messages in thread

* RE: [Intel-gfx] [PATCH v10 4/5] mei: gsc: add runtime pm handlers
  2022-03-10 19:03     ` Rodrigo Vivi
@ 2022-03-13 15:47       ` Usyskin, Alexander
  -1 siblings, 0 replies; 33+ messages in thread
From: Usyskin, Alexander @ 2022-03-13 15:47 UTC (permalink / raw)
  To: Vivi, Rodrigo
  Cc: Greg Kroah-Hartman, Jani Nikula, Joonas Lahtinen, David Airlie,
	Daniel Vetter, Tvrtko Ursulin, linux-kernel, Winkler, Tomas,
	Lubart, Vitaly, intel-gfx



> -----Original Message-----
> From: Vivi, Rodrigo <rodrigo.vivi@intel.com>
> Sent: Thursday, March 10, 2022 21:04
> To: Usyskin, Alexander <alexander.usyskin@intel.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>; Jani Nikula
> <jani.nikula@linux.intel.com>; Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com>; David Airlie <airlied@linux.ie>; Daniel
> Vetter <daniel@ffwll.ch>; Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>;
> linux-kernel@vger.kernel.org; Winkler, Tomas <tomas.winkler@intel.com>;
> Lubart, Vitaly <vitaly.lubart@intel.com>; intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH v10 4/5] mei: gsc: add runtime pm handlers
> 
> On Tue, Mar 08, 2022 at 06:36:53PM +0200, Alexander Usyskin wrote:
> > From: Tomas Winkler <tomas.winkler@intel.com>
> >
> > Implement runtime handlers for mei-gsc, to track
> > idle state of the device properly.
> >
> > CC: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> > Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> > ---
> >  drivers/misc/mei/gsc-me.c | 67
> ++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 66 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
> > index cf427f6fdec9..dac482ddab51 100644
> > --- a/drivers/misc/mei/gsc-me.c
> > +++ b/drivers/misc/mei/gsc-me.c
> > @@ -152,7 +152,72 @@ static int __maybe_unused
> mei_gsc_pm_resume(struct device *device)
> >  	return 0;
> >  }
> >
> > -static SIMPLE_DEV_PM_OPS(mei_gsc_pm_ops, mei_gsc_pm_suspend,
> mei_gsc_pm_resume);
> > +static int __maybe_unused mei_gsc_pm_runtime_idle(struct device
> *device)
> > +{
> > +	struct mei_device *dev = dev_get_drvdata(device);
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +	if (mei_write_is_idle(dev))
> > +		pm_runtime_autosuspend(device);
> 
> This is not needed. The _idle() callback is called right before the
> autosuspend.
> so you just need to return -EBUSY if not idle.
> 

It is taken from blueprint in pci-me.c
IIRC here we ask the autosuspend to kick in after DELAY,
not simply rejecting it unconditionally.

> But also I'm missing the call to enable the autosuspend and set the delay.
>
These calls are in the second patch in the series, at the end of probe.
 
> Is this flow really working and you are getting device suspended when not in
> use?
> (Maybe it is just my ignorance on other flow types here)
> 

GSC low-power is guided by DG card, here we only signaling to parent (i915, I think)
that GSC is idle or that we need resume to perform the operations.

> > +
> > +	return -EBUSY;
> > +}
> > +
> > +static int  __maybe_unused mei_gsc_pm_runtime_suspend(struct device
> *device)
> > +{
> > +	struct mei_device *dev = dev_get_drvdata(device);
> > +	struct mei_me_hw *hw;
> > +	int ret;
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +
> > +	mutex_lock(&dev->device_lock);
> > +
> > +	if (mei_write_is_idle(dev)) {
> > +		hw = to_me_hw(dev);
> > +		hw->pg_state = MEI_PG_ON;
> > +		ret = 0;
> > +	} else {
> > +		ret = -EAGAIN;
> > +	}
> 
> probably not needed this here... but it would be good if you use
> the runtime_pm{get,put} to protect your write operations as well...
> 

We reuse big portions of mei and mei-me drivers and there
all needed runtime_pm calls are implemented.

The runtime pm callbacks are different as GSC do not have
actual HW registers to handle the low power states as CSME has.

> > +
> > +	mutex_unlock(&dev->device_lock);
> > +
> > +	return ret;
> > +}
> > +
> > +static int __maybe_unused mei_gsc_pm_runtime_resume(struct device
> *device)
> > +{
> > +	struct mei_device *dev = dev_get_drvdata(device);
> > +	struct mei_me_hw *hw;
> > +	irqreturn_t irq_ret;
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +
> > +	mutex_lock(&dev->device_lock);
> > +
> > +	hw = to_me_hw(dev);
> > +	hw->pg_state = MEI_PG_OFF;
> > +
> > +	mutex_unlock(&dev->device_lock);
> > +
> > +	irq_ret = mei_me_irq_thread_handler(1, dev);
> > +	if (irq_ret != IRQ_HANDLED)
> > +		dev_err(dev->dev, "thread handler fail %d\n", irq_ret);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct dev_pm_ops mei_gsc_pm_ops = {
> > +	SET_SYSTEM_SLEEP_PM_OPS(mei_gsc_pm_suspend,
> > +				mei_gsc_pm_resume)
> > +	SET_RUNTIME_PM_OPS(mei_gsc_pm_runtime_suspend,
> > +			   mei_gsc_pm_runtime_resume,
> > +			   mei_gsc_pm_runtime_idle)
> > +};
> >
> >  static const struct auxiliary_device_id mei_gsc_id_table[] = {
> >  	{
> > --
> > 2.32.0
> >

-- 
Thanks,
Sasha



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Intel-gfx] [PATCH v10 4/5] mei: gsc: add runtime pm handlers
@ 2022-03-13 15:47       ` Usyskin, Alexander
  0 siblings, 0 replies; 33+ messages in thread
From: Usyskin, Alexander @ 2022-03-13 15:47 UTC (permalink / raw)
  To: Vivi, Rodrigo
  Cc: David Airlie, Greg Kroah-Hartman, intel-gfx, linux-kernel,
	Winkler,  Tomas, Lubart, Vitaly



> -----Original Message-----
> From: Vivi, Rodrigo <rodrigo.vivi@intel.com>
> Sent: Thursday, March 10, 2022 21:04
> To: Usyskin, Alexander <alexander.usyskin@intel.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>; Jani Nikula
> <jani.nikula@linux.intel.com>; Joonas Lahtinen
> <joonas.lahtinen@linux.intel.com>; David Airlie <airlied@linux.ie>; Daniel
> Vetter <daniel@ffwll.ch>; Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>;
> linux-kernel@vger.kernel.org; Winkler, Tomas <tomas.winkler@intel.com>;
> Lubart, Vitaly <vitaly.lubart@intel.com>; intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH v10 4/5] mei: gsc: add runtime pm handlers
> 
> On Tue, Mar 08, 2022 at 06:36:53PM +0200, Alexander Usyskin wrote:
> > From: Tomas Winkler <tomas.winkler@intel.com>
> >
> > Implement runtime handlers for mei-gsc, to track
> > idle state of the device properly.
> >
> > CC: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> > Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> > ---
> >  drivers/misc/mei/gsc-me.c | 67
> ++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 66 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
> > index cf427f6fdec9..dac482ddab51 100644
> > --- a/drivers/misc/mei/gsc-me.c
> > +++ b/drivers/misc/mei/gsc-me.c
> > @@ -152,7 +152,72 @@ static int __maybe_unused
> mei_gsc_pm_resume(struct device *device)
> >  	return 0;
> >  }
> >
> > -static SIMPLE_DEV_PM_OPS(mei_gsc_pm_ops, mei_gsc_pm_suspend,
> mei_gsc_pm_resume);
> > +static int __maybe_unused mei_gsc_pm_runtime_idle(struct device
> *device)
> > +{
> > +	struct mei_device *dev = dev_get_drvdata(device);
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +	if (mei_write_is_idle(dev))
> > +		pm_runtime_autosuspend(device);
> 
> This is not needed. The _idle() callback is called right before the
> autosuspend.
> so you just need to return -EBUSY if not idle.
> 

It is taken from blueprint in pci-me.c
IIRC here we ask the autosuspend to kick in after DELAY,
not simply rejecting it unconditionally.

> But also I'm missing the call to enable the autosuspend and set the delay.
>
These calls are in the second patch in the series, at the end of probe.
 
> Is this flow really working and you are getting device suspended when not in
> use?
> (Maybe it is just my ignorance on other flow types here)
> 

GSC low-power is guided by DG card, here we only signaling to parent (i915, I think)
that GSC is idle or that we need resume to perform the operations.

> > +
> > +	return -EBUSY;
> > +}
> > +
> > +static int  __maybe_unused mei_gsc_pm_runtime_suspend(struct device
> *device)
> > +{
> > +	struct mei_device *dev = dev_get_drvdata(device);
> > +	struct mei_me_hw *hw;
> > +	int ret;
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +
> > +	mutex_lock(&dev->device_lock);
> > +
> > +	if (mei_write_is_idle(dev)) {
> > +		hw = to_me_hw(dev);
> > +		hw->pg_state = MEI_PG_ON;
> > +		ret = 0;
> > +	} else {
> > +		ret = -EAGAIN;
> > +	}
> 
> probably not needed this here... but it would be good if you use
> the runtime_pm{get,put} to protect your write operations as well...
> 

We reuse big portions of mei and mei-me drivers and there
all needed runtime_pm calls are implemented.

The runtime pm callbacks are different as GSC do not have
actual HW registers to handle the low power states as CSME has.

> > +
> > +	mutex_unlock(&dev->device_lock);
> > +
> > +	return ret;
> > +}
> > +
> > +static int __maybe_unused mei_gsc_pm_runtime_resume(struct device
> *device)
> > +{
> > +	struct mei_device *dev = dev_get_drvdata(device);
> > +	struct mei_me_hw *hw;
> > +	irqreturn_t irq_ret;
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +
> > +	mutex_lock(&dev->device_lock);
> > +
> > +	hw = to_me_hw(dev);
> > +	hw->pg_state = MEI_PG_OFF;
> > +
> > +	mutex_unlock(&dev->device_lock);
> > +
> > +	irq_ret = mei_me_irq_thread_handler(1, dev);
> > +	if (irq_ret != IRQ_HANDLED)
> > +		dev_err(dev->dev, "thread handler fail %d\n", irq_ret);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct dev_pm_ops mei_gsc_pm_ops = {
> > +	SET_SYSTEM_SLEEP_PM_OPS(mei_gsc_pm_suspend,
> > +				mei_gsc_pm_resume)
> > +	SET_RUNTIME_PM_OPS(mei_gsc_pm_runtime_suspend,
> > +			   mei_gsc_pm_runtime_resume,
> > +			   mei_gsc_pm_runtime_idle)
> > +};
> >
> >  static const struct auxiliary_device_id mei_gsc_id_table[] = {
> >  	{
> > --
> > 2.32.0
> >

-- 
Thanks,
Sasha



^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2022-03-13 15:47 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-08 16:36 [PATCH v10 0/5] Add driver for GSC controller Alexander Usyskin
2022-03-08 16:36 ` [Intel-gfx] " Alexander Usyskin
2022-03-08 16:36 ` [PATCH v10 1/5] drm/i915/gsc: add gsc as a mei auxiliary device Alexander Usyskin
2022-03-08 16:36   ` [Intel-gfx] " Alexander Usyskin
2022-03-09 22:50   ` Ceraolo Spurio, Daniele
2022-03-09 22:50     ` Ceraolo Spurio, Daniele
2022-03-13 10:02     ` Usyskin, Alexander
2022-03-13 10:02       ` Usyskin, Alexander
2022-03-08 16:36 ` [PATCH v10 2/5] mei: add support for graphics system controller (gsc) devices Alexander Usyskin
2022-03-08 16:36   ` [Intel-gfx] " Alexander Usyskin
2022-03-10  0:24   ` Ceraolo Spurio, Daniele
2022-03-10  0:24     ` Ceraolo Spurio, Daniele
2022-03-13 11:23     ` Usyskin, Alexander
2022-03-13 11:23       ` Usyskin, Alexander
2022-03-08 16:36 ` [PATCH v10 3/5] mei: gsc: setup char driver alive in spite of firmware handshake failure Alexander Usyskin
2022-03-08 16:36   ` [Intel-gfx] " Alexander Usyskin
2022-03-10  0:28   ` Ceraolo Spurio, Daniele
2022-03-10  0:28     ` Ceraolo Spurio, Daniele
2022-03-13 12:12     ` Usyskin, Alexander
2022-03-13 12:12       ` Usyskin, Alexander
2022-03-08 16:36 ` [PATCH v10 4/5] mei: gsc: add runtime pm handlers Alexander Usyskin
2022-03-08 16:36   ` [Intel-gfx] " Alexander Usyskin
2022-03-10 19:03   ` Rodrigo Vivi
2022-03-10 19:03     ` Rodrigo Vivi
2022-03-13 15:47     ` Usyskin, Alexander
2022-03-13 15:47       ` Usyskin, Alexander
2022-03-08 16:36 ` [PATCH v10 5/5] mei: gsc: retrieve the firmware version Alexander Usyskin
2022-03-08 16:36   ` [Intel-gfx] " Alexander Usyskin
2022-03-10  1:14   ` Ceraolo Spurio, Daniele
2022-03-10  1:14     ` Ceraolo Spurio, Daniele
2022-03-08 23:52 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Add driver for GSC controller (rev10) Patchwork
2022-03-08 23:53 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2022-03-09  0:28 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.