[U-Boot] [PATCH] Move ICS CLK chip frequenty calculation code into a common board library

We have several boards that use the same ICS307 CLK chip to drive the System clock and DDR clock. Move the code into a common location so we share it.
Convert the P2020DS board as the first to use the new common ICS307 code.
Signed-off-by: Kumar Gala galak@kernel.crashing.org --- board/freescale/common/Makefile | 1 + board/freescale/common/ics307_clk.c | 101 +++++++++++++++++++++++ board/freescale/common/ics307_clk.h | 30 +++++++ board/freescale/p2020ds/p2020ds.c | 149 ----------------------------------- include/configs/P2020DS.h | 16 +--- 5 files changed, 137 insertions(+), 160 deletions(-) create mode 100644 board/freescale/common/ics307_clk.c create mode 100644 board/freescale/common/ics307_clk.h
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index df289aa..d18445b 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -42,6 +42,7 @@ COBJS-$(CONFIG_MPC8541CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8548CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8555CDS) += cds_pci_ft.o
+COBJS-$(CONFIG_P2020DS) += ics307_clk.o
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/board/freescale/common/ics307_clk.c b/board/freescale/common/ics307_clk.c new file mode 100644 index 0000000..1090848 --- /dev/null +++ b/board/freescale/common/ics307_clk.c @@ -0,0 +1,101 @@ +/* + * Copyright 2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> + +#include "ics307_clk.h" + +#ifdef CONFIG_FSL_NGPIXIS +#include "ngpixis.h" +#define PIXIS_VSYSCLK0 offsetof(struct ngpixis, sclk[0]) +#define PIXIS_VSYSCLK1 offsetof(struct ngpixis, sclk[1]) +#define PIXIS_VSYSCLK2 offsetof(struct ngpixis, sclk[2]) +#define PIXIS_VDDRCLK0 offsetof(struct ngpixis, dclk[0]) +#define PIXIS_VDDRCLK1 offsetof(struct ngpixis, dclk[1]) +#define PIXIS_VDDRCLK2 offsetof(struct ngpixis, dclk[2]) +#endif + +/* decode S[0-2] to Output Divider (OD) */ +static unsigned char ics307_s_to_od[] = { + 10, 2, 8, 4, 5, 7, 3, 6 +}; + +/* + * Calculate frequency being generated by ICS307-02 clock chip based upon + * the control bytes being programmed into it. + */ +static unsigned long +ics307_clk_freq(unsigned char cw0, unsigned char cw1, unsigned char cw2) +{ + const unsigned long input_freq = CONFIG_ICS307_REFCLK_HZ; + unsigned long VDW = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1); + unsigned long RDW = cw2 & 0x7F; + unsigned long OD = ics307_s_to_od[cw0 & 0x7]; + unsigned long freq; + + /* + * CLK1 Freq = Input Frequency * 2 * (VDW + 8) / ((RDW + 2) * OD) + * + * cw0: C1 C0 TTL F1 F0 S2 S1 S0 + * cw1: V8 V7 V6 V5 V4 V3 V2 V1 + * cw2: V0 R6 R5 R4 R3 R2 R1 R0 + * + * R6:R0 = Reference Divider Word (RDW) + * V8:V0 = VCO Divider Word (VDW) + * S2:S0 = Output Divider Select (OD) + * F1:F0 = Function of CLK2 Output + * TTL = duty cycle + * C1:C0 = internal load capacitance for cyrstal + * + * Adding 1 to get a "nicely" rounded number, but this needs + * more tweaking to get a "properly" rounded number. + */ + + freq = 1 + (input_freq * 2 * (VDW + 8) / ((RDW + 2) * OD)); + + debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2, + freq); + return freq; +} + +unsigned long get_board_sys_clk(void) +{ + u8 *pixis_base = (u8 *)PIXIS_BASE; + + return ics307_clk_freq ( + in_8(pixis_base + PIXIS_VSYSCLK0), + in_8(pixis_base + PIXIS_VSYSCLK1), + in_8(pixis_base + PIXIS_VSYSCLK2) + ); +} + +unsigned long get_board_ddr_clk(void) +{ + u8 *pixis_base = (u8 *)PIXIS_BASE; + + return ics307_clk_freq ( + in_8(pixis_base + PIXIS_VDDRCLK0), + in_8(pixis_base + PIXIS_VDDRCLK1), + in_8(pixis_base + PIXIS_VDDRCLK2) + ); +} diff --git a/board/freescale/common/ics307_clk.h b/board/freescale/common/ics307_clk.h new file mode 100644 index 0000000..db3dbc4 --- /dev/null +++ b/board/freescale/common/ics307_clk.h @@ -0,0 +1,30 @@ +/* + * Copyright 2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __ICS_CLK_H_ +#define __ICS_CLK_H_ 1 + +#ifndef __ASSEMBLY__ +extern unsigned long get_board_sys_clk(void); +extern unsigned long get_board_ddr_clk(void); +#endif + +#endif /* __ICS_CLK_H_ */ diff --git a/board/freescale/p2020ds/p2020ds.c b/board/freescale/p2020ds/p2020ds.c index 7b76be8..3935636 100644 --- a/board/freescale/p2020ds/p2020ds.c +++ b/board/freescale/p2020ds/p2020ds.c @@ -326,155 +326,6 @@ int board_early_init_r(void) return 0; }
-#ifdef CONFIG_GET_CLK_FROM_ICS307 -/* decode S[0-2] to Output Divider (OD) */ -static unsigned char ics307_S_to_OD[] = { - 10, 2, 8, 4, 5, 7, 3, 6 -}; - -/* Calculate frequency being generated by ICS307-02 clock chip based upon - * the control bytes being programmed into it. */ -/* XXX: This function should probably go into a common library */ -static unsigned long -ics307_clk_freq(unsigned char cw0, unsigned char cw1, unsigned char cw2) -{ - const unsigned long InputFrequency = CONFIG_ICS307_REFCLK_HZ; - unsigned long VDW = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1); - unsigned long RDW = cw2 & 0x7F; - unsigned long OD = ics307_S_to_OD[cw0 & 0x7]; - unsigned long freq; - - /* CLK1Frequency = InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD) */ - - /* cw0: C1 C0 TTL F1 F0 S2 S1 S0 - * cw1: V8 V7 V6 V5 V4 V3 V2 V1 - * cw2: V0 R6 R5 R4 R3 R2 R1 R0 - * - * R6:R0 = Reference Divider Word (RDW) - * V8:V0 = VCO Divider Word (VDW) - * S2:S0 = Output Divider Select (OD) - * F1:F0 = Function of CLK2 Output - * TTL = duty cycle - * C1:C0 = internal load capacitance for cyrstal - */ - - /* Adding 1 to get a "nicely" rounded number, but this needs - * more tweaking to get a "properly" rounded number. */ - - freq = 1 + (InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD)); - - debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2, - freq); - return freq; -} - -unsigned long get_board_sys_clk(ulong dummy) -{ - return gd->bus_clk; -} - -unsigned long get_board_ddr_clk(ulong dummy) -{ - return gd->mem_clk; -} - -unsigned long calculate_board_sys_clk(ulong dummy) -{ - ulong val; - - val = ics307_clk_freq(in_8(&pixis->sclk[0]), in_8(&pixis->sclk[1]), - in_8(&pixis->sclk[2])); - debug("sysclk val = %lu\n", val); - return val; -} - -unsigned long calculate_board_ddr_clk(ulong dummy) -{ - ulong val; - - val = ics307_clk_freq(in_8(&pixis->dclk[0]), in_8(&pixis->dclk[1]), - in_8(&pixis->dclk[2])); - debug("ddrclk val = %lu\n", val); - return val; -} -#else -unsigned long get_board_sys_clk(ulong dummy) -{ - u8 i; - ulong val = 0; - - i = in_8(&pixis->spd); - i &= 0x07; - - switch (i) { - case 0: - val = 33333333; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66666666; - break; - case 4: - val = 83333333; - break; - case 5: - val = 100000000; - break; - case 6: - val = 133333333; - break; - case 7: - val = 166666666; - break; - } - - return val; -} - -unsigned long get_board_ddr_clk(ulong dummy) -{ - u8 i; - ulong val = 0; - - i = in_8(&pixis->spd); - i &= 0x38; - i >>= 3; - - switch (i) { - case 0: - val = 33333333; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66666666; - break; - case 4: - val = 83333333; - break; - case 5: - val = 100000000; - break; - case 6: - val = 133333333; - break; - case 7: - val = 166666666; - break; - } - return val; -} -#endif - #ifdef CONFIG_TSEC_ENET int board_eth_init(bd_t *bis) { diff --git a/include/configs/P2020DS.h b/include/configs/P2020DS.h index 66be725..9955501 100644 --- a/include/configs/P2020DS.h +++ b/include/configs/P2020DS.h @@ -1,5 +1,5 @@ /* - * Copyright 2007-2009 Freescale Semiconductor, Inc. + * Copyright 2007-2010 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -27,6 +27,8 @@ #ifndef __CONFIG_H #define __CONFIG_H
+#include "../board/freescale/common/ics307_clk.h" + #ifdef CONFIG_MK_36BIT #define CONFIG_PHYS_64BIT #endif @@ -54,17 +56,9 @@ #define CONFIG_TSEC_ENET /* tsec ethernet support */ #define CONFIG_ENV_OVERWRITE
-#ifndef __ASSEMBLY__ -extern unsigned long calculate_board_sys_clk(unsigned long dummy); -extern unsigned long calculate_board_ddr_clk(unsigned long dummy); -/* extern unsigned long get_board_sys_clk(unsigned long dummy); */ -/* extern unsigned long get_board_ddr_clk(unsigned long dummy); */ -#endif -#define CONFIG_SYS_CLK_FREQ calculate_board_sys_clk(0) /* sysclk for MPC85xx */ -#define CONFIG_DDR_CLK_FREQ calculate_board_ddr_clk(0) /* ddrclk for MPC85xx */ +#define CONFIG_SYS_CLK_FREQ get_board_sys_clk() /* sysclk for MPC85xx */ +#define CONFIG_DDR_CLK_FREQ get_board_ddr_clk() /* ddrclk for MPC85xx */ #define CONFIG_ICS307_REFCLK_HZ 33333000 /* ICS307 clock chip ref freq */ -#define CONFIG_GET_CLK_FROM_ICS307 /* decode sysclk and ddrclk freq - from ICS307 instead of switches */
/* * These can be toggled for performance analysis, otherwise use default.

Signed-off-by: Kumar Gala galak@kernel.crashing.org --- board/freescale/common/Makefile | 1 + board/freescale/mpc8572ds/mpc8572ds.c | 145 +-------------------------------- include/configs/MPC8572DS.h | 14 +-- 3 files changed, 7 insertions(+), 153 deletions(-)
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index d18445b..3498638 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -42,6 +42,7 @@ COBJS-$(CONFIG_MPC8541CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8548CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8555CDS) += cds_pci_ft.o
+COBJS-$(CONFIG_MPC8572DS) += ics307_clk.o COBJS-$(CONFIG_P2020DS) += ics307_clk.o
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) diff --git a/board/freescale/mpc8572ds/mpc8572ds.c b/board/freescale/mpc8572ds/mpc8572ds.c index 6029a51..81d481a 100644 --- a/board/freescale/mpc8572ds/mpc8572ds.c +++ b/board/freescale/mpc8572ds/mpc8572ds.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2009 Freescale Semiconductor, Inc. + * Copyright 2007-2010 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -284,149 +284,6 @@ int board_early_init_r(void) return 0; }
-#ifdef CONFIG_GET_CLK_FROM_ICS307 -/* decode S[0-2] to Output Divider (OD) */ -static unsigned char ics307_S_to_OD[] = { - 10, 2, 8, 4, 5, 7, 3, 6 -}; - -/* Calculate frequency being generated by ICS307-02 clock chip based upon - * the control bytes being programmed into it. */ -/* XXX: This function should probably go into a common library */ -static unsigned long -ics307_clk_freq (unsigned char cw0, unsigned char cw1, unsigned char cw2) -{ - const unsigned long InputFrequency = CONFIG_ICS307_REFCLK_HZ; - unsigned long VDW = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1); - unsigned long RDW = cw2 & 0x7F; - unsigned long OD = ics307_S_to_OD[cw0 & 0x7]; - unsigned long freq; - - /* CLK1Frequency = InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD) */ - - /* cw0: C1 C0 TTL F1 F0 S2 S1 S0 - * cw1: V8 V7 V6 V5 V4 V3 V2 V1 - * cw2: V0 R6 R5 R4 R3 R2 R1 R0 - * - * R6:R0 = Reference Divider Word (RDW) - * V8:V0 = VCO Divider Word (VDW) - * S2:S0 = Output Divider Select (OD) - * F1:F0 = Function of CLK2 Output - * TTL = duty cycle - * C1:C0 = internal load capacitance for cyrstal - */ - - /* Adding 1 to get a "nicely" rounded number, but this needs - * more tweaking to get a "properly" rounded number. */ - - freq = 1 + (InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD)); - - debug("ICS307: CW[0-2]: %02X %02X %02X => %u Hz\n", cw0, cw1, cw2, - freq); - return freq; -} - -unsigned long get_board_sys_clk(ulong dummy) -{ - u8 *pixis_base = (u8 *)PIXIS_BASE; - - return ics307_clk_freq ( - in_8(pixis_base + PIXIS_VSYSCLK0), - in_8(pixis_base + PIXIS_VSYSCLK1), - in_8(pixis_base + PIXIS_VSYSCLK2) - ); -} - -unsigned long get_board_ddr_clk(ulong dummy) -{ - u8 *pixis_base = (u8 *)PIXIS_BASE; - - return ics307_clk_freq ( - in_8(pixis_base + PIXIS_VDDRCLK0), - in_8(pixis_base + PIXIS_VDDRCLK1), - in_8(pixis_base + PIXIS_VDDRCLK2) - ); -} -#else -unsigned long get_board_sys_clk(ulong dummy) -{ - u8 i; - ulong val = 0; - u8 *pixis_base = (u8 *)PIXIS_BASE; - - i = in_8(pixis_base + PIXIS_SPD); - i &= 0x07; - - switch (i) { - case 0: - val = 33333333; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66666666; - break; - case 4: - val = 83333333; - break; - case 5: - val = 100000000; - break; - case 6: - val = 133333333; - break; - case 7: - val = 166666666; - break; - } - - return val; -} - -unsigned long get_board_ddr_clk(ulong dummy) -{ - u8 i; - ulong val = 0; - u8 *pixis_base = (u8 *)PIXIS_BASE; - - i = in_8(pixis_base + PIXIS_SPD); - i &= 0x38; - i >>= 3; - - switch (i) { - case 0: - val = 33333333; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66666666; - break; - case 4: - val = 83333333; - break; - case 5: - val = 100000000; - break; - case 6: - val = 133333333; - break; - case 7: - val = 166666666; - break; - } - return val; -} -#endif - #ifdef CONFIG_TSEC_ENET int board_eth_init(bd_t *bis) { diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h index 78b7369..41d9662 100644 --- a/include/configs/MPC8572DS.h +++ b/include/configs/MPC8572DS.h @@ -1,5 +1,5 @@ /* - * Copyright 2007-2008 Freescale Semiconductor, Inc. + * Copyright 2007-2008,2010 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -27,6 +27,8 @@ #ifndef __CONFIG_H #define __CONFIG_H
+#include "../board/freescale/common/ics307_clk.h" + #ifdef CONFIG_MK_36BIT #define CONFIG_PHYS_64BIT #endif @@ -53,15 +55,9 @@ #define CONFIG_TSEC_ENET /* tsec ethernet support */ #define CONFIG_ENV_OVERWRITE
-#ifndef __ASSEMBLY__ -extern unsigned long get_board_sys_clk(unsigned long dummy); -extern unsigned long get_board_ddr_clk(unsigned long dummy); -#endif -#define CONFIG_SYS_CLK_FREQ get_board_sys_clk(0) /* sysclk for MPC85xx */ -#define CONFIG_DDR_CLK_FREQ get_board_ddr_clk(0) /* ddrclk for MPC85xx */ +#define CONFIG_SYS_CLK_FREQ get_board_sys_clk() /* sysclk for MPC85xx */ +#define CONFIG_DDR_CLK_FREQ get_board_ddr_clk() /* ddrclk for MPC85xx */ #define CONFIG_ICS307_REFCLK_HZ 33333000 /* ICS307 clock chip ref freq */ -#define CONFIG_GET_CLK_FROM_ICS307 /* decode sysclk and ddrclk freq - from ICS307 instead of switches */
/* * These can be toggled for performance analysis, otherwise use default.

Signed-off-by: Kumar Gala galak@kernel.crashing.org --- board/freescale/common/Makefile | 1 + board/freescale/mpc8536ds/mpc8536ds.c | 148 --------------------------------- include/configs/MPC8536DS.h | 14 +-- 3 files changed, 6 insertions(+), 157 deletions(-)
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 3498638..bd6a09d 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -42,6 +42,7 @@ COBJS-$(CONFIG_MPC8541CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8548CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8555CDS) += cds_pci_ft.o
+COBJS-$(CONFIG_MPC8536DS) += ics307_clk.o COBJS-$(CONFIG_MPC8572DS) += ics307_clk.o COBJS-$(CONFIG_P2020DS) += ics307_clk.o
diff --git a/board/freescale/mpc8536ds/mpc8536ds.c b/board/freescale/mpc8536ds/mpc8536ds.c index 1968106..50ca3ca 100644 --- a/board/freescale/mpc8536ds/mpc8536ds.c +++ b/board/freescale/mpc8536ds/mpc8536ds.c @@ -350,154 +350,6 @@ int board_early_init_r(void) return 0; }
-#ifdef CONFIG_GET_CLK_FROM_ICS307 -/* decode S[0-2] to Output Divider (OD) */ -static unsigned char -ics307_S_to_OD[] = { - 10, 2, 8, 4, 5, 7, 3, 6 -}; - -/* Calculate frequency being generated by ICS307-02 clock chip based upon - * the control bytes being programmed into it. */ -/* XXX: This function should probably go into a common library */ -static unsigned long -ics307_clk_freq (unsigned char cw0, unsigned char cw1, unsigned char cw2) -{ - const unsigned long long InputFrequency = CONFIG_ICS307_REFCLK_HZ; - unsigned long VDW = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1); - unsigned long RDW = cw2 & 0x7F; - unsigned long OD = ics307_S_to_OD[cw0 & 0x7]; - unsigned long freq; - - /* CLK1Frequency = InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD) */ - - /* cw0: C1 C0 TTL F1 F0 S2 S1 S0 - * cw1: V8 V7 V6 V5 V4 V3 V2 V1 - * cw2: V0 R6 R5 R4 R3 R2 R1 R0 - * - * R6:R0 = Reference Divider Word (RDW) - * V8:V0 = VCO Divider Word (VDW) - * S2:S0 = Output Divider Select (OD) - * F1:F0 = Function of CLK2 Output - * TTL = duty cycle - * C1:C0 = internal load capacitance for cyrstal - */ - - /* Adding 1 to get a "nicely" rounded number, but this needs - * more tweaking to get a "properly" rounded number. */ - - freq = 1 + (InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD)); - - debug("ICS307: CW[0-2]: %02X %02X %02X => %u Hz\n", cw0, cw1, cw2, - freq); - return freq; -} - -unsigned long -get_board_sys_clk(ulong dummy) -{ - u8 *pixis_base = (u8 *)PIXIS_BASE; - - return ics307_clk_freq ( - in_8(pixis_base + PIXIS_VSYSCLK0), - in_8(pixis_base + PIXIS_VSYSCLK1), - in_8(pixis_base + PIXIS_VSYSCLK2) - ); -} - -unsigned long -get_board_ddr_clk(ulong dummy) -{ - u8 *pixis_base = (u8 *)PIXIS_BASE; - - return ics307_clk_freq ( - in_8(pixis_base + PIXIS_VDDRCLK0), - in_8(pixis_base + PIXIS_VDDRCLK1), - in_8(pixis_base + PIXIS_VDDRCLK2) - ); -} -#else -unsigned long -get_board_sys_clk(ulong dummy) -{ - u8 i; - ulong val = 0; - u8 *pixis_base = (u8 *)PIXIS_BASE; - - i = in_8(pixis_base + PIXIS_SPD); - i &= 0x07; - - switch (i) { - case 0: - val = 33333333; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66666666; - break; - case 4: - val = 83333333; - break; - case 5: - val = 100000000; - break; - case 6: - val = 133333333; - break; - case 7: - val = 166666666; - break; - } - - return val; -} - -unsigned long -get_board_ddr_clk(ulong dummy) -{ - u8 i; - ulong val = 0; - u8 *pixis_base = (u8 *)PIXIS_BASE; - - i = in_8(pixis_base + PIXIS_SPD); - i &= 0x38; - i >>= 3; - - switch (i) { - case 0: - val = 33333333; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66666666; - break; - case 4: - val = 83333333; - break; - case 5: - val = 100000000; - break; - case 6: - val = 133333333; - break; - case 7: - val = 166666666; - break; - } - return val; -} -#endif - int board_eth_init(bd_t *bis) { #ifdef CONFIG_TSEC_ENET diff --git a/include/configs/MPC8536DS.h b/include/configs/MPC8536DS.h index da4313a..c52b605 100644 --- a/include/configs/MPC8536DS.h +++ b/include/configs/MPC8536DS.h @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009 Freescale Semiconductor, Inc. + * Copyright 2007-2009,2010 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -27,6 +27,8 @@ #ifndef __CONFIG_H #define __CONFIG_H
+#include "../board/freescale/common/ics307_clk.h" + #ifdef CONFIG_MK_36BIT #define CONFIG_PHYS_64BIT 1 #endif @@ -70,15 +72,9 @@ #define CONFIG_TSEC_ENET /* tsec ethernet support */ #define CONFIG_ENV_OVERWRITE
-#ifndef __ASSEMBLY__ -extern unsigned long get_board_sys_clk(unsigned long dummy); -extern unsigned long get_board_ddr_clk(unsigned long dummy); -#endif -#define CONFIG_SYS_CLK_FREQ get_board_sys_clk(0) /* sysclk for MPC85xx */ -#define CONFIG_DDR_CLK_FREQ get_board_ddr_clk(0) +#define CONFIG_SYS_CLK_FREQ get_board_sys_clk() /* sysclk for MPC85xx */ +#define CONFIG_DDR_CLK_FREQ get_board_ddr_clk() #define CONFIG_ICS307_REFCLK_HZ 33333000 /* ICS307 clock chip ref freq */ -#define CONFIG_GET_CLK_FROM_ICS307 /* decode sysclk and ddrclk freq - from ICS307 instead of switches */
/* * These can be toggled for performance analysis, otherwise use default.

On Fri, May 21, 2010 at 4:18 AM, Kumar Gala galak@kernel.crashing.org wrote:
+#ifdef CONFIG_FSL_NGPIXIS +#include "ngpixis.h" +#define PIXIS_VSYSCLK0 offsetof(struct ngpixis, sclk[0]) +#define PIXIS_VSYSCLK1 offsetof(struct ngpixis, sclk[1]) +#define PIXIS_VSYSCLK2 offsetof(struct ngpixis, sclk[2]) +#define PIXIS_VDDRCLK0 offsetof(struct ngpixis, dclk[0]) +#define PIXIS_VDDRCLK1 offsetof(struct ngpixis, dclk[1]) +#define PIXIS_VDDRCLK2 offsetof(struct ngpixis, dclk[2]) +#endif
Yuck. I specifically created the ngpixis_t structure because Wolfgang objected to the use of macros for offsets.
But I understand why you did it. It's the easiest way to maintain compatibility between pixis and ngpixis.
+/* decode S[0-2] to Output Divider (OD) */ +static unsigned char ics307_s_to_od[] = {
- 10, 2, 8, 4, 5, 7, 3, 6
+};
Can you make this a u8 instead?
+static unsigned long +ics307_clk_freq(unsigned char cw0, unsigned char cw1, unsigned char cw2)
u8's here, also. You might then be able to make this one line.
+{
- const unsigned long input_freq = CONFIG_ICS307_REFCLK_HZ;
- unsigned long VDW = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1);
- unsigned long RDW = cw2 & 0x7F;
- unsigned long OD = ics307_s_to_od[cw0 & 0x7];
- unsigned long freq;
Wolfgang just asked me not to use camel caps.
+#ifndef __ASSEMBLY__ +extern unsigned long get_board_sys_clk(void); +extern unsigned long get_board_ddr_clk(void); +#endif
I don't think we need the "#ifndef __ASSEMBLY__" here.

