[U-Boot] [patch u-boot git arm/next] davinci: display correct clock info

From: David Brownell dbrownell@users.sourceforge.net
Make the DaVinci clock display code work on the dm355 too ... there are pre- and post- dividers on its PLLs, which most other DaVinci processors don't use; and it uses different PLL dividers. Stubbed in support for the DM6467 too. Verified on dm355 and dm6446.
Signed-off-by: David Brownell dbrownell@users.sourceforge.net --- This should move to cpu/arm926ejs/davinci (cpuinfo.c?) someday, like the other SoC-specific code. For another patch.
board/davinci/common/misc.c | 88 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 5 deletions(-)
--- a/board/davinci/common/misc.c +++ b/board/davinci/common/misc.c @@ -28,6 +28,40 @@ #include <net.h> #include <asm/arch/hardware.h>
+ +/* offsets from PLL controller base */ +#define PLLC_PLLCTL 0x100 +#define PLLC_PLLM 0x110 +#define PLLC_PREDIV 0x114 +#define PLLC_PLLDIV1 0x118 +#define PLLC_PLLDIV2 0x11c +#define PLLC_PLLDIV3 0x120 +#define PLLC_POSTDIV 0x128 +#define PLLC_BPDIV 0x12c +#define PLLC_PLLDIV4 0x160 +#define PLLC_PLLDIV5 0x164 +#define PLLC_PLLDIV6 0x168 +#define PLLC_PLLDIV8 0x170 +#define PLLC_PLLDIV9 0x174 + +#define BIT(x) (1 << (x)) + +/* SOC-specific pll info */ +#ifdef CONFIG_SOC_DM355 +#define ARM_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV1 +#endif + +#ifdef CONFIG_SOC_DM644X +#define ARM_PLLDIV PLLC_PLLDIV2 +#define DDR_PLLDIV PLLC_PLLDIV2 +#endif + +#ifdef CONFIG_SOC_DM6447 +#define ARM_PLLDIV PLLC_PLLDIV2 +#define DDR_PLLDIV PLLC_PLLDIV1 +#endif + DECLARE_GLOBAL_DATA_PTR;
int dram_init(void) @@ -38,16 +72,60 @@ int dram_init(void) return(0); }
-static int dv_get_pllm_output(uint32_t pllm) +static unsigned pll_div(volatile void *pllbase, unsigned offset) { - return (pllm + 1) * (CONFIG_SYS_HZ_CLOCK / 1000000); + u32 div; + + div = REG(pllbase + offset); + return (div & BIT(15)) ? (1 + (div & 0x1f)) : 1; +} + +static inline unsigned pll_prediv(volatile void *pllbase) +{ +#ifdef CONFIG_SOC_DM355 + /* this register read seems to fail on pll0 */ + if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) + return 8; + else + return pll_div(pllbase, PLLC_PREDIV); +#endif + return 1; +} + +static inline unsigned pll_postdiv(volatile void *pllbase) +{ +#ifdef CONFIG_SOC_DM355 + return pll_div(pllbase, PLLC_POSTDIV); +#elif defined(CONFIG_SOC_DM6446) + if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) + return pll_div(pllbase, PLLC_POSTDIV); +#endif + return 1; +} + +static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div) +{ + volatile void *pllbase = (volatile void *) pll_addr; + unsigned base = CONFIG_SYS_HZ_CLOCK / 1000; + + /* the PLL might be bypassed */ + if (REG(pllbase + PLLC_PLLCTL) & BIT(0)) { + base /= pll_prediv(pllbase); + base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff); + base /= pll_postdiv(pllbase); + } + return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div)); }
void dv_display_clk_infos(void) { - printf("ARM Clock: %dMHz\n", dv_get_pllm_output(REG(PLL1_PLLM)) / 2); - printf("DDR Clock: %dMHz\n", dv_get_pllm_output(REG(PLL2_PLLM)) / - ((REG(PLL2_DIV2) & 0x1f) + 1) / 2); + printf("ARM Clock: %dMHz\n", + pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV)); + printf("DDR Clock: %dMHz\n", + /* DDR PHY uses an x2 input clock */ + pll_sysclk_mhz(DAVINCI_PLL_CNTRL1_BASE, DDR_PLLDIV) + / 2); + printf("\n"); }
#ifdef CONFIG_DRIVER_TI_EMAC

