From ebf9d5261efc7a60eac54b675b67e3c7ab614f60 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 21 May 2010 03:02:16 -0500 Subject: [PATCH] Move ICS CLK chip frequency 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 Acked-by: Timur Tabi --- 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 df289aa634..d18445be64 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 0000000000..89d8810f74 --- /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 +#include + +#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 0000000000..db3dbc41f7 --- /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 f0ff209c0c..be4b2eb478 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 66be725c8a..99555012f8 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. -- 2.30.2