On Fri, Jun 28, 2024 at 8:10 AM Bibek Kumar Patro <quic_bibekkum@xxxxxxxxxxx> wrote: > > > > On 6/28/2024 7:47 PM, Rob Clark wrote: > > On Fri, Jun 28, 2024 at 7:05 AM Bibek Kumar Patro > > <quic_bibekkum@xxxxxxxxxxx> wrote: > >> > >> Add an adreno-smmu-priv interface for drm/msm to call > >> into arm-smmu-qcom and initiate the PRR bit setup or reset > >> sequence as per request. > >> > >> This will be used by GPU to setup the PRR bit and related > >> configuration registers through adreno-smmu private > >> interface instead of directly poking the smmu hardware. > >> > >> Suggested-by: Rob Clark <robdclark@xxxxxxxxx> > >> Signed-off-by: Bibek Kumar Patro <quic_bibekkum@xxxxxxxxxxx> > >> --- > >> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 23 ++++++++++++++++++++++ > >> drivers/iommu/arm/arm-smmu/arm-smmu.h | 2 ++ > >> include/linux/adreno-smmu-priv.h | 6 +++++- > >> 3 files changed, 30 insertions(+), 1 deletion(-) > >> > >> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > >> index bd101a161d04..64571a1c47b8 100644 > >> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > >> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > >> @@ -28,6 +28,7 @@ > >> #define PREFETCH_SHALLOW (1 << PREFETCH_SHIFT) > >> #define PREFETCH_MODERATE (2 << PREFETCH_SHIFT) > >> #define PREFETCH_DEEP (3 << PREFETCH_SHIFT) > >> +#define GFX_ACTLR_PRR (1 << 5) > >> > >> static const struct actlr_config sc7280_apps_actlr_cfg[] = { > >> { 0x0800, 0x04e0, PREFETCH_DEFAULT | CMTLB }, > >> @@ -235,6 +236,27 @@ static void qcom_adreno_smmu_resume_translation(const void *cookie, bool termina > >> arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_RESUME, reg); > >> } > >> > >> +static void qcom_adreno_smmu_set_prr(const void *cookie, phys_addr_t page_addr, bool set) > >> +{ > >> + struct arm_smmu_domain *smmu_domain = (void *)cookie; > >> + struct arm_smmu_cfg *cfg = &smmu_domain->cfg; > >> + struct arm_smmu_device *smmu = smmu_domain->smmu; > >> + u32 reg = 0; > >> + > >> + writel_relaxed(lower_32_bits(page_addr), > >> + smmu->base + ARM_SMMU_GFX_PRR_CFG_LADDR); > >> + > >> + writel_relaxed(upper_32_bits(page_addr), > >> + smmu->base + ARM_SMMU_GFX_PRR_CFG_UADDR); > >> + > >> + reg = arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR); > >> + reg &= ~GFX_ACTLR_PRR; > >> + if (set) > >> + reg |= FIELD_PREP(GFX_ACTLR_PRR, 1); > >> + arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_ACTLR, reg); > >> + > > > > nit, extra line > > > > Ack, will remove this. Thanks for pointing out. > > > Also, if you passed a `struct page *` instead, then you could drop the > > bool param, ie. passing NULL for the page would disable PRR. But I > > can go either way if others have a strong preference for phys_addr_t. > > > > Oh okay, this looks simple to reset the prr bit. > But since this page is allocated and is used inside gfx driver > before being utilized for prr bit operation, would it be safe for > drm/gfx driver to keep a reference to this page in smmu driver? > > Since we only need the page address for configuring the > CFG_UADDR/CFG_LADDR registers so passed the phys_addr_t. I don't think the smmu driver needs to keep a reference to the page.. we can just say it is the responsibility of the drm driver to call set_prr(NULL) before freeing the page BR, -R > > Otherwise, lgtm > > > > BR, > > -R > > > > Thanks & regards, > Bibek > > >> +} > >> + > >> #define QCOM_ADRENO_SMMU_GPU_SID 0 > >> > >> static bool qcom_adreno_smmu_is_gpu_device(struct device *dev) > >> @@ -407,6 +429,7 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain, > >> priv->get_fault_info = qcom_adreno_smmu_get_fault_info; > >> priv->set_stall = qcom_adreno_smmu_set_stall; > >> priv->resume_translation = qcom_adreno_smmu_resume_translation; > >> + priv->set_prr = qcom_adreno_smmu_set_prr; > >> > >> actlrvar = qsmmu->data->actlrvar; > >> if (!actlrvar) > >> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h > >> index d9c2ef8c1653..3076bef49e20 100644 > >> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h > >> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h > >> @@ -154,6 +154,8 @@ enum arm_smmu_cbar_type { > >> #define ARM_SMMU_SCTLR_M BIT(0) > >> > >> #define ARM_SMMU_CB_ACTLR 0x4 > >> +#define ARM_SMMU_GFX_PRR_CFG_LADDR 0x6008 > >> +#define ARM_SMMU_GFX_PRR_CFG_UADDR 0x600C > >> > >> #define ARM_SMMU_CB_RESUME 0x8 > >> #define ARM_SMMU_RESUME_TERMINATE BIT(0) > >> diff --git a/include/linux/adreno-smmu-priv.h b/include/linux/adreno-smmu-priv.h > >> index c637e0997f6d..d6e2ca9f8d8c 100644 > >> --- a/include/linux/adreno-smmu-priv.h > >> +++ b/include/linux/adreno-smmu-priv.h > >> @@ -49,7 +49,10 @@ struct adreno_smmu_fault_info { > >> * before set_ttbr0_cfg(). If stalling on fault is enabled, > >> * the GPU driver must call resume_translation() > >> * @resume_translation: Resume translation after a fault > >> - * > >> + * @set_prr: Extendible interface to be used by GPU to modify the > >> + * ACTLR register bits, currently used to configure > >> + * Partially-Resident-Region (PRR) feature's > >> + * setup and reset sequence as requested. > >> * > >> * The GPU driver (drm/msm) and adreno-smmu work together for controlling > >> * the GPU's SMMU instance. This is by necessity, as the GPU is directly > >> @@ -67,6 +70,7 @@ struct adreno_smmu_priv { > >> void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info); > >> void (*set_stall)(const void *cookie, bool enabled); > >> void (*resume_translation)(const void *cookie, bool terminate); > >> + void (*set_prr)(const void *cookie, phys_addr_t page_addr, bool set); > >> }; > >> > >> #endif /* __ADRENO_SMMU_PRIV_H */ > >> -- > >> 2.34.1 > >>