Hi Heiko,

On 10/30/2014 04:15 PM, Heiko Schocher wrote:
diff --git a/arch/arm/cpu/at91-common/spl.c b/arch/arm/cpu/at91-common/spl.c
index 674a470..5c9a3ad 100644
--- a/arch/arm/cpu/at91-common/spl.c
+++ b/arch/arm/cpu/at91-common/spl.c

I am thinking, whether it be better to keep this file as two copy? This will remove #ifdef, although a little code duplication.

If this solution acceptable, some suggestion as following:
  - for armv5 (arm926ejs, now at91 series), named it spl_at91.c,
  - for armv7 (cortex-a5, now, sama5d3), named it spl_atmel.c?
(As for arm9 series, we have at91 prefix for SoC name, and for armv7 SoC, we don't have at91 prefix, and it now changed to Atmel Smart)

@@ -8,11 +8,18 @@
  #include <common.h>
  #include <asm/io.h>
  #include <asm/arch/at91_common.h>
+#if !defined(CONFIG_SAMA5D3)
+#include <asm/arch/at91sam9_matrix.h>
+#endif
+#include <asm/arch/at91_pit.h>
  #include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91_rstc.h>
  #include <asm/arch/at91_wdt.h>
  #include <asm/arch/clk.h>
  #include <spl.h>

+DECLARE_GLOBAL_DATA_PTR;
+
  static void at91_disable_wdt(void)
  {
        struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT;
@@ -20,6 +27,33 @@ static void at91_disable_wdt(void)
        writel(AT91_WDT_MR_WDDIS, &wdt->mr);
  }

+u32 spl_boot_device(void)
+{
+#ifdef CONFIG_SYS_USE_MMC
+       return BOOT_DEVICE_MMC1;
+#elif CONFIG_SYS_USE_NANDFLASH
+       return BOOT_DEVICE_NAND;
+#elif CONFIG_SYS_USE_SERIALFLASH
+       return BOOT_DEVICE_SPI;
+#endif
+       return BOOT_DEVICE_NONE;
+}
+
+u32 spl_boot_mode(void)
+{
+       switch (spl_boot_device()) {
+#ifdef CONFIG_SYS_USE_MMC
+       case BOOT_DEVICE_MMC1:
+               return MMCSD_MODE_FS;
+               break;
+#endif
+       case BOOT_DEVICE_NONE:
+       default:
+               hang();
+       }
+}
+
+#if defined(CONFIG_SAMA5D3)
  static void switch_to_main_crystal_osc(void)
  {
        struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
@@ -57,77 +91,134 @@ static void switch_to_main_crystal_osc(void)
        writel(tmp, &pmc->mor);
  }

-void at91_plla_init(u32 pllar)
+void s_init(void)
  {
-       struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+       switch_to_main_crystal_osc();

-       writel(pllar, &pmc->pllar);
-       while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY)))
-               ;
-}
+       /* disable watchdog */
+       at91_disable_wdt();

-void at91_mck_init(u32 mckr)
-{
-       struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
-       u32 tmp;
+       /* PMC configuration */
+       at91_pmc_init();

-       tmp = readl(&pmc->mckr);
-       tmp &= ~(AT91_PMC_MCKR_PRES_MASK |
-                AT91_PMC_MCKR_MDIV_MASK |
-                AT91_PMC_MCKR_PLLADIV_2);
-       tmp |= mckr & (AT91_PMC_MCKR_PRES_MASK |
-                      AT91_PMC_MCKR_MDIV_MASK |
-                      AT91_PMC_MCKR_PLLADIV_2);
-       writel(tmp, &pmc->mckr);
+       at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK);

-       while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
-               ;
-}
+       timer_init();

+       board_early_init_f();

-u32 spl_boot_device(void)
+       preloader_console_init();
+
+       mem_init();
+}
+#else
+static void enable_ext_reset(void)
  {
-#ifdef CONFIG_SYS_USE_MMC
-       return BOOT_DEVICE_MMC1;
-#elif CONFIG_SYS_USE_NANDFLASH
-       return BOOT_DEVICE_NAND;
-#elif CONFIG_SYS_USE_SERIALFLASH
-       return BOOT_DEVICE_SPI;
-#endif
-       return BOOT_DEVICE_NONE;
+       struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC;
+
+       writel(AT91_RSTC_KEY | AT91_RSTC_MR_URSTEN, &rstc->mr);
  }

