This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
test if the PMC is allready up - patch for at91sam7's hal_platform_setup.h...
- From: "oliver munz @ s p e a g" <munz at speag dot ch>
- To: ecos-patches at sourceware dot org, Andrew Lunn <andrew at lunn dot ch>
- Date: Tue, 26 May 2009 21:53:11 +0200
- Subject: test if the PMC is allready up - patch for at91sam7's hal_platform_setup.h...
- Reply-to: munz at speag dot ch
In packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h
the "__main_clock_init__" sets the CPU-clock to 32kHz, enables the
x-tal-oscillator and then configures the PLL. This makes unnecessary
problems if the ecos-application is started from the redboot or from a
JTAG-emulator like BDI2ooo and so on, where the CPU-clock is already set.
further more there is no usefully situation where its good to switch the
CPU to 32kHz, if the x-tal oscillator is allready stable running.
This patch will test if the three relevant PMC-registers are set
correct, and change the values only if it's needed. So it makes startup
from readboot faster, makes debuging simpler and avoid changes of the
system-clock...
For simple flash-programming via JTAG-emulator, the initialisation of
the flash-controller-register is improved.
And the flash-driver is changed to make the same settings like
hal_platform_setup.h...
Index: packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h,v
retrieving revision 1.5
diff -u -r1.5 hal_platform_setup.h
--- packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h 2 Sep 2008 05:37:51 -0000 1.5
+++ packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h 26 May 2009 19:04:35 -0000
@@ -46,7 +46,7 @@
// Contributors:gthomas, asl
// Date: 2006-02-18
// Purpose: AT91SAM7S platform specific support routines
-// Description:
+// Description:
// Usage: #include <cyg/hal/hal_platform_setup.h>
//
//####DESCRIPTIONEND####
@@ -56,20 +56,31 @@
#include <cyg/hal/var_io.h>
#include <cyg/hal/plf_io.h>
+#define AT91_FLASH_FMCN_VALUE (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED * 15 / 10000000 + 1)
+#if defined(CYGNUM_HAL_ARM_AT91_CLOCK_TYPE_EXTCLOCK)
+# define AT91_PMC_MOR_VALUE (AT91_PMC_MOR_OSCBYPASS)
+#else
+# define AT91_PMC_MOR_VALUE (AT91_PMC_MOR_OSCCOUNT(CYGNUM_HAL_ARM_AT91_PMC_MOR_OSCCOUNT) | AT91_PMC_MOR_MOSCEN)
+#endif
+#define AT91_PMC_PLLR_VALUE (AT91_PMC_PLLR_DIV(CYGNUM_HAL_ARM_AT91_PLL_DIVIDER) | AT91_PMC_PLLR_PLLCOUNT(CYGNUM_HAL_ARM_AT91_PLL_COUNT) | AT91_PMC_PLLR_MUL(CYGNUM_HAL_ARM_AT91_PLL_MULTIPLIER-1) | AT91_PMC_PLLR_USBDIV_1)
+#define AT91_PMC_MCKR_VALUE (AT91_PMC_MCKR_PRES_CLK_2 | AT91_PMC_MCKR_PLL_CLK)
+
+
+
// Macro to initialise the Memory Controller
.macro _flash_init
__flash_init__:
ldr r0,=AT91_MC
#if CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 60000000
// When the clock is running faster than 60MHz we need two wait states
- ldr r1,=(AT91_MC_FMR_2FWS)
-#else
+ ldr r1,=(AT91_MC_FMR_2FWS | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT))
+#else
# if CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 30000000
// When the clock is running faster than 30MHz we need a wait state
- ldr r1,=(AT91_MC_FMR_1FWS)
+ ldr r1,=(AT91_MC_FMR_1FWS | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT))
# else
// We have a slow clock, no extra wait states are needed
- ldr r1,=AT91_MC_FMR_0FWS
+ ldr r1,=(AT91_MC_FMR_0FWS | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT))
# endif
#endif
str r1,[r0,#AT91_MC_FMR]
@@ -84,33 +95,38 @@
__main_clock_init__:
ldr r0,=AT91_PMC
- // Check that we have a stable clock before we start switching
+ ldr r2,=AT91_PMC_MOR_VALUE // Load our PMC settings in registers
+ ldr r3,=AT91_PMC_PLLR_VALUE
+ ldr r4,=AT91_PMC_MCKR_VALUE
+
+ ldr r5,[r0,#AT91_PMC_MOR] // Test if the PMC is allready up
+ cmp r2, r5
+ bne wait_pmc_sr_0 // Do the init
+ ldr r5,[r0,#AT91_PMC_PLLR]
+ cmp r3, r5
+ bne wait_pmc_sr_0 // Do the init
+ ldr r5,[r0,#AT91_PMC_MCKR]
+ cmp r4, r5
+ bne wait_pmc_sr_0 // Do the init
+ b pmc_done // All registers are where we want it...
+
+ // We have to set the PMC
wait_pmc_sr_0:
ldr r1,[r0,#AT91_PMC_SR]
ands r1,r1,#AT91_PMC_SR_MCKRDY
beq wait_pmc_sr_0
- // Swap to the slow clock, just to be sure.
- ldr r1,=(AT91_PMC_MCKR_PRES_CLK|AT91_PMC_MCKR_SLOW_CLK)
- str r1,[r0,#AT91_PMC_MCKR]
-
-#if defined(CYGNUM_HAL_ARM_AT91_CLOCK_TYPE_EXTCLOCK)
- ldr r1,=(AT91_PMC_MOR_OSCBYPASS)
-#else
- ldr r1,=(AT91_PMC_MOR_OSCCOUNT(CYGNUM_HAL_ARM_AT91_PMC_MOR_OSCCOUNT)|AT91_PMC_MOR_MOSCEN)
-#endif
- str r1,[r0,#AT91_PMC_MOR]
+ str r2,[r0,#AT91_PMC_MOR]
// Wait for oscilator start timeout
-wait_pmc_sr_1:
+wait_pmc_sr_1:
ldr r1,[r0,#AT91_PMC_SR]
ands r1,r1,#AT91_PMC_SR_MOSCS
beq wait_pmc_sr_1
// Set the PLL multiplier and divider. 16 slow clocks go by
// before the LOCK bit is set. */
- ldr r1,=((AT91_PMC_PLLR_DIV(CYGNUM_HAL_ARM_AT91_PLL_DIVIDER))|(AT91_PMC_PLLR_PLLCOUNT(CYGNUM_HAL_ARM_AT91_PLL_COUNT))|(AT91_PMC_PLLR_MUL(CYGNUM_HAL_ARM_AT91_PLL_MULTIPLIER-1)))
- str r1,[r0,#AT91_PMC_PLLR]
+ str r3,[r0,#AT91_PMC_PLLR]
// Wait for PLL locked indication
wait_pmc_sr_2:
@@ -119,14 +135,14 @@
beq wait_pmc_sr_2
// Enable the PLL clock and set the prescale to 2 */
- ldr r1,=(AT91_PMC_MCKR_PRES_CLK_2|AT91_PMC_MCKR_PLL_CLK)
- str r1,[r0,#AT91_PMC_MCKR]
+ str r4,[r0,#AT91_PMC_MCKR]
// Wait for the MCLK ready indication
wait_pmc_sr_3:
ldr r1,[r0,#AT91_PMC_SR]
ands r1,r1,#AT91_PMC_SR_MCKRDY
beq wait_pmc_sr_3
+pmc_done:
.endm
// Remap the flash from address 0x0 and place RAM there instead.
Index: packages/devs/flash/arm/at91/current/src/at91_flash.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/arm/at91/current/src/at91_flash.c,v
retrieving revision 1.9
diff -u -r1.9 at91_flash.c
--- packages/devs/flash/arm/at91/current/src/at91_flash.c 3 Nov 2008 08:41:59 -0000 1.9
+++ packages/devs/flash/arm/at91/current/src/at91_flash.c 26 May 2009 19:04:28 -0000
// Set the FLASH clock to 1.5 microseconds based on the MCLK. This
// assumes the CPU is still running from the PLL clock as defined in
- // the HAL CDL and the HAL startup code.
- fmcn = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED * 1.5 / 1000000 + 0.999999; // We must round up!
+ // the HAL CDL and the HAL startup code.
+ fmcn = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED * 15 / 10000000 + 1; // We must round up!
HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, flash_mode);
flash_mode = flash_mode & ~AT91_MC_FMR_FMCN_MASK;
// Map a hardware status to a package error. NOP since the errors are
// already mapped.
int flash_hwr_map_error(int err){