fu540-prci.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2018-2021 SiFive, Inc.
  4. * Copyright (C) 2018-2019 Wesley Terpstra
  5. * Copyright (C) 2018-2019 Paul Walmsley
  6. * Copyright (C) 2020-2021 Zong Li
  7. *
  8. * The FU540 PRCI implements clock and reset control for the SiFive
  9. * FU540-C000 chip. This driver assumes that it has sole control
  10. * over all PRCI resources.
  11. *
  12. * This driver is based on the PRCI driver written by Wesley Terpstra:
  13. * https://github.com/riscv/riscv-linux/commit/999529edf517ed75b56659d456d221b2ee56bb60
  14. *
  15. * References:
  16. * - SiFive FU540-C000 manual v1p0, Chapter 7 "Clocking and Reset"
  17. */
  18. #ifndef __SIFIVE_CLK_FU540_PRCI_H
  19. #define __SIFIVE_CLK_FU540_PRCI_H
  20. #include <linux/module.h>
  21. #include <dt-bindings/clock/sifive-fu540-prci.h>
  22. #include "sifive-prci.h"
  23. /* PRCI integration data for each WRPLL instance */
  24. static struct __prci_wrpll_data sifive_fu540_prci_corepll_data = {
  25. .cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
  26. .cfg1_offs = PRCI_COREPLLCFG1_OFFSET,
  27. .enable_bypass = sifive_prci_coreclksel_use_hfclk,
  28. .disable_bypass = sifive_prci_coreclksel_use_corepll,
  29. };
  30. static struct __prci_wrpll_data sifive_fu540_prci_ddrpll_data = {
  31. .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
  32. .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
  33. };
  34. static struct __prci_wrpll_data sifive_fu540_prci_gemgxlpll_data = {
  35. .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
  36. .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
  37. };
  38. /* Linux clock framework integration */
  39. static const struct clk_ops sifive_fu540_prci_wrpll_clk_ops = {
  40. .set_rate = sifive_prci_wrpll_set_rate,
  41. .round_rate = sifive_prci_wrpll_round_rate,
  42. .recalc_rate = sifive_prci_wrpll_recalc_rate,
  43. .enable = sifive_prci_clock_enable,
  44. .disable = sifive_prci_clock_disable,
  45. .is_enabled = sifive_clk_is_enabled,
  46. };
  47. static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = {
  48. .recalc_rate = sifive_prci_wrpll_recalc_rate,
  49. };
  50. static const struct clk_ops sifive_fu540_prci_tlclksel_clk_ops = {
  51. .recalc_rate = sifive_prci_tlclksel_recalc_rate,
  52. };
  53. /* List of clock controls provided by the PRCI */
  54. static struct __prci_clock __prci_init_clocks_fu540[] = {
  55. [FU540_PRCI_CLK_COREPLL] = {
  56. .name = "corepll",
  57. .parent_name = "hfclk",
  58. .ops = &sifive_fu540_prci_wrpll_clk_ops,
  59. .pwd = &sifive_fu540_prci_corepll_data,
  60. },
  61. [FU540_PRCI_CLK_DDRPLL] = {
  62. .name = "ddrpll",
  63. .parent_name = "hfclk",
  64. .ops = &sifive_fu540_prci_wrpll_ro_clk_ops,
  65. .pwd = &sifive_fu540_prci_ddrpll_data,
  66. },
  67. [FU540_PRCI_CLK_GEMGXLPLL] = {
  68. .name = "gemgxlpll",
  69. .parent_name = "hfclk",
  70. .ops = &sifive_fu540_prci_wrpll_clk_ops,
  71. .pwd = &sifive_fu540_prci_gemgxlpll_data,
  72. },
  73. [FU540_PRCI_CLK_TLCLK] = {
  74. .name = "tlclk",
  75. .parent_name = "corepll",
  76. .ops = &sifive_fu540_prci_tlclksel_clk_ops,
  77. },
  78. };
  79. static const struct prci_clk_desc prci_clk_fu540 = {
  80. .clks = __prci_init_clocks_fu540,
  81. .num_clks = ARRAY_SIZE(__prci_init_clocks_fu540),
  82. };
  83. #endif /* __SIFIVE_CLK_FU540_PRCI_H */