Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 906564d4 authored by Sushmita Susheelendra's avatar Sushmita Susheelendra Committed by Gerrit - the friendly Code Review server
Browse files

msm: kgsl: Add support for GPUHTW System Cache usage



Activate and deactivate the slice for GPU pagetable walks
in the system cache upon GPU power collapse/restore.
Configure the SCID for the slice.
Also enable the SMMU domain attribute to allocate pagetable
memory with the right memory attributes for them to be
allocated into the system cache.

CRs-Fixed: 1081617
Change-Id: I16c174b413eaa4aa5c6a3514c9a18f8c990812da
Signed-off-by: default avatarSushmita Susheelendra <ssusheel@codeaurora.org>
parent b1976689
Loading
Loading
Loading
Loading
+13 −0
Original line number Original line Diff line number Diff line
@@ -1037,6 +1037,15 @@ static int adreno_probe(struct platform_device *pdev)
		adreno_dev->gpu_llc_slice = NULL;
		adreno_dev->gpu_llc_slice = NULL;
	}
	}


	/* Get the system cache slice descriptor for GPU pagetables */
	adreno_dev->gpuhtw_llc_slice = adreno_llc_getd(&pdev->dev, "gpuhtw");
	if (IS_ERR(adreno_dev->gpuhtw_llc_slice)) {
		KGSL_DRV_WARN(device,
			"Failed to get gpuhtw LLC slice descriptor (%ld)\n",
			PTR_ERR(adreno_dev->gpuhtw_llc_slice));
		adreno_dev->gpuhtw_llc_slice = NULL;
	}

	adreno_input_handler.private = device;
	adreno_input_handler.private = device;


#ifdef CONFIG_INPUT
#ifdef CONFIG_INPUT
@@ -1109,6 +1118,8 @@ static int adreno_remove(struct platform_device *pdev)
	/* Release the system cache slice descriptor */
	/* Release the system cache slice descriptor */
	if (adreno_dev->gpu_llc_slice)
	if (adreno_dev->gpu_llc_slice)
		adreno_llc_putd(adreno_dev->gpu_llc_slice);
		adreno_llc_putd(adreno_dev->gpu_llc_slice);
	if (adreno_dev->gpuhtw_llc_slice)
		adreno_llc_putd(adreno_dev->gpuhtw_llc_slice);


	kgsl_pwrscale_close(device);
	kgsl_pwrscale_close(device);


@@ -1578,6 +1589,8 @@ static int adreno_stop(struct kgsl_device *device)


	if (adreno_dev->gpu_llc_slice)
	if (adreno_dev->gpu_llc_slice)
		adreno_llc_deactivate_slice(adreno_dev->gpu_llc_slice);
		adreno_llc_deactivate_slice(adreno_dev->gpu_llc_slice);
	if (adreno_dev->gpuhtw_llc_slice)
		adreno_llc_deactivate_slice(adreno_dev->gpuhtw_llc_slice);


	/* Save active coresight registers if applicable */
	/* Save active coresight registers if applicable */
	adreno_coresight_stop(adreno_dev);
	adreno_coresight_stop(adreno_dev);
