-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[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>
- Loading branch information
Scott Wood
authored and
Kumar Gala
committed
Oct 4, 2007
1 parent
5680915
commit bbc6fac
Showing
7 changed files
with
273 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |