Commit 0f857158 authored by Aravind Iddamsetty's avatar Aravind Iddamsetty Committed by Lucas De Marchi
Browse files

drm/i915/mtl: Media GT and Render GT share common GGTT



On XE_LPM+ platforms the media engines are carved out into a separate
GT but have a common GGTMMADR address range which essentially makes
the GGTT address space to be shared between media and render GT. As a
result any updates in GGTT shall invalidate TLB of GTs sharing it and
similarly any operation on GGTT requiring an action on a GT will have to
involve all GTs sharing it. setup_private_pat was being done on a per
GGTT based as that doesn't touch any GGTT structures moved it to per GT
based.

BSPEC: 63834

v2:
1. Add details to commit msg
2. includes fix for failure to add item to ggtt->gt_list, as suggested
by Lucas
3. as ggtt_flush() is used only for ggtt drop i915_is_ggtt check within
it.
4. setup_private_pat moved out of intel_gt_tiles_init

v3:
1. Move out for_each_gt from i915_driver.c (Jani Nikula)

v4: drop using RCU primitives on ggtt->gt_list as it is not an RCU list
(Matt Roper)

Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: default avatarAravind Iddamsetty <aravind.iddamsetty@intel.com>
Reviewed-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Signed-off-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221122070126.4813-1-aravind.iddamsetty@intel.com
parent 900a80c5
Loading
Loading
Loading
Loading
+40 −14
Original line number Original line Diff line number Diff line
@@ -8,6 +8,7 @@
#include <linux/types.h>
#include <linux/types.h>
#include <linux/stop_machine.h>
#include <linux/stop_machine.h>


#include <drm/drm_managed.h>
#include <drm/i915_drm.h>
#include <drm/i915_drm.h>
#include <drm/intel-gtt.h>
#include <drm/intel-gtt.h>


@@ -196,10 +197,13 @@ void i915_ggtt_suspend_vm(struct i915_address_space *vm)


void i915_ggtt_suspend(struct i915_ggtt *ggtt)
void i915_ggtt_suspend(struct i915_ggtt *ggtt)
{
{
	struct intel_gt *gt;

	i915_ggtt_suspend_vm(&ggtt->vm);
	i915_ggtt_suspend_vm(&ggtt->vm);
	ggtt->invalidate(ggtt);
	ggtt->invalidate(ggtt);


	intel_gt_check_and_clear_faults(ggtt->vm.gt);
	list_for_each_entry(gt, &ggtt->gt_list, ggtt_link)
		intel_gt_check_and_clear_faults(gt);
}
}


void gen6_ggtt_invalidate(struct i915_ggtt *ggtt)
void gen6_ggtt_invalidate(struct i915_ggtt *ggtt)
@@ -225,16 +229,21 @@ static void gen8_ggtt_invalidate(struct i915_ggtt *ggtt)


static void guc_ggtt_invalidate(struct i915_ggtt *ggtt)
static void guc_ggtt_invalidate(struct i915_ggtt *ggtt)
{
{
	struct intel_uncore *uncore = ggtt->vm.gt->uncore;
	struct drm_i915_private *i915 = ggtt->vm.i915;
	struct drm_i915_private *i915 = ggtt->vm.i915;


	gen8_ggtt_invalidate(ggtt);
	gen8_ggtt_invalidate(ggtt);


	if (GRAPHICS_VER(i915) >= 12)
	if (GRAPHICS_VER(i915) >= 12) {
		intel_uncore_write_fw(uncore, GEN12_GUC_TLB_INV_CR,
		struct intel_gt *gt;

		list_for_each_entry(gt, &ggtt->gt_list, ggtt_link)
			intel_uncore_write_fw(gt->uncore,
					      GEN12_GUC_TLB_INV_CR,
					      GEN12_GUC_TLB_INV_CR_INVALIDATE);
					      GEN12_GUC_TLB_INV_CR_INVALIDATE);
	else
	} else {
		intel_uncore_write_fw(uncore, GEN8_GTCR, GEN8_GTCR_INVALIDATE);
		intel_uncore_write_fw(ggtt->vm.gt->uncore,
				      GEN8_GTCR, GEN8_GTCR_INVALIDATE);
	}
}
}