On May 21, 2010, at 10:57 AM, Timur Tabi wrote:
On Fri, May 21, 2010 at 4:18 AM, Kumar Gala galak@kernel.crashing.org wrote:
+#ifdef CONFIG_FSL_NGPIXIS +#include "ngpixis.h" +#define PIXIS_VSYSCLK0 offsetof(struct ngpixis, sclk[0]) +#define PIXIS_VSYSCLK1 offsetof(struct ngpixis, sclk[1]) +#define PIXIS_VSYSCLK2 offsetof(struct ngpixis, sclk[2]) +#define PIXIS_VDDRCLK0 offsetof(struct ngpixis, dclk[0]) +#define PIXIS_VDDRCLK1 offsetof(struct ngpixis, dclk[1]) +#define PIXIS_VDDRCLK2 offsetof(struct ngpixis, dclk[2]) +#endif
Yuck. I specifically created the ngpixis_t structure because Wolfgang objected to the use of macros for offsets.
But I understand why you did it. It's the easiest way to maintain compatibility between pixis and ngpixis.
+/* decode S[0-2] to Output Divider (OD) */ +static unsigned char ics307_s_to_od[] = {
10, 2, 8, 4, 5, 7, 3, 6
+};
Can you make this a u8 instead?
+static unsigned long +ics307_clk_freq(unsigned char cw0, unsigned char cw1, unsigned char cw2)
u8's here, also. You might then be able to make this one line.
will make this change.
+{
const unsigned long input_freq = CONFIG_ICS307_REFCLK_HZ;
unsigned long VDW = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1);
unsigned long RDW = cw2 & 0x7F;
unsigned long OD = ics307_s_to_od[cw0 & 0x7];
unsigned long freq;
Wolfgang just asked me not to use camel caps.
where are there camel caps?
+#ifndef __ASSEMBLY__ +extern unsigned long get_board_sys_clk(void); +extern unsigned long get_board_ddr_clk(void); +#endif
I don't think we need the "#ifndef __ASSEMBLY__" here.
We do.

