tcsrcc-sm8650.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
  5. * Copyright (c) 2023, Linaro Limited
  6. */
  7. #include <linux/clk-provider.h>
  8. #include <linux/mod_devicetable.h>
  9. #include <linux/module.h>
  10. #include <linux/platform_device.h>
  11. #include <linux/regmap.h>
  12. #include <dt-bindings/clock/qcom,sm8650-tcsr.h>
  13. #include "clk-branch.h"
  14. #include "clk-regmap.h"
  15. #include "common.h"
  16. #include "reset.h"
  17. enum {
  18. DT_BI_TCXO_PAD,
  19. };
  20. static struct clk_branch tcsr_pcie_0_clkref_en = {
  21. .halt_reg = 0x31100,
  22. .halt_check = BRANCH_HALT_DELAY,
  23. .clkr = {
  24. .enable_reg = 0x31100,
  25. .enable_mask = BIT(0),
  26. .hw.init = &(struct clk_init_data){
  27. .name = "tcsr_pcie_0_clkref_en",
  28. .parent_data = &(const struct clk_parent_data){
  29. .index = DT_BI_TCXO_PAD,
  30. },
  31. .num_parents = 1,
  32. .ops = &clk_branch2_ops,
  33. },
  34. },
  35. };
  36. static struct clk_branch tcsr_pcie_1_clkref_en = {
  37. .halt_reg = 0x31114,
  38. .halt_check = BRANCH_HALT_DELAY,
  39. .clkr = {
  40. .enable_reg = 0x31114,
  41. .enable_mask = BIT(0),
  42. .hw.init = &(struct clk_init_data){
  43. .name = "tcsr_pcie_1_clkref_en",
  44. .parent_data = &(const struct clk_parent_data){
  45. .index = DT_BI_TCXO_PAD,
  46. },
  47. .num_parents = 1,
  48. .ops = &clk_branch2_ops,
  49. },
  50. },
  51. };
  52. static struct clk_branch tcsr_ufs_clkref_en = {
  53. .halt_reg = 0x31110,
  54. .halt_check = BRANCH_HALT_DELAY,
  55. .clkr = {
  56. .enable_reg = 0x31110,
  57. .enable_mask = BIT(0),
  58. .hw.init = &(struct clk_init_data){
  59. .name = "tcsr_ufs_clkref_en",
  60. .parent_data = &(const struct clk_parent_data){
  61. .index = DT_BI_TCXO_PAD,
  62. },
  63. .num_parents = 1,
  64. .ops = &clk_branch2_ops,
  65. },
  66. },
  67. };
  68. static struct clk_branch tcsr_ufs_pad_clkref_en = {
  69. .halt_reg = 0x31104,
  70. .halt_check = BRANCH_HALT_DELAY,
  71. .clkr = {
  72. .enable_reg = 0x31104,
  73. .enable_mask = BIT(0),
  74. .hw.init = &(struct clk_init_data){
  75. .name = "tcsr_ufs_pad_clkref_en",
  76. .parent_data = &(const struct clk_parent_data){
  77. .index = DT_BI_TCXO_PAD,
  78. },
  79. .num_parents = 1,
  80. .ops = &clk_branch2_ops,
  81. },
  82. },
  83. };
  84. static struct clk_branch tcsr_usb2_clkref_en = {
  85. .halt_reg = 0x31118,
  86. .halt_check = BRANCH_HALT_DELAY,
  87. .clkr = {
  88. .enable_reg = 0x31118,
  89. .enable_mask = BIT(0),
  90. .hw.init = &(struct clk_init_data){
  91. .name = "tcsr_usb2_clkref_en",
  92. .parent_data = &(const struct clk_parent_data){
  93. .index = DT_BI_TCXO_PAD,
  94. },
  95. .num_parents = 1,
  96. .ops = &clk_branch2_ops,
  97. },
  98. },
  99. };
  100. static struct clk_branch tcsr_usb3_clkref_en = {
  101. .halt_reg = 0x31108,
  102. .halt_check = BRANCH_HALT_DELAY,
  103. .clkr = {
  104. .enable_reg = 0x31108,
  105. .enable_mask = BIT(0),
  106. .hw.init = &(struct clk_init_data){
  107. .name = "tcsr_usb3_clkref_en",
  108. .parent_data = &(const struct clk_parent_data){
  109. .index = DT_BI_TCXO_PAD,
  110. },
  111. .num_parents = 1,
  112. .ops = &clk_branch2_ops,
  113. },
  114. },
  115. };
  116. static struct clk_regmap *tcsr_cc_sm8650_clocks[] = {
  117. [TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr,
  118. [TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr,
  119. [TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr,
  120. [TCSR_UFS_PAD_CLKREF_EN] = &tcsr_ufs_pad_clkref_en.clkr,
  121. [TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr,
  122. [TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr,
  123. };
  124. static const struct regmap_config tcsr_cc_sm8650_regmap_config = {
  125. .reg_bits = 32,
  126. .reg_stride = 4,
  127. .val_bits = 32,
  128. .max_register = 0x3b000,
  129. .fast_io = true,
  130. };
  131. static const struct qcom_cc_desc tcsr_cc_sm8650_desc = {
  132. .config = &tcsr_cc_sm8650_regmap_config,
  133. .clks = tcsr_cc_sm8650_clocks,
  134. .num_clks = ARRAY_SIZE(tcsr_cc_sm8650_clocks),
  135. };
  136. static const struct of_device_id tcsr_cc_sm8650_match_table[] = {
  137. { .compatible = "qcom,sm8650-tcsr" },
  138. { }
  139. };
  140. MODULE_DEVICE_TABLE(of, tcsr_cc_sm8650_match_table);
  141. static int tcsr_cc_sm8650_probe(struct platform_device *pdev)
  142. {
  143. return qcom_cc_probe(pdev, &tcsr_cc_sm8650_desc);
  144. }
  145. static struct platform_driver tcsr_cc_sm8650_driver = {
  146. .probe = tcsr_cc_sm8650_probe,
  147. .driver = {
  148. .name = "tcsr_cc-sm8650",
  149. .of_match_table = tcsr_cc_sm8650_match_table,
  150. },
  151. };
  152. static int __init tcsr_cc_sm8650_init(void)
  153. {
  154. return platform_driver_register(&tcsr_cc_sm8650_driver);
  155. }
  156. subsys_initcall(tcsr_cc_sm8650_init);
  157. static void __exit tcsr_cc_sm8650_exit(void)
  158. {
  159. platform_driver_unregister(&tcsr_cc_sm8650_driver);
  160. }
  161. module_exit(tcsr_cc_sm8650_exit);
  162. MODULE_DESCRIPTION("QTI TCSRCC SM8650 Driver");
  163. MODULE_LICENSE("GPL");