diff options
276 files changed, 11160 insertions, 1763 deletions
@@ -1,5 +1,5 @@ VERSION = 2013 -PATCHLEVEL = 01 +PATCHLEVEL = 02 SUBLEVEL = 0 EXTRAVERSION = NAME = Amissive Actinocutious Kiwi @@ -547,17 +547,6 @@ quiet_cmd_barebox_version = GEN .version fi; \ $(MAKE) $(build)=common -# Check size of a file -quiet_cmd_check_file_size = CHKSIZE $@ - cmd_check_file_size = set -e; \ - size=`stat -c%s $@`; \ - max_size=`printf "%d" $2`; \ - if [ $$size -gt $$max_size ] ; \ - then \ - echo "$@ size $$size > of the maximum size $$max_size" >&2; \ - exit 1 ; \ - fi; - # Generate System.map quiet_cmd_sysmap = SYSMAP cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap diff --git a/arch/arm/Makefile b/arch/arm/Makefile index a36adfb7e3..fcb296966a 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -69,6 +69,7 @@ machine-$(CONFIG_ARCH_TEGRA) := tegra # by CONFIG_* macro name. board-$(CONFIG_MACH_A9M2410) := a9m2410 board-$(CONFIG_MACH_A9M2440) := a9m2440 +board-$(CONFIG_MACH_ANIMEO_IP) := animeo_ip board-$(CONFIG_MACH_AT91RM9200EK) := at91rm9200ek board-$(CONFIG_MACH_AT91SAM9260EK) := at91sam9260ek board-$(CONFIG_MACH_AT91SAM9261EK) := at91sam9261ek @@ -77,7 +78,9 @@ board-$(CONFIG_MACH_AT91SAM9G10EK) := at91sam9261ek board-$(CONFIG_MACH_AT91SAM9G20EK) := at91sam9260ek board-$(CONFIG_MACH_AT91SAM9N12EK) := at91sam9n12ek board-$(CONFIG_MACH_AT91SAM9X5EK) := at91sam9x5ek +board-$(CONFIG_MACH_AT91SAM9M10IHD) := at91sam9m10ihd board-$(CONFIG_MACH_AT91SAM9M10G45EK) := at91sam9m10g45ek +board-$(CONFIG_MACH_SAMA5D3XEK) := sama5d3xek board-$(CONFIG_MACH_CLEP7212) := clep7212 board-$(CONFIG_MACH_DSS11) := dss11 board-$(CONFIG_MACH_EDB9301) := edb93xx @@ -94,6 +97,7 @@ board-$(CONFIG_MACH_EUKREA_CPUIMX35) := eukrea_cpuimx35 board-$(CONFIG_MACH_EUKREA_CPUIMX51SD) := eukrea_cpuimx51 board-$(CONFIG_MACH_FREESCALE_MX25_3STACK) := freescale-mx25-3-stack board-$(CONFIG_MACH_FREESCALE_MX35_3STACK) := freescale-mx35-3-stack +board-$(CONFIG_MACH_GE863) := telit-evk-pro3 board-$(CONFIG_MACH_IMX21ADS) := imx21ads board-$(CONFIG_MACH_IMX27ADS) := imx27ads board-$(CONFIG_MACH_IMX233_OLINUXINO) := imx233-olinuxino diff --git a/arch/arm/boards/animeo_ip/Makefile b/arch/arm/boards/animeo_ip/Makefile new file mode 100644 index 0000000000..eb072c0161 --- /dev/null +++ b/arch/arm/boards/animeo_ip/Makefile @@ -0,0 +1 @@ +obj-y += init.o diff --git a/arch/arm/boards/animeo_ip/config.h b/arch/arm/boards/animeo_ip/config.h new file mode 100644 index 0000000000..006820cf21 --- /dev/null +++ b/arch/arm/boards/animeo_ip/config.h @@ -0,0 +1,6 @@ +#ifndef __CONFIG_H +#define __CONFIG_H + +#define AT91_MAIN_CLOCK 18432000 /* 18.432 MHz crystal */ + +#endif /* __CONFIG_H */ diff --git a/arch/arm/boards/animeo_ip/env/config b/arch/arm/boards/animeo_ip/env/config new file mode 100644 index 0000000000..a0537b8829 --- /dev/null +++ b/arch/arm/boards/animeo_ip/env/config @@ -0,0 +1,39 @@ +#!/bin/sh + +# use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration +ip=dhcp-barebox +global.dhcp.vendor_id=barebox-animeo-ip + +# 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', 'nor', 'nand' or empty +oftree_loc=nfs + +# can be either 'jffs2' or 'ubifs' +rootfs_type=ubifs +rootfsimage=root.$rootfs_type + +kernelimage=zImage +#kernelimage=uImage +#kernelimage=Image +#kernelimage=Image.lzo + +nand_device=atmel_nand +nand_parts="32k(at91bootstrap),256k(barebox)ro,32k(bareboxenv),704k(user_block),1728k(kernel),-(root)" +rootfs_mtdblock_nand=5 + +autoboot_timeout=3 + +bootargs="console=ttyS1,38400n8 earlyprintk" + +# 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/animeo_ip/init.c b/arch/arm/boards/animeo_ip/init.c new file mode 100644 index 0000000000..ada3bb044e --- /dev/null +++ b/arch/arm/boards/animeo_ip/init.c @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPLv2 only + */ + +#include <common.h> +#include <net.h> +#include <init.h> +#include <environment.h> +#include <fec.h> +#include <asm/armlinux.h> +#include <generated/mach-types.h> +#include <partition.h> +#include <fs.h> +#include <fcntl.h> +#include <io.h> +#include <asm/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/io.h> +#include <mach/at91_pmc.h> +#include <mach/at91_rstc.h> + +static bool animeo_ip_is_buco; +static bool animeo_ip_is_io; + +static int animeo_ip_get_pio_revision(int gpio, char *name) +{ + int ret; + + ret = gpio_request(gpio, name); + if (ret) { + pr_err("animeo_ip: can not request gpio %d as %s (%d)\n", + gpio, name, ret); + return ret; + } + + ret = gpio_direction_input(gpio); + + if (ret) { + pr_err("animeo_ip: can configure gpio %d (%s) as input (%d)\n", + gpio, name, ret); + return ret; + } + + return gpio_get_value(gpio); +} + +static void animeo_ip_detect_version(void) +{ + struct device_d *dev = NULL; + char *model, *version; + int val; + + animeo_ip_is_io = false; + animeo_ip_is_buco = false; + model = "SubCo"; + version = "SDN"; + + dev = add_generic_device_res("animeo_ip", DEVICE_ID_SINGLE, NULL, 0, NULL); + + val = animeo_ip_get_pio_revision(AT91_PIN_PC20, "is_buco"); + if (val < 0) { + pr_warn("Can not detect model use %s by default\n", model); + } else if (val) { + animeo_ip_is_buco = true; + model = "SubCo"; + } + + val = animeo_ip_get_pio_revision(AT91_PIN_PC21, "is_io"); + if (val < 0) { + pr_warn("Can not detect version use %s by default\n", model); + } else if (val) { + animeo_ip_is_io = true; + version = "IO"; + } + + dev_add_param_fixed(dev, "model", model); + dev_add_param_fixed(dev, "version", version); +} + +static struct atmel_nand_data nand_pdata = { + .ale = 21, + .cle = 22, + .det_pin = -EINVAL, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .bus_width_16 = 0, + .on_flash_bbt = 1, +}; + +static struct sam9_smc_config animeo_ip_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 3, + .ncs_write_pulse = 3, + .nwe_pulse = 3, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 2, +}; + +static void animeo_ip_add_device_nand(void) +{ + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(0, 3, &animeo_ip_nand_smc_config); + + at91_add_device_nand(&nand_pdata); +} + +static struct at91_ether_platform_data macb_pdata = { + .phy_addr = 0, +}; + +/* + * MCI (SD/MMC) + */ +#if defined(CONFIG_MCI_ATMEL) +static struct atmel_mci_platform_data __initdata animeo_ip_mci_data = { + .bus_width = 4, + .slot_b = 1, + .detect_pin = -EINVAL, + .wp_pin = -EINVAL, +}; + +static void animeo_ip_add_device_mci(void) +{ + at91_add_device_mci(0, &animeo_ip_mci_data); +} +#else +static void animeo_ip_add_device_mci(void) {} +#endif + +struct gpio_bicolor_led leds[] = { + { + .gpio_c0 = AT91_PIN_PC17, + .gpio_c1 = AT91_PIN_PA2, + .led = { + .name = "power_red_green", + }, + }, { + .gpio_c0 = AT91_PIN_PC19, + .gpio_c1 = AT91_PIN_PC18, + .led = { + .name = "tx_greem_rx_yellow", + }, + }, +}; + +static void __init animeo_ip_add_device_led(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(leds); i++) { + at91_set_gpio_output(leds[i].gpio_c0, leds[i].active_low); + at91_set_gpio_output(leds[i].gpio_c1, leds[i].active_low); + led_gpio_bicolor_register(&leds[i]); + } + led_set_trigger(LED_TRIGGER_HEARTBEAT, &leds[0].led); +} + +static int animeo_ip_mem_init(void) +{ + at91_add_device_sdram(0); + + return 0; +} +mem_initcall(animeo_ip_mem_init); + +static void animeo_export_gpio_in(int gpio, const char *name) +{ + at91_set_gpio_input(gpio, 0); + at91_set_deglitch(gpio, 1); + export_env_ull(name, gpio); +} + +static void animeo_ip_add_device_buttons(void) +{ + animeo_export_gpio_in(AT91_PIN_PB1, "keyswitch_in"); + animeo_export_gpio_in(AT91_PIN_PB2, "error_in"); + animeo_export_gpio_in(AT91_PIN_PC22, "jumper"); + animeo_export_gpio_in(AT91_PIN_PC23, "btn"); +} + +static void animeo_export_gpio_out(int gpio, const char *name) +{ + at91_set_gpio_output(gpio, 0); + export_env_ull(name, gpio); +} + +static void animeo_ip_power_control(void) +{ + animeo_export_gpio_out(AT91_PIN_PB0, "power_radio"); + animeo_export_gpio_out(AT91_PIN_PB3, "error_out_relay"); + animeo_export_gpio_out(AT91_PIN_PC4, "power_save"); +} + +static int animeo_ip_devices_init(void) +{ + animeo_ip_detect_version(); + animeo_ip_power_control(); + animeo_ip_add_device_nand(); + at91_add_device_eth(0, &macb_pdata); + animeo_ip_add_device_mci(); + animeo_ip_add_device_buttons(); + animeo_ip_add_device_led(); + + armlinux_set_bootparams((void *)(AT91_CHIPSELECT_1 + 0x100)); + /* + * in production the machine id used is the cpu module machine id + * PICOCOM1 + */ + armlinux_set_architecture(MACH_TYPE_PICOCOM1); + + devfs_add_partition("nand0", 0x00000, SZ_32K, DEVFS_PARTITION_FIXED, "at91bootstrap_raw"); + dev_add_bb_dev("at91bootstrap_raw", "at91bootstrap"); + devfs_add_partition("nand0", SZ_32K, SZ_256K, DEVFS_PARTITION_FIXED, "self_raw"); + dev_add_bb_dev("self_raw", "self0"); + devfs_add_partition("nand0", SZ_256K + SZ_32K, SZ_32K, DEVFS_PARTITION_FIXED, "env_raw"); + dev_add_bb_dev("env_raw", "env0"); + + return 0; +} + +device_initcall(animeo_ip_devices_init); + +static int animeo_ip_console_init(void) +{ + /* + * disable the dbgu enable by the bootstrap + * so linux can detect that we only enable the uart2 + * and use it for decompress + */ +#define ATMEL_US_BRGR 0x0020 + at91_sys_write(AT91_DBGU + ATMEL_US_BRGR, 0); + at91_register_uart(3, 0); + return 0; +} +console_initcall(animeo_ip_console_init); diff --git a/arch/arm/boards/at91rm9200ek/init.c b/arch/arm/boards/at91rm9200ek/init.c index a40d3b9036..eec71bb07a 100644 --- a/arch/arm/boards/at91rm9200ek/init.c +++ b/arch/arm/boards/at91rm9200ek/init.c @@ -33,13 +33,13 @@ #include <spi/spi.h> static struct at91_ether_platform_data ether_pdata = { - .is_rmii = 1, + .phy_interface = PHY_INTERFACE_MODE_RMII, .phy_addr = 0, }; static int at91rm9200ek_mem_init(void) { - at91_add_device_sdram(64 * 1024 * 1024); + at91_add_device_sdram(0); return 0; } diff --git a/arch/arm/boards/at91sam9260ek/init.c b/arch/arm/boards/at91sam9260ek/init.c index 7bd02793b1..2d52f5a3f8 100644 --- a/arch/arm/boards/at91sam9260ek/init.c +++ b/arch/arm/boards/at91sam9260ek/init.c @@ -127,7 +127,7 @@ static void ek_add_device_nand(void) } static struct at91_ether_platform_data macb_pdata = { - .is_rmii = 1, + .phy_interface = PHY_INTERFACE_MODE_RMII, .phy_addr = 0, }; diff --git a/arch/arm/boards/at91sam9261ek/Makefile b/arch/arm/boards/at91sam9261ek/Makefile index eb072c0161..b6460c3982 100644 --- a/arch/arm/boards/at91sam9261ek/Makefile +++ b/arch/arm/boards/at91sam9261ek/Makefile @@ -1 +1,5 @@ obj-y += init.o + +obj-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += lowlevel_init.o + +pbl-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += lowlevel_init.o diff --git a/arch/arm/boards/at91sam9261ek/env/bin/init_board b/arch/arm/boards/at91sam9261ek/env/bin/init_board index a76a660aba..8e849c6a60 100644 --- a/arch/arm/boards/at91sam9261ek/env/bin/init_board +++ b/arch/arm/boards/at91sam9261ek/env/bin/init_board @@ -1,5 +1,12 @@ #!/bin/sh +splash=/env/splash.png + +if [ -f ${splash} -a -e /dev/fb0 ]; then + splash -o ${splash} + fb0.enable=1 +fi + button_name="dfu_bp" button_wait=5 diff --git a/arch/arm/boards/at91sam9261ek/env/config b/arch/arm/boards/at91sam9261ek/env/config index 7d855779ca..cb3e847f54 100644 --- a/arch/arm/boards/at91sam9261ek/env/config +++ b/arch/arm/boards/at91sam9261ek/env/config @@ -34,8 +34,14 @@ kernelimage=zImage #kernelimage=Image.lzo nand_device=atmel_nand -nand_parts="128k(at91bootstrap),256k(barebox)ro,128k(bareboxenv),128k(bareboxenv2),128k(oftree),4M(kernel),120M(rootfs),-(data)" -rootfs_mtdblock_nand=6 +if [ x$borebox_first_stage = x1 ] +then + nand_parts="384k(barebox)ro,128k(bareboxenv),128k(bareboxenv2),128k(oftree),4M(kernel),120M(rootfs),-(data)" + rootfs_mtdblock_nand=5 +else + nand_parts="128k(at91bootstrap),256k(barebox)ro,128k(bareboxenv),128k(bareboxenv2),128k(oftree),4M(kernel),120M(rootfs),-(data)" + rootfs_mtdblock_nand=6 +fi autoboot_timeout=3 diff --git a/arch/arm/boards/at91sam9261ek/init.c b/arch/arm/boards/at91sam9261ek/init.c index 7c95435c8d..177bb34273 100644 --- a/arch/arm/boards/at91sam9261ek/init.c +++ b/arch/arm/boards/at91sam9261ek/init.c @@ -30,13 +30,14 @@ #include <linux/mtd/nand.h> #include <mach/at91_pmc.h> #include <mach/board.h> -#include <mach/gpio.h> +#include <gpio.h> #include <mach/io.h> #include <mach/at91sam9_smc.h> #include <dm9000.h> #include <gpio_keys.h> #include <readkey.h> #include <led.h> +#include <spi/spi.h> static struct atmel_nand_data nand_pdata = { .ale = 22, @@ -149,6 +150,86 @@ static void ek_add_device_udc(void) static void ek_add_device_udc(void) {} #endif +/* + * LCD Controller + */ +#if defined(CONFIG_DRIVER_VIDEO_ATMEL) +static int ek_gpio_request_output(int gpio, const char *name) +{ + int ret; + + ret = gpio_request(gpio, name); + if (ret) { + pr_err("%s: can not request gpio %d (%d)\n", name, gpio, ret); + return ret; + } + + ret = gpio_direction_output(gpio, 1); + if (ret) + pr_err("%s: can not configure gpio %d as output (%d)\n", name, gpio, ret); + return ret; +} + +/* TFT */ +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "TX09D50VM1CCA @ 60", + .refresh = 60, + .xres = 240, .yres = 320, + .pixclock = KHZ2PICOS(4965), + + .left_margin = 1, .right_margin = 33, + .upper_margin = 1, .lower_margin = 0, + .hsync_len = 5, .vsync_len = 1, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +#define AT91SAM9261_DEFAULT_TFT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ + | ATMEL_LCDC_DISTYPE_TFT \ + | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) + +static void at91_lcdc_tft_power_control(int on) +{ + if (on) + gpio_set_value(AT91_PIN_PA12, 0); /* power up */ + else + gpio_set_value(AT91_PIN_PA12, 1); /* power down */ +} + +static struct atmel_lcdfb_platform_data ek_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 16, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = AT91SAM9261_DEFAULT_TFT_LCDCON2, + .guard_time = 1, + .atmel_lcdfb_power_control = at91_lcdc_tft_power_control, + .mode_list = at91_tft_vga_modes, + .num_modes = ARRAY_SIZE(at91_tft_vga_modes), +}; + +static int at91_lcdc_gpio(void) +{ + return ek_gpio_request_output(AT91_PIN_PA12, "lcdc_tft_power"); +} + +static void ek_add_device_lcdc(void) +{ + if (at91_lcdc_gpio()) + return; + + if (machine_is_at91sam9g10ek()) + ek_lcdc_data.lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB; + + at91_add_device_lcdc(&ek_lcdc_data); +} + +#else +static void ek_add_device_lcdc(void) {} +#endif + #ifdef CONFIG_KEYBOARD_GPIO struct gpio_keys_button keys[] = { { @@ -229,6 +310,46 @@ static void ek_device_add_leds(void) static void ek_device_add_leds(void) {} #endif +/* + * SPI related devices + */ +#if defined(CONFIG_DRIVER_SPI_ATMEL) +/* + * SPI devices + */ +static struct spi_board_info ek_spi_devices[] = { + { /* DataFlash chip */ + .name = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card - jumper (J12) configurable to CS3 or CS0 */ + .name = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +}; + +static unsigned spi0_standard_cs[] = { AT91_PIN_PA3, AT91_PIN_PA6}; +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 + static int at91sam9261ek_mem_init(void) { at91_add_device_sdram(0); @@ -239,15 +360,28 @@ mem_initcall(at91sam9261ek_mem_init); static int at91sam9261ek_devices_init(void) { + u32 barebox_part_start; + u32 barebox_part_size; ek_add_device_nand(); ek_add_device_dm9000(); ek_add_device_udc(); ek_add_device_buttons(); ek_device_add_leds(); - - devfs_add_partition("nand0", 0x00000, SZ_128K, DEVFS_PARTITION_FIXED, "at91bootstrap_raw"); - devfs_add_partition("nand0", SZ_128K, SZ_256K, DEVFS_PARTITION_FIXED, "self_raw"); + ek_add_device_lcdc(); + ek_add_device_spi(); + + if (IS_ENABLED(CONFIG_AT91_LOAD_BAREBOX_SRAM)) { + barebox_part_start = 0; + barebox_part_size = SZ_256K + SZ_128K; + export_env_ull("borebox_first_stage", 1); + } else { + devfs_add_partition("nand0", 0x00000, SZ_128K, DEVFS_PARTITION_FIXED, "at91bootstrap_raw"); + barebox_part_start = SZ_128K; + barebox_part_size = SZ_256K; + } + devfs_add_partition("nand0", barebox_part_start, barebox_part_size, + DEVFS_PARTITION_FIXED, "self_raw"); dev_add_bb_dev("self_raw", "self0"); devfs_add_partition("nand0", SZ_256K + SZ_128K, SZ_128K, DEVFS_PARTITION_FIXED, "env_raw"); dev_add_bb_dev("env_raw", "env0"); diff --git a/arch/arm/boards/at91sam9261ek/lowlevel_init.c b/arch/arm/boards/at91sam9261ek/lowlevel_init.c new file mode 100644 index 0000000000..056584166c --- /dev/null +++ b/arch/arm/boards/at91sam9261ek/lowlevel_init.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2009-2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <init.h> +#include <mach/hardware.h> +#include <mach/at91_rstc.h> +#include <mach/at91_wdt.h> +#include <mach/at91_pmc.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91sam9_sdramc.h> +#include <mach/at91sam9_matrix.h> +#include <mach/at91_lowlevel_init.h> + +#define MASTER_CLOCK 200 + +#if MASTER_CLOCK == 200 +#define MASTER_PLL_MUL 162 +#define MASTER_PLL_DIV 15 +#elif MASTER_CLOCK == 239 +#define MASTER_PLL_MUL 13 +#define MASTER_PLL_DIV 1 +#endif + +void __bare_init at91sam926x_lowlevel_board_config(struct at91sam926x_lowlevel_cfg *cfg) +{ + /* Disable Watchdog */ + cfg->wdt_mr = + AT91_WDT_WDIDLEHLT | AT91_WDT_WDDBGHLT | + AT91_WDT_WDV | + AT91_WDT_WDDIS | + AT91_WDT_WDD; + + /* define PDC[31:16] as DATA[31:16] */ + cfg->ebi_pio_pdr = 0xFFFF0000; + /* no pull-up for D[31:16] */ + cfg->ebi_pio_ppudr = 0xFFFF0000; + /* EBI0_CSA, CS1 SDRAM, CS3 NAND Flash, 3.3V memories */ + cfg->ebi_csa = + AT91_MATRIX_DBPUC | AT91_MATRIX_CS1A_SDRAMC; + + cfg->smc_cs = 3; + cfg->smc_mode = + AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_DBW_8 | + AT91_SMC_EXNWMODE_DISABLE | + AT91_SMC_TDF_(2); + cfg->smc_cycle = + AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5); + cfg->smc_pulse = + AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) | + AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3); + cfg->smc_setup = + AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) | + AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0); + + cfg->pmc_mor = + AT91_PMC_MOSCEN | + (255 << 8); /* Main Oscillator Start-up Time */ + cfg->pmc_pllar = + AT91_PMC_PLLA_WR_ERRATA | /* Bit 29 must be 1 when prog */ + AT91_PMC_OUT | + ((MASTER_PLL_MUL - 1) << 16) | (MASTER_PLL_DIV); + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr1 = + AT91_PMC_CSS_SLOW | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr2 = + AT91_PMC_CSS_PLLA | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + + /* SDRAM */ + /* SDRAMC_TR - Refresh Timer register */ + cfg->sdrc_tr1 = 0x13C; + /* SDRAMC_CR - Configuration register*/ + cfg->sdrc_cr = + AT91_SDRAMC_NC_9 | + AT91_SDRAMC_NR_13 | + AT91_SDRAMC_NB_4 | + AT91_SDRAMC_CAS_2 | + AT91_SDRAMC_DBW_32 | + (2 << 8) | /* Write Recovery Delay */ + (7 << 12) | /* Row Cycle Delay */ + (2 << 16) | /* Row Precharge Delay */ + (2 << 20) | /* Row to Column Delay */ + (5 << 24) | /* Active to Precharge Delay */ + (8 << 28); /* Exit Self Refresh to Active Delay */ + + /* Memory Device Register -> SDRAM */ + cfg->sdrc_mdr = AT91_SDRAMC_MD_SDRAM; + /* SDRAM_TR */ + cfg->sdrc_tr2 = (MASTER_CLOCK * 7); + + /* user reset enable */ + cfg->rstc_rmr = + AT91_RSTC_KEY | + AT91_RSTC_PROCRST | + AT91_RSTC_RSTTYP_WAKEUP | + AT91_RSTC_RSTTYP_WATCHDOG; +} diff --git a/arch/arm/boards/at91sam9263ek/Makefile b/arch/arm/boards/at91sam9263ek/Makefile index eb072c0161..b6460c3982 100644 --- a/arch/arm/boards/at91sam9263ek/Makefile +++ b/arch/arm/boards/at91sam9263ek/Makefile @@ -1 +1,5 @@ obj-y += init.o + +obj-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += lowlevel_init.o + +pbl-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += lowlevel_init.o diff --git a/arch/arm/boards/at91sam9263ek/config.h b/arch/arm/boards/at91sam9263ek/config.h index 14eb4fe241..cc12040e80 100644 --- a/arch/arm/boards/at91sam9263ek/config.h +++ b/arch/arm/boards/at91sam9263ek/config.h @@ -3,91 +3,4 @@ #define AT91_MAIN_CLOCK 16367660 /* 16.367 MHz crystal */ -#define MASTER_PLL_MUL 171 -#define MASTER_PLL_DIV 14 - -/* clocks */ -#define CONFIG_SYS_MOR_VAL \ - (AT91_PMC_MOSCEN | \ - (255 << 8)) /* Main Oscillator Start-up Time */ -#define CONFIG_SYS_PLLAR_VAL \ - (AT91_PMC_PLLA_WR_ERRATA | /* Bit 29 must be 1 when prog */ \ - AT91_PMC_OUT | \ - AT91_PMC_PLLCOUNT | /* PLL Counter */ \ - (2 << 28) | /* PLL Clock Frequency Range */ \ - ((MASTER_PLL_MUL - 1) << 16) | (MASTER_PLL_DIV)) - -/* PCK/2 = MCK Master Clock from PLLA */ -#define CONFIG_SYS_MCKR1_VAL \ - (AT91_PMC_CSS_SLOW | \ - AT91_PMC_PRES_1 | \ - AT91SAM9_PMC_MDIV_2 | \ - AT91_PMC_PDIV_1) -/* PCK/2 = MCK Master Clock from PLLA */ -#define CONFIG_SYS_MCKR2_VAL \ - (AT91_PMC_CSS_PLLA | \ - AT91_PMC_PRES_1 | \ - AT91SAM9_PMC_MDIV_2 | \ - AT91_PMC_PDIV_1) - -/* define PDC[31:16] as DATA[31:16] */ -#define CONFIG_SYS_PIOD_PDR_VAL1 0xFFFF0000 -/* no pull-up for D[31:16] */ -#define CONFIG_SYS_PIOD_PPUDR_VAL 0xFFFF0000 -/* EBI0_CSA, CS1 SDRAM, CS3 NAND Flash, 3.3V memories */ -#define CONFIG_SYS_MATRIX_EBI0CSA_VAL \ - (AT91_MATRIX_EBI0_DBPUC | AT91_MATRIX_EBI0_VDDIOMSEL_3_3V | \ - AT91_MATRIX_EBI0_CS1A_SDRAMC) - -/* SDRAM */ -/* SDRAMC_TR - Refresh Timer register */ -#define CONFIG_SYS_SDRC_TR_VAL1 0x13C -/* SDRAMC_CR - Configuration register*/ -#define CONFIG_SYS_SDRC_CR_VAL \ - (AT91_SDRAMC_NC_9 | \ - AT91_SDRAMC_NR_13 | \ - AT91_SDRAMC_NB_4 | \ - AT91_SDRAMC_CAS_3 | \ - AT91_SDRAMC_DBW_32 | \ - (1 << 8) | /* Write Recovery Delay */ \ - (7 << 12) | /* Row Cycle Delay */ \ - (2 << 16) | /* Row Precharge Delay */ \ - (2 << 20) | /* Row to Column Delay */ \ - (5 << 24) | /* Active to Precharge Delay */ \ - (1 << 28)) /* Exit Self Refresh to Active Delay */ - -/* Memory Device Register -> SDRAM */ -#define CONFIG_SYS_SDRC_MDR_VAL AT91_SDRAMC_MD_SDRAM -#define CONFIG_SYS_SDRC_TR_VAL2 1200 /* SDRAM_TR */ - -/* setup SMC0, CS0 (NOR Flash) - 16-bit, 15 WS */ -#define CONFIG_SYS_SMC_CS 0 -#define CONFIG_SYS_SMC_SETUP_VAL \ - (AT91_SMC_NWESETUP_(10) | AT91_SMC_NCS_WRSETUP_(10) | \ - AT91_SMC_NRDSETUP_(10) | AT91_SMC_NCS_RDSETUP_(10)) -#define CONFIG_SYS_SMC_PULSE_VAL \ - (AT91_SMC_NWEPULSE_(11) | AT91_SMC_NCS_WRPULSE_(11) | \ - AT91_SMC_NRDPULSE_(11) | AT91_SMC_NCS_RDPULSE_(11)) -#define CONFIG_SYS_SMC_CYCLE_VAL \ - (AT91_SMC_NWECYCLE_(22) | AT91_SMC_NRDCYCLE_(22)) -#define CONFIG_SYS_SMC_MODE_VAL \ - (AT91_SMC_READMODE | AT91_SMC_WRITEMODE | \ - AT91_SMC_DBW_16 | \ - AT91_SMC_TDFMODE | \ - AT91_SMC_TDF_(6)) - -/* user reset enable */ -#define CONFIG_SYS_RSTC_RMR_VAL \ - (AT91_RSTC_KEY | \ - AT91_RSTC_PROCRST | \ - AT91_RSTC_RSTTYP_WAKEUP | \ - AT91_RSTC_RSTTYP_WATCHDOG) - -/* Disable Watchdog */ -#define CONFIG_SYS_WDTC_WDMR_VAL \ - (AT91_WDT_WDIDLEHLT | AT91_WDT_WDDBGHLT | \ - AT91_WDT_WDV | \ - AT91_WDT_WDDIS | \ - AT91_WDT_WDD) - #endif /* __CONFIG_H */ diff --git a/arch/arm/boards/at91sam9263ek/env/bin/init_board b/arch/arm/boards/at91sam9263ek/env/bin/init_board index ae2ac7d766..f2e6294648 100644 --- a/arch/arm/boards/at91sam9263ek/env/bin/init_board +++ b/arch/arm/boards/at91sam9263ek/env/bin/init_board @@ -1,5 +1,12 @@ #!/bin/sh +splash=/env/splash.png + +if [ -f ${splash} -a -e /dev/fb0 ]; then + splash -o ${splash} + fb0.enable=1 +fi + button_name="dfu_bp" button_wait=5 diff --git a/arch/arm/boards/at91sam9263ek/init.c b/arch/arm/boards/at91sam9263ek/init.c index a86c0fd510..90fdbeca76 100644 --- a/arch/arm/boards/at91sam9263ek/init.c +++ b/arch/arm/boards/at91sam9263ek/init.c @@ -32,7 +32,7 @@ #include <linux/mtd/nand.h> #include <mach/at91_pmc.h> #include <mach/board.h> -#include <mach/gpio.h> +#include <gpio.h> #include <mach/io.h> #include <mach/at91sam9_smc.h> @@ -83,7 +83,7 @@ static void ek_add_device_nand(void) } static struct at91_ether_platform_data macb_pdata = { - .is_rmii = 1, + .phy_interface = PHY_INTERFACE_MODE_RMII, .phy_addr = 0, }; @@ -149,6 +149,75 @@ static void ek_add_device_udc(void) static void ek_add_device_udc(void) {} #endif +/* + * LCD Controller + */ +#if defined(CONFIG_DRIVER_VIDEO_ATMEL) +static int ek_gpio_request_output(int gpio, const char *name) +{ + int ret; + + ret = gpio_request(gpio, name); + if (ret) { + pr_err("%s: can not request gpio %d (%d)\n", name, gpio, ret); + return ret; + } + + ret = gpio_direction_output(gpio, 1); + if (ret) + pr_err("%s: can not configure gpio %d as output (%d)\n", name, gpio, ret); + return ret; +} + +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "TX09D50VM1CCA @ 60", + .refresh = 60, + .xres = 240, .yres = 320, + .pixclock = KHZ2PICOS(4965), + + .left_margin = 1, .right_margin = 33, + .upper_margin = 1, .lower_margin = 0, + .hsync_len = 5, .vsync_len = 1, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +#define AT91SAM9263_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ + | ATMEL_LCDC_DISTYPE_TFT \ + | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) + +static void at91_lcdc_power_control(int on) +{ + gpio_set_value(AT91_PIN_PA30, on); +} + +/* Driver datas */ +static struct atmel_lcdfb_platform_data ek_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 16, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = AT91SAM9263_DEFAULT_LCDCON2, + .guard_time = 1, + .atmel_lcdfb_power_control = at91_lcdc_power_control, + .mode_list = at91_tft_vga_modes, + .num_modes = ARRAY_SIZE(at91_tft_vga_modes), +}; + +static void ek_add_device_lcdc(void) +{ + if (ek_gpio_request_output(AT91_PIN_PA30, "lcdc_power")) + return; + + at91_add_device_lcdc(&ek_lcdc_data); +} + +#else +static void ek_add_device_lcdc(void) {} +#endif + static void __init ek_add_device_buttons(void) { at91_set_gpio_input(AT91_PIN_PC5, 1); @@ -184,6 +253,7 @@ static int at91sam9263ek_devices_init(void) ek_device_add_leds(); ek_add_device_udc(); ek_add_device_buttons(); + ek_add_device_lcdc(); if (IS_ENABLED(CONFIG_DRIVER_CFI) && cdev_by_name("nor0")) { devfs_add_partition("nor0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self"); diff --git a/arch/arm/boards/at91sam9263ek/lowlevel_init.c b/arch/arm/boards/at91sam9263ek/lowlevel_init.c new file mode 100644 index 0000000000..2f8b312d34 --- /dev/null +++ b/arch/arm/boards/at91sam9263ek/lowlevel_init.c @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2009-2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <init.h> +#include <mach/hardware.h> +#include <mach/at91_rstc.h> +#include <mach/at91_wdt.h> +#include <mach/at91_pmc.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91sam9_sdramc.h> +#include <mach/at91sam9_matrix.h> +#include <mach/at91_lowlevel_init.h> + +#define MASTER_PLL_MUL 171 +#define MASTER_PLL_DIV 14 + +void __bare_init at91sam926x_lowlevel_board_config(struct at91sam926x_lowlevel_cfg *cfg) +{ + /* Disable Watchdog */ + cfg->wdt_mr = + AT91_WDT_WDIDLEHLT | AT91_WDT_WDDBGHLT | + AT91_WDT_WDV | + AT91_WDT_WDDIS | + AT91_WDT_WDD; + + /* define PDC[31:16] as DATA[31:16] */ + cfg->ebi_pio_pdr = 0xFFFF0000; + /* no pull-up for D[31:16] */ + cfg->ebi_pio_ppudr = 0xFFFF0000; + /* EBI0_CSA, CS1 SDRAM, CS3 NAND Flash, 3.3V memories */ + cfg->ebi_csa = + AT91_MATRIX_EBI0_DBPUC | AT91_MATRIX_EBI0_VDDIOMSEL_3_3V | + AT91_MATRIX_EBI0_CS1A_SDRAMC; + + cfg->smc_cs = 0; + cfg->smc_mode = + AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_DBW_16 | + AT91_SMC_TDFMODE | + AT91_SMC_TDF_(6); + cfg->smc_cycle = + AT91_SMC_NWECYCLE_(22) | AT91_SMC_NRDCYCLE_(22); + cfg->smc_pulse = + AT91_SMC_NWEPULSE_(11) | AT91_SMC_NCS_WRPULSE_(11) | + AT91_SMC_NRDPULSE_(11) | AT91_SMC_NCS_RDPULSE_(11); + cfg->smc_setup = + AT91_SMC_NWESETUP_(10) | AT91_SMC_NCS_WRSETUP_(10) | + AT91_SMC_NRDSETUP_(10) | AT91_SMC_NCS_RDSETUP_(10); + + cfg->pmc_mor = + AT91_PMC_MOSCEN | + (255 << 8); /* Main Oscillator Start-up Time */ + cfg->pmc_pllar = + AT91_PMC_PLLA_WR_ERRATA | /* Bit 29 must be 1 when prog */ + AT91_PMC_OUT | + AT91_PMC_PLLCOUNT | /* PLL Counter */ + (2 << 28) | /* PLL Clock Frequency Range */ + ((MASTER_PLL_MUL - 1) << 16) | (MASTER_PLL_DIV); + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr1 = + AT91_PMC_CSS_SLOW | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr2 = + AT91_PMC_CSS_PLLA | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + + /* SDRAM */ + /* SDRAMC_TR - Refresh Timer register */ + cfg->sdrc_tr1 = 0x13C; + /* SDRAMC_CR - Configuration register*/ + cfg->sdrc_cr = + AT91_SDRAMC_NC_9 | + AT91_SDRAMC_NR_13 | + AT91_SDRAMC_NB_4 | + AT91_SDRAMC_CAS_3 | + AT91_SDRAMC_DBW_32 | + (1 << 8) | /* Write Recovery Delay */ + (7 << 12) | /* Row Cycle Delay */ + (2 << 16) | /* Row Precharge Delay */ + (2 << 20) | /* Row to Column Delay */ + (5 << 24) | /* Active to Precharge Delay */ + (1 << 28); /* Exit Self Refresh to Active Delay */ + + /* Memory Device Register -> SDRAM */ + cfg->sdrc_mdr = AT91_SDRAMC_MD_SDRAM; + /* SDRAM_TR */ + cfg->sdrc_tr2 = 1200; + + /* user reset enable */ + cfg->rstc_rmr = + AT91_RSTC_KEY | + AT91_RSTC_PROCRST | + AT91_RSTC_RSTTYP_WAKEUP | + AT91_RSTC_RSTTYP_WATCHDOG; +} diff --git a/arch/arm/boards/at91sam9m10g45ek/env/bin/boot_board b/arch/arm/boards/at91sam9m10g45ek/env/bin/boot_board index 3d7426f527..73daecc001 100644 --- a/arch/arm/boards/at91sam9m10g45ek/env/bin/boot_board +++ b/arch/arm/boards/at91sam9m10g45ek/env/bin/boot_board @@ -5,6 +5,13 @@ export PATH . /env/config +splash=/env/splash.png + +if [ -f ${splash} -a -e /dev/fb0 ]; then + splash -o ${splash} + fb0.enable=1 +fi + menu -r -m boot menu -a -m boot -d "\e[1;36mWelcome on Barebox Boot Sequence\e[0m" menu -e -a -m boot -c 'menu_boot' -d "boot (default) " diff --git a/arch/arm/boards/at91sam9m10g45ek/init.c b/arch/arm/boards/at91sam9m10g45ek/init.c index d77b2bfb09..5b5e31b554 100644 --- a/arch/arm/boards/at91sam9m10g45ek/init.c +++ b/arch/arm/boards/at91sam9m10g45ek/init.c @@ -106,14 +106,13 @@ static void ek_add_device_nand(void) } static struct at91_ether_platform_data macb_pdata = { - .is_rmii = 1, + .phy_interface = PHY_INTERFACE_MODE_RMII, .phy_addr = 0, }; #if defined(CONFIG_MCI_ATMEL) static struct atmel_mci_platform_data ek_mci_data = { .bus_width = 4, - .host_caps = MMC_MODE_HS, .detect_pin = AT91_PIN_PD10, }; @@ -209,21 +208,84 @@ static void ek_device_add_keyboard(void) static void ek_device_add_keyboard(void) {} #endif +#if defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) +/* + * USB HS Host port (common to OHCI & EHCI) + */ +static struct at91_usbh_data ek_usbh_hs_data = { + .ports = 2, + .vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3}, + .vbus_pin_active_low = {1, 1}, +}; + +static void ek_add_device_usb(void) +{ + at91_add_device_usbh_ohci(&ek_usbh_hs_data); + at91_add_device_usbh_ehci(&ek_usbh_hs_data); +} +#else +static void ek_add_device_usb(void) {} +#endif + static int at91sam9m10g45ek_mem_init(void) { - at91_add_device_sdram(128 * 1024 * 1024); + at91_add_device_sdram(0); return 0; } mem_initcall(at91sam9m10g45ek_mem_init); +#if defined(CONFIG_DRIVER_VIDEO_ATMEL) +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "LG", + .refresh = 60, + .xres = 480, .yres = 272, + .pixclock = KHZ2PICOS(9000), + + .left_margin = 1, .right_margin = 1, + .upper_margin = 40, .lower_margin = 1, + .hsync_len = 45, .vsync_len = 1, + + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ + | ATMEL_LCDC_DISTYPE_TFT \ + | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) + +/* Driver datas */ +static struct atmel_lcdfb_platform_data ek_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 32, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2, + .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 + + static int at91sam9m10g45ek_devices_init(void) { ek_add_device_nand(); at91_add_device_eth(0, &macb_pdata); ek_add_device_mci(); + ek_add_device_usb(); ek_device_add_leds(); ek_device_add_keyboard(); + ek_add_device_lcdc(); devfs_add_partition("nand0", 0x00000, SZ_128K, DEVFS_PARTITION_FIXED, "at91bootstrap_raw"); dev_add_bb_dev("at91bootstrap_raw", "at91bootstrap"); diff --git a/arch/arm/boards/at91sam9m10ihd/Makefile b/arch/arm/boards/at91sam9m10ihd/Makefile new file mode 100644 index 0000000000..f2acf201b4 --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/Makefile @@ -0,0 +1,2 @@ +obj-y += init.o +obj-y += hw_version.o diff --git a/arch/arm/boards/at91sam9m10ihd/config.h b/arch/arm/boards/at91sam9m10ihd/config.h new file mode 100644 index 0000000000..ac3114d865 --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/config.h @@ -0,0 +1,6 @@ +#ifndef __CONFIG_H +#define __CONFIG_H + +#define AT91_MAIN_CLOCK 12000000 /* from 12 MHz crystal */ + +#endif /* __CONFIG_H */ diff --git a/arch/arm/boards/at91sam9m10ihd/env/boot/android b/arch/arm/boards/at91sam9m10ihd/env/boot/android new file mode 100644 index 0000000000..e440f18068 --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/boot/android @@ -0,0 +1,11 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + boot-menu-add-entry "$0" "android (nand)" + exit +fi + +global.bootm.image="/dev/nand0.kernel.bb" +global.linux.bootargs.dyn.root="root=/dev/mtdblock1 rootfstype=jffs2 rw init=/init rootdelay=1" +# clean the mtdparts otherwise android does not boot +global -r linux.mtdparts. diff --git a/arch/arm/boards/at91sam9m10ihd/env/boot/mmc b/arch/arm/boards/at91sam9m10ihd/env/boot/mmc new file mode 100644 index 0000000000..89c66ee8fc --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/boot/mmc @@ -0,0 +1,19 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + boot-menu-add-entry "$0" "MMC slot" + exit +fi + +path="/mnt/mmc" + +global.bootm.image="${path}/zimage" + +oftree=${path}/oftree +if [ -f $oftree ]; then + global.bootm.oftree="$oftree" +fi + +# The rootdevice may actually be mmcblk1p2 if a card +# is inserted to the back MMC slot +global.linux.bootargs.dyn.root="root=/dev/mmcblk0p2" diff --git a/arch/arm/boards/at91sam9m10ihd/env/boot/net b/arch/arm/boards/at91sam9m10ihd/env/boot/net new file mode 100644 index 0000000000..cdb2520d39 --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/boot/net @@ -0,0 +1,16 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + boot-menu-add-entry "$0" "network (tftp, nfs) (macb)" + exit +fi + +ethact eth0 + +path="/mnt/tftp" + +global.bootm.image="${path}/${global.user}-linux-${global.hostname}" +#global.bootm.oftree="${path}/${global.user}-oftree-${global.hostname}" +nfsroot="/home/${global.user}/nfsroot/${global.hostname}" +bootargs-ip +global.linux.bootargs.dyn.root="root=/dev/nfs nfsroot=$nfsroot,v3,tcp" diff --git a/arch/arm/boards/at91sam9m10ihd/env/boot/net-usb b/arch/arm/boards/at91sam9m10ihd/env/boot/net-usb new file mode 100644 index 0000000000..6e341a0114 --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/boot/net-usb @@ -0,0 +1,22 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + boot-menu-add-entry "$0" "network (tftp, nfs) (usb ethernet)" + exit +fi + +usb -f +ethact eth1 + +if [ $? -ne 0 ]; then + echo "ERROR: usb ethernet not found" + exit 1 +fi + +path="/mnt/tftp" + +global.bootm.image="${path}/${global.user}-linux-${global.hostname}" +#global.bootm.oftree="${path}/${global.user}-oftree-${global.hostname}" +nfsroot="/home/${global.user}/nfsroot/${global.hostname}" +bootargs-ip +global.linux.bootargs.dyn.root="root=/dev/nfs nfsroot=$nfsroot,v3,tcp" diff --git a/arch/arm/boards/at91sam9m10ihd/env/config b/arch/arm/boards/at91sam9m10ihd/env/config new file mode 100644 index 0000000000..bc2119ee96 --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/config @@ -0,0 +1,21 @@ +#!/bin/sh + +# change network settings in /env/network/eth0 +# change mtd partition settings and automountpoints in /env/init/* + +#global.hostname= + +# set to false if you do not want to have colors +global.allow_color=true + +# user (used for network filenames) +global.user=none + +# timeout in seconds before the default boot entry is started +global.autoboot_timeout=3 + +# default boot entry (one of /env/boot/*) +global.boot.default=android + +# base bootargs +#global.linux.bootargs.base="console=ttyS0,115200" diff --git a/arch/arm/boards/at91sam9m10ihd/env/init/automount b/arch/arm/boards/at91sam9m10ihd/env/init/automount new file mode 100644 index 0000000000..5bb63ccb9e --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/init/automount @@ -0,0 +1,17 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + init-menu-add-entry "$0" "Automountpoints" + exit +fi + +# automount tftp server based on $eth0.serverip + +mkdir -p /mnt/tftp +automount /mnt/tftp 'ifup eth0 && mount -t tftp $eth0.serverip /mnt/tftp' + +# automount nfs server example + +# SD card slot, first partition +mkdir -p /mnt/mmc +automount -d /mnt/mmc 'mount /dev/disk0.0 /mnt/mmc' diff --git a/arch/arm/boards/at91sam9m10ihd/env/init/config-board b/arch/arm/boards/at91sam9m10ihd/env/init/config-board new file mode 100644 index 0000000000..32c107130b --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/init/config-board @@ -0,0 +1,8 @@ +#!/bin/sh + +# board defaults, do not change in running system. Change /env/config +# instead + +global.hostname=at91sam9m10ihd +global.linux.bootargs.base="console=ttyS0,115200" +global.boot.default=android diff --git a/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-001-nand b/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-001-nand new file mode 100644 index 0000000000..ac516d82d7 --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-001-nand @@ -0,0 +1,11 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + init-menu-add-entry "$0" "NAND partitions" + exit +fi + +mtdparts="128k(nand0.at91bootstrap),256k(nand0.barebox)ro,128k(nand0.bareboxenv),128k(nand0.bareboxenv2),128k(nand0.oftree),1280k(nand0.free),3M(nand0.kernel),195M(nand0.rootfs),300M(nand0.userdata),-(nand0.cache)" +kernelname="atmel_nand" + +mtdparts-add -b -d nand0 -k ${kernelname} -p ${mtdparts} diff --git a/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-002-m25p80 b/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-002-m25p80 new file mode 100644 index 0000000000..44198c820e --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/init/mtdparts-002-m25p80 @@ -0,0 +1,11 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + init-menu-add-entry "$0" "SPI NOR partitions" + exit +fi + +mtdparts="32k(m25p0.at91bootstrap)ro,256k(m25p0.barebox),128k(m25p0.bareboxenv),128k(m25p0.bareboxenv2),128k(m25p0.oftree),-(m25p0.kernel)" +kernelname="m25p0" + +mtdparts-add -d m25p0 -k ${kernelname} -p ${mtdparts} diff --git a/arch/arm/boards/at91sam9m10ihd/env/init/ps1 b/arch/arm/boards/at91sam9m10ihd/env/init/ps1 new file mode 100644 index 0000000000..a94acc14f8 --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/init/ps1 @@ -0,0 +1,9 @@ +#!/bin/sh + +/env/config + +if [ ${global.allow_color} = "true" ]; then + export PS1="\e[1;32mbarebox@\e[1;36m\h:\w\e[0m\n# " +else + export PS1="barebox@\h:\w\n# " +fi diff --git a/arch/arm/boards/at91sam9m10ihd/env/init/splash b/arch/arm/boards/at91sam9m10ihd/env/init/splash new file mode 100644 index 0000000000..18e74dfcc9 --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/env/init/splash @@ -0,0 +1,8 @@ +#!/bin/sh + +splash=/env/splash.png + +if [ -f ${splash} -a -e /dev/fb0 ]; then + splash -o ${splash} + fb0.enable=1 +fi diff --git a/arch/arm/boards/at91sam9m10ihd/hw_version.c b/arch/arm/boards/at91sam9m10ihd/hw_version.c new file mode 100644 index 0000000000..cd522f7b2c --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/hw_version.c @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2012-2013 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + */ + +#include <common.h> +#include <fs.h> +#include <fcntl.h> +#include <libbb.h> +#include <asm/armlinux.h> +#include <of.h> +#include <libfdt.h> + +#include "hw_version.h" + +enum board_type { + BOARD_TYPE_DB, + BOARD_TYPE_CPU, +}; + +static struct board_info { + char *name; + enum board_type type; + unsigned char id; +} board_list[] = { + {"SAM9M10-CM", BOARD_TYPE_CPU, 0}, + {"IHD-DB-9M10", BOARD_TYPE_DB, 1}, +}; + +static struct board_info* get_board_info_by_name(const char *name) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(board_list); i++) + if (strcmp(name, board_list[i].name) == 0) + return &board_list[i]; + + return NULL; +} + +static struct vendor_info { + char *name; + enum vendor_id id; +} vendor_list[] = { + {"ATMEL_SH", VENDOR_ATMEL}, + {"FLEX", VENDOR_FLEX}, +}; + +static struct vendor_info* get_vendor_info_by_name(const char *name) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(vendor_list); i++) + if (strcmp(name, vendor_list[i].name) == 0) + return &vendor_list[i]; + + return NULL; +} + +#define BOARD_NAME_LEN 12 +#define VENDOR_NAME_LEN 10 +#define VENDOR_COUNTRY_LEN 2 + +struct one_wire_info { + u8 total_bytes; + u8 vendor_name[VENDOR_NAME_LEN]; + u8 vendor_country[VENDOR_COUNTRY_LEN]; + u8 board_name[BOARD_NAME_LEN]; + u8 year; + u8 week; + u8 revision_code; + u8 revision_id; + u8 reserved; + u8 checksum_l; + u8 checksum_h; +}__attribute__ ((packed)); + +static int at91sam9m10ihd_read_w1(const char *file, struct one_wire_info *info) +{ + int fd; + int ret; + + fd = open(file, O_RDONLY); + if (fd < 0) { + ret = fd; + goto err; + } + + ret = read_full(fd, info, sizeof(*info)); + if (ret < 0) + goto err_open; + + if (ret < sizeof(*info)) { + ret = -EINVAL; + goto err_open; + } + + pr_debug("total_bytes = %d\n", info->total_bytes); + pr_debug("vendor_name = %s\n", info->vendor_name); + pr_debug("vendor_country = %.2s\n", info->vendor_country); + pr_debug("board_name = %s\n", info->board_name); + pr_debug("year = %d\n", info->year); + pr_debug("week = %d\n", info->week); + pr_debug("revision_code = %x\n", info->revision_code); + pr_debug("revision_id = %x\n", info->revision_id); + pr_debug("reserved = %x\n", info->reserved); + pr_debug("checksum_l = %x\n", info->checksum_l); + pr_debug("checksum_h = %x\n", info->checksum_h); + + ret = 0; + +err_open: + close(fd); +err: + if (ret) + pr_err("can not read 1-wire %s (%s)\n", file, strerror(ret)); + return ret; +} + +static u32 sn = 0; +static u32 rev = 0; + +bool at91sam9m10ihd_cm_is_vendor(enum vendor_id vid) +{ + return ((sn >> 5) & 0x1f) == vid; +} + +bool at91sam9m10ihd_db_is_vendor(enum vendor_id vid) +{ + return ((sn >> 15) & 0x1f) == vid; +} + +static void at91sam9m10ihd_devices_detect_one(const char *name) +{ + struct one_wire_info info; + struct board_info* binfo; + struct vendor_info* vinfo; + struct device_d *dev = NULL; + char str[16]; + u8 vendor_id = 0; + + if (at91sam9m10ihd_read_w1(name, &info)) + return; + + binfo = get_board_info_by_name(info.board_name); + + if (!binfo) { + pr_err("board %s no supported\n", info.board_name); + return; + } + + vinfo = get_vendor_info_by_name(info.vendor_name); + if (vinfo) + vendor_id = vinfo->id; + + switch (binfo->type) { + case BOARD_TYPE_CPU: + dev = add_generic_device_res("at91sam9m10ihd", DEVICE_ID_SINGLE, NULL, 0, NULL); + if (!dev) + return; + sn |= (binfo->id & 0x1f); + sn |= ((vendor_id & 0x1f) << 5); + rev |= (info.revision_code - 'A'); + rev |= (((info.revision_id - '0') & 0x3) << 15); + pr_info("CM"); + break; + case BOARD_TYPE_DB: + dev = add_generic_device_res("at91sam9m10ihd-db", DEVICE_ID_SINGLE, NULL, 0, NULL); + if (!dev) + return; + sn |= ((binfo->id & 0x1f) << 20); + sn |= ((vendor_id & 0x1f) << 25); + rev |= ((info.revision_code - 'A') << 10); + rev |= (((info.revision_id - '0') & 0x3) << 21); + pr_info("DB"); + break; + } + + pr_info(": %s [%c%c] from %s\n", + info.board_name, info.revision_code, info.revision_id, + info.vendor_name); + + dev_add_param_fixed(dev, "vendor", info.vendor_name); + dev_add_param_fixed(dev, "board", info.board_name); + sprintf(str, "%.2s", info.vendor_country); + dev_add_param_fixed(dev, "country", str); + sprintf(str, "%d", info.year); + dev_add_param_fixed(dev, "year", str); + sprintf(str, "%d", info.week); + dev_add_param_fixed(dev, "week", str); + sprintf(str, "%c", info.revision_code); + dev_add_param_fixed(dev, "revision_code", str); + sprintf(str, "%c", info.revision_id); + dev_add_param_fixed(dev, "revision_id", str); +} + +void at91sam9m10ihd_devices_detect_hw(void) +{ + at91sam9m10ihd_devices_detect_one("/dev/ds24310"); + at91sam9m10ihd_devices_detect_one("/dev/ds24330"); + + pr_info("sn: 0x%x, rev: 0x%x\n", sn, rev); + armlinux_set_revision(rev); + armlinux_set_serial(sn); +} diff --git a/arch/arm/boards/at91sam9m10ihd/hw_version.h b/arch/arm/boards/at91sam9m10ihd/hw_version.h new file mode 100644 index 0000000000..b9133440d3 --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/hw_version.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012-2013 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + */ + +#ifndef __HW_REVISION_H__ +#define __HW_REVISION_H__ + +enum vendor_id { + VENDOR_UNKNOWN = 0, + VENDOR_ATMEL = 1, + VENDOR_FLEX = 2, +}; + +void at91sam9m10ihd_devices_detect_hw(void); + +bool at91sam9m10ihd_cm_is_vendor(enum vendor_id vid); +bool at91sam9m10ihd_db_is_vendor(enum vendor_id vid); + +#endif /* __HW_REVISION_H__ */ diff --git a/arch/arm/boards/at91sam9m10ihd/init.c b/arch/arm/boards/at91sam9m10ihd/init.c new file mode 100644 index 0000000000..f258caf2b4 --- /dev/null +++ b/arch/arm/boards/at91sam9m10ihd/init.c @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2009-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPLv2 only + */ + +#include <common.h> +#include <net.h> +#include <mci.h> +#include <init.h> +#include <environment.h> +#include <asm/armlinux.h> +#include <generated/mach-types.h> +#include <partition.h> +#include <fs.h> +#include <fcntl.h> +#include <io.h> +#include <asm/hardware.h> +#include <nand.h> +#include <sizes.h> +#include <linux/mtd/nand.h> +#include <mach/board.h> +#include <gpio.h> +#include <mach/io.h> +#include <mach/at91sam9_smc.h> +#include <input/qt1070.h> +#include <readkey.h> +#include <linux/w1-gpio.h> +#include <w1_mac_address.h> +#include <spi/spi.h> + +#include "hw_version.h" + +struct w1_gpio_platform_data w1_pdata = { + .pin = AT91_PIN_PB25, + .ext_pullup_enable_pin = -EINVAL, + .is_open_drain = 0, +}; + +static struct atmel_nand_data nand_pdata = { + .ale = 21, + .cle = 22, + .det_pin = -EINVAL, + .rdy_pin = AT91_PIN_PC15, + .enable_pin = AT91_PIN_PC14, + .bus_width_16 = 0, + .on_flash_bbt = 1, +}; + +static struct sam9_smc_config ek_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 2, + .ncs_write_setup = 0, + .nwe_setup = 2, + + .ncs_read_pulse = 4, + .nrd_pulse = 4, + .ncs_write_pulse = 4, + .nwe_pulse = 4, + + .read_cycle = 7, + .write_cycle = 7, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, + .tdf_cycles = 3, +}; + +static void ek_add_device_nand(void) +{ + /* setup bus-width (8 or 16) */ + if (nand_pdata.bus_width_16) + ek_nand_smc_config.mode |= AT91_SMC_DBW_16; + else + ek_nand_smc_config.mode |= AT91_SMC_DBW_8; + + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(0, 3, &ek_nand_smc_config); + + at91_add_device_nand(&nand_pdata); +} + +static struct at91_ether_platform_data macb_pdata = { + .phy_interface = PHY_INTERFACE_MODE_RMII, + .phy_addr = 0, +}; + +static void ek_add_device_eth(void) +{ + if (w1_local_mac_address_register(0, "tml", "w1-2d-0")) + w1_local_mac_address_register(0, "tml", "w1-23-0"); + + at91_add_device_eth(0, &macb_pdata); +} + +#if defined(CONFIG_MCI_ATMEL) +static struct atmel_mci_platform_data ek_mci0_data = { + .bus_width = 4, + .detect_pin = AT91_PIN_PC25, +}; + +static void ek_add_device_mci(void) +{ + at91_add_device_mci(0, &ek_mci0_data); +} +#else +static void ek_add_device_mci(void) {} +#endif + +struct qt1070_platform_data qt1070_pdata = { + .irq_pin = AT91_PIN_PB19, + .code = { KEY_ENTER, KEY_ENTER, KEY_UP, KEY_DOWN, }, + .nb_code = 4, +}; + +static struct i2c_board_info i2c_devices[] = { + { + .platform_data = &qt1070_pdata, + I2C_BOARD_INFO("qt1070", 0x1b), + }, { + I2C_BOARD_INFO("24c512", 0x51) + }, +}; + +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)); +} + +static const struct spi_board_info ek_spi_devices[] = { + { + .name = "m25p80", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + } +}; + +static unsigned spi0_standard_cs[] = { AT91_PIN_PB3 }; +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); +} + +/* + * USB HS Host port (common to OHCI & EHCI) + */ +static struct at91_usbh_data ek_usbh_hs_data = { + .ports = 1, + .vbus_pin = {AT91_PIN_PC30, -EINVAL}, + .vbus_pin_active_low = {1, 0}, +}; + +static void ek_add_device_usb(void) +{ + at91_add_device_usbh_ohci(&ek_usbh_hs_data); + at91_add_device_usbh_ehci(&ek_usbh_hs_data); +} + +static int at91sam9m10g45ek_mem_init(void) +{ + at91_add_device_sdram(0); + + return 0; +} +mem_initcall(at91sam9m10g45ek_mem_init); + +#if defined(CONFIG_DRIVER_VIDEO_ATMEL) +static int ek_gpio_request_output(int gpio, const char *name) +{ + int ret; + + ret = gpio_request(gpio, name); + if (ret) { + pr_err("%s: can not request gpio %d (%d)\n", name, gpio, ret); + return ret; + } + + ret = gpio_direction_output(gpio, 1); + if (ret) + pr_err("%s: can not configure gpio %d as output (%d)\n", name, gpio, ret); + return ret; +} + +static struct fb_videomode at91fb_default_monspecs[] = { + { + .name = "MULTEK", + .refresh = 60, + .xres = 800, .yres = 480, + .pixclock = KHZ2PICOS(15000), + + .left_margin = 40, .right_margin = 40, + .upper_margin = 29, .lower_margin = 13, + .hsync_len = 48, .vsync_len = 3, + + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ + | ATMEL_LCDC_DISTYPE_TFT \ + | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) + +static void at91_lcdc_power_control(int on) +{ + gpio_set_value(AT91_PIN_PE6, on); +} + +/* Driver datas */ +static struct atmel_lcdfb_platform_data ek_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 16, + .default_dmacon = ATMEL_LCDC_DMAEN, + .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2, + .guard_time = 9, + .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, + .atmel_lcdfb_power_control = at91_lcdc_power_control, + .mode_list = at91fb_default_monspecs, + .num_modes = ARRAY_SIZE(at91fb_default_monspecs), +}; + +static void ek_add_device_lcd(void) +{ + if (ek_gpio_request_output(AT91_PIN_PE6, "lcdc_power")) + return; + + at91_add_device_lcdc(&ek_lcdc_data); +} +#else +static void ek_add_device_lcd(void) {} +#endif + +static void ek_add_device_w1(void) +{ + at91_set_gpio_input(w1_pdata.pin, 0); + at91_set_multi_drive(w1_pdata.pin, 1); + add_generic_device_res("w1-gpio", DEVICE_ID_SINGLE, NULL, 0, &w1_pdata); + + at91sam9m10ihd_devices_detect_hw(); +} + +static int at91sam9m10ihd_devices_init(void) +{ + ek_add_device_w1(); + ek_add_device_nand(); + ek_add_device_eth(); + ek_add_device_mci(); + ek_add_device_spi(); + ek_add_device_i2c(); + ek_add_device_usb(); + ek_add_device_lcd(); + + devfs_add_partition("nand0", 0x00000, SZ_128K, DEVFS_PARTITION_FIXED, "at91bootstrap_raw"); + dev_add_bb_dev("at91bootstrap_raw", "at91bootstrap"); + devfs_add_partition("nand0", SZ_128K, SZ_256K, DEVFS_PARTITION_FIXED, "self_raw"); + dev_add_bb_dev("self_raw", "self0"); + devfs_add_partition("nand0", SZ_256K + SZ_128K, SZ_128K, DEVFS_PARTITION_FIXED, "env_raw"); + dev_add_bb_dev("env_raw", "env0"); + devfs_add_partition("nand0", SZ_512K, SZ_128K, DEVFS_PARTITION_FIXED, "env_raw1"); + dev_add_bb_dev("env_raw1", "env1"); + + armlinux_set_bootparams((void *)(AT91_CHIPSELECT_6 + 0x100)); + /* + * The internal Atmel kernel use the SAM9M10G45EK machine id + * The mainline use DT + */ + armlinux_set_architecture(MACH_TYPE_AT91SAM9M10G45EK); + + return 0; +} +device_initcall(at91sam9m10ihd_devices_init); + +static int at91sam9m10ihd_console_init(void) +{ + at91_register_uart(0, 0); + return 0; +} +console_initcall(at91sam9m10ihd_console_init); diff --git a/arch/arm/boards/at91sam9n12ek/env/bin/init_board b/arch/arm/boards/at91sam9n12ek/env/bin/init_board index 977430debd..b41b63847d 100644 --- a/arch/arm/boards/at91sam9n12ek/env/bin/init_board +++ b/arch/arm/boards/at91sam9n12ek/env/bin/init_board @@ -1,5 +1,12 @@ #!/bin/sh +splash=/env/splash.png + +if [ -f ${splash} -a -e /dev/fb0 ]; then + splash -o ${splash} + fb0.enable=1 +fi + button_name="dfu_bp" button_wait=5 diff --git a/arch/arm/boards/at91sam9n12ek/init.c b/arch/arm/boards/at91sam9n12ek/init.c index 310f41898a..a1816664f1 100644 --- a/arch/arm/boards/at91sam9n12ek/init.c +++ b/arch/arm/boards/at91sam9n12ek/init.c @@ -124,6 +124,75 @@ static void __init ek_add_device_ks8851(void) static void __init ek_add_device_ks8851(void) {} #endif /* CONFIG_DRIVER_NET_KS8851_MLL */ +#if defined(CONFIG_DRIVER_VIDEO_ATMEL_HLCD) +static int ek_gpio_request_output(int gpio, const char *name) +{ + int ret; + + ret = gpio_request(gpio, name); + if (ret) { + pr_err("%s: can not request gpio %d (%d)\n", name, gpio, ret); + return ret; + } + + ret = gpio_direction_output(gpio, 1); + if (ret) + pr_err("%s: can not configure gpio %d as output (%d)\n", name, gpio, ret); + return ret; +} + + +/* + * LCD Controller + */ +static struct fb_videomode at91_tft_vga_modes[] = { + { + .name = "QD", + .refresh = 60, + .xres = 480, .yres = 272, + .pixclock = KHZ2PICOS(9000), + + .left_margin = 8, .right_margin = 43, + .upper_margin = 4, .lower_margin = 12, + .hsync_len = 5, .vsync_len = 10, + + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, +}; + +/* Default output mode is TFT 24 bit */ +#define BPP_OUT_DEFAULT_LCDCFG5 (LCDC_LCDCFG5_MODE_OUTPUT_24BPP) + +static void at91_lcdc_power_control(int on) +{ + gpio_set_value(AT91_PIN_PC25, !on); +} + +/* Driver datas */ +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, + .atmel_lcdfb_power_control = at91_lcdc_power_control, + .mode_list = at91_tft_vga_modes, + .num_modes = ARRAY_SIZE(at91_tft_vga_modes), +}; + +static void ek_add_device_lcdc(void) +{ + if (ek_gpio_request_output(AT91_PIN_PC25, "lcdc_power")) + return; + + at91_add_device_lcdc(&ek_lcdc_data); +} +#else +static void ek_add_device_lcdc(void) {} +#endif + /* * MCI (SD/MMC) */ @@ -131,7 +200,7 @@ static void __init ek_add_device_ks8851(void) {} static struct atmel_mci_platform_data mci0_data = { .bus_width = 4, .detect_pin = AT91_PIN_PA7, - .wp_pin = 0, + .wp_pin = -EINVAL, }; static void ek_add_device_mci(void) @@ -228,7 +297,7 @@ static void __init ek_add_device_buttons(void) static int at91sam9n12ek_mem_init(void) { - at91_add_device_sdram(128 * 1024 * 1024); + at91_add_device_sdram(0); return 0; } @@ -244,6 +313,7 @@ static int at91sam9n12ek_devices_init(void) ek_add_device_i2c(); ek_add_device_ks8851(); ek_add_device_buttons(); + ek_add_device_lcdc(); armlinux_set_bootparams((void *)(AT91_CHIPSELECT_1 + 0x100)); armlinux_set_architecture(CONFIG_MACH_AT91SAM9N12EK); diff --git a/arch/arm/boards/at91sam9x5ek/env/bin/init_board b/arch/arm/boards/at91sam9x5ek/env/bin/init_board new file mode 100644 index 0000000000..f3d417e356 --- /dev/null +++ b/arch/arm/boards/at91sam9x5ek/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/at91sam9x5ek/init.c b/arch/arm/boards/at91sam9x5ek/init.c index f2302054fb..4e1e069564 100644 --- a/arch/arm/boards/at91sam9x5ek/init.c +++ b/arch/arm/boards/at91sam9x5ek/init.c @@ -106,7 +106,7 @@ static void ek_add_device_nand(void) } static struct at91_ether_platform_data macb_pdata = { - .is_rmii = 1, + .phy_interface = PHY_INTERFACE_MODE_RMII, .phy_addr = 0, }; @@ -118,6 +118,49 @@ static void ek_add_device_eth(void) at91_add_device_eth(0, &macb_pdata); } +#if defined(CONFIG_DRIVER_VIDEO_ATMEL_HLCD) +/* + * LCD Controller + */ +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, + }, +}; + +/* Default output mode is TFT 24 bit */ +#define AT91SAM9X5_DEFAULT_LCDCFG5 (LCDC_LCDCFG5_MODE_OUTPUT_24BPP) + +/* Driver datas */ +static struct atmel_lcdfb_platform_data ek_lcdc_data = { + .lcdcon_is_backlight = true, + .default_bpp = 16, + .default_lcdcon2 = AT91SAM9X5_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 + /* * MCI (SD/MMC) */ @@ -125,13 +168,13 @@ static void ek_add_device_eth(void) static struct atmel_mci_platform_data mci0_data = { .bus_width = 4, .detect_pin = AT91_PIN_PD15, - .wp_pin = 0, + .wp_pin = -EINVAL, }; static void ek_add_device_mci(void) { if (at91sam9x5ek_cm_is_vendor(VENDOR_COGENT)) - mci0_data.detect_pin = 0; + mci0_data.detect_pin = -EINVAL; /* MMC0 */ at91_add_device_mci(0, &mci0_data); @@ -192,14 +235,24 @@ static void ek_add_device_spi(void) at91_add_device_spi(0, &spi_pdata); } +#if defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) /* - * USB Host port + * USB HS Host port (common to OHCI & EHCI) */ -static struct at91_usbh_data __initdata ek_usbh_data = { - .ports = 2, - .vbus_pin = {AT91_PIN_PD20, AT91_PIN_PD19}, +static struct at91_usbh_data ek_usbh_hs_data = { + .ports = 2, + .vbus_pin = {AT91_PIN_PD19, AT91_PIN_PD20}, }; +static void ek_add_device_usb(void) +{ + at91_add_device_usbh_ohci(&ek_usbh_hs_data); + at91_add_device_usbh_ehci(&ek_usbh_hs_data); +} +#else +static void ek_add_device_usb(void) {} +#endif + struct gpio_led leds[] = { { .gpio = AT91_PIN_PB18, @@ -228,7 +281,7 @@ static void __init ek_add_led(void) static int at91sam9x5ek_mem_init(void) { - at91_add_device_sdram(128 * 1024 * 1024); + at91_add_device_sdram(0); return 0; } @@ -250,9 +303,10 @@ static int at91sam9x5ek_devices_init(void) ek_add_device_eth(); ek_add_device_spi(); ek_add_device_mci(); - at91_add_device_usbh_ohci(&ek_usbh_data); + ek_add_device_usb(); ek_add_led(); ek_add_device_i2c(); + ek_add_device_lcdc(); armlinux_set_bootparams((void *)(AT91_CHIPSELECT_1 + 0x100)); armlinux_set_architecture(CONFIG_MACH_AT91SAM9X5EK); diff --git a/arch/arm/boards/beaglebone/board.c b/arch/arm/boards/beaglebone/board.c index f9ac7a469f..86de3b0f17 100644 --- a/arch/arm/boards/beaglebone/board.c +++ b/arch/arm/boards/beaglebone/board.c @@ -27,7 +27,7 @@ #include <driver.h> #include <fs.h> #include <linux/stat.h> -#include <environment.h> +#include <envfs.h> #include <sizes.h> #include <io.h> #include <ns16550.h> diff --git a/arch/arm/boards/ccxmx51/ccxmx51.c b/arch/arm/boards/ccxmx51/ccxmx51.c index b3173a424f..a9bf16a3d6 100644 --- a/arch/arm/boards/ccxmx51/ccxmx51.c +++ b/arch/arm/boards/ccxmx51/ccxmx51.c @@ -50,26 +50,26 @@ #include "ccxmx51.h" static struct ccxmx51_ident ccxmx51_ids[] = { -/* 0x00 */ { "Unknown", 0, 0, 0, 0, 0 }, -/* 0x01 */ { "Not supported", 0, 0, 0, 0, 0 }, -/* 0x02 */ { "i.MX515@800MHz, Wireless, PHY, Ext. Eth, Accel", SZ_512M, 0, 1, 1, 1 }, -/* 0x03 */ { "i.MX515@800MHz, PHY, Ext. Eth, Accel", SZ_512M, 0, 1, 1, 0 }, -/* 0x04 */ { "i.MX515@600MHz, Wireless, PHY, Ext. Eth, Accel", SZ_512M, 1, 1, 1, 1 }, -/* 0x05 */ { "i.MX515@600MHz, PHY, Ext. Eth, Accel", SZ_512M, 1, 1, 1, 0 }, -/* 0x06 */ { "i.MX515@800MHz, Wireless, PHY, Accel", SZ_512M, 0, 1, 0, 1 }, -/* 0x07 */ { "i.MX515@800MHz, PHY, Accel", SZ_512M, 0, 1, 0, 0 }, -/* 0x08 */ { "i.MX515@800MHz, Wireless, PHY, Accel", SZ_256M, 0, 1, 0, 1 }, -/* 0x09 */ { "i.MX515@800MHz, PHY, Accel", SZ_256M, 0, 1, 0, 0 }, -/* 0x0a */ { "i.MX515@600MHz, Wireless, PHY, Accel", SZ_256M, 1, 1, 0, 1 }, -/* 0x0b */ { "i.MX515@600MHz, PHY, Accel", SZ_256M, 1, 1, 0, 0 }, -/* 0x0c */ { "i.MX515@800MHz, Wireless, PHY, Accel", SZ_128M, 0, 1, 0, 1 }, -/* 0x0d */ { "i.MX512@800MHz", SZ_128M, 0, 0, 0, 0 }, -/* 0x0e */ { "i.MX515@800MHz, Wireless, PHY, Accel", SZ_512M, 0, 1, 0, 1 }, -/* 0x0f */ { "i.MX515@600MHz, PHY, Accel", SZ_128M, 1, 1, 0, 0 }, -/* 0x10 */ { "i.MX515@600MHz, Wireless, PHY, Accel", SZ_128M, 1, 1, 0, 1 }, -/* 0x11 */ { "i.MX515@800MHz, PHY, Accel", SZ_128M, 0, 1, 0, 0 }, -/* 0x12 */ { "i.MX515@600MHz, Wireless, PHY, Accel", SZ_512M, 1, 1, 0, 1 }, -/* 0x13 */ { "i.MX515@800MHz, PHY, Accel", SZ_512M, 0, 1, 0, 0 }, +/* 0x00 */ { "Unknown", 0, 0, 0, 0 }, +/* 0x01 */ { "Not supported", 0, 0, 0, 0 }, +/* 0x02 */ { "i.MX515@800MHz, Wireless, PHY, Ext. Eth, Accel", 0, 1, 1, 1 }, +/* 0x03 */ { "i.MX515@800MHz, PHY, Ext. Eth, Accel", 0, 1, 1, 0 }, +/* 0x04 */ { "i.MX515@600MHz, Wireless, PHY, Ext. Eth, Accel", 1, 1, 1, 1 }, +/* 0x05 */ { "i.MX515@600MHz, PHY, Ext. Eth, Accel", 1, 1, 1, 0 }, +/* 0x06 */ { "i.MX515@800MHz, Wireless, PHY, Accel", 0, 1, 0, 1 }, +/* 0x07 */ { "i.MX515@800MHz, PHY, Accel", 0, 1, 0, 0 }, +/* 0x08 */ { "i.MX515@800MHz, Wireless, PHY, Accel", 0, 1, 0, 1 }, +/* 0x09 */ { "i.MX515@800MHz, PHY, Accel", 0, 1, 0, 0 }, +/* 0x0a */ { "i.MX515@600MHz, Wireless, PHY, Accel", 1, 1, 0, 1 }, +/* 0x0b */ { "i.MX515@600MHz, PHY, Accel", 1, 1, 0, 0 }, +/* 0x0c */ { "i.MX515@800MHz, Wireless, PHY, Accel", 0, 1, 0, 1 }, +/* 0x0d */ { "i.MX512@800MHz", 0, 0, 0, 0 }, +/* 0x0e */ { "i.MX515@800MHz, Wireless, PHY, Accel", 0, 1, 0, 1 }, +/* 0x0f */ { "i.MX515@600MHz, PHY, Accel", 1, 1, 0, 0 }, +/* 0x10 */ { "i.MX515@600MHz, Wireless, PHY, Accel", 1, 1, 0, 1 }, +/* 0x11 */ { "i.MX515@800MHz, PHY, Accel", 0, 1, 0, 0 }, +/* 0x12 */ { "i.MX515@600MHz, Wireless, PHY, Accel", 1, 1, 0, 1 }, +/* 0x13 */ { "i.MX515@800MHz, PHY, Accel", 0, 1, 0, 0 }, }; struct ccxmx51_ident *ccxmx51_id; @@ -363,12 +363,12 @@ static int ccxmx51_power_init(void) /* De-assert reset of external devices on GP01, GPO2, GPO3 and GPO4 */ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_POWER_MISC, &val); /* GPO1 - External */ - /* GP02 - LAN9221 */ - /* GP03 - FEC */ - /* GP04 - Wireless */ - if (IS_ENABLED(CONFIG_DRIVER_NET_SMC911X) && ccxmx51_id->eth0) + /* GP02 - LAN9221 Power */ + /* GP03 - FEC Reset */ + /* GP04 - Wireless Power */ + if (IS_ENABLED(CONFIG_DRIVER_NET_SMC911X) && ccxmx51_id->eth1) val |= (1 << 8); - if (IS_ENABLED(CONFIG_DRIVER_NET_FEC_IMX) && ccxmx51_id->eth1) + if (IS_ENABLED(CONFIG_DRIVER_NET_FEC_IMX) && ccxmx51_id->eth0) val |= (1 << 10); if (ccxmx51_id->wless) val |= (1 << 12); @@ -408,8 +408,6 @@ static int ccxmx51_devices_init(void) break; } printf("Module Serial : %c%d\n", manloc, ((hwid[2] & 0x3f) << 24) | (hwid[3] << 16) | (hwid[4] << 8) | hwid[5]); - if ((ccxmx51_id->mem_sz - SZ_128M) > 0) - arm_add_mem_device("ram1", MX51_CSD0_BASE_ADDR + SZ_128M, ccxmx51_id->mem_sz - SZ_128M); } imx51_add_uart1(); @@ -435,8 +433,8 @@ static int ccxmx51_devices_init(void) #ifdef CONFIG_DRIVER_NET_FEC_IMX if (ccxmx51_id->eth0 && !pwr) { - imx51_add_fec(&fec_info); eth_register_ethaddr(0, hwid); + imx51_add_fec(&fec_info); } #endif diff --git a/arch/arm/boards/ccxmx51/ccxmx51.h b/arch/arm/boards/ccxmx51/ccxmx51.h index 3feacac034..ef40b7f0a4 100644 --- a/arch/arm/boards/ccxmx51/ccxmx51.h +++ b/arch/arm/boards/ccxmx51/ccxmx51.h @@ -23,7 +23,6 @@ struct ccxmx51_hwid { struct ccxmx51_ident { const char *id_string; - const int mem_sz; const char industrial; const char eth0; const char eth1; diff --git a/arch/arm/boards/ccxmx51/ccxmx51js.c b/arch/arm/boards/ccxmx51/ccxmx51js.c index c947a1ee97..8c1d2dcd63 100644 --- a/arch/arm/boards/ccxmx51/ccxmx51js.c +++ b/arch/arm/boards/ccxmx51/ccxmx51js.c @@ -59,6 +59,7 @@ static iomux_v3_cfg_t ccxmx51js_pads[] = { MX51_PAD_USBH1_DATA5__USBH1_DATA5, MX51_PAD_USBH1_DATA6__USBH1_DATA6, MX51_PAD_USBH1_DATA7__USBH1_DATA7, + MX51_PAD_DISPB2_SER_RS__GPIO3_8, /* Reset */ }; static struct esdhc_platform_data sdhc1_pdata = { diff --git a/arch/arm/boards/dss11/init.c b/arch/arm/boards/dss11/init.c index a2e98259c1..2920d5e80a 100644 --- a/arch/arm/boards/dss11/init.c +++ b/arch/arm/boards/dss11/init.c @@ -113,7 +113,6 @@ static void dss11_phy_reset(void) static struct atmel_mci_platform_data dss11_mci_data = { .slot_b = 1, .bus_width = 4, - .host_caps = MMC_MODE_HS, }; static struct at91_usbh_data dss11_usbh_data = { diff --git a/arch/arm/boards/efika-mx-smartbook/board.c b/arch/arm/boards/efika-mx-smartbook/board.c index a455c55b8d..5c026892cf 100644 --- a/arch/arm/boards/efika-mx-smartbook/board.c +++ b/arch/arm/boards/efika-mx-smartbook/board.c @@ -198,7 +198,7 @@ static int efikamx_mem_init(void) { arm_add_mem_device("ram0", 0x90000000, SZ_512M); - return 0; + return 0; } mem_initcall(efikamx_mem_init); @@ -220,7 +220,7 @@ static const struct spi_board_info efikamx_spi_board_info[] = { .chip_select = 1, .max_speed_hz = 20 * 1000 * 1000, .bus_num = 0, - }, + }, }; static void efikamx_power_init(void) @@ -294,11 +294,11 @@ static void efikamx_power_init(void) /* Set VDIG to 1.8V, VGEN3 to 1.8V, VCAM to 2.6V */ mc13xxx_reg_read(mc, MC13892_REG_SETTING_0, &val); val &= ~(MC13892_SETTING_0_VCAM_MASK | - MC13892_SETTING_0_VGEN3_MASK | - MC13892_SETTING_0_VDIG_MASK); + MC13892_SETTING_0_VGEN3_MASK | + MC13892_SETTING_0_VDIG_MASK); val |= MC13892_SETTING_0_VDIG_1_8 | - MC13892_SETTING_0_VGEN3_1_8 | - MC13892_SETTING_0_VCAM_2_6; + MC13892_SETTING_0_VGEN3_1_8 | + MC13892_SETTING_0_VCAM_2_6; mc13xxx_reg_write(mc, MC13892_REG_SETTING_0, val); /* Set VVIDEO to 2.775V, VAUDIO to 3V, VSD to 3.15V */ @@ -455,7 +455,7 @@ static int efikamx_devices_init(void) imx51_add_mmc1(&efikasb_sd2_data); for (i = 0; i < ARRAY_SIZE(leds); i++) - led_gpio_register(&leds[i]); + led_gpio_register(&leds[i]); imx51_add_i2c1(NULL); diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c index ae2363aa2a..98c9b435be 100644 --- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c +++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c @@ -235,10 +235,3 @@ static int eukrea_cpuimx25_console_init(void) } console_initcall(eukrea_cpuimx25_console_init); - -#ifdef CONFIG_NAND_IMX_BOOT -void __bare_init nand_boot(void) -{ - imx_nand_load_image(_text, barebox_image_size); -} -#endif diff --git a/arch/arm/boards/eukrea_cpuimx25/lowlevel.c b/arch/arm/boards/eukrea_cpuimx25/lowlevel.c index 36ce98bc69..3c1b50cba1 100644 --- a/arch/arm/boards/eukrea_cpuimx25/lowlevel.c +++ b/arch/arm/boards/eukrea_cpuimx25/lowlevel.c @@ -30,27 +30,9 @@ #include <asm-generic/memory_layout.h> #include <asm/system.h> -#ifdef CONFIG_NAND_IMX_BOOT -static void __bare_init __naked insdram(void) -{ - uint32_t r; - - /* setup a stack to be able to call imx_nand_load_image() */ - arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - - imx_nand_load_image(_text, barebox_image_size); - - board_init_lowlevel_return(); -} -#endif - void __bare_init __naked reset(void) { uint32_t r; -#ifdef CONFIG_NAND_IMX_BOOT - unsigned int *trg, *src; - int i; -#endif register uint32_t loops = 0x20000; common_reset(); @@ -146,21 +128,10 @@ void __bare_init __naked reset(void) writel(0x82216080, MX25_ESDCTL_BASE_ADDR + IMX_ESDCTL0); #ifdef CONFIG_NAND_IMX_BOOT - /* skip NAND boot if not running from NFC space */ - r = get_pc(); - if (r < MX25_NFC_BASE_ADDR || r > MX25_NFC_BASE_ADDR + 0x800) - board_init_lowlevel_return(); - - src = (unsigned int *)MX25_NFC_BASE_ADDR; - trg = (unsigned int *)_text; - - /* Move ourselves out of NFC SRAM */ - for (i = 0; i < 0x800 / sizeof(int); i++) - *trg++ = *src++; + /* setup a stack to be able to call imx25_barebox_boot_nand_external() */ + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - /* Jump to SDRAM */ - r = (unsigned int)&insdram; - __asm__ __volatile__("mov pc, %0" : : "r"(r)); + imx25_barebox_boot_nand_external(); #else board_init_lowlevel_return(); #endif diff --git a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c index 498e9b4a8e..65b6c44843 100644 --- a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c +++ b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c @@ -248,12 +248,3 @@ static int eukrea_cpuimx27_late_init(void) } late_initcall(eukrea_cpuimx27_late_init); - -#ifdef CONFIG_NAND_IMX_BOOT -void __bare_init nand_boot(void) -{ - imx_nand_load_image(_text, barebox_image_size); - board_init_lowlevel_return(); -} -#endif - diff --git a/arch/arm/boards/eukrea_cpuimx27/lowlevel_init.S b/arch/arm/boards/eukrea_cpuimx27/lowlevel_init.S index 4ee6efb84e..4e69aac2d5 100644 --- a/arch/arm/boards/eukrea_cpuimx27/lowlevel_init.S +++ b/arch/arm/boards/eukrea_cpuimx27/lowlevel_init.S @@ -126,28 +126,7 @@ reset: #ifdef CONFIG_NAND_IMX_BOOT ldr sp, =STACK_BASE + STACK_SIZE - 12 /* Setup a temporary stack in SDRAM */ - ldr r0, =MX27_NFC_BASE_ADDR /* start of NFC SRAM */ - ldr r2, =MX27_NFC_BASE_ADDR + 0x1000 /* end of NFC SRAM */ - - /* skip NAND boot if not running from NFC space */ - cmp pc, r0 - bls ret - cmp pc, r2 - bhi ret - - /* Move ourselves out of NFC SRAM */ - ldr r1, =_text - -copy_loop: - ldmia r0!, {r3-r9} /* copy from source address [r0] */ - stmia r1!, {r3-r9} /* copy to target address [r1] */ - cmp r0, r2 /* until source end address [r2] */ - ble copy_loop - - ldr pc, =1f /* Jump to SDRAM */ -1: - b nand_boot /* Load barebox from NAND Flash */ - /* to SDRAM */ + b imx27_barebox_boot_nand_external #endif /* CONFIG_NAND_IMX_BOOT */ ret: diff --git a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c index 052333503d..8f4615af41 100644 --- a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c +++ b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c @@ -35,34 +35,10 @@ #define MPCTL_PARAM_532 ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) #define PPCTL_PARAM_300 (IMX_PLL_PD(0) | IMX_PLL_MFD(3) | IMX_PLL_MFI(6) | IMX_PLL_MFN(1)) -#ifdef CONFIG_NAND_IMX_BOOT -static void __bare_init __naked insdram(void) -{ - uint32_t r; - - /* Speed up NAND controller by adjusting the NFC divider */ - r = readl(MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); - r &= ~(0xf << 28); - r |= 0x1 << 28; - writel(r, MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); - - /* setup a stack to be able to call imx_nand_load_image() */ - arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - - imx_nand_load_image(_text, barebox_image_size); - - board_init_lowlevel_return(); -} -#endif - void __bare_init __naked reset(void) { uint32_t r, s; unsigned long ccm_base = MX35_CCM_BASE_ADDR; -#ifdef CONFIG_NAND_IMX_BOOT - unsigned int *trg, *src; - int i; -#endif register uint32_t loops = 0x20000; common_reset(); @@ -155,23 +131,17 @@ void __bare_init __naked reset(void) writel(0x82228080, MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); #ifdef CONFIG_NAND_IMX_BOOT - /* skip NAND boot if not running from NFC space */ - r = get_pc(); - if (r < MX35_NFC_BASE_ADDR || r > MX35_NFC_BASE_ADDR + 0x800) - board_init_lowlevel_return(); - - src = (unsigned int *)MX35_NFC_BASE_ADDR; - trg = (unsigned int *)_text; + /* Speed up NAND controller by adjusting the NFC divider */ + r = readl(MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); + r &= ~(0xf << 28); + r |= 0x1 << 28; + writel(r, MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); - /* Move ourselves out of NFC SRAM */ - for (i = 0; i < 0x800 / sizeof(int); i++) - *trg++ = *src++; + /* setup a stack to be able to call imx35_barebox_boot_nand_external() */ + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - /* Jump to SDRAM */ - r = (unsigned int)&insdram; - __asm__ __volatile__("mov pc, %0" : : "r"(r)); + imx35_barebox_boot_nand_external(); #else board_init_lowlevel_return(); #endif } - diff --git a/arch/arm/boards/freescale-mx25-3-stack/3stack.c b/arch/arm/boards/freescale-mx25-3-stack/3stack.c index 1271ad95ca..4d048beb1b 100644 --- a/arch/arm/boards/freescale-mx25-3-stack/3stack.c +++ b/arch/arm/boards/freescale-mx25-3-stack/3stack.c @@ -274,14 +274,6 @@ static int imx25_console_init(void) console_initcall(imx25_console_init); -#ifdef CONFIG_NAND_IMX_BOOT -void __bare_init nand_boot(void) -{ - imx_nand_load_image(_text, barebox_image_size); - board_init_lowlevel_return(); -} -#endif - static int imx25_core_setup(void) { writel(0x01010103, MX25_CCM_BASE_ADDR + MX25_CCM_PCDR2); @@ -289,4 +281,3 @@ static int imx25_core_setup(void) } core_initcall(imx25_core_setup); - diff --git a/arch/arm/boards/freescale-mx25-3-stack/lowlevel_init.S b/arch/arm/boards/freescale-mx25-3-stack/lowlevel_init.S index fb980991a6..595c485128 100644 --- a/arch/arm/boards/freescale-mx25-3-stack/lowlevel_init.S +++ b/arch/arm/boards/freescale-mx25-3-stack/lowlevel_init.S @@ -100,28 +100,7 @@ reset: #ifdef CONFIG_NAND_IMX_BOOT ldr sp, =STACK_BASE + STACK_SIZE - 12 /* Setup a temporary stack in SDRAM */ - ldr r0, =MX25_NFC_BASE_ADDR /* start of NFC SRAM */ - ldr r2, =MX25_NFC_BASE_ADDR + 0x1000 /* end of NFC SRAM */ - - /* skip NAND boot if not running from NFC space */ - cmp pc, r0 - bls ret - cmp pc, r2 - bhi ret - - /* Move ourselves out of NFC SRAM */ - ldr r1, =_text - -copy_loop: - ldmia r0!, {r3-r9} /* copy from source address [r0] */ - stmia r1!, {r3-r9} /* copy to target address [r1] */ - cmp r0, r2 /* until source end address [r2] */ - ble copy_loop - - ldr pc, =1f /* Jump to SDRAM */ -1: - b nand_boot /* Load barebox from NAND Flash */ - + b imx25_barebox_boot_nand_external #endif /* CONFIG_NAND_IMX_BOOT */ ret: diff --git a/arch/arm/boards/freescale-mx35-3-stack/3stack.c b/arch/arm/boards/freescale-mx35-3-stack/3stack.c index 3128d4fb1a..02844c5987 100644 --- a/arch/arm/boards/freescale-mx35-3-stack/3stack.c +++ b/arch/arm/boards/freescale-mx35-3-stack/3stack.c @@ -427,15 +427,3 @@ static int f3s_pmic_init(void) } late_initcall(f3s_pmic_init); - -#ifdef CONFIG_NAND_IMX_BOOT -void __bare_init nand_boot(void) -{ - /* - * The driver is able to detect NAND's pagesize by CPU internal - * fuses or external pull ups. But not the blocksize... - */ - imx_nand_load_image(_text, barebox_image_size); - board_init_lowlevel_return(); -} -#endif diff --git a/arch/arm/boards/freescale-mx35-3-stack/lowlevel_init.S b/arch/arm/boards/freescale-mx35-3-stack/lowlevel_init.S index dada5f3fd5..5461b61fcb 100644 --- a/arch/arm/boards/freescale-mx35-3-stack/lowlevel_init.S +++ b/arch/arm/boards/freescale-mx35-3-stack/lowlevel_init.S @@ -157,28 +157,7 @@ reset: #ifdef CONFIG_NAND_IMX_BOOT ldr sp, =STACK_BASE + STACK_SIZE - 12 /* Setup a temporary stack in SDRAM */ - ldr r0, =MX35_NFC_BASE_ADDR /* start of NFC SRAM */ - ldr r2, =MX35_NFC_BASE_ADDR + 0x800 /* end of NFC SRAM */ - - /* skip NAND boot if not running from NFC space */ - cmp pc, r0 - blo ret - cmp pc, r2 - bhs ret - - /* Move ourselves out of NFC SRAM */ - ldr r1, =_text - -copy_loop: - ldmia r0!, {r3-r9} /* copy from source address [r0] */ - stmia r1!, {r3-r9} /* copy to target address [r1] */ - cmp r0, r2 /* until source end address [r2] */ - ble copy_loop - - ldr pc, =1f /* Jump to SDRAM */ -1: - b nand_boot /* Load barebox from NAND Flash */ -ret: + b imx35_barebox_boot_nand_external #endif /* CONFIG_NAND_IMX_BOOT */ b board_init_lowlevel_return diff --git a/arch/arm/boards/freescale-mx6-sabrelite/board.c b/arch/arm/boards/freescale-mx6-sabrelite/board.c index 55087c2bc8..2a1278635e 100644 --- a/arch/arm/boards/freescale-mx6-sabrelite/board.c +++ b/arch/arm/boards/freescale-mx6-sabrelite/board.c @@ -231,8 +231,8 @@ static struct esdhc_platform_data sabrelite_sd4_data = { static void sabrelite_ehci_init(void) { - imx6_usb_phy1_disable_oc(); - imx6_usb_phy1_enable(); + imx6_usb_phy2_disable_oc(); + imx6_usb_phy2_enable(); /* hub reset */ gpio_direction_output(204, 0); diff --git a/arch/arm/boards/guf-cupid/lowlevel.c b/arch/arm/boards/guf-cupid/lowlevel.c index 3de0346b98..f2994eb20d 100644 --- a/arch/arm/boards/guf-cupid/lowlevel.c +++ b/arch/arm/boards/guf-cupid/lowlevel.c @@ -42,26 +42,6 @@ #define SDRAM_COMPARE_CONST1 0x55555555 #define SDRAM_COMPARE_CONST2 0xaaaaaaaa -#ifdef CONFIG_NAND_IMX_BOOT -static void __bare_init __naked insdram(void) -{ - uint32_t r; - - /* Speed up NAND controller by adjusting the NFC divider */ - r = readl(MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); - r &= ~(0xf << 28); - r |= 0x1 << 28; - writel(r, MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); - - /* setup a stack to be able to call imx_nand_load_image() */ - arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - - imx_nand_load_image(_text, barebox_image_size); - - board_init_lowlevel_return(); -} -#endif - static void __bare_init noinline setup_sdram(u32 memsize, u32 mode, u32 sdram_addr) { volatile int loop; @@ -188,9 +168,6 @@ void __bare_init __naked reset(void) u32 r0, r1; void *iomuxc_base = (void *)MX35_IOMUXC_BASE_ADDR; int i; -#ifdef CONFIG_NAND_IMX_BOOT - unsigned int *trg, *src; -#endif common_reset(); @@ -330,23 +307,17 @@ void __bare_init __naked reset(void) setup_sdram(r0, ESDMISC_MDDR_EN, 0x80000f00); #ifdef CONFIG_NAND_IMX_BOOT - /* skip NAND boot if not running from NFC space */ - r0 = get_pc(); - if (r0 < MX35_NFC_BASE_ADDR || r0 > MX35_NFC_BASE_ADDR + 0x800) - board_init_lowlevel_return(); - - src = (unsigned int *)MX35_NFC_BASE_ADDR; - trg = (unsigned int *)_text; + /* Speed up NAND controller by adjusting the NFC divider */ + r0 = readl(MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); + r0 &= ~(0xf << 28); + r0 |= 0x1 << 28; + writel(r0, MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); - /* Move ourselves out of NFC SRAM */ - for (i = 0; i < 0x800 / sizeof(int); i++) - *trg++ = *src++; + /* setup a stack to be able to call imx35_barebox_boot_nand_external() */ + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - /* Jump to SDRAM */ - r0 = (unsigned int)&insdram; - __asm__ __volatile__("mov pc, %0" : : "r"(r0)); + imx35_barebox_boot_nand_external(); #else board_init_lowlevel_return(); #endif } - diff --git a/arch/arm/boards/guf-neso/lowlevel.c b/arch/arm/boards/guf-neso/lowlevel.c index ad414d9208..7a366d908c 100644 --- a/arch/arm/boards/guf-neso/lowlevel.c +++ b/arch/arm/boards/guf-neso/lowlevel.c @@ -30,27 +30,12 @@ #include <asm-generic/sections.h> #include <asm-generic/memory_layout.h> -#ifdef CONFIG_NAND_IMX_BOOT -static void __bare_init __naked insdram(void) -{ - /* setup a stack to be able to call imx_nand_load_image() */ - arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - - imx_nand_load_image(_text, barebox_image_size); - - board_init_lowlevel_return(); -} -#endif - #define ESDCTL0_VAL (ESDCTL0_SDE | ESDCTL0_ROW13 | ESDCTL0_COL10) void __bare_init __naked reset(void) { uint32_t r; int i; -#ifdef CONFIG_NAND_IMX_BOOT - unsigned int *trg, *src; -#endif common_reset(); @@ -102,23 +87,11 @@ void __bare_init __naked reset(void) MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0); #ifdef CONFIG_NAND_IMX_BOOT - /* skip NAND boot if not running from NFC space */ - r = get_pc(); - if (r < MX27_NFC_BASE_ADDR || r > MX27_NFC_BASE_ADDR + 0x800) - board_init_lowlevel_return(); - - src = (unsigned int *)MX27_NFC_BASE_ADDR; - trg = (unsigned int *)_text; - - /* Move ourselves out of NFC SRAM */ - for (i = 0; i < 0x800 / sizeof(int); i++) - *trg++ = *src++; + /* setup a stack to be able to call imx27_barebox_boot_nand_external() */ + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - /* Jump to SDRAM */ - r = (unsigned int)&insdram; - __asm__ __volatile__("mov pc, %0" : : "r"(r)); + imx27_barebox_boot_nand_external(); #else board_init_lowlevel_return(); #endif } - diff --git a/arch/arm/boards/guf-vincell/env/init/bootargs-base b/arch/arm/boards/guf-vincell/env/init/bootargs-base deleted file mode 100644 index d86975406e..0000000000 --- a/arch/arm/boards/guf-vincell/env/init/bootargs-base +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "Base bootargs" - exit -fi - -global.linux.bootargs.base="console=ttymxc0,115200" diff --git a/arch/arm/boards/guf-vincell/env/init/config-board b/arch/arm/boards/guf-vincell/env/init/config-board new file mode 100644 index 0000000000..77e9fc8b4d --- /dev/null +++ b/arch/arm/boards/guf-vincell/env/init/config-board @@ -0,0 +1,7 @@ +#!/bin/sh + +# board defaults, do not change in running system. Change /env/config +# instead + +global.hostname=vincell +global.linux.bootargs.base="console=ttymxc0,115200" diff --git a/arch/arm/boards/guf-vincell/env/init/hostname b/arch/arm/boards/guf-vincell/env/init/hostname deleted file mode 100644 index ca2789ddf4..0000000000 --- a/arch/arm/boards/guf-vincell/env/init/hostname +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "hostname" - exit -fi - -global.hostname=vincell diff --git a/arch/arm/boards/imx21ads/imx21ads.c b/arch/arm/boards/imx21ads/imx21ads.c index ca566c831a..3d07633f59 100644 --- a/arch/arm/boards/imx21ads/imx21ads.c +++ b/arch/arm/boards/imx21ads/imx21ads.c @@ -189,12 +189,3 @@ static int mx21ads_console_init(void) } console_initcall(mx21ads_console_init); - -#ifdef CONFIG_NAND_IMX_BOOT -void __bare_init nand_boot(void) -{ - imx_nand_load_image(_text, barebox_image_size); - board_init_lowlevel_return(); -} -#endif - diff --git a/arch/arm/boards/imx21ads/lowlevel_init.S b/arch/arm/boards/imx21ads/lowlevel_init.S index e52cac1443..f06c964dd6 100644 --- a/arch/arm/boards/imx21ads/lowlevel_init.S +++ b/arch/arm/boards/imx21ads/lowlevel_init.S @@ -120,28 +120,7 @@ reset: #ifdef CONFIG_NAND_IMX_BOOT ldr sp, =STACK_BASE + STACK_SIZE - 12 /* Setup a temporary stack in SDRAM */ - ldr r0, =MX21_NFC_BASE_ADDR /* start of NFC SRAM */ - ldr r2, =MX21_NFC_BASE_ADDR + 0x800 /* end of NFC SRAM */ - - /* skip NAND boot if not running from NFC space */ - cmp pc, r0 - bls ret - cmp pc, r2 - bhi ret - - /* Move ourselves out of NFC SRAM */ - ldr r1, =_text - -copy_loop: - ldmia r0!, {r3-r9} /* copy from source address [r0] */ - stmia r1!, {r3-r9} /* copy to target address [r1] */ - cmp r0, r2 /* until source end address [r2] */ - ble copy_loop - - ldr pc, =1f /* Jump to SDRAM */ -1: - b nand_boot /* Load barebox from NAND Flash */ - /* SRAM to SDRAM */ + b imx21_barebox_boot_nand_external #endif /* CONFIG_NAND_IMX_BOOT */ ret: diff --git a/arch/arm/boards/karo-tx25/board.c b/arch/arm/boards/karo-tx25/board.c index 98140b33cc..e581886911 100644 --- a/arch/arm/boards/karo-tx25/board.c +++ b/arch/arm/boards/karo-tx25/board.c @@ -20,6 +20,7 @@ #include <common.h> #include <init.h> #include <driver.h> +#include <sizes.h> #include <environment.h> #include <mach/imx25-regs.h> #include <asm/armlinux.h> @@ -102,10 +103,10 @@ static int tx25_devices_init(void) imx25_add_nand(&nand_info); - devfs_add_partition("nand0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self_raw"); + devfs_add_partition("nand0", 0x00000, SZ_512K, DEVFS_PARTITION_FIXED, "self_raw"); dev_add_bb_dev("self_raw", "self0"); - devfs_add_partition("nand0", 0x40000, 0x80000, DEVFS_PARTITION_FIXED, "env_raw"); + devfs_add_partition("nand0", SZ_512K, SZ_512K, DEVFS_PARTITION_FIXED, "env_raw"); dev_add_bb_dev("env_raw", "env0"); add_mem_device("sram0", 0x78000000, 128 * 1024, @@ -154,13 +155,6 @@ static int tx25_console_init(void) console_initcall(tx25_console_init); -#ifdef CONFIG_NAND_IMX_BOOT -void __bare_init nand_boot(void) -{ - imx_nand_load_image(_text, barebox_image_size); -} -#endif - static iomux_v3_cfg_t tx25_lcdc_gpios[] = { MX25_PAD_A18__GPIO_2_4, /* LCD Reset (active LOW) */ MX25_PAD_PWM__GPIO_1_26, /* LCD Backlight brightness 0: full 1: off */ diff --git a/arch/arm/boards/karo-tx25/env/bin/init_board b/arch/arm/boards/karo-tx25/env/bin/init_board deleted file mode 100644 index 1f35c961dc..0000000000 --- a/arch/arm/boards/karo-tx25/env/bin/init_board +++ /dev/null @@ -1,6 +0,0 @@ - -if [ -e /dev/fb0 -a -e /env/splash.bmp ]; then - splash /env/splash.bmp - fb0.enable=1 -fi - diff --git a/arch/arm/boards/karo-tx25/env/boot/nand-ubi b/arch/arm/boards/karo-tx25/env/boot/nand-ubi new file mode 100644 index 0000000000..67b0cb4afe --- /dev/null +++ b/arch/arm/boards/karo-tx25/env/boot/nand-ubi @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + boot-menu-add-entry "$0" "nand (UBI)" + exit +fi + +global.bootm.image="/dev/nand0.kernel.bb" +#global.bootm.oftree="/env/oftree" +global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=nand0.root rootfstype=ubifs" diff --git a/arch/arm/boards/karo-tx25/env/config b/arch/arm/boards/karo-tx25/env/config deleted file mode 100644 index 87beb6d64b..0000000000 --- a/arch/arm/boards/karo-tx25/env/config +++ /dev/null @@ -1,48 +0,0 @@ - -global.hostname=tx25 -baseboard=tx28stk5 -user= - -# 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.ethaddr=de:ad:be:ef:00:00 -#eth0.netmask=a.b.c.d -#eth0.serverip=a.b.c.d -#eth0.gateway=a.b.c.d - -# can be either 'nfs' or 'tftp' -kernel_loc=tftp -# can be either 'net' or 'initrd' -rootfs_loc=net - -# can be either 'jffs2' or 'ubifs' -rootfs_type=ubifs -rootfsimage=root-${global.hostname}.$rootfs_type - -kernelimage=zImage-${global.hostname} -#kernelimage=uImage-${global.hostname} -#kernelimage=Image-${global.hostname} -#kernelimage=Image-${global.hostname}.lzo - -if [ -n $user ]; then - kernelimage="$user"-"$kernelimage" - nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}" - rootfsimage="$user"-"$rootfsimage" -else - nfsroot="$eth0.serverip:/path/to/nfs/root" -fi - -autoboot_timeout=3 - -bootargs="console=ttymxc0,115200 tx25_base=$baseboard" - -nand_parts="256k(barebox)ro,512k(bareboxenv),2M(kernel),-(root)" -nand_device=mxc_nand -rootfs_mtdblock_nand=3 - -PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m " - diff --git a/arch/arm/boards/karo-tx25/env/init/config-board b/arch/arm/boards/karo-tx25/env/init/config-board new file mode 100644 index 0000000000..943b002d5f --- /dev/null +++ b/arch/arm/boards/karo-tx25/env/init/config-board @@ -0,0 +1,7 @@ +#!/bin/sh + +# board defaults, do not change in running system. Change /env/config +# instead + +global.hostname=tx25 +global.linux.bootargs.base="console=ttymxc0,115200" diff --git a/arch/arm/boards/karo-tx25/env/init/mtdparts-nand b/arch/arm/boards/karo-tx25/env/init/mtdparts-nand new file mode 100644 index 0000000000..4fffefca8b --- /dev/null +++ b/arch/arm/boards/karo-tx25/env/init/mtdparts-nand @@ -0,0 +1,11 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + init-menu-add-entry "$0" "NAND partitions" + exit +fi + +mtdparts="512k(nand0.barebox)ro,512k(nand0.bareboxenv),4M(nand0.kernel),-(nand0.root)" +kernelname="mxc_nand" + +mtdparts-add -b -d nand0 -k ${kernelname} -p ${mtdparts} diff --git a/arch/arm/boards/karo-tx25/lowlevel.c b/arch/arm/boards/karo-tx25/lowlevel.c index 9c5cc5c8ee..b1afe1872d 100644 --- a/arch/arm/boards/karo-tx25/lowlevel.c +++ b/arch/arm/boards/karo-tx25/lowlevel.c @@ -28,20 +28,6 @@ #include <asm-generic/sections.h> #include <asm-generic/memory_layout.h> -#ifdef CONFIG_NAND_IMX_BOOT -static void __bare_init __naked insdram(void) -{ - uint32_t r; - - /* setup a stack to be able to call imx_nand_load_image() */ - arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - - imx_nand_load_image(_text, barebox_image_size); - - board_init_lowlevel_return(); -} -#endif - static inline void __bare_init setup_sdram(uint32_t base, uint32_t esdctl, uint32_t esdcfg) { @@ -69,9 +55,6 @@ static inline void __bare_init setup_sdram(uint32_t base, uint32_t esdctl, void __bare_init __naked reset(void) { uint32_t r; -#ifdef CONFIG_NAND_IMX_BOOT - unsigned int *trg, *src; -#endif common_reset(); @@ -130,7 +113,7 @@ void __bare_init __naked reset(void) /* Skip SDRAM initialization if we run from RAM */ r = get_pc(); - if (r > 0x80000000 && r < 0x90000000) + if (r > 0x80000000 && r < 0xa0000000) board_init_lowlevel_return(); /* set to 3.3v SDRAM */ @@ -150,21 +133,10 @@ void __bare_init __naked reset(void) setup_sdram(0x90000000, ESDCTLVAL, ESDCFGVAL); #ifdef CONFIG_NAND_IMX_BOOT - /* skip NAND boot if not running from NFC space */ - r = get_pc(); - if (r < MX25_NFC_BASE_ADDR || r > MX25_NFC_BASE_ADDR + 0x800) - board_init_lowlevel_return(); - - src = (unsigned int *)MX25_NFC_BASE_ADDR; - trg = (unsigned int *)_text; - - /* Move ourselves out of NFC SRAM */ - for (i = 0; i < 0x800 / sizeof(int); i++) - *trg++ = *src++; + /* setup a stack to be able to call imx25_barebox_boot_nand_external() */ + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - /* Jump to SDRAM */ - r = (unsigned int)&insdram; - __asm__ __volatile__("mov pc, %0" : : "r"(r)); + imx25_barebox_boot_nand_external(); #else board_init_lowlevel_return(); #endif diff --git a/arch/arm/boards/mmccpu/Makefile b/arch/arm/boards/mmccpu/Makefile index eb072c0161..b6460c3982 100644 --- a/arch/arm/boards/mmccpu/Makefile +++ b/arch/arm/boards/mmccpu/Makefile @@ -1 +1,5 @@ obj-y += init.o + +obj-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += lowlevel_init.o + +pbl-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += lowlevel_init.o diff --git a/arch/arm/boards/mmccpu/config.h b/arch/arm/boards/mmccpu/config.h index e6215dc460..c896a93b40 100644 --- a/arch/arm/boards/mmccpu/config.h +++ b/arch/arm/boards/mmccpu/config.h @@ -3,122 +3,4 @@ #define AT91_MAIN_CLOCK 18432000 -/* values */ -#define MASTER_PLL_MUL 54 -#define MASTER_PLL_DIV 4 - -/* clocks */ -#define CONFIG_SYS_MOR_VAL \ - (AT91_PMC_MOSCEN | \ - (255 << 8)) /* Main Oscillator Start-up Time */ -#define CONFIG_SYS_PLLAR_VAL \ - (AT91_PMC_PLLA_WR_ERRATA | /* Bit 29 must be 1 when prog */ \ - AT91_PMC_OUT | \ - AT91_PMC_PLLCOUNT | /* PLL Counter */ \ - (2 << 28) | /* PLL Clock Frequency Range */ \ - ((MASTER_PLL_MUL - 1) << 16) | (MASTER_PLL_DIV)) - -/* PCK/2 = MCK Master Clock from PLLA */ -#define CONFIG_SYS_MCKR1_VAL \ - (AT91_PMC_CSS_SLOW | \ - AT91_PMC_PRES_1 | \ - AT91SAM9_PMC_MDIV_2 | \ - AT91_PMC_PDIV_1) -/* PCK/2 = MCK Master Clock from PLLA */ -#define CONFIG_SYS_MCKR2_VAL \ - (AT91_PMC_CSS_PLLA | \ - AT91_PMC_PRES_1 | \ - AT91SAM9_PMC_MDIV_2 | \ - AT91_PMC_PDIV_1) - -/* define PDC[31:16] as DATA[31:16] */ -#define CONFIG_SYS_PIOD_PDR_VAL1 0xFFFF0000 -/* no pull-up for D[31:16] */ -#define CONFIG_SYS_PIOD_PPUDR_VAL 0xFFFF0000 -/* EBI0_CSA, CS1 SDRAM, CS3 NAND Flash, 1.8V memories */ -#define CONFIG_SYS_MATRIX_EBI0CSA_VAL \ - (AT91_MATRIX_EBI0_DBPUC | AT91_MATRIX_EBI0_VDDIOMSEL_1_8V | \ - AT91_MATRIX_EBI0_CS1A_SDRAMC | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA) - -/* SDRAM */ -/* SDRAMC_TR - Refresh Timer register */ -#define CONFIG_SYS_SDRC_TR_VAL1 0x13c -/* SDRAMC_CR - Configuration register*/ -#define CONFIG_SYS_SDRC_CR_VAL \ - (AT91_SDRAMC_NC_9 | \ - AT91_SDRAMC_NR_13 | \ - AT91_SDRAMC_NB_4 | \ - AT91_SDRAMC_CAS_3 | \ - AT91_SDRAMC_DBW_32 | \ - (2 << 8) | /* tWR - Write Recovery Delay */ \ - (8 << 12) | /* tRC - Row Cycle Delay */ \ - (2 << 16) | /* tRP - Row Precharge Delay */ \ - (2 << 20) | /* tRCD - Row to Column Delay */ \ - (5 << 24) | /* tRAS - Active to Precharge Delay */ \ - (12 << 28)) /* tXSR - Exit Self Refresh to Active Delay */ - -/* Memory Device Register -> SDRAM */ -#define CONFIG_SYS_SDRC_MDR_VAL AT91_SDRAMC_MD_SDRAM -#define CONFIG_SYS_SDRC_TR_VAL2 780 /* SDRAM_TR */ - -/* setup CS0 (NOR Flash) - 16-bit */ -#define CONFIG_SYS_SMC_CS 0 -#if 1 -#define CONFIG_SYS_SMC_SETUP_VAL \ - (AT91_SMC_NWESETUP_(3) | AT91_SMC_NCS_WRSETUP_(2) | \ - AT91_SMC_NRDSETUP_(8) | AT91_SMC_NCS_RDSETUP_(0)) -#define CONFIG_SYS_SMC_PULSE_VAL \ - (AT91_SMC_NWEPULSE_(5) | AT91_SMC_NCS_WRPULSE_(7) | \ - AT91_SMC_NRDPULSE_(5) | AT91_SMC_NCS_RDPULSE_(13)) -#define CONFIG_SYS_SMC_CYCLE_VAL \ - (AT91_SMC_NWECYCLE_(16) | AT91_SMC_NRDCYCLE_(16)) -#define CONFIG_SYS_SMC_MODE_VAL \ - (AT91_SMC_READMODE | AT91_SMC_WRITEMODE | \ - AT91_SMC_DBW_16 | \ - AT91_SMC_TDFMODE | \ - AT91_SMC_TDF_(6)) -#elif 0 /* slow setup */ -#define CONFIG_SYS_SMC_SETUP_VAL \ - (AT91_SMC_NWESETUP_(3) | AT91_SMC_NCS_WRSETUP_(2) | \ - AT91_SMC_NRDSETUP_(8) | AT91_SMC_NCS_RDSETUP_(0)) -#define CONFIG_SYS_SMC_PULSE_VAL \ - (AT91_SMC_NWEPULSE_(5) | AT91_SMC_NCS_WRPULSE_(7) | \ - AT91_SMC_NRDPULSE_(5) | AT91_SMC_NCS_RDPULSE_(13)) -#define CONFIG_SYS_SMC_CYCLE_VAL \ - (AT91_SMC_NWECYCLE_(0xd00) | AT91_SMC_NRDCYCLE_(0xd00)) -#define CONFIG_SYS_SMC_MODE_VAL \ - (AT91_SMC_READMODE | AT91_SMC_WRITEMODE | \ - AT91_SMC_DBW_16 | \ - AT91_SMC_TDFMODE | \ - AT91_SMC_TDF_(1)) -#else /* RONETIX' original values */ -#define CONFIG_SYS_SMC_SETUP_VAL \ - (AT91_SMC_NWESETUP_(10) | AT91_SMC_NCS_WRSETUP_(10) | \ - AT91_SMC_NRDSETUP_(10) | AT91_SMC_NCS_RDSETUP_(10)) -#define CONFIG_SYS_SMC_PULSE_VAL \ - (AT91_SMC_NWEPULSE_(11) | AT91_SMC_NCS_WRPULSE_(11) | \ - AT91_SMC_NRDPULSE_(11) | AT91_SMC_NCS_RDPULSE_(11)) -#define CONFIG_SYS_SMC_CYCLE_VAL \ - (AT91_SMC_NWECYCLE_(22) | AT91_SMC_NRDCYCLE_(22)) -#define CONFIG_SYS_SMC_MODE_VAL \ - (AT91_SMC_READMODE | AT91_SMC_WRITEMODE | \ - AT91_SMC_DBW_16 | \ - AT91_SMC_TDFMODE | \ - AT91_SMC_TDF_(6)) -#endif - -/* user reset enable */ -#define CONFIG_SYS_RSTC_RMR_VAL \ - (AT91_RSTC_KEY | \ - AT91_RSTC_PROCRST | \ - AT91_RSTC_RSTTYP_WAKEUP | \ - AT91_RSTC_RSTTYP_WATCHDOG) - -/* Disable Watchdog */ -#define CONFIG_SYS_WDTC_WDMR_VAL \ - (AT91_WDT_WDIDLEHLT | AT91_WDT_WDDBGHLT | \ - AT91_WDT_WDV | \ - AT91_WDT_WDDIS | \ - AT91_WDT_WDD) - #endif /* __CONFIG_H */ diff --git a/arch/arm/boards/mmccpu/lowlevel_init.c b/arch/arm/boards/mmccpu/lowlevel_init.c new file mode 100644 index 0000000000..c193eae58e --- /dev/null +++ b/arch/arm/boards/mmccpu/lowlevel_init.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2009-2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <init.h> +#include <mach/hardware.h> +#include <mach/at91_rstc.h> +#include <mach/at91_wdt.h> +#include <mach/at91_pmc.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91sam9_sdramc.h> +#include <mach/at91sam9_matrix.h> +#include <mach/at91_lowlevel_init.h> + +#define MASTER_PLL_MUL 54 +#define MASTER_PLL_DIV 4 + +void __bare_init at91sam926x_lowlevel_board_config(struct at91sam926x_lowlevel_cfg *cfg) +{ + /* Disable Watchdog */ + cfg->wdt_mr = + AT91_WDT_WDIDLEHLT | AT91_WDT_WDDBGHLT | + AT91_WDT_WDV | + AT91_WDT_WDDIS | + AT91_WDT_WDD; + + /* define PDC[31:16] as DATA[31:16] */ + cfg->ebi_pio_pdr = 0xFFFF0000; + /* no pull-up for D[31:16] */ + cfg->ebi_pio_ppudr = 0xFFFF0000; + /* EBI0_CSA, CS1 SDRAM, CS3 NAND Flash, 3.3V memories */ + cfg->ebi_csa = + AT91_MATRIX_EBI0_DBPUC | AT91_MATRIX_EBI0_VDDIOMSEL_1_8V | + AT91_MATRIX_EBI0_CS1A_SDRAMC | + AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA; + + cfg->smc_cs = 0; +#if 1 + cfg->smc_mode = + AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_DBW_16 | + AT91_SMC_TDFMODE | + AT91_SMC_TDF_(6); + cfg->smc_cycle = + AT91_SMC_NWECYCLE_(16) | AT91_SMC_NRDCYCLE_(16); + cfg->smc_pulse = + AT91_SMC_NWEPULSE_(5) | AT91_SMC_NCS_WRPULSE_(7) | + AT91_SMC_NRDPULSE_(5) | AT91_SMC_NCS_RDPULSE_(13); + cfg->smc_setup = + AT91_SMC_NWESETUP_(3) | AT91_SMC_NCS_WRSETUP_(2) | + AT91_SMC_NRDSETUP_(8) | AT91_SMC_NCS_RDSETUP_(0); +#elif 0 /* slow setup */ + cfg->smc_mode = + AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_DBW_16 | + AT91_SMC_TDFMODE | + AT91_SMC_TDF_(1); + cfg->smc_cycle = + AT91_SMC_NWECYCLE_(0xd00) | AT91_SMC_NRDCYCLE_(0xd00); + cfg->smc_pulse = + AT91_SMC_NWEPULSE_(5) | AT91_SMC_NCS_WRPULSE_(7) | + AT91_SMC_NRDPULSE_(5) | AT91_SMC_NCS_RDPULSE_(13); + cfg->smc_setup = + AT91_SMC_NWESETUP_(3) | AT91_SMC_NCS_WRSETUP_(2) | + AT91_SMC_NRDSETUP_(8) | AT91_SMC_NCS_RDSETUP_(0); +#else /* RONETIX' original values */ + cfg->smc_mode = + AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_DBW_16 | + AT91_SMC_TDFMODE | + AT91_SMC_TDF_(6); + cfg->smc_cycle = + AT91_SMC_NWECYCLE_(22) | AT91_SMC_NRDCYCLE_(22); + cfg->smc_pulse = + AT91_SMC_NWEPULSE_(11) | AT91_SMC_NCS_WRPULSE_(11) | + AT91_SMC_NRDPULSE_(11) | AT91_SMC_NCS_RDPULSE_(11); + cfg->smc_setup = + AT91_SMC_NWESETUP_(10) | AT91_SMC_NCS_WRSETUP_(10) | + AT91_SMC_NRDSETUP_(10) | AT91_SMC_NCS_RDSETUP_(10); +#endif + + cfg->pmc_mor = + AT91_PMC_MOSCEN | + (255 << 8); /* Main Oscillator Start-up Time */ + cfg->pmc_pllar = + AT91_PMC_PLLA_WR_ERRATA | /* Bit 29 must be 1 when prog */ + AT91_PMC_OUT | + AT91_PMC_PLLCOUNT | /* PLL Counter */ + (2 << 28) | /* PLL Clock Frequency Range */ + ((MASTER_PLL_MUL - 1) << 16) | (MASTER_PLL_DIV); + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr1 = + AT91_PMC_CSS_SLOW | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr2 = + AT91_PMC_CSS_PLLA | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + + /* SDRAM */ + /* SDRAMC_TR - Refresh Timer register */ + cfg->sdrc_tr1 = 0x13C; + /* SDRAMC_CR - Configuration register*/ + cfg->sdrc_cr = + AT91_SDRAMC_NC_9 | + AT91_SDRAMC_NR_13 | + AT91_SDRAMC_NB_4 | + AT91_SDRAMC_CAS_3 | + AT91_SDRAMC_DBW_32 | + (2 << 8) | /* tWR - Write Recovery Delay */ + (8 << 12) | /* tRC - Row Cycle Delay */ + (2 << 16) | /* tRP - Row Precharge Delay */ + (2 << 20) | /* tRCD - Row to Column Delay */ + (5 << 24) | /* tRAS - Active to Precharge Delay */ + (12 << 28); /* tXSR - Exit Self Refresh to Active Delay */ + + /* Memory Device Register -> SDRAM */ + cfg->sdrc_mdr = AT91_SDRAMC_MD_SDRAM; + /* SDRAM_TR */ + cfg->sdrc_tr2 = 780; + + /* user reset enable */ + cfg->rstc_rmr = + AT91_RSTC_KEY | + AT91_RSTC_PROCRST | + AT91_RSTC_RSTTYP_WAKEUP | + AT91_RSTC_RSTTYP_WATCHDOG; +} diff --git a/arch/arm/boards/panda/board.c b/arch/arm/boards/panda/board.c index c5d8fe6409..f1fbd5e944 100644 --- a/arch/arm/boards/panda/board.c +++ b/arch/arm/boards/panda/board.c @@ -19,7 +19,7 @@ #include <sizes.h> #include <asm/mmu.h> #include <mach/gpio.h> -#include <environment.h> +#include <envfs.h> #include <mach/xload.h> #include <i2c/i2c.h> #include <gpio.h> diff --git a/arch/arm/boards/pcm037/lowlevel.c b/arch/arm/boards/pcm037/lowlevel.c index baf63a53b9..da017325fe 100644 --- a/arch/arm/boards/pcm037/lowlevel.c +++ b/arch/arm/boards/pcm037/lowlevel.c @@ -30,28 +30,13 @@ #include <asm/barebox-arm-head.h> #include <mach/esdctl.h> -#ifdef CONFIG_NAND_IMX_BOOT -static void __bare_init __naked insdram(void) -{ - /* setup a stack to be able to call imx_nand_load_image() */ - arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - - imx_nand_load_image(_text, barebox_image_size); - - board_init_lowlevel_return(); -} -#endif - #define ESDCTL0_VAL (ESDCTL0_SDE | ESDCTL0_ROW13 | ESDCTL0_COL10) void __bare_init __naked reset(void) { uint32_t r; volatile int v; -#ifdef CONFIG_NAND_IMX_BOOT - int i; - unsigned int *trg, *src; -#endif + common_reset(); writel(1 << 6, MX31_IPU_CTRL_BASE_ADDR); @@ -141,21 +126,10 @@ void __bare_init __naked reset(void) #endif #ifdef CONFIG_NAND_IMX_BOOT - /* skip NAND boot if not running from NFC space */ - r = get_pc(); - if (r < MX31_NFC_BASE_ADDR || r > MX31_NFC_BASE_ADDR + 0x800) - board_init_lowlevel_return(); - - src = (unsigned int *)MX31_NFC_BASE_ADDR; - trg = (unsigned int *)_text; - - /* Move ourselves out of NFC SRAM */ - for (i = 0; i < 0x800 / sizeof(int); i++) - *trg++ = *src++; + /* setup a stack to be able to call imx31_barebox_boot_nand_external() */ + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - /* Jump to SDRAM */ - r = (unsigned int)&insdram; - __asm__ __volatile__("mov pc, %0" : : "r"(r)); + imx31_barebox_boot_nand_external(); #else board_init_lowlevel_return(); #endif diff --git a/arch/arm/boards/pcm037/pcm037.c b/arch/arm/boards/pcm037/pcm037.c index 7894ff3bdb..959cc8ad8c 100644 --- a/arch/arm/boards/pcm037/pcm037.c +++ b/arch/arm/boards/pcm037/pcm037.c @@ -253,11 +253,3 @@ static int imx31_console_init(void) } console_initcall(imx31_console_init); - -#ifdef CONFIG_NAND_IMX_BOOT -void __bare_init nand_boot(void) -{ - imx_nand_load_image(_text, barebox_image_size); - board_init_lowlevel_return(); -} -#endif diff --git a/arch/arm/boards/pcm038/lowlevel.c b/arch/arm/boards/pcm038/lowlevel.c index 2f93c3127a..4515107741 100644 --- a/arch/arm/boards/pcm038/lowlevel.c +++ b/arch/arm/boards/pcm038/lowlevel.c @@ -31,27 +31,13 @@ #include "pll.h" -#ifdef CONFIG_NAND_IMX_BOOT -static void __bare_init __naked insdram(void) -{ - /* setup a stack to be able to call imx_nand_load_image() */ - arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - - imx_nand_load_image(_text, barebox_image_size); - - board_init_lowlevel_return(); -} -#endif - #define ESDCTL0_VAL (ESDCTL0_SDE | ESDCTL0_ROW13 | ESDCTL0_COL10) void __bare_init __naked reset(void) { uint32_t r; int i; -#ifdef CONFIG_NAND_IMX_BOOT - unsigned int *trg, *src; -#endif + common_reset(); /* ahb lite ip interface */ @@ -108,23 +94,11 @@ void __bare_init __naked reset(void) MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0); #ifdef CONFIG_NAND_IMX_BOOT - /* skip NAND boot if not running from NFC space */ - r = get_pc(); - if (r < MX27_NFC_BASE_ADDR || r > MX27_NFC_BASE_ADDR + 0x800) - board_init_lowlevel_return(); - - src = (unsigned int *)MX27_NFC_BASE_ADDR; - trg = (unsigned int *)_text; - - /* Move ourselves out of NFC SRAM */ - for (i = 0; i < 0x800 / sizeof(int); i++) - *trg++ = *src++; + /* setup a stack to be able to call mx27_barebox_boot_nand_external() */ + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - /* Jump to SDRAM */ - r = (unsigned int)&insdram; - __asm__ __volatile__("mov pc, %0" : : "r"(r)); + imx27_barebox_boot_nand_external(); #else board_init_lowlevel_return(); #endif } - diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c index ea50a78905..5e9c0fdecc 100644 --- a/arch/arm/boards/pcm038/pcm038.c +++ b/arch/arm/boards/pcm038/pcm038.c @@ -13,6 +13,7 @@ * * */ +#define pr_fmt(fmt) "pcm038: " fmt #include <common.h> #include <net.h> @@ -170,7 +171,7 @@ static int pcm038_power_init(void) /* Clocks have changed. Notify clients */ clock_notifier_call_chain(); } else { - printf("Failed to initialize PMIC. Will continue with low CPU speed\n"); + pr_err("Failed to initialize PMIC. Will continue with low CPU speed\n"); } } @@ -315,7 +316,7 @@ static int pcm038_devices_init(void) envdev = "NOR"; } - printf("Using environment in %s Flash\n", envdev); + pr_notice("Using environment in %s Flash\n", envdev); if (imx_iim_read(1, 1, &uid, 6) == 6) armlinux_set_serial(uid); diff --git a/arch/arm/boards/pcm043/lowlevel.c b/arch/arm/boards/pcm043/lowlevel.c index 751f6aefdf..639064f97f 100644 --- a/arch/arm/boards/pcm043/lowlevel.c +++ b/arch/arm/boards/pcm043/lowlevel.c @@ -40,36 +40,13 @@ #define CCM_PDR0_399 0x00011000 #define CCM_PDR0_532 0x00001000 -#ifdef CONFIG_NAND_IMX_BOOT -static void __bare_init __naked insdram(void) -{ - uint32_t r; - - /* Speed up NAND controller by adjusting the NFC divider */ - r = readl(MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); - r &= ~(0xf << 28); - r |= 0x1 << 28; - writel(r, MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); - - /* setup a stack to be able to call imx_nand_load_image() */ - arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - - imx_nand_load_image(_text, barebox_image_size); - - board_init_lowlevel_return(); -} -#endif - void __bare_init __naked reset(void) { uint32_t r, s; unsigned long ccm_base = MX35_CCM_BASE_ADDR; unsigned long iomuxc_base = MX35_IOMUXC_BASE_ADDR; unsigned long esdctl_base = MX35_ESDCTL_BASE_ADDR; -#ifdef CONFIG_NAND_IMX_BOOT - unsigned int *trg, *src; - int i; -#endif + common_reset(); r = get_cr(); @@ -206,23 +183,17 @@ void __bare_init __naked reset(void) writel(0x00002000, esdctl_base + IMX_ESDCTL1); #ifdef CONFIG_NAND_IMX_BOOT - /* skip NAND boot if not running from NFC space */ - r = get_pc(); - if (r < MX35_NFC_BASE_ADDR || r > MX35_NFC_BASE_ADDR + 0x800) - board_init_lowlevel_return(); - - src = (unsigned int *)MX35_NFC_BASE_ADDR; - trg = (unsigned int *)_text; + /* Speed up NAND controller by adjusting the NFC divider */ + r = readl(MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); + r &= ~(0xf << 28); + r |= 0x1 << 28; + writel(r, MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); - /* Move ourselves out of NFC SRAM */ - for (i = 0; i < 0x800 / sizeof(int); i++) - *trg++ = *src++; + /* setup a stack to be able to call imx35_barebox_boot_nand_external() */ + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); - /* Jump to SDRAM */ - r = (unsigned int)&insdram; - __asm__ __volatile__("mov pc, %0" : : "r"(r)); + imx35_barebox_boot_nand_external(); #else board_init_lowlevel_return(); #endif } - diff --git a/arch/arm/boards/phycard-i.MX27/lowlevel_init.S b/arch/arm/boards/phycard-i.MX27/lowlevel_init.S index 38cc55c1dc..cb5d83dd07 100644 --- a/arch/arm/boards/phycard-i.MX27/lowlevel_init.S +++ b/arch/arm/boards/phycard-i.MX27/lowlevel_init.S @@ -111,31 +111,7 @@ reset: #ifdef CONFIG_NAND_IMX_BOOT ldr sp, =0xa0f00000 /* Setup a temporary stack in SDRAM */ - ldr r0, =MX27_NFC_BASE_ADDR /* start of NFC SRAM */ - ldr r2, =MX27_NFC_BASE_ADDR + 0x1000 /* end of NFC SRAM */ - - /* skip NAND boot if not running from NFC space */ - cmp pc, r0 - bls ret - cmp pc, r2 - bhi ret - - /* Move ourselves out of NFC SRAM */ - ldr r1, =_text - -copy_loop: - ldmia r0!, {r3-r9} /* copy from source address [r0] */ - stmia r1!, {r3-r9} /* copy to target address [r1] */ - cmp r0, r2 /* until source end address [r2] */ - ble copy_loop - - ldr pc, =1f /* Jump to SDRAM */ -1: - ldr r0,=_text - ldr r1,=_barebox_image_size - bl imx_nand_load_image - b board_init_lowlevel_return - + b imx27_barebox_boot_nand_external #endif /* CONFIG_NAND_IMX_BOOT */ ret: diff --git a/arch/arm/boards/pm9261/Makefile b/arch/arm/boards/pm9261/Makefile index eb072c0161..b6460c3982 100644 --- a/arch/arm/boards/pm9261/Makefile +++ b/arch/arm/boards/pm9261/Makefile @@ -1 +1,5 @@ obj-y += init.o + +obj-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += lowlevel_init.o + +pbl-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += lowlevel_init.o diff --git a/arch/arm/boards/pm9261/config.h b/arch/arm/boards/pm9261/config.h index 4602aa7e83..006820cf21 100644 --- a/arch/arm/boards/pm9261/config.h +++ b/arch/arm/boards/pm9261/config.h @@ -3,91 +3,4 @@ #define AT91_MAIN_CLOCK 18432000 /* 18.432 MHz crystal */ -#define MASTER_PLL_DIV 15 -#define MASTER_PLL_MUL 162 -#define MAIN_PLL_DIV 2 - -/* clocks */ -#define CONFIG_SYS_MOR_VAL \ - (AT91_PMC_MOSCEN | \ - (255 << 8)) /* Main Oscillator Start-up Time */ -#define CONFIG_SYS_PLLAR_VAL \ - (AT91_PMC_PLLA_WR_ERRATA | /* Bit 29 must be 1 when prog */ \ - AT91_PMC_OUT | \ - ((MASTER_PLL_MUL - 1) << 16) | (MASTER_PLL_DIV)) - -/* PCK/2 = MCK Master Clock from PLLA */ -#define CONFIG_SYS_MCKR1_VAL \ - (AT91_PMC_CSS_SLOW | \ - AT91_PMC_PRES_1 | \ - AT91SAM9_PMC_MDIV_2 | \ - AT91_PMC_PDIV_1) - -/* PCK/2 = MCK Master Clock from PLLA */ -#define CONFIG_SYS_MCKR2_VAL \ - (AT91_PMC_CSS_PLLA | \ - AT91_PMC_PRES_1 | \ - AT91SAM9_PMC_MDIV_2 | \ - AT91_PMC_PDIV_1) - -/* define PDC[31:16] as DATA[31:16] */ -#define CONFIG_SYS_PIOC_PDR_VAL1 0xFFFF0000 -/* no pull-up for D[31:16] */ -#define CONFIG_SYS_PIOC_PPUDR_VAL 0xFFFF0000 - -/* EBI_CSA, no pull-ups for D[15:0], CS1 SDRAM, CS3 NAND Flash */ -#define CONFIG_SYS_MATRIX_EBICSA_VAL \ - (AT91_MATRIX_DBPUC | AT91_MATRIX_CS1A_SDRAMC) - -/* SDRAM */ -/* SDRAMC_TR - Refresh Timer register */ -#define CONFIG_SYS_SDRC_TR_VAL1 0x13C -/* SDRAMC_CR - Configuration register*/ -#define CONFIG_SYS_SDRC_CR_VAL \ - (AT91_SDRAMC_NC_9 | \ - AT91_SDRAMC_NR_13 | \ - AT91_SDRAMC_NB_4 | \ - AT91_SDRAMC_CAS_3 | \ - AT91_SDRAMC_DBW_32 | \ - (1 << 8) | /* Write Recovery Delay */ \ - (7 << 12) | /* Row Cycle Delay */ \ - (3 << 16) | /* Row Precharge Delay */ \ - (2 << 20) | /* Row to Column Delay */ \ - (5 << 24) | /* Active to Precharge Delay */ \ - (1 << 28)) /* Exit Self Refresh to Active Delay */ - -/* Memory Device Register -> SDRAM */ -#define CONFIG_SYS_SDRC_MDR_VAL AT91_SDRAMC_MD_SDRAM -#define CONFIG_SYS_SDRC_TR_VAL2 1200 /* SDRAM_TR */ - -/* setup SMC0, CS0 (NOR Flash) - 16-bit, 15 WS */ -#define CONFIG_SYS_SMC_CS 0 -#define CONFIG_SYS_SMC_SETUP_VAL \ - (AT91_SMC_NWESETUP_(10) | AT91_SMC_NCS_WRSETUP_(10) | \ - AT91_SMC_NRDSETUP_(10) | AT91_SMC_NCS_RDSETUP_(10)) -#define CONFIG_SYS_SMC_PULSE_VAL \ - (AT91_SMC_NWEPULSE_(11) | AT91_SMC_NCS_WRPULSE_(11) | \ - AT91_SMC_NRDPULSE_(11) | AT91_SMC_NCS_RDPULSE_(11)) -#define CONFIG_SYS_SMC_CYCLE_VAL \ - (AT91_SMC_NWECYCLE_(22) | AT91_SMC_NRDCYCLE_(22)) -#define CONFIG_SYS_SMC_MODE_VAL \ - (AT91_SMC_READMODE | AT91_SMC_WRITEMODE | \ - AT91_SMC_DBW_16 | \ - AT91_SMC_TDFMODE | \ - AT91_SMC_TDF_(6)) - -/* user reset enable */ -#define CONFIG_SYS_RSTC_RMR_VAL \ - (AT91_RSTC_KEY | \ - AT91_RSTC_PROCRST | \ - AT91_RSTC_RSTTYP_WAKEUP | \ - AT91_RSTC_RSTTYP_WATCHDOG) - -/* Disable Watchdog */ -#define CONFIG_SYS_WDTC_WDMR_VAL \ - (AT91_WDT_WDIDLEHLT | AT91_WDT_WDDBGHLT | \ - AT91_WDT_WDV | \ - AT91_WDT_WDDIS | \ - AT91_WDT_WDD) - #endif /* __CONFIG_H */ diff --git a/arch/arm/boards/pm9261/lowlevel_init.c b/arch/arm/boards/pm9261/lowlevel_init.c new file mode 100644 index 0000000000..91a64b4158 --- /dev/null +++ b/arch/arm/boards/pm9261/lowlevel_init.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2009-2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <init.h> +#include <mach/hardware.h> +#include <mach/at91_rstc.h> +#include <mach/at91_wdt.h> +#include <mach/at91_pmc.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91sam9_sdramc.h> +#include <mach/at91sam9_matrix.h> +#include <mach/at91_lowlevel_init.h> + +#define MASTER_PLL_DIV 15 +#define MASTER_PLL_MUL 162 +#define MAIN_PLL_DIV 2 + +void __bare_init at91sam926x_lowlevel_board_config(struct at91sam926x_lowlevel_cfg *cfg) +{ + /* Disable Watchdog */ + cfg->wdt_mr = + AT91_WDT_WDIDLEHLT | AT91_WDT_WDDBGHLT | + AT91_WDT_WDV | + AT91_WDT_WDDIS | + AT91_WDT_WDD; + + /* define PDC[31:16] as DATA[31:16] */ + cfg->ebi_pio_pdr = 0xFFFF0000; + /* no pull-up for D[31:16] */ + cfg->ebi_pio_ppudr = 0xFFFF0000; + /* EBI0_CSA, CS1 SDRAM, CS3 NAND Flash, 3.3V memories */ + cfg->ebi_csa = + AT91_MATRIX_DBPUC | AT91_MATRIX_CS1A_SDRAMC; + + cfg->smc_cs = 0; + cfg->smc_mode = + AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_DBW_16 | + AT91_SMC_TDFMODE | + AT91_SMC_TDF_(6); + cfg->smc_cycle = + AT91_SMC_NWECYCLE_(22) | AT91_SMC_NRDCYCLE_(22); + cfg->smc_pulse = + AT91_SMC_NWEPULSE_(11) | AT91_SMC_NCS_WRPULSE_(11) | + AT91_SMC_NRDPULSE_(11) | AT91_SMC_NCS_RDPULSE_(11); + cfg->smc_setup = + AT91_SMC_NWESETUP_(10) | AT91_SMC_NCS_WRSETUP_(10) | + AT91_SMC_NRDSETUP_(10) | AT91_SMC_NCS_RDSETUP_(10); + + cfg->pmc_mor = + AT91_PMC_MOSCEN | + (255 << 8); /* Main Oscillator Start-up Time */ + cfg->pmc_pllar = + AT91_PMC_PLLA_WR_ERRATA | /* Bit 29 must be 1 when prog */ + AT91_PMC_OUT | + ((MASTER_PLL_MUL - 1) << 16) | (MASTER_PLL_DIV); + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr1 = + AT91_PMC_CSS_SLOW | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr2 = + AT91_PMC_CSS_PLLA | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + + /* SDRAM */ + /* SDRAMC_TR - Refresh Timer register */ + cfg->sdrc_tr1 = 0x13C; + /* SDRAMC_CR - Configuration register*/ + cfg->sdrc_cr = + AT91_SDRAMC_NC_9 | + AT91_SDRAMC_NR_13 | + AT91_SDRAMC_NB_4 | + AT91_SDRAMC_CAS_3 | + AT91_SDRAMC_DBW_32 | + (1 << 8) | /* Write Recovery Delay */ + (7 << 12) | /* Row Cycle Delay */ + (3 << 16) | /* Row Precharge Delay */ + (2 << 20) | /* Row to Column Delay */ + (5 << 24) | /* Active to Precharge Delay */ + (1 << 28); /* Exit Self Refresh to Active Delay */ + + /* Memory Device Register -> SDRAM */ + cfg->sdrc_mdr = AT91_SDRAMC_MD_SDRAM; + /* SDRAM_TR */ + cfg->sdrc_tr2 = 1200; + + /* user reset enable */ + cfg->rstc_rmr = + AT91_RSTC_KEY | + AT91_RSTC_PROCRST | + AT91_RSTC_RSTTYP_WAKEUP | + AT91_RSTC_RSTTYP_WATCHDOG; +} diff --git a/arch/arm/boards/pm9263/Makefile b/arch/arm/boards/pm9263/Makefile index eb072c0161..b6460c3982 100644 --- a/arch/arm/boards/pm9263/Makefile +++ b/arch/arm/boards/pm9263/Makefile @@ -1 +1,5 @@ obj-y += init.o + +obj-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += lowlevel_init.o + +pbl-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += lowlevel_init.o diff --git a/arch/arm/boards/pm9263/config.h b/arch/arm/boards/pm9263/config.h index 322c1f3d30..906661330d 100644 --- a/arch/arm/boards/pm9263/config.h +++ b/arch/arm/boards/pm9263/config.h @@ -3,107 +3,4 @@ #define AT91_MAIN_CLOCK 18432000 -#define MASTER_PLL_DIV 6 -#define MASTER_PLL_MUL 65 -#define MAIN_PLL_DIV 2 /* 2 or 4 */ - -/* clocks */ -#define CONFIG_SYS_MOR_VAL \ - (AT91_PMC_MOSCEN | \ - (255 << 8)) /* Main Oscillator Start-up Time */ -#define CONFIG_SYS_PLLAR_VAL \ - (AT91_PMC_PLLA_WR_ERRATA | /* Bit 29 must be 1 when prog */ \ - AT91_PMC_OUT | \ - AT91_PMC_PLLCOUNT | /* PLL Counter */ \ - (2 << 28) | /* PLL Clock Frequency Range */ \ - ((MASTER_PLL_MUL - 1) << 16) | (MASTER_PLL_DIV)) - -#if (MAIN_PLL_DIV == 2) -/* PCK/2 = MCK Master Clock from PLLA */ -#define CONFIG_SYS_MCKR1_VAL \ - (AT91_PMC_CSS_SLOW | \ - AT91_PMC_PRES_1 | \ - AT91SAM9_PMC_MDIV_2 | \ - AT91_PMC_PDIV_1) -/* PCK/2 = MCK Master Clock from PLLA */ -#define CONFIG_SYS_MCKR2_VAL \ - (AT91_PMC_CSS_PLLA | \ - AT91_PMC_PRES_1 | \ - AT91SAM9_PMC_MDIV_2 | \ - AT91_PMC_PDIV_1) -#else -/* PCK/4 = MCK Master Clock from PLLA */ -#define CONFIG_SYS_MCKR1_VAL \ - (AT91_PMC_CSS_SLOW | \ - AT91_PMC_PRES_1 | \ - AT91RM9200_PMC_MDIV_3 | \ - AT91_PMC_PDIV_1) -/* PCK/4 = MCK Master Clock from PLLA */ -#define CONFIG_SYS_MCKR2_VAL \ - (AT91_PMC_CSS_PLLA | \ - AT91_PMC_PRES_1 | \ - AT91RM9200_PMC_MDIV_3 | \ - AT91_PMC_PDIV_1) -#endif -/* define PDC[31:16] as DATA[31:16] */ -#define CONFIG_SYS_PIOD_PDR_VAL1 0xFFFF0000 -/* no pull-up for D[31:16] */ -#define CONFIG_SYS_PIOD_PPUDR_VAL 0xFFFF0000 -/* EBI0_CSA, CS1 SDRAM, CS3 NAND Flash, 3.3V memories */ -#define CONFIG_SYS_MATRIX_EBI0CSA_VAL \ - (AT91_MATRIX_EBI0_DBPUC | AT91_MATRIX_EBI0_VDDIOMSEL_3_3V | \ - AT91_MATRIX_EBI0_CS1A_SDRAMC) - -/* SDRAM */ -/* SDRAMC_TR - Refresh Timer register */ -#define CONFIG_SYS_SDRC_TR_VAL1 0x3AA -/* SDRAMC_CR - Configuration register*/ -#define CONFIG_SYS_SDRC_CR_VAL \ - (AT91_SDRAMC_NC_9 | \ - AT91_SDRAMC_NR_13 | \ - AT91_SDRAMC_NB_4 | \ - AT91_SDRAMC_CAS_2 | \ - AT91_SDRAMC_DBW_32 | \ - (2 << 8) | /* tWR - Write Recovery Delay */ \ - (7 << 12) | /* tRC - Row Cycle Delay */ \ - (2 << 16) | /* tRP - Row Precharge Delay */ \ - (2 << 20) | /* tRCD - Row to Column Delay */ \ - (5 << 24) | /* tRAS - Active to Precharge Delay */ \ - (8 << 28)) /* tXSR - Exit Self Refresh to Active Delay */ - -/* Memory Device Register -> SDRAM */ -#define CONFIG_SYS_SDRC_MDR_VAL AT91_SDRAMC_MD_SDRAM -#define CONFIG_SYS_SDRC_TR_VAL2 1200 /* SDRAM_TR */ - -/* setup SMC0, CS0 (NOR Flash) - 16-bit, 15 WS */ -#define CONFIG_SYS_SMC_CS 0 -#define CONFIG_SYS_SMC_SETUP_VAL \ - (AT91_SMC_NWESETUP_(10) | AT91_SMC_NCS_WRSETUP_(10) | \ - AT91_SMC_NRDSETUP_(10) | AT91_SMC_NCS_RDSETUP_(10)) -#define CONFIG_SYS_SMC_PULSE_VAL \ - (AT91_SMC_NWEPULSE_(11) | AT91_SMC_NCS_WRPULSE_(11) | \ - AT91_SMC_NRDPULSE_(11) | AT91_SMC_NCS_RDPULSE_(11)) -#define CONFIG_SYS_SMC_CYCLE_VAL \ - (AT91_SMC_NWECYCLE_(22) | AT91_SMC_NRDCYCLE_(22)) -#define CONFIG_SYS_SMC_MODE_VAL \ - (AT91_SMC_READMODE | AT91_SMC_WRITEMODE | \ - AT91_SMC_DBW_16 | \ - AT91_SMC_TDFMODE | \ - AT91_SMC_TDF_(6)) - -/* user reset enable */ -#define CONFIG_SYS_RSTC_RMR_VAL \ - (AT91_RSTC_KEY | \ - AT91_RSTC_PROCRST | \ - AT91_RSTC_RSTTYP_WAKEUP | \ - AT91_RSTC_RSTTYP_WATCHDOG) - -/* Disable Watchdog */ -#define CONFIG_SYS_WDTC_WDMR_VAL \ - (AT91_WDT_WDIDLEHLT | AT91_WDT_WDDBGHLT | \ - AT91_WDT_WDV | \ - AT91_WDT_WDDIS | \ - AT91_WDT_WDD) - - #endif /* __CONFIG_H */ diff --git a/arch/arm/boards/pm9263/init.c b/arch/arm/boards/pm9263/init.c index f7ef148b8c..4afa09536d 100644 --- a/arch/arm/boards/pm9263/init.c +++ b/arch/arm/boards/pm9263/init.c @@ -89,8 +89,8 @@ static void pm_add_device_nand(void) } static struct at91_ether_platform_data macb_pdata = { - .is_rmii = 1, - .phy_addr = 0, + .phy_interface = PHY_INTERFACE_MODE_RMII, + .phy_addr = -1, }; static void pm9263_phy_init(void) diff --git a/arch/arm/boards/pm9263/lowlevel_init.c b/arch/arm/boards/pm9263/lowlevel_init.c new file mode 100644 index 0000000000..6336d51063 --- /dev/null +++ b/arch/arm/boards/pm9263/lowlevel_init.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2009-2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <init.h> +#include <mach/hardware.h> +#include <mach/at91_rstc.h> +#include <mach/at91_wdt.h> +#include <mach/at91_pmc.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91sam9_sdramc.h> +#include <mach/at91sam9_matrix.h> +#include <mach/at91_lowlevel_init.h> + +#define MASTER_PLL_DIV 6 +#define MASTER_PLL_MUL 65 +#define MAIN_PLL_DIV 2 /* 2 or 4 */ + +void __bare_init at91sam926x_lowlevel_board_config(struct at91sam926x_lowlevel_cfg *cfg) +{ + /* Disable Watchdog */ + cfg->wdt_mr = + AT91_WDT_WDIDLEHLT | AT91_WDT_WDDBGHLT | + AT91_WDT_WDV | + AT91_WDT_WDDIS | + AT91_WDT_WDD; + + /* define PDC[31:16] as DATA[31:16] */ + cfg->ebi_pio_pdr = 0xFFFF0000; + /* no pull-up for D[31:16] */ + cfg->ebi_pio_ppudr = 0xFFFF0000; + /* EBI0_CSA, CS1 SDRAM, CS3 NAND Flash, 3.3V memories */ + cfg->ebi_csa = + AT91_MATRIX_EBI0_DBPUC | AT91_MATRIX_EBI0_VDDIOMSEL_3_3V | + AT91_MATRIX_EBI0_CS1A_SDRAMC; + + cfg->smc_cs = 0; + cfg->smc_mode = + AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_DBW_16 | + AT91_SMC_TDFMODE | + AT91_SMC_TDF_(6); + cfg->smc_cycle = + AT91_SMC_NWECYCLE_(22) | AT91_SMC_NRDCYCLE_(22); + cfg->smc_pulse = + AT91_SMC_NWEPULSE_(11) | AT91_SMC_NCS_WRPULSE_(11) | + AT91_SMC_NRDPULSE_(11) | AT91_SMC_NCS_RDPULSE_(11); + cfg->smc_setup = + AT91_SMC_NWESETUP_(10) | AT91_SMC_NCS_WRSETUP_(10) | + AT91_SMC_NRDSETUP_(10) | AT91_SMC_NCS_RDSETUP_(10); + + cfg->pmc_mor = + AT91_PMC_MOSCEN | + (255 << 8); /* Main Oscillator Start-up Time */ + cfg->pmc_pllar = + AT91_PMC_PLLA_WR_ERRATA | /* Bit 29 must be 1 when prog */ + AT91_PMC_OUT | + AT91_PMC_PLLCOUNT | /* PLL Counter */ + (2 << 28) | /* PLL Clock Frequency Range */ + ((MASTER_PLL_MUL - 1) << 16) | (MASTER_PLL_DIV); + + if (MAIN_PLL_DIV == 2) { + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr1 = + AT91_PMC_CSS_SLOW | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr2 = + AT91_PMC_CSS_PLLA | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + } else { + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr1 = + AT91_PMC_CSS_SLOW | + AT91_PMC_PRES_1 | + AT91RM9200_PMC_MDIV_3 | + AT91_PMC_PDIV_1; + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr2 = + AT91_PMC_CSS_PLLA | + AT91_PMC_PRES_1 | + AT91RM9200_PMC_MDIV_3 | + AT91_PMC_PDIV_1; + } + + /* SDRAM */ + /* SDRAMC_TR - Refresh Timer register */ + cfg->sdrc_tr1 = 0x3AA; + /* SDRAMC_CR - Configuration register*/ + cfg->sdrc_cr = + AT91_SDRAMC_NC_9 | + AT91_SDRAMC_NR_13 | + AT91_SDRAMC_NB_4 | + AT91_SDRAMC_CAS_2 | + AT91_SDRAMC_DBW_32 | + (2 << 8) | /* tWR - Write Recovery Delay */ + (7 << 12) | /* tRC - Row Cycle Delay */ + (2 << 16) | /* tRP - Row Precharge Delay */ + (2 << 20) | /* tRCD - Row to Column Delay */ + (5 << 24) | /* tRAS - Active to Precharge Delay */ + (8 << 28); /* tXSR - Exit Self Refresh to Active Delay */ + + /* Memory Device Register -> SDRAM */ + cfg->sdrc_mdr = AT91_SDRAMC_MD_SDRAM; + /* SDRAM_TR */ + cfg->sdrc_tr2 = 1200; + + /* user reset enable */ + cfg->rstc_rmr = + AT91_RSTC_KEY | + AT91_RSTC_PROCRST | + AT91_RSTC_RSTTYP_WAKEUP | + AT91_RSTC_RSTTYP_WATCHDOG; +} diff --git a/arch/arm/boards/pm9g45/init.c b/arch/arm/boards/pm9g45/init.c index 8e29f62e8e..720099b125 100644 --- a/arch/arm/boards/pm9g45/init.c +++ b/arch/arm/boards/pm9g45/init.c @@ -113,7 +113,7 @@ static void __init pm9g45_add_device_usbh(void) {} #endif static struct at91_ether_platform_data macb_pdata = { - .is_rmii = 1, + .phy_interface = PHY_INTERFACE_MODE_RMII, .phy_addr = 0, }; @@ -137,7 +137,7 @@ static void pm9g45_add_device_eth(void) static int pm9g45_mem_init(void) { - at91_add_device_sdram(128 * 1024 * 1024); + at91_add_device_sdram(0); return 0; } diff --git a/arch/arm/boards/qil-a9260/init.c b/arch/arm/boards/qil-a9260/init.c index 4977d3b75e..2e131fee8e 100644 --- a/arch/arm/boards/qil-a9260/init.c +++ b/arch/arm/boards/qil-a9260/init.c @@ -78,7 +78,7 @@ static void qil_a9260_add_device_mci(void) {} #ifdef CONFIG_CALAO_MB_QIL_A9260 static struct at91_ether_platform_data macb_pdata = { - .is_rmii = 1, + .phy_interface = PHY_INTERFACE_MODE_RMII, .phy_addr = -1, }; diff --git a/arch/arm/boards/sama5d3xek/Makefile b/arch/arm/boards/sama5d3xek/Makefile new file mode 100644 index 0000000000..db021eeb77 --- /dev/null +++ b/arch/arm/boards/sama5d3xek/Makefile @@ -0,0 +1,2 @@ +obj-y += init.o +obj-$(CONFIG_W1) += hw_version.o diff --git a/arch/arm/boards/sama5d3xek/config.h b/arch/arm/boards/sama5d3xek/config.h new file mode 100644 index 0000000000..d97181032f --- /dev/null +++ b/arch/arm/boards/sama5d3xek/config.h @@ -0,0 +1,6 @@ +#ifndef __CONFIG_H +#define __CONFIG_H + +#define AT91_MAIN_CLOCK 12000000 /* 12 MHz crystal */ + +#endif /* __CONFIG_H */ diff --git a/arch/arm/boards/sama5d3xek/env/bin/init_board b/arch/arm/boards/sama5d3xek/env/bin/init_board new file mode 100644 index 0000000000..f3d417e356 --- /dev/null +++ b/arch/arm/boards/sama5d3xek/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/sama5d3xek/env/config b/arch/arm/boards/sama5d3xek/env/config new file mode 100644 index 0000000000..375e90d74a --- /dev/null +++ b/arch/arm/boards/sama5d3xek/env/config @@ -0,0 +1,44 @@ +#!/bin/sh + +# use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration +ip=dhcp-barebox +global.dhcp.vendor_id=barebox-sama5d3xek +global.dhcp.client_id="${sama5d3xcm.board}-${sama5d3xcm.vendor}" + +# 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),384k(barebox)ro,256k@768k(bareboxenv),256k(bareboxenv2),128k@1536k(oftree),5M@2M(kernel),-@8M(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/sama5d3xek/hw_version.c b/arch/arm/boards/sama5d3xek/hw_version.c new file mode 100644 index 0000000000..a9fcf7dc11 --- /dev/null +++ b/arch/arm/boards/sama5d3xek/hw_version.c @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + */ + +#include <common.h> +#include <fs.h> +#include <fcntl.h> +#include <libbb.h> +#include <asm/armlinux.h> +#include <of.h> +#include <libfdt.h> + +#include "hw_version.h" + +enum board_type { + BOARD_TYPE_MB, + BOARD_TYPE_DM, + BOARD_TYPE_CPU, +}; + +static struct board_info { + char *name; + enum board_type type; + unsigned char id; +} board_list[] = { + {"SAMA5D3x-MB", BOARD_TYPE_MB, 0}, + {"SAMA5D3x-DM", BOARD_TYPE_DM, 1}, + {"SAMA5D31-CM", BOARD_TYPE_CPU, 2}, + {"SAMA5D33-CM", BOARD_TYPE_CPU, 3}, + {"SAMA5D34-CM", BOARD_TYPE_CPU, 4}, + {"SAMA5D35-CM", BOARD_TYPE_CPU, 5}, + {"PDA-DM", BOARD_TYPE_DM, 7}, +}; + +static struct board_info* get_board_info_by_name(const char *name) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(board_list); i++) { + char *bname = board_list[i].name; + if (strncmp(name, bname, strlen(bname)) == 0) + return &board_list[i]; + } + + return NULL; +} + +static struct vendor_info { + char *name; + enum vendor_id id; +} vendor_list[] = { + {"EMBEST", VENDOR_EMBEST}, + {"FLEX", VENDOR_FLEX}, + {"RONETIX", VENDOR_RONETIX}, + {"COGENT", VENDOR_COGENT}, + {"PDA", VENDOR_PDA}, +}; + +static struct vendor_info* get_vendor_info_by_name(const char *name) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(vendor_list); i++) { + char *vname = vendor_list[i].name; + if (strncmp(name, vname, strlen(vname)) == 0) + return &vendor_list[i]; + } + + return NULL; +} + +#define BOARD_NAME_LEN 12 +#define VENDOR_NAME_LEN 10 +#define VENDOR_COUNTRY_LEN 2 + +struct one_wire_info { + u8 total_bytes; + u8 vendor_name[VENDOR_NAME_LEN]; + u8 vendor_country[VENDOR_COUNTRY_LEN]; + u8 board_name[BOARD_NAME_LEN]; + u8 year; + u8 week; + u8 revision_board; + u8 revision_schema; + u8 revision_bom; + u8 checksum_l; + u8 checksum_h; +}__attribute__ ((packed)); + +static int at91sama5d3xek_read_w1(const char *file, struct one_wire_info *info) +{ + int fd; + int ret; + + fd = open(file, O_RDONLY); + if (fd < 0) { + ret = fd; + goto err; + } + + ret = read_full(fd, info, sizeof(*info)); + if (ret < 0) + goto err_open; + + if (ret < sizeof(*info)) { + ret = -EINVAL; + goto err_open; + } + + pr_debug("total_bytes = %d\n", info->total_bytes); + pr_debug("vendor_name = %s\n", info->vendor_name); + pr_debug("vendor_country = %.2s\n", info->vendor_country); + pr_debug("board_name = %s\n", info->board_name); + pr_debug("year = %d\n", info->year); + pr_debug("week = %d\n", info->week); + pr_debug("revision_board = %x\n", info->revision_board); + pr_debug("revision_schema = %x\n", info->revision_schema); + pr_debug("revision_bom = %x\n", info->revision_bom); + pr_debug("checksum_l = %x\n", info->checksum_l); + pr_debug("checksum_h = %x\n", info->checksum_h); + + ret = 0; + +err_open: + close(fd); +err: + if (ret) + pr_err("can not read 1-wire %s (%s)\n", file, strerror(ret)); + return ret; +} + +static u32 sn = 0; +static u32 rev = 0; + +bool at91sama5d3xek_cm_is_vendor(enum vendor_id vid) +{ + return ((sn >> 5) & 0x1f) == vid; +} + +bool at91sama5d3xek_ek_is_vendor(enum vendor_id vid) +{ + return ((sn >> 25) & 0x1f) == vid; +} + +bool at91sama5d3xek_dm_is_vendor(enum vendor_id vid) +{ + return ((sn >> 15) & 0x1f) == vid; +} + +static void at91sama5d3xek_devices_detect_one(const char *name) +{ + struct one_wire_info info; + struct board_info* binfo; + struct vendor_info* vinfo; + struct device_d *dev = NULL; + char str[16]; + char *bname, *vname; + u8 vendor_id = 0; + + if (at91sama5d3xek_read_w1(name, &info)) + return; + + binfo = get_board_info_by_name(info.board_name); + + if (!binfo) { + pr_err("board %s no supported\n", info.board_name); + return; + } + bname = binfo->name; + + vinfo = get_vendor_info_by_name(info.vendor_name); + vname = info.vendor_name; + if (vinfo) { + vendor_id = vinfo->id; + vname = vinfo->name; + } + + switch (binfo->type) { + case BOARD_TYPE_CPU: + dev = add_generic_device_res("sama5d3xcm", DEVICE_ID_SINGLE, NULL, 0, NULL); + if (!dev) + return; + sn |= (binfo->id & 0x1f); + sn |= ((vendor_id & 0x1f) << 5); + rev |= (info.revision_board - 'A'); + rev |= (((info.revision_schema - '0') & 0x3) << 15); + pr_info("CM"); + break; + case BOARD_TYPE_MB: + dev = add_generic_device_res("sama5d3xmb", DEVICE_ID_SINGLE, NULL, 0, NULL); + if (!dev) + return; + sn |= ((binfo->id & 0x1f) << 20); + sn |= ((vendor_id & 0x1f) << 25); + rev |= ((info.revision_board - 'A') << 10); + rev |= (((info.revision_schema - '0') & 0x3) << 21); + pr_info("MB"); + break; + case BOARD_TYPE_DM: + dev = add_generic_device_res("sama5d3xdm", DEVICE_ID_SINGLE, NULL, 0, NULL); + if (!dev) + return; + sn |= ((binfo->id & 0x1f) << 10); + sn |= ((vendor_id & 0x1f) << 15); + rev |= ((info.revision_board - 'A') << 5); + rev |= (((info.revision_schema - '0') & 0x3) << 18); + pr_info("DM"); + break; + } + + pr_info(": %s [%c%c] from %s\n", + bname, info.revision_board, info.revision_schema, vname); + + dev_add_param_fixed(dev, "vendor", vname); + dev_add_param_fixed(dev, "board", bname); + sprintf(str, "%.2s", info.vendor_country); + dev_add_param_fixed(dev, "country", str); + sprintf(str, "%d", info.year); + dev_add_param_fixed(dev, "year", str); + sprintf(str, "%d", info.week); + dev_add_param_fixed(dev, "week", str); + sprintf(str, "%c", info.revision_board); + dev_add_param_fixed(dev, "revision_board", str); + sprintf(str, "%c", info.revision_schema); + dev_add_param_fixed(dev, "revision_schema", str); + sprintf(str, "%c", info.revision_bom); + dev_add_param_fixed(dev, "revision_bom", str); +} + +void at91sama5d3xek_devices_detect_hw(void) +{ + at91sama5d3xek_devices_detect_one("/dev/ds24310"); + at91sama5d3xek_devices_detect_one("/dev/ds28ec200"); + at91sama5d3xek_devices_detect_one("/dev/ds24330"); + + pr_info("sn: 0x%x, rev: 0x%x\n", sn, rev); + armlinux_set_revision(rev); + armlinux_set_serial(sn); +} diff --git a/arch/arm/boards/sama5d3xek/hw_version.h b/arch/arm/boards/sama5d3xek/hw_version.h new file mode 100644 index 0000000000..ed9ea88d42 --- /dev/null +++ b/arch/arm/boards/sama5d3xek/hw_version.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + */ + +#ifndef __HW_REVISION_H__ +#define __HW_REVISION_H__ + +enum vendor_id { + VENDOR_UNKNOWN = 0, + VENDOR_EMBEST = 1, + VENDOR_FLEX = 2, + VENDOR_RONETIX = 3, + VENDOR_COGENT = 4, + VENDOR_PDA = 5, +}; + +#ifdef CONFIG_W1 +bool at91sama5d3xek_cm_is_vendor(enum vendor_id vid); +bool at91sama5d3xek_ek_is_vendor(enum vendor_id vid); +bool at91sama5d3xek_dm_is_vendor(enum vendor_id vid); +void at91sama5d3xek_devices_detect_hw(void); +#else +bool at91sama5d3xek_cm_is_vendor(enum vendor_id vid) +{ + return false; +} + +bool at91sama5d3xek_ek_is_vendor(enum vendor_id vid) +{ + return false; +} + +bool at91sama5d3xek_dm_is_vendor(enum vendor_id vid) +{ + return false; +} + +void at91sama5d3xek_devices_detect_hw(void) {} +#endif + +#endif /* __HW_REVISION_H__ */ diff --git a/arch/arm/boards/sama5d3xek/init.c b/arch/arm/boards/sama5d3xek/init.c new file mode 100644 index 0000000000..110a83f803 --- /dev/null +++ b/arch/arm/boards/sama5d3xek/init.c @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + */ + +#include <common.h> +#include <net.h> +#include <init.h> +#include <environment.h> +#include <asm/armlinux.h> +#include <generated/mach-types.h> +#include <partition.h> +#include <fs.h> +#include <fcntl.h> +#include <io.h> +#include <asm/hardware.h> +#include <nand.h> +#include <sizes.h> +#include <linux/mtd/nand.h> +#include <mach/board.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91sam9_smc.h> +#include <gpio.h> +#include <mach/io.h> +#include <mach/at91_pmc.h> +#include <mach/at91_rstc.h> +#include <mach/at91sam9x5_matrix.h> +#include <input/qt1070.h> +#include <readkey.h> +#include <poller.h> +#include <linux/w1-gpio.h> +#include <w1_mac_address.h> +#include <spi/spi.h> +#include <linux/clk.h> +#include <linux/phy.h> +#include <linux/micrel_phy.h> + +#include "hw_version.h" + +struct w1_gpio_platform_data w1_pdata = { + .pin = AT91_PIN_PE25, + .ext_pullup_enable_pin = -EINVAL, + .is_open_drain = 0, +}; + +#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 = 4, +#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) + .bus_width_16 = 1, +#endif + .on_flash_bbt = 1, +}; + +static struct sam9_smc_config cm_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 6, + .nrd_pulse = 4, + .ncs_write_pulse = 5, + .nwe_pulse = 3, + + .read_cycle = 6, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, + .tdf_cycles = 1, +}; + +static void ek_add_device_nand(void) +{ + struct clk *clk = clk_get(NULL, "smc_clk"); + + clk_enable(clk); + + /* setup bus-width (8 or 16) */ + if (nand_pdata.bus_width_16) + cm_nand_smc_config.mode |= AT91_SMC_DBW_16; + else + cm_nand_smc_config.mode |= AT91_SMC_DBW_8; + + /* configure chip-select 3 (NAND) */ + sam9_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 at91_ether_platform_data macb_pdata = { + .phy_interface = PHY_INTERFACE_MODE_RMII, + .phy_addr = 0, +}; + +static bool used_23 = false; +static bool used_43 = false; + +static int ek_register_mac_address_23(int id) +{ + if (used_23) + return -EBUSY; + + used_23 = true; + + return w1_local_mac_address_register(id, "tml", "w1-23-0"); +} + +static int ek_register_mac_address_43(int id) +{ + if (used_43) + return -EBUSY; + + used_43 = true; + + return w1_local_mac_address_register(id, "tml", "w1-43-0"); +} + +static void ek_add_device_eth(void) +{ + if (w1_local_mac_address_register(0, "tml", "w1-2d-0")) + if (ek_register_mac_address_23(0)) + ek_register_mac_address_43(0); + + if (ek_register_mac_address_23(1)) + ek_register_mac_address_43(1); + + at91_add_device_eth(1, &macb_pdata); +} +#else +static void ek_add_device_eth(void) {} +#endif + +#if defined(CONFIG_DRIVER_VIDEO_ATMEL_HLCD) +/* + * LCD Controller + */ +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, + }, +}; + +/* Default output mode is TFT 24 bit */ +#define BPP_OUT_DEFAULT_LCDCFG5 (LCDC_LCDCFG5_MODE_OUTPUT_24BPP) + +/* Driver datas */ +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) +/* + * MCI (SD/MMC) + */ +static struct atmel_mci_platform_data mci0_data = { + .bus_width = 4, + .detect_pin = AT91_PIN_PD17, + .wp_pin = -EINVAL, +}; + +static struct atmel_mci_platform_data mci1_data = { + .bus_width = 4, + .detect_pin = AT91_PIN_PD18, + .wp_pin = -EINVAL, +}; + +static void ek_add_device_mci(void) +{ + /* MMC0 */ + at91_add_device_mci(0, &mci0_data); + /* MMC1 */ + at91_add_device_mci(1, &mci1_data); +} +#else +static void ek_add_device_mci(void) {} +#endif + +#if defined(CONFIG_I2C_GPIO) +struct qt1070_platform_data qt1070_pdata = { + .irq_pin = AT91_PIN_PE31, +}; + +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(1, i2c_devices, ARRAY_SIZE(i2c_devices)); + at91_add_device_i2c(0, NULL, 0); +} +#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_PD13 }; +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_PE24, + .active_low = 1, + .led = { + .name = "d1", + }, + }, { + .gpio = AT91_PIN_PE25, + .active_low = 1, + .led = { + .name = "d2", + }, + }, +}; + +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 at91sama5d3xek_mem_init(void) +{ + at91_add_device_sdram(0); + + return 0; +} +mem_initcall(at91sama5d3xek_mem_init); + +static void ek_add_device_w1(void) +{ + at91_set_gpio_input(w1_pdata.pin, 0); + at91_set_multi_drive(w1_pdata.pin, 1); + add_generic_device_res("w1-gpio", DEVICE_ID_SINGLE, NULL, 0, &w1_pdata); + + at91sama5d3xek_devices_detect_hw(); +} + +#ifdef CONFIG_POLLER +/* + * The SiI9022A (HDMI) and QT1070 share the same irq + * but if the SiI9022A is not reset the irq is pull down + * So do it. As the SiI9022A need 1s to reset (500ms up then 500ms down then up) + * do it poller to do not slow down the boot + */ +static int hdmi_reset_pin = AT91_PIN_PC31; +static uint64_t hdmi_reset_start; +struct poller_struct hdmi_poller; + +static void hdmi_on_poller(struct poller_struct *poller) +{ + if (!is_timeout_non_interruptible(hdmi_reset_start, 500 * MSECOND)) + return; + + gpio_set_value(hdmi_reset_pin, 1); + + poller_unregister(poller); + ek_add_device_i2c(); +} + +static void hdmi_off_poller(struct poller_struct *poller) +{ + if (!is_timeout_non_interruptible(hdmi_reset_start, 500 * MSECOND)) + return; + + gpio_set_value(hdmi_reset_pin, 0); + + hdmi_reset_start = get_time_ns(); + poller->func = hdmi_on_poller; +} + +static void ek_add_device_hdmi(void) +{ + at91_set_gpio_output(hdmi_reset_pin, 1); + hdmi_reset_start = get_time_ns(); + hdmi_poller.func = hdmi_off_poller; + + poller_register(&hdmi_poller); +} +#else +static void ek_add_device_hdmi(void) +{ + ek_add_device_i2c(); +} +#endif + +static int at91sama5d3xek_devices_init(void) +{ + ek_add_device_w1(); + ek_add_device_hdmi(); + ek_add_device_nand(); + ek_add_led(); + ek_add_device_eth(); + ek_add_device_spi(); + ek_add_device_mci(); + ek_add_device_lcdc(); + + armlinux_set_bootparams((void *)(SAMA5_DDRCS + 0x100)); + + devfs_add_partition("nand0", 0x00000, SZ_256K, DEVFS_PARTITION_FIXED, "at91bootstrap_raw"); + dev_add_bb_dev("at91bootstrap_raw", "at91bootstrap"); + devfs_add_partition("nand0", SZ_256K, SZ_256K + SZ_128K, DEVFS_PARTITION_FIXED, "self_raw"); + dev_add_bb_dev("self_raw", "self0"); + devfs_add_partition("nand0", SZ_512K + SZ_256K, SZ_256K, DEVFS_PARTITION_FIXED, "env_raw"); + dev_add_bb_dev("env_raw", "env0"); + devfs_add_partition("nand0", SZ_1M, SZ_256K, DEVFS_PARTITION_FIXED, "env_raw1"); + dev_add_bb_dev("env_raw1", "env1"); + + return 0; +} +device_initcall(at91sama5d3xek_devices_init); + +static int at91sama5d3xek_console_init(void) +{ + at91_register_uart(0, 0); + at91_register_uart(2, 0); + return 0; +} +console_initcall(at91sama5d3xek_console_init); diff --git a/arch/arm/boards/telit-evk-pro3/Makefile b/arch/arm/boards/telit-evk-pro3/Makefile new file mode 100644 index 0000000000..eb072c0161 --- /dev/null +++ b/arch/arm/boards/telit-evk-pro3/Makefile @@ -0,0 +1 @@ +obj-y += init.o diff --git a/arch/arm/boards/telit-evk-pro3/config.h b/arch/arm/boards/telit-evk-pro3/config.h new file mode 100644 index 0000000000..7aeff30e8c --- /dev/null +++ b/arch/arm/boards/telit-evk-pro3/config.h @@ -0,0 +1,6 @@ +#ifndef __CONFIG_H +#define __CONFIG_H + +#define AT91_MAIN_CLOCK 6000000 /* 6.000 MHz crystal */ + +#endif /* __CONFIG_H */ diff --git a/arch/arm/boards/telit-evk-pro3/env/boot/nand-ubi b/arch/arm/boards/telit-evk-pro3/env/boot/nand-ubi new file mode 100644 index 0000000000..1987492df7 --- /dev/null +++ b/arch/arm/boards/telit-evk-pro3/env/boot/nand-ubi @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + boot-menu-add-entry "$0" "nand (UBI)" + exit +fi + +global.bootm.image="/dev/nand0.kernel.bb" +#global.bootm.oftree="/env/oftree" +global.linux.bootargs.dyn.root="root=ubi0:rootfs ubi.mtd=nand0.rootfs rootfstype=ubifs" diff --git a/arch/arm/boards/telit-evk-pro3/env/init/config-board b/arch/arm/boards/telit-evk-pro3/env/init/config-board new file mode 100644 index 0000000000..741b90213f --- /dev/null +++ b/arch/arm/boards/telit-evk-pro3/env/init/config-board @@ -0,0 +1,8 @@ +#!/bin/sh + +# board defaults, do not change in running system. Change /env/config +# instead + +global.hostname=evk-pro3 +global.linux.bootargs.base="console=ttyS0,115200" +global.boot.default=nand-ubi diff --git a/arch/arm/boards/telit-evk-pro3/env/init/mtdparts-nand b/arch/arm/boards/telit-evk-pro3/env/init/mtdparts-nand new file mode 100644 index 0000000000..58e859bb96 --- /dev/null +++ b/arch/arm/boards/telit-evk-pro3/env/init/mtdparts-nand @@ -0,0 +1,11 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + init-menu-add-entry "$0" "NAND partitions" + exit +fi + +mtdparts="0xC0000(nand0.bootstrap),256k(nand0.barebox)ro,128k(nand0.bareboxenv),3M(nand0.kernel),-(nand0.rootfs)" +kernelname="atmel_nand" + +mtdparts-add -b -d nand0 -k ${kernelname} -p ${mtdparts} diff --git a/arch/arm/boards/telit-evk-pro3/env/init/usb b/arch/arm/boards/telit-evk-pro3/env/init/usb new file mode 100644 index 0000000000..47429f50a4 --- /dev/null +++ b/arch/arm/boards/telit-evk-pro3/env/init/usb @@ -0,0 +1,40 @@ +#!/bin/sh + +# Connect PC31 to GND to enable DFU +gpio_dfu=95 +gpio_name="PC31" +gpio_wait=5 + +product_id=0x1234 +vendor_id=0x4321 + +dfu_config="/dev/nand0.bootstrap.bb(bootstrap)sr,/dev/nand0.barebox.bb(barebox)sr,/dev/nand0.kernel.bb(kernel)r,/dev/nand0.rootfs.bb(rootfs)r" + +echo + +if [ $at91_udc0.vbus != 1 ]; then + echo "No USB Device cable plugged, normal boot" + exit +fi + +gpio_get_value ${gpio_dfu} +if [ $? = 0 ]; then + echo "${gpio_name} low value detected wait ${gpio_wait}s" + timeout -s -a ${gpio_wait} + + if [ $at91_udc0.vbus != 1 ]; then + echo "No USB Device cable plugged, normal boot" + exit + fi + + gpio_get_value ${gpio_dfu} + if [ $? = 0 ]; then + echo "Start DFU Mode" + dfu ${dfu_config} -P ${product_id} -V ${vendor_id} + exit + fi +fi + +global.autoboot_timeout=16 +echo "enable tty over USB Device, increase the boot delay to ${global.autoboot_timeout}s" +usbserial diff --git a/arch/arm/boards/telit-evk-pro3/init.c b/arch/arm/boards/telit-evk-pro3/init.c new file mode 100644 index 0000000000..d5f1b3ea2e --- /dev/null +++ b/arch/arm/boards/telit-evk-pro3/init.c @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2007 Sascha Hauer, Pengutronix + * Copyright (C) 2013 Fabio Porcedda <fabio.porcedda@gmail.com>, Telit + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <asm/armlinux.h> +#include <common.h> +#include <gpio.h> +#include <init.h> +#include <linux/clk.h> +#include <mach/at91_rstc.h> +#include <mach/at91sam9_smc.h> +#include <mach/board.h> +#include <mach/io.h> +#include <nand.h> + +#define BOOTSTRAP_SIZE 0xC0000 + +static struct atmel_nand_data nand_pdata = { + .ale = 21, + .cle = 22, + .det_pin = -EINVAL, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .on_flash_bbt = 1, +}; + +static struct sam9_smc_config evk_nand_smc_config = { + .ncs_read_setup = 0, + .nrd_setup = 1, + .ncs_write_setup = 0, + .nwe_setup = 1, + + .ncs_read_pulse = 3, + .nrd_pulse = 3, + .ncs_write_pulse = 3, + .nwe_pulse = 3, + + .read_cycle = 5, + .write_cycle = 5, + + .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, + .tdf_cycles = 2, +}; + +static void evk_add_device_nand(void) +{ + /* configure chip-select 3 (NAND) */ + sam9_smc_configure(0, 3, &evk_nand_smc_config); + + at91_add_device_nand(&nand_pdata); +} + +static struct at91_ether_platform_data macb_pdata = { + .phy_interface = PHY_INTERFACE_MODE_RMII, + .phy_addr = 0, +}; + +static void evk_phy_reset(void) +{ + unsigned long rstc; + struct clk *clk = clk_get(NULL, "macb_clk"); + + clk_enable(clk); + + at91_set_gpio_input(AT91_PIN_PA14, 0); + at91_set_gpio_input(AT91_PIN_PA15, 0); + at91_set_gpio_input(AT91_PIN_PA17, 0); + at91_set_gpio_input(AT91_PIN_PA25, 0); + at91_set_gpio_input(AT91_PIN_PA26, 0); + at91_set_gpio_input(AT91_PIN_PA28, 0); + + rstc = at91_sys_read(AT91_RSTC_MR) & AT91_RSTC_ERSTL; + + /* Need to reset PHY -> 500ms reset */ + at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY | + (AT91_RSTC_ERSTL & (0x0d << 8)) | + AT91_RSTC_URSTEN); + + at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_EXTRST); + + /* Wait for end hardware reset */ + while (!(at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_NRSTL)) + ; + + /* Restore NRST value */ + at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY | (rstc) | AT91_RSTC_URSTEN); +} + +/* + * MCI (SD/MMC) + */ +#if defined(CONFIG_MCI_ATMEL) +static struct atmel_mci_platform_data __initdata evk_mci_data = { + .bus_width = 4, + .detect_pin = AT91_PIN_PA27, + .wp_pin = AT91_PIN_PA25, +}; + +static void evk_usb_add_device_mci(void) +{ + at91_add_device_mci(0, &evk_mci_data); +} +#else +static void evk_usb_add_device_mci(void) {} +#endif + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata evk_usbh_data = { + .ports = 2, + .vbus_pin = { -EINVAL, -EINVAL }, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata evk_udc_data = { + .vbus_pin = AT91_PIN_PC4, + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ +}; + +static int evk_mem_init(void) +{ + at91_add_device_sdram(0); + + return 0; +} +mem_initcall(evk_mem_init); + +static int evk_devices_init(void) +{ + evk_add_device_nand(); + evk_phy_reset(); + at91_add_device_eth(0, &macb_pdata); + at91_add_device_usbh_ohci(&evk_usbh_data); + at91_add_device_udc(&evk_udc_data); + evk_usb_add_device_mci(); + + armlinux_set_bootparams((void *)(AT91_CHIPSELECT_1 + 0x100)); + + devfs_add_partition("nand0", 0x00000, BOOTSTRAP_SIZE, + DEVFS_PARTITION_FIXED, "bootstrap_raw"); + dev_add_bb_dev("bootstrap_raw", "bootstrap"); + devfs_add_partition("nand0", BOOTSTRAP_SIZE, SZ_256K, + DEVFS_PARTITION_FIXED, "self_raw"); + dev_add_bb_dev("self_raw", "self0"); + devfs_add_partition("nand0", BOOTSTRAP_SIZE + SZ_256K, SZ_128K, + DEVFS_PARTITION_FIXED, "env_raw"); + dev_add_bb_dev("env_raw", "env0"); + devfs_add_partition("nand0", BOOTSTRAP_SIZE + SZ_256K + SZ_128K, + SZ_128K, DEVFS_PARTITION_FIXED, "env_raw1"); + dev_add_bb_dev("env_raw1", "env1"); + + return 0; +} +device_initcall(evk_devices_init); + +static int evk_console_init(void) +{ + at91_register_uart(0, 0); + return 0; +} +console_initcall(evk_console_init); diff --git a/arch/arm/boards/tny-a926x/Makefile b/arch/arm/boards/tny-a926x/Makefile index eb072c0161..36ea09fca8 100644 --- a/arch/arm/boards/tny-a926x/Makefile +++ b/arch/arm/boards/tny-a926x/Makefile @@ -1 +1,10 @@ obj-y += init.o + +bootstrap-$(CONFIG_MACH_TNY_A9263) = tny_a9263_bootstrap.o +obj-$(CONFIG_AT91_BOOTSTRAP) += $(bootstrap-y) + +lowlevel_init-$(CONFIG_MACH_TNY_A9263) = tny_a9263_lowlevel_init.o + +obj-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += $(lowlevel_init-y) + +pbl-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += $(lowlevel_init-y) diff --git a/arch/arm/boards/tny-a926x/init.c b/arch/arm/boards/tny-a926x/init.c index 5fe653173a..4228254e3a 100644 --- a/arch/arm/boards/tny-a926x/init.c +++ b/arch/arm/boards/tny-a926x/init.c @@ -113,7 +113,7 @@ static void tny_a9260_add_device_nand(void) #ifdef CONFIG_DRIVER_NET_MACB static struct at91_ether_platform_data macb_pdata = { - .is_rmii = 1, + .phy_interface = PHY_INTERFACE_MODE_RMII, .phy_addr = -1, }; @@ -160,16 +160,31 @@ static struct spi_board_info tny_a9g20_lpw_spi_devices[] = { }, }; -static int spi0_standard_cs[] = { AT91_PIN_PC11 }; -struct at91_spi_platform_data spi0_pdata = { - .chipselect = spi0_standard_cs, - .num_chipselect = ARRAY_SIZE(spi0_standard_cs), +static struct spi_board_info tny_a9263_spi_devices[] = { + { + .name = "mtd_dataflash", + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + .chip_select = 0, + }, }; -static int spi1_standard_cs[] = { AT91_PIN_PC3 }; -struct at91_spi_platform_data spi1_pdata = { - .chipselect = spi1_standard_cs, - .num_chipselect = ARRAY_SIZE(spi1_standard_cs), +static int tny_a9263_spi0_standard_cs[] = { AT91_PIN_PA5 }; +struct at91_spi_platform_data tny_a9263_spi0_pdata = { + .chipselect = tny_a9263_spi0_standard_cs, + .num_chipselect = ARRAY_SIZE(tny_a9263_spi0_standard_cs), +}; + +static int tny_a9g20_spi0_standard_cs[] = { AT91_PIN_PC11 }; +struct at91_spi_platform_data tny_a9g20_spi0_pdata = { + .chipselect = tny_a9g20_spi0_standard_cs, + .num_chipselect = ARRAY_SIZE(tny_a9g20_spi0_standard_cs), +}; + +static int tny_a9g20_spi1_standard_cs[] = { AT91_PIN_PC3 }; +struct at91_spi_platform_data tny_a9g20_spi1_pdata = { + .chipselect = tny_a9g20_spi1_standard_cs, + .num_chipselect = ARRAY_SIZE(tny_a9g20_spi1_standard_cs), }; static void __init ek_add_device_udc(void) @@ -182,17 +197,19 @@ static void __init ek_add_device_udc(void) static void __init ek_add_device_spi(void) { - if (machine_is_tny_a9263()) - return; + if (machine_is_tny_a9263()) { + spi_register_board_info(tny_a9263_spi_devices, + ARRAY_SIZE(tny_a9263_spi_devices)); + at91_add_device_spi(0, &tny_a9263_spi0_pdata); - if (machine_is_tny_a9g20() && at91_is_low_power_sdram()) { + } else if (machine_is_tny_a9g20() && at91_is_low_power_sdram()) { spi_register_board_info(tny_a9g20_lpw_spi_devices, ARRAY_SIZE(tny_a9g20_lpw_spi_devices)); - at91_add_device_spi(1, &spi1_pdata); + at91_add_device_spi(1, &tny_a9g20_spi1_pdata); } else { spi_register_board_info(tny_a9g20_spi_devices, ARRAY_SIZE(tny_a9g20_spi_devices)); - at91_add_device_spi(0, &spi0_pdata); + at91_add_device_spi(0, &tny_a9g20_spi0_pdata); } } diff --git a/arch/arm/boards/tny-a926x/tny_a9263_bootstrap.c b/arch/arm/boards/tny-a926x/tny_a9263_bootstrap.c new file mode 100644 index 0000000000..368c67744f --- /dev/null +++ b/arch/arm/boards/tny-a926x/tny_a9263_bootstrap.c @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <bootstrap.h> +#include <mach/bootstrap.h> + +#ifdef CONFIG_MTD_DATAFLASH +void * bootstrap_board_read_dataflash(void) +{ + return bootstrap_read_devfs("dataflash0", false, 0xffc0, 204864, 204864); +} +#endif diff --git a/arch/arm/boards/tny-a926x/tny_a9263_lowlevel_init.c b/arch/arm/boards/tny-a926x/tny_a9263_lowlevel_init.c new file mode 100644 index 0000000000..1b146da625 --- /dev/null +++ b/arch/arm/boards/tny-a926x/tny_a9263_lowlevel_init.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2009-2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <init.h> +#include <mach/hardware.h> +#include <mach/at91_rstc.h> +#include <mach/at91_wdt.h> +#include <mach/at91_pmc.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91sam9_sdramc.h> +#include <mach/at91sam9_matrix.h> +#include <mach/at91_lowlevel_init.h> + +#define MASTER_CLOCK 180 + +#if MASTER_CLOCK == 200 +#define MASTER_PLL_MUL 100 +#else +#define MASTER_PLL_MUL 90 +#endif +#define MASTER_PLL_DIV 6 + +void __bare_init at91sam926x_lowlevel_board_config(struct at91sam926x_lowlevel_cfg *cfg) +{ + /* Disable Watchdog */ + cfg->wdt_mr = + AT91_WDT_WDIDLEHLT | AT91_WDT_WDDBGHLT | + AT91_WDT_WDV | + AT91_WDT_WDDIS | + AT91_WDT_WDD; + + /* define PDC[31:16] as DATA[31:16] */ + cfg->ebi_pio_pdr = 0xFFFF0000; + /* no pull-up for D[31:16] */ + cfg->ebi_pio_ppudr = 0xFFFF0000; + /* EBI0_CSA, CS1 SDRAM, CS3 NAND Flash, 3.3V memories */ + cfg->ebi_csa = + AT91_MATRIX_EBI0_DBPUC | AT91_MATRIX_EBI0_VDDIOMSEL_3_3V | + AT91_MATRIX_EBI0_CS1A_SDRAMC; + + cfg->smc_cs = 3; + cfg->smc_mode = + AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_DBW_8 | + AT91_SMC_EXNWMODE_DISABLE | + AT91_SMC_TDF_(2); + cfg->smc_cycle = + AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5); + cfg->smc_pulse = + AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) | + AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3); + cfg->smc_setup = + AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) | + AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0); + + cfg->pmc_mor = AT91_PMC_OSCBYPASS; + cfg->pmc_pllar = + AT91_PMC_PLLA_WR_ERRATA | /* Bit 29 must be 1 when prog */ + AT91_PMC_PLLCOUNT | /* PLL Counter */ + (0 << 28) | /* PLL Clock Frequency Range */ + ((MASTER_PLL_MUL - 1) << 16) | (MASTER_PLL_DIV); + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr1 = + AT91_PMC_CSS_SLOW | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr2 = + AT91_PMC_CSS_PLLA | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + + /* SDRAM */ + /* SDRAMC_TR - Refresh Timer register */ + cfg->sdrc_tr1 = 0x13C; + /* SDRAMC_CR - Configuration register*/ + cfg->sdrc_cr = + AT91_SDRAMC_NR_13 | + AT91_SDRAMC_NC_9 | + AT91_SDRAMC_NB_4 | + AT91_SDRAMC_CAS_2 | + AT91_SDRAMC_DBW_32 | + (2 << 8) | /* Write Recovery Delay */ + (7 << 12) | /* Row Cycle Delay */ + (2 << 16) | /* Row Precharge Delay */ + (2 << 20) | /* Row to Column Delay */ + (5 << 24) | /* Active to Precharge Delay */ + (8 << 28); /* Exit Self Refresh to Active Delay */ + + /* Memory Device Register -> SDRAM */ + cfg->sdrc_mdr = AT91_SDRAMC_MD_SDRAM; + /* SDRAM_TR */ + cfg->sdrc_tr2 = (MASTER_CLOCK * 7); + + /* user reset enable */ + cfg->rstc_rmr = + AT91_RSTC_KEY | + AT91_RSTC_PROCRST | + AT91_RSTC_RSTTYP_WAKEUP | + AT91_RSTC_RSTTYP_WATCHDOG; +} diff --git a/arch/arm/boards/usb-a926x/Makefile b/arch/arm/boards/usb-a926x/Makefile index eb072c0161..e314dd5b03 100644 --- a/arch/arm/boards/usb-a926x/Makefile +++ b/arch/arm/boards/usb-a926x/Makefile @@ -1 +1,10 @@ obj-y += init.o + +bootstrap-$(CONFIG_MACH_USB_A9263) = usb_a9263_bootstrap.o +obj-$(CONFIG_AT91_BOOTSTRAP) += $(bootstrap-y) + +lowlevel_init-$(CONFIG_MACH_USB_A9263) = usb_a9263_lowlevel_init.o + +obj-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += $(lowlevel_init-y) + +pbl-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += $(lowlevel_init-y) diff --git a/arch/arm/boards/usb-a926x/init.c b/arch/arm/boards/usb-a926x/init.c index 95ac6a80ce..0383280b65 100644 --- a/arch/arm/boards/usb-a926x/init.c +++ b/arch/arm/boards/usb-a926x/init.c @@ -51,6 +51,7 @@ static void usb_a9260_set_board_type(void) armlinux_set_architecture(MACH_TYPE_USB_A9260); } +#if defined(CONFIG_NAND_ATMEL) static struct atmel_nand_data nand_pdata = { .ale = 21, .cle = 22, @@ -111,9 +112,13 @@ static void usb_a9260_add_device_nand(void) at91_add_device_nand(&nand_pdata); } +#else +static void usb_a9260_add_device_nand(void) {} +#endif +#if defined(CONFIG_DRIVER_NET_MACB) static struct at91_ether_platform_data macb_pdata = { - .is_rmii = 1, + .phy_interface = PHY_INTERFACE_MODE_RMII, .phy_addr = -1, }; @@ -149,6 +154,16 @@ static void usb_a9260_phy_reset(void) AT91_RSTC_URSTEN); } +static void usb_a9260_add_device_eth(void) +{ + usb_a9260_phy_reset(); + at91_add_device_eth(0, &macb_pdata); +} +#else +static void usb_a9260_add_device_eth(void) {} +#endif + +#if defined(CONFIG_DRIVER_SPI_ATMEL) static const struct spi_board_info usb_a9263_spi_devices[] = { { .name = "mtd_dataflash", @@ -191,6 +206,9 @@ static void usb_a9260_add_spi(void) at91_add_device_spi(1, &spi_a9g20_pdata); } } +#else +static void usb_a9260_add_spi(void) {} +#endif #if defined(CONFIG_MCI_ATMEL) static struct atmel_mci_platform_data __initdata usb_a9260_mci_data = { @@ -205,11 +223,21 @@ static void usb_a9260_add_device_mci(void) static void usb_a9260_add_device_mci(void) {} #endif +#if defined(CONFIG_USB_OHCI) static struct at91_usbh_data ek_usbh_data = { .ports = 2, .vbus_pin = { -EINVAL, -EINVAL }, }; +static void usb_a9260_add_device_usb(void) +{ + at91_add_device_usbh_ohci(&ek_usbh_data); +} +#else +static void usb_a9260_add_device_usb(void) {} +#endif + +#ifdef CONFIG_USB_GADGET_DRIVER_AT91 /* * USB Device port */ @@ -225,7 +253,11 @@ static void __init ek_add_device_udc(void) at91_add_device_udc(&ek_udc_data); } +#else +static void __init ek_add_device_udc(void) {} +#endif +#ifdef CONFIG_LED_GPIO struct gpio_led led = { .gpio = AT91_PIN_PB21, .led = { @@ -241,6 +273,9 @@ static void __init ek_add_led(void) at91_set_gpio_output(led.gpio, led.active_low); led_gpio_register(&led); } +#else +static void ek_add_led(void) {} +#endif static int usb_a9260_mem_init(void) { @@ -356,11 +391,10 @@ static void usb_a9260_device_dab_mmx(void) {} static int usb_a9260_devices_init(void) { usb_a9260_add_device_nand(); - usb_a9260_phy_reset(); - at91_add_device_eth(0, &macb_pdata); usb_a9260_add_device_mci(); + usb_a9260_add_device_eth(); usb_a9260_add_spi(); - at91_add_device_usbh_ohci(&ek_usbh_data); + usb_a9260_add_device_usb(); ek_add_device_udc(); ek_add_led(); ek_add_device_button(); @@ -382,6 +416,7 @@ static int usb_a9260_devices_init(void) } device_initcall(usb_a9260_devices_init); +#ifndef CONFIG_CONSOLE_NONE static int usb_a9260_console_init(void) { struct device_d *dev; @@ -398,3 +433,4 @@ static int usb_a9260_console_init(void) return 0; } console_initcall(usb_a9260_console_init); +#endif diff --git a/arch/arm/boards/usb-a926x/usb_a9263_bootstrap.c b/arch/arm/boards/usb-a926x/usb_a9263_bootstrap.c new file mode 100644 index 0000000000..368c67744f --- /dev/null +++ b/arch/arm/boards/usb-a926x/usb_a9263_bootstrap.c @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <bootstrap.h> +#include <mach/bootstrap.h> + +#ifdef CONFIG_MTD_DATAFLASH +void * bootstrap_board_read_dataflash(void) +{ + return bootstrap_read_devfs("dataflash0", false, 0xffc0, 204864, 204864); +} +#endif diff --git a/arch/arm/boards/usb-a926x/usb_a9263_lowlevel_init.c b/arch/arm/boards/usb-a926x/usb_a9263_lowlevel_init.c new file mode 100644 index 0000000000..f6dc58e3f6 --- /dev/null +++ b/arch/arm/boards/usb-a926x/usb_a9263_lowlevel_init.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2009-2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <init.h> +#include <mach/hardware.h> +#include <mach/at91_rstc.h> +#include <mach/at91_wdt.h> +#include <mach/at91_pmc.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91sam9_sdramc.h> +#include <mach/at91sam9_matrix.h> +#include <mach/at91_lowlevel_init.h> + +#define MASTER_CLOCK 180 + +#if MASTER_CLOCK == 200 +#define MASTER_PLL_MUL 100 +#else +#define MASTER_PLL_MUL 90 +#endif +#define MASTER_PLL_DIV 6 + +void __bare_init at91sam926x_lowlevel_board_config(struct at91sam926x_lowlevel_cfg *cfg) +{ + /* Disable Watchdog */ + cfg->wdt_mr = + AT91_WDT_WDIDLEHLT | AT91_WDT_WDDBGHLT | + AT91_WDT_WDV | + AT91_WDT_WDDIS | + AT91_WDT_WDD; + + /* define PDC[31:16] as DATA[31:16] */ + cfg->ebi_pio_pdr = 0xFFFF0000; + /* no pull-up for D[31:16] */ + cfg->ebi_pio_ppudr = 0xFFFF0000; + /* EBI0_CSA, CS1 SDRAM, CS3 NAND Flash, 3.3V memories */ + cfg->ebi_csa = + AT91_MATRIX_EBI0_DBPUC | AT91_MATRIX_EBI0_VDDIOMSEL_3_3V | + AT91_MATRIX_EBI0_CS1A_SDRAMC; + + cfg->smc_cs = 3; + cfg->smc_mode = + AT91_SMC_READMODE | AT91_SMC_WRITEMODE | + AT91_SMC_DBW_8 | + AT91_SMC_EXNWMODE_DISABLE | + AT91_SMC_TDF_(2); + cfg->smc_cycle = + AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5); + cfg->smc_pulse = + AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) | + AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3); + cfg->smc_setup = + AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) | + AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0); + + cfg->pmc_mor = AT91_PMC_OSCBYPASS; + cfg->pmc_pllar = + AT91_PMC_PLLA_WR_ERRATA | /* Bit 29 must be 1 when prog */ + AT91_PMC_PLLCOUNT | /* PLL Counter */ + (0 << 28) | /* PLL Clock Frequency Range */ + ((MASTER_PLL_MUL - 1) << 16) | (MASTER_PLL_DIV); + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr1 = + AT91_PMC_CSS_SLOW | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + /* PCK/2 = MCK Master Clock from PLLA */ + cfg->pmc_mckr2 = + AT91_PMC_CSS_PLLA | + AT91_PMC_PRES_1 | + AT91SAM9_PMC_MDIV_2 | + AT91_PMC_PDIV_1; + + /* SDRAM */ + /* SDRAMC_TR - Refresh Timer register */ + cfg->sdrc_tr1 = 0x13C; + /* SDRAMC_CR - Configuration register*/ + cfg->sdrc_cr = + AT91_SDRAMC_NR_13 | + AT91_SDRAMC_NB_4 | + AT91_SDRAMC_CAS_2 | + AT91_SDRAMC_DBW_32 | + (2 << 8) | /* Write Recovery Delay */ + (7 << 12) | /* Row Cycle Delay */ + (2 << 16) | /* Row Precharge Delay */ + (2 << 20) | /* Row to Column Delay */ + (5 << 24) | /* Active to Precharge Delay */ + (8 << 28); /* Exit Self Refresh to Active Delay */ + + if (IS_ENABLED(CONFIG_AT91_HAVE_SRAM_128M)) + cfg->sdrc_cr |= AT91_SDRAMC_NC_10; + else + cfg->sdrc_cr |= AT91_SDRAMC_NC_9; + + /* Memory Device Register -> SDRAM */ + cfg->sdrc_mdr = AT91_SDRAMC_MD_SDRAM; + /* SDRAM_TR */ + cfg->sdrc_tr2 = (MASTER_CLOCK * 7); + + /* user reset enable */ + cfg->rstc_rmr = + AT91_RSTC_KEY | + AT91_RSTC_PROCRST | + AT91_RSTC_RSTTYP_WAKEUP | + AT91_RSTC_RSTTYP_WATCHDOG; +} diff --git a/arch/arm/configs/animeo_ip_defconfig b/arch/arm/configs/animeo_ip_defconfig new file mode 100644 index 0000000000..23e7278abf --- /dev/null +++ b/arch/arm/configs/animeo_ip_defconfig @@ -0,0 +1,79 @@ +CONFIG_ARCH_AT91SAM9260=y +CONFIG_MACH_ANIMEO_IP=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000 +CONFIG_AEABI=y +# CONFIG_CMD_ARM_CPUINFO is not set +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_PBL_IMAGE=y +CONFIG_MMU=y +CONFIG_EXPERIMENTAL=y +CONFIG_MALLOC_TLSF=y +CONFIG_PROMPT="Animeo-IP:" +CONFIG_BAUDRATE=38400 +CONFIG_LONGHELP=y +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/animeo_ip/env" +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_FLASH=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_UIMAGE=y +# CONFIG_CMD_BOOTU is not set +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_MTEST=y +CONFIG_CMD_MTEST_ALTERNATIVE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_LED=y +CONFIG_CMD_LED_TRIGGER=y +CONFIG_CMD_MIITOOL=y +CONFIG_CMD_WD=y +CONFIG_CMD_WD_DEFAULT_TIMOUT=16 +CONFIG_NET=y +CONFIG_NET_DHCP=y +CONFIG_NET_NFS=y +CONFIG_NET_PING=y +CONFIG_MICREL_PHY=y +CONFIG_DRIVER_NET_MACB=y +# CONFIG_SPI is not set +CONFIG_MTD=y +# CONFIG_MTD_OOB_DEVICE is not set +CONFIG_NAND=y +# CONFIG_NAND_ECC_HW is not set +# CONFIG_NAND_ECC_HW_SYNDROME is not set +# CONFIG_NAND_ECC_HW_NONE is not set +CONFIG_NAND_ATMEL=y +CONFIG_UBI=y +CONFIG_MCI=y +CONFIG_MCI_STARTUP=y +CONFIG_MCI_ATMEL=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_LED_GPIO_BICOLOR=y +CONFIG_LED_TRIGGERS=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_AT91SAM9X=y +CONFIG_FS_TFTP=y +CONFIG_FS_FAT=y +CONFIG_FS_FAT_LFN=y diff --git a/arch/arm/configs/at91sam9260ek_defconfig b/arch/arm/configs/at91sam9260ek_defconfig index b746bc8019..9c5c7d5203 100644 --- a/arch/arm/configs/at91sam9260ek_defconfig +++ b/arch/arm/configs/at91sam9260ek_defconfig @@ -1,4 +1,5 @@ CONFIG_ARCH_AT91SAM9260=y +CONFIG_MACH_AT91SAM9260EK=y CONFIG_AEABI=y # CONFIG_CMD_ARM_CPUINFO is not set CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y diff --git a/arch/arm/configs/at91sam9261ek_bootstrap_defconfig b/arch/arm/configs/at91sam9261ek_bootstrap_defconfig new file mode 100644 index 0000000000..1511ecbb33 --- /dev/null +++ b/arch/arm/configs/at91sam9261ek_bootstrap_defconfig @@ -0,0 +1,25 @@ +CONFIG_ARCH_AT91SAM9261=y +CONFIG_AT91_BOOTSTRAP=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x27000 +CONFIG_AEABI=y +# CONFIG_CMD_ARM_CPUINFO is not set +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_PBL_IMAGE=y +CONFIG_MMU=y +CONFIG_MALLOC_DUMMY=y +CONFIG_PROMPT="9261-EK:" +CONFIG_SHELL_NONE=y +# CONFIG_TIMESTAMP is not set +CONFIG_CONSOLE_SIMPLE=y +# CONFIG_DEFAULT_ENVIRONMENT is not set +# CONFIG_SPI is not set +CONFIG_MTD=y +# CONFIG_MTD_WRITE is not set +# CONFIG_MTD_OOB_DEVICE is not set +CONFIG_NAND=y +# CONFIG_NAND_ECC_HW is not set +# CONFIG_NAND_ECC_HW_SYNDROME is not set +# CONFIG_NAND_ECC_HW_NONE is not set +CONFIG_NAND_ATMEL=y +# CONFIG_FS_RAMFS is not set +CONFIG_BOOTSTRAP_DEVFS=y diff --git a/arch/arm/configs/at91sam9261ek_defconfig b/arch/arm/configs/at91sam9261ek_defconfig index 5daa47b075..ac5c6638b9 100644 --- a/arch/arm/configs/at91sam9261ek_defconfig +++ b/arch/arm/configs/at91sam9261ek_defconfig @@ -38,6 +38,7 @@ CONFIG_CMD_UIMAGE=y # CONFIG_CMD_BOOTU is not set CONFIG_CMD_RESET=y CONFIG_CMD_GO=y +CONFIG_CMD_SPLASH=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y CONFIG_CMD_GPIO=y @@ -51,9 +52,10 @@ CONFIG_CMD_TFTP=y CONFIG_FS_TFTP=y CONFIG_NET_RESOLV=y CONFIG_DRIVER_NET_DM9K=y -# CONFIG_SPI is not set +CONFIG_DRIVER_SPI_ATMEL=y CONFIG_MTD=y # CONFIG_MTD_OOB_DEVICE is not set +CONFIG_MTD_DATAFLASH=y CONFIG_NAND=y # CONFIG_NAND_ECC_HW is not set # CONFIG_NAND_ECC_HW_SYNDROME is not set @@ -63,7 +65,10 @@ CONFIG_UBI=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DFU=y CONFIG_USB_GADGET_SERIAL=y +CONFIG_VIDEO=y +CONFIG_DRIVER_VIDEO_ATMEL=y CONFIG_LED=y CONFIG_LED_GPIO=y CONFIG_LED_TRIGGERS=y CONFIG_KEYBOARD_GPIO=y +CONFIG_PNG=y diff --git a/arch/arm/configs/at91sam9261ek_first_stage_defconfig b/arch/arm/configs/at91sam9261ek_first_stage_defconfig new file mode 100644 index 0000000000..c4bc207ae5 --- /dev/null +++ b/arch/arm/configs/at91sam9261ek_first_stage_defconfig @@ -0,0 +1,71 @@ +CONFIG_ARCH_AT91SAM9261=y +CONFIG_CMD_AT91_BOOT_TEST=y +CONFIG_AT91_LOAD_BAREBOX_SRAM=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x27000 +CONFIG_AEABI=y +# CONFIG_CMD_ARM_CPUINFO is not set +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_PBL_IMAGE=y +CONFIG_MMU=y +CONFIG_EXPERIMENTAL=y +CONFIG_MALLOC_TLSF=y +CONFIG_PROMPT="9261-EK:" +CONFIG_LONGHELP=y +CONFIG_GLOB=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_MENU=y +CONFIG_CONSOLE_ACTIVATE_ALL=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/at91sam9261ek/env" +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_MENU=y +CONFIG_CMD_MENU_MANAGEMENT=y +CONFIG_CMD_PASSWD=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_BOOTM_INITRD=y +CONFIG_CMD_UIMAGE=y +# CONFIG_CMD_BOOTU is not set +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_MTEST=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_LED=y +CONFIG_CMD_LED_TRIGGER=y +CONFIG_NET=y +CONFIG_NET_DHCP=y +CONFIG_NET_NFS=y +CONFIG_NET_PING=y +CONFIG_NET_RESOLV=y +CONFIG_DRIVER_NET_DM9K=y +CONFIG_DRIVER_SPI_ATMEL=y +CONFIG_MTD=y +# CONFIG_MTD_OOB_DEVICE is not set +CONFIG_MTD_DATAFLASH=y +CONFIG_NAND=y +# CONFIG_NAND_ECC_HW is not set +# CONFIG_NAND_ECC_HW_SYNDROME is not set +# CONFIG_NAND_ECC_HW_NONE is not set +CONFIG_NAND_ATMEL=y +CONFIG_UBI=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DFU=y +CONFIG_USB_GADGET_SERIAL=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_LED_TRIGGERS=y +CONFIG_KEYBOARD_GPIO=y +CONFIG_FS_TFTP=y diff --git a/arch/arm/configs/at91sam9263ek_defconfig b/arch/arm/configs/at91sam9263ek_defconfig index 5d440525aa..e78849a4a0 100644 --- a/arch/arm/configs/at91sam9263ek_defconfig +++ b/arch/arm/configs/at91sam9263ek_defconfig @@ -36,6 +36,7 @@ CONFIG_CMD_UIMAGE=y CONFIG_CMD_RESET=y CONFIG_CMD_GO=y CONFIG_CMD_OFTREE=y +CONFIG_CMD_SPLASH=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y CONFIG_CMD_GPIO=y @@ -63,6 +64,8 @@ CONFIG_UBI=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DFU=y CONFIG_USB_GADGET_SERIAL=y +CONFIG_VIDEO=y +CONFIG_DRIVER_VIDEO_ATMEL=y CONFIG_MCI=y CONFIG_MCI_ATMEL=y CONFIG_LED=y @@ -70,3 +73,4 @@ CONFIG_LED_GPIO=y CONFIG_LED_TRIGGERS=y CONFIG_FS_FAT=y CONFIG_FS_FAT_LFN=y +CONFIG_PNG=y diff --git a/arch/arm/configs/at91sam9m10g45ek_defconfig b/arch/arm/configs/at91sam9m10g45ek_defconfig index 0929f8e7b2..1df34f7511 100644 --- a/arch/arm/configs/at91sam9m10g45ek_defconfig +++ b/arch/arm/configs/at91sam9m10g45ek_defconfig @@ -1,10 +1,12 @@ CONFIG_ARCH_AT91SAM9G45=y +CONFIG_MACH_AT91SAM9M10G45EK=y CONFIG_AEABI=y # CONFIG_CMD_ARM_CPUINFO is not set CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_PBL_IMAGE=y CONFIG_MMU=y CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000 +CONFIG_MALLOC_SIZE=0x800000 CONFIG_MALLOC_TLSF=y CONFIG_PROMPT="9M10G45-EK:" CONFIG_LONGHELP=y @@ -29,8 +31,6 @@ CONFIG_CMD_PASSWD=y CONFIG_CMD_ECHO_E=y CONFIG_CMD_LOADB=y CONFIG_CMD_MEMINFO=y -CONFIG_CMD_MTEST=y -CONFIG_CMD_MTEST_ALTERNATIVE=y CONFIG_CMD_FLASH=y CONFIG_CMD_BOOTM_SHOW_TYPE=y CONFIG_CMD_BOOTM_VERBOSE=y @@ -38,13 +38,17 @@ CONFIG_CMD_BOOTM_INITRD=y CONFIG_CMD_BOOTM_OFTREE=y CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y CONFIG_CMD_UIMAGE=y +# CONFIG_CMD_BOOTU is not set CONFIG_CMD_RESET=y CONFIG_CMD_GO=y CONFIG_CMD_OFTREE=y +CONFIG_CMD_MTEST=y +CONFIG_CMD_MTEST_ALTERNATIVE=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y CONFIG_CMD_MAGICVAR=y CONFIG_CMD_MAGICVAR_HELP=y +CONFIG_CMD_SPLASH=y CONFIG_CMD_GPIO=y CONFIG_CMD_UNCOMPRESS=y CONFIG_CMD_LED=y @@ -58,6 +62,8 @@ CONFIG_FS_TFTP=y CONFIG_NET_NETCONSOLE=y CONFIG_NET_RESOLV=y CONFIG_DRIVER_NET_MACB=y +CONFIG_NET_USB=y +CONFIG_NET_USB_ASIX=y # CONFIG_SPI is not set CONFIG_MTD=y CONFIG_NAND=y @@ -66,6 +72,12 @@ CONFIG_NAND=y # CONFIG_NAND_ECC_HW_NONE is not set CONFIG_NAND_ATMEL=y CONFIG_UBI=y +CONFIG_USB=y +CONFIG_USB_EHCI=y +CONFIG_USB_EHCI_ATMEL=y +CONFIG_USB_STORAGE=y +CONFIG_VIDEO=y +CONFIG_DRIVER_VIDEO_ATMEL=y CONFIG_MCI=y CONFIG_MCI_STARTUP=y CONFIG_MCI_ATMEL=y @@ -75,4 +87,4 @@ CONFIG_LED_TRIGGERS=y CONFIG_FS_FAT=y CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y -CONFIG_LZO_DECOMPRESS=y +CONFIG_PNG=y diff --git a/arch/arm/configs/at91sam9m10ihd_defconfig b/arch/arm/configs/at91sam9m10ihd_defconfig new file mode 100644 index 0000000000..2faaa6857d --- /dev/null +++ b/arch/arm/configs/at91sam9m10ihd_defconfig @@ -0,0 +1,99 @@ +CONFIG_ARCH_AT91SAM9G45=y +CONFIG_MACH_AT91SAM9M10IHD=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000 +CONFIG_AEABI=y +# CONFIG_CMD_ARM_CPUINFO is not set +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_PBL_IMAGE=y +CONFIG_MMU=y +CONFIG_MALLOC_SIZE=0xa00000 +CONFIG_MALLOC_TLSF=y +CONFIG_PROMPT="9M10IHD:" +CONFIG_LONGHELP=y +CONFIG_PROMPT_HUSH_PS2=">" +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_MENU=y +CONFIG_PASSWD_SUM_SHA1=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/at91sam9m10ihd/env" +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_MENU=y +CONFIG_CMD_MENU_MANAGEMENT=y +CONFIG_CMD_PASSWD=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_UBIFORMAT=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_BOOTM_AIMAGE=y +CONFIG_CMD_UIMAGE=y +# CONFIG_CMD_BOOTU is not set +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_MTEST=y +CONFIG_CMD_MTEST_ALTERNATIVE=y +CONFIG_CMD_SPLASH=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_MAGICVAR=y +CONFIG_CMD_MAGICVAR_HELP=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_I2C=y +CONFIG_CMD_SPI=y +CONFIG_NET=y +CONFIG_NET_DHCP=y +CONFIG_NET_NFS=y +CONFIG_NET_PING=y +CONFIG_NET_NETCONSOLE=y +CONFIG_NET_RESOLV=y +CONFIG_DRIVER_NET_MACB=y +CONFIG_NET_USB=y +CONFIG_NET_USB_ASIX=y +CONFIG_DRIVER_SPI_ATMEL=y +CONFIG_I2C=y +CONFIG_I2C_GPIO=y +CONFIG_MTD=y +# CONFIG_MTD_OOB_DEVICE is not set +CONFIG_MTD_M25P80=y +CONFIG_NAND=y +# CONFIG_NAND_ECC_HW is not set +# CONFIG_NAND_ECC_HW_SYNDROME is not set +# CONFIG_NAND_ECC_HW_NONE is not set +CONFIG_NAND_ATMEL=y +CONFIG_UBI=y +CONFIG_USB=y +CONFIG_USB_EHCI=y +CONFIG_USB_EHCI_ATMEL=y +CONFIG_USB_STORAGE=y +CONFIG_VIDEO=y +CONFIG_DRIVER_VIDEO_ATMEL=y +CONFIG_MCI=y +CONFIG_MCI_STARTUP=y +CONFIG_MCI_ATMEL=y +CONFIG_EEPROM_AT24=y +CONFIG_KEYBOARD_QT1070=y +CONFIG_W1=y +CONFIG_W1_MASTER_GPIO=y +CONFIG_W1_SLAVE_DS2431=y +CONFIG_W1_SLAVE_DS2433=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/configs/at91sam9n12ek_defconfig b/arch/arm/configs/at91sam9n12ek_defconfig index d46a9bd258..3e3bd51098 100644 --- a/arch/arm/configs/at91sam9n12ek_defconfig +++ b/arch/arm/configs/at91sam9n12ek_defconfig @@ -6,6 +6,7 @@ CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_PBL_IMAGE=y CONFIG_MMU=y CONFIG_TEXT_BASE=0x26f00000 +CONFIG_MALLOC_SIZE=0xa00000 CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000 CONFIG_EXPERIMENTAL=y CONFIG_MALLOC_TLSF=y @@ -41,6 +42,7 @@ CONFIG_CMD_GO=y CONFIG_CMD_OFTREE=y CONFIG_CMD_MTEST=y CONFIG_CMD_MTEST_ALTERNATIVE=y +CONFIG_CMD_SPLASH=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y CONFIG_CMD_GPIO=y @@ -71,6 +73,8 @@ CONFIG_UBI=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DFU=y CONFIG_USB_GADGET_SERIAL=y +CONFIG_VIDEO=y +CONFIG_DRIVER_VIDEO_ATMEL_HLCD=y CONFIG_MCI=y CONFIG_MCI_STARTUP=y CONFIG_MCI_ATMEL=y @@ -84,4 +88,4 @@ CONFIG_FS_TFTP=y CONFIG_FS_FAT=y CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y -CONFIG_ZLIB=y +CONFIG_PNG=y diff --git a/arch/arm/configs/at91sam9x5ek_defconfig b/arch/arm/configs/at91sam9x5ek_defconfig index 0df86310ab..d2cdaf279c 100644 --- a/arch/arm/configs/at91sam9x5ek_defconfig +++ b/arch/arm/configs/at91sam9x5ek_defconfig @@ -4,6 +4,7 @@ CONFIG_AEABI=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_PBL_IMAGE=y CONFIG_MMU=y +CONFIG_MALLOC_SIZE=0xa00000 CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000 CONFIG_EXPERIMENTAL=y CONFIG_MALLOC_TLSF=y @@ -40,6 +41,7 @@ CONFIG_CMD_GO=y CONFIG_CMD_OFTREE=y CONFIG_CMD_MTEST=y CONFIG_CMD_MTEST_ALTERNATIVE=y +CONFIG_CMD_SPLASH=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y CONFIG_CMD_GPIO=y @@ -52,6 +54,8 @@ CONFIG_NET_NFS=y CONFIG_NET_PING=y CONFIG_NET_NETCONSOLE=y CONFIG_DRIVER_NET_MACB=y +CONFIG_NET_USB=y +CONFIG_NET_USB_ASIX=y CONFIG_DRIVER_SPI_ATMEL=y CONFIG_MTD_M25P80=y CONFIG_I2C=y @@ -66,6 +70,10 @@ CONFIG_NAND=y CONFIG_NAND_ATMEL=y CONFIG_NAND_ATMEL_PMECC=y CONFIG_UBI=y +CONFIG_USB=y +CONFIG_USB_EHCI=y +CONFIG_USB_EHCI_ATMEL=y +CONFIG_USB_STORAGE=y CONFIG_MCI=y CONFIG_MCI_STARTUP=y CONFIG_MCI_ATMEL=y @@ -83,4 +91,4 @@ CONFIG_FS_TFTP=y CONFIG_FS_FAT=y CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y -CONFIG_ZLIB=y +CONFIG_PNG=y diff --git a/arch/arm/configs/ccmx51_defconfig b/arch/arm/configs/ccmx51_defconfig index d14de556b3..67d1dd29c4 100644 --- a/arch/arm/configs/ccmx51_defconfig +++ b/arch/arm/configs/ccmx51_defconfig @@ -2,54 +2,60 @@ CONFIG_ARCH_IMX=y CONFIG_ARCH_IMX51=y CONFIG_MACH_CCMX51=y CONFIG_AEABI=y +CONFIG_CMD_ARM_MMUINFO=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_MMU=y CONFIG_MALLOC_SIZE=0x2000000 CONFIG_LONGHELP=y CONFIG_GLOB=y CONFIG_HUSH_FANCY_PROMPT=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y -CONFIG_PARTITION=y +CONFIG_DEFAULT_ENVIRONMENT_COMPRESSED_LZO=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/ccxmx51/env" CONFIG_CMD_EDIT=y CONFIG_CMD_SLEEP=y CONFIG_CMD_SAVEENV=y -CONFIG_CMD_LOADENV=y CONFIG_CMD_EXPORT=y CONFIG_CMD_PRINTENV=y CONFIG_CMD_READLINE=y CONFIG_CMD_ECHO_E=y CONFIG_CMD_MEMINFO=y -CONFIG_CMD_MTEST=y CONFIG_CMD_FLASH=y -CONFIG_CMD_BOOTM_ZLIB=y -CONFIG_CMD_BOOTM_BZLIB=y CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_BOOTZ=y CONFIG_CMD_RESET=y CONFIG_CMD_GO=y +CONFIG_CMD_NANDTEST=y +CONFIG_CMD_MTEST=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y +CONFIG_CMD_MAGICVAR=y +CONFIG_CMD_MAGICVAR_HELP=y CONFIG_CMD_GPIO=y -CONFIG_CMD_UNLZO=y CONFIG_CMD_I2C=y +CONFIG_CMD_SPI=y +CONFIG_CMD_CLK=y CONFIG_NET=y CONFIG_NET_DHCP=y CONFIG_NET_PING=y -CONFIG_NET_TFTP=y CONFIG_DRIVER_NET_SMC911X=y CONFIG_DRIVER_NET_FEC_IMX=y -CONFIG_DRIVER_SPI_IMX=y CONFIG_I2C=y CONFIG_I2C_IMX=y CONFIG_MTD=y CONFIG_NAND=y CONFIG_NAND_IMX=y CONFIG_USB=y +CONFIG_USB_IMX_CHIPIDEA=y CONFIG_USB_EHCI=y +CONFIG_USB_ULPI=y +CONFIG_USB_STORAGE=y CONFIG_MCI=y -# CONFIG_MCI_WRITE is not set CONFIG_MCI_IMX_ESDHC=y CONFIG_FS_CRAMFS=y CONFIG_FS_FAT=y +CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y +CONFIG_LZO_DECOMPRESS=y diff --git a/arch/arm/configs/eukrea_cpuimx51_defconfig b/arch/arm/configs/eukrea_cpuimx51_defconfig index e4ec7b0a7d..3f5d817625 100644 --- a/arch/arm/configs/eukrea_cpuimx51_defconfig +++ b/arch/arm/configs/eukrea_cpuimx51_defconfig @@ -50,7 +50,6 @@ CONFIG_NET_DHCP=y CONFIG_NET_NFS=y CONFIG_NET_PING=y CONFIG_CMD_TFTP=y -CONFIG_FS_TFTP=y CONFIG_NET_NETCONSOLE=y CONFIG_NET_RESOLV=y CONFIG_DRIVER_NET_FEC_IMX=y diff --git a/arch/arm/configs/pcm027_defconfig b/arch/arm/configs/pcm027_defconfig index e08955b52b..ac9269d3c7 100644 --- a/arch/arm/configs/pcm027_defconfig +++ b/arch/arm/configs/pcm027_defconfig @@ -57,5 +57,4 @@ CONFIG_DRIVER_NET_SMC91111=y CONFIG_DRIVER_CFI=y CONFIG_VIDEO=y CONFIG_DRIVER_VIDEO_PXA=y -CONFIG_FS_TFTP=y CONFIG_LZO_DECOMPRESS=y diff --git a/arch/arm/configs/sama5d3xek_defconfig b/arch/arm/configs/sama5d3xek_defconfig new file mode 100644 index 0000000000..970ded52ca --- /dev/null +++ b/arch/arm/configs/sama5d3xek_defconfig @@ -0,0 +1,95 @@ +CONFIG_ARCH_SAMA5D3=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x60000 +CONFIG_AEABI=y +# CONFIG_CMD_ARM_CPUINFO is not set +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="A5D3X-EK:" +CONFIG_LONGHELP=y +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/sama5d3xek/env" +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_FILETYPE=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_FLASH=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_UIMAGE=y +# CONFIG_CMD_BOOTU is not set +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_MTEST=y +CONFIG_CMD_MTEST_ALTERNATIVE=y +CONFIG_CMD_SPLASH=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_SPI=y +CONFIG_CMD_LED=y +CONFIG_CMD_LED_TRIGGER=y +CONFIG_CMD_MIITOOL=y +CONFIG_NET=y +CONFIG_NET_DHCP=y +CONFIG_NET_NFS=y +CONFIG_NET_PING=y +CONFIG_NET_NETCONSOLE=y +CONFIG_MICREL_PHY=y +CONFIG_DRIVER_NET_MACB=y +CONFIG_DRIVER_SPI_ATMEL=y +CONFIG_I2C=y +CONFIG_I2C_GPIO=y +CONFIG_MTD=y +# CONFIG_MTD_OOB_DEVICE is not set +CONFIG_MTD_M25P80=y +CONFIG_NAND=y +# CONFIG_NAND_ECC_SOFT is not set +# CONFIG_NAND_ECC_HW_SYNDROME is not set +# CONFIG_NAND_ECC_HW_NONE is not set +CONFIG_NAND_ATMEL=y +CONFIG_NAND_ATMEL_PMECC=y +CONFIG_UBI=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_W1=y +CONFIG_W1_MASTER_GPIO=y +CONFIG_W1_SLAVE_DS2431=y +CONFIG_W1_SLAVE_DS2433=y +CONFIG_W1_DUAL_SEARCH=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/configs/telit_evk_pro3_defconfig b/arch/arm/configs/telit_evk_pro3_defconfig new file mode 100644 index 0000000000..050d1763b3 --- /dev/null +++ b/arch/arm/configs/telit_evk_pro3_defconfig @@ -0,0 +1,73 @@ +CONFIG_ARCH_AT91SAM9260=y +CONFIG_MACH_GE863=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000 +CONFIG_AEABI=y +# CONFIG_CMD_ARM_CPUINFO is not set +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_PBL_IMAGE=y +CONFIG_MMU=y +CONFIG_EXPERIMENTAL=y +CONFIG_PROMPT="EVK-PRO3:" +CONFIG_LONGHELP=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_NEW=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/telit-evk-pro3/env" +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_LOADB=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_UBIFORMAT=y +CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_BOOTM_INITRD=y +CONFIG_CMD_BOOTM_OFTREE=y +CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y +CONFIG_CMD_UIMAGE=y +# CONFIG_CMD_BOOTU is not set +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_MTEST=y +CONFIG_CMD_MTEST_ALTERNATIVE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_LED=y +CONFIG_CMD_LED_TRIGGER=y +CONFIG_NET=y +CONFIG_NET_DHCP=y +CONFIG_NET_NFS=y +CONFIG_NET_PING=y +CONFIG_NET_NETCONSOLE=y +CONFIG_DRIVER_NET_MACB=y +# CONFIG_SPI is not set +CONFIG_MTD=y +# CONFIG_MTD_OOB_DEVICE is not set +CONFIG_NAND=y +# CONFIG_NAND_ECC_HW is not set +# CONFIG_NAND_ECC_HW_SYNDROME is not set +# CONFIG_NAND_ECC_HW_NONE is not set +CONFIG_NAND_ATMEL=y +CONFIG_UBI=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DFU=y +CONFIG_USB_GADGET_SERIAL=y +CONFIG_MCI=y +CONFIG_MCI_STARTUP=y +CONFIG_MCI_ATMEL=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_LED_TRIGGERS=y +CONFIG_FS_TFTP=y +CONFIG_FS_FAT=y +CONFIG_FS_FAT_LFN=y diff --git a/arch/arm/configs/tny_a9263_bootstrap_defconfig b/arch/arm/configs/tny_a9263_bootstrap_defconfig new file mode 100644 index 0000000000..d968b6f00f --- /dev/null +++ b/arch/arm/configs/tny_a9263_bootstrap_defconfig @@ -0,0 +1,26 @@ +CONFIG_ARCH_AT91SAM9263=y +CONFIG_MACH_TNY_A9263=y +CONFIG_AT91_BOOTSTRAP=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x12000 +CONFIG_AEABI=y +# CONFIG_CMD_ARM_CPUINFO is not set +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_ENVIRONMENT_VARIABLES=y +CONFIG_PBL_IMAGE=y +CONFIG_MMU=y +CONFIG_MALLOC_DUMMY=y +CONFIG_PROMPT="USB-9263:" +CONFIG_SHELL_NONE=y +CONFIG_CONSOLE_SIMPLE=y +# CONFIG_DEFAULT_ENVIRONMENT is not set +# CONFIG_SPI is not set +CONFIG_MTD=y +# CONFIG_MTD_WRITE is not set +# CONFIG_MTD_OOB_DEVICE is not set +CONFIG_NAND=y +# CONFIG_NAND_ECC_HW is not set +# CONFIG_NAND_ECC_HW_SYNDROME is not set +# CONFIG_NAND_ECC_HW_NONE is not set +CONFIG_NAND_ATMEL=y +# CONFIG_FS_RAMFS is not set +CONFIG_BOOTSTRAP_DEVFS=y diff --git a/arch/arm/configs/tny_a9263_defconfig b/arch/arm/configs/tny_a9263_defconfig index c199cca554..652fd3d453 100644 --- a/arch/arm/configs/tny_a9263_defconfig +++ b/arch/arm/configs/tny_a9263_defconfig @@ -62,6 +62,7 @@ CONFIG_DRIVER_NET_MACB=y CONFIG_DRIVER_SPI_ATMEL=y CONFIG_MTD=y # CONFIG_MTD_OOB_DEVICE is not set +CONFIG_MTD_DATAFLASH=y CONFIG_NAND=y # CONFIG_NAND_ECC_HW is not set # CONFIG_NAND_ECC_HW_SYNDROME is not set diff --git a/arch/arm/configs/tx25stk5_defconfig b/arch/arm/configs/tx25stk5_defconfig index 8ec5178cce..365a940271 100644 --- a/arch/arm/configs/tx25stk5_defconfig +++ b/arch/arm/configs/tx25stk5_defconfig @@ -1,58 +1,71 @@ CONFIG_ARCH_IMX=y +CONFIG_ARCH_IMX_EXTERNAL_BOOT=y +CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND=y CONFIG_ARCH_IMX25=y CONFIG_MACH_TX25=y CONFIG_IMX_IIM=y CONFIG_AEABI=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_ARM_UNWIND=y +CONFIG_PBL_IMAGE=y CONFIG_MMU=y +CONFIG_TEXT_BASE=0x91d00000 CONFIG_MALLOC_SIZE=0x1000000 CONFIG_MALLOC_TLSF=y CONFIG_KALLSYMS=y CONFIG_LONGHELP=y -CONFIG_GLOB=y CONFIG_HUSH_FANCY_PROMPT=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y -CONFIG_PARTITION=y -CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/karo-tx25/env" +CONFIG_RESET_SOURCE=y CONFIG_CMD_EDIT=y CONFIG_CMD_SLEEP=y +CONFIG_CMD_MSLEEP=y CONFIG_CMD_SAVEENV=y -CONFIG_CMD_LOADENV=y CONFIG_CMD_EXPORT=y CONFIG_CMD_PRINTENV=y CONFIG_CMD_READLINE=y CONFIG_CMD_TIME=y +CONFIG_CMD_DIRNAME=y +CONFIG_CMD_LN=y +CONFIG_CMD_READLINK=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_FILETYPE=y CONFIG_CMD_ECHO_E=y CONFIG_CMD_MEMINFO=y CONFIG_CMD_IOMEM=y -CONFIG_CMD_MTEST=y -CONFIG_CMD_MTEST_ALTERNATIVE=y +CONFIG_CMD_CRC=y +CONFIG_CMD_CRC_CMP=y +CONFIG_CMD_MD5SUM=y CONFIG_CMD_FLASH=y +CONFIG_CMD_UBIFORMAT=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_UIMAGE=y -# CONFIG_CMD_BOOTZ is not set # CONFIG_CMD_BOOTU is not set CONFIG_CMD_RESET=y CONFIG_CMD_GO=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_OFTREE_PROBE=y +CONFIG_CMD_MTEST=y +CONFIG_CMD_MTEST_ALTERNATIVE=y +CONFIG_CMD_SPLASH=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y CONFIG_CMD_MAGICVAR=y CONFIG_CMD_MAGICVAR_HELP=y -CONFIG_CMD_SPLASH=y CONFIG_CMD_GPIO=y CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_MIITOOL=y +CONFIG_CMD_CLK=y CONFIG_NET=y CONFIG_NET_DHCP=y CONFIG_NET_PING=y -CONFIG_CMD_TFTP=y -CONFIG_FS_TFTP=y CONFIG_NET_NETCONSOLE=y CONFIG_DRIVER_NET_FEC_IMX=y # CONFIG_SPI is not set @@ -62,5 +75,14 @@ CONFIG_NAND_IMX=y CONFIG_UBI=y CONFIG_VIDEO=y CONFIG_DRIVER_VIDEO_IMX=y +CONFIG_MCI=y +CONFIG_MCI_IMX_ESDHC=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_IMX=y +CONFIG_FS_TFTP=y +CONFIG_FS_NFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FAT_WRITE=y +CONFIG_FS_FAT_LFN=y CONFIG_ZLIB=y CONFIG_LZO_DECOMPRESS=y diff --git a/arch/arm/configs/usb_a9263_128mib_bootstrap_defconfig b/arch/arm/configs/usb_a9263_128mib_bootstrap_defconfig new file mode 100644 index 0000000000..0411bd8057 --- /dev/null +++ b/arch/arm/configs/usb_a9263_128mib_bootstrap_defconfig @@ -0,0 +1,27 @@ +CONFIG_ARCH_AT91SAM9263=y +CONFIG_MACH_USB_A9263=y +CONFIG_AT91_HAVE_SRAM_128M=y +CONFIG_AT91_BOOTSTRAP=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x12000 +CONFIG_AEABI=y +# CONFIG_CMD_ARM_CPUINFO is not set +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_ENVIRONMENT_VARIABLES=y +CONFIG_PBL_IMAGE=y +CONFIG_MMU=y +CONFIG_MALLOC_DUMMY=y +CONFIG_PROMPT="USB-9263:" +CONFIG_SHELL_NONE=y +# CONFIG_CONSOLE_FULL is not set +# CONFIG_DEFAULT_ENVIRONMENT is not set +# CONFIG_SPI is not set +CONFIG_MTD=y +# CONFIG_MTD_WRITE is not set +# CONFIG_MTD_OOB_DEVICE is not set +CONFIG_NAND=y +# CONFIG_NAND_ECC_HW is not set +# CONFIG_NAND_ECC_HW_SYNDROME is not set +# CONFIG_NAND_ECC_HW_NONE is not set +CONFIG_NAND_ATMEL=y +# CONFIG_FS_RAMFS is not set +CONFIG_BOOTSTRAP_DEVFS=y diff --git a/arch/arm/configs/usb_a9263_bootstrap_defconfig b/arch/arm/configs/usb_a9263_bootstrap_defconfig new file mode 100644 index 0000000000..78c1c8f7be --- /dev/null +++ b/arch/arm/configs/usb_a9263_bootstrap_defconfig @@ -0,0 +1,26 @@ +CONFIG_ARCH_AT91SAM9263=y +CONFIG_MACH_USB_A9263=y +CONFIG_AT91_BOOTSTRAP=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x12000 +CONFIG_AEABI=y +# CONFIG_CMD_ARM_CPUINFO is not set +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_ENVIRONMENT_VARIABLES=y +CONFIG_PBL_IMAGE=y +CONFIG_MMU=y +CONFIG_MALLOC_DUMMY=y +CONFIG_PROMPT="USB-9263:" +CONFIG_SHELL_NONE=y +# CONFIG_CONSOLE_FULL is not set +# CONFIG_DEFAULT_ENVIRONMENT is not set +# CONFIG_SPI is not set +CONFIG_MTD=y +# CONFIG_MTD_WRITE is not set +# CONFIG_MTD_OOB_DEVICE is not set +CONFIG_NAND=y +# CONFIG_NAND_ECC_HW is not set +# CONFIG_NAND_ECC_HW_SYNDROME is not set +# CONFIG_NAND_ECC_HW_NONE is not set +CONFIG_NAND_ATMEL=y +# CONFIG_FS_RAMFS is not set +CONFIG_BOOTSTRAP_DEVFS=y diff --git a/arch/arm/cpu/cache-armv7.S b/arch/arm/cpu/cache-armv7.S index 2d68f27eeb..13542d9d0a 100644 --- a/arch/arm/cpu/cache-armv7.S +++ b/arch/arm/cpu/cache-armv7.S @@ -34,6 +34,7 @@ ENDPROC(v7_mmu_cache_on) .section .text.v7_mmu_cache_off ENTRY(v7_mmu_cache_off) + stmfd sp!, {r0-r7, r9-r11} mrc p15, 0, r0, c1, c0 #ifdef CONFIG_MMU bic r0, r0, #0x000d @@ -50,6 +51,7 @@ ENTRY(v7_mmu_cache_off) mcr p15, 0, r0, c7, c5, 6 @ invalidate BTC mcr p15, 0, r0, c7, c10, 4 @ DSB mcr p15, 0, r0, c7, c5, 4 @ ISB + ldmfd sp!, {r0-r7, r9-r11} mov pc, r12 ENDPROC(v7_mmu_cache_off) diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c index 7b5f4eeebb..8f9a43e040 100644 --- a/arch/arm/cpu/mmu.c +++ b/arch/arm/cpu/mmu.c @@ -1,3 +1,24 @@ +/* + * start-pbl.c + * + * Copyright (c) 2009-2013 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#define pr_fmt(fmt) "mmu: " fmt + #include <common.h> #include <init.h> #include <asm/mmu.h> @@ -152,7 +173,7 @@ static int arm_mmu_remap_sdram(struct memory_bank *bank) int i, pte; u32 *ptes; - debug("remapping SDRAM from 0x%08lx (size 0x%08lx)\n", + pr_debug("remapping SDRAM from 0x%08lx (size 0x%08lx)\n", phys, bank->size); /* @@ -164,7 +185,7 @@ static int arm_mmu_remap_sdram(struct memory_bank *bank) ptes = xmemalign(PAGE_SIZE, num_ptes * sizeof(u32)); - debug("ptes: 0x%p ttb_start: 0x%08lx ttb_end: 0x%08lx\n", + pr_debug("ptes: 0x%p ttb_start: 0x%08lx ttb_end: 0x%08lx\n", ptes, ttb_start, ttb_end); for (i = 0; i < num_ptes; i++) { @@ -257,7 +278,7 @@ static int mmu_init(void) ttb = memalign(0x10000, 0x4000); - debug("ttb: 0x%p\n", ttb); + pr_debug("ttb: 0x%p\n", ttb); /* Set the ttb register */ asm volatile ("mcr p15,0,%0,c2,c0,0" : : "r"(ttb) /*:*/); diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index fcba7fb94b..14bab550c3 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -18,10 +18,18 @@ config SOC_AT91SAM9 select AT91SAM9_SMC select AT91SAM9_TIMER +config SOC_SAMA5 + bool + select CPU_V7 + select AT91SAM9_SMC + select AT91SAM9_TIMER + config ARCH_TEXT_BASE hex default 0x73f00000 if ARCH_AT91SAM9G45 default 0x26f00000 if ARCH_AT91SAM9X5 + default 0x20f00000 if ARCH_AT91RM9200 + default 0x21f00000 if MACH_ANIMEO_IP default 0x23f00000 config BOARDINFO @@ -31,9 +39,11 @@ config BOARDINFO default "Atmel at91sam9263-ek" if MACH_AT91SAM9263EK default "Atmel at91sam9g10-ek" if MACH_AT91SAM9G10EK default "Atmel at91sam9g20-ek" if MACH_AT91SAM9G20EK + default "Atmel at91sam9m10ihd" if MACH_AT91SAM9M10IHD default "Atmel at91sam9m10g45-ek" if MACH_AT91SAM9M10G45EK default "Atmel at91sam9n12-ek" if MACH_AT91SAM9N12EK default "Atmel at91sam9x5-ek" if MACH_AT91SAM9X5EK + default "Atmel sama5d3x-ek" if MACH_SAMA5D3XEK default "Bucyrus MMC-CPU" if MACH_MMCCPU default "Calao USB-A9260" if MACH_USB_A9260 default "Calao USB-A9263" if MACH_USB_A9263 @@ -46,6 +56,8 @@ config BOARDINFO default "Calao TNY-A9263" if MACH_TNY_A9263 default "Calao TNY-A9G20" if MACH_TNY_A9G20 default "Calao QIL-A9260" if MACH_QIL_A9260 + default "Somfy Animeo IP" if MACH_ANIMEO_IP + default "Telit EVK-PRO3" if MACH_GE863 config HAVE_NAND_ATMEL_BUSWIDTH_16 bool @@ -59,6 +71,12 @@ config AT91SAM9_RESET config AT91SAM9G45_RESET bool +config HAVE_AT91_LOAD_BAREBOX_SRAM + bool + +config AT91SAM9_LOWLEVEL_INIT + bool + comment "Atmel AT91 System-on-Chip" config SOC_AT91RM9200 @@ -74,6 +92,7 @@ config SOC_AT91SAM9260 select HAVE_AT91_DBGU0 select HAS_MACB select AT91SAM9_RESET + select AT91SAM9_LOWLEVEL_INIT help Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE or AT91SAM9G20 SoC. @@ -83,6 +102,7 @@ config SOC_AT91SAM9261 select SOC_AT91SAM9 select HAVE_AT91_DBGU0 select AT91SAM9_RESET + select AT91SAM9_LOWLEVEL_INIT help Select this if you are using one of Atmel's AT91SAM9261 or AT91SAM9G10 SoC. @@ -92,6 +112,8 @@ config SOC_AT91SAM9263 select HAVE_AT91_DBGU1 select HAS_MACB select AT91SAM9_RESET + select AT91SAM9_LOWLEVEL_INIT + select HAVE_AT91_LOAD_BAREBOX_SRAM config SOC_AT91SAM9G45 bool @@ -139,6 +161,7 @@ config ARCH_AT91SAM9260 config ARCH_AT91SAM9261 bool "AT91SAM9261" select SOC_AT91SAM9261 + select HAVE_AT91_LOAD_BAREBOX_SRAM config ARCH_AT91SAM9263 bool "AT91SAM9263" @@ -164,18 +187,26 @@ config ARCH_AT91SAM9N12 bool "AT91SAM9N12" select SOC_AT91SAM9N12 +config ARCH_SAMA5D3 + bool "SAMA5D3x" + select SOC_SAMA5 + select HAVE_AT91_DBGU1 + select HAS_MACB + select AT91SAM9G45_RESET + endchoice config ARCH_BAREBOX_MAX_BARE_INIT_SIZE hex default 0x1000 if ARCH_AT91SAM9260 - default 0x270000 if ARCH_AT91SAM9261 + default 0x27000 if ARCH_AT91SAM9261 default 0x12000 if ARCH_AT91SAM9263 default 0x4000 if ARCH_AT91SAM9G20 default 0x3000 if ARCH_AT91SAM9G10 default 0xF000 if ARCH_AT91SAM9G45 default 0x6000 if ARCH_AT91SAM9X5 default 0x6000 if ARCH_AT91SAM9N12 + default 0x6000 if ARCH_SAMA5D3 default 0xffffffff config SUPPORT_CALAO_DAB_MMX @@ -209,6 +240,9 @@ if ARCH_AT91SAM9260 choice prompt "AT91SAM9260 Board Type" +config MACH_ANIMEO_IP + bool "Somfy Animeo IP" + config MACH_AT91SAM9260EK bool "Atmel AT91SAM9260-EK" select HAVE_NAND_ATMEL_BUSWIDTH_16 @@ -235,6 +269,13 @@ config MACH_USB_A9260 Select this if you are using a Calao Systems USB-A9260. <http://www.calao-systems.com> +config MACH_GE863 + bool "Telit EVK-PRO3" + select HAVE_DEFAULT_ENVIRONMENT_NEW + help + Say y here if you are using Telit EVK-PRO3 with GE863-PRO3 + <http://www.telit.com> + endchoice endif @@ -249,6 +290,8 @@ choice config MACH_AT91SAM9261EK bool "Atmel AT91SAM9261-EK Evaluation Kit" select HAS_DM9000 + select HAVE_AT91_DATAFLASH_CARD + select MACH_HAS_LOWLEVEL_INIT select HAVE_NAND_ATMEL_BUSWIDTH_16 help Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit. @@ -351,12 +394,14 @@ config MACH_PM9263 config MACH_TNY_A9263 bool "CALAO TNY-A9263" select SUPPORT_CALAO_MOB_TNY_MD2 + select MACH_HAS_LOWLEVEL_INIT help Select this if you are using a Calao Systems TNY-A9263. <http://www.calao-systems.com> config MACH_USB_A9263 bool "CALAO USB-A9263" + select MACH_HAS_LOWLEVEL_INIT help Select this if you are using a Calao Systems USB-A9263. <http://www.calao-systems.com> @@ -370,6 +415,11 @@ if ARCH_AT91SAM9G45 choice prompt "AT91SAM9G45 or AT91SAM9M10 Board Type" +config MACH_AT91SAM9M10IHD + bool "Atmel AT91SAM9M10IDH Tablet" + help + Select this if you are using Atmel's AT91SAM9M10IHD Tablet + config MACH_AT91SAM9M10G45EK bool "Atmel AT91SAM9M10G45-EK Evaluation Kit" select HAVE_NAND_ATMEL_BUSWIDTH_16 @@ -422,6 +472,22 @@ endif # ---------------------------------------------------------- +if ARCH_SAMA5D3 + +choice + prompt "SAMA5D3 Board Type" + +config MACH_SAMA5D3XEK + bool "Atmel SAMA5D3X Evaluation Kit" + help + Select this if you are using Atmel's SAMA5D3X-EK Evaluation Kit. + +endchoice + +endif + +# ---------------------------------------------------------- + comment "AT91 Board Options" config MTD_AT91_DATAFLASH_CARD @@ -479,8 +545,33 @@ config CALAO_MB_QIL_A9260 bool "MB-QIL A9260 Motherboard Board support" depends on MACH_QIL_A9260 +if COMMAND_SUPPORT + config CMD_AT91MUX bool "at91mux dump command" default y +config CMD_AT91CLK + bool "at91clk dump command" + default y + +config CMD_AT91_BOOT_TEST + bool "at91_boot_test" + help + allow to upload a boot binary to sram and execute it + useful to test bootstrap or barebox lowlevel init + +endif + +config AT91_BOOTSTRAP + bool "at91 bootstrap" + depends on MACH_HAS_LOWLEVEL_INIT + select BOOTSTRAP + +config AT91_LOAD_BAREBOX_SRAM + bool "at91 laad barebox in sram" + depends on MACH_HAS_LOWLEVEL_INIT + depends on SHELL_NONE || HAVE_AT91_LOAD_BAREBOX_SRAM + default y if SHELL_NONE + endif diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 53b4dd89ab..f6c8500840 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -1,6 +1,11 @@ obj-y += setup.o clock.o gpio.o +obj-$(CONFIG_CMD_AT91_BOOT_TEST) += boot_test_cmd.o -lowlevel_init-y = at91sam926x_lowlevel_init.o +obj-$(CONFIG_AT91_BOOTSTRAP) += bootstrap.o +lowlevel_init-$(CONFIG_AT91SAM9_LOWLEVEL_INIT) = at91sam926x_lowlevel_init.o +lowlevel_init-$(CONFIG_SOC_AT91SAM9260) += at91sam9260_lowlevel_init.o +lowlevel_init-$(CONFIG_SOC_AT91SAM9261) += at91sam9261_lowlevel_init.o +lowlevel_init-$(CONFIG_SOC_AT91SAM9263) += at91sam9263_lowlevel_init.o lowlevel_init-$(CONFIG_ARCH_AT91RM9200) = at91rm9200_lowlevel_init.o obj-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += $(lowlevel_init-y) @@ -22,3 +27,4 @@ obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam9260_devices.o 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 diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 4109172a5f..82862d7c3b 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -25,6 +25,9 @@ void at91_add_device_sdram(u32 size) { + if (!size) + size = at91rm9200_get_sdram_size(); + arm_add_mem_device("ram0", AT91_CHIPSELECT_1, size); add_mem_device("sram0", AT91RM9200_SRAM_BASE, AT91RM9200_SRAM_SIZE, IORESOURCE_MEM_WRITEABLE); @@ -37,9 +40,18 @@ void at91_add_device_sdram(u32 size) #if defined(CONFIG_USB_OHCI) void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) { + int i; + if (!data) return; + /* Enable VBus control for UHP ports */ + for (i = 0; i < data->ports; i++) { + if (gpio_is_valid(data->vbus_pin[i])) + at91_set_gpio_output(data->vbus_pin[i], + data->vbus_pin_active_low[i]); + } + add_generic_device("at91_ohci", DEVICE_ID_DYNAMIC, NULL, AT91RM9200_UHP_BASE, 1024 * 1024, IORESOURCE_MEM, data); } @@ -91,7 +103,7 @@ void __init at91_add_device_eth(int id, struct at91_ether_platform_data *data) at91_set_A_periph(AT91_PIN_PA8, 0); /* ETXEN */ at91_set_A_periph(AT91_PIN_PA7, 0); /* ETXCK_EREFCK */ - if (!data->is_rmii) { + if (data->phy_interface != PHY_INTERFACE_MODE_RMII) { at91_set_B_periph(AT91_PIN_PB19, 0); /* ERXCK */ at91_set_B_periph(AT91_PIN_PB18, 0); /* ECOL */ at91_set_B_periph(AT91_PIN_PB17, 0); /* ERXDV */ diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index a893a9581a..6e8c37b141 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -42,9 +42,18 @@ void at91_add_device_sdram(u32 size) #if defined(CONFIG_USB_OHCI) void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) { + int i; + if (!data) return; + /* Enable VBus control for UHP ports */ + for (i = 0; i < data->ports; i++) { + if (gpio_is_valid(data->vbus_pin[i])) + at91_set_gpio_output(data->vbus_pin[i], + data->vbus_pin_active_low[i]); + } + add_generic_device("at91_ohci", DEVICE_ID_DYNAMIC, NULL, AT91SAM9260_UHP_BASE, 1024 * 1024, IORESOURCE_MEM, data); } @@ -89,7 +98,7 @@ void at91_add_device_eth(int id, struct at91_ether_platform_data *data) at91_set_A_periph(AT91_PIN_PA21, 0); /* EMDIO */ at91_set_A_periph(AT91_PIN_PA20, 0); /* EMDC */ - if (!data->is_rmii) { + if (data->phy_interface != PHY_INTERFACE_MODE_RMII) { at91_set_B_periph(AT91_PIN_PA28, 0); /* ECRS */ at91_set_B_periph(AT91_PIN_PA29, 0); /* ECOL */ at91_set_B_periph(AT91_PIN_PA25, 0); /* ERX2 */ diff --git a/arch/arm/mach-at91/at91sam9260_lowlevel_init.c b/arch/arm/mach-at91/at91sam9260_lowlevel_init.c new file mode 100644 index 0000000000..c2cf8bfcb5 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9260_lowlevel_init.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2009-2013 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#define __LOWLEVEL_INIT__ + +#include <common.h> +#include <asm/system.h> +#include <asm/barebox-arm.h> +#include <asm/barebox-arm-head.h> +#include <mach/hardware.h> +#include <mach/at91_pmc.h> +#include <mach/at91_pio.h> +#include <mach/at91_rstc.h> +#include <mach/at91_wdt.h> +#include <mach/at91sam9_matrix.h> +#include <mach/at91sam9_sdramc.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91_lowlevel_init.h> +#include <mach/io.h> +#include <init.h> +#include <sizes.h> + +void __naked __bare_init reset(void) +{ + common_reset(); + + arm_setup_stack(AT91SAM9260_SRAM_BASE + AT91SAM9260_SRAM_SIZE - 16); + + at91sam926x_lowlevel_init(IOMEM(AT91SAM9260_BASE_PIOC), false, + AT91_MATRIX_EBICSA); +} diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index becd25f376..e9ca51c820 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -45,9 +45,18 @@ void at91_add_device_sdram(u32 size) #if defined(CONFIG_USB_OHCI) void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) { + int i; + if (!data) return; + /* Enable VBus control for UHP ports */ + for (i = 0; i < data->ports; i++) { + if (gpio_is_valid(data->vbus_pin[i])) + at91_set_gpio_output(data->vbus_pin[i], + data->vbus_pin_active_low[i]); + } + add_generic_device("at91_ohci", DEVICE_ID_DYNAMIC, NULL, AT91SAM9261_UHP_BASE, 1024 * 1024, IORESOURCE_MEM, data); } @@ -199,6 +208,59 @@ void at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata) void __init at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata) {} #endif +/* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_DRIVER_VIDEO_ATMEL) +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) +{ + BUG_ON(!data); + + data->have_intensity_bit = true; + +#if defined(CONFIG_FB_ATMEL_STN) + at91_set_A_periph(AT91_PIN_PB0, 0); /* LCDVSYNC */ + at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ + at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */ + at91_set_A_periph(AT91_PIN_PB5, 0); /* LCDD0 */ + at91_set_A_periph(AT91_PIN_PB6, 0); /* LCDD1 */ + at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */ +#else + at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ + at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */ + at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PB9, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PB10, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PB11, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PB12, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PB15, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PB16, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PB17, 0); /* LCDD12 */ + at91_set_A_periph(AT91_PIN_PB18, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PB19, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PB20, 0); /* LCDD15 */ + at91_set_B_periph(AT91_PIN_PB23, 0); /* LCDD18 */ + at91_set_B_periph(AT91_PIN_PB24, 0); /* LCDD19 */ + at91_set_B_periph(AT91_PIN_PB25, 0); /* LCDD20 */ + at91_set_B_periph(AT91_PIN_PB26, 0); /* LCDD21 */ + at91_set_B_periph(AT91_PIN_PB27, 0); /* LCDD22 */ + at91_set_B_periph(AT91_PIN_PB28, 0); /* LCDD23 */ +#endif + + add_generic_device("atmel_lcdfb", DEVICE_ID_SINGLE, NULL, AT91SAM9261_LCDC_BASE, SZ_4K, + IORESOURCE_MEM, data); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} +#endif + resource_size_t __init at91_configure_dbgu(void) { at91_set_A_periph(AT91_PIN_PA9, 0); /* DRXD */ diff --git a/arch/arm/mach-at91/at91sam9261_lowlevel_init.c b/arch/arm/mach-at91/at91sam9261_lowlevel_init.c new file mode 100644 index 0000000000..a2e065fe73 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9261_lowlevel_init.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2009-2013 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#define __LOWLEVEL_INIT__ + +#include <common.h> +#include <asm/system.h> +#include <asm/barebox-arm.h> +#include <asm/barebox-arm-head.h> +#include <mach/hardware.h> +#include <mach/at91_pmc.h> +#include <mach/at91_pio.h> +#include <mach/at91_rstc.h> +#include <mach/at91_wdt.h> +#include <mach/at91sam9_matrix.h> +#include <mach/at91sam9_sdramc.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91_lowlevel_init.h> +#include <mach/io.h> +#include <init.h> +#include <sizes.h> + +void __naked __bare_init reset(void) +{ + common_reset(); + + arm_setup_stack(AT91SAM9261_SRAM_BASE + AT91SAM9261_SRAM_SIZE - 16); + + at91sam926x_lowlevel_init(IOMEM(AT91SAM9261_BASE_PIOC), false, + AT91_MATRIX_EBICSA); +} diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index eeea1cea20..49d280dd07 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -175,6 +175,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_DEV_ID("at91rm9200-gpio3", &pioCDE_clk), CLKDEV_DEV_ID("at91rm9200-gpio4", &pioCDE_clk), CLKDEV_DEV_ID("at91-pit", &mck), + CLKDEV_CON_DEV_ID("hck1", "atmel_lcdfb", &lcdc_clk), }; static struct clk_lookup usart_clocks_lookups[] = { diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index b72cc5a84a..528a07b7ac 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -50,7 +50,8 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], 0); + at91_set_gpio_output(data->vbus_pin[i], + data->vbus_pin_active_low[i]); } add_generic_device("at91_ohci", DEVICE_ID_DYNAMIC, NULL, AT91SAM9263_UHP_BASE, @@ -96,7 +97,7 @@ void at91_add_device_eth(int id, struct at91_ether_platform_data *data) at91_set_A_periph(AT91_PIN_PE30, 0); /* EMDIO */ at91_set_A_periph(AT91_PIN_PE29, 0); /* EMDC */ - if (!data->is_rmii) { + if (data->phy_interface != PHY_INTERFACE_MODE_RMII) { at91_set_A_periph(AT91_PIN_PE22, 0); /* ECRS */ at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */ at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */ @@ -249,6 +250,48 @@ void at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata) void __init at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata) {} #endif + +/* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_DRIVER_VIDEO_ATMEL) +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) +{ + BUG_ON(!data); + + data->have_intensity_bit = true; + + at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */ + at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */ + at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */ + at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */ + at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */ + at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */ + at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */ + at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD21 */ + at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */ + at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */ + + add_generic_device("atmel_lcdfb", DEVICE_ID_SINGLE, NULL, AT91SAM9263_LCDC_BASE, SZ_4K, + IORESOURCE_MEM, data); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} +#endif + resource_size_t __init at91_configure_dbgu(void) { at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */ diff --git a/arch/arm/mach-at91/at91sam9263_lowlevel_init.c b/arch/arm/mach-at91/at91sam9263_lowlevel_init.c new file mode 100644 index 0000000000..5260658547 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9263_lowlevel_init.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2009-2013 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#define __LOWLEVEL_INIT__ + +#include <common.h> +#include <asm/system.h> +#include <asm/barebox-arm.h> +#include <asm/barebox-arm-head.h> +#include <mach/hardware.h> +#include <mach/at91_pmc.h> +#include <mach/at91_pio.h> +#include <mach/at91_rstc.h> +#include <mach/at91_wdt.h> +#include <mach/at91sam9_matrix.h> +#include <mach/at91sam9_sdramc.h> +#include <mach/at91sam9_smc.h> +#include <mach/at91_lowlevel_init.h> +#include <mach/io.h> +#include <init.h> +#include <sizes.h> + +void __naked __bare_init reset(void) +{ + common_reset(); + + arm_setup_stack(AT91SAM9263_SRAM0_BASE + AT91SAM9263_SRAM0_SIZE - 16); + + at91sam926x_lowlevel_init(IOMEM(AT91SAM9263_BASE_PIOD), true, + AT91_MATRIX_EBI0CSA); +} diff --git a/arch/arm/mach-at91/at91sam926x_lowlevel_init.c b/arch/arm/mach-at91/at91sam926x_lowlevel_init.c index cfae9824d3..8b9b33e2ef 100644 --- a/arch/arm/mach-at91/at91sam926x_lowlevel_init.c +++ b/arch/arm/mach-at91/at91sam926x_lowlevel_init.c @@ -19,8 +19,10 @@ #include <mach/at91sam9_matrix.h> #include <mach/at91sam9_sdramc.h> #include <mach/at91sam9_smc.h> +#include <mach/at91_lowlevel_init.h> #include <mach/io.h> #include <init.h> +#include <sizes.h> static void inline access_sdram(void) { @@ -36,51 +38,54 @@ static void inline pmc_check_mckrdy(void) } while (!(r & AT91_PMC_MCKRDY)); } -void __naked __bare_init reset(void) +static int inline running_in_sram(void) +{ + u32 addr = get_pc(); + + addr >>= 28; + return addr == 0; +} + +void __bare_init at91sam926x_lowlevel_init(void *pio, bool is_pio_asr, + u32 matrix_csa) { u32 r; int i; + int in_sram = running_in_sram(); + struct at91sam926x_lowlevel_cfg cfg; - common_reset(); + at91sam926x_lowlevel_board_config(&cfg); - __raw_writel(CONFIG_SYS_WDTC_WDMR_VAL, AT91_BASE_WDT + AT91_WDT_MR); + __raw_writel(cfg.wdt_mr, AT91_BASE_WDT + AT91_WDT_MR); /* configure PIOx as EBI0 D[16-31] */ -#ifdef CONFIG_ARCH_AT91SAM9263 - __raw_writel(CONFIG_SYS_PIOD_PDR_VAL1, AT91_BASE_PIOD + PIO_PDR); - __raw_writel(CONFIG_SYS_PIOD_PPUDR_VAL, AT91_BASE_PIOD + PIO_PUDR); - __raw_writel(CONFIG_SYS_PIOD_PPUDR_VAL, AT91_BASE_PIOD + PIO_ASR); -#else - __raw_writel(CONFIG_SYS_PIOC_PDR_VAL1, AT91_BASE_PIOC + PIO_PDR); - __raw_writel(CONFIG_SYS_PIOC_PPUDR_VAL, AT91_BASE_PIOC + PIO_PUDR); -#endif + __raw_writel(cfg.ebi_pio_pdr, pio + PIO_PDR); + __raw_writel(cfg.ebi_pio_ppudr, pio + PIO_PUDR); + if (is_pio_asr) + __raw_writel(cfg.ebi_pio_ppudr, pio + PIO_ASR); -#if defined(AT91_MATRIX_EBI0CSA) - at91_sys_write(AT91_MATRIX_EBI0CSA, CONFIG_SYS_MATRIX_EBI0CSA_VAL); -#else /* AT91_MATRIX_EBICSA */ - at91_sys_write(AT91_MATRIX_EBICSA, CONFIG_SYS_MATRIX_EBICSA_VAL); -#endif + at91_sys_write(matrix_csa, cfg.ebi_csa); /* flash */ - at91_smc_write(CONFIG_SYS_SMC_CS, AT91_SMC_MODE, CONFIG_SYS_SMC_MODE_VAL); + at91_smc_write(cfg.smc_cs, AT91_SMC_MODE, cfg.smc_mode); - at91_smc_write(CONFIG_SYS_SMC_CS, AT91_SMC_CYCLE, CONFIG_SYS_SMC_CYCLE_VAL); + at91_smc_write(cfg.smc_cs, AT91_SMC_CYCLE, cfg.smc_cycle); - at91_smc_write(CONFIG_SYS_SMC_CS, AT91_SMC_PULSE, CONFIG_SYS_SMC_PULSE_VAL); + at91_smc_write(cfg.smc_cs, AT91_SMC_PULSE, cfg.smc_pulse); - at91_smc_write(CONFIG_SYS_SMC_CS, AT91_SMC_SETUP, CONFIG_SYS_SMC_SETUP_VAL); + at91_smc_write(cfg.smc_cs, AT91_SMC_SETUP, cfg.smc_setup); /* * PMC Check if the PLL is already initialized */ r = at91_pmc_read(AT91_PMC_MCKR); - if (r & AT91_PMC_CSS) + if (r & AT91_PMC_CSS && !in_sram) goto end; /* * Enable the Main Oscillator */ - at91_pmc_write(AT91_CKGR_MOR, CONFIG_SYS_MOR_VAL); + at91_pmc_write(AT91_CKGR_MOR, cfg.pmc_mor); do { r = at91_pmc_read(AT91_PMC_SR); @@ -89,7 +94,7 @@ void __naked __bare_init reset(void) /* * PLLAR: x MHz for PCK */ - at91_pmc_write(AT91_CKGR_PLLAR, CONFIG_SYS_PLLAR_VAL); + at91_pmc_write(AT91_CKGR_PLLAR, cfg.pmc_pllar); do { r = at91_pmc_read(AT91_PMC_SR); @@ -98,14 +103,14 @@ void __naked __bare_init reset(void) /* * PCK/x = MCK Master Clock from SLOW */ - at91_pmc_write(AT91_PMC_MCKR, CONFIG_SYS_MCKR1_VAL); + at91_pmc_write(AT91_PMC_MCKR, cfg.pmc_mckr1); pmc_check_mckrdy(); /* * PCK/x = MCK Master Clock from PLLA */ - at91_pmc_write(AT91_PMC_MCKR, CONFIG_SYS_MCKR2_VAL); + at91_pmc_write(AT91_PMC_MCKR, cfg.pmc_mckr2); pmc_check_mckrdy(); @@ -117,20 +122,20 @@ void __naked __bare_init reset(void) * SDRAMC Check if Refresh Timer Counter is already initialized */ r = at91_sys_read(AT91_SDRAMC_TR); - if (r) + if (r && !in_sram) goto end; /* SDRAMC_MR : Normal Mode */ at91_sys_write(AT91_SDRAMC_MR, AT91_SDRAMC_MODE_NORMAL); /* SDRAMC_TR - Refresh Timer register */ - at91_sys_write(AT91_SDRAMC_TR, CONFIG_SYS_SDRC_TR_VAL1); + at91_sys_write(AT91_SDRAMC_TR, cfg.sdrc_tr1); /* SDRAMC_CR - Configuration register*/ - at91_sys_write(AT91_SDRAMC_CR, CONFIG_SYS_SDRC_CR_VAL); + at91_sys_write(AT91_SDRAMC_CR, cfg.sdrc_cr); /* Memory Device Type */ - at91_sys_write(AT91_SDRAMC_MDR, CONFIG_SYS_SDRC_MDR_VAL); + at91_sys_write(AT91_SDRAMC_MDR, cfg.sdrc_mdr); /* SDRAMC_MR : Precharge All */ at91_sys_write(AT91_SDRAMC_MR, AT91_SDRAMC_MODE_PRECHARGE); @@ -158,18 +163,25 @@ void __naked __bare_init reset(void) access_sdram(); /* SDRAMC_TR : Refresh Timer Counter */ - at91_sys_write(AT91_SDRAMC_TR, CONFIG_SYS_SDRC_TR_VAL2); + at91_sys_write(AT91_SDRAMC_TR, cfg.sdrc_tr2); /* access SDRAM */ access_sdram(); /* User reset enable*/ - at91_sys_write(AT91_RSTC_MR, CONFIG_SYS_RSTC_RMR_VAL); + at91_sys_write(AT91_RSTC_MR, cfg.rstc_rmr); #ifdef CONFIG_SYS_MATRIX_MCFG_REMAP /* MATRIX_MCFG - REMAP all masters */ at91_sys_write(AT91_MATRIX_MCFG0, 0x1FF); #endif + /* + * When boot from external boot + * we need to enable mck and ohter clock + * so enable all of them + * We will shutdown what we don't need later + */ + at91_pmc_write(AT91_PMC_PCER, 0xffffffff); end: board_init_lowlevel_return(); diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 7118efe9a4..deb9b62954 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -187,6 +187,7 @@ static struct clk *periph_clocks[] __initdata = { static struct clk_lookup periph_clocks_lookups[] = { /* One additional fake clock for ohci */ CLKDEV_CON_ID("ohci_clk", &uhphs_clk), + CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_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), @@ -197,6 +198,7 @@ static struct clk_lookup periph_clocks_lookups[] = { 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), }; static struct clk_lookup usart_clocks_lookups[] = { diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index d2746da9df..bde3429edd 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -15,6 +15,7 @@ #include <asm/hardware.h> #include <mach/at91_pmc.h> #include <mach/at91sam9g45_matrix.h> +#include <mach/at91sam9_ddrsdr.h> #include <mach/board.h> #include <mach/gpio.h> #include <mach/io.h> @@ -24,6 +25,9 @@ void at91_add_device_sdram(u32 size) { + if (!size) + size = at91sam9g45_get_ddram_size(1); + arm_add_mem_device("ram0", AT91_CHIPSELECT_6, size); add_mem_device("sram0", AT91SAM9G45_SRAM_BASE, AT91SAM9G45_SRAM_SIZE, IORESOURCE_MEM_WRITEABLE); @@ -44,7 +48,8 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], 0); + at91_set_gpio_output(data->vbus_pin[i], + data->vbus_pin_active_low[i]); } add_generic_device("at91_ohci", DEVICE_ID_DYNAMIC, NULL, AT91SAM9G45_OHCI_BASE, @@ -54,6 +59,28 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {} #endif +#if defined(CONFIG_USB_EHCI) +void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) +{ + int i; + + if (!data) + return; + + /* Enable VBus control for UHP ports */ + for (i = 0; i < data->ports; i++) { + if (gpio_is_valid(data->vbus_pin[i])) + at91_set_gpio_output(data->vbus_pin[i], + data->vbus_pin_active_low[i]); + } + + add_generic_device("atmel-ehci", DEVICE_ID_SINGLE, NULL, AT91SAM9G45_EHCI_BASE, + 1024 * 1024, IORESOURCE_MEM, data); +} +#else +void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {} +#endif + #if defined(CONFIG_DRIVER_NET_MACB) void at91_add_device_eth(int id, struct at91_ether_platform_data *data) { @@ -72,7 +99,7 @@ void at91_add_device_eth(int id, struct at91_ether_platform_data *data) at91_set_A_periph(AT91_PIN_PA19, 0); /* EMDIO */ at91_set_A_periph(AT91_PIN_PA18, 0); /* EMDC */ - if (!data->is_rmii) { + if (data->phy_interface != PHY_INTERFACE_MODE_RMII) { at91_set_B_periph(AT91_PIN_PA29, 0); /* ECRS */ at91_set_B_periph(AT91_PIN_PA30, 0); /* ECOL */ at91_set_B_periph(AT91_PIN_PA8, 0); /* ERX2 */ @@ -374,3 +401,52 @@ void at91_add_device_spi(int spi_id, struct at91_spi_platform_data *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) +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) +{ + BUG_ON(!data); + + at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */ + + at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */ + at91_set_A_periph(AT91_PIN_PE3, 0); /* LCDVSYNC */ + at91_set_A_periph(AT91_PIN_PE4, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PE5, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PE6, 0); /* LCDDEN */ + at91_set_A_periph(AT91_PIN_PE7, 0); /* LCDD0 */ + at91_set_A_periph(AT91_PIN_PE8, 0); /* LCDD1 */ + at91_set_A_periph(AT91_PIN_PE9, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PE10, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PE11, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PE12, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PE13, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PE14, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PE15, 0); /* LCDD8 */ + at91_set_A_periph(AT91_PIN_PE16, 0); /* LCDD9 */ + at91_set_A_periph(AT91_PIN_PE17, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PE18, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PE19, 0); /* LCDD12 */ + at91_set_A_periph(AT91_PIN_PE20, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PE21, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PE22, 0); /* LCDD15 */ + at91_set_A_periph(AT91_PIN_PE23, 0); /* LCDD16 */ + at91_set_A_periph(AT91_PIN_PE24, 0); /* LCDD17 */ + at91_set_A_periph(AT91_PIN_PE25, 0); /* LCDD18 */ + at91_set_A_periph(AT91_PIN_PE26, 0); /* LCDD19 */ + at91_set_A_periph(AT91_PIN_PE27, 0); /* LCDD20 */ + at91_set_A_periph(AT91_PIN_PE28, 0); /* LCDD21 */ + at91_set_A_periph(AT91_PIN_PE29, 0); /* LCDD22 */ + at91_set_A_periph(AT91_PIN_PE30, 0); /* LCDD23 */ + + add_generic_device("atmel_lcdfb", DEVICE_ID_SINGLE, NULL, AT91SAM9G45_LCDC_BASE, SZ_4K, + IORESOURCE_MEM, data); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} +#endif + diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c index c177975f33..e5aabd11e1 100644 --- a/arch/arm/mach-at91/at91sam9n12.c +++ b/arch/arm/mach-at91/at91sam9n12.c @@ -156,6 +156,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_DEV_ID("at91sam9x5-gpio2", &pioCD_clk), CLKDEV_DEV_ID("at91sam9x5-gpio3", &pioCD_clk), CLKDEV_DEV_ID("at91-pit", &mck), + CLKDEV_CON_DEV_ID("hck1", "atmel_hlcdfb", &lcdc_clk), }; static struct clk_lookup usart_clocks_lookups[] = { diff --git a/arch/arm/mach-at91/at91sam9n12_devices.c b/arch/arm/mach-at91/at91sam9n12_devices.c index 3f41f3e3b5..aeac2aab77 100644 --- a/arch/arm/mach-at91/at91sam9n12_devices.c +++ b/arch/arm/mach-at91/at91sam9n12_devices.c @@ -17,6 +17,7 @@ #include <mach/board.h> #include <mach/at91_pmc.h> #include <mach/at91sam9n12_matrix.h> +#include <mach/at91sam9_ddrsdr.h> #include <mach/gpio.h> #include <mach/io.h> #include <mach/cpu.h> @@ -26,6 +27,9 @@ void at91_add_device_sdram(u32 size) { + if (!size) + size = at91sam9n12_get_ddram_size(); + arm_add_mem_device("ram0", AT91_CHIPSELECT_1, size); add_mem_device("sram0", AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE, IORESOURCE_MEM_WRITEABLE); @@ -46,7 +50,8 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], 0); + at91_set_gpio_output(data->vbus_pin[i], + data->vbus_pin_active_low[i]); } add_generic_device("at91_ohci", DEVICE_ID_DYNAMIC, NULL, AT91SAM9N12_OHCI_BASE, @@ -308,6 +313,56 @@ 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_PC26, 0); /* LCDPWM */ + + at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDVSYNC */ + at91_set_A_periph(AT91_PIN_PC28, 0); /* LCDHSYNC */ + + at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDDISP */ + at91_set_A_periph(AT91_PIN_PC29, 0); /* LCDDEN */ + at91_set_A_periph(AT91_PIN_PC30, 0); /* LCDPCK */ + + at91_set_A_periph(AT91_PIN_PC0, 0); /* LCDD0 */ + at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDD1 */ + at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PC4, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PC5, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD8 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD9 */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PC12, 0); /* LCDD12 */ + at91_set_A_periph(AT91_PIN_PC13, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD15 */ + at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD16 */ + at91_set_A_periph(AT91_PIN_PC17, 0); /* LCDD17 */ + at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD18 */ + at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD19 */ + at91_set_A_periph(AT91_PIN_PC20, 0); /* LCDD20 */ + at91_set_A_periph(AT91_PIN_PC21, 0); /* LCDD21 */ + at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD22 */ + at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD23 */ + + add_generic_device("atmel_hlcdfb", DEVICE_ID_SINGLE, NULL, AT91SAM9N12_BASE_LCDC, SZ_4K, + IORESOURCE_MEM, data); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} +#endif + +/* -------------------------------------------------------------------- * UART * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index 5d43423eb3..01eac18883 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c @@ -206,6 +206,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("macb_clk", "macb0", &macb0_clk), CLKDEV_CON_DEV_ID("macb_clk", "macb1", &macb1_clk), CLKDEV_CON_ID("ohci_clk", &uhphs_clk), + CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi0", &spi0_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi1", &spi1_clk), CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci0", &mmc0_clk), @@ -215,6 +216,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_DEV_ID("at91sam9x5-gpio2", &pioCD_clk), CLKDEV_DEV_ID("at91sam9x5-gpio3", &pioCD_clk), CLKDEV_DEV_ID("at91-pit", &mck), + CLKDEV_CON_DEV_ID("hck1", "atmel_hlcdfb", &lcdc_clk), }; static struct clk_lookup usart_clocks_lookups[] = { diff --git a/arch/arm/mach-at91/at91sam9x5_devices.c b/arch/arm/mach-at91/at91sam9x5_devices.c index e92fa0de21..9f211e3bdd 100644 --- a/arch/arm/mach-at91/at91sam9x5_devices.c +++ b/arch/arm/mach-at91/at91sam9x5_devices.c @@ -16,6 +16,7 @@ #include <mach/board.h> #include <mach/at91_pmc.h> #include <mach/at91sam9x5_matrix.h> +#include <mach/at91sam9_ddrsdr.h> #include <mach/gpio.h> #include <mach/io.h> #include <mach/cpu.h> @@ -25,6 +26,9 @@ void at91_add_device_sdram(u32 size) { + if (!size) + size = at91sam9x5_get_ddram_size(); + arm_add_mem_device("ram0", AT91_CHIPSELECT_1, size); add_mem_device("sram0", AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE, IORESOURCE_MEM_WRITEABLE); @@ -45,7 +49,8 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], 0); + at91_set_gpio_output(data->vbus_pin[i], + data->vbus_pin_active_low[i]); } add_generic_device("at91_ohci", DEVICE_ID_DYNAMIC, NULL, AT91SAM9X5_OHCI_BASE, @@ -55,6 +60,28 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {} #endif +#if defined(CONFIG_USB_EHCI) +void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) +{ + int i; + + if (!data) + return; + + /* Enable VBus control for UHP ports */ + for (i = 0; i < data->ports; i++) { + if (gpio_is_valid(data->vbus_pin[i])) + at91_set_gpio_output(data->vbus_pin[i], + data->vbus_pin_active_low[i]); + } + + add_generic_device("atmel-ehci", DEVICE_ID_SINGLE, NULL, AT91SAM9X5_EHCI_BASE, + 1024 * 1024, IORESOURCE_MEM, data); +} +#else +void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {} +#endif + #if defined(CONFIG_DRIVER_NET_MACB) void at91_add_device_eth(int id, struct at91_ether_platform_data *data) { @@ -84,7 +111,7 @@ void at91_add_device_eth(int id, struct at91_ether_platform_data *data) at91_set_A_periph(AT91_PIN_PB5, 0); /* EMDIO */ at91_set_A_periph(AT91_PIN_PB6, 0); /* EMDC */ - if (!data->is_rmii) { + if (data->phy_interface != PHY_INTERFACE_MODE_RMII) { at91_set_A_periph(AT91_PIN_PB16, 0); /* ECRS */ at91_set_A_periph(AT91_PIN_PB17, 0); /* ECOL */ at91_set_A_periph(AT91_PIN_PB13, 0); /* ERX2 */ @@ -97,7 +124,7 @@ void at91_add_device_eth(int id, struct at91_ether_platform_data *data) break; case 1: start = AT91SAM9X5_BASE_EMAC1; - if (!data->is_rmii) + if (data->phy_interface != PHY_INTERFACE_MODE_RMII) pr_warn("AT91: Only RMII available on interface macb%d.\n", id); /* Pins used for RMII */ @@ -364,6 +391,61 @@ 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); + + if (cpu_is_at91sam9g25() || cpu_is_at91sam9x25()) { + pr_warn("AT91: no lcd on at91sam9g25 or at91sam9x25\n"); + return; + } + + at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDPWM */ + + at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDVSYNC */ + at91_set_A_periph(AT91_PIN_PC28, 0); /* LCDHSYNC */ + + at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDDISP */ + at91_set_A_periph(AT91_PIN_PC29, 0); /* LCDDEN */ + at91_set_A_periph(AT91_PIN_PC30, 0); /* LCDPCK */ + + at91_set_A_periph(AT91_PIN_PC0, 0); /* LCDD0 */ + at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDD1 */ + at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PC4, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PC5, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD8 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD9 */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PC12, 0); /* LCDD12 */ + at91_set_A_periph(AT91_PIN_PC13, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD15 */ + at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD16 */ + at91_set_A_periph(AT91_PIN_PC17, 0); /* LCDD17 */ + at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD18 */ + at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD19 */ + at91_set_A_periph(AT91_PIN_PC20, 0); /* LCDD20 */ + at91_set_A_periph(AT91_PIN_PC21, 0); /* LCDD21 */ + at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD22 */ + at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD23 */ + + add_generic_device("atmel_hlcdfb", DEVICE_ID_SINGLE, NULL, AT91SAM9X5_BASE_LCDC, SZ_4K, + IORESOURCE_MEM, data); +} +#else +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} +#endif + +/* -------------------------------------------------------------------- * UART * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/boot_test_cmd.c b/arch/arm/mach-at91/boot_test_cmd.c new file mode 100644 index 0000000000..aa5c020469 --- /dev/null +++ b/arch/arm/mach-at91/boot_test_cmd.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 only + */ + +#include <common.h> +#include <command.h> +#include <libbb.h> +#include <getopt.h> +#include <fs.h> +#include <fcntl.h> +#include <malloc.h> +#include <errno.h> + +static int do_at91_boot_test(int argc, char *argv[]) +{ + int opt; + u32 *buf32; + void *buf; + void (*jump)(void) = NULL; + int fd; + int ret = 1; + char *sram = "/dev/sram0"; + u32 read_size, write_size; + u32 tmp = 0; + + while ((opt = getopt(argc, argv, "j:s:")) > 0) { + switch (opt) { + case 'j': + jump = (void*)simple_strtoul(optarg, NULL, 0); + break; + case 's': + sram = optarg; + break; + default: + return COMMAND_ERROR_USAGE; + } + } + + if (argc < optind + 1) + return COMMAND_ERROR_USAGE; + + buf32 = buf = read_file(argv[optind], &read_size); + if (!buf) + return -EINVAL; + + write_size = buf32[5]; + + printf("size of the size %d\n", read_size); + printf("size to load in sram %d\n", write_size); + + if (write_size > read_size) { + printf("file smaller than requested sram loading size (%d < %d)\n", write_size, read_size); + goto err; + } + + fd = open(sram, O_WRONLY); + if (fd < 0) { + printf("could not open %s: %s\n", sram, errno_str()); + ret = fd; + goto err; + } + + while (write_size) { + tmp = write(fd, buf, write_size); + if (tmp < 0) { + perror("write"); + goto err_open; + } + buf += tmp; + write_size -= tmp; + } + + shutdown_barebox(); + + jump(); + +err_open: + close(fd); +err: + free(buf); + return ret; +} + +BAREBOX_CMD_HELP_START(at91_boot_test) +BAREBOX_CMD_HELP_USAGE("at91_boot_test [-j <jump addr>] [-s <sram>] file\n") +BAREBOX_CMD_HELP_SHORT("upload the binary to sram and jump as will do the romcode\n") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(at91_boot_test) + .cmd = do_at91_boot_test, + .usage = "upload the binary to sram and jump as will do the romcode", + BAREBOX_CMD_HELP(cmd_at91_boot_test_help) +BAREBOX_CMD_END diff --git a/arch/arm/mach-at91/bootstrap.c b/arch/arm/mach-at91/bootstrap.c new file mode 100644 index 0000000000..4149304c92 --- /dev/null +++ b/arch/arm/mach-at91/bootstrap.c @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <bootstrap.h> +#include <mach/bootstrap.h> +#include <sizes.h> +#include <malloc.h> +#include <init.h> +#include <menu.h> + +#if defined(CONFIG_MCI_ATMEL) +#define is_mmc() 1 +#else +#define is_mmc() 0 +#endif + +#ifdef CONFIG_NAND_ATMEL +#define is_nand() 1 +#else +#define is_nand() 0 +#endif + +#ifdef CONFIG_MTD_M25P80 +#define is_m25p80() 1 +#else +#define is_m25p80() 0 +#endif + +#ifdef CONFIG_MTD_DATAFLASH +#define is_dataflash() 1 +#else +#define is_dataflash() 0 +#endif + +#if defined(CONFIG_MENU) && !defined(CONFIG_NONE) +#define is_menu() 1 +#else +#define is_menu() 0 +#endif + +static char* is_barebox_to_str(bool is_barebox) +{ + return is_barebox ? "barebox" : "unknown"; +} + +static void at91bootstrap_boot_m25p80(bool is_barebox) +{ + char *name = is_barebox_to_str(is_barebox); + int (*func)(void) = NULL; + + func = bootstrap_board_read_m25p80(); + printf("Boot %s from m25p80\n", name); + bootstrap_boot(func, is_barebox); + bootstrap_err("... failed\n"); + free(func); +} + +static void at91bootstrap_boot_dataflash(bool is_barebox) +{ + char *name = is_barebox_to_str(is_barebox); + int (*func)(void) = NULL; + + printf("Boot %s from dataflash\n", name); + func = bootstrap_board_read_dataflash(); + bootstrap_boot(func, is_barebox); + bootstrap_err("... failed\n"); + free(func); +} + +static void at91bootstrap_boot_nand(bool is_barebox) +{ + char *name = is_barebox_to_str(is_barebox); + int (*func)(void) = NULL; + + printf("Boot %s from nand\n", name); + func = bootstrap_read_devfs("nand0", true, SZ_128K, SZ_256K, SZ_1M); + bootstrap_boot(func, is_barebox); + bootstrap_err("... failed\n"); + free(func); +} + +static void at91bootstrap_boot_mmc(void) +{ + int (*func)(void) = NULL; + + printf("Boot from mmc\n"); + func = bootstrap_read_disk("disk0.0", NULL); + bootstrap_boot(func, false); + bootstrap_err("... failed\n"); + free(func); +} + +static void boot_nand_barebox_action(struct menu *m, struct menu_entry *me) +{ + at91bootstrap_boot_nand(true); + + getc(); +} + +static void boot_nand_action(struct menu *m, struct menu_entry *me) +{ + at91bootstrap_boot_nand(false); + + getc(); +} + +static void boot_m25p80_barebox_action(struct menu *m, struct menu_entry *me) +{ + at91bootstrap_boot_nand(true); + + getc(); +} + +static void boot_m25p80_action(struct menu *m, struct menu_entry *me) +{ + at91bootstrap_boot_nand(false); + + getc(); +} + +static void boot_dataflash_barebox_action(struct menu *m, struct menu_entry *me) +{ + at91bootstrap_boot_dataflash(true); + + getc(); +} + +static void boot_dataflash_action(struct menu *m, struct menu_entry *me) +{ + at91bootstrap_boot_dataflash(false); + + getc(); +} + +static void boot_mmc_disk_action(struct menu *m, struct menu_entry *me) +{ + at91bootstrap_boot_mmc(); + + getc(); +} + +static void boot_reset_action(struct menu *m, struct menu_entry *me) +{ + reset_cpu(0); +} + +void at91_bootstrap_menu(void) +{ + struct menu *m; + struct menu_entry *me; + + m = menu_alloc(); + m->display = m->name = "boot"; + + menu_add(m); + + if (is_mmc()) { + me = menu_entry_alloc(); + me->action = boot_mmc_disk_action; + me->type = MENU_ENTRY_NORMAL; + me->display = "mmc"; + menu_add_entry(m, me); + } + + if (is_m25p80()) { + me = menu_entry_alloc(); + me->action = boot_m25p80_barebox_action; + me->type = MENU_ENTRY_NORMAL; + me->display = "m25p80 (barebox)"; + menu_add_entry(m, me); + + me = menu_entry_alloc(); + me->action = boot_m25p80_action; + me->type = MENU_ENTRY_NORMAL; + me->display = "m25p80"; + menu_add_entry(m, me); + } + + if (is_dataflash()) { + me = menu_entry_alloc(); + me->action = boot_dataflash_barebox_action; + me->type = MENU_ENTRY_NORMAL; + me->display = "dataflash (barebox)"; + menu_add_entry(m, me); + + me = menu_entry_alloc(); + me->action = boot_dataflash_action; + me->type = MENU_ENTRY_NORMAL; + me->display = "dataflash"; + menu_add_entry(m, me); + } + + if (is_nand()) { + me = menu_entry_alloc(); + me->action = boot_nand_barebox_action; + me->type = MENU_ENTRY_NORMAL; + me->display = "nand (barebox)"; + menu_add_entry(m, me); + + me = menu_entry_alloc(); + me->action = boot_nand_action; + me->type = MENU_ENTRY_NORMAL; + me->display = "nand"; + menu_add_entry(m, me); + } + + me = menu_entry_alloc(); + me->action = boot_reset_action; + me->type = MENU_ENTRY_NORMAL; + me->display = "reset"; + menu_add_entry(m, me); + + menu_show(m); +} + +static void boot_seq(bool is_barebox) +{ + if (is_m25p80()) + at91bootstrap_boot_m25p80(is_barebox); + + if (is_dataflash()) + at91bootstrap_boot_dataflash(is_barebox); + + if (is_nand()) + at91bootstrap_boot_nand(is_barebox); +} + +static int at91_bootstrap(void) +{ + if (is_menu()) { + printf("press 'm' to start the menu\n"); + if (tstc() && getc() == 'm') + at91_bootstrap_menu(); + } + + if (is_mmc()) + at91bootstrap_boot_mmc(); + + /* First only bootstrap_boot a barebox */ + boot_seq(true); + /* Second bootstrap_boot any */ + boot_seq(false); + + bootstrap_err("bootstrap_booting failed\n"); + while (1); + + return 0; +} + +static int at91_set_bootstrap(void) +{ + barebox_main = at91_bootstrap; + + return 0; +} +late_initcall(at91_set_bootstrap); diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index b231ec0789..2dde6325a7 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -11,6 +11,8 @@ */ #include <common.h> +#include <command.h> +#include <complete.h> #include <linux/list.h> #include <errno.h> #include <linux/err.h> @@ -42,7 +44,10 @@ */ #define cpu_has_utmi() ( cpu_is_at91sam9rl() \ || cpu_is_at91sam9g45() \ - || cpu_is_at91sam9x5()) + || cpu_is_at91sam9x5() \ + || cpu_is_sama5d3()) + +#define cpu_has_1056M_plla() (cpu_is_sama5d3()) #define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ || cpu_is_at91sam9g45() \ @@ -63,7 +68,8 @@ || cpu_is_at91sam9n12())) #define cpu_has_upll() (cpu_is_at91sam9g45() \ - || cpu_is_at91sam9x5()) + || cpu_is_at91sam9x5() \ + || cpu_is_sama5d3()) /* USB host HS & FS */ #define cpu_has_uhp() (!cpu_is_at91sam9rl()) @@ -71,18 +77,22 @@ /* USB device FS only */ #define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ || cpu_is_at91sam9g45() \ - || cpu_is_at91sam9x5())) + || cpu_is_at91sam9x5() \ + || cpu_is_sama5d3())) #define cpu_has_plladiv2() (cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ - || cpu_is_at91sam9n12()) + || cpu_is_at91sam9n12() \ + || cpu_is_sama5d3()) #define cpu_has_mdiv3() (cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ - || cpu_is_at91sam9n12()) + || cpu_is_at91sam9n12() \ + || cpu_is_sama5d3()) #define cpu_has_alt_prescaler() (cpu_is_at91sam9x5() \ - || cpu_is_at91sam9n12()) + || cpu_is_at91sam9n12() \ + || cpu_is_sama5d3()) static LIST_HEAD(clocks); @@ -204,10 +214,26 @@ struct clk mck = { static void pmc_periph_mode(struct clk *clk, int is_on) { - if (is_on) - at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask); - else - at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask); + u32 regval = 0; + + /* + * With sama5d3 chips, you have more than 32 peripherals so only one + * register is not enough to manage their clocks. A peripheral + * control register has been introduced to solve this issue. + */ + if (cpu_is_sama5d3()) { + regval |= AT91_PMC_PCR_CMD; /* write command */ + regval |= clk->pid & AT91_PMC_PCR_PID; /* peripheral selection */ + regval |= AT91_PMC_PCR_DIV(clk->div); + if (is_on) + regval |= AT91_PMC_PCR_EN; /* enable clock */ + at91_pmc_write(AT91_PMC_PCR, regval); + } else { + if (is_on) + at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask); + else + at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask); + } } static struct clk *at91_css_to_clk(unsigned long css) @@ -429,6 +455,8 @@ int clk_register(struct clk *clk) if (clk_is_peripheral(clk)) { if (!clk->parent) clk->parent = &mck; + if (cpu_is_sama5d3()) + clk->rate_hz = DIV_ROUND_UP(clk->parent->rate_hz, 1 << clk->div); clk->mode = pmc_periph_mode; } else if (clk_is_sys(clk)) { @@ -454,7 +482,10 @@ static u32 at91_pll_rate(struct clk *pll, u32 freq, u32 reg) unsigned mul, div; div = reg & 0xff; - mul = (reg >> 16) & 0x7ff; + if (cpu_is_sama5d3()) + mul = (reg >> 18) & 0x7ff; + else + mul = (reg >> 16) & 0x7ff; if (div && mul) { freq /= div; freq *= mul + 1; @@ -609,12 +640,18 @@ int at91_clock_init(unsigned long main_clock) /* 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_300M_plla()) { + if (cpu_has_1056M_plla()) { + if (plla.rate_hz > 1056000000) + pll_overclock = 1; + } else if (cpu_has_300M_plla()) { if (plla.rate_hz > 300000000) pll_overclock = 1; } else if (cpu_has_800M_plla()) { if (plla.rate_hz > 800000000) pll_overclock = 1; + } else if (cpu_has_300M_plla()) { + if (plla.rate_hz > 300000000) + pll_overclock = 1; } else if (cpu_has_240M_plla()) { if (plla.rate_hz > 240000000) pll_overclock = 1; @@ -734,6 +771,7 @@ postconsole_initcall(at91_clock_display); static int at91_clock_reset(void) { unsigned long pcdr = 0; + unsigned long pcdr1 = 0; unsigned long scdr = 0; struct clk *clk; @@ -741,8 +779,17 @@ static int at91_clock_reset(void) if (clk->users > 0) continue; - if (clk->mode == pmc_periph_mode) - pcdr |= clk->pmc_mask; + if (clk->mode == pmc_periph_mode) { + if (cpu_is_sama5d3()) { + u32 pmc_mask = 1 << (clk->pid % 32); + + if (clk->pid > 31) + pcdr1 |= pmc_mask; + else + pcdr |= pmc_mask; + } else + pcdr |= clk->pmc_mask; + } if (clk->mode == pmc_sys_mode) scdr |= clk->pmc_mask; @@ -751,8 +798,91 @@ static int at91_clock_reset(void) } at91_pmc_write(AT91_PMC_PCDR, pcdr); + if (cpu_is_sama5d3()) + at91_pmc_write(AT91_PMC_PCDR1, pcdr1); at91_pmc_write(AT91_PMC_SCDR, scdr); return 0; } late_initcall(at91_clock_reset); + +#ifdef CONFIG_CMD_AT91CLK +static int do_at91clk(int argc, char *argv[]) +{ + u32 scsr, pcsr, pcsr1 = 0, uckr = 0, sr; + struct clk *clk; + + scsr = at91_pmc_read(AT91_PMC_SCSR); + pcsr = at91_pmc_read(AT91_PMC_PCSR); + if (cpu_is_sama5d3()) + 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()) + 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)); + printf("PLLA = %8x\n", at91_pmc_read(AT91_CKGR_PLLAR)); + if (cpu_has_pllb()) + printf("PLLB = %8x\n", at91_pmc_read(AT91_CKGR_PLLBR)); + if (cpu_has_utmi()) { + uckr = at91_pmc_read(AT91_CKGR_UCKR); + printf("UCKR = %8x\n", uckr); + } + printf("MCKR = %8x\n", at91_pmc_read(AT91_PMC_MCKR)); + if (cpu_has_upll()) + printf("USB = %8x\n", at91_pmc_read(AT91_PMC_USB)); + printf("SR = %8x\n", sr); + + printf("\n"); + + list_for_each_entry(clk, &clocks, node) { + char *state; + char *mode = ""; + + if (clk->mode == pmc_sys_mode) { + state = (scsr & clk->pmc_mask) ? "on" : "off"; + mode = "sys"; + } else if (clk->mode == pmc_periph_mode) { + if (cpu_is_sama5d3()) { + u32 pmc_mask = 1 << (clk->pid % 32); + + if (clk->pid > 31) + state = (pcsr1 & pmc_mask) ? "on" : "off"; + else + state = (pcsr & pmc_mask) ? "on" : "off"; + } else { + state = (pcsr & clk->pmc_mask) ? "on" : "off"; + } + mode = "periph"; + } else if (clk->mode == pmc_uckr_mode) { + state = (uckr & clk->pmc_mask) ? "on" : "off"; + mode = "uckr"; + } else if (clk->pmc_mask) { + state = (sr & clk->pmc_mask) ? "on" : "off"; + } else if (clk == &clk32k || clk == &main_clk) { + state = "on"; + } else { + state = ""; + } + + printf("%-10s %-7s users=%2d %-3s %10lu Hz %s\n", + clk->name, mode, clk->users, state, clk_get_rate(clk), + clk->parent ? clk->parent->name : ""); + } + return 0; +} + +BAREBOX_CMD_HELP_START(at91clk) +BAREBOX_CMD_HELP_USAGE("at91clk\n") +BAREBOX_CMD_HELP_SHORT("dump current clock configuration\n"); +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(at91clk) + .cmd = do_at91clk, + .usage = "dump current clock configuration", + BAREBOX_CMD_HELP(cmd_at91clk_help) + BAREBOX_CMD_COMPLETE(empty_complete) +BAREBOX_CMD_END +#endif diff --git a/arch/arm/mach-at91/clock.h b/arch/arm/mach-at91/clock.h index cacc0b5469..8af8d963c8 100644 --- a/arch/arm/mach-at91/clock.h +++ b/arch/arm/mach-at91/clock.h @@ -20,7 +20,9 @@ struct clk { const char *name; /* unique clock name */ struct clk_lookup cl; unsigned long rate_hz; + unsigned div; /* parent clock divider */ struct clk *parent; + unsigned pid; /* peripheral ID */ u32 pmc_mask; void (*mode)(struct clk *, int); unsigned id:3; /* PCK0..4, or 32k/main/a/b */ diff --git a/arch/arm/mach-at91/include/mach/at91_lowlevel_init.h b/arch/arm/mach-at91/include/mach/at91_lowlevel_init.h new file mode 100644 index 0000000000..8c53ce799b --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_lowlevel_init.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2009-2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#ifndef __AT91_LOWLEVEL_INIT_H__ +#define __AT91_LOWLEVEL_INIT_H__ + +struct at91sam926x_lowlevel_cfg { + u32 wdt_mr; + u32 ebi_pio_pdr; + u32 ebi_pio_ppudr; + u32 ebi_csa; + u32 smc_cs; + u32 smc_mode; + u32 smc_cycle; + u32 smc_pulse; + u32 smc_setup; + u32 pmc_mor; + u32 pmc_pllar; + u32 pmc_mckr1; + u32 pmc_mckr2; + u32 sdrc_cr; + u32 sdrc_tr1; + u32 sdrc_mdr; + u32 sdrc_tr2; + u32 rstc_rmr; +}; + +void at91sam926x_lowlevel_board_config(struct at91sam926x_lowlevel_cfg *cfg); +void at91sam926x_lowlevel_init(void *pio, bool is_pio_asr, u32 matrix_csa); + +#endif /* __AT91_LOWLEVEL_INIT_H__ */ diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h index 6fcbf40729..61078717c6 100644 --- a/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -163,13 +163,19 @@ #define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */ #define AT91_PMC_WPVSRC (0xffff << 8) /* Write Protect Violation Source */ -#define AT91_PMC_VER (AT91_PMC + 0xfc) /* PMC Module Version [AT91CAP9 only] */ +#define AT91_PMC_VER 0xfc /* PMC Module Version [AT91CAP9 only] */ -#define AT91_PMC_PCR (AT91_PMC + 0x10c) /* Peripheral Control Register [some SAM9] */ +#define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9] */ #define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */ #define AT91_PMC_PCR_CMD (0x1 << 12) /* Command */ -#define AT91_PMC_PCR_DIV (0x3 << 16) /* Divisor Value */ -#define AT91_PMC_PCRDIV(n) (((n) << 16) & AT91_PMC_PCR_DIV) +#define AT91_PMC_PCR_DIV(n) ((n) << 16) /* Divisor value */ +#define AT91_PMC_PCR_DIV0 0x0 /* Peripheral clock is MCK */ +#define AT91_PMC_PCR_DIV2 0x1 /* Peripheral clock is MCK/2 */ +#define AT91_PMC_PCR_DIV4 0x2 /* Peripheral clock is MCK/4 */ +#define AT91_PMC_PCR_DIV8 0x3 /* Peripheral clock is MCK/8 */ #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ +#define AT91_PMC_PCER1 0x100 /* Peripheral Clock Enable Register 1 */ +#define AT91_PMC_PCDR1 0x104 /* Peripheral Clock Disable Register 1 */ +#define AT91_PMC_PCSR1 0x108 /* Peripheral Clock Status Register 1 */ #endif diff --git a/arch/arm/mach-at91/include/mach/at91rm9200_mc.h b/arch/arm/mach-at91/include/mach/at91rm9200_mc.h index d34e4ed893..fc44a61090 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200_mc.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200_mc.h @@ -157,4 +157,34 @@ #define AT91_BFC_MUXEN (1 << 18) /* Multiplexed Bus Enable */ #define AT91_BFC_RDYEN (1 << 19) /* Ready Enable Mode */ +#ifndef __ASSEMBLY__ +#include <mach/io.h> +static inline u32 at91rm9200_get_sdram_size(void) +{ + u32 cr, mr; + u32 size; + + cr = at91_sys_read(AT91_SDRAMC_CR); + mr = at91_sys_read(AT91_SDRAMC_MR); + + /* Formula: + * size = bank << (col + row + 1); + * if (bandwidth == 32 bits) + * size <<= 1; + */ + size = 1; + /* COL */ + size += (cr & AT91_SDRAMC_NC) + 8; + /* ROW */ + size += ((cr & AT91_SDRAMC_NR) >> 2) + 11; + /* BANK */ + size = ((cr & AT91_SDRAMC_NB) ? 4 : 2) << size; + /* bandwidth */ + if (!(mr & AT91_SDRAMC_DBW)) + size <<= 1; + + return size; +} +#endif + #endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h index 070f730618..88796a6a2c 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h +++ b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h @@ -50,6 +50,10 @@ #define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver [SAM9 Only] */ #define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared [SAM9 Only] */ #define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y [SAM9 Only] */ +#define AT91_DDRSDRC_NB (1 << 20) /* Number of +Banks [not SAM9G45] */ +#define AT91_SDRAMC_NB_4 (0 << 20) +#define AT91_SDRAMC_NB_8 (1 << 20) #define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */ #define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */ @@ -131,4 +135,126 @@ #define AT91_DDRSDRC_WPVS (1 << 0) /* Write protect violation status */ #define AT91_DDRSDRC_WPVSRC (0xffff << 8) /* Write protect violation source */ +#ifndef __ASSEMBLY__ +#include <mach/io.h> + +static inline u32 at91_get_ddram_size(void * __iomem base, bool is_nb) +{ + u32 cr; + u32 mdr; + u32 size; + bool is_sdram; + + cr = __raw_readl(base + AT91_DDRSDRC_CR); + mdr = __raw_readl(base + AT91_DDRSDRC_MDR); + + is_sdram = (mdr & AT91_DDRSDRC_MD) <= AT91_DDRSDRC_MD_LOW_POWER_SDR; + + /* Formula: + * size = bank << (col + row + 1); + * if (bandwidth == 32 bits) + * size <<= 1; + */ + size = 1; + /* COL */ + size += (cr & AT91_DDRSDRC_NC) + 8; + if (!is_sdram) + size ++; + /* ROW */ + size += ((cr & AT91_DDRSDRC_NR) >> 2) + 11; + /* BANK */ + if (is_nb) + size = ((cr & AT91_DDRSDRC_NB) ? 8 : 4) << size; + else + size = 4 << size; + + /* bandwidth */ + if (!(mdr & AT91_DDRSDRC_DBW)) + size <<= 1; + + return size; +} + +#ifdef CONFIG_SOC_AT91SAM9G45 +static inline u32 at91sam9g45_get_ddram_size(int bank) +{ + switch (bank) { + case 0: + return at91_get_ddram_size(IOMEM(AT91SAM9G45_BASE_DDRSDRC0), false); + case 1: + return at91_get_ddram_size(IOMEM(AT91SAM9G45_BASE_DDRSDRC1), false); + default: + return 0; + } +} +#else +static inline u32 at91sam9g45_get_ddram_size(int bank) +{ + return 0; +} +#endif + +#ifdef CONFIG_SOC_AT91SAM9X5 +static inline u32 at91sam9x5_get_ddram_size(void) +{ + return at91_get_ddram_size(IOMEM(AT91SAM9X5_BASE_DDRSDRC0), true); +} +#else +static inline u32 at91sam9x5_get_ddram_size(void) +{ + return 0; +} +#endif + +#ifdef CONFIG_SOC_AT91SAM9N12 +static inline u32 at91sam9n12_get_ddram_size(void) +{ + return at91_get_ddram_size(IOMEM(AT91SAM9N12_BASE_DDRSDRC0), true); +} +#else +static inline u32 at91sam9n12_get_ddram_size(void) +{ + return 0; +} +#endif + +#ifdef CONFIG_SOC_SAMA5 +static inline u32 at91sama5_get_ddram_size(void) +{ + u32 cr; + u32 mdr; + u32 size; + void * __iomem base = IOMEM(SAMA5D3_BASE_MPDDRC); + + cr = __raw_readl(base + AT91_DDRSDRC_CR); + mdr = __raw_readl(base + AT91_DDRSDRC_MDR); + + /* Formula: + * size = bank << (col + row + 1); + * if (bandwidth == 32 bits) + * size <<= 1; + */ + size = 1; + /* COL */ + size += (cr & AT91_DDRSDRC_NC) + 9; + /* ROW */ + size += ((cr & AT91_DDRSDRC_NR) >> 2) + 11; + /* BANK */ + size = ((cr & AT91_DDRSDRC_NB) ? 8 : 4) << size; + + /* bandwidth */ + if (!(mdr & AT91_DDRSDRC_DBW)) + size <<= 1; + + return size; +} +#else +static inline u32 at91sama5_get_ddram_size(void) +{ + return 0; +} +#endif + +#endif + #endif diff --git a/arch/arm/mach-at91/include/mach/atmel_hlcdc.h b/arch/arm/mach-at91/include/mach/atmel_hlcdc.h new file mode 100644 index 0000000000..71ccb96264 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/atmel_hlcdc.h @@ -0,0 +1,760 @@ +/* + * Header file for AT91 High end LCD Controller + * + * Data structure and register user interface + * + * Copyright (C) 2010 Atmel Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PUROFFSETE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __MACH_ATMEL_HLCD_H__ +#define __MACH_ATMEL_HLCD_H__ + +/* Lcdc hardware registers */ +#define ATMEL_LCDC_LCDCFG0 0x0000 +#define LCDC_LCDCFG0_CLKPOL (0x1 << 0) +#define LCDC_LCDCFG0_CLKSEL (0x1 << 2) +#define LCDC_LCDCFG0_CLKPWMSEL (0x1 << 3) +#define LCDC_LCDCFG0_CGDISBASE (0x1 << 8) +#define LCDC_LCDCFG0_CGDISOVR1 (0x1 << 9) +#define LCDC_LCDCFG0_CGDISOVR2 (0x1 << 10) +#define LCDC_LCDCFG0_CGDISHEO (0x1 << 11) +#define LCDC_LCDCFG0_CGDISHCR (0x1 << 12) +#define LCDC_LCDCFG0_CGDISPP (0x1 << 13) +#define LCDC_LCDCFG0_CLKDIV_OFFSET 16 +#define LCDC_LCDCFG0_CLKDIV (0xff << LCDC_LCDCFG0_CLKDIV_OFFSET) + +#define ATMEL_LCDC_LCDCFG1 0x0004 +#define LCDC_LCDCFG1_HSPW_OFFSET 0 +#define LCDC_LCDCFG1_HSPW (0x3f << LCDC_LCDCFG1_HSPW_OFFSET) +#define LCDC_LCDCFG1_VSPW_OFFSET 16 +#define LCDC_LCDCFG1_VSPW (0x3f << LCDC_LCDCFG1_VSPW_OFFSET) + +#define ATMEL_LCDC_LCDCFG2 0x0008 +#define LCDC_LCDCFG2_VFPW_OFFSET 0 +#define LCDC_LCDCFG2_VFPW (0x3f << LCDC_LCDCFG2_VFPW_OFFSET) +#define LCDC_LCDCFG2_VBPW_OFFSET 16 +#define LCDC_LCDCFG2_VBPW (0x3f << LCDC_LCDCFG2_VBPW_OFFSET) + +#define ATMEL_LCDC_LCDCFG3 0x000C +#define LCDC_LCDCFG3_HFPW_OFFSET 0 +#define LCDC_LCDCFG3_HFPW (0xff << LCDC_LCDCFG3_HFPW_OFFSET) +#define LCDC2_LCDCFG3_HFPW (0x1ff << LCDC_LCDCFG3_HFPW_OFFSET) +#define LCDC_LCDCFG3_HBPW_OFFSET 16 +#define LCDC_LCDCFG3_HBPW (0xff << LCDC_LCDCFG3_HBPW_OFFSET) +#define LCDC2_LCDCFG3_HBPW (0x1ff << LCDC_LCDCFG3_HBPW_OFFSET) + +#define ATMEL_LCDC_LCDCFG4 0x0010 +#define LCDC_LCDCFG4_PPL_OFFSET 0 +#define LCDC_LCDCFG4_PPL (0x7ff << LCDC_LCDCFG4_PPL_OFFSET) +#define LCDC_LCDCFG4_RPF_OFFSET 16 +#define LCDC_LCDCFG4_RPF (0x7ff << LCDC_LCDCFG4_RPF_OFFSET) + +#define ATMEL_LCDC_LCDCFG5 0x0014 +#define LCDC_LCDCFG5_HSPOL (0x1 << 0) +#define LCDC_LCDCFG5_VSPOL (0x1 << 1) +#define LCDC_LCDCFG5_VSPDLYS (0x1 << 2) +#define LCDC_LCDCFG5_VSPDLYE (0x1 << 3) +#define LCDC_LCDCFG5_DISPPOL (0x1 << 4) +#define LCDC_LCDCFG5_SERIAL (0x1 << 5) +#define LCDC_LCDCFG5_DITHER (0x1 << 6) +#define LCDC_LCDCFG5_DISPDLY (0x1 << 7) +#define LCDC_LCDCFG5_MODE_OFFSET 8 +#define LCDC_LCDCFG5_MODE (0x3 << LCDC_LCDCFG5_MODE_OFFSET) +#define LCDC_LCDCFG5_MODE_OUTPUT_12BPP (0x0 << 8) +#define LCDC_LCDCFG5_MODE_OUTPUT_16BPP (0x1 << 8) +#define LCDC_LCDCFG5_MODE_OUTPUT_18BPP (0x2 << 8) +#define LCDC_LCDCFG5_MODE_OUTPUT_24BPP (0x3 << 8) +#define LCDC_LCDCFG5_PP (0x1 << 10) +#define LCDC_LCDCFG5_VSPSU (0x1 << 12) +#define LCDC_LCDCFG5_VSPHO (0x1 << 13) +#define LCDC_LCDCFG5_GUARDTIME_OFFSET 16 +#define LCDC_LCDCFG5_GUARDTIME (0x1f << LCDC_LCDCFG5_GUARDTIME_OFFSET) + +#define ATMEL_LCDC_LCDCFG6 0x0018 +#define LCDC_LCDCFG6_PWMPS_OFFSET 0 +#define LCDC_LCDCFG6_PWMPS (0x7 << LCDC_LCDCFG6_PWMPS_OFFSET) +#define LCDC_LCDCFG6_PWMPOL (0x1 << 4) +#define LCDC_LCDCFG6_PWMCVAL_OFFSET 8 +#define LCDC_LCDCFG6_PWMCVAL (0xff << LCDC_LCDCFG6_PWMCVAL_OFFSET) + +#define ATMEL_LCDC_LCDEN 0x0020 +#define LCDC_LCDEN_CLKEN (0x1 << 0) +#define LCDC_LCDEN_SYNCEN (0x1 << 1) +#define LCDC_LCDEN_DISPEN (0x1 << 2) +#define LCDC_LCDEN_PWMEN (0x1 << 3) + +#define ATMEL_LCDC_LCDDIS 0x0024 +#define LCDC_LCDDIS_CLKDIS (0x1 << 0) +#define LCDC_LCDDIS_SYNCDIS (0x1 << 1) +#define LCDC_LCDDIS_DISPDIS (0x1 << 2) +#define LCDC_LCDDIS_PWMDIS (0x1 << 3) +#define LCDC_LCDDIS_CLKRST (0x1 << 8) +#define LCDC_LCDDIS_SYNCRST (0x1 << 9) +#define LCDC_LCDDIS_DISPRST (0x1 << 10) +#define LCDC_LCDDIS_PWMRST (0x1 << 11) + +#define ATMEL_LCDC_LCDSR 0x0028 +#define LCDC_LCDSR_CLKSTS (0x1 << 0) +#define LCDC_LCDSR_LCDSTS (0x1 << 1) +#define LCDC_LCDSR_DISPSTS (0x1 << 2) +#define LCDC_LCDSR_PWMSTS (0x1 << 3) +#define LCDC_LCDSR_SIPSTS (0x1 << 4) + +#define ATMEL_LCDC_LCDIER 0x002C +#define LCDC_LCDIER_SOFIE (0x1 << 0) +#define LCDC_LCDIER_DISIE (0x1 << 1) +#define LCDC_LCDIER_DISPIE (0x1 << 2) +#define LCDC_LCDIER_FIFOERRIE (0x1 << 4) +#define LCDC_LCDIER_BASEIE (0x1 << 8) +#define LCDC_LCDIER_OVR1IE (0x1 << 9) +#define LCDC_LCDIER_OVR2IE (0x1 << 10) +#define LCDC_LCDIER_HEOIE (0x1 << 11) +#define LCDC_LCDIER_HCRIE (0x1 << 12) +#define LCDC_LCDIER_PPIE (0x1 << 13) + +#define ATMEL_LCDC_LCDIDR 0x0030 +#define LCDC_LCDIDR_SOFID (0x1 << 0) +#define LCDC_LCDIDR_DISID (0x1 << 1) +#define LCDC_LCDIDR_DISPID (0x1 << 2) +#define LCDC_LCDIDR_FIFOERRID (0x1 << 4) +#define LCDC_LCDIDR_BASEID (0x1 << 8) +#define LCDC_LCDIDR_OVR1ID (0x1 << 9) +#define LCDC_LCDIDR_OVR2ID (0x1 << 10) +#define LCDC_LCDIDR_HEOID (0x1 << 11) +#define LCDC_LCDIDR_HCRID (0x1 << 12) +#define LCDC_LCDIDR_PPID (0x1 << 13) + +#define ATMEL_LCDC_LCDIMR 0x0034 +#define LCDC_LCDIMR_SOFIM (0x1 << 0) +#define LCDC_LCDIMR_DISIM (0x1 << 1) +#define LCDC_LCDIMR_DISPIM (0x1 << 2) +#define LCDC_LCDIMR_FIFOERRIM (0x1 << 4) +#define LCDC_LCDIMR_BASEIM (0x1 << 8) +#define LCDC_LCDIMR_OVR1IM (0x1 << 9) +#define LCDC_LCDIMR_OVR2IM (0x1 << 10) +#define LCDC_LCDIMR_HEOIM (0x1 << 11) +#define LCDC_LCDIMR_HCRIM (0x1 << 12) +#define LCDC_LCDIMR_PPIM (0x1 << 13) + +#define ATMEL_LCDC_LCDISR 0x0038 +#define LCDC_LCDISR_SOF (0x1 << 0) +#define LCDC_LCDISR_DIS (0x1 << 1) +#define LCDC_LCDISR_DISP (0x1 << 2) +#define LCDC_LCDISR_FIFOERR (0x1 << 4) +#define LCDC_LCDISR_BASE (0x1 << 8) +#define LCDC_LCDISR_OVR1 (0x1 << 9) +#define LCDC_LCDISR_OVR2 (0x1 << 10) +#define LCDC_LCDISR_HEO (0x1 << 11) +#define LCDC_LCDISR_HCR (0x1 << 12) +#define LCDC_LCDISR_PP (0x1 << 13) + +#define ATMEL_LCDC_BASECHER 0x0040 +#define LCDC_BASECHER_CHEN (0x1 << 0) +#define LCDC_BASECHER_UPDATEEN (0x1 << 1) +#define LCDC_BASECHER_A2QEN (0x1 << 2) + +#define ATMEL_LCDC_BASECHDR 0x0044 +#define LCDC_BASECHDR_CHDIS (0x1 << 0) +#define LCDC_BASECHDR_CHRST (0x1 << 8) + +#define ATMEL_LCDC_BASECHSR 0x0048 +#define LCDC_BASECHSR_CHSR (0x1 << 0) +#define LCDC_BASECHSR_UPDATESR (0x1 << 1) +#define LCDC_BASECHSR_A2QSR (0x1 << 2) + +#define ATMEL_LCDC_BASEIER 0x004C +#define LCDC_BASEIER_DMA (0x1 << 2) +#define LCDC_BASEIER_DSCR (0x1 << 3) +#define LCDC_BASEIER_ADD (0x1 << 4) +#define LCDC_BASEIER_DONE (0x1 << 5) +#define LCDC_BASEIER_OVR (0x1 << 6) + +#define ATMEL_LCDC_BASEIDR 0x0050 +#define LCDC_BASEIDR_DMA (0x1 << 2) +#define LCDC_BASEIDR_DSCR (0x1 << 3) +#define LCDC_BASEIDR_ADD (0x1 << 4) +#define LCDC_BASEIDR_DONE (0x1 << 5) +#define LCDC_BASEIDR_OVR (0x1 << 6) + +#define ATMEL_LCDC_BASEIMR 0x0054 +#define LCDC_BASEIMR_DMA (0x1 << 2) +#define LCDC_BASEIMR_DSCR (0x1 << 3) +#define LCDC_BASEIMR_ADD (0x1 << 4) +#define LCDC_BASEIMR_DONE (0x1 << 5) +#define LCDC_BASEIMR_OVR (0x1 << 6) + +#define ATMEL_LCDC_BASEISR 0x0058 +#define LCDC_BASEISR_DMA (0x1 << 2) +#define LCDC_BASEISR_DSCR (0x1 << 3) +#define LCDC_BASEISR_ADD (0x1 << 4) +#define LCDC_BASEISR_DONE (0x1 << 5) +#define LCDC_BASEISR_OVR (0x1 << 6) + +#define ATMEL_LCDC_BASEHEAD 0x005C + +#define ATMEL_LCDC_BASEADDR 0x0060 + +#define ATMEL_LCDC_BASECTRL 0x0064 +#define LCDC_BASECTRL_DFETCH (0x1 << 0) +#define LCDC_BASECTRL_LFETCH (0x1 << 1) +#define LCDC_BASECTRL_DMAIEN (0x1 << 2) +#define LCDC_BASECTRL_DSCRIEN (0x1 << 3) +#define LCDC_BASECTRL_ADDIEN (0x1 << 4) +#define LCDC_BASECTRL_DONEIEN (0x1 << 5) + +#define ATMEL_LCDC_BASENEXT 0x0068 + +#define ATMEL_LCDC_BASECFG0 0x006C +#define LCDC_BASECFG0_SIF (0x1 << 0) +#define LCDC_BASECFG0_BLEN_OFFSET 4 +#define LCDC_BASECFG0_BLEN (0x3 << LCDC_BASECFG0_BLEN_OFFSET) +#define LCDC_BASECFG0_BLEN_AHB_SINGLE (0x0 << 4) +#define LCDC_BASECFG0_BLEN_AHB_INCR4 (0x1 << 4) +#define LCDC_BASECFG0_BLEN_AHB_INCR8 (0x2 << 4) +#define LCDC_BASECFG0_BLEN_AHB_INCR16 (0x3 << 4) +#define LCDC_BASECFG0_DLBO (0x1 << 8) + +#define ATMEL_LCDC_BASECFG1 0x0070 +#define LCDC_BASECFG1_CLUTEN (0x1 << 0) +#define LCDC_BASECFG1_RGBMODE_OFFSET 4 +#define LCDC_BASECFG1_RGBMODE (0xf << LCDC_BASECFG1_RGBMODE_OFFSET) +#define LCDC_BASECFG1_RGBMODE_12BPP_RGB_444 (0x0 << 4) +#define LCDC_BASECFG1_RGBMODE_16BPP_ARGB_4444 (0x1 << 4) +#define LCDC_BASECFG1_RGBMODE_16BPP_RGBA_4444 (0x2 << 4) +#define LCDC_BASECFG1_RGBMODE_16BPP_RGB_565 (0x3 << 4) +#define LCDC_BASECFG1_RGBMODE_16BPP_TRGB_1555 (0x4 << 4) +#define LCDC_BASECFG1_RGBMODE_18BPP_RGB_666 (0x5 << 4) +#define LCDC_BASECFG1_RGBMODE_18BPP_RGB_666_PACKED (0x6 << 4) +#define LCDC_BASECFG1_RGBMODE_19BPP_TRGB_1666 (0x7 << 4) +#define LCDC_BASECFG1_RGBMODE_19BPP_TRGB_PACKED (0x8 << 4) +#define LCDC_BASECFG1_RGBMODE_24BPP_RGB_888 (0x9 << 4) +#define LCDC_BASECFG1_RGBMODE_24BPP_RGB_888_PACKED (0xA << 4) +#define LCDC_BASECFG1_RGBMODE_25BPP_TRGB_1888 (0xB << 4) +#define LCDC_BASECFG1_RGBMODE_32BPP_ARGB_8888 (0xC << 4) +#define LCDC_BASECFG1_RGBMODE_32BPP_RGBA_8888 (0xD << 4) +#define LCDC_BASECFG1_CLUTMODE_OFFSET 8 +#define LCDC_BASECFG1_CLUTMODE (0x3 << LCDC_BASECFG1_CLUTMODE_OFFSET) +#define LCDC_BASECFG1_CLUTMODE_1BPP (0x0 << 8) +#define LCDC_BASECFG1_CLUTMODE_2BPP (0x1 << 8) +#define LCDC_BASECFG1_CLUTMODE_4BPP (0x2 << 8) +#define LCDC_BASECFG1_CLUTMODE_8BPP (0x3 << 8) + +#define ATMEL_LCDC_BASECFG2 0x0074 + +#define ATMEL_LCDC_BASECFG3 0x0078 +#define LCDC_BASECFG3_BDEF_OFFSET 0 +#define LCDC_BASECFG3_BDEF (0xff << LCDC_BASECFG3_BDEF_OFFSET) +#define LCDC_BASECFG3_GDEF_OFFSET 8 +#define LCDC_BASECFG3_GDEF (0xff << LCDC_BASECFG3_GDEF_OFFSET) +#define LCDC_BASECFG3_RDEF_OFFSET 16 +#define LCDC_BASECFG3_RDEF (0xff << LCDC_BASECFG3_RDEF_OFFSET) + +#define ATMEL_LCDC_BASECFG4 0x007C +#define LCDC_BASECFG4_DMA (0x1 << 8) +#define LCDC_BASECFG4_REP (0x1 << 9) +#define LCDC_BASECFG4_DISCEN (0x1 << 11) + +#define ATMEL_LCDC_BASECFG5 0x0080 +#define LCDC_BASECFG5_DISCXPOS_OFFSET 0 +#define LCDC_BASECFG5_DISCXPOS (0x7ff << LCDC_BASECFG5_DISCXPOS_OFFSET) +#define LCDC_BASECFG5_DISCYPOS_OFFSET 16 +#define LCDC_BASECFG5_DISCYPOS (0x7ff << LCDC_BASECFG5_DISCYPOS_OFFSET) + +#define ATMEL_LCDC_BASECFG6 0x0084 +#define LCDC_BASECFG6_DISCXSIZE_OFFSET 0 +#define LCDC_BASECFG6_DISCXSIZE (0x7ff << LCDC_BASECFG6_DISCXSIZE_OFFSET) +#define LCDC_BASECFG6_DISCYSIZE_OFFSET 16 +#define LCDC_BASECFG6_DISCYSIZE (0x7ff << LCDC_BASECFG6_DISCYSIZE_OFFSET) + +#define ATMEL_LCDC_HEOCHER 0x0280 +#define ATMEL_LCDC2_HEOCHER 0x0340 +#define LCDC_HEOCHER_CHEN (0x1 << 0) +#define LCDC_HEOCHER_UPDATEEN (0x1 << 1) +#define LCDC_HEOCHER_A2QEN (0x1 << 2) + +#define ATMEL_LCDC_HEOCHDR 0x0284 +#define LCDC_HEOCHDR_CHDIS (0x1 << 0) +#define LCDC_HEOCHDR_CHRST (0x1 << 8) + +#define ATMEL_LCDC_HEOCHSR 0x0288 +#define LCDC_HEOCHSR_CHSR (0x1 << 0) +#define LCDC_HEOCHSR_UPDATESR (0x1 << 1) +#define LCDC_HEOCHSR_A2QSR (0x1 << 2) + +#define ATMEL_LCDC_HEOIER 0x028C +#define LCDC_HEOIER_DMA (0x1 << 2) +#define LCDC_HEOIER_DSCR (0x1 << 3) +#define LCDC_HEOIER_ADD (0x1 << 4) +#define LCDC_HEOIER_DONE (0x1 << 5) +#define LCDC_HEOIER_OVR (0x1 << 6) +#define LCDC_HEOIER_UDMA (0x1 << 10) +#define LCDC_HEOIER_UDSCR (0x1 << 11) +#define LCDC_HEOIER_UADD (0x1 << 12) +#define LCDC_HEOIER_UDONE (0x1 << 13) +#define LCDC_HEOIER_UOVR (0x1 << 14) +#define LCDC_HEOIER_VDMA (0x1 << 18) +#define LCDC_HEOIER_VDSCR (0x1 << 19) +#define LCDC_HEOIER_VADD (0x1 << 20) +#define LCDC_HEOIER_VDONE (0x1 << 21) +#define LCDC_HEOIER_VOVR (0x1 << 22) + +#define ATMEL_LCDC_HEOIDR 0x0290 +#define LCDC_HEOIDR_DMA (0x1 << 2) +#define LCDC_HEOIDR_DSCR (0x1 << 3) +#define LCDC_HEOIDR_ADD (0x1 << 4) +#define LCDC_HEOIDR_DONE (0x1 << 5) +#define LCDC_HEOIDR_OVR (0x1 << 6) +#define LCDC_HEOIDR_UDMA (0x1 << 10) +#define LCDC_HEOIDR_UDSCR (0x1 << 11) +#define LCDC_HEOIDR_UADD (0x1 << 12) +#define LCDC_HEOIDR_UDONE (0x1 << 13) +#define LCDC_HEOIDR_UOVR (0x1 << 14) +#define LCDC_HEOIDR_VDMA (0x1 << 18) +#define LCDC_HEOIDR_VDSCR (0x1 << 19) +#define LCDC_HEOIDR_VADD (0x1 << 20) +#define LCDC_HEOIDR_VDONE (0x1 << 21) +#define LCDC_HEOIDR_VOVR (0x1 << 22) + +#define ATMEL_LCDC_HEOIMR 0x0294 +#define LCDC_HEOIMR_DMA (0x1 << 2) +#define LCDC_HEOIMR_DSCR (0x1 << 3) +#define LCDC_HEOIMR_ADD (0x1 << 4) +#define LCDC_HEOIMR_DONE (0x1 << 5) +#define LCDC_HEOIMR_OVR (0x1 << 6) +#define LCDC_HEOIMR_UDMA (0x1 << 10) +#define LCDC_HEOIMR_UDSCR (0x1 << 11) +#define LCDC_HEOIMR_UADD (0x1 << 12) +#define LCDC_HEOIMR_UDONE (0x1 << 13) +#define LCDC_HEOIMR_UOVR (0x1 << 14) +#define LCDC_HEOIMR_VDMA (0x1 << 18) +#define LCDC_HEOIMR_VDSCR (0x1 << 19) +#define LCDC_HEOIMR_VADD (0x1 << 20) +#define LCDC_HEOIMR_VDONE (0x1 << 21) +#define LCDC_HEOIMR_VOVR (0x1 << 22) + +#define ATMEL_LCDC_HEOISR 0x0298 +#define LCDC_HEOISR_DMA (0x1 << 2) +#define LCDC_HEOISR_DSCR (0x1 << 3) +#define LCDC_HEOISR_ADD (0x1 << 4) +#define LCDC_HEOISR_DONE (0x1 << 5) +#define LCDC_HEOISR_OVR (0x1 << 6) +#define LCDC_HEOISR_UDMA (0x1 << 10) +#define LCDC_HEOISR_UDSCR (0x1 << 11) +#define LCDC_HEOISR_UADD (0x1 << 12) +#define LCDC_HEOISR_UDONE (0x1 << 13) +#define LCDC_HEOISR_UOVR (0x1 << 14) +#define LCDC_HEOISR_VDMA (0x1 << 18) +#define LCDC_HEOISR_VDSCR (0x1 << 19) +#define LCDC_HEOISR_VADD (0x1 << 20) +#define LCDC_HEOISR_VDONE (0x1 << 21) +#define LCDC_HEOISR_VOVR (0x1 << 22) + +#define ATMEL_LCDC_HEOHEAD 0x029C + +#define ATMEL_LCDC_HEOADDR 0x02A0 + +#define ATMEL_LCDC_HEOCTRL 0x02A4 +#define LCDC_HEOCTRL_DFETCH (0x1 << 0) +#define LCDC_HEOCTRL_LFETCH (0x1 << 1) +#define LCDC_HEOCTRL_DMAIEN (0x1 << 2) +#define LCDC_HEOCTRL_DSCRIEN (0x1 << 3) +#define LCDC_HEOCTRL_ADDIEN (0x1 << 4) +#define LCDC_HEOCTRL_DONEIEN (0x1 << 5) + +#define ATMEL_LCDC_HEONEXT 0x02A8 + +#define ATMEL_LCDC_HEOUHEAD 0x02AC + +#define ATMEL_LCDC_HEOUADDR 0x02B0 + +#define ATMEL_LCDC_HEOUCTRL 0x02B4 +#define LCDC_HEOUCTRL_UDFETCH (0x1 << 0) +#define LCDC_HEOUCTRL_UDMAIEN (0x1 << 2) +#define LCDC_HEOUCTRL_UDSCRIEN (0x1 << 3) +#define LCDC_HEOUCTRL_UADDIEN (0x1 << 4) +#define LCDC_HEOUCTRL_UDONEIEN (0x1 << 5) + +#define ATMEL_LCDC_HEOUNEXT 0x02B8 + +#define ATMEL_LCDC_HEOVHEAD 0x02BC + +#define ATMEL_LCDC_HEOVADDR 0x02C0 + +#define ATMEL_LCDC_HEOVCTRL 0x02C4 +#define LCDC_HEOVCTRL_VDFETCH (0x1 << 0) +#define LCDC_HEOVCTRL_VDMAIEN (0x1 << 2) +#define LCDC_HEOVCTRL_VDSCRIEN (0x1 << 3) +#define LCDC_HEOVCTRL_VADDIEN (0x1 << 4) +#define LCDC_HEOVCTRL_VDONEIEN (0x1 << 5) + +#define ATMEL_LCDC_HEOVNEXT 0x02C8 + +#define ATMEL_LCDC_HEOCFG0 0x02CC +#define LCDC_HEOCFG0_BLEN_OFFSET 4 +#define LCDC_HEOCFG0_BLEN (0x3 << LCDC_HEOCFG0_BLEN_OFFSET) +#define LCDC_HEOCFG0_BLEN_AHB_SINGLE (0x0 << 4) +#define LCDC_HEOCFG0_BLEN_AHB_INCR4 (0x1 << 4) +#define LCDC_HEOCFG0_BLEN_AHB_INCR8 (0x2 << 4) +#define LCDC_HEOCFG0_BLEN_AHB_INCR16 (0x3 << 4) +#define LCDC_HEOCFG0_BLENUV_OFFSET 6 +#define LCDC_HEOCFG0_BLENUV (0x3 << LCDC_HEOCFG0_BLENUV_OFFSET) +#define LCDC_HEOCFG0_BLENUV_AHB_SINGLE (0x0 << 6) +#define LCDC_HEOCFG0_BLENUV_AHB_INCR4 (0x1 << 6) +#define LCDC_HEOCFG0_BLENUV_AHB_INCR8 (0x2 << 6) +#define LCDC_HEOCFG0_BLENUV_AHB_INCR16 (0x3 << 6) +#define LCDC_HEOCFG0_DLBO (0x1 << 8) +#define LCDC_HEOCFG0_ROTDIS (0x1 << 12) +#define LCDC_HEOCFG0_LOCKDIS (0x1 << 13) + +#define ATMEL_LCDC_HEOCFG1 0x02D0 +#define LCDC_HEOCFG1_CLUTEN (0x1 << 0) +#define LCDC_HEOCFG1_YUVEN (0x1 << 1) +#define LCDC_HEOCFG1_RGBMODE_OFFSET 4 +#define LCDC_HEOCFG1_RGBMODE (0xf << LCDC_HEOCFG1_RGBMODE_OFFSET) +#define LCDC_HEOCFG1_RGBMODE_12BPP_RGB_444 (0x0 << 4) +#define LCDC_HEOCFG1_RGBMODE_16BPP_ARGB_4444 (0x1 << 4) +#define LCDC_HEOCFG1_RGBMODE_16BPP_RGBA_4444 (0x2 << 4) +#define LCDC_HEOCFG1_RGBMODE_16BPP_RGB_565 (0x3 << 4) +#define LCDC_HEOCFG1_RGBMODE_16BPP_TRGB_1555 (0x4 << 4) +#define LCDC_HEOCFG1_RGBMODE_18BPP_RGB_666 (0x5 << 4) +#define LCDC_HEOCFG1_RGBMODE_18BPP_RGB_666_PACKED (0x6 << 4) +#define LCDC_HEOCFG1_RGBMODE_19BPP_TRGB_1666 (0x7 << 4) +#define LCDC_HEOCFG1_RGBMODE_19BPP_TRGB_PACKED (0x8 << 4) +#define LCDC_HEOCFG1_RGBMODE_24BPP_RGB_888 (0x9 << 4) +#define LCDC_HEOCFG1_RGBMODE_24BPP_RGB_888_PACKED (0xA << 4) +#define LCDC_HEOCFG1_RGBMODE_25BPP_TRGB_1888 (0xB << 4) +#define LCDC_HEOCFG1_RGBMODE_32BPP_ARGB_8888 (0xC << 4) +#define LCDC_HEOCFG1_RGBMODE_32BPP_RGBA_8888 (0xD << 4) +#define LCDC_HEOCFG1_CLUTMODE_OFFSET 8 +#define LCDC_HEOCFG1_CLUTMODE (0x3 << LCDC_HEOCFG1_CLUTMODE_OFFSET) +#define LCDC_HEOCFG1_CLUTMODE_1BPP (0x0 << 8) +#define LCDC_HEOCFG1_CLUTMODE_2BPP (0x1 << 8) +#define LCDC_HEOCFG1_CLUTMODE_4BPP (0x2 << 8) +#define LCDC_HEOCFG1_CLUTMODE_8BPP (0x3 << 8) +#define LCDC_HEOCFG1_YUVMODE_OFFSET 12 +#define LCDC_HEOCFG1_YUVMODE (0xf << LCDC_HEOCFG1_YUVMODE_OFFSET) +#define LCDC_HEOCFG1_YUVMODE_32BPP_AYCBCR (0x0 << 12) +#define LCDC_HEOCFG1_YUVMODE_16BPP_YCBCR_MODE0 (0x1 << 12) +#define LCDC_HEOCFG1_YUVMODE_16BPP_YCBCR_MODE1 (0x2 << 12) +#define LCDC_HEOCFG1_YUVMODE_16BPP_YCBCR_MODE2 (0x3 << 12) +#define LCDC_HEOCFG1_YUVMODE_16BPP_YCBCR_MODE3 (0x4 << 12) +#define LCDC_HEOCFG1_YUVMODE_16BPP_YCBCR_SEMIPLANAR (0x5 << 12) +#define LCDC_HEOCFG1_YUVMODE_16BPP_YCBCR_PLANAR (0x6 << 12) +#define LCDC_HEOCFG1_YUVMODE_12BPP_YCBCR_SEMIPLANAR (0x7 << 12) +#define LCDC_HEOCFG1_YUVMODE_12BPP_YCBCR_PLANAR (0x8 << 12) +#define LCDC_HEOCFG1_YUV422ROT (0x1 << 16) +#define LCDC_HEOCFG1_YUV422SWP (0x1 << 17) + +#define ATMEL_LCDC_HEOCFG2 0x02D4 +#define LCDC_HEOCFG2_XOFFSET_OFFSET 0 +#define LCDC_HEOCFG2_XOFFSET (0x7ff << LCDC_HEOCFG2_XOFFSET_OFFSET) +#define LCDC_HEOCFG2_YOFFSET_OFFSET 16 +#define LCDC_HEOCFG2_YOFFSET (0x7ff << LCDC_HEOCFG2_YOFFSET_OFFSET) + +#define ATMEL_LCDC_HEOCFG3 0x02D8 +#define LCDC_HEOCFG3_XSIZE_OFFSET 0 +#define LCDC_HEOCFG3_XSIZE (0x7ff << LCDC_HEOCFG3_XSIZE_OFFSET) +#define LCDC_HEOCFG3_YSIZE_OFFSET 16 +#define LCDC_HEOCFG3_YSIZE (0x7ff << LCDC_HEOCFG3_YSIZE_OFFSET) + +#define ATMEL_LCDC_HEOCFG4 0x02DC +#define LCDC_HEOCFG4_XMEM_SIZE_OFFSET 0 +#define LCDC_HEOCFG4_XMEM_SIZE (0x7ff << LCDC_HEOCFG4_XMEM_SIZE_OFFSET) +#define LCDC_HEOCFG4_YMEM_SIZE_OFFSET 16 +#define LCDC_HEOCFG4_YMEM_SIZE (0x7ff << LCDC_HEOCFG4_YMEM_SIZE_OFFSET) + +#define ATMEL_LCDC_HEOCFG5 0x02E0 + +#define ATMEL_LCDC_HEOCFG6 0x02E4 + +#define ATMEL_LCDC_HEOCFG7 0x02E8 + +#define ATMEL_LCDC_HEOCFG8 0x02EC + +#define ATMEL_LCDC_HEOCFG9 0x02F0 +#define LCDC_HEOCFG9_BDEF_OFFSET 0 +#define LCDC_HEOCFG9_BDEF (0xff << LCDC_HEOCFG9_BDEF_OFFSET) +#define LCDC_HEOCFG9_GDEF_OFFSET 8 +#define LCDC_HEOCFG9_GDEF (0xff << LCDC_HEOCFG9_GDEF_OFFSET) +#define LCDC_HEOCFG9_RDEF_OFFSET 16 +#define LCDC_HEOCFG9_RDEF (0xff << LCDC_HEOCFG9_RDEF_OFFSET) + +#define ATMEL_LCDC_HEOCFG10 0x02F4 +#define LCDC_HEOCFG10_BKEY_OFFSET 0 +#define LCDC_HEOCFG10_BKEY (0xff << LCDC_HEOCFG10_BKEY_OFFSET) +#define LCDC_HEOCFG10_GKEY_OFFSET 8 +#define LCDC_HEOCFG10_GKEY (0xff << LCDC_HEOCFG10_GKEY_OFFSET) +#define LCDC_HEOCFG10_RKEY_OFFSET 16 +#define LCDC_HEOCFG10_RKEY (0xff << LCDC_HEOCFG10_RKEY_OFFSET) + +#define ATMEL_LCDC_HEOCFG11 0x02F8 +#define LCDC_HEOCFG11_BMASK_OFFSET 0 +#define LCDC_HEOCFG11_BMASK (0xff << LCDC_HEOCFG11_BMASK_OFFSET) +#define LCDC_HEOCFG11_GMASK_OFFSET 8 +#define LCDC_HEOCFG11_GMASK (0xff << LCDC_HEOCFG11_GMASK_OFFSET) +#define LCDC_HEOCFG11_RMASK_OFFSET 16 +#define LCDC_HEOCFG11_RMASK (0xff << LCDC_HEOCFG11_RMASK_OFFSET) + +#define ATMEL_LCDC_HEOCFG12 0x02FC +#define LCDC_HEOCFG12_CRKEY (0x1 << 0) +#define LCDC_HEOCFG12_INV (0x1 << 1) +#define LCDC_HEOCFG12_ITER2BL (0x1 << 2) +#define LCDC_HEOCFG12_ITER (0x1 << 3) +#define LCDC_HEOCFG12_REVALPHA (0x1 << 4) +#define LCDC_HEOCFG12_GAEN (0x1 << 5) +#define LCDC_HEOCFG12_LAEN (0x1 << 6) +#define LCDC_HEOCFG12_OVR (0x1 << 7) +#define LCDC_HEOCFG12_DMA (0x1 << 8) +#define LCDC_HEOCFG12_REP (0x1 << 9) +#define LCDC_HEOCFG12_DSTKEY (0x1 << 10) +#define LCDC_HEOCFG12_VIDPRI (0x1 << 12) +#define LCDC_HEOCFG12_GA_OFFSET 16 +#define LCDC_HEOCFG12_GA (0xff << LCDC_HEOCFG12_GA_OFFSET) + +#define ATMEL_LCDC_HEOCFG13 0x0300 +#define LCDC_HEOCFG13_XFACTOR_OFFSET 0 +#define LCDC_HEOCFG13_XFACTOR (0x1fff << LCDC_HEOCFG13_XFACTOR_OFFSET) +#define LCDC_HEOCFG13_YFACTOR_OFFSET 16 +#define LCDC_HEOCFG13_YFACTOR (0x1fff << LCDC_HEOCFG13_YFACTOR_OFFSET) +#define LCDC_HEOCFG13_SCALEN (0x1 << 31) + +#define ATMEL_LCDC_HEOCFG14 0x0304 +#define LCDC_HEOCFG14_CSCRY_OFFSET 0 +#define LCDC_HEOCFG14_CSCRY (0x3ff << LCDC_HEOCFG14_CSCRY_OFFSET) +#define LCDC_HEOCFG14_CSCRU_OFFSET 10 +#define LCDC_HEOCFG14_CSCRU (0x3ff << LCDC_HEOCFG14_CSCRU_OFFSET) +#define LCDC_HEOCFG14_CSCRV_OFFSET 20 +#define LCDC_HEOCFG14_CSCRV (0x3ff << LCDC_HEOCFG14_CSCRV_OFFSET) +#define LCDC_HEOCFG14_CSCYOFF (0x1 << 30) + +#define ATMEL_LCDC_HEOCFG15 0x0308 +#define LCDC_HEOCFG15_CSCGY_OFFSET 0 +#define LCDC_HEOCFG15_CSCGY (0x3ff << LCDC_HEOCFG15_CSCGY_OFFSET) +#define LCDC_HEOCFG15_CSCGU_OFFSET 10 +#define LCDC_HEOCFG15_CSCGU (0x3ff << LCDC_HEOCFG15_CSCGU_OFFSET) +#define LCDC_HEOCFG15_CSCGV_OFFSET 20 +#define LCDC_HEOCFG15_CSCGV (0x3ff << LCDC_HEOCFG15_CSCGV_OFFSET) +#define LCDC_HEOCFG15_CSCUOFF (0x1 << 30) + +#define ATMEL_LCDC_HEOCFG16 0x030C +#define LCDC_HEOCFG16_CSCBY_OFFSET 0 +#define LCDC_HEOCFG16_CSCBY (0x3ff << LCDC_HEOCFG16_CSCBY_OFFSET) +#define LCDC_HEOCFG16_CSCBU_OFFSET 10 +#define LCDC_HEOCFG16_CSCBU (0x3ff << LCDC_HEOCFG16_CSCBU_OFFSET) +#define LCDC_HEOCFG16_CSCBV_OFFSET 20 +#define LCDC_HEOCFG16_CSCBV (0x3ff << LCDC_HEOCFG16_CSCBV_OFFSET) +#define LCDC_HEOCFG16_CSCVOFF (0x1 << 30) + +#define ATMEL_LCDC_HCRCHER 0x0340 +#define LCDC_HCRCHER_CHEN (0x1 << 0) +#define LCDC_HCRCHER_UPDATEEN (0x1 << 1) +#define LCDC_HCRCHER_A2QEN (0x1 << 2) + +#define ATMEL_LCDC_HCRCHDR 0x0344 +#define LCDC_HCRCHDR_CHDIS (0x1 << 0) +#define LCDC_HCRCHDR_CHRST (0x1 << 8) + +#define ATMEL_LCDC_HCRCHSR 0x0348 +#define LCDC_HCRCHSR_CHSR (0x1 << 0) +#define LCDC_HCRCHSR_UPDATESR (0x1 << 1) +#define LCDC_HCRCHSR_A2QSR (0x1 << 2) + +#define ATMEL_LCDC_HCRIER 0x034C +#define LCDC_HCRIER_DMA (0x1 << 2) +#define LCDC_HCRIER_DSCR (0x1 << 3) +#define LCDC_HCRIER_ADD (0x1 << 4) +#define LCDC_HCRIER_DONE (0x1 << 5) +#define LCDC_HCRIER_OVR (0x1 << 6) + +#define ATMEL_LCDC_HCRIDR 0x0350 +#define LCDC_HCRIDR_DMA (0x1 << 2) +#define LCDC_HCRIDR_DSCR (0x1 << 3) +#define LCDC_HCRIDR_ADD (0x1 << 4) +#define LCDC_HCRIDR_DONE (0x1 << 5) +#define LCDC_HCRIDR_OVR (0x1 << 6) + +#define ATMEL_LCDC_HCRIMR 0x0354 +#define LCDC_HCRIMR_DMA (0x1 << 2) +#define LCDC_HCRIMR_DSCR (0x1 << 3) +#define LCDC_HCRIMR_ADD (0x1 << 4) +#define LCDC_HCRIMR_DONE (0x1 << 5) +#define LCDC_HCRIMR_OVR (0x1 << 6) + +#define ATMEL_LCDC_HCRISR 0x0358 +#define LCDC_HCRISR_DMA (0x1 << 2) +#define LCDC_HCRISR_DSCR (0x1 << 3) +#define LCDC_HCRISR_ADD (0x1 << 4) +#define LCDC_HCRISR_DONE (0x1 << 5) +#define LCDC_HCRISR_OVR (0x1 << 6) + +#define ATMEL_LCDC_HCRHEAD 0x035C + +#define ATMEL_LCDC_HCRADDR 0x0360 + +#define ATMEL_LCDC_HCRCTRL 0x0364 +#define LCDC_HCRCTRL_DFETCH (0x1 << 0) +#define LCDC_HCRCTRL_LFETCH (0x1 << 1) +#define LCDC_HCRCTRL_DMAIEN (0x1 << 2) +#define LCDC_HCRCTRL_DSCRIEN (0x1 << 3) +#define LCDC_HCRCTRL_ADDIEN (0x1 << 4) +#define LCDC_HCRCTRL_DONEIEN (0x1 << 5) + +#define ATMEL_LCDC_HCRNEXT 0x0368 + +#define ATMEL_LCDC_HCRCFG0 0x036C +#define LCDC_HCRCFG0_BLEN_OFFSET 4 +#define LCDC_HCRCFG0_BLEN (0x3 << LCDC_HCRCFG0_BLEN_OFFSET) +#define LCDC_HCRCFG0_BLEN_AHB_SINGLE (0x0 << 4) +#define LCDC_HCRCFG0_BLEN_AHB_INCR4 (0x1 << 4) +#define LCDC_HCRCFG0_BLEN_AHB_INCR8 (0x2 << 4) +#define LCDC_HCRCFG0_BLEN_AHB_INCR16 (0x3 << 4) +#define LCDC_HCRCFG0_DLBO (0x1 << 8) + +#define ATMEL_LCDC_HCRCFG1 0x0370 +#define LCDC_HCRCFG1_CLUTEN (0x1 << 0) +#define LCDC_HCRCFG1_RGBMODE_OFFSET 4 +#define LCDC_HCRCFG1_RGBMODE (0xf << LCDC_HCRCFG1_RGBMODE_OFFSET) +#define LCDC_HCRCFG1_RGBMODE_12BPP_RGB_444 (0x0 << 4) +#define LCDC_HCRCFG1_RGBMODE_16BPP_ARGB_4444 (0x1 << 4) +#define LCDC_HCRCFG1_RGBMODE_16BPP_RGBA_4444 (0x2 << 4) +#define LCDC_HCRCFG1_RGBMODE_16BPP_RGB_565 (0x3 << 4) +#define LCDC_HCRCFG1_RGBMODE_16BPP_TRGB_1555 (0x4 << 4) +#define LCDC_HCRCFG1_RGBMODE_18BPP_RGB_666 (0x5 << 4) +#define LCDC_HCRCFG1_RGBMODE_18BPP_RGB_666_PACKED (0x6 << 4) +#define LCDC_HCRCFG1_RGBMODE_19BPP_TRGB_1666 (0x7 << 4) +#define LCDC_HCRCFG1_RGBMODE_19BPP_TRGB_PACKED (0x8 << 4) +#define LCDC_HCRCFG1_RGBMODE_24BPP_RGB_888 (0x9 << 4) +#define LCDC_HCRCFG1_RGBMODE_24BPP_RGB_888_PACKED (0xA << 4) +#define LCDC_HCRCFG1_RGBMODE_25BPP_TRGB_1888 (0xB << 4) +#define LCDC_HCRCFG1_RGBMODE_32BPP_ARGB_8888 (0xC << 4) +#define LCDC_HCRCFG1_RGBMODE_32BPP_RGBA_8888 (0xD << 4) +#define LCDC_HCRCFG1_CLUTMODE_OFFSET 8 +#define LCDC_HCRCFG1_CLUTMODE (0x3 << LCDC_HCRCFG1_CLUTMODE_OFFSET) +#define LCDC_HCRCFG1_CLUTMODE_1BPP (0x0 << 8) +#define LCDC_HCRCFG1_CLUTMODE_2BPP (0x1 << 8) +#define LCDC_HCRCFG1_CLUTMODE_4BPP (0x2 << 8) +#define LCDC_HCRCFG1_CLUTMODE_8BPP (0x3 << 8) + +#define ATMEL_LCDC_HCRCFG2 0x0374 +#define LCDC_HCRCFG2_XOFFSET_OFFSET 0 +#define LCDC_HCRCFG2_XOFFSET (0x7ff << LCDC_HCRCFG2_XOFFSET_OFFSET) +#define LCDC_HCRCFG2_YOFFSET_OFFSET 16 +#define LCDC_HCRCFG2_YOFFSET (0x7ff << LCDC_HCRCFG2_YOFFSET_OFFSET) + +#define ATMEL_LCDC_HCRCFG3 0x0378 +#define LCDC_HCRCFG3_XSIZE_OFFSET 0 +#define LCDC_HCRCFG3_XSIZE (0x7f << LCDC_HCRCFG3_XSIZE_OFFSET) +#define LCDC_HCRCFG3_YSIZE_OFFSET 16 +#define LCDC_HCRCFG3_YSIZE (0x7f << LCDC_HCRCFG3_YSIZE_OFFSET) + +#define ATMEL_LCDC_HCRCFG4 0x037C + +#define ATMEL_LCDC_HCRCFG6 0x0384 +#define LCDC_HCRCFG6_BDEF_OFFSET 0 +#define LCDC_HCRCFG6_BDEF (0xff << LCDC_HCRCFG6_BDEF_OFFSET) +#define LCDC_HCRCFG6_GDEF_OFFSET 8 +#define LCDC_HCRCFG6_GDEF (0xff << LCDC_HCRCFG6_GDEF_OFFSET) +#define LCDC_HCRCFG6_RDEF_OFFSET 16 +#define LCDC_HCRCFG6_RDEF (0xff << LCDC_HCRCFG6_RDEF_OFFSET) + +#define ATMEL_LCDC_HCRCFG7 0x0388 +#define LCDC_HCRCFG7_BKEY_OFFSET 0 +#define LCDC_HCRCFG7_BKEY (0xff << LCDC_HCRCFG7_BKEY_OFFSET) +#define LCDC_HCRCFG7_GKEY_OFFSET 8 +#define LCDC_HCRCFG7_GKEY (0xff << LCDC_HCRCFG7_GKEY_OFFSET) +#define LCDC_HCRCFG7_RKEY_OFFSET 16 +#define LCDC_HCRCFG7_RKEY (0xff << LCDC_HCRCFG7_RKEY_OFFSET) + +#define ATMEL_LCDC_HCRCFG8 0x038C +#define LCDC_HCRCFG8_BMASK_OFFSET 0 +#define LCDC_HCRCFG8_BMASK (0xff << LCDC_HCRCFG8_BMASK_OFFSET) +#define LCDC_HCRCFG8_GMASK_OFFSET 8 +#define LCDC_HCRCFG8_GMASK (0xff << LCDC_HCRCFG8_GMASK_OFFSET) +#define LCDC_HCRCFG8_RMASK_OFFSET 16 +#define LCDC_HCRCFG8_RMASK (0xff << LCDC_HCRCFG8_RMASK_OFFSET) + +#define ATMEL_LCDC_HCRCFG9 0x0390 +#define LCDC_HCRCFG9_CRKEY (0x1 << 0) +#define LCDC_HCRCFG9_INV (0x1 << 1) +#define LCDC_HCRCFG9_ITER2BL (0x1 << 2) +#define LCDC_HCRCFG9_ITER (0x1 << 3) +#define LCDC_HCRCFG9_REVALPHA (0x1 << 4) +#define LCDC_HCRCFG9_GAEN (0x1 << 5) +#define LCDC_HCRCFG9_LAEN (0x1 << 6) +#define LCDC_HCRCFG9_OVR (0x1 << 7) +#define LCDC_HCRCFG9_DMA (0x1 << 8) +#define LCDC_HCRCFG9_REP (0x1 << 9) +#define LCDC_HCRCFG9_DSTKEY (0x1 << 10) +#define LCDC_HCRCFG9_GA_OFFSET 16 +#define LCDC_HCRCFG9_GA_Msk (0xff << LCDC_HCRCFG9_GA_OFFSET) + +#define ATMEL_LCDC_BASECLUT 0x400 +#define ATMEL_LCDC2_BASECLUT 0x600 +#define LCDC_BASECLUT_BCLUT_OFFSET 0 +#define LCDC_BASECLUT_BCLUT (0xff << LCDC_BASECLUT_BCLUT_OFFSET) +#define LCDC_BASECLUT_GCLUT_OFFSET 8 +#define LCDC_BASECLUT_GCLUT (0xff << LCDC_BASECLUT_GCLUT_OFFSET) +#define LCDC_BASECLUT_RCLUT_OFFSET 16 +#define LCDC_BASECLUT_RCLUT (0xff << LCDC_BASECLUT_RCLUT_OFFSET) + +#define ATMEL_LCDC_OVR1CLUT 0x800 +#define ATMEL_LCDC2_OVR1CLUT 0xa00 +#define LCDC_OVR1CLUT_BCLUT_OFFSET 0 +#define LCDC_OVR1CLUT_BCLUT (0xff << LCDC_OVR1CLUT_BCLUT_OFFSET) +#define LCDC_OVR1CLUT_GCLUT_OFFSET 8 +#define LCDC_OVR1CLUT_GCLUT (0xff << LCDC_OVR1CLUT_GCLUT_OFFSET) +#define LCDC_OVR1CLUT_RCLUT_OFFSET 16 +#define LCDC_OVR1CLUT_RCLUT (0xff << LCDC_OVR1CLUT_RCLUT_OFFSET) +#define LCDC_OVR1CLUT_ACLUT_OFFSET 24 +#define LCDC_OVR1CLUT_ACLUT (0xff << LCDC_OVR1CLUT_ACLUT_OFFSET) + +#define ATMEL_LCDC_OVR2CLUT 0xe00 +#define LCDC_OVR2CLUT_BCLUT_OFFSET 0 +#define LCDC_OVR2CLUT_BCLUT (0xff << LCDC_OVR2CLUT_BCLUT_OFFSET) +#define LCDC_OVR2CLUT_GCLUT_OFFSET 8 +#define LCDC_OVR2CLUT_GCLUT (0xff << LCDC_OVR2CLUT_GCLUT_OFFSET) +#define LCDC_OVR2CLUT_RCLUT_OFFSET 16 +#define LCDC_OVR2CLUT_RCLUT (0xff << LCDC_OVR2CLUT_RCLUT_OFFSET) +#define LCDC_OVR2CLUT_ACLUT_OFFSET 24 +#define LCDC_OVR2CLUT_ACLUT (0xff << LCDC_OVR2CLUT_ACLUT_OFFSET) + +#define ATMEL_LCDC_HEOCLUT 0x1000 +#define ATMEL_LCDC2_HEOCLUT 0x1200 +#define LCDC_HEOCLUT_BCLUT_OFFSET 0 +#define LCDC_HEOCLUT_BCLUT (0xff << LCDC_HEOCLUT_BCLUT_OFFSET) +#define LCDC_HEOCLUT_GCLUT_OFFSET 8 +#define LCDC_HEOCLUT_GCLUT (0xff << LCDC_HEOCLUT_GCLUT_OFFSET) +#define LCDC_HEOCLUT_RCLUT_OFFSET 16 +#define LCDC_HEOCLUT_RCLUT (0xff << LCDC_HEOCLUT_RCLUT_OFFSET) +#define LCDC_HEOCLUT_ACLUT_OFFSET 24 +#define LCDC_HEOCLUT_ACLUT (0xff << LCDC_HEOCLUT_ACLUT_OFFSET) + +#define ATMEL_LCDC_HCRCLUT 0x1400 +#define ATMEL_LCDC2_HCRCLUT 0x1600 +#define LCDC_HCRCLUT_BCLUT_OFFSET 0 +#define LCDC_HCRCLUT_BCLUT (0xff << LCDC_HCRCLUT_BCLUT_OFFSET) +#define LCDC_HCRCLUT_GCLUT_OFFSET 8 +#define LCDC_HCRCLUT_GCLUT (0xff << LCDC_HCRCLUT_GCLUT_OFFSET) +#define LCDC_HCRCLUT_RCLUT_OFFSET 16 +#define LCDC_HCRCLUT_RCLUT (0xff << LCDC_HCRCLUT_RCLUT_OFFSET) +#define LCDC_HCRCLUT_ACLUT_OFFSET 24 +#define LCDC_HCRCLUT_ACLUT (0xff << LCDC_HCRCLUT_ACLUT_OFFSET) + +/* Base layer CLUT */ +#define ATMEL_HLCDC_LUT 0x0400 + + +#endif /* __MACH_ATMEL_HLCDC4_H__ */ diff --git a/arch/arm/mach-at91/include/mach/barebox-arm-head.h b/arch/arm/mach-at91/include/mach/barebox-arm-head.h index a9c8dd44a7..7d6a009e2f 100644 --- a/arch/arm/mach-at91/include/mach/barebox-arm-head.h +++ b/arch/arm/mach-at91/include/mach/barebox-arm-head.h @@ -1,7 +1,7 @@ #ifndef __MACH_ARM_HEAD_H #define __MACH_ARM_HEAD_H -#ifdef CONFIG_SHELL_NONE +#ifdef CONFIG_AT91_LOAD_BAREBOX_SRAM #define AT91_EXV6 ".word _barebox_image_size\n" #else #define AT91_EXV6 ".word _barebox_bare_init_size\n" diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index b18f1c0a3d..71267e11e6 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -24,13 +24,19 @@ #include <i2c/i2c.h> #include <spi/spi.h> #include <linux/mtd/mtd.h> +#include <fb.h> +#include <video/atmel_lcdc.h> +#include <mach/atmel_hlcdc.h> +#include <linux/phy.h> /* USB Host */ struct at91_usbh_data { u8 ports; /* number of ports on root hub */ int vbus_pin[2]; /* port power-control pin */ + u8 vbus_pin_active_low[2]; /* vbus polarity */ }; extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data); +extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data); void atmel_nand_load_image(void *dest, int size, int pagesize, int blocksize); @@ -70,7 +76,7 @@ struct at91_ether_platform_data { unsigned int phy_flags; unsigned int flags; int phy_addr; - int is_rmii; + phy_interface_t phy_interface; int (*get_ethaddr)(struct eth_device*, unsigned char *adr); }; @@ -147,7 +153,6 @@ static inline struct device_d * at91_register_uart(unsigned id, unsigned pins) struct atmel_mci_platform_data { unsigned slot_b; unsigned bus_width; - unsigned host_caps; /* MCI_MODE_* from mci.h */ int detect_pin; int wp_pin; }; @@ -161,4 +166,6 @@ struct at91_spi_platform_data { }; void at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata); + +void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data); #endif diff --git a/arch/arm/mach-at91/include/mach/bootstrap.h b/arch/arm/mach-at91/include/mach/bootstrap.h new file mode 100644 index 0000000000..a3d19dd54a --- /dev/null +++ b/arch/arm/mach-at91/include/mach/bootstrap.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPLv2 + */ + +#ifndef __MACH_BOOTSTRAP_H__ +#define __MACH_BOOTSTRAP_H__ + +#ifdef CONFIG_MTD_M25P80 +void * bootstrap_board_read_m25p80(void); +#else +static inline void * bootstrap_board_read_m25p80(void) +{ + return NULL; +} +#endif + +#ifdef CONFIG_MTD_DATAFLASH +void * bootstrap_board_read_dataflash(void); +#else +static inline void * bootstrap_board_read_dataflash(void) +{ + return NULL; +} +#endif + +#endif /* __MACH_BOOTSTRAP_H__ */ diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index b6504c19d5..7132489132 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h @@ -26,6 +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_AT91SAM9XE128 0x329973a0 #define ARCH_ID_AT91SAM9XE256 0x329a93a0 @@ -47,6 +48,11 @@ #define ARCH_EXID_AT91SAM9G25 0x00000003 #define ARCH_EXID_AT91SAM9X25 0x00000004 +#define ARCH_EXID_SAMA5D31 0x00444300 +#define ARCH_EXID_SAMA5D33 0x00414300 +#define ARCH_EXID_SAMA5D34 0x00414301 +#define ARCH_EXID_SAMA5D35 0x00584300 + #define ARCH_FAMILY_AT91X92 0x09200000 #define ARCH_FAMILY_AT91SAM9 0x01900000 #define ARCH_FAMILY_AT91SAM9XE 0x02900000 @@ -75,6 +81,9 @@ enum at91_soc_type { /* SAM9N12 */ AT91_SOC_SAM9N12, + /* SAMA5D3 */ + AT91_SOC_SAMA5D3, + /* Unknown type */ AT91_SOC_NONE }; @@ -93,6 +102,10 @@ enum at91_soc_subtype { AT91_SOC_SAM9G15, AT91_SOC_SAM9G35, AT91_SOC_SAM9X35, AT91_SOC_SAM9G25, AT91_SOC_SAM9X25, + /* SAMA5D3 */ + AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34, + AT91_SOC_SAMA5D35, + /* Unknown subtype */ AT91_SOC_SUBTYPE_NONE }; @@ -187,6 +200,20 @@ static inline int at91_soc_is_detected(void) #define cpu_is_at91sam9n12() (0) #endif +#ifdef CONFIG_ARCH_SAMA5D3 +#define cpu_is_sama5d3() (at91_soc_initdata.type == AT91_SOC_SAMA5D3) +#define cpu_is_sama5d31() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D31) +#define cpu_is_sama5d33() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D33) +#define cpu_is_sama5d34() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D34) +#define cpu_is_sama5d35() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D35) +#else +#define cpu_is_sama5d3() (0) +#define cpu_is_sama5d31() (0) +#define cpu_is_sama5d33() (0) +#define cpu_is_sama5d34() (0) +#define cpu_is_sama5d35() (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 e283b9d9ad..8f004deb42 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -38,6 +38,8 @@ #include <mach/at91sam9n12.h> #elif defined(CONFIG_ARCH_AT91SAM9X5) #include <mach/at91sam9x5.h> +#elif defined(CONFIG_ARCH_SAMA5D3) +#include <mach/sama5d3.h> #elif defined(CONFIG_ARCH_AT91CAP9) #include <mach/at91cap9.h> #elif defined(CONFIG_ARCH_AT91X40) @@ -56,6 +58,12 @@ #define AT91_CHIPSELECT_6 0x70000000 #define AT91_CHIPSELECT_7 0x80000000 +#define SAMA5_CHIPSELECT_0 0x10000000 +#define SAMA5_DDRCS 0x20000000 +#define SAMA5_CHIPSELECT_1 0x40000000 +#define SAMA5_CHIPSELECT_2 0x50000000 +#define SAMA5_CHIPSELECT_3 0x60000000 + /* SDRAM */ #ifdef CONFIG_DRAM_BASE #define AT91_SDRAM_BASE CONFIG_DRAM_BASE diff --git a/arch/arm/mach-at91/include/mach/sama5d3.h b/arch/arm/mach-at91/include/mach/sama5d3.h new file mode 100644 index 0000000000..6884ff6a7e --- /dev/null +++ b/arch/arm/mach-at91/include/mach/sama5d3.h @@ -0,0 +1,152 @@ +/* + * Chip-specific header file for the SAMA5D3 family + * + * Copyright (C) 2009-2012 Atmel Corporation. + * + * Common definitions. + * Based on SAMA5D3 datasheet. + * + * Licensed under GPLv2 or later. + */ + +#ifndef SAMA5D3_H +#define SAMA5D3_H + +/* + * Peripheral identifiers/interrupts. + */ +#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ +#define AT91_ID_SYS 1 /* System Peripherals */ +#define SAMA5D3_ID_DBGU 2 /* debug Unit (usually no special interrupt line) */ +#define SAMA5D3_ID_PIT 3 /* Periodic Interval Timer Interrupt */ +#define SAMA5D3_ID_WDT 4 /* Watchdog timer Interrupt */ +#define SAMA5D3_ID_HSMC5 5 /* Static Memory Controller */ +#define SAMA5D3_ID_PIOA 6 /* Parallel I/O Controller A */ +#define SAMA5D3_ID_PIOB 7 /* Parallel I/O Controller B */ +#define SAMA5D3_ID_PIOC 8 /* Parallel I/O Controller C */ +#define SAMA5D3_ID_PIOD 9 /* Parallel I/O Controller D */ +#define SAMA5D3_ID_PIOE 10 /* Parallel I/O Controller E */ +#define SAMA5D3_ID_SMD 11 /* SMD Soft Modem */ +#define SAMA5D3_ID_USART0 12 /* USART0 */ +#define SAMA5D3_ID_USART1 13 /* USART1 */ +#define SAMA5D3_ID_USART2 14 /* USART2 */ +#define SAMA5D3_ID_USART3 15 /* USART3 */ +#define SAMA5D3_ID_UART0 16 /* UART0 */ +#define SAMA5D3_ID_UART1 17 /* UART1 */ +#define SAMA5D3_ID_TWI0 18 /* Two-Wire Interface 0 */ +#define SAMA5D3_ID_TWI1 19 /* Two-Wire Interface 1 */ +#define SAMA5D3_ID_TWI2 20 /* Two-Wire Interface 2 */ +#define SAMA5D3_ID_HSMCI0 21 /* High Speed Multimedia Card Interface 0 */ +#define SAMA5D3_ID_HSMCI1 22 /* High Speed Multimedia Card Interface 1 */ +#define SAMA5D3_ID_HSMCI2 23 /* High Speed Multimedia Card Interface 2 */ +#define SAMA5D3_ID_SPI0 24 /* Serial Peripheral Interface 0 */ +#define SAMA5D3_ID_SPI1 25 /* Serial Peripheral Interface 1 */ +#define SAMA5D3_ID_TC0 26 /* Timer Counter 0 (ch. 0, 1, 2) */ +#define SAMA5D3_ID_TC1 27 /* Timer Counter 1 (ch. 3, 4, 5) */ +#define SAMA5D3_ID_PWM 28 /* Pulse Width Modulation Controller */ +#define SAMA5D3_ID_ADC 29 /* Touch Screen ADC Controller */ +#define SAMA5D3_ID_DMA0 30 /* DMA Controller 0 */ +#define SAMA5D3_ID_DMA1 31 /* DMA Controller 1 */ +#define SAMA5D3_ID_UHPHS 32 /* USB Host High Speed */ +#define SAMA5D3_ID_UDPHS 33 /* USB Device High Speed */ +#define SAMA5D3_ID_GMAC 34 /* Gigabit Ethernet MAC */ +#define SAMA5D3_ID_EMAC 35 /* Ethernet MAC */ +#define SAMA5D3_ID_LCDC 36 /* LCD Controller */ +#define SAMA5D3_ID_ISI 37 /* Image Sensor Interface */ +#define SAMA5D3_ID_SSC0 38 /* Synchronous Serial Controller 0 */ +#define SAMA5D3_ID_SSC1 39 /* Synchronous Serial Controller 1 */ +#define SAMA5D3_ID_CAN0 40 /* CAN controller 0 */ +#define SAMA5D3_ID_CAN1 41 /* CAN controller 1 */ +#define SAMA5D3_ID_SHA 42 /* Secure Hash Algorithm */ +#define SAMA5D3_ID_AES 43 /* Advanced Encryption Standard */ +#define SAMA5D3_ID_TDES 44 /* Triple Data Encryption Standard */ +#define SAMA5D3_ID_TRNG 45 /* True Random Number Generator */ +#define SAMA5D3_ID_ARM 46 /* Performance Monitor Unit */ +#define SAMA5D3_ID_AIC 47 /* Advanced Interrupt Controller */ +#define SAMA5D3_ID_FUSE 48 /* Fuse Controller */ +#define SAMA5D3_ID_MPDDRC 49 /* MPDDR controller */ + +/* + * User Peripheral physical base addresses. + */ + +#define SAMA5D3_BASE_HSMCI0 0xf0000000 /* (MMCI) Base Address */ +#define SAMA5D3_BASE_SPI0 0xf0004000 +#define SAMA5D3_BASE_TC0 0xf0010000 /* (TC0) Base Address */ +#define SAMA5D3_BASE_TC1 0xf0010040 /* (TC1) Base Address */ +#define SAMA5D3_BASE_USART0 0xf001c000 +#define SAMA5D3_BASE_USART1 0xf0020000 +#define SAMA5D3_BASE_GMAC 0xf0028000 /* (GMAC) Base Address */ +#define SAMA5D3_BASE_LCDC 0xf0030000 /* (HLCDC5) Base Address */ +#define SAMA5D3_BASE_HSMCI1 0xf8000000 +#define SAMA5D3_BASE_HSMCI2 0xf8004000 +#define SAMA5D3_BASE_SPI1 0xf8008000 +#define SAMA5D3_BASE_EMAC 0xf802c000 /* (EMAC) Base Address */ +#define SAMA5D3_BASE_UDPHS 0xf8030000 +#define AT91_BASE_SYS 0xffffc000 + +/* + * System Peripherals (offset from AT91_BASE_SYS) + */ +#define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) +#define AT91_GPBR (0xfffffe60 - AT91_BASE_SYS) // KO OAR_TEMP, NO GPBR, error while building in "drivers/rtc/rtc-at91sam9.c" +#define AT91_DDRSDRC0 (0xffffea00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffe00 - AT91_BASE_SYS) + +#define SAMA5D3_BASE_PIOA 0xfffff200 +#define SAMA5D3_BASE_PIOB 0xfffff400 +#define SAMA5D3_BASE_PIOC 0xfffff600 +#define SAMA5D3_BASE_PIOD 0xfffff800 +#define SAMA5D3_BASE_PIOE 0xfffffa00 +#define SAMA5D3_BASE_MPDDRC 0xffffea00 +#define SAMA5D3_BASE_HSMC 0xffffc000 +#define SAMA5D3_BASE_PIT 0xfffffe30 +#define SAMA5D3_BASE_WDT 0xfffffe40 + +#define SAMA5D3_BASE_PMECC 0xffffc070 +#define SAMA5D3_BASE_PMERRLOC 0xffffc500 + +#define AT91_NB_USART 3 + +/* + * Internal Memory. + */ +#define SAMA5D3_SRAM_BASE 0x00300000 /* Internal SRAM base address */ +#define SAMA5D3_SRAM_SIZE (128 * SZ_1K) /* Internal SRAM size (128Kb) */ + +#define SAMA5D3_ROM_BASE 0x00100000 +#define SAMA5D3_ROM_SIZE SZ_1M + +#define SAMA5D3_UDPHS_FIFO 0x00500000 +#define SAMA5D3_OHCI_BASE 0x00600000 /* USB Host controller (OHCI) */ +#define SAMA5D3_EHCI_BASE 0x00700000 /* USB Host controller (EHCI) */ + +/* + * DMA0 peripheral identifiers + * for hardware handshaking interface + */ +#define SAMA5_DMA_ID_MCI0 0 +#define SAMA5_DMA_ID_SPI0_TX 1 +#define SAMA5_DMA_ID_SPI0_RX 2 +#define SAMA5_DMA_ID_USART0_TX 3 +#define SAMA5_DMA_ID_USART0_RX 4 +#define SAMA5_DMA_ID_USART1_TX 5 +#define SAMA5_DMA_ID_USART1_RX 6 +#define SAMA5_DMA_ID_TWI0_TX 7 +#define SAMA5_DMA_ID_TWI0_RX 8 +#define SAMA5_DMA_ID_TWI1_TX 9 +#define SAMA5_DMA_ID_TWI1_RX 10 +#define SAMA5_DMA_ID_UART0_TX 11 +#define SAMA5_DMA_ID_UART0_RX 12 +#define SAMA5_DMA_ID_SSC0_TX 13 +#define SAMA5_DMA_ID_SSC0_RX 14 +#define SAMA5_DMA_ID_SMD_TX 15 +#define SAMA5_DMA_ID_SMD_RX 16 + +/* + * DMA1 peripheral identifiers + * for hardware handshaking interface + */ +#define SAMA5_DMA_ID_MCI1 0 + +#endif diff --git a/arch/arm/mach-at91/include/mach/sama5d3_matrix.h b/arch/arm/mach-at91/include/mach/sama5d3_matrix.h new file mode 100644 index 0000000000..8176b38bd3 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/sama5d3_matrix.h @@ -0,0 +1,15 @@ +/* + * Matrix-centric header file for the SAMA5D3 family + * + * Copyright (C) 2009-2012 Atmel Corporation. + * + * Only EBI related registers. + * Write Protect register definitions may be useful. + * + * Licensed under GPLv2 or later. + */ + +#ifndef SAMA5D3_MATRIX_H +#define SAMA5D3_MATRIX_H + +#endif diff --git a/arch/arm/mach-at91/sama5d3.c b/arch/arm/mach-at91/sama5d3.c new file mode 100644 index 0000000000..0eec696f6e --- /dev/null +++ b/arch/arm/mach-at91/sama5d3.c @@ -0,0 +1,397 @@ +#include <common.h> +#include <gpio.h> +#include <init.h> +#include <asm/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" + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ + + +static struct clk pit_clk = { + .name = "pit_clk", + .pid = SAMA5D3_ID_PIT, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk smc_clk = { + .name = "smc_clk", + .pid = SAMA5D3_ID_HSMC5, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioA_clk = { + .name = "pioA_clk", + .pid = SAMA5D3_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pid = SAMA5D3_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .pid = SAMA5D3_ID_PIOC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioD_clk = { + .name = "pioD_clk", + .pid = SAMA5D3_ID_PIOD, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioE_clk = { + .name = "pioE_clk", + .pid = SAMA5D3_ID_PIOE, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk smd_clk = { + .name = "smd_clk", + .pid = SAMA5D3_ID_SMD, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pid = SAMA5D3_ID_USART0, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pid = SAMA5D3_ID_USART1, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pid = SAMA5D3_ID_USART2, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk usart3_clk = { + .name = "usart3_clk", + .pid = SAMA5D3_ID_USART3, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk uart0_clk = { + .name = "uart0_clk", + .pid = SAMA5D3_ID_UART0, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk uart1_clk = { + .name = "uart1_clk", + .pid = SAMA5D3_ID_UART1, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk twi0_clk = { + .name = "twi0_clk", + .pid = SAMA5D3_ID_TWI0, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk twi1_clk = { + .name = "twi1_clk", + .pid = SAMA5D3_ID_TWI1, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk twi2_clk = { + .name = "twi2_clk", + .pid = SAMA5D3_ID_TWI2, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk mmc0_clk = { + .name = "mci0_clk", + .pid = SAMA5D3_ID_HSMCI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc1_clk = { + .name = "mci1_clk", + .pid = SAMA5D3_ID_HSMCI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc2_clk = { + .name = "mci2_clk", + .pid = SAMA5D3_ID_HSMCI2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pid = SAMA5D3_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi1_clk = { + .name = "spi1_clk", + .pid = SAMA5D3_ID_SPI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tcb0_clk = { + .name = "tcb0_clk", + .pid = SAMA5D3_ID_TC0, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk tcb1_clk = { + .name = "tcb1_clk", + .pid = SAMA5D3_ID_TC1, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk pwm_clk = { + .name = "pwm_clk", + .pid = SAMA5D3_ID_PWM, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk adc_clk = { + .name = "adc_clk", + .pid = SAMA5D3_ID_ADC, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk dma0_clk = { + .name = "dma0_clk", + .pid = SAMA5D3_ID_DMA0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk dma1_clk = { + .name = "dma1_clk", + .pid = SAMA5D3_ID_DMA1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk uhphs_clk = { + .name = "uhphs", + .pid = SAMA5D3_ID_UHPHS, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udphs_clk = { + .name = "udphs_clk", + .pid = SAMA5D3_ID_UDPHS, + .type = CLK_TYPE_PERIPHERAL, +}; +/* gmac only for sama5d33, sama5d34, sama5d35 */ +static struct clk macb0_clk = { + .name = "macb0_clk", + .pid = SAMA5D3_ID_GMAC, + .type = CLK_TYPE_PERIPHERAL, +}; +/* emac only for sama5d31, sama5d35 */ +static struct clk macb1_clk = { + .name = "macb1_clk", + .pid = SAMA5D3_ID_EMAC, + .type = CLK_TYPE_PERIPHERAL, +}; +/* lcd only for sama5d31, sama5d33, sama5d34 */ +static struct clk lcdc_clk = { + .name = "lcdc_clk", + .pid = SAMA5D3_ID_LCDC, + .type = CLK_TYPE_PERIPHERAL, +}; +/* isi only for sama5d33, sama5d35 */ +static struct clk isi_clk = { + .name = "isi_clk", + .pid = SAMA5D3_ID_ISI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc0_clk = { + .name = "ssc0_clk", + .pid = SAMA5D3_ID_SSC0, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk ssc1_clk = { + .name = "ssc1_clk", + .pid = SAMA5D3_ID_SSC1, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk can0_clk = { + .name = "can0_clk", + .pid = SAMA5D3_ID_CAN0, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk can1_clk = { + .name = "can1_clk", + .pid = SAMA5D3_ID_CAN1, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV2, +}; +static struct clk sha_clk = { + .name = "sha_clk", + .pid = SAMA5D3_ID_SHA, + .type = CLK_TYPE_PERIPHERAL, + .div = AT91_PMC_PCR_DIV8, +}; +static struct clk aes_clk = { + .name = "aes_clk", + .pid = SAMA5D3_ID_AES, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tdes_clk = { + .name = "tdes_clk", + .pid = SAMA5D3_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, + &smd_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &usart3_clk, + &uart0_clk, + &uart1_clk, + &twi0_clk, + &twi1_clk, + &twi2_clk, + &mmc0_clk, + &mmc1_clk, + &mmc2_clk, + &spi0_clk, + &spi1_clk, + &tcb0_clk, + &tcb1_clk, + &pwm_clk, + &adc_clk, + &dma0_clk, + &dma1_clk, + &uhphs_clk, + &udphs_clk, + &ssc0_clk, + &ssc1_clk, + &can0_clk, + &can1_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("macb_clk", "macb1", &macb1_clk), + CLKDEV_CON_ID("ohci_clk", &uhphs_clk), + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi0", &spi0_clk), + CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi1", &spi1_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("mci_clk", "atmel_mci2", &mmc2_clk), + CLKDEV_DEV_ID("at91sam9x5-gpio0", &pioA_clk), + CLKDEV_DEV_ID("at91sam9x5-gpio1", &pioB_clk), + CLKDEV_DEV_ID("at91sam9x5-gpio2", &pioC_clk), + CLKDEV_DEV_ID("at91sam9x5-gpio3", &pioD_clk), + CLKDEV_DEV_ID("at91sam9x5-gpio4", &pioE_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_usart2", &usart1_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart3", &usart2_clk), + CLKDEV_CON_DEV_ID("usart", "atmel_usart4", &usart3_clk), +}; + +static void __init sama5d3_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clkdev_add_table(periph_clocks_lookups, + ARRAY_SIZE(periph_clocks_lookups)); + clkdev_add_table(usart_clocks_lookups, + ARRAY_SIZE(usart_clocks_lookups)); + + if ( cpu_is_sama5d33() + || cpu_is_sama5d34() + || cpu_is_sama5d35() ) + clk_register(&macb0_clk); + + if ( cpu_is_sama5d31() + || cpu_is_sama5d35() ) + clk_register(&macb1_clk); + + if (!cpu_is_sama5d35()) + clk_register(&lcdc_clk); + + clk_register(&isi_clk); + + clk_register(&pck0); + clk_register(&pck1); + clk_register(&pck2); + + /* ensure dma are enabled */ + //clk_enable(&dma0_clk); + //clk_enable(&dma1_clk); +} + +/* -------------------------------------------------------------------- + * AT91SAM9x5 processor initialization + * -------------------------------------------------------------------- */ + +static void sama5d3_initialize(void) +{ + /* Init clock subsystem */ + at91_clock_init(AT91_MAIN_CLOCK); + + /* Register the processor-specific clocks */ + sama5d3_register_clocks(); + + /* Register GPIO subsystem */ + at91_add_sam9x5_gpio(0, SAMA5D3_BASE_PIOA); + at91_add_sam9x5_gpio(1, SAMA5D3_BASE_PIOB); + at91_add_sam9x5_gpio(2, SAMA5D3_BASE_PIOC); + at91_add_sam9x5_gpio(3, SAMA5D3_BASE_PIOD); + at91_add_sam9x5_gpio(4, SAMA5D3_BASE_PIOE); + + at91_add_pit(SAMA5D3_BASE_PIT); + at91_add_sam9_smc(DEVICE_ID_SINGLE, SAMA5D3_BASE_HSMC + 0x600, 0xa0); +} + +AT91_SOC_START(sama5d3) + .init = sama5d3_initialize, +AT91_SOC_END diff --git a/arch/arm/mach-at91/sama5d3_devices.c b/arch/arm/mach-at91/sama5d3_devices.c new file mode 100644 index 0000000000..3e4531e8a9 --- /dev/null +++ b/arch/arm/mach-at91/sama5d3_devices.c @@ -0,0 +1,497 @@ +/* + * On-Chip devices setup code for the AT91SAM9x5 family + * + * Copyright (C) 2010 Atmel Corporation. + * + * 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 <asm/armlinux.h> +#include <asm/hardware.h> +#include <mach/board.h> +#include <mach/at91_pmc.h> +#include <mach/at91sam9x5_matrix.h> +#include <mach/at91sam9_ddrsdr.h> +#include <mach/gpio.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", SAMA5D3_SRAM_BASE, + SAMA5D3_SRAM_SIZE, IORESOURCE_MEM_WRITEABLE); +} + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_NAND_ATMEL) +static struct resource nand_resources[] = { + [0] = { + .start = SAMA5_CHIPSELECT_3, + .end = SAMA5_CHIPSELECT_3 + SZ_256M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = SAMA5D3_BASE_PMECC, + .end = SAMA5D3_BASE_PMECC + 0x490 - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = SAMA5D3_BASE_PMERRLOC, + .end = SAMA5D3_BASE_PMERRLOC + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [3] = { + .start = SAMA5D3_ROM_BASE, + .end = SAMA5D3_ROM_BASE + SAMA5D3_ROM_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +void __init at91_add_device_nand(struct atmel_nand_data *data) +{ + if (!data) + return; + + switch (data->pmecc_sector_size) { + case 512: + data->pmecc_lookup_table_offset = 0x10000; + break; + case 1024: + data->pmecc_lookup_table_offset = 0x18000; + break; + default: + pr_err("%s: invalid pmecc_sector_size (%d)\n", __func__, + data->pmecc_sector_size); + return; + } + + at91_set_A_periph(AT91_PIN_PE21, 1); /* ALE */ + at91_set_A_periph(AT91_PIN_PE22, 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 at91_ether_platform_data *data) +{ + if (!data) + return; + + switch (id) { + case 0: + if (cpu_is_sama5d31()) { + pr_warn("AT91: no gmac on sama5d31\n"); + return; + } + + at91_set_A_periph(AT91_PIN_PB16, 0); /* GMDC */ + at91_set_A_periph(AT91_PIN_PB17, 0); /* GMDIO */ + + at91_set_A_periph(AT91_PIN_PB9, 0); /* GTXEN */ + at91_set_A_periph(AT91_PIN_PB11, 0); /* GRXCK */ + at91_set_A_periph(AT91_PIN_PB13, 0); /* GRXER */ + + switch (data->phy_interface) { + case PHY_INTERFACE_MODE_GMII: + at91_set_B_periph(AT91_PIN_PB19, 0); /* GTX4 */ + at91_set_B_periph(AT91_PIN_PB20, 0); /* GTX5 */ + at91_set_B_periph(AT91_PIN_PB21, 0); /* GTX6 */ + at91_set_B_periph(AT91_PIN_PB22, 0); /* GTX7 */ + at91_set_B_periph(AT91_PIN_PB23, 0); /* GRX4 */ + at91_set_B_periph(AT91_PIN_PB24, 0); /* GRX5 */ + at91_set_B_periph(AT91_PIN_PB25, 0); /* GRX6 */ + at91_set_B_periph(AT91_PIN_PB26, 0); /* GRX7 */ + case PHY_INTERFACE_MODE_MII: + case PHY_INTERFACE_MODE_RGMII: + at91_set_A_periph(AT91_PIN_PB0, 0); /* GTX0 */ + at91_set_A_periph(AT91_PIN_PB1, 0); /* GTX1 */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* GTX2 */ + at91_set_A_periph(AT91_PIN_PB3, 0); /* GTX3 */ + at91_set_A_periph(AT91_PIN_PB4, 0); /* GRX0 */ + at91_set_A_periph(AT91_PIN_PB5, 0); /* GRX1 */ + at91_set_A_periph(AT91_PIN_PB6, 0); /* GRX2 */ + at91_set_A_periph(AT91_PIN_PB7, 0); /* GRX3 */ + break; + default: + return; + } + + switch (data->phy_interface) { + case PHY_INTERFACE_MODE_MII: + at91_set_A_periph(AT91_PIN_PB8, 0); /* GTXCK */ + at91_set_A_periph(AT91_PIN_PB10, 0); /* GTXER */ + at91_set_A_periph(AT91_PIN_PB12, 0); /* GRXDV */ + at91_set_A_periph(AT91_PIN_PB14, 0); /* GCRS */ + at91_set_A_periph(AT91_PIN_PB15, 0); /* GCOL */ + break; + case PHY_INTERFACE_MODE_RGMII: + at91_set_A_periph(AT91_PIN_PB8, 0); /* GTXCK */ + at91_set_A_periph(AT91_PIN_PB18, 0); /* G125CK */ + break; + case PHY_INTERFACE_MODE_GMII: + at91_set_A_periph(AT91_PIN_PB10, 0); /* GTXER */ + at91_set_A_periph(AT91_PIN_PB12, 0); /* GRXDV */ + at91_set_A_periph(AT91_PIN_PB14, 0); /* GCRS */ + at91_set_A_periph(AT91_PIN_PB15, 0); /* GCOL */ + at91_set_A_periph(AT91_PIN_PB27, 0); /* G125CK0 */ + break; + default: + return; + } + + add_generic_device("macb", id, NULL, SAMA5D3_BASE_GMAC, SZ_16K, + IORESOURCE_MEM, data); + break; + case 1: + if (cpu_is_sama5d33() || cpu_is_sama5d34()) { + pr_warn("AT91: no macb on sama5d33/d34\n"); + return; + } + + if (data->phy_interface != PHY_INTERFACE_MODE_RMII) { + pr_warn("AT91: Only RMII available on interfacr macb%d.\n", id); + return; + } + + at91_set_A_periph(AT91_PIN_PC7, 0); /* ETXCK_EREFCK */ + at91_set_A_periph(AT91_PIN_PC5, 0); /* ERXDV */ + at91_set_A_periph(AT91_PIN_PC2, 0); /* ERX0 */ + at91_set_A_periph(AT91_PIN_PC3, 0); /* ERX1 */ + at91_set_A_periph(AT91_PIN_PC6, 0); /* ERXER */ + at91_set_A_periph(AT91_PIN_PC4, 0); /* ETXEN */ + at91_set_A_periph(AT91_PIN_PC0, 0); /* ETX0 */ + at91_set_A_periph(AT91_PIN_PC1, 0); /* ETX1 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* EMDIO */ + at91_set_A_periph(AT91_PIN_PC8, 0); /* EMDC */ + add_generic_device("macb", id, NULL, SAMA5D3_BASE_EMAC, SZ_16K, + IORESOURCE_MEM, data); + break; + default: + return; + } + +} +#else +void at91_add_device_eth(int id, struct at91_ether_platform_data *data) {} +#endif + +#if defined(CONFIG_MCI_ATMEL) +/* Consider only one slot : slot 0 */ +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) { + case 0: /* MCI0 */ + start = SAMA5D3_BASE_HSMCI0; + + /* CLK */ + at91_set_A_periph(AT91_PIN_PD9, 0); + + /* CMD */ + at91_set_A_periph(AT91_PIN_PD0, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PD1, 1); + switch (data->bus_width) { + case 8: + at91_set_A_periph(AT91_PIN_PD5, 1); + at91_set_A_periph(AT91_PIN_PD6, 1); + at91_set_A_periph(AT91_PIN_PD7, 1); + at91_set_A_periph(AT91_PIN_PD8, 1); + case 4: + at91_set_A_periph(AT91_PIN_PD2, 1); + at91_set_A_periph(AT91_PIN_PD3, 1); + at91_set_A_periph(AT91_PIN_PD4, 1); + }; + + break; + case 1: /* MCI1 */ + start = SAMA5D3_BASE_HSMCI1; + + /* CLK */ + at91_set_A_periph(AT91_PIN_PB24, 0); + + /* CMD */ + at91_set_A_periph(AT91_PIN_PB19, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PB20, 1); + if (data->bus_width == 4) { + at91_set_A_periph(AT91_PIN_PB21, 1); + at91_set_A_periph(AT91_PIN_PB22, 1); + at91_set_A_periph(AT91_PIN_PB23, 1); + } + break; + case 2: /* MCI2 */ + start = SAMA5D3_BASE_HSMCI2; + + /* CLK */ + at91_set_A_periph(AT91_PIN_PC15, 0); + + /* CMD */ + at91_set_A_periph(AT91_PIN_PC10, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PC11, 1); + if (data->bus_width == 4) { + at91_set_A_periph(AT91_PIN_PC12, 1); + at91_set_A_periph(AT91_PIN_PC13, 1); + at91_set_A_periph(AT91_PIN_PC14, 1); + } + } + + 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_PC26, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PC27, + .scl_is_open_drain = 1, + .udelay = 5, /* ~100 kHz */ + }, { + .sda_pin = AT91_PIN_PA18, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA19, + .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[4] = { AT91_PIN_PD13, AT91_PIN_PD14, AT91_PIN_PD15, AT91_PIN_PD16 }; + +static unsigned spi1_standard_cs[4] = { AT91_PIN_PC25, AT91_PIN_PC26, AT91_PIN_PC27, AT91_PIN_PC28 }; + +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 = SAMA5D3_BASE_SPI0; + at91_set_A_periph(AT91_PIN_PD10, 0); /* SPI0_MISO */ + at91_set_A_periph(AT91_PIN_PD11, 0); /* SPI0_MOSI */ + at91_set_A_periph(AT91_PIN_PD12, 0); /* SPI0_SPCK */ + break; + case 1: + start = SAMA5D3_BASE_SPI1; + at91_set_B_periph(AT91_PIN_PC22, 0); /* SPI1_MISO */ + at91_set_B_periph(AT91_PIN_PC23, 0); /* SPI1_MOSI */ + at91_set_B_periph(AT91_PIN_PC24, 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); + + if (cpu_is_sama5d35()) { + pr_warn("AT91: no lcd on sama5d35\n"); + return; + } + + 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_PA0, 0); /* LCDD0 */ + at91_set_A_periph(AT91_PIN_PA1, 0); /* LCDD1 */ + 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_PA8, 0); /* LCDD8 */ + at91_set_A_periph(AT91_PIN_PA9, 0); /* LCDD9 */ + 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_C_periph(AT91_PIN_PC14, 0); /* LCDD16 */ + at91_set_C_periph(AT91_PIN_PC13, 0); /* LCDD17 */ + at91_set_C_periph(AT91_PIN_PC12, 0); /* LCDD18 */ + at91_set_C_periph(AT91_PIN_PC11, 0); /* LCDD19 */ + at91_set_C_periph(AT91_PIN_PC10, 0); /* LCDD20 */ + at91_set_C_periph(AT91_PIN_PC15, 0); /* LCDD21 */ + at91_set_C_periph(AT91_PIN_PE27, 0); /* LCDD22 */ + at91_set_C_periph(AT91_PIN_PE28, 0); /* LCDD23 */ + + add_generic_device("atmel_hlcdfb", DEVICE_ID_SINGLE, NULL, SAMA5D3_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_PB30, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PB31, 1); /* DTXD */ + + return AT91_BASE_DBGU1; +} + +resource_size_t __init at91_configure_usart0(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PD18, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PD17, 0); /* RXD0 */ + + if (pins & ATMEL_UART_RTS) + at91_set_A_periph(AT91_PIN_PD16, 0); /* RTS0 */ + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PD15, 0); /* CTS0 */ + + return SAMA5D3_BASE_USART0; +} + +resource_size_t __init at91_configure_usart1(unsigned pins) +{ + at91_set_A_periph(AT91_PIN_PB29, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB28, 0); /* RXD1 */ + + if (pins & ATMEL_UART_RTS) + at91_set_A_periph(AT91_PIN_PB27, 0); /* RTS1 */ + if (pins & ATMEL_UART_CTS) + at91_set_A_periph(AT91_PIN_PB26, 0); /* CTS1 */ + + return SAMA5D3_BASE_USART1; +} +#endif diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 9b73bcf496..0444a5fdee 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -87,6 +87,11 @@ static void __init soc_detect(u32 dbgu_base) at91_soc_initdata.type = AT91_SOC_SAM9N12; at91_boot_soc = at91sam9n12_soc; break; + + case ARCH_ID_SAMA5D3: + at91_soc_initdata.type = AT91_SOC_SAMA5D3; + at91_boot_soc = at91sama5d3_soc; + break; } /* at91sam9g10 */ @@ -142,6 +147,23 @@ static void __init soc_detect(u32 dbgu_base) break; } } + + if (at91_soc_initdata.type == AT91_SOC_SAMA5D3) { + switch (at91_soc_initdata.exid) { + case ARCH_EXID_SAMA5D31: + at91_soc_initdata.subtype = AT91_SOC_SAMA5D31; + break; + case ARCH_EXID_SAMA5D33: + at91_soc_initdata.subtype = AT91_SOC_SAMA5D33; + break; + case ARCH_EXID_SAMA5D34: + at91_soc_initdata.subtype = AT91_SOC_SAMA5D34; + break; + case ARCH_EXID_SAMA5D35: + at91_soc_initdata.subtype = AT91_SOC_SAMA5D35; + break; + } + } } static const char *soc_name[] = { @@ -155,6 +177,7 @@ static const char *soc_name[] = { [AT91_SOC_SAM9RL] = "at91sam9rl", [AT91_SOC_SAM9X5] = "at91sam9x5", [AT91_SOC_SAM9N12] = "at91sam9n12", + [AT91_SOC_SAMA5D3] = "sama5d3", [AT91_SOC_NONE] = "Unknown" }; @@ -177,6 +200,10 @@ static const char *soc_subtype_name[] = { [AT91_SOC_SAM9X35] = "at91sam9x35", [AT91_SOC_SAM9G25] = "at91sam9g25", [AT91_SOC_SAM9X25] = "at91sam9x25", + [AT91_SOC_SAMA5D31] = "sama5d31", + [AT91_SOC_SAMA5D33] = "sama5d33", + [AT91_SOC_SAMA5D34] = "sama5d34", + [AT91_SOC_SAMA5D35] = "sama5d35", [AT91_SOC_SUBTYPE_NONE] = "Unknown" }; diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h index 8019ced861..b2278a5b32 100644 --- a/arch/arm/mach-at91/soc.h +++ b/arch/arm/mach-at91/soc.h @@ -18,6 +18,7 @@ extern struct at91_init_soc at91sam9g45_soc; 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; #define AT91_SOC_START(_name) \ struct at91_init_soc __initdata at91##_name##_soc \ @@ -64,3 +65,7 @@ static inline int at91_soc_is_enabled(void) #if !defined(CONFIG_SOC_AT91SAM9N12) #define at91sam9n12_soc at91_boot_soc #endif + +#if !defined(CONFIG_SOC_SAMA5) +#define at91sama5d3_soc at91_boot_soc +#endif diff --git a/arch/arm/mach-bcm2835/core.c b/arch/arm/mach-bcm2835/core.c index b0fec8b008..f44ecd5bf3 100644 --- a/arch/arm/mach-bcm2835/core.c +++ b/arch/arm/mach-bcm2835/core.c @@ -97,5 +97,7 @@ void __noreturn reset_cpu (unsigned long addr) rstc |= PM_RSTC_WRCFG_FULL_RESET; writel(PM_PASSWORD | RESET_TIMEOUT, PM_WDOG); writel(PM_PASSWORD | rstc, PM_RSTC); + + while (1); } EXPORT_SYMBOL(reset_cpu); diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index feef9ad1d5..3cb35a01b0 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -259,6 +259,7 @@ config MACH_FREESCALE_MX25_3STACK config MACH_TX25 bool "Ka-Ro TX25" select MACH_HAS_LOWLEVEL_INIT + select HAVE_DEFAULT_ENVIRONMENT_NEW help Say Y here if you are using the Ka-Ro tx25 board diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c index 9e7af816a2..6e91424638 100644 --- a/arch/arm/mach-imx/clk-imx21.c +++ b/arch/arm/mach-imx/clk-imx21.c @@ -45,9 +45,52 @@ #define CCM_PMCOUNT 0x30 #define CCM_WKGDCTL 0x34 +#define PCCR0_UART1_EN (1 << 0) +#define PCCR0_UART2_EN (1 << 1) +#define PCCR0_UART3_EN (1 << 2) +#define PCCR0_UART4_EN (1 << 3) +#define PCCR0_CSPI1_EN (1 << 4) +#define PCCR0_CSPI2_EN (1 << 5) +#define PCCR0_SSI1_EN (1 << 6) +#define PCCR0_SSI2_EN (1 << 7) +#define PCCR0_FIRI_EN (1 << 8) +#define PCCR0_SDHC1_EN (1 << 9) +#define PCCR0_SDHC2_EN (1 << 10) +#define PCCR0_GPIO_EN (1 << 11) +#define PCCR0_I2C_EN (1 << 12) +#define PCCR0_DMA_EN (1 << 13) +#define PCCR0_USBOTG_EN (1 << 14) +#define PCCR0_EMMA_EN (1 << 15) +#define PCCR0_SSI2_BAUD_EN (1 << 16) +#define PCCR0_SSI1_BAUD_EN (1 << 17) +#define PCCR0_PERCLK3_EN (1 << 18) +#define PCCR0_NFC_EN (1 << 19) +#define PCCR0_FRI_BAUD_EN (1 << 20) +#define PCCR0_SLDC_EN (1 << 21) +#define PCCR0_PERCLK4_EN (1 << 22) +#define PCCR0_HCLK_BMI_EN (1 << 23) +#define PCCR0_HCLK_USBOTG_EN (1 << 24) +#define PCCR0_HCLK_SLCDC_EN (1 << 25) +#define PCCR0_HCLK_LCDC_EN (1 << 26) +#define PCCR0_HCLK_EMMA_EN (1 << 27) +#define PCCR0_HCLK_BROM_EN (1 << 28) +#define PCCR0_HCLK_DMA_EN (1 << 30) +#define PCCR0_HCLK_CSI_EN (1 << 31) + +#define PCCR1_CSPI3_EN (1 << 23) +#define PCCR1_WDT_EN (1 << 24) +#define PCCR1_GPT1_EN (1 << 25) +#define PCCR1_GPT2_EN (1 << 26) +#define PCCR1_GPT3_EN (1 << 27) +#define PCCR1_PWM_EN (1 << 28) +#define PCCR1_RTC_EN (1 << 29) +#define PCCR1_KPP_EN (1 << 30) +#define PCCR1_OWIRE_EN (1 << 31) + enum imx21_clks { ckil, ckih, fpm, mpll_sel, spll_sel, mpll, spll, fclk, hclk, ipg, per1, - per2, per3, per4, usb_div, nfc_div, lcdc_per_gate, clk_max + per2, per3, per4, usb_div, nfc_div, lcdc_per_gate, lcdc_ahb_gate, + lcdc_ipg_gate, clk_max }; static struct clk *clks[clk_max]; @@ -70,14 +113,16 @@ static int imx21_ccm_probe(struct device_d *dev) base = dev_request_mem_region(dev, 0); - writel((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | - (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | - (1 << 13) | (1 << 14) | (1 << 19) | (1 << 22) | - (1 << 24) | (1 << 26) | (1 << 30), + writel(PCCR0_UART1_EN | PCCR0_UART2_EN | PCCR0_UART3_EN | PCCR0_UART4_EN | + PCCR0_CSPI1_EN | PCCR0_CSPI2_EN | PCCR0_SDHC1_EN | + PCCR0_SDHC2_EN | PCCR0_GPIO_EN | PCCR0_I2C_EN | PCCR0_DMA_EN | + PCCR0_USBOTG_EN | PCCR0_NFC_EN | PCCR0_PERCLK4_EN | + PCCR0_HCLK_USBOTG_EN | PCCR0_HCLK_DMA_EN, base + CCM_PCCR0); - writel((1 << 23) | (1 << 24) | (1 << 25) | (1 << 26) | (1 << 27) | - (1 << 28) | (1 << 29) | (1 << 30) | (1 << 31), + writel(PCCR1_CSPI3_EN | PCCR1_WDT_EN | PCCR1_GPT1_EN | PCCR1_GPT2_EN | + PCCR1_GPT3_EN | PCCR1_PWM_EN | PCCR1_RTC_EN | PCCR1_KPP_EN | + PCCR1_OWIRE_EN, base + CCM_PCCR1); clks[ckil] = clk_fixed("ckil", lref); @@ -99,6 +144,12 @@ static int imx21_ccm_probe(struct device_d *dev) clks[usb_div] = imx_clk_divider("usb_div", "spll", base + CCM_CSCR, 26, 3); clks[nfc_div] = imx_clk_divider("nfc_div", "ipg", base + CCM_PCDR0, 12, 4); clks[lcdc_per_gate] = imx_clk_gate("lcdc_per_gate", "per3", base + CCM_PCCR0, 18); + clks[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", base + CCM_PCCR0, 26); + /* + * i.MX21 doesn't have an IPG clock for the LCD. To avoid even more conditionals + * in the framebuffer code, provide a dummy clock. + */ + clks[lcdc_ipg_gate] = clk_fixed("dummy", 0); clkdev_add_physbase(clks[per1], MX21_GPT1_BASE_ADDR, NULL); clkdev_add_physbase(clks[per1], MX21_GPT2_BASE_ADDR, NULL); @@ -114,6 +165,8 @@ static int imx21_ccm_probe(struct device_d *dev) clkdev_add_physbase(clks[ipg], MX21_SDHC1_BASE_ADDR, NULL); clkdev_add_physbase(clks[ipg], MX21_SDHC2_BASE_ADDR, NULL); clkdev_add_physbase(clks[lcdc_per_gate], MX21_LCDC_BASE_ADDR, NULL); + clkdev_add_physbase(clks[lcdc_ahb_gate], MX21_LCDC_BASE_ADDR, "ahb"); + clkdev_add_physbase(clks[lcdc_ipg_gate], MX21_LCDC_BASE_ADDR, "ipg"); return 0; } diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c index 38f15a66ab..95b105dc46 100644 --- a/arch/arm/mach-imx/clk-imx25.c +++ b/arch/arm/mach-imx/clk-imx25.c @@ -150,6 +150,8 @@ static int imx25_ccm_probe(struct device_d *dev) clkdev_add_physbase(clks[per3], MX25_ESDHC1_BASE_ADDR, NULL); clkdev_add_physbase(clks[per4], MX25_ESDHC2_BASE_ADDR, NULL); clkdev_add_physbase(clks[lcdc_per_gate], MX25_LCDC_BASE_ADDR, NULL); + clkdev_add_physbase(clks[dummy], MX25_LCDC_BASE_ADDR, "ipg"); + clkdev_add_physbase(clks[dummy], MX25_LCDC_BASE_ADDR, "ahb"); return 0; } diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c index 222d2a6ebc..e221928a3b 100644 --- a/arch/arm/mach-imx/clk-imx27.c +++ b/arch/arm/mach-imx/clk-imx27.c @@ -93,7 +93,7 @@ enum mx27_clks { dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div, per2_div, per3_div, per4_div, usb_div, cpu_sel, clko_sel, cpu_div, clko_div, - clko_en, lcdc_per_gate, clk_max + clko_en, lcdc_per_gate, lcdc_ahb_gate, lcdc_ipg_gate, clk_max }; static struct clk *clks[clk_max]; @@ -136,7 +136,7 @@ static int imx27_ccm_probe(struct device_d *dev) base = dev_request_mem_region(dev, 0); writel(PCCR0_SDHC3_EN | PCCR0_SDHC2_EN | PCCR0_SDHC1_EN | - PCCR0_PWM_EN | PCCR0_KPP_EN | PCCR0_LCDC_EN | PCCR0_IIM_EN | + PCCR0_PWM_EN | PCCR0_KPP_EN | PCCR0_IIM_EN | PCCR0_I2C2_EN | PCCR0_I2C1_EN | PCCR0_GPT6_EN | PCCR0_GPT5_EN | PCCR0_GPT4_EN | PCCR0_GPT3_EN | PCCR0_GPT2_EN | PCCR0_GPT1_EN | PCCR0_GPIO_EN | PCCR0_FEC_EN | PCCR0_CSPI3_EN | PCCR0_CSPI2_EN | @@ -144,9 +144,9 @@ static int imx27_ccm_probe(struct device_d *dev) base + CCM_PCCR0); writel(PCCR1_NFC_BAUDEN | PCCR1_PERCLK4_EN | PCCR1_PERCLK2_EN | PCCR1_PERCLK1_EN | - PCCR1_HCLK_USB | PCCR1_HCLK_LCDC | PCCR1_HCLK_FEC | PCCR1_HCLK_EMI | - PCCR1_WDT_EN | PCCR1_USB_EN | PCCR1_UART6_EN | PCCR1_UART5_EN | - PCCR1_UART4_EN | PCCR1_UART3_EN | PCCR1_UART2_EN | PCCR1_UART1_EN, + PCCR1_HCLK_USB | PCCR1_HCLK_FEC | PCCR1_HCLK_EMI | PCCR1_WDT_EN | + PCCR1_USB_EN | PCCR1_UART6_EN | PCCR1_UART5_EN | PCCR1_UART4_EN | + PCCR1_UART3_EN | PCCR1_UART2_EN | PCCR1_UART1_EN, base + CCM_PCCR1); clks[dummy] = clk_fixed("dummy", 0); @@ -179,7 +179,9 @@ static int imx27_ccm_probe(struct device_d *dev) else clks[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", base + CCM_CSCR, 13, 3); clks[clko_div] = imx_clk_divider("clko_div", "clko_sel", base + CCM_PCDR0, 22, 3); - clks[lcdc_per_gate] = imx_clk_gate("lcdc_per_gate", "per3_div", base + CCM_PCCR1, 7); + clks[lcdc_per_gate] = imx_clk_gate("lcdc_per_gate", "per3_div", base + CCM_PCCR1, 8); + clks[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", base + CCM_PCCR1, 15); + clks[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", base + CCM_PCCR0, 14); clkdev_add_physbase(clks[per1_div], MX27_GPT1_BASE_ADDR, NULL); clkdev_add_physbase(clks[per1_div], MX27_GPT2_BASE_ADDR, NULL); @@ -202,6 +204,8 @@ static int imx27_ccm_probe(struct device_d *dev) clkdev_add_physbase(clks[per2_div], MX27_SDHC2_BASE_ADDR, NULL); clkdev_add_physbase(clks[per2_div], MX27_SDHC3_BASE_ADDR, NULL); clkdev_add_physbase(clks[lcdc_per_gate], MX27_LCDC_BASE_ADDR, NULL); + clkdev_add_physbase(clks[lcdc_ahb_gate], MX27_LCDC_BASE_ADDR, "ahb"); + clkdev_add_physbase(clks[lcdc_ipg_gate], MX27_LCDC_BASE_ADDR, "ipg"); clkdev_add_physbase(clks[ipg], MX27_FEC_BASE_ADDR, NULL); return 0; diff --git a/arch/arm/mach-imx/clk-imx6.c b/arch/arm/mach-imx/clk-imx6.c index f78d3d2bcd..f1b167aac5 100644 --- a/arch/arm/mach-imx/clk-imx6.c +++ b/arch/arm/mach-imx/clk-imx6.c @@ -205,6 +205,9 @@ static int imx6_ccm_probe(struct device_d *dev) clks[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3); clks[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3); + clks[usbphy1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 6); + clks[usbphy2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 6); + clks[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5); clks[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4); clks[sata_ref_100m] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20); @@ -298,6 +301,8 @@ static int imx6_ccm_probe(struct device_d *dev) clkdev_add_physbase(clks[ipg_per], MX6_I2C2_BASE_ADDR, NULL); clkdev_add_physbase(clks[ipg_per], MX6_I2C3_BASE_ADDR, NULL); clkdev_add_physbase(clks[ahb], MX6_SATA_BASE_ADDR, NULL); + clkdev_add_physbase(clks[usbphy1], MX6_USBPHY1_BASE_ADDR, NULL); + clkdev_add_physbase(clks[usbphy2], MX6_USBPHY2_BASE_ADDR, NULL); writel(0xffffffff, ccm_base + CCGR0); writel(0xffffffff, ccm_base + CCGR1); diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c index dd70e6ddfc..841a9ed796 100644 --- a/arch/arm/mach-imx/esdctl.c +++ b/arch/arm/mach-imx/esdctl.c @@ -168,8 +168,8 @@ static inline unsigned long imx_v4_sdram_size(void __iomem *esdctlbase, int cs) static void add_mem(unsigned long base0, unsigned long size0, unsigned long base1, unsigned long size1) { - debug("%s: cs0 base: 0x%08x cs0 size: 0x%08x\n", __func__, base0, size0); - debug("%s: cs1 base: 0x%08x cs1 size: 0x%08x\n", __func__, base1, size1); + debug("%s: cs0 base: 0x%08lx cs0 size: 0x%08lx\n", __func__, base0, size0); + debug("%s: cs1 base: 0x%08lx cs1 size: 0x%08lx\n", __func__, base1, size1); if (base0 + size0 == base1 && size1 > 0) { /* diff --git a/arch/arm/mach-imx/external-nand-boot.c b/arch/arm/mach-imx/external-nand-boot.c index 2e9e475fed..39ffb944f3 100644 --- a/arch/arm/mach-imx/external-nand-boot.c +++ b/arch/arm/mach-imx/external-nand-boot.c @@ -15,6 +15,8 @@ #include <init.h> #include <io.h> #include <linux/mtd/nand.h> +#include <asm/sections.h> +#include <asm/barebox-arm.h> #include <mach/imx-nand.h> #include <mach/generic.h> #include <mach/imx21-regs.h> @@ -256,6 +258,79 @@ void __bare_init imx_nand_load_image(void *dest, int size) } } +/* + * We are now running at the address we are linked at. Now load the image from + * NAND to SDRAM and continue booting. + */ +static void __bare_init __naked insdram(void) +{ + imx_nand_load_image((void *)_text, barebox_image_size); + + board_init_lowlevel_return(); +} + +/* + * Load and start barebox from NAND. This function also checks if we are really + * running inside the NFC address space. If not, barebox is started from the + * currently running address without loading anything from NAND. + */ +void __bare_init __noreturn imx_barebox_boot_nand_external(unsigned long nfc_base) +{ + u32 r; + u32 *src, *trg; + int i; + + /* skip NAND boot if not running from NFC space */ + r = get_pc(); + if (r < nfc_base || r > nfc_base + 0x800) + board_init_lowlevel_return(); + + src = (unsigned int *)nfc_base; + trg = (unsigned int *)_text; + + /* Move ourselves out of NFC SRAM */ + for (i = 0; i < 0x800 / sizeof(int); i++) + *trg++ = *src++; + + /* Jump to SDRAM */ + r = (unsigned int)&insdram; + __asm__ __volatile__("mov pc, %0" : : "r"(r)); + + /* not reached */ + while (1); +} + +/* + * SoC specific entries for booting in external NAND mode. To be called from + * the board specific entry code. This is safe to call even if not booting from + * NAND. In this case the booting is continued without loading an image from + * NAND. This function needs a stack to be set up. + */ +void __bare_init __noreturn imx21_barebox_boot_nand_external(void) +{ + imx_barebox_boot_nand_external(MX21_NFC_BASE_ADDR); +} + +void __bare_init __noreturn imx25_barebox_boot_nand_external(void) +{ + imx_barebox_boot_nand_external(MX25_NFC_BASE_ADDR); +} + +void __bare_init __noreturn imx27_barebox_boot_nand_external(void) +{ + imx_barebox_boot_nand_external(MX27_NFC_BASE_ADDR); +} + +void __bare_init __noreturn imx31_barebox_boot_nand_external(void) +{ + imx_barebox_boot_nand_external(MX31_NFC_BASE_ADDR); +} + +void __bare_init __noreturn imx35_barebox_boot_nand_external(void) +{ + imx_barebox_boot_nand_external(MX35_NFC_BASE_ADDR); +} + #define CONFIG_NAND_IMX_BOOT_DEBUG #ifdef CONFIG_NAND_IMX_BOOT_DEBUG #include <command.h> diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c index e2ef374a0d..adcd9d2235 100644 --- a/arch/arm/mach-imx/imx25.c +++ b/arch/arm/mach-imx/imx25.c @@ -68,6 +68,7 @@ static int imx25_init(void) add_generic_device("imx_iim", 0, NULL, MX25_IIM_BASE_ADDR, SZ_4K, IORESOURCE_MEM, &imx25_iim_pdata); + add_generic_device("imx-iomuxv3", 0, NULL, MX25_IOMUXC_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx25-ccm", 0, NULL, MX25_CCM_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpt", 0, NULL, MX25_GPT1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 0, NULL, MX25_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c index 37ee5d8487..b62f4128cc 100644 --- a/arch/arm/mach-imx/imx6.c +++ b/arch/arm/mach-imx/imx6.c @@ -68,6 +68,7 @@ static int imx6_init(void) add_generic_device("imx31-gpio", 5, NULL, MX6_GPIO6_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 6, NULL, MX6_GPIO7_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); add_generic_device("imx21-wdt", 0, NULL, MX6_WDOG1_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); + add_generic_device("imx6-usb-misc", 0, NULL, MX6_USBOH3_USB_BASE_ADDR + 0x800, 0x100, IORESOURCE_MEM, NULL); return 0; } diff --git a/arch/arm/mach-imx/include/mach/devices-imx6.h b/arch/arm/mach-imx/include/mach/devices-imx6.h index 0f17016530..a9c7e8dfeb 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx6.h +++ b/arch/arm/mach-imx/include/mach/devices-imx6.h @@ -69,3 +69,29 @@ static inline struct device_d *imx6_add_sata(void) { return add_generic_device("imx6-sata", 0, NULL, MX6_SATA_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); } + +static inline struct device_d *imx6_add_usbotg(void *pdata) +{ + add_generic_device("imx-usb-phy", 0, NULL, MX6_USBPHY1_BASE_ADDR, 0x1000, + IORESOURCE_MEM, NULL); + + return imx_add_usb((void *)MX6_USBOH3_USB_BASE_ADDR, 0, pdata); +} + +static inline struct device_d *imx6_add_usbh1(void *pdata) +{ + add_generic_device("imx-usb-phy", 1, NULL, MX6_USBPHY2_BASE_ADDR, 0x1000, + IORESOURCE_MEM, NULL); + + return imx_add_usb((void *)MX6_USBOH3_USB_BASE_ADDR + 0x200, 1, pdata); +} + +static inline struct device_d *imx6_add_usbh2(void *pdata) +{ + return imx_add_usb((void *)MX6_USBOH3_USB_BASE_ADDR + 0x400, 2, pdata); +} + +static inline struct device_d *imx6_add_usbh3(void *pdata) +{ + return imx_add_usb((void *)MX6_USBOH3_USB_BASE_ADDR + 0x600, 2, pdata); +} diff --git a/arch/arm/mach-imx/include/mach/imx-nand.h b/arch/arm/mach-imx/include/mach/imx-nand.h index fb753cfc13..a1f209ed2c 100644 --- a/arch/arm/mach-imx/include/mach/imx-nand.h +++ b/arch/arm/mach-imx/include/mach/imx-nand.h @@ -4,6 +4,11 @@ #include <linux/mtd/mtd.h> void imx_nand_load_image(void *dest, int size); +void imx21_barebox_boot_nand_external(void); +void imx25_barebox_boot_nand_external(void); +void imx27_barebox_boot_nand_external(void); +void imx31_barebox_boot_nand_external(void); +void imx35_barebox_boot_nand_external(void); void imx_nand_set_layout(int writesize, int datawidth); struct imx_nand_platform_data { diff --git a/arch/arm/mach-imx/include/mach/imx21-regs.h b/arch/arm/mach-imx/include/mach/imx21-regs.h index 1c4b5507d3..87bd99c50b 100644 --- a/arch/arm/mach-imx/include/mach/imx21-regs.h +++ b/arch/arm/mach-imx/include/mach/imx21-regs.h @@ -129,12 +129,6 @@ #define MX21_MPCTL1_BRMO (1 << 6) #define MX21_MPCTL1_LF (1 << 15) -#define MX21_PCCR0_PERCLK3_EN (1 << 18) -#define MX21_PCCR0_NFC_EN (1 << 19) -#define MX21_PCCR0_HCLK_LCDC_EN (1 << 26) - -#define MX21_PCCR1_GPT1_EN (1 << 25) - #define MX21_CCSR_32K_SR (1 << 15) #endif /* _IMX21_REGS_H */ diff --git a/arch/arm/mach-imx/include/mach/imx6-regs.h b/arch/arm/mach-imx/include/mach/imx6-regs.h index 7c72cba838..d947aa6c9d 100644 --- a/arch/arm/mach-imx/include/mach/imx6-regs.h +++ b/arch/arm/mach-imx/include/mach/imx6-regs.h @@ -49,7 +49,8 @@ #define MX6_WDOG2_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x40000) #define MX6_CCM_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x44000) #define MX6_ANATOP_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x48000) -#define MX6_USBPHY1_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x4a000) +#define MX6_USBPHY1_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x49000) +#define MX6_USBPHY2_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x4a000) #define MX6_SNVS_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x4C000) #define MX6_EPIT1_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x50000) #define MX6_EPIT2_BASE_ADDR (MX6_AIPS1_OFF_BASE_ADDR + 0x54000) diff --git a/arch/arm/mach-imx/include/mach/usb.h b/arch/arm/mach-imx/include/mach/usb.h index 0a88e7fe2c..85528d77e6 100644 --- a/arch/arm/mach-imx/include/mach/usb.h +++ b/arch/arm/mach-imx/include/mach/usb.h @@ -11,7 +11,7 @@ #define MX35_H1_USBTE_BIT (1 << 4) #define MXC_EHCI_INTERFACE_SINGLE_UNI (2 << 0) -int imx6_usb_phy1_disable_oc(void); -int imx6_usb_phy1_enable(void); +int imx6_usb_phy2_disable_oc(void); +int imx6_usb_phy2_enable(void); #endif /* __MACH_USB_H_*/ diff --git a/arch/arm/mach-imx/usb-imx6.c b/arch/arm/mach-imx/usb-imx6.c index cd234d2084..5e3df10e44 100644 --- a/arch/arm/mach-imx/usb-imx6.c +++ b/arch/arm/mach-imx/usb-imx6.c @@ -46,7 +46,7 @@ #define USBPHY1_PLL_480_CTRL_EN_USB_CLK (1 << 6) #define USBPHY1_PLL_480_CTRL_BYPASS (1 << 16) -int imx6_usb_phy1_disable_oc(void) +int imx6_usb_phy2_disable_oc(void) { int val; @@ -64,7 +64,7 @@ int imx6_usb_phy1_disable_oc(void) return 0; } -int imx6_usb_phy1_enable(void) +int imx6_usb_phy2_enable(void) { int val; @@ -94,18 +94,18 @@ int imx6_usb_phy1_enable(void) while (readl(MX6_USBOH3_USB_BASE_ADDR + USB_UH1_USBCMD) & USB_CMD_RESET); /* reset usbphy */ - writel(USBPHY_CTRL_SFTRST, MX6_USBPHY1_BASE_ADDR + USBPHY_CTRL + SET); + writel(USBPHY_CTRL_SFTRST, MX6_USBPHY2_BASE_ADDR + USBPHY_CTRL + SET); udelay(10); /* clr reset and clkgate */ - writel(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE, MX6_USBPHY1_BASE_ADDR + USBPHY_CTRL + CLR); + writel(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE, MX6_USBPHY2_BASE_ADDR + USBPHY_CTRL + CLR); /* clr all pwd bits => power up phy */ - writel(0xffffffff, MX6_USBPHY1_BASE_ADDR + CLR); + writel(0xffffffff, MX6_USBPHY2_BASE_ADDR + CLR); /* set utmilvl2/3 */ - val = readl(MX6_USBPHY1_BASE_ADDR + USBPHY_CTRL); + val = readl(MX6_USBPHY2_BASE_ADDR + USBPHY_CTRL); val |= USBPHY_CTRL_ENUTMILEVEL3 | USBPHY_CTRL_ENUTMILEVEL2; - writel(val, MX6_USBPHY1_BASE_ADDR + USBPHY_CTRL + SET); + writel(val, MX6_USBPHY2_BASE_ADDR + USBPHY_CTRL + SET); return 0; } diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig index 6611a65a9c..f659184826 100644 --- a/arch/arm/mach-omap/Kconfig +++ b/arch/arm/mach-omap/Kconfig @@ -128,7 +128,6 @@ config MACH_OMAP343xSDP config MACH_BEAGLE bool "Texas Instrument's Beagle Board" - select HAVE_NOSHELL select HAVE_DEFAULT_ENVIRONMENT_NEW depends on ARCH_OMAP3 help @@ -137,21 +136,18 @@ config MACH_BEAGLE config MACH_BEAGLEBONE bool "Texas Instrument's Beagle Bone" select OMAP_CLOCK_ALL - select HAVE_NOSHELL depends on ARCH_AM33XX help Say Y here if you are using Beagle Bone config MACH_OMAP3EVM bool "Texas Instrument's OMAP3 EVM" - select HAVE_NOSHELL depends on ARCH_OMAP3 help Say Y here if you are using OMAP3EVM config MACH_PANDA bool "Texas Instrument's Panda Board" - select HAVE_NOSHELL select MACH_HAS_LOWLEVEL_INIT select HAVE_DEFAULT_ENVIRONMENT_NEW depends on ARCH_OMAP4 @@ -160,7 +156,6 @@ config MACH_PANDA config MACH_ARCHOSG9 bool "Archos G9 tablets" - select HAVE_NOSHELL select MACH_HAS_LOWLEVEL_INIT depends on ARCH_OMAP4 help @@ -168,7 +163,6 @@ config MACH_ARCHOSG9 config MACH_PCM049 bool "Phytec phyCORE pcm049" - select HAVE_NOSHELL depends on ARCH_OMAP4 select MACH_HAS_LOWLEVEL_INIT help @@ -177,14 +171,12 @@ config MACH_PCM049 config MACH_PCAAL1 bool "Phytec phyCARD-A-L1" - select HAVE_NOSHELL depends on ARCH_OMAP3 help Say Y here if you are using a phyCARD-A-L1 PCA-A-L1 config MACH_PCAAXL2 bool "Phytec phyCARD XL2" - select HAVE_NOSHELL select MACH_HAS_LOWLEVEL_INIT depends on ARCH_OMAP4 help @@ -193,7 +185,6 @@ config MACH_PCAAXL2 config MACH_PCM051 bool "Phytec phyCORE pcm051" select OMAP_CLOCK_ALL - select HAVE_NOSHELL select HAVE_DEFAULT_ENVIRONMENT_NEW depends on ARCH_AM33XX help diff --git a/arch/arm/mach-omap/gpmc.c b/arch/arm/mach-omap/gpmc.c index 3aaa4f69e7..bb84b38650 100644 --- a/arch/arm/mach-omap/gpmc.c +++ b/arch/arm/mach-omap/gpmc.c @@ -89,7 +89,7 @@ void gpmc_generic_init(unsigned int cfg) * But NEVER run me in XIP mode! I will Die! */ while (x < GPMC_NUM_CS) { - debug("gpmccs=%d Reg:0x%x <-0x0\n", x, reg); + debug("gpmccs=%d Reg:0x%p <-0x0\n", x, reg); writel(0x0, reg); reg += GPMC_CONFIG_CS_SIZE; x++; @@ -119,14 +119,14 @@ void gpmc_cs_config(char cs, struct gpmc_config *config) /* Write the CFG1-6 regs */ while (x < 6) { - debug("gpmccfg%d Reg:0x%x <-0x%08x\n", + debug("gpmccfg%d Reg:0x%p <-0x%08x\n", x, reg, config->cfg[x]); writel(config->cfg[x], reg); reg += GPMC_CONFIG_REG_OFF; x++; } /* reg now points to CFG7 */ - debug("gpmccfg%d Reg:0x%x <-0x%08x\n", + debug("gpmccfg%d Reg:0x%p <-0x%08x\n", x, reg, (0x1 << 6) | /* CS enable */ ((config->size & 0xF) << 8) | /* Size */ ((config->base >> 24) & 0x3F)); diff --git a/arch/arm/mach-omap/include/mach/debug_ll.h b/arch/arm/mach-omap/include/mach/debug_ll.h index 142f01a81e..ed1777b55b 100644 --- a/arch/arm/mach-omap/include/mach/debug_ll.h +++ b/arch/arm/mach-omap/include/mach/debug_ll.h @@ -23,9 +23,9 @@ #include <mach/omap3-silicon.h> #ifdef CONFIG_OMAP3EVM_UART1 -#define UART_BASE OMAP_UART1_BASE +#define UART_BASE OMAP3_UART1_BASE #else -#define UART_BASE OMAP_UART3_BASE +#define UART_BASE OMAP3_UART3_BASE #endif #endif diff --git a/arch/arm/mach-omap/xload.c b/arch/arm/mach-omap/xload.c index 47c5d9840e..41533a9680 100644 --- a/arch/arm/mach-omap/xload.c +++ b/arch/arm/mach-omap/xload.c @@ -1,6 +1,7 @@ #include <common.h> #include <partition.h> #include <nand.h> +#include <init.h> #include <driver.h> #include <linux/mtd/mtd.h> #include <fs.h> @@ -171,7 +172,7 @@ enum omap_boot_src omap_bootsrc(void) /* * Replaces the default shell in xload configuration */ -int run_shell(void) +static __noreturn int omap_xload(void) { int (*func)(void) = NULL; @@ -211,3 +212,11 @@ int run_shell(void) while (1); } + +static int omap_set_xload(void) +{ + barebox_main = omap_xload; + + return 0; +} +late_initcall(omap_set_xload); diff --git a/arch/blackfin/include/asm/posix_types.h b/arch/blackfin/include/asm/posix_types.h index b1bf2452dd..9992929ada 100644 --- a/arch/blackfin/include/asm/posix_types.h +++ b/arch/blackfin/include/asm/posix_types.h @@ -38,7 +38,7 @@ typedef int __kernel_pid_t; typedef unsigned short __kernel_ipc_pid_t; typedef unsigned short __kernel_uid_t; typedef unsigned short __kernel_gid_t; -typedef unsigned int __kernel_size_t; +typedef unsigned long __kernel_size_t; typedef int __kernel_ssize_t; typedef int __kernel_ptrdiff_t; typedef long __kernel_time_t; diff --git a/arch/mips/boards/dlink-dir-320/Makefile b/arch/mips/boards/dlink-dir-320/Makefile index ff1a655afe..9e14763111 100644 --- a/arch/mips/boards/dlink-dir-320/Makefile +++ b/arch/mips/boards/dlink-dir-320/Makefile @@ -1 +1,2 @@ +obj-y += board.o obj-$(CONFIG_DRIVER_SERIAL_NS16550) += serial.o diff --git a/arch/mips/boards/dlink-dir-320/board.c b/arch/mips/boards/dlink-dir-320/board.c new file mode 100644 index 0000000000..3eed6f0bcc --- /dev/null +++ b/arch/mips/boards/dlink-dir-320/board.c @@ -0,0 +1,12 @@ +#include <common.h> +#include <init.h> +#include <sizes.h> +#include <asm/memory.h> + +static int mem_init(void) +{ + mips_add_ram0(SZ_32M); + + return 0; +} +mem_initcall(mem_init); diff --git a/arch/mips/boards/qemu-malta/init.c b/arch/mips/boards/qemu-malta/init.c index 28c23aa9a0..fb4472fe86 100644 --- a/arch/mips/boards/qemu-malta/init.c +++ b/arch/mips/boards/qemu-malta/init.c @@ -20,7 +20,7 @@ #include <types.h> #include <driver.h> #include <init.h> -#include <memory.h> +#include <asm/memory.h> #include <ns16550.h> #include <mach/hardware.h> #include <io.h> @@ -30,7 +30,7 @@ static int malta_mem_init(void) { - barebox_add_memory_bank("ram0", 0xa0000000, SZ_256M); + mips_add_ram0(SZ_256M); return 0; } diff --git a/arch/mips/boards/rzx50/Makefile b/arch/mips/boards/rzx50/Makefile index ff1a655afe..9e14763111 100644 --- a/arch/mips/boards/rzx50/Makefile +++ b/arch/mips/boards/rzx50/Makefile @@ -1 +1,2 @@ +obj-y += board.o obj-$(CONFIG_DRIVER_SERIAL_NS16550) += serial.o diff --git a/arch/mips/boards/rzx50/board.c b/arch/mips/boards/rzx50/board.c new file mode 100644 index 0000000000..9e655aba50 --- /dev/null +++ b/arch/mips/boards/rzx50/board.c @@ -0,0 +1,12 @@ +#include <common.h> +#include <init.h> +#include <sizes.h> +#include <asm/memory.h> + +static int mem_init(void) +{ + mips_add_ram0(SZ_64M); + + return 0; +} +mem_initcall(mem_init); diff --git a/arch/mips/include/asm/memory.h b/arch/mips/include/asm/memory.h new file mode 100644 index 0000000000..2aa28b7686 --- /dev/null +++ b/arch/mips/include/asm/memory.h @@ -0,0 +1,12 @@ +#ifndef __ASM_MIPS_MEMORY_H +#define __ASM_MIPS_MEMORY_H + +#include <memory.h> +#include <asm/addrspace.h> + +static inline void mips_add_ram0(resource_size_t size) +{ + barebox_add_memory_bank("kseg0_ram0", KSEG0, size); + barebox_add_memory_bank("kseg1_ram0", KSEG1, size); +} +#endif /* __ASM_MIPS_MEMORY_H */ diff --git a/arch/nios2/include/asm/io.h b/arch/nios2/include/asm/io.h index a88f0e2716..8ee48e08d3 100644 --- a/arch/nios2/include/asm/io.h +++ b/arch/nios2/include/asm/io.h @@ -37,7 +37,7 @@ ({unsigned short val;\ asm volatile("ldhio %0, 0(%1)" : "=r"(val) : "r" (addr)); val; }) #define readl(addr)\ - ({unsigned long val;\ + ({unsigned int val;\ asm volatile("ldwio %0, 0(%1)" : "=r"(val) : "r" (addr)); val; }) #define writeb(val, addr)\ diff --git a/arch/nios2/include/asm/posix_types.h b/arch/nios2/include/asm/posix_types.h index 12906b38d6..5a901ffe43 100644 --- a/arch/nios2/include/asm/posix_types.h +++ b/arch/nios2/include/asm/posix_types.h @@ -27,7 +27,7 @@ typedef int __kernel_pid_t; typedef unsigned short __kernel_ipc_pid_t; typedef unsigned short __kernel_uid_t; typedef unsigned short __kernel_gid_t; -typedef unsigned int __kernel_size_t; +typedef unsigned long __kernel_size_t; typedef int __kernel_ssize_t; typedef int __kernel_ptrdiff_t; typedef long __kernel_time_t; diff --git a/arch/ppc/lib/board.c b/arch/ppc/lib/board.c index d2198627f9..18d2588e2c 100644 --- a/arch/ppc/lib/board.c +++ b/arch/ppc/lib/board.c @@ -52,8 +52,8 @@ void board_init_r (ulong end_of_ram) */ malloc_end = (_text_base - (128 << 10)) & ~(4095); - debug("malloc_end: 0x%08x\n", malloc_end); - debug("TEXT_BASE after relocation: 0x%08x\n", _text_base); + debug("malloc_end: 0x%08lx\n", malloc_end); + debug("TEXT_BASE after relocation: 0x%08lx\n", _text_base); mem_malloc_init((void *)(malloc_end - MALLOC_SIZE), (void *)(malloc_end - 1)); diff --git a/commands/Kconfig b/commands/Kconfig index 2e8f214ead..1addd91d24 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -57,6 +57,13 @@ config CMD_READLINE tristate prompt "readline" +config CMD_LET + tristate + prompt "let" + help + the 'let' command is used for arithmetics. It works like the corresponding + Unix shell command. + config CMD_TRUE tristate default y diff --git a/commands/Makefile b/commands/Makefile index 359f566211..c4baf6a470 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -75,6 +75,7 @@ obj-$(CONFIG_CMD_GLOBAL) += global.o obj-$(CONFIG_CMD_BASENAME) += basename.o obj-$(CONFIG_CMD_DIRNAME) += dirname.o obj-$(CONFIG_CMD_READLINK) += readlink.o +obj-$(CONFIG_CMD_LET) += let.o obj-$(CONFIG_CMD_LN) += ln.o obj-$(CONFIG_CMD_CLK) += clk.o obj-$(CONFIG_CMD_TFTP) += tftp.o diff --git a/commands/let.c b/commands/let.c new file mode 100644 index 0000000000..644ede5e2e --- /dev/null +++ b/commands/let.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de> + * + * Partially based on code from BusyBox. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <common.h> +#include <command.h> +#include <environment.h> +#include <errno.h> +#include <init.h> +#include <malloc.h> +#include <xfuncs.h> +#include <math.h> + +static void setvar(const char *name, const char *val) +{ + setenv(name, val); /* return value is always 0 */ +} + +static arith_t run_arith(const char *s) +{ + arith_state_t math_state; + arith_t result; + + math_state.lookupvar = getenv; + math_state.setvar = setvar; + math_state.endofname = arith_endofname; + + result = arith(&math_state, s); + if (math_state.errmsg) + printf("let: %s\n", math_state.errmsg); + + return result; +} + +static int do_let(int argc, char *argv[]) +{ + arith_t i; + + argv++; + if (!*argv) { + printf("let: expression expected\n"); + return COMMAND_ERROR_USAGE; + } + + do { + i = run_arith(*argv); + } while (*++argv); + + return !i; +} + +BAREBOX_CMD_HELP_START(let) +BAREBOX_CMD_HELP_USAGE("let expr [expr ...]\n") +BAREBOX_CMD_HELP_SHORT("evaluate arithmetic expressions\n") +BAREBOX_CMD_HELP_TEXT ("supported operations are in order of decreasing precedence:\n") +BAREBOX_CMD_HELP_TEXT (" X++, X--\n") +BAREBOX_CMD_HELP_TEXT (" ++X, --X\n") +BAREBOX_CMD_HELP_TEXT (" +X, -X\n") +BAREBOX_CMD_HELP_TEXT (" !X, ~X\n") +BAREBOX_CMD_HELP_TEXT (" X**Y\n") +BAREBOX_CMD_HELP_TEXT (" X*Y, X/Y, X%Y\n") +BAREBOX_CMD_HELP_TEXT (" X+Y, X-Y\n") +BAREBOX_CMD_HELP_TEXT (" X<<Y, X>>Y\n") +BAREBOX_CMD_HELP_TEXT (" X<Y, X<=Y, X>=Y, X>Y\n") +BAREBOX_CMD_HELP_TEXT (" X==Y, X!=Y\n") +BAREBOX_CMD_HELP_TEXT (" X&Y\n") +BAREBOX_CMD_HELP_TEXT (" X^Y\n") +BAREBOX_CMD_HELP_TEXT (" X|Y\n") +BAREBOX_CMD_HELP_TEXT (" X&&Y\n") +BAREBOX_CMD_HELP_TEXT (" X||Y\n") +BAREBOX_CMD_HELP_TEXT (" X?Y:Z\n") +BAREBOX_CMD_HELP_TEXT (" X*=Y, X/=Y, X%=Y\n") +BAREBOX_CMD_HELP_TEXT (" X=Y, X&=Y, X|=Y, X^=Y, X+=Y, X-=Y, X<<=Y, X>>=Y\n") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(let) + .cmd = do_let, + .usage = "evaluate arithmetic expressions", + BAREBOX_CMD_HELP(cmd_let_help) +BAREBOX_CMD_END diff --git a/commands/loadenv.c b/commands/loadenv.c index 48284d7a03..14b964340b 100644 --- a/commands/loadenv.c +++ b/commands/loadenv.c @@ -23,7 +23,7 @@ #include <common.h> #include <getopt.h> #include <command.h> -#include <environment.h> +#include <envfs.h> #include <fs.h> static int do_loadenv(int argc, char *argv[]) diff --git a/commands/saveenv.c b/commands/saveenv.c index dd0de7f75b..7f371a88dd 100644 --- a/commands/saveenv.c +++ b/commands/saveenv.c @@ -25,7 +25,7 @@ #include <errno.h> #include <fs.h> #include <fcntl.h> -#include <environment.h> +#include <envfs.h> static int do_saveenv(int argc, char *argv[]) { diff --git a/common/Kconfig b/common/Kconfig index 43e6936465..609b6d95a4 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -37,9 +37,6 @@ config BLOCK config BLOCK_WRITE bool -config HAVE_NOSHELL - bool - config FILETYPE bool @@ -352,12 +349,11 @@ choice simple shell. No if/then, no return values from commands, no loops config SHELL_NONE - depends on HAVE_NOSHELL bool "no shell (noninteractive build)" help No shell at all. This means no shell is started and your board has - to provide a run_shell() function which is started at the end of - the barebox startup process. + to overwrite the barebox_main function pointer which is then called + at the end of the barebox startup process. endchoice config GLOB @@ -407,7 +403,6 @@ config AUTO_COMPLETE config MENU bool prompt "Menu Framework" - depends on PROCESS_ESCAPE_SEQUENCE help a menu framework that allow us to create list menu to simplify barebox and make it more user-frendly @@ -645,6 +640,22 @@ endmenu menu "Debugging" +config COMPILE_LOGLEVEL + int "loglevel" + default 6 + help + This defines the maximum loglevel compiled into the binary. Less important + messages will be compiled away resulting in a smaller binary. + + 0 system is unusable (emerg) + 1 action must be taken immediately (alert) + 2 critical conditions (crit) + 3 error conditions (err) + 4 warning conditions (warn) + 5 normal but significant condition (notice) + 6 informational (info) + 7 debug-level messages (debug) + config DEBUG_INFO bool prompt "enable debug symbols" diff --git a/common/environment.c b/common/environment.c index e11cd9dd47..e8d623f7e4 100644 --- a/common/environment.c +++ b/common/environment.c @@ -41,9 +41,16 @@ #define EXPORT_SYMBOL(x) #endif +struct action_data { + int fd; + const char *base; + void *writep; +}; +#define PAD4(x) ((x + 3) & ~3) + char *default_environment_path = "/dev/env0"; -int file_size_action(const char *filename, struct stat *statbuf, +static int file_size_action(const char *filename, struct stat *statbuf, void *userdata, int depth) { struct action_data *data = userdata; @@ -68,7 +75,7 @@ int file_size_action(const char *filename, struct stat *statbuf, return 1; } -int file_save_action(const char *filename, struct stat *statbuf, +static int file_save_action(const char *filename, struct stat *statbuf, void *userdata, int depth) { struct action_data *data = userdata; @@ -106,11 +113,13 @@ int file_save_action(const char *filename, struct stat *statbuf, memcpy(data->writep, path, len); inode->size = ENVFS_32(len); data->writep += PAD4(len); - debug("handling symlink %s size %ld namelen %d headerlen %d\n", filename + strlen(data->base), - len, namelen, ENVFS_32(inode->headerlen)); + debug("handling symlink %s size %d namelen %d headerlen %d\n", + filename + strlen(data->base), + len, namelen, ENVFS_32(inode->headerlen)); } else { - debug("handling file %s size %ld namelen %d headerlen %d\n", filename + strlen(data->base), - statbuf->st_size, namelen, ENVFS_32(inode->headerlen)); + debug("handling file %s size %lld namelen %d headerlen %d\n", + filename + strlen(data->base), + statbuf->st_size, namelen, ENVFS_32(inode->headerlen)); inode->size = ENVFS_32(statbuf->st_size); fd = open(filename, O_RDONLY); diff --git a/common/filetype.c b/common/filetype.c index 748e364e65..22fc621a14 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -106,12 +106,12 @@ enum filetype is_fat_or_mbr(const unsigned char *sector, unsigned long *bootsec) return filetype_mbr; } -enum filetype file_detect_type(void *_buf, size_t bufsize) +enum filetype file_detect_type(const void *_buf, size_t bufsize) { - u32 *buf = _buf; - u64 *buf64 = _buf; - u8 *buf8 = _buf; - u16 *buf16 = _buf; + const u32 *buf = _buf; + const u64 *buf64 = _buf; + const u8 *buf8 = _buf; + const u16 *buf16 = _buf; enum filetype type; if (bufsize < 9) @@ -145,7 +145,7 @@ enum filetype file_detect_type(void *_buf, size_t bufsize) return filetype_aimage; if (buf64[0] == le64_to_cpu(0x0a1a0a0d474e5089ull)) return filetype_png; - if (strncmp(buf8 + 0x10, "barebox", 7) == 0) + if (is_barebox_mips_head(_buf)) return filetype_mips_barebox; if (bufsize < 64) diff --git a/common/hush.c b/common/hush.c index f9e6411704..1f468f601a 100644 --- a/common/hush.c +++ b/common/hush.c @@ -937,14 +937,12 @@ static int run_list_real(struct p_context *ctx, struct pipe *pi) return rcode; } -#ifdef DEBUG /* broken, of course, but OK for testing */ -static char *indenter(int i) +static __maybe_unused char *indenter(int i) { static char blanks[] = " "; return &blanks[sizeof(blanks) - i - 1]; } -#endif /* return code is the exit status of the pipe */ static int free_pipe(struct pipe *pi, int indent) diff --git a/common/module.c b/common/module.c index 4cb8ef39ff..109fe5cd00 100644 --- a/common/module.c +++ b/common/module.c @@ -104,7 +104,7 @@ static int simplify_symbols(Elf32_Shdr *sechdrs, sym[i].st_value = resolve_symbol(sechdrs, strtab + sym[i].st_name); - debug("undef : %20s 0x%08x 0x%08lx\n", strtab + sym[i].st_name, sym[i].st_value); + debug("undef : %20s 0x%08x\n", strtab + sym[i].st_name, sym[i].st_value); /* Ok if resolved. */ if (sym[i].st_value != 0) diff --git a/common/parser.c b/common/parser.c index fd578c728b..4d993dfd35 100644 --- a/common/parser.c +++ b/common/parser.c @@ -58,9 +58,7 @@ static void process_macros (const char *input, char *output) /* 1 = waiting for '(' or '{' */ /* 2 = waiting for ')' or '}' */ /* 3 = waiting for ''' */ -#ifdef DEBUG - char *output_start = output; -#endif + char __maybe_unused *output_start = output; pr_debug("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input), input); diff --git a/common/resource.c b/common/resource.c index ea6abe88e3..5795e79c6b 100644 --- a/common/resource.c +++ b/common/resource.c @@ -43,15 +43,21 @@ struct resource *request_region(struct resource *parent, struct resource *r, *new; if (end < start) { - debug("%s: request region 0x%08x:0x%08x: end < start\n", - __func__, start, end); + debug("%s: request region 0x%08llx:0x%08llx: end < start\n", + __func__, + (unsigned long long)start, + (unsigned long long)end); return NULL; } /* outside parent resource? */ if (start < parent->start || end > parent->end) { - debug("%s: 0x%08x:0x%08x outside parent resource 0x%08x:0x%08x\n", - __func__, start, end, parent->start, parent->end); + debug("%s: 0x%08llx:0x%08llx outside parent resource 0x%08llx:0x%08llx\n", + __func__, + (unsigned long long)start, + (unsigned long long)end, + (unsigned long long)parent->start, + (unsigned long long)parent->end); return NULL; } @@ -64,13 +70,19 @@ struct resource *request_region(struct resource *parent, goto ok; if (start > r->end) continue; - debug("%s: 0x%08x:0x%08x conflicts with 0x%08x:0x%08x\n", - __func__, start, end, r->start, r->end); + debug("%s: 0x%08llx:0x%08llx conflicts with 0x%08llx:0x%08llx\n", + __func__, + (unsigned long long)start, + (unsigned long long)end, + (unsigned long long)r->start, + (unsigned long long)r->end); return NULL; } ok: - debug("%s ok: 0x%08x:0x%08x\n", __func__, start, end); + debug("%s ok: 0x%08llx:0x%08llx\n", __func__, + (unsigned long long)start, + (unsigned long long)end); new = xzalloc(sizeof(*new)); init_resource(new, name); diff --git a/common/startup.c b/common/startup.c index 14409a217d..52a8996cdf 100644 --- a/common/startup.c +++ b/common/startup.c @@ -32,8 +32,9 @@ #include <debug_ll.h> #include <fs.h> #include <linux/stat.h> -#include <environment.h> +#include <envfs.h> #include <asm/sections.h> +#include <uncompress.h> extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[], __barebox_initcalls_end[]; @@ -41,32 +42,35 @@ extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[], #ifdef CONFIG_DEFAULT_ENVIRONMENT #include "barebox_default_env.h" -#ifdef CONFIG_DEFAULT_ENVIRONMENT_COMPRESSED -#include <uncompress.h> -void *defaultenv; -#else -#define defaultenv default_environment -#endif - static int register_default_env(void) { -#ifdef CONFIG_DEFAULT_ENVIRONMENT_COMPRESSED int ret; - void *tmp; + void *defaultenv; - tmp = xzalloc(default_environment_size); - memcpy(tmp, default_environment, default_environment_size); + if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_COMPRESSED)) { + void *tmp = malloc(default_environment_size); - defaultenv = xzalloc(default_environment_uncompress_size); + if (!tmp) + return -ENOMEM; - ret = uncompress(tmp, default_environment_size, NULL, NULL, - defaultenv, NULL, uncompress_err_stdout); + memcpy(tmp, default_environment, default_environment_size); - free(tmp); + defaultenv = xzalloc(default_environment_uncompress_size); + + ret = uncompress(tmp, default_environment_size, + NULL, NULL, + defaultenv, NULL, uncompress_err_stdout); + + free(tmp); + + if (ret) { + free(defaultenv); + return ret; + } + } else { + defaultenv = (void *)default_environment; + } - if (ret) - return ret; -#endif add_mem_device("defaultenv", (unsigned long)defaultenv, default_environment_uncompress_size, @@ -88,13 +92,16 @@ static int mount_root(void) fs_initcall(mount_root); #endif -void start_barebox (void) +int (*barebox_main)(void); + +void __noreturn start_barebox(void) { initcall_t *initcall; int result; -#ifdef CONFIG_COMMAND_SUPPORT struct stat s; -#endif + + if (!IS_ENABLED(CONFIG_SHELL_NONE)) + barebox_main = run_shell; for (initcall = __barebox_initcalls_start; initcall < __barebox_initcalls_end; initcall++) { @@ -107,28 +114,37 @@ void start_barebox (void) debug("initcalls done\n"); -#ifdef CONFIG_ENV_HANDLING - if (envfs_load(default_environment_path, "/env", 0)) { -#ifdef CONFIG_DEFAULT_ENVIRONMENT - printf("no valid environment found on %s. " - "Using default environment\n", - default_environment_path); - envfs_load("/dev/defaultenv", "/env", 0); -#endif + if (IS_ENABLED(CONFIG_ENV_HANDLING)) { + int ret; + + ret = envfs_load(default_environment_path, "/env", 0); + + if (ret && IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT)) { + printf("no valid environment found on %s. " + "Using default environment\n", + default_environment_path); + envfs_load("/dev/defaultenv", "/env", 0); + } } -#endif -#ifdef CONFIG_COMMAND_SUPPORT - printf("running /env/bin/init...\n"); - if (!stat("/env/bin/init", &s)) { - run_command("source /env/bin/init", 0); - } else { - printf("not found\n"); + if (IS_ENABLED(CONFIG_COMMAND_SUPPORT)) { + printf("running /env/bin/init...\n"); + + if (!stat("/env/bin/init", &s)) { + run_command("source /env/bin/init", 0); + } else { + printf("not found\n"); + } } -#endif + + if (!barebox_main) { + printf("No main function! aborting.\n"); + hang(); + } + /* main_loop() can return to retry autoboot, if so just run it again. */ for (;;) - run_shell(); + barebox_main(); /* NOTREACHED - no way out of command loop except booting */ } @@ -150,4 +166,3 @@ void shutdown_barebox(void) arch_shutdown(); #endif } - diff --git a/common/uimage.c b/common/uimage.c index 1ac0b7dc42..06f97f0944 100644 --- a/common/uimage.c +++ b/common/uimage.c @@ -440,8 +440,9 @@ struct resource *uimage_load_to_sdram(struct uimage_handle *handle, uimage_resource = request_sdram_region("uimage", start, size); if (!uimage_resource) { - printf("unable to request SDRAM 0x%08x-0x%08x\n", - start, start + size - 1); + printf("unable to request SDRAM 0x%08llx-0x%08llx\n", + (unsigned long long)start, + (unsigned long long)start + size - 1); return NULL; } diff --git a/drivers/input/gpio_keys.c b/drivers/input/gpio_keys.c index 6f3c912924..543ad1a470 100644 --- a/drivers/input/gpio_keys.c +++ b/drivers/input/gpio_keys.c @@ -79,7 +79,7 @@ static int __init gpio_keys_probe(struct device_d *dev) pdata->recv_fifo = kfifo_alloc(pdata->fifo_size); for (i = 0; i < pdata->nbuttons; i++) { - gpio = pdata->buttons->gpio; + gpio = pdata->buttons[i].gpio; ret = gpio_request(gpio, "gpio_keys"); if (ret) { pr_err("gpio_keys: (%d) can not be requested\n", gpio); diff --git a/drivers/mci/at91_mci.h b/drivers/mci/at91_mci.h deleted file mode 100644 index 4025aeb14f..0000000000 --- a/drivers/mci/at91_mci.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * [origin: Linux kernel arch/arm/mach-at91/include/mach/at91_mci.h] - * - * Copyright (C) 2005 Ivan Kokshaysky - * Copyright (C) SAN People - * - * MultiMedia Card Interface (MCI) registers. - * Based on AT91RM9200 datasheet revision F. - * - * 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. - */ - -#ifndef AT91_MCI_H -#define AT91_MCI_H - -#define AT91_MCI_CR 0x00 /* Control Register */ -#define AT91_MCI_MCIEN (1 << 0) /* Multi-Media Interface Enable */ -#define AT91_MCI_MCIDIS (1 << 1) /* Multi-Media Interface Disable */ -#define AT91_MCI_PWSEN (1 << 2) /* Power Save Mode Enable */ -#define AT91_MCI_PWSDIS (1 << 3) /* Power Save Mode Disable */ -#define AT91_MCI_SWRST (1 << 7) /* Software Reset */ - -#define AT91_MCI_MR 0x04 /* Mode Register */ -#define AT91_MCI_CLKDIV (0xff << 0) /* Clock Divider */ -#define AT91_MCI_PWSDIV (7 << 8) /* Power Saving Divider */ -#define AT91_MCI_RDPROOF (1 << 11) /* Read Proof Enable [SAM926[03] only] */ -#define AT91_MCI_WRPROOF (1 << 12) /* Write Proof Enable [SAM926[03] only] */ -#define AT91_MCI_PDCFBYTE (1 << 13) /* PDC Force Byte Transfer [SAM926[03] only] */ -#define AT91_MCI_PDCPADV (1 << 14) /* PDC Padding Value */ -#define AT91_MCI_PDCMODE (1 << 15) /* PDC-orientated Mode */ -#define AT91_MCI_BLKLEN (0xfff << 18) /* Data Block Length */ - -#define AT91_MCI_DTOR 0x08 /* Data Timeout Register */ -#define AT91_MCI_DTOCYC (0xf << 0) /* Data Timeout Cycle Number */ -#define AT91_MCI_DTOMUL (7 << 4) /* Data Timeout Multiplier */ -#define AT91_MCI_DTOMUL_1 (0 << 4) -#define AT91_MCI_DTOMUL_16 (1 << 4) -#define AT91_MCI_DTOMUL_128 (2 << 4) -#define AT91_MCI_DTOMUL_256 (3 << 4) -#define AT91_MCI_DTOMUL_1K (4 << 4) -#define AT91_MCI_DTOMUL_4K (5 << 4) -#define AT91_MCI_DTOMUL_64K (6 << 4) -#define AT91_MCI_DTOMUL_1M (7 << 4) - -#define AT91_MCI_SDCR 0x0c /* SD Card Register */ -#define AT91_MCI_SDCSEL (3 << 0) /* SD Card Selector */ -#define AT91_MCI_SDCBUS (3 << 6) /* 1-bit, 4-bit, or 8-bit bus */ -#define AT91_MCI_SDCBUS_1BIT (0 << 6) /* 1-bit bus */ -#define AT91_MCI_SDCBUS_4BIT (2 << 6) /* 4-bit bus */ -#define AT91_MCI_SDCBUS_8BIT (3 << 6) /* 8-bit bus */ - -#define AT91_MCI_ARGR 0x10 /* Argument Register */ - -#define AT91_MCI_CMDR 0x14 /* Command Register */ -#define AT91_MCI_CMDNB (0x3f << 0) /* Command Number */ -#define AT91_MCI_RSPTYP (3 << 6) /* Response Type */ -#define AT91_MCI_RSPTYP_NONE (0 << 6) -#define AT91_MCI_RSPTYP_48 (1 << 6) -#define AT91_MCI_RSPTYP_136 (2 << 6) -#define AT91_MCI_RSPTYP_R1B (3 << 6) -#define AT91_MCI_SPCMD (7 << 8) /* Special Command */ -#define AT91_MCI_SPCMD_NONE (0 << 8) -#define AT91_MCI_SPCMD_INIT (1 << 8) -#define AT91_MCI_SPCMD_SYNC (2 << 8) -#define AT91_MCI_SPCMD_ICMD (4 << 8) -#define AT91_MCI_SPCMD_IRESP (5 << 8) -#define AT91_MCI_OPDCMD (1 << 11) /* Open Drain Command */ -#define AT91_MCI_MAXLAT (1 << 12) /* Max Latency for Command to Response */ -#define AT91_MCI_TRCMD (3 << 16) /* Transfer Command */ -#define AT91_MCI_TRCMD_NONE (0 << 16) -#define AT91_MCI_TRCMD_START (1 << 16) -#define AT91_MCI_TRCMD_STOP (2 << 16) -#define AT91_MCI_TRDIR (1 << 18) /* Transfer Direction */ -#define AT91_MCI_TRDIR_RX (1 << 18) /* Read Transfer Direction */ -#define AT91_MCI_TRDIR_TX (0 << 18) /* Write Transfer Direction */ -#define AT91_MCI_TRTYP (3 << 19) /* Transfer Type */ -#define AT91_MCI_TRTYP_BLOCK (0 << 19) -#define AT91_MCI_TRTYP_MULTIPLE (1 << 19) -#define AT91_MCI_TRTYP_STREAM (2 << 19) -#define AT91_MCI_TRTYP_SDIO_BYTE (4 << 19) -#define AT91_MCI_TRTYP_SDIO_BLOCK (5 << 19) - -#define AT91_MCI_BLKR 0x18 /* Block Register */ -#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */ -#define AT91_MCI_BLKR_BLKLEN(n) ((0xffff & (n)) << 16) /* Block length */ - -#define AT91_MCI_RSPR(n) (0x20 + ((n) * 4)) /* Response Registers 0-3 */ -#define AT91_MCI_RDR 0x30 /* Receive Data Register */ -#define AT91_MCI_TDR 0x34 /* Transmit Data Register */ - -#define AT91_MCI_SR 0x40 /* Status Register */ -#define AT91_MCI_CMDRDY (1 << 0) /* Command Ready */ -#define AT91_MCI_RXRDY (1 << 1) /* Receiver Ready */ -#define AT91_MCI_TXRDY (1 << 2) /* Transmit Ready */ -#define AT91_MCI_BLKE (1 << 3) /* Data Block Ended */ -#define AT91_MCI_DTIP (1 << 4) /* Data Transfer in Progress */ -#define AT91_MCI_NOTBUSY (1 << 5) /* Data Not Busy */ -#define AT91_MCI_ENDRX (1 << 6) /* End of RX Buffer */ -#define AT91_MCI_ENDTX (1 << 7) /* End fo TX Buffer */ -#define AT91_MCI_SDIOIRQA (1 << 8) /* SDIO Interrupt for Slot A */ -#define AT91_MCI_SDIOIRQB (1 << 9) /* SDIO Interrupt for Slot B */ -#define AT91_MCI_RXBUFF (1 << 14) /* RX Buffer Full */ -#define AT91_MCI_TXBUFE (1 << 15) /* TX Buffer Empty */ -#define AT91_MCI_RINDE (1 << 16) /* Response Index Error */ -#define AT91_MCI_RDIRE (1 << 17) /* Response Direction Error */ -#define AT91_MCI_RCRCE (1 << 18) /* Response CRC Error */ -#define AT91_MCI_RENDE (1 << 19) /* Response End Bit Error */ -#define AT91_MCI_RTOE (1 << 20) /* Response Time-out Error */ -#define AT91_MCI_DCRCE (1 << 21) /* Data CRC Error */ -#define AT91_MCI_DTOE (1 << 22) /* Data Time-out Error */ -#define AT91_MCI_OVRE (1 << 30) /* Overrun */ -#define AT91_MCI_UNRE (1 << 31) /* Underrun */ - -#define AT91_MCI_IER 0x44 /* Interrupt Enable Register */ -#define AT91_MCI_IDR 0x48 /* Interrupt Disable Register */ -#define AT91_MCI_IMR 0x4c /* Interrupt Mask Register */ - -#endif diff --git a/drivers/mci/atmel-mci-regs.h b/drivers/mci/atmel-mci-regs.h new file mode 100644 index 0000000000..af1dba00f9 --- /dev/null +++ b/drivers/mci/atmel-mci-regs.h @@ -0,0 +1,166 @@ +/* + * Atmel MultiMedia Card Interface driver + * + * Copyright (C) 2004-2006 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * Superset of MCI IP registers integrated in Atmel AVR32 and AT91 Processors + * Registers and bitfields marked with [2] are only available in MCI2 + */ + +#ifndef __DRIVERS_MMC_ATMEL_MCI_H__ +#define __DRIVERS_MMC_ATMEL_MCI_H__ + +/* MCI Register Definitions */ +#define ATMCI_CR 0x0000 /* Control */ +# define ATMCI_CR_MCIEN ( 1 << 0) /* MCI Enable */ +# define ATMCI_CR_MCIDIS ( 1 << 1) /* MCI Disable */ +# define ATMCI_CR_PWSEN ( 1 << 2) /* Power Save Enable */ +# define ATMCI_CR_PWSDIS ( 1 << 3) /* Power Save Disable */ +# define ATMCI_CR_SWRST ( 1 << 7) /* Software Reset */ +#define ATMCI_MR 0x0004 /* Mode */ +# define ATMCI_MR_CLKDIV(x) ((x) << 0) /* Clock Divider */ +# define ATMCI_MR_PWSDIV(x) ((x) << 8) /* Power Saving Divider */ +# define ATMCI_MR_RDPROOF ( 1 << 11) /* Read Proof */ +# define ATMCI_MR_WRPROOF ( 1 << 12) /* Write Proof */ +# define ATMCI_MR_PDCFBYTE ( 1 << 13) /* Force Byte Transfer */ +# define ATMCI_MR_PDCPADV ( 1 << 14) /* Padding Value */ +# define ATMCI_MR_PDCMODE ( 1 << 15) /* PDC-oriented Mode */ +# define ATMCI_MR_CLKODD(x) ((x) << 16) /* LSB of Clock Divider */ +#define ATMCI_DTOR 0x0008 /* Data Timeout */ +# define ATMCI_DTOCYC(x) ((x) << 0) /* Data Timeout Cycles */ +# define ATMCI_DTOMUL(x) ((x) << 4) /* Data Timeout Multiplier */ +#define ATMCI_SDCR 0x000c /* SD Card / SDIO */ +# define ATMCI_SDCSEL_SLOT_A ( 0 << 0) /* Select SD slot A */ +# define ATMCI_SDCSEL_SLOT_B ( 1 << 0) /* Select SD slot A */ +# define ATMCI_SDCSEL_MASK ( 3 << 0) +# define ATMCI_SDCBUS_1BIT ( 0 << 6) /* 1-bit data bus */ +# define ATMCI_SDCBUS_4BIT ( 2 << 6) /* 4-bit data bus */ +# define ATMCI_SDCBUS_8BIT ( 3 << 6) /* 8-bit data bus[2] */ +# define ATMCI_SDCBUS_MASK ( 3 << 6) +#define ATMCI_ARGR 0x0010 /* Command Argument */ +#define ATMCI_CMDR 0x0014 /* Command */ +# define ATMCI_CMDR_CMDNB_MASK (0x3f << 0) /* Command Opcode MASK */ +# define ATMCI_CMDR_CMDNB(x) ((x) << 0) /* Command Opcode */ +# define ATMCI_CMDR_RSPTYP ( 3 << 6) /* response mask */ +# define ATMCI_CMDR_RSPTYP_NONE ( 0 << 6) /* No response */ +# define ATMCI_CMDR_RSPTYP_48BIT ( 1 << 6) /* 48-bit response */ +# define ATMCI_CMDR_RSPTYP_136BIT ( 2 << 6) /* 136-bit response */ +# define ATMCI_CMDR_SPCMD_INIT ( 1 << 8) /* Initialization command */ +# define ATMCI_CMDR_SPCMD_SYNC ( 2 << 8) /* Synchronized command */ +# define ATMCI_CMDR_SPCMD_INT ( 4 << 8) /* Interrupt command */ +# define ATMCI_CMDR_SPCMD_INTRESP ( 5 << 8) /* Interrupt response */ +# define ATMCI_CMDR_OPDCMD ( 1 << 11) /* Open Drain */ +# define ATMCI_CMDR_MAXLAT_5CYC ( 0 << 12) /* Max latency 5 cycles */ +# define ATMCI_CMDR_MAXLAT_64CYC ( 1 << 12) /* Max latency 64 cycles */ +# define ATMCI_CMDR_START_XFER ( 1 << 16) /* Start data transfer */ +# define ATMCI_CMDR_STOP_XFER ( 2 << 16) /* Stop data transfer */ +# define ATMCI_CMDR_TRDIR_WRITE ( 0 << 18) /* Write data */ +# define ATMCI_CMDR_TRDIR_READ ( 1 << 18) /* Read data */ +# define ATMCI_CMDR_BLOCK ( 0 << 19) /* Single-block transfer */ +# define ATMCI_CMDR_MULTI_BLOCK ( 1 << 19) /* Multi-block transfer */ +# define ATMCI_CMDR_STREAM ( 2 << 19) /* MMC Stream transfer */ +# define ATMCI_CMDR_SDIO_BYTE ( 4 << 19) /* SDIO Byte transfer */ +# define ATMCI_CMDR_SDIO_BLOCK ( 5 << 19) /* SDIO Block transfer */ +# define ATMCI_CMDR_SDIO_SUSPEND ( 1 << 24) /* SDIO Suspend Command */ +# define ATMCI_CMDR_SDIO_RESUME ( 2 << 24) /* SDIO Resume Command */ +#define ATMCI_BLKR 0x0018 /* Block */ +# define ATMCI_BCNT(x) ((x) << 0) /* Data Block Count */ +# define ATMCI_BLKLEN(x) ((x) << 16) /* Data Block Length */ +#define ATMCI_CSTOR 0x001c /* Completion Signal Timeout[2] */ +# define ATMCI_CSTOCYC(x) ((x) << 0) /* CST cycles */ +# define ATMCI_CSTOMUL(x) ((x) << 4) /* CST multiplier */ +#define ATMCI_RSPR 0x0020 /* Response 0 */ +#define ATMCI_RSPR1 0x0024 /* Response 1 */ +#define ATMCI_RSPR2 0x0028 /* Response 2 */ +#define ATMCI_RSPR3 0x002c /* Response 3 */ +#define ATMCI_RDR 0x0030 /* Receive Data */ +#define ATMCI_TDR 0x0034 /* Transmit Data */ +#define ATMCI_SR 0x0040 /* Status */ +#define ATMCI_IER 0x0044 /* Interrupt Enable */ +#define ATMCI_IDR 0x0048 /* Interrupt Disable */ +#define ATMCI_IMR 0x004c /* Interrupt Mask */ +# define ATMCI_CMDRDY ( 1 << 0) /* Command Ready */ +# define ATMCI_RXRDY ( 1 << 1) /* Receiver Ready */ +# define ATMCI_TXRDY ( 1 << 2) /* Transmitter Ready */ +# define ATMCI_BLKE ( 1 << 3) /* Data Block Ended */ +# define ATMCI_DTIP ( 1 << 4) /* Data Transfer In Progress */ +# define ATMCI_NOTBUSY ( 1 << 5) /* Data Not Busy */ +# define ATMCI_ENDRX ( 1 << 6) /* End of RX Buffer */ +# define ATMCI_ENDTX ( 1 << 7) /* End of TX Buffer */ +# define ATMCI_SDIOIRQA ( 1 << 8) /* SDIO IRQ in slot A */ +# define ATMCI_SDIOIRQB ( 1 << 9) /* SDIO IRQ in slot B */ +# define ATMCI_SDIOWAIT ( 1 << 12) /* SDIO Read Wait Operation Status */ +# define ATMCI_CSRCV ( 1 << 13) /* CE-ATA Completion Signal Received */ +# define ATMCI_RXBUFF ( 1 << 14) /* RX Buffer Full */ +# define ATMCI_TXBUFE ( 1 << 15) /* TX Buffer Empty */ +# define ATMCI_RINDE ( 1 << 16) /* Response Index Error */ +# define ATMCI_RDIRE ( 1 << 17) /* Response Direction Error */ +# define ATMCI_RCRCE ( 1 << 18) /* Response CRC Error */ +# define ATMCI_RENDE ( 1 << 19) /* Response End Bit Error */ +# define ATMCI_RTOE ( 1 << 20) /* Response Time-Out Error */ +# define ATMCI_DCRCE ( 1 << 21) /* Data CRC Error */ +# define ATMCI_DTOE ( 1 << 22) /* Data Time-Out Error */ +# define ATMCI_CSTOE ( 1 << 23) /* Completion Signal Time-out Error */ +# define ATMCI_BLKOVRE ( 1 << 24) /* DMA Block Overrun Error */ +# define ATMCI_DMADONE ( 1 << 25) /* DMA Transfer Done */ +# define ATMCI_FIFOEMPTY ( 1 << 26) /* FIFO Empty Flag */ +# define ATMCI_XFRDONE ( 1 << 27) /* Transfer Done Flag */ +# define ATMCI_ACKRCV ( 1 << 28) /* Boot Operation Acknowledge Received */ +# define ATMCI_ACKRCVE ( 1 << 29) /* Boot Operation Acknowledge Error */ +# define ATMCI_OVRE ( 1 << 30) /* RX Overrun Error */ +# define ATMCI_UNRE ( 1 << 31) /* TX Underrun Error */ +#define ATMCI_DMA 0x0050 /* DMA Configuration[2] */ +# define ATMCI_DMA_OFFSET(x) ((x) << 0) /* DMA Write Buffer Offset */ +# define ATMCI_DMA_CHKSIZE(x) ((x) << 4) /* DMA Channel Read and Write Chunk Size */ +# define ATMCI_DMAEN ( 1 << 8) /* DMA Hardware Handshaking Enable */ +#define ATMCI_CFG 0x0054 /* Configuration[2] */ +# define ATMCI_CFG_FIFOMODE_1DATA ( 1 << 0) /* MCI Internal FIFO control mode */ +# define ATMCI_CFG_FERRCTRL_COR ( 1 << 4) /* Flow Error flag reset control mode */ +# define ATMCI_CFG_HSMODE ( 1 << 8) /* High Speed Mode */ +# define ATMCI_CFG_LSYNC ( 1 << 12) /* Synchronize on the last block */ +#define ATMCI_WPMR 0x00e4 /* Write Protection Mode[2] */ +# define ATMCI_WP_EN ( 1 << 0) /* WP Enable */ +# define ATMCI_WP_KEY (0x4d4349 << 8) /* WP Key */ +#define ATMCI_WPSR 0x00e8 /* Write Protection Status[2] */ +# define ATMCI_GET_WP_VS(x) ((x) & 0x0f) +# define ATMCI_GET_WP_VSRC(x) (((x) >> 8) & 0xffff) +#define ATMCI_VERSION 0x00FC /* Version */ +#define ATMCI_FIFO_APERTURE 0x0200 /* FIFO Aperture[2] */ + +/* This is not including the FIFO Aperture on MCI2 */ +#define ATMCI_REGS_SIZE 0x100 + +/* Register access macros */ +#define atmci_readl(port,reg) \ + __raw_readl((port)->regs + reg) +#define atmci_writel(port,reg,value) \ + __raw_writel((value), (port)->regs + reg) + +/* On AVR chips the Peripheral DMA Controller is not connected to MCI. */ +#ifdef CONFIG_AVR32 +# define ATMCI_PDC_CONNECTED 0 +#else +# define ATMCI_PDC_CONNECTED 1 +#endif + +/* + * Fix sconfig's burst size according to atmel MCI. We need to convert them as: + * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3. + * + * This can be done by finding most significant bit set. + */ +static inline unsigned int atmci_convert_chksize(unsigned int maxburst) +{ + if (maxburst > 1) + return fls(maxburst) - 2; + else + return 0; +} + +#endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */ diff --git a/drivers/mci/atmel_mci.c b/drivers/mci/atmel_mci.c index 4065355be5..dbfb53cb42 100644 --- a/drivers/mci/atmel_mci.c +++ b/drivers/mci/atmel_mci.c @@ -1,5 +1,5 @@ /* - * Atmel AT91 MCI driver + * Atmel MCI driver * * Copyright (C) 2011 Hubert Feurstein <h.feurstein@gmail.com> * @@ -25,11 +25,19 @@ #include <linux/clk.h> #include <linux/err.h> -#include "at91_mci.h" +#include "atmel-mci-regs.h" -struct atmel_mci_host { +struct atmel_mci_caps { + bool has_cfg_reg; + bool has_highspeed; + bool has_rwproof; + bool has_odd_clk_div; + bool need_reset_after_xfer; +}; + +struct atmel_mci { struct mci_host mci; - void __iomem *base; + void __iomem *regs; struct device_d *hw_dev; struct clk *clk; @@ -37,89 +45,105 @@ struct atmel_mci_host { struct mci_cmd *cmd; struct mci_data *data; unsigned slot_b; + int version; + struct atmel_mci_caps caps; + + unsigned long bus_hz; + u32 mode_reg; + u32 cfg_reg; + u32 sdc_reg; + bool need_reset; }; -#define to_mci_host(mci) container_of(mci, struct atmel_mci_host, mci) +#define to_mci_host(mci) container_of(mci, struct atmel_mci, mci) -#define STATUS_ERROR_MASK (AT91_MCI_RINDE \ - | AT91_MCI_RDIRE \ - | AT91_MCI_RCRCE \ - | AT91_MCI_RENDE \ - | AT91_MCI_RTOE \ - | AT91_MCI_DCRCE \ - | AT91_MCI_DTOE \ - | AT91_MCI_OVRE \ - | AT91_MCI_UNRE) +#define STATUS_ERROR_MASK (ATMCI_RINDE \ + | ATMCI_RDIRE \ + | ATMCI_RCRCE \ + | ATMCI_RENDE \ + | ATMCI_RTOE \ + | ATMCI_DCRCE \ + | ATMCI_DTOE \ + | ATMCI_OVRE \ + | ATMCI_UNRE) -static inline u32 atmel_mci_readl(struct atmel_mci_host *host, u32 offset) +static void atmci_set_clk_rate(struct atmel_mci *host, + unsigned int clock_min) { - return readl(host->base + offset); -} + unsigned int clkdiv; -static inline void atmel_mci_writel(struct atmel_mci_host *host, u32 offset, - u32 value) -{ - writel(value, host->base + offset); -} - -static void atmel_mci_reset(struct atmel_mci_host *host) -{ - atmel_mci_writel(host, AT91_MCI_CR, AT91_MCI_SWRST | AT91_MCI_MCIDIS); - atmel_mci_writel(host, AT91_MCI_DTOR, 0x7f); - atmel_mci_writel(host, AT91_MCI_IDR, ~0UL); -} - -static void atmel_set_clk_rate(struct atmel_mci_host *host, - unsigned int clk_ios) -{ - unsigned int divider; - unsigned int clk_in = clk_get_rate(host->clk); + if (!host->mode_reg) { + clk_enable(host->clk); + atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN); + if (host->caps.has_cfg_reg) + atmci_writel(host, ATMCI_CFG, host->cfg_reg); + } - if (clk_ios > 0) { - divider = (clk_in / clk_ios) / 2; - if (divider > 0) - divider -= 1; + if (host->caps.has_odd_clk_div) { + clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2; + if (clkdiv > 511) { + dev_dbg(host->hw_dev, + "clock %u too slow; using %lu\n", + clock_min, host->bus_hz / (511 + 2)); + clkdiv = 511; + } + host->mode_reg = ATMCI_MR_CLKDIV(clkdiv >> 1) + | ATMCI_MR_CLKODD(clkdiv & 1); + } else { + clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1; + if (clkdiv > 255) { + dev_dbg(host->hw_dev, + "clock %u too slow; using %lu\n", + clock_min, host->bus_hz / (2 * 256)); + clkdiv = 255; + } + host->mode_reg = ATMCI_MR_CLKDIV(clkdiv); } - if (clk_ios == 0 || divider > 255) - divider = 255; + dev_dbg(host->hw_dev, "atmel_set_clk_rate: clkIn=%ld clkIos=%d divider=%d\n", + host->bus_hz, clock_min, clkdiv); - dev_dbg(host->hw_dev, "atmel_set_clk_rate: clkIn=%d clkIos=%d divider=%d\n", - clk_in, clk_ios, divider); + /* + * WRPROOF and RDPROOF prevent overruns/underruns by + * stopping the clock when the FIFO is full/empty. + * This state is not expected to last for long. + */ + if (host->caps.has_rwproof) + host->mode_reg |= ATMCI_MR_RDPROOF | ATMCI_MR_WRPROOF; - atmel_mci_writel(host, AT91_MCI_MR, (AT91_MCI_CLKDIV & divider) - | AT91_MCI_RDPROOF | AT91_MCI_WRPROOF); + atmci_writel(host, ATMCI_MR, host->mode_reg); } -static int atmel_poll_status(struct atmel_mci_host *host, u32 mask) +static int atmci_poll_status(struct atmel_mci *host, u32 mask) { u32 stat; uint64_t start = get_time_ns(); do { - stat = atmel_mci_readl(host, AT91_MCI_SR); + stat = atmci_readl(host, ATMCI_SR); if (stat & STATUS_ERROR_MASK) return stat; if (is_timeout(start, SECOND)) { dev_err(host->hw_dev, "timeout\n"); - return AT91_MCI_RTOE | stat; + host->need_reset = true; + return ATMCI_RTOE | stat; } if (stat & mask) return 0; } while (1); } -static int atmel_pull(struct atmel_mci_host *host, void *_buf, int bytes) +static int atmci_pull(struct atmel_mci *host, void *_buf, int bytes) { unsigned int stat; u32 *buf = _buf; while (bytes > 3) { - stat = atmel_poll_status(host, AT91_MCI_RXRDY); + stat = atmci_poll_status(host, ATMCI_RXRDY); if (stat) return stat; - *buf++ = atmel_mci_readl(host, AT91_MCI_RDR); + *buf++ = atmci_readl(host, ATMCI_RDR); bytes -= 4; } @@ -130,21 +154,21 @@ static int atmel_pull(struct atmel_mci_host *host, void *_buf, int bytes) } #ifdef CONFIG_MCI_WRITE -static int atmel_push(struct atmel_mci_host *host, const void *_buf, int bytes) +static int atmci_push(struct atmel_mci *host, const void *_buf, int bytes) { unsigned int stat; const u32 *buf = _buf; while (bytes > 3) { - stat = atmel_poll_status(host, AT91_MCI_TXRDY); + stat = atmci_poll_status(host, ATMCI_TXRDY); if (stat) return stat; - atmel_mci_writel(host, AT91_MCI_TDR, *buf++); + atmci_writel(host, ATMCI_TDR, *buf++); bytes -= 4; } - stat = atmel_poll_status(host, AT91_MCI_TXRDY); + stat = atmci_poll_status(host, ATMCI_TXRDY); if (stat) return stat; @@ -155,7 +179,7 @@ static int atmel_push(struct atmel_mci_host *host, const void *_buf, int bytes) } #endif /* CONFIG_MCI_WRITE */ -static int atmel_transfer_data(struct atmel_mci_host *host) +static int atmci_transfer_data(struct atmel_mci *host) { struct mci_data *data = host->data; int stat; @@ -165,23 +189,23 @@ static int atmel_transfer_data(struct atmel_mci_host *host) host->datasize = 0; if (data->flags & MMC_DATA_READ) { - stat = atmel_pull(host, data->dest, length); + stat = atmci_pull(host, data->dest, length); if (stat) return stat; - stat = atmel_poll_status(host, AT91_MCI_NOTBUSY); + stat = atmci_poll_status(host, ATMCI_NOTBUSY); if (stat) return stat; host->datasize += length; } else { #ifdef CONFIG_MCI_WRITE - stat = atmel_push(host, (const void *)(data->src), length); + stat = atmci_push(host, (const void *)(data->src), length); if (stat) return stat; host->datasize += length; - stat = atmel_poll_status(host, AT91_MCI_NOTBUSY); + stat = atmci_poll_status(host, ATMCI_NOTBUSY); if (stat) return stat; #endif /* CONFIG_MCI_WRITE */ @@ -189,21 +213,21 @@ static int atmel_transfer_data(struct atmel_mci_host *host) return 0; } -static void atmel_finish_request(struct atmel_mci_host *host) +static void atmci_finish_request(struct atmel_mci *host) { host->cmd = NULL; host->data = NULL; } -static int atmel_finish_data(struct atmel_mci_host *host, unsigned int stat) +static int atmci_finish_data(struct atmel_mci *host, unsigned int stat) { int data_error = 0; if (stat & STATUS_ERROR_MASK) { dev_err(host->hw_dev, "request failed (status=0x%08x)\n", stat); - if (stat & AT91_MCI_DCRCE) + if (stat & ATMCI_DCRCE) data_error = -EILSEQ; - else if (stat & (AT91_MCI_RTOE | AT91_MCI_DTOE)) + else if (stat & (ATMCI_RTOE | ATMCI_DTOE)) data_error = -ETIMEDOUT; else data_error = -EIO; @@ -214,7 +238,7 @@ static int atmel_finish_data(struct atmel_mci_host *host, unsigned int stat) return data_error; } -static void atmel_setup_data(struct atmel_mci_host *host, struct mci_data *data) +static void atmci_setup_data(struct atmel_mci *host, struct mci_data *data) { unsigned int nob = data->blocks; unsigned int blksz = data->blocksize; @@ -228,13 +252,13 @@ static void atmel_setup_data(struct atmel_mci_host *host, struct mci_data *data) dev_dbg(host->hw_dev, "atmel_setup_data: nob=%d blksz=%d\n", nob, blksz); - atmel_mci_writel(host, AT91_MCI_BLKR, AT91_MCI_BLKR_BCNT(nob) - | AT91_MCI_BLKR_BLKLEN(blksz)); + atmci_writel(host, ATMCI_BLKR, ATMCI_BCNT(nob) + | ATMCI_BLKLEN(blksz)); host->datasize = datasize; } -static int atmel_read_response(struct atmel_mci_host *host, unsigned int stat) +static int atmci_read_response(struct atmel_mci *host, unsigned int stat) { struct mci_cmd *cmd = host->cmd; int i; @@ -243,10 +267,10 @@ static int atmel_read_response(struct atmel_mci_host *host, unsigned int stat) if (!cmd) return 0; - if (stat & (AT91_MCI_RTOE | AT91_MCI_DTOE)) { + if (stat & (ATMCI_RTOE | ATMCI_DTOE)) { dev_err(host->hw_dev, "command/data timeout\n"); return -ETIMEDOUT; - } else if ((stat & AT91_MCI_RCRCE) && (cmd->resp_type & MMC_RSP_CRC)) { + } else if ((stat & ATMCI_RCRCE) && (cmd->resp_type & MMC_RSP_CRC)) { dev_err(host->hw_dev, "cmd crc error\n"); return -EILSEQ; } @@ -254,39 +278,39 @@ static int atmel_read_response(struct atmel_mci_host *host, unsigned int stat) if (cmd->resp_type & MMC_RSP_PRESENT) { if (cmd->resp_type & MMC_RSP_136) { for (i = 0; i < 4; i++) - resp[i] = atmel_mci_readl(host, AT91_MCI_RSPR(0)); + resp[i] = atmci_readl(host, ATMCI_RSPR); } else { - resp[0] = atmel_mci_readl(host, AT91_MCI_RSPR(0)); + resp[0] = atmci_readl(host, ATMCI_RSPR); } } return 0; } -static int atmel_cmd_done(struct atmel_mci_host *host, unsigned int stat) +static int atmci_cmd_done(struct atmel_mci *host, unsigned int stat) { int datastat; int ret; - ret = atmel_read_response(host, stat); + ret = atmci_read_response(host, stat); if (ret) { - atmel_finish_request(host); + atmci_finish_request(host); return ret; } if (!host->data) { - atmel_finish_request(host); + atmci_finish_request(host); return 0; } - datastat = atmel_transfer_data(host); - ret = atmel_finish_data(host, datastat); - atmel_finish_request(host); + datastat = atmci_transfer_data(host); + ret = atmci_finish_data(host, datastat); + atmci_finish_request(host); return ret; } -static int atmel_start_cmd(struct atmel_mci_host *host, struct mci_cmd *cmd, +static int atmci_start_cmd(struct atmel_mci *host, struct mci_cmd *cmd, unsigned int cmdat) { unsigned flags = 0; @@ -295,129 +319,159 @@ static int atmel_start_cmd(struct atmel_mci_host *host, struct mci_cmd *cmd, if (host->cmd != NULL) dev_err(host->hw_dev, "error!\n"); - if ((atmel_mci_readl(host, AT91_MCI_SR) & AT91_MCI_CMDRDY) == 0) { + if ((atmci_readl(host, ATMCI_SR) & ATMCI_CMDRDY) == 0) { dev_err(host->hw_dev, "mci not ready!\n"); return -EBUSY; } host->cmd = cmd; - cmdval = AT91_MCI_CMDNB & cmd->cmdidx; + cmdval = ATMCI_CMDR_CMDNB_MASK & cmd->cmdidx; switch (cmd->resp_type) { case MMC_RSP_R1: /* short CRC, OPCODE */ case MMC_RSP_R1b:/* short CRC, OPCODE, BUSY */ - flags |= AT91_MCI_RSPTYP_48; + flags |= ATMCI_CMDR_RSPTYP_48BIT; break; case MMC_RSP_R2: /* long 136 bit + CRC */ - flags |= AT91_MCI_RSPTYP_136; + flags |= ATMCI_CMDR_RSPTYP_136BIT; break; case MMC_RSP_R3: /* short */ - flags |= AT91_MCI_RSPTYP_48; + flags |= ATMCI_CMDR_RSPTYP_48BIT; break; case MMC_RSP_NONE: - flags |= AT91_MCI_RSPTYP_NONE; + flags |= ATMCI_CMDR_RSPTYP_NONE; break; default: dev_err(host->hw_dev, "unhandled response type 0x%x\n", cmd->resp_type); return -EINVAL; } - cmdval |= AT91_MCI_RSPTYP & flags; - cmdval |= cmdat & ~(AT91_MCI_CMDNB | AT91_MCI_RSPTYP); + cmdval |= ATMCI_CMDR_RSPTYP & flags; + cmdval |= cmdat & ~(ATMCI_CMDR_CMDNB_MASK | ATMCI_CMDR_RSPTYP); - atmel_mci_writel(host, AT91_MCI_ARGR, cmd->cmdarg); - atmel_mci_writel(host, AT91_MCI_CMDR, cmdval); + atmci_writel(host, ATMCI_ARGR, cmd->cmdarg); + atmci_writel(host, ATMCI_CMDR, cmdval); return 0; } -/** init the host interface */ -static int mci_reset(struct mci_host *mci, struct device_d *mci_dev) +static int atmci_card_present(struct mci_host *mci) { - int ret; - struct atmel_mci_host *host = to_mci_host(mci); + struct atmel_mci *host = to_mci_host(mci); struct atmel_mci_platform_data *pd = host->hw_dev->platform_data; + int ret; + + /* No gpio, assume card is present */ + if (!gpio_is_valid(pd->detect_pin)) + return 1; ret = gpio_get_value(pd->detect_pin); - dev_dbg(host->hw_dev, "card %sdetected\n", ret != 0 ? "not " : ""); - if (pd->detect_pin && ret == 1) - return -ENODEV; + return ret == 0 ? 1 : 0; +} + +/** init the host interface */ +static int atmci_reset(struct mci_host *mci, struct device_d *mci_dev) +{ + struct atmel_mci *host = to_mci_host(mci); clk_enable(host->clk); - atmel_mci_reset(host); + atmci_writel(host, ATMCI_DTOR, 0x7f); + clk_disable(host->clk); return 0; } /** change host interface settings */ -static void mci_set_ios(struct mci_host *mci, struct mci_ios *ios) +static void atmci_set_ios(struct mci_host *mci, struct mci_ios *ios) { - struct atmel_mci_host *host = to_mci_host(mci); + struct atmel_mci *host = to_mci_host(mci); dev_dbg(host->hw_dev, "atmel_mci_set_ios: bus_width=%d clk=%d\n", ios->bus_width, ios->clock); + host->sdc_reg &= ~ATMCI_SDCBUS_MASK; switch (ios->bus_width) { case MMC_BUS_WIDTH_4: - atmel_mci_writel(host, AT91_MCI_SDCR, AT91_MCI_SDCBUS_4BIT); + host->sdc_reg |= ATMCI_SDCBUS_4BIT; break; case MMC_BUS_WIDTH_8: - atmel_mci_writel(host, AT91_MCI_SDCR, AT91_MCI_SDCBUS_8BIT); + host->sdc_reg |= ATMCI_SDCBUS_8BIT; break; case MMC_BUS_WIDTH_1: - atmel_mci_writel(host, AT91_MCI_SDCR, AT91_MCI_SDCBUS_1BIT); + host->sdc_reg |= ATMCI_SDCBUS_1BIT; break; default: return; } - atmel_mci_writel(host, AT91_MCI_SDCR, atmel_mci_readl(host, AT91_MCI_SDCR) - | host->slot_b); if (ios->clock) { - atmel_set_clk_rate(host, ios->clock); - atmel_mci_writel(host, AT91_MCI_CR, AT91_MCI_MCIEN - ); + atmci_set_clk_rate(host, ios->clock); + + if (host->caps.has_cfg_reg) { + /* setup High Speed mode in relation with card capacity */ + if (ios->timing == MMC_TIMING_SD_HS) + host->cfg_reg |= ATMCI_CFG_HSMODE; + else + host->cfg_reg &= ~ATMCI_CFG_HSMODE; + + atmci_writel(host, ATMCI_CFG, host->cfg_reg); + } } else { - atmel_mci_writel(host, AT91_MCI_CR, AT91_MCI_MCIDIS); + atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIDIS); + if (host->mode_reg) { + atmci_readl(host, ATMCI_MR); + clk_disable(host->clk); + } + host->mode_reg = 0; } return; } /** handle a command */ -static int mci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data) +static int atmci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data) { - struct atmel_mci_host *host = to_mci_host(mci); + struct atmel_mci *host = to_mci_host(mci); u32 stat, cmdat = 0; int ret; + if (host->need_reset || host->caps.need_reset_after_xfer) { + atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST); + atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN); + atmci_writel(host, ATMCI_MR, host->mode_reg); + if (host->caps.has_cfg_reg) + atmci_writel(host, ATMCI_CFG, host->cfg_reg); + host->need_reset = false; + } + atmci_writel(host, ATMCI_SDCR, host->sdc_reg); + if (cmd->resp_type != MMC_RSP_NONE) - cmdat |= AT91_MCI_MAXLAT; + cmdat |= ATMCI_CMDR_MAXLAT_64CYC; if (data) { - atmel_setup_data(host, data); + atmci_setup_data(host, data); - cmdat |= AT91_MCI_TRCMD_START | AT91_MCI_TRTYP_MULTIPLE; + cmdat |= ATMCI_CMDR_START_XFER | ATMCI_CMDR_MULTI_BLOCK; if (data->flags & MMC_DATA_READ) - cmdat |= AT91_MCI_TRDIR_RX; + cmdat |= ATMCI_CMDR_TRDIR_READ; } - ret = atmel_start_cmd(host, cmd, cmdat); + ret = atmci_start_cmd(host, cmd, cmdat); if (ret) { - atmel_finish_request(host); + atmci_finish_request(host); return ret; } - stat = atmel_poll_status(host, AT91_MCI_CMDRDY); - return atmel_cmd_done(host, stat); + stat = atmci_poll_status(host, ATMCI_CMDRDY); + return atmci_cmd_done(host, stat); } #ifdef CONFIG_MCI_INFO -static void mci_info(struct device_d *mci_dev) +static void atmci_info(struct device_d *mci_dev) { - struct atmel_mci_host *host = mci_dev->priv; + struct atmel_mci *host = mci_dev->priv; struct atmel_mci_platform_data *pd = host->hw_dev->platform_data; printf(" Bus data width: %d bit\n", host->mci.bus_width); @@ -434,68 +488,141 @@ static void mci_info(struct device_d *mci_dev) printf("- %u Hz upper limit", host->mci.f_max); printf("\n Card detection support: %s\n", - pd->detect_pin != 0 ? "yes" : "no"); + gpio_is_valid(pd->detect_pin) ? "yes" : "no"); } #endif /* CONFIG_MCI_INFO */ +/* + * HSMCI (High Speed MCI) module is not fully compatible with MCI module. + * HSMCI provides DMA support and a new config register but no more supports + * PDC. + */ +static void atmci_get_cap(struct atmel_mci *host) +{ + unsigned int version; + + version = atmci_readl(host, ATMCI_VERSION) & 0x00000fff; + host->version = version; + + dev_info(host->hw_dev, "version: 0x%x\n", version); + + host->caps.has_cfg_reg = 0; + host->caps.has_highspeed = 0; + host->caps.need_reset_after_xfer = 1; + + switch (version & 0xf00) { + case 0x500: + host->caps.has_odd_clk_div = 1; + case 0x400: + case 0x300: + host->caps.has_cfg_reg = 1; + host->caps.has_highspeed = 1; + case 0x200: + host->caps.has_rwproof = 1; + case 0x100: + host->caps.need_reset_after_xfer = 0; + case 0x0: + break; + default: + dev_warn(host->hw_dev, + "Unmanaged mci version, set minimum capabilities\n"); + break; + } +} -static int mci_probe(struct device_d *hw_dev) +static int atmci_probe(struct device_d *hw_dev) { - unsigned long clk_rate; - struct atmel_mci_host *host; + struct atmel_mci *host; struct atmel_mci_platform_data *pd = hw_dev->platform_data; + int ret; if (!pd) { dev_err(hw_dev, "missing platform data\n"); return -EINVAL; } + if (gpio_is_valid(pd->detect_pin)) { + ret = gpio_request(pd->detect_pin, "mci_cd"); + if (ret) { + dev_err(hw_dev, "Impossible to request CD gpio %d (%d)\n", + ret, pd->detect_pin); + return ret; + } + + ret = gpio_direction_input(pd->detect_pin); + if (ret) { + dev_err(hw_dev, "Impossible to configure CD gpio %d as input (%d)\n", + ret, pd->detect_pin); + goto err_gpio_cd_request; + } + } + host = xzalloc(sizeof(*host)); - host->mci.send_cmd = mci_request; - host->mci.set_ios = mci_set_ios; - host->mci.init = mci_reset; + host->mci.send_cmd = atmci_request; + host->mci.set_ios = atmci_set_ios; + host->mci.init = atmci_reset; + host->mci.card_present = atmci_card_present; host->mci.hw_dev = hw_dev; - host->mci.host_caps = pd->host_caps; if (pd->bus_width >= 4) host->mci.host_caps |= MMC_MODE_4BIT; if (pd->bus_width == 8) host->mci.host_caps |= MMC_MODE_8BIT; host->slot_b = pd->slot_b; - host->base = dev_request_mem_region(hw_dev, 0); + host->regs = dev_request_mem_region(hw_dev, 0); host->hw_dev = hw_dev; hw_dev->priv = host; host->clk = clk_get(hw_dev, "mci_clk"); if (IS_ERR(host->clk)) { dev_err(hw_dev, "no mci_clk\n"); - return PTR_ERR(host->clk); + ret = PTR_ERR(host->clk); + goto err_gpio_cd_request; } - clk_rate = clk_get_rate(host->clk); + clk_enable(host->clk); + atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST); + atmci_writel(host, ATMCI_IDR, ~0UL); + host->bus_hz = clk_get_rate(host->clk); + clk_disable(host->clk); host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34; - host->mci.f_min = clk_rate >> 9; - host->mci.f_max = clk_rate >> 1; + host->mci.f_min = DIV_ROUND_UP(host->bus_hz, 512); + host->mci.f_max = host->bus_hz >> 1; + + atmci_get_cap(host); + + if (host->caps.has_highspeed) + host->mci.host_caps |= MMC_MODE_HS; + + if (host->slot_b) + host->sdc_reg = ATMCI_SDCSEL_SLOT_B; + else + host->sdc_reg = ATMCI_SDCSEL_SLOT_A; mci_register(&host->mci); return 0; + +err_gpio_cd_request: + if (gpio_is_valid(pd->detect_pin)) + gpio_free(pd->detect_pin); + + return ret; } -static struct driver_d atmel_mci_driver = { +static struct driver_d atmci_driver = { .name = "atmel_mci", - .probe = mci_probe, + .probe = atmci_probe, #ifdef CONFIG_MCI_INFO - .info = mci_info, + .info = atmci_info, #endif }; -static int atmel_mci_init_driver(void) +static int atmci_init_driver(void) { - platform_driver_register(&atmel_mci_driver); + platform_driver_register(&atmci_driver); return 0; } - -device_initcall(atmel_mci_init_driver); +device_initcall(atmci_init_driver); diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c index dfeb509db4..aad1b86962 100644 --- a/drivers/mci/imx-esdhc.c +++ b/drivers/mci/imx-esdhc.c @@ -421,8 +421,9 @@ static void esdhc_set_ios(struct mci_host *mci, struct mci_ios *ios) } -static int esdhc_card_detect(struct fsl_esdhc_host *host) +static int esdhc_card_present(struct mci_host *mci) { + struct fsl_esdhc_host *host = to_fsl_esdhc(mci); struct fsl_esdhc __iomem *regs = host->regs; struct esdhc_platform_data *pdata = host->dev->platform_data; int ret; @@ -453,16 +454,6 @@ static int esdhc_init(struct mci_host *mci, struct device_d *dev) int timeout = 1000; int ret = 0; - ret = esdhc_card_detect(host); - - if (ret == 0) - return -ENODEV; - - if (ret < 0) - return ret; - - ret = 0; - /* Enable cache snooping */ if (host && !host->no_snoop) esdhc_write32(®s->scr, 0x00000040); @@ -561,6 +552,7 @@ static int fsl_esdhc_probe(struct device_d *dev) host->mci.send_cmd = esdhc_send_cmd; host->mci.set_ios = esdhc_set_ios; host->mci.init = esdhc_init; + host->mci.card_present = esdhc_card_present; host->mci.hw_dev = dev; rate = clk_get_rate(host->clk); diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c index 559f8abc9a..a269aee4e8 100644 --- a/drivers/mci/mci-core.c +++ b/drivers/mci/mci-core.c @@ -1111,8 +1111,14 @@ static int __maybe_unused mci_sd_write(struct block_device *blk, const void *buffer, int block, int num_blocks) { struct mci *mci = container_of(blk, struct mci, blk); + struct mci_host *host = mci->host; int rc; + if (host->card_write_protected && host->card_write_protected(host)) { + dev_err(mci->mci_dev, "card write protected\n"); + return -EPERM; + } + dev_dbg(mci->mci_dev, "%s: Write %d block(s), starting at %d\n", __func__, num_blocks, block); @@ -1352,6 +1358,11 @@ static int mci_card_probe(struct mci *mci) struct mci_host *host = mci->host; int rc, disknum; + if (host->card_present && !host->card_present(host)) { + dev_err(mci->mci_dev, "no card inserted\n"); + return -ENODEV; + } + /* start with a host interface reset */ rc = (host->init)(host, mci->mci_dev); if (rc) { @@ -1448,7 +1459,7 @@ static int mci_set_probe(struct device_d *mci_dev, struct param_d *param, rc = mci_check_if_already_initialized(mci); if (rc != 0) - return rc; + return 0; probe = simple_strtoul(val, NULL, 0); if (probe != 0) { @@ -1499,34 +1510,18 @@ static int mci_probe(struct device_d *mci_dev) dev_info(mci->host->hw_dev, "registered as %s\n", dev_name(mci_dev)); -#ifdef CONFIG_MCI_STARTUP - /* if enabled, probe the attached card immediately */ - rc = mci_card_probe(mci); - if (rc) { - /* - * If it fails, add the 'probe' parameter to give the user - * a chance to insert a card and try again. Note: This may fail - * systems that rely on the MCI card for startup (for the - * persistant environment for example) - */ - rc = add_mci_parameter(mci_dev); - if (rc != 0) { - dev_dbg(mci->mci_dev, "Failed to add 'probe' parameter to the MCI device\n"); - goto on_error; - } - } -#endif - -#ifndef CONFIG_MCI_STARTUP - /* add params on demand */ rc = add_mci_parameter(mci_dev); if (rc != 0) { dev_dbg(mci->mci_dev, "Failed to add 'probe' parameter to the MCI device\n"); goto on_error; } + +#ifdef CONFIG_MCI_STARTUP + /* if enabled, probe the attached card immediately */ + mci_card_probe(mci); #endif - return rc; + return 0; on_error: free(mci); diff --git a/drivers/mci/mxs.c b/drivers/mci/mxs.c index ed644d1080..b5b36650bf 100644 --- a/drivers/mci/mxs.c +++ b/drivers/mci/mxs.c @@ -724,7 +724,7 @@ static int mxs_mci_probe(struct device_d *hw_dev) mxs_mci->index = 3; break; default: - pr_debug("Unknown SSP unit at address 0x%08x\n", mxs_mci->regs); + pr_debug("Unknown SSP unit at address 0x%p\n", mxs_mci->regs); return 0; } #endif diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c index af6e195cb1..070fda652b 100644 --- a/drivers/mtd/core.c +++ b/drivers/mtd/core.c @@ -114,7 +114,9 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf) struct mtd_ecc_stats *ecc = buf; #endif struct region_info_user *reg = buf; +#ifdef CONFIG_MTD_WRITE struct erase_info_user *ei = buf; +#endif loff_t *offset = buf; switch (request) { diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 428d126ddd..55b1020390 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -408,7 +408,8 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, struct spi_transfer t[2]; struct spi_message m; - debug("m25p80_write %ld bytes at 0x%08lX\n", (unsigned long)count, offset); + dev_dbg(&flash->spi->dev, "m25p80_write %ld bytes at 0x%08llx\n", + (unsigned long)len, to); spi_message_init(&m); memset(t, 0, (sizeof t)); @@ -484,7 +485,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, size_t actual; int cmd_sz, ret; - pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev), + dev_dbg(&flash->spi->dev, "%s to 0x%08x, len %zd\n", __func__, (u32)to, len); spi_message_init(&m); @@ -767,7 +768,7 @@ static const struct spi_device_id *jedec_probe(struct spi_device *spi) */ tmp = spi_write_then_read(spi, &code, 1, id, 5); if (tmp < 0) { - pr_debug("%s: error %d reading JEDEC ID\n", + dev_dbg(&spi->dev, "%s: error %d reading JEDEC ID\n", dev_name(&spi->dev), tmp); return ERR_PTR(tmp); } @@ -923,7 +924,7 @@ static int m25p_probe(struct device_d *dev) dev_info(dev, "%s (%lld Kbytes)\n", id->name, (long long)flash->mtd.size >> 10); - pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) " + dev_dbg(dev, "mtd .name = %s, .size = 0x%llx (%lldMiB) " ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n", flash->mtd.name, (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20), @@ -932,7 +933,7 @@ static int m25p_probe(struct device_d *dev) if (flash->mtd.numeraseregions) for (i = 0; i < flash->mtd.numeraseregions; i++) - pr_debug("mtd.eraseregions[%d] = { .offset = 0x%llx, " + dev_dbg(dev, "mtd.eraseregions[%d] = { .offset = 0x%llx, " ".erasesize = 0x%.8x (%uKiB), " ".numblocks = %d }\n", i, (long long)flash->mtd.eraseregions[i].offset, diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index fe9a6e7ab3..411aba7398 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -31,6 +31,9 @@ * published by the Free Software Foundation. * */ + +#define pr_fmt(fmt) "nand: " fmt + #include <common.h> #include <errno.h> #include <clock.h> @@ -1074,19 +1077,19 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I') return 0; - printk(KERN_INFO "ONFI flash detected ... "); + pr_info("ONFI flash detected ... "); chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); for (i = 0; i < 3; i++) { chip->read_buf(mtd, (uint8_t *)p, sizeof(*p)); if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) == le16_to_cpu(p->crc)) { - printk(KERN_INFO "ONFI param page %d valid\n", i); + pr_info("ONFI param page %d valid\n", i); break; } } if (i == 3) { - printk(KERN_INFO "no valid ONFI param page found\n"); + pr_info("no valid ONFI param page found\n"); return 0; } @@ -1106,7 +1109,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, chip->onfi_version = 0; if (!chip->onfi_version) { - printk(KERN_INFO "unsupported ONFI version: %d\n", val); + pr_info("unsupported ONFI version: %d\n", val); return 0; } @@ -1170,7 +1173,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, id_data[1] = chip->read_byte(mtd); if (id_data[0] != *maf_id || id_data[1] != dev_id) { - printk(KERN_ERR "%s: second ID read did not match " + pr_err("%s: second ID read did not match " "%02x,%02x against %02x,%02x\n", __func__, *maf_id, dev_id, id_data[0], id_data[1]); return ERR_PTR(-ENODEV); @@ -1191,7 +1194,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, if (ret) goto ident_done; else { - printk(KERN_ERR "NAND type unknown: %02x,%02x\n", *maf_id, dev_id); + pr_err("NAND type unknown: %02x,%02x\n", *maf_id, dev_id); return ERR_PTR(-ENODEV); } } @@ -1329,10 +1332,10 @@ ident_done: * chip correct ! */ if (busw != (chip->options & NAND_BUSWIDTH_16)) { - printk(KERN_INFO "NAND device: Manufacturer ID:" + pr_info("NAND device: Manufacturer ID:" " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id, nand_manuf_ids[maf_idx].name, mtd->name); - printk(KERN_WARNING "NAND bus width %d instead %d bit\n", + pr_warning("NAND bus width %d instead %d bit\n", (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, busw ? 16 : 8); return ERR_PTR(-EINVAL); @@ -1367,7 +1370,7 @@ ident_done: if (mtd->writesize > 512 && chip->cmdfunc == nand_command) chip->cmdfunc = nand_command_lp; - printk("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s)," + pr_notice("Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s)," " page size: %d, OOB size: %d\n", *maf_id, dev_id, nand_manuf_ids[maf_idx].name, chip->onfi_version ? chip->onfi_params.model : type->name, @@ -1393,7 +1396,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips) struct nand_flash_dev *type; if (chip->options & NAND_BUSWIDTH_AUTO && !chip->set_buswidth) { - printk(KERN_ERR "buswidth detection but no buswidth callback\n"); + pr_err("buswidth detection but no buswidth callback\n"); return -EINVAL; } @@ -1406,7 +1409,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips) type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id); if (IS_ERR(type)) { - printk(KERN_WARNING "No NAND device found (%ld)!\n", PTR_ERR(type)); + pr_warning("No NAND device found (%ld)!\n", PTR_ERR(type)); chip->select_chip(mtd, -1); return PTR_ERR(type); } @@ -1422,7 +1425,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips) break; } if (i > 1) - printk(KERN_INFO "%d NAND chips detected\n", i); + pr_info("%d NAND chips detected\n", i); /* Store the number of chips and calc total size for mtd */ chip->numchips = i; @@ -1436,13 +1439,13 @@ static void __maybe_unused nand_check_hwecc(struct mtd_info *mtd, struct nand_ch if ((!chip->ecc.calculate || !chip->ecc.correct || !chip->ecc.hwctl) && (!chip->ecc.read_page || !chip->ecc.write_page)) { - printk(KERN_WARNING "No ECC functions supplied, " + pr_warning("No ECC functions supplied, " "Hardware ECC not possible\n"); BUG(); } if (mtd->writesize < chip->ecc.size) { - printk(KERN_WARNING "%d byte HW ECC not possible on " + pr_warning("%d byte HW ECC not possible on " "%d byte page size\n", chip->ecc.size, mtd->writesize); BUG(); @@ -1486,7 +1489,7 @@ int nand_scan_tail(struct mtd_info *mtd) chip->ecc.layout = &nand_oob_64; break; default: - printk(KERN_WARNING "No oob scheme defined for " + pr_warning("No oob scheme defined for " "oobsize %d\n", mtd->oobsize); BUG(); } @@ -1527,7 +1530,7 @@ int nand_scan_tail(struct mtd_info *mtd) #endif #ifdef CONFIG_NAND_ECC_NONE case NAND_ECC_NONE: - printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. " + pr_warning("NAND_ECC_NONE selected by board driver. " "This is not recommended !!\n"); chip->ecc.read_page = nand_read_page_raw; #ifdef CONFIG_MTD_WRITE @@ -1540,7 +1543,7 @@ int nand_scan_tail(struct mtd_info *mtd) break; #endif default: - printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n", + pr_warning("Invalid NAND_ECC_MODE %d\n", chip->ecc.mode); BUG(); } @@ -1561,7 +1564,7 @@ int nand_scan_tail(struct mtd_info *mtd) */ chip->ecc.steps = mtd->writesize / chip->ecc.size; if(chip->ecc.steps * chip->ecc.size != mtd->writesize) { - printk(KERN_WARNING "Invalid ecc parameters\n"); + pr_warning("Invalid ecc parameters\n"); BUG(); } chip->ecc.total = chip->ecc.steps * chip->ecc.bytes; diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 3cbf886467..f7ae7cd717 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -51,6 +51,9 @@ * - the space necessary for a bbt in FLASH does not exceed a block boundary * */ + +#define pr_fmt(fmt) "nand: " fmt + #include <common.h> #include <linux/types.h> #include <linux/mtd/mtd.h> @@ -160,10 +163,10 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, res = mtd->read(mtd, from, len, &retlen, buf); if (res < 0) { if (retlen != len) { - printk(KERN_INFO "nand_bbt: Error reading bad block table\n"); + pr_info("nand_bbt: Error reading bad block table\n"); return res; } - printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); + pr_warning("nand_bbt: ECC error while reading bad block table\n"); } /* Analyse data */ @@ -174,7 +177,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, if (tmp == msk) continue; if (reserved_block_code && (tmp == reserved_block_code)) { - printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n", + pr_debug("nand_read_bbt: Reserved block at 0x%08x\n", ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06); mtd->ecc_stats.bbtblocks++; @@ -182,7 +185,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, } /* Leave it for now, if its matured we can move this * message to MTD_DEBUG_LEVEL0 */ - printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", + pr_debug("nand_read_bbt: Bad block at 0x%08x\n", ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); /* Factory marked bad or worn out ? */ if (tmp == 0) @@ -292,7 +295,7 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, scan_read_raw(mtd, buf, td->pages[0] << this->page_shift, mtd->writesize); td->version[0] = buf[mtd->writesize + td->veroffs]; - printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", + pr_debug("Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); } @@ -301,7 +304,7 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, scan_read_raw(mtd, buf, md->pages[0] << this->page_shift, mtd->writesize); md->version[0] = buf[mtd->writesize + md->veroffs]; - printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", + pr_debug("Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); } return 1; @@ -380,7 +383,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, loff_t from; size_t readlen; - printk(KERN_INFO "Scanning device for bad blocks\n"); + pr_info("Scanning device for bad blocks\n"); if (bd->options & NAND_BBT_SCANALLPAGES) len = 1 << (this->bbt_erase_shift - this->page_shift); @@ -409,7 +412,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, from = 0; } else { if (chip >= this->numchips) { - printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n", + pr_warning("create_bbt(): chipnr (%d) > available chips (%d)\n", chip + 1, this->numchips); return -EINVAL; } @@ -433,7 +436,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, if (ret) { this->bbt[i >> 3] |= 0x03 << (i & 0x6); - printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", + pr_warning("Bad eraseblock %d at 0x%08x\n", i >> 1, (unsigned int)from); mtd->ecc_stats.badblocks++; } @@ -517,9 +520,9 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr /* Check, if we found a bbt for each requested chip */ for (i = 0; i < chips; i++) { if (td->pages[i] == -1) - printk(KERN_WARNING "Bad block table not found for chip %d\n", i); + pr_warning("Bad block table not found for chip %d\n", i); else - printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], + pr_debug("Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); } return 0; @@ -634,7 +637,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, if (!md || md->pages[chip] != page) goto write; } - printk(KERN_ERR "No space left to write bad block table\n"); + pr_err("No space left to write bad block table\n"); return -ENOSPC; write: @@ -669,12 +672,12 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, res = mtd->read(mtd, to, len, &retlen, buf); if (res < 0) { if (retlen != len) { - printk(KERN_INFO "nand_bbt: Error " + pr_info("nand_bbt: Error " "reading block for writing " "the bad block table\n"); return res; } - printk(KERN_WARNING "nand_bbt: ECC error " + pr_warning("nand_bbt: ECC error " "while reading block for writing " "bad block table\n"); } @@ -735,7 +738,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, if (res < 0) goto outerr; - printk(KERN_DEBUG "Bad block table written to 0x%08x, version " + pr_debug("Bad block table written to 0x%08x, version " "0x%02X\n", (unsigned int)to, td->version[chip]); /* Mark it as used */ @@ -744,7 +747,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, return 0; outerr: - printk(KERN_WARNING + pr_warning( "nand_bbt: Error while writing bad block table %d\n", res); return res; } @@ -975,7 +978,7 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) /* Allocate memory (2bit per block) and clear the memory bad block table */ this->bbt = kzalloc(len, GFP_KERNEL); if (!this->bbt) { - printk(KERN_ERR "nand_scan_bbt: Out of memory\n"); + pr_err("nand_scan_bbt: Out of memory\n"); return -ENOMEM; } @@ -984,7 +987,7 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) */ if (!td) { if ((res = nand_memory_bbt(mtd, bd))) { - printk(KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n"); + pr_err("nand_bbt: Can't scan flash and build the RAM-based BBT\n"); kfree(this->bbt); this->bbt = NULL; } @@ -996,7 +999,7 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) len += (len >> this->page_shift) * mtd->oobsize; buf = vmalloc(len); if (!buf) { - printk(KERN_ERR "nand_bbt: Out of memory\n"); + pr_err("nand_bbt: Out of memory\n"); kfree(this->bbt); this->bbt = NULL; return -ENOMEM; @@ -1047,7 +1050,7 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) len += (len >> this->page_shift) * mtd->oobsize; buf = kmalloc(len, GFP_KERNEL); if (!buf) { - printk(KERN_ERR "nand_update_bbt: Out of memory\n"); + pr_err("nand_update_bbt: Out of memory\n"); return -ENOMEM; } diff --git a/drivers/mtd/nand/nand_write.c b/drivers/mtd/nand/nand_write.c index 999712795c..12a57a0e4d 100644 --- a/drivers/mtd/nand/nand_write.c +++ b/drivers/mtd/nand/nand_write.c @@ -1,3 +1,5 @@ +#define pr_fmt(fmt) "nand: " fmt + #include <common.h> #include <errno.h> #include <clock.h> @@ -296,10 +298,6 @@ int nand_do_write_ops(struct mtd_info *mtd, loff_t to, (chip->pagebuf << chip->page_shift) < (to + ops->len)) chip->pagebuf = -1; - /* Initialize to all 0xFF, to avoid the possibility of - left over OOB data from a previous OOB read. */ - memset(chip->oob_poi, 0xff, mtd->oobsize); - while(1) { int bytes = mtd->writesize; int cached = writelen > bytes && page != blockmask; @@ -315,8 +313,12 @@ int nand_do_write_ops(struct mtd_info *mtd, loff_t to, wbuf = chip->buffers->databuf; } - if (unlikely(oob)) + if (unlikely(oob)) { oob = nand_fill_oob(chip, oob, ops); + } else { + /* We still need to erase leftover OOB data */ + memset(chip->oob_poi, 0xff, mtd->oobsize); + } ret = chip->write_page(mtd, chip, wbuf, page, cached, (ops->mode == MTD_OOB_RAW)); @@ -624,7 +626,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, */ if (nand_block_checkbad(mtd, ((loff_t) page) << chip->page_shift, 0, allowbbt)) { - printk(KERN_WARNING "nand_erase: attempt to erase a " + pr_warn("nand_erase: attempt to erase a " "bad block at page 0x%08x\n", page); instr->state = MTD_ERASE_FAILED; goto erase_exit; diff --git a/drivers/net/at91_ether.c b/drivers/net/at91_ether.c index 2e3a271d16..a0854dff52 100644 --- a/drivers/net/at91_ether.c +++ b/drivers/net/at91_ether.c @@ -342,7 +342,7 @@ static int at91_ether_probe(struct device_d *dev) mac_cfg |= AT91_EMAC_CLK_DIV32 | AT91_EMAC_BIG; - if (pdata->is_rmii) { + if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII) { ether_dev->interface = PHY_INTERFACE_MODE_RGMII; mac_cfg |= AT91_EMAC_RMII; } else { diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 35e5e58c49..18ac3f84f8 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -121,7 +121,7 @@ static int macb_send(struct eth_device *edev, void *packet, macb->tx_ring[0].addr = (ulong)packet; barrier(); dma_flush_range((ulong) packet, (ulong)packet + length); - writel(MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART), macb->regs + MACB_NCR); + macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART)); wait_on_timeout(100 * MSECOND, !(macb->tx_ring[0].ctrl & TXBUF_USED)); @@ -220,7 +220,7 @@ static void macb_adjust_link(struct eth_device *edev) struct macb_device *macb = edev->priv; u32 reg; - reg = readl(macb->regs + MACB_NCFGR); + reg = macb_readl(macb, NCFGR); reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); if (edev->phydev->duplex) @@ -228,7 +228,7 @@ static void macb_adjust_link(struct eth_device *edev) if (edev->phydev->speed == SPEED_100) reg |= MACB_BIT(SPD); - writel(reg, macb->regs + MACB_NCFGR); + macb_writel(macb, NCFGR, reg); } static int macb_open(struct eth_device *edev) @@ -271,8 +271,8 @@ static int macb_init(struct eth_device *edev) macb->rx_tail = macb->tx_tail = 0; - writel((ulong)macb->rx_ring, macb->regs + MACB_RBQP); - writel((ulong)macb->tx_ring, macb->regs + MACB_TBQP); + macb_writel(macb, RBQP, (ulong)macb->rx_ring); + macb_writel(macb, TBQP, (ulong)macb->tx_ring); if (macb->interface == PHY_INTERFACE_MODE_RMII) val |= MACB_BIT(RMII); @@ -282,10 +282,10 @@ static int macb_init(struct eth_device *edev) #if defined(CONFIG_ARCH_AT91) val |= MACB_BIT(CLKEN); #endif - writel(val, macb->regs + MACB_USRIO); + macb_writel(macb, USRIO, val); /* Enable TX and RX */ - writel(MACB_BIT(TE) | MACB_BIT(RE), macb->regs + MACB_NCR); + macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE)); return 0; } @@ -296,16 +296,16 @@ static void macb_halt(struct eth_device *edev) u32 ncr, tsr; /* Halt the controller and wait for any ongoing transmission to end. */ - ncr = readl(macb->regs + MACB_NCR); + ncr = macb_readl(macb, NCR); ncr |= MACB_BIT(THALT); - writel(ncr, macb->regs + MACB_NCR); + macb_writel(macb, NCR, ncr); do { - tsr = readl(macb->regs + MACB_TSR); + tsr = macb_readl(macb, TSR); } while (tsr & MACB_BIT(TGO)); /* Disable TX and RX, and clear statistics */ - writel(MACB_BIT(CLRSTAT), macb->regs + MACB_NCR); + macb_writel(macb, NCR, MACB_BIT(CLRSTAT)); } static int macb_phy_read(struct mii_bus *bus, int addr, int reg) @@ -320,32 +320,32 @@ static int macb_phy_read(struct mii_bus *bus, int addr, int reg) debug("%s\n", __func__); - netctl = readl(macb->regs + MACB_NCR); + netctl = macb_readl(macb, NCR); netctl |= MACB_BIT(MPE); - writel(netctl, macb->regs + MACB_NCR); + macb_writel(macb, NCR, netctl); frame = (MACB_BF(SOF, 1) | MACB_BF(RW, 2) | MACB_BF(PHYA, addr) | MACB_BF(REGA, reg) | MACB_BF(CODE, 2)); - writel(frame, macb->regs + MACB_MAN); + macb_writel(macb, MAN, frame); start = get_time_ns(); do { - netstat = readl(macb->regs + MACB_NSR); + netstat = macb_readl(macb, NSR); if (is_timeout(start, SECOND)) { printf("phy read timed out\n"); return -1; } } while (!(netstat & MACB_BIT(IDLE))); - frame = readl(macb->regs + MACB_MAN); + frame = macb_readl(macb, MAN); value = MACB_BFEXT(DATA, frame); - netctl = readl(macb->regs + MACB_NCR); + netctl = macb_readl(macb, NCR); netctl &= ~MACB_BIT(MPE); - writel(netctl, macb->regs + MACB_NCR); + macb_writel(macb, NCR, netctl); return value; } @@ -359,9 +359,9 @@ static int macb_phy_write(struct mii_bus *bus, int addr, int reg, u16 value) debug("%s\n", __func__); - netctl = readl(macb->regs + MACB_NCR); + netctl = macb_readl(macb, NCR); netctl |= MACB_BIT(MPE); - writel(netctl, macb->regs + MACB_NCR); + macb_writel(macb, NCR, netctl); frame = (MACB_BF(SOF, 1) | MACB_BF(RW, 1) @@ -369,15 +369,15 @@ static int macb_phy_write(struct mii_bus *bus, int addr, int reg, u16 value) | MACB_BF(REGA, reg) | MACB_BF(CODE, 2) | MACB_BF(DATA, value)); - writel(frame, macb->regs + MACB_MAN); + macb_writel(macb, MAN, frame); do { - netstat = readl(macb->regs + MACB_NSR); + netstat = macb_readl(macb, NSR); } while (!(netstat & MACB_BIT(IDLE))); - netctl = readl(macb->regs + MACB_NCR); + netctl = macb_readl(macb, NCR); netctl &= ~MACB_BIT(MPE); - writel(netctl, macb->regs + MACB_NCR); + macb_writel(macb, NCR, netctl); return 0; } @@ -396,9 +396,8 @@ static int macb_set_ethaddr(struct eth_device *edev, unsigned char *adr) debug("%s\n", __func__); /* set hardware address */ - - writel(adr[0] | adr[1] << 8 | adr[2] << 16 | adr[3] << 24, macb->regs + MACB_SA1B); - writel(adr[4] | adr[5] << 8, macb->regs + MACB_SA1T); + macb_writel(macb, SA1B, adr[0] | adr[1] << 8 | adr[2] << 16 | adr[3] << 24); + macb_writel(macb, SA1T, adr[4] | adr[5] << 8); return 0; } @@ -410,9 +409,7 @@ static int macb_probe(struct device_d *dev) unsigned long macb_hz; u32 ncfgr; struct at91_ether_platform_data *pdata; -#if defined(CONFIG_ARCH_AT91) struct clk *pclk; -#endif if (!dev->platform_data) { printf("macb: no platform_data\n"); @@ -439,10 +436,10 @@ static int macb_probe(struct device_d *dev) macb->miibus.priv = macb; macb->miibus.parent = dev; - if (pdata->is_rmii) - macb->interface = PHY_INTERFACE_MODE_RMII; - else + if (pdata->phy_interface == PHY_INTERFACE_MODE_NA) macb->interface = PHY_INTERFACE_MODE_MII; + else + macb->interface = pdata->phy_interface; macb->phy_flags = pdata->phy_flags; @@ -456,7 +453,6 @@ static int macb_probe(struct device_d *dev) * Do some basic initialization so that we at least can talk * to the PHY */ -#if defined(CONFIG_ARCH_AT91) pclk = clk_get(dev, "macb_clk"); if (IS_ERR(pclk)) { dev_err(dev, "no macb_clk\n"); @@ -465,9 +461,6 @@ static int macb_probe(struct device_d *dev) clk_enable(pclk); macb_hz = clk_get_rate(pclk); -#else - macb_hz = get_macb_pclk_rate(0); -#endif if (macb_hz < 20000000) ncfgr = MACB_BF(CLK, MACB_CLK_DIV8); else if (macb_hz < 40000000) @@ -477,7 +470,7 @@ static int macb_probe(struct device_d *dev) else ncfgr = MACB_BF(CLK, MACB_CLK_DIV64); - writel(ncfgr, macb->regs + MACB_NCFGR); + macb_writel(macb, NCFGR, ncfgr); mdiobus_register(&macb->miibus); eth_register(edev); @@ -496,6 +489,4 @@ static int macb_driver_init(void) platform_driver_register(&macb_driver); return 0; } - device_initcall(macb_driver_init); - diff --git a/drivers/net/macb.h b/drivers/net/macb.h index 1447daa9f5..5d9c534e73 100644 --- a/drivers/net/macb.h +++ b/drivers/net/macb.h @@ -262,4 +262,10 @@ << MACB_##name##_OFFSET)) \ | MACB_BF(name,value)) +/* Register access macros */ +#define macb_readl(port,reg) \ + __raw_readl((port)->regs + MACB_##reg) +#define macb_writel(port,reg,value) \ + __raw_writel((value), (port)->regs + MACB_##reg) + #endif /* __DRIVERS_MACB_H__ */ diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c index 6154940823..637f98b10a 100644 --- a/drivers/nor/cfi_flash.c +++ b/drivers/nor/cfi_flash.c @@ -461,7 +461,7 @@ static int __cfi_erase(struct cdev *cdev, size_t count, loff_t offset, unsigned long start, end; int i, ret = 0; - debug("%s: erase 0x%08lx (size %d)\n", __func__, offset, count); + debug("%s: erase 0x%08llx (size %zu)\n", __func__, offset, count); start = find_sector(finfo, (unsigned long)finfo->base + offset); end = find_sector(finfo, (unsigned long)finfo->base + offset + @@ -633,7 +633,7 @@ static int cfi_protect(struct cdev *cdev, size_t count, loff_t offset, int prot) int i, ret = 0; const char *action = (prot? "protect" : "unprotect"); - printf("%s: %s 0x%p (size %d)\n", __func__, + printf("%s: %s 0x%p (size %zu)\n", __func__, action, finfo->base + offset, count); start = find_sector(finfo, (unsigned long)finfo->base + offset); @@ -654,7 +654,8 @@ static ssize_t cfi_write(struct cdev *cdev, const void *buf, size_t count, loff_ struct flash_info *finfo = (struct flash_info *)cdev->priv; int ret; - debug("cfi_write: buf=0x%p addr=0x%08lx count=0x%08x\n",buf, finfo->base + offset, count); + debug("cfi_write: buf=0x%p addr=0x%p count=0x%08zx\n", + buf, finfo->base + offset, count); ret = write_buff(finfo, buf, (unsigned long)finfo->base + offset, count); return ret == 0 ? count : -1; @@ -840,7 +841,10 @@ void flash_write_cmd(struct flash_info *info, flash_sect_t sect, addr = flash_make_addr (info, sect, offset); flash_make_cmd (info, cmd, &cword); - debug("%s: %p %lX %X => %p %llX\n", __FUNCTION__, info, sect, offset, addr, cword); + + debug("%s: %p %lX %X => %p " CFI_WORD_FMT "\n", __func__, + info, sect, offset, addr, cword); + flash_write_word(info, cword, addr); } @@ -862,7 +866,7 @@ int flash_isequal(struct flash_info *info, flash_sect_t sect, debug ("is= %4.4x %4.4x\n", flash_read16(addr), (u16)cword); retval = (flash_read16(addr) == cword); } else if (bankwidth_is_4(info)) { - debug ("is= %8.8lx %8.8lx\n", flash_read32(addr), (u32)cword); + debug ("is= %8.8x %8.8x\n", flash_read32(addr), (u32)cword); retval = (flash_read32(addr) == cword); } else if (bankwidth_is_8(info)) { #ifdef DEBUG diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h index 8f818ba4aa..944cdde660 100644 --- a/drivers/nor/cfi_flash.h +++ b/drivers/nor/cfi_flash.h @@ -29,12 +29,16 @@ typedef unsigned long flash_sect_t; #if defined(CONFIG_DRIVER_CFI_BANK_WIDTH_8) typedef u64 cfiword_t; +#define CFI_WORD_FMT "0x%016llx" #elif defined(CONFIG_DRIVER_CFI_BANK_WIDTH_4) typedef u32 cfiword_t; +#define CFI_WORD_FMT "0x%08x" #elif defined(CONFIG_DRIVER_CFI_BANK_WIDTH_2) typedef u16 cfiword_t; +#define CFI_WORD_FMT "0x%04x" #else typedef u8 cfiword_t; +#define CFI_WORD_FMT "0x%02x" #endif struct cfi_cmd_set; diff --git a/drivers/of/base.c b/drivers/of/base.c index 7a41618ecd..576841db7d 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -487,9 +487,9 @@ struct device_node *of_find_node_by_path(const char *path) list_for_each_entry(np, &allnodes, list) { if (np->full_name && (strcmp(np->full_name, path) == 0)) - break; + return np; } - return np; + return NULL; } EXPORT_SYMBOL(of_find_node_by_path); diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 9dc931bdc6..a813be5ca4 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -300,6 +300,7 @@ static int usb_new_device(struct usb_device *dev) int port = -1; struct usb_device *parent = dev->parent; unsigned short portstatus; + char str[16]; buf = dma_alloc(USB_BUFSIZ); @@ -438,6 +439,19 @@ static int usb_new_device(struct usb_device *dev) print_usb_device(dev); register_device(&dev->dev); + sprintf(str, "%d", dev->descriptor->iManufacturer); + dev_add_param_fixed(&dev->dev, "iManufacturer", str); + sprintf(str, "%d", dev->descriptor->iProduct); + dev_add_param_fixed(&dev->dev, "iProduct", str); + sprintf(str, "%d", dev->descriptor->iSerialNumber); + dev_add_param_fixed(&dev->dev, "iSerialNumber", str); + dev_add_param_fixed(&dev->dev, "Manufacturer", dev->mf); + dev_add_param_fixed(&dev->dev, "Product", dev->prod); + dev_add_param_fixed(&dev->dev, "SerialNumber", dev->serial); + sprintf(str, "%04x", le16_to_cpu(dev->descriptor->idVendor)); + dev_add_param_fixed(&dev->dev, "idVendor", str); + sprintf(str, "%04x", le16_to_cpu(dev->descriptor->idProduct)); + dev_add_param_fixed(&dev->dev, "idProduct", str); list_add_tail(&dev->list, &usb_device_list); err = 0; diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 439d8ebbb4..5a3ce40705 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -6,9 +6,19 @@ config USB_EHCI_OMAP depends on USB_TWL4030 bool "OMAP EHCI driver" +config USB_EHCI_ATMEL + depends on ARCH_AT91 + depends on USB_EHCI + bool "Atmel EHCI driver" + config USB_OHCI bool "OHCI driver" + depends on !MMU + +if USB_OHCI config USB_OHCI_AT91 depends on ARCH_AT91 bool "AT91 OHCI driver" + +endif diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 00f5e24943..156fc7fed9 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_USB_EHCI) += ehci-hcd.o obj-$(CONFIG_USB_EHCI_OMAP) += ehci-omap.o +obj-$(CONFIG_USB_EHCI_ATMEL) += ehci-atmel.o obj-$(CONFIG_USB_OHCI) += ohci-hcd.o obj-$(CONFIG_USB_OHCI_AT91) += ohci-at91.o diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c new file mode 100644 index 0000000000..5957b8e1d0 --- /dev/null +++ b/drivers/usb/host/ehci-atmel.c @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2010 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <common.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <driver.h> +#include <init.h> +#include <usb/usb.h> +#include <usb/usb_defs.h> +#include <usb/ehci.h> +#include <errno.h> +#include <io.h> + +#include "ehci.h" + +/* interface and function clocks; sometimes also an AHB clock */ +static struct clk *iclk, *fclk; + +static void atmel_start_clock(void) +{ + clk_enable(iclk); + clk_enable(fclk); +} + +static void atmel_stop_clock(void) +{ + clk_disable(fclk); + clk_disable(iclk); +} + +static int atmel_ehci_probe(struct device_d *dev) +{ + struct ehci_data data; + + iclk = clk_get(dev, "ehci_clk"); + if (IS_ERR(iclk)) { + dev_err(dev, "Error getting interface clock\n"); + return -ENOENT; + } + + fclk = clk_get(dev, "uhpck"); + if (IS_ERR(fclk)) { + dev_err(dev, "Error getting function clock\n"); + return -ENOENT; + } + + /* + * Start the USB clocks. + */ + atmel_start_clock(); + + data.flags = 0; + + data.hccr = dev_request_mem_region(dev, 0); + + ehci_register(dev, &data); + + return 0; +} + +static void atmel_ehci_remove(struct device_d *dev) +{ + /* + * Stop the USB clocks. + */ + atmel_stop_clock(); +} + +static struct driver_d atmel_ehci_driver = { + .name = "atmel-ehci", + .probe = atmel_ehci_probe, + .remove = atmel_ehci_remove, +}; + +static int atmel_ehci_init(void) +{ + platform_driver_register(&atmel_ehci_driver); + return 0; +} +device_initcall(atmel_ehci_init); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index ad8cf2f450..d0d6ae4cc3 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -148,7 +148,7 @@ static int ehci_reset(struct ehci_priv *ehci) ehci_writel(&ehci->hcor->or_usbcmd, cmd); ret = handshake(&ehci->hcor->or_usbcmd, CMD_RESET, 0, 250 * 1000); if (ret < 0) { - printf("EHCI fail to reset\n"); + dev_err(ehci->dev, "fail to reset\n"); goto out; } @@ -187,7 +187,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz) } if (idx == 5) { - debug("out of buffer pointers (%u bytes left)\n", sz); + pr_debug("out of buffer pointers (%u bytes left)\n", sz); return -1; } @@ -210,10 +210,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, int ret = 0, i; uint64_t start, timeout_val; - debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe, + dev_dbg(ehci->dev, "pipe=%lx, buffer=%p, length=%d, req=%p\n", pipe, buffer, length, req); if (req != NULL) - debug("req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u\n", + dev_dbg(ehci->dev, "(req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u\n", req->request, req->request, req->requesttype, req->requesttype, le16_to_cpu(req->value), le16_to_cpu(req->value), @@ -258,7 +258,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, (0 << 15) | (0 << 12) | (3 << 10) | (2 << 8) | (0x80 << 0); td->qt_token = cpu_to_hc32(token); if (ehci_td_buffer(td, req, sizeof(*req)) != 0) { - debug("unable construct SETUP td\n"); + dev_dbg(ehci->dev, "unable construct SETUP td\n"); goto fail; } *tdp = cpu_to_hc32((uint32_t) td); @@ -280,7 +280,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, ((usb_pipein(pipe) ? 1 : 0) << 8) | (0x80 << 0); td->qt_token = cpu_to_hc32(token); if (ehci_td_buffer(td, buffer, length) != 0) { - printf("unable construct DATA td\n"); + dev_err(ehci->dev, "unable construct DATA td\n"); goto fail; } *tdp = cpu_to_hc32((uint32_t) td); @@ -325,7 +325,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, ret = handshake(&ehci->hcor->or_usbsts, STD_ASS, STD_ASS, 100 * 1000); if (ret < 0) { - printf("EHCI fail timeout STD_ASS set\n"); + dev_err(ehci->dev, "fail timeout STD_ASS set\n"); goto fail; } @@ -364,7 +364,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, ret = handshake(&ehci->hcor->or_usbsts, STD_ASS, 0, 100 * 1000); if (ret < 0) { - printf("EHCI fail timeout STD_ASS reset\n"); + dev_err(ehci->dev, "fail timeout STD_ASS reset\n"); goto fail; } @@ -372,7 +372,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, token = hc32_to_cpu(qh->qt_token); if (!(token & 0x80)) { - debug("TOKEN=0x%08x\n", token); + dev_dbg(ehci->dev, "TOKEN=0x%08x\n", token); switch (token & 0xfc) { case 0: toggle = token >> 31; @@ -393,12 +393,14 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, break; default: dev->status = USB_ST_CRC_ERR; + if ((token & 0x40) == 0x40) + dev->status |= USB_ST_STALLED; break; } dev->act_len = length - ((token >> 16) & 0x7fff); } else { dev->act_len = 0; - debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n", + dev_dbg(ehci->dev, "dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n", dev->devnum, ehci_readl(&ehci->hcor->or_usbsts), ehci_readl(&ehci->hcor->or_portsc[0]), ehci_readl(&ehci->hcor->or_portsc[1])); @@ -407,7 +409,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, return (dev->status != USB_ST_NOT_PROC) ? 0 : -1; fail: - printf("fail1\n"); + dev_err(ehci->dev, "fail1\n"); td = (void *)hc32_to_cpu(qh->qt_next); while (td != (void *)QT_NEXT_TERMINATE) { qh->qt_next = td->qt_next; @@ -461,14 +463,14 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, uint32_t *status_reg; if (le16_to_cpu(req->index) >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) { - printf("The request port(%d) is not configured\n", + dev_err(ehci->dev, "The request port(%d) is not configured\n", le16_to_cpu(req->index) - 1); return -1; } status_reg = (uint32_t *)&ehci->hcor->or_portsc[le16_to_cpu(req->index) - 1]; srclen = 0; - debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n", + dev_dbg(ehci->dev, "req=%u (%#x), type=%u (%#x), value=%u, index=%u\n", req->request, req->request, req->requesttype, req->requesttype, le16_to_cpu(req->value), le16_to_cpu(req->index)); @@ -479,17 +481,17 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, case DeviceRequest | USB_REQ_GET_DESCRIPTOR: switch (le16_to_cpu(req->value) >> 8) { case USB_DT_DEVICE: - debug("USB_DT_DEVICE request\n"); + dev_dbg(ehci->dev, "USB_DT_DEVICE request\n"); srcptr = &descriptor.device; srclen = 0x12; break; case USB_DT_CONFIG: - debug("USB_DT_CONFIG config\n"); + dev_dbg(ehci->dev, "USB_DT_CONFIG config\n"); srcptr = &descriptor.config; srclen = 0x19; break; case USB_DT_STRING: - debug("USB_DT_STRING config\n"); + dev_dbg(ehci->dev, "USB_DT_STRING config\n"); switch (le16_to_cpu(req->value) & 0xff) { case 0: /* Language */ srcptr = "\4\3\1\0"; @@ -506,34 +508,34 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, srclen = 42; break; default: - debug("unknown value DT_STRING %x\n", + dev_dbg(ehci->dev, "unknown value DT_STRING %x\n", le16_to_cpu(req->value)); goto unknown; } break; default: - debug("unknown value %x\n", le16_to_cpu(req->value)); + dev_dbg(ehci->dev, "unknown value %x\n", le16_to_cpu(req->value)); goto unknown; } break; case ((USB_DIR_IN | USB_RT_HUB) << 8) | USB_REQ_GET_DESCRIPTOR: switch (le16_to_cpu(req->value) >> 8) { case USB_DT_HUB: - debug("USB_DT_HUB config\n"); + dev_dbg(ehci->dev, "USB_DT_HUB config\n"); srcptr = &descriptor.hub; srclen = 0x8; break; default: - debug("unknown value %x\n", le16_to_cpu(req->value)); + dev_dbg(ehci->dev, "unknown value %x\n", le16_to_cpu(req->value)); goto unknown; } break; case USB_REQ_SET_ADDRESS | (USB_RECIP_DEVICE << 8): - debug("USB_REQ_SET_ADDRESS\n"); + dev_dbg(ehci->dev, "USB_REQ_SET_ADDRESS\n"); ehci->rootdev = le16_to_cpu(req->value); break; case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: - debug("USB_REQ_SET_CONFIGURATION\n"); + dev_dbg(ehci->dev, "USB_REQ_SET_CONFIGURATION\n"); /* Nothing to do */ break; case USB_REQ_GET_STATUS | ((USB_DIR_IN | USB_RT_HUB) << 8): @@ -563,7 +565,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, if (!ret) tmpbuf[0] |= USB_PORT_STAT_RESET; else - printf("port(%d) reset error\n", + dev_err(ehci->dev, "port(%d) reset error\n", le16_to_cpu(req->index) - 1); } if (reg & EHCI_PS_PP) @@ -616,7 +618,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, !ehci_is_TDI() && EHCI_PS_IS_LOWSPEED(reg)) { /* Low speed device, give up ownership. */ - debug("port %d low speed --> companion\n", + dev_dbg(ehci->dev, "port %d low speed --> companion\n", req->index - 1); reg |= EHCI_PS_PO; ehci_writel(status_reg, reg); @@ -648,13 +650,13 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, ehci->portreset |= 1 << le16_to_cpu(req->index); else - printf("port(%d) reset error\n", + dev_err(ehci->dev, "port(%d) reset error\n", le16_to_cpu(req->index) - 1); } break; default: - debug("unknown feature %x\n", le16_to_cpu(req->value)); + dev_dbg(ehci->dev, "unknown feature %x\n", le16_to_cpu(req->value)); goto unknown; } /* unblock posted writes */ @@ -682,7 +684,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, ehci->portreset &= ~(1 << le16_to_cpu(req->index)); break; default: - debug("unknown feature %x\n", le16_to_cpu(req->value)); + dev_dbg(ehci->dev, "unknown feature %x\n", le16_to_cpu(req->value)); goto unknown; } ehci_writel(status_reg, reg); @@ -690,7 +692,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, (void) ehci_readl(&ehci->hcor->or_usbcmd); break; default: - debug("Unknown request\n"); + dev_dbg(ehci->dev, "Unknown request\n"); goto unknown; } @@ -699,14 +701,14 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, if (srcptr != NULL && len > 0) memcpy(buffer, srcptr, len); else - debug("Len is 0\n"); + dev_dbg(ehci->dev, "Len is 0\n"); dev->act_len = len; dev->status = 0; return 0; unknown: - debug("requesttype=%x, request=%x, value=%x, index=%x, length=%x\n", + dev_dbg(ehci->dev, "requesttype=%x, request=%x, value=%x, index=%x, length=%x\n", req->requesttype, req->request, le16_to_cpu(req->value), le16_to_cpu(req->index), le16_to_cpu(req->length)); @@ -793,9 +795,11 @@ static int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int length, int timeout) { + struct usb_host *host = dev->host; + struct ehci_priv *ehci = to_ehci(host); if (usb_pipetype(pipe) != PIPE_BULK) { - debug("non-bulk pipe (type=%lu)", usb_pipetype(pipe)); + dev_dbg(ehci->dev, "non-bulk pipe (type=%lu)", usb_pipetype(pipe)); return -1; } return ehci_submit_async(dev, pipe, buffer, length, NULL); @@ -809,7 +813,7 @@ submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, struct ehci_priv *ehci = to_ehci(host); if (usb_pipetype(pipe) != PIPE_CONTROL) { - debug("non-control pipe (type=%lu)", usb_pipetype(pipe)); + dev_dbg(ehci->dev, "non-control pipe (type=%lu)", usb_pipetype(pipe)); return -1; } @@ -825,7 +829,10 @@ static int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int length, int interval) { - debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d", + struct usb_host *host = dev->host; + struct ehci_priv *ehci = to_ehci(host); + + dev_dbg(ehci->dev, "dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d", dev, pipe, buffer, length, interval); return -1; } @@ -841,9 +848,14 @@ int ehci_register(struct device_d *dev, struct ehci_data *data) dev->priv = ehci; ehci->flags = data->flags; ehci->hccr = data->hccr; - ehci->hcor = data->hcor; ehci->dev = dev; + if (data->hcor) + ehci->hcor = data->hcor; + else + ehci->hcor = (void __iomem *)ehci->hccr + + HC_LENGTH(ehci_readl(&ehci->hccr->cr_capbase)); + ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) * NUM_TD); ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD); @@ -877,13 +889,11 @@ static int ehci_probe(struct device_d *dev) else data.flags = EHCI_HAS_TT; - if (dev->num_resources < 2) { - printf("echi: need 2 resources base and data"); - return -ENODEV; - } - data.hccr = dev_request_mem_region(dev, 0); - data.hcor = dev_request_mem_region(dev, 1); + if (dev->num_resources > 1) + data.hcor = dev_request_mem_region(dev, 1); + else + data.hcor = NULL; return ehci_register(dev, &data); } diff --git a/drivers/usb/imx/Kconfig b/drivers/usb/imx/Kconfig index 2c52e727d8..b1ce682f1d 100644 --- a/drivers/usb/imx/Kconfig +++ b/drivers/usb/imx/Kconfig @@ -13,3 +13,8 @@ config USB_IMX_CHIPIDEA This driver is recommended for new designs, but it needs board support to work. It's safe to say yes here. Also select EHCI support for USB host. + +config USB_IMX_PHY + bool + depends on ARCH_IMX + default y if ARCH_IMX6 diff --git a/drivers/usb/imx/Makefile b/drivers/usb/imx/Makefile index e37361c00a..e15bc711a9 100644 --- a/drivers/usb/imx/Makefile +++ b/drivers/usb/imx/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_USB_IMX_CHIPIDEA) += imx-usb-misc.o chipidea-imx.o +obj-$(CONFIG_USB_IMX_PHY) += imx-usb-phy.o diff --git a/drivers/usb/imx/imx-usb-misc.c b/drivers/usb/imx/imx-usb-misc.c index 7c0ba5c5c4..4cdf5ab3af 100644 --- a/drivers/usb/imx/imx-usb-misc.c +++ b/drivers/usb/imx/imx-usb-misc.c @@ -324,6 +324,12 @@ static __maybe_unused int mx5_initialize_usb_hw(void __iomem *base, int port, return 0; } +static __maybe_unused int mx6_initialize_usb_hw(void __iomem *base, int port, + unsigned int flags) +{ + return 0; +} + static struct platform_device_id imx_usbmisc_ids[] = { #ifdef CONFIG_ARCH_IMX25 { @@ -361,6 +367,12 @@ static struct platform_device_id imx_usbmisc_ids[] = { .driver_data = (unsigned long)&mx5_initialize_usb_hw, }, #endif +#ifdef CONFIG_ARCH_IMX6 + { + .name = "imx6-usb-misc", + .driver_data = (unsigned long)&mx6_initialize_usb_hw, + }, +#endif { /* sentinel */ }, diff --git a/drivers/usb/imx/imx-usb-phy.c b/drivers/usb/imx/imx-usb-phy.c new file mode 100644 index 0000000000..ce9c93f42d --- /dev/null +++ b/drivers/usb/imx/imx-usb-phy.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013 Sascha Hauer <s.hauer@pengutronix.de> + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include <common.h> +#include <init.h> +#include <io.h> +#include <driver.h> +#include <malloc.h> +#include <linux/clk.h> +#include <linux/err.h> + +#define SET 0x4 +#define CLR 0x8 + +#define USBPHY_CTRL 0x30 + +#define USBPHY_CTRL_SFTRST (1 << 31) +#define USBPHY_CTRL_CLKGATE (1 << 30) +#define USBPHY_CTRL_ENUTMILEVEL3 (1 << 15) +#define USBPHY_CTRL_ENUTMILEVEL2 (1 << 14) + +struct imx_usbphy { + void __iomem *base; + struct clk *clk; +}; + +static int imx_usbphy_enable(struct imx_usbphy *imxphy) +{ + u32 val; + + clk_enable(imxphy->clk); + + /* reset usbphy */ + writel(USBPHY_CTRL_SFTRST, imxphy->base + USBPHY_CTRL + SET); + + udelay(10); + + /* clr reset and clkgate */ + writel(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE, + imxphy->base + USBPHY_CTRL + CLR); + + /* clr all pwd bits => power up phy */ + writel(0xffffffff, imxphy->base + CLR); + + /* set utmilvl2/3 */ + val = readl(imxphy->base + USBPHY_CTRL); + val |= USBPHY_CTRL_ENUTMILEVEL3 | USBPHY_CTRL_ENUTMILEVEL2; + writel(val, imxphy->base + USBPHY_CTRL + SET); + + return 0; +} + +static int imx_usbphy_probe(struct device_d *dev) +{ + int ret; + struct imx_usbphy *imxphy; + + imxphy = xzalloc(sizeof(*imxphy)); + + imxphy->base = dev_request_mem_region(dev, 0); + if (!imxphy->base) { + ret = -ENODEV; + goto err_free; + } + + imxphy->clk = clk_get(dev, NULL); + if (IS_ERR(imxphy->clk)) { + dev_err(dev, "could not get clk: %s\n", strerror(-PTR_ERR(imxphy->clk))); + goto err_clk; + } + + imx_usbphy_enable(imxphy); + + dev_dbg(dev, "phy enabled\n"); + + return 0; + +err_clk: +err_free: + free(imxphy); + + return ret; +}; + +static struct driver_d imx_usbphy_driver = { + .name = "imx-usb-phy", + .probe = imx_usbphy_probe, +}; + +static int imx_usbphy_init(void) +{ + return platform_driver_register(&imx_usbphy_driver); +} +coredevice_initcall(imx_usbphy_init); diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 354e68b45c..6d6b08f605 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -5,6 +5,14 @@ menuconfig VIDEO if VIDEO +config DRIVER_VIDEO_ATMEL + bool "Atmel LCDC framebuffer driver" + depends on ARCH_AT91 + +config DRIVER_VIDEO_ATMEL_HLCD + bool "Atmel HLCDC framebuffer driver" + depends on ARCH_AT91 + config DRIVER_VIDEO_IMX bool "i.MX framebuffer driver" depends on ARCH_IMX1 || ARCH_IMX21 || ARCH_IMX25 || ARCH_IMX27 diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 77f6682576..742914190c 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -1,5 +1,7 @@ obj-$(CONFIG_VIDEO) += fb.o +obj-$(CONFIG_DRIVER_VIDEO_ATMEL) += atmel_lcdfb.o atmel_lcdfb_core.o +obj-$(CONFIG_DRIVER_VIDEO_ATMEL_HLCD) += atmel_hlcdfb.o atmel_lcdfb_core.o obj-$(CONFIG_DRIVER_VIDEO_STM) += stm.o obj-$(CONFIG_DRIVER_VIDEO_IMX) += imx.o obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c new file mode 100644 index 0000000000..78a737d0b9 --- /dev/null +++ b/drivers/video/atmel_hlcdfb.c @@ -0,0 +1,297 @@ +/* + * Driver for AT91/AT32 LCD Controller + * + * Copyright (C) 2007 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <io.h> +#include <init.h> +#include <linux/clk.h> +#include <mach/hardware.h> +#include <mach/atmel_hlcdc.h> +#include <mach/io.h> +#include <mach/cpu.h> +#include <errno.h> +#include <asm/mmu.h> + +#include "atmel_lcdfb.h" + +#define ATMEL_LCDC_CVAL_DEFAULT 0xc8 + +static void atmel_hlcdfb_stop(struct atmel_lcdfb_info *sinfo, u32 flags) +{ + /* Disable DISP signal */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_DISPDIS); + while ((lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_DISPSTS)) + mdelay(1); + /* Disable synchronization */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_SYNCDIS); + while ((lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_LCDSTS)) + mdelay(1); + /* Disable pixel clock */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_CLKDIS); + while ((lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_CLKSTS)) + mdelay(1); + /* Disable PWM */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDDIS, LCDC_LCDDIS_PWMDIS); + while ((lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_PWMSTS)) + mdelay(1); + + if (!(flags & ATMEL_LCDC_STOP_NOWAIT)) + /* Wait for the end of DMA transfer */ + while (!(lcdc_readl(sinfo, ATMEL_LCDC_BASEISR) & LCDC_BASEISR_DMA)) + mdelay(10); + /*FIXME: OVL DMA? */ +} + +static void atmel_hlcdfb_start(struct atmel_lcdfb_info *sinfo) +{ + lcdc_writel(sinfo, ATMEL_LCDC_LCDEN, LCDC_LCDEN_CLKEN); + while (!(lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_CLKSTS)) + mdelay(1); + lcdc_writel(sinfo, ATMEL_LCDC_LCDEN, LCDC_LCDEN_SYNCEN); + while (!(lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_LCDSTS)) + mdelay(1); + lcdc_writel(sinfo, ATMEL_LCDC_LCDEN, LCDC_LCDEN_DISPEN); + while (!(lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_DISPSTS)) + mdelay(1); + lcdc_writel(sinfo, ATMEL_LCDC_LCDEN, LCDC_LCDEN_PWMEN); + while (!(lcdc_readl(sinfo, ATMEL_LCDC_LCDSR) & LCDC_LCDSR_PWMSTS)) + mdelay(1); +} + +struct atmel_hlcd_dma_desc { + u32 address; + u32 control; + u32 next; +}; + +static void atmel_hlcdfb_update_dma(struct fb_info *info) +{ + struct atmel_lcdfb_info *sinfo = info->priv; + unsigned long dma_addr; + struct atmel_hlcd_dma_desc *desc; + + dma_addr = (u32)info->screen_base; + dma_addr &= ~3UL; + + /* Setup the DMA descriptor, this descriptor will loop to itself */ + desc = sinfo->dma_desc; + + desc->address = dma_addr; + /* Disable DMA transfer interrupt & descriptor loaded interrupt. */ + desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN + | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH; + desc->next = (u32)desc; + + lcdc_writel(sinfo, ATMEL_LCDC_BASEADDR, desc->address); + lcdc_writel(sinfo, ATMEL_LCDC_BASECTRL, desc->control); + lcdc_writel(sinfo, ATMEL_LCDC_BASENEXT, desc->next); + lcdc_writel(sinfo, ATMEL_LCDC_BASECHER, LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN); +} + +static void atmel_hlcdfb_limit_screeninfo(struct fb_videomode *mode) +{ + u32 hbpw, hfpw; + + if (cpu_is_at91sam9x5()) { + hbpw = LCDC_LCDCFG3_HBPW; + hfpw = LCDC_LCDCFG3_HFPW; + } else { + hbpw = LCDC2_LCDCFG3_HBPW; + hfpw = LCDC2_LCDCFG3_HFPW; + } + + /* Saturate vertical and horizontal timings at maximum values */ + mode->vsync_len = min_t(u32, mode->vsync_len, + (LCDC_LCDCFG1_VSPW >> LCDC_LCDCFG1_VSPW_OFFSET) + 1); + mode->upper_margin = min_t(u32, mode->upper_margin, + (LCDC_LCDCFG2_VFPW >> LCDC_LCDCFG2_VFPW_OFFSET) + 1); + mode->lower_margin = min_t(u32, mode->lower_margin, + LCDC_LCDCFG2_VBPW >> LCDC_LCDCFG2_VBPW_OFFSET); + mode->right_margin = min_t(u32, mode->right_margin, + (hbpw >> LCDC_LCDCFG3_HBPW_OFFSET) + 1); + mode->hsync_len = min_t(u32, mode->hsync_len, + (LCDC_LCDCFG1_HSPW >> LCDC_LCDCFG1_HSPW_OFFSET) + 1); + mode->left_margin = min_t(u32, mode->left_margin, + (hfpw >> LCDC_LCDCFG3_HFPW_OFFSET) + 1); +} + +static u32 atmel_hlcdfb_get_rgbmode(struct fb_info *info) +{ + u32 value = 0; + + switch (info->bits_per_pixel) { + case 1: + value = LCDC_BASECFG1_CLUTMODE_1BPP | LCDC_BASECFG1_CLUTEN; + break; + case 2: + value = LCDC_BASECFG1_CLUTMODE_2BPP | LCDC_BASECFG1_CLUTEN; + break; + case 4: + value = LCDC_BASECFG1_CLUTMODE_4BPP | LCDC_BASECFG1_CLUTEN; + break; + case 8: + value = LCDC_BASECFG1_CLUTMODE_8BPP | LCDC_BASECFG1_CLUTEN; + break; + case 12: + value = LCDC_BASECFG1_RGBMODE_12BPP_RGB_444; + break; + case 16: + if (info->transp.offset) + value = LCDC_BASECFG1_RGBMODE_16BPP_ARGB_4444; + else + value = LCDC_BASECFG1_RGBMODE_16BPP_RGB_565; + break; + case 18: + value = LCDC_BASECFG1_RGBMODE_18BPP_RGB_666_PACKED; + break; + case 24: + value = LCDC_BASECFG1_RGBMODE_24BPP_RGB_888_PACKED; + break; + case 32: + value = LCDC_BASECFG1_RGBMODE_32BPP_ARGB_8888; + break; + default: + dev_err(&info->dev, "Cannot set video mode for %dbpp\n", + info->bits_per_pixel); + break; + } + + return value; +} + +static void atmel_hlcdfb_setup_core_base(struct fb_info *info) +{ + struct atmel_lcdfb_info *sinfo = info->priv; + struct atmel_lcdfb_platform_data *pdata = sinfo->pdata; + struct fb_videomode *mode = info->mode; + unsigned long value; + unsigned long clk_value_khz; + + dev_dbg(&info->dev, "%s:\n", __func__); + /* Set pixel clock */ + clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; + + value = DIV_ROUND_CLOSEST(clk_value_khz, PICOS2KHZ(mode->pixclock)); + + if (value < 1) { + dev_notice(&info->dev, "using system clock as pixel clock\n"); + value = LCDC_LCDCFG0_CLKPWMSEL; + } else { + mode->pixclock = KHZ2PICOS(clk_value_khz / value); + dev_dbg(&info->dev, " updated pixclk: %lu KHz\n", + PICOS2KHZ(mode->pixclock)); + value = value - 2; + dev_dbg(&info->dev, " * programming CLKDIV = 0x%08lx\n", + value); + value = (value << LCDC_LCDCFG0_CLKDIV_OFFSET); + } + value |= LCDC_LCDCFG0_CGDISBASE; + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG0, value); + + /* Initialize control register 5 */ + /* In 9x5, the default_lcdcon2 will use for LCDCFG5 */ + value = pdata->default_lcdcon2; + value |= (sinfo->guard_time << LCDC_LCDCFG5_GUARDTIME_OFFSET) + | LCDC_LCDCFG5_DISPDLY + | LCDC_LCDCFG5_VSPDLYS; + + if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT)) + value |= LCDC_LCDCFG5_HSPOL; + if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT)) + value |= LCDC_LCDCFG5_VSPOL; + + dev_dbg(&info->dev, " * LCDC_LCDCFG5 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG5, value); + + /* Vertical & Horizontal Timing */ + value = (mode->vsync_len - 1) << LCDC_LCDCFG1_VSPW_OFFSET; + value |= (mode->hsync_len - 1) << LCDC_LCDCFG1_HSPW_OFFSET; + dev_dbg(&info->dev, " * LCDC_LCDCFG1 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG1, value); + + value = (mode->upper_margin) << LCDC_LCDCFG2_VBPW_OFFSET; + value |= (mode->lower_margin - 1) << LCDC_LCDCFG2_VFPW_OFFSET; + dev_dbg(&info->dev, " * LCDC_LCDCFG2 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG2, value); + + value = (mode->left_margin - 1) << LCDC_LCDCFG3_HBPW_OFFSET; + value |= (mode->right_margin - 1) << LCDC_LCDCFG3_HFPW_OFFSET; + dev_dbg(&info->dev, " * LCDC_LCDCFG3 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG3, value); + + /* Display size */ + value = (mode->yres - 1) << LCDC_LCDCFG4_RPF_OFFSET; + value |= (mode->xres - 1) << LCDC_LCDCFG4_PPL_OFFSET; + dev_dbg(&info->dev, " * LCDC_LCDCFG4 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG4, value); + + lcdc_writel(sinfo, ATMEL_LCDC_BASECFG0, LCDC_BASECFG0_BLEN_AHB_INCR16 | LCDC_BASECFG0_DLBO); + lcdc_writel(sinfo, ATMEL_LCDC_BASECFG1, atmel_hlcdfb_get_rgbmode(info)); + lcdc_writel(sinfo, ATMEL_LCDC_BASECFG2, 0); + lcdc_writel(sinfo, ATMEL_LCDC_BASECFG3, 0); /* Default color */ + lcdc_writel(sinfo, ATMEL_LCDC_BASECFG4, LCDC_BASECFG4_DMA); + + /* Disable all interrupts */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDIDR, ~0UL); + lcdc_writel(sinfo, ATMEL_LCDC_BASEIDR, ~0UL); + /* Enable BASE LAYER overflow interrupts, if want to enable DMA interrupt, also need set it at LCDC_BASECTRL reg */ + lcdc_writel(sinfo, ATMEL_LCDC_BASEIER, LCDC_BASEIER_OVR); + /* FIXME: Let video-driver register a callback */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDIER, LCDC_LCDIER_FIFOERRIE | + LCDC_LCDIER_BASEIE | LCDC_LCDIER_HEOIE); +} + + +static void atmel_hlcdfb_init_contrast(struct atmel_lcdfb_info *sinfo) +{ + /* have some default contrast/backlight settings */ + lcdc_writel(sinfo, ATMEL_LCDC_LCDCFG6, LCDC_LCDCFG6_PWMPOL | + (ATMEL_LCDC_CVAL_DEFAULT << LCDC_LCDCFG6_PWMCVAL_OFFSET)); +} + +struct atmel_lcdfb_devdata atmel_hlcdfb_data = { + .start = atmel_hlcdfb_start, + .stop = atmel_hlcdfb_stop, + .update_dma = atmel_hlcdfb_update_dma, + .setup_core = atmel_hlcdfb_setup_core_base, + .init_contrast = atmel_hlcdfb_init_contrast, + .limit_screeninfo = atmel_hlcdfb_limit_screeninfo, + .dma_desc_size = sizeof(struct atmel_hlcd_dma_desc), +}; + +static int atmel_hlcdc_probe(struct device_d *dev) +{ + return atmel_lcdc_register(dev, &atmel_hlcdfb_data); +} + +static struct driver_d atmel_hlcdc_driver = { + .name = "atmel_hlcdfb", + .probe = atmel_hlcdc_probe, +}; + +static int atmel_hlcdc_init(void) +{ + return platform_driver_register(&atmel_hlcdc_driver); +} +device_initcall(atmel_hlcdc_init); diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c new file mode 100644 index 0000000000..08888cc9ba --- /dev/null +++ b/drivers/video/atmel_lcdfb.c @@ -0,0 +1,263 @@ +/* + * Driver for AT91/AT32 LCD Controller + * + * Copyright (C) 2007 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <io.h> +#include <init.h> +#include <mach/hardware.h> +#include <mach/io.h> +#include <mach/cpu.h> +#include <errno.h> +#include <asm/mmu.h> +#include <linux/clk.h> + +#include "atmel_lcdfb.h" + +/* configurable parameters */ +#define ATMEL_LCDC_CVAL_DEFAULT 0xc8 +#define ATMEL_LCDC_DMA_BURST_LEN 8 /* words */ +#define ATMEL_LCDC_FIFO_SIZE 512 /* words */ + +static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) +{ + unsigned long value; + + if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10() + || cpu_is_at32ap7000())) + return xres; + + value = xres; + if ((lcdcon2 & ATMEL_LCDC_DISTYPE) != ATMEL_LCDC_DISTYPE_TFT) { + /* STN display */ + if ((lcdcon2 & ATMEL_LCDC_DISTYPE) == ATMEL_LCDC_DISTYPE_STNCOLOR) + value *= 3; + + if ( (lcdcon2 & ATMEL_LCDC_IFWIDTH) == ATMEL_LCDC_IFWIDTH_4 + || ( (lcdcon2 & ATMEL_LCDC_IFWIDTH) == ATMEL_LCDC_IFWIDTH_8 + && (lcdcon2 & ATMEL_LCDC_SCANMOD) == ATMEL_LCDC_SCANMOD_DUAL )) + value = DIV_ROUND_UP(value, 4); + else + value = DIV_ROUND_UP(value, 8); + } + + return value; +} + +static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo, u32 flags) +{ + /* Turn off the LCD controller and the DMA controller */ + lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, + sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); + + /* Wait for the LCDC core to become idle */ + while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) + mdelay(10); + + lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); + + if (flags & ATMEL_LCDC_STOP_NOWAIT) + return; + + /* Wait for DMA engine to become idle... */ + while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) + mdelay(10); +} + +static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo) +{ + struct atmel_lcdfb_platform_data *pdata = sinfo->pdata; + + lcdc_writel(sinfo, ATMEL_LCDC_DMACON, pdata->default_dmacon); + lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, + (pdata->guard_time << ATMEL_LCDC_GUARDT_OFFSET) + | ATMEL_LCDC_PWR); +} + +static void atmel_lcdfb_update_dma(struct fb_info *info) +{ + struct atmel_lcdfb_info *sinfo = info->priv; + unsigned long dma_addr; + + dma_addr = (unsigned long)info->screen_base; + + dma_addr &= ~3UL; + + /* Set framebuffer DMA base address and pixel offset */ + lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr); +} + +static void atmel_lcdfb_limit_screeninfo(struct fb_videomode *mode) +{ + /* Saturate vertical and horizontal timings at maximum values */ + mode->vsync_len = min_t(u32, mode->vsync_len, + (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1); + mode->upper_margin = min_t(u32, mode->upper_margin, + ATMEL_LCDC_VBP >> ATMEL_LCDC_VBP_OFFSET); + mode->lower_margin = min_t(u32, mode->lower_margin, + ATMEL_LCDC_VFP); + mode->right_margin = min_t(u32, mode->right_margin, + (ATMEL_LCDC_HFP >> ATMEL_LCDC_HFP_OFFSET) + 1); + mode->hsync_len = min_t(u32, mode->hsync_len, + (ATMEL_LCDC_HPW >> ATMEL_LCDC_HPW_OFFSET) + 1); + mode->left_margin = min_t(u32, mode->left_margin, + ATMEL_LCDC_HBP + 1); + +} + +static void atmel_lcdfb_setup_core(struct fb_info *info) +{ + struct atmel_lcdfb_info *sinfo = info->priv; + struct atmel_lcdfb_platform_data *pdata = sinfo->pdata; + struct fb_videomode *mode = info->mode; + unsigned long clk_value_khz; + unsigned long pix_factor = 2; + unsigned long hozval_linesz; + unsigned long value; + + /* ...set frame size and burst length = 8 words (?) */ + value = (mode->yres * mode->xres * info->bits_per_pixel) / 32; + value |= ((ATMEL_LCDC_DMA_BURST_LEN - 1) << ATMEL_LCDC_BLENGTH_OFFSET); + lcdc_writel(sinfo, ATMEL_LCDC_DMAFRMCFG, value); + + /* Set pixel clock */ + if (cpu_is_at91sam9g45() && !cpu_is_at91sam9g45es()) + pix_factor = 1; + + clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; + + value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(mode->pixclock)); + + if (value < pix_factor) { + dev_notice(&info->dev, "Bypassing pixel clock divider\n"); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS); + } else { + value = (value / pix_factor) - 1; + dev_dbg(&info->dev, " * programming CLKVAL = 0x%08lx\n", + value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, + value << ATMEL_LCDC_CLKVAL_OFFSET); + mode->pixclock = + KHZ2PICOS(clk_value_khz / (pix_factor * (value + 1))); + dev_dbg(&info->dev, " updated pixclk: %lu KHz\n", + PICOS2KHZ(mode->pixclock)); + } + + /* Initialize control register 2 */ + value = pdata->default_lcdcon2; + + if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT)) + value |= ATMEL_LCDC_INVLINE_INVERTED; + if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT)) + value |= ATMEL_LCDC_INVFRAME_INVERTED; + + switch (info->bits_per_pixel) { + case 1: value |= ATMEL_LCDC_PIXELSIZE_1; break; + case 2: value |= ATMEL_LCDC_PIXELSIZE_2; break; + case 4: value |= ATMEL_LCDC_PIXELSIZE_4; break; + case 8: value |= ATMEL_LCDC_PIXELSIZE_8; break; + case 16: value |= ATMEL_LCDC_PIXELSIZE_16; break; + case 24: value |= ATMEL_LCDC_PIXELSIZE_24; break; + case 32: value |= ATMEL_LCDC_PIXELSIZE_32; break; + default: BUG(); break; + } + dev_dbg(&info->dev, " * LCDCON2 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDCON2, value); + + /* Vertical timing */ + value = (mode->vsync_len - 1) << ATMEL_LCDC_VPW_OFFSET; + value |= mode->upper_margin << ATMEL_LCDC_VBP_OFFSET; + value |= mode->lower_margin; + dev_dbg(&info->dev, " * LCDTIM1 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_TIM1, value); + + /* Horizontal timing */ + value = (mode->right_margin - 1) << ATMEL_LCDC_HFP_OFFSET; + value |= (mode->hsync_len - 1) << ATMEL_LCDC_HPW_OFFSET; + value |= (mode->left_margin - 1); + dev_dbg(&info->dev, " * LCDTIM2 = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_TIM2, value); + + /* Horizontal value (aka line size) */ + hozval_linesz = compute_hozval(mode->xres, + lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2)); + + /* Display size */ + value = (hozval_linesz - 1) << ATMEL_LCDC_HOZVAL_OFFSET; + value |= mode->yres - 1; + dev_dbg(&info->dev, " * LCDFRMCFG = %08lx\n", value); + lcdc_writel(sinfo, ATMEL_LCDC_LCDFRMCFG, value); + + /* FIFO Threshold: Use formula from data sheet */ + value = ATMEL_LCDC_FIFO_SIZE - (2 * ATMEL_LCDC_DMA_BURST_LEN + 3); + lcdc_writel(sinfo, ATMEL_LCDC_FIFO, value); + + /* Toggle LCD_MODE every frame */ + lcdc_writel(sinfo, ATMEL_LCDC_MVAL, 0); + + /* Disable all interrupts */ + lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); + + /* Enable FIFO & DMA errors */ + lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI); + + /* ...wait for DMA engine to become idle... */ + while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) + mdelay(10); +} + +static void atmel_lcdfb_init_contrast(struct atmel_lcdfb_info *sinfo) +{ + unsigned long value; + + value = ATMEL_LCDC_PS_DIV8 | + ATMEL_LCDC_POL_POSITIVE | + ATMEL_LCDC_ENA_PWMENABLE; + lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, value); + lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT); +} + +struct atmel_lcdfb_devdata atmel_lcdfb_data = { + .start = atmel_lcdfb_start, + .stop = atmel_lcdfb_stop, + .update_dma = atmel_lcdfb_update_dma, + .setup_core = atmel_lcdfb_setup_core, + .init_contrast = atmel_lcdfb_init_contrast, + .limit_screeninfo = atmel_lcdfb_limit_screeninfo, +}; + +static int atmel_lcdc_probe(struct device_d *dev) +{ + return atmel_lcdc_register(dev, &atmel_lcdfb_data); +} + +static struct driver_d atmel_lcdc_driver = { + .name = "atmel_lcdfb", + .probe = atmel_lcdc_probe, +}; + +static int atmel_lcdc_init(void) +{ + return platform_driver_register(&atmel_lcdc_driver); +} +device_initcall(atmel_lcdc_init); diff --git a/drivers/video/atmel_lcdfb.h b/drivers/video/atmel_lcdfb.h new file mode 100644 index 0000000000..ea4c7e647a --- /dev/null +++ b/drivers/video/atmel_lcdfb.h @@ -0,0 +1,37 @@ + +#include <fb.h> +#include <video/atmel_lcdc.h> + +struct atmel_lcdfb_info; + +struct atmel_lcdfb_devdata { + void (*start)(struct atmel_lcdfb_info *sinfo); + void (*stop)(struct atmel_lcdfb_info *sinfo, u32 flags); + void (*update_dma)(struct fb_info *info); + void (*setup_core)(struct fb_info *info); + void (*init_contrast)(struct atmel_lcdfb_info *sinfo); + void (*limit_screeninfo)(struct fb_videomode *mode); + int dma_desc_size; +}; + +struct atmel_lcdfb_info { + struct fb_info info; + void __iomem *mmio; + struct device_d *device; + + unsigned int guard_time; + unsigned int smem_len; + struct clk *bus_clk; + struct clk *lcdc_clk; + + struct atmel_lcdfb_platform_data *pdata; + struct atmel_lcdfb_devdata *dev_data; + void *dma_desc; +}; + +#define lcdc_readl(sinfo, reg) __raw_readl((sinfo)->mmio+(reg)) +#define lcdc_writel(sinfo, reg, val) __raw_writel((val), (sinfo)->mmio+(reg)) + +#define ATMEL_LCDC_STOP_NOWAIT (1 << 0) + +int atmel_lcdc_register(struct device_d *dev, struct atmel_lcdfb_devdata *data); diff --git a/drivers/video/atmel_lcdfb_core.c b/drivers/video/atmel_lcdfb_core.c new file mode 100644 index 0000000000..bed540da9f --- /dev/null +++ b/drivers/video/atmel_lcdfb_core.c @@ -0,0 +1,313 @@ +/* + * Driver for AT91/AT32 LCD Controller + * + * Copyright (C) 2007 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <io.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <malloc.h> +#include <asm/mmu.h> + +#include "atmel_lcdfb.h" + +static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo) +{ + clk_enable(sinfo->bus_clk); + clk_enable(sinfo->lcdc_clk); +} + +static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo) +{ + clk_disable(sinfo->bus_clk); + clk_disable(sinfo->lcdc_clk); +} + +static void atmel_lcdc_power_controller(struct fb_info *fb_info, int i) +{ + struct atmel_lcdfb_info *sinfo = fb_info->priv; + struct atmel_lcdfb_platform_data *pdata = sinfo->pdata; + + if (pdata->atmel_lcdfb_power_control) + pdata->atmel_lcdfb_power_control(1); +} + +/** + * @param fb_info Framebuffer information + */ +static void atmel_lcdc_enable_controller(struct fb_info *fb_info) +{ + atmel_lcdc_power_controller(fb_info, 1); +} + +/** + * @param fb_info Framebuffer information + */ +static void atmel_lcdc_disable_controller(struct fb_info *fb_info) +{ + atmel_lcdc_power_controller(fb_info, 0); +} + + +static int atmel_lcdfb_check_var(struct fb_info *info) +{ + struct device_d *dev = &info->dev; + struct atmel_lcdfb_info *sinfo = info->priv; + struct atmel_lcdfb_platform_data *pdata = sinfo->pdata; + struct fb_videomode *mode = info->mode; + unsigned long clk_value_khz; + + clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; + + dev_dbg(dev, "%s:\n", __func__); + + if (!(mode->pixclock && info->bits_per_pixel)) { + dev_err(dev, "needed value not specified\n"); + return -EINVAL; + } + + dev_dbg(dev, " resolution: %ux%u\n", mode->xres, mode->yres); + dev_dbg(dev, " pixclk: %lu KHz\n", PICOS2KHZ(mode->pixclock)); + dev_dbg(dev, " bpp: %u\n", info->bits_per_pixel); + dev_dbg(dev, " clk: %lu KHz\n", clk_value_khz); + + if (PICOS2KHZ(mode->pixclock) > clk_value_khz) { + dev_err(dev, "%lu KHz pixel clock is too fast\n", PICOS2KHZ(mode->pixclock)); + return -EINVAL; + } + + /* Saturate vertical and horizontal timings at maximum values */ + if (sinfo->dev_data->limit_screeninfo) + sinfo->dev_data->limit_screeninfo(mode); + + mode->vsync_len = min_t(u32, mode->vsync_len, + (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1); + mode->upper_margin = min_t(u32, mode->upper_margin, + ATMEL_LCDC_VBP >> ATMEL_LCDC_VBP_OFFSET); + mode->lower_margin = min_t(u32, mode->lower_margin, + ATMEL_LCDC_VFP); + mode->right_margin = min_t(u32, mode->right_margin, + (ATMEL_LCDC_HFP >> ATMEL_LCDC_HFP_OFFSET) + 1); + mode->hsync_len = min_t(u32, mode->hsync_len, + (ATMEL_LCDC_HPW >> ATMEL_LCDC_HPW_OFFSET) + 1); + mode->left_margin = min_t(u32, mode->left_margin, + ATMEL_LCDC_HBP + 1); + + /* Some parameters can't be zero */ + mode->vsync_len = max_t(u32, mode->vsync_len, 1); + mode->right_margin = max_t(u32, mode->right_margin, 1); + mode->hsync_len = max_t(u32, mode->hsync_len, 1); + mode->left_margin = max_t(u32, mode->left_margin, 1); + + switch (info->bits_per_pixel) { + case 1: + case 2: + case 4: + case 8: + info->red.offset = info->green.offset = info->blue.offset = 0; + info->red.length = info->green.length = info->blue.length + = info->bits_per_pixel; + break; + case 16: + /* Older SOCs use IBGR:555 rather than BGR:565. */ + if (pdata->have_intensity_bit) + info->green.length = 5; + else + info->green.length = 6; + if (pdata->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) { + /* RGB:5X5 mode */ + info->red.offset = info->green.length + 5; + info->blue.offset = 0; + } else { + /* BGR:5X5 mode */ + info->red.offset = 0; + info->blue.offset = info->green.length + 5; + } + info->green.offset = 5; + info->red.length = info->blue.length = 5; + break; + case 32: + info->transp.offset = 24; + info->transp.length = 8; + /* fall through */ + case 24: + if (pdata->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) { + /* RGB:888 mode */ + info->red.offset = 16; + info->blue.offset = 0; + } else { + /* BGR:888 mode */ + info->red.offset = 0; + info->blue.offset = 16; + } + info->green.offset = 8; + info->red.length = info->green.length = info->blue.length = 8; + break; + default: + dev_err(dev, "color depth %d not supported\n", + info->bits_per_pixel); + return -EINVAL; + } + + return 0; +} + +static void atmel_lcdfb_set_par(struct fb_info *info) +{ + struct atmel_lcdfb_info *sinfo = info->priv; + + if (sinfo->dev_data->stop) + sinfo->dev_data->stop(sinfo, ATMEL_LCDC_STOP_NOWAIT); + + /* Re-initialize the DMA engine... */ + dev_dbg(&info->dev, " * update DMA engine\n"); + sinfo->dev_data->update_dma(info); + + /* Now, the LCDC core... */ + sinfo->dev_data->setup_core(info); + + if (sinfo->dev_data->start) + sinfo->dev_data->start(sinfo); + + dev_dbg(&info->dev, " * DONE\n"); +} + +static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) +{ + struct fb_info *info = &sinfo->info; + struct fb_videomode *mode = info->mode; + unsigned int smem_len; + + free(info->screen_base); + + smem_len = (mode->xres * mode->yres + * ((info->bits_per_pixel + 7) / 8)); + smem_len = max(smem_len, sinfo->smem_len); + + info->screen_base = dma_alloc_coherent(smem_len); + + if (!info->screen_base) + return -ENOMEM; + + memset(info->screen_base, 0, smem_len); + + return 0; +} + +/** + * Prepare the video hardware for a specified video mode + * @param fb_info Framebuffer information + * @param mode The video mode description to initialize + * @return 0 on success + */ +static int atmel_lcdc_activate_var(struct fb_info *info) +{ + struct atmel_lcdfb_info *sinfo = info->priv; + int ret; + + ret = atmel_lcdfb_alloc_video_memory(sinfo); + if (ret) + return ret; + + atmel_lcdfb_set_par(info); + + if (sinfo->dev_data->init_contrast) + sinfo->dev_data->init_contrast(sinfo); + + return atmel_lcdfb_check_var(info); +} + +/* + * There is only one video hardware instance available. + * It makes no sense to dynamically allocate this data + */ +static struct fb_ops atmel_lcdc_ops = { + .fb_activate_var = atmel_lcdc_activate_var, + .fb_enable = atmel_lcdc_enable_controller, + .fb_disable = atmel_lcdc_disable_controller, +}; + +int atmel_lcdc_register(struct device_d *dev, struct atmel_lcdfb_devdata *data) +{ + struct atmel_lcdfb_info *sinfo; + struct atmel_lcdfb_platform_data *pdata = dev->platform_data; + int ret = 0; + struct fb_info *info; + + if (!pdata) { + dev_err(dev, "missing platform_data\n"); + return -EINVAL; + } + + sinfo = xzalloc(sizeof(*sinfo)); + sinfo->pdata = pdata; + sinfo->mmio = dev_request_mem_region(dev, 0); + + sinfo->dev_data = data; + + /* just init */ + info = &sinfo->info; + info->priv = sinfo; + info->fbops = &atmel_lcdc_ops; + info->mode_list = pdata->mode_list; + info->num_modes = pdata->num_modes; + info->mode = &info->mode_list[0]; + info->xres = info->mode->xres; + info->yres = info->mode->yres; + info->bits_per_pixel = pdata->default_bpp; + + /* Enable LCDC Clocks */ + sinfo->bus_clk = clk_get(dev, "hck1"); + if (IS_ERR(sinfo->bus_clk)) { + ret = PTR_ERR(sinfo->bus_clk); + goto err; + } + sinfo->lcdc_clk = clk_get(dev, "lcdc_clk"); + if (IS_ERR(sinfo->lcdc_clk)) { + ret = PTR_ERR(sinfo->lcdc_clk); + goto put_bus_clk; + } + + atmel_lcdfb_start_clock(sinfo); + + if (data->dma_desc_size) + sinfo->dma_desc = dma_alloc_coherent(data->dma_desc_size); + + ret = register_framebuffer(info); + if (ret != 0) { + dev_err(dev, "Failed to register framebuffer\n"); + goto stop_clk; + } + + return ret; + +stop_clk: + if (sinfo->dma_desc) + free(sinfo->dma_desc); + atmel_lcdfb_stop_clock(sinfo); + clk_put(sinfo->lcdc_clk); +put_bus_clk: + clk_put(sinfo->bus_clk); +err: + return ret; +} diff --git a/drivers/video/imx.c b/drivers/video/imx.c index 39ecf6ae9f..a1ccf0aec8 100644 --- a/drivers/video/imx.c +++ b/drivers/video/imx.c @@ -138,7 +138,10 @@ struct imxfb_rgb { struct imxfb_info { void __iomem *regs; - struct clk *clk; + + struct clk *ahb_clk; + struct clk *ipg_clk; + struct clk *per_clk; u_int pcr; u_int pwmr; @@ -252,7 +255,9 @@ static void imxfb_enable_controller(struct fb_info *info) writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR); - clk_enable(fbi->clk); + clk_enable(fbi->ahb_clk); + clk_enable(fbi->ipg_clk); + clk_enable(fbi->per_clk); if (fbi->enable) fbi->enable(1); @@ -267,7 +272,9 @@ static void imxfb_disable_controller(struct fb_info *info) writel(0, fbi->regs + LCDC_RMCR); - clk_disable(fbi->clk); + clk_disable(fbi->per_clk); + clk_disable(fbi->ipg_clk); + clk_disable(fbi->ahb_clk); } /* @@ -321,7 +328,7 @@ static int imxfb_activate_var(struct fb_info *info) writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1), fbi->regs + LCDC_CPOS); - lcd_clk = clk_get_rate(fbi->clk); + lcd_clk = clk_get_rate(fbi->per_clk); tmp = mode->pixclock * (unsigned long long)lcd_clk; @@ -531,9 +538,17 @@ static int imxfb_probe(struct device_d *dev) fbi = xzalloc(sizeof(*fbi)); info = &fbi->info; - fbi->clk = clk_get(dev, NULL); - if (IS_ERR(fbi->clk)) - return PTR_ERR(fbi->clk); + fbi->per_clk = clk_get(dev, NULL); + if (IS_ERR(fbi->per_clk)) + return PTR_ERR(fbi->per_clk); + + fbi->ahb_clk = clk_get(dev, "ahb"); + if (IS_ERR(fbi->ahb_clk)) + return PTR_ERR(fbi->ahb_clk); + + fbi->ipg_clk = clk_get(dev, "ipg"); + if (IS_ERR(fbi->ipg_clk)) + return PTR_ERR(fbi->ipg_clk); fbi->mode = pdata->mode; fbi->regs = dev_request_mem_region(dev, 0); @@ -517,7 +517,7 @@ static int tftp_write(struct device_d *_dev, FILE *f, const void *inbuf, size_t size, now; int ret; - debug("%s: %d\n", __func__, insize); + debug("%s: %zu\n", __func__, insize); size = insize; @@ -552,7 +552,7 @@ static int tftp_read(struct device_d *dev, FILE *f, void *buf, size_t insize) size_t outsize = 0, now; int ret; - debug("%s %d\n", __func__, insize); + debug("%s %zu\n", __func__, insize); while (insize) { now = kfifo_get(priv->fifo, buf, insize); diff --git a/include/bootstrap.h b/include/bootstrap.h new file mode 100644 index 0000000000..0fa6b83157 --- /dev/null +++ b/include/bootstrap.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPLv2 + */ + +#ifndef __BOOSTRAP_H__ +#define __BOOSTRAP_H__ + +#define bootstrap_err(fmt, arg...) printf(fmt, ##arg) + +void bootstrap_boot(int (*func)(void), bool barebox); + +#ifdef CONFIG_BOOTSTRAP_DEVFS +void* bootstrap_read_devfs(char *devname, bool use_bb, int offset, + int default_size, int max_size); +#else +static inline void* bootstrap_read_devfs(char *devname, bool use_bb, int offset, + int default_size, int max_size) +{ + return NULL; +} +#endif + +#ifdef CONFIG_BOOTSTRAP_DISK +void* bootstrap_read_disk(char *devname, char *fstype); +#else +static inline void* bootstrap_read_disk(char *devname, char *fstype) +{ + return NULL; +} +#endif + +#endif /* __BOOSTRAP_H__ */ diff --git a/include/common.h b/include/common.h index 3e67164ea9..e559b94a71 100644 --- a/include/common.h +++ b/include/common.h @@ -29,6 +29,7 @@ #include <linux/kernel.h> #include <linux/stddef.h> #include <asm/common.h> +#include <printk.h> /* * sanity check. The Linux Kernel defines only one of __LITTLE_ENDIAN and @@ -48,22 +49,6 @@ #error "None of __LITTLE_ENDIAN and __BIG_ENDIAN are defined" #endif -#define pr_info(fmt, arg...) printf(fmt, ##arg) -#define pr_notice(fmt, arg...) printf(fmt, ##arg) -#define pr_err(fmt, arg...) printf(fmt, ##arg) -#define pr_warning(fmt, arg...) printf(fmt, ##arg) -#define pr_crit(fmt, arg...) printf(fmt, ##arg) -#define pr_alert(fmt, arg...) printf(fmt, ##arg) -#define pr_emerg(fmt, arg...) printf(fmt, ##arg) - -#ifdef DEBUG -#define pr_debug(fmt, arg...) printf(fmt, ##arg) -#else -#define pr_debug(fmt, arg...) do {} while(0) -#endif - -#define debug(fmt, arg...) pr_debug(fmt, ##arg) - #define BUG() do { \ printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \ panic("BUG!"); \ @@ -159,7 +144,13 @@ int parse_area_spec(const char *str, loff_t *start, loff_t *size); unsigned long strtoul_suffix(const char *str, char **endp, int base); unsigned long long strtoull_suffix(const char *str, char **endp, int base); -void start_barebox(void); +/* + * Function pointer to the main barebox function. Defaults + * to run_shell() when a shell is enabled. + */ +extern int (*barebox_main)(void); + +void __noreturn start_barebox(void); void shutdown_barebox(void); /* diff --git a/include/driver.h b/include/driver.h index 7ad0374f81..31f5d69848 100644 --- a/include/driver.h +++ b/include/driver.h @@ -358,35 +358,6 @@ static inline int dev_close_default(struct device_d *dev, struct filep *f) return 0; } -/* debugging and troubleshooting/diagnostic helpers. */ - -int dev_printf(const struct device_d *dev, const char *format, ...) - __attribute__ ((format(__printf__, 2, 3))); - - -#define dev_emerg(dev, format, arg...) \ - dev_printf((dev) , format , ## arg) -#define dev_alert(dev, format, arg...) \ - dev_printf((dev) , format , ## arg) -#define dev_crit(dev, format, arg...) \ - dev_printf((dev) , format , ## arg) -#define dev_err(dev, format, arg...) \ - dev_printf(dev , format , ## arg) -#define dev_warn(dev, format, arg...) \ - dev_printf((dev) , format , ## arg) -#define dev_notice(dev, format, arg...) \ - dev_printf((dev) , format , ## arg) -#define dev_info(dev, format, arg...) \ - dev_printf((dev) , format , ## arg) - -#if defined(DEBUG) -#define dev_dbg(dev, format, arg...) \ - dev_printf((dev) , format , ## arg) -#else -#define dev_dbg(dev, format, arg...) \ - ({ if (0) dev_printf((dev), format, ##arg); 0; }) -#endif - struct bus_type { char *name; int (*match)(struct device_d *dev, struct driver_d *drv); diff --git a/include/envfs.h b/include/envfs.h index 3d14fcb9ee..2db55ed6a4 100644 --- a/include/envfs.h +++ b/include/envfs.h @@ -89,5 +89,11 @@ struct envfs_super { #error "__BYTE_ORDER must be __LITTLE_ENDIAN or __BIG_ENDIAN" #endif -#endif /* _ENVFS_H */ +#define ENV_FLAG_NO_OVERWRITE (1 << 0) +int envfs_load(char *filename, char *dirname, unsigned flags); +int envfs_save(char *filename, char *dirname); + +/* defaults to /dev/env0 */ +extern char *default_environment_path; +#endif /* _ENVFS_H */ diff --git a/include/environment.h b/include/environment.h index 096c1697c4..7bdd213a52 100644 --- a/include/environment.h +++ b/include/environment.h @@ -20,8 +20,6 @@ #ifndef _ENVIRONMENT_H_ #define _ENVIRONMENT_H_ - -#ifdef __BAREBOX__ /** * Managment of a environment variable */ @@ -72,29 +70,8 @@ static inline int export(const char *var) int env_pop_context(void); int env_push_context(void); -/* defaults to /dev/env0 */ -extern char *default_environment_path; - int export(const char *); -struct stat; -int file_size_action(const char *, struct stat *, void *, int); -int file_save_action(const char *, struct stat *, void *, int); - -#endif /* __BAREBOX__ */ - -#define ENV_FLAG_NO_OVERWRITE (1 << 0) -int envfs_load(char *filename, char *dirname, unsigned flags); -int envfs_save(char *filename, char *dirname); - -/* This part is used for the host and the target */ -struct action_data { - int fd; - const char *base; - void *writep; -}; -#define PAD4(x) ((x + 3) & ~3) - #endif /* _ENVIRONMENT_H_ */ /** diff --git a/include/filetype.h b/include/filetype.h index 91139dbfe3..4d43757b8c 100644 --- a/include/filetype.h +++ b/include/filetype.h @@ -30,7 +30,7 @@ enum filetype { const char *file_type_to_string(enum filetype f); const char *file_type_to_short_string(enum filetype f); -enum filetype file_detect_type(void *_buf, size_t bufsize); +enum filetype file_detect_type(const void *_buf, size_t bufsize); enum filetype file_name_detect_type(const char *filename); enum filetype is_fat_or_mbr(const unsigned char *sector, unsigned long *bootsec); @@ -50,4 +50,25 @@ static inline int is_barebox_arm_head(const char *head) } #endif +#define MIPS_HEAD_SIZE 0x20 +#define MIPS_HEAD_MAGICWORD_OFFSET 0x10 +#define MIPS_HEAD_SIZE_OFFSET 0x1C + +#ifdef CONFIG_MIPS +static inline int is_barebox_mips_head(const char *head) +{ + return !strcmp(head + MIPS_HEAD_MAGICWORD_OFFSET, "barebox"); +} +#else +static inline int is_barebox_mips_head(const char *head) +{ + return 0; +} +#endif + +static inline int is_barebox_head(const char *head) +{ + return is_barebox_arm_head(head) || is_barebox_mips_head(head); +} + #endif /* __FILE_TYPE_H */ diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index be8ad71df4..cb8b3bcaef 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -265,7 +265,7 @@ int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs); #define MTD_DEBUG(n, args...) \ do { \ if (n <= CONFIG_MTD_DEBUG_VERBOSE) \ - printk(KERN_INFO args); \ + pr_info( args); \ } while(0) #else /* CONFIG_MTD_DEBUG */ #define MTD_DEBUG(n, args...) do { } while(0) diff --git a/include/math.h b/include/math.h new file mode 100644 index 0000000000..5648e3f9c1 --- /dev/null +++ b/include/math.h @@ -0,0 +1,92 @@ +/* math.h - interface to shell math "library" -- this allows shells to share + * the implementation of arithmetic $((...)) expansions. + * + * This aims to be a POSIX shell math library as documented here: + * http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04 + * + * See math.c for internal documentation. + */ + +/* The math library has just one function: + * + * arith_t arith(arith_state_t *state, const char *expr); + * + * The expr argument is the math string to parse. All normal expansions must + * be done already. i.e. no dollar symbols should be present. + * + * The state argument is a pointer to a struct of hooks for your shell (see below), + * and an error message string (NULL if no error). + * + * The function returns the answer to the expression. So if you called it + * with the expression: + * "1 + 2 + 3" + * you would obviously get back 6. + */ + +/* To add support to a shell, you need to implement three functions: + * + * lookupvar() - look up and return the value of a variable + * + * If the shell does: + * foo=123 + * Then the code: + * const char *val = lookupvar("foo"); + * will result in val pointing to "123" + * + * setvar() - set a variable to some value + * + * If the arithmetic expansion does something like: + * $(( i = 1)) + * then the math code will make a call like so: + * setvar("i", "1", 0); + * The storage for the first two parameters are not allocated, so your + * shell implementation will most likely need to strdup() them to save. + * + * endofname() - return the end of a variable name from input + * + * The arithmetic code does not know about variable naming conventions. + * So when it is given an experession, it knows something is not numeric, + * but it is up to the shell to dictate what is a valid identifiers. + * So when it encounters something like: + * $(( some_var + 123 )) + * It will make a call like so: + * end = endofname("some_var + 123"); + * So the shell needs to scan the input string and return a pointer to the + * first non-identifier string. In this case, it should return the input + * pointer with an offset pointing to the first space. The typical + * implementation will return the offset of first char that does not match + * the regex (in C locale): ^[a-zA-Z_][a-zA-Z_0-9]* + */ + +#ifndef LIB_MATH_H +#define LIB_MATH_H 1 + +#ifdef ENABLE_SH_MATH_SUPPORT_64 +typedef long long arith_t; +#define ARITH_FMT "%lld" +#define strto_arith_t simple_strtoull +#else +typedef long arith_t; +#define ARITH_FMT "%ld" +#define strto_arith_t simple_strtoul +#endif + +# define is_name(c) (isalpha((unsigned char)(c))) +# define is_in_name(c) ((c) == '_' || (c) == '.' || isalnum((unsigned char)(c))) +const char* arith_endofname(const char *name); + +typedef const char* (*arith_var_lookup_t)(const char *name); +typedef void (*arith_var_set_t)(const char *name, const char *val); +typedef const char* (*arith_var_endofname_t)(const char *name); + +typedef struct arith_state_t { + const char *errmsg; + arith_var_lookup_t lookupvar; + arith_var_set_t setvar; + arith_var_endofname_t endofname; + void *list_of_recursed_names; +} arith_state_t; + +arith_t arith(arith_state_t *state, const char *expr); + +#endif diff --git a/include/mci.h b/include/mci.h index 0041e2714f..cf9582dbe3 100644 --- a/include/mci.h +++ b/include/mci.h @@ -300,6 +300,10 @@ struct mci_host { void (*set_ios)(struct mci_host*, struct mci_ios *); /** handle a command */ int (*send_cmd)(struct mci_host*, struct mci_cmd*, struct mci_data*); + /** check if a card is inserted */ + int (*card_present)(struct mci_host *); + /** check if a card is write protected */ + int (*card_write_protected)(struct mci_host *); }; /** MMC/SD and interface instance information */ diff --git a/include/printk.h b/include/printk.h new file mode 100644 index 0000000000..1d45616f54 --- /dev/null +++ b/include/printk.h @@ -0,0 +1,72 @@ +#ifndef __PRINTK_H +#define __PRINTK_H + +#define MSG_EMERG 0 /* system is unusable */ +#define MSG_ALERT 1 /* action must be taken immediately */ +#define MSG_CRIT 2 /* critical conditions */ +#define MSG_ERR 3 /* error conditions */ +#define MSG_WARNING 4 /* warning conditions */ +#define MSG_NOTICE 5 /* normal but significant condition */ +#define MSG_INFO 6 /* informational */ +#define MSG_DEBUG 7 /* debug-level messages */ + +#ifdef DEBUG +#define LOGLEVEL MSG_DEBUG +#else +#define LOGLEVEL CONFIG_COMPILE_LOGLEVEL +#endif + +/* debugging and troubleshooting/diagnostic helpers. */ + +int dev_printf(const struct device_d *dev, const char *format, ...) + __attribute__ ((format(__printf__, 2, 3))); + +#define __dev_printf(level, dev, format, args...) \ + ({ \ + int ret = 0; \ + if (level <= LOGLEVEL) \ + ret = dev_printf(dev, format, ##args); \ + ret; \ + }) + + +#define dev_emerg(dev, format, arg...) \ + __dev_printf(0, (dev) , format , ## arg) +#define dev_alert(dev, format, arg...) \ + __dev_printf(1, (dev) , format , ## arg) +#define dev_crit(dev, format, arg...) \ + __dev_printf(2, (dev) , format , ## arg) +#define dev_err(dev, format, arg...) \ + __dev_printf(3, (dev) , format , ## arg) +#define dev_warn(dev, format, arg...) \ + __dev_printf(4, (dev) , format , ## arg) +#define dev_notice(dev, format, arg...) \ + __dev_printf(5, (dev) , format , ## arg) +#define dev_info(dev, format, arg...) \ + __dev_printf(6, (dev) , format , ## arg) +#define dev_dbg(dev, format, arg...) \ + __dev_printf(7, (dev) , format , ## arg) + +#define __pr_printk(level, format, args...) \ + ({ \ + int ret = 0; \ + if (level <= LOGLEVEL) \ + ret = printk(format, ##args); \ + ret; \ + }) + +#ifndef pr_fmt +#define pr_fmt(fmt) fmt +#endif + +#define pr_emerg(fmt, arg...) __pr_printk(0, pr_fmt(fmt), ##arg) +#define pr_alert(fmt, arg...) __pr_printk(1, pr_fmt(fmt), ##arg) +#define pr_crit(fmt, arg...) __pr_printk(2, pr_fmt(fmt), ##arg) +#define pr_warning(fmt, arg...) __pr_printk(3, pr_fmt(fmt), ##arg) +#define pr_err(fmt, arg...) __pr_printk(4, pr_fmt(fmt), ##arg) +#define pr_notice(fmt, arg...) __pr_printk(5, pr_fmt(fmt), ##arg) +#define pr_info(fmt, arg...) __pr_printk(6, pr_fmt(fmt), ##arg) +#define pr_debug(fmt, arg...) __pr_printk(7, pr_fmt(fmt), ##arg) +#define debug(fmt, arg...) __pr_printk(7, pr_fmt(fmt), ##arg) + +#endif diff --git a/include/spi/spi.h b/include/spi/spi.h index d6570a402c..fa76e9b59f 100644 --- a/include/spi/spi.h +++ b/include/spi/spi.h @@ -342,6 +342,8 @@ spi_transfer_del(struct spi_transfer *t) int spi_sync(struct spi_device *spi, struct spi_message *message); +struct spi_device *spi_new_device(struct spi_master *master, + struct spi_board_info *chip); int spi_register_master(struct spi_master *master); #ifdef CONFIG_SPI diff --git a/include/video/atmel_lcdc.h b/include/video/atmel_lcdc.h new file mode 100644 index 0000000000..132ee598a5 --- /dev/null +++ b/include/video/atmel_lcdc.h @@ -0,0 +1,206 @@ +/* + * Header file for AT91/AT32 LCD Controller + * + * Data structure and register user interface + * + * Copyright (C) 2007 Atmel Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ATMEL_LCDC_H__ +#define __ATMEL_LCDC_H__ + +/* Way LCD wires are connected to the chip: + * Some Atmel chips use BGR color mode (instead of standard RGB) + * A swapped wiring onboard can bring to RGB mode. + */ +#define ATMEL_LCDC_WIRING_BGR 0 +#define ATMEL_LCDC_WIRING_RGB 1 +#define ATMEL_LCDC_WIRING_RGB555 2 + + + /* LCD Controller info data structure, stored in device platform_data */ +struct atmel_lcdfb_platform_data { + unsigned int guard_time; + unsigned int smem_len; + + bool lcdcon_is_backlight; + bool lcdcon_pol_negative; + u8 saved_lcdcon; + + u8 default_bpp; + u8 lcd_wiring_mode; + unsigned int default_lcdcon2; + unsigned int default_dmacon; + void (*atmel_lcdfb_power_control)(int on); + struct fb_videomode *mode_list; + unsigned num_modes; + + bool have_intensity_bit; +}; + +#define ATMEL_LCDC_DMABADDR1 0x00 +#define ATMEL_LCDC_DMABADDR2 0x04 +#define ATMEL_LCDC_DMAFRMPT1 0x08 +#define ATMEL_LCDC_DMAFRMPT2 0x0c +#define ATMEL_LCDC_DMAFRMADD1 0x10 +#define ATMEL_LCDC_DMAFRMADD2 0x14 + +#define ATMEL_LCDC_DMAFRMCFG 0x18 +#define ATMEL_LCDC_FRSIZE (0x7fffff << 0) +#define ATMEL_LCDC_BLENGTH_OFFSET 24 +#define ATMEL_LCDC_BLENGTH (0x7f << ATMEL_LCDC_BLENGTH_OFFSET) + +#define ATMEL_LCDC_DMACON 0x1c +#define ATMEL_LCDC_DMAEN (0x1 << 0) +#define ATMEL_LCDC_DMARST (0x1 << 1) +#define ATMEL_LCDC_DMABUSY (0x1 << 2) +#define ATMEL_LCDC_DMAUPDT (0x1 << 3) +#define ATMEL_LCDC_DMA2DEN (0x1 << 4) + +#define ATMEL_LCDC_DMA2DCFG 0x20 +#define ATMEL_LCDC_ADDRINC_OFFSET 0 +#define ATMEL_LCDC_ADDRINC (0xffff) +#define ATMEL_LCDC_PIXELOFF_OFFSET 24 +#define ATMEL_LCDC_PIXELOFF (0x1f << 24) + +#define ATMEL_LCDC_LCDCON1 0x0800 +#define ATMEL_LCDC_BYPASS (1 << 0) +#define ATMEL_LCDC_CLKVAL_OFFSET 12 +#define ATMEL_LCDC_CLKVAL (0x1ff << ATMEL_LCDC_CLKVAL_OFFSET) +#define ATMEL_LCDC_LINCNT (0x7ff << 21) + +#define ATMEL_LCDC_LCDCON2 0x0804 +#define ATMEL_LCDC_DISTYPE (3 << 0) +#define ATMEL_LCDC_DISTYPE_STNMONO (0 << 0) +#define ATMEL_LCDC_DISTYPE_STNCOLOR (1 << 0) +#define ATMEL_LCDC_DISTYPE_TFT (2 << 0) +#define ATMEL_LCDC_SCANMOD (1 << 2) +#define ATMEL_LCDC_SCANMOD_SINGLE (0 << 2) +#define ATMEL_LCDC_SCANMOD_DUAL (1 << 2) +#define ATMEL_LCDC_IFWIDTH (3 << 3) +#define ATMEL_LCDC_IFWIDTH_4 (0 << 3) +#define ATMEL_LCDC_IFWIDTH_8 (1 << 3) +#define ATMEL_LCDC_IFWIDTH_16 (2 << 3) +#define ATMEL_LCDC_PIXELSIZE (7 << 5) +#define ATMEL_LCDC_PIXELSIZE_1 (0 << 5) +#define ATMEL_LCDC_PIXELSIZE_2 (1 << 5) +#define ATMEL_LCDC_PIXELSIZE_4 (2 << 5) +#define ATMEL_LCDC_PIXELSIZE_8 (3 << 5) +#define ATMEL_LCDC_PIXELSIZE_16 (4 << 5) +#define ATMEL_LCDC_PIXELSIZE_24 (5 << 5) +#define ATMEL_LCDC_PIXELSIZE_32 (6 << 5) +#define ATMEL_LCDC_INVVD (1 << 8) +#define ATMEL_LCDC_INVVD_NORMAL (0 << 8) +#define ATMEL_LCDC_INVVD_INVERTED (1 << 8) +#define ATMEL_LCDC_INVFRAME (1 << 9 ) +#define ATMEL_LCDC_INVFRAME_NORMAL (0 << 9) +#define ATMEL_LCDC_INVFRAME_INVERTED (1 << 9) +#define ATMEL_LCDC_INVLINE (1 << 10) +#define ATMEL_LCDC_INVLINE_NORMAL (0 << 10) +#define ATMEL_LCDC_INVLINE_INVERTED (1 << 10) +#define ATMEL_LCDC_INVCLK (1 << 11) +#define ATMEL_LCDC_INVCLK_NORMAL (0 << 11) +#define ATMEL_LCDC_INVCLK_INVERTED (1 << 11) +#define ATMEL_LCDC_INVDVAL (1 << 12) +#define ATMEL_LCDC_INVDVAL_NORMAL (0 << 12) +#define ATMEL_LCDC_INVDVAL_INVERTED (1 << 12) +#define ATMEL_LCDC_CLKMOD (1 << 15) +#define ATMEL_LCDC_CLKMOD_ACTIVEDISPLAY (0 << 15) +#define ATMEL_LCDC_CLKMOD_ALWAYSACTIVE (1 << 15) +#define ATMEL_LCDC_MEMOR (1 << 31) +#define ATMEL_LCDC_MEMOR_BIG (0 << 31) +#define ATMEL_LCDC_MEMOR_LITTLE (1 << 31) + +#define ATMEL_LCDC_TIM1 0x0808 +#define ATMEL_LCDC_VFP (0xffU << 0) +#define ATMEL_LCDC_VBP_OFFSET 8 +#define ATMEL_LCDC_VBP (0xffU << ATMEL_LCDC_VBP_OFFSET) +#define ATMEL_LCDC_VPW_OFFSET 16 +#define ATMEL_LCDC_VPW (0x3fU << ATMEL_LCDC_VPW_OFFSET) +#define ATMEL_LCDC_VHDLY_OFFSET 24 +#define ATMEL_LCDC_VHDLY (0xfU << ATMEL_LCDC_VHDLY_OFFSET) + +#define ATMEL_LCDC_TIM2 0x080c +#define ATMEL_LCDC_HBP (0xffU << 0) +#define ATMEL_LCDC_HPW_OFFSET 8 +#define ATMEL_LCDC_HPW (0x3fU << ATMEL_LCDC_HPW_OFFSET) +#define ATMEL_LCDC_HFP_OFFSET 21 +#define ATMEL_LCDC_HFP (0x7ffU << ATMEL_LCDC_HFP_OFFSET) + +#define ATMEL_LCDC_LCDFRMCFG 0x0810 +#define ATMEL_LCDC_LINEVAL (0x7ff << 0) +#define ATMEL_LCDC_HOZVAL_OFFSET 21 +#define ATMEL_LCDC_HOZVAL (0x7ff << ATMEL_LCDC_HOZVAL_OFFSET) + +#define ATMEL_LCDC_FIFO 0x0814 +#define ATMEL_LCDC_FIFOTH (0xffff) + +#define ATMEL_LCDC_MVAL 0x0818 + +#define ATMEL_LCDC_DP1_2 0x081c +#define ATMEL_LCDC_DP4_7 0x0820 +#define ATMEL_LCDC_DP3_5 0x0824 +#define ATMEL_LCDC_DP2_3 0x0828 +#define ATMEL_LCDC_DP5_7 0x082c +#define ATMEL_LCDC_DP3_4 0x0830 +#define ATMEL_LCDC_DP4_5 0x0834 +#define ATMEL_LCDC_DP6_7 0x0838 +#define ATMEL_LCDC_DP1_2_VAL (0xff) +#define ATMEL_LCDC_DP4_7_VAL (0xfffffff) +#define ATMEL_LCDC_DP3_5_VAL (0xfffff) +#define ATMEL_LCDC_DP2_3_VAL (0xfff) +#define ATMEL_LCDC_DP5_7_VAL (0xfffffff) +#define ATMEL_LCDC_DP3_4_VAL (0xffff) +#define ATMEL_LCDC_DP4_5_VAL (0xfffff) +#define ATMEL_LCDC_DP6_7_VAL (0xfffffff) + +#define ATMEL_LCDC_PWRCON 0x083c +#define ATMEL_LCDC_PWR (1 << 0) +#define ATMEL_LCDC_GUARDT_OFFSET 1 +#define ATMEL_LCDC_GUARDT (0x7f << ATMEL_LCDC_GUARDT_OFFSET) +#define ATMEL_LCDC_BUSY (1 << 31) + +#define ATMEL_LCDC_CONTRAST_CTR 0x0840 +#define ATMEL_LCDC_PS (3 << 0) +#define ATMEL_LCDC_PS_DIV1 (0 << 0) +#define ATMEL_LCDC_PS_DIV2 (1 << 0) +#define ATMEL_LCDC_PS_DIV4 (2 << 0) +#define ATMEL_LCDC_PS_DIV8 (3 << 0) +#define ATMEL_LCDC_POL (1 << 2) +#define ATMEL_LCDC_POL_NEGATIVE (0 << 2) +#define ATMEL_LCDC_POL_POSITIVE (1 << 2) +#define ATMEL_LCDC_ENA (1 << 3) +#define ATMEL_LCDC_ENA_PWMDISABLE (0 << 3) +#define ATMEL_LCDC_ENA_PWMENABLE (1 << 3) + +#define ATMEL_LCDC_CONTRAST_VAL 0x0844 +#define ATMEL_LCDC_CVAL (0xff) + +#define ATMEL_LCDC_IER 0x0848 +#define ATMEL_LCDC_IDR 0x084c +#define ATMEL_LCDC_IMR 0x0850 +#define ATMEL_LCDC_ISR 0x0854 +#define ATMEL_LCDC_ICR 0x0858 +#define ATMEL_LCDC_LNI (1 << 0) +#define ATMEL_LCDC_LSTLNI (1 << 1) +#define ATMEL_LCDC_EOFI (1 << 2) +#define ATMEL_LCDC_UFLWI (1 << 4) +#define ATMEL_LCDC_OWRI (1 << 5) +#define ATMEL_LCDC_MERI (1 << 6) + +#define ATMEL_LCDC_LUT(n) (0x0c00 + ((n)*4)) + +#endif /* __ATMEL_LCDC_H__ */ diff --git a/lib/Kconfig b/lib/Kconfig index db8a6ad7a2..457835316b 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -52,4 +52,6 @@ config LIBMTD source lib/gui/Kconfig +source lib/bootstrap/Kconfig + endmenu diff --git a/lib/Makefile b/lib/Makefile index 85f4ec97b6..3c94542153 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,3 +1,4 @@ +obj-$(CONFIG_BOOTSTRAP) += bootstrap/ obj-y += ctype.o obj-y += rbtree.o obj-y += display_options.o @@ -15,6 +16,7 @@ obj-y += libgen.o obj-y += stringlist.o obj-y += recursive_action.o obj-y += make_directory.o +obj-y += math.o obj-$(CONFIG_BZLIB) += decompress_bunzip2.o obj-$(CONFIG_ZLIB) += decompress_inflate.o zlib_inflate/ obj-$(CONFIG_CMDLINE_EDITING) += readline.o diff --git a/lib/bootstrap/Kconfig b/lib/bootstrap/Kconfig new file mode 100644 index 0000000000..558da00c7b --- /dev/null +++ b/lib/bootstrap/Kconfig @@ -0,0 +1,13 @@ +menuconfig BOOTSTRAP + bool "Library bootstrap routines " + depends on SHELL_NONE + +if BOOTSTRAP + +config BOOTSTRAP_DEVFS + bool "devfs support" + +config BOOTSTRAP_DISK + bool "disk support" + +endif diff --git a/lib/bootstrap/Makefile b/lib/bootstrap/Makefile new file mode 100644 index 0000000000..cbaa49f9d9 --- /dev/null +++ b/lib/bootstrap/Makefile @@ -0,0 +1,3 @@ +obj-y += common.o +obj-$(CONFIG_BOOTSTRAP_DEVFS) += devfs.o +obj-$(CONFIG_BOOTSTRAP_DISK) += disk.o diff --git a/lib/bootstrap/common.c b/lib/bootstrap/common.c new file mode 100644 index 0000000000..38ec272129 --- /dev/null +++ b/lib/bootstrap/common.c @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2011 Sascha Hauer, Pengutronix + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <bootstrap.h> +#include <filetype.h> + +void bootstrap_boot(int (*func)(void), bool barebox) +{ + if (!func) + return; + + if (barebox && !is_barebox_head((void*)func)) + return; + + shutdown_barebox(); + func(); + + while (1); +} diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c new file mode 100644 index 0000000000..25d07c761c --- /dev/null +++ b/lib/bootstrap/devfs.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2011 Sascha Hauer, Pengutronix + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <partition.h> +#include <nand.h> +#include <driver.h> +#include <linux/mtd/mtd.h> +#include <fcntl.h> +#include <filetype.h> +#include <sizes.h> +#include <errno.h> +#include <malloc.h> +#include <bootstrap.h> + +#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) +#if defined(CONFIG_ARM) +#define BAREBOX_HEAD_SIZE ARM_HEAD_SIZE +#define BAREBOX_HEAD_SIZE_OFFSET ARM_HEAD_SIZE_OFFSET +#elif defined(CONFIG_MIPS) +#define BAREBOX_HEAD_SIZE MIPS_HEAD_SIZE +#define BAREBOX_HEAD_SIZE_OFFSET MIPS_HEAD_SIZE_OFFSET +#endif + +static void *read_image_head(const char *name) +{ + void *header = xmalloc(BAREBOX_HEAD_SIZE); + struct cdev *cdev; + int ret; + + cdev = cdev_open(name, O_RDONLY); + if (!cdev) { + bootstrap_err("failed to open partition\n"); + return NULL; + } + + ret = cdev_read(cdev, header, BAREBOX_HEAD_SIZE, 0, 0); + cdev_close(cdev); + + if (ret != BAREBOX_HEAD_SIZE) { + bootstrap_err("failed to read from partition\n"); + return NULL; + } + + return header; +} + +static unsigned int get_image_size(void *head) +{ + unsigned int ret = 0; + unsigned int *psize = head + BAREBOX_HEAD_SIZE_OFFSET; + + if (is_barebox_head(head)) + ret = *psize; + debug("Detected barebox image size %u\n", ret); + + return ret; +} +#else +static void *read_image_head(const char *name) +{ + return NULL; +} + +static unsigned int get_image_size(void *head) +{ + return 0; +} +#endif + +void* bootstrap_read_devfs(char *devname, bool use_bb, int offset, + int default_size, int max_size) +{ + int ret; + int size = 0; + void *to, *header; + struct cdev *cdev; + char *partname = "x"; + + devfs_add_partition(devname, offset, max_size, DEVFS_PARTITION_FIXED, partname); + if (use_bb) { + dev_add_bb_dev(partname, "bbx"); + partname = "bbx"; + } + + header = read_image_head(partname); + if (header) { + size = get_image_size(header); + if (!size) + bootstrap_err("%s: failed to get image size\n", devname); + } + + if (!size) { + size = default_size; + bootstrap_err("%s: failed to detect barebox and it's image size so use %d\n", + devname, size); + } + + to = xmalloc(size); + + cdev = cdev_open(partname, O_RDONLY); + if (!cdev) { + bootstrap_err("%s: failed to open %s\n", devname, partname); + return NULL; + } + + ret = cdev_read(cdev, to, size, 0, 0); + if (ret != size) { + bootstrap_err("%s: failed to read from %s\n", devname, partname); + return NULL; + } + + return to; +} diff --git a/lib/bootstrap/disk.c b/lib/bootstrap/disk.c new file mode 100644 index 0000000000..879d3315e8 --- /dev/null +++ b/lib/bootstrap/disk.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2011 Sascha Hauer, Pengutronix + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <fs.h> +#include <fcntl.h> +#include <sizes.h> +#include <errno.h> +#include <malloc.h> +#include <bootstrap.h> + +void* bootstrap_read_disk(char *dev, char *fstype) +{ + int ret; + void *buf; + int len; + char *path = "/"; + + ret = mount(dev, fstype, path); + if (ret) { + bootstrap_err("mounting %s failed with %d\n", dev, ret); + return NULL; + } + + buf = read_file("/barebox.bin", &len); + if (!buf) { + bootstrap_err("could not read barebox.bin from %s\n", dev); + umount(path); + return NULL; + } + + return buf; +} diff --git a/lib/gui/bmp.c b/lib/gui/bmp.c index fce0e69b77..6bf8cd000f 100644 --- a/lib/gui/bmp.c +++ b/lib/gui/bmp.c @@ -24,7 +24,7 @@ struct image *bmp_open(char *inbuf, int insize) img->bits_per_pixel = le16_to_cpu(bmp->header.bit_count); pr_debug("bmp: %d x %d x %d data@0x%p\n", img->width, img->height, - img->bit_per_pixel, img->data); + img->bits_per_pixel, img->data); return img; } diff --git a/lib/gui/graphic_utils.c b/lib/gui/graphic_utils.c index 3800ee2832..95687df13e 100644 --- a/lib/gui/graphic_utils.c +++ b/lib/gui/graphic_utils.c @@ -219,7 +219,7 @@ int fb_open(const char * fbdev, struct screen *sc, bool offscreen) sc->s.y = 0; sc->s.width = sc->info.xres; sc->s.height = sc->info.yres; - sc->fbsize = sc->s.x * sc->s.x * (sc->info.bits_per_pixel >> 3); + sc->fbsize = sc->s.width * sc->s.height * (sc->info.bits_per_pixel >> 3); if (offscreen) { /* Don't fail if malloc fails, just continue rendering directly diff --git a/lib/math.c b/lib/math.c new file mode 100644 index 0000000000..5a68f5e8b2 --- /dev/null +++ b/lib/math.c @@ -0,0 +1,795 @@ +/* + * Arithmetic code ripped out of ash shell for code sharing. + * + * This code is derived from software contributed to Berkeley by + * Kenneth Almquist. + * + * Original BSD copyright notice is retained at the end of this file. + * + * Copyright (c) 1989, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au> + * was re-ported from NetBSD and debianized. + * + * rewrite arith.y to micro stack based cryptic algorithm by + * Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com> + * + * Modified by Paul Mundt <lethal@linux-sh.org> (c) 2004 to support + * dynamic variables. + * + * Modified by Vladimir Oleynik <dzo@simtreas.ru> (c) 2001-2005 to be + * used in busybox and size optimizations, + * rewrote arith (see notes to this), added locale support, + * rewrote dynamic variables. + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ +/* Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* This is my infix parser/evaluator. It is optimized for size, intended + * as a replacement for yacc-based parsers. However, it may well be faster + * than a comparable parser written in yacc. The supported operators are + * listed in #defines below. Parens, order of operations, and error handling + * are supported. This code is thread safe. The exact expression format should + * be that which POSIX specifies for shells. + * + * The code uses a simple two-stack algorithm. See + * http://www.onthenet.com.au/~grahamis/int2008/week02/lect02.html + * for a detailed explanation of the infix-to-postfix algorithm on which + * this is based (this code differs in that it applies operators immediately + * to the stack instead of adding them to a queue to end up with an + * expression). + */ + +/* + * Aug 24, 2001 Manuel Novoa III + * + * Reduced the generated code size by about 30% (i386) and fixed several bugs. + * + * 1) In arith_apply(): + * a) Cached values of *numptr and &(numptr[-1]). + * b) Removed redundant test for zero denominator. + * + * 2) In arith(): + * a) Eliminated redundant code for processing operator tokens by moving + * to a table-based implementation. Also folded handling of parens + * into the table. + * b) Combined all 3 loops which called arith_apply to reduce generated + * code size at the cost of speed. + * + * 3) The following expressions were treated as valid by the original code: + * 1() , 0! , 1 ( *3 ) . + * These bugs have been fixed by internally enclosing the expression in + * parens and then checking that all binary ops and right parens are + * preceded by a valid expression (NUM_TOKEN). + * + * Note: It may be desirable to replace Aaron's test for whitespace with + * ctype's isspace() if it is used by another busybox applet or if additional + * whitespace chars should be considered. Look below the "#include"s for a + * precompiler test. + */ +/* + * Aug 26, 2001 Manuel Novoa III + * + * Return 0 for null expressions. Pointed out by Vladimir Oleynik. + * + * Merge in Aaron's comments previously posted to the busybox list, + * modified slightly to take account of my changes to the code. + * + */ +/* + * (C) 2003 Vladimir Oleynik <dzo@simtreas.ru> + * + * - allow access to variable, + * use recursive value indirection: c="2*2"; a="c"; echo $((a+=2)) produce 6 + * - implement assign syntax (VAR=expr, +=, *= etc) + * - implement exponentiation (** operator) + * - implement comma separated - expr, expr + * - implement ++expr --expr expr++ expr-- + * - implement expr ? expr : expr (but second expr is always calculated) + * - allow hexadecimal and octal numbers + * - restore lost XOR operator + * - protect $((num num)) as true zero expr (Manuel's error) + * - always use special isspace(), see comment from bash ;-) + */ +#include <common.h> +#include <malloc.h> +#include <linux/ctype.h> +#include <linux/string.h> +#include <libbb.h> +#include <math.h> + +#define lookupvar (math_state->lookupvar) +#define setvar (math_state->setvar ) +#define endofname (math_state->endofname) + +typedef unsigned char operator; + +/* An operator's token id is a bit of a bitfield. The lower 5 bits are the + * precedence, and 3 high bits are an ID unique across operators of that + * precedence. The ID portion is so that multiple operators can have the + * same precedence, ensuring that the leftmost one is evaluated first. + * Consider * and / + */ +#define tok_decl(prec,id) (((id)<<5) | (prec)) +#define PREC(op) ((op) & 0x1F) + +#define TOK_LPAREN tok_decl(0,0) + +#define TOK_COMMA tok_decl(1,0) + +/* All assignments are right associative and have the same precedence, + * but there are 11 of them, which doesn't fit into 3 bits for unique id. + * Abusing another precedence level: + */ +#define TOK_ASSIGN tok_decl(2,0) +#define TOK_AND_ASSIGN tok_decl(2,1) +#define TOK_OR_ASSIGN tok_decl(2,2) +#define TOK_XOR_ASSIGN tok_decl(2,3) +#define TOK_PLUS_ASSIGN tok_decl(2,4) +#define TOK_MINUS_ASSIGN tok_decl(2,5) +#define TOK_LSHIFT_ASSIGN tok_decl(2,6) +#define TOK_RSHIFT_ASSIGN tok_decl(2,7) + +#define TOK_MUL_ASSIGN tok_decl(3,0) +#define TOK_DIV_ASSIGN tok_decl(3,1) +#define TOK_REM_ASSIGN tok_decl(3,2) + +#define fix_assignment_prec(prec) do { if (prec == 3) prec = 2; } while (0) + +/* Ternary conditional operator is right associative too */ +#define TOK_CONDITIONAL tok_decl(4,0) +#define TOK_CONDITIONAL_SEP tok_decl(4,1) + +#define TOK_OR tok_decl(5,0) + +#define TOK_AND tok_decl(6,0) + +#define TOK_BOR tok_decl(7,0) + +#define TOK_BXOR tok_decl(8,0) + +#define TOK_BAND tok_decl(9,0) + +#define TOK_EQ tok_decl(10,0) +#define TOK_NE tok_decl(10,1) + +#define TOK_LT tok_decl(11,0) +#define TOK_GT tok_decl(11,1) +#define TOK_GE tok_decl(11,2) +#define TOK_LE tok_decl(11,3) + +#define TOK_LSHIFT tok_decl(12,0) +#define TOK_RSHIFT tok_decl(12,1) + +#define TOK_ADD tok_decl(13,0) +#define TOK_SUB tok_decl(13,1) + +#define TOK_MUL tok_decl(14,0) +#define TOK_DIV tok_decl(14,1) +#define TOK_REM tok_decl(14,2) + +/* Exponent is right associative */ +#define TOK_EXPONENT tok_decl(15,1) + +/* Unary operators */ +#define UNARYPREC 16 +#define TOK_BNOT tok_decl(UNARYPREC,0) +#define TOK_NOT tok_decl(UNARYPREC,1) + +#define TOK_UMINUS tok_decl(UNARYPREC+1,0) +#define TOK_UPLUS tok_decl(UNARYPREC+1,1) + +#define PREC_PRE (UNARYPREC+2) + +#define TOK_PRE_INC tok_decl(PREC_PRE, 0) +#define TOK_PRE_DEC tok_decl(PREC_PRE, 1) + +#define PREC_POST (UNARYPREC+3) + +#define TOK_POST_INC tok_decl(PREC_POST, 0) +#define TOK_POST_DEC tok_decl(PREC_POST, 1) + +#define SPEC_PREC (UNARYPREC+4) + +#define TOK_NUM tok_decl(SPEC_PREC, 0) +#define TOK_RPAREN tok_decl(SPEC_PREC, 1) + +/* from busybox's libbb/skip_whitespace.c */ +static char *skip_whitespace(const char *s) +{ + /* In POSIX/C locale (the only locale we care about: do we REALLY want + * to allow Unicode whitespace in, say, .conf files? nuts!) + * isspace is only these chars: "\t\n\v\f\r" and space. + * "\t\n\v\f\r" happen to have ASCII codes 9,10,11,12,13. + * Use that. + */ + while (*s == ' ' || (unsigned char)(*s - 9) <= (13 - 9)) + s++; + + return (char *) s; +} + +static int is_assign_op(operator op) +{ + operator prec = PREC(op); + fix_assignment_prec(prec); + + return prec == PREC(TOK_ASSIGN) + || prec == PREC_PRE + || prec == PREC_POST; +} + +static int is_right_associative(operator prec) +{ + return prec == PREC(TOK_ASSIGN) + || prec == PREC(TOK_EXPONENT) + || prec == PREC(TOK_CONDITIONAL); +} + +typedef struct { + arith_t val; + /* We acquire second_val only when "expr1 : expr2" part + * of ternary ?: op is evaluated. + * We treat ?: as two binary ops: (expr ? (expr1 : expr2)). + * ':' produces a new value which has two parts, val and second_val; + * then '?' selects one of them based on its left side. + */ + arith_t second_val; + char second_val_present; + /* If NULL then it's just a number, else it's a named variable */ + char *var; +} var_or_num_t; + +typedef struct remembered_name { + struct remembered_name *next; + const char *var; +} remembered_name; + + +static arith_t evaluate_string(arith_state_t *math_state, const char *expr); + +static const char *arith_lookup_val(arith_state_t *math_state, var_or_num_t *t) +{ + if (t->var) { + const char *p = lookupvar(t->var); + if (p) { + remembered_name *cur; + remembered_name cur_save; + + /* did we already see this name? + * testcase: a=b; b=a; echo $((a)) + */ + for (cur = math_state->list_of_recursed_names; cur; cur = cur->next) { + if (strcmp(cur->var, t->var) == 0) { + /* Yes */ + return "expression recursion loop detected"; + } + } + + /* push current var name */ + cur = math_state->list_of_recursed_names; + cur_save.var = t->var; + cur_save.next = cur; + math_state->list_of_recursed_names = &cur_save; + + /* recursively evaluate p as expression */ + t->val = evaluate_string(math_state, p); + + /* pop current var name */ + math_state->list_of_recursed_names = cur; + + return math_state->errmsg; + } + /* treat undefined var as 0 */ + t->val = 0; + } + return 0; +} + +/* "Applying" a token means performing it on the top elements on the integer + * stack. For an unary operator it will only change the top element, but a + * binary operator will pop two arguments and push the result */ +static const char* noinline arith_apply(arith_state_t *math_state, operator op, + var_or_num_t *numstack, var_or_num_t **numstackptr) +{ +#define NUMPTR (*numstackptr) + + var_or_num_t *top_of_stack; + arith_t rez; + const char *err; + + /* There is no operator that can work without arguments */ + if (NUMPTR == numstack) + goto err; + + top_of_stack = NUMPTR - 1; + + /* Resolve name to value, if needed */ + err = arith_lookup_val(math_state, top_of_stack); + if (err) + return err; + + rez = top_of_stack->val; + if (op == TOK_UMINUS) + rez = -rez; + else if (op == TOK_NOT) + rez = !rez; + else if (op == TOK_BNOT) + rez = ~rez; + else if (op == TOK_POST_INC || op == TOK_PRE_INC) + rez++; + else if (op == TOK_POST_DEC || op == TOK_PRE_DEC) + rez--; + else if (op != TOK_UPLUS) { + /* Binary operators */ + arith_t right_side_val; + char bad_second_val; + + /* Binary operators need two arguments */ + if (top_of_stack == numstack) + goto err; + /* ...and they pop one */ + NUMPTR = top_of_stack; /* this decrements NUMPTR */ + + bad_second_val = top_of_stack->second_val_present; + if (op == TOK_CONDITIONAL) { /* ? operation */ + /* Make next if (...) protect against + * $((expr1 ? expr2)) - that is, missing ": expr" */ + bad_second_val = !bad_second_val; + } + if (bad_second_val) { + /* Protect against $((expr <not_?_op> expr1 : expr2)) */ + return "malformed ?: operator"; + } + + top_of_stack--; /* now points to left side */ + + if (op != TOK_ASSIGN) { + /* Resolve left side value (unless the op is '=') */ + err = arith_lookup_val(math_state, top_of_stack); + if (err) + return err; + } + + right_side_val = rez; + rez = top_of_stack->val; + if (op == TOK_CONDITIONAL) /* ? operation */ + rez = (rez ? right_side_val : top_of_stack[1].second_val); + else if (op == TOK_CONDITIONAL_SEP) { /* : operation */ + if (top_of_stack == numstack) { + /* Protect against $((expr : expr)) */ + return "malformed ?: operator"; + } + top_of_stack->second_val_present = op; + top_of_stack->second_val = right_side_val; + } + else if (op == TOK_BOR || op == TOK_OR_ASSIGN) + rez |= right_side_val; + else if (op == TOK_OR) + rez = right_side_val || rez; + else if (op == TOK_BAND || op == TOK_AND_ASSIGN) + rez &= right_side_val; + else if (op == TOK_BXOR || op == TOK_XOR_ASSIGN) + rez ^= right_side_val; + else if (op == TOK_AND) + rez = rez && right_side_val; + else if (op == TOK_EQ) + rez = (rez == right_side_val); + else if (op == TOK_NE) + rez = (rez != right_side_val); + else if (op == TOK_GE) + rez = (rez >= right_side_val); + else if (op == TOK_RSHIFT || op == TOK_RSHIFT_ASSIGN) + rez >>= right_side_val; + else if (op == TOK_LSHIFT || op == TOK_LSHIFT_ASSIGN) + rez <<= right_side_val; + else if (op == TOK_GT) + rez = (rez > right_side_val); + else if (op == TOK_LT) + rez = (rez < right_side_val); + else if (op == TOK_LE) + rez = (rez <= right_side_val); + else if (op == TOK_MUL || op == TOK_MUL_ASSIGN) + rez *= right_side_val; + else if (op == TOK_ADD || op == TOK_PLUS_ASSIGN) + rez += right_side_val; + else if (op == TOK_SUB || op == TOK_MINUS_ASSIGN) + rez -= right_side_val; + else if (op == TOK_ASSIGN || op == TOK_COMMA) + rez = right_side_val; + else if (op == TOK_EXPONENT) { + arith_t c; + if (right_side_val < 0) + return "exponent less than 0"; + c = 1; + while (--right_side_val >= 0) + c *= rez; + rez = c; + } + else if (right_side_val == 0) + return "divide by zero"; + else if (op == TOK_DIV || op == TOK_DIV_ASSIGN) + rez /= right_side_val; + else if (op == TOK_REM || op == TOK_REM_ASSIGN) + rez %= right_side_val; + } + + if (is_assign_op(op)) { + char buf[sizeof(arith_t)*3 + 2]; + + if (top_of_stack->var == NULL) { + /* Hmm, 1=2 ? */ + + /* + * TODO: actually, bash allows ++7 but for some + * reason it evals to 7, not 8 + */ + goto err; + } + /* Save to shell variable */ + sprintf(buf, ARITH_FMT, rez); + setvar(top_of_stack->var, buf); + /* After saving, make previous value for v++ or v-- */ + if (op == TOK_POST_INC) + rez--; + else if (op == TOK_POST_DEC) + rez++; + } + + top_of_stack->val = rez; + /* Erase var name, it is just a number now */ + free(top_of_stack->var); + top_of_stack->var = NULL; + return NULL; + err: + return "arithmetic syntax error"; +#undef NUMPTR +} + +/* longest must be first */ +static const char op_tokens[] __attribute__((aligned(1))) = { + '<','<','=',0, TOK_LSHIFT_ASSIGN, + '>','>','=',0, TOK_RSHIFT_ASSIGN, + '<','<', 0, TOK_LSHIFT, + '>','>', 0, TOK_RSHIFT, + '|','|', 0, TOK_OR, + '&','&', 0, TOK_AND, + '!','=', 0, TOK_NE, + '<','=', 0, TOK_LE, + '>','=', 0, TOK_GE, + '=','=', 0, TOK_EQ, + '|','=', 0, TOK_OR_ASSIGN, + '&','=', 0, TOK_AND_ASSIGN, + '*','=', 0, TOK_MUL_ASSIGN, + '/','=', 0, TOK_DIV_ASSIGN, + '%','=', 0, TOK_REM_ASSIGN, + '+','=', 0, TOK_PLUS_ASSIGN, + '-','=', 0, TOK_MINUS_ASSIGN, + '-','-', 0, TOK_POST_DEC, + '^','=', 0, TOK_XOR_ASSIGN, + '+','+', 0, TOK_POST_INC, + '*','*', 0, TOK_EXPONENT, + '!', 0, TOK_NOT, + '<', 0, TOK_LT, + '>', 0, TOK_GT, + '=', 0, TOK_ASSIGN, + '|', 0, TOK_BOR, + '&', 0, TOK_BAND, + '*', 0, TOK_MUL, + '/', 0, TOK_DIV, + '%', 0, TOK_REM, + '+', 0, TOK_ADD, + '-', 0, TOK_SUB, + '^', 0, TOK_BXOR, + /* uniq */ + '~', 0, TOK_BNOT, + ',', 0, TOK_COMMA, + '?', 0, TOK_CONDITIONAL, + ':', 0, TOK_CONDITIONAL_SEP, + ')', 0, TOK_RPAREN, + '(', 0, TOK_LPAREN, + 0 +}; +#define ptr_to_rparen (&op_tokens[sizeof(op_tokens)-7]) + +const char *arith_endofname(const char *name) +{ + if (!is_name(*name)) + return name; + while (*++name) { + if (!is_in_name(*name)) + break; + } + return name; +} + +static arith_t evaluate_string(arith_state_t *math_state, const char *expr) +{ + operator lasttok; + const char *errmsg; + const char *start_expr = expr = skip_whitespace(expr); + unsigned expr_len = strlen(expr) + 2; + /* Stack of integers */ + /* + * The proof that there can be no more than strlen(startbuf)/2+1 + * integers in any given correct or incorrect expression + * is left as an exercise to the reader. + */ + var_or_num_t *const numstack = xzalloc((expr_len / 2) * sizeof(numstack[0])); + var_or_num_t *numstackptr = numstack; + /* Stack of operator tokens */ + operator *const stack = xzalloc(expr_len * sizeof(stack[0])); + operator *stackptr = stack; + arith_t result; + + if (numstack == NULL || stack == NULL) { + errmsg = "out of memory"; + goto err_with_custom_msg; + } + + /* Start with a left paren */ + *stackptr++ = lasttok = TOK_LPAREN; + errmsg = NULL; + + while (1) { + const char *p; + operator op; + operator prec; + char arithval; + + expr = skip_whitespace(expr); + arithval = *expr; + if (arithval == '\0') { + if (expr == start_expr) { + /* Null expression */ + numstack->val = 0; + goto ret; + } + + /* + * This is only reached after all tokens have been extracted from the + * input stream. If there are still tokens on the operator stack, they + * are to be applied in order. At the end, there should be a final + * result on the integer stack + */ + + if (expr != ptr_to_rparen + 1) { + /* + * If we haven't done so already, + * append a closing right paren + * and let the loop process it + */ + expr = ptr_to_rparen; + continue; + } + /* At this point, we're done with the expression */ + if (numstackptr != numstack + 1) { + /* ...but if there isn't, it's bad */ + goto err; + } + if (numstack->var) { + /* expression is $((var)) only, lookup now */ + errmsg = arith_lookup_val(math_state, numstack); + free(numstack->var); + numstack->var = NULL; + } + goto ret; + } + + p = endofname(expr); + if (p != expr) { + /* Name */ + size_t var_name_size = (p-expr) + 1; /* +1 for NUL */ + free(numstackptr->var); + numstackptr->var = xzalloc(var_name_size); + safe_strncpy(numstackptr->var, expr, var_name_size); + expr = p; + num: + numstackptr->second_val_present = 0; + numstackptr++; + lasttok = TOK_NUM; + continue; + } + + if (isdigit(arithval)) { + /* Number */ + free(numstackptr->var); + numstackptr->var = NULL; + errno = 0; + numstackptr->val = strto_arith_t(expr, (char**) &expr, 0); + if (errno) + numstackptr->val = 0; /* bash compat */ + goto num; + } + + /* Should be an operator */ + p = op_tokens; + while (1) { + /* + * TODO: bash allows 7+++v, treats it as 7 + ++v + * we treat it as 7++ + v and reject + */ + /* Compare expr to current op_tokens[] element */ + const char *e = expr; + while (1) { + if (*p == '\0') { + /* Match: operator is found */ + expr = e; + goto tok_found; + } + if (*p != *e) + break; + p++; + e++; + } + /* No match, go to next element of op_tokens[] */ + while (*p) + p++; + p += 2; /* skip NUL and TOK_foo bytes */ + if (*p == '\0') { + /* No next element, operator not found */ + //math_state->syntax_error_at = expr; + goto err; + } + } + tok_found: + op = p[1]; /* fetch TOK_foo value */ + /* NB: expr now points past the operator */ + + /* post grammar: a++ reduce to num */ + if (lasttok == TOK_POST_INC || lasttok == TOK_POST_DEC) + lasttok = TOK_NUM; + + /* + * Plus and minus are binary (not unary) _only_ if the last + * token was a number, or a right paren (which pretends to be + * a number, since it evaluates to one). Think about it. + * It makes sense. + */ + if (lasttok != TOK_NUM) { + switch (op) { + case TOK_ADD: + op = TOK_UPLUS; + break; + case TOK_SUB: + op = TOK_UMINUS; + break; + case TOK_POST_INC: + op = TOK_PRE_INC; + break; + case TOK_POST_DEC: + op = TOK_PRE_DEC; + break; + } + } + /* + * We don't want an unary operator to cause recursive descent on the + * stack, because there can be many in a row and it could cause an + * operator to be evaluated before its argument is pushed onto the + * integer stack. + * But for binary operators, "apply" everything on the operator + * stack until we find an operator with a lesser priority than the + * one we have just extracted. If op is right-associative, + * then stop "applying" on the equal priority too. + * Left paren is given the lowest priority so it will never be + * "applied" in this way. + */ + prec = PREC(op); + if ((prec > 0 && prec < UNARYPREC) || prec == SPEC_PREC) { + /* not left paren or unary */ + if (lasttok != TOK_NUM) { + /* binary op must be preceded by a num */ + goto err; + } + while (stackptr != stack) { + operator prev_op = *--stackptr; + if (op == TOK_RPAREN) { + /* + * The algorithm employed here is simple: while we don't + * hit an open paren nor the bottom of the stack, pop + * tokens and apply them + */ + if (prev_op == TOK_LPAREN) { + /* + * Any operator directly after a + * close paren should consider itself binary + */ + lasttok = TOK_NUM; + goto next; + } + } else { + operator prev_prec = PREC(prev_op); + fix_assignment_prec(prec); + fix_assignment_prec(prev_prec); + if (prev_prec < prec + || (prev_prec == prec && is_right_associative(prec)) + ) { + stackptr++; + break; + } + } + errmsg = arith_apply(math_state, prev_op, numstack, &numstackptr); + if (errmsg) + goto err_with_custom_msg; + } + if (op == TOK_RPAREN) + goto err; + } + + /* Push this operator to the stack and remember it */ + *stackptr++ = lasttok = op; +next: ; + } /* while (1) */ + +err: + errmsg = "arithmetic syntax error"; +err_with_custom_msg: + result = -1; +ret: + result = numstack->val; + free(stack); + free(numstack); + math_state->errmsg = errmsg; + return result; +} + +arith_t arith(arith_state_t *math_state, const char *expr) +{ + math_state->errmsg = NULL; + math_state->list_of_recursed_names = NULL; + return evaluate_string(math_state, expr); +} + +/* + * Copyright (c) 1989, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Kenneth Almquist. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ diff --git a/lib/xfuncs.c b/lib/xfuncs.c index 4649280329..db85720195 100644 --- a/lib/xfuncs.c +++ b/lib/xfuncs.c @@ -30,7 +30,7 @@ void *xmalloc(size_t size) if (!(p = malloc(size))) panic("ERROR: out of memory\n"); - debug("xmalloc %p (size %d)\n", p, size); + debug("xmalloc %p (size %zu)\n", p, size); return p; } @@ -43,7 +43,7 @@ void *xrealloc(void *ptr, size_t size) if (!(p = realloc(ptr, size))) panic("ERROR: out of memory\n"); - debug("xrealloc %p -> %p (size %d)\n", ptr, p, size); + debug("xrealloc %p -> %p (size %zu)\n", ptr, p, size); return p; } diff --git a/pbl/misc.c b/pbl/misc.c index a2cb44deac..9065bf0855 100644 --- a/pbl/misc.c +++ b/pbl/misc.c @@ -14,6 +14,8 @@ void __noreturn panic(const char *fmt, ...) while(1); } -void start_barebox(void) +void __noreturn start_barebox(void) { + /* Should never be here in the pbl */ + hang(); } diff --git a/pbl/string.c b/pbl/string.c index 6787e82c9b..b773f5cf7c 100644 --- a/pbl/string.c +++ b/pbl/string.c @@ -5,6 +5,7 @@ */ #include <linux/types.h> +#include <linux/string.h> void *memcpy(void *__dest, __const void *__src, size_t __n) { @@ -103,7 +104,7 @@ void *memchr(const void *s, int c, size_t count) return NULL; } -char *strchr(const char *s, int c) +char *_strchr(const char *s, int c) { while (*s != (char)c) if (*s++ == '\0') @@ -111,8 +112,6 @@ char *strchr(const char *s, int c) return (char *)s; } -#undef memset - void *memset(void *s, int c, size_t count) { char *xs = s; @@ -120,8 +119,3 @@ void *memset(void *s, int c, size_t count) *xs++ = c; return s; } - -void __memzero(void *s, size_t count) -{ - memset(s, 0, count); -} diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 14e471d17c..f7d672160c 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -248,3 +248,14 @@ cmd_disasm = $(OBJDUMP) -d $< > $@ quiet_cmd_ln = LN $@ cmd_ln = ln -sf $< $@ + +# Check size of a file +quiet_cmd_check_file_size = CHKSIZE $@ + cmd_check_file_size = set -e; \ + size=`stat -c%s $@`; \ + max_size=`printf "%d" $2`; \ + if [ $$size -gt $$max_size ] ; \ + then \ + echo "$@ size $$size > of the maximum size $$max_size" >&2; \ + exit 1 ; \ + fi; diff --git a/scripts/bareboxenv.c b/scripts/bareboxenv.c index 707d63dd81..9284c0b083 100644 --- a/scripts/bareboxenv.c +++ b/scripts/bareboxenv.c @@ -118,7 +118,6 @@ char *concat_subpath_file(const char *path, const char *f) #include "../include/envfs.h" #include "../crypto/crc32.c" #include "../lib/make_directory.c" -#include "../include/environment.h" #include "../common/environment.c" void usage(char *prgname) |