diff mbox series

[RFC,113/162] drm/i915: Create stolen memory region from local memory

Message ID 20201127120718.454037-114-matthew.auld@intel.com (mailing list archive)
State New, archived
Headers show
Series DG1 + LMEM enabling | expand

Commit Message

Matthew Auld Nov. 27, 2020, 12:06 p.m. UTC
From: CQ Tang <cq.tang@intel.com>

Add "REGION_STOLEN" device info to dg1, create stolen memory
region from upper portion of local device memory, starting
from DSMBASE.

The memory region is marked with "is_devmem=true".

Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Cc: Chris P Wilson <chris.p.wilson@intel.com>
Cc: Balestrieri, Francesco <francesco.balestrieri@intel.com>
Cc: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Cc: Venkata S Dhanalakota <venkata.s.dhanalakota@intel.com>
Cc: Neel Desai <neel.desai@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Sudeep Dutt <sudeep.dutt@intel.com>
Signed-off-by: CQ Tang <cq.tang@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_lmem.c   |  4 +-
 drivers/gpu/drm/i915/gem/i915_gem_lmem.h   |  7 +++
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 56 +++++++++++++++++++++-
 drivers/gpu/drm/i915/i915_pci.c            |  2 +-
 drivers/gpu/drm/i915/i915_reg.h            |  1 +
 drivers/gpu/drm/i915/intel_memory_region.c |  5 ++
 drivers/gpu/drm/i915/intel_memory_region.h |  2 +-
 7 files changed, 71 insertions(+), 6 deletions(-)

Comments

