source: rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/get-system-clock.c @ a762dc2

4.11
Last change on this file since a762dc2 was a762dc2, checked in by Sebastian Huber <sebastian.huber@…>, on Jan 23, 2012 at 10:19:22 AM

Support for MPC5643L.

Rework of the start sequence to reduce the amount assembler code and to
support configuration tables which may be provided by the application.

  • Property mode set to 100644
File size: 2.3 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup mpc55xx
5 *
6 * @brief System clock calculation.
7 */
8
9/*
10 * Copyright (c) 2008-2011 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Obere Lagerstr. 30
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.com/license/LICENSE.
21 */
22
23#include <bsp.h>
24#include <bsp/start.h>
25#include <bsp/mpc55xx-config.h>
26
27uint32_t mpc55xx_get_system_clock(void)
28{
29  uint32_t system_clock = 0;
30
31  #ifdef MPC55XX_HAS_FMPLL
32    volatile struct FMPLL_tag *fmpll = &FMPLL;
33    union FMPLL_SYNSR_tag synsr = { .R = fmpll->SYNSR.R };
34    uint32_t reference_clock = MPC55XX_FMPLL_REF_CLOCK;
35    bool pll_clock_mode = synsr.B.MODE != 0;
36    bool crystal_or_external_reference_mode = synsr.B.PLLSEL != 0;
37
38    if (pll_clock_mode) {
39      if (crystal_or_external_reference_mode) {
40        union FMPLL_SYNCR_tag syncr = { .R = fmpll->SYNCR.R };
41        uint32_t prediv = syncr.B.PREDIV;
42        uint32_t mfd = syncr.B.MFD;
43        uint32_t rfd = syncr.B.RFD;
44
45        system_clock = ((reference_clock * (mfd + 4)) >> rfd) / (prediv + 1);
46      } else {
47        system_clock = 2 * reference_clock;
48      }
49    } else {
50      system_clock = reference_clock;
51    }
52  #endif
53
54  #ifdef MPC55XX_HAS_FMPLL_ENHANCED
55    volatile struct FMPLL_tag *fmpll = &FMPLL;
56    union FMPLL_ESYNCR1_tag esyncr1 = { .R = fmpll->ESYNCR1.R };
57    uint32_t reference_clock = MPC55XX_FMPLL_REF_CLOCK;
58    bool normal_mode = (esyncr1.B.CLKCFG & 0x4U) != 0;
59
60    if (normal_mode) {
61      union FMPLL_ESYNCR2_tag esyncr2 = { .R = fmpll->ESYNCR2.R };
62      uint32_t eprediv = esyncr1.B.EPREDIV;
63      uint32_t emfd = esyncr1.B.EMFD;
64      uint32_t erfd = esyncr2.B.ERFD;
65
66      system_clock = (reference_clock * (emfd + 16))
67        / ((erfd + 1) * (eprediv + 1));
68    } else {
69      system_clock = reference_clock;
70    }
71  #endif
72
73  #ifdef MPC55XX_HAS_MODE_CONTROL
74    /* FIXME: Assumes normal mode and external oscillator */
75    PLLD_CR_32B_tag cr = { . R = CGM.FMPLL [0].CR.R };
76    uint32_t xosc = MPC55XX_FMPLL_REF_CLOCK;
77    uint32_t ldf = cr.B.NDIV;
78    uint32_t idf = cr.B.IDF + 1;
79    uint32_t odf = 2U << cr.B.ODF;
80
81    system_clock = (xosc * ldf) / (idf * odf);
82  #endif
83
84  return system_clock;
85}
Note: See TracBrowser for help on using the repository browser.