clock_sun9i.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * sun9i specific clock code
  4. *
  5. * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
  6. *
  7. * (C) Copyright 2016 Theobroma Systems Design und Consulting GmbH
  8. * Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
  9. */
  10. #include <common.h>
  11. #include <asm/io.h>
  12. #include <asm/arch/clock.h>
  13. #include <asm/arch/prcm.h>
  14. #include <asm/arch/sys_proto.h>
  15. #ifdef CONFIG_SPL_BUILD
  16. void clock_init_safe(void)
  17. {
  18. struct sunxi_ccm_reg * const ccm =
  19. (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  20. /* Set up PLL12 (peripheral 1) */
  21. clock_set_pll12(1200000000);
  22. /* Set up PLL1 (cluster 0) and PLL2 (cluster 1) */
  23. clock_set_pll1(408000000);
  24. clock_set_pll2(408000000);
  25. /* Set up PLL4 (peripheral 0) */
  26. clock_set_pll4(960000000);
  27. /* Set up dividers for AXI0 and APB0 on cluster 0: PLL1 / 2 = 204MHz */
  28. writel(C0_CFG_AXI0_CLK_DIV_RATIO(2) |
  29. C0_CFG_APB0_CLK_DIV_RATIO(2), &ccm->c0_cfg);
  30. /* AHB0: 120 MHz (PLL_PERIPH0 / 8) */
  31. writel(AHBx_SRC_PLL_PERIPH0 | AHBx_CLK_DIV_RATIO(8),
  32. &ccm->ahb0_cfg);
  33. /* AHB1: 240 MHz (PLL_PERIPH0 / 4) */
  34. writel(AHBx_SRC_PLL_PERIPH0 | AHBx_CLK_DIV_RATIO(4),
  35. &ccm->ahb1_cfg);
  36. /* AHB2: 120 MHz (PLL_PERIPH0 / 8) */
  37. writel(AHBx_SRC_PLL_PERIPH0 | AHBx_CLK_DIV_RATIO(8),
  38. &ccm->ahb2_cfg);
  39. /* APB0: 120 MHz (PLL_PERIPH0 / 8) */
  40. writel(APB0_SRC_PLL_PERIPH0 | APB0_CLK_DIV_RATIO(8),
  41. &ccm->apb0_cfg);
  42. /* GTBUS: 400MHz (PERIPH0 div 3) */
  43. writel(GTBUS_SRC_PLL_PERIPH1 | GTBUS_CLK_DIV_RATIO(3),
  44. &ccm->gtbus_cfg);
  45. /* CCI400: 480MHz (PERIPH1 div 2) */
  46. writel(CCI400_SRC_PLL_PERIPH0 | CCI400_CLK_DIV_RATIO(2),
  47. &ccm->cci400_cfg);
  48. /* Deassert DMA reset and open clock gating for DMA */
  49. setbits_le32(&ccm->ahb_reset1_cfg, (1 << 24));
  50. setbits_le32(&ccm->apb1_gate, (1 << 24));
  51. /* set enable-bit in TSTAMP_CTRL_REG */
  52. writel(1, 0x01720000);
  53. }
  54. #endif
  55. void clock_init_uart(void)
  56. {
  57. struct sunxi_ccm_reg *const ccm =
  58. (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  59. /* open the clock for uart */
  60. setbits_le32(&ccm->apb1_gate,
  61. CLK_GATE_OPEN << (APB1_GATE_UART_SHIFT +
  62. CONFIG_CONS_INDEX - 1));
  63. /* deassert uart reset */
  64. setbits_le32(&ccm->apb1_reset_cfg,
  65. 1 << (APB1_RESET_UART_SHIFT +
  66. CONFIG_CONS_INDEX - 1));
  67. }
  68. #ifdef CONFIG_SPL_BUILD
  69. void clock_set_pll1(unsigned int clk)
  70. {
  71. struct sunxi_ccm_reg * const ccm =
  72. (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  73. const int p = 0;
  74. /* Switch cluster 0 to 24MHz clock while changing PLL1 */
  75. clrsetbits_le32(&ccm->cpu_clk_source, C0_CPUX_CLK_SRC_MASK,
  76. C0_CPUX_CLK_SRC_OSC24M);
  77. writel(CCM_PLL1_CTRL_EN | CCM_PLL1_CTRL_P(p) |
  78. CCM_PLL1_CLOCK_TIME_2 |
  79. CCM_PLL1_CTRL_N(clk / 24000000),
  80. &ccm->pll1_c0_cfg);
  81. /*
  82. * Don't bother with the stable-time registers, as it doesn't
  83. * wait until the PLL is stable. Note, that even Allwinner
  84. * just uses a delay loop (or rather the AVS timer) for this
  85. * instead of the PLL_STABLE_STATUS register.
  86. */
  87. sdelay(2000);
  88. /* Switch cluster 0 back to PLL1 */
  89. clrsetbits_le32(&ccm->cpu_clk_source, C0_CPUX_CLK_SRC_MASK,
  90. C0_CPUX_CLK_SRC_PLL1);
  91. }
  92. void clock_set_pll2(unsigned int clk)
  93. {
  94. struct sunxi_ccm_reg * const ccm =
  95. (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  96. const int p = 0;
  97. /* Switch cluster 1 to 24MHz clock while changing PLL2 */
  98. clrsetbits_le32(&ccm->cpu_clk_source, C1_CPUX_CLK_SRC_MASK,
  99. C1_CPUX_CLK_SRC_OSC24M);
  100. writel(CCM_PLL2_CTRL_EN | CCM_PLL2_CTRL_P(p) |
  101. CCM_PLL2_CLOCK_TIME_2 | CCM_PLL2_CTRL_N(clk / 24000000),
  102. &ccm->pll2_c1_cfg);
  103. sdelay(2000);
  104. /* Switch cluster 1 back to PLL2 */
  105. clrsetbits_le32(&ccm->cpu_clk_source, C1_CPUX_CLK_SRC_MASK,
  106. C1_CPUX_CLK_SRC_PLL2);
  107. }
  108. void clock_set_pll6(unsigned int clk)
  109. {
  110. struct sunxi_ccm_reg * const ccm =
  111. (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  112. const int p = 0;
  113. writel(CCM_PLL6_CTRL_EN | CCM_PLL6_CFG_UPDATE | CCM_PLL6_CTRL_P(p)
  114. | CCM_PLL6_CTRL_N(clk / 24000000),
  115. &ccm->pll6_ddr_cfg);
  116. do { } while (!(readl(&ccm->pll_stable_status) & PLL_DDR_STATUS));
  117. sdelay(2000);
  118. }
  119. void clock_set_pll12(unsigned int clk)
  120. {
  121. struct sunxi_ccm_reg * const ccm =
  122. (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  123. if (readl(&ccm->pll12_periph1_cfg) & CCM_PLL12_CTRL_EN)
  124. return;
  125. writel(CCM_PLL12_CTRL_EN | CCM_PLL12_CTRL_N(clk / 24000000),
  126. &ccm->pll12_periph1_cfg);
  127. sdelay(2000);
  128. }
  129. void clock_set_pll4(unsigned int clk)
  130. {
  131. struct sunxi_ccm_reg * const ccm =
  132. (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  133. writel(CCM_PLL4_CTRL_EN | CCM_PLL4_CTRL_N(clk / 24000000),
  134. &ccm->pll4_periph0_cfg);
  135. sdelay(2000);
  136. }
  137. #endif
  138. int clock_twi_onoff(int port, int state)
  139. {
  140. struct sunxi_ccm_reg *const ccm =
  141. (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  142. if (port > 4)
  143. return -1;
  144. /* set the apb reset and clock gate for twi */
  145. if (state) {
  146. setbits_le32(&ccm->apb1_gate,
  147. CLK_GATE_OPEN << (APB1_GATE_TWI_SHIFT + port));
  148. setbits_le32(&ccm->apb1_reset_cfg,
  149. 1 << (APB1_RESET_TWI_SHIFT + port));
  150. } else {
  151. clrbits_le32(&ccm->apb1_reset_cfg,
  152. 1 << (APB1_RESET_TWI_SHIFT + port));
  153. clrbits_le32(&ccm->apb1_gate,
  154. CLK_GATE_OPEN << (APB1_GATE_TWI_SHIFT + port));
  155. }
  156. return 0;
  157. }
  158. unsigned int clock_get_pll4_periph0(void)
  159. {
  160. struct sunxi_ccm_reg *const ccm =
  161. (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  162. uint32_t rval = readl(&ccm->pll4_periph0_cfg);
  163. int n = ((rval & CCM_PLL4_CTRL_N_MASK) >> CCM_PLL4_CTRL_N_SHIFT);
  164. int p = ((rval & CCM_PLL4_CTRL_P_MASK) >> CCM_PLL4_CTRL_P_SHIFT);
  165. int m = ((rval & CCM_PLL4_CTRL_M_MASK) >> CCM_PLL4_CTRL_M_SHIFT) + 1;
  166. const int k = 1;
  167. return ((24000000 * n * k) >> p) / m;
  168. }