@@ -361,6 +361,8 @@ static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
361361{
362362 int ret ;
363363
364+ arm_mmu500_reset (smmu );
365+
364366 /*
365367 * To address performance degradation in non-real time clients,
366368 * such as USB and UFS, turn off wait-for-safe on sdm845 based boards,
@@ -374,41 +376,67 @@ static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
374376 return ret ;
375377}
376378
377- static int qcom_smmu500_reset (struct arm_smmu_device * smmu )
378- {
379- const struct device_node * np = smmu -> dev -> of_node ;
380-
381- arm_mmu500_reset (smmu );
382-
383- if (of_device_is_compatible (np , "qcom,sdm845-smmu-500" ))
384- return qcom_sdm845_smmu500_reset (smmu );
379+ static const struct arm_smmu_impl qcom_smmu_v2_impl = {
380+ .init_context = qcom_smmu_init_context ,
381+ .cfg_probe = qcom_smmu_cfg_probe ,
382+ .def_domain_type = qcom_smmu_def_domain_type ,
383+ .write_s2cr = qcom_smmu_write_s2cr ,
384+ .tlb_sync = qcom_smmu_tlb_sync ,
385+ };
385386
386- return 0 ;
387- }
387+ static const struct arm_smmu_impl qcom_smmu_500_impl = {
388+ .init_context = qcom_smmu_init_context ,
389+ .cfg_probe = qcom_smmu_cfg_probe ,
390+ .def_domain_type = qcom_smmu_def_domain_type ,
391+ .reset = arm_mmu500_reset ,
392+ .write_s2cr = qcom_smmu_write_s2cr ,
393+ .tlb_sync = qcom_smmu_tlb_sync ,
394+ };
388395
389- static const struct arm_smmu_impl qcom_smmu_impl = {
396+ static const struct arm_smmu_impl sdm845_smmu_500_impl = {
390397 .init_context = qcom_smmu_init_context ,
391398 .cfg_probe = qcom_smmu_cfg_probe ,
392399 .def_domain_type = qcom_smmu_def_domain_type ,
393- .reset = qcom_smmu500_reset ,
400+ .reset = qcom_sdm845_smmu500_reset ,
394401 .write_s2cr = qcom_smmu_write_s2cr ,
395402 .tlb_sync = qcom_smmu_tlb_sync ,
396403};
397404
398- static const struct arm_smmu_impl qcom_adreno_smmu_impl = {
405+ static const struct arm_smmu_impl qcom_adreno_smmu_v2_impl = {
406+ .init_context = qcom_adreno_smmu_init_context ,
407+ .def_domain_type = qcom_smmu_def_domain_type ,
408+ .alloc_context_bank = qcom_adreno_smmu_alloc_context_bank ,
409+ .write_sctlr = qcom_adreno_smmu_write_sctlr ,
410+ .tlb_sync = qcom_smmu_tlb_sync ,
411+ };
412+
413+ static const struct arm_smmu_impl qcom_adreno_smmu_500_impl = {
399414 .init_context = qcom_adreno_smmu_init_context ,
400415 .def_domain_type = qcom_smmu_def_domain_type ,
401- .reset = qcom_smmu500_reset ,
416+ .reset = arm_mmu500_reset ,
402417 .alloc_context_bank = qcom_adreno_smmu_alloc_context_bank ,
403418 .write_sctlr = qcom_adreno_smmu_write_sctlr ,
404419 .tlb_sync = qcom_smmu_tlb_sync ,
405420};
406421
407422static struct arm_smmu_device * qcom_smmu_create (struct arm_smmu_device * smmu ,
408- const struct arm_smmu_impl * impl )
423+ const struct qcom_smmu_match_data * data )
409424{
425+ const struct device_node * np = smmu -> dev -> of_node ;
426+ const struct arm_smmu_impl * impl ;
410427 struct qcom_smmu * qsmmu ;
411428
429+ if (!data )
430+ return ERR_PTR (- EINVAL );
431+
432+ if (np && of_device_is_compatible (np , "qcom,adreno-smmu" ))
433+ impl = data -> adreno_impl ;
434+ else
435+ impl = data -> impl ;
436+
437+ if (!impl )
438+ return smmu ;
439+
412440 /* Check to make sure qcom_scm has finished probing */
413441 if (!qcom_scm_is_available ())
414442 return ERR_PTR (- EPROBE_DEFER );
@@ -418,27 +446,77 @@ static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
418446 return ERR_PTR (- ENOMEM );
419447
420448 qsmmu -> smmu .impl = impl ;
421- qsmmu -> cfg = qcom_smmu_impl_data ( smmu ) ;
449+ qsmmu -> cfg = data -> cfg ;
422450
423451 return & qsmmu -> smmu ;
424452}
425453
454+ /* Implementation Defined Register Space 0 register offsets */
455+ static const u32 qcom_smmu_impl0_reg_offset [] = {
456+ [QCOM_SMMU_TBU_PWR_STATUS ] = 0x2204 ,
457+ [QCOM_SMMU_STATS_SYNC_INV_TBU_ACK ] = 0x25dc ,
458+ [QCOM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR ] = 0x2670 ,
459+ };
460+
461+ static const struct qcom_smmu_config qcom_smmu_impl0_cfg = {
462+ .reg_offset = qcom_smmu_impl0_reg_offset ,
463+ };
464+
465+ /*
466+ * It is not yet possible to use MDP SMMU with the bypass quirk on the msm8996,
467+ * there are not enough context banks.
468+ */
469+ static const struct qcom_smmu_match_data msm8996_smmu_data = {
470+ .impl = NULL ,
471+ .adreno_impl = & qcom_adreno_smmu_v2_impl ,
472+ };
473+
474+ static const struct qcom_smmu_match_data qcom_smmu_v2_data = {
475+ .impl = & qcom_smmu_v2_impl ,
476+ .adreno_impl = & qcom_adreno_smmu_v2_impl ,
477+ };
478+
479+ static const struct qcom_smmu_match_data sdm845_smmu_500_data = {
480+ .impl = & sdm845_smmu_500_impl ,
481+ /*
482+ * No need for adreno impl here. On sdm845 the Adreno SMMU is handled
483+ * by the separate sdm845-smmu-v2 device.
484+ */
485+ /* Also no debug configuration. */
486+ };
487+
488+ static const struct qcom_smmu_match_data qcom_smmu_500_impl0_data = {
489+ .impl = & qcom_smmu_500_impl ,
490+ .adreno_impl = & qcom_adreno_smmu_500_impl ,
491+ .cfg = & qcom_smmu_impl0_cfg ,
492+ };
493+
494+ /*
495+ * Do not add any more qcom,SOC-smmu-500 entries to this list, unless they need
496+ * special handling and can not be covered by the qcom,smmu-500 entry.
497+ */
426498static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match [] = {
427- { .compatible = "qcom,msm8998-smmu-v2" },
428- { .compatible = "qcom,qcm2290-smmu-500" },
429- { .compatible = "qcom,sc7180-smmu-500" },
430- { .compatible = "qcom,sc7280-smmu-500" },
431- { .compatible = "qcom,sc8180x-smmu-500" },
432- { .compatible = "qcom,sc8280xp-smmu-500" },
433- { .compatible = "qcom,sdm630-smmu-v2" },
434- { .compatible = "qcom,sdm845-smmu-500" },
435- { .compatible = "qcom,sm6125-smmu-500" },
436- { .compatible = "qcom,sm6350-smmu-500" },
437- { .compatible = "qcom,sm6375-smmu-500" },
438- { .compatible = "qcom,sm8150-smmu-500" },
439- { .compatible = "qcom,sm8250-smmu-500" },
440- { .compatible = "qcom,sm8350-smmu-500" },
441- { .compatible = "qcom,sm8450-smmu-500" },
499+ { .compatible = "qcom,msm8996-smmu-v2" , .data = & msm8996_smmu_data },
500+ { .compatible = "qcom,msm8998-smmu-v2" , .data = & qcom_smmu_v2_data },
501+ { .compatible = "qcom,qcm2290-smmu-500" , .data = & qcom_smmu_500_impl0_data },
502+ { .compatible = "qcom,qdu1000-smmu-500" , .data = & qcom_smmu_500_impl0_data },
503+ { .compatible = "qcom,sc7180-smmu-500" , .data = & qcom_smmu_500_impl0_data },
504+ { .compatible = "qcom,sc7280-smmu-500" , .data = & qcom_smmu_500_impl0_data },
505+ { .compatible = "qcom,sc8180x-smmu-500" , .data = & qcom_smmu_500_impl0_data },
506+ { .compatible = "qcom,sc8280xp-smmu-500" , .data = & qcom_smmu_500_impl0_data },
507+ { .compatible = "qcom,sdm630-smmu-v2" , .data = & qcom_smmu_v2_data },
508+ { .compatible = "qcom,sdm845-smmu-v2" , .data = & qcom_smmu_v2_data },
509+ { .compatible = "qcom,sdm845-smmu-500" , .data = & sdm845_smmu_500_data },
510+ { .compatible = "qcom,sm6115-smmu-500" , .data = & qcom_smmu_500_impl0_data },
511+ { .compatible = "qcom,sm6125-smmu-500" , .data = & qcom_smmu_500_impl0_data },
512+ { .compatible = "qcom,sm6350-smmu-v2" , .data = & qcom_smmu_v2_data },
513+ { .compatible = "qcom,sm6350-smmu-500" , .data = & qcom_smmu_500_impl0_data },
514+ { .compatible = "qcom,sm6375-smmu-500" , .data = & qcom_smmu_500_impl0_data },
515+ { .compatible = "qcom,sm8150-smmu-500" , .data = & qcom_smmu_500_impl0_data },
516+ { .compatible = "qcom,sm8250-smmu-500" , .data = & qcom_smmu_500_impl0_data },
517+ { .compatible = "qcom,sm8350-smmu-500" , .data = & qcom_smmu_500_impl0_data },
518+ { .compatible = "qcom,sm8450-smmu-500" , .data = & qcom_smmu_500_impl0_data },
519+ { .compatible = "qcom,smmu-500" , .data = & qcom_smmu_500_impl0_data },
442520 { }
443521};
444522
@@ -453,26 +531,19 @@ static struct acpi_platform_list qcom_acpi_platlist[] = {
453531struct arm_smmu_device * qcom_smmu_impl_init (struct arm_smmu_device * smmu )
454532{
455533 const struct device_node * np = smmu -> dev -> of_node ;
534+ const struct of_device_id * match ;
456535
457536#ifdef CONFIG_ACPI
458537 if (np == NULL ) {
459538 /* Match platform for ACPI boot */
460539 if (acpi_match_platform_list (qcom_acpi_platlist ) >= 0 )
461- return qcom_smmu_create (smmu , & qcom_smmu_impl );
540+ return qcom_smmu_create (smmu , & qcom_smmu_500_impl0_data );
462541 }
463542#endif
464543
465- /*
466- * Do not change this order of implementation, i.e., first adreno
467- * smmu impl and then apss smmu since we can have both implementing
468- * arm,mmu-500 in which case we will miss setting adreno smmu specific
469- * features if the order is changed.
470- */
471- if (of_device_is_compatible (np , "qcom,adreno-smmu" ))
472- return qcom_smmu_create (smmu , & qcom_adreno_smmu_impl );
473-
474- if (of_match_node (qcom_smmu_impl_of_match , np ))
475- return qcom_smmu_create (smmu , & qcom_smmu_impl );
544+ match = of_match_node (qcom_smmu_impl_of_match , np );
545+ if (match )
546+ return qcom_smmu_create (smmu , match -> data );
476547
477548 return smmu ;
478549}
0 commit comments