mtk-infracfg.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2015 Pengutronix, Sascha Hauer <[email protected]>
  4. */
  5. #include <linux/export.h>
  6. #include <linux/jiffies.h>
  7. #include <linux/regmap.h>
  8. #include <linux/mfd/syscon.h>
  9. #include <linux/soc/mediatek/infracfg.h>
  10. #include <asm/processor.h>
  11. #define MTK_POLL_DELAY_US 10
  12. #define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ))
  13. /**
  14. * mtk_infracfg_set_bus_protection - enable bus protection
  15. * @infracfg: The infracfg regmap
  16. * @mask: The mask containing the protection bits to be enabled.
  17. * @reg_update: The boolean flag determines to set the protection bits
  18. * by regmap_update_bits with enable register(PROTECTEN) or
  19. * by regmap_write with set register(PROTECTEN_SET).
  20. *
  21. * This function enables the bus protection bits for disabled power
  22. * domains so that the system does not hang when some unit accesses the
  23. * bus while in power down.
  24. */
  25. int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
  26. bool reg_update)
  27. {
  28. u32 val;
  29. int ret;
  30. if (reg_update)
  31. regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask,
  32. mask);
  33. else
  34. regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask);
  35. ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
  36. val, (val & mask) == mask,
  37. MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
  38. return ret;
  39. }
  40. /**
  41. * mtk_infracfg_clear_bus_protection - disable bus protection
  42. * @infracfg: The infracfg regmap
  43. * @mask: The mask containing the protection bits to be disabled.
  44. * @reg_update: The boolean flag determines to clear the protection bits
  45. * by regmap_update_bits with enable register(PROTECTEN) or
  46. * by regmap_write with clear register(PROTECTEN_CLR).
  47. *
  48. * This function disables the bus protection bits previously enabled with
  49. * mtk_infracfg_set_bus_protection.
  50. */
  51. int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
  52. bool reg_update)
  53. {
  54. int ret;
  55. u32 val;
  56. if (reg_update)
  57. regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
  58. else
  59. regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask);
  60. ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
  61. val, !(val & mask),
  62. MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
  63. return ret;
  64. }
  65. static int __init mtk_infracfg_init(void)
  66. {
  67. struct regmap *infracfg;
  68. /*
  69. * MT8192 has an experimental path to route GPU traffic to the DSU's
  70. * Accelerator Coherency Port, which is inadvertently enabled by
  71. * default. It turns out not to work, so disable it to prevent spurious
  72. * GPU faults.
  73. */
  74. infracfg = syscon_regmap_lookup_by_compatible("mediatek,mt8192-infracfg");
  75. if (!IS_ERR(infracfg))
  76. regmap_set_bits(infracfg, MT8192_INFRA_CTRL,
  77. MT8192_INFRA_CTRL_DISABLE_MFG2ACP);
  78. return 0;
  79. }
  80. postcore_initcall(mtk_infracfg_init);