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