clock-apq8016.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // SPDX-License-Identifier: BSD-3-Clause
  2. /*
  3. * Clock drivers for Qualcomm APQ8016
  4. *
  5. * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
  6. *
  7. * Based on Little Kernel driver, simplified
  8. */
  9. #include <common.h>
  10. #include <clk-uclass.h>
  11. #include <dm.h>
  12. #include <errno.h>
  13. #include <asm/io.h>
  14. #include <linux/bitops.h>
  15. #include "clock-snapdragon.h"
  16. /* GPLL0 clock control registers */
  17. #define GPLL0_STATUS_ACTIVE BIT(17)
  18. static const struct bcr_regs sdc_regs[] = {
  19. {
  20. .cfg_rcgr = SDCC_CFG_RCGR(1),
  21. .cmd_rcgr = SDCC_CMD_RCGR(1),
  22. .M = SDCC_M(1),
  23. .N = SDCC_N(1),
  24. .D = SDCC_D(1),
  25. },
  26. {
  27. .cfg_rcgr = SDCC_CFG_RCGR(2),
  28. .cmd_rcgr = SDCC_CMD_RCGR(2),
  29. .M = SDCC_M(2),
  30. .N = SDCC_N(2),
  31. .D = SDCC_D(2),
  32. }
  33. };
  34. static struct pll_vote_clk gpll0_vote_clk = {
  35. .status = GPLL0_STATUS,
  36. .status_bit = GPLL0_STATUS_ACTIVE,
  37. .ena_vote = APCS_GPLL_ENA_VOTE,
  38. .vote_bit = BIT(0),
  39. };
  40. static struct vote_clk gcc_blsp1_ahb_clk = {
  41. .cbcr_reg = BLSP1_AHB_CBCR,
  42. .ena_vote = APCS_CLOCK_BRANCH_ENA_VOTE,
  43. .vote_bit = BIT(10),
  44. };
  45. /* SDHCI */
  46. static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
  47. {
  48. int div = 8; /* 100MHz default */
  49. if (rate == 200000000)
  50. div = 4;
  51. clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot));
  52. /* 800Mhz/div, gpll0 */
  53. clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
  54. CFG_CLK_SRC_GPLL0);
  55. clk_enable_gpll0(priv->base, &gpll0_vote_clk);
  56. clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
  57. return rate;
  58. }
  59. static const struct bcr_regs uart2_regs = {
  60. .cfg_rcgr = BLSP1_UART2_APPS_CFG_RCGR,
  61. .cmd_rcgr = BLSP1_UART2_APPS_CMD_RCGR,
  62. .M = BLSP1_UART2_APPS_M,
  63. .N = BLSP1_UART2_APPS_N,
  64. .D = BLSP1_UART2_APPS_D,
  65. };
  66. /* UART: 115200 */
  67. static int clk_init_uart(struct msm_clk_priv *priv)
  68. {
  69. /* Enable AHB clock */
  70. clk_enable_vote_clk(priv->base, &gcc_blsp1_ahb_clk);
  71. /* 7372800 uart block clock @ GPLL0 */
  72. clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625,
  73. CFG_CLK_SRC_GPLL0);
  74. /* Vote for gpll0 clock */
  75. clk_enable_gpll0(priv->base, &gpll0_vote_clk);
  76. /* Enable core clk */
  77. clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
  78. return 0;
  79. }
  80. ulong msm_set_rate(struct clk *clk, ulong rate)
  81. {
  82. struct msm_clk_priv *priv = dev_get_priv(clk->dev);
  83. switch (clk->id) {
  84. case 0: /* SDC1 */
  85. return clk_init_sdc(priv, 0, rate);
  86. break;
  87. case 1: /* SDC2 */
  88. return clk_init_sdc(priv, 1, rate);
  89. break;
  90. case 4: /* UART2 */
  91. return clk_init_uart(priv);
  92. break;
  93. default:
  94. return 0;
  95. }
  96. }