dsi_pll.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020, The Linux Foundation. All rights reserved.
  4. */
  5. #define pr_fmt(fmt) "%s: " fmt, __func__
  6. #include <linux/module.h>
  7. #include <linux/of_device.h>
  8. #include <linux/kernel.h>
  9. #include <linux/err.h>
  10. #include <linux/delay.h>
  11. #include <linux/iopoll.h>
  12. #include <linux/vmalloc.h>
  13. #include <linux/io.h>
  14. #include <linux/of_address.h>
  15. #include "dsi_pll.h"
  16. static int dsi_pll_clock_register(struct platform_device *pdev,
  17. struct dsi_pll_resource *pll_res)
  18. {
  19. int rc;
  20. switch (pll_res->pll_revision) {
  21. case DSI_PLL_5NM:
  22. rc = dsi_pll_clock_register_5nm(pdev, pll_res);
  23. break;
  24. default:
  25. rc = -EINVAL;
  26. break;
  27. }
  28. if (rc)
  29. DSI_PLL_ERR(pll_res, "clock register failed rc=%d\n", rc);
  30. return rc;
  31. }
  32. static inline int dsi_pll_get_ioresources(struct platform_device *pdev,
  33. void __iomem **regmap, char *resource_name)
  34. {
  35. int rc = 0;
  36. struct resource *rsc = platform_get_resource_byname(pdev,
  37. IORESOURCE_MEM, resource_name);
  38. if (rsc) {
  39. if (!regmap)
  40. return -ENOMEM;
  41. *regmap = devm_ioremap(&pdev->dev,
  42. rsc->start, resource_size(rsc));
  43. if (!*regmap)
  44. return -ENOMEM;
  45. }
  46. return rc;
  47. }
  48. static void dsi_pll_free_bootmem(u32 mem_addr, u32 size)
  49. {
  50. unsigned long pfn_start, pfn_end, pfn_idx;
  51. pfn_start = mem_addr >> PAGE_SHIFT;
  52. pfn_end = (mem_addr + size) >> PAGE_SHIFT;
  53. for (pfn_idx = pfn_start; pfn_idx < pfn_end; pfn_idx++)
  54. free_reserved_page(pfn_to_page(pfn_idx));
  55. }
  56. static void dsi_pll_parse_dfps(struct platform_device *pdev,
  57. struct dsi_pll_resource *pll_res)
  58. {
  59. struct device_node *pnode = NULL;
  60. const u32 *addr;
  61. struct vm_struct *area = NULL;
  62. u64 size;
  63. u32 offsets[2];
  64. unsigned long virt_add = 0;
  65. pnode = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
  66. if (IS_ERR_OR_NULL(pnode)) {
  67. DSI_PLL_INFO(pll_res, "of_parse_phandle failed\n");
  68. goto node_err;
  69. }
  70. addr = of_get_address(pnode, 0, &size, NULL);
  71. if (!addr) {
  72. DSI_PLL_ERR(pll_res,
  73. "failed to parse the dfps memory address\n");
  74. goto node_err;
  75. }
  76. /* maintain compatibility for 32/64 bit */
  77. offsets[0] = (u32) of_read_ulong(addr, 2);
  78. offsets[1] = (u32) size;
  79. area = get_vm_area(offsets[1], VM_IOREMAP);
  80. if (!area) {
  81. DSI_PLL_ERR(pll_res, "get_vm_area failed\n");
  82. goto mem_err;
  83. }
  84. virt_add = (unsigned long)area->addr;
  85. if (ioremap_page_range(virt_add, (virt_add + offsets[1]),
  86. offsets[0], PAGE_KERNEL)) {
  87. DSI_PLL_ERR(pll_res, "ioremap_page_range failed\n");
  88. goto mem_err;
  89. }
  90. pll_res->dfps = kzalloc(sizeof(struct dfps_info), GFP_KERNEL);
  91. if (IS_ERR_OR_NULL(pll_res->dfps)) {
  92. DSI_PLL_ERR(pll_res, "pll_res->dfps allocate failed\n");
  93. goto mem_err;
  94. }
  95. /* memcopy complete dfps structure from kernel virtual memory */
  96. memcpy_fromio(pll_res->dfps, area->addr, sizeof(struct dfps_info));
  97. mem_err:
  98. if (virt_add)
  99. unmap_kernel_range(virt_add, (unsigned long) size);
  100. if (area)
  101. vfree(area->addr);
  102. /* free the dfps memory here */
  103. dsi_pll_free_bootmem(offsets[0], offsets[1]);
  104. node_err:
  105. if (pnode)
  106. of_node_put(pnode);
  107. }
  108. int dsi_pll_init(struct platform_device *pdev, struct dsi_pll_resource **pll)
  109. {
  110. int rc = 0;
  111. const char *label;
  112. struct dsi_pll_resource *pll_res = NULL;
  113. if (!pdev->dev.of_node) {
  114. pr_err("Invalid DSI PHY node\n");
  115. return -ENOTSUPP;
  116. }
  117. pll_res = devm_kzalloc(&pdev->dev, sizeof(struct dsi_pll_resource),
  118. GFP_KERNEL);
  119. if (!pll_res)
  120. return -ENOMEM;
  121. *pll = pll_res;
  122. label = of_get_property(pdev->dev.of_node, "pll-label", NULL);
  123. if (!label) {
  124. DSI_PLL_ERR(pll_res, "DSI pll label not specified\n");
  125. return 0;
  126. }
  127. DSI_PLL_INFO(pll_res, "DSI pll label = %s\n", label);
  128. /**
  129. * Currently, Only supports 5nm PLL version. Will add
  130. * support for other versions as needed.
  131. */
  132. if (!strcmp(label, "dsi_pll_5nm"))
  133. pll_res->pll_revision = DSI_PLL_5NM;
  134. else
  135. return -ENOTSUPP;
  136. rc = of_property_read_u32(pdev->dev.of_node, "cell-index",
  137. &pll_res->index);
  138. if (rc) {
  139. DSI_PLL_ERR(pll_res, "Unable to get the cell-index rc=%d\n", rc);
  140. pll_res->index = 0;
  141. }
  142. pll_res->ssc_en = of_property_read_bool(pdev->dev.of_node,
  143. "qcom,dsi-pll-ssc-en");
  144. if (pll_res->ssc_en) {
  145. DSI_PLL_INFO(pll_res, "PLL SSC enabled\n");
  146. rc = of_property_read_u32(pdev->dev.of_node,
  147. "qcom,ssc-frequency-hz", &pll_res->ssc_freq);
  148. rc = of_property_read_u32(pdev->dev.of_node,
  149. "qcom,ssc-ppm", &pll_res->ssc_ppm);
  150. pll_res->ssc_center = false;
  151. label = of_get_property(pdev->dev.of_node,
  152. "qcom,dsi-pll-ssc-mode", NULL);
  153. if (label && !strcmp(label, "center-spread"))
  154. pll_res->ssc_center = true;
  155. }
  156. if (dsi_pll_get_ioresources(pdev, &pll_res->pll_base, "pll_base")) {
  157. DSI_PLL_ERR(pll_res, "Unable to remap pll base resources\n");
  158. return -ENOMEM;
  159. }
  160. pr_info("PLL base=%p\n", pll_res->pll_base);
  161. if (dsi_pll_get_ioresources(pdev, &pll_res->phy_base, "dsi_phy")) {
  162. DSI_PLL_ERR(pll_res, "Unable to remap pll phy base resources\n");
  163. return -ENOMEM;
  164. }
  165. if (dsi_pll_get_ioresources(pdev, &pll_res->dyn_pll_base,
  166. "dyn_refresh_base")) {
  167. DSI_PLL_ERR(pll_res, "Unable to remap dynamic pll base resources\n");
  168. return -ENOMEM;
  169. }
  170. if (dsi_pll_get_ioresources(pdev, &pll_res->gdsc_base, "gdsc_base")) {
  171. DSI_PLL_ERR(pll_res, "Unable to remap gdsc base resources\n");
  172. return -ENOMEM;
  173. }
  174. rc = dsi_pll_clock_register(pdev, pll_res);
  175. if (rc) {
  176. DSI_PLL_ERR(pll_res, "clock register failed rc=%d\n", rc);
  177. return -EINVAL;
  178. }
  179. if (!(pll_res->index))
  180. dsi_pll_parse_dfps(pdev, pll_res);
  181. return rc;
  182. }