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, div; 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 div = (plprcr >> 20) & 3; 47 mfd = (plprcr >> 22) & 0x1f; 48 mfn = (plprcr >> 27) & 0x1f; 49 50 ret = crystal * mfi; 51 52 if (mfn != 0) 53 ret += crystal * mfn / (mfd + 1); 54 55 return ret / (pdf + 1); 56 } 57 58 /* Set common device tree fields based on the given clock frequencies. */ 59 void mpc8xx_set_clocks(u32 sysclk) 60 { 61 void *node; 62 63 dt_fixup_cpu_clocks(sysclk, sysclk / 16, sysclk); 64 65 node = finddevice("/soc/cpm"); 66 if (node) 67 setprop(node, "clock-frequency", &sysclk, 4); 68 69 node = finddevice("/soc/cpm/brg"); 70 if (node) 71 setprop(node, "clock-frequency", &sysclk, 4); 72 } 73 74 int mpc885_fixup_clocks(u32 crystal) 75 { 76 u32 sysclk = mpc885_get_clock(crystal); 77 if (!sysclk) 78 return 0; 79 80 mpc8xx_set_clocks(sysclk); 81 return 1; 82 } 83