smmu.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
  3. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. */
  7. #include <assert.h>
  8. #include <string.h>
  9. #include <platform_def.h>
  10. #include <common/bl_common.h>
  11. #include <common/debug.h>
  12. #include <smmu.h>
  13. #include <tegra_platform.h>
  14. #include <tegra_private.h>
  15. extern void memcpy16(void *dest, const void *src, unsigned int length);
  16. #define SMMU_NUM_CONTEXTS 64U
  17. #define SMMU_CONTEXT_BANK_MAX_IDX 64U
  18. #define MISMATCH_DETECTED 0x55AA55AAU
  19. /*
  20. * Init SMMU during boot or "System Suspend" exit
  21. */
  22. void tegra_smmu_init(void)
  23. {
  24. uint32_t val, cb_idx, smmu_id, ctx_base;
  25. uint32_t num_smmu_devices = plat_get_num_smmu_devices();
  26. for (smmu_id = 0U; smmu_id < num_smmu_devices; smmu_id++) {
  27. /* Program the SMMU pagesize and reset CACHE_LOCK bit */
  28. val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
  29. val |= SMMU_GSR0_PGSIZE_64K;
  30. val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
  31. tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
  32. /* reset CACHE LOCK bit for NS Aux. Config. Register */
  33. val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
  34. val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
  35. tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
  36. /* disable TCU prefetch for all contexts */
  37. ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS)
  38. + SMMU_CBn_ACTLR;
  39. for (cb_idx = 0U; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
  40. val = tegra_smmu_read_32(smmu_id,
  41. ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx));
  42. val &= (uint32_t)~SMMU_CBn_ACTLR_CPRE_BIT;
  43. tegra_smmu_write_32(smmu_id, ctx_base +
  44. (SMMU_GSR0_PGSIZE_64K * cb_idx), val);
  45. }
  46. /* set CACHE LOCK bit for NS Aux. Config. Register */
  47. val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
  48. val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
  49. tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
  50. /* set CACHE LOCK bit for S Aux. Config. Register */
  51. val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
  52. val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
  53. tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
  54. }
  55. }
  56. /*
  57. * Verify SMMU settings have not been altered during boot
  58. */
  59. void tegra_smmu_verify(void)
  60. {
  61. uint32_t cb_idx, ctx_base, smmu_id, val;
  62. uint32_t num_smmu_devices = plat_get_num_smmu_devices();
  63. uint32_t mismatch = 0U;
  64. for (smmu_id = 0U; smmu_id < num_smmu_devices; smmu_id++) {
  65. /* check PGSIZE_64K bit inr S Aux. Config. Register */
  66. val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
  67. if (0U == (val & SMMU_GSR0_PGSIZE_64K)) {
  68. ERROR("%s: PGSIZE_64K Mismatch - smmu_id=%d, GSR0_SECURE_ACR=%x\n",
  69. __func__, smmu_id, val);
  70. mismatch = MISMATCH_DETECTED;
  71. }
  72. /* check CACHE LOCK bit in S Aux. Config. Register */
  73. if (0U == (val & SMMU_ACR_CACHE_LOCK_ENABLE_BIT)) {
  74. ERROR("%s: CACHE_LOCK Mismatch - smmu_id=%d, GSR0_SECURE_ACR=%x\n",
  75. __func__, smmu_id, val);
  76. mismatch = MISMATCH_DETECTED;
  77. }
  78. /* check CACHE LOCK bit in NS Aux. Config. Register */
  79. val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
  80. if (0U == (val & SMMU_ACR_CACHE_LOCK_ENABLE_BIT)) {
  81. ERROR("%s: Mismatch - smmu_id=%d, GNSR_ACR=%x\n",
  82. __func__, smmu_id, val);
  83. mismatch = MISMATCH_DETECTED;
  84. }
  85. /* verify TCU prefetch for all contexts is disabled */
  86. ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) +
  87. SMMU_CBn_ACTLR;
  88. for (cb_idx = 0U; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
  89. val = tegra_smmu_read_32(smmu_id,
  90. ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx));
  91. if (0U != (val & SMMU_CBn_ACTLR_CPRE_BIT)) {
  92. ERROR("%s: Mismatch - smmu_id=%d, cb_idx=%d, GSR0_PGSIZE_64K=%x\n",
  93. __func__, smmu_id, cb_idx, val);
  94. mismatch = MISMATCH_DETECTED;
  95. }
  96. }
  97. }
  98. /* Treat configuration mismatch as fatal */
  99. if ((mismatch == MISMATCH_DETECTED) && tegra_platform_is_silicon()) {
  100. panic();
  101. }
  102. }