Dear Kumar Gala,
In message FA771A99-42EA-4299-9DE1-77AFC32734B2@kernel.crashing.org you wrote:
+{
const unsigned long input_freq = CONFIG_ICS307_REFCLK_HZ;
unsigned long VDW = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1);
unsigned long RDW = cw2 & 0x7F;
unsigned long OD = ics307_s_to_od[cw0 & 0x7];
unsigned long freq;
Wolfgang just asked me not to use camel caps.
where are there camel caps?
There aren't. But we do not allow for ALLCAPS identifiers either (these are reserved for macro names).
Best regards,
Wolfgang Denk

On May 21, 2010, at 10:57 AM, Timur Tabi wrote:
On Fri, May 21, 2010 at 4:18 AM, Kumar Gala galak@kernel.crashing.org wrote:
+#ifdef CONFIG_FSL_NGPIXIS +#include "ngpixis.h" +#define PIXIS_VSYSCLK0 offsetof(struct ngpixis, sclk[0]) +#define PIXIS_VSYSCLK1 offsetof(struct ngpixis, sclk[1]) +#define PIXIS_VSYSCLK2 offsetof(struct ngpixis, sclk[2]) +#define PIXIS_VDDRCLK0 offsetof(struct ngpixis, dclk[0]) +#define PIXIS_VDDRCLK1 offsetof(struct ngpixis, dclk[1]) +#define PIXIS_VDDRCLK2 offsetof(struct ngpixis, dclk[2]) +#endif
Yuck. I specifically created the ngpixis_t structure because Wolfgang objected to the use of macros for offsets.
But I understand why you did it. It's the easiest way to maintain compatibility between pixis and ngpixis.
Wolfgang, is this an issue?
The other option is have 3 different structs:
On p2020: #define PIXIS_VSYSCLK0 offsetof(struct ngpixis, sclk[0]) on 8572: #define PIXIS_VSYSCLK0 0x1C on 8536: #define PIXIS_VSYSCLK0 0x1A
- k

