tegra186-power-domain.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2016, NVIDIA CORPORATION.
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <misc.h>
  8. #include <power-domain-uclass.h>
  9. #include <asm/arch-tegra/bpmp_abi.h>
  10. #define UPDATE BIT(0)
  11. #define ON BIT(1)
  12. static int tegra186_power_domain_request(struct power_domain *power_domain)
  13. {
  14. debug("%s(power_domain=%p) (dev=%p, id=%lu)\n", __func__,
  15. power_domain, power_domain->dev, power_domain->id);
  16. return 0;
  17. }
  18. static int tegra186_power_domain_free(struct power_domain *power_domain)
  19. {
  20. debug("%s(power_domain=%p) (dev=%p, id=%lu)\n", __func__,
  21. power_domain, power_domain->dev, power_domain->id);
  22. return 0;
  23. }
  24. static int tegra186_power_domain_common(struct power_domain *power_domain,
  25. bool on)
  26. {
  27. struct mrq_pg_update_state_request req;
  28. int on_state = on ? ON : 0;
  29. int ret;
  30. req.partition_id = power_domain->id;
  31. req.logic_state = UPDATE | on_state;
  32. req.sram_state = UPDATE | on_state;
  33. /*
  34. * Drivers manage their own clocks so they don't get out of sync, and
  35. * since some power domains have many clocks, only a subset of which
  36. * are actually needed depending on use-case.
  37. */
  38. req.clock_state = UPDATE;
  39. ret = misc_call(power_domain->dev->parent, MRQ_PG_UPDATE_STATE, &req,
  40. sizeof(req), NULL, 0);
  41. if (ret < 0)
  42. return ret;
  43. return 0;
  44. }
  45. static int tegra186_power_domain_on(struct power_domain *power_domain)
  46. {
  47. debug("%s(power_domain=%p) (dev=%p, id=%lu)\n", __func__,
  48. power_domain, power_domain->dev, power_domain->id);
  49. return tegra186_power_domain_common(power_domain, true);
  50. }
  51. static int tegra186_power_domain_off(struct power_domain *power_domain)
  52. {
  53. debug("%s(power_domain=%p) (dev=%p, id=%lu)\n", __func__,
  54. power_domain, power_domain->dev, power_domain->id);
  55. return tegra186_power_domain_common(power_domain, false);
  56. }
  57. struct power_domain_ops tegra186_power_domain_ops = {
  58. .request = tegra186_power_domain_request,
  59. .rfree = tegra186_power_domain_free,
  60. .on = tegra186_power_domain_on,
  61. .off = tegra186_power_domain_off,
  62. };
  63. static int tegra186_power_domain_probe(struct udevice *dev)
  64. {
  65. debug("%s(dev=%p)\n", __func__, dev);
  66. return 0;
  67. }
  68. U_BOOT_DRIVER(tegra186_power_domain) = {
  69. .name = "tegra186_power_domain",
  70. .id = UCLASS_POWER_DOMAIN,
  71. .probe = tegra186_power_domain_probe,
  72. .ops = &tegra186_power_domain_ops,
  73. };