mtk-infracfg.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
  4. */
  5. #include <linux/export.h>
  6. #include <linux/jiffies.h>
  7. #include <linux/regmap.h>
  8. #include <linux/soc/mediatek/infracfg.h>
  9. #include <asm/processor.h>
  10. #define MTK_POLL_DELAY_US 10
  11. #define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ))
  12. #define INFRA_TOPAXI_PROTECTEN 0x0220
  13. #define INFRA_TOPAXI_PROTECTSTA1 0x0228
  14. #define INFRA_TOPAXI_PROTECTEN_SET 0x0260
  15. #define INFRA_TOPAXI_PROTECTEN_CLR 0x0264
  16. /**
  17. * mtk_infracfg_set_bus_protection - enable bus protection
  18. * @regmap: The infracfg regmap
  19. * @mask: The mask containing the protection bits to be enabled.
  20. * @reg_update: The boolean flag determines to set the protection bits
  21. * by regmap_update_bits with enable register(PROTECTEN) or
  22. * by regmap_write with set register(PROTECTEN_SET).
  23. *
  24. * This function enables the bus protection bits for disabled power
  25. * domains so that the system does not hang when some unit accesses the
  26. * bus while in power down.
  27. */
  28. int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
  29. bool reg_update)
  30. {
  31. u32 val;
  32. int ret;
  33. if (reg_update)
  34. regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask,
  35. mask);
  36. else
  37. regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask);
  38. ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
  39. val, (val & mask) == mask,
  40. MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
  41. return ret;
  42. }
  43. /**
  44. * mtk_infracfg_clear_bus_protection - disable bus protection
  45. * @regmap: The infracfg regmap
  46. * @mask: The mask containing the protection bits to be disabled.
  47. * @reg_update: The boolean flag determines to clear the protection bits
  48. * by regmap_update_bits with enable register(PROTECTEN) or
  49. * by regmap_write with clear register(PROTECTEN_CLR).
  50. *
  51. * This function disables the bus protection bits previously enabled with
  52. * mtk_infracfg_set_bus_protection.
  53. */
  54. int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
  55. bool reg_update)
  56. {
  57. int ret;
  58. u32 val;
  59. if (reg_update)
  60. regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
  61. else
  62. regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask);
  63. ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
  64. val, !(val & mask),
  65. MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
  66. return ret;
  67. }