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 14 #include "hw/misc/imx_ccm.h" 15 16 #ifndef DEBUG_IMX_CCM 17 #define DEBUG_IMX_CCM 0 18 #endif 19 20 #define DPRINTF(fmt, args...) \ 21 do { \ 22 if (DEBUG_IMX_CCM) { \ 23 fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_CCM, \ 24 __func__, ##args); \ 25 } \ 26 } while (0) 27 28 29 uint32_t imx_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock) 30 { 31 uint32_t freq = 0; 32 IMXCCMClass *klass = IMX_GET_CLASS(dev); 33 34 if (klass->get_clock_frequency) { 35 freq = klass->get_clock_frequency(dev, clock); 36 } 37 38 DPRINTF("(clock = %d) = %d\n", clock, freq); 39 40 return freq; 41 } 42 43 /* 44 * Calculate PLL output frequency 45 */ 46 uint32_t imx_ccm_calc_pll(uint32_t pllreg, uint32_t base_freq) 47 { 48 int32_t freq; 49 int32_t mfn = MFN(pllreg); /* Numerator */ 50 uint32_t mfi = MFI(pllreg); /* Integer part */ 51 uint32_t mfd = 1 + MFD(pllreg); /* Denominator */ 52 uint32_t pd = 1 + PD(pllreg); /* Pre-divider */ 53 54 if (mfi < 5) { 55 mfi = 5; 56 } 57 58 /* mfn is 10-bit signed twos-complement */ 59 mfn <<= 32 - 10; 60 mfn >>= 32 - 10; 61 62 freq = ((2 * (base_freq >> 10) * (mfi * mfd + mfn)) / 63 (mfd * pd)) << 10; 64 65 DPRINTF("(pllreg = 0x%08x, base_freq = %d) = %d\n", pllreg, base_freq, 66 freq); 67 68 return freq; 69 } 70 71 static const TypeInfo imx_ccm_info = { 72 .name = TYPE_IMX_CCM, 73 .parent = TYPE_SYS_BUS_DEVICE, 74 .instance_size = sizeof(IMXCCMState), 75 .class_size = sizeof(IMXCCMClass), 76 .abstract = true, 77 }; 78 79 static void imx_ccm_register_types(void) 80 { 81 type_register_static(&imx_ccm_info); 82 } 83 84 type_init(imx_ccm_register_types) 85