omap-iommu.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * OMAP IOMMU quirks for various TI SoCs
  3. *
  4. * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
  5. * Suman Anna <s-anna@ti.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * version 2 as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. #include <linux/platform_device.h>
  17. #include <linux/err.h>
  18. #include "omap_hwmod.h"
  19. #include "omap_device.h"
  20. #include "clockdomain.h"
  21. #include "powerdomain.h"
  22. static void omap_iommu_dra7_emu_swsup_config(struct platform_device *pdev,
  23. bool enable)
  24. {
  25. static struct clockdomain *emu_clkdm;
  26. static DEFINE_SPINLOCK(emu_lock);
  27. static atomic_t count;
  28. struct device_node *np = pdev->dev.of_node;
  29. if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu"))
  30. return;
  31. if (!emu_clkdm) {
  32. emu_clkdm = clkdm_lookup("emu_clkdm");
  33. if (WARN_ON_ONCE(!emu_clkdm))
  34. return;
  35. }
  36. spin_lock(&emu_lock);
  37. if (enable && (atomic_inc_return(&count) == 1))
  38. clkdm_deny_idle(emu_clkdm);
  39. else if (!enable && (atomic_dec_return(&count) == 0))
  40. clkdm_allow_idle(emu_clkdm);
  41. spin_unlock(&emu_lock);
  42. }
  43. int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
  44. u8 *pwrst)
  45. {
  46. struct powerdomain *pwrdm;
  47. struct omap_device *od;
  48. u8 next_pwrst;
  49. int ret = 0;
  50. od = to_omap_device(pdev);
  51. if (!od)
  52. return -ENODEV;
  53. if (od->hwmods_cnt != 1)
  54. return -EINVAL;
  55. pwrdm = omap_hwmod_get_pwrdm(od->hwmods[0]);
  56. if (!pwrdm)
  57. return -EINVAL;
  58. if (request) {
  59. *pwrst = pwrdm_read_next_pwrst(pwrdm);
  60. omap_iommu_dra7_emu_swsup_config(pdev, true);
  61. }
  62. if (*pwrst > PWRDM_POWER_RET)
  63. goto out;
  64. next_pwrst = request ? PWRDM_POWER_ON : *pwrst;
  65. ret = pwrdm_set_next_pwrst(pwrdm, next_pwrst);
  66. out:
  67. if (!request)
  68. omap_iommu_dra7_emu_swsup_config(pdev, false);
  69. return ret;
  70. }