mtk-infracfg.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/regmap.h>
  14. #include <linux/export.h>
  15. #include <linux/module.h>
  16. #include <linux/jiffies.h>
  17. #include <linux/soc/mediatek/infracfg.h>
  18. #include <asm/processor.h>
  19. #define INFRA_TOPAXI_PROTECTEN 0x0220
  20. #define INFRA_TOPAXI_PROTECTSTA1 0x0228
  21. #define INFRA_TOPAXI_PROTECTEN1 0x0250
  22. #define INFRA_TOPAXI_PROTECTSTA3 0x0258
  23. static int set_bits_wait(struct regmap *reg, u32 mask, u32 en_ofs, u32 sta_ofs)
  24. {
  25. unsigned long expired;
  26. u32 val;
  27. int ret;
  28. regmap_update_bits(reg, en_ofs, mask, mask);
  29. expired = jiffies + HZ;
  30. while (1) {
  31. ret = regmap_read(reg, sta_ofs, &val);
  32. if (ret)
  33. return ret;
  34. if ((val & mask) == mask)
  35. break;
  36. cpu_relax();
  37. if (time_after(jiffies, expired))
  38. return -EIO;
  39. }
  40. return 0;
  41. }
  42. static int clr_bits_wait(struct regmap *reg, u32 mask, u32 en_ofs, u32 sta_ofs)
  43. {
  44. unsigned long expired;
  45. u32 val;
  46. int ret;
  47. regmap_update_bits(reg, en_ofs, mask, 0);
  48. expired = jiffies + HZ;
  49. while (1) {
  50. ret = regmap_read(reg, sta_ofs, &val);
  51. if (ret)
  52. return ret;
  53. if (!(val & mask))
  54. break;
  55. cpu_relax();
  56. if (time_after(jiffies, expired))
  57. return -EIO;
  58. }
  59. return 0;
  60. }
  61. /**
  62. * mtk_infracfg_set_bus_protection - enable bus protection
  63. * @regmap: The infracfg regmap
  64. * @mask: The mask containing the protection bits to be enabled.
  65. *
  66. * This function enables the bus protection bits for disabled power
  67. * domains so that the system does not hanf when some unit accesses the
  68. * bus while in power down.
  69. */
  70. int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask)
  71. {
  72. return set_bits_wait(infracfg, mask,
  73. INFRA_TOPAXI_PROTECTEN, INFRA_TOPAXI_PROTECTSTA1);
  74. }
  75. /**
  76. * mtk_infracfg_clear_bus_protection - disable bus protection
  77. * @regmap: The infracfg regmap
  78. * @mask: The mask containing the protection bits to be disabled.
  79. *
  80. * This function disables the bus protection bits previously enabled with
  81. * mtk_infracfg_set_bus_protection.
  82. */
  83. int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask)
  84. {
  85. return clr_bits_wait(infracfg, mask,
  86. INFRA_TOPAXI_PROTECTEN, INFRA_TOPAXI_PROTECTSTA1);
  87. }
  88. /**
  89. * mtk_infracfg_set_bus_protection1 - enable bus protection
  90. * @regmap: The infracfg regmap
  91. * @mask: The mask containing the protection bits to be enabled.
  92. *
  93. * This function enables the bus protection bits for disabled power
  94. * domains so that the system does not hanf when some unit accesses the
  95. * bus while in power down.
  96. */
  97. int mtk_infracfg_set_bus_protection1(struct regmap *infracfg, u32 mask)
  98. {
  99. return set_bits_wait(infracfg, mask,
  100. INFRA_TOPAXI_PROTECTEN1, INFRA_TOPAXI_PROTECTSTA3);
  101. }
  102. /**
  103. * mtk_infracfg_clear_bus_protection1 - disable bus protection
  104. * @regmap: The infracfg regmap
  105. * @mask: The mask containing the protection bits to be disabled.
  106. *
  107. * This function disables the bus protection bits previously enabled with
  108. * mtk_infracfg_set_bus_protection.
  109. */
  110. int mtk_infracfg_clear_bus_protection1(struct regmap *infracfg, u32 mask)
  111. {
  112. return clr_bits_wait(infracfg, mask,
  113. INFRA_TOPAXI_PROTECTEN1, INFRA_TOPAXI_PROTECTSTA3);
  114. }
  115. MODULE_LICENSE("GPL v2");