diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2014-10-02 08:54:41 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2014-10-02 08:54:41 +0200 |
commit | 61bf20dcc60c106282fc0352e65713f46c3fa710 (patch) | |
tree | 482ba2c21ac4fda8f3bf14744b5b3649b6561daf /arch | |
parent | 6fe56fe4a68e0cc3445e2210433ec83a664975fb (diff) | |
parent | 791ff495fbeb4185956f62c3e2eabc5a4d698674 (diff) | |
download | barebox-61bf20dcc60c106282fc0352e65713f46c3fa710.tar.gz barebox-61bf20dcc60c106282fc0352e65713f46c3fa710.tar.xz |
Merge branch 'for-next/at91'
Diffstat (limited to 'arch')
28 files changed, 1595 insertions, 37 deletions
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index ebc5f7d5df..5418c06db9 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -93,6 +93,7 @@ obj-$(CONFIG_MACH_SABRELITE) += freescale-mx6-sabrelite/ obj-$(CONFIG_MACH_SABRESD) += freescale-mx6-sabresd/ obj-$(CONFIG_MACH_SAMA5D3XEK) += sama5d3xek/ obj-$(CONFIG_MACH_SAMA5D3_XPLAINED) += sama5d3_xplained/ +obj-$(CONFIG_MACH_SAMA5D4EK) += sama5d4ek/ obj-$(CONFIG_MACH_SCB9328) += scb9328/ obj-$(CONFIG_MACH_SOCFPGA_EBV_SOCRATES) += ebv-socrates/ obj-$(CONFIG_MACH_SOCFPGA_TERASIC_SOCKIT) += terasic-sockit/ diff --git a/arch/arm/boards/sama5d4ek/Makefile b/arch/arm/boards/sama5d4ek/Makefile new file mode 100644 index 0000000000..4363b39243 --- /dev/null +++ b/arch/arm/boards/sama5d4ek/Makefile @@ -0,0 +1 @@ +obj-y += sama5d4ek.o diff --git a/arch/arm/boards/sama5d4ek/env/bin/init_board b/arch/arm/boards/sama5d4ek/env/bin/init_board new file mode 100644 index 0000000000..f3d417e356 --- /dev/null +++ b/arch/arm/boards/sama5d4ek/env/bin/init_board @@ -0,0 +1,15 @@ +#!/bin/sh + +PATH=/env/bin +export PATH + +. /env/config + +splash=/env/splash.png + +if [ -f ${splash} -a -e /dev/fb0 ]; then + splash -o ${splash} + fb0.enable=1 +fi + +exit 1 diff --git a/arch/arm/boards/sama5d4ek/env/config b/arch/arm/boards/sama5d4ek/env/config new file mode 100644 index 0000000000..1007345b9b --- /dev/null +++ b/arch/arm/boards/sama5d4ek/env/config @@ -0,0 +1,42 @@ +#!/bin/sh + +# use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration +ip=dhcp + +# or set your networking parameters here +#eth0.ipaddr=a.b.c.d +#eth0.netmask=a.b.c.d +#eth0.gateway=a.b.c.d +#eth0.serverip=a.b.c.d + +# can be either 'nfs', 'tftp', 'nor' or 'nand' +kernel_loc=nfs +# can be either 'net', 'nor', 'nand' or 'initrd' +rootfs_loc=net +# can be either 'nfs', 'tftp', 'nand' or empty +oftree_loc=nfs + +# can be either 'jffs2' or 'ubifs' +rootfs_type=ubifs +rootfsimage=root.$rootfs_type +ubiroot=rootfs + +# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo +kernelimage=zImage +#kernelimage=uImage +#kernelimage=Image +#kernelimage=Image.lzo + +nand_device=atmel_nand +nand_parts="256k(at91bootstrap),512k(barebox)ro,256k(bareboxenv),256k(bareboxenv2),256k(spare),512k(oftree),6M(kernel),-(rootfs)" +rootfs_mtdblock_nand=7 + +m25p80_parts="64k(bootstrap),384k(barebox),256k(bareboxenv),256k(bareboxenv2),128k(oftree),-(updater)" + +autoboot_timeout=3 + +bootargs="console=ttyS0,115200" + +# set a fancy prompt (if support is compiled in) +PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m\n# " diff --git a/arch/arm/boards/sama5d4ek/sama5d4ek.c b/arch/arm/boards/sama5d4ek/sama5d4ek.c new file mode 100644 index 0000000000..91cffa3b48 --- /dev/null +++ b/arch/arm/boards/sama5d4ek/sama5d4ek.c @@ -0,0 +1,317 @@ +/* + * SAMA5D4EK board configureation. + * + * Copyright (C) 2014 Atmel Corporation, + * Bo Shen <voice.shen@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +#include <common.h> +#include <net.h> +#include <init.h> +#include <environment.h> +#include <asm/armlinux.h> +#include <partition.h> +#include <fs.h> +#include <fcntl.h> +#include <io.h> +#include <mach/hardware.h> +#include <nand.h> +#include <sizes.h> +#include <linux/mtd/nand.h> +#include <mach/board.h> +#include <mach/at91sam9_smc.h> +#include <gpio.h> +#include <mach/iomux.h> +#include <mach/at91_pmc.h> +#include <mach/at91_rstc.h> +#include <mach/at91sam9x5_matrix.h> +#include <input/qt1070.h> +#include <readkey.h> +#include <spi/spi.h> +#include <linux/clk.h> + +#if defined(CONFIG_NAND_ATMEL) +static struct atmel_nand_data nand_pdata = { + .ale = 21, + .cle = 22, + .det_pin = -EINVAL, + .rdy_pin = -EINVAL, + .enable_pin = -EINVAL, + .ecc_mode = NAND_ECC_HW, + .pmecc_sector_size = 512, + .pmecc_corr_cap = 8, + .on_flash_bbt = 1, +}; + +static struct sam9_smc_config cm_nand_smc_config = { + .ncs_read_setup = 1, + .nrd_setup = 1, + .ncs_write_setup = 1, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 2, + .ncs_write_pulse = 3, + .nwe_pulse = 2, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, + .tdf_cycles = 3, + + .tclr = 2, + .tadl = 7, + .tar = 2, + .ocms = 0, + .trr = 3, + .twb = 7, + .rbnsel = 3, + .nfsel = 1, +}; + +static void ek_add_device_nand(void) +{ + struct clk *clk = clk_get(NULL, "smc_clk"); + + clk_enable(clk); + + /* configure chip-select 3 (NAND) */ + sama5_smc_configure(0, 3, &cm_nand_smc_config); + + at91_add_device_nand(&nand_pdata); +} +#else +static void ek_add_device_nand(void) {} +#endif + +#if defined(CONFIG_DRIVER_NET_MACB) +static struct macb_platform_data macb0_pdata = { + .phy_interface = PHY_INTERFACE_MODE_RMII, + .phy_addr = 0, +}; + +static void ek_add_device_eth(void) +{ + at91_add_device_eth(0, &macb0_pdata); +} +#else +static void ek_add_device_eth(void) {} +#endif + +#if defined(CONFIG_DRIVER_VIDEO_ATMEL_HLCD) +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "LG", + .refresh = 60, + .xres = 800, .yres = 480, + .pixclock = KHZ2PICOS(33260), + + .left_margin = 88, .right_margin = 168, + .upper_margin = 8, .lower_margin = 37, + .hsync_len = 128, .vsync_len = 2, + + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +/* Output mode is TFT 18 bits */ +#define BPP_OUT_DEFAULT_LCDCFG5 (LCDC_LCDCFG5_MODE_OUTPUT_18BPP) + +static struct atmel_lcdfb_platform_data ek_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 16, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = BPP_OUT_DEFAULT_LCDCFG5, + .guard_time = 9, + .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, + .mode_list = at91_tft_vga_modes, + .num_modes = ARRAY_SIZE(at91_tft_vga_modes), +}; + +static void ek_add_device_lcdc(void) +{ + at91_add_device_lcdc(&ek_lcdc_data); +} +#else +static void ek_add_device_lcdc(void) {} +#endif + +#if defined(CONFIG_MCI_ATMEL) +static struct atmel_mci_platform_data mci1_data = { + .bus_width = 4, + .detect_pin = AT91_PIN_PE6, + .wp_pin = -EINVAL, +}; + +static void ek_add_device_mci(void) +{ + /* MMC1 */ + at91_add_device_mci(1, &mci1_data); + + /* power on MCI1 */ + at91_set_gpio_output(AT91_PIN_PE15, 0); +} +#else +static void ek_add_device_mci(void) {} +#endif + +#if defined(CONFIG_I2C_GPIO) +struct qt1070_platform_data qt1070_pdata = { + .irq_pin = AT91_PIN_PE25, +}; + +static struct i2c_board_info i2c_devices[] = { + { + .platform_data = &qt1070_pdata, + I2C_BOARD_INFO("qt1070", 0x1b), + }, +}; + +static void ek_add_device_i2c(void) +{ + at91_set_gpio_input(qt1070_pdata.irq_pin, 0); + at91_set_deglitch(qt1070_pdata.irq_pin, 1); + at91_add_device_i2c(0, i2c_devices, ARRAY_SIZE(i2c_devices)); +} +#else +static void ek_add_device_i2c(void) {} +#endif + +#if defined(CONFIG_DRIVER_SPI_ATMEL) +static const struct spi_board_info ek_spi_devices[] = { + { + .name = "m25p80", + .chip_select = 0, + .max_speed_hz = 30 * 1000 * 1000, + .bus_num = 0, + } +}; + +static unsigned spi0_standard_cs[] = { AT91_PIN_PC3 }; +static struct at91_spi_platform_data spi_pdata = { + .chipselect = spi0_standard_cs, + .num_chipselect = ARRAY_SIZE(spi0_standard_cs), +}; + +static void ek_add_device_spi(void) +{ + spi_register_board_info(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + at91_add_device_spi(0, &spi_pdata); +} +#else +static void ek_add_device_spi(void) {} +#endif + +#ifdef CONFIG_LED_GPIO +struct gpio_led leds[] = { + { + .gpio = AT91_PIN_PE28, + .active_low = 0, + .led = { + .name = "d8", + }, + }, { + .gpio = AT91_PIN_PE9, + .active_low = 1, + .led = { + .name = "d9", + }, + }, { + .gpio = AT91_PIN_PE8, + .active_low = 0, + .led = { + .name = "d10", + }, + }, +}; + +static void ek_add_led(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(leds); i++) { + at91_set_gpio_output(leds[i].gpio, leds[i].active_low); + led_gpio_register(&leds[i]); + } + led_set_trigger(LED_TRIGGER_HEARTBEAT, &leds[0].led); +} +#else +static void ek_add_led(void) {} +#endif + +static int sama5d4ek_mem_init(void) +{ + at91_add_device_sdram(0); + + return 0; +} +mem_initcall(sama5d4ek_mem_init); + +static const struct devfs_partition sama5d4ek_nand0_partitions[] = { + { + .offset = 0x00000, + .size = SZ_256K, + .flags = DEVFS_PARTITION_FIXED, + .name = "at91bootstrap_raw", + .bbname = "at91bootstrap", + }, { + .offset = DEVFS_PARTITION_APPEND, + .size = SZ_512K, + .flags = DEVFS_PARTITION_FIXED, + .name = "bootloader_raw", + .bbname = "bootloader", + }, { + .offset = DEVFS_PARTITION_APPEND, + .size = SZ_256K, + .flags = DEVFS_PARTITION_FIXED, + .name = "env_raw", + .bbname = "env0", + }, { + .offset = DEVFS_PARTITION_APPEND, + .size = SZ_256K, + .flags = DEVFS_PARTITION_FIXED, + .name = "env_raw1", + .bbname = "env1", + }, { + /* sentinel */ + } +}; + +static int sama5d4ek_devices_init(void) +{ + ek_add_device_i2c(); + ek_add_device_nand(); + ek_add_led(); + ek_add_device_eth(); + ek_add_device_spi(); + ek_add_device_mci(); + ek_add_device_lcdc(); + + devfs_create_partitions("nand0", sama5d4ek_nand0_partitions); + + return 0; +} +device_initcall(sama5d4ek_devices_init); + +static int sama5d4ek_console_init(void) +{ + barebox_set_model("Atmel sama5d4ek"); + barebox_set_hostname("sama5d4ek"); + + at91_register_uart(4, 0); + + return 0; +} +console_initcall(sama5d4ek_console_init); + +static int sama5d4ek_main_clock(void) +{ + at91_set_main_clock(12000000); + + return 0; +} +pure_initcall(sama5d4ek_main_clock); diff --git a/arch/arm/configs/sama5d4ek_defconfig b/arch/arm/configs/sama5d4ek_defconfig new file mode 100644 index 0000000000..bbf254abf0 --- /dev/null +++ b/arch/arm/configs/sama5d4ek_defconfig @@ -0,0 +1,85 @@ +CONFIG_ARCH_SAMA5D4=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x60000 +CONFIG_AEABI=y +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_PBL_IMAGE=y +CONFIG_MMU=y +CONFIG_TEXT_BASE=0x26f00000 +CONFIG_MALLOC_SIZE=0xA00000 +CONFIG_EXPERIMENTAL=y +CONFIG_MALLOC_TLSF=y +CONFIG_PROMPT="A5D4EK:" +CONFIG_GLOB=y +CONFIG_PROMPT_HUSH_PS2="y" +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_CONSOLE_ACTIVATE_ALL=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/sama5d4ek/env" +CONFIG_DEBUG_INFO=y +# CONFIG_CMD_ARM_CPUINFO is not set +CONFIG_LONGHELP=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_BOOTM_VERBOSE=y +CONFIG_CMD_BOOTM_INITRD=y +CONFIG_CMD_BOOTM_OFTREE=y +CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y +# CONFIG_CMD_BOOTU is not set +CONFIG_CMD_GO=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_RESET=y +CONFIG_CMD_UIMAGE=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_LOADENV=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_FILETYPE=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MIITOOL=y +CONFIG_CMD_PING=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_SPLASH=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_SPI=y +CONFIG_CMD_OFTREE=y +CONFIG_NET=y +CONFIG_NET_NFS=y +CONFIG_OFDEVICE=y +CONFIG_DRIVER_NET_MACB=y +CONFIG_MICREL_PHY=y +CONFIG_DRIVER_SPI_ATMEL=y +CONFIG_I2C=y +CONFIG_I2C_GPIO=y +CONFIG_MTD=y +CONFIG_MTD_RAW_DEVICE=y +CONFIG_MTD_M25P80=y +CONFIG_NAND=y +# CONFIG_NAND_ECC_SOFT is not set +# CONFIG_NAND_ECC_HW_SYNDROME is not set +CONFIG_NAND_ATMEL=y +CONFIG_NAND_ATMEL_PMECC=y +CONFIG_VIDEO=y +CONFIG_DRIVER_VIDEO_ATMEL_HLCD=y +CONFIG_MCI=y +CONFIG_MCI_STARTUP=y +CONFIG_MCI_ATMEL=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_LED_TRIGGERS=y +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_QT1070=y +CONFIG_FS_EXT4=y +CONFIG_FS_TFTP=y +CONFIG_FS_FAT=y +CONFIG_FS_FAT_WRITE=y +CONFIG_FS_FAT_LFN=y +CONFIG_PNG=y diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 826917e12c..8c10c10359 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -6,6 +6,9 @@ config HAVE_AT91_DBGU0 config HAVE_AT91_DBGU1 bool +config HAVE_AT91_DBGU2 + bool + config HAVE_AT91_LOWLEVEL_INIT bool @@ -168,6 +171,13 @@ config ARCH_SAMA5D3 select HAS_MACB select AT91SAM9G45_RESET +config ARCH_SAMA5D4 + bool "SAMA5D4" + select SOC_SAMA5 + select HAVE_AT91_DBGU2 + select HAS_MACB + select AT91SAM9G45_RESET + endchoice config ARCH_BAREBOX_MAX_BARE_INIT_SIZE @@ -472,6 +482,22 @@ endif # ---------------------------------------------------------- +if ARCH_SAMA5D4 + +choice + prompt "SAMA5D4 Board Type" + +config MACH_SAMA5D4EK + bool "Atmel SAMA5D4 Evaluation Kit" + help + Select this if you are using Atmel's SAMA5D4-EK Evaluation Kit. + +endchoice + +endif + +# ---------------------------------------------------------- + comment "AT91 Board Options" config MTD_AT91_DATAFLASH_CARD diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 8599f507c4..c2991b0136 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -12,6 +12,7 @@ lowlevel_init-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5_lowlevel_init.o lowlevel_init-$(CONFIG_SOC_AT91SAM9N12) += at91sam9n12_lowlevel_init.o lowlevel_init-$(CONFIG_ARCH_AT91RM9200) = at91rm9200_lowlevel_init.o lowlevel_init-$(CONFIG_ARCH_SAMA5D3) += sama5d3_lowlevel_init.o +lowlevel_init-$(CONFIG_ARCH_SAMA5D4) += sama5d3_lowlevel_init.o lwl-y += $(lowlevel_init-y) obj-$(CONFIG_AT91SAM9_RESET) += at91sam9_reset.o @@ -31,3 +32,4 @@ obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam9g45_devices.o obj-$(CONFIG_ARCH_AT91SAM9X5) += at91sam9x5.o at91sam9x5_devices.o obj-$(CONFIG_ARCH_AT91SAM9N12) += at91sam9n12.o at91sam9n12_devices.o obj-$(CONFIG_ARCH_SAMA5D3) += sama5d3.o sama5d3_devices.o +obj-$(CONFIG_ARCH_SAMA5D4) += sama5d4.o sama5d4_devices.o diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 9a50debb16..ce6ce90db2 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -192,11 +192,6 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci1", &mmc1_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi0", &spi0_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi1", &spi1_clk), - CLKDEV_DEV_ID("at91rm9200-gpio0", &pioA_clk), - CLKDEV_DEV_ID("at91rm9200-gpio1", &pioB_clk), - CLKDEV_DEV_ID("at91rm9200-gpio2", &pioC_clk), - CLKDEV_DEV_ID("at91rm9200-gpio3", &pioDE_clk), - CLKDEV_DEV_ID("at91rm9200-gpio4", &pioDE_clk), CLKDEV_DEV_ID("at91-pit", &mck), CLKDEV_CON_DEV_ID("hck1", "atmel_lcdfb", &lcdc_clk), }; @@ -238,6 +233,14 @@ static void __init at91sam9g45_register_clocks(void) clkdev_add_table(usart_clocks_lookups, ARRAY_SIZE(usart_clocks_lookups)); + clkdev_add_physbase(&twi0_clk, AT91SAM9G45_BASE_TWI0, NULL); + clkdev_add_physbase(&twi1_clk, AT91SAM9G45_BASE_TWI1, NULL); + clkdev_add_physbase(&pioA_clk, AT91SAM9G45_BASE_PIOA, NULL); + clkdev_add_physbase(&pioB_clk, AT91SAM9G45_BASE_PIOB, NULL); + clkdev_add_physbase(&pioC_clk, AT91SAM9G45_BASE_PIOC, NULL); + clkdev_add_physbase(&pioDE_clk, AT91SAM9G45_BASE_PIOD, NULL); + clkdev_add_physbase(&pioDE_clk, AT91SAM9G45_BASE_PIOE, NULL); + if (cpu_is_at91sam9m10() || cpu_is_at91sam9m11()) clk_register(&vdec_clk); diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 9d2a846447..7a4282e615 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -37,6 +37,7 @@ #define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) #define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL) #define clk_is_sys(x) ((x)->type & CLK_TYPE_SYSTEM) +#define clk_is_periph_h64mx(x) ((x)->type & CLK_TYPE_PERIPH_H64MX) /* @@ -45,7 +46,10 @@ #define cpu_has_utmi() ( cpu_is_at91sam9rl() \ || cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ - || cpu_is_sama5d3()) + || cpu_is_sama5d3() \ + || cpu_is_sama5d4()) + +#define cpu_has_1200M_plla() (cpu_is_sama5d4()) #define cpu_has_1056M_plla() (cpu_is_sama5d3()) @@ -65,11 +69,13 @@ #define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ || cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ - || cpu_is_sama5d3())) + || cpu_is_sama5d3() \ + || cpu_is_sama5d4())) #define cpu_has_upll() (cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ - || cpu_is_sama5d3()) + || cpu_is_sama5d3() \ + || cpu_is_sama5d4()) /* USB host HS & FS */ #define cpu_has_uhp() (!cpu_is_at91sam9rl()) @@ -78,21 +84,30 @@ #define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ || cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ - || cpu_is_sama5d3())) + || cpu_is_sama5d3() \ + || cpu_is_sama5d4())) #define cpu_has_plladiv2() (cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ || cpu_is_at91sam9n12() \ - || cpu_is_sama5d3()) + || cpu_is_sama5d3() \ + || cpu_is_sama5d4()) #define cpu_has_mdiv3() (cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ || cpu_is_at91sam9n12() \ - || cpu_is_sama5d3()) + || cpu_is_sama5d3() \ + || cpu_is_sama5d4()) #define cpu_has_alt_prescaler() (cpu_is_at91sam9x5() \ || cpu_is_at91sam9n12() \ - || cpu_is_sama5d3()) + || cpu_is_sama5d3() \ + || cpu_is_sama5d4()) + +#define cpu_has_pcr() (cpu_is_sama5d3() \ + || cpu_is_sama5d4()) + +#define cpu_has_dual_matrix() (cpu_is_sama5d4()) static LIST_HEAD(clocks); @@ -212,6 +227,12 @@ struct clk mck = { .pmc_mask = AT91_PMC_MCKRDY, /* in PMC_SR */ }; +struct clk h32mx_clk = { + .name = "h32mx", + .parent = &mck, + .pmc_mask = AT91_PMC_H32MXDIV, /* in PMC_MCKR */ +}; + static void pmc_periph_mode(struct clk *clk, int is_on) { u32 regval = 0; @@ -221,7 +242,7 @@ static void pmc_periph_mode(struct clk *clk, int is_on) * register is not enough to manage their clocks. A peripheral * control register has been introduced to solve this issue. */ - if (cpu_is_sama5d3()) { + if (cpu_has_pcr()) { regval |= AT91_PMC_PCR_CMD; /* write command */ regval |= clk->pid & AT91_PMC_PCR_PID; /* peripheral selection */ regval |= AT91_PMC_PCR_DIV(clk->div); @@ -453,9 +474,13 @@ static void __init at91_clk_add(struct clk *clk) int clk_register(struct clk *clk) { if (clk_is_peripheral(clk)) { - if (!clk->parent) - clk->parent = &mck; - if (cpu_is_sama5d3()) + if (!clk->parent) { + if (!cpu_has_dual_matrix() || clk_is_periph_h64mx(clk)) + clk->parent = &mck; + else + clk->parent = &h32mx_clk; + } + if (cpu_has_pcr()) clk->rate_hz = DIV_ROUND_UP(clk->parent->rate_hz, 1 << clk->div); clk->mode = pmc_periph_mode; } @@ -482,7 +507,7 @@ static u32 at91_pll_rate(struct clk *pll, u32 freq, u32 reg) unsigned mul, div; div = reg & 0xff; - if (cpu_is_sama5d3()) + if (cpu_is_sama5d3() || cpu_is_sama5d4()) mul = (reg >> 18) & 0x7ff; else mul = (reg >> 16) & 0x7ff; @@ -647,7 +672,10 @@ int at91_clock_init(void) /* report if PLLA is more than mildly overclocked */ plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_pmc_read(AT91_CKGR_PLLAR)); - if (cpu_has_1056M_plla()) { + if (cpu_has_1200M_plla()) { + if (plla.rate_hz > 1200000000) + pll_overclock = 1; + } else if (cpu_has_1056M_plla()) { if (plla.rate_hz > 1056000000) pll_overclock = 1; } else if (cpu_has_300M_plla()) { @@ -734,6 +762,12 @@ int at91_clock_init(void) mck.id = 4; } + if (cpu_has_dual_matrix()) { + at91_clk_add(&h32mx_clk); + h32mx_clk.rate_hz = h32mx_clk.parent->rate_hz; + h32mx_clk.rate_hz /= (1 << ((mckr & AT91_PMC_H32MXDIV) >> 24)); /* H32MX divisor by 2 */ + } + cpu_freq = freq; /* Register the PMC's standard clocks */ @@ -754,6 +788,8 @@ int at91_clock_init(void) /* MCK and CPU clock are "always on" */ clk_enable(&mck); + if (cpu_has_dual_matrix()) + clk_enable(&h32mx_clk); return 0; } @@ -787,7 +823,7 @@ static int at91_clock_reset(void) continue; if (clk->mode == pmc_periph_mode) { - if (cpu_is_sama5d3()) { + if (cpu_has_pcr()) { u32 pmc_mask = 1 << (clk->pid % 32); if (clk->pid > 31) @@ -805,7 +841,7 @@ static int at91_clock_reset(void) } at91_pmc_write(AT91_PMC_PCDR, pcdr); - if (cpu_is_sama5d3()) + if (cpu_has_pcr()) at91_pmc_write(AT91_PMC_PCDR1, pcdr1); at91_pmc_write(AT91_PMC_SCDR, scdr); @@ -821,12 +857,12 @@ static int do_at91clk(int argc, char *argv[]) scsr = at91_pmc_read(AT91_PMC_SCSR); pcsr = at91_pmc_read(AT91_PMC_PCSR); - if (cpu_is_sama5d3()) + if (cpu_has_pcr()) pcsr1 = at91_pmc_read(AT91_PMC_PCSR1); sr = at91_pmc_read(AT91_PMC_SR); printf("SCSR = %8x\n", scsr); printf("PCSR = %8x\n", pcsr); - if (cpu_is_sama5d3()) + if (cpu_has_pcr()) printf("PCSR1 = %8x\n", pcsr1); printf("MOR = %8x\n", at91_pmc_read(AT91_CKGR_MOR)); printf("MCFR = %8x\n", at91_pmc_read(AT91_CKGR_MCFR)); @@ -852,7 +888,7 @@ static int do_at91clk(int argc, char *argv[]) state = (scsr & clk->pmc_mask) ? "on" : "off"; mode = "sys"; } else if (clk->mode == pmc_periph_mode) { - if (cpu_is_sama5d3()) { + if (cpu_has_pcr()) { u32 pmc_mask = 1 << (clk->pid % 32); if (clk->pid > 31) diff --git a/arch/arm/mach-at91/clock.h b/arch/arm/mach-at91/clock.h index 8af8d963c8..97a08fd83f 100644 --- a/arch/arm/mach-at91/clock.h +++ b/arch/arm/mach-at91/clock.h @@ -13,7 +13,7 @@ #define CLK_TYPE_PROGRAMMABLE 0x4 #define CLK_TYPE_PERIPHERAL 0x8 #define CLK_TYPE_SYSTEM 0x10 - +#define CLK_TYPE_PERIPH_H64MX 0x80 struct clk { struct list_head node; diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h index 61078717c6..d74c14011c 100644 --- a/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -118,6 +118,7 @@ #define AT91_PMC_PLLADIV2 (1 << 12) /* PLLA divisor by 2 [some SAM9 only] */ #define AT91_PMC_PLLADIV2_OFF (0 << 12) #define AT91_PMC_PLLADIV2_ON (1 << 12) +#define AT91_PMC_H32MXDIV (1 << 24) /* AHB 32-bit Matrix Divisor [some SAMA5 only] */ #define AT91_PMC_USB 0x38 /* USB Clock Register [some SAM9 only] */ #define AT91_PMC_USBS (0x1 << 0) /* USB OHCI Input clock selection */ diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index 36e940d928..4fe8fd891c 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -118,6 +118,7 @@ #define AT91_MATRIX 0 /* not supported */ +#define AT91_PMC 0xfffffc00 /* * Internal Memory. diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 3f3a0e1a54..919901d6da 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -125,6 +125,8 @@ #define AT91_ID_UHP AT91SAM9260_ID_UHP #define AT91_PMC_UHP AT91SAM926x_PMC_UHP +#define AT91_PMC 0xfffffc00 + /* * Internal Memory. */ diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 1b48e230b4..9124df5caa 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -102,6 +102,7 @@ #define AT91_USART2 AT91SAM9261_BASE_US2 #define AT91_NB_USART 4 +#define AT91_PMC 0xfffffc00 /* * Internal Memory. diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index b42d191b99..e7ca8b63aa 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -129,6 +129,8 @@ #define AT91_ID_UHP AT91SAM9263_ID_UHP #define AT91_PMC_UHP AT91SAM926x_PMC_UHP +#define AT91_PMC 0xfffffc00 + /* * Internal Memory. */ diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index c81bb80c53..ff12ce458a 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -134,6 +134,8 @@ #define AT91_USART3 AT91SAM9G45_BASE_US3 #define AT91_NB_USART 5 +#define AT91_PMC 0xfffffc00 + /* * Internal Memory. */ diff --git a/arch/arm/mach-at91/include/mach/at91sam9n12.h b/arch/arm/mach-at91/include/mach/at91sam9n12.h index 26bdd13498..249bde466b 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9n12.h +++ b/arch/arm/mach-at91/include/mach/at91sam9n12.h @@ -129,6 +129,7 @@ #define AT91_USART3 AT91SAM9X5_BASE_US3 #define AT91_NB_USART 5 +#define AT91_PMC 0xfffffc00 /* * Internal Memory. diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5.h b/arch/arm/mach-at91/include/mach/at91sam9x5.h index 13b4f44379..7ba2e3b9b1 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9x5.h +++ b/arch/arm/mach-at91/include/mach/at91sam9x5.h @@ -136,6 +136,7 @@ #define AT91_USART3 AT91SAM9X5_BASE_US3 #define AT91_NB_USART 5 +#define AT91_PMC 0xfffffc00 /* * Internal Memory. diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index 0e213ce9da..f684d32949 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h @@ -26,7 +26,7 @@ #define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */ #define ARCH_ID_AT91SAM9X5 0x819a05a0 #define ARCH_ID_AT91SAM9N12 0x819a07a0 -#define ARCH_ID_SAMA5D3 0x8A5C07C0 +#define ARCH_ID_SAMA5 0x8A5C07C0 #define ARCH_ID_AT91SAM9XE128 0x329973a0 #define ARCH_ID_AT91SAM9XE256 0x329a93a0 @@ -48,12 +48,19 @@ #define ARCH_EXID_AT91SAM9G25 0x00000003 #define ARCH_EXID_AT91SAM9X25 0x00000004 +#define ARCH_EXID_SAMA5D3 0x00004300 #define ARCH_EXID_SAMA5D31 0x00444300 #define ARCH_EXID_SAMA5D33 0x00414300 #define ARCH_EXID_SAMA5D34 0x00414301 #define ARCH_EXID_SAMA5D35 0x00584300 #define ARCH_EXID_SAMA5D36 0x00004301 +#define ARCH_EXID_SAMA5D4 0x00000007 +#define ARCH_EXID_SAMA5D41 0x00000001 +#define ARCH_EXID_SAMA5D42 0x00000002 +#define ARCH_EXID_SAMA5D43 0x00000003 +#define ARCH_EXID_SAMA5D44 0x00000004 + #define ARCH_FAMILY_AT91X92 0x09200000 #define ARCH_FAMILY_AT91SAM9 0x01900000 #define ARCH_FAMILY_AT91SAM9XE 0x02900000 @@ -85,6 +92,9 @@ enum at91_soc_type { /* SAMA5D3 */ AT91_SOC_SAMA5D3, + /* SAMA5D4 */ + AT91_SOC_SAMA5D4, + /* Unknown type */ AT91_SOC_NONE }; @@ -107,6 +117,10 @@ enum at91_soc_subtype { AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34, AT91_SOC_SAMA5D35, AT91_SOC_SAMA5D36, + /* SAMA5D4 */ + AT91_SOC_SAMA5D41, AT91_SOC_SAMA5D42, AT91_SOC_SAMA5D43, + AT91_SOC_SAMA5D44, + /* Unknown subtype */ AT91_SOC_SUBTYPE_NONE }; @@ -217,6 +231,20 @@ static inline int at91_soc_is_detected(void) #define cpu_is_sama5d36() (0) #endif +#ifdef CONFIG_ARCH_SAMA5D4 +#define cpu_is_sama5d4() (at91_soc_initdata.type == AT91_SOC_SAMA5D4) +#define cpu_is_sama5d41() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D41) +#define cpu_is_sama5d42() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D42) +#define cpu_is_sama5d43() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D43) +#define cpu_is_sama5d44() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D44) +#else +#define cpu_is_sama5d4() (0) +#define cpu_is_sama5d41() (0) +#define cpu_is_sama5d42() (0) +#define cpu_is_sama5d43() (0) +#define cpu_is_sama5d44() (0) +#endif + /* * Since this is ARM, we will never run on any AVR32 CPU. But these * definitions may reduce clutter in common drivers. diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index 8f004deb42..bbaad714cf 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -19,8 +19,8 @@ #define AT91_BASE_DBGU0 0xfffff200 /* 9263, 9g45 */ #define AT91_BASE_DBGU1 0xffffee00 - -#define AT91_PMC 0xfffffc00 +/* sama5d4 */ +#define AT91_BASE_DBGU2 0xfc069000 #if defined(CONFIG_ARCH_AT91RM9200) #include <mach/at91rm9200.h> @@ -40,6 +40,8 @@ #include <mach/at91sam9x5.h> #elif defined(CONFIG_ARCH_SAMA5D3) #include <mach/sama5d3.h> +#elif defined(CONFIG_ARCH_SAMA5D4) +#include <mach/sama5d4.h> #elif defined(CONFIG_ARCH_AT91CAP9) #include <mach/at91cap9.h> #elif defined(CONFIG_ARCH_AT91X40) diff --git a/arch/arm/mach-at91/include/mach/sama5d3.h b/arch/arm/mach-at91/include/mach/sama5d3.h index 6884ff6a7e..e98b101ee0 100644 --- a/arch/arm/mach-at91/include/mach/sama5d3.h +++ b/arch/arm/mach-at91/include/mach/sama5d3.h @@ -108,6 +108,8 @@ #define AT91_NB_USART 3 +#define AT91_PMC 0xfffffc00 + /* * Internal Memory. */ diff --git a/arch/arm/mach-at91/include/mach/sama5d4.h b/arch/arm/mach-at91/include/mach/sama5d4.h new file mode 100644 index 0000000000..046fdb0426 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/sama5d4.h @@ -0,0 +1,134 @@ +/* + * Chip-specific header file for the SAMA5D4 family + * + * Copyright (C) 2014 Atmel Corporation, + * Bo Shen <voice.shen@atmel.com> + * + * Common definitions. + * Based on SAMA5D4 datasheet. + * + * Licensed under GPLv2 or later. + */ + +#ifndef SAMA5D4_H +#define SAMA5D4_H + +/* + * Peripheral identifiers/interrupts. + */ +#define SAMA5D4_ID_PIT 3 +#define SAMA5D4_ID_WDT 4 +#define SAMA5D4_ID_PIOD 5 +#define SAMA5D4_ID_USART0 6 +#define SAMA5D4_ID_USART1 7 +#define SAMA5D4_ID_DMA0 8 +#define SAMA5D4_ID_ICM 9 +#define SAMA5D4_ID_PKCC 10 +#define SAMA5D4_ID_SCI 11 +#define SAMA5D4_ID_AES 12 +#define SAMA5D4_ID_AESB 13 +#define SAMA5D4_ID_TDES 14 +#define SAMA5D4_ID_SHA 15 +#define SAMA5D4_ID_MPDDRC 16 +#define SAMA5D4_ID_MATRIX1 17 +#define SAMA5D4_ID_MATRIX0 18 +#define SAMA5D4_ID_VDEC 19 +#define SAMA5D4_ID_SECUMOD 20 +#define SAMA5D4_ID_MSADCC 21 +#define SAMA5D4_ID_HSMC 22 +#define SAMA5D4_ID_PIOA 23 +#define SAMA5D4_ID_PIOB 24 +#define SAMA5D4_ID_PIOC 25 +#define SAMA5D4_ID_PIOE 26 +#define SAMA5D4_ID_UART0 27 +#define SAMA5D4_ID_UART1 28 +#define SAMA5D4_ID_USART2 29 +#define SAMA5D4_ID_USART3 30 +#define SAMA5D4_ID_USART4 31 +#define SAMA5D4_ID_TWI0 32 +#define SAMA5D4_ID_TWI1 33 +#define SAMA5D4_ID_TWI2 34 +#define SAMA5D4_ID_HSMCI0 35 +#define SAMA5D4_ID_HSMCI1 36 +#define SAMA5D4_ID_SPI0 37 +#define SAMA5D4_ID_SPI1 38 +#define SAMA5D4_ID_SPI2 39 +#define SAMA5D4_ID_TC0 40 +#define SAMA5D4_ID_TC1 41 +#define SAMA5D4_ID_TC2 42 +#define SAMA5D4_ID_PWM 43 +#define SAMA5D4_ID_ADC 44 +#define SAMA5D4_ID_DBGU 45 +#define SAMA5D4_ID_UHPHS 46 +#define SAMA5D4_ID_UDPHS 47 +#define SAMA5D4_ID_SSC0 48 +#define SAMA5D4_ID_SSC1 49 +#define SAMA5D4_ID_DMA1 50 +#define SAMA5D4_ID_LCDC 51 +#define SAMA5D4_ID_ISI 52 +#define SAMA5D4_ID_TRNG 53 +#define SAMA5D4_ID_GMAC0 54 +#define SAMA5D4_ID_IRQ 56 +#define SAMA5D4_ID_IRQ 56 +#define SAMA5D4_ID_SFC 57 +#define SAMA5D4_ID_SECURAM 59 +#define SAMA5D4_ID_CTB 60 +#define SAMA5D4_ID_SMD 61 +#define SAMA5D4_ID_TWI3 62 +#define SAMA5D4_ID_CATB 63 +#define SAMA5D4_ID_SFR 64 +#define SAMA5D4_ID_AIC 65 +#define SAMA5D4_ID_SAIC 66 +#define SAMA5D4_ID_L2CC 67 + +/* + * User Peripheral physical base addresses. + */ + +#define SAMA5D4_BASE_LCDC 0xf0000000 /* (HLCDC5) Base Address */ +#define SAMA5D4_BASE_MPDDRC 0xf0010000 /* (MPDDRC) Base Address */ +#define SAMA5D4_BASE_PMC 0xf0018000 /* (PMC) Base Address */ +#define SAMA5D4_BASE_HSMCI0 0xf8000000 /* (MMCI0) Base Address */ +#define SAMA5D4_BASE_UART0 0xf8004000 /* (UART0) Base Address */ +#define SAMA5D4_BASE_SPI0 0xf8010000 /* (SPI0) Base Address */ +#define SAMA5D4_BASE_TC0 0xf801c000 /* (TC0) Base Address */ +#define SAMA5D4_BASE_GMAC0 0xf8020000 /* (GMAC0) Base Address */ +#define SAMA5D4_BASE_USART0 0xf802c000 /* (USART0) Base Address */ +#define SAMA5D4_BASE_USART1 0xf8030000 /* (USART1) Base Address */ +#define SAMA5D4_BASE_HSMCI1 0xfc000000 /* (HSMCI1) Base Address */ +#define SAMA5D4_BASE_UART1 0xfc004000 /* (UART1) Base Address */ +#define SAMA5D4_BASE_USART2 0xfc008000 /* (USART2) Base Address */ +#define SAMA5D4_BASE_USART3 0xfc00c000 /* (USART3) Base Address */ +#define SAMA5D4_BASE_USART4 0xfc010000 /* (USART4) Base Address */ +#define SAMA5D4_BASE_SPI1 0xfc018000 /* (SPI1) Base Address */ +#define SAMA5D4_BASE_GMAC1 0xfc028000 /* (GMAC1) Base Address */ +#define SAMA5D4_BASE_HSMC 0xfc05c000 /* (HSMC) Base Address */ +#define SAMA5D4_BASE_PMECC 0xfc05c070 /* (PMECC) Base Address */ +#define SAMA5D4_BASE_PMERRLOC 0xfc05c500 /* (PMERRLOC) Base Address */ +#define SAMA5D4_BASE_PIOD 0xfc068000 /* (PIOD) Base Address */ +#define SAMA5D4_BASE_PIT 0xfc068630 /* (PIT) Base Address */ +#define SAMA5D4_BASE_DBGU 0xfc069000 /* (DBGU) Base Address */ +#define SAMA5D4_BASE_PIOA 0xfc06a000 /* (PIOA) Base Address */ +#define SAMA5D4_BASE_PIOB 0xfc06b000 /* (PIOB) Base Address */ +#define SAMA5D4_BASE_PIOC 0xfc06c000 /* (PIOC) Base Address */ +#define SAMA5D4_BASE_PIOE 0xfc06d000 /* (PIOE) Base Address */ +#define SAMA5D4_BASE_AIC 0xfc06e000 /* (AIC) Base Address */ + +#define SAMA5D4_CHIPSELECT_3 0x80000000 + +/* + * Internal Memory. + */ +#define SAMA5D4_SRAM_BASE 0x00200000 /* Internal SRAM base address */ +#define SAMA5D4_SRAM_SIZE (128 * SZ_1K) /* Internal SRAM size */ + +#define AT91_NB_USART 7 +#define AT91_BASE_SYS 0xf0000000 +#define AT91_PMC SAMA5D4_BASE_PMC +#define AT91_DDRSDRC0 (0xf0010000 - AT91_BASE_SYS) +#define AT91_RSTC (0xfc068600 - AT91_BASE_SYS) +#define SAMA5D3_BASE_MPDDRC SAMA5D4_BASE_MPDDRC +#define SAMA5D3_SRAM_BASE SAMA5D4_SRAM_BASE +#define SAMA5D3_SRAM_SIZE SAMA5D4_SRAM_SIZE + +#endif diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c index 9f028079c2..60c067dbc6 100644 --- a/arch/arm/mach-at91/sam9_smc.c +++ b/arch/arm/mach-at91/sam9_smc.c @@ -19,7 +19,9 @@ #define AT91_SAM9_SMC_CS_STRIDE 0x10 #define AT91_SAMA5_SMC_CS_STRIDE 0x14 -#define AT91_SMC_CS_STRIDE ((at91_soc_initdata.type == AT91_SOC_SAMA5D3) ? AT91_SAMA5_SMC_CS_STRIDE : AT91_SAM9_SMC_CS_STRIDE) +#define AT91_SMC_CS_STRIDE ((at91_soc_initdata.type == AT91_SOC_SAMA5D3 \ + || at91_soc_initdata.type == AT91_SOC_SAMA5D4) \ + ? AT91_SAMA5_SMC_CS_STRIDE : AT91_SAM9_SMC_CS_STRIDE) #define AT91_SMC_CS(id, n) (smc_base_addr[id] + ((n) * AT91_SMC_CS_STRIDE)) static void __iomem *smc_base_addr[2]; @@ -29,7 +31,15 @@ static void sam9_smc_cs_write_mode(void __iomem *base, { void __iomem *mode_reg; - mode_reg = base + ((at91_soc_initdata.type == AT91_SOC_SAMA5D3) ? AT91_SAMA5_SMC_MODE : AT91_SAM9_SMC_MODE); + switch (at91_soc_initdata.type) { + case AT91_SOC_SAMA5D3: + case AT91_SOC_SAMA5D4: + mode_reg = base + AT91_SAMA5_SMC_MODE; + break; + default: + mode_reg = base + AT91_SAM9_SMC_MODE; + break; + } __raw_writel(config->mode | AT91_SMC_TDF_(config->tdf_cycles), @@ -95,7 +105,15 @@ static void sam9_smc_cs_read_mode(void __iomem *base, u32 val; void __iomem *mode_reg; - mode_reg = base + ((at91_soc_initdata.type == AT91_SOC_SAMA5D3) ? AT91_SAMA5_SMC_MODE : AT91_SAM9_SMC_MODE); + switch (at91_soc_initdata.type) { + case AT91_SOC_SAMA5D3: + case AT91_SOC_SAMA5D4: + mode_reg = base + AT91_SAMA5_SMC_MODE; + break; + default: + mode_reg = base + AT91_SAM9_SMC_MODE; + break; + } val = __raw_readl(mode_reg); diff --git a/arch/arm/mach-at91/sama5d4.c b/arch/arm/mach-at91/sama5d4.c new file mode 100644 index 0000000000..4d380ed88e --- /dev/null +++ b/arch/arm/mach-at91/sama5d4.c @@ -0,0 +1,304 @@ +/* + * Chip-specific setup code for the SAMA5D4 family + * + * Copyright (C) 2014 Atmel Corporation, + * Bo Shen <voice.shen@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +#include <common.h> +#include <gpio.h> +#include <init.h> +#include <mach/hardware.h> +#include <mach/at91_pmc.h> +#include <mach/io.h> +#include <mach/cpu.h> +#include <linux/clk.h> + +#include "soc.h" +#include "generic.h" +#include "clock.h" + +/* + * The peripheral clocks. + */ +static struct clk pit_clk = { + .name = "pit_clk", + .pid = SAMA5D4_ID_PIT, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk smc_clk = { + .name = "smc_clk", + .pid = SAMA5D4_ID_HSMC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioA_clk = { + .name = "pioA_clk", + .pid = SAMA5D4_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pid = SAMA5D4_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .pid = SAMA5D4_ID_PIOC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioD_clk = { + .name = "pioD_clk", + .pid = SAMA5D4_ID_PIOD, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioE_clk = { + .name = "pioE_clk", + .pid = SAMA5D4_ID_PIOE, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pid = SAMA5D4_ID_USART0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pid = SAMA5D4_ID_USART2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart3_clk = { + .name = "usart3_clk", + .pid = SAMA5D4_ID_USART3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart4_clk = { + .name = "usart4_clk", + .pid = SAMA5D4_ID_USART4, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc0_clk = { + .name = "mci0_clk", + .pid = SAMA5D4_ID_HSMCI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc1_clk = { + .name = "mci1_clk", + .pid = SAMA5D4_ID_HSMCI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tcb0_clk = { + .name = "tcb0_clk", + .pid = SAMA5D4_ID_TC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tcb1_clk = { + .name = "tcb1_clk", + .pid = SAMA5D4_ID_TC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk adc_clk = { + .name = "adc_clk", + .pid = SAMA5D4_ID_ADC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk dma0_clk = { + .name = "dma0_clk", + .pid = SAMA5D4_ID_DMA0, + .type = CLK_TYPE_PERIPHERAL | CLK_TYPE_PERIPH_H64MX, +}; +static struct clk dma1_clk = { + .name = "dma1_clk", + .pid = SAMA5D4_ID_DMA1, + .type = CLK_TYPE_PERIPHERAL | CLK_TYPE_PERIPH_H64MX, +}; +static struct clk uhphs_clk = { + .name = "uhphs", + .pid = SAMA5D4_ID_UHPHS, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udphs_clk = { + .name = "udphs_clk", + .pid = SAMA5D4_ID_UDPHS, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk lcdc_clk = { + .name = "lcdc_clk", + .pid = SAMA5D4_ID_LCDC, + .type = CLK_TYPE_PERIPHERAL | CLK_TYPE_PERIPH_H64MX, +}; +static struct clk isi_clk = { + .name = "isi_clk", + .pid = SAMA5D4_ID_ISI, + .type = CLK_TYPE_PERIPHERAL | CLK_TYPE_PERIPH_H64MX, +}; +static struct clk macb0_clk = { + .name = "macb0_clk", + .pid = SAMA5D4_ID_GMAC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi0_clk = { + .name = "twi0_clk", + .pid = SAMA5D4_ID_TWI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi2_clk = { + .name = "twi2_clk", + .pid = SAMA5D4_ID_TWI2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pid = SAMA5D4_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk smd_clk = { + .name = "smd_clk", + .pid = SAMA5D4_ID_SMD, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc0_clk = { + .name = "ssc0_clk", + .pid = SAMA5D4_ID_SSC0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc1_clk = { + .name = "ssc1_clk", + .pid = SAMA5D4_ID_SSC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk sha_clk = { + .name = "sha_clk", + .pid = SAMA5D4_ID_SHA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk aes_clk = { + .name = "aes_clk", + .pid = SAMA5D4_ID_AES, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tdes_clk = { + .name = "tdes_clk", + .pid = SAMA5D4_ID_TDES, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pit_clk, + &smc_clk, + &pioA_clk, + &pioB_clk, + &pioC_clk, + &pioD_clk, + &pioE_clk, + &usart0_clk, + &usart2_clk, + &usart3_clk, + &usart4_clk, + &mmc0_clk, + &mmc1_clk, + &tcb0_clk, + &tcb1_clk, + &adc_clk, + &dma0_clk, + &dma1_clk, + &uhphs_clk, + &udphs_clk, + &lcdc_clk, + &isi_clk, + &macb0_clk, + &twi0_clk, + &twi2_clk, + &spi0_clk, + &smd_clk, + &ssc0_clk, + &ssc1_clk, + &sha_clk, + &aes_clk, + &tdes_clk, +}; + +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; + +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; + +static struct clk pck2 = { + .name = "pck2", + .pmc_mask = AT91_PMC_PCK2, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 2, +}; + +static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("macb_clk", "macb0", &macb0_clk), + CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci0", &mmc0_clk), + CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci1", &mmc1_clk), + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi0", &spi0_clk), + CLKDEV_DEV_ID("at91-pit", &pit_clk), + CLKDEV_CON_DEV_ID("hck1", "atmel_hlcdfb", &lcdc_clk), +}; + +static struct clk_lookup usart_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("usart", "atmel_usart0", &mck), + CLKDEV_CON_DEV_ID("usart", "atmel_usart1", &usart0_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart3", &usart2_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart4", &usart3_clk), +}; + +static void __init sama5d4_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clkdev_add_physbase(&pioA_clk, SAMA5D4_BASE_PIOA, 0); + clkdev_add_physbase(&pioB_clk, SAMA5D4_BASE_PIOB, 0); + clkdev_add_physbase(&pioC_clk, SAMA5D4_BASE_PIOC, 0); + clkdev_add_physbase(&pioD_clk, SAMA5D4_BASE_PIOD, 0); + clkdev_add_physbase(&pioE_clk, SAMA5D4_BASE_PIOE, 0); + + clkdev_add_table(periph_clocks_lookups, + ARRAY_SIZE(periph_clocks_lookups)); + + clkdev_add_table(usart_clocks_lookups, + ARRAY_SIZE(usart_clocks_lookups)); + + clk_register(&pck0); + clk_register(&pck1); + clk_register(&pck2); +} + +/* -------------------------------------------------------------------- + * Processor initialization + * -------------------------------------------------------------------- */ +static void sama5d4_initialize(void) +{ + /* Register the processor-specific clocks */ + sama5d4_register_clocks(); + + /* Register GPIO subsystem */ + at91_add_sam9x5_gpio(0, SAMA5D4_BASE_PIOA); + at91_add_sam9x5_gpio(1, SAMA5D4_BASE_PIOB); + at91_add_sam9x5_gpio(2, SAMA5D4_BASE_PIOC); + at91_add_sam9x5_gpio(3, SAMA5D4_BASE_PIOD); + at91_add_sam9x5_gpio(4, SAMA5D4_BASE_PIOE); + + at91_add_pit(SAMA5D4_BASE_PIT); + at91_add_sam9_smc(DEVICE_ID_SINGLE, SAMA5D4_BASE_HSMC + 0x600, 0xa0); +} + +AT91_SOC_START(sama5d4) + .init = sama5d4_initialize, +AT91_SOC_END diff --git a/arch/arm/mach-at91/sama5d4_devices.c b/arch/arm/mach-at91/sama5d4_devices.c new file mode 100644 index 0000000000..3806971688 --- /dev/null +++ b/arch/arm/mach-at91/sama5d4_devices.c @@ -0,0 +1,495 @@ +/* + * On-Chip devices setup code for the SAMA5D4 family + * + * Copyright (C) 2014 Atmel Corporation. + * Bo Shen <voice.shen@atmel.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <common.h> +#include <init.h> +#include <sizes.h> +#include <gpio.h> +#include <asm/armlinux.h> +#include <mach/hardware.h> +#include <mach/board.h> +#include <mach/at91_pmc.h> +#include <mach/at91sam9x5_matrix.h> +#include <mach/at91sam9_ddrsdr.h> +#include <mach/iomux.h> +#include <mach/io.h> +#include <mach/cpu.h> +#include <i2c/i2c-gpio.h> + +#include "generic.h" + +void at91_add_device_sdram(u32 size) +{ + if (!size) + size = at91sama5_get_ddram_size(); + + arm_add_mem_device("ram0", SAMA5_DDRCS, size); + add_mem_device("sram0", SAMA5D4_SRAM_BASE, + SAMA5D4_SRAM_SIZE, IORESOURCE_MEM_WRITEABLE); +} + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ +#if defined(CONFIG_NAND_ATMEL) +static struct resource nand_resources[] = { + [0] = { + .start = SAMA5D4_CHIPSELECT_3, + .end = SAMA5D4_CHIPSELECT_3 + SZ_128M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = SAMA5D4_BASE_PMECC, + .end = SAMA5D4_BASE_PMECC + 0x490 - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = SAMA5D4_BASE_PMERRLOC, + .end = SAMA5D4_BASE_PMERRLOC + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +void __init at91_add_device_nand(struct atmel_nand_data *data) +{ + if (!data) + return; + + at91_set_A_periph(AT91_PIN_PC5, 0); /* D0 */ + at91_set_A_periph(AT91_PIN_PC6, 0); /* D1 */ + at91_set_A_periph(AT91_PIN_PC7, 0); /* D2 */ + at91_set_A_periph(AT91_PIN_PC8, 0); /* D3 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* D4 */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* D5 */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* D6 */ + at91_set_A_periph(AT91_PIN_PC12, 0); /* D7 */ + at91_set_A_periph(AT91_PIN_PC13, 0); /* RE */ + at91_set_A_periph(AT91_PIN_PC14, 0); /* WE */ + at91_set_A_periph(AT91_PIN_PC15, 1); /* NCS */ + at91_set_A_periph(AT91_PIN_PC16, 1); /* RDY */ + at91_set_A_periph(AT91_PIN_PC17, 1); /* ALE */ + at91_set_A_periph(AT91_PIN_PC18, 1); /* CLE */ + + /* enable pin */ + if (gpio_is_valid(data->enable_pin)) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (gpio_is_valid(data->rdy_pin)) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (gpio_is_valid(data->det_pin)) + at91_set_gpio_input(data->det_pin, 1); + + add_generic_device_res("atmel_nand", 0, nand_resources, + ARRAY_SIZE(nand_resources), data); +} +#else +void __init at91_add_device_nand(struct atmel_nand_data *data) {} +#endif + +#if defined(CONFIG_DRIVER_NET_MACB) +void at91_add_device_eth(int id, struct macb_platform_data *data) +{ + if (!data) + return; + + switch (id) { + case 0: + at91_set_A_periph(AT91_PIN_PB16, 0); /* GMDC */ + at91_set_A_periph(AT91_PIN_PB17, 0); /* GMDIO */ + + at91_set_A_periph(AT91_PIN_PB0, 0); /* GTXCK */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* GTXEN */ + at91_set_A_periph(AT91_PIN_PB6, 0); /* GRXDV */ + at91_set_A_periph(AT91_PIN_PB7, 0); /* GRXER */ + + switch (data->phy_interface) { + case PHY_INTERFACE_MODE_MII: + at91_set_A_periph(AT91_PIN_PB4, 0); /* GCRS */ + at91_set_A_periph(AT91_PIN_PB5, 0); /* GCOL */ + at91_set_A_periph(AT91_PIN_PB14, 0); /* GTX2 */ + at91_set_A_periph(AT91_PIN_PB15, 0); /* GTX3 */ + at91_set_A_periph(AT91_PIN_PB3, 0); /* GTXER */ + at91_set_A_periph(AT91_PIN_PB1, 0); /* GRXCK */ + at91_set_A_periph(AT91_PIN_PB10, 0); /* GRX2 */ + at91_set_A_periph(AT91_PIN_PB11, 0); /* GRX3 */ + case PHY_INTERFACE_MODE_RMII: + at91_set_A_periph(AT91_PIN_PB12, 0); /* GTX0 */ + at91_set_A_periph(AT91_PIN_PB13, 0); /* GTX1 */ + at91_set_A_periph(AT91_PIN_PB8, 0); /* GRX0 */ + at91_set_A_periph(AT91_PIN_PB9, 0); /* GRX1 */ + break; + default: + return; + } + + add_generic_device("macb", id, NULL, SAMA5D4_BASE_GMAC0, SZ_16K, + IORESOURCE_MEM, data); + break; + case 1: + at91_set_B_periph(AT91_PIN_PA22, 0); /* GMDC */ + at91_set_B_periph(AT91_PIN_PA23, 0); /* GMDIO */ + + at91_set_B_periph(AT91_PIN_PA2, 0); /* GTXCK */ + at91_set_B_periph(AT91_PIN_PA4, 0); /* GTXEN */ + at91_set_B_periph(AT91_PIN_PA10, 0); /* GRXDV */ + at91_set_B_periph(AT91_PIN_PA11, 0); /* GRXER */ + + switch (data->phy_interface) { + case PHY_INTERFACE_MODE_MII: + at91_set_B_periph(AT91_PIN_PA6, 0); /* GCRS */ + at91_set_B_periph(AT91_PIN_PA9, 0); /* GCOL */ + at91_set_B_periph(AT91_PIN_PA20, 0); /* GTX2 */ + at91_set_B_periph(AT91_PIN_PA21, 0); /* GTX3 */ + at91_set_B_periph(AT91_PIN_PA5, 0); /* GTXER */ + at91_set_B_periph(AT91_PIN_PA3, 0); /* GRXCK */ + at91_set_B_periph(AT91_PIN_PA18, 0); /* GRX2 */ + at91_set_B_periph(AT91_PIN_PA19, 0); /* GRX3 */ + case PHY_INTERFACE_MODE_RMII: + at91_set_B_periph(AT91_PIN_PA12, 0); /* GTX0 */ + at91_set_B_periph(AT91_PIN_PA13, 0); /* GTX1 */ + at91_set_B_periph(AT91_PIN_PA8, 0); /* GRX0 */ + at91_set_B_periph(AT91_PIN_PA9, 0); /* GRX1 */ + break; + default: + return; + } + + add_generic_device("macb", id, NULL, SAMA5D4_BASE_GMAC1, SZ_16K, + IORESOURCE_MEM, data); + break; + default: + return; + } + +} +#else +void at91_add_device_eth(int id, struct macb_platform_data *data) {} +#endif + +#if defined(CONFIG_MCI_ATMEL) +void __init at91_add_device_mci(short mmc_id, + struct atmel_mci_platform_data *data) +{ + resource_size_t start = ~0; + + if (!data) + return; + + /* Must have at least one usable slot */ + if (!data->bus_width) + return; + + /* input/irq */ + if (gpio_is_valid(data->detect_pin)) { + at91_set_gpio_input(data->detect_pin, 1); + at91_set_deglitch(data->detect_pin, 1); + } + + if (gpio_is_valid(data->wp_pin)) + at91_set_gpio_input(data->wp_pin, 1); + + switch (mmc_id) { + /* MCI0 */ + case 0: + start = SAMA5D4_BASE_HSMCI0; + + /* CLK */ + at91_set_B_periph(AT91_PIN_PC4, 0); + + /* CMD */ + at91_set_B_periph(AT91_PIN_PC5, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PC6, 1); + switch (data->bus_width) { + case 8: + at91_set_B_periph(AT91_PIN_PC10, 1); + at91_set_B_periph(AT91_PIN_PC11, 1); + at91_set_B_periph(AT91_PIN_PC12, 1); + at91_set_B_periph(AT91_PIN_PC13, 1); + case 4: + at91_set_B_periph(AT91_PIN_PC7, 1); + at91_set_B_periph(AT91_PIN_PC8, 1); + at91_set_B_periph(AT91_PIN_PC9, 1); + }; + + break; + /* MCI1 */ + case 1: + start = SAMA5D4_BASE_HSMCI1; + + /* + * As the mci1 io internal pull down is to strong, + * which cause external pull up doesn't work, so, + * disable internal pull down. + */ + + /* CLK */ + at91_set_C_periph(AT91_PIN_PE18, 0); + at91_set_pulldown(AT91_PIN_PE18, 0); + + /* CMD */ + at91_set_C_periph(AT91_PIN_PE19, 1); + at91_set_pulldown(AT91_PIN_PE19, 0); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_C_periph(AT91_PIN_PE20, 1); + at91_set_pulldown(AT91_PIN_PE20, 0); + if (data->bus_width == 4) { + at91_set_C_periph(AT91_PIN_PE21, 1); + at91_set_pulldown(AT91_PIN_PE21, 0); + at91_set_C_periph(AT91_PIN_PE22, 1); + at91_set_pulldown(AT91_PIN_PE22, 0); + at91_set_C_periph(AT91_PIN_PE23, 1); + at91_set_pulldown(AT91_PIN_PE23, 0); + } + + break; + } + + add_generic_device("atmel_mci", mmc_id, NULL, start, SZ_16K, + IORESOURCE_MEM, data); +} +#else +void __init at91_add_device_mci(short mmc_id, + struct atmel_mci_platform_data *data) {} +#endif + +#if defined(CONFIG_I2C_GPIO) +static struct i2c_gpio_platform_data pdata_i2c[] = { + { + .sda_pin = AT91_PIN_PA30, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA31, + .scl_is_open_drain = 1, + .udelay = 5, /* ~100 kHz */ + }, { + .sda_pin = AT91_PIN_PE29, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PE30, + .scl_is_open_drain = 1, + .udelay = 5, /* ~100 kHz */ + }, { + .sda_pin = AT91_PIN_PB29, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PB30, + .scl_is_open_drain = 1, + .udelay = 5, /* ~100 kHz */ + }, { + .sda_pin = AT91_PIN_PC25, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PC26, + .scl_is_open_drain = 1, + .udelay = 5, /* ~100 kHz */ + } +}; + +void at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, + int nr_devices) +{ + struct i2c_gpio_platform_data *pdata; + + if (i2c_id > ARRAY_SIZE(pdata_i2c)) + return; + + i2c_register_board_info(i2c_id, devices, nr_devices); + + pdata = &pdata_i2c[i2c_id]; + + at91_set_GPIO_periph(pdata->sda_pin, 1); /* TWD (SDA) */ + at91_set_multi_drive(pdata->sda_pin, 1); + + at91_set_GPIO_periph(pdata->scl_pin, 1); /* TWCK (SCL) */ + at91_set_multi_drive(pdata->scl_pin, 1); + + add_generic_device_res("i2c-gpio", i2c_id, NULL, 0, pdata); +} +#else +void at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, + int nr_devices) {} +#endif + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ +#if defined(CONFIG_DRIVER_SPI_ATMEL) +static unsigned spi0_standard_cs[2] = { AT91_PIN_PC3, AT91_PIN_PC4 }; +static unsigned spi1_standard_cs[2] = { AT91_PIN_PB21, AT91_PIN_PB22 }; + +static struct at91_spi_platform_data spi_pdata[] = { + [0] = { + .chipselect = spi0_standard_cs, + .num_chipselect = ARRAY_SIZE(spi0_standard_cs), + }, + [1] = { + .chipselect = spi1_standard_cs, + .num_chipselect = ARRAY_SIZE(spi1_standard_cs), + }, +}; + +void at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata) +{ + int i; + int cs_pin; + resource_size_t start = ~0; + + BUG_ON(spi_id > 1); + + if (!pdata) + pdata = &spi_pdata[spi_id]; + + for (i = 0; i < pdata->num_chipselect; i++) { + cs_pin = pdata->chipselect[i]; + + /* enable chip-select pin */ + if (gpio_is_valid(cs_pin)) + at91_set_gpio_output(cs_pin, 1); + } + + /* Configure SPI bus(es) */ + switch (spi_id) { + case 0: + start = SAMA5D4_BASE_SPI0; + at91_set_A_periph(AT91_PIN_PC0, 0); /* SPI0_MISO */ + at91_set_A_periph(AT91_PIN_PC1, 0); /* SPI0_MOSI */ + at91_set_A_periph(AT91_PIN_PC2, 0); /* SPI0_SPCK */ + break; + case 1: + start = SAMA5D4_BASE_SPI1; + at91_set_A_periph(AT91_PIN_PB18, 0); /* SPI1_MISO */ + at91_set_A_periph(AT91_PIN_PB19, 0); /* SPI1_MOSI */ + at91_set_A_periph(AT91_PIN_PB20, 0); /* SPI1_SPCK */ + break; + } + + add_generic_device("atmel_spi", spi_id, NULL, start, SZ_16K, + IORESOURCE_MEM, pdata); +} +#else +void at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata) {} +#endif + +/* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ +#if defined(CONFIG_DRIVER_VIDEO_ATMEL_HLCD) +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) +{ + BUG_ON(!data); + + at91_set_A_periph(AT91_PIN_PA24, 0); /* LCDPWM */ + at91_set_A_periph(AT91_PIN_PA25, 0); /* LCDDISP */ + at91_set_A_periph(AT91_PIN_PA26, 0); /* LCDVSYNC */ + at91_set_A_periph(AT91_PIN_PA27, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PA28, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PA29, 0); /* LCDDEN */ + + at91_set_A_periph(AT91_PIN_PA2, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PA3, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PA4, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PA5, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PA6, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PA7, 0); /* LCDD7 */ + + at91_set_A_periph(AT91_PIN_PA10, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PA11, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PA12, 0); /* LCDD12 */ + at91_set_A_periph(AT91_PIN_PA13, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PA14, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PA15, 0); /* LCDD15 */ + + at91_set_A_periph(AT91_PIN_PA18, 0); /* LCDD18 */ + at91_set_A_periph(AT91_PIN_PA19, 0); /* LCDD19 */ + at91_set_A_periph(AT91_PIN_PA20, 0); /* LCDD20 */ + at91_set_A_periph(AT91_PIN_PA21, 0); /* LCDD21 */ + at91_set_A_periph(AT91_PIN_PA22, 0); /* LCDD22 */ + at91_set_A_periph(AT91_PIN_PA23, 0); /* LCDD23 */ + + add_generic_device("atmel_hlcdfb", DEVICE_ID_SINGLE, NULL, + SAMA5D4_BASE_LCDC, SZ_4K, IORESOURCE_MEM, data); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} +#endif + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ +#if defined(CONFIG_DRIVER_SERIAL_ATMEL) +resource_size_t __init at91_configure_dbgu(void) +{ + at91_set_A_periph(AT91_PIN_PB25, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB24, 0); /* RXD1 */ + + return SAMA5D4_BASE_DBGU; +} + +resource_size_t __init at91_configure_usart0(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PD13, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PD12, 0); /* RXD1 */ + + return SAMA5D4_BASE_USART0; +} + +resource_size_t __init at91_configure_usart1(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PD17, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PD16, 0); /* RXD1 */ + + return SAMA5D4_BASE_USART1; +} + + +resource_size_t __init at91_configure_usart2(unsigned pins) +{ + at91_set_B_periph(AT91_PIN_PB5, 1); /* TXD1 */ + at91_set_B_periph(AT91_PIN_PB4, 0); /* RXD1 */ + + return SAMA5D4_BASE_USART2; +} + +resource_size_t __init at91_configure_usart3(unsigned pins) +{ + at91_set_B_periph(AT91_PIN_PE17, 1); /* TXD1 */ + at91_set_B_periph(AT91_PIN_PE16, 0); /* RXD1 */ + + return SAMA5D4_BASE_USART3; +} + +resource_size_t __init at91_configure_usart4(unsigned pins) +{ + at91_set_B_periph(AT91_PIN_PE27, 1); /* TXD1 */ + at91_set_B_periph(AT91_PIN_PE26, 0); /* RXD1 */ + + return SAMA5D4_BASE_USART4; +} + +resource_size_t __init at91_configure_usart5(unsigned pins) +{ + at91_set_B_periph(AT91_PIN_PE30, 1); /* TXD1 */ + at91_set_B_periph(AT91_PIN_PE29, 0); /* RXD1 */ + + return SAMA5D4_BASE_UART0; +} + +resource_size_t __init at91_configure_usart6(unsigned pins) +{ + at91_set_C_periph(AT91_PIN_PC26, 1); /* TXD1 */ + at91_set_C_periph(AT91_PIN_PC25, 0); /* RXD1 */ + + return SAMA5D4_BASE_UART1; +} +#endif diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 076d0812b3..030b8a2c58 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -39,6 +39,9 @@ static void __init soc_detect(u32 dbgu_base) cidr = __raw_readl(dbgu_base + AT91_DBGU_CIDR); socid = cidr & ~AT91_CIDR_VERSION; + /* sub version of soc */ + at91_soc_initdata.exid = __raw_readl(dbgu_base + AT91_DBGU_EXID); + switch (socid) { case ARCH_ID_AT91RM9200: at91_soc_initdata.type = AT91_SOC_RM9200; @@ -89,9 +92,16 @@ static void __init soc_detect(u32 dbgu_base) at91_boot_soc = at91sam9n12_soc; break; - case ARCH_ID_SAMA5D3: - at91_soc_initdata.type = AT91_SOC_SAMA5D3; - at91_boot_soc = at91sama5d3_soc; + case ARCH_ID_SAMA5: + if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) { + at91_soc_initdata.type = AT91_SOC_SAMA5D3; + at91_boot_soc = at91sama5d3_soc; + } else { + if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D4) { + at91_soc_initdata.type = AT91_SOC_SAMA5D4; + at91_boot_soc = at91sama5d4_soc; + } + } break; } @@ -112,9 +122,6 @@ static void __init soc_detect(u32 dbgu_base) at91_soc_initdata.cidr = cidr; - /* sub version of soc */ - at91_soc_initdata.exid = __raw_readl(dbgu_base + AT91_DBGU_EXID); - if (at91_soc_initdata.type == AT91_SOC_SAM9G45) { switch (at91_soc_initdata.exid) { case ARCH_EXID_AT91SAM9M10: @@ -168,6 +175,23 @@ static void __init soc_detect(u32 dbgu_base) break; } } + + if (at91_soc_initdata.type == AT91_SOC_SAMA5D4) { + switch (at91_soc_initdata.exid) { + case ARCH_EXID_SAMA5D41: + at91_soc_initdata.subtype = AT91_SOC_SAMA5D41; + break; + case ARCH_EXID_SAMA5D42: + at91_soc_initdata.subtype = AT91_SOC_SAMA5D42; + break; + case ARCH_EXID_SAMA5D43: + at91_soc_initdata.subtype = AT91_SOC_SAMA5D43; + break; + case ARCH_EXID_SAMA5D44: + at91_soc_initdata.subtype = AT91_SOC_SAMA5D44; + break; + } + } } static const char *soc_name[] = { @@ -182,6 +206,7 @@ static const char *soc_name[] = { [AT91_SOC_SAM9X5] = "at91sam9x5", [AT91_SOC_SAM9N12] = "at91sam9n12", [AT91_SOC_SAMA5D3] = "sama5d3", + [AT91_SOC_SAMA5D4] = "sama5d4", [AT91_SOC_NONE] = "Unknown" }; @@ -209,6 +234,10 @@ static const char *soc_subtype_name[] = { [AT91_SOC_SAMA5D34] = "sama5d34", [AT91_SOC_SAMA5D35] = "sama5d35", [AT91_SOC_SAMA5D36] = "sama5d36", + [AT91_SOC_SAMA5D41] = "sama5d41", + [AT91_SOC_SAMA5D42] = "sama5d42", + [AT91_SOC_SAMA5D43] = "sama5d43", + [AT91_SOC_SAMA5D44] = "sama5d44", [AT91_SOC_SUBTYPE_NONE] = "Unknown" }; @@ -226,6 +255,8 @@ static int at91_detect(void) soc_detect(AT91_BASE_DBGU0); if (!at91_soc_is_detected()) soc_detect(AT91_BASE_DBGU1); + if (!at91_soc_is_detected()) + soc_detect(AT91_BASE_DBGU2); if (!at91_soc_is_detected()) panic("AT91: Impossible to detect the SOC type"); diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h index b2278a5b32..76e4621f8a 100644 --- a/arch/arm/mach-at91/soc.h +++ b/arch/arm/mach-at91/soc.h @@ -19,6 +19,7 @@ extern struct at91_init_soc at91sam9rl_soc; extern struct at91_init_soc at91sam9x5_soc; extern struct at91_init_soc at91sam9n12_soc; extern struct at91_init_soc at91sama5d3_soc; +extern struct at91_init_soc at91sama5d4_soc; #define AT91_SOC_START(_name) \ struct at91_init_soc __initdata at91##_name##_soc \ @@ -66,6 +67,10 @@ static inline int at91_soc_is_enabled(void) #define at91sam9n12_soc at91_boot_soc #endif -#if !defined(CONFIG_SOC_SAMA5) +#if !defined(CONFIG_ARCH_SAMA5D3) #define at91sama5d3_soc at91_boot_soc #endif + +#if !defined(CONFIG_ARCH_SAMA5D4) +#define at91sama5d4_soc at91_boot_soc +#endif |