#include <common.h>
#include <asm/io.h>
+#include <asm/arch/at91sam9260_matrix.h>
#include <asm/arch/at91_common.h>
#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91sam9_sdramc.h>
#include <asm/arch/gpio.h>
/*
#endif
}
#endif
+
+void at91_sdram_hw_init(void)
+{
+ at91_set_a_periph(AT91_PIO_PORTC, 16, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 17, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 18, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 19, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 20, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 21, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 22, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 23, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 24, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 25, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 26, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 27, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 28, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 29, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 30, 0);
+ at91_set_a_periph(AT91_PIO_PORTC, 31, 0);
+}
return 0;
}
+
+#if !defined(AT91_PLL_LOCK_TIMEOUT)
+#define AT91_PLL_LOCK_TIMEOUT 1000000
+#endif
+
+void at91_plla_init(u32 pllar)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+ int timeout = AT91_PLL_LOCK_TIMEOUT;
+
+ writel(pllar, &pmc->pllar);
+ while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY))) {
+ timeout--;
+ if (timeout == 0)
+ break;
+ }
+}
+void at91_pllb_init(u32 pllbr)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+ int timeout = AT91_PLL_LOCK_TIMEOUT;
+
+ writel(pllbr, &pmc->pllbr);
+ while (!(readl(&pmc->sr) & (AT91_PMC_LOCKB | AT91_PMC_MCKRDY))) {
+ timeout--;
+ if (timeout == 0)
+ break;
+ }
+}
+
+void at91_mck_init(u32 mckr)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+ int timeout = AT91_PLL_LOCK_TIMEOUT;
+ u32 tmp;
+
+ tmp = readl(&pmc->mckr);
+ tmp &= ~(AT91_PMC_MCKR_PRES_MASK |
+ AT91_PMC_MCKR_MDIV_MASK |
+ AT91_PMC_MCKR_PLLADIV_MASK |
+ AT91_PMC_MCKR_CSS_MASK);
+ tmp |= mckr & (AT91_PMC_MCKR_PRES_MASK |
+ AT91_PMC_MCKR_MDIV_MASK |
+ AT91_PMC_MCKR_PLLADIV_MASK |
+ AT91_PMC_MCKR_CSS_MASK);
+ writel(tmp, &pmc->mckr);
+
+ while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) {
+ timeout--;
+ if (timeout == 0)
+ break;
+ }
+}
+
+void at91_periph_clk_enable(int id)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+
+ writel(1 << id, &pmc->pcer);
+}
return 0;
}
+void at91_plla_init(u32 pllar)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+
+ writel(pllar, &pmc->pllar);
+ while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY)))
+ ;
+}
+
+void at91_mck_init(u32 mckr)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+ u32 tmp;
+
+ tmp = readl(&pmc->mckr);
+ tmp &= ~(AT91_PMC_MCKR_CSS_MASK |
+ AT91_PMC_MCKR_PRES_MASK |
+ AT91_PMC_MCKR_MDIV_MASK |
+ AT91_PMC_MCKR_PLLADIV_2);
+ tmp |= mckr & (AT91_PMC_MCKR_CSS_MASK |
+ AT91_PMC_MCKR_PRES_MASK |
+ AT91_PMC_MCKR_MDIV_MASK |
+ AT91_PMC_MCKR_PLLADIV_2);
+ writel(tmp, &pmc->mckr);
+
+ while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
+ ;
+}
+
void at91_periph_clk_enable(int id)
{
struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
obj-$(CONFIG_AT91_WANTS_COMMON_PHY) += phy.o
ifneq ($(CONFIG_SPL_BUILD),)
-obj-$(CONFIG_AT91SAM9M10G45) += mpddrc.o
-obj-$(CONFIG_SAMA5D3) += mpddrc.o
+obj-$(CONFIG_AT91SAM9G20) += sdram.o spl_at91.o
+obj-$(CONFIG_AT91SAM9M10G45) += mpddrc.o spl_at91.o
+obj-$(CONFIG_SAMA5D3) += mpddrc.o spl_atmel.o
obj-y += spl.o
endif
--- /dev/null
+/*
+ * (C) Copyright 2014
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * (C) Copyright 2007-2008
+ * Stelian Pop <stelian@popies.net>
+ * Lead Tech Design <www.leadtechdesign.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/at91_common.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91sam9_sdramc.h>
+#include <asm/arch/gpio.h>
+
+int sdramc_initialize(unsigned int sdram_address, const struct sdramc_reg *p)
+{
+ struct sdramc_reg *reg = (struct sdramc_reg *)ATMEL_BASE_SDRAMC;
+ unsigned int i;
+
+ /* SDRAM feature must be in the configuration register */
+ writel(p->cr, ®->cr);
+
+ /* The SDRAM memory type must be set in the Memory Device Register */
+ writel(p->mdr, ®->mdr);
+
+ /*
+ * The minimum pause of 200 us is provided to precede any single
+ * toggle
+ */
+ for (i = 0; i < 1000; i++)
+ ;
+
+ /* A NOP command is issued to the SDRAM devices */
+ writel(AT91_SDRAMC_MODE_NOP, ®->mr);
+ writel(0x00000000, sdram_address);
+
+ /* An All Banks Precharge command is issued to the SDRAM devices */
+ writel(AT91_SDRAMC_MODE_PRECHARGE, ®->mr);
+ writel(0x00000000, sdram_address);
+
+ for (i = 0; i < 10000; i++)
+ ;
+
+ /* Eight auto-refresh cycles are provided */
+ for (i = 0; i < 8; i++) {
+ writel(AT91_SDRAMC_MODE_REFRESH, ®->mr);
+ writel(0x00000001 + i, sdram_address + 4 + 4 * i);
+ }
+
+ /*
+ * A Mode Register set (MRS) cyscle is issued to program the
+ * SDRAM parameters(TCSR, PASR, DS)
+ */
+ writel(AT91_SDRAMC_MODE_LMR, ®->mr);
+ writel(0xcafedede, sdram_address + 0x24);
+
+ /*
+ * The application must go into Normal Mode, setting Mode
+ * to 0 in the Mode Register and perform a write access at
+ * any location in the SDRAM.
+ */
+ writel(AT91_SDRAMC_MODE_NORMAL, ®->mr);
+ writel(0x00000000, sdram_address); /* Perform Normal mode */
+
+ /*
+ * Write the refresh rate into the count field in the SDRAMC
+ * Refresh Timer Rgister.
+ */
+ writel(p->tr, ®->tr);
+
+ return 0;
+}
#include <common.h>
#include <asm/io.h>
#include <asm/arch/at91_common.h>
-#include <asm/arch/at91_pmc.h>
#include <asm/arch/at91_wdt.h>
#include <asm/arch/clk.h>
#include <spl.h>
-static void at91_disable_wdt(void)
+void at91_disable_wdt(void)
{
struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT;
writel(AT91_WDT_MR_WDDIS, &wdt->mr);
}
-static void switch_to_main_crystal_osc(void)
-{
- struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
- u32 tmp;
-
- tmp = readl(&pmc->mor);
- tmp &= ~AT91_PMC_MOR_OSCOUNT(0xff);
- tmp &= ~AT91_PMC_MOR_KEY(0xff);
- tmp |= AT91_PMC_MOR_MOSCEN;
- tmp |= AT91_PMC_MOR_OSCOUNT(8);
- tmp |= AT91_PMC_MOR_KEY(0x37);
- writel(tmp, &pmc->mor);
- while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCS))
- ;
-
- tmp = readl(&pmc->mor);
- tmp &= ~AT91_PMC_MOR_OSCBYPASS;
- tmp &= ~AT91_PMC_MOR_KEY(0xff);
- tmp |= AT91_PMC_MOR_KEY(0x37);
- writel(tmp, &pmc->mor);
-
- tmp = readl(&pmc->mor);
- tmp |= AT91_PMC_MOR_MOSCSEL;
- tmp &= ~AT91_PMC_MOR_KEY(0xff);
- tmp |= AT91_PMC_MOR_KEY(0x37);
- writel(tmp, &pmc->mor);
-
- while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCSELS))
- ;
-
- /* Wait until MAINRDY field is set to make sure main clock is stable */
- while (!(readl(&pmc->mcfr) & AT91_PMC_MAINRDY))
- ;
-
- tmp = readl(&pmc->mor);
- tmp &= ~AT91_PMC_MOR_MOSCRCEN;
- tmp &= ~AT91_PMC_MOR_KEY(0xff);
- tmp |= AT91_PMC_MOR_KEY(0x37);
- writel(tmp, &pmc->mor);
-}
-
-void at91_plla_init(u32 pllar)
-{
- struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
-
- writel(pllar, &pmc->pllar);
- while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY)))
- ;
-}
-
-void at91_mck_init(u32 mckr)
-{
- struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
- u32 tmp;
-
- tmp = readl(&pmc->mckr);
- tmp &= ~(AT91_PMC_MCKR_CSS_MASK |
- AT91_PMC_MCKR_PRES_MASK |
- AT91_PMC_MCKR_MDIV_MASK |
- AT91_PMC_MCKR_PLLADIV_2);
- tmp |= mckr & (AT91_PMC_MCKR_CSS_MASK |
- AT91_PMC_MCKR_PRES_MASK |
- AT91_PMC_MCKR_MDIV_MASK |
- AT91_PMC_MCKR_PLLADIV_2);
- writel(tmp, &pmc->mckr);
-
- while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
- ;
-}
-
-
u32 spl_boot_device(void)
{
#ifdef CONFIG_SYS_USE_MMC
hang();
}
}
-
-void s_init(void)
-{
- switch_to_main_crystal_osc();
-
- /* disable watchdog */
- at91_disable_wdt();
-
- /* PMC configuration */
- at91_pmc_init();
-
- at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK);
-
- timer_init();
-
- board_early_init_f();
-
- preloader_console_init();
-
- mem_init();
-}
--- /dev/null
+/*
+ * (C) Copyright 2014 DENX Software Engineering
+ * Heiko Schocher <hs@denx.de>
+ *
+ * Based on:
+ * Copyright (C) 2013 Atmel Corporation
+ * Bo Shen <voice.shen@atmel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/at91_common.h>
+#include <asm/arch/at91sam9_matrix.h>
+#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 enable_ext_reset(void)
+{
+ struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC;
+
+ writel(AT91_RSTC_KEY | AT91_RSTC_MR_URSTEN, &rstc->mr);
+}
+
+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 __weak matrix_init(void)
+{
+}
+
+void __weak at91_spl_board_init(void)
+{
+}
+
+void spl_board_init(void)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+
+ lowlevel_clock_init();
+ at91_disable_wdt();
+
+ /*
+ * At this stage the main oscillator is supposed to be enabled
+ * PCK = MCK = MOSC
+ */
+ writel(0x00, &pmc->pllicpr);
+
+ /* Configure PLLA = MOSC * (PLL_MULA + 1) / PLL_DIVA */
+ at91_plla_init(CONFIG_SYS_AT91_PLLA);
+
+ /* PCK = PLLA = 2 * MCK */
+ at91_mck_init(CONFIG_SYS_MCKR);
+
+ /* 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();
+
+ /* Initialize matrix */
+ matrix_init();
+
+ 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();
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Atmel Corporation
+ * Bo Shen <voice.shen@atmel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/at91_common.h>
+#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 switch_to_main_crystal_osc(void)
+{
+ struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+ u32 tmp;
+
+ tmp = readl(&pmc->mor);
+ tmp &= ~AT91_PMC_MOR_OSCOUNT(0xff);
+ tmp &= ~AT91_PMC_MOR_KEY(0xff);
+ tmp |= AT91_PMC_MOR_MOSCEN;
+ tmp |= AT91_PMC_MOR_OSCOUNT(8);
+ tmp |= AT91_PMC_MOR_KEY(0x37);
+ writel(tmp, &pmc->mor);
+ while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCS))
+ ;
+
+ tmp = readl(&pmc->mor);
+ tmp &= ~AT91_PMC_MOR_OSCBYPASS;
+ tmp &= ~AT91_PMC_MOR_KEY(0xff);
+ tmp |= AT91_PMC_MOR_KEY(0x37);
+ writel(tmp, &pmc->mor);
+
+ tmp = readl(&pmc->mor);
+ tmp |= AT91_PMC_MOR_MOSCSEL;
+ tmp &= ~AT91_PMC_MOR_KEY(0xff);
+ tmp |= AT91_PMC_MOR_KEY(0x37);
+ writel(tmp, &pmc->mor);
+
+ while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCSELS))
+ ;
+
+ /* Wait until MAINRDY field is set to make sure main clock is stable */
+ while (!(readl(&pmc->mcfr) & AT91_PMC_MAINRDY))
+ ;
+
+ tmp = readl(&pmc->mor);
+ tmp &= ~AT91_PMC_MOR_MOSCRCEN;
+ tmp &= ~AT91_PMC_MOR_KEY(0xff);
+ tmp |= AT91_PMC_MOR_KEY(0x37);
+ writel(tmp, &pmc->mor);
+}
+
+void s_init(void)
+{
+ switch_to_main_crystal_osc();
+
+ /* disable watchdog */
+ at91_disable_wdt();
+
+ /* PMC configuration */
+ at91_pmc_init();
+
+ at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK);
+
+ timer_init();
+
+ board_early_init_f();
+
+ preloader_console_init();
+
+ mem_init();
+}
void at91_uhp_hw_init(void);
void at91_lcd_hw_init(void);
void at91_plla_init(u32 pllar);
+void at91_pllb_init(u32 pllar);
void at91_mck_init(u32 mckr);
void at91_pmc_init(void);
void mem_init(void);
void at91_phy_reset(void);
+void at91_sdram_hw_init(void);
+void at91_mck_init(u32 mckr);
+void at91_spl_board_init(void);
+void at91_disable_wdt(void);
+void matrix_init(void);
#endif /* AT91_COMMON_H */
#define AT91_PMC_MCKR_MDIV_MASK 0x00000300
#endif
+#define AT91_PMC_MCKR_PLLADIV_MASK 0x00003000
#define AT91_PMC_MCKR_PLLADIV_1 0x00000000
#define AT91_PMC_MCKR_PLLADIV_2 0x00001000
#define ATMEL_BASE_SDRAMC 0xffffea00
#define ATMEL_BASE_SMC 0xffffec00
#define ATMEL_BASE_MATRIX 0xffffee00
+#define ATMEL_BASE_CCFG 0xffffef14
#define ATMEL_BASE_AIC 0xfffff000
#define ATMEL_BASE_DBGU 0xfffff200
#define ATMEL_BASE_PIOA 0xfffff400
#define AT91_MATRIX_DBPUC (1 << 8)
#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16)
#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16)
+#define AT91_MATRIX_EBI_IOSR_SEL (1 << 17)
+
+/* Maximum Number of Allowed Cycles for a Burst */
+#define AT91_MATRIX_SLOT_CYCLE (0xff << 0)
+#define AT91_MATRIX_SLOT_CYCLE_(x) (x << 0)
#endif
#define AT91_ASM_SDRAMC_CR (ATMEL_BASE_SDRAMC + 0x08)
#define AT91_ASM_SDRAMC_MDR (ATMEL_BASE_SDRAMC + 0x24)
+#else
+struct sdramc_reg {
+ u32 mr;
+ u32 tr;
+ u32 cr;
+ u32 lpr;
+ u32 ier;
+ u32 idr;
+ u32 imr;
+ u32 isr;
+ u32 mdr;
+};
+
+int sdramc_initialize(unsigned int sdram_address,
+ const struct sdramc_reg *p);
#endif
/* SDRAM Controller (SDRAMC) registers */
#define AT91_SDRAMC_DBW_32 (0 << 7)
#define AT91_SDRAMC_DBW_16 (1 << 7)
#define AT91_SDRAMC_TWR (0xf << 8) /* Write Recovery Delay */
+#define AT91_SDRAMC_TWR_VAL(x) (x << 8)
#define AT91_SDRAMC_TRC (0xf << 12) /* Row Cycle Delay */
+#define AT91_SDRAMC_TRC_VAL(x) (x << 12)
#define AT91_SDRAMC_TRP (0xf << 16) /* Row Precharge Delay */
+#define AT91_SDRAMC_TRP_VAL(x) (x << 16)
#define AT91_SDRAMC_TRCD (0xf << 20) /* Row to Column Delay */
+#define AT91_SDRAMC_TRCD_VAL(x) (x << 20)
#define AT91_SDRAMC_TRAS (0xf << 24) /* Active to Precharge Delay */
+#define AT91_SDRAMC_TRAS_VAL(x) (x << 24)
#define AT91_SDRAMC_TXSR (0xf << 28) /* Exit Self Refresh to Active Delay */
+#define AT91_SDRAMC_TXSR_VAL(x) (x << 28)
#define AT91_SDRAMC_LPR (ATMEL_BASE_SDRAMC + 0x10) /* SDRAM Controller Low Power Register */
#define AT91_SDRAMC_LPCB (3 << 0) /* Low-power Configurations */
#define AT91_SDRAMC_MD_SDRAM 0
#define AT91_SDRAMC_MD_LOW_POWER_SDRAM 1
-
#endif