On 15:38 Wed 29 Apr , David Brownell wrote:
From: David Brownell dbrownell@users.sourceforge.net
Make the DaVinci clock display code work on the dm355 too ... there are pre- and post- dividers on its PLLs, which most other DaVinci processors don't use; and it uses different PLL dividers. Stubbed in support for the DM6467 too. Verified on dm355 and dm6446.
Signed-off-by: David Brownell dbrownell@users.sourceforge.net
This should move to cpu/arm926ejs/davinci (cpuinfo.c?) someday, like the other SoC-specific code. For another patch.
good idea
cpu.c will be better
btw a clock design as done for at91 & avr32 will be nice too
board/davinci/common/misc.c | 88 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 5 deletions(-)
--- a/board/davinci/common/misc.c +++ b/board/davinci/common/misc.c @@ -28,6 +28,40 @@ #include <net.h> #include <asm/arch/hardware.h>
+/* offsets from PLL controller base */ +#define PLLC_PLLCTL 0x100 +#define PLLC_PLLM 0x110 +#define PLLC_PREDIV 0x114 +#define PLLC_PLLDIV1 0x118 +#define PLLC_PLLDIV2 0x11c +#define PLLC_PLLDIV3 0x120 +#define PLLC_POSTDIV 0x128 +#define PLLC_BPDIV 0x12c +#define PLLC_PLLDIV4 0x160 +#define PLLC_PLLDIV5 0x164 +#define PLLC_PLLDIV6 0x168 +#define PLLC_PLLDIV8 0x170 +#define PLLC_PLLDIV9 0x174
who will init the PLL? can we detect it if they are already init?
+#define BIT(x) (1 << (x))
please remove
+/* SOC-specific pll info */ +#ifdef CONFIG_SOC_DM355 +#define ARM_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV1 +#endif
+#ifdef CONFIG_SOC_DM644X +#define ARM_PLLDIV PLLC_PLLDIV2 +#define DDR_PLLDIV PLLC_PLLDIV2 +#endif
+#ifdef CONFIG_SOC_DM6447 +#define ARM_PLLDIV PLLC_PLLDIV2 +#define DDR_PLLDIV PLLC_PLLDIV1 +#endif
DECLARE_GLOBAL_DATA_PTR;
int dram_init(void) @@ -38,16 +72,60 @@ int dram_init(void) return(0); }
-static int dv_get_pllm_output(uint32_t pllm) +static unsigned pll_div(volatile void *pllbase, unsigned offset) {
- return (pllm + 1) * (CONFIG_SYS_HZ_CLOCK / 1000000);
- u32 div;
- div = REG(pllbase + offset);
- return (div & BIT(15)) ? (1 + (div & 0x1f)) : 1;
+}
+static inline unsigned pll_prediv(volatile void *pllbase) +{ +#ifdef CONFIG_SOC_DM355
- /* this register read seems to fail on pll0 */
maybe an errata?
- if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE)
return 8;
- else
return pll_div(pllbase, PLLC_PREDIV);
+#endif
- return 1;
+}
+static inline unsigned pll_postdiv(volatile void *pllbase) +{ +#ifdef CONFIG_SOC_DM355
- return pll_div(pllbase, PLLC_POSTDIV);
+#elif defined(CONFIG_SOC_DM6446)
- if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE)
return pll_div(pllbase, PLLC_POSTDIV);
+#endif
- return 1;
+}
+static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div) +{
- volatile void *pllbase = (volatile void *) pll_addr;
- unsined base = CONFIG_SYS_HZ_CLOCK / 1000;
- /* the PLL might be bypassed */
- if (REG(pllbase + PLLC_PLLCTL) & BIT(0)) {
base /= pll_prediv(pllbase);
base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff);
base /= pll_postdiv(pllbase);
- }
- return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div));
}
void dv_display_clk_infos(void) {
- printf("ARM Clock: %dMHz\n", dv_get_pllm_output(REG(PLL1_PLLM)) / 2);
- printf("DDR Clock: %dMHz\n", dv_get_pllm_output(REG(PLL2_PLLM)) /
((REG(PLL2_DIV2) & 0x1f) + 1) / 2);
- printf("ARM Clock: %dMHz\n",
pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV));
- printf("DDR Clock: %dMHz\n",
/* DDR PHY uses an x2 input clock */
pll_sysclk_mhz(DAVINCI_PLL_CNTRL1_BASE, DDR_PLLDIV)
/ 2);
- printf("\n");
puts("");
Best Regards, J.

