mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	[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>
This commit is contained in:
		
							parent
							
								
									568091512d
								
							
						
					
					
						commit
						bbc6fac387
					
				
					 7 changed files with 273 additions and 1 deletions
				
			
		|  | @ -46,7 +46,8 @@ src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \ | |||
| 		ns16550.c serial.c simple_alloc.c div64.S util.S \
 | ||||
| 		gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
 | ||||
| 		4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
 | ||||
| 		cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c | ||||
| 		cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c \
 | ||||
| 		fsl-soc.c mpc8xx.c pq2.c | ||||
| src-plat := of.c cuboot-52xx.c cuboot-83xx.c cuboot-85xx.c holly.c \
 | ||||
| 		cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
 | ||||
| 		ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
 | ||||
|  |  | |||
							
								
								
									
										57
									
								
								arch/powerpc/boot/fsl-soc.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								arch/powerpc/boot/fsl-soc.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,57 @@ | |||
| /*
 | ||||
|  * Freescale SOC support functions | ||||
|  * | ||||
|  * Author: Scott Wood <scottwood@freescale.com> | ||||
|  * | ||||
|  * Copyright (c) 2007 Freescale Semiconductor, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify it | ||||
|  * under the terms of the GNU General Public License version 2 as published | ||||
|  * by the Free Software Foundation. | ||||
|  */ | ||||
| 
 | ||||
| #include "ops.h" | ||||
| #include "types.h" | ||||
| #include "fsl-soc.h" | ||||
| #include "stdio.h" | ||||
| 
 | ||||
| static u32 prop_buf[MAX_PROP_LEN / 4]; | ||||
| 
 | ||||
| u32 *fsl_get_immr(void) | ||||
| { | ||||
| 	void *soc; | ||||
| 	unsigned long ret = 0; | ||||
| 
 | ||||
| 	soc = find_node_by_devtype(NULL, "soc"); | ||||
| 	if (soc) { | ||||
| 		int size; | ||||
| 		u32 naddr; | ||||
| 
 | ||||
| 		size = getprop(soc, "#address-cells", prop_buf, MAX_PROP_LEN); | ||||
| 		if (size == 4) | ||||
| 			naddr = prop_buf[0]; | ||||
| 		else | ||||
| 			naddr = 2; | ||||
| 
 | ||||
| 		if (naddr != 1 && naddr != 2) | ||||
| 			goto err; | ||||
| 
 | ||||
| 		size = getprop(soc, "ranges", prop_buf, MAX_PROP_LEN); | ||||
| 
 | ||||
| 		if (size < 12) | ||||
| 			goto err; | ||||
| 		if (prop_buf[0] != 0) | ||||
| 			goto err; | ||||
| 		if (naddr == 2 && prop_buf[1] != 0) | ||||
| 			goto err; | ||||
| 
 | ||||
| 		if (!dt_xlate_addr(soc, prop_buf + naddr, 8, &ret)) | ||||
| 			ret = 0; | ||||
| 	} | ||||
| 
 | ||||
| err: | ||||
| 	if (!ret) | ||||
| 		printf("fsl_get_immr: Failed to find immr base\r\n"); | ||||
| 
 | ||||
| 	return (u32 *)ret; | ||||
| } | ||||
							
								
								
									
										8
									
								
								arch/powerpc/boot/fsl-soc.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								arch/powerpc/boot/fsl-soc.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| #ifndef _PPC_BOOT_FSL_SOC_H_ | ||||
| #define _PPC_BOOT_FSL_SOC_H_ | ||||
| 
 | ||||
| #include "types.h" | ||||
| 
 | ||||
| u32 *fsl_get_immr(void); | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										82
									
								
								arch/powerpc/boot/mpc8xx.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								arch/powerpc/boot/mpc8xx.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,82 @@ | |||
| /*
 | ||||
|  * MPC8xx support functions | ||||
|  * | ||||
|  * Author: Scott Wood <scottwood@freescale.com> | ||||
|  * | ||||
|  * Copyright (c) 2007 Freescale Semiconductor, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify it | ||||
|  * under the terms of the GNU General Public License version 2 as published | ||||
|  * by the Free Software Foundation. | ||||
|  */ | ||||
| 
 | ||||
| #include "ops.h" | ||||
| #include "types.h" | ||||
| #include "fsl-soc.h" | ||||
| #include "mpc8xx.h" | ||||
| #include "stdio.h" | ||||
| #include "io.h" | ||||
| 
 | ||||
| #define MPC8XX_PLPRCR (0x284/4) /* PLL and Reset Control Register */ | ||||
| 
 | ||||
| /* Return system clock from crystal frequency */ | ||||
| u32 mpc885_get_clock(u32 crystal) | ||||
| { | ||||
| 	u32 *immr; | ||||
| 	u32 plprcr; | ||||
| 	int mfi, mfn, mfd, pdf, div; | ||||
| 	u32 ret; | ||||
| 
 | ||||
| 	immr = fsl_get_immr(); | ||||
| 	if (!immr) { | ||||
| 		printf("mpc885_get_clock: Couldn't get IMMR base.\r\n"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	plprcr = in_be32(&immr[MPC8XX_PLPRCR]); | ||||
| 
 | ||||
| 	mfi = (plprcr >> 16) & 15; | ||||
| 	if (mfi < 5) { | ||||
| 		printf("Warning: PLPRCR[MFI] value of %d out-of-bounds\r\n", | ||||
| 		       mfi); | ||||
| 		mfi = 5; | ||||
| 	} | ||||
| 
 | ||||
| 	pdf = (plprcr >> 1) & 0xf; | ||||
| 	div = (plprcr >> 20) & 3; | ||||
| 	mfd = (plprcr >> 22) & 0x1f; | ||||
| 	mfn = (plprcr >> 27) & 0x1f; | ||||
| 
 | ||||
| 	ret = crystal * mfi; | ||||
| 
 | ||||
| 	if (mfn != 0) | ||||
| 		ret += crystal * mfn / (mfd + 1); | ||||
| 
 | ||||
| 	return ret / (pdf + 1); | ||||
| } | ||||
| 
 | ||||
| /* Set common device tree fields based on the given clock frequencies. */ | ||||
| void mpc8xx_set_clocks(u32 sysclk) | ||||
| { | ||||
| 	void *node; | ||||
| 
 | ||||
| 	dt_fixup_cpu_clocks(sysclk, sysclk / 16, sysclk); | ||||
| 
 | ||||
| 	node = finddevice("/soc/cpm"); | ||||
| 	if (node) | ||||
| 		setprop(node, "clock-frequency", &sysclk, 4); | ||||
| 
 | ||||
| 	node = finddevice("/soc/cpm/brg"); | ||||
| 	if (node) | ||||
| 		setprop(node, "clock-frequency", &sysclk, 4); | ||||
| } | ||||
| 
 | ||||
| int mpc885_fixup_clocks(u32 crystal) | ||||
| { | ||||
| 	u32 sysclk = mpc885_get_clock(crystal); | ||||
| 	if (!sysclk) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	mpc8xx_set_clocks(sysclk); | ||||
| 	return 1; | ||||
| } | ||||
							
								
								
									
										11
									
								
								arch/powerpc/boot/mpc8xx.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								arch/powerpc/boot/mpc8xx.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| #ifndef _PPC_BOOT_MPC8xx_H_ | ||||
| #define _PPC_BOOT_MPC8xx_H_ | ||||
| 
 | ||||
| #include "types.h" | ||||
| 
 | ||||
| void mpc8xx_set_clocks(u32 sysclk); | ||||
| 
 | ||||
| u32 mpc885_get_clock(u32 crystal); | ||||
| int mpc885_fixup_clocks(u32 crystal); | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										102
									
								
								arch/powerpc/boot/pq2.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								arch/powerpc/boot/pq2.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,102 @@ | |||
| /*
 | ||||
|  * PowerQUICC II support functions | ||||
|  * | ||||
|  * Author: Scott Wood <scottwood@freescale.com> | ||||
|  * | ||||
|  * Copyright (c) 2007 Freescale Semiconductor, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify it | ||||
|  * under the terms of the GNU General Public License version 2 as published | ||||
|  * by the Free Software Foundation. | ||||
|  */ | ||||
| 
 | ||||
| #include "ops.h" | ||||
| #include "types.h" | ||||
| #include "fsl-soc.h" | ||||
| #include "pq2.h" | ||||
| #include "stdio.h" | ||||
| #include "io.h" | ||||
| 
 | ||||
| #define PQ2_SCCR (0x10c80/4) /* System Clock Configuration Register */ | ||||
| #define PQ2_SCMR (0x10c88/4) /* System Clock Mode Register */ | ||||
| 
 | ||||
| static int pq2_corecnf_map[] = { | ||||
| 	3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, -1, | ||||
| 	6, 5, 13, 2, 14, 4, 15, 9, 0, 11, 8, 10, 16, 12, 7, -1 | ||||
| }; | ||||
| 
 | ||||
| /* Get various clocks from crystal frequency.
 | ||||
|  * Returns zero on failure and non-zero on success. | ||||
|  */ | ||||
| int pq2_get_clocks(u32 crystal, u32 *sysfreq, u32 *corefreq, | ||||
|                    u32 *timebase, u32 *brgfreq) | ||||
| { | ||||
| 	u32 *immr; | ||||
| 	u32 sccr, scmr, mainclk, busclk; | ||||
| 	int corecnf, busdf, plldf, pllmf, dfbrg; | ||||
| 
 | ||||
| 	immr = fsl_get_immr(); | ||||
| 	if (!immr) { | ||||
| 		printf("pq2_get_clocks: Couldn't get IMMR base.\r\n"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	sccr = in_be32(&immr[PQ2_SCCR]); | ||||
| 	scmr = in_be32(&immr[PQ2_SCMR]); | ||||
| 
 | ||||
| 	dfbrg = sccr & 3; | ||||
| 	corecnf = (scmr >> 24) & 0x1f; | ||||
| 	busdf = (scmr >> 20) & 0xf; | ||||
| 	plldf = (scmr >> 12) & 1; | ||||
| 	pllmf = scmr & 0xfff; | ||||
| 
 | ||||
| 	mainclk = crystal * (pllmf + 1) / (plldf + 1); | ||||
| 	busclk = mainclk / (busdf + 1); | ||||
| 
 | ||||
| 	if (sysfreq) | ||||
| 		*sysfreq = mainclk / 2; | ||||
| 	if (timebase) | ||||
| 		*timebase = busclk / 4; | ||||
| 	if (brgfreq) | ||||
| 		*brgfreq = mainclk / (1 << ((dfbrg + 1) * 2)); | ||||
| 
 | ||||
| 	if (corefreq) { | ||||
| 		int coremult = pq2_corecnf_map[corecnf]; | ||||
| 
 | ||||
| 		if (coremult < 0) | ||||
| 			*corefreq = mainclk / 2; | ||||
| 		else if (coremult == 0) | ||||
| 			return 0; | ||||
| 		else | ||||
| 			*corefreq = busclk * coremult / 2; | ||||
| 	} | ||||
| 
 | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| /* Set common device tree fields based on the given clock frequencies. */ | ||||
| void pq2_set_clocks(u32 sysfreq, u32 corefreq, u32 timebase, u32 brgfreq) | ||||
| { | ||||
| 	void *node; | ||||
| 
 | ||||
| 	dt_fixup_cpu_clocks(corefreq, timebase, sysfreq); | ||||
| 
 | ||||
| 	node = finddevice("/soc/cpm"); | ||||
| 	if (node) | ||||
| 		setprop(node, "clock-frequency", &sysfreq, 4); | ||||
| 
 | ||||
| 	node = finddevice("/soc/cpm/brg"); | ||||
| 	if (node) | ||||
| 		setprop(node, "clock-frequency", &brgfreq, 4); | ||||
| } | ||||
| 
 | ||||
| int pq2_fixup_clocks(u32 crystal) | ||||
| { | ||||
| 	u32 sysfreq, corefreq, timebase, brgfreq; | ||||
| 
 | ||||
| 	if (!pq2_get_clocks(crystal, &sysfreq, &corefreq, &timebase, &brgfreq)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	pq2_set_clocks(sysfreq, corefreq, timebase, brgfreq); | ||||
| 	return 1; | ||||
| } | ||||
							
								
								
									
										11
									
								
								arch/powerpc/boot/pq2.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								arch/powerpc/boot/pq2.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| #ifndef _PPC_BOOT_PQ2_H_ | ||||
| #define _PPC_BOOT_PQ2_H_ | ||||
| 
 | ||||
| #include "types.h" | ||||
| 
 | ||||
| int pq2_get_clocks(u32 crystal, u32 *sysfreq, u32 *corefreq, | ||||
|                    u32 *timebase, u32 *brgfreq); | ||||
| void pq2_set_clocks(u32 sysfreq, u32 corefreq, u32 timebase, u32 brgfreq); | ||||
| int pq2_fixup_clocks(u32 crystal); | ||||
| 
 | ||||
| #endif | ||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Scott Wood
						Scott Wood