2
0

imx_ccm.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * IMX31 Clock Control Module
  3. *
  4. * Copyright (C) 2012 NICTA
  5. * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
  6. *
  7. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  8. * See the COPYING file in the top-level directory.
  9. *
  10. * This is an abstract base class used to get a common interface to
  11. * retrieve the CCM frequencies from the various i.MX SOC.
  12. */
  13. #include "qemu/osdep.h"
  14. #include "hw/misc/imx_ccm.h"
  15. #include "qemu/module.h"
  16. #ifndef DEBUG_IMX_CCM
  17. #define DEBUG_IMX_CCM 0
  18. #endif
  19. #define DPRINTF(fmt, args...) \
  20. do { \
  21. if (DEBUG_IMX_CCM) { \
  22. fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_CCM, \
  23. __func__, ##args); \
  24. } \
  25. } while (0)
  26. uint32_t imx_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
  27. {
  28. uint32_t freq = 0;
  29. IMXCCMClass *klass = IMX_CCM_GET_CLASS(dev);
  30. if (klass->get_clock_frequency) {
  31. freq = klass->get_clock_frequency(dev, clock);
  32. }
  33. DPRINTF("(clock = %d) = %u\n", clock, freq);
  34. return freq;
  35. }
  36. /*
  37. * Calculate PLL output frequency
  38. */
  39. uint32_t imx_ccm_calc_pll(uint32_t pllreg, uint32_t base_freq)
  40. {
  41. int32_t freq;
  42. int32_t mfn = MFN(pllreg); /* Numerator */
  43. uint32_t mfi = MFI(pllreg); /* Integer part */
  44. uint32_t mfd = 1 + MFD(pllreg); /* Denominator */
  45. uint32_t pd = 1 + PD(pllreg); /* Pre-divider */
  46. if (mfi < 5) {
  47. mfi = 5;
  48. }
  49. /* mfn is 10-bit signed twos-complement */
  50. mfn <<= 32 - 10;
  51. mfn >>= 32 - 10;
  52. freq = ((2 * (base_freq >> 10) * (mfi * mfd + mfn)) /
  53. (mfd * pd)) << 10;
  54. DPRINTF("(pllreg = 0x%08x, base_freq = %u) = %d\n", pllreg, base_freq,
  55. freq);
  56. return freq;
  57. }
  58. static const TypeInfo imx_ccm_info = {
  59. .name = TYPE_IMX_CCM,
  60. .parent = TYPE_SYS_BUS_DEVICE,
  61. .instance_size = sizeof(IMXCCMState),
  62. .class_size = sizeof(IMXCCMClass),
  63. .abstract = true,
  64. };
  65. static void imx_ccm_register_types(void)
  66. {
  67. type_register_static(&imx_ccm_info);
  68. }
  69. type_init(imx_ccm_register_types)