+3 −0
Original line number Original line Diff line number Diff line
@@ -398,6 +398,7 @@ struct adreno_gpu_core {
 * @active_list_lock: Lock to protect active_list
 * @active_list_lock: Lock to protect active_list
 * @gpu_llc_slice: GPU system cache slice descriptor
 * @gpu_llc_slice: GPU system cache slice descriptor
 * @gpu_llc_slice_enable: To enable the GPU system cache slice or not
 * @gpu_llc_slice_enable: To enable the GPU system cache slice or not
 * @gpuhtw_llc_slice: GPU pagetables system cache slice descriptor
 */
 */
struct adreno_device {
struct adreno_device {
	struct kgsl_device dev;    /* Must be first field in this struct */
	struct kgsl_device dev;    /* Must be first field in this struct */
@@ -459,6 +460,7 @@ struct adreno_device {


	void *gpu_llc_slice;
	void *gpu_llc_slice;
	bool gpu_llc_slice_enable;
	bool gpu_llc_slice_enable;
	void *gpuhtw_llc_slice;
};
};


/**
/**
@@ -815,6 +817,7 @@ struct adreno_gpudev {
	void (*clk_set_options)(struct adreno_device *,
	void (*clk_set_options)(struct adreno_device *,
				const char *, struct clk *);
				const char *, struct clk *);
	void (*llc_configure_gpu_scid)(struct adreno_device *adreno_dev);
	void (*llc_configure_gpu_scid)(struct adreno_device *adreno_dev);
	void (*llc_configure_gpuhtw_scid)(struct adreno_device *adreno_dev);
	void (*llc_enable_overrides)(struct adreno_device *adreno_dev);
	void (*llc_enable_overrides)(struct adreno_device *adreno_dev);
};
};


+23 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,10 @@
#define A6XX_GPU_LLC_SCID_NUM_BITS	5
#define A6XX_GPU_LLC_SCID_NUM_BITS	5
#define A6XX_GPU_LLC_SCID_MASK \
#define A6XX_GPU_LLC_SCID_MASK \
	((1 << (A6XX_LLC_NUM_GPU_SCIDS * A6XX_GPU_LLC_SCID_NUM_BITS)) - 1)
	((1 << (A6XX_LLC_NUM_GPU_SCIDS * A6XX_GPU_LLC_SCID_NUM_BITS)) - 1)
#define A6XX_GPUHTW_LLC_SCID_SHIFT	25
#define A6XX_GPUHTW_LLC_SCID_MASK \
	(((1 << A6XX_GPU_LLC_SCID_NUM_BITS) - 1) << A6XX_GPUHTW_LLC_SCID_SHIFT)

#define A6XX_GPU_CX_REG_BASE		0x509E000
#define A6XX_GPU_CX_REG_BASE		0x509E000
#define A6XX_GPU_CX_REG_SIZE		0x1000
#define A6XX_GPU_CX_REG_SIZE		0x1000


@@ -629,6 +633,24 @@ static void a6xx_llc_configure_gpu_scid(struct adreno_device *adreno_dev)
	iounmap(gpu_cx_reg);
	iounmap(gpu_cx_reg);
}
}


/*
 * a6xx_llc_configure_gpuhtw_scid() - Program the SCID for GPU pagetables
 * @adreno_dev: The adreno device pointer
 */
static void a6xx_llc_configure_gpuhtw_scid(struct adreno_device *adreno_dev)
{
	uint32_t gpuhtw_scid;
	void __iomem *gpu_cx_reg;

	gpuhtw_scid = adreno_llc_get_scid(adreno_dev->gpuhtw_llc_slice);

	gpu_cx_reg = ioremap(A6XX_GPU_CX_REG_BASE, A6XX_GPU_CX_REG_SIZE);
	extregrmw(gpu_cx_reg + A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1,
			A6XX_GPUHTW_LLC_SCID_MASK,
			gpuhtw_scid << A6XX_GPUHTW_LLC_SCID_SHIFT);
	iounmap(gpu_cx_reg);
}

/*
/*
 * a6xx_llc_enable_overrides() - Override the page attributes
 * a6xx_llc_enable_overrides() - Override the page attributes
 * @adreno_dev: The adreno device pointer
 * @adreno_dev: The adreno device pointer
@@ -762,5 +784,6 @@ struct adreno_gpudev adreno_a6xx_gpudev = {
	.microcode_read = a6xx_microcode_read,
	.microcode_read = a6xx_microcode_read,
	.enable_64bit = a6xx_enable_64bit,
	.enable_64bit = a6xx_enable_64bit,
	.llc_configure_gpu_scid = a6xx_llc_configure_gpu_scid,
	.llc_configure_gpu_scid = a6xx_llc_configure_gpu_scid,
	.llc_configure_gpuhtw_scid = a6xx_llc_configure_gpuhtw_scid,
	.llc_enable_overrides = a6xx_llc_enable_overrides
	.llc_enable_overrides = a6xx_llc_enable_overrides
};
};
+9 −2
Original line number Original line Diff line number Diff line
@@ -52,10 +52,17 @@ static inline void adreno_llc_setup(struct kgsl_device *device)
		if (!llcc_slice_activate(adreno_dev->gpu_llc_slice)) {
		if (!llcc_slice_activate(adreno_dev->gpu_llc_slice)) {
			if (gpudev->llc_configure_gpu_scid)
			if (gpudev->llc_configure_gpu_scid)
				gpudev->llc_configure_gpu_scid(adreno_dev);
				gpudev->llc_configure_gpu_scid(adreno_dev);
		}

	if (adreno_dev->gpuhtw_llc_slice)
		if (!llcc_slice_activate(adreno_dev->gpuhtw_llc_slice)) {
			if (gpudev->llc_configure_gpuhtw_scid)
				gpudev->llc_configure_gpuhtw_scid(adreno_dev);
		}

	if (gpudev->llc_enable_overrides)
	if (gpudev->llc_enable_overrides)
		gpudev->llc_enable_overrides(adreno_dev);
		gpudev->llc_enable_overrides(adreno_dev);
}
}
}


#else
#else
static inline bool adreno_llc_supported(void)
static inline bool adreno_llc_supported(void)
+28 −0
Original line number Original line Diff line number Diff line
@@ -1142,6 +1142,28 @@ static void _free_pt(struct kgsl_iommu_context *ctx, struct kgsl_pagetable *pt)
	kfree(iommu_pt);
	kfree(iommu_pt);
}
}


void _enable_gpuhtw_llc(struct kgsl_mmu *mmu, struct kgsl_iommu_pt *iommu_pt)
{
	struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	int gpuhtw_llc_enable = 1;
	int ret;

	/* GPU pagetable walk LLC slice not enabled */
	if (!adreno_dev->gpuhtw_llc_slice)
		return;

	/* Domain attribute to enable system cache for GPU pagetable walks */
	ret = iommu_domain_set_attr(iommu_pt->domain,
			DOMAIN_ATTR_USE_UPSTREAM_HINT, &gpuhtw_llc_enable);
	/*
	 * Warn that the system cache will not be used for GPU
	 * pagetable walks. This is not a fatal error.
	 */
	WARN_ONCE(ret,
		"System cache not enabled for GPU pagetable walks: %d\n", ret);
}

static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
{
{
	int ret = 0;
	int ret = 0;
@@ -1165,6 +1187,8 @@ static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
		}
		}
	}
	}


	_enable_gpuhtw_llc(mmu, iommu_pt);

	ret = _attach_pt(iommu_pt, ctx);
	ret = _attach_pt(iommu_pt, ctx);
	if (ret)
	if (ret)
		goto done;
		goto done;
@@ -1237,6 +1261,8 @@ static int _init_secure_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
		goto done;
		goto done;
	}
	}


	_enable_gpuhtw_llc(mmu, iommu_pt);

	ret = _attach_pt(iommu_pt, ctx);
	ret = _attach_pt(iommu_pt, ctx);


	if (MMU_FEATURE(mmu, KGSL_MMU_HYP_SECURE_ALLOC))
	if (MMU_FEATURE(mmu, KGSL_MMU_HYP_SECURE_ALLOC))
@@ -1297,6 +1323,8 @@ static int _init_per_process_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
		goto done;
		goto done;
	}
	}


	_enable_gpuhtw_llc(mmu, iommu_pt);

	ret = _attach_pt(iommu_pt, ctx);
	ret = _attach_pt(iommu_pt, ctx);
	if (ret)
	if (ret)
		goto done;
		goto done;