sysctl.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. /*
  2. * SPDX-License-Identifier: Apache-2.0
  3. *
  4. * Copyright 2018 Canaan Inc.
  5. * Copyright (c) 2019 Western Digital Corporation or its affiliates.
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. #include <sbi/riscv_encoding.h>
  20. #include "sysctl.h"
  21. volatile sysctl_t *const sysctl = (volatile sysctl_t *)SYSCTL_BASE_ADDR;
  22. #define SYSCTRL_CLOCK_FREQ_IN0 (26000000UL)
  23. static u32 sysctl_pll0_get_freq(void)
  24. {
  25. u32 freq_in, nr, nf, od;
  26. freq_in = SYSCTRL_CLOCK_FREQ_IN0;
  27. nr = sysctl->pll0.clkr0 + 1;
  28. nf = sysctl->pll0.clkf0 + 1;
  29. od = sysctl->pll0.clkod0 + 1;
  30. /*
  31. * Get final PLL output freq
  32. * FOUT = FIN / NR * NF / OD
  33. * = (FIN * NF) / (NR * OD)
  34. */
  35. return ((u64)freq_in * (u64)nf) / ((u64)nr * (u64)od);
  36. }
  37. u32 sysctl_get_cpu_freq(void)
  38. {
  39. int clock_source;
  40. clock_source = (int)sysctl->clk_sel0.aclk_sel;
  41. switch (clock_source) {
  42. case 0:
  43. return SYSCTRL_CLOCK_FREQ_IN0;
  44. case 1:
  45. return sysctl_pll0_get_freq() /
  46. (2ULL << (int)sysctl->clk_sel0.aclk_divider_sel);
  47. default:
  48. return 0;
  49. }
  50. }