Dear Kumar Gala,
In message 7E86BC8F-7E3F-49B1-B1C5-B21991303AF5@kernel.crashing.org you wrote:
galak@kernel.crashing.org wrote:
+#ifdef CONFIG_FSL_NGPIXIS +#include "ngpixis.h" +#define PIXIS_VSYSCLK0 offsetof(struct ngpixis, sclk[0]) +#define PIXIS_VSYSCLK1 offsetof(struct ngpixis, sclk[1]) +#define PIXIS_VSYSCLK2 offsetof(struct ngpixis, sclk[2]) +#define PIXIS_VDDRCLK0 offsetof(struct ngpixis, dclk[0]) +#define PIXIS_VDDRCLK1 offsetof(struct ngpixis, dclk[1]) +#define PIXIS_VDDRCLK2 offsetof(struct ngpixis, dclk[2]) +#endif
Yuck. I specifically created the ngpixis_t structure because Wolfgang objected to the use of macros for offsets.
But I understand why you did it. It's the easiest way to maintain compatibility between pixis and ngpixis.
Wolfgang, is this an issue?
This, in itself, it not an issue.
The issue comes when you wrote code like this:
+ return ics307_clk_freq ( + in_8(pixis_base + PIXIS_VSYSCLK0), + in_8(pixis_base + PIXIS_VSYSCLK1), + in_8(pixis_base + PIXIS_VSYSCLK2) + ); +} + +unsigned long get_board_ddr_clk(void) +{ + u8 *pixis_base = (u8 *)PIXIS_BASE; + + return ics307_clk_freq ( + in_8(pixis_base + PIXIS_VDDRCLK0), + in_8(pixis_base + PIXIS_VDDRCLK1), + in_8(pixis_base + PIXIS_VDDRCLK2) + );
This clearly gets a NAK because you should use a struct, and not base address + offset notation.
The other option is have 3 different structs:
On p2020: #define PIXIS_VSYSCLK0 offsetof(struct ngpixis, > sclk[0]) on 8572: #define PIXIS_VSYSCLK0 0x1C on 8536: #define PIXIS_VSYSCLK0 0x1A
I see #defines here, no structs.
I'm not sure if you need different structs (haven't looked into these), or if clever notation of the struct is sufficient.
Best regards,
Wolfgang Denk

On Fri, May 21, 2010 at 4:18 AM, Kumar Gala galak@kernel.crashing.org wrote:
+COBJS-$(CONFIG_P2020DS) += ics307_clk.o
How about changing this to:
COBJS-$(CONFIG_ICS307_REFCLK_HZ) += ics307_clk.o

On May 21, 2010, at 1:42 PM, Timur Tabi wrote:
On Fri, May 21, 2010 at 4:18 AM, Kumar Gala galak@kernel.crashing.org wrote:
+COBJS-$(CONFIG_P2020DS) += ics307_clk.o
How about changing this to:
COBJS-$(CONFIG_ICS307_REFCLK_HZ) += ics307_clk.o
I'd rather it be board explicit so new boards ports have to decide if they want to use the code or not.
- k

On Fri, May 21, 2010 at 4:18 AM, Kumar Gala galak@kernel.crashing.org wrote:
- * Adding 1 to get a "nicely" rounded number, but this needs
- * more tweaking to get a "properly" rounded number.
- */
- freq = 1 + (input_freq * 2 * (VDW + 8) / ((RDW + 2) * OD));
Is this rounding algorithm the reason why I get output like this:
Clock Configuration: CPU0:799.992 MHz, CPU1:799.992 MHz, CCB:399.996 MHz, DDR:299.997 MHz (599.994 MT/s data rate) (Asynchronous), LBC:25 MHz
If so, maybe we should fix it?

On Fri, May 21, 2010 at 1:59 PM, Timur Tabi timur.tabi@gmail.com wrote:
Is this rounding algorithm the reason why I get output like this:
Clock Configuration: CPU0:799.992 MHz, CPU1:799.992 MHz, CCB:399.996 MHz, DDR:299.997 MHz (599.994 MT/s data rate) (Asynchronous), LBC:25 MHz
If so, maybe we should fix it?
To answer my own question: yes.
So here's a better version of that function that rounds to the nearest MHz and is of a proper coding style:
static const unsigned long ics307_clk_freq(unsigned char cw0, unsigned char cw1, unsigned char cw2) { static const u8 s2od[] = { 10, 2, 8, 4, 5, 7, 3, 6 }; unsigned long vdw = (cw1 << 1) | (cw2 >> 7); unsigned long rdw = cw2 & 0x7f; unsigned long od = s2od[cw0 & 0x7]; unsigned long freq;
freq = 2 * CONFIG_ICS307_REFCLK_HZ * (vdw + 8) / ((rdw + 2) * od);
/* Round freq to the nearest MHz */ freq += 500000; freq /= 1000000; freq *= 1000000;
debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2, freq); return freq; }
And the result:
Clock Configuration: CPU0:800 MHz, CPU1:800 MHz, CCB:400 MHz, DDR:300 MHz (600 MT/s data rate) (Asynchronous), LBC:25 MHz

