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