turingcc-qcs404.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2019, Linaro Ltd.
  4. */
  5. #include <linux/bitops.h>
  6. #include <linux/clk-provider.h>
  7. #include <linux/err.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/module.h>
  10. #include <linux/of_address.h>
  11. #include <linux/pm_clock.h>
  12. #include <linux/pm_runtime.h>
  13. #include <linux/regmap.h>
  14. #include <dt-bindings/clock/qcom,turingcc-qcs404.h>
  15. #include "clk-regmap.h"
  16. #include "clk-branch.h"
  17. #include "common.h"
  18. #include "reset.h"
  19. static struct clk_branch turing_wrapper_aon_cbcr = {
  20. .halt_reg = 0x5098,
  21. .halt_check = BRANCH_HALT,
  22. .clkr = {
  23. .enable_reg = 0x5098,
  24. .enable_mask = BIT(0),
  25. .hw.init = &(struct clk_init_data) {
  26. .name = "turing_wrapper_aon_clk",
  27. .ops = &clk_branch2_aon_ops,
  28. },
  29. },
  30. };
  31. static struct clk_branch turing_q6ss_ahbm_aon_cbcr = {
  32. .halt_reg = 0x9000,
  33. .halt_check = BRANCH_HALT,
  34. .clkr = {
  35. .enable_reg = 0x9000,
  36. .enable_mask = BIT(0),
  37. .hw.init = &(struct clk_init_data) {
  38. .name = "turing_q6ss_ahbm_aon_cbcr",
  39. .ops = &clk_branch2_ops,
  40. },
  41. },
  42. };
  43. static struct clk_branch turing_q6ss_q6_axim_clk = {
  44. .halt_reg = 0xb000,
  45. .halt_check = BRANCH_HALT,
  46. .clkr = {
  47. .enable_reg = 0xb000,
  48. .enable_mask = BIT(0),
  49. .hw.init = &(struct clk_init_data) {
  50. .name = "turing_q6ss_q6_axim_clk",
  51. .ops = &clk_branch2_aon_ops,
  52. },
  53. },
  54. };
  55. static struct clk_branch turing_q6ss_ahbs_aon_cbcr = {
  56. .halt_reg = 0x10000,
  57. .halt_check = BRANCH_HALT,
  58. .clkr = {
  59. .enable_reg = 0x10000,
  60. .enable_mask = BIT(0),
  61. .hw.init = &(struct clk_init_data) {
  62. .name = "turing_q6ss_ahbs_aon_clk",
  63. .ops = &clk_branch2_aon_ops,
  64. },
  65. },
  66. };
  67. static struct clk_branch turing_wrapper_qos_ahbs_aon_cbcr = {
  68. .halt_reg = 0x11014,
  69. .halt_check = BRANCH_HALT,
  70. .clkr = {
  71. .enable_reg = 0x11014,
  72. .enable_mask = BIT(0),
  73. .hw.init = &(struct clk_init_data) {
  74. .name = "turing_wrapper_qos_ahbs_aon_clk",
  75. .ops = &clk_branch2_aon_ops,
  76. },
  77. },
  78. };
  79. static struct clk_regmap *turingcc_clocks[] = {
  80. [TURING_WRAPPER_AON_CLK] = &turing_wrapper_aon_cbcr.clkr,
  81. [TURING_Q6SS_AHBM_AON_CLK] = &turing_q6ss_ahbm_aon_cbcr.clkr,
  82. [TURING_Q6SS_Q6_AXIM_CLK] = &turing_q6ss_q6_axim_clk.clkr,
  83. [TURING_Q6SS_AHBS_AON_CLK] = &turing_q6ss_ahbs_aon_cbcr.clkr,
  84. [TURING_WRAPPER_QOS_AHBS_AON_CLK] = &turing_wrapper_qos_ahbs_aon_cbcr.clkr,
  85. };
  86. static const struct regmap_config turingcc_regmap_config = {
  87. .reg_bits = 32,
  88. .reg_stride = 4,
  89. .val_bits = 32,
  90. .max_register = 0x23004,
  91. .fast_io = true,
  92. };
  93. static const struct qcom_cc_desc turingcc_desc = {
  94. .config = &turingcc_regmap_config,
  95. .clks = turingcc_clocks,
  96. .num_clks = ARRAY_SIZE(turingcc_clocks),
  97. };
  98. static int turingcc_probe(struct platform_device *pdev)
  99. {
  100. int ret;
  101. ret = devm_pm_runtime_enable(&pdev->dev);
  102. if (ret)
  103. return ret;
  104. ret = devm_pm_clk_create(&pdev->dev);
  105. if (ret)
  106. return ret;
  107. ret = pm_clk_add(&pdev->dev, NULL);
  108. if (ret < 0) {
  109. dev_err(&pdev->dev, "failed to acquire iface clock\n");
  110. return ret;
  111. }
  112. ret = pm_runtime_resume_and_get(&pdev->dev);
  113. if (ret)
  114. return ret;
  115. ret = qcom_cc_probe(pdev, &turingcc_desc);
  116. if (ret < 0)
  117. goto err_put_rpm;
  118. pm_runtime_put(&pdev->dev);
  119. return 0;
  120. err_put_rpm:
  121. pm_runtime_put_sync(&pdev->dev);
  122. return ret;
  123. }
  124. static const struct dev_pm_ops turingcc_pm_ops = {
  125. SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
  126. };
  127. static const struct of_device_id turingcc_match_table[] = {
  128. { .compatible = "qcom,qcs404-turingcc" },
  129. { }
  130. };
  131. MODULE_DEVICE_TABLE(of, turingcc_match_table);
  132. static struct platform_driver turingcc_driver = {
  133. .probe = turingcc_probe,
  134. .driver = {
  135. .name = "qcs404-turingcc",
  136. .of_match_table = turingcc_match_table,
  137. .pm = &turingcc_pm_ops,
  138. },
  139. };
  140. module_platform_driver(turingcc_driver);
  141. MODULE_DESCRIPTION("Qualcomm QCS404 Turing Clock Controller");
  142. MODULE_LICENSE("GPL v2");