diff --git a/arch/arm/dts/sama5d2.dtsi b/arch/arm/dts/sama5d2.dtsi index 19feb6609db..a881d9e05c0 100644 --- a/arch/arm/dts/sama5d2.dtsi +++ b/arch/arm/dts/sama5d2.dtsi @@ -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>; diff --git a/arch/arm/mach-at91/arm926ejs/Makefile b/arch/arm/mach-at91/arm926ejs/Makefile index ddc323f6415..d36e15a51cc 100644 --- a/arch/arm/mach-at91/arm926ejs/Makefile +++ b/arch/arm/mach-at91/arm926ejs/Makefile @@ -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 diff --git a/arch/arm/mach-at91/arm926ejs/cache.c b/arch/arm/mach-at91/arm926ejs/cache.c new file mode 100644 index 00000000000..8813706232e --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/cache.c @@ -0,0 +1,29 @@ +/* + * (C) Copyright 2016 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include + +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 diff --git a/arch/arm/mach-at91/arm926ejs/clock.c b/arch/arm/mach-at91/arm926ejs/clock.c index c8d24ae8265..e3181fab84f 100644 --- a/arch/arm/mach-at91/arm926ejs/clock.c +++ b/arch/arm/mach-at91/arm926ejs/clock.c @@ -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) ? diff --git a/arch/arm/mach-at91/include/mach/atmel_mpddrc.h b/arch/arm/mach-at91/include/mach/atmel_mpddrc.h index d37d9082cdb..f6bcecda383 100644 --- a/arch/arm/mach-at91/include/mach/atmel_mpddrc.h +++ b/arch/arm/mach-at91/include/mach/atmel_mpddrc.h @@ -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 diff --git a/board/atmel/sama5d2_xplained/sama5d2_xplained.c b/board/atmel/sama5d2_xplained/sama5d2_xplained.c index 93df7ba32a8..c5337af4de6 100644 --- a/board/atmel/sama5d2_xplained/sama5d2_xplained.c +++ b/board/atmel/sama5d2_xplained/sama5d2_xplained.c @@ -7,6 +7,9 @@ #include #include +#include +#include +#include #include #include #include @@ -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) diff --git a/board/bluewater/gurnard/gurnard.c b/board/bluewater/gurnard/gurnard.c index 2a36d29788c..08b1401372c 100644 --- a/board/bluewater/gurnard/gurnard.c +++ b/board/bluewater/gurnard/gurnard.c @@ -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 diff --git a/configs/sama5d2_xplained_mmc_defconfig b/configs/sama5d2_xplained_mmc_defconfig index 23ab4d6d34d..8a786f1a062 100644 --- a/configs/sama5d2_xplained_mmc_defconfig +++ b/configs/sama5d2_xplained_mmc_defconfig @@ -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 diff --git a/configs/sama5d2_xplained_spiflash_defconfig b/configs/sama5d2_xplained_spiflash_defconfig index f208dc2473f..51594e71f71 100644 --- a/configs/sama5d2_xplained_spiflash_defconfig +++ b/configs/sama5d2_xplained_spiflash_defconfig @@ -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 diff --git a/drivers/clk/at91/Kconfig b/drivers/clk/at91/Kconfig index 10050d8a442..904ed48e51e 100644 --- a/drivers/clk/at91/Kconfig +++ b/drivers/clk/at91/Kconfig @@ -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 diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index f6164cc8ca1..d36f64ffdf8 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -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, }; diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c index 16688e90b41..e1ed447133e 100644 --- a/drivers/clk/at91/clk-peripheral.c +++ b/drivers/clk/at91/clk-peripheral.c @@ -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", - .id = UCLASS_CLK, - .of_match = sam9x5_periph_clk_match, - .bind = sam9x5_periph_clk_bind, - .probe = sam9x5_periph_clk_probe, +U_BOOT_DRIVER(clk_periph) = { + .name = "periph-clk", + .id = UCLASS_CLK, .platdata_auto_alloc_size = sizeof(struct pmc_platdata), - .ops = &sam9x5_periph_clk_ops, + .probe = at91_clk_probe, + .ops = &periph_clk_ops, }; diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c index fa80bade7a9..5b59a0c8520 100644 --- a/drivers/clk/at91/clk-system.c +++ b/drivers/clk/at91/clk-system.c @@ -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, }; diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index a08d7e82eb3..76ba91af812 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -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; +} diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 5444c84db66..f222fce11f4 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -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 diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c index b207611de1c..6035e209599 100644 --- a/drivers/clk/at91/sckc.c +++ b/drivers/clk/at91/sckc.c @@ -6,25 +6,18 @@ */ #include -#include #include #include 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, }; diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index c42fff6ec29..153ceba702d 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -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) diff --git a/drivers/gpio/atmel_pio4.c b/drivers/gpio/atmel_pio4.c index 7adea885650..cb90b0241a2 100644 --- a/drivers/gpio/atmel_pio4.c +++ b/drivers/gpio/atmel_pio4.c @@ -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; diff --git a/drivers/i2c/at91_i2c.c b/drivers/i2c/at91_i2c.c index d71f75c5faa..4bc54eea596 100644 --- a/drivers/i2c/at91_i2c.c +++ b/drivers/i2c/at91_i2c.c @@ -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; diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c index 20bba1a2797..6654b542788 100644 --- a/drivers/mmc/atmel_sdhci.c +++ b/drivers/mmc/atmel_sdhci.c @@ -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; diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 317d15849d3..56c024f97a1 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -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 diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c index e450135c757..7674f97e8dd 100644 --- a/drivers/serial/atmel_usart.c +++ b/drivers/serial/atmel_usart.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -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 diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 8724f87c498..0f51b3a21b8 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -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 diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index ed6278b86fd..76491142318 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -4,16 +4,30 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include +#include +#include +#include #include #include +#include #include #include #include +#ifdef CONFIG_DM_SPI +#include +#endif +#ifdef CONFIG_DM_GPIO +#include +#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, ®_base->csr[cs]); + + mode = ATMEL_SPI_MR_MSTR | + ATMEL_SPI_MR_MODFDIS | + ATMEL_SPI_MR_WDRBT | + ATMEL_SPI_MR_PCS(~(1 << cs)); + + writel(mode, ®_base->mr); + + writel(ATMEL_SPI_CR_SPIEN, ®_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(®_base->rdr); + } + + for (len_tx = 0, len_rx = 0; len_rx < len; ) { + status = readl(®_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, ®_base->tdr); + len_tx++; + } + + if (status & ATMEL_SPI_SR_RDRF) { + value = readl(®_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__, ®_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 diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 2b138c51535..a5c6d349747 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -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; diff --git a/include/configs/at91-sama5_common.h b/include/configs/at91-sama5_common.h index b09ef33e574..13140bae1f8 100644 --- a/include/configs/at91-sama5_common.h +++ b/include/configs/at91-sama5_common.h @@ -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" diff --git a/include/configs/at91sam9rlek.h b/include/configs/at91sam9rlek.h index 5b3a3d1b481..23184ceba00 100644 --- a/include/configs/at91sam9rlek.h +++ b/include/configs/at91sam9rlek.h @@ -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" diff --git a/include/configs/sama5d2_xplained.h b/include/configs/sama5d2_xplained.h index 30fb9a4dfb6..f6946453e5d 100644 --- a/include/configs/sama5d2_xplained.h +++ b/include/configs/sama5d2_xplained.h @@ -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