u64 gen8_ggtt_pte_encode(dma_addr_t addr,
u64 gen8_ggtt_pte_encode(dma_addr_t addr,
@@ -986,8 +995,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)


	ggtt->vm.pte_encode = gen8_ggtt_pte_encode;
	ggtt->vm.pte_encode = gen8_ggtt_pte_encode;


	setup_private_pat(ggtt->vm.gt);

	return ggtt_probe_common(ggtt, size);
	return ggtt_probe_common(ggtt, size);
}
}


@@ -1196,7 +1203,14 @@ static int ggtt_probe_hw(struct i915_ggtt *ggtt, struct intel_gt *gt)
 */
 */
int i915_ggtt_probe_hw(struct drm_i915_private *i915)
int i915_ggtt_probe_hw(struct drm_i915_private *i915)
{
{
	int ret;
	struct intel_gt *gt;
	int ret, i;

	for_each_gt(gt, i915, i) {
		ret = intel_gt_assign_ggtt(gt);
		if (ret)
			return ret;
	}


	ret = ggtt_probe_hw(to_gt(i915)->ggtt, to_gt(i915));
	ret = ggtt_probe_hw(to_gt(i915)->ggtt, to_gt(i915));
	if (ret)
	if (ret)
@@ -1208,6 +1222,19 @@ int i915_ggtt_probe_hw(struct drm_i915_private *i915)
	return 0;
	return 0;
}
}


struct i915_ggtt *i915_ggtt_create(struct drm_i915_private *i915)
{
	struct i915_ggtt *ggtt;

	ggtt = drmm_kzalloc(&i915->drm, sizeof(*ggtt), GFP_KERNEL);
	if (!ggtt)
		return ERR_PTR(-ENOMEM);

	INIT_LIST_HEAD(&ggtt->gt_list);

	return ggtt;
}

