clk-eth.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2014 Broadcom Corporation.
  4. */
  5. #include <common.h>
  6. #include <asm/io.h>
  7. #include <linux/errno.h>
  8. #include <asm/arch/sysmap.h>
  9. #include <asm/kona-common/clk.h>
  10. #include "clk-core.h"
  11. #define WR_ACCESS_ADDR ESUB_CLK_BASE_ADDR
  12. #define WR_ACCESS_PASSWORD 0xA5A500
  13. #define PLLE_POST_RESETB_ADDR (ESUB_CLK_BASE_ADDR + 0x00000C00)
  14. #define PLLE_RESETB_ADDR (ESUB_CLK_BASE_ADDR + 0x00000C58)
  15. #define PLLE_RESETB_I_PLL_RESETB_PLLE_MASK 0x00010000
  16. #define PLLE_POST_RESETB_I_POST_RESETB_PLLE_MASK 0x00000001
  17. #define PLL_LOCK_ADDR (ESUB_CLK_BASE_ADDR + 0x00000C38)
  18. #define PLL_LOCK_PLL_LOCK_PLLE_MASK 0x00000001
  19. #define ESW_SYS_DIV_ADDR (ESUB_CLK_BASE_ADDR + 0x00000A04)
  20. #define ESW_SYS_DIV_PLL_SELECT_MASK 0x00000300
  21. #define ESW_SYS_DIV_DIV_MASK 0x0000001C
  22. #define ESW_SYS_DIV_PLL_VAR_208M_CLK_SELECT 0x00000100
  23. #define ESW_SYS_DIV_DIV_SELECT 0x4
  24. #define ESW_SYS_DIV_TRIGGER_MASK 0x00000001
  25. #define ESUB_AXI_DIV_DEBUG_ADDR (ESUB_CLK_BASE_ADDR + 0x00000E04)
  26. #define ESUB_AXI_DIV_DEBUG_PLL_SELECT_MASK 0x0000001C
  27. #define ESUB_AXI_DIV_DEBUG_PLL_SELECT_OVERRIDE_MASK 0x00000040
  28. #define ESUB_AXI_DIV_DEBUG_PLL_VAR_208M_CLK_SELECT 0x0
  29. #define ESUB_AXI_DIV_DEBUG_TRIGGER_MASK 0x00000001
  30. #define PLL_MAX_RETRY 100
  31. /* Enable appropriate clocks for Ethernet */
  32. int clk_eth_enable(void)
  33. {
  34. int rc = -1;
  35. int retry_count = 0;
  36. rc = clk_get_and_enable("esub_ccu_clk");
  37. /* Enable Access to CCU registers */
  38. writel((1 | WR_ACCESS_PASSWORD), WR_ACCESS_ADDR);
  39. writel(readl(PLLE_POST_RESETB_ADDR) &
  40. ~PLLE_POST_RESETB_I_POST_RESETB_PLLE_MASK,
  41. PLLE_POST_RESETB_ADDR);
  42. /* Take PLL out of reset and put into normal mode */
  43. writel(readl(PLLE_RESETB_ADDR) | PLLE_RESETB_I_PLL_RESETB_PLLE_MASK,
  44. PLLE_RESETB_ADDR);
  45. /* Wait for PLL lock */
  46. rc = -1;
  47. while (retry_count < PLL_MAX_RETRY) {
  48. udelay(100);
  49. if (readl(PLL_LOCK_ADDR) & PLL_LOCK_PLL_LOCK_PLLE_MASK) {
  50. rc = 0;
  51. break;
  52. }
  53. retry_count++;
  54. }
  55. if (rc == -1) {
  56. printf("%s: ETH-PLL lock timeout, Ethernet is not enabled!\n",
  57. __func__);
  58. return -1;
  59. }
  60. writel(readl(PLLE_POST_RESETB_ADDR) |
  61. PLLE_POST_RESETB_I_POST_RESETB_PLLE_MASK,
  62. PLLE_POST_RESETB_ADDR);
  63. /* Switch esw_sys_clk to use 104MHz(208MHz/2) clock */
  64. writel((readl(ESW_SYS_DIV_ADDR) &
  65. ~(ESW_SYS_DIV_PLL_SELECT_MASK | ESW_SYS_DIV_DIV_MASK)) |
  66. ESW_SYS_DIV_PLL_VAR_208M_CLK_SELECT | ESW_SYS_DIV_DIV_SELECT,
  67. ESW_SYS_DIV_ADDR);
  68. writel(readl(ESW_SYS_DIV_ADDR) | ESW_SYS_DIV_TRIGGER_MASK,
  69. ESW_SYS_DIV_ADDR);
  70. /* Wait for trigger complete */
  71. rc = -1;
  72. retry_count = 0;
  73. while (retry_count < PLL_MAX_RETRY) {
  74. udelay(100);
  75. if (!(readl(ESW_SYS_DIV_ADDR) & ESW_SYS_DIV_TRIGGER_MASK)) {
  76. rc = 0;
  77. break;
  78. }
  79. retry_count++;
  80. }
  81. if (rc == -1) {
  82. printf("%s: SYS CLK Trigger timeout, Ethernet is not enabled!\n",
  83. __func__);
  84. return -1;
  85. }
  86. /* switch Esub AXI clock to 208MHz */
  87. writel((readl(ESUB_AXI_DIV_DEBUG_ADDR) &
  88. ~(ESUB_AXI_DIV_DEBUG_PLL_SELECT_MASK |
  89. ESUB_AXI_DIV_DEBUG_PLL_SELECT_OVERRIDE_MASK |
  90. ESUB_AXI_DIV_DEBUG_TRIGGER_MASK)) |
  91. ESUB_AXI_DIV_DEBUG_PLL_VAR_208M_CLK_SELECT |
  92. ESUB_AXI_DIV_DEBUG_PLL_SELECT_OVERRIDE_MASK,
  93. ESUB_AXI_DIV_DEBUG_ADDR);
  94. writel(readl(ESUB_AXI_DIV_DEBUG_ADDR) |
  95. ESUB_AXI_DIV_DEBUG_TRIGGER_MASK,
  96. ESUB_AXI_DIV_DEBUG_ADDR);
  97. /* Wait for trigger complete */
  98. rc = -1;
  99. retry_count = 0;
  100. while (retry_count < PLL_MAX_RETRY) {
  101. udelay(100);
  102. if (!(readl(ESUB_AXI_DIV_DEBUG_ADDR) &
  103. ESUB_AXI_DIV_DEBUG_TRIGGER_MASK)) {
  104. rc = 0;
  105. break;
  106. }
  107. retry_count++;
  108. }
  109. if (rc == -1) {
  110. printf("%s: AXI CLK Trigger timeout, Ethernet is not enabled!\n",
  111. __func__);
  112. return -1;
  113. }
  114. /* Disable Access to CCU registers */
  115. writel(WR_ACCESS_PASSWORD, WR_ACCESS_ADDR);
  116. return rc;
  117. }