Jean-Christophe PLAGNIOL-VILLARD wrote:
On 15:38 Wed 29 Apr , David Brownell wrote:
From: David Brownell dbrownell@users.sourceforge.net
Make the DaVinci clock display code work on the dm355 too ... there are pre- and post- dividers on its PLLs, which most other DaVinci processors don't use; and it uses different PLL dividers. Stubbed in support for the DM6467 too. Verified on dm355 and dm6446.
Signed-off-by: David Brownell dbrownell@users.sourceforge.net
This should move to cpu/arm926ejs/davinci (cpuinfo.c?) someday, like the other SoC-specific code. For another patch.
good idea
cpu.c will be better
Good idea. This would give me a happy place for the cpu_eth_init() as mentioned in another thread.
regards, Ben

On Wednesday 29 April 2009, Jean-Christophe PLAGNIOL-VILLARD wrote:
On 15:38 Wed 29 Apr , David Brownell wrote:
From: David Brownell dbrownell@users.sourceforge.net
Make the DaVinci clock display code work on the dm355 too ... there are pre- and post- dividers on its PLLs, which most other DaVinci processors don't use; and it uses different PLL dividers. Stubbed in support for the DM6467 too. Verified on dm355 and dm6446.
Signed-off-by: David Brownell dbrownell@users.sourceforge.net
This should move to cpu/arm926ejs/davinci (cpuinfo.c?) someday, like the other SoC-specific code. For another patch.
good idea
cpu.c will be better
I was thinking of using CONFIG_DISPLAY_CPUINFO hooks for that, and those seem to be in cpuinfo.c files. (Someday, when time allows.)
btw a clock design as done for at91 & avr32 will be nice too
It's missing from at91rm9200 ... ;)
Those seem to be useful if U-Boot is the first stage boot loader, running out of NOR flash and needing to do lots of low level setup: configure PLLs, clock divisors, memory timings, start DRAM, and so on.
But most DaVinci boards boot from NAND flash nowadays, making U-boot be a third stage loader with no lowlevel init. So it doesn't need such code ... but if it did, it would touch the PLL controllers in very different ways (modifying the registers and handshaking, not just reading like this).
+/* offsets from PLL controller base */ +#define PLLC_PLLCTL 0x100 +#define PLLC_PLLM 0x110 +#define PLLC_PREDIV 0x114 +#define PLLC_PLLDIV1 0x118 +#define PLLC_PLLDIV2 0x11c +#define PLLC_PLLDIV3 0x120 +#define PLLC_POSTDIV 0x128 +#define PLLC_BPDIV 0x12c +#define PLLC_PLLDIV4 0x160 +#define PLLC_PLLDIV5 0x164 +#define PLLC_PLLDIV6 0x168 +#define PLLC_PLLDIV8 0x170 +#define PLLC_PLLDIV9 0x174
who will init the PLL? can we detect it if they are already init?
PLL setup is part of lowlevel init ... usually it's done by the second stage boot loader (UBL) if this is booting from anything except NOR flash. For NOR boot that's now done in cpu/.../lowlevel_init.S code.
By the time this code is called, that's been done a long time ago ... we're running out of DRAM, which can't work without active PLLs. (The oscillator is from 20-30 MHz, the DRAM clock must be 125 MHz and up, QED.)
+#define BIT(x) (1 << (x))
please remove
When there's a standard definition somewhere ... the one in include/asm/arch-ixp/ixp425.h is unusable here.
+static inline unsigned pll_prediv(volatile void *pllbase) +{ +#ifdef CONFIG_SOC_DM355
- /* this register read seems to fail on pll0 */
maybe an errata?
I didn't see it published, if so. I noticed that issue when doing similar code on Linux.
void dv_display_clk_infos(void) {
- printf("ARM Clock: %dMHz\n", dv_get_pllm_output(REG(PLL1_PLLM)) / 2);
- printf("DDR Clock: %dMHz\n", dv_get_pllm_output(REG(PLL2_PLLM)) /
((REG(PLL2_DIV2) & 0x1f) + 1) / 2);
- printf("ARM Clock: %dMHz\n",
pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV));
- printf("DDR Clock: %dMHz\n",
/* DDR PHY uses an x2 input clock */
pll_sysclk_mhz(DAVINCI_PLL_CNTRL1_BASE, DDR_PLLDIV)
/ 2);
- printf("\n");
puts("");
OK
Best Regards, J.

On 17:13 Wed 29 Apr , David Brownell wrote:
On Wednesday 29 April 2009, Jean-Christophe PLAGNIOL-VILLARD wrote:
On 15:38 Wed 29 Apr , David Brownell wrote:
From: David Brownell dbrownell@users.sourceforge.net
Make the DaVinci clock display code work on the dm355 too ... there are pre- and post- dividers on its PLLs, which most other DaVinci processors don't use; and it uses different PLL dividers. Stubbed in support for the DM6467 too. Verified on dm355 and dm6446.
Signed-off-by: David Brownell dbrownell@users.sourceforge.net
This should move to cpu/arm926ejs/davinci (cpuinfo.c?) someday, like the other SoC-specific code. For another patch.
good idea
cpu.c will be better
I was thinking of using CONFIG_DISPLAY_CPUINFO hooks for that, and those seem to be in cpuinfo.c files. (Someday, when time allows.)
btw a clock design as done for at91 & avr32 will be nice too
It's missing from at91rm9200 ... ;)
sure but in preparaton as the at91rm9200 will be merge with the AT91 soon
Those seem to be useful if U-Boot is the first stage boot loader, running out of NOR flash and needing to do lots of low level setup: configure PLLs, clock divisors, memory timings, start DRAM, and so on.
But most DaVinci boards boot from NAND flash nowadays, making U-boot be a third stage loader with no lowlevel init. So it doesn't need such code ... but if it did, it would touch the PLL controllers in very different ways (modifying the registers and handshaking, not just reading like this).
ok the calc clock, I've more in mind the get_xxx_clk_rate() api
+/* offsets from PLL controller base */ +#define PLLC_PLLCTL 0x100 +#define PLLC_PLLM 0x110 +#define PLLC_PREDIV 0x114 +#define PLLC_PLLDIV1 0x118 +#define PLLC_PLLDIV2 0x11c +#define PLLC_PLLDIV3 0x120 +#define PLLC_POSTDIV 0x128 +#define PLLC_BPDIV 0x12c +#define PLLC_PLLDIV4 0x160 +#define PLLC_PLLDIV5 0x164 +#define PLLC_PLLDIV6 0x168 +#define PLLC_PLLDIV8 0x170 +#define PLLC_PLLDIV9 0x174
who will init the PLL? can we detect it if they are already init?
PLL setup is part of lowlevel init ... usually it's done by the second stage boot loader (UBL) if this is booting from anything except NOR flash. For NOR boot that's now done in cpu/.../lowlevel_init.S code.
By the time this code is called, that's been done a long time ago ... we're running out of DRAM, which can't work without active PLLs. (The oscillator is from 20-30 MHz, the DRAM clock must be 125 MHz and up, QED.)
my idea is more this the lowlovel will init the pll (lowlevel_init.S or other stage bootloader) so instead of hardcoding the PPLDIV read it in the register and then calculate the clock rate and it need it set the other non used clock depending on the IP used by u-boot (at runtime)
Best Regards, J.

On Wednesday 29 April 2009, Jean-Christophe PLAGNIOL-VILLARD wrote:
my idea is more this the lowlovel will init the pll (lowlevel_init.S or other stage bootloader)
Right ...
so instead of hardcoding the PPLDIV read it in the register and then calculate the clock rate
That's all this code does: read the PLL registers (and divider taps), and display settings in use by the current board. It happens that some SoCs have slightly different PLL configuration (like pre/post dividers) and feed important components (ARM, DSP, DDR) from different PLL dividers.
and it need it set the other non used clock depending on the IP used by u-boot (at runtime)
I don't know what you mean here. PLL/tap configuration is distinct from clock distribution on the chip.
The cpu/arm926ejs/davinci/psc.c code handles clock distribution (and resets). So for example the dm355 chips leave most modules clocked but in reset, while the dm6446 leaves them unclocked and in reset ... so modules needed by u-boot get uniformly taken out of reset and clocked. But that's *unrelated* to this PLL display code.
- Dave

On 23:35 Wed 29 Apr , David Brownell wrote:
On Wednesday 29 April 2009, Jean-Christophe PLAGNIOL-VILLARD wrote:
my idea is more this the lowlovel will init the pll (lowlevel_init.S or other stage bootloader)
Right ...
so instead of hardcoding the PPLDIV read it in the register and then calculate the clock rate
That's all this code does: read the PLL registers (and divider taps), and display settings in use by the current board.
yes but it's does not provice help full api to use it other where in the code
It happens that some SoCs have slightly different PLL configuration (like pre/post dividers) and feed important components (ARM, DSP, DDR) from different PLL dividers.
the PLL dividers are hardcoded why?
and it need it set the other non used clock depending on the IP used by u-boot (at runtime)
I don't know what you mean here. PLL/tap configuration is distinct from clock distribution on the chip.
The cpu/arm926ejs/davinci/psc.c code handles clock distribution (and resets). So for example the dm355 chips leave most modules clocked but in reset, while the dm6446 leaves them unclocked and in reset ... so modules needed by u-boot get uniformly taken out of reset and clocked.
I known that's why I've in mind to set only the clock if we use the drivers/IP at run time othewise let it off
But that's *unrelated* to this PLL display code.
I agree this not for this patch but for an improvement
Best Regards, J.

On Thursday 30 April 2009, Jean-Christophe PLAGNIOL-VILLARD wrote:
On 23:35 Wed 29 Apr , David Brownell wrote:
On Wednesday 29 April 2009, Jean-Christophe PLAGNIOL-VILLARD wrote:
my idea is more this the lowlovel will init the pll (lowlevel_init.S or other stage bootloader)
Right ...
so instead of hardcoding the PPLDIV read it in the register and then calculate the clock rate
That's all this code does: read the PLL registers (and divider taps), and display settings in use by the current board.
yes but it's does not provice help full api to use it other where in the code
Use it where/why? There's not been a need for anything analagous to <linux/clk.h> ...
It happens that some SoCs have slightly different PLL configuration (like pre/post dividers) and feed important components (ARM, DSP, DDR) from different PLL dividers.
the PLL dividers are hardcoded why?
A few are hard-wired in silicon, others are programmable. Either way, they rarely change after lowlevel init.
Mostly it's a case of *which* divider -- DIV1, DIV2, DIV4, etc. Each divider feeds a fixed set of modules, and different SoCs map them differently: fixed/not, which modules, allowable frequency ranges, etc.
It happens that the cases U-Boot cares about today bypass the PLL and dividers entirely: clocks going to timer and the UART directly match the main xtal. Or, like USB, the exact clock rate is either hard wired (60 MHz for the PHY) or doesn't matter.
- Dave

On Wednesday 29 April 2009, Jean-Christophe PLAGNIOL-VILLARD wrote:
cpu.c will be better
Here's a followup patch that applies on top of this one, and creates the cpu.c you wanted.
=== CUT HERE From: David Brownell dbrownell@users.sourceforge.net
Move the clock-rate dumping code into the cpu/.../davinci area where it should have been, enabled by CONFIG_DISPLAY_CPUINFO, updating the format and showing the DSP clock (where relevant).
Switch boards to use the cpuinfo() hook for this stuff.
Remove a few now-obsolete PLL #defines.
Signed-off-by: David Brownell dbrownell@users.sourceforge.net --- board/davinci/common/misc.c | 89 -------------------- board/davinci/common/misc.h | 1 board/davinci/dvevm/dvevm.c | 2 board/davinci/schmoogie/schmoogie.c | 2 board/davinci/sffsdr/sffsdr.c | 2 board/davinci/sonata/sonata.c | 2 cpu/arm926ejs/davinci/Makefile | 2 cpu/arm926ejs/davinci/cpu.c | 131 ++++++++++++++++++++++++++++++ include/asm-arm/arch-davinci/hardware.h | 5 - include/configs/davinci_dvevm.h | 1 include/configs/davinci_schmoogie.h | 1 include/configs/davinci_sffsdr.h | 4 include/configs/davinci_sonata.h | 1 13 files changed, 137 insertions(+), 106 deletions(-)
--- a/board/davinci/common/misc.c +++ b/board/davinci/common/misc.c @@ -29,39 +29,6 @@ #include <asm/arch/hardware.h>
-/* offsets from PLL controller base */ -#define PLLC_PLLCTL 0x100 -#define PLLC_PLLM 0x110 -#define PLLC_PREDIV 0x114 -#define PLLC_PLLDIV1 0x118 -#define PLLC_PLLDIV2 0x11c -#define PLLC_PLLDIV3 0x120 -#define PLLC_POSTDIV 0x128 -#define PLLC_BPDIV 0x12c -#define PLLC_PLLDIV4 0x160 -#define PLLC_PLLDIV5 0x164 -#define PLLC_PLLDIV6 0x168 -#define PLLC_PLLDIV8 0x170 -#define PLLC_PLLDIV9 0x174 - -#define BIT(x) (1 << (x)) - -/* SOC-specific pll info */ -#ifdef CONFIG_SOC_DM355 -#define ARM_PLLDIV PLLC_PLLDIV1 -#define DDR_PLLDIV PLLC_PLLDIV1 -#endif - -#ifdef CONFIG_SOC_DM644X -#define ARM_PLLDIV PLLC_PLLDIV2 -#define DDR_PLLDIV PLLC_PLLDIV2 -#endif - -#ifdef CONFIG_SOC_DM6447 -#define ARM_PLLDIV PLLC_PLLDIV2 -#define DDR_PLLDIV PLLC_PLLDIV1 -#endif - DECLARE_GLOBAL_DATA_PTR;
int dram_init(void) @@ -72,62 +39,6 @@ int dram_init(void) return(0); }
-static unsigned pll_div(volatile void *pllbase, unsigned offset) -{ - u32 div; - - div = REG(pllbase + offset); - return (div & BIT(15)) ? (1 + (div & 0x1f)) : 1; -} - -static inline unsigned pll_prediv(volatile void *pllbase) -{ -#ifdef CONFIG_SOC_DM355 - /* this register read seems to fail on pll0 */ - if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) - return 8; - else - return pll_div(pllbase, PLLC_PREDIV); -#endif - return 1; -} - -static inline unsigned pll_postdiv(volatile void *pllbase) -{ -#ifdef CONFIG_SOC_DM355 - return pll_div(pllbase, PLLC_POSTDIV); -#elif defined(CONFIG_SOC_DM6446) - if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) - return pll_div(pllbase, PLLC_POSTDIV); -#endif - return 1; -} - -static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div) -{ - volatile void *pllbase = (volatile void *) pll_addr; - unsigned base = CONFIG_SYS_HZ_CLOCK / 1000; - - /* the PLL might be bypassed */ - if (REG(pllbase + PLLC_PLLCTL) & BIT(0)) { - base /= pll_prediv(pllbase); - base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff); - base /= pll_postdiv(pllbase); - } - return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div)); -} - -void dv_display_clk_infos(void) -{ - printf("ARM Clock: %dMHz\n", - pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV)); - printf("DDR Clock: %dMHz\n", - /* DDR PHY uses an x2 input clock */ - pll_sysclk_mhz(DAVINCI_PLL_CNTRL1_BASE, DDR_PLLDIV) - / 2); - printf("\n"); -} - #ifdef CONFIG_DRIVER_TI_EMAC
/* Read ethernet MAC address from EEPROM for DVEVM compatible boards. --- a/board/davinci/common/misc.h +++ b/board/davinci/common/misc.h @@ -24,7 +24,6 @@
extern int eth_hw_init(void);
-void dv_display_clk_infos(void); int dvevm_read_mac_address(uint8_t *buf); void dv_configure_mac_address(uint8_t *rom_enetaddr);
--- a/board/davinci/dvevm/dvevm.c +++ b/board/davinci/dvevm/dvevm.c @@ -69,8 +69,6 @@ int misc_init_r(void) uint8_t video_mode; uint8_t eeprom_enetaddr[6];
- dv_display_clk_infos(); - /* Read Ethernet MAC address from EEPROM if available. */ if (dvevm_read_mac_address(eeprom_enetaddr)) dv_configure_mac_address(eeprom_enetaddr); --- a/board/davinci/schmoogie/schmoogie.c +++ b/board/davinci/schmoogie/schmoogie.c @@ -104,8 +104,6 @@ int misc_init_r(void) 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35 };
- dv_display_clk_infos(); - /* Set serial number from UID chip */ if (i2c_read(CONFIG_SYS_UID_ADDR, 0, 1, buf, 8)) { printf("\nUID @ 0x%02x read FAILED!!!\n", CONFIG_SYS_UID_ADDR); --- a/board/davinci/sffsdr/sffsdr.c +++ b/board/davinci/sffsdr/sffsdr.c @@ -131,8 +131,6 @@ int misc_init_r(void) /* EMIF-A CS3 configuration for FPGA. */ REG(DAVINCI_A3CR) = DAVINCI_A3CR_VAL;
- dv_display_clk_infos(); - /* Configure I2C switch (PCA9543) to enable channel 0. */ i2cbuf = CONFIG_SYS_I2C_PCA9543_ENABLE_CH0; if (i2c_write(CONFIG_SYS_I2C_PCA9543_ADDR, 0, --- a/board/davinci/sonata/sonata.c +++ b/board/davinci/sonata/sonata.c @@ -66,8 +66,6 @@ int misc_init_r(void) { uint8_t eeprom_enetaddr[6];
- dv_display_clk_infos(); - /* Read Ethernet MAC address from EEPROM if available. */ if (dvevm_read_mac_address(eeprom_enetaddr)) dv_configure_mac_address(eeprom_enetaddr); --- a/cpu/arm926ejs/davinci/Makefile +++ b/cpu/arm926ejs/davinci/Makefile @@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
-COBJS-y += timer.o psc.o +COBJS-y += cpu.o timer.o psc.o COBJS-$(CONFIG_SOC_DM355) += dm355.o COBJS-$(CONFIG_SOC_DM644X) += dm644x.o COBJS-$(CONFIG_DRIVER_TI_EMAC) += ether.o lxt972.o dp83848.o --- /dev/null +++ b/cpu/arm926ejs/davinci/cpu.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2004 Texas Instruments. + * Copyright (C) 2009 David Brownell + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <common.h> +#include <asm/arch/hardware.h> + + +/* offsets from PLL controller base */ +#define PLLC_PLLCTL 0x100 +#define PLLC_PLLM 0x110 +#define PLLC_PREDIV 0x114 +#define PLLC_PLLDIV1 0x118 +#define PLLC_PLLDIV2 0x11c +#define PLLC_PLLDIV3 0x120 +#define PLLC_POSTDIV 0x128 +#define PLLC_BPDIV 0x12c +#define PLLC_PLLDIV4 0x160 +#define PLLC_PLLDIV5 0x164 +#define PLLC_PLLDIV6 0x168 +#define PLLC_PLLDIV8 0x170 +#define PLLC_PLLDIV9 0x174 + +#define BIT(x) (1 << (x)) + +/* SOC-specific pll info */ +#ifdef CONFIG_SOC_DM355 +#define ARM_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV1 +#endif + +#ifdef CONFIG_SOC_DM644X +#define ARM_PLLDIV PLLC_PLLDIV2 +#define DSP_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV2 +#endif + +#ifdef CONFIG_SOC_DM6447 +#define ARM_PLLDIV PLLC_PLLDIV2 +#define DSP_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV1 +#endif + + +#ifdef CONFIG_DISPLAY_CPUINFO + +static unsigned pll_div(volatile void *pllbase, unsigned offset) +{ + u32 div; + + div = REG(pllbase + offset); + return (div & BIT(15)) ? (1 + (div & 0x1f)) : 1; +} + +static inline unsigned pll_prediv(volatile void *pllbase) +{ +#ifdef CONFIG_SOC_DM355 + /* this register read seems to fail on pll0 */ + if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) + return 8; + else + return pll_div(pllbase, PLLC_PREDIV); +#endif + return 1; +} + +static inline unsigned pll_postdiv(volatile void *pllbase) +{ +#ifdef CONFIG_SOC_DM355 + return pll_div(pllbase, PLLC_POSTDIV); +#elif defined(CONFIG_SOC_DM6446) + if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) + return pll_div(pllbase, PLLC_POSTDIV); +#endif + return 1; +} + +static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div) +{ + volatile void *pllbase = (volatile void *) pll_addr; + unsigned base = CONFIG_SYS_HZ_CLOCK / 1000; + + /* the PLL might be bypassed */ + if (REG(pllbase + PLLC_PLLCTL) & BIT(0)) { + base /= pll_prediv(pllbase); + base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff); + base /= pll_postdiv(pllbase); + } + return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div)); +} + +int print_cpuinfo(void) +{ + /* REVISIT fetch and display CPU ID and revision information + * too ... that will matter as more revisions appear. + */ + printf("Cores: ARM %d MHz", + pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV)); + +#ifdef DSP_PLLDIV + printf(", DSP %d MHz", + pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, DSP_PLLDIV)); +#endif + + printf("\nDDR: %d MHz\n", + /* DDR PHY uses an x2 input clock */ + pll_sysclk_mhz(DAVINCI_PLL_CNTRL1_BASE, DDR_PLLDIV) + / 2); + return 0; +} + +#endif + --- a/include/asm-arm/arch-davinci/hardware.h +++ b/include/asm-arm/arch-davinci/hardware.h @@ -175,11 +175,6 @@ void davinci_errata_workarounds(void);
#define PSC_SILVER_BULLET (0x01c41a20)
-/* Some PLL defines */ -#define PLL1_PLLM (0x01c40910) -#define PLL2_PLLM (0x01c40d10) -#define PLL2_DIV2 (0x01c40d1c) - /* Miscellania... */ #define VBPR (0x20000020)
--- a/include/configs/davinci_dvevm.h +++ b/include/configs/davinci_dvevm.h @@ -52,6 +52,7 @@ #define DV_EVM #define CONFIG_SYS_NAND_SMALLPAGE #define CONFIG_SYS_USE_NOR +#define CONFIG_DISPLAY_CPUINFO /*===================*/ /* SoC Configuration */ /*===================*/ --- a/include/configs/davinci_schmoogie.h +++ b/include/configs/davinci_schmoogie.h @@ -27,6 +27,7 @@ #define SCHMOOGIE #define CONFIG_SYS_NAND_LARGEPAGE #define CONFIG_SYS_USE_NAND +#define CONFIG_DISPLAY_CPUINFO /*===================*/ /* SoC Configuration */ /*===================*/ --- a/include/configs/davinci_sffsdr.h +++ b/include/configs/davinci_sffsdr.h @@ -28,8 +28,8 @@ #define SFFSDR #define CONFIG_SYS_NAND_LARGEPAGE #define CONFIG_SYS_USE_NAND -#define CONFIG_SYS_USE_DSPLINK /* This is to prevent U-Boot from - * powering ON the DSP. */ +#define CONFIG_SYS_USE_DSPLINK /* don't power up the DSP. */ +#define CONFIG_DISPLAY_CPUINFO /* SoC Configuration */ #define CONFIG_ARM926EJS /* arm926ejs CPU core */ #define CONFIG_SYS_TIMERBASE 0x01c21400 /* use timer 0 */ --- a/include/configs/davinci_sonata.h +++ b/include/configs/davinci_sonata.h @@ -52,6 +52,7 @@ #define SONATA_BOARD #define CONFIG_SYS_NAND_SMALLPAGE #define CONFIG_SYS_USE_NOR +#define CONFIG_DISPLAY_CPUINFO /*===================*/ /* SoC Configuration */ /*===================*/

On 18:23 Thu 30 Apr , David Brownell wrote:
On Wednesday 29 April 2009, Jean-Christophe PLAGNIOL-VILLARD wrote:
cpu.c will be better
Here's a followup patch that applies on top of this one, and creates the cpu.c you wanted.
please move this
=== CUT HERE From: David Brownell dbrownell@users.sourceforge.net
Move the clock-rate dumping code into the cpu/.../davinci area where it should have been, enabled by CONFIG_DISPLAY_CPUINFO, updating the format and showing the DSP clock (where relevant).
Switch boards to use the cpuinfo() hook for this stuff.
Remove a few now-obsolete PLL #defines.
Signed-off-by: David Brownell dbrownell@users.sourceforge.net
HERE
it will help to not manually fix the patch
applied to arm/next
Best Regards, J.
participants (3)
-
Ben Warren
-
David Brownell
-
Jean-Christophe PLAGNIOL-VILLARD