@@ -147,16 +147,57 @@ static const struct arm_smmu_impl arm_mmu500_impl = {
147147 .reset = arm_mmu500_reset ,
148148};
149149
150+ static u64 mrvl_mmu500_readq (struct arm_smmu_device * smmu , int page , int off )
151+ {
152+ /*
153+ * Marvell Armada-AP806 erratum #582743.
154+ * Split all the readq to double readl
155+ */
156+ return hi_lo_readq_relaxed (arm_smmu_page (smmu , page ) + off );
157+ }
158+
159+ static void mrvl_mmu500_writeq (struct arm_smmu_device * smmu , int page , int off ,
160+ u64 val )
161+ {
162+ /*
163+ * Marvell Armada-AP806 erratum #582743.
164+ * Split all the writeq to double writel
165+ */
166+ hi_lo_writeq_relaxed (val , arm_smmu_page (smmu , page ) + off );
167+ }
168+
169+ static int mrvl_mmu500_cfg_probe (struct arm_smmu_device * smmu )
170+ {
171+
172+ /*
173+ * Armada-AP806 erratum #582743.
174+ * Hide the SMMU_IDR2.PTFSv8 fields to sidestep the AArch64
175+ * formats altogether and allow using 32 bits access on the
176+ * interconnect.
177+ */
178+ smmu -> features &= ~(ARM_SMMU_FEAT_FMT_AARCH64_4K |
179+ ARM_SMMU_FEAT_FMT_AARCH64_16K |
180+ ARM_SMMU_FEAT_FMT_AARCH64_64K );
181+
182+ return 0 ;
183+ }
184+
185+ static const struct arm_smmu_impl mrvl_mmu500_impl = {
186+ .read_reg64 = mrvl_mmu500_readq ,
187+ .write_reg64 = mrvl_mmu500_writeq ,
188+ .cfg_probe = mrvl_mmu500_cfg_probe ,
189+ .reset = arm_mmu500_reset ,
190+ };
191+
150192
151193struct arm_smmu_device * arm_smmu_impl_init (struct arm_smmu_device * smmu )
152194{
153195 const struct device_node * np = smmu -> dev -> of_node ;
154196
155197 /*
156- * We will inevitably have to combine model-specific implementation
157- * quirks with platform-specific integration quirks, but everything
158- * we currently support happens to work out as straightforward
159- * mutually-exclusive assignments.
198+ * Set the impl for model-specific implementation quirks first,
199+ * such that platform integration quirks can pick it up and
200+ * inherit from it if necessary.
160201 */
161202 switch (smmu -> model ) {
162203 case ARM_MMU500 :
@@ -168,12 +209,21 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
168209 break ;
169210 }
170211
212+ /* This is implicitly MMU-400 */
171213 if (of_property_read_bool (np , "calxeda,smmu-secure-config-access" ))
172214 smmu -> impl = & calxeda_impl ;
173215
216+ if (of_device_is_compatible (np , "nvidia,tegra194-smmu" ))
217+ return nvidia_smmu_impl_init (smmu );
218+
174219 if (of_device_is_compatible (np , "qcom,sdm845-smmu-500" ) ||
175- of_device_is_compatible (np , "qcom,sc7180-smmu-500" ))
220+ of_device_is_compatible (np , "qcom,sc7180-smmu-500" ) ||
221+ of_device_is_compatible (np , "qcom,sm8150-smmu-500" ) ||
222+ of_device_is_compatible (np , "qcom,sm8250-smmu-500" ))
176223 return qcom_smmu_impl_init (smmu );
177224
225+ if (of_device_is_compatible (np , "marvell,ap806-smmu-500" ))
226+ smmu -> impl = & mrvl_mmu500_impl ;
227+
178228 return smmu ;
179229}
0 commit comments