int i915_ggtt_enable_hw(struct drm_i915_private *i915)
int i915_ggtt_enable_hw(struct drm_i915_private *i915)
{
{
	if (GRAPHICS_VER(i915) < 6)
	if (GRAPHICS_VER(i915) < 6)
@@ -1296,9 +1323,11 @@ bool i915_ggtt_resume_vm(struct i915_address_space *vm)


void i915_ggtt_resume(struct i915_ggtt *ggtt)
void i915_ggtt_resume(struct i915_ggtt *ggtt)
{
{
	struct intel_gt *gt;
	bool flush;
	bool flush;


	intel_gt_check_and_clear_faults(ggtt->vm.gt);
	list_for_each_entry(gt, &ggtt->gt_list, ggtt_link)
		intel_gt_check_and_clear_faults(gt);


	flush = i915_ggtt_resume_vm(&ggtt->vm);
	flush = i915_ggtt_resume_vm(&ggtt->vm);


@@ -1307,9 +1336,6 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
	if (flush)
	if (flush)
		wbinvd_on_all_cpus();
		wbinvd_on_all_cpus();


	if (GRAPHICS_VER(ggtt->vm.i915) >= 8)
		setup_private_pat(ggtt->vm.gt);

	intel_ggtt_restore_fences(ggtt);
	intel_ggtt_restore_fences(ggtt);
}
}


+11 −2
Original line number Original line Diff line number Diff line
@@ -109,9 +109,18 @@ static int intel_gt_probe_lmem(struct intel_gt *gt)


int intel_gt_assign_ggtt(struct intel_gt *gt)
int intel_gt_assign_ggtt(struct intel_gt *gt)
{
{
	gt->ggtt = drmm_kzalloc(&gt->i915->drm, sizeof(*gt->ggtt), GFP_KERNEL);
	/* Media GT shares primary GT's GGTT */
	if (gt->type == GT_MEDIA) {
		gt->ggtt = to_gt(gt->i915)->ggtt;
	} else {
		gt->ggtt = i915_ggtt_create(gt->i915);
		if (IS_ERR(gt->ggtt))
			return PTR_ERR(gt->ggtt);
	}


	return gt->ggtt ? 0 : -ENOMEM;
	list_add_tail(&gt->ggtt_link, &gt->ggtt->gt_list);

	return 0;
}
}


int intel_gt_init_mmio(struct intel_gt *gt)
int intel_gt_init_mmio(struct intel_gt *gt)
+3 −0
Original line number Original line Diff line number Diff line
@@ -277,6 +277,9 @@ struct intel_gt {
	struct kobject *sysfs_defaults;
	struct kobject *sysfs_defaults;


	struct i915_perf_gt perf;
	struct i915_perf_gt perf;

	/** link: &ggtt.gt_list */
	struct list_head ggtt_link;
};
};


struct intel_gt_definition {
struct intel_gt_definition {
+4 −0
Original line number Original line Diff line number Diff line
@@ -390,6 +390,9 @@ struct i915_ggtt {
	struct mutex error_mutex;
	struct mutex error_mutex;
	struct drm_mm_node error_capture;
	struct drm_mm_node error_capture;
	struct drm_mm_node uc_fw;
	struct drm_mm_node uc_fw;

	/** List of GTs mapping this GGTT */
	struct list_head gt_list;
};
};


struct i915_ppgtt {
struct i915_ppgtt {
@@ -584,6 +587,7 @@ void i915_ggtt_disable_guc(struct i915_ggtt *ggtt);
int i915_init_ggtt(struct drm_i915_private *i915);
int i915_init_ggtt(struct drm_i915_private *i915);
void i915_ggtt_driver_release(struct drm_i915_private *i915);
void i915_ggtt_driver_release(struct drm_i915_private *i915);
void i915_ggtt_driver_late_release(struct drm_i915_private *i915);
void i915_ggtt_driver_late_release(struct drm_i915_private *i915);
struct i915_ggtt *i915_ggtt_create(struct drm_i915_private *i915);


static inline bool i915_ggtt_has_aperture(const struct i915_ggtt *ggtt)
static inline bool i915_ggtt_has_aperture(const struct i915_ggtt *ggtt)
{
{
+7 −5
Original line number Original line Diff line number Diff line
@@ -612,10 +612,6 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv)


	i915_perf_init(dev_priv);
	i915_perf_init(dev_priv);


	ret = intel_gt_assign_ggtt(to_gt(dev_priv));
	if (ret)
		goto err_perf;

	ret = i915_ggtt_probe_hw(dev_priv);
	ret = i915_ggtt_probe_hw(dev_priv);
	if (ret)
	if (ret)
		goto err_perf;
		goto err_perf;
@@ -1316,7 +1312,8 @@ int i915_driver_suspend_switcheroo(struct drm_i915_private *i915,
static int i915_drm_resume(struct drm_device *dev)
static int i915_drm_resume(struct drm_device *dev)
{
{
	struct drm_i915_private *dev_priv = to_i915(dev);
	struct drm_i915_private *dev_priv = to_i915(dev);
	int ret;
	struct intel_gt *gt;
	int ret, i;


	disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
	disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);


@@ -1331,6 +1328,11 @@ static int i915_drm_resume(struct drm_device *dev)
		drm_err(&dev_priv->drm, "failed to re-enable GGTT\n");
		drm_err(&dev_priv->drm, "failed to re-enable GGTT\n");


	i915_ggtt_resume(to_gt(dev_priv)->ggtt);
	i915_ggtt_resume(to_gt(dev_priv)->ggtt);

	for_each_gt(gt, dev_priv, i)
		if (GRAPHICS_VER(gt->i915) >= 8)
			setup_private_pat(gt);

	/* Must be called after GGTT is resumed. */
	/* Must be called after GGTT is resumed. */
	intel_dpt_resume(dev_priv);
	intel_dpt_resume(dev_priv);


Loading