coresight-replicator-qcom.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/amba/bus.h>
  14. #include <linux/clk.h>
  15. #include <linux/coresight.h>
  16. #include <linux/device.h>
  17. #include <linux/module.h>
  18. #include <linux/err.h>
  19. #include <linux/init.h>
  20. #include <linux/io.h>
  21. #include <linux/kernel.h>
  22. #include <linux/of.h>
  23. #include <linux/pm_runtime.h>
  24. #include <linux/slab.h>
  25. #include "coresight-priv.h"
  26. #define REPLICATOR_IDFILTER0 0x000
  27. #define REPLICATOR_IDFILTER1 0x004
  28. /**
  29. * struct replicator_state - specifics associated to a replicator component
  30. * @base: memory mapped base address for this component.
  31. * @dev: the device entity associated with this component
  32. * @atclk: optional clock for the core parts of the replicator.
  33. * @csdev: component vitals needed by the framework
  34. */
  35. struct replicator_state {
  36. void __iomem *base;
  37. struct device *dev;
  38. struct clk *atclk;
  39. struct coresight_device *csdev;
  40. };
  41. static int replicator_enable(struct coresight_device *csdev, int inport,
  42. int outport)
  43. {
  44. struct replicator_state *drvdata = dev_get_drvdata(csdev->dev.parent);
  45. pm_runtime_get_sync(drvdata->dev);
  46. CS_UNLOCK(drvdata->base);
  47. /*
  48. * Ensure that the other port is disabled
  49. * 0x00 - passing through the replicator unimpeded
  50. * 0xff - disable (or impede) the flow of ATB data
  51. */
  52. if (outport == 0) {
  53. writel_relaxed(0x00, drvdata->base + REPLICATOR_IDFILTER0);
  54. writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER1);
  55. } else {
  56. writel_relaxed(0x00, drvdata->base + REPLICATOR_IDFILTER1);
  57. writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER0);
  58. }
  59. CS_LOCK(drvdata->base);
  60. dev_info(drvdata->dev, "REPLICATOR enabled\n");
  61. return 0;
  62. }
  63. static void replicator_disable(struct coresight_device *csdev, int inport,
  64. int outport)
  65. {
  66. struct replicator_state *drvdata = dev_get_drvdata(csdev->dev.parent);
  67. CS_UNLOCK(drvdata->base);
  68. /* disable the flow of ATB data through port */
  69. if (outport == 0)
  70. writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER0);
  71. else
  72. writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER1);
  73. CS_LOCK(drvdata->base);
  74. pm_runtime_put(drvdata->dev);
  75. dev_info(drvdata->dev, "REPLICATOR disabled\n");
  76. }
  77. static const struct coresight_ops_link replicator_link_ops = {
  78. .enable = replicator_enable,
  79. .disable = replicator_disable,
  80. };
  81. static const struct coresight_ops replicator_cs_ops = {
  82. .link_ops = &replicator_link_ops,
  83. };
  84. static int replicator_probe(struct amba_device *adev, const struct amba_id *id)
  85. {
  86. int ret;
  87. struct device *dev = &adev->dev;
  88. struct resource *res = &adev->res;
  89. struct coresight_platform_data *pdata = NULL;
  90. struct replicator_state *drvdata;
  91. struct coresight_desc *desc;
  92. struct device_node *np = adev->dev.of_node;
  93. void __iomem *base;
  94. if (np) {
  95. pdata = of_get_coresight_platform_data(dev, np);
  96. if (IS_ERR(pdata))
  97. return PTR_ERR(pdata);
  98. adev->dev.platform_data = pdata;
  99. }
  100. drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
  101. if (!drvdata)
  102. return -ENOMEM;
  103. drvdata->dev = &adev->dev;
  104. drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
  105. if (!IS_ERR(drvdata->atclk)) {
  106. ret = clk_prepare_enable(drvdata->atclk);
  107. if (ret)
  108. return ret;
  109. }
  110. /* Validity for the resource is already checked by the AMBA core */
  111. base = devm_ioremap_resource(dev, res);
  112. if (IS_ERR(base))
  113. return PTR_ERR(base);
  114. drvdata->base = base;
  115. dev_set_drvdata(dev, drvdata);
  116. pm_runtime_put(&adev->dev);
  117. desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
  118. if (!desc)
  119. return -ENOMEM;
  120. desc->type = CORESIGHT_DEV_TYPE_LINK;
  121. desc->subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT;
  122. desc->ops = &replicator_cs_ops;
  123. desc->pdata = adev->dev.platform_data;
  124. desc->dev = &adev->dev;
  125. drvdata->csdev = coresight_register(desc);
  126. if (IS_ERR(drvdata->csdev))
  127. return PTR_ERR(drvdata->csdev);
  128. dev_info(dev, "%s initialized\n", (char *)id->data);
  129. return 0;
  130. }
  131. static int replicator_remove(struct amba_device *adev)
  132. {
  133. struct replicator_state *drvdata = amba_get_drvdata(adev);
  134. pm_runtime_disable(&adev->dev);
  135. coresight_unregister(drvdata->csdev);
  136. return 0;
  137. }
  138. #ifdef CONFIG_PM
  139. static int replicator_runtime_suspend(struct device *dev)
  140. {
  141. struct replicator_state *drvdata = dev_get_drvdata(dev);
  142. if (drvdata && !IS_ERR(drvdata->atclk))
  143. clk_disable_unprepare(drvdata->atclk);
  144. return 0;
  145. }
  146. static int replicator_runtime_resume(struct device *dev)
  147. {
  148. struct replicator_state *drvdata = dev_get_drvdata(dev);
  149. if (drvdata && !IS_ERR(drvdata->atclk))
  150. clk_prepare_enable(drvdata->atclk);
  151. return 0;
  152. }
  153. #endif
  154. static const struct dev_pm_ops replicator_dev_pm_ops = {
  155. SET_RUNTIME_PM_OPS(replicator_runtime_suspend,
  156. replicator_runtime_resume,
  157. NULL)
  158. };
  159. static struct amba_id replicator_ids[] = {
  160. {
  161. .id = 0x0003b909,
  162. .mask = 0x0003ffff,
  163. .data = "REPLICATOR 1.0",
  164. },
  165. { 0, 0 },
  166. };
  167. static struct amba_driver replicator_driver = {
  168. .drv = {
  169. .name = "coresight-replicator-qcom",
  170. .pm = &replicator_dev_pm_ops,
  171. },
  172. .probe = replicator_probe,
  173. .remove = replicator_remove,
  174. .id_table = replicator_ids,
  175. };
  176. module_amba_driver(replicator_driver);