-u32 spl_boot_mode(void)
+#if defined(CONFIG_ATMEL_MATRIX_INIT)
+static void matrix_init(void)
  {
-       switch (spl_boot_device()) {
-#ifdef CONFIG_SYS_USE_MMC
-       case BOOT_DEVICE_MMC1:
-               return MMCSD_MODE_FS;
-               break;
+       struct at91_matrix *mat = (struct at91_matrix *)ATMEL_BASE_MATRIX;
+
+       writel((readl(&mat->scfg[3]) & (~AT91_MATRIX_SLOT_CYCLE))
+                       | AT91_MATRIX_SLOT_CYCLE_(0x40),
+                       &mat->scfg[3]);
+}
  #endif
-       case BOOT_DEVICE_NONE:
-       default:
-               hang();
+
+void lowlevel_clock_init(void)
+{
+       struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+
+       if (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) {
+               /* Enable Main Oscillator */
+               writel(AT91_PMC_MOSCS | (0x40 << 8), &pmc->mor);
+
+               /* Wait until Main Oscillator is stable */
+               while (!(readl(&pmc->sr) & AT91_PMC_MOSCS))
+                       ;
        }
+
+       /* After stabilization, switch to Main Oscillator */
+       if ((readl(&pmc->mckr) & AT91_PMC_CSS) == AT91_PMC_CSS_SLOW) {
+               unsigned long tmp;
+
+               tmp = readl(&pmc->mckr);
+               tmp &= ~AT91_PMC_CSS;
+               tmp |= AT91_PMC_CSS_MAIN;
+               writel(tmp, &pmc->mckr);
+               while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
+                       ;
+
+               tmp &= ~AT91_PMC_PRES;
+               tmp |= AT91_PMC_PRES_1;
+               writel(tmp, &pmc->mckr);
+               while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
+                       ;
+       }
+
+       return;
  }

-void s_init(void)
+void __weak at91_spl_board_init(void)
  {
-       switch_to_main_crystal_osc();
+}

-       /* disable watchdog */
+void spl_board_init(void)
+{
+       struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+
+       lowlevel_clock_init();
        at91_disable_wdt();

-       /* PMC configuration */
-       at91_pmc_init();
+       /*
+        * At this stage the main oscillator is supposed to be enabled
+        * PCK = MCK = MOSC
+        */
+       writel(0x00, &pmc->pllicpr);

-       at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK);
+       /* Configure PLLA = MOSC * (PLL_MULA + 1) / PLL_DIVA */
+       at91_plla_init(CONFIG_SYS_AT91_PLLA);

-       timer_init();
+       /* PCK = PLLA = 2 * MCK */
+       at91_mck_init(CONFIG_SYS_MCKR);

-       board_early_init_f();
+       /* Switch MCK on PLLA output */
+       at91_mck_init(CONFIG_SYS_MCKR_CSS);
+
+#if defined(CONFIG_SYS_AT91_PLLB)
+       /* Configure PLLB */
+       at91_pllb_init(CONFIG_SYS_AT91_PLLB);
+#endif
+
+       /* Enable External Reset */
+       enable_ext_reset();

+#if defined(CONFIG_ATMEL_MATRIX_INIT)
+       /* Initialize matrix */
+       matrix_init();
+#endif

Can this also be weak function? And put matrix_init() code to SoC/board related file.

+       gd->arch.mck_rate_hz = CONFIG_SYS_MASTER_CLOCK;
+       /*
+        * init timer long enough for using in spl.
+        */
+       timer_init();
+
+       /* enable clocks for all PIOs */
+       at91_periph_clk_enable(ATMEL_ID_PIOA);
+       at91_periph_clk_enable(ATMEL_ID_PIOB);
+       at91_periph_clk_enable(ATMEL_ID_PIOC);
+       /* init console */
+       at91_seriald_hw_init();
        preloader_console_init();

        mem_init();
+
+       at91_spl_board_init();
  }
+#endif

Best Regards,
Bo Shen

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to