Merge branch 'master' of git://git.denx.de/u-boot-atmel

This commit is contained in:
Tom Rini 2016-10-28 14:14:18 -04:00
commit 1df182ddf7
28 changed files with 796 additions and 385 deletions

View File

@ -79,7 +79,7 @@
#clock-cells = <0>;
};
plla: pllack {
plla: pllack@0 {
compatible = "atmel,sama5d3-clk-pll";
#clock-cells = <0>;
clocks = <&main>;
@ -146,17 +146,17 @@
interrupt-parent = <&pmc>;
clocks = <&main>, <&plladiv>, <&utmi>, <&mck>;
prog0: prog0 {
prog0: prog@0 {
#clock-cells = <0>;
reg = <0>;
};
prog1: prog1 {
prog1: prog@1 {
#clock-cells = <0>;
reg = <1>;
};
prog2: prog2 {
prog2: prog@2 {
#clock-cells = <0>;
reg = <2>;
};
@ -167,49 +167,49 @@
#address-cells = <1>;
#size-cells = <0>;
ddrck: ddrck {
ddrck: ddrck@2 {
#clock-cells = <0>;
reg = <2>;
clocks = <&mck>;
};
lcdck: lcdck {
lcdck: lcdck@3 {
#clock-cells = <0>;
reg = <3>;
clocks = <&mck>;
};
uhpck: uhpck {
uhpck: uhpck@6 {
#clock-cells = <0>;
reg = <6>;
clocks = <&usb>;
};
udpck: udpck {
udpck: udpck@7 {
#clock-cells = <0>;
reg = <7>;
clocks = <&usb>;
};
pck0: pck0 {
pck0: pck0@8 {
#clock-cells = <0>;
reg = <8>;
clocks = <&prog0>;
};
pck1: pck1 {
pck1: pck1@9 {
#clock-cells = <0>;
reg = <9>;
clocks = <&prog1>;
};
pck2: pck2 {
pck2: pck2@10 {
#clock-cells = <0>;
reg = <10>;
clocks = <&prog2>;
};
iscck: iscck {
iscck: iscck@18 {
#clock-cells = <0>;
reg = <18>;
clocks = <&mck>;
@ -222,203 +222,203 @@
#size-cells = <0>;
clocks = <&h32ck>;
macb0_clk: macb0_clk {
macb0_clk: macb0_clk@5 {
#clock-cells = <0>;
reg = <5>;
atmel,clk-output-range = <0 83000000>;
};
tdes_clk: tdes_clk {
tdes_clk: tdes_clk@11 {
#clock-cells = <0>;
reg = <11>;
atmel,clk-output-range = <0 83000000>;
};
matrix1_clk: matrix1_clk {
matrix1_clk: matrix1_clk@14 {
#clock-cells = <0>;
reg = <14>;
};
hsmc_clk: hsmc_clk {
hsmc_clk: hsmc_clk@17 {
#clock-cells = <0>;
reg = <17>;
};
pioA_clk: pioA_clk {
pioA_clk: pioA_clk@18 {
#clock-cells = <0>;
reg = <18>;
atmel,clk-output-range = <0 83000000>;
};
flx0_clk: flx0_clk {
flx0_clk: flx0_clk@19 {
#clock-cells = <0>;
reg = <19>;
atmel,clk-output-range = <0 83000000>;
};
flx1_clk: flx1_clk {
flx1_clk: flx1_clk@20 {
#clock-cells = <0>;
reg = <20>;
atmel,clk-output-range = <0 83000000>;
};
flx2_clk: flx2_clk {
flx2_clk: flx2_clk@21 {
#clock-cells = <0>;
reg = <21>;
atmel,clk-output-range = <0 83000000>;
};
flx3_clk: flx3_clk {
flx3_clk: flx3_clk@22 {
#clock-cells = <0>;
reg = <22>;
atmel,clk-output-range = <0 83000000>;
};
flx4_clk: flx4_clk {
flx4_clk: flx4_clk@23 {
#clock-cells = <0>;
reg = <23>;
atmel,clk-output-range = <0 83000000>;
};
uart0_clk: uart0_clk {
uart0_clk: uart0_clk@24 {
#clock-cells = <0>;
reg = <24>;
atmel,clk-output-range = <0 83000000>;
};
uart1_clk: uart1_clk {
uart1_clk: uart1_clk@25 {
#clock-cells = <0>;
reg = <25>;
atmel,clk-output-range = <0 83000000>;
};
uart2_clk: uart2_clk {
uart2_clk: uart2_clk@26 {
#clock-cells = <0>;
reg = <26>;
atmel,clk-output-range = <0 83000000>;
};
uart3_clk: uart3_clk {
uart3_clk: uart3_clk@27 {
#clock-cells = <0>;
reg = <27>;
atmel,clk-output-range = <0 83000000>;
};
uart4_clk: uart4_clk {
uart4_clk: uart4_clk@28 {
#clock-cells = <0>;
reg = <28>;
atmel,clk-output-range = <0 83000000>;
};
twi0_clk: twi0_clk {
twi0_clk: twi0_clk@29 {
reg = <29>;
#clock-cells = <0>;
atmel,clk-output-range = <0 83000000>;
};
twi1_clk: twi1_clk {
twi1_clk: twi1_clk@30 {
#clock-cells = <0>;
reg = <30>;
atmel,clk-output-range = <0 83000000>;
};
spi0_clk: spi0_clk {
spi0_clk: spi0_clk@33 {
#clock-cells = <0>;
reg = <33>;
atmel,clk-output-range = <0 83000000>;
};
spi1_clk: spi1_clk {
spi1_clk: spi1_clk@34 {
#clock-cells = <0>;
reg = <34>;
atmel,clk-output-range = <0 83000000>;
};
tcb0_clk: tcb0_clk {
tcb0_clk: tcb0_clk@35 {
#clock-cells = <0>;
reg = <35>;
atmel,clk-output-range = <0 83000000>;
};
tcb1_clk: tcb1_clk {
tcb1_clk: tcb1_clk@36 {
#clock-cells = <0>;
reg = <36>;
atmel,clk-output-range = <0 83000000>;
};
pwm_clk: pwm_clk {
pwm_clk: pwm_clk@38 {
#clock-cells = <0>;
reg = <38>;
atmel,clk-output-range = <0 83000000>;
};
adc_clk: adc_clk {
adc_clk: adc_clk@40 {
#clock-cells = <0>;
reg = <40>;
atmel,clk-output-range = <0 83000000>;
};
uhphs_clk: uhphs_clk {
uhphs_clk: uhphs_clk@41 {
#clock-cells = <0>;
reg = <41>;
atmel,clk-output-range = <0 83000000>;
};
udphs_clk: udphs_clk {
udphs_clk: udphs_clk@42 {
#clock-cells = <0>;
reg = <42>;
atmel,clk-output-range = <0 83000000>;
};
ssc0_clk: ssc0_clk {
ssc0_clk: ssc0_clk@43 {
#clock-cells = <0>;
reg = <43>;
atmel,clk-output-range = <0 83000000>;
};
ssc1_clk: ssc1_clk {
ssc1_clk: ssc1_clk@44 {
#clock-cells = <0>;
reg = <44>;
atmel,clk-output-range = <0 83000000>;
};
trng_clk: trng_clk {
trng_clk: trng_clk@47 {
#clock-cells = <0>;
reg = <47>;
atmel,clk-output-range = <0 83000000>;
};
pdmic_clk: pdmic_clk {
pdmic_clk: pdmic_clk@48 {
#clock-cells = <0>;
reg = <48>;
atmel,clk-output-range = <0 83000000>;
};
i2s0_clk: i2s0_clk {
i2s0_clk: i2s0_clk@54 {
#clock-cells = <0>;
reg = <54>;
atmel,clk-output-range = <0 83000000>;
};
i2s1_clk: i2s1_clk {
i2s1_clk: i2s1_clk@55 {
#clock-cells = <0>;
reg = <55>;
atmel,clk-output-range = <0 83000000>;
};
can0_clk: can0_clk {
can0_clk: can0_clk@56 {
#clock-cells = <0>;
reg = <56>;
atmel,clk-output-range = <0 83000000>;
};
can1_clk: can1_clk {
can1_clk: can1_clk@57 {
#clock-cells = <0>;
reg = <57>;
atmel,clk-output-range = <0 83000000>;
};
classd_clk: classd_clk {
classd_clk: classd_clk@59 {
#clock-cells = <0>;
reg = <59>;
atmel,clk-output-range = <0 83000000>;
@ -431,67 +431,67 @@
#size-cells = <0>;
clocks = <&mck>;
dma0_clk: dma0_clk {
dma0_clk: dma0_clk@6 {
#clock-cells = <0>;
reg = <6>;
};
dma1_clk: dma1_clk {
dma1_clk: dma1_clk@7 {
#clock-cells = <0>;
reg = <7>;
};
aes_clk: aes_clk {
aes_clk: aes_clk@9 {
#clock-cells = <0>;
reg = <9>;
};
aesb_clk: aesb_clk {
aesb_clk: aesb_clk@10 {
#clock-cells = <0>;
reg = <10>;
};
sha_clk: sha_clk {
sha_clk: sha_clk@12 {
#clock-cells = <0>;
reg = <12>;
};
mpddr_clk: mpddr_clk {
mpddr_clk: mpddr_clk@13 {
#clock-cells = <0>;
reg = <13>;
};
matrix0_clk: matrix0_clk {
matrix0_clk: matrix0_clk@15 {
#clock-cells = <0>;
reg = <15>;
};
sdmmc0_hclk: sdmmc0_hclk {
sdmmc0_hclk: sdmmc0_hclk@31 {
#clock-cells = <0>;
reg = <31>;
};
sdmmc1_hclk: sdmmc1_hclk {
sdmmc1_hclk: sdmmc1_hclk@32 {
#clock-cells = <0>;
reg = <32>;
};
lcdc_clk: lcdc_clk {
lcdc_clk: lcdc_clk@45 {
#clock-cells = <0>;
reg = <45>;
};
isc_clk: isc_clk {
isc_clk: isc_clk@46 {
#clock-cells = <0>;
reg = <46>;
};
qspi0_clk: qspi0_clk {
qspi0_clk: qspi0_clk@52 {
#clock-cells = <0>;
reg = <52>;
};
qspi1_clk: qspi1_clk {
qspi1_clk: qspi1_clk@53 {
#clock-cells = <0>;
reg = <53>;
};
@ -504,62 +504,62 @@
interrupt-parent = <&pmc>;
clocks = <&main>, <&plla>, <&utmi>, <&mck>;
sdmmc0_gclk: sdmmc0_gclk {
sdmmc0_gclk: sdmmc0_gclk@31 {
#clock-cells = <0>;
reg = <31>;
};
sdmmc1_gclk: sdmmc1_gclk {
sdmmc1_gclk: sdmmc1_gclk@32 {
#clock-cells = <0>;
reg = <32>;
};
tcb0_gclk: tcb0_gclk {
tcb0_gclk: tcb0_gclk@35 {
#clock-cells = <0>;
reg = <35>;
atmel,clk-output-range = <0 83000000>;
};
tcb1_gclk: tcb1_gclk {
tcb1_gclk: tcb1_gclk@36 {
#clock-cells = <0>;
reg = <36>;
atmel,clk-output-range = <0 83000000>;
};
pwm_gclk: pwm_gclk {
pwm_gclk: pwm_gclk@38 {
#clock-cells = <0>;
reg = <38>;
atmel,clk-output-range = <0 83000000>;
};
pdmic_gclk: pdmic_gclk {
pdmic_gclk: pdmic_gclk@48 {
#clock-cells = <0>;
reg = <48>;
};
i2s0_gclk: i2s0_gclk {
i2s0_gclk: i2s0_gclk@54 {
#clock-cells = <0>;
reg = <54>;
};
i2s1_gclk: i2s1_gclk {
i2s1_gclk: i2s1_gclk@55 {
#clock-cells = <0>;
reg = <55>;
};
can0_gclk: can0_gclk {
can0_gclk: can0_gclk@56 {
#clock-cells = <0>;
reg = <56>;
atmel,clk-output-range = <0 80000000>;
};
can1_gclk: can1_gclk {
can1_gclk: can1_gclk@57 {
#clock-cells = <0>;
reg = <57>;
atmel,clk-output-range = <0 80000000>;
};
classd_gclk: classd_gclk {
classd_gclk: classd_gclk@59 {
#clock-cells = <0>;
reg = <59>;
atmel,clk-output-range = <0 100000000>;

View File

@ -18,6 +18,7 @@ obj-$(CONFIG_AT91SAM9N12) += at91sam9n12_devices.o
obj-$(CONFIG_AT91SAM9X5) += at91sam9x5_devices.o
obj-$(CONFIG_AT91_EFLASH) += eflash.o
obj-$(CONFIG_AT91_LED) += led.o
obj-y += cache.o
obj-y += clock.o
obj-y += cpu.o
obj-y += reset.o

View File

@ -0,0 +1,29 @@
/*
* (C) Copyright 2016
* Heiko Schocher, DENX Software Engineering, hs@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <linux/types.h>
#include <common.h>
void enable_caches(void)
{
#ifndef CONFIG_SYS_ICACHE_OFF
icache_enable();
#endif
}
#ifndef CONFIG_SYS_ICACHE_OFF
/* Invalidate entire I-cache and branch predictor array */
void invalidate_icache_all(void)
{
unsigned long i = 0;
asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (i));
}
#else
void invalidate_icache_all(void)
{
}
#endif

View File

@ -162,7 +162,13 @@ int at91_clock_init(unsigned long main_clock)
gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
freq = gd->arch.mck_rate_hz;
#if defined(CONFIG_AT91SAM9X5)
/* different in prescale on at91sam9x5 */
freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 4));
#else
freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */
#endif
#if defined(CONFIG_AT91SAM9G20)
/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ?

View File

@ -147,6 +147,9 @@ int ddr3_init(const unsigned int base,
#define ATMEL_MPDDRC_TPR2_TFAW_MASK 0xf
/* Bit field in Memory Device Register */
#define ATMEL_MPDDRC_MD_SDR_SDRAM 0x0
#define ATMEL_MPDDRC_MD_LP_SDR_SDRAM 0x1
#define ATMEL_MPDDRC_MD_DDR_SDRAM 0x2
#define ATMEL_MPDDRC_MD_LPDDR_SDRAM 0x3
#define ATMEL_MPDDRC_MD_DDR3_SDRAM 0x4
#define ATMEL_MPDDRC_MD_LPDDR3_SDRAM 0x5

View File

@ -7,6 +7,9 @@
#include <common.h>
#include <atmel_hlcdc.h>
#include <debug_uart.h>
#include <dm.h>
#include <i2c.h>
#include <lcd.h>
#include <mmc.h>
#include <net.h>
@ -25,32 +28,6 @@
DECLARE_GLOBAL_DATA_PTR;
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
return bus == 0 && cs == 0;
}
void spi_cs_activate(struct spi_slave *slave)
{
atmel_pio4_set_pio_output(AT91_PIO_PORTA, 17, 0);
}
void spi_cs_deactivate(struct spi_slave *slave)
{
atmel_pio4_set_pio_output(AT91_PIO_PORTA, 17, 1);
}
static void board_spi0_hw_init(void)
{
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 14, 0);
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 15, 0);
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 16, 0);
atmel_pio4_set_pio_output(AT91_PIO_PORTA, 17, 1);
at91_periph_clk_enable(ATMEL_ID_SPI0);
}
static void board_usb_hw_init(void)
{
atmel_pio4_set_pio_output(AT91_PIO_PORTB, 10, 1);
@ -157,55 +134,6 @@ static void board_gmac_hw_init(void)
at91_periph_clk_enable(ATMEL_ID_GMAC);
}
static void board_sdhci0_hw_init(void)
{
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 0, 0); /* SDMMC0_CK */
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 1, 0); /* SDMMC0_CMD */
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 2, 0); /* SDMMC0_DAT0 */
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 3, 0); /* SDMMC0_DAT1 */
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 4, 0); /* SDMMC0_DAT2 */
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 5, 0); /* SDMMC0_DAT3 */
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 6, 0); /* SDMMC0_DAT4 */
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 7, 0); /* SDMMC0_DAT5 */
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 8, 0); /* SDMMC0_DAT6 */
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 9, 0); /* SDMMC0_DAT7 */
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 10, 0); /* SDMMC0_RSTN */
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 11, 0); /* SDMMC0_VDDSEL */
atmel_pio4_set_a_periph(AT91_PIO_PORTA, 13, 0); /* SDMMC0_CD */
at91_periph_clk_enable(ATMEL_ID_SDMMC0);
at91_enable_periph_generated_clk(ATMEL_ID_SDMMC0,
GCK_CSS_UPLL_CLK, 1);
}
static void board_sdhci1_hw_init(void)
{
atmel_pio4_set_e_periph(AT91_PIO_PORTA, 18, 0); /* SDMMC1_DAT0 */
atmel_pio4_set_e_periph(AT91_PIO_PORTA, 19, 0); /* SDMMC1_DAT1 */
atmel_pio4_set_e_periph(AT91_PIO_PORTA, 20, 0); /* SDMMC1_DAT2 */
atmel_pio4_set_e_periph(AT91_PIO_PORTA, 21, 0); /* SDMMC1_DAT3 */
atmel_pio4_set_e_periph(AT91_PIO_PORTA, 22, 0); /* SDMMC1_CK */
atmel_pio4_set_e_periph(AT91_PIO_PORTA, 27, 0); /* SDMMC1_RSTN */
atmel_pio4_set_e_periph(AT91_PIO_PORTA, 28, 0); /* SDMMC1_CMD */
atmel_pio4_set_e_periph(AT91_PIO_PORTA, 30, 0); /* SDMMC1_CD */
at91_periph_clk_enable(ATMEL_ID_SDMMC1);
at91_enable_periph_generated_clk(ATMEL_ID_SDMMC1,
GCK_CSS_UPLL_CLK, 1);
}
int board_mmc_init(bd_t *bis)
{
#ifdef CONFIG_ATMEL_SDHCI0
atmel_sdhci_init((void *)ATMEL_BASE_SDMMC0, ATMEL_ID_SDMMC0);
#endif
#ifdef CONFIG_ATMEL_SDHCI1
atmel_sdhci_init((void *)ATMEL_BASE_SDMMC1, ATMEL_ID_SDMMC1);
#endif
return 0;
}
static void board_uart1_hw_init(void)
{
atmel_pio4_set_a_periph(AT91_PIO_PORTD, 2, 1); /* URXD1 */
@ -214,34 +142,31 @@ static void board_uart1_hw_init(void)
at91_periph_clk_enable(ATMEL_ID_UART1);
}
#ifdef CONFIG_DEBUG_UART_BOARD_INIT
void board_debug_uart_init(void)
{
board_uart1_hw_init();
}
#endif
#ifdef CONFIG_BOARD_EARLY_INIT_F
int board_early_init_f(void)
{
at91_periph_clk_enable(ATMEL_ID_PIOA);
at91_periph_clk_enable(ATMEL_ID_PIOB);
at91_periph_clk_enable(ATMEL_ID_PIOC);
at91_periph_clk_enable(ATMEL_ID_PIOD);
#ifdef CONFIG_DEBUG_UART
debug_uart_init();
#else
board_uart1_hw_init();
#endif
return 0;
}
#endif
int board_init(void)
{
/* address of boot parameters */
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
#ifdef CONFIG_ATMEL_SPI
board_spi0_hw_init();
#endif
#ifdef CONFIG_ATMEL_SDHCI
#ifdef CONFIG_ATMEL_SDHCI0
board_sdhci0_hw_init();
#endif
#ifdef CONFIG_ATMEL_SDHCI1
board_sdhci1_hw_init();
#endif
#endif
#ifdef CONFIG_MACB
board_gmac_hw_init();
#endif
@ -283,21 +208,59 @@ int board_eth_init(bd_t *bis)
return rc;
}
#ifdef CONFIG_CMD_I2C
static int set_ethaddr_from_eeprom(void)
{
const int ETH_ADDR_LEN = 6;
unsigned char ethaddr[ETH_ADDR_LEN];
const char *ETHADDR_NAME = "ethaddr";
struct udevice *bus, *dev;
if (getenv(ETHADDR_NAME))
return 0;
if (uclass_get_device_by_seq(UCLASS_I2C, 1, &bus)) {
printf("Cannot find I2C bus 1\n");
return -1;
}
if (dm_i2c_probe(bus, AT24MAC_ADDR, 0, &dev)) {
printf("Failed to probe I2C chip\n");
return -1;
}
if (dm_i2c_read(dev, AT24MAC_REG, ethaddr, ETH_ADDR_LEN)) {
printf("Failed to read ethernet address from EEPROM\n");
return -1;
}
if (!is_valid_ethaddr(ethaddr)) {
printf("The ethernet address read from EEPROM is not valid!\n");
return -1;
}
return eth_setenv_enetaddr(ETHADDR_NAME, ethaddr);
}
#else
static int set_ethaddr_from_eeprom(void)
{
return 0;
}
#endif
#ifdef CONFIG_MISC_INIT_R
int misc_init_r(void)
{
set_ethaddr_from_eeprom();
return 0;
}
#endif
/* SPL */
#ifdef CONFIG_SPL_BUILD
void spl_board_init(void)
{
#ifdef CONFIG_SYS_USE_SERIALFLASH
board_spi0_hw_init();
#endif
#ifdef CONFIG_ATMEL_SDHCI
#ifdef CONFIG_ATMEL_SDHCI0
board_sdhci0_hw_init();
#endif
#ifdef CONFIG_ATMEL_SDHCI1
board_sdhci1_hw_init();
#endif
#endif
}
static void ddrc_conf(struct atmel_mpddrc_config *ddrc)

View File

@ -414,12 +414,6 @@ void reset_phy(void)
{
}
/* This breaks the Ethernet MAC at present */
void enable_caches(void)
{
dcache_enable();
}
/* SPI chip select control - only used for FPGA programming */
#ifdef CONFIG_ATMEL_SPI

View File

@ -8,6 +8,9 @@ CONFIG_SPL_FAT_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_DM_GPIO=y
CONFIG_DM_SERIAL=y
CONFIG_DEFAULT_DEVICE_TREE="at91-sama5d2_xplained"
CONFIG_FIT=y
CONFIG_SYS_EXTRA_OPTIONS="SAMA5D2,SYS_USE_MMC"
CONFIG_BOOTDELAY=3
@ -21,14 +24,46 @@ CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_I2C=y
CONFIG_CMD_USB=y
# CONFIG_CMD_FPGA is not set
CONFIG_CMD_DHCP=y
CONFIG_CMD_PING=y
CONFIG_CMD_FAT=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_DM=y
CONFIG_SPL_DM=y
CONFIG_BLK=y
CONFIG_CLK=y
CONFIG_SPL_CLK=y
CONFIG_CLK_AT91=y
CONFIG_AT91_UTMI=y
CONFIG_AT91_H32MX=y
CONFIG_AT91_GENERIC_CLK=y
CONFIG_ATMEL_PIO4=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_AT91=y
CONFIG_DM_MMC=y
CONFIG_DM_MMC_OPS=y
CONFIG_ATMEL_SDHCI=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_ATMEL=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_AT91PIO4=y
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_ATMEL=y
CONFIG_DEBUG_UART_BASE=0xf8020000
CONFIG_DEBUG_UART_CLOCK=0
CONFIG_DEBUG_UART_BOARD_INIT=y
CONFIG_DEBUG_UART_ANNOUNCE=y
CONFIG_ATMEL_USART=y
CONFIG_DM_SPI=y
CONFIG_ATMEL_SPI=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_ATMEL_USBA=y
CONFIG_OF_LIBFDT=y

View File

@ -7,6 +7,9 @@ CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI_SUPPORT=y
CONFIG_DM_GPIO=y
CONFIG_DM_SERIAL=y
CONFIG_DEFAULT_DEVICE_TREE="at91-sama5d2_xplained"
CONFIG_FIT=y
CONFIG_SYS_EXTRA_OPTIONS="SAMA5D2,SYS_USE_SERIALFLASH"
CONFIG_BOOTDELAY=3
@ -20,14 +23,46 @@ CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_I2C=y
CONFIG_CMD_USB=y
# CONFIG_CMD_FPGA is not set
CONFIG_CMD_DHCP=y
CONFIG_CMD_PING=y
CONFIG_CMD_FAT=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_DM=y
CONFIG_SPL_DM=y
CONFIG_BLK=y
CONFIG_CLK=y
CONFIG_SPL_CLK=y
CONFIG_CLK_AT91=y
CONFIG_AT91_UTMI=y
CONFIG_AT91_H32MX=y
CONFIG_AT91_GENERIC_CLK=y
CONFIG_ATMEL_PIO4=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_AT91=y
CONFIG_DM_MMC=y
CONFIG_DM_MMC_OPS=y
CONFIG_ATMEL_SDHCI=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_ATMEL=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_AT91PIO4=y
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_ATMEL=y
CONFIG_DEBUG_UART_BASE=0xf8020000
CONFIG_DEBUG_UART_CLOCK=0
CONFIG_DEBUG_UART_BOARD_INIT=y
CONFIG_DEBUG_UART_ANNOUNCE=y
CONFIG_ATMEL_USART=y
CONFIG_DM_SPI=y
CONFIG_ATMEL_SPI=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_ATMEL_USBA=y
CONFIG_OF_LIBFDT=y

View File

@ -1,6 +1,7 @@
config CLK_AT91
bool "AT91 clock drivers"
depends on CLK
select MISC
help
This option is used to enable the AT91 clock driver.
The driver supports the AT91 clock generator, including

View File

@ -17,15 +17,41 @@ DECLARE_GLOBAL_DATA_PTR;
#define GENERATED_SOURCE_MAX 6
#define GENERATED_MAX_DIV 255
struct generated_clk_priv {
/**
* generated_clk_bind() - for the generated clock driver
* Recursively bind its children as clk devices.
*
* @return: 0 on success, or negative error code on failure
*/
static int generated_clk_bind(struct udevice *dev)
{
return at91_clk_sub_device_bind(dev, "generic-clk");
}
static const struct udevice_id generated_clk_match[] = {
{ .compatible = "atmel,sama5d2-clk-generated" },
{}
};
U_BOOT_DRIVER(generated_clk) = {
.name = "generated-clk",
.id = UCLASS_MISC,
.of_match = generated_clk_match,
.bind = generated_clk_bind,
};
/*-------------------------------------------------------------*/
struct generic_clk_priv {
u32 num_parents;
};
static ulong generated_clk_get_rate(struct clk *clk)
static ulong generic_clk_get_rate(struct clk *clk)
{
struct pmc_platdata *plat = dev_get_platdata(clk->dev);
struct at91_pmc *pmc = plat->reg_base;
struct clk parent;
ulong clk_rate;
u32 tmp, gckdiv;
u8 parent_id;
int ret;
@ -36,18 +62,22 @@ static ulong generated_clk_get_rate(struct clk *clk)
AT91_PMC_PCR_GCKCSS_MASK;
gckdiv = (tmp >> AT91_PMC_PCR_GCKDIV_OFFSET) & AT91_PMC_PCR_GCKDIV_MASK;
ret = clk_get_by_index(clk->dev, parent_id, &parent);
ret = clk_get_by_index(dev_get_parent(clk->dev), parent_id, &parent);
if (ret)
return 0;
return clk_get_rate(&parent) / (gckdiv + 1);
clk_rate = clk_get_rate(&parent) / (gckdiv + 1);
clk_free(&parent);
return clk_rate;
}
static ulong generated_clk_set_rate(struct clk *clk, ulong rate)
static ulong generic_clk_set_rate(struct clk *clk, ulong rate)
{
struct pmc_platdata *plat = dev_get_platdata(clk->dev);
struct at91_pmc *pmc = plat->reg_base;
struct generated_clk_priv *priv = dev_get_priv(clk->dev);
struct generic_clk_priv *priv = dev_get_priv(clk->dev);
struct clk parent, best_parent;
ulong tmp_rate, best_rate = rate, parent_rate;
int tmp_diff, best_diff = -1;
@ -58,7 +88,7 @@ static ulong generated_clk_set_rate(struct clk *clk, ulong rate)
int ret;
for (i = 0; i < priv->num_parents; i++) {
ret = clk_get_by_index(clk->dev, i, &parent);
ret = clk_get_by_index(dev_get_parent(clk->dev), i, &parent);
if (ret)
return ret;
@ -111,18 +141,20 @@ static ulong generated_clk_set_rate(struct clk *clk, ulong rate)
return 0;
}
static struct clk_ops generated_clk_ops = {
.get_rate = generated_clk_get_rate,
.set_rate = generated_clk_set_rate,
static struct clk_ops generic_clk_ops = {
.of_xlate = at91_clk_of_xlate,
.get_rate = generic_clk_get_rate,
.set_rate = generic_clk_set_rate,
};
static int generated_clk_ofdata_to_platdata(struct udevice *dev)
static int generic_clk_ofdata_to_platdata(struct udevice *dev)
{
struct generated_clk_priv *priv = dev_get_priv(dev);
struct generic_clk_priv *priv = dev_get_priv(dev);
u32 cells[GENERATED_SOURCE_MAX];
u32 num_parents;
num_parents = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset,
num_parents = fdtdec_get_int_array_count(gd->fdt_blob,
dev_get_parent(dev)->of_offset,
"clocks", cells,
GENERATED_SOURCE_MAX);
@ -134,29 +166,12 @@ static int generated_clk_ofdata_to_platdata(struct udevice *dev)
return 0;
}
static int generated_clk_bind(struct udevice *dev)
{
return at91_pmc_clk_node_bind(dev);
}
static int generated_clk_probe(struct udevice *dev)
{
return at91_pmc_core_probe(dev);
}
static const struct udevice_id generated_clk_match[] = {
{ .compatible = "atmel,sama5d2-clk-generated" },
{}
};
U_BOOT_DRIVER(generated_clk) = {
.name = "generated-clk",
U_BOOT_DRIVER(generic_clk) = {
.name = "generic-clk",
.id = UCLASS_CLK,
.of_match = generated_clk_match,
.bind = generated_clk_bind,
.probe = generated_clk_probe,
.ofdata_to_platdata = generated_clk_ofdata_to_platdata,
.priv_auto_alloc_size = sizeof(struct generated_clk_priv),
.probe = at91_clk_probe,
.ofdata_to_platdata = generic_clk_ofdata_to_platdata,
.priv_auto_alloc_size = sizeof(struct generic_clk_priv),
.platdata_auto_alloc_size = sizeof(struct pmc_platdata),
.ops = &generated_clk_ops,
.ops = &generic_clk_ops,
};

View File

@ -16,7 +16,32 @@
#define PERIPHERAL_ID_MAX 31
#define PERIPHERAL_MASK(id) (1 << ((id) & PERIPHERAL_ID_MAX))
static int sam9x5_periph_clk_enable(struct clk *clk)
/**
* sam9x5_periph_clk_bind() - for the periph clock driver
* Recursively bind its children as clk devices.
*
* @return: 0 on success, or negative error code on failure
*/
static int sam9x5_periph_clk_bind(struct udevice *dev)
{
return at91_clk_sub_device_bind(dev, "periph-clk");
}
static const struct udevice_id sam9x5_periph_clk_match[] = {
{ .compatible = "atmel,at91sam9x5-clk-peripheral" },
{}
};
U_BOOT_DRIVER(sam9x5_periph_clk) = {
.name = "sam9x5-periph-clk",
.id = UCLASS_MISC,
.of_match = sam9x5_periph_clk_match,
.bind = sam9x5_periph_clk_bind,
};
/*---------------------------------------------------------*/
static int periph_clk_enable(struct clk *clk)
{
struct pmc_platdata *plat = dev_get_platdata(clk->dev);
struct at91_pmc *pmc = plat->reg_base;
@ -30,31 +55,36 @@ static int sam9x5_periph_clk_enable(struct clk *clk)
return 0;
}
static struct clk_ops sam9x5_periph_clk_ops = {
.enable = sam9x5_periph_clk_enable,
};
static int sam9x5_periph_clk_bind(struct udevice *dev)
static ulong periph_get_rate(struct clk *clk)
{
return at91_pmc_clk_node_bind(dev);
struct udevice *dev;
struct clk clk_dev;
ulong clk_rate;
int ret;
dev = dev_get_parent(clk->dev);
ret = clk_get_by_index(dev, 0, &clk_dev);
if (ret)
return ret;
clk_rate = clk_get_rate(&clk_dev);
clk_free(&clk_dev);
return clk_rate;
}
static int sam9x5_periph_clk_probe(struct udevice *dev)
{
return at91_pmc_core_probe(dev);
}
static const struct udevice_id sam9x5_periph_clk_match[] = {
{ .compatible = "atmel,at91sam9x5-clk-peripheral" },
{}
static struct clk_ops periph_clk_ops = {
.of_xlate = at91_clk_of_xlate,
.enable = periph_clk_enable,
.get_rate = periph_get_rate,
};
U_BOOT_DRIVER(sam9x5_periph_clk) = {
.name = "sam9x5-periph-clk",
U_BOOT_DRIVER(clk_periph) = {
.name = "periph-clk",
.id = UCLASS_CLK,
.of_match = sam9x5_periph_clk_match,
.bind = sam9x5_periph_clk_bind,
.probe = sam9x5_periph_clk_probe,
.platdata_auto_alloc_size = sizeof(struct pmc_platdata),
.ops = &sam9x5_periph_clk_ops,
.probe = at91_clk_probe,
.ops = &periph_clk_ops,
};

View File

@ -14,12 +14,37 @@
#define SYSTEM_MAX_ID 31
/**
* at91_system_clk_bind() - for the system clock driver
* Recursively bind its children as clk devices.
*
* @return: 0 on success, or negative error code on failure
*/
static int at91_system_clk_bind(struct udevice *dev)
{
return at91_clk_sub_device_bind(dev, "system-clk");
}
static const struct udevice_id at91_system_clk_match[] = {
{ .compatible = "atmel,at91rm9200-clk-system" },
{}
};
U_BOOT_DRIVER(at91_system_clk) = {
.name = "at91-system-clk",
.id = UCLASS_MISC,
.of_match = at91_system_clk_match,
.bind = at91_system_clk_bind,
};
/*----------------------------------------------------------*/
static inline int is_pck(int id)
{
return (id >= 8) && (id <= 15);
}
static int at91_system_clk_enable(struct clk *clk)
static int system_clk_enable(struct clk *clk)
{
struct pmc_platdata *plat = dev_get_platdata(clk->dev);
struct at91_pmc *pmc = plat->reg_base;
@ -46,31 +71,15 @@ static int at91_system_clk_enable(struct clk *clk)
return 0;
}
static struct clk_ops at91_system_clk_ops = {
.enable = at91_system_clk_enable,
static struct clk_ops system_clk_ops = {
.of_xlate = at91_clk_of_xlate,
.enable = system_clk_enable,
};
static int at91_system_clk_bind(struct udevice *dev)
{
return at91_pmc_clk_node_bind(dev);
}
static int at91_system_clk_probe(struct udevice *dev)
{
return at91_pmc_core_probe(dev);
}
static const struct udevice_id at91_system_clk_match[] = {
{ .compatible = "atmel,at91rm9200-clk-system" },
{}
};
U_BOOT_DRIVER(at91_system_clk) = {
.name = "at91-system-clk",
U_BOOT_DRIVER(system_clk) = {
.name = "system-clk",
.id = UCLASS_CLK,
.of_match = at91_system_clk_match,
.bind = at91_system_clk_bind,
.probe = at91_system_clk_probe,
.probe = at91_clk_probe,
.platdata_auto_alloc_size = sizeof(struct pmc_platdata),
.ops = &at91_system_clk_ops,
.ops = &system_clk_ops,
};

View File

@ -14,23 +14,19 @@
DECLARE_GLOBAL_DATA_PTR;
static int at91_pmc_bind(struct udevice *dev)
{
return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
}
static const struct udevice_id at91_pmc_match[] = {
{ .compatible = "atmel,sama5d2-pmc" },
{}
};
U_BOOT_DRIVER(at91_pmc) = {
.name = "at91-pmc-core",
.id = UCLASS_CLK,
.name = "at91-pmc",
.id = UCLASS_SIMPLE_BUS,
.of_match = at91_pmc_match,
.bind = at91_pmc_bind,
};
/*---------------------------------------------------------*/
int at91_pmc_core_probe(struct udevice *dev)
{
struct pmc_platdata *plat = dev_get_platdata(dev);
@ -42,21 +38,41 @@ int at91_pmc_core_probe(struct udevice *dev)
return 0;
}
int at91_pmc_clk_node_bind(struct udevice *dev)
/**
* at91_clk_sub_device_bind() - for the at91 clock driver
* Recursively bind its children as clk devices.
*
* @return: 0 on success, or negative error code on failure
*/
int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
{
const void *fdt = gd->fdt_blob;
int offset = dev->of_offset;
bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
const char *name;
int ret;
for (offset = fdt_first_subnode(fdt, offset);
offset > 0;
offset = fdt_next_subnode(fdt, offset)) {
if (pre_reloc_only &&
!fdt_getprop(fdt, offset, "u-boot,dm-pre-reloc", NULL))
continue;
/*
* If this node has "compatible" property, this is not
* a clock sub-node, but a normal device. skip.
*/
fdt_get_property(fdt, offset, "compatible", &ret);
if (ret >= 0)
continue;
if (ret != -FDT_ERR_NOTFOUND)
return ret;
name = fdt_get_name(fdt, offset, NULL);
if (!name)
return -EINVAL;
ret = device_bind_driver_to_node(dev, "clk", name,
ret = device_bind_driver_to_node(dev, drv_name, name,
offset, NULL);
if (ret)
return ret;
@ -65,7 +81,33 @@ int at91_pmc_clk_node_bind(struct udevice *dev)
return 0;
}
U_BOOT_DRIVER(clk_generic) = {
.id = UCLASS_CLK,
.name = "clk",
};
int at91_clk_of_xlate(struct clk *clk, struct fdtdec_phandle_args *args)
{
int periph;
if (args->args_count) {
debug("Invalid args_count: %d\n", args->args_count);
return -EINVAL;
}
periph = fdtdec_get_uint(gd->fdt_blob, clk->dev->of_offset, "reg", -1);
if (periph < 0)
return -EINVAL;
clk->id = periph;
return 0;
}
int at91_clk_probe(struct udevice *dev)
{
struct udevice *dev_periph_container, *dev_pmc;
struct pmc_platdata *plat = dev_get_platdata(dev);
dev_periph_container = dev_get_parent(dev);
dev_pmc = dev_get_parent(dev_periph_container);
plat->reg_base = (struct at91_pmc *)dev_get_addr_ptr(dev_pmc);
return 0;
}

View File

@ -13,6 +13,9 @@ struct pmc_platdata {
};
int at91_pmc_core_probe(struct udevice *dev);
int at91_pmc_clk_node_bind(struct udevice *dev);
int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name);
int at91_clk_of_xlate(struct clk *clk, struct fdtdec_phandle_args *args);
int at91_clk_probe(struct udevice *dev);
#endif

View File

@ -6,25 +6,18 @@
*/
#include <common.h>
#include <clk-uclass.h>
#include <dm/device.h>
#include <dm/root.h>
DECLARE_GLOBAL_DATA_PTR;
static int at91_sckc_clk_bind(struct udevice *dev)
{
return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
}
static const struct udevice_id at91_sckc_clk_match[] = {
static const struct udevice_id at91_sckc_match[] = {
{ .compatible = "atmel,at91sam9x5-sckc" },
{}
};
U_BOOT_DRIVER(at91_sckc_clk) = {
.name = "at91_sckc_clk",
.id = UCLASS_CLK,
.of_match = at91_sckc_clk_match,
.bind = at91_sckc_clk_bind,
U_BOOT_DRIVER(at91_sckc) = {
.name = "at91-sckc",
.id = UCLASS_SIMPLE_BUS,
.of_match = at91_sckc_match,
};

View File

@ -80,6 +80,9 @@ int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
__func__, ret);
return ret;
}
clk->dev = dev_clk;
ops = clk_dev_ops(dev_clk);
if (ops->of_xlate)

View File

@ -284,27 +284,15 @@ static int atmel_pio4_probe(struct udevice *dev)
struct atmel_pio4_platdata *plat = dev_get_platdata(dev);
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct atmel_pioctrl_data *pioctrl_data;
struct udevice *dev_clk;
struct clk clk;
fdt_addr_t addr_base;
u32 nbanks;
int periph;
int ret;
ret = clk_get_by_index(dev, 0, &clk);
if (ret)
return ret;
periph = fdtdec_get_uint(gd->fdt_blob, clk.dev->of_offset, "reg", -1);
if (periph < 0)
return -EINVAL;
dev_clk = dev_get_parent(clk.dev);
ret = clk_request(dev_clk, &clk);
if (ret)
return ret;
clk.id = periph;
ret = clk_enable(&clk);
if (ret)
return ret;

View File

@ -176,37 +176,21 @@ static void at91_calc_i2c_clock(struct udevice *dev, int i2c_clk)
static int at91_i2c_enable_clk(struct udevice *dev)
{
struct at91_i2c_bus *bus = dev_get_priv(dev);
struct udevice *dev_clk;
struct clk clk;
ulong clk_rate;
int periph;
int ret;
ret = clk_get_by_index(dev, 0, &clk);
if (ret)
return -EINVAL;
periph = fdtdec_get_uint(gd->fdt_blob, clk.dev->of_offset, "reg", -1);
if (periph < 0)
return -EINVAL;
dev_clk = dev_get_parent(clk.dev);
ret = clk_request(dev_clk, &clk);
if (ret)
return ret;
clk.id = periph;
ret = clk_enable(&clk);
if (ret)
return ret;
ret = clk_get_by_index(dev_clk, 0, &clk);
if (ret)
return ret;
clk_rate = clk_get_rate(&clk);
if (!clk_rate)
return -ENODEV;
return -EINVAL;
bus->bus_clk_rate = clk_rate;

View File

@ -50,29 +50,6 @@ struct atmel_sdhci_plat {
struct mmc mmc;
};
static int atmel_sdhci_get_clk(struct udevice *dev, int index, struct clk *clk)
{
struct udevice *dev_clk;
int periph, ret;
ret = clk_get_by_index(dev, index, clk);
if (ret)
return ret;
periph = fdtdec_get_uint(gd->fdt_blob, clk->dev->of_offset, "reg", -1);
if (periph < 0)
return -EINVAL;
dev_clk = dev_get_parent(clk->dev);
ret = clk_request(dev_clk, clk);
if (ret)
return ret;
clk->id = periph;
return 0;
}
static int atmel_sdhci_probe(struct udevice *dev)
{
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
@ -85,7 +62,7 @@ static int atmel_sdhci_probe(struct udevice *dev)
struct clk clk;
int ret;
ret = atmel_sdhci_get_clk(dev, 0, &clk);
ret = clk_get_by_index(dev, 0, &clk);
if (ret)
return ret;
@ -106,7 +83,7 @@ static int atmel_sdhci_probe(struct udevice *dev)
clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >> SDHCI_CLOCK_MUL_SHIFT;
gck_rate = clk_base * 1000000 * (clk_mul + 1);
ret = atmel_sdhci_get_clk(dev, 1, &clk);
ret = clk_get_by_index(dev, 1, &clk);
if (ret)
return ret;

View File

@ -98,6 +98,13 @@ config DEBUG_UART_AR933X
driver will be available until the real driver model serial is
running.
config DEBUG_UART_ATMEL
bool "Atmel USART"
help
Select this to enable a debug UART using the atmel usart driver. You
will need to provide parameters to make this work. The driver will
be available until the real driver-model serial is running.
config DEBUG_UART_NS16550
bool "ns16550"
help
@ -296,6 +303,13 @@ config AR933X_UART
tree binding to operate, please refer to the document at
doc/device-tree-bindings/serial/qca,ar9330-uart.txt.
config ATMEL_USART
bool "Atmel USART support"
help
Select this to enable USART support for Atmel SoCs. It can be
configured in the device tree, and input clock frequency can
be got from the clk node.
config FSL_LPUART
bool "Freescale LPUART support"
help

View File

@ -11,6 +11,7 @@
#include <errno.h>
#include <watchdog.h>
#include <serial.h>
#include <debug_uart.h>
#include <linux/compiler.h>
#include <asm/io.h>
@ -226,3 +227,24 @@ U_BOOT_DRIVER(serial_atmel) = {
.priv_auto_alloc_size = sizeof(struct atmel_serial_priv),
};
#endif
#ifdef CONFIG_DEBUG_UART_ATMEL
static inline void _debug_uart_init(void)
{
atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_DEBUG_UART_BASE;
atmel_serial_setbrg_internal(usart, 0, CONFIG_BAUDRATE);
}
static inline void _debug_uart_putc(int ch)
{
atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_DEBUG_UART_BASE;
while (!(readl(&usart->csr) & USART3_BIT(TXRDY)))
;
writel(ch, &usart->thr);
}
DEBUG_UART_FUNCS
#endif

View File

@ -32,6 +32,14 @@ config ATH79_SPI
uses driver model and requires a device tree binding to operate.
please refer to doc/device-tree-bindings/spi/spi-ath79.txt.
config ATMEL_SPI
bool "Atmel SPI driver"
depends on ARCH_AT91
help
This enables driver for the Atmel SPI Controller, present on
many AT32 (AVR32) and AT91 (ARM) chips. This driver can be
used to access the SPI Flash, such as AT25DF321.
config CADENCE_QSPI
bool "Cadence QSPI driver"
help

View File

@ -4,16 +4,30 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <fdtdec.h>
#include <spi.h>
#include <malloc.h>
#include <wait_bit.h>
#include <asm/io.h>
#include <asm/arch/clk.h>
#include <asm/arch/hardware.h>
#ifdef CONFIG_DM_SPI
#include <asm/arch/at91_spi.h>
#endif
#ifdef CONFIG_DM_GPIO
#include <asm/gpio.h>
#endif
#include "atmel_spi.h"
DECLARE_GLOBAL_DATA_PTR;
#ifndef CONFIG_DM_SPI
static int spi_has_wdrbt(struct atmel_spi_slave *slave)
{
unsigned int ver;
@ -209,3 +223,277 @@ out:
return 0;
}
#else
#define MAX_CS_COUNT 4
struct atmel_spi_platdata {
struct at91_spi *regs;
};
struct atmel_spi_priv {
unsigned int freq; /* Default frequency */
unsigned int mode;
ulong bus_clk_rate;
struct gpio_desc cs_gpios[MAX_CS_COUNT];
};
static int atmel_spi_claim_bus(struct udevice *dev)
{
struct udevice *bus = dev_get_parent(dev);
struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
struct atmel_spi_priv *priv = dev_get_priv(bus);
struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
struct at91_spi *reg_base = bus_plat->regs;
u32 cs = slave_plat->cs;
u32 freq = priv->freq;
u32 scbr, csrx, mode;
scbr = (priv->bus_clk_rate + freq - 1) / freq;
if (scbr > ATMEL_SPI_CSRx_SCBR_MAX)
return -EINVAL;
if (scbr < 1)
scbr = 1;
csrx = ATMEL_SPI_CSRx_SCBR(scbr);
csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8);
if (!(priv->mode & SPI_CPHA))
csrx |= ATMEL_SPI_CSRx_NCPHA;
if (priv->mode & SPI_CPOL)
csrx |= ATMEL_SPI_CSRx_CPOL;
writel(csrx, &reg_base->csr[cs]);
mode = ATMEL_SPI_MR_MSTR |
ATMEL_SPI_MR_MODFDIS |
ATMEL_SPI_MR_WDRBT |
ATMEL_SPI_MR_PCS(~(1 << cs));
writel(mode, &reg_base->mr);
writel(ATMEL_SPI_CR_SPIEN, &reg_base->cr);
return 0;
}
static int atmel_spi_release_bus(struct udevice *dev)
{
struct udevice *bus = dev_get_parent(dev);
struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
writel(ATMEL_SPI_CR_SPIDIS, &bus_plat->regs->cr);
return 0;
}
static void atmel_spi_cs_activate(struct udevice *dev)
{
struct udevice *bus = dev_get_parent(dev);
struct atmel_spi_priv *priv = dev_get_priv(bus);
struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
u32 cs = slave_plat->cs;
dm_gpio_set_value(&priv->cs_gpios[cs], 0);
}
static void atmel_spi_cs_deactivate(struct udevice *dev)
{
struct udevice *bus = dev_get_parent(dev);
struct atmel_spi_priv *priv = dev_get_priv(bus);
struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
u32 cs = slave_plat->cs;
dm_gpio_set_value(&priv->cs_gpios[cs], 1);
}
static int atmel_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
struct udevice *bus = dev_get_parent(dev);
struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
struct at91_spi *reg_base = bus_plat->regs;
u32 len_tx, len_rx, len;
u32 status;
const u8 *txp = dout;
u8 *rxp = din;
u8 value;
if (bitlen == 0)
goto out;
/*
* The controller can do non-multiple-of-8 bit
* transfers, but this driver currently doesn't support it.
*
* It's also not clear how such transfers are supposed to be
* represented as a stream of bytes...this is a limitation of
* the current SPI interface.
*/
if (bitlen % 8) {
/* Errors always terminate an ongoing transfer */
flags |= SPI_XFER_END;
goto out;
}
len = bitlen / 8;
/*
* The controller can do automatic CS control, but it is
* somewhat quirky, and it doesn't really buy us much anyway
* in the context of U-Boot.
*/
if (flags & SPI_XFER_BEGIN) {
atmel_spi_cs_activate(dev);
/*
* sometimes the RDR is not empty when we get here,
* in theory that should not happen, but it DOES happen.
* Read it here to be on the safe side.
* That also clears the OVRES flag. Required if the
* following loop exits due to OVRES!
*/
readl(&reg_base->rdr);
}
for (len_tx = 0, len_rx = 0; len_rx < len; ) {
status = readl(&reg_base->sr);
if (status & ATMEL_SPI_SR_OVRES)
return -1;
if ((len_tx < len) && (status & ATMEL_SPI_SR_TDRE)) {
if (txp)
value = *txp++;
else
value = 0;
writel(value, &reg_base->tdr);
len_tx++;
}
if (status & ATMEL_SPI_SR_RDRF) {
value = readl(&reg_base->rdr);
if (rxp)
*rxp++ = value;
len_rx++;
}
}
out:
if (flags & SPI_XFER_END) {
/*
* Wait until the transfer is completely done before
* we deactivate CS.
*/
wait_for_bit(__func__, &reg_base->sr,
ATMEL_SPI_SR_TXEMPTY, true, 1000, false);
atmel_spi_cs_deactivate(dev);
}
return 0;
}
static int atmel_spi_set_speed(struct udevice *bus, uint speed)
{
struct atmel_spi_priv *priv = dev_get_priv(bus);
priv->freq = speed;
return 0;
}
static int atmel_spi_set_mode(struct udevice *bus, uint mode)
{
struct atmel_spi_priv *priv = dev_get_priv(bus);
priv->mode = mode;
return 0;
}
static const struct dm_spi_ops atmel_spi_ops = {
.claim_bus = atmel_spi_claim_bus,
.release_bus = atmel_spi_release_bus,
.xfer = atmel_spi_xfer,
.set_speed = atmel_spi_set_speed,
.set_mode = atmel_spi_set_mode,
/*
* cs_info is not needed, since we require all chip selects to be
* in the device tree explicitly
*/
};
static int atmel_spi_enable_clk(struct udevice *bus)
{
struct atmel_spi_priv *priv = dev_get_priv(bus);
struct clk clk;
ulong clk_rate;
int ret;
ret = clk_get_by_index(bus, 0, &clk);
if (ret)
return -EINVAL;
ret = clk_enable(&clk);
if (ret)
return ret;
clk_rate = clk_get_rate(&clk);
if (!clk_rate)
return -EINVAL;
priv->bus_clk_rate = clk_rate;
clk_free(&clk);
return 0;
}
static int atmel_spi_probe(struct udevice *bus)
{
struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
struct atmel_spi_priv *priv = dev_get_priv(bus);
int i, ret;
ret = atmel_spi_enable_clk(bus);
if (ret)
return ret;
bus_plat->regs = (struct at91_spi *)dev_get_addr(bus);
ret = gpio_request_list_by_name(bus, "cs-gpios", priv->cs_gpios,
ARRAY_SIZE(priv->cs_gpios), 0);
if (ret < 0) {
error("Can't get %s gpios! Error: %d", bus->name, ret);
return ret;
}
for(i = 0; i < ARRAY_SIZE(priv->cs_gpios); i++) {
dm_gpio_set_dir_flags(&priv->cs_gpios[i],
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
}
writel(ATMEL_SPI_CR_SWRST, &bus_plat->regs->cr);
return 0;
}
static const struct udevice_id atmel_spi_ids[] = {
{ .compatible = "atmel,at91rm9200-spi" },
{ }
};
U_BOOT_DRIVER(atmel_spi) = {
.name = "atmel_spi",
.id = UCLASS_SPI,
.of_match = atmel_spi_ids,
.ops = &atmel_spi_ops,
.platdata_auto_alloc_size = sizeof(struct atmel_spi_platdata),
.priv_auto_alloc_size = sizeof(struct atmel_spi_priv),
.probe = atmel_spi_probe,
};
#endif

View File

@ -56,9 +56,7 @@ struct ehci_atmel_priv {
static int ehci_atmel_enable_clk(struct udevice *dev)
{
struct udevice *dev_clk;
struct clk clk;
int periph;
int ret;
ret = clk_get_by_index(dev, 0, &clk);
@ -73,19 +71,6 @@ static int ehci_atmel_enable_clk(struct udevice *dev)
if (ret)
return -EINVAL;
periph = fdtdec_get_uint(gd->fdt_blob, clk.dev->of_offset, "reg", -1);
if (periph < 0)
return -EINVAL;
dev_clk = dev_get_parent(clk.dev);
if (!dev_clk)
return -ENODEV;
ret = clk_request(dev_clk, &clk);
if (ret)
return ret;
clk.id = periph;
ret = clk_enable(&clk);
if (ret)
return ret;

View File

@ -74,7 +74,7 @@
#define CONFIG_BOOTARGS \
"console=ttyS0,115200 earlyprintk " \
"mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro," \
"256K(env),256k(env_redundent),256k(spare)," \
"256K(env),256k(env_redundant),256k(spare)," \
"512k(dtb),6M(kernel)ro,-(rootfs) " \
"rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs"

View File

@ -148,7 +148,7 @@
#define CONFIG_BOOTARGS \
"console=ttyS0,115200 earlyprintk " \
"mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro," \
"256K(env),256k(env_redundent),256k(spare)," \
"256K(env),256k(env_redundant),256k(spare)," \
"512k(dtb),6M(kernel)ro,-(rootfs) " \
"rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs"

View File

@ -15,10 +15,9 @@
#include "at91-sama5_common.h"
/* serial console */
#define CONFIG_ATMEL_USART
#define CONFIG_USART_BASE ATMEL_BASE_UART1
#define CONFIG_USART_ID ATMEL_ID_UART1
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_MISC_INIT_R
/* SDRAM */
#define CONFIG_NR_DRAM_BANKS 1
@ -34,14 +33,8 @@
#define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */
#undef CONFIG_AT91_GPIO
#define CONFIG_ATMEL_PIO4
/* SerialFlash */
#ifdef CONFIG_CMD_SF
#define CONFIG_ATMEL_SPI
#define CONFIG_ATMEL_SPI0
#define CONFIG_SPI_FLASH_ATMEL
#define CONFIG_SF_DEFAULT_BUS 0
#define CONFIG_SF_DEFAULT_CS 0
#define CONFIG_SF_DEFAULT_SPEED 30000000
@ -51,23 +44,9 @@
#undef CONFIG_CMD_NAND
/* MMC */
#ifdef CONFIG_CMD_MMC
#define CONFIG_MMC
#define CONFIG_GENERIC_MMC
#define CONFIG_SDHCI
#define CONFIG_ATMEL_SDHCI
#define CONFIG_ATMEL_SDHCI0
#define CONFIG_ATMEL_SDHCI1
#define CONFIG_SUPPORT_EMMC_BOOT
#endif
/* USB */
#ifdef CONFIG_CMD_USB
#define CONFIG_USB_EHCI
#define CONFIG_USB_EHCI_ATMEL
#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
#endif
/* USB device */
@ -79,6 +58,10 @@
#define CONFIG_DOS_PARTITION
#endif
/* I2C */
#define AT24MAC_ADDR 0x5c
#define AT24MAC_REG 0x9a
/* Ethernet Hardware */
#define CONFIG_MACB
#define CONFIG_RMII