Jani Nikula Dec. 7, 2020, 1:39 p.m. UTC | #1
On Fri, 27 Nov 2020, Matthew Auld <matthew.auld@intel.com> wrote:
> From: CQ Tang <cq.tang@intel.com>
>
> Add "REGION_STOLEN" device info to dg1, create stolen memory
> region from upper portion of local device memory, starting
> from DSMBASE.
>
> The memory region is marked with "is_devmem=true".
>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Matthew Auld <matthew.auld@intel.com>
> Cc: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
> Cc: Chris P Wilson <chris.p.wilson@intel.com>
> Cc: Balestrieri, Francesco <francesco.balestrieri@intel.com>
> Cc: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
> Cc: Venkata S Dhanalakota <venkata.s.dhanalakota@intel.com>
> Cc: Neel Desai <neel.desai@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Sudeep Dutt <sudeep.dutt@intel.com>
> Signed-off-by: CQ Tang <cq.tang@intel.com>
> Cc: Lucas De Marchi <lucas.demarchi@intel.com>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_lmem.c   |  4 +-
>  drivers/gpu/drm/i915/gem/i915_gem_lmem.h   |  7 +++
>  drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 56 +++++++++++++++++++++-
>  drivers/gpu/drm/i915/i915_pci.c            |  2 +-
>  drivers/gpu/drm/i915/i915_reg.h            |  1 +
>  drivers/gpu/drm/i915/intel_memory_region.c |  5 ++
>  drivers/gpu/drm/i915/intel_memory_region.h |  2 +-
>  7 files changed, 71 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
> index 71c07e1f6f26..b2fd2bc862c0 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
> @@ -111,8 +111,8 @@ int i915_gem_object_lmem_pread(struct drm_i915_gem_object *obj,
>  	return ret;
>  }
>  
> -static int i915_gem_object_lmem_pwrite(struct drm_i915_gem_object *obj,
> -				       const struct drm_i915_gem_pwrite *arg)
> +int i915_gem_object_lmem_pwrite(struct drm_i915_gem_object *obj,
> +				const struct drm_i915_gem_pwrite *arg)
>  {
>  	struct drm_i915_private *i915 = to_i915(obj->base.dev);
>  	struct intel_runtime_pm *rpm = &i915->runtime_pm;
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
> index e11e0545e39c..c59aa6c014c7 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
> @@ -11,9 +11,16 @@
>  struct drm_i915_private;
>  struct drm_i915_gem_object;
>  struct intel_memory_region;
> +struct drm_i915_gem_pread;
> +struct drm_i915_gem_pwrite;
>  
>  extern const struct drm_i915_gem_object_ops i915_gem_lmem_obj_ops;
>  
> +int i915_gem_object_lmem_pread(struct drm_i915_gem_object *obj,
> +			       const struct drm_i915_gem_pread *args);
> +int i915_gem_object_lmem_pwrite(struct drm_i915_gem_object *obj,
> +				const struct drm_i915_gem_pwrite *args);
> +
>  void __iomem *
>  i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
>  			    unsigned long n,
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
> index 0ddf48e472a0..633745336f40 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
> @@ -10,6 +10,7 @@
>  #include <drm/drm_mm.h>
>  #include <drm/i915_drm.h>
>  
> +#include "gem/i915_gem_lmem.h"
>  #include "gem/i915_gem_region.h"
>  #include "i915_drv.h"
>  #include "i915_gem_stolen.h"
> @@ -121,6 +122,14 @@ static int i915_adjust_stolen(struct drm_i915_private *i915,
>  		}
>  	}
>  
> +	/*
> +	 * With device local memory, we don't need to check the address range,
> +	 * this is device memory physical address, could overlap with system
> +	 * memory.
> +	 */
> +	if (HAS_LMEM(i915))
> +		return 0;
> +
>  	/*
>  	 * Verify that nothing else uses this physical address. Stolen
>  	 * memory should be reserved by the BIOS and hidden from the
> @@ -607,7 +616,7 @@ static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj,
>  	kfree(pages);
>  }
>  
> -static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
> +static struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {

Making driver specific ops non-const seems suspicious...

>  	.name = "i915_gem_object_stolen",
>  	.get_pages = i915_gem_object_get_pages_stolen,
>  	.put_pages = i915_gem_object_put_pages_stolen,
> @@ -716,7 +725,19 @@ i915_gem_object_create_stolen(struct drm_i915_private *i915,
>  
>  static int init_stolen(struct intel_memory_region *mem)
>  {
> -	intel_memory_region_set_name(mem, "stolen");
> +	if (mem->type == INTEL_MEMORY_STOLEN_SYSTEM)
> +		intel_memory_region_set_name(mem, "stolen-system");
> +	else
> +		intel_memory_region_set_name(mem, "stolen-local");
> +
> +	if (HAS_LMEM(mem->i915)) {
> +		i915_gem_object_stolen_ops.pread = i915_gem_object_lmem_pread;
> +		i915_gem_object_stolen_ops.pwrite = i915_gem_object_lmem_pwrite;

...and AFAICT this modifies the ops for all devices, including the
integrated GPU, if any of the devices HAS_LMEM().

BR,
Jani.

> +		if (!io_mapping_init_wc(&mem->iomap,
> +					mem->io_start,
> +					resource_size(&mem->region)))
> +			return -EIO;
> +	}
>  
>  	/*
>  	 * Initialise stolen early so that we may reserve preallocated
> @@ -736,8 +757,39 @@ static const struct intel_memory_region_ops i915_region_stolen_ops = {
>  	.create_object = i915_gem_object_create_stolen_region,
>  };
>  
> +static
> +struct intel_memory_region *setup_lmem_stolen(struct drm_i915_private *i915)
> +{
> +	struct intel_uncore *uncore = &i915->uncore;
> +	struct pci_dev *pdev = i915->drm.pdev;
> +	struct intel_memory_region *mem;
> +	resource_size_t io_start;
> +	resource_size_t lmem_size;
> +	u64 lmem_base;
> +
> +	lmem_base = intel_uncore_read64(uncore, GEN12_DSMBASE);
> +	lmem_size = pci_resource_len(pdev, 2) - lmem_base;
> +	io_start = pci_resource_start(pdev, 2) + lmem_base;
> +
> +	mem = intel_memory_region_create(i915, lmem_base, lmem_size,
> +					 I915_GTT_PAGE_SIZE_4K, io_start,
> +					 &i915_region_stolen_ops);
> +	if (!IS_ERR(mem)) {
> +		DRM_INFO("Intel graphics stolen LMEM: %pR\n", &mem->region);
> +		DRM_INFO("Intel graphics stolen LMEM IO start: %llx\n",
> +			 (u64)mem->io_start);
> +		/* this is real device memory */
> +		mem->is_devmem = true;
> +	}
> +
> +	return mem;
> +}
> +
>  struct intel_memory_region *i915_gem_stolen_setup(struct drm_i915_private *i915)
>  {
> +	if (HAS_LMEM(i915))
> +		return setup_lmem_stolen(i915);
> +
>  	return intel_memory_region_create(i915,
>  					  intel_graphics_stolen_res.start,
>  					  resource_size(&intel_graphics_stolen_res),
> diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
> index 8243178a56f9..c3d9b36ef651 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -907,7 +907,7 @@ static const struct intel_device_info rkl_info = {
>  
>  #define GEN12_DGFX_FEATURES \
>  	GEN12_FEATURES, \
> -	.memory_regions = REGION_SMEM | REGION_LMEM, \
> +	.memory_regions = REGION_SMEM | REGION_LMEM | REGION_STOLEN_LMEM, \
>  	.has_master_unit_irq = 1, \
>  	.has_llc = 0, \
>  	.has_snoop = 1, \
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 0e01ea0cb0a4..3c8350f108e4 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -12067,6 +12067,7 @@ enum skl_power_gate {
>  #define   LMEM_ENABLE			(1 << 31)
>  
>  #define GEN12_GSMBASE			_MMIO(0x108100)
> +#define GEN12_DSMBASE			_MMIO(0x1080C0)
>  
>  /* gamt regs */
>  #define GEN8_L3_LRA_1_GPGPU _MMIO(0x4dd4)
> diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
> index 043541d409bd..c7a1d84e7ee8 100644
> --- a/drivers/gpu/drm/i915/intel_memory_region.c
> +++ b/drivers/gpu/drm/i915/intel_memory_region.c
> @@ -19,6 +19,10 @@ const struct intel_memory_region_info intel_region_map[] = {
>                 .class = INTEL_MEMORY_STOLEN_SYSTEM,
>                 .instance = 0,
>         },
> +       [INTEL_REGION_STOLEN_LMEM] = {
> +	       .class = INTEL_MEMORY_STOLEN_LOCAL,
> +	       .instance = 0,
> +       },
>  };
>  
>  struct intel_memory_region *
> @@ -311,6 +315,7 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
>  		case INTEL_MEMORY_SYSTEM:
>  			mem = i915_gem_shmem_setup(i915);
>  			break;
> +		case INTEL_MEMORY_STOLEN_LOCAL: /* fallthrough */
>  		case INTEL_MEMORY_STOLEN_SYSTEM:
>  			mem = i915_gem_stolen_setup(i915);
>  			break;
> diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
> index b7a9e34faaf1..8da82cb2afe3 100644
> --- a/drivers/gpu/drm/i915/intel_memory_region.h
> +++ b/drivers/gpu/drm/i915/intel_memory_region.h
> @@ -93,7 +93,7 @@ struct intel_memory_region {
>  	u16 type;
>  	u16 instance;
>  	enum intel_region_id id;
> -	char name[8];
> +	char name[16];
>  	struct intel_gt *gt; /* GT closest to this region. */
>  	bool is_devmem;	/* true for device memory */
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
index 71c07e1f6f26..b2fd2bc862c0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
@@ -111,8 +111,8 @@  int i915_gem_object_lmem_pread(struct drm_i915_gem_object *obj,
 	return ret;
 }
 
-static int i915_gem_object_lmem_pwrite(struct drm_i915_gem_object *obj,
-				       const struct drm_i915_gem_pwrite *arg)
+int i915_gem_object_lmem_pwrite(struct drm_i915_gem_object *obj,
+				const struct drm_i915_gem_pwrite *arg)
 {
 	struct drm_i915_private *i915 = to_i915(obj->base.dev);
 	struct intel_runtime_pm *rpm = &i915->runtime_pm;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
index e11e0545e39c..c59aa6c014c7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.h
@@ -11,9 +11,16 @@ 
 struct drm_i915_private;
 struct drm_i915_gem_object;
 struct intel_memory_region;
+struct drm_i915_gem_pread;
+struct drm_i915_gem_pwrite;
 
 extern const struct drm_i915_gem_object_ops i915_gem_lmem_obj_ops;
 
+int i915_gem_object_lmem_pread(struct drm_i915_gem_object *obj,
+			       const struct drm_i915_gem_pread *args);
+int i915_gem_object_lmem_pwrite(struct drm_i915_gem_object *obj,
+				const struct drm_i915_gem_pwrite *args);
+
 void __iomem *
 i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
 			    unsigned long n,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index 0ddf48e472a0..633745336f40 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -10,6 +10,7 @@ 
 #include <drm/drm_mm.h>
 #include <drm/i915_drm.h>
 
+#include "gem/i915_gem_lmem.h"
 #include "gem/i915_gem_region.h"
 #include "i915_drv.h"
 #include "i915_gem_stolen.h"
@@ -121,6 +122,14 @@  static int i915_adjust_stolen(struct drm_i915_private *i915,
 		}
 	}
 
+	/*
+	 * With device local memory, we don't need to check the address range,
+	 * this is device memory physical address, could overlap with system
+	 * memory.
+	 */
+	if (HAS_LMEM(i915))
+		return 0;
+
 	/*
 	 * Verify that nothing else uses this physical address. Stolen
 	 * memory should be reserved by the BIOS and hidden from the
@@ -607,7 +616,7 @@  static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj,
 	kfree(pages);
 }
 
-static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
+static struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
 	.name = "i915_gem_object_stolen",
 	.get_pages = i915_gem_object_get_pages_stolen,
 	.put_pages = i915_gem_object_put_pages_stolen,
@@ -716,7 +725,19 @@  i915_gem_object_create_stolen(struct drm_i915_private *i915,
 
 static int init_stolen(struct intel_memory_region *mem)
 {
-	intel_memory_region_set_name(mem, "stolen");
+	if (mem->type == INTEL_MEMORY_STOLEN_SYSTEM)
+		intel_memory_region_set_name(mem, "stolen-system");
+	else
+		intel_memory_region_set_name(mem, "stolen-local");
+
+	if (HAS_LMEM(mem->i915)) {
+		i915_gem_object_stolen_ops.pread = i915_gem_object_lmem_pread;
+		i915_gem_object_stolen_ops.pwrite = i915_gem_object_lmem_pwrite;
+		if (!io_mapping_init_wc(&mem->iomap,
+					mem->io_start,
+					resource_size(&mem->region)))
+			return -EIO;
+	}
 
 	/*
 	 * Initialise stolen early so that we may reserve preallocated
@@ -736,8 +757,39 @@  static const struct intel_memory_region_ops i915_region_stolen_ops = {
 	.create_object = i915_gem_object_create_stolen_region,
 };
 
+static
+struct intel_memory_region *setup_lmem_stolen(struct drm_i915_private *i915)
+{
+	struct intel_uncore *uncore = &i915->uncore;
+	struct pci_dev *pdev = i915->drm.pdev;
+	struct intel_memory_region *mem;
+	resource_size_t io_start;
+	resource_size_t lmem_size;
+	u64 lmem_base;
+
+	lmem_base = intel_uncore_read64(uncore, GEN12_DSMBASE);
+	lmem_size = pci_resource_len(pdev, 2) - lmem_base;
+	io_start = pci_resource_start(pdev, 2) + lmem_base;
+
+	mem = intel_memory_region_create(i915, lmem_base, lmem_size,
+					 I915_GTT_PAGE_SIZE_4K, io_start,
+					 &i915_region_stolen_ops);
+	if (!IS_ERR(mem)) {
+		DRM_INFO("Intel graphics stolen LMEM: %pR\n", &mem->region);
+		DRM_INFO("Intel graphics stolen LMEM IO start: %llx\n",
+			 (u64)mem->io_start);
+		/* this is real device memory */
+		mem->is_devmem = true;
+	}
+
+	return mem;
+}
+
 struct intel_memory_region *i915_gem_stolen_setup(struct drm_i915_private *i915)
 {
+	if (HAS_LMEM(i915))
+		return setup_lmem_stolen(i915);
+
 	return intel_memory_region_create(i915,
 					  intel_graphics_stolen_res.start,
 					  resource_size(&intel_graphics_stolen_res),
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 8243178a56f9..c3d9b36ef651 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -907,7 +907,7 @@  static const struct intel_device_info rkl_info = {
 
 #define GEN12_DGFX_FEATURES \
 	GEN12_FEATURES, \
-	.memory_regions = REGION_SMEM | REGION_LMEM, \
+	.memory_regions = REGION_SMEM | REGION_LMEM | REGION_STOLEN_LMEM, \
 	.has_master_unit_irq = 1, \
 	.has_llc = 0, \
 	.has_snoop = 1, \
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 0e01ea0cb0a4..3c8350f108e4 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -12067,6 +12067,7 @@  enum skl_power_gate {
 #define   LMEM_ENABLE			(1 << 31)
 
 #define GEN12_GSMBASE			_MMIO(0x108100)
+#define GEN12_DSMBASE			_MMIO(0x1080C0)
 
 /* gamt regs */
 #define GEN8_L3_LRA_1_GPGPU _MMIO(0x4dd4)
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index 043541d409bd..c7a1d84e7ee8 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -19,6 +19,10 @@  const struct intel_memory_region_info intel_region_map[] = {
                .class = INTEL_MEMORY_STOLEN_SYSTEM,
                .instance = 0,
        },
+       [INTEL_REGION_STOLEN_LMEM] = {
+	       .class = INTEL_MEMORY_STOLEN_LOCAL,
+	       .instance = 0,
+       },
 };
 
 struct intel_memory_region *
@@ -311,6 +315,7 @@  int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 		case INTEL_MEMORY_SYSTEM:
 			mem = i915_gem_shmem_setup(i915);
 			break;
+		case INTEL_MEMORY_STOLEN_LOCAL: /* fallthrough */
 		case INTEL_MEMORY_STOLEN_SYSTEM:
 			mem = i915_gem_stolen_setup(i915);
 			break;
diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
index b7a9e34faaf1..8da82cb2afe3 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.h
+++ b/drivers/gpu/drm/i915/intel_memory_region.h
@@ -93,7 +93,7 @@  struct intel_memory_region {
 	u16 type;
 	u16 instance;
 	enum intel_region_id id;
-	char name[8];
+	char name[16];
 	struct intel_gt *gt; /* GT closest to this region. */
 	bool is_devmem;	/* true for device memory */