All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Andreas Bießmann" <andreas.devel@googlemail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH atmel/next 1/7] arm920t/at91: add clock.c
Date: Sun, 12 Jun 2011 13:49:11 +0200	[thread overview]
Message-ID: <1307879357-97986-2-git-send-email-andreas.devel@googlemail.com> (raw)
In-Reply-To: <1307879357-97986-1-git-send-email-andreas.devel@googlemail.com>

This patch adds an copy of arm926ejs/at91/clock.c to arm920t/at91. The
arm926ejs specialities are removed from arm920t version and vice versa.

Signed-off-by: Andreas Bie?mann <andreas.devel@googlemail.com>
---
 arch/arm/cpu/arm920t/at91/Makefile   |    1 +
 arch/arm/cpu/arm920t/at91/clock.c    |  160 ++++++++++++++++++++++++++++++++++
 arch/arm/cpu/arm926ejs/at91/clock.c  |   35 +-------
 arch/arm/include/asm/arch-at91/clk.h |   42 ++++++++--
 4 files changed, 198 insertions(+), 40 deletions(-)
 create mode 100644 arch/arm/cpu/arm920t/at91/clock.c

diff --git a/arch/arm/cpu/arm920t/at91/Makefile b/arch/arm/cpu/arm920t/at91/Makefile
index 5c71b77..8258ecd 100644
--- a/arch/arm/cpu/arm920t/at91/Makefile
+++ b/arch/arm/cpu/arm920t/at91/Makefile
@@ -28,6 +28,7 @@ LIB	= $(obj)lib$(SOC).o
 SOBJS	+= lowlevel_init.o
 COBJS	+= reset.o
 COBJS	+= timer.o
+COBJS	+= clock.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/arch/arm/cpu/arm920t/at91/clock.c b/arch/arm/cpu/arm920t/at91/clock.c
new file mode 100644
index 0000000..02318b3
--- /dev/null
+++ b/arch/arm/cpu/arm920t/at91/clock.c
@@ -0,0 +1,160 @@
+/*
+ * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c]
+ *
+ * Copyright (C) 2011 Andreas Bie?mann
+ * Copyright (C) 2005 David Brownell
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * 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.
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/clk.h>
+
+#if !defined(CONFIG_AT91FAMILY)
+# error You need to define CONFIG_AT91FAMILY in your board config!
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static unsigned long at91_css_to_rate(unsigned long css)
+{
+	switch (css) {
+	case AT91_PMC_MCKR_CSS_SLOW:
+		return CONFIG_SYS_AT91_SLOW_CLOCK;
+	case AT91_PMC_MCKR_CSS_MAIN:
+		return gd->main_clk_rate_hz;
+	case AT91_PMC_MCKR_CSS_PLLA:
+		return gd->plla_rate_hz;
+	case AT91_PMC_MCKR_CSS_PLLB:
+		return gd->pllb_rate_hz;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_USB_ATMEL
+static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq)
+{
+	unsigned i, div = 0, mul = 0, diff = 1 << 30;
+	unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00;
+
+	/* PLL output max 240 MHz (or 180 MHz per errata) */
+	if (out_freq > 240000000)
+		goto fail;
+
+	for (i = 1; i < 256; i++) {
+		int diff1;
+		unsigned input, mul1;
+
+		/*
+		 * PLL input between 1MHz and 32MHz per spec, but lower
+		 * frequences seem necessary in some cases so allow 100K.
+		 * Warning: some newer products need 2MHz min.
+		 */
+		input = main_freq / i;
+		if (input < 100000)
+			continue;
+		if (input > 32000000)
+			continue;
+
+		mul1 = out_freq / input;
+		if (mul1 > 2048)
+			continue;
+		if (mul1 < 2)
+			goto fail;
+
+		diff1 = out_freq - input * mul1;
+		if (diff1 < 0)
+			diff1 = -diff1;
+		if (diff > diff1) {
+			diff = diff1;
+			div = i;
+			mul = mul1;
+			if (diff == 0)
+				break;
+		}
+	}
+	if (i == 256 && diff > (out_freq >> 5))
+		goto fail;
+	return ret | ((mul - 1) << 16) | div;
+fail:
+	return 0;
+}
+#endif
+
+static u32 at91_pll_rate(u32 freq, u32 reg)
+{
+	unsigned mul, div;
+
+	div = reg & 0xff;
+	mul = (reg >> 16) & 0x7ff;
+	if (div && mul) {
+		freq /= div;
+		freq *= mul + 1;
+	} else
+		freq = 0;
+
+	return freq;
+}
+
+
+int at91_clock_init(unsigned long main_clock)
+{
+	unsigned freq, mckr;
+	at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;
+#ifndef CONFIG_SYS_AT91_MAIN_CLOCK
+	unsigned tmp;
+	/*
+	 * When the bootloader initialized the main oscillator correctly,
+	 * there's no problem using the cycle counter.  But if it didn't,
+	 * or when using oscillator bypass mode, we must be told the speed
+	 * of the main clock.
+	 */
+	if (!main_clock) {
+		do {
+			tmp = readl(&pmc->mcfr);
+		} while (!(tmp & AT91_PMC_MCFR_MAINRDY));
+		tmp &= AT91_PMC_MCFR_MAINF_MASK;
+		main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
+	}
+#endif
+	gd->main_clk_rate_hz = main_clock;
+
+	/* report if PLLA is more than mildly overclocked */
+	gd->plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
+
+#ifdef CONFIG_USB_ATMEL
+	/*
+	 * USB clock init:  choose 48 MHz PLLB value,
+	 * disable 48MHz clock during usb peripheral suspend.
+	 *
+	 * REVISIT:  assumes MCK doesn't derive from PLLB!
+	 */
+	gd->at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) |
+			     AT91_PMC_PLLBR_USBDIV_2;
+	gd->pllb_rate_hz = at91_pll_rate(main_clock, gd->at91_pllb_usb_init);
+#endif
+
+	/*
+	 * MCK and CPU derive from one of those primary clocks.
+	 * For now, assume this parentage won't change.
+	 */
+	mckr = readl(&pmc->mckr);
+	gd->mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
+	freq = gd->mck_rate_hz;
+
+	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2));	/* prescale */
+	/* mdiv */
+	gd->mck_rate_hz = freq / (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
+	gd->cpu_clk_rate_hz = freq;
+
+	return 0;
+}
+
diff --git a/arch/arm/cpu/arm926ejs/at91/clock.c b/arch/arm/cpu/arm926ejs/at91/clock.c
index 608af2c..a7085de 100644
--- a/arch/arm/cpu/arm926ejs/at91/clock.c
+++ b/arch/arm/cpu/arm926ejs/at91/clock.c
@@ -23,36 +23,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-unsigned long get_cpu_clk_rate(void)
-{
-	return gd->cpu_clk_rate_hz;
-}
-
-unsigned long get_main_clk_rate(void)
-{
-	return gd->main_clk_rate_hz;
-}
-
-unsigned long get_mck_clk_rate(void)
-{
-	return gd->mck_rate_hz;
-}
-
-unsigned long get_plla_clk_rate(void)
-{
-	return gd->plla_rate_hz;
-}
-
-unsigned long get_pllb_clk_rate(void)
-{
-	return gd->pllb_rate_hz;
-}
-
-u32 get_pllb_init(void)
-{
-	return gd->at91_pllb_usb_init;
-}
-
 static unsigned long at91_css_to_rate(unsigned long css)
 {
 	switch (css) {
@@ -192,10 +162,7 @@ int at91_clock_init(unsigned long main_clock)
 	freq = gd->mck_rate_hz;
 
 	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2));	/* prescale */
