imx8m-power-domain.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright 2017 NXP
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <malloc.h>
  8. #include <power-domain-uclass.h>
  9. #include <asm/io.h>
  10. #include <asm/arch/power-domain.h>
  11. #include <asm/mach-imx/sys_proto.h>
  12. #include <dm/device-internal.h>
  13. #include <dm/device.h>
  14. #include <imx_sip.h>
  15. #include <linux/arm-smccc.h>
  16. DECLARE_GLOBAL_DATA_PTR;
  17. static int imx8m_power_domain_request(struct power_domain *power_domain)
  18. {
  19. return 0;
  20. }
  21. static int imx8m_power_domain_free(struct power_domain *power_domain)
  22. {
  23. return 0;
  24. }
  25. static int imx8m_power_domain_on(struct power_domain *power_domain)
  26. {
  27. struct udevice *dev = power_domain->dev;
  28. struct imx8m_power_domain_platdata *pdata;
  29. pdata = dev_get_platdata(dev);
  30. if (pdata->resource_id < 0)
  31. return -EINVAL;
  32. if (pdata->has_pd)
  33. power_domain_on(&pdata->pd);
  34. arm_smccc_smc(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN,
  35. pdata->resource_id, 1, 0, 0, 0, 0, NULL);
  36. return 0;
  37. }
  38. static int imx8m_power_domain_off(struct power_domain *power_domain)
  39. {
  40. struct udevice *dev = power_domain->dev;
  41. struct imx8m_power_domain_platdata *pdata;
  42. pdata = dev_get_platdata(dev);
  43. if (pdata->resource_id < 0)
  44. return -EINVAL;
  45. arm_smccc_smc(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN,
  46. pdata->resource_id, 0, 0, 0, 0, 0, NULL);
  47. if (pdata->has_pd)
  48. power_domain_off(&pdata->pd);
  49. return 0;
  50. }
  51. static int imx8m_power_domain_of_xlate(struct power_domain *power_domain,
  52. struct ofnode_phandle_args *args)
  53. {
  54. return 0;
  55. }
  56. static int imx8m_power_domain_bind(struct udevice *dev)
  57. {
  58. int offset;
  59. const char *name;
  60. int ret = 0;
  61. offset = dev_of_offset(dev);
  62. for (offset = fdt_first_subnode(gd->fdt_blob, offset); offset > 0;
  63. offset = fdt_next_subnode(gd->fdt_blob, offset)) {
  64. /* Bind the subnode to this driver */
  65. name = fdt_get_name(gd->fdt_blob, offset, NULL);
  66. ret = device_bind_with_driver_data(dev, dev->driver, name,
  67. dev->driver_data,
  68. offset_to_ofnode(offset),
  69. NULL);
  70. if (ret == -ENODEV)
  71. printf("Driver '%s' refuses to bind\n",
  72. dev->driver->name);
  73. if (ret)
  74. printf("Error binding driver '%s': %d\n",
  75. dev->driver->name, ret);
  76. }
  77. return 0;
  78. }
  79. static int imx8m_power_domain_probe(struct udevice *dev)
  80. {
  81. return 0;
  82. }
  83. static int imx8m_power_domain_ofdata_to_platdata(struct udevice *dev)
  84. {
  85. struct imx8m_power_domain_platdata *pdata = dev_get_platdata(dev);
  86. pdata->resource_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
  87. "reg", -1);
  88. if (!power_domain_get(dev, &pdata->pd))
  89. pdata->has_pd = 1;
  90. return 0;
  91. }
  92. static const struct udevice_id imx8m_power_domain_ids[] = {
  93. { .compatible = "fsl,imx8mq-gpc" },
  94. { }
  95. };
  96. struct power_domain_ops imx8m_power_domain_ops = {
  97. .request = imx8m_power_domain_request,
  98. .rfree = imx8m_power_domain_free,
  99. .on = imx8m_power_domain_on,
  100. .off = imx8m_power_domain_off,
  101. .of_xlate = imx8m_power_domain_of_xlate,
  102. };
  103. U_BOOT_DRIVER(imx8m_power_domain) = {
  104. .name = "imx8m_power_domain",
  105. .id = UCLASS_POWER_DOMAIN,
  106. .of_match = imx8m_power_domain_ids,
  107. .bind = imx8m_power_domain_bind,
  108. .probe = imx8m_power_domain_probe,
  109. .ofdata_to_platdata = imx8m_power_domain_ofdata_to_platdata,
  110. .platdata_auto_alloc_size = sizeof(struct imx8m_power_domain_platdata),
  111. .ops = &imx8m_power_domain_ops,
  112. };