diff options
408 files changed, 11898 insertions, 2964 deletions
diff --git a/.gitignore b/.gitignore index 9af6710290..064753d211 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ barebox.spi barebox.ubl barebox.uimage barebox.map +barebox-flash-image System.map Module.symvers barebox_default_env* @@ -1,5 +1,5 @@ VERSION = 2012 -PATCHLEVEL = 10 +PATCHLEVEL = 11 SUBLEVEL = 0 EXTRAVERSION = NAME = Amissive Actinocutious Kiwi @@ -136,6 +136,9 @@ ifeq ($(skip-makefile),) PHONY += all _all: all +# CDPATH can have sideeffects; disable, since we do know where we want to cd to +export CDPATH= + srctree := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR)) objtree := $(CURDIR) src := $(srctree) @@ -475,7 +478,7 @@ export KBUILD_BINARY ?= barebox.bin # Also any assignments in arch/$(ARCH)/Makefile take precedence over # the default value. -barebox-flash-image: $(KBUILD_IMAGE) +barebox-flash-image: $(KBUILD_IMAGE) FORCE $(call if_changed,ln) all: barebox-flash-image diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8278c82e3a..3afd88514f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -31,6 +31,20 @@ config ARCH_AT91 select HAS_DEBUG_LL select HAVE_MACH_ARM_HEAD +config ARCH_BCM2835 + bool "Broadcom BCM2835 boards" + select GPIOLIB + select CPU_ARM1176 + select CLKDEV_LOOKUP + select COMMON_CLK + select CLOCKSOURCE_BCM2835 + select ARM_AMBA + +config ARCH_CLPS711X + bool "Cirrus Logic EP711x/EP721x/EP731x" + select CLKDEV_LOOKUP + select CPU_32v4T + config ARCH_EP93XX bool "Cirrus Logic EP93xx" select CPU_ARM920T @@ -42,6 +56,7 @@ config ARCH_IMX select GPIOLIB select COMMON_CLK select CLKDEV_LOOKUP + select WATCHDOG_IMX_RESET_SOURCE config ARCH_MXS bool "Freescale i.MX23/28 (mxs) based" @@ -54,6 +69,7 @@ config ARCH_NETX config ARCH_NOMADIK bool "STMicroelectronics Nomadik" select CPU_ARM926T + select CLOCKSOURCE_NOMADIK help Support for the Nomadik platform by ST-Ericsson @@ -71,14 +87,12 @@ config ARCH_S3C24xx select ARCH_SAMSUNG select CPU_ARM920T select GENERIC_GPIO -# -# Currently no board support -# -#config ARCH_S5PCxx -# bool "Samsung S5PC110, S5PV210" -# select ARCH_SAMSUNG -# select CPU_V7 -# select GENERIC_GPIO + +config ARCH_S5PCxx + bool "Samsung S5PC110, S5PV210" + select ARCH_SAMSUNG + select CPU_V7 + select GENERIC_GPIO config ARCH_S3C64xx bool "Samsung S3C64xx" @@ -89,6 +103,7 @@ config ARCH_S3C64xx config ARCH_VERSATILE bool "ARM Versatile boards (ARM926EJ-S)" select CPU_ARM926T + select GPIOLIB config ARCH_TEGRA bool "Nvidia Tegra-based boards" @@ -99,6 +114,8 @@ endchoice source arch/arm/cpu/Kconfig source arch/arm/mach-at91/Kconfig +source arch/arm/mach-bcm2835/Kconfig +source arch/arm/mach-clps711x/Kconfig source arch/arm/mach-ep93xx/Kconfig source arch/arm/mach-imx/Kconfig source arch/arm/mach-mxs/Kconfig @@ -123,6 +140,7 @@ config AEABI config THUMB2_BAREBOX select ARM_ASM_UNIFIED + select AEABI depends on CPU_V7 bool "Compile barebox in thumb-2 mode (read help)" help diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 855043aedf..4b630ab4cb 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -52,6 +52,8 @@ AFLAGS += -include asm/unified.h -msoft-float $(AFLAGS_THUMB2) # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. machine-$(CONFIG_ARCH_AT91) := at91 +machine-$(CONFIG_ARCH_BCM2835) := bcm2835 +machine-$(CONFIG_ARCH_CLPS711X) := clps711x machine-$(CONFIG_ARCH_EP93XX) := ep93xx machine-$(CONFIG_ARCH_IMX) := imx machine-$(CONFIG_ARCH_MXS) := mxs @@ -75,6 +77,7 @@ board-$(CONFIG_MACH_AT91SAM9G10EK) := at91sam9261ek board-$(CONFIG_MACH_AT91SAM9G20EK) := at91sam9260ek board-$(CONFIG_MACH_AT91SAM9X5EK) := at91sam9x5ek board-$(CONFIG_MACH_AT91SAM9M10G45EK) := at91sam9m10g45ek +board-$(CONFIG_MACH_CLEP7212) := clep7212 board-$(CONFIG_MACH_DSS11) := dss11 board-$(CONFIG_MACH_EDB9301) := edb93xx board-$(CONFIG_MACH_EDB9302) := edb93xx @@ -112,6 +115,7 @@ board-$(CONFIG_MACH_PCM043) := pcm043 board-$(CONFIG_MACH_PM9261) := pm9261 board-$(CONFIG_MACH_PM9263) := pm9263 board-$(CONFIG_MACH_PM9G45) := pm9g45 +board-$(CONFIG_MACH_RPI) := raspberry-pi board-$(CONFIG_MACH_SCB9328) := scb9328 board-$(CONFIG_MACH_NESO) := guf-neso board-$(CONFIG_MACH_MX23EVK) := freescale-mx23-evk diff --git a/arch/arm/boards/a9m2440/lowlevel_init.S b/arch/arm/boards/a9m2440/lowlevel_init.S index da29efdc21..8f6cfcbe68 100644 --- a/arch/arm/boards/a9m2440/lowlevel_init.S +++ b/arch/arm/boards/a9m2440/lowlevel_init.S @@ -225,7 +225,7 @@ reset: cmp pc, #S3C_SDRAM_END bhs 1f - mov pc, r10 + b board_init_lowlevel_return /* we are running from NOR or NAND/SRAM memory. Do further initialisation */ 1: diff --git a/arch/arm/boards/at91rm9200ek/env/config b/arch/arm/boards/at91rm9200ek/env/config index a3830cb31a..76c180bcac 100644 --- a/arch/arm/boards/at91rm9200ek/env/config +++ b/arch/arm/boards/at91rm9200ek/env/config @@ -15,6 +15,8 @@ global.dhcp.vendor_id=barebox-at91rm9200ek kernel_loc=nfs # can be either 'net', 'nor' or 'initrd' rootfs_loc=net +# can be either 'nfs', 'tftp', or empty +oftree_loc=nfs # can be either 'jffs2' or 'ubifs' rootfs_type=ubifs diff --git a/arch/arm/boards/at91sam9260ek/Makefile b/arch/arm/boards/at91sam9260ek/Makefile index 73ef72e210..eb072c0161 100644 --- a/arch/arm/boards/at91sam9260ek/Makefile +++ b/arch/arm/boards/at91sam9260ek/Makefile @@ -1,2 +1 @@ -obj-y += lowlevel_init.o obj-y += init.o diff --git a/arch/arm/boards/at91sam9x5ek/Makefile b/arch/arm/boards/at91sam9x5ek/Makefile index eb072c0161..f2acf201b4 100644 --- a/arch/arm/boards/at91sam9x5ek/Makefile +++ b/arch/arm/boards/at91sam9x5ek/Makefile @@ -1 +1,2 @@ obj-y += init.o +obj-y += hw_version.o diff --git a/arch/arm/boards/at91sam9x5ek/env/config b/arch/arm/boards/at91sam9x5ek/env/config index 6a985cedc5..b8cf4e3f30 100644 --- a/arch/arm/boards/at91sam9x5ek/env/config +++ b/arch/arm/boards/at91sam9x5ek/env/config @@ -4,6 +4,7 @@ # use 'none' if you want to skip kernel ip autoconfiguration ip=dhcp-barebox global.dhcp.vendor_id=barebox-at91sam9x5ek +global.dhcp.client_id="${at91sam9x5cm.board}-${at91sam9x5cm.vendor}" # or set your networking parameters here #eth0.ipaddr=a.b.c.d @@ -21,6 +22,7 @@ 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 @@ -29,7 +31,7 @@ kernelimage=zImage #kernelimage=Image.lzo nand_device=atmel_nand -nand_parts="128k(at91bootstrap),256k(barebox)ro,128k(bareboxenv),128k(bareboxenv2),128k(oftree),1M(free),4M(kernel),120M(rootfs),-(data)" +nand_parts="256k(at91bootstrap),384k(barebox)ro,128k(bareboxenv),128k(bareboxenv2),128k(oftree),1M(free),6M(kernel),120M(rootfs),-(data)" rootfs_mtdblock_nand=7 autoboot_timeout=3 diff --git a/arch/arm/boards/at91sam9x5ek/hw_version.c b/arch/arm/boards/at91sam9x5ek/hw_version.c new file mode 100644 index 0000000000..47c640a35f --- /dev/null +++ b/arch/arm/boards/at91sam9x5ek/hw_version.c @@ -0,0 +1,272 @@ +/* + * 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_EK, + BOARD_TYPE_DM, + BOARD_TYPE_CPU, +}; + +static struct board_info { + char *name; + enum board_type type; + unsigned char id; +} board_list[] = { + {"SAM9x5-EK", BOARD_TYPE_EK, 0}, + {"SAM9x5-DM", BOARD_TYPE_DM, 1}, + {"SAM9G15-CM", BOARD_TYPE_CPU, 2}, + {"SAM9G25-CM", BOARD_TYPE_CPU, 3}, + {"SAM9G35-CM", BOARD_TYPE_CPU, 4}, + {"SAM9X25-CM", BOARD_TYPE_CPU, 5}, + {"SAM9X35-CM", BOARD_TYPE_CPU, 6}, + {"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++) + 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[] = { + {"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++) + 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 at91sam9x5ek_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 at91sam9x5ek_cm_is_vendor(enum vendor_id vid) +{ + return ((sn >> 5) & 0x1f) == vid; +} + +bool at91sam9x5ek_ek_is_vendor(enum vendor_id vid) +{ + return ((sn >> 15) & 0x1f) == vid; +} + +bool at91sam9x5ek_dm_is_vendor(enum vendor_id vid) +{ + return ((sn >> 25) & 0x1f) == vid; +} + +static void at91sam9x5ek_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 (at91sam9x5ek_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("at91sam9x5cm", 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_EK: + dev = add_generic_device_res("at91sam9x5ek", 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("EK"); + break; + case BOARD_TYPE_DM: + dev = add_generic_device_res("at91sam9x5dm", DEVICE_ID_SINGLE, NULL, 0, NULL); + if (!dev) + return; + sn |= ((binfo->id & 0x1f) << 10); + sn |= ((vendor_id & 0x1f) << 15); + rev |= ((info.revision_code - 'A') << 5); + rev |= (((info.revision_id - '0') & 0x3) << 18); + pr_info("DM"); + 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); +} + +#define NODE_NAME_LEN 128 + +static int cm_cogent_fixup(struct fdt_header *fdt) +{ + int off, ret; + char node_name[NODE_NAME_LEN]; + + off = fdt_node_offset_by_compatible(fdt, -1, "atmel,hsmci"); + + while (off != -FDT_ERR_NOTFOUND) { + off = fdt_subnode_offset(fdt, off, "slot"); + fdt_get_path(fdt, off, node_name, NODE_NAME_LEN); + ret = fdt_setprop(fdt, off, "broken-cd", NULL, 0); + if (ret < 0) { + pr_err("error %d while adding broken-cd property to node %s\n", + ret, node_name); + return ret; + } else { + pr_debug("add broken-cd property to node %s\n", node_name); + } + + off = fdt_node_offset_by_compatible(fdt, off, "atmel,hsmci"); + } + + return 0; +} + +void at91sam9x5ek_devices_detect_hw(void) +{ + at91sam9x5ek_devices_detect_one("/dev/ds24310"); + at91sam9x5ek_devices_detect_one("/dev/ds24311"); + at91sam9x5ek_devices_detect_one("/dev/ds24330"); + + pr_info("sn: 0x%x, rev: 0x%x\n", sn, rev); + armlinux_set_revision(rev); + armlinux_set_serial(sn); + + if (at91sam9x5ek_cm_is_vendor(VENDOR_COGENT)) + of_register_fixup(cm_cogent_fixup); +} diff --git a/arch/arm/boards/at91sam9x5ek/hw_version.h b/arch/arm/boards/at91sam9x5ek/hw_version.h new file mode 100644 index 0000000000..91fd42942d --- /dev/null +++ b/arch/arm/boards/at91sam9x5ek/hw_version.h @@ -0,0 +1,34 @@ +/* + * 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, +}; + +bool at91sam9x5ek_cm_is_vendor(enum vendor_id vid); +bool at91sam9x5ek_ek_is_vendor(enum vendor_id vid); +bool at91sam9x5ek_dm_is_vendor(enum vendor_id vid); +void at91sam9x5ek_devices_detect_hw(void); + +#endif /* __HW_REVISION_H__ */ diff --git a/arch/arm/boards/at91sam9x5ek/init.c b/arch/arm/boards/at91sam9x5ek/init.c index d7dc30def7..2536477316 100644 --- a/arch/arm/boards/at91sam9x5ek/init.c +++ b/arch/arm/boards/at91sam9x5ek/init.c @@ -36,8 +36,19 @@ #include <mach/io.h> #include <mach/at91_pmc.h> #include <mach/at91_rstc.h> -#include <gpio_keys.h> +#include <mach/at91sam9x5_matrix.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_PB18, + .is_open_drain = 0, +}; static struct atmel_nand_data nand_pdata = { .ale = 21, @@ -80,6 +91,14 @@ static void ek_add_device_nand(void) /* configure chip-select 3 (NAND) */ sam9_smc_configure(3, &cm_nand_smc_config); + if (at91sam9x5ek_cm_is_vendor(VENDOR_COGENT)) { + unsigned long csa; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + csa |= AT91_MATRIX_EBI_VDDIOMSEL_1_8V; + at91_sys_write(AT91_MATRIX_EBICSA, csa); + } + at91_add_device_nand(&nand_pdata); } @@ -88,6 +107,88 @@ static struct at91_ether_platform_data macb_pdata = { .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); +} + +/* + * MCI (SD/MMC) + */ +/* mci0 detect_pin is revision dependent */ +static struct atmel_mci_platform_data mci0_data = { + .bus_width = 4, + .detect_pin = AT91_PIN_PD15, + .wp_pin = 0, +}; + +static void ek_add_device_mci(void) +{ + if (at91sam9x5ek_cm_is_vendor(VENDOR_COGENT)) + mci0_data.detect_pin = 0; + + /* MMC0 */ + at91_add_device_mci(0, &mci0_data); +} + +struct qt1070_platform_data qt1070_pdata = { + .irq_pin = AT91_PIN_PA7, +}; + +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_cm_cogent_spi_devices[] = { + { + .name = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + } +}; + +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_PA14}; +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) +{ + if (at91sam9x5ek_cm_is_vendor(VENDOR_COGENT)) + spi_register_board_info(ek_cm_cogent_spi_devices, + ARRAY_SIZE(ek_cm_cogent_spi_devices)); + else + spi_register_board_info(ek_spi_devices, + ARRAY_SIZE(ek_spi_devices)); + at91_add_device_spi(0, &spi_pdata); +} + /* * USB Host port */ @@ -130,12 +231,25 @@ static int at91sam9x5ek_mem_init(void) } mem_initcall(at91sam9x5ek_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); + + at91sam9x5ek_devices_detect_hw(); +} + static int at91sam9x5ek_devices_init(void) { + ek_add_device_w1(); ek_add_device_nand(); - at91_add_device_eth(0, &macb_pdata); + ek_add_device_eth(); + ek_add_device_spi(); + ek_add_device_mci(); at91_add_device_usbh_ohci(&ek_usbh_data); ek_add_led(); + ek_add_device_i2c(); armlinux_set_bootparams((void *)(AT91_CHIPSELECT_1 + 0x100)); armlinux_set_architecture(CONFIG_MACH_AT91SAM9X5EK); @@ -157,7 +271,6 @@ static int at91sam9x5ek_console_init(void) { at91_register_uart(0, 0); at91_register_uart(1, 0); - at91_register_uart(2, 0); return 0; } console_initcall(at91sam9x5ek_console_init); diff --git a/arch/arm/boards/ccxmx51/ccxmx51.c b/arch/arm/boards/ccxmx51/ccxmx51.c index 0b450d64e7..a8d172c0ff 100644 --- a/arch/arm/boards/ccxmx51/ccxmx51.c +++ b/arch/arm/boards/ccxmx51/ccxmx51.c @@ -23,7 +23,7 @@ #include <net.h> #include <init.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx51-regs.h> #include <fec.h> #include <mach/gpio.h> #include <asm/armlinux.h> @@ -45,6 +45,7 @@ #include <mach/iim.h> #include <mach/clock-imx51_53.h> #include <mach/imx5.h> +#include <mach/revision.h> #include "ccxmx51.h" diff --git a/arch/arm/boards/ccxmx51/ccxmx51js.c b/arch/arm/boards/ccxmx51/ccxmx51js.c index f04615d888..c947a1ee97 100644 --- a/arch/arm/boards/ccxmx51/ccxmx51js.c +++ b/arch/arm/boards/ccxmx51/ccxmx51js.c @@ -20,7 +20,7 @@ #include <init.h> #include <mci.h> #include <asm/armlinux.h> -#include <mach/imx-regs.h> +#include <mach/imx51-regs.h> #include <mach/iomux-mx51.h> #include <mach/devices-imx51.h> #include <generated/mach-types.h> diff --git a/arch/arm/boards/clep7212/Makefile b/arch/arm/boards/clep7212/Makefile new file mode 100644 index 0000000000..a63aeaef39 --- /dev/null +++ b/arch/arm/boards/clep7212/Makefile @@ -0,0 +1,2 @@ +obj-y += lowlevel.o clep7212.o +pbl-y += lowlevel.o diff --git a/arch/arm/boards/clep7212/clep7212.c b/arch/arm/boards/clep7212/clep7212.c new file mode 100644 index 0000000000..a32337fafe --- /dev/null +++ b/arch/arm/boards/clep7212/clep7212.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> + * + * 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 <driver.h> +#include <init.h> +#include <partition.h> +#include <io.h> +#include <sizes.h> +#include <asm/armlinux.h> +#include <generated/mach-types.h> + +#include <mach/clps711x.h> +#include <mach/devices.h> + +static int clps711x_mem_init(void) +{ + ulong memsize = get_ram_size((ulong *)SDRAM0_BASE, SZ_32M); + + arm_add_mem_device("ram0", SDRAM0_BASE, memsize); + + return 0; +} +mem_initcall(clps711x_mem_init); + +static int clps711x_devices_init(void) +{ + u32 serial_h = 0, serial_l = readl(UNIQID); + + /* Setup Chipselects */ + clps711x_setup_memcfg(0, MEMCFG_WAITSTATE_6_1 | MEMCFG_BUS_WIDTH_16); + clps711x_setup_memcfg(1, MEMCFG_WAITSTATE_6_1 | MEMCFG_BUS_WIDTH_8); + clps711x_setup_memcfg(2, MEMCFG_WAITSTATE_8_3 | MEMCFG_BUS_WIDTH_16 | + MEMCFG_CLKENB); + clps711x_setup_memcfg(3, MEMCFG_WAITSTATE_6_1 | MEMCFG_BUS_WIDTH_32); + + add_cfi_flash_device(0, CS0_BASE, SZ_32M, 0); + + devfs_add_partition("nor0", 0x00000, SZ_256K, DEVFS_PARTITION_FIXED, + "self0"); + devfs_add_partition("nor0", SZ_256K, SZ_256K, DEVFS_PARTITION_FIXED, + "env0"); + + armlinux_set_bootparams((void *)SDRAM0_BASE + 0x100); + armlinux_set_architecture(MACH_TYPE_CLEP7212); + armlinux_set_serial(((u64)serial_h << 32) | serial_l); + + return 0; +} +device_initcall(clps711x_devices_init); + +static int clps711x_console_init(void) +{ + clps711x_add_uart(0); + + return 0; +} +console_initcall(clps711x_console_init); diff --git a/arch/arm/boards/clep7212/config.h b/arch/arm/boards/clep7212/config.h new file mode 100644 index 0000000000..6ae9a40e19 --- /dev/null +++ b/arch/arm/boards/clep7212/config.h @@ -0,0 +1,4 @@ +#ifndef __CONFIG_H +#define __CONFIG_H + +#endif /* __CONFIG_H */ diff --git a/arch/arm/boards/clep7212/env/bin/mtdparts-add b/arch/arm/boards/clep7212/env/bin/mtdparts-add new file mode 100644 index 0000000000..ef1bc0215f --- /dev/null +++ b/arch/arm/boards/clep7212/env/bin/mtdparts-add @@ -0,0 +1,21 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + init-menu-add-entry "$0" "Partitions" + exit +fi + +norparts="256k(barebox),256k(bareboxenv),3584k(kernel),-(root)" +ramparts="-(ramdisk)" + +if [ -e /dev/nor0 ]; then + addpart -n /dev/nor0 "${norparts}" + + global linux.mtdparts.nor + global.linux.mtdparts.nor="physmap-flash.0:${norparts}" +else + echo "NOR Flash not found." +fi + +global linux.mtdparts.ram +global.linux.mtdparts.ram="mtd-ram.0:${ramparts}" diff --git a/arch/arm/boards/clep7212/env/boot/nor b/arch/arm/boards/clep7212/env/boot/nor new file mode 100644 index 0000000000..5cf1e15833 --- /dev/null +++ b/arch/arm/boards/clep7212/env/boot/nor @@ -0,0 +1,9 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + boot-menu-add-entry "$0" "NOR Flash" + exit +fi + +global.bootm.image="/dev/kernel" +global.linux.bootargs.dyn.root="root=/dev/mtdblock4 ro" diff --git a/arch/arm/boards/clep7212/env/init/automount b/arch/arm/boards/clep7212/env/init/automount new file mode 100644 index 0000000000..978b96450d --- /dev/null +++ b/arch/arm/boards/clep7212/env/init/automount @@ -0,0 +1,6 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + init-menu-add-entry "$0" "Automountpoints" + exit +fi diff --git a/arch/arm/boards/freescale-mx6-sabrelite/env/init/bootargs-base b/arch/arm/boards/clep7212/env/init/bootargs-base index 2c51febff7..ec08e39181 100644 --- a/arch/arm/boards/freescale-mx6-sabrelite/env/init/bootargs-base +++ b/arch/arm/boards/clep7212/env/init/bootargs-base @@ -5,4 +5,4 @@ if [ "$1" = menu ]; then exit fi -global.linux.bootargs.base="console=ttymxc1,115200" +global.linux.bootargs.base="earlyprintk console=ttyCL0,57600n8" diff --git a/arch/arm/boards/clep7212/env/init/general b/arch/arm/boards/clep7212/env/init/general new file mode 100644 index 0000000000..77e6a59e6b --- /dev/null +++ b/arch/arm/boards/clep7212/env/init/general @@ -0,0 +1,12 @@ +#!/bin/sh + +if [ "$1" = menu ]; then + init-menu-add-entry "$0" "general config settings" + exit +fi + +global.user=barebox +global.autoboot_timeout=2 +global.boot.default=nor + +/env/bin/mtdparts-add diff --git a/arch/arm/boards/pcm038/env/init/hostname b/arch/arm/boards/clep7212/env/init/hostname index 09c2f08c38..684ee63ba5 100644 --- a/arch/arm/boards/pcm038/env/init/hostname +++ b/arch/arm/boards/clep7212/env/init/hostname @@ -5,4 +5,4 @@ if [ "$1" = menu ]; then exit fi -global.hostname=pcm038 +global.hostname=clep7212 diff --git a/arch/arm/boards/clep7212/lowlevel.c b/arch/arm/boards/clep7212/lowlevel.c new file mode 100644 index 0000000000..9b7e2410f3 --- /dev/null +++ b/arch/arm/boards/clep7212/lowlevel.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> + * + * 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 <asm/io.h> +#include <asm/barebox-arm.h> +#include <asm/barebox-arm-head.h> + +#include <mach/clps711x.h> + +#define MAIN_CLOCK 3686400 +#define CPU_SPEED 92160000 +#define BUS_SPEED (CPU_SPEED / 2) + +#define PLL_VALUE (((CPU_SPEED * 2) / MAIN_CLOCK) << 24) +#define SDRAM_REFRESH_RATE (64 * (BUS_SPEED / (8192 * 1000))) + +void __naked __bare_init reset(void) +{ + u32 tmp; + + common_reset(); + + /* Setup base clock */ + writel(SYSCON3_CLKCTL0 | SYSCON3_CLKCTL1, SYSCON3); + asm("nop"); + + /* Setup PLL */ + writel(PLL_VALUE, PLLW); + asm("nop"); + + /* CLKEN select, SDRAM width=32 */ + writel(SYSCON2_CLKENSL, SYSCON2); + + /* Enable SDQM pins */ + tmp = readl(SYSCON3); + tmp &= ~SYSCON3_ENPD67; + writel(tmp, SYSCON3); + + /* Setup Refresh Rate (64ms 8K Blocks) */ + writel(SDRAM_REFRESH_RATE, SDRFPR); + + /* Setup SDRAM (32MB, 16Bit*2, CAS=3) */ + writel(SDCONF_CASLAT_3 | SDCONF_SIZE_256 | SDCONF_WIDTH_16 | + SDCONF_CLKCTL | SDCONF_ACTIVE, SDCONF); + + board_init_lowlevel_return(); +} diff --git a/arch/arm/boards/crystalfontz-cfa10036/env/boot/mmc-ext3 b/arch/arm/boards/crystalfontz-cfa10036/env/boot/mmc-ext3 index 7d7eb50b37..b2325af1aa 100644 --- a/arch/arm/boards/crystalfontz-cfa10036/env/boot/mmc-ext3 +++ b/arch/arm/boards/crystalfontz-cfa10036/env/boot/mmc-ext3 @@ -7,4 +7,4 @@ fi global.bootm.image="/mnt/disk0.1/zImage-cfa10036" global.bootm.oftree="/mnt/disk0.1/oftree-cfa10036" -bootargs-root-ext -r 3 -m mmcblk0p3 +global.linux.bootargs.dyn.root="root=/dev/mmcblk0p3 rootfstype=ext3 rootwait" diff --git a/arch/arm/boards/crystalfontz-cfa10036/env/init/bootargs-base b/arch/arm/boards/crystalfontz-cfa10036/env/init/bootargs-base deleted file mode 100644 index 4dda5501e3..0000000000 --- a/arch/arm/boards/crystalfontz-cfa10036/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=ttyAMA0,115200" diff --git a/arch/arm/boards/crystalfontz-cfa10036/env/init/config-board b/arch/arm/boards/crystalfontz-cfa10036/env/init/config-board new file mode 100644 index 0000000000..b99866ecfe --- /dev/null +++ b/arch/arm/boards/crystalfontz-cfa10036/env/init/config-board @@ -0,0 +1,7 @@ +#!/bin/sh + +# board defaults, do not change in running system. Change /env/config +# instead + +global.hostname=cfa10036 +global.linux.bootargs.base="console=ttyAMA0,115200" diff --git a/arch/arm/boards/crystalfontz-cfa10036/env/init/hostname b/arch/arm/boards/crystalfontz-cfa10036/env/init/hostname deleted file mode 100644 index 1dbe346fdf..0000000000 --- a/arch/arm/boards/crystalfontz-cfa10036/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=cfa10036 diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c index bf3cbc375a..92e8df2b9f 100644 --- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c +++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c @@ -22,7 +22,7 @@ #include <init.h> #include <driver.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx25-regs.h> #include <asm/armlinux.h> #include <asm/barebox-arm.h> #include <asm-generic/sections.h> @@ -250,18 +250,3 @@ void __bare_init nand_boot(void) imx_nand_load_image(_text, barebox_image_size); } #endif - -static int eukrea_cpuimx25_core_init(void) { - /* enable UART1, FEC, SDHC, USB & I2C clock */ - writel(readl(MX25_CCM_BASE_ADDR + CCM_CGCR0) | (1 << 6) | (1 << 23) - | (1 << 15) | (1 << 21) | (1 << 3) | (1 << 28), - MX25_CCM_BASE_ADDR + CCM_CGCR0); - writel(readl(MX25_CCM_BASE_ADDR + CCM_CGCR1) | (1 << 23) | (1 << 15) - | (1 << 13), MX25_CCM_BASE_ADDR + CCM_CGCR1); - writel(readl(MX25_CCM_BASE_ADDR + CCM_CGCR2) | (1 << 14), - MX25_CCM_BASE_ADDR + CCM_CGCR2); - - return 0; -} - -core_initcall(eukrea_cpuimx25_core_init); diff --git a/arch/arm/boards/eukrea_cpuimx25/flash_header.c b/arch/arm/boards/eukrea_cpuimx25/flash_header.c index 344c7ffc13..9102c2a371 100644 --- a/arch/arm/boards/eukrea_cpuimx25/flash_header.c +++ b/arch/arm/boards/eukrea_cpuimx25/flash_header.c @@ -23,7 +23,7 @@ */ #include <common.h> #include <mach/imx-flash-header.h> -#include <mach/imx-regs.h> +#include <mach/imx25-regs.h> #include <asm/barebox-arm-head.h> void __naked __flash_header_start go(void) diff --git a/arch/arm/boards/eukrea_cpuimx25/lowlevel.c b/arch/arm/boards/eukrea_cpuimx25/lowlevel.c index cd80b251be..36ce98bc69 100644 --- a/arch/arm/boards/eukrea_cpuimx25/lowlevel.c +++ b/arch/arm/boards/eukrea_cpuimx25/lowlevel.c @@ -19,7 +19,7 @@ */ #include <common.h> #include <init.h> -#include <mach/imx-regs.h> +#include <mach/imx25-regs.h> #include <mach/imx-pll.h> #include <mach/esdctl.h> #include <io.h> @@ -36,8 +36,7 @@ static void __bare_init __naked insdram(void) uint32_t r; /* setup a stack to be able to call imx_nand_load_image() */ - r = STACK_BASE + STACK_SIZE - 12; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); imx_nand_load_image(_text, barebox_image_size); @@ -57,15 +56,15 @@ void __bare_init __naked reset(void) common_reset(); /* restart the MPLL and wait until it's stable */ - writel(readl(MX25_CCM_BASE_ADDR + CCM_CCTL) | (1 << 27), - MX25_CCM_BASE_ADDR + CCM_CCTL); - while (readl(MX25_CCM_BASE_ADDR + CCM_CCTL) & (1 << 27)) {}; + writel(readl(MX25_CCM_BASE_ADDR + MX25_CCM_CCTL) | (1 << 27), + MX25_CCM_BASE_ADDR + MX25_CCM_CCTL); + while (readl(MX25_CCM_BASE_ADDR + MX25_CCM_CCTL) & (1 << 27)) {}; /* Configure dividers and ARM clock source * ARM @ 400 MHz * AHB @ 133 MHz */ - writel(0x20034000, MX25_CCM_BASE_ADDR + CCM_CCTL); + writel(0x20034000, MX25_CCM_BASE_ADDR + MX25_CCM_CCTL); /* Enable UART1 / FEC / */ /* writel(0x1FFFFFFF, MX25_CCM_BASE_ADDR + CCM_CGCR0); @@ -118,10 +117,10 @@ void __bare_init __naked reset(void) writel(0x1, 0xb8003000); /* Speed up NAND controller by adjusting the NFC divider */ - r = readl(MX25_CCM_BASE_ADDR + CCM_PCDR2); + r = readl(MX25_CCM_BASE_ADDR + MX25_CCM_PCDR2); r &= ~0xf; r |= 0x1; - writel(r, MX25_CCM_BASE_ADDR + CCM_PCDR2); + writel(r, MX25_CCM_BASE_ADDR + MX25_CCM_PCDR2); /* Skip SDRAM initialization if we run from RAM */ r = get_pc(); @@ -129,22 +128,22 @@ void __bare_init __naked reset(void) board_init_lowlevel_return(); /* Init Mobile DDR */ - writel(0x0000000E, ESDMISC); - writel(0x00000004, ESDMISC); + writel(0x0000000E, MX25_ESDCTL_BASE_ADDR + IMX_ESDMISC); + writel(0x00000004, MX25_ESDCTL_BASE_ADDR + IMX_ESDMISC); __asm__ volatile ("1:\n" "subs %0, %1, #1\n" "bne 1b":"=r" (loops):"0" (loops)); - writel(0x0029572B, ESDCFG0); - writel(0x92210000, ESDCTL0); + writel(0x0029572B, MX25_ESDCTL_BASE_ADDR + IMX_ESDCFG0); + writel(0x92210000, MX25_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writeb(0xda, MX25_CSD0_BASE_ADDR + 0x400); - writel(0xA2210000, ESDCTL0); + writel(0xA2210000, MX25_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writeb(0xda, MX25_CSD0_BASE_ADDR); writeb(0xda, MX25_CSD0_BASE_ADDR); - writel(0xB2210000, ESDCTL0); + writel(0xB2210000, MX25_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writeb(0xda, MX25_CSD0_BASE_ADDR + 0x33); writeb(0xda, MX25_CSD0_BASE_ADDR + 0x1000000); - writel(0x82216080, ESDCTL0); + writel(0x82216080, MX25_ESDCTL_BASE_ADDR + IMX_ESDCTL0); #ifdef CONFIG_NAND_IMX_BOOT /* skip NAND boot if not running from NFC space */ diff --git a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c index cff4f77985..c89ce8a192 100644 --- a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c +++ b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c @@ -21,7 +21,7 @@ #include <net.h> #include <init.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> #include <fec.h> #include <notifier.h> #include <mach/gpio.h> @@ -194,7 +194,6 @@ static int eukrea_cpuimx27_devices_init(void) #endif imx27_add_nand(&nand_info); - PCCR0 |= PCCR0_I2C1_EN; i2c_register_board_info(0, i2c_devices, ARRAY_SIZE(i2c_devices)); imx27_add_i2c0(NULL); @@ -223,11 +222,16 @@ device_initcall(eukrea_cpuimx27_devices_init); static int eukrea_cpuimx27_console_init(void) { + uint32_t val; + #ifdef CONFIG_DRIVER_SERIAL_IMX imx27_add_uart0(); #endif /* configure 8 bit UART on cs3 */ - FMCR &= ~0x2; + val = readl(MX27_SYSCTRL_BASE_ADDR + MX27_FMCR); + val &= ~0x2; + writel(val, MX27_SYSCTRL_BASE_ADDR + MX27_FMCR); + imx27_setup_weimcs(3, 0x0000D603, 0x0D1D0D01, 0x00D20000); #ifdef CONFIG_DRIVER_SERIAL_NS16550 add_ns16550_device(DEVICE_ID_DYNAMIC, MX27_CS3_BASE_ADDR + QUART_OFFSET, 0xf, diff --git a/arch/arm/boards/eukrea_cpuimx27/lowlevel_init.S b/arch/arm/boards/eukrea_cpuimx27/lowlevel_init.S index 1983d480f9..4ee6efb84e 100644 --- a/arch/arm/boards/eukrea_cpuimx27/lowlevel_init.S +++ b/arch/arm/boards/eukrea_cpuimx27/lowlevel_init.S @@ -1,6 +1,7 @@ #include <config.h> #include <asm-generic/memory_layout.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> +#include <mach/esdctl.h> #include <asm/barebox-arm-head.h> #define writel(val, reg) \ @@ -9,10 +10,10 @@ str r1, [r0]; #if defined CONFIG_EUKREA_CPUIMX27_SDRAM_256MB -#define ROWS0 ESDCTL_ROW14 +#define ROWS0 ESDCTL0_ROW14 #define CFG0 0x0029572D #elif defined CONFIG_EUKREA_CPUIMX27_SDRAM_128MB -#define ROWS0 ESDCTL_ROW13 +#define ROWS0 ESDCTL0_ROW13 #define CFG0 0x00095728 #endif @@ -22,20 +23,26 @@ /* * DDR on CSD0 */ - writel(0x0000000C, ESDMISC) /* Enable DDR SDRAM operation */ - - writel(0x55555555, DSCR(3)) /* Set the driving strength */ - writel(0x55555555, DSCR(5)) - writel(0x55555555, DSCR(6)) - writel(0x00005005, DSCR(7)) - writel(0x15555555, DSCR(8)) - - writel(0x00000004, ESDMISC) /* Initial reset */ - writel(CFG0, ESDCFG0) - - writel(ESDCTL0_VAL | ESDCTL0_SMODE_PRECHARGE, ESDCTL0) /* precharge CSD0 all banks */ + /* Enable DDR SDRAM operation */ + writel(0x0000000C, MX27_ESDCTL_BASE_ADDR + IMX_ESDMISC) + + /* Set the driving strength */ + writel(0x55555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(3)) + writel(0x55555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(5)) + writel(0x55555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(6)) + writel(0x00005005, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(7)) + writel(0x15555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(8)) + + /* Initial reset */ + writel(0x00000004, MX27_ESDCTL_BASE_ADDR + IMX_ESDMISC) + writel(CFG0, MX27_ESDCTL_BASE_ADDR + IMX_ESDCFG0) + + /* precharge CSD0 all banks */ + writel(ESDCTL0_VAL | ESDCTL0_SMODE_PRECHARGE, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0) writel(0x00000000, 0xA0000F00) /* CSD0 precharge address (A10 = 1) */ - writel(ESDCTL0_VAL | ESDCTL0_SMODE_AUTO_REFRESH, ESDCTL0) + writel(ESDCTL0_VAL | ESDCTL0_SMODE_AUTO_REFRESH, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0) ldr r0, =0xa0000f00 mov r1, #0 @@ -45,7 +52,8 @@ subs r2, #1 bne 1b - writel(ESDCTL0_VAL | ESDCTL0_SMODE_LOAD_MODE, ESDCTL0) + writel(ESDCTL0_VAL | ESDCTL0_SMODE_LOAD_MODE, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0) ldr r0, =0xA0000033 mov r1, #0xda strb r1, [r0] @@ -56,7 +64,9 @@ #endif mov r1, #0xff strb r1, [r0] - writel(ESDCTL0_VAL | ESDCTL0_DSIZ_31_0 | ESDCTL0_REF4 | ESDCTL0_BL | ESDCTL0_SMODE_NORMAL, ESDCTL0) + writel(ESDCTL0_VAL | ESDCTL0_DSIZ_31_0 | ESDCTL0_REF4 | + ESDCTL0_BL | ESDCTL0_SMODE_NORMAL, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0) .endm .section ".text_bare_init","ax" @@ -67,23 +77,26 @@ reset: common_reset r0 /* ahb lite ip interface */ - writel(0x20040304, AIPI1_PSR0) - writel(0xDFFBFCFB, AIPI1_PSR1) - writel(0x00000000, AIPI2_PSR0) - writel(0xFFFFFFFF, AIPI2_PSR1) + writel(0x20040304, MX27_AIPI_BASE_ADDR + MX27_AIPI1_PSR0) + writel(0xDFFBFCFB, MX27_AIPI_BASE_ADDR + MX27_AIPI1_PSR1) + writel(0x00000000, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR0) + writel(0xFFFFFFFF, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR1) /* disable mpll/spll */ - ldr r0, =CSCR + ldr r0, =MX27_CCM_BASE_ADDR + MX27_CSCR ldr r1, [r0] bic r1, r1, #0x03 str r1, [r0] - + /* * pll clock initialization - see section 3.4.3 of the i.MX27 manual */ - writel(0x00331C23, MPCTL0) /* MPLL = 399 MHz */ - writel(0x040C2403, SPCTL0) /* SPLL = 240 MHz */ - writel(0x33F38107 | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART, CSCR) + /* MPLL = 399 MHz */ + writel(0x00331C23, MX27_CCM_BASE_ADDR + MX27_MPCTL0) + /* SPLL = 240 MHz */ + writel(0x040C2403, MX27_CCM_BASE_ADDR + MX27_SPCTL0) + writel(0x33F38107 | MX27_CSCR_MPLL_RESTART | MX27_CSCR_SPLL_RESTART, + MX27_CCM_BASE_ADDR + MX27_CSCR) /* add some delay here */ mov r1, #0x1000 @@ -91,12 +104,14 @@ reset: bne 1b /* clock gating enable */ - writel(0x00050f08, GPCR) + writel(0x00050f08, MX27_SYSCTRL_BASE_ADDR + MX27_GPCR) /* peripheral clock divider */ - writel(0x130400c3, PCDR0) /* FIXME */ - writel(0x09030208, PCDR1) /* PERDIV1=08 @133 MHz */ - /* PERDIV1=04 @266 MHz */ + /* FIXME */ + writel(0x130400c3, MX27_CCM_BASE_ADDR + MX27_PCDR0) + /* PERDIV1=08 @133 MHz */ + writel(0x09030208, MX27_CCM_BASE_ADDR + MX27_PCDR1) + /* PERDIV1=04 @266 MHz */ /* skip sdram initialization if we run from ram */ cmp pc, #0xa0000000 diff --git a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c index 53cc428c84..fdbc26ab42 100644 --- a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c +++ b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c @@ -41,7 +41,7 @@ #include <mach/gpio.h> #include <mach/imx-nand.h> -#include <mach/imx-regs.h> +#include <mach/imx35-regs.h> #include <mach/iomux-mx35.h> #include <mach/iomux-v3.h> #include <mach/imx-ipu-fb.h> @@ -246,14 +246,14 @@ static int eukrea_cpuimx35_core_init(void) u32 reg; /* enable clock for I2C1, SDHC1, USB and FEC */ - reg = readl(MX35_CCM_BASE_ADDR + CCM_CGR1); - reg |= 0x3 << CCM_CGR1_FEC_SHIFT; - reg |= 0x3 << CCM_CGR1_SDHC1_SHIFT; - reg |= 0x3 << CCM_CGR1_I2C1_SHIFT, - reg = writel(reg, MX35_CCM_BASE_ADDR + CCM_CGR1); - reg = readl(MX35_CCM_BASE_ADDR + CCM_CGR2); - reg |= 0x3 << CCM_CGR2_USB_SHIFT; - reg = writel(reg, MX35_CCM_BASE_ADDR + CCM_CGR2); + reg = readl(MX35_CCM_BASE_ADDR + MX35_CCM_CGR1); + reg |= 0x3 << MX35_CCM_CGR1_FEC_SHIFT; + reg |= 0x3 << MX35_CCM_CGR1_SDHC1_SHIFT; + reg |= 0x3 << MX35_CCM_CGR1_I2C1_SHIFT, + reg = writel(reg, MX35_CCM_BASE_ADDR + MX35_CCM_CGR1); + reg = readl(MX35_CCM_BASE_ADDR + MX35_CCM_CGR2); + reg |= 0x3 << MX35_CCM_CGR2_USB_SHIFT; + reg = writel(reg, MX35_CCM_BASE_ADDR + MX35_CCM_CGR2); /* AIPS setup - Only setup MPROTx registers. The PACR default values are good.*/ /* @@ -345,10 +345,10 @@ static int do_cpufreq(int argc, char *argv[]) switch (freq) { case 399: - writel(MPCTL_PARAM_399, MX35_CCM_BASE_ADDR + CCM_MPCTL); + writel(MPCTL_PARAM_399, MX35_CCM_BASE_ADDR + MX35_CCM_MPCTL); break; case 532: - writel(MPCTL_PARAM_532, MX35_CCM_BASE_ADDR + CCM_MPCTL); + writel(MPCTL_PARAM_532, MX35_CCM_BASE_ADDR + MX35_CCM_MPCTL); break; default: return COMMAND_ERROR_USAGE; diff --git a/arch/arm/boards/eukrea_cpuimx35/flash_header.c b/arch/arm/boards/eukrea_cpuimx35/flash_header.c index 26752d1cbf..6fa9c8b0ef 100644 --- a/arch/arm/boards/eukrea_cpuimx35/flash_header.c +++ b/arch/arm/boards/eukrea_cpuimx35/flash_header.c @@ -1,6 +1,6 @@ #include <common.h> #include <mach/imx-flash-header.h> -#include <mach/imx-regs.h> +#include <mach/imx35-regs.h> #include <asm/barebox-arm-head.h> void __naked __flash_header_start go(void) diff --git a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c index ea932f773e..052333503d 100644 --- a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c +++ b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c @@ -18,7 +18,7 @@ */ #include <common.h> #include <init.h> -#include <mach/imx-regs.h> +#include <mach/imx35-regs.h> #include <mach/imx-pll.h> #include <mach/esdctl.h> #include <asm/cache-l2x0.h> @@ -41,14 +41,13 @@ 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 + CCM_PDR4); + r = readl(MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); r &= ~(0xf << 28); r |= 0x1 << 28; - writel(r, MX35_CCM_BASE_ADDR + CCM_PDR4); + writel(r, MX35_CCM_BASE_ADDR + MX35_CCM_PDR4); /* setup a stack to be able to call imx_nand_load_image() */ - r = STACK_BASE + STACK_SIZE - 12; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); imx_nand_load_image(_text, barebox_image_size); @@ -106,27 +105,27 @@ void __bare_init __naked reset(void) * End of ARM1136 init */ - writel(0x003F4208, ccm_base + CCM_CCMR); + writel(0x003F4208, ccm_base + MX35_CCM_CCMR); /* Set MPLL , arm clock and ahb clock*/ - writel(MPCTL_PARAM_532, ccm_base + CCM_MPCTL); + writel(MPCTL_PARAM_532, ccm_base + MX35_CCM_MPCTL); - writel(PPCTL_PARAM_300, ccm_base + CCM_PPCTL); - writel(0x00001000, ccm_base + CCM_PDR0); + writel(PPCTL_PARAM_300, ccm_base + MX35_CCM_PPCTL); + writel(0x00001000, ccm_base + MX35_CCM_PDR0); - r = readl(ccm_base + CCM_CGR0); + r = readl(ccm_base + MX35_CCM_CGR0); r |= 0x00300000; - writel(r, ccm_base + CCM_CGR0); + writel(r, ccm_base + MX35_CCM_CGR0); - r = readl(ccm_base + CCM_CGR1); + r = readl(ccm_base + MX35_CCM_CGR1); r |= 0x00030C00; r |= 0x00000003; - writel(r, ccm_base + CCM_CGR1); + writel(r, ccm_base + MX35_CCM_CGR1); /* enable watchdog asap */ - r = readl(ccm_base + CCM_CGR2); + r = readl(ccm_base + MX35_CCM_CGR2); r |= 0x03000000; - writel(r, ccm_base + CCM_CGR2); + writel(r, ccm_base + MX35_CCM_CGR2); r = readl(MX35_L2CC_BASE_ADDR + L2X0_AUX_CTRL); r |= 0x1000; @@ -138,22 +137,22 @@ void __bare_init __naked reset(void) board_init_lowlevel_return(); /* Init Mobile DDR */ - writel(0x0000000E, ESDMISC); - writel(0x00000004, ESDMISC); + writel(0x0000000E, MX35_ESDCTL_BASE_ADDR + IMX_ESDMISC); + writel(0x00000004, MX35_ESDCTL_BASE_ADDR + IMX_ESDMISC); __asm__ volatile ("1:\n" "subs %0, %1, #1\n" "bne 1b":"=r" (loops):"0" (loops)); - writel(0x0009572B, ESDCFG0); - writel(0x92220000, ESDCTL0); + writel(0x0009572B, MX35_ESDCTL_BASE_ADDR + IMX_ESDCFG0); + writel(0x92220000, MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writeb(0xda, MX35_CSD0_BASE_ADDR + 0x400); - writel(0xA2220000, ESDCTL0); + writel(0xA2220000, MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writeb(0xda, MX35_CSD0_BASE_ADDR); writeb(0xda, MX35_CSD0_BASE_ADDR); - writel(0xB2220000, ESDCTL0); + writel(0xB2220000, MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writeb(0xda, MX35_CSD0_BASE_ADDR + 0x33); writeb(0xda, MX35_CSD0_BASE_ADDR + 0x2000000); - writel(0x82228080, ESDCTL0); + writel(0x82228080, MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); #ifdef CONFIG_NAND_IMX_BOOT /* skip NAND boot if not running from NFC space */ diff --git a/arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c b/arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c index 1279f8965a..ab0ff81d73 100644 --- a/arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c +++ b/arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c @@ -19,7 +19,7 @@ #include <net.h> #include <init.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx51-regs.h> #include <fec.h> #include <mach/gpio.h> #include <asm/armlinux.h> diff --git a/arch/arm/boards/freescale-mx25-3-stack/3stack.c b/arch/arm/boards/freescale-mx25-3-stack/3stack.c index a0ae938809..5ce2f8e290 100644 --- a/arch/arm/boards/freescale-mx25-3-stack/3stack.c +++ b/arch/arm/boards/freescale-mx25-3-stack/3stack.c @@ -21,7 +21,7 @@ #include <init.h> #include <driver.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx25-regs.h> #include <asm/armlinux.h> #include <asm-generic/sections.h> #include <asm/barebox-arm.h> @@ -167,8 +167,8 @@ static int imx25_3ds_fec_init(void) * FEC_RESET_B: gpio2[3] is ALT 5 mode of pin A17 * FEC_ENABLE_B: gpio4[8] is ALT 5 mode of pin D12 */ - writel(0x8, IMX_IOMUXC_BASE + 0x0238); /* open drain */ - writel(0x0, IMX_IOMUXC_BASE + 0x028C); /* cmos, no pu/pd */ + writel(0x8, MX25_IOMUXC_BASE_ADDR + 0x0238); /* open drain */ + writel(0x0, MX25_IOMUXC_BASE_ADDR + 0x028C); /* cmos, no pu/pd */ #define FEC_ENABLE_GPIO 35 #define FEC_RESET_B_GPIO 104 @@ -215,7 +215,7 @@ static int imx25_devices_init(void) imx25_iim_register_fec_ethaddr(); imx25_add_fec(&fec_info); - if (readl(MX25_CCM_BASE_ADDR + CCM_RCSR) & (1 << 14)) + if (readl(MX25_CCM_BASE_ADDR + MX25_CCM_RCSR) & (1 << 14)) nand_info.width = 2; imx25_add_nand(&nand_info); @@ -298,7 +298,7 @@ void __bare_init nand_boot(void) static int imx25_core_setup(void) { - writel(0x01010103, MX25_CCM_BASE_ADDR + CCM_PCDR2); + writel(0x01010103, MX25_CCM_BASE_ADDR + MX25_CCM_PCDR2); return 0; } 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 f911f9d7f8..fb980991a6 100644 --- a/arch/arm/boards/freescale-mx25-3-stack/lowlevel_init.S +++ b/arch/arm/boards/freescale-mx25-3-stack/lowlevel_init.S @@ -18,7 +18,7 @@ */ #include <asm-generic/memory_layout.h> -#include <mach/imx-regs.h> +#include <mach/imx25-regs.h> #include <mach/imx-pll.h> #include <mach/esdctl.h> #include <asm/barebox-arm-head.h> @@ -66,9 +66,9 @@ reset: str r1, [r0, #MX25_CCM_MCR] /* enable all the clocks */ - writel(0x1FFFFFFF, MX25_CCM_BASE_ADDR + CCM_CGCR0) - writel(0xFFFFFFFF, MX25_CCM_BASE_ADDR + CCM_CGCR1) - writel(0x000FDFFF, MX25_CCM_BASE_ADDR + CCM_CGCR2) + writel(0x1FFFFFFF, MX25_CCM_BASE_ADDR + MX25_CCM_CGCR0) + writel(0xFFFFFFFF, MX25_CCM_BASE_ADDR + MX25_CCM_CGCR1) + writel(0x000FDFFF, MX25_CCM_BASE_ADDR + MX25_CCM_CGCR2) writel(0x0000FEFF, MX25_CCM_BASE_ADDR + MX25_CCM_MCR) /* Skip SDRAM initialization if we run from RAM */ diff --git a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c index 7cd61f9e96..5bcb24cf45 100644 --- a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c +++ b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c @@ -236,7 +236,7 @@ static int mx28_evk_devices_init(void) imx_enable_enetclk(); mx28_evk_fec_reset(); - add_generic_device("fec_imx", 0, NULL, IMX_FEC0_BASE, 0x4000, + add_generic_device("imx28-fec", 0, NULL, IMX_FEC0_BASE, 0x4000, IORESOURCE_MEM, &fec_info); return 0; diff --git a/arch/arm/boards/freescale-mx35-3-stack/3stack.c b/arch/arm/boards/freescale-mx35-3-stack/3stack.c index 9a01424402..7da031ab6b 100644 --- a/arch/arm/boards/freescale-mx35-3-stack/3stack.c +++ b/arch/arm/boards/freescale-mx35-3-stack/3stack.c @@ -41,12 +41,13 @@ #include <mach/gpio.h> #include <mach/weim.h> #include <mach/imx-nand.h> -#include <mach/imx-regs.h> +#include <mach/imx35-regs.h> #include <mach/iomux-mx35.h> #include <mach/iomux-v3.h> #include <mach/imx-ipu-fb.h> #include <mach/generic.h> #include <mach/devices-imx35.h> +#include <mach/revision.h> #include <i2c/i2c.h> #include <mfd/mc13xxx.h> @@ -143,7 +144,7 @@ static int f3s_devices_init(void) /* CS0: Nor Flash */ imx35_setup_weimcs(0, 0x0000cf03, 0x10000d03, 0x00720900); - reg = readl(MX35_CCM_BASE_ADDR + CCM_RCSR); + reg = readl(MX35_CCM_BASE_ADDR + MX35_CCM_RCSR); /* some fuses provide us vital information about connected hardware */ if (reg & 0x20000000) nand_info.width = 2; /* 16 bit */ @@ -281,10 +282,10 @@ static int f3s_core_init(void) imx35_setup_weimcs(5, 0x0000D843, 0x22252521, 0x22220A00); /* enable clock for I2C1 and FEC */ - reg = readl(MX35_CCM_BASE_ADDR + CCM_CGR1); - reg |= 0x3 << CCM_CGR1_FEC_SHIFT; - reg |= 0x3 << CCM_CGR1_I2C1_SHIFT; - reg = writel(reg, MX35_CCM_BASE_ADDR + CCM_CGR1); + reg = readl(MX35_CCM_BASE_ADDR + MX35_CCM_CGR1); + reg |= 0x3 << MX35_CCM_CGR1_FEC_SHIFT; + reg |= 0x3 << MX35_CCM_CGR1_I2C1_SHIFT; + reg = writel(reg, MX35_CCM_BASE_ADDR + MX35_CCM_CGR1); /* AIPS setup - Only setup MPROTx registers. The PACR default values are good.*/ /* diff --git a/arch/arm/boards/freescale-mx35-3-stack/flash_header.c b/arch/arm/boards/freescale-mx35-3-stack/flash_header.c index 66763dbf2a..076b816491 100644 --- a/arch/arm/boards/freescale-mx35-3-stack/flash_header.c +++ b/arch/arm/boards/freescale-mx35-3-stack/flash_header.c @@ -1,6 +1,6 @@ #include <common.h> #include <mach/imx-flash-header.h> -#include <mach/imx-regs.h> +#include <mach/imx35-regs.h> #include <asm/barebox-arm-head.h> void __naked __flash_header_start go(void) 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 e5d0feb18f..dada5f3fd5 100644 --- a/arch/arm/boards/freescale-mx35-3-stack/lowlevel_init.S +++ b/arch/arm/boards/freescale-mx35-3-stack/lowlevel_init.S @@ -17,7 +17,7 @@ * */ -#include <mach/imx-regs.h> +#include <mach/imx35-regs.h> #include <mach/imx-pll.h> #include <mach/esdctl.h> #include <asm/cache-l2x0.h> @@ -98,27 +98,27 @@ reset: ldr r0, CCM_BASE_ADDR_W ldr r2, CCM_CCMR_W - str r2, [r0, #CCM_CCMR] + str r2, [r0, #MX35_CCM_CCMR] ldr r3, MPCTL_PARAM_532_W /* consumer path*/ /* Set MPLL, arm clock and ahb clock */ - str r3, [r0, #CCM_MPCTL] + str r3, [r0, #MX35_CCM_MPCTL] ldr r1, PPCTL_PARAM_W - str r1, [r0, #CCM_PPCTL] + str r1, [r0, #MX35_CCM_PPCTL] ldr r1, CCM_PDR0_W - str r1, [r0, #CCM_PDR0] + str r1, [r0, #MX35_CCM_PDR0] - ldr r1, [r0, #CCM_CGR0] + ldr r1, [r0, #MX35_CCM_CGR0] orr r1, r1, #0x00300000 - str r1, [r0, #CCM_CGR0] + str r1, [r0, #MX35_CCM_CGR0] - ldr r1, [r0, #CCM_CGR1] + ldr r1, [r0, #MX35_CCM_CGR1] orr r1, r1, #0x00000C00 orr r1, r1, #0x00000003 - str r1, [r0, #CCM_CGR1] + str r1, [r0, #MX35_CCM_CGR1] /* Skip SDRAM initialization if we run from RAM */ cmp pc, #CSD0_BASE_ADDR @@ -140,13 +140,13 @@ reset: /* setup bank 0 */ mov r5, #0x00 mov r2, #0x00 - mov r1, #CSD0_BASE_ADDR + mov r1, #MX35_CSD0_BASE_ADDR bl setup_sdram_bank /* setup bank 1 */ mov r5, #0x00 mov r2, #0x00 - mov r1, #CSD1_BASE_ADDR + mov r1, #MX35_CSD1_BASE_ADDR bl setup_sdram_bank mov lr, fp diff --git a/arch/arm/boards/freescale-mx51-pdk/board.c b/arch/arm/boards/freescale-mx51-pdk/board.c index 3a8e5eaf04..9db0ed9bef 100644 --- a/arch/arm/boards/freescale-mx51-pdk/board.c +++ b/arch/arm/boards/freescale-mx51-pdk/board.c @@ -17,7 +17,7 @@ #include <common.h> #include <init.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx51-regs.h> #include <fec.h> #include <mach/gpio.h> #include <asm/armlinux.h> @@ -25,6 +25,7 @@ #include <partition.h> #include <fs.h> #include <fcntl.h> +#include <mach/bbu.h> #include <nand.h> #include <notifier.h> #include <spi/spi.h> @@ -37,7 +38,9 @@ #include <mach/generic.h> #include <mach/iomux-mx51.h> #include <mach/devices-imx51.h> +#include <mach/revision.h> #include <mach/iim.h> +#include <mach/imx-flash-header.h> static struct fec_platform_data fec_info = { .xcv_type = MII100, @@ -234,6 +237,10 @@ static void babbage_power_init(void) mdelay(50); } +#define DCD_NAME static struct imx_dcd_entry dcd_entry + +#include "dcd-data.h" + static int f3s_devices_init(void) { spi_register_board_info(mx51_babbage_spi_board_info, @@ -254,6 +261,9 @@ static int f3s_devices_init(void) armlinux_set_bootparams((void *)0x90000100); armlinux_set_architecture(MACH_TYPE_MX51_BABBAGE); + imx51_bbu_internal_mmc_register_handler("mmc", "/dev/disk0", + BBU_HANDLER_FLAG_DEFAULT, dcd_entry, sizeof(dcd_entry)); + return 0; } diff --git a/arch/arm/boards/freescale-mx51-pdk/dcd-data.h b/arch/arm/boards/freescale-mx51-pdk/dcd-data.h new file mode 100644 index 0000000000..4dd6c0d26c --- /dev/null +++ b/arch/arm/boards/freescale-mx51-pdk/dcd-data.h @@ -0,0 +1,60 @@ + +DCD_NAME[] = { + { .ptr_type = 4, .addr = 0x73fa88a0, .val = 0x00000200, }, + { .ptr_type = 4, .addr = 0x73fa850c, .val = 0x000020c5, }, + { .ptr_type = 4, .addr = 0x73fa8510, .val = 0x000020c5, }, + { .ptr_type = 4, .addr = 0x73fa883c, .val = 0x00000002, }, + { .ptr_type = 4, .addr = 0x73fa8848, .val = 0x00000002, }, + { .ptr_type = 4, .addr = 0x73fa84b8, .val = 0x000000e7, }, + { .ptr_type = 4, .addr = 0x73fa84bc, .val = 0x00000045, }, + { .ptr_type = 4, .addr = 0x73fa84c0, .val = 0x00000045, }, + { .ptr_type = 4, .addr = 0x73fa84c4, .val = 0x00000045, }, + { .ptr_type = 4, .addr = 0x73fa84c8, .val = 0x00000045, }, + { .ptr_type = 4, .addr = 0x73fa8820, .val = 0x00000000, }, + { .ptr_type = 4, .addr = 0x73fa84a4, .val = 0x00000003, }, + { .ptr_type = 4, .addr = 0x73fa84a8, .val = 0x00000003, }, + { .ptr_type = 4, .addr = 0x73fa84ac, .val = 0x000000e3, }, + { .ptr_type = 4, .addr = 0x73fa84b0, .val = 0x000000e3, }, + { .ptr_type = 4, .addr = 0x73fa84b4, .val = 0x000000e3, }, + { .ptr_type = 4, .addr = 0x73fa84cc, .val = 0x000000e3, }, + { .ptr_type = 4, .addr = 0x73fa84d0, .val = 0x000000e2, }, + { .ptr_type = 4, .addr = 0x73fa882c, .val = 0x00000004, }, + { .ptr_type = 4, .addr = 0x73fa88a4, .val = 0x00000004, }, + { .ptr_type = 4, .addr = 0x73fa88ac, .val = 0x00000004, }, + { .ptr_type = 4, .addr = 0x73fa88b8, .val = 0x00000004, }, + { .ptr_type = 4, .addr = 0x83fd9000, .val = 0x82a20000, }, + { .ptr_type = 4, .addr = 0x83fd9008, .val = 0x82a20000, }, + { .ptr_type = 4, .addr = 0x83fd9010, .val = 0x000ad0d0, }, + { .ptr_type = 4, .addr = 0x83fd9004, .val = 0x3f3584ab, }, + { .ptr_type = 4, .addr = 0x83fd900c, .val = 0x3f3584ab, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x04008008, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801a, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801b, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00448019, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x07328018, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x04008008, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008010, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008010, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x06328018, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x03808019, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00408019, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008000, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0400800c, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801e, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801f, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801d, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0732801c, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0400800c, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008014, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008014, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0632801c, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0380801d, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0040801d, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008004, }, + { .ptr_type = 4, .addr = 0x83fd9000, .val = 0xb2a20000, }, + { .ptr_type = 4, .addr = 0x83fd9008, .val = 0xb2a20000, }, + { .ptr_type = 4, .addr = 0x83fd9010, .val = 0x000ad6d0, }, + { .ptr_type = 4, .addr = 0x83fd9034, .val = 0x90000000, }, + { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00000000, }, +}; + diff --git a/arch/arm/boards/freescale-mx51-pdk/env/init/config-board b/arch/arm/boards/freescale-mx51-pdk/env/init/config-board new file mode 100644 index 0000000000..cfc483eb3d --- /dev/null +++ b/arch/arm/boards/freescale-mx51-pdk/env/init/config-board @@ -0,0 +1,7 @@ +#!/bin/sh + +# board defaults, do not change in running system. Change /env/config +# instead + +global.hostname=babbage +global.linux.bootargs.base="console=ttymxc0,115200" diff --git a/arch/arm/boards/freescale-mx51-pdk/env/init/hostname b/arch/arm/boards/freescale-mx51-pdk/env/init/hostname deleted file mode 100644 index 4c78902a17..0000000000 --- a/arch/arm/boards/freescale-mx51-pdk/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=babbage diff --git a/arch/arm/boards/freescale-mx51-pdk/flash_header.c b/arch/arm/boards/freescale-mx51-pdk/flash_header.c index c148eea4ff..f3f1e4bfd5 100644 --- a/arch/arm/boards/freescale-mx51-pdk/flash_header.c +++ b/arch/arm/boards/freescale-mx51-pdk/flash_header.c @@ -7,64 +7,9 @@ void __naked __flash_header_start go(void) barebox_arm_head(); } -struct imx_dcd_entry __dcd_entry_section dcd_entry[] = { - { .ptr_type = 4, .addr = 0x73fa88a0, .val = 0x00000200, }, - { .ptr_type = 4, .addr = 0x73fa850c, .val = 0x000020c5, }, - { .ptr_type = 4, .addr = 0x73fa8510, .val = 0x000020c5, }, - { .ptr_type = 4, .addr = 0x73fa883c, .val = 0x00000002, }, - { .ptr_type = 4, .addr = 0x73fa8848, .val = 0x00000002, }, - { .ptr_type = 4, .addr = 0x73fa84b8, .val = 0x000000e7, }, - { .ptr_type = 4, .addr = 0x73fa84bc, .val = 0x00000045, }, - { .ptr_type = 4, .addr = 0x73fa84c0, .val = 0x00000045, }, - { .ptr_type = 4, .addr = 0x73fa84c4, .val = 0x00000045, }, - { .ptr_type = 4, .addr = 0x73fa84c8, .val = 0x00000045, }, - { .ptr_type = 4, .addr = 0x73fa8820, .val = 0x00000000, }, - { .ptr_type = 4, .addr = 0x73fa84a4, .val = 0x00000003, }, - { .ptr_type = 4, .addr = 0x73fa84a8, .val = 0x00000003, }, - { .ptr_type = 4, .addr = 0x73fa84ac, .val = 0x000000e3, }, - { .ptr_type = 4, .addr = 0x73fa84b0, .val = 0x000000e3, }, - { .ptr_type = 4, .addr = 0x73fa84b4, .val = 0x000000e3, }, - { .ptr_type = 4, .addr = 0x73fa84cc, .val = 0x000000e3, }, - { .ptr_type = 4, .addr = 0x73fa84d0, .val = 0x000000e2, }, - { .ptr_type = 4, .addr = 0x73fa882c, .val = 0x00000004, }, - { .ptr_type = 4, .addr = 0x73fa88a4, .val = 0x00000004, }, - { .ptr_type = 4, .addr = 0x73fa88ac, .val = 0x00000004, }, - { .ptr_type = 4, .addr = 0x73fa88b8, .val = 0x00000004, }, - { .ptr_type = 4, .addr = 0x83fd9000, .val = 0x82a20000, }, - { .ptr_type = 4, .addr = 0x83fd9008, .val = 0x82a20000, }, - { .ptr_type = 4, .addr = 0x83fd9010, .val = 0x000ad0d0, }, - { .ptr_type = 4, .addr = 0x83fd9004, .val = 0x3f3584ab, }, - { .ptr_type = 4, .addr = 0x83fd900c, .val = 0x3f3584ab, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x04008008, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801a, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801b, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00448019, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x07328018, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x04008008, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008010, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008010, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x06328018, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x03808019, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00408019, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008000, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0400800c, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801e, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801f, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801d, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0732801c, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0400800c, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008014, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008014, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0632801c, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0380801d, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0040801d, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008004, }, - { .ptr_type = 4, .addr = 0x83fd9000, .val = 0xb2a20000, }, - { .ptr_type = 4, .addr = 0x83fd9008, .val = 0xb2a20000, }, - { .ptr_type = 4, .addr = 0x83fd9010, .val = 0x000ad6d0, }, - { .ptr_type = 4, .addr = 0x83fd9034, .val = 0x90000000, }, - { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00000000, }, -}; +#define DCD_NAME struct imx_dcd_entry __dcd_entry_section dcd_entry + +#include "dcd-data.h" #define APP_DEST 0x90000000 diff --git a/arch/arm/boards/freescale-mx53-loco/board.c b/arch/arm/boards/freescale-mx53-loco/board.c index 0d715559dc..216d26a0a8 100644 --- a/arch/arm/boards/freescale-mx53-loco/board.c +++ b/arch/arm/boards/freescale-mx53-loco/board.c @@ -27,7 +27,7 @@ #include <generated/mach-types.h> -#include <mach/imx-regs.h> +#include <mach/imx53-regs.h> #include <mach/iomux-mx53.h> #include <mach/devices-imx53.h> #include <mach/generic.h> @@ -35,6 +35,9 @@ #include <mach/imx-nand.h> #include <mach/iim.h> #include <mach/imx5.h> +#include <mach/revision.h> +#include <mach/bbu.h> +#include <mach/imx-flash-header.h> #include <i2c/i2c.h> #include <mfd/mc34708.h> @@ -176,10 +179,15 @@ static void loco_ehci_init(void) add_generic_usb_ehci_device(1, MX53_OTG_BASE_ADDR + 0x200, NULL); } +#define DCD_NAME static struct imx_dcd_v2_entry dcd_entry + +#include "dcd-data.h" + static int loco_devices_init(void) { imx53_iim_register_fec_ethaddr(); + loco_fec_reset(); imx53_add_fec(&fec_info); imx53_add_mmc0(&loco_sd1_data); imx53_add_mmc2(&loco_sd3_data); @@ -189,13 +197,14 @@ static int loco_devices_init(void) if (IS_ENABLED(CONFIG_USB_EHCI)) loco_ehci_init(); - loco_fec_reset(); - set_silicon_rev(imx_silicon_revision()); armlinux_set_bootparams((void *)0x70000100); armlinux_set_architecture(MACH_TYPE_MX53_LOCO); + imx53_bbu_internal_mmc_register_handler("mmc", "/dev/disk0", + BBU_HANDLER_FLAG_DEFAULT, dcd_entry, sizeof(dcd_entry)); + return 0; } diff --git a/arch/arm/boards/freescale-mx53-loco/dcd-data.h b/arch/arm/boards/freescale-mx53-loco/dcd-data.h new file mode 100644 index 0000000000..9f95fb4b89 --- /dev/null +++ b/arch/arm/boards/freescale-mx53-loco/dcd-data.h @@ -0,0 +1,54 @@ + +DCD_NAME[] = { + { .addr = cpu_to_be32(0x53fa8554), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa8558), .val = cpu_to_be32(0x00300040), }, + { .addr = cpu_to_be32(0x53fa8560), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa8564), .val = cpu_to_be32(0x00300040), }, + { .addr = cpu_to_be32(0x53fa8568), .val = cpu_to_be32(0x00300040), }, + { .addr = cpu_to_be32(0x53fa8570), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa8574), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa8578), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa857c), .val = cpu_to_be32(0x00300040), }, + { .addr = cpu_to_be32(0x53fa8580), .val = cpu_to_be32(0x00300040), }, + { .addr = cpu_to_be32(0x53fa8584), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa8588), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa8590), .val = cpu_to_be32(0x00300040), }, + { .addr = cpu_to_be32(0x53fa8594), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa86f0), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa86f4), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa86fc), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa8714), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa8718), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa871c), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa8720), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa8724), .val = cpu_to_be32(0x04000000), }, + { .addr = cpu_to_be32(0x53fa8728), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x53fa872c), .val = cpu_to_be32(0x00300000), }, + { .addr = cpu_to_be32(0x63fd9088), .val = cpu_to_be32(0x35343535), }, + { .addr = cpu_to_be32(0x63fd9090), .val = cpu_to_be32(0x4d444c44), }, + { .addr = cpu_to_be32(0x63fd907c), .val = cpu_to_be32(0x01370138), }, + { .addr = cpu_to_be32(0x63fd9080), .val = cpu_to_be32(0x013b013c), }, + { .addr = cpu_to_be32(0x63fd9018), .val = cpu_to_be32(0x00011740), }, + { .addr = cpu_to_be32(0x63fd9000), .val = cpu_to_be32(0xc3190000), }, + { .addr = cpu_to_be32(0x63fd900c), .val = cpu_to_be32(0x9f5152e3), }, + { .addr = cpu_to_be32(0x63fd9010), .val = cpu_to_be32(0xb68e8a63), }, + { .addr = cpu_to_be32(0x63fd9014), .val = cpu_to_be32(0x01ff00db), }, + { .addr = cpu_to_be32(0x63fd902c), .val = cpu_to_be32(0x000026d2), }, + { .addr = cpu_to_be32(0x63fd9030), .val = cpu_to_be32(0x009f0e21), }, + { .addr = cpu_to_be32(0x63fd9008), .val = cpu_to_be32(0x12273030), }, + { .addr = cpu_to_be32(0x63fd9004), .val = cpu_to_be32(0x0002002d), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008032), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008033), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00028031), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x052080b0), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x04008040), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x0000803a), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x0000803b), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00028039), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x05208138), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x04008048), }, + { .addr = cpu_to_be32(0x63fd9020), .val = cpu_to_be32(0x00005800), }, + { .addr = cpu_to_be32(0x63fd9040), .val = cpu_to_be32(0x04b80003), }, + { .addr = cpu_to_be32(0x63fd9058), .val = cpu_to_be32(0x00022227), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00000000), }, +}; diff --git a/arch/arm/boards/freescale-mx53-loco/flash_header.c b/arch/arm/boards/freescale-mx53-loco/flash_header.c index c2ab25582e..dc1162bac8 100644 --- a/arch/arm/boards/freescale-mx53-loco/flash_header.c +++ b/arch/arm/boards/freescale-mx53-loco/flash_header.c @@ -23,59 +23,9 @@ void __naked __flash_header_start go(void) barebox_arm_head(); } -struct imx_dcd_v2_entry __dcd_entry_section dcd_entry[] = { - { .addr = cpu_to_be32(0x53fa8554), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa8558), .val = cpu_to_be32(0x00300040), }, - { .addr = cpu_to_be32(0x53fa8560), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa8564), .val = cpu_to_be32(0x00300040), }, - { .addr = cpu_to_be32(0x53fa8568), .val = cpu_to_be32(0x00300040), }, - { .addr = cpu_to_be32(0x53fa8570), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa8574), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa8578), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa857c), .val = cpu_to_be32(0x00300040), }, - { .addr = cpu_to_be32(0x53fa8580), .val = cpu_to_be32(0x00300040), }, - { .addr = cpu_to_be32(0x53fa8584), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa8588), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa8590), .val = cpu_to_be32(0x00300040), }, - { .addr = cpu_to_be32(0x53fa8594), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa86f0), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa86f4), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa86fc), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa8714), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa8718), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa871c), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa8720), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa8724), .val = cpu_to_be32(0x04000000), }, - { .addr = cpu_to_be32(0x53fa8728), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x53fa872c), .val = cpu_to_be32(0x00300000), }, - { .addr = cpu_to_be32(0x63fd9088), .val = cpu_to_be32(0x35343535), }, - { .addr = cpu_to_be32(0x63fd9090), .val = cpu_to_be32(0x4d444c44), }, - { .addr = cpu_to_be32(0x63fd907c), .val = cpu_to_be32(0x01370138), }, - { .addr = cpu_to_be32(0x63fd9080), .val = cpu_to_be32(0x013b013c), }, - { .addr = cpu_to_be32(0x63fd9018), .val = cpu_to_be32(0x00011740), }, - { .addr = cpu_to_be32(0x63fd9000), .val = cpu_to_be32(0xc3190000), }, - { .addr = cpu_to_be32(0x63fd900c), .val = cpu_to_be32(0x9f5152e3), }, - { .addr = cpu_to_be32(0x63fd9010), .val = cpu_to_be32(0xb68e8a63), }, - { .addr = cpu_to_be32(0x63fd9014), .val = cpu_to_be32(0x01ff00db), }, - { .addr = cpu_to_be32(0x63fd902c), .val = cpu_to_be32(0x000026d2), }, - { .addr = cpu_to_be32(0x63fd9030), .val = cpu_to_be32(0x009f0e21), }, - { .addr = cpu_to_be32(0x63fd9008), .val = cpu_to_be32(0x12273030), }, - { .addr = cpu_to_be32(0x63fd9004), .val = cpu_to_be32(0x0002002d), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008032), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008033), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00028031), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x052080b0), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x04008040), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x0000803a), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x0000803b), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00028039), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x05208138), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x04008048), }, - { .addr = cpu_to_be32(0x63fd9020), .val = cpu_to_be32(0x00005800), }, - { .addr = cpu_to_be32(0x63fd9040), .val = cpu_to_be32(0x04b80003), }, - { .addr = cpu_to_be32(0x63fd9058), .val = cpu_to_be32(0x00022227), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00000000), }, -}; +#define DCD_NAME struct imx_dcd_v2_entry __dcd_entry_section dcd_entry + +#include "dcd-data.h" #define APP_DEST 0x70000000 diff --git a/arch/arm/boards/freescale-mx53-smd/board.c b/arch/arm/boards/freescale-mx53-smd/board.c index 04831030a8..a5ad009106 100644 --- a/arch/arm/boards/freescale-mx53-smd/board.c +++ b/arch/arm/boards/freescale-mx53-smd/board.c @@ -27,7 +27,7 @@ #include <generated/mach-types.h> -#include <mach/imx-regs.h> +#include <mach/imx53-regs.h> #include <mach/iomux-mx53.h> #include <mach/devices-imx53.h> #include <mach/generic.h> diff --git a/arch/arm/boards/freescale-mx6-arm2/board.c b/arch/arm/boards/freescale-mx6-arm2/board.c index ccc73182db..ce9874d85f 100644 --- a/arch/arm/boards/freescale-mx6-arm2/board.c +++ b/arch/arm/boards/freescale-mx6-arm2/board.c @@ -15,7 +15,7 @@ #include <common.h> #include <init.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx6-regs.h> #include <fec.h> #include <mach/gpio.h> #include <asm/armlinux.h> diff --git a/arch/arm/boards/freescale-mx6-sabrelite/board.c b/arch/arm/boards/freescale-mx6-sabrelite/board.c index 25402d7c9c..da37e17b8f 100644 --- a/arch/arm/boards/freescale-mx6-sabrelite/board.c +++ b/arch/arm/boards/freescale-mx6-sabrelite/board.c @@ -17,7 +17,7 @@ #include <common.h> #include <init.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx6-regs.h> #include <fec.h> #include <mach/gpio.h> #include <asm/armlinux.h> @@ -200,7 +200,7 @@ static inline int imx6_iim_register_fec_ethaddr(void) return 0; } -static int sabrelite_spi_cs[] = {GPIO_PORTC + 19}; +static int sabrelite_spi_cs[] = {IMX_GPIO_NR(3, 19)}; static struct spi_imx_master sabrelite_spi_0_data = { .chipselect = sabrelite_spi_cs, diff --git a/arch/arm/boards/freescale-mx6-sabrelite/env/init/config-board b/arch/arm/boards/freescale-mx6-sabrelite/env/init/config-board new file mode 100644 index 0000000000..e39e4b6141 --- /dev/null +++ b/arch/arm/boards/freescale-mx6-sabrelite/env/init/config-board @@ -0,0 +1,7 @@ +#!/bin/sh + +# board defaults, do not change in running system. Change /env/config +# instead + +global.hostname=SabreLite +global.linux.bootargs.base="console=ttymxc1,115200" diff --git a/arch/arm/boards/friendlyarm-tiny210/Makefile b/arch/arm/boards/friendlyarm-tiny210/Makefile index 9c38e6038b..20060a53e3 100644 --- a/arch/arm/boards/friendlyarm-tiny210/Makefile +++ b/arch/arm/boards/friendlyarm-tiny210/Makefile @@ -1 +1,2 @@ obj-y += tiny210.o lowlevel.o +pbl-y += lowlevel.o diff --git a/arch/arm/boards/guf-cupid/board.c b/arch/arm/boards/guf-cupid/board.c index 933a9cd057..5b1732631a 100644 --- a/arch/arm/boards/guf-cupid/board.c +++ b/arch/arm/boards/guf-cupid/board.c @@ -25,7 +25,7 @@ #include <driver.h> #include <environment.h> #include <fs.h> -#include <mach/imx-regs.h> +#include <mach/imx35-regs.h> #include <asm/armlinux.h> #include <mach/gpio.h> #include <io.h> @@ -117,7 +117,7 @@ static int cupid_devices_init(void) gpio_direction_output(GPIO_LCD_ENABLE, 0); gpio_direction_output(GPIO_LCD_BACKLIGHT, 0); - reg = readl(MX35_CCM_BASE_ADDR + CCM_RCSR); + reg = readl(MX35_CCM_BASE_ADDR + MX35_CCM_RCSR); /* some fuses provide us vital information about connected hardware */ if (reg & 0x20000000) nand_info.width = 2; /* 16 bit */ @@ -339,10 +339,10 @@ static int do_cpufreq(int argc, char *argv[]) switch (freq) { case 399: - writel(MPCTL_PARAM_399, MX35_CCM_BASE_ADDR + CCM_MPCTL); + writel(MPCTL_PARAM_399, MX35_CCM_BASE_ADDR + MX35_CCM_MPCTL); break; case 532: - writel(MPCTL_PARAM_532, MX35_CCM_BASE_ADDR + CCM_MPCTL); + writel(MPCTL_PARAM_532, MX35_CCM_BASE_ADDR + MX35_CCM_MPCTL); break; default: return COMMAND_ERROR_USAGE; diff --git a/arch/arm/boards/guf-cupid/lowlevel.c b/arch/arm/boards/guf-cupid/lowlevel.c index d451fd9393..f2e44af7a5 100644 --- a/arch/arm/boards/guf-cupid/lowlevel.c +++ b/arch/arm/boards/guf-cupid/lowlevel.c @@ -18,7 +18,7 @@ */ #include <common.h> #include <init.h> -#include <mach/imx-regs.h> +#include <mach/imx35-regs.h> #include <mach/imx-pll.h> #include <mach/esdctl.h> #include <asm/cache-l2x0.h> @@ -54,8 +54,7 @@ static void __bare_init __naked insdram(void) writel(r, MX35_CCM_BASE_ADDR + CCM_PDR4); /* setup a stack to be able to call imx_nand_load_image() */ - r = STACK_BASE + STACK_SIZE - 12; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); imx_nand_load_image(_text, barebox_image_size); @@ -71,15 +70,15 @@ static void __bare_init noinline setup_sdram(u32 memsize, u32 mode, u32 sdram_ad u32 r1, r0; /* disable second SDRAM region to save power */ - r1 = readl(ESDCTL1); + r1 = readl(MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL1); r1 &= ~ESDCTL0_SDE; - writel(r1, ESDCTL1); + writel(r1, MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL1); mode |= ESDMISC_RST | ESDMISC_MDDR_DL_RST; - writel(mode, ESDMISC); + writel(mode, MX35_ESDCTL_BASE_ADDR + IMX_ESDMISC); mode &= ~(ESDMISC_RST | ESDMISC_MDDR_DL_RST); - writel(mode, ESDMISC); + writel(mode, MX35_ESDCTL_BASE_ADDR + IMX_ESDMISC); /* wait for esdctl reset */ for (loop = 0; loop < 0x20000; loop++); @@ -90,16 +89,18 @@ static void __bare_init noinline setup_sdram(u32 memsize, u32 mode, u32 sdram_ad ESDCFGx_tRRD_2 | ESDCFGx_tCAS_3 | ESDCFGx_tRCD_3 | ESDCFGx_tRC_20; - writel(r1, ESDCFG0); + writel(r1, MX35_ESDCTL_BASE_ADDR + IMX_ESDCFG0); /* enable SDRAM controller */ - writel(memsize | ESDCTL0_SMODE_NORMAL, ESDCTL0); + writel(memsize | ESDCTL0_SMODE_NORMAL, + MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); /* Micron Datasheet Initialization Step 3: Wait 200us before first command */ for (loop = 0; loop < 1000; loop++); /* Micron Datasheet Initialization Step 4: PRE CHARGE ALL */ - writel(memsize | ESDCTL0_SMODE_PRECHARGE, ESDCTL0); + writel(memsize | ESDCTL0_SMODE_PRECHARGE, + MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writeb(r11, sdram_addr); /* Micron Datasheet Initialization Step 5: NOP for tRP (at least 22.5ns) @@ -109,7 +110,8 @@ static void __bare_init noinline setup_sdram(u32 memsize, u32 mode, u32 sdram_ad /* Micron Datasheet Initialization Step 6: 2 AUTO REFRESH and tRFC NOP * (at least 140ns) */ - writel(memsize | ESDCTL0_SMODE_AUTO_REFRESH, ESDCTL0); + writel(memsize | ESDCTL0_SMODE_AUTO_REFRESH, + MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writeb(r11, r9); /* AUTO REFRESH #1 */ for (loop = 0; loop < 3; loop++); /* ~140ns delay at 532MHz */ @@ -119,7 +121,8 @@ static void __bare_init noinline setup_sdram(u32 memsize, u32 mode, u32 sdram_ad for (loop = 0; loop < 3; loop++); /* ~140ns delay at 532MHz */ /* Micron Datasheet Initialization Step 7: LOAD MODE REGISTER */ - writel(memsize | ESDCTL0_SMODE_LOAD_MODE, ESDCTL0); + writel(memsize | ESDCTL0_SMODE_LOAD_MODE, + MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writeb(r11, r9 + (SDRAM_MODE_BL_8 | SDRAM_MODE_BSEQ | SDRAM_MODE_CL_3)); /* Micron Datasheet Initialization Step 8: tMRD = 2 tCK NOP @@ -134,7 +137,8 @@ static void __bare_init noinline setup_sdram(u32 memsize, u32 mode, u32 sdram_ad */ /* Now configure SDRAM-Controller and check that it works */ - writel(memsize | ESDCTL0_BL | ESDCTL0_REF4, ESDCTL0); + writel(memsize | ESDCTL0_BL | ESDCTL0_REF4, + MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); /* Freescale asks for first access to be a write to properly * initialize DQS pin-state and keepers @@ -156,10 +160,10 @@ static void __bare_init noinline setup_sdram(u32 memsize, u32 mode, u32 sdram_ad /* if both value are identical, we don't have 14 rows. assume 13 instead */ if (readl(r9) == readl(r9 + (1 << 25))) { - r0 = readl(ESDCTL0); + r0 = readl(MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); r0 &= ~ESDCTL0_ROW_MASK; r0 |= ESDCTL0_ROW13; - writel(r0, ESDCTL0); + writel(r0, MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); } /* So far we asssumed that we have 10 columns, verify this */ @@ -168,10 +172,10 @@ static void __bare_init noinline setup_sdram(u32 memsize, u32 mode, u32 sdram_ad /* if both value are identical, we don't have 10 cols. assume 9 instead */ if (readl(r9) == readl(r9 + (1 << 11))) { - r0 = readl(ESDCTL0); + r0 = readl(MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); r0 &= ~ESDCTL0_COL_MASK; r0 |= ESDCTL0_COL9; - writel(r0, ESDCTL0); + writel(r0, MX35_ESDCTL_BASE_ADDR + IMX_ESDCTL0); } } @@ -182,7 +186,7 @@ static void __bare_init noinline setup_sdram(u32 memsize, u32 mode, u32 sdram_ad void __bare_init __naked reset(void) { u32 r0, r1; - void *iomuxc_base = (void *)IMX_IOMUXC_BASE; + void *iomuxc_base = (void *)MX35_IOMUXC_BASE_ADDR; int i; #ifdef CONFIG_NAND_IMX_BOOT unsigned int *trg, *src; @@ -190,8 +194,7 @@ void __bare_init __naked reset(void) common_reset(); - r0 = 0x10000000 + 128 * 1024 - 16; - __asm__ __volatile__("mov sp, %0" : : "r"(r0)); + arm_setup_stack(0x10000000 + 128 * 1024 - 16); /* * ARM1136 init @@ -299,27 +302,27 @@ void __bare_init __naked reset(void) /* Configure clocks */ /* setup cpu/bus clocks */ - writel(0x003f4208, MX35_CCM_BASE_ADDR + CCM_CCMR); + writel(0x003f4208, MX35_CCM_BASE_ADDR + MX35_CCM_CCMR); /* configure MPLL */ - writel(MPCTL_PARAM_532, MX35_CCM_BASE_ADDR + CCM_MPCTL); + writel(MPCTL_PARAM_532, MX35_CCM_BASE_ADDR + MX35_CCM_MPCTL); /* configure PPLL */ - writel(PPCTL_PARAM_300, MX35_CCM_BASE_ADDR + CCM_PPCTL); + writel(PPCTL_PARAM_300, MX35_CCM_BASE_ADDR + MX35_CCM_PPCTL); /* configure core dividers */ - r0 = PDR0_CCM_PER_AHB(1) | PDR0_HSP_PODF(2); + r0 = MX35_PDR0_CCM_PER_AHB(1) | MX35_PDR0_HSP_PODF(2); - writel(r0, MX35_CCM_BASE_ADDR + CCM_PDR0); + writel(r0, MX35_CCM_BASE_ADDR + MX35_CCM_PDR0); /* configure clock-gates */ - r0 = readl(MX35_CCM_BASE_ADDR + CCM_CGR0); + r0 = readl(MX35_CCM_BASE_ADDR + MX35_CCM_CGR0); r0 |= 0x00300000; - writel(r0, MX35_CCM_BASE_ADDR + CCM_CGR0); + writel(r0, MX35_CCM_BASE_ADDR + MX35_CCM_CGR0); - r0 = readl(MX35_CCM_BASE_ADDR + CCM_CGR1); + r0 = readl(MX35_CCM_BASE_ADDR + MX35_CCM_CGR1); r0 |= 0x00000c03; - writel(r0, MX35_CCM_BASE_ADDR + CCM_CGR1); + writel(r0, MX35_CCM_BASE_ADDR + MX35_CCM_CGR1); /* Configure SDRAM */ /* Try 32-Bit 256 MB DDR memory */ diff --git a/arch/arm/boards/guf-neso/board.c b/arch/arm/boards/guf-neso/board.c index 7adee929b0..200a2efc53 100644 --- a/arch/arm/boards/guf-neso/board.c +++ b/arch/arm/boards/guf-neso/board.c @@ -35,7 +35,7 @@ #include <mach/gpio.h> #include <mach/spi.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> #include <mach/iomux-mx27.h> #include <mach/imx-nand.h> #include <mach/imx-pll.h> @@ -320,10 +320,10 @@ static int neso_pll(void) pllfunc(); /* clock gating enable */ - GPCR = 0x00050f08; + writel(0x00050f08, MX27_SYSCTRL_BASE_ADDR + MX27_GPCR); - PCDR0 = 0x130410c3; - PCDR1 = 0x09030911; + writel(0x130410c3, MX27_CCM_BASE_ADDR + MX27_PCDR0); + writel(0x09030911, MX27_CCM_BASE_ADDR + MX27_PCDR1); /* Clocks have changed. Notify clients */ clock_notifier_call_chain(); diff --git a/arch/arm/boards/guf-neso/lowlevel.c b/arch/arm/boards/guf-neso/lowlevel.c index 52fe6cffa8..ad414d9208 100644 --- a/arch/arm/boards/guf-neso/lowlevel.c +++ b/arch/arm/boards/guf-neso/lowlevel.c @@ -18,7 +18,7 @@ */ #include <common.h> #include <init.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> #include <mach/imx-pll.h> #include <mach/esdctl.h> #include <asm/cache-l2x0.h> @@ -33,13 +33,8 @@ #ifdef CONFIG_NAND_IMX_BOOT static void __bare_init __naked insdram(void) { - uint32_t r; - - PCCR1 |= PCCR1_NFC_BAUDEN; - /* setup a stack to be able to call imx_nand_load_image() */ - r = STACK_BASE + STACK_SIZE - 12; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); imx_nand_load_image(_text, barebox_image_size); @@ -60,10 +55,10 @@ void __bare_init __naked reset(void) common_reset(); /* ahb lite ip interface */ - AIPI1_PSR0 = 0x20040304; - AIPI1_PSR1 = 0xDFFBFCFB; - AIPI2_PSR0 = 0x00000000; - AIPI2_PSR1 = 0xFFFFFFFF; + writel(0x20040304, MX27_AIPI_BASE_ADDR + MX27_AIPI1_PSR0); + writel(0xDFFBFCFB, MX27_AIPI_BASE_ADDR + MX27_AIPI1_PSR1); + writel(0x00000000, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR0); + writel(0xFFFFFFFF, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR1); /* Skip SDRAM initialization if we run from RAM */ r = get_pc(); @@ -73,30 +68,38 @@ void __bare_init __naked reset(void) /* * DDR on CSD0 */ - writel(0x00000008, ESDMISC); /* Enable DDR SDRAM operation */ - - DSCR(3) = 0x55555555; /* Set the driving strength */ - DSCR(5) = 0x55555555; - DSCR(6) = 0x55555555; - DSCR(7) = 0x00005005; - DSCR(8) = 0x15555555; - - writel(0x00000004, ESDMISC); /* Initial reset */ - writel(0x006ac73a, ESDCFG0); - - writel(ESDCTL0_VAL | ESDCTL0_SMODE_PRECHARGE, ESDCTL0); /* precharge CSD0 all banks */ + /* Enable DDR SDRAM operation */ + writel(0x00000008, MX27_ESDCTL_BASE_ADDR + IMX_ESDMISC); + + /* Set the driving strength */ + writel(0x55555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(3)); + writel(0x55555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(5)); + writel(0x55555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(6)); + writel(0x00005005, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(7)); + writel(0x15555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(8)); + + /* Initial reset */ + writel(0x00000004, MX27_ESDCTL_BASE_ADDR + IMX_ESDMISC); + writel(0x006ac73a, MX27_ESDCTL_BASE_ADDR + IMX_ESDCFG0); + + /* precharge CSD0 all banks */ + writel(ESDCTL0_VAL | ESDCTL0_SMODE_PRECHARGE, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writel(0x00000000, 0xA0000F00); /* CSD0 precharge address (A10 = 1) */ - writel(ESDCTL0_VAL | ESDCTL0_SMODE_AUTO_REFRESH, ESDCTL0); + writel(ESDCTL0_VAL | ESDCTL0_SMODE_AUTO_REFRESH, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0); for (i = 0; i < 8; i++) writel(0, 0xa0000f00); - writel(ESDCTL0_VAL | ESDCTL0_SMODE_LOAD_MODE, ESDCTL0); + writel(ESDCTL0_VAL | ESDCTL0_SMODE_LOAD_MODE, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writeb(0xda, 0xa0000033); writeb(0xff, 0xa1000000); writel(ESDCTL0_VAL | ESDCTL0_DSIZ_31_0 | ESDCTL0_REF4 | - ESDCTL0_BL | ESDCTL0_SMODE_NORMAL, ESDCTL0); + ESDCTL0_BL | ESDCTL0_SMODE_NORMAL, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0); #ifdef CONFIG_NAND_IMX_BOOT /* skip NAND boot if not running from NFC space */ diff --git a/arch/arm/boards/guf-neso/pll_init.S b/arch/arm/boards/guf-neso/pll_init.S index 87e5312fb4..4c6cb67fd4 100644 --- a/arch/arm/boards/guf-neso/pll_init.S +++ b/arch/arm/boards/guf-neso/pll_init.S @@ -1,5 +1,5 @@ #include <config.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> #include <mach/imx-pll.h> #include <linux/linkage.h> @@ -8,34 +8,37 @@ ldr r1, =val; \ str r1, [r0]; -#define CSCR_VAL CSCR_USB_DIV(3) | \ - CSCR_SD_CNT(3) | \ - CSCR_MSHC_SEL | \ - CSCR_H264_SEL | \ - CSCR_SSI1_SEL | \ - CSCR_SSI2_SEL | \ - CSCR_MCU_SEL | \ - CSCR_ARM_SRC_MPLL | \ - CSCR_SP_SEL | \ - CSCR_ARM_DIV(0) | \ - CSCR_FPM_EN | \ - CSCR_SPEN | \ - CSCR_MPEN | \ - CSCR_AHB_DIV(1) +#define CSCR_VAL MX27_CSCR_USB_DIV(3) | \ + MX27_CSCR_SD_CNT(3) | \ + MX27_CSCR_MSHC_SEL | \ + MX27_CSCR_H264_SEL | \ + MX27_CSCR_SSI1_SEL | \ + MX27_CSCR_SSI2_SEL | \ + MX27_CSCR_MCU_SEL | \ + MX27_CSCR_ARM_SRC_MPLL | \ + MX27_CSCR_SP_SEL | \ + MX27_CSCR_ARM_DIV(0) | \ + MX27_CSCR_FPM_EN | \ + MX27_CSCR_SPEN | \ + MX27_CSCR_MPEN | \ + MX27_CSCR_AHB_DIV(1) ENTRY(neso_pll_init) + /* 399 MHz */ writel(IMX_PLL_PD(0) | IMX_PLL_MFD(51) | IMX_PLL_MFI(7) | - IMX_PLL_MFN(35), MPCTL0) /* 399 MHz */ + IMX_PLL_MFN(35), MX27_CCM_BASE_ADDR + MX27_MPCTL0) + /* SPLL = 2 * 26 * 4.61538 MHz = 240 MHz */ writel(IMX_PLL_PD(1) | IMX_PLL_MFD(12) | IMX_PLL_MFI(9) | - IMX_PLL_MFN(3), SPCTL0) /* SPLL = 2 * 26 * 4.61538 MHz = 240 MHz */ + IMX_PLL_MFN(3), MX27_CCM_BASE_ADDR + MX27_SPCTL0) - writel(CSCR_VAL | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART, CSCR) + writel(CSCR_VAL | MX27_CSCR_MPLL_RESTART | MX27_CSCR_SPLL_RESTART, + MX27_CCM_BASE_ADDR + MX27_CSCR) ldr r2, =16000 1: diff --git a/arch/arm/boards/imx21ads/imx21ads.c b/arch/arm/boards/imx21ads/imx21ads.c index 22406beb5a..ca566c831a 100644 --- a/arch/arm/boards/imx21ads/imx21ads.c +++ b/arch/arm/boards/imx21ads/imx21ads.c @@ -21,7 +21,7 @@ #include <net.h> #include <init.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx21-regs.h> #include <asm/armlinux.h> #include <asm-generic/sections.h> #include <asm/barebox-arm.h> @@ -95,10 +95,10 @@ static int imx21ads_timing_init(void) imx21_setup_eimcs(4, 0x0, 0x0); imx21_setup_eimcs(5, 0x0, 0x0); - temp = PCDR0; + temp = readl(MX21_CCM_BASE_ADDR + MX21_PCDR0); temp &= ~0xF000; temp |= 0xA000; /* Set NFC divider; 0xA yields 24.18MHz */ - PCDR0 = temp; + writel(temp, MX21_CCM_BASE_ADDR + MX21_PCDR0); return 0; } @@ -193,7 +193,6 @@ console_initcall(mx21ads_console_init); #ifdef CONFIG_NAND_IMX_BOOT void __bare_init nand_boot(void) { - PCCR0 |= PCCR0_NFC_EN; imx_nand_load_image(_text, barebox_image_size); board_init_lowlevel_return(); } diff --git a/arch/arm/boards/imx21ads/lowlevel_init.S b/arch/arm/boards/imx21ads/lowlevel_init.S index 0cb8aaf950..e52cac1443 100644 --- a/arch/arm/boards/imx21ads/lowlevel_init.S +++ b/arch/arm/boards/imx21ads/lowlevel_init.S @@ -15,7 +15,7 @@ #include <config.h> #include <asm-generic/memory_layout.h> -#include <mach/imx-regs.h> +#include <mach/imx21-regs.h> #include <asm/barebox-arm-head.h> .section ".text_bare_init","ax" @@ -30,17 +30,17 @@ reset: * on chip peripherals) as described in section 7.2 of rev3 of the i.MX21 * reference manual. */ - ldr r0, =AIPI1_PSR0 + ldr r0, =MX21_AIPI_BASE_ADDR + MX21_AIPI1_PSR0 ldr r1, =0x00040304 str r1, [r0] - ldr r0, =AIPI1_PSR1 + ldr r0, =MX21_AIPI_BASE_ADDR + MX21_AIPI1_PSR1 ldr r1, =0xfffbfcfb str r1, [r0] - ldr r0, =AIPI2_PSR0 + ldr r0, =MX21_AIPI_BASE_ADDR + MX21_AIPI2_PSR0 ldr r1, =0x3ffc0000 str r1, [r0] - ldr r0, =AIPI2_PSR1 + ldr r0, =MX21_AIPI_BASE_ADDR + MX21_AIPI2_PSR1 ldr r1, =0xffffffff str r1, [r0] @@ -48,11 +48,11 @@ reset: * Configure CPU core clock (266MHz), peripheral clock (133MHz) and enable * the clock to peripherals. */ - ldr r0, =CSCR + ldr r0, =MX21_CCM_BASE_ADDR + MX21_CSCR ldr r1, =0x17180607 str r1, [r0] - ldr r0, =PCCR1 + ldr r0, =MX21_CCM_BASE_ADDR + MX21_PCCR1 ldr r1, =0x0e000000 str r1, [r0] @@ -65,7 +65,7 @@ reset: * CSD1 not required, because the MX21ADS board only contains 64Mbyte. * CS3 can therefore be made available. */ - ldr r0, =FMCR + ldr r0, =MX21_SYSCTRL_BASE_ADDR + MX21_FMCR ldr r1, =0xffffffc9 str r1, [r0] @@ -79,7 +79,7 @@ reset: 1: /* Precharge */ - ldr r0, =SDCTL0 + ldr r0, =MX21_X_MEMC_BASE_ADDR + MX21_SDCTL0 ldr r1, =0x92120300 str r1, [r0] ldr r2, =0xc0200000 @@ -113,7 +113,7 @@ reset: str r1, [r0] /* Set NFC_CLK to 24MHz */ - ldr r0, =PCDR0 + ldr r0, =MX21_CCM_BASE_ADDR + MX21_PCDR0 ldr r1, =0x6419a007 str r1, [r0] diff --git a/arch/arm/boards/imx27ads/imx27ads.c b/arch/arm/boards/imx27ads/imx27ads.c index 22c6e40f9f..f41b155d16 100644 --- a/arch/arm/boards/imx27ads/imx27ads.c +++ b/arch/arm/boards/imx27ads/imx27ads.c @@ -18,7 +18,7 @@ #include <net.h> #include <init.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> #include <asm/armlinux.h> #include <io.h> #include <fec.h> diff --git a/arch/arm/boards/imx27ads/lowlevel_init.S b/arch/arm/boards/imx27ads/lowlevel_init.S index 1bebb1d0a4..2dc34b5967 100644 --- a/arch/arm/boards/imx27ads/lowlevel_init.S +++ b/arch/arm/boards/imx27ads/lowlevel_init.S @@ -5,7 +5,7 @@ */ #include <config.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> #include <asm/barebox-arm-head.h> #define writel(val, reg) \ @@ -118,13 +118,13 @@ reset: common_reset r0 /* ahb lite ip interface */ - writel(0x20040304, AIPI1_PSR0) - writel(0xDFFBFCFB, AIPI1_PSR1) - writel(0x00000000, AIPI2_PSR0) - writel(0xFFFFFFFF, AIPI2_PSR1) + writel(0x20040304, MX27_AIPI_BASE_ADDR + MX27_AIPI1_PSR0) + writel(0xDFFBFCFB, MX27_AIPI_BASE_ADDR + MX27_AIPI1_PSR1) + writel(0x00000000, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR0) + writel(0xFFFFFFFF, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR1) /* disable mpll/spll */ - ldr r0, =CSCR + ldr r0, =MX27_CCM_BASE_ADDR + MX27_CSCR ldr r1, [r0] bic r1, r1, #0x03 str r1, [r0] @@ -136,15 +136,16 @@ reset: * with 1.2 V core voltage! Find out if this is * documented somewhere. */ - writel(0x00191403, MPCTL0) /* MPLL = 199.5*2 MHz */ - writel(0x040C2403, SPCTL0) /* SPLL = FIXME (needs review) */ + writel(0x00191403, MX27_CCM_BASE_ADDR + MX27_MPCTL0) /* MPLL = 199.5*2 MHz */ + writel(0x040C2403, MX27_CCM_BASE_ADDR + MX27_SPCTL0) /* SPLL = FIXME (needs review) */ /* * ARM clock = (399 MHz / 2) / (ARM divider = 1) = 200 MHz * AHB clock = (399 MHz / 3) / (AHB divider = 2) = 66.5 MHz * System clock (HCLK) = 133 MHz */ - writel(0x33F30307 | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART, CSCR) + writel(0x33F30307 | MX27_CSCR_MPLL_RESTART | MX27_CSCR_SPLL_RESTART, + MX27_CCM_BASE_ADDR + MX27_CSCR) /* add some delay here */ mov r1, #0x1000 @@ -152,13 +153,14 @@ reset: bne 1b /* clock gating enable */ - writel(0x00050f08, GPCR) + writel(0x00050f08, MX27_SYSCTRL_BASE_ADDR + MX27_GPCR) /* peripheral clock divider */ - writel(0x23C8F403, PCDR0) /* FIXME */ - writel(0x09030913, PCDR1) /* PERDIV1=08 @133 MHz */ - /* PERDIV1=04 @266 MHz * - * / + /* FIXME */ + writel(0x23C8F403, MX27_CCM_BASE_ADDR + MX27_PCDR0) + /* PERDIV1=08 @133 MHz */ + /* PERDIV1=04 @266 MHz */ + writel(0x09030913, MX27_CCM_BASE_ADDR + MX27_PCDR1) /* skip sdram initialization if we run from ram */ cmp pc, #0xa0000000 bls 1f diff --git a/arch/arm/boards/karo-tx25/board.c b/arch/arm/boards/karo-tx25/board.c index 5413ea801c..1ffd890dd6 100644 --- a/arch/arm/boards/karo-tx25/board.c +++ b/arch/arm/boards/karo-tx25/board.c @@ -21,7 +21,7 @@ #include <init.h> #include <driver.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx25-regs.h> #include <asm/armlinux.h> #include <asm-generic/sections.h> #include <asm/barebox-arm.h> @@ -75,8 +75,8 @@ static iomux_v3_cfg_t karo_tx25_padsd_fec[] = { MX25_PAD_FEC_TX_CLK__FEC_TX_CLK, }; -#define TX25_FEC_PWR_GPIO (GPIO_PORTD | 9) -#define TX25_FEC_RST_GPIO (GPIO_PORTD | 7) +#define TX25_FEC_PWR_GPIO IMX_GPIO_NR(4, 9) +#define TX25_FEC_RST_GPIO IMX_GPIO_NR(4, 7) static void noinline gpio_fec_active(void) { @@ -108,7 +108,7 @@ static int tx25_devices_init(void) imx25_iim_register_fec_ethaddr(); imx25_add_fec(&fec_info); - if (readl(MX25_CCM_BASE_ADDR + CCM_RCSR) & (1 << 14)) + if (readl(MX25_CCM_BASE_ADDR + MX25_CCM_RCSR) & (1 << 14)) nand_info.width = 2; imx25_add_nand(&nand_info); @@ -217,9 +217,9 @@ static struct imx_fb_videomode stk5_fb_mode = { .pcr = PCR_TFT | PCR_COLOR | PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL, }; -#define STK5_LCD_BACKLIGHT_GPIO (GPIO_PORTA | 26) -#define STK5_LCD_RESET_GPIO (GPIO_PORTB | 4) -#define STK5_LCD_POWER_GPIO (GPIO_PORTB | 5) +#define STK5_LCD_BACKLIGHT_GPIO IMX_GPIO_NR(1, 26) +#define STK5_LCD_RESET_GPIO IMX_GPIO_NR(2, 4) +#define STK5_LCD_POWER_GPIO IMX_GPIO_NR(2, 5) static void tx25_fb_enable(int enable) { diff --git a/arch/arm/boards/karo-tx25/lowlevel.c b/arch/arm/boards/karo-tx25/lowlevel.c index 3192abdeb6..9c5cc5c8ee 100644 --- a/arch/arm/boards/karo-tx25/lowlevel.c +++ b/arch/arm/boards/karo-tx25/lowlevel.c @@ -18,7 +18,7 @@ */ #include <common.h> #include <init.h> -#include <mach/imx-regs.h> +#include <mach/imx25-regs.h> #include <mach/esdctl.h> #include <io.h> #include <mach/imx-nand.h> @@ -34,8 +34,7 @@ static void __bare_init __naked insdram(void) uint32_t r; /* setup a stack to be able to call imx_nand_load_image() */ - r = STACK_BASE + STACK_SIZE - 12; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); imx_nand_load_image(_text, barebox_image_size); @@ -46,8 +45,8 @@ static void __bare_init __naked insdram(void) static inline void __bare_init setup_sdram(uint32_t base, uint32_t esdctl, uint32_t esdcfg) { - uint32_t esdctlreg = ESDCTL0; - uint32_t esdcfgreg = ESDCFG0; + uint32_t esdctlreg = MX25_ESDCTL_BASE_ADDR + IMX_ESDCTL0; + uint32_t esdcfgreg = MX25_ESDCTL_BASE_ADDR + IMX_ESDCFG0; if (base == 0x90000000) { esdctlreg += 8; @@ -122,12 +121,12 @@ void __bare_init __naked reset(void) writel(0x1, 0xb8003000); /* configure ARM clk */ - writel(0x20034000, MX25_CCM_BASE_ADDR + CCM_CCTL); + writel(0x20034000, MX25_CCM_BASE_ADDR + MX25_CCM_CCTL); /* enable all the clocks */ - writel(0x1fffffff, MX25_CCM_BASE_ADDR + CCM_CGCR0); - writel(0xffffffff, MX25_CCM_BASE_ADDR + CCM_CGCR1); - writel(0x000fdfff, MX25_CCM_BASE_ADDR + CCM_CGCR2); + writel(0x1fffffff, MX25_CCM_BASE_ADDR + MX25_CCM_CGCR0); + writel(0xffffffff, MX25_CCM_BASE_ADDR + MX25_CCM_CGCR1); + writel(0x000fdfff, MX25_CCM_BASE_ADDR + MX25_CCM_CGCR2); /* Skip SDRAM initialization if we run from RAM */ r = get_pc(); @@ -137,9 +136,9 @@ void __bare_init __naked reset(void) /* set to 3.3v SDRAM */ writel(0x800, MX25_IOMUXC_BASE_ADDR + 0x454); - writel(ESDMISC_RST, ESDMISC); + writel(ESDMISC_RST, MX25_ESDCTL_BASE_ADDR + IMX_ESDMISC); - while (!(readl(ESDMISC) & (1 << 31))); + while (!(readl(MX25_ESDCTL_BASE_ADDR + IMX_ESDMISC) & (1 << 31))); #define ESDCTLVAL (ESDCTL0_ROW13 | ESDCTL0_COL9 | ESDCTL0_DSIZ_15_0 | \ ESDCTL0_REF4 | ESDCTL0_PWDT_PRECHARGE_PWDN | ESDCTL0_BL) diff --git a/arch/arm/boards/karo-tx28/tx28-stk5.c b/arch/arm/boards/karo-tx28/tx28-stk5.c index 961787669b..766e77b247 100644 --- a/arch/arm/boards/karo-tx28/tx28-stk5.c +++ b/arch/arm/boards/karo-tx28/tx28-stk5.c @@ -393,7 +393,7 @@ void base_board_init(void) tx28_get_ethaddr(); imx_enable_enetclk(); - add_generic_device("fec_imx", 0, NULL, IMX_FEC0_BASE, 0x4000, + add_generic_device("imx28-fec", 0, NULL, IMX_FEC0_BASE, 0x4000, IORESOURCE_MEM, &fec_info); ret = register_persistent_environment(); diff --git a/arch/arm/boards/karo-tx51/tx51.c b/arch/arm/boards/karo-tx51/tx51.c index 3ee0ebd66e..dd377c140a 100644 --- a/arch/arm/boards/karo-tx51/tx51.c +++ b/arch/arm/boards/karo-tx51/tx51.c @@ -18,7 +18,7 @@ #include <common.h> #include <init.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx51-regs.h> #include <fec.h> #include <mach/gpio.h> #include <asm/armlinux.h> diff --git a/arch/arm/boards/karo-tx53/Makefile b/arch/arm/boards/karo-tx53/Makefile index b56ce7f50d..2f45976184 100644 --- a/arch/arm/boards/karo-tx53/Makefile +++ b/arch/arm/boards/karo-tx53/Makefile @@ -1,2 +1,5 @@ obj-y += board.o obj-y += flash_header.o +pbl-y += flash_header.o +obj-y += lowlevel.o +pbl-y += lowlevel.o diff --git a/arch/arm/boards/karo-tx53/board.c b/arch/arm/boards/karo-tx53/board.c index c8509bebcb..8f87c9c9a8 100644 --- a/arch/arm/boards/karo-tx53/board.c +++ b/arch/arm/boards/karo-tx53/board.c @@ -25,7 +25,7 @@ #include <generated/mach-types.h> -#include <mach/imx-regs.h> +#include <mach/imx53-regs.h> #include <mach/iomux-mx53.h> #include <mach/devices-imx53.h> #include <mach/generic.h> @@ -33,6 +33,8 @@ #include <mach/imx-nand.h> #include <mach/iim.h> #include <mach/imx5.h> +#include <mach/imx-flash-header.h> +#include <mach/bbu.h> #include <asm/armlinux.h> #include <io.h> @@ -99,7 +101,10 @@ static iomux_v3_cfg_t tx53_pads[] = { static int tx53_mem_init(void) { - arm_add_mem_device("ram0", 0x70000000, SZ_1G); + if (IS_ENABLED(CONFIG_TX53_REV_1011)) + arm_add_mem_device("ram0", 0x70000000, SZ_1G); + else + arm_add_mem_device("ram0", 0x70000000, SZ_512M); return 0; } @@ -203,6 +208,14 @@ static inline void tx53_fec_init(void) ARRAY_SIZE(tx53_fec_pads)); } +#define DCD_NAME_1011 static struct imx_dcd_v2_entry dcd_entry_1011 + +#include "dcd-data-1011.h" + +#define DCD_NAME_XX30 static u32 dcd_entry_xx30 + +#include "dcd-data-xx30.h" + static int tx53_devices_init(void) { imx53_iim_register_fec_ethaddr(); @@ -214,6 +227,14 @@ static int tx53_devices_init(void) armlinux_set_bootparams((void *)0x70000100); armlinux_set_architecture(MACH_TYPE_TX53); + /* rev xx30 can boot from nand or USB */ + imx53_bbu_internal_nand_register_handler("nand-xx30", + BBU_HANDLER_FLAG_DEFAULT, (void *)dcd_entry_xx30, sizeof(dcd_entry_xx30), SZ_512K); + + /* rev 1011 can boot from MMC/SD, other bootsource currently unknown */ + imx53_bbu_internal_mmc_register_handler("mmc-1011", "/dev/disk0", + 0, (void *)dcd_entry_1011, sizeof(dcd_entry_1011)); + return 0; } @@ -221,8 +242,25 @@ device_initcall(tx53_devices_init); static int tx53_part_init(void) { - devfs_add_partition("disk0", 0x00000, SZ_512K, DEVFS_PARTITION_FIXED, "self0"); - devfs_add_partition("disk0", SZ_512K, SZ_1M, DEVFS_PARTITION_FIXED, "env0"); + const char *envdev; + + switch (imx_bootsource()) { + case bootsource_mmc: + devfs_add_partition("disk0", 0x00000, SZ_512K, DEVFS_PARTITION_FIXED, "self0"); + devfs_add_partition("disk0", SZ_512K, SZ_1M, DEVFS_PARTITION_FIXED, "env0"); + envdev = "MMC"; + break; + case bootsource_nand: + default: + devfs_add_partition("nand0", 0x00000, 0x80000, DEVFS_PARTITION_FIXED, "self_raw"); + dev_add_bb_dev("self_raw", "self0"); + devfs_add_partition("nand0", 0x80000, 0x100000, DEVFS_PARTITION_FIXED, "env_raw"); + dev_add_bb_dev("env_raw", "env0"); + envdev = "NAND"; + break; + } + + printf("Using environment in %s\n", envdev); return 0; } @@ -232,7 +270,8 @@ static int tx53_console_init(void) { mxc_iomux_v3_setup_multiple_pads(tx53_pads, ARRAY_SIZE(tx53_pads)); - imx53_init_lowlevel(1000); + if (!IS_ENABLED(CONFIG_TX53_REV_XX30)) + imx53_init_lowlevel(1000); imx53_add_uart0(); return 0; diff --git a/arch/arm/boards/karo-tx53/dcd-data-1011.h b/arch/arm/boards/karo-tx53/dcd-data-1011.h new file mode 100644 index 0000000000..7034ff80de --- /dev/null +++ b/arch/arm/boards/karo-tx53/dcd-data-1011.h @@ -0,0 +1,94 @@ +DCD_NAME_1011[] = { + { .addr = cpu_to_be32(0x53fd406c), .val = cpu_to_be32(0xffffffff), }, + { .addr = cpu_to_be32(0x53fd4070), .val = cpu_to_be32(0xffffffff), }, + { .addr = cpu_to_be32(0x53fd4074), .val = cpu_to_be32(0xffffffff), }, + { .addr = cpu_to_be32(0x53fd4078), .val = cpu_to_be32(0xffffffff), }, + { .addr = cpu_to_be32(0x53fd407c), .val = cpu_to_be32(0xffffffff), }, + { .addr = cpu_to_be32(0x53fd4080), .val = cpu_to_be32(0xffffffff), }, + { .addr = cpu_to_be32(0x53fd4088), .val = cpu_to_be32(0xffffffff), }, + { .addr = cpu_to_be32(0x53fa8174), .val = cpu_to_be32(0x00000011), }, + { .addr = cpu_to_be32(0x63fd800c), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa8554), .val = cpu_to_be32(0x00200000), }, + { .addr = cpu_to_be32(0x53fa8560), .val = cpu_to_be32(0x00200000), }, + { .addr = cpu_to_be32(0x53fa8594), .val = cpu_to_be32(0x00200000), }, + { .addr = cpu_to_be32(0x53fa8584), .val = cpu_to_be32(0x00200000), }, + { .addr = cpu_to_be32(0x53fa8558), .val = cpu_to_be32(0x00200040), }, + { .addr = cpu_to_be32(0x53fa8568), .val = cpu_to_be32(0x00200040), }, + { .addr = cpu_to_be32(0x53fa8590), .val = cpu_to_be32(0x00200040), }, + { .addr = cpu_to_be32(0x53fa857c), .val = cpu_to_be32(0x00200040), }, + { .addr = cpu_to_be32(0x53fa8564), .val = cpu_to_be32(0x00200040), }, + { .addr = cpu_to_be32(0x53fa8580), .val = cpu_to_be32(0x00200040), }, + { .addr = cpu_to_be32(0x53fa8570), .val = cpu_to_be32(0x00200000), }, + { .addr = cpu_to_be32(0x53fa8578), .val = cpu_to_be32(0x00200000), }, + { .addr = cpu_to_be32(0x53fa872c), .val = cpu_to_be32(0x00200000), }, + { .addr = cpu_to_be32(0x53fa8728), .val = cpu_to_be32(0x00200000), }, + { .addr = cpu_to_be32(0x53fa871c), .val = cpu_to_be32(0x00200000), }, + { .addr = cpu_to_be32(0x53fa8718), .val = cpu_to_be32(0x00200000), }, + { .addr = cpu_to_be32(0x53fa8574), .val = cpu_to_be32(0x00280000), }, + { .addr = cpu_to_be32(0x53fa8588), .val = cpu_to_be32(0x00280000), }, + { .addr = cpu_to_be32(0x53fa86f0), .val = cpu_to_be32(0x00280000), }, + { .addr = cpu_to_be32(0x53fa8720), .val = cpu_to_be32(0x00280000), }, + { .addr = cpu_to_be32(0x53fa86fc), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa86f4), .val = cpu_to_be32(0x00000200), }, + { .addr = cpu_to_be32(0x53fa8714), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa8724), .val = cpu_to_be32(0x06000000), }, + { .addr = cpu_to_be32(0x63fd9088), .val = cpu_to_be32(0x36353b38), }, + { .addr = cpu_to_be32(0x63fd9090), .val = cpu_to_be32(0x49434942), }, + { .addr = cpu_to_be32(0x63fd90f8), .val = cpu_to_be32(0x00000800), }, + { .addr = cpu_to_be32(0x63fd907c), .val = cpu_to_be32(0x01350138), }, + { .addr = cpu_to_be32(0x63fd9080), .val = cpu_to_be32(0x01380139), }, + { .addr = cpu_to_be32(0x63fd9018), .val = cpu_to_be32(0x00001710), }, + { .addr = cpu_to_be32(0x63fd9000), .val = cpu_to_be32(0x84110000), }, + { .addr = cpu_to_be32(0x63fd900c), .val = cpu_to_be32(0x4d5122d2), }, + { .addr = cpu_to_be32(0x63fd9010), .val = cpu_to_be32(0xb6f18a22), }, + { .addr = cpu_to_be32(0x63fd9014), .val = cpu_to_be32(0x00c700db), }, + { .addr = cpu_to_be32(0x63fd902c), .val = cpu_to_be32(0x000026d2), }, + { .addr = cpu_to_be32(0x63fd9030), .val = cpu_to_be32(0x009f000e), }, + { .addr = cpu_to_be32(0x63fd9008), .val = cpu_to_be32(0x12272000), }, + { .addr = cpu_to_be32(0x63fd9004), .val = cpu_to_be32(0x00030012), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x04008010), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008020), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008020), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x0a528030), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x03868031), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00068031), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008032), }, + { .addr = cpu_to_be32(0x63fd9020), .val = cpu_to_be32(0x00005800), }, + { .addr = cpu_to_be32(0x63fd9058), .val = cpu_to_be32(0x00033332), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00448031), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x04008018), }, + { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x63fd9040), .val = cpu_to_be32(0x04b80003), }, + { .addr = cpu_to_be32(0x53fa8004), .val = cpu_to_be32(0x00194005), }, + { .addr = cpu_to_be32(0x53fa819c), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa81a0), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa81a4), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa81a8), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa81ac), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa81b0), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa81b4), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa81b8), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa81dc), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa81e0), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa8228), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa822c), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa8230), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa8234), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa8238), .val = cpu_to_be32(0x00000000), }, + { .addr = cpu_to_be32(0x53fa84ec), .val = cpu_to_be32(0x000000e4), }, + { .addr = cpu_to_be32(0x53fa84f0), .val = cpu_to_be32(0x000000e4), }, + { .addr = cpu_to_be32(0x53fa84f4), .val = cpu_to_be32(0x000000e4), }, + { .addr = cpu_to_be32(0x53fa84f8), .val = cpu_to_be32(0x000000e4), }, + { .addr = cpu_to_be32(0x53fa84fc), .val = cpu_to_be32(0x000000e4), }, + { .addr = cpu_to_be32(0x53fa8500), .val = cpu_to_be32(0x000000e4), }, + { .addr = cpu_to_be32(0x53fa8504), .val = cpu_to_be32(0x000000e4), }, + { .addr = cpu_to_be32(0x53fa8508), .val = cpu_to_be32(0x000000e4), }, + { .addr = cpu_to_be32(0x53fa852c), .val = cpu_to_be32(0x00000004), }, + { .addr = cpu_to_be32(0x53fa8530), .val = cpu_to_be32(0x00000004), }, + { .addr = cpu_to_be32(0x53fa85a0), .val = cpu_to_be32(0x00000004), }, + { .addr = cpu_to_be32(0x53fa85a4), .val = cpu_to_be32(0x00000004), }, + { .addr = cpu_to_be32(0x53fa85a8), .val = cpu_to_be32(0x000000e4), }, + { .addr = cpu_to_be32(0x53fa85ac), .val = cpu_to_be32(0x000000e4), }, + { .addr = cpu_to_be32(0x53fa85b0), .val = cpu_to_be32(0x00000004), }, +}; diff --git a/arch/arm/boards/karo-tx53/dcd-data-xx30.h b/arch/arm/boards/karo-tx53/dcd-data-xx30.h new file mode 100644 index 0000000000..cb982dc2e3 --- /dev/null +++ b/arch/arm/boards/karo-tx53/dcd-data-xx30.h @@ -0,0 +1,144 @@ + +#define DCD_ITEM(adr, val) cpu_to_be32(adr), cpu_to_be32(val) +#define DCD_WR_CMD(len) cpu_to_be32(0xcc << 24 | (len) << 8 | 0x04) +#define DCD_CHECK_CMD(a, b, c) cpu_to_be32(a), cpu_to_be32(b), cpu_to_be32(c) + +/* + * This board uses advanced features of the DCD which do not corporate + * well with our flash header defines. The DCD consists of commands which + * have the length econded into them. Normally the DCDs only have a single + * command (DCD_COMMAND_WRITE_TAG) which is already part of struct + * imx_flash_header_v2. Now this board uses multiple commands, so we cannot + * calculate the command length using sizeof(dcd_entry). + */ + +DCD_NAME_XX30[] = { + DCD_ITEM(0x53fd4068, 0xffcc0fff), + DCD_ITEM(0x53fd406c, 0x000fffc3), + DCD_ITEM(0x53fd4070, 0x033c0000), + DCD_ITEM(0x53fd4074, 0x00000000), + DCD_ITEM(0x53fd4078, 0x00000000), + DCD_ITEM(0x53fd407c, 0x00fff033), + DCD_ITEM(0x53fd4080, 0x0f00030f), + DCD_ITEM(0x53fd4084, 0xfff00000), + DCD_ITEM(0x53fd4088, 0x00000000), + DCD_ITEM(0x53fa8174, 0x00000011), + DCD_ITEM(0x53fa8318, 0x00000011), + DCD_ITEM(0x63fd800c, 0x00000000), + DCD_ITEM(0x53fd4014, 0x00888944), + DCD_ITEM(0x53fd4018, 0x00016154), + DCD_ITEM(0x53fa8724, 0x04000000), + DCD_ITEM(0x53fa86f4, 0x00000000), + DCD_ITEM(0x53fa8714, 0x00000000), + DCD_ITEM(0x53fa86fc, 0x00000080), + DCD_ITEM(0x53fa8710, 0x00000000), + DCD_ITEM(0x53fa8708, 0x00000040), + DCD_ITEM(0x53fa8584, 0x00280000), + DCD_ITEM(0x53fa8594, 0x00280000), + DCD_ITEM(0x53fa8560, 0x00280000), + DCD_ITEM(0x53fa8554, 0x00280000), + DCD_ITEM(0x53fa857c, 0x00a80040), + DCD_ITEM(0x53fa8590, 0x00a80040), + DCD_ITEM(0x53fa8568, 0x00a80040), + DCD_ITEM(0x53fa8558, 0x00a80040), + DCD_ITEM(0x53fa8580, 0x00280040), + DCD_ITEM(0x53fa8578, 0x00280000), + DCD_ITEM(0x53fa8564, 0x00280040), + DCD_ITEM(0x53fa8570, 0x00280000), + DCD_ITEM(0x53fa858c, 0x000000c0), + DCD_ITEM(0x53fa855c, 0x000000c0), + DCD_ITEM(0x53fa8574, 0x00280000), + DCD_ITEM(0x53fa8588, 0x00280000), + DCD_ITEM(0x53fa86f0, 0x00280000), + DCD_ITEM(0x53fa8720, 0x00280000), + DCD_ITEM(0x53fa8718, 0x00280000), + DCD_ITEM(0x53fa871c, 0x00280000), + DCD_ITEM(0x53fa8728, 0x00280000), + DCD_ITEM(0x53fa872c, 0x00280000), + DCD_ITEM(0x63fd904c, 0x001f001f), + DCD_ITEM(0x63fd9050, 0x001f001f), + DCD_ITEM(0x63fd907c, 0x011e011e), + DCD_ITEM(0x63fd9080, 0x011f0120), + DCD_ITEM(0x63fd9088, 0x3a393d3b), + DCD_ITEM(0x63fd9090, 0x3f3f3f3f), + DCD_ITEM(0x63fd9018, 0x00011740), + DCD_ITEM(0x63fd9000, 0x83190000), + DCD_ITEM(0x63fd900c, 0x3f435316), + DCD_ITEM(0x63fd9010, 0xb66e0a63), + DCD_ITEM(0x63fd9014, 0x01ff00db), + DCD_ITEM(0x63fd902c, 0x000026d2), + DCD_ITEM(0x63fd9030, 0x00430f24), + DCD_ITEM(0x63fd9008, 0x1b221010), + DCD_ITEM(0x63fd9004, 0x00030012), + DCD_ITEM(0x63fd901c, 0x00008032), + DCD_ITEM(0x63fd901c, 0x00008033), + DCD_ITEM(0x63fd901c, 0x00408031), + DCD_ITEM(0x63fd901c, 0x055080b0), + DCD_ITEM(0x63fd9020, 0x00005800), + DCD_ITEM(0x63fd9058, 0x00011112), + DCD_ITEM(0x63fd90d0, 0x00000003), + DCD_ITEM(0x63fd901c, 0x04008010), + DCD_ITEM(0x63fd901c, 0x00008040), + DCD_ITEM(0x63fd9040, 0x0539002b), + DCD_CHECK_CMD(0xcf000c04, 0x63fd9040, 0x00010000), + DCD_WR_CMD(0x24), + DCD_ITEM(0x63fd901c, 0x00048033), + DCD_ITEM(0x63fd901c, 0x00848231), + DCD_ITEM(0x63fd901c, 0x00000000), + DCD_ITEM(0x63fd9048, 0x00000001), + DCD_CHECK_CMD(0xcf000c04, 0x63fd9048, 0x00000001), + DCD_WR_CMD(0x2c), + DCD_ITEM(0x63fd901c, 0x00048031), + DCD_ITEM(0x63fd901c, 0x00008033), + DCD_ITEM(0x63fd901c, 0x04008010), + DCD_ITEM(0x63fd901c, 0x00048033), + DCD_ITEM(0x63fd907c, 0x90000000), + DCD_CHECK_CMD(0xcf000c04, 0x63fd907c, 0x90000000), + DCD_WR_CMD(0x2c), + DCD_ITEM(0x63fd901c, 0x00008033), + DCD_ITEM(0x63fd901c, 0x00000000), + DCD_ITEM(0x63fd901c, 0x04008010), + DCD_ITEM(0x63fd901c, 0x00048033), + DCD_ITEM(0x63fd90a4, 0x00000010), + DCD_CHECK_CMD(0xcf000c04, 0x63fd90a4, 0x00000010), + DCD_WR_CMD(0x24), + DCD_ITEM(0x63fd901c, 0x00008033), + DCD_ITEM(0x63fd901c, 0x04008010), + DCD_ITEM(0x63fd901c, 0x00048033), + DCD_ITEM(0x63fd90a0, 0x00000010), + DCD_CHECK_CMD(0xcf000c04, 0x63fd90a0, 0x00000010), + DCD_WR_CMD(0x010c), + DCD_ITEM(0x63fd901c, 0x00008033), + DCD_ITEM(0x63fd901c, 0x00000000), + DCD_ITEM(0x53fa8004, 0x00194005), + DCD_ITEM(0x53fa819c, 0x00000000), + DCD_ITEM(0x53fa81a0, 0x00000000), + DCD_ITEM(0x53fa81a4, 0x00000000), + DCD_ITEM(0x53fa81a8, 0x00000000), + DCD_ITEM(0x53fa81ac, 0x00000000), + DCD_ITEM(0x53fa81b0, 0x00000000), + DCD_ITEM(0x53fa81b4, 0x00000000), + DCD_ITEM(0x53fa81b8, 0x00000000), + DCD_ITEM(0x53fa81dc, 0x00000000), + DCD_ITEM(0x53fa81e0, 0x00000000), + DCD_ITEM(0x53fa8228, 0x00000000), + DCD_ITEM(0x53fa822c, 0x00000000), + DCD_ITEM(0x53fa8230, 0x00000000), + DCD_ITEM(0x53fa8234, 0x00000000), + DCD_ITEM(0x53fa8238, 0x00000000), + DCD_ITEM(0x53fa84ec, 0x000000e4), + DCD_ITEM(0x53fa84f0, 0x000000e4), + DCD_ITEM(0x53fa84f4, 0x000000e4), + DCD_ITEM(0x53fa84f8, 0x000000e4), + DCD_ITEM(0x53fa84fc, 0x000000e4), + DCD_ITEM(0x53fa8500, 0x000000e4), + DCD_ITEM(0x53fa8504, 0x000000e4), + DCD_ITEM(0x53fa8508, 0x000000e4), + DCD_ITEM(0x53fa852c, 0x00000004), + DCD_ITEM(0x53fa8530, 0x00000004), + DCD_ITEM(0x53fa85a0, 0x00000004), + DCD_ITEM(0x53fa85a4, 0x00000004), + DCD_ITEM(0x53fa85a8, 0x000000e4), + DCD_ITEM(0x53fa85ac, 0x000000e4), + DCD_ITEM(0x53fa85b0, 0x00000004), +}; diff --git a/arch/arm/boards/karo-tx53/env/init/bootargs-base b/arch/arm/boards/karo-tx53/env/init/bootargs-base deleted file mode 100644 index d86975406e..0000000000 --- a/arch/arm/boards/karo-tx53/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/karo-tx53/env/init/config-board b/arch/arm/boards/karo-tx53/env/init/config-board new file mode 100644 index 0000000000..3ebfac6c9b --- /dev/null +++ b/arch/arm/boards/karo-tx53/env/init/config-board @@ -0,0 +1,7 @@ +#!/bin/sh + +# board defaults, do not change in running system. Change /env/config +# instead + +global.hostname=tx53 +global.linux.bootargs.base="console=ttymxc0,115200" diff --git a/arch/arm/boards/karo-tx53/env/init/hostname b/arch/arm/boards/karo-tx53/env/init/hostname deleted file mode 100644 index 2de91305e5..0000000000 --- a/arch/arm/boards/karo-tx53/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=tx53 diff --git a/arch/arm/boards/karo-tx53/flash_header.c b/arch/arm/boards/karo-tx53/flash_header.c index 9b97fab2df..5c6aa53e47 100644 --- a/arch/arm/boards/karo-tx53/flash_header.c +++ b/arch/arm/boards/karo-tx53/flash_header.c @@ -20,109 +20,31 @@ void __naked __flash_header_start go(void) { - barebox_arm_head(); + barebox_arm_imx_fcb_head(); } /* * FIXME: These are the dcd values for a Ka-Ro TX53 1011 which * is not in production. It has 1GB DDR2 memory. */ -struct imx_dcd_v2_entry __dcd_entry_section dcd_entry[] = { - { .addr = cpu_to_be32(0x53fd406c), .val = cpu_to_be32(0xffffffff), }, - { .addr = cpu_to_be32(0x53fd4070), .val = cpu_to_be32(0xffffffff), }, - { .addr = cpu_to_be32(0x53fd4074), .val = cpu_to_be32(0xffffffff), }, - { .addr = cpu_to_be32(0x53fd4078), .val = cpu_to_be32(0xffffffff), }, - { .addr = cpu_to_be32(0x53fd407c), .val = cpu_to_be32(0xffffffff), }, - { .addr = cpu_to_be32(0x53fd4080), .val = cpu_to_be32(0xffffffff), }, - { .addr = cpu_to_be32(0x53fd4088), .val = cpu_to_be32(0xffffffff), }, - { .addr = cpu_to_be32(0x53fa8174), .val = cpu_to_be32(0x00000011), }, - { .addr = cpu_to_be32(0x63fd800c), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa8554), .val = cpu_to_be32(0x00200000), }, - { .addr = cpu_to_be32(0x53fa8560), .val = cpu_to_be32(0x00200000), }, - { .addr = cpu_to_be32(0x53fa8594), .val = cpu_to_be32(0x00200000), }, - { .addr = cpu_to_be32(0x53fa8584), .val = cpu_to_be32(0x00200000), }, - { .addr = cpu_to_be32(0x53fa8558), .val = cpu_to_be32(0x00200040), }, - { .addr = cpu_to_be32(0x53fa8568), .val = cpu_to_be32(0x00200040), }, - { .addr = cpu_to_be32(0x53fa8590), .val = cpu_to_be32(0x00200040), }, - { .addr = cpu_to_be32(0x53fa857c), .val = cpu_to_be32(0x00200040), }, - { .addr = cpu_to_be32(0x53fa8564), .val = cpu_to_be32(0x00200040), }, - { .addr = cpu_to_be32(0x53fa8580), .val = cpu_to_be32(0x00200040), }, - { .addr = cpu_to_be32(0x53fa8570), .val = cpu_to_be32(0x00200000), }, - { .addr = cpu_to_be32(0x53fa8578), .val = cpu_to_be32(0x00200000), }, - { .addr = cpu_to_be32(0x53fa872c), .val = cpu_to_be32(0x00200000), }, - { .addr = cpu_to_be32(0x53fa8728), .val = cpu_to_be32(0x00200000), }, - { .addr = cpu_to_be32(0x53fa871c), .val = cpu_to_be32(0x00200000), }, - { .addr = cpu_to_be32(0x53fa8718), .val = cpu_to_be32(0x00200000), }, - { .addr = cpu_to_be32(0x53fa8574), .val = cpu_to_be32(0x00280000), }, - { .addr = cpu_to_be32(0x53fa8588), .val = cpu_to_be32(0x00280000), }, - { .addr = cpu_to_be32(0x53fa86f0), .val = cpu_to_be32(0x00280000), }, - { .addr = cpu_to_be32(0x53fa8720), .val = cpu_to_be32(0x00280000), }, - { .addr = cpu_to_be32(0x53fa86fc), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa86f4), .val = cpu_to_be32(0x00000200), }, - { .addr = cpu_to_be32(0x53fa8714), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa8724), .val = cpu_to_be32(0x06000000), }, - { .addr = cpu_to_be32(0x63fd9088), .val = cpu_to_be32(0x36353b38), }, - { .addr = cpu_to_be32(0x63fd9090), .val = cpu_to_be32(0x49434942), }, - { .addr = cpu_to_be32(0x63fd90f8), .val = cpu_to_be32(0x00000800), }, - { .addr = cpu_to_be32(0x63fd907c), .val = cpu_to_be32(0x01350138), }, - { .addr = cpu_to_be32(0x63fd9080), .val = cpu_to_be32(0x01380139), }, - { .addr = cpu_to_be32(0x63fd9018), .val = cpu_to_be32(0x00001710), }, - { .addr = cpu_to_be32(0x63fd9000), .val = cpu_to_be32(0x84110000), }, - { .addr = cpu_to_be32(0x63fd900c), .val = cpu_to_be32(0x4d5122d2), }, - { .addr = cpu_to_be32(0x63fd9010), .val = cpu_to_be32(0xb6f18a22), }, - { .addr = cpu_to_be32(0x63fd9014), .val = cpu_to_be32(0x00c700db), }, - { .addr = cpu_to_be32(0x63fd902c), .val = cpu_to_be32(0x000026d2), }, - { .addr = cpu_to_be32(0x63fd9030), .val = cpu_to_be32(0x009f000e), }, - { .addr = cpu_to_be32(0x63fd9008), .val = cpu_to_be32(0x12272000), }, - { .addr = cpu_to_be32(0x63fd9004), .val = cpu_to_be32(0x00030012), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x04008010), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008020), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008020), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x0a528030), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x03868031), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00068031), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008032), }, - { .addr = cpu_to_be32(0x63fd9020), .val = cpu_to_be32(0x00005800), }, - { .addr = cpu_to_be32(0x63fd9058), .val = cpu_to_be32(0x00033332), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00448031), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x04008018), }, - { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x63fd9040), .val = cpu_to_be32(0x04b80003), }, - { .addr = cpu_to_be32(0x53fa8004), .val = cpu_to_be32(0x00194005), }, - { .addr = cpu_to_be32(0x53fa819c), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa81a0), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa81a4), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa81a8), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa81ac), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa81b0), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa81b4), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa81b8), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa81dc), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa81e0), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa8228), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa822c), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa8230), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa8234), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa8238), .val = cpu_to_be32(0x00000000), }, - { .addr = cpu_to_be32(0x53fa84ec), .val = cpu_to_be32(0x000000e4), }, - { .addr = cpu_to_be32(0x53fa84f0), .val = cpu_to_be32(0x000000e4), }, - { .addr = cpu_to_be32(0x53fa84f4), .val = cpu_to_be32(0x000000e4), }, - { .addr = cpu_to_be32(0x53fa84f8), .val = cpu_to_be32(0x000000e4), }, - { .addr = cpu_to_be32(0x53fa84fc), .val = cpu_to_be32(0x000000e4), }, - { .addr = cpu_to_be32(0x53fa8500), .val = cpu_to_be32(0x000000e4), }, - { .addr = cpu_to_be32(0x53fa8504), .val = cpu_to_be32(0x000000e4), }, - { .addr = cpu_to_be32(0x53fa8508), .val = cpu_to_be32(0x000000e4), }, - { .addr = cpu_to_be32(0x53fa852c), .val = cpu_to_be32(0x00000004), }, - { .addr = cpu_to_be32(0x53fa8530), .val = cpu_to_be32(0x00000004), }, - { .addr = cpu_to_be32(0x53fa85a0), .val = cpu_to_be32(0x00000004), }, - { .addr = cpu_to_be32(0x53fa85a4), .val = cpu_to_be32(0x00000004), }, - { .addr = cpu_to_be32(0x53fa85a8), .val = cpu_to_be32(0x000000e4), }, - { .addr = cpu_to_be32(0x53fa85ac), .val = cpu_to_be32(0x000000e4), }, - { .addr = cpu_to_be32(0x53fa85b0), .val = cpu_to_be32(0x00000004), }, -}; +#ifdef CONFIG_TX53_REV_1011 + +#define DCD_NAME_1011 struct imx_dcd_v2_entry __dcd_entry_section dcd_entry + +#include "dcd-data-1011.h" + +#elif defined(CONFIG_TX53_REV_XX30) + +#define DCD_NAME_XX30 u32 __dcd_entry_section dcd_entry + +#include "dcd-data-xx30.h" + +#endif + +#define APP_DEST 0x71000000 -#define APP_DEST 0x70000000 +int tx53_dcdentry_size = sizeof(dcd_entry); +void *tx53_dcd_entry = &dcd_entry; struct imx_flash_header_v2 __flash_header_section flash_header = { .header.tag = IVT_HEADER_TAG, @@ -142,6 +64,10 @@ struct imx_flash_header_v2 __flash_header_section flash_header = { .dcd.header.version = DCD_VERSION, .dcd.command.tag = DCD_COMMAND_WRITE_TAG, +#ifdef CONFIG_TX53_REV_1011 .dcd.command.length = cpu_to_be16(sizeof(struct imx_dcd_command) + sizeof(dcd_entry)), +#elif defined(CONFIG_TX53_REV_XX30) + .dcd.command.length = cpu_to_be16(0x21c), +#endif .dcd.command.param = DCD_COMMAND_WRITE_PARAM, }; diff --git a/arch/arm/boards/karo-tx53/lowlevel.c b/arch/arm/boards/karo-tx53/lowlevel.c new file mode 100644 index 0000000000..0ca164bda5 --- /dev/null +++ b/arch/arm/boards/karo-tx53/lowlevel.c @@ -0,0 +1,22 @@ +#include <common.h> +#include <asm/barebox-arm-head.h> +#include <asm/barebox-arm.h> +#include <mach/imx5.h> + +#ifdef CONFIG_MACH_DO_LOWLEVEL_INIT + +void __naked reset(void) +{ + common_reset(); + + /* + * For the TX53 rev 8030 the SDRAM setup is not stable without + * the proper PLL setup. It will crash once we enable the MMU, + * so do the PLL setup here. + */ + if (IS_ENABLED(CONFIG_TX53_REV_XX30)) + imx53_init_lowlevel(800); + + board_init_lowlevel_return(); +} +#endif diff --git a/arch/arm/boards/panda/lowlevel.c b/arch/arm/boards/panda/lowlevel.c index 33d06be29a..36e2bc5886 100644 --- a/arch/arm/boards/panda/lowlevel.c +++ b/arch/arm/boards/panda/lowlevel.c @@ -76,16 +76,12 @@ static void noinline panda_init_lowlevel(void) void reset(void) { - u32 r; - common_reset(); if (get_pc() > 0x80000000) board_init_lowlevel_return(); - r = 0x4030d000; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); + arm_setup_stack(0x4030d000); panda_init_lowlevel(); } - diff --git a/arch/arm/boards/pcm037/lowlevel_init.S b/arch/arm/boards/pcm037/lowlevel_init.S index a6747c2482..f9ecce1141 100644 --- a/arch/arm/boards/pcm037/lowlevel_init.S +++ b/arch/arm/boards/pcm037/lowlevel_init.S @@ -17,9 +17,10 @@ * */ -#include <mach/imx-regs.h> +#include <mach/imx31-regs.h> #include <mach/imx-pll.h> #include <asm/barebox-arm-head.h> +#include <mach/esdctl.h> #define writel(val, reg) \ ldr r0, =reg; \ @@ -46,24 +47,30 @@ reset: common_reset r0 - writel(0x074B0BF5, MX31_CCM_BASE_ADDR + CCM_CCMR) + writel(0x074B0BF5, MX31_CCM_BASE_ADDR + MX31_CCM_CCMR) DELAY 0x40000 - writel(0x074B0BF5 | CCMR_MPE, MX31_CCM_BASE_ADDR + CCM_CCMR) - writel((0x074B0BF5 | CCMR_MPE) & ~CCMR_MDS, MX31_CCM_BASE_ADDR + CCM_CCMR) - - writel(PDR0_CSI_PODF(0xff1) | \ - PDR0_PER_PODF(7) | \ - PDR0_HSP_PODF(3) | \ - PDR0_NFC_PODF(5) | \ - PDR0_IPG_PODF(1) | \ - PDR0_MAX_PODF(3) | \ - PDR0_MCU_PODF(0), \ - MX31_CCM_BASE_ADDR + CCM_PDR0) - - writel(IMX_PLL_PD(0) | IMX_PLL_MFD(0xe) | IMX_PLL_MFI(9) | IMX_PLL_MFN(0xd), MX31_CCM_BASE_ADDR + CCM_MPCTL) - writel(IMX_PLL_PD(1) | IMX_PLL_MFD(0x43) | IMX_PLL_MFI(12) | IMX_PLL_MFN(1), MX31_CCM_BASE_ADDR + CCM_SPCTL) + writel(0x074B0BF5 | MX31_CCMR_MPE, MX31_CCM_BASE_ADDR + + MX31_CCM_CCMR) + writel((0x074B0BF5 | MX31_CCMR_MPE) & ~MX31_CCMR_MDS, + MX31_CCM_BASE_ADDR + MX31_CCM_CCMR) + + writel(MX31_PDR0_CSI_PODF(0xff1) | \ + MX31_PDR0_PER_PODF(7) | \ + MX31_PDR0_HSP_PODF(3) | \ + MX31_PDR0_NFC_PODF(5) | \ + MX31_PDR0_IPG_PODF(1) | \ + MX31_PDR0_MAX_PODF(3) | \ + MX31_PDR0_MCU_PODF(0), \ + MX31_CCM_BASE_ADDR + MX31_CCM_PDR0) + + writel(IMX_PLL_PD(0) | IMX_PLL_MFD(0xe) | + IMX_PLL_MFI(9) | IMX_PLL_MFN(0xd), + MX31_CCM_BASE_ADDR + MX31_CCM_MPCTL) + writel(IMX_PLL_PD(1) | IMX_PLL_MFD(0x43) | IMX_PLL_MFI(12) | + IMX_PLL_MFN(1), MX31_CCM_BASE_ADDR + + MX31_CCM_SPCTL) /* Configure IOMUXC * Clears 0x43fa_c26c - 0x43fa_c2dc with 0, except 0x43fa_c278 (untouched), 0x43fa_c27c (set to 0x1000) and 0x43fa_c280 (untouched) @@ -96,19 +103,19 @@ clear_iomux: #elif defined CONFIG_PCM037_SDRAM_BANK0_256MB #define ROWS0 ESDCTL0_ROW14 #endif - writel(0x00000004, ESDMISC) - writel(0x006ac73a, ESDCFG0) - writel(0x90100000 | ROWS0, ESDCTL0) + writel(0x00000004, MX31_ESDCTL_BASE_ADDR + IMX_ESDMISC) + writel(0x006ac73a, MX31_ESDCTL_BASE_ADDR + IMX_ESDCFG0) + writel(0x90100000 | ROWS0, MX31_ESDCTL_BASE_ADDR + IMX_ESDCTL0) writel(0x12344321, MX31_CSD0_BASE_ADDR + 0xf00) - writel(0xa0100000 | ROWS0, ESDCTL0) + writel(0xa0100000 | ROWS0, MX31_ESDCTL_BASE_ADDR + IMX_ESDCTL0) writel(0x12344321, MX31_CSD0_BASE_ADDR) writel(0x12344321, MX31_CSD0_BASE_ADDR) - writel(0xb0100000 | ROWS0, ESDCTL0) + writel(0xb0100000 | ROWS0, MX31_ESDCTL_BASE_ADDR + IMX_ESDCTL0) writeb(0xda, MX31_CSD0_BASE_ADDR + 0x33) writeb(0xff, MX31_CSD0_BASE_ADDR + 0x01000000) - writel(0x80226080 | ROWS0, ESDCTL0) + writel(0x80226080 | ROWS0, MX31_ESDCTL_BASE_ADDR + IMX_ESDCTL0) writel(0xDEADBEEF, MX31_CSD0_BASE_ADDR) - writel(0x0000000c, ESDMISC) + writel(0x0000000c, MX31_ESDCTL_BASE_ADDR + IMX_ESDMISC) #ifndef CONFIG_PCM037_SDRAM_BANK1_NONE #if defined CONFIG_PCM037_SDRAM_BANK1_128MB @@ -116,18 +123,18 @@ clear_iomux: #elif defined CONFIG_PCM037_SDRAM_BANK1_256MB #define ROWS1 ESDCTL0_ROW14 #endif - writel(0x006ac73a, ESDCFG1) - writel(0x90100000 | ROWS1, ESDCTL1) + writel(0x006ac73a, MX31_ESDCTL_BASE_ADDR + IMX_ESDCFG1) + writel(0x90100000 | ROWS1, MX31_ESDCTL_BASE_ADDR + IMX_ESDCTL1) writel(0x12344321, MX31_CSD1_BASE_ADDR + 0xf00) - writel(0xa0100000 | ROWS1, ESDCTL1) + writel(0xa0100000 | ROWS1, MX31_ESDCTL_BASE_ADDR + IMX_ESDCTL1) writel(0x12344321, MX31_CSD1_BASE_ADDR) writel(0x12344321, MX31_CSD1_BASE_ADDR) - writel(0xb0100000 | ROWS1, ESDCTL1) + writel(0xb0100000 | ROWS1, MX31_ESDCTL_BASE_ADDR + IMX_ESDCTL1) writeb(0xda, MX31_CSD1_BASE_ADDR + 0x33) writeb(0xff, MX31_CSD1_BASE_ADDR + 0x01000000) - writel(0x80226080 | ROWS1, ESDCTL1) + writel(0x80226080 | ROWS1, MX31_ESDCTL_BASE_ADDR + IMX_ESDCTL1) writel(0xDEADBEEF, MX31_CSD1_BASE_ADDR) - writel(0x0000000c, ESDMISC) + writel(0x0000000c, MX31_ESDCTL_BASE_ADDR + IMX_ESDMISC) #endif #ifdef CONFIG_NAND_IMX_BOOT diff --git a/arch/arm/boards/pcm037/pcm037.c b/arch/arm/boards/pcm037/pcm037.c index 1a1688d053..ff4089ad25 100644 --- a/arch/arm/boards/pcm037/pcm037.c +++ b/arch/arm/boards/pcm037/pcm037.c @@ -24,7 +24,7 @@ #include <fs.h> #include <environment.h> #include <usb/ulpi.h> -#include <mach/imx-regs.h> +#include <mach/imx31-regs.h> #include <mach/iomux-mx31.h> #include <asm/armlinux.h> #include <asm-generic/sections.h> @@ -96,7 +96,7 @@ static void pcm037_usb_init(void) /* Host 2 */ tmp = readl(MX31_USB_OTG_BASE_ADDR + 0x8); tmp |= 1 << 11; - writel(tmp, IOMUXC_BASE + 0x8); + writel(tmp, MX31_IOMUXC_BASE_ADDR + 0x8); imx_iomux_mode(IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC)); imx_iomux_mode(IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC)); diff --git a/arch/arm/boards/pcm038/env/boot/nand-ubi b/arch/arm/boards/pcm038/env/boot/nand-ubi index a3f748e746..67b0cb4afe 100644 --- a/arch/arm/boards/pcm038/env/boot/nand-ubi +++ b/arch/arm/boards/pcm038/env/boot/nand-ubi @@ -7,4 +7,4 @@ fi global.bootm.image="/dev/nand0.kernel.bb" #global.bootm.oftree="/env/oftree" -bootargs-root-ubi -r root -m nand0.root +global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=nand0.root rootfstype=ubifs" diff --git a/arch/arm/boards/pcm038/env/init/bootargs-base b/arch/arm/boards/pcm038/env/init/bootargs-base deleted file mode 100644 index d86975406e..0000000000 --- a/arch/arm/boards/pcm038/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/pcm038/env/init/config-board b/arch/arm/boards/pcm038/env/init/config-board new file mode 100644 index 0000000000..93fd41bcf1 --- /dev/null +++ b/arch/arm/boards/pcm038/env/init/config-board @@ -0,0 +1,7 @@ +#!/bin/sh + +# board defaults, do not change in running system. Change /env/config +# instead + +global.hostname=pcm038 +global.linux.bootargs.base="console=ttymxc0,115200" diff --git a/arch/arm/boards/pcm038/lowlevel.c b/arch/arm/boards/pcm038/lowlevel.c index 7ecff3afa8..2f93c3127a 100644 --- a/arch/arm/boards/pcm038/lowlevel.c +++ b/arch/arm/boards/pcm038/lowlevel.c @@ -18,7 +18,7 @@ */ #include <common.h> #include <init.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> #include <mach/imx-pll.h> #include <mach/esdctl.h> #include <io.h> @@ -34,13 +34,8 @@ #ifdef CONFIG_NAND_IMX_BOOT static void __bare_init __naked insdram(void) { - uint32_t r; - - PCCR1 |= PCCR1_NFC_BAUDEN; - /* setup a stack to be able to call imx_nand_load_image() */ - r = STACK_BASE + STACK_SIZE - 12; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); imx_nand_load_image(_text, barebox_image_size); @@ -60,10 +55,10 @@ void __bare_init __naked reset(void) common_reset(); /* ahb lite ip interface */ - AIPI1_PSR0 = 0x20040304; - AIPI1_PSR1 = 0xDFFBFCFB; - AIPI2_PSR0 = 0x00000000; - AIPI2_PSR1 = 0xFFFFFFFF; + writel(0x20040304, MX27_AIPI_BASE_ADDR + MX27_AIPI1_PSR0); + writel(0xDFFBFCFB, MX27_AIPI_BASE_ADDR + MX27_AIPI1_PSR1); + writel(0x00000000, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR0); + writel(0xFFFFFFFF, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR1); /* Skip SDRAM initialization if we run from RAM */ r = get_pc(); @@ -71,37 +66,46 @@ void __bare_init __naked reset(void) board_init_lowlevel_return(); /* re-program the PLL prior(!) starting the SDRAM controller */ - MPCTL0 = MPCTL0_VAL; - SPCTL0 = SPCTL0_VAL; - CSCR = CSCR_VAL | CSCR_UPDATE_DIS | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART; + writel(MPCTL0_VAL, MX27_CCM_BASE_ADDR + MX27_MPCTL0); + writel(SPCTL0_VAL, MX27_CCM_BASE_ADDR + MX27_SPCTL0); + writel(CSCR_VAL | MX27_CSCR_UPDATE_DIS | MX27_CSCR_MPLL_RESTART | + MX27_CSCR_SPLL_RESTART, MX27_CCM_BASE_ADDR + MX27_CSCR); /* * DDR on CSD0 */ - writel(0x00000008, ESDMISC); /* Enable DDR SDRAM operation */ - - DSCR(3) = 0x55555555; /* Set the driving strength */ - DSCR(5) = 0x55555555; - DSCR(6) = 0x55555555; - DSCR(7) = 0x00005005; - DSCR(8) = 0x15555555; - - writel(0x00000004, ESDMISC); /* Initial reset */ - writel(0x006ac73a, ESDCFG0); - - writel(ESDCTL0_VAL | ESDCTL0_SMODE_PRECHARGE, ESDCTL0); /* precharge CSD0 all banks */ + /* Enable DDR SDRAM operation */ + writel(0x00000008, MX27_ESDCTL_BASE_ADDR + IMX_ESDMISC); + + /* Set the driving strength */ + writel(0x55555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(3)); + writel(0x55555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(5)); + writel(0x55555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(6)); + writel(0x00005005, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(7)); + writel(0x15555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(8)); + + /* Initial reset */ + writel(0x00000004, MX27_ESDCTL_BASE_ADDR + IMX_ESDMISC); + writel(0x006ac73a, MX27_ESDCTL_BASE_ADDR + IMX_ESDCFG0); + + /* precharge CSD0 all banks */ + writel(ESDCTL0_VAL | ESDCTL0_SMODE_PRECHARGE, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writel(0x00000000, 0xA0000F00); /* CSD0 precharge address (A10 = 1) */ - writel(ESDCTL0_VAL | ESDCTL0_SMODE_AUTO_REFRESH, ESDCTL0); + writel(ESDCTL0_VAL | ESDCTL0_SMODE_AUTO_REFRESH, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0); for (i = 0; i < 8; i++) writel(0, 0xa0000f00); - writel(ESDCTL0_VAL | ESDCTL0_SMODE_LOAD_MODE, ESDCTL0); + writel(ESDCTL0_VAL | ESDCTL0_SMODE_LOAD_MODE, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0); writeb(0xda, 0xa0000033); writeb(0xff, 0xa1000000); writel(ESDCTL0_VAL | ESDCTL0_DSIZ_31_0 | ESDCTL0_REF4 | - ESDCTL0_BL | ESDCTL0_SMODE_NORMAL, ESDCTL0); + ESDCTL0_BL | ESDCTL0_SMODE_NORMAL, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0); #ifdef CONFIG_NAND_IMX_BOOT /* skip NAND boot if not running from NFC space */ diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c index 58b1ec9ef4..715d604726 100644 --- a/arch/arm/boards/pcm038/pcm038.c +++ b/arch/arm/boards/pcm038/pcm038.c @@ -18,7 +18,7 @@ #include <net.h> #include <init.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> #include <fec.h> #include <notifier.h> #include <mach/gpio.h> @@ -39,6 +39,7 @@ #include <mach/devices-imx27.h> #include <mach/iim.h> #include <mfd/mc13xxx.h> +#include <mach/generic.h> #include "pll.h" @@ -111,8 +112,8 @@ static inline uint32_t get_pll_spctl10(void) { uint32_t reg; - reg = SPCTL0; - SPCTL0 = reg; + reg = readl(MX27_CCM_BASE_ADDR + MX27_SPCTL0); + writel(reg, MX27_CCM_BASE_ADDR + MX27_SPCTL0); return reg; } @@ -126,7 +127,8 @@ static int pcm038_power_init(void) struct mc13xxx *mc13xxx = mc13xxx_get(); /* PLL registers already set to their final values? */ - if (spctl0 == SPCTL0_VAL && MPCTL0 == MPCTL0_VAL) { + if (spctl0 == SPCTL0_VAL && + readl(MX27_CCM_BASE_ADDR + MX27_MPCTL0) == MPCTL0_VAL) { console_flush(); if (mc13xxx) { mc13xxx_reg_write(mc13xxx, MC13783_REG_SWITCHERS(0), @@ -161,9 +163,9 @@ static int pcm038_power_init(void) /* wait for required power level to run the CPU at 400 MHz */ udelay(100000); - CSCR = CSCR_VAL_FINAL; - PCDR0 = 0x130410c3; - PCDR1 = 0x09030911; + writel(CSCR_VAL_FINAL, MX27_CCM_BASE_ADDR + MX27_CSCR); + writel(0x130410c3, MX27_CCM_BASE_ADDR + MX27_PCDR0); + writel(0x09030911, MX27_CCM_BASE_ADDR + MX27_PCDR1); /* Clocks have changed. Notify clients */ clock_notifier_call_chain(); @@ -173,7 +175,7 @@ static int pcm038_power_init(void) } /* clock gating enable */ - GPCR = 0x00050f08; + writel(0x00050f08, MX27_SYSCTRL_BASE_ADDR + MX27_GPCR); return 0; } @@ -281,9 +283,6 @@ static int pcm038_devices_init(void) for (i = 0; i < ARRAY_SIZE(mode); i++) imx_gpio_mode(mode[i]); - PCCR0 |= PCCR0_CSPI1_EN; - PCCR1 |= PCCR1_PERCLK2_EN; - spi_register_board_info(pcm038_spi_board_info, ARRAY_SIZE(pcm038_spi_board_info)); imx27_add_spi0(&pcm038_spi_0_data); @@ -293,7 +292,6 @@ static int pcm038_devices_init(void) imx27_add_nand(&nand_info); imx27_add_fb(&pcm038_fb_data); - PCCR0 |= PCCR0_I2C1_EN | PCCR0_I2C2_EN; imx27_add_i2c0(NULL); imx27_add_i2c1(NULL); @@ -302,11 +300,8 @@ static int pcm038_devices_init(void) */ imx27_add_fec(&fec_info); - switch ((GPCR & GPCR_BOOT_MASK) >> GPCR_BOOT_SHIFT) { - case GPCR_BOOT_8BIT_NAND_2k: - case GPCR_BOOT_16BIT_NAND_2k: - case GPCR_BOOT_16BIT_NAND_512: - case GPCR_BOOT_8BIT_NAND_512: + switch (imx_bootsource()) { + case bootsource_nand: devfs_add_partition("nand0", 0x00000, 0x80000, DEVFS_PARTITION_FIXED, "self_raw"); dev_add_bb_dev("self_raw", "self0"); diff --git a/arch/arm/boards/pcm038/pcm970.c b/arch/arm/boards/pcm038/pcm970.c index a6b6c83efa..93a183988a 100644 --- a/arch/arm/boards/pcm038/pcm970.c +++ b/arch/arm/boards/pcm038/pcm970.c @@ -16,7 +16,7 @@ #include <init.h> #include <sizes.h> #include <platform_ide.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> #include <mach/iomux-mx27.h> #include <mach/weim.h> #include <mach/gpio.h> @@ -112,35 +112,38 @@ static void pcm970_ide_init(void) mdelay(10); /* Reset PCMCIA Status Change Register */ - writel(0x00000fff, PCMCIA_PSCR); + writel(0x00000fff, MX27_PCMCIA_CTL_BASE_ADDR + MX27_PCMCIA_PSCR); mdelay(10); /* Check PCMCIA Input Pins Register for Card Detect & Power */ - if ((readl(PCMCIA_PIPR) & ((1 << 8) | (3 << 3))) != (1 << 8)) { + if ((readl(MX27_PCMCIA_CTL_BASE_ADDR + MX27_PCMCIA_PIPR) & + ((1 << 8) | (3 << 3))) != (1 << 8)) { printf("CompactFlash card not found. Driver not enabled.\n"); return; } /* Disable all interrupts */ - writel(0, PCMCIA_PER); + writel(0, MX27_PCMCIA_CTL_BASE_ADDR + MX27_PCMCIA_PER); /* Disable all PCMCIA banks */ for (i = 0; i < 5; i++) - writel(0, PCMCIA_POR(i)); + writel(0, MX27_PCMCIA_CTL_BASE_ADDR + MX27_PCMCIA_POR(i)); /* Not use internal PCOE */ - writel(0, PCMCIA_PGCR); + writel(0, MX27_PCMCIA_CTL_BASE_ADDR + MX27_PCMCIA_PGCR); /* Setup PCMCIA bank0 for Common memory mode */ - writel(0, PCMCIA_PBR(0)); - writel(0, PCMCIA_POFR(0)); - writel((0 << 25) | (17 << 17) | (4 << 11) | (3 << 5) | 0xf, PCMCIA_POR(0)); + writel(0, MX27_PCMCIA_CTL_BASE_ADDR + MX27_PCMCIA_PBR(0)); + writel(0, MX27_PCMCIA_CTL_BASE_ADDR + MX27_PCMCIA_POFR(0)); + writel((0 << 25) | (17 << 17) | (4 << 11) | (3 << 5) | 0xf, + MX27_PCMCIA_CTL_BASE_ADDR + MX27_PCMCIA_POR(0)); /* Clear PCMCIA General Status Register */ - writel(0x0000001f, PCMCIA_PGSR); + writel(0x0000001f, MX27_PCMCIA_CTL_BASE_ADDR + MX27_PCMCIA_PGSR); /* Make PCMCIA bank0 valid */ - writel(readl(PCMCIA_POR(0)) | (1 << 29), PCMCIA_POR(0)); + writel(readl(MX27_PCMCIA_POR(0)) | (1 << 29), + MX27_PCMCIA_CTL_BASE_ADDR + MX27_PCMCIA_POR(0)); platform_device_register(&pcm970_ide_device); } @@ -162,7 +165,6 @@ static void pcm970_mmc_init(void) for (i = 0; i < ARRAY_SIZE(mode); i++) imx_gpio_mode(mode[i]); - PCCR0 |= PCCR0_SDHC2_EN; imx27_add_mmc1(NULL); } diff --git a/arch/arm/boards/pcm038/pll.h b/arch/arm/boards/pcm038/pll.h index a7da4a44e3..8bdb76d111 100644 --- a/arch/arm/boards/pcm038/pll.h +++ b/arch/arm/boards/pcm038/pll.h @@ -22,35 +22,35 @@ /* define the PLL setting we want to run the system */ /* main clock divider settings immediately after reset (at 1.25 V core supply) */ -#define CSCR_VAL (CSCR_USB_DIV(3) | \ - CSCR_SD_CNT(3) | \ - CSCR_MSHC_SEL | \ - CSCR_H264_SEL | \ - CSCR_SSI1_SEL | \ - CSCR_SSI2_SEL | \ - CSCR_SP_SEL | /* 26 MHz reference */ \ - CSCR_MCU_SEL | /* 26 MHz reference */ \ - CSCR_ARM_DIV(0) | /* CPU runs at MPLL/3 clock */ \ - CSCR_AHB_DIV(1) | /* AHB runs at MPLL/6 clock */ \ - CSCR_FPM_EN | \ - CSCR_SPEN | \ - CSCR_MPEN) +#define CSCR_VAL (MX27_CSCR_USB_DIV(3) | \ + MX27_CSCR_SD_CNT(3) | \ + MX27_CSCR_MSHC_SEL | \ + MX27_CSCR_H264_SEL | \ + MX27_CSCR_SSI1_SEL | \ + MX27_CSCR_SSI2_SEL | \ + MX27_CSCR_SP_SEL | /* 26 MHz reference */ \ + MX27_CSCR_MCU_SEL | /* 26 MHz reference */ \ + MX27_CSCR_ARM_DIV(0) | /* CPU runs at MPLL/3 clock */ \ + MX27_CSCR_AHB_DIV(1) | /* AHB runs at MPLL/6 clock */ \ + MX27_CSCR_FPM_EN | \ + MX27_CSCR_SPEN | \ + MX27_CSCR_MPEN) /* main clock divider settings after core voltage increases to 1.45 V */ -#define CSCR_VAL_FINAL (CSCR_USB_DIV(3) | \ - CSCR_SD_CNT(3) | \ - CSCR_MSHC_SEL | \ - CSCR_H264_SEL | \ - CSCR_SSI1_SEL | \ - CSCR_SSI2_SEL | \ - CSCR_SP_SEL | /* 26 MHz reference */ \ - CSCR_MCU_SEL | /* 26 MHz reference */ \ - CSCR_ARM_SRC_MPLL | /* use main MPLL clock */ \ - CSCR_ARM_DIV(0) | /* CPU run at full MPLL clock */ \ - CSCR_AHB_DIV(1) | /* AHB runs at MPLL/6 clock */ \ - CSCR_FPM_EN | /* do not disable it! */ \ - CSCR_SPEN | \ - CSCR_MPEN) +#define CSCR_VAL_FINAL (MX27_CSCR_USB_DIV(3) | \ + MX27_CSCR_SD_CNT(3) | \ + MX27_CSCR_MSHC_SEL | \ + MX27_CSCR_H264_SEL | \ + MX27_CSCR_SSI1_SEL | \ + MX27_CSCR_SSI2_SEL | \ + MX27_CSCR_SP_SEL | /* 26 MHz reference */ \ + MX27_CSCR_MCU_SEL | /* 26 MHz reference */ \ + MX27_CSCR_ARM_SRC_MPLL | /* use main MPLL clock */ \ + MX27_CSCR_ARM_DIV(0) | /* CPU run at full MPLL clock */ \ + MX27_CSCR_AHB_DIV(1) | /* AHB runs at MPLL/6 clock */ \ + MX27_CSCR_FPM_EN | /* do not disable it! */ \ + MX27_CSCR_SPEN | \ + MX27_CSCR_MPEN) /* MPLL should provide a 399 MHz clock from the 26 MHz reference */ #define MPCTL0_VAL (IMX_PLL_PD(0) | \ diff --git a/arch/arm/boards/pcm043/lowlevel.c b/arch/arm/boards/pcm043/lowlevel.c index 4516e9f017..06f05abef1 100644 --- a/arch/arm/boards/pcm043/lowlevel.c +++ b/arch/arm/boards/pcm043/lowlevel.c @@ -18,7 +18,7 @@ */ #include <common.h> #include <init.h> -#include <mach/imx-regs.h> +#include <mach/imx35-regs.h> #include <mach/imx-pll.h> #include <mach/esdctl.h> #include <asm/cache-l2x0.h> @@ -52,8 +52,7 @@ static void __bare_init __naked insdram(void) writel(r, MX35_CCM_BASE_ADDR + CCM_PDR4); /* setup a stack to be able to call imx_nand_load_image() */ - r = STACK_BASE + STACK_SIZE - 12; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); + arm_setup_stack(STACK_BASE + STACK_SIZE - 12); imx_nand_load_image(_text, barebox_image_size); @@ -66,6 +65,7 @@ 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; @@ -110,28 +110,28 @@ void __bare_init __naked reset(void) * End of ARM1136 init */ - writel(0x003F4208, ccm_base + CCM_CCMR); + writel(0x003F4208, ccm_base + MX35_CCM_CCMR); /* Set MPLL , arm clock and ahb clock*/ - writel(MPCTL_PARAM_532, ccm_base + CCM_MPCTL); + writel(MPCTL_PARAM_532, ccm_base + MX35_CCM_MPCTL); - writel(PPCTL_PARAM_300, ccm_base + CCM_PPCTL); + writel(PPCTL_PARAM_300, ccm_base + MX35_CCM_PPCTL); /* Check silicon revision and use 532MHz if >=2.1 */ r = readl(MX35_IIM_BASE_ADDR + 0x24); if (r >= IMX35_CHIP_REVISION_2_1) - writel(CCM_PDR0_532, ccm_base + CCM_PDR0); + writel(CCM_PDR0_532, ccm_base + MX35_CCM_PDR0); else - writel(CCM_PDR0_399, ccm_base + CCM_PDR0); + writel(CCM_PDR0_399, ccm_base + MX35_CCM_PDR0); - r = readl(ccm_base + CCM_CGR0); + r = readl(ccm_base + MX35_CCM_CGR0); r |= 0x00300000; - writel(r, ccm_base + CCM_CGR0); + writel(r, ccm_base + MX35_CCM_CGR0); - r = readl(ccm_base + CCM_CGR1); + r = readl(ccm_base + MX35_CCM_CGR1); r |= 0x00000C00; r |= 0x00000003; - writel(r, ccm_base + CCM_CGR1); + writel(r, ccm_base + MX35_CCM_CGR1); r = readl(MX35_L2CC_BASE_ADDR + L2X0_AUX_CTRL); r |= 0x1000; @@ -154,17 +154,17 @@ void __bare_init __naked reset(void) writel(r, iomuxc_base + 0x7a4); /* MDDR init, enable mDDR*/ - writel(0x00000304, ESDMISC); /* was 0x00000004 */ + writel(0x00000304, esdctl_base + IMX_ESDMISC); /* was 0x00000004 */ /* set timing paramters */ - writel(0x0025541F, ESDCFG0); + writel(0x0025541F, esdctl_base + IMX_ESDCFG0); /* select Precharge-All mode */ - writel(0x92220000, ESDCTL0); + writel(0x92220000, esdctl_base + IMX_ESDCTL0); /* Precharge-All */ writel(0x12345678, MX35_CSD0_BASE_ADDR + 0x400); /* select Load-Mode-Register mode */ - writel(0xB8001000, ESDCTL0); + writel(0xB8001000, esdctl_base + IMX_ESDCTL0); /* Load reg EMR2 */ writeb(0xda, 0x84000000); /* Load reg EMR3 */ @@ -175,18 +175,18 @@ void __bare_init __naked reset(void) writeb(0xda, 0x80000333); /* select Precharge-All mode */ - writel(0x92220000, ESDCTL0); + writel(0x92220000, esdctl_base + IMX_ESDCTL0); /* Precharge-All */ writel(0x12345678, MX35_CSD0_BASE_ADDR + 0x400); /* select Manual-Refresh mode */ - writel(0xA2220000, ESDCTL0); + writel(0xA2220000, esdctl_base + IMX_ESDCTL0); /* Manual-Refresh 2 times */ writel(0x87654321, MX35_CSD0_BASE_ADDR); writel(0x87654321, MX35_CSD0_BASE_ADDR); /* select Load-Mode-Register mode */ - writel(0xB2220000, ESDCTL0); + writel(0xB2220000, esdctl_base + IMX_ESDCTL0); /* Load reg MR -- CL3, BL8, end DLL reset */ writeb(0xda, 0x80000233); /* Load reg EMR1 -- OCD default */ @@ -198,12 +198,12 @@ void __bare_init __naked reset(void) * DSIZ32-bit, BL8, COL10-bit, ROW13-bit * disable PWT & PRCT * disable Auto-Refresh */ - writel(0x82220080, ESDCTL0); + writel(0x82220080, esdctl_base + IMX_ESDCTL0); /* enable Auto-Refresh */ - writel(0x82228080, ESDCTL0); + writel(0x82228080, esdctl_base + IMX_ESDCTL0); /* enable Auto-Refresh */ - writel(0x00002000, ESDCTL1); + writel(0x00002000, esdctl_base + IMX_ESDCTL1); #ifdef CONFIG_NAND_IMX_BOOT /* skip NAND boot if not running from NFC space */ diff --git a/arch/arm/boards/pcm043/pcm043.c b/arch/arm/boards/pcm043/pcm043.c index 09bc96af78..abfeaf148a 100644 --- a/arch/arm/boards/pcm043/pcm043.c +++ b/arch/arm/boards/pcm043/pcm043.c @@ -26,7 +26,7 @@ #include <environment.h> #include <fs.h> #include <sizes.h> -#include <mach/imx-regs.h> +#include <mach/imx35-regs.h> #include <asm/armlinux.h> #include <mach/gpio.h> #include <io.h> @@ -127,7 +127,7 @@ static int imx35_devices_init(void) led_gpio_register(&led0); - reg = readl(MX35_CCM_BASE_ADDR + CCM_RCSR); + reg = readl(MX35_CCM_BASE_ADDR + MX35_CCM_RCSR); /* some fuses provide us vital information about connected hardware */ if (reg & 0x20000000) nand_info.width = 2; /* 16 bit */ @@ -308,10 +308,10 @@ static int do_cpufreq(int argc, char *argv[]) switch (freq) { case 399: - writel(MPCTL_PARAM_399, MX35_CCM_BASE_ADDR + CCM_MPCTL); + writel(MPCTL_PARAM_399, MX35_CCM_BASE_ADDR + MX35_CCM_MPCTL); break; case 532: - writel(MPCTL_PARAM_532, MX35_CCM_BASE_ADDR + CCM_MPCTL); + writel(MPCTL_PARAM_532, MX35_CCM_BASE_ADDR + MX35_CCM_MPCTL); break; default: return COMMAND_ERROR_USAGE; diff --git a/arch/arm/boards/pcm049/lowlevel.c b/arch/arm/boards/pcm049/lowlevel.c index c3fc6c7e1f..b64244ca79 100644 --- a/arch/arm/boards/pcm049/lowlevel.c +++ b/arch/arm/boards/pcm049/lowlevel.c @@ -86,16 +86,12 @@ static void noinline pcm049_init_lowlevel(void) void reset(void) { - u32 r; - common_reset(); if (get_pc() > 0x80000000) board_init_lowlevel_return(); - r = 0x4030d000; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); + arm_setup_stack(0x4030d000); pcm049_init_lowlevel(); } - diff --git a/arch/arm/boards/phycard-a-xl2/lowlevel.c b/arch/arm/boards/phycard-a-xl2/lowlevel.c index 24b4ab8ea5..5d8693abdd 100644 --- a/arch/arm/boards/phycard-a-xl2/lowlevel.c +++ b/arch/arm/boards/phycard-a-xl2/lowlevel.c @@ -86,15 +86,12 @@ static noinline void pcaaxl2_init_lowlevel(void) void reset(void) { - u32 r; - common_reset(); if (get_pc() > 0x80000000) board_init_lowlevel_return(); - r = 0x4030d000; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); + arm_setup_stack(0x4030d000); pcaaxl2_init_lowlevel(); } diff --git a/arch/arm/boards/phycard-i.MX27/lowlevel_init.S b/arch/arm/boards/phycard-i.MX27/lowlevel_init.S index 3c36889e7a..8f0000f822 100644 --- a/arch/arm/boards/phycard-i.MX27/lowlevel_init.S +++ b/arch/arm/boards/phycard-i.MX27/lowlevel_init.S @@ -5,7 +5,7 @@ */ #include <config.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> #include <mach/imx-pll.h> #include <asm/barebox-arm-head.h> @@ -21,20 +21,26 @@ /* * DDR on CSD0 */ - writel(0x00000008, ESDMISC) /* Enable DDR SDRAM operation */ - - writel(0x55555555, DSCR(3)) /* Set the driving strength */ - writel(0x55555555, DSCR(5)) - writel(0x55555555, DSCR(6)) - writel(0x00005005, DSCR(7)) - writel(0x15555555, DSCR(8)) - - writel(0x00000004, ESDMISC) /* Initial reset */ - writel(0x006ac73a, ESDCFG0) - - writel(ESDCTL0_VAL | ESDCTL0_SMODE_PRECHARGE, ESDCTL0) /* precharge CSD0 all banks */ + /* Enable DDR SDRAM operation */ + writel(0x00000008, MX27_ESDCTL_BASE_ADDR + IMX_ESDMISC) + + /* Set the driving strength */ + writel(0x55555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(3)) + writel(0x55555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(5)) + writel(0x55555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(6)) + writel(0x00005005, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(7)) + writel(0x15555555, MX27_SYSCTRL_BASE_ADDR + MX27_DSCR(8)) + + /* Initial reset */ + writel(0x00000004, MX27_ESDCTL_BASE_ADDR + IMX_ESDMISC) + writel(0x006ac73a, MX27_ESDCTL_BASE_ADDR + IMX_ESDCFG0) + + /* precharge CSD0 all banks */ + writel(ESDCTL0_VAL | ESDCTL0_SMODE_PRECHARGE, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0) writel(0x00000000, 0xA0000F00) /* CSD0 precharge address (A10 = 1) */ - writel(ESDCTL0_VAL | ESDCTL0_SMODE_AUTO_REFRESH, ESDCTL0) + writel(ESDCTL0_VAL | ESDCTL0_SMODE_AUTO_REFRESH, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0) ldr r0, =0xa0000f00 mov r1, #0 @@ -44,14 +50,17 @@ subs r2, #1 bne 1b - writel(ESDCTL0_VAL | ESDCTL0_SMODE_LOAD_MODE, ESDCTL0) + writel(ESDCTL0_VAL | ESDCTL0_SMODE_LOAD_MODE, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0) ldr r0, =0xA0000033 mov r1, #0xda strb r1, [r0] ldr r0, =0xA1000000 mov r1, #0xff strb r1, [r0] - writel(ESDCTL0_VAL | ESDCTL0_DSIZ_31_0 | ESDCTL0_REF4 | ESDCTL0_BL | ESDCTL0_SMODE_NORMAL, ESDCTL0) + writel(ESDCTL0_VAL | ESDCTL0_DSIZ_31_0 | ESDCTL0_REF4 | + ESDCTL0_BL | ESDCTL0_SMODE_NORMAL, + MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0) .endm .section ".text_bare_init","ax" @@ -61,10 +70,10 @@ reset: common_reset r0 /* ahb lite ip interface */ - writel(0x20040304, AIPI1_PSR0) - writel(0xDFFBFCFB, AIPI1_PSR1) - writel(0x00000000, AIPI2_PSR0) - writel(0xFFFFFFFF, AIPI2_PSR1) + writel(0x20040304, MX27_AIPI_BASE_ADDR + MX27_AIPI1_PSR0) + writel(0xDFFBFCFB, MX27_AIPI_BASE_ADDR + MX27_AIPI1_PSR1) + writel(0x00000000, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR0) + writel(0xFFFFFFFF, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR1) /* skip sdram initialization if we run from ram */ cmp pc, #0xa0000000 @@ -75,21 +84,26 @@ reset: b board_init_lowlevel_return 1: + /* 399 MHz */ writel(IMX_PLL_PD(0) | IMX_PLL_MFD(51) | IMX_PLL_MFI(7) | - IMX_PLL_MFN(35), MPCTL0) /* 399 MHz */ + IMX_PLL_MFN(35), MX27_CCM_BASE_ADDR + MX27_MPCTL0) + /* SPLL = 2 * 26 * 4.61538 MHz = 240 MHz */ writel(IMX_PLL_PD(1) | IMX_PLL_MFD(12) | IMX_PLL_MFI(9) | - IMX_PLL_MFN(3), SPCTL0) /* SPLL = 2 * 26 * 4.61538 MHz = 240 MHz */ - - writel(CSCR_MPLL_RESTART | CSCR_SPLL_RESTART | CSCR_ARM_SRC_MPLL | - CSCR_MCU_SEL | CSCR_SP_SEL | CSCR_FPM_EN | CSCR_MPEN | - CSCR_SPEN | CSCR_ARM_DIV(0) | CSCR_AHB_DIV(1) | CSCR_USB_DIV(3) | - CSCR_SD_CNT(3) | CSCR_SSI2_SEL | CSCR_SSI1_SEL | CSCR_H264_SEL | - CSCR_MSHC_SEL, CSCR) + IMX_PLL_MFN(3), MX27_CCM_BASE_ADDR + MX27_SPCTL0) + + writel(MX27_CSCR_MPLL_RESTART | MX27_CSCR_SPLL_RESTART | + MX27_CSCR_ARM_SRC_MPLL | MX27_CSCR_MCU_SEL | + MX27_CSCR_SP_SEL | MX27_CSCR_FPM_EN | + MX27_CSCR_MPEN | MX27_CSCR_SPEN | MX27_CSCR_ARM_DIV(0) | + MX27_CSCR_AHB_DIV(1) | MX27_CSCR_USB_DIV(3) | + MX27_CSCR_SD_CNT(3) | MX27_CSCR_SSI2_SEL | + MX27_CSCR_SSI1_SEL | MX27_CSCR_H264_SEL | + MX27_CSCR_MSHC_SEL, MX27_CCM_BASE_ADDR + MX27_CSCR) sdram_init diff --git a/arch/arm/boards/phycard-i.MX27/pca100.c b/arch/arm/boards/phycard-i.MX27/pca100.c index 45e59fbfd2..0b66b04e5f 100644 --- a/arch/arm/boards/phycard-i.MX27/pca100.c +++ b/arch/arm/boards/phycard-i.MX27/pca100.c @@ -18,7 +18,7 @@ #include <net.h> #include <init.h> #include <environment.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> #include <fec.h> #include <mach/gpio.h> #include <asm/armlinux.h> @@ -279,8 +279,6 @@ static int pca100_devices_init(void) PD18_PF_I2C_CLK, }; - PCCR0 |= PCCR0_SDHC2_EN; - pca100_usb_init(); /* initizalize gpios */ @@ -292,8 +290,6 @@ static int pca100_devices_init(void) imx27_add_mmc1(NULL); imx27_add_fb(&pca100_fb_data); - PCCR1 |= PCCR1_PERCLK2_EN; - #ifdef CONFIG_USB pca100_usb_register(); #endif diff --git a/arch/arm/boards/pm9261/init.c b/arch/arm/boards/pm9261/init.c index 5214394461..6d2ac98156 100644 --- a/arch/arm/boards/pm9261/init.c +++ b/arch/arm/boards/pm9261/init.c @@ -1,4 +1,6 @@ /* + * Copyright (C) 2009-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * * Copyright (C) 2007 Sascha Hauer, Pengutronix * * This program is free software; you can redistribute it and/or @@ -34,6 +36,13 @@ #include <mach/at91sam9_smc.h> #include <mach/sam9_smc.h> #include <dm9000.h> +#include <linux/w1-gpio.h> +#include <w1_mac_address.h> + +struct w1_gpio_platform_data w1_pdata = { + .pin = AT91_PIN_PA7, + .is_open_drain = 0, +}; static struct atmel_nand_data nand_pdata = { .ale = 22, @@ -112,6 +121,7 @@ static struct sam9_smc_config __initdata dm9000_smc_config = { static void __init pm_add_device_dm9000(void) { + w1_local_mac_address_register(0, "ron", "w1-1-0"); /* Configure chip-select 2 (DM9000) */ sam9_smc_configure(2, &dm9000_smc_config); diff --git a/arch/arm/boards/pm9263/init.c b/arch/arm/boards/pm9263/init.c index b17a90a7d1..14e821fd1b 100644 --- a/arch/arm/boards/pm9263/init.c +++ b/arch/arm/boards/pm9263/init.c @@ -1,4 +1,6 @@ /* + * Copyright (C) 2009-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * * Copyright (C) 2007 Sascha Hauer, Pengutronix * * This program is free software; you can redistribute it and/or @@ -34,6 +36,13 @@ #include <mach/io.h> #include <mach/at91sam9_smc.h> #include <mach/sam9_smc.h> +#include <linux/w1-gpio.h> +#include <w1_mac_address.h> + +struct w1_gpio_platform_data w1_pdata = { + .pin = AT91_PIN_PB31, + .is_open_drain = 0, +}; static struct atmel_nand_data nand_pdata = { .ale = 21, @@ -85,6 +94,24 @@ static struct at91_ether_platform_data macb_pdata = { .phy_addr = 0, }; +static void pm9263_phy_init(void) +{ + /* + * PB27 enables the 50MHz oscillator for Ethernet PHY + * 1 - enable + * 0 - disable + */ + at91_set_gpio_output(AT91_PIN_PB27, 1); + at91_set_gpio_value(AT91_PIN_PB27, 1); /* 1- enable, 0 - disable */ +} + +static void pm9263_add_device_eth(void) +{ + w1_local_mac_address_register(0, "ron", "w1-1-0"); + pm9263_phy_init(); + at91_add_device_eth(0, &macb_pdata); +} + static int pm9263_mem_init(void) { at91_add_device_sdram(64 * 1024 * 1024); @@ -95,16 +122,11 @@ mem_initcall(pm9263_mem_init); static int pm9263_devices_init(void) { - /* - * PB27 enables the 50MHz oscillator for Ethernet PHY - * 1 - enable - * 0 - disable - */ - at91_set_gpio_output(AT91_PIN_PB27, 1); - at91_set_gpio_value(AT91_PIN_PB27, 1); /* 1- enable, 0 - disable */ + at91_set_gpio_input(w1_pdata.pin, 0); + add_generic_device_res("w1-gpio", DEVICE_ID_SINGLE, NULL, 0, &w1_pdata); pm_add_device_nand(); - at91_add_device_eth(0, &macb_pdata); + pm9263_add_device_eth(); add_cfi_flash_device(0, AT91_CHIPSELECT_0, 4 * 1024 * 1024, 0); devfs_add_partition("nor0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self0"); diff --git a/arch/arm/boards/pm9g45/env/config b/arch/arm/boards/pm9g45/env/config index 5f05e6f04f..18ac565d49 100644 --- a/arch/arm/boards/pm9g45/env/config +++ b/arch/arm/boards/pm9g45/env/config @@ -2,7 +2,8 @@ # use 'dhcp' to do dhcp in barebox and in kernel # use 'none' if you want to skip kernel ip autoconfiguration -ip=dhcp +ip=dhcp-barebox +global.dhcp.vendor_id=barebox-pm9g45 # or set your networking parameters here #eth0.ipaddr=a.b.c.d @@ -11,16 +12,18 @@ ip=dhcp #eth0.serverip=a.b.c.d # can be either 'nfs', 'tftp' or 'nand' -kernel_loc=nand +kernel_loc=nfs # can be either 'net', 'nand' or 'initrd' -rootfs_loc=nand +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 -#kernelimage=zImage -kernelimage=uImage +kernelimage=zImage +#kernelimage=uImage #kernelimage=Image #kernelimage=Image.lzo diff --git a/arch/arm/boards/pm9g45/init.c b/arch/arm/boards/pm9g45/init.c index 17b38d4b59..675ebe8515 100644 --- a/arch/arm/boards/pm9g45/init.c +++ b/arch/arm/boards/pm9g45/init.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * Copyright (C) 2009-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> * * Copyright (C) 2007 Sascha Hauer, Pengutronix * @@ -35,6 +35,13 @@ #include <mach/io.h> #include <mach/at91sam9_smc.h> #include <mach/sam9_smc.h> +#include <linux/w1-gpio.h> +#include <w1_mac_address.h> + +struct w1_gpio_platform_data w1_pdata = { + .pin = AT91_PIN_PA31, + .is_open_drain = 0, +}; static struct atmel_nand_data nand_pdata = { .ale = 21, @@ -43,6 +50,7 @@ static struct atmel_nand_data nand_pdata = { .rdy_pin = AT91_PIN_PD3, .enable_pin = AT91_PIN_PC14, .bus_width_16 = 0, + .on_flash_bbt = 1, }; static struct sam9_smc_config pm_nand_smc_config = { @@ -121,6 +129,13 @@ static void pm9g45_phy_init(void) at91_set_gpio_value(AT91_PIN_PD2, 1); } +static void pm9g45_add_device_eth(void) +{ + w1_local_mac_address_register(0, "ron", "w1-1-0"); + pm9g45_phy_init(); + at91_add_device_eth(0, &macb_pdata); +} + static int pm9g45_mem_init(void) { at91_add_device_sdram(128 * 1024 * 1024); @@ -131,15 +146,19 @@ mem_initcall(pm9g45_mem_init); static int pm9g45_devices_init(void) { + at91_set_gpio_input(w1_pdata.pin, 0); + add_generic_device_res("w1-gpio", DEVICE_ID_SINGLE, NULL, 0, &w1_pdata); + pm_add_device_nand(); pm9g45_add_device_mci(); - pm9g45_phy_init(); - at91_add_device_eth(0, &macb_pdata); + pm9g45_add_device_eth(); pm9g45_add_device_usbh(); - devfs_add_partition("nand0", 0x00000, 0x80000, DEVFS_PARTITION_FIXED, "self_raw"); + 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", 0x40000, 0x40000, DEVFS_PARTITION_FIXED, "env_raw"); + devfs_add_partition("nand0", SZ_256K + SZ_128K, SZ_128K, DEVFS_PARTITION_FIXED, "env_raw"); dev_add_bb_dev("env_raw", "env0"); armlinux_set_bootparams((void *)(AT91_CHIPSELECT_6 + 0x100)); diff --git a/arch/arm/boards/raspberry-pi/Makefile b/arch/arm/boards/raspberry-pi/Makefile new file mode 100644 index 0000000000..6ce5edeb27 --- /dev/null +++ b/arch/arm/boards/raspberry-pi/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_MACH_RPI) += rpi.o diff --git a/arch/arm/boards/raspberry-pi/config.h b/arch/arm/boards/raspberry-pi/config.h new file mode 100644 index 0000000000..ca15136817 --- /dev/null +++ b/arch/arm/boards/raspberry-pi/config.h @@ -0,0 +1,4 @@ +#ifndef __CONFIG_H +#define __CONFIG_H + +#endif /* __CONFIG_H */ diff --git a/arch/arm/boards/freescale-mx51-pdk/env/init/bootargs-base b/arch/arm/boards/raspberry-pi/env/init/bootargs-base index d86975406e..d86975406e 100644 --- a/arch/arm/boards/freescale-mx51-pdk/env/init/bootargs-base +++ b/arch/arm/boards/raspberry-pi/env/init/bootargs-base diff --git a/arch/arm/boards/freescale-mx6-sabrelite/env/init/hostname b/arch/arm/boards/raspberry-pi/env/init/hostname index db5b2b22ce..7e8f294357 100644 --- a/arch/arm/boards/freescale-mx6-sabrelite/env/init/hostname +++ b/arch/arm/boards/raspberry-pi/env/init/hostname @@ -5,4 +5,4 @@ if [ "$1" = menu ]; then exit fi -global.hostname=SabreLite +global.hostname=Raspberry-Pi diff --git a/arch/arm/boards/raspberry-pi/rpi.c b/arch/arm/boards/raspberry-pi/rpi.c new file mode 100644 index 0000000000..3be95ae5c4 --- /dev/null +++ b/arch/arm/boards/raspberry-pi/rpi.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2009 Carlo Caione <carlo@carlocaione.org> + * + * 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 <asm/armlinux.h> +#include <generated/mach-types.h> + +#include <mach/core.h> + +static int rpi_mem_init(void) +{ + bcm2835_add_device_sdram(0); + return 0; +} +mem_initcall(rpi_mem_init); + +static int rpi_console_init(void) +{ + bcm2835_register_uart(); + return 0; +} +console_initcall(rpi_console_init); + +static int rpi_devices_init(void) +{ + armlinux_set_architecture(MACH_TYPE_BCM2708); + armlinux_set_bootparams((void *)(0x00000100)); + return 0; +} + +device_initcall(rpi_devices_init); diff --git a/arch/arm/boards/scb9328/lowlevel_init.S b/arch/arm/boards/scb9328/lowlevel_init.S index fabc89ea1e..cefac8481a 100644 --- a/arch/arm/boards/scb9328/lowlevel_init.S +++ b/arch/arm/boards/scb9328/lowlevel_init.S @@ -12,7 +12,7 @@ * GNU General Public License for more details. */ -#include <mach/imx-regs.h> +#include <mach/imx1-regs.h> #include <asm/barebox-arm-head.h> #define CPU200 @@ -82,13 +82,13 @@ reset: common_reset r0 /* Change PERCLK1DIV to 14 ie 14+1 */ - writel(CFG_PCDR_VAL, PCDR) + writel(CFG_PCDR_VAL, MX1_CCM_BASE_ADDR + MX1_PCDR) /* set MCU PLL Control Register 0 */ - writel(CFG_MPCTL0_VAL, MPCTL0) + writel(CFG_MPCTL0_VAL, MX1_CCM_BASE_ADDR + MX1_MPCTL0) /* set mpll restart bit */ - ldr r0, =CSCR + ldr r0, =MX1_CCM_BASE_ADDR + MX1_CSCR ldr r1, [r0] orr r1,r1,#(1<<21) str r1, [r0] @@ -104,10 +104,10 @@ reset: bne 1b /* set System PLL Control Register 0 */ - writel(CFG_SPCTL0_VAL, SPCTL0) + writel(CFG_SPCTL0_VAL, MX1_CCM_BASE_ADDR + MX1_SPCTL0) /* set spll restart bit */ - ldr r0, =CSCR + ldr r0, =MX1_CCM_BASE_ADDR + MX1_CSCR ldr r1, [r0] orr r1,r1,#(1<<22) str r1, [r0] @@ -122,7 +122,7 @@ reset: subs r2,r2,#1 bne 1b - writel(CFG_CSCR_VAL, CSCR) + writel(CFG_CSCR_VAL, MX1_CCM_BASE_ADDR + MX1_CSCR) /* I have now read the ARM920 DataSheet back-to-Back, and have stumbled upon *this..... @@ -157,9 +157,12 @@ reset: /* SDRAM Setup */ - writel(0x910a8200, SDCTL0) /* Precharge cmd, CAS = 2 */ - writel(0x0, 0x08200000) /* Issue Precharge all Command */ - writel(0xa10a8200, SDCTL0) /* Autorefresh cmd, CAS = 2 */ + /* Precharge cmd, CAS = 2 */ + writel(0x910a8200, MX1_SDRAMC_BASE_ADDR + MX1_SDCTL0) + /* Issue Precharge all Command */ + writel(0x0, 0x08200000) + /* Autorefresh cmd, CAS = 2 */ + writel(0xa10a8200, MX1_SDRAMC_BASE_ADDR + MX1_SDCTL0) ldr r0, =0x08000000 ldr r1, =0x0 /* Issue AutoRefresh Command */ @@ -172,8 +175,10 @@ reset: str r1, [r0] str r1, [r0] - writel(0xb10a8300, SDCTL0) - writel(0x0, 0x08223000) /* CAS Latency 2, issue Mode Register Command, Burst Length = 8 */ - writel(0x810a8200, SDCTL0) /* Set to Normal Mode CAS 2 */ + writel(0xb10a8300, MX1_SDRAMC_BASE_ADDR + MX1_SDCTL0) + /* CAS Latency 2, issue Mode Register Command, Burst Length = 8 */ + writel(0x0, 0x08223000) + /* Set to Normal Mode CAS 2 */ + writel(0x810a8200, MX1_SDRAMC_BASE_ADDR + MX1_SDCTL0) b board_init_lowlevel_return diff --git a/arch/arm/boards/scb9328/scb9328.c b/arch/arm/boards/scb9328/scb9328.c index c83132adc8..c70852c308 100644 --- a/arch/arm/boards/scb9328/scb9328.c +++ b/arch/arm/boards/scb9328/scb9328.c @@ -19,7 +19,7 @@ #include <init.h> #include <environment.h> #include <generated/mach-types.h> -#include <mach/imx-regs.h> +#include <mach/imx1-regs.h> #include <asm/armlinux.h> #include <mach/gpio.h> #include <mach/weim.h> @@ -29,6 +29,7 @@ #include <fcntl.h> #include <dm9000.h> #include <led.h> +#include <mach/iomux-mx1.h> #include <mach/devices-imx1.h> static struct dm9000_platform_data dm9000_data = { @@ -68,8 +69,8 @@ static int scb9328_devices_init(void) for (i = 0; i < ARRAY_SIZE(leds); i++) led_gpio_register(&leds[i]); -/* CS3 becomes CS3 by clearing reset default bit 1 in FMCR */ - FMCR = 0x1; + /* CS3 becomes CS3 by clearing reset default bit 1 in FMCR */ + writel(0x1, MX1_SCM_BASE_ADDR + MX1_FMCR); imx1_setup_eimcs(0, 0x000F2000, 0x11110d01); imx1_setup_eimcs(1, 0x000F0a00, 0x11110601); diff --git a/arch/arm/boards/tqma53/board.c b/arch/arm/boards/tqma53/board.c index 8c3d855608..77535b53f2 100644 --- a/arch/arm/boards/tqma53/board.c +++ b/arch/arm/boards/tqma53/board.c @@ -30,7 +30,7 @@ #include <asm/mmu.h> #include <generated/mach-types.h> -#include <mach/imx-regs.h> +#include <mach/imx53-regs.h> #include <mach/iomux-mx53.h> #include <mach/devices-imx53.h> #include <mach/generic.h> diff --git a/arch/arm/boards/tqma53/env/init/bootargs-base b/arch/arm/boards/tqma53/env/init/bootargs-base deleted file mode 100644 index d86975406e..0000000000 --- a/arch/arm/boards/tqma53/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/tqma53/env/init/config-board b/arch/arm/boards/tqma53/env/init/config-board new file mode 100644 index 0000000000..4776438315 --- /dev/null +++ b/arch/arm/boards/tqma53/env/init/config-board @@ -0,0 +1,7 @@ +#!/bin/sh + +# board defaults, do not change in running system. Change /env/config +# instead + +global.hostname=tqma53 +global.linux.bootargs.base="console=ttymxc0,115200" diff --git a/arch/arm/boards/tqma53/env/init/hostname b/arch/arm/boards/tqma53/env/init/hostname deleted file mode 100644 index c56ac6a5ea..0000000000 --- a/arch/arm/boards/tqma53/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=tqma53 diff --git a/arch/arm/boards/versatile/versatilepb.c b/arch/arm/boards/versatile/versatilepb.c index 5a9c0b65ec..2eb7473b74 100644 --- a/arch/arm/boards/versatile/versatilepb.c +++ b/arch/arm/boards/versatile/versatilepb.c @@ -47,6 +47,7 @@ mem_initcall(vpb_mem_init); static int vpb_devices_init(void) { add_cfi_flash_device(DEVICE_ID_DYNAMIC, VERSATILE_FLASH_BASE, VERSATILE_FLASH_SIZE, 0); + versatile_register_i2c(); devfs_add_partition("nor0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self"); devfs_add_partition("nor0", 0x40000, 0x20000, DEVFS_PARTITION_FIXED, "env0"); diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig index 6a105c6ebc..2bcade91fb 100644 --- a/arch/arm/configs/at91rm9200ek_defconfig +++ b/arch/arm/configs/at91rm9200ek_defconfig @@ -32,9 +32,14 @@ CONFIG_CMD_FLASH=y CONFIG_CMD_BOOTM_ZLIB=y CONFIG_CMD_BOOTM_BZLIB=y CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_BOOTM_VERBOSE=y CONFIG_CMD_BOOTM_INITRD=y +CONFIG_CMD_BOOTM_OFTREE=y +CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y +# CONFIG_CMD_BOOTU is not set CONFIG_CMD_RESET=y CONFIG_CMD_GO=y +CONFIG_CMD_OFTREE=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y CONFIG_CMD_GPIO=y diff --git a/arch/arm/configs/at91sam9x5ek_defconfig b/arch/arm/configs/at91sam9x5ek_defconfig index cda360ddbb..6c3534849b 100644 --- a/arch/arm/configs/at91sam9x5ek_defconfig +++ b/arch/arm/configs/at91sam9x5ek_defconfig @@ -3,6 +3,7 @@ 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_EXPERIMENTAL=y CONFIG_MALLOC_TLSF=y @@ -41,6 +42,7 @@ CONFIG_CMD_OFTREE=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y CONFIG_CMD_LED=y CONFIG_CMD_LED_TRIGGER=y CONFIG_NET=y @@ -51,20 +53,31 @@ CONFIG_CMD_TFTP=y CONFIG_FS_TFTP=y CONFIG_NET_NETCONSOLE=y CONFIG_DRIVER_NET_MACB=y -# CONFIG_SPI is not set +CONFIG_DRIVER_SPI_ATMEL=y +CONFIG_MTD_M25P80=y +CONFIG_I2C=y +CONFIG_I2C_GPIO=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_DISK=y -CONFIG_DISK_WRITE=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_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_FAT=y CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y diff --git a/arch/arm/configs/clps711x_defconfig b/arch/arm/configs/clps711x_defconfig new file mode 100644 index 0000000000..cf2b3b6825 --- /dev/null +++ b/arch/arm/configs/clps711x_defconfig @@ -0,0 +1,42 @@ +CONFIG_ARCH_CLPS711X=y +CONFIG_AEABI=y +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +# CONFIG_MEMINFO is not set +CONFIG_TEXT_BASE=0xc0780000 +CONFIG_EXPERIMENTAL=y +CONFIG_BAUDRATE=57600 +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_DEFAULT_ENVIRONMENT_COMPRESSED_LZO=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/clep7212/env" +CONFIG_CMD_EDIT=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_IOMEM=y +CONFIG_CMD_CRC=y +CONFIG_CMD_CRC_CMP=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_BOOTM_INITRD=y +CONFIG_CMD_BOOTZ=y +# CONFIG_CMD_BOOTU is not set +CONFIG_CMD_RESET=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_MAGICVAR=y +CONFIG_CMD_MAGICVAR_HELP=y +# CONFIG_SPI is not set +CONFIG_DRIVER_CFI=y +# CONFIG_DRIVER_CFI_BANK_WIDTH_1 is not set +# CONFIG_DRIVER_CFI_BANK_WIDTH_4 is not set +CONFIG_MTD=y +CONFIG_DISK=y +CONFIG_DISK_WRITE=y +CONFIG_DISK_INTF_PLATFORM_IDE=y +CONFIG_FS_CRAMFS=y +CONFIG_FS_FAT=y +CONFIG_FS_FAT_LFN=y +CONFIG_LZO_DECOMPRESS=y diff --git a/arch/arm/configs/freescale_mx53_loco_defconfig b/arch/arm/configs/freescale_mx53_loco_defconfig index 37aa18239e..b50b0509c3 100644 --- a/arch/arm/configs/freescale_mx53_loco_defconfig +++ b/arch/arm/configs/freescale_mx53_loco_defconfig @@ -53,6 +53,7 @@ CONFIG_NET_PING=y CONFIG_CMD_TFTP=y CONFIG_FS_TFTP=y CONFIG_NET_NETCONSOLE=y +CONFIG_SMSC_PHY=y CONFIG_DRIVER_NET_FEC_IMX=y # CONFIG_SPI is not set CONFIG_I2C=y diff --git a/arch/arm/configs/pm9261_defconfig b/arch/arm/configs/pm9261_defconfig index 1db16d5207..0aea2c9939 100644 --- a/arch/arm/configs/pm9261_defconfig +++ b/arch/arm/configs/pm9261_defconfig @@ -50,3 +50,5 @@ CONFIG_MTD=y CONFIG_NAND=y CONFIG_NAND_ATMEL=y CONFIG_UBI=y +CONFIG_W1=y +CONFIG_W1_MASTER_GPIO=y diff --git a/arch/arm/configs/pm9263_defconfig b/arch/arm/configs/pm9263_defconfig index 8c928946da..e223e773f0 100644 --- a/arch/arm/configs/pm9263_defconfig +++ b/arch/arm/configs/pm9263_defconfig @@ -35,3 +35,5 @@ CONFIG_DRIVER_NET_MACB=y # CONFIG_SPI is not set CONFIG_DRIVER_CFI=y CONFIG_CFI_BUFFER_WRITE=y +CONFIG_W1=y +CONFIG_W1_MASTER_GPIO=y diff --git a/arch/arm/configs/pm9g45_defconfig b/arch/arm/configs/pm9g45_defconfig index 331f122635..d242bdc0f3 100644 --- a/arch/arm/configs/pm9g45_defconfig +++ b/arch/arm/configs/pm9g45_defconfig @@ -1,36 +1,52 @@ CONFIG_ARCH_AT91SAM9G45=y CONFIG_MACH_PM9G45=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_TLSF=y CONFIG_LONGHELP=y +CONFIG_GLOB=y +CONFIG_GLOB_SORT=y +CONFIG_HUSH_FANCY_PROMPT=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/pm9g45/env" -CONFIG_POLLER=y -CONFIG_ENABLE_DEVICE_NOISE=y CONFIG_CMD_EDIT=y CONFIG_CMD_SAVEENV=y CONFIG_CMD_EXPORT=y CONFIG_CMD_PRINTENV=y CONFIG_CMD_READLINE=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_LOADB=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_TIMEOUT=y CONFIG_CMD_PARTITION=y CONFIG_NET=y CONFIG_NET_DHCP=y +CONFIG_NET_NFS=y CONFIG_NET_PING=y -CONFIG_CMD_TFTP=y -CONFIG_FS_TFTP=y CONFIG_NET_RESOLV=y CONFIG_DRIVER_NET_MACB=y -CONFIG_DRIVER_SPI_ATMEL=y -CONFIG_MTD_M25P80=y -CONFIG_MTD_SST25L=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_DISK_ATA=y @@ -40,7 +56,9 @@ CONFIG_USB_OHCI_AT91=y CONFIG_USB_STORAGE=y CONFIG_MCI=y CONFIG_MCI_ATMEL=y -CONFIG_EEPROM_AT25=y +CONFIG_W1=y +CONFIG_W1_MASTER_GPIO=y +CONFIG_FS_TFTP=y CONFIG_FS_FAT=y CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y diff --git a/arch/arm/configs/rpi_defconfig b/arch/arm/configs/rpi_defconfig new file mode 100644 index 0000000000..014e28c73d --- /dev/null +++ b/arch/arm/configs/rpi_defconfig @@ -0,0 +1,41 @@ +CONFIG_ARCH_BCM2835=y +CONFIG_GPIO_BCM2835=y +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_PROMPT="R-Pi> " +CONFIG_LONGHELP=y +CONFIG_GLOB=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_MENU=y +CONFIG_PARTITION=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/raspberry-pi/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_MENU=y +CONFIG_CMD_MENU_MANAGEMENT=y +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_BOOTM_ZLIB=y +CONFIG_CMD_BOOTM_BZLIB=y +CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_RESET=y +CONFIG_CMD_CLK=y +CONFIG_CMD_GO=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_GPIO=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SHA1=y +CONFIG_SHA256=y diff --git a/arch/arm/configs/tx53stk5_defconfig b/arch/arm/configs/tx53stk5_defconfig index 95cf460b47..e0ab9c8ccf 100644 --- a/arch/arm/configs/tx53stk5_defconfig +++ b/arch/arm/configs/tx53stk5_defconfig @@ -1,13 +1,16 @@ CONFIG_ARCH_IMX=y CONFIG_ARCH_IMX53=y CONFIG_MACH_TX53=y +CONFIG_TX53_REV_XX30=y CONFIG_IMX_IIM=y CONFIG_AEABI=y CONFIG_THUMB2_BAREBOX=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_ARM_UNWIND=y +CONFIG_PBL_IMAGE=y +CONFIG_IMAGE_COMPRESSION_GZIP=y CONFIG_MMU=y -CONFIG_TEXT_BASE=0x97f00000 +CONFIG_TEXT_BASE=0x87f00000 CONFIG_MALLOC_SIZE=0x2000000 CONFIG_MALLOC_TLSF=y CONFIG_KALLSYMS=y @@ -16,7 +19,6 @@ CONFIG_HUSH_FANCY_PROMPT=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y CONFIG_MENU=y -CONFIG_DEFAULT_ENVIRONMENT_COMPRESSED_LZO=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/karo-tx53/env" CONFIG_RESET_SOURCE=y @@ -36,8 +38,6 @@ CONFIG_CMD_MEMINFO=y CONFIG_CMD_IOMEM=y CONFIG_CMD_CRC=y CONFIG_CMD_CRC_CMP=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 @@ -47,6 +47,8 @@ CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y CONFIG_CMD_UIMAGE=y CONFIG_CMD_RESET=y CONFIG_CMD_GO=y +CONFIG_CMD_MTEST=y +CONFIG_CMD_MTEST_ALTERNATIVE=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y CONFIG_CMD_MAGICVAR=y @@ -57,8 +59,6 @@ CONFIG_CMD_LED=y CONFIG_NET=y CONFIG_NET_DHCP=y CONFIG_NET_PING=y -CONFIG_NET_TFTP=y -CONFIG_NET_TFTP_PUSH=y CONFIG_DRIVER_NET_FEC_IMX=y CONFIG_MTD=y CONFIG_NAND=y diff --git a/arch/arm/configs/versatilepb_defconfig b/arch/arm/configs/versatilepb_defconfig index 87aec4d526..8daf9ae72f 100644 --- a/arch/arm/configs/versatilepb_defconfig +++ b/arch/arm/configs/versatilepb_defconfig @@ -32,7 +32,9 @@ CONFIG_CMD_RESET=y CONFIG_CMD_GO=y CONFIG_CMD_TIMEOUT=y CONFIG_CMD_PARTITION=y +CONFIG_CMD_GPIO=y CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_I2C=y CONFIG_NET=y CONFIG_NET_DHCP=y CONFIG_NET_NFS=y @@ -43,6 +45,9 @@ CONFIG_NET_NETCONSOLE=y CONFIG_NET_RESOLV=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_DRIVER_NET_SMC91111=y +CONFIG_GPIO_PL061=y +CONFIG_I2C=y +CONFIG_I2C_VERSATILE=y CONFIG_FS_CRAMFS=y CONFIG_SHA1=y CONFIG_SHA256=y diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig index 2ed678961d..d8a5fb1734 100644 --- a/arch/arm/cpu/Kconfig +++ b/arch/arm/cpu/Kconfig @@ -8,6 +8,11 @@ config CPU_32 # which CPUs we support in the kernel image, and the compiler instruction # optimiser behaviour. +# ARM1176 +config CPU_ARM1176 + bool + select CPU_V6 + # ARM920T config CPU_ARM920T bool diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile index f7ab2761ad..4b0259c15b 100644 --- a/arch/arm/cpu/Makefile +++ b/arch/arm/cpu/Makefile @@ -1,14 +1,15 @@ obj-y += cpu.o obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions.o obj-$(CONFIG_ARM_EXCEPTIONS) += interrupts.o -obj-y += start.o +obj-y += start.o setupc.o # # Any variants can be called as start-armxyz.S # obj-$(CONFIG_CMD_ARM_CPUINFO) += cpuinfo.o obj-$(CONFIG_CMD_ARM_MMUINFO) += mmuinfo.o -obj-$(CONFIG_MMU) += mmu.o +obj-$(CONFIG_MMU) += mmu.o cache.o +pbl-$(CONFIG_MMU) += cache.o obj-$(CONFIG_CPU_32v4T) += cache-armv4.o pbl-$(CONFIG_CPU_32v4T) += cache-armv4.o obj-$(CONFIG_CPU_32v5) += cache-armv5.o @@ -19,4 +20,4 @@ obj-$(CONFIG_CPU_32v7) += cache-armv7.o pbl-$(CONFIG_CPU_32v7) += cache-armv7.o obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o -pbl-y += start-pbl.o +pbl-y += start-pbl.o setupc.o diff --git a/arch/arm/cpu/cache-armv4.S b/arch/arm/cpu/cache-armv4.S index 22fab1455c..1d1a1e32bf 100644 --- a/arch/arm/cpu/cache-armv4.S +++ b/arch/arm/cpu/cache-armv4.S @@ -4,7 +4,7 @@ #define CACHE_DLINESIZE 32 .section .text.__mmu_cache_on -ENTRY(__mmu_cache_on) +ENTRY(v4_mmu_cache_on) mov r12, lr #ifdef CONFIG_MMU mov r0, #0 @@ -21,7 +21,7 @@ ENTRY(__mmu_cache_on) mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs #endif mov pc, r12 -ENDPROC(__mmu_cache_on) +ENDPROC(v4_mmu_cache_on) __common_mmu_cache_on: orr r0, r0, #0x000d @ Write buffer, mmu @@ -31,8 +31,8 @@ __common_mmu_cache_on: mrc p15, 0, r0, c1, c0, 0 @ and read it back to sub pc, lr, r0, lsr #32 @ properly flush pipeline -.section .text.__mmu_cache_off -ENTRY(__mmu_cache_off) +.section .text.v4_mmu_cache_off +ENTRY(v4_mmu_cache_off) #ifdef CONFIG_MMU mrc p15, 0, r0, c1, c0 bic r0, r0, #0x000d @@ -42,10 +42,10 @@ ENTRY(__mmu_cache_off) mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 #endif mov pc, lr -ENDPROC(__mmu_cache_off) +ENDPROC(v4_mmu_cache_off) -.section .text.__mmu_cache_flush -ENTRY(__mmu_cache_flush) +.section .text.v4_mmu_cache_flush +ENTRY(v4_mmu_cache_flush) stmfd sp!, {r6, r11, lr} mrc p15, 0, r6, c0, c0 @ get processor ID mov r2, #64*1024 @ default: 32K dcache size (*2) @@ -76,7 +76,7 @@ no_cache_id: mcr p15, 0, r1, c7, c6, 0 @ flush D cache mcr p15, 0, r1, c7, c10, 4 @ drain WB ldmfd sp!, {r6, r11, pc} -ENDPROC(__mmu_cache_flush) +ENDPROC(v4_mmu_cache_flush) /* * dma_inv_range(start, end) @@ -91,8 +91,8 @@ ENDPROC(__mmu_cache_flush) * * (same as v4wb) */ -.section .text.__dma_inv_range -ENTRY(__dma_inv_range) +.section .text.v4_dma_inv_range +ENTRY(v4_dma_inv_range) tst r0, #CACHE_DLINESIZE - 1 bic r0, r0, #CACHE_DLINESIZE - 1 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry @@ -115,8 +115,8 @@ ENTRY(__dma_inv_range) * * (same as v4wb) */ -.section .text.__dma_clean_range -ENTRY(__dma_clean_range) +.section .text.v4_dma_clean_range +ENTRY(v4_dma_clean_range) bic r0, r0, #CACHE_DLINESIZE - 1 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #CACHE_DLINESIZE @@ -133,8 +133,8 @@ ENTRY(__dma_clean_range) * - start - virtual start address * - end - virtual end address */ -.section .text.__dma_flush_range -ENTRY(__dma_flush_range) +.section .text.v4_dma_flush_range +ENTRY(v4_dma_flush_range) bic r0, r0, #CACHE_DLINESIZE - 1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE diff --git a/arch/arm/cpu/cache-armv5.S b/arch/arm/cpu/cache-armv5.S index d6ffaf10e2..4267f3e37f 100644 --- a/arch/arm/cpu/cache-armv5.S +++ b/arch/arm/cpu/cache-armv5.S @@ -3,8 +3,8 @@ #define CACHE_DLINESIZE 32 -.section .text.__mmu_cache_on -ENTRY(__mmu_cache_on) +.section .text.v5_mmu_cache_on +ENTRY(v5_mmu_cache_on) mov r12, lr #ifdef CONFIG_MMU mov r0, #0 @@ -21,7 +21,7 @@ ENTRY(__mmu_cache_on) mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs #endif mov pc, r12 -ENDPROC(__mmu_cache_on) +ENDPROC(v5_mmu_cache_on) __common_mmu_cache_on: orr r0, r0, #0x000d @ Write buffer, mmu @@ -31,8 +31,8 @@ __common_mmu_cache_on: mrc p15, 0, r0, c1, c0, 0 @ and read it back to sub pc, lr, r0, lsr #32 @ properly flush pipeline -.section .text.__mmu_cache_off -ENTRY(__mmu_cache_off) +.section .text.v5_mmu_cache_off +ENTRY(v5_mmu_cache_off) #ifdef CONFIG_MMU mrc p15, 0, r0, c1, c0 bic r0, r0, #0x000d @@ -42,16 +42,16 @@ ENTRY(__mmu_cache_off) mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 #endif mov pc, lr -ENDPROC(__mmu_cache_off) +ENDPROC(v5_mmu_cache_off) -.section .text.__mmu_cache_flush -ENTRY(__mmu_cache_flush) +.section .text.v5_mmu_cache_flush +ENTRY(v5_mmu_cache_flush) 1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache bne 1b mcr p15, 0, r0, c7, c5, 0 @ flush I cache mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr -ENDPROC(__mmu_cache_flush) +ENDPROC(v5_mmu_cache_flush) /* * dma_inv_range(start, end) @@ -66,8 +66,8 @@ ENDPROC(__mmu_cache_flush) * * (same as v4wb) */ -.section .text.__dma_inv_range -ENTRY(__dma_inv_range) +.section .text.v5_dma_inv_range +ENTRY(v5_dma_inv_range) tst r0, #CACHE_DLINESIZE - 1 bic r0, r0, #CACHE_DLINESIZE - 1 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry @@ -90,8 +90,8 @@ ENTRY(__dma_inv_range) * * (same as v4wb) */ -.section .text.__dma_clean_range -ENTRY(__dma_clean_range) +.section .text.v5_dma_clean_range +ENTRY(v5_dma_clean_range) bic r0, r0, #CACHE_DLINESIZE - 1 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #CACHE_DLINESIZE @@ -108,8 +108,8 @@ ENTRY(__dma_clean_range) * - start - virtual start address * - end - virtual end address */ -.section .text.__dma_flush_range -ENTRY(__dma_flush_range) +.section .text.v5_dma_flush_range +ENTRY(v5_dma_flush_range) bic r0, r0, #CACHE_DLINESIZE - 1 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE diff --git a/arch/arm/cpu/cache-armv6.S b/arch/arm/cpu/cache-armv6.S index 02b1d3e58a..7a06751997 100644 --- a/arch/arm/cpu/cache-armv6.S +++ b/arch/arm/cpu/cache-armv6.S @@ -5,8 +5,8 @@ #define CACHE_LINE_SIZE 32 #define D_CACHE_LINE_SIZE 32 -.section .text.__mmu_cache_on -ENTRY(__mmu_cache_on) +.section .text.v6_mmu_cache_on +ENTRY(v6_mmu_cache_on) mov r12, lr #ifdef CONFIG_MMU mov r0, #0 @@ -23,7 +23,7 @@ ENTRY(__mmu_cache_on) mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs #endif mov pc, r12 -ENDPROC(__mmu_cache_on) +ENDPROC(v6_mmu_cache_on) __common_mmu_cache_on: orr r0, r0, #0x000d @ Write buffer, mmu @@ -34,8 +34,8 @@ __common_mmu_cache_on: sub pc, lr, r0, lsr #32 @ properly flush pipeline -.section .text.__mmu_cache_off -ENTRY(__mmu_cache_off) +.section .text.v6_mmu_cache_off +ENTRY(v6_mmu_cache_off) #ifdef CONFIG_MMU mrc p15, 0, r0, c1, c0 bic r0, r0, #0x000d @@ -46,15 +46,15 @@ ENTRY(__mmu_cache_off) #endif mov pc, lr -.section .text.__mmu_cache_flush -ENTRY(__mmu_cache_flush) +.section .text.v6_mmu_cache_flush +ENTRY(v6_mmu_cache_flush) mov r1, #0 mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB mcr p15, 0, r1, c7, c15, 0 @ clean+invalidate unified mcr p15, 0, r1, c7, c10, 4 @ drain WB mov pc, lr -ENDPROC(__mmu_cache_flush) +ENDPROC(v6_mmu_cache_flush) /* * v6_dma_inv_range(start,end) @@ -66,8 +66,8 @@ ENDPROC(__mmu_cache_flush) * - start - virtual start address of region * - end - virtual end address of region */ -.section .text.__dma_inv_range -ENTRY(__dma_inv_range) +.section .text.v6_dma_inv_range +ENTRY(v6_dma_inv_range) tst r0, #D_CACHE_LINE_SIZE - 1 bic r0, r0, #D_CACHE_LINE_SIZE - 1 #ifdef HARVARD_CACHE @@ -94,15 +94,15 @@ ENTRY(__dma_inv_range) mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer mov pc, lr -ENDPROC(__dma_inv_range) +ENDPROC(v6_dma_inv_range) /* * v6_dma_clean_range(start,end) * - start - virtual start address of region * - end - virtual end address of region */ -.section .text.__dma_clean_range -ENTRY(__dma_clean_range) +.section .text.v6_dma_clean_range +ENTRY(v6_dma_clean_range) bic r0, r0, #D_CACHE_LINE_SIZE - 1 1: #ifdef HARVARD_CACHE @@ -116,15 +116,15 @@ ENTRY(__dma_clean_range) mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer mov pc, lr -ENDPROC(__dma_clean_range) +ENDPROC(v6_dma_clean_range) /* * v6_dma_flush_range(start,end) * - start - virtual start address of region * - end - virtual end address of region */ -.section .text.__dma_flush_range -ENTRY(__dma_flush_range) +.section .text.v6_dma_flush_range +ENTRY(v6_dma_flush_range) bic r0, r0, #D_CACHE_LINE_SIZE - 1 1: #ifdef HARVARD_CACHE @@ -138,4 +138,4 @@ ENTRY(__dma_flush_range) mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer mov pc, lr -ENDPROC(__dma_flush_range) +ENDPROC(v6_dma_flush_range) diff --git a/arch/arm/cpu/cache-armv7.S b/arch/arm/cpu/cache-armv7.S index 2eba959672..2d68f27eeb 100644 --- a/arch/arm/cpu/cache-armv7.S +++ b/arch/arm/cpu/cache-armv7.S @@ -1,8 +1,8 @@ #include <linux/linkage.h> #include <init.h> -.section .text.__mmu_cache_on -ENTRY(__mmu_cache_on) +.section .text.v7_mmu_cache_on +ENTRY(v7_mmu_cache_on) stmfd sp!, {r11, lr} mov r12, lr #ifdef CONFIG_MMU @@ -30,10 +30,10 @@ ENTRY(__mmu_cache_on) mov r0, #0 mcr p15, 0, r0, c7, c5, 4 @ ISB ldmfd sp!, {r11, pc} -ENDPROC(__mmu_cache_on) +ENDPROC(v7_mmu_cache_on) -.section .text.__mmu_cache_off -ENTRY(__mmu_cache_off) +.section .text.v7_mmu_cache_off +ENTRY(v7_mmu_cache_off) mrc p15, 0, r0, c1, c0 #ifdef CONFIG_MMU bic r0, r0, #0x000d @@ -42,7 +42,7 @@ ENTRY(__mmu_cache_off) #endif mcr p15, 0, r0, c1, c0 @ turn MMU and cache off mov r12, lr - bl __mmu_cache_flush + bl v7_mmu_cache_flush mov r0, #0 #ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB @@ -51,10 +51,10 @@ ENTRY(__mmu_cache_off) mcr p15, 0, r0, c7, c10, 4 @ DSB mcr p15, 0, r0, c7, c5, 4 @ ISB mov pc, r12 -ENDPROC(__mmu_cache_off) +ENDPROC(v7_mmu_cache_off) -.section .text.__mmu_cache_flush -ENTRY(__mmu_cache_flush) +.section .text.v7_mmu_cache_flush +ENTRY(v7_mmu_cache_flush) stmfd sp!, {r10, lr} mrc p15, 0, r10, c0, c1, 5 @ read ID_MMFR1 tst r10, #0xf << 16 @ hierarchical cache (ARMv7) @@ -114,7 +114,7 @@ iflush: mcr p15, 0, r10, c7, c10, 4 @ DSB mcr p15, 0, r10, c7, c5, 4 @ ISB ldmfd sp!, {r10, pc} -ENDPROC(__mmu_cache_flush) +ENDPROC(v7_mmu_cache_flush) /* * cache_line_size - get the cache line size from the CSIDR register @@ -138,8 +138,8 @@ ENDPROC(__mmu_cache_flush) * - start - virtual start address of region * - end - virtual end address of region */ -.section .text.__dma_inv_range -ENTRY(__dma_inv_range) +.section .text.v7_dma_inv_range +ENTRY(v7_dma_inv_range) dcache_line_size r2, r3 sub r3, r2, #1 tst r0, r3 @@ -156,15 +156,15 @@ ENTRY(__dma_inv_range) blo 1b dsb mov pc, lr -ENDPROC(__dma_inv_range) +ENDPROC(v7_dma_inv_range) /* * v7_dma_clean_range(start,end) * - start - virtual start address of region * - end - virtual end address of region */ -.section .text.__dma_clean_range -ENTRY(__dma_clean_range) +.section .text.v7_dma_clean_range +ENTRY(v7_dma_clean_range) dcache_line_size r2, r3 sub r3, r2, #1 bic r0, r0, r3 @@ -175,15 +175,15 @@ ENTRY(__dma_clean_range) blo 1b dsb mov pc, lr -ENDPROC(__dma_clean_range) +ENDPROC(v7_dma_clean_range) /* * v7_dma_flush_range(start,end) * - start - virtual start address of region * - end - virtual end address of region */ -.section .text.__dma_flush_range -ENTRY(__dma_flush_range) +.section .text.v7_dma_flush_range +ENTRY(v7_dma_flush_range) dcache_line_size r2, r3 sub r3, r2, #1 bic r0, r0, r3 @@ -194,4 +194,4 @@ ENTRY(__dma_flush_range) blo 1b dsb mov pc, lr -ENDPROC(__dma_flush_range) +ENDPROC(v7_dma_flush_range) diff --git a/arch/arm/cpu/cache.c b/arch/arm/cpu/cache.c new file mode 100644 index 0000000000..1254609bb6 --- /dev/null +++ b/arch/arm/cpu/cache.c @@ -0,0 +1,103 @@ +#include <common.h> +#include <init.h> +#include <asm/mmu.h> +#include <asm/cache.h> +#include <asm/system_info.h> + +int arm_architecture; + +struct cache_fns { + void (*dma_clean_range)(unsigned long start, unsigned long end); + void (*dma_flush_range)(unsigned long start, unsigned long end); + void (*dma_inv_range)(unsigned long start, unsigned long end); + void (*mmu_cache_on)(void); + void (*mmu_cache_off)(void); + void (*mmu_cache_flush)(void); +}; + +struct cache_fns *cache_fns; + +#define DEFINE_CPU_FNS(arch) \ + void arch##_dma_clean_range(unsigned long start, unsigned long end); \ + void arch##_dma_flush_range(unsigned long start, unsigned long end); \ + void arch##_dma_inv_range(unsigned long start, unsigned long end); \ + void arch##_mmu_cache_on(void); \ + void arch##_mmu_cache_off(void); \ + void arch##_mmu_cache_flush(void); \ + \ + static struct cache_fns __maybe_unused cache_fns_arm##arch = { \ + .dma_clean_range = arch##_dma_clean_range, \ + .dma_flush_range = arch##_dma_flush_range, \ + .dma_inv_range = arch##_dma_inv_range, \ + .mmu_cache_on = arch##_mmu_cache_on, \ + .mmu_cache_off = arch##_mmu_cache_off, \ + .mmu_cache_flush = arch##_mmu_cache_flush, \ + }; + +DEFINE_CPU_FNS(v4) +DEFINE_CPU_FNS(v5) +DEFINE_CPU_FNS(v6) +DEFINE_CPU_FNS(v7) + +void __dma_clean_range(unsigned long start, unsigned long end) +{ + cache_fns->dma_clean_range(start, end); +} + +void __dma_flush_range(unsigned long start, unsigned long end) +{ + cache_fns->dma_flush_range(start, end); +} + +void __dma_inv_range(unsigned long start, unsigned long end) +{ + cache_fns->dma_inv_range(start, end); +} + +void __mmu_cache_on(void) +{ + cache_fns->mmu_cache_on(); +} + +void __mmu_cache_off(void) +{ + cache_fns->mmu_cache_off(); +} + +void __mmu_cache_flush(void) +{ + cache_fns->mmu_cache_flush(); +} + +int arm_set_cache_functions(void) +{ + switch (cpu_architecture()) { +#ifdef CONFIG_CPU_32v4T + case CPU_ARCH_ARMv4T: + cache_fns = &cache_fns_armv4; + break; +#endif +#ifdef CONFIG_CPU_32v5 + case CPU_ARCH_ARMv5: + case CPU_ARCH_ARMv5T: + case CPU_ARCH_ARMv5TE: + case CPU_ARCH_ARMv5TEJ: + cache_fns = &cache_fns_armv5; + break; +#endif +#ifdef CONFIG_CPU_32v6 + case CPU_ARCH_ARMv6: + cache_fns = &cache_fns_armv6; + break; +#endif +#ifdef CONFIG_CPU_32v7 + case CPU_ARCH_ARMv7: + cache_fns = &cache_fns_armv7; + break; +#endif + default: + BUG(); + } + + return 0; +} diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c index 87ba877013..2ca871fc60 100644 --- a/arch/arm/cpu/cpu.c +++ b/arch/arm/cpu/cpu.c @@ -28,6 +28,10 @@ #include <asm/mmu.h> #include <asm/system.h> #include <asm/memory.h> +#include <asm/system_info.h> +#include <asm/cputype.h> +#include <asm/cache.h> +#include <asm/ptrace.h> /** * Enable processor's instruction cache @@ -71,20 +75,20 @@ int icache_status(void) */ void arch_shutdown(void) { + uint32_t r; + #ifdef CONFIG_MMU - /* nearly the same as below, but this could also disable - * second level cache. - */ mmu_disable(); -#else - asm volatile ( - "bl __mmu_cache_flush;" - "bl __mmu_cache_off;" - : - : - : "r0", "r1", "r2", "r3", "r6", "r10", "r12", "lr", "cc", "memory" - ); #endif + flush_icache(); + /* + * barebox normally does not use interrupts, but some functionalities + * (eg. OMAP4_USBBOOT) require them enabled. So be sure interrupts are + * disabled before exiting. + */ + __asm__ __volatile__("mrs %0, cpsr" : "=r"(r)); + r |= PSR_I_BIT; + __asm__ __volatile__("msr cpsr, %0" : : "r"(r)); } #ifdef CONFIG_THUMB2_BAREBOX @@ -112,3 +116,48 @@ static int execute_init(void) } postcore_initcall(execute_init); #endif + +#ifdef ARM_MULTIARCH +static int __get_cpu_architecture(void) +{ + int cpu_arch; + + if ((read_cpuid_id() & 0x0008f000) == 0) { + cpu_arch = CPU_ARCH_UNKNOWN; + } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) { + cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3; + } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) { + cpu_arch = (read_cpuid_id() >> 16) & 7; + if (cpu_arch) + cpu_arch += CPU_ARCH_ARMv3; + } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { + unsigned int mmfr0; + + /* Revised CPUID format. Read the Memory Model Feature + * Register 0 and check for VMSAv7 or PMSAv7 */ + asm("mrc p15, 0, %0, c0, c1, 4" + : "=r" (mmfr0)); + if ((mmfr0 & 0x0000000f) >= 0x00000003 || + (mmfr0 & 0x000000f0) >= 0x00000030) + cpu_arch = CPU_ARCH_ARMv7; + else if ((mmfr0 & 0x0000000f) == 0x00000002 || + (mmfr0 & 0x000000f0) == 0x00000020) + cpu_arch = CPU_ARCH_ARMv6; + else + cpu_arch = CPU_ARCH_UNKNOWN; + } else + cpu_arch = CPU_ARCH_UNKNOWN; + + return cpu_arch; +} + +int __cpu_architecture; + +int __pure cpu_architecture(void) +{ + if(__cpu_architecture == CPU_ARCH_UNKNOWN) + __cpu_architecture = __get_cpu_architecture(); + + return __cpu_architecture; +} +#endif diff --git a/arch/arm/cpu/exceptions.S b/arch/arm/cpu/exceptions.S index 7f94f9f929..115c4e56b8 100644 --- a/arch/arm/cpu/exceptions.S +++ b/arch/arm/cpu/exceptions.S @@ -35,10 +35,6 @@ #define S_R0 0 #define MODE_SVC 0x13 -#define I_BIT 0x80 - -_STACK_START: - .word STACK_BASE + STACK_SIZE - 4 /* * use bad_save_user_regs for abort/prefetch/undef/swi ... @@ -48,8 +44,7 @@ _STACK_START: .macro bad_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0-r12 - ldr r2, _STACK_START - sub r2, r2, #(8) @ set base 2 words into abort stack + ldr r2, =abort_stack ldmia r2, {r2 - r3} @ get pc, cpsr add r0, sp, #S_FRAME_SIZE @ restore sp_SVC @@ -80,9 +75,7 @@ _STACK_START: .endm .macro get_bad_stack - ldr r13, _STACK_START - sub r13, r13, #(8) @ reserved a couple spots in abort stack - + ldr r13, =abort_stack str lr, [r13] @ save caller lr / spsr mrs lr, spsr str lr, [r13, #4] @@ -163,3 +156,8 @@ fiq: 1: b 1b /* irq (interrupt) */ 1: b 1b /* fiq (fast interrupt) */ #endif + +.section .data +.align 4 +abort_stack: +.space 8 diff --git a/arch/arm/cpu/interrupts.c b/arch/arm/cpu/interrupts.c index 4ed562f3dd..6e60adc43a 100644 --- a/arch/arm/cpu/interrupts.c +++ b/arch/arm/cpu/interrupts.c @@ -57,9 +57,9 @@ void show_regs (struct pt_regs *regs) printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0); printf ("Flags: %c%c%c%c", - flags & CC_N_BIT ? 'N' : 'n', - flags & CC_Z_BIT ? 'Z' : 'z', - flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v'); + flags & PSR_N_BIT ? 'N' : 'n', + flags & PSR_Z_BIT ? 'Z' : 'z', + flags & PSR_C_BIT ? 'C' : 'c', flags & PSR_V_BIT ? 'V' : 'v'); printf (" IRQs %s FIQs %s Mode %s%s\n", interrupts_enabled (regs) ? "on" : "off", fast_interrupts_enabled (regs) ? "on" : "off", diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c index e3ca722300..068e0eac1d 100644 --- a/arch/arm/cpu/mmu.c +++ b/arch/arm/cpu/mmu.c @@ -6,7 +6,9 @@ #include <asm/memory.h> #include <asm/barebox-arm.h> #include <asm/system.h> +#include <asm/cache.h> #include <memory.h> +#include <asm/system_info.h> #include "mmu.h" @@ -43,13 +45,15 @@ static inline void tlb_invalidate(void) ); } -#ifdef CONFIG_CPU_V7 -#define PTE_FLAGS_CACHED (PTE_EXT_TEX(1) | PTE_BUFFERABLE | PTE_CACHEABLE) -#define PTE_FLAGS_UNCACHED (0) -#else -#define PTE_FLAGS_CACHED (PTE_SMALL_AP_UNO_SRW | PTE_BUFFERABLE | PTE_CACHEABLE) -#define PTE_FLAGS_UNCACHED PTE_SMALL_AP_UNO_SRW -#endif +extern int arm_architecture; + +#define PTE_FLAGS_CACHED_V7 (PTE_EXT_TEX(1) | PTE_BUFFERABLE | PTE_CACHEABLE) +#define PTE_FLAGS_UNCACHED_V7 (0) +#define PTE_FLAGS_CACHED_V4 (PTE_SMALL_AP_UNO_SRW | PTE_BUFFERABLE | PTE_CACHEABLE) +#define PTE_FLAGS_UNCACHED_V4 PTE_SMALL_AP_UNO_SRW + +static uint32_t PTE_FLAGS_CACHED; +static uint32_t PTE_FLAGS_UNCACHED; #define PTE_MASK ((1 << 12) - 1) @@ -226,6 +230,16 @@ static int mmu_init(void) struct memory_bank *bank; int i; + arm_set_cache_functions(); + + if (cpu_architecture() >= CPU_ARCH_ARMv7) { + PTE_FLAGS_CACHED = PTE_FLAGS_CACHED_V7; + PTE_FLAGS_UNCACHED = PTE_FLAGS_UNCACHED_V7; + } else { + PTE_FLAGS_CACHED = PTE_FLAGS_CACHED_V4; + PTE_FLAGS_UNCACHED = PTE_FLAGS_UNCACHED_V4; + } + ttb = memalign(0x10000, 0x4000); debug("ttb: 0x%p\n", ttb); diff --git a/arch/arm/cpu/setupc.S b/arch/arm/cpu/setupc.S new file mode 100644 index 0000000000..9a8d54c224 --- /dev/null +++ b/arch/arm/cpu/setupc.S @@ -0,0 +1,34 @@ +#include <linux/linkage.h> + +.section .text.setupc + +/* + * setup_c: copy binary to link address, clear bss and + * continue executing at new address. + * + * This function does not return to the address it is + * called from, but to the same location in the copied + * binary. + */ +ENTRY(setup_c) + push {r4, r5} + mov r5, lr + bl get_runtime_offset + subs r4, r0, #0 + beq 1f /* skip memcpy if already at correct address */ + ldr r0,=_text + ldr r2,=__bss_start + sub r2, r2, r0 + sub r1, r0, r4 + bl memcpy /* memcpy(_text, _text - offset, __bss_start - _text) */ +1: ldr r0, =__bss_start + mov r1, #0 + ldr r2, =__bss_stop + sub r2, r2, r0 + bl memset /* clear bss */ + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 /* flush icache */ + add lr, r5, r4 /* adjust return address to new location */ + pop {r4, r5} + mov pc, lr +ENDPROC(setup_c) diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c index 0467dfe832..609aedb39c 100644 --- a/arch/arm/cpu/start-pbl.c +++ b/arch/arm/cpu/start-pbl.c @@ -174,12 +174,11 @@ static void barebox_uncompress(void *compressed_start, unsigned int len) */ void __naked board_init_lowlevel_return(void) { - uint32_t r, offset; + uint32_t offset; uint32_t pg_start, pg_end, pg_len; /* Setup the stack */ - r = STACK_BASE + STACK_SIZE - 16; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); + arm_setup_stack(STACK_BASE + STACK_SIZE - 16); /* Get offset between linked address and runtime address */ offset = get_runtime_offset(); @@ -188,43 +187,16 @@ void __naked board_init_lowlevel_return(void) pg_end = (uint32_t)&input_data_end - offset; pg_len = pg_end - pg_start; - if (IS_ENABLED(CONFIG_PBL_FORCE_PIGGYDATA_COPY)) - goto copy_piggy_link; + if (offset && (IS_ENABLED(CONFIG_PBL_FORCE_PIGGYDATA_COPY) || + region_overlap(pg_start, pg_len, TEXT_BASE, pg_len * 4))) { + /* + * copy piggydata binary to its link address + */ + memcpy(&input_data, (void *)pg_start, pg_len); + pg_start = (uint32_t)&input_data; + } - /* - * Check if the piggydata binary will be overwritten - * by the uncompressed binary or by the pbl relocation - */ - if (!offset || - !((pg_start >= TEXT_BASE && pg_start < TEXT_BASE + pg_len * 4) || - ((uint32_t)_text >= pg_start && (uint32_t)_text <= pg_end))) - goto copy_link; - -copy_piggy_link: - /* - * copy piggydata binary to its link address - */ - memcpy(&input_data, (void *)pg_start, pg_len); - pg_start = (uint32_t)&input_data; - -copy_link: - /* relocate to link address if necessary */ - if (offset) - memcpy((void *)_text, (void *)(_text - offset), - __bss_start - _text); - - /* clear bss */ - memset(__bss_start, 0, __bss_stop - __bss_start); - - flush_icache(); + setup_c(); - r = (unsigned int)&barebox_uncompress; - /* call barebox_uncompress with its absolute address */ - __asm__ __volatile__( - "mov r0, %1\n" - "mov r1, %2\n" - "mov pc, %0\n" - : - : "r"(r), "r"(pg_start), "r"(pg_len) - : "r0", "r1"); + barebox_uncompress((void *)pg_start, pg_len); } diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c index 867626758d..793445a828 100644 --- a/arch/arm/cpu/start.c +++ b/arch/arm/cpu/start.c @@ -24,32 +24,19 @@ #include <asm-generic/memory_layout.h> #include <asm/sections.h> #include <asm/cache.h> +#include <memory.h> -#ifdef CONFIG_PBL_IMAGE /* * First function in the uncompressed image. We get here from * the pbl. */ void __naked __section(.text_entry) start(void) { - u32 r; - - /* Setup the stack */ - r = STACK_BASE + STACK_SIZE - 16; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); - /* clear bss */ - memset(__bss_start, 0, __bss_stop - __bss_start); - - start_barebox(); -} +#ifdef CONFIG_PBL_IMAGE + board_init_lowlevel_return(); #else - -/* - * First function in the image without pbl support - */ -void __naked __section(.text_entry) start(void) -{ barebox_arm_head(); +#endif } /* @@ -70,27 +57,9 @@ void __naked __bare_init reset(void) */ void __naked board_init_lowlevel_return(void) { - uint32_t r, offset; - - /* Setup the stack */ - r = STACK_BASE + STACK_SIZE - 16; - __asm__ __volatile__("mov sp, %0" : : "r"(r)); - - /* Get offset between linked address and runtime address */ - offset = get_runtime_offset(); + arm_setup_stack(STACK_BASE + STACK_SIZE - 16); - /* relocate to link address if necessary */ - if (offset) - memcpy((void *)_text, (void *)(_text - offset), - __bss_start - _text); + setup_c(); - /* clear bss */ - memset(__bss_start, 0, __bss_stop - __bss_start); - - flush_icache(); - - /* call start_barebox with its absolute address */ - r = (unsigned int)&start_barebox; - __asm__ __volatile__("mov pc, %0" : : "r"(r)); + start_barebox(); } -#endif diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h index 9e17b4f5fb..993130df2d 100644 --- a/arch/arm/include/asm/barebox-arm.h +++ b/arch/arm/include/asm/barebox-arm.h @@ -38,4 +38,6 @@ void board_init_lowlevel(void); void board_init_lowlevel_return(void); uint32_t get_runtime_offset(void); +void setup_c(void); + #endif /* _BAREBOX_ARM_H_ */ diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h index ff797493f7..d5877ffc44 100644 --- a/arch/arm/include/asm/cache.h +++ b/arch/arm/include/asm/cache.h @@ -6,4 +6,6 @@ static inline void flush_icache(void) asm volatile("mcr p15, 0, %0, c7, c5, 0" : : "r" (0)); } +int arm_set_cache_functions(void); + #endif diff --git a/arch/arm/include/asm/common.h b/arch/arm/include/asm/common.h index f3a87c81c9..133bb8e1f6 100644 --- a/arch/arm/include/asm/common.h +++ b/arch/arm/include/asm/common.h @@ -16,4 +16,9 @@ static inline unsigned long get_pc(void) return pc; } +static inline void arm_setup_stack(unsigned long top) +{ + __asm__ __volatile__("mov sp, %0" : : "r"(top)); +} + #endif /* __ASM_ARM_COMMON_H */ diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h new file mode 100644 index 0000000000..f39939bd44 --- /dev/null +++ b/arch/arm/include/asm/cputype.h @@ -0,0 +1,100 @@ +#ifndef __ASM_ARM_CPUTYPE_H +#define __ASM_ARM_CPUTYPE_H + +#include <linux/stringify.h> +#include <linux/kernel.h> + +#define CPUID_ID 0 +#define CPUID_CACHETYPE 1 +#define CPUID_TCM 2 +#define CPUID_TLBTYPE 3 +#define CPUID_MPIDR 5 + +#define CPUID_EXT_PFR0 "c1, 0" +#define CPUID_EXT_PFR1 "c1, 1" +#define CPUID_EXT_DFR0 "c1, 2" +#define CPUID_EXT_AFR0 "c1, 3" +#define CPUID_EXT_MMFR0 "c1, 4" +#define CPUID_EXT_MMFR1 "c1, 5" +#define CPUID_EXT_MMFR2 "c1, 6" +#define CPUID_EXT_MMFR3 "c1, 7" +#define CPUID_EXT_ISAR0 "c2, 0" +#define CPUID_EXT_ISAR1 "c2, 1" +#define CPUID_EXT_ISAR2 "c2, 2" +#define CPUID_EXT_ISAR3 "c2, 3" +#define CPUID_EXT_ISAR4 "c2, 4" +#define CPUID_EXT_ISAR5 "c2, 5" + +extern unsigned int processor_id; + +#define read_cpuid(reg) \ + ({ \ + unsigned int __val; \ + asm("mrc p15, 0, %0, c0, c0, " __stringify(reg) \ + : "=r" (__val) \ + : \ + : "cc"); \ + __val; \ + }) +#define read_cpuid_ext(ext_reg) \ + ({ \ + unsigned int __val; \ + asm("mrc p15, 0, %0, c0, " ext_reg \ + : "=r" (__val) \ + : \ + : "cc"); \ + __val; \ + }) + +/* + * The CPU ID never changes at run time, so we might as well tell the + * compiler that it's constant. Use this function to read the CPU ID + * rather than directly reading processor_id or read_cpuid() directly. + */ +static inline unsigned int __attribute_const__ read_cpuid_id(void) +{ + return read_cpuid(CPUID_ID); +} + +static inline unsigned int __attribute_const__ read_cpuid_cachetype(void) +{ + return read_cpuid(CPUID_CACHETYPE); +} + +static inline unsigned int __attribute_const__ read_cpuid_tcmstatus(void) +{ + return read_cpuid(CPUID_TCM); +} + +static inline unsigned int __attribute_const__ read_cpuid_mpidr(void) +{ + return read_cpuid(CPUID_MPIDR); +} + +/* + * Intel's XScale3 core supports some v6 features (supersections, L2) + * but advertises itself as v5 as it does not support the v6 ISA. For + * this reason, we need a way to explicitly test for this type of CPU. + */ +#ifndef CONFIG_CPU_XSC3 +#define cpu_is_xsc3() 0 +#else +static inline int cpu_is_xsc3(void) +{ + unsigned int id; + id = read_cpuid_id() & 0xffffe000; + /* It covers both Intel ID and Marvell ID */ + if ((id == 0x69056000) || (id == 0x56056000)) + return 1; + + return 0; +} +#endif + +#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3) +#define cpu_is_xscale() 0 +#else +#define cpu_is_xscale() 1 +#endif + +#endif diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index b38436930d..022d365b24 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -23,25 +23,30 @@ /* * PSR bits */ -#define USR26_MODE 0x00 -#define FIQ26_MODE 0x01 -#define IRQ26_MODE 0x02 -#define SVC26_MODE 0x03 -#define USR_MODE 0x10 -#define FIQ_MODE 0x11 -#define IRQ_MODE 0x12 -#define SVC_MODE 0x13 -#define ABT_MODE 0x17 -#define UND_MODE 0x1b -#define SYSTEM_MODE 0x1f -#define MODE_MASK 0x1f -#define T_BIT 0x20 -#define F_BIT 0x40 -#define I_BIT 0x80 -#define CC_V_BIT (1 << 28) -#define CC_C_BIT (1 << 29) -#define CC_Z_BIT (1 << 30) -#define CC_N_BIT (1 << 31) +#define USR26_MODE 0x00000000 +#define FIQ26_MODE 0x00000001 +#define IRQ26_MODE 0x00000002 +#define SVC26_MODE 0x00000003 +#define USR_MODE 0x00000010 +#define FIQ_MODE 0x00000011 +#define IRQ_MODE 0x00000012 +#define SVC_MODE 0x00000013 +#define ABT_MODE 0x00000017 +#define UND_MODE 0x0000001b +#define SYSTEM_MODE 0x0000001f +#define MODE32_BIT 0x00000010 +#define MODE_MASK 0x0000001f +#define PSR_T_BIT 0x00000020 +#define PSR_F_BIT 0x00000040 +#define PSR_I_BIT 0x00000080 +#define PSR_A_BIT 0x00000100 +#define PSR_E_BIT 0x00000200 +#define PSR_J_BIT 0x01000000 +#define PSR_Q_BIT 0x08000000 +#define PSR_V_BIT 0x10000000 +#define PSR_C_BIT 0x20000000 +#define PSR_Z_BIT 0x40000000 +#define PSR_N_BIT 0x80000000 #define PCMASK 0 #ifndef __ASSEMBLY__ @@ -79,7 +84,7 @@ struct pt_regs { #ifdef CONFIG_ARM_THUMB #define thumb_mode(regs) \ - (((regs)->ARM_cpsr & T_BIT)) + (((regs)->ARM_cpsr & PSR_T_BIT)) #else #define thumb_mode(regs) (0) #endif @@ -88,13 +93,13 @@ struct pt_regs { ((regs)->ARM_cpsr & MODE_MASK) #define interrupts_enabled(regs) \ - (!((regs)->ARM_cpsr & I_BIT)) + (!((regs)->ARM_cpsr & PSR_I_BIT)) #define fast_interrupts_enabled(regs) \ - (!((regs)->ARM_cpsr & F_BIT)) + (!((regs)->ARM_cpsr & PSR_F_BIT)) #define condition_codes(regs) \ - ((regs)->ARM_cpsr & (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT)) + ((regs)->ARM_cpsr & (PSR_V_BIT | PSR_C_BIT | PSR_Z_BIT | PSR_N_BIT)) /* Are the current registers suitable for user mode? * (used to maintain security in signal handlers) @@ -102,13 +107,14 @@ struct pt_regs { static inline int valid_user_regs(struct pt_regs *regs) { if ((regs->ARM_cpsr & 0xf) == 0 && - (regs->ARM_cpsr & (F_BIT|I_BIT)) == 0) + (regs->ARM_cpsr & (PSR_F_BIT | PSR_I_BIT)) == 0) return 1; /* * Force CPSR to something logical... */ - regs->ARM_cpsr &= (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT|0x10); + regs->ARM_cpsr &= (PSR_V_BIT | PSR_C_BIT | PSR_Z_BIT | PSR_N_BIT | + 0x10); return 0; } diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h new file mode 100644 index 0000000000..5b676313c0 --- /dev/null +++ b/arch/arm/include/asm/system_info.h @@ -0,0 +1,60 @@ +#ifndef __ASM_ARM_SYSTEM_INFO_H +#define __ASM_ARM_SYSTEM_INFO_H + +#define CPU_ARCH_UNKNOWN 0 +#define CPU_ARCH_ARMv3 1 +#define CPU_ARCH_ARMv4 2 +#define CPU_ARCH_ARMv4T 3 +#define CPU_ARCH_ARMv5 4 +#define CPU_ARCH_ARMv5T 5 +#define CPU_ARCH_ARMv5TE 6 +#define CPU_ARCH_ARMv5TEJ 7 +#define CPU_ARCH_ARMv6 8 +#define CPU_ARCH_ARMv7 9 + +#ifdef CONFIG_CPU_32v4T +#ifdef ARM_ARCH +#define ARM_MULTIARCH +#else +#define ARM_ARCH CPU_ARCH_ARMv4T +#endif +#endif + +#ifdef CONFIG_CPU_32v5 +#ifdef ARM_ARCH +#define ARM_MULTIARCH +#else +#define ARM_ARCH CPU_ARCH_ARMv5 +#endif +#endif + +#ifdef CONFIG_CPU_32v6 +#ifdef ARM_ARCH +#define ARM_MULTIARCH +#else +#define ARM_ARCH CPU_ARCH_ARMv6 +#endif +#endif + +#ifdef CONFIG_CPU_32v7 +#ifdef ARM_ARCH +#define ARM_MULTIARCH +#else +#define ARM_ARCH CPU_ARCH_ARMv7 +#endif +#endif + +#ifndef __ASSEMBLY__ + +#ifdef ARM_MULTIARCH +extern int __pure cpu_architecture(void); +#else +static inline int __pure cpu_architecture(void) +{ + return ARM_ARCH; +} +#endif + +#endif /* !__ASSEMBLY__ */ + +#endif /* __ASM_ARM_SYSTEM_INFO_H */ diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index c5b76ea979..288c0b24a8 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -269,8 +269,9 @@ static int do_bootz_linux(struct image_data *data) ret = do_bootz_linux_fdt(fd, data); if (ret && ret != -ENXIO) - return ret; + goto err_out; + close(fd); return __do_bootm_linux(data, swap); err_out: @@ -431,6 +432,7 @@ static int do_bootm_aimage(struct image_data *data) reset_cpu(0); } + close(fd); return __do_bootm_linux(data, 0); err_out: diff --git a/arch/arm/lib/bootz.c b/arch/arm/lib/bootz.c index f394a6b0eb..f0691277d0 100644 --- a/arch/arm/lib/bootz.c +++ b/arch/arm/lib/bootz.c @@ -30,6 +30,7 @@ static int do_bootz(int argc, char *argv[]) u32 end; int usemap = 0; struct memory_bank *bank = list_first_entry(&memory_banks, struct memory_bank, list); + struct resource *res = NULL; if (argc != 2) return COMMAND_ERROR_USAGE; @@ -83,8 +84,10 @@ static int do_bootz(int argc, char *argv[]) zimage = xmalloc(end); } else { zimage = (void *)bank->start + SZ_8M; - if (bank->start + SZ_8M + end >= MALLOC_BASE) { - printf("won't overwrite malloc space with image\n"); + res = request_sdram_region("zimage", + bank->start + SZ_8M, end); + if (!res) { + printf("can't request region for kernel\n"); goto err_out1; } } @@ -94,7 +97,7 @@ static int do_bootz(int argc, char *argv[]) ret = read(fd, zimage + sizeof(*header), end - sizeof(*header)); if (ret < end - sizeof(*header)) { printf("could not read %s\n", argv[1]); - goto err_out1; + goto err_out2; } } @@ -113,6 +116,9 @@ static int do_bootz(int argc, char *argv[]) return 0; +err_out2: + if (res) + release_sdram_region(res); err_out1: free(zimage); err_out: diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 30225fae97..b3f18850bc 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -3,6 +3,7 @@ if ARCH_AT91 config ARCH_TEXT_BASE hex default 0x73f00000 if ARCH_AT91SAM9G45 + default 0x26f00000 if ARCH_AT91SAM9X5 default 0x23f00000 config BOARDINFO diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 8cb2f57751..1a2d0fdaba 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -18,6 +18,7 @@ #include <mach/gpio.h> #include <mach/io.h> #include <mach/at91rm9200_mc.h> +#include <i2c/i2c-gpio.h> #include <sizes.h> #include "generic.h" @@ -154,6 +155,33 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) void __init at91_add_device_nand(struct atmel_nand_data *data) {} #endif +#if defined(CONFIG_I2C_GPIO) +static struct i2c_gpio_platform_data pdata_i2c = { + .sda_pin = AT91_PIN_PA25, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA26, + .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 = &pdata_i2c; + + i2c_register_board_info(0, devices, nr_devices); + + 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", 0, NULL, 0, pdata); +} +#else +void at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {} +#endif + /* -------------------------------------------------------------------- * SPI * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 9c9534eccf..7450ec11ae 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -20,6 +20,7 @@ #include <mach/gpio.h> #include <mach/io.h> #include <mach/cpu.h> +#include <i2c/i2c-gpio.h> #include "generic.h" @@ -155,6 +156,37 @@ void at91_add_device_nand(struct atmel_nand_data *data) {} #endif /* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_I2C_GPIO) +static struct i2c_gpio_platform_data pdata_i2c = { + .sda_pin = AT91_PIN_PA23, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA24, + .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 = &pdata_i2c; + + i2c_register_board_info(0, devices, nr_devices); + + 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", 0, NULL, 0, pdata); +} +#else +void at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {} +#endif + +/* -------------------------------------------------------------------- * SPI * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 0091e2dbe9..68d75c3fad 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -20,6 +20,7 @@ #include <mach/gpio.h> #include <mach/io.h> #include <mach/cpu.h> +#include <i2c/i2c-gpio.h> #include "generic.h" @@ -107,6 +108,36 @@ void at91_add_device_nand(struct atmel_nand_data *data) {} #endif /* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ +#if defined(CONFIG_I2C_GPIO) +static struct i2c_gpio_platform_data pdata_i2c = { + .sda_pin = AT91_PIN_PA7, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA8, + .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 = &pdata_i2c; + + i2c_register_board_info(0, devices, nr_devices); + + 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", 0, NULL, 0, pdata); +} +#else +void at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {} +#endif + +/* -------------------------------------------------------------------- * SPI * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index e6864802b7..deffc27b1c 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -19,6 +19,7 @@ #include <mach/board.h> #include <mach/gpio.h> #include <mach/io.h> +#include <i2c/i2c-gpio.h> #include "generic.h" @@ -157,6 +158,36 @@ void at91_add_device_nand(struct atmel_nand_data *data) {} #endif /* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ +#if defined(CONFIG_I2C_GPIO) +static struct i2c_gpio_platform_data pdata_i2c = { + .sda_pin = AT91_PIN_PB4, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PB5, + .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 = &pdata_i2c; + + i2c_register_board_info(0, devices, nr_devices); + + 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", 0, NULL, 0, pdata); +} +#else +void at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {} +#endif + +/* -------------------------------------------------------------------- * SPI * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 22b455e1a9..35cd2e722b 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -18,6 +18,7 @@ #include <mach/board.h> #include <mach/gpio.h> #include <mach/io.h> +#include <i2c/i2c-gpio.h> #include "generic.h" @@ -132,6 +133,55 @@ void at91_add_device_nand(struct atmel_nand_data *data) void at91_add_device_nand(struct atmel_nand_data *data) {} #endif +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ +#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) +static struct i2c_gpio_platform_data pdata_i2c0 = { + .sda_pin = AT91_PIN_PA20, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA21, + .scl_is_open_drain = 1, + .udelay = 5, /* ~100 kHz */ +}; + +static struct i2c_gpio_platform_data pdata_i2c1 = { + .sda_pin = AT91_PIN_PB10, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PB11, + .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 = &pdata_i2c; + + i2c_register_board_info(i2c_id, devices, nr_devices); + + switch (i2c_id) { + case 0; + pdata = &pdata_i2c0; + break; + case 1; + pdata = &pdata_i2c1; + break; + default: + return; + } + + 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 + resource_size_t __init at91_configure_dbgu(void) { at91_set_A_periph(AT91_PIN_PB12, 0); /* DRXD */ diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index c256989780..7c7d997260 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c @@ -205,6 +205,10 @@ 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), }; 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 26a380d2ce..14fcb1e6af 100644 --- a/arch/arm/mach-at91/at91sam9x5_devices.c +++ b/arch/arm/mach-at91/at91sam9x5_devices.c @@ -19,6 +19,7 @@ #include <mach/gpio.h> #include <mach/io.h> #include <mach/cpu.h> +#include <i2c/i2c-gpio.h> #include "generic.h" @@ -122,6 +123,68 @@ void at91_add_device_eth(int id, struct at91_ether_platform_data *data) 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 (data->detect_pin) { + at91_set_gpio_input(data->detect_pin, 1); + at91_set_deglitch(data->detect_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + + if (mmc_id == 0) { /* MCI0 */ + start = AT91SAM9X5_BASE_MCI0; + + /* CLK */ + at91_set_A_periph(AT91_PIN_PA17, 0); + + /* CMD */ + at91_set_A_periph(AT91_PIN_PA16, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA15, 1); + if (data->bus_width == 4) { + at91_set_A_periph(AT91_PIN_PA18, 1); + at91_set_A_periph(AT91_PIN_PA19, 1); + at91_set_A_periph(AT91_PIN_PA20, 1); + } + } else { /* MCI1 */ + start = AT91SAM9X5_BASE_MCI1; + + /* CLK */ + at91_set_B_periph(AT91_PIN_PA13, 0); + + /* CMD */ + at91_set_B_periph(AT91_PIN_PA12, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA11, 1); + if (data->bus_width == 4) { + at91_set_B_periph(AT91_PIN_PA2, 1); + at91_set_B_periph(AT91_PIN_PA3, 1); + at91_set_B_periph(AT91_PIN_PA4, 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 + /* -------------------------------------------------------------------- * NAND / SmartMedia * -------------------------------------------------------------------- */ @@ -169,6 +232,125 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) void __init at91_add_device_nand(struct atmel_nand_data *data) {} #endif +#if defined(CONFIG_I2C_GPIO) +static struct i2c_gpio_platform_data pdata_i2c0 = { + .sda_pin = AT91_PIN_PA30, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PA31, + .scl_is_open_drain = 1, + .udelay = 5, /* ~100 kHz */ +}; + +static struct i2c_gpio_platform_data pdata_i2c1 = { + .sda_pin = AT91_PIN_PC0, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PC1, + .scl_is_open_drain = 1, + .udelay = 5, /* ~100 kHz */ +}; + +static struct i2c_gpio_platform_data pdata_i2c2 = { + .sda_pin = AT91_PIN_PB4, + .sda_is_open_drain = 1, + .scl_pin = AT91_PIN_PB5, + .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; + + i2c_register_board_info(i2c_id, devices, nr_devices); + + switch (i2c_id) { + case 0: + pdata = &pdata_i2c0; + break; + case 1: + pdata = &pdata_i2c1; + break; + case 2: + pdata = &pdata_i2c2; + break; + default: + return; + } + + 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_PA14, AT91_PIN_PA7, AT91_PIN_PA1, AT91_PIN_PB3 }; + +static unsigned spi1_standard_cs[4] = { AT91_PIN_PA8, AT91_PIN_PA0, AT91_PIN_PA31, AT91_PIN_PA30 }; + +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 (cs_pin > 0) + at91_set_gpio_output(cs_pin, 1); + } + + /* Configure SPI bus(es) */ + switch (spi_id) { + case 0: + start = AT91SAM9X5_BASE_SPI0; + at91_set_A_periph(AT91_PIN_PA11, 0); /* SPI0_MISO */ + at91_set_A_periph(AT91_PIN_PA12, 0); /* SPI0_MOSI */ + at91_set_A_periph(AT91_PIN_PA13, 0); /* SPI0_SPCK */ + break; + case 1: + start = AT91SAM9X5_BASE_SPI1; + at91_set_B_periph(AT91_PIN_PA21, 0); /* SPI1_MISO */ + at91_set_B_periph(AT91_PIN_PA22, 0); /* SPI1_MOSI */ + at91_set_B_periph(AT91_PIN_PA23, 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 + /* -------------------------------------------------------------------- * UART * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index 670c73d8d8..1ce07628e9 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -21,6 +21,7 @@ #include <mach/hardware.h> #include <sizes.h> #include <net.h> +#include <i2c/i2c.h> #include <spi/spi.h> #include <linux/mtd/mtd.h> @@ -71,6 +72,8 @@ struct at91_ether_platform_data { void at91_add_device_eth(int id, struct at91_ether_platform_data *data); +void at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices); + /* SDRAM */ void at91_add_device_sdram(u32 size); diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h index 3533bf9e3f..fa695a617c 100644 --- a/arch/arm/mach-at91/include/mach/gpio.h +++ b/arch/arm/mach-at91/include/mach/gpio.h @@ -22,6 +22,17 @@ /* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ +#define ARCH_NR_GPIOS 256 + +static inline int gpio_is_valid(int gpio) +{ + if (gpio < 1) + return 0; + if (gpio < ARCH_NR_GPIOS) + return 1; + return 0; +} + #define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0) #define AT91_PIN_PA1 (PIN_BASE + 0x00 + 1) #define AT91_PIN_PA2 (PIN_BASE + 0x00 + 2) diff --git a/arch/arm/mach-bcm2835/Kconfig b/arch/arm/mach-bcm2835/Kconfig new file mode 100644 index 0000000000..9d97aea2b8 --- /dev/null +++ b/arch/arm/mach-bcm2835/Kconfig @@ -0,0 +1,18 @@ +if ARCH_BCM2835 + +config ARCH_TEXT_BASE + hex + default 0x04000000 if MACH_RPI + +config BOARDINFO + default "RaspberryPi (BCM2835/ARM1176JZF-S)" if MACH_RPI + +choice + prompt "Broadcom Board type" + +config MACH_RPI + bool "RaspberryPi (BCM2835/ARM1176JZF-S)" + +endchoice + +endif diff --git a/arch/arm/mach-bcm2835/Makefile b/arch/arm/mach-bcm2835/Makefile new file mode 100644 index 0000000000..820eb10ac2 --- /dev/null +++ b/arch/arm/mach-bcm2835/Makefile @@ -0,0 +1 @@ +obj-y += core.o diff --git a/arch/arm/mach-bcm2835/core.c b/arch/arm/mach-bcm2835/core.c new file mode 100644 index 0000000000..b0fec8b008 --- /dev/null +++ b/arch/arm/mach-bcm2835/core.c @@ -0,0 +1,101 @@ +/* + * Author: Carlo Caione <carlo@carlocaione.org> + * + * Based on mach-nomadik + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnio@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 <init.h> + +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/err.h> + +#include <io.h> +#include <asm/armlinux.h> +#include <sizes.h> + +#include <mach/platform.h> +#include <mach/wd.h> +#include <mach/core.h> +#include <linux/amba/bus.h> + +enum brcm_clks { + dummy, clk_ref_3, clk_ref_1, clks_max +}; + +static struct clk *clks[clks_max]; + +static int bcm2835_clk_init(void) +{ + int ret; + + clks[dummy] = clk_fixed("dummy", 0); + clks[clk_ref_3] = clk_fixed("ref3", 3 * 1000 * 1000); + clks[clk_ref_1] = clk_fixed("ref1", 1 * 1000 * 1000); + + ret = clk_register_clkdev(clks[dummy], "apb_pclk", NULL); + if (ret) + goto clk_err; + + ret = clk_register_clkdev(clks[clk_ref_3], NULL, "uart0-pl0110"); + if (ret) + goto clk_err; + + ret = clk_register_clkdev(clks[clk_ref_1], NULL, "bcm2835-cs"); + if (ret) + goto clk_err; + + return 0; + +clk_err: + return ret; + +} +postcore_initcall(bcm2835_clk_init); + +static int bcm2835_dev_init(void) +{ + add_generic_device("bcm2835-gpio", 0, NULL, BCM2835_GPIO_BASE, 0xB0, IORESOURCE_MEM, NULL); + add_generic_device("bcm2835-cs", DEVICE_ID_SINGLE, NULL, BCM2835_ST_BASE, 0x1C, IORESOURCE_MEM, NULL); + return 0; +} +coredevice_initcall(bcm2835_dev_init); + +void bcm2835_register_uart(void) +{ + amba_apb_device_add(NULL, "uart0-pl011", 0, BCM2835_UART0_BASE, 4096, NULL, 0); +} + +void bcm2835_add_device_sdram(u32 size) +{ + if (!size) + size = get_ram_size((ulong *) BCM2835_SDRAM_BASE, SZ_128M); + + arm_add_mem_device("ram0", BCM2835_SDRAM_BASE, size); +} +#define RESET_TIMEOUT 10 + +void __noreturn reset_cpu (unsigned long addr) +{ + uint32_t rstc; + + rstc = readl(PM_RSTC); + rstc &= ~PM_RSTC_WRCFG_SET; + rstc |= PM_RSTC_WRCFG_FULL_RESET; + writel(PM_PASSWORD | RESET_TIMEOUT, PM_WDOG); + writel(PM_PASSWORD | rstc, PM_RSTC); +} +EXPORT_SYMBOL(reset_cpu); diff --git a/arch/arm/mach-bcm2835/include/mach/clkdev.h b/arch/arm/mach-bcm2835/include/mach/clkdev.h new file mode 100644 index 0000000000..04b37a8980 --- /dev/null +++ b/arch/arm/mach-bcm2835/include/mach/clkdev.h @@ -0,0 +1,7 @@ +#ifndef __ASM_MACH_CLKDEV_H +#define __ASM_MACH_CLKDEV_H + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif diff --git a/arch/arm/boards/at91sam9260ek/lowlevel_init.S b/arch/arm/mach-bcm2835/include/mach/core.h index 043892122c..9379af209b 100644 --- a/arch/arm/boards/at91sam9260ek/lowlevel_init.S +++ b/arch/arm/mach-bcm2835/include/mach/core.h @@ -1,9 +1,5 @@ /* - * Board specific setup info - * - * - * See file CREDITS for list of people who contributed to this - * project. + * Copyright (C) 2009 Carlo Caione <carlo@carlocaione.org> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -17,9 +13,10 @@ * */ -#include <asm/barebox-arm-head.h> +#ifndef __BCM2835_CORE_H__ +#define __BCM2835_CORE_H__ + +void bcm2835_register_uart(void); +void bcm2835_add_device_sdram(u32 size); -.globl reset -reset: - common_reset r0 - b board_init_lowlevel_return +#endif diff --git a/arch/arm/mach-bcm2835/include/mach/gpio.h b/arch/arm/mach-bcm2835/include/mach/gpio.h new file mode 100644 index 0000000000..306ab4c9f2 --- /dev/null +++ b/arch/arm/mach-bcm2835/include/mach/gpio.h @@ -0,0 +1 @@ +#include <asm-generic/gpio.h> diff --git a/arch/arm/mach-bcm2835/include/mach/platform.h b/arch/arm/mach-bcm2835/include/mach/platform.h new file mode 100644 index 0000000000..e55085a75b --- /dev/null +++ b/arch/arm/mach-bcm2835/include/mach/platform.h @@ -0,0 +1,50 @@ +/* + * Extract from arch/arm/mach-bcm2708/include/mach/platform.h + * + * Copyright (C) 2010 Broadcom + * + * 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 _BCM2835_PLATFORM_H +#define _BCM2835_PLATFORM_H + +/* + * SDRAM + */ +#define BCM2835_SDRAM_BASE 0x00000000 + +/* + * Definitions and addresses for the ARM CONTROL logic + * This file is manually generated. + */ + +#define BCM2835_PERI_BASE 0x20000000 +#define BCM2835_ST_BASE (BCM2835_PERI_BASE + 0x3000) /* System Timer */ +#define BCM2835_DMA_BASE (BCM2835_PERI_BASE + 0x7000) /* DMA controller */ +#define BCM2835_ARM_BASE (BCM2835_PERI_BASE + 0xB000) /* BCM2708 ARM control block */ +#define BCM2835_PM_BASE (BCM2835_PERI_BASE + 0x100000) /* Power Management, Reset controller and Watchdog registers */ +#define BCM2835_GPIO_BASE (BCM2835_PERI_BASE + 0x200000) /* GPIO */ +#define BCM2835_UART0_BASE (BCM2835_PERI_BASE + 0x201000) /* Uart 0 */ +#define BCM2835_MMCI0_BASE (BCM2835_PERI_BASE + 0x202000) /* MMC interface */ +#define BCM2835_SPI0_BASE (BCM2835_PERI_BASE + 0x204000) /* SPI0 */ +#define BCM2835_BSC0_BASE (BCM2835_PERI_BASE + 0x205000) /* BSC0 I2C/TWI */ +#define BCM2835_UART1_BASE (BCM2835_PERI_BASE + 0x215000) /* Uart 1 */ +#define BCM2835_EMMC_BASE (BCM2835_PERI_BASE + 0x300000) /* eMMC interface */ +#define BCM2835_SMI_BASE (BCM2835_PERI_BASE + 0x600000) /* SMI */ +#define BCM2835_BSC1_BASE (BCM2835_PERI_BASE + 0x804000) /* BSC1 I2C/TWI */ +#define BCM2835_USB_BASE (BCM2835_PERI_BASE + 0x980000) /* DTC_OTG USB controller */ +#define BCM2835_MCORE_BASE (BCM2835_PERI_BASE + 0x0000) /* Fake frame buffer device (actually the multicore sync block*/ + +#endif + +/* END */ diff --git a/arch/arm/mach-bcm2835/include/mach/wd.h b/arch/arm/mach-bcm2835/include/mach/wd.h new file mode 100644 index 0000000000..ad8b762d96 --- /dev/null +++ b/arch/arm/mach-bcm2835/include/mach/wd.h @@ -0,0 +1,47 @@ +/* + * Extract from arch/arm/mach-bcm2708/include/mach/platform.h + * + * Copyright (C) 2010 Broadcom + * + * 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 _WD_H +#define _WD_H + +/* + * Watchdog + */ +#define PM_RSTC (BCM2835_PM_BASE+0x1c) +#define PM_RSTS (BCM2835_PM_BASE+0x20) +#define PM_WDOG (BCM2835_PM_BASE+0x24) + +#define PM_WDOG_RESET 0000000000 +#define PM_PASSWORD 0x5a000000 +#define PM_WDOG_TIME_SET 0x000fffff +#define PM_RSTC_WRCFG_CLR 0xffffffcf +#define PM_RSTC_WRCFG_SET 0x00000030 +#define PM_RSTC_WRCFG_FULL_RESET 0x00000020 +#define PM_RSTC_RESET 0x00000102 + +#define PM_RSTS_HADPOR_SET 0x00001000 +#define PM_RSTS_HADSRH_SET 0x00000400 +#define PM_RSTS_HADSRF_SET 0x00000200 +#define PM_RSTS_HADSRQ_SET 0x00000100 +#define PM_RSTS_HADWRH_SET 0x00000040 +#define PM_RSTS_HADWRF_SET 0x00000020 +#define PM_RSTS_HADWRQ_SET 0x00000010 +#define PM_RSTS_HADDRH_SET 0x00000004 +#define PM_RSTS_HADDRF_SET 0x00000002 +#define PM_RSTS_HADDRQ_SET 0x00000001 + +#endif diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig new file mode 100644 index 0000000000..469ca72f12 --- /dev/null +++ b/arch/arm/mach-clps711x/Kconfig @@ -0,0 +1,26 @@ +if ARCH_CLPS711X + +choice + prompt "Cirrus Logic EP711x/EP721x/EP731x Board Type" + +config MACH_CLEP7212 + bool "Cirrus Logic CLEP7212" + select MACH_HAS_LOWLEVEL_INIT + select MACH_DO_LOWLEVEL_INIT + help + Boards based on the Cirrus Logic 7212/7312 CPU. + +endchoice + +config BOARDINFO + default "Cirrus Logic CLEP7212" if MACH_CLEP7212 + +config ARCH_TEXT_BASE + hex + default 0xc0780000 if MACH_CLEP7212 + +config BAREBOX_MAX_IMAGE_SIZE + hex + default 0x00080000 if MACH_CLEP7212 + +endif diff --git a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile new file mode 100644 index 0000000000..41012bc016 --- /dev/null +++ b/arch/arm/mach-clps711x/Makefile @@ -0,0 +1 @@ +obj-y += clock.o devices.o reset.o diff --git a/arch/arm/mach-clps711x/clock.c b/arch/arm/mach-clps711x/clock.c new file mode 100644 index 0000000000..5cafba98e9 --- /dev/null +++ b/arch/arm/mach-clps711x/clock.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> + * + * 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 <clock.h> +#include <asm/io.h> +#include <linux/clkdev.h> + +#include <mach/clps711x.h> + +struct clk { + unsigned long rate; +}; + +static struct clk uart_clk, bus_clk; + +uint64_t clocksource_read(void) +{ + return ~readw(TC2D); +} + +static struct clocksource cs = { + .read = clocksource_read, + .mask = CLOCKSOURCE_MASK(16), +}; + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +int clk_enable(struct clk *clk) +{ + /* Do nothing */ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + /* Do nothing */ +} +EXPORT_SYMBOL(clk_disable); + +static int clocks_init(void) +{ + int osc, ext, pll, cpu, timer; + u32 tmp; + + osc = 3686400; + ext = 13000000; + + tmp = readl(PLLR) >> 24; + if (tmp) + pll = (osc * tmp) / 2; + else + pll = 73728000; /* Default value for old CPUs */ + + tmp = readl(SYSFLG2); + if (tmp & SYSFLG2_CKMODE) { + cpu = ext; + bus_clk.rate = cpu; + } else { + cpu = pll; + if (cpu >= 36864000) + bus_clk.rate = cpu / 2; + else + bus_clk.rate = 36864000 / 2; + } + + uart_clk.rate = bus_clk.rate / 10; + + if (tmp & SYSFLG2_CKMODE) { + tmp = readw(SYSCON2); + if (tmp & SYSCON2_OSTB) + timer = ext / 26; + else + timer = 541440; + } else + timer = cpu / 144; + + tmp = readl(SYSCON1); + tmp &= ~SYSCON1_TC2M; /* Free running mode */ + tmp |= SYSCON1_TC2S; /* High frequency source */ + writel(tmp, SYSCON1); + + clocks_calc_mult_shift(&cs.mult, &cs.shift, timer, NSEC_PER_SEC, 10); + + return init_clock(&cs); +} +core_initcall(clocks_init); + +static struct clk_lookup clocks_lookups[] = { + CLKDEV_CON_ID("bus", &bus_clk), + CLKDEV_DEV_ID("clps711x_serial0", &uart_clk), + CLKDEV_DEV_ID("clps711x_serial1", &uart_clk), +}; + +static int clkdev_init(void) +{ + clkdev_add_table(clocks_lookups, ARRAY_SIZE(clocks_lookups)); + + return 0; +} +postcore_initcall(clkdev_init); diff --git a/arch/arm/mach-clps711x/devices.c b/arch/arm/mach-clps711x/devices.c new file mode 100644 index 0000000000..08f27d26be --- /dev/null +++ b/arch/arm/mach-clps711x/devices.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> + * + * 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 <asm/io.h> + +#include <mach/clps711x.h> + +inline void _clps711x_setup_memcfg(int bank, u32 addr, u32 val) +{ + u32 tmp = readl(addr); + + tmp &= ~(0xff << (bank * 8)); + tmp |= val << (bank * 8); + + writel(tmp, addr); +} + +void clps711x_setup_memcfg(int bank, u32 val) +{ + switch (bank) { + case 0 ... 3: + _clps711x_setup_memcfg(bank, MEMCFG1, val); + break; + case 4 ... 7: + _clps711x_setup_memcfg(bank - 4, MEMCFG2, val); + break; + } +} + +static struct resource uart0_resources[] = { + { + .start = UBRLCR1, + .end = UBRLCR1, + .flags = IORESOURCE_MEM, + }, + { + .start = SYSCON1, + .end = SYSCON1, + .flags = IORESOURCE_MEM, + }, + { + .start = SYSFLG1, + .end = SYSFLG1, + .flags = IORESOURCE_MEM, + }, + { + .start = UARTDR1, + .end = UARTDR1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource uart1_resources[] = { + { + .start = UBRLCR2, + .end = UBRLCR2, + .flags = IORESOURCE_MEM, + }, + { + .start = SYSCON2, + .end = SYSCON2, + .flags = IORESOURCE_MEM, + }, + { + .start = SYSFLG2, + .end = SYSFLG2, + .flags = IORESOURCE_MEM, + }, + { + .start = UARTDR2, + .end = UARTDR2, + .flags = IORESOURCE_MEM, + }, +}; + +void clps711x_add_uart(unsigned int id) +{ + switch (id) { + case 0: + add_generic_device_res("clps711x_serial", 0, uart0_resources, + ARRAY_SIZE(uart0_resources), NULL); + break; + case 1: + add_generic_device_res("clps711x_serial", 1, uart1_resources, + ARRAY_SIZE(uart1_resources), NULL); + break; + } +} diff --git a/arch/arm/mach-clps711x/include/mach/clkdev.h b/arch/arm/mach-clps711x/include/mach/clkdev.h new file mode 100644 index 0000000000..9278209017 --- /dev/null +++ b/arch/arm/mach-clps711x/include/mach/clkdev.h @@ -0,0 +1,7 @@ +#ifndef __MACH_CLKDEV_H +#define __MACH_CLKDEV_H + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif diff --git a/arch/arm/mach-clps711x/include/mach/clps711x.h b/arch/arm/mach-clps711x/include/mach/clps711x.h new file mode 100644 index 0000000000..048992a361 --- /dev/null +++ b/arch/arm/mach-clps711x/include/mach/clps711x.h @@ -0,0 +1,284 @@ +/* + * Hardware definitions for Cirrus Logic CLPS711X + * + * Copyright (C) 2000 Deep Blue Solutions Ltd. + * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> + * + * 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 __MACH_CLPS711X_H +#define __MACH_CLPS711X_H + +#define CS0_BASE (0x00000000) +#define CS1_BASE (0x10000000) +#define CS2_BASE (0x20000000) +#define CS3_BASE (0x30000000) +#define CS4_BASE (0x40000000) +#define CS5_BASE (0x50000000) +#define CS6_BASE (0x60000000) +#define CS7_BASE (0x70000000) +#define REGS_BASE (0x80000000) +#define SDRAM0_BASE (0xc0000000) +#define SDRAM1_BASE (0xd0000000) + +#define PADR (REGS_BASE + 0x0000) +#define PBDR (REGS_BASE + 0x0001) +#define PCDR (REGS_BASE + 0x0002) +#define PDDR (REGS_BASE + 0x0003) +#define PADDR (REGS_BASE + 0x0040) +#define PBDDR (REGS_BASE + 0x0041) +#define PCDDR (REGS_BASE + 0x0042) +#define PDDDR (REGS_BASE + 0x0043) +#define PEDR (REGS_BASE + 0x0083) +#define PEDDR (REGS_BASE + 0x00c3) +#define SYSCON1 (REGS_BASE + 0x0100) +#define SYSFLG1 (REGS_BASE + 0x0140) +#define MEMCFG1 (REGS_BASE + 0x0180) +#define MEMCFG2 (REGS_BASE + 0x01c0) +#define DRFPR (REGS_BASE + 0x0200) +#define INTSR1 (REGS_BASE + 0x0240) +#define INTMR1 (REGS_BASE + 0x0280) +#define LCDCON (REGS_BASE + 0x02c0) +#define TC1D (REGS_BASE + 0x0300) +#define TC2D (REGS_BASE + 0x0340) +#define RTCDR (REGS_BASE + 0x0380) +#define RTCMR (REGS_BASE + 0x03c0) +#define PMPCON (REGS_BASE + 0x0400) +#define CODR (REGS_BASE + 0x0440) +#define UARTDR1 (REGS_BASE + 0x0480) +#define UBRLCR1 (REGS_BASE + 0x04c0) +#define SYNCIO (REGS_BASE + 0x0500) +#define PALLSW (REGS_BASE + 0x0540) +#define PALMSW (REGS_BASE + 0x0580) +#define STFCLR (REGS_BASE + 0x05c0) +#define BLEOI (REGS_BASE + 0x0600) +#define MCEOI (REGS_BASE + 0x0640) +#define TEOI (REGS_BASE + 0x0680) +#define TC1EOI (REGS_BASE + 0x06c0) +#define TC2EOI (REGS_BASE + 0x0700) +#define RTCEOI (REGS_BASE + 0x0740) +#define UMSEOI (REGS_BASE + 0x0780) +#define COEOI (REGS_BASE + 0x07c0) +#define HALT (REGS_BASE + 0x0800) +#define STDBY (REGS_BASE + 0x0840) + +#define FBADDR (REGS_BASE + 0x1000) +#define SYSCON2 (REGS_BASE + 0x1100) +#define SYSFLG2 (REGS_BASE + 0x1140) +#define INTSR2 (REGS_BASE + 0x1240) +#define INTMR2 (REGS_BASE + 0x1280) +#define UARTDR2 (REGS_BASE + 0x1480) +#define UBRLCR2 (REGS_BASE + 0x14c0) +#define SS2DR (REGS_BASE + 0x1500) +#define SRXEOF (REGS_BASE + 0x1600) +#define SS2POP (REGS_BASE + 0x16c0) +#define KBDEOI (REGS_BASE + 0x1700) + +#define DAIR (REGS_BASE + 0x2000) +#define DAIDR0 (REGS_BASE + 0x2040) +#define DAIDR1 (REGS_BASE + 0x2080) +#define DAIDR2 (REGS_BASE + 0x20c0) +#define DAISR (REGS_BASE + 0x2100) +#define SYSCON3 (REGS_BASE + 0x2200) +#define INTSR3 (REGS_BASE + 0x2240) +#define INTMR3 (REGS_BASE + 0x2280) +#define LEDFLSH (REGS_BASE + 0x22c0) +#define SDCONF (REGS_BASE + 0x2300) +#define SDRFPR (REGS_BASE + 0x2340) +#define UNIQID (REGS_BASE + 0x2440) +#define DAI64FS (REGS_BASE + 0x2600) +#define PLLW (REGS_BASE + 0x2610) +#define PLLR (REGS_BASE + 0xa5a8) +#define RANDID0 (REGS_BASE + 0x2700) +#define RANDID1 (REGS_BASE + 0x2704) +#define RANDID2 (REGS_BASE + 0x2708) +#define RANDID3 (REGS_BASE + 0x270c) + +/* common bits: SYSCON1 / SYSCON2 */ +#define SYSCON_UARTEN (1 << 8) + +#define SYSCON1_KBDSCAN(x) ((x) & 15) +#define SYSCON1_KBDSCANMASK (15) +#define SYSCON1_TC1M (1 << 4) +#define SYSCON1_TC1S (1 << 5) +#define SYSCON1_TC2M (1 << 6) +#define SYSCON1_TC2S (1 << 7) +#define SYSCON1_UART1EN SYSCON_UARTEN +#define SYSCON1_BZTOG (1 << 9) +#define SYSCON1_BZMOD (1 << 10) +#define SYSCON1_DBGEN (1 << 11) +#define SYSCON1_LCDEN (1 << 12) +#define SYSCON1_CDENTX (1 << 13) +#define SYSCON1_CDENRX (1 << 14) +#define SYSCON1_SIREN (1 << 15) +#define SYSCON1_ADCKSEL(x) (((x) & 3) << 16) +#define SYSCON1_ADCKSEL_MASK (3 << 16) +#define SYSCON1_EXCKEN (1 << 18) +#define SYSCON1_WAKEDIS (1 << 19) +#define SYSCON1_IRTXM (1 << 20) + +/* common bits: SYSFLG1 / SYSFLG2 */ +#define SYSFLG_UBUSY (1 << 11) +#define SYSFLG_URXFE (1 << 22) +#define SYSFLG_UTXFF (1 << 23) + +#define SYSFLG1_MCDR (1 << 0) +#define SYSFLG1_DCDET (1 << 1) +#define SYSFLG1_WUDR (1 << 2) +#define SYSFLG1_WUON (1 << 3) +#define SYSFLG1_CTS (1 << 8) +#define SYSFLG1_DSR (1 << 9) +#define SYSFLG1_DCD (1 << 10) +#define SYSFLG1_UBUSY SYSFLG_UBUSY +#define SYSFLG1_NBFLG (1 << 12) +#define SYSFLG1_RSTFLG (1 << 13) +#define SYSFLG1_PFFLG (1 << 14) +#define SYSFLG1_CLDFLG (1 << 15) +#define SYSFLG1_URXFE SYSFLG_URXFE +#define SYSFLG1_UTXFF SYSFLG_UTXFF +#define SYSFLG1_CRXFE (1 << 24) +#define SYSFLG1_CTXFF (1 << 25) +#define SYSFLG1_SSIBUSY (1 << 26) +#define SYSFLG1_ID (1 << 29) +#define SYSFLG1_VERID(x) (((x) >> 30) & 3) +#define SYSFLG1_VERID_MASK (3 << 30) + +#define SYSFLG2_SSRXOF (1 << 0) +#define SYSFLG2_RESVAL (1 << 1) +#define SYSFLG2_RESFRM (1 << 2) +#define SYSFLG2_SS2RXFE (1 << 3) +#define SYSFLG2_SS2TXFF (1 << 4) +#define SYSFLG2_SS2TXUF (1 << 5) +#define SYSFLG2_CKMODE (1 << 6) +#define SYSFLG2_UBUSY SYSFLG_UBUSY +#define SYSFLG2_URXFE SYSFLG_URXFE +#define SYSFLG2_UTXFF SYSFLG_UTXFF + +#define LCDCON_GSEN (1 << 30) +#define LCDCON_GSMD (1 << 31) + +#define SYSCON2_SERSEL (1 << 0) +#define SYSCON2_KBD6 (1 << 1) +#define SYSCON2_DRAMZ (1 << 2) +#define SYSCON2_KBWEN (1 << 3) +#define SYSCON2_SS2TXEN (1 << 4) +#define SYSCON2_PCCARD1 (1 << 5) +#define SYSCON2_PCCARD2 (1 << 6) +#define SYSCON2_SS2RXEN (1 << 7) +#define SYSCON2_UART2EN SYSCON_UARTEN +#define SYSCON2_SS2MAEN (1 << 9) +#define SYSCON2_OSTB (1 << 12) +#define SYSCON2_CLKENSL (1 << 13) +#define SYSCON2_BUZFREQ (1 << 14) + +/* common bits: UARTDR1 / UARTDR2 */ +#define UARTDR_FRMERR (1 << 8) +#define UARTDR_PARERR (1 << 9) +#define UARTDR_OVERR (1 << 10) + +/* common bits: UBRLCR1 / UBRLCR2 */ +#define UBRLCR_BAUD_MASK ((1 << 12) - 1) +#define UBRLCR_BREAK (1 << 12) +#define UBRLCR_PRTEN (1 << 13) +#define UBRLCR_EVENPRT (1 << 14) +#define UBRLCR_XSTOP (1 << 15) +#define UBRLCR_FIFOEN (1 << 16) +#define UBRLCR_WRDLEN5 (0 << 17) +#define UBRLCR_WRDLEN6 (1 << 17) +#define UBRLCR_WRDLEN7 (2 << 17) +#define UBRLCR_WRDLEN8 (3 << 17) +#define UBRLCR_WRDLEN_MASK (3 << 17) + +#define SYNCIO_FRMLEN(x) (((x) & 0x1f) << 8) +#define SYNCIO_SMCKEN (1 << 13) +#define SYNCIO_TXFRMEN (1 << 14) + +#define DAIR_RESERVED (0x0404) +#define DAIR_DAIEN (1 << 16) +#define DAIR_ECS (1 << 17) +#define DAIR_LCTM (1 << 19) +#define DAIR_LCRM (1 << 20) +#define DAIR_RCTM (1 << 21) +#define DAIR_RCRM (1 << 22) +#define DAIR_LBM (1 << 23) + +#define DAIDR2_FIFOEN (1 << 15) +#define DAIDR2_FIFOLEFT (0x0d << 16) +#define DAIDR2_FIFORIGHT (0x11 << 16) + +#define DAISR_RCTS (1 << 0) +#define DAISR_RCRS (1 << 1) +#define DAISR_LCTS (1 << 2) +#define DAISR_LCRS (1 << 3) +#define DAISR_RCTU (1 << 4) +#define DAISR_RCRO (1 << 5) +#define DAISR_LCTU (1 << 6) +#define DAISR_LCRO (1 << 7) +#define DAISR_RCNF (1 << 8) +#define DAISR_RCNE (1 << 9) +#define DAISR_LCNF (1 << 10) +#define DAISR_LCNE (1 << 11) +#define DAISR_FIFO (1 << 12) + +#define DAI64FS_I2SF64 (1 << 0) +#define DAI64FS_AUDIOCLKEN (1 << 1) +#define DAI64FS_AUDIOCLKSRC (1 << 2) +#define DAI64FS_MCLK256EN (1 << 3) +#define DAI64FS_LOOPBACK (1 << 5) +#define DAI64FS_AUDIV_MASK (0x7f) +#define DAI64FS_AUDIV(x) (((x) & DAI64FS_AUDIV_MASK) << 8) + +#define SYSCON3_ADCCON (1 << 0) +#define SYSCON3_CLKCTL0 (1 << 1) +#define SYSCON3_CLKCTL1 (1 << 2) +#define SYSCON3_DAISEL (1 << 3) +#define SYSCON3_ADCCKNSEN (1 << 4) +#define SYSCON3_VERSN(x) (((x) >> 5) & 7) +#define SYSCON3_VERSN_MASK (7 << 5) +#define SYSCON3_FASTWAKE (1 << 8) +#define SYSCON3_DAIEN (1 << 9) +#define SYSCON3_128FS SYSCON3_DAIEN +#define SYSCON3_ENPD67 (1 << 10) + +#define SDCONF_ACTIVE (1 << 10) +#define SDCONF_CLKCTL (1 << 9) +#define SDCONF_WIDTH_4 (0 << 7) +#define SDCONF_WIDTH_8 (1 << 7) +#define SDCONF_WIDTH_16 (2 << 7) +#define SDCONF_WIDTH_32 (3 << 7) +#define SDCONF_SIZE_16 (0 << 5) +#define SDCONF_SIZE_64 (1 << 5) +#define SDCONF_SIZE_128 (2 << 5) +#define SDCONF_SIZE_256 (3 << 5) +#define SDCONF_CASLAT_2 (2) +#define SDCONF_CASLAT_3 (3) + +#define MEMCFG_BUS_WIDTH_32 (1) +#define MEMCFG_BUS_WIDTH_16 (0) +#define MEMCFG_BUS_WIDTH_8 (3) + +#define MEMCFG_SQAEN (1 << 6) +#define MEMCFG_CLKENB (1 << 7) + +#define MEMCFG_WAITSTATE_8_3 (0 << 2) +#define MEMCFG_WAITSTATE_7_3 (1 << 2) +#define MEMCFG_WAITSTATE_6_3 (2 << 2) +#define MEMCFG_WAITSTATE_5_3 (3 << 2) +#define MEMCFG_WAITSTATE_4_2 (4 << 2) +#define MEMCFG_WAITSTATE_3_2 (5 << 2) +#define MEMCFG_WAITSTATE_2_2 (6 << 2) +#define MEMCFG_WAITSTATE_1_2 (7 << 2) +#define MEMCFG_WAITSTATE_8_1 (8 << 2) +#define MEMCFG_WAITSTATE_7_1 (9 << 2) +#define MEMCFG_WAITSTATE_6_1 (10 << 2) +#define MEMCFG_WAITSTATE_5_1 (11 << 2) +#define MEMCFG_WAITSTATE_4_0 (12 << 2) +#define MEMCFG_WAITSTATE_3_0 (13 << 2) +#define MEMCFG_WAITSTATE_2_0 (14 << 2) +#define MEMCFG_WAITSTATE_1_0 (15 << 2) + +#endif diff --git a/arch/arm/mach-clps711x/include/mach/devices.h b/arch/arm/mach-clps711x/include/mach/devices.h new file mode 100644 index 0000000000..18a251a1d9 --- /dev/null +++ b/arch/arm/mach-clps711x/include/mach/devices.h @@ -0,0 +1,7 @@ +#ifndef __MACH_DEVICES_H +#define __MACH_DEVICES_H + +void clps711x_setup_memcfg(int bank, u32 val); +void clps711x_add_uart(unsigned int id); + +#endif diff --git a/arch/arm/mach-clps711x/reset.c b/arch/arm/mach-clps711x/reset.c new file mode 100644 index 0000000000..4a42ef412d --- /dev/null +++ b/arch/arm/mach-clps711x/reset.c @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> + * + * 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> + +extern void start(void); + +void __noreturn reset_cpu(unsigned long addr) +{ + arch_shutdown(); + + asm("mov pc, #0"); + + hang(); +} diff --git a/arch/arm/mach-ep93xx/include/mach/gpio.h b/arch/arm/mach-ep93xx/include/mach/gpio.h index 5f1b4bc001..306ab4c9f2 100644 --- a/arch/arm/mach-ep93xx/include/mach/gpio.h +++ b/arch/arm/mach-ep93xx/include/mach/gpio.h @@ -1,26 +1 @@ -/* - * Copyright (C) 2010 Matthias Kaehlcke <matthias@kaehlcke.net> - * - * 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 __ASM_ARCH_GPIO_H -#define __ASM_ARCH_GPIO_H - -void gpio_set_value(unsigned gpio, int value); -int gpio_get_value(unsigned gpio); -int gpio_direction_output(unsigned gpio, int value); -int gpio_direction_input(unsigned gpio); - -#endif /* __ASM_ARCH_GPIO_H */ - +#include <asm-generic/gpio.h> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index d27d4f34d5..cca839465d 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -27,7 +27,7 @@ config ARCH_TEXT_BASE default 0x4fc00000 if MACH_MX6Q_ARM2 default 0x97f00000 if MACH_CCMX51 default 0x4fc00000 if MACH_SABRELITE - default 0x7fe00000 if MACH_TX53 + default 0x8fe00000 if MACH_TX53 config BOARDINFO default "Eukrea CPUIMX25" if MACH_EUKREA_CPUIMX25 @@ -464,11 +464,22 @@ config MACH_TQMA53_1GB_RAM config MACH_TX53 bool "Ka-Ro TX53" select HAVE_DEFAULT_ENVIRONMENT_NEW + select MACH_HAS_LOWLEVEL_INIT help Say Y here if you are using the Ka-Ro tx53 board endchoice +if MACH_TX53 +choice + prompt "TX53 board revision" +config TX53_REV_1011 + bool "1011" +config TX53_REV_XX30 + bool "8030 / 1030" +endchoice +endif + endif if ARCH_IMX6 diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index e43f92e430..259733ece0 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -1,5 +1,4 @@ obj-y += clocksource.o gpio.o -obj-$(CONFIG_RESET_SOURCE) += reset_source.o obj-$(CONFIG_ARCH_IMX1) += imx1.o iomux-v1.o clk-imx1.o obj-$(CONFIG_ARCH_IMX25) += imx25.o iomux-v3.o clk-imx25.o obj-$(CONFIG_ARCH_IMX21) += imx21.o iomux-v1.o clk-imx21.o @@ -8,11 +7,13 @@ obj-$(CONFIG_ARCH_IMX31) += imx31.o iomux-v2.o clk-imx31.o obj-$(CONFIG_ARCH_IMX35) += imx35.o iomux-v3.o clk-imx35.o obj-$(CONFIG_ARCH_IMX51) += imx51.o iomux-v3.o imx5.o clk-imx5.o obj-$(CONFIG_ARCH_IMX53) += imx53.o iomux-v3.o imx5.o clk-imx5.o +pbl-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o obj-$(CONFIG_ARCH_IMX6) += imx6.o iomux-v3.o usb-imx6.o clk-imx6.o obj-$(CONFIG_IMX_IIM) += iim.o obj-$(CONFIG_NAND_IMX) += nand.o obj-$(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND) += external-nand-boot.o pbl-$(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND) += external-nand-boot.o obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-pfd.o -obj-y += devices.o +obj-y += devices.o imx.o obj-y += boot.o +obj-$(CONFIG_BAREBOX_UPDATE) += imx-bbu-internal.o diff --git a/arch/arm/mach-imx/boot.c b/arch/arm/mach-imx/boot.c index 11c688e64c..cdddbe5824 100644 --- a/arch/arm/mach-imx/boot.c +++ b/arch/arm/mach-imx/boot.c @@ -17,9 +17,65 @@ #include <magicvar.h> #include <io.h> -#include <mach/imx-regs.h> +#include <mach/generic.h> + +static const char *bootsource_str[] = { + [bootsource_unknown] = "unknown", + [bootsource_nand] = "nand", + [bootsource_nor] = "nor", + [bootsource_mmc] = "mmc", + [bootsource_i2c] = "i2c", + [bootsource_spi] = "spi", + [bootsource_serial] = "serial", + [bootsource_onenand] = "onenand", + [bootsource_hd] = "harddisk", +}; + +static enum imx_bootsource bootsource; + +void imx_set_bootsource(enum imx_bootsource src) +{ + if (src >= ARRAY_SIZE(bootsource_str)) + src = bootsource_unknown; + + bootsource = src; + + setenv("barebox_loc", bootsource_str[src]); + export("barebox_loc"); +} + +enum imx_bootsource imx_bootsource(void) +{ + return bootsource; +} + +BAREBOX_MAGICVAR(barebox_loc, "The source barebox has been booted from"); + +/* [CTRL][TYPE] */ +static const enum imx_bootsource locations[4][4] = { + { /* CTRL = WEIM */ + bootsource_nor, + bootsource_unknown, + bootsource_onenand, + bootsource_unknown, + }, { /* CTRL == NAND */ + bootsource_nand, + bootsource_nand, + bootsource_nand, + bootsource_nand, + }, { /* CTRL == ATA, (imx35 only) */ + bootsource_unknown, + bootsource_unknown, /* might be p-ata */ + bootsource_unknown, + bootsource_unknown, + }, { /* CTRL == expansion */ + bootsource_mmc, /* note imx25 could also be: movinand, ce-ata */ + bootsource_unknown, + bootsource_i2c, + bootsource_spi, + } +}; -#if defined(CONFIG_ARCH_IMX25) || defined(CONFIG_ARCH_IMX35) /* * Saves the boot source media into the $barebox_loc enviroment variable * @@ -38,43 +94,14 @@ * Note also that I suspect that the boot source pins are only sampled at * power up. */ -static int imx_25_35_boot_save_loc(void) +int imx_25_35_boot_save_loc(unsigned int ctrl, unsigned int type) { const char *bareboxloc = NULL; - uint32_t reg; - unsigned int ctrl, type; + enum imx_bootsource src; - /* [CTRL][TYPE] */ - const char *const locations[4][4] = { - { /* CTRL = WEIM */ - "nor", - NULL, - "onenand", - NULL, - }, { /* CTRL == NAND */ - "nand", - "nand", - "nand", - "nand", - }, { /* CTRL == ATA, (imx35 only) */ - NULL, - NULL, /* might be p-ata */ - NULL, - NULL, - }, { /* CTRL == expansion */ - "mmc", /* note imx25 could also be: movinand, ce-ata */ - NULL, - "i2c", - "spi", - } - }; - - reg = readl(IMX_CCM_BASE + CCM_RCSR); - ctrl = (reg >> CCM_RCSR_MEM_CTRL_SHIFT) & 0x3; - type = (reg >> CCM_RCSR_MEM_TYPE_SHIFT) & 0x3; - - bareboxloc = locations[ctrl][type]; + src = locations[ctrl][type]; + imx_set_bootsource(src); if (bareboxloc) { setenv("barebox_loc", bareboxloc); export("barebox_loc"); @@ -82,32 +109,112 @@ static int imx_25_35_boot_save_loc(void) return 0; } -coredevice_initcall(imx_25_35_boot_save_loc); -#endif -#if defined(CONFIG_ARCH_IMX27) -static int imx_27_boot_save_loc(void) +#define IMX27_SYSCTRL_GPCR 0x18 +#define IMX27_GPCR_BOOT_SHIFT 16 +#define IMX27_GPCR_BOOT_MASK (0xf << IMX27_GPCR_BOOT_SHIFT) +#define IMX27_GPCR_BOOT_UART_USB 0 +#define IMX27_GPCR_BOOT_8BIT_NAND_2k 2 +#define IMX27_GPCR_BOOT_16BIT_NAND_2k 3 +#define IMX27_GPCR_BOOT_16BIT_NAND_512 4 +#define IMX27_GPCR_BOOT_16BIT_CS0 5 +#define IMX27_GPCR_BOOT_32BIT_CS0 6 +#define IMX27_GPCR_BOOT_8BIT_NAND_512 7 + +void imx_27_boot_save_loc(void __iomem *sysctrl_base) { - switch ((GPCR & GPCR_BOOT_MASK) >> GPCR_BOOT_SHIFT) { - case GPCR_BOOT_UART_USB: - setenv("barebox_loc", "serial"); + enum imx_bootsource src; + uint32_t val; + + val = readl(sysctrl_base + IMX27_SYSCTRL_GPCR); + val &= IMX27_GPCR_BOOT_MASK; + val >>= IMX27_GPCR_BOOT_SHIFT; + + switch (val) { + case IMX27_GPCR_BOOT_UART_USB: + src = bootsource_serial; break; - case GPCR_BOOT_8BIT_NAND_2k: - case GPCR_BOOT_16BIT_NAND_2k: - case GPCR_BOOT_16BIT_NAND_512: - case GPCR_BOOT_8BIT_NAND_512: - setenv("barebox_loc", "nand"); + case IMX27_GPCR_BOOT_8BIT_NAND_2k: + case IMX27_GPCR_BOOT_16BIT_NAND_2k: + case IMX27_GPCR_BOOT_16BIT_NAND_512: + case IMX27_GPCR_BOOT_8BIT_NAND_512: + src = bootsource_nand; break; default: - setenv("barebox_loc", "nor"); + src = bootsource_nor; break; } - export("barebox_loc"); + imx_set_bootsource(src); +} + +#define IMX51_SRC_SBMR 0x4 +#define IMX51_SBMR_BT_MEM_TYPE_SHIFT 7 +#define IMX51_SBMR_BT_MEM_CTL_SHIFT 0 +#define IMX51_SBMR_BMOD_SHIFT 14 + +int imx51_boot_save_loc(void __iomem *src_base) +{ + enum imx_bootsource src = bootsource_unknown; + uint32_t reg; + unsigned int ctrl, type; + + reg = readl(src_base + IMX51_SRC_SBMR); + + switch ((reg >> IMX51_SBMR_BMOD_SHIFT) & 0x3) { + case 0: + case 2: + /* internal boot */ + ctrl = (reg >> IMX51_SBMR_BT_MEM_CTL_SHIFT) & 0x3; + type = (reg >> IMX51_SBMR_BT_MEM_TYPE_SHIFT) & 0x3; + + src = locations[ctrl][type]; + break; + case 1: + /* reserved */ + src = bootsource_unknown; + break; + case 3: + src = bootsource_serial; + break; + + } + + imx_set_bootsource(src); return 0; } -coredevice_initcall(imx_27_boot_save_loc); -#endif -BAREBOX_MAGICVAR(barebox_loc, "The source barebox has been booted from"); +#define IMX53_SRC_SBMR 0x4 +int imx53_boot_save_loc(void __iomem *src_base) +{ + enum imx_bootsource src = bootsource_unknown; + uint32_t cfg1 = readl(src_base + IMX53_SRC_SBMR) & 0xff; + + switch (cfg1 >> 4) { + case 2: + src = bootsource_hd; + break; + case 3: + if (cfg1 & (1 << 3)) + src = bootsource_spi; + else + src = bootsource_i2c; + break; + case 4: + case 5: + case 6: + case 7: + src = bootsource_mmc; + break; + default: + break; + } + + if (cfg1 & (1 << 7)) + src = bootsource_nand; + + imx_set_bootsource(src); + + return 0; +} diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c index 45e9c6643f..0d04a92f36 100644 --- a/arch/arm/mach-imx/clk-imx1.c +++ b/arch/arm/mach-imx/clk-imx1.c @@ -96,9 +96,18 @@ static int imx1_ccm_probe(struct device_d *dev) return 0; } +static __maybe_unused struct of_device_id imx1_ccm_dt_ids[] = { + { + .compatible = "fsl,imx1-ccm", + }, { + /* sentinel */ + } +}; + static struct driver_d imx1_ccm_driver = { .probe = imx1_ccm_probe, .name = "imx1-ccm", + .of_compatible = DRV_OF_COMPAT(imx1_ccm_dt_ids), }; static int imx1_ccm_init(void) diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c index 69aaa9e6ad..9e7af816a2 100644 --- a/arch/arm/mach-imx/clk-imx21.c +++ b/arch/arm/mach-imx/clk-imx21.c @@ -47,7 +47,7 @@ enum imx21_clks { ckil, ckih, fpm, mpll_sel, spll_sel, mpll, spll, fclk, hclk, ipg, per1, - per2, per3, per4, usb_div, nfc_div, clk_max + per2, per3, per4, usb_div, nfc_div, lcdc_per_gate, clk_max }; static struct clk *clks[clk_max]; @@ -70,6 +70,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), + base + CCM_PCCR0); + + writel((1 << 23) | (1 << 24) | (1 << 25) | (1 << 26) | (1 << 27) | + (1 << 28) | (1 << 29) | (1 << 30) | (1 << 31), + base + CCM_PCCR1); + clks[ckil] = clk_fixed("ckil", lref); clks[ckih] = clk_fixed("ckih", href); clks[fpm] = imx_clk_fixed_factor("fpm", "ckil", 512, 1); @@ -88,6 +98,7 @@ static int imx21_ccm_probe(struct device_d *dev) clks[per4] = imx_clk_divider("per4", "mpll", base + CCM_PCDR1, 24, 6); 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); clkdev_add_physbase(clks[per1], MX21_GPT1_BASE_ADDR, NULL); clkdev_add_physbase(clks[per1], MX21_GPT2_BASE_ADDR, NULL); @@ -98,18 +109,27 @@ static int imx21_ccm_probe(struct device_d *dev) clkdev_add_physbase(clks[per1], MX21_UART4_BASE_ADDR, NULL); clkdev_add_physbase(clks[per2], MX21_CSPI1_BASE_ADDR, NULL); clkdev_add_physbase(clks[per2], MX21_CSPI2_BASE_ADDR, NULL); + clkdev_add_physbase(clks[per2], MX21_CSPI3_BASE_ADDR, NULL); clkdev_add_physbase(clks[ipg], MX21_I2C_BASE_ADDR, NULL); clkdev_add_physbase(clks[ipg], MX21_SDHC1_BASE_ADDR, NULL); clkdev_add_physbase(clks[ipg], MX21_SDHC2_BASE_ADDR, NULL); - clkdev_add_physbase(clks[per3], MX21_CSPI3_BASE_ADDR, NULL); - clkdev_add_physbase(clks[per3], MX21_LCDC_BASE_ADDR, NULL); + clkdev_add_physbase(clks[lcdc_per_gate], MX21_LCDC_BASE_ADDR, NULL); return 0; } +static __maybe_unused struct of_device_id imx21_ccm_dt_ids[] = { + { + .compatible = "fsl,imx21-ccm", + }, { + /* sentinel */ + } +}; + static struct driver_d imx21_ccm_driver = { .probe = imx21_ccm_probe, .name = "imx21-ccm", + .of_compatible = DRV_OF_COMPAT(imx21_ccm_dt_ids), }; static int imx21_ccm_init(void) diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c index 3b9588ced5..38f15a66ab 100644 --- a/arch/arm/mach-imx/clk-imx25.c +++ b/arch/arm/mach-imx/clk-imx25.c @@ -55,7 +55,7 @@ enum mx25_clks { per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel, per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5, per6, per7, per8, per9, per10, per11, per12, per13, per14, per15, - clk_max + lcdc_per_gate, clk_max }; static struct clk *clks[clk_max]; @@ -76,9 +76,19 @@ static int imx25_ccm_probe(struct device_d *dev) base = dev_request_mem_region(dev, 0); - writel(0x10e88578, base + CCM_CGCR0); - writel(0x0478e1e0, base + CCM_CGCR0); - writel(0x0007c400, base + CCM_CGCR0); + writel((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 8) | (1 << 9) | + (1 << 10) | (1 << 15) | (1 << 19) | (1 << 21) | (1 << 22) | + (1 << 23) | (1 << 24) | (1 << 28), + base + CCM_CGCR0); + + writel((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 13) | (1 << 14) | + (1 << 15) | (1 << 19) | (1 << 20) | (1 << 21) | (1 << 22) | + (1 << 26) | (1 << 29) | (1 << 31), + base + CCM_CGCR1); + + writel((1 << 0) | (1 << 1) | (1 << 2) | (1 << 10) | (1 << 13) | (1 << 14) | + (1 << 15) | (1 << 16) | (1 << 17) | (1 << 18), + base + CCM_CGCR2); clks[dummy] = clk_fixed("dummy", 0); clks[osc] = clk_fixed("osc", 24000000); @@ -122,6 +132,7 @@ static int imx25_ccm_probe(struct device_d *dev) clks[per13] = imx_clk_divider("per13", "per13_sel", base + CCM_PCDR3, 8, 6); clks[per14] = imx_clk_divider("per14", "per14_sel", base + CCM_PCDR3, 16, 6); clks[per15] = imx_clk_divider("per15", "per15_sel", base + CCM_PCDR3, 24, 6); + clks[lcdc_per_gate] = imx_clk_gate("lcdc_per_gate", "per7", base + CCM_CGCR0, 7); clkdev_add_physbase(clks[per15], MX25_UART1_BASE_ADDR, NULL); clkdev_add_physbase(clks[per15], MX25_UART2_BASE_ADDR, NULL); @@ -138,13 +149,23 @@ static int imx25_ccm_probe(struct device_d *dev) clkdev_add_physbase(clks[ipg], MX25_CSPI3_BASE_ADDR, NULL); 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); return 0; } +static __maybe_unused struct of_device_id imx25_ccm_dt_ids[] = { + { + .compatible = "fsl,imx25-ccm", + }, { + /* sentinel */ + } +}; + static struct driver_d imx25_ccm_driver = { .probe = imx25_ccm_probe, .name = "imx25-ccm", + .of_compatible = DRV_OF_COMPAT(imx25_ccm_dt_ids), }; static int imx25_ccm_init(void) diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c index abfde0fd62..222d2a6ebc 100644 --- a/arch/arm/mach-imx/clk-imx27.c +++ b/arch/arm/mach-imx/clk-imx27.c @@ -7,6 +7,7 @@ #include <linux/err.h> #include <mach/imx27-regs.h> #include <mach/generic.h> +#include <mach/revision.h> #include "clk.h" @@ -26,10 +27,73 @@ #define CCM_PMCOUNT 0x30 #define CCM_WKGDCTL 0x34 +#define PCCR0_SSI2_EN (1 << 0) +#define PCCR0_SSI1_EN (1 << 1) +#define PCCR0_SLCDC_EN (1 << 2) +#define PCCR0_SDHC3_EN (1 << 3) +#define PCCR0_SDHC2_EN (1 << 4) +#define PCCR0_SDHC1_EN (1 << 5) +#define PCCR0_SDC_EN (1 << 6) +#define PCCR0_SAHARA_EN (1 << 7) +#define PCCR0_RTIC_EN (1 << 8) +#define PCCR0_RTC_EN (1 << 9) +#define PCCR0_PWM_EN (1 << 11) +#define PCCR0_OWIRE_EN (1 << 12) +#define PCCR0_MSHC_EN (1 << 13) +#define PCCR0_LCDC_EN (1 << 14) +#define PCCR0_KPP_EN (1 << 15) +#define PCCR0_IIM_EN (1 << 16) +#define PCCR0_I2C2_EN (1 << 17) +#define PCCR0_I2C1_EN (1 << 18) +#define PCCR0_GPT6_EN (1 << 19) +#define PCCR0_GPT5_EN (1 << 20) +#define PCCR0_GPT4_EN (1 << 21) +#define PCCR0_GPT3_EN (1 << 22) +#define PCCR0_GPT2_EN (1 << 23) +#define PCCR0_GPT1_EN (1 << 24) +#define PCCR0_GPIO_EN (1 << 25) +#define PCCR0_FEC_EN (1 << 26) +#define PCCR0_EMMA_EN (1 << 27) +#define PCCR0_DMA_EN (1 << 28) +#define PCCR0_CSPI3_EN (1 << 29) +#define PCCR0_CSPI2_EN (1 << 30) +#define PCCR0_CSPI1_EN (1 << 31) + +#define PCCR1_MSHC_BAUDEN (1 << 2) +#define PCCR1_NFC_BAUDEN (1 << 3) +#define PCCR1_SSI2_BAUDEN (1 << 4) +#define PCCR1_SSI1_BAUDEN (1 << 5) +#define PCCR1_H264_BAUDEN (1 << 6) +#define PCCR1_PERCLK4_EN (1 << 7) +#define PCCR1_PERCLK3_EN (1 << 8) +#define PCCR1_PERCLK2_EN (1 << 9) +#define PCCR1_PERCLK1_EN (1 << 10) +#define PCCR1_HCLK_USB (1 << 11) +#define PCCR1_HCLK_SLCDC (1 << 12) +#define PCCR1_HCLK_SAHARA (1 << 13) +#define PCCR1_HCLK_RTIC (1 << 14) +#define PCCR1_HCLK_LCDC (1 << 15) +#define PCCR1_HCLK_H264 (1 << 16) +#define PCCR1_HCLK_FEC (1 << 17) +#define PCCR1_HCLK_EMMA (1 << 18) +#define PCCR1_HCLK_EMI (1 << 19) +#define PCCR1_HCLK_DMA (1 << 20) +#define PCCR1_HCLK_CSI (1 << 21) +#define PCCR1_HCLK_BROM (1 << 22) +#define PCCR1_HCLK_ATA (1 << 23) +#define PCCR1_WDT_EN (1 << 24) +#define PCCR1_USB_EN (1 << 25) +#define PCCR1_UART6_EN (1 << 26) +#define PCCR1_UART5_EN (1 << 27) +#define PCCR1_UART4_EN (1 << 28) +#define PCCR1_UART3_EN (1 << 29) +#define PCCR1_UART2_EN (1 << 30) +#define PCCR1_UART1_EN (1 << 31) + 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, clk_max + clko_en, lcdc_per_gate, clk_max }; static struct clk *clks[clk_max]; @@ -72,18 +136,18 @@ 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_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 | PCCR0_CSPI1_EN, + PCCR0_PWM_EN | PCCR0_KPP_EN | PCCR0_LCDC_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 | + PCCR0_CSPI1_EN, base + CCM_PCCR0); - writel(PCCR1_NFC_BAUDEN | PCCR1_PERCLK4_EN | PCCR1_PERCLK3_EN | - PCCR1_PERCLK2_EN | PCCR1_PERCLK1_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); + 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, + base + CCM_PCCR1); clks[dummy] = clk_fixed("dummy", 0); clks[ckih] = clk_fixed("ckih", 26000000); @@ -92,7 +156,7 @@ static int imx27_ccm_probe(struct device_d *dev) clks[spll] = imx_clk_pllv1("spll", "ckih", base + CCM_SPCTL0); clks[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3); - if (imx_silicon_revision() >= IMX27_CHIP_REVISION_2_0) { + if (imx_silicon_revision() >= IMX_CHIP_REV_2_0) { clks[ahb] = imx_clk_divider("ahb", "mpll_main2", base + CCM_CSCR, 8, 2); clks[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2); } else { @@ -110,11 +174,12 @@ static int imx27_ccm_probe(struct device_d *dev) ARRAY_SIZE(cpu_sel_clks)); clks[clko_sel] = imx_clk_mux("clko_sel", base + CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks)); - if (imx_silicon_revision() >= IMX27_CHIP_REVISION_2_0) + if (imx_silicon_revision() >= IMX_CHIP_REV_2_0) clks[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", base + CCM_CSCR, 12, 2); 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); clkdev_add_physbase(clks[per1_div], MX27_GPT1_BASE_ADDR, NULL); clkdev_add_physbase(clks[per1_div], MX27_GPT2_BASE_ADDR, NULL); @@ -136,15 +201,24 @@ static int imx27_ccm_probe(struct device_d *dev) clkdev_add_physbase(clks[per2_div], MX27_SDHC1_BASE_ADDR, NULL); 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[per3_div], MX27_LCDC_BASE_ADDR, NULL); + clkdev_add_physbase(clks[lcdc_per_gate], MX27_LCDC_BASE_ADDR, NULL); clkdev_add_physbase(clks[ipg], MX27_FEC_BASE_ADDR, NULL); return 0; } +static __maybe_unused struct of_device_id imx27_ccm_dt_ids[] = { + { + .compatible = "fsl,imx27-ccm", + }, { + /* sentinel */ + } +}; + static struct driver_d imx27_ccm_driver = { .probe = imx27_ccm_probe, .name = "imx27-ccm", + .of_compatible = DRV_OF_COMPAT(imx27_ccm_dt_ids), }; static int imx27_ccm_init(void) diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c index cf8963a326..aa1b652ddd 100644 --- a/arch/arm/mach-imx/clk-imx31.c +++ b/arch/arm/mach-imx/clk-imx31.c @@ -121,9 +121,18 @@ static int imx31_ccm_probe(struct device_d *dev) return 0; } +static __maybe_unused struct of_device_id imx31_ccm_dt_ids[] = { + { + .compatible = "fsl,imx31-ccm", + }, { + /* sentinel */ + } +}; + static struct driver_d imx31_ccm_driver = { .probe = imx31_ccm_probe, .name = "imx31-ccm", + .of_compatible = DRV_OF_COMPAT(imx31_ccm_dt_ids), }; static int imx31_ccm_init(void) diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index dfa75614fa..5b5a9e7882 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -174,9 +174,18 @@ static int imx35_ccm_probe(struct device_d *dev) return 0; } +static __maybe_unused struct of_device_id imx35_ccm_dt_ids[] = { + { + .compatible = "fsl,imx35-ccm", + }, { + /* sentinel */ + } +}; + static struct driver_d imx35_ccm_driver = { .probe = imx35_ccm_probe, .name = "imx35-ccm", + .of_compatible = DRV_OF_COMPAT(imx35_ccm_dt_ids), }; static int imx35_ccm_init(void) diff --git a/arch/arm/mach-imx/clk-imx5.c b/arch/arm/mach-imx/clk-imx5.c index 365fcb3338..050842d103 100644 --- a/arch/arm/mach-imx/clk-imx5.c +++ b/arch/arm/mach-imx/clk-imx5.c @@ -13,7 +13,8 @@ #include <io.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx-regs.h> +#include <mach/imx51-regs.h> +#include <mach/imx53-regs.h> #include "clk.h" @@ -233,9 +234,18 @@ static int imx51_ccm_probe(struct device_d *dev) return 0; } +static __maybe_unused struct of_device_id imx51_ccm_dt_ids[] = { + { + .compatible = "fsl,imx51-ccm", + }, { + /* sentinel */ + } +}; + static struct driver_d imx51_ccm_driver = { .probe = imx51_ccm_probe, .name = "imx51-ccm", + .of_compatible = DRV_OF_COMPAT(imx51_ccm_dt_ids), }; static int imx51_ccm_init(void) @@ -285,9 +295,18 @@ static int imx53_ccm_probe(struct device_d *dev) return 0; } +static __maybe_unused struct of_device_id imx53_ccm_dt_ids[] = { + { + .compatible = "fsl,imx53-ccm", + }, { + /* sentinel */ + } +}; + static struct driver_d imx53_ccm_driver = { .probe = imx53_ccm_probe, .name = "imx53-ccm", + .of_compatible = DRV_OF_COMPAT(imx53_ccm_dt_ids), }; static int imx53_ccm_init(void) diff --git a/arch/arm/mach-imx/clk-imx6.c b/arch/arm/mach-imx/clk-imx6.c index 19a8bc6836..a1da47a959 100644 --- a/arch/arm/mach-imx/clk-imx6.c +++ b/arch/arm/mach-imx/clk-imx6.c @@ -294,9 +294,18 @@ static int imx6_ccm_probe(struct device_d *dev) return 0; } +static __maybe_unused struct of_device_id imx6_ccm_dt_ids[] = { + { + .compatible = "fsl,imx6-ccm", + }, { + /* sentinel */ + } +}; + static struct driver_d imx6_ccm_driver = { .probe = imx6_ccm_probe, .name = "imx6-ccm", + .of_compatible = DRV_OF_COMPAT(imx6_ccm_dt_ids), }; static int imx6_ccm_init(void) diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c index 69072698c4..7e087c1789 100644 --- a/arch/arm/mach-imx/clk-pllv2.c +++ b/arch/arm/mach-imx/clk-pllv2.c @@ -17,7 +17,6 @@ #include <io.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx-regs.h> #include <malloc.h> #include <asm-generic/div64.h> diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c index a99eec56a3..e337e87f13 100644 --- a/arch/arm/mach-imx/clk-pllv3.c +++ b/arch/arm/mach-imx/clk-pllv3.c @@ -17,7 +17,6 @@ #include <io.h> #include <linux/clkdev.h> #include <linux/err.h> -#include <mach/imx-regs.h> #include <malloc.h> #include <clock.h> #include <asm-generic/div64.h> diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h index 3d79950697..0f30082e1f 100644 --- a/arch/arm/mach-imx/clk.h +++ b/arch/arm/mach-imx/clk.h @@ -19,6 +19,12 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg, return clk_mux(name, reg, shift, width, parents, num_parents); } +static inline struct clk *imx_clk_gate(const char *name, const char *parent, + void __iomem *reg, u8 shift) +{ + return clk_gate(name, parent, reg, shift); +} + struct clk *imx_clk_pllv1(const char *name, const char *parent, void __iomem *base); diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c index 69a688c09d..e18685ec29 100644 --- a/arch/arm/mach-imx/clocksource.c +++ b/arch/arm/mach-imx/clocksource.c @@ -32,7 +32,6 @@ #include <linux/clk.h> #include <linux/err.h> #include <notifier.h> -#include <mach/imx-regs.h> #include <io.h> /* Part 1: Registers */ @@ -108,18 +107,6 @@ static int imx_gpt_probe(struct device_d *dev) /* setup GP Timer 1 */ writel(TCTL_SWR, timer_base + GPT_TCTL); -#ifdef CONFIG_ARCH_IMX21 - PCCR1 |= PCCR1_GPT1_EN; -#endif -#ifdef CONFIG_ARCH_IMX27 - PCCR0 |= PCCR0_GPT1_EN; - PCCR1 |= PCCR1_PERCLK1_EN; -#endif -#ifdef CONFIG_ARCH_IMX25 - writel(readl(IMX_CCM_BASE + CCM_CGCR1) | (1 << 19), - IMX_CCM_BASE + CCM_CGCR1); -#endif - for (i = 0; i < 100; i++) writel(0, timer_base + GPT_TCTL); /* We have no udelay by now */ @@ -179,40 +166,3 @@ static int imx_gpt_init(void) return platform_driver_register(&imx_gpt_driver); } coredevice_initcall(imx_gpt_init); - -/* - * Watchdog Registers - */ -#ifdef CONFIG_ARCH_IMX1 -#define WDOG_WCR 0x00 /* Watchdog Control Register */ -#define WDOG_WSR 0x04 /* Watchdog Service Register */ -#define WDOG_WSTR 0x08 /* Watchdog Status Register */ -#define WDOG_WCR_WDE (1 << 0) -#else -#define WDOG_WCR 0x00 /* Watchdog Control Register */ -#define WDOG_WSR 0x02 /* Watchdog Service Register */ -#define WDOG_WSTR 0x04 /* Watchdog Status Register */ -#define WDOG_WCR_WDE (1 << 2) -#endif - -/* - * Reset the cpu by setting up the watchdog timer and let it time out - */ -void __noreturn reset_cpu (unsigned long addr) -{ - void __iomem *wdt = IOMEM(IMX_WDT_BASE); - - /* Disable watchdog and set Time-Out field to 0 */ - writew(0x0, wdt + WDOG_WCR); - - /* Write Service Sequence */ - writew(0x5555, wdt + WDOG_WSR); - writew(0xaaaa, wdt + WDOG_WSR); - - /* Enable watchdog */ - writew(WDOG_WCR_WDE, wdt + WDOG_WCR); - - while (1); - /*NOTREACHED*/ -} -EXPORT_SYMBOL(reset_cpu); diff --git a/arch/arm/mach-imx/devices.c b/arch/arm/mach-imx/devices.c index 9fde84f1a1..4ee4e6cc8d 100644 --- a/arch/arm/mach-imx/devices.c +++ b/arch/arm/mach-imx/devices.c @@ -8,9 +8,14 @@ static inline struct device_d *imx_add_device(char *name, int id, void *base, in IORESOURCE_MEM, pdata); } -struct device_d *imx_add_fec(void *base, struct fec_platform_data *pdata) +struct device_d *imx_add_fec_imx27(void *base, struct fec_platform_data *pdata) { - return imx_add_device("fec_imx", -1, base, 0x1000, pdata); + return imx_add_device("imx27-fec", -1, base, 0x1000, pdata); +} + +struct device_d *imx_add_fec_imx6(void *base, struct fec_platform_data *pdata) +{ + return imx_add_device("imx6-fec", -1, base, 0x1000, pdata); } struct device_d *imx_add_spi(void *base, int id, struct spi_imx_master *pdata) @@ -23,9 +28,14 @@ struct device_d *imx_add_i2c(void *base, int id, struct i2c_platform_data *pdata return imx_add_device("i2c-fsl", id, base, 0x1000, pdata); } -struct device_d *imx_add_uart(void *base, int id) +struct device_d *imx_add_uart_imx1(void *base, int id) +{ + return imx_add_device("imx1-uart", id, base, 0x1000, NULL); +} + +struct device_d *imx_add_uart_imx21(void *base, int id) { - return imx_add_device("imx_serial", id, base, 0x1000, NULL); + return imx_add_device("imx21-uart", id, base, 0x1000, NULL); } struct device_d *imx_add_nand(void *base, struct imx_nand_platform_data *pdata) diff --git a/arch/arm/mach-imx/external-nand-boot.c b/arch/arm/mach-imx/external-nand-boot.c index a5909923f6..2e9e475fed 100644 --- a/arch/arm/mach-imx/external-nand-boot.c +++ b/arch/arm/mach-imx/external-nand-boot.c @@ -17,7 +17,11 @@ #include <linux/mtd/nand.h> #include <mach/imx-nand.h> #include <mach/generic.h> -#include <mach/imx-regs.h> +#include <mach/imx21-regs.h> +#include <mach/imx25-regs.h> +#include <mach/imx27-regs.h> +#include <mach/imx31-regs.h> +#include <mach/imx35-regs.h> static void __bare_init noinline imx_nandboot_wait_op_done(void *regs) { @@ -116,7 +120,13 @@ static void __bare_init __memcpy32(void *trg, const void *src, int size) static int __maybe_unused is_pagesize_2k(void) { #ifdef CONFIG_ARCH_IMX21 - if (readl(IMX_SYSTEM_CTL_BASE + 0x14) & (1 << 5)) + if (readl(MX21_SYSCTRL_BASE_ADDR + 0x14) & (1 << 5)) + return 1; + else + return 0; +#endif +#if defined(CONFIG_ARCH_IMX25) + if (readl(MX25_CCM_BASE_ADDR + MX25_CCM_RCSR) & (1 << 8)) return 1; else return 0; @@ -128,13 +138,13 @@ static int __maybe_unused is_pagesize_2k(void) return 0; #endif #ifdef CONFIG_ARCH_IMX31 - if (readl(IMX_CCM_BASE + CCM_RCSR) & RCSR_NFMS) + if (readl(MX31_CCM_BASE_ADDR + MX31_CCM_RCSR) & MX31_RCSR_NFMS) return 1; else return 0; #endif -#if defined(CONFIG_ARCH_IMX35) || defined(CONFIG_ARCH_IMX25) - if (readl(IMX_CCM_BASE + CCM_RCSR) & (1 << 8)) +#if defined(CONFIG_ARCH_IMX35) + if (readl(MX35_CCM_BASE_ADDR + MX35_CCM_RCSR) & (1 << 8)) return 1; else return 0; @@ -163,7 +173,21 @@ void __bare_init imx_nand_load_image(void *dest, int size) blocksize = 16 * 1024; } - base = (void __iomem *)IMX_NFC_BASE; +#ifdef CONFIG_ARCH_IMX21 + base = (void __iomem *)MX21_NFC_BASE_ADDR; +#endif +#ifdef CONFIG_ARCH_IMX25 + base = (void __iomem *)MX25_NFC_BASE_ADDR; +#endif +#ifdef CONFIG_ARCH_IMX27 + base = (void __iomem *)MX27_NFC_BASE_ADDR; +#endif +#ifdef CONFIG_ARCH_IMX31 + base = (void __iomem *)MX31_NFC_BASE_ADDR; +#endif +#ifdef CONFIG_ARCH_IMX35 + base = (void __iomem *)MX35_NFC_BASE_ADDR; +#endif if (nfc_is_v21()) { regs = base + 0x1e00; spare0 = base + 0x1000; diff --git a/arch/arm/mach-imx/gpio.c b/arch/arm/mach-imx/gpio.c index 6c88948da0..1bf4100964 100644 --- a/arch/arm/mach-imx/gpio.c +++ b/arch/arm/mach-imx/gpio.c @@ -23,7 +23,6 @@ #include <common.h> #include <errno.h> #include <io.h> -#include <mach/imx-regs.h> #include <gpio.h> #include <init.h> @@ -137,6 +136,7 @@ static int imx_gpio_probe(struct device_d *dev) imxgpio->chip.base = of_alias_get_id(dev->device_node, "gpio"); if (imxgpio->chip.base < 0) return imxgpio->chip.base; + imxgpio->chip.base *= 32; } else { imxgpio->chip.base = dev->id * 32; } diff --git a/arch/arm/mach-imx/imx-bbu-internal.c b/arch/arm/mach-imx/imx-bbu-internal.c new file mode 100644 index 0000000000..85d10cf4e7 --- /dev/null +++ b/arch/arm/mach-imx/imx-bbu-internal.c @@ -0,0 +1,543 @@ +/* + * imx-bbu-internal.c - i.MX specific update functions for internal boot + * + * Copyright (c) 2012 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 IMX_INTERNAL_NAND_BBU + +#include <common.h> +#include <malloc.h> +#include <bbu.h> +#include <filetype.h> +#include <errno.h> +#include <fs.h> +#include <fcntl.h> +#include <sizes.h> +#include <linux/mtd/mtd-abi.h> +#include <linux/stat.h> +#include <ioctl.h> +#include <mach/bbu.h> +#include <mach/imx-flash-header.h> + +#define FLASH_HEADER_OFFSET_MMC 0x400 + +#define IMX_INTERNAL_FLAG_NAND (1 << 0) +#define IMX_INTERNAL_FLAG_KEEP_DOSPART (1 << 1) + +struct imx_internal_bbu_handler { + struct bbu_handler handler; + const void *dcd; + int dcdsize; + unsigned long app_dest; + unsigned long flash_header_offset; + size_t device_size; + unsigned long flags; +}; + +/* + * Actually write an image to the target device, eventually keeping a + * DOS partition table on the device + */ +static int imx_bbu_write_device(struct imx_internal_bbu_handler *imx_handler, + struct bbu_data *data, void *buf, int image_len) +{ + int fd, ret; + + fd = open(data->devicefile, O_RDWR | O_CREAT); + if (fd < 0) + return fd; + + if (imx_handler->flags & IMX_INTERNAL_FLAG_KEEP_DOSPART) { + void *mbr = xzalloc(512); + + debug("%s: reading DOS partition table in order to keep it\n"); + + ret = read(fd, mbr, 512); + if (ret < 0) { + free(mbr); + goto err_close; + } + + memcpy(buf + 0x1b8, mbr + 0x1b8, 0x48); + free(buf); + + ret = lseek(fd, 0, SEEK_SET); + if (ret) + goto err_close; + } + + ret = write(fd, buf, image_len); + if (ret < 0) + goto err_close; + + ret = 0; + +err_close: + close(fd); + + return ret; +} + +/* + * Update barebox on a v1 type internal boot (i.MX25, i.MX35, i.MX51) + * + * This constructs a DCD header, adds the specific DCD data and writes + * the resulting image to the device. Currently this handles MMC/SD + * devices. + */ +static int imx_bbu_internal_v1_update(struct bbu_handler *handler, struct bbu_data *data) +{ + struct imx_internal_bbu_handler *imx_handler = + container_of(handler, struct imx_internal_bbu_handler, handler); + struct imx_flash_header *flash_header; + unsigned long flash_header_offset = imx_handler->flash_header_offset; + u32 *dcd_image_size; + void *imx_pre_image; + int imx_pre_image_size = 0x2000; + int ret, image_len; + void *buf; + + if (file_detect_type(data->image) != filetype_arm_barebox) { + if (!bbu_force(data, "Not an ARM barebox image")) + return -EINVAL; + } + + ret = bbu_confirm(data); + if (ret) + return ret; + + printf("updating to %s\n", data->devicefile); + + imx_pre_image = xzalloc(imx_pre_image_size); + flash_header = imx_pre_image + flash_header_offset; + + flash_header->app_code_jump_vector = imx_handler->app_dest + 0x1000; + flash_header->app_code_barker = APP_CODE_BARKER; + flash_header->app_code_csf = 0; + flash_header->dcd_ptr_ptr = imx_handler->app_dest + flash_header_offset + + offsetof(struct imx_flash_header, dcd); + flash_header->super_root_key = 0; + flash_header->dcd = imx_handler->app_dest + flash_header_offset + + offsetof(struct imx_flash_header, dcd_barker); + flash_header->app_dest = imx_handler->app_dest; + flash_header->dcd_barker = DCD_BARKER; + flash_header->dcd_block_len = imx_handler->dcdsize; + + memcpy((void *)flash_header + sizeof(*flash_header), imx_handler->dcd, imx_handler->dcdsize); + + dcd_image_size = (imx_pre_image + flash_header_offset + sizeof(*flash_header) + imx_handler->dcdsize); + + *dcd_image_size = ALIGN(imx_pre_image_size + data->len, 4096); + + /* Create a buffer containing header and image data */ + image_len = data->len + imx_pre_image_size; + buf = xzalloc(image_len); + memcpy(buf, imx_pre_image, imx_pre_image_size); + memcpy(buf + imx_pre_image_size, data->image, data->len); + + ret = imx_bbu_write_device(imx_handler, data, buf, image_len); + + free(buf); + + free(imx_pre_image); + + return ret; +} + +#define DBBT_MAGIC 0x44424254 +#define FCB_MAGIC 0x20424346 + +/* + * Write an image to NAND. This creates a FCB header and a DBBT (Discovered Bad + * Block Table). The DBBT is initialized with the bad blocks known from the mtd + * layer. + */ +static int imx_bbu_internal_v2_write_nand_dbbt(struct imx_internal_bbu_handler *imx_handler, + struct bbu_data *data, void *image, int image_len) +{ + struct mtd_info_user meminfo; + int fd; + struct stat s; + int size_available, size_need; + int ret; + uint32_t *ptr, *num_bb, *bb; + uint64_t offset; + int block = 0, len, now, blocksize; + + ret = stat(data->devicefile, &s); + if (ret) + return ret; + + size_available = s.st_size; + + fd = open(data->devicefile, O_RDWR); + if (fd < 0) + return fd; + + ret = ioctl(fd, MEMGETINFO, &meminfo); + if (ret) + goto out; + + blocksize = meminfo.erasesize; + + ptr = image + 0x4; + *ptr++ = FCB_MAGIC; /* FCB */ + *ptr++ = 1; /* FCB version */ + + ptr = image + 0x78; /* DBBT start page */ + *ptr = 4; + + ptr = image + 4 * 2048 + 4; + *ptr++ = DBBT_MAGIC; /* DBBT */ + *ptr = 1; /* DBBT version */ + + ptr = (u32*)(image + 0x2010); + /* + * This is marked as reserved in the i.MX53 reference manual, but + * must be != 0. Otherwise the ROM ignores the DBBT + */ + *ptr = 1; + + ptr = (u32*)(image + 0x4004); /* start of DBBT */ + num_bb = ptr; + bb = ptr + 1; + offset = 0; + + size_need = data->len + 0x8000; + + /* + * Collect bad blocks and construct DBBT + */ + while (size_need > 0) { + ret = ioctl(fd, MEMGETBADBLOCK, &offset); + if (ret < 0) + goto out; + + if (ret) { + if (!offset) { + printf("1st block is bad. This is not supported\n"); + ret = -EINVAL; + goto out; + } + + debug("bad block at 0x%08llx\n", offset); + *num_bb += 1; + if (*num_bb == 425) { + /* Maximum number of bad blocks the ROM supports */ + printf("maximum number of bad blocks reached\n"); + ret = -ENOSPC; + goto out; + } + *bb++ = block; + offset += blocksize; + block++; + continue; + } + size_need -= blocksize; + size_available -= blocksize; + offset += blocksize; + block++; + + if (size_available < 0) { + printf("device is too small"); + ret = -ENOSPC; + goto out; + } + } + + debug("total image size: 0x%08x. Space needed including bad blocks: 0x%08x\n", + data->len + 0x8000, + data->len + 0x8000 + *num_bb * blocksize); + + if (data->len + 0x8000 + *num_bb * blocksize > imx_handler->device_size) { + printf("needed space (0x%08x) exceeds partition space (0x%08x)\n", + data->len + 0x8000 + *num_bb * blocksize, + imx_handler->device_size); + ret = -ENOSPC; + goto out; + } + + len = data->len + 0x8000; + offset = 0; + + /* + * Write image to NAND skipping bad blocks + */ + while (len > 0) { + now = min(len, blocksize); + + ret = ioctl(fd, MEMGETBADBLOCK, &offset); + if (ret < 0) + goto out; + + if (ret) { + ret = lseek(fd, offset + blocksize, SEEK_SET); + if (ret < 0) + goto out; + offset += blocksize; + continue; + } + + debug("writing %d bytes at 0x%08llx\n", now, offset); + + ret = erase(fd, blocksize, offset); + if (ret) + goto out; + + ret = write(fd, image, now); + if (ret < 0) + goto out; + + len -= now; + image += now; + offset += now; + } + + ret = 0; + +out: + close(fd); + + return ret; +} + +/* + * Update barebox on a v2 type internal boot (i.MX53) + * + * This constructs a DCD header, adds the specific DCD data and writes + * the resulting image to the device. Currently this handles MMC/SD + * and NAND devices. + */ +static int imx_bbu_internal_v2_update(struct bbu_handler *handler, struct bbu_data *data) +{ + struct imx_internal_bbu_handler *imx_handler = + container_of(handler, struct imx_internal_bbu_handler, handler); + struct imx_flash_header_v2 *flash_header; + unsigned long flash_header_offset = imx_handler->flash_header_offset; + void *imx_pre_image; + int imx_pre_image_size; + int ret, image_len; + void *buf; + + if (file_detect_type(data->image) != filetype_arm_barebox) { + if (!bbu_force(data, "Not an ARM barebox image")) + return -EINVAL; + } + + ret = bbu_confirm(data); + if (ret) + return ret; + + printf("updating to %s\n", data->devicefile); + + if (imx_handler->flags & IMX_INTERNAL_FLAG_NAND) + /* NAND needs additional space for the DBBT */ + imx_pre_image_size = 0x8000; + else + imx_pre_image_size = 0x2000; + + imx_pre_image = xzalloc(imx_pre_image_size); + flash_header = imx_pre_image + flash_header_offset; + + flash_header->header.tag = IVT_HEADER_TAG; + flash_header->header.length = cpu_to_be16(32); + flash_header->header.version = IVT_VERSION; + + flash_header->entry = imx_handler->app_dest + imx_pre_image_size; + flash_header->dcd_ptr = imx_handler->app_dest + flash_header_offset + + offsetof(struct imx_flash_header_v2, dcd); + flash_header->boot_data_ptr = imx_handler->app_dest + + flash_header_offset + offsetof(struct imx_flash_header_v2, boot_data); + flash_header->self = imx_handler->app_dest + flash_header_offset; + + flash_header->boot_data.start = imx_handler->app_dest; + flash_header->boot_data.size = ALIGN(imx_pre_image_size + data->len, 4096);; + + flash_header->dcd.header.tag = DCD_HEADER_TAG; + flash_header->dcd.header.length = cpu_to_be16(sizeof(struct imx_dcd) + + imx_handler->dcdsize); + flash_header->dcd.header.version = DCD_VERSION; + + /* Add dcd data */ + memcpy((void *)flash_header + sizeof(*flash_header), imx_handler->dcd, imx_handler->dcdsize); + + /* Create a buffer containing header and image data */ + image_len = data->len + imx_pre_image_size; + buf = xzalloc(image_len); + memcpy(buf, imx_pre_image, imx_pre_image_size); + memcpy(buf + imx_pre_image_size, data->image, data->len); + + if (imx_handler->flags & IMX_INTERNAL_FLAG_NAND) { + ret = imx_bbu_internal_v2_write_nand_dbbt(imx_handler, data, buf, + image_len); + goto out_free_buf; + } + + ret = imx_bbu_write_device(imx_handler, data, buf, image_len); + +out_free_buf: + free(buf); + + free(imx_pre_image); + return ret; +} + +/* + * On the i.MX53 the dcd data can contain several commands. Each of them must + * have its length encoded into it. We can't express that during compile time, + * so use this function if you are using multiple dcd commands and wish to + * concatenate them together to a single dcd table with the correct sizes for + * each command. + */ +void *imx53_bbu_internal_concat_dcd_table(struct dcd_table *table, int num_entries) +{ + int i; + unsigned int dcdsize = 0, pos = 0; + void *dcdptr; + + for (i = 0; i < num_entries; i++) + dcdsize += table[i].size; + + dcdptr = xmalloc(dcdsize); + + for (i = 0; i < num_entries; i++) { + u32 *current = dcdptr + pos; + memcpy(current, table[i].data, table[i].size); + *current |= cpu_to_be32(table[i].size << 8); + pos += table[i].size; + } + + return dcdptr; +} + +static struct imx_internal_bbu_handler *__init_handler(const char *name, char *devicefile, + unsigned long flags) +{ + struct imx_internal_bbu_handler *imx_handler; + struct bbu_handler *handler; + + imx_handler = xzalloc(sizeof(*imx_handler)); + handler = &imx_handler->handler; + handler->devicefile = devicefile; + handler->name = name; + handler->flags = flags; + + return imx_handler; +} + +static int __register_handler(struct imx_internal_bbu_handler *imx_handler) +{ + int ret; + + ret = bbu_register_handler(&imx_handler->handler); + if (ret) + free(imx_handler); + + return ret; +} + +/* + * Register a i.MX51 internal boot update handler for MMC/SD + */ +int imx51_bbu_internal_mmc_register_handler(const char *name, char *devicefile, + unsigned long flags, struct imx_dcd_entry *dcd, int dcdsize) +{ + struct imx_internal_bbu_handler *imx_handler; + + imx_handler = __init_handler(name, devicefile, flags); + imx_handler->dcd = dcd; + imx_handler->dcdsize = dcdsize; + imx_handler->flash_header_offset = FLASH_HEADER_OFFSET_MMC; + imx_handler->app_dest = 0x90000000; + imx_handler->flags = IMX_INTERNAL_FLAG_KEEP_DOSPART; + imx_handler->handler.handler = imx_bbu_internal_v1_update; + + return __register_handler(imx_handler); +} + +#define DCD_WR_CMD(len) cpu_to_be32(0xcc << 24 | (((len) & 0xffff) << 8) | 0x04) + +static int imx53_bbu_internal_init_dcd(struct imx_internal_bbu_handler *imx_handler, + void *dcd, int dcdsize) +{ + uint32_t *dcd32 = dcd; + + /* + * The DCD data we have compiled in does not have a DCD_WR_CMD at + * the beginning. Instead it is contained in struct imx_flash_header_v2. + * This is necessary to generate the DCD size at compile time. If + * we are passed such a DCD data here, prepend a DCD_WR_CMD. + */ + if ((*dcd32 & 0xff0000ff) != DCD_WR_CMD(0)) { + __be32 *buf; + + debug("%s: dcd does not have a DCD_WR_CMD. Prepending one\n"); + + buf = xmalloc(dcdsize + sizeof(__be32)); + + *buf = DCD_WR_CMD(dcdsize + sizeof(__be32)); + memcpy(&buf[1], dcd, dcdsize); + + imx_handler->dcd = buf; + imx_handler->dcdsize = dcdsize + sizeof(__be32); + } else { + debug("%s: dcd already has a DCD_WR_CMD. Using original dcd data\n"); + + imx_handler->dcd = dcd; + imx_handler->dcdsize = dcdsize; + } + + return 0; +} + +/* + * Register a i.MX53 internal boot update handler for MMC/SD + */ +int imx53_bbu_internal_mmc_register_handler(const char *name, char *devicefile, + unsigned long flags, struct imx_dcd_v2_entry *dcd, int dcdsize) +{ + struct imx_internal_bbu_handler *imx_handler; + + imx_handler = __init_handler(name, devicefile, flags); + imx53_bbu_internal_init_dcd(imx_handler, dcd, dcdsize); + imx_handler->flash_header_offset = FLASH_HEADER_OFFSET_MMC; + imx_handler->app_dest = 0x70000000; + imx_handler->flags = IMX_INTERNAL_FLAG_KEEP_DOSPART; + imx_handler->handler.handler = imx_bbu_internal_v2_update; + + return __register_handler(imx_handler); +} + +/* + * Register a i.MX53 internal boot update handler for NAND + */ +int imx53_bbu_internal_nand_register_handler(const char *name, + unsigned long flags, struct imx_dcd_v2_entry *dcd, int dcdsize, + int partition_size) +{ + struct imx_internal_bbu_handler *imx_handler; + + imx_handler = __init_handler(name, NULL, flags); + imx53_bbu_internal_init_dcd(imx_handler, dcd, dcdsize); + imx_handler->flash_header_offset = 0x400; + imx_handler->app_dest = 0x70000000; + imx_handler->handler.handler = imx_bbu_internal_v2_update; + imx_handler->flags = IMX_INTERNAL_FLAG_NAND; + imx_handler->handler.devicefile = "/dev/nand0"; + imx_handler->device_size = partition_size; + + return __register_handler(imx_handler); +} diff --git a/arch/arm/mach-imx/imx.c b/arch/arm/mach-imx/imx.c new file mode 100644 index 0000000000..d36f3d9443 --- /dev/null +++ b/arch/arm/mach-imx/imx.c @@ -0,0 +1,31 @@ +/* + * 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 <mach/revision.h> + +static int __imx_silicon_revision = IMX_CHIP_REV_UNKNOWN; + +int imx_silicon_revision(void) +{ + return __imx_silicon_revision; +} + +void imx_set_silicon_revision(const char *soc, int revision) +{ + __imx_silicon_revision = revision; + + printf("detected %s revision %d.%d\n", soc, + (revision >> 4) & 0xf, + revision & 0xf); +} diff --git a/arch/arm/mach-imx/imx1.c b/arch/arm/mach-imx/imx1.c index 790e4535d7..18901ea6d0 100644 --- a/arch/arm/mach-imx/imx1.c +++ b/arch/arm/mach-imx/imx1.c @@ -14,8 +14,34 @@ #include <common.h> #include <init.h> #include <io.h> -#include <mach/imx-regs.h> +#include <mach/imx1-regs.h> #include <mach/weim.h> +#include <mach/iomux-v1.h> +#include <reset_source.h> + +#define MX1_RSR MX1_SCM_BASE_ADDR +#define RSR_EXR (1 << 0) +#define RSR_WDR (1 << 1) + +static void imx1_detect_reset_source(void) +{ + u32 val = readl((void *)MX1_RSR) & 0x3; + + switch (val) { + case RSR_EXR: + set_reset_source(RESET_RST); + return; + case RSR_WDR: + set_reset_source(RESET_WDG); + return; + case 0: + set_reset_source(RESET_POR); + return; + default: + /* else keep the default 'unknown' state */ + return; + } +} void imx1_setup_eimcs(size_t cs, unsigned upper, unsigned lower) { @@ -25,12 +51,16 @@ void imx1_setup_eimcs(size_t cs, unsigned upper, unsigned lower) static int imx1_init(void) { + imx_iomuxv1_init((void *)MX1_GPIO1_BASE_ADDR); + imx1_detect_reset_source(); + add_generic_device("imx1-ccm", 0, NULL, MX1_CCM_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx1-gpt", 0, NULL, MX1_TIM1_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); add_generic_device("imx1-gpio", 0, NULL, MX1_GPIO1_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); add_generic_device("imx1-gpio", 1, NULL, MX1_GPIO2_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); add_generic_device("imx1-gpio", 2, NULL, MX1_GPIO3_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); add_generic_device("imx1-gpio", 3, NULL, MX1_GPIO4_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx1-wdt", 0, NULL, MX1_WDT_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); return 0; } diff --git a/arch/arm/mach-imx/imx21.c b/arch/arm/mach-imx/imx21.c index 7ed0809760..cddf3c088e 100644 --- a/arch/arm/mach-imx/imx21.c +++ b/arch/arm/mach-imx/imx21.c @@ -14,8 +14,9 @@ #include <common.h> #include <init.h> #include <io.h> -#include <mach/imx-regs.h> +#include <mach/imx21-regs.h> #include <mach/weim.h> +#include <mach/iomux-v1.h> void imx21_setup_eimcs(size_t cs, unsigned upper, unsigned lower) { @@ -23,16 +24,10 @@ void imx21_setup_eimcs(size_t cs, unsigned upper, unsigned lower) writel(lower, MX21_EIM_BASE_ADDR + 4 + cs * 8); } -int imx_silicon_revision(void) -{ - // Known values: - // 0x101D101D : mask set ID 0M55B - // 0x201D101D : mask set ID 1M55B or M55B - return CID; -} - static int imx21_init(void) { + imx_iomuxv1_init((void *)MX21_GPIO1_BASE_ADDR); + add_generic_device("imx21-ccm", 0, NULL, MX21_CCM_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); add_generic_device("imx1-gpt", 0, NULL, MX21_GPT1_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); add_generic_device("imx-gpio", 0, NULL, MX21_GPIO1_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); @@ -41,6 +36,7 @@ static int imx21_init(void) add_generic_device("imx-gpio", 3, NULL, MX21_GPIO4_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); add_generic_device("imx-gpio", 4, NULL, MX21_GPIO5_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); add_generic_device("imx-gpio", 5, NULL, MX21_GPIO6_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx21-wdt", 0, NULL, MX21_WDOG_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); return 0; } diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c index 5e6532a8f9..3bd95c146a 100644 --- a/arch/arm/mach-imx/imx25.c +++ b/arch/arm/mach-imx/imx25.c @@ -13,10 +13,11 @@ #include <common.h> #include <init.h> -#include <mach/imx-regs.h> +#include <mach/imx25-regs.h> #include <mach/iim.h> #include <io.h> #include <mach/weim.h> +#include <mach/generic.h> #include <sizes.h> void imx25_setup_weimcs(size_t cs, unsigned upper, unsigned lower, @@ -58,6 +59,12 @@ static struct imx_iim_platform_data imx25_iim_pdata = { static int imx25_init(void) { + uint32_t val; + + val = readl(MX25_CCM_BASE_ADDR + MX25_CCM_RCSR); + imx_25_35_boot_save_loc((val >> MX25_CCM_RCSR_MEM_CTRL_SHIFT) & 0x3, + (val >> MX25_CCM_RCSR_MEM_TYPE_SHIFT) & 0x3); + add_generic_device("imx_iim", 0, NULL, MX25_IIM_BASE_ADDR, SZ_4K, IORESOURCE_MEM, &imx25_iim_pdata); @@ -67,6 +74,7 @@ static int imx25_init(void) add_generic_device("imx31-gpio", 1, NULL, MX25_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 2, NULL, MX25_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 3, NULL, MX25_GPIO4_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx21-wdt", 0, NULL, MX25_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); return 0; } diff --git a/arch/arm/mach-imx/imx27.c b/arch/arm/mach-imx/imx27.c index 8116e6f932..a0a510f5ab 100644 --- a/arch/arm/mach-imx/imx27.c +++ b/arch/arm/mach-imx/imx27.c @@ -12,15 +12,40 @@ */ #include <common.h> -#include <mach/imx-regs.h> +#include <mach/imx27-regs.h> #include <mach/weim.h> +#include <mach/iomux-v1.h> #include <sizes.h> +#include <mach/revision.h> +#include <mach/generic.h> #include <init.h> #include <io.h> -int imx_silicon_revision(void) +static int imx27_silicon_revision(void) { - return CID >> 28; + uint32_t val; + int rev; + + val = readl(MX27_SYSCTRL_BASE_ADDR); + + switch (val >> 28) { + case 0: + rev = IMX_CHIP_REV_1_0; + break; + case 1: + rev = IMX_CHIP_REV_2_0; + break; + case 2: + rev = IMX_CHIP_REV_2_1; + break; + default: + rev = IMX_CHIP_REV_UNKNOWN; + break; + } + + imx_set_silicon_revision("i.MX27", rev); + + return 0; } void imx27_setup_weimcs(size_t cs, unsigned upper, unsigned lower, @@ -73,6 +98,11 @@ static void imx27_init_max(void) static int imx27_init(void) { + imx27_silicon_revision(); + imx_27_boot_save_loc((void *)MX27_SYSCTRL_BASE_ADDR); + + imx_iomuxv1_init((void *)MX27_GPIO1_BASE_ADDR); + add_generic_device("imx_iim", 0, NULL, MX27_IIM_BASE_ADDR, SZ_4K, IORESOURCE_MEM, NULL); @@ -86,6 +116,7 @@ static int imx27_init(void) add_generic_device("imx1-gpio", 3, NULL, MX27_GPIO4_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); add_generic_device("imx1-gpio", 4, NULL, MX27_GPIO5_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); add_generic_device("imx1-gpio", 5, NULL, MX27_GPIO6_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx21-wdt", 0, NULL, MX27_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); return 0; } diff --git a/arch/arm/mach-imx/imx31.c b/arch/arm/mach-imx/imx31.c index 90eee0a209..b2f0724bd1 100644 --- a/arch/arm/mach-imx/imx31.c +++ b/arch/arm/mach-imx/imx31.c @@ -15,7 +15,7 @@ #include <init.h> #include <sizes.h> #include <io.h> -#include <mach/imx-regs.h> +#include <mach/imx31-regs.h> #include <mach/weim.h> void imx31_setup_weimcs(size_t cs, unsigned upper, unsigned lower, @@ -31,11 +31,13 @@ static int imx31_init(void) add_generic_device("imx_iim", 0, NULL, MX31_IIM_BASE_ADDR, SZ_4K, IORESOURCE_MEM, NULL); + add_generic_device("imx31-iomux", 0, NULL, MX31_IOMUXC_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-ccm", 0, NULL, MX31_CCM_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpt", 0, NULL, MX31_GPT1_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); add_generic_device("imx-gpio", 0, NULL, MX31_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx-gpio", 1, NULL, MX31_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx-gpio", 2, NULL, MX31_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx21-wdt", 0, NULL, MX31_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); return 0; } diff --git a/arch/arm/mach-imx/imx35.c b/arch/arm/mach-imx/imx35.c index 722dd4c38c..737eb3a3a8 100644 --- a/arch/arm/mach-imx/imx35.c +++ b/arch/arm/mach-imx/imx35.c @@ -16,8 +16,9 @@ #include <init.h> #include <io.h> #include <mach/weim.h> -#include <mach/imx-regs.h> +#include <mach/imx35-regs.h> #include <mach/iim.h> +#include <mach/revision.h> #include <mach/generic.h> void imx35_setup_weimcs(size_t cs, unsigned upper, unsigned lower, @@ -28,14 +29,14 @@ void imx35_setup_weimcs(size_t cs, unsigned upper, unsigned lower, writel(additional, MX35_WEIM_BASE_ADDR + (cs * 0x10) + 0x8); } -int imx_silicon_revision() +static void imx35_silicon_revision(void) { uint32_t reg; reg = readl(MX35_IIM_BASE_ADDR + IIM_SREV); /* 0×00 = TO 1.0, First silicon */ reg += IMX_CHIP_REV_1_0; - return (reg & 0xFF); + imx_set_silicon_revision("i.MX35", reg & 0xFF); } /* @@ -58,14 +59,24 @@ core_initcall(imx35_l2_fix); static int imx35_init(void) { + uint32_t val; + + imx35_silicon_revision(); + + val = readl(MX35_CCM_BASE_ADDR + MX35_CCM_RCSR); + imx_25_35_boot_save_loc((val >> MX35_CCM_RCSR_MEM_CTRL_SHIFT) & 0x3, + (val >> MX35_CCM_RCSR_MEM_TYPE_SHIFT) & 0x3); + add_generic_device("imx_iim", 0, NULL, MX35_IIM_BASE_ADDR, SZ_4K, IORESOURCE_MEM, NULL); + add_generic_device("imx-iomuxv3", 0, NULL, MX35_IOMUXC_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx35-ccm", 0, NULL, MX35_CCM_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpt", 0, NULL, MX35_GPT1_BASE_ADDR, 0x100, IORESOURCE_MEM, NULL); add_generic_device("imx-gpio", 0, NULL, MX35_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx-gpio", 1, NULL, MX35_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx-gpio", 2, NULL, MX35_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx21-wdt", 0, NULL, MX35_WDOG_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); return 0; } diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c index 8709c43ac2..f5a867be3f 100644 --- a/arch/arm/mach-imx/imx51.c +++ b/arch/arm/mach-imx/imx51.c @@ -17,69 +17,58 @@ #include <environment.h> #include <io.h> #include <mach/imx5.h> -#include <mach/imx-regs.h> +#include <mach/imx51-regs.h> +#include <mach/revision.h> #include <mach/clock-imx51_53.h> +#include <mach/generic.h> #define SI_REV 0x48 -static u32 mx51_silicon_revision; -static char *mx51_rev_string = "unknown"; - -int imx_silicon_revision(void) -{ - return mx51_silicon_revision; -} - -static int query_silicon_revision(void) +static int imx51_silicon_revision(void) { void __iomem *rom = MX51_IROM_BASE_ADDR; + u32 mx51_silicon_revision; u32 rev; rev = readl(rom + SI_REV); switch (rev) { case 0x1: mx51_silicon_revision = IMX_CHIP_REV_1_0; - mx51_rev_string = "1.0"; break; case 0x2: mx51_silicon_revision = IMX_CHIP_REV_1_1; - mx51_rev_string = "1.1"; break; case 0x10: mx51_silicon_revision = IMX_CHIP_REV_2_0; - mx51_rev_string = "2.0"; break; case 0x20: mx51_silicon_revision = IMX_CHIP_REV_3_0; - mx51_rev_string = "3.0"; break; default: mx51_silicon_revision = 0; } - return 0; -} -core_initcall(query_silicon_revision); - -static int imx51_print_silicon_rev(void) -{ - printf("detected i.MX51 rev %s\n", mx51_rev_string); + imx_set_silicon_revision("i.MX51", mx51_silicon_revision); return 0; } -device_initcall(imx51_print_silicon_rev); static int imx51_init(void) { + imx51_silicon_revision(); + imx51_boot_save_loc((void *)MX51_SRC_BASE_ADDR); + add_generic_device("imx_iim", 0, NULL, MX51_IIM_BASE_ADDR, SZ_4K, IORESOURCE_MEM, NULL); + add_generic_device("imx-iomuxv3", 0, NULL, MX51_IOMUXC_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx51-ccm", 0, NULL, MX51_CCM_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpt", 0, NULL, MX51_GPT1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 0, NULL, MX51_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 1, NULL, MX51_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 2, NULL, MX51_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 3, NULL, MX51_GPIO4_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx21-wdt", 0, NULL, MX51_WDOG_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); return 0; } @@ -104,73 +93,6 @@ postcore_initcall(imx51_init); * power up. */ -#define SRC_SBMR 0x4 -#define SBMR_BT_MEM_TYPE_SHIFT 7 -#define SBMR_BT_MEM_CTL_SHIFT 0 -#define SBMR_BMOD_SHIFT 14 - -static int imx51_boot_save_loc(void) -{ - const char *bareboxloc = NULL; - uint32_t reg; - unsigned int ctrl, type; - - /* [CTRL][TYPE] */ - const char *const locations[4][4] = { - { /* CTRL = WEIM */ - "nor", - NULL, - "onenand", - NULL, - }, { /* CTRL == NAND */ - "nand", - "nand", - "nand", - "nand", - }, { /* CTRL == reserved */ - NULL, - NULL, - NULL, - NULL, - }, { /* CTRL == expansion */ - "mmc", - NULL, - "i2c", - "spi", - } - }; - - reg = readl(MX51_SRC_BASE_ADDR + SRC_SBMR); - - switch ((reg >> SBMR_BMOD_SHIFT) & 0x3) { - case 0: - case 2: - /* internal boot */ - ctrl = (reg >> SBMR_BT_MEM_CTL_SHIFT) & 0x3; - type = (reg >> SBMR_BT_MEM_TYPE_SHIFT) & 0x3; - - bareboxloc = locations[ctrl][type]; - break; - case 1: - /* reserved */ - bareboxloc = "unknown"; - break; - case 3: - bareboxloc = "serial"; - break; - - } - - if (bareboxloc) { - setenv("barebox_loc", bareboxloc); - export("barebox_loc"); - } - - return 0; -} - -coredevice_initcall(imx51_boot_save_loc); - #define setup_pll_800(base) imx5_setup_pll((base), 800, (( 8 << 4) + ((1 - 1) << 0)), ( 3 - 1), 1) #define setup_pll_665(base) imx5_setup_pll((base), 665, (( 6 << 4) + ((1 - 1) << 0)), (96 - 1), 89) #define setup_pll_600(base) imx5_setup_pll((base), 600, (( 6 << 4) + ((1 - 1) << 0)), ( 4 - 1), 1) diff --git a/arch/arm/mach-imx/imx53.c b/arch/arm/mach-imx/imx53.c index 88b4274fd5..e424e7d903 100644 --- a/arch/arm/mach-imx/imx53.c +++ b/arch/arm/mach-imx/imx53.c @@ -17,59 +17,48 @@ #include <notifier.h> #include <sizes.h> #include <mach/imx5.h> -#include <mach/imx-regs.h> +#include <mach/imx53-regs.h> +#include <mach/revision.h> #include <mach/clock-imx51_53.h> +#include <mach/generic.h> #define SI_REV 0x48 -static u32 mx53_silicon_revision; -static char *mx53_rev_string = "unknown"; - -int imx_silicon_revision(void) -{ - return mx53_silicon_revision; -} - -static int query_silicon_revision(void) +static int imx53_silicon_revision(void) { void __iomem *rom = MX53_IROM_BASE_ADDR; u32 rev; + u32 mx53_silicon_revision; rev = readl(rom + SI_REV); switch (rev) { case 0x10: mx53_silicon_revision = IMX_CHIP_REV_1_0; - mx53_rev_string = "1.0"; break; case 0x20: mx53_silicon_revision = IMX_CHIP_REV_2_0; - mx53_rev_string = "2.0"; break; case 0x21: mx53_silicon_revision = IMX_CHIP_REV_2_1; - mx53_rev_string = "2.1"; break; default: mx53_silicon_revision = 0; } - return 0; -} -core_initcall(query_silicon_revision); - -static int imx53_print_silicon_rev(void) -{ - printf("detected i.MX53 rev %s\n", mx53_rev_string); + imx_set_silicon_revision("i.MX53", mx53_silicon_revision); return 0; } -device_initcall(imx53_print_silicon_rev); static int imx53_init(void) { + imx53_silicon_revision(); + imx53_boot_save_loc((void *)MX53_SRC_BASE_ADDR); + add_generic_device("imx_iim", 0, NULL, MX53_IIM_BASE_ADDR, SZ_4K, IORESOURCE_MEM, NULL); + add_generic_device("imx-iomuxv3", 0, NULL, MX53_IOMUXC_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx53-ccm", 0, NULL, MX53_CCM_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpt", 0, NULL, 0X53fa0000, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 0, NULL, MX53_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); @@ -79,6 +68,7 @@ static int imx53_init(void) add_generic_device("imx31-gpio", 4, NULL, MX53_GPIO5_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 5, NULL, MX53_GPIO6_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 6, NULL, MX53_GPIO7_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); + add_generic_device("imx21-wdt", 0, NULL, MX53_WDOG1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); return 0; } @@ -203,6 +193,8 @@ void imx53_init_lowlevel(unsigned int cpufreq_mhz) writel(0xffffffff, ccm + MX5_CCM_CCGR6); writel(0xffffffff, ccm + MX53_CCM_CCGR7); - clock_notifier_call_chain(); + if (!IS_ENABLED(__PBL__)) + clock_notifier_call_chain(); + writel(0, ccm + MX5_CCM_CCDR); } diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c index a5ec36471e..c9eec5ab75 100644 --- a/arch/arm/mach-imx/imx6.c +++ b/arch/arm/mach-imx/imx6.c @@ -54,6 +54,7 @@ void imx6_init_lowlevel(void) static int imx6_init(void) { + add_generic_device("imx-iomuxv3", 0, NULL, MX6_IOMUXC_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx6-ccm", 0, NULL, MX6_CCM_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpt", 0, NULL, 0x02098000, 0x1000, IORESOURCE_MEM, NULL); add_generic_device("imx31-gpio", 0, NULL, MX6_GPIO1_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); @@ -63,6 +64,7 @@ static int imx6_init(void) add_generic_device("imx31-gpio", 4, NULL, MX6_GPIO5_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL); 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); return 0; } diff --git a/arch/arm/mach-imx/include/mach/bbu.h b/arch/arm/mach-imx/include/mach/bbu.h new file mode 100644 index 0000000000..f9ec1cc0af --- /dev/null +++ b/arch/arm/mach-imx/include/mach/bbu.h @@ -0,0 +1,51 @@ +#ifndef __MACH_BBU_H +#define __MACH_BBU_H + +#include <bbu.h> + +struct imx_dcd_entry; +struct imx_dcd_v2_entry; + +#ifdef CONFIG_BAREBOX_UPDATE + +int imx51_bbu_internal_mmc_register_handler(const char *name, char *devicefile, + unsigned long flags, struct imx_dcd_entry *, int dcdsize); + +int imx53_bbu_internal_mmc_register_handler(const char *name, char *devicefile, + unsigned long flags, struct imx_dcd_v2_entry *, int dcdsize); + +int imx53_bbu_internal_nand_register_handler(const char *name, + unsigned long flags, struct imx_dcd_v2_entry *, int dcdsize, + int partition_size); + +#else + +static inline int imx51_bbu_internal_mmc_register_handler(const char *name, char *devicefile, + unsigned long flags, struct imx_dcd_entry *dcd, int dcdsize) +{ + return -ENOSYS; +} + +static inline int imx53_bbu_internal_mmc_register_handler(const char *name, char *devicefile, + unsigned long flags, struct imx_dcd_v2_entry *dcd, int dcdsize) +{ + return -ENOSYS; +} + +static inline int imx53_bbu_internal_nand_register_handler(const char *name, + unsigned long flags, struct imx_dcd_v2_entry *dcd, int dcdsize, + int partition_size) +{ + return -ENOSYS; +} + +#endif + +struct dcd_table { + void *data; + unsigned int size; +}; + +void *imx53_bbu_internal_concat_dcd_table(struct dcd_table *table, int num_entries); + +#endif diff --git a/arch/arm/mach-imx/include/mach/devices-imx1.h b/arch/arm/mach-imx/include/mach/devices-imx1.h index c73113cf64..391c1a9c8e 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx1.h +++ b/arch/arm/mach-imx/include/mach/devices-imx1.h @@ -2,10 +2,10 @@ static inline struct device_d *imx1_add_uart0(void) { - return imx_add_uart((void *)MX1_UART1_BASE_ADDR, 0); + return imx_add_uart_imx1((void *)MX1_UART1_BASE_ADDR, 0); } static inline struct device_d *imx1_add_uart1(void) { - return imx_add_uart((void *)MX1_UART2_BASE_ADDR, 1); + return imx_add_uart_imx1((void *)MX1_UART2_BASE_ADDR, 1); } diff --git a/arch/arm/mach-imx/include/mach/devices-imx21.h b/arch/arm/mach-imx/include/mach/devices-imx21.h index 31c5f8c17b..ad7ee5ed02 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx21.h +++ b/arch/arm/mach-imx/include/mach/devices-imx21.h @@ -3,22 +3,22 @@ static inline struct device_d *imx21_add_uart0(void) { - return imx_add_uart((void *)MX21_UART1_BASE_ADDR, 0); + return imx_add_uart_imx21((void *)MX21_UART1_BASE_ADDR, 0); } static inline struct device_d *imx21_add_uart1(void) { - return imx_add_uart((void *)MX21_UART2_BASE_ADDR, 1); + return imx_add_uart_imx21((void *)MX21_UART2_BASE_ADDR, 1); } static inline struct device_d *imx21_add_uart2(void) { - return imx_add_uart((void *)MX21_UART2_BASE_ADDR, 2); + return imx_add_uart_imx21((void *)MX21_UART2_BASE_ADDR, 2); } static inline struct device_d *imx21_add_uart3(void) { - return imx_add_uart((void *)MX21_UART2_BASE_ADDR, 3); + return imx_add_uart_imx21((void *)MX21_UART2_BASE_ADDR, 3); } static inline struct device_d *imx21_add_nand(struct imx_nand_platform_data *pdata) diff --git a/arch/arm/mach-imx/include/mach/devices-imx25.h b/arch/arm/mach-imx/include/mach/devices-imx25.h index 86cda35a43..a655be9564 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx25.h +++ b/arch/arm/mach-imx/include/mach/devices-imx25.h @@ -33,27 +33,27 @@ static inline struct device_d *imx25_add_spi2(struct spi_imx_master *pdata) static inline struct device_d *imx25_add_uart0(void) { - return imx_add_uart((void *)MX25_UART1_BASE_ADDR, 0); + return imx_add_uart_imx21((void *)MX25_UART1_BASE_ADDR, 0); } static inline struct device_d *imx25_add_uart1(void) { - return imx_add_uart((void *)MX25_UART2_BASE_ADDR, 1); + return imx_add_uart_imx21((void *)MX25_UART2_BASE_ADDR, 1); } static inline struct device_d *imx25_add_uart2(void) { - return imx_add_uart((void *)MX25_UART3_BASE_ADDR, 2); + return imx_add_uart_imx21((void *)MX25_UART3_BASE_ADDR, 2); } static inline struct device_d *imx25_add_uart3(void) { - return imx_add_uart((void *)MX25_UART4_BASE_ADDR, 3); + return imx_add_uart_imx21((void *)MX25_UART4_BASE_ADDR, 3); } static inline struct device_d *imx25_add_uart4(void) { - return imx_add_uart((void *)MX25_UART5_BASE_ADDR, 4); + return imx_add_uart_imx21((void *)MX25_UART5_BASE_ADDR, 4); } static inline struct device_d *imx25_add_nand(struct imx_nand_platform_data *pdata) @@ -68,7 +68,7 @@ static inline struct device_d *imx25_add_fb(struct imx_fb_platform_data *pdata) static inline struct device_d *imx25_add_fec(struct fec_platform_data *pdata) { - return imx_add_fec((void *)MX25_FEC_BASE_ADDR, pdata); + return imx_add_fec_imx27((void *)MX25_FEC_BASE_ADDR, pdata); } static inline struct device_d *imx25_add_mmc0(struct esdhc_platform_data *pdata) diff --git a/arch/arm/mach-imx/include/mach/devices-imx27.h b/arch/arm/mach-imx/include/mach/devices-imx27.h index 2799343e59..79da93531d 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx27.h +++ b/arch/arm/mach-imx/include/mach/devices-imx27.h @@ -23,22 +23,22 @@ static inline struct device_d *imx27_add_i2c1(struct i2c_platform_data *pdata) static inline struct device_d *imx27_add_uart0(void) { - return imx_add_uart((void *)MX27_UART1_BASE_ADDR, 0); + return imx_add_uart_imx21((void *)MX27_UART1_BASE_ADDR, 0); } static inline struct device_d *imx27_add_uart1(void) { - return imx_add_uart((void *)MX27_UART2_BASE_ADDR, 1); + return imx_add_uart_imx21((void *)MX27_UART2_BASE_ADDR, 1); } static inline struct device_d *imx27_add_uart2(void) { - return imx_add_uart((void *)MX27_UART3_BASE_ADDR, 2); + return imx_add_uart_imx21((void *)MX27_UART3_BASE_ADDR, 2); } static inline struct device_d *imx27_add_uart3(void) { - return imx_add_uart((void *)MX27_UART4_BASE_ADDR, 3); + return imx_add_uart_imx21((void *)MX27_UART4_BASE_ADDR, 3); } static inline struct device_d *imx27_add_nand(struct imx_nand_platform_data *pdata) @@ -53,7 +53,7 @@ static inline struct device_d *imx27_add_fb(struct imx_fb_platform_data *pdata) static inline struct device_d *imx27_add_fec(struct fec_platform_data *pdata) { - return imx_add_fec((void *)MX27_FEC_BASE_ADDR, pdata); + return imx_add_fec_imx27((void *)MX27_FEC_BASE_ADDR, pdata); } static inline struct device_d *imx27_add_mmc0(void *pdata) diff --git a/arch/arm/mach-imx/include/mach/devices-imx31.h b/arch/arm/mach-imx/include/mach/devices-imx31.h index d45e4e1027..fe719301ad 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx31.h +++ b/arch/arm/mach-imx/include/mach/devices-imx31.h @@ -1,5 +1,5 @@ -#include <mach/imx-regs.h> +#include <mach/imx31-regs.h> #include <mach/devices.h> static inline struct device_d *imx31_add_spi0(struct spi_imx_master *pdata) @@ -19,27 +19,27 @@ static inline struct device_d *imx31_add_spi2(struct spi_imx_master *pdata) static inline struct device_d *imx31_add_uart0(void) { - return imx_add_uart((void *)MX31_UART1_BASE_ADDR, 0); + return imx_add_uart_imx21((void *)MX31_UART1_BASE_ADDR, 0); } static inline struct device_d *imx31_add_uart1(void) { - return imx_add_uart((void *)MX31_UART2_BASE_ADDR, 1); + return imx_add_uart_imx21((void *)MX31_UART2_BASE_ADDR, 1); } static inline struct device_d *imx31_add_uart2(void) { - return imx_add_uart((void *)MX31_UART3_BASE_ADDR, 2); + return imx_add_uart_imx21((void *)MX31_UART3_BASE_ADDR, 2); } static inline struct device_d *imx31_add_uart3(void) { - return imx_add_uart((void *)MX31_UART4_BASE_ADDR, 3); + return imx_add_uart_imx21((void *)MX31_UART4_BASE_ADDR, 3); } static inline struct device_d *imx31_add_uart4(void) { - return imx_add_uart((void *)MX31_UART5_BASE_ADDR, 4); + return imx_add_uart_imx21((void *)MX31_UART5_BASE_ADDR, 4); } static inline struct device_d *imx31_add_nand(struct imx_nand_platform_data *pdata) diff --git a/arch/arm/mach-imx/include/mach/devices-imx35.h b/arch/arm/mach-imx/include/mach/devices-imx35.h index 27c49e7161..912c41872e 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx35.h +++ b/arch/arm/mach-imx/include/mach/devices-imx35.h @@ -28,17 +28,17 @@ static inline struct device_d *imx35_add_spi(struct spi_imx_master *pdata) static inline struct device_d *imx35_add_uart0(void) { - return imx_add_uart((void *)MX35_UART1_BASE_ADDR, 0); + return imx_add_uart_imx21((void *)MX35_UART1_BASE_ADDR, 0); } static inline struct device_d *imx35_add_uart1(void) { - return imx_add_uart((void *)MX35_UART2_BASE_ADDR, 1); + return imx_add_uart_imx21((void *)MX35_UART2_BASE_ADDR, 1); } static inline struct device_d *imx35_add_uart2(void) { - return imx_add_uart((void *)MX35_UART3_BASE_ADDR, 2); + return imx_add_uart_imx21((void *)MX35_UART3_BASE_ADDR, 2); } static inline struct device_d *imx35_add_nand(struct imx_nand_platform_data *pdata) @@ -53,7 +53,7 @@ static inline struct device_d *imx35_add_fb(struct imx_ipu_fb_platform_data *pda static inline struct device_d *imx35_add_fec(struct fec_platform_data *pdata) { - return imx_add_fec((void *)MX35_FEC_BASE_ADDR, pdata); + return imx_add_fec_imx27((void *)MX35_FEC_BASE_ADDR, pdata); } static inline struct device_d *imx35_add_mmc0(struct esdhc_platform_data *pdata) diff --git a/arch/arm/mach-imx/include/mach/devices-imx51.h b/arch/arm/mach-imx/include/mach/devices-imx51.h index 4b35c96e21..8ee3c17478 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx51.h +++ b/arch/arm/mach-imx/include/mach/devices-imx51.h @@ -29,22 +29,22 @@ static inline struct device_d *imx51_add_i2c1(struct i2c_platform_data *pdata) static inline struct device_d *imx51_add_uart0(void) { - return imx_add_uart((void *)MX51_UART1_BASE_ADDR, 0); + return imx_add_uart_imx21((void *)MX51_UART1_BASE_ADDR, 0); } static inline struct device_d *imx51_add_uart1(void) { - return imx_add_uart((void *)MX51_UART2_BASE_ADDR, 1); + return imx_add_uart_imx21((void *)MX51_UART2_BASE_ADDR, 1); } static inline struct device_d *imx51_add_uart2(void) { - return imx_add_uart((void *)MX51_UART3_BASE_ADDR, 2); + return imx_add_uart_imx21((void *)MX51_UART3_BASE_ADDR, 2); } static inline struct device_d *imx51_add_fec(struct fec_platform_data *pdata) { - return imx_add_fec((void *)MX51_MXC_FEC_BASE_ADDR, pdata); + return imx_add_fec_imx27((void *)MX51_MXC_FEC_BASE_ADDR, pdata); } static inline struct device_d *imx51_add_mmc0(struct esdhc_platform_data *pdata) diff --git a/arch/arm/mach-imx/include/mach/devices-imx53.h b/arch/arm/mach-imx/include/mach/devices-imx53.h index 54d7b27be1..5f967eaac2 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx53.h +++ b/arch/arm/mach-imx/include/mach/devices-imx53.h @@ -23,22 +23,22 @@ static inline struct device_d *imx53_add_i2c1(struct i2c_platform_data *pdata) static inline struct device_d *imx53_add_uart0(void) { - return imx_add_uart((void *)MX53_UART1_BASE_ADDR, 0); + return imx_add_uart_imx21((void *)MX53_UART1_BASE_ADDR, 0); } static inline struct device_d *imx53_add_uart1(void) { - return imx_add_uart((void *)MX53_UART2_BASE_ADDR, 1); + return imx_add_uart_imx21((void *)MX53_UART2_BASE_ADDR, 1); } static inline struct device_d *imx53_add_uart2(void) { - return imx_add_uart((void *)MX53_UART3_BASE_ADDR, 2); + return imx_add_uart_imx21((void *)MX53_UART3_BASE_ADDR, 2); } static inline struct device_d *imx53_add_fec(struct fec_platform_data *pdata) { - return imx_add_fec((void *)MX53_FEC_BASE_ADDR, pdata); + return imx_add_fec_imx27((void *)MX53_FEC_BASE_ADDR, pdata); } static inline struct device_d *imx53_add_mmc0(struct esdhc_platform_data *pdata) diff --git a/arch/arm/mach-imx/include/mach/devices-imx6.h b/arch/arm/mach-imx/include/mach/devices-imx6.h index c73e4888ed..f8282e7fca 100644 --- a/arch/arm/mach-imx/include/mach/devices-imx6.h +++ b/arch/arm/mach-imx/include/mach/devices-imx6.h @@ -2,22 +2,22 @@ static inline struct device_d *imx6_add_uart0(void) { - return imx_add_uart((void *)MX6_UART1_BASE_ADDR, 0); + return imx_add_uart_imx21((void *)MX6_UART1_BASE_ADDR, 0); } static inline struct device_d *imx6_add_uart1(void) { - return imx_add_uart((void *)MX6_UART2_BASE_ADDR, 1); + return imx_add_uart_imx21((void *)MX6_UART2_BASE_ADDR, 1); } static inline struct device_d *imx6_add_uart2(void) { - return imx_add_uart((void *)MX6_UART3_BASE_ADDR, 2); + return imx_add_uart_imx21((void *)MX6_UART3_BASE_ADDR, 2); } static inline struct device_d *imx6_add_uart3(void) { - return imx_add_uart((void *)MX6_UART4_BASE_ADDR, 3); + return imx_add_uart_imx21((void *)MX6_UART4_BASE_ADDR, 3); } static inline struct device_d *imx6_add_mmc0(struct esdhc_platform_data *pdata) @@ -42,7 +42,7 @@ static inline struct device_d *imx6_add_mmc3(struct esdhc_platform_data *pdata) static inline struct device_d *imx6_add_fec(struct fec_platform_data *pdata) { - return imx_add_fec((void *)MX6_ENET_BASE_ADDR, pdata); + return imx_add_fec_imx6((void *)MX6_ENET_BASE_ADDR, pdata); } static inline struct device_d *imx6_add_spi0(struct spi_imx_master *pdata) diff --git a/arch/arm/mach-imx/include/mach/devices.h b/arch/arm/mach-imx/include/mach/devices.h index da9164616e..f7824f5406 100644 --- a/arch/arm/mach-imx/include/mach/devices.h +++ b/arch/arm/mach-imx/include/mach/devices.h @@ -8,10 +8,12 @@ #include <mach/imx-ipu-fb.h> #include <mach/esdhc.h> -struct device_d *imx_add_fec(void *base, struct fec_platform_data *pdata); +struct device_d *imx_add_fec_imx27(void *base, struct fec_platform_data *pdata); +struct device_d *imx_add_fec_imx6(void *base, struct fec_platform_data *pdata); struct device_d *imx_add_spi(void *base, int id, struct spi_imx_master *pdata); struct device_d *imx_add_i2c(void *base, int id, struct i2c_platform_data *pdata); -struct device_d *imx_add_uart(void *base, int id); +struct device_d *imx_add_uart_imx1(void *base, int id); +struct device_d *imx_add_uart_imx21(void *base, int id); struct device_d *imx_add_nand(void *base, struct imx_nand_platform_data *pdata); struct device_d *imx_add_fb(void *base, struct imx_fb_platform_data *pdata); struct device_d *imx_add_ipufb(void *base, struct imx_ipu_fb_platform_data *pdata); diff --git a/arch/arm/mach-imx/include/mach/esdctl.h b/arch/arm/mach-imx/include/mach/esdctl.h index 10c8b9bd8e..8124c870e9 100644 --- a/arch/arm/mach-imx/include/mach/esdctl.h +++ b/arch/arm/mach-imx/include/mach/esdctl.h @@ -1,10 +1,10 @@ /* SDRAM Controller registers */ -#define ESDCTL0 (IMX_ESD_BASE + 0x00) /* Enhanced SDRAM Control Register 0 */ -#define ESDCFG0 (IMX_ESD_BASE + 0x04) /* Enhanced SDRAM Configuration Register 0 */ -#define ESDCTL1 (IMX_ESD_BASE + 0x08) /* Enhanced SDRAM Control Register 1 */ -#define ESDCFG1 (IMX_ESD_BASE + 0x0C) /* Enhanced SDRAM Configuration Register 1 */ -#define ESDMISC (IMX_ESD_BASE + 0x10) /* Enhanced SDRAM Miscellanious Register */ +#define IMX_ESDCTL0 0x00 /* Enhanced SDRAM Control Register 0 */ +#define IMX_ESDCFG0 0x04 /* Enhanced SDRAM Configuration Register 0 */ +#define IMX_ESDCTL1 0x08 /* Enhanced SDRAM Control Register 1 */ +#define IMX_ESDCFG1 0x0C /* Enhanced SDRAM Configuration Register 1 */ +#define IMX_ESDMISC 0x10 /* Enhanced SDRAM Miscellanious Register */ #define ESDCTL0_SDE (1 << 31) #define ESDCTL0_SMODE_NORMAL (0 << 28) diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h index 99f301205c..39bb7e351e 100644 --- a/arch/arm/mach-imx/include/mach/generic.h +++ b/arch/arm/mach-imx/include/mach/generic.h @@ -1,10 +1,29 @@ -int imx_silicon_revision(void); -#define IMX27_CHIP_REVISION_1_0 0 -#define IMX27_CHIP_REVISION_2_0 1 - u64 imx_uid(void); +enum imx_bootsource { + bootsource_unknown, + bootsource_nand, + bootsource_nor, + bootsource_mmc, + bootsource_i2c, + bootsource_spi, + bootsource_serial, + bootsource_onenand, + bootsource_hd, +}; + +enum imx_bootsource imx_bootsource(void); +void imx_set_bootsource(enum imx_bootsource src); + +int imx_25_35_boot_save_loc(unsigned int ctrl, unsigned int type); +void imx_27_boot_save_loc(void __iomem *sysctrl_base); +int imx51_boot_save_loc(void __iomem *src_base); +int imx53_boot_save_loc(void __iomem *src_base); + +/* There's a off-by-one betweem the gpio bank number and the gpiochip */ +/* range e.g. GPIO_1_5 is gpio 5 under linux */ +#define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr)) #ifdef CONFIG_ARCH_IMX1 #define cpu_is_mx1() (1) diff --git a/arch/arm/mach-imx/include/mach/gpio.h b/arch/arm/mach-imx/include/mach/gpio.h index 0ebc3f939f..489ae2cf09 100644 --- a/arch/arm/mach-imx/include/mach/gpio.h +++ b/arch/arm/mach-imx/include/mach/gpio.h @@ -1,11 +1,8 @@ #ifndef __ASM_ARCH_GPIO_H #define __ASM_ARCH_GPIO_H +#include <asm-generic/gpio.h> + void imx_gpio_mode(int gpio_mode); -void gpio_set_value(unsigned gpio, int value); -int gpio_get_value(unsigned gpio); -int gpio_direction_output(unsigned gpio, int value); -int gpio_direction_input(unsigned gpio); #endif /* __ASM_ARCH_GPIO_H */ - diff --git a/arch/arm/mach-imx/include/mach/imx-flash-header.h b/arch/arm/mach-imx/include/mach/imx-flash-header.h index a51d4736fa..9a351ad74a 100644 --- a/arch/arm/mach-imx/include/mach/imx-flash-header.h +++ b/arch/arm/mach-imx/include/mach/imx-flash-header.h @@ -120,7 +120,9 @@ struct imx_dcd_command { struct imx_dcd { struct imx_ivt_header header; +#ifndef IMX_INTERNAL_NAND_BBU struct imx_dcd_command command; +#endif }; struct imx_boot_data { @@ -144,4 +146,37 @@ struct imx_flash_header_v2 { struct imx_dcd dcd; }; +/* + * A variant of the standard barebox header in the i.MX FCB + * format. Needed for i.MX53 NAND boot + */ +static inline void barebox_arm_imx_fcb_head(void) +{ + __asm__ __volatile__ ( + ".arm\n" + " b 1f\n" + ".word 0x20424346\n" /* FCB */ + ".word 0x1\n" +#ifdef CONFIG_THUMB2_BAREBOX + "1: adr r9, 1f + 1\n" + " bx r9\n" + ".thumb\n" + "1:\n" + "bl reset\n" +#else + "1: b reset\n" + ".word 0x0\n" + ".word 0x0\n" +#endif + ".word 0x0\n" + ".word 0x0\n" + + ".asciz \"barebox\"\n" + ".word _text\n" /* text base. If copied there, + * barebox can skip relocation + */ + ".word _barebox_image_size\n" /* image size to copy */ + ); +} + #endif /* __MACH_FLASH_HEADER_H */ diff --git a/arch/arm/mach-imx/include/mach/imx-regs.h b/arch/arm/mach-imx/include/mach/imx-regs.h deleted file mode 100644 index 235bac3b82..0000000000 --- a/arch/arm/mach-imx/include/mach/imx-regs.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * - * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> - * - * 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. - * - */ - -#ifndef _IMX_REGS_H -#define _IMX_REGS_H - -/* ------------------------------------------------------------------------ - * Motorola IMX system registers - * ------------------------------------------------------------------------ - */ - -# ifndef __ASSEMBLY__ -# define __REG(x) (*((volatile u32 *)(x))) -# define __REG16(x) (*(volatile u16 *)(x)) -# define __REG2(x,y) (*(volatile u32 *)((u32)&__REG(x) + (y))) -# else -# define __REG(x) (x) -# define __REG16(x) (x) -# define __REG2(x,y) ((x)+(y)) -#endif - -#ifdef CONFIG_ARCH_IMX1 -# include <mach/imx1-regs.h> -#elif defined CONFIG_ARCH_IMX21 -# include <mach/imx21-regs.h> -#elif defined CONFIG_ARCH_IMX27 -# include <mach/imx27-regs.h> -#elif defined CONFIG_ARCH_IMX31 -# include <mach/imx31-regs.h> -#elif defined CONFIG_ARCH_IMX35 -# include <mach/imx35-regs.h> -#elif defined CONFIG_ARCH_IMX25 -# include <mach/imx25-regs.h> -#elif defined CONFIG_ARCH_IMX51 -# include <mach/imx51-regs.h> -#elif defined CONFIG_ARCH_IMX53 -# include <mach/imx53-regs.h> -#elif defined CONFIG_ARCH_IMX6 -# include <mach/imx6-regs.h> -#else -# error "unknown i.MX soc type" -#endif - -/* There's a off-by-one betweem the gpio bank number and the gpiochip */ -/* range e.g. GPIO_1_5 is gpio 5 under linux */ -#define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr)) - -#define GPIO_PIN_MASK 0x1f - -#define GPIO_PORT_SHIFT 5 -#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT) - -#define GPIO_PORTA (0 << GPIO_PORT_SHIFT) -#define GPIO_PORTB (1 << GPIO_PORT_SHIFT) -#define GPIO_PORTC (2 << GPIO_PORT_SHIFT) -#define GPIO_PORTD (3 << GPIO_PORT_SHIFT) -#define GPIO_PORTE (4 << GPIO_PORT_SHIFT) -#define GPIO_PORTF (5 << GPIO_PORT_SHIFT) - -#define GPIO_OUT (1 << 8) -#define GPIO_IN (0 << 8) -#define GPIO_PUEN (1 << 9) - -#define GPIO_PF (1 << 10) -#define GPIO_AF (1 << 11) - -#define GPIO_OCR_SHIFT 12 -#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT) -#define GPIO_AIN (0 << GPIO_OCR_SHIFT) -#define GPIO_BIN (1 << GPIO_OCR_SHIFT) -#define GPIO_CIN (2 << GPIO_OCR_SHIFT) -#define GPIO_GPIO (3 << GPIO_OCR_SHIFT) - -#define GPIO_AOUT_SHIFT 14 -#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT) - -#define GPIO_BOUT_SHIFT 16 -#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT) - -#define GPIO_GIUS (1<<16) - -/* silicon revisions */ -#define IMX_CHIP_REV_1_0 0x10 -#define IMX_CHIP_REV_1_1 0x11 -#define IMX_CHIP_REV_1_2 0x12 -#define IMX_CHIP_REV_1_3 0x13 -#define IMX_CHIP_REV_2_0 0x20 -#define IMX_CHIP_REV_2_1 0x21 -#define IMX_CHIP_REV_2_2 0x22 -#define IMX_CHIP_REV_2_3 0x23 -#define IMX_CHIP_REV_3_0 0x30 -#define IMX_CHIP_REV_3_1 0x31 -#define IMX_CHIP_REV_3_2 0x32 - -#endif /* _IMX_REGS_H */ diff --git a/arch/arm/mach-imx/include/mach/imx1-regs.h b/arch/arm/mach-imx/include/mach/imx1-regs.h index cb60c84d31..df6ede5b24 100644 --- a/arch/arm/mach-imx/include/mach/imx1-regs.h +++ b/arch/arm/mach-imx/include/mach/imx1-regs.h @@ -59,161 +59,25 @@ #define MX1_AVIC_BASE_ADDR (0x23000 + MX1_IO_BASE_ADDR) #define MX1_CSI_BASE_ADDR (0x24000 + MX1_IO_BASE_ADDR) -/* FIXME: get rid of these */ -#define IMX_TIM1_BASE MX1_CCM_BASE_ADDR -#define IMX_WDT_BASE MX1_WDT_BASE_ADDR -#define IMX_GPIO_BASE MX1_GPIO_BASE_ADDR - -/* SYSCTRL Registers */ -#define SIDR __REG(MX1_SCM_BASE_ADDR + 0x4) /* Silicon ID Register */ -#define FMCR __REG(MX1_SCM_BASE_ADDR + 0x8) /* Function Multiplex Control Register */ -#define GPCR __REG(MX1_SCM_BASE_ADDR + 0xC) /* Function Multiplex Control Register */ - -/* SDRAM controller registers */ - -#define SDCTL0 __REG(MX1_SDRAMC_BASE_ADDR) /* SDRAM 0 Control Register */ -#define SDCTL1 __REG(MX1_SDRAMC_BASE_ADDR + 0x4) /* SDRAM 1 Control Register */ -#define SDMISC __REG(MX1_SDRAMC_BASE_ADDR + 0x14) /* Miscellaneous Register */ -#define SDRST __REG(MX1_SDRAMC_BASE_ADDR + 0x18) /* SDRAM Reset Register */ - -/* PLL registers */ -#define CSCR __REG(MX1_CCM_BASE_ADDR) /* Clock Source Control Register */ -#define MPCTL0 __REG(MX1_CCM_BASE_ADDR + 0x4) /* MCU PLL Control Register 0 */ -#define MPCTL1 __REG(MX1_CCM_BASE_ADDR + 0x8) /* MCU PLL and System Clock Register 1 */ -#define SPCTL0 __REG(MX1_CCM_BASE_ADDR + 0xc) /* System PLL Control Register 0 */ -#define SPCTL1 __REG(MX1_CCM_BASE_ADDR + 0x10) /* System PLL Control Register 1 */ -#define PCDR __REG(MX1_CCM_BASE_ADDR + 0x20) /* Peripheral Clock Divider Register */ - -#define CSCR_MPLL_RESTART (1<<21) - -/* assignements for GPIO alternate/primary functions */ - -/* FIXME: This list is not completed. The correct directions are - * missing on some (many) pins - */ -#define PA0_PF_A24 ( GPIO_PORTA | GPIO_PF | 0 ) -#define PA0_AIN_SPI2_CLK ( GPIO_PORTA | GPIO_OUT | GPIO_AIN | 0 ) -#define PA0_AF_ETMTRACESYNC ( GPIO_PORTA | GPIO_AF | 0 ) -#define PA1_AOUT_SPI2_RXD ( GPIO_PORTA | GPIO_IN | GPIO_AOUT | 1 ) -#define PA1_PF_TIN ( GPIO_PORTA | GPIO_PF | 1 ) -#define PA2_PF_PWM0 ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 2 ) -#define PA3_PF_CSI_MCLK ( GPIO_PORTA | GPIO_PF | 3 ) -#define PA4_PF_CSI_D0 ( GPIO_PORTA | GPIO_PF | 4 ) -#define PA5_PF_CSI_D1 ( GPIO_PORTA | GPIO_PF | 5 ) -#define PA6_PF_CSI_D2 ( GPIO_PORTA | GPIO_PF | 6 ) -#define PA7_PF_CSI_D3 ( GPIO_PORTA | GPIO_PF | 7 ) -#define PA8_PF_CSI_D4 ( GPIO_PORTA | GPIO_PF | 8 ) -#define PA9_PF_CSI_D5 ( GPIO_PORTA | GPIO_PF | 9 ) -#define PA10_PF_CSI_D6 ( GPIO_PORTA | GPIO_PF | 10 ) -#define PA11_PF_CSI_D7 ( GPIO_PORTA | GPIO_PF | 11 ) -#define PA12_PF_CSI_VSYNC ( GPIO_PORTA | GPIO_PF | 12 ) -#define PA13_PF_CSI_HSYNC ( GPIO_PORTA | GPIO_PF | 13 ) -#define PA14_PF_CSI_PIXCLK ( GPIO_PORTA | GPIO_PF | 14 ) -#define PA15_PF_I2C_SDA ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 15 ) -#define PA16_PF_I2C_SCL ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 16 ) -#define PA17_AF_ETMTRACEPKT4 ( GPIO_PORTA | GPIO_AF | 17 ) -#define PA17_AIN_SPI2_SS ( GPIO_PORTA | GPIO_AIN | 17 ) -#define PA18_AF_ETMTRACEPKT5 ( GPIO_PORTA | GPIO_AF | 18 ) -#define PA19_AF_ETMTRACEPKT6 ( GPIO_PORTA | GPIO_AF | 19 ) -#define PA20_AF_ETMTRACEPKT7 ( GPIO_PORTA | GPIO_AF | 20 ) -#define PA21_PF_A0 ( GPIO_PORTA | GPIO_PF | 21 ) -#define PA22_PF_CS4 ( GPIO_PORTA | GPIO_PF | 22 ) -#define PA23_PF_CS5 ( GPIO_PORTA | GPIO_PF | 23 ) -#define PA24_PF_A16 ( GPIO_PORTA | GPIO_PF | 24 ) -#define PA24_AF_ETMTRACEPKT0 ( GPIO_PORTA | GPIO_AF | 24 ) -#define PA25_PF_A17 ( GPIO_PORTA | GPIO_PF | 25 ) -#define PA25_AF_ETMTRACEPKT1 ( GPIO_PORTA | GPIO_AF | 25 ) -#define PA26_PF_A18 ( GPIO_PORTA | GPIO_PF | 26 ) -#define PA26_AF_ETMTRACEPKT2 ( GPIO_PORTA | GPIO_AF | 26 ) -#define PA27_PF_A19 ( GPIO_PORTA | GPIO_PF | 27 ) -#define PA27_AF_ETMTRACEPKT3 ( GPIO_PORTA | GPIO_AF | 27 ) -#define PA28_PF_A20 ( GPIO_PORTA | GPIO_PF | 28 ) -#define PA28_AF_ETMPIPESTAT0 ( GPIO_PORTA | GPIO_AF | 28 ) -#define PA29_PF_A21 ( GPIO_PORTA | GPIO_PF | 29 ) -#define PA29_AF_ETMPIPESTAT1 ( GPIO_PORTA | GPIO_AF | 29 ) -#define PA30_PF_A22 ( GPIO_PORTA | GPIO_PF | 30 ) -#define PA30_AF_ETMPIPESTAT2 ( GPIO_PORTA | GPIO_AF | 30 ) -#define PA31_PF_A23 ( GPIO_PORTA | GPIO_PF | 31 ) -#define PA31_AF_ETMTRACECLK ( GPIO_PORTA | GPIO_AF | 31 ) -#define PB8_PF_SD_DAT0 ( GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8 ) -#define PB8_AF_MS_PIO ( GPIO_PORTB | GPIO_AF | 8 ) -#define PB9_PF_SD_DAT1 ( GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9 ) -#define PB9_AF_MS_PI1 ( GPIO_PORTB | GPIO_AF | 9 ) -#define PB10_PF_SD_DAT2 ( GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10 ) -#define PB10_AF_MS_SCLKI ( GPIO_PORTB | GPIO_AF | 10 ) -#define PB11_PF_SD_DAT3 ( GPIO_PORTB | GPIO_PF | GPIO_PUEN | 11 ) -#define PB11_AF_MS_SDIO ( GPIO_PORTB | GPIO_AF | 11 ) -#define PB12_PF_SD_CLK ( GPIO_PORTB | GPIO_PF | GPIO_OUT | 12 ) -#define PB12_AF_MS_SCLK0 ( GPIO_PORTB | GPIO_AF | 12 ) -#define PB13_PF_SD_CMD ( GPIO_PORTB | GPIO_PF | GPIO_OUT | GPIO_PUEN | 13 ) -#define PB13_AF_MS_BS ( GPIO_PORTB | GPIO_AF | 13 ) -#define PB14_AF_SSI_RXFS ( GPIO_PORTB | GPIO_AF | 14 ) -#define PB15_AF_SSI_RXCLK ( GPIO_PORTB | GPIO_AF | 15 ) -#define PB16_AF_SSI_RXDAT ( GPIO_PORTB | GPIO_IN | GPIO_AF | 16 ) -#define PB17_AF_SSI_TXDAT ( GPIO_PORTB | GPIO_OUT | GPIO_AF | 17 ) -#define PB18_AF_SSI_TXFS ( GPIO_PORTB | GPIO_AF | 18 ) -#define PB19_AF_SSI_TXCLK ( GPIO_PORTB | GPIO_AF | 19 ) -#define PB20_PF_USBD_AFE ( GPIO_PORTB | GPIO_PF | 20 ) -#define PB21_PF_USBD_OE ( GPIO_PORTB | GPIO_PF | 21 ) -#define PB22_PFUSBD_RCV ( GPIO_PORTB | GPIO_PF | 22 ) -#define PB23_PF_USBD_SUSPND ( GPIO_PORTB | GPIO_PF | 23 ) -#define PB24_PF_USBD_VP ( GPIO_PORTB | GPIO_PF | 24 ) -#define PB25_PF_USBD_VM ( GPIO_PORTB | GPIO_PF | 25 ) -#define PB26_PF_USBD_VPO ( GPIO_PORTB | GPIO_PF | 26 ) -#define PB27_PF_USBD_VMO ( GPIO_PORTB | GPIO_PF | 27 ) -#define PB28_PF_UART2_CTS ( GPIO_PORTB | GPIO_OUT | GPIO_PF | 28 ) -#define PB29_PF_UART2_RTS ( GPIO_PORTB | GPIO_IN | GPIO_PF | 29 ) -#define PB30_PF_UART2_TXD ( GPIO_PORTB | GPIO_OUT | GPIO_PF | 30 ) -#define PB31_PF_UART2_RXD ( GPIO_PORTB | GPIO_IN | GPIO_PF | 31 ) -#define PC3_PF_SSI_RXFS ( GPIO_PORTC | GPIO_PF | 3 ) -#define PC4_PF_SSI_RXCLK ( GPIO_PORTC | GPIO_PF | 4 ) -#define PC5_PF_SSI_RXDAT ( GPIO_PORTC | GPIO_IN | GPIO_PF | 5 ) -#define PC6_PF_SSI_TXDAT ( GPIO_PORTC | GPIO_OUT | GPIO_PF | 6 ) -#define PC7_PF_SSI_TXFS ( GPIO_PORTC | GPIO_PF | 7 ) -#define PC8_PF_SSI_TXCLK ( GPIO_PORTC | GPIO_PF | 8 ) -#define PC9_PF_UART1_CTS ( GPIO_PORTC | GPIO_OUT | GPIO_PF | 9 ) -#define PC10_PF_UART1_RTS ( GPIO_PORTC | GPIO_IN | GPIO_PF | 10 ) -#define PC11_PF_UART1_TXD ( GPIO_PORTC | GPIO_OUT | GPIO_PF | 11 ) -#define PC12_PF_UART1_RXD ( GPIO_PORTC | GPIO_IN | GPIO_PF | 12 ) -#define PC13_PF_SPI1_SPI_RDY ( GPIO_PORTC | GPIO_PF | 13 ) -#define PC14_PF_SPI1_SCLK ( GPIO_PORTC | GPIO_PF | 14 ) -#define PC15_PF_SPI1_SS ( GPIO_PORTC | GPIO_PF | 15 ) -#define PC16_PF_SPI1_MISO ( GPIO_PORTC | GPIO_PF | 16 ) -#define PC17_PF_SPI1_MOSI ( GPIO_PORTC | GPIO_PF | 17 ) -#define PD6_PF_LSCLK ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 6 ) -#define PD7_PF_REV ( GPIO_PORTD | GPIO_PF | 7 ) -#define PD7_AF_UART2_DTR ( GPIO_PORTD | GPIO_IN | GPIO_AF | 7 ) -#define PD7_AIN_SPI2_SCLK ( GPIO_PORTD | GPIO_AIN | 7 ) -#define PD8_PF_CLS ( GPIO_PORTD | GPIO_PF | 8 ) -#define PD8_AF_UART2_DCD ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 8 ) -#define PD8_AIN_SPI2_SS ( GPIO_PORTD | GPIO_AIN | 8 ) -#define PD9_PF_PS ( GPIO_PORTD | GPIO_PF | 9 ) -#define PD9_AF_UART2_RI ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 9 ) -#define PD9_AOUT_SPI2_RXD ( GPIO_PORTD | GPIO_IN | GPIO_AOUT | 9 ) -#define PD10_PF_SPL_SPR ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 10 ) -#define PD10_AF_UART2_DSR ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 10 ) -#define PD10_AIN_SPI2_TXD ( GPIO_PORTD | GPIO_OUT | GPIO_AIN | 10 ) -#define PD11_PF_CONTRAST ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 11 ) -#define PD12_PF_ACD_OE ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 12 ) -#define PD13_PF_LP_HSYNC ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 13 ) -#define PD14_PF_FLM_VSYNC ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 14 ) -#define PD15_PF_LD0 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 15 ) -#define PD16_PF_LD1 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 16 ) -#define PD17_PF_LD2 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 17 ) -#define PD18_PF_LD3 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 18 ) -#define PD19_PF_LD4 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 19 ) -#define PD20_PF_LD5 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 20 ) -#define PD21_PF_LD6 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 21 ) -#define PD22_PF_LD7 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 22 ) -#define PD23_PF_LD8 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 23 ) -#define PD24_PF_LD9 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 24 ) -#define PD25_PF_LD10 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 25 ) -#define PD26_PF_LD11 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 26 ) -#define PD27_PF_LD12 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 27 ) -#define PD28_PF_LD13 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 28 ) -#define PD29_PF_LD14 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 29 ) -#define PD30_PF_LD15 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 30 ) -#define PD31_PF_TMR2OUT ( GPIO_PORTD | GPIO_PF | 31 ) -#define PD31_BIN_SPI2_TXD ( GPIO_PORTD | GPIO_BIN | 31 ) +/* SYSCTRL Registers (base MX1_SCM_BASE_ADDR) */ +#define MX1_SIDR 0x4 /* Silicon ID Register */ +#define MX1_FMCR 0x8 /* Function Multiplex Control Register */ +#define MX1_GPCR 0xC /* Function Multiplex Control Register */ + +/* SDRAM controller registers (base MX1_SDRAMC_BASE_ADDR) */ +#define MX1_SDCTL0 0x0 /* SDRAM 0 Control Register */ +#define MX1_SDCTL1 0x4 /* SDRAM 1 Control Register */ +#define MX1_SDMISC 0x14 /* Miscellaneous Register */ +#define MX1_SDRST 0x18 /* SDRAM Reset Register */ + +/* PLL registers (base MX1_CCM_BASE_ADDR) */ +#define MX1_CSCR 0x0 /* Clock Source Control Register */ +#define MX1_MPCTL0 0x4 /* MCU PLL Control Register 0 */ +#define MX1_MPCTL1 0x8 /* MCU PLL and System Clock Register 1 */ +#define MX1_SPCTL0 0xc /* System PLL Control Register 0 */ +#define MX1_SPCTL1 0x10 /* System PLL Control Register 1 */ +#define MX1_PCDR 0x20 /* Peripheral Clock Divider Register */ + +#define MX1_CSCR_MPLL_RESTART (1<<21) #endif /* _IMX1_REGS_H */ diff --git a/arch/arm/mach-imx/include/mach/imx21-regs.h b/arch/arm/mach-imx/include/mach/imx21-regs.h index 9952b8bd1f..1c4b5507d3 100644 --- a/arch/arm/mach-imx/include/mach/imx21-regs.h +++ b/arch/arm/mach-imx/include/mach/imx21-regs.h @@ -71,76 +71,70 @@ #define MX21_IRAM_BASE_ADDR 0xffffe800 /* internal ram */ -/* FIXME: Get rid of these */ -#define IMX_GPIO_BASE MX21_GPIO_BASE_ADDR -#define IMX_TIM1_BASE MX21_GPT1_BASE_ADDR -#define IMX_WDT_BASE MX21_WDOG_BASE_ADDR -#define IMX_SYSTEM_CTL_BASE MX21_SYSCTRL_BASE_ADDR - -/* AIPI */ -#define AIPI1_PSR0 __REG(MX21_AIPI_BASE_ADDR + 0x00) -#define AIPI1_PSR1 __REG(MX21_AIPI_BASE_ADDR + 0x04) -#define AIPI2_PSR0 __REG(MX21_AIPI_BASE_ADDR + 0x20000 + 0x00) -#define AIPI2_PSR1 __REG(MX21_AIPI_BASE_ADDR + 0x20000 + 0x04) - -/* System Control */ -#define SUID0 __REG(MX21_SYSCTRL_BASE_ADDR + 0x4) /* Silicon ID Register (12 bytes) */ -#define SUID1 __REG(MX21_SYSCTRL_BASE_ADDR + 0x8) /* Silicon ID Register (12 bytes) */ -#define CID __REG(MX21_SYSCTRL_BASE_ADDR + 0xC) /* Silicon ID Register (12 bytes) */ -#define FMCR __REG(MX21_SYSCTRL_BASE_ADDR + 0x14) /* Function Multeplexing Control Register */ -#define GPCR __REG(MX21_SYSCTRL_BASE_ADDR + 0x18) /* Global Peripheral Control Register */ -#define WBCR __REG(MX21_SYSCTRL_BASE_ADDR + 0x1C) /* Well Bias Control Register */ -#define DSCR(x) __REG(MX21_SYSCTRL_BASE_ADDR + 0x1C + ((x) << 2)) /* Driving Strength Control Register 1 - 13 */ - -#define GPCR_BOOT_SHIFT 16 -#define GPCR_BOOT_MASK (0xf << GPCR_BOOT_SHIFT) -#define GPCR_BOOT_UART_USB 0 -#define GPCR_BOOT_8BIT_NAND_2k 2 -#define GPCR_BOOT_16BIT_NAND_2k 3 -#define GPCR_BOOT_16BIT_NAND_512 4 -#define GPCR_BOOT_16BIT_CS0 5 -#define GPCR_BOOT_32BIT_CS0 6 -#define GPCR_BOOT_8BIT_NAND_512 7 - -/* SDRAM Controller registers bitfields */ -#define SDCTL0 __REG(MX21_X_MEMC_BASE_ADDR + 0x00) /* SDRAM 0 Control Register */ -#define SDCTL1 __REG(MX21_X_MEMC_BASE_ADDR + 0x04) /* SDRAM 0 Control Register */ -#define SDRST __REG(MX21_X_MEMC_BASE_ADDR + 0x18) /* SDRAM Reset Register */ -#define SDMISC __REG(MX21_X_MEMC_BASE_ADDR + 0x14) /* SDRAM Miscellaneous Register */ - -/* PLL registers */ -#define CSCR __REG(MX21_CCM_BASE_ADDR + 0x00) /* Clock Source Control Register */ -#define MPCTL0 __REG(MX21_CCM_BASE_ADDR + 0x04) /* MCU PLL Control Register 0 */ -#define MPCTL1 __REG(MX21_CCM_BASE_ADDR + 0x08) /* MCU PLL Control Register 1 */ -#define SPCTL0 __REG(MX21_CCM_BASE_ADDR + 0x0c) /* System PLL Control Register 0 */ -#define SPCTL1 __REG(MX21_CCM_BASE_ADDR + 0x10) /* System PLL Control Register 1 */ -#define OSC26MCTL __REG(MX21_CCM_BASE_ADDR + 0x14) /* Oscillator 26M Register */ -#define PCDR0 __REG(MX21_CCM_BASE_ADDR + 0x18) /* Peripheral Clock Divider Register 0 */ -#define PCDR1 __REG(MX21_CCM_BASE_ADDR + 0x1c) /* Peripheral Clock Divider Register 1 */ -#define PCCR0 __REG(MX21_CCM_BASE_ADDR + 0x20) /* Peripheral Clock Control Register 0 */ -#define PCCR1 __REG(MX21_CCM_BASE_ADDR + 0x24) /* Peripheral Clock Control Register 1 */ -#define CCSR __REG(MX21_CCM_BASE_ADDR + 0x28) /* Clock Control Status Register */ - -#define CSCR_MPEN (1 << 0) -#define CSCR_SPEN (1 << 1) -#define CSCR_FPM_EN (1 << 2) -#define CSCR_OSC26M_DIS (1 << 3) -#define CSCR_OSC26M_DIV1P5 (1 << 4) -#define CSCR_MCU_SEL (1 << 16) -#define CSCR_SP_SEL (1 << 17) -#define CSCR_SD_CNT(d) (((d) & 0x3) << 24) -#define CSCR_USB_DIV(d) (((d) & 0x7) << 26) -#define CSCR_PRESC(d) (((d) & 0x7) << 29) - -#define MPCTL1_BRMO (1 << 6) -#define MPCTL1_LF (1 << 15) - -#define PCCR0_PERCLK3_EN (1 << 18) -#define PCCR0_NFC_EN (1 << 19) -#define PCCR0_HCLK_LCDC_EN (1 << 26) - -#define PCCR1_GPT1_EN (1 << 25) - -#define CCSR_32K_SR (1 << 15) +/* AIPI (base MX21_AIPI_BASE_ADDR) */ +#define MX21_AIPI1_PSR0 0x00 +#define MX21_AIPI1_PSR1 0x04 +#define MX21_AIPI2_PSR0 (0x20000 + 0x00) +#define MX21_AIPI2_PSR1 (0x20000 + 0x04) + +/* System Control (base: MX21_SYSCTRL_BASE_ADDR) */ +#define MX21_SUID0 0x4 /* Silicon ID Register (12 bytes) */ +#define MX21_SUID1 0x8 /* Silicon ID Register (12 bytes) */ +#define MX21_CID 0xC /* Silicon ID Register (12 bytes) */ +#define MX21_FMCR 0x14 /* Function Multeplexing Control Register */ +#define MX21_GPCR 0x18 /* Global Peripheral Control Register */ +#define MX21_WBCR 0x1C /* Well Bias Control Register */ +#define MX21_DSCR(x) 0x1C + ((x) << 2) /* Driving Strength Control Register 1 - 13 */ + +#define MX21_GPCR_BOOT_SHIFT 16 +#define MX21_GPCR_BOOT_MASK (0xf << GPCR_BOOT_SHIFT) +#define MX21_GPCR_BOOT_UART_USB 0 +#define MX21_GPCR_BOOT_8BIT_NAND_2k 2 +#define MX21_GPCR_BOOT_16BIT_NAND_2k 3 +#define MX21_GPCR_BOOT_16BIT_NAND_512 4 +#define MX21_GPCR_BOOT_16BIT_CS0 5 +#define MX21_GPCR_BOOT_32BIT_CS0 6 +#define MX21_GPCR_BOOT_8BIT_NAND_512 7 + +/* SDRAM Controller registers bitfields (base: MX21_X_MEMC_BASE_ADDR) */ +#define MX21_SDCTL0 0x00 /* SDRAM 0 Control Register */ +#define MX21_SDCTL1 0x04 /* SDRAM 0 Control Register */ +#define MX21_SDRST 0x18 /* SDRAM Reset Register */ +#define MX21_SDMISC 0x14 /* SDRAM Miscellaneous Register */ + +/* PLL registers (base: MX21_CCM_BASE_ADDR) */ +#define MX21_CSCR 0x00 /* Clock Source Control Register */ +#define MX21_MPCTL0 0x04 /* MCU PLL Control Register 0 */ +#define MX21_MPCTL1 0x08 /* MCU PLL Control Register 1 */ +#define MX21_SPCTL0 0x0c /* System PLL Control Register 0 */ +#define MX21_SPCTL1 0x10 /* System PLL Control Register 1 */ +#define MX21_OSC26MCTL 0x14 /* Oscillator 26M Register */ +#define MX21_PCDR0 0x18 /* Peripheral Clock Divider Register 0 */ +#define MX21_PCDR1 0x1c /* Peripheral Clock Divider Register 1 */ +#define MX21_PCCR0 0x20 /* Peripheral Clock Control Register 0 */ +#define MX21_PCCR1 0x24 /* Peripheral Clock Control Register 1 */ +#define MX21_CCSR 0x28 /* Clock Control Status Register */ + +#define MX21_CSCR_MPEN (1 << 0) +#define MX21_CSCR_SPEN (1 << 1) +#define MX21_CSCR_FPM_EN (1 << 2) +#define MX21_CSCR_OSC26M_DIS (1 << 3) +#define MX21_CSCR_OSC26M_DIV1P5 (1 << 4) +#define MX21_CSCR_MCU_SEL (1 << 16) +#define MX21_CSCR_SP_SEL (1 << 17) +#define MX21_CSCR_SD_CNT(d) (((d) & 0x3) << 24) +#define MX21_CSCR_USB_DIV(d) (((d) & 0x7) << 26) +#define MX21_CSCR_PRESC(d) (((d) & 0x7) << 29) + +#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/imx25-regs.h b/arch/arm/mach-imx/include/mach/imx25-regs.h index 0bf6e119e0..b8ae45a787 100644 --- a/arch/arm/mach-imx/include/mach/imx25-regs.h +++ b/arch/arm/mach-imx/include/mach/imx25-regs.h @@ -76,46 +76,39 @@ #define MX25_USB_HS_BASE_ADDR (MX25_USB_BASE_ADDR + 0x0400) #define MX25_CSI_BASE_ADDR 0x53ff8000 -/* FIXME: Get rid of these */ -#define IMX_TIM1_BASE MX25_GPT1_BASE_ADDR -#define IMX_IOMUXC_BASE MX25_IOMUXC_BASE_ADDR -#define IMX_WDT_BASE MX25_WDOG_BASE_ADDR -#define IMX_CCM_BASE MX25_CCM_BASE_ADDR -#define IMX_ESD_BASE MX25_ESDCTL_BASE_ADDR - /* * Clock Controller Module (CCM) */ -#define CCM_MPCTL 0x00 -#define CCM_UPCTL 0x04 -#define CCM_CCTL 0x08 -#define CCM_CGCR0 0x0C -#define CCM_CGCR1 0x10 -#define CCM_CGCR2 0x14 -#define CCM_PCDR0 0x18 -#define CCM_PCDR1 0x1C -#define CCM_PCDR2 0x20 -#define CCM_PCDR3 0x24 -#define CCM_RCSR 0x28 -#define CCM_CRDR 0x2C -#define CCM_DCVR0 0x30 -#define CCM_DCVR1 0x34 -#define CCM_DCVR2 0x38 -#define CCM_DCVR3 0x3c -#define CCM_LTR0 0x40 -#define CCM_LTR1 0x44 -#define CCM_LTR2 0x48 -#define CCM_LTR3 0x4c - -#define PDR0_AUTO_MUX_DIV(x) (((x) & 0x7) << 9) -#define PDR0_CCM_PER_AHB(x) (((x) & 0x7) << 12) -#define PDR0_CON_MUX_DIV(x) (((x) & 0xf) << 16) -#define PDR0_HSP_PODF(x) (((x) & 0x3) << 20) -#define PDR0_AUTO_CON (1 << 0) -#define PDR0_PER_SEL (1 << 26) - -#define CCM_RCSR_MEM_CTRL_SHIFT 30 -#define CCM_RCSR_MEM_TYPE_SHIFT 28 +#define MX25_CCM_MPCTL 0x00 +#define MX25_CCM_UPCTL 0x04 +#define MX25_CCM_CCTL 0x08 +#define MX25_CCM_CGCR0 0x0C +#define MX25_CCM_CGCR1 0x10 +#define MX25_CCM_CGCR2 0x14 +#define MX25_CCM_PCDR0 0x18 +#define MX25_CCM_PCDR1 0x1C +#define MX25_CCM_PCDR2 0x20 +#define MX25_CCM_PCDR3 0x24 +#define MX25_CCM_RCSR 0x28 +#define MX25_CCM_CRDR 0x2C +#define MX25_CCM_DCVR0 0x30 +#define MX25_CCM_DCVR1 0x34 +#define MX25_CCM_DCVR2 0x38 +#define MX25_CCM_DCVR3 0x3c +#define MX25_CCM_LTR0 0x40 +#define MX25_CCM_LTR1 0x44 +#define MX25_CCM_LTR2 0x48 +#define MX25_CCM_LTR3 0x4c + +#define MX25_PDR0_AUTO_MUX_DIV(x) (((x) & 0x7) << 9) +#define MX25_PDR0_CCM_PER_AHB(x) (((x) & 0x7) << 12) +#define MX25_PDR0_CON_MUX_DIV(x) (((x) & 0xf) << 16) +#define MX25_PDR0_HSP_PODF(x) (((x) & 0x3) << 20) +#define MX25_PDR0_AUTO_CON (1 << 0) +#define MX25_PDR0_PER_SEL (1 << 26) + +#define MX25_CCM_RCSR_MEM_CTRL_SHIFT 30 +#define MX25_CCM_RCSR_MEM_TYPE_SHIFT 28 /* * Adresses and ranges of the external chip select lines @@ -139,14 +132,4 @@ #define MX25_ESDCTL_BASE_ADDR 0xb8001000 #define MX25_WEIM_BASE_ADDR 0xb8002000 -/* - * Watchdog Registers - */ -#define WCR __REG16(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */ -#define WSR __REG16(IMX_WDT_BASE + 0x02) /* Watchdog Service Register */ -#define WSTR __REG16(IMX_WDT_BASE + 0x04) /* Watchdog Status Register */ - -/* important definition of some bits of WCR */ -#define WCR_WDE 0x04 - #endif /* __ASM_ARCH_MX25_REGS_H */ diff --git a/arch/arm/mach-imx/include/mach/imx27-regs.h b/arch/arm/mach-imx/include/mach/imx27-regs.h index 5db1a3c3eb..90b4614bdf 100644 --- a/arch/arm/mach-imx/include/mach/imx27-regs.h +++ b/arch/arm/mach-imx/include/mach/imx27-regs.h @@ -86,7 +86,7 @@ #define MX27_X_MEMC_BASE_ADDR 0xd8000000 #define MX27_X_MEMC_SIZE SZ_1M #define MX27_NFC_BASE_ADDR (MX27_X_MEMC_BASE_ADDR) -#define MX27_SDRAMC_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x1000) +#define MX27_ESDCTL_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x1000) #define MX27_WEIM_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x2000) #define MX27_M3IF_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x3000) #define MX27_PCMCIA_CTL_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x4000) @@ -101,181 +101,65 @@ /* IRAM */ #define MX27_IRAM_BASE_ADDR 0xffff4c00 /* internal ram */ -/* FIXME: get rid of these */ -#define IMX_GPIO_BASE MX27_GPIO_BASE_ADDR -#define IMX_NFC_BASE MX27_NFC_BASE_ADDR -#define IMX_WDT_BASE MX27_WDOG_BASE_ADDR -#define IMX_ESD_BASE MX27_SDRAMC_BASE_ADDR - -#define PCMCIA_PIPR (MX27_PCMCIA_CTL_BASE_ADDR + 0x00) -#define PCMCIA_PSCR (MX27_PCMCIA_CTL_BASE_ADDR + 0x04) -#define PCMCIA_PER (MX27_PCMCIA_CTL_BASE_ADDR + 0x08) -#define PCMCIA_PBR(x) (MX27_PCMCIA_CTL_BASE_ADDR + 0x0c + ((x) << 2)) -#define PCMCIA_POR(x) (MX27_PCMCIA_CTL_BASE_ADDR + 0x28 + ((x) << 2)) -#define PCMCIA_POFR(x) (MX27_PCMCIA_CTL_BASE_ADDR + 0x44 + ((x) << 2)) -#define PCMCIA_PGCR (MX27_PCMCIA_CTL_BASE_ADDR + 0x60) -#define PCMCIA_PGSR (MX27_PCMCIA_CTL_BASE_ADDR + 0x64) - -/* AIPI */ -#define AIPI1_PSR0 __REG(MX27_AIPI_BASE_ADDR + 0x00) -#define AIPI1_PSR1 __REG(MX27_AIPI_BASE_ADDR + 0x04) -#define AIPI2_PSR0 __REG(MX27_AIPI_BASE_ADDR + 0x20000 + 0x00) -#define AIPI2_PSR1 __REG(MX27_AIPI_BASE_ADDR + 0x20000 + 0x04) - -/* System Control */ -#define CID __REG(MX27_SYSCTRL_BASE_ADDR + 0x0) /* Chip ID Register */ -#define FMCR __REG(MX27_SYSCTRL_BASE_ADDR + 0x14) /* Function Multeplexing Control Register */ -#define GPCR __REG(MX27_SYSCTRL_BASE_ADDR + 0x18) /* Global Peripheral Control Register */ -#define WBCR __REG(MX27_SYSCTRL_BASE_ADDR + 0x1C) /* Well Bias Control Register */ -#define DSCR(x) __REG(MX27_SYSCTRL_BASE_ADDR + 0x1C + ((x) << 2)) /* Driving Strength Control Register 1 - 13 */ - -#define GPCR_BOOT_SHIFT 16 -#define GPCR_BOOT_MASK (0xf << GPCR_BOOT_SHIFT) -#define GPCR_BOOT_UART_USB 0 -#define GPCR_BOOT_8BIT_NAND_2k 2 -#define GPCR_BOOT_16BIT_NAND_2k 3 -#define GPCR_BOOT_16BIT_NAND_512 4 -#define GPCR_BOOT_16BIT_CS0 5 -#define GPCR_BOOT_32BIT_CS0 6 -#define GPCR_BOOT_8BIT_NAND_512 7 +/* PCMCIA (base: MX27_PCMCIA_CTL_BASE_ADDR) */ +#define MX27_PCMCIA_PIPR 0x00 +#define MX27_PCMCIA_PSCR 0x04 +#define MX27_PCMCIA_PER 0x08 +#define MX27_PCMCIA_PBR(x) (0x0c + ((x) << 2)) +#define MX27_PCMCIA_POR(x) (0x28 + ((x) << 2)) +#define MX27_PCMCIA_POFR(x) (0x44 + ((x) << 2)) +#define MX27_PCMCIA_PGCR 0x60 +#define MX27_PCMCIA_PGSR 0x64 + +/* AIPI (base: MX27_AIPI_BASE_ADDR) */ +#define MX27_AIPI1_PSR0 0x00 +#define MX27_AIPI1_PSR1 0x04 +#define MX27_AIPI2_PSR0 (0x20000 + 0x00) +#define MX27_AIPI2_PSR1 (0x20000 + 0x04) + +/* System Control (base: MX27_SYSCTRL_BASE_ADDR) */ +#define MX27_CID 0x0 /* Chip ID Register */ +#define MX27_FMCR 0x14 /* Function Multeplexing Control Register */ +#define MX27_GPCR 0x18 /* Global Peripheral Control Register */ +#define MX27_WBCR 0x1C /* Well Bias Control Register */ +#define MX27_DSCR(x) (0x1C + ((x) << 2)) /* Driving Strength Control Register 1 - 13 */ #include "esdctl.h" -/* PLL registers */ -#define CSCR __REG(MX27_CCM_BASE_ADDR + 0x00) /* Clock Source Control Register */ -#define MPCTL0 __REG(MX27_CCM_BASE_ADDR + 0x04) /* MCU PLL Control Register 0 */ -#define MPCTL1 __REG(MX27_CCM_BASE_ADDR + 0x08) /* MCU PLL Control Register 1 */ -#define SPCTL0 __REG(MX27_CCM_BASE_ADDR + 0x0c) /* System PLL Control Register 0 */ -#define SPCTL1 __REG(MX27_CCM_BASE_ADDR + 0x10) /* System PLL Control Register 1 */ -#define OSC26MCTL __REG(MX27_CCM_BASE_ADDR + 0x14) /* Oscillator 26M Register */ -#define PCDR0 __REG(MX27_CCM_BASE_ADDR + 0x18) /* Peripheral Clock Divider Register 0 */ -#define PCDR1 __REG(MX27_CCM_BASE_ADDR + 0x1c) /* Peripheral Clock Divider Register 1 */ -#define PCCR0 __REG(MX27_CCM_BASE_ADDR + 0x20) /* Peripheral Clock Control Register 0 */ -#define PCCR1 __REG(MX27_CCM_BASE_ADDR + 0x24) /* Peripheral Clock Control Register 1 */ -#define CCSR __REG(MX27_CCM_BASE_ADDR + 0x28) /* Clock Control Status Register */ - -#define CSCR_MPEN (1 << 0) -#define CSCR_SPEN (1 << 1) -#define CSCR_FPM_EN (1 << 2) -#define CSCR_OSC26M_DIS (1 << 3) -#define CSCR_OSC26M_DIV1P5 (1 << 4) -#define CSCR_AHB_DIV(d) (((d) & 0x3) << 8) -#define CSCR_ARM_DIV(d) (((d) & 0x3) << 12) -#define CSCR_ARM_SRC_MPLL (1 << 15) -#define CSCR_MCU_SEL (1 << 16) -#define CSCR_SP_SEL (1 << 17) -#define CSCR_MPLL_RESTART (1 << 18) -#define CSCR_SPLL_RESTART (1 << 19) -#define CSCR_MSHC_SEL (1 << 20) -#define CSCR_H264_SEL (1 << 21) -#define CSCR_SSI1_SEL (1 << 22) -#define CSCR_SSI2_SEL (1 << 23) -#define CSCR_SD_CNT(d) (((d) & 0x3) << 24) -#define CSCR_USB_DIV(d) (((d) & 0x7) << 28) -#define CSCR_UPDATE_DIS (1 << 31) - -#define MPCTL1_BRMO (1 << 6) -#define MPCTL1_LF (1 << 15) - -#define PCCR0_SSI2_EN (1 << 0) -#define PCCR0_SSI1_EN (1 << 1) -#define PCCR0_SLCDC_EN (1 << 2) -#define PCCR0_SDHC3_EN (1 << 3) -#define PCCR0_SDHC2_EN (1 << 4) -#define PCCR0_SDHC1_EN (1 << 5) -#define PCCR0_SDC_EN (1 << 6) -#define PCCR0_SAHARA_EN (1 << 7) -#define PCCR0_RTIC_EN (1 << 8) -#define PCCR0_RTC_EN (1 << 9) -#define PCCR0_PWM_EN (1 << 11) -#define PCCR0_OWIRE_EN (1 << 12) -#define PCCR0_MSHC_EN (1 << 13) -#define PCCR0_LCDC_EN (1 << 14) -#define PCCR0_KPP_EN (1 << 15) -#define PCCR0_IIM_EN (1 << 16) -#define PCCR0_I2C2_EN (1 << 17) -#define PCCR0_I2C1_EN (1 << 18) -#define PCCR0_GPT6_EN (1 << 19) -#define PCCR0_GPT5_EN (1 << 20) -#define PCCR0_GPT4_EN (1 << 21) -#define PCCR0_GPT3_EN (1 << 22) -#define PCCR0_GPT2_EN (1 << 23) -#define PCCR0_GPT1_EN (1 << 24) -#define PCCR0_GPIO_EN (1 << 25) -#define PCCR0_FEC_EN (1 << 26) -#define PCCR0_EMMA_EN (1 << 27) -#define PCCR0_DMA_EN (1 << 28) -#define PCCR0_CSPI3_EN (1 << 29) -#define PCCR0_CSPI2_EN (1 << 30) -#define PCCR0_CSPI1_EN (1 << 31) - -#define PCCR1_MSHC_BAUDEN (1 << 2) -#define PCCR1_NFC_BAUDEN (1 << 3) -#define PCCR1_SSI2_BAUDEN (1 << 4) -#define PCCR1_SSI1_BAUDEN (1 << 5) -#define PCCR1_H264_BAUDEN (1 << 6) -#define PCCR1_PERCLK4_EN (1 << 7) -#define PCCR1_PERCLK3_EN (1 << 8) -#define PCCR1_PERCLK2_EN (1 << 9) -#define PCCR1_PERCLK1_EN (1 << 10) -#define PCCR1_HCLK_USB (1 << 11) -#define PCCR1_HCLK_SLCDC (1 << 12) -#define PCCR1_HCLK_SAHARA (1 << 13) -#define PCCR1_HCLK_RTIC (1 << 14) -#define PCCR1_HCLK_LCDC (1 << 15) -#define PCCR1_HCLK_H264 (1 << 16) -#define PCCR1_HCLK_FEC (1 << 17) -#define PCCR1_HCLK_EMMA (1 << 18) -#define PCCR1_HCLK_EMI (1 << 19) -#define PCCR1_HCLK_DMA (1 << 20) -#define PCCR1_HCLK_CSI (1 << 21) -#define PCCR1_HCLK_BROM (1 << 22) -#define PCCR1_HCLK_ATA (1 << 23) -#define PCCR1_WDT_EN (1 << 24) -#define PCCR1_USB_EN (1 << 25) -#define PCCR1_UART6_EN (1 << 26) -#define PCCR1_UART5_EN (1 << 27) -#define PCCR1_UART4_EN (1 << 28) -#define PCCR1_UART3_EN (1 << 29) -#define PCCR1_UART2_EN (1 << 30) -#define PCCR1_UART1_EN (1 << 31) - -#define CCSR_32K_SR (1 << 15) - -/* SDRAM Controller registers bitfields */ -#define ESDCTL_PRCT(x) (((x) & 3f) << 0) -#define ESDCTL_BL (1 << 7) -#define ESDCTL_FP (1 << 8) -#define ESDCTL_PWDT(x) (((x) & 3) << 10) -#define ESDCTL_SREFR(x) (((x) & 7) << 13) -#define ESDCTL_DSIZ_16_UPPER (0 << 16) -#define ESDCTL_DSIZ_16_LOWER (0 << 16) -#define ESDCTL_DSIZ_32 (0 << 16) -#define ESDCTL_COL8 (0 << 20) -#define ESDCTL_COL9 (1 << 20) -#define ESDCTL_COL10 (2 << 20) -#define ESDCTL_ROW11 (0 << 24) -#define ESDCTL_ROW12 (1 << 24) -#define ESDCTL_ROW13 (2 << 24) -#define ESDCTL_ROW14 (3 << 24) -#define ESDCTL_ROW15 (4 << 24) -#define ESDCTL_SP (1 << 27) -#define ESDCTL_SMODE_NORMAL (0 << 28) -#define ESDCTL_SMODE_PRECHAGRE (1 << 28) -#define ESDCTL_SMODE_AUTO_REF (2 << 28) -#define ESDCTL_SMODE_LOAD_MODE (3 << 28) -#define ESDCTL_SMODE_MAN_REF (4 << 28) -#define ESDCTL_SDE (1 << 31) - -#define ESDCFG_TRC(x) (((x) & 0xf) << 0) -#define ESDCFG_TRCD(x) (((x) & 0x7) << 4) -#define ESDCFG_TCAS(x) (((x) & 0x3) << 8) -#define ESDCFG_TRRD(x) (((x) & 0x3) << 10) -#define ESDCFG_TRAS(x) (((x) & 0x7) << 12) -#define ESDCFG_TWR (1 << 15) -#define ESDCFG_TMRD(x) (((x) & 0x3) << 16) -#define ESDCFG_TRP(x) (((x) & 0x3) << 18) -#define ESDCFG_TWTR (1 << 20) -#define ESDCFG_TXP(x) (((x) & 0x3) << 21) +/* PLL registers (base: MX27_CCM_BASE_ADDR) */ +#define MX27_CSCR 0x00 /* Clock Source Control Register */ +#define MX27_MPCTL0 0x04 /* MCU PLL Control Register 0 */ +#define MX27_MPCTL1 0x08 /* MCU PLL Control Register 1 */ +#define MX27_SPCTL0 0x0c /* System PLL Control Register 0 */ +#define MX27_SPCTL1 0x10 /* System PLL Control Register 1 */ +#define MX27_OSC26MCTL 0x14 /* Oscillator 26M Register */ +#define MX27_PCDR0 0x18 /* Peripheral Clock Divider Register 0 */ +#define MX27_PCDR1 0x1c /* Peripheral Clock Divider Register 1 */ +#define MX27_PCCR0 0x20 /* Peripheral Clock Control Register 0 */ +#define MX27_PCCR1 0x24 /* Peripheral Clock Control Register 1 */ +#define MX27_CCSR 0x28 /* Clock Control Status Register */ + +#define MX27_CSCR_MPEN (1 << 0) +#define MX27_CSCR_SPEN (1 << 1) +#define MX27_CSCR_FPM_EN (1 << 2) +#define MX27_CSCR_OSC26M_DIS (1 << 3) +#define MX27_CSCR_OSC26M_DIV1P5 (1 << 4) +#define MX27_CSCR_AHB_DIV(d) (((d) & 0x3) << 8) +#define MX27_CSCR_ARM_DIV(d) (((d) & 0x3) << 12) +#define MX27_CSCR_ARM_SRC_MPLL (1 << 15) +#define MX27_CSCR_MCU_SEL (1 << 16) +#define MX27_CSCR_SP_SEL (1 << 17) +#define MX27_CSCR_MPLL_RESTART (1 << 18) +#define MX27_CSCR_SPLL_RESTART (1 << 19) +#define MX27_CSCR_MSHC_SEL (1 << 20) +#define MX27_CSCR_H264_SEL (1 << 21) +#define MX27_CSCR_SSI1_SEL (1 << 22) +#define MX27_CSCR_SSI2_SEL (1 << 23) +#define MX27_CSCR_SD_CNT(d) (((d) & 0x3) << 24) +#define MX27_CSCR_USB_DIV(d) (((d) & 0x7) << 28) +#define MX27_CSCR_UPDATE_DIS (1 << 31) + +#define MX27_MPCTL1_BRMO (1 << 6) +#define MX27_MPCTL1_LF (1 << 15) #endif /* _IMX27_REGS_H */ diff --git a/arch/arm/mach-imx/include/mach/imx31-regs.h b/arch/arm/mach-imx/include/mach/imx31-regs.h index 57f65dad1e..f641fe6129 100644 --- a/arch/arm/mach-imx/include/mach/imx31-regs.h +++ b/arch/arm/mach-imx/include/mach/imx31-regs.h @@ -130,105 +130,61 @@ #define MX31_PCMCIA_MEM_BASE_ADDR 0xbc000000 -/* FIXME: Get rid of these */ -#define IMX_TIM1_BASE MX31_GPT1_BASE_ADDR -#define IMX_WDT_BASE MX31_WDOG_BASE_ADDR -#define IMX_ESD_BASE MX31_ESDCTL_BASE_ADDR -#define IMX_NFC_BASE MX31_NFC_BASE_ADDR -#define IOMUXC_BASE MX31_IOMUXC_BASE_ADDR - /* * Clock Controller Module (CCM) */ -#define CCM_CCMR 0x00 -#define CCM_PDR0 0x04 -#define CCM_PDR1 0x08 -#define CCM_RCSR 0x0c -#define CCM_MPCTL 0x10 -#define CCM_UPCTL 0x14 -#define CCM_SPCTL 0x18 -#define CCM_COSR 0x1C - -/* - * ????????????? - */ -#define CCMR_MDS (1 << 7) -#define CCMR_SBYCS (1 << 4) -#define CCMR_MPE (1 << 3) -#define CCMR_PRCS_MASK (3 << 1) -#define CCMR_FPM (1 << 1) -#define CCMR_CKIH (2 << 1) - -#define RCSR_NFMS (1 << 30) - -/* - * ????????????? - */ -#define PDR0_CSI_PODF(x) (((x) & 0x1ff) << 23) -#define PDR0_PER_PODF(x) (((x) & 0x1f) << 16) -#define PDR0_HSP_PODF(x) (((x) & 0x7) << 11) -#define PDR0_NFC_PODF(x) (((x) & 0x7) << 8) -#define PDR0_IPG_PODF(x) (((x) & 0x3) << 6) -#define PDR0_MAX_PODF(x) (((x) & 0x7) << 3) -#define PDR0_MCU_PODF(x) ((x) & 0x7) - -#include "esdctl.h" - -/* - * ??????????? - */ -#define IOMUXC_GPR (IOMUXC_BASE + 0x8) -#define IOMUXC_SW_MUX_CTL(x) (IOMUXC_BASE + 0xc + (x) * 4) -#define IOMUXC_SW_PAD_CTL(x) (IOMUXC_BASE + 0x154 + (x) * 4) +#define MX31_CCM_CCMR 0x00 +#define MX31_CCM_PDR0 0x04 +#define MX31_CCM_PDR1 0x08 +#define MX31_CCM_RCSR 0x0c +#define MX31_CCM_MPCTL 0x10 +#define MX31_CCM_UPCTL 0x14 +#define MX31_CCM_SPCTL 0x18 +#define MX31_CCM_COSR 0x1C + +#define MX31_CCMR_MDS (1 << 7) +#define MX31_CCMR_SBYCS (1 << 4) +#define MX31_CCMR_MPE (1 << 3) +#define MX31_CCMR_PRCS_MASK (3 << 1) +#define MX31_CCMR_FPM (1 << 1) +#define MX31_CCMR_CKIH (2 << 1) + +#define MX31_RCSR_NFMS (1 << 30) + +#define MX31_PDR0_CSI_PODF(x) (((x) & 0x1ff) << 23) +#define MX31_PDR0_PER_PODF(x) (((x) & 0x1f) << 16) +#define MX31_PDR0_HSP_PODF(x) (((x) & 0x7) << 11) +#define MX31_PDR0_NFC_PODF(x) (((x) & 0x7) << 8) +#define MX31_PDR0_IPG_PODF(x) (((x) & 0x3) << 6) +#define MX31_PDR0_MAX_PODF(x) (((x) & 0x7) << 3) +#define MX31_PDR0_MCU_PODF(x) ((x) & 0x7) + +#define MX31_IOMUXC_GPR (IOMUXC_BASE + 0x8) +#define MX31_IOMUXC_SW_MUX_CTL(x) (IOMUXC_BASE + 0xc + (x) * 4) +#define MX31_IOMUXC_SW_PAD_CTL(x) (IOMUXC_BASE + 0x154 + (x) * 4) /* * Signal Multiplexing (IOMUX) */ /* bits in the SW_MUX_CTL registers */ -#define MUX_CTL_OUT_GPIO_DR (0 << 4) -#define MUX_CTL_OUT_FUNC (1 << 4) -#define MUX_CTL_OUT_ALT1 (2 << 4) -#define MUX_CTL_OUT_ALT2 (3 << 4) -#define MUX_CTL_OUT_ALT3 (4 << 4) -#define MUX_CTL_OUT_ALT4 (5 << 4) -#define MUX_CTL_OUT_ALT5 (6 << 4) -#define MUX_CTL_OUT_ALT6 (7 << 4) -#define MUX_CTL_IN_NONE (0 << 0) -#define MUX_CTL_IN_GPIO (1 << 0) -#define MUX_CTL_IN_FUNC (2 << 0) -#define MUX_CTL_IN_ALT1 (4 << 0) -#define MUX_CTL_IN_ALT2 (8 << 0) - -#define MUX_CTL_FUNC (MUX_CTL_OUT_FUNC | MUX_CTL_IN_FUNC) -#define MUX_CTL_ALT1 (MUX_CTL_OUT_ALT1 | MUX_CTL_IN_ALT1) -#define MUX_CTL_ALT2 (MUX_CTL_OUT_ALT2 | MUX_CTL_IN_ALT2) -#define MUX_CTL_GPIO (MUX_CTL_OUT_GPIO_DR | MUX_CTL_IN_GPIO) - -/* Register offsets based on IOMUXC_BASE */ -/* 0x00 .. 0x7b */ -#define MUX_CTL_RTS1 0x7c -#define MUX_CTL_CTS1 0x7d -#define MUX_CTL_DTR_DCE1 0x7e -#define MUX_CTL_DSR_DCE1 0x7f -#define MUX_CTL_CSPI2_SCLK 0x80 -#define MUX_CTL_CSPI2_SPI_RDY 0x81 -#define MUX_CTL_RXD1 0x82 -#define MUX_CTL_TXD1 0x83 -#define MUX_CTL_CSPI2_MISO 0x84 -/* 0x85 .. 0x8a */ -#define MUX_CTL_CSPI2_MOSI 0x8b - -/* The modes a specific pin can be in - * these macros can be used in mx31_gpio_mux() and have the form - * MUX_[contact name]__[pin function] - */ -#define MUX_RXD1_UART1_RXD_MUX ((MUX_CTL_FUNC << 8) | MUX_CTL_RXD1) -#define MUX_TXD1_UART1_TXD_MUX ((MUX_CTL_FUNC << 8) | MUX_CTL_TXD1) -#define MUX_RTS1_UART1_RTS_B ((MUX_CTL_FUNC << 8) | MUX_CTL_RTS1) -#define MUX_RTS1_UART1_CTS_B ((MUX_CTL_FUNC << 8) | MUX_CTL_CTS1) - -#define MUX_CSPI2_MOSI_I2C2_SCL ((MUX_CTL_ALT1 << 8) | MUX_CTL_CSPI2_MOSI) -#define MUX_CSPI2_MISO_I2C2_SCL ((MUX_CTL_ALT1 << 8) | MUX_CTL_CSPI2_MISO) +#define MX31_MUX_CTL_OUT_GPIO_DR (0 << 4) +#define MX31_MUX_CTL_OUT_FUNC (1 << 4) +#define MX31_MUX_CTL_OUT_ALT1 (2 << 4) +#define MX31_MUX_CTL_OUT_ALT2 (3 << 4) +#define MX31_MUX_CTL_OUT_ALT3 (4 << 4) +#define MX31_MUX_CTL_OUT_ALT4 (5 << 4) +#define MX31_MUX_CTL_OUT_ALT5 (6 << 4) +#define MX31_MUX_CTL_OUT_ALT6 (7 << 4) +#define MX31_MUX_CTL_IN_NONE (0 << 0) +#define MX31_MUX_CTL_IN_GPIO (1 << 0) +#define MX31_MUX_CTL_IN_FUNC (2 << 0) +#define MX31_MUX_CTL_IN_ALT1 (4 << 0) +#define MX31_MUX_CTL_IN_ALT2 (8 << 0) + +#define MX31_MUX_CTL_FUNC (MX31_MUX_CTL_OUT_FUNC | MX31_MUX_CTL_IN_FUNC) +#define MX31_MUX_CTL_ALT1 (MX31_MUX_CTL_OUT_ALT1 | MX31_MUX_CTL_IN_ALT1) +#define MX31_MUX_CTL_ALT2 (MX31_MUX_CTL_OUT_ALT2 | MX31_MUX_CTL_IN_ALT2) +#define MX31_MUX_CTL_GPIO (MX31_MUX_CTL_OUT_GPIO_DR | MX31_MUX_CTL_IN_GPIO) #endif /* __ASM_ARCH_MX31_REGS_H */ diff --git a/arch/arm/mach-imx/include/mach/imx35-regs.h b/arch/arm/mach-imx/include/mach/imx35-regs.h index 19f6389b95..bbfde2339a 100644 --- a/arch/arm/mach-imx/include/mach/imx35-regs.h +++ b/arch/arm/mach-imx/include/mach/imx35-regs.h @@ -130,47 +130,39 @@ #define MX35_NFC_BASE_ADDR 0xbb000000 #define MX35_PCMCIA_MEM_BASE_ADDR 0xbc000000 -/* FIXME: Get rid of these */ -#define IMX_WDT_BASE MX35_WDOG_BASE_ADDR -#define IMX_TIM1_BASE MX35_GPT1_BASE_ADDR -#define IMX_ESD_BASE MX35_ESDCTL_BASE_ADDR -#define IMX_IOMUXC_BASE MX35_IOMUXC_BASE_ADDR -#define IMX_CCM_BASE MX35_CCM_BASE_ADDR -#define IMX_NFC_BASE MX35_NFC_BASE_ADDR - /* * Clock Controller Module (CCM) */ -#define CCM_CCMR 0x00 -#define CCM_PDR0 0x04 -#define CCM_PDR1 0x08 -#define CCM_PDR2 0x0C -#define CCM_PDR3 0x10 -#define CCM_PDR4 0x14 -#define CCM_RCSR 0x18 -#define CCM_MPCTL 0x1C -#define CCM_PPCTL 0x20 -#define CCM_ACMR 0x24 -#define CCM_COSR 0x28 -#define CCM_CGR0 0x2C -#define CCM_CGR1 0x30 -#define CCM_CGR2 0x34 -#define CCM_CGR3 0x38 - -#define CCM_CGR0_CSPI1_SHIFT 10 -#define CCM_CGR1_FEC_SHIFT 0 -#define CCM_CGR1_I2C1_SHIFT 10 -#define CCM_CGR1_SDHC1_SHIFT 26 -#define CCM_CGR2_USB_SHIFT 22 - -#define CCM_RCSR_MEM_CTRL_SHIFT 25 -#define CCM_RCSR_MEM_TYPE_SHIFT 23 - -#define PDR0_AUTO_MUX_DIV(x) (((x) & 0x7) << 9) -#define PDR0_CCM_PER_AHB(x) (((x) & 0x7) << 12) -#define PDR0_CON_MUX_DIV(x) (((x) & 0xf) << 16) -#define PDR0_HSP_PODF(x) (((x) & 0x3) << 20) -#define PDR0_AUTO_CON (1 << 0) -#define PDR0_PER_SEL (1 << 26) +#define MX35_CCM_CCMR 0x00 +#define MX35_CCM_PDR0 0x04 +#define MX35_CCM_PDR1 0x08 +#define MX35_CCM_PDR2 0x0C +#define MX35_CCM_PDR3 0x10 +#define MX35_CCM_PDR4 0x14 +#define MX35_CCM_RCSR 0x18 +#define MX35_CCM_MPCTL 0x1C +#define MX35_CCM_PPCTL 0x20 +#define MX35_CCM_ACMR 0x24 +#define MX35_CCM_COSR 0x28 +#define MX35_CCM_CGR0 0x2C +#define MX35_CCM_CGR1 0x30 +#define MX35_CCM_CGR2 0x34 +#define MX35_CCM_CGR3 0x38 + +#define MX35_CCM_CGR0_CSPI1_SHIFT 10 +#define MX35_CCM_CGR1_FEC_SHIFT 0 +#define MX35_CCM_CGR1_I2C1_SHIFT 10 +#define MX35_CCM_CGR1_SDHC1_SHIFT 26 +#define MX35_CCM_CGR2_USB_SHIFT 22 + +#define MX35_CCM_RCSR_MEM_CTRL_SHIFT 25 +#define MX35_CCM_RCSR_MEM_TYPE_SHIFT 23 + +#define MX35_PDR0_AUTO_MUX_DIV(x) (((x) & 0x7) << 9) +#define MX35_PDR0_CCM_PER_AHB(x) (((x) & 0x7) << 12) +#define MX35_PDR0_CON_MUX_DIV(x) (((x) & 0xf) << 16) +#define MX35_PDR0_HSP_PODF(x) (((x) & 0x3) << 20) +#define MX35_PDR0_AUTO_CON (1 << 0) +#define MX35_PDR0_PER_SEL (1 << 26) #endif /* __ASM_ARCH_MX35_REGS_H */ diff --git a/arch/arm/mach-imx/include/mach/imx51-regs.h b/arch/arm/mach-imx/include/mach/imx51-regs.h index c451004ecc..8eb74cdb7a 100644 --- a/arch/arm/mach-imx/include/mach/imx51-regs.h +++ b/arch/arm/mach-imx/include/mach/imx51-regs.h @@ -1,10 +1,6 @@ #ifndef __MACH_IMX51_REGS_H #define __MACH_IMX51_REGS_H -#define IMX_TIM1_BASE 0x73fa0000 -#define IMX_WDT_BASE 0x73f98000 -#define IMX_IOMUXC_BASE 0x73fa8000 - /* WEIM registers */ #define WEIM_CSxGCR1(n) (((n) * 0x18) + 0x00) #define WEIM_CSxGCR2(n) (((n) * 0x18) + 0x04) diff --git a/arch/arm/mach-imx/include/mach/imx53-regs.h b/arch/arm/mach-imx/include/mach/imx53-regs.h index e57d1abdd0..8025e97720 100644 --- a/arch/arm/mach-imx/include/mach/imx53-regs.h +++ b/arch/arm/mach-imx/include/mach/imx53-regs.h @@ -1,10 +1,6 @@ #ifndef __MACH_IMX53_REGS_H #define __MACH_IMX53_REGS_H -#define IMX_TIM1_BASE 0X53FA0000 -#define IMX_WDT_BASE 0X53F98000 -#define IMX_IOMUXC_BASE 0X53FA8000 - #define MX53_IROM_BASE_ADDR 0x0 /* diff --git a/arch/arm/mach-imx/include/mach/imx6-regs.h b/arch/arm/mach-imx/include/mach/imx6-regs.h index eca4fa663a..716e6b4f25 100644 --- a/arch/arm/mach-imx/include/mach/imx6-regs.h +++ b/arch/arm/mach-imx/include/mach/imx6-regs.h @@ -1,10 +1,6 @@ #ifndef __MACH_IMX6_REGS_H #define __MACH_IMX6_REGS_H -#define IMX_TIM1_BASE 0x02098000 -#define IMX_WDT_BASE 0x020bc000 -#define IMX_IOMUXC_BASE 0x020e0000 - #define MX6_AIPS1_ARB_BASE_ADDR 0x02000000 #define MX6_AIPS2_ARB_BASE_ADDR 0x02100000 @@ -12,8 +8,6 @@ #define MX6_ATZ1_BASE_ADDR MX6_AIPS1_ARB_BASE_ADDR #define MX6_ATZ2_BASE_ADDR MX6_AIPS2_ARB_BASE_ADDR -#define IPU_CTRL_BASE_ADDR 0x02400000 - /* slots 0,7 of SDMA reserved, therefore left unused in IPMUX3 */ #define MX6_SPDIF_BASE_ADDR (MX6_ATZ1_BASE_ADDR + 0x04000) #define MX6_ECSPI1_BASE_ADDR (MX6_ATZ1_BASE_ADDR + 0x08000) diff --git a/arch/arm/mach-imx/include/mach/iomux-mx1.h b/arch/arm/mach-imx/include/mach/iomux-mx1.h new file mode 100644 index 0000000000..51317d35d5 --- /dev/null +++ b/arch/arm/mach-imx/include/mach/iomux-mx1.h @@ -0,0 +1,135 @@ +#ifndef __MACH_IOMUX_MX1_H +#define __MACH_IOMUX_MX1_H + +#include <mach/iomux-v1.h> + +/* + * FIXME: This list is not completed. The correct directions are + * missing on some (many) pins + */ +#define PA0_PF_A24 ( GPIO_PORTA | GPIO_PF | 0 ) +#define PA0_AIN_SPI2_CLK ( GPIO_PORTA | GPIO_OUT | GPIO_AIN | 0 ) +#define PA0_AF_ETMTRACESYNC ( GPIO_PORTA | GPIO_AF | 0 ) +#define PA1_AOUT_SPI2_RXD ( GPIO_PORTA | GPIO_IN | GPIO_AOUT | 1 ) +#define PA1_PF_TIN ( GPIO_PORTA | GPIO_PF | 1 ) +#define PA2_PF_PWM0 ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 2 ) +#define PA3_PF_CSI_MCLK ( GPIO_PORTA | GPIO_PF | 3 ) +#define PA4_PF_CSI_D0 ( GPIO_PORTA | GPIO_PF | 4 ) +#define PA5_PF_CSI_D1 ( GPIO_PORTA | GPIO_PF | 5 ) +#define PA6_PF_CSI_D2 ( GPIO_PORTA | GPIO_PF | 6 ) +#define PA7_PF_CSI_D3 ( GPIO_PORTA | GPIO_PF | 7 ) +#define PA8_PF_CSI_D4 ( GPIO_PORTA | GPIO_PF | 8 ) +#define PA9_PF_CSI_D5 ( GPIO_PORTA | GPIO_PF | 9 ) +#define PA10_PF_CSI_D6 ( GPIO_PORTA | GPIO_PF | 10 ) +#define PA11_PF_CSI_D7 ( GPIO_PORTA | GPIO_PF | 11 ) +#define PA12_PF_CSI_VSYNC ( GPIO_PORTA | GPIO_PF | 12 ) +#define PA13_PF_CSI_HSYNC ( GPIO_PORTA | GPIO_PF | 13 ) +#define PA14_PF_CSI_PIXCLK ( GPIO_PORTA | GPIO_PF | 14 ) +#define PA15_PF_I2C_SDA ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 15 ) +#define PA16_PF_I2C_SCL ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 16 ) +#define PA17_AF_ETMTRACEPKT4 ( GPIO_PORTA | GPIO_AF | 17 ) +#define PA17_AIN_SPI2_SS ( GPIO_PORTA | GPIO_AIN | 17 ) +#define PA18_AF_ETMTRACEPKT5 ( GPIO_PORTA | GPIO_AF | 18 ) +#define PA19_AF_ETMTRACEPKT6 ( GPIO_PORTA | GPIO_AF | 19 ) +#define PA20_AF_ETMTRACEPKT7 ( GPIO_PORTA | GPIO_AF | 20 ) +#define PA21_PF_A0 ( GPIO_PORTA | GPIO_PF | 21 ) +#define PA22_PF_CS4 ( GPIO_PORTA | GPIO_PF | 22 ) +#define PA23_PF_CS5 ( GPIO_PORTA | GPIO_PF | 23 ) +#define PA24_PF_A16 ( GPIO_PORTA | GPIO_PF | 24 ) +#define PA24_AF_ETMTRACEPKT0 ( GPIO_PORTA | GPIO_AF | 24 ) +#define PA25_PF_A17 ( GPIO_PORTA | GPIO_PF | 25 ) +#define PA25_AF_ETMTRACEPKT1 ( GPIO_PORTA | GPIO_AF | 25 ) +#define PA26_PF_A18 ( GPIO_PORTA | GPIO_PF | 26 ) +#define PA26_AF_ETMTRACEPKT2 ( GPIO_PORTA | GPIO_AF | 26 ) +#define PA27_PF_A19 ( GPIO_PORTA | GPIO_PF | 27 ) +#define PA27_AF_ETMTRACEPKT3 ( GPIO_PORTA | GPIO_AF | 27 ) +#define PA28_PF_A20 ( GPIO_PORTA | GPIO_PF | 28 ) +#define PA28_AF_ETMPIPESTAT0 ( GPIO_PORTA | GPIO_AF | 28 ) +#define PA29_PF_A21 ( GPIO_PORTA | GPIO_PF | 29 ) +#define PA29_AF_ETMPIPESTAT1 ( GPIO_PORTA | GPIO_AF | 29 ) +#define PA30_PF_A22 ( GPIO_PORTA | GPIO_PF | 30 ) +#define PA30_AF_ETMPIPESTAT2 ( GPIO_PORTA | GPIO_AF | 30 ) +#define PA31_PF_A23 ( GPIO_PORTA | GPIO_PF | 31 ) +#define PA31_AF_ETMTRACECLK ( GPIO_PORTA | GPIO_AF | 31 ) +#define PB8_PF_SD_DAT0 ( GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8 ) +#define PB8_AF_MS_PIO ( GPIO_PORTB | GPIO_AF | 8 ) +#define PB9_PF_SD_DAT1 ( GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9 ) +#define PB9_AF_MS_PI1 ( GPIO_PORTB | GPIO_AF | 9 ) +#define PB10_PF_SD_DAT2 ( GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10 ) +#define PB10_AF_MS_SCLKI ( GPIO_PORTB | GPIO_AF | 10 ) +#define PB11_PF_SD_DAT3 ( GPIO_PORTB | GPIO_PF | GPIO_PUEN | 11 ) +#define PB11_AF_MS_SDIO ( GPIO_PORTB | GPIO_AF | 11 ) +#define PB12_PF_SD_CLK ( GPIO_PORTB | GPIO_PF | GPIO_OUT | 12 ) +#define PB12_AF_MS_SCLK0 ( GPIO_PORTB | GPIO_AF | 12 ) +#define PB13_PF_SD_CMD ( GPIO_PORTB | GPIO_PF | GPIO_OUT | GPIO_PUEN | 13 ) +#define PB13_AF_MS_BS ( GPIO_PORTB | GPIO_AF | 13 ) +#define PB14_AF_SSI_RXFS ( GPIO_PORTB | GPIO_AF | 14 ) +#define PB15_AF_SSI_RXCLK ( GPIO_PORTB | GPIO_AF | 15 ) +#define PB16_AF_SSI_RXDAT ( GPIO_PORTB | GPIO_IN | GPIO_AF | 16 ) +#define PB17_AF_SSI_TXDAT ( GPIO_PORTB | GPIO_OUT | GPIO_AF | 17 ) +#define PB18_AF_SSI_TXFS ( GPIO_PORTB | GPIO_AF | 18 ) +#define PB19_AF_SSI_TXCLK ( GPIO_PORTB | GPIO_AF | 19 ) +#define PB20_PF_USBD_AFE ( GPIO_PORTB | GPIO_PF | 20 ) +#define PB21_PF_USBD_OE ( GPIO_PORTB | GPIO_PF | 21 ) +#define PB22_PFUSBD_RCV ( GPIO_PORTB | GPIO_PF | 22 ) +#define PB23_PF_USBD_SUSPND ( GPIO_PORTB | GPIO_PF | 23 ) +#define PB24_PF_USBD_VP ( GPIO_PORTB | GPIO_PF | 24 ) +#define PB25_PF_USBD_VM ( GPIO_PORTB | GPIO_PF | 25 ) +#define PB26_PF_USBD_VPO ( GPIO_PORTB | GPIO_PF | 26 ) +#define PB27_PF_USBD_VMO ( GPIO_PORTB | GPIO_PF | 27 ) +#define PB28_PF_UART2_CTS ( GPIO_PORTB | GPIO_OUT | GPIO_PF | 28 ) +#define PB29_PF_UART2_RTS ( GPIO_PORTB | GPIO_IN | GPIO_PF | 29 ) +#define PB30_PF_UART2_TXD ( GPIO_PORTB | GPIO_OUT | GPIO_PF | 30 ) +#define PB31_PF_UART2_RXD ( GPIO_PORTB | GPIO_IN | GPIO_PF | 31 ) +#define PC3_PF_SSI_RXFS ( GPIO_PORTC | GPIO_PF | 3 ) +#define PC4_PF_SSI_RXCLK ( GPIO_PORTC | GPIO_PF | 4 ) +#define PC5_PF_SSI_RXDAT ( GPIO_PORTC | GPIO_IN | GPIO_PF | 5 ) +#define PC6_PF_SSI_TXDAT ( GPIO_PORTC | GPIO_OUT | GPIO_PF | 6 ) +#define PC7_PF_SSI_TXFS ( GPIO_PORTC | GPIO_PF | 7 ) +#define PC8_PF_SSI_TXCLK ( GPIO_PORTC | GPIO_PF | 8 ) +#define PC9_PF_UART1_CTS ( GPIO_PORTC | GPIO_OUT | GPIO_PF | 9 ) +#define PC10_PF_UART1_RTS ( GPIO_PORTC | GPIO_IN | GPIO_PF | 10 ) +#define PC11_PF_UART1_TXD ( GPIO_PORTC | GPIO_OUT | GPIO_PF | 11 ) +#define PC12_PF_UART1_RXD ( GPIO_PORTC | GPIO_IN | GPIO_PF | 12 ) +#define PC13_PF_SPI1_SPI_RDY ( GPIO_PORTC | GPIO_PF | 13 ) +#define PC14_PF_SPI1_SCLK ( GPIO_PORTC | GPIO_PF | 14 ) +#define PC15_PF_SPI1_SS ( GPIO_PORTC | GPIO_PF | 15 ) +#define PC16_PF_SPI1_MISO ( GPIO_PORTC | GPIO_PF | 16 ) +#define PC17_PF_SPI1_MOSI ( GPIO_PORTC | GPIO_PF | 17 ) +#define PD6_PF_LSCLK ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 6 ) +#define PD7_PF_REV ( GPIO_PORTD | GPIO_PF | 7 ) +#define PD7_AF_UART2_DTR ( GPIO_PORTD | GPIO_IN | GPIO_AF | 7 ) +#define PD7_AIN_SPI2_SCLK ( GPIO_PORTD | GPIO_AIN | 7 ) +#define PD8_PF_CLS ( GPIO_PORTD | GPIO_PF | 8 ) +#define PD8_AF_UART2_DCD ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 8 ) +#define PD8_AIN_SPI2_SS ( GPIO_PORTD | GPIO_AIN | 8 ) +#define PD9_PF_PS ( GPIO_PORTD | GPIO_PF | 9 ) +#define PD9_AF_UART2_RI ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 9 ) +#define PD9_AOUT_SPI2_RXD ( GPIO_PORTD | GPIO_IN | GPIO_AOUT | 9 ) +#define PD10_PF_SPL_SPR ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 10 ) +#define PD10_AF_UART2_DSR ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 10 ) +#define PD10_AIN_SPI2_TXD ( GPIO_PORTD | GPIO_OUT | GPIO_AIN | 10 ) +#define PD11_PF_CONTRAST ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 11 ) +#define PD12_PF_ACD_OE ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 12 ) +#define PD13_PF_LP_HSYNC ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 13 ) +#define PD14_PF_FLM_VSYNC ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 14 ) +#define PD15_PF_LD0 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 15 ) +#define PD16_PF_LD1 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 16 ) +#define PD17_PF_LD2 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 17 ) +#define PD18_PF_LD3 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 18 ) +#define PD19_PF_LD4 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 19 ) +#define PD20_PF_LD5 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 20 ) +#define PD21_PF_LD6 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 21 ) +#define PD22_PF_LD7 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 22 ) +#define PD23_PF_LD8 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 23 ) +#define PD24_PF_LD9 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 24 ) +#define PD25_PF_LD10 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 25 ) +#define PD26_PF_LD11 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 26 ) +#define PD27_PF_LD12 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 27 ) +#define PD28_PF_LD13 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 28 ) +#define PD29_PF_LD14 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 29 ) +#define PD30_PF_LD15 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 30 ) +#define PD31_PF_TMR2OUT ( GPIO_PORTD | GPIO_PF | 31 ) +#define PD31_BIN_SPI2_TXD ( GPIO_PORTD | GPIO_BIN | 31 ) + +#endif /* __MACH_IOMUX_MX1_H */ diff --git a/arch/arm/mach-imx/include/mach/iomux-mx21.h b/arch/arm/mach-imx/include/mach/iomux-mx21.h index 482c4f2513..203190d1d7 100644 --- a/arch/arm/mach-imx/include/mach/iomux-mx21.h +++ b/arch/arm/mach-imx/include/mach/iomux-mx21.h @@ -13,6 +13,7 @@ #ifndef __MACH_IOMUX_MX21_H__ #define __MACH_IOMUX_MX21_H__ +#include <mach/iomux-v1.h> #include <mach/iomux-mx2x.h> /* Primary GPIO pin functions */ diff --git a/arch/arm/mach-imx/include/mach/iomux-mx27.h b/arch/arm/mach-imx/include/mach/iomux-mx27.h index ff9d6573fa..7d2496708e 100644 --- a/arch/arm/mach-imx/include/mach/iomux-mx27.h +++ b/arch/arm/mach-imx/include/mach/iomux-mx27.h @@ -15,6 +15,7 @@ #ifndef __MACH_IOMUX_MX27_H__ #define __MACH_IOMUX_MX27_H__ +#include <mach/iomux-v1.h> #include <mach/iomux-mx2x.h> /* Primary GPIO pin functions */ diff --git a/arch/arm/mach-imx/include/mach/iomux-mx35.h b/arch/arm/mach-imx/include/mach/iomux-mx35.h index 331b070647..30b94e3b00 100644 --- a/arch/arm/mach-imx/include/mach/iomux-mx35.h +++ b/arch/arm/mach-imx/include/mach/iomux-mx35.h @@ -667,7 +667,7 @@ #define MX35_PAD_LD8__SDMA_SDMA_DEBUG_PC_8 IOMUX_PAD(0x634, 0x1d0, 6, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_LD9__IPU_DISPB_DAT_9 IOMUX_PAD(0x638, 0x1d4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX35_PAD_LD9__GPIO2_9 IOMUX_PAD(0x638, 0x1d4, 5, 0x8e4 0, NO_PAD_CTRL) +#define MX35_PAD_LD9__GPIO2_9 IOMUX_PAD(0x638, 0x1d4, 5, 0x8e4, 0, NO_PAD_CTRL) #define MX35_PAD_LD9__SDMA_SDMA_DEBUG_PC_9 IOMUX_PAD(0x638, 0x1d4, 6, 0x0, 0, NO_PAD_CTRL) #define MX35_PAD_LD10__IPU_DISPB_DAT_10 IOMUX_PAD(0x63c, 0x1d8, 0, 0x0, 0, NO_PAD_CTRL) diff --git a/arch/arm/mach-imx/include/mach/iomux-v1.h b/arch/arm/mach-imx/include/mach/iomux-v1.h new file mode 100644 index 0000000000..55fbcdb94e --- /dev/null +++ b/arch/arm/mach-imx/include/mach/iomux-v1.h @@ -0,0 +1,48 @@ +#ifndef __MACH_IOMUX_V1_H__ +#define __MACH_IOMUX_V1_H__ + +#define GPIO_PIN_MASK 0x1f + +#define GPIO_PORT_SHIFT 5 +#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT) + +#define GPIO_PORTA (0 << GPIO_PORT_SHIFT) +#define GPIO_PORTB (1 << GPIO_PORT_SHIFT) +#define GPIO_PORTC (2 << GPIO_PORT_SHIFT) +#define GPIO_PORTD (3 << GPIO_PORT_SHIFT) +#define GPIO_PORTE (4 << GPIO_PORT_SHIFT) +#define GPIO_PORTF (5 << GPIO_PORT_SHIFT) + +#define GPIO_OUT (1 << 8) +#define GPIO_IN (0 << 8) +#define GPIO_PUEN (1 << 9) + +#define GPIO_PF (1 << 10) +#define GPIO_AF (1 << 11) + +#define GPIO_OCR_SHIFT 12 +#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT) +#define GPIO_AIN (0 << GPIO_OCR_SHIFT) +#define GPIO_BIN (1 << GPIO_OCR_SHIFT) +#define GPIO_CIN (2 << GPIO_OCR_SHIFT) +#define GPIO_GPIO (3 << GPIO_OCR_SHIFT) + +#define GPIO_AOUT_SHIFT 14 +#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT) + +#define GPIO_BOUT_SHIFT 16 +#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT) + +#define GPIO_GIUS (1 << 16) + +void imx_iomuxv1_init(void __iomem *base); + +#endif /* __MACH_IOMUX_V1_H__ */ diff --git a/arch/arm/mach-imx/include/mach/revision.h b/arch/arm/mach-imx/include/mach/revision.h new file mode 100644 index 0000000000..bc6f20a3fb --- /dev/null +++ b/arch/arm/mach-imx/include/mach/revision.h @@ -0,0 +1,22 @@ +#ifndef __MACH_REVISION_H__ +#define __MACH_REVISION_H__ + +/* silicon revisions */ +#define IMX_CHIP_REV_1_0 0x10 +#define IMX_CHIP_REV_1_1 0x11 +#define IMX_CHIP_REV_1_2 0x12 +#define IMX_CHIP_REV_1_3 0x13 +#define IMX_CHIP_REV_2_0 0x20 +#define IMX_CHIP_REV_2_1 0x21 +#define IMX_CHIP_REV_2_2 0x22 +#define IMX_CHIP_REV_2_3 0x23 +#define IMX_CHIP_REV_3_0 0x30 +#define IMX_CHIP_REV_3_1 0x31 +#define IMX_CHIP_REV_3_2 0x32 +#define IMX_CHIP_REV_UNKNOWN 0xff + +int imx_silicon_revision(void); + +void imx_set_silicon_revision(const char *soc, int revision); + +#endif /* __MACH_REVISION_H__ */ diff --git a/arch/arm/mach-imx/iomux-v1.c b/arch/arm/mach-imx/iomux-v1.c index f2dfdb3ffd..f8f90615c6 100644 --- a/arch/arm/mach-imx/iomux-v1.c +++ b/arch/arm/mach-imx/iomux-v1.c @@ -1,5 +1,6 @@ #include <common.h> -#include <mach/imx-regs.h> +#include <io.h> +#include <mach/iomux-v1.h> /* * GPIO Module and I/O Multiplexer @@ -8,23 +9,25 @@ * i.MX1 and i.MXL: 0 <= x <= 3 * i.MX27 : 0 <= x <= 5 */ -#define DDIR(x) __REG2(IMX_GPIO_BASE + 0x00, ((x) & 7) << 8) -#define OCR1(x) __REG2(IMX_GPIO_BASE + 0x04, ((x) & 7) << 8) -#define OCR2(x) __REG2(IMX_GPIO_BASE + 0x08, ((x) & 7) << 8) -#define ICONFA1(x) __REG2(IMX_GPIO_BASE + 0x0c, ((x) & 7) << 8) -#define ICONFA2(x) __REG2(IMX_GPIO_BASE + 0x10, ((x) & 7) << 8) -#define ICONFB1(x) __REG2(IMX_GPIO_BASE + 0x14, ((x) & 7) << 8) -#define ICONFB2(x) __REG2(IMX_GPIO_BASE + 0x18, ((x) & 7) << 8) -#define DR(x) __REG2(IMX_GPIO_BASE + 0x1c, ((x) & 7) << 8) -#define GIUS(x) __REG2(IMX_GPIO_BASE + 0x20, ((x) & 7) << 8) -#define SSR(x) __REG2(IMX_GPIO_BASE + 0x24, ((x) & 7) << 8) -#define ICR1(x) __REG2(IMX_GPIO_BASE + 0x28, ((x) & 7) << 8) -#define ICR2(x) __REG2(IMX_GPIO_BASE + 0x2c, ((x) & 7) << 8) -#define IMR(x) __REG2(IMX_GPIO_BASE + 0x30, ((x) & 7) << 8) -#define ISR(x) __REG2(IMX_GPIO_BASE + 0x34, ((x) & 7) << 8) -#define GPR(x) __REG2(IMX_GPIO_BASE + 0x38, ((x) & 7) << 8) -#define SWR(x) __REG2(IMX_GPIO_BASE + 0x3c, ((x) & 7) << 8) -#define PUEN(x) __REG2(IMX_GPIO_BASE + 0x40, ((x) & 7) << 8) +#define DDIR 0x00 +#define OCR1 0x04 +#define OCR2 0x08 +#define ICONFA1 0x0c +#define ICONFA2 0x10 +#define ICONFB1 0x14 +#define ICONFB2 0x18 +#define DR 0x1c +#define GIUS 0x20 +#define SSR 0x24 +#define ICR1 0x28 +#define ICR2 0x2c +#define IMR 0x30 +#define ISR 0x34 +#define GPR 0x38 +#define SWR 0x3c +#define PUEN 0x40 + +static void __iomem *iomuxv1_base; void imx_gpio_mode(int gpio_mode) { @@ -33,55 +36,81 @@ void imx_gpio_mode(int gpio_mode) unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT; unsigned int aout = (gpio_mode & GPIO_AOUT_MASK) >> GPIO_AOUT_SHIFT; unsigned int bout = (gpio_mode & GPIO_BOUT_MASK) >> GPIO_BOUT_SHIFT; - unsigned int tmp; + void __iomem *portbase = iomuxv1_base + port * 0x100; + uint32_t val; + + if (!iomuxv1_base) + return; /* Pullup enable */ - if(gpio_mode & GPIO_PUEN) - PUEN(port) |= (1 << pin); + val = readl(portbase + PUEN); + if (gpio_mode & GPIO_PUEN) + val |= (1 << pin); else - PUEN(port) &= ~(1 << pin); + val &= ~(1 << pin); + writel(val, portbase + PUEN); /* Data direction */ - if(gpio_mode & GPIO_OUT) - DDIR(port) |= 1 << pin; + val = readl(portbase + DDIR); + if (gpio_mode & GPIO_OUT) + val |= 1 << pin; else - DDIR(port) &= ~(1 << pin); + val &= ~(1 << pin); + writel(val, portbase + DDIR); /* Primary / alternate function */ - if(gpio_mode & GPIO_AF) - GPR(port) |= (1 << pin); + val = readl(portbase + GPR); + if (gpio_mode & GPIO_AF) + val |= (1 << pin); else - GPR(port) &= ~(1 << pin); + val &= ~(1 << pin); + writel(val, portbase + GPR); /* use as gpio? */ - if(!(gpio_mode & (GPIO_PF | GPIO_AF))) - GIUS(port) |= (1 << pin); + val = readl(portbase + GIUS); + if (!(gpio_mode & (GPIO_PF | GPIO_AF))) + val |= (1 << pin); else - GIUS(port) &= ~(1 << pin); + val &= ~(1 << pin); + writel(val, portbase + GIUS); /* Output / input configuration */ if (pin < 16) { - tmp = OCR1(port); - tmp &= ~(3 << (pin * 2)); - tmp |= (ocr << (pin * 2)); - OCR1(port) = tmp; + val = readl(portbase + OCR1); + val &= ~(3 << (pin * 2)); + val |= (ocr << (pin * 2)); + writel(val, portbase + OCR1); + + val = readl(portbase + ICONFA1); + val &= ~(3 << (pin * 2)); + val |= aout << (pin * 2); + writel(val, portbase + ICONFA1); - ICONFA1(port) &= ~(3 << (pin * 2)); - ICONFA1(port) |= aout << (pin * 2); - ICONFB1(port) &= ~(3 << (pin * 2)); - ICONFB1(port) |= bout << (pin * 2); + val = readl(portbase + ICONFB1); + val &= ~(3 << (pin * 2)); + val |= bout << (pin * 2); + writel(val, portbase + ICONFB1); } else { pin -= 16; - tmp = OCR2(port); - tmp &= ~(3 << (pin * 2)); - tmp |= (ocr << (pin * 2)); - OCR2(port) = tmp; + val = readl(portbase + OCR2); + val &= ~(3 << (pin * 2)); + val |= (ocr << (pin * 2)); + writel(val, portbase + OCR2); - ICONFA2(port) &= ~(3 << (pin * 2)); - ICONFA2(port) |= aout << (pin * 2); - ICONFB2(port) &= ~(3 << (pin * 2)); - ICONFB2(port) |= bout << (pin * 2); + val = readl(portbase + ICONFA2); + val &= ~(3 << (pin * 2)); + val |= aout << (pin * 2); + writel(val, portbase + ICONFA2); + + val = readl(portbase + ICONFB2); + val &= ~(3 << (pin * 2)); + val |= bout << (pin * 2); + writel(val, portbase + ICONFB2); } } +void imx_iomuxv1_init(void __iomem *base) +{ + iomuxv1_base = base; +} diff --git a/arch/arm/mach-imx/iomux-v2.c b/arch/arm/mach-imx/iomux-v2.c index 08af54c4c7..dbbb8a26fd 100644 --- a/arch/arm/mach-imx/iomux-v2.c +++ b/arch/arm/mach-imx/iomux-v2.c @@ -16,19 +16,22 @@ #include <common.h> #include <io.h> -#include <mach/imx-regs.h> +#include <init.h> #include <mach/iomux-mx31.h> /* * IOMUX register (base) addresses */ -#define IOMUXINT_OBS1 (IOMUXC_BASE + 0x000) -#define IOMUXINT_OBS2 (IOMUXC_BASE + 0x004) -#define IOMUXGPR (IOMUXC_BASE + 0x008) -#define IOMUXSW_MUX_CTL (IOMUXC_BASE + 0x00C) -#define IOMUXSW_PAD_CTL (IOMUXC_BASE + 0x154) +#define IOMUXINT_OBS1 0x000 +#define IOMUXINT_OBS2 0x004 +#define IOMUXGPR 0x008 +#define IOMUXSW_MUX_CTL 0x00C +#define IOMUXSW_PAD_CTL 0x154 #define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3) + +static void __iomem *base; + /* * set the mode for a IOMUX pin. */ @@ -37,7 +40,10 @@ int imx_iomux_mode(unsigned int pin_mode) u32 field, l, mode, ret = 0; void __iomem *reg; - reg = (void *)(IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK)); + if (!base) + return -EINVAL; + + reg = base + IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK); field = pin_mode & 0x3; mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT; @@ -61,8 +67,11 @@ void imx_iomux_set_pad(enum iomux_pins pin, u32 config) u32 field, l; void __iomem *reg; + if (!base) + return; + pin &= IOMUX_PADNUM_MASK; - reg = (void *)(IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4); + reg = base + IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4; field = (pin + 2) % 3; pr_debug("%s: reg offset = 0x%x, field = %d\n", @@ -83,14 +92,51 @@ void imx_iomux_set_gpr(enum iomux_gp_func gp, int en) { u32 l; - l = readl(IOMUXGPR); + if (!base) + return; + + l = readl(base + IOMUXGPR); if (en) l |= gp; else l &= ~gp; - writel(l, IOMUXGPR); + writel(l, base + IOMUXGPR); } EXPORT_SYMBOL(mxc_iomux_set_gpr); +static int imx_iomux_probe(struct device_d *dev) +{ + base = dev_request_mem_region(dev, 0); + + return 0; +} +static __maybe_unused struct of_device_id imx_iomux_dt_ids[] = { + { + .compatible = "fsl,imx31-iomux", + }, { + /* sentinel */ + } +}; + +static struct platform_device_id imx_iomux_ids[] = { + { + .name = "imx31-iomux", + }, { + /* sentinel */ + }, +}; + +static struct driver_d imx_iomux_driver = { + .name = "imx-iomuxv2", + .probe = imx_iomux_probe, + .of_compatible = DRV_OF_COMPAT(imx_iomux_dt_ids), + .id_table = imx_iomux_ids, +}; + +static int imx_iomux_init(void) +{ + return platform_driver_register(&imx_iomux_driver); +} +postcore_initcall(imx_iomux_init); diff --git a/arch/arm/mach-imx/iomux-v3.c b/arch/arm/mach-imx/iomux-v3.c index 948b610b10..8a6064da6c 100644 --- a/arch/arm/mach-imx/iomux-v3.c +++ b/arch/arm/mach-imx/iomux-v3.c @@ -15,11 +15,11 @@ * */ #include <common.h> +#include <init.h> #include <io.h> #include <mach/iomux-v3.h> -#include <mach/imx-regs.h> -static void __iomem *base = (void *)IMX_IOMUXC_BASE; +static void __iomem *base; /* * configures a single pad in the iomuxer @@ -33,6 +33,9 @@ int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad) u32 pad_ctrl_ofs = (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT; u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT; + if (!base) + return -EINVAL; + debug("%s: mux 0x%08x -> 0x%04x pad: 0x%08x -> 0x%04x sel_inp: 0x%08x -> 0x%04x\n", __func__, mux_mode, mux_ctrl_ofs, pad_ctrl, pad_ctrl_ofs, sel_input, sel_input_ofs); @@ -66,3 +69,39 @@ int mxc_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count) return 0; } EXPORT_SYMBOL(mxc_iomux_v3_setup_multiple_pads); + +static int imx_iomux_probe(struct device_d *dev) +{ + base = dev_request_mem_region(dev, 0); + + return 0; +} + +static __maybe_unused struct of_device_id imx_iomux_dt_ids[] = { + { + .compatible = "fsl,imx35-iomux", + }, { + /* sentinel */ + } +}; + +static struct platform_device_id imx_iomux_ids[] = { + { + .name = "imx35-iomux", + }, { + /* sentinel */ + }, +}; + +static struct driver_d imx_iomux_driver = { + .name = "imx-iomuxv3", + .probe = imx_iomux_probe, + .of_compatible = DRV_OF_COMPAT(imx_iomux_dt_ids), + .id_table = imx_iomux_ids, +}; + +static int imx_iomux_init(void) +{ + return platform_driver_register(&imx_iomux_driver); +} +postcore_initcall(imx_iomux_init); diff --git a/arch/arm/mach-imx/nand.c b/arch/arm/mach-imx/nand.c index fff9a12379..f298a36046 100644 --- a/arch/arm/mach-imx/nand.c +++ b/arch/arm/mach-imx/nand.c @@ -12,20 +12,23 @@ */ #include <common.h> -#include <mach/imx-regs.h> +#include <mach/generic.h> +#include <mach/imx21-regs.h> +#include <mach/imx25-regs.h> +#include <mach/imx27-regs.h> +#include <mach/imx35-regs.h> #include <io.h> -#if defined(CONFIG_ARCH_IMX35) || defined (CONFIG_ARCH_IMX25) - #define RCSR_NFC_FMS (1 << 8) #define RCSR_NFC_4K (1 << 9) #define RCSR_NFC_16BIT_SEL (1 << 14) -void imx_nand_set_layout(int writesize, int datawidth) +static __maybe_unused void imx25_35_nand_set_layout(void __iomem *reg_rcsr, + int writesize, int datawidth) { unsigned int rcsr; - rcsr = readl(IMX_CCM_BASE + CCM_RCSR); + rcsr = readl(reg_rcsr); switch (writesize) { case 512: @@ -52,19 +55,18 @@ void imx_nand_set_layout(int writesize, int datawidth) break; } - writel(rcsr, IMX_CCM_BASE + CCM_RCSR); + writel(rcsr, reg_rcsr); } -#elif defined(CONFIG_ARCH_IMX21) || defined (CONFIG_ARCH_IMX27) - #define FMCR_NF_FMS (1 << 5) #define FMCR_NF_16BIT_SEL (1 << 4) -void imx_nand_set_layout(int writesize, int datawidth) +static __maybe_unused void imx21_27_nand_set_layout(void __iomem *reg_fmcr, + int writesize, int datawidth) { unsigned int fmcr; - fmcr = FMCR; + fmcr = readl(reg_fmcr); switch (writesize) { case 512: @@ -88,23 +90,29 @@ void imx_nand_set_layout(int writesize, int datawidth) break; } - FMCR = fmcr; -} - -#elif defined CONFIG_ARCH_IMX51 || defined CONFIG_ARCH_IMX53 - -void imx_nand_set_layout(int writesize, int datawidth) -{ - /* Just silence the compiler warning below. On i.MX51 we don't - * have external boot. - */ + writel(fmcr, reg_fmcr); } -#else -#warning using empty imx_nand_set_layout(). NAND flash will not work properly if not booting from it - void imx_nand_set_layout(int writesize, int datawidth) { -} - +#ifdef CONFIG_ARCH_IMX21 + if (cpu_is_mx21()) + imx21_27_nand_set_layout((void *)(MX21_SYSCTRL_BASE_ADDR + + 0x14), writesize, datawidth); #endif +#ifdef CONFIG_ARCH_IMX27 + if (cpu_is_mx27()) + imx21_27_nand_set_layout((void *)(MX27_SYSCTRL_BASE_ADDR + + 0x14), writesize, datawidth); +#endif +#ifdef CONFIG_ARCH_IMX25 + if (cpu_is_mx25()) + imx25_35_nand_set_layout((void *)MX25_CCM_BASE_ADDR + + MX25_CCM_RCSR, writesize, datawidth); +#endif +#ifdef CONFIG_ARCH_IMX35 + if (cpu_is_mx35()) + imx25_35_nand_set_layout((void *)MX35_CCM_BASE_ADDR + + MX35_CCM_RCSR, writesize, datawidth); +#endif +} diff --git a/arch/arm/mach-imx/reset_source.c b/arch/arm/mach-imx/reset_source.c deleted file mode 100644 index e7b2a906c5..0000000000 --- a/arch/arm/mach-imx/reset_source.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * (C) Copyright 2012 Juergen Beisert - <kernel@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 <reset_source.h> -#include <mach/imx-regs.h> - -#ifdef CONFIG_ARCH_IMX1 -# define IMX_RESET_SRC_WDOG (1 << 1) -# define IMX_RESET_SRC_HRDRESET (1 << 0) -/* let the compiler sort out useless code on this arch */ -# define IMX_RESET_SRC_WARMSTART 0 -# define IMX_RESET_SRC_COLDSTART 0 -#else - /* WRSR checked for i.MX25, i.MX27, i.MX31, i.MX35 and i.MX51 */ -# define WDOG_WRSR 0x04 - /* valid for i.MX25, i.MX27, i.MX31, i.MX35, i.MX51 */ -# define IMX_RESET_SRC_WARMSTART (1 << 0) - /* valid for i.MX25, i.MX27, i.MX31, i.MX35, i.MX51 */ -# define IMX_RESET_SRC_WDOG (1 << 1) - /* valid for i.MX27, i.MX31, always '0' on i.MX25, i.MX35, i.MX51 */ -# define IMX_RESET_SRC_HRDRESET (1 << 3) - /* valid for i.MX27, i.MX31, always '0' on i.MX25, i.MX35, i.MX51 */ -# define IMX_RESET_SRC_COLDSTART (1 << 4) -#endif - -static unsigned read_detection_register(void) -{ -#ifdef CONFIG_ARCH_IMX1 - return readl(IMX_SYSCTRL_BASE); -#else - return readw(IMX_WDT_BASE + WDOG_WRSR); -#endif -} - -static int imx_detect_reset_source(void) -{ - unsigned reg = read_detection_register(); - - if (reg & IMX_RESET_SRC_COLDSTART) { - set_reset_source(RESET_POR); - return 0; - } - - if (reg & (IMX_RESET_SRC_HRDRESET | IMX_RESET_SRC_WARMSTART)) { - set_reset_source(RESET_RST); - return 0; - } - - if (reg & IMX_RESET_SRC_WDOG) { - set_reset_source(RESET_WDG); - return 0; - } - - /* else keep the default 'unknown' state */ - return 0; -} - -device_initcall(imx_detect_reset_source); diff --git a/arch/arm/mach-mxs/include/mach/gpio.h b/arch/arm/mach-mxs/include/mach/gpio.h index 1e575fa0c4..4e7c8fe87e 100644 --- a/arch/arm/mach-mxs/include/mach/gpio.h +++ b/arch/arm/mach-mxs/include/mach/gpio.h @@ -25,10 +25,8 @@ # include <mach/iomux-imx28.h> #endif +#include <asm-generic/gpio.h> + void imx_gpio_mode(uint32_t); -void gpio_set_value(unsigned, int); -int gpio_direction_input(unsigned); -int gpio_direction_output(unsigned, int); -int gpio_get_value(unsigned); #endif /* __ASM_MACH_GPIO_H */ diff --git a/arch/arm/mach-nomadik/8815.c b/arch/arm/mach-nomadik/8815.c index 81c5ce16d8..c5cac580d2 100644 --- a/arch/arm/mach-nomadik/8815.c +++ b/arch/arm/mach-nomadik/8815.c @@ -29,6 +29,10 @@ static struct clk st8815_clk_48 = { .rate = 48 * 1000 * 1000, }; +static struct clk st8815_clk_2_4 = { + .rate = 2400000, +}; + static struct clk st8815_dummy; void st8815_add_device_sdram(u32 size) @@ -38,6 +42,7 @@ void st8815_add_device_sdram(u32 size) static struct clk_lookup clocks_lookups[] = { CLKDEV_CON_ID("apb_pclk", &st8815_dummy), + CLKDEV_CON_ID("nomadik_mtu", &st8815_clk_2_4), CLKDEV_DEV_ID("uart-pl0110", &st8815_clk_48), CLKDEV_DEV_ID("uart-pl0111", &st8815_clk_48), }; diff --git a/arch/arm/mach-nomadik/include/mach/mtu.h b/arch/arm/mach-nomadik/include/mach/mtu.h deleted file mode 100644 index 9095d86a5a..0000000000 --- a/arch/arm/mach-nomadik/include/mach/mtu.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __ASM_ARCH_MTU_H -#define __ASM_ARCH_MTU_H - -/* - * The MTU device hosts four different counters, with 4 set of - * registers. These are register names. - */ - -#define MTU_IMSC 0x00 /* Interrupt mask set/clear */ -#define MTU_RIS 0x04 /* Raw interrupt status */ -#define MTU_MIS 0x08 /* Masked interrupt status */ -#define MTU_ICR 0x0C /* Interrupt clear register */ - -/* per-timer registers take 0..3 as argument */ -#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */ -#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */ - -#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */ -#define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */ - - -/* bits for the control register */ -#define MTU_CRn_ENA 0x80 -#define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */ -#define MTU_CRn_PRESCALE_MASK 0x0c -#define MTU_CRn_PRESCALE_1 0x00 -#define MTU_CRn_PRESCALE_16 0x04 -#define MTU_CRn_PRESCALE_256 0x08 -#define MTU_CRn_32BITS 0x02 -#define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/ - -/* Other registers are usual amba/primecell registers, currently not used */ -#define MTU_ITCR 0xff0 -#define MTU_ITOP 0xff4 - -#define MTU_PERIPH_ID0 0xfe0 -#define MTU_PERIPH_ID1 0xfe4 -#define MTU_PERIPH_ID2 0xfe8 -#define MTU_PERIPH_ID3 0xfeC - -#define MTU_PCELL0 0xff0 -#define MTU_PCELL1 0xff4 -#define MTU_PCELL2 0xff8 -#define MTU_PCELL3 0xffC - -#endif /* __ASM_ARCH_MTU_H */ diff --git a/arch/arm/mach-nomadik/include/mach/timex.h b/arch/arm/mach-nomadik/include/mach/timex.h deleted file mode 100644 index b2b41faa1b..0000000000 --- a/arch/arm/mach-nomadik/include/mach/timex.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_ARCH_TIMEX_H -#define __ASM_ARCH_TIMEX_H - -#define CLOCK_TICK_RATE 2400000 - -#endif diff --git a/arch/arm/mach-nomadik/timer.c b/arch/arm/mach-nomadik/timer.c index becd36357a..0b8dc866eb 100644 --- a/arch/arm/mach-nomadik/timer.c +++ b/arch/arm/mach-nomadik/timer.c @@ -10,55 +10,16 @@ */ #include <common.h> #include <init.h> -#include <clock.h> #include <io.h> #include <mach/hardware.h> -#include <mach/mtu.h> -#include <mach/timex.h> /* Initial value for SRC control register: all timers use MXTAL/8 source */ #define SRC_CR_INIT_MASK 0x00007fff #define SRC_CR_INIT_VAL 0x2aaa8000 -static u32 nmdk_cycle; /* write-once */ -static __iomem void *mtu_base; - -/* - * clocksource: the MTU device is a decrementing counters, so we negate - * the value being read. - */ -static uint64_t nmdk_read_timer(void) -{ - return nmdk_cycle - readl(mtu_base + MTU_VAL(0)); -} - -static struct clocksource nmdk_clksrc = { - .read = nmdk_read_timer, - .shift = 20, - .mask = CLOCKSOURCE_MASK(32), -}; - -static void nmdk_timer_reset(void) -{ - u32 cr; - - writel(0, mtu_base + MTU_CR(0)); /* off */ - - /* configure load and background-load, and fire it up */ - writel(nmdk_cycle, mtu_base + MTU_LR(0)); - writel(nmdk_cycle, mtu_base + MTU_BGLR(0)); - cr = MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS; - writel(cr, mtu_base + MTU_CR(0)); - writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); -} - -static int nmdk_timer_init(void) +static int st8815_timer_init(void) { u32 src_cr; - unsigned long rate; - - rate = CLOCK_TICK_RATE; /* 2.4MHz */ - nmdk_cycle = (rate + 1000 / 2) / 1000; /* Configure timer sources in "system reset controller" ctrl reg */ src_cr = readl(NOMADIK_SRC_BASE); @@ -66,16 +27,7 @@ static int nmdk_timer_init(void) src_cr |= SRC_CR_INIT_VAL; writel(src_cr, NOMADIK_SRC_BASE); - /* Save global pointer to mtu, used by functions above */ - mtu_base = (void *)NOMADIK_MTU0_BASE; - - /* Init the timer and register clocksource */ - nmdk_timer_reset(); - - nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift); - - init_clock(&nmdk_clksrc); - + add_generic_device("nomadik_mtu", DEVICE_ID_SINGLE, NULL, NOMADIK_MTU0_BASE, 0x1000, IORESOURCE_MEM, NULL); return 0; } -core_initcall(nmdk_timer_init); +coredevice_initcall(st8815_timer_init); diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile index f752bc7986..3a6d50cd81 100644 --- a/arch/arm/mach-omap/Makefile +++ b/arch/arm/mach-omap/Makefile @@ -23,6 +23,7 @@ pbl-$(CONFIG_ARCH_OMAP3) += omap3_core.o omap3_generic.o auxcr.o obj-$(CONFIG_ARCH_OMAP4) += omap4_generic.o omap4_clock.o pbl-$(CONFIG_ARCH_OMAP4) += omap4_generic.o omap4_clock.o obj-$(CONFIG_OMAP3_CLOCK_CONFIG) += omap3_clock.o +pbl-$(CONFIG_OMAP3_CLOCK_CONFIG) += omap3_clock.o obj-$(CONFIG_OMAP_GPMC) += gpmc.o devices-gpmc-nand.o obj-$(CONFIG_SHELL_NONE) += xload.o obj-$(CONFIG_I2C_TWL6030) += omap4_twl6030_mmc.o diff --git a/arch/arm/mach-omap/gpio.c b/arch/arm/mach-omap/gpio.c index 376e9a7d55..49ffbda503 100644 --- a/arch/arm/mach-omap/gpio.c +++ b/arch/arm/mach-omap/gpio.c @@ -133,7 +133,7 @@ static int omap_gpio_probe(struct device_d *dev) omapgpio = xzalloc(sizeof(*omapgpio)); omapgpio->base = dev_request_mem_region(dev, 0); omapgpio->chip.ops = &omap_gpio_ops; - omapgpio->chip.base = -1; + omapgpio->chip.base = dev->id * 32; omapgpio->chip.ngpio = 32; omapgpio->chip.dev = dev; gpiochip_add(&omapgpio->chip); diff --git a/arch/arm/mach-omap/include/mach/gpio.h b/arch/arm/mach-omap/include/mach/gpio.h index 79bf4485b9..306ab4c9f2 100644 --- a/arch/arm/mach-omap/include/mach/gpio.h +++ b/arch/arm/mach-omap/include/mach/gpio.h @@ -1,42 +1 @@ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix <Tom.Rix@windriver.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. - * - * - * This work is derived from the linux 2.6.27 kernel source - * To fetch, use the kernel repository - * git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git - * Use the v2.6.27 tag. - * - * Below is the original's header including its copyright - * - * linux/arch/arm/plat-omap/gpio.c - * - * Support functions for OMAP GPIO - * - * Copyright (C) 2003-2005 Nokia Corporation - * Written by Juha Yrjölä <juha.yrjola@nokia.com> - * - * 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. - */ -#ifndef _GPIO_H -#define _GPIO_H - -void gpio_set_value(unsigned gpio, int value); -int gpio_get_value(unsigned gpio); -int gpio_direction_output(unsigned gpio, int value); -int gpio_direction_input(unsigned gpio); - -#endif /* _GPIO_H_ */ +#include <asm-generic/gpio.h> diff --git a/arch/arm/mach-omap/omap3_generic.c b/arch/arm/mach-omap/omap3_generic.c index 5028e9a9e6..1e1308ec6a 100644 --- a/arch/arm/mach-omap/omap3_generic.c +++ b/arch/arm/mach-omap/omap3_generic.c @@ -512,21 +512,23 @@ const struct gpmc_config omap3_nand_cfg = { .size = GPMC_SIZE_16M, }; +#ifndef __PBL__ static int omap3_gpio_init(void) { add_generic_device("omap-gpio", 0, NULL, 0x48310000, - 0x100, IORESOURCE_MEM, NULL); + 0xf00, IORESOURCE_MEM, NULL); add_generic_device("omap-gpio", 1, NULL, 0x49050000, - 0x100, IORESOURCE_MEM, NULL); + 0xf00, IORESOURCE_MEM, NULL); add_generic_device("omap-gpio", 2, NULL, 0x49052000, - 0x100, IORESOURCE_MEM, NULL); + 0xf00, IORESOURCE_MEM, NULL); add_generic_device("omap-gpio", 3, NULL, 0x49054000, - 0x100, IORESOURCE_MEM, NULL); + 0xf00, IORESOURCE_MEM, NULL); add_generic_device("omap-gpio", 4, NULL, 0x49056000, - 0x100, IORESOURCE_MEM, NULL); + 0xf00, IORESOURCE_MEM, NULL); add_generic_device("omap-gpio", 5, NULL, 0x49058000, - 0x100, IORESOURCE_MEM, NULL); + 0xf00, IORESOURCE_MEM, NULL); return 0; } coredevice_initcall(omap3_gpio_init); +#endif diff --git a/arch/arm/mach-omap/omap4_generic.c b/arch/arm/mach-omap/omap4_generic.c index a159dfcb7e..d7771bf543 100644 --- a/arch/arm/mach-omap/omap4_generic.c +++ b/arch/arm/mach-omap/omap4_generic.c @@ -484,11 +484,27 @@ enum omap_boot_src omap4_bootsrc(void) return OMAP_BOOTSRC_UNKNOWN; } +#define GPIO_MASK 0x1f + +static void __iomem *omap4_get_gpio_base(unsigned gpio) +{ + void __iomem *base; + + if (gpio < 32) + base = (void *)0x4a310000; + else + base = (void *)(0x48053000 + ((gpio & ~GPIO_MASK) << 8)); + + return base; +} + #define I2C_SLAVE 0x12 noinline int omap4_scale_vcores(unsigned vsel0_pin) { + void __iomem *base; unsigned int rev = omap4_revision(); + u32 val = 0; /* For VC bypass only VCOREx_CGF_FORCE is necessary and * VCOREx_CFG_VOLTAGE changes can be discarded @@ -510,8 +526,17 @@ noinline int omap4_scale_vcores(unsigned vsel0_pin) * VSEL1 is grounded on board. So the following selects * VSEL1 = 0 and VSEL0 = 1 */ - gpio_direction_output(vsel0_pin, 0); - gpio_set_value(vsel0_pin, 1); + base = omap4_get_gpio_base(vsel0_pin); + + val = 1 << (vsel0_pin & GPIO_MASK); + writel(val, base + 0x190); + + val = readl(base + 0x134); + val &= ~(1 << (vsel0_pin & GPIO_MASK)); + writel(val, base + 0x134); + + val = 1 << (vsel0_pin & GPIO_MASK); + writel(val, base + 0x194); } /* set VCORE1 force VSEL */ @@ -576,17 +601,17 @@ const struct gpmc_config omap4_nand_cfg = { static int omap4_gpio_init(void) { add_generic_device("omap-gpio", 0, NULL, 0x4a310100, - 0x1000, IORESOURCE_MEM, NULL); + 0xf00, IORESOURCE_MEM, NULL); add_generic_device("omap-gpio", 1, NULL, 0x48055100, - 0x1000, IORESOURCE_MEM, NULL); + 0xf00, IORESOURCE_MEM, NULL); add_generic_device("omap-gpio", 2, NULL, 0x48057100, - 0x1000, IORESOURCE_MEM, NULL); + 0xf00, IORESOURCE_MEM, NULL); add_generic_device("omap-gpio", 3, NULL, 0x48059100, - 0x1000, IORESOURCE_MEM, NULL); + 0xf00, IORESOURCE_MEM, NULL); add_generic_device("omap-gpio", 4, NULL, 0x4805b100, - 0x1000, IORESOURCE_MEM, NULL); + 0xf00, IORESOURCE_MEM, NULL); add_generic_device("omap-gpio", 5, NULL, 0x4805d100, - 0x1000, IORESOURCE_MEM, NULL); + 0xf00, IORESOURCE_MEM, NULL); return 0; } diff --git a/arch/arm/mach-samsung/Kconfig b/arch/arm/mach-samsung/Kconfig index 7312f5e89b..3a4d910001 100644 --- a/arch/arm/mach-samsung/Kconfig +++ b/arch/arm/mach-samsung/Kconfig @@ -175,6 +175,7 @@ config S3C_SDRAM_INIT config S3C_NAND_BOOT bool prompt "Booting from NAND" + depends on ARCH_S3C24xx select MTD select NAND select NAND_S3C24XX diff --git a/arch/arm/mach-samsung/Makefile b/arch/arm/mach-samsung/Makefile index 0ffe3705ef..46393e1725 100644 --- a/arch/arm/mach-samsung/Makefile +++ b/arch/arm/mach-samsung/Makefile @@ -7,4 +7,5 @@ pbl-$(CONFIG_ARCH_S5PCxx) += lowlevel-s5pcxx.o obj-$(CONFIG_ARCH_S3C24xx) += gpio-s3c24x0.o clocks-s3c24xx.o mem-s3c24x0.o obj-$(CONFIG_ARCH_S3C64xx) += gpio-s3c64xx.o clocks-s3c64xx.o mem-s3c64xx.o obj-$(CONFIG_ARCH_S5PCxx) += gpio-s5pcxx.o clocks-s5pcxx.o mem-s5pcxx.o +pbl-$(CONFIG_ARCH_S5PCxx) += mem-s5pcxx.o obj-$(CONFIG_S3C_LOWLEVEL_INIT) += $(obj-lowlevel-y) diff --git a/arch/arm/mach-samsung/include/mach/gpio.h b/arch/arm/mach-samsung/include/mach/gpio.h index 2b4569547e..9e64a841b6 100644 --- a/arch/arm/mach-samsung/include/mach/gpio.h +++ b/arch/arm/mach-samsung/include/mach/gpio.h @@ -23,10 +23,8 @@ # include <mach/iomux-s5pcxx.h> #endif -void gpio_set_value(unsigned, int); -int gpio_direction_input(unsigned); -int gpio_direction_output(unsigned, int); -int gpio_get_value(unsigned); +#include <asm-generic/gpio.h> + void s3c_gpio_mode(unsigned); #endif /* __ASM_MACH_GPIO_H */ diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 5c75e11e98..8aca2a19e3 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -26,6 +26,7 @@ #include <init.h> #include <clock.h> #include <debug_ll.h> +#include <sizes.h> #include <linux/clkdev.h> #include <linux/clk.h> @@ -182,6 +183,12 @@ void versatile_register_uart(unsigned id) amba_apb_device_add(NULL, "uart-pl011", id, start, 4096, NULL, 0); } +void versatile_register_i2c(void) +{ + add_generic_device("versatile-i2c", DEVICE_ID_DYNAMIC, NULL, + VERSATILE_I2C_BASE, SZ_4K, IORESOURCE_MEM, NULL); +} + void __noreturn reset_cpu (unsigned long ignored) { u32 val; @@ -196,3 +203,13 @@ void __noreturn reset_cpu (unsigned long ignored) while(1); } EXPORT_SYMBOL(reset_cpu); + +static int versatile_init(void) +{ + amba_apb_device_add(NULL, "pl061_gpio", 0, 0x101e4000, 4096, NULL, 0); + amba_apb_device_add(NULL, "pl061_gpio", 1, 0x101e5000, 4096, NULL, 0); + amba_apb_device_add(NULL, "pl061_gpio", 2, 0x101e6000, 4096, NULL, 0); + amba_apb_device_add(NULL, "pl061_gpio", 3, 0x101e7000, 4096, NULL, 0); + return 0; +} +coredevice_initcall(versatile_init); diff --git a/arch/arm/mach-versatile/include/mach/gpio.h b/arch/arm/mach-versatile/include/mach/gpio.h new file mode 100644 index 0000000000..306ab4c9f2 --- /dev/null +++ b/arch/arm/mach-versatile/include/mach/gpio.h @@ -0,0 +1 @@ +#include <asm-generic/gpio.h> diff --git a/arch/arm/mach-versatile/include/mach/init.h b/arch/arm/mach-versatile/include/mach/init.h index 878cde0370..b40e4f90b0 100644 --- a/arch/arm/mach-versatile/include/mach/init.h +++ b/arch/arm/mach-versatile/include/mach/init.h @@ -4,5 +4,6 @@ void versatile_add_sdram(u32 size); void versatile_register_uart(unsigned id); +void versatile_register_i2c(void); #endif diff --git a/arch/arm/pbl/.gitignore b/arch/arm/pbl/.gitignore index 3384d8b3c1..d71bb7c286 100644 --- a/arch/arm/pbl/.gitignore +++ b/arch/arm/pbl/.gitignore @@ -3,3 +3,4 @@ piggy.lzo zbarebox zbarebox.bin zbarebox.lds +zbarebox.map diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 87c48ed693..608f19bda1 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -566,7 +566,6 @@ do { \ #define __read_64bit_c0_split(source, sel) \ ({ \ unsigned long long __val; \ - unsigned long __flags; \ \ if (sel == 0) \ __asm__ __volatile__( \ @@ -592,8 +591,6 @@ do { \ #define __write_64bit_c0_split(source, sel, val) \ do { \ - unsigned long __flags; \ - \ if (sel == 0) \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ diff --git a/arch/nios2/lib/longlong.h b/arch/nios2/lib/longlong.h index 4ab928efad..12716828ad 100644 --- a/arch/nios2/lib/longlong.h +++ b/arch/nios2/lib/longlong.h @@ -11,7 +11,7 @@ * 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 have to define the following before including this file: UWtype -- An unsigned type, default type for operations (typically a "word") diff --git a/arch/sandbox/Makefile b/arch/sandbox/Makefile index c0aa8c6ed2..596c8f8309 100644 --- a/arch/sandbox/Makefile +++ b/arch/sandbox/Makefile @@ -39,10 +39,13 @@ archprepare: maketools PHONY += maketools -SDL_LIBS-$(CONFIG_DRIVER_VIDEO_SDL) := $(shell pkg-config sdl --libs) +ifeq ($(CONFIG_DRIVER_VIDEO_SDL),y) +SDL_LIBS := $(shell pkg-config sdl --libs) +endif + cmd_barebox__ = $(CC) -o $@ -Wl,-T,$(barebox-lds) \ -Wl,--start-group $(barebox-common) -Wl,--end-group \ - -lrt -lpthread $(SDL_LIBS-y) + -lrt -lpthread $(SDL_LIBS) common-y += $(BOARD) arch/sandbox/os/ diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c index 0dedfe19f4..36c8d622b6 100644 --- a/arch/sandbox/os/common.c +++ b/arch/sandbox/os/common.c @@ -311,11 +311,6 @@ int main(int argc, char *argv[]) case 'i': break; case 'e': - sprintf(str, "env%d", envno); - ret = add_image(optarg, str); - if (ret) - exit(1); - envno++; break; case 'O': fd = open(optarg, O_WRONLY); @@ -376,6 +371,13 @@ int main(int argc, char *argv[]) exit(1); fdno++; break; + case 'e': + sprintf(str, "env%d", envno); + ret = add_image(optarg, str); + if (ret) + exit(1); + envno++; + break; default: break; } @@ -401,7 +403,7 @@ static void print_usage(const char *prgname) "Usage: %s [OPTIONS]\n" "Start barebox.\n\n" "Options:\n\n" -" -m, " +" -m, --malloc=<size> Start sandbox with a specified malloc-space size in bytes.\n" " -i, --image=<file> Map an image file to barebox. This option can be given\n" " multiple times. The files will show up as\n" " /dev/fd0 ... /dev/fdx under barebox.\n" @@ -434,6 +436,10 @@ static void print_usage(const char *prgname) * * Options can be: * + * -m, --malloc=\<size\> + * + * Start sandbox with a specified malloc-space \<size\> in bytes. + * * -i \<file\> * * Map a \<file\> to barebox. This option can be given multiple times. The \<file\>s diff --git a/commands/Kconfig b/commands/Kconfig index 0ab958a5b2..5e4db90c21 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -230,6 +230,11 @@ config CMD_TFTP barebox can mount tftp as a filesystem. This command is only needed to preserve backward compatibility to the old tftp command. +config CMD_FILETYPE + tristate + select FILETYPE + prompt "filetype" + endmenu menu "console " @@ -509,6 +514,11 @@ endif endmenu +config CMD_BAREBOX_UPDATE + tristate + select BAREBOX_UPDATE + prompt "barebox-update" + config CMD_TIMEOUT tristate prompt "timeout" @@ -651,6 +661,7 @@ if CMD_WD config CMD_WD_DEFAULT_TIMOUT int + default 0 prompt "default timeout" help Define the default timeout value in [seconds] if the first call of diff --git a/commands/Makefile b/commands/Makefile index c6416ca84b..db431d35f1 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -76,4 +76,6 @@ obj-$(CONFIG_CMD_READLINK) += readlink.o obj-$(CONFIG_CMD_LN) += ln.o obj-$(CONFIG_CMD_CLK) += clk.o obj-$(CONFIG_CMD_TFTP) += tftp.o +obj-$(CONFIG_CMD_FILETYPE) += filetype.o +obj-$(CONFIG_CMD_BAREBOX_UPDATE)+= barebox-update.o obj-$(CONFIG_CMD_MIITOOL) += miitool.o diff --git a/commands/automount.c b/commands/automount.c index 4f7aa0e01e..4713932610 100644 --- a/commands/automount.c +++ b/commands/automount.c @@ -65,7 +65,7 @@ BAREBOX_CMD_HELP_END BAREBOX_CMD_START(automount) .cmd = do_automount, - .usage = "automount [OPTIONS] <PATH> <cmd>\n", + .usage = "automount [OPTIONS] <PATH> <cmd>", BAREBOX_CMD_HELP(cmd_automount_help) BAREBOX_CMD_END diff --git a/commands/barebox-update.c b/commands/barebox-update.c new file mode 100644 index 0000000000..f550572c90 --- /dev/null +++ b/commands/barebox-update.c @@ -0,0 +1,86 @@ +/* + * barebox-update.c - update barebox + * + * Copyright (c) 2012 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. + */ +#include <common.h> +#include <command.h> +#include <getopt.h> +#include <malloc.h> +#include <errno.h> +#include <bbu.h> +#include <fs.h> + +static int do_barebox_update(int argc, char *argv[]) +{ + int opt, ret; + struct bbu_data data = {}; + + while ((opt = getopt(argc, argv, "t:yf:ld:")) > 0) { + switch (opt) { + case 'd': + data.devicefile = optarg; + break; + case 'f': + data.force = simple_strtoul(optarg, NULL, 0); + data.flags |= BBU_FLAG_FORCE; + break; + case 't': + data.handler_name = optarg; + break; + case 'y': + data.flags |= BBU_FLAG_YES; + break; + case 'l': + printf("registered update handlers:\n"); + bbu_handlers_list(); + return 0; + default: + return COMMAND_ERROR_USAGE; + } + } + + if (!(argc - optind)) + return COMMAND_ERROR_USAGE; + + data.imagefile = argv[optind]; + + data.image = read_file(data.imagefile, &data.len); + if (!data.image) + return -errno; + + ret = barebox_update(&data); + + free(data.image); + + return ret; +} + +BAREBOX_CMD_HELP_START(barebox_update) +BAREBOX_CMD_HELP_USAGE("barebox_update [OPTIONS] <image>\n") +BAREBOX_CMD_HELP_SHORT("Update barebox to persistent media\n") +BAREBOX_CMD_HELP_OPT("-t <target>", "\n") +BAREBOX_CMD_HELP_OPT("-d <device>", "write image to <device> instead of handler default\n") +BAREBOX_CMD_HELP_OPT(" ", "Can be used for debugging purposes (-d /tmpfile)\n") +BAREBOX_CMD_HELP_OPT("-y\t", "yes. Do not ask for confirmation\n") +BAREBOX_CMD_HELP_OPT("-f <level>", "Set force level\n") +BAREBOX_CMD_HELP_OPT("-l\t", "list registered targets\n") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(barebox_update) + .cmd = do_barebox_update, + .usage = "update barebox", + BAREBOX_CMD_HELP(cmd_barebox_update_help) +BAREBOX_CMD_END diff --git a/commands/bootm.c b/commands/bootm.c index 8e51695d94..98d2e4faf6 100644 --- a/commands/bootm.c +++ b/commands/bootm.c @@ -49,6 +49,11 @@ static LIST_HEAD(handler_list); +/* + * Additional oftree size for the fixed tree + */ +#define OFTREE_SIZE_INCREASE 0x8000 + int register_image_handler(struct image_handler *handler) { list_add_tail(&handler->list, &handler_list); @@ -70,6 +75,7 @@ static int bootm_open_os_uimage(struct image_data *data) if (ret) { printf("Checking data crc failed with %s\n", strerror(-ret)); + uimage_close(data->os); return ret; } } @@ -79,6 +85,7 @@ static int bootm_open_os_uimage(struct image_data *data) if (data->os->header.ih_arch != IH_ARCH) { printf("Unsupported Architecture 0x%x\n", data->os->header.ih_arch); + uimage_close(data->os); return -EINVAL; } @@ -88,8 +95,10 @@ static int bootm_open_os_uimage(struct image_data *data) if (data->os_address != UIMAGE_INVALID_ADDRESS) { data->os_res = uimage_load_to_sdram(data->os, 0, data->os_address); - if (!data->os_res) + if (!data->os_res) { + uimage_close(data->os); return -ENOMEM; + } } return 0; @@ -132,6 +141,7 @@ static int bootm_open_oftree(struct image_data *data, const char *oftree, int nu struct fdt_header *fdt, *fixfdt; int ret; size_t size; + unsigned int align; if (bootm_verbose(data)) printf("Loading oftree from '%s'\n", oftree); @@ -180,12 +190,21 @@ static int bootm_open_oftree(struct image_data *data, const char *oftree, int nu file_type_to_string(ft)); } - fixfdt = xmemalign(4096, size + 0x8000); + /* + * ARM Linux uses a single 1MiB section (with 1MiB alignment) + * for mapping the devicetree, so we are not allowed to cross + * 1MiB boundaries. + */ + align = 1 << fls(size + OFTREE_SIZE_INCREASE - 1); + + fixfdt = xmemalign(align, size + OFTREE_SIZE_INCREASE); memcpy(fixfdt, fdt, size); + + ret = fdt_open_into(fdt, fixfdt, size + OFTREE_SIZE_INCREASE); + free(fdt); - ret = fdt_open_into(fixfdt, fixfdt, size + 0x8000); if (ret) { printf("unable to parse %s\n", oftree); return -ENODEV; diff --git a/commands/filetype.c b/commands/filetype.c new file mode 100644 index 0000000000..20d335bd6d --- /dev/null +++ b/commands/filetype.c @@ -0,0 +1,97 @@ +/* + * (C) Copyright 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 Only + */ + +#include <common.h> +#include <command.h> +#include <fs.h> +#include <filetype.h> +#include <environment.h> +#include <magicvar.h> +#include <getopt.h> +#include <linux/stat.h> +#include <fs.h> + +static int do_filetype(int argc, char *argv[]) +{ + int opt; + enum filetype type; + char *filename = NULL; + int verbose = -1, list = 0; + const char *varname = NULL; + struct stat s; + int ret; + + while ((opt = getopt(argc, argv, "vls:")) > 0) { + switch (opt) { + case 'v': + verbose = 1; + break; + case 'l': + list = 1; + break; + case 's': + varname = optarg; + /* in scripting mode default to nonverbose */ + if (verbose < 0) + verbose = 0; + break; + default: + return COMMAND_ERROR_USAGE; + } + } + + if (verbose < 0) + verbose = 1; + + if (list) { + int i; + + printf("known filetypes:\n"); + + for (i = 1; i < filetype_max; i++) + printf("%-16s: %s\n", file_type_to_short_string(i), + file_type_to_string(i)); + return 0; + } + + if (argc - optind < 1) + return COMMAND_ERROR_USAGE; + + filename = argv[optind]; + + ret = stat(filename, &s); + if (ret) + return ret; + + if (S_ISDIR(s.st_mode)) + return -EISDIR; + + type = file_name_detect_type(filename); + + if (verbose) + printf("%s: %s (%s)\n", filename, + file_type_to_string(type), + file_type_to_short_string(type)); + + if (varname) + setenv(varname, file_type_to_short_string(type)); + + return 0; +} + +BAREBOX_CMD_HELP_START(filetype) +BAREBOX_CMD_HELP_USAGE("filetype [OPTIONS] <file>\n") +BAREBOX_CMD_HELP_SHORT("detect type of a file and export result to a variable\n") +BAREBOX_CMD_HELP_OPT("-v", "verbose\n") +BAREBOX_CMD_HELP_OPT("-s <v>", "set <v> to shortname\n") +BAREBOX_CMD_HELP_OPT("-l", "list known filetypes\n") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(filetype) + .cmd = do_filetype, + .usage = "detect file type", + BAREBOX_CMD_HELP(cmd_filetype_help) +BAREBOX_CMD_END diff --git a/commands/mount.c b/commands/mount.c index f339c37173..be26af84ab 100644 --- a/commands/mount.c +++ b/commands/mount.c @@ -33,7 +33,8 @@ static int do_mount(int argc, char *argv[]) int opt; int ret = 0; struct fs_device_d *fsdev; - char *type = NULL; + const char *type = NULL; + const char *mountpoint, *dev; if (argc == 1) { for_each_fs_device(fsdev) { @@ -56,7 +57,19 @@ static int do_mount(int argc, char *argv[]) if (argc < optind + 2) return COMMAND_ERROR_USAGE; - if ((ret = mount(argv[optind], type, argv[optind + 1]))) { + dev = argv[optind]; + + if (argc == optind + 3) { + /* + * Old behaviour: mount <dev> <type> <mountpoint> + */ + type = argv[optind + 1]; + mountpoint = argv[optind + 2]; + } else { + mountpoint = argv[optind + 1]; + } + + if ((ret = mount(dev, type, mountpoint))) { perror("mount"); return 1; } diff --git a/common/Kconfig b/common/Kconfig index 9210739ee4..d60db80747 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -58,6 +58,9 @@ config GLOBALVAR config STDDEV bool +config BAREBOX_UPDATE + bool + menu "General Settings " config LOCALVERSION @@ -468,17 +471,19 @@ config CONSOLE_FULL prompt "Enable full console support" help This option enables full console support capable of - handling multiple consoles. + handling multiple consoles. Also the full console support + is able to store the output which comes before a console + is registered in a circular buffer which will be printed + once the first console is registered. Recommended for most + usecases. -config CONSOLE_SIMPLE - bool - default y - depends on !CONSOLE_FULL +choice + prompt "Console activation strategy" + depends on CONSOLE_FULL + default CONSOLE_ACTIVATE_FIRST config CONSOLE_ACTIVATE_FIRST - depends on CONSOLE_FULL bool - default y prompt "activate first console on startup" help Normally on startup all consoles are disabled, so you won't @@ -486,13 +491,28 @@ config CONSOLE_ACTIVATE_FIRST enables the first console. config CONSOLE_ACTIVATE_ALL - depends on CONSOLE_FULL - depends on !CONSOLE_ACTIVATE_FIRST bool prompt "activate all consoles on startup" help Enabling this options activates all consoles on startup, so you will get output and a prompt on all consoles simultaneously. + Only the first registered console will have the full startup + log though. + +config CONSOLE_ACTIVATE_NONE + prompt "leave all consoles disabled" + bool + help + Leave all consoles disabled on startup. Board code or environment + is responsible for enabling a console. Otherwise you'll get a working + barebox, you just won't see anything. + +endchoice + +config CONSOLE_SIMPLE + bool + default y + depends on !CONSOLE_FULL config PARTITION bool diff --git a/common/Makefile b/common/Makefile index b74c76b7ae..d82fc998bc 100644 --- a/common/Makefile +++ b/common/Makefile @@ -38,12 +38,13 @@ obj-$(CONFIG_MENU) += menu.o obj-$(CONFIG_PASSWORD) += password.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_FLEXIBLE_BOOTARGS) += bootargs.o +obj-$(CONFIG_BAREBOX_UPDATE) += bbu.o extra-$(CONFIG_MODULES) += module.lds -extra-y += barebox_default_env +extra-y += barebox_default_env barebox_default_env.h ifdef CONFIG_DEFAULT_ENVIRONMENT -$(obj)/startup.o: include/generated/barebox_default_env.h -$(obj)/env.o: include/generated/barebox_default_env.h +$(obj)/startup.o: $(obj)/barebox_default_env.h +$(obj)/env.o: $(obj)/barebox_default_env.h ifeq ($(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW),y) DEFAULT_ENVIRONMENT_PATH = "defaultenv-2/base" @@ -89,18 +90,21 @@ ifeq ($(CONFIG_DEFAULT_ENVIRONMENT_COMPRESSED_LZO),y) barebox_default_env_comp = .lzo endif -$(obj)/barebox_default_env.gz: $(obj)/barebox_default_env +$(obj)/barebox_default_env.gz: $(obj)/barebox_default_env FORCE $(call if_changed,gzip) -$(obj)/barebox_default_env.bz2: $(obj)/barebox_default_env +$(obj)/barebox_default_env.bz2: $(obj)/barebox_default_env FORCE $(call if_changed,bzip2) -$(obj)/barebox_default_env.lzo: $(obj)/barebox_default_env +$(obj)/barebox_default_env.lzo: $(obj)/barebox_default_env FORCE $(call if_changed,lzo) -include/generated/barebox_default_env.h: $(obj)/barebox_default_env$(barebox_default_env_comp) - $(Q)cat $< | (cd $(obj) && $(objtree)/scripts/bin2c default_environment) > $@ - $(Q)echo "const int default_environment_uncompress_size=`stat -c%s $(obj)/barebox_default_env`;" >> $@ +quiet_cmd_env_h = ENVH $@ +cmd_env_h = cat $< | (cd $(obj) && $(objtree)/scripts/bin2c default_environment) > $@; \ + echo "const int default_environment_uncompress_size=`stat -c%s $(obj)/barebox_default_env`;" >> $@ + +$(obj)/barebox_default_env.h: $(obj)/barebox_default_env$(barebox_default_env_comp) FORCE + $(call if_changed,env_h) # dependencies on generated files need to be listed explicitly $(obj)/version.o: include/generated/compile.h diff --git a/common/bbu.c b/common/bbu.c new file mode 100644 index 0000000000..92f8d2b2f4 --- /dev/null +++ b/common/bbu.c @@ -0,0 +1,150 @@ +/* + * bbu.c - barebox update functions + * + * Copyright (c) 2012 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. + */ +#include <common.h> +#include <bbu.h> +#include <linux/list.h> +#include <errno.h> +#include <readkey.h> + +static LIST_HEAD(bbu_image_handlers); + +int bbu_force(struct bbu_data *data, const char *fmt, ...) +{ + va_list args; + + printf("UPDATE: "); + + va_start(args, fmt); + + vprintf(fmt, args); + + va_end(args); + + if (!(data->flags & BBU_FLAG_FORCE)) + goto out; + + if (!data->force) + goto out; + + data->force--; + + printf(" (forced)\n"); + + return 1; +out: + printf("\n"); + + return 0; +} + +int bbu_confirm(struct bbu_data *data) +{ + int key; + + if (data->flags & BBU_FLAG_YES) + return 0; + + printf("update barebox from %s using handler %s to %s (y/n)?\n", + data->imagefile, data->handler_name, + data->devicefile); + + key = read_key(); + + if (key == 'y') + return 0; + + return -EINTR; +} + +static struct bbu_handler *bbu_find_handler(const char *name, unsigned long flags) +{ + struct bbu_handler *handler; + + list_for_each_entry(handler, &bbu_image_handlers, list) { + if (!name) { + if (flags & BBU_HANDLER_FLAG_DEFAULT) + return handler; + continue; + } + + if (!strcmp(handler->name, name)) + return handler; + } + + return NULL; +} + +/* + * do a barebox update with data from *data + */ +int barebox_update(struct bbu_data *data) +{ + struct bbu_handler *handler; + int ret; + + handler = bbu_find_handler(data->handler_name, data->flags); + if (!handler) + return -ENODEV; + + if (!data->devicefile) + data->devicefile = handler->devicefile; + + ret = handler->handler(handler, data); + if (ret == -EINTR) + printf("update aborted\n"); + + if (!ret) + printf("update succeeded\n"); + + return ret; +} + +/* + * print a list of all registered update handlers + */ +void bbu_handlers_list(void) +{ + struct bbu_handler *handler; + + if (list_empty(&bbu_image_handlers)) + printf("(none)\n"); + + list_for_each_entry(handler, &bbu_image_handlers, list) + printf("%s%-11s -> %-10s\n", + handler->flags & BBU_HANDLER_FLAG_DEFAULT ? + "* " : " ", + handler->name, + handler->devicefile); +} + +/* + * register a new update handler + */ +int bbu_register_handler(struct bbu_handler *handler) +{ + if (bbu_find_handler(handler->name, 0)) + return -EBUSY; + + if (handler->flags & BBU_HANDLER_FLAG_DEFAULT && + bbu_find_handler(NULL, BBU_HANDLER_FLAG_DEFAULT)) + return -EBUSY; + + list_add_tail(&handler->list, &bbu_image_handlers); + + return 0; +} diff --git a/common/clock.c b/common/clock.c index 8adbeaff3e..9c7c1ba58c 100644 --- a/common/clock.c +++ b/common/clock.c @@ -135,23 +135,29 @@ uint32_t clocksource_hz2mult(uint32_t hz, uint32_t shift_constant) return (uint32_t)tmp; } -int is_timeout(uint64_t start_ns, uint64_t time_offset_ns) +int is_timeout_non_interruptible(uint64_t start_ns, uint64_t time_offset_ns) { - if (time_offset_ns >= 100 * USECOND) - poller_call(); - if ((int64_t)(start_ns + time_offset_ns - get_time_ns()) < 0) return 1; else return 0; } +EXPORT_SYMBOL(is_timeout_non_interruptible); + +int is_timeout(uint64_t start_ns, uint64_t time_offset_ns) +{ + if (time_offset_ns >= 100 * USECOND) + poller_call(); + + return is_timeout_non_interruptible(start_ns, time_offset_ns); +} EXPORT_SYMBOL(is_timeout); void ndelay(unsigned long nsecs) { uint64_t start = get_time_ns(); - while(!is_timeout(start, nsecs)); + while(!is_timeout_non_interruptible(start, nsecs)); } EXPORT_SYMBOL(ndelay); diff --git a/common/command.c b/common/command.c index 873b3ff6f4..7f2b777939 100644 --- a/common/command.c +++ b/common/command.c @@ -85,7 +85,7 @@ int execute_command(int argc, char **argv) #else printf ("Unknown command '%s'\n", argv[0]); #endif - ret = -1; /* give up after bad command */ + ret = 1; /* give up after bad command */ } getopt_context_restore(&gc); diff --git a/common/console.c b/common/console.c index 3dd964cf6f..fdd5f422dc 100644 --- a/common/console.c +++ b/common/console.c @@ -32,6 +32,7 @@ #include <poller.h> #include <linux/list.h> #include <linux/stringify.h> +#include <debug_ll.h> LIST_HEAD(console_list); EXPORT_SYMBOL(console_list); @@ -44,6 +45,16 @@ EXPORT_SYMBOL(console_list); static int initialized = 0; +#define CONSOLE_BUFFER_SIZE 1024 + +static char console_input_buffer[CONSOLE_BUFFER_SIZE]; +static char console_output_buffer[CONSOLE_BUFFER_SIZE]; + +static struct kfifo __console_input_fifo; +static struct kfifo __console_output_fifo; +static struct kfifo *console_input_fifo = &__console_input_fifo; +static struct kfifo *console_output_fifo = &__console_output_fifo; + static int console_std_set(struct device_d *dev, struct param_d *param, const char *val) { @@ -74,6 +85,17 @@ static int console_std_set(struct device_d *dev, struct param_d *param, dev_param_set_generic(dev, param, active); + if (initialized < CONSOLE_INIT_FULL) { + char ch; + initialized = CONSOLE_INIT_FULL; + PUTS_LL("Switch to console ["); + PUTS_LL(dev_name(dev)); + PUTS_LL("]\n"); + barebox_banner(); + while (kfifo_getc(console_output_fifo, &ch) == 0) + console_putc(CONSOLE_STDOUT, ch); + } + return 0; } @@ -108,16 +130,6 @@ static int console_baudrate_set(struct device_d *dev, struct param_d *param, return 0; } -#define CONSOLE_BUFFER_SIZE 1024 - -static char console_input_buffer[CONSOLE_BUFFER_SIZE]; -static char console_output_buffer[CONSOLE_BUFFER_SIZE]; - -static struct kfifo __console_input_fifo; -static struct kfifo __console_output_fifo; -static struct kfifo *console_input_fifo = &__console_input_fifo; -static struct kfifo *console_output_fifo = &__console_output_fifo; - static void console_init_early(void) { kfifo_init(console_input_fifo, console_input_buffer, @@ -131,8 +143,7 @@ static void console_init_early(void) int console_register(struct console_device *newcdev) { struct device_d *dev = &newcdev->class_dev; - int first = 0; - char ch; + int activate = 0; if (initialized == CONSOLE_UNINITIALIZED) console_init_early(); @@ -150,23 +161,20 @@ int console_register(struct console_device *newcdev) dev_add_param(dev, "active", console_std_set, NULL, 0); - initialized = CONSOLE_INIT_FULL; -#ifdef CONFIG_CONSOLE_ACTIVATE_ALL - dev_set_param(dev, "active", "ioe"); -#endif -#ifdef CONFIG_CONSOLE_ACTIVATE_FIRST - if (list_empty(&console_list)) { - first = 1; - dev_set_param(dev, "active", "ioe"); + if (IS_ENABLED(CONFIG_CONSOLE_ACTIVATE_FIRST)) { + if (list_empty(&console_list)) + activate = 1; + } else if (IS_ENABLED(CONFIG_CONSOLE_ACTIVATE_ALL)) { + activate = 1; } -#endif + + if (newcdev->dev && of_device_is_stdout_path(newcdev->dev)) + activate = 1; list_add_tail(&newcdev->list, &console_list); - while (kfifo_getc(console_output_fifo, &ch) == 0) - console_putc(CONSOLE_STDOUT, ch); - if (first) - barebox_banner(); + if (activate) + dev_set_param(dev, "active", "ioe"); return 0; } @@ -276,6 +284,7 @@ void console_putc(unsigned int ch, char c) case CONSOLE_INITIALIZED_BUFFER: kfifo_putc(console_output_fifo, c); + PUTC_LL(c); return; case CONSOLE_INIT_FULL: diff --git a/common/console_simple.c b/common/console_simple.c index 7ad88d9a99..a4d4315c72 100644 --- a/common/console_simple.c +++ b/common/console_simple.c @@ -2,6 +2,7 @@ #include <common.h> #include <fs.h> #include <errno.h> +#include <debug_ll.h> LIST_HEAD(console_list); EXPORT_SYMBOL(console_list); @@ -85,8 +86,10 @@ EXPORT_SYMBOL(console_puts); void console_putc(unsigned int ch, char c) { - if (!console) + if (!console) { + PUTC_LL(c); return; + } console->putc(console, c); if (c == '\n') diff --git a/common/filetype.c b/common/filetype.c index f37370e457..b8d54f7fe0 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -24,30 +24,43 @@ #include <malloc.h> #include <errno.h> -static const char *filetype_str[] = { - [filetype_unknown] = "unknown", - [filetype_arm_zimage] = "arm Linux zImage", - [filetype_lzo_compressed] = "lzo compressed", - [filetype_arm_barebox] = "arm barebox image", - [filetype_uimage] = "U-Boot uImage", - [filetype_ubi] = "UBI image", - [filetype_jffs2] = "JFFS2 image", - [filetype_gzip] = "gzip compressed", - [filetype_bzip2] = "bzip2 compressed", - [filetype_oftree] = "open firmware flat device tree", - [filetype_aimage] = "Android boot image", - [filetype_sh] = "Bourne Shell", - [filetype_mips_barebox] = "MIPS barebox image", - [filetype_fat] = "FAT filesytem", - [filetype_mbr] = "MBR sector", - [filetype_bmp] = "BMP image", - [filetype_png] = "PNG image", +struct filetype_str { + const char *name; /* human readable filetype */ + const char *shortname; /* short string without spaces for shell scripts */ +}; + +static const struct filetype_str filetype_str[] = { + [filetype_unknown] = { "unknown", "unkown" }, + [filetype_arm_zimage] = { "arm Linux zImage", "arm-zimage" }, + [filetype_lzo_compressed] = { "lzo compressed", "lzo" }, + [filetype_arm_barebox] = { "arm barebox image", "arm-barebox" }, + [filetype_uimage] = { "U-Boot uImage", "u-boot" }, + [filetype_ubi] = { "UBI image", "ubi" }, + [filetype_jffs2] = { "JFFS2 image", "jffs2" }, + [filetype_gzip] = { "gzip compressed", "gzip" }, + [filetype_bzip2] = { "bzip2 compressed", "bzip2" }, + [filetype_oftree] = { "open firmware flat device tree", "dtb" }, + [filetype_aimage] = { "Android boot image", "android" }, + [filetype_sh] = { "Bourne Shell", "sh" }, + [filetype_mips_barebox] = { "MIPS barebox image", "mips-barebox" }, + [filetype_fat] = { "FAT filesytem", "fat" }, + [filetype_mbr] = { "MBR sector", "mbr" }, + [filetype_bmp] = { "BMP image", "bmp" }, + [filetype_png] = { "PNG image", "png" }, }; const char *file_type_to_string(enum filetype f) { if (f < ARRAY_SIZE(filetype_str)) - return filetype_str[f]; + return filetype_str[f].name; + + return NULL; +} + +const char *file_type_to_short_string(enum filetype f) +{ + if (f < ARRAY_SIZE(filetype_str)) + return filetype_str[f].shortname; return NULL; } diff --git a/common/partitions.c b/common/partitions.c index 5682b5119c..24310a3a4f 100644 --- a/common/partitions.c +++ b/common/partitions.c @@ -53,8 +53,8 @@ static int disk_guess_size(struct device_d *dev, struct partition_entry *table) for (i = 0; i < 4; i++) { if (table[i].partition_start != 0) { - size += get_unaligned(&table[i].partition_start) - size; - size += get_unaligned(&table[i].partition_size); + size += get_unaligned_le32(&table[i].partition_start) - size; + size += get_unaligned_le32(&table[i].partition_size); } } @@ -98,8 +98,8 @@ static void __maybe_unused try_dos_partition(struct block_device *blk, blk->num_blocks = disk_guess_size(blk->dev, table); for (i = 0; i < 4; i++) { - pentry.first_sec = get_unaligned(&table[i].partition_start); - pentry.size = get_unaligned(&table[i].partition_size); + pentry.first_sec = get_unaligned_le32(&table[i].partition_start); + pentry.size = get_unaligned_le32(&table[i].partition_size); if (pentry.first_sec != 0) { pd->parts[pd->used_entries].first_sec = pentry.first_sec; diff --git a/common/startup.c b/common/startup.c index 775f97ca87..7bb3c73c12 100644 --- a/common/startup.c +++ b/common/startup.c @@ -39,7 +39,7 @@ extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[], __barebox_initcalls_end[]; #ifdef CONFIG_DEFAULT_ENVIRONMENT -#include <generated/barebox_default_env.h> +#include "barebox_default_env.h" #ifdef CONFIG_DEFAULT_ENVIRONMENT_COMPRESSED #include <uncompress.h> diff --git a/common/uimage.c b/common/uimage.c index b58dff1dd2..344bd61c06 100644 --- a/common/uimage.c +++ b/common/uimage.c @@ -225,8 +225,8 @@ void uimage_close(struct uimage_handle *handle) free(handle->name); free(handle); - if (IS_BUILTIN(CONFIG_FS_TFTP) && !stat("/.uimage_tmp", &s)) - unlink("/.uimage_tmp"); + if (IS_BUILTIN(CONFIG_FS_TFTP) && !stat(uimage_tmp, &s)) + unlink(uimage_tmp); } EXPORT_SYMBOL(uimage_close); diff --git a/defaultenv-2/base/bin/boot b/defaultenv-2/base/bin/boot index 103eb8767e..ebbd951703 100644 --- a/defaultenv-2/base/bin/boot +++ b/defaultenv-2/base/bin/boot @@ -45,7 +45,7 @@ fi if [ -n "$scr" ]; then if [ ! -f /env/boot/$scr ]; then - echo -e "/env/boot/$scr does not exist.Valid choices:\n$sources" + echo -e "/env/boot/$scr does not exist. Valid choices:\n$sources" exit fi /env/boot/$scr diff --git a/defaultenv-2/base/bin/bootargs-ip-barebox b/defaultenv-2/base/bin/bootargs-ip-barebox deleted file mode 100644 index 5a3b984069..0000000000 --- a/defaultenv-2/base/bin/bootargs-ip-barebox +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# pass barebox ip settings for eth0 to Linux - -ifup eth0 - -global.linux.bootargs.dyn.ip="ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask::eth0:" diff --git a/defaultenv-2/base/bin/bootargs-ip-dhcp b/defaultenv-2/base/bin/bootargs-ip-dhcp deleted file mode 100644 index dec8ae452a..0000000000 --- a/defaultenv-2/base/bin/bootargs-ip-dhcp +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -# Do dhcp in Linux - -global.linux.bootargs.dyn.ip="ip=dhcp" diff --git a/defaultenv-2/base/bin/bootargs-ip-none b/defaultenv-2/base/bin/bootargs-ip-none deleted file mode 100644 index 88aaa21a78..0000000000 --- a/defaultenv-2/base/bin/bootargs-ip-none +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -# disable ip setup in Linux - -global.linux.bootargs.dyn.ip="ip=none" diff --git a/defaultenv-2/base/bin/bootargs-root-disk b/defaultenv-2/base/bin/bootargs-root-disk deleted file mode 100644 index aa60cf33f0..0000000000 --- a/defaultenv-2/base/bin/bootargs-root-disk +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -usage="$0 [OPTIONS]\n -p <partition>\n -t <fstype>" - -while getopt "p:t:h" opt; do - if [ ${opt} = p ]; then - part=${OPTARG} - elif [ ${opt} = t ]; then - fstype=${OPTARG} - elif [ ${opt} = h ]; then - echo -e "$usage" - exit 0 - fi -done - -if [ -z "${part}" ]; then - echo "$0: no partition given" - exit 1 -fi - -if [ -z "${fstype}" ]; then - echo "$0: no filesystem type given" - exit 1 -fi - -global.linux.bootargs.dyn.root="root=/dev/$part rootfstype=$fstype rootwait" diff --git a/defaultenv-2/base/bin/bootargs-root-ext b/defaultenv-2/base/bin/bootargs-root-ext deleted file mode 100644 index dbdddb9fcc..0000000000 --- a/defaultenv-2/base/bin/bootargs-root-ext +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -while getopt "m:r:" opt; do - if [ ${opt} = m ]; then - part=${OPTARG} - fi - if [ ${opt} = r ]; then - type=${OPTARG} - fi -done - -global.linux.bootargs.dyn.root="root=/dev/$part rootfstype=ext$type rootwait" diff --git a/defaultenv-2/base/bin/bootargs-root-initrd b/defaultenv-2/base/bin/bootargs-root-initrd deleted file mode 100644 index cc711a1051..0000000000 --- a/defaultenv-2/base/bin/bootargs-root-initrd +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -rdinit="/sbin/init" - -usage="$0 [OPTIONS]\n -i <rdinitpath> (/sbin/init)" - -while getopt "i:h" opt; do - if [ ${opt} = i ]; then - rdinit=${OPTARG} - elif [ ${opt} = h ]; then - echo -e "$usage" - exit 0 - fi -done - -global.linux.bootargs.dyn.root="root=/dev/ram0 rdinit=${rdinit}" diff --git a/defaultenv-2/base/bin/bootargs-root-jffs2 b/defaultenv-2/base/bin/bootargs-root-jffs2 deleted file mode 100644 index a8eb5e7bb8..0000000000 --- a/defaultenv-2/base/bin/bootargs-root-jffs2 +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -mtd= - -usage="$0 [OPTIONS]\n -m <mtd>" - -while getopt "m:h" opt; do - if [ ${opt} = m ]; then - mtd=${OPTARG} - elif [ ${opt} = h ]; then - echo -e "$usage" - exit 0 - fi -done - -if [ -z "$mtd" ]; then - echo -e "$usage" - exit 1 -fi - -global.linux.bootargs.dyn.root="root=$mtd rootfstype=jffs2" diff --git a/defaultenv-2/base/bin/bootargs-root-nfs b/defaultenv-2/base/bin/bootargs-root-nfs deleted file mode 100644 index 355f93dbe3..0000000000 --- a/defaultenv-2/base/bin/bootargs-root-nfs +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -usage="$0 [OPTIONS]\n -n <nfspath>\n -s <serverip>" - -while getopt "n:s:h" opt; do - if [ ${opt} = n ]; then - nfsroot=${OPTARG} - elif [ ${opt} = s ]; then - serverip=${OPTARG} - elif [ ${opt} = h ]; then - echo -e "$usage" - exit 0 - fi -done - -if [ -n ${serverip} ]; then - nfsroot="$serverip:$nfsroot" -fi - -global.linux.bootargs.dyn.root="root=/dev/nfs nfsroot=$nfsroot,v3,tcp" diff --git a/defaultenv-2/base/bin/bootargs-root-ubi b/defaultenv-2/base/bin/bootargs-root-ubi deleted file mode 100644 index 4260336915..0000000000 --- a/defaultenv-2/base/bin/bootargs-root-ubi +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh - -ubiroot=root -mtd= - -usage="$0 [OPTIONS]\n -r <ubiroot> (root)\n -m <mtd>" - -while getopt "m:r:h" opt; do - if [ ${opt} = r ]; then - ubiroot=${OPTARG} - elif [ ${opt} = m ]; then - mtd=${OPTARG} - elif [ ${opt} = h ]; then - echo -e "$usage" - exit 0 - fi -done - -if [ -z "$mtd" ]; then - echo -e "$usage" - exit 1 -fi - -global.linux.bootargs.dyn.root="root=ubi0:$ubiroot ubi.mtd=$mtd rootfstype=ubifs" diff --git a/defaultenv-2/base/bin/init b/defaultenv-2/base/bin/init index 8e8871d10a..bb4abcdec9 100644 --- a/defaultenv-2/base/bin/init +++ b/defaultenv-2/base/bin/init @@ -8,12 +8,18 @@ global autoboot_timeout=3 global boot.default=net global allow_color=true global linux.bootargs.base -#linux.bootargs.dyn.* will be clearer at the beginning of boot +#linux.bootargs.dyn.* will be cleared at the beginning of boot global linux.bootargs.dyn.ip global linux.bootargs.dyn.root global editcmd=sedit -/env/init/general +/env/config + +if [ ${global.allow_color} = "true" ]; then + export PS1="\e[1;32mbarebox@\e[1;36m\h:\w\e[0m " +else + export PS1="barebox@\h:\w " +fi if [ -e /env/menu ]; then echo -e -n "\nHit m for menu or any other key to stop autoboot: " diff --git a/defaultenv-2/base/boot/initrd b/defaultenv-2/base/boot/initrd deleted file mode 100644 index 7c44d07a6e..0000000000 --- a/defaultenv-2/base/boot/initrd +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -if [ "$1" = menu ]; then - boot-menu-add-entry "$0" "kernel + initrd via tftp" - exit -fi - -path="/mnt/tftp" -global.bootm.image="${path}/${global.user}-linux-${global.hostname}" -global.bootm.initrd="${path}/initramfs" -bootargs-root-initrd -#global.bootm.oftree=<path to oftree> - -global.linux.bootargs.dyn.root="root=/dev/ram0" - -#bootargs-root-nfs -n "<path on server>" -s <serverip> -#bootargs-root-ubi -r <volume> -m <mtdname> diff --git a/defaultenv-2/base/boot/net b/defaultenv-2/base/boot/net index 922bef12bb..90c25aa147 100644 --- a/defaultenv-2/base/boot/net +++ b/defaultenv-2/base/boot/net @@ -11,4 +11,4 @@ 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 -bootargs-root-nfs -n "$nfsroot" +global.linux.bootargs.dyn.root="root=/dev/nfs nfsroot=$nfsroot,v3,tcp" diff --git a/defaultenv-2/base/config b/defaultenv-2/base/config new file mode 100644 index 0000000000..189e5a68f2 --- /dev/null +++ b/defaultenv-2/base/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=net + +# base bootargs +#global.linux.bootargs.base="console=ttyS0,115200" diff --git a/defaultenv-2/base/data/boot-template b/defaultenv-2/base/data/boot-template index 1cacf18bf7..9297499036 100644 --- a/defaultenv-2/base/data/boot-template +++ b/defaultenv-2/base/data/boot-template @@ -11,6 +11,4 @@ global.bootm.image=<path to image> #bootargs-ip -#bootargs-root-nfs -n "<path on server>" -s <serverip> -#bootargs-root-jffs2 -m <mtdname> -#bootargs-root-ubi -r <volume> -m <mtdname> +global.linux.bootargs.dyn.root="root=<rootfs here>" diff --git a/defaultenv-2/base/init/bootargs-base b/defaultenv-2/base/init/bootargs-base deleted file mode 100644 index 8e588ad43d..0000000000 --- a/defaultenv-2/base/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=ttyS0,115200" diff --git a/defaultenv-2/base/init/general b/defaultenv-2/base/init/general deleted file mode 100644 index 98a92d1b80..0000000000 --- a/defaultenv-2/base/init/general +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "general config settings" - exit -fi - -# user (used for network filenames) -global.user=sha - -# timeout in seconds before the default boot entry is started -global.autoboot_timeout=3 - -# default boot entry (one of /env/boot/*) -global.boot.default=net diff --git a/defaultenv-2/base/init/hostname b/defaultenv-2/base/init/hostname deleted file mode 100644 index 57a2c94798..0000000000 --- a/defaultenv-2/base/init/hostname +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$1" = menu ]; then - init-menu-add-entry "$0" "hostname" - exit -fi - -global.hostname=generic diff --git a/defaultenv-2/base/init/prompt b/defaultenv-2/base/init/prompt deleted file mode 100644 index 11dce9fe0e..0000000000 --- a/defaultenv-2/base/init/prompt +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -if [ ${global.allow_color} = "true" ]; then - export PS1="\e[1;32mbarebox@\e[1;36m\h:\w\e[0m " -else - export PS1="barebox@\h:\w " -fi diff --git a/defaultenv-2/menu/menu/boot-menu-add-entry b/defaultenv-2/menu/menu/boot-menu-add-entry index 7e1d9c6d58..f06c524034 100644 --- a/defaultenv-2/menu/menu/boot-menu-add-entry +++ b/defaultenv-2/menu/menu/boot-menu-add-entry @@ -1,5 +1,5 @@ #!/bin/sh -menu -e -a -m boot -c "boot $1" -d "Boot: ${GREEN}$2${NC}" +menu -e -a -m boot -c "boot -v $1; echo; readline \"press enter to continue\" a " -d "Boot: ${GREEN}$2${NC}" menu -e -a -m boot_entries_edit -c "$global.editcmd /env/boot/$1" -d "${GREEN}$2${NC}" menu -e -a -m boot_entries_remove -c "rm /env/boot/$1" -d "${GREEN}$2${NC}" diff --git a/defaultenv-2/menu/menu/mainmenu b/defaultenv-2/menu/menu/mainmenu index 5bd7027e2a..c74cc9c767 100644 --- a/defaultenv-2/menu/menu/mainmenu +++ b/defaultenv-2/menu/menu/mainmenu @@ -15,6 +15,7 @@ while true; do boot-entries-collect menu -e -a -R -m boot -c "$global.editcmd /env/network/eth0" -d "Network settings" + menu -e -a -R -m boot -c "$global.editcmd /env/config" -d "Config settings" menu -e -a -m boot -c "boot-entries-edit" -d "Edit boot entries" menu -e -a -m boot -c "init-entries-edit" -d "Edit init entries" menu -e -a -R -m boot -c "saveenv || echo \"failed to save environment\" && sleep 2" -d "Save settings" diff --git a/drivers/Kconfig b/drivers/Kconfig index d0b5e3abdb..f6446e8413 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -11,6 +11,7 @@ source "drivers/usb/Kconfig" source "drivers/video/Kconfig" source "drivers/mci/Kconfig" source "drivers/clk/Kconfig" +source "drivers/clocksource/Kconfig" source "drivers/mfd/Kconfig" source "drivers/misc/Kconfig" source "drivers/led/Kconfig" @@ -21,5 +22,6 @@ source "drivers/pwm/Kconfig" source "drivers/dma/Kconfig" source "drivers/gpio/Kconfig" source "drivers/of/Kconfig" +source "drivers/w1/Kconfig" endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 2a1f8b0f23..1fddee0dd4 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_I2C) += i2c/ obj-$(CONFIG_MCI) += mci/ obj-$(CONFIG_VIDEO) += video/ obj-y += clk/ +obj-y += clocksource/ obj-y += mfd/ obj-$(CONFIG_LED) += led/ obj-y += eeprom/ @@ -21,3 +22,4 @@ obj-y += dma/ obj-y += watchdog/ obj-y += gpio/ obj-$(CONFIG_OFDEVICE) += of/ +obj-$(CONFIG_W1) += w1/ diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index f0a40b69c5..d1ab53ca72 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -157,6 +157,13 @@ int amba_device_add(struct amba_device *dev) if (ret) goto err_release; + if (IS_ENABLED(CONFIG_PARAMETER)) { + char str[16]; + + sprintf(str, "0x%08x", dev->periphid); + dev_add_param_fixed(&dev->dev, "periphid", str); + } + return ret; err_release: release_region(res); diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 1dd139f7a3..69782d2e7b 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -11,7 +11,7 @@ LIST_HEAD(bus_list); EXPORT_SYMBOL(bus_list); -struct bus_type *get_bus_by_name(const char *name) +static struct bus_type *get_bus_by_name(const char *name) { struct bus_type *bus; diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 3f5f6a2a15..dc2df91522 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -387,6 +387,21 @@ void devices_shutdown(void) } } +int dev_get_drvdata(struct device_d *dev, unsigned long *data) +{ + if (dev->of_id_entry) { + *data = dev->of_id_entry->data; + return 0; + } + + if (dev->id_entry) { + *data = dev->id_entry->driver_data; + return 0; + } + + return -ENODEV; +} + #ifdef CONFIG_CMD_DEVINFO static int do_devinfo_subtree(struct device_d *dev, int depth) { @@ -421,21 +436,6 @@ static int do_devinfo_subtree(struct device_d *dev, int depth) return 0; } -int dev_get_drvdata(struct device_d *dev, unsigned long *data) -{ - if (dev->of_id_entry) { - *data = dev->of_id_entry->data; - return 0; - } - - if (dev->id_entry) { - *data = dev->id_entry->driver_data; - return 0; - } - - return -ENODEV; -} - static int do_devinfo(int argc, char *argv[]) { struct device_d *dev; diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 13b4620506..ea4e37bbb7 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -66,18 +66,6 @@ int platform_device_register(struct device_d *new_device) { new_device->bus = &platform_bus; - if (new_device->resource) { - struct device_d *dev; - - bus_for_each_device(new_device->bus, dev) { - if (!dev->resource) - continue; - if (dev->resource->start == new_device->resource->start) { - return -EBUSY; - } - } - } - return register_device(new_device); } diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 39a75a4e4a..3cc7163829 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -1,2 +1,3 @@ -obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed.o clk-divider.o clk-fixed-factor.o clk-mux.o +obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed.o clk-divider.o clk-fixed-factor.o \ + clk-mux.o clk-gate.o obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c new file mode 100644 index 0000000000..cf1bb1af62 --- /dev/null +++ b/drivers/clk/clk-gate.c @@ -0,0 +1,78 @@ +/* + * clk-gate.c - generic barebox clock support. Based on Linux clk support + * + * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix + * + * 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 <io.h> +#include <malloc.h> +#include <linux/clk.h> +#include <linux/err.h> + +struct clk_gate { + struct clk clk; + void __iomem *reg; + int shift; + const char *parent; +}; + +static int clk_gate_enable(struct clk *clk) +{ + struct clk_gate *g = container_of(clk, struct clk_gate, clk); + u32 val; + + val = readl(g->reg); + val |= 1 << g->shift; + writel(val, g->reg); + + return 0; +} + +static void clk_gate_disable(struct clk *clk) +{ + struct clk_gate *g = container_of(clk, struct clk_gate, clk); + u32 val; + + val = readl(g->reg); + val &= ~(1 << g->shift); + writel(val, g->reg); +} + +struct clk_ops clk_gate_ops = { + .enable = clk_gate_enable, + .disable = clk_gate_disable, +}; + +struct clk *clk_gate(const char *name, const char *parent, void __iomem *reg, + u8 shift) +{ + struct clk_gate *g = xzalloc(sizeof(*g)); + int ret; + + g->parent = parent; + g->reg = reg; + g->shift = shift; + g->clk.ops = &clk_gate_ops; + g->clk.name = name; + g->clk.parent_names = &g->parent; + g->clk.num_parents = 1; + + ret = clk_register(&g->clk); + if (ret) { + free(g); + return ERR_PTR(ret); + } + + return &g->clk; +} diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 1ae822ffa6..5441eeb8dc 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -178,6 +178,27 @@ struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, } EXPORT_SYMBOL(clkdev_alloc); +int clk_register_clkdev(struct clk *clk, const char *con_id, + const char *dev_fmt, ...) +{ + struct clk_lookup *cl; + va_list ap; + + if (IS_ERR(clk)) + return PTR_ERR(clk); + + va_start(ap, dev_fmt); + cl = clkdev_alloc(clk, con_id, dev_fmt, ap); + va_end(ap); + + if (!cl) + return -ENOMEM; + + clkdev_add(cl); + + return 0; +} + int clk_add_alias(const char *alias, const char *alias_dev_name, char *id, struct device_d *dev) { diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig new file mode 100644 index 0000000000..09acdd74c5 --- /dev/null +++ b/drivers/clocksource/Kconfig @@ -0,0 +1,11 @@ +config ARM_SMP_TWD + bool + depends on ARM && CPU_V7 + +config CLOCKSOURCE_BCM2835 + bool + depends on ARCH_BCM2835 + +config CLOCKSOURCE_NOMADIK + bool + depends on ARM diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile new file mode 100644 index 0000000000..92d7c1344a --- /dev/null +++ b/drivers/clocksource/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_ARM_SMP_TWD) += arm_smp_twd.o +obj-$(CONFIG_CLOCKSOURCE_BCM2835) += bcm2835.o +obj-$(CONFIG_CLOCKSOURCE_NOMADIK) += nomadik.o diff --git a/drivers/clocksource/arm_smp_twd.c b/drivers/clocksource/arm_smp_twd.c new file mode 100644 index 0000000000..746d566441 --- /dev/null +++ b/drivers/clocksource/arm_smp_twd.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPL v2 + */ +#include <common.h> +#include <init.h> +#include <clock.h> +#include <io.h> +#include <driver.h> +#include <errno.h> +#include <linux/clk.h> +#include <linux/err.h> + +#define TWD_TIMER_LOAD 0x00 +#define TWD_TIMER_COUNTER 0x04 +#define TWD_TIMER_CONTROL 0x08 +#define TWD_TIMER_INTSTAT 0x0C + +#define TWD_TIMER_CONTROL_ENABLE (1 << 0) +#define TWD_TIMER_CONTROL_ONESHOT (0 << 1) +#define TWD_TIMER_CONTROL_PERIODIC (1 << 1) +#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2) + +#define TWD_TIMER_CONTROL_PRESC(x) (((x) & 0xff) << 8) + +static __iomem void *twd_base; +static struct clk *twd_clk; + +static uint64_t smp_twd_read(void) +{ + return ~readl(twd_base + TWD_TIMER_COUNTER); +} + +static struct clocksource smp_twd_clksrc = { + .read = smp_twd_read, + .shift = 20, + .mask = CLOCKSOURCE_MASK(32), +}; + +#define SMP_TWD_MAX_FREQ (25 *1000 * 1000) + +static int smp_twd_probe(struct device_d *dev) +{ + u32 tick_rate; + u32 val; + int ret; + u32 presc = 0; + + twd_clk = clk_get(dev, NULL); + if (IS_ERR(twd_clk)) { + ret = PTR_ERR(twd_clk); + dev_err(dev, "clock not found: %d\n", ret); + return ret; + } + + ret = clk_enable(twd_clk); + if (ret < 0) { + dev_err(dev, "clock failed to enable: %d\n", ret); + clk_put(twd_clk); + return ret; + } + + twd_base = dev_request_mem_region(dev, 0); + + tick_rate = clk_get_rate(twd_clk); + if (tick_rate > SMP_TWD_MAX_FREQ) { + presc = tick_rate / SMP_TWD_MAX_FREQ; + if (presc) + presc--; + presc = min((u32)0xff, presc); + tick_rate /= presc + 1; + } + + val = TWD_TIMER_CONTROL_PRESC(presc) | + TWD_TIMER_CONTROL_PERIODIC; + writel(val, twd_base + TWD_TIMER_CONTROL); + + writel(0xffffffff, twd_base + TWD_TIMER_LOAD); + + val = readl(twd_base + TWD_TIMER_CONTROL); + val |= TWD_TIMER_CONTROL_ENABLE; + writel(val, twd_base + TWD_TIMER_CONTROL); + + smp_twd_clksrc.mult = clocksource_hz2mult(tick_rate, smp_twd_clksrc.shift); + + init_clock(&smp_twd_clksrc); + + return 0; +} + +static struct driver_d smp_twd_driver = { + .name = "smp_twd", + .probe = smp_twd_probe, +}; + +static int smp_twd_init(void) +{ + return platform_driver_register(&smp_twd_driver); +} +coredevice_initcall(smp_twd_init); diff --git a/drivers/clocksource/bcm2835.c b/drivers/clocksource/bcm2835.c new file mode 100644 index 0000000000..d5fe0f03a2 --- /dev/null +++ b/drivers/clocksource/bcm2835.c @@ -0,0 +1,90 @@ +/* + * Author: Carlo Caione <carlo@carlocaione.org> + * + * Based on clocksource for nomadik + * + * 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 <clock.h> +#include <io.h> +#include <init.h> +#include <driver.h> +#include <errno.h> +#include <linux/clk.h> +#include <linux/err.h> + +/* Registers */ +#define ST_CLO 0x04 + +static __iomem void *stc_base; + +static uint64_t stc_read_cycles(void) +{ + return readl(stc_base + ST_CLO); +} + +static struct clocksource bcm2835_stc = { + .read = stc_read_cycles, + .mask = CLOCKSOURCE_MASK(32), +}; + +static int bcm2835_cs_probe(struct device_d *dev) +{ + static struct clk *stc_clk; + u32 rate; + int ret; + + stc_clk = clk_get(dev, NULL); + if (IS_ERR(stc_clk)) { + ret = PTR_ERR(stc_clk); + dev_err(dev, "clock not found: %d\n", ret); + return ret; + } + + ret = clk_enable(stc_clk); + if (ret) { + dev_err(dev, "clock failed to enable: %d\n", ret); + clk_put(stc_clk); + return ret; + } + + rate = clk_get_rate(stc_clk); + stc_base = dev_request_mem_region(dev, 0); + + clocks_calc_mult_shift(&bcm2835_stc.mult, &bcm2835_stc.shift, rate, NSEC_PER_SEC, 60); + init_clock(&bcm2835_stc); + + return 0; +} + +static __maybe_unused struct of_device_id bcm2835_cs_dt_ids[] = { + { + .compatible = "brcm,bcm2835-system-timer", + }, { + /* sentinel */ + } +}; + +static struct driver_d bcm2835_cs_driver = { + .name = "bcm2835-cs", + .probe = bcm2835_cs_probe, + .of_compatible = DRV_OF_COMPAT(bcm2835_cs_dt_ids), +}; + +static int bcm2835_cs_init(void) +{ + return platform_driver_register(&bcm2835_cs_driver); +} +coredevice_initcall(bcm2835_cs_init); diff --git a/drivers/clocksource/nomadik.c b/drivers/clocksource/nomadik.c new file mode 100644 index 0000000000..8a3e6d930e --- /dev/null +++ b/drivers/clocksource/nomadik.c @@ -0,0 +1,147 @@ +/* + * linux/arch/arm/mach-nomadik/timer.c + * + * Copyright (C) 2008 STMicroelectronics + * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x + * + * 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. + */ +#include <common.h> +#include <clock.h> +#include <io.h> +#include <init.h> +#include <driver.h> +#include <errno.h> +#include <linux/clk.h> +#include <linux/err.h> + +/* + * The MTU device hosts four different counters, with 4 set of + * registers. These are register names. + */ + +#define MTU_IMSC 0x00 /* Interrupt mask set/clear */ +#define MTU_RIS 0x04 /* Raw interrupt status */ +#define MTU_MIS 0x08 /* Masked interrupt status */ +#define MTU_ICR 0x0C /* Interrupt clear register */ + +/* per-timer registers take 0..3 as argument */ +#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */ +#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */ +#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */ +#define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */ + +/* bits for the control register */ +#define MTU_CRn_ENA 0x80 +#define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */ +#define MTU_CRn_PRESCALE_MASK 0x0c +#define MTU_CRn_PRESCALE_1 0x00 +#define MTU_CRn_PRESCALE_16 0x04 +#define MTU_CRn_PRESCALE_256 0x08 +#define MTU_CRn_32BITS 0x02 +#define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/ + +/* Other registers are usual amba/primecell registers, currently not used */ +#define MTU_ITCR 0xff0 +#define MTU_ITOP 0xff4 + +#define MTU_PERIPH_ID0 0xfe0 +#define MTU_PERIPH_ID1 0xfe4 +#define MTU_PERIPH_ID2 0xfe8 +#define MTU_PERIPH_ID3 0xfeC + +#define MTU_PCELL0 0xff0 +#define MTU_PCELL1 0xff4 +#define MTU_PCELL2 0xff8 +#define MTU_PCELL3 0xffC + +static __iomem void *mtu_base; +static u32 clk_prescale; +static u32 nmdk_cycle; /* write-once */ + +/* + * clocksource: the MTU device is a decrementing counters, so we negate + * the value being read. + */ +static uint64_t nmdk_read_timer(void) +{ + return nmdk_cycle - readl(mtu_base + MTU_VAL(0)); +} + +static struct clocksource nmdk_clksrc = { + .read = nmdk_read_timer, + .shift = 20, + .mask = CLOCKSOURCE_MASK(32), +}; + +static void nmdk_timer_reset(void) +{ + u32 cr; + + /* Disable */ + writel(0, mtu_base + MTU_CR(0)); /* off */ + + /* configure load and background-load, and fire it up */ + writel(nmdk_cycle, mtu_base + MTU_LR(0)); + writel(nmdk_cycle, mtu_base + MTU_BGLR(0)); + + cr = clk_prescale | MTU_CRn_32BITS; + writel(cr, mtu_base + MTU_CR(0)); + writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); +} + +static int nmdk_mtu_probe(struct device_d *dev) +{ + static struct clk *mtu_clk; + u32 rate; + int ret; + + mtu_clk = clk_get(dev, NULL); + if (IS_ERR(mtu_clk)) { + ret = PTR_ERR(mtu_clk); + dev_err(dev, "clock not found: %d\n", ret); + return ret; + } + + ret = clk_enable(mtu_clk); + if (ret < 0) { + dev_err(dev, "clock failed to enable: %d\n", ret); + clk_put(mtu_clk); + return ret; + } + + rate = clk_get_rate(mtu_clk); + if (rate > 32000000) { + rate /= 16; + clk_prescale = MTU_CRn_PRESCALE_16; + } else { + clk_prescale = MTU_CRn_PRESCALE_1; + } + + nmdk_cycle = (rate + 1000 / 2) / 1000; + + /* Save global pointer to mtu, used by functions above */ + mtu_base = dev_request_mem_region(dev, 0); + + /* Init the timer and register clocksource */ + nmdk_timer_reset(); + + nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift); + + init_clock(&nmdk_clksrc); + + return 0; +} + +static struct driver_d nmdk_mtu_driver = { + .name = "nomadik_mtu", + .probe = nmdk_mtu_probe, +}; + +static int nmdk_mtu_init(void) +{ + return platform_driver_register(&nmdk_mtu_driver); +} +coredevice_initcall(nmdk_mtu_init); diff --git a/drivers/eeprom/Kconfig b/drivers/eeprom/Kconfig index a0b54899c6..ce9cfe7ec8 100644 --- a/drivers/eeprom/Kconfig +++ b/drivers/eeprom/Kconfig @@ -8,4 +8,23 @@ config EEPROM_AT25 after you configure the board init code to know about each eeprom on your target board. +config EEPROM_AT24 + bool "at24 based eeprom" + depends on I2C + help + Enable this driver to get read/write support to most I2C EEPROMs, + after you configure the driver to know about each EEPROM on + your target board. Use these generic chip names, instead of + vendor-specific ones like at24c64 or 24lc02: + + 24c00, 24c01, 24c02, spd (readonly 24c02), 24c04, 24c08, + 24c16, 24c32, 24c64, 24c128, 24c256, 24c512, 24c1024 + + Unless you like data loss puzzles, always be sure that any chip + you configure as a 24c32 (32 kbit) or larger is NOT really a + 24c16 (16 kbit) or smaller, and vice versa. Marking the chip + as read-only won't help recover from this. Also, if your chip + has any software write-protect mechanism you may want to review the + code to make sure this driver won't turn it on by accident. + endmenu diff --git a/drivers/eeprom/Makefile b/drivers/eeprom/Makefile index e323bd0caf..e287eb02ff 100644 --- a/drivers/eeprom/Makefile +++ b/drivers/eeprom/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_EEPROM_AT25) += at25.o +obj-$(CONFIG_EEPROM_AT24) += at24.o diff --git a/drivers/eeprom/at24.c b/drivers/eeprom/at24.c new file mode 100644 index 0000000000..6f0133acdb --- /dev/null +++ b/drivers/eeprom/at24.c @@ -0,0 +1,460 @@ +/* + * at24.c - handle most I2C EEPROMs + * + * Copyright (C) 2005-2007 David Brownell + * Copyright (C) 2008 Wolfram Sang, Pengutronix + * + * 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 <malloc.h> +#include <clock.h> +#include <driver.h> +#include <xfuncs.h> +#include <errno.h> +#include <linux/math64.h> +#include <linux/log2.h> +#include <i2c/i2c.h> +#include <i2c/at24.h> + +/* + * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. + * Differences between different vendor product lines (like Atmel AT24C or + * MicroChip 24LC, etc) won't much matter for typical read/write access. + * There are also I2C RAM chips, likewise interchangeable. One example + * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes). + * + * However, misconfiguration can lose data. "Set 16-bit memory address" + * to a part with 8-bit addressing will overwrite data. Writing with too + * big a page size also loses data. And it's not safe to assume that the + * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC + * uses 0x51, for just one example. + * + * So this driver uses "new style" I2C driver binding, expecting to be + * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or + * similar kernel-resident tables; or, configuration data coming from + * a bootloader. + * + * Other than binding model, current differences from "eeprom" driver are + * that this one handles write access and isn't restricted to 24c02 devices. + * It also handles larger devices (32 kbit and up) with two-byte addresses, + * which won't work on pure SMBus systems. + */ + +struct at24_data { + struct at24_platform_data chip; + + struct cdev cdev; + struct file_operations fops; + + u8 *writebuf; + unsigned write_max; + unsigned num_addresses; + + /* + * Some chips tie up multiple I2C addresses; dummy devices reserve + * them for us. + */ + struct i2c_client *client[]; +}; + +/* + * This parameter is to help this driver avoid blocking other drivers out + * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C + * clock, one 256 byte read takes about 1/43 second which is excessive; + * but the 1/170 second it takes at 400 kHz may be quite reasonable; and + * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. + * + * This value is forced to be a power of two so that writes align on pages. + */ +static unsigned io_limit = 128; + +/* + * Specs often allow 5 msec for a page write, sometimes 20 msec; + * it's important to recover from write timeouts. + */ +static unsigned write_timeout = 25; + +#define AT24_SIZE_BYTELEN 5 +#define AT24_SIZE_FLAGS 8 + +#define AT24_BITMASK(x) (BIT(x) - 1) + +/* create non-zero magic value for given eeprom parameters */ +#define AT24_DEVICE_MAGIC(_len, _flags) \ + ((1 << AT24_SIZE_FLAGS | (_flags)) \ + << AT24_SIZE_BYTELEN | ilog2(_len)) + +static struct platform_device_id at24_ids[] = { + /* needs 8 addresses as A0-A2 are ignored */ + { "24c00", AT24_DEVICE_MAGIC(128 / 8, AT24_FLAG_TAKE8ADDR) }, + /* old variants can't be handled with this generic entry! */ + { "24c01", AT24_DEVICE_MAGIC(1024 / 8, 0) }, + { "24c02", AT24_DEVICE_MAGIC(2048 / 8, 0) }, + /* spd is a 24c02 in memory DIMMs */ + { "spd", AT24_DEVICE_MAGIC(2048 / 8, + AT24_FLAG_READONLY | AT24_FLAG_IRUGO) }, + { "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) }, + /* 24rf08 quirk is handled at i2c-core */ + { "24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) }, + { "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) }, + { "24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) }, + { "24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) }, + { "24c128", AT24_DEVICE_MAGIC(131072 / 8, AT24_FLAG_ADDR16) }, + { "24c256", AT24_DEVICE_MAGIC(262144 / 8, AT24_FLAG_ADDR16) }, + { "24c512", AT24_DEVICE_MAGIC(524288 / 8, AT24_FLAG_ADDR16) }, + { "24c1024", AT24_DEVICE_MAGIC(1048576 / 8, AT24_FLAG_ADDR16) }, + { "at24", 0 }, + { /* END OF LIST */ } +}; + +/*-------------------------------------------------------------------------*/ + +/* + * This routine supports chips which consume multiple I2C addresses. It + * computes the addressing information to be used for a given r/w request. + * Assumes that sanity checks for offset happened at sysfs-layer. + */ +static struct i2c_client *at24_translate_offset(struct at24_data *at24, + unsigned *offset) +{ + unsigned i; + + if (at24->chip.flags & AT24_FLAG_ADDR16) { + i = *offset >> 16; + *offset &= 0xffff; + } else { + i = *offset >> 8; + *offset &= 0xff; + } + + return at24->client[i]; +} + +static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, + unsigned offset, size_t count) +{ + struct i2c_msg msg[2]; + u8 msgbuf[2]; + struct i2c_client *client; + int status, i; + uint64_t start, read_time; + + memset(msg, 0, sizeof(msg)); + + /* + * REVISIT some multi-address chips don't rollover page reads to + * the next slave address, so we may need to truncate the count. + * Those chips might need another quirk flag. + * + * If the real hardware used four adjacent 24c02 chips and that + * were misconfigured as one 24c08, that would be a similar effect: + * one "eeprom" file not four, but larger reads would fail when + * they crossed certain pages. + */ + + /* + * Slave address and byte offset derive from the offset. Always + * set the byte address; on a multi-master board, another master + * may have changed the chip's "current" address pointer. + */ + client = at24_translate_offset(at24, &offset); + + if (count > io_limit) + count = io_limit; + + i = 0; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msgbuf[i++] = offset >> 8; + msgbuf[i++] = offset; + + msg[0].addr = client->addr; + msg[0].buf = msgbuf; + msg[0].len = i; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + start = get_time_ns(); + do { + read_time = get_time_ns(); + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + status = count; + dev_dbg(&client->dev, "read %zu@%d --> %d (%llu)\n", + count, offset, status, read_time); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + mdelay(1); + } while (!is_timeout(start, write_timeout * MSECOND)); + + return -ETIMEDOUT; +} + +static ssize_t at24_read(struct at24_data *at24, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) + return count; + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + while (count) { + ssize_t status; + + status = at24_eeprom_read(at24, buf, off, count); + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + return retval; +} + +static ssize_t at24_cdev_read(struct cdev *cdev, void *buf, size_t count, + loff_t off, ulong flags) +{ + struct at24_data *at24 = cdev->priv; + + return at24_read(at24, buf, off, count); +} + +/* + * Note that if the hardware write-protect pin is pulled high, the whole + * chip is normally write protected. But there are plenty of product + * variants here, including OTP fuses and partial chip protect. + * + * We only use page mode writes; the alternative is sloooow. This routine + * writes at most one page. + */ +static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, + unsigned offset, size_t count) +{ + struct i2c_client *client; + struct i2c_msg msg; + ssize_t status; + uint64_t start, write_time; + unsigned next_page; + int i = 0; + + /* Get corresponding I2C address and adjust offset */ + client = at24_translate_offset(at24, &offset); + + /* write_max is at most a page */ + if (count > at24->write_max) + count = at24->write_max; + + /* Never roll over backwards, to the start of this page */ + next_page = roundup(offset + 1, at24->chip.page_size); + if (offset + count > next_page) + count = next_page - offset; + + + msg.addr = client->addr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = at24->writebuf; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msg.buf[i++] = offset >> 8; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + + /* + * Writes fail if the previous one didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + start = get_time_ns(); + do { + write_time = get_time_ns(); + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + dev_dbg(&client->dev, "write %zu@%d --> %zd (%llu)\n", + count, offset, status, write_time); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + mdelay(1); + } while (!is_timeout(start, write_timeout * MSECOND)); + + return -ETIMEDOUT; +} + +static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off, + size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) + return count; + + while (count) { + ssize_t status; + + status = at24_eeprom_write(at24, buf, off, count); + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + return retval; +} + +static ssize_t at24_cdev_write(struct cdev *cdev, const void *buf, size_t count, + loff_t off, ulong flags) +{ + struct at24_data *at24 = cdev->priv; + + return at24_write(at24, buf, off, count); +} + +static int at24_probe(struct device_d *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct at24_platform_data chip; + bool writable; + struct at24_data *at24; + int err; + unsigned i, num_addresses; + + if (dev->platform_data) { + chip = *(struct at24_platform_data *)dev->platform_data; + } else { + unsigned long magic; + + err = dev_get_drvdata(dev, (unsigned long *)&magic); + if (err) + return err; + + chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN)); + magic >>= AT24_SIZE_BYTELEN; + chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS); + /* + * This is slow, but we can't know all eeproms, so we better + * play safe. Specifying custom eeprom-types via platform_data + * is recommended anyhow. + */ + chip.page_size = 1; + } + + if (!is_power_of_2(chip.byte_len)) + dev_warn(&client->dev, + "byte_len looks suspicious (no power of 2)!\n"); + if (!chip.page_size) { + dev_err(&client->dev, "page_size must not be 0!\n"); + err = -EINVAL; + goto err_out; + } + if (!is_power_of_2(chip.page_size)) + dev_warn(&client->dev, + "page_size looks suspicious (no power of 2)!\n"); + + if (chip.flags & AT24_FLAG_TAKE8ADDR) + num_addresses = 8; + else + num_addresses = DIV_ROUND_UP(chip.byte_len, + (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256); + + at24 = xzalloc(sizeof(struct at24_data) + + num_addresses * sizeof(struct i2c_client *)); + + at24->chip = chip; + at24->num_addresses = num_addresses; + at24->cdev.name = asprintf("eeprom%d", dev->id); + at24->cdev.priv = at24; + at24->cdev.dev = dev; + at24->cdev.ops = &at24->fops; + at24->fops.lseek = dev_lseek_default; + at24->fops.read = at24_cdev_read, + at24->cdev.size = chip.byte_len; + + writable = !(chip.flags & AT24_FLAG_READONLY); + if (writable) { + unsigned write_max = chip.page_size; + + at24->fops.write = at24_cdev_write; + + if (write_max > io_limit) + write_max = io_limit; + at24->write_max = write_max; + + /* buffer (data + address at the beginning) */ + at24->writebuf = xmalloc(write_max + 2); + } + + at24->client[0] = client; + + /* use dummy devices for multiple-address chips */ + for (i = 1; i < num_addresses; i++) { + at24->client[i] = i2c_new_dummy(client->adapter, + client->addr + i); + if (!at24->client[i]) { + dev_err(&client->dev, "address 0x%02x unavailable\n", + client->addr + i); + err = -EADDRINUSE; + goto err_clients; + } + } + + devfs_create(&at24->cdev); + + return 0; + +err_clients: + kfree(at24->writebuf); + kfree(at24); +err_out: + dev_dbg(&client->dev, "probe error %d\n", err); + return err; + +} + +static struct driver_d at24_driver = { + .name = "at24", + .probe = at24_probe, + .id_table = at24_ids, +}; + +static int at24_init(void) +{ + i2c_register_driver(&at24_driver); + return 0; +} +device_initcall(at24_init); diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 022a30988e..e8eeb6d4c3 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1,10 +1,21 @@ config GPIOLIB bool + select GENERIC_GPIO if GPIOLIB menu "GPIO " +config GPIO_BCM2835 + bool "GPIO support for BCM2835" + depends on ARCH_BCM2835 + +config GPIO_PL061 + bool "PrimeCell PL061 GPIO support" + depends on ARM_AMBA + help + Say yes here to support the PrimeCell PL061 GPIO device + config GPIO_STMPE depends on I2C_STMPE bool "STMPE GPIO Expander" diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 945122b083..993ab89596 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -1,2 +1,4 @@ obj-$(CONFIG_GPIOLIB) += gpio.o +obj-$(CONFIG_GPIO_BCM2835) += gpio-bcm2835.o +obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o diff --git a/drivers/gpio/gpio-bcm2835.c b/drivers/gpio/gpio-bcm2835.c new file mode 100644 index 0000000000..cec15c98b1 --- /dev/null +++ b/drivers/gpio/gpio-bcm2835.c @@ -0,0 +1,158 @@ +/* + * Author: Carlo Caione <carlo@carlocaione.org> + * + * Based on linux/arch/arm/mach-bcm2708/bcm2708_gpio.c + * + * 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 <errno.h> +#include <malloc.h> +#include <io.h> +#include <gpio.h> +#include <init.h> + +#define GPIOFSEL(x) (0x00+(x)*4) +#define GPIOSET(x) (0x1c+(x)*4) +#define GPIOCLR(x) (0x28+(x)*4) +#define GPIOLEV(x) (0x34+(x)*4) +#define GPIOEDS(x) (0x40+(x)*4) +#define GPIOREN(x) (0x4c+(x)*4) +#define GPIOFEN(x) (0x58+(x)*4) +#define GPIOHEN(x) (0x64+(x)*4) +#define GPIOLEN(x) (0x70+(x)*4) +#define GPIOAREN(x) (0x7c+(x)*4) +#define GPIOAFEN(x) (0x88+(x)*4) +#define GPIOUD(x) (0x94+(x)*4) +#define GPIOUDCLK(x) (0x98+(x)*4) + +enum { + GPIO_FSEL_INPUT, GPIO_FSEL_OUTPUT, + GPIO_FSEL_ALT5, GPIO_FSEL_ALT_4, + GPIO_FSEL_ALT0, GPIO_FSEL_ALT1, + GPIO_FSEL_ALT2, GPIO_FSEL_ALT3, +}; + +struct bcm2835_gpio_chip { + void __iomem *base; + struct gpio_chip chip; +}; + +static int bcm2835_set_function(struct gpio_chip *chip, unsigned gpio, int function) +{ + struct bcm2835_gpio_chip *bcmgpio = container_of(chip, struct bcm2835_gpio_chip, chip); + void __iomem *base = bcmgpio->base; + unsigned gpiodir; + unsigned gpio_bank = gpio / 10; + unsigned gpio_field_offset = (gpio - 10 * gpio_bank) * 3; + + gpiodir = readl(base + GPIOFSEL(gpio_bank)); + gpiodir &= ~(7 << gpio_field_offset); + gpiodir |= function << gpio_field_offset; + writel(gpiodir, base + GPIOFSEL(gpio_bank)); + gpiodir = readl(base + GPIOFSEL(gpio_bank)); + + return 0; +} + +static void bcm2835_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) +{ + struct bcm2835_gpio_chip *bcmgpio = container_of(chip, struct bcm2835_gpio_chip, chip); + void __iomem *base = bcmgpio->base; + unsigned gpio_bank = gpio / 32; + unsigned gpio_field_offset = gpio % 32; + + if (value) + writel(1 << gpio_field_offset, base + GPIOSET(gpio_bank)); + else + writel(1 << gpio_field_offset, base + GPIOCLR(gpio_bank)); +} + +static int bcm2835_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + struct bcm2835_gpio_chip *bcmgpio = container_of(chip, struct bcm2835_gpio_chip, chip); + void __iomem *base = bcmgpio->base; + unsigned gpio_bank = gpio / 32; + unsigned gpio_field_offset = gpio % 32; + unsigned lev; + + lev = readl(base + GPIOLEV(gpio_bank)); + return 0x1 & (lev >> gpio_field_offset); +} + +static int bcm2835_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + return bcm2835_set_function(chip, gpio, GPIO_FSEL_INPUT); +} + +static int bcm2835_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) +{ + bcm2835_set_function(chip, gpio, GPIO_FSEL_OUTPUT); + bcm2835_gpio_set_value(chip, gpio, value); + + return 0; +} + +static struct gpio_ops bcm2835_gpio_ops = { + .direction_input = bcm2835_gpio_direction_input, + .direction_output = bcm2835_gpio_direction_output, + .get = bcm2835_gpio_get_value, + .set = bcm2835_gpio_set_value, +}; + +static int bcm2835_gpio_probe(struct device_d *dev) +{ + struct bcm2835_gpio_chip *bcmgpio; + int ret; + + bcmgpio = xzalloc(sizeof(*bcmgpio)); + bcmgpio->base = dev_request_mem_region(dev, 0); + bcmgpio->chip.ops = &bcm2835_gpio_ops; + bcmgpio->chip.base = 0; + bcmgpio->chip.ngpio = 54; + bcmgpio->chip.dev = dev; + + ret = gpiochip_add(&bcmgpio->chip); + if (ret) { + dev_err(dev, "couldn't add gpiochip, ret = %d\n", ret); + goto err; + } + dev_info(dev, "probed gpiochip%d with base %d\n", dev->id, bcmgpio->chip.base); + + return 0; + +err: + kfree(bcmgpio); + + return ret; +} + +static __maybe_unused struct of_device_id bcm2835_gpio_dt_ids[] = { + { + .compatible = "brcm,bcm2835-gpio", + }, { + /* sentinel */ + } +}; + +static struct driver_d bcm2835_gpio_driver = { + .name = "bcm2835-gpio", + .probe = bcm2835_gpio_probe, + .of_compatible = DRV_OF_COMPAT(bcm2835_gpio_dt_ids), +}; + +static int bcm2835_gpio_add(void) +{ + return platform_driver_register(&bcm2835_gpio_driver); +} +coredevice_initcall(bcm2835_gpio_add); diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c new file mode 100644 index 0000000000..f34aba9da9 --- /dev/null +++ b/drivers/gpio/gpio-pl061.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2008, 2009 Provigent Ltd. + * + * 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. + * + * Driver for the ARM PrimeCell(tm) General Purpose Input/Output (PL061) + * + * Data sheet: ARM DDI 0190B, September 2000 + */ +#include <common.h> +#include <malloc.h> +#include <errno.h> +#include <io.h> +#include <gpio.h> +#include <init.h> + +#include <linux/amba/bus.h> +#include <linux/amba/pl061.h> + +#define GPIODIR 0x400 +#define GPIOIS 0x404 +#define GPIOIBE 0x408 +#define GPIOIEV 0x40C +#define GPIOIE 0x410 +#define GPIORIS 0x414 +#define GPIOMIS 0x418 +#define GPIOIC 0x41C + +#define PL061_GPIO_NR 8 + +struct pl061_gpio { + void __iomem *base; + struct gpio_chip gc; +}; + +static int pl061_direction_input(struct gpio_chip *gc, unsigned offset) +{ + struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); + unsigned char gpiodir; + + if (offset >= gc->ngpio) + return -EINVAL; + + gpiodir = readb(chip->base + GPIODIR); + gpiodir &= ~(1 << offset); + writeb(gpiodir, chip->base + GPIODIR); + + return 0; +} + +static int pl061_direction_output(struct gpio_chip *gc, unsigned offset, + int value) +{ + struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); + unsigned char gpiodir; + + if (offset >= gc->ngpio) + return -EINVAL; + + writeb(!!value << offset, chip->base + (1 << (offset + 2))); + gpiodir = readb(chip->base + GPIODIR); + gpiodir |= 1 << offset; + writeb(gpiodir, chip->base + GPIODIR); + + /* + * gpio value is set again, because pl061 doesn't allow to set value of + * a gpio pin before configuring it in OUT mode. + */ + writeb(!!value << offset, chip->base + (1 << (offset + 2))); + + return 0; +} + +static int pl061_get_value(struct gpio_chip *gc, unsigned offset) +{ + struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); + + return !!readb(chip->base + (1 << (offset + 2))); +} + +static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value) +{ + struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); + + writeb(!!value << offset, chip->base + (1 << (offset + 2))); +} + +static struct gpio_ops pl061_gpio_ops = { + .direction_input = pl061_direction_input, + .direction_output = pl061_direction_output, + .get = pl061_get_value, + .set = pl061_set_value, +}; + +static int pl061_probe(struct amba_device *dev, const struct amba_id *id) +{ + struct pl061_platform_data *pdata; + struct pl061_gpio *chip; + int ret; + + chip = xzalloc(sizeof(*chip)); + + pdata = dev->dev.platform_data; + if (pdata) { + chip->gc.base = pdata->gpio_base; + } else { + chip->gc.base = -1; + } + + chip->base = amba_get_mem_region(dev); + + chip->gc.ops = &pl061_gpio_ops; + chip->gc.ngpio = PL061_GPIO_NR; + chip->gc.dev = &dev->dev; + + ret = gpiochip_add(&chip->gc); + if (ret) { + dev_err(&dev->dev, "couldn't add gpiochip, ret = %d\n", ret); + goto free_mem; + } + + writeb(0, chip->base + GPIOIE); /* disable irqs */ + + return 0; + +free_mem: + kfree(chip); + + return ret; +} + +static struct amba_id pl061_ids[] = { + { + .id = 0x00041061, + .mask = 0x000fffff, + }, + { 0, 0 }, +}; + +static struct amba_driver pl061_gpio_driver = { + .drv = { + .name = "pl061_gpio", + }, + .id_table = pl061_ids, + .probe = pl061_probe, +}; + +static int __init pl061_gpio_init(void) +{ + return amba_driver_register(&pl061_gpio_driver); +} +coredevice_initcall(pl061_gpio_init); + +MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); +MODULE_DESCRIPTION("PL061 GPIO driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpio/gpio.c b/drivers/gpio/gpio.c index 6ad8d274e7..042a0621b0 100644 --- a/drivers/gpio/gpio.c +++ b/drivers/gpio/gpio.c @@ -4,17 +4,8 @@ static LIST_HEAD(chip_list); -#define ARCH_NR_GPIOS 256 - static struct gpio_chip *gpio_desc[ARCH_NR_GPIOS]; -static int gpio_is_valid(unsigned gpio) -{ - if (gpio < ARCH_NR_GPIOS) - return 1; - return 0; -} - void gpio_set_value(unsigned gpio, int value) { struct gpio_chip *chip = gpio_desc[gpio]; diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index c2af818393..038e2ee454 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -3,6 +3,7 @@ menuconfig I2C if I2C +source drivers/i2c/algos/Kconfig source drivers/i2c/busses/Kconfig endif diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 42e22c01b0..5ce0324714 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -1 +1 @@ -obj-$(CONFIG_I2C) += i2c.o busses/ +obj-$(CONFIG_I2C) += i2c.o busses/ algos/ diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig new file mode 100644 index 0000000000..c74b148f5e --- /dev/null +++ b/drivers/i2c/algos/Kconfig @@ -0,0 +1,6 @@ +# +# I2C algorithm drivers configuration +# + +config I2C_ALGOBIT + bool diff --git a/drivers/i2c/algos/Makefile b/drivers/i2c/algos/Makefile new file mode 100644 index 0000000000..e0a03995b5 --- /dev/null +++ b/drivers/i2c/algos/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the i2c algorithms +# + +obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c new file mode 100644 index 0000000000..dc43eb83a4 --- /dev/null +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -0,0 +1,605 @@ +/* ------------------------------------------------------------------------- + * i2c-algo-bit.c i2c driver algorithms for bit-shift adapters + * ------------------------------------------------------------------------- + * Copyright (C) 1995-2000 Simon G. Vogl + + 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., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301 USA. + * ------------------------------------------------------------------------- */ + +/* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki + <kmalkki@cc.hut.fi> and Jean Delvare <khali@linux-fr.org> */ + +#include <common.h> +#include <init.h> +#include <errno.h> +#include <clock.h> +#include <i2c/i2c.h> +#include <i2c/i2c-algo-bit.h> + +/* ----- global defines ----------------------------------------------- */ + +#ifdef DEBUG +#define bit_dbg(level, dev, format, args...) \ + do { \ + if (i2c_debug >= level) \ + dev_dbg(dev, format, ##args); \ + } while (0) +#else +#define bit_dbg(level, dev, format, args...) \ + do {} while (0) +#endif /* DEBUG */ + +/* ----- global variables --------------------------------------------- */ + +static int bit_test; /* see if the line-setting functions work */ + +#ifdef DEBUG +static int i2c_debug = 1; +#endif + +/* --- setting states on the bus with the right timing: --------------- */ + +#define setsda(adap, val) adap->setsda(adap->data, val) +#define setscl(adap, val) adap->setscl(adap->data, val) +#define getsda(adap) adap->getsda(adap->data) +#define getscl(adap) adap->getscl(adap->data) + +static inline void sdalo(struct i2c_algo_bit_data *adap) +{ + setsda(adap, 0); + udelay((adap->udelay + 1) / 2); +} + +static inline void sdahi(struct i2c_algo_bit_data *adap) +{ + setsda(adap, 1); + udelay((adap->udelay + 1) / 2); +} + +static inline void scllo(struct i2c_algo_bit_data *adap) +{ + setscl(adap, 0); + udelay(adap->udelay / 2); +} + +/* + * Raise scl line, and do checking for delays. This is necessary for slower + * devices. + */ +static int sclhi(struct i2c_algo_bit_data *adap) +{ + uint64_t start; + + setscl(adap, 1); + + /* Not all adapters have scl sense line... */ + if (!adap->getscl) + goto done; + + start = get_time_ns(); + while (!getscl(adap)) { + /* This hw knows how to read the clock line, so we wait + * until it actually gets high. This is safer as some + * chips may hold it low ("clock stretching") while they + * are processing data internally. + */ + if (is_timeout(start, adap->timeout_ms * MSECOND)) { + /* Test one last time, as we may have been preempted + * between last check and timeout test. + */ + if (getscl(adap)) + break; + return -ETIMEDOUT; + } + } +#ifdef DEBUG + if (jiffies != start && i2c_debug >= 3) + pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go " + "high\n", jiffies - start); +#endif + +done: + udelay(adap->udelay); + return 0; +} + + +/* --- other auxiliary functions -------------------------------------- */ +static void i2c_start(struct i2c_algo_bit_data *adap) +{ + /* assert: scl, sda are high */ + setsda(adap, 0); + udelay(adap->udelay); + scllo(adap); +} + +static void i2c_repstart(struct i2c_algo_bit_data *adap) +{ + /* assert: scl is low */ + sdahi(adap); + sclhi(adap); + setsda(adap, 0); + udelay(adap->udelay); + scllo(adap); +} + + +static void i2c_stop(struct i2c_algo_bit_data *adap) +{ + /* assert: scl is low */ + sdalo(adap); + sclhi(adap); + setsda(adap, 1); + udelay(adap->udelay); +} + + + +/* send a byte without start cond., look for arbitration, + check ackn. from slave */ +/* returns: + * 1 if the device acknowledged + * 0 if the device did not ack + * -ETIMEDOUT if an error occurred (while raising the scl line) + */ +static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c) +{ + int i; + int sb; + int ack; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + /* assert: scl is low */ + for (i = 7; i >= 0; i--) { + sb = (c >> i) & 1; + setsda(adap, sb); + udelay((adap->udelay + 1) / 2); + if (sclhi(adap) < 0) { /* timed out */ + bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " + "timeout at bit #%d\n", (int)c, i); + return -ETIMEDOUT; + } + /* FIXME do arbitration here: + * if (sb && !getsda(adap)) -> ouch! Get out of here. + * + * Report a unique code, so higher level code can retry + * the whole (combined) message and *NOT* issue STOP. + */ + scllo(adap); + } + sdahi(adap); + if (sclhi(adap) < 0) { /* timeout */ + bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " + "timeout at ack\n", (int)c); + return -ETIMEDOUT; + } + + /* read ack: SDA should be pulled down by slave, or it may + * NAK (usually to report problems with the data we wrote). + */ + ack = !getsda(adap); /* ack: sda is pulled low -> success */ + bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c, + ack ? "A" : "NA"); + + scllo(adap); + return ack; + /* assert: scl is low (sda undef) */ +} + + +static int i2c_inb(struct i2c_adapter *i2c_adap) +{ + /* read byte via i2c port, without start/stop sequence */ + /* acknowledge is sent in i2c_read. */ + int i; + unsigned char indata = 0; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + /* assert: scl is low */ + sdahi(adap); + for (i = 0; i < 8; i++) { + if (sclhi(adap) < 0) { /* timeout */ + bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit " + "#%d\n", 7 - i); + return -ETIMEDOUT; + } + indata *= 2; + if (getsda(adap)) + indata |= 0x01; + setscl(adap, 0); + udelay(i == 7 ? adap->udelay / 2 : adap->udelay); + } + /* assert: scl is low */ + return indata; +} + +/* + * Sanity check for the adapter hardware - check the reaction of + * the bus lines only if it seems to be idle. + */ +static int test_bus(struct i2c_adapter *i2c_adap) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + struct device_d *dev = &i2c_adap->dev; + int scl, sda, ret; + + if (adap->pre_xfer) { + ret = adap->pre_xfer(i2c_adap); + if (ret < 0) + return -ENODEV; + } + + if (adap->getscl == NULL) + dev_info(dev, "Testing SDA only, SCL is not readable\n"); + + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 1 : getscl(adap); + if (!scl || !sda) { + dev_warn(dev, "bus seems to be busy (scl=%d, sda=%d)\n", scl, sda); + goto bailout; + } + + sdalo(adap); + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 1 : getscl(adap); + if (sda) { + dev_warn(dev, "SDA stuck high!\n"); + goto bailout; + } + if (!scl) { + dev_warn(dev, "SCL unexpected low while pulling SDA low!\n"); + goto bailout; + } + + sdahi(adap); + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 1 : getscl(adap); + if (!sda) { + dev_warn(dev, "SDA stuck low!\n"); + goto bailout; + } + if (!scl) { + dev_warn(dev, "SCL unexpected low while pulling SDA high!\n"); + goto bailout; + } + + scllo(adap); + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 0 : getscl(adap); + if (scl) { + dev_warn(dev, "SCL stuck high!\n"); + goto bailout; + } + if (!sda) { + dev_warn(dev, "SDA unexpected low while pulling SCL low!\n"); + goto bailout; + } + + sclhi(adap); + sda = getsda(adap); + scl = (adap->getscl == NULL) ? 1 : getscl(adap); + if (!scl) { + dev_warn(dev, "SCL stuck low!\n"); + goto bailout; + } + if (!sda) { + dev_warn(dev, "SDA unexpected low while pulling SCL high!\n"); + goto bailout; + } + + if (adap->post_xfer) + adap->post_xfer(i2c_adap); + + dev_info(dev, "Test OK\n"); + return 0; +bailout: + sdahi(adap); + sclhi(adap); + + if (adap->post_xfer) + adap->post_xfer(i2c_adap); + + return -ENODEV; +} + +/* ----- Utility functions + */ + +/* try_address tries to contact a chip for a number of + * times before it gives up. + * return values: + * 1 chip answered + * 0 chip did not answer + * -x transmission error + */ +static int try_address(struct i2c_adapter *i2c_adap, + unsigned char addr, int retries) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + int i, ret = 0; + + for (i = 0; i <= retries; i++) { + ret = i2c_outb(i2c_adap, addr); + if (ret == 1 || i == retries) + break; + bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); + i2c_stop(adap); + udelay(adap->udelay); + bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); + i2c_start(adap); + } + if (i && ret) + bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at " + "0x%02x: %s\n", i + 1, + addr & 1 ? "read from" : "write to", addr >> 1, + ret == 1 ? "success" : "failed, timeout?"); + return ret; +} + +static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + const unsigned char *temp = msg->buf; + int count = msg->len; + unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; + int retval; + int wrcount = 0; + + while (count > 0) { + retval = i2c_outb(i2c_adap, *temp); + + /* OK/ACK; or ignored NAK */ + if ((retval > 0) || (nak_ok && (retval == 0))) { + count--; + temp++; + wrcount++; + + /* A slave NAKing the master means the slave didn't like + * something about the data it saw. For example, maybe + * the SMBus PEC was wrong. + */ + } else if (retval == 0) { + dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n"); + return -EIO; + + /* Timeout; or (someday) lost arbitration + * + * FIXME Lost ARB implies retrying the transaction from + * the first message, after the "winning" master issues + * its STOP. As a rule, upper layer code has no reason + * to know or care about this ... it is *NOT* an error. + */ + } else { + dev_err(&i2c_adap->dev, "sendbytes: error %d\n", + retval); + return retval; + } + } + return wrcount; +} + +static int acknak(struct i2c_adapter *i2c_adap, int is_ack) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + /* assert: sda is high */ + if (is_ack) /* send ack */ + setsda(adap, 0); + udelay((adap->udelay + 1) / 2); + if (sclhi(adap) < 0) { /* timeout */ + dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n"); + return -ETIMEDOUT; + } + scllo(adap); + return 0; +} + +static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + int inval; + int rdcount = 0; /* counts bytes read */ + unsigned char *temp = msg->buf; + int count = msg->len; + + while (count > 0) { + inval = i2c_inb(i2c_adap); + if (inval >= 0) { + *temp = inval; + rdcount++; + } else { /* read timed out */ + break; + } + + temp++; + count--; + + bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n", + inval, + (flags & I2C_M_NO_RD_ACK) + ? "(no ack/nak)" + : (count ? "A" : "NA")); + + inval = acknak(i2c_adap, count); + if (inval < 0) + return inval; + } + return rdcount; +} + +/* doAddress initiates the transfer by generating the start condition (in + * try_address) and transmits the address in the necessary format to handle + * reads, writes as well as 10bit-addresses. + * returns: + * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set + * -x an error occurred (like: -ENXIO if the device did not answer, or + * -ETIMEDOUT, for example if the lines are stuck...) + */ +static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + unsigned short flags = msg->flags; + unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + unsigned char addr; + int ret, retries; + + retries = nak_ok ? 0 : i2c_adap->retries; + + if (flags & I2C_M_TEN) { + /* a ten bit address */ + addr = 0xf0 | ((msg->addr >> 7) & 0x06); + bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); + /* try extended address code...*/ + ret = try_address(i2c_adap, addr, retries); + if ((ret != 1) && !nak_ok) { + dev_err(&i2c_adap->dev, + "died at extended address code\n"); + return -ENXIO; + } + /* the remaining 8 bit address */ + ret = i2c_outb(i2c_adap, msg->addr & 0xff); + if ((ret != 1) && !nak_ok) { + /* the chip did not ack / xmission error occurred */ + dev_err(&i2c_adap->dev, "died at 2nd address code\n"); + return -ENXIO; + } + if (flags & I2C_M_RD) { + bit_dbg(3, &i2c_adap->dev, "emitting repeated " + "start condition\n"); + i2c_repstart(adap); + /* okay, now switch into reading mode */ + addr |= 0x01; + ret = try_address(i2c_adap, addr, retries); + if ((ret != 1) && !nak_ok) { + dev_err(&i2c_adap->dev, + "died at repeated address code\n"); + return -EIO; + } + } + } else { /* normal 7bit address */ + addr = msg->addr << 1; + if (flags & I2C_M_RD) + addr |= 1; + ret = try_address(i2c_adap, addr, retries); + if ((ret != 1) && !nak_ok) + return -ENXIO; + } + + return 0; +} + +static int bit_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg msgs[], int num) +{ + struct i2c_msg *pmsg; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + int i, ret; + unsigned short nak_ok; + + if (adap->pre_xfer) { + ret = adap->pre_xfer(i2c_adap); + if (ret < 0) + return ret; + } + + bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); + i2c_start(adap); + for (i = 0; i < num; i++) { + pmsg = &msgs[i]; + nak_ok = pmsg->flags & I2C_M_IGNORE_NAK; + if (i) { + bit_dbg(3, &i2c_adap->dev, "emitting " + "repeated start condition\n"); + i2c_repstart(adap); + } + ret = bit_doAddress(i2c_adap, pmsg); + if ((ret != 0) && !nak_ok) { + bit_dbg(1, &i2c_adap->dev, "NAK from " + "device addr 0x%02x msg #%d\n", + msgs[i].addr, i); + goto bailout; + } + if (pmsg->flags & I2C_M_RD) { + /* read bytes into buffer*/ + ret = readbytes(i2c_adap, pmsg); + if (ret >= 1) + bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n", + ret, ret == 1 ? "" : "s"); + if (ret < pmsg->len) { + if (ret >= 0) + ret = -EIO; + goto bailout; + } + } else { + /* write bytes from buffer */ + ret = sendbytes(i2c_adap, pmsg); + if (ret >= 1) + bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n", + ret, ret == 1 ? "" : "s"); + if (ret < pmsg->len) { + if (ret >= 0) + ret = -EIO; + goto bailout; + } + } + } + ret = i; + +bailout: + bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); + i2c_stop(adap); + + if (adap->post_xfer) + adap->post_xfer(i2c_adap); + return ret; +} + +/* + * registering functions to load algorithms at runtime + */ +static int __i2c_bit_add_bus(struct i2c_adapter *adap, + int (*add_adapter)(struct i2c_adapter *)) +{ + struct i2c_algo_bit_data *bit_adap = adap->algo_data; + int ret; + + if (bit_test) { + ret = test_bus(adap); + if (bit_test >= 2 && ret < 0) + return -ENODEV; + } + + /* register new adapter to i2c module... */ + //adap->algo = &i2c_bit_algo; + adap->retries = 3; + adap->master_xfer = bit_xfer; + + ret = add_adapter(adap); + if (ret < 0) + return ret; + + /* Complain if SCL can't be read */ + if (bit_adap->getscl == NULL) { + dev_warn(&adap->dev, "Not I2C compliant: can't read SCL\n"); + dev_warn(&adap->dev, "Bus may be unreliable\n"); + } + return 0; +} + +int i2c_bit_add_numbered_bus(struct i2c_adapter *adap) +{ + return __i2c_bit_add_bus(adap, i2c_add_numbered_adapter); +} +EXPORT_SYMBOL(i2c_bit_add_numbered_bus); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 3f998eafa5..68d9b469e8 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -4,6 +4,14 @@ menu "I2C Hardware Bus support" +config I2C_GPIO + tristate "GPIO-based bitbanging I2C" + depends on GENERIC_GPIO + select I2C_ALGOBIT + help + This is a very simple bitbanging I2C driver utilizing the + arch-neutral GPIO API to control the SCL and SDA lines. + config I2C_IMX bool "MPC85xx/i.MX I2C Master driver" depends on (ARCH_IMX && !ARCH_IMX1) || ARCH_MPC85XX @@ -12,4 +20,12 @@ config I2C_OMAP bool "OMAP I2C Master driver" depends on ARCH_OMAP +config I2C_VERSATILE + tristate "ARM Versatile/Realview I2C bus support" + depends on ARCH_VERSATILE + select I2C_ALGOBIT + help + Say yes if you want to support the I2C serial bus on ARMs Versatile + range of platforms. + endmenu diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index e4c5125580..a30f9b87e3 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -1,2 +1,4 @@ +obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_I2C_IMX) += i2c-imx.o obj-$(CONFIG_I2C_OMAP) += i2c-omap.o +obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c new file mode 100644 index 0000000000..98ce2d59ab --- /dev/null +++ b/drivers/i2c/busses/i2c-gpio.c @@ -0,0 +1,177 @@ +/* + * Bitbanging I2C bus driver using the GPIO API + * + * 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 version 2 as + * published by the Free Software Foundation. + */ + +#include <common.h> +#include <driver.h> +#include <i2c/i2c.h> +#include <i2c/i2c-algo-bit.h> +#include <i2c/i2c-gpio.h> +#include <init.h> +#include <gpio.h> + +struct i2c_gpio_private_data { + struct i2c_adapter adap; + struct i2c_algo_bit_data bit_data; + struct i2c_gpio_platform_data pdata; +}; + +/* Toggle SDA by changing the direction of the pin */ +static void i2c_gpio_setsda_dir(void *data, int state) +{ + struct i2c_gpio_platform_data *pdata = data; + + if (state) + gpio_direction_input(pdata->sda_pin); + else + gpio_direction_output(pdata->sda_pin, 0); +} + +/* + * Toggle SDA by changing the output value of the pin. This is only + * valid for pins configured as open drain (i.e. setting the value + * high effectively turns off the output driver.) + */ +static void i2c_gpio_setsda_val(void *data, int state) +{ + struct i2c_gpio_platform_data *pdata = data; + + gpio_set_value(pdata->sda_pin, state); +} + +/* Toggle SCL by changing the direction of the pin. */ +static void i2c_gpio_setscl_dir(void *data, int state) +{ + struct i2c_gpio_platform_data *pdata = data; + + if (state) + gpio_direction_input(pdata->scl_pin); + else + gpio_direction_output(pdata->scl_pin, 0); +} + +/* + * Toggle SCL by changing the output value of the pin. This is used + * for pins that are configured as open drain and for output-only + * pins. The latter case will break the i2c protocol, but it will + * often work in practice. + */ +static void i2c_gpio_setscl_val(void *data, int state) +{ + struct i2c_gpio_platform_data *pdata = data; + + gpio_set_value(pdata->scl_pin, state); +} + +static int i2c_gpio_getsda(void *data) +{ + struct i2c_gpio_platform_data *pdata = data; + + return gpio_get_value(pdata->sda_pin); +} + +static int i2c_gpio_getscl(void *data) +{ + struct i2c_gpio_platform_data *pdata = data; + + return gpio_get_value(pdata->scl_pin); +} + +static int i2c_gpio_probe(struct device_d *dev) +{ + struct i2c_gpio_private_data *priv; + struct i2c_gpio_platform_data *pdata; + struct i2c_algo_bit_data *bit_data; + struct i2c_adapter *adap; + int ret; + + priv = xzalloc(sizeof(*priv)); + + adap = &priv->adap; + bit_data = &priv->bit_data; + pdata = &priv->pdata; + + if (!dev->platform_data) + return -ENXIO; + memcpy(pdata, dev->platform_data, sizeof(*pdata)); + + ret = gpio_request(pdata->sda_pin, "sda"); + if (ret) + goto err_request_sda; + ret = gpio_request(pdata->scl_pin, "scl"); + if (ret) + goto err_request_scl; + + if (pdata->sda_is_open_drain) { + gpio_direction_output(pdata->sda_pin, 1); + bit_data->setsda = i2c_gpio_setsda_val; + } else { + gpio_direction_input(pdata->sda_pin); + bit_data->setsda = i2c_gpio_setsda_dir; + } + + if (pdata->scl_is_open_drain || pdata->scl_is_output_only) { + gpio_direction_output(pdata->scl_pin, 1); + bit_data->setscl = i2c_gpio_setscl_val; + } else { + gpio_direction_input(pdata->scl_pin); + bit_data->setscl = i2c_gpio_setscl_dir; + } + + if (!pdata->scl_is_output_only) + bit_data->getscl = i2c_gpio_getscl; + bit_data->getsda = i2c_gpio_getsda; + + if (pdata->udelay) + bit_data->udelay = pdata->udelay; + else if (pdata->scl_is_output_only) + bit_data->udelay = 50; /* 10 kHz */ + else + bit_data->udelay = 5; /* 100 kHz */ + + if (pdata->timeout_ms) + bit_data->timeout_ms = pdata->timeout_ms; + else + bit_data->timeout_ms = 100; /* 100 ms */ + + bit_data->data = pdata; + + adap->algo_data = bit_data; + adap->dev.parent = dev; + + adap->nr = dev->id; + ret = i2c_bit_add_numbered_bus(adap); + if (ret) + goto err_add_bus; + + dev_info(dev, "using pins %u (SDA) and %u (SCL%s)\n", + pdata->sda_pin, pdata->scl_pin, + pdata->scl_is_output_only + ? ", no clock stretching" : ""); + + return 0; + +err_add_bus: + gpio_free(pdata->scl_pin); +err_request_scl: + gpio_free(pdata->sda_pin); +err_request_sda: + return ret; +} + +static struct driver_d i2c_gpio_driver = { + .name = "i2c-gpio", + .probe = i2c_gpio_probe, +}; + +static int __init i2c_gpio_init(void) +{ + return platform_driver_register(&i2c_gpio_driver); +} +device_initcall(i2c_gpio_init); diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index a1012a784e..68348eb159 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -154,7 +154,7 @@ static int i2c_fsl_bus_busy(struct i2c_adapter *adapter, int for_busy) if (!for_busy && !(temp & I2SR_IBB)) break; if (is_timeout(start, 500 * MSECOND)) { - dev_err(adapter->dev, + dev_err(&adapter->dev, "<%s> timeout waiting for I2C bus %s\n", __func__,for_busy ? "busy" : "not busy"); return -EIO; @@ -177,7 +177,7 @@ static int i2c_fsl_trx_complete(struct i2c_adapter *adapter) break; if (is_timeout(start, 100 * MSECOND)) { - dev_err(adapter->dev, "<%s> TXR timeout\n", __func__); + dev_err(&adapter->dev, "<%s> TXR timeout\n", __func__); return -EIO; } } @@ -199,7 +199,7 @@ static int i2c_fsl_acked(struct i2c_adapter *adapter) break; if (is_timeout(start, MSECOND)) { - dev_dbg(adapter->dev, "<%s> No ACK\n", __func__); + dev_dbg(&adapter->dev, "<%s> No ACK\n", __func__); return -EIO; } } @@ -296,7 +296,7 @@ static void i2c_fsl_set_clk(struct fsl_i2c_struct *i2c_fsl, * Translate to dfsr = 5 * Frequency / 100,000,000 */ dfsr = (5 * (i2c_clk / 1000)) / 100000; - dev_dbg(i2c_fsl->adapter.dev, + dev_dbg(&i2c_fsl->adapter.dev, "<%s> requested speed:%d, i2c_clk:%d\n", __func__, rate, i2c_clk); if (!dfsr) @@ -315,12 +315,12 @@ static void i2c_fsl_set_clk(struct fsl_i2c_struct *i2c_fsl, bin_ga = (ga & 0x3) | ((ga & 0x4) << 3); fdr = bin_gb | bin_ga; rate = i2c_clk / est_div; - dev_dbg(i2c_fsl->adapter.dev, + dev_dbg(&i2c_fsl->adapter.dev, "FDR:0x%.2x, div:%ld, ga:0x%x, gb:0x%x," " a:%d, b:%d, speed:%d\n", fdr, est_div, ga, gb, a, b, rate); /* Condition 2 not accounted for */ - dev_dbg(i2c_fsl->adapter.dev, + dev_dbg(&i2c_fsl->adapter.dev, "Tr <= %d ns\n", (b - 3 * dfsr) * 1000000 / (i2c_clk / 1000)); } @@ -330,9 +330,9 @@ static void i2c_fsl_set_clk(struct fsl_i2c_struct *i2c_fsl, if (a == 24) a += 4; } - dev_dbg(i2c_fsl->adapter.dev, + dev_dbg(&i2c_fsl->adapter.dev, "divider:%d, est_div:%ld, DFSR:%d\n", divider, est_div, dfsr); - dev_dbg(i2c_fsl->adapter.dev, "FDR:0x%.2x, speed:%d\n", fdr, rate); + dev_dbg(&i2c_fsl->adapter.dev, "FDR:0x%.2x, speed:%d\n", fdr, rate); i2c_fsl->ifdr = fdr; i2c_fsl->dfsrr = dfsr; } @@ -368,9 +368,9 @@ static void i2c_fsl_set_clk(struct fsl_i2c_struct *i2c_fsl, (500000U * i2c_clk_div[i][0] + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2); - dev_dbg(i2c_fsl->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n", + dev_dbg(&i2c_fsl->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n", __func__, i2c_clk_rate, div); - dev_dbg(i2c_fsl->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n", + dev_dbg(&i2c_fsl->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n", __func__, i2c_clk_div[i][1], i2c_clk_div[i][0]); } #endif @@ -382,7 +382,7 @@ static int i2c_fsl_write(struct i2c_adapter *adapter, struct i2c_msg *msgs) int i, result; if ( !(msgs->flags & I2C_M_DATA_ONLY) ) { - dev_dbg(adapter->dev, + dev_dbg(&adapter->dev, "<%s> write slave address: addr=0x%02x\n", __func__, msgs->addr << 1); @@ -399,7 +399,7 @@ static int i2c_fsl_write(struct i2c_adapter *adapter, struct i2c_msg *msgs) /* write data */ for (i = 0; i < msgs->len; i++) { - dev_dbg(adapter->dev, + dev_dbg(&adapter->dev, "<%s> write byte: B%d=0x%02X\n", __func__, i, msgs->buf[i]); writeb(msgs->buf[i], base + FSL_I2C_I2DR); @@ -425,7 +425,7 @@ static int i2c_fsl_read(struct i2c_adapter *adapter, struct i2c_msg *msgs) writeb(0x0, base + FSL_I2C_I2SR); if ( !(msgs->flags & I2C_M_DATA_ONLY) ) { - dev_dbg(adapter->dev, + dev_dbg(&adapter->dev, "<%s> write slave address: addr=0x%02x\n", __func__, (msgs->addr << 1) | 0x01); @@ -478,7 +478,7 @@ static int i2c_fsl_read(struct i2c_adapter *adapter, struct i2c_msg *msgs) } msgs->buf[i] = readb(base + FSL_I2C_I2DR); - dev_dbg(adapter->dev, "<%s> read byte: B%d=0x%02X\n", + dev_dbg(&adapter->dev, "<%s> read byte: B%d=0x%02X\n", __func__, i, msgs->buf[i]); } return 0; @@ -544,7 +544,7 @@ static int __init i2c_fsl_probe(struct device_d *pdev) /* Setup i2c_fsl driver structure */ i2c_fsl->adapter.master_xfer = i2c_fsl_xfer; i2c_fsl->adapter.nr = pdev->id; - i2c_fsl->adapter.dev = pdev; + i2c_fsl->adapter.dev.parent = pdev; i2c_fsl->base = dev_request_mem_region(pdev, 0); i2c_fsl->dfsrr = -1; diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 24961ebda6..f371875aad 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -318,7 +318,7 @@ static int omap_i2c_init(struct omap_i2c_struct *i2c_omap) while (!(omap_i2c_read_reg(i2c_omap, OMAP_I2C_SYSS_REG) & SYSS_RESETDONE_MASK)) { if (is_timeout(start, MSECOND)) { - dev_warn(i2c_omap->adapter.dev, "timeout waiting " + dev_warn(&i2c_omap->adapter.dev, "timeout waiting " "for controller reset\n"); return -ETIMEDOUT; } @@ -453,7 +453,7 @@ static int omap_i2c_wait_for_bb(struct i2c_adapter *adapter) start = get_time_ns(); while (omap_i2c_read_reg(i2c_omap, OMAP_I2C_STAT_REG) & OMAP_I2C_STAT_BB) { if (is_timeout(start, MSECOND)) { - dev_warn(adapter->dev, "timeout waiting for bus ready\n"); + dev_warn(&adapter->dev, "timeout waiting for bus ready\n"); return -ETIMEDOUT; } } @@ -476,9 +476,9 @@ omap_i2c_isr(struct omap_i2c_struct *dev) bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) & bits) { - dev_dbg(dev->adapter.dev, "IRQ (ISR = 0x%04x)\n", stat); + dev_dbg(&dev->adapter.dev, "IRQ (ISR = 0x%04x)\n", stat); if (count++ == 100) { - dev_warn(dev->adapter.dev, "Too much work in one IRQ\n"); + dev_warn(&dev->adapter.dev, "Too much work in one IRQ\n"); break; } @@ -499,7 +499,7 @@ complete: OMAP_I2C_CON_STP); } if (stat & OMAP_I2C_STAT_AL) { - dev_err(dev->adapter.dev, "Arbitration lost\n"); + dev_err(&dev->adapter.dev, "Arbitration lost\n"); err |= OMAP_I2C_STAT_AL; } if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | @@ -536,11 +536,11 @@ complete: } } else { if (stat & OMAP_I2C_STAT_RRDY) - dev_err(dev->adapter.dev, + dev_err(&dev->adapter.dev, "RRDY IRQ while no data" " requested\n"); if (stat & OMAP_I2C_STAT_RDR) - dev_err(dev->adapter.dev, + dev_err(&dev->adapter.dev, "RDR IRQ while no data" " requested\n"); break; @@ -577,11 +577,11 @@ complete: } } else { if (stat & OMAP_I2C_STAT_XRDY) - dev_err(dev->adapter.dev, + dev_err(&dev->adapter.dev, "XRDY IRQ while no " "data to send\n"); if (stat & OMAP_I2C_STAT_XDR) - dev_err(dev->adapter.dev, + dev_err(&dev->adapter.dev, "XDR IRQ while no " "data to send\n"); break; @@ -613,11 +613,11 @@ complete: continue; } if (stat & OMAP_I2C_STAT_ROVR) { - dev_err(dev->adapter.dev, "Receive overrun\n"); + dev_err(&dev->adapter.dev, "Receive overrun\n"); dev->cmd_err |= OMAP_I2C_STAT_ROVR; } if (stat & OMAP_I2C_STAT_XUDF) { - dev_err(dev->adapter.dev, "Transmit underflow\n"); + dev_err(&dev->adapter.dev, "Transmit underflow\n"); dev->cmd_err |= OMAP_I2C_STAT_XUDF; } } @@ -639,7 +639,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adapter, int ret = 0; - dev_dbg(adapter->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", + dev_dbg(&adapter->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", msg->addr, msg->len, msg->flags, stop); if (msg->len == 0) @@ -687,7 +687,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adapter, /* Let the user know if i2c is in a bad state */ if (is_timeout(start, MSECOND)) { - dev_err(adapter->dev, "controller timed out " + dev_err(&adapter->dev, "controller timed out " "waiting for start condition to finish\n"); return -ETIMEDOUT; } @@ -707,7 +707,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adapter, while (ret){ ret = omap_i2c_isr(i2c_omap); if (is_timeout(start, MSECOND)) { - dev_err(adapter->dev, + dev_err(&adapter->dev, "timed out on polling for " "open i2c message handling\n"); return -ETIMEDOUT; @@ -835,7 +835,7 @@ i2c_omap_probe(struct device_d *pdev) i2c_omap->adapter.master_xfer = omap_i2c_xfer, i2c_omap->adapter.nr = pdev->id; - i2c_omap->adapter.dev = pdev; + i2c_omap->adapter.dev.parent = pdev; /* i2c device drivers may be active on return from add_adapter() */ r = i2c_add_numbered_adapter(&i2c_omap->adapter); diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c new file mode 100644 index 0000000000..7c993226f8 --- /dev/null +++ b/drivers/i2c/busses/i2c-versatile.c @@ -0,0 +1,112 @@ +/* + * i2c-versatile.c + * + * Copyright (C) 2006 ARM Ltd. + * written by Russell King, Deep Blue Solutions Ltd. + * + * 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. + */ +#include <common.h> +#include <driver.h> +#include <i2c/i2c.h> +#include <i2c/i2c-algo-bit.h> +#include <init.h> +#include <malloc.h> +#include <io.h> + +#define I2C_CONTROL 0x00 +#define I2C_CONTROLS 0x00 +#define I2C_CONTROLC 0x04 +#define SCL (1 << 0) +#define SDA (1 << 1) + +struct i2c_versatile { + struct i2c_adapter adap; + struct i2c_algo_bit_data algo; + void __iomem *base; +}; + +static void i2c_versatile_setsda(void *data, int state) +{ + struct i2c_versatile *i2c = data; + + writel(SDA, i2c->base + (state ? I2C_CONTROLS : I2C_CONTROLC)); +} + +static void i2c_versatile_setscl(void *data, int state) +{ + struct i2c_versatile *i2c = data; + + writel(SCL, i2c->base + (state ? I2C_CONTROLS : I2C_CONTROLC)); +} + +static int i2c_versatile_getsda(void *data) +{ + struct i2c_versatile *i2c = data; + return !!(readl(i2c->base + I2C_CONTROL) & SDA); +} + +static int i2c_versatile_getscl(void *data) +{ + struct i2c_versatile *i2c = data; + return !!(readl(i2c->base + I2C_CONTROL) & SCL); +} + +static struct i2c_algo_bit_data i2c_versatile_algo = { + .setsda = i2c_versatile_setsda, + .setscl = i2c_versatile_setscl, + .getsda = i2c_versatile_getsda, + .getscl = i2c_versatile_getscl, + .udelay = 30, + .timeout_ms = 100, +}; + +static int i2c_versatile_probe(struct device_d *dev) +{ + struct i2c_versatile *i2c; + int ret; + + i2c = kzalloc(sizeof(struct i2c_versatile), GFP_KERNEL); + if (!i2c) { + ret = -ENOMEM; + goto err_release; + } + + i2c->base = dev_request_mem_region(dev, 0); + if (!i2c->base) { + ret = -ENOMEM; + goto err_free; + } + + writel(SCL | SDA, i2c->base + I2C_CONTROLS); + + i2c->adap.algo_data = &i2c->algo; + i2c->adap.dev.parent = dev; + i2c->algo = i2c_versatile_algo; + i2c->algo.data = i2c; + + i2c->adap.nr = dev->id; + ret = i2c_bit_add_numbered_bus(&i2c->adap); + if (ret >= 0) { + return 0; + } + + err_free: + kfree(i2c); + err_release: + return ret; +} + +static struct driver_d i2c_versatile_driver = { + .name = "versatile-i2c", + .probe = i2c_versatile_probe, +}; + +static int __init i2c_versatile_init(void) +{ + return platform_driver_register(&i2c_versatile_driver); +} + +device_initcall(i2c_versatile_init); diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c index 27fd256cf7..94f23dd854 100644 --- a/drivers/i2c/i2c.c +++ b/drivers/i2c/i2c.c @@ -80,7 +80,7 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) */ for (ret = 0; ret < num; ret++) { - dev_dbg(adap->dev, "master_xfer[%d] %c, addr=0x%02x, " + dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, " "len=%d\n", ret, (msgs[ret].flags & I2C_M_RD) ? 'R' : 'W', msgs[ret].addr, msgs[ret].len); } @@ -256,6 +256,9 @@ struct i2c_client *i2c_new_device(struct i2c_adapter *adapter, client->adapter = adapter; client->addr = chip->addr; + client->dev.parent = &adapter->dev; + dev_add_child(client->dev.parent, &client->dev); + status = register_device(&client->dev); #if 0 @@ -279,6 +282,34 @@ struct i2c_client *i2c_new_device(struct i2c_adapter *adapter, EXPORT_SYMBOL(i2c_new_device); /** + * i2c_new_dummy - return a new i2c device bound to a dummy driver + * @adapter: the adapter managing the device + * @address: seven bit address to be used + * Context: can sleep + * + * This returns an I2C client bound to the "dummy" driver, intended for use + * with devices that consume multiple addresses. Examples of such chips + * include various EEPROMS (like 24c04 and 24c08 models). + * + * These dummy devices have two main uses. First, most I2C and SMBus calls + * except i2c_transfer() need a client handle; the dummy will be that handle. + * And second, this prevents the specified address from being bound to a + * different driver. + * + * This returns the new i2c client, which should be saved for later use with + * i2c_unregister_device(); or NULL to indicate an error. + */ +struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address) +{ + struct i2c_board_info info = { + I2C_BOARD_INFO("dummy", address), + }; + + return i2c_new_device(adapter, &info); +} +EXPORT_SYMBOL_GPL(i2c_new_dummy); + +/** * i2c_register_board_info - register I2C devices for a given board * * @param info array of chip descriptors @@ -363,9 +394,21 @@ struct i2c_adapter *i2c_get_adapter(int busnum) */ int i2c_add_numbered_adapter(struct i2c_adapter *adapter) { + int ret; + if (i2c_get_adapter(adapter->nr)) return -EBUSY; + adapter->dev.id = adapter->nr; + strcpy(adapter->dev.name, "i2c"); + + if (adapter->dev.parent) + dev_add_child(adapter->dev.parent, &adapter->dev); + + ret = register_device(&adapter->dev); + if (ret) + return ret; + list_add_tail(&adapter->list, &adapter_list); /* populate children from any i2c device tables */ @@ -377,7 +420,22 @@ EXPORT_SYMBOL(i2c_add_numbered_adapter); static int i2c_match(struct device_d *dev, struct driver_d *drv) { - return strcmp(dev->name, drv->name) ? -1 : 0; + if (!strcmp(dev->name, drv->name)) + return 0; + + if (drv->id_table) { + struct platform_device_id *id = drv->id_table; + + while (id->name) { + if (!strcmp(id->name, dev->name)) { + dev->id_entry = id; + return 0; + } + id++; + } + } + + return -1; } static int i2c_probe(struct device_d *dev) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 15979a2761..846483c794 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -30,4 +30,12 @@ config KEYBOARD_IMX_KEYPAD setup logic must also provide a 'matrix_keymap_data' structure, defining the used keys. +config KEYBOARD_QT1070 + tristate "Atmel AT42QT1070 Touch Sensor Chip" + depends on I2C + select POLLER + help + Say Y here if you want to use Atmel AT42QT1070 QTouch + Sensor chip as input device. + endmenu diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 3d105cc8b0..d042980b15 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o obj-$(CONFIG_KEYBOARD_IMX_KEYPAD) += imx_keypad.o +obj-$(CONFIG_KEYBOARD_QT1070) += qt1070.o diff --git a/drivers/input/qt1070.c b/drivers/input/qt1070.c new file mode 100644 index 0000000000..c66189e9c7 --- /dev/null +++ b/drivers/input/qt1070.c @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#include <common.h> +#include <errno.h> +#include <init.h> +#include <clock.h> +#include <poller.h> +#include <kfifo.h> +#include <i2c/i2c.h> +#include <malloc.h> +#include <readkey.h> +#include <input/qt1070.h> +#include <gpio.h> + +#define QT1070_CHIP_ID 0x2e + +#define QT1070_READ_CHIP_ID 0x00 +#define QT1070_FW_VERSION 0x01 +#define QT1070_DET_STATUS 0x02 +#define QT1070_KEY_STATUS 0x03 + +/* Calibrate */ +#define QT1070_CALIBRATE_CMD 0x38 +#define QT1070_CAL_TIME 200 + +/* Reset */ +#define QT1070_RESET 0x39 +#define QT1070_RESET_TIME 255 + +static int default_code[QT1070_NB_BUTTONS] = { + KEY_ENTER, KEY_HOME, KEY_UP, KEY_DOWN, + KEY_RIGHT, KEY_LEFT, KEY_CLEAR_SCREEN }; + +struct qt1070_data { + int code[QT1070_NB_BUTTONS]; + + int irq_pin; + + u64 start; + + /* optional */ + int fifo_size; + + struct i2c_client *client; + u8 button_state[QT1070_NB_BUTTONS]; + u8 previous_state; + + struct kfifo *recv_fifo; + struct poller_struct poller; + struct console_device cdev; +}; + +static inline struct qt1070_data * +poller_to_qt_data(struct poller_struct *poller) +{ + return container_of(poller, struct qt1070_data, poller); +} + +static inline struct qt1070_data * +cdev_to_qt_data(struct console_device *cdev) +{ + return container_of(cdev, struct qt1070_data, cdev); +} + +static bool qt1070_read(struct qt1070_data *data, u8 reg, u8 *val) +{ + int ret; + + ret = i2c_read_reg(data->client, reg, val, 1); + + if (ret < 0) + return ret; + if (ret != 1) + return -EIO; + return 0; +} + +static bool qt1070_write(struct qt1070_data *data, u8 reg, const u8 val) +{ + int ret; + + ret = i2c_write_reg(data->client, reg, &val, 1); + if (ret < 0) + return ret; + if (ret != 1) + return -EIO; + return 0; +} + +static void qt1070_poller(struct poller_struct *poller) +{ + struct qt1070_data *data = poller_to_qt_data(poller); + int i; + u8 buf, bt; + u8 mask = 0x1; + + if (gpio_is_valid(data->irq_pin)) { + /* active low */ + if (gpio_get_value(data->irq_pin)) + return; + } + + qt1070_read(data, QT1070_DET_STATUS, &buf); + + if (qt1070_read(data, QT1070_KEY_STATUS, &buf)) + return; + + if (!buf & !data->previous_state) + return; + + for (i = 0; i < QT1070_NB_BUTTONS; i++) { + bt = buf & mask; + + if (!bt && data->button_state[i]) { + dev_dbg(data->cdev.dev, "release key(%d) as %d\n", i, data->code[i]); + kfifo_put(data->recv_fifo, (u_char*)&data->code[i], sizeof(int)); + } else if (bt) { + dev_dbg(data->cdev.dev, "pressed key(%d) as %d\n", i, data->code[i]); + } + + data->button_state[i] = bt; + mask <<= 1; + } + + data->previous_state = buf; +} + +static void qt1070_reset_poller(struct poller_struct *poller) +{ + struct qt1070_data *data = poller_to_qt_data(poller); + u8 buf; + + if (!is_timeout_non_interruptible(data->start, QT1070_RESET_TIME * MSECOND)) + return; + + /* clear the status */ + qt1070_read(data, QT1070_DET_STATUS, &buf); + + poller->func = qt1070_poller; +} + +static void qt1070_calibrate_poller(struct poller_struct *poller) +{ + struct qt1070_data *data = poller_to_qt_data(poller); + int ret; + + if (!is_timeout_non_interruptible(data->start, QT1070_CAL_TIME * MSECOND)) + return; + + /* Soft reset */ + ret = qt1070_write(data, QT1070_RESET, 1); + if (ret) { + dev_err(data->cdev.dev, "can not reset the chip (%d)\n", ret); + poller_unregister(poller); + return; + } + data->start = get_time_ns(); + + poller->func = qt1070_reset_poller; +} + +static int qt1070_tstc(struct console_device *cdev) +{ + struct qt1070_data *data = cdev_to_qt_data(cdev); + + return (kfifo_len(data->recv_fifo) == 0) ? 0 : 1; +} + +static int qt1070_getc(struct console_device *cdev) +{ + int code = 0; + struct qt1070_data *data = cdev_to_qt_data(cdev); + + kfifo_get(data->recv_fifo, (u_char*)&code, sizeof(int)); + return code; +} + +static int qt1070_pdata_init(struct device_d *dev, struct qt1070_data *data) +{ + struct qt1070_platform_data *pdata = dev->platform_data; + int ret; + + if (!pdata) + return 0; + + if (pdata->nb_code) + memcpy(data->code, pdata->code, sizeof(int) * pdata->nb_code); + + if (!gpio_is_valid(pdata->irq_pin)) + return 0; + + ret = gpio_request(pdata->irq_pin, "qt1070"); + if (ret) + return ret; + + ret = gpio_direction_input(pdata->irq_pin); + if (ret) + goto err; + + data->irq_pin = pdata->irq_pin; + + return 0; +err: + gpio_free(pdata->irq_pin); + return ret; +} + +static int qt1070_probe(struct device_d *dev) +{ + struct console_device *cdev; + struct qt1070_data *data; + u8 fw_version, chip_id; + int ret; + char buf[6]; + + data = xzalloc(sizeof(*data)); + data->client = to_i2c_client(dev); + data->irq_pin = -EINVAL; + + ret = qt1070_read(data, QT1070_READ_CHIP_ID, &chip_id); + if (ret) { + dev_err(dev, "can not read chip id (%d)\n", ret); + goto err; + } + + if (chip_id != QT1070_CHIP_ID) { + dev_err(dev, "unsupported id 0x%x\n", chip_id); + ret = -ENXIO; + goto err; + } + + ret = qt1070_read(data, QT1070_FW_VERSION, &fw_version); + if (ret) { + dev_err(dev, "can not read firmware version (%d)\n", ret); + goto err; + } + + sprintf(buf, "0x%x", fw_version); + dev_add_param_fixed(dev, "fw_version", buf); + sprintf(buf, "0x%x", chip_id); + dev_add_param_fixed(dev, "chip_ip", buf); + + ret = qt1070_pdata_init(dev, data); + if (ret) { + dev_err(dev, "can not get pdata (%d)\n", ret); + goto err; + } + + /* Calibrate device */ + ret = qt1070_write(data, QT1070_CALIBRATE_CMD, 1); + if (ret) { + dev_err(dev, "can not calibrate the chip (%d)\n", ret); + goto err; + } + data->start = get_time_ns(); + + memcpy(data->code, default_code, sizeof(int) * ARRAY_SIZE(default_code)); + + data->fifo_size = 50; + data->recv_fifo = kfifo_alloc(data->fifo_size); + + data->poller.func = qt1070_calibrate_poller; + + cdev = &data->cdev; + cdev->dev = dev; + cdev->f_caps = CONSOLE_STDIN; + cdev->tstc = qt1070_tstc; + cdev->getc = qt1070_getc; + + console_register(&data->cdev); + + ret = poller_register(&data->poller); + if (ret) + goto err; + + return 0; +err: + free(data); + return ret; +} + +static struct driver_d qt1070_driver = { + .name = "qt1070", + .probe = qt1070_probe, +}; + +static int qt1070_init(void) +{ + i2c_register_driver(&qt1070_driver); + return 0; +} +device_initcall(qt1070_init); diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig index b1a678e17a..5c0ca4dfa0 100644 --- a/drivers/mci/Kconfig +++ b/drivers/mci/Kconfig @@ -88,6 +88,7 @@ config MCI_ATMEL config MCI_SPI bool "MMC/SD over SPI" + select CRC7 depends on SPI help Some systems access MMC/SD/SDIO cards using a SPI controller @@ -98,7 +99,6 @@ config MCI_SPI config MMC_SPI_CRC_ON bool "Enable CRC protection for transfers" - select CRC7 select CRC16 depends on MCI_SPI help diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c index 216a8a59f7..bf2b0f897e 100644 --- a/drivers/mci/mci-core.c +++ b/drivers/mci/mci-core.c @@ -222,6 +222,7 @@ static int sd_send_op_cond(struct mci *mci) int err; unsigned voltages; unsigned busy; + unsigned arg; /* * Most cards do not answer if some reserved bits @@ -240,9 +241,12 @@ static int sd_send_op_cond(struct mci *mci) return err; } - mci_setup_cmd(&cmd, SD_CMD_APP_SEND_OP_COND, - mmc_host_is_spi(host) ? 0 : (voltages | (mci->version == SD_VERSION_2 ? OCR_HCS : 0)), - MMC_RSP_R3); + arg = mmc_host_is_spi(host) ? 0 : voltages; + + if (mci->version == SD_VERSION_2) + arg |= OCR_HCS; + + mci_setup_cmd(&cmd, SD_CMD_APP_SEND_OP_COND, arg, MMC_RSP_R3); err = mci_send_cmd(mci, &cmd, NULL); if (err) { dev_dbg(mci->mci_dev, "SD operation condition set failed: %d\n", err); @@ -749,7 +753,7 @@ static void mci_extract_card_capacity_from_csd(struct mci *mci) mci->capacity = (csize + 1) << (cmult + 2); mci->capacity *= mci->read_bl_len; - dev_dbg(mci->mci_dev, "Capacity: %u MiB\n", (unsigned)mci->capacity >> 20); + dev_dbg(mci->mci_dev, "Capacity: %u MiB\n", (unsigned)(mci->capacity >> 20)); } static int mmc_compare_ext_csds(struct mci *mci, unsigned bus_width) diff --git a/drivers/mci/mci_spi.c b/drivers/mci/mci_spi.c index 5894104231..679a0e1e02 100644 --- a/drivers/mci/mci_spi.c +++ b/drivers/mci/mci_spi.c @@ -121,14 +121,6 @@ mmc_spi_writebytes(struct mmc_spi_host *host, unsigned len, void *data) return status; } -/* - * Note that while the CRC, in general, is ignored in SPI mode, the very first - * command must be followed by a valid CRC, since the card is not yet in SPI mode. - * The CRC byte for a CMD0 command with a zero argument is a constant 0x4A. For - * simplicity, this CRC byte is always sent with every command. - */ -#define MMC_SPI_CMD0_CRC ((0x4a << 1) | 0x1) - static int mmc_spi_command_send(struct mmc_spi_host *host, struct mci_cmd *cmd) { uint8_t r1; @@ -141,11 +133,7 @@ static int mmc_spi_command_send(struct mmc_spi_host *host, struct mci_cmd *cmd) command[3] = cmd->cmdarg >> 16; command[4] = cmd->cmdarg >> 8; command[5] = cmd->cmdarg; -#ifdef CONFIG_MMC_SPI_CRC_ON command[6] = (crc7(0, &command[1], 5) << 1) | 0x01; -#else - command[6] = MMC_SPI_CMD0_CRC; -#endif mmc_spi_writebytes(host, 7, command); @@ -330,7 +318,15 @@ static void mmc_spi_set_ios(struct mci_host *mci, struct mci_ios *ios) { struct mmc_spi_host *host = to_spi_host(mci); - spi_setup(host->spi); + if (host->spi->max_speed_hz != ios->clock && ios->clock != 0) { + int status; + + host->spi->max_speed_hz = ios->clock; + status = spi_setup(host->spi); + dev_dbg(&host->spi->dev, + "mmc_spi: clock to %d Hz, %d\n", + host->spi->max_speed_hz, status); + } } static int mmc_spi_init(struct mci_host *mci, struct device_d *mci_dev) @@ -378,6 +374,7 @@ static int spi_mci_probe(struct device_d *dev) struct spi_device *spi = (struct spi_device *)dev->type_data; struct mmc_spi_host *host; void *ones; + int status; host = xzalloc(sizeof(*host)); host->mci.send_cmd = mmc_spi_request; @@ -385,6 +382,35 @@ static int spi_mci_probe(struct device_d *dev) host->mci.init = mmc_spi_init; host->mci.hw_dev = dev; + /* MMC and SD specs only seem to care that sampling is on the + * rising edge ... meaning SPI modes 0 or 3. So either SPI mode + * should be legit. We'll use mode 0 since the steady state is 0, + * which is appropriate for hotplugging, unless the platform data + * specify mode 3 (if hardware is not compatible to mode 0). + */ + if (spi->mode != SPI_MODE_3) + spi->mode = SPI_MODE_0; + spi->bits_per_word = 8; + + status = spi_setup(spi); + if (status < 0) { + dev_dbg(&spi->dev, "needs SPI mode %02x, %d KHz; %d\n", + spi->mode, spi->max_speed_hz / 1000, + status); + return status; + } + + /* SPI doesn't need the lowspeed device identification thing for + * MMC or SD cards, since it never comes up in open drain mode. + * That's good; some SPI masters can't handle very low speeds! + * + * However, low speed SDIO cards need not handle over 400 KHz; + * that's the only reason not to use a few MHz for f_min (until + * the upper layer reads the target frequency from the CSD). + */ + host->mci.f_min = 400000; + host->mci.f_max = spi->max_speed_hz; + host->dev = dev; host->spi = spi; dev->priv = host; diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index 12e95c16b4..d7c29cc636 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c @@ -35,7 +35,7 @@ int stmpe_reg_read(struct stmpe *stmpe, u32 reg, u8 *val) return ret == 1 ? 0 : ret; } -EXPORT_SYMBOL(stmpe_reg_read) +EXPORT_SYMBOL(stmpe_reg_read); int stmpe_reg_write(struct stmpe *stmpe, u32 reg, u8 val) { @@ -45,7 +45,7 @@ int stmpe_reg_write(struct stmpe *stmpe, u32 reg, u8 val) return ret == 1 ? 0 : ret; } -EXPORT_SYMBOL(stmpe_reg_write) +EXPORT_SYMBOL(stmpe_reg_write); int stmpe_set_bits(struct stmpe *stmpe, u32 reg, u8 mask, u8 val) { diff --git a/drivers/mfd/twl6030.c b/drivers/mfd/twl6030.c index 01728fd317..6b872abe95 100644 --- a/drivers/mfd/twl6030.c +++ b/drivers/mfd/twl6030.c @@ -39,6 +39,27 @@ static int twl_probe(struct device_d *dev) devfs_create(&(twl_dev->core.cdev)); + if (IS_ENABLED(CONFIG_DEBUG)) { + u8 i, jtag_rev, eprom_rev; + int r; + u64 dieid; + + r = twl6030_reg_read(twl_dev, TWL6030_JTAG_JTAGVERNUM, + &jtag_rev); + r |= twl6030_reg_read(twl_dev, TWL6030_JTAG_EPROM_REV, + &eprom_rev); + for (i = 0; i < 8; i++) + r |= twl6030_reg_read(twl_dev, TWL6030_DIEID_0+i, + ((u8 *)(&dieid))+i); + if (r) + dev_dbg(dev, "TWL6030 Error reading ID\n"); + else + dev_dbg(dev, "TWL6030 JTAG REV: 0x%02X, " + "EPROM REV: 0x%02X, " + "DIE ID: 0x%016llX\n", + (unsigned)jtag_rev, (unsigned)eprom_rev, dieid); + } + return 0; } diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index c3d31ec9a2..699046b0de 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -11,6 +11,7 @@ if MISC_DEVICES config JTAG tristate "JTAG Bitbang driver" + depends on GENERIC_GPIO help Controls JTAG chains connected to I/O pins diff --git a/drivers/misc/jtag.c b/drivers/misc/jtag.c index cf2d000756..6c5dea4f2b 100644 --- a/drivers/misc/jtag.c +++ b/drivers/misc/jtag.c @@ -21,14 +21,12 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <fs.h> +#include <common.h> #include <errno.h> -//#include <linux/list.h> #include <jtag.h> #include <gpio.h> #include <driver.h> #include <malloc.h> -#include <common.h> #include <init.h> #include <ioctl.h> diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c index 65507419c4..7c323a1b3a 100644 --- a/drivers/mtd/core.c +++ b/drivers/mtd/core.c @@ -143,6 +143,7 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf) user->flags = mtd->flags; user->size = mtd->size; user->erasesize = mtd->erasesize; + user->writesize = mtd->writesize; user->oobsize = mtd->oobsize; user->mtd = mtd; /* The below fields are obsolete */ diff --git a/drivers/mtd/mtdraw.c b/drivers/mtd/mtdraw.c index f541802a84..079575c326 100644 --- a/drivers/mtd/mtdraw.c +++ b/drivers/mtd/mtdraw.c @@ -258,11 +258,11 @@ static int mtdraw_erase(struct cdev *cdev, size_t count, loff_t _offset) } #else static ssize_t mtdraw_write(struct cdev *cdev, const void *buf, size_t count, - ulong offset, ulong flags) + loff_t offset, ulong flags) { return 0; } -static ssize_t mtdraw_erase(struct cdev *cdev, size_t count, ulong offset) +static ssize_t mtdraw_erase(struct cdev *cdev, size_t count, loff_t offset) { return 0; } diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 6889b4430c..3876a144e9 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -55,6 +55,7 @@ config NAND_IMX config NAND_MXS bool + select NAND_BBT prompt "i.MX23/28 NAND driver" depends on MXS_APBH_DMA diff --git a/drivers/mtd/nand/nand_imx.c b/drivers/mtd/nand/nand_imx.c index b1b7f55e0e..7a207e3236 100644 --- a/drivers/mtd/nand/nand_imx.c +++ b/drivers/mtd/nand/nand_imx.c @@ -26,7 +26,6 @@ #include <linux/mtd/nand.h> #include <mach/generic.h> #include <mach/imx-nand.h> -#include <mach/imx-regs.h> #include <io.h> #include <errno.h> @@ -1107,12 +1106,6 @@ static int __init imxnd_probe(struct device_d *dev) struct nand_ecclayout *oob_smallpage, *oob_largepage, *oob_4kpage; int err = 0; -#ifdef CONFIG_ARCH_IMX27 - PCCR1 |= PCCR1_NFC_BAUDEN; -#endif -#ifdef CONFIG_ARCH_IMX21 - PCCR0 |= PCCR0_NFC_EN; -#endif /* Allocate memory for MTD device structure and private data */ host = kzalloc(sizeof(struct imx_nand_host) + NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE, GFP_KERNEL); @@ -1175,6 +1168,9 @@ static int __init imxnd_probe(struct device_d *dev) oob_smallpage = &nandv2_hw_eccoob_smallpage; oob_largepage = &nandv2_hw_eccoob_largepage; oob_4kpage = &nandv2_hw_eccoob_4k; + } else { + err = -EINVAL; + goto escan; } host->dev = dev; diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index f2c8923c46..1ea12095c2 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -701,7 +701,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) * * This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number * to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in - * which case this function finds a vacant device nubert and assings it + * which case this function finds a vacant device number and assigns it * automatically. Returns the new UBI device number in case of success and a * negative error code in case of failure. * diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 93c3491b9f..4bc4a99019 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -23,7 +23,7 @@ static ssize_t ubi_volume_cdev_read(struct cdev *cdev, void *buf, size_t size, loff_t offp = offset; int usable_leb_size = vol->usable_leb_size; - printf("%s: %d @ 0x%08llx\n", __func__, size, offset); + printf("%s: %zd @ 0x%08llx\n", __func__, size, offset); len = size > usable_leb_size ? usable_leb_size : size; diff --git a/drivers/net/designware.c b/drivers/net/designware.c index ec518252dd..44cd15b432 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -241,6 +241,16 @@ static void dwc_update_linkspeed(struct eth_device *edev) conf &= ~MII_PORTSELECT; else conf |= MII_PORTSELECT; + + if ((edev->phydev->interface != PHY_INTERFACE_MODE_MII) && + (edev->phydev->interface != PHY_INTERFACE_MODE_GMII)) { + + if (edev->phydev->speed == 100) + conf |= FES_100; + else + conf &= ~FES_100; + } + writel(conf, &mac_p->conf); } diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index b95c4f056e..2378a19366 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -30,7 +30,6 @@ #include <asm/mmu.h> #include <mach/generic.h> -#include <mach/imx-regs.h> #include <mach/clock.h> #ifndef CONFIG_ARCH_MXS # include <mach/iim.h> @@ -310,7 +309,7 @@ static int fec_init(struct eth_device *dev) } if (fec->xcv_type == RMII) { - if (cpu_is_mx28()) { + if (fec_is_imx28(fec)) { rcntl |= FEC_R_CNTRL_RMII_MODE | FEC_R_CNTRL_FCE | FEC_R_CNTRL_NO_LGTH_CHECK; } else { @@ -340,7 +339,7 @@ static int fec_init(struct eth_device *dev) xwmrk = 0x2; /* set ENET tx at store and forward mode */ - if (cpu_is_mx6()) + if (fec_is_imx6(fec)) xwmrk |= 1 << 8; writel(xwmrk, fec->regs + FEC_X_WMRK); @@ -407,7 +406,7 @@ static int fec_open(struct eth_device *edev) ecr = FEC_ECNTRL_ETHER_EN; /* Enable Swap to support little-endian device */ - if (cpu_is_mx6()) + if (fec_is_imx6(fec)) ecr |= 0x100; writel(ecr, fec->regs + FEC_ECNTRL); @@ -481,7 +480,7 @@ static int fec_send(struct eth_device *dev, void *eth_data, int data_length) * Note: We are always using the first buffer for transmission, * the second will be empty and only used to stop the DMA engine */ - if (cpu_is_mx28()) + if (fec_is_imx28(fec)) eth_data = imx28_fix_endianess_wr(eth_data, (data_length + 3) >> 2); writew(data_length, &fec->tbd_base[fec->tbd_index].data_length); @@ -548,7 +547,7 @@ static int fec_recv(struct eth_device *dev) printf("some error: 0x%08x\n", ievent); return 0; } - if (!cpu_is_mx28()) { + if (!fec_is_imx28(fec)) { if (ievent & FEC_IEVENT_HBERR) { /* Heartbeat error */ writel(readl(fec->regs + FEC_X_CNTRL) | 0x1, @@ -574,7 +573,7 @@ static int fec_recv(struct eth_device *dev) if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) && ((readw(&rbd->data_length) - 4) > 14)) { - if (cpu_is_mx28()) + if (fec_is_imx28(fec)) imx28_fix_endianess_rd( phys_to_virt(readl(&rbd->data_pointer)), (readw(&rbd->data_length) + 3) >> 2); @@ -628,15 +627,18 @@ static int fec_probe(struct device_d *dev) struct fec_priv *fec; void *base; int ret; -#ifdef CONFIG_ARCH_IMX27 - PCCR0 |= PCCR0_FEC_EN; -#endif + enum fec_type type; + + ret = dev_get_drvdata(dev, (unsigned long *)&type); + if (ret) + return ret; + fec = xzalloc(sizeof(*fec)); + fec->type = type; edev = &fec->edev; dev->priv = fec; edev->priv = fec; edev->open = fec_open; - edev->init = fec_init; edev->send = fec_send; edev->recv = fec_recv; edev->halt = fec_halt; @@ -675,14 +677,21 @@ static int fec_probe(struct device_d *dev) fec_alloc_receive_packets(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE); - fec->xcv_type = pdata->xcv_type; + if (pdata) { + fec->xcv_type = pdata->xcv_type; + fec->phy_init = pdata->phy_init; + fec->phy_addr = pdata->phy_addr; + } else { + fec->xcv_type = MII100; + fec->phy_addr = -1; + } + + fec_init(edev); if (fec->xcv_type != SEVENWIRE) { - fec->phy_init = pdata->phy_init; fec->miibus.read = fec_miibus_read; fec->miibus.write = fec_miibus_write; - fec->phy_addr = pdata->phy_addr; - switch (pdata->xcv_type) { + switch (fec->xcv_type) { case RMII: fec->interface = PHY_INTERFACE_MODE_RMII; break; @@ -719,13 +728,45 @@ static void fec_remove(struct device_d *dev) fec_halt(&fec->edev); } +static __maybe_unused struct of_device_id imx_fec_dt_ids[] = { + { + .compatible = "fsl,imx27-fec", + .data = FEC_TYPE_IMX27, + }, { + .compatible = "fsl,imx28-fec", + .data = FEC_TYPE_IMX28, + }, { + .compatible = "fsl,imx6q-fec", + .data = FEC_TYPE_IMX6, + }, { + /* sentinel */ + } +}; + +static struct platform_device_id imx_fec_ids[] = { + { + .name = "imx27-fec", + .driver_data = (unsigned long)FEC_TYPE_IMX27, + }, { + .name = "imx28-fec", + .driver_data = (unsigned long)FEC_TYPE_IMX28, + }, { + .name = "imx6-fec", + .driver_data = (unsigned long)FEC_TYPE_IMX6, + }, { + /* sentinel */ + }, +}; + /** * Driver description for registering */ static struct driver_d fec_driver = { - .name = "fec_imx", - .probe = fec_probe, + .name = "fec_imx", + .probe = fec_probe, .remove = fec_remove, + .of_compatible = DRV_OF_COMPAT(imx_fec_dt_ids), + .id_table = imx_fec_ids, }; static int fec_register(void) diff --git a/drivers/net/fec_imx.h b/drivers/net/fec_imx.h index d147dca113..1eb1eba5a1 100644 --- a/drivers/net/fec_imx.h +++ b/drivers/net/fec_imx.h @@ -122,6 +122,12 @@ struct buffer_descriptor { uint32_t data_pointer; /**< payload's buffer address */ }; +enum fec_type { + FEC_TYPE_IMX27, + FEC_TYPE_IMX28, + FEC_TYPE_IMX6, +}; + /** * @brief i.MX27-FEC private structure */ @@ -139,8 +145,24 @@ struct fec_priv { struct mii_bus miibus; void (*phy_init)(struct phy_device *dev); struct clk *clk; + enum fec_type type; }; +static inline int fec_is_imx27(struct fec_priv *priv) +{ + return priv->type == FEC_TYPE_IMX27; +} + +static inline int fec_is_imx28(struct fec_priv *priv) +{ + return priv->type == FEC_TYPE_IMX28; +} + +static inline int fec_is_imx6(struct fec_priv *priv) +{ + return priv->type == FEC_TYPE_IMX6; +} + /** * @brief Numbers of buffer descriptors for receiving * diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index bf834b622e..55675baea6 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -82,7 +82,6 @@ static void gfar_adjust_link(struct eth_device *edev) struct gfar_private *priv = edev->priv; void __iomem *regs = priv->regs; u32 ecntrl, maccfg2; - uint32_t status; priv->link = edev->phydev->link; priv->duplexity =edev->phydev->duplex; diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index b66261ae99..616b539887 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -14,4 +14,9 @@ config GENERIC_PHY endif +config SMSC_PHY + bool "Drivers for SMSC PHYs" + ---help--- + Currently supports the LAN83C185, LAN8187 and LAN8700 PHYs + endmenu diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 82e90d426a..0caeb7058d 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -1,2 +1,3 @@ obj-y += phy.o mdio_bus.o obj-$(CONFIG_GENERIC_PHY) += generic.o +obj-$(CONFIG_SMSC_PHY) += smsc.o diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 88c3ff7723..e1ecc27ae9 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -581,3 +581,15 @@ int phy_driver_register(struct phy_driver *phydrv) return register_driver(&phydrv->drv); } + +int phy_drivers_register(struct phy_driver *new_driver, int n) +{ + int i, ret = 0; + + for (i = 0; i < n; i++) { + ret = phy_driver_register(new_driver + i); + if (ret) + return ret; + } + return ret; +} diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c new file mode 100644 index 0000000000..a318624dce --- /dev/null +++ b/drivers/net/phy/smsc.c @@ -0,0 +1,146 @@ +/* + * drivers/net/phy/smsc.c + * + * Driver for SMSC PHYs + * + * Author: Herbert Valerio Riedel + * + * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org> + * + * 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. + * + * Support added for SMSC LAN8187 and LAN8700 by steve.glendinning@shawell.net + * + */ + +#include <common.h> +#include <init.h> +#include <linux/mii.h> +#include <linux/ethtool.h> +#include <linux/phy.h> +#include <linux/smscphy.h> + +static int smsc_phy_ack_interrupt(struct phy_device *phydev) +{ + int rc = phy_read (phydev, MII_LAN83C185_ISF); + + return rc < 0 ? rc : 0; +} + +static int smsc_phy_config_init(struct phy_device *phydev) +{ + int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); + if (rc < 0) + return rc; + + /* Enable energy detect mode for this SMSC Transceivers */ + rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, + rc | MII_LAN83C185_EDPWRDOWN); + if (rc < 0) + return rc; + + return smsc_phy_ack_interrupt (phydev); +} + +static int lan87xx_config_init(struct phy_device *phydev) +{ + /* + * Make sure the EDPWRDOWN bit is NOT set. Setting this bit on + * LAN8710/LAN8720 PHY causes the PHY to misbehave, likely due + * to a bug on the chip. + * + * When the system is powered on with the network cable being + * disconnected all the way until after ifconfig ethX up is + * issued for the LAN port with this PHY, connecting the cable + * afterwards does not cause LINK change detection, while the + * expected behavior is the Link UP being detected. + */ + int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); + if (rc < 0) + return rc; + + rc &= ~MII_LAN83C185_EDPWRDOWN; + + rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, rc); + if (rc < 0) + return rc; + + return smsc_phy_ack_interrupt(phydev); +} + +static int lan911x_config_init(struct phy_device *phydev) +{ + return smsc_phy_ack_interrupt(phydev); +} + +static struct phy_driver smsc_phy_driver[] = { +{ + .phy_id = 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */ + .phy_id_mask = 0xfffffff0, + .drv.name = "SMSC LAN83C185", + + .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause + | SUPPORTED_Asym_Pause), + + /* basic functions */ + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, + .config_init = smsc_phy_config_init, +}, { + .phy_id = 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */ + .phy_id_mask = 0xfffffff0, + .drv.name = "SMSC LAN8187", + + .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause + | SUPPORTED_Asym_Pause), + + /* basic functions */ + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, + .config_init = smsc_phy_config_init, +}, { + .phy_id = 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */ + .phy_id_mask = 0xfffffff0, + .drv.name = "SMSC LAN8700", + + .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause + | SUPPORTED_Asym_Pause), + + /* basic functions */ + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, + .config_init = smsc_phy_config_init, +}, { + .phy_id = 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */ + .phy_id_mask = 0xfffffff0, + .drv.name = "SMSC LAN911x Internal PHY", + + .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause + | SUPPORTED_Asym_Pause), + + /* basic functions */ + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, + .config_init = lan911x_config_init, +}, { + .phy_id = 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */ + .phy_id_mask = 0xfffffff0, + .drv.name = "SMSC LAN8710/LAN8720", + + .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause + | SUPPORTED_Asym_Pause), + + /* basic functions */ + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, + .config_init = lan87xx_config_init, +} }; + +static int __init smsc_init(void) +{ + return phy_drivers_register(smsc_phy_driver, ARRAY_SIZE(smsc_phy_driver)); +} +fs_initcall(smsc_init); diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 97680cfb54..5975e2a342 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -154,7 +154,7 @@ static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, void *buf; int err = -ENOMEM; - dev_dbg(&dev->edev.dev, "asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d", + dev_dbg(&dev->edev.dev, "asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", cmd, value, index, size); buf = malloc(size); @@ -187,7 +187,7 @@ static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, void *buf = NULL; int err = -ENOMEM; - dev_dbg(&dev->edev.dev, "asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d", + dev_dbg(&dev->edev.dev, "asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", cmd, value, index, size); if (data) { @@ -218,7 +218,7 @@ static inline int asix_set_sw_mii(struct usbnet *dev) int ret; ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); if (ret < 0) - dev_err(&dev->edev.dev, "Failed to enable software MII access"); + dev_err(&dev->edev.dev, "Failed to enable software MII access\n"); return ret; } @@ -227,7 +227,7 @@ static inline int asix_set_hw_mii(struct usbnet *dev) int ret; ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); if (ret < 0) - dev_err(&dev->edev.dev, "Failed to enable hardware MII access"); + dev_err(&dev->edev.dev, "Failed to enable hardware MII access\n"); return ret; } @@ -241,7 +241,7 @@ static int asix_mdio_read(struct mii_bus *bus, int phy_id, int loc) (__u16)loc, 2, &res); asix_set_hw_mii(dev); - dev_dbg(&dev->edev.dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", + dev_dbg(&dev->edev.dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", phy_id, loc, le16_to_cpu(res)); return le16_to_cpu(res); @@ -252,7 +252,7 @@ static int asix_mdio_write(struct mii_bus *bus, int phy_id, int loc, u16 val) struct usbnet *dev = bus->priv; __le16 res = cpu_to_le16(val); - dev_dbg(&dev->edev.dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", + dev_dbg(&dev->edev.dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", phy_id, loc, val); asix_set_sw_mii(dev); @@ -270,10 +270,10 @@ static inline int asix_get_phy_addr(struct usbnet *dev) dev_dbg(&dev->edev.dev, "asix_get_phy_addr()"); if (ret < 0) { - dev_err(&dev->edev.dev, "Error reading PHYID register: %02x", ret); + dev_err(&dev->edev.dev, "Error reading PHYID register: %02x\n", ret); goto out; } - dev_dbg(&dev->edev.dev, "asix_get_phy_addr() returning 0x%04x", *((__le16 *)buf)); + dev_dbg(&dev->edev.dev, "asix_get_phy_addr() returning 0x%04x\n", *((__le16 *)buf)); ret = buf[1]; out: @@ -286,7 +286,7 @@ static int asix_sw_reset(struct usbnet *dev, u8 flags) ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL); if (ret < 0) - dev_err(&dev->edev.dev, "Failed to send software reset: %02x", ret); + dev_err(&dev->edev.dev, "Failed to send software reset: %02x\n", ret); return ret; } @@ -297,7 +297,7 @@ static u16 asix_read_rx_ctl(struct usbnet *dev) int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v); if (ret < 0) { - dev_err(&dev->edev.dev, "Error reading RX_CTL register: %02x", ret); + dev_err(&dev->edev.dev, "Error reading RX_CTL register: %02x\n", ret); goto out; } ret = le16_to_cpu(v); @@ -309,10 +309,10 @@ static int asix_write_rx_ctl(struct usbnet *dev, u16 mode) { int ret; - dev_dbg(&dev->edev.dev, "asix_write_rx_ctl() - mode = 0x%04x", mode); + dev_dbg(&dev->edev.dev, "asix_write_rx_ctl() - mode = 0x%04x\n", mode); ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); if (ret < 0) - dev_err(&dev->edev.dev, "Failed to write RX_CTL mode to 0x%04x: %02x", + dev_err(&dev->edev.dev, "Failed to write RX_CTL mode to 0x%04x: %02x\n", mode, ret); return ret; @@ -324,7 +324,7 @@ static u16 asix_read_medium_status(struct usbnet *dev) int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); if (ret < 0) { - dev_err(&dev->edev.dev, "Error reading Medium Status register: %02x", ret); + dev_err(&dev->edev.dev, "Error reading Medium Status register: %02x\n", ret); goto out; } ret = le16_to_cpu(v); @@ -336,10 +336,10 @@ static int asix_write_medium_mode(struct usbnet *dev, u16 mode) { int ret; - dev_dbg(&dev->edev.dev, "asix_write_medium_mode() - mode = 0x%04x", mode); + dev_dbg(&dev->edev.dev, "asix_write_medium_mode() - mode = 0x%04x\n", mode); ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); if (ret < 0) - dev_err(&dev->edev.dev, "Failed to write Medium Mode mode to 0x%04x: %02x", + dev_err(&dev->edev.dev, "Failed to write Medium Mode mode to 0x%04x: %02x\n", mode, ret); return ret; @@ -349,10 +349,10 @@ static int asix_write_gpio(struct usbnet *dev, u16 value, int sleep) { int ret; - dev_dbg(&dev->edev.dev,"asix_write_gpio() - value = 0x%04x", value); + dev_dbg(&dev->edev.dev,"asix_write_gpio() - value = 0x%04x\n", value); ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL); if (ret < 0) - dev_err(&dev->edev.dev, "Failed to write GPIO value 0x%04x: %02x", + dev_err(&dev->edev.dev, "Failed to write GPIO value 0x%04x: %02x\n", value, ret); if (sleep) @@ -369,7 +369,7 @@ static int asix_get_ethaddr(struct eth_device *edev, unsigned char *adr) /* Get the MAC address */ if ((ret = asix_read_cmd(udev, AX_CMD_READ_NODE_ID, 0, 0, 6, adr)) < 0) { - debug("Failed to read MAC address: %d", ret); + debug("Failed to read MAC address: %d\n", ret); return -1; } @@ -390,7 +390,7 @@ static int ax88172_get_ethaddr(struct eth_device *edev, unsigned char *adr) /* Get the MAC address */ if ((ret = asix_read_cmd(udev, AX88172_CMD_READ_NODE_ID, 0, 0, 6, adr)) < 0) { - debug("read AX_CMD_READ_NODE_ID failed: %d", ret); + debug("read AX_CMD_READ_NODE_ID failed: %d\n", ret); return -1; } @@ -409,13 +409,13 @@ static int asix_rx_fixup(struct usbnet *dev, void *buf, int len) while (len > 0) { if ((short)(header & 0x0000ffff) != ~((short)((header & 0xffff0000) >> 16))) - dev_err(&dev->edev.dev, "asix_rx_fixup() Bad Header Length"); + dev_err(&dev->edev.dev, "asix_rx_fixup() Bad Header Length\n"); /* get the packet length */ size = (unsigned short) (header & 0x0000ffff); if (size > 1514) { - dev_err(&dev->edev.dev, "asix_rx_fixup() Bad RX Length %d", size); + dev_err(&dev->edev.dev, "asix_rx_fixup() Bad RX Length %d\n", size); return 0; } @@ -434,7 +434,7 @@ static int asix_rx_fixup(struct usbnet *dev, void *buf, int len) } if (len < 0) { - dev_err(&dev->edev.dev,"asix_rx_fixup() Bad SKB Length %d", len); + dev_err(&dev->edev.dev,"asix_rx_fixup() Bad SKB Length %d\n", len); return -1; } return 0; @@ -549,7 +549,7 @@ static int ax88772_bind(struct usbnet *dev) embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL)) < 0) { - debug("Select PHY #1 failed: %d", ret); + debug("Select PHY #1 failed: %d\n", ret); goto out; } @@ -572,12 +572,12 @@ static int ax88772_bind(struct usbnet *dev) mdelay(150); rx_ctl = asix_read_rx_ctl(dev); - debug("RX_CTL is 0x%04x after software reset", rx_ctl); + debug("RX_CTL is 0x%04x after software reset\n", rx_ctl); if ((ret = asix_write_rx_ctl(dev, 0x0000)) < 0) goto out; rx_ctl = asix_read_rx_ctl(dev); - debug("RX_CTL is 0x%04x setting to 0x0000", rx_ctl); + debug("RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); dev->edev.get_ethaddr = asix_get_ethaddr; dev->edev.set_ethaddr = asix_set_ethaddr; @@ -599,7 +599,7 @@ static int ax88772_bind(struct usbnet *dev) if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, AX88772_IPG2_DEFAULT, 0, NULL)) < 0) { - debug("Write IPG,IPG1,IPG2 failed: %d", ret); + debug("Write IPG,IPG1,IPG2 failed: %d\n", ret); goto out; } @@ -608,10 +608,10 @@ static int ax88772_bind(struct usbnet *dev) goto out; rx_ctl = asix_read_rx_ctl(dev); - debug("RX_CTL is 0x%04x after all initializations", rx_ctl); + debug("RX_CTL is 0x%04x after all initializations\n", rx_ctl); rx_ctl = asix_read_medium_status(dev); - debug("Medium Status is 0x%04x after all initializations", rx_ctl); + debug("Medium Status is 0x%04x after all initializations\n", rx_ctl); /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ if (dev->driver_info->flags & FLAG_FRAMING_AX) { diff --git a/drivers/of/Makefile b/drivers/of/Makefile index c14aaec79f..5a5960d182 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -1,3 +1,3 @@ obj-y += base.o -obj-y += gpio.o +obj-$(CONFIG_GPIOLIB) += gpio.o obj-y += partition.o diff --git a/drivers/of/base.c b/drivers/of/base.c index fd152d65d9..e9e9716bbc 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -105,6 +105,9 @@ struct property *of_find_property(const struct device_node *node, const char *na { struct property *p; + if (!node) + return NULL; + list_for_each_entry(p, &node->properties, list) if (!strcmp(p->name, name)) return p; @@ -711,11 +714,15 @@ static void __of_probe(struct device_node *node) __of_probe(n); } +struct device_node *of_chosen; + int of_probe(void) { if(!root_node) return -ENODEV; + of_chosen = of_find_node_by_path("/chosen"); + __of_probe(root_node); return 0; @@ -800,3 +807,22 @@ int of_parse_dtb(struct fdt_header *fdt) return 0; } + +int of_device_is_stdout_path(struct device_d *dev) +{ + struct device_node *dn; + const char *name; + + name = of_get_property(of_chosen, "linux,stdout-path", NULL); + if (name == NULL) + return 0; + dn = of_find_node_by_path(name); + + if (!dn) + return 0; + + if (dn == dev->device_node) + return 1; + + return 0; +} diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 7eb96edf28..02bc8bfdb3 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -43,6 +43,11 @@ config DRIVER_SERIAL_BLACKFIN default y bool "Blackfin serial driver" +config DRIVER_SERIAL_CLPS711X + depends on ARCH_CLPS711X + default y + bool "CLPS711X serial driver" + config DRIVER_SERIAL_ALTERA depends on NIOS2 default y diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index e2d56b96b7..e6f1e22610 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_DRIVER_SERIAL_NETX) += serial_netx.o obj-$(CONFIG_DRIVER_SERIAL_LINUX_CONSOLE) += linux_console.o obj-$(CONFIG_DRIVER_SERIAL_MPC5XXX) += serial_mpc5xxx.o obj-$(CONFIG_DRIVER_SERIAL_BLACKFIN) += serial_blackfin.o +obj-$(CONFIG_DRIVER_SERIAL_CLPS711X) += serial_clps711x.o obj-$(CONFIG_DRIVER_SERIAL_NS16550) += serial_ns16550.o obj-$(CONFIG_DRIVER_SERIAL_PL010) += serial_pl010.o obj-$(CONFIG_DRIVER_SERIAL_S3C) += serial_s3c.o diff --git a/drivers/serial/serial_clps711x.c b/drivers/serial/serial_clps711x.c new file mode 100644 index 0000000000..21d0b55d3a --- /dev/null +++ b/drivers/serial/serial_clps711x.c @@ -0,0 +1,157 @@ +/* + * Simple CLPS711X serial driver + * + * (C) Copyright 2012 Alexander Shiyan <shc_work@mail.ru> + * + * 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 <malloc.h> +#include <init.h> +#include <io.h> +#include <linux/clk.h> +#include <linux/err.h> + +#include <mach/clps711x.h> + +struct clps711x_uart { + void __iomem *UBRLCR; + void __iomem *SYSCON; + void __iomem *SYSFLG; + void __iomem *UARTDR; + struct clk *uart_clk; + struct console_device cdev; +}; + +static int clps711x_setbaudrate(struct console_device *cdev, int baudrate) +{ + struct clps711x_uart *s = cdev->dev->priv; + int divisor; + u32 tmp; + + divisor = (clk_get_rate(s->uart_clk) / 16) / baudrate; + + tmp = readl(s->UBRLCR) & ~UBRLCR_BAUD_MASK; + tmp |= divisor - 1; + writel(tmp, s->UBRLCR); + + return 0; +} + +static void clps711x_init_port(struct console_device *cdev) +{ + struct clps711x_uart *s = cdev->dev->priv; + u32 tmp; + + /* Disable the UART */ + writel(readl(s->SYSCON) & ~SYSCON_UARTEN, s->SYSCON); + + /* Setup Line Control Register */ + tmp = readl(s->UBRLCR) & UBRLCR_BAUD_MASK; + tmp |= UBRLCR_FIFOEN | UBRLCR_WRDLEN8; /* FIFO on, 8N1 mode */ + writel(tmp, s->UBRLCR); + + /* Set default baudrate on initialization */ + clps711x_setbaudrate(cdev, CONFIG_BAUDRATE); + + /* Enable the UART */ + writel(readl(s->SYSCON) | SYSCON_UARTEN, s->SYSCON); +} + +static void clps711x_putc(struct console_device *cdev, char c) +{ + struct clps711x_uart *s = cdev->dev->priv; + + /* Wait until there is space in the FIFO */ + while (readl(s->SYSFLG) & SYSFLG_UTXFF) + barrier(); + + /* Send the character */ + writew(c, s->UARTDR); +} + +static int clps711x_getc(struct console_device *cdev) +{ + struct clps711x_uart *s = cdev->dev->priv; + u16 data; + + /* Wait until there is data in the FIFO */ + while (readl(s->SYSFLG) & SYSFLG_URXFE) + barrier(); + + data = readw(s->UARTDR); + + /* Check for an error flag */ + if (data & (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR)) + return -1; + + return (int)data; +} + +static int clps711x_tstc(struct console_device *cdev) +{ + struct clps711x_uart *s = cdev->dev->priv; + + return !(readl(s->SYSFLG) & SYSFLG_URXFE); +} + +static void clps711x_flush(struct console_device *cdev) +{ + struct clps711x_uart *s = cdev->dev->priv; + + while (readl(s->SYSFLG) & SYSFLG_UBUSY) + barrier(); +} + +static int clps711x_probe(struct device_d *dev) +{ + struct clps711x_uart *s; + + BUG_ON(dev->num_resources != 4); + + s = xzalloc(sizeof(struct clps711x_uart)); + s->uart_clk = clk_get(dev, NULL); + BUG_ON(IS_ERR(s->uart_clk)); + + s->UBRLCR = dev_get_mem_region(dev, 0); + s->SYSCON = dev_get_mem_region(dev, 1); + s->SYSFLG = dev_get_mem_region(dev, 2); + s->UARTDR = dev_get_mem_region(dev, 3); + + dev->priv = s; + s->cdev.dev = dev; + s->cdev.f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR; + s->cdev.tstc = clps711x_tstc; + s->cdev.putc = clps711x_putc; + s->cdev.getc = clps711x_getc; + s->cdev.flush = clps711x_flush; + s->cdev.setbrg = clps711x_setbaudrate; + clps711x_init_port(&s->cdev); + + return console_register(&s->cdev); +} + +static void clps711x_remove(struct device_d *dev) +{ + struct clps711x_uart *s = dev->priv; + + clps711x_flush(&s->cdev); + console_unregister(&s->cdev); + free(s); +} + +static struct driver_d clps711x_driver = { + .name = "clps711x_serial", + .probe = clps711x_probe, + .remove = clps711x_remove, +}; + +static int clps711x_init(void) +{ + return platform_driver_register(&clps711x_driver); +} +console_initcall(clps711x_init); diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c index a7119405c2..694eac2918 100644 --- a/drivers/serial/serial_imx.c +++ b/drivers/serial/serial_imx.c @@ -15,7 +15,6 @@ */ #include <common.h> -#include <mach/imx-regs.h> #include <driver.h> #include <init.h> #include <malloc.h> @@ -38,20 +37,6 @@ #define UBIR 0xa4 /* BRM Incremental Register */ #define UBMR 0xa8 /* BRM Modulator Register */ #define UBRC 0xac /* Baud Rate Count Register */ -#ifdef CONFIG_ARCH_IMX1 -#define BIPR1 0xb0 /* Incremental Preset Register 1 */ -#define BIPR2 0xb4 /* Incremental Preset Register 2 */ -#define BIPR3 0xb8 /* Incremental Preset Register 3 */ -#define BIPR4 0xbc /* Incremental Preset Register 4 */ -#define BMPR1 0xc0 /* BRM Modulator Register 1 */ -#define BMPR2 0xc4 /* BRM Modulator Register 2 */ -#define BMPR3 0xc8 /* BRM Modulator Register 3 */ -#define BMPR4 0xcc /* BRM Modulator Register 4 */ -#define UTS 0xd0 /* UART Test Register */ -#else -#define ONEMS 0xb0 /* One Millisecond register */ -#define UTS 0xb4 /* UART Test Register */ -#endif /* UART Control Register Bit Fields.*/ #define URXD_CHARRDY (1<<15) @@ -148,23 +133,29 @@ /* * create default values for different platforms */ -#ifdef CONFIG_ARCH_IMX1 -# define UCR1_VAL (UCR1_UARTCLKEN) -# define UCR3_VAL 0 -# define UCR4_VAL (UCR4_CTSTL_32 | UCR4_REF16) -#endif -#if defined CONFIG_ARCH_IMX21 || defined CONFIG_ARCH_IMX27 -# define UCR1_VAL (UCR1_UARTCLKEN) -# define UCR3_VAL (0x700 | UCR3_RXDMUXSEL) -# define UCR4_VAL UCR4_CTSTL_32 -#endif -#if defined CONFIG_ARCH_IMX31 || defined CONFIG_ARCH_IMX35 || \ - defined CONFIG_ARCH_IMX25 || defined CONFIG_ARCH_IMX51 || \ - defined CONFIG_ARCH_IMX53 || defined CONFIG_ARCH_IMX6 -# define UCR1_VAL (0) -# define UCR3_VAL (0x700 | UCR3_RXDMUXSEL) -# define UCR4_VAL UCR4_CTSTL_32 -#endif +struct imx_serial_devtype_data { + u32 ucr1_val; + u32 ucr3_val; + u32 ucr4_val; + u32 uts; + u32 onems; +}; + +struct imx_serial_devtype_data imx1_data = { + .ucr1_val = UCR1_UARTCLKEN, + .ucr3_val = 0, + .ucr4_val = UCR4_CTSTL_32 | UCR4_REF16, + .uts = 0xd0, + .onems = 0, +}; + +struct imx_serial_devtype_data imx21_data = { + .ucr1_val = 0, + .ucr3_val = 0x700 | UCR3_RXDMUXSEL, + .ucr4_val = UCR4_CTSTL_32, + .uts = 0xb4, + .onems = 0xb0, +}; struct imx_serial_priv { struct console_device cdev; @@ -172,6 +163,7 @@ struct imx_serial_priv { struct notifier_block notify; void __iomem *regs; struct clk *clk; + struct imx_serial_devtype_data *devtype; }; static int imx_serial_reffreq(struct imx_serial_priv *priv) @@ -196,23 +188,23 @@ static int imx_serial_init_port(struct console_device *cdev) void __iomem *regs = priv->regs; uint32_t val; - writel(UCR1_VAL, regs + UCR1); + writel(priv->devtype->ucr1_val, regs + UCR1); writel(UCR2_WS | UCR2_IRTS, regs + UCR2); - writel(UCR3_VAL, regs + UCR3); - writel(UCR4_VAL, regs + UCR4); + writel(priv->devtype->ucr3_val, regs + UCR3); + writel(priv->devtype->ucr4_val, regs + UCR4); writel(0x0000002B, regs + UESC); writel(0, regs + UTIM); writel(0, regs + UBIR); writel(0, regs + UBMR); - writel(0, regs + UTS); + writel(0, regs + priv->devtype->uts); /* Configure FIFOs */ writel(0xa81, regs + UFCR); -#ifdef ONEMS - writel(imx_serial_reffreq(priv) / 1000, regs + ONEMS); -#endif + + if (priv->devtype->onems) + writel(imx_serial_reffreq(priv) / 1000, regs + priv->devtype->onems); /* Enable FIFOs */ val = readl(regs + UCR2); @@ -240,7 +232,7 @@ static void imx_serial_putc(struct console_device *cdev, char c) struct imx_serial_priv, cdev); /* Wait for Tx FIFO not full */ - while (readl(priv->regs + UTS) & UTS_TXFULL); + while (readl(priv->regs + priv->devtype->uts) & UTS_TXFULL); writel(c, priv->regs + URTX0); } @@ -251,7 +243,7 @@ static int imx_serial_tstc(struct console_device *cdev) struct imx_serial_priv, cdev); /* If receive fifo is empty, return false */ - if (readl(priv->regs + UTS) & UTS_RXEMPTY) + if (readl(priv->regs + priv->devtype->uts) & UTS_RXEMPTY) return 0; return 1; } @@ -262,7 +254,7 @@ static int imx_serial_getc(struct console_device *cdev) struct imx_serial_priv, cdev); unsigned char ch; - while (readl(priv->regs + UTS) & UTS_RXEMPTY); + while (readl(priv->regs + priv->devtype->uts) & UTS_RXEMPTY); ch = readl(priv->regs + URXD0); @@ -318,9 +310,15 @@ static int imx_serial_probe(struct device_d *dev) struct console_device *cdev; struct imx_serial_priv *priv; uint32_t val; + struct imx_serial_devtype_data *devtype; int ret; + ret = dev_get_drvdata(dev, (unsigned long *)&devtype); + if (ret) + return ret; + priv = xzalloc(sizeof(*priv)); + priv->devtype = devtype; cdev = &priv->cdev; dev->priv = priv; @@ -371,20 +369,33 @@ static void imx_serial_remove(struct device_d *dev) static __maybe_unused struct of_device_id imx_serial_dt_ids[] = { { .compatible = "fsl,imx1-uart", - .data = 0, + .data = (unsigned long)&imx1_data, }, { .compatible = "fsl,imx21-uart", - .data = 1, + .data = (unsigned long)&imx21_data, }, { /* sentinel */ } }; +static struct platform_device_id imx_serial_ids[] = { + { + .name = "imx1-uart", + .driver_data = (unsigned long)&imx1_data, + }, { + .name = "imx21-uart", + .driver_data = (unsigned long)&imx21_data, + }, { + /* sentinel */ + }, +}; + static struct driver_d imx_serial_driver = { .name = "imx_serial", .probe = imx_serial_probe, .remove = imx_serial_remove, .of_compatible = DRV_OF_COMPAT(imx_serial_dt_ids), + .id_table = imx_serial_ids, }; static int imx_serial_init(void) diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c index 3f8fd33416..a29920d7dd 100644 --- a/drivers/video/imx-ipu-fb.c +++ b/drivers/video/imx-ipu-fb.c @@ -20,7 +20,7 @@ #include <common.h> #include <init.h> #include <io.h> -#include <mach/imx-regs.h> +#include <mach/imx35-regs.h> #include <fb.h> #include <mach/imxfb.h> #include <malloc.h> @@ -742,9 +742,9 @@ static void ipu_fb_enable(struct fb_info *info) /* ipu_idmac.c::ipu_probe() */ /* Start the clock */ - reg = readl(IMX_CCM_BASE + CCM_CGR1); + reg = readl(MX35_CCM_BASE_ADDR + MX35_CCM_CGR1); reg |= (3 << 18); - writel(reg, IMX_CCM_BASE + CCM_CGR1); + writel(reg, MX35_CCM_BASE_ADDR + MX35_CCM_CGR1); /* ipu_idmac.c::ipu_idmac_init() */ diff --git a/drivers/video/imx.c b/drivers/video/imx.c index 9406b36e71..39ecf6ae9f 100644 --- a/drivers/video/imx.c +++ b/drivers/video/imx.c @@ -24,7 +24,6 @@ #include <init.h> #include <linux/clk.h> #include <linux/err.h> -#include <mach/imx-regs.h> #include <asm-generic/div64.h> #define LCDC_SSA 0x00 @@ -252,19 +251,9 @@ static void imxfb_enable_controller(struct fb_info *info) struct imxfb_info *fbi = info->priv; writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR); -#ifdef CONFIG_ARCH_IMX21 - PCCR0 |= PCCR0_PERCLK3_EN | PCCR0_HCLK_LCDC_EN; -#endif -#ifdef CONFIG_ARCH_IMX27 - PCCR0 |= PCCR0_LCDC_EN; - PCCR1 |= PCCR1_HCLK_LCDC; -#endif -#ifdef CONFIG_ARCH_IMX25 - writel(readl(IMX_CCM_BASE + CCM_CGCR0) | (1 << 24) | (1 << 7), - IMX_CCM_BASE + CCM_CGCR0); - writel(readl(IMX_CCM_BASE + CCM_CGCR1) | (1 << 29), - IMX_CCM_BASE + CCM_CGCR1); -#endif + + clk_enable(fbi->clk); + if (fbi->enable) fbi->enable(1); } @@ -277,19 +266,8 @@ static void imxfb_disable_controller(struct fb_info *info) fbi->enable(0); writel(0, fbi->regs + LCDC_RMCR); -#ifdef CONFIG_ARCH_IMX21 - PCCR0 &= ~(PCCR0_PERCLK3_EN | PCCR0_HCLK_LCDC_EN); -#endif -#ifdef CONFIG_ARCH_IMX27 - PCCR0 &= ~PCCR0_LCDC_EN; - PCCR1 &= ~PCCR1_HCLK_LCDC; -#endif -#ifdef CONFIG_ARCH_IMX25 - writel(readl(IMX_CCM_BASE + CCM_CGCR0) & ~((1 << 24) | (1 << 7)), - IMX_CCM_BASE + CCM_CGCR0); - writel(readl(IMX_CCM_BASE + CCM_CGCR1) & ~(1 << 29), - IMX_CCM_BASE + CCM_CGCR1); -#endif + + clk_disable(fbi->clk); } /* @@ -541,19 +519,6 @@ static int imxfb_probe(struct device_d *dev) if (!pdata) return -ENODEV; -#ifdef CONFIG_ARCH_IMX21 - PCCR0 &= ~(PCCR0_PERCLK3_EN | PCCR0_HCLK_LCDC_EN); -#endif -#ifdef CONFIG_ARCH_IMX27 - PCCR0 &= ~PCCR0_LCDC_EN; - PCCR1 &= ~PCCR1_HCLK_LCDC; -#endif -#ifdef CONFIG_ARCH_IMX25 - writel(readl(IMX_CCM_BASE + CCM_CGCR0) & ~((1 << 24) | (1 << 7)), - IMX_CCM_BASE + CCM_CGCR0); - writel(readl(IMX_CCM_BASE + CCM_CGCR1) & ~(1 << 29), - IMX_CCM_BASE + CCM_CGCR1); -#endif if (!pdata->num_modes) { dev_err(dev, "no modes. bailing out\n"); return -EINVAL; diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig new file mode 100644 index 0000000000..ab349977a4 --- /dev/null +++ b/drivers/w1/Kconfig @@ -0,0 +1,14 @@ +menuconfig W1 + bool "Dallas's 1-wire support" + ---help--- + Dallas' 1-wire bus is useful to connect slow 1-pin devices + such as iButtons and thermal sensors. + + If you want W1 support, you should say Y here. + +if W1 + +source drivers/w1/masters/Kconfig +source drivers/w1/slaves/Kconfig + +endif # W1 diff --git a/drivers/w1/Makefile b/drivers/w1/Makefile new file mode 100644 index 0000000000..3e36d2f120 --- /dev/null +++ b/drivers/w1/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the Dallas's 1-wire bus. +# + +obj-$(CONFIG_W1) += w1.o +obj-y += masters/ slaves/ diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig new file mode 100644 index 0000000000..e429c14fb9 --- /dev/null +++ b/drivers/w1/masters/Kconfig @@ -0,0 +1,14 @@ +# +# 1-wire bus master configuration +# + +menu "1-wire Bus Masters" + +config W1_MASTER_GPIO + bool "GPIO 1-wire busmaster" + depends on GENERIC_GPIO + help + Say Y here if you want to communicate with your 1-wire devices using + GPIO pins. This driver uses the GPIO API to control the wire. + +endmenu diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile new file mode 100644 index 0000000000..84b35bb0eb --- /dev/null +++ b/drivers/w1/masters/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for 1-wire bus master drivers. +# + +obj-$(CONFIG_W1_MASTER_GPIO) += w1-gpio.o diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c new file mode 100644 index 0000000000..0a3794d144 --- /dev/null +++ b/drivers/w1/masters/w1-gpio.c @@ -0,0 +1,116 @@ +/* + * w1-gpio - GPIO w1 bus master driver + * + * Copyright (C) 2007 Ville Syrjala <syrjala@sci.fi> + * 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 version 2 + * as published by the Free Software Foundation. + */ + +#include <common.h> +#include <init.h> +#include <malloc.h> +#include <xfuncs.h> +#include <driver.h> +#include <linux/w1-gpio.h> +#include <gpio.h> + +#include "../w1.h" + +static void w1_gpio_write_bit_dir(struct w1_bus *bus, u8 bit) +{ + struct w1_gpio_platform_data *pdata = bus->data; + + if (bit) + gpio_direction_input(pdata->pin); + else + gpio_direction_output(pdata->pin, 0); +} + +static void w1_gpio_write_bit_val(struct w1_bus *bus, u8 bit) +{ + struct w1_gpio_platform_data *pdata = bus->data; + + gpio_set_value(pdata->pin, bit); +} + +static u8 w1_gpio_read_bit(struct w1_bus *bus) +{ + struct w1_gpio_platform_data *pdata = bus->data; + + return gpio_get_value(pdata->pin) ? 1 : 0; +} + +static int __init w1_gpio_probe(struct device_d *dev) +{ + struct w1_bus *master; + struct w1_gpio_platform_data *pdata; + int err; + + pdata = dev->platform_data; + + if (!pdata) + return -ENXIO; + + master = xzalloc(sizeof(struct w1_bus)); + + err = gpio_request(pdata->pin, "w1"); + if (err) + goto free_master; + + if (gpio_is_valid(pdata->ext_pullup_enable_pin)) { + err = gpio_request(pdata->pin, "w1 pullup"); + if (err < 0) + goto free_gpio; + + gpio_direction_output(pdata->pin, 0); + } + + master->data = pdata; + master->read_bit = w1_gpio_read_bit; + + if (pdata->is_open_drain) { + gpio_direction_output(pdata->pin, 1); + master->write_bit = w1_gpio_write_bit_val; + } else { + gpio_direction_input(pdata->pin); + master->write_bit = w1_gpio_write_bit_dir; + } + + master->parent = dev; + + err = w1_bus_register(master); + if (err) + goto free_gpio_ext_pu; + + if (pdata->enable_external_pullup) + pdata->enable_external_pullup(1); + + if (gpio_is_valid(pdata->ext_pullup_enable_pin)) + gpio_set_value(pdata->ext_pullup_enable_pin, 1); + + return 0; + + free_gpio_ext_pu: + if (gpio_is_valid(pdata->ext_pullup_enable_pin)) + gpio_free(pdata->ext_pullup_enable_pin); + free_gpio: + gpio_free(pdata->pin); + free_master: + kfree(master); + + return err; +} + +static struct driver_d w1_gpio_driver = { + .name = "w1-gpio", + .probe = w1_gpio_probe, +}; + +static int __init w1_gpio_init(void) +{ + return platform_driver_register(&w1_gpio_driver); +} +device_initcall(w1_gpio_init); diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig new file mode 100644 index 0000000000..946a0b3bbe --- /dev/null +++ b/drivers/w1/slaves/Kconfig @@ -0,0 +1,27 @@ +# +# 1-wire slaves configuration +# + +menu "1-wire Slaves" + +config W1_SLAVE_DS2431 + bool "1kb EEPROM family support (DS2431)" + help + Say Y here if you want to use a 1-wire + 1kb EEPROM family device (DS2431) + +config W1_SLAVE_DS2431_WRITE + bool "write support" + depends on W1_SLAVE_DS2431 + +config W1_SLAVE_DS2433 + bool "4kb EEPROM family support (DS2433)" + help + Say Y here if you want to use a 1-wire + 4kb EEPROM family device (DS2433). + +config W1_SLAVE_DS2433_WRITE + bool "write support" + depends on W1_SLAVE_DS2433 + +endmenu diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile new file mode 100644 index 0000000000..dd7160aaf2 --- /dev/null +++ b/drivers/w1/slaves/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the Dallas's 1-wire slaves. +# + +obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o +obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c new file mode 100644 index 0000000000..30e6e1d496 --- /dev/null +++ b/drivers/w1/slaves/w1_ds2431.c @@ -0,0 +1,294 @@ +/* + * w1_ds2431.c - w1 family 2d (DS2431) driver + * + * Copyright (c) 2008 Bernhard Weirich <bernhard.weirich@riedel.net> + * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Heavily inspired by w1_DS2433 driver from Ben Gardner <bgardner@wabtec.com> + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include <init.h> +#include "../w1.h" + +#define W1_F2D_EEPROM_SIZE 128 +#define W1_F2D_PAGE_COUNT 4 +#define W1_F2D_PAGE_BITS 5 +#define W1_F2D_PAGE_SIZE (1 << W1_F2D_PAGE_BITS) +#define W1_F2D_PAGE_MASK 0x1F + +#define W1_F2D_SCRATCH_BITS 3 +#define W1_F2D_SCRATCH_SIZE (1 << W1_F2D_SCRATCH_BITS) +#define W1_F2D_SCRATCH_MASK (W1_F2D_SCRATCH_SIZE - 1) + +#define W1_F2D_READ_EEPROM 0xF0 +#define W1_F2D_WRITE_SCRATCH 0x0F +#define W1_F2D_READ_SCRATCH 0xAA +#define W1_F2D_COPY_SCRATCH 0x55 + + +#define W1_F2D_TPROG_MS 11 + +#define W1_F2D_READ_RETRIES 10 +#define W1_F2D_READ_MAXLEN 8 + +#define DRIVERNAME "ds2431" + +static int ds2431_count = 0; + +/* + * Check the file size bounds and adjusts count as needed. + * This would not be needed if the file size didn't reset to 0 after a write. + */ +static inline size_t ds2431_fix_count(loff_t off, size_t count, size_t size) +{ + if (off > size) + return 0; + + if ((off + count) > size) + return size - off; + + return count; +} + +/* + * Read a block from W1 ROM two times and compares the results. + * If they are equal they are returned, otherwise the read + * is repeated W1_F2D_READ_RETRIES times. + * + * count must not exceed W1_F2D_READ_MAXLEN. + */ +int ds2431_readblock(struct w1_device *dev, int off, int count, char *buf) +{ + struct w1_bus *bus = dev->bus; + u8 wrbuf[3]; + u8 cmp[W1_F2D_READ_MAXLEN]; + int tries = W1_F2D_READ_RETRIES; + + do { + wrbuf[0] = W1_F2D_READ_EEPROM; + wrbuf[1] = off & 0xff; + wrbuf[2] = off >> 8; + + if (w1_reset_select_slave(dev)) + return -1; + + w1_write_block(bus, wrbuf, 3); + w1_read_block(bus, buf, count); + + if (w1_reset_select_slave(dev)) + return -1; + + w1_write_block(bus, wrbuf, 3); + w1_read_block(bus, cmp, count); + + if (!memcmp(cmp, buf, count)) + return 0; + } while (--tries); + + dev_err(&dev->dev, "proof reading failed %d times\n", + W1_F2D_READ_RETRIES); + + return -1; +} + +static ssize_t ds2431_cdev_read(struct cdev *cdev, void *buf, size_t count, + loff_t off, ulong flags) +{ + struct w1_device *dev = cdev->priv; + int todo = count; + + count = ds2431_fix_count(off, count, W1_F2D_EEPROM_SIZE); + if (count == 0) + return 0; + + /* read directly from the EEPROM in chunks of W1_F2D_READ_MAXLEN */ + while (todo > 0) { + int block_read; + + if (todo >= W1_F2D_READ_MAXLEN) + block_read = W1_F2D_READ_MAXLEN; + else + block_read = todo; + + if (ds2431_readblock(dev, off, block_read, buf) < 0) + count = -EIO; + + todo -= W1_F2D_READ_MAXLEN; + buf += W1_F2D_READ_MAXLEN; + off += W1_F2D_READ_MAXLEN; + } + + return count; +} + +#ifdef CONFIG_W1_SLAVE_DS2431_WRITE +/* + * Writes to the scratchpad and reads it back for verification. + * Then copies the scratchpad to EEPROM. + * The data must be aligned at W1_F2D_SCRATCH_SIZE bytes and + * must be W1_F2D_SCRATCH_SIZE bytes long. + * The master must be locked. + * + * @param sl The slave structure + * @param addr Address for the write + * @param len length must be <= (W1_F2D_PAGE_SIZE - (addr & W1_F2D_PAGE_MASK)) + * @param data The data to write + * @return 0=Success -1=failure + */ +static int ds2431_write(struct w1_device *dev, int addr, int len, const u8 *data) +{ + struct w1_bus *bus = dev->bus; + int tries = W1_F2D_READ_RETRIES; + u8 wrbuf[4]; + u8 rdbuf[W1_F2D_SCRATCH_SIZE + 3]; + u8 es = (addr + len - 1) % W1_F2D_SCRATCH_SIZE; + +retry: + + /* Write the data to the scratchpad */ + if (w1_reset_select_slave(dev)) + return -1; + + wrbuf[0] = W1_F2D_WRITE_SCRATCH; + wrbuf[1] = addr & 0xff; + wrbuf[2] = addr >> 8; + + w1_write_block(bus, wrbuf, 3); + w1_write_block(bus, data, len); + + /* Read the scratchpad and verify */ + if (w1_reset_select_slave(dev)) + return -1; + + w1_write_8(bus, W1_F2D_READ_SCRATCH); + w1_read_block(bus, rdbuf, len + 3); + + /* Compare what was read against the data written */ + if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) || + (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0)) { + + if (--tries) + goto retry; + + dev_err(&dev->dev, + "could not write to eeprom, scratchpad compare failed %d times\n", + W1_F2D_READ_RETRIES); + + return -1; + } + + /* Copy the scratchpad to EEPROM */ + if (w1_reset_select_slave(dev)) + return -1; + + wrbuf[0] = W1_F2D_COPY_SCRATCH; + wrbuf[3] = es; + w1_write_block(bus, wrbuf, 4); + + /* Sleep for tprog ms to wait for the write to complete */ + mdelay(W1_F2D_TPROG_MS); + + /* Reset the bus to wake up the EEPROM */ + w1_reset_bus(bus); + + return 0; +} + +static ssize_t ds2431_cdev_write(struct cdev *cdev, const void *buf, size_t count, + loff_t off, ulong flags) +{ + struct w1_device *dev = cdev->priv; + int addr, len; + int copy; + + count = ds2431_fix_count(off, count, W1_F2D_EEPROM_SIZE); + if (count == 0) + return 0; + + /* Can only write data in blocks of the size of the scratchpad */ + addr = off; + len = count; + while (len > 0) { + + /* if len too short or addr not aligned */ + if (len < W1_F2D_SCRATCH_SIZE || addr & W1_F2D_SCRATCH_MASK) { + char tmp[W1_F2D_SCRATCH_SIZE]; + + /* read the block and update the parts to be written */ + if (ds2431_readblock(dev, addr & ~W1_F2D_SCRATCH_MASK, + W1_F2D_SCRATCH_SIZE, tmp)) { + count = -EIO; + goto out_up; + } + + /* copy at most to the boundary of the PAGE or len */ + copy = W1_F2D_SCRATCH_SIZE - + (addr & W1_F2D_SCRATCH_MASK); + + if (copy > len) + copy = len; + + memcpy(&tmp[addr & W1_F2D_SCRATCH_MASK], buf, copy); + if (ds2431_write(dev, addr & ~W1_F2D_SCRATCH_MASK, + W1_F2D_SCRATCH_SIZE, tmp) < 0) { + count = -EIO; + goto out_up; + } + } else { + + copy = W1_F2D_SCRATCH_SIZE; + if (ds2431_write(dev, addr, copy, buf) < 0) { + count = -EIO; + goto out_up; + } + } + buf += copy; + addr += copy; + len -= copy; + } + +out_up: + return count; +} +#else +#define ds2431_cdev_write NULL +#endif + +static struct file_operations ds2431_ops = { + .read = ds2431_cdev_read, + .write = ds2431_cdev_write, + .lseek = dev_lseek_default, +}; + +static int ds2431_probe(struct w1_device *dev) +{ + struct cdev *cdev; + + cdev = xzalloc(sizeof(*cdev)); + cdev->dev = &dev->dev; + cdev->priv = dev; + cdev->ops = &ds2431_ops; + cdev->size = W1_F2D_EEPROM_SIZE; + cdev->name = asprintf(DRIVERNAME"%d", ds2431_count++); + if (cdev->name == NULL) + return -ENOMEM; + + return devfs_create(cdev); +} + +struct w1_driver ds2431_driver = { + .drv = { + .name = DRIVERNAME, + }, + .probe = ds2431_probe, + .fid = 0x2d, +}; + +static int w1_ds2431_init(void) +{ + return w1_driver_register(&ds2431_driver); +} +device_initcall(w1_ds2431_init); diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c new file mode 100644 index 0000000000..51279fb0eb --- /dev/null +++ b/drivers/w1/slaves/w1_ds2433.c @@ -0,0 +1,196 @@ +/* + * w1_ds2433.c - w1 family 23 (DS2433) driver + * + * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com> + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include <init.h> +#include "../w1.h" + +#define W1_EEPROM_SIZE 512 +#define W1_PAGE_COUNT 16 +#define W1_PAGE_SIZE 32 +#define W1_PAGE_BITS 5 +#define W1_PAGE_MASK 0x1F + +#define W1_F23_TIME 300 + +#define W1_F23_READ_EEPROM 0xF0 +#define W1_F23_WRITE_SCRATCH 0x0F +#define W1_F23_READ_SCRATCH 0xAA +#define W1_F23_COPY_SCRATCH 0x55 + +#define DRIVERNAME "ds2433" + +static int ds2433_count = 0; + +/** + * Check the file size bounds and adjusts count as needed. + * This would not be needed if the file size didn't reset to 0 after a write. + */ +static inline size_t ds2433_fix_count(loff_t off, size_t count, size_t size) +{ + if (off > size) + return 0; + + if ((off + count) > size) + return (size - off); + + return count; +} + +static ssize_t ds2433_cdev_read(struct cdev *cdev, void *buf, size_t count, + loff_t off, ulong flags) +{ + struct w1_device *dev = cdev->priv; + struct w1_bus *bus = dev->bus; + u8 wrbuf[3]; + + if ((count = ds2433_fix_count(off, count, W1_EEPROM_SIZE)) == 0) + return 0; + + /* read directly from the EEPROM */ + if (w1_reset_select_slave(dev)) { + count = -EIO; + goto out_up; + } + + wrbuf[0] = W1_F23_READ_EEPROM; + wrbuf[1] = off & 0xff; + wrbuf[2] = off >> 8; + w1_write_block(bus, wrbuf, 3); + w1_read_block(bus, buf, count); + +out_up: + return count; +} + +#ifdef CONFIG_W1_SLAVE_DS2433_WRITE +/** + * Writes to the scratchpad and reads it back for verification. + * Then copies the scratchpad to EEPROM. + * The data must be on one page. + * The master must be locked. + * + * @param sl The slave structure + * @param addr Address for the write + * @param len length must be <= (W1_PAGE_SIZE - (addr & W1_PAGE_MASK)) + * @param data The data to write + * @return 0=Success -1=failure + */ +static int ds2433_write(struct w1_device *dev, int addr, int len, const u8 *data) +{ + struct w1_bus *bus = dev->bus; + u8 wrbuf[4]; + u8 rdbuf[W1_PAGE_SIZE + 3]; + u8 es = (addr + len - 1) & 0x1f; + + /* Write the data to the scratchpad */ + if (w1_reset_select_slave(dev)) + return -1; + + wrbuf[0] = W1_F23_WRITE_SCRATCH; + wrbuf[1] = addr & 0xff; + wrbuf[2] = addr >> 8; + + w1_write_block(bus, wrbuf, 3); + w1_write_block(bus, data, len); + + /* Read the scratchpad and verify */ + if (w1_reset_select_slave(dev)) + return -1; + + w1_write_8(bus, W1_F23_READ_SCRATCH); + w1_read_block(bus, rdbuf, len + 3); + + /* Compare what was read against the data written */ + if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) || + (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0)) + return -1; + + /* Copy the scratchpad to EEPROM */ + if (w1_reset_select_slave(dev)) + return -1; + + wrbuf[0] = W1_F23_COPY_SCRATCH; + wrbuf[3] = es; + w1_write_block(bus, wrbuf, 4); + + /* Sleep for 5 ms to wait for the write to complete */ + mdelay(5); + + /* Reset the bus to wake up the EEPROM (this may not be needed) */ + w1_reset_bus(bus); + return 0; +} + +static ssize_t ds2433_cdev_write(struct cdev *cdev, const void *buf, size_t count, + loff_t off, ulong flags) +{ + struct w1_device *dev = cdev->priv; + int addr, len, idx; + const u8 *buf8 = buf; + + if ((count = ds2433_fix_count(off, count, W1_EEPROM_SIZE)) == 0) + return 0; + + /* Can only write data to one page at a time */ + idx = 0; + while (idx < count) { + addr = off + idx; + len = W1_PAGE_SIZE - (addr & W1_PAGE_MASK); + if (len > (count - idx)) + len = count - idx; + + if (ds2433_write(dev, addr, len, &buf8[idx]) < 0) { + count = -EIO; + goto out_up; + } + idx += len; + } + +out_up: + return count; +} +#else +#define ds2433_cdev_write NULL +#endif + +static struct file_operations ds2433_ops = { + .read = ds2433_cdev_read, + .write = ds2433_cdev_write, + .lseek = dev_lseek_default, +}; + +static int ds2433_probe(struct w1_device *dev) +{ + struct cdev *cdev; + + cdev = xzalloc(sizeof(*cdev)); + cdev->dev = &dev->dev; + cdev->priv = dev; + cdev->ops = &ds2433_ops; + cdev->size = W1_EEPROM_SIZE; + cdev->name = asprintf(DRIVERNAME"%d", ds2433_count++); + if (cdev->name == NULL) + return -ENOMEM; + + return devfs_create(cdev); +} + +struct w1_driver ds2433_driver = { + .drv = { + .name = DRIVERNAME, + }, + .probe = ds2433_probe, + .fid = 0x23, +}; + +static int w1_ds2433_init(void) +{ + return w1_driver_register(&ds2433_driver); +} +device_initcall(w1_ds2433_init); diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c new file mode 100644 index 0000000000..11b8320d12 --- /dev/null +++ b/drivers/w1/w1.c @@ -0,0 +1,621 @@ +/* + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> + * 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 <init.h> +#include <clock.h> + +#include "w1.h" + +static LIST_HEAD(w1_buses); + +static void w1_pre_write(struct w1_bus *bus); +static void w1_post_write(struct w1_bus *bus); + +static void w1_delay(unsigned long usecs) +{ + uint64_t start = get_time_ns(); + + while(!is_timeout_non_interruptible(start, usecs * USECOND)); +} + +static u8 w1_crc8_table[] = { + 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, + 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, + 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, + 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, + 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, + 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, + 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, + 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, + 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, + 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, + 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, + 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, + 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, + 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, + 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, + 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53 +}; + +u8 w1_calc_crc8(u8 * data, int len) +{ + u8 crc = 0; + + while (len--) + crc = w1_crc8_table[crc ^ *data++]; + + return crc; +} + +/** + * Issues a reset bus sequence. + * + * @param dev The bus master pointer + * @return 0=Device present, 1=No device present or error + */ +int w1_reset_bus(struct w1_bus *bus) +{ + return bus->reset_bus(bus) & 0x1; +} + +static u8 w1_soft_reset_bus(struct w1_bus *bus) +{ + int result; + + bus->write_bit(bus, 0); + /* minimum 480, max ? us + * be nice and sleep, except 18b20 spec lists 960us maximum, + * so until we can sleep with microsecond accuracy, spin. + * Feel free to come up with some other way to give up the + * cpu for such a short amount of time AND get it back in + * the maximum amount of time. + */ + w1_delay(500); + bus->write_bit(bus, 1); + w1_delay(70); + + result = bus->read_bit(bus) & 0x1; + /* minmum 70 (above) + 430 = 500 us + * There aren't any timing requirements between a reset and + * the following transactions. Sleeping is safe here. + */ + /* w1_delay(430); min required time */ + mdelay(1); + + return result; +} + +/** + * Generates a write-0 or write-1 cycle and samples the level. + */ +static u8 w1_touch_bit(struct w1_bus *bus, int bit) +{ + return bus->touch_bit(bus, bit); +} + +/** + * Generates a write-0 or write-1 cycle. + * Only call if dev->bus_master->touch_bit is NULL + */ +static void w1_write_bit(struct w1_bus *bus, int bit) +{ + if (bit) { + bus->write_bit(bus, 0); + w1_delay(6); + bus->write_bit(bus, 1); + w1_delay(64); + } else { + bus->write_bit(bus, 0); + w1_delay(60); + bus->write_bit(bus, 1); + w1_delay(10); + } +} + +/** + * Reads 8 bits. + * + * @param dev the master device + * @return the byte read + */ +u8 w1_read_8(struct w1_bus *bus) +{ + return bus->read_byte(bus); +} + +static u8 w1_soft_read_8(struct w1_bus *bus) +{ + int i; + u8 res = 0; + + for (i = 0; i < 8; ++i) + res |= (w1_touch_bit(bus, 1) << i); + + return res; +} + +/** + * Writes a series of bytes. + * + * @param dev the master device + * @param buf pointer to the data to write + * @param len the number of bytes to write + */ +void w1_write_block(struct w1_bus *bus, const u8 *buf, int len) +{ + int i; + + if (bus->write_block) { + w1_pre_write(bus); + bus->write_block(bus, buf, len); + } else { + for (i = 0; i < len; ++i) + w1_write_8(bus, buf[i]); /* calls w1_pre_write */ + } + w1_post_write(bus); +} + +/** + * Touches a series of bytes. + * + * @param dev the master device + * @param buf pointer to the data to write + * @param len the number of bytes to write + */ +void w1_touch_block(struct w1_bus *bus, u8 *buf, int len) +{ + int i, j; + u8 tmp; + + for (i = 0; i < len; ++i) { + tmp = 0; + for (j = 0; j < 8; ++j) { + if (j == 7) + w1_pre_write(bus); + tmp |= w1_touch_bit(bus, (buf[i] >> j) & 0x1) << j; + } + + buf[i] = tmp; + } +} + +/** + * Generates a write-1 cycle and samples the level. + * Only call if dev->bus_master->touch_bit is NULL + */ +static u8 w1_read_bit(struct w1_bus *bus) +{ + int result; + + /* sample timing is critical here */ + bus->write_bit(bus, 0); + w1_delay(6); + bus->write_bit(bus, 1); + w1_delay(9); + + result = bus->read_bit(bus); + + w1_delay(55); + + return result & 0x1; +} + +/** + * Does a triplet - used for searching ROM addresses. + * Return bits: + * bit 0 = id_bit + * bit 1 = comp_bit + * bit 2 = dir_taken + * If both bits 0 & 1 are set, the search should be restarted. + * + * @param dev the master device + * @param bdir the bit to write if both id_bit and comp_bit are 0 + * @return bit fields - see above + */ +u8 w1_triplet(struct w1_bus *bus, int bdir) +{ + return bus->triplet(bus, bdir); +} + +static u8 w1_soft_triplet(struct w1_bus *bus, u8 bdir) +{ + u8 id_bit = w1_touch_bit(bus, 1); + u8 comp_bit = w1_touch_bit(bus, 1); + u8 retval; + + if (id_bit && comp_bit) + return 0x03; /* error */ + + if (!id_bit && !comp_bit) { + /* Both bits are valid, take the direction given */ + retval = bdir ? 0x04 : 0; + } else { + /* Only one bit is valid, take that direction */ + bdir = id_bit; + retval = id_bit ? 0x05 : 0x02; + } + + w1_touch_bit(bus, bdir); + return retval; +} + +static u8 w1_soft_touch_bit(struct w1_bus *bus, u8 bit) +{ + if (bit) + return w1_read_bit(bus); + + w1_write_bit(bus, 0); + return 0; +} + +/** + * Pre-write operation, currently only supporting strong pullups. + * Program the hardware for a strong pullup, if one has been requested and + * the hardware supports it. + * + * @param dev the master device + */ +static void w1_pre_write(struct w1_bus *bus) +{ + if (!bus->set_pullup) + return; + + if (bus->pullup_duration && bus->enable_pullup) + bus->set_pullup(bus, bus->pullup_duration); +} + +/** + * Post-write operation, currently only supporting strong pullups. + * If a strong pullup was requested, clear it if the hardware supports + * them, or execute the delay otherwise, in either case clear the request. + * + * @param dev the master device + */ +static void w1_post_write(struct w1_bus *bus) +{ + if (!bus->pullup_duration) + return; + + if (bus->enable_pullup && bus->set_pullup) + bus->set_pullup(bus, 0); + else + mdelay(bus->pullup_duration); + bus->pullup_duration = 0; +} + +/** + * Writes 8 bits. + * + * @param dev the master device + * @param byte the byte to write + */ +void w1_write_8(struct w1_bus *bus, u8 byte) +{ + if (bus->write_byte) { + w1_pre_write(bus); + bus->write_byte(bus, byte); + } else { + int i; + + for (i = 0; i < 8; ++i) { + if (i == 7) + w1_pre_write(bus); + w1_touch_bit(bus, (byte >> i) & 0x1); + } + } + w1_post_write(bus); +} + +/** + * Reads a series of bytes. + * + * @param dev the master device + * @param buf pointer to the buffer to fill + * @param len the number of bytes to read + * @return the number of bytes read + */ +u8 w1_read_block(struct w1_bus *bus, u8 *buf, int len) +{ + return bus->read_block(bus, buf, len); +} + +static u8 w1_soft_read_block(struct w1_bus *bus, u8 *buf, int len) +{ + int i; + + for (i = 0; i < len; ++i) + buf[i] = w1_read_8(bus); + return len; +} + +/** + * Resets the bus and then selects the slave by sending either a skip rom + * or a rom match. + * The w1 master lock must be held. + * + * @param sl the slave to select + * @return 0=success, anything else=error + */ +int w1_reset_select_slave(struct w1_device *dev) +{ + struct w1_bus *bus = dev->bus; + + if (w1_reset_bus(bus)) + return -1; + + if (bus->slave_count == 1) + w1_write_8(bus, W1_SKIP_ROM); + else { + u8 match[9] = {W1_MATCH_ROM, }; + u64 rn = le64_to_cpu(*((u64*)&dev->reg_num)); + + memcpy(&match[1], &rn, 8); + w1_write_block(bus, match, 9); + } + return 0; +} + +#define to_w1_device(d) container_of(d, struct w1_device, dev) +#define to_w1_driver(d) container_of(d, struct w1_driver, drv) + +static int w1_bus_match(struct device_d *_dev, struct driver_d *_drv) +{ + struct w1_device *dev = to_w1_device(_dev); + struct w1_driver *drv = to_w1_driver(_drv); + + return !(drv->fid == dev->fid); +} + +static int w1_bus_probe(struct device_d *_dev) +{ + struct w1_driver *drv = to_w1_driver(_dev->driver); + struct w1_device *dev = to_w1_device(_dev); + + return drv->probe(dev); +} + +static void w1_bus_remove(struct device_d *_dev) +{ + struct w1_driver *drv = to_w1_driver(_dev->driver); + struct w1_device *dev = to_w1_device(_dev); + + return drv->remove(dev); +} + +struct bus_type w1_bustype= { + .name = "w1_bus", + .match = w1_bus_match, + .probe = w1_bus_probe, + .remove = w1_bus_remove, +}; + +static int w1_device_register(struct w1_bus *bus, struct w1_device *dev) +{ + char str[18]; + int ret; + + sprintf(dev->dev.name, "w1-%x-", dev->fid); + dev->dev.id = DEVICE_ID_DYNAMIC; + dev->dev.bus = &w1_bustype; + dev->bus = bus; + + dev->dev.parent = &bus->dev; + dev_add_child(dev->dev.parent, &dev->dev); + + ret = register_device(&dev->dev); + if (ret) + return ret; + + sprintf(str, "0x%x", dev->fid); + dev_add_param_fixed(&dev->dev, "fid", str); + sprintf(str, "0x%llx", dev->id); + dev_add_param_fixed(&dev->dev, "id", str); + sprintf(str, "0x%llx", dev->reg_num); + dev_add_param_fixed(&dev->dev, "reg_num", str); + + return ret; +} + +int w1_driver_register(struct w1_driver *drv) +{ + drv->drv.bus = &w1_bustype; + + if (drv->probe) + drv->drv.probe = w1_bus_probe; + if (drv->remove) + drv->drv.remove = w1_bus_remove; + + return register_driver(&drv->drv); +} + +void w1_found(struct w1_bus *bus, u64 rn) +{ + struct w1_device *dev = xzalloc(sizeof(*dev)); + u64 tmp = be64_to_cpu(rn); + + dev->reg_num = rn; + dev->fid = tmp >> 56; + dev->id = (tmp >> 8) & 0xffffffffffff; + dev->crc = tmp & 0xff; + + dev_dbg(&bus->dev, "%s: familly = 0x%x, id = 0x%llx, crc = 0x%x\n", + __func__, dev->fid, dev->id, dev->crc); + + if (dev->crc != w1_calc_crc8((u8 *)&rn, 7)) { + dev_err(&bus->dev, "0x%llx crc error\n", rn); + return; + } + + w1_device_register(bus, dev); +} + +/** + * Performs a ROM Search & registers any devices found. + * The 1-wire search is a simple binary tree search. + * For each bit of the address, we read two bits and write one bit. + * The bit written will put to sleep all devies that don't match that bit. + * When the two reads differ, the direction choice is obvious. + * When both bits are 0, we must choose a path to take. + * When we can scan all 64 bits without having to choose a path, we are done. + * + * See "Application note 187 1-wire search algorithm" at www.maxim-ic.com + * + * @dev The master device to search + * @cb Function to call when a device is found + */ +static void w1_search(struct w1_bus *bus, u8 search_type) +{ + u64 last_rn, rn, tmp64; + int i, slave_count = 0; + int last_zero, last_device; + int search_bit, desc_bit; + u8 triplet_ret = 0; + + search_bit = 0; + rn = last_rn = 0; + last_device = 0; + last_zero = -1; + + desc_bit = 64; + + while ( !last_device && (slave_count++ < bus->max_slave_count) ) { + last_rn = rn; + rn = 0; + + /* + * Reset bus and all 1-wire device state machines + * so they can respond to our requests. + * + * Return 0 - device(s) present, 1 - no devices present. + */ + if (w1_reset_bus(bus)) { + dev_dbg(&bus->dev, "No devices present on the wire.\n"); + break; + } + + /* Do fast search on single slave bus */ + if (bus->max_slave_count == 1) { + int rv; + w1_write_8(bus, W1_READ_ROM); + rv = w1_read_block(bus, (u8 *)&rn, 8); + + if (rv == 8 && rn) + w1_found(bus, rn); + + break; + } + + /* Start the search */ + w1_write_8(bus, search_type); + for (i = 0; i < 64; ++i) { + /* Determine the direction/search bit */ + if (i == desc_bit) + search_bit = 1; /* took the 0 path last time, so take the 1 path */ + else if (i > desc_bit) + search_bit = 0; /* take the 0 path on the next branch */ + else + search_bit = ((last_rn >> i) & 0x1); + + /** Read two bits and write one bit */ + triplet_ret = w1_triplet(bus, search_bit); + + /* quit if no device responded */ + if ( (triplet_ret & 0x03) == 0x03 ) + break; + + /* If both directions were valid, and we took the 0 path... */ + if (triplet_ret == 0) + last_zero = i; + + /* extract the direction taken & update the device number */ + tmp64 = (triplet_ret >> 2); + rn |= (tmp64 << i); + } + + if ( (triplet_ret & 0x03) != 0x03 ) { + if ( (desc_bit == last_zero) || (last_zero < 0)) + last_device = 1; + desc_bit = last_zero; + w1_found(bus, rn); + } + } + + w1_reset_bus(bus); +} + +int w1_bus_register(struct w1_bus *bus) +{ + int ret; + + /* validate minimum functionality */ + if (!(bus->touch_bit && bus->reset_bus) && + !(bus->write_bit && bus->read_bit)) { + pr_err("w1_bus_register: invalid function set\n"); + return -EINVAL; + } + /* While it would be electrically possible to make a device that + * generated a strong pullup in bit bang mode, only hardware that + * controls 1-wire time frames are even expected to support a strong + * pullup. w1_io.c would need to support calling set_pullup before + * the last write_bit operation of a w1_write_8 which it currently + * doesn't. + */ + if (!bus->touch_bit && bus->set_pullup) { + pr_err("w1_add_bus_device: set_pullup requires touch_bit, disabling\n"); + bus->set_pullup = NULL; + } + + if (!bus->reset_bus) + bus->reset_bus = w1_soft_reset_bus; + + if (!bus->touch_bit) + bus->touch_bit = w1_soft_touch_bit; + + if (!bus->read_block) + bus->read_block = w1_soft_read_block; + + if (!bus->read_byte) + bus->read_byte = w1_soft_read_8; + + if (!bus->triplet) + bus->triplet = w1_soft_triplet; + + if (!bus->max_slave_count) + bus->max_slave_count = 10; + + list_add_tail(&bus->list, &w1_buses); + + strcpy(bus->dev.name, "w1_bus"); + bus->dev.id = DEVICE_ID_DYNAMIC; + + bus->dev.parent = bus->parent; + if (bus->parent) + dev_add_child(bus->parent, &bus->dev); + + ret = register_device(&bus->dev); + if (ret) + return ret; + + w1_search(bus, W1_SEARCH); + + return 0; +} + +static int w1_bus_init(void) +{ + return bus_register(&w1_bustype); +} +pure_initcall(w1_bus_init); diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h new file mode 100644 index 0000000000..1373f69f62 --- /dev/null +++ b/drivers/w1/w1.h @@ -0,0 +1,152 @@ +/* + * w1.h + * + * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> + * 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 __W1_H +#define __W1_H + +#include <common.h> +#include <driver.h> + +struct w1_device { + u64 reg_num; + u8 fid; + u64 id; + u8 crc; + + struct w1_bus *bus; + struct device_d dev; +}; + +struct w1_driver { + u8 fid; + u64 id; + + int (*probe) (struct w1_device *dev); + void (*remove) (struct w1_device *dev); + struct driver_d drv; +}; + +int w1_driver_register(struct w1_driver *drv); + +extern struct bus_type w1_bustype; + +#define W1_MAXNAMELEN 32 + +#define W1_SEARCH 0xF0 +#define W1_ALARM_SEARCH 0xEC +#define W1_CONVERT_TEMP 0x44 +#define W1_SKIP_ROM 0xCC +#define W1_READ_SCRATCHPAD 0xBE +#define W1_READ_ROM 0x33 +#define W1_READ_PSUPPLY 0xB4 +#define W1_MATCH_ROM 0x55 +#define W1_RESUME_CMD 0xA5 + +#define W1_SLAVE_ACTIVE 0 + +/** + * Note: read_bit and write_bit are very low level functions and should only + * be used with hardware that doesn't really support 1-wire operations, + * like a parallel/serial port. + * Either define read_bit and write_bit OR define, at minimum, touch_bit and + * reset_bus. + */ +struct w1_bus +{ + struct device_d dev; + struct device_d *parent; + + /** + * Sample the line level + * @return the level read (0 or 1) + */ + u8 (*read_bit)(struct w1_bus *); + + /** Sets the line level */ + void (*write_bit)(struct w1_bus *, u8); + + /** + * touch_bit is the lowest-level function for devices that really + * support the 1-wire protocol. + * touch_bit(0) = write-0 cycle + * touch_bit(1) = write-1 / read cycle + * @return the bit read (0 or 1) + */ + u8 (*touch_bit)(struct w1_bus *, u8); + + /** + * Reads a bytes. Same as 8 touch_bit(1) calls. + * @return the byte read + */ + u8 (*read_byte)(struct w1_bus *); + + /** + * Writes a byte. Same as 8 touch_bit(x) calls. + */ + void (*write_byte)(struct w1_bus *, u8); + + /** + * Same as a series of read_byte() calls + * @return the number of bytes read + */ + u8 (*read_block)(struct w1_bus *, u8 *, int); + + /** Same as a series of write_byte() calls */ + void (*write_block)(struct w1_bus *, const u8 *, int); + + /** + * Combines two reads and a smart write for ROM searches + * @return bit0=Id bit1=comp_id bit2=dir_taken + */ + u8 (*triplet)(struct w1_bus *, u8); + + /** + * long write-0 with a read for the presence pulse detection + * @return -1=Error, 0=Device present, 1=No device present + */ + u8 (*reset_bus)(struct w1_bus *); + + /** + * Put out a strong pull-up pulse of the specified duration. + * @return -1=Error, 0=completed + */ + u8 (*set_pullup)(struct w1_bus *, int); + + /** 5V strong pullup enabled flag, 1 enabled, zero disabled. */ + int enable_pullup; + /** 5V strong pullup duration in milliseconds, zero disabled. */ + int pullup_duration; + + int max_slave_count, slave_count; + + void *data; + struct list_head list; +}; + +u8 w1_read_block(struct w1_bus *bus, u8 *buf, int len); +void w1_write_block(struct w1_bus *bus, const u8 *buf, int len); +void w1_touch_block(struct w1_bus *bus, u8 *buf, int len); +u8 w1_triplet(struct w1_bus *bus, int bdir); +u8 w1_read_8(struct w1_bus *bus); +void w1_write_8(struct w1_bus *bus, u8 byte); +int w1_reset_select_slave(struct w1_device *dev); +int w1_reset_bus(struct w1_bus *bus); +u8 w1_calc_crc8(u8 * data, int len); + +int w1_bus_register(struct w1_bus *bus); + +#endif /* __W1_H */ diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 8fdc7a5aa8..ba33617d22 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1,3 +1,7 @@ + +config WATCHDOG_IMX_RESET_SOURCE + bool + menuconfig WATCHDOG bool "Watchdog support " help @@ -12,4 +16,9 @@ config WATCHDOG_MXS28 help Add support for watchdog management for the i.MX28 SoC. +config WATCHDOG_IMX + bool "i.MX watchdog" + depends on ARCH_IMX + help + Add support for watchdog found on Freescale i.MX SoCs. endif diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index b29103b6cc..f522b88708 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_WATCHDOG) += wd_core.o obj-$(CONFIG_WATCHDOG_MXS28) += im28wd.o +obj-$(CONFIG_WATCHDOG_IMX_RESET_SOURCE) += imxwd.o diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c new file mode 100644 index 0000000000..c422f9819c --- /dev/null +++ b/drivers/watchdog/imxwd.c @@ -0,0 +1,235 @@ +/* + * (c) 2012 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 <errno.h> +#include <malloc.h> +#include <watchdog.h> +#include <reset_source.h> + +struct imx_wd { + struct watchdog wd; + void __iomem *base; + struct device_d *dev; + int (*set_timeout)(struct imx_wd *, unsigned); +}; + +#define to_imx_wd(h) container_of(h, struct imx_wd, wd) + +#define IMX1_WDOG_WCR 0x00 /* Watchdog Control Register */ +#define IMX1_WDOG_WSR 0x04 /* Watchdog Service Register */ +#define IMX1_WDOG_WSTR 0x08 /* Watchdog Status Register */ +#define IMX1_WDOG_WCR_WDE (1 << 0) +#define IMX1_WDOG_WCR_WHALT (1 << 15) + +#define IMX21_WDOG_WCR 0x00 /* Watchdog Control Register */ +#define IMX21_WDOG_WSR 0x02 /* Watchdog Service Register */ +#define IMX21_WDOG_WSTR 0x04 /* Watchdog Status Register */ +#define IMX21_WDOG_WCR_WDE (1 << 2) +#define IMX21_WDOG_WCR_SRS (1 << 4) +#define IMX21_WDOG_WCR_WDA (1 << 5) + +/* valid for i.MX25, i.MX27, i.MX31, i.MX35, i.MX51 */ +#define WSTR_WARMSTART (1 << 0) +/* valid for i.MX25, i.MX27, i.MX31, i.MX35, i.MX51 */ +#define WSTR_WDOG (1 << 1) +/* valid for i.MX27, i.MX31, always '0' on i.MX25, i.MX35, i.MX51 */ +#define WSTR_HARDRESET (1 << 3) +/* valid for i.MX27, i.MX31, always '0' on i.MX25, i.MX35, i.MX51 */ +#define WSTR_COLDSTART (1 << 4) + +static int imx1_watchdog_set_timeout(struct imx_wd *priv, int timeout) +{ + u16 val; + + dev_dbg(priv->dev, "%s: %d\n", __func__, timeout); + + if (timeout > 64) + return -EINVAL; + + if (!timeout) { + writew(IMX1_WDOG_WCR_WHALT, priv->base + IMX1_WDOG_WCR); + return 0; + } + + if (timeout > 0) + val = (timeout * 2 - 1) << 8; + else + val = 0; + + writew(val, priv->base + IMX1_WDOG_WCR); + writew(IMX1_WDOG_WCR_WDE | val, priv->base + IMX1_WDOG_WCR); + + /* Write Service Sequence */ + writew(0x5555, priv->base + IMX1_WDOG_WSR); + writew(0xaaaa, priv->base + IMX1_WDOG_WSR); + + return 0; +} + +static int imx21_watchdog_set_timeout(struct imx_wd *priv, int timeout) +{ + u16 val; + + dev_dbg(priv->dev, "%s: %d\n", __func__, timeout); + + if (!timeout || timeout > 128) + return -EINVAL; + + if (timeout > 0) + val = ((timeout * 2 - 1) << 8) | IMX21_WDOG_WCR_SRS | + IMX21_WDOG_WCR_WDA; + else + val = 0; + + writew(val, priv->base + IMX21_WDOG_WCR); + writew(IMX21_WDOG_WCR_WDE | val, priv->base + IMX21_WDOG_WCR); + + /* Write Service Sequence */ + writew(0x5555, priv->base + IMX21_WDOG_WSR); + writew(0xaaaa, priv->base + IMX21_WDOG_WSR); + + return 0; +} + +static int imx_watchdog_set_timeout(struct watchdog *wd, unsigned timeout) +{ + struct imx_wd *priv = (struct imx_wd *)to_imx_wd(wd); + + return priv->set_timeout(priv, timeout); +} + +static struct imx_wd *reset_wd; + +void __noreturn reset_cpu(unsigned long addr) +{ + if (reset_wd) + reset_wd->set_timeout(reset_wd, -1); + + mdelay(1000); + + hang(); +} + +static void imx_watchdog_detect_reset_source(struct imx_wd *priv) +{ + u16 val = readw(priv->base + IMX21_WDOG_WSTR); + + if (val & WSTR_COLDSTART) { + set_reset_source(RESET_POR); + return; + } + + if (val & (WSTR_HARDRESET | WSTR_WARMSTART)) { + set_reset_source(RESET_RST); + return; + } + + if (val & WSTR_WDOG) { + set_reset_source(RESET_WDG); + return; + } + + /* else keep the default 'unknown' state */ +} + +static int imx_wd_probe(struct device_d *dev) +{ + struct imx_wd *priv; + void *fn; + int ret; + + ret = dev_get_drvdata(dev, (unsigned long *)&fn); + if (ret) + return ret; + + priv = xzalloc(sizeof(struct imx_wd)); + priv->base = dev_request_mem_region(dev, 0); + priv->set_timeout = fn; + priv->wd.set_timeout = imx_watchdog_set_timeout; + priv->dev = dev; + + if (!reset_wd) + reset_wd = priv; + + if (IS_ENABLED(CONFIG_WATCHDOG_IMX)) { + ret = watchdog_register(&priv->wd); + if (ret) + goto on_error; + } + + if (fn != imx1_watchdog_set_timeout) + imx_watchdog_detect_reset_source(priv); + + dev->priv = priv; + + return 0; + +on_error: + if (reset_wd && reset_wd != priv) + free(priv); + return ret; +} + +static void imx_wd_remove(struct device_d *dev) +{ + struct imx_wd *priv = dev->priv; + + if (IS_ENABLED(CONFIG_WATCHDOG_IMX)) + watchdog_deregister(&priv->wd); + + if (reset_wd && reset_wd != priv) + free(priv); +} + +static __maybe_unused struct of_device_id imx_wdt_dt_ids[] = { + { + .compatible = "fsl,imx1-wdt", + .data = (unsigned long)&imx1_watchdog_set_timeout, + }, { + .compatible = "fsl,imx21-wdt", + .data = (unsigned long)&imx21_watchdog_set_timeout, + }, { + /* sentinel */ + } +}; + +static struct platform_device_id imx_wdt_ids[] = { + { + .name = "imx1-wdt", + .driver_data = (unsigned long)&imx1_watchdog_set_timeout, + }, { + .name = "imx21-wdt", + .driver_data = (unsigned long)&imx21_watchdog_set_timeout, + }, { + /* sentinel */ + }, +}; + +static struct driver_d imx_wd_driver = { + .name = "imx-watchdog", + .probe = imx_wd_probe, + .remove = imx_wd_remove, + .of_compatible = DRV_OF_COMPAT(imx_wdt_dt_ids), + .id_table = imx_wdt_ids, +}; + +static int imx_wd_init(void) +{ + return platform_driver_register(&imx_wd_driver); +} + +device_initcall(imx_wd_init); diff --git a/fs/devfs-core.c b/fs/devfs-core.c index 2788fe7e7a..0d2f75a5c3 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -136,6 +136,7 @@ static int partition_ioctl(struct cdev *cdev, int request, void *buf) user->flags = cdev->mtd->flags; user->size = cdev->mtd->size; user->erasesize = cdev->mtd->erasesize; + user->writesize = cdev->mtd->writesize; user->oobsize = cdev->mtd->oobsize; user->mtd = cdev->mtd; /* The below fields are obsolete */ @@ -715,12 +715,13 @@ int ioctl(int fd, int request, void *buf) { struct device_d *dev; struct fs_driver_d *fsdrv; - FILE *f = &files[fd]; + FILE *f; int ret; if (check_fd(fd)) return -errno; + f = &files[fd]; dev = f->dev; fsdrv = dev_to_fs_driver(dev); @@ -738,12 +739,13 @@ int read(int fd, void *buf, size_t count) { struct device_d *dev; struct fs_driver_d *fsdrv; - FILE *f = &files[fd]; + FILE *f; int ret; if (check_fd(fd)) return -errno; + f = &files[fd]; dev = f->dev; fsdrv = dev_to_fs_driver(dev); @@ -768,12 +770,13 @@ ssize_t write(int fd, const void *buf, size_t count) { struct device_d *dev; struct fs_driver_d *fsdrv; - FILE *f = &files[fd]; + FILE *f; int ret; if (check_fd(fd)) return -errno; + f = &files[fd]; dev = f->dev; fsdrv = dev_to_fs_driver(dev); @@ -803,12 +806,13 @@ int flush(int fd) { struct device_d *dev; struct fs_driver_d *fsdrv; - FILE *f = &files[fd]; + FILE *f; int ret; if (check_fd(fd)) return -errno; + f = &files[fd]; dev = f->dev; fsdrv = dev_to_fs_driver(dev); @@ -827,13 +831,14 @@ loff_t lseek(int fildes, loff_t offset, int whence) { struct device_d *dev; struct fs_driver_d *fsdrv; - FILE *f = &files[fildes]; + FILE *f; loff_t pos; int ret; if (check_fd(fildes)) return -1; + f = &files[fildes]; dev = f->dev; fsdrv = dev_to_fs_driver(dev); if (!fsdrv->lseek) { @@ -877,11 +882,12 @@ int erase(int fd, size_t count, unsigned long offset) { struct device_d *dev; struct fs_driver_d *fsdrv; - FILE *f = &files[fd]; + FILE *f; int ret; if (check_fd(fd)) return -errno; + f = &files[fd]; if (offset >= f->size) return 0; if (count > f->size - offset) @@ -905,11 +911,12 @@ int protect(int fd, size_t count, unsigned long offset, int prot) { struct device_d *dev; struct fs_driver_d *fsdrv; - FILE *f = &files[fd]; + FILE *f; int ret; if (check_fd(fd)) return -errno; + f = &files[fd]; if (offset >= f->size) return 0; if (count > f->size - offset) @@ -948,13 +955,14 @@ void *memmap(int fd, int flags) { struct device_d *dev; struct fs_driver_d *fsdrv; - FILE *f = &files[fd]; + FILE *f; void *retp = (void *)-1; int ret; if (check_fd(fd)) return retp; + f = &files[fd]; dev = f->dev; fsdrv = dev_to_fs_driver(dev); @@ -975,12 +983,13 @@ int close(int fd) { struct device_d *dev; struct fs_driver_d *fsdrv; - FILE *f = &files[fd]; + FILE *f; int ret; if (check_fd(fd)) return -errno; + f = &files[fd]; dev = f->dev; fsdrv = dev_to_fs_driver(dev); @@ -62,6 +62,7 @@ #define STATE_DONE 8 #define TFTP_BLOCK_SIZE 512 /* default TFTP block size */ +#define TFTP_FIFO_SIZE 4096 #define TFTP_ERR_RESEND 1 @@ -80,6 +81,7 @@ struct file_priv { struct kfifo *fifo; void *buf; int blocksize; + int block_requested; }; struct tftp_priv { @@ -152,11 +154,14 @@ static int tftp_send(struct file_priv *priv) break; case STATE_RDATA: + if (priv->block == priv->block_requested) + return 0; case STATE_OACK: xp = pkt; s = (uint16_t *)pkt; *s++ = htons(TFTP_ACK); *s++ = htons(priv->block); + priv->block_requested = priv->block; pkt = (unsigned char *)s; len = pkt - xp; break; @@ -199,6 +204,7 @@ static int tftp_poll(struct file_priv *priv) if (is_timeout(priv->resend_timeout, TFTP_RESEND_TIMEOUT)) { printf("T "); priv->resend_timeout = get_time_ns(); + priv->block_requested = -1; return TFTP_ERR_RESEND; } @@ -392,8 +398,9 @@ static struct file_priv *tftp_do_open(struct device_d *dev, priv->err = -EINVAL; priv->filename = filename; priv->blocksize = TFTP_BLOCK_SIZE; + priv->block_requested = -1; - priv->fifo = kfifo_alloc(4096); + priv->fifo = kfifo_alloc(TFTP_FIFO_SIZE); if (!priv->fifo) { ret = -ENOMEM; goto out; @@ -552,6 +559,9 @@ static int tftp_read(struct device_d *dev, FILE *f, void *buf, size_t insize) outsize += now; buf += now; insize -= now; + } + + if (TFTP_FIFO_SIZE - kfifo_len(priv->fifo) >= priv->blocksize) { tftp_send(priv); tftp_timer_reset(priv); } diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h new file mode 100644 index 0000000000..c2e7a5d368 --- /dev/null +++ b/include/asm-generic/gpio.h @@ -0,0 +1,21 @@ +#ifndef __ASM_GENERIC_GPIO_H +#define __ASM_GENERIC_GPIO_H + +#define ARCH_NR_GPIOS 256 + +static inline int gpio_is_valid(int gpio) +{ + if (gpio < 0) + return 0; + if (gpio < ARCH_NR_GPIOS) + return 1; + return 0; +} + +void gpio_set_value(unsigned gpio, int value); +int gpio_get_value(unsigned gpio); +int gpio_direction_output(unsigned gpio, int value); +int gpio_direction_input(unsigned gpio); + +#endif /* __ASM_GENERIC_GPIO_H */ + diff --git a/include/bbu.h b/include/bbu.h new file mode 100644 index 0000000000..095eebcf4a --- /dev/null +++ b/include/bbu.h @@ -0,0 +1,49 @@ +#ifndef __INCLUDE_BBU_H +#define __INCLUDE_BBU_H + +struct bbu_data { +#define BBU_FLAG_FORCE (1 << 0) +#define BBU_FLAG_YES (1 << 1) + unsigned long flags; + int force; + void *image; + const char *imagefile; + const char *devicefile; + size_t len; + const char *handler_name; +}; + +struct bbu_handler { + int (*handler)(struct bbu_handler *, struct bbu_data *); + const char *name; + struct list_head list; +#define BBU_HANDLER_FLAG_DEFAULT (1 << 0) + unsigned long flags; + + /* default device file, can be overwritten on the command line */ + const char *devicefile; +}; + +int bbu_force(struct bbu_data *, const char *fmt, ...) + __attribute__ ((format(__printf__, 2, 3))); + +int bbu_confirm(struct bbu_data *); + +int barebox_update(struct bbu_data *); + +void bbu_handlers_list(void); + +#ifdef CONFIG_BAREBOX_UPDATE + +int bbu_register_handler(struct bbu_handler *); + +#else + +static inline int bbu_register_handler(struct bbu_handler *unused) +{ + return -EINVAL; +} + +#endif + +#endif /* __INCLUDE_BBU_H */ diff --git a/include/clock.h b/include/clock.h index c01a8d00ab..a169790d0f 100644 --- a/include/clock.h +++ b/include/clock.h @@ -32,6 +32,7 @@ void clocks_calc_mult_shift(uint32_t *mult, uint32_t *shift, uint32_t from, uint uint32_t clocksource_hz2mult(uint32_t hz, uint32_t shift_constant); int is_timeout(uint64_t start_ns, uint64_t time_offset_ns); +int is_timeout_non_interruptible(uint64_t start_ns, uint64_t time_offset_ns); // void udelay(unsigned long usecs); diff --git a/include/common.h b/include/common.h index c1f44b402c..e30774a43e 100644 --- a/include/common.h +++ b/include/common.h @@ -256,4 +256,17 @@ static inline void barebox_banner(void) {} (__x < 0) ? -__x : __x; \ }) +/* + * Check if two regions overlap. returns true if they do, false otherwise + */ +static inline bool region_overlap(unsigned long starta, unsigned long lena, + unsigned long startb, unsigned long lenb) +{ + if (starta + lena <= startb) + return 0; + if (startb + lenb <= starta) + return 0; + return 1; +} + #endif /* __COMMON_H_ */ diff --git a/include/debug_ll.h b/include/debug_ll.h index a8bac273e2..c7445731d6 100644 --- a/include/debug_ll.h +++ b/include/debug_ll.h @@ -30,7 +30,7 @@ ch += (ch >= 10) ? 'a' - 10 : '0';\ PUTC_LL (ch); }}) -static __inline__ void PUTS_LL(char * str) +static __inline__ void PUTS_LL(const char * str) { while (*str) { if (*str == '\n') { diff --git a/include/environment.h b/include/environment.h index fd7735ae74..4184977009 100644 --- a/include/environment.h +++ b/include/environment.h @@ -61,6 +61,12 @@ static inline unsigned long long getenv_ull(const char *name) { return 0; } + +static inline int export(const char *var) +{ + return -EINVAL; +} + #endif int env_pop_context(void); diff --git a/include/filetype.h b/include/filetype.h index 0b6cd24a6d..0a722a0a54 100644 --- a/include/filetype.h +++ b/include/filetype.h @@ -22,9 +22,11 @@ enum filetype { filetype_mbr, filetype_bmp, filetype_png, + filetype_max, }; 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); enum filetype file_name_detect_type(const char *filename); enum filetype is_fat_or_mbr(const unsigned char *sector, unsigned long *bootsec); diff --git a/include/i2c/at24.h b/include/i2c/at24.h new file mode 100644 index 0000000000..1013308459 --- /dev/null +++ b/include/i2c/at24.h @@ -0,0 +1,35 @@ +/* + * at24.h - platform_data for the at24 (generic eeprom) driver + * (C) Copyright 2008 by Pengutronix + * (C) Copyright 2012 by Wolfram Sang + * same license as the driver + */ + +#ifndef _LINUX_AT24_H +#define _LINUX_AT24_H + +#include <linux/types.h> + +/** + * struct at24_platform_data - data to set up at24 (generic eeprom) driver + * @byte_len: size of eeprom in byte + * @page_size: number of byte which can be written in one go + * @flags: tunable options, check AT24_FLAG_* defines + * + * If you set up a custom eeprom type, please double-check the parameters. + * Especially page_size needs extra care, as you risk data loss if your value + * is bigger than what the chip actually supports! + * + */ + +struct at24_platform_data { + u32 byte_len; /* size (sum of all addr) */ + u16 page_size; /* for writes */ + u8 flags; +#define AT24_FLAG_ADDR16 0x80 /* address pointer is 16 bit */ +#define AT24_FLAG_READONLY 0x40 /* sysfs-entry will be read-only */ +#define AT24_FLAG_IRUGO 0x20 /* sysfs-entry will be world-readable */ +#define AT24_FLAG_TAKE8ADDR 0x10 /* take always 8 addresses (24c00) */ +}; + +#endif /* _LINUX_AT24_H */ diff --git a/include/i2c/i2c-algo-bit.h b/include/i2c/i2c-algo-bit.h new file mode 100644 index 0000000000..1b72219687 --- /dev/null +++ b/include/i2c/i2c-algo-bit.h @@ -0,0 +1,55 @@ +/* ------------------------------------------------------------------------- */ +/* i2c-algo-bit.h i2c driver algorithms for bit-shift adapters */ +/* ------------------------------------------------------------------------- */ +/* Copyright (C) 1995-99 Simon G. Vogl + + 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., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301 USA. */ +/* ------------------------------------------------------------------------- */ + +/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even + Frodo Looijaard <frodol@dds.nl> */ + +#ifndef _LINUX_I2C_ALGO_BIT_H +#define _LINUX_I2C_ALGO_BIT_H + +/* --- Defines for bit-adapters --------------------------------------- */ +/* + * This struct contains the hw-dependent functions of bit-style adapters to + * manipulate the line states, and to init any hw-specific features. This is + * only used if you have more than one hw-type of adapter running. + */ +struct i2c_algo_bit_data { + void *data; /* private data for lowlevel routines */ + void (*setsda) (void *data, int state); + void (*setscl) (void *data, int state); + int (*getsda) (void *data); + int (*getscl) (void *data); + int (*pre_xfer) (struct i2c_adapter *); + void (*post_xfer) (struct i2c_adapter *); + + /* local settings */ + int udelay; /* half clock cycle time in us, + minimum 2 us for fast-mode I2C, + minimum 5 us for standard-mode I2C and SMBus, + maximum 50 us for SMBus */ + int timeout_ms; /* in ms */ +}; + +int i2c_bit_add_bus(struct i2c_adapter *); +int i2c_bit_add_numbered_bus(struct i2c_adapter *); +extern const struct i2c_algorithm i2c_bit_algo; + +#endif /* _LINUX_I2C_ALGO_BIT_H */ diff --git a/include/i2c/i2c-gpio.h b/include/i2c/i2c-gpio.h new file mode 100644 index 0000000000..55feb82a90 --- /dev/null +++ b/include/i2c/i2c-gpio.h @@ -0,0 +1,38 @@ +/* + * i2c-gpio interface to platform code + * + * 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 version 2 as + * published by the Free Software Foundation. + */ +#ifndef _LINUX_I2C_GPIO_H +#define _LINUX_I2C_GPIO_H + +/** + * struct i2c_gpio_platform_data - Platform-dependent data for i2c-gpio + * @sda_pin: GPIO pin ID to use for SDA + * @scl_pin: GPIO pin ID to use for SCL + * @udelay: signal toggle delay. SCL frequency is (500 / udelay) kHz + * @timeout_ms: clock stretching timeout in ms. If the slave keeps + * SCL low for longer than this, the transfer will time out. + * @sda_is_open_drain: SDA is configured as open drain, i.e. the pin + * isn't actively driven high when setting the output value high. + * gpio_get_value() must return the actual pin state even if the + * pin is configured as an output. + * @scl_is_open_drain: SCL is set up as open drain. Same requirements + * as for sda_is_open_drain apply. + * @scl_is_output_only: SCL output drivers cannot be turned off. + */ +struct i2c_gpio_platform_data { + unsigned int sda_pin; + unsigned int scl_pin; + int udelay; + int timeout_ms; + unsigned int sda_is_open_drain:1; + unsigned int scl_is_open_drain:1; + unsigned int scl_is_output_only:1; +}; + +#endif /* _LINUX_I2C_GPIO_H */ diff --git a/include/i2c/i2c.h b/include/i2c/i2c.h index de2a7ea27d..dc5e5fc99b 100644 --- a/include/i2c/i2c.h +++ b/include/i2c/i2c.h @@ -66,10 +66,12 @@ struct i2c_msg { * */ struct i2c_adapter { - struct device_d *dev; /* ptr to device */ + struct device_d dev; /* ptr to device */ int nr; /* bus number */ int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); struct list_head list; + int retries; + void *algo_data; }; @@ -127,6 +129,14 @@ static inline int i2c_register_board_info(int busnum, extern int i2c_add_numbered_adapter(struct i2c_adapter *adapter); struct i2c_adapter *i2c_get_adapter(int busnum); +/* For devices that use several addresses, use i2c_new_dummy() to make + * client handles for the extra addresses. + */ +extern struct i2c_client * +i2c_new_dummy(struct i2c_adapter *adap, u16 address); + + + extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); extern int i2c_master_send(struct i2c_client *client, const char *buf, int count); extern int i2c_master_recv(struct i2c_client *client, char *buf, int count); diff --git a/include/input/qt1070.h b/include/input/qt1070.h new file mode 100644 index 0000000000..014f67bf00 --- /dev/null +++ b/include/input/qt1070.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#ifndef __QT1070_H__ +#define __QT1070_H__ + +#define QT1070_NB_BUTTONS 7 + +struct qt1070_platform_data { + int code[QT1070_NB_BUTTONS]; + int nb_code; + int irq_pin; +}; + +#endif /* __QT1070_H__ */ diff --git a/include/linux/amba/pl061.h b/include/linux/amba/pl061.h new file mode 100644 index 0000000000..d498cd7a8c --- /dev/null +++ b/include/linux/amba/pl061.h @@ -0,0 +1,12 @@ +#ifndef __AMBA_PL061_H__ +#define __AMBA_PL061_H__ + +#include <linux/types.h> + +/* platform data for the PL061 GPIO driver */ + +struct pl061_platform_data { + /* number of the first GPIO */ + unsigned gpio_base; +}; +#endif /* __AMBA_PL061_H__ */ diff --git a/include/linux/clk.h b/include/linux/clk.h index e9031dd17a..00588bff05 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -188,6 +188,8 @@ struct clk *clk_fixed_factor(const char *name, const char *parent, unsigned int mult, unsigned int div); struct clk *clk_mux(const char *name, void __iomem *reg, u8 shift, u8 width, const char **parents, u8 num_parents); +struct clk *clk_gate(const char *name, const char *parent, void __iomem *reg, + u8 shift); int clk_register(struct clk *clk); diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h index d2f0d8972e..1fc0ab9973 100644 --- a/include/linux/clkdev.h +++ b/include/linux/clkdev.h @@ -33,6 +33,7 @@ void clkdev_drop(struct clk_lookup *cl); void clkdev_add_table(struct clk_lookup *, size_t); int clk_add_alias(const char *, const char *, char *, struct device_d *); +int clk_register_clkdev(struct clk *, const char *, const char *, ...); int clkdev_add_physbase(struct clk *clk, unsigned long base, const char *id); diff --git a/include/linux/kernel.h b/include/linux/kernel.h index e9e2f0764f..92c3391f16 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -90,5 +90,20 @@ __val = __val < __min ? __min: __val; \ __val > __max ? __max: __val; }) + +/* The `const' in roundup() prevents gcc-3.3 from calling __divdi3 */ +#define roundup(x, y) ( \ +{ \ + const typeof(y) __y = y; \ + (((x) + (__y - 1)) / __y) * __y; \ +} \ +) +#define rounddown(x, y) ( \ +{ \ + typeof(x) __x = (x); \ + __x - (__x % (y)); \ +} \ +) + #endif /* _LINUX_KERNEL_H */ diff --git a/include/linux/log2.h b/include/linux/log2.h new file mode 100644 index 0000000000..389043a93c --- /dev/null +++ b/include/linux/log2.h @@ -0,0 +1,190 @@ +/* Integer base 2 logarithm calculation + * + * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.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. + */ + +#ifndef _LINUX_LOG2_H +#define _LINUX_LOG2_H + +#include <linux/types.h> +#include <linux/bitops.h> + +/* + * deal with unrepresentable constant logarithms + */ +extern __attribute__((const, noreturn)) +int ____ilog2_NaN(void); + +/* + * non-constant log of base 2 calculators + * - the arch may override these in asm/bitops.h if they can be implemented + * more efficiently than using fls() and fls64() + * - the arch is not required to handle n==0 if implementing the fallback + */ +#ifndef CONFIG_ARCH_HAS_ILOG2_U32 +static inline __attribute__((const)) +int __ilog2_u32(u32 n) +{ + return fls(n) - 1; +} +#endif + +#ifndef CONFIG_ARCH_HAS_ILOG2_U64 +static inline __attribute__((const)) +int __ilog2_u64(u64 n) +{ + return fls64(n) - 1; +} +#endif + +/* + * Determine whether some value is a power of two, where zero is + * *not* considered a power of two. + */ + +static inline __attribute__((const)) +bool is_power_of_2(unsigned long n) +{ + return (n != 0 && ((n & (n - 1)) == 0)); +} + +/** + * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value + * @n - parameter + * + * constant-capable log of base 2 calculation + * - this can be used to initialise global variables from constant data, hence + * the massive ternary operator construction + * + * selects the appropriately-sized optimised version depending on sizeof(n) + */ +#define ilog2(n) \ +( \ + __builtin_constant_p(n) ? ( \ + (n) < 1 ? ____ilog2_NaN() : \ + (n) & (1ULL << 63) ? 63 : \ + (n) & (1ULL << 62) ? 62 : \ + (n) & (1ULL << 61) ? 61 : \ + (n) & (1ULL << 60) ? 60 : \ + (n) & (1ULL << 59) ? 59 : \ + (n) & (1ULL << 58) ? 58 : \ + (n) & (1ULL << 57) ? 57 : \ + (n) & (1ULL << 56) ? 56 : \ + (n) & (1ULL << 55) ? 55 : \ + (n) & (1ULL << 54) ? 54 : \ + (n) & (1ULL << 53) ? 53 : \ + (n) & (1ULL << 52) ? 52 : \ + (n) & (1ULL << 51) ? 51 : \ + (n) & (1ULL << 50) ? 50 : \ + (n) & (1ULL << 49) ? 49 : \ + (n) & (1ULL << 48) ? 48 : \ + (n) & (1ULL << 47) ? 47 : \ + (n) & (1ULL << 46) ? 46 : \ + (n) & (1ULL << 45) ? 45 : \ + (n) & (1ULL << 44) ? 44 : \ + (n) & (1ULL << 43) ? 43 : \ + (n) & (1ULL << 42) ? 42 : \ + (n) & (1ULL << 41) ? 41 : \ + (n) & (1ULL << 40) ? 40 : \ + (n) & (1ULL << 39) ? 39 : \ + (n) & (1ULL << 38) ? 38 : \ + (n) & (1ULL << 37) ? 37 : \ + (n) & (1ULL << 36) ? 36 : \ + (n) & (1ULL << 35) ? 35 : \ + (n) & (1ULL << 34) ? 34 : \ + (n) & (1ULL << 33) ? 33 : \ + (n) & (1ULL << 32) ? 32 : \ + (n) & (1ULL << 31) ? 31 : \ + (n) & (1ULL << 30) ? 30 : \ + (n) & (1ULL << 29) ? 29 : \ + (n) & (1ULL << 28) ? 28 : \ + (n) & (1ULL << 27) ? 27 : \ + (n) & (1ULL << 26) ? 26 : \ + (n) & (1ULL << 25) ? 25 : \ + (n) & (1ULL << 24) ? 24 : \ + (n) & (1ULL << 23) ? 23 : \ + (n) & (1ULL << 22) ? 22 : \ + (n) & (1ULL << 21) ? 21 : \ + (n) & (1ULL << 20) ? 20 : \ + (n) & (1ULL << 19) ? 19 : \ + (n) & (1ULL << 18) ? 18 : \ + (n) & (1ULL << 17) ? 17 : \ + (n) & (1ULL << 16) ? 16 : \ + (n) & (1ULL << 15) ? 15 : \ + (n) & (1ULL << 14) ? 14 : \ + (n) & (1ULL << 13) ? 13 : \ + (n) & (1ULL << 12) ? 12 : \ + (n) & (1ULL << 11) ? 11 : \ + (n) & (1ULL << 10) ? 10 : \ + (n) & (1ULL << 9) ? 9 : \ + (n) & (1ULL << 8) ? 8 : \ + (n) & (1ULL << 7) ? 7 : \ + (n) & (1ULL << 6) ? 6 : \ + (n) & (1ULL << 5) ? 5 : \ + (n) & (1ULL << 4) ? 4 : \ + (n) & (1ULL << 3) ? 3 : \ + (n) & (1ULL << 2) ? 2 : \ + (n) & (1ULL << 1) ? 1 : \ + (n) & (1ULL << 0) ? 0 : \ + ____ilog2_NaN() \ + ) : \ + (sizeof(n) <= 4) ? \ + __ilog2_u32(n) : \ + __ilog2_u64(n) \ + ) + +/** + * roundup_pow_of_two - round the given value up to nearest power of two + * @n - parameter + * + * round the given value up to the nearest power of two + * - the result is undefined when n == 0 + * - this can be used to initialise global variables from constant data + */ +#define roundup_pow_of_two(n) \ +( \ + __builtin_constant_p(n) ? ( \ + (n == 1) ? 1 : \ + (1UL << (ilog2((n) - 1) + 1)) \ + ) : \ + __roundup_pow_of_two(n) \ + ) + +/** + * rounddown_pow_of_two - round the given value down to nearest power of two + * @n - parameter + * + * round the given value down to the nearest power of two + * - the result is undefined when n == 0 + * - this can be used to initialise global variables from constant data + */ +#define rounddown_pow_of_two(n) \ +( \ + __builtin_constant_p(n) ? ( \ + (1UL << ilog2(n))) : \ + __rounddown_pow_of_two(n) \ + ) + +/** + * order_base_2 - calculate the (rounded up) base 2 order of the argument + * @n: parameter + * + * The first few values calculated by this routine: + * ob2(0) = 0 + * ob2(1) = 0 + * ob2(2) = 1 + * ob2(3) = 2 + * ob2(4) = 2 + * ob2(5) = 3 + * ... and so on. + */ + +#define order_base_2(n) ilog2(roundup_pow_of_two(n)) + +#endif /* _LINUX_LOG2_H */ diff --git a/include/linux/math64.h b/include/linux/math64.h new file mode 100644 index 0000000000..71dd6d7109 --- /dev/null +++ b/include/linux/math64.h @@ -0,0 +1,121 @@ +#ifndef _LINUX_MATH64_H +#define _LINUX_MATH64_H + +#include <linux/types.h> +#include <asm-generic/div64.h> + +#if BITS_PER_LONG == 64 + +#define div64_long(x,y) div64_s64((x),(y)) + +/** + * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder + * + * This is commonly provided by 32bit archs to provide an optimized 64bit + * divide. + */ +static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) +{ + *remainder = dividend % divisor; + return dividend / divisor; +} + +/** + * div_s64_rem - signed 64bit divide with 32bit divisor with remainder + */ +static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder) +{ + *remainder = dividend % divisor; + return dividend / divisor; +} + +/** + * div64_u64 - unsigned 64bit divide with 64bit divisor + */ +static inline u64 div64_u64(u64 dividend, u64 divisor) +{ + return dividend / divisor; +} + +/** + * div64_s64 - signed 64bit divide with 64bit divisor + */ +static inline s64 div64_s64(s64 dividend, s64 divisor) +{ + return dividend / divisor; +} + +#elif BITS_PER_LONG == 32 + +#define div64_long(x,y) div_s64((x),(y)) + +#ifndef div_u64_rem +static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) +{ + *remainder = do_div(dividend, divisor); + return dividend; +} +#endif + +#ifndef div_s64_rem +extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder); +#endif + +#ifndef div64_u64 +extern u64 div64_u64(u64 dividend, u64 divisor); +#endif + +#ifndef div64_s64 +extern s64 div64_s64(s64 dividend, s64 divisor); +#endif + +#endif /* BITS_PER_LONG */ + +/** + * div_u64 - unsigned 64bit divide with 32bit divisor + * + * This is the most common 64bit divide and should be used if possible, + * as many 32bit archs can optimize this variant better than a full 64bit + * divide. + */ +#ifndef div_u64 +static inline u64 div_u64(u64 dividend, u32 divisor) +{ + u32 remainder; + return div_u64_rem(dividend, divisor, &remainder); +} +#endif + +/** + * div_s64 - signed 64bit divide with 32bit divisor + */ +#ifndef div_s64 +static inline s64 div_s64(s64 dividend, s32 divisor) +{ + s32 remainder; + return div_s64_rem(dividend, divisor, &remainder); +} +#endif + +u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder); + +static __always_inline u32 +__iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) +{ + u32 ret = 0; + + while (dividend >= divisor) { + /* The following asm() prevents the compiler from + optimising this loop into a modulo operation. */ + asm("" : "+rm"(dividend)); + + dividend -= divisor; + ret++; + } + + *remainder = dividend; + + return ret; +} + +#endif /* _LINUX_MATH64_H */ diff --git a/include/linux/phy.h b/include/linux/phy.h index 76f9edb237..4f14daef65 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -226,6 +226,7 @@ struct phy_driver { #define PHY_ANY_UID 0xffffffff int phy_driver_register(struct phy_driver *drv); +int phy_drivers_register(struct phy_driver *new_driver, int n); struct phy_device *get_phy_device(struct mii_bus *bus, int addr); int phy_init(void); diff --git a/include/linux/smscphy.h b/include/linux/smscphy.h new file mode 100644 index 0000000000..ce718cbce4 --- /dev/null +++ b/include/linux/smscphy.h @@ -0,0 +1,25 @@ +#ifndef __LINUX_SMSCPHY_H__ +#define __LINUX_SMSCPHY_H__ + +#define MII_LAN83C185_ISF 29 /* Interrupt Source Flags */ +#define MII_LAN83C185_IM 30 /* Interrupt Mask */ +#define MII_LAN83C185_CTRL_STATUS 17 /* Mode/Status Register */ + +#define MII_LAN83C185_ISF_INT1 (1<<1) /* Auto-Negotiation Page Received */ +#define MII_LAN83C185_ISF_INT2 (1<<2) /* Parallel Detection Fault */ +#define MII_LAN83C185_ISF_INT3 (1<<3) /* Auto-Negotiation LP Ack */ +#define MII_LAN83C185_ISF_INT4 (1<<4) /* Link Down */ +#define MII_LAN83C185_ISF_INT5 (1<<5) /* Remote Fault Detected */ +#define MII_LAN83C185_ISF_INT6 (1<<6) /* Auto-Negotiation complete */ +#define MII_LAN83C185_ISF_INT7 (1<<7) /* ENERGYON */ + +#define MII_LAN83C185_ISF_INT_ALL (0x0e) + +#define MII_LAN83C185_ISF_INT_PHYLIB_EVENTS \ + (MII_LAN83C185_ISF_INT6 | MII_LAN83C185_ISF_INT4 | \ + MII_LAN83C185_ISF_INT7) + +#define MII_LAN83C185_EDPWRDOWN (1 << 13) /* EDPWRDOWN */ +#define MII_LAN83C185_ENERGYON (1 << 1) /* ENERGYON */ + +#endif /* __LINUX_SMSCPHY_H__ */ diff --git a/include/linux/w1-gpio.h b/include/linux/w1-gpio.h new file mode 100644 index 0000000000..065e3ae79a --- /dev/null +++ b/include/linux/w1-gpio.h @@ -0,0 +1,25 @@ +/* + * w1-gpio interface to platform code + * + * Copyright (C) 2007 Ville Syrjala <syrjala@sci.fi> + * + * 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. + */ +#ifndef _LINUX_W1_GPIO_H +#define _LINUX_W1_GPIO_H + +/** + * struct w1_gpio_platform_data - Platform-dependent data for w1-gpio + * @pin: GPIO pin to use + * @is_open_drain: GPIO pin is configured as open drain + */ +struct w1_gpio_platform_data { + unsigned int pin; + unsigned int is_open_drain:1; + void (*enable_external_pullup)(int enable); + unsigned int ext_pullup_enable_pin; +}; + +#endif /* _LINUX_W1_GPIO_H */ diff --git a/include/mfd/twl6030.h b/include/mfd/twl6030.h index f1278d4485..bb4f773225 100644 --- a/include/mfd/twl6030.h +++ b/include/mfd/twl6030.h @@ -371,6 +371,14 @@ enum twl6030_reg { /* JTAG */ TWL6030_JTAG_JTAGVERNUM = 0x0287, TWL6030_JTAG_EPROM_REV = 0x02DF, + TWL6030_DIEID_0 = 0x02C0, + TWL6030_DIEID_1 = 0x02C1, + TWL6030_DIEID_2 = 0x02C2, + TWL6030_DIEID_3 = 0x02C3, + TWL6030_DIEID_4 = 0x02C4, + TWL6030_DIEID_5 = 0x02C5, + TWL6030_DIEID_6 = 0x02C6, + TWL6030_DIEID_7 = 0x02C7, /* GPADC Trimming */ TWL6030_GPADC_TRIM1 = 0x02CD, TWL6030_GPADC_TRIM2 = 0x02CE, diff --git a/include/of.h b/include/of.h index 7b6a23ad71..e6342b667c 100644 --- a/include/of.h +++ b/include/of.h @@ -114,6 +114,7 @@ int of_parse_partitions(const char *cdevname, struct device_node *of_get_root_node(void); int of_alias_get_id(struct device_node *np, const char *stem); +int of_device_is_stdout_path(struct device_d *dev); #else static inline int of_parse_partitions(const char *cdevname, struct device_node *node) @@ -130,6 +131,11 @@ static inline int of_alias_get_id(struct device_node *np, const char *stem) { return -ENOENT; } + +static inline int of_device_is_stdout_path(struct device_d *dev) +{ + return 0; +} #endif #endif /* __OF_H */ diff --git a/include/reset_source.h b/include/reset_source.h index 6734fbdee6..75e7ba8d40 100644 --- a/include/reset_source.h +++ b/include/reset_source.h @@ -22,6 +22,12 @@ enum reset_src_type { RESET_JTAG, /* JTAG reset */ }; +#ifdef CONFIG_RESET_SOURCE void set_reset_source(enum reset_src_type); +#else +static inline void set_reset_source(enum reset_src_type unused) +{ +} +#endif #endif /* __INCLUDE_RESET_SOURCE_H */ diff --git a/include/w1_mac_address.h b/include/w1_mac_address.h new file mode 100644 index 0000000000..89dd914095 --- /dev/null +++ b/include/w1_mac_address.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com> + * + * Under GPLv2 only + */ + +#ifndef __W1_MAC_ADDRESS_H__ +#define __W1_MAC_ADDRESS_H__ + +/** + * w1_local_mac_address_register - use the first 3 byte of the id of a 1-wire + * or 6 if no OUI provided device to provide an Ethernet address + * @ethid: ethernet device id + * @oui: Ethernet OUI (3 bytes) + * @w1_dev: 1-wire device name + * + * Generate a local Ethernet address (MAC) that is not multicast using a 1-wire id. + */ +static inline int w1_local_mac_address_register(int ethid, char * oui, char *w1_dev) +{ + char addr[6]; + const char *val; + u64 id; + int nb_oui = 0; + int i, shift; + char *tmp = NULL; + int ret = 0; + + if (oui) { + nb_oui = 3; + + for (i = 0; i < nb_oui; i++) + addr[i] = oui[i]; + } + + tmp = asprintf("%s.id", w1_dev); + if (!tmp) + return -ENOMEM; + + val = getenv(tmp); + if (!val) { + ret = -EINVAL; + goto err; + } + + id = simple_strtoull(val, NULL, 16); + if (!id) { + ret = -EINVAL; + goto err; + } + + for (i = nb_oui, shift = 40; i < 6; i++, shift -= 8) + addr[i] = (id >> shift) & 0xff; + + addr[0] &= 0xfe; /* clear multicast bit */ + addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ + + eth_register_ethaddr(ethid, addr); + +err: + free(tmp); + return ret; +} + +#endif /* __W1_MAC_ADDRESS_H__ */ diff --git a/lib/parameter.c b/lib/parameter.c index 152a5dd27b..c00b82438d 100644 --- a/lib/parameter.c +++ b/lib/parameter.c @@ -242,6 +242,7 @@ void dev_remove_parameters(struct device_d *dev) list_for_each_entry_safe(p, n, &dev->parameters, list) { p->set(dev, p, NULL); list_del(&p->list); + free(p->name); free(p); } } @@ -269,7 +269,8 @@ int eth_register(struct eth_device *edev) dev_add_param(dev, "netmask", eth_set_ipaddr, NULL, 0); dev_add_param(dev, "serverip", eth_set_ipaddr, NULL, 0); - edev->init(edev); + if (edev->init) + edev->init(edev); list_add_tail(&edev->list, &netdev_list); diff --git a/pbl/misc.c b/pbl/misc.c index 47e9ceabe3..a2cb44deac 100644 --- a/pbl/misc.c +++ b/pbl/misc.c @@ -4,6 +4,11 @@ #include <linux/string.h> #include <linux/ctype.h> +void __noreturn hang(void) +{ + while (1); +} + void __noreturn panic(const char *fmt, ...) { while(1); diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 383d73f66b..a95bbe4e74 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -241,7 +241,7 @@ endef # Built-in and composite module parts -pbl-%.o: %.c +pbl-%.o: %.c FORCE $(call cmd,force_checksrc) $(call if_changed_rule,pbl_cc_o_c) @@ -284,7 +284,7 @@ cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< quiet_cmd_pbl_as_o_S = PBLAS $@ cmd_pbl_as_o_S = $(CC) -D__PBL__ $(a_flags) $(PBL_CPPFLAGS) -c -o $@ $< -pbl-%.o: %.S +pbl-%.o: %.S FORCE $(call if_changed_dep,pbl_as_o_S) %.o: %.S FORCE diff --git a/scripts/mk-am35xx-spi-image.c b/scripts/mk-am35xx-spi-image.c index ec311fdd4d..74e79dbee1 100644 --- a/scripts/mk-am35xx-spi-image.c +++ b/scripts/mk-am35xx-spi-image.c @@ -95,12 +95,8 @@ int main(int argc, char *argv[]) perror("ftello"); exit(EXIT_FAILURE); } - if (pos % 4) { - printf("error: image size must be a multiple of 4 bytes\n"); - exit(EXIT_FAILURE); - } if (pos > 0x100000) { - printf("error: image should be smaller than 1 MiB\n"); + fprintf(stderr, "error: image should be smaller than 1 MiB\n"); exit(EXIT_FAILURE); } @@ -109,6 +105,8 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } + pos = (pos + 3) & ~3; + /* image size */ temp = htobe32((uint32_t)pos); fwrite(&temp, sizeof(uint32_t), 1, stdout); @@ -121,7 +119,7 @@ int main(int argc, char *argv[]) size = fread(&temp, 1, sizeof(uint32_t), input); if (!size) break; - if (size != 4) { + if (size < 4 && !feof(input)) { perror("fread"); exit(EXIT_FAILURE); } |