tegra186-power-domain.c 2.3 KB

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