uboot/arch/m68k/cpu/mcf5445x/speed.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 *
   4 * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc.
   5 * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
   6 */
   7
   8#include <common.h>
   9#include <clock_legacy.h>
  10#include <asm/global_data.h>
  11#include <asm/processor.h>
  12
  13#include <asm/immap.h>
  14#include <asm/io.h>
  15
  16DECLARE_GLOBAL_DATA_PTR;
  17
  18/*
  19 * Low Power Divider specifications
  20 */
  21#define CLOCK_LPD_MIN           (1 << 0)        /* Divider (decoded) */
  22#define CLOCK_LPD_MAX           (1 << 15)       /* Divider (decoded) */
  23
  24#define CLOCK_PLL_FVCO_MAX      540000000
  25#define CLOCK_PLL_FVCO_MIN      300000000
  26
  27#define CLOCK_PLL_FSYS_MAX      266666666
  28#define CLOCK_PLL_FSYS_MIN      100000000
  29#define MHZ                     1000000
  30
  31void clock_enter_limp(int lpdiv)
  32{
  33        ccm_t *ccm = (ccm_t *)MMAP_CCM;
  34        int i, j;
  35
  36        /* Check bounds of divider */
  37        if (lpdiv < CLOCK_LPD_MIN)
  38                lpdiv = CLOCK_LPD_MIN;
  39        if (lpdiv > CLOCK_LPD_MAX)
  40                lpdiv = CLOCK_LPD_MAX;
  41
  42        /* Round divider down to nearest power of two */
  43        for (i = 0, j = lpdiv; j != 1; j >>= 1, i++) ;
  44
  45        /* Enable Limp Mode */
  46        setbits_be16(&ccm->misccr, CCM_MISCCR_LIMP);
  47}
  48
  49/*
  50 * brief   Exit Limp mode
  51 * warning The PLL should be set and locked prior to exiting Limp mode
  52 */
  53void clock_exit_limp(void)
  54{
  55        ccm_t *ccm = (ccm_t *)MMAP_CCM;
  56        pll_t *pll = (pll_t *)MMAP_PLL;
  57
  58        /* Exit Limp mode */
  59        clrbits_be16(&ccm->misccr, CCM_MISCCR_LIMP);
  60
  61        /* Wait for the PLL to lock */
  62        while (!(in_be32(&pll->psr) & PLL_PSR_LOCK))
  63                ;
  64}
  65
  66#ifdef CONFIG_MCF5441x
  67void setup_5441x_clocks(void)
  68{
  69        ccm_t *ccm = (ccm_t *)MMAP_CCM;
  70        pll_t *pll = (pll_t *)MMAP_PLL;
  71        int temp, vco = 0, bootmod_ccr, pdr;
  72
  73        bootmod_ccr = (in_be16(&ccm->ccr) & CCM_CCR_BOOTMOD) >> 14;
  74
  75        switch (bootmod_ccr) {
  76        case 0:
  77                out_be32(&pll->pcr, 0x00000013);
  78                out_be32(&pll->pdr, 0x00e70c61);
  79                clock_exit_limp();
  80                break;
  81        case 2:
  82                break;
  83        case 3:
  84                break;
  85        }
  86
  87        /*Change frequency for Modelo SER1 USB host*/
  88#ifdef CONFIG_LOW_MCFCLK
  89        temp = in_be32(&pll->pcr);
  90        temp &= ~0x3f;
  91        temp |= 5;
  92        out_be32(&pll->pcr, temp);
  93
  94        temp = in_be32(&pll->pdr);
  95        temp &= ~0x001f0000;
  96        temp |= 0x00040000;
  97        out_be32(&pll->pdr, temp);
  98        __asm__("tpf");
  99#endif
 100
 101        setbits_be16(&ccm->misccr2, 0x02);
 102
 103        vco =  ((in_be32(&pll->pcr) & PLL_CR_FBKDIV_BITS) + 1) *
 104                CONFIG_SYS_INPUT_CLKSRC;
 105        gd->arch.vco_clk = vco;
 106
 107        gd->arch.inp_clk = CONFIG_SYS_INPUT_CLKSRC;     /* Input clock */
 108
 109        pdr = in_be32(&pll->pdr);
 110        temp = (pdr & PLL_DR_OUTDIV1_BITS) + 1;
 111        gd->cpu_clk = vco / temp;       /* cpu clock */
 112        gd->arch.flb_clk = vco / temp;  /* FlexBus clock */
 113        gd->arch.flb_clk >>= 1;
 114        if (in_be16(&ccm->misccr2) & 2)         /* fsys/4 */
 115                gd->arch.flb_clk >>= 1;
 116
 117        temp = ((pdr & PLL_DR_OUTDIV2_BITS) >> 5) + 1;
 118        gd->bus_clk = vco / temp;       /* bus clock */
 119
 120        temp = ((pdr & PLL_DR_OUTDIV3_BITS) >> 10) + 1;
 121        gd->arch.sdhc_clk = vco / temp;
 122}
 123#endif
 124
 125/* get_clocks() fills in gd->cpu_clock and gd->bus_clk */
 126int get_clocks(void)
 127{
 128#ifdef CONFIG_MCF5441x
 129        setup_5441x_clocks();
 130#endif
 131
 132#ifdef CONFIG_SYS_FSL_I2C
 133        gd->arch.i2c1_clk = gd->bus_clk;
 134#endif
 135
 136        return (0);
 137}
 138