1 /* 2 * IMX31 Clock Control Module 3 * 4 * Copyright (C) 2012 NICTA 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 or later. 7 * See the COPYING file in the top-level directory. 8 * 9 * To get the timer frequencies right, we need to emulate at least part of 10 * the CCM. 11 */ 12 13 #include "hw/hw.h" 14 #include "hw/sysbus.h" 15 #include "sysemu/sysemu.h" 16 #include "hw/arm/imx.h" 17 18 #define CKIH_FREQ 26000000 /* 26MHz crystal input */ 19 #define CKIL_FREQ 32768 /* nominal 32khz clock */ 20 21 22 //#define DEBUG_CCM 1 23 #ifdef DEBUG_CCM 24 #define DPRINTF(fmt, args...) \ 25 do { printf("imx_ccm: " fmt , ##args); } while (0) 26 #else 27 #define DPRINTF(fmt, args...) do {} while (0) 28 #endif 29 30 static int imx_ccm_post_load(void *opaque, int version_id); 31 32 typedef struct { 33 SysBusDevice busdev; 34 MemoryRegion iomem; 35 36 uint32_t ccmr; 37 uint32_t pdr0; 38 uint32_t pdr1; 39 uint32_t mpctl; 40 uint32_t spctl; 41 uint32_t cgr[3]; 42 uint32_t pmcr0; 43 uint32_t pmcr1; 44 45 /* Frequencies precalculated on register changes */ 46 uint32_t pll_refclk_freq; 47 uint32_t mcu_clk_freq; 48 uint32_t hsp_clk_freq; 49 uint32_t ipg_clk_freq; 50 } IMXCCMState; 51 52 static const VMStateDescription vmstate_imx_ccm = { 53 .name = "imx-ccm", 54 .version_id = 1, 55 .minimum_version_id = 1, 56 .minimum_version_id_old = 1, 57 .fields = (VMStateField[]) { 58 VMSTATE_UINT32(ccmr, IMXCCMState), 59 VMSTATE_UINT32(pdr0, IMXCCMState), 60 VMSTATE_UINT32(pdr1, IMXCCMState), 61 VMSTATE_UINT32(mpctl, IMXCCMState), 62 VMSTATE_UINT32(spctl, IMXCCMState), 63 VMSTATE_UINT32_ARRAY(cgr, IMXCCMState, 3), 64 VMSTATE_UINT32(pmcr0, IMXCCMState), 65 VMSTATE_UINT32(pmcr1, IMXCCMState), 66 VMSTATE_UINT32(pll_refclk_freq, IMXCCMState), 67 }, 68 .post_load = imx_ccm_post_load, 69 }; 70 71 /* CCMR */ 72 #define CCMR_FPME (1<<0) 73 #define CCMR_MPE (1<<3) 74 #define CCMR_MDS (1<<7) 75 #define CCMR_FPMF (1<<26) 76 #define CCMR_PRCS (3<<1) 77 78 /* PDR0 */ 79 #define PDR0_MCU_PODF_SHIFT (0) 80 #define PDR0_MCU_PODF_MASK (0x7) 81 #define PDR0_MAX_PODF_SHIFT (3) 82 #define PDR0_MAX_PODF_MASK (0x7) 83 #define PDR0_IPG_PODF_SHIFT (6) 84 #define PDR0_IPG_PODF_MASK (0x3) 85 #define PDR0_NFC_PODF_SHIFT (8) 86 #define PDR0_NFC_PODF_MASK (0x7) 87 #define PDR0_HSP_PODF_SHIFT (11) 88 #define PDR0_HSP_PODF_MASK (0x7) 89 #define PDR0_PER_PODF_SHIFT (16) 90 #define PDR0_PER_PODF_MASK (0x1f) 91 #define PDR0_CSI_PODF_SHIFT (23) 92 #define PDR0_CSI_PODF_MASK (0x1ff) 93 94 #define EXTRACT(value, name) (((value) >> PDR0_##name##_PODF_SHIFT) \ 95 & PDR0_##name##_PODF_MASK) 96 #define INSERT(value, name) (((value) & PDR0_##name##_PODF_MASK) << \ 97 PDR0_##name##_PODF_SHIFT) 98 /* PLL control registers */ 99 #define PD(v) (((v) >> 26) & 0xf) 100 #define MFD(v) (((v) >> 16) & 0x3ff) 101 #define MFI(v) (((v) >> 10) & 0xf); 102 #define MFN(v) ((v) & 0x3ff) 103 104 #define PLL_PD(x) (((x) & 0xf) << 26) 105 #define PLL_MFD(x) (((x) & 0x3ff) << 16) 106 #define PLL_MFI(x) (((x) & 0xf) << 10) 107 #define PLL_MFN(x) (((x) & 0x3ff) << 0) 108 109 uint32_t imx_clock_frequency(DeviceState *dev, IMXClk clock) 110 { 111 IMXCCMState *s = container_of(dev, IMXCCMState, busdev.qdev); 112 113 switch (clock) { 114 case NOCLK: 115 return 0; 116 case MCU: 117 return s->mcu_clk_freq; 118 case HSP: 119 return s->hsp_clk_freq; 120 case IPG: 121 return s->ipg_clk_freq; 122 case CLK_32k: 123 return CKIL_FREQ; 124 } 125 return 0; 126 } 127 128 /* 129 * Calculate PLL output frequency 130 */ 131 static uint32_t calc_pll(uint32_t pllreg, uint32_t base_freq) 132 { 133 int32_t mfn = MFN(pllreg); /* Numerator */ 134 uint32_t mfi = MFI(pllreg); /* Integer part */ 135 uint32_t mfd = 1 + MFD(pllreg); /* Denominator */ 136 uint32_t pd = 1 + PD(pllreg); /* Pre-divider */ 137 138 if (mfi < 5) { 139 mfi = 5; 140 } 141 /* mfn is 10-bit signed twos-complement */ 142 mfn <<= 32 - 10; 143 mfn >>= 32 - 10; 144 145 return ((2 * (base_freq >> 10) * (mfi * mfd + mfn)) / 146 (mfd * pd)) << 10; 147 } 148 149 static void update_clocks(IMXCCMState *s) 150 { 151 /* 152 * If we ever emulate more clocks, this should switch to a data-driven 153 * approach 154 */ 155 156 if ((s->ccmr & CCMR_PRCS) == 2) { 157 s->pll_refclk_freq = CKIL_FREQ * 1024; 158 } else { 159 s->pll_refclk_freq = CKIH_FREQ; 160 } 161 162 /* ipg_clk_arm aka MCU clock */ 163 if ((s->ccmr & CCMR_MDS) || !(s->ccmr & CCMR_MPE)) { 164 s->mcu_clk_freq = s->pll_refclk_freq; 165 } else { 166 s->mcu_clk_freq = calc_pll(s->mpctl, s->pll_refclk_freq); 167 } 168 169 /* High-speed clock */ 170 s->hsp_clk_freq = s->mcu_clk_freq / (1 + EXTRACT(s->pdr0, HSP)); 171 s->ipg_clk_freq = s->hsp_clk_freq / (1 + EXTRACT(s->pdr0, IPG)); 172 173 DPRINTF("Clocks: mcu %uMHz, HSP %uMHz, IPG %uHz\n", 174 s->mcu_clk_freq / 1000000, 175 s->hsp_clk_freq / 1000000, 176 s->ipg_clk_freq); 177 } 178 179 static void imx_ccm_reset(DeviceState *dev) 180 { 181 IMXCCMState *s = container_of(dev, IMXCCMState, busdev.qdev); 182 183 s->ccmr = 0x074b0b7b; 184 s->pdr0 = 0xff870b48; 185 s->pdr1 = 0x49fcfe7f; 186 s->mpctl = PLL_PD(1) | PLL_MFD(0) | PLL_MFI(6) | PLL_MFN(0); 187 s->cgr[0] = s->cgr[1] = s->cgr[2] = 0xffffffff; 188 s->spctl = PLL_PD(1) | PLL_MFD(4) | PLL_MFI(0xc) | PLL_MFN(1); 189 s->pmcr0 = 0x80209828; 190 191 update_clocks(s); 192 } 193 194 static uint64_t imx_ccm_read(void *opaque, hwaddr offset, 195 unsigned size) 196 { 197 IMXCCMState *s = (IMXCCMState *)opaque; 198 199 DPRINTF("read(offset=%x)", offset >> 2); 200 switch (offset >> 2) { 201 case 0: /* CCMR */ 202 DPRINTF(" ccmr = 0x%x\n", s->ccmr); 203 return s->ccmr; 204 case 1: 205 DPRINTF(" pdr0 = 0x%x\n", s->pdr0); 206 return s->pdr0; 207 case 2: 208 DPRINTF(" pdr1 = 0x%x\n", s->pdr1); 209 return s->pdr1; 210 case 4: 211 DPRINTF(" mpctl = 0x%x\n", s->mpctl); 212 return s->mpctl; 213 case 6: 214 DPRINTF(" spctl = 0x%x\n", s->spctl); 215 return s->spctl; 216 case 8: 217 DPRINTF(" cgr0 = 0x%x\n", s->cgr[0]); 218 return s->cgr[0]; 219 case 9: 220 DPRINTF(" cgr1 = 0x%x\n", s->cgr[1]); 221 return s->cgr[1]; 222 case 10: 223 DPRINTF(" cgr2 = 0x%x\n", s->cgr[2]); 224 return s->cgr[2]; 225 case 18: /* LTR1 */ 226 return 0x00004040; 227 case 23: 228 DPRINTF(" pcmr0 = 0x%x\n", s->pmcr0); 229 return s->pmcr0; 230 } 231 DPRINTF(" return 0\n"); 232 return 0; 233 } 234 235 static void imx_ccm_write(void *opaque, hwaddr offset, 236 uint64_t value, unsigned size) 237 { 238 IMXCCMState *s = (IMXCCMState *)opaque; 239 240 DPRINTF("write(offset=%x, value = %x)\n", 241 offset >> 2, (unsigned int)value); 242 switch (offset >> 2) { 243 case 0: 244 s->ccmr = CCMR_FPMF | (value & 0x3b6fdfff); 245 break; 246 case 1: 247 s->pdr0 = value & 0xff9f3fff; 248 break; 249 case 2: 250 s->pdr1 = value; 251 break; 252 case 4: 253 s->mpctl = value & 0xbfff3fff; 254 break; 255 case 6: 256 s->spctl = value & 0xbfff3fff; 257 break; 258 case 8: 259 s->cgr[0] = value; 260 return; 261 case 9: 262 s->cgr[1] = value; 263 return; 264 case 10: 265 s->cgr[2] = value; 266 return; 267 268 default: 269 return; 270 } 271 update_clocks(s); 272 } 273 274 static const struct MemoryRegionOps imx_ccm_ops = { 275 .read = imx_ccm_read, 276 .write = imx_ccm_write, 277 .endianness = DEVICE_NATIVE_ENDIAN, 278 }; 279 280 static int imx_ccm_init(SysBusDevice *dev) 281 { 282 IMXCCMState *s = FROM_SYSBUS(typeof(*s), dev); 283 284 memory_region_init_io(&s->iomem, OBJECT(dev), &imx_ccm_ops, s, 285 "imx_ccm", 0x1000); 286 sysbus_init_mmio(dev, &s->iomem); 287 288 return 0; 289 } 290 291 static int imx_ccm_post_load(void *opaque, int version_id) 292 { 293 IMXCCMState *s = (IMXCCMState *)opaque; 294 295 update_clocks(s); 296 return 0; 297 } 298 299 static void imx_ccm_class_init(ObjectClass *klass, void *data) 300 { 301 DeviceClass *dc = DEVICE_CLASS(klass); 302 SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); 303 304 sbc->init = imx_ccm_init; 305 dc->reset = imx_ccm_reset; 306 dc->vmsd = &vmstate_imx_ccm; 307 dc->desc = "i.MX Clock Control Module"; 308 } 309 310 static const TypeInfo imx_ccm_info = { 311 .name = "imx_ccm", 312 .parent = TYPE_SYS_BUS_DEVICE, 313 .instance_size = sizeof(IMXCCMState), 314 .class_init = imx_ccm_class_init, 315 }; 316 317 static void imx_ccm_register_types(void) 318 { 319 type_register_static(&imx_ccm_info); 320 } 321 322 type_init(imx_ccm_register_types) 323