clock.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2015 Atmel Corporation
  4. * Wenyou Yang <wenyou.yang@atmel.com>
  5. */
  6. #include <common.h>
  7. #include <asm/io.h>
  8. #include <asm/arch/hardware.h>
  9. #include <asm/arch/at91_pmc.h>
  10. #define EN_UPLL_TIMEOUT 500
  11. void at91_periph_clk_enable(int id)
  12. {
  13. struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
  14. #ifdef CPU_HAS_PCR
  15. u32 regval;
  16. u32 div_value;
  17. if (id > AT91_PMC_PCR_PID_MASK)
  18. return;
  19. writel(id, &pmc->pcr);
  20. div_value = readl(&pmc->pcr) & AT91_PMC_PCR_DIV;
  21. regval = AT91_PMC_PCR_EN | AT91_PMC_PCR_CMD_WRITE | id | div_value;
  22. writel(regval, &pmc->pcr);
  23. #else
  24. writel(0x01 << id, &pmc->pcer);
  25. #endif
  26. }
  27. void at91_periph_clk_disable(int id)
  28. {
  29. struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
  30. #ifdef CPU_HAS_PCR
  31. u32 regval;
  32. if (id > AT91_PMC_PCR_PID_MASK)
  33. return;
  34. regval = AT91_PMC_PCR_CMD_WRITE | id;
  35. writel(regval, &pmc->pcr);
  36. #else
  37. writel(0x01 << id, &pmc->pcdr);
  38. #endif
  39. }
  40. void at91_system_clk_enable(int sys_clk)
  41. {
  42. struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
  43. writel(sys_clk, &pmc->scer);
  44. }
  45. void at91_system_clk_disable(int sys_clk)
  46. {
  47. struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
  48. writel(sys_clk, &pmc->scdr);
  49. }
  50. int at91_upll_clk_enable(void)
  51. {
  52. struct at91_pmc *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
  53. ulong start_time, tmp_time;
  54. if ((readl(&pmc->uckr) & AT91_PMC_UPLLEN) == AT91_PMC_UPLLEN)
  55. return 0;
  56. start_time = get_timer(0);
  57. writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr);
  58. while ((readl(&pmc->sr) & AT91_PMC_LOCKU) != AT91_PMC_LOCKU) {
  59. tmp_time = get_timer(0);
  60. if ((tmp_time - start_time) > EN_UPLL_TIMEOUT) {
  61. printf("ERROR: failed to enable UPLL\n");
  62. return -1;
  63. }
  64. }
  65. return 0;
  66. }
  67. int at91_upll_clk_disable(void)
  68. {
  69. struct at91_pmc *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
  70. ulong start_time, tmp_time;
  71. start_time = get_timer(0);
  72. writel(readl(&pmc->uckr) & ~AT91_PMC_UPLLEN, &pmc->uckr);
  73. while ((readl(&pmc->sr) & AT91_PMC_LOCKU) == AT91_PMC_LOCKU) {
  74. tmp_time = get_timer(0);
  75. if ((tmp_time - start_time) > EN_UPLL_TIMEOUT) {
  76. printf("ERROR: failed to stop UPLL\n");
  77. return -1;
  78. }
  79. }
  80. return 0;
  81. }
  82. void at91_usb_clk_init(u32 value)
  83. {
  84. struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
  85. writel(value, &pmc->usb);
  86. }
  87. void at91_pllicpr_init(u32 icpr)
  88. {
  89. struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
  90. writel(icpr, &pmc->pllicpr);
  91. }