From f41fb2b6b66aab395591cabdadbeb1a97c8ec59b Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 6 Dec 2011 14:01:55 +0000 Subject: 2011-12-06 Sebastian Huber * misc/system-clocks.c: New file. * Makefile.am: Reflect change from above. * include/nand-mlc.h: Fixed lpc32xx_mlc_is_bad_page(). * make/custom/lpc32xx.inc, make/custom/lpc32xx_mzx_stage_1.cfg: Flags for EABI tool chain. * configure.ac, include/bsp.h, include/lpc32xx.h, misc/emc.c, misc/i2c.c, rtc/rtc-config.c, startup/bspstarthooks.c: Avoid compile time ARM_CLK and HCLK. --- c/src/lib/libbsp/arm/lpc32xx/ChangeLog | 11 ++ c/src/lib/libbsp/arm/lpc32xx/Makefile.am | 49 ++++---- c/src/lib/libbsp/arm/lpc32xx/configure.ac | 6 - c/src/lib/libbsp/arm/lpc32xx/include/bsp.h | 40 +++++- c/src/lib/libbsp/arm/lpc32xx/include/lpc32xx.h | 6 + c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h | 19 ++- .../lib/libbsp/arm/lpc32xx/make/custom/lpc32xx.inc | 5 +- .../lpc32xx/make/custom/lpc32xx_mzx_stage_1.cfg | 2 + c/src/lib/libbsp/arm/lpc32xx/misc/emc.c | 3 - c/src/lib/libbsp/arm/lpc32xx/misc/i2c.c | 26 ++-- c/src/lib/libbsp/arm/lpc32xx/misc/system-clocks.c | 140 +++++++++++++++++++++ c/src/lib/libbsp/arm/lpc32xx/rtc/rtc-config.c | 15 +-- .../lib/libbsp/arm/lpc32xx/startup/bspstarthooks.c | 73 +++++++---- 13 files changed, 303 insertions(+), 92 deletions(-) create mode 100644 c/src/lib/libbsp/arm/lpc32xx/misc/system-clocks.c diff --git a/c/src/lib/libbsp/arm/lpc32xx/ChangeLog b/c/src/lib/libbsp/arm/lpc32xx/ChangeLog index 28ec9b594b..b179775841 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/ChangeLog +++ b/c/src/lib/libbsp/arm/lpc32xx/ChangeLog @@ -1,3 +1,14 @@ +2011-12-06 Sebastian Huber + + * misc/system-clocks.c: New file. + * Makefile.am: Reflect change from above. + * include/nand-mlc.h: Fixed lpc32xx_mlc_is_bad_page(). + * make/custom/lpc32xx.inc, make/custom/lpc32xx_mzx_stage_1.cfg: Flags + for EABI tool chain. + * configure.ac, include/bsp.h, include/lpc32xx.h, misc/emc.c, + misc/i2c.c, rtc/rtc-config.c, startup/bspstarthooks.c: Avoid compile + time ARM_CLK and HCLK. + 2011-11-29 Joel Sherrill * Makefile.am: Add shared/startup/bsp-start-memcpy.S diff --git a/c/src/lib/libbsp/arm/lpc32xx/Makefile.am b/c/src/lib/libbsp/arm/lpc32xx/Makefile.am index 0e8bbd106d..0a14fa0bdb 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/Makefile.am +++ b/c/src/lib/libbsp/arm/lpc32xx/Makefile.am @@ -82,23 +82,23 @@ libbsp_a_CPPFLAGS = libbsp_a_LIBADD = # Shared -libbsp_a_SOURCES += ../../shared/bootcard.c \ - ../../shared/bspclean.c \ - ../../shared/bspgetworkarea.c \ - ../../shared/bsplibc.c \ - ../../shared/bsppost.c \ - ../../shared/bsppredriverhook.c \ - ../../shared/bsppretaskinghook.c \ - ../../shared/gnatinstallhandler.c \ - ../../shared/sbrk.c \ - ../../shared/src/stackalloc.c \ - ../../shared/src/uart-output-char.c \ - ../shared/abort/simple_abort.c +libbsp_a_SOURCES += ../../shared/bootcard.c +libbsp_a_SOURCES += ../../shared/bspclean.c +libbsp_a_SOURCES += ../../shared/bspgetworkarea.c +libbsp_a_SOURCES += ../../shared/bsplibc.c +libbsp_a_SOURCES += ../../shared/bsppost.c +libbsp_a_SOURCES += ../../shared/bsppredriverhook.c +libbsp_a_SOURCES += ../../shared/bsppretaskinghook.c +libbsp_a_SOURCES += ../../shared/gnatinstallhandler.c +libbsp_a_SOURCES += ../../shared/sbrk.c +libbsp_a_SOURCES += ../../shared/src/stackalloc.c +libbsp_a_SOURCES += ../../shared/src/uart-output-char.c +libbsp_a_SOURCES += ../shared/abort/simple_abort.c libbsp_a_SOURCES += ../shared/startup/bsp-start-memcpy.S # Startup -libbsp_a_SOURCES += startup/bspstart.c \ - startup/bspreset.c +libbsp_a_SOURCES += startup/bspreset.c +libbsp_a_SOURCES += startup/bspstart.c # IRQ libbsp_a_SOURCES += ../../shared/src/irq-generic.c \ @@ -126,16 +126,17 @@ libbsp_a_SOURCES += ../../shared/tod.c \ rtc/rtc-config.c # Misc -libbsp_a_SOURCES += misc/timer.c \ - misc/nand-mlc.c \ - misc/nand-mlc-read-blocks.c \ - misc/nand-mlc-write-blocks.c \ - misc/nand-mlc-erase-block-safe.c \ - misc/restart.c \ - misc/boot.c \ - misc/emc.c \ - misc/mmu.c \ - misc/i2c.c +libbsp_a_SOURCES += misc/boot.c +libbsp_a_SOURCES += misc/emc.c +libbsp_a_SOURCES += misc/i2c.c +libbsp_a_SOURCES += misc/mmu.c +libbsp_a_SOURCES += misc/nand-mlc.c +libbsp_a_SOURCES += misc/nand-mlc-erase-block-safe.c +libbsp_a_SOURCES += misc/nand-mlc-read-blocks.c +libbsp_a_SOURCES += misc/nand-mlc-write-blocks.c +libbsp_a_SOURCES += misc/restart.c +libbsp_a_SOURCES += misc/system-clocks.c +libbsp_a_SOURCES += misc/timer.c # SSP diff --git a/c/src/lib/libbsp/arm/lpc32xx/configure.ac b/c/src/lib/libbsp/arm/lpc32xx/configure.ac index a52c45029b..b78781dc0b 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/configure.ac +++ b/c/src/lib/libbsp/arm/lpc32xx/configure.ac @@ -31,12 +31,6 @@ RTEMS_BSPOPTS_HELP([LPC32XX_OSCILLATOR_MAIN],[main oscillator frequency in Hz]) RTEMS_BSPOPTS_SET([LPC32XX_OSCILLATOR_RTC],[*],[32768U]) RTEMS_BSPOPTS_HELP([LPC32XX_OSCILLATOR_RTC],[RTC oscillator frequency in Hz]) -RTEMS_BSPOPTS_SET([LPC32XX_ARM_CLK],[*],[208000000U]) -RTEMS_BSPOPTS_HELP([LPC32XX_ARM_CLK],[ARM clock in Hz]) - -RTEMS_BSPOPTS_SET([LPC32XX_HCLK],[*],[104000000U]) -RTEMS_BSPOPTS_HELP([LPC32XX_HCLK],[AHB bus clock in Hz]) - RTEMS_BSPOPTS_SET([LPC32XX_PERIPH_CLK],[*],[13000000U]) RTEMS_BSPOPTS_HELP([LPC32XX_PERIPH_CLK],[peripheral clock in Hz]) diff --git a/c/src/lib/libbsp/arm/lpc32xx/include/bsp.h b/c/src/lib/libbsp/arm/lpc32xx/include/bsp.h index 7b904b7b0a..74627ae4df 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/include/bsp.h +++ b/c/src/lib/libbsp/arm/lpc32xx/include/bsp.h @@ -7,12 +7,13 @@ */ /* - * Copyright (c) 2009, 2010 - * embedded brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * + * Copyright (c) 2009-2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -110,6 +111,33 @@ static inline void lpc32xx_micro_seconds_delay(unsigned us) } while (elapsed < delay); } +#if LPC32XX_OSCILLATOR_MAIN == 13000000U + #define LPC32XX_HCLKPLL_CTRL_INIT_VALUE \ + (HCLK_PLL_POWER | HCLK_PLL_DIRECT | HCLK_PLL_M(16 - 1)) + #define LPC32XX_HCLKDIV_CTRL_INIT_VALUE \ + (HCLK_DIV_HCLK(2 - 1) | HCLK_DIV_PERIPH_CLK(16 - 1) | HCLK_DIV_DDRAM_CLK(1)) +#else + #error "unexpected main oscillator frequency" +#endif + +bool lpc32xx_start_pll_setup( + uint32_t hclkpll_ctrl, + uint32_t hclkdiv_ctrl, + bool force +); + +uint32_t lpc32xx_sysclk(void); + +uint32_t lpc32xx_hclkpll_clk(void); + +uint32_t lpc32xx_periph_clk(void); + +uint32_t lpc32xx_hclk(void); + +uint32_t lpc32xx_arm_clk(void); + +uint32_t lpc32xx_dram_clk(void); + void bsp_restart(void *addr); #define BSP_CONSOLE_UART_BASE LPC32XX_BASE_UART_5 diff --git a/c/src/lib/libbsp/arm/lpc32xx/include/lpc32xx.h b/c/src/lib/libbsp/arm/lpc32xx/include/lpc32xx.h index b4ad928ca5..4a14c5626e 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/include/lpc32xx.h +++ b/c/src/lib/libbsp/arm/lpc32xx/include/lpc32xx.h @@ -201,8 +201,11 @@ #define HCLK_PLL_LOCK BSP_BIT32(0) #define HCLK_PLL_M(val) BSP_FLD32(val, 1, 8) +#define HCLK_PLL_M_GET(reg) BSP_FLD32GET(reg, 1, 8) #define HCLK_PLL_N(val) BSP_FLD32(val, 9, 10) +#define HCLK_PLL_N_GET(reg) BSP_FLD32GET(reg, 9, 10) #define HCLK_PLL_P(val) BSP_FLD32(val, 11, 12) +#define HCLK_PLL_P_GET(reg) BSP_FLD32GET(reg, 11, 12) #define HCLK_PLL_FBD_FCLKOUT BSP_BIT32(13) #define HCLK_PLL_DIRECT BSP_BIT32(14) #define HCLK_PLL_BYPASS BSP_BIT32(15) @@ -217,8 +220,11 @@ */ #define HCLK_DIV_HCLK(val) BSP_FLD32(val, 0, 1) +#define HCLK_DIV_HCLK_GET(reg) BSP_FLD32GET(reg, 0, 1) #define HCLK_DIV_PERIPH_CLK(val) BSP_FLD32(val, 2, 6) +#define HCLK_DIV_PERIPH_CLK_GET(reg) BSP_FLD32GET(reg, 2, 6) #define HCLK_DIV_DDRAM_CLK(val) BSP_FLD32(val, 7, 8) +#define HCLK_DIV_DDRAM_CLK_GET(reg) BSP_FLD32GET(reg, 7, 8) /** @} */ diff --git a/c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h b/c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h index 61d035bb94..cc91a7956b 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h +++ b/c/src/lib/libbsp/arm/lpc32xx/include/nand-mlc.h @@ -392,10 +392,25 @@ rtems_status_code lpc32xx_mlc_read_blocks( uint32_t page_buffer_1 [MLC_LARGE_DATA_WORD_COUNT] ); +/** + * @brief Checks if the page spare area indicates to a bad page. + * + * If the first (byte offset 0) or sixth (byte offset 5) byte of the spare area + * has a value other than 0xff, then it returns @true (the page is bad), else + * it returns @a false (the page is not bad). + * + * Samsung uses the sixth byte to indicate a bad page. Mircon uses the first + * and sixth byte to indicate a bad page. + * + * This functions works only for small page flashes. + */ static inline bool lpc32xx_mlc_is_bad_page(const uint32_t *spare) { - uint32_t valid_block_mask = 0xff00; - return (spare [1] & valid_block_mask) != valid_block_mask; + uint32_t first_byte_mask = 0x000000ff; + uint32_t sixth_byte_mask = 0x0000ff00; + + return (spare [0] & first_byte_mask) != first_byte_mask + || (spare [1] & sixth_byte_mask) != sixth_byte_mask; } /** @} */ diff --git a/c/src/lib/libbsp/arm/lpc32xx/make/custom/lpc32xx.inc b/c/src/lib/libbsp/arm/lpc32xx/make/custom/lpc32xx.inc index 79fdd7ce68..ed373827f4 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/make/custom/lpc32xx.inc +++ b/c/src/lib/libbsp/arm/lpc32xx/make/custom/lpc32xx.inc @@ -8,7 +8,6 @@ include $(RTEMS_ROOT)/make/custom/default.cfg RTEMS_CPU = arm -CPU_CFLAGS = -mstructure-size-boundary=8 -mcpu=arm926ej-s -mfpu=vfp -mfloat-abi=soft -mthumb \ - -fno-schedule-insns2 +CPU_CFLAGS = -mcpu=arm926ej-s -mthumb -CFLAGS_OPTIMIZE_V = -O2 -g +CFLAGS_OPTIMIZE_V ?= -O2 -g diff --git a/c/src/lib/libbsp/arm/lpc32xx/make/custom/lpc32xx_mzx_stage_1.cfg b/c/src/lib/libbsp/arm/lpc32xx/make/custom/lpc32xx_mzx_stage_1.cfg index c2127b14b3..043adf5be9 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/make/custom/lpc32xx_mzx_stage_1.cfg +++ b/c/src/lib/libbsp/arm/lpc32xx/make/custom/lpc32xx_mzx_stage_1.cfg @@ -4,4 +4,6 @@ # $Id$ # +CFLAGS_OPTIMIZE_V = -Os -g + include $(RTEMS_ROOT)/make/custom/lpc32xx.inc diff --git a/c/src/lib/libbsp/arm/lpc32xx/misc/emc.c b/c/src/lib/libbsp/arm/lpc32xx/misc/emc.c index b9e8152e47..cdfe2153a7 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/misc/emc.c +++ b/c/src/lib/libbsp/arm/lpc32xx/misc/emc.c @@ -93,9 +93,6 @@ static void dynamic_init(const lpc32xx_emc_dynamic_config *cfg) void lpc32xx_emc_init(const lpc32xx_emc_dynamic_config *dyn_cfg) { - /* Enable clock */ - LPC32XX_HCLKDIV_CTRL |= HCLK_DIV_DDRAM_CLK(1); - /* Enable buffers in AHB ports */ emc_ahb [0].control = EMC_AHB_PORT_BUFF_EN; emc_ahb [3].control = EMC_AHB_PORT_BUFF_EN; diff --git a/c/src/lib/libbsp/arm/lpc32xx/misc/i2c.c b/c/src/lib/libbsp/arm/lpc32xx/misc/i2c.c index 60526d4fe0..8dfdc58cfc 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/misc/i2c.c +++ b/c/src/lib/libbsp/arm/lpc32xx/misc/i2c.c @@ -7,12 +7,13 @@ */ /* - * Copyright (c) 2010 - * embedded brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * + * Copyright (c) 2010-2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -51,31 +52,28 @@ rtems_status_code lpc32xx_i2c_init( return lpc32xx_i2c_clock(i2c, clock_in_hz); } -#if LPC32XX_HCLK != 104000000U - #error "unexpected HCLK" -#endif - rtems_status_code lpc32xx_i2c_clock( volatile lpc32xx_i2c *i2c, unsigned clock_in_hz ) { + uint32_t clk_div = lpc32xx_hclk() / clock_in_hz; uint32_t clk_lo = 0; uint32_t clk_hi = 0; switch (clock_in_hz) { case 100000: - clk_lo = 520; - clk_hi = 520; + clk_lo = clk_div / 2; break; case 400000: - clk_lo = 166; - clk_hi = 94; + clk_lo = (64 * clk_div) / 100; break; default: return RTEMS_INVALID_CLOCK; } + clk_hi = clk_div - clk_lo; + i2c->clk_lo = clk_lo; i2c->clk_hi = clk_hi; diff --git a/c/src/lib/libbsp/arm/lpc32xx/misc/system-clocks.c b/c/src/lib/libbsp/arm/lpc32xx/misc/system-clocks.c new file mode 100644 index 0000000000..f324ef869f --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc32xx/misc/system-clocks.c @@ -0,0 +1,140 @@ +/** + * @file + * + * @ingroup lpc32xx + * + * @brief System clocks. + */ + +/* + * Copyright (c) 2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include + +uint32_t lpc32xx_sysclk(void) +{ + uint32_t sysclk_ctrl = LPC32XX_SYSCLK_CTRL; + + return (sysclk_ctrl & 0x1) == 0 ? + LPC32XX_OSCILLATOR_MAIN + : (397 * LPC32XX_OSCILLATOR_RTC); +} + +uint32_t lpc32xx_hclkpll_clk(void) +{ + uint32_t sysclk = lpc32xx_sysclk(); + uint32_t hclkpll_ctrl = LPC32XX_HCLKPLL_CTRL; + uint32_t m = HCLK_PLL_M_GET(hclkpll_ctrl) + 1; + uint32_t n = HCLK_PLL_N_GET(hclkpll_ctrl) + 1; + uint32_t p = 1U << HCLK_PLL_P_GET(hclkpll_ctrl); + uint32_t hclkpll_clk = 0; + + if ((hclkpll_ctrl & HCLK_PLL_BYPASS) != 0) { + if ((hclkpll_ctrl & HCLK_PLL_DIRECT) != 0) { + hclkpll_clk = sysclk; + } else { + hclkpll_clk = sysclk / (2 * p); + } + } else { + if ((hclkpll_ctrl & HCLK_PLL_DIRECT) != 0) { + hclkpll_clk = (m * sysclk) / n; + } else { + if ((hclkpll_ctrl & HCLK_PLL_FBD_FCLKOUT) != 0) { + hclkpll_clk = m * (sysclk / n); + } else { + hclkpll_clk = (m / (2 * p)) * (sysclk / n); + } + } + } + + return hclkpll_clk; +} + +uint32_t lpc32xx_periph_clk(void) +{ + uint32_t pwr_ctrl = LPC32XX_PWR_CTRL; + uint32_t periph_clk = 0; + + if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) != 0) { + uint32_t hclkdiv_ctrl = LPC32XX_HCLKDIV_CTRL; + uint32_t div = HCLK_DIV_PERIPH_CLK_GET(hclkdiv_ctrl) + 1; + + periph_clk = lpc32xx_hclkpll_clk() / div; + } else { + periph_clk = lpc32xx_sysclk(); + } + + return periph_clk; +} + +uint32_t lpc32xx_hclk(void) +{ + uint32_t pwr_ctrl = LPC32XX_PWR_CTRL; + uint32_t hclk = 0; + + if ((pwr_ctrl & PWR_HCLK_USES_PERIPH_CLK) != 0) { + hclk = lpc32xx_periph_clk(); + } else { + if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) != 0) { + uint32_t hclkdiv_ctrl = LPC32XX_HCLKDIV_CTRL; + uint32_t div = 1U << HCLK_DIV_HCLK_GET(hclkdiv_ctrl); + + hclk = lpc32xx_hclkpll_clk() / div; + } else { + hclk = lpc32xx_sysclk(); + } + } + + return hclk; +} + +uint32_t lpc32xx_arm_clk(void) +{ + uint32_t pwr_ctrl = LPC32XX_PWR_CTRL; + uint32_t arm_clk = 0; + + if ((pwr_ctrl & PWR_HCLK_USES_PERIPH_CLK) != 0) { + arm_clk = lpc32xx_periph_clk(); + } else { + if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) != 0) { + arm_clk = lpc32xx_hclkpll_clk(); + } else { + arm_clk = lpc32xx_sysclk(); + } + } + + return arm_clk; +} + +uint32_t lpc32xx_dram_clk(void) +{ + uint32_t hclkdiv_ctrl = LPC32XX_HCLKDIV_CTRL; + uint32_t div = HCLK_DIV_DDRAM_CLK_GET(hclkdiv_ctrl); + uint32_t dram_clk = 0; + + if (div != 0) { + uint32_t pwr_ctrl = LPC32XX_PWR_CTRL; + + if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) != 0) { + dram_clk = lpc32xx_hclkpll_clk(); + } else { + dram_clk = lpc32xx_sysclk(); + } + + dram_clk /= div; + } + + return dram_clk; +} diff --git a/c/src/lib/libbsp/arm/lpc32xx/rtc/rtc-config.c b/c/src/lib/libbsp/arm/lpc32xx/rtc/rtc-config.c index 8268df311d..bcbc20fce9 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/rtc/rtc-config.c +++ b/c/src/lib/libbsp/arm/lpc32xx/rtc/rtc-config.c @@ -7,12 +7,13 @@ */ /* - * Copyright (c) 2009 - * embedded brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * + * Copyright (c) 2009-2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -40,7 +41,7 @@ static void lpc32xx_rtc_set(uint32_t val) { - unsigned i = LPC32XX_ARM_CLK / LPC32XX_OSCILLATOR_RTC; + unsigned i = lpc32xx_arm_clk() / LPC32XX_OSCILLATOR_RTC; lpc32xx.rtc.ctrl |= LPC32XX_RTC_CTRL_STOP; lpc32xx.rtc.ucount = val; diff --git a/c/src/lib/libbsp/arm/lpc32xx/startup/bspstarthooks.c b/c/src/lib/libbsp/arm/lpc32xx/startup/bspstarthooks.c index 05fcdba6b6..e1b79ebf90 100644 --- a/c/src/lib/libbsp/arm/lpc32xx/startup/bspstarthooks.c +++ b/c/src/lib/libbsp/arm/lpc32xx/startup/bspstarthooks.c @@ -7,21 +7,20 @@ */ /* - * Copyright (c) 2009 - * embedded brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * + * Copyright (c) 2009-2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. */ -#include - -#include +#include #include #include #include @@ -44,7 +43,7 @@ LINKER_SYMBOL(lpc32xx_translation_table_base); -static void BSP_START_TEXT_SECTION clear_bss(void) +static BSP_START_TEXT_SECTION void clear_bss(void) { const int *end = (const int *) bsp_section_bss_end; int *out = (int *) bsp_section_bss_begin; @@ -134,7 +133,7 @@ static void BSP_START_TEXT_SECTION clear_bss(void) } }; - static void BSP_START_TEXT_SECTION set_translation_table_entries( + static BSP_START_TEXT_SECTION void set_translation_table_entries( uint32_t *ttb, const lpc32xx_mmu_config *config ) @@ -151,7 +150,7 @@ static void BSP_START_TEXT_SECTION clear_bss(void) } } - static void BSP_START_TEXT_SECTION + static BSP_START_TEXT_SECTION void setup_translation_table_and_enable_mmu(uint32_t ctrl) { uint32_t const dac = @@ -179,7 +178,7 @@ static void BSP_START_TEXT_SECTION clear_bss(void) } #endif -static void BSP_START_TEXT_SECTION setup_mmu_and_cache(void) +static BSP_START_TEXT_SECTION void setup_mmu_and_cache(void) { uint32_t ctrl = 0; @@ -198,36 +197,56 @@ static void BSP_START_TEXT_SECTION setup_mmu_and_cache(void) #endif } -#if LPC32XX_OSCILLATOR_MAIN != 13000000U - #error "unexpected main oscillator frequency" -#endif - -static void BSP_START_TEXT_SECTION setup_pll(void) +BSP_START_TEXT_SECTION bool lpc32xx_start_pll_setup( + uint32_t hclkpll_ctrl, + uint32_t hclkdiv_ctrl, + bool force +) { uint32_t pwr_ctrl = LPC32XX_PWR_CTRL; + bool settings_ok = + ((LPC32XX_HCLKPLL_CTRL ^ hclkpll_ctrl) & BSP_MSK32(1, 16)) == 0 + && ((LPC32XX_HCLKDIV_CTRL ^ hclkdiv_ctrl) & BSP_MSK32(0, 8)) == 0; - if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) == 0) { - /* Enable HCLK PLL */ - LPC32XX_HCLKPLL_CTRL = HCLK_PLL_POWER | HCLK_PLL_DIRECT | HCLK_PLL_M(16 - 1); + if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) == 0 || (!settings_ok && force)) { + /* Disable HCLK PLL output */ + LPC32XX_PWR_CTRL = pwr_ctrl & ~PWR_NORMAL_RUN_MODE; + + /* Configure HCLK PLL */ + LPC32XX_HCLKPLL_CTRL = hclkpll_ctrl; while ((LPC32XX_HCLKPLL_CTRL & HCLK_PLL_LOCK) == 0) { /* Wait */ } /* Setup HCLK divider */ - LPC32XX_HCLKDIV_CTRL = HCLK_DIV_HCLK(2 - 1) | HCLK_DIV_PERIPH_CLK(16 - 1); + LPC32XX_HCLKDIV_CTRL = hclkdiv_ctrl; /* Enable HCLK PLL output */ LPC32XX_PWR_CTRL = pwr_ctrl | PWR_NORMAL_RUN_MODE; } + + return settings_ok; +} + +#if LPC32XX_OSCILLATOR_MAIN != 13000000U + #error "unexpected main oscillator frequency" +#endif + +static BSP_START_TEXT_SECTION void setup_pll(void) +{ + uint32_t hclkpll_ctrl = LPC32XX_HCLKPLL_CTRL_INIT_VALUE; + uint32_t hclkdiv_ctrl = LPC32XX_HCLKDIV_CTRL_INIT_VALUE; + + lpc32xx_start_pll_setup(hclkpll_ctrl, hclkdiv_ctrl, false); } -void BSP_START_TEXT_SECTION bsp_start_hook_0(void) +BSP_START_TEXT_SECTION void bsp_start_hook_0(void) { setup_pll(); setup_mmu_and_cache(); } -static void BSP_START_TEXT_SECTION stop_dma_activities(void) +static BSP_START_TEXT_SECTION void stop_dma_activities(void) { #ifdef LPC32XX_STOP_GPDMA LPC32XX_DO_STOP_GPDMA; @@ -242,7 +261,7 @@ static void BSP_START_TEXT_SECTION stop_dma_activities(void) #endif } -static void BSP_START_TEXT_SECTION setup_uarts(void) +static BSP_START_TEXT_SECTION void setup_uarts(void) { uint32_t uartclk_ctrl = 0; @@ -277,7 +296,7 @@ static void BSP_START_TEXT_SECTION setup_uarts(void) #endif } -static void BSP_START_TEXT_SECTION setup_timer(void) +static BSP_START_TEXT_SECTION void setup_timer(void) { volatile lpc_timer *timer = LPC32XX_STANDARD_TIMER; @@ -292,7 +311,7 @@ static void BSP_START_TEXT_SECTION setup_timer(void) timer->tcr = LPC_TIMER_TCR_EN; } -void BSP_START_TEXT_SECTION bsp_start_hook_1(void) +BSP_START_TEXT_SECTION void bsp_start_hook_1(void) { stop_dma_activities(); setup_uarts(); -- cgit v1.2.3