Dear Timur Tabi,
In message AANLkTilJi5KnON3Qd_58DY7xPEGviIiBE1QY0gXoQUvT@mail.gmail.com you wrote:
So here's a better version of that function that rounds to the nearest MHz and is of a proper coding style:
Why do we need that?
And the result:
Clock Configuration: CPU0:800 MHz, CPU1:800 MHz, CCB:400 MHz, DDR:300 MHz (600 MT/s data rate) (Asynchronous), LBC:25 MHz
The result looks ugly (why do we have double spaces after the numbers?, why do the numbers not align vertically?).
This makes me wonder why you use a "%-4s" format in arch/powerpc/cpu/mpc8?xx/cpu.c - may I recommend changing this into "%s" (if you don't care about vertical alignment), or something like "%4s" else?
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
So here's a better version of that function that rounds to the nearest MHz and is of a proper coding style:
Why do we need that?
Um, because you complained about it?
+static unsigned long ics307_clk_freq(unsigned char cw0, unsigned char cw1,
unsigned char cw2)
+{
- const unsigned long InputFrequency = CONFIG_ICS307_REFCLK_HZ;
- unsigned long VDW = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1);
- unsigned long RDW = cw2 & 0x7F;
- unsigned long OD = ics307_S_to_OD[cw0 & 0x7];
- unsigned long freq;
Please do not use any CamelCase or UPPER CASE identifiers.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Also, because this is silly:
Clock Configuration: CPU0:799.992 MHz, CPU1:799.992 MHz, CCB:399.996 MHz, DDR:299.997 MHz (599.994 MT/s data rate) (Asynchronous), LBC:25 MHz
Why display 799.992 MHZ when 800 MHz makes more sense?
Clock Configuration: CPU0:800 MHz, CPU1:800 MHz, CCB:400 MHz, DDR:300 MHz (600 MT/s data rate) (Asynchronous), LBC:25 MHz
The result looks ugly (why do we have double spaces after the numbers?, why do the numbers not align vertically?).
This makes me wonder why you use a "%-4s" format in arch/powerpc/cpu/mpc8?xx/cpu.c - may I recommend changing this into "%s" (if you don't care about vertical alignment), or something like "%4s" else?
I'm okay with that.

Dear Timur Tabi,
In message 4BF6E5DF.5020306@freescale.com you wrote:
So here's a better version of that function that rounds to the nearest MHz and is of a proper coding style:
Why do we need that?
Um, because you complained about it?
I mean, why do we need that function? strmhz() already includes rounding. Are you really rounding, or cutting off precsion?
Also, because this is silly:
Clock Configuration: CPU0:799.992 MHz, CPU1:799.992 MHz, CCB:399.996 MHz, DDR:299.997 MHz (599.994 MT/s data rate) (Asynchronous), LBC:25 MHz
Why display 799.992 MHZ when 800 MHz makes more sense?
Hm... does it really make more sense? Or is it just less precise, or do you hush up an error?
799.992 MHz seems to be 24 * 33,333,000 Hz. Are you sure this is the exact quartz frequency on your board? If yes, then the number printed should probably remain 799.992 MHz. Or is it 33,333,333 Hz? Or 33,000,000 ?
Clock Configuration: CPU0:800 MHz, CPU1:800 MHz, CCB:400 MHz, DDR:300 MHz (600 MT/s data rate) (Asynchronous), LBC:25 MHz
The result looks ugly (why do we have double spaces after the numbers?, why do the numbers not align vertically?).
This makes me wonder why you use a "%-4s" format in arch/powerpc/cpu/mpc8?xx/cpu.c - may I recommend changing this into "%s" (if you don't care about vertical alignment), or something like "%4s" else?
I'm okay with that.
Fine.
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
799.992 MHz seems to be 24 * 33,333,000 Hz. Are you sure this is the exact quartz frequency on your board? If yes, then the number printed should probably remain 799.992 MHz. Or is it 33,333,333 Hz? Or 33,000,000 ?
Ok, I see your point. Technically, I am returning a less precise number.
However, the current code adds a 1 to the result, which is definitely wrong. On my board, for example, it returns 99999001, which is not correct. So the existing "rounding" algorithm is broken.
However, I believe that displaying 799.999 MHz instead of 800 MHz is silly. The problem is that strmhz() rounds to the nearest KHz. I wonder if that's really useful. Perhaps we should make it act more like print_size(), where it prints KHz, MHz, or GHz as appropriate, and rounds to the nearest 10th, instead of 1000th.

Dear Timur Tabi,
In message 4BF6ECD0.4060202@freescale.com you wrote:
However, the current code adds a 1 to the result, which is definitely wrong. On my board, for example, it returns 99999001, which is not correct. So the existing "rounding" algorithm is broken.
Agreed.
However, I believe that displaying 799.999 MHz instead of 800 MHz is silly. The problem is that strmhz() rounds to the nearest KHz. I wonder if that's really useful. Perhaps we should make it act more like print_size(), where
Well, the function is "strMHZ", and it prints a frequency in MHz with exactly 3 digits precision - so rounding to the nearest kHz is exactly the right thing to do.
it prints KHz, MHz, or GHz as appropriate, and rounds to the nearest 10th, instead of 1000th.
That would IMHO be less useful, and require changes to MANY boards (essentially all of them) as the output format needs to be adjusted.
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
Well, the function is "strMHZ", and it prints a frequency in MHz with exactly 3 digits precision - so rounding to the nearest kHz is exactly the right thing to do.
Actually, it's not really three significant digits. "799.992" is six significant digits. If you you wanted three, it would have to be "800".
See http://en.wikipedia.org/wiki/Significant_figures
I guess it's a question of taste, but I don't see how printing "799.992 MHz" is better than "800 MHz".
it prints KHz, MHz, or GHz as appropriate, and rounds to the nearest 10th, instead of 1000th.
That would IMHO be less useful, and require changes to MANY boards (essentially all of them) as the output format needs to be adjusted.
How about adding a function to strmhz.c that acts like print_size(), and then the caller can choose which one he wants? We could call it print_hz or print_freq.

On May 21, 2010, at 3:16 PM, Wolfgang Denk wrote:
Dear Timur Tabi,
In message 4BF6E5DF.5020306@freescale.com you wrote:
So here's a better version of that function that rounds to the nearest MHz and is of a proper coding style:
Why do we need that?
Um, because you complained about it?
I mean, why do we need that function? strmhz() already includes rounding. Are you really rounding, or cutting off precsion?
Also, because this is silly:
Clock Configuration: CPU0:799.992 MHz, CPU1:799.992 MHz, CCB:399.996 MHz, DDR:299.997 MHz (599.994 MT/s data rate) (Asynchronous), LBC:25 MHz
Why display 799.992 MHZ when 800 MHz makes more sense?
Hm... does it really make more sense? Or is it just less precise, or do you hush up an error?
799.992 MHz seems to be 24 * 33,333,000 Hz. Are you sure this is the exact quartz frequency on your board? If yes, then the number printed should probably remain 799.992 MHz. Or is it 33,333,333 Hz? Or 33,000,000 ?
Its a 33,333,000 Hz input crystal so the math is correct. Rounding in the ICS code is wrong.
- k

We have several boards that use the same ICS307 CLK chip to drive the System clock and DDR clock. Move the code into a common location so we share it.
Convert the P2020DS board as the first to use the new common ICS307 code.
Signed-off-by: Kumar Gala galak@kernel.crashing.org --- * Use new common pixis.h for non-NGPIXIS boards * removed caps
board/freescale/common/Makefile | 1 + board/freescale/common/ics307_clk.c | 91 +++++++++++++++++++++ board/freescale/common/ics307_clk.h | 30 +++++++ board/freescale/p2020ds/p2020ds.c | 149 ----------------------------------- include/configs/P2020DS.h | 16 +--- 5 files changed, 127 insertions(+), 160 deletions(-) create mode 100644 board/freescale/common/ics307_clk.c create mode 100644 board/freescale/common/ics307_clk.h
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index df289aa..d18445b 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -42,6 +42,7 @@ COBJS-$(CONFIG_MPC8541CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8548CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8555CDS) += cds_pci_ft.o
+COBJS-$(CONFIG_P2020DS) += ics307_clk.o
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/board/freescale/common/ics307_clk.c b/board/freescale/common/ics307_clk.c new file mode 100644 index 0000000..bca8f90 --- /dev/null +++ b/board/freescale/common/ics307_clk.c @@ -0,0 +1,91 @@ +/* + * Copyright 2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> + +#include "ics307_clk.h" + +#ifdef CONFIG_FSL_NGPIXIS +#include "ngpixis.h" +#else +#include "pixis.h" +#endif + +/* decode S[0-2] to Output Divider (OD) */ +static unsigned char ics307_s_to_od[] = { + 10, 2, 8, 4, 5, 7, 3, 6 +}; + +/* + * Calculate frequency being generated by ICS307-02 clock chip based upon + * the control bytes being programmed into it. + */ +static unsigned long +ics307_clk_freq(unsigned char cw0, unsigned char cw1, unsigned char cw2) +{ + const unsigned long input_freq = CONFIG_ICS307_REFCLK_HZ; + unsigned long vdw = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1); + unsigned long rdw = cw2 & 0x7F; + unsigned long od = ics307_s_to_od[cw0 & 0x7]; + unsigned long freq; + + /* + * CLK1 Freq = Input Frequency * 2 * (VDW + 8) / ((RDW + 2) * OD) + * + * cw0: C1 C0 TTL F1 F0 S2 S1 S0 + * cw1: V8 V7 V6 V5 V4 V3 V2 V1 + * cw2: V0 R6 R5 R4 R3 R2 R1 R0 + * + * R6:R0 = Reference Divider Word (RDW) + * V8:V0 = VCO Divider Word (VDW) + * S2:S0 = Output Divider Select (OD) + * F1:F0 = Function of CLK2 Output + * TTL = duty cycle + * C1:C0 = internal load capacitance for cyrstal + * + * Adding 1 to get a "nicely" rounded number, but this needs + * more tweaking to get a "properly" rounded number. + */ + + freq = 1 + (input_freq * 2 * (vdw + 8) / ((rdw + 2) * od)); + + debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2, + freq); + return freq; +} + +unsigned long get_board_sys_clk(void) +{ + return ics307_clk_freq( + in_8(&pixis->sclk[0]), + in_8(&pixis->sclk[1]), + in_8(&pixis->sclk[2])); +} + +unsigned long get_board_ddr_clk(void) +{ + return ics307_clk_freq( + in_8(&pixis->dclk[0]), + in_8(&pixis->dclk[1]), + in_8(&pixis->dclk[2])); +} diff --git a/board/freescale/common/ics307_clk.h b/board/freescale/common/ics307_clk.h new file mode 100644 index 0000000..db3dbc4 --- /dev/null +++ b/board/freescale/common/ics307_clk.h @@ -0,0 +1,30 @@ +/* + * Copyright 2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __ICS_CLK_H_ +#define __ICS_CLK_H_ 1 + +#ifndef __ASSEMBLY__ +extern unsigned long get_board_sys_clk(void); +extern unsigned long get_board_ddr_clk(void); +#endif + +#endif /* __ICS_CLK_H_ */ diff --git a/board/freescale/p2020ds/p2020ds.c b/board/freescale/p2020ds/p2020ds.c index f0ff209..be4b2eb 100644 --- a/board/freescale/p2020ds/p2020ds.c +++ b/board/freescale/p2020ds/p2020ds.c @@ -313,155 +313,6 @@ int board_early_init_r(void) return 0; }
-#ifdef CONFIG_GET_CLK_FROM_ICS307 -/* decode S[0-2] to Output Divider (OD) */ -static unsigned char ics307_S_to_OD[] = { - 10, 2, 8, 4, 5, 7, 3, 6 -}; - -/* Calculate frequency being generated by ICS307-02 clock chip based upon - * the control bytes being programmed into it. */ -/* XXX: This function should probably go into a common library */ -static unsigned long -ics307_clk_freq(unsigned char cw0, unsigned char cw1, unsigned char cw2) -{ - const unsigned long InputFrequency = CONFIG_ICS307_REFCLK_HZ; - unsigned long VDW = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1); - unsigned long RDW = cw2 & 0x7F; - unsigned long OD = ics307_S_to_OD[cw0 & 0x7]; - unsigned long freq; - - /* CLK1Frequency = InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD) */ - - /* cw0: C1 C0 TTL F1 F0 S2 S1 S0 - * cw1: V8 V7 V6 V5 V4 V3 V2 V1 - * cw2: V0 R6 R5 R4 R3 R2 R1 R0 - * - * R6:R0 = Reference Divider Word (RDW) - * V8:V0 = VCO Divider Word (VDW) - * S2:S0 = Output Divider Select (OD) - * F1:F0 = Function of CLK2 Output - * TTL = duty cycle - * C1:C0 = internal load capacitance for cyrstal - */ - - /* Adding 1 to get a "nicely" rounded number, but this needs - * more tweaking to get a "properly" rounded number. */ - - freq = 1 + (InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD)); - - debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2, - freq); - return freq; -} - -unsigned long get_board_sys_clk(ulong dummy) -{ - return gd->bus_clk; -} - -unsigned long get_board_ddr_clk(ulong dummy) -{ - return gd->mem_clk; -} - -unsigned long calculate_board_sys_clk(ulong dummy) -{ - ulong val; - - val = ics307_clk_freq(in_8(&pixis->sclk[0]), in_8(&pixis->sclk[1]), - in_8(&pixis->sclk[2])); - debug("sysclk val = %lu\n", val); - return val; -} - -unsigned long calculate_board_ddr_clk(ulong dummy) -{ - ulong val; - - val = ics307_clk_freq(in_8(&pixis->dclk[0]), in_8(&pixis->dclk[1]), - in_8(&pixis->dclk[2])); - debug("ddrclk val = %lu\n", val); - return val; -} -#else -unsigned long get_board_sys_clk(ulong dummy) -{ - u8 i; - ulong val = 0; - - i = in_8(&pixis->spd); - i &= 0x07; - - switch (i) { - case 0: - val = 33333333; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66666666; - break; - case 4: - val = 83333333; - break; - case 5: - val = 100000000; - break; - case 6: - val = 133333333; - break; - case 7: - val = 166666666; - break; - } - - return val; -} - -unsigned long get_board_ddr_clk(ulong dummy) -{ - u8 i; - ulong val = 0; - - i = in_8(&pixis->spd); - i &= 0x38; - i >>= 3; - - switch (i) { - case 0: - val = 33333333; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66666666; - break; - case 4: - val = 83333333; - break; - case 5: - val = 100000000; - break; - case 6: - val = 133333333; - break; - case 7: - val = 166666666; - break; - } - return val; -} -#endif - #ifdef CONFIG_TSEC_ENET int board_eth_init(bd_t *bis) { diff --git a/include/configs/P2020DS.h b/include/configs/P2020DS.h index 66be725..9955501 100644 --- a/include/configs/P2020DS.h +++ b/include/configs/P2020DS.h @@ -1,5 +1,5 @@ /* - * Copyright 2007-2009 Freescale Semiconductor, Inc. + * Copyright 2007-2010 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -27,6 +27,8 @@ #ifndef __CONFIG_H #define __CONFIG_H
+#include "../board/freescale/common/ics307_clk.h" + #ifdef CONFIG_MK_36BIT #define CONFIG_PHYS_64BIT #endif @@ -54,17 +56,9 @@ #define CONFIG_TSEC_ENET /* tsec ethernet support */ #define CONFIG_ENV_OVERWRITE
-#ifndef __ASSEMBLY__ -extern unsigned long calculate_board_sys_clk(unsigned long dummy); -extern unsigned long calculate_board_ddr_clk(unsigned long dummy); -/* extern unsigned long get_board_sys_clk(unsigned long dummy); */ -/* extern unsigned long get_board_ddr_clk(unsigned long dummy); */ -#endif -#define CONFIG_SYS_CLK_FREQ calculate_board_sys_clk(0) /* sysclk for MPC85xx */ -#define CONFIG_DDR_CLK_FREQ calculate_board_ddr_clk(0) /* ddrclk for MPC85xx */ +#define CONFIG_SYS_CLK_FREQ get_board_sys_clk() /* sysclk for MPC85xx */ +#define CONFIG_DDR_CLK_FREQ get_board_ddr_clk() /* ddrclk for MPC85xx */ #define CONFIG_ICS307_REFCLK_HZ 33333000 /* ICS307 clock chip ref freq */ -#define CONFIG_GET_CLK_FROM_ICS307 /* decode sysclk and ddrclk freq - from ICS307 instead of switches */
/* * These can be toggled for performance analysis, otherwise use default.

On Sat, May 22, 2010 at 5:36 PM, Kumar Gala galak@kernel.crashing.org wrote:
+static unsigned long +ics307_clk_freq(unsigned char cw0, unsigned char cw1, unsigned char cw2)
You forgot to change these to u8
Also, you can declare this function as "const". You could just use the version of this function that I posted, you just need to remove my rounding code.
- * Adding 1 to get a "nicely" rounded number, but this needs
- * more tweaking to get a "properly" rounded number.
- */
- freq = 1 + (input_freq * 2 * (vdw + 8) / ((rdw + 2) * od));
The "1 +" is wrong and should be removed. It doesn't do what the comment says it does, and as you said earlier, rounding is wrong for this function.

