apss-ipq6018.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/kernel.h>
  6. #include <linux/err.h>
  7. #include <linux/platform_device.h>
  8. #include <linux/clk-provider.h>
  9. #include <linux/regmap.h>
  10. #include <linux/module.h>
  11. #include <dt-bindings/clock/qcom,apss-ipq.h>
  12. #include "common.h"
  13. #include "clk-regmap.h"
  14. #include "clk-branch.h"
  15. #include "clk-alpha-pll.h"
  16. #include "clk-rcg.h"
  17. enum {
  18. P_XO,
  19. P_APSS_PLL_EARLY,
  20. };
  21. static const struct clk_parent_data parents_apcs_alias0_clk_src[] = {
  22. { .fw_name = "xo" },
  23. { .fw_name = "pll" },
  24. };
  25. static const struct parent_map parents_apcs_alias0_clk_src_map[] = {
  26. { P_XO, 0 },
  27. { P_APSS_PLL_EARLY, 5 },
  28. };
  29. static struct clk_rcg2 apcs_alias0_clk_src = {
  30. .cmd_rcgr = 0x0050,
  31. .hid_width = 5,
  32. .parent_map = parents_apcs_alias0_clk_src_map,
  33. .clkr.hw.init = &(struct clk_init_data){
  34. .name = "apcs_alias0_clk_src",
  35. .parent_data = parents_apcs_alias0_clk_src,
  36. .num_parents = ARRAY_SIZE(parents_apcs_alias0_clk_src),
  37. .ops = &clk_rcg2_mux_closest_ops,
  38. .flags = CLK_SET_RATE_PARENT,
  39. },
  40. };
  41. static struct clk_branch apcs_alias0_core_clk = {
  42. .halt_reg = 0x0058,
  43. .clkr = {
  44. .enable_reg = 0x0058,
  45. .enable_mask = BIT(0),
  46. .hw.init = &(struct clk_init_data){
  47. .name = "apcs_alias0_core_clk",
  48. .parent_hws = (const struct clk_hw *[]){
  49. &apcs_alias0_clk_src.clkr.hw },
  50. .num_parents = 1,
  51. .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
  52. .ops = &clk_branch2_ops,
  53. },
  54. },
  55. };
  56. static const struct regmap_config apss_ipq6018_regmap_config = {
  57. .reg_bits = 32,
  58. .reg_stride = 4,
  59. .val_bits = 32,
  60. .max_register = 0x1000,
  61. .fast_io = true,
  62. };
  63. static struct clk_regmap *apss_ipq6018_clks[] = {
  64. [APCS_ALIAS0_CLK_SRC] = &apcs_alias0_clk_src.clkr,
  65. [APCS_ALIAS0_CORE_CLK] = &apcs_alias0_core_clk.clkr,
  66. };
  67. static const struct qcom_cc_desc apss_ipq6018_desc = {
  68. .config = &apss_ipq6018_regmap_config,
  69. .clks = apss_ipq6018_clks,
  70. .num_clks = ARRAY_SIZE(apss_ipq6018_clks),
  71. };
  72. static int apss_ipq6018_probe(struct platform_device *pdev)
  73. {
  74. struct regmap *regmap;
  75. regmap = dev_get_regmap(pdev->dev.parent, NULL);
  76. if (!regmap)
  77. return -ENODEV;
  78. return qcom_cc_really_probe(pdev, &apss_ipq6018_desc, regmap);
  79. }
  80. static struct platform_driver apss_ipq6018_driver = {
  81. .probe = apss_ipq6018_probe,
  82. .driver = {
  83. .name = "qcom,apss-ipq6018-clk",
  84. },
  85. };
  86. module_platform_driver(apss_ipq6018_driver);
  87. MODULE_DESCRIPTION("QCOM APSS IPQ 6018 CLK Driver");
  88. MODULE_LICENSE("GPL v2");