clock-apq8016.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * Clock drivers for Qualcomm APQ8016
  3. *
  4. * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
  5. *
  6. * Based on Little Kernel driver, simplified
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. #include <common.h>
  11. #include <clk-uclass.h>
  12. #include <dm.h>
  13. #include <errno.h>
  14. #include <asm/io.h>
  15. #include <linux/bitops.h>
  16. /* GPLL0 clock control registers */
  17. #define GPLL0_STATUS 0x2101C
  18. #define GPLL0_STATUS_ACTIVE BIT(17)
  19. #define APCS_GPLL_ENA_VOTE 0x45000
  20. #define APCS_GPLL_ENA_VOTE_GPLL0 BIT(0)
  21. /* vote reg for blsp1 clock */
  22. #define APCS_CLOCK_BRANCH_ENA_VOTE 0x45004
  23. #define APCS_CLOCK_BRANCH_ENA_VOTE_BLSP1 BIT(10)
  24. /* SDC(n) clock control registers; n=1,2 */
  25. /* block control register */
  26. #define SDCC_BCR(n) ((n * 0x1000) + 0x41000)
  27. /* cmd */
  28. #define SDCC_CMD_RCGR(n) ((n * 0x1000) + 0x41004)
  29. /* cfg */
  30. #define SDCC_CFG_RCGR(n) ((n * 0x1000) + 0x41008)
  31. /* m */
  32. #define SDCC_M(n) ((n * 0x1000) + 0x4100C)
  33. /* n */
  34. #define SDCC_N(n) ((n * 0x1000) + 0x41010)
  35. /* d */
  36. #define SDCC_D(n) ((n * 0x1000) + 0x41014)
  37. /* branch control */
  38. #define SDCC_APPS_CBCR(n) ((n * 0x1000) + 0x41018)
  39. #define SDCC_AHB_CBCR(n) ((n * 0x1000) + 0x4101C)
  40. /* BLSP1 AHB clock (root clock for BLSP) */
  41. #define BLSP1_AHB_CBCR 0x1008
  42. /* Uart clock control registers */
  43. #define BLSP1_UART2_BCR 0x3028
  44. #define BLSP1_UART2_APPS_CBCR 0x302C
  45. #define BLSP1_UART2_APPS_CMD_RCGR 0x3034
  46. #define BLSP1_UART2_APPS_CFG_RCGR 0x3038
  47. #define BLSP1_UART2_APPS_M 0x303C
  48. #define BLSP1_UART2_APPS_N 0x3040
  49. #define BLSP1_UART2_APPS_D 0x3044
  50. /* CBCR register fields */
  51. #define CBCR_BRANCH_ENABLE_BIT BIT(0)
  52. #define CBCR_BRANCH_OFF_BIT BIT(31)
  53. struct msm_clk_priv {
  54. phys_addr_t base;
  55. };
  56. /* Enable clock controlled by CBC soft macro */
  57. static void clk_enable_cbc(phys_addr_t cbcr)
  58. {
  59. setbits_le32(cbcr, CBCR_BRANCH_ENABLE_BIT);
  60. while (readl(cbcr) & CBCR_BRANCH_OFF_BIT)
  61. ;
  62. }
  63. /* clock has 800MHz */
  64. static void clk_enable_gpll0(phys_addr_t base)
  65. {
  66. if (readl(base + GPLL0_STATUS) & GPLL0_STATUS_ACTIVE)
  67. return; /* clock already enabled */
  68. setbits_le32(base + APCS_GPLL_ENA_VOTE, APCS_GPLL_ENA_VOTE_GPLL0);
  69. while ((readl(base + GPLL0_STATUS) & GPLL0_STATUS_ACTIVE) == 0)
  70. ;
  71. }
  72. #define APPS_CMD_RGCR_UPDATE BIT(0)
  73. /* Update clock command via CMD_RGCR */
  74. static void clk_bcr_update(phys_addr_t apps_cmd_rgcr)
  75. {
  76. setbits_le32(apps_cmd_rgcr, APPS_CMD_RGCR_UPDATE);
  77. /* Wait for frequency to be updated. */
  78. while (readl(apps_cmd_rgcr) & APPS_CMD_RGCR_UPDATE)
  79. ;
  80. }
  81. struct bcr_regs {
  82. uintptr_t cfg_rcgr;
  83. uintptr_t cmd_rcgr;
  84. uintptr_t M;
  85. uintptr_t N;
  86. uintptr_t D;
  87. };
  88. /* RCGR_CFG register fields */
  89. #define CFG_MODE_DUAL_EDGE (0x2 << 12) /* Counter mode */
  90. /* sources */
  91. #define CFG_CLK_SRC_CXO (0 << 8)
  92. #define CFG_CLK_SRC_GPLL0 (1 << 8)
  93. #define CFG_CLK_SRC_MASK (7 << 8)
  94. /* Mask for supported fields */
  95. #define CFG_MASK 0x3FFF
  96. #define CFG_DIVIDER_MASK 0x1F
  97. /* root set rate for clocks with half integer and MND divider */
  98. static void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
  99. int div, int m, int n, int source)
  100. {
  101. uint32_t cfg;
  102. /* M value for MND divider. */
  103. uint32_t m_val = m;
  104. /* NOT(N-M) value for MND divider. */
  105. uint32_t n_val = ~((n)-(m)) * !!(n);
  106. /* NOT 2D value for MND divider. */
  107. uint32_t d_val = ~(n);
  108. /* Program MND values */
  109. writel(m_val, base + regs->M);
  110. writel(n_val, base + regs->N);
  111. writel(d_val, base + regs->D);
  112. /* setup src select and divider */
  113. cfg = readl(base + regs->cfg_rcgr);
  114. cfg &= ~CFG_MASK;
  115. cfg |= source & CFG_CLK_SRC_MASK; /* Select clock source */
  116. /* Set the divider; HW permits fraction dividers (+0.5), but
  117. for simplicity, we will support integers only */
  118. if (div)
  119. cfg |= (2 * div - 1) & CFG_DIVIDER_MASK;
  120. if (n_val)
  121. cfg |= CFG_MODE_DUAL_EDGE;
  122. writel(cfg, base + regs->cfg_rcgr); /* Write new clock configuration */
  123. /* Inform h/w to start using the new config. */
  124. clk_bcr_update(base + regs->cmd_rcgr);
  125. }
  126. static const struct bcr_regs sdc_regs[] = {
  127. {
  128. .cfg_rcgr = SDCC_CFG_RCGR(1),
  129. .cmd_rcgr = SDCC_CMD_RCGR(1),
  130. .M = SDCC_M(1),
  131. .N = SDCC_N(1),
  132. .D = SDCC_D(1),
  133. },
  134. {
  135. .cfg_rcgr = SDCC_CFG_RCGR(2),
  136. .cmd_rcgr = SDCC_CMD_RCGR(2),
  137. .M = SDCC_M(2),
  138. .N = SDCC_N(2),
  139. .D = SDCC_D(2),
  140. }
  141. };
  142. /* Init clock for SDHCI controller */
  143. static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
  144. {
  145. int div = 8; /* 100MHz default */
  146. if (rate == 200000000)
  147. div = 4;
  148. clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot));
  149. /* 800Mhz/div, gpll0 */
  150. clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
  151. CFG_CLK_SRC_GPLL0);
  152. clk_enable_gpll0(priv->base);
  153. clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
  154. return rate;
  155. }
  156. static const struct bcr_regs uart2_regs = {
  157. .cfg_rcgr = BLSP1_UART2_APPS_CFG_RCGR,
  158. .cmd_rcgr = BLSP1_UART2_APPS_CMD_RCGR,
  159. .M = BLSP1_UART2_APPS_M,
  160. .N = BLSP1_UART2_APPS_N,
  161. .D = BLSP1_UART2_APPS_D,
  162. };
  163. /* Init UART clock, 115200 */
  164. static int clk_init_uart(struct msm_clk_priv *priv)
  165. {
  166. /* Enable iface clk */
  167. clk_enable_cbc(priv->base + BLSP1_AHB_CBCR);
  168. /* 7372800 uart block clock @ GPLL0 */
  169. clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625,
  170. CFG_CLK_SRC_GPLL0);
  171. clk_enable_gpll0(priv->base);
  172. /* Enable core clk */
  173. clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
  174. return 0;
  175. }
  176. ulong msm_set_rate(struct clk *clk, ulong rate)
  177. {
  178. struct msm_clk_priv *priv = dev_get_priv(clk->dev);
  179. switch (clk->id) {
  180. case 0: /* SDC1 */
  181. return clk_init_sdc(priv, 0, rate);
  182. break;
  183. case 1: /* SDC2 */
  184. return clk_init_sdc(priv, 1, rate);
  185. break;
  186. case 4: /* UART2 */
  187. return clk_init_uart(priv);
  188. break;
  189. default:
  190. return 0;
  191. }
  192. }
  193. static int msm_clk_probe(struct udevice *dev)
  194. {
  195. struct msm_clk_priv *priv = dev_get_priv(dev);
  196. priv->base = dev_get_addr(dev);
  197. if (priv->base == FDT_ADDR_T_NONE)
  198. return -EINVAL;
  199. return 0;
  200. }
  201. static struct clk_ops msm_clk_ops = {
  202. .set_rate = msm_set_rate,
  203. };
  204. static const struct udevice_id msm_clk_ids[] = {
  205. { .compatible = "qcom,gcc-msm8916" },
  206. { .compatible = "qcom,gcc-apq8016" },
  207. { }
  208. };
  209. U_BOOT_DRIVER(clk_msm) = {
  210. .name = "clk_msm",
  211. .id = UCLASS_CLK,
  212. .of_match = msm_clk_ids,
  213. .ops = &msm_clk_ops,
  214. .priv_auto_alloc_size = sizeof(struct msm_clk_priv),
  215. .probe = msm_clk_probe,
  216. };