On May 24, 2010, at 9:52 AM, Timur Tabi wrote:
On Sat, May 22, 2010 at 5:36 PM, Kumar Gala galak@kernel.crashing.org wrote:
+static unsigned long +ics307_clk_freq(unsigned char cw0, unsigned char cw1, unsigned char cw2)
You forgot to change these to u8
Oops, thought that was fixed.
Also, you can declare this function as "const". You could just use the version of this function that I posted, you just need to remove my rounding code.
What in the world does 'const' get me in C.
* Adding 1 to get a "nicely" rounded number, but this needs
* more tweaking to get a "properly" rounded number.
*/
freq = 1 + (input_freq * 2 * (vdw + 8) / ((rdw + 2) * od));
The "1 +" is wrong and should be removed. It doesn't do what the comment says it does, and as you said earlier, rounding is wrong for this function.
Dropped the 1+
- k

On Mon, May 24, 2010 at 1:57 PM, Kumar Gala galak@kernel.crashing.org wrote:
What in the world does 'const' get me in C.
Actually, scrap that. A const function tells the compiler that, for a given set of parameters, the returned value is always the same, so the compiler will eliminate redundant calls to the function. But the problem is that it needs to be a const __attribute__, and the debug() call would need to be deleted for it to be valid anyway.

We have several boards that use the same ICS307 CLK chip to drive the System clock and DDR clock. Move the code into a common location so we share it.
Convert the P2020DS board as the first to use the new common ICS307 code.
Signed-off-by: Kumar Gala galak@kernel.crashing.org --- * unsigned char -> u8 * remove 1 +
board/freescale/common/Makefile | 1 + board/freescale/common/ics307_clk.c | 88 ++++++++++++++++++++ board/freescale/common/ics307_clk.h | 30 +++++++ board/freescale/p2020ds/p2020ds.c | 149 ----------------------------------- include/configs/P2020DS.h | 16 +--- 5 files changed, 124 insertions(+), 160 deletions(-) create mode 100644 board/freescale/common/ics307_clk.c create mode 100644 board/freescale/common/ics307_clk.h
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index df289aa..d18445b 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -42,6 +42,7 @@ COBJS-$(CONFIG_MPC8541CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8548CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8555CDS) += cds_pci_ft.o
+COBJS-$(CONFIG_P2020DS) += ics307_clk.o
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/board/freescale/common/ics307_clk.c b/board/freescale/common/ics307_clk.c new file mode 100644 index 0000000..89d8810 --- /dev/null +++ b/board/freescale/common/ics307_clk.c @@ -0,0 +1,88 @@ +/* + * Copyright 2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> + +#include "ics307_clk.h" + +#ifdef CONFIG_FSL_NGPIXIS +#include "ngpixis.h" +#else +#include "pixis.h" +#endif + +/* decode S[0-2] to Output Divider (OD) */ +static u8 ics307_s_to_od[] = { + 10, 2, 8, 4, 5, 7, 3, 6 +}; + +/* + * Calculate frequency being generated by ICS307-02 clock chip based upon + * the control bytes being programmed into it. + */ +static unsigned long ics307_clk_freq(u8 cw0, u8 cw1, u8 cw2) +{ + const unsigned long input_freq = CONFIG_ICS307_REFCLK_HZ; + unsigned long vdw = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1); + unsigned long rdw = cw2 & 0x7F; + unsigned long od = ics307_s_to_od[cw0 & 0x7]; + unsigned long freq; + + /* + * CLK1 Freq = Input Frequency * 2 * (VDW + 8) / ((RDW + 2) * OD) + * + * cw0: C1 C0 TTL F1 F0 S2 S1 S0 + * cw1: V8 V7 V6 V5 V4 V3 V2 V1 + * cw2: V0 R6 R5 R4 R3 R2 R1 R0 + * + * R6:R0 = Reference Divider Word (RDW) + * V8:V0 = VCO Divider Word (VDW) + * S2:S0 = Output Divider Select (OD) + * F1:F0 = Function of CLK2 Output + * TTL = duty cycle + * C1:C0 = internal load capacitance for cyrstal + * + */ + + freq = input_freq * 2 * (vdw + 8) / ((rdw + 2) * od); + + debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2, + freq); + return freq; +} + +unsigned long get_board_sys_clk(void) +{ + return ics307_clk_freq( + in_8(&pixis->sclk[0]), + in_8(&pixis->sclk[1]), + in_8(&pixis->sclk[2])); +} + +unsigned long get_board_ddr_clk(void) +{ + return ics307_clk_freq( + in_8(&pixis->dclk[0]), + in_8(&pixis->dclk[1]), + in_8(&pixis->dclk[2])); +} diff --git a/board/freescale/common/ics307_clk.h b/board/freescale/common/ics307_clk.h new file mode 100644 index 0000000..db3dbc4 --- /dev/null +++ b/board/freescale/common/ics307_clk.h @@ -0,0 +1,30 @@ +/* + * Copyright 2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __ICS_CLK_H_ +#define __ICS_CLK_H_ 1 + +#ifndef __ASSEMBLY__ +extern unsigned long get_board_sys_clk(void); +extern unsigned long get_board_ddr_clk(void); +#endif + +#endif /* __ICS_CLK_H_ */ diff --git a/board/freescale/p2020ds/p2020ds.c b/board/freescale/p2020ds/p2020ds.c index f0ff209..be4b2eb 100644 --- a/board/freescale/p2020ds/p2020ds.c +++ b/board/freescale/p2020ds/p2020ds.c @@ -313,155 +313,6 @@ int board_early_init_r(void) return 0; }
-#ifdef CONFIG_GET_CLK_FROM_ICS307 -/* decode S[0-2] to Output Divider (OD) */ -static unsigned char ics307_S_to_OD[] = { - 10, 2, 8, 4, 5, 7, 3, 6 -}; - -/* Calculate frequency being generated by ICS307-02 clock chip based upon - * the control bytes being programmed into it. */ -/* XXX: This function should probably go into a common library */ -static unsigned long -ics307_clk_freq(unsigned char cw0, unsigned char cw1, unsigned char cw2) -{ - const unsigned long InputFrequency = CONFIG_ICS307_REFCLK_HZ; - unsigned long VDW = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1); - unsigned long RDW = cw2 & 0x7F; - unsigned long OD = ics307_S_to_OD[cw0 & 0x7]; - unsigned long freq; - - /* CLK1Frequency = InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD) */ - - /* cw0: C1 C0 TTL F1 F0 S2 S1 S0 - * cw1: V8 V7 V6 V5 V4 V3 V2 V1 - * cw2: V0 R6 R5 R4 R3 R2 R1 R0 - * - * R6:R0 = Reference Divider Word (RDW) - * V8:V0 = VCO Divider Word (VDW) - * S2:S0 = Output Divider Select (OD) - * F1:F0 = Function of CLK2 Output - * TTL = duty cycle - * C1:C0 = internal load capacitance for cyrstal - */ - - /* Adding 1 to get a "nicely" rounded number, but this needs - * more tweaking to get a "properly" rounded number. */ - - freq = 1 + (InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD)); - - debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2, - freq); - return freq; -} - -unsigned long get_board_sys_clk(ulong dummy) -{ - return gd->bus_clk; -} - -unsigned long get_board_ddr_clk(ulong dummy) -{ - return gd->mem_clk; -} - -unsigned long calculate_board_sys_clk(ulong dummy) -{ - ulong val; - - val = ics307_clk_freq(in_8(&pixis->sclk[0]), in_8(&pixis->sclk[1]), - in_8(&pixis->sclk[2])); - debug("sysclk val = %lu\n", val); - return val; -} - -unsigned long calculate_board_ddr_clk(ulong dummy) -{ - ulong val; - - val = ics307_clk_freq(in_8(&pixis->dclk[0]), in_8(&pixis->dclk[1]), - in_8(&pixis->dclk[2])); - debug("ddrclk val = %lu\n", val); - return val; -} -#else -unsigned long get_board_sys_clk(ulong dummy) -{ - u8 i; - ulong val = 0; - - i = in_8(&pixis->spd); - i &= 0x07; - - switch (i) { - case 0: - val = 33333333; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66666666; - break; - case 4: - val = 83333333; - break; - case 5: - val = 100000000; - break; - case 6: - val = 133333333; - break; - case 7: - val = 166666666; - break; - } - - return val; -} - -unsigned long get_board_ddr_clk(ulong dummy) -{ - u8 i; - ulong val = 0; - - i = in_8(&pixis->spd); - i &= 0x38; - i >>= 3; - - switch (i) { - case 0: - val = 33333333; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66666666; - break; - case 4: - val = 83333333; - break; - case 5: - val = 100000000; - break; - case 6: - val = 133333333; - break; - case 7: - val = 166666666; - break; - } - return val; -} -#endif - #ifdef CONFIG_TSEC_ENET int board_eth_init(bd_t *bis) { diff --git a/include/configs/P2020DS.h b/include/configs/P2020DS.h index 66be725..9955501 100644 --- a/include/configs/P2020DS.h +++ b/include/configs/P2020DS.h @@ -1,5 +1,5 @@ /* - * Copyright 2007-2009 Freescale Semiconductor, Inc. + * Copyright 2007-2010 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -27,6 +27,8 @@ #ifndef __CONFIG_H #define __CONFIG_H
+#include "../board/freescale/common/ics307_clk.h" + #ifdef CONFIG_MK_36BIT #define CONFIG_PHYS_64BIT #endif @@ -54,17 +56,9 @@ #define CONFIG_TSEC_ENET /* tsec ethernet support */ #define CONFIG_ENV_OVERWRITE
-#ifndef __ASSEMBLY__ -extern unsigned long calculate_board_sys_clk(unsigned long dummy); -extern unsigned long calculate_board_ddr_clk(unsigned long dummy); -/* extern unsigned long get_board_sys_clk(unsigned long dummy); */ -/* extern unsigned long get_board_ddr_clk(unsigned long dummy); */ -#endif -#define CONFIG_SYS_CLK_FREQ calculate_board_sys_clk(0) /* sysclk for MPC85xx */ -#define CONFIG_DDR_CLK_FREQ calculate_board_ddr_clk(0) /* ddrclk for MPC85xx */ +#define CONFIG_SYS_CLK_FREQ get_board_sys_clk() /* sysclk for MPC85xx */ +#define CONFIG_DDR_CLK_FREQ get_board_ddr_clk() /* ddrclk for MPC85xx */ #define CONFIG_ICS307_REFCLK_HZ 33333000 /* ICS307 clock chip ref freq */ -#define CONFIG_GET_CLK_FROM_ICS307 /* decode sysclk and ddrclk freq - from ICS307 instead of switches */
/* * These can be toggled for performance analysis, otherwise use default.

On Mon, May 24, 2010 at 3:09 PM, Kumar Gala galak@kernel.crashing.org wrote:
We have several boards that use the same ICS307 CLK chip to drive the System clock and DDR clock. Move the code into a common location so we share it.
Convert the P2020DS board as the first to use the new common ICS307 code.
Signed-off-by: Kumar Gala galak@kernel.crashing.org
Acked-by: Timur Tabi timur@freescale.com

On May 24, 2010, at 3:09 PM, Kumar Gala wrote:
We have several boards that use the same ICS307 CLK chip to drive the System clock and DDR clock. Move the code into a common location so we share it.
Convert the P2020DS board as the first to use the new common ICS307 code.
Signed-off-by: Kumar Gala galak@kernel.crashing.org
- unsigned char -> u8
- remove 1 +
applied to 85xx
- k

Dear Kumar Gala,
In message 93AA257E-BDBB-4AC9-80D3-D83C7F7B467F@kernel.crashing.org you wrote:
On May 24, 2010, at 3:09 PM, Kumar Gala wrote:
We have several boards that use the same ICS307 CLK chip to drive the System clock and DDR clock. Move the code into a common location so we share it.
Convert the P2020DS board as the first to use the new common ICS307 code.
Signed-off-by: Kumar Gala galak@kernel.crashing.org
- unsigned char -> u8
- remove 1 +
applied to 85xx
Please fix the typo in the Subject when applying (or request a resubmit). Thanks.
Best regards,
Wolfgang Denk

We have several boards that use the same ICS307 CLK chip to drive the System clock and DDR clock. Move the code into a common location so we share it.
Convert the P2020DS board as the first to use the new common ICS307 code.
Signed-off-by: Kumar Gala galak@kernel.crashing.org Acked-by: Timur Tabi timur@freescale.com --- * Fixed commit message spelling
board/freescale/common/Makefile | 1 + board/freescale/common/ics307_clk.c | 88 ++++++++++++++++++++ board/freescale/common/ics307_clk.h | 30 +++++++ board/freescale/p2020ds/p2020ds.c | 149 ----------------------------------- include/configs/P2020DS.h | 16 +--- 5 files changed, 124 insertions(+), 160 deletions(-) create mode 100644 board/freescale/common/ics307_clk.c create mode 100644 board/freescale/common/ics307_clk.h
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index df289aa..d18445b 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -42,6 +42,7 @@ COBJS-$(CONFIG_MPC8541CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8548CDS) += cds_pci_ft.o COBJS-$(CONFIG_MPC8555CDS) += cds_pci_ft.o
+COBJS-$(CONFIG_P2020DS) += ics307_clk.o
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/board/freescale/common/ics307_clk.c b/board/freescale/common/ics307_clk.c new file mode 100644 index 0000000..89d8810 --- /dev/null +++ b/board/freescale/common/ics307_clk.c @@ -0,0 +1,88 @@ +/* + * Copyright 2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> + +#include "ics307_clk.h" + +#ifdef CONFIG_FSL_NGPIXIS +#include "ngpixis.h" +#else +#include "pixis.h" +#endif + +/* decode S[0-2] to Output Divider (OD) */ +static u8 ics307_s_to_od[] = { + 10, 2, 8, 4, 5, 7, 3, 6 +}; + +/* + * Calculate frequency being generated by ICS307-02 clock chip based upon + * the control bytes being programmed into it. + */ +static unsigned long ics307_clk_freq(u8 cw0, u8 cw1, u8 cw2) +{ + const unsigned long input_freq = CONFIG_ICS307_REFCLK_HZ; + unsigned long vdw = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1); + unsigned long rdw = cw2 & 0x7F; + unsigned long od = ics307_s_to_od[cw0 & 0x7]; + unsigned long freq; + + /* + * CLK1 Freq = Input Frequency * 2 * (VDW + 8) / ((RDW + 2) * OD) + * + * cw0: C1 C0 TTL F1 F0 S2 S1 S0 + * cw1: V8 V7 V6 V5 V4 V3 V2 V1 + * cw2: V0 R6 R5 R4 R3 R2 R1 R0 + * + * R6:R0 = Reference Divider Word (RDW) + * V8:V0 = VCO Divider Word (VDW) + * S2:S0 = Output Divider Select (OD) + * F1:F0 = Function of CLK2 Output + * TTL = duty cycle + * C1:C0 = internal load capacitance for cyrstal + * + */ + + freq = input_freq * 2 * (vdw + 8) / ((rdw + 2) * od); + + debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2, + freq); + return freq; +} + +unsigned long get_board_sys_clk(void) +{ + return ics307_clk_freq( + in_8(&pixis->sclk[0]), + in_8(&pixis->sclk[1]), + in_8(&pixis->sclk[2])); +} + +unsigned long get_board_ddr_clk(void) +{ + return ics307_clk_freq( + in_8(&pixis->dclk[0]), + in_8(&pixis->dclk[1]), + in_8(&pixis->dclk[2])); +} diff --git a/board/freescale/common/ics307_clk.h b/board/freescale/common/ics307_clk.h new file mode 100644 index 0000000..db3dbc4 --- /dev/null +++ b/board/freescale/common/ics307_clk.h @@ -0,0 +1,30 @@ +/* + * Copyright 2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __ICS_CLK_H_ +#define __ICS_CLK_H_ 1 + +#ifndef __ASSEMBLY__ +extern unsigned long get_board_sys_clk(void); +extern unsigned long get_board_ddr_clk(void); +#endif + +#endif /* __ICS_CLK_H_ */ diff --git a/board/freescale/p2020ds/p2020ds.c b/board/freescale/p2020ds/p2020ds.c index f0ff209..be4b2eb 100644 --- a/board/freescale/p2020ds/p2020ds.c +++ b/board/freescale/p2020ds/p2020ds.c @@ -313,155 +313,6 @@ int board_early_init_r(void) return 0; }
-#ifdef CONFIG_GET_CLK_FROM_ICS307 -/* decode S[0-2] to Output Divider (OD) */ -static unsigned char ics307_S_to_OD[] = { - 10, 2, 8, 4, 5, 7, 3, 6 -}; - -/* Calculate frequency being generated by ICS307-02 clock chip based upon - * the control bytes being programmed into it. */ -/* XXX: This function should probably go into a common library */ -static unsigned long -ics307_clk_freq(unsigned char cw0, unsigned char cw1, unsigned char cw2) -{ - const unsigned long InputFrequency = CONFIG_ICS307_REFCLK_HZ; - unsigned long VDW = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1); - unsigned long RDW = cw2 & 0x7F; - unsigned long OD = ics307_S_to_OD[cw0 & 0x7]; - unsigned long freq; - - /* CLK1Frequency = InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD) */ - - /* cw0: C1 C0 TTL F1 F0 S2 S1 S0 - * cw1: V8 V7 V6 V5 V4 V3 V2 V1 - * cw2: V0 R6 R5 R4 R3 R2 R1 R0 - * - * R6:R0 = Reference Divider Word (RDW) - * V8:V0 = VCO Divider Word (VDW) - * S2:S0 = Output Divider Select (OD) - * F1:F0 = Function of CLK2 Output - * TTL = duty cycle - * C1:C0 = internal load capacitance for cyrstal - */ - - /* Adding 1 to get a "nicely" rounded number, but this needs - * more tweaking to get a "properly" rounded number. */ - - freq = 1 + (InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD)); - - debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2, - freq); - return freq; -} - -unsigned long get_board_sys_clk(ulong dummy) -{ - return gd->bus_clk; -} - -unsigned long get_board_ddr_clk(ulong dummy) -{ - return gd->mem_clk; -} - -unsigned long calculate_board_sys_clk(ulong dummy) -{ - ulong val; - - val = ics307_clk_freq(in_8(&pixis->sclk[0]), in_8(&pixis->sclk[1]), - in_8(&pixis->sclk[2])); - debug("sysclk val = %lu\n", val); - return val; -} - -unsigned long calculate_board_ddr_clk(ulong dummy) -{ - ulong val; - - val = ics307_clk_freq(in_8(&pixis->dclk[0]), in_8(&pixis->dclk[1]), - in_8(&pixis->dclk[2])); - debug("ddrclk val = %lu\n", val); - return val; -} -#else -unsigned long get_board_sys_clk(ulong dummy) -{ - u8 i; - ulong val = 0; - - i = in_8(&pixis->spd); - i &= 0x07; - - switch (i) { - case 0: - val = 33333333; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66666666; - break; - case 4: - val = 83333333; - break; - case 5: - val = 100000000; - break; - case 6: - val = 133333333; - break; - case 7: - val = 166666666; - break; - } - - return val; -} - -unsigned long get_board_ddr_clk(ulong dummy) -{ - u8 i; - ulong val = 0; - - i = in_8(&pixis->spd); - i &= 0x38; - i >>= 3; - - switch (i) { - case 0: - val = 33333333; - break; - case 1: - val = 40000000; - break; - case 2: - val = 50000000; - break; - case 3: - val = 66666666; - break; - case 4: - val = 83333333; - break; - case 5: - val = 100000000; - break; - case 6: - val = 133333333; - break; - case 7: - val = 166666666; - break; - } - return val; -} -#endif - #ifdef CONFIG_TSEC_ENET int board_eth_init(bd_t *bis) { diff --git a/include/configs/P2020DS.h b/include/configs/P2020DS.h index 66be725..9955501 100644 --- a/include/configs/P2020DS.h +++ b/include/configs/P2020DS.h @@ -1,5 +1,5 @@ /* - * Copyright 2007-2009 Freescale Semiconductor, Inc. + * Copyright 2007-2010 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -27,6 +27,8 @@ #ifndef __CONFIG_H #define __CONFIG_H
+#include "../board/freescale/common/ics307_clk.h" + #ifdef CONFIG_MK_36BIT #define CONFIG_PHYS_64BIT #endif @@ -54,17 +56,9 @@ #define CONFIG_TSEC_ENET /* tsec ethernet support */ #define CONFIG_ENV_OVERWRITE
-#ifndef __ASSEMBLY__ -extern unsigned long calculate_board_sys_clk(unsigned long dummy); -extern unsigned long calculate_board_ddr_clk(unsigned long dummy); -/* extern unsigned long get_board_sys_clk(unsigned long dummy); */ -/* extern unsigned long get_board_ddr_clk(unsigned long dummy); */ -#endif -#define CONFIG_SYS_CLK_FREQ calculate_board_sys_clk(0) /* sysclk for MPC85xx */ -#define CONFIG_DDR_CLK_FREQ calculate_board_ddr_clk(0) /* ddrclk for MPC85xx */ +#define CONFIG_SYS_CLK_FREQ get_board_sys_clk() /* sysclk for MPC85xx */ +#define CONFIG_DDR_CLK_FREQ get_board_ddr_clk() /* ddrclk for MPC85xx */ #define CONFIG_ICS307_REFCLK_HZ 33333000 /* ICS307 clock chip ref freq */ -#define CONFIG_GET_CLK_FROM_ICS307 /* decode sysclk and ddrclk freq - from ICS307 instead of switches */
/* * These can be toggled for performance analysis, otherwise use default.
participants (4)
-
Kumar Gala
-
Timur Tabi
-
Timur Tabi
-
Wolfgang Denk