ti_power_proc.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2015-2016
  4. * Texas Instruments Incorporated - http://www.ti.com/
  5. */
  6. #define pr_fmt(fmt) "%s: " fmt, __func__
  7. #include <common.h>
  8. #include <dm.h>
  9. #include <errno.h>
  10. #include <fdtdec.h>
  11. #include <log.h>
  12. #include <remoteproc.h>
  13. #include <mach/psc_defs.h>
  14. DECLARE_GLOBAL_DATA_PTR;
  15. /**
  16. * struct ti_powerproc_privdata - power processor private data
  17. * @loadaddr: base address for loading the power processor
  18. * @psc_module: psc module address.
  19. */
  20. struct ti_powerproc_privdata {
  21. phys_addr_t loadaddr;
  22. u32 psc_module;
  23. };
  24. /**
  25. * ti_of_to_priv() - generate private data from device tree
  26. * @dev: corresponding ti remote processor device
  27. * @priv: pointer to driver specific private data
  28. *
  29. * Return: 0 if all went ok, else corresponding -ve error
  30. */
  31. static int ti_of_to_priv(struct udevice *dev,
  32. struct ti_powerproc_privdata *priv)
  33. {
  34. int node = dev_of_offset(dev);
  35. const void *blob = gd->fdt_blob;
  36. int tmp;
  37. if (!blob) {
  38. debug("'%s' no dt?\n", dev->name);
  39. return -EINVAL;
  40. }
  41. priv->loadaddr = fdtdec_get_addr(blob, node, "reg");
  42. if (priv->loadaddr == FDT_ADDR_T_NONE) {
  43. debug("'%s': no 'reg' property\n", dev->name);
  44. return -EINVAL;
  45. }
  46. tmp = fdtdec_get_int(blob, node, "ti,lpsc_module", -EINVAL);
  47. if (tmp < 0) {
  48. debug("'%s': no 'ti,lpsc_module' property\n", dev->name);
  49. return tmp;
  50. }
  51. priv->psc_module = tmp;
  52. return 0;
  53. }
  54. /**
  55. * ti_powerproc_probe() - Basic probe
  56. * @dev: corresponding ti remote processor device
  57. *
  58. * Return: 0 if all went ok, else corresponding -ve error
  59. */
  60. static int ti_powerproc_probe(struct udevice *dev)
  61. {
  62. struct dm_rproc_uclass_pdata *uc_pdata;
  63. struct ti_powerproc_privdata *priv;
  64. int ret;
  65. uc_pdata = dev_get_uclass_platdata(dev);
  66. priv = dev_get_priv(dev);
  67. ret = ti_of_to_priv(dev, priv);
  68. debug("%s probed with slave_addr=0x%08lX module=%d(%d)\n",
  69. uc_pdata->name, priv->loadaddr, priv->psc_module, ret);
  70. return ret;
  71. }
  72. /**
  73. * ti_powerproc_load() - Loadup the TI remote processor
  74. * @dev: corresponding ti remote processor device
  75. * @addr: Address in memory where image binary is stored
  76. * @size: Size in bytes of the image binary
  77. *
  78. * Return: 0 if all went ok, else corresponding -ve error
  79. */
  80. static int ti_powerproc_load(struct udevice *dev, ulong addr, ulong size)
  81. {
  82. struct dm_rproc_uclass_pdata *uc_pdata;
  83. struct ti_powerproc_privdata *priv;
  84. int ret;
  85. uc_pdata = dev_get_uclass_platdata(dev);
  86. if (!uc_pdata) {
  87. debug("%s: no uc pdata!\n", dev->name);
  88. return -EINVAL;
  89. }
  90. priv = dev_get_priv(dev);
  91. ret = psc_module_keep_in_reset_enabled(priv->psc_module, false);
  92. if (ret) {
  93. debug("%s Unable to disable module '%d'(ret=%d)\n",
  94. uc_pdata->name, priv->psc_module, ret);
  95. return ret;
  96. }
  97. debug("%s: Loading binary from 0x%08lX, size 0x%08lX to 0x%08lX\n",
  98. uc_pdata->name, addr, size, priv->loadaddr);
  99. memcpy((void *)priv->loadaddr, (void *)addr, size);
  100. debug("%s: Complete!\n", uc_pdata->name);
  101. return 0;
  102. }
  103. /**
  104. * ti_powerproc_start() - (replace: short desc)
  105. * @dev: corresponding ti remote processor device
  106. *
  107. * Return: 0 if all went ok, else corresponding -ve error
  108. */
  109. static int ti_powerproc_start(struct udevice *dev)
  110. {
  111. struct dm_rproc_uclass_pdata *uc_pdata;
  112. struct ti_powerproc_privdata *priv;
  113. int ret;
  114. uc_pdata = dev_get_uclass_platdata(dev);
  115. if (!uc_pdata) {
  116. debug("%s: no uc pdata!\n", dev->name);
  117. return -EINVAL;
  118. }
  119. priv = dev_get_priv(dev);
  120. ret = psc_disable_module(priv->psc_module);
  121. if (ret) {
  122. debug("%s Unable to disable module '%d'(ret=%d)\n",
  123. uc_pdata->name, priv->psc_module, ret);
  124. return ret;
  125. }
  126. ret = psc_module_release_from_reset(priv->psc_module);
  127. if (ret) {
  128. debug("%s Failed to wait for module '%d'(ret=%d)\n",
  129. uc_pdata->name, priv->psc_module, ret);
  130. return ret;
  131. }
  132. ret = psc_enable_module(priv->psc_module);
  133. if (ret) {
  134. debug("%s Unable to disable module '%d'(ret=%d)\n",
  135. uc_pdata->name, priv->psc_module, ret);
  136. return ret;
  137. }
  138. return 0;
  139. }
  140. static const struct dm_rproc_ops ti_powerproc_ops = {
  141. .load = ti_powerproc_load,
  142. .start = ti_powerproc_start,
  143. };
  144. static const struct udevice_id ti_powerproc_ids[] = {
  145. {.compatible = "ti,power-processor"},
  146. {}
  147. };
  148. U_BOOT_DRIVER(ti_powerproc) = {
  149. .name = "ti_power_proc",
  150. .of_match = ti_powerproc_ids,
  151. .id = UCLASS_REMOTEPROC,
  152. .ops = &ti_powerproc_ops,
  153. .probe = ti_powerproc_probe,
  154. .priv_auto_alloc_size = sizeof(struct ti_powerproc_privdata),
  155. };