1bbc6fac3SScott Wood /* 2bbc6fac3SScott Wood * MPC8xx support functions 3bbc6fac3SScott Wood * 4bbc6fac3SScott Wood * Author: Scott Wood <scottwood@freescale.com> 5bbc6fac3SScott Wood * 6bbc6fac3SScott Wood * Copyright (c) 2007 Freescale Semiconductor, Inc. 7bbc6fac3SScott Wood * 8bbc6fac3SScott Wood * This program is free software; you can redistribute it and/or modify it 9bbc6fac3SScott Wood * under the terms of the GNU General Public License version 2 as published 10bbc6fac3SScott Wood * by the Free Software Foundation. 11bbc6fac3SScott Wood */ 12bbc6fac3SScott Wood 13bbc6fac3SScott Wood #include "ops.h" 14bbc6fac3SScott Wood #include "types.h" 15bbc6fac3SScott Wood #include "fsl-soc.h" 16bbc6fac3SScott Wood #include "mpc8xx.h" 17bbc6fac3SScott Wood #include "stdio.h" 18bbc6fac3SScott Wood #include "io.h" 19bbc6fac3SScott Wood 20bbc6fac3SScott Wood #define MPC8XX_PLPRCR (0x284/4) /* PLL and Reset Control Register */ 21bbc6fac3SScott Wood 22bbc6fac3SScott Wood /* Return system clock from crystal frequency */ 23bbc6fac3SScott Wood u32 mpc885_get_clock(u32 crystal) 24bbc6fac3SScott Wood { 25bbc6fac3SScott Wood u32 *immr; 26bbc6fac3SScott Wood u32 plprcr; 27bbc6fac3SScott Wood int mfi, mfn, mfd, pdf, div; 28bbc6fac3SScott Wood u32 ret; 29bbc6fac3SScott Wood 30bbc6fac3SScott Wood immr = fsl_get_immr(); 31bbc6fac3SScott Wood if (!immr) { 32bbc6fac3SScott Wood printf("mpc885_get_clock: Couldn't get IMMR base.\r\n"); 33bbc6fac3SScott Wood return 0; 34bbc6fac3SScott Wood } 35bbc6fac3SScott Wood 36bbc6fac3SScott Wood plprcr = in_be32(&immr[MPC8XX_PLPRCR]); 37bbc6fac3SScott Wood 38bbc6fac3SScott Wood mfi = (plprcr >> 16) & 15; 39bbc6fac3SScott Wood if (mfi < 5) { 40bbc6fac3SScott Wood printf("Warning: PLPRCR[MFI] value of %d out-of-bounds\r\n", 41bbc6fac3SScott Wood mfi); 42bbc6fac3SScott Wood mfi = 5; 43bbc6fac3SScott Wood } 44bbc6fac3SScott Wood 45bbc6fac3SScott Wood pdf = (plprcr >> 1) & 0xf; 46bbc6fac3SScott Wood div = (plprcr >> 20) & 3; 47bbc6fac3SScott Wood mfd = (plprcr >> 22) & 0x1f; 48bbc6fac3SScott Wood mfn = (plprcr >> 27) & 0x1f; 49bbc6fac3SScott Wood 50bbc6fac3SScott Wood ret = crystal * mfi; 51bbc6fac3SScott Wood 52bbc6fac3SScott Wood if (mfn != 0) 53bbc6fac3SScott Wood ret += crystal * mfn / (mfd + 1); 54bbc6fac3SScott Wood 55bbc6fac3SScott Wood return ret / (pdf + 1); 56bbc6fac3SScott Wood } 57bbc6fac3SScott Wood 58bbc6fac3SScott Wood /* Set common device tree fields based on the given clock frequencies. */ 59bbc6fac3SScott Wood void mpc8xx_set_clocks(u32 sysclk) 60bbc6fac3SScott Wood { 61bbc6fac3SScott Wood void *node; 62bbc6fac3SScott Wood 63bbc6fac3SScott Wood dt_fixup_cpu_clocks(sysclk, sysclk / 16, sysclk); 64bbc6fac3SScott Wood 65bbc6fac3SScott Wood node = finddevice("/soc/cpm"); 66bbc6fac3SScott Wood if (node) 67bbc6fac3SScott Wood setprop(node, "clock-frequency", &sysclk, 4); 68bbc6fac3SScott Wood 69bbc6fac3SScott Wood node = finddevice("/soc/cpm/brg"); 70bbc6fac3SScott Wood if (node) 71bbc6fac3SScott Wood setprop(node, "clock-frequency", &sysclk, 4); 72bbc6fac3SScott Wood } 73bbc6fac3SScott Wood 74bbc6fac3SScott Wood int mpc885_fixup_clocks(u32 crystal) 75bbc6fac3SScott Wood { 76bbc6fac3SScott Wood u32 sysclk = mpc885_get_clock(crystal); 77bbc6fac3SScott Wood if (!sysclk) 78bbc6fac3SScott Wood return 0; 79bbc6fac3SScott Wood 80bbc6fac3SScott Wood mpc8xx_set_clocks(sysclk); 81bbc6fac3SScott Wood return 1; 82bbc6fac3SScott Wood } 83