From: Michael Schwingen <rincewind@discworld.dascon.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] Fixing IXP42x boards - some general questions
Date: Thu, 23 Dec 2010 16:13:42 +0100 [thread overview]
Message-ID: <20101223151341.GA31823@discworld.dascon.de> (raw)
In-Reply-To: <201012231155.02005.marek.vasut@gmail.com>
On Thu, Dec 23, 2010 at 11:55:01AM +0100, Marek Vasut wrote:
> On Thursday 23 December 2010 11:10:37 Wolfgang Denk wrote:
> >
> > > Timer system.
> > >
> > > - For IXP, there are two variants of the timer system - one using
> > >
> > > interrupts, and one without interrupts. Both do not work currently.
> > > I have patches that fix the non-interrupt version, changing
> > > CONFIG_SYS_HZ from 66666666 to 1000, bringing it in line with what most
> > > other ARM platforms do.
> >
> > I cannot nomment on this. Marek?
>
> http://download.intel.com/design/network/manuals/25248006.pdf page 411 or so.
>
> What's the second variant ? Either way -- you should use the non-interrupt
> version. Remember, you're writing a bootloader, use the KISS principle ; you
> generally use the timer only to implement *delay() functions.
>
> Therefore, as Wolfgang said, you use 1000 ticks per second in uboot's internal
> counting, but "convert" it from/to your real timer's ticks in timer.c
>
> What problem do you have there? Also, can you please let us see the patches?
I don't have any problems - I just want to know what the preferred way is in
doing this, before I spend time touching multiple boards.
Patch for the timer part is attached - note that this is work-in-progress
and probably needs some cleanup before submission.
cu
Michael
diff --git a/arch/arm/cpu/ixp/timer.c b/arch/arm/cpu/ixp/timer.c
index edf341f..9715eab 100644
--- a/arch/arm/cpu/ixp/timer.c
+++ b/arch/arm/cpu/ixp/timer.c
@@ -1,4 +1,7 @@
/*
+ * (C) Copyright 2010
+ * Michael Schwingen, michael at schwingen.org
+ *
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr at denx.de.
*
@@ -31,11 +34,11 @@
#include <common.h>
#include <asm/arch/ixp425.h>
+#include <div64.h>
#ifdef CONFIG_TIMER_IRQ
-#define FREQ 66666666
-#define CLOCK_TICK_RATE (((FREQ / CONFIG_SYS_HZ & ~IXP425_OST_RELOAD_MASK) + 1) * CONFIG_SYS_HZ)
+#define CLOCK_TICK_RATE (((CONFIG_IXP425_TIMER_CLK / CONFIG_SYS_HZ & ~IXP425_OST_RELOAD_MASK) + 1) * CONFIG_SYS_HZ)
#define LATCH ((CLOCK_TICK_RATE + CONFIG_SYS_HZ/2) / CONFIG_SYS_HZ) /* For divider */
/*
@@ -79,57 +82,98 @@ int timer_init (void)
return 0;
}
-#else
-ulong get_timer (ulong base)
+
+#else /* not CONFIG_TIMER_IRQ */
+
+/*
+ * The IXP42x time-stamp timer runs at 2*OSC_IN (66.666MHz when using a
+ * 33.333MHz crystal).
+ */
+static inline unsigned long long tick_to_time(unsigned long long tick)
{
- return get_timer_masked () - base;
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, CONFIG_IXP425_TIMER_CLK);
+ return tick;
}
-void ixp425_udelay(unsigned long usec)
+static inline unsigned long long time_to_tick(unsigned long long time)
{
- /*
- * This function has a max usec, but since it is called from udelay
- * we should not have to worry... be happy
- */
- unsigned long usecs = CONFIG_SYS_HZ/1000000L & ~IXP425_OST_RELOAD_MASK;
+ time *= CONFIG_IXP425_TIMER_CLK;
+ do_div(time, CONFIG_SYS_HZ);
+ return time;
+}
- *IXP425_OSST = IXP425_OSST_TIMER_1_PEND;
- usecs |= IXP425_OST_ONE_SHOT | IXP425_OST_ENABLE;
- *IXP425_OSRT1 = usecs;
- while (!(*IXP425_OSST & IXP425_OSST_TIMER_1_PEND));
+static inline unsigned long long us_to_tick(unsigned long long us)
+{
+ us = us * CONFIG_IXP425_TIMER_CLK + 999999;
+ do_div(us, 1000000);
+ return us;
}
-void __udelay (unsigned long usec)
+static ulong timestamp;
+static ulong lastinc;
+
+unsigned long long get_ticks (void)
{
- while (usec--) ixp425_udelay(1);
+ ulong now = *IXP425_OSTS_B;
+
+ if (*IXP425_OSST & IXP425_OSST_TIMER_TS_PEND) {
+ /* rollover of timestamp timer register */
+ timestamp += (0xFFFFFFFF - lastinc) + now + 1;
+ *IXP425_OSST = IXP425_OSST_TIMER_TS_PEND;
+ }
+ else {
+ /* move stamp forward with absolut diff ticks */
+ timestamp += (now - lastinc);
+ }
+ lastinc = now;
+ return timestamp;
}
-static ulong reload_constant = 0xfffffff0;
void reset_timer_masked (void)
{
- ulong reload = reload_constant | IXP425_OST_ONE_SHOT | IXP425_OST_ENABLE;
+ /* reset time */
+ lastinc = *IXP425_OSTS_B; /* capture current timestamp counter */
+ timestamp = 0; /* start "advancing" time stamp from 0 */
+}
- *IXP425_OSST = IXP425_OSST_TIMER_1_PEND;
- *IXP425_OSRT1 = reload;
+void reset_timer(void)
+{
+ reset_timer_masked();
}
ulong get_timer_masked (void)
{
- /*
- * Note that it is possible for this to wrap!
- * In this case we return max.
- */
- ulong current = *IXP425_OST1;
- if (*IXP425_OSST & IXP425_OSST_TIMER_1_PEND)
- {
- return reload_constant;
- }
- return (reload_constant - current);
+ return tick_to_time(get_ticks());
+}
+
+ulong get_timer (ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+void set_timer (ulong t)
+{
+ timestamp = time_to_tick(t);
}
+/* delay x useconds AND preserve advance timestamp value */
+void __udelay (unsigned long usec)
+{
+ unsigned long long tmp;
+
+ tmp = get_ticks() + us_to_tick(usec);
+
+ while (get_ticks() < tmp)
+ ;
+}
+
+
int timer_init(void)
{
+ *IXP425_OSST = IXP425_OSST_TIMER_TS_PEND;
return 0;
}
+
#endif
diff --git a/arch/arm/include/asm/arch-ixp/ixp425.h b/arch/arm/include/asm/arch-ixp/ixp425.h
index 2114437..ddbf713 100644
--- a/arch/arm/include/asm/arch-ixp/ixp425.h
+++ b/arch/arm/include/asm/arch-ixp/ixp425.h
@@ -391,9 +391,8 @@
#define IXP425_TIMER_REG(x) (IXP425_TIMER_BASE_PHYS+(x))
#endif
-#if 0 /* test-only: also defined in npe/include/... */
-#define IXP425_OSTS IXP425_TIMER_REG(IXP425_OSTS_OFFSET)
-#endif
+/* _B to avoid collision: also defined in npe/include/... */
+#define IXP425_OSTS_B IXP425_TIMER_REG(IXP425_OSTS_OFFSET)
#define IXP425_OST1 IXP425_TIMER_REG(IXP425_OST1_OFFSET)
#define IXP425_OSRT1 IXP425_TIMER_REG(IXP425_OSRT1_OFFSET)
#define IXP425_OST2 IXP425_TIMER_REG(IXP425_OST2_OFFSET)
diff --git a/include/configs/actux3.h b/include/configs/actux3.h
index 76acf5a..4afe5ac 100644
--- a/include/configs/actux3.h
+++ b/include/configs/actux3.h
@@ -28,6 +28,7 @@
#define CONFIG_IXP425 1
#define CONFIG_ACTUX3 1
+#define CONFIG_USE_FUNCTION_SECTIONS 1
#define CONFIG_DISPLAY_CPUINFO 1
#define CONFIG_DISPLAY_BOARDINFO 1
@@ -37,6 +38,7 @@
#define CONFIG_BAUDRATE 115200
#define CONFIG_BOOTDELAY 3
#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
+#define CONFIG_BOARD_EARLY_INIT_F 1
/***************************************************************
* U-boot generic defines start here.
@@ -83,8 +85,9 @@
#define CONFIG_SYS_MEMTEST_START 0x00400000
#define CONFIG_SYS_MEMTEST_END 0x00800000
-/* spec says 66.666 MHz, but it appears to be 33 */
-#define CONFIG_SYS_HZ 3333333
+/* timer clock - 2* OSC_IN system clock */
+#define CONFIG_IXP425_TIMER_CLK 66666666
+#define CONFIG_SYS_HZ 1000
/* default load address */
#define CONFIG_SYS_LOAD_ADDR 0x00010000
@@ -111,7 +114,7 @@
/* SDRAM settings */
#define CONFIG_NR_DRAM_BANKS 1
#define PHYS_SDRAM_1 0x00000000
-#define CONFIG_SYS_DRAM_BASE 0x00000000
+#define CONFIG_SYS_SDRAM_BASE 0x00000000
/* 16MB SDRAM */
#define CONFIG_SYS_SDR_CONFIG 0x3A
@@ -121,6 +124,7 @@
#define CONFIG_SYS_DRAM_SIZE 0x01000000
/* FLASH organization */
+#define CONFIG_SYS_TEXT_BASE 0x50000000
#define CONFIG_SYS_MAX_FLASH_BANKS 1
/* max number of sectors on one chip */
#define CONFIG_SYS_MAX_FLASH_SECT 140
@@ -150,6 +154,11 @@
#define CONFIG_PHY_ADDR 0x10
/* MII PHY management */
#define CONFIG_MII 1
+/* fixed-speed switch without standard PHY registers on MII */
+#define CONFIG_MII_NPE0_FIXEDLINK 1
+#define CONFIG_MII_NPE0_SPEED 100
+#define CONFIG_MII_NPE0_FULLDUPLEX 1
+
/* Number of ethernet rx buffers & descriptors */
#define CONFIG_SYS_RX_ETH_BUFFER 16
#define CONFIG_RESET_PHY_R 1
@@ -223,4 +232,8 @@
" tftpboot ${loadaddr} ${kernelfile};" \
" bootm\0"
+/* additions for new relocation code, must be added to all boards */
+#define CONFIG_SYS_INIT_SP_ADDR \
+ (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE)
+
#endif /* __CONFIG_H */
next prev parent reply other threads:[~2010-12-23 15:13 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-23 9:33 [U-Boot] Fixing IXP42x boards - some general questions Michael Schwingen
2010-12-23 10:10 ` Wolfgang Denk
2010-12-23 10:55 ` Marek Vasut
2010-12-23 15:13 ` Michael Schwingen [this message]
2010-12-23 12:23 ` Michael Schwingen
2010-12-23 10:20 ` Albert ARIBAUD
2010-12-23 10:39 ` Michael Schwingen
2010-12-23 11:28 ` Albert ARIBAUD
2010-12-23 11:57 ` Michael Schwingen
2010-12-23 18:25 ` Michael Schwingen
2010-12-23 18:47 ` Albert ARIBAUD
2010-12-23 20:17 ` Michael Schwingen
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=20101223151341.GA31823@discworld.dascon.de \
--to=rincewind@discworld.dascon.de \
--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.