* [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings
2023-11-27 14:54 [PATCH v3 0/4] iommu/arm-smmu: introduction of ACTLR implementation for Qualcomm SoCs Bibek Kumar Patro
@ 2023-11-27 14:54 ` Bibek Kumar Patro
2023-11-27 15:33 ` Konrad Dybcio
` (3 more replies)
2023-11-27 14:54 ` [PATCH v3 2/4] iommu/arm-smmu: add ACTLR data and support for SM8550 Bibek Kumar Patro
` (2 subsequent siblings)
3 siblings, 4 replies; 16+ messages in thread
From: Bibek Kumar Patro @ 2023-11-27 14:54 UTC (permalink / raw)
To: will, robin.murphy, joro, dmitry.baryshkov, a39.skl,
konrad.dybcio, quic_bjorande, mani, quic_eberman, robdclark,
u.kleine-koenig, robh, vladimir.oltean, quic_pkondeti,
quic_molvera
Cc: linux-arm-msm, linux-arm-kernel, iommu, linux-kernel,
qipl.kernel.upstream, Bibek Kumar Patro
Currently in Qualcomm SoCs the default prefetch is set to 1 which allows
the TLB to fetch just the next page table. MMU-500 features ACTLR
register which is implementation defined and is used for Qualcomm SoCs
to have a prefetch setting of 1/3/7/15 enabling TLB to prefetch
the next set of page tables accordingly allowing for faster translations.
ACTLR value is unique for each SMR (Stream matching register) and stored
in a pre-populated table. This value is set to the register during
context bank initialisation.
Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
---
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 56 +++++++++++++++++++++-
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 6 ++-
drivers/iommu/arm/arm-smmu/arm-smmu.c | 5 +-
drivers/iommu/arm/arm-smmu/arm-smmu.h | 5 ++
4 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 7f52ac67495f..4a38cae29be2 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -14,6 +14,12 @@
#define QCOM_DUMMY_VAL -1
+struct actlr_config {
+ u16 sid;
+ u16 mask;
+ u32 actlr;
+};
+
static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
{
return container_of(smmu, struct qcom_smmu, smmu);
@@ -205,10 +211,40 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
return true;
}
+static void arm_smmu_set_actlr(struct device *dev, struct arm_smmu_device *smmu, int cbndx,
+ const struct actlr_config *actlrcfg, size_t actlrcfg_size)
+{
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+ struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
+ struct arm_smmu_smr *smr;
+ int i;
+ int j;
+ u16 id;
+ u16 mask;
+ int idx;
+
+ for (i = 0; i < actlrcfg_size; ++i) {
+ id = (actlrcfg + i)->sid;
+ mask = (actlrcfg + i)->mask;
+
+ for_each_cfg_sme(cfg, fwspec, j, idx) {
+ smr = &smmu->smrs[idx];
+ if (smr_is_subset(*smr, id, mask))
+ arm_smmu_cb_write(smmu, cbndx, ARM_SMMU_CB_ACTLR,
+ (actlrcfg + i)->actlr);
+ }
+ }
+}
+
static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
{
struct adreno_smmu_priv *priv;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
+ struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+ const struct actlr_config *actlrcfg;
+ size_t actlrcfg_size;
+ int cbndx = smmu_domain->cfg.cbndx;
smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
@@ -238,6 +274,12 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
priv->set_stall = qcom_adreno_smmu_set_stall;
priv->resume_translation = qcom_adreno_smmu_resume_translation;
+ if (qsmmu->data->actlrcfg_gfx) {
+ actlrcfg = qsmmu->data->actlrcfg_gfx;
+ actlrcfg_size = qsmmu->data->actlrcfg_gfx_size;
+ arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
+ }
+
return 0;
}
@@ -263,6 +305,18 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
{
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
+ struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+ const struct actlr_config *actlrcfg;
+ size_t actlrcfg_size;
+ int cbndx = smmu_domain->cfg.cbndx;
+
+ if (qsmmu->data->actlrcfg) {
+ actlrcfg = qsmmu->data->actlrcfg;
+ actlrcfg_size = qsmmu->data->actlrcfg_size;
+ arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
+ }
+
smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
return 0;
@@ -464,7 +518,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
return ERR_PTR(-ENOMEM);
qsmmu->smmu.impl = impl;
- qsmmu->cfg = data->cfg;
+ qsmmu->data = data;
return &qsmmu->smmu;
}
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
index 593910567b88..138fc57f7b0d 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
@@ -8,7 +8,7 @@
struct qcom_smmu {
struct arm_smmu_device smmu;
- const struct qcom_smmu_config *cfg;
+ const struct qcom_smmu_match_data *data;
bool bypass_quirk;
u8 bypass_cbndx;
u32 stall_enabled;
@@ -25,6 +25,10 @@ struct qcom_smmu_config {
};
struct qcom_smmu_match_data {
+ const struct actlr_config *actlrcfg;
+ size_t actlrcfg_size;
+ const struct actlr_config *actlrcfg_gfx;
+ size_t actlrcfg_gfx_size;
const struct qcom_smmu_config *cfg;
const struct arm_smmu_impl *impl;
const struct arm_smmu_impl *adreno_impl;
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index d6d1a2a55cc0..8e4faf015286 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -990,9 +990,10 @@ static int arm_smmu_find_sme(struct arm_smmu_device *smmu, u16 id, u16 mask)
* expect simply identical entries for this case, but there's
* no harm in accommodating the generalisation.
*/
- if ((mask & smrs[i].mask) == mask &&
- !((id ^ smrs[i].id) & ~smrs[i].mask))
+
+ if (smr_is_subset(smrs[i], id, mask))
return i;
+
/*
* If the new entry has any other overlap with an existing one,
* though, then there always exists at least one stream ID
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index 703fd5817ec1..b1638bbc41d4 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -501,6 +501,11 @@ static inline void arm_smmu_writeq(struct arm_smmu_device *smmu, int page,
writeq_relaxed(val, arm_smmu_page(smmu, page) + offset);
}
+static inline bool smr_is_subset(struct arm_smmu_smr smrs, u16 id, u16 mask)
+{
+ return (mask & smrs.mask) == mask && !((id ^ smrs.id) & ~smrs.mask);
+}
+
#define ARM_SMMU_GR0 0
#define ARM_SMMU_GR1 1
#define ARM_SMMU_CB(s, n) ((s)->numpage + (n))
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings
2023-11-27 14:54 ` [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings Bibek Kumar Patro
@ 2023-11-27 15:33 ` Konrad Dybcio
2023-11-29 11:47 ` Bibek Kumar Patro
2023-11-27 16:07 ` Dmitry Baryshkov
` (2 subsequent siblings)
3 siblings, 1 reply; 16+ messages in thread
From: Konrad Dybcio @ 2023-11-27 15:33 UTC (permalink / raw)
To: Bibek Kumar Patro, will, robin.murphy, joro, dmitry.baryshkov,
a39.skl, quic_bjorande, mani, quic_eberman, robdclark,
u.kleine-koenig, robh, vladimir.oltean, quic_pkondeti,
quic_molvera
Cc: linux-arm-msm, linux-arm-kernel, iommu, linux-kernel,
qipl.kernel.upstream
On 27.11.2023 15:54, Bibek Kumar Patro wrote:
> Currently in Qualcomm SoCs the default prefetch is set to 1 which allows
> the TLB to fetch just the next page table. MMU-500 features ACTLR
> register which is implementation defined and is used for Qualcomm SoCs
> to have a prefetch setting of 1/3/7/15 enabling TLB to prefetch
> the next set of page tables accordingly allowing for faster translations.
>
> ACTLR value is unique for each SMR (Stream matching register) and stored
> in a pre-populated table. This value is set to the register during
> context bank initialisation.
>
> Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
>
> ---
> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 56 +++++++++++++++++++++-
> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 6 ++-
> drivers/iommu/arm/arm-smmu/arm-smmu.c | 5 +-
> drivers/iommu/arm/arm-smmu/arm-smmu.h | 5 ++
> 4 files changed, 68 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 7f52ac67495f..4a38cae29be2 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -14,6 +14,12 @@
>
> #define QCOM_DUMMY_VAL -1
>
> +struct actlr_config {
> + u16 sid;
> + u16 mask;
> + u32 actlr;
> +};
> +
> static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
> {
> return container_of(smmu, struct qcom_smmu, smmu);
> @@ -205,10 +211,40 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
> return true;
> }
>
> +static void arm_smmu_set_actlr(struct device *dev, struct arm_smmu_device *smmu, int cbndx,
> + const struct actlr_config *actlrcfg, size_t actlrcfg_size)
> +{
> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> + struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
> + struct arm_smmu_smr *smr;
> + int i;
> + int j;
> + u16 id;
> + u16 mask;
> + int idx;
> +
> + for (i = 0; i < actlrcfg_size; ++i) {
> + id = (actlrcfg + i)->sid;
> + mask = (actlrcfg + i)->mask;
actrlcfg[i].id?
> +
> + for_each_cfg_sme(cfg, fwspec, j, idx) {
> + smr = &smmu->smrs[idx];
> + if (smr_is_subset(*smr, id, mask))
Any reason for this value to be a pointer?
> + arm_smmu_cb_write(smmu, cbndx, ARM_SMMU_CB_ACTLR,
> + (actlrcfg + i)->actlr);
ditto
> + }
> + }
> +}
> +
> static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
> {
> struct adreno_smmu_priv *priv;
> + struct arm_smmu_device *smmu = smmu_domain->smmu;
> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> + const struct actlr_config *actlrcfg;
> + size_t actlrcfg_size;
> + int cbndx = smmu_domain->cfg.cbndx;
Reverse-Christmas-tree sorting, please
>
> smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>
> @@ -238,6 +274,12 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> priv->set_stall = qcom_adreno_smmu_set_stall;
> priv->resume_translation = qcom_adreno_smmu_resume_translation;
>
> + if (qsmmu->data->actlrcfg_gfx) {
> + actlrcfg = qsmmu->data->actlrcfg_gfx;
> + actlrcfg_size = qsmmu->data->actlrcfg_gfx_size;
These can be passed directly s arm_smmu_set_actrl arguments
> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
> + }
> +
> return 0;
> }
>
> @@ -263,6 +305,18 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
> static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
> {
> + struct arm_smmu_device *smmu = smmu_domain->smmu;
> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> + const struct actlr_config *actlrcfg;
> + size_t actlrcfg_size;
> + int cbndx = smmu_domain->cfg.cbndx;
> +
> + if (qsmmu->data->actlrcfg) {
> + actlrcfg = qsmmu->data->actlrcfg;
> + actlrcfg_size = qsmmu->data->actlrcfg_size;
> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
ditto
Konrad
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings
2023-11-27 15:33 ` Konrad Dybcio
@ 2023-11-29 11:47 ` Bibek Kumar Patro
0 siblings, 0 replies; 16+ messages in thread
From: Bibek Kumar Patro @ 2023-11-29 11:47 UTC (permalink / raw)
To: Konrad Dybcio, will, robin.murphy, joro, dmitry.baryshkov,
a39.skl, quic_bjorande, mani, quic_eberman, robdclark,
u.kleine-koenig, robh, vladimir.oltean, quic_pkondeti,
quic_molvera
Cc: linux-arm-msm, linux-arm-kernel, iommu, linux-kernel,
qipl.kernel.upstream
On 11/27/2023 9:03 PM, Konrad Dybcio wrote:
> On 27.11.2023 15:54, Bibek Kumar Patro wrote:
>> Currently in Qualcomm SoCs the default prefetch is set to 1 which allows
>> the TLB to fetch just the next page table. MMU-500 features ACTLR
>> register which is implementation defined and is used for Qualcomm SoCs
>> to have a prefetch setting of 1/3/7/15 enabling TLB to prefetch
>> the next set of page tables accordingly allowing for faster translations.
>>
>> ACTLR value is unique for each SMR (Stream matching register) and stored
>> in a pre-populated table. This value is set to the register during
>> context bank initialisation.
>>
>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
>>
>> ---
>> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 56 +++++++++++++++++++++-
>> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 6 ++-
>> drivers/iommu/arm/arm-smmu/arm-smmu.c | 5 +-
>> drivers/iommu/arm/arm-smmu/arm-smmu.h | 5 ++
>> 4 files changed, 68 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> index 7f52ac67495f..4a38cae29be2 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> @@ -14,6 +14,12 @@
>>
>> #define QCOM_DUMMY_VAL -1
>>
>> +struct actlr_config {
>> + u16 sid;
>> + u16 mask;
>> + u32 actlr;
>> +};
>> +
>> static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
>> {
>> return container_of(smmu, struct qcom_smmu, smmu);
>> @@ -205,10 +211,40 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
>> return true;
>> }
>>
>> +static void arm_smmu_set_actlr(struct device *dev, struct arm_smmu_device *smmu, int cbndx,
>> + const struct actlr_config *actlrcfg, size_t actlrcfg_size)
>> +{
>> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
>> + struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
>> + struct arm_smmu_smr *smr;
>> + int i;
>> + int j;
>> + u16 id;
>> + u16 mask;
>> + int idx;
>> +
>> + for (i = 0; i < actlrcfg_size; ++i) {
>> + id = (actlrcfg + i)->sid;
>> + mask = (actlrcfg + i)->mask;
> actrlcfg[i].id?
>
Noted, array indexing instead of incrementing the base address
should also work.
>> +
>> + for_each_cfg_sme(cfg, fwspec, j, idx) {
>> + smr = &smmu->smrs[idx];
>> + if (smr_is_subset(*smr, id, mask))
> Any reason for this value to be a pointer?
>
>> + arm_smmu_cb_write(smmu, cbndx, ARM_SMMU_CB_ACTLR,
>> + (actlrcfg + i)->actlr);
> ditto
>
Noted
>> + }
>> + }
>> +}
>> +
>> static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>> {
>> struct adreno_smmu_priv *priv;
>> + struct arm_smmu_device *smmu = smmu_domain->smmu;
>> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
>> + const struct actlr_config *actlrcfg;
>> + size_t actlrcfg_size;
>> + int cbndx = smmu_domain->cfg.cbndx;
> Reverse-Christmas-tree sorting, please
>
Noted, thanks for pointing this, I will
take care of this in next revision.
>>
>> smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>>
>> @@ -238,6 +274,12 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>> priv->set_stall = qcom_adreno_smmu_set_stall;
>> priv->resume_translation = qcom_adreno_smmu_resume_translation;
>>
>> + if (qsmmu->data->actlrcfg_gfx) {
>> + actlrcfg = qsmmu->data->actlrcfg_gfx;
>> + actlrcfg_size = qsmmu->data->actlrcfg_gfx_size;
> These can be passed directly s arm_smmu_set_actrl arguments
>
Noted, will address in next revision. since there won't be any issue
during time of access, I can pass these values directly.
>> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
>> + }
>> +
>> return 0;
>> }
>>
>> @@ -263,6 +305,18 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
>> static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>> {
>> + struct arm_smmu_device *smmu = smmu_domain->smmu;
>> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
>> + const struct actlr_config *actlrcfg;
>> + size_t actlrcfg_size;
>> + int cbndx = smmu_domain->cfg.cbndx;
>> +
>> + if (qsmmu->data->actlrcfg) {
>> + actlrcfg = qsmmu->data->actlrcfg;
>> + actlrcfg_size = qsmmu->data->actlrcfg_size;
>> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
> ditto
>
Noted.
> Konrad
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings
2023-11-27 14:54 ` [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings Bibek Kumar Patro
2023-11-27 15:33 ` Konrad Dybcio
@ 2023-11-27 16:07 ` Dmitry Baryshkov
2023-11-29 8:43 ` Bibek Kumar Patro
2023-11-29 12:04 ` Bibek Kumar Patro
2023-11-28 3:01 ` Bjorn Andersson
2023-12-01 10:09 ` kernel test robot
3 siblings, 2 replies; 16+ messages in thread
From: Dmitry Baryshkov @ 2023-11-27 16:07 UTC (permalink / raw)
To: Bibek Kumar Patro
Cc: will, robin.murphy, joro, a39.skl, konrad.dybcio, quic_bjorande,
mani, quic_eberman, robdclark, u.kleine-koenig, robh,
vladimir.oltean, quic_pkondeti, quic_molvera, linux-arm-msm,
linux-arm-kernel, iommu, linux-kernel, qipl.kernel.upstream
On Mon, 27 Nov 2023 at 16:54, Bibek Kumar Patro
<quic_bibekkum@quicinc.com> wrote:
>
> Currently in Qualcomm SoCs the default prefetch is set to 1 which allows
> the TLB to fetch just the next page table. MMU-500 features ACTLR
> register which is implementation defined and is used for Qualcomm SoCs
> to have a prefetch setting of 1/3/7/15 enabling TLB to prefetch
> the next set of page tables accordingly allowing for faster translations.
>
> ACTLR value is unique for each SMR (Stream matching register) and stored
> in a pre-populated table. This value is set to the register during
> context bank initialisation.
>
> Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
>
> ---
> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 56 +++++++++++++++++++++-
> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 6 ++-
> drivers/iommu/arm/arm-smmu/arm-smmu.c | 5 +-
> drivers/iommu/arm/arm-smmu/arm-smmu.h | 5 ++
> 4 files changed, 68 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 7f52ac67495f..4a38cae29be2 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -14,6 +14,12 @@
>
> #define QCOM_DUMMY_VAL -1
>
> +struct actlr_config {
> + u16 sid;
> + u16 mask;
> + u32 actlr;
> +};
> +
> static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
> {
> return container_of(smmu, struct qcom_smmu, smmu);
> @@ -205,10 +211,40 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
> return true;
> }
>
> +static void arm_smmu_set_actlr(struct device *dev, struct arm_smmu_device *smmu, int cbndx,
> + const struct actlr_config *actlrcfg, size_t actlrcfg_size)
> +{
> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> + struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
> + struct arm_smmu_smr *smr;
> + int i;
> + int j;
> + u16 id;
> + u16 mask;
> + int idx;
> +
> + for (i = 0; i < actlrcfg_size; ++i) {
> + id = (actlrcfg + i)->sid;
> + mask = (actlrcfg + i)->mask;
> +
> + for_each_cfg_sme(cfg, fwspec, j, idx) {
> + smr = &smmu->smrs[idx];
> + if (smr_is_subset(*smr, id, mask))
> + arm_smmu_cb_write(smmu, cbndx, ARM_SMMU_CB_ACTLR,
> + (actlrcfg + i)->actlr);
> + }
> + }
> +}
> +
> static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
> {
> struct adreno_smmu_priv *priv;
> + struct arm_smmu_device *smmu = smmu_domain->smmu;
> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> + const struct actlr_config *actlrcfg;
> + size_t actlrcfg_size;
> + int cbndx = smmu_domain->cfg.cbndx;
>
> smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>
> @@ -238,6 +274,12 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> priv->set_stall = qcom_adreno_smmu_set_stall;
> priv->resume_translation = qcom_adreno_smmu_resume_translation;
>
> + if (qsmmu->data->actlrcfg_gfx) {
> + actlrcfg = qsmmu->data->actlrcfg_gfx;
> + actlrcfg_size = qsmmu->data->actlrcfg_gfx_size;
> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
> + }
> +
> return 0;
> }
>
> @@ -263,6 +305,18 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
> static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
> {
> + struct arm_smmu_device *smmu = smmu_domain->smmu;
> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> + const struct actlr_config *actlrcfg;
> + size_t actlrcfg_size;
> + int cbndx = smmu_domain->cfg.cbndx;
> +
> + if (qsmmu->data->actlrcfg) {
> + actlrcfg = qsmmu->data->actlrcfg;
> + actlrcfg_size = qsmmu->data->actlrcfg_size;
> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
> + }
> +
> smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>
> return 0;
> @@ -464,7 +518,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
> return ERR_PTR(-ENOMEM);
>
> qsmmu->smmu.impl = impl;
> - qsmmu->cfg = data->cfg;
> + qsmmu->data = data;
This should go to a separate commit. It is not related to ACTLR support
>
> return &qsmmu->smmu;
> }
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
> index 593910567b88..138fc57f7b0d 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
> @@ -8,7 +8,7 @@
>
> struct qcom_smmu {
> struct arm_smmu_device smmu;
> - const struct qcom_smmu_config *cfg;
> + const struct qcom_smmu_match_data *data;
> bool bypass_quirk;
> u8 bypass_cbndx;
> u32 stall_enabled;
> @@ -25,6 +25,10 @@ struct qcom_smmu_config {
> };
>
> struct qcom_smmu_match_data {
> + const struct actlr_config *actlrcfg;
> + size_t actlrcfg_size;
> + const struct actlr_config *actlrcfg_gfx;
> + size_t actlrcfg_gfx_size;
> const struct qcom_smmu_config *cfg;
> const struct arm_smmu_impl *impl;
> const struct arm_smmu_impl *adreno_impl;
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index d6d1a2a55cc0..8e4faf015286 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -990,9 +990,10 @@ static int arm_smmu_find_sme(struct arm_smmu_device *smmu, u16 id, u16 mask)
> * expect simply identical entries for this case, but there's
> * no harm in accommodating the generalisation.
> */
> - if ((mask & smrs[i].mask) == mask &&
> - !((id ^ smrs[i].id) & ~smrs[i].mask))
> +
> + if (smr_is_subset(smrs[i], id, mask))
> return i;
> +
> /*
> * If the new entry has any other overlap with an existing one,
> * though, then there always exists at least one stream ID
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> index 703fd5817ec1..b1638bbc41d4 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> @@ -501,6 +501,11 @@ static inline void arm_smmu_writeq(struct arm_smmu_device *smmu, int page,
> writeq_relaxed(val, arm_smmu_page(smmu, page) + offset);
> }
>
> +static inline bool smr_is_subset(struct arm_smmu_smr smrs, u16 id, u16 mask)
A pointer to the struct, please
> +{
> + return (mask & smrs.mask) == mask && !((id ^ smrs.id) & ~smrs.mask);
> +}
> +
> #define ARM_SMMU_GR0 0
> #define ARM_SMMU_GR1 1
> #define ARM_SMMU_CB(s, n) ((s)->numpage + (n))
> --
> 2.17.1
>
--
With best wishes
Dmitry
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings
2023-11-27 16:07 ` Dmitry Baryshkov
@ 2023-11-29 8:43 ` Bibek Kumar Patro
2023-11-29 12:04 ` Bibek Kumar Patro
1 sibling, 0 replies; 16+ messages in thread
From: Bibek Kumar Patro @ 2023-11-29 8:43 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: will, robin.murphy, joro, a39.skl, konrad.dybcio, quic_bjorande,
mani, quic_eberman, robdclark, u.kleine-koenig, robh,
vladimir.oltean, quic_pkondeti, quic_molvera, linux-arm-msm,
linux-arm-kernel, iommu, linux-kernel, qipl.kernel.upstream
On 11/27/2023 9:37 PM, Dmitry Baryshkov wrote:
> On Mon, 27 Nov 2023 at 16:54, Bibek Kumar Patro
> <quic_bibekkum@quicinc.com> wrote:
>>
>> Currently in Qualcomm SoCs the default prefetch is set to 1 which allows
>> the TLB to fetch just the next page table. MMU-500 features ACTLR
>> register which is implementation defined and is used for Qualcomm SoCs
>> to have a prefetch setting of 1/3/7/15 enabling TLB to prefetch
>> the next set of page tables accordingly allowing for faster translations.
>>
>> ACTLR value is unique for each SMR (Stream matching register) and stored
>> in a pre-populated table. This value is set to the register during
>> context bank initialisation.
>>
>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
>>
>> ---
>> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 56 +++++++++++++++++++++-
>> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 6 ++-
>> drivers/iommu/arm/arm-smmu/arm-smmu.c | 5 +-
>> drivers/iommu/arm/arm-smmu/arm-smmu.h | 5 ++
>> 4 files changed, 68 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> index 7f52ac67495f..4a38cae29be2 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> @@ -14,6 +14,12 @@
>>
>> #define QCOM_DUMMY_VAL -1
>>
>> +struct actlr_config {
>> + u16 sid;
>> + u16 mask;
>> + u32 actlr;
>> +};
>> +
>> static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
>> {
>> return container_of(smmu, struct qcom_smmu, smmu);
>> @@ -205,10 +211,40 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
>> return true;
>> }
>>
>> +static void arm_smmu_set_actlr(struct device *dev, struct arm_smmu_device *smmu, int cbndx,
>> + const struct actlr_config *actlrcfg, size_t actlrcfg_size)
>> +{
>> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
>> + struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
>> + struct arm_smmu_smr *smr;
>> + int i;
>> + int j;
>> + u16 id;
>> + u16 mask;
>> + int idx;
>> +
>> + for (i = 0; i < actlrcfg_size; ++i) {
>> + id = (actlrcfg + i)->sid;
>> + mask = (actlrcfg + i)->mask;
>> +
>> + for_each_cfg_sme(cfg, fwspec, j, idx) {
>> + smr = &smmu->smrs[idx];
>> + if (smr_is_subset(*smr, id, mask))
>> + arm_smmu_cb_write(smmu, cbndx, ARM_SMMU_CB_ACTLR,
>> + (actlrcfg + i)->actlr);
>> + }
>> + }
>> +}
>> +
>> static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>> {
>> struct adreno_smmu_priv *priv;
>> + struct arm_smmu_device *smmu = smmu_domain->smmu;
>> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
>> + const struct actlr_config *actlrcfg;
>> + size_t actlrcfg_size;
>> + int cbndx = smmu_domain->cfg.cbndx;
>>
>> smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>>
>> @@ -238,6 +274,12 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>> priv->set_stall = qcom_adreno_smmu_set_stall;
>> priv->resume_translation = qcom_adreno_smmu_resume_translation;
>>
>> + if (qsmmu->data->actlrcfg_gfx) {
>> + actlrcfg = qsmmu->data->actlrcfg_gfx;
>> + actlrcfg_size = qsmmu->data->actlrcfg_gfx_size;
>> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
>> + }
>> +
>> return 0;
>> }
>>
>> @@ -263,6 +305,18 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
>> static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>> {
>> + struct arm_smmu_device *smmu = smmu_domain->smmu;
>> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
>> + const struct actlr_config *actlrcfg;
>> + size_t actlrcfg_size;
>> + int cbndx = smmu_domain->cfg.cbndx;
>> +
>> + if (qsmmu->data->actlrcfg) {
>> + actlrcfg = qsmmu->data->actlrcfg;
>> + actlrcfg_size = qsmmu->data->actlrcfg_size;
>> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
>> + }
>> +
>> smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>>
>> return 0;
>> @@ -464,7 +518,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
>> return ERR_PTR(-ENOMEM);
>>
>> qsmmu->smmu.impl = impl;
>> - qsmmu->cfg = data->cfg;
>> + qsmmu->data = data;
>
> This should go to a separate commit. It is not related to ACTLR support
>
>>
>> return &qsmmu->smmu;
>> }
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
>> index 593910567b88..138fc57f7b0d 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
>> @@ -8,7 +8,7 @@
>>
>> struct qcom_smmu {
>> struct arm_smmu_device smmu;
>> - const struct qcom_smmu_config *cfg;
>> + const struct qcom_smmu_match_data *data;
>> bool bypass_quirk;
>> u8 bypass_cbndx;
>> u32 stall_enabled;
>> @@ -25,6 +25,10 @@ struct qcom_smmu_config {
>> };
>>
>> struct qcom_smmu_match_data {
>> + const struct actlr_config *actlrcfg;
>> + size_t actlrcfg_size;
>> + const struct actlr_config *actlrcfg_gfx;
>> + size_t actlrcfg_gfx_size;
>> const struct qcom_smmu_config *cfg;
>> const struct arm_smmu_impl *impl;
>> const struct arm_smmu_impl *adreno_impl;
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> index d6d1a2a55cc0..8e4faf015286 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> @@ -990,9 +990,10 @@ static int arm_smmu_find_sme(struct arm_smmu_device *smmu, u16 id, u16 mask)
>> * expect simply identical entries for this case, but there's
>> * no harm in accommodating the generalisation.
>> */
>> - if ((mask & smrs[i].mask) == mask &&
>> - !((id ^ smrs[i].id) & ~smrs[i].mask))
>> +
>> + if (smr_is_subset(smrs[i], id, mask))
>> return i;
>> +
>> /*
>> * If the new entry has any other overlap with an existing one,
>> * though, then there always exists at least one stream ID
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>> index 703fd5817ec1..b1638bbc41d4 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>> @@ -501,6 +501,11 @@ static inline void arm_smmu_writeq(struct arm_smmu_device *smmu, int page,
>> writeq_relaxed(val, arm_smmu_page(smmu, page) + offset);
>> }
>>
>> +static inline bool smr_is_subset(struct arm_smmu_smr smrs, u16 id, u16 mask)
>
> A pointer to the struct, please
Noted, will evaluate address this in next revision.
Thanks & Regards,
Bibek
>
>> +{
>> + return (mask & smrs.mask) == mask && !((id ^ smrs.id) & ~smrs.mask);
>> +}
>> +
>> #define ARM_SMMU_GR0 0
>> #define ARM_SMMU_GR1 1
>> #define ARM_SMMU_CB(s, n) ((s)->numpage + (n))
>> --
>> 2.17.1
>>
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings
2023-11-27 16:07 ` Dmitry Baryshkov
2023-11-29 8:43 ` Bibek Kumar Patro
@ 2023-11-29 12:04 ` Bibek Kumar Patro
1 sibling, 0 replies; 16+ messages in thread
From: Bibek Kumar Patro @ 2023-11-29 12:04 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: will, robin.murphy, joro, a39.skl, konrad.dybcio, quic_bjorande,
mani, quic_eberman, robdclark, u.kleine-koenig, robh,
vladimir.oltean, quic_pkondeti, quic_molvera, linux-arm-msm,
linux-arm-kernel, iommu, linux-kernel, qipl.kernel.upstream
On 11/27/2023 9:37 PM, Dmitry Baryshkov wrote:
> On Mon, 27 Nov 2023 at 16:54, Bibek Kumar Patro
> <quic_bibekkum@quicinc.com> wrote:
>>
>> Currently in Qualcomm SoCs the default prefetch is set to 1 which allows
>> the TLB to fetch just the next page table. MMU-500 features ACTLR
>> register which is implementation defined and is used for Qualcomm SoCs
>> to have a prefetch setting of 1/3/7/15 enabling TLB to prefetch
>> the next set of page tables accordingly allowing for faster translations.
>>
>> ACTLR value is unique for each SMR (Stream matching register) and stored
>> in a pre-populated table. This value is set to the register during
>> context bank initialisation.
>>
>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
>>
>> ---
>> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 56 +++++++++++++++++++++-
>> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 6 ++-
>> drivers/iommu/arm/arm-smmu/arm-smmu.c | 5 +-
>> drivers/iommu/arm/arm-smmu/arm-smmu.h | 5 ++
>> 4 files changed, 68 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> index 7f52ac67495f..4a38cae29be2 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> @@ -14,6 +14,12 @@
>>
>> #define QCOM_DUMMY_VAL -1
>>
>> +struct actlr_config {
>> + u16 sid;
>> + u16 mask;
>> + u32 actlr;
>> +};
>> +
>> static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
>> {
>> return container_of(smmu, struct qcom_smmu, smmu);
>> @@ -205,10 +211,40 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
>> return true;
>> }
>>
>> +static void arm_smmu_set_actlr(struct device *dev, struct arm_smmu_device *smmu, int cbndx,
>> + const struct actlr_config *actlrcfg, size_t actlrcfg_size)
>> +{
>> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
>> + struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
>> + struct arm_smmu_smr *smr;
>> + int i;
>> + int j;
>> + u16 id;
>> + u16 mask;
>> + int idx;
>> +
>> + for (i = 0; i < actlrcfg_size; ++i) {
>> + id = (actlrcfg + i)->sid;
>> + mask = (actlrcfg + i)->mask;
>> +
>> + for_each_cfg_sme(cfg, fwspec, j, idx) {
>> + smr = &smmu->smrs[idx];
>> + if (smr_is_subset(*smr, id, mask))
>> + arm_smmu_cb_write(smmu, cbndx, ARM_SMMU_CB_ACTLR,
>> + (actlrcfg + i)->actlr);
>> + }
>> + }
>> +}
>> +
>> static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>> {
>> struct adreno_smmu_priv *priv;
>> + struct arm_smmu_device *smmu = smmu_domain->smmu;
>> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
>> + const struct actlr_config *actlrcfg;
>> + size_t actlrcfg_size;
>> + int cbndx = smmu_domain->cfg.cbndx;
>>
>> smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>>
>> @@ -238,6 +274,12 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>> priv->set_stall = qcom_adreno_smmu_set_stall;
>> priv->resume_translation = qcom_adreno_smmu_resume_translation;
>>
>> + if (qsmmu->data->actlrcfg_gfx) {
>> + actlrcfg = qsmmu->data->actlrcfg_gfx;
>> + actlrcfg_size = qsmmu->data->actlrcfg_gfx_size;
>> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
>> + }
>> +
>> return 0;
>> }
>>
>> @@ -263,6 +305,18 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
>> static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>> {
>> + struct arm_smmu_device *smmu = smmu_domain->smmu;
>> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
>> + const struct actlr_config *actlrcfg;
>> + size_t actlrcfg_size;
>> + int cbndx = smmu_domain->cfg.cbndx;
>> +
>> + if (qsmmu->data->actlrcfg) {
>> + actlrcfg = qsmmu->data->actlrcfg;
>> + actlrcfg_size = qsmmu->data->actlrcfg_size;
>> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
>> + }
>> +
>> smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>>
>> return 0;
>> @@ -464,7 +518,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
>> return ERR_PTR(-ENOMEM);
>>
>> qsmmu->smmu.impl = impl;
>> - qsmmu->cfg = data->cfg;
>> + qsmmu->data = data;
>
> This should go to a separate commit. It is not related to ACTLR support
qsmmu->data has the actlrcfg/actlrcfg_gfx as well hence clubbed this
change here as rightly suggested by Robin[1] on v2 revision.
Initially planned[2] for separate patch, but later clubbing it with
actlr patch looked like a cleaner approach.
Would it be okay to keep it here? Or separate patch would be better?
[1]:https://lore.kernel.org/all/c75d107a-44cb-4df3-b583-13719df1f8be@arm.com/
[2]:https://lore.kernel.org/all/9b406a7c-57b8-4b5f-8fbc-714560cce8cf@quicinc.com/
>
>>
>> return &qsmmu->smmu;
>> }
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
>> index 593910567b88..138fc57f7b0d 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
>> @@ -8,7 +8,7 @@
>>
>> struct qcom_smmu {
>> struct arm_smmu_device smmu;
>> - const struct qcom_smmu_config *cfg;
>> + const struct qcom_smmu_match_data *data;
>> bool bypass_quirk;
>> u8 bypass_cbndx;
>> u32 stall_enabled;
>> @@ -25,6 +25,10 @@ struct qcom_smmu_config {
>> };
>>
>> struct qcom_smmu_match_data {
>> + const struct actlr_config *actlrcfg;
>> + size_t actlrcfg_size;
>> + const struct actlr_config *actlrcfg_gfx;
>> + size_t actlrcfg_gfx_size;
>> const struct qcom_smmu_config *cfg;
>> const struct arm_smmu_impl *impl;
>> const struct arm_smmu_impl *adreno_impl;
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> index d6d1a2a55cc0..8e4faf015286 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> @@ -990,9 +990,10 @@ static int arm_smmu_find_sme(struct arm_smmu_device *smmu, u16 id, u16 mask)
>> * expect simply identical entries for this case, but there's
>> * no harm in accommodating the generalisation.
>> */
>> - if ((mask & smrs[i].mask) == mask &&
>> - !((id ^ smrs[i].id) & ~smrs[i].mask))
>> +
>> + if (smr_is_subset(smrs[i], id, mask))
>> return i;
>> +
>> /*
>> * If the new entry has any other overlap with an existing one,
>> * though, then there always exists at least one stream ID
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>> index 703fd5817ec1..b1638bbc41d4 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>> @@ -501,6 +501,11 @@ static inline void arm_smmu_writeq(struct arm_smmu_device *smmu, int page,
>> writeq_relaxed(val, arm_smmu_page(smmu, page) + offset);
>> }
>>
>> +static inline bool smr_is_subset(struct arm_smmu_smr smrs, u16 id, u16 mask)
>
> A pointer to the struct, please
>
>> +{
>> + return (mask & smrs.mask) == mask && !((id ^ smrs.id) & ~smrs.mask);
>> +}
>> +
>> #define ARM_SMMU_GR0 0
>> #define ARM_SMMU_GR1 1
>> #define ARM_SMMU_CB(s, n) ((s)->numpage + (n))
>> --
>> 2.17.1
>>
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings
2023-11-27 14:54 ` [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings Bibek Kumar Patro
2023-11-27 15:33 ` Konrad Dybcio
2023-11-27 16:07 ` Dmitry Baryshkov
@ 2023-11-28 3:01 ` Bjorn Andersson
2023-11-29 8:44 ` Bibek Kumar Patro
2023-12-01 10:09 ` kernel test robot
3 siblings, 1 reply; 16+ messages in thread
From: Bjorn Andersson @ 2023-11-28 3:01 UTC (permalink / raw)
To: Bibek Kumar Patro
Cc: will, robin.murphy, joro, dmitry.baryshkov, a39.skl,
konrad.dybcio, quic_bjorande, mani, quic_eberman, robdclark,
u.kleine-koenig, robh, vladimir.oltean, quic_pkondeti,
quic_molvera, linux-arm-msm, linux-arm-kernel, iommu,
linux-kernel, qipl.kernel.upstream
On Mon, Nov 27, 2023 at 08:24:09PM +0530, Bibek Kumar Patro wrote:
> Currently in Qualcomm SoCs the default prefetch is set to 1 which allows
> the TLB to fetch just the next page table. MMU-500 features ACTLR
> register which is implementation defined and is used for Qualcomm SoCs
> to have a prefetch setting of 1/3/7/15 enabling TLB to prefetch
In the previous discussion with Dmitry you stated that the "prefetch
setting" doesn't directly map to any known values. This commit message
give a clear indication about the meaning of these values.
So, please fix the commit message to properly document the value space -
to avoid confusion when people are searching for the meaning of the
defines...
Please also clarify why there are 4 possible values here, 4 possible
values of the 2 prefetch settings bits in the register, but only 3
defines in the actual patch.
Regards,
Bjorn
> the next set of page tables accordingly allowing for faster translations.
>
> ACTLR value is unique for each SMR (Stream matching register) and stored
> in a pre-populated table. This value is set to the register during
> context bank initialisation.
>
> Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
>
> ---
> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 56 +++++++++++++++++++++-
> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 6 ++-
> drivers/iommu/arm/arm-smmu/arm-smmu.c | 5 +-
> drivers/iommu/arm/arm-smmu/arm-smmu.h | 5 ++
> 4 files changed, 68 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 7f52ac67495f..4a38cae29be2 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -14,6 +14,12 @@
>
> #define QCOM_DUMMY_VAL -1
>
> +struct actlr_config {
> + u16 sid;
> + u16 mask;
> + u32 actlr;
> +};
> +
> static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
> {
> return container_of(smmu, struct qcom_smmu, smmu);
> @@ -205,10 +211,40 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
> return true;
> }
>
> +static void arm_smmu_set_actlr(struct device *dev, struct arm_smmu_device *smmu, int cbndx,
> + const struct actlr_config *actlrcfg, size_t actlrcfg_size)
> +{
> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> + struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
> + struct arm_smmu_smr *smr;
> + int i;
> + int j;
> + u16 id;
> + u16 mask;
> + int idx;
> +
> + for (i = 0; i < actlrcfg_size; ++i) {
> + id = (actlrcfg + i)->sid;
> + mask = (actlrcfg + i)->mask;
> +
> + for_each_cfg_sme(cfg, fwspec, j, idx) {
> + smr = &smmu->smrs[idx];
> + if (smr_is_subset(*smr, id, mask))
> + arm_smmu_cb_write(smmu, cbndx, ARM_SMMU_CB_ACTLR,
> + (actlrcfg + i)->actlr);
> + }
> + }
> +}
> +
> static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
> {
> struct adreno_smmu_priv *priv;
> + struct arm_smmu_device *smmu = smmu_domain->smmu;
> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> + const struct actlr_config *actlrcfg;
> + size_t actlrcfg_size;
> + int cbndx = smmu_domain->cfg.cbndx;
>
> smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>
> @@ -238,6 +274,12 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> priv->set_stall = qcom_adreno_smmu_set_stall;
> priv->resume_translation = qcom_adreno_smmu_resume_translation;
>
> + if (qsmmu->data->actlrcfg_gfx) {
> + actlrcfg = qsmmu->data->actlrcfg_gfx;
> + actlrcfg_size = qsmmu->data->actlrcfg_gfx_size;
> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
> + }
> +
> return 0;
> }
>
> @@ -263,6 +305,18 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
> static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
> {
> + struct arm_smmu_device *smmu = smmu_domain->smmu;
> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> + const struct actlr_config *actlrcfg;
> + size_t actlrcfg_size;
> + int cbndx = smmu_domain->cfg.cbndx;
> +
> + if (qsmmu->data->actlrcfg) {
> + actlrcfg = qsmmu->data->actlrcfg;
> + actlrcfg_size = qsmmu->data->actlrcfg_size;
> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
> + }
> +
> smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>
> return 0;
> @@ -464,7 +518,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
> return ERR_PTR(-ENOMEM);
>
> qsmmu->smmu.impl = impl;
> - qsmmu->cfg = data->cfg;
> + qsmmu->data = data;
>
> return &qsmmu->smmu;
> }
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
> index 593910567b88..138fc57f7b0d 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
> @@ -8,7 +8,7 @@
>
> struct qcom_smmu {
> struct arm_smmu_device smmu;
> - const struct qcom_smmu_config *cfg;
> + const struct qcom_smmu_match_data *data;
> bool bypass_quirk;
> u8 bypass_cbndx;
> u32 stall_enabled;
> @@ -25,6 +25,10 @@ struct qcom_smmu_config {
> };
>
> struct qcom_smmu_match_data {
> + const struct actlr_config *actlrcfg;
> + size_t actlrcfg_size;
> + const struct actlr_config *actlrcfg_gfx;
> + size_t actlrcfg_gfx_size;
> const struct qcom_smmu_config *cfg;
> const struct arm_smmu_impl *impl;
> const struct arm_smmu_impl *adreno_impl;
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index d6d1a2a55cc0..8e4faf015286 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -990,9 +990,10 @@ static int arm_smmu_find_sme(struct arm_smmu_device *smmu, u16 id, u16 mask)
> * expect simply identical entries for this case, but there's
> * no harm in accommodating the generalisation.
> */
> - if ((mask & smrs[i].mask) == mask &&
> - !((id ^ smrs[i].id) & ~smrs[i].mask))
> +
> + if (smr_is_subset(smrs[i], id, mask))
> return i;
> +
> /*
> * If the new entry has any other overlap with an existing one,
> * though, then there always exists at least one stream ID
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> index 703fd5817ec1..b1638bbc41d4 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> @@ -501,6 +501,11 @@ static inline void arm_smmu_writeq(struct arm_smmu_device *smmu, int page,
> writeq_relaxed(val, arm_smmu_page(smmu, page) + offset);
> }
>
> +static inline bool smr_is_subset(struct arm_smmu_smr smrs, u16 id, u16 mask)
> +{
> + return (mask & smrs.mask) == mask && !((id ^ smrs.id) & ~smrs.mask);
> +}
> +
> #define ARM_SMMU_GR0 0
> #define ARM_SMMU_GR1 1
> #define ARM_SMMU_CB(s, n) ((s)->numpage + (n))
> --
> 2.17.1
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings
2023-11-28 3:01 ` Bjorn Andersson
@ 2023-11-29 8:44 ` Bibek Kumar Patro
0 siblings, 0 replies; 16+ messages in thread
From: Bibek Kumar Patro @ 2023-11-29 8:44 UTC (permalink / raw)
To: Bjorn Andersson
Cc: will, robin.murphy, joro, dmitry.baryshkov, a39.skl,
konrad.dybcio, quic_bjorande, mani, quic_eberman, robdclark,
u.kleine-koenig, robh, vladimir.oltean, quic_pkondeti,
quic_molvera, linux-arm-msm, linux-arm-kernel, iommu,
linux-kernel, qipl.kernel.upstream
On 11/28/2023 8:31 AM, Bjorn Andersson wrote:
> On Mon, Nov 27, 2023 at 08:24:09PM +0530, Bibek Kumar Patro wrote:
>> Currently in Qualcomm SoCs the default prefetch is set to 1 which allows
>> the TLB to fetch just the next page table. MMU-500 features ACTLR
>> register which is implementation defined and is used for Qualcomm SoCs
>> to have a prefetch setting of 1/3/7/15 enabling TLB to prefetch
>
> In the previous discussion with Dmitry you stated that the "prefetch
> setting" doesn't directly map to any known values. This commit message
> give a clear indication about the meaning of these values.
>
> So, please fix the commit message to properly document the value space -
> to avoid confusion when people are searching for the meaning of the
> defines...
>
Noted, agree on the same. Thanks for pointing this out.
Will fix the description accordingly, avoid mentioning
meaning of these values.
>
> Please also clarify why there are 4 possible values here, 4 possible
> values of the 2 prefetch settings bits in the register, but only 3
> defines in the actual patch.
>
One of the values haven't been yet used in the targets whose list are
posted in this series, hence corresponding define is not mentioned in
the actual patch yet.
Thanks & Regards,
Bibek
> Regards,
> Bjorn
>
>> the next set of page tables accordingly allowing for faster translations.
>>
>> ACTLR value is unique for each SMR (Stream matching register) and stored
>> in a pre-populated table. This value is set to the register during
>> context bank initialisation.
>>
>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
>>
>> ---
>> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 56 +++++++++++++++++++++-
>> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h | 6 ++-
>> drivers/iommu/arm/arm-smmu/arm-smmu.c | 5 +-
>> drivers/iommu/arm/arm-smmu/arm-smmu.h | 5 ++
>> 4 files changed, 68 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> index 7f52ac67495f..4a38cae29be2 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> @@ -14,6 +14,12 @@
>>
>> #define QCOM_DUMMY_VAL -1
>>
>> +struct actlr_config {
>> + u16 sid;
>> + u16 mask;
>> + u32 actlr;
>> +};
>> +
>> static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
>> {
>> return container_of(smmu, struct qcom_smmu, smmu);
>> @@ -205,10 +211,40 @@ static bool qcom_adreno_can_do_ttbr1(struct arm_smmu_device *smmu)
>> return true;
>> }
>>
>> +static void arm_smmu_set_actlr(struct device *dev, struct arm_smmu_device *smmu, int cbndx,
>> + const struct actlr_config *actlrcfg, size_t actlrcfg_size)
>> +{
>> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
>> + struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
>> + struct arm_smmu_smr *smr;
>> + int i;
>> + int j;
>> + u16 id;
>> + u16 mask;
>> + int idx;
>> +
>> + for (i = 0; i < actlrcfg_size; ++i) {
>> + id = (actlrcfg + i)->sid;
>> + mask = (actlrcfg + i)->mask;
>> +
>> + for_each_cfg_sme(cfg, fwspec, j, idx) {
>> + smr = &smmu->smrs[idx];
>> + if (smr_is_subset(*smr, id, mask))
>> + arm_smmu_cb_write(smmu, cbndx, ARM_SMMU_CB_ACTLR,
>> + (actlrcfg + i)->actlr);
>> + }
>> + }
>> +}
>> +
>> static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>> {
>> struct adreno_smmu_priv *priv;
>> + struct arm_smmu_device *smmu = smmu_domain->smmu;
>> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
>> + const struct actlr_config *actlrcfg;
>> + size_t actlrcfg_size;
>> + int cbndx = smmu_domain->cfg.cbndx;
>>
>> smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>>
>> @@ -238,6 +274,12 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>> priv->set_stall = qcom_adreno_smmu_set_stall;
>> priv->resume_translation = qcom_adreno_smmu_resume_translation;
>>
>> + if (qsmmu->data->actlrcfg_gfx) {
>> + actlrcfg = qsmmu->data->actlrcfg_gfx;
>> + actlrcfg_size = qsmmu->data->actlrcfg_gfx_size;
>> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
>> + }
>> +
>> return 0;
>> }
>>
>> @@ -263,6 +305,18 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
>> static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>> struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>> {
>> + struct arm_smmu_device *smmu = smmu_domain->smmu;
>> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
>> + const struct actlr_config *actlrcfg;
>> + size_t actlrcfg_size;
>> + int cbndx = smmu_domain->cfg.cbndx;
>> +
>> + if (qsmmu->data->actlrcfg) {
>> + actlrcfg = qsmmu->data->actlrcfg;
>> + actlrcfg_size = qsmmu->data->actlrcfg_size;
>> + arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
>> + }
>> +
>> smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
>>
>> return 0;
>> @@ -464,7 +518,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
>> return ERR_PTR(-ENOMEM);
>>
>> qsmmu->smmu.impl = impl;
>> - qsmmu->cfg = data->cfg;
>> + qsmmu->data = data;
>>
>> return &qsmmu->smmu;
>> }
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
>> index 593910567b88..138fc57f7b0d 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
>> @@ -8,7 +8,7 @@
>>
>> struct qcom_smmu {
>> struct arm_smmu_device smmu;
>> - const struct qcom_smmu_config *cfg;
>> + const struct qcom_smmu_match_data *data;
>> bool bypass_quirk;
>> u8 bypass_cbndx;
>> u32 stall_enabled;
>> @@ -25,6 +25,10 @@ struct qcom_smmu_config {
>> };
>>
>> struct qcom_smmu_match_data {
>> + const struct actlr_config *actlrcfg;
>> + size_t actlrcfg_size;
>> + const struct actlr_config *actlrcfg_gfx;
>> + size_t actlrcfg_gfx_size;
>> const struct qcom_smmu_config *cfg;
>> const struct arm_smmu_impl *impl;
>> const struct arm_smmu_impl *adreno_impl;
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> index d6d1a2a55cc0..8e4faf015286 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> @@ -990,9 +990,10 @@ static int arm_smmu_find_sme(struct arm_smmu_device *smmu, u16 id, u16 mask)
>> * expect simply identical entries for this case, but there's
>> * no harm in accommodating the generalisation.
>> */
>> - if ((mask & smrs[i].mask) == mask &&
>> - !((id ^ smrs[i].id) & ~smrs[i].mask))
>> +
>> + if (smr_is_subset(smrs[i], id, mask))
>> return i;
>> +
>> /*
>> * If the new entry has any other overlap with an existing one,
>> * though, then there always exists at least one stream ID
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>> index 703fd5817ec1..b1638bbc41d4 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
>> @@ -501,6 +501,11 @@ static inline void arm_smmu_writeq(struct arm_smmu_device *smmu, int page,
>> writeq_relaxed(val, arm_smmu_page(smmu, page) + offset);
>> }
>>
>> +static inline bool smr_is_subset(struct arm_smmu_smr smrs, u16 id, u16 mask)
>> +{
>> + return (mask & smrs.mask) == mask && !((id ^ smrs.id) & ~smrs.mask);
>> +}
>> +
>> #define ARM_SMMU_GR0 0
>> #define ARM_SMMU_GR1 1
>> #define ARM_SMMU_CB(s, n) ((s)->numpage + (n))
>> --
>> 2.17.1
>>
>>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings
2023-11-27 14:54 ` [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings Bibek Kumar Patro
` (2 preceding siblings ...)
2023-11-28 3:01 ` Bjorn Andersson
@ 2023-12-01 10:09 ` kernel test robot
3 siblings, 0 replies; 16+ messages in thread
From: kernel test robot @ 2023-12-01 10:09 UTC (permalink / raw)
To: Bibek Kumar Patro, will, robin.murphy, joro, dmitry.baryshkov,
a39.skl, konrad.dybcio, quic_bjorande, mani, quic_eberman,
robdclark, u.kleine-koenig, robh, vladimir.oltean, quic_pkondeti,
quic_molvera
Cc: llvm, oe-kbuild-all, linux-arm-msm, linux-arm-kernel, iommu,
linux-kernel, qipl.kernel.upstream, Bibek Kumar Patro
Hi Bibek,
kernel test robot noticed the following build errors:
[auto build test ERROR on v6.7-rc3]
[also build test ERROR on linus/master next-20231201]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Bibek-Kumar-Patro/iommu-arm-smmu-add-ACTLR-data-and-support-for-SM8550/20231127-235746
base: v6.7-rc3
patch link: https://lore.kernel.org/r/20231127145412.3981-2-quic_bibekkum%40quicinc.com
patch subject: [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings
config: arm64-allyesconfig (https://download.01.org/0day-ci/archive/20231201/202312011750.Pwca3TWE-lkp@intel.com/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231201/202312011750.Pwca3TWE-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202312011750.Pwca3TWE-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c:25:16: error: no member named 'cfg' in 'struct qcom_smmu'
25 | cfg = qsmmu->cfg;
| ~~~~~ ^
1 error generated.
vim +25 drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 12
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 13 void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu)
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 14 {
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 15 int ret;
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 16 u32 tbu_pwr_status, sync_inv_ack, sync_inv_progress;
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 17 struct qcom_smmu *qsmmu = container_of(smmu, struct qcom_smmu, smmu);
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 18 const struct qcom_smmu_config *cfg;
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 19 static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 20 DEFAULT_RATELIMIT_BURST);
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 21
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 22 if (__ratelimit(&rs)) {
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 23 dev_err(smmu->dev, "TLB sync timed out -- SMMU may be deadlocked\n");
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 24
b9b721d117e9d3 Sai Prakash Ranjan 2022-07-08 @25 cfg = qsmmu->cfg;
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 2/4] iommu/arm-smmu: add ACTLR data and support for SM8550
2023-11-27 14:54 [PATCH v3 0/4] iommu/arm-smmu: introduction of ACTLR implementation for Qualcomm SoCs Bibek Kumar Patro
2023-11-27 14:54 ` [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings Bibek Kumar Patro
@ 2023-11-27 14:54 ` Bibek Kumar Patro
2023-11-27 15:34 ` Konrad Dybcio
2023-11-27 14:54 ` [PATCH v3 3/4] iommu/arm-smmu: add ACTLR data and support for SC7280 Bibek Kumar Patro
2023-11-27 14:54 ` [PATCH v3 4/4] iommu/arm-smmu: re-enable context caching in smmu reset operation Bibek Kumar Patro
3 siblings, 1 reply; 16+ messages in thread
From: Bibek Kumar Patro @ 2023-11-27 14:54 UTC (permalink / raw)
To: will, robin.murphy, joro, dmitry.baryshkov, a39.skl,
konrad.dybcio, quic_bjorande, mani, quic_eberman, robdclark,
u.kleine-koenig, robh, vladimir.oltean, quic_pkondeti,
quic_molvera
Cc: linux-arm-msm, linux-arm-kernel, iommu, linux-kernel,
qipl.kernel.upstream, Bibek Kumar Patro
Add ACTLR data table for SM8550 along with support for
same including SM8550 specific implementation operations.
Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
---
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 81 ++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 4a38cae29be2..247eaa194129 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -20,6 +20,75 @@ struct actlr_config {
u32 actlr;
};
+#define PREFETCH_DISABLE 0
+#define PREFETCH_SHALLOW BIT(8)
+#define PREFETCH_DEEP (BIT(9) | BIT(8))
+#define PREFETCH_DEEP_GFX (BIT(9) | BIT(8) | BIT(5) | BIT(3))
+#define CPRE BIT(1) /* Enable context caching in the prefetch buffer */
+#define CMTLB BIT(0) /* Enable context caching in the macro TLB */
+
+static const struct actlr_config sm8550_apps_actlr_cfg[] = {
+ { 0x18a0, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+ { 0x18e0, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+ { 0x0800, 0x0020, PREFETCH_DISABLE | CMTLB },
+ { 0x1800, 0x00c0, PREFETCH_DISABLE | CMTLB },
+ { 0x1820, 0x0000, PREFETCH_DISABLE | CMTLB },
+ { 0x1860, 0x0000, PREFETCH_DISABLE | CMTLB },
+ { 0x0c01, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x0c02, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x0c03, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x0c04, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x0c05, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x0c06, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x0c07, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x0c08, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x0c09, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x0c0c, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x0c0d, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x0c0e, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x0c0f, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x1961, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x1962, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x1963, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x1964, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x1965, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x1966, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x1967, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x1968, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x1969, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x196c, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x196d, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x196e, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x196f, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19c1, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19c2, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19c3, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19c4, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19c5, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19c6, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19c7, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19c8, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19c9, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19cc, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19cd, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19ce, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x19cf, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+ { 0x1c00, 0x0002, PREFETCH_SHALLOW | CPRE | CMTLB },
+ { 0x1c01, 0x0000, PREFETCH_DISABLE | CMTLB },
+ { 0x1920, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+ { 0x1923, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+ { 0x1924, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+ { 0x1940, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+ { 0x1941, 0x0004, PREFETCH_SHALLOW | CPRE | CMTLB },
+ { 0x1943, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+ { 0x1944, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+ { 0x1947, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+};
+
+static const struct actlr_config sm8550_gfx_actlr_cfg[] = {
+ { 0x0000, 0x03ff, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+};
+
static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
{
return container_of(smmu, struct qcom_smmu, smmu);
@@ -557,6 +626,17 @@ static const struct qcom_smmu_match_data sdm845_smmu_500_data = {
/* Also no debug configuration. */
};
+
+static const struct qcom_smmu_match_data sm8550_smmu_500_impl0_data = {
+ .impl = &qcom_smmu_500_impl,
+ .adreno_impl = &qcom_adreno_smmu_500_impl,
+ .cfg = &qcom_smmu_impl0_cfg,
+ .actlrcfg = sm8550_apps_actlr_cfg,
+ .actlrcfg_size = ARRAY_SIZE(sm8550_apps_actlr_cfg),
+ .actlrcfg_gfx = sm8550_gfx_actlr_cfg,
+ .actlrcfg_gfx_size = ARRAY_SIZE(sm8550_gfx_actlr_cfg),
+};
+
static const struct qcom_smmu_match_data qcom_smmu_500_impl0_data = {
.impl = &qcom_smmu_500_impl,
.adreno_impl = &qcom_adreno_smmu_500_impl,
@@ -590,6 +670,7 @@ static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = {
{ .compatible = "qcom,sm8250-smmu-500", .data = &qcom_smmu_500_impl0_data },
{ .compatible = "qcom,sm8350-smmu-500", .data = &qcom_smmu_500_impl0_data },
{ .compatible = "qcom,sm8450-smmu-500", .data = &qcom_smmu_500_impl0_data },
+ { .compatible = "qcom,sm8550-smmu-500", .data = &sm8550_smmu_500_impl0_data },
{ .compatible = "qcom,smmu-500", .data = &qcom_smmu_500_impl0_data },
{ }
};
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v3 2/4] iommu/arm-smmu: add ACTLR data and support for SM8550
2023-11-27 14:54 ` [PATCH v3 2/4] iommu/arm-smmu: add ACTLR data and support for SM8550 Bibek Kumar Patro
@ 2023-11-27 15:34 ` Konrad Dybcio
0 siblings, 0 replies; 16+ messages in thread
From: Konrad Dybcio @ 2023-11-27 15:34 UTC (permalink / raw)
To: Bibek Kumar Patro, will, robin.murphy, joro, dmitry.baryshkov,
a39.skl, quic_bjorande, mani, quic_eberman, robdclark,
u.kleine-koenig, robh, vladimir.oltean, quic_pkondeti,
quic_molvera
Cc: linux-arm-msm, linux-arm-kernel, iommu, linux-kernel,
qipl.kernel.upstream
On 27.11.2023 15:54, Bibek Kumar Patro wrote:
> Add ACTLR data table for SM8550 along with support for
> same including SM8550 specific implementation operations.
>
> Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
> ---
Acked-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Konrad
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 3/4] iommu/arm-smmu: add ACTLR data and support for SC7280
2023-11-27 14:54 [PATCH v3 0/4] iommu/arm-smmu: introduction of ACTLR implementation for Qualcomm SoCs Bibek Kumar Patro
2023-11-27 14:54 ` [PATCH v3 1/4] iommu/arm-smmu: introduction of ACTLR for custom prefetcher settings Bibek Kumar Patro
2023-11-27 14:54 ` [PATCH v3 2/4] iommu/arm-smmu: add ACTLR data and support for SM8550 Bibek Kumar Patro
@ 2023-11-27 14:54 ` Bibek Kumar Patro
2023-11-27 15:35 ` Konrad Dybcio
2023-11-27 14:54 ` [PATCH v3 4/4] iommu/arm-smmu: re-enable context caching in smmu reset operation Bibek Kumar Patro
3 siblings, 1 reply; 16+ messages in thread
From: Bibek Kumar Patro @ 2023-11-27 14:54 UTC (permalink / raw)
To: will, robin.murphy, joro, dmitry.baryshkov, a39.skl,
konrad.dybcio, quic_bjorande, mani, quic_eberman, robdclark,
u.kleine-koenig, robh, vladimir.oltean, quic_pkondeti,
quic_molvera
Cc: linux-arm-msm, linux-arm-kernel, iommu, linux-kernel,
qipl.kernel.upstream, Bibek Kumar Patro
Add ACTLR data table for SC7280 along with support for
same including SC7280 specific implementation operations.
Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
---
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 25 +++++++++++++++++++++-
1 file changed, 24 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 247eaa194129..f0ad09f9a974 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -27,6 +27,20 @@ struct actlr_config {
#define CPRE BIT(1) /* Enable context caching in the prefetch buffer */
#define CMTLB BIT(0) /* Enable context caching in the macro TLB */
+static const struct actlr_config sc7280_apps_actlr_cfg[] = {
+ { 0x0800, 0x24E1, PREFETCH_DISABLE | CMTLB },
+ { 0x2000, 0x0163, PREFETCH_DISABLE | CMTLB },
+ { 0x2080, 0x0461, PREFETCH_DISABLE | CMTLB },
+ { 0x2100, 0x0161, PREFETCH_DISABLE | CMTLB },
+ { 0x0900, 0x0407, PREFETCH_SHALLOW | CPRE | CMTLB },
+ { 0x2180, 0x0027, PREFETCH_SHALLOW | CPRE | CMTLB },
+ { 0x1000, 0x07ff, PREFETCH_DEEP | CPRE | CMTLB },
+};
+
+static const struct actlr_config sc7280_gfx_actlr_cfg[] = {
+ { 0x0000, 0x07ff, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+};
+
static const struct actlr_config sm8550_apps_actlr_cfg[] = {
{ 0x18a0, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
{ 0x18e0, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
@@ -626,6 +640,15 @@ static const struct qcom_smmu_match_data sdm845_smmu_500_data = {
/* Also no debug configuration. */
};
+static const struct qcom_smmu_match_data sc7280_smmu_500_impl0_data = {
+ .impl = &qcom_smmu_500_impl,
+ .adreno_impl = &qcom_adreno_smmu_500_impl,
+ .cfg = &qcom_smmu_impl0_cfg,
+ .actlrcfg = sc7280_apps_actlr_cfg,
+ .actlrcfg_size = ARRAY_SIZE(sc7280_apps_actlr_cfg),
+ .actlrcfg_gfx = sc7280_gfx_actlr_cfg,
+ .actlrcfg_gfx_size = ARRAY_SIZE(sc7280_gfx_actlr_cfg),
+};
static const struct qcom_smmu_match_data sm8550_smmu_500_impl0_data = {
.impl = &qcom_smmu_500_impl,
@@ -654,7 +677,7 @@ static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = {
{ .compatible = "qcom,qdu1000-smmu-500", .data = &qcom_smmu_500_impl0_data },
{ .compatible = "qcom,sc7180-smmu-500", .data = &qcom_smmu_500_impl0_data },
{ .compatible = "qcom,sc7180-smmu-v2", .data = &qcom_smmu_v2_data },
- { .compatible = "qcom,sc7280-smmu-500", .data = &qcom_smmu_500_impl0_data },
+ { .compatible = "qcom,sc7280-smmu-500", .data = &sc7280_smmu_500_impl0_data },
{ .compatible = "qcom,sc8180x-smmu-500", .data = &qcom_smmu_500_impl0_data },
{ .compatible = "qcom,sc8280xp-smmu-500", .data = &qcom_smmu_500_impl0_data },
{ .compatible = "qcom,sdm630-smmu-v2", .data = &qcom_smmu_v2_data },
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v3 3/4] iommu/arm-smmu: add ACTLR data and support for SC7280
2023-11-27 14:54 ` [PATCH v3 3/4] iommu/arm-smmu: add ACTLR data and support for SC7280 Bibek Kumar Patro
@ 2023-11-27 15:35 ` Konrad Dybcio
2023-11-29 6:14 ` Bibek Kumar Patro
0 siblings, 1 reply; 16+ messages in thread
From: Konrad Dybcio @ 2023-11-27 15:35 UTC (permalink / raw)
To: Bibek Kumar Patro, will, robin.murphy, joro, dmitry.baryshkov,
a39.skl, quic_bjorande, mani, quic_eberman, robdclark,
u.kleine-koenig, robh, vladimir.oltean, quic_pkondeti,
quic_molvera
Cc: linux-arm-msm, linux-arm-kernel, iommu, linux-kernel,
qipl.kernel.upstream
On 27.11.2023 15:54, Bibek Kumar Patro wrote:
> Add ACTLR data table for SC7280 along with support for
> same including SC7280 specific implementation operations.
>
> Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
> ---
> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 25 +++++++++++++++++++++-
> 1 file changed, 24 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 247eaa194129..f0ad09f9a974 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -27,6 +27,20 @@ struct actlr_config {
> #define CPRE BIT(1) /* Enable context caching in the prefetch buffer */
> #define CMTLB BIT(0) /* Enable context caching in the macro TLB */
>
> +static const struct actlr_config sc7280_apps_actlr_cfg[] = {
> + { 0x0800, 0x24E1, PREFETCH_DISABLE | CMTLB },
hex should be lowercase
> + { 0x2000, 0x0163, PREFETCH_DISABLE | CMTLB },
> + { 0x2080, 0x0461, PREFETCH_DISABLE | CMTLB },
> + { 0x2100, 0x0161, PREFETCH_DISABLE | CMTLB },
> + { 0x0900, 0x0407, PREFETCH_SHALLOW | CPRE | CMTLB },
> + { 0x2180, 0x0027, PREFETCH_SHALLOW | CPRE | CMTLB },
> + { 0x1000, 0x07ff, PREFETCH_DEEP | CPRE | CMTLB },
> +};
Any reason this list is so much smaller than 8550's? Is it complete?
Konrad
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 3/4] iommu/arm-smmu: add ACTLR data and support for SC7280
2023-11-27 15:35 ` Konrad Dybcio
@ 2023-11-29 6:14 ` Bibek Kumar Patro
0 siblings, 0 replies; 16+ messages in thread
From: Bibek Kumar Patro @ 2023-11-29 6:14 UTC (permalink / raw)
To: Konrad Dybcio, will, robin.murphy, joro, dmitry.baryshkov,
a39.skl, quic_bjorande, mani, quic_eberman, robdclark,
u.kleine-koenig, robh, vladimir.oltean, quic_pkondeti,
quic_molvera
Cc: linux-arm-msm, linux-arm-kernel, iommu, linux-kernel,
qipl.kernel.upstream
On 11/27/2023 9:05 PM, Konrad Dybcio wrote:
> On 27.11.2023 15:54, Bibek Kumar Patro wrote:
>> Add ACTLR data table for SC7280 along with support for
>> same including SC7280 specific implementation operations.
>>
>> Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
>> ---
>> drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 25 +++++++++++++++++++++-
>> 1 file changed, 24 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 247eaa194129..f0ad09f9a974 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
>> @@ -27,6 +27,20 @@ struct actlr_config {
>> #define CPRE BIT(1) /* Enable context caching in the prefetch buffer */
>> #define CMTLB BIT(0) /* Enable context caching in the macro TLB */
>>
>> +static const struct actlr_config sc7280_apps_actlr_cfg[] = {
>> + { 0x0800, 0x24E1, PREFETCH_DISABLE | CMTLB },
> hex should be lowercase
Noted,thanks for pointing this out will take care of this in next
version.
>
>> + { 0x2000, 0x0163, PREFETCH_DISABLE | CMTLB },
>> + { 0x2080, 0x0461, PREFETCH_DISABLE | CMTLB },
>> + { 0x2100, 0x0161, PREFETCH_DISABLE | CMTLB },
>> + { 0x0900, 0x0407, PREFETCH_SHALLOW | CPRE | CMTLB },
>> + { 0x2180, 0x0027, PREFETCH_SHALLOW | CPRE | CMTLB },
>> + { 0x1000, 0x07ff, PREFETCH_DEEP | CPRE | CMTLB },
>> +};
> Any reason this list is so much smaller than 8550's? Is it complete?
Yes it's complete only. This list varies targetwise actually so we just
fill it referring the hardware settings reference document. So size of
the list might vary as per target.
>
> Konrad
Thanks & regards,
Bibek
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 4/4] iommu/arm-smmu: re-enable context caching in smmu reset operation
2023-11-27 14:54 [PATCH v3 0/4] iommu/arm-smmu: introduction of ACTLR implementation for Qualcomm SoCs Bibek Kumar Patro
` (2 preceding siblings ...)
2023-11-27 14:54 ` [PATCH v3 3/4] iommu/arm-smmu: add ACTLR data and support for SC7280 Bibek Kumar Patro
@ 2023-11-27 14:54 ` Bibek Kumar Patro
3 siblings, 0 replies; 16+ messages in thread
From: Bibek Kumar Patro @ 2023-11-27 14:54 UTC (permalink / raw)
To: will, robin.murphy, joro, dmitry.baryshkov, a39.skl,
konrad.dybcio, quic_bjorande, mani, quic_eberman, robdclark,
u.kleine-koenig, robh, vladimir.oltean, quic_pkondeti,
quic_molvera
Cc: linux-arm-msm, linux-arm-kernel, iommu, linux-kernel,
qipl.kernel.upstream, Bibek Kumar Patro
Default MMU-500 reset operation disables context caching in
prefetch buffer. It is however expected for context banks using
the ACTLR register to retain their prefetch value during reset
and runtime suspend.
Replace default MMU-500 reset operation with Qualcomm specific reset
operation which envelope the default reset operation and re-enables
context caching in prefetch buffer for Qualcomm SoCs.
Signed-off-by: Bibek Kumar Patro <quic_bibekkum@quicinc.com>
---
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 23 +++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index f0ad09f9a974..2c676a09fa31 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -512,11 +512,28 @@ static int qcom_smmu_def_domain_type(struct device *dev)
return match ? IOMMU_DOMAIN_IDENTITY : 0;
}
+static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
+{
+ int i;
+ u32 reg;
+
+ arm_mmu500_reset(smmu);
+
+ /* Re-enable context caching after reset */
+ for (i = 0; i < smmu->num_context_banks; ++i) {
+ reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR);
+ reg |= CPRE;
+ arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_ACTLR, reg);
+ }
+
+ return 0;
+}
+
static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
{
int ret;
- arm_mmu500_reset(smmu);
+ qcom_smmu500_reset(smmu);
/*
* To address performance degradation in non-real time clients,
@@ -543,7 +560,7 @@ static const struct arm_smmu_impl qcom_smmu_500_impl = {
.init_context = qcom_smmu_init_context,
.cfg_probe = qcom_smmu_cfg_probe,
.def_domain_type = qcom_smmu_def_domain_type,
- .reset = arm_mmu500_reset,
+ .reset = qcom_smmu500_reset,
.write_s2cr = qcom_smmu_write_s2cr,
.tlb_sync = qcom_smmu_tlb_sync,
};
@@ -568,7 +585,7 @@ static const struct arm_smmu_impl qcom_adreno_smmu_v2_impl = {
static const struct arm_smmu_impl qcom_adreno_smmu_500_impl = {
.init_context = qcom_adreno_smmu_init_context,
.def_domain_type = qcom_smmu_def_domain_type,
- .reset = arm_mmu500_reset,
+ .reset = qcom_smmu500_reset,
.alloc_context_bank = qcom_adreno_smmu_alloc_context_bank,
.write_sctlr = qcom_adreno_smmu_write_sctlr,
.tlb_sync = qcom_smmu_tlb_sync,
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread