axg-aoclk.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Amlogic Meson-AXG Clock Controller Driver
  4. *
  5. * Copyright (c) 2016 Baylibre SAS.
  6. * Author: Michael Turquette <mturquette@baylibre.com>
  7. *
  8. * Copyright (c) 2018 Amlogic, inc.
  9. * Author: Qiufang Dai <qiufang.dai@amlogic.com>
  10. */
  11. #include <linux/clk-provider.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/reset-controller.h>
  14. #include <linux/mfd/syscon.h>
  15. #include "clk-regmap.h"
  16. #include "meson-aoclk.h"
  17. #include "axg-aoclk.h"
  18. #define AXG_AO_GATE(_name, _bit) \
  19. static struct clk_regmap axg_aoclk_##_name = { \
  20. .data = &(struct clk_regmap_gate_data) { \
  21. .offset = (AO_RTI_GEN_CNTL_REG0), \
  22. .bit_idx = (_bit), \
  23. }, \
  24. .hw.init = &(struct clk_init_data) { \
  25. .name = "axg_ao_" #_name, \
  26. .ops = &clk_regmap_gate_ops, \
  27. .parent_names = (const char *[]){ "clk81" }, \
  28. .num_parents = 1, \
  29. .flags = CLK_IGNORE_UNUSED, \
  30. }, \
  31. }
  32. AXG_AO_GATE(remote, 0);
  33. AXG_AO_GATE(i2c_master, 1);
  34. AXG_AO_GATE(i2c_slave, 2);
  35. AXG_AO_GATE(uart1, 3);
  36. AXG_AO_GATE(uart2, 5);
  37. AXG_AO_GATE(ir_blaster, 6);
  38. AXG_AO_GATE(saradc, 7);
  39. static struct clk_regmap axg_aoclk_clk81 = {
  40. .data = &(struct clk_regmap_mux_data) {
  41. .offset = AO_RTI_PWR_CNTL_REG0,
  42. .mask = 0x1,
  43. .shift = 8,
  44. },
  45. .hw.init = &(struct clk_init_data){
  46. .name = "axg_ao_clk81",
  47. .ops = &clk_regmap_mux_ro_ops,
  48. .parent_names = (const char *[]){ "clk81", "ao_alt_xtal"},
  49. .num_parents = 2,
  50. },
  51. };
  52. static struct clk_regmap axg_aoclk_saradc_mux = {
  53. .data = &(struct clk_regmap_mux_data) {
  54. .offset = AO_SAR_CLK,
  55. .mask = 0x3,
  56. .shift = 9,
  57. },
  58. .hw.init = &(struct clk_init_data){
  59. .name = "axg_ao_saradc_mux",
  60. .ops = &clk_regmap_mux_ops,
  61. .parent_names = (const char *[]){ "xtal", "axg_ao_clk81" },
  62. .num_parents = 2,
  63. },
  64. };
  65. static struct clk_regmap axg_aoclk_saradc_div = {
  66. .data = &(struct clk_regmap_div_data) {
  67. .offset = AO_SAR_CLK,
  68. .shift = 0,
  69. .width = 8,
  70. },
  71. .hw.init = &(struct clk_init_data){
  72. .name = "axg_ao_saradc_div",
  73. .ops = &clk_regmap_divider_ops,
  74. .parent_names = (const char *[]){ "axg_ao_saradc_mux" },
  75. .num_parents = 1,
  76. .flags = CLK_SET_RATE_PARENT,
  77. },
  78. };
  79. static struct clk_regmap axg_aoclk_saradc_gate = {
  80. .data = &(struct clk_regmap_gate_data) {
  81. .offset = AO_SAR_CLK,
  82. .bit_idx = 8,
  83. },
  84. .hw.init = &(struct clk_init_data){
  85. .name = "axg_ao_saradc_gate",
  86. .ops = &clk_regmap_gate_ops,
  87. .parent_names = (const char *[]){ "axg_ao_saradc_div" },
  88. .num_parents = 1,
  89. .flags = CLK_SET_RATE_PARENT,
  90. },
  91. };
  92. static const unsigned int axg_aoclk_reset[] = {
  93. [RESET_AO_REMOTE] = 16,
  94. [RESET_AO_I2C_MASTER] = 18,
  95. [RESET_AO_I2C_SLAVE] = 19,
  96. [RESET_AO_UART1] = 17,
  97. [RESET_AO_UART2] = 22,
  98. [RESET_AO_IR_BLASTER] = 23,
  99. };
  100. static struct clk_regmap *axg_aoclk_regmap[] = {
  101. [CLKID_AO_REMOTE] = &axg_aoclk_remote,
  102. [CLKID_AO_I2C_MASTER] = &axg_aoclk_i2c_master,
  103. [CLKID_AO_I2C_SLAVE] = &axg_aoclk_i2c_slave,
  104. [CLKID_AO_UART1] = &axg_aoclk_uart1,
  105. [CLKID_AO_UART2] = &axg_aoclk_uart2,
  106. [CLKID_AO_IR_BLASTER] = &axg_aoclk_ir_blaster,
  107. [CLKID_AO_SAR_ADC] = &axg_aoclk_saradc,
  108. [CLKID_AO_CLK81] = &axg_aoclk_clk81,
  109. [CLKID_AO_SAR_ADC_SEL] = &axg_aoclk_saradc_mux,
  110. [CLKID_AO_SAR_ADC_DIV] = &axg_aoclk_saradc_div,
  111. [CLKID_AO_SAR_ADC_CLK] = &axg_aoclk_saradc_gate,
  112. };
  113. static const struct clk_hw_onecell_data axg_aoclk_onecell_data = {
  114. .hws = {
  115. [CLKID_AO_REMOTE] = &axg_aoclk_remote.hw,
  116. [CLKID_AO_I2C_MASTER] = &axg_aoclk_i2c_master.hw,
  117. [CLKID_AO_I2C_SLAVE] = &axg_aoclk_i2c_slave.hw,
  118. [CLKID_AO_UART1] = &axg_aoclk_uart1.hw,
  119. [CLKID_AO_UART2] = &axg_aoclk_uart2.hw,
  120. [CLKID_AO_IR_BLASTER] = &axg_aoclk_ir_blaster.hw,
  121. [CLKID_AO_SAR_ADC] = &axg_aoclk_saradc.hw,
  122. [CLKID_AO_CLK81] = &axg_aoclk_clk81.hw,
  123. [CLKID_AO_SAR_ADC_SEL] = &axg_aoclk_saradc_mux.hw,
  124. [CLKID_AO_SAR_ADC_DIV] = &axg_aoclk_saradc_div.hw,
  125. [CLKID_AO_SAR_ADC_CLK] = &axg_aoclk_saradc_gate.hw,
  126. },
  127. .num = NR_CLKS,
  128. };
  129. static const struct meson_aoclk_data axg_aoclkc_data = {
  130. .reset_reg = AO_RTI_GEN_CNTL_REG0,
  131. .num_reset = ARRAY_SIZE(axg_aoclk_reset),
  132. .reset = axg_aoclk_reset,
  133. .num_clks = ARRAY_SIZE(axg_aoclk_regmap),
  134. .clks = axg_aoclk_regmap,
  135. .hw_data = &axg_aoclk_onecell_data,
  136. };
  137. static const struct of_device_id axg_aoclkc_match_table[] = {
  138. {
  139. .compatible = "amlogic,meson-axg-aoclkc",
  140. .data = &axg_aoclkc_data,
  141. },
  142. { }
  143. };
  144. static struct platform_driver axg_aoclkc_driver = {
  145. .probe = meson_aoclkc_probe,
  146. .driver = {
  147. .name = "axg-aoclkc",
  148. .of_match_table = axg_aoclkc_match_table,
  149. },
  150. };
  151. builtin_platform_driver(axg_aoclkc_driver);