-#if defined(CONFIG_AT91RM9200)
-	/* mdiv */
-	gd->mck_rate_hz = freq / (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
-#elif defined(CONFIG_AT91SAM9G20)
+#if defined(CONFIG_AT91SAM9G20)
 	/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
 	gd->mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ?
 		freq / ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 7) : freq;
diff --git a/arch/arm/include/asm/arch-at91/clk.h b/arch/arm/include/asm/arch-at91/clk.h
index 457e6c9..f645327 100644
--- a/arch/arm/include/asm/arch-at91/clk.h
+++ b/arch/arm/include/asm/arch-at91/clk.h
@@ -26,13 +26,43 @@
 #define __ASM_ARM_ARCH_CLK_H__
 
 #include <asm/arch/hardware.h>
+#include <asm/global_data.h>
 
-unsigned long get_cpu_clk_rate(void);
-unsigned long get_main_clk_rate(void);
-unsigned long get_mck_clk_rate(void);
-unsigned long get_plla_clk_rate(void);
-unsigned long get_pllb_clk_rate(void);
-unsigned int  get_pllb_init(void);
+static inline unsigned long get_cpu_clk_rate(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	return gd->cpu_clk_rate_hz;
+}
+
+static inline unsigned long get_main_clk_rate(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	return gd->main_clk_rate_hz;
+}
+
+static inline unsigned long get_mck_clk_rate(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	return gd->mck_rate_hz;
+}
+
+static inline unsigned long get_plla_clk_rate(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	return gd->plla_rate_hz;
+}
+
+static inline unsigned long get_pllb_clk_rate(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	return gd->pllb_rate_hz;
+}
+
+static inline u32 get_pllb_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	return gd->at91_pllb_usb_init;
+}
 
 static inline unsigned long get_macb_pclk_rate(unsigned int dev_id)
 {
-- 
1.7.5.4

  reply	other threads:[~2011-06-12 11:49 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-12 11:49 [U-Boot] [PATCH atmel/next 0/7] replace at91rm9200_usart by atmel_usart Andreas Bießmann
2011-06-12 11:49 ` Andreas Bießmann [this message]
2011-06-12 11:49 ` [U-Boot] [PATCH atmel/next 2/7] arm920t/at91: use new clock.c features Andreas Bießmann
2011-06-12 11:49 ` [U-Boot] [PATCH atmel/next 3/7] arm920t/at91: add at91rm9200_devices.c Andreas Bießmann
2011-06-12 11:49 ` [U-Boot] [PATCH atmel/next 4/7] at91rm9200ek: use atmel_usart Andreas Bießmann
2011-06-12 11:49 ` [U-Boot] [PATCH atmel/next 5/7] eb_cpux9k2: " Andreas Bießmann
2011-06-26 18:10   ` Jens Scharsig
2011-06-12 11:49 ` [U-Boot] [PATCH atmel/next 6/7] cpuat91: " Andreas Bießmann
2011-06-12 11:49 ` [U-Boot] [PATCH atmel/next 7/7] driver/serial: delete at91rm9200_usart Andreas Bießmann
2011-06-30  8:42 ` [U-Boot] [PATCH atmel/next 0/7] replace at91rm9200_usart by atmel_usart Reinhard Meyer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1307879357-97986-2-git-send-email-andreas.devel@googlemail.com \
    --to=andreas.devel@googlemail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.