Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[POWERPC] bootwrapper: Add fsl_get_immr() and 8xx/pq2 clock functions.

fsl_get_immr() uses /soc/ranges to determine the immr.

mpc885_get_clock() transforms a crystal frequency into a system frequency
according to the PLL register settings.

pq2_get_clocks() does the same as the above for the PowerQUICC II,
except that it produces several different clocks.

The mpc8xx/pq2 set_clocks() functions modify common properties in
the device tree based on the given clock data.

The mpc885/pq2 fixup_clocks() functions call get_clocks(), and
pass the results to set_clocks().

Signed-off-by: Scott Wood <scottwood@freescale.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>

authored by

Scott Wood and committed by
Kumar Gala
bbc6fac3 56809151

+273 -1
+2 -1
arch/powerpc/boot/Makefile
··· 46 46 ns16550.c serial.c simple_alloc.c div64.S util.S \ 47 47 gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \ 48 48 4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \ 49 - cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c 49 + cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c \ 50 + fsl-soc.c mpc8xx.c pq2.c 50 51 src-plat := of.c cuboot-52xx.c cuboot-83xx.c cuboot-85xx.c holly.c \ 51 52 cuboot-ebony.c treeboot-ebony.c prpmc2800.c \ 52 53 ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
+57
arch/powerpc/boot/fsl-soc.c
··· 1 + /* 2 + * Freescale SOC 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 "stdio.h" 17 + 18 + static u32 prop_buf[MAX_PROP_LEN / 4]; 19 + 20 + u32 *fsl_get_immr(void) 21 + { 22 + void *soc; 23 + unsigned long ret = 0; 24 + 25 + soc = find_node_by_devtype(NULL, "soc"); 26 + if (soc) { 27 + int size; 28 + u32 naddr; 29 + 30 + size = getprop(soc, "#address-cells", prop_buf, MAX_PROP_LEN); 31 + if (size == 4) 32 + naddr = prop_buf[0]; 33 + else 34 + naddr = 2; 35 + 36 + if (naddr != 1 && naddr != 2) 37 + goto err; 38 + 39 + size = getprop(soc, "ranges", prop_buf, MAX_PROP_LEN); 40 + 41 + if (size < 12) 42 + goto err; 43 + if (prop_buf[0] != 0) 44 + goto err; 45 + if (naddr == 2 && prop_buf[1] != 0) 46 + goto err; 47 + 48 + if (!dt_xlate_addr(soc, prop_buf + naddr, 8, &ret)) 49 + ret = 0; 50 + } 51 + 52 + err: 53 + if (!ret) 54 + printf("fsl_get_immr: Failed to find immr base\r\n"); 55 + 56 + return (u32 *)ret; 57 + }
+8
arch/powerpc/boot/fsl-soc.h
··· 1 + #ifndef _PPC_BOOT_FSL_SOC_H_ 2 + #define _PPC_BOOT_FSL_SOC_H_ 3 + 4 + #include "types.h" 5 + 6 + u32 *fsl_get_immr(void); 7 + 8 + #endif
+82
arch/powerpc/boot/mpc8xx.c
··· 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 + }
+11
arch/powerpc/boot/mpc8xx.h
··· 1 + #ifndef _PPC_BOOT_MPC8xx_H_ 2 + #define _PPC_BOOT_MPC8xx_H_ 3 + 4 + #include "types.h" 5 + 6 + void mpc8xx_set_clocks(u32 sysclk); 7 + 8 + u32 mpc885_get_clock(u32 crystal); 9 + int mpc885_fixup_clocks(u32 crystal); 10 + 11 + #endif
+102
arch/powerpc/boot/pq2.c
··· 1 + /* 2 + * PowerQUICC II 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 "pq2.h" 17 + #include "stdio.h" 18 + #include "io.h" 19 + 20 + #define PQ2_SCCR (0x10c80/4) /* System Clock Configuration Register */ 21 + #define PQ2_SCMR (0x10c88/4) /* System Clock Mode Register */ 22 + 23 + static int pq2_corecnf_map[] = { 24 + 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, -1, 25 + 6, 5, 13, 2, 14, 4, 15, 9, 0, 11, 8, 10, 16, 12, 7, -1 26 + }; 27 + 28 + /* Get various clocks from crystal frequency. 29 + * Returns zero on failure and non-zero on success. 30 + */ 31 + int pq2_get_clocks(u32 crystal, u32 *sysfreq, u32 *corefreq, 32 + u32 *timebase, u32 *brgfreq) 33 + { 34 + u32 *immr; 35 + u32 sccr, scmr, mainclk, busclk; 36 + int corecnf, busdf, plldf, pllmf, dfbrg; 37 + 38 + immr = fsl_get_immr(); 39 + if (!immr) { 40 + printf("pq2_get_clocks: Couldn't get IMMR base.\r\n"); 41 + return 0; 42 + } 43 + 44 + sccr = in_be32(&immr[PQ2_SCCR]); 45 + scmr = in_be32(&immr[PQ2_SCMR]); 46 + 47 + dfbrg = sccr & 3; 48 + corecnf = (scmr >> 24) & 0x1f; 49 + busdf = (scmr >> 20) & 0xf; 50 + plldf = (scmr >> 12) & 1; 51 + pllmf = scmr & 0xfff; 52 + 53 + mainclk = crystal * (pllmf + 1) / (plldf + 1); 54 + busclk = mainclk / (busdf + 1); 55 + 56 + if (sysfreq) 57 + *sysfreq = mainclk / 2; 58 + if (timebase) 59 + *timebase = busclk / 4; 60 + if (brgfreq) 61 + *brgfreq = mainclk / (1 << ((dfbrg + 1) * 2)); 62 + 63 + if (corefreq) { 64 + int coremult = pq2_corecnf_map[corecnf]; 65 + 66 + if (coremult < 0) 67 + *corefreq = mainclk / 2; 68 + else if (coremult == 0) 69 + return 0; 70 + else 71 + *corefreq = busclk * coremult / 2; 72 + } 73 + 74 + return 1; 75 + } 76 + 77 + /* Set common device tree fields based on the given clock frequencies. */ 78 + void pq2_set_clocks(u32 sysfreq, u32 corefreq, u32 timebase, u32 brgfreq) 79 + { 80 + void *node; 81 + 82 + dt_fixup_cpu_clocks(corefreq, timebase, sysfreq); 83 + 84 + node = finddevice("/soc/cpm"); 85 + if (node) 86 + setprop(node, "clock-frequency", &sysfreq, 4); 87 + 88 + node = finddevice("/soc/cpm/brg"); 89 + if (node) 90 + setprop(node, "clock-frequency", &brgfreq, 4); 91 + } 92 + 93 + int pq2_fixup_clocks(u32 crystal) 94 + { 95 + u32 sysfreq, corefreq, timebase, brgfreq; 96 + 97 + if (!pq2_get_clocks(crystal, &sysfreq, &corefreq, &timebase, &brgfreq)) 98 + return 0; 99 + 100 + pq2_set_clocks(sysfreq, corefreq, timebase, brgfreq); 101 + return 1; 102 + }
+11
arch/powerpc/boot/pq2.h
··· 1 + #ifndef _PPC_BOOT_PQ2_H_ 2 + #define _PPC_BOOT_PQ2_H_ 3 + 4 + #include "types.h" 5 + 6 + int pq2_get_clocks(u32 crystal, u32 *sysfreq, u32 *corefreq, 7 + u32 *timebase, u32 *brgfreq); 8 + void pq2_set_clocks(u32 sysfreq, u32 corefreq, u32 timebase, u32 brgfreq); 9 + int pq2_fixup_clocks(u32 crystal); 10 + 11 + #endif