diff options
author | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2012-09-30 23:49:17 +0200 |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2012-09-30 23:49:17 +0200 |
commit | 1c27059a2f7158a9c9a8778535b030935d75179d (patch) | |
tree | bf577d5c9f0da21c5d57feed1091214e54c39dec | |
parent | 8f0732ac3dc3bdbbcada313dc4b4b38d5d2c376a (diff) | |
parent | 4668a086bb0a769b741e3a4ffab85f1c41c7cdb8 (diff) | |
download | u-boot-imx-1c27059a2f7158a9c9a8778535b030935d75179d.zip u-boot-imx-1c27059a2f7158a9c9a8778535b030935d75179d.tar.gz u-boot-imx-1c27059a2f7158a9c9a8778535b030935d75179d.tar.bz2 |
Merge remote-tracking branch 'u-boot/master'
613 files changed, 24783 insertions, 10881 deletions
@@ -75,10 +75,5 @@ cscope.* /ctags /etags -# OneNAND IPL files -/onenand_ipl/onenand-ipl* -/onenand_ipl/board/*/onenand* -/onenand_ipl/board/*/*.S - # spl ais files /spl/*.ais diff --git a/MAINTAINERS b/MAINTAINERS index 4aabcff..aa54fe1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -777,10 +777,6 @@ Nagendra T S <nagendra@mistralsolutions.com> am3517_crane ARM ARMV7 (AM35x SoC) -Kyungmin Park <kyungmin.park@samsung.com> - - apollon ARM1136EJS - Sandeep Paulraj <s-paulraj@ti.com> davinci_dm355evm ARM926EJS @@ -1112,6 +1108,7 @@ Wolfgang Wegner <w.wegner@astro-kom.de> Andreas Bießmann <andreas.devel@googlemail.com> grasshopper AT32AP7000 + atngw100mkii AT32AP7000 Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com> @@ -334,18 +334,27 @@ LIST_ppc=" \ LIST_SA="$(boards_by_cpu sa1100)" ######################################################################### +## ARM7 Systems +######################################################################### + +LIST_ARM7="$(boards_by_cpu arm720t)" + +######################################################################### ## ARM9 Systems ######################################################################### LIST_ARM9="$(boards_by_cpu arm920t) \ $(boards_by_cpu arm926ejs) \ $(boards_by_cpu arm925t) \ + $(boards_by_cpu arm946es) \ " ######################################################################### ## ARM11 Systems ######################################################################### -LIST_ARM11="$(boards_by_cpu arm1136)" +LIST_ARM11="$(boards_by_cpu arm1136) \ + $(boards_by_cpu arm1176) \ +" ######################################################################### ## ARMV7 Systems @@ -371,16 +380,7 @@ LIST_ixp="$(boards_by_cpu ixp)" ## ARM groups ######################################################################### -LIST_arm=" \ - ${LIST_SA} \ - ${LIST_ARM9} \ - ${LIST_ARM10} \ - ${LIST_ARM11} \ - ${LIST_ARMV7} \ - ${LIST_at91} \ - ${LIST_pxa} \ - ${LIST_ixp} \ -" +LIST_arm="$(boards_by_arch arm)" ######################################################################### ## MIPS Systems (default = big endian) @@ -388,6 +388,9 @@ LIST_arm=" \ LIST_mips4kc=" \ incaip \ + incaip_100MHz \ + incaip_133MHz \ + incaip_150MHz \ qemu_mips \ vct_platinum \ vct_platinum_small \ @@ -461,14 +464,7 @@ LIST_microblaze="$(boards_by_arch microblaze)" ## ColdFire Systems ######################################################################### -LIST_m68k="$(boards_by_arch m68k) - EB+MCF-EV123 \ - EB+MCF-EV123_internal \ - M52277EVB \ - M5235EVB \ - M54451EVB \ - M54455EVB \ -" +LIST_m68k="$(boards_by_arch m68k)" LIST_coldfire=${LIST_m68k} ######################################################################### @@ -22,9 +22,9 @@ # VERSION = 2012 -PATCHLEVEL = 07 +PATCHLEVEL = 10 SUBLEVEL = -EXTRAVERSION = +EXTRAVERSION = -rc1 ifneq "$(SUBLEVEL)" "" U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) else @@ -238,13 +238,19 @@ ifdef SOC LIBS-y += $(CPUDIR)/$(SOC)/lib$(SOC).o endif ifeq ($(CPU),ixp) -LIBS-y += arch/arm/cpu/ixp/npe/libnpe.o +LIBS-y += drivers/net/npe/libnpe.o endif LIBS-$(CONFIG_OF_EMBED) += dts/libdts.o LIBS-y += arch/$(ARCH)/lib/lib$(ARCH).o -LIBS-y += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \ - fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \ - fs/ubifs/libubifs.o fs/zfs/libzfs.o +LIBS-y += fs/cramfs/libcramfs.o \ + fs/ext4/libext4fs.o \ + fs/fat/libfat.o \ + fs/fdos/libfdos.o \ + fs/jffs2/libjffs2.o \ + fs/reiserfs/libreiserfs.o \ + fs/ubifs/libubifs.o \ + fs/yaffs2/libyaffs2.o \ + fs/zfs/libzfs.o LIBS-y += net/libnet.o LIBS-y += disk/libdisk.o LIBS-y += drivers/bios_emulator/libatibiosemu.o @@ -269,6 +275,7 @@ LIBS-y += drivers/pci/libpci.o LIBS-y += drivers/pcmcia/libpcmcia.o LIBS-y += drivers/power/libpower.o LIBS-y += drivers/spi/libspi.o +LIBS-y += drivers/dfu/libdfu.o ifeq ($(CPU),mpc83xx) LIBS-y += drivers/qe/libqe.o LIBS-y += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o @@ -374,7 +381,6 @@ ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map ALL-$(CONFIG_NAND_U_BOOT) += $(obj)u-boot-nand.bin ALL-$(CONFIG_ONENAND_U_BOOT) += $(obj)u-boot-onenand.bin -ONENAND_BIN ?= $(obj)onenand_ipl/onenand-ipl-2k.bin ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin ALL-$(CONFIG_OF_SEPARATE) += $(obj)u-boot.dtb $(obj)u-boot-dtb.bin @@ -432,6 +438,11 @@ $(obj)u-boot.kwb: $(obj)u-boot.bin $(obj)tools/mkimage -n $(CONFIG_SYS_KWD_CONFIG) -T kwbimage \ -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) -d $< $@ +$(obj)u-boot.pbl: $(obj)u-boot.bin + $(obj)tools/mkimage -n $(CONFIG_PBLRCW_CONFIG) \ + -R $(CONFIG_PBLPBI_CONFIG) -T pblimage \ + -d $< $@ + $(obj)u-boot.sha1: $(obj)u-boot.bin $(obj)tools/ubsha1 $(obj)u-boot.bin @@ -446,7 +457,7 @@ $(obj)u-boot.ubl: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin rm $(obj)u-boot-ubl.bin rm $(obj)spl/u-boot-spl-pad.bin -$(obj)u-boot.ais: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin +$(obj)u-boot.ais: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img $(obj)tools/mkimage -s -n $(if $(CONFIG_AIS_CONFIG_FILE),$(CONFIG_AIS_CONFIG_FILE),"/dev/null") \ -T aisimage \ -e $(CONFIG_SPL_TEXT_BASE) \ @@ -455,7 +466,7 @@ $(obj)u-boot.ais: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin $(OBJCOPY) ${OBJCFLAGS} -I binary \ --pad-to=$(CONFIG_SPL_MAX_SIZE) -O binary \ $(obj)spl/u-boot-spl.ais $(obj)spl/u-boot-spl-pad.ais - cat $(obj)spl/u-boot-spl-pad.ais $(obj)u-boot.bin > \ + cat $(obj)spl/u-boot-spl-pad.ais $(obj)u-boot.img > \ $(obj)u-boot.ais # Specify the target for use in elftosb call @@ -513,7 +524,7 @@ $(obj)u-boot: depend \ $(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds $(GEN_UBOOT) ifeq ($(CONFIG_KALLSYMS),y) - smap=`$(call SYSTEM_MAP,u-boot) | \ + smap=`$(call SYSTEM_MAP,$(obj)u-boot) | \ awk '$$2 ~ /[tTwW]/ {printf $$1 $$3 "\\\\000"}'` ; \ $(CC) $(CFLAGS) -DSYSTEM_MAP="\"$${smap}\"" \ -c common/system_map.c -o $(obj)common/system_map.o @@ -546,12 +557,6 @@ nand_spl: $(TIMESTAMP_FILE) $(VERSION_FILE) depend $(obj)u-boot-nand.bin: nand_spl $(obj)u-boot.bin cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin -onenand_ipl: $(TIMESTAMP_FILE) $(VERSION_FILE) $(obj)include/autoconf.mk - $(MAKE) -C onenand_ipl/board/$(BOARDDIR) all - -$(obj)u-boot-onenand.bin: onenand_ipl $(obj)u-boot.bin - cat $(ONENAND_BIN) $(obj)u-boot.bin > $(obj)u-boot-onenand.bin - $(obj)spl/u-boot-spl.bin: $(SUBDIR_TOOLS) depend $(MAKE) -C spl all @@ -786,12 +791,6 @@ clean: @rm -f $(obj)lib/asm-offsets.s @rm -f $(obj)include/generated/asm-offsets.h @rm -f $(obj)$(CPUDIR)/$(SOC)/asm-offsets.s - @rm -f $(obj)nand_spl/{u-boot.lds,u-boot-nand_spl.lds,u-boot-spl,u-boot-spl.map,System.map} - @rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl.map} - @rm -f $(ONENAND_BIN) - @rm -f $(obj)onenand_ipl/u-boot.lds - @rm -f $(obj)spl/{u-boot-spl,u-boot-spl.bin,u-boot-spl.lds,u-boot-spl.map} - @rm -f $(obj)MLO @rm -f $(TIMESTAMP_FILE) $(VERSION_FILE) @find $(OBJTREE) -type f \ \( -name 'core' -o -name '*.bak' -o -name '*~' -o -name '*.su' \ @@ -810,19 +809,22 @@ clobber: tidy $(obj)cscope.* $(obj)*.*~ @rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL-y) @rm -f $(obj)u-boot.kwb + @rm -f $(obj)u-boot.pbl @rm -f $(obj)u-boot.imx @rm -f $(obj)u-boot.ubl @rm -f $(obj)u-boot.ais @rm -f $(obj)u-boot.dtb @rm -f $(obj)u-boot.sb @rm -f $(obj)u-boot.spr + @rm -f $(obj)nand_spl/{u-boot.lds,u-boot-nand_spl.lds,u-boot-spl,u-boot-spl.map,System.map} + @rm -f $(obj)spl/{u-boot-spl,u-boot-spl.bin,u-boot-spl.lds,u-boot-spl.map} + @rm -f $(obj)MLO @rm -f $(obj)tools/xway-swap-bytes @rm -f $(obj)arch/powerpc/cpu/mpc824x/bedbug_603e.c @rm -f $(obj)arch/powerpc/cpu/mpc83xx/ddr-gen?.c @rm -fr $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm @rm -fr $(obj)include/generated @[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -name "*" -type l -print | xargs rm -f - @[ ! -d $(obj)onenand_ipl ] || find $(obj)onenand_ipl -name "*" -type l -print | xargs rm -f @rm -f $(obj)dts/*.tmp @rm -f $(obj)spl/u-boot-spl{,-pad}.ais @@ -383,6 +383,31 @@ The following options need to be configured: symbol should be set to the TLB1 entry to be used for this purpose. + CONFIG_SYS_FSL_ERRATUM_A004510 + + Enables a workaround for erratum A004510. If set, + then CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV and + CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY must be set. + + CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV + CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 (optional) + + Defines one or two SoC revisions (low 8 bits of SVR) + for which the A004510 workaround should be applied. + + The rest of SVR is either not relevant to the decision + of whether the erratum is present (e.g. p2040 versus + p2041) or is implied by the build target, which controls + whether CONFIG_SYS_FSL_ERRATUM_A004510 is set. + + See Freescale App Note 4493 for more information about + this erratum. + + CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY + + This is the value to write into CCSR offset 0x18600 + according to the A004510 workaround. + - Generic CPU options: CONFIG_SYS_BIG_ENDIAN, CONFIG_SYS_LITTLE_ENDIAN @@ -907,7 +932,8 @@ The following options need to be configured: If this variable is defined, an environment variable named "ver" is created by U-Boot showing the U-Boot version as printed by the "version" command. - This variable is readonly. + Any change to this variable will be reverted at the + next reset. - Real-Time Clock: @@ -950,13 +976,20 @@ The following options need to be configured: commands like bootm or iminfo. This option is automatically enabled when you select CONFIG_CMD_DATE . -- Partition Support: - CONFIG_MAC_PARTITION and/or CONFIG_DOS_PARTITION - and/or CONFIG_ISO_PARTITION and/or CONFIG_EFI_PARTITION +- Partition Labels (disklabels) Supported: + Zero or more of the following: + CONFIG_MAC_PARTITION Apple's MacOS partition table. + CONFIG_DOS_PARTITION MS Dos partition table, traditional on the + Intel architecture, USB sticks, etc. + CONFIG_ISO_PARTITION ISO partition table, used on CDROM etc. + CONFIG_EFI_PARTITION GPT partition table, common when EFI is the + bootloader. Note 2TB partition limit; see + disk/part_efi.c + CONFIG_MTD_PARTITIONS Memory Technology Device partition table. If IDE or SCSI support is enabled (CONFIG_CMD_IDE or CONFIG_CMD_SCSI) you must configure support for at - least one partition type as well. + least one non-MTD partition type as well. - IDE Reset method: CONFIG_IDE_RESET_ROUTINE - this is defined in several @@ -1450,6 +1483,12 @@ The following options need to be configured: can be displayed via the splashscreen support or the bmp command. +- Do compresssing for memory range: + CONFIG_CMD_ZIP + + If this option is set, it would use zlib deflate method + to compress the specified memory at its best effort. + - Compression support: CONFIG_BZIP2 @@ -2564,6 +2603,15 @@ FIT uImage format: CONFIG_SYS_SPL_MALLOC_SIZE The size of the malloc pool used in SPL. + CONFIG_SPL_FRAMEWORK + Enable the SPL framework under common/. This framework + supports MMC, NAND and YMODEM loading of U-Boot and NAND + NAND loading of the Linux Kernel. + + CONFIG_SPL_DISPLAY_PRINT + For ARM, enable an optional function to print more information + about the running system. + CONFIG_SPL_LIBCOMMON_SUPPORT Support for common/libcommon.o in SPL binary @@ -2627,6 +2675,9 @@ FIT uImage format: CONFIG_SPL_SPI_SUPPORT Support for drivers/spi/libspi.o in SPL binary + CONFIG_SPL_RAM_DEVICE + Support for running image already present in ram, in SPL binary + CONFIG_SPL_LIBGENERIC_SUPPORT Support for lib/libgeneric.o in SPL binary @@ -3092,12 +3143,12 @@ to save the current settings. These two #defines specify the address and size of the environment area within the remote memory space. The local device can get the environment from remote memory - space by SRIO or other links. + space by SRIO or PCIE links. BE CAREFUL! For some special cases, the local device can not use "saveenv" command. For example, the local device will get the -environment stored in a remote NOR flash by SRIO link, but it can -not erase, write this NOR flash by SRIO interface. +environment stored in a remote NOR flash by SRIO or PCIE link, +but it can not erase, write this NOR flash by SRIO or PCIE interface. - CONFIG_ENV_IS_IN_NAND: @@ -3377,6 +3428,13 @@ Low Level (hardware related) configuration options: Disable PCI-Express on systems where it is supported but not required. +- CONFIG_PCI_ENUM_ONLY + Only scan through and get the devices on the busses. + Don't do any setup work, presumably because someone or + something has already done it, and we don't need to do it + a second time. Useful for platforms that are pre-booted + by coreboot or similar. + - CONFIG_SYS_SRIO: Chip has SRIO or not @@ -3538,9 +3596,9 @@ within that device. - CONFIG_SYS_QE_FMAN_FW_IN_REMOTE Specifies that QE/FMAN firmware is located in the remote (master) memory space. CONFIG_SYS_FMAN_FW_ADDR is a virtual address which - can be mapped from slave TLB->slave LAW->slave SRIO outbound window - ->master inbound window->master LAW->the ucode address in master's - NOR flash. + can be mapped from slave TLB->slave LAW->slave SRIO or PCIE outbound + window->master inbound window->master LAW->the ucode address in + master's memory space. Building the Software: ====================== diff --git a/arch/arm/cpu/arm1176/bcm2835/Makefile b/arch/arm/cpu/arm1176/bcm2835/Makefile index 4ea6d6b..95da6a8 100644 --- a/arch/arm/cpu/arm1176/bcm2835/Makefile +++ b/arch/arm/cpu/arm1176/bcm2835/Makefile @@ -17,7 +17,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o SOBJS := lowlevel_init.o -COBJS := reset.o timer.o +COBJS := init.o reset.o timer.o SRCS := $(SOBJS:.o=.c) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/arch/arm/cpu/arm1176/bcm2835/init.c b/arch/arm/cpu/arm1176/bcm2835/init.c new file mode 100644 index 0000000..e90d3bb --- /dev/null +++ b/arch/arm/cpu/arm1176/bcm2835/init.c @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2012 Stephen Warren + * + * 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> + +int arch_cpu_init(void) +{ + icache_enable(); + + return 0; +} diff --git a/arch/arm/cpu/arm1176/cpu.c b/arch/arm/cpu/arm1176/cpu.c index 532a90b..c0fd114 100644 --- a/arch/arm/cpu/arm1176/cpu.c +++ b/arch/arm/cpu/arm1176/cpu.c @@ -65,10 +65,3 @@ static void cache_flush (void) /* mem barrier to sync things */ asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0)); } - -int arch_cpu_init(void) -{ - icache_enable(); - - return 0; -} diff --git a/arch/arm/cpu/arm926ejs/davinci/Makefile b/arch/arm/cpu/arm926ejs/davinci/Makefile index c91928e..dec7bfb 100644 --- a/arch/arm/cpu/arm926ejs/davinci/Makefile +++ b/arch/arm/cpu/arm926ejs/davinci/Makefile @@ -37,7 +37,7 @@ COBJS-$(CONFIG_SOC_DA850) += da850_pinmux.o COBJS-$(CONFIG_DRIVER_TI_EMAC) += lxt972.o dp83848.o et1011c.o ksz8873.o ifdef CONFIG_SPL_BUILD -COBJS-y += spl.o +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o COBJS-$(CONFIG_SOC_DM365) += dm365_lowlevel.o COBJS-$(CONFIG_SOC_DA8XX) += da850_lowlevel.o endif diff --git a/arch/arm/cpu/arm926ejs/davinci/config.mk b/arch/arm/cpu/arm926ejs/davinci/config.mk new file mode 100644 index 0000000..7452315 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/config.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2012, Texas Instruments, Incorporated - http://www.ti.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 "as is" WITHOUT ANY WARRANTY of any +# kind, whether express or implied; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +ifndef CONFIG_SPL_BUILD +ALL-$(CONFIG_SPL_FRAMEWORK) += $(obj)u-boot.ais +endif diff --git a/arch/arm/cpu/arm926ejs/davinci/spl.c b/arch/arm/cpu/arm926ejs/davinci/spl.c index 03c85c8..714fa92 100644 --- a/arch/arm/cpu/arm926ejs/davinci/spl.c +++ b/arch/arm/cpu/arm926ejs/davinci/spl.c @@ -21,6 +21,8 @@ * MA 02111-1307 USA */ #include <common.h> +#include <config.h> +#include <spl.h> #include <asm/u-boot.h> #include <asm/utils.h> #include <nand.h> @@ -30,15 +32,9 @@ #include <spi_flash.h> #include <mmc.h> -#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT - DECLARE_GLOBAL_DATA_PTR; -/* Define global data structure pointer to it*/ -static gd_t gdata __attribute__ ((section(".data"))); -static bd_t bdata __attribute__ ((section(".data"))); - -#else +#ifndef CONFIG_SPL_LIBCOMMON_SUPPORT void puts(const char *str) { while (*str) @@ -52,53 +48,49 @@ void putc(char c) NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), c); } - #endif /* CONFIG_SPL_LIBCOMMON_SUPPORT */ -inline void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - for (;;) - ; -} - void board_init_f(ulong dummy) { + /* First, setup our stack pointer. */ + asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK)); + + /* Second, perform our low-level init. */ #ifdef CONFIG_SOC_DM365 dm36x_lowlevel_init(0); #endif #ifdef CONFIG_SOC_DA8XX arch_cpu_init(); #endif - relocate_code(CONFIG_SPL_STACK, NULL, CONFIG_SPL_TEXT_BASE); -} -void board_init_r(gd_t *id, ulong dummy) -{ -#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT - mem_malloc_init(CONFIG_SYS_TEXT_BASE - CONFIG_SYS_MALLOC_LEN, - CONFIG_SYS_MALLOC_LEN); + /* Third, we clear the BSS. */ + memset(__bss_start, 0, __bss_end__ - __bss_start); + /* Finally, setup gd and move to the next step. */ gd = &gdata; - gd->bd = &bdata; - gd->flags |= GD_FLG_RELOC; - gd->baudrate = CONFIG_BAUDRATE; - serial_init(); /* serial communications setup */ - gd->have_console = 1; + board_init_r(NULL, 0); +} -#endif +void spl_board_init(void) +{ + preloader_console_init(); +} -#ifdef CONFIG_SPL_NAND_LOAD - nand_init(); - puts("Nand boot...\n"); - nand_boot(); -#endif -#ifdef CONFIG_SPL_SPI_LOAD - puts("SPI boot...\n"); - spi_boot(); -#endif -#ifdef CONFIG_SPL_MMC_LOAD - puts("MMC boot...\n"); - spl_mmc_load(); +u32 spl_boot_mode(void) +{ + return MMCSD_MODE_RAW; +} + +u32 spl_boot_device(void) +{ +#ifdef CONFIG_SPL_NAND_SIMPLE + return BOOT_DEVICE_NAND; +#elif defined(CONFIG_SPL_SPI_LOAD) + return BOOT_DEVICE_SPI; +#elif defined(CONFIG_SPL_MMC_LOAD) + return BOOT_DEVICE_MMC1; +#else + puts("Unknown boot device\n"); + hang(); #endif } diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S index 6f05f1a..521d462 100644 --- a/arch/arm/cpu/arm926ejs/start.S +++ b/arch/arm/cpu/arm926ejs/start.S @@ -215,6 +215,7 @@ call_board_init_f: /*------------------------------------------------------------------------------*/ +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_NAND_SPL) /* * void relocate_code (addr_sp, gd, addr_moni) * @@ -344,6 +345,7 @@ _rel_dyn_end_ofs: .word __rel_dyn_end - _start _dynsym_start_ofs: .word __dynsym_start - _start +#endif /* ************************************************************************* diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index ecc2671..978b184 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -18,6 +18,7 @@ #include <common.h> #include <errno.h> +#include <spl.h> #include <asm/arch/cpu.h> #include <asm/arch/hardware.h> #include <asm/arch/omap.h> @@ -27,7 +28,6 @@ #include <asm/arch/mmc_host_def.h> #include <asm/arch/sys_proto.h> #include <asm/io.h> -#include <asm/omap_common.h> #include <asm/emif.h> #include <asm/gpio.h> #include <i2c.h> @@ -166,6 +166,8 @@ void s_init(void) regVal |= UART_SMART_IDLE_EN; writel(regVal, &uart_base->uartsyscfg); + gd = &gdata; + preloader_console_init(); /* Initalize the board header */ diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index d37b22d..1f2fa02 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -42,19 +42,6 @@ COBJS += boot-common.o SOBJS += lowlevel_init.o endif -ifdef CONFIG_SPL_BUILD -COBJS += spl.o -ifdef CONFIG_SPL_NAND_SUPPORT -COBJS += spl_nand.o -endif -ifdef CONFIG_SPL_MMC_SUPPORT -COBJS += spl_mmc.o -endif -ifdef CONFIG_SPL_YMODEM_SUPPORT -COBJS += spl_ymodem.o -endif -endif - ifndef CONFIG_SPL_BUILD ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) COBJS += mem-common.o diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index f211f76..0f19141 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -17,8 +17,10 @@ */ #include <common.h> +#include <spl.h> #include <asm/omap_common.h> #include <asm/arch/omap.h> +#include <asm/arch/mmc_host_def.h> /* * This is used to verify if the configuration header @@ -37,13 +39,34 @@ struct omap_boot_parameters boot_params __attribute__ ((section(".data"))); */ u32 omap_bootmode = MMCSD_MODE_FAT; -u32 omap_boot_device(void) +u32 spl_boot_device(void) { return (u32) (boot_params.omap_bootdevice); } -u32 omap_boot_mode(void) +u32 spl_boot_mode(void) { return omap_bootmode; } + +void spl_board_init(void) +{ +#ifdef CONFIG_SPL_NAND_SUPPORT + gpmc_init(); +#endif +} + +int board_mmc_init(bd_t *bis) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + omap_mmc_init(0, 0, 0); + break; + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC2_2: + omap_mmc_init(1, 0, 0); + break; + } + return 0; +} #endif diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index 459ebb5..9ef10bd 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -28,10 +28,10 @@ * MA 02111-1307 USA */ #include <common.h> +#include <spl.h> #include <asm/arch/sys_proto.h> #include <asm/sizes.h> #include <asm/emif.h> -#include <asm/omap_common.h> DECLARE_GLOBAL_DATA_PTR; @@ -92,6 +92,11 @@ static void init_boot_params(void) { boot_params_ptr = (u32 *) &boot_params; } + +void spl_display_print(void) +{ + omap_rev_string(); +} #endif /* @@ -119,6 +124,9 @@ void s_init(void) set_mux_conf_regs(); #ifdef CONFIG_SPL_BUILD setup_clocks_for_console(); + + gd = &gdata; + preloader_console_init(); do_io_settings(); #endif diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S index 1ece073..9766563 100644 --- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S @@ -52,18 +52,18 @@ ENTRY(save_boot_params) ldr r1, =boot_params str r0, [r1] #ifdef CONFIG_SPL_BUILD - /* Store the boot device in omap_boot_device */ + /* Store the boot device in spl_boot_device */ ldrb r2, [r0, #BOOT_DEVICE_OFFSET] @ r1 <- value of boot device and r2, #BOOT_DEVICE_MASK ldr r3, =boot_params - strb r2, [r3, #BOOT_DEVICE_OFFSET] @ omap_boot_device <- r1 + strb r2, [r3, #BOOT_DEVICE_OFFSET] @ spl_boot_device <- r1 /* boot mode is passed only for devices that can raw/fat mode */ cmp r2, #2 blt 2f cmp r2, #7 bgt 2f - /* Store the boot mode (raw/FAT) in omap_boot_mode */ + /* Store the boot mode (raw/FAT) in omap_bootmode */ ldr r2, [r0, #DEV_DESC_PTR_OFFSET] @ get the device descriptor ptr ldr r2, [r2, #DEV_DATA_PTR_OFFSET] @ get the pDeviceData ptr ldr r2, [r2, #BOOT_MODE_OFFSET] @ get the boot mode diff --git a/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds b/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds index 8867e06..1d8efb2 100644 --- a/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds +++ b/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds @@ -37,9 +37,9 @@ SECTIONS { .text : { - __start = .; - arch/arm/cpu/armv7/start.o (.text) - *(.text*) + __start = .; + arch/arm/cpu/armv7/start.o (.text) + *(.text*) } >.sram . = ALIGN(4); diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index f2e52e9..9cee1d9 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -33,6 +33,7 @@ * MA 02111-1307 USA */ #include <common.h> +#include <spl.h> #include <asm/io.h> #include <asm/arch/sys_proto.h> #include <asm/arch/mem.h> @@ -40,9 +41,12 @@ #include <asm/armv7.h> #include <asm/arch/gpio.h> #include <asm/omap_common.h> +#include <asm/arch/mmc_host_def.h> #include <i2c.h> #include <linux/compiler.h> +DECLARE_GLOBAL_DATA_PTR; + /* Declarations */ extern omap3_sysinfo sysinfo; static void omap3_setup_aux_cr(void); @@ -69,30 +73,44 @@ const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx; u32 omap3_boot_device = BOOT_DEVICE_NAND; /* auto boot mode detection is not possible for OMAP3 - hard code */ -u32 omap_boot_mode(void) +u32 spl_boot_mode(void) { - switch (omap_boot_device()) { + switch (spl_boot_device()) { case BOOT_DEVICE_MMC2: return MMCSD_MODE_RAW; case BOOT_DEVICE_MMC1: return MMCSD_MODE_FAT; break; - case BOOT_DEVICE_NAND: - return NAND_MODE_HW_ECC; - break; default: puts("spl: ERROR: unknown device - can't select boot mode\n"); hang(); } } -u32 omap_boot_device(void) +u32 spl_boot_device(void) { return omap3_boot_device; } +int board_mmc_init(bd_t *bis) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + omap_mmc_init(0, 0, 0); + break; + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC2_2: + omap_mmc_init(1, 0, 0); + break; + } + return 0; +} + void spl_board_init(void) { +#ifdef CONFIG_SPL_NAND_SUPPORT + gpmc_init(); +#endif #ifdef CONFIG_SPL_I2C_SUPPORT i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); #endif @@ -236,6 +254,8 @@ void s_init(void) #endif #ifdef CONFIG_SPL_BUILD + gd = &gdata; + preloader_console_init(); timer_init(); diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 32658eb..f26308d 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -164,6 +164,7 @@ call_board_init_f: /*------------------------------------------------------------------------------*/ +#ifndef CONFIG_SPL_BUILD /* * void relocate_code (addr_sp, gd, addr_moni) * @@ -194,7 +195,6 @@ copy_loop: cmp r0, r2 /* until source end address [r2] */ blo copy_loop -#ifndef CONFIG_SPL_BUILD /* * fix .rel.dyn relocations */ @@ -241,20 +241,12 @@ _rel_dyn_end_ofs: _dynsym_start_ofs: .word __dynsym_start - _start -#endif /* #ifndef CONFIG_SPL_BUILD */ - clear_bss: -#ifdef CONFIG_SPL_BUILD - /* No relocation for SPL */ - ldr r0, =__bss_start - ldr r1, =__bss_end__ -#else ldr r0, _bss_start_ofs ldr r1, _bss_end_ofs mov r4, r6 /* reloc addr */ add r0, r0, r4 add r1, r1, r4 -#endif mov r2, #0x00000000 /* clear */ clbss_l:cmp r0, r1 /* clear loop... */ @@ -281,12 +273,10 @@ jump_2_ram: * Move vector table */ #if !defined(CONFIG_TEGRA20) -#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) /* Set vector address in CP15 VBAR register */ ldr r0, =_start add r0, r0, r9 mcr p15, 0, r0, c12, c0, 0 @Set VBAR -#endif #endif /* !Tegra20 */ ldr r0, _board_init_r_ofs @@ -302,6 +292,7 @@ jump_2_ram: _board_init_r_ofs: .word board_init_r - _start ENDPROC(relocate_code) +#endif /************************************************************************* * diff --git a/arch/arm/include/asm/arch-am33xx/spl.h b/arch/arm/include/asm/arch-am33xx/spl.h new file mode 100644 index 0000000..70f521d --- /dev/null +++ b/arch/arm/include/asm/arch-am33xx/spl.h @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NAND 5 +#define BOOT_DEVICE_MMC1 8 +#define BOOT_DEVICE_MMC2 9 /* eMMC or daughter card */ +#define BOOT_DEVICE_UART 65 +#define BOOT_DEVICE_MMC2_2 0xFF +#endif diff --git a/onenand_ipl/board/apollon/u-boot.onenand.lds b/arch/arm/include/asm/arch-davinci/spl.h index 721d2f5..fb01db0 100644 --- a/onenand_ipl/board/apollon/u-boot.onenand.lds +++ b/arch/arm/include/asm/arch-davinci/spl.h @@ -1,8 +1,6 @@ /* - * (C) Copyright 2005-2008 Samsung Electronics - * Kyungmin Park <kyungmin.park@samsung.com> - * - * Derived from X-loader + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> * * See file CREDITS for list of people who contributed to this * project. @@ -14,7 +12,7 @@ * * 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 + * 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 @@ -22,32 +20,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } +#define BOOT_DEVICE_NAND 1 +#define BOOT_DEVICE_SPI 2 +#define BOOT_DEVICE_MMC1 3 +#define BOOT_DEVICE_MMC2 4 /* dummy */ +#define BOOT_DEVICE_MMC2_2 5 /* dummy */ - . = ALIGN(4); - __bss_start = .; - .bss : { *(.bss) . = ALIGN(4); } - __bss_end__ = .; -} +#endif diff --git a/arch/arm/include/asm/arch-exynos/mmc.h b/arch/arm/include/asm/arch-exynos/mmc.h index 0f701c9..afdfcf0 100644 --- a/arch/arm/include/asm/arch-exynos/mmc.h +++ b/arch/arm/include/asm/arch-exynos/mmc.h @@ -64,11 +64,11 @@ #define SDHCI_CTRL4_DRIVE_MASK(_x) ((_x) << 16) #define SDHCI_CTRL4_DRIVE_SHIFT (16) -int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks); +int s5p_sdhci_init(u32 regbase, int index, int bus_width); static inline unsigned int s5p_mmc_init(int index, int bus_width) { unsigned int base = samsung_get_base_mmc() + (0x10000 * index); - return s5p_sdhci_init(base, 52000000, 400000, index); + return s5p_sdhci_init(base, index, bus_width); } #endif diff --git a/arch/arm/include/asm/arch-omap24xx/omap2420.h b/arch/arm/include/asm/arch-omap24xx/omap2420.h index 6032419..d8d5647 100644 --- a/arch/arm/include/asm/arch-omap24xx/omap2420.h +++ b/arch/arm/include/asm/arch-omap24xx/omap2420.h @@ -228,16 +228,6 @@ #define LAN_RESET_REGISTER (H4_CS1_BASE+0x1c) #endif /* endif CONFIG_2420H4 */ -#if defined(CONFIG_APOLLON) -#define APOLLON_CS0_BASE 0x00000000 /* OneNAND */ -#define APOLLON_CS1_BASE 0x08000000 /* ethernet */ -#define APOLLON_CS2_BASE 0x10000000 /* OneNAND */ -#define APOLLON_CS3_BASE 0x18000000 /* NOR */ - -#define ETH_CONTROL_REG (APOLLON_CS1_BASE + 0x30b) -#define LAN_RESET_REGISTER (APOLLON_CS1_BASE + 0x1c) -#endif /* endif CONFIG_APOLLON */ - /* Common */ #define LOW_LEVEL_SRAM_STACK 0x4020FFFC diff --git a/arch/arm/include/asm/arch-omap3/spl.h b/arch/arm/include/asm/arch-omap3/spl.h new file mode 100644 index 0000000..404e16a --- /dev/null +++ b/arch/arm/include/asm/arch-omap3/spl.h @@ -0,0 +1,34 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NONE 0 +#define BOOT_DEVICE_XIP 1 +#define BOOT_DEVICE_NAND 2 +#define BOOT_DEVICE_ONE_NAND 3 +#define BOOT_DEVICE_MMC2 5 /*emmc*/ +#define BOOT_DEVICE_MMC1 6 +#define BOOT_DEVICE_XIPWAIT 7 +#define BOOT_DEVICE_MMC2_2 0xFF +#endif diff --git a/arch/arm/include/asm/arch-omap4/cpu.h b/arch/arm/include/asm/arch-omap4/cpu.h index a8c4c60..3a0bfbf 100644 --- a/arch/arm/include/asm/arch-omap4/cpu.h +++ b/arch/arm/include/asm/arch-omap4/cpu.h @@ -138,6 +138,7 @@ struct watchdog { #define I2C_BASE1 (OMAP44XX_L4_PER_BASE + 0x70000) #define I2C_BASE2 (OMAP44XX_L4_PER_BASE + 0x72000) #define I2C_BASE3 (OMAP44XX_L4_PER_BASE + 0x60000) +#define I2C_BASE4 (OMAP44XX_L4_PER_BASE + 0x350000) /* MUSB base */ #define MUSB_BASE (OMAP44XX_L4_CORE_BASE + 0xAB000) diff --git a/arch/arm/include/asm/arch-omap4/i2c.h b/arch/arm/include/asm/arch-omap4/i2c.h index a91b4c2..02ee2f8 100644 --- a/arch/arm/include/asm/arch-omap4/i2c.h +++ b/arch/arm/include/asm/arch-omap4/i2c.h @@ -23,7 +23,7 @@ #ifndef _OMAP4_I2C_H_ #define _OMAP4_I2C_H_ -#define I2C_BUS_MAX 3 +#define I2C_BUS_MAX 4 #define I2C_DEFAULT_BASE I2C_BASE1 struct i2c { diff --git a/include/configs/P3060QDS.h b/arch/arm/include/asm/arch-omap4/spl.h index 8006547..cec84dc 100644 --- a/include/configs/P3060QDS.h +++ b/arch/arm/include/asm/arch-omap4/spl.h @@ -1,5 +1,6 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> * * See file CREDITS for list of people who contributed to this * project. @@ -19,30 +20,16 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ -/* - * P3060 QDS board configuration file - */ -#define CONFIG_P3060QDS -#define CONFIG_PHYS_64BIT -#define CONFIG_PPC_P3060 -#define CONFIG_FSL_QIXIS - -#define CONFIG_NAND_FSL_ELBC - -#define CONFIG_ICS307_REFCLK_HZ 25000000 /* ICS307 ref clk freq */ - -#define CONFIG_SPI_FLASH_ATMEL -#define CONFIG_SPI_FLASH_EON -#define CONFIG_SPI_FLASH_SST - -#include "corenet_ds.h" - -#define SGMII_CARD_PORT1_PHY_ADDR 0x1C -#define SGMII_CARD_PORT2_PHY_ADDR 0x1D -#define SGMII_CARD_PORT3_PHY_ADDR 0x1E -#define SGMII_CARD_PORT4_PHY_ADDR 0x1F +#define BOOT_DEVICE_NONE 0 +#define BOOT_DEVICE_XIP 1 +#define BOOT_DEVICE_XIPWAIT 2 +#define BOOT_DEVICE_NAND 3 +#define BOOT_DEVICE_ONE_NAND 4 +#define BOOT_DEVICE_MMC1 5 +#define BOOT_DEVICE_MMC2 6 +#define BOOT_DEVICE_MMC2_2 0xFF -/* There is a PCA9547 8-channel I2C-bus multiplexer on P3060QDS board */ -#define CONFIG_I2C_MUX -#define CONFIG_I2C_MULTI_BUS +#endif diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h index d633573..b48f81d 100644 --- a/arch/arm/include/asm/arch-omap4/sys_proto.h +++ b/arch/arm/include/asm/arch-omap4/sys_proto.h @@ -42,7 +42,6 @@ void sr32(void *, u32, u32, u32); u32 wait_on_value(u32, u32, void *, u32); void sdelay(unsigned long); void set_pl310_ctrl_reg(u32 val); -void omap_rev_string(void); void setup_clocks_for_console(void); void prcm_init(void); void bypass_dpll(u32 *const base); diff --git a/arch/arm/include/asm/arch-omap5/spl.h b/arch/arm/include/asm/arch-omap5/spl.h new file mode 100644 index 0000000..d125c61 --- /dev/null +++ b/arch/arm/include/asm/arch-omap5/spl.h @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NONE 0 +#define BOOT_DEVICE_XIP 1 +#define BOOT_DEVICE_XIPWAIT 2 +#define BOOT_DEVICE_NAND 3 +#define BOOT_DEVICE_ONE_NAND 4 +#define BOOT_DEVICE_MMC1 5 +#define BOOT_DEVICE_MMC2 6 +#define BOOT_DEVICE_MMC2_2 7 + +#endif diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h index 74feb90..72e9df7 100644 --- a/arch/arm/include/asm/arch-omap5/sys_proto.h +++ b/arch/arm/include/asm/arch-omap5/sys_proto.h @@ -42,7 +42,6 @@ void set_muxconf_regs_non_essential(void); void sr32(void *, u32, u32, u32); u32 wait_on_value(u32, u32, void *, u32); void sdelay(unsigned long); -void omap_rev_string(void); void setup_clocks_for_console(void); void prcm_init(void); void bypass_dpll(u32 *const base); diff --git a/arch/arm/include/asm/arch-pxa/regs-usb.h b/arch/arm/include/asm/arch-pxa/regs-usb.h new file mode 100644 index 0000000..dda7954 --- /dev/null +++ b/arch/arm/include/asm/arch-pxa/regs-usb.h @@ -0,0 +1,159 @@ +/* + * PXA25x UDC definitions + * + * Copyright (C) 2012 Łukasz Dałek <luk0104@gmail.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __REGS_USB_H__ +#define __REGS_USB_H__ + +struct pxa25x_udc_regs { + /* UDC Control Register */ + uint32_t udccr; /* 0x000 */ + uint32_t reserved1; + + /* UDC Control Function Register */ + uint32_t udccfr; /* 0x008 */ + uint32_t reserved2; + + /* UDC Endpoint Control/Status Registers */ + uint32_t udccs[16]; /* 0x010 - 0x04c */ + + /* UDC Interrupt Control/Status Registers */ + uint32_t uicr0; /* 0x050 */ + uint32_t uicr1; /* 0x054 */ + uint32_t usir0; /* 0x058 */ + uint32_t usir1; /* 0x05c */ + + /* UDC Frame Number/Byte Count Registers */ + uint32_t ufnrh; /* 0x060 */ + uint32_t ufnrl; /* 0x064 */ + uint32_t ubcr2; /* 0x068 */ + uint32_t ubcr4; /* 0x06c */ + uint32_t ubcr7; /* 0x070 */ + uint32_t ubcr9; /* 0x074 */ + uint32_t ubcr12; /* 0x078 */ + uint32_t ubcr14; /* 0x07c */ + + /* UDC Endpoint Data Registers */ + uint32_t uddr0; /* 0x080 */ + uint32_t reserved3[7]; + uint32_t uddr5; /* 0x0a0 */ + uint32_t reserved4[7]; + uint32_t uddr10; /* 0x0c0 */ + uint32_t reserved5[7]; + uint32_t uddr15; /* 0x0e0 */ + uint32_t reserved6[7]; + uint32_t uddr1; /* 0x100 */ + uint32_t reserved7[31]; + uint32_t uddr2; /* 0x180 */ + uint32_t reserved8[31]; + uint32_t uddr3; /* 0x200 */ + uint32_t reserved9[127]; + uint32_t uddr4; /* 0x400 */ + uint32_t reserved10[127]; + uint32_t uddr6; /* 0x600 */ + uint32_t reserved11[31]; + uint32_t uddr7; /* 0x680 */ + uint32_t reserved12[31]; + uint32_t uddr8; /* 0x700 */ + uint32_t reserved13[127]; + uint32_t uddr9; /* 0x900 */ + uint32_t reserved14[127]; + uint32_t uddr11; /* 0xb00 */ + uint32_t reserved15[31]; + uint32_t uddr12; /* 0xb80 */ + uint32_t reserved16[31]; + uint32_t uddr13; /* 0xc00 */ + uint32_t reserved17[127]; + uint32_t uddr14; /* 0xe00 */ + +}; + +#define PXA25X_UDC_BASE 0x40600000 + +#define UDCCR_UDE (1 << 0) +#define UDCCR_UDA (1 << 1) +#define UDCCR_RSM (1 << 2) +#define UDCCR_RESIR (1 << 3) +#define UDCCR_SUSIR (1 << 4) +#define UDCCR_SRM (1 << 5) +#define UDCCR_RSTIR (1 << 6) +#define UDCCR_REM (1 << 7) + +/* Bulk IN endpoint 1/6/11 */ +#define UDCCS_BI_TSP (1 << 7) +#define UDCCS_BI_FST (1 << 5) +#define UDCCS_BI_SST (1 << 4) +#define UDCCS_BI_TUR (1 << 3) +#define UDCCS_BI_FTF (1 << 2) +#define UDCCS_BI_TPC (1 << 1) +#define UDCCS_BI_TFS (1 << 0) + +/* Bulk OUT endpoint 2/7/12 */ +#define UDCCS_BO_RSP (1 << 7) +#define UDCCS_BO_RNE (1 << 6) +#define UDCCS_BO_FST (1 << 5) +#define UDCCS_BO_SST (1 << 4) +#define UDCCS_BO_DME (1 << 3) +#define UDCCS_BO_RPC (1 << 1) +#define UDCCS_BO_RFS (1 << 0) + +/* Isochronous OUT endpoint 4/9/14 */ +#define UDCCS_IO_RSP (1 << 7) +#define UDCCS_IO_RNE (1 << 6) +#define UDCCS_IO_DME (1 << 3) +#define UDCCS_IO_ROF (1 << 2) +#define UDCCS_IO_RPC (1 << 1) +#define UDCCS_IO_RFS (1 << 0) + +/* Control endpoint 0 */ +#define UDCCS0_OPR (1 << 0) +#define UDCCS0_IPR (1 << 1) +#define UDCCS0_FTF (1 << 2) +#define UDCCS0_DRWF (1 << 3) +#define UDCCS0_SST (1 << 4) +#define UDCCS0_FST (1 << 5) +#define UDCCS0_RNE (1 << 6) +#define UDCCS0_SA (1 << 7) + +#define UICR0_IM0 (1 << 0) + +#define USIR0_IR0 (1 << 0) +#define USIR0_IR1 (1 << 1) +#define USIR0_IR2 (1 << 2) +#define USIR0_IR3 (1 << 3) +#define USIR0_IR4 (1 << 4) +#define USIR0_IR5 (1 << 5) +#define USIR0_IR6 (1 << 6) +#define USIR0_IR7 (1 << 7) + +#define UDCCFR_AREN (1 << 7) /* ACK response enable (now) */ +#define UDCCFR_ACM (1 << 2) /* ACK control mode (wait for AREN) */ +/* + * Intel(R) PXA255 Processor Specification, September 2003 (page 31) + * define new "must be one" bits in UDCCFR (see Table 12-13.) + */ +#define UDCCFR_MB1 (0xff & ~(UDCCFR_AREN | UDCCFR_ACM)) + +#define UFNRH_SIR (1 << 7) /* SOF interrupt request */ +#define UFNRH_SIM (1 << 6) /* SOF interrupt mask */ +#define UFNRH_IPE14 (1 << 5) /* ISO packet error, ep14 */ +#define UFNRH_IPE9 (1 << 4) /* ISO packet error, ep9 */ +#define UFNRH_IPE4 (1 << 3) /* ISO packet error, ep4 */ + +#endif /* __REGS_USB_H__ */ diff --git a/arch/arm/include/asm/arch-s5pc1xx/mmc.h b/arch/arm/include/asm/arch-s5pc1xx/mmc.h index 0f701c9..afdfcf0 100644 --- a/arch/arm/include/asm/arch-s5pc1xx/mmc.h +++ b/arch/arm/include/asm/arch-s5pc1xx/mmc.h @@ -64,11 +64,11 @@ #define SDHCI_CTRL4_DRIVE_MASK(_x) ((_x) << 16) #define SDHCI_CTRL4_DRIVE_SHIFT (16) -int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks); +int s5p_sdhci_init(u32 regbase, int index, int bus_width); static inline unsigned int s5p_mmc_init(int index, int bus_width) { unsigned int base = samsung_get_base_mmc() + (0x10000 * index); - return s5p_sdhci_init(base, 52000000, 400000, index); + return s5p_sdhci_init(base, index, bus_width); } #endif diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 71ef9b0..2a40b89 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -34,83 +34,6 @@ #define OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL 2 #define OMAP_INIT_CONTEXT_UBOOT_AFTER_CH 3 -void preloader_console_init(void); - -/* Boot device */ -#ifdef CONFIG_OMAP54XX -#define BOOT_DEVICE_NONE 0 -#define BOOT_DEVICE_XIP 1 -#define BOOT_DEVICE_XIPWAIT 2 -#define BOOT_DEVICE_NAND 3 -#define BOOT_DEVICE_ONE_NAND 4 -#define BOOT_DEVICE_MMC1 5 -#define BOOT_DEVICE_MMC2 6 -#define BOOT_DEVICE_MMC2_2 7 -#elif defined(CONFIG_OMAP44XX) /* OMAP4 */ -#define BOOT_DEVICE_NONE 0 -#define BOOT_DEVICE_XIP 1 -#define BOOT_DEVICE_XIPWAIT 2 -#define BOOT_DEVICE_NAND 3 -#define BOOT_DEVICE_ONE_NAND 4 -#define BOOT_DEVICE_MMC1 5 -#define BOOT_DEVICE_MMC2 6 -#define BOOT_DEVICE_MMC2_2 0xFF -#elif defined(CONFIG_OMAP34XX) /* OMAP3 */ -#define BOOT_DEVICE_NONE 0 -#define BOOT_DEVICE_XIP 1 -#define BOOT_DEVICE_NAND 2 -#define BOOT_DEVICE_ONE_NAND 3 -#define BOOT_DEVICE_MMC2 5 /*emmc*/ -#define BOOT_DEVICE_MMC1 6 -#define BOOT_DEVICE_XIPWAIT 7 -#define BOOT_DEVICE_MMC2_2 0xFF -#elif defined(CONFIG_AM33XX) /* AM33XX */ -#define BOOT_DEVICE_NAND 5 -#define BOOT_DEVICE_MMC1 8 -#define BOOT_DEVICE_MMC2 9 /* eMMC or daughter card */ -#define BOOT_DEVICE_UART 65 -#define BOOT_DEVICE_MMC2_2 0xFF -#endif - -/* Boot type */ -#define MMCSD_MODE_UNDEFINED 0 -#define MMCSD_MODE_RAW 1 -#define MMCSD_MODE_FAT 2 -#define NAND_MODE_HW_ECC 3 - -struct spl_image_info { - const char *name; - u8 os; - u32 load_addr; - u32 entry_point; - u32 size; -}; - -extern struct spl_image_info spl_image; - -extern u32* boot_params_ptr; -u32 omap_boot_device(void); -u32 omap_boot_mode(void); - -/* SPL common function s*/ -void spl_parse_image_header(const struct image_header *header); -void omap_rev_string(void); -void spl_board_prepare_for_linux(void); -int spl_start_uboot(void); - -/* NAND SPL functions */ -void spl_nand_load_image(void); - -/* MMC SPL functions */ -void spl_mmc_load_image(void); - -/* YMODEM SPL functions */ -void spl_ymodem_load_image(void); - -#ifdef CONFIG_SPL_BOARD_INIT -void spl_board_init(void); -#endif - static inline u32 omap_revision(void) { extern u32 *const omap_si_rev; diff --git a/board/freescale/p3060qds/p3060qds.h b/arch/arm/include/asm/spl.h index 3da6815..62011aa 100644 --- a/board/freescale/p3060qds/p3060qds.h +++ b/arch/arm/include/asm/spl.h @@ -1,5 +1,9 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -8,7 +12,7 @@ * * 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 + * 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 @@ -16,15 +20,15 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ +#ifndef _ASM_SPL_H_ +#define _ASM_SPL_H_ -#ifndef __P3060QDS_H__ -#define __P3060QDS_H__ +/* Platform-specific defines */ +#include <asm/arch/spl.h> -#include <asm/fsl_ddr_sdram.h> -#include <asm/u-boot.h> +/* Linker symbols. */ +extern char __bss_start[], __bss_end__[]; -void fdt_fixup_board_enet(void *blob); -void pci_of_setup(void *blob, bd_t *bd); -extern fixed_ddr_parm_t fixed_ddr_parm_0[]; +extern gd_t gdata; #endif diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index bd3b77f..3422ac1 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -44,6 +44,8 @@ COBJS-y += interrupts.o COBJS-y += reset.o SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o +else +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o endif COBJS-y += cache.o diff --git a/arch/arm/lib/spl.c b/arch/arm/lib/spl.c new file mode 100644 index 0000000..f568f61 --- /dev/null +++ b/arch/arm/lib/spl.c @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2010-2012 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> + * Tom Rini <trini@ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <config.h> +#include <spl.h> +#include <image.h> +#include <linux/compiler.h> + +/* Pointer to as well as the global data structure for SPL */ +DECLARE_GLOBAL_DATA_PTR; +gd_t gdata __attribute__ ((section(".data"))); + +/* + * In the context of SPL, board_init_f must ensure that any clocks/etc for + * DDR are enabled, ensure that the stack pointer is valid, clear the BSS + * and call board_init_f. We provide this version by default but mark it + * as __weak to allow for platforms to do this in their own way if needed. + */ +void __weak board_init_f(ulong dummy) +{ + /* Set the stack pointer. */ + asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK)); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end__ - __bss_start); + + /* Set global data pointer. */ + gd = &gdata; + + board_init_r(NULL, 0); +} + +/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +void __noreturn jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%p\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + cleanup_before_linux(); + image_entry(0, CONFIG_MACH_TYPE, arg); +} +#endif diff --git a/arch/avr32/config.mk b/arch/avr32/config.mk index d8e7ebb..a751a3d 100644 --- a/arch/avr32/config.mk +++ b/arch/avr32/config.mk @@ -29,5 +29,3 @@ PLATFORM_RELFLAGS += -ffixed-r5 -fPIC -mno-init-got -mrelax PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections LDFLAGS_u-boot = --gc-sections --relax - -LDSCRIPT = $(SRCTREE)/$(CPUDIR)/u-boot.lds diff --git a/arch/avr32/cpu/at32ap700x/portmux.c b/arch/avr32/cpu/at32ap700x/portmux.c index e3e38a2..7eb42de 100644 --- a/arch/avr32/cpu/at32ap700x/portmux.c +++ b/arch/avr32/cpu/at32ap700x/portmux.c @@ -122,7 +122,7 @@ void portmux_enable_macb1(unsigned long flags, unsigned long drive_strength) portd_mask |= (1 << 15);/* SPD */ /* REVISIT: Some pins are probably pure outputs */ - portmux_select_peripheral(PORTMUX_PORT_D, portc_mask, + portmux_select_peripheral(PORTMUX_PORT_D, portd_mask, PORTMUX_FUNC_B, PORTMUX_BUSKEEPER); portmux_select_peripheral(PORTMUX_PORT_C, portc_mask, PORTMUX_FUNC_B, PORTMUX_BUSKEEPER); diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index d7a64b4..9d3b76e 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -250,7 +250,6 @@ void board_init_f(ulong board_type) void board_init_r(gd_t *new_gd, ulong dest_addr) { - extern void malloc_bin_reloc (void); #ifndef CONFIG_ENV_IS_NOWHERE extern char * env_name_spec; #endif diff --git a/arch/m68k/cpu/mcf5227x/cpu.c b/arch/m68k/cpu/mcf5227x/cpu.c index 09ef1d2..3a0ab97 100644 --- a/arch/m68k/cpu/mcf5227x/cpu.c +++ b/arch/m68k/cpu/mcf5227x/cpu.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -30,14 +30,15 @@ #include <command.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM); + rcm_t *rcm = (rcm_t *) (MMAP_RCM); udelay(1000); - rcm->rcr |= RCM_RCR_SOFTRST; + setbits_8(&rcm->rcr, RCM_RCR_SOFTRST); /* we don't return! */ return 0; @@ -45,14 +46,14 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int checkcpu(void) { - volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + ccm_t *ccm = (ccm_t *) MMAP_CCM; u16 msk; u16 id = 0; u8 ver; puts("CPU: "); - msk = (ccm->cir >> 6); - ver = (ccm->cir & 0x003f); + msk = (in_be16(&ccm->cir) >> 6); + ver = (in_be16(&ccm->cir) & 0x003f); switch (msk) { case 0x6c: id = 52277; diff --git a/arch/m68k/cpu/mcf5227x/cpu_init.c b/arch/m68k/cpu/mcf5227x/cpu_init.c index beb78f5..e23b20d 100644 --- a/arch/m68k/cpu/mcf5227x/cpu_init.c +++ b/arch/m68k/cpu/mcf5227x/cpu_init.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2004-2007 Freescale Semiconductor, Inc. + * (C) Copyright 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -29,6 +29,7 @@ #include <watchdog.h> #include <asm/immap.h> +#include <asm/io.h> #include <asm/rtc.h> /* @@ -40,70 +41,70 @@ */ void cpu_init_f(void) { - volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + pll_t *pll = (pll_t *)MMAP_PLL; #if !defined(CONFIG_CF_SBF) /* Workaround, must place before fbcs */ - pll->psr = 0x12; - - scm1->mpr = 0x77777777; - scm1->pacra = 0; - scm1->pacrb = 0; - scm1->pacrc = 0; - scm1->pacrd = 0; - scm1->pacre = 0; - scm1->pacrf = 0; - scm1->pacrg = 0; - scm1->pacri = 0; + out_be32(&pll->psr, 0x12); + + out_be32(&scm1->mpr, 0x77777777); + out_be32(&scm1->pacra, 0); + out_be32(&scm1->pacrb, 0); + out_be32(&scm1->pacrc, 0); + out_be32(&scm1->pacrd, 0); + out_be32(&scm1->pacre, 0); + out_be32(&scm1->pacrf, 0); + out_be32(&scm1->pacrg, 0); + out_be32(&scm1->pacri, 0); #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) \ && defined(CONFIG_SYS_CS0_CTRL)) - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #endif #endif /* CONFIG_CF_SBF */ #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) \ && defined(CONFIG_SYS_CS1_CTRL)) - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) \ && defined(CONFIG_SYS_CS2_CTRL)) - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) \ && defined(CONFIG_SYS_CS3_CTRL)) - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) \ && defined(CONFIG_SYS_CS4_CTRL)) - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) \ && defined(CONFIG_SYS_CS5_CTRL)) - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif #ifdef CONFIG_FSL_I2C - gpio->par_i2c = GPIO_PAR_I2C_SCL_SCL | GPIO_PAR_I2C_SDA_SDA; + out_8(&gpio->par_i2c, GPIO_PAR_I2C_SCL_SCL | GPIO_PAR_I2C_SDA_SDA); #endif icache_enable(); @@ -115,11 +116,11 @@ void cpu_init_f(void) int cpu_init_r(void) { #ifdef CONFIG_MCFRTC - volatile rtc_t *rtc = (volatile rtc_t *)(CONFIG_SYS_MCFRTC_BASE); - volatile rtcex_t *rtcex = (volatile rtcex_t *)&rtc->extended; + rtc_t *rtc = (rtc_t *)(CONFIG_SYS_MCFRTC_BASE); + rtcex_t *rtcex = (rtcex_t *)&rtc->extended; - rtcex->gocu = (CONFIG_SYS_RTC_OSCILLATOR >> 16) & 0xFFFF; - rtcex->gocl = CONFIG_SYS_RTC_OSCILLATOR & 0xFFFF; + out_be32(&rtcex->gocu, (CONFIG_SYS_RTC_OSCILLATOR >> 16) & 0xffff); + out_be32(&rtcex->gocl, CONFIG_SYS_RTC_OSCILLATOR & 0xffff); #endif return (0); @@ -127,27 +128,27 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= - (GPIO_PAR_UART_U0TXD_UNMASK & GPIO_PAR_UART_U0RXD_UNMASK); - gpio->par_uart |= - (GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); + clrbits_be16(&gpio->par_uart, + ~(GPIO_PAR_UART_U0TXD_UNMASK & GPIO_PAR_UART_U0RXD_UNMASK)); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); break; case 1: - gpio->par_uart &= - (GPIO_PAR_UART_U1TXD_UNMASK & GPIO_PAR_UART_U1RXD_UNMASK); - gpio->par_uart |= - (GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); + clrbits_be16(&gpio->par_uart, + ~(GPIO_PAR_UART_U1TXD_UNMASK & GPIO_PAR_UART_U1RXD_UNMASK)); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); break; case 2: - gpio->par_dspi &= - (GPIO_PAR_DSPI_SIN_UNMASK & GPIO_PAR_DSPI_SOUT_UNMASK); - gpio->par_dspi = - (GPIO_PAR_DSPI_SIN_U2RXD | GPIO_PAR_DSPI_SOUT_U2TXD); + clrbits_8(&gpio->par_dspi, + ~(GPIO_PAR_DSPI_SIN_UNMASK & GPIO_PAR_DSPI_SOUT_UNMASK)); + out_8(&gpio->par_dspi, + GPIO_PAR_DSPI_SIN_U2RXD | GPIO_PAR_DSPI_SOUT_U2TXD); break; } } @@ -155,32 +156,32 @@ void uart_port_conf(int port) #ifdef CONFIG_CF_DSPI void cfspi_port_conf(void) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; - gpio->par_dspi = - GPIO_PAR_DSPI_SIN_SIN | GPIO_PAR_DSPI_SOUT_SOUT | - GPIO_PAR_DSPI_SCK_SCK; + out_8(&gpio->par_dspi, + GPIO_PAR_DSPI_SIN_SIN | GPIO_PAR_DSPI_SOUT_SOUT | + GPIO_PAR_DSPI_SCK_SCK); } int cfspi_claim_bus(uint bus, uint cs) { - volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + dspi_t *dspi = (dspi_t *) MMAP_DSPI; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; - if ((dspi->sr & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) + if ((in_be32(&dspi->sr) & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) return -1; /* Clear FIFO and resume transfer */ - dspi->mcr &= ~(DSPI_MCR_CTXF | DSPI_MCR_CRXF); + clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF); switch (cs) { case 0: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_UNMASK; - gpio->par_dspi |= GPIO_PAR_DSPI_PCS0_PCS0; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_UNMASK); + setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0); break; case 2: - gpio->par_timer &= GPIO_PAR_TIMER_T2IN_UNMASK; - gpio->par_timer |= GPIO_PAR_TIMER_T2IN_DSPIPCS2; + clrbits_8(&gpio->par_timer, ~GPIO_PAR_TIMER_T2IN_UNMASK); + setbits_8(&gpio->par_timer, GPIO_PAR_TIMER_T2IN_DSPIPCS2); break; } @@ -189,17 +190,18 @@ int cfspi_claim_bus(uint bus, uint cs) void cfspi_release_bus(uint bus, uint cs) { - volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + dspi_t *dspi = (dspi_t *) MMAP_DSPI; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; - dspi->mcr &= ~(DSPI_MCR_CTXF | DSPI_MCR_CRXF); /* Clear FIFO */ + /* Clear FIFO */ + clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF); switch (cs) { case 0: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0); break; case 2: - gpio->par_timer &= GPIO_PAR_TIMER_T2IN_UNMASK; + clrbits_8(&gpio->par_timer, ~GPIO_PAR_TIMER_T2IN_UNMASK); break; } } diff --git a/arch/m68k/cpu/mcf5227x/interrupts.c b/arch/m68k/cpu/mcf5227x/interrupts.c index 85828a6..a2cf519 100644 --- a/arch/m68k/cpu/mcf5227x/interrupts.c +++ b/arch/m68k/cpu/mcf5227x/interrupts.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,14 +28,15 @@ /* CPU specific interrupt routine */ #include <common.h> #include <asm/immap.h> +#include <asm/io.h> int interrupt_init(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); /* Make sure all interrupts are disabled */ - intp->imrh0 |= 0xFFFFFFFF; - intp->imrl0 |= 0xFFFFFFFF; + setbits_be32(&intp->imrh0, 0xffffffff); + setbits_be32(&intp->imrl0, 0xffffffff); enable_interrupts(); return 0; @@ -44,9 +45,9 @@ int interrupt_init(void) #if defined(CONFIG_MCFTMR) void dtimer_intr_setup(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); - intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; - intp->imrh0 &= ~CONFIG_SYS_TMRINTR_MASK; + out_8(&intp->icr0[CONFIG_SYS_TMRINTR_NO], CONFIG_SYS_TMRINTR_PRI); + clrbits_be32(&intp->imrh0, CONFIG_SYS_TMRINTR_MASK); } #endif diff --git a/arch/m68k/cpu/mcf5227x/speed.c b/arch/m68k/cpu/mcf5227x/speed.c index 7e385d3..b94a9ed 100644 --- a/arch/m68k/cpu/mcf5227x/speed.c +++ b/arch/m68k/cpu/mcf5227x/speed.c @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -26,6 +26,7 @@ #include <asm/processor.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -44,7 +45,7 @@ DECLARE_GLOBAL_DATA_PTR; void clock_enter_limp(int lpdiv) { - volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; + ccm_t *ccm = (ccm_t *)MMAP_CCM; int i, j; /* Check bounds of divider */ @@ -57,10 +58,10 @@ void clock_enter_limp(int lpdiv) for (i = 0, j = lpdiv; j != 1; j >>= 1, i++) ; /* Apply the divider to the system clock */ - ccm->cdr = (ccm->cdr & 0xF0FF) | CCM_CDR_LPDIV(i); + clrsetbits_be16(&ccm->cdr, 0x0f00, CCM_CDR_LPDIV(i)); /* Enable Limp Mode */ - ccm->misccr |= CCM_MISCCR_LIMP; + setbits_be16(&ccm->misccr, CCM_MISCCR_LIMP); } /* @@ -69,14 +70,15 @@ void clock_enter_limp(int lpdiv) */ void clock_exit_limp(void) { - volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; - volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + ccm_t *ccm = (ccm_t *)MMAP_CCM; + pll_t *pll = (pll_t *)MMAP_PLL; /* Exit Limp mode */ - ccm->misccr &= ~CCM_MISCCR_LIMP; + clrbits_be16(&ccm->misccr, CCM_MISCCR_LIMP); /* Wait for the PLL to lock */ - while (!(pll->psr & PLL_PSR_LOCK)) ; + while (!(in_be32(&pll->psr) & PLL_PSR_LOCK)) + ; } /* @@ -85,12 +87,12 @@ void clock_exit_limp(void) int get_clocks(void) { - volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; - volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + ccm_t *ccm = (ccm_t *)MMAP_CCM; + pll_t *pll = (pll_t *)MMAP_PLL; int vco, temp, pcrvalue, pfdr; u8 bootmode; - pcrvalue = pll->pcr & 0xFF0F0FFF; + pcrvalue = in_be32(&pll->pcr) & 0xFF0F0FFF; pfdr = pcrvalue >> 24; if (pfdr == 0x1E) @@ -102,32 +104,32 @@ int get_clocks(void) if (bootmode == 0) { /* Normal mode */ - vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; if ((vco < CLOCK_PLL_FVCO_MIN) || (vco > CLOCK_PLL_FVCO_MAX)) { /* Default value */ - pcrvalue = (pll->pcr & 0x00FFFFFF); + pcrvalue = (in_be32(&pll->pcr) & 0x00FFFFFF); pcrvalue |= 0x1E << 24; - pll->pcr = pcrvalue; + out_be32(&pll->pcr, pcrvalue); vco = - ((pll->pcr & 0xFF000000) >> 24) * + ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; } gd->vco_clk = vco; /* Vco clock */ } else if (bootmode == 3) { /* serial mode */ - vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; gd->vco_clk = vco; /* Vco clock */ } - if ((ccm->ccr & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { + if ((in_be16(&ccm->ccr) & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { /* Limp mode */ } else { gd->inp_clk = CONFIG_SYS_INPUT_CLKSRC; /* Input clock */ - temp = (pll->pcr & PLL_PCR_OUTDIV1_MASK) + 1; + temp = (in_be32(&pll->pcr) & PLL_PCR_OUTDIV1_MASK) + 1; gd->cpu_clk = vco / temp; /* cpu clock */ - temp = ((pll->pcr & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; + temp = ((in_be32(&pll->pcr) & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; gd->flb_clk = vco / temp; /* flexbus clock */ gd->bus_clk = gd->flb_clk; } diff --git a/arch/m68k/cpu/mcf523x/cpu.c b/arch/m68k/cpu/mcf523x/cpu.c index 2376f97..a3f5684 100644 --- a/arch/m68k/cpu/mcf523x/cpu.c +++ b/arch/m68k/cpu/mcf523x/cpu.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -31,28 +31,29 @@ #include <netdev.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + ccm_t *ccm = (ccm_t *) MMAP_CCM; - ccm->rcr = CCM_RCR_SOFTRST; + out_8(&ccm->rcr, CCM_RCR_SOFTRST); /* we don't return! */ return 0; -}; +} int checkcpu(void) { - volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + ccm_t *ccm = (ccm_t *) MMAP_CCM; u16 msk; u16 id = 0; u8 ver; puts("CPU: "); - msk = (ccm->cir >> 6); - ver = (ccm->cir & 0x003f); + msk = (in_be16(&ccm->cir) >> 6); + ver = (in_be16(&ccm->cir) & 0x003f); switch (msk) { case 0x31: id = 5235; @@ -76,19 +77,21 @@ int checkcpu(void) /* Called by macro WATCHDOG_RESET */ void watchdog_reset(void) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); - wdp->sr = 0x5555; /* Count register */ + /* Count register */ + out_be16(&wdp->sr, 0x5555); asm("nop"); - wdp->sr = 0xAAAA; /* Count register */ + out_be16(&wdp->sr, 0xaaaa); } int watchdog_disable(void) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); /* UserManual, once the wdog is disabled, wdog cannot be re-enabled */ - wdp->cr |= WTM_WCR_HALTED; /* halted watchdog timer */ + /* halted watchdog timer */ + setbits_be16(&wdp->cr, WTM_WCR_HALTED); puts("WATCHDOG:disabled\n"); return (0); @@ -96,15 +99,15 @@ int watchdog_disable(void) int watchdog_init(void) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); u32 wdog_module = 0; /* set timeout and enable watchdog */ wdog_module = ((CONFIG_SYS_CLK / CONFIG_SYS_HZ) * CONFIG_WATCHDOG_TIMEOUT); wdog_module |= (wdog_module / 8192); - wdp->mr = wdog_module; + out_be16(&wdp->mr, wdog_module); - wdp->cr = WTM_WCR_EN; + out_be16(&wdp->cr, WTM_WCR_EN); puts("WATCHDOG:enabled\n"); return (0); diff --git a/arch/m68k/cpu/mcf523x/cpu_init.c b/arch/m68k/cpu/mcf523x/cpu_init.c index 0f299f0..d1c0b40 100644 --- a/arch/m68k/cpu/mcf523x/cpu_init.c +++ b/arch/m68k/cpu/mcf523x/cpu_init.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2007 Freescale Semiconductor, Inc. + * (C) Copyright 2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,6 +28,7 @@ #include <common.h> #include <watchdog.h> #include <asm/immap.h> +#include <asm/io.h> #if defined(CONFIG_CMD_NET) #include <config.h> @@ -44,74 +45,74 @@ */ void cpu_init_f(void) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - volatile wdog_t *wdog = (wdog_t *) MMAP_WDOG; - volatile scm_t *scm = (scm_t *) MMAP_SCM; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + wdog_t *wdog = (wdog_t *) MMAP_WDOG; + scm_t *scm = (scm_t *) MMAP_SCM; /* watchdog is enabled by default - disable the watchdog */ #ifndef CONFIG_WATCHDOG - wdog->cr = 0; + out_be16(&wdog->cr, 0); #endif - scm->rambar = (CONFIG_SYS_INIT_RAM_ADDR | SCM_RAMBAR_BDE); + out_be32(&scm->rambar, CONFIG_SYS_INIT_RAM_ADDR | SCM_RAMBAR_BDE); /* Port configuration */ - gpio->par_cs = 0; + out_8(&gpio->par_cs, 0); #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) && defined(CONFIG_SYS_CS0_CTRL)) - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #endif #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) && defined(CONFIG_SYS_CS1_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS1; - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS1); + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) && defined(CONFIG_SYS_CS2_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS2; - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS2); + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) && defined(CONFIG_SYS_CS3_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS3; - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS3); + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) && defined(CONFIG_SYS_CS4_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS4; - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS4); + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) && defined(CONFIG_SYS_CS5_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS5; - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS5); + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif #if (defined(CONFIG_SYS_CS6_BASE) && defined(CONFIG_SYS_CS6_MASK) && defined(CONFIG_SYS_CS6_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS6; - fbcs->csar6 = CONFIG_SYS_CS6_BASE; - fbcs->cscr6 = CONFIG_SYS_CS6_CTRL; - fbcs->csmr6 = CONFIG_SYS_CS6_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS6); + out_be32(&fbcs->csar6, CONFIG_SYS_CS6_BASE); + out_be32(&fbcs->cscr6, CONFIG_SYS_CS6_CTRL); + out_be32(&fbcs->csmr6, CONFIG_SYS_CS6_MASK); #endif #if (defined(CONFIG_SYS_CS7_BASE) && defined(CONFIG_SYS_CS7_MASK) && defined(CONFIG_SYS_CS7_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS7; - fbcs->csar7 = CONFIG_SYS_CS7_BASE; - fbcs->cscr7 = CONFIG_SYS_CS7_CTRL; - fbcs->csmr7 = CONFIG_SYS_CS7_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS7); + out_be32(&fbcs->csar7, CONFIG_SYS_CS7_BASE); + out_be32(&fbcs->cscr7, CONFIG_SYS_CS7_CTRL); + out_be32(&fbcs->csmr7, CONFIG_SYS_CS7_MASK); #endif #ifdef CONFIG_FSL_I2C @@ -132,29 +133,33 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= ~(GPIO_PAR_UART_U0RXD | GPIO_PAR_UART_U0TXD); - gpio->par_uart |= (GPIO_PAR_UART_U0RXD | GPIO_PAR_UART_U0TXD); + clrbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U0RXD | GPIO_PAR_UART_U0TXD); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U0RXD | GPIO_PAR_UART_U0TXD); break; case 1: - gpio->par_uart &= - ~(GPIO_PAR_UART_U1RXD_MASK | GPIO_PAR_UART_U1TXD_MASK); - gpio->par_uart |= - (GPIO_PAR_UART_U1RXD_U1RXD | GPIO_PAR_UART_U1TXD_U1TXD); + clrbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U1RXD_MASK | GPIO_PAR_UART_U1TXD_MASK); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U1RXD_U1RXD | GPIO_PAR_UART_U1TXD_U1TXD); break; case 2: #ifdef CONFIG_SYS_UART2_PRI_GPIO - gpio->par_uart &= ~(GPIO_PAR_UART_U2RXD | GPIO_PAR_UART_U2TXD); - gpio->par_uart |= (GPIO_PAR_UART_U2RXD | GPIO_PAR_UART_U2TXD); + clrbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U2RXD | GPIO_PAR_UART_U2TXD); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U2RXD | GPIO_PAR_UART_U2TXD); #elif defined(CONFIG_SYS_UART2_ALT1_GPIO) - gpio->feci2c &= - ~(GPIO_PAR_FECI2C_EMDC_MASK | GPIO_PAR_FECI2C_EMDIO_MASK); - gpio->feci2c |= - (GPIO_PAR_FECI2C_EMDC_U2TXD | GPIO_PAR_FECI2C_EMDIO_U2RXD); + clrbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_EMDC_MASK | GPIO_PAR_FECI2C_EMDIO_MASK); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_EMDC_U2TXD | GPIO_PAR_FECI2C_EMDIO_U2RXD); #endif break; } @@ -163,15 +168,16 @@ void uart_port_conf(int port) #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; if (setclear) { - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_EMDC_FECEMDC | - GPIO_PAR_FECI2C_EMDIO_FECEMDIO); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_EMDC_FECEMDC | + GPIO_PAR_FECI2C_EMDIO_FECEMDIO); } else { - gpio->par_feci2c &= - ~(GPIO_PAR_FECI2C_EMDC_MASK | GPIO_PAR_FECI2C_EMDIO_MASK); + clrbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_EMDC_MASK | + GPIO_PAR_FECI2C_EMDIO_MASK); } return 0; diff --git a/arch/m68k/cpu/mcf523x/interrupts.c b/arch/m68k/cpu/mcf523x/interrupts.c index db5ccdf..76115a4 100644 --- a/arch/m68k/cpu/mcf523x/interrupts.c +++ b/arch/m68k/cpu/mcf523x/interrupts.c @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -25,13 +25,14 @@ /* CPU specific interrupt routine */ #include <common.h> #include <asm/immap.h> +#include <asm/io.h> int interrupt_init(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); /* Make sure all interrupts are disabled */ - intp->imrl0 |= 0x1; + setbits_be32(&intp->imrl0, 0x1); enable_interrupts(); return 0; @@ -40,10 +41,10 @@ int interrupt_init(void) #if defined(CONFIG_MCFTMR) void dtimer_intr_setup(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); - intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; - intp->imrl0 &= ~INTC_IPRL_INT0; - intp->imrl0 &= ~CONFIG_SYS_TMRINTR_MASK; + out_8(&intp->icr0[CONFIG_SYS_TMRINTR_NO], CONFIG_SYS_TMRINTR_PRI); + clrbits_be32(&intp->imrl0, INTC_IPRL_INT0); + clrbits_be32(&intp->imrl0, CONFIG_SYS_TMRINTR_MASK); } #endif diff --git a/arch/m68k/cpu/mcf523x/speed.c b/arch/m68k/cpu/mcf523x/speed.c index 6096ba4..e2a6ae3 100644 --- a/arch/m68k/cpu/mcf523x/speed.c +++ b/arch/m68k/cpu/mcf523x/speed.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -29,6 +29,7 @@ #include <asm/processor.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; /* @@ -36,11 +37,12 @@ DECLARE_GLOBAL_DATA_PTR; */ int get_clocks(void) { - volatile pll_t *pll = (volatile pll_t *)(MMAP_PLL); + pll_t *pll = (pll_t *)(MMAP_PLL); - pll->syncr = PLL_SYNCR_MFD(1); + out_be32(&pll->syncr, PLL_SYNCR_MFD(1)); - while (!(pll->synsr & PLL_SYNSR_LOCK)); + while (!(in_be32(&pll->synsr) & PLL_SYNSR_LOCK)) + ; gd->bus_clk = CONFIG_SYS_CLK; gd->cpu_clk = (gd->bus_clk * 2); diff --git a/arch/m68k/cpu/mcf52x2/cpu.c b/arch/m68k/cpu/mcf52x2/cpu.c index 571d078..7c6100c 100644 --- a/arch/m68k/cpu/mcf52x2/cpu.c +++ b/arch/m68k/cpu/mcf52x2/cpu.c @@ -9,6 +9,8 @@ * MCF5275 additions * Copyright (C) 2008 Arthur Shipkowski (art@videon-central.com) * + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * * See file CREDITS for list of people who contributed to this * project. * @@ -32,6 +34,7 @@ #include <watchdog.h> #include <command.h> #include <asm/immap.h> +#include <asm/io.h> #include <netdev.h> #include "cpu.h" @@ -40,11 +43,11 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_M5208 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile rcm_t *rcm = (rcm_t *)(MMAP_RCM); + rcm_t *rcm = (rcm_t *)(MMAP_RCM); udelay(1000); - rcm->rcr = RCM_RCR_SOFTRST; + out_8(&rcm->rcr, RCM_RCR_SOFTRST); /* we don't return! */ return 0; @@ -65,18 +68,21 @@ int checkcpu(void) /* Called by macro WATCHDOG_RESET */ void watchdog_reset(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); - wdt->sr = 0x5555; - wdt->sr = 0xAAAA; + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); + + out_be16(&wdt->sr, 0x5555); + out_be16(&wdt->sr, 0xaaaa); } int watchdog_disable(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); - wdt->sr = 0x5555; /* reset watchdog counter */ - wdt->sr = 0xAAAA; - wdt->cr = 0; /* disable watchdog timer */ + /* reset watchdog counter */ + out_be16(&wdt->sr, 0x5555); + out_be16(&wdt->sr, 0xaaaa); + /* disable watchdog timer */ + out_be16(&wdt->cr, 0); puts("WATCHDOG:disabled\n"); return (0); @@ -84,15 +90,18 @@ int watchdog_disable(void) int watchdog_init(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); - wdt->cr = 0; /* disable watchdog */ + /* disable watchdog */ + out_be16(&wdt->cr, 0); /* set timeout and enable watchdog */ - wdt->mr = - ((CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000)) - 1; - wdt->sr = 0x5555; /* reset watchdog counter */ - wdt->sr = 0xAAAA; + out_be16(&wdt->mr, + (CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000) - 1); + + /* reset watchdog counter */ + out_be16(&wdt->sr, 0x5555); + out_be16(&wdt->sr, 0xaaaa); puts("WATCHDOG:enabled\n"); return (0); @@ -178,13 +187,13 @@ int watchdog_init(void) #ifdef CONFIG_M5272 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); - wdp->wdog_wrrr = 0; + out_be16(&wdp->wdog_wrrr, 0); udelay(1000); /* enable watchdog, set timeout to 0 and wait */ - wdp->wdog_wrrr = 1; + out_be16(&wdp->wdog_wrrr, 1); while (1) ; /* we don't return! */ @@ -193,12 +202,12 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int checkcpu(void) { - volatile sysctrl_t *sysctrl = (sysctrl_t *) (MMAP_CFG); + sysctrl_t *sysctrl = (sysctrl_t *) (MMAP_CFG); uchar msk; char *suf; puts("CPU: "); - msk = (sysctrl->sc_dir > 28) & 0xf; + msk = (in_be32(&sysctrl->sc_dir) > 28) & 0xf; switch (msk) { case 0x2: suf = "1K75N"; @@ -221,17 +230,21 @@ int checkcpu(void) /* Called by macro WATCHDOG_RESET */ void watchdog_reset(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); - wdt->wdog_wcr = 0; + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); + + out_be16(&wdt->wdog_wcr, 0); } int watchdog_disable(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); - wdt->wdog_wcr = 0; /* reset watchdog counter */ - wdt->wdog_wirr = 0; /* disable watchdog interrupt */ - wdt->wdog_wrrr = 0; /* disable watchdog timer */ + /* reset watchdog counter */ + out_be16(&wdt->wdog_wcr, 0); + /* disable watchdog interrupt */ + out_be16(&wdt->wdog_wirr, 0); + /* disable watchdog timer */ + out_be16(&wdt->wdog_wrrr, 0); puts("WATCHDOG:disabled\n"); return (0); @@ -239,14 +252,17 @@ int watchdog_disable(void) int watchdog_init(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); - wdt->wdog_wirr = 0; /* disable watchdog interrupt */ + /* disable watchdog interrupt */ + out_be16(&wdt->wdog_wirr, 0); /* set timeout and enable watchdog */ - wdt->wdog_wrrr = - ((CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000)) - 1; - wdt->wdog_wcr = 0; /* reset watchdog counter */ + out_be16(&wdt->wdog_wrrr, + (CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000) - 1); + + /* reset watchdog counter */ + out_be16(&wdt->wdog_wcr, 0); puts("WATCHDOG:enabled\n"); return (0); @@ -258,11 +274,11 @@ int watchdog_init(void) #ifdef CONFIG_M5275 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile rcm_t *rcm = (rcm_t *)(MMAP_RCM); + rcm_t *rcm = (rcm_t *)(MMAP_RCM); udelay(1000); - rcm->rcr = RCM_RCR_SOFTRST; + out_8(&rcm->rcr, RCM_RCR_SOFTRST); /* we don't return! */ return 0; @@ -282,18 +298,22 @@ int checkcpu(void) /* Called by macro WATCHDOG_RESET */ void watchdog_reset(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); - wdt->wsr = 0x5555; - wdt->wsr = 0xAAAA; + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); + + out_be16(&wdt->wsr, 0x5555); + out_be16(&wdt->wsr, 0xaaaa); } int watchdog_disable(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); - wdt->wsr = 0x5555; /* reset watchdog counter */ - wdt->wsr = 0xAAAA; - wdt->wcr = 0; /* disable watchdog timer */ + /* reset watchdog counter */ + out_be16(&wdt->wsr, 0x5555); + out_be16(&wdt->wsr, 0xaaaa); + + /* disable watchdog timer */ + out_be16(&wdt->wcr, 0); puts("WATCHDOG:disabled\n"); return (0); @@ -301,15 +321,18 @@ int watchdog_disable(void) int watchdog_init(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); - wdt->wcr = 0; /* disable watchdog */ + /* disable watchdog */ + out_be16(&wdt->wcr, 0); /* set timeout and enable watchdog */ - wdt->wmr = - ((CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000)) - 1; - wdt->wsr = 0x5555; /* reset watchdog counter */ - wdt->wsr = 0xAAAA; + out_be16(&wdt->wmr, + (CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000) - 1); + + /* reset watchdog counter */ + out_be16(&wdt->wsr, 0x5555); + out_be16(&wdt->wsr, 0xaaaa); puts("WATCHDOG:enabled\n"); return (0); diff --git a/arch/m68k/cpu/mcf52x2/cpu_init.c b/arch/m68k/cpu/mcf52x2/cpu_init.c index a98a926..5d0e9f0 100644 --- a/arch/m68k/cpu/mcf52x2/cpu_init.c +++ b/arch/m68k/cpu/mcf52x2/cpu_init.c @@ -8,7 +8,7 @@ * (c) Copyright 2010 * Arcturus Networks Inc. <www.arcturusnetworks.com> * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * Hayden Fraser (Hayden.Fraser@freescale.com) * @@ -37,6 +37,7 @@ #include <common.h> #include <watchdog.h> #include <asm/immap.h> +#include <asm/io.h> #if defined(CONFIG_CMD_NET) #include <config.h> @@ -48,57 +49,57 @@ /* Only 5272 Flexbus chipselect is different from the rest */ void init_fbcs(void) { - volatile fbcs_t *fbcs = (fbcs_t *) (MMAP_FBCS); + fbcs_t *fbcs = (fbcs_t *) (MMAP_FBCS); #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) \ && defined(CONFIG_SYS_CS0_CTRL)) - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #else #warning "Chip Select 0 are not initialized/used" #endif #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) \ && defined(CONFIG_SYS_CS1_CTRL)) - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) \ && defined(CONFIG_SYS_CS2_CTRL)) - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) \ && defined(CONFIG_SYS_CS3_CTRL)) - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) \ && defined(CONFIG_SYS_CS4_CTRL)) - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) \ && defined(CONFIG_SYS_CS5_CTRL)) - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif #if (defined(CONFIG_SYS_CS6_BASE) && defined(CONFIG_SYS_CS6_MASK) \ && defined(CONFIG_SYS_CS6_CTRL)) - fbcs->csar6 = CONFIG_SYS_CS6_BASE; - fbcs->cscr6 = CONFIG_SYS_CS6_CTRL; - fbcs->csmr6 = CONFIG_SYS_CS6_MASK; + out_be32(&fbcs->csar6, CONFIG_SYS_CS6_BASE); + out_be32(&fbcs->cscr6, CONFIG_SYS_CS6_CTRL); + out_be32(&fbcs->csmr6, CONFIG_SYS_CS6_MASK); #endif #if (defined(CONFIG_SYS_CS7_BASE) && defined(CONFIG_SYS_CS7_MASK) \ && defined(CONFIG_SYS_CS7_CTRL)) - fbcs->csar7 = CONFIG_SYS_CS7_BASE; - fbcs->cscr7 = CONFIG_SYS_CS7_CTRL; - fbcs->csmr7 = CONFIG_SYS_CS7_MASK; + out_be32(&fbcs->csar7, CONFIG_SYS_CS7_BASE); + out_be32(&fbcs->cscr7, CONFIG_SYS_CS7_CTRL); + out_be32(&fbcs->csmr7, CONFIG_SYS_CS7_MASK); #endif } #endif @@ -106,22 +107,22 @@ void init_fbcs(void) #if defined(CONFIG_M5208) void cpu_init_f(void) { - volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + scm1_t *scm1 = (scm1_t *) MMAP_SCM1; #ifndef CONFIG_WATCHDOG - volatile wdog_t *wdg = (wdog_t *) MMAP_WDOG; + wdog_t *wdg = (wdog_t *) MMAP_WDOG; /* Disable the watchdog if we aren't using it */ - wdg->cr = 0; + out_be16(&wdg->cr, 0); #endif - scm1->mpr = 0x77777777; - scm1->pacra = 0; - scm1->pacrb = 0; - scm1->pacrc = 0; - scm1->pacrd = 0; - scm1->pacre = 0; - scm1->pacrf = 0; + out_be32(&scm1->mpr, 0x77777777); + out_be32(&scm1->pacra, 0); + out_be32(&scm1->pacrb, 0); + out_be32(&scm1->pacrc, 0); + out_be32(&scm1->pacrd, 0); + out_be32(&scm1->pacre, 0); + out_be32(&scm1->pacrf, 0); /* FlexBus Chipselect */ init_fbcs(); @@ -137,36 +138,36 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= GPIO_PAR_UART0_UNMASK; - gpio->par_uart |= (GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); + clrbits_be16(&gpio->par_uart, ~GPIO_PAR_UART0_UNMASK); + setbits_be16(&gpio->par_uart, GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); break; case 1: - gpio->par_uart &= GPIO_PAR_UART0_UNMASK; - gpio->par_uart |= (GPIO_PAR_UART_U1TXD | GPIO_PAR_UART_U1RXD); + clrbits_be16(&gpio->par_uart, ~GPIO_PAR_UART0_UNMASK); + setbits_be16(&gpio->par_uart, GPIO_PAR_UART_U1TXD | GPIO_PAR_UART_U1RXD); break; case 2: #ifdef CONFIG_SYS_UART2_PRI_GPIO - gpio->par_timer &= - (GPIO_PAR_TMR_TIN0_UNMASK | GPIO_PAR_TMR_TIN1_UNMASK); - gpio->par_timer |= - (GPIO_PAR_TMR_TIN0_U2TXD | GPIO_PAR_TMR_TIN1_U2RXD); + clrbits_8(&gpio->par_timer, + ~(GPIO_PAR_TMR_TIN0_UNMASK | GPIO_PAR_TMR_TIN1_UNMASK)); + setbits_8(&gpio->par_timer, + GPIO_PAR_TMR_TIN0_U2TXD | GPIO_PAR_TMR_TIN1_U2RXD); #endif #ifdef CONFIG_SYS_UART2_ALT1_GPIO - gpio->par_feci2c &= - (GPIO_PAR_FECI2C_MDC_UNMASK | GPIO_PAR_FECI2C_MDIO_UNMASK); - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_MDC_U2TXD | GPIO_PAR_FECI2C_MDIO_U2RXD); + clrbits_8(&gpio->par_feci2c, + ~(GPIO_PAR_FECI2C_MDC_UNMASK | GPIO_PAR_FECI2C_MDIO_UNMASK)); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC_U2TXD | GPIO_PAR_FECI2C_MDIO_U2RXD); #endif #ifdef CONFIG_SYS_UART2_ALT1_GPIO - gpio->par_feci2c &= - (GPIO_PAR_FECI2C_SDA_UNMASK | GPIO_PAR_FECI2C_SCL_UNMASK); - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_SDA_U2TXD | GPIO_PAR_FECI2C_SCL_U2RXD); + clrbits_8(&gpio->par_feci2c, + ~(GPIO_PAR_FECI2C_SDA_UNMASK | GPIO_PAR_FECI2C_SCL_UNMASK)); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SDA_U2TXD | GPIO_PAR_FECI2C_SCL_U2RXD); #endif break; } @@ -175,17 +176,17 @@ void uart_port_conf(int port) #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; if (setclear) { - gpio->par_fec |= - GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC; - gpio->par_feci2c |= - GPIO_PAR_FECI2C_MDC_MDC | GPIO_PAR_FECI2C_MDIO_MDIO; + setbits_8(&gpio->par_fec, + GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC_MDC | GPIO_PAR_FECI2C_MDIO_MDIO); } else { - gpio->par_fec &= - (GPIO_PAR_FEC_7W_UNMASK & GPIO_PAR_FEC_MII_UNMASK); - gpio->par_feci2c &= GPIO_PAR_FECI2C_RMII_UNMASK; + clrbits_8(&gpio->par_fec, + ~(GPIO_PAR_FEC_7W_UNMASK & GPIO_PAR_FEC_MII_UNMASK)); + clrbits_8(&gpio->par_feci2c, ~GPIO_PAR_FECI2C_RMII_UNMASK); } return 0; } @@ -249,17 +250,17 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile u32 *par = (u32 *) MMAP_PAR; + u32 *par = (u32 *) MMAP_PAR; /* Setup Ports: */ switch (port) { case 1: - *par &= 0xFFE7FFFF; - *par |= 0x00180000; + clrbits_be32(par, 0x00180000); + setbits_be32(par, 0x00180000); break; case 2: - *par &= 0xFFFFFFFC; - *par &= 0x00000003; + clrbits_be32(par, 0x00000003); + clrbits_be32(par, 0xFFFFFFFC); break; } } @@ -332,7 +333,20 @@ int fecpin_setclear(struct eth_device *dev, int setclear) return 0; } #endif /* CONFIG_CMD_NET */ -#endif + +#if defined(CONFIG_CF_QSPI) + +/* Configure PIOs for SIN, SOUT, and SCK */ +void cfspi_port_conf(void) +{ + mbar_writeByte(MCF_GPIO_PAR_QSPI, + MCF_GPIO_PAR_QSPI_SIN_SIN | + MCF_GPIO_PAR_QSPI_SOUT_SOUT | + MCF_GPIO_PAR_QSPI_SCK_SCK); +} +#endif /* CONFIG_CF_QSPI */ + +#endif /* CONFIG_M5271 */ #if defined(CONFIG_M5272) /* @@ -348,59 +362,59 @@ void cpu_init_f(void) * already initialized. */ #ifndef CONFIG_MONITOR_IS_IN_RAM - volatile sysctrl_t *sysctrl = (sysctrl_t *) (CONFIG_SYS_MBAR); - volatile gpio_t *gpio = (gpio_t *) (MMAP_GPIO); - volatile csctrl_t *csctrl = (csctrl_t *) (MMAP_FBCS); + sysctrl_t *sysctrl = (sysctrl_t *) (CONFIG_SYS_MBAR); + gpio_t *gpio = (gpio_t *) (MMAP_GPIO); + csctrl_t *csctrl = (csctrl_t *) (MMAP_FBCS); - sysctrl->sc_scr = CONFIG_SYS_SCR; - sysctrl->sc_spr = CONFIG_SYS_SPR; + out_be16(&sysctrl->sc_scr, CONFIG_SYS_SCR); + out_be16(&sysctrl->sc_spr, CONFIG_SYS_SPR); /* Setup Ports: */ - gpio->gpio_pacnt = CONFIG_SYS_PACNT; - gpio->gpio_paddr = CONFIG_SYS_PADDR; - gpio->gpio_padat = CONFIG_SYS_PADAT; - gpio->gpio_pbcnt = CONFIG_SYS_PBCNT; - gpio->gpio_pbddr = CONFIG_SYS_PBDDR; - gpio->gpio_pbdat = CONFIG_SYS_PBDAT; - gpio->gpio_pdcnt = CONFIG_SYS_PDCNT; + out_be32(&gpio->gpio_pacnt, CONFIG_SYS_PACNT); + out_be16(&gpio->gpio_paddr, CONFIG_SYS_PADDR); + out_be16(&gpio->gpio_padat, CONFIG_SYS_PADAT); + out_be32(&gpio->gpio_pbcnt, CONFIG_SYS_PBCNT); + out_be16(&gpio->gpio_pbddr, CONFIG_SYS_PBDDR); + out_be16(&gpio->gpio_pbdat, CONFIG_SYS_PBDAT); + out_be32(&gpio->gpio_pdcnt, CONFIG_SYS_PDCNT); /* Memory Controller: */ - csctrl->cs_br0 = CONFIG_SYS_BR0_PRELIM; - csctrl->cs_or0 = CONFIG_SYS_OR0_PRELIM; + out_be32(&csctrl->cs_br0, CONFIG_SYS_BR0_PRELIM); + out_be32(&csctrl->cs_or0, CONFIG_SYS_OR0_PRELIM); #if (defined(CONFIG_SYS_OR1_PRELIM) && defined(CONFIG_SYS_BR1_PRELIM)) - csctrl->cs_br1 = CONFIG_SYS_BR1_PRELIM; - csctrl->cs_or1 = CONFIG_SYS_OR1_PRELIM; + out_be32(&csctrl->cs_br1, CONFIG_SYS_BR1_PRELIM); + out_be32(&csctrl->cs_or1, CONFIG_SYS_OR1_PRELIM); #endif #if defined(CONFIG_SYS_OR2_PRELIM) && defined(CONFIG_SYS_BR2_PRELIM) - csctrl->cs_br2 = CONFIG_SYS_BR2_PRELIM; - csctrl->cs_or2 = CONFIG_SYS_OR2_PRELIM; + out_be32(&csctrl->cs_br2, CONFIG_SYS_BR2_PRELIM); + out_be32(&csctrl->cs_or2, CONFIG_SYS_OR2_PRELIM); #endif #if defined(CONFIG_SYS_OR3_PRELIM) && defined(CONFIG_SYS_BR3_PRELIM) - csctrl->cs_br3 = CONFIG_SYS_BR3_PRELIM; - csctrl->cs_or3 = CONFIG_SYS_OR3_PRELIM; + out_be32(&csctrl->cs_br3, CONFIG_SYS_BR3_PRELIM); + out_be32(&csctrl->cs_or3, CONFIG_SYS_OR3_PRELIM); #endif #if defined(CONFIG_SYS_OR4_PRELIM) && defined(CONFIG_SYS_BR4_PRELIM) - csctrl->cs_br4 = CONFIG_SYS_BR4_PRELIM; - csctrl->cs_or4 = CONFIG_SYS_OR4_PRELIM; + out_be32(&csctrl->cs_br4, CONFIG_SYS_BR4_PRELIM); + out_be32(&csctrl->cs_or4, CONFIG_SYS_OR4_PRELIM); #endif #if defined(CONFIG_SYS_OR5_PRELIM) && defined(CONFIG_SYS_BR5_PRELIM) - csctrl->cs_br5 = CONFIG_SYS_BR5_PRELIM; - csctrl->cs_or5 = CONFIG_SYS_OR5_PRELIM; + out_be32(&csctrl->cs_br5, CONFIG_SYS_BR5_PRELIM); + out_be32(&csctrl->cs_or5, CONFIG_SYS_OR5_PRELIM); #endif #if defined(CONFIG_SYS_OR6_PRELIM) && defined(CONFIG_SYS_BR6_PRELIM) - csctrl->cs_br6 = CONFIG_SYS_BR6_PRELIM; - csctrl->cs_or6 = CONFIG_SYS_OR6_PRELIM; + out_be32(&csctrl->cs_br6, CONFIG_SYS_BR6_PRELIM); + out_be32(&csctrl->cs_or6, CONFIG_SYS_OR6_PRELIM); #endif #if defined(CONFIG_SYS_OR7_PRELIM) && defined(CONFIG_SYS_BR7_PRELIM) - csctrl->cs_br7 = CONFIG_SYS_BR7_PRELIM; - csctrl->cs_or7 = CONFIG_SYS_OR7_PRELIM; + out_be32(&csctrl->cs_br7, CONFIG_SYS_BR7_PRELIM); + out_be32(&csctrl->cs_or7, CONFIG_SYS_OR7_PRELIM); #endif #endif /* #ifndef CONFIG_MONITOR_IS_IN_RAM */ @@ -420,17 +434,21 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->gpio_pbcnt &= ~(GPIO_PBCNT_PB0MSK | GPIO_PBCNT_PB1MSK); - gpio->gpio_pbcnt |= (GPIO_PBCNT_URT0_TXD | GPIO_PBCNT_URT0_RXD); + clrbits_be32(&gpio->gpio_pbcnt, + GPIO_PBCNT_PB0MSK | GPIO_PBCNT_PB1MSK); + setbits_be32(&gpio->gpio_pbcnt, + GPIO_PBCNT_URT0_TXD | GPIO_PBCNT_URT0_RXD); break; case 1: - gpio->gpio_pdcnt &= ~(GPIO_PDCNT_PD1MSK | GPIO_PDCNT_PD4MSK); - gpio->gpio_pdcnt |= (GPIO_PDCNT_URT1_RXD | GPIO_PDCNT_URT1_TXD); + clrbits_be32(&gpio->gpio_pdcnt, + GPIO_PDCNT_PD1MSK | GPIO_PDCNT_PD4MSK); + setbits_be32(&gpio->gpio_pdcnt, + GPIO_PDCNT_URT1_RXD | GPIO_PDCNT_URT1_TXD); break; } } @@ -438,13 +456,14 @@ void uart_port_conf(int port) #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; if (setclear) { - gpio->gpio_pbcnt |= GPIO_PBCNT_E_MDC | GPIO_PBCNT_E_RXER | - GPIO_PBCNT_E_RXD1 | GPIO_PBCNT_E_RXD2 | - GPIO_PBCNT_E_RXD3 | GPIO_PBCNT_E_TXD1 | - GPIO_PBCNT_E_TXD2 | GPIO_PBCNT_E_TXD3; + setbits_be32(&gpio->gpio_pbcnt, + GPIO_PBCNT_E_MDC | GPIO_PBCNT_E_RXER | + GPIO_PBCNT_E_RXD1 | GPIO_PBCNT_E_RXD2 | + GPIO_PBCNT_E_RXD3 | GPIO_PBCNT_E_TXD1 | + GPIO_PBCNT_E_TXD2 | GPIO_PBCNT_E_TXD3); } else { } return 0; @@ -469,11 +488,11 @@ void cpu_init_f(void) */ #ifndef CONFIG_MONITOR_IS_IN_RAM - volatile wdog_t *wdog_reg = (wdog_t *) (MMAP_WDOG); - volatile gpio_t *gpio_reg = (gpio_t *) (MMAP_GPIO); + wdog_t *wdog_reg = (wdog_t *) (MMAP_WDOG); + gpio_t *gpio_reg = (gpio_t *) (MMAP_GPIO); /* Kill watchdog so we can initialize the PLL */ - wdog_reg->wcr = 0; + out_be16(&wdog_reg->wcr, 0); /* FlexBus Chipselect */ init_fbcs(); @@ -498,21 +517,21 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= ~UART0_ENABLE_MASK; - gpio->par_uart |= UART0_ENABLE_MASK; + clrbits_be16(&gpio->par_uart, UART0_ENABLE_MASK); + setbits_be16(&gpio->par_uart, UART0_ENABLE_MASK); break; case 1: - gpio->par_uart &= ~UART1_ENABLE_MASK; - gpio->par_uart |= UART1_ENABLE_MASK; + clrbits_be16(&gpio->par_uart, UART1_ENABLE_MASK); + setbits_be16(&gpio->par_uart, UART1_ENABLE_MASK); break; case 2: - gpio->par_uart &= ~UART2_ENABLE_MASK; - gpio->par_uart |= UART2_ENABLE_MASK; + clrbits_be16(&gpio->par_uart, UART2_ENABLE_MASK); + setbits_be16(&gpio->par_uart, UART2_ENABLE_MASK); break; } } @@ -521,24 +540,24 @@ void uart_port_conf(int port) int fecpin_setclear(struct eth_device *dev, int setclear) { struct fec_info_s *info = (struct fec_info_s *) dev->priv; - volatile gpio_t *gpio = (gpio_t *)MMAP_GPIO; + gpio_t *gpio = (gpio_t *)MMAP_GPIO; if (setclear) { /* Enable Ethernet pins */ if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { - gpio->par_feci2c |= 0x0F00; - gpio->par_fec0hl |= 0xC0; + setbits_be16(&gpio->par_feci2c, 0x0f00); + setbits_8(&gpio->par_fec0hl, 0xc0); } else { - gpio->par_feci2c |= 0x00A0; - gpio->par_fec1hl |= 0xC0; + setbits_be16(&gpio->par_feci2c, 0x00a0); + setbits_8(&gpio->par_fec1hl, 0xc0); } } else { if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { - gpio->par_feci2c &= ~0x0F00; - gpio->par_fec0hl &= ~0xC0; + clrbits_be16(&gpio->par_feci2c, 0x0f00); + clrbits_8(&gpio->par_fec0hl, 0xc0); } else { - gpio->par_feci2c &= ~0x00A0; - gpio->par_fec1hl &= ~0xC0; + clrbits_be16(&gpio->par_feci2c, 0x00a0); + clrbits_8(&gpio->par_fec1hl, 0xc0); } } diff --git a/arch/m68k/cpu/mcf52x2/interrupts.c b/arch/m68k/cpu/mcf52x2/interrupts.c index dff8c6a..915eb70 100644 --- a/arch/m68k/cpu/mcf52x2/interrupts.c +++ b/arch/m68k/cpu/mcf52x2/interrupts.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,20 +28,22 @@ #include <watchdog.h> #include <asm/processor.h> #include <asm/immap.h> +#include <asm/io.h> #ifdef CONFIG_M5272 int interrupt_init(void) { - volatile intctrl_t *intp = (intctrl_t *) (MMAP_INTC); + intctrl_t *intp = (intctrl_t *) (MMAP_INTC); /* disable all external interrupts */ - intp->int_icr1 = 0x88888888; - intp->int_icr2 = 0x88888888; - intp->int_icr3 = 0x88888888; - intp->int_icr4 = 0x88888888; - intp->int_pitr = 0x00000000; + out_be32(&intp->int_icr1, 0x88888888); + out_be32(&intp->int_icr2, 0x88888888); + out_be32(&intp->int_icr3, 0x88888888); + out_be32(&intp->int_icr4, 0x88888888); + out_be32(&intp->int_pitr, 0x00000000); + /* initialize vector register */ - intp->int_pivr = 0x40; + out_8(&intp->int_pivr, 0x40); enable_interrupts(); @@ -51,10 +53,10 @@ int interrupt_init(void) #if defined(CONFIG_MCFTMR) void dtimer_intr_setup(void) { - volatile intctrl_t *intp = (intctrl_t *) (CONFIG_SYS_INTR_BASE); + intctrl_t *intp = (intctrl_t *) (CONFIG_SYS_INTR_BASE); - intp->int_icr1 &= ~INT_ICR1_TMR3MASK; - intp->int_icr1 |= CONFIG_SYS_TMRINTR_PRI; + clrbits_be32(&intp->int_icr1, INT_ICR1_TMR3MASK); + setbits_be32(&intp->int_icr1, CONFIG_SYS_TMRINTR_PRI); } #endif /* CONFIG_MCFTMR */ #endif /* CONFIG_M5272 */ @@ -63,14 +65,14 @@ void dtimer_intr_setup(void) defined(CONFIG_M5271) || defined(CONFIG_M5275) int interrupt_init(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); /* Make sure all interrupts are disabled */ #if defined(CONFIG_M5208) - intp->imrl0 = 0xFFFFFFFF; - intp->imrh0 = 0xFFFFFFFF; + out_be32(&intp->imrl0, 0xffffffff); + out_be32(&intp->imrh0, 0xffffffff); #else - intp->imrl0 |= 0x1; + setbits_be32(&intp->imrl0, 0x1); #endif enable_interrupts(); @@ -80,11 +82,11 @@ int interrupt_init(void) #if defined(CONFIG_MCFTMR) void dtimer_intr_setup(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); - intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; - intp->imrl0 &= 0xFFFFFFFE; - intp->imrl0 &= ~CONFIG_SYS_TMRINTR_MASK; + out_8(&intp->icr0[CONFIG_SYS_TMRINTR_NO], CONFIG_SYS_TMRINTR_PRI); + clrbits_be32(&intp->imrl0, 0x00000001); + clrbits_be32(&intp->imrl0, CONFIG_SYS_TMRINTR_MASK); } #endif /* CONFIG_MCFTMR */ #endif /* CONFIG_M5282 | CONFIG_M5271 | CONFIG_M5275 */ diff --git a/arch/m68k/cpu/mcf52x2/speed.c b/arch/m68k/cpu/mcf52x2/speed.c index b485e1c..70abed2 100644 --- a/arch/m68k/cpu/mcf52x2/speed.c +++ b/arch/m68k/cpu/mcf52x2/speed.c @@ -2,7 +2,7 @@ * (C) Copyright 2003 * Josef Baumgartner <josef.baumgartner@telex.de> * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * Hayden Fraser (Hayden.Fraser@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include <common.h> #include <asm/processor.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -34,10 +35,10 @@ DECLARE_GLOBAL_DATA_PTR; int get_clocks (void) { #if defined(CONFIG_M5208) - volatile pll_t *pll = (pll_t *) MMAP_PLL; + pll_t *pll = (pll_t *) MMAP_PLL; - pll->odr = CONFIG_SYS_PLL_ODR; - pll->fdr = CONFIG_SYS_PLL_FDR; + out_8(&pll->odr, CONFIG_SYS_PLL_ODR); + out_8(&pll->fdr, CONFIG_SYS_PLL_FDR); #endif #if defined(CONFIG_M5249) || defined(CONFIG_M5253) @@ -70,14 +71,14 @@ int get_clocks (void) #endif /* CONFIG_M5249 || CONFIG_M5253 */ #if defined(CONFIG_M5275) - volatile pll_t *pll = (volatile pll_t *)(MMAP_PLL); + pll_t *pll = (pll_t *)(MMAP_PLL); /* Setup PLL */ - pll->syncr = 0x01080000; - while (!(pll->synsr & FMPLL_SYNSR_LOCK)) + out_be32(&pll->syncr, 0x01080000); + while (!(in_be32(&pll->synsr) & FMPLL_SYNSR_LOCK)) ; - pll->syncr = 0x01000000; - while (!(pll->synsr & FMPLL_SYNSR_LOCK)) + out_be32(&pll->syncr, 0x01000000); + while (!(in_be32(&pll->synsr) & FMPLL_SYNSR_LOCK)) ; #endif diff --git a/arch/m68k/cpu/mcf532x/cpu.c b/arch/m68k/cpu/mcf532x/cpu.c index 3346784..4f160a6 100644 --- a/arch/m68k/cpu/mcf532x/cpu.c +++ b/arch/m68k/cpu/mcf532x/cpu.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2008, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -31,15 +31,16 @@ #include <netdev.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM); + rcm_t *rcm = (rcm_t *) (MMAP_RCM); udelay(1000); - rcm->rcr |= RCM_RCR_SOFTRST; + setbits_8(&rcm->rcr, RCM_RCR_SOFTRST); /* we don't return! */ return 0; @@ -47,14 +48,14 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int checkcpu(void) { - volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + ccm_t *ccm = (ccm_t *) MMAP_CCM; u16 msk; u16 id = 0; u8 ver; puts("CPU: "); - msk = (ccm->cir >> 6); - ver = (ccm->cir & 0x003f); + msk = (in_be16(&ccm->cir) >> 6); + ver = (in_be16(&ccm->cir) & 0x003f); switch (msk) { #ifdef CONFIG_MCF5301x case 0x78: @@ -115,18 +116,20 @@ int checkcpu(void) /* Called by macro WATCHDOG_RESET */ void watchdog_reset(void) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); - wdp->sr = 0x5555; /* Count register */ - wdp->sr = 0xAAAA; /* Count register */ + /* Count register */ + out_be16(&wdp->sr, 0x5555); + out_be16(&wdp->sr, 0xaaaa); } int watchdog_disable(void) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); /* UserManual, once the wdog is disabled, wdog cannot be re-enabled */ - wdp->cr |= WTM_WCR_HALTED; /* halted watchdog timer */ + /* halted watchdog timer */ + setbits_be16(&wdp->cr, WTM_WCR_HALTED); puts("WATCHDOG:disabled\n"); return (0); @@ -134,18 +137,18 @@ int watchdog_disable(void) int watchdog_init(void) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); u32 wdog_module = 0; /* set timeout and enable watchdog */ wdog_module = ((CONFIG_SYS_CLK / 1000) * CONFIG_WATCHDOG_TIMEOUT); #ifdef CONFIG_M5329 - wdp->mr = (wdog_module / 8192); + out_be16(&wdp->mr, wdog_module / 8192); #else - wdp->mr = (wdog_module / 4096); + out_be16(&wdp->mr, wdog_module / 4096); #endif - wdp->cr = WTM_WCR_EN; + out_be16(&wdp->cr, WTM_WCR_EN); puts("WATCHDOG:enabled\n"); return (0); diff --git a/arch/m68k/cpu/mcf532x/cpu_init.c b/arch/m68k/cpu/mcf532x/cpu_init.c index 6f551b6..f571fad 100644 --- a/arch/m68k/cpu/mcf532x/cpu_init.c +++ b/arch/m68k/cpu/mcf532x/cpu_init.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2004-2008 Freescale Semiconductor, Inc. + * (C) Copyright 2004-2008, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,6 +28,7 @@ #include <common.h> #include <watchdog.h> #include <asm/immap.h> +#include <asm/io.h> #if defined(CONFIG_CMD_NET) #include <config.h> @@ -38,72 +39,68 @@ #ifdef CONFIG_MCF5301x void cpu_init_f(void) { - volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - - /* watchdog is enabled by default - disable the watchdog */ -#ifndef CONFIG_WATCHDOG - /*wdog->cr = 0; */ -#endif - - scm1->mpr = 0x77777777; - scm1->pacra = 0; - scm1->pacrb = 0; - scm1->pacrc = 0; - scm1->pacrd = 0; - scm1->pacre = 0; - scm1->pacrf = 0; - scm1->pacrg = 0; + scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + + out_be32(&scm1->mpr, 0x77777777); + out_be32(&scm1->pacra, 0); + out_be32(&scm1->pacrb, 0); + out_be32(&scm1->pacrc, 0); + out_be32(&scm1->pacrd, 0); + out_be32(&scm1->pacre, 0); + out_be32(&scm1->pacrf, 0); + out_be32(&scm1->pacrg, 0); #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) \ && defined(CONFIG_SYS_CS0_CTRL)) - gpio->par_cs |= GPIO_PAR_CS0_CS0; - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS0_CS0); + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #endif #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) \ && defined(CONFIG_SYS_CS1_CTRL)) - gpio->par_cs |= GPIO_PAR_CS1_CS1; - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS1_CS1); + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) \ && defined(CONFIG_SYS_CS2_CTRL)) - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) \ && defined(CONFIG_SYS_CS3_CTRL)) - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) \ && defined(CONFIG_SYS_CS4_CTRL)) - gpio->par_cs |= GPIO_PAR_CS4; - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS4); + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) \ && defined(CONFIG_SYS_CS5_CTRL)) - gpio->par_cs |= GPIO_PAR_CS5; - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS5); + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif #ifdef CONFIG_FSL_I2C - gpio->par_feci2c = GPIO_PAR_FECI2C_SDA_SDA | GPIO_PAR_FECI2C_SCL_SCL; + out_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SDA_SDA | GPIO_PAR_FECI2C_SCL_SCL); #endif icache_enable(); @@ -113,21 +110,21 @@ void cpu_init_f(void) int cpu_init_r(void) { #ifdef CONFIG_MCFFEC - volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + ccm_t *ccm = (ccm_t *) MMAP_CCM; #endif #ifdef CONFIG_MCFRTC - volatile rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE); - volatile rtcex_t *rtcex = (rtcex_t *) & rtc->extended; + rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE); + rtcex_t *rtcex = (rtcex_t *) &rtc->extended; - rtcex->gocu = CONFIG_SYS_RTC_CNT; - rtcex->gocl = CONFIG_SYS_RTC_SETUP; + out_be32(&rtcex->gocu, CONFIG_SYS_RTC_CNT); + out_be32(&rtcex->gocl, CONFIG_SYS_RTC_SETUP); #endif #ifdef CONFIG_MCFFEC if (CONFIG_SYS_FEC0_MIIBASE != CONFIG_SYS_FEC1_MIIBASE) - ccm->misccr |= CCM_MISCCR_FECM; + setbits_be16(&ccm->misccr, CCM_MISCCR_FECM); else - ccm->misccr &= ~CCM_MISCCR_FECM; + clrbits_be16(&ccm->misccr, CCM_MISCCR_FECM); #endif return (0); @@ -135,41 +132,52 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= ~(GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); - gpio->par_uart |= (GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); + clrbits_8(&gpio->par_uart, + GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); + setbits_8(&gpio->par_uart, + GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); break; case 1: #ifdef CONFIG_SYS_UART1_ALT1_GPIO - gpio->par_simp1h &= - ~(GPIO_PAR_SIMP1H_DATA1_UNMASK | - GPIO_PAR_SIMP1H_VEN1_UNMASK); - gpio->par_simp1h |= - (GPIO_PAR_SIMP1H_DATA1_U1TXD | GPIO_PAR_SIMP1H_VEN1_U1RXD); + clrbits_8(&gpio->par_simp1h, + GPIO_PAR_SIMP1H_DATA1_UNMASK | + GPIO_PAR_SIMP1H_VEN1_UNMASK); + setbits_8(&gpio->par_simp1h, + GPIO_PAR_SIMP1H_DATA1_U1TXD | + GPIO_PAR_SIMP1H_VEN1_U1RXD); #elif defined(CONFIG_SYS_UART1_ALT2_GPIO) - gpio->par_ssih &= - ~(GPIO_PAR_SSIH_RXD_UNMASK | GPIO_PAR_SSIH_TXD_UNMASK); - gpio->par_ssih |= - (GPIO_PAR_SSIH_RXD_U1RXD | GPIO_PAR_SSIH_TXD_U1TXD); + clrbits_8(&gpio->par_ssih, + GPIO_PAR_SSIH_RXD_UNMASK | + GPIO_PAR_SSIH_TXD_UNMASK); + setbits_8(&gpio->par_ssih, + GPIO_PAR_SSIH_RXD_U1RXD | + GPIO_PAR_SSIH_TXD_U1TXD); #endif break; case 2: #ifdef CONFIG_SYS_UART2_PRI_GPIO - gpio->par_uart |= (GPIO_PAR_UART_U2TXD | GPIO_PAR_UART_U2RXD); + setbits_8(&gpio->par_uart, + GPIO_PAR_UART_U2TXD | + GPIO_PAR_UART_U2RXD); #elif defined(CONFIG_SYS_UART2_ALT1_GPIO) - gpio->par_dspih &= - ~(GPIO_PAR_DSPIH_SIN_UNMASK | GPIO_PAR_DSPIH_SOUT_UNMASK); - gpio->par_dspih |= - (GPIO_PAR_DSPIH_SIN_U2RXD | GPIO_PAR_DSPIH_SOUT_U2TXD); + clrbits_8(&gpio->par_dspih, + GPIO_PAR_DSPIH_SIN_UNMASK | + GPIO_PAR_DSPIH_SOUT_UNMASK); + setbits_8(&gpio->par_dspih, + GPIO_PAR_DSPIH_SIN_U2RXD | + GPIO_PAR_DSPIH_SOUT_U2TXD); #elif defined(CONFIG_SYS_UART2_ALT2_GPIO) - gpio->par_feci2c &= - ~(GPIO_PAR_FECI2C_SDA_UNMASK | GPIO_PAR_FECI2C_SCL_UNMASK); - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_SDA_U2TXD | GPIO_PAR_FECI2C_SCL_U2RXD); + clrbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SDA_UNMASK | + GPIO_PAR_FECI2C_SCL_UNMASK); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SDA_U2TXD | + GPIO_PAR_FECI2C_SCL_U2RXD); #endif break; } @@ -178,30 +186,30 @@ void uart_port_conf(int port) #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; struct fec_info_s *info = (struct fec_info_s *)dev->priv; if (setclear) { if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { - gpio->par_fec |= - GPIO_PAR_FEC0_7W_FEC | GPIO_PAR_FEC0_RMII_FEC; - gpio->par_feci2c |= - GPIO_PAR_FECI2C_MDC0 | GPIO_PAR_FECI2C_MDIO0; + setbits_8(&gpio->par_fec, + GPIO_PAR_FEC0_7W_FEC | GPIO_PAR_FEC0_RMII_FEC); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC0 | GPIO_PAR_FECI2C_MDIO0); } else { - gpio->par_fec |= - GPIO_PAR_FEC1_7W_FEC | GPIO_PAR_FEC1_RMII_FEC; - gpio->par_feci2c |= - GPIO_PAR_FECI2C_MDC1 | GPIO_PAR_FECI2C_MDIO1; + setbits_8(&gpio->par_fec, + GPIO_PAR_FEC1_7W_FEC | GPIO_PAR_FEC1_RMII_FEC); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC1 | GPIO_PAR_FECI2C_MDIO1); } } else { if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { - gpio->par_fec &= - ~(GPIO_PAR_FEC0_7W_FEC | GPIO_PAR_FEC0_RMII_FEC); - gpio->par_feci2c &= GPIO_PAR_FECI2C_RMII0_UNMASK; + clrbits_8(&gpio->par_fec, + GPIO_PAR_FEC0_7W_FEC | GPIO_PAR_FEC0_RMII_FEC); + clrbits_8(&gpio->par_feci2c, ~GPIO_PAR_FECI2C_RMII0_UNMASK); } else { - gpio->par_fec &= - ~(GPIO_PAR_FEC1_7W_FEC | GPIO_PAR_FEC1_RMII_FEC); - gpio->par_feci2c &= GPIO_PAR_FECI2C_RMII1_UNMASK; + clrbits_8(&gpio->par_fec, + GPIO_PAR_FEC1_7W_FEC | GPIO_PAR_FEC1_RMII_FEC); + clrbits_8(&gpio->par_feci2c, ~GPIO_PAR_FECI2C_RMII1_UNMASK); } } return 0; @@ -212,80 +220,81 @@ int fecpin_setclear(struct eth_device *dev, int setclear) #ifdef CONFIG_MCF532x void cpu_init_f(void) { - volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; - volatile scm2_t *scm2 = (scm2_t *) MMAP_SCM2; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - volatile wdog_t *wdog = (wdog_t *) MMAP_WDOG; + scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + scm2_t *scm2 = (scm2_t *) MMAP_SCM2; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + wdog_t *wdog = (wdog_t *) MMAP_WDOG; /* watchdog is enabled by default - disable the watchdog */ #ifndef CONFIG_WATCHDOG - wdog->cr = 0; + out_be16(&wdog->cr, 0); #endif - scm1->mpr0 = 0x77777777; - scm2->pacra = 0; - scm2->pacrb = 0; - scm2->pacrc = 0; - scm2->pacrd = 0; - scm2->pacre = 0; - scm2->pacrf = 0; - scm2->pacrg = 0; - scm1->pacrh = 0; + out_be32(&scm1->mpr0, 0x77777777); + out_be32(&scm2->pacra, 0); + out_be32(&scm2->pacrb, 0); + out_be32(&scm2->pacrc, 0); + out_be32(&scm2->pacrd, 0); + out_be32(&scm2->pacre, 0); + out_be32(&scm2->pacrf, 0); + out_be32(&scm2->pacrg, 0); + out_be32(&scm1->pacrh, 0); /* Port configuration */ - gpio->par_cs = 0; + out_8(&gpio->par_cs, 0); #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) \ && defined(CONFIG_SYS_CS0_CTRL)) - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #endif #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) \ && defined(CONFIG_SYS_CS1_CTRL)) /* Latch chipselect */ - gpio->par_cs |= GPIO_PAR_CS1; - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS1); + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) \ && defined(CONFIG_SYS_CS2_CTRL)) - gpio->par_cs |= GPIO_PAR_CS2; - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS2); + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) \ && defined(CONFIG_SYS_CS3_CTRL)) - gpio->par_cs |= GPIO_PAR_CS3; - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS3); + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) \ && defined(CONFIG_SYS_CS4_CTRL)) - gpio->par_cs |= GPIO_PAR_CS4; - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS4); + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) \ && defined(CONFIG_SYS_CS5_CTRL)) - gpio->par_cs |= GPIO_PAR_CS5; - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS5); + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif #ifdef CONFIG_FSL_I2C - gpio->par_feci2c = GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA; + out_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA); #endif icache_enable(); @@ -301,30 +310,35 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= ~(GPIO_PAR_UART_TXD0 | GPIO_PAR_UART_RXD0); - gpio->par_uart |= (GPIO_PAR_UART_TXD0 | GPIO_PAR_UART_RXD0); + clrbits_be16(&gpio->par_uart, + GPIO_PAR_UART_TXD0 | GPIO_PAR_UART_RXD0); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_TXD0 | GPIO_PAR_UART_RXD0); break; case 1: - gpio->par_uart &= - ~(GPIO_PAR_UART_TXD1(3) | GPIO_PAR_UART_RXD1(3)); - gpio->par_uart |= - (GPIO_PAR_UART_TXD1(3) | GPIO_PAR_UART_RXD1(3)); + clrbits_be16(&gpio->par_uart, + GPIO_PAR_UART_TXD1(3) | GPIO_PAR_UART_RXD1(3)); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_TXD1(3) | GPIO_PAR_UART_RXD1(3)); break; case 2: #ifdef CONFIG_SYS_UART2_ALT1_GPIO - gpio->par_timer &= 0x0F; - gpio->par_timer |= (GPIO_PAR_TIN3_URXD2 | GPIO_PAR_TIN2_UTXD2); + clrbits_8(&gpio->par_timer, 0xf0); + setbits_8(&gpio->par_timer, + GPIO_PAR_TIN3_URXD2 | GPIO_PAR_TIN2_UTXD2); #elif defined(CONFIG_SYS_UART2_ALT2_GPIO) - gpio->par_feci2c &= 0xFF00; - gpio->par_feci2c |= (GPIO_PAR_FECI2C_SCL_UTXD2 | GPIO_PAR_FECI2C_SDA_URXD2); + clrbits_8(&gpio->par_feci2c, 0x00ff); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SCL_UTXD2 | GPIO_PAR_FECI2C_SDA_URXD2); #elif defined(CONFIG_SYS_UART2_ALT3_GPIO) - gpio->par_ssi &= 0xF0FF; - gpio->par_ssi |= (GPIO_PAR_SSI_RXD(2) | GPIO_PAR_SSI_TXD(2)); + clrbits_be16(&gpio->par_ssi, 0x0f00); + setbits_be16(&gpio->par_ssi, + GPIO_PAR_SSI_RXD(2) | GPIO_PAR_SSI_TXD(2)); #endif break; } @@ -333,16 +347,18 @@ void uart_port_conf(int port) #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; if (setclear) { - gpio->par_fec |= GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC; - gpio->par_feci2c |= - GPIO_PAR_FECI2C_MDC_EMDC | GPIO_PAR_FECI2C_MDIO_EMDIO; + setbits_8(&gpio->par_fec, + GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC_EMDC | GPIO_PAR_FECI2C_MDIO_EMDIO); } else { - gpio->par_fec &= ~(GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC); - gpio->par_feci2c &= - ~(GPIO_PAR_FECI2C_MDC_EMDC | GPIO_PAR_FECI2C_MDIO_EMDIO); + clrbits_8(&gpio->par_fec, + GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC); + clrbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC_EMDC | GPIO_PAR_FECI2C_MDIO_EMDIO); } return 0; } diff --git a/arch/m68k/cpu/mcf532x/interrupts.c b/arch/m68k/cpu/mcf532x/interrupts.c index d6c8205..d1ea2ff 100644 --- a/arch/m68k/cpu/mcf532x/interrupts.c +++ b/arch/m68k/cpu/mcf532x/interrupts.c @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -25,14 +25,15 @@ /* CPU specific interrupt routine */ #include <common.h> #include <asm/immap.h> +#include <asm/io.h> int interrupt_init(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); /* Make sure all interrupts are disabled */ - intp->imrh0 |= 0xFFFFFFFF; - intp->imrl0 |= 0xFFFFFFFF; + setbits_be32(&intp->imrh0, 0xffffffff); + setbits_be32(&intp->imrl0, 0xffffffff); enable_interrupts(); return 0; @@ -41,9 +42,9 @@ int interrupt_init(void) #if defined(CONFIG_MCFTMR) void dtimer_intr_setup(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); - intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; - intp->imrh0 &= ~CONFIG_SYS_TMRINTR_MASK; + out_8(&intp->icr0[CONFIG_SYS_TMRINTR_NO], CONFIG_SYS_TMRINTR_PRI); + clrbits_be32(&intp->imrh0, CONFIG_SYS_TMRINTR_MASK); } #endif diff --git a/arch/m68k/cpu/mcf532x/speed.c b/arch/m68k/cpu/mcf532x/speed.c index 5a29e25..cfdcc8b 100644 --- a/arch/m68k/cpu/mcf532x/speed.c +++ b/arch/m68k/cpu/mcf532x/speed.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2008, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -29,6 +29,7 @@ #include <asm/processor.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -65,13 +66,13 @@ DECLARE_GLOBAL_DATA_PTR; /* Get the value of the current system clock */ int get_sys_clock(void) { - volatile ccm_t *ccm = (volatile ccm_t *)(MMAP_CCM); - volatile pll_t *pll = (volatile pll_t *)(MMAP_PLL); + ccm_t *ccm = (ccm_t *)(MMAP_CCM); + pll_t *pll = (pll_t *)(MMAP_PLL); int divider; /* Test to see if device is in LIMP mode */ - if (ccm->misccr & CCM_MISCCR_LIMP) { - divider = ccm->cdr & CCM_CDR_LPDIV(0xF); + if (in_be16(&ccm->misccr) & CCM_MISCCR_LIMP) { + divider = in_be16(&ccm->cdr) & CCM_CDR_LPDIV(0xF); #ifdef CONFIG_MCF5301x return (FREF / (3 * (1 << divider))); #endif @@ -80,14 +81,14 @@ int get_sys_clock(void) #endif } else { #ifdef CONFIG_MCF5301x - u32 pfdr = (pll->pcr & 0x3F) + 1; - u32 refdiv = (1 << ((pll->pcr & PLL_PCR_REFDIV(7)) >> 8)); - u32 busdiv = ((pll->pdr & 0x00F0) >> 4) + 1; + u32 pfdr = (in_be32(&pll->pcr) & 0x3F) + 1; + u32 refdiv = (1 << ((in_be32(&pll->pcr) & PLL_PCR_REFDIV(7)) >> 8)); + u32 busdiv = ((in_be32(&pll->pdr) & 0x00F0) >> 4) + 1; return (((FREF * pfdr) / refdiv) / busdiv); #endif #ifdef CONFIG_MCF532x - return ((FREF * pll->pfdr) / (BUSDIV * 4)); + return (FREF * in_8(&pll->pfdr)) / (BUSDIV * 4); #endif } } @@ -103,7 +104,7 @@ int get_sys_clock(void) */ int clock_limp(int div) { - volatile ccm_t *ccm = (volatile ccm_t *)(MMAP_CCM); + ccm_t *ccm = (ccm_t *)(MMAP_CCM); u32 temp; /* Check bounds of divider */ @@ -113,12 +114,12 @@ int clock_limp(int div) div = MAX_LPD; /* Save of the current value of the SSIDIV so we don't overwrite the value */ - temp = (ccm->cdr & CCM_CDR_SSIDIV(0xFF)); + temp = (in_be16(&ccm->cdr) & CCM_CDR_SSIDIV(0xFF)); /* Apply the divider to the system clock */ - ccm->cdr = (CCM_CDR_LPDIV(div) | CCM_CDR_SSIDIV(temp)); + out_be16(&ccm->cdr, CCM_CDR_LPDIV(div) | CCM_CDR_SSIDIV(temp)); - ccm->misccr |= CCM_MISCCR_LIMP; + setbits_be16(&ccm->misccr, CCM_MISCCR_LIMP); return (FREF / (3 * (1 << div))); } @@ -126,14 +127,15 @@ int clock_limp(int div) /* Exit low power LIMP mode */ int clock_exit_limp(void) { - volatile ccm_t *ccm = (volatile ccm_t *)(MMAP_CCM); + ccm_t *ccm = (ccm_t *)(MMAP_CCM); int fout; /* Exit LIMP mode */ - ccm->misccr &= (~CCM_MISCCR_LIMP); + clrbits_be16(&ccm->misccr, CCM_MISCCR_LIMP); /* Wait for PLL to lock */ - while (!(ccm->misccr & CCM_MISCCR_PLL_LOCK)) ; + while (!(in_be16(&ccm->misccr) & CCM_MISCCR_PLL_LOCK)) + ; fout = get_sys_clock(); @@ -153,10 +155,10 @@ int clock_exit_limp(void) int clock_pll(int fsys, int flags) { #ifdef CONFIG_MCF532x - volatile u32 *sdram_workaround = (volatile u32 *)(MMAP_SDRAM + 0x80); + u32 *sdram_workaround = (u32 *)(MMAP_SDRAM + 0x80); #endif - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); - volatile pll_t *pll = (volatile pll_t *)(MMAP_PLL); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); + pll_t *pll = (pll_t *)(MMAP_PLL); int fref, temp, fout, mfd; u32 i; @@ -165,13 +167,13 @@ int clock_pll(int fsys, int flags) if (fsys == 0) { /* Return current PLL output */ #ifdef CONFIG_MCF5301x - u32 busdiv = ((pll->pdr >> 4) & 0x0F) + 1; - mfd = (pll->pcr & 0x3F) + 1; + u32 busdiv = ((in_be32(&pll->pdr) >> 4) & 0x0F) + 1; + mfd = (in_be32(&pll->pcr) & 0x3F) + 1; return (fref * mfd) / busdiv; #endif #ifdef CONFIG_MCF532x - mfd = pll->pfdr; + mfd = in_8(&pll->pfdr); return (fref * mfd / (BUSDIV * 4)); #endif @@ -211,8 +213,8 @@ int clock_pll(int fsys, int flags) * If it has then the SDRAM needs to be put into self refresh * mode before reprogramming the PLL. */ - if (sdram->ctrl & SDRAMC_SDCR_REF) - sdram->ctrl &= ~SDRAMC_SDCR_CKE; + if (in_be32(&sdram->ctrl) & SDRAMC_SDCR_REF) + clrbits_be32(&sdram->ctrl, SDRAMC_SDCR_CKE); /* * Initialize the PLL to generate the new system clock frequency. @@ -223,35 +225,36 @@ int clock_pll(int fsys, int flags) clock_limp(DEFAULT_LPD); #ifdef CONFIG_MCF5301x - pll->pdr = - PLL_PDR_OUTDIV1((BUSDIV / 3) - 1) | - PLL_PDR_OUTDIV2(BUSDIV - 1) | - PLL_PDR_OUTDIV3((BUSDIV / 2) - 1) | - PLL_PDR_OUTDIV4(USBDIV - 1); - - pll->pcr &= PLL_PCR_FBDIV_UNMASK; - pll->pcr |= PLL_PCR_FBDIV(mfd - 1); + out_be32(&pll->pdr, + PLL_PDR_OUTDIV1((BUSDIV / 3) - 1) | + PLL_PDR_OUTDIV2(BUSDIV - 1) | + PLL_PDR_OUTDIV3((BUSDIV / 2) - 1) | + PLL_PDR_OUTDIV4(USBDIV - 1)); + + clrbits_be32(&pll->pcr, ~PLL_PCR_FBDIV_UNMASK); + setbits_be32(&pll->pcr, PLL_PCR_FBDIV(mfd - 1)); #endif #ifdef CONFIG_MCF532x /* Reprogram PLL for desired fsys */ - pll->podr = (PLL_PODR_CPUDIV(BUSDIV / 3) | PLL_PODR_BUSDIV(BUSDIV)); + out_8(&pll->podr, + PLL_PODR_CPUDIV(BUSDIV / 3) | PLL_PODR_BUSDIV(BUSDIV)); - pll->pfdr = mfd; + out_8(&pll->pfdr, mfd); #endif /* Exit LIMP mode */ clock_exit_limp(); /* Return the SDRAM to normal operation if it is in use. */ - if (sdram->ctrl & SDRAMC_SDCR_REF) - sdram->ctrl |= SDRAMC_SDCR_CKE; + if (in_be32(&sdram->ctrl) & SDRAMC_SDCR_REF) + setbits_be32(&sdram->ctrl, SDRAMC_SDCR_CKE); #ifdef CONFIG_MCF532x /* * software workaround for SDRAM opeartion after exiting LIMP * mode errata */ - *sdram_workaround = CONFIG_SYS_SDRAM_BASE; + out_be32(sdram_workaround, CONFIG_SYS_SDRAM_BASE); #endif /* wait for DQS logic to relock */ diff --git a/arch/m68k/cpu/mcf5445x/cpu.c b/arch/m68k/cpu/mcf5445x/cpu.c index 323a54e..adfc708 100644 --- a/arch/m68k/cpu/mcf5445x/cpu.c +++ b/arch/m68k/cpu/mcf5445x/cpu.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -31,14 +31,15 @@ #include <netdev.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM); + rcm_t *rcm = (rcm_t *) (MMAP_RCM); udelay(1000); - rcm->rcr |= RCM_RCR_SOFTRST; + setbits_8(&rcm->rcr, RCM_RCR_SOFTRST); /* we don't return! */ return 0; @@ -46,14 +47,14 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int checkcpu(void) { - volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + ccm_t *ccm = (ccm_t *) MMAP_CCM; u16 msk; u16 id = 0; u8 ver; puts("CPU: "); - msk = (ccm->cir >> 6); - ver = (ccm->cir & 0x003f); + msk = (in_be16(&ccm->cir) >> 6); + ver = (in_be16(&ccm->cir) & 0x003f); switch (msk) { case 0x48: id = 54455; diff --git a/arch/m68k/cpu/mcf5445x/cpu_init.c b/arch/m68k/cpu/mcf5445x/cpu_init.c index fdcd185..3f9209f 100644 --- a/arch/m68k/cpu/mcf5445x/cpu_init.c +++ b/arch/m68k/cpu/mcf5445x/cpu_init.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2004-2007 Freescale Semiconductor, Inc. + * (C) Copyright 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -30,6 +30,7 @@ #include <asm/immap.h> #include <asm/processor.h> #include <asm/rtc.h> +#include <asm/io.h> #if defined(CONFIG_CMD_NET) #include <config.h> @@ -46,64 +47,64 @@ */ void cpu_init_f(void) { - volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - - scm1->mpr = 0x77777777; - scm1->pacra = 0; - scm1->pacrb = 0; - scm1->pacrc = 0; - scm1->pacrd = 0; - scm1->pacre = 0; - scm1->pacrf = 0; - scm1->pacrg = 0; + scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + + out_be32(&scm1->mpr, 0x77777777); + out_be32(&scm1->pacra, 0); + out_be32(&scm1->pacrb, 0); + out_be32(&scm1->pacrc, 0); + out_be32(&scm1->pacrd, 0); + out_be32(&scm1->pacre, 0); + out_be32(&scm1->pacrf, 0); + out_be32(&scm1->pacrg, 0); /* FlexBus */ - gpio->par_be = - GPIO_PAR_BE_BE3_BE3 | GPIO_PAR_BE_BE2_BE2 | GPIO_PAR_BE_BE1_BE1 | - GPIO_PAR_BE_BE0_BE0; - gpio->par_fbctl = - GPIO_PAR_FBCTL_OE | GPIO_PAR_FBCTL_TA_TA | GPIO_PAR_FBCTL_RW_RW | - GPIO_PAR_FBCTL_TS_TS; + out_8(&gpio->par_be, + GPIO_PAR_BE_BE3_BE3 | GPIO_PAR_BE_BE2_BE2 | + GPIO_PAR_BE_BE1_BE1 | GPIO_PAR_BE_BE0_BE0); + out_8(&gpio->par_fbctl, + GPIO_PAR_FBCTL_OE | GPIO_PAR_FBCTL_TA_TA | + GPIO_PAR_FBCTL_RW_RW | GPIO_PAR_FBCTL_TS_TS); #if !defined(CONFIG_CF_SBF) #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) && defined(CONFIG_SYS_CS0_CTRL)) - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #endif #endif #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) && defined(CONFIG_SYS_CS1_CTRL)) /* Latch chipselect */ - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) && defined(CONFIG_SYS_CS2_CTRL)) - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) && defined(CONFIG_SYS_CS3_CTRL)) - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) && defined(CONFIG_SYS_CS4_CTRL)) - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) && defined(CONFIG_SYS_CS5_CTRL)) - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif /* @@ -115,7 +116,8 @@ void cpu_init_f(void) setvbr(CONFIG_SYS_CS0_BASE); #ifdef CONFIG_FSL_I2C - gpio->par_feci2c = GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA; + out_be16(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA); #endif icache_enable(); @@ -127,11 +129,11 @@ void cpu_init_f(void) int cpu_init_r(void) { #ifdef CONFIG_MCFRTC - volatile rtc_t *rtc = (volatile rtc_t *)(CONFIG_SYS_MCFRTC_BASE); - volatile rtcex_t *rtcex = (volatile rtcex_t *)&rtc->extended; + rtc_t *rtc = (rtc_t *)(CONFIG_SYS_MCFRTC_BASE); + rtcex_t *rtcex = (rtcex_t *)&rtc->extended; - rtcex->gocu = (CONFIG_SYS_RTC_OSCILLATOR >> 16) & 0xFFFF; - rtcex->gocl = CONFIG_SYS_RTC_OSCILLATOR & 0xFFFF; + out_be32(&rtcex->gocu, (CONFIG_SYS_RTC_OSCILLATOR >> 16) & 0xffff); + out_be32(&rtcex->gocl, CONFIG_SYS_RTC_OSCILLATOR & 0xffff); #endif return (0); @@ -139,40 +141,40 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= - ~(GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); - gpio->par_uart |= - (GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); + clrbits_8(&gpio->par_uart, + GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); + setbits_8(&gpio->par_uart, + GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); break; case 1: #ifdef CONFIG_SYS_UART1_PRI_GPIO - gpio->par_uart &= - ~(GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); - gpio->par_uart |= - (GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); + clrbits_8(&gpio->par_uart, + GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); + setbits_8(&gpio->par_uart, + GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); #elif defined(CONFIG_SYS_UART1_ALT1_GPIO) - gpio->par_ssi &= - (GPIO_PAR_SSI_SRXD_UNMASK | GPIO_PAR_SSI_STXD_UNMASK); - gpio->par_ssi |= - (GPIO_PAR_SSI_SRXD_U1RXD | GPIO_PAR_SSI_STXD_U1TXD); + clrbits_be16(&gpio->par_ssi, + ~(GPIO_PAR_SSI_SRXD_UNMASK | GPIO_PAR_SSI_STXD_UNMASK)); + setbits_be16(&gpio->par_ssi, + GPIO_PAR_SSI_SRXD_U1RXD | GPIO_PAR_SSI_STXD_U1TXD); #endif break; case 2: #if defined(CONFIG_SYS_UART2_ALT1_GPIO) - gpio->par_timer &= - (GPIO_PAR_TIMER_T3IN_UNMASK | GPIO_PAR_TIMER_T2IN_UNMASK); - gpio->par_timer |= - (GPIO_PAR_TIMER_T3IN_U2RXD | GPIO_PAR_TIMER_T2IN_U2TXD); + clrbits_8(&gpio->par_timer, + ~(GPIO_PAR_TIMER_T3IN_UNMASK | GPIO_PAR_TIMER_T2IN_UNMASK)); + setbits_8(&gpio->par_timer, + GPIO_PAR_TIMER_T3IN_U2RXD | GPIO_PAR_TIMER_T2IN_U2TXD); #elif defined(CONFIG_SYS_UART2_ALT2_GPIO) - gpio->par_timer &= - (GPIO_PAR_FECI2C_SCL_UNMASK | GPIO_PAR_FECI2C_SDA_UNMASK); - gpio->par_timer |= - (GPIO_PAR_FECI2C_SCL_U2TXD | GPIO_PAR_FECI2C_SDA_U2RXD); + clrbits_8(&gpio->par_timer, + ~(GPIO_PAR_FECI2C_SCL_UNMASK | GPIO_PAR_FECI2C_SDA_UNMASK)); + setbits_8(&gpio->par_timer, + GPIO_PAR_FECI2C_SCL_U2TXD | GPIO_PAR_FECI2C_SDA_U2RXD); #endif break; } @@ -181,43 +183,43 @@ void uart_port_conf(int port) #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; struct fec_info_s *info = (struct fec_info_s *)dev->priv; if (setclear) { #ifdef CONFIG_SYS_FEC_NO_SHARED_PHY if (info->iobase == CONFIG_SYS_FEC0_IOBASE) - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_MDC0_MDC0 | - GPIO_PAR_FECI2C_MDIO0_MDIO0); + setbits_be16(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC0_MDC0 | + GPIO_PAR_FECI2C_MDIO0_MDIO0); else - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_MDC1_MDC1 | - GPIO_PAR_FECI2C_MDIO1_MDIO1); + setbits_be16(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC1_MDC1 | + GPIO_PAR_FECI2C_MDIO1_MDIO1); #else - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_MDC0_MDC0 | GPIO_PAR_FECI2C_MDIO0_MDIO0); + setbits_be16(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC0_MDC0 | GPIO_PAR_FECI2C_MDIO0_MDIO0); #endif if (info->iobase == CONFIG_SYS_FEC0_IOBASE) - gpio->par_fec |= GPIO_PAR_FEC_FEC0_RMII_GPIO; + setbits_8(&gpio->par_fec, GPIO_PAR_FEC_FEC0_RMII_GPIO); else - gpio->par_fec |= GPIO_PAR_FEC_FEC1_RMII_ATA; + setbits_8(&gpio->par_fec, GPIO_PAR_FEC_FEC1_RMII_ATA); } else { - gpio->par_feci2c &= - ~(GPIO_PAR_FECI2C_MDC0_MDC0 | GPIO_PAR_FECI2C_MDIO0_MDIO0); + clrbits_be16(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC0_MDC0 | GPIO_PAR_FECI2C_MDIO0_MDIO0); if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { #ifdef CONFIG_SYS_FEC_FULL_MII - gpio->par_fec |= GPIO_PAR_FEC_FEC0_MII; + setbits_8(&gpio->par_fec, GPIO_PAR_FEC_FEC0_MII); #else - gpio->par_fec &= GPIO_PAR_FEC_FEC0_UNMASK; + clrbits_8(&gpio->par_fec, ~GPIO_PAR_FEC_FEC0_UNMASK); #endif } else { #ifdef CONFIG_SYS_FEC_FULL_MII - gpio->par_fec |= GPIO_PAR_FEC_FEC1_MII; + setbits_8(&gpio->par_fec, GPIO_PAR_FEC_FEC1_MII); #else - gpio->par_fec &= GPIO_PAR_FEC_FEC1_UNMASK; + clrbits_8(&gpio->par_fec, ~GPIO_PAR_FEC_FEC1_UNMASK); #endif } } @@ -228,43 +230,45 @@ int fecpin_setclear(struct eth_device *dev, int setclear) #ifdef CONFIG_CF_DSPI void cfspi_port_conf(void) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; - gpio->par_dspi = GPIO_PAR_DSPI_SIN_SIN | GPIO_PAR_DSPI_SOUT_SOUT | - GPIO_PAR_DSPI_SCK_SCK; + out_8(&gpio->par_dspi, + GPIO_PAR_DSPI_SIN_SIN | + GPIO_PAR_DSPI_SOUT_SOUT | + GPIO_PAR_DSPI_SCK_SCK); } int cfspi_claim_bus(uint bus, uint cs) { - volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + dspi_t *dspi = (dspi_t *) MMAP_DSPI; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; - if ((dspi->sr & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) + if ((in_be32(&dspi->sr) & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) return -1; /* Clear FIFO and resume transfer */ - dspi->mcr &= ~(DSPI_MCR_CTXF | DSPI_MCR_CRXF); + clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF); switch (cs) { case 0: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0; - gpio->par_dspi |= GPIO_PAR_DSPI_PCS0_PCS0; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0); + setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0); break; case 1: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS1_PCS1; - gpio->par_dspi |= GPIO_PAR_DSPI_PCS1_PCS1; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS1_PCS1); + setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS1_PCS1); break; case 2: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS2_PCS2; - gpio->par_dspi |= GPIO_PAR_DSPI_PCS2_PCS2; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS2_PCS2); + setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS2_PCS2); break; case 3: - gpio->par_dma &= GPIO_PAR_DMA_DACK0_UNMASK; - gpio->par_dma |= GPIO_PAR_DMA_DACK0_PCS3; + clrbits_8(&gpio->par_dma, ~GPIO_PAR_DMA_DACK0_UNMASK); + setbits_8(&gpio->par_dma, GPIO_PAR_DMA_DACK0_PCS3); break; case 5: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS5_PCS5; - gpio->par_dspi |= GPIO_PAR_DSPI_PCS5_PCS5; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS5_PCS5); + setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS5_PCS5); break; } @@ -273,26 +277,27 @@ int cfspi_claim_bus(uint bus, uint cs) void cfspi_release_bus(uint bus, uint cs) { - volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + dspi_t *dspi = (dspi_t *) MMAP_DSPI; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; - dspi->mcr &= ~(DSPI_MCR_CTXF | DSPI_MCR_CRXF); /* Clear FIFO */ + /* Clear FIFO */ + clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF); switch (cs) { case 0: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0); break; case 1: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS1_PCS1; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS1_PCS1); break; case 2: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS2_PCS2; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS2_PCS2); break; case 3: - gpio->par_dma &= GPIO_PAR_DMA_DACK0_UNMASK; + clrbits_8(&gpio->par_dma, ~GPIO_PAR_DMA_DACK0_UNMASK); break; case 5: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS5_PCS5; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS5_PCS5); break; } } diff --git a/arch/m68k/cpu/mcf5445x/interrupts.c b/arch/m68k/cpu/mcf5445x/interrupts.c index 85828a6..a2cf519 100644 --- a/arch/m68k/cpu/mcf5445x/interrupts.c +++ b/arch/m68k/cpu/mcf5445x/interrupts.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,14 +28,15 @@ /* CPU specific interrupt routine */ #include <common.h> #include <asm/immap.h> +#include <asm/io.h> int interrupt_init(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); /* Make sure all interrupts are disabled */ - intp->imrh0 |= 0xFFFFFFFF; - intp->imrl0 |= 0xFFFFFFFF; + setbits_be32(&intp->imrh0, 0xffffffff); + setbits_be32(&intp->imrl0, 0xffffffff); enable_interrupts(); return 0; @@ -44,9 +45,9 @@ int interrupt_init(void) #if defined(CONFIG_MCFTMR) void dtimer_intr_setup(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); - intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; - intp->imrh0 &= ~CONFIG_SYS_TMRINTR_MASK; + out_8(&intp->icr0[CONFIG_SYS_TMRINTR_NO], CONFIG_SYS_TMRINTR_PRI); + clrbits_be32(&intp->imrh0, CONFIG_SYS_TMRINTR_MASK); } #endif diff --git a/arch/m68k/cpu/mcf5445x/pci.c b/arch/m68k/cpu/mcf5445x/pci.c index 7f9784c..c32fcee 100644 --- a/arch/m68k/cpu/mcf5445x/pci.c +++ b/arch/m68k/cpu/mcf5445x/pci.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -60,78 +60,82 @@ PCI_OP(write, dword, u32, out_le32, 0) void pci_mcf5445x_init(struct pci_controller *hose) { - volatile pci_t *pci = (volatile pci_t *)MMAP_PCI; - volatile pciarb_t *pciarb = (volatile pciarb_t *)MMAP_PCIARB; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + pci_t *pci = (pci_t *)MMAP_PCI; + pciarb_t *pciarb = (pciarb_t *)MMAP_PCIARB; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; u32 barEn = 0; - pciarb->acr = 0x001F001F; + out_be32(&pciarb->acr, 0x001f001f); /* Set PCIGNT1, PCIREQ1, PCIREQ0/PCIGNTIN, PCIGNT0/PCIREQOUT, PCIREQ2, PCIGNT2 */ - gpio->par_pci = - GPIO_PAR_PCI_GNT3_GNT3 | GPIO_PAR_PCI_GNT2 | GPIO_PAR_PCI_GNT1 | - GPIO_PAR_PCI_GNT0 | GPIO_PAR_PCI_REQ3_REQ3 | GPIO_PAR_PCI_REQ2 | - GPIO_PAR_PCI_REQ1 | GPIO_PAR_PCI_REQ0; + out_be16(&gpio->par_pci, + GPIO_PAR_PCI_GNT3_GNT3 | GPIO_PAR_PCI_GNT2 | + GPIO_PAR_PCI_GNT1 | GPIO_PAR_PCI_GNT0 | + GPIO_PAR_PCI_REQ3_REQ3 | GPIO_PAR_PCI_REQ2 | + GPIO_PAR_PCI_REQ1 | GPIO_PAR_PCI_REQ0); /* Assert reset bit */ - pci->gscr |= PCI_GSCR_PR; + setbits_be32(&pci->gscr, PCI_GSCR_PR); - pci->tcr1 |= PCI_TCR1_P; + setbits_be32(&pci->tcr1, PCI_TCR1_P); /* Initiator windows */ - pci->iw0btar = CONFIG_SYS_PCI_MEM_PHYS | (CONFIG_SYS_PCI_MEM_PHYS >> 16); - pci->iw1btar = CONFIG_SYS_PCI_IO_PHYS | (CONFIG_SYS_PCI_IO_PHYS >> 16); - pci->iw2btar = CONFIG_SYS_PCI_CFG_PHYS | (CONFIG_SYS_PCI_CFG_PHYS >> 16); + out_be32(&pci->iw0btar, + CONFIG_SYS_PCI_MEM_PHYS | (CONFIG_SYS_PCI_MEM_PHYS >> 16)); + out_be32(&pci->iw1btar, + CONFIG_SYS_PCI_IO_PHYS | (CONFIG_SYS_PCI_IO_PHYS >> 16)); + out_be32(&pci->iw2btar, + CONFIG_SYS_PCI_CFG_PHYS | (CONFIG_SYS_PCI_CFG_PHYS >> 16)); - pci->iwcr = - PCI_IWCR_W0C_EN | PCI_IWCR_W1C_EN | PCI_IWCR_W1C_IO | - PCI_IWCR_W2C_EN | PCI_IWCR_W2C_IO; + out_be32(&pci->iwcr, + PCI_IWCR_W0C_EN | PCI_IWCR_W1C_EN | PCI_IWCR_W1C_IO | + PCI_IWCR_W2C_EN | PCI_IWCR_W2C_IO); - pci->icr = 0; + out_be32(&pci->icr, 0); /* Enable bus master and mem access */ - pci->scr = PCI_SCR_B | PCI_SCR_M; + out_be32(&pci->scr, PCI_SCR_B | PCI_SCR_M); /* Cache line size and master latency */ - pci->cr1 = PCI_CR1_CLS(8) | PCI_CR1_LTMR(0xF8); - pci->cr2 = 0; + out_be32(&pci->cr1, PCI_CR1_CLS(8) | PCI_CR1_LTMR(0xF8)); + out_be32(&pci->cr2, 0); #ifdef CONFIG_SYS_PCI_BAR0 - pci->bar0 = PCI_BAR_BAR0(CONFIG_SYS_PCI_BAR0); - pci->tbatr0 = CONFIG_SYS_PCI_TBATR0 | PCI_TBATR_EN; + out_be32(&pci->bar0, PCI_BAR_BAR0(CONFIG_SYS_PCI_BAR0)); + out_be32(&pci->tbatr0, CONFIG_SYS_PCI_TBATR0 | PCI_TBATR_EN); barEn |= PCI_TCR2_B0E; #endif #ifdef CONFIG_SYS_PCI_BAR1 - pci->bar1 = PCI_BAR_BAR1(CONFIG_SYS_PCI_BAR1); - pci->tbatr1 = CONFIG_SYS_PCI_TBATR1 | PCI_TBATR_EN; + out_be32(&pci->bar1, PCI_BAR_BAR1(CONFIG_SYS_PCI_BAR1)); + out_be32(&pci->tbatr1, CONFIG_SYS_PCI_TBATR1 | PCI_TBATR_EN); barEn |= PCI_TCR2_B1E; #endif #ifdef CONFIG_SYS_PCI_BAR2 - pci->bar2 = PCI_BAR_BAR2(CONFIG_SYS_PCI_BAR2); - pci->tbatr2 = CONFIG_SYS_PCI_TBATR2 | PCI_TBATR_EN; + out_be32(&pci->bar2, PCI_BAR_BAR2(CONFIG_SYS_PCI_BAR2)); + out_be32(&pci->tbatr2, CONFIG_SYS_PCI_TBATR2 | PCI_TBATR_EN); barEn |= PCI_TCR2_B2E; #endif #ifdef CONFIG_SYS_PCI_BAR3 - pci->bar3 = PCI_BAR_BAR3(CONFIG_SYS_PCI_BAR3); - pci->tbatr3 = CONFIG_SYS_PCI_TBATR3 | PCI_TBATR_EN; + out_be32(&pci->bar3, PCI_BAR_BAR3(CONFIG_SYS_PCI_BAR3)); + out_be32(&pci->tbatr3, CONFIG_SYS_PCI_TBATR3 | PCI_TBATR_EN); barEn |= PCI_TCR2_B3E; #endif #ifdef CONFIG_SYS_PCI_BAR4 - pci->bar4 = PCI_BAR_BAR4(CONFIG_SYS_PCI_BAR4); - pci->tbatr4 = CONFIG_SYS_PCI_TBATR4 | PCI_TBATR_EN; + out_be32(&pci->bar4, PCI_BAR_BAR4(CONFIG_SYS_PCI_BAR4)); + out_be32(&pci->tbatr4, CONFIG_SYS_PCI_TBATR4 | PCI_TBATR_EN); barEn |= PCI_TCR2_B4E; #endif #ifdef CONFIG_SYS_PCI_BAR5 - pci->bar5 = PCI_BAR_BAR5(CONFIG_SYS_PCI_BAR5); - pci->tbatr5 = CONFIG_SYS_PCI_TBATR5 | PCI_TBATR_EN; + out_be32(&pci->bar5, PCI_BAR_BAR5(CONFIG_SYS_PCI_BAR5)); + out_be32(&pci->tbatr5, CONFIG_SYS_PCI_TBATR5 | PCI_TBATR_EN); barEn |= PCI_TCR2_B5E; #endif - pci->tcr2 = barEn; + out_be32(&pci->tcr2, barEn); /* Deassert reset bit */ - pci->gscr &= ~PCI_GSCR_PR; + clrbits_be32(&pci->gscr, PCI_GSCR_PR); udelay(1000); /* Enable PCI bus master support */ diff --git a/arch/m68k/cpu/mcf5445x/speed.c b/arch/m68k/cpu/mcf5445x/speed.c index 9c0c077..073b7ef 100644 --- a/arch/m68k/cpu/mcf5445x/speed.c +++ b/arch/m68k/cpu/mcf5445x/speed.c @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -26,6 +26,7 @@ #include <asm/processor.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -44,7 +45,7 @@ DECLARE_GLOBAL_DATA_PTR; void clock_enter_limp(int lpdiv) { - volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; + ccm_t *ccm = (ccm_t *)MMAP_CCM; int i, j; /* Check bounds of divider */ @@ -57,10 +58,10 @@ void clock_enter_limp(int lpdiv) for (i = 0, j = lpdiv; j != 1; j >>= 1, i++) ; /* Apply the divider to the system clock */ - ccm->cdr = (ccm->cdr & 0xF0FF) | CCM_CDR_LPDIV(i); + clrsetbits_be16(&ccm->cdr, 0x0f00, CCM_CDR_LPDIV(i)); /* Enable Limp Mode */ - ccm->misccr |= CCM_MISCCR_LIMP; + setbits_be16(&ccm->misccr, CCM_MISCCR_LIMP); } /* @@ -69,14 +70,15 @@ void clock_enter_limp(int lpdiv) */ void clock_exit_limp(void) { - volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; - volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + ccm_t *ccm = (ccm_t *)MMAP_CCM; + pll_t *pll = (pll_t *)MMAP_PLL; /* Exit Limp mode */ - ccm->misccr &= ~CCM_MISCCR_LIMP; + clrbits_be16(&ccm->misccr, CCM_MISCCR_LIMP); /* Wait for the PLL to lock */ - while (!(pll->psr & PLL_PSR_LOCK)) ; + while (!(in_be32(&pll->psr) & PLL_PSR_LOCK)) + ; } /* @@ -85,8 +87,8 @@ void clock_exit_limp(void) int get_clocks(void) { - volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; - volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + ccm_t *ccm = (ccm_t *)MMAP_CCM; + pll_t *pll = (pll_t *)MMAP_PLL; int pllmult_nopci[] = { 20, 10, 24, 18, 12, 6, 16, 8 }; int pllmult_pci[] = { 12, 6, 16, 8 }; int vco = 0, bPci, temp, fbtemp, pcrvalue; @@ -94,13 +96,13 @@ int get_clocks(void) u16 fbpll_mask; #ifdef CONFIG_M54455EVB - volatile u8 *cpld = (volatile u8 *)(CONFIG_SYS_CS2_BASE + 3); + u8 *cpld = (u8 *)(CONFIG_SYS_CS2_BASE + 3); #endif u8 bootmode; /* To determine PCI is present or not */ - if (((ccm->ccr & CCM_CCR_360_FBCONFIG_MASK) == 0x00e0) || - ((ccm->ccr & CCM_CCR_360_FBCONFIG_MASK) == 0x0060)) { + if (((in_be16(&ccm->ccr) & CCM_CCR_360_FBCONFIG_MASK) == 0x00e0) || + ((in_be16(&ccm->ccr) & CCM_CCR_360_FBCONFIG_MASK) == 0x0060)) { pPllmult = &pllmult_pci[0]; fbpll_mask = 3; /* 11b */ bPci = 1; @@ -114,7 +116,7 @@ int get_clocks(void) } #ifdef CONFIG_M54455EVB - bootmode = (*cpld & 0x03); + bootmode = (in_8(cpld) & 0x03); if (bootmode != 3) { /* Temporary read from CCR- fixed fb issue, must be the same clock @@ -122,11 +124,11 @@ int get_clocks(void) fbtemp = pPllmult[ccm->ccr & fbpll_mask]; /* Break down into small pieces, code still in flex bus */ - pcrvalue = pll->pcr & 0xFFFFF0FF; + pcrvalue = in_be32(&pll->pcr) & 0xFFFFF0FF; temp = fbtemp - 1; pcrvalue |= PLL_PCR_OUTDIV3(temp); - pll->pcr = pcrvalue; + out_be32(&pll->pcr, pcrvalue); } #endif #ifdef CONFIG_M54451EVB @@ -137,9 +139,10 @@ int get_clocks(void) bootmode = 2; /* default value is 16 mul, set to 20 mul */ - pcrvalue = (pll->pcr & 0x00FFFFFF) | 0x14000000; - pll->pcr = pcrvalue; - while ((pll->psr & PLL_PSR_LOCK) != PLL_PSR_LOCK); + pcrvalue = (in_be32(&pll->pcr) & 0x00FFFFFF) | 0x14000000; + out_be32(&pll->pcr, pcrvalue); + while ((in_be32(&pll->psr) & PLL_PSR_LOCK) != PLL_PSR_LOCK) + ; #endif #endif @@ -149,10 +152,10 @@ int get_clocks(void) if ((vco < CLOCK_PLL_FVCO_MIN) || (vco > CLOCK_PLL_FVCO_MAX)) { /* invaild range, re-set in PCR */ - int temp = ((pll->pcr & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; + int temp = ((in_be32(&pll->pcr) & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; int i, j, bus; - j = (pll->pcr & 0xFF000000) >> 24; + j = (in_be32(&pll->pcr) & 0xFF000000) >> 24; for (i = j; i < 0xFF; i++) { vco = i * CONFIG_SYS_INPUT_CLKSRC; if (vco >= CLOCK_PLL_FVCO_MIN) { @@ -163,47 +166,47 @@ int get_clocks(void) break; } } - pcrvalue = pll->pcr & 0x00FF00FF; + pcrvalue = in_be32(&pll->pcr) & 0x00FF00FF; fbtemp = ((i - 1) << 8) | ((i - 1) << 12); pcrvalue |= ((i << 24) | fbtemp); - pll->pcr = pcrvalue; + out_be32(&pll->pcr, pcrvalue); } gd->vco_clk = vco; /* Vco clock */ } else if (bootmode == 2) { /* Normal mode */ - vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; if ((vco < CLOCK_PLL_FVCO_MIN) || (vco > CLOCK_PLL_FVCO_MAX)) { /* Default value */ - pcrvalue = (pll->pcr & 0x00FFFFFF); - pcrvalue |= pPllmult[ccm->ccr & fbpll_mask] << 24; - pll->pcr = pcrvalue; - vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + pcrvalue = (in_be32(&pll->pcr) & 0x00FFFFFF); + pcrvalue |= pPllmult[in_be16(&ccm->ccr) & fbpll_mask] << 24; + out_be32(&pll->pcr, pcrvalue); + vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; } gd->vco_clk = vco; /* Vco clock */ } else if (bootmode == 3) { /* serial mode */ - vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; gd->vco_clk = vco; /* Vco clock */ } - if ((ccm->ccr & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { + if ((in_be16(&ccm->ccr) & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { /* Limp mode */ } else { gd->inp_clk = CONFIG_SYS_INPUT_CLKSRC; /* Input clock */ - temp = (pll->pcr & PLL_PCR_OUTDIV1_MASK) + 1; + temp = (in_be32(&pll->pcr) & PLL_PCR_OUTDIV1_MASK) + 1; gd->cpu_clk = vco / temp; /* cpu clock */ - temp = ((pll->pcr & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; + temp = ((in_be32(&pll->pcr) & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; gd->bus_clk = vco / temp; /* bus clock */ - temp = ((pll->pcr & PLL_PCR_OUTDIV3_MASK) >> 8) + 1; + temp = ((in_be32(&pll->pcr) & PLL_PCR_OUTDIV3_MASK) >> 8) + 1; gd->flb_clk = vco / temp; /* FlexBus clock */ #ifdef CONFIG_PCI if (bPci) { - temp = ((pll->pcr & PLL_PCR_OUTDIV4_MASK) >> 12) + 1; + temp = ((in_be32(&pll->pcr) & PLL_PCR_OUTDIV4_MASK) >> 12) + 1; gd->pci_clk = vco / temp; /* PCI clock */ } #endif diff --git a/arch/m68k/cpu/mcf547x_8x/cpu.c b/arch/m68k/cpu/mcf547x_8x/cpu.c index 7590f2c..157a8e4 100644 --- a/arch/m68k/cpu/mcf547x_8x/cpu.c +++ b/arch/m68k/cpu/mcf547x_8x/cpu.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -31,19 +31,20 @@ #include <netdev.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); + gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); - gptmr->pre = 10; - gptmr->cnt = 1; + out_be16(&gptmr->pre, 10); + out_be16(&gptmr->cnt, 1); /* enable watchdog, set timeout to 0 and wait */ - gptmr->mode = GPT_TMS_SGPIO; - gptmr->ctrl = GPT_CTRL_WDEN | GPT_CTRL_CE; + out_8(&gptmr->mode, GPT_TMS_SGPIO); + out_8(&gptmr->ctrl, GPT_CTRL_WDEN | GPT_CTRL_CE); /* we don't return! */ return 1; @@ -51,12 +52,12 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int checkcpu(void) { - volatile siu_t *siu = (siu_t *) MMAP_SIU; + siu_t *siu = (siu_t *) MMAP_SIU; u16 id = 0; puts("CPU: "); - switch ((siu->jtagid & 0x000FF000) >> 12) { + switch ((in_be32(&siu->jtagid) & 0x000FF000) >> 12) { case 0x0C: id = 5485; break; @@ -111,18 +112,18 @@ int checkcpu(void) /* Called by macro WATCHDOG_RESET */ void hw_watchdog_reset(void) { - volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); + gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); - gptmr->ocpw = 0xa5; + out_8(&gptmr->ocpw, 0xa5); } int watchdog_disable(void) { - volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); + gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); /* UserManual, once the wdog is disabled, wdog cannot be re-enabled */ - gptmr->mode = 0; - gptmr->ctrl = 0; + out_8(&gptmr->mode, 0); + out_8(&gptmr->ctrl, 0); puts("WATCHDOG:disabled\n"); @@ -131,14 +132,13 @@ int watchdog_disable(void) int watchdog_init(void) { + gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); - volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); + out_be16(&gptmr->pre, CONFIG_WATCHDOG_TIMEOUT); + out_be16(&gptmr->cnt, CONFIG_SYS_TIMER_PRESCALER * 1000); - gptmr->pre = CONFIG_WATCHDOG_TIMEOUT; - gptmr->cnt = CONFIG_SYS_TIMER_PRESCALER * 1000; - - gptmr->mode = GPT_TMS_SGPIO; - gptmr->ctrl = GPT_CTRL_CE | GPT_CTRL_WDEN; + out_8(&gptmr->mode, GPT_TMS_SGPIO); + out_8(&gptmr->ctrl, GPT_CTRL_CE | GPT_CTRL_WDEN); puts("WATCHDOG:enabled\n"); return (0); diff --git a/arch/m68k/cpu/mcf547x_8x/cpu_init.c b/arch/m68k/cpu/mcf547x_8x/cpu_init.c index 60c9126..4eb8a7c 100644 --- a/arch/m68k/cpu/mcf547x_8x/cpu_init.c +++ b/arch/m68k/cpu/mcf547x_8x/cpu_init.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2007 Freescale Semiconductor, Inc. + * (C) Copyright 2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,6 +28,7 @@ #include <common.h> #include <MCD_dma.h> #include <asm/immap.h> +#include <asm/io.h> #if defined(CONFIG_CMD_NET) #include <config.h> @@ -44,58 +45,59 @@ */ void cpu_init_f(void) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - volatile xlbarb_t *xlbarb = (volatile xlbarb_t *) MMAP_XARB; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + xlbarb_t *xlbarb = (xlbarb_t *) MMAP_XARB; - xlbarb->adrto = 0x2000; - xlbarb->datto = 0x2500; - xlbarb->busto = 0x3000; + out_be32(&xlbarb->adrto, 0x2000); + out_be32(&xlbarb->datto, 0x2500); + out_be32(&xlbarb->busto, 0x3000); - xlbarb->cfg = XARB_CFG_AT | XARB_CFG_DT; + out_be32(&xlbarb->cfg, XARB_CFG_AT | XARB_CFG_DT); /* Master Priority Enable */ - xlbarb->prien = 0xff; - xlbarb->pri = 0; + out_be32(&xlbarb->prien, 0xff); + out_be32(&xlbarb->pri, 0); #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) && defined(CONFIG_SYS_CS0_CTRL)) - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #endif #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) && defined(CONFIG_SYS_CS1_CTRL)) - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) && defined(CONFIG_SYS_CS2_CTRL)) - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) && defined(CONFIG_SYS_CS3_CTRL)) - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) && defined(CONFIG_SYS_CS4_CTRL)) - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) && defined(CONFIG_SYS_CS5_CTRL)) - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif #ifdef CONFIG_FSL_I2C - gpio->par_feci2cirq = GPIO_PAR_FECI2CIRQ_SCL | GPIO_PAR_FECI2CIRQ_SDA; + out_be16(&gpio->par_feci2cirq, + GPIO_PAR_FECI2CIRQ_SCL | GPIO_PAR_FECI2CIRQ_SDA); #endif icache_enable(); @@ -115,44 +117,44 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile u8 *pscsicr = (u8 *) (CONFIG_SYS_UART_BASE + 0x40); + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + u8 *pscsicr = (u8 *) (CONFIG_SYS_UART_BASE + 0x40); /* Setup Ports: */ switch (port) { case 0: - gpio->par_psc0 = (GPIO_PAR_PSC0_TXD0 | GPIO_PAR_PSC0_RXD0); + out_8(&gpio->par_psc0, GPIO_PAR_PSC0_TXD0 | GPIO_PAR_PSC0_RXD0); break; case 1: - gpio->par_psc1 = (GPIO_PAR_PSC1_TXD1 | GPIO_PAR_PSC1_RXD1); + out_8(&gpio->par_psc1, GPIO_PAR_PSC1_TXD1 | GPIO_PAR_PSC1_RXD1); break; case 2: - gpio->par_psc2 = (GPIO_PAR_PSC2_TXD2 | GPIO_PAR_PSC2_RXD2); + out_8(&gpio->par_psc2, GPIO_PAR_PSC2_TXD2 | GPIO_PAR_PSC2_RXD2); break; case 3: - gpio->par_psc3 = (GPIO_PAR_PSC3_TXD3 | GPIO_PAR_PSC3_RXD3); + out_8(&gpio->par_psc3, GPIO_PAR_PSC3_TXD3 | GPIO_PAR_PSC3_RXD3); break; } - *pscsicr &= 0xF8; + clrbits_8(pscsicr, 0x07); } #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; struct fec_info_dma *info = (struct fec_info_dma *)dev->priv; if (setclear) { if (info->iobase == CONFIG_SYS_FEC0_IOBASE) - gpio->par_feci2cirq |= 0xF000; + setbits_be16(&gpio->par_feci2cirq, 0xf000); else - gpio->par_feci2cirq |= 0x0FC0; + setbits_be16(&gpio->par_feci2cirq, 0x0fc0); } else { if (info->iobase == CONFIG_SYS_FEC0_IOBASE) - gpio->par_feci2cirq &= 0x0FFF; + clrbits_be16(&gpio->par_feci2cirq, 0xf000); else - gpio->par_feci2cirq &= 0xF03F; + clrbits_be16(&gpio->par_feci2cirq, 0x0fc0); } return 0; } diff --git a/arch/m68k/cpu/mcf547x_8x/interrupts.c b/arch/m68k/cpu/mcf547x_8x/interrupts.c index 76be876..d215438 100644 --- a/arch/m68k/cpu/mcf547x_8x/interrupts.c +++ b/arch/m68k/cpu/mcf547x_8x/interrupts.c @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -25,14 +25,15 @@ /* CPU specific interrupt routine */ #include <common.h> #include <asm/immap.h> +#include <asm/io.h> int interrupt_init(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); /* Make sure all interrupts are disabled */ - intp->imrh0 |= 0xFFFFFFFF; - intp->imrl0 |= 0xFFFFFFFF; + setbits_be32(&intp->imrh0, 0xffffffff); + setbits_be32(&intp->imrl0, 0xffffffff); enable_interrupts(); @@ -42,9 +43,9 @@ int interrupt_init(void) #if defined(CONFIG_SLTTMR) void dtimer_intr_setup(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); - intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; - intp->imrh0 &= ~CONFIG_SYS_TMRINTR_MASK; + out_8(&intp->icr0[CONFIG_SYS_TMRINTR_NO], CONFIG_SYS_TMRINTR_PRI); + clrbits_be32(&intp->imrh0, CONFIG_SYS_TMRINTR_MASK); } #endif diff --git a/arch/m68k/cpu/mcf547x_8x/pci.c b/arch/m68k/cpu/mcf547x_8x/pci.c index f867dc1..1a81e3f 100644 --- a/arch/m68k/cpu/mcf547x_8x/pci.c +++ b/arch/m68k/cpu/mcf547x_8x/pci.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -88,53 +88,56 @@ int pci_read_cfg_dword(struct pci_controller *hose, pci_dev_t dev, void pci_mcf547x_8x_init(struct pci_controller *hose) { - volatile pci_t *pci = (volatile pci_t *) MMAP_PCI; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + pci_t *pci = (pci_t *) MMAP_PCI; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Port configuration */ - gpio->par_pcibg = - GPIO_PAR_PCIBG_PCIBG0(3) | GPIO_PAR_PCIBG_PCIBG1(3) | - GPIO_PAR_PCIBG_PCIBG2(3) | GPIO_PAR_PCIBG_PCIBG3(3) | - GPIO_PAR_PCIBG_PCIBG4(3); - gpio->par_pcibr = - GPIO_PAR_PCIBR_PCIBR0(3) | GPIO_PAR_PCIBR_PCIBR1(3) | - GPIO_PAR_PCIBR_PCIBR2(3) | GPIO_PAR_PCIBR_PCIBR3(3) | - GPIO_PAR_PCIBR_PCIBR4(3); + out_be16(&gpio->par_pcibg, + GPIO_PAR_PCIBG_PCIBG0(3) | GPIO_PAR_PCIBG_PCIBG1(3) | + GPIO_PAR_PCIBG_PCIBG2(3) | GPIO_PAR_PCIBG_PCIBG3(3) | + GPIO_PAR_PCIBG_PCIBG4(3)); + out_be16(&gpio->par_pcibr, + GPIO_PAR_PCIBR_PCIBR0(3) | GPIO_PAR_PCIBR_PCIBR1(3) | + GPIO_PAR_PCIBR_PCIBR2(3) | GPIO_PAR_PCIBR_PCIBR3(3) | + GPIO_PAR_PCIBR_PCIBR4(3)); /* Assert reset bit */ - pci->gscr |= PCI_GSCR_PR; + setbits_be32(&pci->gscr, PCI_GSCR_PR); - pci->tcr1 = PCI_TCR1_P; + out_be32(&pci->tcr1, PCI_TCR1_P); /* Initiator windows */ - pci->iw0btar = CONFIG_SYS_PCI_MEM_PHYS | (CONFIG_SYS_PCI_MEM_PHYS >> 16); - pci->iw1btar = CONFIG_SYS_PCI_IO_PHYS | (CONFIG_SYS_PCI_IO_PHYS >> 16); - pci->iw2btar = CONFIG_SYS_PCI_CFG_PHYS | (CONFIG_SYS_PCI_CFG_PHYS >> 16); + out_be32(&pci->iw0btar, + CONFIG_SYS_PCI_MEM_PHYS | (CONFIG_SYS_PCI_MEM_PHYS >> 16)); + out_be32(&pci->iw1btar, + CONFIG_SYS_PCI_IO_PHYS | (CONFIG_SYS_PCI_IO_PHYS >> 16)); + out_be32(&pci->iw2btar, + CONFIG_SYS_PCI_CFG_PHYS | (CONFIG_SYS_PCI_CFG_PHYS >> 16)); - pci->iwcr = - PCI_IWCR_W0C_EN | PCI_IWCR_W1C_EN | PCI_IWCR_W1C_IO | - PCI_IWCR_W2C_EN | PCI_IWCR_W2C_IO; + out_be32(&pci->iwcr, + PCI_IWCR_W0C_EN | PCI_IWCR_W1C_EN | PCI_IWCR_W1C_IO | + PCI_IWCR_W2C_EN | PCI_IWCR_W2C_IO); - pci->icr = 0; + out_be32(&pci->icr, 0); /* Enable bus master and mem access */ - pci->scr = PCI_SCR_B | PCI_SCR_M; + out_be32(&pci->scr, PCI_SCR_B | PCI_SCR_M); /* Cache line size and master latency */ - pci->cr1 = PCI_CR1_CLS(8) | PCI_CR1_LTMR(0xF8); - pci->cr2 = 0; + out_be32(&pci->cr1, PCI_CR1_CLS(8) | PCI_CR1_LTMR(0xf8)); + out_be32(&pci->cr2, 0); #ifdef CONFIG_SYS_PCI_BAR0 - pci->bar0 = PCI_BAR_BAR0(CONFIG_SYS_PCI_BAR0); - pci->tbatr0a = CONFIG_SYS_PCI_TBATR0 | PCI_TBATR_EN; + out_be32(&pci->bar0, PCI_BAR_BAR0(CONFIG_SYS_PCI_BAR0)); + out_be32(&pci->tbatr0a, CONFIG_SYS_PCI_TBATR0 | PCI_TBATR_EN); #endif #ifdef CONFIG_SYS_PCI_BAR1 - pci->bar1 = PCI_BAR_BAR1(CONFIG_SYS_PCI_BAR1); - pci->tbatr1a = CONFIG_SYS_PCI_TBATR1 | PCI_TBATR_EN; + out_be32(&pci->bar1, PCI_BAR_BAR1(CONFIG_SYS_PCI_BAR1)); + out_be32(&pci->tbatr1a, CONFIG_SYS_PCI_TBATR1 | PCI_TBATR_EN); #endif /* Deassert reset bit */ - pci->gscr &= ~PCI_GSCR_PR; + clrbits_be32(&pci->gscr, PCI_GSCR_PR); udelay(1000); /* Enable PCI bus master support */ diff --git a/arch/m68k/cpu/mcf547x_8x/slicetimer.c b/arch/m68k/cpu/mcf547x_8x/slicetimer.c index ee2e35b..25dd2ae 100644 --- a/arch/m68k/cpu/mcf547x_8x/slicetimer.c +++ b/arch/m68k/cpu/mcf547x_8x/slicetimer.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2007 Freescale Semiconductor, Inc. + * (C) Copyright 2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -25,6 +25,7 @@ #include <asm/timer.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -42,31 +43,32 @@ extern void dtimer_intr_setup(void); void __udelay(unsigned long usec) { - volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE); + slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE); u32 now, freq; /* 1 us period */ freq = CONFIG_SYS_TIMER_PRESCALER; - timerp->cr = 0; /* Disable */ - timerp->tcnt = usec * freq; - timerp->cr = SLT_CR_TEN; + /* Disable */ + out_be32(&timerp->cr, 0); + out_be32(&timerp->tcnt, usec * freq); + out_be32(&timerp->cr, SLT_CR_TEN); - now = timerp->cnt; + now = in_be32(&timerp->cnt); while (now != 0) - now = timerp->cnt; + now = in_be32(&timerp->cnt); - timerp->sr |= SLT_SR_ST; - timerp->cr = 0; + setbits_be32(&timerp->sr, SLT_SR_ST); + out_be32(&timerp->cr, 0); } void dtimer_interrupt(void *not_used) { - volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); + slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); /* check for timer interrupt asserted */ if ((CONFIG_SYS_TMRPND_REG & CONFIG_SYS_TMRINTR_MASK) == CONFIG_SYS_TMRINTR_PEND) { - timerp->sr |= SLT_SR_ST; + setbits_be32(&timerp->sr, SLT_SR_ST); timestamp++; return; } @@ -74,25 +76,27 @@ void dtimer_interrupt(void *not_used) int timer_init(void) { - volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); + slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); timestamp = 0; - timerp->cr = 0; /* disable timer */ - timerp->tcnt = 0; - timerp->sr = SLT_SR_BE | SLT_SR_ST; /* clear status */ + /* disable timer */ + out_be32(&timerp->cr, 0); + out_be32(&timerp->tcnt, 0); + /* clear status */ + out_be32(&timerp->sr, SLT_SR_BE | SLT_SR_ST); /* initialize and enable timer interrupt */ irq_install_handler(CONFIG_SYS_TMRINTR_NO, dtimer_interrupt, 0); /* Interrupt every ms */ - timerp->tcnt = 1000 * CONFIG_SYS_TIMER_PRESCALER; + out_be32(&timerp->tcnt, 1000 * CONFIG_SYS_TIMER_PRESCALER); dtimer_intr_setup(); /* set a period of 1us, set timer mode to restart and enable timer and interrupt */ - timerp->cr = SLT_CR_RUN | SLT_CR_IEN | SLT_CR_TEN; + out_be32(&timerp->cr, SLT_CR_RUN | SLT_CR_IEN | SLT_CR_TEN); return 0; } diff --git a/arch/m68k/include/asm/bitops.h b/arch/m68k/include/asm/bitops.h index ad971b4..525d90c 100644 --- a/arch/m68k/include/asm/bitops.h +++ b/arch/m68k/include/asm/bitops.h @@ -17,41 +17,36 @@ extern int test_and_change_bit(int nr, volatile void *addr); #ifdef __KERNEL__ -/* - * ffs: find first bit set. This is defined the same way as - * the libc and compiler builtin ffs routines, therefore - * differs in spirit from the above ffz (man ffs). - */ -extern __inline__ int ffs(int x) + +extern inline int test_bit(int nr, __const__ volatile void *addr) { - int r = 1; - - if (!x) - return 0; - if (!(x & 0xffff)) { - x >>= 16; - r += 16; - } - if (!(x & 0xff)) { - x >>= 8; - r += 8; - } - if (!(x & 0xf)) { - x >>= 4; - r += 4; - } - if (!(x & 3)) { - x >>= 2; - r += 2; - } - if (!(x & 1)) { - x >>= 1; - r += 1; - } - return r; + __const__ unsigned int *p = (__const__ unsigned int *) addr; + + return (p[nr >> 5] & (1UL << (nr & 31))) != 0; } + +extern inline int test_and_set_bit(int nr, volatile void *vaddr) +{ + char retval; + + volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3]; + __asm__ __volatile__ ("bset %2,(%4); sne %0" + : "=d" (retval), "=m" (*p) + : "di" (nr & 7), "m" (*p), "a" (p)); + + return retval; +} + #define __ffs(x) (ffs(x) - 1) -#define PLATFORM_FFS + +/* + * * hweightN: returns the hamming weight (i.e. the number + * * of bits set) of a N-bit word + * */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) #endif /* __KERNEL__ */ diff --git a/arch/m68k/include/asm/coldfire/flexbus.h b/arch/m68k/include/asm/coldfire/flexbus.h index 51cbbd8..9a3078a 100644 --- a/arch/m68k/include/asm/coldfire/flexbus.h +++ b/arch/m68k/include/asm/coldfire/flexbus.h @@ -29,7 +29,57 @@ /********************************************************************* * FlexBus Chip Selects (FBCS) *********************************************************************/ +#ifdef CONFIG_M5235 +typedef struct fbcs { + u16 csar0; /* Chip-select Address */ + u16 res1; + u32 csmr0; /* Chip-select Mask */ + u16 res2; + u16 cscr0; /* Chip-select Control */ + + u16 csar1; + u16 res3; + u32 csmr1; + u16 res4; + u16 cscr1; + + u16 csar2; + u16 res5; + u32 csmr2; + u16 res6; + u16 cscr2; + + u16 csar3; + u16 res7; + u32 csmr3; + u16 res8; + u16 cscr3; + + u16 csar4; + u16 res9; + u32 csmr4; + u16 res10; + u16 cscr4; + + u16 csar5; + u16 res11; + u32 csmr5; + u16 res12; + u16 cscr5; + u16 csar6; + u16 res13; + u32 csmr6; + u16 res14; + u16 cscr6; + + u16 csar7; + u16 res15; + u32 csmr7; + u16 res16; + u16 cscr7; +} fbcs_t; +#else typedef struct fbcs { u32 csar0; /* Chip-select Address */ u32 csmr0; /* Chip-select Mask */ @@ -56,6 +106,7 @@ typedef struct fbcs { u32 csmr7; u32 cscr7; } fbcs_t; +#endif #define FBCS_CSAR_BA(x) ((x) & 0xFFFF0000) @@ -94,6 +145,22 @@ typedef struct fbcs { #endif #define FBCS_CSMR_V (0x00000001) /* Valid bit */ +#ifdef CONFIG_M5235 +#define FBCS_CSCR_SRWS(x) (((x) & 0x3) << 14) +#define FBCS_CSCR_IWS(x) (((x) & 0xF) << 10) +#define FBCS_CSCR_AA_ON (1 << 8) +#define FBCS_CSCR_AA_OFF (0 << 8) +#define FBCS_CSCR_PS_32 (0 << 6) +#define FBCS_CSCR_PS_16 (2 << 6) +#define FBCS_CSCR_PS_8 (1 << 6) +#define FBCS_CSCR_BEM_ON (1 << 5) +#define FBCS_CSCR_BEM_OFF (0 << 5) +#define FBCS_CSCR_BSTR_ON (1 << 4) +#define FBCS_CSCR_BSTR_OFF (0 << 4) +#define FBCS_CSCR_BSTW_ON (1 << 3) +#define FBCS_CSCR_BSTW_OFF (0 << 3) +#define FBCS_CSCR_SWWS(x) (((x) & 0x7) << 0) +#else #define FBCS_CSCR_SWS(x) (((x) & 0x3F) << 26) #define FBCS_CSCR_SWS_MASK (0x03FFFFFF) #define FBCS_CSCR_SWSEN (0x00800000) @@ -116,5 +183,6 @@ typedef struct fbcs { #define FBCS_CSCR_PS_16 (0x00000080) #define FBCS_CSCR_PS_8 (0x00000040) #define FBCS_CSCR_PS_32 (0x00000000) +#endif #endif /* __FLEXBUS_H */ diff --git a/arch/m68k/include/asm/coldfire/qspi.h b/arch/m68k/include/asm/coldfire/qspi.h index 8bcd2e4..9fd98f6 100644 --- a/arch/m68k/include/asm/coldfire/qspi.h +++ b/arch/m68k/include/asm/coldfire/qspi.h @@ -98,7 +98,7 @@ typedef struct qspi_ctrl { #define QSPI_QAR_RECV (0x0010) #define QSPI_QAR_CMD (0x0020) -/* DR */ +/* DR with RAM command word definitions */ #define QSPI_QDR_CONT (0x8000) #define QSPI_QDR_BITSE (0x4000) #define QSPI_QDR_DT (0x2000) diff --git a/arch/m68k/include/asm/io.h b/arch/m68k/include/asm/io.h index d86eaf9..50ed749 100644 --- a/arch/m68k/include/asm/io.h +++ b/arch/m68k/include/asm/io.h @@ -1,7 +1,7 @@ /* * IO header file * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -225,6 +225,42 @@ extern inline void out_be32(volatile unsigned *addr, int val) *addr = val; } +/* Clear and set bits in one shot. These macros can be used to clear and + * set multiple bits in a register using a single call. These macros can + * also be used to set a multiple-bit bit pattern using a mask, by + * specifying the mask in the 'clear' parameter and the new bit pattern + * in the 'set' parameter. + */ + +#define clrbits(type, addr, clear) \ + out_##type((addr), in_##type(addr) & ~(clear)) + +#define setbits(type, addr, set) \ + out_##type((addr), in_##type(addr) | (set)) + +#define clrsetbits(type, addr, clear, set) \ + out_##type((addr), (in_##type(addr) & ~(clear)) | (set)) + +#define clrbits_be32(addr, clear) clrbits(be32, addr, clear) +#define setbits_be32(addr, set) setbits(be32, addr, set) +#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set) + +#define clrbits_le32(addr, clear) clrbits(le32, addr, clear) +#define setbits_le32(addr, set) setbits(le32, addr, set) +#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set) + +#define clrbits_be16(addr, clear) clrbits(be16, addr, clear) +#define setbits_be16(addr, set) setbits(be16, addr, set) +#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set) + +#define clrbits_le16(addr, clear) clrbits(le16, addr, clear) +#define setbits_le16(addr, set) setbits(le16, addr, set) +#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set) + +#define clrbits_8(addr, clear) clrbits(8, addr, clear) +#define setbits_8(addr, set) setbits(8, addr, set) +#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) + static inline void sync(void) { /* This sync function is for PowerPC or other architecture instruction diff --git a/arch/m68k/include/asm/m5271.h b/arch/m68k/include/asm/m5271.h index d25261b..b2bc051 100644 --- a/arch/m68k/include/asm/m5271.h +++ b/arch/m68k/include/asm/m5271.h @@ -171,6 +171,32 @@ #define MCF_GPIO_PAR_UART_U1RXD_UART1 0x0C00 #define MCF_GPIO_PAR_UART_U1TXD_UART1 0x0300 +/* Bit definitions and macros for PAR_QSPI */ +#define MCF_GPIO_PAR_QSPI_PCS1_UNMASK 0x3F +#define MCF_GPIO_PAR_QSPI_PCS1_PCS1 0xC0 +#define MCF_GPIO_PAR_QSPI_PCS1_SDRAM_SCKE 0x80 +#define MCF_GPIO_PAR_QSPI_PCS1_GPIO 0x00 +#define MCF_GPIO_PAR_QSPI_PCS0_UNMASK 0xDF +#define MCF_GPIO_PAR_QSPI_PCS0_PCS0 0x20 +#define MCF_GPIO_PAR_QSPI_PCS0_GPIO 0x00 +#define MCF_GPIO_PAR_QSPI_SIN_UNMASK 0xE7 +#define MCF_GPIO_PAR_QSPI_SIN_SIN 0x18 +#define MCF_GPIO_PAR_QSPI_SIN_I2C_SDA 0x10 +#define MCF_GPIO_PAR_QSPI_SIN_GPIO 0x00 +#define MCF_GPIO_PAR_QSPI_SOUT_UNMASK 0xFB +#define MCF_GPIO_PAR_QSPI_SOUT_SOUT 0x04 +#define MCF_GPIO_PAR_QSPI_SOUT_GPIO 0x00 +#define MCF_GPIO_PAR_QSPI_SCK_UNMASK 0xFC +#define MCF_GPIO_PAR_QSPI_SCK_SCK 0x03 +#define MCF_GPIO_PAR_QSPI_SCK_I2C_SCL 0x02 +#define MCF_GPIO_PAR_QSPI_SCK_GPIO 0x00 + +/* Bit definitions and macros for PAR_TIMER for QSPI */ +#define MCF_GPIO_PAR_TIMER_T3IN_UNMASK 0x3FFF +#define MCF_GPIO_PAR_TIMER_T3IN_QSPI_PCS2 0x4000 +#define MCF_GPIO_PAR_TIMER_T3OUT_UNMASK 0xFF3F +#define MCF_GPIO_PAR_TIMER_T3OUT_QSPI_PCS3 0x0040 + #define MCF_GPIO_PAR_SDRAM_PAR_CSSDCS(x) (((x)&0x03)<<6) #define MCF_SDRAMC_DCR 0x000040 diff --git a/arch/m68k/lib/board.c b/arch/m68k/lib/board.c index 65a8595..2add630 100644 --- a/arch/m68k/lib/board.c +++ b/arch/m68k/lib/board.c @@ -389,7 +389,6 @@ void board_init_r (gd_t *id, ulong dest_addr) { char *s; bd_t *bd; - extern void malloc_bin_reloc (void); #ifndef CONFIG_ENV_IS_NOWHERE extern char * env_name_spec; diff --git a/arch/microblaze/config.mk b/arch/microblaze/config.mk index aca79e2..b4935f0 100644 --- a/arch/microblaze/config.mk +++ b/arch/microblaze/config.mk @@ -31,3 +31,5 @@ CONFIG_STANDALONE_LOAD_ADDR ?= 0x80F00000 PLATFORM_CPPFLAGS += -ffixed-r31 -D__microblaze__ LDSCRIPT ?= $(SRCTREE)/$(CPUDIR)/u-boot.lds + +CONFIG_ARCH_DEVICE_TREE := microblaze diff --git a/arch/microblaze/cpu/interrupts.c b/arch/microblaze/cpu/interrupts.c index ee67082..7f2ee64 100644 --- a/arch/microblaze/cpu/interrupts.c +++ b/arch/microblaze/cpu/interrupts.c @@ -32,15 +32,12 @@ #undef DEBUG_INT -extern void microblaze_disable_interrupts (void); -extern void microblaze_enable_interrupts (void); - -void enable_interrupts (void) +void enable_interrupts(void) { MSRSET(0x2); } -int disable_interrupts (void) +int disable_interrupts(void) { unsigned int msr; @@ -58,20 +55,21 @@ microblaze_intc_t *intc; /* default handler */ static void def_hdlr(void) { - puts ("def_hdlr\n"); + puts("def_hdlr\n"); } static void enable_one_interrupt(int irq) { int mask; int offset = 1; + offset <<= irq; mask = intc->ier; intc->ier = (mask | offset); #ifdef DEBUG_INT - printf ("Enable one interrupt irq %x - mask %x,ier %x\n", offset, mask, + printf("Enable one interrupt irq %x - mask %x,ier %x\n", offset, mask, intc->ier); - printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + printf("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, intc->iar, intc->mer); #endif } @@ -80,25 +78,26 @@ static void disable_one_interrupt(int irq) { int mask; int offset = 1; + offset <<= irq; mask = intc->ier; intc->ier = (mask & ~offset); #ifdef DEBUG_INT - printf ("Disable one interrupt irq %x - mask %x,ier %x\n", irq, mask, + printf("Disable one interrupt irq %x - mask %x,ier %x\n", irq, mask, intc->ier); - printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + printf("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, intc->iar, intc->mer); #endif } -/* adding new handler for interrupt */ -void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg) +int install_interrupt_handler(int irq, interrupt_handler_t *hdlr, void *arg) { struct irq_action *act; + /* irq out of range */ if ((irq < 0) || (irq > irq_no)) { - puts ("IRQ out of range\n"); - return; + puts("IRQ out of range\n"); + return -1; } act = &vecs[irq]; if (hdlr) { /* enable */ @@ -106,11 +105,14 @@ void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg) act->arg = arg; act->count = 0; enable_one_interrupt (irq); - } else { /* disable */ - act->handler = (interrupt_handler_t *) def_hdlr; - act->arg = (void *)irq; - disable_one_interrupt (irq); + return 0; } + + /* Disable */ + act->handler = (interrupt_handler_t *) def_hdlr; + act->arg = (void *)irq; + disable_one_interrupt(irq); + return 1; } /* initialization interrupt controller - hardware */ @@ -122,7 +124,7 @@ static void intc_init(void) /* XIntc_Start - hw_interrupt enable and all interrupt enable */ intc->mer = 0x3; #ifdef DEBUG_INT - printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + printf("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, intc->iar, intc->mer); #endif } @@ -157,7 +159,7 @@ int interrupts_init(void) return 0; } -void interrupt_handler (void) +void interrupt_handler(void) { int irqs = intc->ivr; /* find active interrupt */ int mask = 1; diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 8a2f634..8564c4e 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -149,7 +149,7 @@ clear_bss: cmp r6, r5, r4 /* check if we have reach the end */ bnei r6, 2b 3: /* jumping to board_init */ - brai board_init + brai board_init_f 1: bri 1b /* diff --git a/arch/microblaze/cpu/timer.c b/arch/microblaze/cpu/timer.c index cc6b897..1330401 100644 --- a/arch/microblaze/cpu/timer.c +++ b/arch/microblaze/cpu/timer.c @@ -27,42 +27,30 @@ #include <asm/microblaze_intc.h> volatile int timestamp = 0; +microblaze_timer_t *tmr; -#ifdef CONFIG_SYS_TIMER_0 ulong get_timer (ulong base) { - return (timestamp - base); + if (tmr) + return timestamp - base; + return timestamp++ - base; } -#else -ulong get_timer (ulong base) -{ - return (timestamp++ - base); -} -#endif -#ifdef CONFIG_SYS_TIMER_0 void __udelay(unsigned long usec) { - int i; + u32 i; - i = get_timer(0); - while ((get_timer(0) - i) < (usec / 1000)) - ; + if (tmr) { + i = get_timer(0); + while ((get_timer(0) - i) < (usec / 1000)) + ; + } else { + for (i = 0; i < (usec * XILINX_CLOCK_FREQ / 10000000); i++) + ; + } } -#else -void __udelay(unsigned long usec) -{ - unsigned int i; - for (i = 0; i < (usec * CONFIG_XILINX_CLOCK_FREQ / 10000000); i++) - ; -} -#endif - -#ifdef CONFIG_SYS_TIMER_0 -microblaze_timer_t *tmr = (microblaze_timer_t *) (CONFIG_SYS_TIMER_0_ADDR); - -void timer_isr (void *arg) +static void timer_isr(void *arg) { timestamp++; tmr->control = tmr->control | TIMER_INTERRUPT; @@ -70,15 +58,30 @@ void timer_isr (void *arg) int timer_init (void) { - tmr->loadreg = CONFIG_SYS_TIMER_0_PRELOAD; - tmr->control = TIMER_INTERRUPT | TIMER_RESET; - tmr->control = - TIMER_ENABLE | TIMER_ENABLE_INTR | TIMER_RELOAD | TIMER_DOWN_COUNT; - timestamp = 0; - install_interrupt_handler (CONFIG_SYS_TIMER_0_IRQ, timer_isr, (void *)tmr); + int irq = -1; + u32 preload = 0; + u32 ret = 0; + +#if defined(CONFIG_SYS_TIMER_0_ADDR) && defined(CONFIG_SYS_INTC_0_NUM) + preload = XILINX_CLOCK_FREQ / CONFIG_SYS_HZ; + irq = CONFIG_SYS_TIMER_0_IRQ; + tmr = (microblaze_timer_t *) (CONFIG_SYS_TIMER_0_ADDR); +#endif + + if (tmr && preload && irq >= 0) { + tmr->loadreg = preload; + tmr->control = TIMER_INTERRUPT | TIMER_RESET; + tmr->control = TIMER_ENABLE | TIMER_ENABLE_INTR |\ + TIMER_RELOAD | TIMER_DOWN_COUNT; + timestamp = 0; + ret = install_interrupt_handler (irq, timer_isr, (void *)tmr); + if (ret) + tmr = NULL; + } + + /* No problem if timer is not found/initialized */ return 0; } -#endif /* * This function is derived from PowerPC code (read timebase as long long). diff --git a/arch/microblaze/cpu/u-boot.lds b/arch/microblaze/cpu/u-boot.lds index ee41145..d033a28 100644 --- a/arch/microblaze/cpu/u-boot.lds +++ b/arch/microblaze/cpu/u-boot.lds @@ -45,6 +45,7 @@ SECTIONS .data ALIGN(0x4): { __data_start = .; + dts/libdts.o (.data) *(.data) __data_end = .; } diff --git a/arch/microblaze/include/asm/global_data.h b/arch/microblaze/include/asm/global_data.h index 0dc4ce9..de3b8db 100644 --- a/arch/microblaze/include/asm/global_data.h +++ b/arch/microblaze/include/asm/global_data.h @@ -41,6 +41,7 @@ typedef struct global_data { unsigned long precon_buf_idx; /* Pre-Console buffer index */ #endif unsigned long env_addr; /* Address of Environment struct */ + const void *fdt_blob; /* Our device tree, NULL if none */ unsigned long env_valid; /* Checksum of Environment valid? */ unsigned long fb_base; /* base address of frame buffer */ void **jt; /* jump table */ diff --git a/arch/microblaze/include/asm/microblaze_intc.h b/arch/microblaze/include/asm/microblaze_intc.h index 6142b9c..e9640f5 100644 --- a/arch/microblaze/include/asm/microblaze_intc.h +++ b/arch/microblaze/include/asm/microblaze_intc.h @@ -39,7 +39,16 @@ struct irq_action { int count; /* number of interrupt */ }; -void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, +/** + * Register and unregister interrupt handler rutines + * + * @param irq IRQ number + * @param hdlr Interrupt handler rutine + * @param arg Pointer to argument which is passed to int. handler rutine + * @return 0 if registration pass, 1 if unregistration pass, + * or an error code < 0 otherwise + */ +int install_interrupt_handler(int irq, interrupt_handler_t *hdlr, void *arg); int interrupts_init(void); diff --git a/arch/microblaze/include/asm/microblaze_timer.h b/arch/microblaze/include/asm/microblaze_timer.h index 844c8db..28e8b02 100644 --- a/arch/microblaze/include/asm/microblaze_timer.h +++ b/arch/microblaze/include/asm/microblaze_timer.h @@ -39,3 +39,6 @@ typedef volatile struct microblaze_timer_t { int loadreg; /* load register TLR */ int counter; /* timer/counter register */ } microblaze_timer_t; + +int timer_init(void); + diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h index 2295d0a..2c4d5ff 100644 --- a/arch/microblaze/include/asm/processor.h +++ b/arch/microblaze/include/asm/processor.h @@ -28,4 +28,7 @@ extern char __end[]; extern char __text_start[]; +/* Microblaze board initialization function */ +void board_init(void); + #endif /* __ASM_MICROBLAZE_PROCESSOR_H */ diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c index b80250a..674b573 100644 --- a/arch/microblaze/lib/board.c +++ b/arch/microblaze/lib/board.c @@ -32,21 +32,13 @@ #include <stdio_dev.h> #include <serial.h> #include <net.h> +#include <linux/compiler.h> #include <asm/processor.h> #include <asm/microblaze_intc.h> +#include <fdtdec.h> DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_SYS_GPIO_0 -extern int gpio_init (void); -#endif -#ifdef CONFIG_SYS_TIMER_0 -extern int timer_init (void); -#endif -#ifdef CONFIG_SYS_FSL_2 -extern void fsl_init2 (void); -#endif - /* * All attempts to come up with a "common" initialization sequence * that works for all boards and architectures failed: some of the @@ -63,31 +55,26 @@ typedef int (init_fnc_t) (void); init_fnc_t *init_sequence[] = { env_init, +#ifdef CONFIG_OF_CONTROL + fdtdec_check_fdt, +#endif serial_init, console_init_f, -#ifdef CONFIG_SYS_GPIO_0 - gpio_init, -#endif interrupts_init, -#ifdef CONFIG_SYS_TIMER_0 timer_init, -#endif -#ifdef CONFIG_SYS_FSL_2 - fsl_init2, -#endif NULL, }; unsigned long monitor_flash_len; -void board_init (void) +void board_init_f(ulong not_used) { bd_t *bd; init_fnc_t **init_fnc_ptr; gd = (gd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET); bd = (bd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET \ - GENERATED_BD_INFO_SIZE); - char *s; + __maybe_unused char *s; #if defined(CONFIG_CMD_FLASH) ulong flash_size = 0; #endif @@ -103,6 +90,17 @@ void board_init (void) monitor_flash_len = __end - __text_start; +#ifdef CONFIG_OF_EMBED + /* Get a pointer to the FDT */ + gd->fdt_blob = _binary_dt_dtb_start; +#elif defined CONFIG_OF_SEPARATE + /* FDT is at end of image */ + gd->fdt_blob = (void *)__end; +#endif + /* Allow the early environment to override the fdt address */ + gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, + (uintptr_t)gd->fdt_blob); + /* * The Malloc area is immediately below the monitor copy in DRAM * aka CONFIG_SYS_MONITOR_BASE - Note there is no need for reloc_off @@ -121,6 +119,15 @@ void board_init (void) } } +#ifdef CONFIG_OF_CONTROL + /* For now, put this check after the console is ready */ + if (fdtdec_prepare_fdt()) { + panic("** CONFIG_OF_CONTROL defined but no FDT - please see " + "doc/README.fdt-control"); + } else + printf("DTB: 0x%x\n", (u32)gd->fdt_blob); +#endif + puts ("SDRAM :\n"); printf ("\t\tIcache:%s\n", icache_status() ? "ON" : "OFF"); printf ("\t\tDcache:%s\n", dcache_status() ? "ON" : "OFF"); @@ -129,9 +136,8 @@ void board_init (void) #if defined(CONFIG_CMD_FLASH) puts ("Flash: "); bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; - if (0 < (flash_size = flash_init ())) { - bd->bi_flashsize = flash_size; - bd->bi_flashoffset = CONFIG_SYS_FLASH_BASE + flash_size; + flash_size = flash_init(); + if (bd->bi_flashstart && flash_size > 0) { # ifdef CONFIG_SYS_FLASH_CHECKSUM print_size (flash_size, ""); /* @@ -142,13 +148,16 @@ void board_init (void) s = getenv ("flashchecksum"); if (s && (*s == 'y')) { printf (" CRC: %08X", - crc32 (0, (const unsigned char *) CONFIG_SYS_FLASH_BASE, flash_size) + crc32(0, (const u8 *)bd->bi_flashstart, + flash_size) ); } putc ('\n'); # else /* !CONFIG_SYS_FLASH_CHECKSUM */ print_size (flash_size, "\n"); # endif /* CONFIG_SYS_FLASH_CHECKSUM */ + bd->bi_flashsize = flash_size; + bd->bi_flashoffset = bd->bi_flashstart + flash_size; } else { puts ("Flash init FAILED"); bd->bi_flashstart = 0; @@ -169,6 +178,8 @@ void board_init (void) /* Initialize the console (after the relocation and devices init) */ console_init_r(); + board_init(); + /* Initialize from environment */ load_addr = getenv_ulong("loadaddr", 16, load_addr); diff --git a/arch/mips/config.mk b/arch/mips/config.mk index 6ab8acd..de9140b 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -23,7 +23,21 @@ CROSS_COMPILE ?= mips_4KC- -CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds +# Handle special prefix in ELDK 4.0 toolchain +ifneq (,$(findstring 4KCle,$(CROSS_COMPILE))) +ENDIANNESS := -EL +endif + +ifdef CONFIG_SYS_LITTLE_ENDIAN +ENDIANNESS := -EL +endif + +ifdef CONFIG_SYS_BIG_ENDIAN +ENDIANNESS := -EB +endif + +# Default to EB if no endianess is configured +ENDIANNESS ?= -EB PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__ @@ -47,8 +61,8 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__ # On the other hand, we want PIC in the U-Boot code to relocate it from ROM # to RAM. $28 is always used as gp. # -PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic +PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic $(ENDIANNESS) PLATFORM_CPPFLAGS += -msoft-float -PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib +PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib $(ENDIANNESS) PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections LDFLAGS_FINAL += --gc-sections diff --git a/arch/mips/cpu/mips32/config.mk b/arch/mips/cpu/mips32/config.mk index a1cd590..481e984 100644 --- a/arch/mips/cpu/mips32/config.mk +++ b/arch/mips/cpu/mips32/config.mk @@ -29,21 +29,6 @@ # MIPSFLAGS := -march=mips32r2 -# Handle special prefix in ELDK 4.0 toolchain -ifneq (,$(findstring 4KCle,$(CROSS_COMPILE))) -ENDIANNESS := -EL -endif +PLATFORM_CPPFLAGS += $(MIPSFLAGS) -ifdef CONFIG_SYS_LITTLE_ENDIAN -ENDIANNESS := -EL -endif - -ifdef CONFIG_SYS_BIG_ENDIAN -ENDIANNESS := -EB -endif - -# Default to EB if no endianess is configured -ENDIANNESS ?= -EB - -PLATFORM_CPPFLAGS += $(MIPSFLAGS) $(ENDIANNESS) -PLATFORM_LDFLAGS += $(ENDIANNESS) +CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds diff --git a/arch/mips/cpu/xburst/config.mk b/arch/mips/cpu/xburst/config.mk index bce0c1b..1536746 100644 --- a/arch/mips/cpu/xburst/config.mk +++ b/arch/mips/cpu/xburst/config.mk @@ -20,5 +20,6 @@ # MA 02111-1307 USA # -PLATFORM_CPPFLAGS += -march=mips32 -EL -PLATFORM_LDFLAGS += -EL +PLATFORM_CPPFLAGS += -march=mips32 + +CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds diff --git a/arch/mips/cpu/xburst/cpu.c b/arch/mips/cpu/xburst/cpu.c index e976341..ddcbfaa 100644 --- a/arch/mips/cpu/xburst/cpu.c +++ b/arch/mips/cpu/xburst/cpu.c @@ -62,7 +62,7 @@ void __attribute__((weak)) _machine_restart(void) writew(100, &wdt->tdr); /* wdt_set_data(100) */ writew(0, &wdt->tcnt); /* wdt_set_count(0); */ - writew(TCU_TSSR_WDTSC, &tcu->tscr); /* tcu_start_wdt_clock */ + writel(TCU_TSSR_WDTSC, &tcu->tscr); /* tcu_start_wdt_clock */ writeb(readb(&wdt->tcer) | WDT_TCER_TCEN, &wdt->tcer); /* wdt start */ while (1) diff --git a/arch/mips/cpu/xburst/timer.c b/arch/mips/cpu/xburst/timer.c index de6f5da..b6b3855 100644 --- a/arch/mips/cpu/xburst/timer.c +++ b/arch/mips/cpu/xburst/timer.c @@ -34,13 +34,13 @@ static struct jz4740_tcu *tcu = (struct jz4740_tcu *)JZ4740_TCU_BASE; void reset_timer_masked(void) { /* reset time */ - gd->lastinc = readw(&tcu->tcnt0); + gd->lastinc = readl(&tcu->tcnt0); gd->tbl = 0; } ulong get_timer_masked(void) { - ulong now = readw(&tcu->tcnt0); + ulong now = readl(&tcu->tcnt0); if (gd->lastinc <= now) gd->tbl += now - gd->lastinc; /* normal mode */ @@ -83,11 +83,11 @@ void udelay_masked(unsigned long usec) int timer_init(void) { - writew(TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN, &tcu->tcsr0); + writel(TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN, &tcu->tcsr0); - writew(0, &tcu->tcnt0); - writew(0, &tcu->tdhr0); - writew(TIMER_FDATA, &tcu->tdfr0); + writel(0, &tcu->tcnt0); + writel(0, &tcu->tdhr0); + writel(TIMER_FDATA, &tcu->tdfr0); /* mask irqs */ writel((1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)), &tcu->tmsr); diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 9244f31..967e98a 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -25,6 +25,13 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).o +## Build a couple of necessary functions into a private libgcc +LIBGCC = $(obj)libgcc.o +GLSOBJS += ashldi3.o +GLSOBJS += ashrdi3.o +GLSOBJS += lshrdi3.o +LGOBJS := $(addprefix $(obj),$(GLSOBJS)) + SOBJS-y += COBJS-y += board.o @@ -37,9 +44,22 @@ endif SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) +# Always build libmips.o +TARGETS := $(LIB) + +# Build private libgcc only when asked for +ifdef USE_PRIVATE_LIBGCC +TARGETS += $(LIBGCC) +endif + +all: $(TARGETS) + $(LIB): $(obj).depend $(OBJS) $(call cmd_link_o_target, $(OBJS)) +$(LIBGCC): $(obj).depend $(LGOBJS) + $(call cmd_link_o_target, $(LGOBJS)) + ######################################################################### # defines $(obj).depend target diff --git a/arch/mips/lib/ashldi3.c b/arch/mips/lib/ashldi3.c new file mode 100644 index 0000000..9b50d86 --- /dev/null +++ b/arch/mips/lib/ashldi3.c @@ -0,0 +1,25 @@ +#include "libgcc.h" + +long long __ashldi3(long long u, word_type b) +{ + DWunion uu, w; + word_type bm; + + if (b == 0) + return u; + + uu.ll = u; + bm = 32 - b; + + if (bm <= 0) { + w.s.low = 0; + w.s.high = (unsigned int) uu.s.low << -bm; + } else { + const unsigned int carries = (unsigned int) uu.s.low >> bm; + + w.s.low = (unsigned int) uu.s.low << b; + w.s.high = ((unsigned int) uu.s.high << b) | carries; + } + + return w.ll; +} diff --git a/arch/mips/lib/ashrdi3.c b/arch/mips/lib/ashrdi3.c new file mode 100644 index 0000000..f30359b --- /dev/null +++ b/arch/mips/lib/ashrdi3.c @@ -0,0 +1,27 @@ +#include "libgcc.h" + +long long __ashrdi3(long long u, word_type b) +{ + DWunion uu, w; + word_type bm; + + if (b == 0) + return u; + + uu.ll = u; + bm = 32 - b; + + if (bm <= 0) { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = + uu.s.high >> 31; + w.s.low = uu.s.high >> -bm; + } else { + const unsigned int carries = (unsigned int) uu.s.high << bm; + + w.s.high = uu.s.high >> b; + w.s.low = ((unsigned int) uu.s.low >> b) | carries; + } + + return w.ll; +} diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c index 62d47a8..b14b33e 100644 --- a/arch/mips/lib/board.c +++ b/arch/mips/lib/board.c @@ -248,7 +248,6 @@ void board_init_r(gd_t *id, ulong dest_addr) #ifndef CONFIG_SYS_NO_FLASH ulong size; #endif - extern void malloc_bin_reloc(void); #ifndef CONFIG_ENV_IS_NOWHERE extern char *env_name_spec; #endif diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h new file mode 100644 index 0000000..05909d5 --- /dev/null +++ b/arch/mips/lib/libgcc.h @@ -0,0 +1,25 @@ +#ifndef __ASM_LIBGCC_H +#define __ASM_LIBGCC_H + +#include <asm/byteorder.h> + +typedef int word_type __attribute__ ((mode (__word__))); + +#ifdef __BIG_ENDIAN +struct DWstruct { + int high, low; +}; +#elif defined(__LITTLE_ENDIAN) +struct DWstruct { + int low, high; +}; +#else +#error I feel sick. +#endif + +typedef union { + struct DWstruct s; + long long ll; +} DWunion; + +#endif /* __ASM_LIBGCC_H */ diff --git a/arch/mips/lib/lshrdi3.c b/arch/mips/lib/lshrdi3.c new file mode 100644 index 0000000..bb340ac --- /dev/null +++ b/arch/mips/lib/lshrdi3.c @@ -0,0 +1,25 @@ +#include "libgcc.h" + +long long __lshrdi3(long long u, word_type b) +{ + DWunion uu, w; + word_type bm; + + if (b == 0) + return u; + + uu.ll = u; + bm = 32 - b; + + if (bm <= 0) { + w.s.high = 0; + w.s.low = (unsigned int) uu.s.high >> -bm; + } else { + const unsigned int carries = (unsigned int) uu.s.high << bm; + + w.s.high = (unsigned int) uu.s.high >> b; + w.s.low = ((unsigned int) uu.s.low >> b) | carries; + } + + return w.ll; +} diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c index 2164a50..17d3ee0 100644 --- a/arch/nds32/lib/board.c +++ b/arch/nds32/lib/board.c @@ -306,8 +306,6 @@ void board_init_r(gd_t *id, ulong dest_addr) bd_t *bd; ulong malloc_start; - extern void malloc_bin_reloc(void); - gd = id; bd = gd->bd; diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile index 34f6c54..33e93c8 100644 --- a/arch/powerpc/cpu/mpc85xx/Makefile +++ b/arch/powerpc/cpu/mpc85xx/Makefile @@ -55,8 +55,6 @@ COBJS-$(CONFIG_P1011) += ddr-gen3.o COBJS-$(CONFIG_P1012) += ddr-gen3.o COBJS-$(CONFIG_P1013) += ddr-gen3.o COBJS-$(CONFIG_P1014) += ddr-gen3.o -COBJS-$(CONFIG_P1015) += ddr-gen3.o -COBJS-$(CONFIG_P1016) += ddr-gen3.o COBJS-$(CONFIG_P1020) += ddr-gen3.o COBJS-$(CONFIG_P1021) += ddr-gen3.o COBJS-$(CONFIG_P1022) += ddr-gen3.o @@ -64,10 +62,8 @@ COBJS-$(CONFIG_P1024) += ddr-gen3.o COBJS-$(CONFIG_P1025) += ddr-gen3.o COBJS-$(CONFIG_P2010) += ddr-gen3.o COBJS-$(CONFIG_P2020) += ddr-gen3.o -COBJS-$(CONFIG_PPC_P2040) += ddr-gen3.o COBJS-$(CONFIG_PPC_P2041) += ddr-gen3.o COBJS-$(CONFIG_PPC_P3041) += ddr-gen3.o -COBJS-$(CONFIG_PPC_P3060) += ddr-gen3.o COBJS-$(CONFIG_PPC_P4080) += ddr-gen3.o COBJS-$(CONFIG_PPC_P5020) += ddr-gen3.o COBJS-$(CONFIG_BSC9131) += ddr-gen3.o @@ -80,10 +76,8 @@ COBJS-$(CONFIG_PCI) += pci.o COBJS-$(CONFIG_SYS_DPAA_QBMAN) += portals.o # various SoC specific assignments -COBJS-$(CONFIG_PPC_P2040) += p2041_ids.o COBJS-$(CONFIG_PPC_P2041) += p2041_ids.o COBJS-$(CONFIG_PPC_P3041) += p3041_ids.o -COBJS-$(CONFIG_PPC_P3060) += p3060_ids.o COBJS-$(CONFIG_PPC_P4080) += p4080_ids.o COBJS-$(CONFIG_PPC_P5020) += p5020_ids.o @@ -103,8 +97,6 @@ COBJS-$(CONFIG_P1011) += p1021_serdes.o COBJS-$(CONFIG_P1012) += p1021_serdes.o COBJS-$(CONFIG_P1013) += p1022_serdes.o COBJS-$(CONFIG_P1014) += p1010_serdes.o -COBJS-$(CONFIG_P1015) += p1021_serdes.o -COBJS-$(CONFIG_P1016) += p1021_serdes.o COBJS-$(CONFIG_P1017) += p1023_serdes.o COBJS-$(CONFIG_P1020) += p1021_serdes.o COBJS-$(CONFIG_P1021) += p1021_serdes.o @@ -114,10 +106,8 @@ COBJS-$(CONFIG_P1024) += p1021_serdes.o COBJS-$(CONFIG_P1025) += p1021_serdes.o COBJS-$(CONFIG_P2010) += p2020_serdes.o COBJS-$(CONFIG_P2020) += p2020_serdes.o -COBJS-$(CONFIG_PPC_P2040) += p2041_serdes.o COBJS-$(CONFIG_PPC_P2041) += p2041_serdes.o COBJS-$(CONFIG_PPC_P3041) += p3041_serdes.o -COBJS-$(CONFIG_PPC_P3060) += p3060_serdes.o COBJS-$(CONFIG_PPC_P4080) += p4080_serdes.o COBJS-$(CONFIG_PPC_P5020) += p5020_serdes.o diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index 4e1a54a..e8989bd 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -27,6 +27,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 + extern int enable_cpu_a011_workaround; +#endif __maybe_unused u32 svr = get_svr(); #if defined(CONFIG_FSL_SATA_V2) && defined(CONFIG_FSL_SATA_ERRATUM_A001) @@ -56,8 +59,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0 * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1 + * The SVR has been checked by cpu_init_r(). */ - if (SVR_SOC_VER(svr) != SVR_P4080 || SVR_MAJ(svr) < 3) + if (enable_cpu_a011_workaround) puts("Work-around for Erratum CPU-A011 enabled\n"); #endif #if defined(CONFIG_SYS_FSL_ERRATUM_CPU_A003999) @@ -120,6 +124,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0)) puts("Work-around for Erratum NMG ETSEC129 enabled\n"); #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 + puts("Work-around for Erratum A004510 enabled\n"); +#endif return 0; } diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index c1815e8..5ddb294 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -117,6 +117,9 @@ int checkcpu (void) case PVR_VER_E5500: puts("E5500"); break; + case PVR_VER_E6500: + puts("E6500"); + break; default: puts("Unknown"); break; @@ -427,11 +430,21 @@ static void dump_spd_ddr_reg(void) case 0: ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR; break; -#ifdef CONFIG_SYS_MPC85xx_DDR2_ADDR +#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) case 1: ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR; break; #endif +#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) + case 2: + ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR; + break; +#endif +#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) + case 3: + ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR; + break; +#endif default: printf("%s unexpected controller number = %u\n", __func__, i); diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index fc6c287..afb5671 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -38,6 +38,7 @@ #include <asm/fsl_law.h> #include <asm/fsl_serdes.h> #include <asm/fsl_srio.h> +#include <hwconfig.h> #include <linux/compiler.h> #include "mp.h" #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND @@ -311,11 +312,41 @@ int cpu_init_r(void) #if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \ defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011) /* + * CPU22 and NMG_CPU_A011 share the same workaround. * CPU22 applies to P4080 rev 1.0, 2.0, fixed in 3.0 * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0 - * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1 + * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1, both + * fixed in 2.0. NMG_CPU_A011 is activated by default and can + * be disabled by hwconfig with syntax: + * + * fsl_cpu_a011:disable */ - if (SVR_SOC_VER(svr) != SVR_P4080 || SVR_MAJ(svr) < 3) { + extern int enable_cpu_a011_workaround; +#ifdef CONFIG_SYS_P4080_ERRATUM_CPU22 + enable_cpu_a011_workaround = (SVR_MAJ(svr) < 3); +#else + char buffer[HWCONFIG_BUFFER_SIZE]; + char *buf = NULL; + int n, res; + + n = getenv_f("hwconfig", buffer, sizeof(buffer)); + if (n > 0) + buf = buffer; + + res = hwconfig_arg_cmp_f("fsl_cpu_a011", "disable", buf); + if (res > 0) + enable_cpu_a011_workaround = 0; + else { + if (n >= HWCONFIG_BUFFER_SIZE) { + printf("fsl_cpu_a011 was not found. hwconfig variable " + "may be too long\n"); + } + enable_cpu_a011_workaround = + (SVR_SOC_VER(svr) == SVR_P4080 && SVR_MAJ(svr) < 3) || + (SVR_SOC_VER(svr) != SVR_P4080 && SVR_MAJ(svr) < 2); + } +#endif + if (enable_cpu_a011_workaround) { flush_dcache(); mtspr(L1CSR2, (mfspr(L1CSR2) | L1CSR2_DCWS)); sync(); @@ -447,11 +478,18 @@ skip_l2: #ifdef CONFIG_SYS_SRIO srio_init(); -#ifdef CONFIG_SRIOBOOT_MASTER - srio_boot_master(); -#ifdef CONFIG_SRIOBOOT_SLAVE_HOLDOFF - srio_boot_master_release_slave(); -#endif +#ifdef CONFIG_FSL_CORENET + char *s = getenv("bootmaster"); + if (s) { + if (!strcmp(s, "SRIO1")) { + srio_boot_master(1); + srio_boot_master_release_slave(1); + } + if (!strcmp(s, "SRIO2")) { + srio_boot_master(2); + srio_boot_master_release_slave(2); + } + } #endif #endif diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c index 81961de..ca4ed62 100644 --- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c +++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -32,9 +32,21 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, case 0: ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR; break; +#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) case 1: ddr = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR; break; +#endif +#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) + case 2: + ddr = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR; + break; +#endif +#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) + case 3: + ddr = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR; + break; +#endif default: printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num); return; @@ -43,6 +55,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, out_be32(&ddr->eor, regs->ddr_eor); #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 + debug("Workaround for ERRATUM_DDR111_DDR134\n"); for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { cs_sa = (regs->cs[i].bnds >> 16) & 0xfff; cs_ea = regs->cs[i].bnds & 0xfff; @@ -115,8 +128,12 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, out_be32(&ddr->ddr_cdr2, regs->ddr_cdr2); out_be32(&ddr->err_disable, regs->err_disable); out_be32(&ddr->err_int_en, regs->err_int_en); - for (i = 0; i < 32; i++) - out_be32(&ddr->debug[i], regs->debug[i]); + for (i = 0; i < 32; i++) { + if (regs->debug[i]) { + debug("Write to debug_%d as %08x\n", i+1, regs->debug[i]); + out_be32(&ddr->debug[i], regs->debug[i]); + } + } #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003474 out_be32(&ddr->debug[12], 0x00000015); @@ -128,6 +145,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN); out_be32(&ddr->sdram_cfg, temp_sdram_cfg); #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003 + debug("Workaround for ERRATUM_DDR_A003\n"); if (regs->ddr_sdram_rcw_2 & 0x00f00000) { out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2 & 0xf07fffff); out_be32(&ddr->debug[2], 0x00000400); @@ -209,6 +227,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, * This erratum does not affect DDR3 mode, only for DDR2 mode. */ #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_115 + debug("Workaround for ERRATUM_DDR_115\n"); if ((((in_be32(&ddr->sdram_cfg) >> 24) & 0x7) == SDRAM_TYPE_DDR2) && in_be32(&ddr->sdram_cfg) & 0x80000) { /* set DEBUG_1[31] */ @@ -216,6 +235,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, } #endif #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 + debug("Workaround for ERRATUM_DDR111_DDR134\n"); /* * This is the combined workaround for DDR111 and DDR134 * following the published errata for MPC8572 diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 21c3ad4..a0a9b4c 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -57,8 +57,9 @@ void ft_fixup_cpu(void *blob, u64 memory_limit) u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0); if (reg) { - u64 val = *reg * SIZE_BOOT_ENTRY + spin_tbl_addr; - val = cpu_to_fdt32(val); + u32 phys_cpu_id = thread_to_core(*reg); + u64 val = phys_cpu_id * SIZE_BOOT_ENTRY + spin_tbl_addr; + val = cpu_to_fdt64(val); if (*reg == id) { fdt_setprop_string(blob, off, "status", "okay"); @@ -534,7 +535,7 @@ void fdt_fixup_fman_firmware(void *blob) #define fdt_fixup_fman_firmware(x) #endif -#if defined(CONFIG_PPC_P4080) || defined(CONFIG_PPC_P3060) +#if defined(CONFIG_PPC_P4080) static void fdt_fixup_usb(void *fdt) { ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c index 4b52dad..2a68060 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -46,8 +46,6 @@ static u32 serdes_prtcl_map; -#define HWCONFIG_BUFFER_SIZE 128 - #ifdef DEBUG static const char *serdes_prtcl_str[] = { [NONE] = "NA", @@ -68,6 +66,7 @@ static const char *serdes_prtcl_str[] = { [SGMII_FM2_DTSEC2] = "SGMII_FM2_DTSEC2", [SGMII_FM2_DTSEC3] = "SGMII_FM2_DTSEC3", [SGMII_FM2_DTSEC4] = "SGMII_FM2_DTSEC4", + [SGMII_FM2_DTSEC5] = "SGMII_FM2_DTSEC5", [XAUI_FM1] = "XAUI_FM1", [XAUI_FM2] = "XAUI_FM2", [AURORA] = "DEBUG", @@ -658,6 +657,7 @@ void fsl_serdes_init(void) case SGMII_FM2_DTSEC2: case SGMII_FM2_DTSEC3: case SGMII_FM2_DTSEC4: + case SGMII_FM2_DTSEC5: case XAUI_FM1: case XAUI_FM2: case SRIO1: @@ -717,6 +717,10 @@ void fsl_serdes_init(void) serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 | FSL_CORENET_DEVDISR2_DTSEC2_4; break; + case SGMII_FM2_DTSEC5: + serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 | + FSL_CORENET_DEVDISR2_DTSEC2_5; + break; case XAUI_FM1: serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 | FSL_CORENET_DEVDISR2_10GEC1; diff --git a/arch/powerpc/cpu/mpc85xx/p3060_ids.c b/arch/powerpc/cpu/mpc85xx/p3060_ids.c deleted file mode 100644 index d32142f..0000000 --- a/arch/powerpc/cpu/mpc85xx/p3060_ids.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/fsl_portals.h> -#include <asm/fsl_liodn.h> - -#ifdef CONFIG_SYS_DPAA_QBMAN -struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = { - /* dqrr liodn, frame data liodn, liodn off, sdest */ - SET_QP_INFO( 1, 2, 1, 0), - SET_QP_INFO( 3, 4, 2, 1), - SET_QP_INFO( 5, 6, 3, 2), - SET_QP_INFO( 7, 8, 4, 3), - SET_QP_INFO( 9, 10, 5, 4), - SET_QP_INFO(11, 12, 6, 5), - SET_QP_INFO(13, 14, 7, 6), - SET_QP_INFO(15, 16, 8, 7), - SET_QP_INFO(17, 18, 9, 0), /* for now sdest to 0 */ - SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */ -}; -#endif - -struct srio_liodn_id_table srio_liodn_tbl[] = { - SET_SRIO_LIODN_1(1, 198), - SET_SRIO_LIODN_1(2, 199), -}; -int srio_liodn_tbl_sz = ARRAY_SIZE(srio_liodn_tbl); - -struct liodn_id_table liodn_tbl[] = { - SET_USB_LIODN(1, "fsl-usb2-mph", 127), - SET_USB_LIODN(2, "fsl-usb2-dr", 157), - - SET_PCI_LIODN("fsl,qoriq-pcie-v2.2", 1, 193), - SET_PCI_LIODN("fsl,qoriq-pcie-v2.2", 2, 194), - - SET_DMA_LIODN(1, 196), - SET_DMA_LIODN(2, 197), - - SET_GUTS_LIODN("fsl,srio-rmu", 200, rmuliodnr, 0xd3000), - -#ifdef CONFIG_SYS_DPAA_QBMAN - SET_QMAN_LIODN(31), - SET_BMAN_LIODN(32), -#endif - SET_PME_LIODN(128), -}; -int liodn_tbl_sz = ARRAY_SIZE(liodn_tbl); - -#ifdef CONFIG_SYS_DPAA_FMAN -struct liodn_id_table fman1_liodn_tbl[] = { - SET_FMAN_RX_1G_LIODN(1, 0, 11), - SET_FMAN_RX_1G_LIODN(1, 1, 12), - SET_FMAN_RX_1G_LIODN(1, 2, 13), - SET_FMAN_RX_1G_LIODN(1, 3, 14), -}; -int fman1_liodn_tbl_sz = ARRAY_SIZE(fman1_liodn_tbl); - -#if (CONFIG_SYS_NUM_FMAN == 2) -struct liodn_id_table fman2_liodn_tbl[] = { - SET_FMAN_RX_1G_LIODN(2, 0, 16), - SET_FMAN_RX_1G_LIODN(2, 1, 17), - SET_FMAN_RX_1G_LIODN(2, 2, 18), - SET_FMAN_RX_1G_LIODN(2, 3, 19), -}; -int fman2_liodn_tbl_sz = ARRAY_SIZE(fman2_liodn_tbl); -#endif -#endif - -struct liodn_id_table sec_liodn_tbl[] = { - SET_SEC_JR_LIODN_ENTRY(0, 146, 154), - SET_SEC_JR_LIODN_ENTRY(1, 147, 155), - SET_SEC_JR_LIODN_ENTRY(2, 178, 186), - SET_SEC_JR_LIODN_ENTRY(3, 179, 187), - SET_SEC_RTIC_LIODN_ENTRY(a, 144), - SET_SEC_RTIC_LIODN_ENTRY(b, 145), - SET_SEC_RTIC_LIODN_ENTRY(c, 176), - SET_SEC_RTIC_LIODN_ENTRY(d, 177), - SET_SEC_DECO_LIODN_ENTRY(0, 129, 161), - SET_SEC_DECO_LIODN_ENTRY(1, 130, 162), - SET_SEC_DECO_LIODN_ENTRY(2, 131, 163), - SET_SEC_DECO_LIODN_ENTRY(3, 132, 164), - SET_SEC_DECO_LIODN_ENTRY(4, 133, 165), -}; -int sec_liodn_tbl_sz = ARRAY_SIZE(sec_liodn_tbl); - -struct liodn_id_table liodn_bases[] = { - [FSL_HW_PORTAL_SEC] = SET_LIODN_BASE_2(96, 106), -#ifdef CONFIG_SYS_DPAA_FMAN - [FSL_HW_PORTAL_FMAN1] = SET_LIODN_BASE_1(32), -#if (CONFIG_SYS_NUM_FMAN == 2) - [FSL_HW_PORTAL_FMAN2] = SET_LIODN_BASE_1(64), -#endif -#endif -#ifdef CONFIG_SYS_DPAA_PME - [FSL_HW_PORTAL_PME] = SET_LIODN_BASE_2(116, 133), -#endif -}; diff --git a/arch/powerpc/cpu/mpc85xx/p3060_serdes.c b/arch/powerpc/cpu/mpc85xx/p3060_serdes.c deleted file mode 100644 index e720dcf..0000000 --- a/arch/powerpc/cpu/mpc85xx/p3060_serdes.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/fsl_serdes.h> -#include <asm/processor.h> -#include <asm/io.h> -#include "fsl_corenet_serdes.h" - -static u8 serdes_cfg_tbl[][SRDS_MAX_LANES] = { - [0x03] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2, - SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4, SGMII_FM2_DTSEC1, - SGMII_FM1_DTSEC1, SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, - NONE, NONE, AURORA, AURORA}, - [0x06] = {PCIE1, PCIE1, PCIE1, PCIE1, NONE, NONE, SGMII_FM2_DTSEC3, - SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4, - SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, SGMII_FM2_DTSEC2, - SGMII_FM1_DTSEC2, NONE, NONE, AURORA, AURORA}, - [0x16] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, - AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, - SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, SGMII_FM2_DTSEC3, - SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, - [0x19] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, - AURORA, AURORA, PCIE2, PCIE2, PCIE2, PCIE2, SGMII_FM2_DTSEC3, - SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, - [0x1c] = {NONE, NONE, SRIO1, SRIO2, NONE, NONE, NONE, NONE, - AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, - SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, SGMII_FM2_DTSEC3, - SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, -}; - -enum srds_prtcl serdes_get_prtcl(int cfg, int lane) -{ - if (!serdes_lane_enabled(lane)) - return NONE; - - return serdes_cfg_tbl[cfg][lane]; -} - -int is_serdes_prtcl_valid(u32 prtcl) -{ - int i; - - if (prtcl > ARRAY_SIZE(serdes_cfg_tbl)) - return 0; - - for (i = 0; i < SRDS_MAX_LANES; i++) { - if (serdes_cfg_tbl[prtcl][i] != NONE) - return 1; - } - - return 0; -} - -void soc_serdes_init(void) -{ - /* - * On the P3060 the devdisr2 register does not correctly reflect - * the state of the MACs based on the RCW fields. So disable the MACs - * based on the srds_prtcl and ec1, ec2, ec3 fields - */ - - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 devdisr2 = in_be32(&gur->devdisr2); - u32 rcwsr11 = in_be32(&gur->rcwsr[11]); - - /* NOTE: Leave FM1-1,FM1-2 alone for MDIO access */ - - if (!is_serdes_configured(SGMII_FM1_DTSEC3)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC1_3; - - if (!is_serdes_configured(SGMII_FM1_DTSEC4)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC1_4; - - if (!is_serdes_configured(SGMII_FM2_DTSEC1)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_1; - - if (!is_serdes_configured(SGMII_FM2_DTSEC2)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_2; - - if (!is_serdes_configured(SGMII_FM2_DTSEC3)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_3; - - if (!is_serdes_configured(SGMII_FM2_DTSEC4)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_4; - - if ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) { - devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC1_2; - } - - if ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1) { - devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC2_1; - } - - out_be32(&gur->devdisr2, devdisr2); -} diff --git a/arch/powerpc/cpu/mpc85xx/release.S b/arch/powerpc/cpu/mpc85xx/release.S index 1860684..22e73e0 100644 --- a/arch/powerpc/cpu/mpc85xx/release.S +++ b/arch/powerpc/cpu/mpc85xx/release.S @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * Kumar Gala <kumar.gala@freescale.com> * * See file CREDITS for list of people who contributed to this @@ -74,6 +74,33 @@ __secondary_start_page: mtspr 977,r3 #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 + mfspr r3,SPRN_SVR + rlwinm r3,r3,0,0xff + li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV + cmpw r3,r4 + beq 1f + +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 + li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 + cmpw r3,r4 + beq 1f +#endif + + /* Not a supported revision affected by erratum */ + b 2f + +1: /* Erratum says set bits 55:60 to 001001 */ + msync + isync + mfspr r3,976 + li r4,0x48 + rlwimi r3,r4,0,0x1f8 + mtspr 976,r3 + isync +2: +#endif + /* Enable branch prediction */ lis r3,BUCSR_ENABLE@h ori r3,r3,BUCSR_ENABLE@l @@ -128,7 +155,27 @@ __secondary_start_page: /* r10 has the base address for the entry */ mfspr r0,SPRN_PIR -#ifdef CONFIG_E500MC +#if defined(CONFIG_E6500) +/* + * PIR definition for E6500 + * 0-17 Reserved (logic 0s) + * 8-19 CHIP_ID, 2’b00 - SoC 1 + * all others - reserved + * 20-24 CLUSTER_ID 5’b00000 - CCM 1 + * all others - reserved + * 25-26 CORE_CLUSTER_ID 2’b00 - cluster 1 + * 2’b01 - cluster 2 + * 2’b10 - cluster 3 + * 2’b11 - cluster 4 + * 27-28 CORE_ID 2’b00 - core 0 + * 2’b01 - core 1 + * 2’b10 - core 2 + * 2’b11 - core 3 + * 29-31 THREAD_ID 3’b000 - thread 0 + * 3’b001 - thread 1 + */ + rlwinm r4,r0,29,25,31 +#elif defined(CONFIG_E500MC) rlwinm r4,r0,27,27,31 #else mr r4,r0 @@ -143,6 +190,25 @@ __secondary_start_page: mtspr L1CSR2,r8 #endif +#ifdef CONFIG_E6500 + mfspr r0,SPRN_PIR + /* + * core 0 thread 0: pir reset value 0x00, new pir 0 + * core 0 thread 1: pir reset value 0x01, new pir 1 + * core 1 thread 0: pir reset value 0x08, new pir 2 + * core 1 thread 1: pir reset value 0x09, new pir 3 + * core 2 thread 0: pir reset value 0x10, new pir 4 + * core 2 thread 1: pir reset value 0x11, new pir 5 + * etc. + * + * Only thread 0 of each core will be running, updating PIR doesn't + * need to deal with the thread bits. + */ + rlwinm r4,r0,30,24,30 +#endif + + mtspr SPRN_PIR,r4 /* write to PIR register */ + #if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \ defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011) /* @@ -163,6 +229,12 @@ __secondary_start_page: cmpw r3,r5 bge 2f 1: +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 + lis r3,toreset(enable_cpu_a011_workaround)@ha + lwz r3,toreset(enable_cpu_a011_workaround)@l(r3) + cmpwi r3,0 + beq 2f +#endif mfspr r3,L1CSR2 oris r3,r3,(L1CSR2_DCWS)@h mtspr L1CSR2,r3 @@ -220,7 +292,7 @@ __secondary_start_page: /* setup the entry */ li r3,0 li r8,1 - stw r0,ENTRY_PIR(r10) + stw r4,ENTRY_PIR(r10) stw r3,ENTRY_ADDR_UPPER(r10) stw r8,ENTRY_ADDR_LOWER(r10) stw r3,ENTRY_R3_UPPER(r10) @@ -346,6 +418,15 @@ __bootpg_addr: __spin_table: .space CONFIG_MAX_CPUS*ENTRY_SIZE + /* + * This variable is set by cpu_init_r() after parsing hwconfig + * to enable workaround for erratum NMG_CPU_A011. + */ + .align L1_CACHE_SHIFT + .global enable_cpu_a011_workaround +enable_cpu_a011_workaround: + .long 1 + /* Fill in the empty space. The actual reset vector is * the last word of the page */ __secondary_start_code_end: diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index ce47532..abfeb26 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -186,8 +186,7 @@ void get_sys_info (sys_info_t * sysInfo) #endif #ifdef CONFIG_QE -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) sysInfo->freqQE = sysInfo->freqSystemBus; #else qe_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_QE_RATIO) diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index 6aabc30..9e04257 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -86,6 +86,35 @@ _start_e500: li r1,MSR_DE mtmsr r1 +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 + mfspr r3,SPRN_SVR + rlwinm r3,r3,0,0xff + li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV + cmpw r3,r4 + beq 1f + +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 + li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 + cmpw r3,r4 + beq 1f +#endif + + /* Not a supported revision affected by erratum */ + li r27,0 + b 2f + +1: li r27,1 /* Remember for later that we have the erratum */ + /* Erratum says set bits 55:60 to 001001 */ + msync + isync + mfspr r3,976 + li r4,0x48 + rlwimi r3,r4,0,0x1f8 + mtspr 976,r3 + isync +2: +#endif + #if defined(CONFIG_SECURE_BOOT) && defined(CONFIG_E500MC) /* ISBC uses L2 as stack. * Disable L2 cache here so that u-boot can enable it later @@ -406,12 +435,11 @@ l2_disabled: * Search for the TLB that covers the code we're executing, and shrink it * so that it covers only this 4K page. That will ensure that any other * TLB we create won't interfere with it. We assume that the TLB exists, - * which is why we don't check the Valid bit of MAS1. + * which is why we don't check the Valid bit of MAS1. We also assume + * it is in TLB1. * * This is necessary, for example, when booting from the on-chip ROM, * which (oddly) creates a single 4GB TLB that covers CCSR and DDR. - * If we don't shrink this TLB now, then we'll accidentally delete it - * in "purge_old_ccsr_tlb" below. */ bl nexti /* Find our address */ nexti: mflr r1 /* R1 = our PC */ @@ -421,11 +449,15 @@ nexti: mflr r1 /* R1 = our PC */ msync tlbsx 0, r1 /* This must succeed */ + mfspr r14, MAS0 /* Save ESEL for later */ + rlwinm r14, r14, 16, 0xfff + /* Set the size of the TLB to 4KB */ mfspr r3, MAS1 li r2, 0xF00 andc r3, r3, r2 /* Clear the TSIZE bits */ ori r3, r3, MAS1_TSIZE(BOOKE_PAGESZ_4K)@l + oris r3, r3, MAS1_IPROT@h mtspr MAS1, r3 /* @@ -440,6 +472,14 @@ nexti: mflr r1 /* R1 = our PC */ mfspr r2, MAS2 andc r2, r2, r3 or r2, r2, r1 +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 + cmpwi r27,0 + beq 1f + andi. r15, r2, MAS2_I|MAS2_G /* save the old I/G for later */ + rlwinm r2, r2, 0, ~MAS2_I + ori r2, r2, MAS2_G +1: +#endif mtspr MAS2, r2 /* Set the EPN to our PC base address */ mfspr r2, MAS3 @@ -452,6 +492,39 @@ nexti: mflr r1 /* R1 = our PC */ tlbwe /* + * Clear out any other TLB entries that may exist, to avoid conflicts. + * Our TLB entry is in r14. + */ + li r0, TLBIVAX_ALL | TLBIVAX_TLB0 + tlbivax 0, r0 + tlbsync + + mfspr r4, SPRN_TLB1CFG + rlwinm r4, r4, 0, TLBnCFG_NENTRY_MASK + + li r3, 0 + mtspr MAS1, r3 +1: cmpw r3, r14 +#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(CONFIG_NAND_SPL) + cmpwi cr1, r3, CONFIG_SYS_PPC_E500_DEBUG_TLB + cror cr0*4+eq, cr0*4+eq, cr1*4+eq +#endif + rlwinm r5, r3, 16, MAS0_ESEL_MSK + addi r3, r3, 1 + beq 2f /* skip the entry we're executing from */ + + oris r5, r5, MAS0_TLBSEL(1)@h + mtspr MAS0, r5 + + isync + tlbwe + isync + msync + +2: cmpw r3, r4 + blt 1b + +/* * Relocate CCSR, if necessary. We relocate CCSR if (obviously) the default * location is not where we want it. This typically happens on a 36-bit * system, where we want to move CCSR to near the top of 36-bit address space. @@ -469,41 +542,15 @@ nexti: mflr r1 /* R1 = our PC */ #error "CONFIG_SYS_CCSRBAR_PHYS_HIGH and CONFIG_SYS_CCSRBAR_PHYS_LOW) must be defined." #endif -purge_old_ccsr_tlb: - lis r8, CONFIG_SYS_CCSRBAR@h - ori r8, r8, CONFIG_SYS_CCSRBAR@l - lis r9, (CONFIG_SYS_CCSRBAR + 0x1000)@h - ori r9, r9, (CONFIG_SYS_CCSRBAR + 0x1000)@l - - /* - * In a multi-stage boot (e.g. NAND boot), a previous stage may have - * created a TLB for CCSR, which will interfere with our relocation - * code. Since we're going to create a new TLB for CCSR anyway, - * it should be safe to delete this old TLB here. We have to search - * for it, though. - */ - - li r1, 0 - mtspr MAS6, r1 /* Search the current address space and PID */ - isync - msync - tlbsx 0, r8 - mfspr r1, MAS1 - andis. r2, r1, MAS1_VALID@h /* Check for the Valid bit */ - beq 1f /* Skip if no TLB found */ - - rlwinm r1, r1, 0, 1, 31 /* Clear Valid bit */ - mtspr MAS1, r1 - isync - msync - tlbwe -1: - create_ccsr_new_tlb: /* * Create a TLB for the new location of CCSR. Register R8 is reserved * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR). */ + lis r8, CONFIG_SYS_CCSRBAR@h + ori r8, r8, CONFIG_SYS_CCSRBAR@l + lis r9, (CONFIG_SYS_CCSRBAR + 0x1000)@h + ori r9, r9, (CONFIG_SYS_CCSRBAR + 0x1000)@l lis r0, FSL_BOOKE_MAS0(0, 0, 0)@h ori r0, r0, FSL_BOOKE_MAS0(0, 0, 0)@l lis r1, FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@h @@ -719,6 +766,253 @@ delete_temp_tlbs: tlbwe #endif /* #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) */ +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 +#define DCSR_LAWBARH0 (CONFIG_SYS_CCSRBAR + 0x1000) +#define LAW_SIZE_1M 0x13 +#define DCSRBAR_LAWAR (LAW_EN | (0x1d << 20) | LAW_SIZE_1M) + + cmpwi r27,0 + beq 9f + + /* + * Create a TLB entry for CCSR + * + * We're executing out of TLB1 entry in r14, and that's the only + * TLB entry that exists. To allocate some TLB entries for our + * own use, flip a bit high enough that we won't flip it again + * via incrementing. + */ + + xori r8, r14, 32 + lis r0, MAS0_TLBSEL(1)@h + rlwimi r0, r8, 16, MAS0_ESEL_MSK + lis r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)@h + ori r1, r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)@l + lis r7, CONFIG_SYS_CCSRBAR@h + ori r7, r7, CONFIG_SYS_CCSRBAR@l + ori r2, r7, MAS2_I|MAS2_G + lis r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@h + ori r3, r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@l + lis r4, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h + ori r4, r4, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l + mtspr MAS0, r0 + mtspr MAS1, r1 + mtspr MAS2, r2 + mtspr MAS3, r3 + mtspr MAS7, r4 + isync + tlbwe + isync + msync + + /* Map DCSR temporarily to physical address zero */ + li r0, 0 + lis r3, DCSRBAR_LAWAR@h + ori r3, r3, DCSRBAR_LAWAR@l + + stw r0, 0xc00(r7) /* LAWBARH0 */ + stw r0, 0xc04(r7) /* LAWBARL0 */ + sync + stw r3, 0xc08(r7) /* LAWAR0 */ + + /* Read back from LAWAR to ensure the update is complete. */ + lwz r3, 0xc08(r7) /* LAWAR0 */ + isync + + /* Create a TLB entry for DCSR at zero */ + + addi r9, r8, 1 + lis r0, MAS0_TLBSEL(1)@h + rlwimi r0, r9, 16, MAS0_ESEL_MSK + lis r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M)@h + ori r1, r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M)@l + li r6, 0 /* DCSR effective address */ + ori r2, r6, MAS2_I|MAS2_G + li r3, MAS3_SW|MAS3_SR + li r4, 0 + mtspr MAS0, r0 + mtspr MAS1, r1 + mtspr MAS2, r2 + mtspr MAS3, r3 + mtspr MAS7, r4 + isync + tlbwe + isync + msync + + /* enable the timebase */ +#define CTBENR 0xe2084 + li r3, 1 + addis r4, r7, CTBENR@ha + stw r3, CTBENR@l(r4) + lwz r3, CTBENR@l(r4) + twi 0,r3,0 + isync + + .macro erratum_set_ccsr offset value + addis r3, r7, \offset@ha + lis r4, \value@h + addi r3, r3, \offset@l + ori r4, r4, \value@l + bl erratum_set_value + .endm + + .macro erratum_set_dcsr offset value + addis r3, r6, \offset@ha + lis r4, \value@h + addi r3, r3, \offset@l + ori r4, r4, \value@l + bl erratum_set_value + .endm + + erratum_set_dcsr 0xb0e08 0xe0201800 + erratum_set_dcsr 0xb0e18 0xe0201800 + erratum_set_dcsr 0xb0e38 0xe0400000 + erratum_set_dcsr 0xb0008 0x00900000 + erratum_set_dcsr 0xb0e40 0xe00a0000 + erratum_set_ccsr 0x18600 CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY + erratum_set_ccsr 0x10f00 0x415e5000 + erratum_set_ccsr 0x11f00 0x415e5000 + + /* Make temp mapping uncacheable again, if it was initially */ + bl 2f +2: mflr r3 + tlbsx 0, r3 + mfspr r4, MAS2 + rlwimi r4, r15, 0, MAS2_I + rlwimi r4, r15, 0, MAS2_G + mtspr MAS2, r4 + isync + tlbwe + isync + msync + + /* Clear the cache */ + lis r3,(L1CSR1_ICFI|L1CSR1_ICLFR)@h + ori r3,r3,(L1CSR1_ICFI|L1CSR1_ICLFR)@l + sync + isync + mtspr SPRN_L1CSR1,r3 + isync +2: sync + mfspr r4,SPRN_L1CSR1 + and. r4,r4,r3 + bne 2b + + lis r3,(L1CSR1_CPE|L1CSR1_ICE)@h + ori r3,r3,(L1CSR1_CPE|L1CSR1_ICE)@l + sync + isync + mtspr SPRN_L1CSR1,r3 + isync +2: sync + mfspr r4,SPRN_L1CSR1 + and. r4,r4,r3 + beq 2b + + /* Remove temporary mappings */ + lis r0, MAS0_TLBSEL(1)@h + rlwimi r0, r9, 16, MAS0_ESEL_MSK + li r3, 0 + mtspr MAS0, r0 + mtspr MAS1, r3 + isync + tlbwe + isync + msync + + li r3, 0 + stw r3, 0xc08(r7) /* LAWAR0 */ + lwz r3, 0xc08(r7) + isync + + lis r0, MAS0_TLBSEL(1)@h + rlwimi r0, r8, 16, MAS0_ESEL_MSK + li r3, 0 + mtspr MAS0, r0 + mtspr MAS1, r3 + isync + tlbwe + isync + msync + + b 9f + + /* r3 = addr, r4 = value, clobbers r5, r11, r12 */ +erratum_set_value: + /* Lock two cache lines into I-Cache */ + sync + mfspr r11, SPRN_L1CSR1 + rlwinm r11, r11, 0, ~L1CSR1_ICUL + sync + isync + mtspr SPRN_L1CSR1, r11 + isync + + mflr r12 + bl 5f +5: mflr r5 + addi r5, r5, 2f - 5b + icbtls 0, 0, r5 + addi r5, r5, 64 + + sync + mfspr r11, SPRN_L1CSR1 +3: andi. r11, r11, L1CSR1_ICUL + bne 3b + + icbtls 0, 0, r5 + addi r5, r5, 64 + + sync + mfspr r11, SPRN_L1CSR1 +3: andi. r11, r11, L1CSR1_ICUL + bne 3b + + b 2f + .align 6 + /* Inside a locked cacheline, wait a while, write, then wait a while */ +2: sync + + mfspr r5, SPRN_TBRL + addis r11, r5, 0x10000@h /* wait 65536 timebase ticks */ +4: mfspr r5, SPRN_TBRL + subf. r5, r5, r11 + bgt 4b + + stw r4, 0(r3) + + mfspr r5, SPRN_TBRL + addis r11, r5, 0x10000@h /* wait 65536 timebase ticks */ +4: mfspr r5, SPRN_TBRL + subf. r5, r5, r11 + bgt 4b + + sync + + /* + * Fill out the rest of this cache line and the next with nops, + * to ensure that nothing outside the locked area will be + * fetched due to a branch. + */ + .rept 19 + nop + .endr + + sync + mfspr r11, SPRN_L1CSR1 + rlwinm r11, r11, 0, ~L1CSR1_ICUL + sync + isync + mtspr SPRN_L1CSR1, r11 + isync + + mtlr r12 + blr + +9: +#endif + create_init_ram_area: lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l @@ -855,18 +1149,12 @@ version_string: .globl _start_cont _start_cont: /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/ - lis r1,CONFIG_SYS_INIT_RAM_ADDR@h - ori r1,r1,CONFIG_SYS_INIT_SP_OFFSET@l - + lis r3,(CONFIG_SYS_INIT_RAM_ADDR)@h + ori r3,r3,((CONFIG_SYS_INIT_SP_OFFSET-16)&~0xf)@l /* Align to 16 */ li r0,0 - stwu r0,-4(r1) - stwu r0,-4(r1) /* Terminate call chain */ - - stwu r1,-8(r1) /* Save back chain and move SP */ - lis r0,RESET_VECTOR@h /* Address of reset vector */ - ori r0,r0,RESET_VECTOR@l - stwu r1,-8(r1) /* Save back chain and move SP */ - stw r0,+12(r1) /* Save return addr (underflow vect) */ + stw r0,0(r3) /* Terminate Back Chain */ + stw r0,+4(r3) /* NULL return address. */ + mr r1,r3 /* Transfer to SP(r1) */ GET_GOT bl cpu_init_early_f diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c index cbc6742..78a8f92 100644 --- a/arch/powerpc/cpu/mpc8xxx/cpu.c +++ b/arch/powerpc/cpu/mpc8xxx/cpu.c @@ -57,8 +57,6 @@ struct cpu_type cpu_type_list [] = { CPU_TYPE_ENTRY(P1012, P1012, 1), CPU_TYPE_ENTRY(P1013, P1013, 1), CPU_TYPE_ENTRY(P1014, P1014, 1), - CPU_TYPE_ENTRY(P1015, P1015, 1), - CPU_TYPE_ENTRY(P1016, P1016, 1), CPU_TYPE_ENTRY(P1017, P1017, 1), CPU_TYPE_ENTRY(P1020, P1020, 2), CPU_TYPE_ENTRY(P1021, P1021, 2), @@ -71,7 +69,6 @@ struct cpu_type cpu_type_list [] = { CPU_TYPE_ENTRY(P2040, P2040, 4), CPU_TYPE_ENTRY(P2041, P2041, 4), CPU_TYPE_ENTRY(P3041, P3041, 4), - CPU_TYPE_ENTRY_MASK(P3060, P3060, 6, 0xf3), CPU_TYPE_ENTRY(P4040, P4040, 4), CPU_TYPE_ENTRY(P4080, P4080, 8), CPU_TYPE_ENTRY(P5010, P5010, 1), @@ -85,7 +82,39 @@ struct cpu_type cpu_type_list [] = { #endif }; -struct cpu_type cpu_type_unknown = CPU_TYPE_ENTRY(Unknown, Unknown, 1); +#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 +u32 compute_ppc_cpumask(void) +{ + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + int i = 0, count = 0; + u32 cluster, mask = 0; + + do { + int j; + cluster = in_be32(&gur->tp_cluster[i++].lower); + for (j = 0; j < 4; j++) { + u32 idx = (cluster >> (j*8)) & TP_CLUSTER_INIT_MASK; + u32 type = in_be32(&gur->tp_ityp[idx]); + + if (type & TP_ITYP_AV) { + if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_PPC) + mask |= 1 << count; + } + count++; + } + } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); + + return mask; +} +#else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ +/* + * Before chassis genenration 2, the cpumask should be hard-coded. + * In case of cpu type unknown or cpumask unset, use 1 as fail save. + */ +#define compute_ppc_cpumask() 1 +#endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ + +struct cpu_type cpu_type_unknown = CPU_TYPE_ENTRY(Unknown, Unknown, 0); struct cpu_type *identify_cpu(u32 ver) { @@ -113,6 +142,9 @@ u32 cpu_mask() return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> MPC8xxx_PICFRR_NCPU_SHIFT) + 1; + if (cpu->num_cores == 0) + return compute_ppc_cpumask(); + return cpu->mask; } @@ -120,13 +152,14 @@ u32 cpu_mask() * Return the number of cores on this SOC. */ int cpu_numcores() { - ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR; struct cpu_type *cpu = gd->cpu; - /* better to query feature reporting register than just assume 1 */ - if (cpu == &cpu_type_unknown) - return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> - MPC8xxx_PICFRR_NCPU_SHIFT) + 1; + /* + * Report # of cores in terms of the cpu_mask if we haven't + * figured out how many there are yet + */ + if (cpu->num_cores == 0) + return hweight32(cpu_mask()); return cpu->num_cores; } @@ -138,9 +171,7 @@ int cpu_numcores() { */ int is_core_valid(unsigned int core) { - struct cpu_type *cpu = gd->cpu; - - return !!((1 << core) & cpu->mask); + return !!((1 << core) & cpu_mask()); } int probecpu (void) @@ -156,6 +187,19 @@ int probecpu (void) return 0; } +/* Once in memory, compute mask & # cores once and save them off */ +int fixup_cpu(void) +{ + struct cpu_type *cpu = gd->cpu; + + if (cpu->num_cores == 0) { + cpu->mask = cpu_mask(); + cpu->num_cores = cpu_numcores(); + } + + return 0; +} + /* * Initializes on-chip ethernet controllers. * to override, implement board_eth_init() diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c index 2067d53..2592873 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * 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 @@ -151,8 +151,19 @@ static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr, if (dimm_params[dimm_number].n_ranks > 0) { go_config = 1; /* These fields only available in CS0_CONFIG */ - intlv_en = popts->memctl_interleaving; - intlv_ctl = popts->memctl_interleaving_mode; + if (!popts->memctl_interleaving) + break; + switch (popts->memctl_interleaving_mode) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + intlv_en = popts->memctl_interleaving; + intlv_ctl = popts->memctl_interleaving_mode; + break; + default: + break; + } } break; case 1: @@ -302,29 +313,41 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */ static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr, + const memctl_options_t *popts, const common_timing_params_t *common_dimm, unsigned int cas_latency) { + /* Extended precharge to activate interval (tRP) */ + unsigned int ext_pretoact = 0; /* Extended Activate to precharge interval (tRAS) */ unsigned int ext_acttopre = 0; - unsigned int ext_refrec; /* Extended refresh recovery time (tRFC) */ - unsigned int ext_caslat = 0; /* Extended MCAS latency from READ cmd */ - unsigned int cntl_adj = 0; /* Control Adjust */ - - /* If the tRAS > 19 MCLK, we use the ext mode */ - if (picos_to_mclk(common_dimm->tRAS_ps) > 0x13) - ext_acttopre = 1; - + /* Extended activate to read/write interval (tRCD) */ + unsigned int ext_acttorw = 0; + /* Extended refresh recovery time (tRFC) */ + unsigned int ext_refrec; + /* Extended MCAS latency from READ cmd */ + unsigned int ext_caslat = 0; + /* Extended last data to precharge interval (tWR) */ + unsigned int ext_wrrec = 0; + /* Control Adjust */ + unsigned int cntl_adj = 0; + + ext_pretoact = picos_to_mclk(common_dimm->tRP_ps) >> 4; + ext_acttopre = picos_to_mclk(common_dimm->tRAS_ps) >> 4; + ext_acttorw = picos_to_mclk(common_dimm->tRCD_ps) >> 4; + ext_caslat = (2 * cas_latency - 1) >> 4; ext_refrec = (picos_to_mclk(common_dimm->tRFC_ps) - 8) >> 4; - - /* If the CAS latency more than 8, use the ext mode */ - if (cas_latency > 8) - ext_caslat = 1; + /* ext_wrrec only deals with 16 clock and above, or 14 with OTF */ + ext_wrrec = (picos_to_mclk(common_dimm->tWR_ps) + + (popts->OTF_burst_chop_en ? 2 : 0)) >> 4; ddr->timing_cfg_3 = (0 - | ((ext_acttopre & 0x1) << 24) - | ((ext_refrec & 0xF) << 16) - | ((ext_caslat & 0x1) << 12) + | ((ext_pretoact & 0x1) << 28) + | ((ext_acttopre & 0x2) << 24) + | ((ext_acttorw & 0x1) << 22) + | ((ext_refrec & 0x1F) << 16) + | ((ext_caslat & 0x3) << 12) + | ((ext_wrrec & 0x1) << 8) | ((cntl_adj & 0x7) << 0) ); debug("FSLDDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3); @@ -386,15 +409,16 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, * we need set extend bit for it at * TIMING_CFG_3[EXT_CASLAT] */ - if (cas_latency > 8) - cas_latency -= 8; caslat_ctrl = 2 * cas_latency - 1; #endif refrec_ctrl = picos_to_mclk(common_dimm->tRFC_ps) - 8; wrrec_mclk = picos_to_mclk(common_dimm->tWR_ps); - wrrec_mclk = wrrec_table[wrrec_mclk - 1]; + if (wrrec_mclk > 16) + printf("Error: WRREC doesn't support more than 16 clocks\n"); + else + wrrec_mclk = wrrec_table[wrrec_mclk - 1]; if (popts->OTF_burst_chop_en) wrrec_mclk += 2; @@ -825,7 +849,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, /* Mode Register - MR0 */ unsigned int dll_on; /* DLL control for precharge PD, 0=off, 1=on */ - unsigned int wr; /* Write Recovery */ + unsigned int wr = 0; /* Write Recovery */ unsigned int dll_rst; /* DLL Reset */ unsigned int mode; /* Normal=0 or Test=1 */ unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */ @@ -885,24 +909,37 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, dll_on = 1; wr_mclk = (common_dimm->tWR_ps + mclk_ps - 1) / mclk_ps; - wr = wr_table[wr_mclk - 5]; + if (wr_mclk <= 16) { + wr = wr_table[wr_mclk - 5]; + } else { + printf("Error: unsupported write recovery for mode register " + "wr_mclk = %d\n", wr_mclk); + } dll_rst = 0; /* dll no reset */ mode = 0; /* normal mode */ /* look up table to get the cas latency bits */ - if (cas_latency >= 5 && cas_latency <= 11) { - unsigned char cas_latency_table[7] = { + if (cas_latency >= 5 && cas_latency <= 16) { + unsigned char cas_latency_table[] = { 0x2, /* 5 clocks */ 0x4, /* 6 clocks */ 0x6, /* 7 clocks */ 0x8, /* 8 clocks */ 0xa, /* 9 clocks */ 0xc, /* 10 clocks */ - 0xe /* 11 clocks */ + 0xe, /* 11 clocks */ + 0x1, /* 12 clocks */ + 0x3, /* 13 clocks */ + 0x5, /* 14 clocks */ + 0x7, /* 15 clocks */ + 0x9, /* 16 clocks */ }; caslat = cas_latency_table[cas_latency - 5]; + } else { + printf("Error: unsupported cas latency for mode register\n"); } + bt = 0; /* Nibble sequential */ switch (popts->burst_length) { @@ -930,6 +967,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, | ((mode & 0x1) << 7) | (((caslat >> 1) & 0x7) << 4) | ((bt & 0x1) << 3) + | ((caslat & 1) << 2) | ((bl & 0x3) << 0) ); @@ -1399,73 +1437,37 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, /* Chip Select Memory Bounds (CSn_BNDS) */ for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { - unsigned long long ea = 0, sa = 0; + unsigned long long ea, sa; unsigned int cs_per_dimm = CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR; unsigned int dimm_number = i / cs_per_dimm; unsigned long long rank_density - = dimm_params[dimm_number].rank_density; + = dimm_params[dimm_number].rank_density >> dbw_cap_adj; - if (((i == 1) && (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1)) || - ((i == 2) && (popts->ba_intlv_ctl & 0x04)) || - ((i == 3) && (popts->ba_intlv_ctl & FSL_DDR_CS2_CS3))) { - /* - * Don't set up boundaries for unused CS - * cs1 for cs0_cs1, cs0_cs1_and_cs2_cs3, cs0_cs1_cs2_cs3 - * cs2 for cs0_cs1_cs2_cs3 - * cs3 for cs2_cs3, cs0_cs1_and_cs2_cs3, cs0_cs1_cs2_cs3 - * But we need to set the ODT_RD_CFG and - * ODT_WR_CFG for CS1_CONFIG here. - */ - set_csn_config(dimm_number, i, ddr, popts, dimm_params); - continue; - } if (dimm_params[dimm_number].n_ranks == 0) { debug("Skipping setup of CS%u " "because n_ranks on DIMM %u is 0\n", i, dimm_number); continue; } - if (popts->memctl_interleaving && popts->ba_intlv_ctl) { - /* - * This works superbank 2CS - * There are 2 or more memory controllers configured - * identically, memory is interleaved between them, - * and each controller uses rank interleaving within - * itself. Therefore the starting and ending address - * on each controller is twice the amount present on - * each controller. If any CS is not included in the - * interleaving, the memory on that CS is not accssible - * and the total memory size is reduced. The CS is also - * disabled. - */ - unsigned long long ctlr_density = 0; + if (popts->memctl_interleaving) { switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { + case FSL_DDR_CS0_CS1_CS2_CS3: + break; case FSL_DDR_CS0_CS1: case FSL_DDR_CS0_CS1_AND_CS2_CS3: - ctlr_density = dimm_params[0].rank_density * 2; if (i > 1) cs_en = 0; break; case FSL_DDR_CS2_CS3: - ctlr_density = dimm_params[0].rank_density; + default: if (i > 0) cs_en = 0; break; - case FSL_DDR_CS0_CS1_CS2_CS3: - /* - * The four CS interleaving should have been verified by - * populate_memctl_options() - */ - ctlr_density = dimm_params[0].rank_density * 4; - break; - default: - break; } - ea = (CONFIG_NUM_DDR_CONTROLLERS * - (ctlr_density >> dbw_cap_adj)) - 1; - } - else if (!popts->memctl_interleaving && popts->ba_intlv_ctl) { + sa = common_dimm->base_address; + ea = common_dimm->total_mem - 1; + } else if (!popts->memctl_interleaving) { /* * If memory interleaving between controllers is NOT * enabled, the starting address for each memory @@ -1477,49 +1479,40 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, */ switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { case FSL_DDR_CS0_CS1_CS2_CS3: - /* CS0+CS1+CS2+CS3 interleaving, only CS0_CNDS - * needs to be set. - */ sa = common_dimm->base_address; - ea = sa + (4 * (rank_density >> dbw_cap_adj))-1; + ea = common_dimm->total_mem - 1; break; case FSL_DDR_CS0_CS1_AND_CS2_CS3: - /* CS0+CS1 and CS2+CS3 interleaving, CS0_CNDS - * and CS2_CNDS need to be set. - */ - if ((i == 2) && (dimm_number == 0)) { + if ((i >= 2) && (dimm_number == 0)) { sa = dimm_params[dimm_number].base_address + - 2 * (rank_density >> dbw_cap_adj); - ea = sa + 2 * (rank_density >> dbw_cap_adj) - 1; + 2 * rank_density; + ea = sa + 2 * rank_density - 1; } else { sa = dimm_params[dimm_number].base_address; - ea = sa + (2 * (rank_density >> - dbw_cap_adj)) - 1; + ea = sa + 2 * rank_density - 1; } break; case FSL_DDR_CS0_CS1: - /* CS0+CS1 interleaving, CS0_CNDS needs - * to be set - */ if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { sa = dimm_params[dimm_number].base_address; - ea = sa + (rank_density >> dbw_cap_adj) - 1; - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); + ea = sa + rank_density - 1; + if (i != 1) + sa += (i % cs_per_dimm) * rank_density; + ea += (i % cs_per_dimm) * rank_density; } else { sa = 0; ea = 0; } if (i == 0) - ea += (rank_density >> dbw_cap_adj); + ea += rank_density; break; case FSL_DDR_CS2_CS3: - /* CS2+CS3 interleaving*/ if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { sa = dimm_params[dimm_number].base_address; - ea = sa + (rank_density >> dbw_cap_adj) - 1; - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); + ea = sa + rank_density - 1; + if (i != 3) + sa += (i % cs_per_dimm) * rank_density; + ea += (i % cs_per_dimm) * rank_density; } else { sa = 0; ea = 0; @@ -1528,38 +1521,18 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, ea += (rank_density >> dbw_cap_adj); break; default: /* No bank(chip-select) interleaving */ + sa = dimm_params[dimm_number].base_address; + ea = sa + rank_density - 1; + if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { + sa += (i % cs_per_dimm) * rank_density; + ea += (i % cs_per_dimm) * rank_density; + } else { + sa = 0; + ea = 0; + } break; } } - else if (popts->memctl_interleaving && !popts->ba_intlv_ctl) { - /* - * Only the rank on CS0 of each memory controller may - * be used if memory controller interleaving is used - * without rank interleaving within each memory - * controller. However, the ending address programmed - * into each CS0 must be the sum of the amount of - * memory in the two CS0 ranks. - */ - if (i == 0) { - ea = (2 * (rank_density >> dbw_cap_adj)) - 1; - } - - } - else if (!popts->memctl_interleaving && !popts->ba_intlv_ctl) { - /* - * No rank interleaving and no memory controller - * interleaving. - */ - sa = dimm_params[dimm_number].base_address; - ea = sa + (rank_density >> dbw_cap_adj) - 1; - if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - } else { - sa = 0; - ea = 0; - } - } sa >>= 24; ea >>= 24; @@ -1574,7 +1547,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, set_csn_config(dimm_number, i, ddr, popts, dimm_params); set_csn_config_2(i, ddr); } else - printf("CS%d is disabled.\n", i); + debug("CS%d is disabled.\n", i); } /* @@ -1590,7 +1563,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, set_timing_cfg_0(ddr, popts); #endif - set_timing_cfg_3(ddr, common_dimm, cas_latency); + set_timing_cfg_3(ddr, popts, common_dimm, cas_latency); set_timing_cfg_1(ddr, popts, common_dimm, cas_latency); set_timing_cfg_2(ddr, popts, common_dimm, cas_latency, additive_latency); diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c index d0a5466..3e7c269 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * Dave Liu <daveliu@freescale.com> * * calculate the organization and timing parameter @@ -90,6 +90,7 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, { unsigned int retval; unsigned int mtb_ps; + int ftb_10th_ps; int i; if (spd->mem_type) { @@ -197,6 +198,14 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, pdimm->mtb_ps = mtb_ps; /* + * FTB - fine timebase + * use 1/10th of ps as our unit to avoid floating point + * eg, 10 for 1ps, 25 for 2.5ps, 50 for 5ps + */ + ftb_10th_ps = + ((spd->ftb_div & 0xf0) >> 4) * 10 / (spd->ftb_div & 0x0f); + pdimm->ftb_10th_ps = ftb_10th_ps; + /* * sdram minimum cycle time * we assume the MTB is 0.125ns * eg: @@ -204,7 +213,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * =12 MTB (1.5ns) ->DDR3-1333 * =10 MTB (1.25ns) ->DDR3-1600 */ - pdimm->tCKmin_X_ps = spd->tCK_min * mtb_ps; + pdimm->tCKmin_X_ps = spd->tCK_min * mtb_ps + + (spd->fine_tCK_min * ftb_10th_ps) / 10; /* * CAS latency supported @@ -222,7 +232,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1333H 108 MTB (13.5ns) * DDR3-1600H 90 MTB (11.25ns) */ - pdimm->tAA_ps = spd->tAA_min * mtb_ps; + pdimm->tAA_ps = spd->tAA_min * mtb_ps + + (spd->fine_tAA_min * ftb_10th_ps) / 10; /* * min write recovery time @@ -239,7 +250,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1333H 108 MTB (13.5ns) * DDR3-1600H 90 MTB (11.25) */ - pdimm->tRCD_ps = spd->tRCD_min * mtb_ps; + pdimm->tRCD_ps = spd->tRCD_min * mtb_ps + + (spd->fine_tRCD_min * ftb_10th_ps) / 10; /* * min row active to row active delay time @@ -257,7 +269,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1333H 108 MTB (13.5ns) * DDR3-1600H 90 MTB (11.25ns) */ - pdimm->tRP_ps = spd->tRP_min * mtb_ps; + pdimm->tRP_ps = spd->tRP_min * mtb_ps + + (spd->fine_tRP_min * ftb_10th_ps) / 10; /* min active to precharge delay time * eg: tRAS_min = @@ -277,7 +290,7 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1600H 370 MTB (46.25ns) */ pdimm->tRC_ps = (((spd->tRAS_tRC_ext & 0xf0) << 4) | spd->tRC_min_lsb) - * mtb_ps; + * mtb_ps + (spd->fine_tRC_min * ftb_10th_ps) / 10; /* * min refresh recovery delay time * eg: tRFC_min = diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c index 5b72437..f59d105 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Freescale Semiconductor, Inc. + * Copyright 2010-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -1047,7 +1047,7 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd) /* General Section: Bytes 0-59 */ -#define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, y); +#define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, (u8)y); #define PRINT_NNXXS(n0, n1, x0, x1, s) \ printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1); @@ -1121,11 +1121,21 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd) "therm_sensor SDRAM Thermal Sensor"); PRINT_NXS(33, spd->device_type, "device_type SDRAM Device Type"); - - printf("%-3d-%3d: ", 34, 59); /* Reserved, General Section */ - - for (i = 34; i <= 59; i++) - printf("%02x ", spd->res_34_59[i - 34]); + PRINT_NXS(34, spd->fine_tCK_min, + "fine_tCK_min Fine offset for tCKmin"); + PRINT_NXS(35, spd->fine_tAA_min, + "fine_tAA_min Fine offset for tAAmin"); + PRINT_NXS(36, spd->fine_tRCD_min, + "fine_tRCD_min Fine offset for tRCDmin"); + PRINT_NXS(37, spd->fine_tRP_min, + "fine_tRP_min Fine offset for tRPmin"); + PRINT_NXS(38, spd->fine_tRC_min, + "fine_tRC_min Fine offset for tRCmin"); + + printf("%-3d-%3d: ", 39, 59); /* Reserved, General Section */ + + for (i = 39; i <= 59; i++) + printf("%02x ", spd->res_39_59[i - 39]); puts("\n"); @@ -1388,7 +1398,7 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) * No need to worry for buffer overflow here in * this function; readline() maxes out at CFG_CBSIZE */ - readline_into_buffer(prompt, buffer); + readline_into_buffer(prompt, buffer, 0); argc = parse_line(buffer, argv); if (argc == 0) continue; diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c index 20c7db0..03a784c 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -27,8 +27,10 @@ compute_cas_latency_ddr3(const dimm_params_t *dimm_params, /* compute the common CAS latency supported between slots */ tmp = dimm_params[0].caslat_X; - for (i = 1; i < number_of_dimms; i++) - tmp &= dimm_params[i].caslat_X; + for (i = 1; i < number_of_dimms; i++) { + if (dimm_params[i].n_ranks) + tmp &= dimm_params[i].caslat_X; + } common_caslat = tmp; /* compute the max tAAmin tCKmin between slots */ @@ -491,5 +493,15 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, */ outpdimm->additive_latency = additive_latency; + debug("tCKmin_ps = %u\n", outpdimm->tCKmin_X_ps); + debug("tRCD_ps = %u\n", outpdimm->tRCD_ps); + debug("tRP_ps = %u\n", outpdimm->tRP_ps); + debug("tRAS_ps = %u\n", outpdimm->tRAS_ps); + debug("tWR_ps = %u\n", outpdimm->tWR_ps); + debug("tWTR_ps = %u\n", outpdimm->tWTR_ps); + debug("tRFC_ps = %u\n", outpdimm->tRFC_ps); + debug("tRRD_ps = %u\n", outpdimm->tRRD_ps); + debug("tRC_ps = %u\n", outpdimm->tRC_ps); + return 0; } diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c index c2a03e3..b47268c 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/main.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -15,13 +15,15 @@ #include <common.h> #include <i2c.h> #include <asm/fsl_ddr_sdram.h> +#include <asm/fsl_law.h> #include "ddr.h" -extern void fsl_ddr_set_lawbar( +void fsl_ddr_set_lawbar( const common_timing_params_t *memctl_common_params, unsigned int memctl_interleaved, unsigned int ctrl_num); +void fsl_ddr_set_intl3r(const unsigned int granule_size); /* processor specific function */ extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, @@ -51,6 +53,22 @@ u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ }; +#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) +u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { + [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ + [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */ + [2][0] = SPD_EEPROM_ADDRESS3, /* controller 3 */ +}; +#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { + [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ + [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ + [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ + [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ + [2][0] = SPD_EEPROM_ADDRESS5, /* controller 3 */ + [2][1] = SPD_EEPROM_ADDRESS6, /* controller 3 */ +}; + #endif static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address) @@ -156,12 +174,12 @@ const char * step_to_string(unsigned int step) { return step_string_tbl[s]; } -int step_assign_addresses(fsl_ddr_info_t *pinfo, - unsigned int dbw_cap_adj[], - unsigned int *all_memctl_interleaving, - unsigned int *all_ctlr_rank_interleaving) +unsigned long long step_assign_addresses(fsl_ddr_info_t *pinfo, + unsigned int dbw_cap_adj[]) { int i, j; + unsigned long long total_mem, current_mem_base, total_ctlr_mem; + unsigned long long rank_density, ctlr_density = 0; /* * If a reduced data width is requested, but the SPD @@ -220,86 +238,108 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo, "specified controller %u\n", i); return 1; } + debug("dbw_cap_adj[%d]=%d\n", i, dbw_cap_adj[i]); } - j = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - if (pinfo->memctl_opts[i].memctl_interleaving) - j++; - /* - * Not support less than all memory controllers interleaving - * if more than two controllers - */ - if (j == CONFIG_NUM_DDR_CONTROLLERS) - *all_memctl_interleaving = 1; - - /* Check that all controllers are rank interleaving. */ - j = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - if (pinfo->memctl_opts[i].ba_intlv_ctl) - j++; - /* - * All memory controllers must be populated to qualify for - * all controller rank interleaving - */ - if (j == CONFIG_NUM_DDR_CONTROLLERS) - *all_ctlr_rank_interleaving = 1; - - if (*all_memctl_interleaving) { - unsigned long long addr, total_mem_per_ctlr = 0; - /* - * If interleaving between memory controllers, - * make each controller start at a base address - * of 0. - * - * Also, if bank interleaving (chip select - * interleaving) is enabled on each memory - * controller, CS0 needs to be programmed to - * cover the entire memory range on that memory - * controller - * - * Bank interleaving also implies that each - * addressed chip select is identical in size. - */ - + current_mem_base = 0ull; + total_mem = 0; + if (pinfo->memctl_opts[0].memctl_interleaving) { + rank_density = pinfo->dimm_params[0][0].rank_density >> + dbw_cap_adj[0]; + switch (pinfo->memctl_opts[0].ba_intlv_ctl & + FSL_DDR_CS0_CS1_CS2_CS3) { + case FSL_DDR_CS0_CS1_CS2_CS3: + ctlr_density = 4 * rank_density; + break; + case FSL_DDR_CS0_CS1: + case FSL_DDR_CS0_CS1_AND_CS2_CS3: + ctlr_density = 2 * rank_density; + break; + case FSL_DDR_CS2_CS3: + default: + ctlr_density = rank_density; + break; + } + debug("rank density is 0x%llx, ctlr density is 0x%llx\n", + rank_density, ctlr_density); for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - addr = 0; - pinfo->common_timing_params[i].base_address = 0ull; - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - unsigned long long cap - = pinfo->dimm_params[i][j].capacity; - - pinfo->dimm_params[i][j].base_address = addr; - addr += cap >> dbw_cap_adj[i]; - total_mem_per_ctlr += cap >> dbw_cap_adj[i]; + if (pinfo->memctl_opts[i].memctl_interleaving) { + switch (pinfo->memctl_opts[i].memctl_interleaving_mode) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + total_ctlr_mem = 2 * ctlr_density; + break; + case FSL_DDR_3WAY_1KB_INTERLEAVING: + case FSL_DDR_3WAY_4KB_INTERLEAVING: + case FSL_DDR_3WAY_8KB_INTERLEAVING: + total_ctlr_mem = 3 * ctlr_density; + break; + case FSL_DDR_4WAY_1KB_INTERLEAVING: + case FSL_DDR_4WAY_4KB_INTERLEAVING: + case FSL_DDR_4WAY_8KB_INTERLEAVING: + total_ctlr_mem = 4 * ctlr_density; + break; + default: + panic("Unknown interleaving mode"); + } + pinfo->common_timing_params[i].base_address = + current_mem_base; + pinfo->common_timing_params[i].total_mem = + total_ctlr_mem; + total_mem = current_mem_base + total_ctlr_mem; + debug("ctrl %d base 0x%llx\n", i, current_mem_base); + debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); + } else { + /* when 3rd controller not interleaved */ + current_mem_base = total_mem; + total_ctlr_mem = 0; + pinfo->common_timing_params[i].base_address = + current_mem_base; + for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { + unsigned long long cap = + pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i]; + pinfo->dimm_params[i][j].base_address = + current_mem_base; + debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base); + current_mem_base += cap; + total_ctlr_mem += cap; + } + debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); + pinfo->common_timing_params[i].total_mem = + total_ctlr_mem; + total_mem += total_ctlr_mem; } } - pinfo->common_timing_params[0].total_mem = total_mem_per_ctlr; } else { /* * Simple linear assignment if memory * controllers are not interleaved. */ - unsigned long long cur_memsize = 0; for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - u64 total_mem_per_ctlr = 0; + total_ctlr_mem = 0; pinfo->common_timing_params[i].base_address = - cur_memsize; + current_mem_base; for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { /* Compute DIMM base addresses. */ unsigned long long cap = - pinfo->dimm_params[i][j].capacity; + pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i]; pinfo->dimm_params[i][j].base_address = - cur_memsize; - cur_memsize += cap >> dbw_cap_adj[i]; - total_mem_per_ctlr += cap >> dbw_cap_adj[i]; + current_mem_base; + debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base); + current_mem_base += cap; + total_ctlr_mem += cap; } + debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); pinfo->common_timing_params[i].total_mem = - total_mem_per_ctlr; + total_ctlr_mem; + total_mem += total_ctlr_mem; } } + debug("Total mem by %s is 0x%llx\n", __func__, total_mem); - return 0; + return total_mem; } unsigned long long @@ -307,8 +347,6 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, unsigned int size_only) { unsigned int i, j; - unsigned int all_controllers_memctl_interleaving = 0; - unsigned int all_controllers_rank_interleaving = 0; unsigned long long total_mem = 0; fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg; @@ -345,9 +383,10 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, retval = compute_dimm_parameters(spd, pdimm, i); #ifdef CONFIG_SYS_DDR_RAW_TIMING - if (retval != 0) { - printf("SPD error! Trying fallback to " - "raw timing calculation\n"); + if (!i && !j && retval) { + printf("SPD error on controller %d! " + "Trying fallback to raw timing " + "calculation\n", i); fsl_ddr_get_dimm_params(pdimm, i, j); } #else @@ -407,17 +446,14 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, &pinfo->memctl_opts[i], pinfo->dimm_params[i], i); } - check_interleaving_options(pinfo); case STEP_ASSIGN_ADDRESSES: /* STEP 5: Assign addresses to chip selects */ - step_assign_addresses(pinfo, - dbw_capacity_adjust, - &all_controllers_memctl_interleaving, - &all_controllers_rank_interleaving); + check_interleaving_options(pinfo); + total_mem = step_assign_addresses(pinfo, dbw_capacity_adjust); case STEP_COMPUTE_REGS: /* STEP 6: compute controller register values */ - debug("FSL Memory ctrl cg register computation\n"); + debug("FSL Memory ctrl register computation\n"); for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { if (timing_params[i].ndimms_present == 0) { memset(&ddr_reg[i], 0, @@ -437,21 +473,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, break; } - /* Compute the total amount of memory. */ - - /* - * If bank interleaving but NOT memory controller interleaving - * CS_BNDS describe the quantity of memory on each memory - * controller, so the total is the sum across. - */ - if (!all_controllers_memctl_interleaving - && all_controllers_rank_interleaving) { - total_mem = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - total_mem += timing_params[i].total_mem; - } - - } else { + { /* * Compute the amount of memory available just by * looking for the highest valid CSn_BNDS value. @@ -489,7 +511,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, phys_size_t fsl_ddr_sdram(void) { unsigned int i; - unsigned int memctl_interleaved; + unsigned int law_memctl = LAW_TRGT_IF_DDR_1; unsigned long long total_memory; fsl_ddr_info_t info; @@ -504,34 +526,6 @@ phys_size_t fsl_ddr_sdram(void) #endif total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 0); - /* Check for memory controller interleaving. */ - memctl_interleaved = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - memctl_interleaved += - info.memctl_opts[i].memctl_interleaving; - } - - if (memctl_interleaved) { - if (memctl_interleaved == CONFIG_NUM_DDR_CONTROLLERS) { - debug("memctl interleaving\n"); - /* - * Change the meaning of memctl_interleaved - * to be "boolean". - */ - memctl_interleaved = 1; - } else { - printf("Warning: memctl interleaving not " - "properly configured on all controllers\n"); - memctl_interleaved = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - info.memctl_opts[i].memctl_interleaving = 0; - debug("Recomputing with memctl_interleaving off.\n"); - total_memory = fsl_ddr_compute(&info, - STEP_ASSIGN_ADDRESSES, - 0); - } - } - /* Program configuration registers. */ for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { debug("Programming controller %u\n", i); @@ -544,24 +538,69 @@ phys_size_t fsl_ddr_sdram(void) fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i); } - if (memctl_interleaved) { - const unsigned int ctrl_num = 0; - - /* Only set LAWBAR1 if memory controller interleaving is on. */ - fsl_ddr_set_lawbar(&info.common_timing_params[0], - memctl_interleaved, ctrl_num); - } else { - /* - * Memory controller interleaving is NOT on; - * set each lawbar individually. - */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + /* program LAWs */ + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + if (info.memctl_opts[i].memctl_interleaving) { + switch (info.memctl_opts[i].memctl_interleaving_mode) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + if (i == 0) { + law_memctl = LAW_TRGT_IF_DDR_INTRLV; + fsl_ddr_set_lawbar(&info.common_timing_params[i], + law_memctl, i); + } else if (i == 2) { + law_memctl = LAW_TRGT_IF_DDR_INTLV_34; + fsl_ddr_set_lawbar(&info.common_timing_params[i], + law_memctl, i); + } + break; + case FSL_DDR_3WAY_1KB_INTERLEAVING: + case FSL_DDR_3WAY_4KB_INTERLEAVING: + case FSL_DDR_3WAY_8KB_INTERLEAVING: + law_memctl = LAW_TRGT_IF_DDR_INTLV_123; + if (i == 0) { + fsl_ddr_set_intl3r(info.memctl_opts[i].memctl_interleaving_mode); + fsl_ddr_set_lawbar(&info.common_timing_params[i], + law_memctl, i); + } + break; + case FSL_DDR_4WAY_1KB_INTERLEAVING: + case FSL_DDR_4WAY_4KB_INTERLEAVING: + case FSL_DDR_4WAY_8KB_INTERLEAVING: + law_memctl = LAW_TRGT_IF_DDR_INTLV_1234; + if (i == 0) + fsl_ddr_set_lawbar(&info.common_timing_params[i], + law_memctl, i); + /* place holder for future 4-way interleaving */ + break; + default: + break; + } + } else { + switch (i) { + case 0: + law_memctl = LAW_TRGT_IF_DDR_1; + break; + case 1: + law_memctl = LAW_TRGT_IF_DDR_2; + break; + case 2: + law_memctl = LAW_TRGT_IF_DDR_3; + break; + case 3: + law_memctl = LAW_TRGT_IF_DDR_4; + break; + default: + break; + } fsl_ddr_set_lawbar(&info.common_timing_params[i], - 0, i); + law_memctl, i); } } - debug("total_memory = %llu\n", total_memory); + debug("total_memory by %s = %llu\n", __func__, total_memory); #if !defined(CONFIG_PHYS_64BIT) /* Check for 4G or more. Bad. */ diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c index 00ec57b..13e4825 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c @@ -1,5 +1,5 @@ /* - * Copyright 2008, 2010-2011 Freescale Semiconductor, Inc. + * Copyright 2008, 2010-2012 Freescale Semiconductor, Inc. * * 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 @@ -19,7 +19,6 @@ * This is pretty fragile on both the use of stack and if the buffer is big * enough. However we will get a warning from getenv_f for the later. */ -#define HWCONFIG_BUFFER_SIZE 128 /* Board-specific functions defined in each board's ddr.c */ extern void fsl_ddr_board_options(memctl_options_t *popts, @@ -790,46 +789,97 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, * should be a subset of the requested configuration. */ #if (CONFIG_NUM_DDR_CONTROLLERS > 1) - if (hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf)) { - if (pdimm[0].n_ranks == 0) { - printf("There is no rank on CS0 for controller %d. Because only" - " rank on CS0 and ranks chip-select interleaved with CS0" - " are controller interleaved, force non memory " - "controller interleaving\n", ctrl_num); - popts->memctl_interleaving = 0; - } else { - popts->memctl_interleaving = 1; - /* - * test null first. if CONFIG_HWCONFIG is not defined - * hwconfig_arg_cmp returns non-zero - */ - if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "null", buf)) { - popts->memctl_interleaving = 0; - debug("memory controller interleaving disabled.\n"); - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "cacheline", buf)) - popts->memctl_interleaving_mode = - FSL_DDR_CACHE_LINE_INTERLEAVING; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "page", buf)) - popts->memctl_interleaving_mode = - FSL_DDR_PAGE_INTERLEAVING; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "bank", buf)) - popts->memctl_interleaving_mode = - FSL_DDR_BANK_INTERLEAVING; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "superbank", buf)) - popts->memctl_interleaving_mode = - FSL_DDR_SUPERBANK_INTERLEAVING; - else { - popts->memctl_interleaving = 0; - printf("hwconfig has unrecognized parameter for ctlr_intlv.\n"); - } - } + if (!hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf)) + goto done; + + if (pdimm[0].n_ranks == 0) { + printf("There is no rank on CS0 for controller %d.\n", ctrl_num); + popts->memctl_interleaving = 0; + goto done; + } + popts->memctl_interleaving = 1; + /* + * test null first. if CONFIG_HWCONFIG is not defined + * hwconfig_arg_cmp returns non-zero + */ + if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", + "null", buf)) { + popts->memctl_interleaving = 0; + debug("memory controller interleaving disabled.\n"); + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "cacheline", buf)) { + popts->memctl_interleaving_mode = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : FSL_DDR_CACHE_LINE_INTERLEAVING; + popts->memctl_interleaving = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : 1; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "page", buf)) { + popts->memctl_interleaving_mode = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : FSL_DDR_PAGE_INTERLEAVING; + popts->memctl_interleaving = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : 1; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "bank", buf)) { + popts->memctl_interleaving_mode = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : FSL_DDR_BANK_INTERLEAVING; + popts->memctl_interleaving = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : 1; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "superbank", buf)) { + popts->memctl_interleaving_mode = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : FSL_DDR_SUPERBANK_INTERLEAVING; + popts->memctl_interleaving = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : 1; +#if (CONFIG_NUM_DDR_CONTROLLERS == 3) + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "3way_1KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_3WAY_1KB_INTERLEAVING; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "3way_4KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_3WAY_4KB_INTERLEAVING; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "3way_8KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_3WAY_8KB_INTERLEAVING; +#elif (CONFIG_NUM_DDR_CONTROLLERS == 4) + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "4way_1KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_4WAY_1KB_INTERLEAVING; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "4way_4KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_4WAY_4KB_INTERLEAVING; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "4way_8KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_4WAY_8KB_INTERLEAVING; +#endif + } else { + popts->memctl_interleaving = 0; + printf("hwconfig has unrecognized parameter for ctlr_intlv.\n"); } +done: #endif if ((hwconfig_sub_f("fsl_ddr", "bank_intlv", buf)) && (CONFIG_CHIP_SELECTS_PER_CTRL > 1)) { @@ -859,20 +909,20 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for " "CS0+CS1+CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) { popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for " "CS0+CS1+CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } if (pdimm[0].capacity != pdimm[1].capacity) { popts->ba_intlv_ctl = 0; printf("Not identical DIMM size for " "CS0+CS1+CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } #endif break; @@ -881,7 +931,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for " "CS0+CS1 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } break; case FSL_DDR_CS2_CS3: @@ -889,13 +939,13 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, if (pdimm[0].n_ranks < 4) { popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for CS2+CS3 " - "on controller %d, force non-interleaving!\n", ctrl_num); + "on controller %d, interleaving disabled!\n", ctrl_num); } #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) if (pdimm[1].n_ranks < 2) { popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for CS2+CS3 " - "on controller %d, force non-interleaving!\n", ctrl_num); + "on controller %d, interleaving disabled!\n", ctrl_num); } #endif break; @@ -905,14 +955,14 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, popts->ba_intlv_ctl = 0; printf("Not enough bank(CS) for CS0+CS1 and " "CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) { popts->ba_intlv_ctl = 0; printf("Not enough bank(CS) for CS0+CS1 and " "CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } #endif break; @@ -954,33 +1004,73 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, void check_interleaving_options(fsl_ddr_info_t *pinfo) { - int i, j, check_n_ranks, intlv_fixed = 0; + int i, j, k, check_n_ranks, intlv_invalid = 0; + unsigned int check_intlv, check_n_row_addr, check_n_col_addr; unsigned long long check_rank_density; + struct dimm_params_s *dimm; /* * Check if all controllers are configured for memory * controller interleaving. Identical dimms are recommended. At least - * the size should be checked. + * the size, row and col address should be checked. */ j = 0; check_n_ranks = pinfo->dimm_params[0][0].n_ranks; check_rank_density = pinfo->dimm_params[0][0].rank_density; + check_n_row_addr = pinfo->dimm_params[0][0].n_row_addr; + check_n_col_addr = pinfo->dimm_params[0][0].n_col_addr; + check_intlv = pinfo->memctl_opts[0].memctl_interleaving_mode; for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if ((pinfo->memctl_opts[i].memctl_interleaving) && \ - (check_rank_density == pinfo->dimm_params[i][0].rank_density) && \ - (check_n_ranks == pinfo->dimm_params[i][0].n_ranks)) { + dimm = &pinfo->dimm_params[i][0]; + if (!pinfo->memctl_opts[i].memctl_interleaving) { + continue; + } else if (((check_rank_density != dimm->rank_density) || + (check_n_ranks != dimm->n_ranks) || + (check_n_row_addr != dimm->n_row_addr) || + (check_n_col_addr != dimm->n_col_addr) || + (check_intlv != + pinfo->memctl_opts[i].memctl_interleaving_mode))){ + intlv_invalid = 1; + break; + } else { j++; } + } - if (j != CONFIG_NUM_DDR_CONTROLLERS) { + if (intlv_invalid) { for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - if (pinfo->memctl_opts[i].memctl_interleaving) { + pinfo->memctl_opts[i].memctl_interleaving = 0; + printf("Not all DIMMs are identical. " + "Memory controller interleaving disabled.\n"); + } else { + switch (check_intlv) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + if (3 == CONFIG_NUM_DDR_CONTROLLERS) + k = 2; + else + k = CONFIG_NUM_DDR_CONTROLLERS; + break; + case FSL_DDR_3WAY_1KB_INTERLEAVING: + case FSL_DDR_3WAY_4KB_INTERLEAVING: + case FSL_DDR_3WAY_8KB_INTERLEAVING: + case FSL_DDR_4WAY_1KB_INTERLEAVING: + case FSL_DDR_4WAY_4KB_INTERLEAVING: + case FSL_DDR_4WAY_8KB_INTERLEAVING: + default: + k = CONFIG_NUM_DDR_CONTROLLERS; + break; + } + debug("%d of %d controllers are interleaving.\n", j, k); + if (j != k) { + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) pinfo->memctl_opts[i].memctl_interleaving = 0; - intlv_fixed = 1; - } - if (intlv_fixed) - printf("Not all DIMMs are identical in size. " - "Memory controller interleaving disabled.\n"); + printf("Not all controllers have compatible " + "interleaving mode. All disabled.\n"); + } } + debug("Checking interleaving options completed\n"); } int fsl_use_spd(void) diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/util.c b/arch/powerpc/cpu/mpc8xxx/ddr/util.c index eb6a17a..664ad09 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/util.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/util.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -79,7 +79,7 @@ unsigned int mclk_to_picos(unsigned int mclk) void __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, - unsigned int memctl_interleaved, + unsigned int law_memctl, unsigned int ctrl_num) { unsigned long long base = memctl_common_params->base_address; @@ -98,28 +98,13 @@ __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, if ((base + size) >= CONFIG_MAX_MEM_MAPPED) size = CONFIG_MAX_MEM_MAPPED - base; #endif - - if (ctrl_num == 0) { - /* - * Set up LAW for DDR controller 1 space. - */ - unsigned int lawbar1_target_id = memctl_interleaved - ? LAW_TRGT_IF_DDR_INTRLV : LAW_TRGT_IF_DDR_1; - - if (set_ddr_laws(base, size, lawbar1_target_id) < 0) { - printf("%s: ERROR (ctrl #0, intrlv=%d)\n", __func__, - memctl_interleaved); - return ; - } - } else if (ctrl_num == 1) { - if (set_ddr_laws(base, size, LAW_TRGT_IF_DDR_2) < 0) { - printf("%s: ERROR (ctrl #1)\n", __func__); - return ; - } - } else { - printf("%s: unexpected DDR controller number (%u)\n", __func__, - ctrl_num); + if (set_ddr_laws(base, size, law_memctl) < 0) { + printf("%s: ERROR (ctrl #%d, TRGT ID=%x)\n", __func__, ctrl_num, + law_memctl); + return ; } + debug("setup ddr law base = 0x%llx, size 0x%llx, TRGT_ID 0x%x\n", + base, size, law_memctl); } __attribute__((weak, alias("__fsl_ddr_set_lawbar"))) void @@ -127,6 +112,15 @@ fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, unsigned int memctl_interleaved, unsigned int ctrl_num); +void fsl_ddr_set_intl3r(const unsigned int granule_size) +{ +#ifdef CONFIG_E6500 + u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); + *mcintl3r = 0x80000000 | (granule_size & 0x1f); + debug("Enable MCINTL3R with granule size 0x%x\n", granule_size); +#endif +} + void board_add_ram_info(int use_default) { #if defined(CONFIG_MPC83xx) @@ -137,6 +131,9 @@ void board_add_ram_info(int use_default) #elif defined(CONFIG_MPC86xx) ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR); #endif +#if defined(CONFIG_E6500) && (CONFIG_NUM_DDR_CONTROLLERS == 3) + u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); +#endif #if (CONFIG_NUM_DDR_CONTROLLERS > 1) uint32_t cs0_config = in_be32(&ddr->cs0_config); #endif @@ -180,7 +177,29 @@ void board_add_ram_info(int use_default) else puts(", ECC off)"); -#if (CONFIG_NUM_DDR_CONTROLLERS > 1) +#if (CONFIG_NUM_DDR_CONTROLLERS == 3) +#ifdef CONFIG_E6500 + if (*mcintl3r & 0x80000000) { + puts("\n"); + puts(" DDR Controller Interleaving Mode: "); + switch (*mcintl3r & 0x1f) { + case FSL_DDR_3WAY_1KB_INTERLEAVING: + puts("3-way 1KB"); + break; + case FSL_DDR_3WAY_4KB_INTERLEAVING: + puts("3-way 4KB"); + break; + case FSL_DDR_3WAY_8KB_INTERLEAVING: + puts("3-way 8KB"); + break; + default: + puts("3-way UNKNOWN"); + break; + } + } +#endif +#endif +#if (CONFIG_NUM_DDR_CONTROLLERS >= 2) if (cs0_config & 0x20000000) { puts("\n"); puts(" DDR Controller Interleaving Mode: "); diff --git a/arch/powerpc/cpu/mpc8xxx/fdt.c b/arch/powerpc/cpu/mpc8xxx/fdt.c index 09810be..32ab050 100644 --- a/arch/powerpc/cpu/mpc8xxx/fdt.c +++ b/arch/powerpc/cpu/mpc8xxx/fdt.c @@ -62,8 +62,9 @@ void ft_fixup_num_cores(void *blob) { off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); while (off != -FDT_ERR_NOTFOUND) { u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0); + u32 phys_cpu_id = thread_to_core(*reg); - if (!is_core_valid(*reg) || is_core_disabled(*reg)) { + if (!is_core_valid(phys_cpu_id) || is_core_disabled(phys_cpu_id)) { int ph = fdt_get_phandle(blob, off); /* Delete the cpu node once there are no cpu handles */ diff --git a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c index 6682496..56b319f 100644 --- a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c +++ b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c @@ -44,12 +44,18 @@ void init_early_memctl_regs(void) set_ifc_ftim(IFC_CS0, IFC_FTIM3, CONFIG_SYS_CS0_FTIM3); #if !defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) || defined(CONFIG_SYS_RAMBOOT) +#ifdef CONFIG_SYS_CSPR0_EXT + set_ifc_cspr_ext(IFC_CS0, CONFIG_SYS_CSPR0_EXT); +#endif set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0); set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0); set_ifc_csor(IFC_CS0, CONFIG_SYS_CSOR0); #endif #endif +#ifdef CONFIG_SYS_CSPR1_EXT + set_ifc_cspr_ext(IFC_CS1, CONFIG_SYS_CSPR1_EXT); +#endif #if defined(CONFIG_SYS_CSPR1) && defined(CONFIG_SYS_CSOR1) set_ifc_ftim(IFC_CS1, IFC_FTIM0, CONFIG_SYS_CS1_FTIM0); set_ifc_ftim(IFC_CS1, IFC_FTIM1, CONFIG_SYS_CS1_FTIM1); @@ -61,6 +67,9 @@ void init_early_memctl_regs(void) set_ifc_cspr(IFC_CS1, CONFIG_SYS_CSPR1); #endif +#ifdef CONFIG_SYS_CSPR2_EXT + set_ifc_cspr_ext(IFC_CS2, CONFIG_SYS_CSPR2_EXT); +#endif #if defined(CONFIG_SYS_CSPR2) && defined(CONFIG_SYS_CSOR2) set_ifc_ftim(IFC_CS2, IFC_FTIM0, CONFIG_SYS_CS2_FTIM0); set_ifc_ftim(IFC_CS2, IFC_FTIM1, CONFIG_SYS_CS2_FTIM1); @@ -72,6 +81,9 @@ void init_early_memctl_regs(void) set_ifc_cspr(IFC_CS2, CONFIG_SYS_CSPR2); #endif +#ifdef CONFIG_SYS_CSPR3_EXT + set_ifc_cspr_ext(IFC_CS3, CONFIG_SYS_CSPR3_EXT); +#endif #if defined(CONFIG_SYS_CSPR3) && defined(CONFIG_SYS_CSOR3) set_ifc_ftim(IFC_CS3, IFC_FTIM0, CONFIG_SYS_CS3_FTIM0); set_ifc_ftim(IFC_CS3, IFC_FTIM1, CONFIG_SYS_CS3_FTIM1); diff --git a/arch/powerpc/cpu/mpc8xxx/srio.c b/arch/powerpc/cpu/mpc8xxx/srio.c index c7f3949..0cb65b3 100644 --- a/arch/powerpc/cpu/mpc8xxx/srio.c +++ b/arch/powerpc/cpu/mpc8xxx/srio.c @@ -95,126 +95,92 @@ void srio_init(void) } } -#ifdef CONFIG_SRIOBOOT_MASTER -void srio_boot_master(void) +#ifdef CONFIG_FSL_CORENET +void srio_boot_master(int port) { struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR; /* set port accept-all */ - out_be32((void *)&srio->impl.port[CONFIG_SRIOBOOT_MASTER_PORT].ptaacr, + out_be32((void *)&srio->impl.port[port - 1].ptaacr, SRIO_PORT_ACCEPT_ALL); - debug("SRIOBOOT - MASTER: Master port [ %d ] for srio boot.\n", - CONFIG_SRIOBOOT_MASTER_PORT); + debug("SRIOBOOT - MASTER: Master port [ %d ] for srio boot.\n", port); /* configure inbound window for slave's u-boot image */ debug("SRIOBOOT - MASTER: Inbound window for slave's image; " "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS1, - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS1, - CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[0].riwtar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS1 >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[0].riwbar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS1 >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[0].riwar, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); + out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwtar, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwbar, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwar, SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE)); + | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE)); /* configure inbound window for slave's u-boot image */ debug("SRIOBOOT - MASTER: Inbound window for slave's image; " "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS2, - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS2, - CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[1].riwtar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS2 >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[1].riwbar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS2 >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[1].riwar, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); + out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwtar, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwbar, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwar, SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE)); + | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE)); - /* configure inbound window for slave's ucode */ - debug("SRIOBOOT - MASTER: Inbound window for slave's ucode; " + /* configure inbound window for slave's ucode and ENV */ + debug("SRIOBOOT - MASTER: Inbound window for slave's ucode and ENV; " "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", - (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_LAW_PHYS, - (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_SRIO_PHYS, - CONFIG_SRIOBOOT_SLAVE_UCODE_SIZE); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[2].riwtar, - CONFIG_SRIOBOOT_SLAVE_UCODE_LAW_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[2].riwbar, - CONFIG_SRIOBOOT_SLAVE_UCODE_SRIO_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[2].riwar, - SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_UCODE_SIZE)); - - /* configure inbound window for slave's ENV */ - debug("SRIOBOOT - MASTER: Inbound window for slave's ENV; " - "Local = 0x%llx, Siro = 0x%llx, Size = 0x%x\n", - CONFIG_SRIOBOOT_SLAVE_ENV_LAW_PHYS, - CONFIG_SRIOBOOT_SLAVE_ENV_SRIO_PHYS, - CONFIG_SRIOBOOT_SLAVE_ENV_SIZE); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[3].riwtar, - CONFIG_SRIOBOOT_SLAVE_ENV_LAW_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[3].riwbar, - CONFIG_SRIOBOOT_SLAVE_ENV_SRIO_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[3].riwar, + (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE); + out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwtar, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwbar, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwar, SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_ENV_SIZE)); + | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE)); } -#ifdef CONFIG_SRIOBOOT_SLAVE_HOLDOFF -void srio_boot_master_release_slave(void) +void srio_boot_master_release_slave(int port) { struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR; u32 escsr; debug("SRIOBOOT - MASTER: " "Check the port status and release slave core ...\n"); - escsr = in_be32((void *)&srio->lp_serial - .port[CONFIG_SRIOBOOT_MASTER_PORT].pescsr); + escsr = in_be32((void *)&srio->lp_serial.port[port - 1].pescsr); if (escsr & 0x2) { if (escsr & 0x10100) { debug("SRIOBOOT - MASTER: Port [ %d ] is error.\n", - CONFIG_SRIOBOOT_MASTER_PORT); + port); } else { debug("SRIOBOOT - MASTER: " - "Port [ %d ] is ready, now release slave's core ...\n", - CONFIG_SRIOBOOT_MASTER_PORT); + "Port [ %d ] is ready, now release slave's core ...\n", + port); /* * configure outbound window * with maintenance attribute to set slave's LCSBA1CSR */ - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowtar, 0); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowtear, 0); - if (CONFIG_SRIOBOOT_MASTER_PORT) - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + if (port - 1) + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowbar, CONFIG_SYS_SRIO2_MEM_PHYS >> 12); else - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowbar, CONFIG_SYS_SRIO1_MEM_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowar, SRIO_OB_ATMU_AR_MAINT | atmu_size_mask(SRIO_MAINT_WIN_SIZE)); @@ -223,27 +189,22 @@ void srio_boot_master_release_slave(void) * configure outbound window * with R/W attribute to set slave's BRR */ - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowtar, SRIO_LCSBA1CSR >> 9); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowtear, 0); - if (CONFIG_SRIOBOOT_MASTER_PORT) - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + if (port - 1) + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowbar, (CONFIG_SYS_SRIO2_MEM_PHYS + SRIO_MAINT_WIN_SIZE) >> 12); else - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowbar, (CONFIG_SYS_SRIO1_MEM_PHYS + SRIO_MAINT_WIN_SIZE) >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowar, SRIO_OB_ATMU_AR_RW | atmu_size_mask(SRIO_RW_WIN_SIZE)); @@ -252,7 +213,7 @@ void srio_boot_master_release_slave(void) * Set the LCSBA1CSR register in slave * by the maint-outbound window */ - if (CONFIG_SRIOBOOT_MASTER_PORT) { + if (port - 1) { out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT + SRIO_LCSBA1CSR_OFFSET, SRIO_LCSBA1CSR); @@ -266,8 +227,8 @@ void srio_boot_master_release_slave(void) */ out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT + SRIO_MAINT_WIN_SIZE - + CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET, - CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK); + + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET, + CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK); } else { out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT + SRIO_LCSBA1CSR_OFFSET, @@ -282,15 +243,13 @@ void srio_boot_master_release_slave(void) */ out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT + SRIO_MAINT_WIN_SIZE - + CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET, - CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK); + + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET, + CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK); } debug("SRIOBOOT - MASTER: " "Release slave successfully! Now the slave should start up!\n"); } } else - debug("SRIOBOOT - MASTER: Port [ %d ] is not ready.\n", - CONFIG_SRIOBOOT_MASTER_PORT); + debug("SRIOBOOT - MASTER: Port [ %d ] is not ready.\n", port); } #endif -#endif diff --git a/arch/powerpc/include/asm/config.h b/arch/powerpc/include/asm/config.h index d138636..67cea01 100644 --- a/arch/powerpc/include/asm/config.h +++ b/arch/powerpc/include/asm/config.h @@ -29,6 +29,10 @@ #include <asm/config_mpc86xx.h> #endif +#ifndef HWCONFIG_BUFFER_SIZE + #define HWCONFIG_BUFFER_SIZE 256 +#endif + /* CONFIG_HARD_SPI triggers SPI bus initialization in PowerPC */ #if defined(CONFIG_MPC8XXX_SPI) || defined(CONFIG_FSL_ESPI) # ifndef CONFIG_HARD_SPI diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index b6c44bb..aa27741 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -37,6 +37,7 @@ #if defined(CONFIG_MPC8536) #define CONFIG_MAX_CPUS 1 #define CONFIG_SYS_FSL_NUM_LAWS 12 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 1 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 @@ -54,12 +55,14 @@ #elif defined(CONFIG_MPC8544) #define CONFIG_MAX_CPUS 1 #define CONFIG_SYS_FSL_NUM_LAWS 10 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 0 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #elif defined(CONFIG_MPC8548) #define CONFIG_MAX_CPUS 1 #define CONFIG_SYS_FSL_NUM_LAWS 10 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 0 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #define CONFIG_SYS_FSL_ERRATUM_NMG_DDR120 @@ -113,6 +116,7 @@ #elif defined(CONFIG_MPC8572) #define CONFIG_MAX_CPUS 2 #define CONFIG_SYS_FSL_NUM_LAWS 12 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #define CONFIG_SYS_FSL_ERRATUM_DDR_115 @@ -191,33 +195,6 @@ #define CONFIG_SYS_FSL_ERRATUM_P1010_A003549 #define CONFIG_SYS_FSL_ERRATUM_IFC_A003399 -/* P1015 is single core version of P1024 */ -#elif defined(CONFIG_P1015) -#define CONFIG_MAX_CPUS 1 -#define CONFIG_SYS_FSL_NUM_LAWS 12 -#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2 -#define CONFIG_TSECV2 -#define CONFIG_FSL_PCIE_DISABLE_ASPM -#define CONFIG_SYS_FSL_SEC_COMPAT 2 -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 -#define CONFIG_SYS_FSL_ERRATUM_ELBC_A001 -#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 - -/* P1016 is single core version of P1025 */ -#elif defined(CONFIG_P1016) -#define CONFIG_MAX_CPUS 1 -#define CONFIG_SYS_FSL_NUM_LAWS 12 -#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2 -#define CONFIG_TSECV2 -#define CONFIG_FSL_PCIE_DISABLE_ASPM -#define CONFIG_SYS_FSL_SEC_COMPAT 2 -#define CONFIG_SYS_FSL_ERRATUM_ELBC_A001 -#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 -#define QE_MURAM_SIZE 0x6000UL -#define MAX_QE_RISC 1 -#define QE_NUM_OF_SNUM 28 -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 - /* P1017 is single core version of P1023 */ #elif defined(CONFIG_P1017) #define CONFIG_MAX_CPUS 1 @@ -333,30 +310,7 @@ #define CONFIG_SYS_FSL_RMU #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM 2 -#elif defined(CONFIG_PPC_P2040) -#define CONFIG_MAX_CPUS 4 -#define CONFIG_SYS_FSL_NUM_CC_PLLS 2 -#define CONFIG_SYS_FSL_NUM_LAWS 32 -#define CONFIG_SYS_FSL_SEC_COMPAT 4 -#define CONFIG_SYS_NUM_FMAN 1 -#define CONFIG_SYS_NUM_FM1_DTSEC 5 -#define CONFIG_NUM_DDR_CONTROLLERS 1 -#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 -#define CONFIG_SYS_FSL_TBCLK_DIV 32 -#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 -#define CONFIG_SYS_FSL_USB1_PHY_ENABLE -#define CONFIG_SYS_FSL_USB2_PHY_ENABLE -#define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY -#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 -#define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 -#define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 -#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 -#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -#define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 -#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 - -#elif defined(CONFIG_PPC_P2041) +#elif defined(CONFIG_PPC_P2041) /* also supports P2040 */ #define CONFIG_MAX_CPUS 4 #define CONFIG_SYS_FSL_NUM_CC_PLLS 2 #define CONFIG_SYS_FSL_NUM_LAWS 32 @@ -380,6 +334,10 @@ #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 +#define CONFIG_SYS_FSL_ERRATUM_A004510 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x10 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 0x11 +#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000 #elif defined(CONFIG_PPC_P3041) #define CONFIG_MAX_CPUS 4 @@ -399,47 +357,18 @@ #define CONFIG_SYS_FSL_USB2_PHY_ENABLE #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 +#define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 +#define CONFIG_SYS_FSL_ERRATUM_A004510 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x10 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 0x11 +#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000 -#elif defined(CONFIG_PPC_P3060) -#define CONFIG_MAX_CPUS 8 -#define CONFIG_SYS_FSL_NUM_CC_PLLS 4 -#define CONFIG_SYS_FSL_NUM_LAWS 32 -#define CONFIG_SYS_FSL_SEC_COMPAT 4 -#define CONFIG_SYS_NUM_FMAN 2 -#define CONFIG_SYS_NUM_FM1_DTSEC 4 -#define CONFIG_SYS_NUM_FM2_DTSEC 4 -#define CONFIG_NUM_DDR_CONTROLLERS 1 -#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 -#define CONFIG_SYS_FSL_TBCLK_DIV 16 -#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 -#define CONFIG_SYS_FSL_ERRATUM_DDR_A003 -#define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 -#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -#define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 -#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 - -#elif defined(CONFIG_PPC_P4040) -#define CONFIG_MAX_CPUS 4 -#define CONFIG_SYS_FSL_NUM_CC_PLLS 4 -#define CONFIG_SYS_FSL_NUM_LAWS 32 -#define CONFIG_SYS_FSL_SEC_COMPAT 4 -#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 -#define CONFIG_SYS_FSL_TBCLK_DIV 16 -#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,p4080-pcie" -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 -#define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 -#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 -#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -#define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 -#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 - -#elif defined(CONFIG_PPC_P4080) +#elif defined(CONFIG_PPC_P4080) /* also supports P4040 */ #define CONFIG_MAX_CPUS 8 #define CONFIG_SYS_FSL_NUM_CC_PLLS 4 #define CONFIG_SYS_FSL_NUM_LAWS 32 @@ -474,32 +403,11 @@ #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 #define CONFIG_SYS_FSL_RMU #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM 2 +#define CONFIG_SYS_FSL_ERRATUM_A004510 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x20 +#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xff000000 -/* P5010 is single core version of P5020 */ -#elif defined(CONFIG_PPC_P5010) -#define CONFIG_MAX_CPUS 1 -#define CONFIG_SYS_FSL_NUM_CC_PLLS 2 -#define CONFIG_SYS_FSL_NUM_LAWS 32 -#define CONFIG_SYS_FSL_SEC_COMPAT 4 -#define CONFIG_FSL_SATA_V2 -#define CONFIG_SYS_NUM_FMAN 1 -#define CONFIG_SYS_NUM_FM1_DTSEC 5 -#define CONFIG_SYS_NUM_FM1_10GEC 1 -#define CONFIG_NUM_DDR_CONTROLLERS 1 -#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 -#define CONFIG_SYS_FSL_TBCLK_DIV 32 -#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 -#define CONFIG_SYS_FSL_USB1_PHY_ENABLE -#define CONFIG_SYS_FSL_USB2_PHY_ENABLE -#define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY -#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 -#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 -#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -#define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 -#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 - -#elif defined(CONFIG_PPC_P5020) +#elif defined(CONFIG_PPC_P5020) /* also supports P5010 */ #define CONFIG_MAX_CPUS 2 #define CONFIG_SYS_FSL_NUM_CC_PLLS 2 #define CONFIG_SYS_FSL_NUM_LAWS 32 @@ -521,6 +429,9 @@ #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 +#define CONFIG_SYS_FSL_ERRATUM_A004510 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x10 +#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xc0000000 #elif defined(CONFIG_BSC9131) #define CONFIG_MAX_CPUS 1 diff --git a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h index 982b809..ffe4db8 100644 --- a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h +++ b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h @@ -43,6 +43,7 @@ typedef struct dimm_params_s { /* DIMM timing parameters */ unsigned int mtb_ps; /* medium timebase ps, only for ddr3 */ + unsigned int ftb_10th_ps; /* fine timebase, in 1/10 ps, only for ddr3 */ unsigned int tAA_ps; /* minimum CAS latency time, only for ddr3 */ unsigned int tFAW_ps; /* four active window delay, only for ddr3 */ diff --git a/arch/powerpc/include/asm/fsl_ddr_sdram.h b/arch/powerpc/include/asm/fsl_ddr_sdram.h index 93639ba..e271342 100644 --- a/arch/powerpc/include/asm/fsl_ddr_sdram.h +++ b/arch/powerpc/include/asm/fsl_ddr_sdram.h @@ -76,6 +76,13 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t; #define FSL_DDR_PAGE_INTERLEAVING 0x1 #define FSL_DDR_BANK_INTERLEAVING 0x2 #define FSL_DDR_SUPERBANK_INTERLEAVING 0x3 +#define FSL_DDR_3WAY_1KB_INTERLEAVING 0xA +#define FSL_DDR_3WAY_4KB_INTERLEAVING 0xC +#define FSL_DDR_3WAY_8KB_INTERLEAVING 0xD +/* placeholder for 4-way interleaving */ +#define FSL_DDR_4WAY_1KB_INTERLEAVING 0x1A +#define FSL_DDR_4WAY_4KB_INTERLEAVING 0x1C +#define FSL_DDR_4WAY_8KB_INTERLEAVING 0x1D /* DDR_SDRAM_CFG - DDR SDRAM Control Configuration */ @@ -88,6 +95,7 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t; #define SDRAM_CFG_SDRAM_TYPE_MASK 0x07000000 #define SDRAM_CFG_SDRAM_TYPE_SHIFT 24 #define SDRAM_CFG_DYN_PWR 0x00200000 +#define SDRAM_CFG_DBW_MASK 0x00180000 #define SDRAM_CFG_32_BE 0x00080000 #define SDRAM_CFG_16_BE 0x00100000 #define SDRAM_CFG_8_BE 0x00040000 diff --git a/arch/powerpc/include/asm/fsl_ifc.h b/arch/powerpc/include/asm/fsl_ifc.h index 7d95eb4..ba41b73 100644 --- a/arch/powerpc/include/asm/fsl_ifc.h +++ b/arch/powerpc/include/asm/fsl_ifc.h @@ -783,12 +783,16 @@ extern void init_early_memctl_regs(void); #define IFC_BASE_ADDR ((struct fsl_ifc *)CONFIG_SYS_IFC_ADDR) +#define get_ifc_cspr_ext(i) (in_be32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr_ext)) #define get_ifc_cspr(i) (in_be32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr)) +#define get_ifc_csor_ext(i) (in_be32(&(IFC_BASE_ADDR)->csor_cs[i].csor_ext)) #define get_ifc_csor(i) (in_be32(&(IFC_BASE_ADDR)->csor_cs[i].csor)) #define get_ifc_amask(i) (in_be32(&(IFC_BASE_ADDR)->amask_cs[i].amask)) #define get_ifc_ftim(i, j) (in_be32(&(IFC_BASE_ADDR)->ftim_cs[i].ftim[j])) +#define set_ifc_cspr_ext(i, v) (out_be32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr_ext, v)) #define set_ifc_cspr(i, v) (out_be32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr, v)) +#define set_ifc_csor_ext(i, v) (out_be32(&(IFC_BASE_ADDR)->csor_cs[i].csor_ext, v)) #define set_ifc_csor(i, v) (out_be32(&(IFC_BASE_ADDR)->csor_cs[i].csor, v)) #define set_ifc_amask(i, v) (out_be32(&(IFC_BASE_ADDR)->amask_cs[i].amask, v)) #define set_ifc_ftim(i, j, v) \ @@ -909,22 +913,24 @@ struct fsl_ifc_gpcm { */ struct fsl_ifc { u32 ifc_rev; - u32 res1[0x3]; + u32 res1[0x2]; struct { + u32 cspr_ext; u32 cspr; - u32 res2[0x2]; + u32 res2; } cspr_cs[FSL_IFC_BANK_COUNT]; - u32 res3[0x18]; + u32 res3[0x19]; struct { u32 amask; u32 res4[0x2]; } amask_cs[FSL_IFC_BANK_COUNT]; - u32 res5[0x18]; + u32 res5[0x17]; struct { + u32 csor_ext; u32 csor; - u32 res6[0x2]; + u32 res6; } csor_cs[FSL_IFC_BANK_COUNT]; - u32 res7[0x18]; + u32 res7[0x19]; struct { u32 ftim[4]; u32 res8[0x8]; diff --git a/arch/powerpc/include/asm/fsl_law.h b/arch/powerpc/include/asm/fsl_law.h index 13caffd..f9cec8e 100644 --- a/arch/powerpc/include/asm/fsl_law.h +++ b/arch/powerpc/include/asm/fsl_law.h @@ -60,14 +60,19 @@ enum law_trgt_if { LAW_TRGT_IF_DDR_1 = 0x10, LAW_TRGT_IF_DDR_2 = 0x11, /* 2nd controller */ + LAW_TRGT_IF_DDR_3 = 0x12, + LAW_TRGT_IF_DDR_4 = 0x13, LAW_TRGT_IF_DDR_INTRLV = 0x14, - + LAW_TRGT_IF_DDR_INTLV_34 = 0x15, + LAW_TRGT_IF_DDR_INTLV_123 = 0x17, + LAW_TRGT_IF_DDR_INTLV_1234 = 0x16, LAW_TRGT_IF_BMAN = 0x18, LAW_TRGT_IF_DCSR = 0x1d, LAW_TRGT_IF_LBC = 0x1f, LAW_TRGT_IF_QMAN = 0x3c, }; #define LAW_TRGT_IF_DDR LAW_TRGT_IF_DDR_1 +#define LAW_TRGT_IF_IFC LAW_TRGT_IF_LBC #else enum law_trgt_if { LAW_TRGT_IF_PCI = 0x00, @@ -86,6 +91,12 @@ enum law_trgt_if { LAW_TRGT_IF_DPAA_SWP_SRAM = 0x0e, LAW_TRGT_IF_DDR = 0x0f, LAW_TRGT_IF_DDR_2 = 0x16, /* 2nd controller */ + /* place holder for 3-way and 4-way interleaving */ + LAW_TRGT_IF_DDR_3, + LAW_TRGT_IF_DDR_4, + LAW_TRGT_IF_DDR_INTLV_34, + LAW_TRGT_IF_DDR_INTLV_123, + LAW_TRGT_IF_DDR_INTLV_1234, }; #define LAW_TRGT_IF_DDR_1 LAW_TRGT_IF_DDR #define LAW_TRGT_IF_PCI_1 LAW_TRGT_IF_PCI diff --git a/arch/powerpc/include/asm/fsl_serdes.h b/arch/powerpc/include/asm/fsl_serdes.h index 0f31af1..22525f1 100644 --- a/arch/powerpc/include/asm/fsl_serdes.h +++ b/arch/powerpc/include/asm/fsl_serdes.h @@ -41,6 +41,7 @@ enum srds_prtcl { SGMII_FM2_DTSEC2, SGMII_FM2_DTSEC3, SGMII_FM2_DTSEC4, + SGMII_FM2_DTSEC5, SGMII_TSEC1, SGMII_TSEC2, SGMII_TSEC3, diff --git a/arch/powerpc/include/asm/fsl_srio.h b/arch/powerpc/include/asm/fsl_srio.h index a905a26..dfd8e08 100644 --- a/arch/powerpc/include/asm/fsl_srio.h +++ b/arch/powerpc/include/asm/fsl_srio.h @@ -55,10 +55,8 @@ enum atmu_size { #define atmu_size_bytes(x) (1ULL << ((x & 0x3f) + 1)) extern void srio_init(void); -#ifdef CONFIG_SRIOBOOT_MASTER -extern void srio_boot_master(void); -#ifdef CONFIG_SRIOBOOT_SLAVE_HOLDOFF -extern void srio_boot_master_release_slave(void); -#endif +#ifdef CONFIG_FSL_CORENET +extern void srio_boot_master(int port); +extern void srio_boot_master_release_slave(int port); #endif #endif diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 53d563e..7de33a7 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -1729,6 +1729,7 @@ typedef struct ccsr_gur { #define FSL_CORENET_DEVDISR2_DTSEC2_2 0x00004000 #define FSL_CORENET_DEVDISR2_DTSEC2_3 0x00002000 #define FSL_CORENET_DEVDISR2_DTSEC2_4 0x00001000 +#define FSL_CORENET_DEVDISR2_DTSEC2_5 0x00000800 #define FSL_CORENET_NUM_DEVDISR 2 u8 res7[8]; u32 powmgtcsr; /* Power management status & control */ @@ -1758,13 +1759,14 @@ typedef struct ccsr_gur { #define FSL_CORENET_RCWSR5_DDR_SYNC 0x00000080 #define FSL_CORENET_RCWSR5_DDR_SYNC_SHIFT 7 #define FSL_CORENET_RCWSR5_SRDS_EN 0x00002000 +#define FSL_CORENET_RCWSR6_BOOT_LOC 0x0f800000 #define FSL_CORENET_RCWSRn_SRDS_LPD_B2 0x3c000000 /* bits 162..165 */ #define FSL_CORENET_RCWSRn_SRDS_LPD_B3 0x003c0000 /* bits 170..173 */ #define FSL_CORENET_RCWSR7_MCK_TO_PLAT_RAT 0x00400000 #define FSL_CORENET_RCWSR8_HOST_AGT_B1 0x00e00000 #define FSL_CORENET_RCWSR8_HOST_AGT_B2 0x00100000 #define FSL_CORENET_RCWSR11_EC1 0x00c00000 /* bits 360..361 */ -#if defined(CONFIG_PPC_P4080) || defined(CONFIG_PPC_P3060) +#ifdef CONFIG_PPC_P4080 #define FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1 0x00000000 #define FSL_CORENET_RCWSR11_EC1_FM1_USB1 0x00800000 #define FSL_CORENET_RCWSR11_EC2 0x001c0000 /* bits 363..365 */ @@ -1772,7 +1774,7 @@ typedef struct ccsr_gur { #define FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2 0x00080000 #define FSL_CORENET_RCWSR11_EC2_USB2 0x00100000 #endif -#if defined(CONFIG_PPC_P2040) || defined(CONFIG_PPC_P2041) \ +#if defined(CONFIG_PPC_P2041) \ || defined(CONFIG_PPC_P3041) || defined(CONFIG_PPC_P5020) #define FSL_CORENET_RCWSR11_EC1_FM1_DTSEC4_RGMII 0x00000000 #define FSL_CORENET_RCWSR11_EC1_FM1_DTSEC4_MII 0x00800000 @@ -1836,7 +1838,13 @@ typedef struct ccsr_gur { u8 res31[184]; u32 sriopstecr; /* SRIO prescaler timer enable control */ u32 dcsrcr; /* DCSR Control register */ - u8 res32[1784]; + u8 res31a[56]; + u32 tp_ityp[64]; /* Topology Initiator Type Register */ + struct { + u32 upper; + u32 lower; + } tp_cluster[16]; /* Core Cluster n Topology Register */ + u8 res32[1344]; u32 pmuxcr; /* Pin multiplexing control */ u8 res33[60]; u32 iovselsr; /* I/O voltage selection status */ @@ -1849,6 +1857,18 @@ typedef struct ccsr_gur { u8 res37[380]; } ccsr_gur_t; +#define TP_ITYP_AV 0x00000001 /* Initiator available */ +#define TP_ITYP_TYPE(x) (((x) & 0x6) >> 1) /* Initiator Type */ +#define TP_ITYP_TYPE_OTHER 0x0 +#define TP_ITYP_TYPE_PPC 0x1 /* PowerPC */ +#define TP_ITYP_TYPE_SC 0x2 /* StarCore DSP */ +#define TP_ITYP_TYPE_HA 0x3 /* HW Accelerator */ +#define TP_ITYP_THDS(x) (((x) & 0x18) >> 3) /* # threads */ +#define TP_ITYP_VER(x) (((x) & 0xe0) >> 5) /* Initiator Version */ + +#define TP_CLUSTER_EOC 0x80000000 /* end of clusters */ +#define TP_CLUSTER_INIT_MASK 0x0000003f /* initiator mask */ + #define FSL_CORENET_DCSR_SZ_MASK 0x00000003 #define FSL_CORENET_DCSR_SZ_4M 0x0 #define FSL_CORENET_DCSR_SZ_1G 0x3 @@ -1890,6 +1910,73 @@ typedef struct ccsr_clk { u8 res15[0x3dc]; } ccsr_clk_t; +#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 +typedef struct ccsr_rcpm { + u8 res_00[12]; + u32 tph10sr0; /* Thread PH10 Status Register */ + u8 res_10[12]; + u32 tph10setr0; /* Thread PH10 Set Control Register */ + u8 res_20[12]; + u32 tph10clrr0; /* Thread PH10 Clear Control Register */ + u8 res_30[12]; + u32 tph10psr0; /* Thread PH10 Previous Status Register */ + u8 res_40[12]; + u32 twaitsr0; /* Thread Wait Status Register */ + u8 res_50[96]; + u32 pcph15sr; /* Physical Core PH15 Status Register */ + u32 pcph15setr; /* Physical Core PH15 Set Control Register */ + u32 pcph15clrr; /* Physical Core PH15 Clear Control Register */ + u32 pcph15psr; /* Physical Core PH15 Prev Status Register */ + u8 res_c0[16]; + u32 pcph20sr; /* Physical Core PH20 Status Register */ + u32 pcph20setr; /* Physical Core PH20 Set Control Register */ + u32 pcph20clrr; /* Physical Core PH20 Clear Control Register */ + u32 pcph20psr; /* Physical Core PH20 Prev Status Register */ + u32 pcpw20sr; /* Physical Core PW20 Status Register */ + u8 res_e0[12]; + u32 pcph30sr; /* Physical Core PH30 Status Register */ + u32 pcph30setr; /* Physical Core PH30 Set Control Register */ + u32 pcph30clrr; /* Physical Core PH30 Clear Control Register */ + u32 pcph30psr; /* Physical Core PH30 Prev Status Register */ + u8 res_100[32]; + u32 ippwrgatecr; /* IP Power Gating Control Register */ + u8 res_124[12]; + u32 powmgtcsr; /* Power Management Control & Status Reg */ + u8 res_134[12]; + u32 ippdexpcr[4]; /* IP Powerdown Exception Control Reg */ + u8 res_150[12]; + u32 tpmimr0; /* Thread PM Interrupt Mask Reg */ + u8 res_160[12]; + u32 tpmcimr0; /* Thread PM Crit Interrupt Mask Reg */ + u8 res_170[12]; + u32 tpmmcmr0; /* Thread PM Machine Check Interrupt Mask Reg */ + u8 res_180[12]; + u32 tpmnmimr0; /* Thread PM NMI Mask Reg */ + u8 res_190[12]; + u32 tmcpmaskcr0; /* Thread Machine Check Mask Control Reg */ + u32 pctbenr; /* Physical Core Time Base Enable Reg */ + u32 pctbclkselr; /* Physical Core Time Base Clock Select */ + u32 tbclkdivr; /* Time Base Clock Divider Register */ + u8 res_1ac[4]; + u32 ttbhltcr[4]; /* Thread Time Base Halt Control Register */ + u32 clpcl10sr; /* Cluster PCL10 Status Register */ + u32 clpcl10setr; /* Cluster PCL30 Set Control Register */ + u32 clpcl10clrr; /* Cluster PCL30 Clear Control Register */ + u32 clpcl10psr; /* Cluster PCL30 Prev Status Register */ + u32 cddslpsetr; /* Core Domain Deep Sleep Set Register */ + u32 cddslpclrr; /* Core Domain Deep Sleep Clear Register */ + u32 cdpwroksetr; /* Core Domain Power OK Set Register */ + u32 cdpwrokclrr; /* Core Domain Power OK Clear Register */ + u32 cdpwrensr; /* Core Domain Power Enable Status Register */ + u32 cddslsr; /* Core Domain Deep Sleep Status Register */ + u8 res_1e8[8]; + u32 dslpcntcr[8]; /* Deep Sleep Counter Cfg Register */ + u8 res_300[3568]; +} ccsr_rcpm_t; + +#define ctbenrl pctbenr + +#else typedef struct ccsr_rcpm { u8 res1[4]; u32 cdozsrl; /* Core Doze Status */ @@ -1926,6 +2013,7 @@ typedef struct ccsr_rcpm { u32 ctbhltcrl; /* Core Time Base Halt Control */ u8 res18[0xf68]; } ccsr_rcpm_t; +#endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ #else typedef struct ccsr_gur { @@ -2259,8 +2347,7 @@ typedef struct ccsr_gur { u8 res11a[76]; par_io_t qe_par_io[7]; u8 res11b[1600]; -#elif defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#elif defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) u8 res11a[12]; u32 iovselsr; u8 res11b[60]; @@ -2534,6 +2621,7 @@ struct ccsr_rman { #define CONFIG_SYS_FSL_CORENET_CCM_OFFSET 0x0000 #define CONFIG_SYS_MPC85xx_DDR_OFFSET 0x8000 #define CONFIG_SYS_MPC85xx_DDR2_OFFSET 0x9000 +#define CONFIG_SYS_MPC85xx_DDR3_OFFSET 0xA000 #define CONFIG_SYS_FSL_CORENET_CLK_OFFSET 0xE1000 #define CONFIG_SYS_FSL_CORENET_RCPM_OFFSET 0xE2000 #define CONFIG_SYS_FSL_CORENET_SERDES_OFFSET 0xEA000 @@ -2544,6 +2632,7 @@ struct ccsr_rman { #define CONFIG_SYS_MPC85xx_ESPI_OFFSET 0x110000 #define CONFIG_SYS_MPC85xx_ESDHC_OFFSET 0x114000 #define CONFIG_SYS_MPC85xx_LBC_OFFSET 0x124000 +#define CONFIG_SYS_MPC85xx_IFC_OFFSET 0x124000 #define CONFIG_SYS_MPC85xx_GPIO_OFFSET 0x130000 #define CONFIG_SYS_FSL_CORENET_RMAN_OFFSET 0x1e0000 #define CONFIG_SYS_MPC85xx_PCIE1_OFFSET 0x200000 @@ -2652,6 +2741,8 @@ struct ccsr_rman { (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR_OFFSET) #define CONFIG_SYS_MPC85xx_DDR2_ADDR \ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR2_OFFSET) +#define CONFIG_SYS_MPC85xx_DDR3_ADDR \ + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR3_OFFSET) #define CONFIG_SYS_LBC_ADDR \ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_LBC_OFFSET) #define CONFIG_SYS_IFC_ADDR \ diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index ec0bfae..9e20861 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -162,7 +162,7 @@ static inline void __raw_writel(unsigned int v, volatile void __iomem *addr) * is actually performed (i.e. the data has come back) before we start * executing any following instructions. */ -static inline u8 in_8(const volatile unsigned char __iomem *addr) +extern inline u8 in_8(const volatile unsigned char __iomem *addr) { u8 ret; @@ -173,7 +173,7 @@ static inline u8 in_8(const volatile unsigned char __iomem *addr) return ret; } -static inline void out_8(volatile unsigned char __iomem *addr, u8 val) +extern inline void out_8(volatile unsigned char __iomem *addr, u8 val) { __asm__ __volatile__("sync;\n" "stb%U0%X0 %1,%0;\n" @@ -181,7 +181,7 @@ static inline void out_8(volatile unsigned char __iomem *addr, u8 val) : "r" (val)); } -static inline u16 in_le16(const volatile unsigned short __iomem *addr) +extern inline u16 in_le16(const volatile unsigned short __iomem *addr) { u16 ret; @@ -192,7 +192,7 @@ static inline u16 in_le16(const volatile unsigned short __iomem *addr) return ret; } -static inline u16 in_be16(const volatile unsigned short __iomem *addr) +extern inline u16 in_be16(const volatile unsigned short __iomem *addr) { u16 ret; @@ -202,18 +202,18 @@ static inline u16 in_be16(const volatile unsigned short __iomem *addr) return ret; } -static inline void out_le16(volatile unsigned short __iomem *addr, u16 val) +extern inline void out_le16(volatile unsigned short __iomem *addr, u16 val) { __asm__ __volatile__("sync; sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); } -static inline void out_be16(volatile unsigned short __iomem *addr, u16 val) +extern inline void out_be16(volatile unsigned short __iomem *addr, u16 val) { __asm__ __volatile__("sync; sth%U0%X0 %1,%0" : "=m" (*addr) : "r" (val)); } -static inline u32 in_le32(const volatile unsigned __iomem *addr) +extern inline u32 in_le32(const volatile unsigned __iomem *addr) { u32 ret; @@ -224,7 +224,7 @@ static inline u32 in_le32(const volatile unsigned __iomem *addr) return ret; } -static inline u32 in_be32(const volatile unsigned __iomem *addr) +extern inline u32 in_be32(const volatile unsigned __iomem *addr) { u32 ret; @@ -234,13 +234,13 @@ static inline u32 in_be32(const volatile unsigned __iomem *addr) return ret; } -static inline void out_le32(volatile unsigned __iomem *addr, u32 val) +extern inline void out_le32(volatile unsigned __iomem *addr, u32 val) { __asm__ __volatile__("sync; stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); } -static inline void out_be32(volatile unsigned __iomem *addr, u32 val) +extern inline void out_be32(volatile unsigned __iomem *addr, u32 val) { __asm__ __volatile__("sync; stw%U0%X0 %1,%0" : "=m" (*addr) : "r" (val)); } diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 209103e..2e0e292 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -475,6 +475,10 @@ extern void print_bats(void); #define BOOKE_PAGESZ_256GB 14 #define BOOKE_PAGESZ_1TB 15 +#define TLBIVAX_ALL 4 +#define TLBIVAX_TLB0 0 +#define TLBIVAX_TLB1 8 + #ifdef CONFIG_E500 #ifndef __ASSEMBLY__ extern void set_tlb(u8 tlb, u32 epn, u64 rpn, diff --git a/arch/powerpc/include/asm/mp.h b/arch/powerpc/include/asm/mp.h index 3ffa30b..fe490ba 100644 --- a/arch/powerpc/include/asm/mp.h +++ b/arch/powerpc/include/asm/mp.h @@ -28,4 +28,10 @@ void cpu_mp_lmb_reserve(struct lmb *lmb); u32 determine_mp_bootpg(void); int is_core_disabled(int nr); +#ifdef CONFIG_E6500 +#define thread_to_core(x) (x >> 1) +#else +#define thread_to_core(x) (x) +#endif + #endif diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index dc009d6..36695e2 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -486,11 +486,13 @@ #define SPRN_L2CFG0 0x207 /* L2 Cache Configuration Register 0 */ #define SPRN_L1CSR0 0x3f2 /* L1 Data Cache Control and Status Register 0 */ #define L1CSR0_CPE 0x00010000 /* Data Cache Parity Enable */ +#define L1CSR0_CUL 0x00000400 /* (D-)Cache Unable to Lock */ #define L1CSR0_DCLFR 0x00000100 /* D-Cache Lock Flash Reset */ #define L1CSR0_DCFI 0x00000002 /* Data Cache Flash Invalidate */ #define L1CSR0_DCE 0x00000001 /* Data Cache Enable */ #define SPRN_L1CSR1 0x3f3 /* L1 Instruction Cache Control and Status Register 1 */ #define L1CSR1_CPE 0x00010000 /* Instruction Cache Parity Enable */ +#define L1CSR1_ICUL 0x00000400 /* I-Cache Unable to Lock */ #define L1CSR1_ICLFR 0x00000100 /* I-Cache Lock Flash Reset */ #define L1CSR1_ICFI 0x00000002 /* Instruction Cache Flash Invalidate */ #define L1CSR1_ICE 0x00000001 /* Instruction Cache Enable */ @@ -513,6 +515,7 @@ #define SPRN_TLB0CFG 0x2B0 /* TLB 0 Config Register */ #define SPRN_TLB1CFG 0x2B1 /* TLB 1 Config Register */ +#define TLBnCFG_NENTRY_MASK 0x00000fff #define SPRN_TLB0PS 0x158 /* TLB 0 Page Size Register */ #define SPRN_TLB1PS 0x159 /* TLB 1 Page Size Register */ #define SPRN_MMUCSR0 0x3f4 /* MMU control and status register 0 */ @@ -948,6 +951,7 @@ #define PVR_VER_E500_V2 0x8021 #define PVR_VER_E500MC 0x8023 #define PVR_VER_E5500 0x8024 +#define PVR_VER_E6500 0x8040 #define PVR_86xx 0x80040000 @@ -1075,8 +1079,6 @@ #define SVR_P1012 0x80E501 #define SVR_P1013 0x80E700 #define SVR_P1014 0x80F101 -#define SVR_P1015 0x80E502 -#define SVR_P1016 0x80E503 #define SVR_P1017 0x80F700 #define SVR_P1020 0x80E400 #define SVR_P1021 0x80E401 @@ -1089,7 +1091,6 @@ #define SVR_P2040 0x821000 #define SVR_P2041 0x821001 #define SVR_P3041 0x821103 -#define SVR_P3060 0x820002 #define SVR_P4040 0x820100 #define SVR_P4080 0x820000 #define SVR_P5010 0x822100 @@ -1158,6 +1159,7 @@ struct cpu_type { }; struct cpu_type *identify_cpu(u32 ver); +int fixup_cpu(void); #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) #define CPU_TYPE_ENTRY(n, v, nc) \ diff --git a/arch/powerpc/include/asm/u-boot.h b/arch/powerpc/include/asm/u-boot.h index 1552054..b2fa2b5 100644 --- a/arch/powerpc/include/asm/u-boot.h +++ b/arch/powerpc/include/asm/u-boot.h @@ -63,6 +63,7 @@ typedef struct bd_info { unsigned long bi_vcofreq; /* VCO Freq, in MHz */ #endif unsigned long bi_bootflags; /* boot / reboot flag (Unused) */ + unsigned long bi_ip_addr; /* IP Address */ unsigned char bi_enetaddr[6]; /* OLD: see README.enetaddr */ unsigned short bi_ethspeed; /* Ethernet speed in Mbps */ unsigned long bi_intfreq; /* Internal Freq, in MHz */ diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index fea310e..07feaf5 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -345,6 +345,13 @@ ulong get_effective_memsize(void) #endif } +int __fixup_cpu(void) +{ + return 0; +} + +int fixup_cpu(void) __attribute__((weak, alias("__fixup_cpu"))); + /* * This is the first part of the initialization sequence that is * implemented in C, but still running from ROM. @@ -521,9 +528,8 @@ void board_init_f(ulong bootflag) addr_sp -= 16; addr_sp &= ~0xF; s = (ulong *) addr_sp; - *s-- = 0; - *s-- = 0; - addr_sp = (ulong) s; + *s = 0; /* Terminate back chain */ + *++s = 0; /* NULL return address */ debug("Stack Pointer at: %08lx\n", addr_sp); /* @@ -647,6 +653,12 @@ void board_init_r(gd_t *id, ulong dest_addr) * We need to update it to point to the same CPU entry in RAM. */ gd->cpu += dest_addr - CONFIG_SYS_MONITOR_BASE; + + /* + * If we didn't know the cpu mask & # cores, we can save them of + * now rather than 'computing' them constantly + */ + fixup_cpu(); #endif #ifdef CONFIG_SYS_EXTRA_ENV_RELOC diff --git a/arch/powerpc/lib/ticks.S b/arch/powerpc/lib/ticks.S index b8d25b7..1781039 100644 --- a/arch/powerpc/lib/ticks.S +++ b/arch/powerpc/lib/ticks.S @@ -47,7 +47,9 @@ get_ticks: */ .globl wait_ticks wait_ticks: - mflr r8 /* save link register */ + stwu r1, -16(r1) + mflr r0 /* save link register */ + stw r0, 20(r1) /* Use r0 or GDB will be unhappy */ mr r7, r3 /* save tick count */ bl get_ticks /* Get start time */ @@ -61,5 +63,6 @@ wait_ticks: subfe. r3, r3, r6 bge 1b /* Loop until time expired */ - mtlr r8 /* restore link register */ + mtlr r0 /* restore link register */ + addi r1,r1,16 blr diff --git a/arch/sandbox/include/asm/errno.h b/arch/sandbox/include/asm/errno.h new file mode 100644 index 0000000..4c82b50 --- /dev/null +++ b/arch/sandbox/include/asm/errno.h @@ -0,0 +1 @@ +#include <asm-generic/errno.h> diff --git a/arch/sparc/cpu/leon2/interrupts.c b/arch/sparc/cpu/leon2/interrupts.c index 5149550..f707efd 100644 --- a/arch/sparc/cpu/leon2/interrupts.c +++ b/arch/sparc/cpu/leon2/interrupts.c @@ -207,9 +207,9 @@ void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const a for (irq = 0; irq < NR_IRQS; irq++) { if (irq_handlers[irq].handler != NULL) { - printf("%02d %08lx %08lx %ld\n", irq, - (unsigned int)irq_handlers[irq].handler, - (unsigned int)irq_handlers[irq].arg, + printf("%02d %p %p %d\n", irq, + irq_handlers[irq].handler, + irq_handlers[irq].arg, irq_handlers[irq].count); } } diff --git a/arch/sparc/cpu/leon3/interrupts.c b/arch/sparc/cpu/leon3/interrupts.c index 4138f9b..4a3847d 100644 --- a/arch/sparc/cpu/leon3/interrupts.c +++ b/arch/sparc/cpu/leon3/interrupts.c @@ -209,9 +209,9 @@ void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const a for (irq = 0; irq < NR_IRQS; irq++) { if (irq_handlers[irq].handler != NULL) { - printf("%02d %08lx %08lx %ld\n", irq, - (unsigned int)irq_handlers[irq].handler, - (unsigned int)irq_handlers[irq].arg, + printf("%02d %p %p %d\n", irq, + irq_handlers[irq].handler, + irq_handlers[irq].arg, irq_handlers[irq].count); } } diff --git a/arch/sparc/lib/board.c b/arch/sparc/lib/board.c index 7e48775..ff0e0f2 100644 --- a/arch/sparc/lib/board.c +++ b/arch/sparc/lib/board.c @@ -62,7 +62,6 @@ DECLARE_GLOBAL_DATA_PTR; */ extern void timer_interrupt_init(void); -extern void malloc_bin_reloc(void); extern int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]); extern int prom_init(void); @@ -166,7 +165,6 @@ char *str_init_seq_done = "\n\rInit sequence done...\r\n\r\n"; void board_init_f(ulong bootflag) { bd_t *bd; - unsigned char *s; init_fnc_t **init_fnc_ptr; int j; diff --git a/board/apollon/apollon.c b/board/apollon/apollon.c deleted file mode 100644 index 76626f0..0000000 --- a/board/apollon/apollon.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * (C) Copyright 2005-2007 - * Samsung Electronics. - * Kyungmin Park <kyungmin.park@samsung.com> - * - * Derived from omap2420 - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include <common.h> -#include <netdev.h> -#include <asm/arch/omap2420.h> -#include <asm/io.h> -#include <asm/arch/bits.h> -#include <asm/arch/mux.h> -#include <asm/arch/sys_proto.h> -#include <asm/arch/sys_info.h> -#include <asm/arch/mem.h> -#include <asm/mach-types.h> - -void wait_for_command_complete(unsigned int wd_base); - -DECLARE_GLOBAL_DATA_PTR; - -#define write_config_reg(reg, value) \ -do { \ - writeb(value, reg); \ -} while (0) - -#define mask_config_reg(reg, mask) \ -do { \ - char value = readb(reg) & ~(mask); \ - writeb(value, reg); \ -} while (0) - -/******************************************************* - * Routine: delay - * Description: spinning delay to use before udelay works - ******************************************************/ -static inline void delay(unsigned long loops) -{ - __asm__("1:\n" "subs %0, %1, #1\n" - "bne 1b":"=r" (loops):"0"(loops)); -} - -/***************************************** - * Routine: board_init - * Description: Early hardware init. - *****************************************/ -int board_init(void) -{ - gpmc_init(); /* in SRAM or SDRM, finish GPMC */ - - gd->bd->bi_arch_number = 919; - /* adress of boot parameters */ - gd->bd->bi_boot_params = (OMAP2420_SDRC_CS0 + 0x100); - - return 0; -} - -/********************************************************** - * Routine: s_init - * Description: Does early system init of muxing and clocks. - * - Called path is with sram stack. - **********************************************************/ -void s_init(void) -{ - watchdog_init(); - set_muxconf_regs(); - delay(100); - - peripheral_enable(); - icache_enable(); -} - -/******************************************************* - * Routine: misc_init_r - * Description: Init ethernet (done here so udelay works) - ********************************************************/ -int misc_init_r(void) -{ - return (0); -} - -/**************************************** - * Routine: watchdog_init - * Description: Shut down watch dogs - *****************************************/ -void watchdog_init(void) -{ - /* There are 4 watch dogs. 1 secure, and 3 general purpose. - * The ROM takes care of the secure one. Of the 3 GP ones, - * 1 can reset us directly, the other 2 only generate MPU interrupts. - */ - __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR); - wait_for_command_complete(WD2_BASE); - __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR); - -#define MPU_WD_CLOCKED 1 -#if MPU_WD_CLOCKED - /* value 0x10 stick on aptix, BIT4 polarity seems oppsite */ - __raw_writel(WD_UNLOCK1, WD3_BASE + WSPR); - wait_for_command_complete(WD3_BASE); - __raw_writel(WD_UNLOCK2, WD3_BASE + WSPR); - - __raw_writel(WD_UNLOCK1, WD4_BASE + WSPR); - wait_for_command_complete(WD4_BASE); - __raw_writel(WD_UNLOCK2, WD4_BASE + WSPR); -#endif -} - -/****************************************************** - * Routine: wait_for_command_complete - * Description: Wait for posting to finish on watchdog - ******************************************************/ -void wait_for_command_complete(unsigned int wd_base) -{ - int pending = 1; - do { - pending = __raw_readl(wd_base + WWPS); - } while (pending); -} - -/******************************************************************* - * Routine:board_eth_init - * Description: take the Ethernet controller out of reset and wait - * for the EEPROM load to complete. - ******************************************************************/ -int board_eth_init(bd_t *bis) -{ - int rc = 0; -#ifdef CONFIG_LAN91C96 - int cnt = 20; - - __raw_writeb(0x03, OMAP2420_CTRL_BASE + 0x0f2); /*protect->gpio74 */ - - __raw_writew(0x0, LAN_RESET_REGISTER); - do { - __raw_writew(0x1, LAN_RESET_REGISTER); - udelay(100); - if (cnt == 0) - goto eth_reset_err_out; - --cnt; - } while (__raw_readw(LAN_RESET_REGISTER) != 0x1); - - cnt = 20; - - do { - __raw_writew(0x0, LAN_RESET_REGISTER); - udelay(100); - if (cnt == 0) - goto eth_reset_err_out; - --cnt; - } while (__raw_readw(LAN_RESET_REGISTER) != 0x0000); - udelay(1000); - - mask_config_reg(ETH_CONTROL_REG, 0x01); - udelay(1000); - rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE); -eth_reset_err_out: -#endif - return rc; -} - -/********************************************** - * Routine: dram_init - * Description: sets uboots idea of sdram size - **********************************************/ -int dram_init(void) -{ - unsigned int size; - u32 mtype, btype; -#define NOT_EARLY 0 - - btype = get_board_type(); - mtype = get_mem_type(); - - display_board_info(btype); - - if ((mtype == DDR_COMBO) || (mtype == DDR_STACKED)) { - /* init other chip select */ - do_sdrc_init(SDRC_CS1_OSET, NOT_EARLY); - } - - size = get_sdr_cs_size(SDRC_CS0_OSET); - - gd->bd->bi_dram[0].start = PHYS_SDRAM_1; - gd->bd->bi_dram[0].size = size; -#if CONFIG_NR_DRAM_BANKS > 1 - size = get_sdr_cs_size(SDRC_CS1_OSET); - - gd->bd->bi_dram[1].start = gd->bd->bi_dram[0].start + - gd->bd->bi_dram[0].size; - gd->bd->bi_dram[1].size = size; -#endif - - return 0; -} - -/********************************************************** - * Routine: set_muxconf_regs - * Description: Setting up the configuration Mux registers - * specific to the hardware - *********************************************************/ -void set_muxconf_regs(void) -{ - muxSetupSDRC(); - muxSetupGPMC(); - muxSetupUsb0(); /* USB Device */ - muxSetupUsbHost(); /* USB Host */ - muxSetupUART1(); - muxSetupLCD(); - muxSetupMMCSD(); - muxSetupTouchScreen(); -} - -/***************************************************************** - * Routine: peripheral_enable - * Description: Enable the clks & power for perifs (GPT2, UART1,...) - ******************************************************************/ -void peripheral_enable(void) -{ - unsigned int v, if_clks = 0, func_clks = 0; - - /* Enable GP2 timer. */ - if_clks |= BIT4 | BIT3; - func_clks |= BIT4 | BIT3; - /* Sys_clk input OMAP2420_GPT2 */ - v = __raw_readl(CM_CLKSEL2_CORE) | 0x4 | 0x2; - __raw_writel(v, CM_CLKSEL2_CORE); - __raw_writel(0x1, CM_CLKSEL_WKUP); - -#ifdef CONFIG_SYS_NS16550 - /* Enable UART1 clock */ - func_clks |= BIT21; - if_clks |= BIT21; -#endif - /* Interface clocks on */ - v = __raw_readl(CM_ICLKEN1_CORE) | if_clks; - __raw_writel(v, CM_ICLKEN1_CORE); - /* Functional Clocks on */ - v = __raw_readl(CM_FCLKEN1_CORE) | func_clks; - __raw_writel(v, CM_FCLKEN1_CORE); - delay(1000); - -#ifndef KERNEL_UPDATED - { -#define V1 0xffffffff -#define V2 0x00000007 - - __raw_writel(V1, CM_FCLKEN1_CORE); - __raw_writel(V2, CM_FCLKEN2_CORE); - __raw_writel(V1, CM_ICLKEN1_CORE); - __raw_writel(V1, CM_ICLKEN2_CORE); - } -#endif -} - -/**************************************** - * Routine: muxSetupUsb0 (ostboot) - * Description: Setup usb muxing - *****************************************/ -void muxSetupUsb0(void) -{ - mask_config_reg(CONTROL_PADCONF_USB0_PUEN, 0x1f); - mask_config_reg(CONTROL_PADCONF_USB0_VP, 0x1f); - mask_config_reg(CONTROL_PADCONF_USB0_VM, 0x1f); - mask_config_reg(CONTROL_PADCONF_USB0_RCV, 0x1f); - mask_config_reg(CONTROL_PADCONF_USB0_TXEN, 0x1f); - mask_config_reg(CONTROL_PADCONF_USB0_SE0, 0x1f); - mask_config_reg(CONTROL_PADCONF_USB0_DAT, 0x1f); -} - -/**************************************** - * Routine: muxSetupUSBHost (ostboot) - * Description: Setup USB Host muxing - *****************************************/ -void muxSetupUsbHost(void) -{ - /* V19 */ - write_config_reg(CONTROL_PADCONF_USB1_RCV, 1); - /* W20 */ - write_config_reg(CONTROL_PADCONF_USB1_TXEN, 1); - /* N14 */ - write_config_reg(CONTROL_PADCONF_GPIO69, 3); - /* P15 */ - write_config_reg(CONTROL_PADCONF_GPIO70, 3); - /* L18 */ - write_config_reg(CONTROL_PADCONF_GPIO102, 3); - /* L19 */ - write_config_reg(CONTROL_PADCONF_GPIO103, 3); - /* K15 */ - write_config_reg(CONTROL_PADCONF_GPIO104, 3); - /* K14 */ - write_config_reg(CONTROL_PADCONF_GPIO105, 3); -} - -/**************************************** - * Routine: muxSetupUART1 (ostboot) - * Description: Set up uart1 muxing - *****************************************/ -void muxSetupUART1(void) -{ - /* UART1_CTS pin configuration, PIN = D21, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_UART1_CTS, 0); - /* UART1_RTS pin configuration, PIN = H21, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_UART1_RTS, 0); - /* UART1_TX pin configuration, PIN = L20, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_UART1_TX, 0); - /* UART1_RX pin configuration, PIN = T21, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_UART1_RX, 0); -} - -/**************************************** - * Routine: muxSetupLCD (ostboot) - * Description: Setup lcd muxing - *****************************************/ -void muxSetupLCD(void) -{ - /* LCD_D0 pin configuration, PIN = Y7, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D0, 0); - /* LCD_D1 pin configuration, PIN = P10 , Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D1, 0); - /* LCD_D2 pin configuration, PIN = V8, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D2, 0); - /* LCD_D3 pin configuration, PIN = Y8, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D3, 0); - /* LCD_D4 pin configuration, PIN = W8, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D4, 0); - /* LCD_D5 pin configuration, PIN = R10, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D5, 0); - /* LCD_D6 pin configuration, PIN = Y9, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D6, 0); - /* LCD_D7 pin configuration, PIN = V9, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D7, 0); - /* LCD_D8 pin configuration, PIN = W9, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D8, 0); - /* LCD_D9 pin configuration, PIN = P11, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D9, 0); - /* LCD_D10 pin configuration, PIN = V10, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D10, 0); - /* LCD_D11 pin configuration, PIN = Y10, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D11, 0); - /* LCD_D12 pin configuration, PIN = W10, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D12, 0); - /* LCD_D13 pin configuration, PIN = R11, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D13, 0); - /* LCD_D14 pin configuration, PIN = V11, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D14, 0); - /* LCD_D15 pin configuration, PIN = W11, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D15, 0); - /* LCD_D16 pin configuration, PIN = P12, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D16, 0); - /* LCD_D17 pin configuration, PIN = R12, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D17, 0); - /* LCD_PCLK pin configuration, PIN = W6, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_PCLK, 0); - /* LCD_VSYNC pin configuration, PIN = V7, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_VSYNC, 0); - /* LCD_HSYNC pin configuration, PIN = Y6, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_HSYNC, 0); - /* LCD_ACBIAS pin configuration, PIN = W7, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_ACBIAS, 0); -} - -/**************************************** - * Routine: muxSetupMMCSD (ostboot) - * Description: set up MMC muxing - *****************************************/ -void muxSetupMMCSD(void) -{ - /* SDMMC_CLKI pin configuration, PIN = H15, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_CLKI, 0); - /* SDMMC_CLKO pin configuration, PIN = G19, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_CLKO, 0); - /* SDMMC_CMD pin configuration, PIN = H18, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_CMD, 0); - /* SDMMC_DAT0 pin configuration, PIN = F20, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT0, 0); - /* SDMMC_DAT1 pin configuration, PIN = H14, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT1, 0); - /* SDMMC_DAT2 pin configuration, PIN = E19, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT2, 0); - /* SDMMC_DAT3 pin configuration, PIN = D19, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT3, 0); - /* SDMMC_DDIR0 pin configuration, PIN = F19, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT_DIR0, 0); - /* SDMMC_DDIR1 pin configuration, PIN = E20, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT_DIR1, 0); - /* SDMMC_DDIR2 pin configuration, PIN = F18, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT_DIR2, 0); - /* SDMMC_DDIR3 pin configuration, PIN = E18, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT_DIR3, 0); - /* SDMMC_CDIR pin configuration, PIN = G18, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_CMD_DIR, 0); -} - -/****************************************** - * Routine: muxSetupTouchScreen (ostboot) - * Description: Set up touch screen muxing - *******************************************/ -void muxSetupTouchScreen(void) -{ - /* SPI1_CLK pin configuration, PIN = U18, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_SPI1_CLK, 0); - /* SPI1_MOSI pin configuration, PIN = V20, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_SPI1_SIMO, 0); - /* SPI1_MISO pin configuration, PIN = T18, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_SPI1_SOMI, 0); - /* SPI1_nCS0 pin configuration, PIN = U19, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_SPI1_NCS0, 0); -#define CONTROL_PADCONF_GPIO85 CONTROL_PADCONF_SPI1_NCS1 - /* PEN_IRQ pin configuration, PIN = N15, Mode = 3, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_GPIO85, 3); -} - -/*************************************************************** - * Routine: muxSetupGPMC (ostboot) - * Description: Configures balls which cam up in protected mode - ***************************************************************/ -void muxSetupGPMC(void) -{ - /* gpmc_io_dir, MCR */ - volatile unsigned int *MCR = (unsigned int *) 0x4800008C; - *MCR = 0x19000000; - - /* NOR FLASH CS0 */ - /* signal - Gpmc_clk; pin - J4; offset - 0x0088; mode 0; Byte-3 */ - write_config_reg(CONTROL_PADCONF_GPMC_D2_BYTE3, 0); - /* MPDB(Multi Port Debug Port) CS1 */ - /* signal - gpmc_ncs1; pin - N8; offset - 0x008D; mode 0; Byte-1 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE1, 0); - /* signal - Gpmc_ncs2; pin - E2; offset - 0x008E; mode 0; Byte-2 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE2, 0); - /* signal - Gpmc_ncs3; pin - N2; offset - 0x008F; mode 0; Byte-3 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE3, 0); - /* signal - Gpmc_ncs4; pin - ??; offset - 0x0090; mode 0; Byte-4 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE4, 0); - /* signal - Gpmc_ncs5; pin - ??; offset - 0x0091; mode 0; Byte-5 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE5, 0); - /* signal - Gpmc_ncs6; pin - ??; offset - 0x0092; mode 0; Byte-6 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE6, 0); - /* signal - Gpmc_ncs7; pin - ??; offset - 0x0093; mode 0; Byte-7 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE7, 0); -} - -/**************************************************************** - * Routine: muxSetupSDRC (ostboot) - * Description: Configures balls which come up in protected mode - ****************************************************************/ -void muxSetupSDRC(void) -{ - /* It's set by IPL */ -} diff --git a/board/apollon/config.mk b/board/apollon/config.mk deleted file mode 100644 index 66005d4..0000000 --- a/board/apollon/config.mk +++ /dev/null @@ -1,25 +0,0 @@ -# -# (C) Copyright 2005-2007 -# Samsung Electronics -# -# Samsung December board with OMAP2420 (ARM1136) cpu -# see http://www.ti.com/ for more information on Texas Instruments -# -# December has 1 bank of 128MB mDDR-SDRAM on CS0 -# December has 1 bank of 00MB mDDR-SDRAM on CS1 -# Physical Address: -# 8000'0000 (bank0) -# A000/0000 (bank1) ES2 will be configurable -# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 -# (mem base + reserved) -# For use with external or internal boots. -CONFIG_SYS_TEXT_BASE = 0x83e80000 - -# Used with full SRAM boot. -# This is either with a GP system or a signed boot image. -# easiest, and safest way to go if you can. -#CONFIG_SYS_TEXT_BASE = 0x40270000 - -# Handy to get symbols to debug ROM version. -#CONFIG_SYS_TEXT_BASE = 0x0 -#CONFIG_SYS_TEXT_BASE = 0x08000000 diff --git a/board/apollon/lowlevel_init.S b/board/apollon/lowlevel_init.S deleted file mode 100644 index f066fe4..0000000 --- a/board/apollon/lowlevel_init.S +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Board specific setup info - * - * (C) Copyright 2005-2007 - * Samsung Electronics, - * Kyungmin Park <kyungmin.park@samsung.com> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <config.h> -#include <version.h> -#include <asm/arch/omap2420.h> -#include <asm/arch/mem.h> -#include <asm/arch/clocks.h> -#include "mem.h" - -#define APOLLON_CS0_BASE 0x00000000 - -#ifdef PRCM_CONFIG_I -#define SDRC_ACTIM_CTRLA_0_VAL 0x7BA35907 -#define SDRC_ACTIM_CTRLB_0_VAL 0x00000013 -#define SDRC_RFR_CTRL_0_VAL 0x00044C01 -#elif defined(PRCM_CONFIG_II) -#define SDRC_ACTIM_CTRLA_0_VAL 0x4A59B485 -#define SDRC_ACTIM_CTRLB_0_VAL 0x0000000C -#define SDRC_RFR_CTRL_0_VAL 0x00030001 -#endif - -#define SDRAM_BASE_ADDRESS 0x80008000 - -_TEXT_BASE: - .word CONFIG_SYS_TEXT_BASE /* sdram load addr from config.mk */ - -.globl lowlevel_init -lowlevel_init: - -#ifdef CONFIG_SYS_NOR_BOOT - /* Check running in SDRAM */ - mov r0, pc, lsr #28 - cmp r0, #8 - beq prcm_setup - -flash_setup: - /* In Flash */ - ldr r0, =WD2_BASE - ldr r1, =WD_UNLOCK1 - str r1, [r0, #WSPR] - - ldr r1, =WD_UNLOCK2 - str r1, [r0, #WSPR] - - /* Pin muxing for SDRC */ - mov r1, #0x00 - ldr r0, =0x480000A1 /* ball C12, mode 0 */ - strb r1, [r0] - - ldr r0, =0x48000032 /* ball D11, mode 0 */ - strb r1, [r0] - - ldr r0, =0x480000A3 /* ball B13, mode 0 */ - strb r1, [r0] - - /* SDRC setting */ - ldr r0, =OMAP2420_SDRC_BASE - ldr r1, =0x00000010 - str r1, [r0, #0x10] - - ldr r1, =0x00000100 - str r1, [r0, #0x44] - - /* SDRC CS0 configuration */ - ldr r1, =0x00d04011 - str r1, [r0, #0x80] - - ldr r1, =SDRC_ACTIM_CTRLA_0_VAL - str r1, [r0, #0x9C] - - ldr r1, =SDRC_ACTIM_CTRLB_0_VAL - str r1, [r0, #0xA0] - - ldr r1, =SDRC_RFR_CTRL_0_VAL - str r1, [r0, #0xA4] - - ldr r1, =0x00000041 - str r1, [r0, #0x70] - - /* Manual command sequence */ - ldr r1, =0x00000007 - str r1, [r0, #0xA8] - - ldr r1, =0x00000000 - str r1, [r0, #0xA8] - - ldr r1, =0x00000001 - str r1, [r0, #0xA8] - - ldr r1, =0x00000002 - str r1, [r0, #0xA8] - str r1, [r0, #0xA8] - - /* - * CS0 SDRC Mode register - * Burst length = 4 - DDR memory - * Serial mode - * CAS latency = 3 - */ - ldr r1, =0x00000032 - str r1, [r0, #0x84] - - /* Note: You MUST set EMR values */ - /* EMR1 & EMR2 */ - ldr r1, =0x00000000 - str r1, [r0, #0x88] - str r1, [r0, #0x8C] - -#ifdef OLD_SDRC_DLLA_CTRL - /* SDRC_DLLA_CTRL */ - ldr r1, =0x00007306 - str r1, [r0, #0x60] - - ldr r1, =0x00007303 - str r1, [r0, #0x60] -#else - /* SDRC_DLLA_CTRL */ - ldr r1, =0x00000506 - str r1, [r0, #0x60] - - ldr r1, =0x00000503 - str r1, [r0, #0x60] -#endif - -#ifdef __BROKEN_FEATURE__ - /* SDRC_DLLB_CTRL */ - ldr r1, =0x00000506 - str r1, [r0, #0x68] - - ldr r1, =0x00000503 - str r1, [r0, #0x68] -#endif - - /* little delay after init */ - mov r2, #0x1800 -1: - subs r2, r2, #0x1 - bne 1b - - /* Setup base address */ - ldr r0, =0x00000000 /* NOR address */ - ldr r1, =SDRAM_BASE_ADDRESS /* SDRAM address */ - ldr r2, =0x20000 /* Size: 128KB */ - -copy_loop: - ldmia r0!, {r3-r10} - stmia r1!, {r3-r10} - cmp r0, r2 - ble copy_loop - - ldr r1, =SDRAM_BASE_ADDRESS - mov lr, pc - mov pc, r1 -#endif - -prcm_setup: - ldr r0, =OMAP2420_CM_BASE - ldr r1, [r0, #0x544] /* CLKSEL2_PLL */ - bic r1, r1, #0x03 - orr r1, r1, #0x02 - str r1, [r0, #0x544] - - ldr r1, [r0, #0x500] - bic r1, r1, #0x03 - orr r1, r1, #0x01 - str r1, [r0, #0x500] - - ldr r1, [r0, #0x140] - bic r1, r1, #0x1f - orr r1, r1, #0x02 - str r1, [r0, #0x140] - -#ifdef PRCM_CONFIG_I - ldr r1, =0x000003C3 -#else - ldr r1, =0x00000343 -#endif - str r1, [r0, #0x840] - - ldr r1, =0x00000002 - str r1, [r0, #0x340] - - ldr r1, =CM_CLKSEL1_CORE -#ifdef PRCM_CONFIG_I - ldr r2, =0x08300C44 -#else - ldr r2, =0x04600C26 -#endif - str r2, [r1] - - ldr r0, =OMAP2420_CM_BASE - ldr r1, [r0, #0x084] - and r1, r1, #0x01 - cmp r1, #0x01 - bne clkvalid - - b . - -clkvalid: - mov r1, #0x01 - str r1, [r0, #0x080] - -waitvalid: - ldr r1, [r0, #0x084] - and r1, r1, #0x01 - cmp r1, #0x00 - bne waitvalid - - ldr r0, =CM_CLKSEL1_PLL -#ifdef PRCM_CONFIG_I - ldr r1, =0x01837100 -#else - ldr r1, =0x01832100 -#endif - str r1, [r0] - - ldr r0, =PRCM_CLKCFG_CTRL - mov r1, #0x01 - str r1, [r0] - mov r6, #0x50 -loop1: - subs r6, r6, #0x01 - cmp r6, #0x01 - bne loop1 - - ldr r0, =CM_CLKEN_PLL - mov r1, #0x0f - str r1, [r0] - - mov r6, #0x100 -loop2: - subs r6, r6, #0x01 - cmp r6, #0x01 - bne loop2 - - ldr r0, =0x48008200 - ldr r1, =0xbfffffff - str r1, [r0] - - ldr r0, =0x48008210 - ldr r1, =0xfffffff9 - str r1, [r0] - - ldr r0, =0x4806a004 - ldr r1, =0x00 - strb r1, [r0] - - ldr r0, =0x4806a020 - ldr r1, =0x07 - strb r1, [r0] - - ldr r0, =0x4806a00c - ldr r1, =0x83 - strb r1, [r0] - - ldr r0, =0x4806a000 - ldr r1, =0x1a - strb r1, [r0] - - ldr r0, =0x4806a004 - ldr r1, =0x00 - strb r1, [r0] - - ldr r0, =0x4806a00c - ldr r1, =0x03 - strb r1, [r0] - - ldr r0, =0x4806a010 - ldr r1, =0x03 - strb r1, [r0] - - ldr r0, =0x4806a008 - ldr r1, =0x04 - strb r1, [r0] - - ldr r0, =0x4806a020 - ldr r1, =0x00 - strb r1, [r0] - -#if 0 - ldr r0, =0x4806a000 - mov r1, #'u' - strb r1, [r0] -#endif - -#if 0 - /* LED0 OFF */ - ldr r3, =0x480000E5 - mov r4, #0x0b - strb r4, [r3] -#endif - - ldr sp, SRAM_STACK - str ip, [sp] /* stash old link register */ - mov ip, lr /* save link reg across call */ - bl s_init /* go setup pll,mux,memory */ - ldr ip, [sp] /* restore save ip */ - mov lr, ip /* restore link reg */ - - /* map interrupt controller */ - ldr r0, VAL_INTH_SETUP - mcr p15, 0, r0, c15, c2, 4 - - /* back to arch calling code */ - mov pc, lr - - /* the literal pools origin */ - .ltorg - -VAL_INTH_SETUP: - .word PERIFERAL_PORT_BASE -SRAM_STACK: - .word LOW_LEVEL_SRAM_STACK diff --git a/board/apollon/mem.c b/board/apollon/mem.c deleted file mode 100644 index 36bf6e9..0000000 --- a/board/apollon/mem.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * (C) Copyright 2005-2007 - * Samsung Electronics, - * Kyungmin Park <kyungmin.park@samsung.com> - * - * Derived from omap2420 - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/arch/omap2420.h> -#include <asm/io.h> -#include <asm/arch/bits.h> -#include <asm/arch/mux.h> -#include <asm/arch/mem.h> -#include <asm/arch/clocks.h> -#include <asm/arch/sys_proto.h> -#include <asm/arch/sys_info.h> - -#include "mem.h" - -/************************************************************ - * sdelay() - simple spin loop. Will be constant time as - * its generally used in 12MHz bypass conditions only. This - * is necessary until timers are accessible. - * - * not inline to increase chances its in cache when called - *************************************************************/ -void sdelay(unsigned long loops) -{ - __asm__("1:\n" "subs %0, %1, #1\n" - "bne 1b":"=r" (loops):"0"(loops)); -} - -/******************************************************************** - * prcm_init() - inits clocks for PRCM as defined in clocks.h - * (config II default). - * -- called from SRAM, or Flash (using temp SRAM stack). - ********************************************************************/ -void prcm_init(void) { } - -/************************************************************************** - * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow - * command line mem=xyz use all memory with out discontigious support - * compiled in. Could do it at the ATAG, but there really is two banks... - * Called as part of 2nd phase DDR init. - **************************************************************************/ -void make_cs1_contiguous(void) -{ - u32 size, a_add_low, a_add_high; - - size = get_sdr_cs_size(SDRC_CS0_OSET); - size /= SZ_32M; /* find size to offset CS1 */ - a_add_high = (size & 3) << 8; /* set up low field */ - a_add_low = (size & 0x3C) >> 2; /* set up high field */ - __raw_writel((a_add_high | a_add_low), SDRC_CS_CFG); - -} - -/******************************************************** - * mem_ok() - test used to see if timings are correct - * for a part. Helps in gussing which part - * we are currently using. - *******************************************************/ -u32 mem_ok(void) -{ - u32 val1, val2; - u32 pattern = 0x12345678; - - /* clear pos A */ - __raw_writel(0x0, OMAP2420_SDRC_CS0 + 0x400); - /* pattern to pos B */ - __raw_writel(pattern, OMAP2420_SDRC_CS0); - /* remove pattern off the bus */ - __raw_writel(0x0, OMAP2420_SDRC_CS0 + 4); - /* get pos A value */ - val1 = __raw_readl(OMAP2420_SDRC_CS0 + 0x400); - val2 = __raw_readl(OMAP2420_SDRC_CS0); /* get val2 */ - - /* see if pos A value changed */ - if ((val1 != 0) || (val2 != pattern)) - return (0); - else - return (1); -} - -/******************************************************** - * sdrc_init() - init the sdrc chip selects CS0 and CS1 - * - early init routines, called from flash or - * SRAM. - *******************************************************/ -void sdrc_init(void) -{ -#define EARLY_INIT 1 - /* only init up first bank here */ - do_sdrc_init(SDRC_CS0_OSET, EARLY_INIT); -} - -/************************************************************************* - * do_sdrc_init(): initialize the SDRAM for use. - * -called from low level code with stack only. - * -code sets up SDRAM timing and muxing for 2422 or 2420. - * -optimal settings can be placed here, or redone after i2c - * inspection of board info - * - * This is a bit ugly, but should handle all memory moduels - * used with the APOLLON. The first time though this code from s_init() - * we configure the first chip select. Later on we come back and - * will configure the 2nd chip select if it exists. - * - **************************************************************************/ -void do_sdrc_init(u32 offset, u32 early) -{ -} - -/***************************************************** - * gpmc_init(): init gpmc bus - * Init GPMC for x16, MuxMode (SDRAM in x32). - * This code can only be executed from SRAM or SDRAM. - *****************************************************/ -void gpmc_init(void) -{ - u32 mux = 0, mtype, mwidth, rev, tval; - - rev = get_cpu_rev(); - if (rev == CPU_2420_2422_ES1) - tval = 1; - else - tval = 0; /* disable bit switched meaning */ - - /* global settings */ - __raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */ - __raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ - __raw_writel(tval, GPMC_TIMEOUT_CONTROL); /* timeout disable */ -#ifdef CONFIG_SYS_NAND_BOOT - /* set nWP, disable limited addr */ - __raw_writel(0x001, GPMC_CONFIG); -#else - /* set nWP, disable limited addr */ - __raw_writel(0x111, GPMC_CONFIG); -#endif - - /* discover bus connection from sysboot */ - if (is_gpmc_muxed() == GPMC_MUXED) - mux = BIT9; - mtype = get_gpmc0_type(); - mwidth = get_gpmc0_width(); - - /* setup cs0 */ - __raw_writel(0x0, GPMC_CONFIG7_0); /* disable current map */ - sdelay(1000); - -#ifdef CONFIG_SYS_NOR_BOOT - __raw_writel(APOLLON_24XX_GPMC_CONFIG1_3, GPMC_CONFIG1_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG2_3, GPMC_CONFIG2_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG3_3, GPMC_CONFIG3_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG4_3, GPMC_CONFIG4_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG5_3, GPMC_CONFIG5_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG6_3, GPMC_CONFIG6_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG7_3, GPMC_CONFIG7_0); -#else - __raw_writel(APOLLON_24XX_GPMC_CONFIG1_0 | mux | mtype | mwidth, - GPMC_CONFIG1_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG2_0, GPMC_CONFIG2_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG3_0, GPMC_CONFIG3_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG4_0, GPMC_CONFIG4_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG5_0, GPMC_CONFIG5_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG6_0, GPMC_CONFIG6_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG7_0, GPMC_CONFIG7_0); -#endif - sdelay(2000); - - /* setup cs1 */ - __raw_writel(0, GPMC_CONFIG7_1); /* disable any mapping */ - sdelay(1000); - - __raw_writel(APOLLON_24XX_GPMC_CONFIG1_1, GPMC_CONFIG1_1); - __raw_writel(APOLLON_24XX_GPMC_CONFIG2_1, GPMC_CONFIG2_1); - __raw_writel(APOLLON_24XX_GPMC_CONFIG3_1, GPMC_CONFIG3_1); - __raw_writel(APOLLON_24XX_GPMC_CONFIG4_1, GPMC_CONFIG4_1); - __raw_writel(APOLLON_24XX_GPMC_CONFIG5_1, GPMC_CONFIG5_1); - __raw_writel(APOLLON_24XX_GPMC_CONFIG6_1, GPMC_CONFIG6_1); - __raw_writel(APOLLON_24XX_GPMC_CONFIG7_1, GPMC_CONFIG7_1); - sdelay(2000); - - /* setup cs2 */ - __raw_writel(0x0, GPMC_CONFIG7_2); /* disable current map */ - sdelay(1000); - __raw_writel(APOLLON_24XX_GPMC_CONFIG1_0 | mux | mtype | mwidth, - GPMC_CONFIG1_2); - /* It's same as cs 0 */ - __raw_writel(APOLLON_24XX_GPMC_CONFIG2_0, GPMC_CONFIG2_2); - __raw_writel(APOLLON_24XX_GPMC_CONFIG3_0, GPMC_CONFIG3_2); - __raw_writel(APOLLON_24XX_GPMC_CONFIG4_0, GPMC_CONFIG4_2); - __raw_writel(APOLLON_24XX_GPMC_CONFIG5_0, GPMC_CONFIG5_2); - __raw_writel(APOLLON_24XX_GPMC_CONFIG6_0, GPMC_CONFIG6_2); -#ifdef CONFIG_SYS_NOR_BOOT - __raw_writel(APOLLON_24XX_GPMC_CONFIG7_0, GPMC_CONFIG7_2); -#else - __raw_writel(APOLLON_24XX_GPMC_CONFIG7_2, GPMC_CONFIG7_2); -#endif - -#ifndef CONFIG_SYS_NOR_BOOT - /* setup cs3 */ - __raw_writel(0, GPMC_CONFIG7_3); /* disable any mapping */ - sdelay(1000); - - __raw_writel(APOLLON_24XX_GPMC_CONFIG1_3, GPMC_CONFIG1_3); - __raw_writel(APOLLON_24XX_GPMC_CONFIG2_3, GPMC_CONFIG2_3); - __raw_writel(APOLLON_24XX_GPMC_CONFIG3_3, GPMC_CONFIG3_3); - __raw_writel(APOLLON_24XX_GPMC_CONFIG4_3, GPMC_CONFIG4_3); - __raw_writel(APOLLON_24XX_GPMC_CONFIG5_3, GPMC_CONFIG5_3); - __raw_writel(APOLLON_24XX_GPMC_CONFIG6_3, GPMC_CONFIG6_3); - __raw_writel(APOLLON_24XX_GPMC_CONFIG7_3, GPMC_CONFIG7_3); -#endif - -#ifndef ASYNC_NOR - __raw_writew(0xaa, (APOLLON_CS3_BASE + 0xaaa)); - __raw_writew(0x55, (APOLLON_CS3_BASE + 0x554)); - __raw_writew(0xc0, (APOLLON_CS3_BASE | SYNC_NOR_VALUE)); -#endif - sdelay(2000); -} diff --git a/board/apollon/mem.h b/board/apollon/mem.h deleted file mode 100644 index 09c4ea4..0000000 --- a/board/apollon/mem.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * (C) Copyright 2005-2007 - * Samsung Electronics, - * Kyungmin Park <kyungmin.park@samsung.com> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef _APOLLON_OMAP24XX_MEM_H_ -#define _APOLLON_OMAP24XX_MEM_H_ - -/* Slower full frequency range default timings for x32 operation*/ -#define APOLLON_2420_SDRC_SHARING 0x00000100 -#define APOLLON_2420_SDRC_MDCFG_0_DDR 0x00d04011 -#define APOLLON_2420_SDRC_MR_0_DDR 0x00000032 - -/* optimized timings good for current shipping parts */ -#define APOLLON_242X_SDRC_ACTIM_CTRLA_0_100MHz 0x4A59B485 -#define APOLLON_242X_SDRC_ACTIM_CTRLB_0_100MHz 0x0000000C - -#define APOLLON_242X_SDRC_ACTIM_CTRLA_0_166MHz 0x7BA35907 -#define APOLLON_242X_SDRC_ACTIM_CTRLB_0_166MHz 0x00000013 - -#define APOLLON_242X_SDRC_RFR_CTRL_100MHz 0x00030001 -#define APOLLON_242X_SDRC_RFR_CTRL_166MHz 0x00044C01 - -#define APOLLON_242x_SDRC_DLLAB_CTRL_100MHz 0x00007306 -#define APOLLON_242x_SDRC_DLLAB_CTRL_166MHz 0x00000506 - -#ifdef PRCM_CONFIG_I -#define APOLLON_2420_SDRC_ACTIM_CTRLA_0 APOLLON_242X_SDRC_ACTIM_CTRLA_0_166MHz -#define APOLLON_2420_SDRC_ACTIM_CTRLB_0 APOLLON_242X_SDRC_ACTIM_CTRLB_0_166MHz -#define APOLLON_2420_SDRC_RFR_CTRL APOLLON_242X_SDRC_RFR_CTRL_166MHz -#define APOLLON_2420_SDRC_DLLAB_CTRL APOLLON_242x_SDRC_DLLAB_CTRL_166MHz -#elif PRCM_CONFIG_II -#define APOLLON_2420_SDRC_ACTIM_CTRLA_0 APOLLON_242X_SDRC_ACTIM_CTRLA_0_100MHz -#define APOLLON_2420_SDRC_ACTIM_CTRLB_0 APOLLON_242X_SDRC_ACTIM_CTRLB_0_100MHz -#define APOLLON_2420_SDRC_RFR_CTRL APOLLON_242X_SDRC_RFR_CTRL_100MHz -#define APOLLON_2420_SDRC_DLLAB_CTRL APOLLON_242x_SDRC_DLLAB_CTRL_100MHz -#endif - -/* GPMC settings */ -#ifdef PRCM_CONFIG_I /* L3 at 165MHz */ -/* CS0: OneNAND */ -# define APOLLON_24XX_GPMC_CONFIG1_0 0x00000001 -# define APOLLON_24XX_GPMC_CONFIG2_0 0x000c1000 -# define APOLLON_24XX_GPMC_CONFIG3_0 0x00030400 -# define APOLLON_24XX_GPMC_CONFIG4_0 0x0b841006 -# define APOLLON_24XX_GPMC_CONFIG5_0 0x020f0c11 -# define APOLLON_24XX_GPMC_CONFIG6_0 0x00000000 -# define APOLLON_24XX_GPMC_CONFIG7_0 (0x00000e40|(APOLLON_CS0_BASE >> 24)) - -/* CS1: Ethernet */ -# define APOLLON_24XX_GPMC_CONFIG1_1 0x00011203 -# define APOLLON_24XX_GPMC_CONFIG2_1 0x001F1F01 -# define APOLLON_24XX_GPMC_CONFIG3_1 0x00080803 -# define APOLLON_24XX_GPMC_CONFIG4_1 0x1C0b1C0a -# define APOLLON_24XX_GPMC_CONFIG5_1 0x041F1F1F -# define APOLLON_24XX_GPMC_CONFIG6_1 0x000004C4 -# define APOLLON_24XX_GPMC_CONFIG7_1 (0x00000F40|(APOLLON_CS1_BASE >> 24)) - -/* CS2: OneNAND */ -/* It's same as CS0 */ -# define APOLLON_24XX_GPMC_CONFIG7_2 (0x00000e40|(APOLLON_CS2_BASE >> 24)) - -/* CS3: NOR */ -#ifdef ASYNC_NOR -# define APOLLON_24XX_GPMC_CONFIG1_3 0x00021201 -# define APOLLON_24XX_GPMC_CONFIG2_3 0x00121601 -# define APOLLON_24XX_GPMC_CONFIG3_3 0x00040401 -# define APOLLON_24XX_GPMC_CONFIG4_3 0x12061605 -# define APOLLON_24XX_GPMC_CONFIG5_3 0x01151317 -#else -# define SYNC_NOR_VALUE 0x24aaa -# define APOLLON_24XX_GPMC_CONFIG1_3 0xe5011211 -# define APOLLON_24XX_GPMC_CONFIG2_3 0x00090b01 -# define APOLLON_24XX_GPMC_CONFIG3_3 0x00020201 -# define APOLLON_24XX_GPMC_CONFIG4_3 0x09030b03 -# define APOLLON_24XX_GPMC_CONFIG5_3 0x010a0a0c -#endif /* ASYNC_NOR */ -# define APOLLON_24XX_GPMC_CONFIG6_3 0x00000000 -# define APOLLON_24XX_GPMC_CONFIG7_3 (0x00000e40|(APOLLON_CS3_BASE >> 24)) -#endif /* endif PRCM_CONFIG_I */ - -#ifdef PRCM_CONFIG_II /* L3 at 100MHz */ -/* CS0: OneNAND */ -# define APOLLON_24XX_GPMC_CONFIG1_0 0x00000001 -# define APOLLON_24XX_GPMC_CONFIG2_0 0x00081080 -# define APOLLON_24XX_GPMC_CONFIG3_0 0x00030300 -# define APOLLON_24XX_GPMC_CONFIG4_0 0x08041004 -# define APOLLON_24XX_GPMC_CONFIG5_0 0x020b0910 -# define APOLLON_24XX_GPMC_CONFIG6_0 0x00000000 -# define APOLLON_24XX_GPMC_CONFIG7_0 (0x00000C40|(APOLLON_CS0_BASE >> 24)) - -/* CS1: ethernet */ -# define APOLLON_24XX_GPMC_CONFIG1_1 0x00401203 -# define APOLLON_24XX_GPMC_CONFIG2_1 0x001F1F01 -# define APOLLON_24XX_GPMC_CONFIG3_1 0x00080803 -# define APOLLON_24XX_GPMC_CONFIG4_1 0x1C091C09 -# define APOLLON_24XX_GPMC_CONFIG5_1 0x041F1F1F -# define APOLLON_24XX_GPMC_CONFIG6_1 0x000004C4 -# define APOLLON_24XX_GPMC_CONFIG7_1 (0x00000F40|(APOLLON_CS1_BASE >> 24)) - -/* CS2: OneNAND */ -/* It's same as CS0 */ -# define APOLLON_24XX_GPMC_CONFIG7_2 (0x00000e40|(APOLLON_CS2_BASE >> 24)) - -/* CS3: NOR */ -#define ASYNC_NOR -#ifdef ASYNC_NOR -# define APOLLON_24XX_GPMC_CONFIG1_3 0x00021201 -# define APOLLON_24XX_GPMC_CONFIG2_3 0x00121601 -# define APOLLON_24XX_GPMC_CONFIG3_3 0x00040401 -# define APOLLON_24XX_GPMC_CONFIG4_3 0x12061605 -# define APOLLON_24XX_GPMC_CONFIG5_3 0x01151317 -#else -# define SYNC_NOR_VALUE 0x24aaa -# define APOLLON_24XX_GPMC_CONFIG1_3 0xe1001202 -# define APOLLON_24XX_GPMC_CONFIG2_3 0x00151501 -# define APOLLON_24XX_GPMC_CONFIG3_3 0x00050501 -# define APOLLON_24XX_GPMC_CONFIG4_3 0x0e070e07 -# define APOLLON_24XX_GPMC_CONFIG5_3 0x01131F1F -#endif /* ASYNC_NOR */ -# define APOLLON_24XX_GPMC_CONFIG6_3 0x00000000 -# define APOLLON_24XX_GPMC_CONFIG7_3 (0x00000C40|(APOLLON_CS3_BASE >> 24)) -#endif /* endif PRCM_CONFIG_II */ - -#ifdef PRCM_CONFIG_III /* L3 at 133MHz */ -# ifdef CONFIG_SYS_NAND_BOOT -# define APOLLON_24XX_GPMC_CONFIG1_0 0x0 -# define APOLLON_24XX_GPMC_CONFIG2_0 0x00141400 -# define APOLLON_24XX_GPMC_CONFIG3_0 0x00141400 -# define APOLLON_24XX_GPMC_CONFIG4_0 0x0F010F01 -# define APOLLON_24XX_GPMC_CONFIG5_0 0x010C1414 -# define APOLLON_24XX_GPMC_CONFIG6_0 0x00000A80 -# else /* NOR boot */ -# define APOLLON_24XX_GPMC_CONFIG1_0 0x3 -# define APOLLON_24XX_GPMC_CONFIG2_0 0x00151501 -# define APOLLON_24XX_GPMC_CONFIG3_0 0x00060602 -# define APOLLON_24XX_GPMC_CONFIG4_0 0x10081008 -# define APOLLON_24XX_GPMC_CONFIG5_0 0x01131F1F -# define APOLLON_24XX_GPMC_CONFIG6_0 0x000004c4 -# endif /* endif CONFIG_SYS_NAND_BOOT */ -# define APOLLON_24XX_GPMC_CONFIG7_0 (0x00000C40|(APOLLON_CS0_BASE >> 24)) -# define APOLLON_24XX_GPMC_CONFIG1_1 0x00011000 -# define APOLLON_24XX_GPMC_CONFIG2_1 0x001f1f01 -# define APOLLON_24XX_GPMC_CONFIG3_1 0x00080803 -# define APOLLON_24XX_GPMC_CONFIG4_1 0x1C091C09 -# define APOLLON_24XX_GPMC_CONFIG5_1 0x041f1F1F -# define APOLLON_24XX_GPMC_CONFIG6_1 0x000004C4 -# define APOLLON_24XX_GPMC_CONFIG7_1 (0x00000F40|(APOLLON_CS1_BASE >> 24)) -#endif /* endif CONFIG_SYS_PRCM_III */ - -#endif /* endif _APOLLON_OMAP24XX_MEM_H_ */ diff --git a/board/apollon/sys_info.c b/board/apollon/sys_info.c deleted file mode 100644 index 4f950ae..0000000 --- a/board/apollon/sys_info.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * (C) Copyright 2005-2007 - * Samsung Electronics, - * Kyungmin Park <kyungmin.park@samsung.com> - * - * Derived from omap2420 - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/arch/omap2420.h> -#include <asm/io.h> -#include <asm/arch/bits.h> -#include <asm/arch/mem.h> /* get mem tables */ -#include <asm/arch/sys_proto.h> -#include <asm/arch/sys_info.h> -#include <i2c.h> - -/************************************************************************** - * get_prod_id() - get id info from chips - ***************************************************************************/ -static u32 get_prod_id(void) -{ - u32 p; - p = __raw_readl(PRODUCTION_ID); /* get production ID */ - return ((p & CPU_242X_PID_MASK) >> 16); -} - -/************************************************************************** - * get_cpu_type() - low level get cpu type - * - no C globals yet. - * - just looking to say if this is a 2422 or 2420 or ... - * - to start with we will look at switch settings.. - * - 2422 id's same as 2420 for ES1 will rely on H4 board characteristics - * (mux for 2420, non-mux for 2422). - ***************************************************************************/ -u32 get_cpu_type(void) -{ - u32 v; - - switch (get_prod_id()) { - case 1:; /* 2420 */ - case 2: - return (CPU_2420); - break; /* 2420 pop */ - case 4: - return (CPU_2422); - break; - case 8: - return (CPU_2423); - break; - default: - break; /* early 2420/2422's unmarked */ - } - - v = __raw_readl(TAP_IDCODE_REG); - v &= CPU_24XX_ID_MASK; - /* currently 2420 and 2422 have same id */ - if (v == CPU_2420_CHIPID) { - if (is_gpmc_muxed() == GPMC_MUXED) /* if mux'ed */ - return (CPU_2420); - else - return (CPU_2422); - } else - return (CPU_2420); /* don't know, say 2420 */ -} - -/****************************************** - * get_cpu_rev(void) - extract version info - ******************************************/ -u32 get_cpu_rev(void) -{ - u32 v; - v = __raw_readl(TAP_IDCODE_REG); - v = v >> 28; - return (v + 1); /* currently 2422 and 2420 match up */ -} - -/**************************************************** - * is_mem_sdr() - return 1 if mem type in use is SDR - ****************************************************/ -u32 is_mem_sdr(void) -{ - volatile u32 *burst = (volatile u32 *)(SDRC_MR_0 + SDRC_CS0_OSET); - if (*burst == H4_2420_SDRC_MR_0_SDR) - return (1); - return (0); -} - -/*********************************************************** - * get_mem_type() - identify type of mDDR part used. - * 2422 uses stacked DDR, 2 parts CS0/CS1. - * 2420 may have 1 or 2, no good way to know...only init 1... - * when eeprom data is up we can select 1 more. - *************************************************************/ -u32 get_mem_type(void) -{ - u32 cpu, sdr = is_mem_sdr(); - - cpu = get_cpu_type(); - if (cpu == CPU_2422 || cpu == CPU_2423) - return (DDR_STACKED); - - if (get_prod_id() == 0x2) - return (XDR_POP); - - if (get_board_type() == BOARD_H4_MENELAUS) - if (sdr) - return (SDR_DISCRETE); - else - return (DDR_COMBO); - else if (sdr) /* SDP + SDR kit */ - return (SDR_DISCRETE); - else - return (DDR_DISCRETE); /* origional SDP */ -} - -/*********************************************************************** - * get_cs0_size() - get size of chip select 0/1 - ************************************************************************/ -u32 get_sdr_cs_size(u32 offset) -{ - u32 size; - size = __raw_readl(SDRC_MCFG_0 + offset) >> 8; /* get ram size field */ - size &= 0x2FF; /* remove unwanted bits */ - size *= SZ_2M; /* find size in MB */ - return (size); -} - -/*********************************************************************** - * get_board_type() - get board type based on current production stats. - * --- NOTE: 2 I2C EEPROMs will someday be populated with proper info. - * when they are available we can get info from there. This should - * be correct of all known boards up until today. - ************************************************************************/ -u32 get_board_type(void) -{ - return (BOARD_H4_SDP); -} - -/****************************************************************** - * get_sysboot_value() - get init word settings (dip switch on h4) - ******************************************************************/ -inline u32 get_sysboot_value(void) -{ - return (0x00000FFF & __raw_readl(CONTROL_STATUS)); -} - -/*************************************************************************** - * get_gpmc0_base() - Return current address hardware will be - * fetching from. The below effectively gives what is correct, its a bit - * mis-leading compared to the TRM. For the most general case the mask - * needs to be also taken into account this does work in practice. - * - for u-boot we currently map: - * -- 0 to nothing, - * -- 4 to flash - * -- 8 to enent - * -- c to wifi - ****************************************************************************/ -u32 get_gpmc0_base(void) -{ - u32 b; - - b = __raw_readl(GPMC_CONFIG7_0); - b &= 0x1F; /* keep base [5:0] */ - b = b << 24; /* ret 0x0b000000 */ - return (b); -} - -/***************************************************************** - * is_gpmc_muxed() - tells if address/data lines are multiplexed - *****************************************************************/ -u32 is_gpmc_muxed(void) -{ - u32 mux; - mux = get_sysboot_value(); - if ((mux & (BIT0 | BIT1 | BIT2 | BIT3)) == (BIT0 | BIT2 | BIT3)) - return (GPMC_MUXED); /* NAND Boot mode */ - if (mux & BIT1) /* if mux'ed */ - return (GPMC_MUXED); - else - return (GPMC_NONMUXED); -} - -/************************************************************************ - * get_gpmc0_type() - read sysboot lines to see type of memory attached - ************************************************************************/ -u32 get_gpmc0_type(void) -{ - u32 type; - type = get_sysboot_value(); - if ((type & (BIT3 | BIT2)) == (BIT3 | BIT2)) - return (TYPE_NAND); - else - return (TYPE_NOR); -} - -/******************************************************************* - * get_gpmc0_width() - See if bus is in x8 or x16 (mainly for nand) - *******************************************************************/ -u32 get_gpmc0_width(void) -{ - u32 width; - width = get_sysboot_value(); - if ((width & 0xF) == (BIT3 | BIT2)) - return (WIDTH_8BIT); - else - return (WIDTH_16BIT); -} - -/********************************************************************* - * wait_on_value() - common routine to allow waiting for changes in - * volatile regs. - *********************************************************************/ -u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) -{ - u32 i = 0, val; - do { - ++i; - val = __raw_readl(read_addr) & read_bit_mask; - if (val == match_value) - return (1); - if (i == bound) - return (0); - } while (1); -} - -/********************************************************************* - * display_board_info() - print banner with board info. - *********************************************************************/ -void display_board_info(u32 btype) -{ - char cpu_2420[] = "2420"; /* cpu type */ - char cpu_2422[] = "2422"; - char cpu_2423[] = "2423"; - char mem_sdr[] = "mSDR"; /* memory type */ - char mem_ddr[] = "mDDR"; - char t_tst[] = "TST"; /* security level */ - char t_emu[] = "EMU"; - char t_hs[] = "HS"; - char t_gp[] = "GP"; - char unk[] = "?"; - - char *cpu_s, *mem_s, *sec_s; - u32 cpu, rev, sec; - - rev = get_cpu_rev(); - cpu = get_cpu_type(); - sec = get_device_type(); - - if (is_mem_sdr()) - mem_s = mem_sdr; - else - mem_s = mem_ddr; - - if (cpu == CPU_2423) - cpu_s = cpu_2423; - else if (cpu == CPU_2422) - cpu_s = cpu_2422; - else - cpu_s = cpu_2420; - - switch (sec) { - case TST_DEVICE: - sec_s = t_tst; - break; - case EMU_DEVICE: - sec_s = t_emu; - break; - case HS_DEVICE: - sec_s = t_hs; - break; - case GP_DEVICE: - sec_s = t_gp; - break; - default: - sec_s = unk; - } - - printf("OMAP%s-%s revision %d\n", cpu_s, sec_s, rev - 1); - printf("Samsung Apollon SDP Base Board + %s \n", mem_s); -} - -/************************************************************************* - * get_board_rev() - setup to pass kernel board revision information - * 0 = 242x IP platform (first 2xx boards) - * 1 = 242x Menelaus platfrom. - *************************************************************************/ -u32 get_board_rev(void) -{ - u32 rev = 0; - u32 btype = get_board_type(); - - if (btype == BOARD_H4_MENELAUS) - rev = 1; - return (rev); -} - -/******************************************************** - * get_base(); get upper addr of current execution - *******************************************************/ -u32 get_base(void) -{ - u32 val; - __asm__ __volatile__("mov %0, pc \n":"=r"(val)::"memory"); - val &= 0xF0000000; - val >>= 28; - return (val); -} - -/******************************************************** - * get_base2(); get 2upper addr of current execution - *******************************************************/ -u32 get_base2(void) -{ - u32 val; - __asm__ __volatile__("mov %0, pc \n":"=r"(val)::"memory"); - val &= 0xFF000000; - val >>= 24; - return (val); -} - -/******************************************************** - * running_in_flash() - tell if currently running in - * flash. - *******************************************************/ -u32 running_in_flash(void) -{ - if (get_base() < 4) - return (1); /* in flash */ - return (0); /* running in SRAM or SDRAM */ -} - -/******************************************************** - * running_in_sram() - tell if currently running in - * sram. - *******************************************************/ -u32 running_in_sram(void) -{ - if (get_base() == 4) - return (1); /* in SRAM */ - return (0); /* running in FLASH or SDRAM */ -} - -/******************************************************** - * running_in_sdram() - tell if currently running in - * flash. - *******************************************************/ -u32 running_in_sdram(void) -{ - if (get_base() > 4) - return (1); /* in sdram */ - return (0); /* running in SRAM or FLASH */ -} - -/************************************************************* - * running_from_internal_boot() - am I a signed NOR image. - *************************************************************/ -u32 running_from_internal_boot(void) -{ - u32 v, base; - - v = get_sysboot_value() & BIT3; - base = get_base2(); - /* if running at mask rom flash address and - * sysboot3 says this was an internal boot - */ - if ((base == 0x08) && v) - return (1); - else - return (0); -} - -/************************************************************* - * get_device_type(): tell if GP/HS/EMU/TST - *************************************************************/ -u32 get_device_type(void) -{ - int mode; - mode = __raw_readl(CONTROL_STATUS) & (BIT10 | BIT9 | BIT8); - return (mode >>= 8); -} diff --git a/board/atmel/atngw100mkii/Makefile b/board/atmel/atngw100mkii/Makefile new file mode 100644 index 0000000..7fbd20d --- /dev/null +++ b/board/atmel/atngw100mkii/Makefile @@ -0,0 +1,40 @@ +# +# Copyright (C) 2005-2006 Atmel Corporation +# +# See file CREDITS for list of people who contributed to this project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA + +include $(TOPDIR)/config.mk + +LIB := $(obj)lib$(BOARD).o + +COBJS := $(BOARD).o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/atmel/atngw100mkii/atngw100mkii.c b/board/atmel/atngw100mkii/atngw100mkii.c new file mode 100644 index 0000000..f4023b3 --- /dev/null +++ b/board/atmel/atngw100mkii/atngw100mkii.c @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2010 Atmel Corporation + * + * Copyright (C) 2012 Andreas Bießmann <andreas.devel@googlemail.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> + +#include <spi.h> +#include <netdev.h> + +#include <asm/io.h> +#include <asm/sdram.h> +#include <asm/arch/clk.h> +#include <asm/arch/gpio.h> +#include <asm/arch/hmatrix.h> +#include <asm/arch/mmu.h> +#include <asm/arch/portmux.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { + { + /* Atmel AT49BV640D 8 MiB x16 NOR flash on NCS0 */ + .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_NONE, + }, { + /* Micron MT29F2G16AAD 256 MiB x16 NAND flash on NCS3 */ + .virt_pgno = EBI_SRAM_CS3_BASE >> PAGE_SHIFT, + .nr_pages = EBI_SRAM_CS3_SIZE >> PAGE_SHIFT, + .phys = (EBI_SRAM_CS3_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_NONE, + }, { + /* 2x16-bit ISSI IS42S16320B 64 MiB SDRAM (128 MiB total) */ + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_WRBACK, + }, +}; + +static const struct sdram_config sdram_config = { + .data_bits = SDRAM_DATA_32BIT, + .row_bits = 13, + .col_bits = 10, + .bank_bits = 2, + .cas = 3, + .twr = 2, + .trc = 7, + .trp = 2, + .trcd = 2, + .tras = 5, + .txsr = 6, + /* 7.81 us */ + .refresh_period = (781 * (SDRAMC_BUS_HZ / 1000)) / 100000, +}; + +int board_early_init_f(void) +{ + /* Enable SDRAM in the EBI mux */ + hmatrix_slave_write(EBI, SFR, HMATRIX_BIT(EBI_SDRAM_ENABLE) + | HMATRIX_BIT(EBI_NAND_ENABLE)); + + portmux_enable_ebi(32, 23, PORTMUX_EBI_NAND, + PORTMUX_DRIVE_HIGH); + portmux_select_gpio(PORTMUX_PORT_E, 1 << 23, + PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH + | PORTMUX_DRIVE_MIN); + portmux_enable_usart1(PORTMUX_DRIVE_MIN); + +#if defined(CONFIG_MACB) + portmux_enable_macb0(PORTMUX_MACB_MII, PORTMUX_DRIVE_HIGH); + portmux_enable_macb1(PORTMUX_MACB_MII, PORTMUX_DRIVE_HIGH); +#endif +#if defined(CONFIG_MMC) + portmux_enable_mmci(0, PORTMUX_MMCI_4BIT, PORTMUX_DRIVE_LOW); +#endif +#if defined(CONFIG_ATMEL_SPI) + portmux_enable_spi0(1 << 0, PORTMUX_DRIVE_LOW); +#endif + + return 0; +} + +phys_size_t initdram(int board_type) +{ + unsigned long expected_size; + unsigned long actual_size; + void *sdram_base; + + sdram_base = uncached(EBI_SDRAM_BASE); + + expected_size = sdram_init(sdram_base, &sdram_config); + actual_size = get_ram_size(sdram_base, expected_size); + + if (expected_size != actual_size) + printf("Warning: Only %lu of %lu MiB SDRAM is working\n", + actual_size >> 20, expected_size >> 20); + + return actual_size; +} + +int board_early_init_r(void) +{ + gd->bd->bi_phy_id[0] = 0x01; + gd->bd->bi_phy_id[1] = 0x03; + return 0; +} + +#ifdef CONFIG_CMD_NET +int board_eth_init(bd_t *bi) +{ + macb_eth_initialize(0, (void *)ATMEL_BASE_MACB0, bi->bi_phy_id[0]); + macb_eth_initialize(1, (void *)ATMEL_BASE_MACB1, bi->bi_phy_id[1]); + return 0; +} +#endif + +/* SPI chip select control */ +#ifdef CONFIG_ATMEL_SPI +#define ATNGW100_DATAFLASH_CS_PIN GPIO_PIN_PA(3) + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return bus == 0 && cs == 0; +} + +void spi_cs_activate(struct spi_slave *slave) +{ + gpio_set_value(ATNGW100_DATAFLASH_CS_PIN, 0); +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + gpio_set_value(ATNGW100_DATAFLASH_CS_PIN, 1); +} +#endif /* CONFIG_ATMEL_SPI */ diff --git a/board/davinci/da8xxevm/README.da850 b/board/davinci/da8xxevm/README.da850 new file mode 100644 index 0000000..313a1ef --- /dev/null +++ b/board/davinci/da8xxevm/README.da850 @@ -0,0 +1,68 @@ +Summary +======= +The README is for the boot procedure used for various DA850 (or compatible +parts such as the AM1808) based boards. + +In the context of U-Boot, the board is booted in three stages. The initial +bootloader which executes upon reset is the ROM Boot Loader (RBL) and sits +in the internal ROM. The RBL initializes the internal memory and then +depending on the exact board and pin configurations will initialize another +controller (such as SPI or NAND) to continue the boot process by loading +the secondary program loader (SPL). The SPL will initialize the system +further (some clocks, SDRAM) and then load the full u-boot from a +predefined location in persistent storage to DDR and jumps to the u-boot +entry point. + +AIS is an image format defined by TI for the images that are to be loaded +to memory by the RBL. The image is divided into a series of sections and +the image's entry point is specified. Each section comes with meta data +like the target address the section is to be copied to and the size of the +section, which is used by the RBL to load the image. At the end of the +image the RBL jumps to the image entry point. The AIS format allows for +other things such as programming the clocks and SDRAM if the header is +programmed for it. We do not take advantage of this and instead use SPL as +it allows for additional flexibility (run-time detect of board revision, +loading the next image from a different media, etc). + + +Compilation +=========== +The exact build target you need will depend on the board you have. For +Logic PD boards, or other boards which store the ethernet MAC address at +the end of SPI flash, run 'make da850evm'. For boards which store the +ethernet MAC address in the i2c EEPROM located at 0x50, run +'make da850_am18xxevm'. Once this build completes you will have a +u-boot.ais file that needs to be written to the correct persistent +storage. + + +Flashing the images to SPI +========================== +The AIS image can be written to SPI flash using the following commands. +Assuming that the network is configured and enabled and the u-boot.ais file +is tftp'able. + +U-Boot > sf probe 0 +U-Boot > sf erase 0 +320000 +U-Boot > tftp u-boot.ais +U-Boot > sf write c0700000 0 $filesize + + +Recovery +======== + +In the case of a "bricked" board, you need to use the TI tools found +here[1] to write the u-boot.ais file. An example of recovering to the SPI +flash of an AM1808 would be: + +$ mono sfh_OMAP-L138.exe -targetType AM1808 -p /dev/ttyUSB0 \ + -flash_noubl /path/to/u-boot.ais + +For other target types and flash locations: + +$ mono sfh_OMAP-L138.exe -h + +Links +===== +[1] + http://processors.wiki.ti.com/index.php/Serial_Boot_and_Flash_Loading_Utility_for_OMAP-L138 diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 0b40dc7..54cb098 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -51,14 +51,12 @@ COBJS-$(CONFIG_MPC8572DS) += ics307_clk.o COBJS-$(CONFIG_P1022DS) += ics307_clk.o COBJS-$(CONFIG_P2020DS) += ics307_clk.o COBJS-$(CONFIG_P3041DS) += ics307_clk.o -COBJS-$(CONFIG_P3060QDS) += ics307_clk.o COBJS-$(CONFIG_P4080DS) += ics307_clk.o COBJS-$(CONFIG_P5020DS) += ics307_clk.o # deal with common files for P-series corenet based devices SUBLIB-$(CONFIG_P2041RDB) += p_corenet/libp_corenet.o SUBLIB-$(CONFIG_P3041DS) += p_corenet/libp_corenet.o -SUBLIB-$(CONFIG_P3060QDS) += p_corenet/libp_corenet.o SUBLIB-$(CONFIG_P4080DS) += p_corenet/libp_corenet.o SUBLIB-$(CONFIG_P5020DS) += p_corenet/libp_corenet.o diff --git a/board/freescale/common/fman.c b/board/freescale/common/fman.c index 6ddf816..3ef4936 100644 --- a/board/freescale/common/fman.c +++ b/board/freescale/common/fman.c @@ -25,6 +25,9 @@ #include <libfdt_env.h> #include <fdt_support.h> +#include <fm_eth.h> +#include <asm/fsl_serdes.h> + /* * Given the following ... * @@ -67,3 +70,31 @@ int fdt_set_phy_handle(void *fdt, char *compat, phys_addr_t addr, return fdt_setprop(fdt, offset, "phy-handle", &ph, sizeof(ph)); } + +/* + * Return the SerDes device enum for a given Fman port + * + * This function just maps the fm_port namespace to the srds_prtcl namespace. + */ +enum srds_prtcl serdes_device_from_fm_port(enum fm_port port) +{ + static const enum srds_prtcl srds_table[] = { + [FM1_DTSEC1] = SGMII_FM1_DTSEC1, + [FM1_DTSEC2] = SGMII_FM1_DTSEC2, + [FM1_DTSEC3] = SGMII_FM1_DTSEC3, + [FM1_DTSEC4] = SGMII_FM1_DTSEC4, + [FM1_DTSEC5] = SGMII_FM1_DTSEC5, + [FM1_10GEC1] = XAUI_FM1, + [FM2_DTSEC1] = SGMII_FM2_DTSEC1, + [FM2_DTSEC2] = SGMII_FM2_DTSEC2, + [FM2_DTSEC3] = SGMII_FM2_DTSEC3, + [FM2_DTSEC4] = SGMII_FM2_DTSEC4, + [FM2_DTSEC5] = SGMII_FM2_DTSEC5, + [FM2_10GEC1] = XAUI_FM2, + }; + + if ((port < FM1_DTSEC1) || (port > FM2_10GEC1)) + return NONE; + else + return srds_table[port]; +} diff --git a/board/freescale/common/fman.h b/board/freescale/common/fman.h index d39ef08..734b1da 100644 --- a/board/freescale/common/fman.h +++ b/board/freescale/common/fman.h @@ -23,4 +23,6 @@ int fdt_set_phy_handle(void *fdt, char *compat, phys_addr_t addr, const char *alias); +enum srds_prtcl serdes_device_from_fm_port(enum fm_port port); + #endif diff --git a/board/freescale/common/p_corenet/law.c b/board/freescale/common/p_corenet/law.c index c4566dd..09ef561 100644 --- a/board/freescale/common/p_corenet/law.c +++ b/board/freescale/common/p_corenet/law.c @@ -48,19 +48,6 @@ struct law_entry law_table[] = { #ifdef CONFIG_SYS_NAND_BASE_PHYS SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC), #endif -#ifdef CONFIG_SRIOBOOT_SLAVE -#if defined(CONFIG_SRIOBOOT_SLAVE_PORT0) - SET_LAW(CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS, - LAW_SIZE_1M, LAW_TRGT_IF_RIO_1), - SET_LAW(CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS, - LAW_SIZE_1M, LAW_TRGT_IF_RIO_1), -#elif defined(CONFIG_SRIOBOOT_SLAVE_PORT1) - SET_LAW(CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS, - LAW_SIZE_1M, LAW_TRGT_IF_RIO_2), - SET_LAW(CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS, - LAW_SIZE_1M, LAW_TRGT_IF_RIO_2), -#endif -#endif }; int num_law_entries = ARRAY_SIZE(law_table); diff --git a/board/freescale/common/p_corenet/tlb.c b/board/freescale/common/p_corenet/tlb.c index da21627..e5cf208 100644 --- a/board/freescale/common/p_corenet/tlb.c +++ b/board/freescale/common/p_corenet/tlb.c @@ -66,13 +66,13 @@ struct fsl_e_tlb_entry tlb_table[] = { SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L3_ADDR, CONFIG_SYS_INIT_L3_ADDR, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 0, BOOKE_PAGESZ_1M, 1), -#elif defined(CONFIG_SRIOBOOT_SLAVE) +#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) /* - * SRIOBOOT-SLAVE. When slave boot, the address of the + * SRIO_PCIE_BOOT-SLAVE. When slave boot, the address of the * space is at 0xfff00000, it covered the 0xfffff000. */ - SET_TLB_ENTRY(1, CONFIG_SYS_SRIOBOOT_SLAVE_ADDR, - CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS, + SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR, + CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G, 0, 0, BOOKE_PAGESZ_1M, 1), #else @@ -147,13 +147,13 @@ struct fsl_e_tlb_entry tlb_table[] = { MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 16, BOOKE_PAGESZ_1M, 1), #endif -#ifdef CONFIG_SRIOBOOT_SLAVE +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE /* - * SRIOBOOT-SLAVE. 1M space from 0xffe00000 for fetching ucode - * and ENV from master + * SRIO_PCIE_BOOT-SLAVE. 1M space from 0xffe00000 for + * fetching ucode and ENV from master */ - SET_TLB_ENTRY(1, CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR, - CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS, + SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR, + CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_G, 0, 17, BOOKE_PAGESZ_1M, 1), #endif diff --git a/board/freescale/corenet_ds/eth_p4080.c b/board/freescale/corenet_ds/eth_p4080.c index b87b092..2c69c51 100644 --- a/board/freescale/corenet_ds/eth_p4080.c +++ b/board/freescale/corenet_ds/eth_p4080.c @@ -68,6 +68,15 @@ static char *mdio_names[16] = { NULL, NULL, NULL, }; +/* + * Mapping of all 18 SERDES lanes to board slots. A value of '0' here means + * that the mapping must be determined dynamically, or that the lane maps to + * something other than a board slot. + */ +static u8 lane_to_slot[] = { + 1, 1, 2, 2, 3, 3, 3, 3, 6, 6, 4, 4, 4, 4, 5, 5, 5, 5 +}; + static char *p4080ds_mdio_name_for_muxval(u32 muxval) { return mdio_names[(muxval & EMI_MASK) >> 28]; @@ -290,15 +299,6 @@ void fdt_fixup_board_enet(void *fdt) } } -enum board_slots { - SLOT1 = 1, - SLOT2, - SLOT3, - SLOT4, - SLOT5, - SLOT6, -}; - int board_eth_init(bd_t *bis) { #ifdef CONFIG_FMAN_ENET @@ -307,27 +307,6 @@ int board_eth_init(bd_t *bis) struct fsl_pq_mdio_info dtsec_mdio_info; struct tgec_mdio_info tgec_mdio_info; - u8 lane_to_slot[] = { - SLOT1, /* 0 - Bank 1:A */ - SLOT1, /* 1 - Bank 1:B */ - SLOT2, /* 2 - Bank 1:C */ - SLOT2, /* 3 - Bank 1:D */ - SLOT3, /* 4 - Bank 1:E */ - SLOT3, /* 5 - Bank 1:F */ - SLOT3, /* 6 - Bank 1:G */ - SLOT3, /* 7 - Bank 1:H */ - SLOT6, /* 8 - Bank 1:I */ - SLOT6, /* 9 - Bank 1:J */ - SLOT4, /* 10 - Bank 2:A */ - SLOT4, /* 11 - Bank 2:B */ - SLOT4, /* 12 - Bank 2:C */ - SLOT4, /* 13 - Bank 2:D */ - SLOT5, /* 14 - Bank 3:A */ - SLOT5, /* 15 - Bank 3:B */ - SLOT5, /* 16 - Bank 3:C */ - SLOT5, /* 17 - Bank 3:D */ - }; - /* Initialize the mdio_mux array so we can recognize empty elements */ for (i = 0; i < NUM_FM_PORTS; i++) mdio_mux[i] = EMI_NONE; @@ -380,17 +359,17 @@ int board_eth_init(bd_t *bis) break; slot = lane_to_slot[lane]; switch (slot) { - case SLOT3: + case 3: mdio_mux[i] = EMI1_SLOT3; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; - case SLOT4: + case 4: mdio_mux[i] = EMI1_SLOT4; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; - case SLOT5: + case 5: mdio_mux[i] = EMI1_SLOT5; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); @@ -417,12 +396,12 @@ int board_eth_init(bd_t *bis) break; slot = lane_to_slot[lane]; switch (slot) { - case SLOT4: + case 4: mdio_mux[i] = EMI2_SLOT4; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; - case SLOT5: + case 5: mdio_mux[i] = EMI2_SLOT5; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); @@ -444,17 +423,17 @@ int board_eth_init(bd_t *bis) break; slot = lane_to_slot[lane]; switch (slot) { - case SLOT3: + case 3: mdio_mux[i] = EMI1_SLOT3; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; - case SLOT4: + case 4: mdio_mux[i] = EMI1_SLOT4; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; - case SLOT5: + case 5: mdio_mux[i] = EMI1_SLOT5; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); @@ -481,12 +460,12 @@ int board_eth_init(bd_t *bis) break; slot = lane_to_slot[lane]; switch (slot) { - case SLOT4: + case 4: mdio_mux[i] = EMI2_SLOT4; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; - case SLOT5: + case 5: mdio_mux[i] = EMI2_SLOT5; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); diff --git a/board/freescale/corenet_ds/pbi.cfg b/board/freescale/corenet_ds/pbi.cfg new file mode 100644 index 0000000..50806ca --- /dev/null +++ b/board/freescale/corenet_ds/pbi.cfg @@ -0,0 +1,51 @@ +# +# Copyright 2012 Freescale Semiconductor, Inc. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA +# +# Refer docs/README.pblimage for more details about how-to configure +# and create PBL boot image +# + +#PBI commands +#Initialize CPC1 as 1MB SRAM +09010000 00200400 +09138000 00000000 +091380c0 00000100 +09010100 00000000 +09010104 fff0000b +09010f00 08000000 +09010000 80000000 +#Configure LAW for CPC1 +09000d00 00000000 +09000d04 fff00000 +09000d08 81000013 +09000010 00000000 +09000014 ff000000 +09000018 81000000 +#Initialize eSPI controller, default configuration is slow for eSPI to +#load data, this configuration comes from u-boot eSPI driver. +09110000 80000403 +09110020 2d170008 +09110024 00100008 +09110028 00100008 +0911002c 00100008 +#Flush PBL data +09138000 00000000 +091380c0 00000000 diff --git a/board/freescale/corenet_ds/rcw_p3041ds.cfg b/board/freescale/corenet_ds/rcw_p3041ds.cfg new file mode 100644 index 0000000..8813156 --- /dev/null +++ b/board/freescale/corenet_ds/rcw_p3041ds.cfg @@ -0,0 +1,11 @@ +# +# Default RCW for P3041DS. +# + +#PBL preamble and RCW header +aa55aa55 010e0100 +#64 bytes RCW data +12600000 00000000 241C0000 00000000 +D8984A01 03002000 58000000 41000000 +00000000 00000000 00000000 10070000 +00000000 00000000 00000000 00000000 diff --git a/board/freescale/corenet_ds/rcw_p4080ds.cfg b/board/freescale/corenet_ds/rcw_p4080ds.cfg new file mode 100644 index 0000000..6a26339 --- /dev/null +++ b/board/freescale/corenet_ds/rcw_p4080ds.cfg @@ -0,0 +1,11 @@ +# +# Default RCW for P4080DS. +# + +#PBL preamble and RCW header +aa55aa55 010e0100 +#64 bytes RCW data +105a0000 00000000 1e1e181e 0000cccc +58400000 3c3c2000 58000000 e1000000 +00000000 00000000 00000000 008b6000 +00000000 00000000 00000000 00000000 diff --git a/board/freescale/corenet_ds/rcw_p5020ds.cfg b/board/freescale/corenet_ds/rcw_p5020ds.cfg new file mode 100644 index 0000000..b09e409 --- /dev/null +++ b/board/freescale/corenet_ds/rcw_p5020ds.cfg @@ -0,0 +1,11 @@ +# +# Default RCW for P5020DS. +# + +#PBL preamble and RCW header +aa55aa55 010e0100 +#64 bytes RCW data +0C540000 00000000 1E120000 00000000 +D8984A01 03002000 58000000 41000000 +00000000 00000000 00000000 10070000 +00000000 00000000 00000000 00000000 diff --git a/board/freescale/m5208evbe/m5208evbe.c b/board/freescale/m5208evbe/m5208evbe.c index 5f99e2f..355cfed 100644 --- a/board/freescale/m5208evbe/m5208evbe.c +++ b/board/freescale/m5208evbe/m5208evbe.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2008, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include <config.h> #include <common.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -39,7 +40,7 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); u32 dramsize, i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; @@ -50,34 +51,35 @@ phys_size_t initdram(int board_type) } i--; - sdram->cs0 = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->cs0, CONFIG_SYS_SDRAM_BASE | i); #ifdef CONFIG_SYS_SDRAM_BASE1 - sdram->cs1 = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->cs1, CONFIG_SYS_SDRAM_BASE | i); #endif - sdram->cfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->cfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->cfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->cfg2, CONFIG_SYS_SDRAM_CFG2); udelay(500); /* Issue PALL */ - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); asm("nop"); /* Perform two refresh cycles */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); asm("nop"); /* Issue LEMR */ - sdram->mode = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE); asm("nop"); - sdram->mode = CONFIG_SYS_SDRAM_EMOD; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_EMOD); asm("nop"); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); asm("nop"); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00; + out_be32(&sdram->ctrl, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00); asm("nop"); udelay(100); diff --git a/board/freescale/m52277evb/m52277evb.c b/board/freescale/m52277evb/m52277evb.c index 9109edb..a9bec58 100644 --- a/board/freescale/m52277evb/m52277evb.c +++ b/board/freescale/m52277evb/m52277evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -26,6 +26,7 @@ #include <common.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -47,8 +48,8 @@ phys_size_t initdram(int board_type) */ dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; #else - volatile sdramc_t *sdram = (volatile sdramc_t *)(MMAP_SDRAM); - volatile gpio_t *gpio = (volatile gpio_t *)(MMAP_GPIO); + sdramc_t *sdram = (sdramc_t *)(MMAP_SDRAM); + gpio_t *gpio = (gpio_t *)(MMAP_GPIO); u32 i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; @@ -59,36 +60,37 @@ phys_size_t initdram(int board_type) } i--; - gpio->mscr_sdram = CONFIG_SYS_SDRAM_DRV_STRENGTH; + out_8(&gpio->mscr_sdram, CONFIG_SYS_SDRAM_DRV_STRENGTH); - sdram->sdcs0 = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->sdcs0, CONFIG_SYS_SDRAM_BASE | i); - sdram->sdcfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->sdcfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->sdcfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->sdcfg2, CONFIG_SYS_SDRAM_CFG2); /* Issue PALL */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 2); __asm__("nop"); /* Issue LEMR */ - sdram->sdmr = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_MODE); __asm__("nop"); - sdram->sdmr = CONFIG_SYS_SDRAM_EMOD; + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_EMOD); __asm__("nop"); udelay(1000); /* Issue PALL */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 2); __asm__("nop"); /* Perform two refresh cycles */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 4); __asm__("nop"); - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 4); __asm__("nop"); - sdram->sdcr = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000C00; + out_be32(&sdram->sdcr, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00); udelay(100); #endif diff --git a/board/freescale/m5235evb/m5235evb.c b/board/freescale/m5235evb/m5235evb.c index b9e6126..e9a568e 100644 --- a/board/freescale/m5235evb/m5235evb.c +++ b/board/freescale/m5235evb/m5235evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include <config.h> #include <common.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -39,8 +40,8 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); - volatile gpio_t *gpio = (volatile gpio_t *)(MMAP_GPIO); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); + gpio_t *gpio = (gpio_t *)(MMAP_GPIO); u32 dramsize, i, dramclk; /* @@ -48,14 +49,15 @@ phys_size_t initdram(int board_type) * the port-size of SDRAM. In this case it is necessary to enable * Data[15:0] on Port Address/Data. */ - gpio->par_ad = - GPIO_PAR_AD_ADDR23 | GPIO_PAR_AD_ADDR22 | GPIO_PAR_AD_ADDR21 | - GPIO_PAR_AD_DATAL; + out_8(&gpio->par_ad, + GPIO_PAR_AD_ADDR23 | GPIO_PAR_AD_ADDR22 | GPIO_PAR_AD_ADDR21 | + GPIO_PAR_AD_DATAL); /* Initialize PAR to enable SDRAM signals */ - gpio->par_sdram = - GPIO_PAR_SDRAM_SDWE | GPIO_PAR_SDRAM_SCAS | GPIO_PAR_SDRAM_SRAS | - GPIO_PAR_SDRAM_SCKE | GPIO_PAR_SDRAM_SDCS(3); + out_8(&gpio->par_sdram, + GPIO_PAR_SDRAM_SDWE | GPIO_PAR_SDRAM_SCAS | + GPIO_PAR_SDRAM_SRAS | GPIO_PAR_SDRAM_SCKE | + GPIO_PAR_SDRAM_SDCS(3)); dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; for (i = 0x13; i < 0x20; i++) { @@ -64,25 +66,28 @@ phys_size_t initdram(int board_type) } i--; - if (!(sdram->dacr0 & SDRAMC_DARCn_RE)) { + if (!(in_be32(&sdram->dacr0) & SDRAMC_DARCn_RE)) { dramclk = gd->bus_clk / (CONFIG_SYS_HZ * CONFIG_SYS_HZ); /* Initialize DRAM Control Register: DCR */ - sdram->dcr = SDRAMC_DCR_RTIM_9CLKS | - SDRAMC_DCR_RTIM_6CLKS | SDRAMC_DCR_RC((15 * dramclk) >> 4); + out_be16(&sdram->dcr, SDRAMC_DCR_RTIM_9CLKS | + SDRAMC_DCR_RTIM_6CLKS | + SDRAMC_DCR_RC((15 * dramclk) >> 4)); /* Initialize DACR0 */ - sdram->dacr0 = - SDRAMC_DARCn_BA(CONFIG_SYS_SDRAM_BASE) | SDRAMC_DARCn_CASL_C1 | - SDRAMC_DARCn_CBM_CMD20 | SDRAMC_DARCn_PS_32; + out_be32(&sdram->dacr0, + SDRAMC_DARCn_BA(CONFIG_SYS_SDRAM_BASE) | + SDRAMC_DARCn_CASL_C1 | SDRAMC_DARCn_CBM_CMD20 | + SDRAMC_DARCn_PS_32); asm("nop"); /* Initialize DMR0 */ - sdram->dmr0 = ((dramsize - 1) & 0xFFFC0000) | SDRAMC_DMRn_V; + out_be32(&sdram->dmr0, + ((dramsize - 1) & 0xFFFC0000) | SDRAMC_DMRn_V); asm("nop"); /* Set IP (bit 3) in DACR */ - sdram->dacr0 |= SDRAMC_DARCn_IP; + setbits_be32(&sdram->dacr0, SDRAMC_DARCn_IP); /* Wait 30ns to allow banks to precharge */ for (i = 0; i < 5; i++) { @@ -93,7 +98,7 @@ phys_size_t initdram(int board_type) *(u32 *) (CONFIG_SYS_SDRAM_BASE) = 0xA5A59696; /* Set RE (bit 15) in DACR */ - sdram->dacr0 |= SDRAMC_DARCn_RE; + setbits_be32(&sdram->dacr0, SDRAMC_DARCn_RE); /* Wait for at least 8 auto refresh cycles to occur */ for (i = 0; i < 0x2000; i++) { @@ -101,7 +106,7 @@ phys_size_t initdram(int board_type) } /* Finish the configuration by issuing the MRS. */ - sdram->dacr0 |= SDRAMC_DARCn_IMRS; + setbits_be32(&sdram->dacr0, SDRAMC_DARCn_IMRS); asm("nop"); /* Write to the SDRAM Mode Register */ diff --git a/board/freescale/m5253demo/m5253demo.c b/board/freescale/m5253demo/m5253demo.c index 8ffb2cc..052993d 100644 --- a/board/freescale/m5253demo/m5253demo.c +++ b/board/freescale/m5253demo/m5253demo.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * Hayden Fraser (Hayden.Fraser@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -109,7 +109,7 @@ int ide_preinit(void) void ide_set_reset(int idereset) { - volatile atac_t *ata = (atac_t *) CONFIG_SYS_ATA_BASE_ADDR; + atac_t *ata = (atac_t *) CONFIG_SYS_ATA_BASE_ADDR; long period; /* t1, t2, t3, t4, t5, t6, t9, tRD, tA */ int piotms[5][9] = { {70, 165, 60, 30, 50, 5, 20, 0, 35}, /* PIO 0 */ @@ -120,7 +120,8 @@ void ide_set_reset(int idereset) }; if (idereset) { - ata->cr = 0; /* control reset */ + /* control reset */ + out_8(&ata->cr, 0); udelay(100); } else { mbar2_writeLong(CIM_MISCCR, CIM_MISCCR_CPUEND); @@ -129,17 +130,19 @@ void ide_set_reset(int idereset) period = 1000000000 / (CONFIG_SYS_CLK / 2); /* period in ns */ /*ata->ton = CALC_TIMING (180); */ - ata->t1 = CALC_TIMING(piotms[2][0]); - ata->t2w = CALC_TIMING(piotms[2][1]); - ata->t2r = CALC_TIMING(piotms[2][1]); - ata->ta = CALC_TIMING(piotms[2][8]); - ata->trd = CALC_TIMING(piotms[2][7]); - ata->t4 = CALC_TIMING(piotms[2][3]); - ata->t9 = CALC_TIMING(piotms[2][6]); - - ata->cr = 0x40; /* IORDY enable */ + out_8(&ata->t1, CALC_TIMING(piotms[2][0])); + out_8(&ata->t2w, CALC_TIMING(piotms[2][1])); + out_8(&ata->t2r, CALC_TIMING(piotms[2][1])); + out_8(&ata->ta, CALC_TIMING(piotms[2][8])); + out_8(&ata->trd, CALC_TIMING(piotms[2][7])); + out_8(&ata->t4, CALC_TIMING(piotms[2][3])); + out_8(&ata->t9, CALC_TIMING(piotms[2][6])); + + /* IORDY enable */ + out_8(&ata->cr, 0x40); udelay(2000); - ata->cr |= 0x01; /* IORDY enable */ + /* IORDY enable */ + setbits_8(&ata->cr, 0x01); } } #endif /* CONFIG_CMD_IDE */ diff --git a/board/freescale/m5253evbe/m5253evbe.c b/board/freescale/m5253evbe/m5253evbe.c index ae69f67..658748b 100644 --- a/board/freescale/m5253evbe/m5253evbe.c +++ b/board/freescale/m5253evbe/m5253evbe.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * Hayden Fraser (Hayden.Fraser@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -26,6 +26,7 @@ #include <common.h> #include <asm/immap.h> +#include <asm/io.h> int checkboard(void) { @@ -101,7 +102,7 @@ int ide_preinit(void) void ide_set_reset(int idereset) { - volatile atac_t *ata = (atac_t *) CONFIG_SYS_ATA_BASE_ADDR; + atac_t *ata = (atac_t *) CONFIG_SYS_ATA_BASE_ADDR; long period; /* t1, t2, t3, t4, t5, t6, t9, tRD, tA */ int piotms[5][9] = { {70, 165, 60, 30, 50, 5, 20, 0, 35}, /* PIO 0 */ @@ -112,7 +113,8 @@ void ide_set_reset(int idereset) }; if (idereset) { - ata->cr = 0; /* control reset */ + /* control reset */ + out_8(&ata->cr, 0); udelay(100); } else { mbar2_writeLong(CIM_MISCCR, CIM_MISCCR_CPUEND); @@ -121,17 +123,19 @@ void ide_set_reset(int idereset) period = 1000000000 / (CONFIG_SYS_CLK / 2); /* period in ns */ /*ata->ton = CALC_TIMING (180); */ - ata->t1 = CALC_TIMING(piotms[2][0]); - ata->t2w = CALC_TIMING(piotms[2][1]); - ata->t2r = CALC_TIMING(piotms[2][1]); - ata->ta = CALC_TIMING(piotms[2][8]); - ata->trd = CALC_TIMING(piotms[2][7]); - ata->t4 = CALC_TIMING(piotms[2][3]); - ata->t9 = CALC_TIMING(piotms[2][6]); - - ata->cr = 0x40; /* IORDY enable */ + out_8(&ata->t1, CALC_TIMING(piotms[2][0])); + out_8(&ata->t2w, CALC_TIMING(piotms[2][1])); + out_8(&ata->t2r, CALC_TIMING(piotms[2][1])); + out_8(&ata->ta, CALC_TIMING(piotms[2][8])); + out_8(&ata->trd, CALC_TIMING(piotms[2][7])); + out_8(&ata->t4, CALC_TIMING(piotms[2][3])); + out_8(&ata->t9, CALC_TIMING(piotms[2][6])); + + /* IORDY enable */ + out_8(&ata->cr, 0x40); udelay(2000); - ata->cr |= 0x01; /* IORDY enable */ + /* IORDY enable */ + setbits_8(&ata->cr, 0x01); } } #endif /* CONFIG_CMD_IDE */ diff --git a/board/freescale/m5272c3/m5272c3.c b/board/freescale/m5272c3/m5272c3.c index 902ca3a..c3160ce 100644 --- a/board/freescale/m5272c3/m5272c3.c +++ b/board/freescale/m5272c3/m5272c3.c @@ -2,6 +2,8 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * * See file CREDITS for list of people who contributed to this * project. * @@ -23,6 +25,7 @@ #include <common.h> #include <asm/immap.h> +#include <asm/io.h> int checkboard (void) { @@ -32,10 +35,10 @@ int checkboard (void) { }; phys_size_t initdram (int board_type) { - volatile sdramctrl_t * sdp = (sdramctrl_t *)(MMAP_SDRAM); + sdramctrl_t * sdp = (sdramctrl_t *)(MMAP_SDRAM); - sdp->sdram_sdtr = 0xf539; - sdp->sdram_sdcr = 0x4211; + out_be16(&sdp->sdram_sdtr, 0xf539); + out_be16(&sdp->sdram_sdcr, 0x4211); /* Dummy write to start SDRAM */ *((volatile unsigned long *)0) = 0; diff --git a/board/freescale/m5275evb/m5275evb.c b/board/freescale/m5275evb/m5275evb.c index 35c9b20..1bbe5a3 100644 --- a/board/freescale/m5275evb/m5275evb.c +++ b/board/freescale/m5275evb/m5275evb.c @@ -4,6 +4,8 @@ * * Copyright (C) 2005-2008 Arthur Shipkowski (art@videon-central.com) * + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * * See file CREDITS for list of people who contributed to this * project. * @@ -25,6 +27,7 @@ #include <common.h> #include <asm/immap.h> +#include <asm/io.h> #define PERIOD 13 /* system bus period in ns */ #define SDRAM_TREFI 7800 /* in ns */ @@ -38,67 +41,68 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile sdramctrl_t *sdp = (sdramctrl_t *)(MMAP_SDRAM); - volatile gpio_t *gpio_reg = (gpio_t *)(MMAP_GPIO); + sdramctrl_t *sdp = (sdramctrl_t *)(MMAP_SDRAM); + gpio_t *gpio_reg = (gpio_t *)(MMAP_GPIO); - gpio_reg->par_sdram = 0x3FF; /* Enable SDRAM */ + /* Enable SDRAM */ + out_be16(&gpio_reg->par_sdram, 0x3FF); /* Set up chip select */ - sdp->sdbar0 = CONFIG_SYS_SDRAM_BASE; - sdp->sdbmr0 = MCF_SDRAMC_SDMRn_BAM_32M | MCF_SDRAMC_SDMRn_V; + out_be32(&sdp->sdbar0, CONFIG_SYS_SDRAM_BASE); + out_be32(&sdp->sdbmr0, MCF_SDRAMC_SDMRn_BAM_32M | MCF_SDRAMC_SDMRn_V); /* Set up timing */ - sdp->sdcfg1 = 0x83711630; - sdp->sdcfg2 = 0x46770000; + out_be32(&sdp->sdcfg1, 0x83711630); + out_be32(&sdp->sdcfg2, 0x46770000); /* Enable clock */ - sdp->sdcr = MCF_SDRAMC_SDCR_MODE_EN | MCF_SDRAMC_SDCR_CKE; + out_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_MODE_EN | MCF_SDRAMC_SDCR_CKE); /* Set precharge */ - sdp->sdcr |= MCF_SDRAMC_SDCR_IPALL; + setbits_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_IPALL); /* Dummy write to start SDRAM */ *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; /* Send LEMR */ - sdp->sdmr = MCF_SDRAMC_SDMR_BNKAD_LEMR - | MCF_SDRAMC_SDMR_AD(0x0) - | MCF_SDRAMC_SDMR_CMD; + setbits_be32(&sdp->sdmr, + MCF_SDRAMC_SDMR_BNKAD_LEMR | MCF_SDRAMC_SDMR_AD(0x0) | + MCF_SDRAMC_SDMR_CMD); *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; /* Send LMR */ - sdp->sdmr = 0x058d0000; + out_be32(&sdp->sdmr, 0x058d0000); *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; /* Stop sending commands */ - sdp->sdmr &= ~(MCF_SDRAMC_SDMR_CMD); + clrbits_be32(&sdp->sdmr, MCF_SDRAMC_SDMR_CMD); /* Set precharge */ - sdp->sdcr |= MCF_SDRAMC_SDCR_IPALL; + setbits_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_IPALL); *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; /* Stop manual precharge, send 2 IREF */ - sdp->sdcr &= ~(MCF_SDRAMC_SDCR_IPALL); - sdp->sdcr |= MCF_SDRAMC_SDCR_IREF; + clrbits_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_IPALL); + setbits_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_IREF); *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; - /* Write mode register, clear reset DLL */ - sdp->sdmr = 0x018d0000; + + out_be32(&sdp->sdmr, 0x018d0000); *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; /* Stop sending commands */ - sdp->sdmr &= ~(MCF_SDRAMC_SDMR_CMD); - sdp->sdcr &= ~(MCF_SDRAMC_SDCR_MODE_EN); + clrbits_be32(&sdp->sdmr, MCF_SDRAMC_SDMR_CMD); + clrbits_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_MODE_EN); /* Turn on auto refresh, lock SDMR */ - sdp->sdcr = + out_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_CKE | MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_MUX(1) /* 1 added to round up */ | MCF_SDRAMC_SDCR_RCNT((SDRAM_TREFI/(PERIOD*64)) - 1 + 1) - | MCF_SDRAMC_SDCR_DQS_OE(0x3); + | MCF_SDRAMC_SDCR_DQS_OE(0x3)); return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; }; diff --git a/board/freescale/m53017evb/m53017evb.c b/board/freescale/m53017evb/m53017evb.c index f331786..142485f 100644 --- a/board/freescale/m53017evb/m53017evb.c +++ b/board/freescale/m53017evb/m53017evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2008, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include <config.h> #include <common.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -39,7 +40,7 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); u32 dramsize, i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; @@ -50,34 +51,35 @@ phys_size_t initdram(int board_type) } i--; - sdram->cs0 = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->cs0, CONFIG_SYS_SDRAM_BASE | i); #ifdef CONFIG_SYS_SDRAM_BASE1 - sdram->cs1 = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->cs1, CONFIG_SYS_SDRAM_BASE | i); #endif - sdram->cfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->cfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->cfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->cfg2, CONFIG_SYS_SDRAM_CFG2); udelay(500); /* Issue PALL */ - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); asm("nop"); /* Perform two refresh cycles */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); asm("nop"); /* Issue LEMR */ - sdram->mode = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE); asm("nop"); - sdram->mode = CONFIG_SYS_SDRAM_EMOD; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_EMOD); asm("nop"); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); asm("nop"); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00; + out_be32(&sdram->ctrl, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00); asm("nop"); udelay(100); diff --git a/board/freescale/m5329evb/m5329evb.c b/board/freescale/m5329evb/m5329evb.c index b4df22f..1c14b83 100644 --- a/board/freescale/m5329evb/m5329evb.c +++ b/board/freescale/m5329evb/m5329evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include <config.h> #include <common.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -39,7 +40,7 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); u32 dramsize, i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; @@ -50,29 +51,30 @@ phys_size_t initdram(int board_type) } i--; - sdram->cs0 = (CONFIG_SYS_SDRAM_BASE | i); - sdram->cfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->cfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->cs0, CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->cfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->cfg2, CONFIG_SYS_SDRAM_CFG2); /* Issue PALL */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Issue LEMR */ - sdram->mode = CONFIG_SYS_SDRAM_EMOD; - sdram->mode = (CONFIG_SYS_SDRAM_MODE | 0x04000000); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_EMOD); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE | 0x04000000); udelay(500); /* Issue PALL */ - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Perform two refresh cycles */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); - sdram->mode = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00; + out_be32(&sdram->ctrl, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00); udelay(100); diff --git a/board/freescale/m5329evb/nand.c b/board/freescale/m5329evb/nand.c index 16025f9..c70c98c 100644 --- a/board/freescale/m5329evb/nand.c +++ b/board/freescale/m5329evb/nand.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -67,18 +67,18 @@ static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd, unsigned int ctrl) int board_nand_init(struct nand_chip *nand) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* * set up pin configuration - enabled 2nd output buffer's signals * (nand_ngpio - nCE USB1/2_PWR_EN, LATCH_GPIOs, LCD_VEEEN, etc) * to use nCE signal */ - gpio->par_timer &= ~GPIO_PAR_TIN3_TIN3; - gpio->pddr_timer |= 0x08; - gpio->ppd_timer |= 0x08; - gpio->pclrr_timer = 0; - gpio->podr_timer = 0; + clrbits_8(&gpio->par_timer, GPIO_PAR_TIN3_TIN3); + setbits_8(&gpio->pddr_timer, 0x08); + setbits_8(&gpio->ppd_timer, 0x08); + out_8(&gpio->pclrr_timer, 0); + out_8(&gpio->podr_timer, 0); nand->chip_delay = 60; nand->ecc.mode = NAND_ECC_SOFT; diff --git a/board/freescale/m5373evb/m5373evb.c b/board/freescale/m5373evb/m5373evb.c index 376de4b..8eb3512 100644 --- a/board/freescale/m5373evb/m5373evb.c +++ b/board/freescale/m5373evb/m5373evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include <config.h> #include <common.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -39,7 +40,7 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); u32 dramsize, i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; @@ -50,29 +51,30 @@ phys_size_t initdram(int board_type) } i--; - sdram->cs0 = (CONFIG_SYS_SDRAM_BASE | i); - sdram->cfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->cfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->cs0, CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->cfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->cfg2, CONFIG_SYS_SDRAM_CFG2); /* Issue PALL */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Issue LEMR */ - sdram->mode = CONFIG_SYS_SDRAM_EMOD; - sdram->mode = (CONFIG_SYS_SDRAM_MODE | 0x04000000); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_EMOD); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE | 0x04000000); udelay(500); /* Issue PALL */ - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Perform two refresh cycles */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); - sdram->mode = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00; + out_be32(&sdram->ctrl, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00); udelay(100); diff --git a/board/freescale/m5373evb/nand.c b/board/freescale/m5373evb/nand.c index df8c03b..ed79e39 100644 --- a/board/freescale/m5373evb/nand.c +++ b/board/freescale/m5373evb/nand.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -68,21 +68,21 @@ static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd, unsigned int ctrl) int board_nand_init(struct nand_chip *nand) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - fbcs->csmr2 &= ~FBCS_CSMR_WP; + clrbits_be32(&fbcs->csmr2, FBCS_CSMR_WP); /* * set up pin configuration - enabled 2nd output buffer's signals * (nand_ngpio - nCE USB1/2_PWR_EN, LATCH_GPIOs, LCD_VEEEN, etc) * to use nCE signal */ - gpio->par_timer &= ~GPIO_PAR_TIN3_TIN3; - gpio->pddr_timer |= 0x08; - gpio->ppd_timer |= 0x08; - gpio->pclrr_timer = 0; - gpio->podr_timer = 0; + clrbits_8(&gpio->par_timer, GPIO_PAR_TIN3_TIN3); + setbits_8(&gpio->pddr_timer, 0x08); + setbits_8(&gpio->ppd_timer, 0x08); + out_8(&gpio->pclrr_timer, 0); + out_8(&gpio->podr_timer, 0); nand->chip_delay = 60; nand->ecc.mode = NAND_ECC_SOFT; diff --git a/board/freescale/m54451evb/m54451evb.c b/board/freescale/m54451evb/m54451evb.c index 088c8c4..32a9374 100644 --- a/board/freescale/m54451evb/m54451evb.c +++ b/board/freescale/m54451evb/m54451evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2008, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include <common.h> #include <spi.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -51,14 +52,14 @@ phys_size_t initdram(int board_type) */ dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; #else - volatile sdramc_t *sdram = (volatile sdramc_t *)(MMAP_SDRAM); - volatile gpio_t *gpio = (volatile gpio_t *)(MMAP_GPIO); + sdramc_t *sdram = (sdramc_t *)(MMAP_SDRAM); + gpio_t *gpio = (gpio_t *)(MMAP_GPIO); u32 i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; - if ((sdram->sdcfg1 == CONFIG_SYS_SDRAM_CFG1) && - (sdram->sdcfg2 == CONFIG_SYS_SDRAM_CFG2)) + if ((in_be32(&sdram->sdcfg1) == CONFIG_SYS_SDRAM_CFG1) && + (in_be32(&sdram->sdcfg2) == CONFIG_SYS_SDRAM_CFG2)) return dramsize; for (i = 0x13; i < 0x20; i++) { @@ -67,32 +68,33 @@ phys_size_t initdram(int board_type) } i--; - gpio->mscr_sdram = CONFIG_SYS_SDRAM_DRV_STRENGTH; + out_8(&gpio->mscr_sdram, CONFIG_SYS_SDRAM_DRV_STRENGTH); - sdram->sdcs0 = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->sdcs0, CONFIG_SYS_SDRAM_BASE | i); - sdram->sdcfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->sdcfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->sdcfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->sdcfg2, CONFIG_SYS_SDRAM_CFG2); udelay(200); /* Issue PALL */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 2); __asm__("nop"); /* Perform two refresh cycles */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 4); __asm__("nop"); - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 4); __asm__("nop"); /* Issue LEMR */ - sdram->sdmr = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_MODE); __asm__("nop"); - sdram->sdmr = CONFIG_SYS_SDRAM_EMOD; + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_MODE); __asm__("nop"); - sdram->sdcr = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000000; + out_be32(&sdram->sdcr, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000000); udelay(100); #endif diff --git a/board/freescale/m54455evb/m54455evb.c b/board/freescale/m54455evb/m54455evb.c index 2a84514..0ca268e 100644 --- a/board/freescale/m54455evb/m54455evb.c +++ b/board/freescale/m54455evb/m54455evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include <common.h> #include <pci.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -47,8 +48,8 @@ phys_size_t initdram(int board_type) */ dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000 >> 1; #else - volatile sdramc_t *sdram = (volatile sdramc_t *)(MMAP_SDRAM); - volatile gpio_t *gpio = (volatile gpio_t *)(MMAP_GPIO); + sdramc_t *sdram = (sdramc_t *)(MMAP_SDRAM); + gpio_t *gpio = (gpio_t *)(MMAP_GPIO); u32 i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000 >> 1; @@ -59,33 +60,34 @@ phys_size_t initdram(int board_type) } i--; - gpio->mscr_sdram = CONFIG_SYS_SDRAM_DRV_STRENGTH; + out_8(&gpio->mscr_sdram, CONFIG_SYS_SDRAM_DRV_STRENGTH); - sdram->sdcs0 = (CONFIG_SYS_SDRAM_BASE | i); - sdram->sdcs1 = (CONFIG_SYS_SDRAM_BASE1 | i); + out_be32(&sdram->sdcs0, CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->sdcs1, CONFIG_SYS_SDRAM_BASE1 | i); - sdram->sdcfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->sdcfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->sdcfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->sdcfg2, CONFIG_SYS_SDRAM_CFG2); /* Issue PALL */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 2); /* Issue LEMR */ - sdram->sdmr = CONFIG_SYS_SDRAM_EMOD | 0x408; - sdram->sdmr = CONFIG_SYS_SDRAM_MODE | 0x300; + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_EMOD | 0x408); + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_MODE | 0x300); udelay(500); /* Issue PALL */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 2); /* Perform two refresh cycles */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 4); - sdram->sdmr = CONFIG_SYS_SDRAM_MODE | 0x200; + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_MODE | 0x200); - sdram->sdcr = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00; + out_be32(&sdram->sdcr, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00); udelay(100); #endif @@ -105,26 +107,29 @@ int testdram(void) int ide_preinit(void) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - - gpio->par_fec |= (gpio->par_fec & GPIO_PAR_FEC_FEC1_UNMASK) | 0x10; - gpio->par_feci2c |= - (gpio->par_feci2c & 0xF0FF) | (GPIO_PAR_FECI2C_MDC1_ATA_DIOR | - GPIO_PAR_FECI2C_MDIO1_ATA_DIOW); - gpio->par_ata |= - (GPIO_PAR_ATA_BUFEN | GPIO_PAR_ATA_CS1 | GPIO_PAR_ATA_CS0 | - GPIO_PAR_ATA_DA2 | GPIO_PAR_ATA_DA1 | GPIO_PAR_ATA_DA0 - | GPIO_PAR_ATA_RESET_RESET | GPIO_PAR_ATA_DMARQ_DMARQ | - GPIO_PAR_ATA_IORDY_IORDY); - gpio->par_pci |= - (GPIO_PAR_PCI_GNT3_ATA_DMACK | GPIO_PAR_PCI_REQ3_ATA_INTRQ); + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + u32 tmp; + + tmp = (in_8(&gpio->par_fec) & GPIO_PAR_FEC_FEC1_UNMASK) | 0x10; + setbits_8(&gpio->par_fec, tmp); + tmp = ((in_be16(&gpio->par_feci2c) & 0xf0ff) | + (GPIO_PAR_FECI2C_MDC1_ATA_DIOR | GPIO_PAR_FECI2C_MDIO1_ATA_DIOW)); + setbits_be16(&gpio->par_feci2c, tmp); + + setbits_be16(&gpio->par_ata, + GPIO_PAR_ATA_BUFEN | GPIO_PAR_ATA_CS1 | GPIO_PAR_ATA_CS0 | + GPIO_PAR_ATA_DA2 | GPIO_PAR_ATA_DA1 | GPIO_PAR_ATA_DA0 | + GPIO_PAR_ATA_RESET_RESET | GPIO_PAR_ATA_DMARQ_DMARQ | + GPIO_PAR_ATA_IORDY_IORDY); + setbits_be16(&gpio->par_pci, + GPIO_PAR_PCI_GNT3_ATA_DMACK | GPIO_PAR_PCI_REQ3_ATA_INTRQ); return (0); } void ide_set_reset(int idereset) { - volatile atac_t *ata = (atac_t *) MMAP_ATA; + atac_t *ata = (atac_t *) MMAP_ATA; long period; /* t1, t2, t3, t4, t5, t6, t9, tRD, tA */ int piotms[5][9] = { @@ -136,24 +141,27 @@ void ide_set_reset(int idereset) }; /* PIO 4 */ if (idereset) { - ata->cr = 0; /* control reset */ + /* control reset */ + out_8(&ata->cr, 0); udelay(10000); } else { #define CALC_TIMING(t) (t + period - 1) / period period = 1000000000 / gd->bus_clk; /* period in ns */ /*ata->ton = CALC_TIMING (180); */ - ata->t1 = CALC_TIMING(piotms[2][0]); - ata->t2w = CALC_TIMING(piotms[2][1]); - ata->t2r = CALC_TIMING(piotms[2][1]); - ata->ta = CALC_TIMING(piotms[2][8]); - ata->trd = CALC_TIMING(piotms[2][7]); - ata->t4 = CALC_TIMING(piotms[2][3]); - ata->t9 = CALC_TIMING(piotms[2][6]); - - ata->cr = 0x40; /* IORDY enable */ + out_8(&ata->t1, CALC_TIMING(piotms[2][0])); + out_8(&ata->t2w, CALC_TIMING(piotms[2][1])); + out_8(&ata->t2r, CALC_TIMING(piotms[2][1])); + out_8(&ata->ta, CALC_TIMING(piotms[2][8])); + out_8(&ata->trd, CALC_TIMING(piotms[2][7])); + out_8(&ata->t4, CALC_TIMING(piotms[2][3])); + out_8(&ata->t9, CALC_TIMING(piotms[2][6])); + + /* IORDY enable */ + out_8(&ata->cr, 0x40); udelay(200000); - ata->cr |= 0x01; /* IORDY enable */ + /* IORDY enable */ + setbits_8(&ata->cr, 0x01); } } #endif diff --git a/board/freescale/m547xevb/m547xevb.c b/board/freescale/m547xevb/m547xevb.c index 9f1ec38..fd9bddd 100644 --- a/board/freescale/m547xevb/m547xevb.c +++ b/board/freescale/m547xevb/m547xevb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,6 +28,7 @@ #include <common.h> #include <pci.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -40,14 +41,14 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile siu_t *siu = (siu_t *) (MMAP_SIU); - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + siu_t *siu = (siu_t *) (MMAP_SIU); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); u32 dramsize, i; #ifdef CONFIG_SYS_DRAMSZ1 u32 temp; #endif - siu->drv = CONFIG_SYS_SDRAM_DRVSTRENGTH; + out_be32(&siu->drv, CONFIG_SYS_SDRAM_DRVSTRENGTH); dramsize = CONFIG_SYS_DRAMSZ * 0x100000; for (i = 0x13; i < 0x20; i++) { @@ -55,7 +56,7 @@ phys_size_t initdram(int board_type) break; } i--; - siu->cs0cfg = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&siu->cs0cfg, CONFIG_SYS_SDRAM_BASE | i); #ifdef CONFIG_SYS_DRAMSZ1 temp = CONFIG_SYS_DRAMSZ1 * 0x100000; @@ -65,31 +66,32 @@ phys_size_t initdram(int board_type) } i--; dramsize += temp; - siu->cs1cfg = ((CONFIG_SYS_SDRAM_BASE + temp) | i); + out_be32(&siu->cs1cfg, (CONFIG_SYS_SDRAM_BASE + temp) | i); #endif - sdram->cfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->cfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->cfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->cfg2, CONFIG_SYS_SDRAM_CFG2); /* Issue PALL */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Issue LEMR */ - sdram->mode = CONFIG_SYS_SDRAM_EMOD; - sdram->mode = (CONFIG_SYS_SDRAM_MODE | 0x04000000); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_EMOD); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE | 0x04000000); udelay(500); /* Issue PALL */ - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Perform two refresh cycles */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); - sdram->mode = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00; + out_be32(&sdram->ctrl, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00); udelay(100); diff --git a/board/freescale/m548xevb/m548xevb.c b/board/freescale/m548xevb/m548xevb.c index fbc0888..fb216d8 100644 --- a/board/freescale/m548xevb/m548xevb.c +++ b/board/freescale/m548xevb/m548xevb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,6 +28,7 @@ #include <common.h> #include <pci.h> #include <asm/immap.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -40,14 +41,14 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile siu_t *siu = (siu_t *) (MMAP_SIU); - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + siu_t *siu = (siu_t *) (MMAP_SIU); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); u32 dramsize, i; #ifdef CONFIG_SYS_DRAMSZ1 u32 temp; #endif - siu->drv = CONFIG_SYS_SDRAM_DRVSTRENGTH; + out_be32(&siu->drv, CONFIG_SYS_SDRAM_DRVSTRENGTH); dramsize = CONFIG_SYS_DRAMSZ * 0x100000; for (i = 0x13; i < 0x20; i++) { @@ -55,7 +56,7 @@ phys_size_t initdram(int board_type) break; } i--; - siu->cs0cfg = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&siu->cs0cfg, CONFIG_SYS_SDRAM_BASE | i); #ifdef CONFIG_SYS_DRAMSZ1 temp = CONFIG_SYS_DRAMSZ1 * 0x100000; @@ -65,31 +66,32 @@ phys_size_t initdram(int board_type) } i--; dramsize += temp; - siu->cs1cfg = ((CONFIG_SYS_SDRAM_BASE + temp) | i); + out_be32(&siu->cs1cfg, (CONFIG_SYS_SDRAM_BASE + temp) | i); #endif - sdram->cfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->cfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->cfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->cfg2, CONFIG_SYS_SDRAM_CFG2); /* Issue PALL */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Issue LEMR */ - sdram->mode = CONFIG_SYS_SDRAM_EMOD; - sdram->mode = (CONFIG_SYS_SDRAM_MODE | 0x04000000); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_EMOD); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE | 0x04000000); udelay(500); /* Issue PALL */ - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Perform two refresh cycles */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); - sdram->mode = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00; + out_be32(&sdram->ctrl, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00); udelay(100); diff --git a/board/freescale/mpc8308rdb/mpc8308rdb.c b/board/freescale/mpc8308rdb/mpc8308rdb.c index 5c54357..7e3fa1a 100644 --- a/board/freescale/mpc8308rdb/mpc8308rdb.c +++ b/board/freescale/mpc8308rdb/mpc8308rdb.c @@ -24,18 +24,56 @@ #include <common.h> #include <hwconfig.h> #include <i2c.h> +#include <spi.h> #include <libfdt.h> #include <fdt_support.h> #include <pci.h> #include <mpc83xx.h> #include <vsc7385.h> #include <netdev.h> +#include <fsl_esdhc.h> #include <asm/io.h> #include <asm/fsl_serdes.h> #include <asm/fsl_mpc83xx_serdes.h> DECLARE_GLOBAL_DATA_PTR; +/* + * The following are used to control the SPI chip selects for the SPI command. + */ +#ifdef CONFIG_MPC8XXX_SPI + +#define SPI_CS_MASK 0x00400000 + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return bus == 0 && cs == 0; +} + +void spi_cs_activate(struct spi_slave *slave) +{ + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + + /* active low */ + clrbits_be32(&immr->gpio[0].dat, SPI_CS_MASK); +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + + /* inactive high */ + setbits_be32(&immr->gpio[0].dat, SPI_CS_MASK); +} +#endif /* CONFIG_MPC8XXX_SPI */ + +#ifdef CONFIG_FSL_ESDHC +int board_mmc_init(bd_t *bd) +{ + return fsl_esdhc_mmc_init(bd); +} +#endif + static u8 read_board_info(void) { u8 val8; @@ -109,6 +147,25 @@ void pci_init_board(void) */ int misc_init_r(void) { +#ifdef CONFIG_MPC8XXX_SPI + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + sysconf83xx_t *sysconf = &immr->sysconf; + + /* + * Set proper bits in SICRH to allow SPI on header J8 + * + * NOTE: this breaks the TSEC2 interface, attached to the Vitesse + * switch. The pinmux configuration does not have a fine enough + * granularity to support both simultaneously. + */ + clrsetbits_be32(&sysconf->sicrh, SICRH_GPIO_A_TSEC2, SICRH_GPIO_A_GPIO); + puts("WARNING: SPI enabled, TSEC2 support is broken\n"); + + /* Set header J8 SPI chip select output, disabled */ + setbits_be32(&immr->gpio[0].dir, SPI_CS_MASK); + setbits_be32(&immr->gpio[0].dat, SPI_CS_MASK); +#endif + #ifdef CONFIG_VSC7385_IMAGE if (vsc7385_upload_firmware((void *) CONFIG_VSC7385_IMAGE, CONFIG_VSC7385_IMAGE_SIZE)) { @@ -124,6 +181,7 @@ void ft_board_setup(void *blob, bd_t *bd) { ft_cpu_setup(blob, bd); fdt_fixup_dr_usb(blob, bd); + fdt_fixup_esdhc(blob, bd); } #endif diff --git a/board/freescale/mpc8540ads/mpc8540ads.c b/board/freescale/mpc8540ads/mpc8540ads.c index c75585e..a275d3a 100644 --- a/board/freescale/mpc8540ads/mpc8540ads.c +++ b/board/freescale/mpc8540ads/mpc8540ads.c @@ -87,10 +87,10 @@ local_bus_init(void) lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { - lbc->lcrr = CONFIG_SYS_LBC_LCRR | 0x80000000; /* DLL Bypass */ + lbc->lcrr = CONFIG_SYS_LBC_LCRR | LCRR_DBYP; /* DLL Bypass */ } else if (lbc_hz >= 133) { - lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~0x80000000); /* DLL Enabled */ + lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~LCRR_DBYP); /* DLL Enabled */ } else { /* @@ -105,7 +105,7 @@ local_bus_init(void) lbc->lcrr = 0x10000004; } - lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~0x80000000); /* DLL Enabled */ + lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~LCRR_DBYP); /* DLL Enabled */ udelay(200); /* diff --git a/board/freescale/mpc8541cds/mpc8541cds.c b/board/freescale/mpc8541cds/mpc8541cds.c index 532d32a..13ca84b 100644 --- a/board/freescale/mpc8541cds/mpc8541cds.c +++ b/board/freescale/mpc8541cds/mpc8541cds.c @@ -269,13 +269,13 @@ local_bus_init(void) lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { - lbc->lcrr |= 0x80000000; /* DLL Bypass */ + lbc->lcrr |= LCRR_DBYP; /* DLL Bypass */ } else if (lbc_hz >= 133) { - lbc->lcrr &= (~0x80000000); /* DLL Enabled */ + lbc->lcrr &= (~LCRR_DBYP); /* DLL Enabled */ } else { - lbc->lcrr &= (~0x80000000); /* DLL Enabled */ + lbc->lcrr &= (~LCRR_DBYP); /* DLL Enabled */ udelay(200); /* diff --git a/board/freescale/mpc8555cds/mpc8555cds.c b/board/freescale/mpc8555cds/mpc8555cds.c index 3361614..4cfd61c 100644 --- a/board/freescale/mpc8555cds/mpc8555cds.c +++ b/board/freescale/mpc8555cds/mpc8555cds.c @@ -267,13 +267,13 @@ local_bus_init(void) lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { - lbc->lcrr |= 0x80000000; /* DLL Bypass */ + lbc->lcrr |= LCRR_DBYP; /* DLL Bypass */ } else if (lbc_hz >= 133) { - lbc->lcrr &= (~0x80000000); /* DLL Enabled */ + lbc->lcrr &= (~LCRR_DBYP); /* DLL Enabled */ } else { - lbc->lcrr &= (~0x80000000); /* DLL Enabled */ + lbc->lcrr &= (~LCRR_DBYP); /* DLL Enabled */ udelay(200); /* diff --git a/board/freescale/mpc8560ads/mpc8560ads.c b/board/freescale/mpc8560ads/mpc8560ads.c index 1a165bf..285edbc 100644 --- a/board/freescale/mpc8560ads/mpc8560ads.c +++ b/board/freescale/mpc8560ads/mpc8560ads.c @@ -292,10 +292,10 @@ local_bus_init(void) lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { - lbc->lcrr = CONFIG_SYS_LBC_LCRR | 0x80000000; /* DLL Bypass */ + lbc->lcrr = CONFIG_SYS_LBC_LCRR | LCRR_DBYP; /* DLL Bypass */ } else if (lbc_hz >= 133) { - lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~0x80000000); /* DLL Enabled */ + lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~LCRR_DBYP); /* DLL Enabled */ } else { /* @@ -310,7 +310,7 @@ local_bus_init(void) lbc->lcrr = 0x10000004; } - lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~0x80000000);/* DLL Enabled */ + lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~LCRR_DBYP);/* DLL Enabled */ udelay(200); /* diff --git a/board/freescale/p1010rdb/ddr.c b/board/freescale/p1010rdb/ddr.c index 10c5a42..6d00caf 100644 --- a/board/freescale/p1010rdb/ddr.c +++ b/board/freescale/p1010rdb/ddr.c @@ -147,10 +147,11 @@ phys_size_t fixed_sdram(void) cpu = gd->cpu; /* P1014 and it's derivatives support max 16bit DDR width */ if (cpu->soc_ver == SVR_P1014) { + ddr_cfg_regs.ddr_sdram_cfg &= ~SDRAM_CFG_DBW_MASK; ddr_cfg_regs.ddr_sdram_cfg |= SDRAM_CFG_16_BE; - ddr_cfg_regs.cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS >> 1; - ddr_cfg_regs.ddr_sdram_cfg &= ~0x00180000; - ddr_cfg_regs.ddr_sdram_cfg |= 0x001080000; + /* divide SA and EA by two and then mask the rest so we don't + * write to reserved fields */ + ddr_cfg_regs.cs[0].bnds = (CONFIG_SYS_DDR_CS0_BNDS >> 1) & 0x0fff0fff; } ddr_size = (phys_size_t) CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; diff --git a/board/freescale/p1_p2_rdb_pc/law.c b/board/freescale/p1_p2_rdb_pc/law.c index 7968919..0da8300 100644 --- a/board/freescale/p1_p2_rdb_pc/law.c +++ b/board/freescale/p1_p2_rdb_pc/law.c @@ -25,13 +25,11 @@ #include <asm/mmu.h> struct law_entry law_table[] = { -#ifndef CONFIG_NAND_SPL SET_LAW(CONFIG_SYS_CPLD_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC), SET_LAW(CONFIG_SYS_PMC_BASE_PHYS, LAW_SIZE_64K, LAW_TRGT_IF_LBC), #ifdef CONFIG_VSC7385_ENET SET_LAW(CONFIG_SYS_VSC7385_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC), #endif -#endif SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_64M, LAW_TRGT_IF_LBC), #ifdef CONFIG_SYS_NAND_BASE_PHYS SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC), diff --git a/board/freescale/p3060qds/README b/board/freescale/p3060qds/README deleted file mode 100644 index ec62798..0000000 --- a/board/freescale/p3060qds/README +++ /dev/null @@ -1,110 +0,0 @@ -Overview -========= -The P3060QDS is a Freescale reference board that hosts the six-core P3060 SOC. - -The P3060 Processor combines six e500mc Power Architecture processor -cores(1.2GHz) with high-performance datapath acceleration -architecture(DPAA), CoreNet fabric infrastructure, as well as network -and peripheral bus interfaces required for networking, telecom/datacom, -wireless infrastructure, and military/aerospace applications. - - -P3060QDS Board Specifications: -============================== -Memory subsystem: - * 2G Bytes UDIMM DDR3(64bit bus) with ECC on - * 128M Bytes NOR flash single-chip memory - * 16M Bytes SPI flash - * 8K Bytes AT24C64 I2C EEPROM for RCW - -Ethernet(Default SERDES 0x19): - * FM1-dTSEC1: connected to RGMII PHY1 (Vitesse VSC8641 on board,Bottom of dual RJ45) - * FM1-dTSEC2: connected to RGMII PHY2 (Vitesse VSC8641 on board,Top of dual RJ45) - * FM1-dTSEC3: connected to SGMII PHY (Vitesse VSC8234 port1 in slot1) - * FM1-dTSEC4: connected to SGMII PHY (Vitesse VSC8234 port3 in slot1) - * FM2-dTSEC1: connected to SGMII PHY (Vitesse VSC8234 port0 in slot2) - * FM2-dTSEC2: connected to SGMII PHY (Vitesse VSC8234 port2 in slot2) - * FM2-dTSEC3: connected to SGMII PHY (Vitesse VSC8234 port0 in slot1) - * FM2-dTSEC4: connected to SGMII PHY (Vitesse VSC8234 port2 in slot1) - -PCIe: - * PCIe1: Lanes A, B, C and D of Bank1 are connected to one x4 PCIe SLOT4 - * PCIe2: Lanes E, F, G and H of Bank1 are connected to one x4 PCIe SLOT3 - -RapidIO: - * sRIO1: Lanes E, F, G and H of Bank1 are connected to sRIO1 (SLOT3) - * sRIO2: Lanes A, B, C and D of Bank1 are connected to sRIO2 (SLOT4) - -USB: - * USB1: connected via an external ULPI PHY SMC3315 to a TYPE-A interface - * USB2: connected via an external ULPI PHY SMC3315 to a TYPE-AB interface - -I2C: - * I2C1_CH0: EEPROM AT24C64(0x50) RCW, AT24C02(0x51) DDR SPD, - AT24C02(0x53) DDR SPD, AT24C02(0x57) SystemID, RTC DS3232(0x68) - * I2C1_CH1: 1588 RiserCard(0x55), HSLB Testport, TempMon - ADT7461(0x4C), SerDesMux DS64MB201(0x51/59/5C/5D) - * I2C1_CH2: VDD/GVDD/GIDD ZL6100 (0x21/0x22/0x23/0x24/0x40) - * I2C1_CH3: OCM CFG AT24C02(0x55), OCM IPL AT24C64(0x56) - * I2C1_CH4: PCIe SLOT1 - * I2C1_CH5: PCIe SLOT2 - * I2C1_CH6: PCIe SLOT3 - * I2C1_CH7: PCIe SLOT4 - * I2C2: NULL - * I2C3: NULL - -UART: - * Supports two UARTs up to 115200 bps for console - - -Boot from NOR flash -=================== -1. Build image - export ARCH=powerpc - export CROSS_COMPILE=/your_path/gcc-4.5.xx-eglibc-2.11.xx/powerpc-linux-gnu/bin/powerpc-linux-gnu- - make P3060QDS_config - make - -2. Program image - => tftp 1000000 u-boot.bin - => protect off all - => erase eff80000 efffffff - => cp.b 1000000 eff80000 80000 - -3. Program RCW - => tftp 1000000 rcw.bin - => protect off all - => erase e8000000 e801ffff - => cp.b 1000000 e8000000 50 - -4. Program FMAN Firmware ucode - => tftp 1000000 ucode.bin - => protect off all - => erase ef000000 ef0fffff - => cp.b 1000000 ef000000 2000 - -5. Change DIP-switch - RCW Location: SW1[1-5] = 01101 (eLBC 16bit NOR flash) - Note: 1 stands for 'on', 0 stands for 'off' - - -Using the Device Tree Source File -================================= -To create the DTB (Device Tree Binary) image file, use a command -similar to this: - dtc -O dtb -b 0 -p 1024 p3060qds.dts > p3060qds.dtb - -Or use the following command: - {linux-2.6}/make p3060qds.dtb ARCH=powerpc - -then the dtb file will be generated under the following directory: - {linux-2.6}/arch/powerpc/boot/p3060qds.dtb - - -Booting Linux -============= -Place a linux uImage in the TFTP disk area. - tftp 1000000 uImage - tftp 2000000 rootfs.ext2.gz.uboot - tftp 3000000 p3060rdb.dtb - bootm 1000000 2000000 3000000 diff --git a/board/freescale/p3060qds/ddr.c b/board/freescale/p3060qds/ddr.c deleted file mode 100644 index 9affbf0..0000000 --- a/board/freescale/p3060qds/ddr.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2009-2011 Freescale Semiconductor, Inc. - * - * 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 <i2c.h> -#include <hwconfig.h> -#include <asm/mmu.h> -#include <asm/fsl_ddr_sdram.h> -#include <asm/fsl_ddr_dimm_params.h> -#include <asm/fsl_law.h> - -#include "p3060qds.h" - -/* - * Fixed sdram init -- doesn't use serial presence detect. - */ - -phys_size_t fixed_sdram(void) -{ - int i; - char buf[32]; - fsl_ddr_cfg_regs_t ddr_cfg_regs; - phys_size_t ddr_size; - unsigned int lawbar1_target_id; - ulong ddr_freq, ddr_freq_mhz; - - ddr_freq = get_ddr_freq(0); - ddr_freq_mhz = ddr_freq / 1000000; - - printf("Configuring DDR for %s MT/s data rate\n", - strmhz(buf, ddr_freq)); - - for (i = 0; fixed_ddr_parm_0[i].max_freq > 0; i++) { - if ((ddr_freq_mhz > fixed_ddr_parm_0[i].min_freq) && - (ddr_freq_mhz <= fixed_ddr_parm_0[i].max_freq)) { - memcpy(&ddr_cfg_regs, - fixed_ddr_parm_0[i].ddr_settings, - sizeof(ddr_cfg_regs)); - break; - } - } - - if (fixed_ddr_parm_0[i].max_freq == 0) - panic("Unsupported DDR data rate %s MT/s data rate\n", - strmhz(buf, ddr_freq)); - - ddr_size = (phys_size_t) CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; - ddr_cfg_regs.ddr_cdr1 = DDR_CDR1_DHC_EN; - fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 0); - - /* - * setup laws for DDR. If not interleaving, presuming half memory on - * DDR1 and the other half on DDR2 - */ - if (fixed_ddr_parm_0[i].ddr_settings->cs[0].config & 0x20000000) { - if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE, - ddr_size, - LAW_TRGT_IF_DDR_INTRLV) < 0) { - printf("ERROR setting Local Access Windows for DDR\n"); - return 0; - } - } else { - lawbar1_target_id = LAW_TRGT_IF_DDR_1; - if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE, - ddr_size, - lawbar1_target_id) < 0) { - printf("ERROR setting Local Access Windows for DDR\n"); - return 0; - } - } - return ddr_size; -} - -struct board_specific_params { - u32 n_ranks; - u32 datarate_mhz_high; - u32 clk_adjust; - u32 wrlvl_start; - u32 cpo; - u32 write_data_delay; - u32 force_2T; -}; - -/* - * This table contains all valid speeds we want to override with board - * specific parameters. datarate_mhz_high values need to be in ascending order - * for each n_ranks group. - */ -static const struct board_specific_params udimm[] = { - /* - * memory controller 0 - * num| hi| clk| wrlvl | cpo |wrdata|2T - * ranks| mhz|adjst| start | |delay | - */ - {4, 850, 4, 6, 0xff, 2, 0}, - {4, 950, 5, 7, 0xff, 2, 0}, - {4, 1050, 5, 8, 0xff, 2, 0}, - {4, 1250, 5, 10, 0xff, 2, 0}, - {4, 1350, 5, 11, 0xff, 2, 0}, - {4, 1666, 5, 12, 0xff, 2, 0}, - {2, 850, 5, 6, 0xff, 2, 0}, - {2, 950, 5, 7, 0xff, 2, 0}, - {2, 1250, 4, 6, 0xff, 2, 0}, - {2, 1350, 5, 7, 0xff, 2, 0}, - {2, 1666, 5, 8, 0xff, 2, 0}, - {1, 850, 4, 5, 0xff, 2, 0}, - {1, 950, 4, 7, 0xff, 2, 0}, - {1, 1666, 4, 8, 0xff, 2, 0}, - {} -}; - -static const struct board_specific_params rdimm[] = { - /* - * memory controller 0 - * num| hi| clk| wrlvl | cpo |wrdata|2T - * ranks| mhz|adjst| start | |delay | - */ - {4, 850, 4, 6, 0xff, 2, 0}, - {4, 950, 5, 7, 0xff, 2, 0}, - {4, 1050, 5, 8, 0xff, 2, 0}, - {4, 1250, 5, 10, 0xff, 2, 0}, - {4, 1350, 5, 11, 0xff, 2, 0}, - {4, 1666, 5, 12, 0xff, 2, 0}, - {2, 850, 4, 6, 0xff, 2, 0}, - {2, 1050, 4, 7, 0xff, 2, 0}, - {2, 1666, 4, 8, 0xff, 2, 0}, - {1, 850, 4, 5, 0xff, 2, 0}, - {1, 950, 4, 7, 0xff, 2, 0}, - {1, 1666, 4, 8, 0xff, 2, 0}, - {} -}; - -void fsl_ddr_board_options(memctl_options_t *popts, - dimm_params_t *pdimm, - unsigned int ctrl_num) -{ - const struct board_specific_params *pbsp, *pbsp_highest = NULL; - ulong ddr_freq; - - if (ctrl_num) { - printf("Wrong parameter for controller number %d", ctrl_num); - return; - } - if (!pdimm->n_ranks) - return; - - if (popts->registered_dimm_en) - pbsp = rdimm; - else - pbsp = udimm; - - /* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr - * freqency and n_banks specified in board_specific_parameters table. - */ - ddr_freq = get_ddr_freq(0) / 1000000; - while (pbsp->datarate_mhz_high) { - if (pbsp->n_ranks == pdimm->n_ranks) { - if (ddr_freq <= pbsp->datarate_mhz_high) { - popts->cpo_override = pbsp->cpo; - popts->write_data_delay = - pbsp->write_data_delay; - popts->clk_adjust = pbsp->clk_adjust; - popts->wrlvl_start = pbsp->wrlvl_start; - popts->twoT_en = pbsp->force_2T; - goto found; - } - pbsp_highest = pbsp; - } - pbsp++; - } - - if (pbsp_highest) { - printf("Error: board specific timing not found " - "for data rate %lu MT/s!\n" - "Trying to use the highest speed (%u) parameters\n", - ddr_freq, pbsp_highest->datarate_mhz_high); - popts->cpo_override = pbsp_highest->cpo; - popts->write_data_delay = pbsp_highest->write_data_delay; - popts->clk_adjust = pbsp_highest->clk_adjust; - popts->wrlvl_start = pbsp_highest->wrlvl_start; - popts->twoT_en = pbsp_highest->force_2T; - } else { - panic("DIMM is not supported by this board"); - } - - -found: - - /* - * The datasheet of HMT125U7BFR8C-H9 blocks CL=7 as reservered. - * However SPD still claims CL=7 is supported. Extensive tests - * confirmed this board cannot work stably with CL=7 with this - * particular DIMM. - */ - if (ddr_freq >= 800 && ddr_freq < 1066 && \ - !strncmp(pdimm[0].mpart, "HMT125U7BFR8C-H9", 16)) { - popts->cas_latency_override = 1; - popts->cas_latency_override_value = 8; - debug("Override CL to 8\n"); - } - /* - * Factors to consider for half-strength driver enable: - * - number of DIMMs installed - */ - popts->half_strength_driver_enable = 0; - /* - * Write leveling override - */ - popts->wrlvl_override = 1; - popts->wrlvl_sample = 0xf; - - /* - * Rtt and Rtt_WR override - */ - popts->rtt_override = 0; - - /* Enable ZQ calibration */ - popts->zq_en = 1; - - /* DHC_EN =1, ODT = 60 Ohm */ - popts->ddr_cdr1 = DDR_CDR1_DHC_EN; -} - -phys_size_t initdram(int board_type) -{ - phys_size_t dram_size; - - puts("Initializing...."); - - if (fsl_use_spd()) { - puts("using SPD\n"); - dram_size = fsl_ddr_sdram(); - } else { - puts("using fixed parameters\n"); - dram_size = fixed_sdram(); - } - - dram_size = setup_ddr_tlbs(dram_size / 0x100000); - dram_size *= 0x100000; - - debug(" DDR: "); - return dram_size; -} diff --git a/board/freescale/p3060qds/eth.c b/board/freescale/p3060qds/eth.c deleted file mode 100644 index 3f812db..0000000 --- a/board/freescale/p3060qds/eth.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <command.h> -#include <netdev.h> -#include <asm/mmu.h> -#include <asm/processor.h> -#include <asm/cache.h> -#include <asm/immap_85xx.h> -#include <asm/fsl_law.h> -#include <asm/fsl_ddr_sdram.h> -#include <asm/fsl_serdes.h> -#include <asm/fsl_portals.h> -#include <asm/fsl_liodn.h> -#include <malloc.h> -#include <fm_eth.h> -#include <fsl_mdio.h> -#include <miiphy.h> -#include <phy.h> -#include <asm/fsl_dtsec.h> - -#include "../common/qixis.h" -#include "../common/fman.h" - -#include "p3060qds_qixis.h" - -#define EMI_NONE 0xffffffff -#define EMI1_RGMII1 0 -#define EMI1_SLOT1 1 -#define EMI1_SLOT2 2 -#define EMI1_SLOT3 3 -#define EMI1_RGMII2 4 - -static int mdio_mux[NUM_FM_PORTS]; - -static char *mdio_names[5] = { - "P3060QDS_MDIO0", - "P3060QDS_MDIO1", - "P3060QDS_MDIO2", - "P3060QDS_MDIO3", - "P3060QDS_MDIO4", -}; - -/* - * Mapping of all 18 SERDES lanes to board slots. - * A value of '0' here means that the mapping must be determined - * dynamically, Lane 8/9/16/17 map to Slot1 or Aurora debug - */ -static u8 lane_to_slot[] = { - 4, 4, 4, 4, 3, 3, 3, 3, 0, 0, 2, 2, 2, 2, 1, 1, 0, 0 -}; - -static char *p3060qds_mdio_name_for_muxval(u32 muxval) -{ - return mdio_names[muxval]; -} - -struct mii_dev *mii_dev_for_muxval(u32 muxval) -{ - struct mii_dev *bus; - char *name = p3060qds_mdio_name_for_muxval(muxval); - - if (!name) { - printf("No bus for muxval %x\n", muxval); - return NULL; - } - - bus = miiphy_get_dev_by_name(name); - - if (!bus) { - printf("No bus by name %s\n", name); - return NULL; - } - - return bus; -} - -struct p3060qds_mdio { - u32 muxval; - struct mii_dev *realbus; -}; - -static void p3060qds_mux_mdio(u32 muxval) -{ - u8 brdcfg4; - - brdcfg4 = QIXIS_READ(brdcfg[4]); - brdcfg4 &= ~BRDCFG4_EMISEL_MASK; - brdcfg4 |= (muxval << 4); - QIXIS_WRITE(brdcfg[4], brdcfg4); -} - -static int p3060qds_mdio_read(struct mii_dev *bus, int addr, int devad, - int regnum) -{ - struct p3060qds_mdio *priv = bus->priv; - - p3060qds_mux_mdio(priv->muxval); - - return priv->realbus->read(priv->realbus, addr, devad, regnum); -} - -static int p3060qds_mdio_write(struct mii_dev *bus, int addr, int devad, - int regnum, u16 value) -{ - struct p3060qds_mdio *priv = bus->priv; - - p3060qds_mux_mdio(priv->muxval); - - return priv->realbus->write(priv->realbus, addr, devad, regnum, value); -} - -static int p3060qds_mdio_reset(struct mii_dev *bus) -{ - struct p3060qds_mdio *priv = bus->priv; - - return priv->realbus->reset(priv->realbus); -} - -static int p3060qds_mdio_init(char *realbusname, u32 muxval) -{ - struct p3060qds_mdio *pmdio; - struct mii_dev *bus = mdio_alloc(); - - if (!bus) { - printf("Failed to allocate P3060QDS MDIO bus\n"); - return -1; - } - - pmdio = malloc(sizeof(*pmdio)); - if (!pmdio) { - printf("Failed to allocate P3060QDS private data\n"); - free(bus); - return -1; - } - - bus->read = p3060qds_mdio_read; - bus->write = p3060qds_mdio_write; - bus->reset = p3060qds_mdio_reset; - sprintf(bus->name, p3060qds_mdio_name_for_muxval(muxval)); - - pmdio->realbus = miiphy_get_dev_by_name(realbusname); - - if (!pmdio->realbus) { - printf("No bus with name %s\n", realbusname); - free(bus); - free(pmdio); - return -1; - } - - pmdio->muxval = muxval; - bus->priv = pmdio; - - return mdio_register(bus); -} - -void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, - enum fm_port port, int offset) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - int srds_prtcl = (in_be32(&gur->rcwsr[4]) & - FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; - - if (mdio_mux[port] == EMI1_RGMII1) - fdt_set_phy_handle(blob, prop, pa, "phy_rgmii1"); - - if (mdio_mux[port] == EMI1_RGMII2) - fdt_set_phy_handle(blob, prop, pa, "phy_rgmii2"); - - if ((mdio_mux[port] == EMI1_SLOT1) && ((srds_prtcl == 0x3) - || (srds_prtcl == 0x6))) { - switch (port) { - case FM2_DTSEC4: - fdt_set_phy_handle(blob, prop, pa, "phy2_slot1"); - break; - case FM1_DTSEC4: - fdt_set_phy_handle(blob, prop, pa, "phy3_slot1"); - break; - default: - break; - } - } - - if (mdio_mux[port] == EMI1_SLOT3) { - switch (port) { - case FM2_DTSEC3: - fdt_set_phy_handle(blob, prop, pa, "phy0_slot3"); - break; - case FM1_DTSEC3: - fdt_set_phy_handle(blob, prop, pa, "phy1_slot3"); - break; - default: - break; - } - } -} - -void fdt_fixup_board_enet(void *fdt) -{ - int i, lane, idx; - - for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { - idx = i - FM1_DTSEC1; - switch (fm_info_get_enet_if(i)) { - case PHY_INTERFACE_MODE_SGMII: - lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx); - if (lane < 0) - break; - - switch (mdio_mux[i]) { - case EMI1_SLOT1: - if (lane >= 14) { - fdt_status_okay_by_alias(fdt, - "emi1_slot1"); - fdt_status_disabled_by_alias(fdt, - "emi1_slot1_bk1"); - } else { - fdt_status_disabled_by_alias(fdt, - "emi1_slot1"); - fdt_status_okay_by_alias(fdt, - "emi1_slot1_bk1"); - } - break; - case EMI1_SLOT2: - fdt_status_okay_by_alias(fdt, "emi1_slot2"); - break; - case EMI1_SLOT3: - fdt_status_okay_by_alias(fdt, "emi1_slot3"); - break; - } - break; - case PHY_INTERFACE_MODE_RGMII: - if (i == FM1_DTSEC1) - fdt_status_okay_by_alias(fdt, "emi1_rgmii1"); - - if (i == FM1_DTSEC2) - fdt_status_okay_by_alias(fdt, "emi1_rgmii2"); - break; - default: - break; - } - } -#if (CONFIG_SYS_NUM_FMAN == 2) - for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) { - idx = i - FM2_DTSEC1; - switch (fm_info_get_enet_if(i)) { - case PHY_INTERFACE_MODE_SGMII: - lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx); - if (lane >= 0) { - switch (mdio_mux[i]) { - case EMI1_SLOT1: - if (lane >= 14) - fdt_status_okay_by_alias(fdt, - "emi1_slot1"); - else - fdt_status_okay_by_alias(fdt, - "emi1_slot1_bk1"); - break; - case EMI1_SLOT2: - fdt_status_okay_by_alias(fdt, - "emi1_slot2"); - break; - case EMI1_SLOT3: - fdt_status_okay_by_alias(fdt, - "emi1_slot3"); - break; - } - } - break; - default: - break; - } - } -#endif -} - -static void initialize_lane_to_slot(void) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - int sdprtl = (in_be32(&gur->rcwsr[4]) & - FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; - - switch (sdprtl) { - case 0x03: - case 0x06: - lane_to_slot[8] = 1; - lane_to_slot[9] = lane_to_slot[8]; - lane_to_slot[16] = 5; - lane_to_slot[17] = lane_to_slot[16]; - break; - case 0x16: - case 0x19: - case 0x1C: - lane_to_slot[8] = 5; - lane_to_slot[9] = lane_to_slot[8]; - lane_to_slot[16] = 1; - lane_to_slot[17] = lane_to_slot[16]; - break; - default: - puts("Invalid SerDes protocol for P3060QDS\n"); - break; - } -} - -int board_eth_init(bd_t *bis) -{ -#ifdef CONFIG_FMAN_ENET - struct dtsec *tsec = (void *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR; - int i; - struct fsl_pq_mdio_info dtsec_mdio_info; - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - int srds_cfg = (in_be32(&gur->rcwsr[4]) & - FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; - - initialize_lane_to_slot(); - - /* - * Set TBIPA on FM1@DTSEC1. This is needed for configurations - * where FM1@DTSEC1 isn't used directly, since it provides - * MDIO for other ports. - */ - out_be32(&tsec->tbipa, CONFIG_SYS_TBIPA_VALUE); - - /* Initialize the mdio_mux array so we can recognize empty elements */ - for (i = 0; i < NUM_FM_PORTS; i++) - mdio_mux[i] = EMI_NONE; - - dtsec_mdio_info.regs = - (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR; - dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME; - - /* Register the 1G MDIO bus */ - fsl_pq_mdio_init(bis, &dtsec_mdio_info); - - /* Register the 5 muxing front-ends to the MDIO buses */ - if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_RGMII) - p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1); - - if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_RGMII) - p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2); - p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1); - p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2); - p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3); - - if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_RGMII) - fm_info_set_phy_address(FM1_DTSEC1, 1); /* RGMII1 */ - else if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_SGMII) - fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT2_PHY_ADDR); - - if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_RGMII) - fm_info_set_phy_address(FM1_DTSEC2, 2); /* RGMII2 */ - else if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_SGMII) - fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR); - - fm_info_set_phy_address(FM2_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR); - fm_info_set_phy_address(FM2_DTSEC2, SGMII_CARD_PORT3_PHY_ADDR); - - switch (srds_cfg) { - case 0x03: - case 0x06: - fm_info_set_phy_address(FM2_DTSEC3, SGMII_CARD_PORT3_PHY_ADDR); - fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT4_PHY_ADDR); - fm_info_set_phy_address(FM2_DTSEC4, SGMII_CARD_PORT1_PHY_ADDR); - fm_info_set_phy_address(FM1_DTSEC4, SGMII_CARD_PORT2_PHY_ADDR); - break; - case 0x16: - case 0x19: - case 0x1C: - fm_info_set_phy_address(FM2_DTSEC3, SGMII_CARD_PORT1_PHY_ADDR); - fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT2_PHY_ADDR); - fm_info_set_phy_address(FM2_DTSEC4, SGMII_CARD_PORT3_PHY_ADDR); - fm_info_set_phy_address(FM1_DTSEC4, SGMII_CARD_PORT4_PHY_ADDR); - break; - default: - puts("Invalid SerDes protocol for P3060QDS\n"); - break; - } - - for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { - int idx = i - FM1_DTSEC1, lane, slot; - switch (fm_info_get_enet_if(i)) { - case PHY_INTERFACE_MODE_SGMII: - lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx); - if (lane < 0) - break; - slot = lane_to_slot[lane]; - if (QIXIS_READ(present) & (1 << (slot - 1))) - fm_disable_port(i); - switch (slot) { - case 1: - mdio_mux[i] = EMI1_SLOT1; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - break; - case 2: - mdio_mux[i] = EMI1_SLOT2; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - break; - case 3: - mdio_mux[i] = EMI1_SLOT3; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - break; - }; - break; - case PHY_INTERFACE_MODE_RGMII: - if (i == FM1_DTSEC1) { - mdio_mux[i] = EMI1_RGMII1; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - } else if (i == FM1_DTSEC2) { - mdio_mux[i] = EMI1_RGMII2; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - } - break; - default: - break; - } - } - -#if (CONFIG_SYS_NUM_FMAN == 2) - for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) { - int idx = i - FM2_DTSEC1, lane, slot; - switch (fm_info_get_enet_if(i)) { - case PHY_INTERFACE_MODE_SGMII: - lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx); - if (lane < 0) - break; - slot = lane_to_slot[lane]; - if (QIXIS_READ(present) & (1 << (slot - 1))) - fm_disable_port(i); - switch (slot) { - case 1: - mdio_mux[i] = EMI1_SLOT1; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - break; - case 2: - mdio_mux[i] = EMI1_SLOT2; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - break; - case 3: - mdio_mux[i] = EMI1_SLOT3; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - break; - }; - break; - default: - break; - } - } -#endif /* CONFIG_SYS_NUM_FMAN */ - - cpu_eth_init(bis); -#endif /* CONFIG_FMAN_ENET */ - - return pci_eth_init(bis); -} diff --git a/board/freescale/p3060qds/fixed_ddr.c b/board/freescale/p3060qds/fixed_ddr.c deleted file mode 100644 index 125988d..0000000 --- a/board/freescale/p3060qds/fixed_ddr.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2009-2011 Freescale Semiconductor, Inc. - * - * 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 <asm/fsl_ddr_sdram.h> - -#define CONFIG_SYS_DDR_TIMING_3_1200 0x01030000 -#define CONFIG_SYS_DDR_TIMING_0_1200 0xCC550104 -#define CONFIG_SYS_DDR_TIMING_1_1200 0x868FAA45 -#define CONFIG_SYS_DDR_TIMING_2_1200 0x0FB8A912 -#define CONFIG_SYS_DDR_MODE_1_1200 0x00441A40 -#define CONFIG_SYS_DDR_MODE_2_1200 0x00100000 -#define CONFIG_SYS_DDR_INTERVAL_1200 0x12480100 -#define CONFIG_SYS_DDR_CLK_CTRL_1200 0x02800000 - -#define CONFIG_SYS_DDR_TIMING_3_1000 0x00020000 -#define CONFIG_SYS_DDR_TIMING_0_1000 0xCC440104 -#define CONFIG_SYS_DDR_TIMING_1_1000 0x727DF944 -#define CONFIG_SYS_DDR_TIMING_2_1000 0x0FB088CF -#define CONFIG_SYS_DDR_MODE_1_1000 0x00441830 -#define CONFIG_SYS_DDR_MODE_2_1000 0x00080000 -#define CONFIG_SYS_DDR_INTERVAL_1000 0x0F3C0100 -#define CONFIG_SYS_DDR_CLK_CTRL_1000 0x02800000 - -#define CONFIG_SYS_DDR_TIMING_3_900 0x00020000 -#define CONFIG_SYS_DDR_TIMING_0_900 0xCC440104 -#define CONFIG_SYS_DDR_TIMING_1_900 0x616ba844 -#define CONFIG_SYS_DDR_TIMING_2_900 0x0fb088ce -#define CONFIG_SYS_DDR_MODE_1_900 0x00441620 -#define CONFIG_SYS_DDR_MODE_2_900 0x00080000 -#define CONFIG_SYS_DDR_INTERVAL_900 0x0db60100 -#define CONFIG_SYS_DDR_CLK_CTRL_900 0x02800000 - -#define CONFIG_SYS_DDR_TIMING_3_800 0x00020000 -#define CONFIG_SYS_DDR_TIMING_0_800 0xcc330104 -#define CONFIG_SYS_DDR_TIMING_1_800 0x6f6b4744 -#define CONFIG_SYS_DDR_TIMING_2_800 0x0fa888cc -#define CONFIG_SYS_DDR_MODE_1_800 0x00441420 -#define CONFIG_SYS_DDR_MODE_2_800 0x00000000 -#define CONFIG_SYS_DDR_INTERVAL_800 0x0c300100 -#define CONFIG_SYS_DDR_CLK_CTRL_800 0x02800000 - -#define CONFIG_SYS_DDR_CS0_BNDS 0x000000FF -#define CONFIG_SYS_DDR_CS1_BNDS 0x00000000 -#define CONFIG_SYS_DDR_CS2_BNDS 0x000000FF -#define CONFIG_SYS_DDR_CS3_BNDS 0x000000FF -#define CONFIG_SYS_DDR2_CS0_BNDS 0x000000FF -#define CONFIG_SYS_DDR2_CS1_BNDS 0x00000000 -#define CONFIG_SYS_DDR2_CS2_BNDS 0x000000FF -#define CONFIG_SYS_DDR2_CS3_BNDS 0x000000FF -#define CONFIG_SYS_DDR_CS0_CONFIG 0xA0044202 -#define CONFIG_SYS_DDR_CS0_CONFIG_2 0x00000000 -#define CONFIG_SYS_DDR_CS1_CONFIG 0x80004202 -#define CONFIG_SYS_DDR_CS2_CONFIG 0x00000000 -#define CONFIG_SYS_DDR_CS3_CONFIG 0x00000000 -#define CONFIG_SYS_DDR2_CS0_CONFIG 0x80044202 -#define CONFIG_SYS_DDR2_CS1_CONFIG 0x80004202 -#define CONFIG_SYS_DDR2_CS2_CONFIG 0x00000000 -#define CONFIG_SYS_DDR2_CS3_CONFIG 0x00000000 -#define CONFIG_SYS_DDR_INIT_ADDR 0x00000000 -#define CONFIG_SYS_DDR_INIT_EXT_ADDR 0x00000000 -#define CONFIG_SYS_DDR_CS1_CONFIG 0x80004202 -#define CONFIG_SYS_DDR_DATA_INIT 0xdeadbeef -#define CONFIG_SYS_DDR_TIMING_4 0x00000001 -#define CONFIG_SYS_DDR_TIMING_5 0x02401400 -#define CONFIG_SYS_DDR_MODE_CONTROL 0x00000000 -#define CONFIG_SYS_DDR_ZQ_CNTL 0x89080600 -#define CONFIG_SYS_DDR_WRLVL_CNTL 0x8675F607 -#define CONFIG_SYS_DDR_SDRAM_CFG 0xE7044000 -#define CONFIG_SYS_DDR_SDRAM_CFG2 0x24401031 -#define CONFIG_SYS_DDR_RCW_1 0x00000000 -#define CONFIG_SYS_DDR_RCW_2 0x00000000 -#define CONFIG_MEM_INIT_VALUE 0xdeadbeef - -fsl_ddr_cfg_regs_t ddr_cfg_regs_800 = { - .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, - .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, - .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS, - .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS, - .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, - .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, - .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, - .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG, - .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG, - .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_800, - .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_800, - .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_800, - .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_800, - .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG, - .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2, - .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_800, - .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_800, - .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, - .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_800, - .ddr_data_init = CONFIG_MEM_INIT_VALUE, - .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_800, - .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, - .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, - .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, - .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, - .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL, - .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL, - .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, - .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 -}; - -fsl_ddr_cfg_regs_t ddr_cfg_regs_900 = { - .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, - .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, - .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS, - .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS, - .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, - .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, - .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, - .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG, - .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG, - .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_900, - .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_900, - .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_900, - .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_900, - .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG, - .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2, - .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_900, - .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_900, - .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, - .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_900, - .ddr_data_init = CONFIG_MEM_INIT_VALUE, - .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_900, - .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, - .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, - .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, - .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, - .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL, - .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL, - .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, - .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 -}; - -fsl_ddr_cfg_regs_t ddr_cfg_regs_1000 = { - .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, - .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, - .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS, - .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS, - .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, - .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, - .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, - .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG, - .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG, - .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_1000, - .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_1000, - .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_1000, - .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_1000, - .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG, - .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2, - .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_1000, - .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_1000, - .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, - .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_1000, - .ddr_data_init = CONFIG_MEM_INIT_VALUE, - .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_1000, - .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, - .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, - .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, - .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, - .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL, - .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL, - .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, - .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 -}; - -fsl_ddr_cfg_regs_t ddr_cfg_regs_1200 = { - .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, - .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, - .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS, - .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS, - .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, - .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, - .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, - .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG, - .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG, - .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_1200, - .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_1200, - .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_1200, - .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_1200, - .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG, - .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2, - .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_1200, - .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_1200, - .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, - .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_1200, - .ddr_data_init = CONFIG_MEM_INIT_VALUE, - .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_1200, - .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, - .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, - .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, - .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, - .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL, - .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL, - .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, - .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 -}; - -fixed_ddr_parm_t fixed_ddr_parm_0[] = { - {750, 850, &ddr_cfg_regs_800}, - {850, 950, &ddr_cfg_regs_900}, - {950, 1050, &ddr_cfg_regs_1000}, - {1050, 1250, &ddr_cfg_regs_1200}, - {0, 0, NULL} -}; diff --git a/board/freescale/p3060qds/p3060qds.c b/board/freescale/p3060qds/p3060qds.c deleted file mode 100644 index 43e7f28..0000000 --- a/board/freescale/p3060qds/p3060qds.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright 2011-2012 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <command.h> -#include <netdev.h> -#include <linux/compiler.h> -#include <asm/mmu.h> -#include <asm/processor.h> -#include <asm/cache.h> -#include <asm/immap_85xx.h> -#include <asm/fsl_law.h> -#include <asm/fsl_serdes.h> -#include <asm/fsl_portals.h> -#include <asm/fsl_liodn.h> -#include <fm_eth.h> -#include <configs/P3060QDS.h> -#include <libfdt.h> -#include <fdt_support.h> - -#include "../common/qixis.h" -#include "p3060qds.h" -#include "p3060qds_qixis.h" - -DECLARE_GLOBAL_DATA_PTR; - -int checkboard(void) -{ - u8 sw; - struct cpu_type *cpu = gd->cpu; - ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; - unsigned int i; - - printf("Board: %s", cpu->name); - puts("QDS, "); - - printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ", - QIXIS_READ(id), QIXIS_READ(arch), QIXIS_READ(scver)); - - sw = QIXIS_READ(brdcfg[0]); - sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT; - - if (sw < 0x8) - printf("vBank: %d\n", sw); - else if (sw == 0x8) - puts("Promjet\n"); - else if (sw == 0x9) - puts("NAND\n"); - else - printf("invalid setting of SW%u\n", PIXIS_LBMAP_SWITCH); - - puts("Reset Configuration Word (RCW):"); - for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) { - u32 rcw = in_be32(&gur->rcwsr[i]); - - if ((i % 4) == 0) - printf("\n %08x:", i * 4); - printf(" %08x", rcw); - } - puts("\n"); - - puts("SERDES Reference Clocks: "); - sw = QIXIS_READ(brdcfg[2]); - for (i = 0; i < 3; i++) { - static const char * const freq[] = {"100", "125", "Reserved", - "156.25"}; - unsigned int clock = (sw >> (2 * i)) & 3; - - printf("Bank%u=%sMhz ", i+1, freq[clock]); - } - puts("\n"); - - return 0; -} - -int board_early_init_f(void) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - /* only single DDR controller on QDS board, disable DDR1_MCK4/5 */ - setbits_be32(&gur->ddrclkdr, 0x00030000); - - return 0; -} - -void board_config_serdes_mux(void) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - int cfg = (in_be32(&gur->rcwsr[4]) & - FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; - - switch (cfg) { - case 0x03: - case 0x06: - /* set Lane I,J as SGMII */ - QIXIS_WRITE(brdcfg[6], BRDCFG6_SD4MX_B | BRDCFG6_SD3MX_A | - BRDCFG6_SD2MX_B | BRDCFG6_SD1MX_A); - break; - case 0x16: - case 0x19: - case 0x1c: - /* set Lane I,J as Aurora Debug */ - QIXIS_WRITE(brdcfg[6], BRDCFG6_SD4MX_A | BRDCFG6_SD3MX_B | - BRDCFG6_SD2MX_A | BRDCFG6_SD1MX_B); - break; - default: - puts("Invalid SerDes protocol for P3060QDS\n"); - break; - } -} - -void board_config_usb_mux(void) -{ - u8 brdcfg4, brdcfg5, brdcfg7; - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 rcwsr11 = in_be32(&gur->rcwsr[11]); - u32 ec1 = rcwsr11 & FSL_CORENET_RCWSR11_EC1; - u32 ec2 = rcwsr11 & FSL_CORENET_RCWSR11_EC2; - - brdcfg4 = QIXIS_READ(brdcfg[4]); - brdcfg4 &= ~BRDCFG4_EC_MODE_MASK; - if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_USB1) && - (ec2 == FSL_CORENET_RCWSR11_EC2_USB2)) { - brdcfg4 |= BRDCFG4_EC2_USB_EC1_USB; - - } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_USB1) && - ((ec2 == FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) || - (ec2 == FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1))) { - brdcfg4 |= BRDCFG4_EC2_RGMII_EC1_USB; - - } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1) && - (ec2 == FSL_CORENET_RCWSR11_EC2_USB2)) { - brdcfg4 |= BRDCFG4_EC2_USB_EC1_RGMII; - - } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1) && - ((ec2 == FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) || - (ec2 == FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1))) { - brdcfg4 |= BRDCFG4_EC2_RGMII_EC1_RGMII; - } else { - brdcfg4 |= BRDCFG4_EC2_MII_EC1_MII; - } - QIXIS_WRITE(brdcfg[4], brdcfg4); - - brdcfg5 = QIXIS_READ(brdcfg[5]); - brdcfg5 &= ~(BRDCFG5_USB1ID_MASK | BRDCFG5_USB2ID_MASK); - brdcfg5 |= (BRDCFG5_USB1ID_CTRL | BRDCFG5_USB2ID_CTRL); - QIXIS_WRITE(brdcfg[5], brdcfg5); - - brdcfg7 = BRDCFG7_JTAGMX_COP_JTAG | BRDCFG7_IQ1MX_IRQ_EVT | - BRDCFG7_G1MX_USB1 | BRDCFG7_D1MX_TSEC3USB | BRDCFG7_I3MX_USB1; - QIXIS_WRITE(brdcfg[7], brdcfg7); -} - -int board_early_init_r(void) -{ - const unsigned int flashbase = CONFIG_SYS_FLASH_BASE; - const u8 flash_esel = find_tlb_idx((void *)flashbase, 1); - - /* - * Remap Boot flash + PROMJET region to caching-inhibited - * so that flash can be erased properly. - */ - - /* Flush d-cache and invalidate i-cache of any FLASH data */ - flush_dcache(); - invalidate_icache(); - - /* invalidate existing TLB entry for flash + promjet */ - disable_tlb(flash_esel); - - set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, flash_esel, BOOKE_PAGESZ_256M, 1); - - set_liodns(); -#ifdef CONFIG_SYS_DPAA_QBMAN - setup_portals(); -#endif - board_config_serdes_mux(); - board_config_usb_mux(); - - return 0; -} - -static const char *serdes_clock_to_string(u32 clock) -{ - switch (clock) { - case SRDS_PLLCR0_RFCK_SEL_100: - return "100"; - case SRDS_PLLCR0_RFCK_SEL_125: - return "125"; - case SRDS_PLLCR0_RFCK_SEL_156_25: - return "156.25"; - default: - return "150"; - } -} - -#define NUM_SRDS_BANKS 3 - -int misc_init_r(void) -{ - serdes_corenet_t *srds_regs; - u32 actual[NUM_SRDS_BANKS]; - unsigned int i; - u8 sw; - - sw = QIXIS_READ(brdcfg[2]); - for (i = 0; i < 3; i++) { - unsigned int clock = (sw >> (2 * i)) & 3; - switch (clock) { - case 0: - actual[i] = SRDS_PLLCR0_RFCK_SEL_100; - break; - case 1: - actual[i] = SRDS_PLLCR0_RFCK_SEL_125; - break; - case 3: - actual[i] = SRDS_PLLCR0_RFCK_SEL_156_25; - break; - default: - printf("Warning: SDREFCLK%u switch setting of '10' is " - "unsupported\n", i + 1); - break; - } - } - - srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; - for (i = 0; i < NUM_SRDS_BANKS; i++) { - u32 pllcr0 = in_be32(&srds_regs->bank[i].pllcr0); - u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK; - if (expected != actual[i]) { - printf("Warning: SERDES bank %u expects reference clock" - " %sMHz, but actual is %sMHz\n", i + 1, - serdes_clock_to_string(expected), - serdes_clock_to_string(actual[i])); - } - } - - return 0; -} - -/* - * This is map of CVDD values. 33 means CVDD is 3.3v, 25 means CVDD is 2.5v, - * 18 means CVDD is 1.8v. - */ -static u8 IO_VSEL[] = { - 33, 33, 33, 25, 25, 25, 18, 18, 18, - 33, 33, 33, 25, 25, 25, 18, 18, 18, - 33, 33, 33, 25, 25, 25, 18, 18, 18, - 33, 33, 33, 33, 33 -}; - -#define IO_VSEL_MASK 0x1f - -/* - * different CVDD selects diffenert spi flashs, read dutcfg[3] to get CVDD, - * then set status of spi flash nodes to 'disabled' according to CVDD. - * CVDD '33' will select spi flash0 and flash1, CVDD '25' will select spi - * flash2, CVDD '18' will select spi flash3. - */ -void fdt_fixup_board_spi(void *blob) -{ - u8 sw5 = QIXIS_READ(dutcfg[3]); - - switch (IO_VSEL[sw5 & IO_VSEL_MASK]) { - /* 3.3v */ - case 33: - do_fixup_by_compat(blob, "atmel,at45db081d", "status", - "disabled", strlen("disabled") + 1, 1); - do_fixup_by_compat(blob, "spansion,sst25wf040", "status", - "disabled", strlen("disabled") + 1, 1); - break; - /* 2.5v */ - case 25: - do_fixup_by_compat(blob, "spansion,s25sl12801", "status", - "disabled", strlen("disabled") + 1, 1); - do_fixup_by_compat(blob, "spansion,en25q32", "status", - "disabled", strlen("disabled") + 1, 1); - do_fixup_by_compat(blob, "spansion,sst25wf040", "status", - "disabled", strlen("disabled") + 1, 1); - break; - /* 1.8v */ - case 18: - do_fixup_by_compat(blob, "spansion,s25sl12801", "status", - "disabled", strlen("disabled") + 1, 1); - do_fixup_by_compat(blob, "spansion,en25q32", "status", - "disabled", strlen("disabled") + 1, 1); - do_fixup_by_compat(blob, "atmel,at45db081d", "status", - "disabled", strlen("disabled") + 1, 1); - break; - } -} - -void ft_board_setup(void *blob, bd_t *bd) -{ - phys_addr_t base; - phys_size_t size; - - ft_cpu_setup(blob, bd); - - base = getenv_bootm_low(); - size = getenv_bootm_size(); - - fdt_fixup_memory(blob, (u64)base, (u64)size); - -#if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_MPH_USB) - fdt_fixup_dr_usb(blob, bd); -#endif - -#ifdef CONFIG_PCI - pci_of_setup(blob, bd); -#endif - - fdt_fixup_liodn(blob); - fdt_fixup_dr_usb(blob, bd); - fdt_fixup_board_spi(blob); - -#ifdef CONFIG_SYS_DPAA_FMAN - fdt_fixup_fman_ethernet(blob); - fdt_fixup_board_enet(blob); -#endif -} diff --git a/board/freescale/p3060qds/p3060qds_qixis.h b/board/freescale/p3060qds/p3060qds_qixis.h deleted file mode 100644 index 4d5d6a2..0000000 --- a/board/freescale/p3060qds/p3060qds_qixis.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef __P3060QDS_QIXIS_H__ -#define __P3060QDS_QIXIS_H__ - -/* Definitions of QIXIS Registers for P3060QDS */ - -/* BRDCFG4[4:7]] select EC1 and EC2 as a pair */ -#define BRDCFG4_EC_MODE_MASK 0x0F -#define BRDCFG4_EC2_MII_EC1_MII 0x00 -#define BRDCFG4_EC2_MII_EC1_USB 0x03 -#define BRDCFG4_EC2_USB_EC1_MII 0x0C -#define BRDCFG4_EC2_USB_EC1_USB 0x0F -#define BRDCFG4_EC2_USB_EC1_RGMII 0x0E -#define BRDCFG4_EC2_RGMII_EC1_USB 0x0B -#define BRDCFG4_EC2_RGMII_EC1_RGMII 0x0A -#define BRDCFG4_EMISEL_MASK 0xF0 - -#define BRDCFG5_ECLKS_MASK 0x80 -#define BRDCFG5_USB1ID_MASK 0x40 -#define BRDCFG5_USB2ID_MASK 0x20 -#define BRDCFG5_GC2MX_MASK 0x0C -#define BRDCFG5_T15MX_MASK 0x03 -#define BRDCFG5_ECLKS_IEEE1588_CM 0x80 -#define BRDCFG5_USB1ID_CTRL 0x40 -#define BRDCFG5_USB2ID_CTRL 0x20 - -#define BRDCFG6_SD1MX_A 0x01 -#define BRDCFG6_SD1MX_B 0x00 -#define BRDCFG6_SD2MX_A 0x02 -#define BRDCFG6_SD2MX_B 0x00 -#define BRDCFG6_SD3MX_A 0x04 -#define BRDCFG6_SD3MX_B 0x00 -#define BRDCFG6_SD4MX_A 0x08 -#define BRDCFG6_SD4MX_B 0x00 - -#define BRDCFG7_JTAGMX_MASK 0xC0 -#define BRDCFG7_IQ1MX_MASK 0x20 -#define BRDCFG7_G1MX_MASK 0x10 -#define BRDCFG7_D1MX_MASK 0x0C -#define BRDCFG7_I3MX_MASK 0x03 -#define BRDCFG7_JTAGMX_AURORA 0x00 -#define BRDCFG7_JTAGMX_FPGA 0x80 -#define BRDCFG7_JTAGMX_COP_JTAG 0xC0 -#define BRDCFG7_IQ1MX_IRQ_EVT 0x00 -#define BRDCFG7_IQ1MX_USB2 0x20 -#define BRDCFG7_G1MX_USB1 0x00 -#define BRDCFG7_G1MX_TSEC3 0x10 -#define BRDCFG7_D1MX_DMA 0x00 -#define BRDCFG7_D1MX_TSEC3USB 0x04 -#define BRDCFG7_D1MX_HDLC2 0x08 -#define BRDCFG7_I3MX_UART2_I2C34 0x00 -#define BRDCFG7_I3MX_GPIO_EVT 0x01 -#define BRDCFG7_I3MX_USB1 0x02 -#define BRDCFG7_I3MX_TSEC3 0x03 - -#endif diff --git a/board/mcc200/lcd.c b/board/mcc200/lcd.c index d8f754c..893f4b7 100644 --- a/board/mcc200/lcd.c +++ b/board/mcc200/lcd.c @@ -21,6 +21,7 @@ #include <common.h> #include <lcd.h> #include <mpc5xxx.h> +#include <malloc.h> #ifdef CONFIG_LCD @@ -210,4 +211,23 @@ void show_progress (int size, int tot) } #endif + +int bmp_display(ulong addr, int x, int y) +{ + int ret; + bmp_image_t *bmp = (bmp_image_t *)addr; + + if (!bmp) { + printf("There is no valid bmp file at the given address\n"); + return 1; + } + + ret = lcd_display_bitmap((ulong)bmp, x, y); + + if ((unsigned long)bmp != addr) + free(bmp); + + return ret; +} + #endif /* CONFIG_LCD */ diff --git a/board/overo/overo.c b/board/overo/overo.c index f973870..c6d50a0 100644 --- a/board/overo/overo.c +++ b/board/overo/overo.c @@ -101,16 +101,6 @@ int board_init(void) } /* - * Routine: omap_rev_string - * Description: For SPL builds output board rev - */ -#ifdef CONFIG_SPL_BUILD -void omap_rev_string(void) -{ -} -#endif - -/* * Routine: get_board_revision * Description: Returns the board revision */ diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c index 3583d01..d975209 100644 --- a/board/qi/qi_lb60/qi_lb60.c +++ b/board/qi/qi_lb60/qi_lb60.c @@ -69,7 +69,7 @@ static void gpio_init(void) static void cpm_init(void) { struct jz4740_cpm *cpm = (struct jz4740_cpm *)JZ4740_CPM_BASE; - uint32_t reg = readw(&cpm->clkgr); + uint32_t reg = readl(&cpm->clkgr); reg |= CPM_CLKGR_IPU | CPM_CLKGR_CIM | @@ -81,7 +81,7 @@ static void cpm_init(void) CPM_CLKGR_UDC | CPM_CLKGR_AIC1; - writew(reg, &cpm->clkgr); + writel(reg, &cpm->clkgr); } int board_early_init_f(void) diff --git a/board/freescale/p3060qds/Makefile b/board/samsung/common/Makefile index ae136f4..0bcd594 100644 --- a/board/freescale/p3060qds/Makefile +++ b/board/samsung/common/Makefile @@ -1,7 +1,6 @@ # -# Copyright 2011 Freescale Semiconductor, Inc. -# (C) Copyright 2001-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# Copyright (C) 2012 Samsung Electronics +# Lukasz Majewski <l.majewski@samsung.com> # # See file CREDITS for list of people who contributed to this # project. @@ -24,26 +23,16 @@ include $(TOPDIR)/config.mk -LIB = $(obj)lib$(BOARD).o +LIB = $(obj)libsamsung.o -COBJS-y += $(BOARD).o -COBJS-y += ddr.o -COBJS-y += eth.o -COBJS-y += fixed_ddr.o +COBJS-$(CONFIG_SOFT_I2C_MULTI_BUS) += multi_i2c.o -SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +SRCS := $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) -SOBJS := $(addprefix $(obj),$(SOBJS)) -$(LIB): $(obj).depend $(OBJS) $(SOBJS) +$(LIB): $(obj).depend $(OBJS) $(call cmd_link_o_target, $(OBJS)) -clean: - rm -f $(OBJS) $(SOBJS) - -distclean: clean - rm -f $(LIB) core *.bak .depend - ######################################################################### # defines $(obj).depend target diff --git a/board/samsung/common/multi_i2c.c b/board/samsung/common/multi_i2c.c new file mode 100644 index 0000000..d6c3d37 --- /dev/null +++ b/board/samsung/common/multi_i2c.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Lukasz Majewski <l.majewski@samsung.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <i2c.h> + +/* Handle multiple I2C buses instances */ +int get_multi_scl_pin(void) +{ + unsigned int bus = I2C_GET_BUS(); + + switch (bus) { + case I2C_0: /* I2C_0 definition - compatibility layer */ + case I2C_5: + return CONFIG_SOFT_I2C_I2C5_SCL; + case I2C_9: + return CONFIG_SOFT_I2C_I2C9_SCL; + default: + printf("I2C_%d not supported!\n", bus); + }; + + return 0; +} + +int get_multi_sda_pin(void) +{ + unsigned int bus = I2C_GET_BUS(); + + switch (bus) { + case I2C_0: /* I2C_0 definition - compatibility layer */ + case I2C_5: + return CONFIG_SOFT_I2C_I2C5_SDA; + case I2C_9: + return CONFIG_SOFT_I2C_I2C9_SDA; + default: + printf("I2C_%d not supported!\n", bus); + }; + + return 0; +} + +int multi_i2c_init(void) +{ + return 0; +} diff --git a/board/samsung/goni/lowlevel_init.S b/board/samsung/goni/lowlevel_init.S index 30a5835..1effc9c 100644 --- a/board/samsung/goni/lowlevel_init.S +++ b/board/samsung/goni/lowlevel_init.S @@ -79,11 +79,7 @@ skip_check_didle: str r1, [r0, #0x0] @ GPIO_CON_OFFSET ldr r1, [r0, #0x4] @ GPIO_DAT_OFFSET -#ifdef CONFIG_ONENAND_IPL - orr r1, r1, #(1 << 1) @ 1 * 1-bit -#else bic r1, r1, #(1 << 1) -#endif str r1, [r0, #0x4] @ GPIO_DAT_OFFSET /* Don't setup at s5pc100 */ @@ -182,7 +178,6 @@ skip_check_didle: /* Do not release retention here for S5PC110 */ streq r1, [r0] -#ifndef CONFIG_ONENAND_IPL /* Disable Watchdog */ ldreq r0, =S5PC100_WATCHDOG_BASE @ 0xEA200000 ldrne r0, =S5PC110_WATCHDOG_BASE @ 0xE2700000 @@ -193,7 +188,6 @@ skip_check_didle: ldrne r0, =S5PC110_SROMC_BASE ldr r1, =0x9 str r1, [r0] -#endif /* S5PC100 has 3 groups of interrupt sources */ ldreq r0, =S5PC100_VIC0_BASE @ 0xE4000000 @@ -207,7 +201,6 @@ skip_check_didle: str r3, [r1, #0x14] @ INTENCLEAR str r3, [r2, #0x14] @ INTENCLEAR -#ifndef CONFIG_ONENAND_IPL /* Set all interrupts as IRQ */ str r5, [r0, #0xc] @ INTSELECT str r5, [r1, #0xc] @ INTSELECT @@ -217,120 +210,12 @@ skip_check_didle: str r5, [r0, #0xf00] @ INTADDRESS str r5, [r1, #0xf00] @ INTADDRESS str r5, [r2, #0xf00] @ INTADDRESS -#endif -#ifndef CONFIG_ONENAND_IPL /* for UART */ bl uart_asm_init bl internal_ram_init -#endif - -#ifdef CONFIG_ONENAND_IPL - /* init system clock */ - bl system_clock_init - - /* OneNAND Sync Read Support at S5PC110 only - * RM[15] : Sync Read - * BRWL[14:12] : 7 CLK - * BL[11:9] : Continuous - * VHF[3] : Very High Frequency Enable (Over 83MHz) - * HF[2] : High Frequency Enable (Over 66MHz) - * WM[1] : Sync Write - */ - cmp r7, r8 - ldrne r1, =0xE006 - ldrne r0, =0xB001E442 - strneh r1, [r0] - - /* - * GCE[26] : Gated Clock Enable - * RPE[17] : Enables Read Prefetch - */ - ldrne r1, =((1 << 26) | (1 << 17) | 0xE006) - ldrne r0, =0xB0600000 - strne r1, [r0, #0x100] @ ONENAND_IF_CTRL - ldrne r1, =0x1212 - strne r1, [r0, #0x108] - - /* Board detection to set proper memory configuration */ - cmp r7, r8 - moveq r9, #1 /* r9 has 1Gib default at s5pc100 */ - movne r9, #2 /* r9 has 2Gib default at s5pc110 */ - - ldr r2, =0xE0200200 - ldr r4, [r2, #0x48] - - bic r1, r4, #(0x3F << 4) /* PULLUP_DISABLE: 3 * 2-bit */ - bic r1, r1, #(0x3 << 2) /* PULLUP_DISABLE: 2 * 2-bit */ - bic r1, r1, #(0x3 << 14) /* PULLUP_DISABLE: 2 * 2-bit */ - str r1, [r2, #0x48] - /* For write completion */ - nop - nop - - ldr r3, [r2, #0x44] - and r1, r3, #(0x7 << 2) - mov r1, r1, lsr #2 - cmp r1, #0x5 - moveq r9, #3 - cmp r1, #0x6 - moveq r9, #1 - cmp r1, #0x7 - moveq r9, #2 - and r0, r3, #(0x1 << 1) - mov r0, r0, lsr #1 - orr r1, r1, r0, lsl #3 - cmp r1, #0x8 - moveq r9, #3 - and r1, r3, #(0x7 << 2) - mov r1, r1, lsr #2 - and r0, r3, #(0x1 << 7) - mov r0, r0, lsr #7 - orr r1, r1, r0, lsl #3 - cmp r1, #0x9 - moveq r9, #3 - str r4, [r2, #0x48] /* Restore PULLUP configuration */ - - bl mem_ctrl_asm_init - - /* Wakeup support. Don't know if it's going to be used, untested. */ - ldreq r0, =S5PC100_RST_STAT - ldrne r0, =S5PC110_RST_STAT - ldr r1, [r0] - biceq r1, r1, #0xfffffff7 - moveq r2, #(1 << 3) - bicne r1, r1, #0xfffeffff - movne r2, #(1 << 16) - cmp r1, r2 - bne 1f -wakeup: - /* turn off L2 cache */ - bl l2_cache_disable - - cmp r7, r8 - ldreq r0, =0xC100 - ldrne r0, =0xC110 - - /* invalidate L2 cache also */ - bl invalidate_dcache - - /* turn on L2 cache */ - bl l2_cache_enable - - cmp r7, r8 - /* Load return address and jump to kernel */ - ldreq r0, =S5PC100_INFORM0 - ldrne r0, =S5PC110_INFORM0 - - /* r1 = physical address of s5pc1xx_cpu_resume function */ - ldr r1, [r0] - /* Jump to kernel (sleep-s5pc1xx.S) */ - mov pc, r1 - nop - nop -#else cmp r7, r8 /* Clear wakeup status register */ ldreq r0, =S5PC100_WAKEUP_STAT @@ -347,7 +232,6 @@ wakeup: orr r1, r1, r2 str r1, [r0] -#endif b 1f didle_wakeup: @@ -517,7 +401,6 @@ system_clock_init: mov pc, lr -#ifndef CONFIG_ONENAND_IPL internal_ram_init: ldreq r0, =0xE3800000 ldrne r0, =0xF1500000 @@ -525,9 +408,7 @@ internal_ram_init: str r1, [r0] mov pc, lr -#endif -#ifndef CONFIG_ONENAND_IPL /* * uart_asm_init: Initialize UART's pins */ @@ -582,4 +463,3 @@ uart_asm_init: str r1, [r0, #0x4] @ S5PC1XX_GPIO_DAT_OFFSET 200: mov pc, lr -#endif diff --git a/board/samsung/smdkc100/lowlevel_init.S b/board/samsung/smdkc100/lowlevel_init.S index 6d18835..6f9a554 100644 --- a/board/samsung/smdkc100/lowlevel_init.S +++ b/board/samsung/smdkc100/lowlevel_init.S @@ -50,12 +50,10 @@ lowlevel_init: orr r0, r0, #0x0 str r5, [r0] -#ifndef CONFIG_ONENAND_IPL /* setting SRAM */ ldr r0, =S5PC100_SROMC_BASE ldr r1, =0x9 str r1, [r0] -#endif /* S5PC100 has 3 groups of interrupt sources */ ldr r0, =S5PC100_VIC0_BASE @0xE4000000 @@ -68,7 +66,6 @@ lowlevel_init: str r3, [r1, #0x14] @INTENCLEAR str r3, [r2, #0x14] @INTENCLEAR -#ifndef CONFIG_ONENAND_IPL /* Set all interrupts as IRQ */ str r5, [r0, #0xc] @INTSELECT str r5, [r1, #0xc] @INTSELECT @@ -78,54 +75,17 @@ lowlevel_init: str r5, [r0, #0xf00] @INTADDRESS str r5, [r1, #0xf00] @INTADDRESS str r5, [r2, #0xf00] @INTADDRESS -#endif -#ifndef CONFIG_ONENAND_IPL /* for UART */ bl uart_asm_init /* for TZPC */ bl tzpc_asm_init -#endif - -#ifdef CONFIG_ONENAND_IPL - /* init system clock */ - bl system_clock_init - - bl mem_ctrl_asm_init - - /* Wakeup support. Don't know if it's going to be used, untested. */ - ldr r0, =S5PC100_RST_STAT - ldr r1, [r0] - bic r1, r1, #0xfffffff7 - cmp r1, #0x8 - beq wakeup_reset -#endif 1: mov lr, r9 mov pc, lr -#ifdef CONFIG_ONENAND_IPL -wakeup_reset: - - /* Clear wakeup status register */ - ldr r0, =S5PC100_WAKEUP_STAT - ldr r1, [r0] - str r1, [r0] - - /* Load return address and jump to kernel */ - ldr r0, =S5PC100_INFORM0 - - /* r1 = physical address of s5pc100_cpu_resume function */ - ldr r1, [r0] - - /* Jump to kernel (sleep.S) */ - mov pc, r1 - nop - nop -#endif - /* * system_clock_init: Initialize core clock and bus clock. * void system_clock_init(void) @@ -178,7 +138,6 @@ system_clock_init: mov pc, lr -#ifndef CONFIG_ONENAND_IPL /* * uart_asm_init: Initialize UART's pins */ @@ -212,4 +171,3 @@ tzpc_asm_init: str r1, [r0, #0x810] mov pc, lr -#endif diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index a8b2b11..e11a892 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -59,6 +59,8 @@ static int hwrevision(int rev) return (board_rev & 0xf) == rev; } +struct s3c_plat_otg_data s5pc210_otg_data; + int board_init(void) { gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; @@ -73,6 +75,21 @@ int board_init(void) return 0; } +void i2c_init_board(void) +{ + struct exynos4_gpio_part1 *gpio1 = + (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1(); + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2(); + + /* I2C_5 -> PMIC */ + s5p_gpio_direction_output(&gpio1->b, 7, 1); + s5p_gpio_direction_output(&gpio1->b, 6, 1); + /* I2C_9 -> FG */ + s5p_gpio_direction_output(&gpio2->y4, 0, 1); + s5p_gpio_direction_output(&gpio2->y4, 1, 1); +} + int dram_init(void) { gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) + @@ -259,6 +276,12 @@ struct s3c_plat_otg_data s5pc210_otg_data = { .usb_phy_ctrl = EXYNOS4_USBPHY_CONTROL, .usb_flags = PHY0_SLEEP, }; + +void board_usb_init(void) +{ + debug("USB_udc_probe\n"); + s3c_udc_probe(&s5pc210_otg_data); +} #endif static void pmic_reset(void) diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index a1e2bfe..b75e62c 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -28,6 +28,7 @@ #include <common.h> #include <config.h> #include <netdev.h> +#include <asm/processor.h> #include <asm/microblaze_intc.h> #include <asm/asm.h> @@ -69,6 +70,14 @@ int fsl_init2 (void) { } #endif +void board_init(void) +{ + gpio_init(); +#ifdef CONFIG_SYS_FSL_2 + fsl_init2(); +#endif +} + int board_eth_init(bd_t *bis) { int ret = 0; @@ -50,7 +50,6 @@ tt01 arm arm1136 - hale imx31_litekit arm arm1136 - logicpd mx31 flea3 arm arm1136 - CarMediaLab mx35 mx35pdk arm arm1136 - freescale mx35 -apollon arm arm1136 apollon - omap24xx omap2420h4 arm arm1136 - ti omap24xx tnetv107x_evm arm arm1176 tnetv107xevm ti tnetv107x rpi_b arm arm1176 rpi_b raspberrypi bcm2835 @@ -303,6 +302,7 @@ tec arm armv7:arm720t tec avionic paz00 arm armv7:arm720t paz00 compal tegra20 trimslice arm armv7:arm720t trimslice compulab tegra20 atngw100 avr32 at32ap - atmel at32ap700x +atngw100mkii avr32 at32ap - atmel at32ap700x atstk1002 avr32 at32ap atstk1000 atmel at32ap700x atstk1003 avr32 at32ap atstk1000 atmel at32ap700x atstk1004 avr32 at32ap atstk1000 atmel at32ap700x @@ -390,7 +390,8 @@ M5485FFE m68k mcf547x_8x m548xevb freescale - M5485GFE m68k mcf547x_8x m548xevb freescale - M5485EVB:SYS_BUSCLK=100000000,SYS_BOOTSZ=4,SYS_DRAMSZ=64 M5485HFE m68k mcf547x_8x m548xevb freescale - M5485EVB:SYS_BUSCLK=100000000,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_NOR1SZ=16,SYS_VIDEO microblaze-generic microblaze microblaze microblaze-generic xilinx -qemu_mips mips mips32 qemu-mips - - qemu-mips +qemu_mips mips mips32 qemu-mips - - qemu-mips:SYS_BIG_ENDIAN +qemu_mipsel mips mips32 qemu-mips - - qemu-mips:SYS_LITTLE_ENDIAN vct_platinum mips mips32 vct micronas - vct:VCT_PLATINUM vct_platinumavc mips mips32 vct micronas - vct:VCT_PLATINUMAVC vct_platinumavc_onenand mips mips32 vct micronas - vct:VCT_PLATINUMAVC,VCT_ONENAND @@ -808,29 +809,24 @@ P2041RDB_NAND powerpc mpc85xx p2041rdb freescale P2041RDB_SDCARD powerpc mpc85xx p2041rdb freescale - P2041RDB:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P2041RDB_SECURE_BOOT powerpc mpc85xx p2041rdb freescale - P2041RDB:SECURE_BOOT P2041RDB_SPIFLASH powerpc mpc85xx p2041rdb freescale - P2041RDB:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 +P2041RDB_SRIO_PCIE_BOOT powerpc mpc85xx p2041rdb freescale - P2041RDB:SRIO_PCIE_BOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 P3041DS powerpc mpc85xx corenet_ds freescale P3041DS_NAND powerpc mpc85xx corenet_ds freescale - P3041DS:RAMBOOT_PBL,NAND,SYS_TEXT_BASE=0xFFF80000 P3041DS_SDCARD powerpc mpc85xx corenet_ds freescale - P3041DS:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P3041DS_SECURE_BOOT powerpc mpc85xx corenet_ds freescale - P3041DS:SECURE_BOOT P3041DS_SPIFLASH powerpc mpc85xx corenet_ds freescale - P3041DS:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 -P3041DS_SRIOBOOT_MASTER powerpc mpc85xx corenet_ds freescale - P3041DS:SRIOBOOT_MASTER -P3041DS_SRIOBOOT_SLAVE powerpc mpc85xx corenet_ds freescale - P3041DS:SRIOBOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 -P3060QDS powerpc mpc85xx p3060qds freescale -P3060QDS_NAND powerpc mpc85xx p3060qds freescale - P3060QDS:RAMBOOT_PBL,NAND,SYS_TEXT_BASE=0xFFF80000 -P3060QDS_SECURE_BOOT powerpc mpc85xx p3060qds freescale - P3060QDS:SECURE_BOOT +P3041DS_SRIO_PCIE_BOOT powerpc mpc85xx corenet_ds freescale - P3041DS:SRIO_PCIE_BOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 P4080DS powerpc mpc85xx corenet_ds freescale P4080DS_SDCARD powerpc mpc85xx corenet_ds freescale - P4080DS:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P4080DS_SECURE_BOOT powerpc mpc85xx corenet_ds freescale - P4080DS:SECURE_BOOT P4080DS_SPIFLASH powerpc mpc85xx corenet_ds freescale - P4080DS:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 -P4080DS_SRIOBOOT_MASTER powerpc mpc85xx corenet_ds freescale - P4080DS:SRIOBOOT_MASTER -P4080DS_SRIOBOOT_SLAVE powerpc mpc85xx corenet_ds freescale - P4080DS:SRIOBOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 +P4080DS_SRIO_PCIE_BOOT powerpc mpc85xx corenet_ds freescale - P4080DS:SRIO_PCIE_BOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 P5020DS powerpc mpc85xx corenet_ds freescale P5020DS_NAND powerpc mpc85xx corenet_ds freescale - P5020DS:RAMBOOT_PBL,NAND,SYS_TEXT_BASE=0xFFF80000 P5020DS_SDCARD powerpc mpc85xx corenet_ds freescale - P5020DS:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P5020DS_SECURE_BOOT powerpc mpc85xx corenet_ds freescale - P5020DS:SECURE_BOOT P5020DS_SPIFLASH powerpc mpc85xx corenet_ds freescale - P5020DS:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 -P5020DS_SRIOBOOT_MASTER powerpc mpc85xx corenet_ds freescale - P5020DS:SRIOBOOT_MASTER -P5020DS_SRIOBOOT_SLAVE powerpc mpc85xx corenet_ds freescale - P5020DS:SRIOBOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 +P5020DS_SRIO_PCIE_BOOT powerpc mpc85xx corenet_ds freescale - P5020DS:SRIO_PCIE_BOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 BSC9131RDB_SPIFLASH powerpc mpc85xx bsc9131rdb freescale - BSC9131RDB:BSC9131RDB,SPIFLASH stxgp3 powerpc mpc85xx stxgp3 stx stxssa powerpc mpc85xx stxssa stx - stxssa diff --git a/common/Makefile b/common/Makefile index 3d62775..125b2be 100644 --- a/common/Makefile +++ b/common/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_SYS_HUSH_PARSER) += hush.o COBJS-y += s_record.o COBJS-$(CONFIG_SERIAL_MULTI) += serial.o COBJS-y += xyzModem.o +COBJS-y += cmd_disk.o # core command COBJS-y += cmd_boot.o @@ -86,7 +87,13 @@ COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o COBJS-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o +COBJS-$(CONFIG_CMD_EXT4) += cmd_ext4.o COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o +ifdef CONFIG_CMD_EXT4 +COBJS-y += cmd_ext_common.o +else +COBJS-$(CONFIG_CMD_EXT2) += cmd_ext_common.o +endif COBJS-$(CONFIG_CMD_FAT) += cmd_fat.o COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o COBJS-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o @@ -129,6 +136,7 @@ COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o COBJS-$(CONFIG_CMD_NET) += cmd_net.o COBJS-$(CONFIG_CMD_ONENAND) += cmd_onenand.o COBJS-$(CONFIG_CMD_OTP) += cmd_otp.o +COBJS-$(CONFIG_CMD_PART) += cmd_part.o ifdef CONFIG_PCI COBJS-$(CONFIG_CMD_PCI) += cmd_pci.o endif @@ -162,6 +170,7 @@ endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o +COBJS-$(CONFIG_CMD_ZIP) += cmd_zip.o COBJS-$(CONFIG_CMD_ZFS) += cmd_zfs.o # others @@ -184,6 +193,7 @@ COBJS-$(CONFIG_MENU) += menu.o COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o COBJS-$(CONFIG_UPDATE_TFTP) += update.o COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o +COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o endif ifdef CONFIG_SPL_BUILD diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index 42f08fd..23bd8a5 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -216,15 +216,15 @@ int do_bdinfo(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) print_num("flashstart ", bd->bi_flashstart); print_num("CONFIG_SYS_MONITOR_BASE ", CONFIG_SYS_MONITOR_BASE); print_num("CONFIG_ENV_ADDR ", CONFIG_ENV_ADDR); - printf("CONFIG_SYS_RELOC_MONITOR_BASE = 0x%lx (%d)\n", CONFIG_SYS_RELOC_MONITOR_BASE, + printf("CONFIG_SYS_RELOC_MONITOR_BASE = 0x%x (%d)\n", CONFIG_SYS_RELOC_MONITOR_BASE, CONFIG_SYS_MONITOR_LEN); - printf("CONFIG_SYS_MALLOC_BASE = 0x%lx (%d)\n", CONFIG_SYS_MALLOC_BASE, + printf("CONFIG_SYS_MALLOC_BASE = 0x%x (%d)\n", CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN); - printf("CONFIG_SYS_INIT_SP_OFFSET = 0x%lx (%d)\n", CONFIG_SYS_INIT_SP_OFFSET, + printf("CONFIG_SYS_INIT_SP_OFFSET = 0x%x (%d)\n", CONFIG_SYS_INIT_SP_OFFSET, CONFIG_SYS_STACK_SIZE); - printf("CONFIG_SYS_PROM_OFFSET = 0x%lx (%d)\n", CONFIG_SYS_PROM_OFFSET, + printf("CONFIG_SYS_PROM_OFFSET = 0x%x (%d)\n", CONFIG_SYS_PROM_OFFSET, CONFIG_SYS_PROM_SIZE); - printf("CONFIG_SYS_GBL_DATA_OFFSET = 0x%lx (%d)\n", CONFIG_SYS_GBL_DATA_OFFSET, + printf("CONFIG_SYS_GBL_DATA_OFFSET = 0x%x (%d)\n", CONFIG_SYS_GBL_DATA_OFFSET, GENERATED_GBL_DATA_SIZE); #if defined(CONFIG_CMD_NET) diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 45e726a..83fa5d7 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -564,6 +564,13 @@ int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc, break; case BOOTM_STATE_OS_GO: disable_interrupts(); +#ifdef CONFIG_NETCONSOLE + /* + * Stop the ethernet stack if NetConsole could have + * left it up + */ + eth_halt(); +#endif arch_preboot_os(); boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images); break; @@ -622,6 +629,11 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) */ iflag = disable_interrupts(); +#ifdef CONFIG_NETCONSOLE + /* Stop the ethernet stack if NetConsole could have left it up */ + eth_halt(); +#endif + #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the @@ -1599,6 +1611,11 @@ static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) */ disable_interrupts(); +#ifdef CONFIG_NETCONSOLE + /* Stop the ethernet stack if NetConsole could have left it up */ + eth_halt(); +#endif + #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the diff --git a/common/cmd_dfu.c b/common/cmd_dfu.c new file mode 100644 index 0000000..62fb890 --- /dev/null +++ b/common/cmd_dfu.c @@ -0,0 +1,81 @@ +/* + * cmd_dfu.c -- dfu command + * + * Copyright (C) 2012 Samsung Electronics + * authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com> + * Lukasz Majewski <l.majewski@samsung.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <malloc.h> +#include <dfu.h> +#include <asm/errno.h> +#include <g_dnl.h> + +static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const char *str_env; + char s[] = "dfu"; + char *env_bkp; + int ret; + + if (argc < 3) + return CMD_RET_USAGE; + + str_env = getenv("dfu_alt_info"); + if (str_env == NULL) { + printf("%s: \"dfu_alt_info\" env variable not defined!\n", + __func__); + return CMD_RET_FAILURE; + } + + env_bkp = strdup(str_env); + ret = dfu_config_entities(env_bkp, argv[1], + (int)simple_strtoul(argv[2], NULL, 10)); + if (ret) + return CMD_RET_FAILURE; + + if (strcmp(argv[3], "list") == 0) { + dfu_show_entities(); + goto done; + } + + board_usb_init(); + g_dnl_register(s); + while (1) { + if (ctrlc()) + goto exit; + + usb_gadget_handle_interrupts(); + } +exit: + g_dnl_unregister(); +done: + dfu_free_entities(); + free(env_bkp); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu, + "Device Firmware Upgrade", + "<interface> <dev> [list]\n" + " - device firmware upgrade on a device <dev>\n" + " attached to interface <interface>\n" + " [list] - list available alt settings" +); diff --git a/common/cmd_disk.c b/common/cmd_disk.c new file mode 100644 index 0000000..ee4e215 --- /dev/null +++ b/common/cmd_disk.c @@ -0,0 +1,144 @@ +/* + * (C) Copyright 2000-2011 + * Wolfgang Denk, DENX Software Engineering, wd@denx.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ +#include <common.h> +#include <command.h> +#include <part.h> + +#if defined(CONFIG_CMD_IDE) || defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_USB_STORAGE) +int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, + char *const argv[]) +{ + int dev, part; + ulong addr = CONFIG_SYS_LOAD_ADDR; + ulong cnt; + disk_partition_t info; + image_header_t *hdr; + block_dev_desc_t *dev_desc; + +#if defined(CONFIG_FIT) + const void *fit_hdr = NULL; +#endif + + bootstage_mark(BOOTSTAGE_ID_IDE_START); + if (argc > 3) { + bootstage_error(BOOTSTAGE_ID_IDE_ADDR); + return CMD_RET_USAGE; + } + bootstage_mark(BOOTSTAGE_ID_IDE_ADDR); + + if (argc > 1) + addr = simple_strtoul(argv[1], NULL, 16); + + bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE); + + part = get_device_and_partition(intf, (argc == 3) ? argv[2] : NULL, + &dev_desc, &info, 1); + if (part < 0) { + bootstage_error(BOOTSTAGE_ID_IDE_TYPE); + return 1; + } + + dev = dev_desc->dev; + bootstage_mark(BOOTSTAGE_ID_IDE_TYPE); + + printf("\nLoading from %s device %d, partition %d: " + "Name: %.32s Type: %.32s\n", intf, dev, part, info.name, + info.type); + + debug("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", + info.start, info.size, info.blksz); + + if (dev_desc->block_read(dev, info.start, 1, (ulong *) addr) != 1) { + printf("** Read error on %d:%d\n", dev, part); + bootstage_error(BOOTSTAGE_ID_IDE_PART_READ); + return 1; + } + bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ); + + switch (genimg_get_format((void *) addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *) addr; + + bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT); + + if (!image_check_hcrc(hdr)) { + puts("\n** Bad Header Checksum **\n"); + bootstage_error(BOOTSTAGE_ID_IDE_CHECKSUM); + return 1; + } + bootstage_mark(BOOTSTAGE_ID_IDE_CHECKSUM); + + image_print_contents(hdr); + + cnt = image_get_image_size(hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (const void *) addr; + puts("Fit image detected...\n"); + + cnt = fit_get_size(fit_hdr); + break; +#endif + default: + bootstage_error(BOOTSTAGE_ID_IDE_FORMAT); + puts("** Unknown image type\n"); + return 1; + } + + cnt += info.blksz - 1; + cnt /= info.blksz; + cnt -= 1; + + if (dev_desc->block_read(dev, info.start + 1, cnt, + (ulong *)(addr + info.blksz)) != cnt) { + printf("** Read error on %d:%d\n", dev, part); + bootstage_error(BOOTSTAGE_ID_IDE_READ); + return 1; + } + bootstage_mark(BOOTSTAGE_ID_IDE_READ); + +#if defined(CONFIG_FIT) + /* This cannot be done earlier, + * we need complete FIT image in RAM first */ + if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) { + if (!fit_check_format(fit_hdr)) { + bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ); + puts("** Bad FIT image format\n"); + return 1; + } + bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK); + fit_print_contents(fit_hdr); + } +#endif + + flush_cache(addr, (cnt+1)*info.blksz); + + /* Loading ok, update default load address */ + load_addr = addr; + + return bootm_maybe_autostart(cmdtp, argv[0]); +} +#endif diff --git a/common/cmd_ext2.c b/common/cmd_ext2.c index 79b1e2f..c27d9c7 100644 --- a/common/cmd_ext2.c +++ b/common/cmd_ext2.c @@ -1,4 +1,9 @@ /* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar <uma.shankar@samsung.com> + * Manjunatha C Achar <a.manjunatha@samsung.com> + * (C) Copyright 2004 * esd gmbh <www.esd-electronics.com> * Reinhard Arlt <reinhard.arlt@esd-electronics.com> @@ -33,225 +38,35 @@ * Ext2fs support */ #include <common.h> -#include <part.h> -#include <config.h> -#include <command.h> -#include <image.h> -#include <linux/ctype.h> -#include <asm/byteorder.h> -#include <ext2fs.h> -#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) -#include <usb.h> -#endif - -#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION) -#error DOS or EFI partition support must be selected -#endif - -/* #define EXT2_DEBUG */ - -#ifdef EXT2_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif +#include <ext_common.h> int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - char *filename = "/"; - int dev=0; - int part=1; - char *ep; - block_dev_desc_t *dev_desc=NULL; - int part_length; - - if (argc < 3) - return CMD_RET_USAGE; - - dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - - if (dev_desc == NULL) { - printf ("\n** Block device %s %d not supported\n", argv[1], dev); - return 1; - } - - if (*ep) { - if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } - - if (argc == 4) - filename = argv[3]; - - PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename); - - if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) { - printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part); - ext2fs_close(); - return 1; - } - - if (!ext2fs_mount(part_length)) { - printf ("** Bad ext2 partition or disk - %s %d:%d **\n", argv[1], dev, part); - ext2fs_close(); - return 1; - } - - if (ext2fs_ls (filename)) { - printf ("** Error ext2fs_ls() **\n"); - ext2fs_close(); - return 1; - }; - - ext2fs_close(); + if (do_ext_ls(cmdtp, flag, argc, argv)) + return -1; return 0; } -U_BOOT_CMD( - ext2ls, 4, 1, do_ext2ls, - "list files in a directory (default /)", - "<interface> <dev[:part]> [directory]\n" - " - list files from 'dev' on 'interface' in a 'directory'" -); - /****************************************************************************** * Ext2fs boot command intepreter. Derived from diskboot */ int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - char *filename = NULL; - char *ep; - int dev, part = 1; - ulong addr = 0, part_length; - int filelen; - disk_partition_t info; - block_dev_desc_t *dev_desc = NULL; - char buf [12]; - unsigned long count; - char *addr_str; - - switch (argc) { - case 3: - addr_str = getenv("loadaddr"); - if (addr_str != NULL) - addr = simple_strtoul (addr_str, NULL, 16); - else - addr = CONFIG_SYS_LOAD_ADDR; - - filename = getenv ("bootfile"); - count = 0; - break; - case 4: - addr = simple_strtoul (argv[3], NULL, 16); - filename = getenv ("bootfile"); - count = 0; - break; - case 5: - addr = simple_strtoul (argv[3], NULL, 16); - filename = argv[4]; - count = 0; - break; - case 6: - addr = simple_strtoul (argv[3], NULL, 16); - filename = argv[4]; - count = simple_strtoul (argv[5], NULL, 16); - break; - - default: - return CMD_RET_USAGE; - } - - if (!filename) { - puts ("** No boot file defined **\n"); - return 1; - } - - dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - if (dev_desc==NULL) { - printf ("** Block device %s %d not supported\n", argv[1], dev); - return 1; - } - if (*ep) { - if (*ep != ':') { - puts ("** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } - - PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part); - - if (part != 0) { - if (get_partition_info (dev_desc, part, &info)) { - printf ("** Bad partition %d **\n", part); - return 1; - } - - if (strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) { - printf ("** Invalid partition type \"%.32s\"" - " (expect \"" BOOT_PART_TYPE "\")\n", - info.type); - return 1; - } - printf ("Loading file \"%s\" " - "from %s device %d:%d (%.32s)\n", - filename, - argv[1], dev, part, info.name); - } else { - printf ("Loading file \"%s\" from %s device %d\n", - filename, argv[1], dev); - } - - - if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) { - printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part); - ext2fs_close(); - return 1; - } - - if (!ext2fs_mount(part_length)) { - printf ("** Bad ext2 partition or disk - %s %d:%d **\n", - argv[1], dev, part); - ext2fs_close(); - return 1; - } - - filelen = ext2fs_open(filename); - if (filelen < 0) { - printf("** File not found %s\n", filename); - ext2fs_close(); - return 1; - } - if ((count < filelen) && (count != 0)) { - filelen = count; - } - - if (ext2fs_read((char *)addr, filelen) != filelen) { - printf("** Unable to read \"%s\" from %s %d:%d **\n", - filename, argv[1], dev, part); - ext2fs_close(); - return 1; - } - - ext2fs_close(); - - /* Loading ok, update default load address */ - load_addr = addr; - - printf ("%d bytes read\n", filelen); - sprintf(buf, "%X", filelen); - setenv("filesize", buf); + if (do_ext_load(cmdtp, flag, argc, argv)) + return -1; return 0; } U_BOOT_CMD( + ext2ls, 4, 1, do_ext2ls, + "list files in a directory (default /)", + "<interface> <dev[:part]> [directory]\n" + " - list files from 'dev' on 'interface' in a 'directory'" +); + +U_BOOT_CMD( ext2load, 6, 0, do_ext2load, "load binary file from a Ext2 filesystem", "<interface> <dev[:part]> [addr] [filename] [bytes]\n" diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c new file mode 100644 index 0000000..ca46561 --- /dev/null +++ b/common/cmd_ext4.c @@ -0,0 +1,145 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar <uma.shankar@samsung.com> + * Manjunatha C Achar <a.manjunatha@samsung.com> + * + * Ext4fs support + * made from existing cmd_ext2.c file of Uboot + * + * (C) Copyright 2004 + * esd gmbh <www.esd-electronics.com> + * Reinhard Arlt <reinhard.arlt@esd-electronics.com> + * + * made from cmd_reiserfs by + * + * (C) Copyright 2003 - 2004 + * Sysgo Real-Time Solutions, AG <www.elinos.com> + * Pavel Bartusek <pba@sysgo.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/* + * Changelog: + * 0.1 - Newly created file for ext4fs support. Taken from cmd_ext2.c + * file in uboot. Added ext4fs ls load and write support. + */ + +#include <common.h> +#include <part.h> +#include <config.h> +#include <command.h> +#include <image.h> +#include <linux/ctype.h> +#include <asm/byteorder.h> +#include <ext_common.h> +#include <ext4fs.h> +#include <linux/stat.h> +#include <malloc.h> + +#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) +#include <usb.h> +#endif + +int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + if (do_ext_load(cmdtp, flag, argc, argv)) + return -1; + + return 0; +} + +int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + if (do_ext_ls(cmdtp, flag, argc, argv)) + return -1; + + return 0; +} + +#if defined(CONFIG_CMD_EXT4_WRITE) +int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + const char *filename = "/"; + int dev, part; + unsigned long ram_address; + unsigned long file_size; + disk_partition_t info; + block_dev_desc_t *dev_desc; + + if (argc < 6) + return cmd_usage(cmdtp); + + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); + if (part < 0) + return 1; + + dev = dev_desc->dev; + + /* get the filename */ + filename = argv[3]; + + /* get the address in hexadecimal format (string to int) */ + ram_address = simple_strtoul(argv[4], NULL, 16); + + /* get the filesize in base 10 format */ + file_size = simple_strtoul(argv[5], NULL, 10); + + /* set the device as block device */ + ext4fs_set_blk_dev(dev_desc, &info); + + /* mount the filesystem */ + if (!ext4fs_mount(info.size)) { + printf("Bad ext4 partition %s %d:%lu\n", argv[1], dev, part); + goto fail; + } + + /* start write */ + if (ext4fs_write(filename, (unsigned char *)ram_address, file_size)) { + printf("** Error ext4fs_write() **\n"); + goto fail; + } + ext4fs_close(); + + return 0; + +fail: + ext4fs_close(); + + return 1; +} + +U_BOOT_CMD(ext4write, 6, 1, do_ext4_write, + "create a file in the root directory", + "<interface> <dev[:part]> [Absolute filename path] [Address] [sizebytes]\n" + " - create a file in / directory"); + +#endif + +U_BOOT_CMD(ext4ls, 4, 1, do_ext4_ls, + "list files in a directory (default /)", + "<interface> <dev[:part]> [directory]\n" + " - list files from 'dev' on 'interface' in a 'directory'"); + +U_BOOT_CMD(ext4load, 6, 0, do_ext4_load, + "load binary file from a Ext4 filesystem", + "<interface> <dev[:part]> [addr] [filename] [bytes]\n" + " - load binary file 'filename' from 'dev' on 'interface'\n" + " to address 'addr' from ext4 filesystem"); diff --git a/common/cmd_ext_common.c b/common/cmd_ext_common.c new file mode 100644 index 0000000..1952f4d --- /dev/null +++ b/common/cmd_ext_common.c @@ -0,0 +1,197 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT2/4 filesystem implementation in Uboot by + * Uma Shankar <uma.shankar@samsung.com> + * Manjunatha C Achar <a.manjunatha@samsung.com> + * + * Ext4fs support + * made from existing cmd_ext2.c file of Uboot + * + * (C) Copyright 2004 + * esd gmbh <www.esd-electronics.com> + * Reinhard Arlt <reinhard.arlt@esd-electronics.com> + * + * made from cmd_reiserfs by + * + * (C) Copyright 2003 - 2004 + * Sysgo Real-Time Solutions, AG <www.elinos.com> + * Pavel Bartusek <pba@sysgo.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/* + * Changelog: + * 0.1 - Newly created file for ext4fs support. Taken from cmd_ext2.c + * file in uboot. Added ext4fs ls load and write support. + */ + +#include <common.h> +#include <part.h> +#include <config.h> +#include <command.h> +#include <image.h> +#include <linux/ctype.h> +#include <asm/byteorder.h> +#include <ext_common.h> +#include <ext4fs.h> +#include <linux/stat.h> +#include <malloc.h> + +#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) +#include <usb.h> +#endif + +#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION) +#error DOS or EFI partition support must be selected +#endif + +#define DOS_PART_MAGIC_OFFSET 0x1fe +#define DOS_FS_TYPE_OFFSET 0x36 +#define DOS_FS32_TYPE_OFFSET 0x52 + +int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + char *filename = NULL; + int dev, part; + ulong addr = 0; + int filelen; + disk_partition_t info; + block_dev_desc_t *dev_desc; + char buf[12]; + unsigned long count; + const char *addr_str; + + count = 0; + addr = simple_strtoul(argv[3], NULL, 16); + filename = getenv("bootfile"); + switch (argc) { + case 3: + addr_str = getenv("loadaddr"); + if (addr_str != NULL) + addr = simple_strtoul(addr_str, NULL, 16); + else + addr = CONFIG_SYS_LOAD_ADDR; + + break; + case 4: + break; + case 5: + filename = argv[4]; + break; + case 6: + filename = argv[4]; + count = simple_strtoul(argv[5], NULL, 16); + break; + + default: + return cmd_usage(cmdtp); + } + + if (!filename) { + puts("** No boot file defined **\n"); + return 1; + } + + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); + if (part < 0) + return 1; + + dev = dev_desc->dev; + printf("Loading file \"%s\" from %s device %d%c%c\n", + filename, argv[1], dev, + part ? ':' : ' ', part ? part + '0' : ' '); + + ext4fs_set_blk_dev(dev_desc, &info); + + if (!ext4fs_mount(info.size)) { + printf("** Bad ext2 partition or disk - %s %d:%d **\n", + argv[1], dev, part); + ext4fs_close(); + goto fail; + } + + filelen = ext4fs_open(filename); + if (filelen < 0) { + printf("** File not found %s\n", filename); + ext4fs_close(); + goto fail; + } + if ((count < filelen) && (count != 0)) + filelen = count; + + if (ext4fs_read((char *)addr, filelen) != filelen) { + printf("** Unable to read \"%s\" from %s %d:%d **\n", + filename, argv[1], dev, part); + ext4fs_close(); + goto fail; + } + + ext4fs_close(); + /* Loading ok, update default load address */ + load_addr = addr; + + printf("%d bytes read\n", filelen); + sprintf(buf, "%X", filelen); + setenv("filesize", buf); + + return 0; +fail: + return 1; +} + +int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + const char *filename = "/"; + int dev; + int part; + block_dev_desc_t *dev_desc; + disk_partition_t info; + + if (argc < 2) + return cmd_usage(cmdtp); + + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); + if (part < 0) + return 1; + + if (argc == 4) + filename = argv[3]; + + dev = dev_desc->dev; + ext4fs_set_blk_dev(dev_desc, &info); + + if (!ext4fs_mount(info.size)) { + printf("** Bad ext2 partition or disk - %s %d:%d **\n", + argv[1], dev, part); + ext4fs_close(); + goto fail; + } + + if (ext4fs_ls(filename)) { + printf("** Error extfs_ls() **\n"); + ext4fs_close(); + goto fail; + }; + + ext4fs_close(); + return 0; + +fail: + return 1; +} diff --git a/common/cmd_fat.c b/common/cmd_fat.c index 559a16d..5a5698b 100644 --- a/common/cmd_fat.c +++ b/common/cmd_fat.c @@ -37,43 +37,35 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { long size; unsigned long offset; - unsigned long count; + unsigned long count = 0; + unsigned long pos = 0; char buf [12]; block_dev_desc_t *dev_desc=NULL; - int dev=0; - int part=1; - char *ep; + disk_partition_t info; + int part, dev; if (argc < 5) { - printf( "usage: fatload <interface> <dev[:part]> " - "<addr> <filename> [bytes]\n"); + printf("usage: fatload <interface> [<dev[:part]>] " + "<addr> <filename> [bytes [pos]]\n"); return 1; } - dev = (int)simple_strtoul(argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - if (dev_desc == NULL) { - puts("\n** Invalid boot device **\n"); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } + + dev = dev_desc->dev; if (fat_register_device(dev_desc,part)!=0) { printf("\n** Unable to use %s %d:%d for fatload **\n", argv[1], dev, part); return 1; } offset = simple_strtoul(argv[3], NULL, 16); - if (argc == 6) + if (argc >= 6) count = simple_strtoul(argv[5], NULL, 16); - else - count = 0; - size = file_fat_read(argv[4], (unsigned char *)offset, count); + if (argc >= 7) + pos = simple_strtoul(argv[6], NULL, 16); + size = file_fat_read_at(argv[4], pos, (unsigned char *)offset, count); if(size==-1) { printf("\n** Unable to read \"%s\" from %s %d:%d **\n", @@ -91,39 +83,34 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( - fatload, 6, 0, do_fat_fsload, + fatload, 7, 0, do_fat_fsload, "load binary file from a dos filesystem", - "<interface> <dev[:part]> <addr> <filename> [bytes]\n" - " - load binary file 'filename' from 'dev' on 'interface'\n" - " to address 'addr' from dos filesystem" + "<interface> [<dev[:part]>] <addr> <filename> [bytes [pos]]\n" + " - Load binary file 'filename' from 'dev' on 'interface'\n" + " to address 'addr' from dos filesystem.\n" + " 'pos' gives the file position to start loading from.\n" + " If 'pos' is omitted, 0 is used. 'pos' requires 'bytes'.\n" + " 'bytes' gives the size to load. If 'bytes' is 0 or omitted,\n" + " the load stops on end of file." ); int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = "/"; - int ret; - int dev=0; - int part=1; - char *ep; + int ret, dev, part; block_dev_desc_t *dev_desc=NULL; + disk_partition_t info; - if (argc < 3) { - printf("usage: fatls <interface> <dev[:part]> [directory]\n"); + if (argc < 2) { + printf("usage: fatls <interface> [<dev[:part]>] [directory]\n"); return 0; } - dev = (int)simple_strtoul(argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - if (dev_desc == NULL) { - puts("\n** Invalid boot device **\n"); + + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } + + dev = dev_desc->dev; if (fat_register_device(dev_desc,part)!=0) { printf("\n** Unable to use %s %d:%d for fatls **\n", argv[1], dev, part); @@ -142,34 +129,26 @@ int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( fatls, 4, 1, do_fat_ls, "list files in a directory (default /)", - "<interface> <dev[:part]> [directory]\n" + "<interface> [<dev[:part]>] [directory]\n" " - list files from 'dev' on 'interface' in a 'directory'" ); int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int dev=0; - int part=1; - char *ep; - block_dev_desc_t *dev_desc=NULL; + int dev, part; + block_dev_desc_t *dev_desc; + disk_partition_t info; if (argc < 2) { - printf("usage: fatinfo <interface> <dev[:part]>\n"); + printf("usage: fatinfo <interface> [<dev[:part]>]\n"); return 0; } - dev = (int)simple_strtoul(argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - if (dev_desc == NULL) { - puts("\n** Invalid boot device **\n"); + + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } + + dev = dev_desc->dev; if (fat_register_device(dev_desc,part)!=0) { printf("\n** Unable to use %s %d:%d for fatinfo **\n", argv[1], dev, part); @@ -181,7 +160,7 @@ int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( fatinfo, 3, 1, do_fat_fsinfo, "print information about filesystem", - "<interface> <dev[:part]>\n" + "<interface> [<dev[:part]>]\n" " - print information about filesystem from 'dev' on 'interface'" ); @@ -193,26 +172,19 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag, unsigned long addr; unsigned long count; block_dev_desc_t *dev_desc = NULL; + disk_partition_t info; int dev = 0; int part = 1; - char *ep; if (argc < 5) return cmd_usage(cmdtp); - dev = (int)simple_strtoul(argv[2], &ep, 16); - dev_desc = get_dev(argv[1], dev); - if (dev_desc == NULL) { - puts("\n** Invalid boot device **\n"); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } + + dev = dev_desc->dev; + if (fat_register_device(dev_desc, part) != 0) { printf("\n** Unable to use %s %d:%d for fatwrite **\n", argv[1], dev, part); diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 9a5c53e..e2225c4 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -114,10 +114,21 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) } } + return CMD_RET_SUCCESS; + } + + if (!working_fdt) { + puts( + "No FDT memory address configured. Please configure\n" + "the FDT address via \"fdt addr <address>\" command.\n" + "Aborting!\n"); + return CMD_RET_FAILURE; + } + /* * Move the working_fdt */ - } else if (strncmp(argv[1], "mo", 2) == 0) { + if (strncmp(argv[1], "mo", 2) == 0) { struct fdt_header *newaddr; int len; int err; diff --git a/common/cmd_flash.c b/common/cmd_flash.c index 0e9b2e3..e55d366 100644 --- a/common/cmd_flash.c +++ b/common/cmd_flash.c @@ -443,7 +443,8 @@ int flash_sect_erase (ulong addr_first, ulong addr_last) rcode = flash_erase (info, s_first[bank], s_last[bank]); } } - printf ("Erased %d sectors\n", erased); + if (rcode == 0) + printf("Erased %d sectors\n", erased); } else if (rcode == 0) { puts ("Error: start and/or end address" " not on sector boundary\n"); diff --git a/common/cmd_ide.c b/common/cmd_ide.c index f5b6c7b..6e1e568 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -334,156 +334,7 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - char *boot_device = NULL; - char *ep; - int dev, part = 0; - ulong addr, cnt; - disk_partition_t info; - image_header_t *hdr; - -#if defined(CONFIG_FIT) - const void *fit_hdr = NULL; -#endif - - bootstage_mark(BOOTSTAGE_ID_IDE_START); - switch (argc) { - case 1: - addr = CONFIG_SYS_LOAD_ADDR; - boot_device = getenv("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - default: - bootstage_error(BOOTSTAGE_ID_IDE_ADDR); - return CMD_RET_USAGE; - } - bootstage_mark(BOOTSTAGE_ID_IDE_ADDR); - - if (!boot_device) { - puts("\n** No boot device **\n"); - bootstage_error(BOOTSTAGE_ID_IDE_BOOT_DEVICE); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE); - - dev = simple_strtoul(boot_device, &ep, 16); - - if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { - printf("\n** Device %d not available\n", dev); - bootstage_error(BOOTSTAGE_ID_IDE_TYPE); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_TYPE); - - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - bootstage_error(BOOTSTAGE_ID_IDE_PART); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } - bootstage_mark(BOOTSTAGE_ID_IDE_PART); - - if (get_partition_info(&ide_dev_desc[dev], part, &info)) { - bootstage_error(BOOTSTAGE_ID_IDE_PART_INFO); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_PART_INFO); - - if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) - && - (strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0) - ) { - printf("\n** Invalid partition type \"%.32s\"" " (expect \"" - BOOT_PART_TYPE "\")\n", - info.type); - bootstage_error(BOOTSTAGE_ID_IDE_PART_TYPE); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_PART_TYPE); - - printf("\nLoading from IDE device %d, partition %d: " - "Name: %.32s Type: %.32s\n", dev, part, info.name, info.type); - - debug("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", - info.start, info.size, info.blksz); - - if (ide_dev_desc[dev]. - block_read(dev, info.start, 1, (ulong *) addr) != 1) { - printf("** Read error on %d:%d\n", dev, part); - bootstage_error(BOOTSTAGE_ID_IDE_PART_READ); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ); - - switch (genimg_get_format((void *) addr)) { - case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *) addr; - - bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT); - - if (!image_check_hcrc(hdr)) { - puts("\n** Bad Header Checksum **\n"); - bootstage_error(BOOTSTAGE_ID_IDE_CHECKSUM); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_CHECKSUM); - - image_print_contents(hdr); - - cnt = image_get_image_size(hdr); - break; -#if defined(CONFIG_FIT) - case IMAGE_FORMAT_FIT: - fit_hdr = (const void *) addr; - puts("Fit image detected...\n"); - - cnt = fit_get_size(fit_hdr); - break; -#endif - default: - bootstage_error(BOOTSTAGE_ID_IDE_FORMAT); - puts("** Unknown image type\n"); - return 1; - } - - cnt += info.blksz - 1; - cnt /= info.blksz; - cnt -= 1; - - if (ide_dev_desc[dev].block_read(dev, info.start + 1, cnt, - (ulong *)(addr + info.blksz)) != cnt) { - printf("** Read error on %d:%d\n", dev, part); - bootstage_error(BOOTSTAGE_ID_IDE_READ); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_READ); - -#if defined(CONFIG_FIT) - /* This cannot be done earlier, we need complete FIT image in RAM first */ - if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) { - if (!fit_check_format(fit_hdr)) { - bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ); - puts("** Bad FIT image format\n"); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK); - fit_print_contents(fit_hdr); - } -#endif - - /* Loading ok, update default load address */ - - load_addr = addr; - - return bootm_maybe_autostart(cmdtp, argv[0]); + return common_diskboot(cmdtp, "ide", argc, argv); } /* ------------------------------------------------------------------------- */ diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 750509d..79a1088 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -144,8 +144,7 @@ int do_mmcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( mmcinfo, 1, 0, do_mmcinfo, "display MMC info", - " - device number of the device to dislay info of\n" - "" + "- dislay info of the current MMC device" ); int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 4367f5a..e24ed7f 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -231,12 +231,18 @@ print: #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK static void print_status(ulong start, ulong end, ulong erasesize, int status) { + /* + * Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is + * not the same as others. Instead of bit 1 being lock, it is + * #lock_tight. To make the driver support either format, ignore bit 1 + * and use only bit 0 and bit 2. + */ printf("%08lx - %08lx: %08lx blocks %s%s%s\n", start, end - 1, (end - start) / erasesize, ((status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), - ((status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), + (!(status & NAND_LOCK_STATUS_UNLOCK) ? "LOCK " : ""), ((status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); } @@ -749,11 +755,18 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) return 0; } - if (strcmp(cmd, "unlock") == 0) { + if (strncmp(cmd, "unlock", 5) == 0) { + int allexcept = 0; + + s = strchr(cmd, '.'); + + if (s && !strcmp(s, ".allexcept")) + allexcept = 1; + if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size) < 0) return 1; - if (!nand_unlock(&nand_info[dev], off, size)) { + if (!nand_unlock(&nand_info[dev], off, size, allexcept)) { puts("NAND flash successfully unlocked\n"); } else { puts("Error unlocking NAND flash, " @@ -807,7 +820,7 @@ U_BOOT_CMD( "\n" "nand lock [tight] [status]\n" " bring nand to lock state or display locked pages\n" - "nand unlock [offset] [size] - unlock section" + "nand unlock[.allexcept] [offset] [size] - unlock section" #endif #ifdef CONFIG_ENV_OFFSET_OOB "\n" diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index fd05e72..3474bc6 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -198,31 +198,20 @@ static int do_env_grep(cmd_tbl_t *cmdtp, int flag, #endif /* - * Set a new environment variable, - * or replace or delete an existing one. + * Perform consistency checking before setting, replacing, or deleting an + * environment variable, then (if successful) apply the changes to internals so + * to make them effective. Code for this function was taken out of + * _do_env_set(), which now calls it instead. + * Also called as a callback function by himport_r(). + * Returns 0 in case of success, 1 in case of failure. + * When (flag & H_FORCE) is set, do not print out any error message and force + * overwriting of write-once variables. */ -int _do_env_set(int flag, int argc, char * const argv[]) + +int env_check_apply(const char *name, const char *oldval, + const char *newval, int flag) { - int i, len; int console = -1; - char *name, *value, *s; - ENTRY e, *ep; - - name = argv[1]; - - if (strchr(name, '=')) { - printf("## Error: illegal character '=' in variable name" - "\"%s\"\n", name); - return 1; - } - - env_id++; - /* - * search if variable with this name already exists - */ - e.key = name; - e.data = NULL; - hsearch_r(e, FIND, &ep, &env_htab); /* Check for console redirection */ if (strcmp(name, "stdin") == 0) @@ -233,60 +222,75 @@ int _do_env_set(int flag, int argc, char * const argv[]) console = stderr; if (console != -1) { - if (argc < 3) { /* Cannot delete it! */ - printf("Can't delete \"%s\"\n", name); + if ((newval == NULL) || (*newval == '\0')) { + /* We cannot delete stdin/stdout/stderr */ + if ((flag & H_FORCE) == 0) + printf("Can't delete \"%s\"\n", name); return 1; } #ifdef CONFIG_CONSOLE_MUX - i = iomux_doenv(console, argv[2]); - if (i) - return i; + if (iomux_doenv(console, newval)) + return 1; #else /* Try assigning specified device */ - if (console_assign(console, argv[2]) < 0) + if (console_assign(console, newval) < 0) return 1; #ifdef CONFIG_SERIAL_MULTI - if (serial_assign(argv[2]) < 0) + if (serial_assign(newval) < 0) return 1; #endif #endif /* CONFIG_CONSOLE_MUX */ } /* - * Some variables like "ethaddr" and "serial#" can be set only - * once and cannot be deleted; also, "ver" is readonly. + * Some variables like "ethaddr" and "serial#" can be set only once and + * cannot be deleted, unless CONFIG_ENV_OVERWRITE is defined. */ - if (ep) { /* variable exists */ #ifndef CONFIG_ENV_OVERWRITE + if (oldval != NULL && /* variable exists */ + (flag & H_FORCE) == 0) { /* and we are not forced */ if (strcmp(name, "serial#") == 0 || (strcmp(name, "ethaddr") == 0 #if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR) - && strcmp(ep->data, MK_STR(CONFIG_ETHADDR)) != 0 + && strcmp(oldval, MK_STR(CONFIG_ETHADDR)) != 0 #endif /* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */ )) { printf("Can't overwrite \"%s\"\n", name); return 1; } + } #endif + /* + * When we change baudrate, or we are doing an env default -a + * (which will erase all variables prior to calling this), + * we want the baudrate to actually change - for real. + */ + if (oldval != NULL || /* variable exists */ + (flag & H_NOCLEAR) == 0) { /* or env is clear */ /* * Switch to new baudrate if new baudrate is supported */ if (strcmp(name, "baudrate") == 0) { - int baudrate = simple_strtoul(argv[2], NULL, 10); + int baudrate = simple_strtoul(newval, NULL, 10); int i; for (i = 0; i < N_BAUDRATES; ++i) { if (baudrate == baudrate_table[i]) break; } if (i == N_BAUDRATES) { - printf("## Baudrate %d bps not supported\n", - baudrate); + if ((flag & H_FORCE) == 0) + printf("## Baudrate %d bps not " + "supported\n", baudrate); return 1; } + if (gd->baudrate == baudrate) { + /* If unchanged, we just say it's OK */ + return 0; + } printf("## Switch baudrate to %d bps and" - "press ENTER ...\n", baudrate); + "press ENTER ...\n", baudrate); udelay(50000); gd->baudrate = baudrate; #if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2) @@ -300,9 +304,62 @@ int _do_env_set(int flag, int argc, char * const argv[]) } } + /* + * Some variables should be updated when the corresponding + * entry in the environment is changed + */ + if (strcmp(name, "loadaddr") == 0) { + load_addr = simple_strtoul(newval, NULL, 16); + return 0; + } +#if defined(CONFIG_CMD_NET) + else if (strcmp(name, "bootfile") == 0) { + copy_filename(BootFile, newval, sizeof(BootFile)); + return 0; + } +#endif + return 0; +} + +/* + * Set a new environment variable, + * or replace or delete an existing one. +*/ +int _do_env_set(int flag, int argc, char * const argv[]) +{ + int i, len; + char *name, *value, *s; + ENTRY e, *ep; + + name = argv[1]; + value = argv[2]; + + if (strchr(name, '=')) { + printf("## Error: illegal character '='" + "in variable name \"%s\"\n", name); + return 1; + } + + env_id++; + /* + * search if variable with this name already exists + */ + e.key = name; + e.data = NULL; + hsearch_r(e, FIND, &ep, &env_htab); + + /* + * Perform requested checks. Notice how since we are overwriting + * a single variable, we need to set H_NOCLEAR + */ + if (env_check_apply(name, ep ? ep->data : NULL, value, H_NOCLEAR)) { + debug("check function did not approve, refusing\n"); + return 1; + } + /* Delete only ? */ if (argc < 3 || argv[2] == NULL) { - int rc = hdelete_r(name, &env_htab); + int rc = hdelete_r(name, &env_htab, 0); return !rc; } @@ -337,20 +394,6 @@ int _do_env_set(int flag, int argc, char * const argv[]) return 1; } - /* - * Some variables should be updated when the corresponding - * entry in the environment is changed - */ - if (strcmp(argv[1], "loadaddr") == 0) { - load_addr = simple_strtoul(argv[2], NULL, 16); - return 0; - } -#if defined(CONFIG_CMD_NET) - else if (strcmp(argv[1], "bootfile") == 0) { - copy_filename(BootFile, argv[2], sizeof(BootFile)); - return 0; - } -#endif return 0; } @@ -613,14 +656,41 @@ int envmatch(uchar *s1, int i2) return -1; } -static int do_env_default(cmd_tbl_t *cmdtp, int flag, +static int do_env_default(cmd_tbl_t *cmdtp, int __flag, int argc, char * const argv[]) { - if (argc != 2 || strcmp(argv[1], "-f") != 0) - return CMD_RET_USAGE; + int all = 0, flag = 0; - set_default_env("## Resetting to default environment\n"); - return 0; + debug("Initial value for argc=%d\n", argc); + while (--argc > 0 && **++argv == '-') { + char *arg = *argv; + + while (*++arg) { + switch (*arg) { + case 'a': /* default all */ + all = 1; + break; + case 'f': /* force */ + flag |= H_FORCE; + break; + default: + return cmd_usage(cmdtp); + } + } + } + debug("Final value for argc=%d\n", argc); + if (all && (argc == 0)) { + /* Reset the whole environment */ + set_default_env("## Resetting to default environment\n"); + return 0; + } + if (!all && (argc > 0)) { + /* Reset individual variables */ + set_default_vars(argc, argv); + return 0; + } + + return cmd_usage(cmdtp); } static int do_env_delete(cmd_tbl_t *cmdtp, int flag, @@ -872,7 +942,8 @@ static int do_env_import(cmd_tbl_t *cmdtp, int flag, addr = (char *)ep->data; } - if (himport_r(&env_htab, addr, size, sep, del ? 0 : H_NOCLEAR) == 0) { + if (himport_r(&env_htab, addr, size, sep, del ? 0 : H_NOCLEAR, + 0, NULL, 0 /* do_apply */) == 0) { error("Environment import failed: errno = %d\n", errno); return 1; } @@ -950,15 +1021,20 @@ U_BOOT_CMD( #if defined(CONFIG_CMD_ASKENV) "ask name [message] [size] - ask for environment variable\nenv " #endif - "default -f - reset default environment\n" + "default [-f] -a - [forcibly] reset default environment\n" + "env default [-f] var [...] - [forcibly] reset variable(s) to their default values\n" #if defined(CONFIG_CMD_EDITENV) "env edit name - edit environment variable\n" #endif +#if defined(CONFIG_CMD_EXPORTENV) "env export [-t | -b | -c] [-s size] addr [var ...] - export environment\n" +#endif #if defined(CONFIG_CMD_GREPENV) "env grep string [...] - search environment\n" #endif +#if defined(CONFIG_CMD_IMPORTENV) "env import [-d] [-t | -b | -c] addr [size] - import environment\n" +#endif "env print [name ...] - print environment\n" #if defined(CONFIG_CMD_RUN) "env run var [...] - run commands in an environment variable\n" diff --git a/common/cmd_part.c b/common/cmd_part.c new file mode 100644 index 0000000..d997597 --- /dev/null +++ b/common/cmd_part.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * made from cmd_ext2, which was: + * + * (C) Copyright 2004 + * esd gmbh <www.esd-electronics.com> + * Reinhard Arlt <reinhard.arlt@esd-electronics.com> + * + * made from cmd_reiserfs by + * + * (C) Copyright 2003 - 2004 + * Sysgo Real-Time Solutions, AG <www.elinos.com> + * Pavel Bartusek <pba@sysgo.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; 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, see <http://www.gnu.org/licenses/>. + */ + +#include <common.h> +#include <config.h> +#include <command.h> +#include <part.h> +#include <vsprintf.h> + +#ifndef CONFIG_PARTITION_UUIDS +#error CONFIG_PARTITION_UUIDS must be enabled for CONFIG_CMD_PART to be enabled +#endif + +int do_part_uuid(int argc, char * const argv[]) +{ + int part; + block_dev_desc_t *dev_desc; + disk_partition_t info; + + if (argc < 2) + return CMD_RET_USAGE; + if (argc > 3) + return CMD_RET_USAGE; + + part = get_device_and_partition(argv[0], argv[1], &dev_desc, &info, 0); + if (part < 0) + return 1; + + if (argc > 2) + setenv(argv[2], info.uuid); + else + printf("%s\n", info.uuid); + + return 0; +} + +int do_part_list(int argc, char * const argv[]) +{ + int ret; + block_dev_desc_t *desc; + + if (argc != 2) + return CMD_RET_USAGE; + + ret = get_device(argv[0], argv[1], &desc); + if (ret < 0) + return 1; + + print_part(desc); + + return 0; +} + +int do_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc < 2) + return CMD_RET_USAGE; + + if (!strcmp(argv[1], "uuid")) + return do_part_uuid(argc - 2, argv + 2); + else if (!strcmp(argv[1], "list")) + return do_part_list(argc - 2, argv + 2); + + return CMD_RET_USAGE; +} + +U_BOOT_CMD( + part, 5, 1, do_part, + "disk partition related commands", + "part uuid <interface> <dev>:<part>\n" + " - print partition UUID\n" + "part uuid <interface> <dev>:<part> <varname>\n" + " - set environment variable to partition UUID\n" + "part list <interface> <dev>\n" + " - print a device's partition table" +); diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c index 6b31dea..ee75db9 100644 --- a/common/cmd_pxe.c +++ b/common/cmd_pxe.c @@ -450,6 +450,7 @@ struct pxe_label { char *kernel; char *append; char *initrd; + char *fdt; int attempted; int localboot; struct list_head list; @@ -517,6 +518,9 @@ static void label_destroy(struct pxe_label *label) if (label->initrd) free(label->initrd); + if (label->fdt) + free(label->fdt); + free(label); } @@ -541,6 +545,9 @@ static void label_print(void *data) if (label->initrd) printf("\t\tinitrd: %s\n", label->initrd); + + if (label->fdt) + printf("\tfdt: %s\n", label->fdt); } /* @@ -628,10 +635,29 @@ static void label_boot(struct pxe_label *label) bootm_argv[1] = getenv("kernel_addr_r"); /* - * fdt usage is optional. If there is an fdt_addr specified, we will - * pass it along to bootm, and adjust argc appropriately. + * fdt usage is optional: + * It handles the following scenarios. All scenarios are exclusive + * + * Scenario 1: If fdt_addr_r specified and "fdt" label is defined in + * pxe file, retrieve fdt blob from server. Pass fdt_addr_r to bootm, + * and adjust argc appropriately. + * + * Scenario 2: If there is an fdt_addr specified, pass it along to + * bootm, and adjust argc appropriately. + * + * Scenario 3: fdt blob is not available. */ - bootm_argv[3] = getenv("fdt_addr"); + bootm_argv[3] = getenv("fdt_addr_r"); + + /* if fdt label is defined then get fdt from server */ + if (bootm_argv[3] && label->fdt) { + if (get_relfile_envaddr(label->fdt, "fdt_addr_r") < 0) { + printf("Skipping %s for failure retrieving fdt\n", + label->name); + return; + } + } else + bootm_argv[3] = getenv("fdt_addr"); if (bootm_argv[3]) bootm_argc = 4; @@ -658,6 +684,7 @@ enum token_type { T_DEFAULT, T_PROMPT, T_INCLUDE, + T_FDT, T_INVALID }; @@ -685,6 +712,7 @@ static const struct token keywords[] = { {"append", T_APPEND}, {"initrd", T_INITRD}, {"include", T_INCLUDE}, + {"fdt", T_FDT}, {NULL, T_INVALID} }; @@ -1074,6 +1102,11 @@ static int parse_label(char **c, struct pxe_menu *cfg) err = parse_sliteral(c, &label->initrd); break; + case T_FDT: + if (!label->fdt) + err = parse_sliteral(c, &label->fdt); + break; + case T_LOCALBOOT: err = parse_integer(c, &label->localboot); break; diff --git a/common/cmd_reiser.c b/common/cmd_reiser.c index fbb9484..e658618 100644 --- a/common/cmd_reiser.c +++ b/common/cmd_reiser.c @@ -50,43 +50,27 @@ int do_reiserls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = "/"; - int dev=0; - int part=1; - char *ep; + int dev, part; block_dev_desc_t *dev_desc=NULL; - int part_length; + disk_partition_t info; if (argc < 3) return CMD_RET_USAGE; - dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - - if (dev_desc == NULL) { - printf ("\n** Block device %s %d not supported\n", argv[1], dev); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); + if (part < 0) return 1; - } - - if (*ep) { - if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } if (argc == 4) { filename = argv[3]; } + dev = dev_desc->dev; PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename); - if ((part_length = reiserfs_set_blk_dev(dev_desc, part)) == 0) { - printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part); - return 1; - } + reiserfs_set_blk_dev(dev_desc, &info); - if (!reiserfs_mount(part_length)) { + if (!reiserfs_mount(info.size)) { printf ("** Bad Reiserfs partition or disk - %s %d:%d **\n", argv[1], dev, part); return 1; } @@ -112,9 +96,8 @@ U_BOOT_CMD( int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = NULL; - char *ep; - int dev, part = 0; - ulong addr = 0, part_length, filelen; + int dev, part; + ulong addr = 0, filelen; disk_partition_t info; block_dev_desc_t *dev_desc = NULL; char buf [12]; @@ -157,49 +140,19 @@ int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - if (dev_desc==NULL) { - printf ("\n** Block device %s %d not supported\n", argv[1], dev); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } - PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part); + dev = dev_desc->dev; - if (part != 0) { - if (get_partition_info (dev_desc, part, &info)) { - printf ("** Bad partition %d **\n", part); - return 1; - } + printf("Loading file \"%s\" from %s device %d%c%c\n", + filename, argv[1], dev, + part ? ':' : ' ', part ? part + '0' : ' '); - if (strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) { - printf ("\n** Invalid partition type \"%.32s\"" - " (expect \"" BOOT_PART_TYPE "\")\n", - info.type); - return 1; - } - PRINTF ("\nLoading from block device %s device %d, partition %d: " - "Name: %.32s Type: %.32s File:%s\n", - argv[1], dev, part, info.name, info.type, filename); - } else { - PRINTF ("\nLoading from block device %s device %d, File:%s\n", - argv[1], dev, filename); - } - - - if ((part_length = reiserfs_set_blk_dev(dev_desc, part)) == 0) { - printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part); - return 1; - } + reiserfs_set_blk_dev(dev_desc, &info); - if (!reiserfs_mount(part_length)) { + if (!reiserfs_mount(info.size)) { printf ("** Bad Reiserfs partition or disk - %s %d:%d **\n", argv[1], dev, part); return 1; } diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index d15b567..22d0119 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -206,128 +206,7 @@ block_dev_desc_t * scsi_get_dev(int dev) */ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - char *boot_device = NULL; - char *ep; - int dev, part = 0; - ulong addr, cnt; - disk_partition_t info; - image_header_t *hdr; -#if defined(CONFIG_FIT) - const void *fit_hdr = NULL; -#endif - - switch (argc) { - case 1: - addr = CONFIG_SYS_LOAD_ADDR; - boot_device = getenv ("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv ("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - default: - return CMD_RET_USAGE; - } - - if (!boot_device) { - puts ("\n** No boot device **\n"); - return 1; - } - - dev = simple_strtoul(boot_device, &ep, 16); - printf("booting from dev %d\n",dev); - if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { - printf ("\n** Device %d not available\n", dev); - return 1; - } - - if (*ep) { - if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } - if (get_partition_info (&scsi_dev_desc[dev], part, &info)) { - printf("error reading partinfo\n"); - return 1; - } - if ((strncmp((char *)(info.type), BOOT_PART_TYPE, sizeof(info.type)) != 0) && - (strncmp((char *)(info.type), BOOT_PART_COMP, sizeof(info.type)) != 0)) { - printf ("\n** Invalid partition type \"%.32s\"" - " (expect \"" BOOT_PART_TYPE "\")\n", - info.type); - return 1; - } - - printf ("\nLoading from SCSI device %d, partition %d: " - "Name: %.32s Type: %.32s\n", - dev, part, info.name, info.type); - - debug ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", - info.start, info.size, info.blksz); - - if (scsi_read (dev, info.start, 1, (ulong *)addr) != 1) { - printf ("** Read error on %d:%d\n", dev, part); - return 1; - } - - switch (genimg_get_format ((void *)addr)) { - case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *)addr; - - if (!image_check_hcrc (hdr)) { - puts ("\n** Bad Header Checksum **\n"); - return 1; - } - - image_print_contents (hdr); - cnt = image_get_image_size (hdr); - break; -#if defined(CONFIG_FIT) - case IMAGE_FORMAT_FIT: - fit_hdr = (const void *)addr; - puts ("Fit image detected...\n"); - - cnt = fit_get_size (fit_hdr); - break; -#endif - default: - puts ("** Unknown image type\n"); - return 1; - } - - cnt += info.blksz - 1; - cnt /= info.blksz; - cnt -= 1; - - if (scsi_read (dev, info.start+1, cnt, - (ulong *)(addr+info.blksz)) != cnt) { - printf ("** Read error on %d:%d\n", dev, part); - return 1; - } - -#if defined(CONFIG_FIT) - /* This cannot be done earlier, we need complete FIT image in RAM first */ - if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) { - if (!fit_check_format (fit_hdr)) { - puts ("** Bad FIT image format\n"); - return 1; - } - fit_print_contents (fit_hdr); - } -#endif - - /* Loading ok, update default load address */ - load_addr = addr; - - flush_cache (addr, (cnt+1)*info.blksz); - - return bootm_maybe_autostart(cmdtp, argv[0]); + return common_diskboot(cmdtp, "scsi", argc, argv); } /********************************************************************************* diff --git a/common/cmd_usb.c b/common/cmd_usb.c index a8e3ae5..181e727 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -355,143 +355,7 @@ void usb_show_tree(struct usb_device *dev) #ifdef CONFIG_USB_STORAGE int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - char *boot_device = NULL; - char *ep; - int dev, part = 1; - ulong addr, cnt; - disk_partition_t info; - image_header_t *hdr; - block_dev_desc_t *stor_dev; -#if defined(CONFIG_FIT) - const void *fit_hdr = NULL; -#endif - - switch (argc) { - case 1: - addr = CONFIG_SYS_LOAD_ADDR; - boot_device = getenv("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - default: - return CMD_RET_USAGE; - } - - if (!boot_device) { - puts("\n** No boot device **\n"); - return 1; - } - - dev = simple_strtoul(boot_device, &ep, 16); - stor_dev = usb_stor_get_dev(dev); - if (stor_dev == NULL || stor_dev->type == DEV_TYPE_UNKNOWN) { - printf("\n** Device %d not available\n", dev); - return 1; - } - if (stor_dev->block_read == NULL) { - printf("storage device not initialized. Use usb scan\n"); - return 1; - } - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } - - if (get_partition_info(stor_dev, part, &info)) { - /* try to boot raw .... */ - strncpy((char *)&info.type[0], BOOT_PART_TYPE, - sizeof(BOOT_PART_TYPE)); - strncpy((char *)&info.name[0], "Raw", 4); - info.start = 0; - info.blksz = 0x200; - info.size = 2880; - printf("error reading partinfo...try to boot raw\n"); - } - if ((strncmp((char *)info.type, BOOT_PART_TYPE, - sizeof(info.type)) != 0) && - (strncmp((char *)info.type, BOOT_PART_COMP, - sizeof(info.type)) != 0)) { - printf("\n** Invalid partition type \"%.32s\"" - " (expect \"" BOOT_PART_TYPE "\")\n", - info.type); - return 1; - } - printf("\nLoading from USB device %d, partition %d: " - "Name: %.32s Type: %.32s\n", - dev, part, info.name, info.type); - - debug("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", - info.start, info.size, info.blksz); - - if (stor_dev->block_read(dev, info.start, 1, (ulong *)addr) != 1) { - printf("** Read error on %d:%d\n", dev, part); - return 1; - } - - switch (genimg_get_format((void *)addr)) { - case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *)addr; - - if (!image_check_hcrc(hdr)) { - puts("\n** Bad Header Checksum **\n"); - return 1; - } - - image_print_contents(hdr); - - cnt = image_get_image_size(hdr); - break; -#if defined(CONFIG_FIT) - case IMAGE_FORMAT_FIT: - fit_hdr = (const void *)addr; - puts("Fit image detected...\n"); - - cnt = fit_get_size(fit_hdr); - break; -#endif - default: - puts("** Unknown image type\n"); - return 1; - } - - cnt += info.blksz - 1; - cnt /= info.blksz; - cnt -= 1; - - if (stor_dev->block_read(dev, info.start+1, cnt, - (ulong *)(addr+info.blksz)) != cnt) { - printf("\n** Read error on %d:%d\n", dev, part); - return 1; - } - -#if defined(CONFIG_FIT) - /* This cannot be done earlier, we need complete FIT image in RAM - * first - */ - if (genimg_get_format((void *)addr) == IMAGE_FORMAT_FIT) { - if (!fit_check_format(fit_hdr)) { - puts("** Bad FIT image format\n"); - return 1; - } - fit_print_contents(fit_hdr); - } -#endif - - /* Loading ok, update default load address */ - load_addr = addr; - - flush_cache(addr, (cnt+1)*info.blksz); - - return bootm_maybe_autostart(cmdtp, argv[0]); + return common_diskboot(cmdtp, "usb", argc, argv); } #endif /* CONFIG_USB_STORAGE */ diff --git a/common/cmd_zfs.c b/common/cmd_zfs.c index a6ea2c0..d580f7b 100644 --- a/common/cmd_zfs.c +++ b/common/cmd_zfs.c @@ -49,12 +49,11 @@ static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *filename = NULL; - char *ep; int dev; - unsigned long part = 1; + int part; ulong addr = 0; - ulong part_length; disk_partition_t info; + block_dev_desc_t *dev_desc; char buf[12]; unsigned long count; const char *addr_str; @@ -95,48 +94,17 @@ static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - dev = (int)simple_strtoul(argv[2], &ep, 16); - zfs_dev_desc = get_dev(argv[1], dev); - if (zfs_dev_desc == NULL) { - printf("** Block device %s %d not supported\n", argv[1], dev); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts("** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } + dev = dev_desc->dev; + printf("Loading file \"%s\" from %s device %d%c%c\n", + filename, argv[1], dev, + part ? ':' : ' ', part ? part + '0' : ' '); - if (part != 0) { - if (get_partition_info(zfs_dev_desc, part, &info)) { - printf("** Bad partition %lu **\n", part); - return 1; - } - - if (strncmp((char *)info.type, BOOT_PART_TYPE, - strlen(BOOT_PART_TYPE)) != 0) { - printf("** Invalid partition type \"%s\" (expect \"" BOOT_PART_TYPE "\")\n", - info.type); - return 1; - } - printf("Loading file \"%s\" " - "from %s device %d:%lu %s\n", - filename, argv[1], dev, part, info.name); - } else { - printf("Loading file \"%s\" from %s device %d\n", - filename, argv[1], dev); - } - - part_length = zfs_set_blk_dev(zfs_dev_desc, part); - if (part_length == 0) { - printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part); - return 1; - } - - vdev.part_length = part_length; + zfs_set_blk_dev(dev_desc, &info); + vdev.part_length = info.size; memset(&zfile, 0, sizeof(zfile)); zfile.device = &vdev; @@ -149,7 +117,7 @@ static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) zfile.size = (uint64_t)count; if (zfs_read(&zfile, (char *)addr, zfile.size) != zfile.size) { - printf("** Unable to read \"%s\" from %s %d:%lu **\n", + printf("** Unable to read \"%s\" from %s %d:%d **\n", filename, argv[1], dev, part); zfs_close(&zfile); return 1; @@ -181,41 +149,23 @@ int zfs_print(const char *entry, const struct zfs_dirhook_info *data) static int do_zfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { const char *filename = "/"; - int dev; - unsigned long part = 1; - char *ep; - int part_length; + int part; + block_dev_desc_t *dev_desc; + disk_partition_t info; struct device_s vdev; - if (argc < 3) + if (argc < 2) return cmd_usage(cmdtp); - dev = (int)simple_strtoul(argv[2], &ep, 16); - zfs_dev_desc = get_dev(argv[1], dev); - - if (zfs_dev_desc == NULL) { - printf("\n** Block device %s %d not supported\n", argv[1], dev); - return 1; - } - - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } - if (argc == 4) filename = argv[3]; - part_length = zfs_set_blk_dev(zfs_dev_desc, part); - if (part_length == 0) { - printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); + if (part < 0) return 1; - } - vdev.part_length = part_length; + zfs_set_blk_dev(dev_desc, &info); + vdev.part_length = info.size; zfs_ls(&vdev, filename, zfs_print); diff --git a/common/cmd_zip.c b/common/cmd_zip.c new file mode 100644 index 0000000..a73c86d --- /dev/null +++ b/common/cmd_zip.c @@ -0,0 +1,60 @@ +/* + * (C) Copyright 2012 + * Lei Wen <leiwen@marvell.com>, Marvell Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> + +static int do_zip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unsigned long src, dst; + unsigned long src_len, dst_len = ~0UL; + char buf[32]; + + switch (argc) { + case 5: + dst_len = simple_strtoul(argv[4], NULL, 16); + /* fall through */ + case 4: + src = simple_strtoul(argv[1], NULL, 16); + src_len = simple_strtoul(argv[2], NULL, 16); + dst = simple_strtoul(argv[3], NULL, 16); + break; + default: + return cmd_usage(cmdtp); + } + + if (gzip((void *) dst, &dst_len, (void *) src, src_len) != 0) + return 1; + + printf("Compressed size: %ld = 0x%lX\n", dst_len, dst_len); + sprintf(buf, "%lX", dst_len); + setenv("filesize", buf); + + return 0; +} + +U_BOOT_CMD( + zip, 5, 1, do_zip, + "zip a memory region", + "srcaddr srcsize dstaddr [dstsize]" +); diff --git a/common/dlmalloc.c b/common/dlmalloc.c index c645d73..1d7e527 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -1487,11 +1487,11 @@ static mbinptr av_[NAV * 2 + 2] = { #ifdef CONFIG_NEEDS_MANUAL_RELOC void malloc_bin_reloc (void) { - unsigned long *p = (unsigned long *)(&av_[2]); - int i; - for (i=2; i<(sizeof(av_)/sizeof(mbinptr)); ++i) { - *p++ += gd->reloc_off; - } + mbinptr *p = &av_[2]; + size_t i; + + for (i = 2; i < ARRAY_SIZE(av_); ++i, ++p) + *p = (mbinptr)((ulong)*p + gd->reloc_off); } #endif diff --git a/common/env_common.c b/common/env_common.c index d9e990d..3e46c26 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -80,6 +80,9 @@ const uchar default_environment[] = { #ifdef CONFIG_ETH5ADDR "eth5addr=" MK_STR(CONFIG_ETH5ADDR) "\0" #endif +#ifdef CONFIG_ETHPRIME + "ethprime=" CONFIG_ETHPRIME "\0" +#endif #ifdef CONFIG_IPADDR "ipaddr=" MK_STR(CONFIG_IPADDR) "\0" #endif @@ -133,7 +136,9 @@ const uchar default_environment[] = { "\0" }; -struct hsearch_data env_htab; +struct hsearch_data env_htab = { + .apply = env_check_apply, +}; static uchar __env_get_char_spec(int index) { @@ -175,6 +180,11 @@ const uchar *env_get_addr(int index) void set_default_env(const char *s) { + /* + * By default, do not apply changes as they will eventually + * be applied by someone else + */ + int do_apply = 0; if (sizeof(default_environment) > ENV_SIZE) { puts("*** Error - default environment is too large\n\n"); return; @@ -186,6 +196,14 @@ void set_default_env(const char *s) "using default environment\n\n", s + 1); } else { + /* + * This set_to_default was explicitly asked for + * by the user, as opposed to being a recovery + * mechanism. Therefore we check every single + * variable and apply changes to the system + * right away (e.g. baudrate, console). + */ + do_apply = 1; puts(s); } } else { @@ -193,12 +211,26 @@ void set_default_env(const char *s) } if (himport_r(&env_htab, (char *)default_environment, - sizeof(default_environment), '\0', 0) == 0) + sizeof(default_environment), '\0', 0, + 0, NULL, do_apply) == 0) error("Environment import failed: errno = %d\n", errno); gd->flags |= GD_FLG_ENV_READY; } + +/* [re]set individual variables to their value in the default environment */ +int set_default_vars(int nvars, char * const vars[]) +{ + /* + * Special use-case: import from default environment + * (and use \0 as a separator) + */ + return himport_r(&env_htab, (const char *)default_environment, + sizeof(default_environment), '\0', H_NOCLEAR, + nvars, vars, 1 /* do_apply */); +} + /* * Check if CRC is valid and (if yes) import the environment. * Note that "buf" may or may not be aligned. @@ -218,7 +250,8 @@ int env_import(const char *buf, int check) } } - if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0)) { + if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, + 0, NULL, 0 /* do_apply */)) { gd->flags |= GD_FLG_ENV_READY; return 1; } diff --git a/common/env_fat.c b/common/env_fat.c index bad92aa..6ef5318 100644 --- a/common/env_fat.c +++ b/common/env_fat.c @@ -40,11 +40,6 @@ env_t *env_ptr; DECLARE_GLOBAL_DATA_PTR; -uchar env_get_char_spec(int index) -{ - return *((uchar *)(gd->env_addr + index)); -} - int env_init(void) { /* use default */ @@ -63,6 +58,7 @@ int saveenv(void) block_dev_desc_t *dev_desc = NULL; int dev = FAT_ENV_DEVICE; int part = FAT_ENV_PART; + int err; res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL); @@ -72,7 +68,7 @@ int saveenv(void) } #ifdef CONFIG_MMC - if (strcmp (FAT_ENV_INTERFACE, "mmc") == 0) { + if (strcmp(FAT_ENV_INTERFACE, "mmc") == 0) { struct mmc *mmc = find_mmc_device(dev); if (!mmc) { @@ -91,14 +87,17 @@ int saveenv(void) FAT_ENV_INTERFACE, dev); return 1; } - if (fat_register_device(dev_desc, part) != 0) { + + err = fat_register_device(dev_desc, part); + if (err) { printf("Failed to register %s%d:%d\n", FAT_ENV_INTERFACE, dev, part); return 1; } env_new.crc = crc32(0, env_new.data, ENV_SIZE); - if (file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)) == -1) { + err = file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)); + if (err == -1) { printf("\n** Unable to write \"%s\" from %s%d:%d **\n", FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part); return 1; @@ -115,9 +114,10 @@ void env_relocate_spec(void) block_dev_desc_t *dev_desc = NULL; int dev = FAT_ENV_DEVICE; int part = FAT_ENV_PART; + int err; #ifdef CONFIG_MMC - if (strcmp (FAT_ENV_INTERFACE, "mmc") == 0) { + if (strcmp(FAT_ENV_INTERFACE, "mmc") == 0) { struct mmc *mmc = find_mmc_device(dev); if (!mmc) { @@ -138,14 +138,17 @@ void env_relocate_spec(void) set_default_env(NULL); return; } - if (fat_register_device(dev_desc, part) != 0) { + + err = fat_register_device(dev_desc, part); + if (err) { printf("Failed to register %s%d:%d\n", FAT_ENV_INTERFACE, dev, part); set_default_env(NULL); return; } - if (file_fat_read(FAT_ENV_FILE, (unsigned char *)&buf, CONFIG_ENV_SIZE) == -1) { + err = file_fat_read(FAT_ENV_FILE, (uchar *)&buf, CONFIG_ENV_SIZE); + if (err == -1) { printf("\n** Unable to read \"%s\" from %s%d:%d **\n", FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part); set_default_env(NULL); diff --git a/common/env_nand.c b/common/env_nand.c index e8daec9..79e8033 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -226,7 +226,7 @@ int saveenv(void) int saveenv(void) { int ret = 0; - env_t env_new; + ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); ssize_t len; char *res; nand_erase_options_t nand_erase_options; @@ -238,20 +238,20 @@ int saveenv(void) if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) return 1; - res = (char *)&env_new.data; + res = (char *)&env_new->data; len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new->crc = crc32(0, env_new->data, ENV_SIZE); puts("Erasing Nand...\n"); if (nand_erase_opts(&nand_info[0], &nand_erase_options)) return 1; puts("Writing to Nand... "); - if (writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new)) { + if (writeenv(CONFIG_ENV_OFFSET, (u_char *)env_new)) { puts("FAILED!\n"); return 1; } @@ -398,7 +398,7 @@ void env_relocate_spec(void) { #if !defined(ENV_IS_EMBEDDED) int ret; - char buf[CONFIG_ENV_SIZE]; + ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); #if defined(CONFIG_ENV_OFFSET_OOB) ret = get_nand_env_oob(&nand_info[0], &nand_env_oob_offset); diff --git a/common/env_remote.c b/common/env_remote.c index 3bf0f95..6c10c90 100644 --- a/common/env_remote.c +++ b/common/env_remote.c @@ -41,11 +41,6 @@ DECLARE_GLOBAL_DATA_PTR; #define CONFIG_ENV_OFFSET 0 #endif -uchar env_get_char_spec(int index) -{ - return *((uchar *)(gd->env_addr + index)); -} - int env_init(void) { if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) { @@ -62,8 +57,8 @@ int env_init(void) #ifdef CONFIG_CMD_SAVEENV int saveenv(void) { -#ifdef CONFIG_SRIOBOOT_SLAVE - printf("Can not support the 'saveenv' when boot from SRIO!\n"); +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE + printf("Can not support the 'saveenv' when boot from SRIO or PCIE!\n"); return 1; #else return 0; diff --git a/common/flash.c b/common/flash.c index 781cb9c..8244ba2 100644 --- a/common/flash.c +++ b/common/flash.c @@ -221,6 +221,9 @@ void flash_perror (int err) case ERR_PROG_ERROR: puts ("General Flash Programming Error\n"); break; + case ERR_ABORTED: + puts("Flash Programming Aborted\n"); + break; default: printf ("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err); break; diff --git a/common/hush.c b/common/hush.c index 1eff182..4c84c2f 100644 --- a/common/hush.c +++ b/common/hush.c @@ -127,6 +127,7 @@ #endif #endif #define SPECIAL_VAR_SYMBOL 03 +#define SUBSTED_VAR_SYMBOL 04 #ifndef __U_BOOT__ #define FLAG_EXIT_FROM_LOOP 1 #define FLAG_PARSE_SEMICOLON (1 << 1) /* symbol ';' is special for parser */ @@ -499,6 +500,7 @@ static void remove_bg_job(struct pipe *pi); /* local variable support */ static char **make_list_in(char **inp, char *name); static char *insert_var_value(char *inp); +static char *insert_var_value_sub(char *inp, int tag_subst); #ifndef __U_BOOT__ /* Table of built-in functions. They can be forked or not, depending on @@ -2743,13 +2745,50 @@ static int parse_group(o_string *dest, struct p_context *ctx, static char *lookup_param(char *src) { char *p; + char *sep; + char *default_val = NULL; + int assign = 0; + int expand_empty = 0; if (!src) return NULL; - p = getenv(src); - if (!p) - p = get_local_var(src); + sep = strchr(src, ':'); + + if (sep) { + *sep = '\0'; + if (*(sep + 1) == '-') + default_val = sep+2; + if (*(sep + 1) == '=') { + default_val = sep+2; + assign = 1; + } + if (*(sep + 1) == '+') { + default_val = sep+2; + expand_empty = 1; + } + } + + p = getenv(src); + if (!p) + p = get_local_var(src); + + if (!p || strlen(p) == 0) { + p = default_val; + if (assign) { + char *var = malloc(strlen(src)+strlen(default_val)+2); + if (var) { + sprintf(var, "%s=%s", src, default_val); + set_local_var(var, 0); + } + free(var); + } + } else if (expand_empty) { + p += strlen(p); + } + + if (sep) + *sep = ':'; return p; } @@ -3051,6 +3090,21 @@ int parse_stream(o_string *dest, struct p_context *ctx, return 1; break; #endif + case SUBSTED_VAR_SYMBOL: + dest->nonnull = 1; + while (ch = b_getch(input), ch != EOF && + ch != SUBSTED_VAR_SYMBOL) { + debug_printf("subst, pass=%d\n", ch); + if (input->__promptme == 0) + return 1; + b_addchr(dest, ch); + } + debug_printf("subst, term=%d\n", ch); + if (ch == EOF) { + syntax(); + return 1; + } + break; default: syntax(); /* this is really an internal logic error */ return 1; @@ -3092,6 +3146,10 @@ void update_ifs_map(void) mapset((uchar *)"\\$'\"`", 3); /* never flow through */ mapset((uchar *)"<>;&|(){}#", 1); /* flow through if quoted */ #else + { + uchar subst[2] = {SUBSTED_VAR_SYMBOL, 0}; + mapset(subst, 3); /* never flow through */ + } mapset((uchar *)"\\$'\"", 3); /* never flow through */ mapset((uchar *)";&|#", 1); /* flow through if quoted */ #endif @@ -3431,25 +3489,57 @@ final_return: static char *insert_var_value(char *inp) { + return insert_var_value_sub(inp, 0); +} + +static char *insert_var_value_sub(char *inp, int tag_subst) +{ int res_str_len = 0; int len; int done = 0; char *p, *p1, *res_str = NULL; while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) { + /* check the beginning of the string for normal charachters */ if (p != inp) { + /* copy any charachters to the result string */ len = p - inp; res_str = xrealloc(res_str, (res_str_len + len)); strncpy((res_str + res_str_len), inp, len); res_str_len += len; } inp = ++p; + /* find the ending marker */ p = strchr(inp, SPECIAL_VAR_SYMBOL); *p = '\0'; + /* look up the value to substitute */ if ((p1 = lookup_param(inp))) { - len = res_str_len + strlen(p1); + if (tag_subst) + len = res_str_len + strlen(p1) + 2; + else + len = res_str_len + strlen(p1); res_str = xrealloc(res_str, (1 + len)); - strcpy((res_str + res_str_len), p1); + if (tag_subst) { + /* + * copy the variable value to the result + * string + */ + strcpy((res_str + res_str_len + 1), p1); + + /* + * mark the replaced text to be accepted as + * is + */ + res_str[res_str_len] = SUBSTED_VAR_SYMBOL; + res_str[res_str_len + 1 + strlen(p1)] = + SUBSTED_VAR_SYMBOL; + } else + /* + * copy the variable value to the result + * string + */ + strcpy((res_str + res_str_len), p1); + res_str_len = len; } *p = SPECIAL_VAR_SYMBOL; @@ -3513,9 +3603,14 @@ static char * make_string(char ** inp) char *str = NULL; int n; int len = 2; + char *noeval_str; + int noeval = 0; + noeval_str = get_local_var("HUSH_NO_EVAL"); + if (noeval_str != NULL && *noeval_str != '0' && *noeval_str != '\0') + noeval = 1; for (n = 0; inp[n]; n++) { - p = insert_var_value(inp[n]); + p = insert_var_value_sub(inp[n], noeval); str = xrealloc(str, (len + strlen(p))); if (n) { strcat(str, " "); diff --git a/common/image.c b/common/image.c index 91954ac..f084d2b 100644 --- a/common/image.c +++ b/common/image.c @@ -143,6 +143,7 @@ static const table_entry_t uimage_type[] = { { IH_TYPE_INVALID, NULL, "Invalid Image", }, { IH_TYPE_MULTI, "multi", "Multi-File Image", }, { IH_TYPE_OMAPIMAGE, "omapimage", "TI OMAP SPL With GP CH",}, + { IH_TYPE_PBLIMAGE, "pblimage", "Freescale PBL Boot Image",}, { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, { IH_TYPE_SCRIPT, "script", "Script", }, { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, @@ -2042,13 +2043,13 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) printf("%s Architecture: %s\n", p, genimg_get_arch_name(arch)); } - if (type == IH_TYPE_KERNEL) { + if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK)) { fit_image_get_os(fit, image_noffset, &os); printf("%s OS: %s\n", p, genimg_get_os_name(os)); } if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || - (type == IH_TYPE_FIRMWARE)) { + (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK)) { ret = fit_image_get_load(fit, image_noffset, &load); printf("%s Load Address: ", p); if (ret) @@ -2057,7 +2058,8 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) printf("0x%08lx\n", load); } - if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) { + if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || + (type == IH_TYPE_RAMDISK)) { fit_image_get_entry(fit, image_noffset, &entry); printf("%s Entry Point: ", p); if (ret) diff --git a/common/lcd.c b/common/lcd.c index 506a138..b6be800 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -498,23 +498,43 @@ static int lcd_getbgcolor(void) /************************************************************************/ /* ** Chipset depending Bitmap / Logo stuff... */ /************************************************************************/ +static inline ushort *configuration_get_cmap(void) +{ +#if defined CONFIG_CPU_PXA + struct pxafb_info *fbi = &panel_info.pxa; + return (ushort *)fbi->palette; +#elif defined(CONFIG_MPC823) + immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; + cpm8xx_t *cp = &(immr->im_cpm); + return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]); +#elif defined(CONFIG_ATMEL_LCD) + return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); +#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) + return panel_info.cmap; +#else +#if defined(CONFIG_LCD_LOGO) + return bmp_logo_palette; +#else + return NULL; +#endif +#endif +} + #ifdef CONFIG_LCD_LOGO void bitmap_plot(int x, int y) { #ifdef CONFIG_ATMEL_LCD - uint *cmap; + uint *cmap = (uint *)bmp_logo_palette; #else - ushort *cmap; + ushort *cmap = (ushort *)bmp_logo_palette; #endif ushort i, j; uchar *bmap; uchar *fb; ushort *fb16; -#if defined(CONFIG_CPU_PXA) - struct pxafb_info *fbi = &panel_info.pxa; -#elif defined(CONFIG_MPC823) - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - volatile cpm8xx_t *cp = &(immr->im_cpm); +#if defined(CONFIG_MPC823) + immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; + cpm8xx_t *cp = &(immr->im_cpm); #endif debug("Logo: width %d height %d colors %d cmap %d\n", @@ -525,20 +545,17 @@ void bitmap_plot(int x, int y) fb = (uchar *)(lcd_base + y * lcd_line_length + x); if (NBITS(panel_info.vl_bpix) < 12) { - /* Leave room for default color map */ -#if defined(CONFIG_CPU_PXA) - cmap = (ushort *) fbi->palette; -#elif defined(CONFIG_MPC823) + /* Leave room for default color map + * default case: generic system with no cmap (most likely 16bpp) + * cmap was set to the source palette, so no change is done. + * This avoids even more ifdefs in the next stanza + */ +#if defined(CONFIG_MPC823) cmap = (ushort *) &(cp->lcd_cmap[BMP_LOGO_OFFSET * sizeof(ushort)]); #elif defined(CONFIG_ATMEL_LCD) - cmap = (uint *) (panel_info.mmio + ATMEL_LCDC_LUT(0)); + cmap = (uint *)configuration_get_cmap(); #else - /* - * default case: generic system with no cmap (most likely 16bpp) - * We set cmap to the source palette, so no change is done. - * This avoids even more ifdef in the next stanza - */ - cmap = bmp_logo_palette; + cmap = configuration_get_cmap(); #endif WATCHDOG_RESET(); @@ -607,7 +624,46 @@ static inline void bitmap_plot(int x, int y) {} #ifdef CONFIG_SPLASH_SCREEN_ALIGN #define BMP_ALIGN_CENTER 0x7FFF + +static void splash_align_axis(int *axis, unsigned long panel_size, + unsigned long picture_size) +{ + unsigned long panel_picture_delta = panel_size - picture_size; + unsigned long axis_alignment; + + if (*axis == BMP_ALIGN_CENTER) + axis_alignment = panel_picture_delta / 2; + else if (*axis < 0) + axis_alignment = panel_picture_delta + *axis + 1; + else + return; + + *axis = max(0, axis_alignment); +} +#endif + +#if defined(CONFIG_MPC823) || defined(CONFIG_MCC200) +#define FB_PUT_BYTE(fb, from) *(fb)++ = (255 - *(from)++) +#else +#define FB_PUT_BYTE(fb, from) *(fb)++ = *(from)++ +#endif + +#if defined(CONFIG_BMP_16BPP) +#if defined(CONFIG_ATMEL_LCD_BGR555) +static inline void fb_put_word(uchar **fb, uchar **from) +{ + *(*fb)++ = (((*from)[0] & 0x1f) << 2) | ((*from)[1] & 0x03); + *(*fb)++ = ((*from)[0] & 0xe0) | (((*from)[1] & 0x7c) >> 2); + *from += 2; +} +#else +static inline void fb_put_word(uchar **fb, uchar **from) +{ + *(*fb)++ = *(*from)++; + *(*fb)++ = *(*from)++; +} #endif +#endif /* CONFIG_BMP_16BPP */ int lcd_display_bitmap(ulong bmp_image, int x, int y) { @@ -623,14 +679,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) unsigned long width, height, byte_width; unsigned long pwidth = panel_info.vl_col; unsigned colors, bpix, bmp_bpix; -#if defined(CONFIG_CPU_PXA) - struct pxafb_info *fbi = &panel_info.pxa; -#elif defined(CONFIG_MPC823) - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - volatile cpm8xx_t *cp = &(immr->im_cpm); -#endif - if (!((bmp->header.signature[0] == 'B') && + if (!bmp || !((bmp->header.signature[0] == 'B') && (bmp->header.signature[1] == 'M'))) { printf("Error: no valid bmp image at %lx\n", bmp_image); @@ -666,14 +716,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) #if !defined(CONFIG_MCC200) /* MCC200 LCD doesn't need CMAP, supports 1bpp b&w only */ if (bmp_bpix == 8) { -#if defined(CONFIG_CPU_PXA) - cmap = (ushort *)fbi->palette; -#elif defined(CONFIG_MPC823) - cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]); -#elif !defined(CONFIG_ATMEL_LCD) && !defined(CONFIG_EXYNOS_FB) - cmap = panel_info.cmap; -#endif - + cmap = configuration_get_cmap(); cmap_base = cmap; /* Set color map */ @@ -722,15 +765,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) padded_line = (width&0x3) ? ((width&~0x3)+4) : (width); #ifdef CONFIG_SPLASH_SCREEN_ALIGN - if (x == BMP_ALIGN_CENTER) - x = max(0, (pwidth - width) / 2); - else if (x < 0) - x = max(0, pwidth - width + x + 1); - - if (y == BMP_ALIGN_CENTER) - y = max(0, (panel_info.vl_row - height) / 2); - else if (y < 0) - y = max(0, panel_info.vl_row - height + y + 1); + splash_align_axis(&x, pwidth, width); + splash_align_axis(&y, panel_info.vl_row, height); #endif /* CONFIG_SPLASH_SCREEN_ALIGN */ if ((x + width) > pwidth) @@ -754,11 +790,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) WATCHDOG_RESET(); for (j = 0; j < width; j++) { if (bpix != 16) { -#if defined(CONFIG_CPU_PXA) || defined(CONFIG_ATMEL_LCD) - *(fb++) = *(bmap++); -#elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200) - *(fb++) = 255 - *(bmap++); -#endif + FB_PUT_BYTE(fb, bmap); } else { *(uint16_t *)fb = cmap_base[*(bmap++)]; fb += sizeof(uint16_t) / sizeof(*fb); @@ -773,18 +805,9 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) case 16: for (i = 0; i < height; ++i) { WATCHDOG_RESET(); - for (j = 0; j < width; j++) { -#if defined(CONFIG_ATMEL_LCD_BGR555) - *(fb++) = ((bmap[0] & 0x1f) << 2) | - (bmap[1] & 0x03); - *(fb++) = (bmap[0] & 0xe0) | - ((bmap[1] & 0x7c) >> 2); - bmap += 2; -#else - *(fb++) = *(bmap++); - *(fb++) = *(bmap++); -#endif - } + for (j = 0; j < width; j++) + fb_put_word(&fb, &bmap); + bmap += (padded_line - width) * 2; fb -= (width * 2 + lcd_line_length); } @@ -842,17 +865,7 @@ static void *lcd_logo(void) } #endif /* CONFIG_SPLASH_SCREEN_ALIGN */ -#ifdef CONFIG_VIDEO_BMP_GZIP - bmp_image_t *bmp = (bmp_image_t *)addr; - unsigned long len; - - if (!((bmp->header.signature[0] == 'B') && - (bmp->header.signature[1] == 'M'))) { - addr = (ulong)gunzip_bmp(addr, &len); - } -#endif - - if (lcd_display_bitmap(addr, x, y) == 0) + if (bmp_display(addr, x, y) == 0) return (void *)lcd_base; } #endif /* CONFIG_SPLASH_SCREEN */ diff --git a/common/spl/Makefile b/common/spl/Makefile new file mode 100644 index 0000000..7cf01ad --- /dev/null +++ b/common/spl/Makefile @@ -0,0 +1,39 @@ +# +# (C) Copyright 2012 +# Texas Instruments Incorporated - http://www.ti.com/ +# Aneesh V <aneesh@ti.com> +# +# This file is released under the terms of GPL v2 and any later version. +# See the file COPYING in the root directory of the source tree for details. +# +# Based on common/Makefile. +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)libspl.o + +ifdef CONFIG_SPL_BUILD +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o +COBJS-$(CONFIG_SPL_NOR_SUPPORT) += spl_nor.o +COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o +COBJS-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o +endif + +COBJS := $(sort $(COBJS-y)) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/common/spl/spl.c index 4d1ac85..c640f87 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/common/spl/spl.c @@ -23,15 +23,11 @@ * MA 02111-1307 USA */ #include <common.h> +#include <spl.h> #include <asm/u-boot.h> -#include <asm/utils.h> -#include <asm/arch/sys_proto.h> #include <nand.h> -#include <mmc.h> #include <fat.h> #include <version.h> -#include <asm/omap_common.h> -#include <asm/arch/mmc_host_def.h> #include <i2c.h> #include <image.h> #include <malloc.h> @@ -39,11 +35,17 @@ DECLARE_GLOBAL_DATA_PTR; -u32* boot_params_ptr = NULL; +#ifndef CONFIG_SYS_UBOOT_START +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE +#endif +#ifndef CONFIG_SYS_MONITOR_LEN +#define CONFIG_SYS_MONITOR_LEN (200 * 1024) +#endif + +u32 *boot_params_ptr = NULL; struct spl_image_info spl_image; -/* Define global data structure pointer to it*/ -static gd_t gdata __attribute__ ((section(".data"))); +/* Define board data structure */ static bd_t bdata __attribute__ ((section(".data"))); inline void hang(void) @@ -53,18 +55,6 @@ inline void hang(void) ; } -void board_init_f(ulong dummy) -{ - /* - * We call relocate_code() with relocation target same as the - * CONFIG_SYS_SPL_TEXT_BASE. This will result in relocation getting - * skipped. Instead, only .bss initialization will happen. That's - * all we need - */ - debug(">>board_init_f()\n"); - relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); -} - /* * Default function to determine if u-boot or the OS should * be started. This implementation always returns 1. @@ -78,8 +68,8 @@ void board_init_f(ulong dummy) #ifdef CONFIG_SPL_OS_BOOT __weak int spl_start_uboot(void) { - printf("SPL: Please implement spl_start_uboot() for your board\n"); - printf("SPL: Direct Linux boot not active!\n"); + puts("SPL: Please implement spl_start_uboot() for your board\n"); + puts("SPL: Direct Linux boot not active!\n"); return 1; } #endif @@ -88,47 +78,41 @@ void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); - if (__be32_to_cpu(header->ih_magic) == IH_MAGIC) { - spl_image.size = __be32_to_cpu(header->ih_size) + header_size; - spl_image.entry_point = __be32_to_cpu(header->ih_load); - /* Load including the header */ - spl_image.load_addr = spl_image.entry_point - header_size; - spl_image.os = header->ih_os; - spl_image.name = (const char *)&header->ih_name; + if (image_get_magic(header) == IH_MAGIC) { + if (spl_image.flags & SPL_COPY_PAYLOAD_ONLY) { + /* + * On some system (e.g. powerpc), the load-address and + * entry-point is located at address 0. We can't load + * to 0-0x40. So skip header in this case. + */ + spl_image.load_addr = image_get_load(header); + spl_image.entry_point = image_get_ep(header); + spl_image.size = image_get_data_size(header); + } else { + spl_image.entry_point = image_get_load(header); + /* Load including the header */ + spl_image.load_addr = spl_image.entry_point - + header_size; + spl_image.size = image_get_data_size(header) + + header_size; + } + spl_image.os = image_get_os(header); + spl_image.name = image_get_name(header); debug("spl: payload image: %s load addr: 0x%x size: %d\n", spl_image.name, spl_image.load_addr, spl_image.size); } else { /* Signature not found - assume u-boot.bin */ - printf("mkimage signature not found - ih_magic = %x\n", + debug("mkimage signature not found - ih_magic = %x\n", header->ih_magic); - debug("Assuming u-boot.bin ..\n"); /* Let's assume U-Boot will not be more than 200 KB */ - spl_image.size = 200 * 1024; - spl_image.entry_point = CONFIG_SYS_TEXT_BASE; + spl_image.size = CONFIG_SYS_MONITOR_LEN; + spl_image.entry_point = CONFIG_SYS_UBOOT_START; spl_image.load_addr = CONFIG_SYS_TEXT_BASE; spl_image.os = IH_OS_U_BOOT; spl_image.name = "U-Boot"; } } -/* - * This function jumps to an image with argument. Normally an FDT or ATAGS - * image. - * arg: Pointer to paramter image in RAM - */ -#ifdef CONFIG_SPL_OS_BOOT -static void __noreturn jump_to_image_linux(void *arg) -{ - debug("Entering kernel arg pointer: 0x%p\n", arg); - typedef void (*image_entry_arg_t)(int, int, void *) - __attribute__ ((noreturn)); - image_entry_arg_t image_entry = - (image_entry_arg_t) spl_image.entry_point; - cleanup_before_linux(); - image_entry(0, CONFIG_MACH_TYPE, arg); -} -#endif - static void __noreturn jump_to_image_no_args(void) { typedef void __noreturn (*image_entry_noargs_t)(u32 *); @@ -144,21 +128,45 @@ static void __noreturn jump_to_image_no_args(void) image_entry((u32 *)boot_params_ptr_addr); } -void board_init_r(gd_t *id, ulong dummy) +#ifdef CONFIG_SPL_RAM_DEVICE +static void spl_ram_load_image(void) +{ + const struct image_header *header; + + /* + * Get the header. It will point to an address defined by handoff + * which will tell where the image located inside the flash. For + * now, it will temporary fixed to address pointed by U-Boot. + */ + header = (struct image_header *) + (CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); + + spl_parse_image_header(header); +} +#endif + +void board_init_r(gd_t *dummy1, ulong dummy2) { u32 boot_device; debug(">>spl:board_init_r()\n"); +#ifdef CONFIG_SYS_SPL_MALLOC_START mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, CONFIG_SYS_SPL_MALLOC_SIZE); +#endif #ifdef CONFIG_SPL_BOARD_INIT spl_board_init(); #endif - boot_device = omap_boot_device(); + boot_device = spl_boot_device(); debug("boot device - %d\n", boot_device); switch (boot_device) { +#ifdef CONFIG_SPL_RAM_DEVICE + case BOOT_DEVICE_RAM: + spl_ram_load_image(); + break; +#endif #ifdef CONFIG_SPL_MMC_SUPPORT case BOOT_DEVICE_MMC1: case BOOT_DEVICE_MMC2: @@ -171,41 +179,48 @@ void board_init_r(gd_t *id, ulong dummy) spl_nand_load_image(); break; #endif +#ifdef CONFIG_SPL_NOR_SUPPORT + case BOOT_DEVICE_NOR: + spl_nor_load_image(); + break; +#endif #ifdef CONFIG_SPL_YMODEM_SUPPORT case BOOT_DEVICE_UART: spl_ymodem_load_image(); break; #endif +#ifdef CONFIG_SPL_SPI_SUPPORT + case BOOT_DEVICE_SPI: + spl_spi_load_image(); + break; +#endif default: - printf("SPL: Un-supported Boot Device - %d!!!\n", boot_device); + debug("SPL: Un-supported Boot Device\n"); hang(); - break; } switch (spl_image.os) { case IH_OS_U_BOOT: debug("Jumping to U-Boot\n"); - jump_to_image_no_args(); break; #ifdef CONFIG_SPL_OS_BOOT case IH_OS_LINUX: debug("Jumping to Linux\n"); spl_board_prepare_for_linux(); jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); - break; #endif default: - puts("Unsupported OS image.. Jumping nevertheless..\n"); - jump_to_image_no_args(); + debug("Unsupported OS image.. Jumping nevertheless..\n"); } + jump_to_image_no_args(); } -/* This requires UART clocks to be enabled */ +/* + * This requires UART clocks to be enabled. In order for this to work the + * caller must ensure that the gd pointer is valid. + */ void preloader_console_init(void) { - const char *u_boot_rev = U_BOOT_VERSION; - - gd = &gdata; gd->bd = &bdata; gd->flags |= GD_FLG_RELOC; gd->baudrate = CONFIG_BAUDRATE; @@ -214,15 +229,9 @@ void preloader_console_init(void) gd->have_console = 1; - /* Avoid a second "U-Boot" coming from this string */ - u_boot_rev = &u_boot_rev[7]; - - printf("\nU-Boot SPL %s (%s - %s)\n", u_boot_rev, U_BOOT_DATE, - U_BOOT_TIME); - omap_rev_string(); -} - -void __weak omap_rev_string() -{ - printf("Texas Instruments Revision detection unimplemented\n"); + puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ + U_BOOT_TIME ")\n"); +#ifdef CONFIG_SPL_DISPLAY_PRINT + spl_display_print(); +#endif } diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/common/spl/spl_nand.c index 8cf55c9..61de5a4 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/common/spl/spl_nand.c @@ -21,13 +21,10 @@ * MA 02111-1307 USA */ #include <common.h> -#include <asm/u-boot.h> -#include <asm/utils.h> -#include <asm/arch/sys_proto.h> +#include <config.h> +#include <spl.h> #include <asm/io.h> #include <nand.h> -#include <version.h> -#include <asm/omap_common.h> void spl_nand_load_image(void) { @@ -35,16 +32,8 @@ void spl_nand_load_image(void) int *src __attribute__((unused)); int *dst __attribute__((unused)); - switch (omap_boot_mode()) { - case NAND_MODE_HW_ECC: - debug("spl: nand - using hw ecc\n"); - gpmc_init(); - nand_init(); - break; - default: - puts("spl: ERROR: This bootmode is not implemented - hanging"); - hang(); - } + debug("spl: nand - using hw ecc\n"); + nand_init(); /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); @@ -80,10 +69,10 @@ void spl_nand_load_image(void) nand_deselect(); return; } else { - printf("The Expected Linux image was not" - "found. Please check your NAND" + puts("The Expected Linux image was not " + "found. Please check your NAND " "configuration.\n"); - printf("Trying to start u-boot now...\n"); + puts("Trying to start u-boot now...\n"); } } #endif diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c new file mode 100644 index 0000000..976e865 --- /dev/null +++ b/common/spl/spl_nor.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2012 Stefan Roese <sr@denx.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. + */ + +#include <common.h> +#include <spl.h> + +void spl_nor_load_image(void) +{ + /* + * Loading of the payload to SDRAM is done with skipping of + * the mkimage header in this SPL NOR driver + */ + spl_image.flags |= SPL_COPY_PAYLOAD_ONLY; + + if (spl_start_uboot()) { + /* + * Load real U-Boot from its location in NOR flash to its + * defined location in SDRAM + */ + spl_parse_image_header( + (const struct image_header *)CONFIG_SYS_UBOOT_BASE); + + memcpy((void *)spl_image.load_addr, + (void *)(CONFIG_SYS_UBOOT_BASE + + sizeof(struct image_header)), + spl_image.size); + } else { + /* + * Load Linux from its location in NOR flash to its defined + * location in SDRAM + */ + spl_parse_image_header( + (const struct image_header *)CONFIG_SYS_OS_BASE); + + memcpy((void *)spl_image.load_addr, + (void *)(CONFIG_SYS_OS_BASE + + sizeof(struct image_header)), + spl_image.size); + + /* + * Copy DT blob (fdt) to SDRAM. Passing pointer to flash + * doesn't work (16 KiB should be enough for DT) + */ + memcpy((void *)CONFIG_SYS_SPL_ARGS_ADDR, + (void *)(CONFIG_SYS_FDT_BASE), + (16 << 10)); + } +} diff --git a/arch/arm/cpu/armv7/omap-common/spl_ymodem.c b/common/spl/spl_ymodem.c index 47663f7..40e5035 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_ymodem.c +++ b/common/spl/spl_ymodem.c @@ -26,11 +26,10 @@ * MA 02111-1307 USA */ #include <common.h> +#include <spl.h> #include <xyzModem.h> #include <asm/u-boot.h> #include <asm/utils.h> -#include <asm/arch/sys_proto.h> -#include <asm/omap_common.h> #define BUF_SIZE 1024 diff --git a/common/usb_hub.c b/common/usb_hub.c index f35ad95..32750e8 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -43,6 +43,7 @@ #include <common.h> #include <command.h> #include <asm/processor.h> +#include <asm/unaligned.h> #include <linux/ctype.h> #include <asm/byteorder.h> #include <asm/unaligned.h> @@ -269,6 +270,7 @@ static int usb_hub_configure(struct usb_device *dev) int i; ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ); unsigned char *bitmap; + short hubCharacteristics; struct usb_hub_descriptor *descriptor; struct usb_hub_device *hub; #ifdef USB_HUB_DEBUG @@ -304,8 +306,9 @@ static int usb_hub_configure(struct usb_device *dev) } memcpy((unsigned char *)&hub->desc, buffer, descriptor->bLength); /* adjust 16bit values */ - hub->desc.wHubCharacteristics = - le16_to_cpu(descriptor->wHubCharacteristics); + put_unaligned(le16_to_cpu(get_unaligned( + &descriptor->wHubCharacteristics)), + &hub->desc.wHubCharacteristics); /* set the bitmap */ bitmap = (unsigned char *)&hub->desc.DeviceRemovable[0]; /* devices not removable by default */ @@ -322,7 +325,8 @@ static int usb_hub_configure(struct usb_device *dev) dev->maxchild = descriptor->bNbrPorts; USB_HUB_PRINTF("%d ports detected\n", dev->maxchild); - switch (hub->desc.wHubCharacteristics & HUB_CHAR_LPSM) { + hubCharacteristics = get_unaligned(&hub->desc.wHubCharacteristics); + switch (hubCharacteristics & HUB_CHAR_LPSM) { case 0x00: USB_HUB_PRINTF("ganged power switching\n"); break; @@ -335,12 +339,12 @@ static int usb_hub_configure(struct usb_device *dev) break; } - if (hub->desc.wHubCharacteristics & HUB_CHAR_COMPOUND) + if (hubCharacteristics & HUB_CHAR_COMPOUND) USB_HUB_PRINTF("part of a compound device\n"); else USB_HUB_PRINTF("standalone hub\n"); - switch (hub->desc.wHubCharacteristics & HUB_CHAR_OCPM) { + switch (hubCharacteristics & HUB_CHAR_OCPM) { case 0x00: USB_HUB_PRINTF("global over-current protection\n"); break; diff --git a/common/usb_storage.c b/common/usb_storage.c index bdc306f..4aeed82 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -136,6 +136,7 @@ struct us_data { struct usb_device *pusb_dev; /* this usb_device */ unsigned int flags; /* from filter initially */ +# define USB_READY (1 << 0) unsigned char ifnum; /* interface number */ unsigned char ep_in; /* in endpoint */ unsigned char ep_out; /* out ....... */ @@ -155,11 +156,16 @@ struct us_data { trans_cmnd transport; /* transport routine */ }; +#ifdef CONFIG_USB_EHCI /* - * The U-Boot EHCI driver cannot handle more than 5 page aligned buffers - * of 4096 bytes in a transfer without running itself out of qt_buffers + * The U-Boot EHCI driver can handle any transfer length as long as there is + * enough free heap space left, but the SCSI READ(10) and WRITE(10) commands are + * limited to 65535 blocks. */ -#define USB_MAX_XFER_BLK(start, blksz) (((4096 * 5) - (start % 4096)) / blksz) +#define USB_MAX_XFER_BLK 65535 +#else +#define USB_MAX_XFER_BLK 20 +#endif static struct us_data usb_stor[USB_MAX_STOR_DEV]; @@ -693,7 +699,8 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us) usb_stor_BBB_reset(us); return USB_STOR_TRANSPORT_FAILED; } - mdelay(5); + if (!(us->flags & USB_READY)) + mdelay(5); pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in); pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out); /* DATA phase + error handling */ @@ -958,8 +965,10 @@ static int usb_test_unit_ready(ccb *srb, struct us_data *ss) srb->cmd[1] = srb->lun << 5; srb->datalen = 0; srb->cmdlen = 12; - if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) + if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) { + ss->flags |= USB_READY; return 0; + } usb_request_sense(srb, ss); mdelay(100); } while (retries--); @@ -1046,7 +1055,7 @@ static void usb_bin_fixup(struct usb_device_descriptor descriptor, unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, void *buffer) { - unsigned long start, blks, buf_addr, max_xfer_blk; + unsigned long start, blks, buf_addr; unsigned short smallblks; struct usb_device *dev; struct us_data *ss; @@ -1074,12 +1083,6 @@ unsigned long usb_stor_read(int device, unsigned long blknr, buf_addr = (unsigned long)buffer; start = blknr; blks = blkcnt; - if (usb_test_unit_ready(srb, ss)) { - printf("Device NOT ready\n Request Sense returned %02X %02X" - " %02X\n", srb->sense_buf[2], srb->sense_buf[12], - srb->sense_buf[13]); - return 0; - } USB_STOR_PRINTF("\nusb_read: dev %d startblk %lx, blccnt %lx" " buffer %lx\n", device, start, blks, buf_addr); @@ -1088,14 +1091,12 @@ unsigned long usb_stor_read(int device, unsigned long blknr, /* XXX need some comment here */ retry = 2; srb->pdata = (unsigned char *)buf_addr; - max_xfer_blk = USB_MAX_XFER_BLK(buf_addr, - usb_dev_desc[device].blksz); - if (blks > max_xfer_blk) - smallblks = (unsigned short) max_xfer_blk; + if (blks > USB_MAX_XFER_BLK) + smallblks = USB_MAX_XFER_BLK; else smallblks = (unsigned short) blks; retry_it: - if (smallblks == max_xfer_blk) + if (smallblks == USB_MAX_XFER_BLK) usb_show_progress(); srb->datalen = usb_dev_desc[device].blksz * smallblks; srb->pdata = (unsigned char *)buf_addr; @@ -1111,12 +1112,13 @@ retry_it: blks -= smallblks; buf_addr += srb->datalen; } while (blks != 0); + ss->flags &= ~USB_READY; USB_STOR_PRINTF("usb_read: end startblk %lx, blccnt %x buffer %lx\n", start, smallblks, buf_addr); usb_disable_asynch(0); /* asynch transfer allowed */ - if (blkcnt >= max_xfer_blk) + if (blkcnt >= USB_MAX_XFER_BLK) debug("\n"); return blkcnt; } @@ -1124,7 +1126,7 @@ retry_it: unsigned long usb_stor_write(int device, unsigned long blknr, unsigned long blkcnt, const void *buffer) { - unsigned long start, blks, buf_addr, max_xfer_blk; + unsigned long start, blks, buf_addr; unsigned short smallblks; struct usb_device *dev; struct us_data *ss; @@ -1153,12 +1155,6 @@ unsigned long usb_stor_write(int device, unsigned long blknr, buf_addr = (unsigned long)buffer; start = blknr; blks = blkcnt; - if (usb_test_unit_ready(srb, ss)) { - printf("Device NOT ready\n Request Sense returned %02X %02X" - " %02X\n", srb->sense_buf[2], srb->sense_buf[12], - srb->sense_buf[13]); - return 0; - } USB_STOR_PRINTF("\nusb_write: dev %d startblk %lx, blccnt %lx" " buffer %lx\n", device, start, blks, buf_addr); @@ -1169,14 +1165,12 @@ unsigned long usb_stor_write(int device, unsigned long blknr, */ retry = 2; srb->pdata = (unsigned char *)buf_addr; - max_xfer_blk = USB_MAX_XFER_BLK(buf_addr, - usb_dev_desc[device].blksz); - if (blks > max_xfer_blk) - smallblks = (unsigned short) max_xfer_blk; + if (blks > USB_MAX_XFER_BLK) + smallblks = USB_MAX_XFER_BLK; else smallblks = (unsigned short) blks; retry_it: - if (smallblks == max_xfer_blk) + if (smallblks == USB_MAX_XFER_BLK) usb_show_progress(); srb->datalen = usb_dev_desc[device].blksz * smallblks; srb->pdata = (unsigned char *)buf_addr; @@ -1192,12 +1186,13 @@ retry_it: blks -= smallblks; buf_addr += srb->datalen; } while (blks != 0); + ss->flags &= ~USB_READY; USB_STOR_PRINTF("usb_write: end startblk %lx, blccnt %x buffer %lx\n", start, smallblks, buf_addr); usb_disable_asynch(0); /* asynch transfer allowed */ - if (blkcnt >= max_xfer_blk) + if (blkcnt >= USB_MAX_XFER_BLK) debug("\n"); return blkcnt; @@ -1403,6 +1398,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss, cap[0] = 2880; cap[1] = 0x200; } + ss->flags &= ~USB_READY; USB_STOR_PRINTF("Read Capacity returns: 0x%lx, 0x%lx\n", cap[0], cap[1]); #if 0 diff --git a/disk/part.c b/disk/part.c index 76f3939..3022969 100644 --- a/disk/part.c +++ b/disk/part.c @@ -24,6 +24,7 @@ #include <common.h> #include <command.h> #include <ide.h> +#include <malloc.h> #include <part.h> #undef PART_DEBUG @@ -70,7 +71,7 @@ static const struct block_drvr block_drvr[] = { DECLARE_GLOBAL_DATA_PTR; -block_dev_desc_t *get_dev(char* ifname, int dev) +block_dev_desc_t *get_dev(const char *ifname, int dev) { const struct block_drvr *drvr = block_drvr; block_dev_desc_t* (*reloc_get_dev)(int dev); @@ -97,7 +98,7 @@ block_dev_desc_t *get_dev(char* ifname, int dev) return NULL; } #else -block_dev_desc_t *get_dev(char* ifname, int dev) +block_dev_desc_t *get_dev(const char *ifname, int dev) { return NULL; } @@ -288,64 +289,10 @@ void init_part (block_dev_desc_t * dev_desc) return; } #endif + dev_desc->part_type = PART_TYPE_UNKNOWN; } -int get_partition_info (block_dev_desc_t *dev_desc, int part - , disk_partition_t *info) -{ - switch (dev_desc->part_type) { -#ifdef CONFIG_MAC_PARTITION - case PART_TYPE_MAC: - if (get_partition_info_mac(dev_desc,part,info) == 0) { - PRINTF ("## Valid MAC partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_DOS_PARTITION - case PART_TYPE_DOS: - if (get_partition_info_dos(dev_desc,part,info) == 0) { - PRINTF ("## Valid DOS partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_ISO_PARTITION - case PART_TYPE_ISO: - if (get_partition_info_iso(dev_desc,part,info) == 0) { - PRINTF ("## Valid ISO boot partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_AMIGA_PARTITION - case PART_TYPE_AMIGA: - if (get_partition_info_amiga(dev_desc, part, info) == 0) - { - PRINTF ("## Valid Amiga partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_EFI_PARTITION - case PART_TYPE_EFI: - if (get_partition_info_efi(dev_desc,part,info) == 0) { - PRINTF ("## Valid EFI partition found ##\n"); - return (0); - } - break; -#endif - default: - break; - } - return (-1); -} - static void print_part_header (const char *type, block_dev_desc_t * dev_desc) { puts ("\nPartition Map for "); @@ -433,3 +380,268 @@ void print_part (block_dev_desc_t * dev_desc) #endif #endif + +int get_partition_info(block_dev_desc_t *dev_desc, int part + , disk_partition_t *info) +{ +#if defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ + defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_CMD_USB) || \ + defined(CONFIG_MMC) || \ + defined(CONFIG_SYSTEMACE) + +#ifdef CONFIG_PARTITION_UUIDS + /* The common case is no UUID support */ + info->uuid[0] = 0; +#endif + + switch (dev_desc->part_type) { +#ifdef CONFIG_MAC_PARTITION + case PART_TYPE_MAC: + if (get_partition_info_mac(dev_desc, part, info) == 0) { + PRINTF("## Valid MAC partition found ##\n"); + return 0; + } + break; +#endif + +#ifdef CONFIG_DOS_PARTITION + case PART_TYPE_DOS: + if (get_partition_info_dos(dev_desc, part, info) == 0) { + PRINTF("## Valid DOS partition found ##\n"); + return 0; + } + break; +#endif + +#ifdef CONFIG_ISO_PARTITION + case PART_TYPE_ISO: + if (get_partition_info_iso(dev_desc, part, info) == 0) { + PRINTF("## Valid ISO boot partition found ##\n"); + return 0; + } + break; +#endif + +#ifdef CONFIG_AMIGA_PARTITION + case PART_TYPE_AMIGA: + if (get_partition_info_amiga(dev_desc, part, info) == 0) { + PRINTF("## Valid Amiga partition found ##\n"); + return 0; + } + break; +#endif + +#ifdef CONFIG_EFI_PARTITION + case PART_TYPE_EFI: + if (get_partition_info_efi(dev_desc, part, info) == 0) { + PRINTF("## Valid EFI partition found ##\n"); + return 0; + } + break; +#endif + default: + break; + } +#endif + + return -1; +} + +int get_device(const char *ifname, const char *dev_str, + block_dev_desc_t **dev_desc) +{ + char *ep; + int dev; + + dev = simple_strtoul(dev_str, &ep, 16); + if (*ep) { + printf("** Bad device specification %s %s **\n", + ifname, dev_str); + return -1; + } + + *dev_desc = get_dev(ifname, dev); + if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) { + printf("** Bad device %s %s **\n", ifname, dev_str); + return -1; + } + + return dev; +} + +#define PART_UNSPECIFIED -2 +#define PART_AUTO -1 +#define MAX_SEARCH_PARTITIONS 16 +int get_device_and_partition(const char *ifname, const char *dev_part_str, + block_dev_desc_t **dev_desc, + disk_partition_t *info, int allow_whole_dev) +{ + int ret = -1; + const char *part_str; + char *dup_str = NULL; + const char *dev_str; + int dev; + char *ep; + int p; + int part; + disk_partition_t tmpinfo; + + /* If no dev_part_str, use bootdevice environment variable */ + if (!dev_part_str || !strlen(dev_part_str) || + !strcmp(dev_part_str, "-")) + dev_part_str = getenv("bootdevice"); + + /* If still no dev_part_str, it's an error */ + if (!dev_part_str) { + printf("** No device specified **\n"); + goto cleanup; + } + + /* Separate device and partition ID specification */ + part_str = strchr(dev_part_str, ':'); + if (part_str) { + dup_str = strdup(dev_part_str); + dup_str[part_str - dev_part_str] = 0; + dev_str = dup_str; + part_str++; + } else { + dev_str = dev_part_str; + } + + /* Look up the device */ + dev = get_device(ifname, dev_str, dev_desc); + if (dev < 0) + goto cleanup; + + /* Convert partition ID string to number */ + if (!part_str || !*part_str) { + part = PART_UNSPECIFIED; + } else if (!strcmp(part_str, "auto")) { + part = PART_AUTO; + } else { + /* Something specified -> use exactly that */ + part = (int)simple_strtoul(part_str, &ep, 16); + /* + * Less than whole string converted, + * or request for whole device, but caller requires partition. + */ + if (*ep || (part == 0 && !allow_whole_dev)) { + printf("** Bad partition specification %s %s **\n", + ifname, dev_part_str); + goto cleanup; + } + } + + /* + * No partition table on device, + * or user requested partition 0 (entire device). + */ + if (((*dev_desc)->part_type == PART_TYPE_UNKNOWN) || + (part == 0)) { + if (!(*dev_desc)->lba) { + printf("** Bad device size - %s %s **\n", ifname, + dev_str); + goto cleanup; + } + + /* + * If user specified a partition ID other than 0, + * or the calling command only accepts partitions, + * it's an error. + */ + if ((part > 0) || (!allow_whole_dev)) { + printf("** No partition table - %s %s **\n", ifname, + dev_str); + goto cleanup; + } + + info->start = 0; + info->size = (*dev_desc)->lba; + info->blksz = (*dev_desc)->blksz; + info->bootable = 0; +#ifdef CONFIG_PARTITION_UUIDS + info->uuid[0] = 0; +#endif + + ret = 0; + goto cleanup; + } + + /* + * Now there's known to be a partition table, + * not specifying a partition means to pick partition 1. + */ + if (part == PART_UNSPECIFIED) + part = 1; + + /* + * If user didn't specify a partition number, or did specify something + * other than "auto", use that partition number directly. + */ + if (part != PART_AUTO) { + ret = get_partition_info(*dev_desc, part, info); + if (ret) { + printf("** Invalid partition %d **\n", part); + goto cleanup; + } + } else { + /* + * Find the first bootable partition. + * If none are bootable, fall back to the first valid partition. + */ + part = 0; + for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { + ret = get_partition_info(*dev_desc, p, info); + if (ret) + continue; + + /* + * First valid partition, or new better partition? + * If so, save partition ID. + */ + if (!part || info->bootable) + part = p; + + /* Best possible partition? Stop searching. */ + if (info->bootable) + break; + + /* + * We now need to search further for best possible. + * If we what we just queried was the best so far, + * save the info since we over-write it next loop. + */ + if (part == p) + tmpinfo = *info; + } + /* If we found any acceptable partition */ + if (part) { + /* + * If we searched all possible partition IDs, + * return the first valid partition we found. + */ + if (p == MAX_SEARCH_PARTITIONS + 1) + *info = tmpinfo; + ret = 0; + } else { + printf("** No valid partitions found **\n"); + goto cleanup; + } + } + if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) { + printf("** Invalid partition type \"%.32s\"" + " (expect \"" BOOT_PART_TYPE "\")\n", + info->type); + ret = -1; + goto cleanup; + } + + ret = part; + goto cleanup; + +cleanup: + free(dup_str); + return ret; +} diff --git a/disk/part_dos.c b/disk/part_dos.c index a43dd9c..c9a3e2b 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -60,14 +60,20 @@ static inline int is_extended(int part_type) part_type == 0x85); } +static inline int is_bootable(dos_partition_t *p) +{ + return p->boot_ind == 0x80; +} + static void print_one_part (dos_partition_t *p, int ext_part_sector, int part_num) { int lba_start = ext_part_sector + le32_to_int (p->start4); int lba_size = le32_to_int (p->size4); - printf ("%5d\t\t%10d\t%10d\t%2x%s\n", + printf("%5d\t\t%10d\t%10d\t%2x%s%s\n", part_num, lba_start, lba_size, p->sys_ind, - (is_extended (p->sys_ind) ? " Extd" : "")); + (is_extended(p->sys_ind) ? " Extd" : ""), + (is_bootable(p) ? " Boot" : "")); } static int test_block_type(unsigned char *buffer) @@ -163,7 +169,8 @@ static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_s */ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part_sector, int relative, int part_num, - int which_part, disk_partition_t *info) + int which_part, disk_partition_t *info, + unsigned int disksig) { ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); dos_partition_t *pt; @@ -182,6 +189,11 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part return -1; } +#ifdef CONFIG_PARTITION_UUIDS + if (!ext_part_sector) + disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]); +#endif + /* Print all primary/logical partitions */ pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); for (i = 0; i < 4; i++, pt++) { @@ -222,6 +234,10 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part } /* sprintf(info->type, "%d, pt->sys_ind); */ sprintf ((char *)info->type, "U-Boot"); + info->bootable = is_bootable(pt); +#ifdef CONFIG_PARTITION_UUIDS + sprintf(info->uuid, "%08x-%02x", disksig, part_num); +#endif return 0; } @@ -240,7 +256,7 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part return get_partition_info_extended (dev_desc, lba_start, ext_part_sector == 0 ? lba_start : relative, - part_num, which_part, info); + part_num, which_part, info, disksig); } } return -1; @@ -254,7 +270,7 @@ void print_part_dos (block_dev_desc_t *dev_desc) int get_partition_info_dos (block_dev_desc_t *dev_desc, int part, disk_partition_t * info) { - return get_partition_info_extended (dev_desc, 0, 0, 1, part, info); + return get_partition_info_extended(dev_desc, 0, 0, 1, part, info, 0); } diff --git a/disk/part_dos.h b/disk/part_dos.h index de75542..7b77c1d 100644 --- a/disk/part_dos.h +++ b/disk/part_dos.h @@ -24,7 +24,7 @@ #ifndef _DISK_PART_DOS_H #define _DISK_PART_DOS_H - +#define DOS_PART_DISKSIG_OFFSET 0x1b8 #define DOS_PART_TBL_OFFSET 0x1be #define DOS_PART_MAGIC_OFFSET 0x1fe #define DOS_PBR_FSTYPE_OFFSET 0x36 diff --git a/disk/part_efi.c b/disk/part_efi.c index 02927a0..264ea9c 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -154,6 +154,28 @@ void print_part_efi(block_dev_desc_t * dev_desc) return; } +#ifdef CONFIG_PARTITION_UUIDS +static void uuid_string(unsigned char *uuid, char *str) +{ + static const u8 le[16] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, + 12, 13, 14, 15}; + int i; + + for (i = 0; i < 16; i++) { + sprintf(str, "%02x", uuid[le[i]]); + str += 2; + switch (i) { + case 3: + case 5: + case 7: + case 9: + *str++ = '-'; + break; + } + } +} +#endif + int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, disk_partition_t * info) { @@ -173,6 +195,13 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, return -1; } + if (part > le32_to_int(gpt_head->num_partition_entries) || + !is_pte_valid(&gpt_pte[part - 1])) { + printf("%s: *** ERROR: Invalid partition number %d ***\n", + __func__, part); + return -1; + } + /* The ulong casting limits the maximum disk size to 2 TB */ info->start = (ulong) le64_to_int(gpt_pte[part - 1].starting_lba); /* The ending LBA is inclusive, to calculate size, add 1 to it */ @@ -183,6 +212,9 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, sprintf((char *)info->name, "%s", print_efiname(&gpt_pte[part - 1])); sprintf((char *)info->type, "U-Boot"); +#ifdef CONFIG_PARTITION_UUIDS + uuid_string(gpt_pte[part - 1].unique_partition_guid.b, info->uuid); +#endif debug("%s: start 0x%lX, size 0x%lX, name %s", __func__, info->start, info->size, info->name); diff --git a/disk/part_mac.c b/disk/part_mac.c index c1afc8c..cb443ac 100644 --- a/disk/part_mac.c +++ b/disk/part_mac.c @@ -60,23 +60,23 @@ static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partitio */ int test_part_mac (block_dev_desc_t *dev_desc) { - mac_driver_desc_t ddesc; - mac_partition_t mpart; + ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); + ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); ulong i, n; - if (part_mac_read_ddb (dev_desc, &ddesc)) { + if (part_mac_read_ddb (dev_desc, ddesc)) { /* error reading Driver Desriptor Block, or no valid Signature */ return (-1); } n = 1; /* assuming at least one partition */ for (i=1; i<=n; ++i) { - if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)&mpart) != 1) || - (mpart.signature != MAC_PARTITION_MAGIC) ) { + if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)mpart) != 1) || + (mpart->signature != MAC_PARTITION_MAGIC) ) { return (-1); } /* update partition count */ - n = mpart.map_count; + n = mpart->map_count; } return (0); } @@ -85,20 +85,20 @@ int test_part_mac (block_dev_desc_t *dev_desc) void print_part_mac (block_dev_desc_t *dev_desc) { ulong i, n; - mac_driver_desc_t ddesc; - mac_partition_t mpart; + ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); + ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); ldiv_t mb, gb; - if (part_mac_read_ddb (dev_desc, &ddesc)) { + if (part_mac_read_ddb (dev_desc, ddesc)) { /* error reading Driver Desriptor Block, or no valid Signature */ return; } - n = ddesc.blk_count; + n = ddesc->blk_count; - mb = ldiv(n, ((1024 * 1024) / ddesc.blk_size)); /* MB */ + mb = ldiv(n, ((1024 * 1024) / ddesc->blk_size)); /* MB */ /* round to 1 digit */ - mb.rem *= 10 * ddesc.blk_size; + mb.rem *= 10 * ddesc->blk_size; mb.rem += 512 * 1024; mb.rem /= 1024 * 1024; @@ -112,10 +112,10 @@ void print_part_mac (block_dev_desc_t *dev_desc) "DeviceType=0x%x, DeviceId=0x%x\n\n" " #: type name" " length base (size)\n", - ddesc.blk_size, - ddesc.blk_count, + ddesc->blk_size, + ddesc->blk_count, mb.quot, mb.rem, gb.quot, gb.rem, - ddesc.dev_type, ddesc.dev_id + ddesc->dev_type, ddesc->dev_id ); n = 1; /* assuming at least one partition */ @@ -124,25 +124,25 @@ void print_part_mac (block_dev_desc_t *dev_desc) char c; printf ("%4ld: ", i); - if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)&mpart) != 1) { + if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)mpart) != 1) { printf ("** Can't read Partition Map on %d:%ld **\n", dev_desc->dev, i); return; } - if (mpart.signature != MAC_PARTITION_MAGIC) { + if (mpart->signature != MAC_PARTITION_MAGIC) { printf ("** Bad Signature on %d:%ld - " "expected 0x%04x, got 0x%04x\n", - dev_desc->dev, i, MAC_PARTITION_MAGIC, mpart.signature); + dev_desc->dev, i, MAC_PARTITION_MAGIC, mpart->signature); return; } /* update partition count */ - n = mpart.map_count; + n = mpart->map_count; c = 'k'; - bytes = mpart.block_count; - bytes /= (1024 / ddesc.blk_size); /* kB; assumes blk_size == 512 */ + bytes = mpart->block_count; + bytes /= (1024 / ddesc->blk_size); /* kB; assumes blk_size == 512 */ if (bytes >= 1024) { bytes >>= 10; c = 'M'; @@ -153,10 +153,10 @@ void print_part_mac (block_dev_desc_t *dev_desc) } printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n", - mpart.type, - mpart.name, - mpart.block_count, - mpart.start_block, + mpart->type, + mpart->name, + mpart->block_count, + mpart->start_block, bytes, c ); } @@ -231,23 +231,23 @@ static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partitio int get_partition_info_mac (block_dev_desc_t *dev_desc, int part, disk_partition_t *info) { - mac_driver_desc_t ddesc; - mac_partition_t mpart; + ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); + ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); - if (part_mac_read_ddb (dev_desc, &ddesc)) { + if (part_mac_read_ddb (dev_desc, ddesc)) { return (-1); } - info->blksz = ddesc.blk_size; + info->blksz = ddesc->blk_size; - if (part_mac_read_pdb (dev_desc, part, &mpart)) { + if (part_mac_read_pdb (dev_desc, part, mpart)) { return (-1); } - info->start = mpart.start_block; - info->size = mpart.block_count; - memcpy (info->type, mpart.type, sizeof(info->type)); - memcpy (info->name, mpart.name, sizeof(info->name)); + info->start = mpart->start_block; + info->size = mpart->block_count; + memcpy (info->type, mpart->type, sizeof(info->type)); + memcpy (info->name, mpart->name, sizeof(info->name)); return (0); } diff --git a/doc/README.NetConsole b/doc/README.NetConsole index c8bcb90..af7fc60 100644 --- a/doc/README.NetConsole +++ b/doc/README.NetConsole @@ -6,11 +6,16 @@ serial and network input/output devices by adjusting the 'stdin' and set either of these variables to "nc". Input and output can be switched independently. +CONFIG_NETCONSOLE_BUFFER_SIZE - Override the default buffer size + We use an environment variable 'ncip' to set the IP address and the port of the destination. The format is <ip_addr>:<port>. If <port> is omitted, the value of 6666 is used. If the env var doesn't exist, the broadcast address and port 6666 are used. If it is set to an IP address of 0 (or 0.0.0.0) then no messages are sent to the network. +The source / listening port can be configured separately by setting +the 'ncinport' environment variable and the destination port can be +configured by setting the 'ncoutport' environment variable. For example, if your server IP is 192.168.1.1, you could use: diff --git a/doc/README.SPL b/doc/README.SPL index e4a5ac3..4e1cb28 100644 --- a/doc/README.SPL +++ b/doc/README.SPL @@ -66,6 +66,7 @@ CONFIG_SPL_DMA_SUPPORT (drivers/dma/libdma.o) CONFIG_SPL_POST_MEM_SUPPORT (post/drivers/memory.o) CONFIG_SPL_NAND_LOAD (drivers/mtd/nand/nand_spl_load.o) CONFIG_SPL_SPI_LOAD (drivers/mtd/spi/spi_spl_load.o) +CONFIG_SPL_RAM_DEVICE (common/spl/spl.c) Normally CPU is assumed to be the same between the SPL and normal @@ -78,3 +79,33 @@ an SPL CPU in boards.cfg as follows: This this case CPU will be set to "normal_cpu" during the main u-boot build and "spl_cpu" during the SPL build. + + +Debugging +--------- + +When building SPL with DEBUG set you may also need to set CONFIG_PANIC_HANG +as in most cases do_reset is not defined within SPL. + + +Estimating stack usage +---------------------- + +With gcc 4.6 (and later) and the use of GNU cflow it is possible to estimate +stack usage at various points in run sequence of SPL. The -fstack-usage option +to gcc will produce '.su' files (such as arch/arm/cpu/armv7/syslib.su) that +will give stack usage information and cflow can construct program flow. + +Must have gcc 4.6 or later, which supports -fstack-usage + +1) Build normally +2) Perform the following shell command to generate a list of C files used in +SPL: +$ find spl -name '*.su' | sed -e 's:^spl/::' -e 's:[.]su$:.c:' > used-spl.list +3) Execute cflow: +$ cflow --main=board_init_r `cat used-spl.list` 2>&1 | $PAGER + +cflow will spit out a number of warnings as it does not parse +the config files and picks functions based on #ifdef. Parsing the '.i' +files instead introduces another set of headaches. These warnings are +not usually important to understanding the flow, however. diff --git a/doc/README.commands b/doc/README.commands index 27815d2..125f077 100644 --- a/doc/README.commands +++ b/doc/README.commands @@ -22,6 +22,13 @@ This makes it possible for the final link to extract all commands compiled into any object code and construct a static array so the command can be found in an array starting at __u_boot_cmd_start. +To ensure that the linker does not discard these symbols when linking +full U-Boot we generate a list of all the commands we have built (based +on the sections mentioned above) and use that to force the linker to +first enter the symbol as undefined in the output object so that there +is then a need for the symbol to be kept (this is the UNDEF_SYM logic in +the Makefile). + If a new board is defined do not forget to define the command section by writing in u-boot.lds ($(TOPDIR)/board/boardname/u-boot.lds) these 3 lines: diff --git a/doc/README.ext4 b/doc/README.ext4 new file mode 100644 index 0000000..b3ea8b7 --- /dev/null +++ b/doc/README.ext4 @@ -0,0 +1,46 @@ +This patch series adds support for ext4 ls,load and write features in uboot +Journaling is supported for write feature. + +To Enable ext2 ls and load commands, modify the board specific config file with +#define CONFIG_CMD_EXT2 + +To Enable ext4 ls and load commands, modify the board specific config file with +#define CONFIG_CMD_EXT4 + +To enable ext4 write command, modify the board specific config file with +#define CONFIG_CMD_EXT4 +#define CONFIG_CMD_EXT4_WRITE + +Steps to test: + +1. After applying the patch, ext4 specific commands can be seen + in the boot loader prompt using + UBOOT #help + + ext4load- load binary file from a Ext4 file system + ext4ls - list files in a directory (default /) + ext4write- create a file in ext4 formatted partition + +2. To list the files in ext4 formatted partition, execute + ext4ls <interface> <dev[:part]> [directory] + For example: + UBOOT #ext4ls mmc 0:5 /usr/lib + +3. To read and load a file from an ext4 formatted partition to RAM, execute + ext4load <interface> <dev[:part]> [addr] [filename] [bytes] + For example: + UBOOT #ext4load mmc 2:2 0x30007fc0 uImage + +4. To write a file to a ext4 formatted partition. + a) First load a file to RAM at a particular address for example 0x30007fc0. + Now execute ext4write command + ext4write <interface> <dev[:part]> [filename] [Address] [sizebytes] + For example: + UBOOT #ext4write mmc 2:2 /boot/uImage 0x30007fc0 6183120 + (here 6183120 is the size of the file to be written) + Note: Absolute path is required for the file to be written + +References : + -- ext4 implementation in Linux Kernel + -- Uboot existing ext2 load and ls implementation + -- Journaling block device JBD2 implementation in linux Kernel diff --git a/doc/README.fsl-ddr b/doc/README.fsl-ddr index 5e21658..f94b56f 100644 --- a/doc/README.fsl-ddr +++ b/doc/README.fsl-ddr @@ -1,5 +1,28 @@ - -Table of interleaving modes supported in cpu/8xxx/ddr/ +Table of interleaving 2-4 controllers +===================================== + +--------------+-----------------------------------------------------------+ + |Configuration | Memory Controller | + | | 1 2 3 4 | + |--------------+--------------+--------------+-----------------------------+ + | Two memory | Not Intlv'ed | Not Intlv'ed | | + | complexes +--------------+--------------+ | + | | 2-way Intlv'ed | | + |--------------+--------------+--------------+--------------+ | + | | Not Intlv'ed | Not Intlv'ed | Not Intlv'ed | | + | Three memory +--------------+--------------+--------------+ | + | complexes | 2-way Intlv'ed | Not Intlv'ed | | + | +-----------------------------+--------------+ | + | | 3-way Intlv'ed | | + +--------------+--------------+--------------+--------------+--------------+ + | | Not Intlv'ed | Not Intlv'ed | Not Intlv'ed | Not Intlv'ed | + | Four memory +--------------+--------------+--------------+--------------+ + | complexes | 2-way Intlv'ed | 2-way Intlv'ed | + | +-----------------------------+-----------------------------+ + | | 4-way Intlv'ed | + +--------------+-----------------------------------------------------------+ + + +Table of 2-way interleaving modes supported in cpu/8xxx/ddr/ ====================================================== +-------------+---------------------------------------------------------+ | | Rank Interleaving | @@ -56,6 +79,15 @@ The ways to configure the ddr interleaving mode # superbank setenv hwconfig "fsl_ddr:ctlr_intlv=superbank" + # 1KB 3-way interleaving + setenv hwconfig "fsl_ddr:ctlr_intlv=3way_1KB" + + # 4KB 3-way interleaving + setenv hwconfig "fsl_ddr:ctlr_intlv=3way_4KB" + + # 8KB 3-way interleaving + setenv hwconfig "fsl_ddr:ctlr_intlv=3way_8KB" + # disable bank (chip-select) interleaving setenv hwconfig "fsl_ddr:bank_intlv=null" diff --git a/doc/README.nand b/doc/README.nand index 1602b5e..c130189 100644 --- a/doc/README.nand +++ b/doc/README.nand @@ -228,6 +228,8 @@ NAND locking command (for chips with active LOCKPRE pin) "nand unlock [offset] [size]" unlock consecutive area (can be called multiple times for different areas) + "nand unlock.allexcept [offset] [size]" + unlock all except specified consecutive area I have tested the code with board containing 128MiB NAND large page chips and 32MiB small page chips. diff --git a/doc/README.pblimage b/doc/README.pblimage new file mode 100644 index 0000000..2b9bb5c --- /dev/null +++ b/doc/README.pblimage @@ -0,0 +1,114 @@ +------------------------------------------------------------------ +Freescale PBL(pre-boot loader) Boot Image generation using mkimage +------------------------------------------------------------------ + +The CoreNet SoC's can boot directly from eSPI FLASH, SD/MMC and +NAND, etc. These SoCs use PBL to load RCW and/or pre-initialization +instructions. For more details refer section 5 Pre-boot loader +specifications of reference manual P3041RM/P4080RM/P5020RM at link: +http://www.freescale.com/webapp/search/Serp.jsp?Reference+Manuals + +Building PBL Boot Image and boot steps +-------------------------------------- + +1. Building PBL Boot Image. + The default Image is u-boot.pbl. + + For eSPI boot(available on P3041/P4080/P5020): + To build the eSPI boot image: + make <board_name>_SPIFLASH_config + make u-boot.pbl + + For SD boot(available on P3041/P4080/P5020): + To build the SD boot image: + make <board_name>_SDCARD_config + make u-boot.pbl + + For Nand boot(available on P3041/P5020): + To build the NAND boot image: + make <board_name>_NAND_config + make u-boot.pbl + + +2. pblimage support available with mkimage utility will generate Freescale PBL +boot image that can be flashed on the board eSPI flash, SD/MMC and NAND. +Following steps describe it in detail. + + 1). Boot from eSPI flash + Write u-boot.pbl to eSPI flash from offset 0x0. + for ex in u-boot: + =>tftp 100000 u-boot.pbl + =>sf probe 0 + =>sf erase 0 100000 + =>sf write 100000 0 $filesize + Change SW1[1:5] = off off on off on. + + 2). Boot from SD/MMC + Write u-boot.pbl to SD/MMC from offset 0x1000. + for ex in u-boot: + =>tftp 100000 u-boot.pbl + =>mmcinfo + =>mmc write 100000 8 441 + Change SW1[1:5] = off off on on off. + + 3). Boot from Nand + Write u-boot.pbl to Nand from offset 0x0. + for ex in u-boot: + =>tftp 100000 u-boot.pbl + =>nand info + =>nand erase 0 100000 + =>nand write 100000 0 $filesize + Change SW1[1:5] = off on off off on + Change SW7[1:4] = on off off on + +Board specific configuration file specifications: +------------------------------------------------ +1. Configuration files rcw.cfg and pbi.cfg must present in the +board/freescale/corenet_ds/, rcw.cfg is for RCW, pbi.cfg is for +PBI instructions. File name must not be changed since they are used +in Makefile. +2. These files can have empty lines and lines starting with "#" as first +character to put comments + +Typical example of rcw.cfg file: +----------------------------------- + +#PBL preamble and RCW header +aa55aa55 010e0100 +#64 bytes RCW data +4c580000 00000000 18185218 0000cccc +40464000 3c3c2000 58000000 61000000 +00000000 00000000 00000000 008b6000 +00000000 00000000 00000000 00000000 + +Typical example of pbi.cfg file: +----------------------------------- + +#PBI commands +#Initialize CPC1 +09010000 00200400 +09138000 00000000 +091380c0 00000100 +09010100 00000000 +09010104 fff0000b +09010f00 08000000 +09010000 80000000 +#Configure LAW for CPC1 +09000d00 00000000 +09000d04 fff00000 +09000d08 81000013 +09000010 00000000 +09000014 ff000000 +09000018 81000000 +#Initialize eSPI controller +09110000 80000403 +09110020 2d170008 +09110024 00100008 +09110028 00100008 +0911002c 00100008 +#Flush PBL data +09138000 00000000 +091380c0 00000000 + +------------------------------------------------ +Author: Shaohui Xie<Shaohui.Xie@freescale.com> diff --git a/doc/README.pxe b/doc/README.pxe index 2bbf53d..f00f280 100644 --- a/doc/README.pxe +++ b/doc/README.pxe @@ -93,8 +93,13 @@ pxe boot be passed to the bootm command to boot the kernel. These environment variables are required to be set. - fdt_addr - the location of a fdt blob. If this is set, it will be passed - to bootm when booting a kernel. + fdt_addr_r - location in RAM at which 'pxe boot' will store the fdt blob it + retrieves from tftp. The retrieval is possible if 'fdt' label is defined in + pxe file and 'fdt_addr_r' is set. If retrieval is possible, 'fdt_addr_r' + will be passed to bootm command to boot the kernel. + + fdt_addr - the location of a fdt blob. 'fdt_addr' will be passed to bootm + command if it is set and 'fdt_addr_r' is not passed to bootm command. pxe file format =============== @@ -156,6 +161,11 @@ initrd <path> - if this label is chosen, use tftp to retrieve the initrd the initrd_addr_r environment variable, and that address will be passed to bootm. +fdt <path> - if this label is chosen, use tftp to retrieve the fdt blob + at <path>. it will be stored at the address indicated in + the fdt_addr_r environment variable, and that address will + be passed to bootm. + localboot <flag> - Run the command defined by "localcmd" in the environment. <flag> is ignored and is only here to match the syntax of PXELINUX config files. diff --git a/doc/README.scrapyard b/doc/README.scrapyard index 4b5558d..5929a8e 100644 --- a/doc/README.scrapyard +++ b/doc/README.scrapyard @@ -11,6 +11,7 @@ easily if here is something they might want to dig for... Board Arch CPU removed Commit last known maintainer/contact ============================================================================= +apollon arm omap24xx - 2012-09-06 Kyungmin Park <kyungmin.park@samsung.com> tb0229 mips mips32 - 2011-12-12 rmu powerpc MPC850 fb82fd7 2011-12-07 Wolfgang Denk <wd@denx.de> OXC powerpc MPC8240 309a292 2011-12-07 diff --git a/doc/README.srio-boot-corenet b/doc/README.srio-boot-corenet deleted file mode 100644 index 56b094c..0000000 --- a/doc/README.srio-boot-corenet +++ /dev/null @@ -1,103 +0,0 @@ ------------------------------- -SRIO Boot on Corenet Platforms ------------------------------- - -For some PowerPC processors with SRIO interface, boot location can be configured -to SRIO by RCW. The processor booting from SRIO can do without flash for u-boot -image, ucode and ENV. All the images can be fetched from another processor's -memory space by SRIO link connected between them. - -This document describes the processes based on an example implemented on P4080DS -platforms and a RCW example with boot from SRIO configuration. - -Environment of the SRIO boot: - a) Master and slave can be SOCs in one board or SOCs in separate boards. - b) They are connected with SRIO links, whether 1x or 4x, and directly or - through switch system. - c) Only Master has NorFlash for booting, and all the Master's and Slave's - U-Boot images, UCodes will be stored in this flash. - d) Slave has its own EEPROM for RCW and PBI. - e) Slave's RCW should configure the SerDes for SRIO boot port, set the boot - location to SRIO, and holdoff all the cores if needed. - - ---------- ----------- ----------- - | | | | | | - | | | | | | - | NorFlash|<----->| Master | SRIO | Slave |<---->[EEPROM] - | | | |<===========>| | - | | | | | | - ---------- ----------- ----------- - -The example based on P4080DS platform: - Two P4080DS platforms can be used to implement the boot from SRIO. Their SRIO - ports 0 will be connected directly and will be used for the boot from SRIO. - - 1. Slave's RCW example for boot from SRIO port 0 and core 0 not in holdoff. - 00000000: aa55 aa55 010e 0100 0c58 0000 0000 0000 - 00000010: 1818 1818 0000 8888 7440 4000 0000 2000 - 00000020: f400 0000 0100 0000 0000 0000 0000 0000 - 00000030: 0000 0000 0083 0000 0000 0000 0000 0000 - 00000040: 0000 0000 0000 0000 0813 8040 698b 93fe - - 2. Slave's RCW example for boot from SRIO port 0 and all cores in holdoff. - 00000000: aa55 aa55 010e 0100 0c58 0000 0000 0000 - 00000010: 1818 1818 0000 8888 7440 4000 0000 2000 - 00000020: f440 0000 0100 0000 0000 0000 0000 0000 - 00000030: 0000 0000 0083 0000 0000 0000 0000 0000 - 00000040: 0000 0000 0000 0000 0813 8040 063c 778f - - 3. Sequence in Step by Step. - a) Update RCW for slave with boot from SRIO port 0 configuration. - b) Program slave's U-Boot image, UCode, and ENV parameters into master's - NorFlash. - c) Start up master and it will boot up normally from its NorFlash. - Then, it will finish necessary configurations for slave's boot from - SRIO port 0. - d) Master will set inbound SRIO windows covered slave's U-Boot image stored - in master's NorFlash. - e) Master will set an inbound SRIO window covered slave's UCode stored in - master's NorFlash. - f) Master will set an inbound SRIO window covered slave's ENV stored in - master's NorFlash. - g) If need to release slave's core, master will set outbound SRIO windows - in order to configure slave's registers for the core's releasing. - h) If all cores of slave in holdoff, slave should be powered on before all - the above master's steps, and wait to be released by master. If not all - cores in holdoff, that means core 0 will start up normally, slave should - be powered on after all the above master's steps. In the startup phase - of the slave from SRIO, it will finish some necessary configurations. - i) Slave will set a specific TLB entry for the boot process. - j) Slave will set a LAW entry with the TargetID SRIO port 0 for the boot. - k) Slave will set a specific TLB entry in order to fetch UCode and ENV - from master. - l) Slave will set a LAW entry with the TargetID SRIO port 0 for UCode and ENV. - -How to use this feature: - To use this feature, you need to focus three points. - - 1. Slave's RCW with SRIO boot configurations, and all cores in holdoff - configurations if needed. - Please refer to the examples given above. - - 2. U-Boot image's compilation. - For master, U-Boot image should be generated specifically by - - make xxxx_SRIOBOOT_MASTER_config. - - For example, master U-Boot image used on P4080DS should be compiled with - - make P4080DS_SRIOBOOT_MASTER_config. - - For slave, U-Boot image should be generated specifically by - - make xxxx_SRIOBOOT_SLAVE_config. - - For example, slave U-Boot image used on P4080DS should be compiled with - - make P4080DS_SRIOBOOT_SLAVE_config. - - 3. Necessary modifications based on a specific environment. - For a specific environment, the SRIO port for boot, the addresses of the - slave's U-Boot image, UCode, ENV stored in master's NorFlash, and any other - configurations can be modified in the file: - include/configs/corenet_ds.h. diff --git a/doc/README.srio-pcie-boot-corenet b/doc/README.srio-pcie-boot-corenet new file mode 100644 index 0000000..cd7e7ee --- /dev/null +++ b/doc/README.srio-pcie-boot-corenet @@ -0,0 +1,112 @@ +--------------------------------------- +SRIO and PCIE Boot on Corenet Platforms +--------------------------------------- + +For some PowerPC processors with SRIO or PCIE interface, boot location can be +configured to SRIO or PCIE by RCW. The processor booting from SRIO or PCIE can +do without flash for u-boot image, ucode and ENV. All the images can be fetched +from another processor's memory space by SRIO or PCIE link connected between +them. + +This document describes the processes based on an example implemented on P4080DS +platforms and a RCW example with boot from SRIO or PCIE configuration. + +Environment of the SRIO or PCIE boot: + a) Master and slave can be SOCs in one board or SOCs in separate boards. + b) They are connected with SRIO or PCIE links, whether 1x, 2x or 4x, and + directly or through switch system. + c) Only Master has NorFlash for booting, and all the Master's and Slave's + U-Boot images, UCodes will be stored in this flash. + d) Slave has its own EEPROM for RCW and PBI. + e) Slave's RCW should configure the SerDes for SRIO or PCIE boot port, set + the boot location to SRIO or PCIE, and holdoff all the cores. + + ---------- ----------- ----------- + | | | | | | + | | | | | | + | NorFlash|<----->| Master |SRIO or PCIE | Slave |<---->[EEPROM] + | | | |<===========>| | + | | | | | | + ---------- ----------- ----------- + +The example based on P4080DS platform: + Two P4080DS platforms can be used to implement the boot from SRIO or PCIE. + Their SRIO or PCIE ports 1 will be connected directly and will be used for + the boot from SRIO or PCIE. + + 1. Slave's RCW example for boot from SRIO port 1 and all cores in holdoff. + 00000000: aa55 aa55 010e 0100 0c58 0000 0000 0000 + 00000010: 1818 1818 0000 8888 7440 4000 0000 2000 + 00000020: f440 0000 0100 0000 0000 0000 0000 0000 + 00000030: 0000 0000 0083 0000 0000 0000 0000 0000 + 00000040: 0000 0000 0000 0000 0813 8040 063c 778f + + 2. Slave's RCW example for boot from PCIE port 1 and all cores in holdoff. + 00000000: aa55 aa55 010e 0100 0c58 0000 0000 0000 + 00000010: 1818 1818 0000 8888 1440 4000 0000 2000 + 00000020: f040 0000 0100 0000 0020 0000 0000 0000 + 00000030: 0000 0000 0083 0000 0000 0000 0000 0000 + 00000040: 0000 0000 0000 0000 0813 8040 547e ffc9 + + 3. Sequence in Step by Step. + a) Update RCW for slave with boot from SRIO or PCIE port 1 configuration. + b) Program slave's U-Boot image, UCode, and ENV parameters into master's + NorFlash. + c) Set environment variable "bootmaster" to "SRIO1" or "PCIE1" and save + environment for master. + setenv bootmaster SRIO1 + or + setenv bootmaster PCIE1 + saveenv + d) Restart up master and it will boot up normally from its NorFlash. + Then, it will finish necessary configurations for slave's boot from + SRIO or PCIE port 1. + e) Master will set inbound SRIO or PCIE windows covered slave's U-Boot + image stored in master's NorFlash. + f) Master will set an inbound SRIO or PCIE window covered slave's UCode + and ENV stored in master's NorFlash. + g) Master will set outbound SRIO or PCIE windows in order to configure + slave's registers for the core's releasing. + h) Since all cores of slave in holdoff, slave should be powered on before + all the above master's steps, and wait to be released by master. In the + startup phase of the slave from SRIO or PCIE, it will finish some + necessary configurations. + i) Slave will set a specific TLB entry for the boot process. + j) Slave will set a LAW entry with the TargetID SRIO or PCIE port 1 for + the boot. + k) Slave will set a specific TLB entry in order to fetch UCode and ENV + from master. + l) Slave will set a LAW entry with the TargetID SRIO or PCIE port 1 for + UCode and ENV. + +How to use this feature: + To use this feature, you need to focus those points. + + 1. Slave's RCW with SRIO or PCIE boot configurations, and all cores in holdoff + configurations. + Please refer to the examples given above. + + 2. U-Boot image's compilation. + For master, U-Boot image should be generated normally. + + For example, master U-Boot image used on P4080DS should be compiled with + + make P4080DS_config. + + For slave, U-Boot image should be generated specifically by + + make xxxx_SRIO_PCIE_BOOT_config. + + For example, slave U-Boot image used on P4080DS should be compiled with + + make P4080DS_SRIO_PCIE_BOOT_config. + + 3. Necessary modifications based on a specific environment. + For a specific environment, the addresses of the slave's U-Boot image, + UCode, ENV stored in master's NorFlash, and any other configurations + can be modified in the file: + include/configs/corenet_ds.h. + + 4. Set and save the environment variable "bootmaster" with "SRIO1", "SRIO2" + or "PCIE1", "PCIE2", "PCIE3" for master, and then restart it in order to + perform the role as a master for boot from SRIO or PCIE. diff --git a/doc/SPL/README.omap3 b/doc/SPL/README.omap3 index a543e65..c77ca43 100644 --- a/doc/SPL/README.omap3 +++ b/doc/SPL/README.omap3 @@ -50,25 +50,3 @@ For the areas that reside within DDR1 they must not be used prior to s_init() completing. Note that CONFIG_SYS_TEXT_BASE must be clear of the areas that SPL uses while running. This is why we have two versions of the memory map that only vary in where the BSS and malloc pool reside. - -Estimating stack usage ----------------------- - -With gcc 4.6 (and later) and the use of GNU cflow it is possible to estimate -stack usage at various points in run sequence of SPL. The -fstack-usage option -to gcc will produce '.su' files (such as arch/arm/cpu/armv7/syslib.su) that -will give stack usage information and cflow can construct program flow. - -Must have gcc 4.6 or later, which supports -fstack-usage - -1) Build normally -2) Perform the following shell command to generate a list of C files used in -SPL: -$ find spl -name '*.su' | sed -e 's:^spl/::' -e 's:[.]su$:.c:' > used-spl.list -3) Execute cflow: -$ cflow --main=board_init_r `cat used-spl.list` 2>&1 | $PAGER - -cflow will spit out a number of warnings as it does not parse -the config files and picks functions based on #ifdef. Parsing the '.i' -files instead introduces another set of headaches. These warnings are -not usually important to understanding the flow, however. diff --git a/doc/driver-model/UDM-block.txt b/doc/driver-model/UDM-block.txt new file mode 100644 index 0000000..5d5c776 --- /dev/null +++ b/doc/driver-model/UDM-block.txt @@ -0,0 +1,279 @@ +The U-Boot Driver Model Project +=============================== +Block device subsystem analysis +=============================== + +Pavel Herrmann <morpheus.ibis@gmail.com> +2012-03-08 + +I) Overview +----------- + + U-Boot currently implements several distinct APIs for block devices - some + drivers use the SATA API, some drivers use the IDE API, sym53c8xx and + AHCI use the SCSI API, mg_disk has a separate API, and systemace also has a + separate API. There are also MMC and USB APIs used outside of drivers/block, + those will be detailed in their specific documents. + + Block devices are described by block_dev_desc structure, that holds, among + other things, the read/write/erase callbacks. Block device structures are + stored in any way depending on the API, but can be accessed by + + block_dev_desc_t * $api_get_dev(int dev) + + function, as seen in disk/part.c. + + 1) SATA interface + ----------------- + + The SATA interface drivers implement the following functions: + + int init_sata(int dev) + int scan_sata(int dev) + ulong sata_read(int dev, ulong blknr, ulong blkcnt, void *buffer) + ulong sata_write(int dev, ulong blknr, ulong blkcnt, const void *buffer) + + Block devices are kept in sata_dev_desc[], which is prefilled with values + common to all SATA devices in cmd_sata.c, and then modified in init_sata + function in the drivers. Callbacks of the block device use SATA API + directly. The sata_get_dev function is defined in cmd_sata.c. + + 2) SCSI interface + ----------------- + + The SCSI interface drivers implement the following functions: + + void scsi_print_error(ccb *pccb) + int scsi_exec(ccb *pccb) + void scsi_bus_reset(void) + void scsi_low_level_init(int busdevfunc) + + The SCSI API works through the scsi_exec function, the actual operation + requested is found in the ccb structure. + + Block devices are kept in scsi_dev_desc[], which lives only in cmd_scsi.c. + Callbacks of the block device use functions from cmd_scsi.c, which in turn + call scsi_exec of the controller. The scsi_get_dev function is also defined + in cmd_scsi.c. + + 3) mg_disk interface + -------------------- + + The mg_disk interface drivers implement the following functions: + + struct mg_drv_data* mg_get_drv_data (void) + uint mg_disk_init (void) + uint mg_disk_read (u32 addr, u8 *buff, u32 len) + uint mg_disk_write(u32 addr, u8 *buff, u32 len) + uint mg_disk_write_sects(void *buff, u32 sect_num, u32 sect_cnt) + uint mg_disk_read_sects(void *buff, u32 sect_num, u32 sect_cnt) + + The mg_get_drv_data function is to be overridden per-board, but there are no + board in-tree that do this. + + Only one driver for this API exists, and it only supports one block device. + Callbacks for this device are implemented in mg_disk.c and call the mg_disk + API. The mg_disk_get_dev function is defined in mg_disk.c and ignores the + device number, always returning the same device. + + 4) systemace interface + ---------------------- + + The systemace interface does not define any driver API, and has no command + itself. The single defined function is systemace_get_devs() from + systemace.c, which returns a single static structure for the only supported + block device. Callbacks for this device are also implemented in systemace.c. + + 5) IDE interface + ---------------- + + The IDE interface drivers implement the following functions, but only if + CONFIG_IDE_AHB is set: + + uchar ide_read_register(int dev, unsigned int port); + void ide_write_register(int dev, unsigned int port, unsigned char val); + void ide_read_data(int dev, ulong *sect_buf, int words); + void ide_write_data(int dev, ulong *sect_buf, int words); + + The first two functions are called from ide_inb()/ide_outb(), and will + default to direct memory access if CONFIG_IDE_AHB is not set, or + ide_inb()/ide_outb() functions will get overridden by the board altogether. + + The second two functions are called from input_data()/output_data() + functions, and also default to direct memory access, but cannot be + overridden by the board. + + One function shared by IDE drivers (but not defined in ide.h) is + int ide_preinit(void) + This function gets called from ide_init in cmd_ide.c if CONFIG_IDE_PREINIT + is defined, and will do the driver-specific initialization of the device. + + Block devices are kept in ide_dev_desc[], which is filled in cmd_ide.c. + Callbacks of the block device are defined in cmd_ide.c, and use the + ide_inb()/ide_outb()/input_data()/output_data() functions mentioned above. + The ide_get_dev function is defined in cmd_ide.c. + +II) Approach +------------ + + A new block controller core and an associated API will be created to mimic the + current SATA API, its drivers will have the following ops: + + struct block_ctrl_ops { + int scan(instance *i); + int reset(instance *i, int port); + lbaint_t read(instance *i, int port, lbaint_t start, lbatin_t length, + void *buffer); + lbaint_t write(instance *i, int port, lbaint_t start, lbatin_t length, + void*buffer); + } + + The current sata_init() function will be changed into the driver probe() + function. The read() and write() functions should never be called directly, + instead they should be called by block device driver for disks. + + Other block APIs would either be transformed into this API, or be kept as + legacy for old drivers, or be dropped altogether. + + Legacy driver APIs will each have its own driver core that will contain the + shared logic, which is currently located mostly in cmd_* files. Callbacks for + block device drivers will then probably be implemented as a part of the core + logic, and will use the driver ops (which will copy current state of + respective APIs) to do the work. + + All drivers will be cleaned up, most ifdefs should be converted into + platform_data, to enable support for multiple devices with different settings. + + A new block device core will also be created, and will keep track of all + block devices on all interfaces. + + Current block_dev_desc structure will be changed to fit the driver model, all + identification and configuration will be placed in private data, and + a single accessor and modifier will be defined, to accommodate the need for + different sets of options for different interfaces, while keeping the + structure small. The new block device drivers will have the following ops + structure (lbaint_t is either 32bit or 64bit unsigned, depending on + CONFIG_LBA48): + + struct blockdev_ops { + lbaint_t (*block_read)(struct instance *i, lbaint_t start, lbaint_t blkcnt, + void *buffer); + lbaint_t (*block_write)(struct instance *i, lbaint_t start, lbaint_t blkcnt, + void *buffer); + lbaint_t (*block_erase)(struct instance *i, lbaint_t start, lbaint_t blkcnt + ); + int (*get_option)(struct instance *i, enum blockdev_option_code op, + struct option *res); + int (*set_option)(struct instance *i, enum blockdev_option_code op, + struct option *val); + } + + struct option { + uint32_t flags + union data { + uint64_t data_u; + char* data_s; + void* data_p; + } + } + + enum blockdev_option_code { + BLKD_OPT_IFTYPE=0, + BLKD_OPT_TYPE, + BLKD_OPT_BLOCKSIZE, + BLKD_OPT_BLOCKCOUNT, + BLKD_OPT_REMOVABLE, + BLKD_OPT_LBA48, + BLKD_OPT_VENDOR, + BLKD_OPT_PRODICT, + BLKD_OPT_REVISION, + BLKD_OPT_SCSILUN, + BLKD_OPT_SCSITARGET, + BLKD_OPT_OFFSET + } + + Flags in option above will contain the type of returned data (which should be + checked against what is expected, even though the option requested should + specify it), and a flag to indicate whether the returned pointer needs to be + free()'d. + + The block device core will contain the logic now located in disk/part.c and + related files, and will be used to forward requests to block devices. The API + for the block device core will copy the ops of a block device (with a string + identifier instead of instance pointer). This means that partitions will also + be handled by the block device core, and exported as block devices, making + them transparent to the rest of the code. + + Sadly, this will change how file systems can access the devices, and thus will + affect a lot of places. However, these changes should be localized and easy to + implement. + + AHCI driver will be rewritten to fit the new unified block controller API, + making SCSI API easy to merge with sym53c8xx, or remove it once the device + driver has died. + + Optionally, IDE core may be changed into one driver with unified block + controller API, as most of it is already in one place and device drivers are + just sets of hooks. Additionally, mg_disk driver is unused and may be removed + in near future. + + + +III) Analysis of in-tree drivers +-------------------------------- + + 1) ahci.c + --------- + SCSI API, will be rewritten for a different API. + + 2) ata_piix.c + ------------- + SATA API, easy to port. + + 3) fsl_sata.c + ------------- + SATA API, few CONFIG macros, easy to port. + + 4) ftide020.c + ------------- + IDE API, defines CONFIG_IDE_AHB and ide_preinit hook functions. + + 5) mg_disk.c + ------------ + Single driver with mg_disk API, not much to change, easy to port. + + 6) mvsata_ide.c + --------------- + IDE API, only defines ide_preinit hook function. + + 7) mxc_ata.c + ------------ + IDE API, only defines ide_preinit hook function. + + 8) pata_bfin.c + -------------- + SATA API, easy to port. + + 9) sata_dwc.c + ------------- + SATA API, easy to port. + + 10) sata_sil3114.c + ------------------ + SATA API, easy to port. + + 11) sata_sil.c + -------------- + SATA API, easy to port. + + 12) sil680.c + ------------ + IDE API, only defines ide_preinit hook function. + + 13) sym53c8xx.c + --------------- + SCSI API, may be merged with code from cmd_scsi. + + 14) systemace.c + --------------- + Single driver with systemace API, not much to change, easy to port. diff --git a/doc/driver-model/UDM-cores.txt b/doc/driver-model/UDM-cores.txt new file mode 100644 index 0000000..4e13188 --- /dev/null +++ b/doc/driver-model/UDM-cores.txt @@ -0,0 +1,126 @@ +The U-Boot Driver Model Project +=============================== +Driver cores API document +========================= + +Pavel Herrmann <morpheus.ibis@gmail.com> + +1) Overview +----------- + Driver cores will be used as a wrapper for devices of the same type, and as + an abstraction for device driver APIs. For each driver API (which roughly + correspond to device types), there will be one driver core. Each driver core + will implement three APIs - a driver API (which will be the same as API of + drivers the core wraps around), a core API (which will be implemented by all + cores) and a command API (core-specific API which will be exposed to + commands). + + A) Command API + The command API will provide access to shared functionality for a specific + device, which is currently located mostly in commands. Commands will be + rewritten to be more lightweight by using this API. As this API will be + different for each core, it is out of scope of this document. + + B) Driver API + The driver API will act as a wrapper around actual device drivers, + providing a single entrypoint for device access. All functions in this API + have an instance* argument (probably called "this" or "i"), which will be + examined by the core, and a correct function for the specified driver will + get called. + + If the core gets called with a group instance pointer (as discussed in + design), it will automatically select the instance that is associated + with this core, and use it as target of the call. if the group contains + multiple instances of a single type, the caller must explicitly use an + accessor to select the correct instance. + + This accessor will look like: + struct instance *get_instance_from_group(struct instance *group, int i) + + When called with a non-group instance, it will simply return the instance. + + C) Core API + The core API will be implemented by all cores, and will provide + functionality for getting driver instances from non-driver code. This API + will consist of following functions: + + int get_count(struct instance *core); + struct instance* get_instance(struct instance *core, int index); + int init(struct instance *core); + int bind(struct instance *core, struct instance *dev, void *ops, + void *hint); + int unbind(struct instance *core, instance *dev); + int replace(struct instance *core, struct_instance *new_dev, + struct instance *old_dev); + int destroy(struct instance *core); + int reloc(struct instance *new_core, struct instance *old_core); + + The 'hint' parameter of bind() serves for additional data a driver can + pass to the core, to help it create the correct internal state for this + instance. the replace() function will get called during instance + relocation, and will replace the old instance with the new one, keeping + the internal state untouched. + + +2) Lifetime of a driver core +---------------------------- + Driver cores will be initialized at runtime, to limit memory footprint in + early-init stage, when we have to fit into ~1KB of memory. All active cores + will be stored in a tree structure (referenced as "Core tree") in global data, + which provides good tradeoff between size and access time. + Every core will have a number constant associated with it, which will be used + to find the instance in Core tree, and to refer to the core in all calls + working with the Core tree. + The Core Tree should be implemented using B-tree (or a similar structure) + to guarantee acceptable time overhead in all cases. + + Code for working with the core (i2c in this example) follows: + + core_init(CORE_I2C); + This will check whether we already have a i2c core, and if not it creates + a new instance and adds it into the Core tree. This will not be exported, + all code should depend on get_core_instance to init the core when + necessary. + + get_core_instance(CORE_I2C); + This is an accessor into the Core tree, which will return the instance + of i2c core, creating it if necessary + + core_bind(CORE_I2C, instance, driver_ops); + This will get called in bind() function of a driver, and will add the + instance into cores internal list of devices. If the core is not found, it + will get created. + + driver_activate(instance *inst); + This call will recursively activate all devices necessary for using the + specified device. the code could be simplified as: + { + if (is_activated(inst)) + return; + driver_activate(inst->bus); + get_driver(inst)->probe(inst); + } + + The case with multiple parents will need to be handled here as well. + get_driver is an accessor to available drivers, which will get struct + driver based on a name in the instance. + + i2c_write(instance *inst, ...); + An actual call to some method of the driver. This code will look like: + { + driver_activate(inst); + struct instance *core = get_core_instance(CORE_I2C); + device_ops = get_ops(inst); + device_ops->write(...); + } + + get_ops will not be an exported function, it will be internal and specific + to the core, as it needs to know how are the ops stored, and what type + they are. + + Please note that above examples represent the algorithm, not the actual code, + as they are missing checks for validity of return values. + + core_init() function will get called the first time the core is requested, + either by core_link() or core_get_instance(). This way, the cores will get + created only when they are necessary, which will reduce our memory footprint. diff --git a/doc/driver-model/UDM-design.txt b/doc/driver-model/UDM-design.txt new file mode 100644 index 0000000..185f477 --- /dev/null +++ b/doc/driver-model/UDM-design.txt @@ -0,0 +1,315 @@ +The U-Boot Driver Model Project +=============================== +Design document +=============== +Marek Vasut <marek.vasut@gmail.com> +Pavel Herrmann <morpheus.ibis@gmail.com> +2012-05-17 + +I) The modular concept +---------------------- + +The driver core design is done with modularity in mind. The long-term plan is to +extend this modularity to allow loading not only drivers, but various other +objects into U-Boot at runtime -- like commands, support for other boards etc. + +II) Driver core initialization stages +------------------------------------- + +The drivers have to be initialized in two stages, since the U-Boot bootloader +runs in two stages itself. The first stage is the one which is executed before +the bootloader itself is relocated. The second stage then happens after +relocation. + + 1) First stage + -------------- + + The first stage runs after the bootloader did very basic hardware init. This + means the stack pointer was configured, caches disabled and that's about it. + The problem with this part is the memory management isn't running at all. To + make things even worse, at this point, the RAM is still likely uninitialized + and therefore unavailable. + + 2) Second stage + --------------- + + At this stage, the bootloader has initialized RAM and is running from it's + final location. Dynamic memory allocations are working at this point. Most of + the driver initialization is executed here. + +III) The drivers +---------------- + + 1) The structure of a driver + ---------------------------- + + The driver will contain a structure located in a separate section, which + will allow linker to create a list of compiled-in drivers at compile time. + Let's call this list "driver_list". + + struct driver __attribute__((section(driver_list))) { + /* The name of the driver */ + char name[STATIC_CONFIG_DRIVER_NAME_LENGTH]; + + /* + * This function should connect this driver with cores it depends on and + * with other drivers, likely bus drivers + */ + int (*bind)(struct instance *i); + + /* This function actually initializes the hardware. */ + int (*probe)(struct instance *i); + + /* + * The function of the driver called when U-Boot finished relocation. + * This is particularly important to eg. move pointers to DMA buffers + * and such from the location before relocation to their final location. + */ + int (*reloc)(struct instance *i); + + /* + * This is called when the driver is shuting down, to deinitialize the + * hardware. + */ + int (*remove)(struct instance *i); + + /* This is called to remove the driver from the driver tree */ + int (*unbind)(struct instance *i); + + /* This is a list of cores this driver depends on */ + struct driver *cores[]; + }; + + The cores[] array in here is very important. It allows u-boot to figure out, + in compile-time, which possible cores can be activated at runtime. Therefore + if there are cores that won't be ever activated, GCC LTO might remove them + from the final binary. Actually, this information might be used to drive build + of the cores. + + FIXME: Should *cores[] be really struct driver, pointing to drivers that + represent the cores? Shouldn't it be core instance pointer? + + 2) Instantiation of a driver + ---------------------------- + + The driver is instantiated by calling: + + driver_bind(struct instance *bus, const struct driver_info *di) + + The "struct instance *bus" is a pointer to a bus with which this driver should + be registered with. The "root" bus pointer is supplied to the board init + functions. + + FIXME: We need some functions that will return list of busses of certain type + registered with the system so the user can find proper instance even if + he has no bus pointer (this will come handy if the user isn't + registering the driver from board init function, but somewhere else). + + The "const struct driver_info *di" pointer points to a structure defining the + driver to be registered. The structure is defined as follows: + + struct driver_info { + char name[STATIC_CONFIG_DRIVER_NAME_LENGTH]; + void *platform_data; + } + + The instantiation of a driver by calling driver_bind() creates an instance + of the driver by allocating "struct driver_instance". Note that only struct + instance is passed to the driver. The wrapping struct driver_instance is there + for purposes of the driver core: + + struct driver_instance { + uint32_t flags; + struct instance i; + }; + + struct instance { + /* Pointer to a driver information passed by driver_register() */ + const struct driver_info *info; + /* Pointer to a bus this driver is bound with */ + struct instance *bus; + /* Pointer to this driver's own private data */ + void *private_data; + /* Pointer to the first block of successor nodes (optional) */ + struct successor_block *succ; + } + + The instantiation of a driver does not mean the hardware is initialized. The + driver_bind() call only creates the instance of the driver, fills in the "bus" + pointer and calls the drivers' .bind() function. The .bind() function of the + driver should hook the driver with the remaining cores and/or drivers it + depends on. + + It's important to note here, that in case the driver instance has multiple + parents, such parent can be connected with this instance by calling: + + driver_link(struct instance *parent, struct instance *dev); + + This will connect the other parent driver with the newly instantiated driver. + Note that this must be called after driver_bind() and before driver_acticate() + (driver_activate() will be explained below). To allow struct instance to have + multiple parent pointer, the struct instance *bus will utilize it's last bit + to indicate if this is a pointer to struct instance or to an array if + instances, struct successor block. The approach is similar as the approach to + *succ in struct instance, described in the following paragraph. + + The last pointer of the struct instance, the pointer to successor nodes, is + used only in case of a bus driver. Otherwise the pointer contains NULL value. + The last bit of this field indicates if this is a bus having a single child + node (so the last bit is 0) or if this bus has multiple child nodes (the last + bit is 1). In the former case, the driver core should clear the last bit and + this pointer points directly to the child node. In the later case of a bus + driver, the pointer points to an instance of structure: + + struct successor_block { + /* Array of pointers to instances of devices attached to this bus */ + struct instance *dev[BLOCKING_FACTOR]; + /* Pointer to next block of successors */ + struct successor_block *next; + } + + Some of the *dev[] array members might be NULL in case there are no more + devices attached. The *next is NULL in case the list of attached devices + doesn't continue anymore. The BLOCKING_FACTOR is used to allocate multiple + slots for successor devices at once to avoid fragmentation of memory. + + 3) The bind() function of a driver + ---------------------------------- + + The bind function of a driver connects the driver with various cores the + driver provides functions for. The driver model related part will look like + the following example for a bus driver: + + int driver_bind(struct instance *in) + { + ... + core_bind(&core_i2c_static_instance, in, i2c_bus_funcs); + ... + } + + FIXME: What if we need to run-time determine, depending on some hardware + register, what kind of i2c_bus_funcs to pass? + + This makes the i2c core aware of a new bus. The i2c_bus_funcs is a constant + structure of functions any i2c bus driver must provide to work. This will + allow the i2c command operate with the bus. The core_i2c_static_instance is + the pointer to the instance of a core this driver provides function to. + + FIXME: Maybe replace "core-i2c" with CORE_I2C global pointer to an instance of + the core? + + 4) The instantiation of a core driver + ------------------------------------- + + The core driver is special in the way that it's single-instance driver. It is + always present in the system, though it might not be activated. The fact that + it's single instance allows it to be instantiated at compile time. + + Therefore, all possible structures of this driver can be in read-only memory, + especially struct driver and struct driver_instance. But the successor list, + which needs special treatment. + + To solve the problem with a successor list and the core driver flags, a new + entry in struct gd (global data) will be introduced. This entry will point to + runtime allocated array of struct driver_instance. It will be possible to + allocate the exact amount of struct driver_instance necessary, as the number + of cores that might be activated will be known at compile time. The cores will + then behave like any usual driver. + + Pointers to the struct instance of cores can be computed at compile time, + therefore allowing the resulting u-boot binary to save some overhead. + + 5) The probe() function of a driver + ----------------------------------- + + The probe function of a driver allocates necessary resources and does required + initialization of the hardware itself. This is usually called only when the + driver is needed, as a part of the defered probe mechanism. + + The driver core should implement a function called + + int driver_activate(struct instance *in); + + which should call the .probe() function of the driver and then configure the + state of the driver instance to "ACTIVATED". This state of a driver instance + should be stored in a wrap-around structure for the structure instance, the + struct driver_instance. + + 6) The command side interface to a driver + ----------------------------------------- + + The U-Boot command shall communicate only with the specific driver core. The + driver core in turn exports necessary API towards the command. + + 7) Demonstration imaginary board + -------------------------------- + + Consider the following computer: + + * + | + +-- System power management logic + | + +-- CPU clock controlling logc + | + +-- NAND controller + | | + | +-- NAND flash chip + | + +-- 128MB of DDR DRAM + | + +-- I2C bus #0 + | | + | +-- RTC + | | + | +-- EEPROM #0 + | | + | +-- EEPROM #1 + | + +-- USB host-only IP core + | | + | +-- USB storage device + | + +-- USB OTG-capable IP core + | | + | +-- connection to the host PC + | + +-- GPIO + | | + | +-- User LED #0 + | | + | +-- User LED #1 + | + +-- UART0 + | + +-- UART1 + | + +-- Ethernet controller #0 + | + +-- Ethernet controller #1 + | + +-- Audio codec + | + +-- PCI bridge + | | + | +-- Ethernet controller #2 + | | + | +-- SPI host card + | | | + | | +-- Audio amplifier (must be operational before codec) + | | + | +-- GPIO host card + | | + | +-- User LED #2 + | + +-- LCD controller + | + +-- PWM controller (must be enabled after LCD controller) + | + +-- SPI host controller + | | + | +-- SD/MMC connected via SPI + | | + | +-- SPI flash + | + +-- CPLD/FPGA with stored configuration of the board diff --git a/doc/driver-model/UDM-fpga.txt b/doc/driver-model/UDM-fpga.txt new file mode 100644 index 0000000..4f9df94 --- /dev/null +++ b/doc/driver-model/UDM-fpga.txt @@ -0,0 +1,115 @@ +The U-Boot Driver Model Project +=============================== +I/O system analysis +=================== +Marek Vasut <marek.vasut@gmail.com> +2012-02-21 + +I) Overview +----------- + +The current FPGA implementation is handled by command "fpga". This command in +turn calls the following functions: + +fpga_info() +fpga_load() +fpga_dump() + +These functions are implemented by what appears to be FPGA multiplexer, located +in drivers/fpga/fpga.c . This code determines which device to operate with +depending on the device ID. + +The fpga_info() function is multiplexer of the functions providing information +about the particular FPGA device. These functions are implemented in the drivers +for the particular FPGA device: + +xilinx_info() +altera_info() +lattice_info() + +Similar approach is used for fpga_load(), which multiplexes "xilinx_load()", +"altera_load()" and "lattice_load()" and is used to load firmware into the FPGA +device. + +The fpga_dump() function, which prints the contents of the FPGA device, is no +different either, by multiplexing "xilinx_dump()", "altera_dump()" and +"lattice_dump()" functions. + +Finally, each new FPGA device is registered by calling "fpga_add()" function. +This function takes two arguments, the second one being particularly important, +because it's basically what will become platform_data. Currently, it's data that +are passed to the driver from the board/platform code. + +II) Approach +------------ + +The path to conversion of the FPGA subsystem will be very straightforward, since +the FPGA subsystem is already quite dynamic. Multiple things will need to be +modified though. + +First is the registration of the new FPGA device towards the FPGA core. This +will be achieved by calling: + + fpga_device_register(struct instance *i, const struct fpga_ops *ops); + +The particularly interesting part is the struct fpga_ops, which contains +operations supported by the FPGA device. These are basically the already used +calls in the current implementation: + +struct fpga_ops { + int info(struct instance *i); + int load(struct instance *i, const char *buf, size_t size); + int dump(struct instance *i, const char *buf, size_t size); +} + +The other piece that'll have to be modified is how the devices are tracked. +It'll be necessary to introduce a linked list of devices within the FPGA core +instead of tracking them by ID number. + +Next, the "Xilinx_desc", "Lattice_desc" and "Altera_desc" structures will have +to be moved to driver's private_data. Finally, structures passed from the board +and/or platform files, like "Xilinx_Virtex2_Slave_SelectMap_fns" would be passed +via platform_data to the driver. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) Altera driver + ---------------- + The driver is realized using the following files: + + drivers/fpga/altera.c + drivers/fpga/ACEX1K.c + drivers/fpga/cyclon2.c + drivers/fpga/stratixII.c + + All of the sub-drivers implement basically the same info-load-dump interface + and there's no expected problem during the conversion. The driver itself will + be realised by altera.c and all the sub-drivers will be linked in. The + distinction will be done by passing different platform data. + + 2) Lattice driver + ----------------- + The driver is realized using the following files: + + drivers/fpga/lattice.c + drivers/fpga/ivm_core.c + + This driver also implements the standard interface, but to realise the + operations with the FPGA device, uses functions from "ivm_core.c" file. This + file implements the main communications logic and has to be linked in together + with "lattice.c". No problem converting is expected here. + + 3) Xilinx driver + ---------------- + The driver is realized using the following files: + + drivers/fpga/xilinx.c + drivers/fpga/spartan2.c + drivers/fpga/spartan3.c + drivers/fpga/virtex2.c + + This set of sub-drivers is special by defining a big set of macros in + "include/spartan3.h" and similar files. These macros would need to be either + rewritten or replaced. Otherwise, there are no problems expected during the + conversion process. diff --git a/doc/driver-model/UDM-gpio.txt b/doc/driver-model/UDM-gpio.txt new file mode 100644 index 0000000..8ff0a96 --- /dev/null +++ b/doc/driver-model/UDM-gpio.txt @@ -0,0 +1,106 @@ +The U-Boot Driver Model Project +=============================== +GPIO analysis +============= +Viktor Krivak <viktor.krivak@gmail.com> +2012-02-24 + +I) Overview +----------- + + At this moment U-Boot provides standard API that consists of 7 functions. + + int gpio_request(unsigned gpio, const char *label) + int gpio_free(unsigned gpio) + int gpio_direction_input(unsigned gpio) + int gpio_direction_output(unsigned gpio, int value) + int gpio_get_value(unsigned gpio) + void gpio_set_value(unsigned gpio, int value) + + Methods "gpio_request()" and "gpio_free()" are used for claiming and releasing + GPIOs. First one should check if the desired pin exists and if the pin wasn't + requested already elsewhere. The method also has a label argument that can be + used for debug purposes. The label argument should be copied into the internal + memory, but only if the DEBUG macro is set. The "gpio_free()" is the exact + opposite. It releases the particular pin. Other methods are used for setting + input or output direction and obtaining or setting values of the pins. + +II) Approach +------------ + + 1) Request and free GPIO + ------------------------ + + The "gpio_request()" implementation is basically the same for all boards. + The function checks if the particular GPIO is correct and checks if the + GPIO pin is still free. If the conditions are met, the method marks the + GPIO claimed in it's internal structure. If macro DEBUG is defined, the + function also copies the label argument to the structure. If the pin is + already locked, the function returns -1 and if DEBUG is defined, certain + debug output is generated, including the contents of the label argument. + The "gpio_free()" function releases the lock and eventually deallocates + data used by the copied label argument. + + 2) Internal data + ---------------- + + Internal data are driver specific. They have to contain some mechanism to + realise the locking though. This can be done for example using a bit field. + + 3) Operations provided by the driver + ------------------------------------ + + The driver operations basically meet API that is already defined and used. + Except for "gpio_request()" and "gpio_free()", all methods can be converted in + a simple manner. The driver provides the following structure: + + struct gpio_driver_ops { + int (*gpio_request)(struct instance *i, unsigned gpio, + const char *label); + int (*gpio_free)(struct instance *i, unsigned gpio); + int (*gpio_direction_input)(struct instance *i, unsigned gpio); + int (*gpio_direction_output)(struct instance *i, unsigned gpio, + int value); + int (*gpio_get_value)(struct instance *i, unsigned gpio); + void (*gpio_set_value)(struct instance *i, unsigned gpio, int value); + } + +III) Analysis of in-tree drivers +-------------------------------- + + 1) altera_pio.c + --------------- + Meets standard API. Implements gpio_request() properly. Simple conversion + possible. + + 2) at91_gpio.c + -------------- + Don't meet standard API. Need some other methods to implement. + + 3) da8xx_gpio.c + --------------- + Meets standard API. Implements gpio_request() properly. Simple conversion + possible. + + 4) kw_gpio.c + ------------ + Doesn't meet standard API. Needs some other methods to implement and move some + methods to another file. + + 5) mpc83xx_gpio.c + ----------------- + Meets standard API. Doesn't implement gpio_request() properly (only checks + if the pin is valid). Simple conversion possible. + + 6) mvgpio.c + ----------- + Meets standard API. Doesn't implement gpio_request() properly (only checks + if the pin is valid). Simple conversion possible. + + 7) mvgpio.h + ----------- + Wrong placement. Will be moved to another location. + + 8) mvmfp.c + ---------- + Wrong placement. Will be moved to another location. diff --git a/doc/driver-model/UDM-hwmon.txt b/doc/driver-model/UDM-hwmon.txt new file mode 100644 index 0000000..cc5d529 --- /dev/null +++ b/doc/driver-model/UDM-hwmon.txt @@ -0,0 +1,118 @@ +The U-Boot Driver Model Project +=============================== +Hwmon device subsystem analysis +=============================== + +Tomas Hlavacek <tmshlvck@gmail.com> +2012-03-02 + +I) Overview +----------- + +U-Boot currently implements one API for HW monitoring devices. The +interface is defined in include/dtt.h and comprises of functions: + + void dtt_init(void); + int dtt_init_one(int); + int dtt_read(int sensor, int reg); + int dtt_write(int sensor, int reg, int val); + int dtt_get_temp(int sensor); + +The functions are implemented by a proper device driver in drivers/hwmon +directory and the driver to be compiled in is selected in a Makefile. +Drivers are mutually exclusive. + +Drivers depends on I2O code and naturally on board specific data. There are +few ad-hoc constants put in dtt.h file and driver headers and code. This +has to be consolidated into board specific data or driver headers if those +constants makes sense globally. + + +II) Approach +------------ + + 1) New API + ---------- + In the UDM each hwmon driver would register itself by a function + + int hwmon_device_register(struct instance *i, + struct hwmon_device_ops *o); + + The structure being defined as follows: + + struct hwmon_device_ops { + int (*read)(struct instance *i, int sensor, int reg); + int (*write)(struct instance *i, int sensor, int reg, + int val); + int (*get_temp)(struct instance *i, int sensor); + }; + + + 2) Conversion thougths + ---------------------- + U-Boot hwmon drivers exports virtually the same functions (with exceptions) + and we are considering low number of drivers and code anyway. The interface + is already similar and unified by the interface defined in dtt.h. + Current initialization functions dtt_init() and dtt_init_one() will be + converted into probe() and hwmon_device_register(), so the funcionality will + be kept in more proper places. Besides implementing core registration and + initialization we need to do code cleanup, especially separate + driver-specific and HW specific constants. + + 3) Special consideration due to early initialization + ---------------------------------------------------- + The dtt_init() function call is used during early initialization in + board/gdsys/405ex/io64.c for starting up fans. The dtt code is perfectly + usable in the early stage because it uses only local variables and no heap + memory is required at this level. However the underlying code of I2C has to + keep the same properties with regard to possibility of running in early + initialization stage. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) drivers/hwmon/lm81.c + ----------------------- + The driver is standard dtt. Simple conversion is possible. + + + 2) drivers/hwmon/ds1722.c + ------------------------- + The driver is not standard dtt, but interface is similar to dtt. + The interface has to be changed in order to comply to above mentioned + specification. + + + 3) drivers/hwmon/ds1775.c + ------------------------- + The driver is standard dtt. Simple conversion is possible. + + + 4) drivers/hwmon/lm73.c + ----------------------- + The driver is standard dtt. Simple conversion is possible. + + + 5) drivers/hwmon/lm63.c + ----------------------- + The driver is standard dtt. Simple conversion is possible. + + + 6) drivers/hwmon/adt7460.c + -------------------------- + The driver is standard dtt. Simple conversion is possible. + + + 7) drivers/hwmon/lm75.c + ----------------------- + The driver is standard dtt. Simple conversion is possible. + + + 8) drivers/hwmon/ds1621.c + ------------------------- + The driver is standard dtt. Simple conversion is possible. + + + 9) drivers/hwmon/adm1021.c + -------------------------- + The driver is standard dtt. Simple conversion is possible. diff --git a/doc/driver-model/UDM-keyboard.txt b/doc/driver-model/UDM-keyboard.txt new file mode 100644 index 0000000..ef3761d --- /dev/null +++ b/doc/driver-model/UDM-keyboard.txt @@ -0,0 +1,47 @@ +The U-Boot Driver Model Project +=============================== +Keyboard input analysis +======================= +Marek Vasut <marek.vasut@gmail.com> +2012-02-20 + +I) Overview +----------- + +The keyboard drivers are most often registered with STDIO subsystem. There are +components of the keyboard drivers though, which operate in severe ad-hoc +manner, often being related to interrupt-driven keypress reception. This +components will require the most sanitization of all parts of keyboard input +subsystem. + +Otherwise, the keyboard is no different from other standard input but with the +necessity to decode scancodes. These are decoded using tables provided by +keyboard drivers. These tables are often driver specific. + +II) Approach +------------ + +The most problematic part is the interrupt driven keypress reception. For this, +the buffers that are currently shared throughout the whole U-Boot would need to +be converted into driver's private data. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) board/mpl/common/kbd.c + ------------------------- + This driver is a classic STDIO driver, no problem with conversion is expected. + Only necessary change will be to move this driver to a proper location. + + 2) board/rbc823/kbd.c + --------------------- + This driver is a classic STDIO driver, no problem with conversion is expected. + Only necessary change will be to move this driver to a proper location. + + 3) drivers/input/keyboard.c + --------------------------- + This driver is special in many ways. Firstly because this is a universal stub + driver for converting scancodes from i8042 and the likes. Secondly because the + buffer is filled by various other ad-hoc implementations of keyboard input by + using this buffer as an extern. This will need to be fixed by allowing drivers + to pass certain routines to this driver via platform data. diff --git a/doc/driver-model/UDM-mmc.txt b/doc/driver-model/UDM-mmc.txt new file mode 100644 index 0000000..bed4306 --- /dev/null +++ b/doc/driver-model/UDM-mmc.txt @@ -0,0 +1,319 @@ +The U-Boot Driver Model Project +=============================== +MMC system analysis +=================== +Marek Vasut <marek.vasut@gmail.com> +2012-02-25 + +I) Overview +----------- + +The MMC subsystem is already quite dynamic in it's nature. It's only necessary +to flip the subsystem to properly defined API. + +The probing process of MMC drivers start by calling "mmc_initialize()", +implemented by MMC framework, from the architecture initialization file. The +"mmc_initialize()" function in turn calls "board_mmc_init()" function and if +this doesn't succeed, "cpu_mmc_init()" function is called. It is important to +note that both of the "*_mmc_init()" functions have weak aliases to functions +which automatically fail. + +Both of the "*_mmc_init()" functions though serve only one purpose. To call +driver specific probe function, which in turn actually registers the driver with +MMC subsystem. Each of the driver specific probe functions is currently done in +very ad-hoc manner. + +The registration with the MMC subsystem is done by calling "mmc_register()", +whose argument is a runtime configured structure of information about the MMC +driver. Currently, the information structure is intermixed with driver's internal +data. The description of the structure follows: + +struct mmc { + /* + * API: Allows this driver to be a member of the linked list of all MMC drivers + * registered with MMC subsystem + */ + struct list_head link; + + /* DRIVER: Name of the registered driver */ + char name[32]; + + /* DRIVER: Driver's private data */ + void *priv; + + /* DRIVER: Voltages the host bus can provide */ + uint voltages; + + /* API: Version of the card */ + uint version; + + /* API: Test if the driver was already initialized */ + uint has_init; + + /* DRIVER: Minimum frequency the host bus can provide */ + uint f_min; + + /* DRIVER: Maximum frequency the host bus can provide */ + uint f_max; + + /* API: Is the card SDHC */ + int high_capacity; + + /* API: Actual width of the bus used by the current card */ + uint bus_width; + + /* + * DRIVER: Clock frequency to be configured on the host bus, this is read-only + * for the driver. + */ + uint clock; + + /* API: Capabilities of the card */ + uint card_caps; + + /* DRIVER: MMC bus capabilities */ + uint host_caps; + + /* API: Configuration and ID data retrieved from the card */ + uint ocr; + uint scr[2]; + uint csd[4]; + uint cid[4]; + ushort rca; + + /* API: Partition configuration */ + char part_config; + + /* API: Number of partitions */ + char part_num; + + /* API: Transmission speed */ + uint tran_speed; + + /* API: Read block length */ + uint read_bl_len; + + /* API: Write block length */ + uint write_bl_len; + + /* API: Erase group size */ + uint erase_grp_size; + + /* API: Capacity of the card */ + u64 capacity; + + /* API: Descriptor of this block device */ + block_dev_desc_t block_dev; + + /* DRIVER: Function used to submit command to the card */ + int (*send_cmd)(struct mmc *mmc, + struct mmc_cmd *cmd, struct mmc_data *data); + + /* DRIVER: Function used to configure the host */ + void (*set_ios)(struct mmc *mmc); + + /* DRIVER: Function used to initialize the host */ + int (*init)(struct mmc *mmc); + + /* DRIVER: Function used to report the status of Card Detect pin */ + int (*getcd)(struct mmc *mmc); + + /* + * DRIVER: Maximum amount of blocks sent during multiblock xfer, + * set to 0 to autodetect. + */ + uint b_max; +}; + +The API above is the new API used by most of the drivers. There're still drivers +in the tree that use old, legacy API though. + +2) Approach +----------- + +To convert the MMC subsystem to a proper driver model, the "struct mmc" +structure will have to be properly split in the first place. The result will +consist of multiple parts, first will be the structure defining operations +provided by the MMC driver: + +struct mmc_driver_ops { + /* Function used to submit command to the card */ + int (*send_cmd)(struct mmc *mmc, + struct mmc_cmd *cmd, struct mmc_data *data); + /* DRIVER: Function used to configure the host */ + void (*set_ios)(struct mmc *mmc); + /* Function used to initialize the host */ + int (*init)(struct mmc *mmc); + /* Function used to report the status of Card Detect pin */ + int (*getcd)(struct mmc *mmc); +} + +The second part will define the parameters of the MMC driver: + +struct mmc_driver_params { + /* Voltages the host bus can provide */ + uint32_t voltages; + /* Minimum frequency the host bus can provide */ + uint32_t f_min; + /* Maximum frequency the host bus can provide */ + uint32_t f_max; + /* MMC bus capabilities */ + uint32_t host_caps; + /* + * Maximum amount of blocks sent during multiblock xfer, + * set to 0 to autodetect. + */ + uint32_t b_max; +} + +And finally, the internal per-card data of the MMC subsystem core: + +struct mmc_card_props { + /* Version of the card */ + uint32_t version; + /* Test if the driver was already initializes */ + bool has_init; + /* Is the card SDHC */ + bool high_capacity; + /* Actual width of the bus used by the current card */ + uint8_t bus_width; + /* Capabilities of the card */ + uint32_t card_caps; + /* Configuration and ID data retrieved from the card */ + uint32_t ocr; + uint32_t scr[2]; + uint32_t csd[4]; + uint32_t cid[4]; + uint16_t rca; + /* Partition configuration */ + uint8_t part_config; + /* Number of partitions */ + uint8_t part_num; + /* Transmission speed */ + uint32_t tran_speed; + /* Read block length */ + uint32_t read_bl_len; + /* Write block length */ + uint32_t write_bl_len; + /* Erase group size */ + uint32_t erase_grp_size; + /* Capacity of the card */ + uint64_t capacity; + /* Descriptor of this block device */ + block_dev_desc_t block_dev; +} + +The probe() function will then register the MMC driver by calling: + + mmc_device_register(struct instance *i, struct mmc_driver_ops *o, + struct mmc_driver_params *p); + +The struct mmc_driver_params will have to be dynamic in some cases, but the +driver shouldn't modify it's contents elsewhere than in probe() call. + +Next, since the MMC drivers will now be consistently registered into the driver +tree from board file, the functions "board_mmc_init()" and "cpu_mmc_init()" will +disappear altogether. + +As for the legacy drivers, these will either be converted or removed altogether. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) arm_pl180_mmci.c + ------------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 2) atmel_mci.c + -------------- + This driver uses the legacy API and should be removed unless converted. It is + probably possbible to replace this driver with gen_atmel_mci.c . No conversion + will be done on this driver. + + 3) bfin_sdh.c + ------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 4) davinci_mmc.c + ---------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 5) fsl_esdhc.c + -------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple, unless some problem appears due to the FDT + component of the driver. + + 6) ftsdc010_esdhc.c + ------------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 7) gen_atmel_mci.c + ------------------ + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 8) mmc_spi.c + ------------ + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 9) mv_sdhci.c + ------------- + This is a component of the SDHCI support, allowing it to run on Marvell + Kirkwood chip. It is probable the SDHCI support will have to be modified to + allow calling functions from this file based on information passed via + platform_data. + + 10) mxcmmc.c + ------------ + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 11) mxsmmc.c + ------------ + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 12) omap_hsmmc.c + ---------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 13) pxa_mmc.c + ------------- + This driver uses the legacy API and is written in a severely ad-hoc manner. + This driver will be removed in favor of pxa_mmc_gen.c, which is proved to work + better and is already well tested. No conversion will be done on this driver + anymore. + + 14) pxa_mmc_gen.c + ----------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 15) s5p_mmc.c + ------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 16) sdhci.c + ----------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple, though it'd be necessary to modify this driver + to also support the Kirkwood series and probably also Tegra series of CPUs. + See the respective parts of this section for details. + + 17) sh_mmcif.c + -------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 18) tegra2_mmc.c + ---------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. diff --git a/doc/driver-model/UDM-net.txt b/doc/driver-model/UDM-net.txt new file mode 100644 index 0000000..e2ea8f5 --- /dev/null +++ b/doc/driver-model/UDM-net.txt @@ -0,0 +1,434 @@ +The U-Boot Driver Model Project +=============================== +Net system analysis +=================== +Marek Vasut <marek.vasut@gmail.com> +2012-03-03 + +I) Overview +----------- + +The networking subsystem already supports multiple devices. Therefore the +conversion shall not be very hard. + +The network subsystem is operated from net/eth.c, which tracks all registered +ethernet interfaces and calls their particular functions registered via +eth_register(). + +The eth_register() is called from the network driver initialization function, +which in turn is called most often either from "board_net_init()" or +"cpu_net_init()". This function has one important argument, which is the +"struct eth_device", defined at include/net.h: + +struct eth_device { + /* DRIVER: Name of the device */ + char name[NAMESIZE]; + /* DRIVER: MAC address */ + unsigned char enetaddr[6]; + /* DRIVER: Register base address */ + int iobase; + /* CORE: state of the device */ + int state; + + /* DRIVER: Device initialization function */ + int (*init) (struct eth_device*, bd_t*); + /* DRIVER: Function for sending packets */ + int (*send) (struct eth_device*, volatile void* packet, int length); + /* DRIVER: Function for receiving packets */ + int (*recv) (struct eth_device*); + /* DRIVER: Function to cease operation of the device */ + void (*halt) (struct eth_device*); + /* DRIVER: Function to send multicast packet (OPTIONAL) */ + int (*mcast) (struct eth_device*, u32 ip, u8 set); + /* DRIVER: Function to change ethernet MAC address */ + int (*write_hwaddr) (struct eth_device*); + /* CORE: Next device in the linked list of devices managed by net core */ + struct eth_device *next; + /* CORE: Device index */ + int index; + /* DRIVER: Driver's private data */ + void *priv; +}; + +This structure defines the particular driver, though also contains elements that +should not be exposed to the driver, like core state. + +Small, but important part of the networking subsystem is the PHY management +layer, whose drivers are contained in drivers/net/phy. These drivers register in +a very similar manner to network drivers, by calling "phy_register()" with the +argument of "struct phy_driver": + +struct phy_driver { + /* DRIVER: Name of the PHY driver */ + char *name; + /* DRIVER: UID of the PHY driver */ + unsigned int uid; + /* DRIVER: Mask for UID of the PHY driver */ + unsigned int mask; + /* DRIVER: MMDS of the PHY driver */ + unsigned int mmds; + /* DRIVER: Features the PHY driver supports */ + u32 features; + /* DRIVER: Initialize the PHY hardware */ + int (*probe)(struct phy_device *phydev); + /* DRIVER: Reconfigure the PHY hardware */ + int (*config)(struct phy_device *phydev); + /* DRIVER: Turn on the PHY hardware, allow it to send/receive */ + int (*startup)(struct phy_device *phydev); + /* DRIVER: Turn off the PHY hardware */ + int (*shutdown)(struct phy_device *phydev); + /* CORE: Allows this driver to be part of list of drivers */ + struct list_head list; +}; + +II) Approach +------------ + +To convert the elements of network subsystem to proper driver model method, the +"struct eth_device" will have to be split into multiple components. The first +will be a structure defining the driver operations: + +struct eth_driver_ops { + int (*init)(struct instance*, bd_t*); + int (*send)(struct instance*, void *packet, int length); + int (*recv)(struct instance*); + void (*halt)(struct instance*); + int (*mcast)(struct instance*, u32 ip, u8 set); + int (*write_hwaddr)(struct instance*); +}; + +Next, there'll be platform data which will be per-driver and will replace the +"priv" part of "struct eth_device". Last part will be the per-device core state. + +With regards to the PHY part of the API, the "struct phy_driver" is almost ready +to be used with the new driver model approach. The only change will be the +replacement of per-driver initialization functions and removal of +"phy_register()" function in favor or driver model approach. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) drivers/net/4xx_enet.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 2) drivers/net/altera_tse.c + --------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 3) drivers/net/armada100_fec.c + ------------------------------ + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 4) drivers/net/at91_emac.c + -------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 5) drivers/net/ax88180.c + ------------------------ + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 6) drivers/net/ax88796.c + ------------------------ + + This file contains a components of the NE2000 driver, implementing only + different parts on the NE2000 clone AX88796. This being no standalone driver, + no conversion will be done here. + + 7) drivers/net/bfin_mac.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 8) drivers/net/calxedaxgmac.c + ----------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 9) drivers/net/cs8900.c + ----------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 10) drivers/net/davinci_emac.c + ------------------------------ + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 11) drivers/net/dc2114x.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 12) drivers/net/designware.c + ---------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 13) drivers/net/dm9000x.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 14) drivers/net/dnet.c + ---------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 15) drivers/net/e1000.c + ----------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 16) drivers/net/e1000_spi.c + --------------------------- + + Driver for the SPI bus integrated on the Intel E1000. This is not part of the + network stack. + + 17) drivers/net/eepro100.c + -------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 18) drivers/net/enc28j60.c + -------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 19) drivers/net/ep93xx_eth.c + ---------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 20) drivers/net/ethoc.c + ----------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 21) drivers/net/fec_mxc.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 22) drivers/net/fsl_mcdmafec.c + ------------------------------ + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 23) drivers/net/fsl_mdio.c + -------------------------- + + This file contains driver for FSL MDIO interface, which is not part of the + networking stack. + + 24) drivers/net/ftgmac100.c + --------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 25) drivers/net/ftmac100.c + -------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 26) drivers/net/greth.c + ----------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 27) drivers/net/inca-ip_sw.c + ---------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 28) drivers/net/ks8695eth.c + --------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 29) drivers/net/lan91c96.c + -------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 30) drivers/net/macb.c + ---------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 31) drivers/net/mcffec.c + ------------------------ + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 32) drivers/net/mcfmii.c + ------------------------ + + This file contains MII interface driver for MCF FEC. + + 33) drivers/net/mpc512x_fec.c + ----------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 34) drivers/net/mpc5xxx_fec.c + ----------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 35) drivers/net/mvgbe.c + ----------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 36) drivers/net/natsemi.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 37) drivers/net/ne2000_base.c + ----------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. This driver contains the core + implementation of NE2000, which needs a few external functions, implemented by + AX88796, NE2000 etc. + + 38) drivers/net/ne2000.c + ------------------------ + + This file implements external functions necessary for native NE2000 compatible + networking card to work. + + 39) drivers/net/netarm_eth.c + ---------------------------- + + This driver uses the old, legacy, network API and will either have to be + converted or removed. + + 40) drivers/net/netconsole.c + ---------------------------- + + This is actually an STDIO driver. + + 41) drivers/net/ns8382x.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 42) drivers/net/pcnet.c + ----------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 43) drivers/net/plb2800_eth.c + ----------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 44) drivers/net/rtl8139.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 45) drivers/net/rtl8169.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 46) drivers/net/sh_eth.c + ------------------------ + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 47) drivers/net/smc91111.c + -------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 48) drivers/net/smc911x.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 49) drivers/net/tsec.c + ---------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 50) drivers/net/tsi108_eth.c + ---------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 51) drivers/net/uli526x.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 52) drivers/net/vsc7385.c + ------------------------- + + This is a driver that only uploads firmware to a switch. This is not subject + of conversion. + + 53) drivers/net/xilinx_axi_emac.c + --------------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 54) drivers/net/xilinx_emaclite.c + --------------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. diff --git a/doc/driver-model/UDM-pci.txt b/doc/driver-model/UDM-pci.txt new file mode 100644 index 0000000..b65e9ea --- /dev/null +++ b/doc/driver-model/UDM-pci.txt @@ -0,0 +1,265 @@ +The U-Boot Driver Model Project +=============================== +PCI subsystem analysis +====================== + +Pavel Herrmann <morpheus.ibis@gmail.com> +2012-03-17 + +I) Overview +----------- + + U-Boot already supports multiple PCI busses, stored in a linked-list of + pci_controller structures. This structure contains generic driver data, bus + interface operations and private data for the driver. + + Bus interface operations for PCI are (names are self-explanatory): + + read_byte() + read_word() + read_dword() + write_byte() + write_word() + write_dword() + + Each driver has to implement dword operations, and either implement word and + byte operations, or use shared $operation_config_$type_via_dword (eg. + read_config_byte_via_dword and similar) function. These functions are used + for config space I/O (read_config_dword and similar functions of the PCI + subsystem), which is used to configure the connected devices for standard MMIO + operations. All data transfers by respective device drivers are then done by + MMIO + + Each driver also defines a separate init function, which has unique symbol + name, and thus more drivers can be compiled in without colliding. This init + function is typically called from pci_init_board(), different for each + particular board. + + Some boards also define a function called fixup_irq, which gets called after + scanning the PCI bus for devices, and should dismiss any interrupts. + + Several drivers are also located in arch/ and should be moved to drivers/pci. + +II) Approach +------------ + + The pci_controller structure needs to be broken down to fit the new driver + model. Due to a large number of members, this will be done through three + distinct accessors, one for memory regions, one for config table and one for + everything else. That will make the pci_ops structure look like this: + + struct pci_ops { + int (*read_byte)(struct instance *bus, pci_dev_t *dev, int addr, + u8 *buf); + int (*read_word)(struct instance *bus, pci_dev_t *dev, int addr, + u16 *buf); + int (*read_dword)(struct instance *bus, pci_dev_t *dev, int addr, + u32 *buf); + int (*write_byte)(struct instance *bus, pci_dev_t *dev, int addr, + u8 val); + int (*write_byte)(struct instance *bus, pci_dev_t *dev, int addr, + u8 val); + int (*write_dword)(struct instance *bus, pci_dev_t *dev, int addr, + u32 val); + void (*fixup_irq)(struct instance *bus, pci_dev_t *dev); + struct pci_region* (*get_region)(struct instance *, uint num); + struct pci_config_table* (*get_cfg_table)(struct instance *bus); + uint (*get_option)(struct instance * bus, enum pci_option_code op); + } + + enum pci_option_code { + PCI_OPT_BUS_NUMBER=0, + PCI_OPT_REGION_COUNT, + PCI_OPT_INDIRECT_TYPE, + PCI_OPT_AUTO_MEM, + PCI_OPT_AUTO_IO, + PCI_OPT_AUTO_PREFETCH, + PCI_OPT_AUTO_FB, + PCI_OPT_CURRENT_BUS, + PCI_OPT_CFG_ADDR, + } + + The return value for get_option will be an unsigned integer value for any + option code. If the option currently is a pointer to pci_region, it will + return an index for get_region function. Special case has to be made for + PCI_OPT_CFG_ADDR, which should be interpreted as a pointer, but it is only + used for equality in find_hose_by_cfg_addr, and thus can be returned as an + uint. Other function using cfg_addr value are read/write functions for + specific drivers (especially ops for indirect bridges), and thus have access + to private_data of the driver instance. + + The config table accessor will return a pointer to a NULL-terminated array of + pci_config_table, which is supplied by the board in platform_data, or NULL if + the board didn't specify one. This table is used to override PnP + auto-initialization, or to specific initialization functions for non-PNP + devices. + + Transparent PCI-PCI bridges will get their own driver, and will forward all + operations to operations of their parent bus. This however makes it + impossible to use instances to identify devices, as not all devices will be + directly visible to the respective bus driver. + + Init functions of controller drivers will be moved to their respective + probe() functions, in accordance to the driver model. + + The PCI core will handle all mapping functions currently found in pci.c, as + well as proxy functions for read/write operations of the drivers. The PCI + core will also handle bus scanning and device configuration. + + The PnP helper functions currently in pci_auto.c will also be a part of PCI + core, but they will be exposed only to PCI controller drivers, not to other + device drivers. + + The PCI API for device drivers will remain largely unchanged, most drivers + will require no changes at all, and all modifications will be limited to + changing the pci_controlle into instance*. + +III) Analysis of in-tree drivers +-------------------------------- + + A) drivers in drivers/pci/ + -------------------------- + + 1) pci_indirect.c + ----------------- + Shared driver for indirect PCI bridges, several CONFIG macros - will + require significant cleanup. + + 2) pci_ixp.c + ------------ + Standard driver, specifies all read/write functions separately. + + 3) pci_sh4.c + ------------ + Shared init function for SH4 drivers, uses dword for read/write ops. + + 4) pci_sh7751.c + --------------- + Standard driver, uses SH4 shared init. + + 5) pci_sh7780.c + --------------- + Standard driver, uses SH4 shared init. + + 6) tsi108_pci.c + --------------- + Standard driver, uses dword for read/write ops. + + 7) fsl_pci_init.c + ----------------- + Driver for PCI and PCI-e, uses indirect functions. + + 8) pci_ftpci100.c + ----------------- + Standard driver, uses indirect functions, has separate scan/setup + functions. + + B) driver in arch/ + ------------------ + + 1) x86/lib/pci_type1.c + ---------------------- + Standard driver, specifies all read/write functions separately. + + 2) m68k/cpu/mcf5445x/pci.c + -------------------------- + Standard driver, specifies all read/write functions separately. + + 3) m68k/cpu/mcf547x_8x/pci.c + ---------------------------- + Standard driver, specifies all read/write functions separately. + + 4) powerpc/cpu/mpc824x/pci.c + ---------------------------- + Standard driver, uses indirect functions, does not setup HW. + + 5) powerpc/cpu/mpc8260/pci.c + ---------------------------- + Standard driver, uses indirect functions. + + 6) powerpc/cpu/ppc4xx/4xx_pci.c + ------------------------------- + Standard driver, uses indirect functions. + + 7) powerpc/cpu/ppc4xx/4xx_pcie.c + -------------------------------- + PCI-e driver, specifies all read/write functions separately. + + 8) powerpc/cpu/mpc83xx/pci.c + ---------------------------- + Standard driver, uses indirect functions. + + 9) powerpc/cpu/mpc83xx/pcie.c + ----------------------------- + PCI-e driver, specifies all read/write functions separately. + + 10) powerpc/cpu/mpc5xxx/pci_mpc5200.c + ------------------------------------- + Standard driver, uses dword for read/write ops. + + 11) powerpc/cpu/mpc512x/pci.c + ----------------------------- + Standard driver, uses indirect functions. + + 12) powerpc/cpu/mpc8220/pci.c + ----------------------------- + Standard driver, specifies all read/write functions separately. + + 13) powerpc/cpu/mpc85xx/pci.c + ----------------------------- + Standard driver, uses indirect functions, has two busses. + + C) drivers in board/ + -------------------- + + 1) eltec/elppc/pci.c + -------------------- + Standard driver, uses indirect functions. + + 2) amirix/ap1000/pci.c + ---------------------- + Standard driver, specifies all read/write functions separately. + + 3) prodrive/p3mx/pci.c + ---------------------- + Standard driver, uses dword for read/write ops, has two busses. + + 4) esd/cpci750/pci.c + -------------------- + Standard driver, uses dword for read/write ops, has two busses. + + 5) esd/common/pci.c + ------------------- + Standard driver, uses dword for read/write ops. + + 6) dave/common/pci.c + -------------------- + Standard driver, uses dword for read/write ops. + + 7) ppmc7xx/pci.c + ---------------- + Standard driver, uses indirect functions. + + 8) pcippc2/cpc710_pci.c + ----------------------- + Standard driver, uses indirect functions, has two busses. + + 9) Marvell/db64360/pci.c + ------------------------ + Standard driver, uses dword for read/write ops, has two busses. + + 10) Marvell/db64460/pci.c + ------------------------- + Standard driver, uses dword for read/write ops, has two busses. + + 11) evb64260/pci.c + ------------------ + Standard driver, uses dword for read/write ops, has two busses. + + 12) armltd/integrator/pci.c + --------------------------- + Standard driver, specifies all read/write functions separately. + + All drivers will be moved to drivers/pci. Several drivers seem + similar/identical, especially those located under board, and may be merged + into one. diff --git a/doc/driver-model/UDM-pcmcia.txt b/doc/driver-model/UDM-pcmcia.txt new file mode 100644 index 0000000..fc31461 --- /dev/null +++ b/doc/driver-model/UDM-pcmcia.txt @@ -0,0 +1,78 @@ +The U-Boot Driver Model Project +=============================== +PCMCIA analysis +=============== +Viktor Krivak <viktor.krivak@gmail.com> +2012-03-17 + +I) Overview +----------- + + U-boot implements only 2 methods to interoperate with pcmcia. One to turn + device on and other to turn device off. Names of these methods are usually + pcmcia_on() and pcmcia_off() without any parameters. Some files in driver + directory implements only internal API. These methods aren't used outside + driver directory and they are not converted to new driver model. + +II) Approach +----------- + + 1) New API + ---------- + + Current API is preserved and all internal methods are hiden. + + struct ops { + void (*pcmcia_on)(struct instance *i); + void (*pcmcia_off)(struct instance *i); + } + + 2) Conversion + ------------- + + In header file pcmcia.h are some other variables which are used for + additional configuration. But all have to be moved to platform data or to + specific driver implementation. + + 3) Platform data + ---------------- + + Many boards have custom implementation of internal API. Pointers to these + methods are stored in platform_data. But the most implementations for Intel + 82365 and compatible PC Card controllers and Yenta-compatible + PCI-to-CardBus controllers implement whole API per board. In these cases + pcmcia_on() and pcmcia_off() behave only as wrappers and call specific + board methods. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) i82365.c + ----------- + Driver methods have different name i82365_init() and i82365_exit but + all functionality is the same. Board files board/atc/ti113x.c and + board/cpc45/pd67290.c use their own implementation of these method. + In this case all methods in driver behave only as wrappers. + + 2) marubun_pcmcia.c + ------------------- + Meets standard API behaviour. Simple conversion. + + 3) mpc8xx_pcmcia.c + ------------------ + Meets standard API behaviour. Simple conversion. + + 4) rpx_pcmcia.c + --------------- + Implements only internal API used in other drivers. Non of methods + implemented here are used outside driver model. + + 5) ti_pci1410a.c + ---------------- + Has different API but methods in this file are never called. Probably + dead code. + + 6)tqm8xx_pcmcia.c + ----------------- + Implements only internal API used in other drivers. Non of methods + implemented here are used outside driver model. diff --git a/doc/driver-model/UDM-power.txt b/doc/driver-model/UDM-power.txt new file mode 100644 index 0000000..9ac1a5f --- /dev/null +++ b/doc/driver-model/UDM-power.txt @@ -0,0 +1,88 @@ +The U-Boot Driver Model Project +=============================== +POWER analysis +============== +Viktor Krivak <viktor.krivak@gmail.com> +2012-03-09 + +I) Overview +----------- + + 1) Actual state + --------------- + + At this moment power doesn't contain API. There are many methods for + initialization of some board specific functions but only few does what is + expected. Basically only one file contains something meaningful for this + driver. + + 2) Current implementation + ------------------------- + + In file twl6030.c are methods twl6030_stop_usb_charging() and + twl6030_start_usb_charging() for start and stop charging from USB. There are + also methods to get information about battery state and initialization of + battery charging. Only these methods are used in converted API. + + +II) Approach +------------ + + 1) New API + ---------- + + New API implements only functions specific for managing power. All board + specific init methods are moved to other files. Name of methods are + self-explanatory. + + struct ops { + void (*start_usb_charging)(struct instance *i); + void (*stop_usb_charging)(struct instance *i); + int (*get_battery_current)(struct instance *i); + int (*get_battery_voltage)(struct instance *i); + void (*init_battery_charging)(struct instance *i); + } + + 2) Conversions of other methods + ------------------------------- + + Methods that can't be converted to new API are moved to board file or to + special file for board hacks. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) ftpmu010.c + ------------- + All methods of this file are moved to another location. + void ftpmu010_32768osc_enable(void): Move to boards hacks + void ftpmu010_mfpsr_select_dev(unsigned int dev): Move to board file + arch/nds32/lib/board.c + void ftpmu010_mfpsr_diselect_dev(unsigned int dev): Dead code + void ftpmu010_dlldis_disable(void): Dead code + void ftpmu010_sdram_clk_disable(unsigned int cr0): Move to board file + arch/nds32/lib/board.c + void ftpmu010_sdramhtc_set(unsigned int val): Move to board file + arch/nds32/lib/board.c + + 2) twl4030.c + ------------ + All methods of this file are moved to another location. + void twl4030_power_reset_init(void): Move to board hacks + void twl4030_pmrecv_vsel_cfg(u8 vsel_reg, u8 vsel_val, u8 dev_grp, + u8 dev_grp_sel): Move to board hacks + void twl4030_power_init(void): Move to board hacks + void twl4030_power_mmc_init(void): Move to board hacks + + 3) twl6030.c + ------------ + Some methods are converted to new API and rest are moved to another location. + void twl6030_stop_usb_charging(void): Convert to new API + void twl6030_start_usb_charging(void): Convert to new API + int twl6030_get_battery_current(void): Convert to new API + int twl6030_get_battery_voltage(void): Convert to new API + void twl6030_init_battery_charging(void): Convert to new API + void twl6030_power_mmc_init(): Move to board file + drivers/mmc/omap_hsmmc.c + void twl6030_usb_device_settings(): Move to board file + drivers/usb/musb/omap3.c diff --git a/doc/driver-model/UDM-rtc.txt b/doc/driver-model/UDM-rtc.txt new file mode 100644 index 0000000..5d9fb33 --- /dev/null +++ b/doc/driver-model/UDM-rtc.txt @@ -0,0 +1,258 @@ +============================= +RTC device subsystem analysis +============================= + +Tomas Hlavacek <tmshlvck@gmail.com> +2012-03-10 + +I) Overview +----------- + +U-Boot currently implements one common API for RTC devices. The interface +is defined in include/rtc.h and comprises of functions and structures: + + struct rtc_time { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + }; + + int rtc_get (struct rtc_time *); + int rtc_set (struct rtc_time *); + void rtc_reset (void); + +The functions are implemented by a proper device driver in drivers/rtc +directory and the driver to be compiled in is selected in a Makefile. +Drivers are mutually exclusive. + +Drivers depends on date code in drivers/rtc/date.c and naturally on board +specific data. + +II) Approach +------------ + + 1) New API + ---------- + In the UDM each rtc driver would register itself by a function + + int rtc_device_register(struct instance *i, + struct rtc_device_ops *o); + + The structure being defined as follows: + + struct rtc_device_ops { + int (*get_time)(struct instance *i, struct rtc_time *t); + int (*set_time)(struct instance *i, struct rtc_time *t); + int (*reset)(struct instance *i); + }; + + + 2) Conversion thougths + ---------------------- + U-Boot RTC drivers exports the same functions and therefore the conversion + of the drivers is straight-forward. There is no initialization needed. + + +III) Analysis of in-tree drivers +-------------------------------- + + 1) drivers/rtc/rv3029.c + ----------------------- + The driver is standard rtc. Simple conversion is possible. + + + 2) drivers/rtc/s3c24x0_rtc.c + ---------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 3) drivers/rtc/pt7c4338.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 4) drivers/rtc/mvrtc.c + ---------------------- + The driver is standard rtc. Simple conversion is possible. + + + 5) drivers/rtc/ftrtc010.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 6) drivers/rtc/mpc5xxx.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 7) drivers/rtc/ds164x.c + ----------------------- + The driver is standard rtc. Simple conversion is possible. + + + 8) drivers/rtc/rs5c372.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 9) drivers/rtc/m41t94.c + ----------------------- + The driver is standard rtc. Simple conversion is possible. + + + 10) drivers/rtc/mc13xxx-rtc.c + ----------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 11) drivers/rtc/mcfrtc.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 12) drivers/rtc/davinci.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 13) drivers/rtc/rx8025.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 14) drivers/rtc/bfin_rtc.c + -------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 15) drivers/rtc/m41t62.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 16) drivers/rtc/ds1306.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 17) drivers/rtc/mpc8xx.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 18) drivers/rtc/ds3231.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 19) drivers/rtc/ds12887.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 20) drivers/rtc/ds1302.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 21) drivers/rtc/ds1374.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 22) drivers/rtc/ds174x.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 23) drivers/rtc/m41t60.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 24) drivers/rtc/m48t35ax.c + -------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 25) drivers/rtc/pl031.c + ----------------------- + The driver is standard rtc. Simple conversion is possible. + + + 26) drivers/rtc/x1205.c + ----------------------- + The driver is standard rtc. Simple conversion is possible. + + + 27) drivers/rtc/m41t11.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 28) drivers/rtc/pcf8563.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 29) drivers/rtc/mk48t59.c + ------------------------- + Macros needs cleanup. Besides that the driver is standard rtc. + Simple conversion is possible. + + + 30) drivers/rtc/mxsrtc.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 31) drivers/rtc/ds1307.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 32) drivers/rtc/ds1556.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 33) drivers/rtc/rtc4543.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 34) drivers/rtc/s3c44b0_rtc.c + ----------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 35) drivers/rtc/ds1337.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 36) drivers/rtc/isl1208.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 37) drivers/rtc/max6900.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 38) drivers/rtc/mc146818.c + -------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 39) drivers/rtc/at91sam9_rtt.c + ------------------------------ + The driver is standard rtc. Simple conversion is possible. diff --git a/doc/driver-model/UDM-serial.txt b/doc/driver-model/UDM-serial.txt new file mode 100644 index 0000000..e9c274d --- /dev/null +++ b/doc/driver-model/UDM-serial.txt @@ -0,0 +1,191 @@ +The U-Boot Driver Model Project +=============================== +Serial I/O analysis +=================== +Marek Vasut <marek.vasut@gmail.com> +2012-02-20 + +I) Overview +----------- + +The serial port support currently requires the driver to export the following +functions: + + serial_putc() ...... Output a character + serial_puts() ...... Output string, often done using serial_putc() + serial_tstc() ...... Test if incoming character is in a buffer + serial_getc() ...... Retrieve incoming character + serial_setbrg() .... Configure port options + serial_init() ...... Initialize the hardware + +The simpliest implementation, supporting only one port, simply defines these six +functions and calls them. Such calls are scattered all around U-Boot, especiall +serial_putc(), serial_puts(), serial_tstc() and serial_getc(). The serial_init() +and serial_setbrg() are often called from platform-dependent places. + +It's important to consider current implementation of CONFIG_SERIAL_MULTI though. +This resides in common/serial.c and behaves as a multiplexer for serial ports. +This, by calling serial_assign(), allows user to switch I/O from one serial port +to another. Though the environmental variables "stdin", "stdout", "stderr" +remain set to "serial". + +These variables are managed by the IOMUX. This resides in common/iomux.c and +manages all console input/output from U-Boot. For serial port, only one IOMUX is +always registered, called "serial" and the switching of different serial ports +is done by code in common/serial.c. + +On a final note, it's important to mention function default_serial_console(), +which is platform specific and reports the default serial console for the +platform, unless proper environment variable overrides this. + +II) Approach +------------ + +Drivers not using CONFIG_SERIAL_MULTI already will have to be converted to +similar approach. The probe() function of a driver will call a function +registering the driver with a STDIO subsystem core, stdio_device_register(). + +The serial_init() function will now be replaced by probe() function of the +driver, the rest of the components of the driver will be converted to standard +STDIO driver calls. See [ UDM-stdio.txt ] for details. + +The serial_setbrg() function depends on global data pointer. This is wrong, +since there is likely to be user willing to configure different baudrate on two +different serial ports. The function will be replaced with STDIO's "conf()" +call, with STDIO_CONFIG_SERIAL_BAUDRATE argument. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) altera_jtag_uart.c + --------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 2) altera_uart.c + ---------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 3) arm_dcc.c + ------------ + No support for CONFIG_SERIAL_MULTI. Simple conversion possible, unless used + with CONFIG_ARM_DCC_MULTI. Then it registers another separate IOMUX. + + 4) atmel_usart.c + ---------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 5) mcfuart.c + ------------ + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 6) ns16550.c + ------------ + This driver seems complicated and certain consideration will need to be made + during conversion. This driver is implemented in very universal manner, + therefore it'll be necessary to properly design it's platform_data. + + 7) ns9750_serial.c + ------------------ + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 8) opencores_yanu.c + ------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 9) s3c4510b_uart.c + ------------------ + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 10) s3c64xx.c + ------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 11) sandbox.c + ------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 12) serial.c + ------------ + This is a complementary part of NS16550 UART driver, see above. + + 13) serial_clps7111.c + --------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 14) serial_imx.c + ---------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. This driver + might be removed in favor of serial_mxc.c . + + 15) serial_ixp.c + ---------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 16) serial_ks8695.c + ------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 17) serial_lh7a40x.c + -------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 18) serial_lpc2292.c + -------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 19) serial_max3100.c + -------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 20) serial_mxc.c + ---------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 21) serial_netarm.c + ------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 22) serial_pl01x.c + ------------------ + No support for CONFIG_SERIAL_MULTI. Simple conversion possible, though this + driver in fact contains two drivers in total. + + 23) serial_pxa.c + ---------------- + This driver is a bit complicated, but due to clean support for + CONFIG_SERIAL_MULTI, there are no expected obstructions throughout the + conversion process. + + 24) serial_s3c24x0.c + -------------------- + This driver, being quite ad-hoc might need some work to bring back to shape. + + 25) serial_s3c44b0.c + -------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 26) serial_s5p.c + ---------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 27) serial_sa1100.c + ------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 28) serial_sh.c + --------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 29) serial_xuartlite.c + ---------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 30) usbtty.c + ------------ + This driver seems very complicated and entangled with USB framework. The + conversion might be complicated here. + + 31) arch/powerpc/cpu/mpc512x/serial.c + ------------------------------------- + This driver supports CONFIG_SERIAL_MULTI. This driver will need to be moved to + proper place. diff --git a/doc/driver-model/UDM-spi.txt b/doc/driver-model/UDM-spi.txt new file mode 100644 index 0000000..7442a32 --- /dev/null +++ b/doc/driver-model/UDM-spi.txt @@ -0,0 +1,200 @@ +The U-Boot Driver Model Project +=============================== +SPI analysis +============ +Viktor Krivak <viktor.krivak@gmail.com> +2012-03-03 + +I) Overview +----------- + + 1) The SPI driver + ----------------- + + At this moment U-Boot provides standard API that consist of 7 functions: + + void spi_init(void); + struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode); + void spi_free_slave(struct spi_slave *slave); + int spi_claim_bus(struct spi_slave *slave); + void spi_release_bus(struct spi_slave *slave); + int spi_xfer(struct spi_slave *slave, unsigned int bitlen, + const void *dout, void *din, unsigned long flags); + int spi_cs_is_valid(unsigned int bus, unsigned int cs); + void spi_cs_activate(struct spi_slave *slave); + void spi_cs_deactivate(struct spi_slave *slave); + void spi_set_speed(struct spi_slave *slave, uint hz); + + Method spi_init() is usually empty. All necessary configuration are sets by + spi_setup_slave(). But this configuration is usually stored only in memory. + No real hardware sets are made. All hardware settings are provided by method + spi_claim_bus(). This method claims the bus and it can't be claimed again + until it's release. That's mean all calls of method spi_claim_bus() will + fail. But lots of cpu implementation don't meet this behaviour. + Method spi_release_bus() does exact opposite. It release bus directly by + some hardware sets. spi_free_slave() only free memory allocated by + spi_setup_slave(). Method spi_xfer() do actually read and write operation + throw specified bus and cs. Other methods are self explanatory. + + 2) Current limitations + ---------------------- + + Theoretically at this moment api allows use more then one bus per device at + the time. But in real this can be achieved only when all buses have their + own base addresses in memory. + + +II) Approach +------------ + + 1) Claiming bus + --------------- + + The current api cannot be used because struct spi_slave have to be in + private data. In that case user are prohibited to use different bus on one + device at same time. But when base memory address for bus are different. + It's possible make more instance of this driver. Otherwise it can't can be + done because of hardware limitation. + + 2) API change + ------------- + + Method spi_init() is moved to probe. Methods spi_setup_slave() and + spi_claim_bus() are joined to one method. This method checks if desired bus + exists and is available then configure necessary hardware and claims bus. + Method spi_release_bus() and spi_free_slave() are also joined to meet this + new approach. Other function remain same. Only struct spi_slave was change + to instance. + + struct ops { + int (*spi_request_bus)(struct instance *i, unsigned int bus, + unsigned int cs, unsigned int max_hz, + unsigned int mode); + void (*spi_release_bus)(struct instance *i); + int (*spi_xfer) (struct instance *i, unsigned int bitlen, + const void *dout, void *din, unsigned long flags); + int (*spi_cs_is_valid)(struct instance *i, unsigned int bus, + unsigned int cs); + void (*spi_cs_activate)(struct instance *i); + void (*spi_cs_deactivate)(struct instance *i); + void (*spi_set_speed)(struct instance *i, uint hz); + } + + 3) Legacy API + ------------- + + To easy conversion of the whole driver. Original and new api can exist next + to each other. New API is designed to be only a wrapper that extracts + necessary information from private_data and use old api. When driver can + use more than one bus at the time. New API require multiple instance. One + for each bus. In this case spi_slave have to be copied in each instance. + + 4) Conversion TIME-LINE + ----------------------- + + To prevent build corruption api conversion have to be processed in several + independent steps. In first step all old API methods are renamed. After that + new API and core function are implemented. Next step is conversion of all + board init methods to set platform data. After all these steps it is possible + to start conversion of all remaining calls. This procedure guarantees that + build procedure and binaries are never broken. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) altera_spi.c + --------------- + All methods have designated structure. Simple conversion possible. + + 2) andes_spi.c + -------------- + All methods have designated structure. Simple conversion possible. + + 3) andes_spi.h + -------------- + Support file for andes_spi.c. No conversion is needed. + + 4) armada100_spi.c + ------------------ + All methods have designated structure. Simple conversion possible. + + 5) atmel_dataflash_spi.c + ------------------------ + Wrong placement. Will be moved to another location. + + 6) atmel_spi.c + -------------- + Supports more than one bus. Need some minor change. + + 7) atmel_spi.h + -------------- + Support file for andes_spi.c. No conversion is needed. + + 8) bfin_spi.c + ------------- + Supports more than one bus. Need some minor change. + + 9) cf_spi.c + ----------- + Cooperate with some cpu specific methods from other files. Hard conversion. + + 10) davinci_spi.c + ----------------- + All methods have designated structure. Simple conversion possible. + + 11) davinci_spi.h + ----------------- + Support file for davinci_spi.h. No conversion is needed. + + 12) fsl_espi.c + -------------- + All methods have designated structure. Simple conversion possible. + + 13) kirkwood_spi.c + ------------------ + All methods have designated structure. Simple conversion possible. + + 14) mpc8xxx_spi.c + ----------------- + All methods have designated structure. Simple conversion possible. + + 15) mpc52xx_spi.c + ----------------- + All methods have designated structure. Simple conversion possible. + + 16) mxc_spi.c + ------------- + All methods have designated structure. Simple conversion possible. + + 17) mxs_spi.c + ------------- + All methods have designated structure. Simple conversion possible. + + 18) oc_tiny_spi.c + ----------------- + Supports more than one bus. Need some minor change. + + 19) omap3_spi.c + --------------- + Supports more than one bus. Need some minor change. + + 20) omap3_spi.h + --------------- + Support file for omap3_spi.c. No conversion is needed. + + 21) sh_spi.c + ------------ + All methods have designated structure. Simple conversion possible. + + 22) sh_spi.h + ------------ + Support file for sh_spi.h. No conversion is needed. + + 23) soft_spi.c + -------------- + Use many board specific method linked from other files. Need careful debugging. + + 24) tegra2_spi.c + ---------------- + Some hardware specific problem when releasing bus. diff --git a/doc/driver-model/UDM-stdio.txt b/doc/driver-model/UDM-stdio.txt new file mode 100644 index 0000000..a6c484f --- /dev/null +++ b/doc/driver-model/UDM-stdio.txt @@ -0,0 +1,191 @@ +The U-Boot Driver Model Project +=============================== +I/O system analysis +=================== +Marek Vasut <marek.vasut@gmail.com> +2012-02-20 + +I) Overview +----------- + +The console input and output is currently done using the STDIO subsystem in +U-Boot. The design of this subsystem is already flexible enough to be easily +converted to new driver model approach. Minor changes will need to be done +though. + +Each device that wants to register with STDIO subsystem has to define struct +stdio_dev, defined in include/stdio_dev.h and containing the following fields: + +struct stdio_dev { + int flags; /* Device flags: input/output/system */ + int ext; /* Supported extensions */ + char name[16]; /* Device name */ + +/* GENERAL functions */ + + int (*start) (void); /* To start the device */ + int (*stop) (void); /* To stop the device */ + +/* OUTPUT functions */ + + void (*putc) (const char c); /* To put a char */ + void (*puts) (const char *s); /* To put a string (accelerator) */ + +/* INPUT functions */ + + int (*tstc) (void); /* To test if a char is ready... */ + int (*getc) (void); /* To get that char */ + +/* Other functions */ + + void *priv; /* Private extensions */ + struct list_head list; +}; + +Currently used flags are DEV_FLAGS_INPUT, DEV_FLAGS_OUTPUT and DEV_FLAGS_SYSTEM, +extensions being only one, the DEV_EXT_VIDEO. + +The private extensions are now used as a per-device carrier of private data and +finally list allows this structure to be a member of linked list of STDIO +devices. + +The STDIN, STDOUT and STDERR routing is handled by environment variables +"stdin", "stdout" and "stderr". By configuring the variable to the name of a +driver, functions of such driver are called to execute that particular +operation. + +II) Approach +------------ + + 1) Similarity of serial, video and keyboard drivers + --------------------------------------------------- + + All of these drivers can be unified under the STDIO subsystem if modified + slightly. The serial drivers basically define both input and output functions + and need function to configure baudrate. The keyboard drivers provide only + input. On the other hand, video drivers provide output, but need to be + configured in certain way. This configuration might be dynamic, therefore the + STDIO has to be modified to provide such flexibility. + + 2) Unification of serial, video and keyboard drivers + ---------------------------------------------------- + + Every STDIO device would register a structure containing operation it supports + with the STDIO core by calling: + + int stdio_device_register(struct instance *i, struct stdio_device_ops *o); + + The structure being defined as follows: + + struct stdio_device_ops { + void (*putc)(struct instance *i, const char c); + void (*puts)(struct instance *i, const char *s); /* OPTIONAL */ + + int (*tstc)(struct instance *i); + int (*getc)(struct instance *i); + + int (*init)(struct instance *i); + int (*exit)(struct instance *i); + int (*conf)(struct instance *i, enum stdio_config c, const void *data); + }; + + The "putc()" function will emit a character, the "puts()" function will emit a + string. If both of these are set to NULL, the device is considered STDIN only, + aka input only device. + + The "getc()" retrieves a character from a STDIN device, while "tstc()" tests + if there is a character in the buffer of STDIN device. In case these two are + set to NULL, this device is STDOUT / STDERR device. + + Setting all "putc()", "puts()", "getc()" and "tstc()" calls to NULL isn't an + error condition, though such device does nothing. By instroducing tests for + these functions being NULL, the "flags" and "ext" fields from original struct + stdio_dev can be eliminated. + + The "init()" and "exit()" calls are replacement for "start()" and "exit()" + calls in the old approach. The "priv" part of the old struct stdio_dev will be + replaced by common private data in the driver model and the struct list_head + list will be eliminated by introducing common STDIO core, that tracks all the + STDIO devices. + + Lastly, the "conf()" call will allow the user to configure various options of + the driver. The enum stdio_config contains all possible configuration options + available to the STDIO devices, const void *data being the argument to be + configured. Currently, the enum stdio_config will contain at least the + following options: + + enum stdio_config { + STDIO_CONFIG_SERIAL_BAUDRATE, + }; + + 3) Transformation of stdio routing + ---------------------------------- + + By allowing multiple instances of drivers, the environment variables "stdin", + "stdout" and "stderr" can no longer be set to the name of the driver. + Therefore the STDIO core, tracking all of the STDIO devices in the system will + need to have a small amount of internal data for each device: + + struct stdio_device_node { + struct instance *i; + struct stdio_device_ops *ops; + uint8_t id; + uint8_t flags; + struct list_head list; + } + + The "id" is the order of the instance of the same driver. The "flags" variable + allows multiple drivers to be used at the same time and even for different + purpose. The following flags will be defined: + + STDIO_FLG_STDIN ..... This device will be used as an input device. All input + from all devices with this flag set will be received + and passed to the upper layers. + STDIO_FLG_STDOUT .... This device will be used as an output device. All + output sent to stdout will be routed to all devices + with this flag set. + STDIO_FLG_STDERR .... This device will be used as an standard error output + device. All output sent to stderr will be routed to + all devices with this flag set. + + The "list" member of this structure allows to have a linked list of all + registered STDIO devices. + +III) Analysis of in-tree drivers +-------------------------------- + +For in-depth analysis of serial port drivers, refer to [ UDM-serial.txt ]. +For in-depth analysis of keyboard drivers, refer to [ UDM-keyboard.txt ]. +For in-depth analysis of video drivers, refer to [ UDM-video.txt ]. + + 1) arch/blackfin/cpu/jtag-console.c + ----------------------------------- + This driver is a classic STDIO driver, no problem with conversion is expected. + + 2) board/mpl/pati/pati.c + ------------------------ + This driver registers with the STDIO framework, though it uses a lot of ad-hoc + stuff which will need to be sorted out. + + 3) board/netphone/phone_console.c + --------------------------------- + This driver is a classic STDIO driver, no problem with conversion is expected. + + 4) drivers/net/netconsole.c + --------------------------- + This driver is a classic STDIO driver, no problem with conversion is expected. + +IV) Other involved files (To be removed) +---------------------------------------- + +common/cmd_console.c +common/cmd_log.c +common/cmd_terminal.c +common/console.c +common/fdt_support.c +common/iomux.c +common/lcd.c +common/serial.c +common/stdio.c +common/usb_kbd.c +doc/README.iomux diff --git a/doc/driver-model/UDM-tpm.txt b/doc/driver-model/UDM-tpm.txt new file mode 100644 index 0000000..91a953a --- /dev/null +++ b/doc/driver-model/UDM-tpm.txt @@ -0,0 +1,48 @@ +The U-Boot Driver Model Project +=============================== +TPM system analysis +=================== +Marek Vasut <marek.vasut@gmail.com> +2012-02-23 + +I) Overview +----------- + +There is currently only one TPM chip driver available and therefore the API +controlling it is very much based on this. The API is very simple: + + int tis_open(void); + int tis_close(void); + int tis_sendrecv(const u8 *sendbuf, size_t send_size, + u8 *recvbuf, size_t *recv_len); + +The command operating the TPM chip only provides operations to send and receive +bytes from the chip. + +II) Approach +------------ + +The API can't be generalised too much considering there's only one TPM chip +supported. But it's a good idea to split the tis_sendrecv() function in two +functions. Therefore the new API will use register the TPM chip by calling: + + tpm_device_register(struct instance *i, const struct tpm_ops *ops); + +And the struct tpm_ops will contain the following members: + + struct tpm_ops { + int (*tpm_open)(struct instance *i); + int (*tpm_close)(struct instance *i); + int (*tpm_send)(const uint8_t *buf, const size_t size); + int (*tpm_recv)(uint8_t *buf, size_t *size); + }; + +The behaviour of "tpm_open()" and "tpm_close()" will basically copy the +behaviour of "tis_open()" and "tis_close()". The "tpm_send()" will be based on +the "tis_senddata()" and "tis_recv()" will be based on "tis_readresponse()". + +III) Analysis of in-tree drivers +-------------------------------- + +There is only one in-tree driver present, the "drivers/tpm/generic_lpc_tpm.c", +which will be simply converted as outlined in previous chapter. diff --git a/doc/driver-model/UDM-twserial.txt b/doc/driver-model/UDM-twserial.txt new file mode 100644 index 0000000..289416a --- /dev/null +++ b/doc/driver-model/UDM-twserial.txt @@ -0,0 +1,47 @@ +================================== +TWserial device subsystem analysis +================================== + +Tomas Hlavacek<tmshlvck@gmail.com> +2012-03-21 + +I) Overview +----------- + +U-Boot currently implements one common API for TWSerial devices. The interface +is defined in include/tws.h and comprises of functions: + + int tws_read(uchar *buffer, int len); + int tws_write(uchar *buffer, int len); + +The functions are implemented by a proper device driver in drivers/twserial +directory and the driver to be compiled in is selected in a Makefile. There is +only one driver present now. + +The driver depends on ad-hoc code in board specific data, namely functions: + + void tws_ce(unsigned bit); + void tws_wr(unsigned bit); + void tws_clk(unsigned bit); + void tws_data(unsigned bit); + unsigned tws_data_read(void); + void tws_data_config_output(unsigned output); + +implemented in include/configs/inka4x0.h . + +II) Approach +------------ + + U-Boot TWserial drivers exports two simple functions and therefore the conversion + of the driver and creating a core for it is not needed. It should be consolidated + with include/configs/inka4x0.h and taken to the misc/ dir. + + +III) Analysis of in-tree drivers +-------------------------------- + + 1) drivers/twserial/soft_tws.c + ------------------------------ + The driver is the only TWserial driver. The ad-hoc part in + include/configs/inka4x0.h and the core soft_tws driver should be consolidated + to one compact driver and moved to misc/ . diff --git a/doc/driver-model/UDM-usb.txt b/doc/driver-model/UDM-usb.txt new file mode 100644 index 0000000..5ce85b5 --- /dev/null +++ b/doc/driver-model/UDM-usb.txt @@ -0,0 +1,94 @@ +The U-Boot Driver Model Project +=============================== +USB analysis +============ +Marek Vasut <marek.vasut@gmail.com> +2012-02-16 + +I) Overview +----------- + + 1) The USB Host driver + ---------------------- + There are basically four or five USB host drivers. All such drivers currently + provide at least the following fuctions: + + usb_lowlevel_init() ... Do the initialization of the USB controller hardware + usb_lowlevel_stop() ... Do the shutdown of the USB controller hardware + + usb_event_poll() ...... Poll interrupt from USB device, often used by KBD + + submit_control_msg() .. Submit message via Control endpoint + submit_int_msg() ...... Submit message via Interrupt endpoint + submit_bulk_msg() ..... Submit message via Bulk endpoint + + + This allows for the host driver to be easily abstracted. + + 2) The USB hierarchy + -------------------- + + In the current implementation, the USB Host driver provides operations to + communicate via the USB bus. This is realised by providing access to a USB + root port to which an USB root hub is attached. The USB bus is scanned and for + each newly found device, a struct usb_device is allocated. See common/usb.c + and include/usb.h for details. + +II) Approach +------------ + + 1) The USB Host driver + ---------------------- + + Converting the host driver will follow the classic driver model consideration. + Though, the host driver will have to call a function that registers a root + port with the USB core in it's probe() function, let's call this function + + usb_register_root_port(&ops); + + This will allow the USB core to track all available root ports. The ops + parameter will contain structure describing operations supported by the root + port: + + struct usb_port_ops { + void (*usb_event_poll)(); + int (*submit_control_msg)(); + int (*submit_int_msg)(); + int (*submit_bulk_msg)(); + } + + 2) The USB hierarchy and hub drivers + ------------------------------------ + + Converting the USB heirarchy should be fairy simple, considering the already + dynamic nature of the implementation. The current usb_hub_device structure + will have to be converted to a struct instance. Every such instance will + contain components of struct usb_device and struct usb_hub_device in it's + private data, providing only accessors in order to properly encapsulate the + driver. + + By registering the root port, the USB framework will instantiate a USB hub + driver, which is always present, the root hub. The root hub and any subsequent + hub instance is represented by struct instance and it's private data contain + amongst others common bits from struct usb_device. + + Note the USB hub driver is partly defying the usual method of registering a + set of callbacks to a particular core driver. Instead, a static set of + functions is defined and the USB hub instance is passed to those. This creates + certain restrictions as of how the USB hub driver looks, but considering the + specification for USB hub is given and a different type of USB hub won't ever + exist, this approach is ok: + + - Report how many ports does this hub have: + uint get_nr_ports(struct instance *hub); + - Get pointer to device connected to a port: + struct instance *(*get_child)(struct instance *hub, int port); + - Instantiate and configure device on port: + struct instance *(*enum_dev_on_port)(struct instance *hub, int port); + + 3) USB device drivers + --------------------- + + The USB device driver, in turn, will have to register various ops structures + with certain cores. For example, USB disc driver will have to register it's + ops with core handling USB discs etc. diff --git a/doc/driver-model/UDM-video.txt b/doc/driver-model/UDM-video.txt new file mode 100644 index 0000000..342aeee --- /dev/null +++ b/doc/driver-model/UDM-video.txt @@ -0,0 +1,74 @@ +The U-Boot Driver Model Project +=============================== +Video output analysis +===================== +Marek Vasut <marek.vasut@gmail.com> +2012-02-20 + +I) Overview +----------- + +The video drivers are most often registered with video subsystem. This subsystem +often expects to be allowed access to framebuffer of certain parameters. This +subsystem also provides calls for STDIO subsystem to allow it to output +characters on the screen. For this part, see [ UDM-stdio.txt ]. + +Therefore the API has two parts, the video driver part and the part where the +video driver core registers with STDIO API. + +The video driver part will follow the current cfb_console approach, though +allowing it to be more dynamic. + +II) Approach +------------ + +Registering the video driver into the video driver core is done by calling the +following function from the driver probe() function: + + video_device_register(struct instance *i, GraphicDevice *gd); + +Because the video driver core is in charge or rendering characters as well as +bitmaps on the screen, it will in turn call stdio_device_register(i, so), where +"i" is the same instance as the video driver's one. But "so" will be special +static struct stdio_device_ops handling the character output. + + +III) Analysis of in-tree drivers +-------------------------------- + + 1) arch/powerpc/cpu/mpc8xx/video.c + ---------------------------------- + This driver copies the cfb_console [ see drivers/video/cfb_console.c ] + approach and acts only as a STDIO device. Therefore there are currently two + possible approaches, first being the conversion of this driver to usual STDIO + device and second, long-term one, being conversion of this driver to video + driver that provides console. + + 2) arch/x86/lib/video.c + ----------------------- + This driver registers two separate STDIO devices and should be therefore + converted as such. + + 3) board/bf527-ezkit/video.c + ---------------------------- + This driver seems bogus as it behaves as STDIO device, but provides no input + or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use + or present otherwise than as a dead code/define. + + 4) board/bf533-stamp/video.c + ---------------------------- + This driver seems bogus as it behaves as STDIO device, but provides no input + or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use + or present otherwise than as a dead code/define. + + 5) board/bf548-ezkit/video.c + ---------------------------- + This driver seems bogus as it behaves as STDIO device, but provides no input + or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use + or present otherwise than as a dead code/define. + + 6) board/cm-bf548/video.c + ---------------------------- + This driver seems bogus as it behaves as STDIO device, but provides no input + or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use + or present otherwise than as a dead code/define. diff --git a/doc/driver-model/UDM-watchdog.txt b/doc/driver-model/UDM-watchdog.txt new file mode 100644 index 0000000..271bd26 --- /dev/null +++ b/doc/driver-model/UDM-watchdog.txt @@ -0,0 +1,334 @@ +The U-Boot Driver Model Project +=============================== +Watchdog device subsystem analysis +================================== + +Tomas Hlavacek <tmshlvck@gmail.com> +2012-03-09 + +I) Overview +----------- + +U-Boot currently implements an API for HW watchdog devices as explicit drivers +in drivers/watchdog directory. There are also drivers for both hardware and +software watchdog on particular CPUs implemented in arch/*/cpu/*/cpu.c. There +are macros in include/watchdog.h that selects between SW and HW watchdog and +assembly SW implementation. + +The current common interface comprises of one set out of these two possible +variants: + + 1) + void watchdog_reset(void); + int watchdog_disable(void); + int watchdog_init(void); + + 2) + void hw_watchdog_reset(void); + void hw_watchdog_init(void); + +The watchdog implementations are also spread through board/*/*.c that in +some cases. The API and semantics is in most cases same as the above +mentioned common functions. + + +II) Approach +------------ + + 1) New API + ---------- + + In the UDM each watchdog driver would register itself by a function + + int watchdog_device_register(struct instance *i, + const struct watchdog_device_ops *o); + + The structure being defined as follows: + + struct watchdog_device_ops { + int (*disable)(struct instance *i); + void (*reset)(struct instance *i); + }; + + The watchdog_init() function will be dissolved into probe() function. + + 2) Conversion thougths + ---------------------- + + Conversion of watchdog implementations to a new API could be divided + to three subsections: a) HW implementations, which are mostly compliant + to the above mentioned API; b) SW implementations, which are compliant + to the above mentioned API and c) SW implementations that are not compliant + to the API and has to be rectified or partially rewritten. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) drivers/watchdog/at91sam9_wdt.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 2) drivers/watchdog/ftwdt010_wdt.c + ---------------------------------- + The driver is ad-hoc HW watchdog. Conversion has to take into account + driver parts spread in include/faraday/*. Restructuring the driver and + code cleanup has to be considered. + + + 3) arch/arm/cpu/arm1136/mx31/timer.c + ------------------------------------ + The driver is semi-standard ad-hoc HW watchdog. Conversion has to take + into account driver parts spread in the timer.c file. + + + 4) arch/arm/cpu/arm926ejs/davinci/timer.c + ----------------------------------------- + The driver is ad-hoc semi-standard HW watchdog. Conversion has to take + into account driver parts spread in the timer.c file. + + + 5) arch/arm/cpu/armv7/omap-common/hwinit-common.c + ------------------------------------------------- + The driver is non-standard ad-hoc HW watchdog. Conversion is possible + but functions has to be renamed and constants moved to another places. + + + 6) arch/arm/cpu/armv7/omap3/board.c + ----------------------------------- + The driver is non-standard ad-hoc HW watchdog. Conversion is possible + but functions has to be renamed and constants moved to another places. + + + 7) arch/blackfin/cpu/watchdog.c + ------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 8) arch/m68k/cpu/mcf523x/cpu.c + ------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 9) arch/m68k/cpu/mcf52x2/cpu.c + ------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 10) arch/m68k/cpu/mcf532x/cpu.c + ------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 11) arch/m68k/cpu/mcf547x_8x/cpu.c + ---------------------------------- + The driver is standard HW watchdog (there is slight naming convention + violation that has to be rectified). Simple conversion is possible. + + + 12) arch/powerpc/cpu/74xx_7xx/cpu.c + ----------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 13) arch/powerpc/cpu/mpc512x/cpu.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 14) arch/powerpc/cpu/mpc5xx/cpu.c + --------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 15) arch/powerpc/cpu/mpc5xxx/cpu.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 16) arch/powerpc/cpu/mpc8260/cpu.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 17) arch/powerpc/cpu/mpc83xx/cpu.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 18) arch/powerpc/cpu/mpc85xx/cpu.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 19) arch/powerpc/cpu/mpc86xx/cpu.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 20) arch/powerpc/cpu/mpc8xx/cpu.c + + The driver is standard HW watchdog. Simple conversion is possible. + + + 21) arch/powerpc/cpu/ppc4xx/cpu.c + --------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 22) arch/sh/cpu/sh2/watchdog.c + ------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 23) arch/sh/cpu/sh3/watchdog.c + ------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 24) arch/sh/cpu/sh4/watchdog.c + ------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 25) board/amcc/luan/luan.c + -------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 26) board/amcc/yosemite/yosemite.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 27) board/apollon/apollon.c + --------------------------- + The driver is standard HW watchdog however the watchdog_init() + function is called in early initialization. Simple conversion is possible. + + + 28) board/bmw/m48t59y.c + ----------------------- + Special watchdog driver. Dead code. To be removed. + + + 29) board/davedenx/qong/qong.c + ------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 30) board/dvlhost/watchdog.c + ---------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 31) board/eNET/eNET.c + --------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 32) board/eltec/elppc/elppc.c + ----------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 33) board/enbw/enbw_cmc/enbw_cmc.c + ---------------------------------- + Only function proxy call. Code cleanup needed. + + + 34) board/freescale/mx31pdk/mx31pdk.c + ------------------------------------- + Only function proxy call. Code cleanup needed. + + + 35) board/gth2/gth2.c + --------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 36) board/lwmon5/lwmon5.c + ------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 37) board/manroland/mucmc52/mucmc52.c + ------------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 38) board/manroland/uc101/uc101.c + --------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 39) board/mousse/m48t59y.c + -------------------------- + Special watchdog driver. Dead code. To be removed. + + + 40) board/mvblue/mvblue.c + ------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 41) board/netphone/netphone.c + ----------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 42) board/netta/netta.c + ----------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 43) board/netta2/netta2.c + ------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 44) board/omicron/calimain/calimain.c + ------------------------------------- + Only function proxy call. Code cleanup needed. + + + 45) board/pcippc2/pcippc2.c + --------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 46) board/pcs440ep/pcs440ep.c + ----------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 47) board/stx/stxxtc/stxxtc.c + ----------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 48) board/ti/omap2420h4/omap2420h4.c + ------------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 49) board/ttcontrol/vision2/vision2.c + ------------------------------------- + The driver is standard HW watchdog but namespace is polluted by + non-standard macros. Simple conversion is possible, code cleanup + needed. + + + 50) board/v38b/v38b.c + --------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 51) board/ve8313/ve8313.c + ------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 52) board/w7o/watchdog.c + ------------------------ + The driver is standard HW watchdog. Simple conversion is possible. diff --git a/drivers/block/ata_piix.c b/drivers/block/ata_piix.c index c81d11a..1c3ab8a 100644 --- a/drivers/block/ata_piix.c +++ b/drivers/block/ata_piix.c @@ -204,9 +204,6 @@ init_sata (int dev) dev_print (&sata_dev_desc[devno]); /* initialize partition type */ init_part (&sata_dev_desc[devno]); - if (sata_curr_device < 0) - sata_curr_device = - i * CONFIG_SYS_SATA_DEVS_PER_BUS + j; } } } diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c index 58402b9..247cf06 100644 --- a/drivers/block/systemace.c +++ b/drivers/block/systemace.c @@ -51,24 +51,36 @@ * to be the base address for the chip, usually in the local * peripheral bus. */ -#if (CONFIG_SYS_SYSTEMACE_WIDTH == 8) + +static u32 base = CONFIG_SYS_SYSTEMACE_BASE; +static u32 width = CONFIG_SYS_SYSTEMACE_WIDTH; + +static void ace_writew(u16 val, unsigned off) +{ + if (width == 8) { #if !defined(__BIG_ENDIAN) -#define ace_readw(off) ((readb(CONFIG_SYS_SYSTEMACE_BASE+off)<<8) | \ - (readb(CONFIG_SYS_SYSTEMACE_BASE+off+1))) -#define ace_writew(val, off) {writeb(val>>8, CONFIG_SYS_SYSTEMACE_BASE+off); \ - writeb(val, CONFIG_SYS_SYSTEMACE_BASE+off+1);} + writeb(val >> 8, base + off); + writeb(val, base + off + 1); #else -#define ace_readw(off) ((readb(CONFIG_SYS_SYSTEMACE_BASE+off)) | \ - (readb(CONFIG_SYS_SYSTEMACE_BASE+off+1)<<8)) -#define ace_writew(val, off) {writeb(val, CONFIG_SYS_SYSTEMACE_BASE+off); \ - writeb(val>>8, CONFIG_SYS_SYSTEMACE_BASE+off+1);} + writeb(val, base + off); + writeb(val >> 8, base + off + 1); #endif + } + out16(base + off, val); +} + +static u16 ace_readw(unsigned off) +{ + if (width == 8) { +#if !defined(__BIG_ENDIAN) + return (readb(base + off) << 8) | readb(base + off + 1); #else -#define ace_readw(off) (in16(CONFIG_SYS_SYSTEMACE_BASE+off)) -#define ace_writew(val, off) (out16(CONFIG_SYS_SYSTEMACE_BASE+off,val)) + return readb(base + off) | (readb(base + off + 1) << 8); #endif + } -/* */ + return in16(base + off); +} static unsigned long systemace_read(int dev, unsigned long start, unsigned long blkcnt, void *buffer); @@ -121,7 +133,7 @@ block_dev_desc_t *systemace_get_dev(int dev) /* * Ensure the correct bus mode (8/16 bits) gets enabled */ - ace_writew(CONFIG_SYS_SYSTEMACE_WIDTH == 8 ? 0 : 0x0001, 0); + ace_writew(width == 8 ? 0 : 0x0001, 0); init_part(&systemace_dev); diff --git a/board/apollon/Makefile b/drivers/dfu/Makefile index 1bf1a32..7b717bc 100644 --- a/board/apollon/Makefile +++ b/drivers/dfu/Makefile @@ -1,6 +1,6 @@ # -# (C) Copyright 2000, 2001, 2002 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# Copyright (C) 2012 Samsung Electronics +# Lukasz Majewski <l.majewski@samsung.com> # # See file CREDITS for list of people who contributed to this # project. @@ -23,21 +23,22 @@ include $(TOPDIR)/config.mk -LIB = $(obj)lib$(BOARD).o +LIB = $(obj)libdfu.o -COBJS-y := apollon.o mem.o sys_info.o -SOBJS := lowlevel_init.o +COBJS-$(CONFIG_DFU_FUNCTION) += dfu.o +COBJS-$(CONFIG_DFU_MMC) += dfu_mmc.o -COBJS := $(COBJS-y) -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -SOBJS := $(addprefix $(obj),$(SOBJS)) +SRCS := $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) -$(LIB): $(obj).depend $(OBJS) $(SOBJS) - $(call cmd_link_o_target, $(OBJS) $(SOBJS)) +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) ######################################################################### +# defines $(obj).depend target include $(SRCTREE)/rules.mk sinclude $(obj).depend + +######################################################################### diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c new file mode 100644 index 0000000..e8477fb --- /dev/null +++ b/drivers/dfu/dfu.c @@ -0,0 +1,238 @@ +/* + * dfu.c -- DFU back-end routines + * + * Copyright (C) 2012 Samsung Electronics + * author: Lukasz Majewski <l.majewski@samsung.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <common.h> +#include <malloc.h> +#include <mmc.h> +#include <fat.h> +#include <dfu.h> +#include <linux/list.h> +#include <linux/compiler.h> + +static LIST_HEAD(dfu_list); +static int dfu_alt_num; + +static int dfu_find_alt_num(const char *s) +{ + int i = 0; + + for (; *s; s++) + if (*s == ';') + i++; + + return ++i; +} + +static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE) + dfu_buf[DFU_DATA_BUF_SIZE]; + +int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) +{ + static unsigned char *i_buf; + static int i_blk_seq_num; + long w_size = 0; + int ret = 0; + + debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x i_buf: 0x%p\n", + __func__, dfu->name, buf, size, blk_seq_num, i_buf); + + if (blk_seq_num == 0) { + i_buf = dfu_buf; + i_blk_seq_num = 0; + } + + if (i_blk_seq_num++ != blk_seq_num) { + printf("%s: Wrong sequence number! [%d] [%d]\n", + __func__, i_blk_seq_num, blk_seq_num); + return -1; + } + + memcpy(i_buf, buf, size); + i_buf += size; + + if (size == 0) { + /* Integrity check (if needed) */ + debug("%s: %s %d [B] CRC32: 0x%x\n", __func__, dfu->name, + i_buf - dfu_buf, crc32(0, dfu_buf, i_buf - dfu_buf)); + + w_size = i_buf - dfu_buf; + ret = dfu->write_medium(dfu, dfu_buf, &w_size); + if (ret) + debug("%s: Write error!\n", __func__); + + i_blk_seq_num = 0; + i_buf = NULL; + return ret; + } + + return ret; +} + +int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) +{ + static unsigned char *i_buf; + static int i_blk_seq_num; + static long r_size; + static u32 crc; + int ret = 0; + + debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x i_buf: 0x%p\n", + __func__, dfu->name, buf, size, blk_seq_num, i_buf); + + if (blk_seq_num == 0) { + i_buf = dfu_buf; + ret = dfu->read_medium(dfu, i_buf, &r_size); + debug("%s: %s %ld [B]\n", __func__, dfu->name, r_size); + i_blk_seq_num = 0; + /* Integrity check (if needed) */ + crc = crc32(0, dfu_buf, r_size); + } + + if (i_blk_seq_num++ != blk_seq_num) { + printf("%s: Wrong sequence number! [%d] [%d]\n", + __func__, i_blk_seq_num, blk_seq_num); + return -1; + } + + if (r_size >= size) { + memcpy(buf, i_buf, size); + i_buf += size; + r_size -= size; + return size; + } else { + memcpy(buf, i_buf, r_size); + i_buf += r_size; + debug("%s: %s CRC32: 0x%x\n", __func__, dfu->name, crc); + puts("UPLOAD ... done\nCtrl+C to exit ...\n"); + + i_buf = NULL; + i_blk_seq_num = 0; + crc = 0; + return r_size; + } + return ret; +} + +static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt, + char *interface, int num) +{ + char *st; + + debug("%s: %s interface: %s num: %d\n", __func__, s, interface, num); + st = strsep(&s, " "); + strcpy(dfu->name, st); + + dfu->dev_num = num; + dfu->alt = alt; + + /* Specific for mmc device */ + if (strcmp(interface, "mmc") == 0) { + if (dfu_fill_entity_mmc(dfu, s)) + return -1; + } else { + printf("%s: Device %s not (yet) supported!\n", + __func__, interface); + return -1; + } + + return 0; +} + +void dfu_free_entities(void) +{ + struct dfu_entity *dfu, *p, *t = NULL; + + list_for_each_entry_safe_reverse(dfu, p, &dfu_list, list) { + list_del(&dfu->list); + t = dfu; + } + if (t) + free(t); + INIT_LIST_HEAD(&dfu_list); +} + +int dfu_config_entities(char *env, char *interface, int num) +{ + struct dfu_entity *dfu; + int i, ret; + char *s; + + dfu_alt_num = dfu_find_alt_num(env); + debug("%s: dfu_alt_num=%d\n", __func__, dfu_alt_num); + + dfu = calloc(sizeof(*dfu), dfu_alt_num); + if (!dfu) + return -1; + for (i = 0; i < dfu_alt_num; i++) { + + s = strsep(&env, ";"); + ret = dfu_fill_entity(&dfu[i], s, i, interface, num); + if (ret) + return -1; + + list_add_tail(&dfu[i].list, &dfu_list); + } + + return 0; +} + +const char *dfu_get_dev_type(enum dfu_device_type t) +{ + const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND" }; + return dev_t[t]; +} + +const char *dfu_get_layout(enum dfu_layout l) +{ + const char *dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2", + "EXT3", "EXT4" }; + return dfu_layout[l]; +} + +void dfu_show_entities(void) +{ + struct dfu_entity *dfu; + + puts("DFU alt settings list:\n"); + + list_for_each_entry(dfu, &dfu_list, list) { + printf("dev: %s alt: %d name: %s layout: %s\n", + dfu_get_dev_type(dfu->dev_type), dfu->alt, + dfu->name, dfu_get_layout(dfu->layout)); + } +} + +int dfu_get_alt_number(void) +{ + return dfu_alt_num; +} + +struct dfu_entity *dfu_get_entity(int alt) +{ + struct dfu_entity *dfu; + + list_for_each_entry(dfu, &dfu_list, list) { + if (dfu->alt == alt) + return dfu; + } + + return NULL; +} diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c new file mode 100644 index 0000000..5d504df --- /dev/null +++ b/drivers/dfu/dfu_mmc.c @@ -0,0 +1,182 @@ +/* + * dfu.c -- DFU back-end routines + * + * Copyright (C) 2012 Samsung Electronics + * author: Lukasz Majewski <l.majewski@samsung.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <common.h> +#include <malloc.h> +#include <dfu.h> + +enum dfu_mmc_op { + DFU_OP_READ = 1, + DFU_OP_WRITE, +}; + +static int mmc_block_op(enum dfu_mmc_op op, struct dfu_entity *dfu, + void *buf, long *len) +{ + char cmd_buf[DFU_CMD_BUF_SIZE]; + + sprintf(cmd_buf, "mmc %s 0x%x %x %x", + op == DFU_OP_READ ? "read" : "write", + (unsigned int) buf, + dfu->data.mmc.lba_start, + dfu->data.mmc.lba_size); + + if (op == DFU_OP_READ) + *len = dfu->data.mmc.lba_blk_size * dfu->data.mmc.lba_size; + + debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); + return run_command(cmd_buf, 0); +} + +static inline int mmc_block_write(struct dfu_entity *dfu, void *buf, long *len) +{ + return mmc_block_op(DFU_OP_WRITE, dfu, buf, len); +} + +static inline int mmc_block_read(struct dfu_entity *dfu, void *buf, long *len) +{ + return mmc_block_op(DFU_OP_READ, dfu, buf, len); +} + +static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu, + void *buf, long *len) +{ + char cmd_buf[DFU_CMD_BUF_SIZE]; + char *str_env; + int ret; + + switch (dfu->layout) { + case DFU_FS_FAT: + sprintf(cmd_buf, "fat%s mmc %d:%d 0x%x %s %lx", + op == DFU_OP_READ ? "load" : "write", + dfu->data.mmc.dev, dfu->data.mmc.part, + (unsigned int) buf, dfu->name, *len); + break; + case DFU_FS_EXT4: + sprintf(cmd_buf, "ext4%s mmc %d:%d /%s 0x%x %ld", + op == DFU_OP_READ ? "load" : "write", + dfu->data.mmc.dev, dfu->data.mmc.part, + dfu->name, (unsigned int) buf, *len); + break; + default: + printf("%s: Layout (%s) not (yet) supported!\n", __func__, + dfu_get_layout(dfu->layout)); + } + + debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); + + ret = run_command(cmd_buf, 0); + if (ret) { + puts("dfu: Read error!\n"); + return ret; + } + + if (dfu->layout != DFU_RAW_ADDR && op == DFU_OP_READ) { + str_env = getenv("filesize"); + if (str_env == NULL) { + puts("dfu: Wrong file size!\n"); + return -1; + } + *len = simple_strtoul(str_env, NULL, 16); + } + + return ret; +} + +static inline int mmc_file_write(struct dfu_entity *dfu, void *buf, long *len) +{ + return mmc_file_op(DFU_OP_WRITE, dfu, buf, len); +} + +static inline int mmc_file_read(struct dfu_entity *dfu, void *buf, long *len) +{ + return mmc_file_op(DFU_OP_READ, dfu, buf, len); +} + +int dfu_write_medium_mmc(struct dfu_entity *dfu, void *buf, long *len) +{ + int ret = -1; + + switch (dfu->layout) { + case DFU_RAW_ADDR: + ret = mmc_block_write(dfu, buf, len); + break; + case DFU_FS_FAT: + case DFU_FS_EXT4: + ret = mmc_file_write(dfu, buf, len); + break; + default: + printf("%s: Layout (%s) not (yet) supported!\n", __func__, + dfu_get_layout(dfu->layout)); + } + + return ret; +} + +int dfu_read_medium_mmc(struct dfu_entity *dfu, void *buf, long *len) +{ + int ret = -1; + + switch (dfu->layout) { + case DFU_RAW_ADDR: + ret = mmc_block_read(dfu, buf, len); + break; + case DFU_FS_FAT: + case DFU_FS_EXT4: + ret = mmc_file_read(dfu, buf, len); + break; + default: + printf("%s: Layout (%s) not (yet) supported!\n", __func__, + dfu_get_layout(dfu->layout)); + } + + return ret; +} + +int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s) +{ + char *st; + + dfu->dev_type = DFU_DEV_MMC; + st = strsep(&s, " "); + if (!strcmp(st, "mmc")) { + dfu->layout = DFU_RAW_ADDR; + dfu->data.mmc.lba_start = simple_strtoul(s, &s, 16); + dfu->data.mmc.lba_size = simple_strtoul(++s, &s, 16); + dfu->data.mmc.lba_blk_size = get_mmc_blk_size(dfu->dev_num); + } else if (!strcmp(st, "fat")) { + dfu->layout = DFU_FS_FAT; + } else if (!strcmp(st, "ext4")) { + dfu->layout = DFU_FS_EXT4; + } else { + printf("%s: Memory layout (%s) not supported!\n", __func__, st); + } + + if (dfu->layout == DFU_FS_EXT4 || dfu->layout == DFU_FS_FAT) { + dfu->data.mmc.dev = simple_strtoul(s, &s, 10); + dfu->data.mmc.part = simple_strtoul(++s, &s, 10); + } + + dfu->read_medium = dfu_read_medium_mmc; + dfu->write_medium = dfu_write_medium_mmc; + + return 0; +} diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c index 978507b..094305f 100644 --- a/drivers/i2c/omap24xx_i2c.c +++ b/drivers/i2c/omap24xx_i2c.c @@ -442,6 +442,14 @@ int i2c_set_bus_num(unsigned int bus) return -1; } +#if I2C_BUS_MAX == 4 + if (bus == 3) + i2c_base = (struct i2c *)I2C_BASE4; + else + if (bus == 2) + i2c_base = (struct i2c *)I2C_BASE3; + else +#endif #if I2C_BUS_MAX == 3 if (bus == 2) i2c_base = (struct i2c *)I2C_BASE3; diff --git a/drivers/input/key_matrix.c b/drivers/input/key_matrix.c index 84b898f..715e57a 100644 --- a/drivers/input/key_matrix.c +++ b/drivers/input/key_matrix.c @@ -23,6 +23,7 @@ * MA 02111-1307 USA */ +#include <common.h> #include <fdtdec.h> #include <key_matrix.h> #include <malloc.h> diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c index a7d04b7..223cd5d 100644 --- a/drivers/misc/fsl_law.c +++ b/drivers/misc/fsl_law.c @@ -275,5 +275,59 @@ void init_laws(void) law_table[i].size, law_table[i].trgt_id); } +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE + /* check RCW to get which port is used for boot */ + ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + u32 bootloc = in_be32(&gur->rcwsr[6]); + /* + * in SRIO or PCIE boot we need to set specail LAWs for + * SRIO or PCIE interfaces. + */ + switch ((bootloc & FSL_CORENET_RCWSR6_BOOT_LOC) >> 23) { + case 0x0: /* boot from PCIE1 */ + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_PCIE_1); + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_PCIE_1); + break; + case 0x1: /* boot from PCIE2 */ + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_PCIE_2); + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_PCIE_2); + break; + case 0x2: /* boot from PCIE3 */ + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_PCIE_3); + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_PCIE_3); + break; + case 0x8: /* boot from SRIO1 */ + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_RIO_1); + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_RIO_1); + break; + case 0x9: /* boot from SRIO2 */ + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_RIO_2); + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_RIO_2); + break; + default: + break; + } +#endif + return ; } diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 2b96cdc..565ba6a 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -25,8 +25,8 @@ include $(TOPDIR)/config.mk LIB := $(obj)libmmc.o -ifdef CONFIG_SPL_MMC_LOAD -COBJS-$(CONFIG_SPL_MMC_LOAD) += spl_mmc_load.o +ifdef CONFIG_SPL_BUILD +COBJS-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o endif COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index db2c7ab..af1380a 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -52,7 +52,7 @@ static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd) debug("CMD%d time out\n", cmd->cmdidx); return TIMEOUT; } else if ((hoststatus & SDI_STA_CCRCFAIL) && - (cmd->flags & MMC_RSP_CRC)) { + (cmd->resp_type & MMC_RSP_CRC)) { printf("CMD%d CRC error\n", cmd->cmdidx); return -EILSEQ; } diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 551d6a9..a60cfe1 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -151,7 +151,6 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) printf("CMD_SEND:%d\n", cmd->cmdidx); printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg); - printf("\t\tFLAG\t\t\t %d\n", cmd->flags); ret = mmc->send_cmd(mmc, cmd, data); switch (cmd->resp_type) { case MMC_RSP_NONE: @@ -213,7 +212,6 @@ int mmc_send_status(struct mmc *mmc, int timeout) cmd.resp_type = MMC_RSP_R1; if (!mmc_host_is_spi(mmc)) cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; do { err = mmc_send_cmd(mmc, &cmd, NULL); @@ -238,7 +236,7 @@ int mmc_send_status(struct mmc *mmc, int timeout) status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9; printf("CURR STATE:%d\n", status); #endif - if (!timeout) { + if (timeout <= 0) { printf("Timeout waiting card ready\n"); return TIMEOUT; } @@ -253,7 +251,6 @@ int mmc_set_blocklen(struct mmc *mmc, int len) cmd.cmdidx = MMC_CMD_SET_BLOCKLEN; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = len; - cmd.flags = 0; return mmc_send_cmd(mmc, &cmd, NULL); } @@ -299,7 +296,6 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) cmd.cmdidx = start_cmd; cmd.cmdarg = start; cmd.resp_type = MMC_RSP_R1; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -386,7 +382,6 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src) cmd.cmdarg = start * mmc->write_bl_len; cmd.resp_type = MMC_RSP_R1; - cmd.flags = 0; data.src = src; data.blocks = blkcnt; @@ -405,7 +400,6 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src) cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; cmd.cmdarg = 0; cmd.resp_type = MMC_RSP_R1b; - cmd.flags = 0; if (mmc_send_cmd(mmc, &cmd, NULL)) { printf("mmc fail to send stop cmd\n"); return 0; @@ -459,7 +453,6 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt) cmd.cmdarg = start * mmc->read_bl_len; cmd.resp_type = MMC_RSP_R1; - cmd.flags = 0; data.dest = dst; data.blocks = blkcnt; @@ -473,7 +466,6 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt) cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; cmd.cmdarg = 0; cmd.resp_type = MMC_RSP_R1b; - cmd.flags = 0; if (mmc_send_cmd(mmc, &cmd, NULL)) { printf("mmc fail to send stop cmd\n"); return 0; @@ -525,7 +517,6 @@ int mmc_go_idle(struct mmc* mmc) cmd.cmdidx = MMC_CMD_GO_IDLE_STATE; cmd.cmdarg = 0; cmd.resp_type = MMC_RSP_NONE; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -548,7 +539,6 @@ sd_send_op_cond(struct mmc *mmc) cmd.cmdidx = MMC_CMD_APP_CMD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -589,7 +579,6 @@ sd_send_op_cond(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SPI_READ_OCR; cmd.resp_type = MMC_RSP_R3; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -618,7 +607,6 @@ int mmc_send_op_cond(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SEND_OP_COND; cmd.resp_type = MMC_RSP_R3; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -638,8 +626,6 @@ int mmc_send_op_cond(struct mmc *mmc) if (mmc->host_caps & MMC_MODE_HC) cmd.cmdarg |= OCR_HCS; - cmd.flags = 0; - err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -655,7 +641,6 @@ int mmc_send_op_cond(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SPI_READ_OCR; cmd.resp_type = MMC_RSP_R3; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -673,7 +658,7 @@ int mmc_send_op_cond(struct mmc *mmc) } -int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd) +int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd) { struct mmc_cmd cmd; struct mmc_data data; @@ -683,9 +668,8 @@ int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd) cmd.cmdidx = MMC_CMD_SEND_EXT_CSD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 0; - cmd.flags = 0; - data.dest = ext_csd; + data.dest = (char *)ext_csd; data.blocks = 1; data.blocksize = 512; data.flags = MMC_DATA_READ; @@ -707,7 +691,6 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | (index << 16) | (value << 8); - cmd.flags = 0; ret = mmc_send_cmd(mmc, &cmd, NULL); @@ -721,7 +704,7 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) int mmc_change_freq(struct mmc *mmc) { - ALLOC_CACHE_ALIGN_BUFFER(char, ext_csd, 512); + ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); char cardtype; int err; @@ -800,7 +783,6 @@ int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp) cmd.cmdarg = (mode << 31) | 0xffffff; cmd.cmdarg &= ~(0xf << (group * 4)); cmd.cmdarg |= value << (group * 4); - cmd.flags = 0; data.dest = (char *)resp; data.blocksize = 64; @@ -829,7 +811,6 @@ int sd_change_freq(struct mmc *mmc) cmd.cmdidx = MMC_CMD_APP_CMD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -839,7 +820,6 @@ int sd_change_freq(struct mmc *mmc) cmd.cmdidx = SD_CMD_APP_SEND_SCR; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 0; - cmd.flags = 0; timeout = 3; @@ -983,8 +963,8 @@ int mmc_startup(struct mmc *mmc) uint mult, freq; u64 cmult, csize, capacity; struct mmc_cmd cmd; - ALLOC_CACHE_ALIGN_BUFFER(char, ext_csd, 512); - ALLOC_CACHE_ALIGN_BUFFER(char, test_csd, 512); + ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); + ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, 512); int timeout = 1000; #ifdef CONFIG_MMC_SPI_CRC_ON @@ -992,7 +972,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 1; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -1005,7 +984,6 @@ int mmc_startup(struct mmc *mmc) MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */ cmd.resp_type = MMC_RSP_R2; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -1023,7 +1001,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR; cmd.cmdarg = mmc->rca << 16; cmd.resp_type = MMC_RSP_R6; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -1038,7 +1015,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SEND_CSD; cmd.resp_type = MMC_RSP_R2; cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -1115,7 +1091,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SELECT_CARD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -1183,7 +1158,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = MMC_CMD_APP_CMD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -1192,7 +1166,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 2; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) return err; @@ -1260,7 +1233,9 @@ int mmc_startup(struct mmc *mmc) (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff); sprintf(mmc->block_dev.revision, "%d.%d", mmc->cid[2] >> 28, (mmc->cid[2] >> 24) & 0xf); +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT) init_part(&mmc->block_dev); +#endif return 0; } @@ -1274,7 +1249,6 @@ int mmc_send_if_cond(struct mmc *mmc) /* We set the bit if the host supports voltages between 2.7 and 3.6 V */ cmd.cmdarg = ((mmc->voltages & 0xff8000) != 0) << 8 | 0xaa; cmd.resp_type = MMC_RSP_R7; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -1312,10 +1286,9 @@ int mmc_register(struct mmc *mmc) block_dev_desc_t *mmc_get_dev(int dev) { struct mmc *mmc = find_mmc_device(dev); - if (!mmc) + if (!mmc || mmc_init(mmc)) return NULL; - mmc_init(mmc); return &mmc->block_dev; } #endif diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c index 2c5bf17..b3ec441 100644 --- a/drivers/mmc/pxa_mmc_gen.c +++ b/drivers/mmc/pxa_mmc_gen.c @@ -118,7 +118,7 @@ static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd, int ret; /* The card can send a "busy" response */ - if (cmd->flags & MMC_RSP_BUSY) + if (cmd->resp_type & MMC_RSP_BUSY) cmdat |= MMC_CMDAT_BUSY; /* Inform the controller about response type */ @@ -181,9 +181,11 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) /* The command response didn't arrive */ if (stat & MMC_STAT_TIME_OUT_RESPONSE) return -ETIMEDOUT; - else if (stat & MMC_STAT_RES_CRC_ERROR && cmd->flags & MMC_RSP_CRC) { + else if (stat & MMC_STAT_RES_CRC_ERROR + && cmd->resp_type & MMC_RSP_CRC) { #ifdef PXAMMC_CRC_SKIP - if (cmd->flags & MMC_RSP_136 && cmd->response[0] & (1 << 31)) + if (cmd->resp_type & MMC_RSP_136 + && cmd->response[0] & (1 << 31)) printf("Ignoring CRC, this may be dangerous!\n"); else #endif diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 1d4481b..b978236 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -21,6 +21,7 @@ #include <malloc.h> #include <sdhci.h> #include <asm/arch/mmc.h> +#include <asm/arch/clk.h> static char *S5P_NAME = "SAMSUNG SDHCI"; static void s5p_sdhci_set_control_reg(struct sdhci_host *host) @@ -54,7 +55,7 @@ static void s5p_sdhci_set_control_reg(struct sdhci_host *host) * 00 = Delay3 (inverter delay) * 10 = Delay4 (inverter delay + 2ns) */ - val = SDHCI_CTRL3_FCSEL3 | SDHCI_CTRL3_FCSEL1; + val = SDHCI_CTRL3_FCSEL0 | SDHCI_CTRL3_FCSEL1; sdhci_writel(host, val, SDHCI_CONTROL3); /* @@ -69,7 +70,7 @@ static void s5p_sdhci_set_control_reg(struct sdhci_host *host) sdhci_writel(host, ctrl, SDHCI_CONTROL2); } -int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks) +int s5p_sdhci_init(u32 regbase, int index, int bus_width) { struct sdhci_host *host = NULL; host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host)); @@ -80,19 +81,18 @@ int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks) host->name = S5P_NAME; host->ioaddr = (void *)regbase; - host->quirks = quirks; - host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE; + host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE | + SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR; host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - if (quirks & SDHCI_QUIRK_REG32_RW) - host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16; - else - host->version = sdhci_readw(host, SDHCI_HOST_VERSION); + host->version = sdhci_readw(host, SDHCI_HOST_VERSION); host->set_control_reg = &s5p_sdhci_set_control_reg; + host->set_clock = set_mmc_clk; + host->index = index; host->host_caps = MMC_MODE_HC; - add_sdhci(host, max_clk, min_clk); + add_sdhci(host, 52000000, 400000); return 0; } diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 1709643..2e3c408 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -260,7 +260,7 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) if (clock == 0) return 0; - if (host->version >= SDHCI_SPEC_300) { + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) { /* Version 3.00 divisors must be a multiple of 2. */ if (mmc->f_max <= clock) div = 1; @@ -279,6 +279,9 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) } div >>= 1; + if (host->set_clock) + host->set_clock(host->index, div); + clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) << SDHCI_DIVIDER_HI_SHIFT; @@ -347,10 +350,10 @@ void sdhci_set_ios(struct mmc *mmc) ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); if (mmc->bus_width == 8) { ctrl &= ~SDHCI_CTRL_4BITBUS; - if (host->version >= SDHCI_SPEC_300) + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) ctrl |= SDHCI_CTRL_8BITBUS; } else { - if (host->version >= SDHCI_SPEC_300) + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) ctrl &= ~SDHCI_CTRL_8BITBUS; if (mmc->bus_width == 4) ctrl |= SDHCI_CTRL_4BITBUS; @@ -381,12 +384,25 @@ int sdhci_init(struct mmc *mmc) } } + sdhci_set_power(host, fls(mmc->voltages) - 1); + + if (host->quirks & SDHCI_QUIRK_NO_CD) { + unsigned int status; + + sdhci_writel(host, SDHCI_CTRL_CD_TEST_INS | SDHCI_CTRL_CD_TEST, + SDHCI_HOST_CONTROL); + + status = sdhci_readl(host, SDHCI_PRESENT_STATE); + while ((!(status & SDHCI_CARD_PRESENT)) || + (!(status & SDHCI_CARD_STATE_STABLE)) || + (!(status & SDHCI_CARD_DETECT_PIN_LEVEL))) + status = sdhci_readl(host, SDHCI_PRESENT_STATE); + } + /* Eable all state */ sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_ENABLE); sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_SIGNAL_ENABLE); - sdhci_set_power(host, fls(mmc->voltages) - 1); - return 0; } @@ -421,7 +437,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) if (max_clk) mmc->f_max = max_clk; else { - if (host->version >= SDHCI_SPEC_300) + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) mmc->f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; else @@ -436,7 +452,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) if (min_clk) mmc->f_min = min_clk; else { - if (host->version >= SDHCI_SPEC_300) + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_300; else mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_200; diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 2835e24..4588568 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -593,7 +593,7 @@ int mmcif_mmc_init(void) mmc->f_max = CLKDEV_EMMC_DATA; mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT | - MMC_MODE_8BIT; + MMC_MODE_8BIT | MMC_MODE_HC; memcpy(mmc->name, DRIVER_NAME, sizeof(DRIVER_NAME)); mmc->send_cmd = sh_mmcif_request; mmc->set_ios = sh_mmcif_set_ios; diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/drivers/mmc/spl_mmc.c index 2f921bb..753c6a0 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_mmc.c +++ b/drivers/mmc/spl_mmc.c @@ -23,33 +23,15 @@ * MA 02111-1307 USA */ #include <common.h> +#include <spl.h> #include <asm/u-boot.h> #include <asm/utils.h> -#include <asm/arch/sys_proto.h> #include <mmc.h> #include <fat.h> #include <version.h> -#include <asm/omap_common.h> -#include <asm/arch/mmc_host_def.h> DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_GENERIC_MMC -int board_mmc_init(bd_t *bis) -{ - switch (omap_boot_device()) { - case BOOT_DEVICE_MMC1: - omap_mmc_init(0, 0, 0); - break; - case BOOT_DEVICE_MMC2: - case BOOT_DEVICE_MMC2_2: - omap_mmc_init(1, 0, 0); - break; - } - return 0; -} -#endif - static void mmc_load_image_raw(struct mmc *mmc) { u32 image_size_sectors, err; @@ -69,8 +51,8 @@ static void mmc_load_image_raw(struct mmc *mmc) spl_parse_image_header(header); /* convert size to sectors - round up */ - image_size_sectors = (spl_image.size + MMCSD_SECTOR_SIZE - 1) / - MMCSD_SECTOR_SIZE; + image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / + mmc->read_bl_len; /* Read the header too to avoid extra memcpy */ err = mmc->block_dev.block_read(0, @@ -84,6 +66,7 @@ end: } } +#ifdef CONFIG_SPL_FAT_SUPPORT static void mmc_load_image_fat(struct mmc *mmc) { s32 err; @@ -116,6 +99,7 @@ end: hang(); } } +#endif void spl_mmc_load_image(void) { @@ -136,13 +120,15 @@ void spl_mmc_load_image(void) printf("spl: mmc init failed: err - %d\n", err); hang(); } - boot_mode = omap_boot_mode(); + boot_mode = spl_boot_mode(); if (boot_mode == MMCSD_MODE_RAW) { debug("boot mode - RAW\n"); mmc_load_image_raw(mmc); +#ifdef CONFIG_SPL_FAT_SUPPORT } else if (boot_mode == MMCSD_MODE_FAT) { debug("boot mode - FAT\n"); mmc_load_image_fat(mmc); +#endif } else { puts("spl: wrong MMC boot mode\n"); hang(); diff --git a/drivers/mmc/spl_mmc_load.c b/drivers/mmc/spl_mmc_load.c deleted file mode 100644 index 79a68fb..0000000 --- a/drivers/mmc/spl_mmc_load.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.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. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <common.h> -#include <mmc.h> - -DECLARE_GLOBAL_DATA_PTR; - -static void mmc_load_image(struct mmc *mmc) -{ - s32 err; - void (*uboot)(void) __noreturn; - - err = mmc->block_dev.block_read(0, CONFIG_SYS_MMC_U_BOOT_OFFS, - CONFIG_SYS_MMC_U_BOOT_SIZE/512, - (u32 *)CONFIG_SYS_TEXT_BASE); - - if (err <= 0) { - printf("spl: error reading image %s, err - %d\n", - "u-boot.img", err); - hang(); - } - uboot = (void *) CONFIG_SYS_TEXT_BASE; - (*uboot)(); -} - -void spl_mmc_load(void) -{ - struct mmc *mmc; - int err; - void (mmc_load_image)(struct mmc *mmc) __noreturn; - - mmc_initialize(gd->bd); - mmc = find_mmc_device(0); - if (!mmc) { - puts("spl: mmc device not found!!\n"); - hang(); - } else { - puts("spl: mmc device found\n"); - } - err = mmc_init(mmc); - if (err) { - printf("spl: mmc init failed: err - %d\n", err); - hang(); - } - mmc_load_image(mmc); -} diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index f0f301a..43140f3 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -1077,7 +1077,38 @@ int flash_erase (flash_info_t * info, int s_first, int s_last) for (sect = s_first; sect <= s_last; sect++) { + if (ctrlc()) { + printf("\n"); + return 1; + } + if (info->protect[sect] == 0) { /* not protected */ +#ifdef CONFIG_SYS_FLASH_CHECK_BLANK_BEFORE_ERASE + int k; + int size; + int erased; + u32 *flash; + + /* + * Check if whole sector is erased + */ + size = flash_sector_size(info, sect); + erased = 1; + flash = (u32 *)info->start[sect]; + /* divide by 4 for longword access */ + size = size >> 2; + for (k = 0; k < size; k++) { + if (flash_read32(flash++) != 0xffffffff) { + erased = 0; + break; + } + } + if (erased) { + if (flash_verbose) + putc(','); + continue; + } +#endif switch (info->vendor) { case CFI_CMDSET_INTEL_PROG_REGIONS: case CFI_CMDSET_INTEL_STANDARD: @@ -1353,6 +1384,9 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) src += i; cnt -= i; FLASH_SHOW_PROGRESS(scale, dots, digit, i); + /* Only check every once in a while */ + if ((cnt & 0xFFFF) < buffered_size && ctrlc()) + return ERR_ABORTED; } #else while (cnt >= info->portwidth) { @@ -1365,6 +1399,9 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) wp += info->portwidth; cnt -= info->portwidth; FLASH_SHOW_PROGRESS(scale, dots, digit, info->portwidth); + /* Only check every once in a while */ + if ((cnt & 0xFFFF) < info->portwidth && ctrlc()) + return ERR_ABORTED; } #endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */ diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 936186f..d0ded48 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -25,168 +25,23 @@ #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35) #include <asm/arch/imx-regs.h> #endif +#include <fsl_nfc.h> #define DRIVER_NAME "mxc_nand" -/* - * TODO: Use same register defs here as nand_spl mxc nand driver. - */ -/* - * Register map and bit definitions for the Freescale NAND Flash Controller - * present in various i.MX devices. - * - * MX31 and MX27 have version 1 which has - * 4 512 byte main buffers and - * 4 16 byte spare buffers - * to support up to 2K byte pagesize nand. - * Reading or writing a 2K page requires 4 FDI/FDO cycles. - * - * MX25 has version 1.1 which has - * 8 512 byte main buffers and - * 8 64 byte spare buffers - * to support up to 4K byte pagesize nand. - * Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle. - * Also some of registers are moved and/or changed meaning as seen below. - */ -#if defined(CONFIG_MX31) || defined(CONFIG_MX27) -#define MXC_NFC_V1 -#elif defined(CONFIG_MX25) || defined(CONFIG_MX35) -#define MXC_NFC_V1_1 -#else -#warning "MXC NFC version not defined" -#endif - -#if defined(MXC_NFC_V1) -#define NAND_MXC_NR_BUFS 4 -#define NAND_MXC_SPARE_BUF_SIZE 16 -#define NAND_MXC_REG_OFFSET 0xe00 -#define is_mxc_nfc_11() 0 -#elif defined(MXC_NFC_V1_1) -#define NAND_MXC_NR_BUFS 8 -#define NAND_MXC_SPARE_BUF_SIZE 64 -#define NAND_MXC_REG_OFFSET 0x1e00 -#define is_mxc_nfc_11() 1 -#else -#error "define CONFIG_NAND_MXC_VXXX to use mtd mxc nand driver" -#endif -struct nfc_regs { - uint8_t main_area[NAND_MXC_NR_BUFS][0x200]; - uint8_t spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE]; - /* - * reserved size is offset of nfc registers - * minus total main and spare sizes - */ - uint8_t reserved1[NAND_MXC_REG_OFFSET - - NAND_MXC_NR_BUFS * (512 + NAND_MXC_SPARE_BUF_SIZE)]; -#if defined(MXC_NFC_V1) - uint16_t nfc_buf_size; - uint16_t reserved2; - uint16_t nfc_buf_addr; - uint16_t nfc_flash_addr; - uint16_t nfc_flash_cmd; - uint16_t nfc_config; - uint16_t nfc_ecc_status_result; - uint16_t nfc_rsltmain_area; - uint16_t nfc_rsltspare_area; - uint16_t nfc_wrprot; - uint16_t nfc_unlockstart_blkaddr; - uint16_t nfc_unlockend_blkaddr; - uint16_t nfc_nf_wrprst; - uint16_t nfc_config1; - uint16_t nfc_config2; -#elif defined(MXC_NFC_V1_1) - uint16_t reserved2[2]; - uint16_t nfc_buf_addr; - uint16_t nfc_flash_addr; - uint16_t nfc_flash_cmd; - uint16_t nfc_config; - uint16_t nfc_ecc_status_result; - uint16_t nfc_ecc_status_result2; - uint16_t nfc_spare_area_size; - uint16_t nfc_wrprot; - uint16_t reserved3[2]; - uint16_t nfc_nf_wrprst; - uint16_t nfc_config1; - uint16_t nfc_config2; - uint16_t reserved4; - uint16_t nfc_unlockstart_blkaddr; - uint16_t nfc_unlockend_blkaddr; - uint16_t nfc_unlockstart_blkaddr1; - uint16_t nfc_unlockend_blkaddr1; - uint16_t nfc_unlockstart_blkaddr2; - uint16_t nfc_unlockend_blkaddr2; - uint16_t nfc_unlockstart_blkaddr3; - uint16_t nfc_unlockend_blkaddr3; -#endif -}; - -/* - * Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register - * for Command operation - */ -#define NFC_CMD 0x1 - -/* - * Set INT to 0, FADD to 1, rest to 0 in NFC_CONFIG2 Register - * for Address operation - */ -#define NFC_ADDR 0x2 - -/* - * Set INT to 0, FDI to 1, rest to 0 in NFC_CONFIG2 Register - * for Input operation - */ -#define NFC_INPUT 0x4 - -/* - * Set INT to 0, FDO to 001, rest to 0 in NFC_CONFIG2 Register - * for Data Output operation - */ -#define NFC_OUTPUT 0x8 - -/* - * Set INT to 0, FD0 to 010, rest to 0 in NFC_CONFIG2 Register - * for Read ID operation - */ -#define NFC_ID 0x10 - -/* - * Set INT to 0, FDO to 100, rest to 0 in NFC_CONFIG2 Register - * for Read Status operation - */ -#define NFC_STATUS 0x20 - -/* - * Set INT to 1, rest to 0 in NFC_CONFIG2 Register for Read - * Status operation - */ -#define NFC_INT 0x8000 - -#ifdef MXC_NFC_V1_1 -#define NFC_4_8N_ECC (1 << 0) -#else -#define NFC_4_8N_ECC 0 -#endif -#define NFC_SP_EN (1 << 2) -#define NFC_ECC_EN (1 << 3) -#define NFC_BIG (1 << 5) -#define NFC_RST (1 << 6) -#define NFC_CE (1 << 7) -#define NFC_ONE_CYCLE (1 << 8) - typedef enum {false, true} bool; struct mxc_nand_host { - struct mtd_info mtd; - struct nand_chip *nand; - - struct nfc_regs __iomem *regs; - int spare_only; - int status_request; - int pagesize_2k; - int clk_act; - uint16_t col_addr; - unsigned int page_addr; + struct mtd_info mtd; + struct nand_chip *nand; + + struct fsl_nfc_regs __iomem *regs; + int spare_only; + int status_request; + int pagesize_2k; + int clk_act; + uint16_t col_addr; + unsigned int page_addr; }; static struct mxc_nand_host mxc_host; @@ -222,7 +77,7 @@ static struct nand_ecclayout nand_hw_eccoob2k = { .oobfree = { {2, 4}, {11, 11}, {27, 11}, {43, 11}, {59, 5} }, }; #endif -#elif defined(MXC_NFC_V1_1) +#elif defined(MXC_NFC_V2_1) #ifndef CONFIG_SYS_NAND_LARGEPAGE static struct nand_ecclayout nand_hw_eccoob = { .eccbytes = 9, @@ -268,8 +123,7 @@ static int is_16bit_nand(void) #elif defined(CONFIG_MX25) || defined(CONFIG_MX35) static int is_16bit_nand(void) { - struct ccm_regs *ccm = - (struct ccm_regs *)IMX_CCM_BASE; + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; if (readl(&ccm->rcsr) & CCM_RCSR_NF_16BIT_SEL) return 1; @@ -304,10 +158,10 @@ static void wait_op_done(struct mxc_nand_host *host, int max_retries, uint32_t tmp; while (max_retries-- > 0) { - if (readw(&host->regs->nfc_config2) & NFC_INT) { - tmp = readw(&host->regs->nfc_config2); + if (readw(&host->regs->config2) & NFC_INT) { + tmp = readw(&host->regs->config2); tmp &= ~NFC_INT; - writew(tmp, &host->regs->nfc_config2); + writew(tmp, &host->regs->config2); break; } udelay(1); @@ -326,8 +180,8 @@ static void send_cmd(struct mxc_nand_host *host, uint16_t cmd) { MTDDEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x)\n", cmd); - writew(cmd, &host->regs->nfc_flash_cmd); - writew(NFC_CMD, &host->regs->nfc_config2); + writew(cmd, &host->regs->flash_cmd); + writew(NFC_CMD, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, cmd); @@ -342,8 +196,8 @@ static void send_addr(struct mxc_nand_host *host, uint16_t addr) { MTDDEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x)\n", addr); - writew(addr, &host->regs->nfc_flash_addr); - writew(NFC_ADDR, &host->regs->nfc_config2); + writew(addr, &host->regs->flash_addr); + writew(NFC_ADDR, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, addr); @@ -359,7 +213,7 @@ static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, if (spare_only) MTDDEBUG(MTD_DEBUG_LEVEL1, "send_prog_page (%d)\n", spare_only); - if (is_mxc_nfc_11()) { + if (is_mxc_nfc_21()) { int i; /* * The controller copies the 64 bytes of spare data from @@ -375,19 +229,19 @@ static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, } } - writew(buf_id, &host->regs->nfc_buf_addr); + writew(buf_id, &host->regs->buf_addr); /* Configure spare or page+spare access */ if (!host->pagesize_2k) { - uint16_t config1 = readw(&host->regs->nfc_config1); + uint16_t config1 = readw(&host->regs->config1); if (spare_only) config1 |= NFC_SP_EN; else - config1 &= ~(NFC_SP_EN); - writew(config1, &host->regs->nfc_config1); + config1 &= ~NFC_SP_EN; + writew(config1, &host->regs->config1); } - writew(NFC_INPUT, &host->regs->nfc_config2); + writew(NFC_INPUT, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, spare_only); @@ -402,24 +256,24 @@ static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id, { MTDDEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only); - writew(buf_id, &host->regs->nfc_buf_addr); + writew(buf_id, &host->regs->buf_addr); /* Configure spare or page+spare access */ if (!host->pagesize_2k) { - uint32_t config1 = readw(&host->regs->nfc_config1); + uint32_t config1 = readw(&host->regs->config1); if (spare_only) config1 |= NFC_SP_EN; else config1 &= ~NFC_SP_EN; - writew(config1, &host->regs->nfc_config1); + writew(config1, &host->regs->config1); } - writew(NFC_OUTPUT, &host->regs->nfc_config2); + writew(NFC_OUTPUT, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, spare_only); - if (is_mxc_nfc_11()) { + if (is_mxc_nfc_21()) { int i; /* @@ -442,14 +296,14 @@ static void send_read_id(struct mxc_nand_host *host) uint16_t tmp; /* NANDFC buffer 0 is used for device ID output */ - writew(0x0, &host->regs->nfc_buf_addr); + writew(0x0, &host->regs->buf_addr); /* Read ID into main buffer */ - tmp = readw(&host->regs->nfc_config1); + tmp = readw(&host->regs->config1); tmp &= ~NFC_SP_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); - writew(NFC_ID, &host->regs->nfc_config2); + writew(NFC_ID, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, 0); @@ -469,14 +323,14 @@ static uint16_t get_dev_status(struct mxc_nand_host *host) /* store the main area1 first word, later do recovery */ store = readl(main_buf); /* NANDFC buffer 1 is used for device status */ - writew(1, &host->regs->nfc_buf_addr); + writew(1, &host->regs->buf_addr); /* Read status into main buffer */ - tmp = readw(&host->regs->nfc_config1); + tmp = readw(&host->regs->config1); tmp &= ~NFC_SP_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); - writew(NFC_STATUS, &host->regs->nfc_config2); + writew(NFC_STATUS, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, 0); @@ -501,29 +355,29 @@ static int mxc_nand_dev_ready(struct mtd_info *mtd) return 1; } -#ifdef CONFIG_MXC_NAND_HWECC -static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) -{ - /* - * If HW ECC is enabled, we turn it on during init. There is - * no need to enable again here. - */ -} - -#ifdef MXC_NFC_V1_1 static void _mxc_nand_enable_hwecc(struct mtd_info *mtd, int on) { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - uint16_t tmp = readw(&host->regs->nfc_config1); + uint16_t tmp = readw(&host->regs->config1); if (on) tmp |= NFC_ECC_EN; else tmp &= ~NFC_ECC_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); +} + +#ifdef CONFIG_MXC_NAND_HWECC +static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) +{ + /* + * If HW ECC is enabled, we turn it on during init. There is + * no need to enable again here. + */ } +#ifdef MXC_NFC_V2_1 static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip, int page, int sndcmd) @@ -616,7 +470,7 @@ static int mxc_nand_read_page_raw_syndrome(struct mtd_info *mtd, size = mtd->oobsize - (oob - chip->oob_poi); if (size) chip->read_buf(mtd, oob, size); - _mxc_nand_enable_hwecc(mtd, 0); + _mxc_nand_enable_hwecc(mtd, 1); return 0; } @@ -799,7 +653,7 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - uint16_t ecc_status = readw(&host->regs->nfc_ecc_status_result); + uint32_t ecc_status = readl(&host->regs->ecc_status_result); int subpages = mtd->writesize / nand_chip->subpagesize; int pg2blk_shift = nand_chip->phys_erase_shift - nand_chip->page_shift; @@ -832,7 +686,6 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, #define mxc_nand_write_page_syndrome NULL #define mxc_nand_write_page_raw_syndrome NULL #define mxc_nand_write_oob_syndrome NULL -#define mxc_nfc_11_nand_correct_data NULL static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) @@ -845,7 +698,7 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, * additional correction. 2-Bit errors cannot be corrected by * HW ECC, so we need to return failure */ - uint16_t ecc_status = readw(&host->regs->nfc_ecc_status_result); + uint16_t ecc_status = readw(&host->regs->ecc_status_result); if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { MTDDEBUG(MTD_DEBUG_LEVEL0, @@ -1208,7 +1061,7 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command, case NAND_CMD_PAGEPROG: send_prog_page(host, 0, host->spare_only); - if (host->pagesize_2k && !is_mxc_nfc_11()) { + if (host->pagesize_2k && is_mxc_nfc_1()) { /* data in 4 areas */ send_prog_page(host, 1, host->spare_only); send_prog_page(host, 2, host->spare_only); @@ -1258,7 +1111,7 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command, send_cmd(host, NAND_CMD_READSTART); /* read for each AREA */ send_read_page(host, 0, host->spare_only); - if (!is_mxc_nfc_11()) { + if (is_mxc_nfc_1()) { send_read_page(host, 1, host->spare_only); send_read_page(host, 2, host->spare_only); send_read_page(host, 3, host->spare_only); @@ -1284,24 +1137,6 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command, } } -#ifdef MXC_NFC_V1_1 -static void mxc_setup_config1(void) -{ - uint16_t tmp; - - tmp = readw(&host->regs->nfc_config1); - tmp |= NFC_ONE_CYCLE; - tmp |= NFC_4_8N_ECC; - writew(tmp, &host->regs->nfc_config1); - if (host->pagesize_2k) - writew(64/2, &host->regs->nfc_spare_area_size); - else - writew(16/2, &host->regs->nfc_spare_area_size); -} -#else -#define mxc_setup_config1() -#endif - #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; @@ -1332,8 +1167,9 @@ static struct nand_bbt_descr bbt_mirror_descr = { int board_nand_init(struct nand_chip *this) { struct mtd_info *mtd; +#ifdef MXC_NFC_V2_1 uint16_t tmp; - int err = 0; +#endif #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT this->options |= NAND_USE_FLASH_BBT; @@ -1359,14 +1195,14 @@ int board_nand_init(struct nand_chip *this) this->read_buf = mxc_nand_read_buf; this->verify_buf = mxc_nand_verify_buf; - host->regs = (struct nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE; + host->regs = (struct fsl_nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE; host->clk_act = 1; #ifdef CONFIG_MXC_NAND_HWECC this->ecc.calculate = mxc_nand_calculate_ecc; this->ecc.hwctl = mxc_nand_enable_hwecc; this->ecc.correct = mxc_nand_correct_data; - if (is_mxc_nfc_11()) { + if (is_mxc_nfc_21()) { this->ecc.mode = NAND_ECC_HW_SYNDROME; this->ecc.read_page = mxc_nand_read_page_syndrome; this->ecc.read_page_raw = mxc_nand_read_page_raw_syndrome; @@ -1383,27 +1219,46 @@ int board_nand_init(struct nand_chip *this) host->pagesize_2k = 0; this->ecc.size = 512; - tmp = readw(&host->regs->nfc_config1); - tmp |= NFC_ECC_EN; - writew(tmp, &host->regs->nfc_config1); + _mxc_nand_enable_hwecc(mtd, 1); #else this->ecc.layout = &nand_soft_eccoob; this->ecc.mode = NAND_ECC_SOFT; - tmp = readw(&host->regs->nfc_config1); - tmp &= ~NFC_ECC_EN; - writew(tmp, &host->regs->nfc_config1); + _mxc_nand_enable_hwecc(mtd, 0); #endif /* Reset NAND */ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + /* NAND bus width determines access functions used by upper layer */ + if (is_16bit_nand()) + this->options |= NAND_BUSWIDTH_16; + +#ifdef CONFIG_SYS_NAND_LARGEPAGE + host->pagesize_2k = 1; + this->ecc.layout = &nand_hw_eccoob2k; +#else + host->pagesize_2k = 0; + this->ecc.layout = &nand_hw_eccoob; +#endif + +#ifdef MXC_NFC_V2_1 + tmp = readw(&host->regs->config1); + tmp |= NFC_ONE_CYCLE; + tmp |= NFC_4_8N_ECC; + writew(tmp, &host->regs->config1); + if (host->pagesize_2k) + writew(64/2, &host->regs->spare_area_size); + else + writew(16/2, &host->regs->spare_area_size); +#endif + /* * preset operation * Unlock the internal RAM Buffer */ - writew(0x2, &host->regs->nfc_config); + writew(0x2, &host->regs->config); /* Blocks to be unlocked */ - writew(0x0, &host->regs->nfc_unlockstart_blkaddr); + writew(0x0, &host->regs->unlockstart_blkaddr); /* Originally (Freescale LTIB 2.6.21) 0x4000 was written to the * unlockend_blkaddr, but the magic 0x4000 does not always work * when writing more than some 32 megabytes (on 2k page nands) @@ -1415,22 +1270,10 @@ int board_nand_init(struct nand_chip *this) * This might be NAND chip specific and the i.MX31 datasheet is * extremely vague about the semantics of this register. */ - writew(0xFFFF, &host->regs->nfc_unlockend_blkaddr); + writew(0xFFFF, &host->regs->unlockend_blkaddr); /* Unlock Block Command for given address range */ - writew(0x4, &host->regs->nfc_wrprot); + writew(0x4, &host->regs->wrprot); - /* NAND bus width determines access functions used by upper layer */ - if (is_16bit_nand()) - this->options |= NAND_BUSWIDTH_16; - -#ifdef CONFIG_SYS_NAND_LARGEPAGE - host->pagesize_2k = 1; - this->ecc.layout = &nand_hw_eccoob2k; -#else - host->pagesize_2k = 0; - this->ecc.layout = &nand_hw_eccoob; -#endif - mxc_setup_config1(); - return err; + return 0; } diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 891af1f..71f5027 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2573,14 +2573,13 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, mtd->writesize = le32_to_cpu(p->byte_per_page); mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize; mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); - chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize; + chip->chipsize = le32_to_cpu(p->blocks_per_lun); + chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count; *busw = 0; if (le16_to_cpu(p->features) & 1) *busw = NAND_BUSWIDTH_16; - chip->options &= ~NAND_CHIPOPTIONS_MSK; - chip->options |= (NAND_NO_READRDY | - NAND_NO_AUTOINCR) & NAND_CHIPOPTIONS_MSK; + chip->options |= NAND_NO_READRDY | NAND_NO_AUTOINCR; return 1; } @@ -2752,8 +2751,7 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, } } /* Get chip options, preserve non chip based options */ - chip->options &= ~NAND_CHIPOPTIONS_MSK; - chip->options |= type->options & NAND_CHIPOPTIONS_MSK; + chip->options |= type->options; /* Check if chip is a not a samsung device. Do not clear the * options for chips which are not having an extended id. diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 7ed8b18..c4752a7 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -207,12 +207,6 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) * Support for locking / unlocking operations of some NAND devices *****************************************************************************/ -#define NAND_CMD_LOCK 0x2a -#define NAND_CMD_LOCK_TIGHT 0x2c -#define NAND_CMD_UNLOCK1 0x23 -#define NAND_CMD_UNLOCK2 0x24 -#define NAND_CMD_LOCK_STATUS 0x7a - /** * nand_lock: Set all pages of NAND flash chip to the LOCK or LOCK-TIGHT * state @@ -271,7 +265,6 @@ int nand_lock(struct mtd_info *mtd, int tight) * >0 lock status: * bitfield with the following combinations: * NAND_LOCK_STATUS_TIGHT: page in tight state - * NAND_LOCK_STATUS_LOCK: page locked * NAND_LOCK_STATUS_UNLOCK: page unlocked * */ @@ -300,7 +293,6 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) chip->cmdfunc(mtd, NAND_CMD_LOCK_STATUS, -1, page & chip->pagemask); ret = chip->read_byte(mtd) & (NAND_LOCK_STATUS_TIGHT - | NAND_LOCK_STATUS_LOCK | NAND_LOCK_STATUS_UNLOCK); out: @@ -317,18 +309,21 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) * @param start start byte address * @param length number of bytes to unlock (must be a multiple of * page size nand->writesize) + * @param allexcept if set, unlock everything not selected * * @return 0 on success, -1 in case of error */ -int nand_unlock(struct mtd_info *mtd, ulong start, ulong length) +int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length, + int allexcept) { int ret = 0; int chipnr; int status; int page; struct nand_chip *chip = mtd->priv; - printf ("nand_unlock: start: %08x, length: %d!\n", - (int)start, (int)length); + + debug("nand_unlock%s: start: %08llx, length: %d!\n", + allexcept ? " (allexcept)" : "", start, length); /* select the NAND device */ chipnr = (int)(start >> chip->chip_shift); @@ -368,6 +363,15 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length) /* submit ADDRESS of LAST page to unlock */ page += (int)(length >> chip->page_shift); + + /* + * Page addresses for unlocking are supposed to be block-aligned. + * At least some NAND chips use the low bit to indicate that the + * page range should be inverted. + */ + if (allexcept) + page |= 1; + chip->cmdfunc(mtd, NAND_CMD_UNLOCK2, -1, page & chip->pagemask); /* call wait ready function */ diff --git a/drivers/mtd/spi/spi_spl_load.c b/drivers/mtd/spi/spi_spl_load.c index 1aa30ac..d4f81f2 100644 --- a/drivers/mtd/spi/spi_spl_load.c +++ b/drivers/mtd/spi/spi_spl_load.c @@ -24,16 +24,17 @@ #include <common.h> #include <spi_flash.h> +#include <spl.h> /* * The main entry for SPI booting. It's necessary that SDRAM is already * configured and available since this code loads the main U-Boot image * from SPI into SDRAM and starts it from there. */ -void spi_boot(void) +void spl_spi_load_image(void) { struct spi_flash *flash; - void (*uboot)(void) __noreturn; + struct image_header *header; /* * Load U-Boot image from SPI flash into RAM @@ -42,17 +43,17 @@ void spi_boot(void) flash = spi_flash_probe(CONFIG_SPL_SPI_BUS, CONFIG_SPL_SPI_CS, CONFIG_SF_DEFAULT_SPEED, SPI_MODE_3); if (!flash) { - puts("failed.\n"); + puts("SPI probe failed.\n"); hang(); } - spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, - CONFIG_SYS_SPI_U_BOOT_SIZE, - (void *) CONFIG_SYS_TEXT_BASE); + /* use CONFIG_SYS_TEXT_BASE as temporary storage area */ + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); - /* - * Jump to U-Boot image - */ - uboot = (void *) CONFIG_SYS_TEXT_BASE; - (*uboot)(); + /* Load u-boot, mkimage header is 64 bytes. */ + spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40, + (void *) header); + spl_parse_image_header(header); + spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); } diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 011cd51..e4abac7 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -80,6 +80,7 @@ COBJS-$(CONFIG_XILINX_AXIEMAC) += xilinx_axi_emac.o COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o COBJS-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \ xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o +COBJS-$(CONFIG_ZYNQ_GEM) += zynq_gem.o COBJS := $(sort $(COBJS-y)) SRCS := $(COBJS:.o=.c) diff --git a/drivers/net/armada100_fec.c b/drivers/net/armada100_fec.c index d318a36..ed7cf20 100644 --- a/drivers/net/armada100_fec.c +++ b/drivers/net/armada100_fec.c @@ -565,7 +565,7 @@ static int armdfec_send(struct eth_device *dev, void *dataptr, int datasize) struct tx_desc *p_txdesc = darmdfec->p_txdesc; void *p = (void *)dataptr; int retry = PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS; - u32 cmd_sts; + u32 cmd_sts, temp; /* Copy buffer if it's misaligned */ if ((u32)dataptr & 0x07) { @@ -586,7 +586,8 @@ static int armdfec_send(struct eth_device *dev, void *dataptr, int datasize) p_txdesc->byte_cnt = datasize; /* Apply send command using high priority TX queue */ - writel((u32)p_txdesc, ®s->txcdp[TXQ]); + temp = (u32)®s->txcdp[TXQ]; + writel((u32)p_txdesc, temp); writel(SDMA_CMD_TXDL | SDMA_CMD_TXDH | SDMA_CMD_ERD, ®s->sdma_cmd); /* diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index fbfc842..3e232c7 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -31,9 +31,16 @@ #include <asm/arch/imx-regs.h> #include <asm/io.h> #include <asm/errno.h> +#include <linux/compiler.h> DECLARE_GLOBAL_DATA_PTR; +/* + * Timeout the transfer after 5 mS. This is usually a bit more, since + * the code in the tightloops this timeout is used in adds some overhead. + */ +#define FEC_XFER_TIMEOUT 5000 + #ifndef CONFIG_MII #error "CONFIG_MII has to be defined!" #endif @@ -249,7 +256,7 @@ static int miiphy_wait_aneg(struct eth_device *dev) static int fec_rx_task_enable(struct fec_priv *fec) { - writel(1 << 24, &fec->eth->r_des_active); + writel(FEC_R_DES_ACTIVE_RDAR, &fec->eth->r_des_active); return 0; } @@ -260,7 +267,7 @@ static int fec_rx_task_disable(struct fec_priv *fec) static int fec_tx_task_enable(struct fec_priv *fec) { - writel(1 << 24, &fec->eth->x_des_active); + writel(FEC_X_DES_ACTIVE_TDAR, &fec->eth->x_des_active); return 0; } @@ -694,8 +701,10 @@ static void fec_halt(struct eth_device *dev) static int fec_send(struct eth_device *dev, void *packet, int length) { unsigned int status; - uint32_t size; + uint32_t size, end; uint32_t addr; + int timeout = FEC_XFER_TIMEOUT; + int ret = 0; /* * This routine transmits one frame. This routine only accepts @@ -721,8 +730,9 @@ static int fec_send(struct eth_device *dev, void *packet, int length) #endif addr = (uint32_t)packet; - size = roundup(length, ARCH_DMA_MINALIGN); - flush_dcache_range(addr, addr + size); + end = roundup(addr + length, ARCH_DMA_MINALIGN); + addr &= ~(ARCH_DMA_MINALIGN - 1); + flush_dcache_range(addr, end); writew(length, &fec->tbd_base[fec->tbd_index].data_length); writel(addr, &fec->tbd_base[fec->tbd_index].data_pointer); @@ -758,22 +768,28 @@ static int fec_send(struct eth_device *dev, void *packet, int length) * invalidate data cache to see what's really in RAM. Also, we need * barrier here. */ - invalidate_dcache_range(addr, addr + size); - while (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) { - udelay(1); - invalidate_dcache_range(addr, addr + size); + while (--timeout) { + if (!(readl(&fec->eth->x_des_active) & FEC_X_DES_ACTIVE_TDAR)) + break; } - debug("fec_send: status 0x%x index %d\n", + if (!timeout) + ret = -EINVAL; + + invalidate_dcache_range(addr, addr + size); + if (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) + ret = -EINVAL; + + debug("fec_send: status 0x%x index %d ret %i\n", readw(&fec->tbd_base[fec->tbd_index].status), - fec->tbd_index); + fec->tbd_index, ret); /* for next transmission use the other buffer */ if (fec->tbd_index) fec->tbd_index = 0; else fec->tbd_index = 1; - return 0; + return ret; } /** @@ -789,9 +805,9 @@ static int fec_recv(struct eth_device *dev) int frame_length, len = 0; struct nbuf *frame; uint16_t bd_status; - uint32_t addr, size; + uint32_t addr, size, end; int i; - uchar buff[FEC_MAX_PKT_SIZE]; + uchar buff[FEC_MAX_PKT_SIZE] __aligned(ARCH_DMA_MINALIGN); /* * Check if any critical events have happened @@ -853,8 +869,9 @@ static int fec_recv(struct eth_device *dev) * Invalidate data cache over the buffer */ addr = (uint32_t)frame; - size = roundup(frame_length, ARCH_DMA_MINALIGN); - invalidate_dcache_range(addr, addr + size); + end = roundup(addr + frame_length, ARCH_DMA_MINALIGN); + addr &= ~(ARCH_DMA_MINALIGN - 1); + invalidate_dcache_range(addr, end); /* * Fill the buffer and pass it to upper layers diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index 852b2e0..203285a 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -213,6 +213,9 @@ struct ethernet_regs { #define FEC_X_WMRK_STRFWD 0x00000100 +#define FEC_X_DES_ACTIVE_TDAR 0x01000000 +#define FEC_R_DES_ACTIVE_RDAR 0x01000000 + #if defined(CONFIG_MX25) || defined(CONFIG_MX53) /* defines for MIIGSK */ /* RMII frequency control: 0=50MHz, 1=5MHz */ diff --git a/drivers/net/fm/Makefile b/drivers/net/fm/Makefile index 072b178..cc57354 100644 --- a/drivers/net/fm/Makefile +++ b/drivers/net/fm/Makefile @@ -36,10 +36,8 @@ COBJS-y += tgec_phy.o COBJS-$(CONFIG_P1017) += p1023.o COBJS-$(CONFIG_P1023) += p1023.o # The P204x, P304x, and P5020 are the same -COBJS-$(CONFIG_PPC_P2040) += p5020.o COBJS-$(CONFIG_PPC_P2041) += p5020.o COBJS-$(CONFIG_PPC_P3041) += p5020.o -COBJS-$(CONFIG_PPC_P3060) += p3060.o COBJS-$(CONFIG_PPC_P4080) += p4080.o COBJS-$(CONFIG_PPC_P5020) += p5020.o endif diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index 953c359..736b8b9 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -50,6 +50,9 @@ struct fm_eth_info fm_info[] = { #if (CONFIG_SYS_NUM_FM2_DTSEC >= 4) FM_DTSEC_INFO_INITIALIZER(2, 4), #endif +#if (CONFIG_SYS_NUM_FM2_DTSEC >= 5) + FM_DTSEC_INFO_INITIALIZER(2, 5), +#endif #if (CONFIG_SYS_NUM_FM1_10GEC >= 1) FM_TGEC_INFO_INITIALIZER(1, 1), #endif @@ -152,6 +155,22 @@ void fm_info_set_phy_address(enum fm_port port, int address) } /* + * Returns the PHY address for a given Fman port + * + * The port must be set via a prior call to fm_info_set_phy_address(). + * A negative error code is returned if the port is invalid. + */ +int fm_info_get_phy_address(enum fm_port port) +{ + int i = fm_port_to_index(port); + + if (i == -1) + return -1; + + return fm_info[i].phy_addr; +} + +/* * Returns the type of the data interface between the given MAC and its PHY. * This is typically determined by the RCW. */ @@ -181,7 +200,8 @@ void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop) { - int off, ph; + int off; + uint32_t ph; phys_addr_t paddr = CONFIG_SYS_CCSRBAR_PHYS + info->compat_offset; u64 dtsec1_addr = (u64)CONFIG_SYS_CCSRBAR_PHYS + CONFIG_SYS_FSL_FM1_DTSEC1_OFFSET; @@ -198,12 +218,10 @@ static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop) off = fdt_node_offset_by_compat_reg(blob, prop, paddr); /* Don't disable FM1-DTSEC1 MAC as its used for MDIO */ - if (paddr != dtsec1_addr) { - /* disable the mac node */ - fdt_setprop_string(blob, off, "status", "disabled"); - } + if (paddr != dtsec1_addr) + fdt_status_disabled(blob, off); /* disable the MAC node */ - /* disable the node point to the mac */ + /* disable the fsl,dpa-ethernet node that points to the MAC */ ph = fdt_get_phandle(blob, off); do_fixup_by_prop(blob, "fsl,fman-mac", &ph, sizeof(ph), "status", "disabled", strlen("disabled") + 1, 1); diff --git a/drivers/net/fm/p3060.c b/drivers/net/fm/p3060.c deleted file mode 100644 index c9748a9..0000000 --- a/drivers/net/fm/p3060.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include <common.h> -#include <phy.h> -#include <fm_eth.h> -#include <asm/io.h> -#include <asm/immap_85xx.h> -#include <asm/fsl_serdes.h> - -u32 port_to_devdisr[] = { - [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1, - [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2, - [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3, - [FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4, - [FM2_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC2_1, - [FM2_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC2_2, - [FM2_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC2_3, - [FM2_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC2_4, -}; - -static int is_device_disabled(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 devdisr2 = in_be32(&gur->devdisr2); - - return port_to_devdisr[port] & devdisr2; -} - -void fman_disable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - /* don't allow disabling of DTSEC1 as its needed for MDIO */ - if (port == FM1_DTSEC1) - return; - - setbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -phy_interface_t fman_port_enet_if(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 rcwsr11 = in_be32(&gur->rcwsr[11]); - - if (is_device_disabled(port)) - return PHY_INTERFACE_MODE_NONE; - - /* handle RGMII/MII first */ - if ((port == FM1_DTSEC1) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) == - FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM1_DTSEC2) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM2_DTSEC1) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1)) - return PHY_INTERFACE_MODE_RGMII; - - switch (port) { - case FM1_DTSEC1: - case FM1_DTSEC2: - case FM1_DTSEC3: - case FM1_DTSEC4: - if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - case FM2_DTSEC1: - case FM2_DTSEC2: - case FM2_DTSEC3: - case FM2_DTSEC4: - if (is_serdes_configured(SGMII_FM2_DTSEC1 + port - FM2_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - default: - return PHY_INTERFACE_MODE_NONE; - } - - return PHY_INTERFACE_MODE_NONE; -} diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 08206c8..3103a74 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -483,7 +483,7 @@ int greth_recv(struct eth_device *dev) greth_regs *regs = greth->regs; greth_bd *rxbd; unsigned int status, len = 0, bad; - unsigned char *d; + char *d; int enable = 0; int i; @@ -504,7 +504,7 @@ int greth_recv(struct eth_device *dev) goto done; } - debug("greth_recv: packet 0x%lx, 0x%lx, len: %d\n", + debug("greth_recv: packet 0x%x, 0x%x, len: %d\n", (unsigned int)rxbd, status, status & GRETH_BD_LEN); /* Check status for errors. @@ -620,7 +620,7 @@ int greth_initialize(bd_t * bis) greth->regs = (greth_regs *) apbdev.address; greth->irq = apbdev.irq; - debug("Found GRETH at 0x%lx, irq %d\n", greth->regs, greth->irq); + debug("Found GRETH at %p, irq %d\n", greth->regs, greth->irq); dev->priv = (void *)greth; dev->iobase = (unsigned int)greth->regs; dev->init = greth_init; @@ -652,7 +652,7 @@ int greth_initialize(bd_t * bis) /* initiate PHY, select speed/duplex depending on connected PHY */ if (greth_init_phy(greth, bis)) { /* Failed to init PHY (timedout) */ - debug("GRETH[0x%08x]: Failed to init PHY\n", greth->regs); + debug("GRETH[%p]: Failed to init PHY\n", greth->regs); return -1; } @@ -681,6 +681,6 @@ int greth_initialize(bd_t * bis) /* set and remember MAC address */ greth_set_hwaddr(greth, addr); - debug("GRETH[0x%08x]: Initialized successfully\n", greth->regs); + debug("GRETH[%p]: Initialized successfully\n", greth->regs); return 0; } diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 8f55cdc..0e1ced7 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -364,7 +364,7 @@ static int macb_phy_find(struct macb_device *macb) } /* PHY isn't up to snuff */ - printf("%s: PHY not found", macb->netdev.name); + printf("%s: PHY not found\n", macb->netdev.name); return 0; } diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 14243b8..dd7032a 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -28,7 +28,11 @@ DECLARE_GLOBAL_DATA_PTR; -static char input_buffer[512]; +#ifndef CONFIG_NETCONSOLE_BUFFER_SIZE +#define CONFIG_NETCONSOLE_BUFFER_SIZE 512 +#endif + +static char input_buffer[CONFIG_NETCONSOLE_BUFFER_SIZE]; static int input_size; /* char count in input buffer */ static int input_offset; /* offset to valid chars in input buffer */ static int input_recursion; @@ -36,9 +40,15 @@ static int output_recursion; static int net_timeout; static uchar nc_ether[6]; /* server enet address */ static IPaddr_t nc_ip; /* server ip */ -static short nc_port; /* source/target port */ +static short nc_out_port; /* target output port */ +static short nc_in_port; /* source input port */ static const char *output_packet; /* used by first send udp */ static int output_packet_len; +/* + * Start with a default last protocol. + * We are only interested in NETCONS or not. + */ +enum proto_t net_loop_last_protocol = BOOTP; static void nc_wait_arp_handler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, @@ -59,8 +69,69 @@ static void nc_timeout(void) net_set_state(NETLOOP_SUCCESS); } +static int is_broadcast(IPaddr_t ip) +{ + static IPaddr_t netmask; + static IPaddr_t our_ip; + static int env_changed_id; + int env_id = get_env_id(); + + /* update only when the environment has changed */ + if (env_changed_id != env_id) { + netmask = getenv_IPaddr("netmask"); + our_ip = getenv_IPaddr("ipaddr"); + + env_changed_id = env_id; + } + + return (ip == ~0 || /* 255.255.255.255 */ + ((netmask & our_ip) == (netmask & ip) && /* on the same net */ + (netmask | ip) == ~0)); /* broadcast to our net */ +} + +static int refresh_settings_from_env(void) +{ + const char *p; + static int env_changed_id; + int env_id = get_env_id(); + + /* update only when the environment has changed */ + if (env_changed_id != env_id) { + if (getenv("ncip")) { + nc_ip = getenv_IPaddr("ncip"); + if (!nc_ip) + return -1; /* ncip is 0.0.0.0 */ + p = strchr(getenv("ncip"), ':'); + if (p != NULL) { + nc_out_port = simple_strtoul(p + 1, NULL, 10); + nc_in_port = nc_out_port; + } + } else + nc_ip = ~0; /* ncip is not set, so broadcast */ + + p = getenv("ncoutport"); + if (p != NULL) + nc_out_port = simple_strtoul(p, NULL, 10); + p = getenv("ncinport"); + if (p != NULL) + nc_in_port = simple_strtoul(p, NULL, 10); + + if (is_broadcast(nc_ip)) + /* broadcast MAC address */ + memset(nc_ether, 0xff, sizeof(nc_ether)); + else + /* force arp request */ + memset(nc_ether, 0, sizeof(nc_ether)); + } + return 0; +} + +/** + * Called from NetLoop in net/net.c before each packet + */ void NcStart(void) { + refresh_settings_from_env(); if (!output_packet_len || memcmp(nc_ether, NetEtherNullAddr, 6)) { /* going to check for input packet */ net_set_udp_handler(nc_handler); @@ -71,18 +142,22 @@ void NcStart(void) net_set_arp_handler(nc_wait_arp_handler); pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; memcpy(pkt, output_packet, output_packet_len); - NetSendUDPPacket(nc_ether, nc_ip, nc_port, nc_port, + NetSendUDPPacket(nc_ether, nc_ip, nc_out_port, nc_in_port, output_packet_len); } } -int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len) +int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, + unsigned src_port, unsigned len) { int end, chunk; - if (dest != nc_port || !len) + if (dest_port != nc_in_port || !len) return 0; /* not for us */ + if (src_ip != nc_ip && !is_broadcast(nc_ip)) + return 0; /* not from our client */ + debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt); if (input_size == sizeof(input_buffer)) @@ -131,47 +206,39 @@ static void nc_send_packet(const char *buf, int len) } if (eth->state != ETH_STATE_ACTIVE) { - if (eth_init(gd->bd) < 0) - return; + if (eth_is_on_demand_init()) { + if (eth_init(gd->bd) < 0) + return; + eth_set_last_protocol(NETCONS); + } else + eth_init_state_only(gd->bd); + inited = 1; } pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; memcpy(pkt, buf, len); ether = nc_ether; ip = nc_ip; - NetSendUDPPacket(ether, ip, nc_port, nc_port, len); + NetSendUDPPacket(ether, ip, nc_out_port, nc_in_port, len); - if (inited) - eth_halt(); + if (inited) { + if (eth_is_on_demand_init()) + eth_halt(); + else + eth_halt_state_only(); + } } static int nc_start(void) { - int netmask, our_ip; - - nc_port = 6666; /* default port */ - - if (getenv("ncip")) { - char *p; - - nc_ip = getenv_IPaddr("ncip"); - if (!nc_ip) - return -1; /* ncip is 0.0.0.0 */ - p = strchr(getenv("ncip"), ':'); - if (p != NULL) - nc_port = simple_strtoul(p + 1, NULL, 10); - } else - nc_ip = ~0; /* ncip is not set */ + int retval; - our_ip = getenv_IPaddr("ipaddr"); - netmask = getenv_IPaddr("netmask"); + nc_out_port = 6666; /* default port */ + nc_in_port = nc_out_port; - if (nc_ip == ~0 || /* 255.255.255.255 */ - ((netmask & our_ip) == (netmask & nc_ip) && /* on the same net */ - (netmask | nc_ip) == ~0)) /* broadcast to our net */ - memset(nc_ether, 0xff, sizeof(nc_ether)); - else - memset(nc_ether, 0, sizeof(nc_ether)); /* force arp request */ + retval = refresh_settings_from_env(); + if (retval != 0) + return retval; /* * Initialize the static IP settings and buffer pointers @@ -203,7 +270,7 @@ static void nc_puts(const char *s) len = strlen(s); while (len) { - int send_len = min(len, 512); + int send_len = min(len, sizeof(input_buffer)); nc_send_packet(s, send_len); len -= send_len; s += send_len; diff --git a/arch/arm/cpu/ixp/npe/IxEthAcc.c b/drivers/net/npe/IxEthAcc.c index 20d3d9e..20d3d9e 100644 --- a/arch/arm/cpu/ixp/npe/IxEthAcc.c +++ b/drivers/net/npe/IxEthAcc.c diff --git a/arch/arm/cpu/ixp/npe/IxEthAccCommon.c b/drivers/net/npe/IxEthAccCommon.c index 211203d..211203d 100644 --- a/arch/arm/cpu/ixp/npe/IxEthAccCommon.c +++ b/drivers/net/npe/IxEthAccCommon.c diff --git a/arch/arm/cpu/ixp/npe/IxEthAccControlInterface.c b/drivers/net/npe/IxEthAccControlInterface.c index 4432847..4432847 100644 --- a/arch/arm/cpu/ixp/npe/IxEthAccControlInterface.c +++ b/drivers/net/npe/IxEthAccControlInterface.c diff --git a/arch/arm/cpu/ixp/npe/IxEthAccDataPlane.c b/drivers/net/npe/IxEthAccDataPlane.c index b62f0d0..b62f0d0 100644 --- a/arch/arm/cpu/ixp/npe/IxEthAccDataPlane.c +++ b/drivers/net/npe/IxEthAccDataPlane.c diff --git a/arch/arm/cpu/ixp/npe/IxEthAccMac.c b/drivers/net/npe/IxEthAccMac.c index 369ee91..369ee91 100644 --- a/arch/arm/cpu/ixp/npe/IxEthAccMac.c +++ b/drivers/net/npe/IxEthAccMac.c diff --git a/arch/arm/cpu/ixp/npe/IxEthAccMii.c b/drivers/net/npe/IxEthAccMii.c index d282aa6..d282aa6 100644 --- a/arch/arm/cpu/ixp/npe/IxEthAccMii.c +++ b/drivers/net/npe/IxEthAccMii.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBAPI.c b/drivers/net/npe/IxEthDBAPI.c index b2bfb72..b2bfb72 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBAPI.c +++ b/drivers/net/npe/IxEthDBAPI.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBAPISupport.c b/drivers/net/npe/IxEthDBAPISupport.c index 36bc200..36bc200 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBAPISupport.c +++ b/drivers/net/npe/IxEthDBAPISupport.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBCore.c b/drivers/net/npe/IxEthDBCore.c index 25b7cbb..25b7cbb 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBCore.c +++ b/drivers/net/npe/IxEthDBCore.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBEvents.c b/drivers/net/npe/IxEthDBEvents.c index 4d44e03..4d44e03 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBEvents.c +++ b/drivers/net/npe/IxEthDBEvents.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c b/drivers/net/npe/IxEthDBFeatures.c index 7a58d26..7a58d26 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c +++ b/drivers/net/npe/IxEthDBFeatures.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBFirewall.c b/drivers/net/npe/IxEthDBFirewall.c index eb46174..eb46174 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBFirewall.c +++ b/drivers/net/npe/IxEthDBFirewall.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBHashtable.c b/drivers/net/npe/IxEthDBHashtable.c index f1b18e6..f1b18e6 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBHashtable.c +++ b/drivers/net/npe/IxEthDBHashtable.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBLearning.c b/drivers/net/npe/IxEthDBLearning.c index 2287dbe..2287dbe 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBLearning.c +++ b/drivers/net/npe/IxEthDBLearning.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBMem.c b/drivers/net/npe/IxEthDBMem.c index 133cbef..133cbef 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBMem.c +++ b/drivers/net/npe/IxEthDBMem.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBNPEAdaptor.c b/drivers/net/npe/IxEthDBNPEAdaptor.c index 112a46c..112a46c 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBNPEAdaptor.c +++ b/drivers/net/npe/IxEthDBNPEAdaptor.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBPortUpdate.c b/drivers/net/npe/IxEthDBPortUpdate.c index cdf114b..cdf114b 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBPortUpdate.c +++ b/drivers/net/npe/IxEthDBPortUpdate.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBReports.c b/drivers/net/npe/IxEthDBReports.c index 9c7ae1c..9c7ae1c 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBReports.c +++ b/drivers/net/npe/IxEthDBReports.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBSearch.c b/drivers/net/npe/IxEthDBSearch.c index 4a10878..4a10878 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBSearch.c +++ b/drivers/net/npe/IxEthDBSearch.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBSpanningTree.c b/drivers/net/npe/IxEthDBSpanningTree.c index 6d9fd6e..6d9fd6e 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBSpanningTree.c +++ b/drivers/net/npe/IxEthDBSpanningTree.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBUtil.c b/drivers/net/npe/IxEthDBUtil.c index e708bf1..e708bf1 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBUtil.c +++ b/drivers/net/npe/IxEthDBUtil.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBVlan.c b/drivers/net/npe/IxEthDBVlan.c index e2efb9b..e2efb9b 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBVlan.c +++ b/drivers/net/npe/IxEthDBVlan.c diff --git a/arch/arm/cpu/ixp/npe/IxEthDBWiFi.c b/drivers/net/npe/IxEthDBWiFi.c index 0a6043f..0a6043f 100644 --- a/arch/arm/cpu/ixp/npe/IxEthDBWiFi.c +++ b/drivers/net/npe/IxEthDBWiFi.c diff --git a/arch/arm/cpu/ixp/npe/IxEthMii.c b/drivers/net/npe/IxEthMii.c index 4d92f17..4d92f17 100644 --- a/arch/arm/cpu/ixp/npe/IxEthMii.c +++ b/drivers/net/npe/IxEthMii.c diff --git a/arch/arm/cpu/ixp/npe/IxFeatureCtrl.c b/drivers/net/npe/IxFeatureCtrl.c index 2e196a1..2e196a1 100644 --- a/arch/arm/cpu/ixp/npe/IxFeatureCtrl.c +++ b/drivers/net/npe/IxFeatureCtrl.c diff --git a/arch/arm/cpu/ixp/npe/IxNpeDl.c b/drivers/net/npe/IxNpeDl.c index 3738337..3738337 100644 --- a/arch/arm/cpu/ixp/npe/IxNpeDl.c +++ b/drivers/net/npe/IxNpeDl.c diff --git a/arch/arm/cpu/ixp/npe/IxNpeDlImageMgr.c b/drivers/net/npe/IxNpeDlImageMgr.c index 9bcdc9c..9bcdc9c 100644 --- a/arch/arm/cpu/ixp/npe/IxNpeDlImageMgr.c +++ b/drivers/net/npe/IxNpeDlImageMgr.c diff --git a/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgr.c b/drivers/net/npe/IxNpeDlNpeMgr.c index a9ea8bc..a9ea8bc 100644 --- a/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgr.c +++ b/drivers/net/npe/IxNpeDlNpeMgr.c diff --git a/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c b/drivers/net/npe/IxNpeDlNpeMgrUtils.c index 18cac50..18cac50 100644 --- a/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c +++ b/drivers/net/npe/IxNpeDlNpeMgrUtils.c diff --git a/arch/arm/cpu/ixp/npe/IxNpeMh.c b/drivers/net/npe/IxNpeMh.c index 8703def..8703def 100644 --- a/arch/arm/cpu/ixp/npe/IxNpeMh.c +++ b/drivers/net/npe/IxNpeMh.c diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhConfig.c b/drivers/net/npe/IxNpeMhConfig.c index 50c8f21..50c8f21 100644 --- a/arch/arm/cpu/ixp/npe/IxNpeMhConfig.c +++ b/drivers/net/npe/IxNpeMhConfig.c diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhReceive.c b/drivers/net/npe/IxNpeMhReceive.c index 57c8be3..57c8be3 100644 --- a/arch/arm/cpu/ixp/npe/IxNpeMhReceive.c +++ b/drivers/net/npe/IxNpeMhReceive.c diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhSend.c b/drivers/net/npe/IxNpeMhSend.c index 318913a..318913a 100644 --- a/arch/arm/cpu/ixp/npe/IxNpeMhSend.c +++ b/drivers/net/npe/IxNpeMhSend.c diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c b/drivers/net/npe/IxNpeMhSolicitedCbMgr.c index 8e083a6..8e083a6 100644 --- a/arch/arm/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c +++ b/drivers/net/npe/IxNpeMhSolicitedCbMgr.c diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c b/drivers/net/npe/IxNpeMhUnsolicitedCbMgr.c index d37f9f9..d37f9f9 100644 --- a/arch/arm/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c +++ b/drivers/net/npe/IxNpeMhUnsolicitedCbMgr.c diff --git a/arch/arm/cpu/ixp/npe/IxOsalBufferMgt.c b/drivers/net/npe/IxOsalBufferMgt.c index fa8db47..fa8db47 100644 --- a/arch/arm/cpu/ixp/npe/IxOsalBufferMgt.c +++ b/drivers/net/npe/IxOsalBufferMgt.c diff --git a/arch/arm/cpu/ixp/npe/IxOsalIoMem.c b/drivers/net/npe/IxOsalIoMem.c index 34df92b..34df92b 100644 --- a/arch/arm/cpu/ixp/npe/IxOsalIoMem.c +++ b/drivers/net/npe/IxOsalIoMem.c diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsCacheMMU.c b/drivers/net/npe/IxOsalOsCacheMMU.c index 3db1a70..3db1a70 100644 --- a/arch/arm/cpu/ixp/npe/IxOsalOsCacheMMU.c +++ b/drivers/net/npe/IxOsalOsCacheMMU.c diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsMsgQ.c b/drivers/net/npe/IxOsalOsMsgQ.c index 45a5c68..45a5c68 100644 --- a/arch/arm/cpu/ixp/npe/IxOsalOsMsgQ.c +++ b/drivers/net/npe/IxOsalOsMsgQ.c diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsSemaphore.c b/drivers/net/npe/IxOsalOsSemaphore.c index 443aefd..443aefd 100644 --- a/arch/arm/cpu/ixp/npe/IxOsalOsSemaphore.c +++ b/drivers/net/npe/IxOsalOsSemaphore.c diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsServices.c b/drivers/net/npe/IxOsalOsServices.c index e18c6c4..e18c6c4 100644 --- a/arch/arm/cpu/ixp/npe/IxOsalOsServices.c +++ b/drivers/net/npe/IxOsalOsServices.c diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsThread.c b/drivers/net/npe/IxOsalOsThread.c index e6a4967..e6a4967 100644 --- a/arch/arm/cpu/ixp/npe/IxOsalOsThread.c +++ b/drivers/net/npe/IxOsalOsThread.c diff --git a/arch/arm/cpu/ixp/npe/IxQMgrAqmIf.c b/drivers/net/npe/IxQMgrAqmIf.c index 7386513..7386513 100644 --- a/arch/arm/cpu/ixp/npe/IxQMgrAqmIf.c +++ b/drivers/net/npe/IxQMgrAqmIf.c diff --git a/arch/arm/cpu/ixp/npe/IxQMgrDispatcher.c b/drivers/net/npe/IxQMgrDispatcher.c index 9cb1439..9cb1439 100644 --- a/arch/arm/cpu/ixp/npe/IxQMgrDispatcher.c +++ b/drivers/net/npe/IxQMgrDispatcher.c diff --git a/arch/arm/cpu/ixp/npe/IxQMgrInit.c b/drivers/net/npe/IxQMgrInit.c index b00c22d..b00c22d 100644 --- a/arch/arm/cpu/ixp/npe/IxQMgrInit.c +++ b/drivers/net/npe/IxQMgrInit.c diff --git a/arch/arm/cpu/ixp/npe/IxQMgrQAccess.c b/drivers/net/npe/IxQMgrQAccess.c index 8885736..8885736 100644 --- a/arch/arm/cpu/ixp/npe/IxQMgrQAccess.c +++ b/drivers/net/npe/IxQMgrQAccess.c diff --git a/arch/arm/cpu/ixp/npe/IxQMgrQCfg.c b/drivers/net/npe/IxQMgrQCfg.c index ec7d837..ec7d837 100644 --- a/arch/arm/cpu/ixp/npe/IxQMgrQCfg.c +++ b/drivers/net/npe/IxQMgrQCfg.c diff --git a/arch/arm/cpu/ixp/npe/Makefile b/drivers/net/npe/Makefile index 14ab3c7..d13391b 100644 --- a/arch/arm/cpu/ixp/npe/Makefile +++ b/drivers/net/npe/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libnpe.o -LOCAL_CFLAGS += -I$(TOPDIR)/arch/arm/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux +LOCAL_CFLAGS += -I$(TOPDIR)/drivers/net/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux CFLAGS += $(LOCAL_CFLAGS) CPPFLAGS += $(LOCAL_CFLAGS) # needed for depend HOSTCFLAGS += $(LOCAL_CFLAGS) diff --git a/arch/arm/cpu/ixp/npe/include/IxAssert.h b/drivers/net/npe/include/IxAssert.h index eae8b3f..eae8b3f 100644 --- a/arch/arm/cpu/ixp/npe/include/IxAssert.h +++ b/drivers/net/npe/include/IxAssert.h diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmSch.h b/drivers/net/npe/include/IxAtmSch.h index 73c3be2..73c3be2 100644 --- a/arch/arm/cpu/ixp/npe/include/IxAtmSch.h +++ b/drivers/net/npe/include/IxAtmSch.h diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmTypes.h b/drivers/net/npe/include/IxAtmTypes.h index 8624c33..8624c33 100644 --- a/arch/arm/cpu/ixp/npe/include/IxAtmTypes.h +++ b/drivers/net/npe/include/IxAtmTypes.h diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmdAcc.h b/drivers/net/npe/include/IxAtmdAcc.h index ae7b243..ae7b243 100644 --- a/arch/arm/cpu/ixp/npe/include/IxAtmdAcc.h +++ b/drivers/net/npe/include/IxAtmdAcc.h diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmdAccCtrl.h b/drivers/net/npe/include/IxAtmdAccCtrl.h index 50ef582..50ef582 100644 --- a/arch/arm/cpu/ixp/npe/include/IxAtmdAccCtrl.h +++ b/drivers/net/npe/include/IxAtmdAccCtrl.h diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmm.h b/drivers/net/npe/include/IxAtmm.h index fcf523f..fcf523f 100644 --- a/arch/arm/cpu/ixp/npe/include/IxAtmm.h +++ b/drivers/net/npe/include/IxAtmm.h diff --git a/arch/arm/cpu/ixp/npe/include/IxDmaAcc.h b/drivers/net/npe/include/IxDmaAcc.h index 45c7527..45c7527 100644 --- a/arch/arm/cpu/ixp/npe/include/IxDmaAcc.h +++ b/drivers/net/npe/include/IxDmaAcc.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAcc.h b/drivers/net/npe/include/IxEthAcc.h index ff706c4..ff706c4 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthAcc.h +++ b/drivers/net/npe/include/IxEthAcc.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccDataPlane_p.h b/drivers/net/npe/include/IxEthAccDataPlane_p.h index 8b8e6b2..8b8e6b2 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthAccDataPlane_p.h +++ b/drivers/net/npe/include/IxEthAccDataPlane_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccMac_p.h b/drivers/net/npe/include/IxEthAccMac_p.h index 93e9d98..93e9d98 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthAccMac_p.h +++ b/drivers/net/npe/include/IxEthAccMac_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccMii_p.h b/drivers/net/npe/include/IxEthAccMii_p.h index 568d4a0..568d4a0 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthAccMii_p.h +++ b/drivers/net/npe/include/IxEthAccMii_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h b/drivers/net/npe/include/IxEthAccQueueAssign_p.h index e5fd16e..e5fd16e 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h +++ b/drivers/net/npe/include/IxEthAccQueueAssign_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAcc_p.h b/drivers/net/npe/include/IxEthAcc_p.h index 4e0de82..4e0de82 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthAcc_p.h +++ b/drivers/net/npe/include/IxEthAcc_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDB.h b/drivers/net/npe/include/IxEthDB.h index 1189c9a..1189c9a 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthDB.h +++ b/drivers/net/npe/include/IxEthDB.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBLocks_p.h b/drivers/net/npe/include/IxEthDBLocks_p.h index 1d8b24f..1d8b24f 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthDBLocks_p.h +++ b/drivers/net/npe/include/IxEthDBLocks_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBLog_p.h b/drivers/net/npe/include/IxEthDBLog_p.h index 1d6b0bb..1d6b0bb 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthDBLog_p.h +++ b/drivers/net/npe/include/IxEthDBLog_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBMessages_p.h b/drivers/net/npe/include/IxEthDBMessages_p.h index ff18160..ff18160 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthDBMessages_p.h +++ b/drivers/net/npe/include/IxEthDBMessages_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBPortDefs.h b/drivers/net/npe/include/IxEthDBPortDefs.h index c3acbdd..c3acbdd 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthDBPortDefs.h +++ b/drivers/net/npe/include/IxEthDBPortDefs.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBQoS.h b/drivers/net/npe/include/IxEthDBQoS.h index 6d34889..6d34889 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthDBQoS.h +++ b/drivers/net/npe/include/IxEthDBQoS.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDB_p.h b/drivers/net/npe/include/IxEthDB_p.h index ccec7ea..ccec7ea 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthDB_p.h +++ b/drivers/net/npe/include/IxEthDB_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthMii.h b/drivers/net/npe/include/IxEthMii.h index 397253a..397253a 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthMii.h +++ b/drivers/net/npe/include/IxEthMii.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthMii_p.h b/drivers/net/npe/include/IxEthMii_p.h index 104b65c..104b65c 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthMii_p.h +++ b/drivers/net/npe/include/IxEthMii_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxEthNpe.h b/drivers/net/npe/include/IxEthNpe.h index 21bdedc..21bdedc 100644 --- a/arch/arm/cpu/ixp/npe/include/IxEthNpe.h +++ b/drivers/net/npe/include/IxEthNpe.h diff --git a/arch/arm/cpu/ixp/npe/include/IxFeatureCtrl.h b/drivers/net/npe/include/IxFeatureCtrl.h index dabc38e..dabc38e 100644 --- a/arch/arm/cpu/ixp/npe/include/IxFeatureCtrl.h +++ b/drivers/net/npe/include/IxFeatureCtrl.h diff --git a/arch/arm/cpu/ixp/npe/include/IxHssAcc.h b/drivers/net/npe/include/IxHssAcc.h index 07bb119..07bb119 100644 --- a/arch/arm/cpu/ixp/npe/include/IxHssAcc.h +++ b/drivers/net/npe/include/IxHssAcc.h diff --git a/arch/arm/cpu/ixp/npe/include/IxI2cDrv.h b/drivers/net/npe/include/IxI2cDrv.h index 92c6b24..92c6b24 100644 --- a/arch/arm/cpu/ixp/npe/include/IxI2cDrv.h +++ b/drivers/net/npe/include/IxI2cDrv.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeA.h b/drivers/net/npe/include/IxNpeA.h index 90669c2..90669c2 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeA.h +++ b/drivers/net/npe/include/IxNpeA.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeDl.h b/drivers/net/npe/include/IxNpeDl.h index 86f69f4..86f69f4 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeDl.h +++ b/drivers/net/npe/include/IxNpeDl.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeDlImageMgr_p.h b/drivers/net/npe/include/IxNpeDlImageMgr_p.h index 622f879..622f879 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeDlImageMgr_p.h +++ b/drivers/net/npe/include/IxNpeDlImageMgr_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeDlMacros_p.h b/drivers/net/npe/include/IxNpeDlMacros_p.h index e32906a..e32906a 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeDlMacros_p.h +++ b/drivers/net/npe/include/IxNpeDlMacros_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgrEcRegisters_p.h b/drivers/net/npe/include/IxNpeDlNpeMgrEcRegisters_p.h index f682126..f682126 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgrEcRegisters_p.h +++ b/drivers/net/npe/include/IxNpeDlNpeMgrEcRegisters_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgrUtils_p.h b/drivers/net/npe/include/IxNpeDlNpeMgrUtils_p.h index a752f26..a752f26 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgrUtils_p.h +++ b/drivers/net/npe/include/IxNpeDlNpeMgrUtils_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgr_p.h b/drivers/net/npe/include/IxNpeDlNpeMgr_p.h index b7fb0f0..b7fb0f0 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgr_p.h +++ b/drivers/net/npe/include/IxNpeDlNpeMgr_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMh.h b/drivers/net/npe/include/IxNpeMh.h index 20ee38b..20ee38b 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeMh.h +++ b/drivers/net/npe/include/IxNpeMh.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMhConfig_p.h b/drivers/net/npe/include/IxNpeMhConfig_p.h index 375b346..375b346 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeMhConfig_p.h +++ b/drivers/net/npe/include/IxNpeMhConfig_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMhMacros_p.h b/drivers/net/npe/include/IxNpeMhMacros_p.h index 68f34ef..68f34ef 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeMhMacros_p.h +++ b/drivers/net/npe/include/IxNpeMhMacros_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMhReceive_p.h b/drivers/net/npe/include/IxNpeMhReceive_p.h index 6416bed..6416bed 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeMhReceive_p.h +++ b/drivers/net/npe/include/IxNpeMhReceive_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMhSend_p.h b/drivers/net/npe/include/IxNpeMhSend_p.h index 977cc94..977cc94 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeMhSend_p.h +++ b/drivers/net/npe/include/IxNpeMhSend_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMhSolicitedCbMgr_p.h b/drivers/net/npe/include/IxNpeMhSolicitedCbMgr_p.h index 40cd496..40cd496 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeMhSolicitedCbMgr_p.h +++ b/drivers/net/npe/include/IxNpeMhSolicitedCbMgr_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMhUnsolicitedCbMgr_p.h b/drivers/net/npe/include/IxNpeMhUnsolicitedCbMgr_p.h index dea8caf..dea8caf 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeMhUnsolicitedCbMgr_p.h +++ b/drivers/net/npe/include/IxNpeMhUnsolicitedCbMgr_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxNpeMicrocode.h b/drivers/net/npe/include/IxNpeMicrocode.h index 893d803..893d803 100644 --- a/arch/arm/cpu/ixp/npe/include/IxNpeMicrocode.h +++ b/drivers/net/npe/include/IxNpeMicrocode.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsBufLib.h b/drivers/net/npe/include/IxOsBufLib.h index a297a97..a297a97 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsBufLib.h +++ b/drivers/net/npe/include/IxOsBufLib.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsBuffMgt.h b/drivers/net/npe/include/IxOsBuffMgt.h index b7de712..b7de712 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsBuffMgt.h +++ b/drivers/net/npe/include/IxOsBuffMgt.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsBuffPoolMgt.h b/drivers/net/npe/include/IxOsBuffPoolMgt.h index 4a983c7..4a983c7 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsBuffPoolMgt.h +++ b/drivers/net/npe/include/IxOsBuffPoolMgt.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsCacheMMU.h b/drivers/net/npe/include/IxOsCacheMMU.h index 2c8592f..2c8592f 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsCacheMMU.h +++ b/drivers/net/npe/include/IxOsCacheMMU.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsPrintf.h b/drivers/net/npe/include/IxOsPrintf.h index 218e140..218e140 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsPrintf.h +++ b/drivers/net/npe/include/IxOsPrintf.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsServices.h b/drivers/net/npe/include/IxOsServices.h index 62e8a79..62e8a79 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsServices.h +++ b/drivers/net/npe/include/IxOsServices.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsServicesComponents.h b/drivers/net/npe/include/IxOsServicesComponents.h index d662cd3..d662cd3 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsServicesComponents.h +++ b/drivers/net/npe/include/IxOsServicesComponents.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsServicesEndianess.h b/drivers/net/npe/include/IxOsServicesEndianess.h index 0d6cd8c..0d6cd8c 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsServicesEndianess.h +++ b/drivers/net/npe/include/IxOsServicesEndianess.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsServicesMemAccess.h b/drivers/net/npe/include/IxOsServicesMemAccess.h index 58e9941..58e9941 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsServicesMemAccess.h +++ b/drivers/net/npe/include/IxOsServicesMemAccess.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsServicesMemMap.h b/drivers/net/npe/include/IxOsServicesMemMap.h index 4ce37c3..4ce37c3 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsServicesMemMap.h +++ b/drivers/net/npe/include/IxOsServicesMemMap.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsal.h b/drivers/net/npe/include/IxOsal.h index 4ca2e45..4ca2e45 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsal.h +++ b/drivers/net/npe/include/IxOsal.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalAssert.h b/drivers/net/npe/include/IxOsalAssert.h index 04a4f51..04a4f51 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalAssert.h +++ b/drivers/net/npe/include/IxOsalAssert.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackward.h b/drivers/net/npe/include/IxOsalBackward.h index ea9f307..ea9f307 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalBackward.h +++ b/drivers/net/npe/include/IxOsalBackward.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardAssert.h b/drivers/net/npe/include/IxOsalBackwardAssert.h index be1e272..be1e272 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardAssert.h +++ b/drivers/net/npe/include/IxOsalBackwardAssert.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardBufferMgt.h b/drivers/net/npe/include/IxOsalBackwardBufferMgt.h index 4cf80d3..4cf80d3 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardBufferMgt.h +++ b/drivers/net/npe/include/IxOsalBackwardBufferMgt.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardCacheMMU.h b/drivers/net/npe/include/IxOsalBackwardCacheMMU.h index fe570e6..fe570e6 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardCacheMMU.h +++ b/drivers/net/npe/include/IxOsalBackwardCacheMMU.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardMemMap.h b/drivers/net/npe/include/IxOsalBackwardMemMap.h index 3881a3b..3881a3b 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardMemMap.h +++ b/drivers/net/npe/include/IxOsalBackwardMemMap.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardOsServices.h b/drivers/net/npe/include/IxOsalBackwardOsServices.h index 0ccff84..0ccff84 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardOsServices.h +++ b/drivers/net/npe/include/IxOsalBackwardOsServices.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardOssl.h b/drivers/net/npe/include/IxOsalBackwardOssl.h index 634b494..634b494 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalBackwardOssl.h +++ b/drivers/net/npe/include/IxOsalBackwardOssl.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBufferMgt.h b/drivers/net/npe/include/IxOsalBufferMgt.h index 497ed04..497ed04 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalBufferMgt.h +++ b/drivers/net/npe/include/IxOsalBufferMgt.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalBufferMgtDefault.h b/drivers/net/npe/include/IxOsalBufferMgtDefault.h index 684b52e..684b52e 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalBufferMgtDefault.h +++ b/drivers/net/npe/include/IxOsalBufferMgtDefault.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalConfig.h b/drivers/net/npe/include/IxOsalConfig.h index d56e796..d56e796 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalConfig.h +++ b/drivers/net/npe/include/IxOsalConfig.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalEndianess.h b/drivers/net/npe/include/IxOsalEndianess.h index 3b1c739..3b1c739 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalEndianess.h +++ b/drivers/net/npe/include/IxOsalEndianess.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalIoMem.h b/drivers/net/npe/include/IxOsalIoMem.h index ea6d64d..ea6d64d 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalIoMem.h +++ b/drivers/net/npe/include/IxOsalIoMem.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalMemAccess.h b/drivers/net/npe/include/IxOsalMemAccess.h index 9e7fb87..9e7fb87 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalMemAccess.h +++ b/drivers/net/npe/include/IxOsalMemAccess.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOem.h b/drivers/net/npe/include/IxOsalOem.h index f894026..f894026 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalOem.h +++ b/drivers/net/npe/include/IxOsalOem.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOs.h b/drivers/net/npe/include/IxOsalOs.h index 6c66613..6c66613 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalOs.h +++ b/drivers/net/npe/include/IxOsalOs.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOsAssert.h b/drivers/net/npe/include/IxOsalOsAssert.h index e4c3e1f..e4c3e1f 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalOsAssert.h +++ b/drivers/net/npe/include/IxOsalOsAssert.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOsBufferMgt.h b/drivers/net/npe/include/IxOsalOsBufferMgt.h index 8e46586..8e46586 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalOsBufferMgt.h +++ b/drivers/net/npe/include/IxOsalOsBufferMgt.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOsIxp400.h b/drivers/net/npe/include/IxOsalOsIxp400.h index 44a94fb..44a94fb 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalOsIxp400.h +++ b/drivers/net/npe/include/IxOsalOsIxp400.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOsIxp400CustomizedMapping.h b/drivers/net/npe/include/IxOsalOsIxp400CustomizedMapping.h index 47ce3a2..47ce3a2 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalOsIxp400CustomizedMapping.h +++ b/drivers/net/npe/include/IxOsalOsIxp400CustomizedMapping.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOsTypes.h b/drivers/net/npe/include/IxOsalOsTypes.h index 272eef1..272eef1 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalOsTypes.h +++ b/drivers/net/npe/include/IxOsalOsTypes.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalOsUtilitySymbols.h b/drivers/net/npe/include/IxOsalOsUtilitySymbols.h index beb45a0..beb45a0 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalOsUtilitySymbols.h +++ b/drivers/net/npe/include/IxOsalOsUtilitySymbols.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalTypes.h b/drivers/net/npe/include/IxOsalTypes.h index a190a70..a190a70 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalTypes.h +++ b/drivers/net/npe/include/IxOsalTypes.h diff --git a/arch/arm/cpu/ixp/npe/include/IxOsalUtilitySymbols.h b/drivers/net/npe/include/IxOsalUtilitySymbols.h index f2a73db..f2a73db 100644 --- a/arch/arm/cpu/ixp/npe/include/IxOsalUtilitySymbols.h +++ b/drivers/net/npe/include/IxOsalUtilitySymbols.h diff --git a/arch/arm/cpu/ixp/npe/include/IxParityENAcc.h b/drivers/net/npe/include/IxParityENAcc.h index 62fe171..62fe171 100644 --- a/arch/arm/cpu/ixp/npe/include/IxParityENAcc.h +++ b/drivers/net/npe/include/IxParityENAcc.h diff --git a/arch/arm/cpu/ixp/npe/include/IxPerfProfAcc.h b/drivers/net/npe/include/IxPerfProfAcc.h index 65c0ba9..65c0ba9 100644 --- a/arch/arm/cpu/ixp/npe/include/IxPerfProfAcc.h +++ b/drivers/net/npe/include/IxPerfProfAcc.h diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgr.h b/drivers/net/npe/include/IxQMgr.h index 03d7e07..03d7e07 100644 --- a/arch/arm/cpu/ixp/npe/include/IxQMgr.h +++ b/drivers/net/npe/include/IxQMgr.h diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgrAqmIf_p.h b/drivers/net/npe/include/IxQMgrAqmIf_p.h index 4f0f64d..4f0f64d 100644 --- a/arch/arm/cpu/ixp/npe/include/IxQMgrAqmIf_p.h +++ b/drivers/net/npe/include/IxQMgrAqmIf_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgrDefines_p.h b/drivers/net/npe/include/IxQMgrDefines_p.h index 0183596..0183596 100644 --- a/arch/arm/cpu/ixp/npe/include/IxQMgrDefines_p.h +++ b/drivers/net/npe/include/IxQMgrDefines_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgrDispatcher_p.h b/drivers/net/npe/include/IxQMgrDispatcher_p.h index 71a3f85..71a3f85 100644 --- a/arch/arm/cpu/ixp/npe/include/IxQMgrDispatcher_p.h +++ b/drivers/net/npe/include/IxQMgrDispatcher_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgrLog_p.h b/drivers/net/npe/include/IxQMgrLog_p.h index 6b685b8..6b685b8 100644 --- a/arch/arm/cpu/ixp/npe/include/IxQMgrLog_p.h +++ b/drivers/net/npe/include/IxQMgrLog_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgrQAccess_p.h b/drivers/net/npe/include/IxQMgrQAccess_p.h index 8612670..8612670 100644 --- a/arch/arm/cpu/ixp/npe/include/IxQMgrQAccess_p.h +++ b/drivers/net/npe/include/IxQMgrQAccess_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxQMgrQCfg_p.h b/drivers/net/npe/include/IxQMgrQCfg_p.h index c9dae1e..c9dae1e 100644 --- a/arch/arm/cpu/ixp/npe/include/IxQMgrQCfg_p.h +++ b/drivers/net/npe/include/IxQMgrQCfg_p.h diff --git a/arch/arm/cpu/ixp/npe/include/IxQueueAssignments.h b/drivers/net/npe/include/IxQueueAssignments.h index b65d621..b65d621 100644 --- a/arch/arm/cpu/ixp/npe/include/IxQueueAssignments.h +++ b/drivers/net/npe/include/IxQueueAssignments.h diff --git a/arch/arm/cpu/ixp/npe/include/IxSspAcc.h b/drivers/net/npe/include/IxSspAcc.h index 35e7abf..35e7abf 100644 --- a/arch/arm/cpu/ixp/npe/include/IxSspAcc.h +++ b/drivers/net/npe/include/IxSspAcc.h diff --git a/arch/arm/cpu/ixp/npe/include/IxTimeSyncAcc.h b/drivers/net/npe/include/IxTimeSyncAcc.h index 25effed..25effed 100644 --- a/arch/arm/cpu/ixp/npe/include/IxTimeSyncAcc.h +++ b/drivers/net/npe/include/IxTimeSyncAcc.h diff --git a/arch/arm/cpu/ixp/npe/include/IxTimerCtrl.h b/drivers/net/npe/include/IxTimerCtrl.h index 669dd3e..669dd3e 100644 --- a/arch/arm/cpu/ixp/npe/include/IxTimerCtrl.h +++ b/drivers/net/npe/include/IxTimerCtrl.h diff --git a/arch/arm/cpu/ixp/npe/include/IxTypes.h b/drivers/net/npe/include/IxTypes.h index c4c5a2d..c4c5a2d 100644 --- a/arch/arm/cpu/ixp/npe/include/IxTypes.h +++ b/drivers/net/npe/include/IxTypes.h diff --git a/arch/arm/cpu/ixp/npe/include/IxUART.h b/drivers/net/npe/include/IxUART.h index 03a4444..03a4444 100644 --- a/arch/arm/cpu/ixp/npe/include/IxUART.h +++ b/drivers/net/npe/include/IxUART.h diff --git a/arch/arm/cpu/ixp/npe/include/IxVersionId.h b/drivers/net/npe/include/IxVersionId.h index 27796ed..27796ed 100644 --- a/arch/arm/cpu/ixp/npe/include/IxVersionId.h +++ b/drivers/net/npe/include/IxVersionId.h diff --git a/arch/arm/cpu/ixp/npe/include/ix_error.h b/drivers/net/npe/include/ix_error.h index d32ace2..d32ace2 100644 --- a/arch/arm/cpu/ixp/npe/include/ix_error.h +++ b/drivers/net/npe/include/ix_error.h diff --git a/arch/arm/cpu/ixp/npe/include/ix_macros.h b/drivers/net/npe/include/ix_macros.h index 53f5942..53f5942 100644 --- a/arch/arm/cpu/ixp/npe/include/ix_macros.h +++ b/drivers/net/npe/include/ix_macros.h diff --git a/arch/arm/cpu/ixp/npe/include/ix_os_type.h b/drivers/net/npe/include/ix_os_type.h index 8575096..8575096 100644 --- a/arch/arm/cpu/ixp/npe/include/ix_os_type.h +++ b/drivers/net/npe/include/ix_os_type.h diff --git a/arch/arm/cpu/ixp/npe/include/ix_ossl.h b/drivers/net/npe/include/ix_ossl.h index b59f7d0..b59f7d0 100644 --- a/arch/arm/cpu/ixp/npe/include/ix_ossl.h +++ b/drivers/net/npe/include/ix_ossl.h diff --git a/arch/arm/cpu/ixp/npe/include/ix_symbols.h b/drivers/net/npe/include/ix_symbols.h index f7bb029..f7bb029 100644 --- a/arch/arm/cpu/ixp/npe/include/ix_symbols.h +++ b/drivers/net/npe/include/ix_symbols.h diff --git a/arch/arm/cpu/ixp/npe/include/ix_types.h b/drivers/net/npe/include/ix_types.h index fc7b1e9..fc7b1e9 100644 --- a/arch/arm/cpu/ixp/npe/include/ix_types.h +++ b/drivers/net/npe/include/ix_types.h diff --git a/arch/arm/cpu/ixp/npe/include/npe.h b/drivers/net/npe/include/npe.h index b5eef86..b5eef86 100644 --- a/arch/arm/cpu/ixp/npe/include/npe.h +++ b/drivers/net/npe/include/npe.h diff --git a/arch/arm/cpu/ixp/npe/include/os_datatypes.h b/drivers/net/npe/include/os_datatypes.h index 4387b2a..4387b2a 100644 --- a/arch/arm/cpu/ixp/npe/include/os_datatypes.h +++ b/drivers/net/npe/include/os_datatypes.h diff --git a/arch/arm/cpu/ixp/npe/miiphy.c b/drivers/net/npe/miiphy.c index a04779a..a04779a 100644 --- a/arch/arm/cpu/ixp/npe/miiphy.c +++ b/drivers/net/npe/miiphy.c diff --git a/arch/arm/cpu/ixp/npe/npe.c b/drivers/net/npe/npe.c index 1fe3a95..1fe3a95 100644 --- a/arch/arm/cpu/ixp/npe/npe.c +++ b/drivers/net/npe/npe.c diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index feced39..5e90d70 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -27,6 +27,7 @@ LIB := $(obj)libphy.o COBJS-$(CONFIG_BITBANGMII) += miiphybb.o COBJS-$(CONFIG_MV88E61XX_SWITCH) += mv88e61xx.o +COBJS-$(CONFIG_MV88E6352_SWITCH) += mv88e6352.o COBJS-$(CONFIG_PHYLIB) += phy.o COBJS-$(CONFIG_PHYLIB_10G) += generic_10g.o diff --git a/drivers/net/phy/mv88e6352.c b/drivers/net/phy/mv88e6352.c new file mode 100644 index 0000000..7269a6a --- /dev/null +++ b/drivers/net/phy/mv88e6352.c @@ -0,0 +1,318 @@ +/* + * (C) Copyright 2012 + * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; 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 + */ + +#include <common.h> +#include <miiphy.h> +#include <asm/errno.h> +#include <mv88e6352.h> + +#define SMI_HDR ((0x8 | 0x1) << 12) +#define SMI_BUSY_MASK (0x8000) +#define SMIRD_OP (0x2 << 10) +#define SMIWR_OP (0x1 << 10) +#define SMI_MASK 0x1f +#define PORT_SHIFT 5 + +#define COMMAND_REG 0 +#define DATA_REG 1 + +/* global registers */ +#define GLOBAL 0x1b + +#define GLOBAL_STATUS 0x00 +#define PPU_STATE 0x8000 + +#define GLOBAL_CTRL 0x04 +#define SW_RESET 0x8000 +#define PPU_ENABLE 0x4000 + +static int sw_wait_rdy(const char *devname, u8 phy_addr) +{ + u16 command; + u32 timeout = 100; + int ret; + + /* wait till the SMI is not busy */ + do { + /* read command register */ + ret = miiphy_read(devname, phy_addr, COMMAND_REG, &command); + if (ret < 0) { + printf("%s: Error reading command register\n", + __func__); + return ret; + } + if (timeout-- == 0) { + printf("Err..(%s) SMI busy timeout\n", __func__); + return -EFAULT; + } + } while (command & SMI_BUSY_MASK); + + return 0; +} + +static int sw_reg_read(const char *devname, u8 phy_addr, u8 port, + u8 reg, u16 *data) +{ + int ret; + u16 command; + + ret = sw_wait_rdy(devname, phy_addr); + if (ret) + return ret; + + command = SMI_HDR | SMIRD_OP | ((port&SMI_MASK) << PORT_SHIFT) | + (reg & SMI_MASK); + debug("%s: write to command: %#x\n", __func__, command); + ret = miiphy_write(devname, phy_addr, COMMAND_REG, command); + if (ret) + return ret; + + ret = sw_wait_rdy(devname, phy_addr); + if (ret) + return ret; + + ret = miiphy_read(devname, phy_addr, DATA_REG, data); + + return ret; +} + +static int sw_reg_write(const char *devname, u8 phy_addr, u8 port, + u8 reg, u16 data) +{ + int ret; + u16 value; + + ret = sw_wait_rdy(devname, phy_addr); + if (ret) + return ret; + + debug("%s: write to data: %#x\n", __func__, data); + ret = miiphy_write(devname, phy_addr, DATA_REG, data); + if (ret) + return ret; + + value = SMI_HDR | SMIWR_OP | ((port & SMI_MASK) << PORT_SHIFT) | + (reg & SMI_MASK); + debug("%s: write to command: %#x\n", __func__, value); + ret = miiphy_write(devname, phy_addr, COMMAND_REG, value); + if (ret) + return ret; + + ret = sw_wait_rdy(devname, phy_addr); + if (ret) + return ret; + + return 0; +} + +static int ppu_enable(const char *devname, u8 phy_addr) +{ + int i, ret = 0; + u16 reg; + + ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, ®); + if (ret) { + printf("%s: Error reading global ctrl reg\n", __func__); + return ret; + } + + reg |= PPU_ENABLE; + + ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg); + if (ret) { + printf("%s: Error writing global ctrl reg\n", __func__); + return ret; + } + + for (i = 0; i < 1000; i++) { + sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS, + ®); + if ((reg & 0xc000) == 0xc000) + return 0; + udelay(1000); + } + + return -ETIMEDOUT; +} + +static int ppu_disable(const char *devname, u8 phy_addr) +{ + int i, ret = 0; + u16 reg; + + ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, ®); + if (ret) { + printf("%s: Error reading global ctrl reg\n", __func__); + return ret; + } + + reg &= ~PPU_ENABLE; + + ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg); + if (ret) { + printf("%s: Error writing global ctrl reg\n", __func__); + return ret; + } + + for (i = 0; i < 1000; i++) { + sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS, + ®); + if ((reg & 0xc000) != 0xc000) + return 0; + udelay(1000); + } + + return -ETIMEDOUT; +} + +int mv88e_sw_program(const char *devname, u8 phy_addr, + struct mv88e_sw_reg *regs, int regs_nb) +{ + int i, ret = 0; + + /* first we need to disable the PPU */ + ret = ppu_disable(devname, phy_addr); + if (ret) { + printf("%s: Error disabling PPU\n", __func__); + return ret; + } + + for (i = 0; i < regs_nb; i++) { + ret = sw_reg_write(devname, phy_addr, regs[i].port, + regs[i].reg, regs[i].value); + if (ret) { + printf("%s: Error configuring switch\n", __func__); + ppu_enable(devname, phy_addr); + return ret; + } + } + + /* re-enable the PPU */ + ret = ppu_enable(devname, phy_addr); + if (ret) { + printf("%s: Error enabling PPU\n", __func__); + return ret; + } + + return 0; +} + +int mv88e_sw_reset(const char *devname, u8 phy_addr) +{ + int i, ret = 0; + u16 reg; + + ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, ®); + if (ret) { + printf("%s: Error reading global ctrl reg\n", __func__); + return ret; + } + + reg = SW_RESET | PPU_ENABLE | 0x0400; + + ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg); + if (ret) { + printf("%s: Error writing global ctrl reg\n", __func__); + return ret; + } + + for (i = 0; i < 1000; i++) { + sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS, + ®); + if ((reg & 0xc800) != 0xc800) + return 0; + udelay(1000); + } + + return -ETIMEDOUT; +} + +int do_mvsw_reg_read(const char *name, int argc, char * const argv[]) +{ + u16 value = 0, phyaddr, reg, port; + int ret; + + phyaddr = simple_strtoul(argv[1], NULL, 10); + port = simple_strtoul(argv[2], NULL, 10); + reg = simple_strtoul(argv[3], NULL, 10); + + ret = sw_reg_read(name, phyaddr, port, reg, &value); + printf("%#x\n", value); + + return ret; +} + +int do_mvsw_reg_write(const char *name, int argc, char * const argv[]) +{ + u16 value = 0, phyaddr, reg, port; + int ret; + + phyaddr = simple_strtoul(argv[1], NULL, 10); + port = simple_strtoul(argv[2], NULL, 10); + reg = simple_strtoul(argv[3], NULL, 10); + value = simple_strtoul(argv[4], NULL, 16); + + ret = sw_reg_write(name, phyaddr, port, reg, value); + + return ret; +} + + +int do_mvsw_reg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int ret; + const char *cmd, *ethname; + + if (argc < 2) + return cmd_usage(cmdtp); + + cmd = argv[1]; + --argc; + ++argv; + + if (strcmp(cmd, "read") == 0) { + if (argc < 5) + return cmd_usage(cmdtp); + ethname = argv[1]; + --argc; + ++argv; + ret = do_mvsw_reg_read(ethname, argc, argv); + } else if (strcmp(cmd, "write") == 0) { + if (argc < 6) + return cmd_usage(cmdtp); + ethname = argv[1]; + --argc; + ++argv; + ret = do_mvsw_reg_write(ethname, argc, argv); + } else + return cmd_usage(cmdtp); + + return ret; +} + +U_BOOT_CMD( + mvsw_reg, 7, 1, do_mvsw_reg, + "marvell 88e6352 switch register access", + "write ethname phyaddr port reg value\n" + "mvsw_reg read ethname phyaddr port reg\n" + ); diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index d48d4fe..0a0f40d 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -1,6 +1,9 @@ /* * Vitesse PHY drivers * + * Copyright 2010-2012 Freescale Semiconductor, Inc. + * Author: Andy Fleming + * Add vsc8662 phy support - Priyanka Jain * 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 @@ -15,10 +18,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA - * - * Copyright 2010-2011 Freescale Semiconductor, Inc. - * author Andy Fleming - * */ #include <miiphy.h> @@ -206,6 +205,16 @@ static struct phy_driver VSC8641_driver = { .shutdown = &genphy_shutdown, }; +static struct phy_driver VSC8662_driver = { + .name = "Vitesse VSC8662", + .uid = 0x70660, + .mask = 0xffff0, + .features = PHY_GBIT_FEATURES, + .config = &genphy_config_aneg, + .startup = &vitesse_startup, + .shutdown = &genphy_shutdown, +}; + /* Vitesse bought Cicada, so we'll put these here */ static struct phy_driver cis8201_driver = { .name = "CIS8201", @@ -235,6 +244,7 @@ int phy_vitesse_init(void) phy_register(&VSC8244_driver); phy_register(&VSC8211_driver); phy_register(&VSC8221_driver); + phy_register(&VSC8662_driver); phy_register(&cis8201_driver); phy_register(&cis8204_driver); diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 09af860..2d9cc32 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -394,7 +394,7 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) sh_eth_write(eth, TPAUSER_TPAUSE, TPAUSER); #endif -#if defined(CONFIG_CPU_SH7734) +#if defined(CONFIG_CPU_SH7734) || defined(CONFIG_R8A7740) sh_eth_write(eth, CONFIG_SH_ETHER_SH7734_MII, RMII_MII); #endif /* Configure phy */ diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index 3703c55..61d2df9 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -1,8 +1,8 @@ /* * sh_eth.h - Driver for Renesas SuperH ethernet controler. * - * Copyright (C) 2008, 2011 Renesas Solutions Corp. - * Copyright (c) 2008, 2011 Nobuhiro Iwamatsu + * Copyright (C) 2008 - 2012 Renesas Solutions Corp. + * Copyright (c) 2008 - 2012 Nobuhiro Iwamatsu * Copyright (c) 2007 Carlos Munoz <carlos@kenati.com> * * This program is free software; you can redistribute it and/or modify @@ -25,6 +25,7 @@ #define SHETHER_NAME "sh_eth" +#if defined(CONFIG_SH) /* Malloc returns addresses in the P1 area (cacheable). However we need to use area P2 (non-cacheable) */ #define ADDR_TO_P2(addr) ((((int)(addr) & ~0xe0000000) | 0xa0000000)) @@ -35,6 +36,12 @@ #else #define ADDR_TO_PHY(addr) ((int)(addr) & ~0xe0000000) #endif +#elif defined(CONFIG_ARM) +#define inl readl +#define outl writel +#define ADDR_TO_PHY(addr) ((int)(addr)) +#define ADDR_TO_P2(addr) (addr) +#endif /* defined(CONFIG_SH) */ /* Number of supported ports */ #define MAX_PORT_NUM 2 @@ -292,6 +299,9 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { #elif defined(CONFIG_CPU_SH7724) #define SH_ETH_TYPE_ETHER #define BASE_IO_ADDR 0xA4600000 +#elif defined(CONFIG_R8A7740) +#define SH_ETH_TYPE_GETHER +#define BASE_IO_ADDR 0xE9A00000 #endif /* diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index d5bd737..d890d60 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -28,6 +28,9 @@ #include <config.h> #include <malloc.h> #include <asm/io.h> +#include <fdtdec.h> + +DECLARE_GLOBAL_DATA_PTR; #undef DEBUG @@ -375,3 +378,30 @@ int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr, return 1; } + +#ifdef CONFIG_OF_CONTROL +int xilinx_emaclite_init(bd_t *bis) +{ + int offset = 0; + u32 ret = 0; + u32 reg; + + do { + offset = fdt_node_offset_by_compatible(gd->fdt_blob, offset, + "xlnx,xps-ethernetlite-1.00.a"); + if (offset != -1) { + reg = fdtdec_get_addr(gd->fdt_blob, offset, "reg"); + if (reg != FDT_ADDR_T_NONE) { + u32 rxpp = fdtdec_get_int(gd->fdt_blob, offset, + "xlnx,rx-ping-pong", 0); + u32 txpp = fdtdec_get_int(gd->fdt_blob, offset, + "xlnx,tx-ping-pong", 0); + ret |= xilinx_emaclite_initialize(bis, reg, + txpp, rxpp); + } + } + } while (offset != -1); + + return ret; +} +#endif diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c new file mode 100644 index 0000000..3596065 --- /dev/null +++ b/drivers/net/zynq_gem.c @@ -0,0 +1,440 @@ +/* + * (C) Copyright 2011 Michal Simek + * + * Michal SIMEK <monstr@monstr.eu> + * + * Based on Xilinx gmac driver: + * (C) Copyright 2011 Xilinx + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <net.h> +#include <config.h> +#include <malloc.h> +#include <asm/io.h> +#include <phy.h> +#include <miiphy.h> +#include <watchdog.h> + +#if !defined(CONFIG_PHYLIB) +# error XILINX_GEM_ETHERNET requires PHYLIB +#endif + +/* Bit/mask specification */ +#define ZYNQ_GEM_PHYMNTNC_OP_MASK 0x40020000 /* operation mask bits */ +#define ZYNQ_GEM_PHYMNTNC_OP_R_MASK 0x20000000 /* read operation */ +#define ZYNQ_GEM_PHYMNTNC_OP_W_MASK 0x10000000 /* write operation */ +#define ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK 23 /* Shift bits for PHYAD */ +#define ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK 18 /* Shift bits for PHREG */ + +#define ZYNQ_GEM_RXBUF_EOF_MASK 0x00008000 /* End of frame. */ +#define ZYNQ_GEM_RXBUF_SOF_MASK 0x00004000 /* Start of frame. */ +#define ZYNQ_GEM_RXBUF_LEN_MASK 0x00003FFF /* Mask for length field */ + +#define ZYNQ_GEM_RXBUF_WRAP_MASK 0x00000002 /* Wrap bit, last BD */ +#define ZYNQ_GEM_RXBUF_NEW_MASK 0x00000001 /* Used bit.. */ +#define ZYNQ_GEM_RXBUF_ADD_MASK 0xFFFFFFFC /* Mask for address */ + +/* Wrap bit, last descriptor */ +#define ZYNQ_GEM_TXBUF_WRAP_MASK 0x40000000 +#define ZYNQ_GEM_TXBUF_LAST_MASK 0x00008000 /* Last buffer */ + +#define ZYNQ_GEM_TXSR_HRESPNOK_MASK 0x00000100 /* Transmit hresp not OK */ +#define ZYNQ_GEM_TXSR_URUN_MASK 0x00000040 /* Transmit underrun */ +/* Transmit buffs exhausted mid frame */ +#define ZYNQ_GEM_TXSR_BUFEXH_MASK 0x00000010 + +#define ZYNQ_GEM_NWCTRL_TXEN_MASK 0x00000008 /* Enable transmit */ +#define ZYNQ_GEM_NWCTRL_RXEN_MASK 0x00000004 /* Enable receive */ +#define ZYNQ_GEM_NWCTRL_MDEN_MASK 0x00000010 /* Enable MDIO port */ +#define ZYNQ_GEM_NWCTRL_STARTTX_MASK 0x00000200 /* Start tx (tx_go) */ + +#define ZYNQ_GEM_NWCFG_SPEED 0x00000001 /* 100 Mbps operation */ +#define ZYNQ_GEM_NWCFG_FDEN 0x00000002 /* Full Duplex mode */ +#define ZYNQ_GEM_NWCFG_FSREM 0x00020000 /* FCS removal */ +#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000080000 /* Div pclk by 32, 80MHz */ + +#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_NWCFG_SPEED | \ + ZYNQ_GEM_NWCFG_FDEN | \ + ZYNQ_GEM_NWCFG_FSREM | \ + ZYNQ_GEM_NWCFG_MDCCLKDIV) + +#define ZYNQ_GEM_NWSR_MDIOIDLE_MASK 0x00000004 /* PHY management idle */ + +#define ZYNQ_GEM_DMACR_BLENGTH 0x00000004 /* INCR4 AHB bursts */ +/* Use full configured addressable space (8 Kb) */ +#define ZYNQ_GEM_DMACR_RXSIZE 0x00000300 +/* Use full configured addressable space (4 Kb) */ +#define ZYNQ_GEM_DMACR_TXSIZE 0x00000400 +/* Set with binary 00011000 to use 1536 byte(1*max length frame/buffer) */ +#define ZYNQ_GEM_DMACR_RXBUF 0x00180000 + +#define ZYNQ_GEM_DMACR_INIT (ZYNQ_GEM_DMACR_BLENGTH | \ + ZYNQ_GEM_DMACR_RXSIZE | \ + ZYNQ_GEM_DMACR_TXSIZE | \ + ZYNQ_GEM_DMACR_RXBUF) + +/* Device registers */ +struct zynq_gem_regs { + u32 nwctrl; /* Network Control reg */ + u32 nwcfg; /* Network Config reg */ + u32 nwsr; /* Network Status reg */ + u32 reserved1; + u32 dmacr; /* DMA Control reg */ + u32 txsr; /* TX Status reg */ + u32 rxqbase; /* RX Q Base address reg */ + u32 txqbase; /* TX Q Base address reg */ + u32 rxsr; /* RX Status reg */ + u32 reserved2[2]; + u32 idr; /* Interrupt Disable reg */ + u32 reserved3; + u32 phymntnc; /* Phy Maintaince reg */ + u32 reserved4[18]; + u32 hashl; /* Hash Low address reg */ + u32 hashh; /* Hash High address reg */ +#define LADDR_LOW 0 +#define LADDR_HIGH 1 + u32 laddr[4][LADDR_HIGH + 1]; /* Specific1 addr low/high reg */ + u32 match[4]; /* Type ID1 Match reg */ + u32 reserved6[18]; + u32 stat[44]; /* Octects transmitted Low reg - stat start */ +}; + +/* BD descriptors */ +struct emac_bd { + u32 addr; /* Next descriptor pointer */ + u32 status; +}; + +#define RX_BUF 3 + +/* Initialized, rxbd_current, rx_first_buf must be 0 after init */ +struct zynq_gem_priv { + struct emac_bd tx_bd; + struct emac_bd rx_bd[RX_BUF]; + char rxbuffers[RX_BUF * PKTSIZE_ALIGN]; + u32 rxbd_current; + u32 rx_first_buf; + int phyaddr; + struct phy_device *phydev; + struct mii_dev *bus; +}; + +static inline int mdio_wait(struct eth_device *dev) +{ + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + u32 timeout = 200; + + /* Wait till MDIO interface is ready to accept a new transaction. */ + while (--timeout) { + if (readl(®s->nwsr) & ZYNQ_GEM_NWSR_MDIOIDLE_MASK) + break; + WATCHDOG_RESET(); + } + + if (!timeout) { + printf("%s: Timeout\n", __func__); + return 1; + } + + return 0; +} + +static u32 phy_setup_op(struct eth_device *dev, u32 phy_addr, u32 regnum, + u32 op, u16 *data) +{ + u32 mgtcr; + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + + if (mdio_wait(dev)) + return 1; + + /* Construct mgtcr mask for the operation */ + mgtcr = ZYNQ_GEM_PHYMNTNC_OP_MASK | op | + (phy_addr << ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK) | + (regnum << ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK) | *data; + + /* Write mgtcr and wait for completion */ + writel(mgtcr, ®s->phymntnc); + + if (mdio_wait(dev)) + return 1; + + if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK) + *data = readl(®s->phymntnc); + + return 0; +} + +static u32 phyread(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 *val) +{ + return phy_setup_op(dev, phy_addr, regnum, + ZYNQ_GEM_PHYMNTNC_OP_R_MASK, val); +} + +static u32 phywrite(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 data) +{ + return phy_setup_op(dev, phy_addr, regnum, + ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data); +} + +static int zynq_gem_setup_mac(struct eth_device *dev) +{ + u32 i, macaddrlow, macaddrhigh; + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + + /* Set the MAC bits [31:0] in BOT */ + macaddrlow = dev->enetaddr[0]; + macaddrlow |= dev->enetaddr[1] << 8; + macaddrlow |= dev->enetaddr[2] << 16; + macaddrlow |= dev->enetaddr[3] << 24; + + /* Set MAC bits [47:32] in TOP */ + macaddrhigh = dev->enetaddr[4]; + macaddrhigh |= dev->enetaddr[5] << 8; + + for (i = 0; i < 4; i++) { + writel(0, ®s->laddr[i][LADDR_LOW]); + writel(0, ®s->laddr[i][LADDR_HIGH]); + /* Do not use MATCHx register */ + writel(0, ®s->match[i]); + } + + writel(macaddrlow, ®s->laddr[0][LADDR_LOW]); + writel(macaddrhigh, ®s->laddr[0][LADDR_HIGH]); + + return 0; +} + +static int zynq_gem_init(struct eth_device *dev, bd_t * bis) +{ + u32 i; + struct phy_device *phydev; + const u32 stat_size = (sizeof(struct zynq_gem_regs) - + offsetof(struct zynq_gem_regs, stat)) / 4; + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + struct zynq_gem_priv *priv = dev->priv; + const u32 supported = SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full; + + /* Disable all interrupts */ + writel(0xFFFFFFFF, ®s->idr); + + /* Disable the receiver & transmitter */ + writel(0, ®s->nwctrl); + writel(0, ®s->txsr); + writel(0, ®s->rxsr); + writel(0, ®s->phymntnc); + + /* Clear the Hash registers for the mac address pointed by AddressPtr */ + writel(0x0, ®s->hashl); + /* Write bits [63:32] in TOP */ + writel(0x0, ®s->hashh); + + /* Clear all counters */ + for (i = 0; i <= stat_size; i++) + readl(®s->stat[i]); + + /* Setup RxBD space */ + memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd)); + /* Create the RxBD ring */ + memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers)); + + for (i = 0; i < RX_BUF; i++) { + priv->rx_bd[i].status = 0xF0000000; + priv->rx_bd[i].addr = (u32)((char *) &(priv->rxbuffers) + + (i * PKTSIZE_ALIGN)); + } + /* WRAP bit to last BD */ + priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; + /* Write RxBDs to IP */ + writel((u32) &(priv->rx_bd), ®s->rxqbase); + + /* MAC Setup */ + /* Setup Network Configuration register */ + writel(ZYNQ_GEM_NWCFG_INIT, ®s->nwcfg); + + /* Setup for DMA Configuration register */ + writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); + + /* Setup for Network Control register, MDIO, Rx and Tx enable */ + setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK | + ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK); + + /* interface - look at tsec */ + phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0); + + phydev->supported &= supported; + phydev->advertising = phydev->supported; + priv->phydev = phydev; + phy_config(phydev); + phy_startup(phydev); + + return 0; +} + +static int zynq_gem_send(struct eth_device *dev, void *ptr, int len) +{ + u32 status; + struct zynq_gem_priv *priv = dev->priv; + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + const u32 mask = ZYNQ_GEM_TXSR_HRESPNOK_MASK | \ + ZYNQ_GEM_TXSR_URUN_MASK | ZYNQ_GEM_TXSR_BUFEXH_MASK; + + /* setup BD */ + writel((u32)&(priv->tx_bd), ®s->txqbase); + + /* Setup Tx BD */ + memset((void *) &(priv->tx_bd), 0, sizeof(struct emac_bd)); + + priv->tx_bd.addr = (u32)ptr; + priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK | + ZYNQ_GEM_TXBUF_WRAP_MASK; + + /* Start transmit */ + setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK); + + /* Read the stat register to know if the packet has been transmitted */ + status = readl(®s->txsr); + if (status & mask) + printf("Something has gone wrong here!? Status is 0x%x.\n", + status); + + /* Clear Tx status register before leaving . */ + writel(status, ®s->txsr); + return 0; +} + +/* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */ +static int zynq_gem_recv(struct eth_device *dev) +{ + int frame_len; + struct zynq_gem_priv *priv = dev->priv; + struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current]; + struct emac_bd *first_bd; + + if (!(current_bd->addr & ZYNQ_GEM_RXBUF_NEW_MASK)) + return 0; + + if (!(current_bd->status & + (ZYNQ_GEM_RXBUF_SOF_MASK | ZYNQ_GEM_RXBUF_EOF_MASK))) { + printf("GEM: SOF or EOF not set for last buffer received!\n"); + return 0; + } + + frame_len = current_bd->status & ZYNQ_GEM_RXBUF_LEN_MASK; + if (frame_len) { + NetReceive((u8 *) (current_bd->addr & + ZYNQ_GEM_RXBUF_ADD_MASK), frame_len); + + if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) + priv->rx_first_buf = priv->rxbd_current; + else { + current_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; + current_bd->status = 0xF0000000; /* FIXME */ + } + + if (current_bd->status & ZYNQ_GEM_RXBUF_EOF_MASK) { + first_bd = &priv->rx_bd[priv->rx_first_buf]; + first_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; + first_bd->status = 0xF0000000; + } + + if ((++priv->rxbd_current) >= RX_BUF) + priv->rxbd_current = 0; + + return frame_len; + } + + return 0; +} + +static void zynq_gem_halt(struct eth_device *dev) +{ + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + + /* Disable the receiver & transmitter */ + writel(0, ®s->nwctrl); +} + +static int zynq_gem_miiphyread(const char *devname, uchar addr, + uchar reg, ushort *val) +{ + struct eth_device *dev = eth_get_dev(); + int ret; + + ret = phyread(dev, addr, reg, val); + debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, *val); + return ret; +} + +static int zynq_gem_miiphy_write(const char *devname, uchar addr, + uchar reg, ushort val) +{ + struct eth_device *dev = eth_get_dev(); + + debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val); + return phywrite(dev, addr, reg, val); +} + +int zynq_gem_initialize(bd_t *bis, int base_addr) +{ + struct eth_device *dev; + struct zynq_gem_priv *priv; + + dev = calloc(1, sizeof(*dev)); + if (dev == NULL) + return -1; + + dev->priv = calloc(1, sizeof(struct zynq_gem_priv)); + if (dev->priv == NULL) { + free(dev); + return -1; + } + priv = dev->priv; + +#ifdef CONFIG_PHY_ADDR + priv->phyaddr = CONFIG_PHY_ADDR; +#else + priv->phyaddr = -1; +#endif + + sprintf(dev->name, "Gem.%x", base_addr); + + dev->iobase = base_addr; + + dev->init = zynq_gem_init; + dev->halt = zynq_gem_halt; + dev->send = zynq_gem_send; + dev->recv = zynq_gem_recv; + dev->write_hwaddr = zynq_gem_setup_mac; + + eth_register(dev); + + miiphy_register(dev->name, zynq_gem_miiphyread, zynq_gem_miiphy_write); + priv->bus = miiphy_get_dev_by_name(dev->name); + + return 1; +} diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index 1d75a82..0d46c96 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -211,6 +211,95 @@ static int fsl_pci_setup_inbound_windows(struct pci_controller *hose, return 1; } +#ifdef CONFIG_FSL_CORENET +static void fsl_pcie_boot_master(pit_t *pi) +{ + /* configure inbound window for slave's u-boot image */ + debug("PCIEBOOT - MASTER: Inbound window for slave's image; " + "Local = 0x%llx, Bus = 0x%llx, Size = 0x%x\n", + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); + struct pci_region r_inbound; + u32 sz_inbound = __ilog2_u64(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE) + - 1; + pci_set_region(&r_inbound, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + sz_inbound, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + set_inbound_window(pi--, &r_inbound, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); + + /* configure inbound window for slave's u-boot image */ + debug("PCIEBOOT - MASTER: Inbound window for slave's image; " + "Local = 0x%llx, Bus = 0x%llx, Size = 0x%x\n", + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); + pci_set_region(&r_inbound, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + sz_inbound, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + set_inbound_window(pi--, &r_inbound, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); + + /* configure inbound window for slave's ucode and ENV */ + debug("PCIEBOOT - MASTER: Inbound window for slave's " + "ucode and ENV; " + "Local = 0x%llx, Bus = 0x%llx, Size = 0x%x\n", + (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE); + sz_inbound = __ilog2_u64(CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE) + - 1; + pci_set_region(&r_inbound, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS, + sz_inbound, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + set_inbound_window(pi--, &r_inbound, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE); +} + +static void fsl_pcie_boot_master_release_slave(int port) +{ + unsigned long release_addr; + + /* now release slave's core 0 */ + switch (port) { + case 1: + release_addr = CONFIG_SYS_PCIE1_MEM_VIRT + + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET; + break; + case 2: + release_addr = CONFIG_SYS_PCIE2_MEM_VIRT + + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET; + break; + case 3: + release_addr = CONFIG_SYS_PCIE3_MEM_VIRT + + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET; + break; + default: + release_addr = 0; + break; + } + if (release_addr != 0) { + out_be32((void *)release_addr, + CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK); + debug("PCIEBOOT - MASTER: " + "Release slave successfully! Now the slave should start up!\n"); + } else { + debug("PCIEBOOT - MASTER: " + "Release slave failed!\n"); + } +} +#endif + void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info) { u32 cfg_addr = (u32)&((ccsr_fsl_pci_t *)pci_info->regs)->cfg_addr; @@ -295,8 +384,25 @@ void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info) /* see if we are a PCIe or PCI controller */ pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap); +#ifdef CONFIG_FSL_CORENET + /* boot from PCIE --master */ + char *s = getenv("bootmaster"); + char pcie[6]; + sprintf(pcie, "PCIE%d", pci_info->pci_num); + + if (s && (strcmp(s, pcie) == 0)) { + debug("PCIEBOOT - MASTER: Master port [ %d ] for pcie boot.\n", + pci_info->pci_num); + fsl_pcie_boot_master((pit_t *)pi); + } else { + /* inbound */ + inbound = fsl_pci_setup_inbound_windows(hose, + out_lo, pcie_cap, pi); + } +#else /* inbound */ inbound = fsl_pci_setup_inbound_windows(hose, out_lo, pcie_cap, pi); +#endif for (r = 0; r < hose->region_count; r++) debug("PCI reg:%d %016llx:%016llx %016llx %08lx\n", r, @@ -488,6 +594,16 @@ int fsl_pci_init_port(struct fsl_pci_info *pci_info, if (fsl_is_pci_agent(hose)) { fsl_pci_config_unlock(hose); hose->last_busno = hose->first_busno; +#ifdef CONFIG_FSL_CORENET + } else { + /* boot from PCIE --master releases slave's core 0 */ + char *s = getenv("bootmaster"); + char pcie[6]; + sprintf(pcie, "PCIE%d", pci_info->pci_num); + + if (s && (strcmp(s, pcie) == 0)) + fsl_pcie_boot_master_release_slave(pci_info->pci_num); +#endif } pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 398542b..d864f13 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -151,13 +151,14 @@ void pci_register_hose(struct pci_controller* hose) *phose = hose; } -struct pci_controller *pci_bus_to_hose (int bus) +struct pci_controller *pci_bus_to_hose(int bus) { struct pci_controller *hose; - for (hose = hose_head; hose; hose = hose->next) + for (hose = hose_head; hose; hose = hose->next) { if (bus >= hose->first_busno && bus <= hose->last_busno) return hose; + } printf("pci_bus_to_hose() failed\n"); return NULL; @@ -196,21 +197,20 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) pci_dev_t bdf; int i, bus, found_multi = 0; - for (hose = hose_head; hose; hose = hose->next) - { + for (hose = hose_head; hose; hose = hose->next) { #ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE for (bus = hose->last_busno; bus >= hose->first_busno; bus--) #else for (bus = hose->first_busno; bus <= hose->last_busno; bus++) #endif - for (bdf = PCI_BDF(bus,0,0); + for (bdf = PCI_BDF(bus, 0, 0); #if defined(CONFIG_ELPPC) || defined(CONFIG_PPMC7XX) - bdf < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1); + bdf < PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1, + PCI_MAX_PCI_FUNCTIONS - 1); #else - bdf < PCI_BDF(bus+1,0,0); + bdf < PCI_BDF(bus + 1, 0, 0); #endif - bdf += PCI_BDF(0,0,1)) - { + bdf += PCI_BDF(0, 0, 1)) { if (!PCI_FUNC(bdf)) { pci_read_config_byte(bdf, PCI_HEADER_TYPE, @@ -229,19 +229,19 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) PCI_DEVICE_ID, &device); - for (i=0; ids[i].vendor != 0; i++) + for (i = 0; ids[i].vendor != 0; i++) { if (vendor == ids[i].vendor && - device == ids[i].device) - { + device == ids[i].device) { if (index <= 0) return bdf; index--; } + } } } - return (-1); + return -1; } pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index) @@ -258,7 +258,7 @@ pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index) * */ -int __pci_hose_phys_to_bus (struct pci_controller *hose, +int __pci_hose_phys_to_bus(struct pci_controller *hose, phys_addr_t phys_addr, unsigned long flags, unsigned long skip_mask, @@ -297,12 +297,14 @@ pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose, int ret; if (!hose) { - puts ("pci_hose_phys_to_bus: invalid hose\n"); + puts("pci_hose_phys_to_bus: invalid hose\n"); return bus_addr; } - /* if PCI_REGION_MEM is set we do a two pass search with preference - * on matches that don't have PCI_REGION_SYS_MEMORY set */ + /* + * if PCI_REGION_MEM is set we do a two pass search with preference + * on matches that don't have PCI_REGION_SYS_MEMORY set + */ if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) { ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, PCI_REGION_SYS_MEMORY, &bus_addr); @@ -313,12 +315,12 @@ pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose, ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr); if (ret) - puts ("pci_hose_phys_to_bus: invalid physical address\n"); + puts("pci_hose_phys_to_bus: invalid physical address\n"); return bus_addr; } -int __pci_hose_bus_to_phys (struct pci_controller *hose, +int __pci_hose_bus_to_phys(struct pci_controller *hose, pci_addr_t bus_addr, unsigned long flags, unsigned long skip_mask, @@ -354,12 +356,14 @@ phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose, int ret; if (!hose) { - puts ("pci_hose_bus_to_phys: invalid hose\n"); + puts("pci_hose_bus_to_phys: invalid hose\n"); return phys_addr; } - /* if PCI_REGION_MEM is set we do a two pass search with preference - * on matches that don't have PCI_REGION_SYS_MEMORY set */ + /* + * if PCI_REGION_MEM is set we do a two pass search with preference + * on matches that don't have PCI_REGION_SYS_MEMORY set + */ if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) { ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, PCI_REGION_SYS_MEMORY, &phys_addr); @@ -370,7 +374,7 @@ phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose, ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr); if (ret) - puts ("pci_hose_bus_to_phys: invalid physical address\n"); + puts("pci_hose_bus_to_phys: invalid physical address\n"); return phys_addr; } @@ -385,20 +389,21 @@ int pci_hose_config_device(struct pci_controller *hose, pci_addr_t mem, unsigned long command) { - unsigned int bar_response, old_command; + u32 bar_response; + unsigned int old_command; pci_addr_t bar_value; pci_size_t bar_size; unsigned char pin; int bar, found_mem64; - debug ("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n", - io, (u64)mem, command); + debug("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n", io, + (u64)mem, command); - pci_hose_write_config_dword (hose, dev, PCI_COMMAND, 0); + pci_hose_write_config_dword(hose, dev, PCI_COMMAND, 0); for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar += 4) { - pci_hose_write_config_dword (hose, dev, bar, 0xffffffff); - pci_hose_read_config_dword (hose, dev, bar, &bar_response); + pci_hose_write_config_dword(hose, dev, bar, 0xffffffff); + pci_hose_read_config_dword(hose, dev, bar, &bar_response); if (!bar_response) continue; @@ -418,8 +423,10 @@ int pci_hose_config_device(struct pci_controller *hose, PCI_BASE_ADDRESS_MEM_TYPE_64) { u32 bar_response_upper; u64 bar64; - pci_hose_write_config_dword(hose, dev, bar+4, 0xffffffff); - pci_hose_read_config_dword(hose, dev, bar+4, &bar_response_upper); + pci_hose_write_config_dword(hose, dev, bar + 4, + 0xffffffff); + pci_hose_read_config_dword(hose, dev, bar + 4, + &bar_response_upper); bar64 = ((u64)bar_response_upper << 32) | bar_response; @@ -442,27 +449,28 @@ int pci_hose_config_device(struct pci_controller *hose, if (found_mem64) { bar += 4; #ifdef CONFIG_SYS_PCI_64BIT - pci_hose_write_config_dword(hose, dev, bar, (u32)(bar_value>>32)); + pci_hose_write_config_dword(hose, dev, bar, + (u32)(bar_value >> 32)); #else - pci_hose_write_config_dword (hose, dev, bar, 0x00000000); + pci_hose_write_config_dword(hose, dev, bar, 0x00000000); #endif } } /* Configure Cache Line Size Register */ - pci_hose_write_config_byte (hose, dev, PCI_CACHE_LINE_SIZE, 0x08); + pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08); /* Configure Latency Timer */ - pci_hose_write_config_byte (hose, dev, PCI_LATENCY_TIMER, 0x80); + pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); /* Disable interrupt line, if device says it wants to use interrupts */ - pci_hose_read_config_byte (hose, dev, PCI_INTERRUPT_PIN, &pin); + pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin); if (pin != 0) { - pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE, 0xff); + pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 0xff); } - pci_hose_read_config_dword (hose, dev, PCI_COMMAND, &old_command); - pci_hose_write_config_dword (hose, dev, PCI_COMMAND, + pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &old_command); + pci_hose_write_config_dword(hose, dev, PCI_COMMAND, (old_command & 0xffff0000) | command); return 0; @@ -500,7 +508,8 @@ void pci_cfgfunc_config_device(struct pci_controller *hose, pci_dev_t dev, struct pci_config_table *entry) { - pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1], entry->priv[2]); + pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1], + entry->priv[2]); } void pci_cfgfunc_do_nothing(struct pci_controller *hose, @@ -509,10 +518,7 @@ void pci_cfgfunc_do_nothing(struct pci_controller *hose, } /* - * - */ - -/* HJF: Changed this to return int. I think this is required + * HJF: Changed this to return int. I think this is required * to get the correct result when scanning bridges */ extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev); @@ -618,10 +624,12 @@ int pci_print_dev(struct pci_controller *hose, pci_dev_t dev) int pci_hose_scan_bus(struct pci_controller *hose, int bus) { - unsigned int sub_bus, found_multi=0; + unsigned int sub_bus, found_multi = 0; unsigned short vendor, device, class; unsigned char header_type; +#ifndef CONFIG_PCI_PNP struct pci_config_table *cfg; +#endif pci_dev_t dev; #ifdef CONFIG_PCI_SCAN_SHOW static int indent = 0; @@ -630,8 +638,9 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus) sub_bus = bus; for (dev = PCI_BDF(bus,0,0); - dev < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1); - dev += PCI_BDF(0,0,1)) { + dev < PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1, + PCI_MAX_PCI_FUNCTIONS - 1); + dev += PCI_BDF(0, 0, 1)) { if (pci_skip_dev(hose, dev)) continue; @@ -649,8 +658,8 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus) if (!PCI_FUNC(dev)) found_multi = header_type & 0x80; - debug ("PCI Scan: Found Bus %d, Device %d, Function %d\n", - PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev) ); + debug("PCI Scan: Found Bus %d, Device %d, Function %d\n", + PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev)); pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device); pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class); @@ -668,18 +677,16 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus) } #endif +#ifdef CONFIG_PCI_PNP + sub_bus = max(pciauto_config_device(hose, dev), sub_bus); +#else cfg = pci_find_config(hose, class, vendor, device, PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev)); if (cfg) { cfg->config_device(hose, dev, cfg); sub_bus = max(sub_bus, hose->current_busno); -#ifdef CONFIG_PCI_PNP - } else { - int n = pciauto_config_device(hose, dev); - - sub_bus = max(sub_bus, n); -#endif } +#endif #ifdef CONFIG_PCI_SCAN_SHOW indent--; @@ -711,10 +718,11 @@ int pci_hose_scan(struct pci_controller *hose) } #endif /* CONFIG_PCI_BOOTDELAY */ - /* Start scan at current_busno. + /* + * Start scan at current_busno. * PCIe will start scan at first_busno+1. */ - /* For legacy support, ensure current>=first */ + /* For legacy support, ensure current >= first */ if (hose->first_busno > hose->current_busno) hose->current_busno = hose->first_busno; #ifdef CONFIG_PCI_PNP diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 87ee2c2..cd78030 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -35,7 +35,7 @@ * */ -void pciauto_region_init(struct pci_region* res) +void pciauto_region_init(struct pci_region *res) { /* * Avoid allocating PCI resources from address 0 -- this is illegal @@ -50,7 +50,8 @@ void pciauto_region_align(struct pci_region *res, pci_size_t size) res->bus_lower = ((res->bus_lower - 1) | (size - 1)) + 1; } -int pciauto_region_allocate(struct pci_region* res, pci_size_t size, pci_addr_t *bar) +int pciauto_region_allocate(struct pci_region *res, pci_size_t size, + pci_addr_t *bar) { pci_addr_t addr; @@ -88,58 +89,77 @@ void pciauto_setup_device(struct pci_controller *hose, struct pci_region *prefetch, struct pci_region *io) { - unsigned int bar_response; - pci_addr_t bar_value; + u32 bar_response; pci_size_t bar_size; - unsigned int cmdstat = 0; - struct pci_region *bar_res; + u16 cmdstat = 0; int bar, bar_nr = 0; +#ifndef CONFIG_PCI_ENUM_ONLY + pci_addr_t bar_value; + struct pci_region *bar_res; int found_mem64 = 0; +#endif - pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat); + pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER; - for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_0 + (bars_num*4); bar += 4) { + for (bar = PCI_BASE_ADDRESS_0; + bar < PCI_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) { /* Tickle the BAR and get the response */ +#ifndef CONFIG_PCI_ENUM_ONLY pci_hose_write_config_dword(hose, dev, bar, 0xffffffff); +#endif pci_hose_read_config_dword(hose, dev, bar, &bar_response); /* If BAR is not implemented go to the next BAR */ if (!bar_response) continue; +#ifndef CONFIG_PCI_ENUM_ONLY found_mem64 = 0; +#endif /* Check the BAR type and set our address mask */ if (bar_response & PCI_BASE_ADDRESS_SPACE) { bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK)) & 0xffff) + 1; +#ifndef CONFIG_PCI_ENUM_ONLY bar_res = io; +#endif DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ", bar_nr, (u64)bar_size); } else { - if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) { u32 bar_response_upper; u64 bar64; - pci_hose_write_config_dword(hose, dev, bar+4, 0xffffffff); - pci_hose_read_config_dword(hose, dev, bar+4, &bar_response_upper); + +#ifndef CONFIG_PCI_ENUM_ONLY + pci_hose_write_config_dword(hose, dev, bar + 4, + 0xffffffff); +#endif + pci_hose_read_config_dword(hose, dev, bar + 4, + &bar_response_upper); bar64 = ((u64)bar_response_upper << 32) | bar_response; bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1; +#ifndef CONFIG_PCI_ENUM_ONLY found_mem64 = 1; +#endif } else { bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1); } +#ifndef CONFIG_PCI_ENUM_ONLY if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH)) bar_res = prefetch; else bar_res = mem; +#endif DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%llx, ", bar_nr, (u64)bar_size); } +#ifndef CONFIG_PCI_ENUM_ONLY if (pciauto_region_allocate(bar_res, bar_size, &bar_value) == 0) { /* Write it out and update our limit */ pci_hose_write_config_dword(hose, dev, bar, (u32)bar_value); @@ -158,16 +178,17 @@ void pciauto_setup_device(struct pci_controller *hose, #endif } - cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ? - PCI_COMMAND_IO : PCI_COMMAND_MEMORY; } +#endif + cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ? + PCI_COMMAND_IO : PCI_COMMAND_MEMORY; DEBUGF("\n"); bar_nr++; } - pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat); + pci_hose_write_config_word(hose, dev, PCI_COMMAND, cmdstat); pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, CONFIG_SYS_PCI_CACHE_LINE_SIZE); pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); @@ -179,9 +200,9 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose, struct pci_region *pci_mem = hose->pci_mem; struct pci_region *pci_prefetch = hose->pci_prefetch; struct pci_region *pci_io = hose->pci_io; - unsigned int cmdstat; + u16 cmdstat; - pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat); + pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); /* Configure bus number registers */ pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, @@ -229,7 +250,8 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose, } /* Enable memory and I/O accesses, enable bus master */ - pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER); + pci_hose_write_config_word(hose, dev, PCI_COMMAND, + cmdstat | PCI_COMMAND_MASTER); } void pciauto_postscan_setup_bridge(struct pci_controller *hose, @@ -248,7 +270,7 @@ void pciauto_postscan_setup_bridge(struct pci_controller *hose, pciauto_region_align(pci_mem, 0x100000); pci_hose_write_config_word(hose, dev, PCI_MEMORY_LIMIT, - (pci_mem->bus_lower-1) >> 16); + (pci_mem->bus_lower - 1) >> 16); } if (pci_prefetch) { @@ -256,7 +278,7 @@ void pciauto_postscan_setup_bridge(struct pci_controller *hose, pciauto_region_align(pci_prefetch, 0x100000); pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, - (pci_prefetch->bus_lower-1) >> 16); + (pci_prefetch->bus_lower - 1) >> 16); } if (pci_io) { @@ -264,9 +286,9 @@ void pciauto_postscan_setup_bridge(struct pci_controller *hose, pciauto_region_align(pci_io, 0x1000); pci_hose_write_config_byte(hose, dev, PCI_IO_LIMIT, - ((pci_io->bus_lower-1) & 0x0000f000) >> 8); + ((pci_io->bus_lower - 1) & 0x0000f000) >> 8); pci_hose_write_config_word(hose, dev, PCI_IO_LIMIT_UPPER16, - ((pci_io->bus_lower-1) & 0xffff0000) >> 16); + ((pci_io->bus_lower - 1) & 0xffff0000) >> 16); } } @@ -280,7 +302,7 @@ void pciauto_config_init(struct pci_controller *hose) hose->pci_io = hose->pci_mem = NULL; - for (i=0; i<hose->region_count; i++) { + for (i = 0; i < hose->region_count; i++) { switch(hose->regions[i].flags) { case PCI_REGION_IO: if (!hose->pci_io || @@ -338,7 +360,8 @@ void pciauto_config_init(struct pci_controller *hose) } } -/* HJF: Changed this to return int. I think this is required +/* + * HJF: Changed this to return int. I think this is required * to get the correct result when scanning bridges */ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) @@ -350,16 +373,11 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class); - switch(class) { - case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */ - DEBUGF("PCI AutoConfig: Found PowerPC device\n"); - pciauto_setup_device(hose, dev, 6, hose->pci_mem, - hose->pci_prefetch, hose->pci_io); - break; - + switch (class) { case PCI_CLASS_BRIDGE_PCI: hose->current_busno++; - pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_prefetch, hose->pci_io); + pciauto_setup_device(hose, dev, 2, hose->pci_mem, + hose->pci_prefetch, hose->pci_io); DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev)); @@ -385,14 +403,20 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) return sub_bus; } - pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io); + pciauto_setup_device(hose, dev, 6, hose->pci_mem, + hose->pci_prefetch, hose->pci_io); break; case PCI_CLASS_BRIDGE_CARDBUS: - /* just do a minimal setup of the bridge, let the OS take care of the rest */ - pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io); + /* + * just do a minimal setup of the bridge, + * let the OS take care of the rest + */ + pciauto_setup_device(hose, dev, 0, hose->pci_mem, + hose->pci_prefetch, hose->pci_io); - DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n", PCI_DEV(dev)); + DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n", + PCI_DEV(dev)); hose->current_busno++; break; @@ -412,11 +436,17 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) * the PIMMR window to be allocated (BAR0 - 1MB size) */ DEBUGF("PCI Autoconfig: Broken bridge found, only minimal config\n"); - pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io); + pciauto_setup_device(hose, dev, 0, hose->pci_mem, + hose->pci_prefetch, hose->pci_io); break; #endif + + case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */ + DEBUGF("PCI AutoConfig: Found PowerPC device\n"); + default: - pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io); + pciauto_setup_device(hose, dev, 6, hose->pci_mem, + hose->pci_prefetch, hose->pci_io); break; } diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c index 216c898..e6ae709 100644 --- a/drivers/qe/uec.c +++ b/drivers/qe/uec.c @@ -580,8 +580,7 @@ static void phy_change(struct eth_device *dev) { uec_private_t *uec = (uec_private_t *)dev->priv; -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); /* QE9 and QE12 need to be set for enabling QE MII managment signals */ @@ -592,8 +591,7 @@ static void phy_change(struct eth_device *dev) /* Update the link, speed, duplex */ uec->mii_info->phyinfo->read_status(uec->mii_info); -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) /* * QE12 is muxed with LBCTL, it needs to be released for enabling * LBCTL signal for LBC usage. @@ -1208,16 +1206,14 @@ static int uec_init(struct eth_device* dev, bd_t *bd) uec_private_t *uec; int err, i; struct phy_info *curphy; -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); #endif uec = (uec_private_t *)dev->priv; if (uec->the_first_run == 0) { -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) /* QE9 and QE12 need to be set for enabling QE MII managment signals */ setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_QE9); setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_QE12); @@ -1249,8 +1245,7 @@ static int uec_init(struct eth_device* dev, bd_t *bd) udelay(100000); } while (1); -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) /* QE12 needs to be released for enabling LBCTL signal*/ clrbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_QE12); #endif diff --git a/drivers/rtc/pcf8563.c b/drivers/rtc/pcf8563.c index 339e5f6..a028533 100644 --- a/drivers/rtc/pcf8563.c +++ b/drivers/rtc/pcf8563.c @@ -72,7 +72,7 @@ int rtc_get (struct rtc_time *tmp) tmp->tm_hour = bcd2bin (hour & 0x3F); tmp->tm_mday = bcd2bin (mday & 0x3F); tmp->tm_mon = bcd2bin (mon_cent & 0x1F); - tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900); + tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 1900 : 2000); tmp->tm_wday = bcd2bin (wday & 0x07); tmp->tm_yday = 0; tmp->tm_isdst= 0; @@ -94,7 +94,7 @@ int rtc_set (struct rtc_time *tmp) rtc_write (0x08, bin2bcd(tmp->tm_year % 100)); - century = (tmp->tm_year >= 2000) ? 0x80 : 0; + century = (tmp->tm_year >= 2000) ? 0 : 0x80; rtc_write (0x07, bin2bcd(tmp->tm_mon) | century); rtc_write (0x06, bin2bcd(tmp->tm_wday)); diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 3a38f9e..2bdb68b 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -89,11 +89,17 @@ int uartlite_serial_tstc(const int port) return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA; } +static int uartlite_serial_init(const int port) +{ + if (userial_ports[port]) + return 0; + return -1; +} + #if !defined(CONFIG_SERIAL_MULTI) int serial_init(void) { - /* FIXME: Nothing for now. We should initialize fifo, etc */ - return 0; + return uartlite_serial_init(0); } void serial_setbrg(void) @@ -126,7 +132,7 @@ int serial_tstc(void) /* Multi serial device functions */ #define DECLARE_ESERIAL_FUNCTIONS(port) \ int userial##port##_init(void) \ - { return(0); } \ + { return uartlite_serial_init(port); } \ void userial##port##_setbrg(void) {} \ int userial##port##_getc(void) \ { return uartlite_serial_getc(port); } \ @@ -163,17 +169,15 @@ struct serial_device uartlite_serial3_device = __weak struct serial_device *default_serial_console(void) { -# ifdef XILINX_UARTLITE_BASEADDR - return &uartlite_serial0_device; -# endif /* XILINX_UARTLITE_BASEADDR */ -# ifdef XILINX_UARTLITE_BASEADDR1 - return &uartlite_serial1_device; -# endif /* XILINX_UARTLITE_BASEADDR1 */ -# ifdef XILINX_UARTLITE_BASEADDR2 - return &uartlite_serial2_device; -# endif /* XILINX_UARTLITE_BASEADDR2 */ -# ifdef XILINX_UARTLITE_BASEADDR3 - return &uartlite_serial3_device; -# endif /* XILINX_UARTLITE_BASEADDR3 */ + if (userial_ports[0]) + return &uartlite_serial0_device; + if (userial_ports[1]) + return &uartlite_serial1_device; + if (userial_ports[2]) + return &uartlite_serial2_device; + if (userial_ports[3]) + return &uartlite_serial3_device; + + return NULL; } #endif /* CONFIG_SERIAL_MULTI */ diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 80b981f..f0b82c6 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -32,6 +32,7 @@ COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o COBJS-$(CONFIG_CF_SPI) += cf_spi.o +COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o diff --git a/drivers/spi/cf_qspi.c b/drivers/spi/cf_qspi.c new file mode 100644 index 0000000..72dd1a5 --- /dev/null +++ b/drivers/spi/cf_qspi.c @@ -0,0 +1,373 @@ +/* + * Freescale Coldfire Queued SPI driver + * + * NOTE: + * This driver is written to transfer 8 bit at-a-time and uses the dedicated + * SPI slave select pins as bit-banged GPIO to work with spi_flash subsystem. + * + * + * Copyright (C) 2011 Ruggedcom, Inc. + * Richard Retanubun (richardretanubun@freescale.com) + * + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <malloc.h> +#include <spi.h> +#include <asm/immap.h> +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define clamp(x, low, high) (min(max(low, x), high)) +#define to_cf_qspi_slave(s) container_of(s, struct cf_qspi_slave, s) + +struct cf_qspi_slave { + struct spi_slave slave; /* Specific bus:cs ID for each device */ + qspi_t *regs; /* Pointer to SPI controller registers */ + u16 qmr; /* QMR: Queued Mode Register */ + u16 qwr; /* QWR: Queued Wrap Register */ + u16 qcr; /* QCR: Queued Command Ram */ +}; + +/* Register write wrapper functions */ +static void write_qmr(volatile qspi_t *qspi, u16 val) { qspi->mr = val; } +static void write_qdlyr(volatile qspi_t *qspi, u16 val) { qspi->dlyr = val; } +static void write_qwr(volatile qspi_t *qspi, u16 val) { qspi->wr = val; } +static void write_qir(volatile qspi_t *qspi, u16 val) { qspi->ir = val; } +static void write_qar(volatile qspi_t *qspi, u16 val) { qspi->ar = val; } +static void write_qdr(volatile qspi_t *qspi, u16 val) { qspi->dr = val; } +/* Register read wrapper functions */ +static u16 read_qdlyr(volatile qspi_t *qspi) { return qspi->dlyr; } +static u16 read_qwr(volatile qspi_t *qspi) { return qspi->wr; } +static u16 read_qir(volatile qspi_t *qspi) { return qspi->ir; } +static u16 read_qdr(volatile qspi_t *qspi) { return qspi->dr; } + +/* These call points may be different for each ColdFire CPU */ +extern void cfspi_port_conf(void); +static void cfspi_cs_activate(uint bus, uint cs, uint cs_active_high); +static void cfspi_cs_deactivate(uint bus, uint cs, uint cs_active_high); + +int spi_claim_bus(struct spi_slave *slave) +{ + return 0; +} +void spi_release_bus(struct spi_slave *slave) +{ +} + +__attribute__((weak)) +void spi_init(void) +{ + cfspi_port_conf(); +} + +__attribute__((weak)) +void spi_cs_activate(struct spi_slave *slave) +{ + struct cf_qspi_slave *dev = to_cf_qspi_slave(slave); + + cfspi_cs_activate(slave->bus, slave->cs, !(dev->qwr & QSPI_QWR_CSIV)); +} + +__attribute__((weak)) +void spi_cs_deactivate(struct spi_slave *slave) +{ + struct cf_qspi_slave *dev = to_cf_qspi_slave(slave); + + cfspi_cs_deactivate(slave->bus, slave->cs, !(dev->qwr & QSPI_QWR_CSIV)); +} + +__attribute__((weak)) +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + /* Only 1 bus and 4 chipselect per controller */ + if (bus == 0 && (cs >= 0 && cs < 4)) + return 1; + else + return 0; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct cf_qspi_slave *dev = to_cf_qspi_slave(slave); + + free(dev); +} + +/* Translate information given by spi_setup_slave to members of cf_qspi_slave */ +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct cf_qspi_slave *dev = NULL; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + dev = malloc(sizeof(struct cf_qspi_slave)); + if (!dev) + return NULL; + + /* Initialize to known value */ + dev->slave.bus = bus; + dev->slave.cs = cs; + dev->regs = (qspi_t *)MMAP_QSPI; + dev->qmr = 0; + dev->qwr = 0; + dev->qcr = 0; + + + /* Map max_hz to QMR[BAUD] */ + if (max_hz == 0) /* Go as fast as possible */ + dev->qmr = 2u; + else /* Get the closest baud rate */ + dev->qmr = clamp(((gd->bus_clk >> 2) + max_hz - 1)/max_hz, + 2u, 255u); + + /* Map mode to QMR[CPOL] and QMR[CPHA] */ + if (mode & SPI_CPOL) + dev->qmr |= QSPI_QMR_CPOL; + + if (mode & SPI_CPHA) + dev->qmr |= QSPI_QMR_CPHA; + + /* Hardcode bit length to 8 bit per transter */ + dev->qmr |= QSPI_QMR_BITS_8; + + /* Set QMR[MSTR] to enable QSPI as master */ + dev->qmr |= QSPI_QMR_MSTR; + + /* + * Set QCR and QWR to default values for spi flash operation. + * If more custom QCR and QRW are needed, overload mode variable + */ + dev->qcr = (QSPI_QDR_CONT | QSPI_QDR_BITSE); + + if (!(mode & SPI_CS_HIGH)) + dev->qwr |= QSPI_QWR_CSIV; + + return &dev->slave; +} + +/* Transfer 8 bit at a time */ +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + struct cf_qspi_slave *dev = to_cf_qspi_slave(slave); + volatile qspi_t *qspi = dev->regs; + u8 *txbuf = (u8 *)dout; + u8 *rxbuf = (u8 *)din; + u32 count = ((bitlen / 8) + (bitlen % 8 ? 1 : 0)); + u32 n, i = 0; + + /* Sanitize arguments */ + if (slave == NULL) { + printf("%s: NULL slave ptr\n", __func__); + return -1; + } + + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(slave); + + /* There is something to send, lets process it. spi_xfer is also called + * just to toggle chip select, so bitlen of 0 is valid */ + if (count > 0) { + /* + * NOTE: Since chip select is driven as a bit-bang-ed GPIO + * using spi_cs_activate() and spi_cs_deactivate(), + * the chip select settings inside the controller + * (i.e. QCR[CONT] and QWR[CSIV]) are moot. The bits are set to + * keep the controller settings consistent with the actual + * operation of the bus. + */ + + /* Write the slave device's settings for the controller.*/ + write_qmr(qspi, dev->qmr); + write_qwr(qspi, dev->qwr); + + /* Limit transfer to 16 at a time */ + n = min(count, 16u); + do { + /* Setup queue end point */ + write_qwr(qspi, ((read_qwr(qspi) & QSPI_QWR_ENDQP_MASK) + | QSPI_QWR_ENDQP((n-1)))); + + /* Write Command RAM */ + write_qar(qspi, QSPI_QAR_CMD); + for (i = 0; i < n; ++i) + write_qdr(qspi, dev->qcr); + + /* Write TxBuf, if none given, fill with ZEROes */ + write_qar(qspi, QSPI_QAR_TRANS); + if (txbuf) { + for (i = 0; i < n; ++i) + write_qdr(qspi, *txbuf++); + } else { + for (i = 0; i < n; ++i) + write_qdr(qspi, 0); + } + + /* Clear QIR[SPIF] by writing a 1 to it */ + write_qir(qspi, read_qir(qspi) | QSPI_QIR_SPIF); + /* Set QDLYR[SPE] to start sending */ + write_qdlyr(qspi, read_qdlyr(qspi) | QSPI_QDLYR_SPE); + + /* Poll QIR[SPIF] for transfer completion */ + while ((read_qir(qspi) & QSPI_QIR_SPIF) != 1) + udelay(1); + + /* If given read RxBuf, load data to it */ + if (rxbuf) { + write_qar(qspi, QSPI_QAR_RECV); + for (i = 0; i < n; ++i) + *rxbuf++ = read_qdr(qspi); + } + + /* Decrement count */ + count -= n; + } while (count); + } + + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); + + return 0; +} + +/* Each MCF CPU may have different pin assignments for chip selects. */ +#if defined(CONFIG_M5271) +/* Assert chip select, val = [1|0] , dir = out, mode = GPIO */ +void cfspi_cs_activate(uint bus, uint cs, uint cs_active_high) +{ + debug("%s: bus %d cs %d cs_active_high %d\n", + __func__, bus, cs, cs_active_high); + + switch (cs) { + case 0: /* QSPI_CS[0] = PQSPI[3] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PPDSDR_QSPI, 0x08); + else + mbar_writeByte(MCF_GPIO_PCLRR_QSPI, 0xF7); + + mbar_writeByte(MCF_GPIO_PDDR_QSPI, + mbar_readByte(MCF_GPIO_PDDR_QSPI) | 0x08); + + mbar_writeByte(MCF_GPIO_PAR_QSPI, + mbar_readByte(MCF_GPIO_PAR_QSPI) & 0xDF); + break; + case 1: /* QSPI_CS[1] = PQSPI[4] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PPDSDR_QSPI, 0x10); + else + mbar_writeByte(MCF_GPIO_PCLRR_QSPI, 0xEF); + + mbar_writeByte(MCF_GPIO_PDDR_QSPI, + mbar_readByte(MCF_GPIO_PDDR_QSPI) | 0x10); + + mbar_writeByte(MCF_GPIO_PAR_QSPI, + mbar_readByte(MCF_GPIO_PAR_QSPI) & 0x3F); + break; + case 2: /* QSPI_CS[2] = PTIMER[7] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PPDSDR_TIMER, 0x80); + else + mbar_writeByte(MCF_GPIO_PCLRR_TIMER, 0x7F); + + mbar_writeByte(MCF_GPIO_PDDR_TIMER, + mbar_readByte(MCF_GPIO_PDDR_TIMER) | 0x80); + + mbar_writeShort(MCF_GPIO_PAR_TIMER, + mbar_readShort(MCF_GPIO_PAR_TIMER) & 0x3FFF); + break; + case 3: /* QSPI_CS[3] = PTIMER[3] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PPDSDR_TIMER, 0x08); + else + mbar_writeByte(MCF_GPIO_PCLRR_TIMER, 0xF7); + + mbar_writeByte(MCF_GPIO_PDDR_TIMER, + mbar_readByte(MCF_GPIO_PDDR_TIMER) | 0x08); + + mbar_writeShort(MCF_GPIO_PAR_TIMER, + mbar_readShort(MCF_GPIO_PAR_TIMER) & 0xFF3F); + break; + } +} + +/* Deassert chip select, val = [1|0], dir = in, mode = GPIO + * direction set as IN to undrive the pin, external pullup/pulldown will bring + * bus to deassert state. + */ +void cfspi_cs_deactivate(uint bus, uint cs, uint cs_active_high) +{ + debug("%s: bus %d cs %d cs_active_high %d\n", + __func__, bus, cs, cs_active_high); + + switch (cs) { + case 0: /* QSPI_CS[0] = PQSPI[3] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PCLRR_QSPI, 0xF7); + else + mbar_writeByte(MCF_GPIO_PPDSDR_QSPI, 0x08); + + mbar_writeByte(MCF_GPIO_PDDR_QSPI, + mbar_readByte(MCF_GPIO_PDDR_QSPI) & 0xF7); + + mbar_writeByte(MCF_GPIO_PAR_QSPI, + mbar_readByte(MCF_GPIO_PAR_QSPI) & 0xDF); + break; + case 1: /* QSPI_CS[1] = PQSPI[4] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PCLRR_QSPI, 0xEF); + else + mbar_writeByte(MCF_GPIO_PPDSDR_QSPI, 0x10); + + mbar_writeByte(MCF_GPIO_PDDR_QSPI, + mbar_readByte(MCF_GPIO_PDDR_QSPI) & 0xEF); + + mbar_writeByte(MCF_GPIO_PAR_QSPI, + mbar_readByte(MCF_GPIO_PAR_QSPI) & 0x3F); + break; + case 2: /* QSPI_CS[2] = PTIMER[7] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PCLRR_TIMER, 0x7F); + else + mbar_writeByte(MCF_GPIO_PPDSDR_TIMER, 0x80); + + mbar_writeByte(MCF_GPIO_PDDR_TIMER, + mbar_readByte(MCF_GPIO_PDDR_TIMER) & 0x7F); + + mbar_writeShort(MCF_GPIO_PAR_TIMER, + mbar_readShort(MCF_GPIO_PAR_TIMER) & 0x3FFF); + break; + case 3: /* QSPI_CS[3] = PTIMER[3] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PCLRR_TIMER, 0xF7); + else + mbar_writeByte(MCF_GPIO_PPDSDR_TIMER, 0x08); + + mbar_writeByte(MCF_GPIO_PDDR_TIMER, + mbar_readByte(MCF_GPIO_PDDR_TIMER) & 0xF7); + + mbar_writeShort(MCF_GPIO_PAR_TIMER, + mbar_readShort(MCF_GPIO_PAR_TIMER) & 0xFF3F); + break; + } +} +#endif /* CONFIG_M5271 */ diff --git a/drivers/spi/mpc8xxx_spi.c b/drivers/spi/mpc8xxx_spi.c index 44ab39d..4e46041 100644 --- a/drivers/spi/mpc8xxx_spi.c +++ b/drivers/spi/mpc8xxx_spi.c @@ -124,6 +124,8 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, * len > 16 0 */ + spi->mode &= ~SPI_MODE_EN; + if (bitlen <= 16) { if (bitlen <= 4) spi->mode = (spi->mode & 0xff0fffff) | @@ -138,6 +140,8 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, dout += 4; } + spi->mode |= SPI_MODE_EN; + spi->tx = tmpdout; /* Write the data out */ debug("*** spi_xfer: ... %08x written\n", tmpdout); diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index e563c19..52a4134 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -78,7 +78,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int mode) { struct xilinx_spi_slave *xilspi; - struct xilinx_spi_reg *regs; if (!spi_cs_is_valid(bus, cs)) { printf("XILSPI error: %s: unsupported bus %d / cs %d\n", diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c index 8fb7fc8..75ec8f7 100644 --- a/drivers/usb/eth/asix.c +++ b/drivers/usb/eth/asix.c @@ -23,6 +23,7 @@ #include <usb.h> #include <linux/mii.h> #include "usb_ether.h" +#include <malloc.h> /* ASIX AX8817X based USB 2.0 Ethernet Devices */ @@ -31,10 +32,12 @@ #define AX_CMD_READ_MII_REG 0x07 #define AX_CMD_WRITE_MII_REG 0x08 #define AX_CMD_SET_HW_MII 0x0a +#define AX_CMD_READ_EEPROM 0x0b #define AX_CMD_READ_RX_CTL 0x0f #define AX_CMD_WRITE_RX_CTL 0x10 #define AX_CMD_WRITE_IPG0 0x12 #define AX_CMD_READ_NODE_ID 0x13 +#define AX_CMD_WRITE_NODE_ID 0x14 #define AX_CMD_READ_PHY_ID 0x19 #define AX_CMD_WRITE_MEDIUM_MODE 0x1b #define AX_CMD_WRITE_GPIOS 0x1f @@ -97,9 +100,21 @@ #define AX_RX_URB_SIZE 2048 #define PHY_CONNECT_TIMEOUT 5000 +/* asix_flags defines */ +#define FLAG_NONE 0 +#define FLAG_TYPE_AX88172 (1U << 0) +#define FLAG_TYPE_AX88772 (1U << 1) +#define FLAG_TYPE_AX88772B (1U << 2) +#define FLAG_EEPROM_MAC (1U << 3) /* initial mac address in eeprom */ + /* local vars */ static int curr_eth_dev; /* index for name of next device detected */ +/* driver private */ +struct asix_private { + int flags; +}; + /* * Asix infrastructure commands */ @@ -284,6 +299,21 @@ static int asix_write_gpio(struct ueth_data *dev, u16 value, int sleep) return ret; } +static int asix_write_hwaddr(struct eth_device *eth) +{ + struct ueth_data *dev = (struct ueth_data *)eth->priv; + int ret; + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN); + + memcpy(buf, eth->enetaddr, ETH_ALEN); + + ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, buf); + if (ret < 0) + debug("Failed to set MAC address: %02x\n", ret); + + return ret; +} + /* * mii commands */ @@ -310,66 +340,87 @@ static int mii_nway_restart(struct ueth_data *dev) return r; } -/* - * Asix callbacks - */ -static int asix_init(struct eth_device *eth, bd_t *bd) +static int asix_read_mac(struct eth_device *eth) { - int embd_phy; + struct ueth_data *dev = (struct ueth_data *)eth->priv; + struct asix_private *priv = (struct asix_private *)dev->dev_priv; + int i; ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN); - u16 rx_ctl; - struct ueth_data *dev = (struct ueth_data *)eth->priv; - int timeout = 0; -#define TIMEOUT_RESOLUTION 50 /* ms */ - int link_detected; - debug("** %s()\n", __func__); + if (priv->flags & FLAG_EEPROM_MAC) { + for (i = 0; i < (ETH_ALEN >> 1); i++) { + if (asix_read_cmd(dev, AX_CMD_READ_EEPROM, + 0x04 + i, 0, 2, buf) < 0) { + debug("Failed to read SROM address 04h.\n"); + return -1; + } + memcpy((eth->enetaddr + i * 2), buf, 2); + } + } else { + if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf) + < 0) { + debug("Failed to read MAC address.\n"); + return -1; + } + memcpy(eth->enetaddr, buf, ETH_ALEN); + } + + return 0; +} + +static int asix_basic_reset(struct ueth_data *dev) +{ + int embd_phy; + u16 rx_ctl; if (asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5) < 0) - goto out_err; + return -1; /* 0x10 is the phy id of the embedded 10/100 ethernet phy */ embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); if (asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL) < 0) { debug("Select PHY #1 failed\n"); - goto out_err; + return -1; } if (asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL) < 0) - goto out_err; + return -1; if (asix_sw_reset(dev, AX_SWRESET_CLEAR) < 0) - goto out_err; + return -1; if (embd_phy) { if (asix_sw_reset(dev, AX_SWRESET_IPRL) < 0) - goto out_err; + return -1; } else { if (asix_sw_reset(dev, AX_SWRESET_PRTE) < 0) - goto out_err; + return -1; } rx_ctl = asix_read_rx_ctl(dev); debug("RX_CTL is 0x%04x after software reset\n", rx_ctl); if (asix_write_rx_ctl(dev, 0x0000) < 0) - goto out_err; + return -1; rx_ctl = asix_read_rx_ctl(dev); debug("RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); - /* Get the MAC address */ - if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID, - 0, 0, ETH_ALEN, buf) < 0) { - debug("Failed to read MAC address.\n"); - goto out_err; - } - memcpy(eth->enetaddr, buf, ETH_ALEN); - debug("MAC %02x:%02x:%02x:%02x:%02x:%02x\n", - eth->enetaddr[0], eth->enetaddr[1], - eth->enetaddr[2], eth->enetaddr[3], - eth->enetaddr[4], eth->enetaddr[5]); + return 0; +} + +/* + * Asix callbacks + */ +static int asix_init(struct eth_device *eth, bd_t *bd) +{ + struct ueth_data *dev = (struct ueth_data *)eth->priv; + int timeout = 0; +#define TIMEOUT_RESOLUTION 50 /* ms */ + int link_detected; + + debug("** %s()\n", __func__); dev->phy_id = asix_get_phy_addr(dev); if (dev->phy_id < 0) @@ -493,13 +544,13 @@ static int asix_recv(struct eth_device *eth) } memcpy(&packet_len, buf_ptr, sizeof(packet_len)); le32_to_cpus(&packet_len); - if (((packet_len >> 16) ^ 0xffff) != (packet_len & 0xffff)) { + if (((~packet_len >> 16) & 0x7ff) != (packet_len & 0x7ff)) { debug("Rx: malformed packet length: %#x (%#x:%#x)\n", - packet_len, (packet_len >> 16) ^ 0xffff, - packet_len & 0xffff); + packet_len, (~packet_len >> 16) & 0x7ff, + packet_len & 0x7ff); return -1; } - packet_len = packet_len & 0xffff; + packet_len = packet_len & 0x7ff; if (packet_len > actual_len - sizeof(packet_len)) { debug("Rx: too large packet: %d\n", packet_len); return -1; @@ -534,19 +585,24 @@ void asix_eth_before_probe(void) struct asix_dongle { unsigned short vendor; unsigned short product; + int flags; }; -static struct asix_dongle asix_dongles[] = { - { 0x05ac, 0x1402 }, /* Apple USB Ethernet Adapter */ - { 0x07d1, 0x3c05 }, /* D-Link DUB-E100 H/W Ver B1 */ - { 0x0b95, 0x772a }, /* Cables-to-Go USB Ethernet Adapter */ - { 0x0b95, 0x7720 }, /* Trendnet TU2-ET100 V3.0R */ - { 0x0b95, 0x1720 }, /* SMC */ - { 0x0db0, 0xa877 }, /* MSI - ASIX 88772a */ - { 0x13b1, 0x0018 }, /* Linksys 200M v2.1 */ - { 0x1557, 0x7720 }, /* 0Q0 cable ethernet */ - { 0x2001, 0x3c05 }, /* DLink DUB-E100 H/W Ver B1 Alternate */ - { 0x0000, 0x0000 } /* END - Do not remove */ +static const struct asix_dongle const asix_dongles[] = { + { 0x05ac, 0x1402, FLAG_TYPE_AX88772 }, /* Apple USB Ethernet Adapter */ + { 0x07d1, 0x3c05, FLAG_TYPE_AX88772 }, /* D-Link DUB-E100 H/W Ver B1 */ + /* Cables-to-Go USB Ethernet Adapter */ + { 0x0b95, 0x772a, FLAG_TYPE_AX88772 }, + { 0x0b95, 0x7720, FLAG_TYPE_AX88772 }, /* Trendnet TU2-ET100 V3.0R */ + { 0x0b95, 0x1720, FLAG_TYPE_AX88172 }, /* SMC */ + { 0x0db0, 0xa877, FLAG_TYPE_AX88772 }, /* MSI - ASIX 88772a */ + { 0x13b1, 0x0018, FLAG_TYPE_AX88172 }, /* Linksys 200M v2.1 */ + { 0x1557, 0x7720, FLAG_TYPE_AX88772 }, /* 0Q0 cable ethernet */ + /* DLink DUB-E100 H/W Ver B1 Alternate */ + { 0x2001, 0x3c05, FLAG_TYPE_AX88772 }, + /* ASIX 88772B */ + { 0x0b95, 0x772b, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC }, + { 0x0000, 0x0000, FLAG_NONE } /* END - Do not remove */ }; /* Probe to see if a new device is actually an asix device */ @@ -555,6 +611,7 @@ int asix_eth_probe(struct usb_device *dev, unsigned int ifnum, { struct usb_interface *iface; struct usb_interface_descriptor *iface_desc; + int ep_in_found = 0, ep_out_found = 0; int i; /* let's examine the device now */ @@ -583,6 +640,13 @@ int asix_eth_probe(struct usb_device *dev, unsigned int ifnum, ss->subclass = iface_desc->bInterfaceSubClass; ss->protocol = iface_desc->bInterfaceProtocol; + /* alloc driver private */ + ss->dev_priv = calloc(1, sizeof(struct asix_private)); + if (!ss->dev_priv) + return 0; + + ((struct asix_private *)ss->dev_priv)->flags = asix_dongles[i].flags; + /* * We are expecting a minimum of 3 endpoints - in, out (bulk), and * int. We will ignore any others. @@ -591,13 +655,20 @@ int asix_eth_probe(struct usb_device *dev, unsigned int ifnum, /* is it an BULK endpoint? */ if ((iface->ep_desc[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) { - if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN) - ss->ep_in = iface->ep_desc[i].bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - else - ss->ep_out = - iface->ep_desc[i].bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; + u8 ep_addr = iface->ep_desc[i].bEndpointAddress; + if (ep_addr & USB_DIR_IN) { + if (!ep_in_found) { + ss->ep_in = ep_addr & + USB_ENDPOINT_NUMBER_MASK; + ep_in_found = 1; + } + } else { + if (!ep_out_found) { + ss->ep_out = ep_addr & + USB_ENDPOINT_NUMBER_MASK; + ep_out_found = 1; + } + } } /* is it an interrupt endpoint? */ @@ -624,6 +695,8 @@ int asix_eth_probe(struct usb_device *dev, unsigned int ifnum, int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss, struct eth_device *eth) { + struct asix_private *priv = (struct asix_private *)ss->dev_priv; + if (!eth) { debug("%s: missing parameter.\n", __func__); return 0; @@ -633,7 +706,17 @@ int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss, eth->send = asix_send; eth->recv = asix_recv; eth->halt = asix_halt; + if (!(priv->flags & FLAG_TYPE_AX88172)) + eth->write_hwaddr = asix_write_hwaddr; eth->priv = ss; + if (asix_basic_reset(ss)) + return 0; + + /* Get the MAC address */ + if (asix_read_mac(eth)) + return 0; + debug("MAC %pM\n", eth->enetaddr); + return 1; } diff --git a/drivers/usb/eth/smsc95xx.c b/drivers/usb/eth/smsc95xx.c index c62a8c1..dc5ca65 100644 --- a/drivers/usb/eth/smsc95xx.c +++ b/drivers/usb/eth/smsc95xx.c @@ -25,6 +25,7 @@ #include <usb.h> #include <linux/mii.h> #include "usb_ether.h" +#include <malloc.h> /* SMSC LAN95xx based USB 2.0 Ethernet Devices */ @@ -146,6 +147,12 @@ /* local vars */ static int curr_eth_dev; /* index for name of next device detected */ +/* driver private */ +struct smsc95xx_private { + size_t rx_urb_size; /* maximum USB URB size */ + u32 mac_cr; /* MAC control register value */ + int have_hwaddr; /* 1 if we have a hardware MAC address */ +}; /* * Smsc95xx infrastructure commands @@ -377,6 +384,7 @@ static int smsc95xx_init_mac_address(struct eth_device *eth, static int smsc95xx_write_hwaddr(struct eth_device *eth) { struct ueth_data *dev = (struct ueth_data *)eth->priv; + struct smsc95xx_private *priv = dev->dev_priv; u32 addr_lo = __get_unaligned_le32(ð->enetaddr[0]); u32 addr_hi = __get_unaligned_le16(ð->enetaddr[4]); int ret; @@ -392,7 +400,7 @@ static int smsc95xx_write_hwaddr(struct eth_device *eth) return ret; debug("MAC %pM\n", eth->enetaddr); - dev->have_hwaddr = 1; + priv->have_hwaddr = 1; return 0; } @@ -425,19 +433,22 @@ static int smsc95xx_set_csums(struct ueth_data *dev, static void smsc95xx_set_multicast(struct ueth_data *dev) { + struct smsc95xx_private *priv = dev->dev_priv; + /* No multicast in u-boot */ - dev->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_); + priv->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_); } /* starts the TX path */ static void smsc95xx_start_tx_path(struct ueth_data *dev) { + struct smsc95xx_private *priv = dev->dev_priv; u32 reg_val; /* Enable Tx at MAC */ - dev->mac_cr |= MAC_CR_TXEN_; + priv->mac_cr |= MAC_CR_TXEN_; - smsc95xx_write_reg(dev, MAC_CR, dev->mac_cr); + smsc95xx_write_reg(dev, MAC_CR, priv->mac_cr); /* Enable Tx at SCSRs */ reg_val = TX_CFG_ON_; @@ -447,8 +458,10 @@ static void smsc95xx_start_tx_path(struct ueth_data *dev) /* Starts the Receive path */ static void smsc95xx_start_rx_path(struct ueth_data *dev) { - dev->mac_cr |= MAC_CR_RXEN_; - smsc95xx_write_reg(dev, MAC_CR, dev->mac_cr); + struct smsc95xx_private *priv = dev->dev_priv; + + priv->mac_cr |= MAC_CR_RXEN_; + smsc95xx_write_reg(dev, MAC_CR, priv->mac_cr); } /* @@ -462,6 +475,8 @@ static int smsc95xx_init(struct eth_device *eth, bd_t *bd) u32 burst_cap; int timeout; struct ueth_data *dev = (struct ueth_data *)eth->priv; + struct smsc95xx_private *priv = + (struct smsc95xx_private *)dev->dev_priv; #define TIMEOUT_RESOLUTION 50 /* ms */ int link_detected; @@ -504,9 +519,9 @@ static int smsc95xx_init(struct eth_device *eth, bd_t *bd) debug("timeout waiting for PHY Reset\n"); return -1; } - if (!dev->have_hwaddr && smsc95xx_init_mac_address(eth, dev) == 0) - dev->have_hwaddr = 1; - if (!dev->have_hwaddr) { + if (!priv->have_hwaddr && smsc95xx_init_mac_address(eth, dev) == 0) + priv->have_hwaddr = 1; + if (!priv->have_hwaddr) { puts("Error: SMSC95xx: No MAC address set - set usbethaddr\n"); return -1; } @@ -532,16 +547,16 @@ static int smsc95xx_init(struct eth_device *eth, bd_t *bd) #ifdef TURBO_MODE if (dev->pusb_dev->speed == USB_SPEED_HIGH) { burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE; - dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; + priv->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; } else { burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE; - dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; + priv->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; } #else burst_cap = 0; - dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; + priv->rx_urb_size = MAX_SINGLE_PACKET_SIZE; #endif - debug("rx_urb_size=%ld\n", (ulong)dev->rx_urb_size); + debug("rx_urb_size=%ld\n", (ulong)priv->rx_urb_size); ret = smsc95xx_write_reg(dev, BURST_CAP, burst_cap); if (ret < 0) @@ -606,7 +621,7 @@ static int smsc95xx_init(struct eth_device *eth, bd_t *bd) if (ret < 0) return ret; - ret = smsc95xx_read_reg(dev, MAC_CR, &dev->mac_cr); + ret = smsc95xx_read_reg(dev, MAC_CR, &priv->mac_cr); if (ret < 0) return ret; @@ -857,6 +872,12 @@ int smsc95xx_eth_probe(struct usb_device *dev, unsigned int ifnum, return 0; } dev->privptr = (void *)ss; + + /* alloc driver private */ + ss->dev_priv = calloc(1, sizeof(struct smsc95xx_private)); + if (!ss->dev_priv) + return 0; + return 1; } diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 87d1918..5bbdd36 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -29,6 +29,8 @@ LIB := $(obj)libusb_gadget.o ifdef CONFIG_USB_GADGET COBJS-y += epautoconf.o config.o usbstring.o COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o +COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o +COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o endif ifdef CONFIG_USB_ETHER COBJS-y += ether.o epautoconf.o config.o usbstring.o diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c new file mode 100644 index 0000000..3ec4c65 --- /dev/null +++ b/drivers/usb/gadget/f_dfu.c @@ -0,0 +1,749 @@ +/* + * f_dfu.c -- Device Firmware Update USB function + * + * Copyright (C) 2012 Samsung Electronics + * authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com> + * Lukasz Majewski <l.majewski@samsung.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <errno.h> +#include <common.h> +#include <malloc.h> + +#include <linux/usb/ch9.h> +#include <usbdescriptors.h> +#include <linux/usb/gadget.h> +#include <linux/usb/composite.h> + +#include <dfu.h> +#include "f_dfu.h" + +struct f_dfu { + struct usb_function usb_function; + + struct usb_descriptor_header **function; + struct usb_string *strings; + + /* when configured, we have one config */ + u8 config; + u8 altsetting; + enum dfu_state dfu_state; + unsigned int dfu_status; + + /* Send/received block number is handy for data integrity check */ + int blk_seq_num; +}; + +typedef int (*dfu_state_fn) (struct f_dfu *, + const struct usb_ctrlrequest *, + struct usb_gadget *, + struct usb_request *); + +static inline struct f_dfu *func_to_dfu(struct usb_function *f) +{ + return container_of(f, struct f_dfu, usb_function); +} + +static const struct dfu_function_descriptor dfu_func = { + .bLength = sizeof dfu_func, + .bDescriptorType = DFU_DT_FUNC, + .bmAttributes = DFU_BIT_WILL_DETACH | + DFU_BIT_MANIFESTATION_TOLERANT | + DFU_BIT_CAN_UPLOAD | + DFU_BIT_CAN_DNLOAD, + .wDetachTimeOut = 0, + .wTransferSize = DFU_USB_BUFSIZ, + .bcdDFUVersion = __constant_cpu_to_le16(0x0110), +}; + +static struct usb_interface_descriptor dfu_intf_runtime = { + .bLength = sizeof dfu_intf_runtime, + .bDescriptorType = USB_DT_INTERFACE, + .bNumEndpoints = 0, + .bInterfaceClass = USB_CLASS_APP_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 1, + /* .iInterface = DYNAMIC */ +}; + +static struct usb_descriptor_header *dfu_runtime_descs[] = { + (struct usb_descriptor_header *) &dfu_intf_runtime, + NULL, +}; + +static const struct usb_qualifier_descriptor dev_qualifier = { + .bLength = sizeof dev_qualifier, + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = __constant_cpu_to_le16(0x0200), + .bDeviceClass = USB_CLASS_VENDOR_SPEC, + .bNumConfigurations = 1, +}; + +static const char dfu_name[] = "Device Firmware Upgrade"; + +/* + * static strings, in UTF-8 + * + * dfu_generic configuration + */ +static struct usb_string strings_dfu_generic[] = { + [0].s = dfu_name, + { } /* end of list */ +}; + +static struct usb_gadget_strings stringtab_dfu_generic = { + .language = 0x0409, /* en-us */ + .strings = strings_dfu_generic, +}; + +static struct usb_gadget_strings *dfu_generic_strings[] = { + &stringtab_dfu_generic, + NULL, +}; + +/* + * usb_function specific + */ +static struct usb_gadget_strings stringtab_dfu = { + .language = 0x0409, /* en-us */ + /* + * .strings + * + * assigned during initialization, + * depends on number of flash entities + * + */ +}; + +static struct usb_gadget_strings *dfu_strings[] = { + &stringtab_dfu, + NULL, +}; + +/*-------------------------------------------------------------------------*/ + +static void dnload_request_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct f_dfu *f_dfu = req->context; + + dfu_write(dfu_get_entity(f_dfu->altsetting), req->buf, + req->length, f_dfu->blk_seq_num); + + if (req->length == 0) + puts("DOWNLOAD ... OK\nCtrl+C to exit ...\n"); +} + +static void handle_getstatus(struct usb_request *req) +{ + struct dfu_status *dstat = (struct dfu_status *)req->buf; + struct f_dfu *f_dfu = req->context; + + switch (f_dfu->dfu_state) { + case DFU_STATE_dfuDNLOAD_SYNC: + case DFU_STATE_dfuDNBUSY: + f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_IDLE; + break; + case DFU_STATE_dfuMANIFEST_SYNC: + break; + default: + break; + } + + /* send status response */ + dstat->bStatus = f_dfu->dfu_status; + dstat->bState = f_dfu->dfu_state; + dstat->iString = 0; +} + +static void handle_getstate(struct usb_request *req) +{ + struct f_dfu *f_dfu = req->context; + + ((u8 *)req->buf)[0] = f_dfu->dfu_state; + req->actual = sizeof(u8); +} + +static inline void to_dfu_mode(struct f_dfu *f_dfu) +{ + f_dfu->usb_function.strings = dfu_strings; + f_dfu->usb_function.hs_descriptors = f_dfu->function; +} + +static inline void to_runtime_mode(struct f_dfu *f_dfu) +{ + f_dfu->usb_function.strings = NULL; + f_dfu->usb_function.hs_descriptors = dfu_runtime_descs; +} + +static int handle_upload(struct usb_request *req, u16 len) +{ + struct f_dfu *f_dfu = req->context; + + return dfu_read(dfu_get_entity(f_dfu->altsetting), req->buf, + req->length, f_dfu->blk_seq_num); +} + +static int handle_dnload(struct usb_gadget *gadget, u16 len) +{ + struct usb_composite_dev *cdev = get_gadget_data(gadget); + struct usb_request *req = cdev->req; + struct f_dfu *f_dfu = req->context; + + if (len == 0) + f_dfu->dfu_state = DFU_STATE_dfuMANIFEST_SYNC; + + req->complete = dnload_request_complete; + + return len; +} + +/*-------------------------------------------------------------------------*/ +/* DFU state machine */ +static int state_app_idle(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + case USB_REQ_DFU_DETACH: + f_dfu->dfu_state = DFU_STATE_appDETACH; + to_dfu_mode(f_dfu); + f_dfu->dfu_state = DFU_STATE_dfuIDLE; + value = RET_ZLP; + break; + default: + value = RET_STALL; + break; + } + + return value; +} + +static int state_app_detach(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + default: + f_dfu->dfu_state = DFU_STATE_appIDLE; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_idle(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + u16 w_value = le16_to_cpu(ctrl->wValue); + u16 len = le16_to_cpu(ctrl->wLength); + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_DNLOAD: + if (len == 0) { + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC; + f_dfu->blk_seq_num = w_value; + value = handle_dnload(gadget, len); + break; + case USB_REQ_DFU_UPLOAD: + f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE; + f_dfu->blk_seq_num = 0; + value = handle_upload(req, len); + break; + case USB_REQ_DFU_ABORT: + /* no zlp? */ + value = RET_ZLP; + break; + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + case USB_REQ_DFU_DETACH: + /* + * Proprietary extension: 'detach' from idle mode and + * get back to runtime mode in case of USB Reset. As + * much as I dislike this, we just can't use every USB + * bus reset to switch back to runtime mode, since at + * least the Linux USB stack likes to send a number of + * resets in a row :( + */ + f_dfu->dfu_state = + DFU_STATE_dfuMANIFEST_WAIT_RST; + to_runtime_mode(f_dfu); + f_dfu->dfu_state = DFU_STATE_appIDLE; + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_dnload_sync(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_dnbusy(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_dnload_idle(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + u16 w_value = le16_to_cpu(ctrl->wValue); + u16 len = le16_to_cpu(ctrl->wLength); + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_DNLOAD: + f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC; + f_dfu->blk_seq_num = w_value; + value = handle_dnload(gadget, len); + break; + case USB_REQ_DFU_ABORT: + f_dfu->dfu_state = DFU_STATE_dfuIDLE; + value = RET_ZLP; + break; + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_manifest_sync(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_GETSTATUS: + /* We're MainfestationTolerant */ + f_dfu->dfu_state = DFU_STATE_dfuIDLE; + handle_getstatus(req); + f_dfu->blk_seq_num = 0; + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_upload_idle(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + u16 w_value = le16_to_cpu(ctrl->wValue); + u16 len = le16_to_cpu(ctrl->wLength); + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_UPLOAD: + /* state transition if less data then requested */ + f_dfu->blk_seq_num = w_value; + value = handle_upload(req, len); + if (value >= 0 && value < len) + f_dfu->dfu_state = DFU_STATE_dfuIDLE; + break; + case USB_REQ_DFU_ABORT: + f_dfu->dfu_state = DFU_STATE_dfuIDLE; + /* no zlp? */ + value = RET_ZLP; + break; + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_error(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + case USB_REQ_DFU_CLRSTATUS: + f_dfu->dfu_state = DFU_STATE_dfuIDLE; + f_dfu->dfu_status = DFU_STATUS_OK; + /* no zlp? */ + value = RET_ZLP; + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static dfu_state_fn dfu_state[] = { + state_app_idle, /* DFU_STATE_appIDLE */ + state_app_detach, /* DFU_STATE_appDETACH */ + state_dfu_idle, /* DFU_STATE_dfuIDLE */ + state_dfu_dnload_sync, /* DFU_STATE_dfuDNLOAD_SYNC */ + state_dfu_dnbusy, /* DFU_STATE_dfuDNBUSY */ + state_dfu_dnload_idle, /* DFU_STATE_dfuDNLOAD_IDLE */ + state_dfu_manifest_sync, /* DFU_STATE_dfuMANIFEST_SYNC */ + NULL, /* DFU_STATE_dfuMANIFEST */ + NULL, /* DFU_STATE_dfuMANIFEST_WAIT_RST */ + state_dfu_upload_idle, /* DFU_STATE_dfuUPLOAD_IDLE */ + state_dfu_error /* DFU_STATE_dfuERROR */ +}; + +static int +dfu_handle(struct usb_function *f, const struct usb_ctrlrequest *ctrl) +{ + struct usb_gadget *gadget = f->config->cdev->gadget; + struct usb_request *req = f->config->cdev->req; + struct f_dfu *f_dfu = f->config->cdev->req->context; + u16 len = le16_to_cpu(ctrl->wLength); + u16 w_value = le16_to_cpu(ctrl->wValue); + int value = 0; + u8 req_type = ctrl->bRequestType & USB_TYPE_MASK; + + debug("w_value: 0x%x len: 0x%x\n", w_value, len); + debug("req_type: 0x%x ctrl->bRequest: 0x%x f_dfu->dfu_state: 0x%x\n", + req_type, ctrl->bRequest, f_dfu->dfu_state); + + if (req_type == USB_TYPE_STANDARD) { + if (ctrl->bRequest == USB_REQ_GET_DESCRIPTOR && + (w_value >> 8) == DFU_DT_FUNC) { + value = min(len, (u16) sizeof(dfu_func)); + memcpy(req->buf, &dfu_func, value); + } + } else /* DFU specific request */ + value = dfu_state[f_dfu->dfu_state] (f_dfu, ctrl, gadget, req); + + if (value >= 0) { + req->length = value; + req->zero = value < len; + value = usb_ep_queue(gadget->ep0, req, 0); + if (value < 0) { + debug("ep_queue --> %d\n", value); + req->status = 0; + } + } + + return value; +} + +/*-------------------------------------------------------------------------*/ + +static int +dfu_prepare_strings(struct f_dfu *f_dfu, int n) +{ + struct dfu_entity *de = NULL; + int i = 0; + + f_dfu->strings = calloc(sizeof(struct usb_string), n + 1); + if (!f_dfu->strings) + goto enomem; + + for (i = 0; i < n; ++i) { + de = dfu_get_entity(i); + f_dfu->strings[i].s = de->name; + } + + f_dfu->strings[i].id = 0; + f_dfu->strings[i].s = NULL; + + return 0; + +enomem: + while (i) + f_dfu->strings[--i].s = NULL; + + free(f_dfu->strings); + + return -ENOMEM; +} + +static int dfu_prepare_function(struct f_dfu *f_dfu, int n) +{ + struct usb_interface_descriptor *d; + int i = 0; + + f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n); + if (!f_dfu->function) + goto enomem; + + for (i = 0; i < n; ++i) { + d = calloc(sizeof(*d), 1); + if (!d) + goto enomem; + + d->bLength = sizeof(*d); + d->bDescriptorType = USB_DT_INTERFACE; + d->bAlternateSetting = i; + d->bNumEndpoints = 0; + d->bInterfaceClass = USB_CLASS_APP_SPEC; + d->bInterfaceSubClass = 1; + d->bInterfaceProtocol = 2; + + f_dfu->function[i] = (struct usb_descriptor_header *)d; + } + f_dfu->function[i] = NULL; + + return 0; + +enomem: + while (i) { + free(f_dfu->function[--i]); + f_dfu->function[i] = NULL; + } + free(f_dfu->function); + + return -ENOMEM; +} + +static int dfu_bind(struct usb_configuration *c, struct usb_function *f) +{ + struct usb_composite_dev *cdev = c->cdev; + struct f_dfu *f_dfu = func_to_dfu(f); + int alt_num = dfu_get_alt_number(); + int rv, id, i; + + id = usb_interface_id(c, f); + if (id < 0) + return id; + dfu_intf_runtime.bInterfaceNumber = id; + + f_dfu->dfu_state = DFU_STATE_appIDLE; + f_dfu->dfu_status = DFU_STATUS_OK; + + rv = dfu_prepare_function(f_dfu, alt_num); + if (rv) + goto error; + + rv = dfu_prepare_strings(f_dfu, alt_num); + if (rv) + goto error; + for (i = 0; i < alt_num; i++) { + id = usb_string_id(cdev); + if (id < 0) + return id; + f_dfu->strings[i].id = id; + ((struct usb_interface_descriptor *)f_dfu->function[i]) + ->iInterface = id; + } + + stringtab_dfu.strings = f_dfu->strings; + + cdev->req->context = f_dfu; + +error: + return rv; +} + +static void dfu_unbind(struct usb_configuration *c, struct usb_function *f) +{ + struct f_dfu *f_dfu = func_to_dfu(f); + int alt_num = dfu_get_alt_number(); + int i; + + if (f_dfu->strings) { + i = alt_num; + while (i) + f_dfu->strings[--i].s = NULL; + + free(f_dfu->strings); + } + + if (f_dfu->function) { + i = alt_num; + while (i) { + free(f_dfu->function[--i]); + f_dfu->function[i] = NULL; + } + free(f_dfu->function); + } + + free(f_dfu); +} + +static int dfu_set_alt(struct usb_function *f, unsigned intf, unsigned alt) +{ + struct f_dfu *f_dfu = func_to_dfu(f); + + debug("%s: intf:%d alt:%d\n", __func__, intf, alt); + + f_dfu->altsetting = alt; + + return 0; +} + +/* TODO: is this really what we need here? */ +static void dfu_disable(struct usb_function *f) +{ + struct f_dfu *f_dfu = func_to_dfu(f); + if (f_dfu->config == 0) + return; + + debug("%s: reset config\n", __func__); + + f_dfu->config = 0; +} + +static int dfu_bind_config(struct usb_configuration *c) +{ + struct f_dfu *f_dfu; + int status; + + f_dfu = calloc(sizeof(*f_dfu), 1); + if (!f_dfu) + return -ENOMEM; + f_dfu->usb_function.name = "dfu"; + f_dfu->usb_function.hs_descriptors = dfu_runtime_descs; + f_dfu->usb_function.bind = dfu_bind; + f_dfu->usb_function.unbind = dfu_unbind; + f_dfu->usb_function.set_alt = dfu_set_alt; + f_dfu->usb_function.disable = dfu_disable; + f_dfu->usb_function.strings = dfu_generic_strings, + f_dfu->usb_function.setup = dfu_handle, + + status = usb_add_function(c, &f_dfu->usb_function); + if (status) + free(f_dfu); + + return status; +} + +int dfu_add(struct usb_configuration *c) +{ + int id; + + id = usb_string_id(c->cdev); + if (id < 0) + return id; + strings_dfu_generic[0].id = id; + dfu_intf_runtime.iInterface = id; + + debug("%s: cdev: 0x%p gadget:0x%p gadget->ep0: 0x%p\n", __func__, + c->cdev, c->cdev->gadget, c->cdev->gadget->ep0); + + return dfu_bind_config(c); +} diff --git a/drivers/usb/gadget/f_dfu.h b/drivers/usb/gadget/f_dfu.h new file mode 100644 index 0000000..023e1ad --- /dev/null +++ b/drivers/usb/gadget/f_dfu.h @@ -0,0 +1,100 @@ +/* + * f_dfu.h -- Device Firmware Update gadget + * + * Copyright (C) 2011-2012 Samsung Electronics + * author: Andrzej Pietrasiewicz <andrzej.p@samsung.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __F_DFU_H_ +#define __F_DFU_H_ + +#include <linux/compiler.h> +#include <linux/usb/composite.h> + +#define DFU_CONFIG_VAL 1 +#define DFU_DT_FUNC 0x21 + +#define DFU_BIT_WILL_DETACH (0x1 << 3) +#define DFU_BIT_MANIFESTATION_TOLERANT (0x1 << 2) +#define DFU_BIT_CAN_UPLOAD (0x1 << 1) +#define DFU_BIT_CAN_DNLOAD 0x1 + +/* big enough to hold our biggest descriptor */ +#define DFU_USB_BUFSIZ 4096 + +#define USB_REQ_DFU_DETACH 0x00 +#define USB_REQ_DFU_DNLOAD 0x01 +#define USB_REQ_DFU_UPLOAD 0x02 +#define USB_REQ_DFU_GETSTATUS 0x03 +#define USB_REQ_DFU_CLRSTATUS 0x04 +#define USB_REQ_DFU_GETSTATE 0x05 +#define USB_REQ_DFU_ABORT 0x06 + +#define DFU_STATUS_OK 0x00 +#define DFU_STATUS_errTARGET 0x01 +#define DFU_STATUS_errFILE 0x02 +#define DFU_STATUS_errWRITE 0x03 +#define DFU_STATUS_errERASE 0x04 +#define DFU_STATUS_errCHECK_ERASED 0x05 +#define DFU_STATUS_errPROG 0x06 +#define DFU_STATUS_errVERIFY 0x07 +#define DFU_STATUS_errADDRESS 0x08 +#define DFU_STATUS_errNOTDONE 0x09 +#define DFU_STATUS_errFIRMWARE 0x0a +#define DFU_STATUS_errVENDOR 0x0b +#define DFU_STATUS_errUSBR 0x0c +#define DFU_STATUS_errPOR 0x0d +#define DFU_STATUS_errUNKNOWN 0x0e +#define DFU_STATUS_errSTALLEDPKT 0x0f + +#define RET_STALL -1 +#define RET_ZLP 0 +#define RET_STAT_LEN 6 + +enum dfu_state { + DFU_STATE_appIDLE = 0, + DFU_STATE_appDETACH = 1, + DFU_STATE_dfuIDLE = 2, + DFU_STATE_dfuDNLOAD_SYNC = 3, + DFU_STATE_dfuDNBUSY = 4, + DFU_STATE_dfuDNLOAD_IDLE = 5, + DFU_STATE_dfuMANIFEST_SYNC = 6, + DFU_STATE_dfuMANIFEST = 7, + DFU_STATE_dfuMANIFEST_WAIT_RST = 8, + DFU_STATE_dfuUPLOAD_IDLE = 9, + DFU_STATE_dfuERROR = 10, +}; + +struct dfu_status { + __u8 bStatus; + __u8 bwPollTimeout[3]; + __u8 bState; + __u8 iString; +} __packed; + +struct dfu_function_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bmAttributes; + __le16 wDetachTimeOut; + __le16 wTransferSize; + __le16 bcdDFUVersion; +} __packed; + +/* configuration-specific linkup */ +int dfu_add(struct usb_configuration *c); +#endif /* __F_DFU_H_ */ diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c new file mode 100644 index 0000000..7d87050 --- /dev/null +++ b/drivers/usb/gadget/g_dnl.c @@ -0,0 +1,202 @@ +/* + * g_dnl.c -- USB Downloader Gadget + * + * Copyright (C) 2012 Samsung Electronics + * Lukasz Majewski <l.majewski@samsung.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <errno.h> +#include <common.h> +#include <malloc.h> + +#include <mmc.h> +#include <part.h> + +#include <g_dnl.h> +#include "f_dfu.h" + +#include "gadget_chips.h" +#include "composite.c" + +/* + * One needs to define the following: + * CONFIG_G_DNL_VENDOR_NUM + * CONFIG_G_DNL_PRODUCT_NUM + * CONFIG_G_DNL_MANUFACTURER + * at e.g. ./include/configs/<board>.h + */ + +#define STRING_MANUFACTURER 25 +#define STRING_PRODUCT 2 +#define STRING_USBDOWN 2 +#define CONFIG_USBDOWNLOADER 2 + +#define DRIVER_VERSION "usb_dnl 2.0" + +static const char shortname[] = "usb_dnl_"; +static const char product[] = "USB download gadget"; +static const char manufacturer[] = CONFIG_G_DNL_MANUFACTURER; + +static struct usb_device_descriptor device_desc = { + .bLength = sizeof device_desc, + .bDescriptorType = USB_DT_DEVICE, + + .bcdUSB = __constant_cpu_to_le16(0x0200), + .bDeviceClass = USB_CLASS_COMM, + .bDeviceSubClass = 0x02, /*0x02:CDC-modem , 0x00:CDC-serial*/ + + .idVendor = __constant_cpu_to_le16(CONFIG_G_DNL_VENDOR_NUM), + .idProduct = __constant_cpu_to_le16(CONFIG_G_DNL_PRODUCT_NUM), + .iProduct = STRING_PRODUCT, + .bNumConfigurations = 1, +}; + +/* static strings, in UTF-8 */ +static struct usb_string g_dnl_string_defs[] = { + { 0, manufacturer, }, + { 1, product, }, +}; + +static struct usb_gadget_strings g_dnl_string_tab = { + .language = 0x0409, /* en-us */ + .strings = g_dnl_string_defs, +}; + +static struct usb_gadget_strings *g_dnl_composite_strings[] = { + &g_dnl_string_tab, + NULL, +}; + +static int g_dnl_unbind(struct usb_composite_dev *cdev) +{ + debug("%s\n", __func__); + return 0; +} + +static int g_dnl_do_config(struct usb_configuration *c) +{ + const char *s = c->cdev->driver->name; + int ret = -1; + + debug("%s: configuration: 0x%p composite dev: 0x%p\n", + __func__, c, c->cdev); + + printf("GADGET DRIVER: %s\n", s); + if (!strcmp(s, "usb_dnl_dfu")) + ret = dfu_add(c); + + return ret; +} + +static int g_dnl_config_register(struct usb_composite_dev *cdev) +{ + static struct usb_configuration config = { + .label = "usb_dnload", + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, + .bConfigurationValue = CONFIG_USBDOWNLOADER, + .iConfiguration = STRING_USBDOWN, + + .bind = g_dnl_do_config, + }; + + return usb_add_config(cdev, &config); +} + +static int g_dnl_bind(struct usb_composite_dev *cdev) +{ + struct usb_gadget *gadget = cdev->gadget; + int id, ret; + int gcnum; + + debug("%s: gadget: 0x%p cdev: 0x%p\n", __func__, gadget, cdev); + + id = usb_string_id(cdev); + + if (id < 0) + return id; + g_dnl_string_defs[0].id = id; + device_desc.iManufacturer = id; + + id = usb_string_id(cdev); + if (id < 0) + return id; + + g_dnl_string_defs[1].id = id; + device_desc.iProduct = id; + + ret = g_dnl_config_register(cdev); + if (ret) + goto error; + + gcnum = usb_gadget_controller_number(gadget); + + debug("gcnum: %d\n", gcnum); + if (gcnum >= 0) + device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); + else { + debug("%s: controller '%s' not recognized\n", + shortname, gadget->name); + device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); + } + + return 0; + + error: + g_dnl_unbind(cdev); + return -ENOMEM; +} + +static struct usb_composite_driver g_dnl_driver = { + .name = NULL, + .dev = &device_desc, + .strings = g_dnl_composite_strings, + + .bind = g_dnl_bind, + .unbind = g_dnl_unbind, +}; + +int g_dnl_register(const char *type) +{ + /* We only allow "dfu" atm, so 3 should be enough */ + static char name[sizeof(shortname) + 3]; + int ret; + + if (!strcmp(type, "dfu")) { + strcpy(name, shortname); + strcat(name, type); + } else { + printf("%s: unknown command: %s\n", __func__, type); + return -EINVAL; + } + + g_dnl_driver.name = name; + + debug("%s: g_dnl_driver.name: %s\n", __func__, g_dnl_driver.name); + ret = usb_composite_register(&g_dnl_driver); + + if (ret) { + printf("%s: failed!, error: %d\n", __func__, ret); + return ret; + } + + return 0; +} + +void g_dnl_unregister(void) +{ + usb_composite_unregister(&g_dnl_driver); +} diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 2a82a29..392e286 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -22,6 +22,7 @@ */ #include <common.h> #include <asm/byteorder.h> +#include <asm/unaligned.h> #include <usb.h> #include <asm/io.h> #include <malloc.h> @@ -163,7 +164,7 @@ static int ehci_reset(void) #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH cmd = ehci_readl(&hcor->or_txfilltuning); - cmd &= ~TXFIFO_THRESH(0x3f); + cmd &= ~TXFIFO_THRESH_MASK; cmd |= TXFIFO_THRESH(CONFIG_USB_EHCI_TXFIFO_THRESH); ehci_writel(&hcor->or_txfilltuning, cmd); #endif @@ -183,10 +184,10 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz) flush_dcache_range(addr, ALIGN(addr + sz, ARCH_DMA_MINALIGN)); idx = 0; - while (idx < 5) { + while (idx < QT_BUFFER_CNT) { td->qt_buffer[idx] = cpu_to_hc32(addr); td->qt_buffer_hi[idx] = 0; - next = (addr + 4096) & ~4095; + next = (addr + EHCI_PAGE_SIZE) & ~(EHCI_PAGE_SIZE - 1); delta = next - addr; if (delta >= sz) break; @@ -195,7 +196,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz) idx++; } - if (idx == 5) { + if (idx == QT_BUFFER_CNT) { printf("out of buffer pointers (%u bytes left)\n", sz); return -1; } @@ -208,13 +209,14 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, int length, struct devrequest *req) { ALLOC_ALIGN_BUFFER(struct QH, qh, 1, USB_DMA_MINALIGN); - ALLOC_ALIGN_BUFFER(struct qTD, qtd, 3, USB_DMA_MINALIGN); + struct qTD *qtd; + int qtd_count = 0; int qtd_counter = 0; volatile struct qTD *vtd; unsigned long ts; uint32_t *tdp; - uint32_t endpt, token, usbsts; + uint32_t endpt, maxpacket, token, usbsts; uint32_t c, toggle; uint32_t cmd; int timeout; @@ -229,8 +231,73 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, le16_to_cpu(req->value), le16_to_cpu(req->value), le16_to_cpu(req->index)); +#define PKT_ALIGN 512 + /* + * The USB transfer is split into qTD transfers. Eeach qTD transfer is + * described by a transfer descriptor (the qTD). The qTDs form a linked + * list with a queue head (QH). + * + * Each qTD transfer starts with a new USB packet, i.e. a packet cannot + * have its beginning in a qTD transfer and its end in the following + * one, so the qTD transfer lengths have to be chosen accordingly. + * + * Each qTD transfer uses up to QT_BUFFER_CNT data buffers, mapped to + * single pages. The first data buffer can start at any offset within a + * page (not considering the cache-line alignment issues), while the + * following buffers must be page-aligned. There is no alignment + * constraint on the size of a qTD transfer. + */ + if (req != NULL) + /* 1 qTD will be needed for SETUP, and 1 for ACK. */ + qtd_count += 1 + 1; + if (length > 0 || req == NULL) { + /* + * Determine the qTD transfer size that will be used for the + * data payload (not considering the first qTD transfer, which + * may be longer or shorter, and the final one, which may be + * shorter). + * + * In order to keep each packet within a qTD transfer, the qTD + * transfer size is aligned to PKT_ALIGN, which is a multiple of + * wMaxPacketSize (except in some cases for interrupt transfers, + * see comment in submit_int_msg()). + * + * By default, i.e. if the input buffer is aligned to PKT_ALIGN, + * QT_BUFFER_CNT full pages will be used. + */ + int xfr_sz = QT_BUFFER_CNT; + /* + * However, if the input buffer is not aligned to PKT_ALIGN, the + * qTD transfer size will be one page shorter, and the first qTD + * data buffer of each transfer will be page-unaligned. + */ + if ((uint32_t)buffer & (PKT_ALIGN - 1)) + xfr_sz--; + /* Convert the qTD transfer size to bytes. */ + xfr_sz *= EHCI_PAGE_SIZE; + /* + * Approximate by excess the number of qTDs that will be + * required for the data payload. The exact formula is way more + * complicated and saves at most 2 qTDs, i.e. a total of 128 + * bytes. + */ + qtd_count += 2 + length / xfr_sz; + } +/* + * Threshold value based on the worst-case total size of the allocated qTDs for + * a mass-storage transfer of 65535 blocks of 512 bytes. + */ +#if CONFIG_SYS_MALLOC_LEN <= 64 + 128 * 1024 +#warning CONFIG_SYS_MALLOC_LEN may be too small for EHCI +#endif + qtd = memalign(USB_DMA_MINALIGN, qtd_count * sizeof(struct qTD)); + if (qtd == NULL) { + printf("unable to allocate TDs\n"); + return -1; + } + memset(qh, 0, sizeof(struct QH)); - memset(qtd, 0, 3 * sizeof(*qtd)); + memset(qtd, 0, qtd_count * sizeof(*qtd)); toggle = usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)); @@ -245,20 +312,18 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, * - qh_overlay.qt_altnext */ qh->qh_link = cpu_to_hc32((uint32_t)qh_list | QH_LINK_TYPE_QH); - c = (usb_pipespeed(pipe) != USB_SPEED_HIGH && - usb_pipeendpoint(pipe) == 0) ? 1 : 0; - endpt = (8 << 28) | - (c << 27) | - (usb_maxpacket(dev, pipe) << 16) | - (0 << 15) | - (1 << 14) | - (usb_pipespeed(pipe) << 12) | - (usb_pipeendpoint(pipe) << 8) | - (0 << 7) | (usb_pipedevice(pipe) << 0); + c = usb_pipespeed(pipe) != USB_SPEED_HIGH && !usb_pipeendpoint(pipe); + maxpacket = usb_maxpacket(dev, pipe); + endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) | + QH_ENDPT1_MAXPKTLEN(maxpacket) | QH_ENDPT1_H(0) | + QH_ENDPT1_DTC(QH_ENDPT1_DTC_DT_FROM_QTD) | + QH_ENDPT1_EPS(usb_pipespeed(pipe)) | + QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) | + QH_ENDPT1_DEVADDR(usb_pipedevice(pipe)); qh->qh_endpt1 = cpu_to_hc32(endpt); - endpt = (1 << 30) | - (dev->portnr << 23) | - (dev->parent->devnum << 16) | (0 << 8) | (0 << 0); + endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_PORTNUM(dev->portnr) | + QH_ENDPT2_HUBADDR(dev->parent->devnum) | + QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0); qh->qh_endpt2 = cpu_to_hc32(endpt); qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); @@ -276,12 +341,13 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, */ qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); - token = (0 << 31) | - (sizeof(*req) << 16) | - (0 << 15) | (0 << 12) | (3 << 10) | (2 << 8) | (0x80 << 0); + token = QT_TOKEN_DT(0) | QT_TOKEN_TOTALBYTES(sizeof(*req)) | + QT_TOKEN_IOC(0) | QT_TOKEN_CPAGE(0) | QT_TOKEN_CERR(3) | + QT_TOKEN_PID(QT_TOKEN_PID_SETUP) | + QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE); qtd[qtd_counter].qt_token = cpu_to_hc32(token); - if (ehci_td_buffer(&qtd[qtd_counter], req, sizeof(*req)) != 0) { - printf("unable construct SETUP td\n"); + if (ehci_td_buffer(&qtd[qtd_counter], req, sizeof(*req))) { + printf("unable to construct SETUP TD\n"); goto fail; } /* Update previous qTD! */ @@ -291,31 +357,71 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, } if (length > 0 || req == NULL) { - /* - * Setup request qTD (3.5 in ehci-r10.pdf) - * - * qt_next ................ 03-00 H - * qt_altnext ............. 07-04 H - * qt_token ............... 0B-08 H - * - * [ buffer, buffer_hi ] loaded with "buffer". - */ - qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); - qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); - token = (toggle << 31) | - (length << 16) | - ((req == NULL ? 1 : 0) << 15) | - (0 << 12) | - (3 << 10) | - ((usb_pipein(pipe) ? 1 : 0) << 8) | (0x80 << 0); - qtd[qtd_counter].qt_token = cpu_to_hc32(token); - if (ehci_td_buffer(&qtd[qtd_counter], buffer, length) != 0) { - printf("unable construct DATA td\n"); - goto fail; - } - /* Update previous qTD! */ - *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]); - tdp = &qtd[qtd_counter++].qt_next; + uint8_t *buf_ptr = buffer; + int left_length = length; + + do { + /* + * Determine the size of this qTD transfer. By default, + * QT_BUFFER_CNT full pages can be used. + */ + int xfr_bytes = QT_BUFFER_CNT * EHCI_PAGE_SIZE; + /* + * However, if the input buffer is not page-aligned, the + * portion of the first page before the buffer start + * offset within that page is unusable. + */ + xfr_bytes -= (uint32_t)buf_ptr & (EHCI_PAGE_SIZE - 1); + /* + * In order to keep each packet within a qTD transfer, + * align the qTD transfer size to PKT_ALIGN. + */ + xfr_bytes &= ~(PKT_ALIGN - 1); + /* + * This transfer may be shorter than the available qTD + * transfer size that has just been computed. + */ + xfr_bytes = min(xfr_bytes, left_length); + + /* + * Setup request qTD (3.5 in ehci-r10.pdf) + * + * qt_next ................ 03-00 H + * qt_altnext ............. 07-04 H + * qt_token ............... 0B-08 H + * + * [ buffer, buffer_hi ] loaded with "buffer". + */ + qtd[qtd_counter].qt_next = + cpu_to_hc32(QT_NEXT_TERMINATE); + qtd[qtd_counter].qt_altnext = + cpu_to_hc32(QT_NEXT_TERMINATE); + token = QT_TOKEN_DT(toggle) | + QT_TOKEN_TOTALBYTES(xfr_bytes) | + QT_TOKEN_IOC(req == NULL) | QT_TOKEN_CPAGE(0) | + QT_TOKEN_CERR(3) | + QT_TOKEN_PID(usb_pipein(pipe) ? + QT_TOKEN_PID_IN : QT_TOKEN_PID_OUT) | + QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE); + qtd[qtd_counter].qt_token = cpu_to_hc32(token); + if (ehci_td_buffer(&qtd[qtd_counter], buf_ptr, + xfr_bytes)) { + printf("unable to construct DATA TD\n"); + goto fail; + } + /* Update previous qTD! */ + *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]); + tdp = &qtd[qtd_counter++].qt_next; + /* + * Data toggle has to be adjusted since the qTD transfer + * size is not always an even multiple of + * wMaxPacketSize. + */ + if ((xfr_bytes / maxpacket) & 1) + toggle ^= 1; + buf_ptr += xfr_bytes; + left_length -= xfr_bytes; + } while (left_length > 0); } if (req != NULL) { @@ -328,12 +434,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, */ qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); - token = (toggle << 31) | - (0 << 16) | - (1 << 15) | - (0 << 12) | - (3 << 10) | - ((usb_pipein(pipe) ? 0 : 1) << 8) | (0x80 << 0); + token = QT_TOKEN_DT(1) | QT_TOKEN_TOTALBYTES(0) | + QT_TOKEN_IOC(1) | QT_TOKEN_CPAGE(0) | QT_TOKEN_CERR(3) | + QT_TOKEN_PID(usb_pipein(pipe) ? + QT_TOKEN_PID_OUT : QT_TOKEN_PID_IN) | + QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE); qtd[qtd_counter].qt_token = cpu_to_hc32(token); /* Update previous qTD! */ *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]); @@ -346,7 +451,8 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, flush_dcache_range((uint32_t)qh_list, ALIGN_END_ADDR(struct QH, qh_list, 1)); flush_dcache_range((uint32_t)qh, ALIGN_END_ADDR(struct QH, qh, 1)); - flush_dcache_range((uint32_t)qtd, ALIGN_END_ADDR(struct qTD, qtd, 3)); + flush_dcache_range((uint32_t)qtd, + ALIGN_END_ADDR(struct qTD, qtd, qtd_count)); /* Set async. queue head pointer. */ ehci_writel(&hcor->or_asynclistaddr, (uint32_t)qh_list); @@ -359,10 +465,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, cmd |= CMD_ASE; ehci_writel(&hcor->or_usbcmd, cmd); - ret = handshake((uint32_t *)&hcor->or_usbsts, STD_ASS, STD_ASS, + ret = handshake((uint32_t *)&hcor->or_usbsts, STS_ASS, STS_ASS, 100 * 1000); if (ret < 0) { - printf("EHCI fail timeout STD_ASS set\n"); + printf("EHCI fail timeout STS_ASS set\n"); goto fail; } @@ -377,10 +483,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, invalidate_dcache_range((uint32_t)qh, ALIGN_END_ADDR(struct QH, qh, 1)); invalidate_dcache_range((uint32_t)qtd, - ALIGN_END_ADDR(struct qTD, qtd, 3)); + ALIGN_END_ADDR(struct qTD, qtd, qtd_count)); token = hc32_to_cpu(vtd->qt_token); - if (!(token & 0x80)) + if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)) break; WATCHDOG_RESET(); } while (get_timer(ts) < timeout); @@ -398,50 +504,50 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, ALIGN((uint32_t)buffer + length, ARCH_DMA_MINALIGN)); /* Check that the TD processing happened */ - if (token & 0x80) { + if (QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE) printf("EHCI timed out on TD - token=%#x\n", token); - } /* Disable async schedule. */ cmd = ehci_readl(&hcor->or_usbcmd); cmd &= ~CMD_ASE; ehci_writel(&hcor->or_usbcmd, cmd); - ret = handshake((uint32_t *)&hcor->or_usbsts, STD_ASS, 0, + ret = handshake((uint32_t *)&hcor->or_usbsts, STS_ASS, 0, 100 * 1000); if (ret < 0) { - printf("EHCI fail timeout STD_ASS reset\n"); + printf("EHCI fail timeout STS_ASS reset\n"); goto fail; } token = hc32_to_cpu(qh->qh_overlay.qt_token); - if (!(token & 0x80)) { + if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)) { debug("TOKEN=%#x\n", token); - switch (token & 0xfc) { + switch (QT_TOKEN_GET_STATUS(token) & + ~(QT_TOKEN_STATUS_SPLITXSTATE | QT_TOKEN_STATUS_PERR)) { case 0: - toggle = token >> 31; + toggle = QT_TOKEN_GET_DT(token); usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), toggle); dev->status = 0; break; - case 0x40: + case QT_TOKEN_STATUS_HALTED: dev->status = USB_ST_STALLED; break; - case 0xa0: - case 0x20: + case QT_TOKEN_STATUS_ACTIVE | QT_TOKEN_STATUS_DATBUFERR: + case QT_TOKEN_STATUS_DATBUFERR: dev->status = USB_ST_BUF_ERR; break; - case 0x50: - case 0x10: + case QT_TOKEN_STATUS_HALTED | QT_TOKEN_STATUS_BABBLEDET: + case QT_TOKEN_STATUS_BABBLEDET: dev->status = USB_ST_BABBLE_DET; break; default: dev->status = USB_ST_CRC_ERR; - if ((token & 0x40) == 0x40) + if (QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_HALTED) dev->status |= USB_ST_STALLED; break; } - dev->act_len = length - ((token >> 16) & 0x7fff); + dev->act_len = length - QT_TOKEN_GET_TOTALBYTES(token); } else { dev->act_len = 0; debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n", @@ -450,9 +556,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, ehci_readl(&hcor->or_portsc[1])); } + free(qtd); return (dev->status != USB_ST_NOT_PROC) ? 0 : -1; fail: + free(qtd); return -1; } @@ -499,12 +607,14 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, case USB_DT_DEVICE: debug("USB_DT_DEVICE request\n"); srcptr = &descriptor.device; - srclen = 0x12; + srclen = descriptor.device.bLength; break; case USB_DT_CONFIG: debug("USB_DT_CONFIG config\n"); srcptr = &descriptor.config; - srclen = 0x19; + srclen = descriptor.config.bLength + + descriptor.interface.bLength + + descriptor.endpoint.bLength; break; case USB_DT_STRING: debug("USB_DT_STRING config\n"); @@ -539,7 +649,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, case USB_DT_HUB: debug("USB_DT_HUB config\n"); srcptr = &descriptor.hub; - srclen = 0x8; + srclen = descriptor.hub.bLength; break; default: debug("unknown value %x\n", le16_to_cpu(req->value)); @@ -577,13 +687,13 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, tmpbuf[1] |= USB_PORT_STAT_POWER >> 8; if (ehci_is_TDI()) { - switch ((reg >> 26) & 3) { - case 0: + switch (PORTSC_PSPD(reg)) { + case PORTSC_PSPD_FS: break; - case 1: + case PORTSC_PSPD_LS: tmpbuf[1] |= USB_PORT_STAT_LOW_SPEED >> 8; break; - case 2: + case PORTSC_PSPD_HS: default: tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8; break; @@ -729,36 +839,40 @@ int usb_lowlevel_init(void) uint32_t reg; uint32_t cmd; - if (ehci_hcd_init() != 0) + if (ehci_hcd_init()) return -1; /* EHCI spec section 4.1 */ - if (ehci_reset() != 0) + if (ehci_reset()) return -1; #if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET) - if (ehci_hcd_init() != 0) + if (ehci_hcd_init()) return -1; #endif /* Set head of reclaim list */ memset(qh_list, 0, sizeof(*qh_list)); qh_list->qh_link = cpu_to_hc32((uint32_t)qh_list | QH_LINK_TYPE_QH); - qh_list->qh_endpt1 = cpu_to_hc32((1 << 15) | (USB_SPEED_HIGH << 12)); + qh_list->qh_endpt1 = cpu_to_hc32(QH_ENDPT1_H(1) | + QH_ENDPT1_EPS(USB_SPEED_HIGH)); qh_list->qh_curtd = cpu_to_hc32(QT_NEXT_TERMINATE); qh_list->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qh_list->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); - qh_list->qh_overlay.qt_token = cpu_to_hc32(0x40); + qh_list->qh_overlay.qt_token = + cpu_to_hc32(QT_TOKEN_STATUS(QT_TOKEN_STATUS_HALTED)); reg = ehci_readl(&hccr->cr_hcsparams); descriptor.hub.bNbrPorts = HCS_N_PORTS(reg); printf("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts); /* Port Indicators */ if (HCS_INDICATOR(reg)) - descriptor.hub.wHubCharacteristics |= 0x80; + put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics) + | 0x80, &descriptor.hub.wHubCharacteristics); /* Port Power Control */ if (HCS_PPC(reg)) - descriptor.hub.wHubCharacteristics |= 0x01; + put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics) + | 0x01, &descriptor.hub.wHubCharacteristics); /* Start the host controller. */ cmd = ehci_readl(&hcor->or_usbcmd); @@ -808,7 +922,7 @@ submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, } if (usb_pipedevice(pipe) == rootdev) { - if (rootdev == 0) + if (!rootdev) dev->speed = USB_SPEED_HIGH; return ehci_submit_root(dev, pipe, buffer, length, setup); } @@ -819,8 +933,24 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int length, int interval) { - debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d", dev, pipe, buffer, length, interval); + + /* + * Interrupt transfers requiring several transactions are not supported + * because bInterval is ignored. + * + * Also, ehci_submit_async() relies on wMaxPacketSize being a power of 2 + * <= PKT_ALIGN if several qTDs are required, while the USB + * specification does not constrain this for interrupt transfers. That + * means that ehci_submit_async() would support interrupt transfers + * requiring several transactions only as long as the transfer size does + * not require more than a single qTD. + */ + if (length > usb_maxpacket(dev, pipe)) { + printf("%s: Interrupt transfers requiring several transactions " + "are not supported.\n", __func__); + return -1; + } return ehci_submit_async(dev, pipe, buffer, length, NULL); } diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index cc00ce4..39acdf9 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -68,7 +68,7 @@ struct ehci_hcor { #define CMD_RESET (1 << 1) /* reset HC not bus */ #define CMD_RUN (1 << 0) /* start/stop HC */ uint32_t or_usbsts; -#define STD_ASS (1 << 15) +#define STS_ASS (1 << 15) #define STS_HALT (1 << 12) uint32_t or_usbintr; #define INTR_UE (1 << 0) /* USB interrupt enable */ @@ -83,11 +83,16 @@ struct ehci_hcor { uint32_t _reserved_0_; uint32_t or_burstsize; uint32_t or_txfilltuning; +#define TXFIFO_THRESH_MASK (0x3f << 16) #define TXFIFO_THRESH(p) ((p & 0x3f) << 16) uint32_t _reserved_1_[6]; uint32_t or_configflag; #define FLAG_CF (1 << 0) /* true: we'll support "high speed" */ uint32_t or_portsc[CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS]; +#define PORTSC_PSPD(x) (((x) >> 26) & 0x3) +#define PORTSC_PSPD_FS 0x0 +#define PORTSC_PSPD_LS 0x1 +#define PORTSC_PSPD_HS 0x2 uint32_t or_systune; } __attribute__ ((packed, aligned(4))); @@ -171,16 +176,40 @@ struct usb_linux_config_descriptor { /* Queue Element Transfer Descriptor (qTD). */ struct qTD { /* this part defined by EHCI spec */ - uint32_t qt_next; /* see EHCI 3.5.1 */ + uint32_t qt_next; /* see EHCI 3.5.1 */ #define QT_NEXT_TERMINATE 1 - uint32_t qt_altnext; /* see EHCI 3.5.2 */ - uint32_t qt_token; /* see EHCI 3.5.3 */ - uint32_t qt_buffer[5]; /* see EHCI 3.5.4 */ - uint32_t qt_buffer_hi[5]; /* Appendix B */ + uint32_t qt_altnext; /* see EHCI 3.5.2 */ + uint32_t qt_token; /* see EHCI 3.5.3 */ +#define QT_TOKEN_DT(x) (((x) & 0x1) << 31) /* Data Toggle */ +#define QT_TOKEN_GET_DT(x) (((x) >> 31) & 0x1) +#define QT_TOKEN_TOTALBYTES(x) (((x) & 0x7fff) << 16) /* Total Bytes to Transfer */ +#define QT_TOKEN_GET_TOTALBYTES(x) (((x) >> 16) & 0x7fff) +#define QT_TOKEN_IOC(x) (((x) & 0x1) << 15) /* Interrupt On Complete */ +#define QT_TOKEN_CPAGE(x) (((x) & 0x7) << 12) /* Current Page */ +#define QT_TOKEN_CERR(x) (((x) & 0x3) << 10) /* Error Counter */ +#define QT_TOKEN_PID(x) (((x) & 0x3) << 8) /* PID Code */ +#define QT_TOKEN_PID_OUT 0x0 +#define QT_TOKEN_PID_IN 0x1 +#define QT_TOKEN_PID_SETUP 0x2 +#define QT_TOKEN_STATUS(x) (((x) & 0xff) << 0) /* Status */ +#define QT_TOKEN_GET_STATUS(x) (((x) >> 0) & 0xff) +#define QT_TOKEN_STATUS_ACTIVE 0x80 +#define QT_TOKEN_STATUS_HALTED 0x40 +#define QT_TOKEN_STATUS_DATBUFERR 0x20 +#define QT_TOKEN_STATUS_BABBLEDET 0x10 +#define QT_TOKEN_STATUS_XACTERR 0x08 +#define QT_TOKEN_STATUS_MISSEDUFRAME 0x04 +#define QT_TOKEN_STATUS_SPLITXSTATE 0x02 +#define QT_TOKEN_STATUS_PERR 0x01 +#define QT_BUFFER_CNT 5 + uint32_t qt_buffer[QT_BUFFER_CNT]; /* see EHCI 3.5.4 */ + uint32_t qt_buffer_hi[QT_BUFFER_CNT]; /* Appendix B */ /* pad struct for 32 byte alignment */ uint32_t unused[3]; }; +#define EHCI_PAGE_SIZE 4096 + /* Queue Head (QH). */ struct QH { uint32_t qh_link; @@ -190,7 +219,26 @@ struct QH { #define QH_LINK_TYPE_SITD 4 #define QH_LINK_TYPE_FSTN 6 uint32_t qh_endpt1; +#define QH_ENDPT1_RL(x) (((x) & 0xf) << 28) /* NAK Count Reload */ +#define QH_ENDPT1_C(x) (((x) & 0x1) << 27) /* Control Endpoint Flag */ +#define QH_ENDPT1_MAXPKTLEN(x) (((x) & 0x7ff) << 16) /* Maximum Packet Length */ +#define QH_ENDPT1_H(x) (((x) & 0x1) << 15) /* Head of Reclamation List Flag */ +#define QH_ENDPT1_DTC(x) (((x) & 0x1) << 14) /* Data Toggle Control */ +#define QH_ENDPT1_DTC_IGNORE_QTD_TD 0x0 +#define QH_ENDPT1_DTC_DT_FROM_QTD 0x1 +#define QH_ENDPT1_EPS(x) (((x) & 0x3) << 12) /* Endpoint Speed */ +#define QH_ENDPT1_EPS_FS 0x0 +#define QH_ENDPT1_EPS_LS 0x1 +#define QH_ENDPT1_EPS_HS 0x2 +#define QH_ENDPT1_ENDPT(x) (((x) & 0xf) << 8) /* Endpoint Number */ +#define QH_ENDPT1_I(x) (((x) & 0x1) << 7) /* Inactivate on Next Transaction */ +#define QH_ENDPT1_DEVADDR(x) (((x) & 0x7f) << 0) /* Device Address */ uint32_t qh_endpt2; +#define QH_ENDPT2_MULT(x) (((x) & 0x3) << 30) /* High-Bandwidth Pipe Multiplier */ +#define QH_ENDPT2_PORTNUM(x) (((x) & 0x7f) << 23) /* Port Number */ +#define QH_ENDPT2_HUBADDR(x) (((x) & 0x7f) << 16) /* Hub Address */ +#define QH_ENDPT2_UFCMASK(x) (((x) & 0xff) << 8) /* Split Completion Mask */ +#define QH_ENDPT2_UFSMASK(x) (((x) & 0xff) << 0) /* Interrupt Schedule Mask */ uint32_t qh_curtd; struct qTD qh_overlay; /* diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index d24f2f1..9f47351 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1261,19 +1261,11 @@ static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, int leni = transfer_len; int len = 0; int stat = 0; - __u32 datab[4]; - union { - void *ptr; - __u8 *u8; - __u16 *u16; - __u32 *u32; - } databuf; __u16 bmRType_bReq; __u16 wValue; __u16 wIndex; __u16 wLength; - - databuf.u32 = (__u32 *)datab; + ALLOC_ALIGN_BUFFER(__u8, databuf, 16, sizeof(u32)); #ifdef DEBUG pkt_print(NULL, dev, pipe, buffer, transfer_len, @@ -1304,20 +1296,20 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, */ case RH_GET_STATUS: - databuf.u16[0] = cpu_to_le16(1); + *(u16 *)databuf = cpu_to_le16(1); OK(2); case RH_GET_STATUS | RH_INTERFACE: - databuf.u16[0] = cpu_to_le16(0); + *(u16 *)databuf = cpu_to_le16(0); OK(2); case RH_GET_STATUS | RH_ENDPOINT: - databuf.u16[0] = cpu_to_le16(0); + *(u16 *)databuf = cpu_to_le16(0); OK(2); case RH_GET_STATUS | RH_CLASS: - databuf.u32[0] = cpu_to_le32( + *(u32 *)databuf = cpu_to_le32( RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE)); OK(4); case RH_GET_STATUS | RH_OTHER | RH_CLASS: - databuf.u32[0] = cpu_to_le32(RD_RH_PORTSTAT); + *(u32 *)databuf = cpu_to_le32(RD_RH_PORTSTAT); OK(4); case RH_CLEAR_FEATURE | RH_ENDPOINT: @@ -1381,14 +1373,14 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, min_t(unsigned int, sizeof(root_hub_dev_des), wLength)); - databuf.ptr = root_hub_dev_des; OK(len); + databuf = root_hub_dev_des; OK(len); case (0x02): /* configuration descriptor */ len = min_t(unsigned int, leni, min_t(unsigned int, sizeof(root_hub_config_des), wLength)); - databuf.ptr = root_hub_config_des; OK(len); + databuf = root_hub_config_des; OK(len); case (0x03): /* string descriptors */ if (wValue == 0x0300) { len = min_t(unsigned int, @@ -1396,7 +1388,7 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, min_t(unsigned int, sizeof(root_hub_str_index0), wLength)); - databuf.ptr = root_hub_str_index0; + databuf = root_hub_str_index0; OK(len); } if (wValue == 0x0301) { @@ -1405,7 +1397,7 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, min_t(unsigned int, sizeof(root_hub_str_index1), wLength)); - databuf.ptr = root_hub_str_index1; + databuf = root_hub_str_index1; OK(len); } default: @@ -1417,40 +1409,40 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, { __u32 temp = roothub_a(&gohci); - databuf.u8[0] = 9; /* min length; */ - databuf.u8[1] = 0x29; - databuf.u8[2] = temp & RH_A_NDP; + databuf[0] = 9; /* min length; */ + databuf[1] = 0x29; + databuf[2] = temp & RH_A_NDP; #ifdef CONFIG_AT91C_PQFP_UHPBUG - databuf.u8[2] = (databuf.u8[2] == 2) ? 1 : 0; + databuf[2] = (databuf[2] == 2) ? 1 : 0; #endif - databuf.u8[3] = 0; + databuf[3] = 0; if (temp & RH_A_PSM) /* per-port power switching? */ - databuf.u8[3] |= 0x1; + databuf[3] |= 0x1; if (temp & RH_A_NOCP) /* no overcurrent reporting? */ - databuf.u8[3] |= 0x10; + databuf[3] |= 0x10; else if (temp & RH_A_OCPM)/* per-port overcurrent reporting? */ - databuf.u8[3] |= 0x8; + databuf[3] |= 0x8; - /* corresponds to databuf.u8[4-7] */ - databuf.u8[1] = 0; - databuf.u8[5] = (temp & RH_A_POTPGT) >> 24; + databuf[4] = 0; + databuf[5] = (temp & RH_A_POTPGT) >> 24; + databuf[6] = 0; temp = roothub_b(&gohci); - databuf.u8[7] = temp & RH_B_DR; - if (databuf.u8[2] < 7) { - databuf.u8[8] = 0xff; + databuf[7] = temp & RH_B_DR; + if (databuf[2] < 7) { + databuf[8] = 0xff; } else { - databuf.u8[0] += 2; - databuf.u8[8] = (temp & RH_B_DR) >> 8; - databuf.u8[10] = databuf.u8[9] = 0xff; + databuf[0] += 2; + databuf[8] = (temp & RH_B_DR) >> 8; + databuf[10] = databuf[9] = 0xff; } len = min_t(unsigned int, leni, - min_t(unsigned int, databuf.u8[0], wLength)); + min_t(unsigned int, databuf[0], wLength)); OK(len); } case RH_GET_CONFIGURATION: - databuf.u8[0] = 0x01; + databuf[0] = 0x01; OK(1); case RH_SET_CONFIGURATION: @@ -1469,8 +1461,8 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, #endif len = min_t(int, len, leni); - if (data != databuf.ptr) - memcpy(data, databuf.ptr, len); + if (data != databuf) + memcpy(data, databuf, len); dev->act_len = len; dev->status = stat; diff --git a/drivers/usb/musb/musb_hcd.c b/drivers/usb/musb/musb_hcd.c index 2df52c1..8d44c46 100644 --- a/drivers/usb/musb/musb_hcd.c +++ b/drivers/usb/musb/musb_hcd.c @@ -1113,7 +1113,7 @@ int usb_lowlevel_init(void) * should be a usb device connected. */ timeout = musb_cfg.timeout; - while (timeout--) + while (--timeout) if (readb(&musbr->devctl) & MUSB_DEVCTL_HM) break; diff --git a/drivers/video/fsl_diu_fb.c b/drivers/video/fsl_diu_fb.c index 648ffa3..a98cb67 100644 --- a/drivers/video/fsl_diu_fb.c +++ b/drivers/video/fsl_diu_fb.c @@ -271,7 +271,6 @@ int fsl_diu_init(u16 xres, u16 yres, u32 pixel_format, int gamma_fix) struct diu *hw = (struct diu *)CONFIG_SYS_DIU_ADDR; u8 *gamma_table_base; unsigned int i, j; - struct diu_ad *dummy_ad; struct diu_addr gamma; struct diu_addr cursor; @@ -302,14 +301,6 @@ int fsl_diu_init(u16 xres, u16 yres, u32 pixel_format, int gamma_fix) return -1; } - /* The AD struct for the dummy framebuffer and the FB itself */ - dummy_ad = allocate_fb(2, 4, 4, NULL); - if (!dummy_ad) { - printf("DIU: Out of memory\n"); - return -1; - } - dummy_ad->pix_fmt = 0x88883316; - /* read mode info */ info.var.xres = fsl_diu_mode_db->xres; info.var.yres = fsl_diu_mode_db->yres; @@ -376,10 +367,7 @@ int fsl_diu_init(u16 xres, u16 yres, u32 pixel_format, int gamma_fix) out_be32(&hw->gamma, gamma.paddr); out_be32(&hw->cursor, cursor.paddr); out_be32(&hw->bgnd, 0x007F7F7F); - out_be32(&hw->bgnd_wb, 0); out_be32(&hw->disp_size, info.var.yres << 16 | info.var.xres); - out_be32(&hw->wb_size, 0); - out_be32(&hw->wb_mem_addr, 0); out_be32(&hw->hsyn_para, info.var.left_margin << 22 | info.var.hsync_len << 11 | info.var.right_margin); @@ -388,18 +376,13 @@ int fsl_diu_init(u16 xres, u16 yres, u32 pixel_format, int gamma_fix) info.var.vsync_len << 11 | info.var.lower_margin); - out_be32(&hw->syn_pol, 0); - out_be32(&hw->thresholds, 0x00037800); - out_be32(&hw->int_status, 0); - out_be32(&hw->int_mask, 0); - out_be32(&hw->plut, 0x01F5F666); /* Pixel Clock configuration */ diu_set_pixel_clock(info.var.pixclock); /* Set the frame buffers */ out_be32(&hw->desc[0], virt_to_phys(ad)); - out_be32(&hw->desc[1], virt_to_phys(dummy_ad)); - out_be32(&hw->desc[2], virt_to_phys(dummy_ad)); + out_be32(&hw->desc[1], 0); + out_be32(&hw->desc[2], 0); /* Enable the DIU, set display to all three planes */ out_be32(&hw->diu_mode, 1); diff --git a/fs/Makefile b/fs/Makefile index 28da76e..901e189 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -23,7 +23,10 @@ # subdirs-$(CONFIG_CMD_CRAMFS) := cramfs -subdirs-$(CONFIG_CMD_EXT2) += ext2 +subdirs-$(CONFIG_CMD_EXT4) += ext4 +ifndef CONFIG_CMD_EXT4 +subdirs-$(CONFIG_CMD_EXT2) += ext4 +endif subdirs-$(CONFIG_CMD_FAT) += fat subdirs-$(CONFIG_CMD_FDOS) += fdos subdirs-$(CONFIG_CMD_JFFS2) += jffs2 diff --git a/fs/ext2/dev.c b/fs/ext2/dev.c deleted file mode 100644 index 874e211..0000000 --- a/fs/ext2/dev.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * (C) Copyright 2004 - * esd gmbh <www.esd-electronics.com> - * Reinhard Arlt <reinhard.arlt@esd-electronics.com> - * - * based on code of fs/reiserfs/dev.c by - * - * (C) Copyright 2003 - 2004 - * Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.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. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - - -#include <common.h> -#include <config.h> -#include <ext2fs.h> - -static block_dev_desc_t *ext2fs_block_dev_desc; -static disk_partition_t part_info; - -int ext2fs_set_blk_dev(block_dev_desc_t *rbdd, int part) -{ - ext2fs_block_dev_desc = rbdd; - - if (part == 0) { - /* disk doesn't use partition table */ - part_info.start = 0; - part_info.size = rbdd->lba; - part_info.blksz = rbdd->blksz; - } else { - if (get_partition_info - (ext2fs_block_dev_desc, part, &part_info)) { - return 0; - } - } - return part_info.size; -} - - -int ext2fs_devread(int sector, int byte_offset, int byte_len, char *buf) -{ - ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, SECTOR_SIZE); - unsigned sectors; - - /* - * Check partition boundaries - */ - if ((sector < 0) || - ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >= - part_info.size)) { - /* errnum = ERR_OUTSIDE_PART; */ - printf(" ** %s read outside partition sector %d\n", - __func__, - sector); - return 0; - } - - /* - * Get the read to the beginning of a partition. - */ - sector += byte_offset >> SECTOR_BITS; - byte_offset &= SECTOR_SIZE - 1; - - debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len); - - if (ext2fs_block_dev_desc == NULL) { - printf(" ** %s Invalid Block Device Descriptor (NULL)\n", - __func__); - return 0; - } - - if (byte_offset != 0) { - /* read first part which isn't aligned with start of sector */ - if (ext2fs_block_dev_desc-> - block_read(ext2fs_block_dev_desc->dev, - part_info.start + sector, 1, - (unsigned long *) sec_buf) != 1) { - printf(" ** %s read error **\n", __func__); - return 0; - } - memcpy(buf, sec_buf + byte_offset, - min(SECTOR_SIZE - byte_offset, byte_len)); - buf += min(SECTOR_SIZE - byte_offset, byte_len); - byte_len -= min(SECTOR_SIZE - byte_offset, byte_len); - sector++; - } - - /* read sector aligned part */ - sectors = byte_len / SECTOR_SIZE; - - if (sectors > 0) { - if (ext2fs_block_dev_desc->block_read( - ext2fs_block_dev_desc->dev, - part_info.start + sector, - sectors, - (unsigned long *) buf) != sectors) { - printf(" ** %s read error - block\n", __func__); - return 0; - } - - buf += sectors * SECTOR_SIZE; - byte_len -= sectors * SECTOR_SIZE; - sector += sectors; - } - - if (byte_len != 0) { - /* read rest of data which are not in whole sector */ - if (ext2fs_block_dev_desc-> - block_read(ext2fs_block_dev_desc->dev, - part_info.start + sector, 1, - (unsigned long *) sec_buf) != 1) { - printf(" ** %s read error - last part\n", __func__); - return 0; - } - memcpy(buf, sec_buf, byte_len); - } - return 1; -} diff --git a/fs/ext2/ext2fs.c b/fs/ext2/ext2fs.c deleted file mode 100644 index 418404e..0000000 --- a/fs/ext2/ext2fs.c +++ /dev/null @@ -1,919 +0,0 @@ -/* - * (C) Copyright 2004 - * esd gmbh <www.esd-electronics.com> - * Reinhard Arlt <reinhard.arlt@esd-electronics.com> - * - * based on code from grub2 fs/ext2.c and fs/fshelp.c by - * - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <common.h> -#include <ext2fs.h> -#include <malloc.h> -#include <asm/byteorder.h> - -extern int ext2fs_devread (int sector, int byte_offset, int byte_len, - char *buf); - -/* Magic value used to identify an ext2 filesystem. */ -#define EXT2_MAGIC 0xEF53 -/* Amount of indirect blocks in an inode. */ -#define INDIRECT_BLOCKS 12 -/* Maximum lenght of a pathname. */ -#define EXT2_PATH_MAX 4096 -/* Maximum nesting of symlinks, used to prevent a loop. */ -#define EXT2_MAX_SYMLINKCNT 8 - -/* Filetype used in directory entry. */ -#define FILETYPE_UNKNOWN 0 -#define FILETYPE_REG 1 -#define FILETYPE_DIRECTORY 2 -#define FILETYPE_SYMLINK 7 - -/* Filetype information as used in inodes. */ -#define FILETYPE_INO_MASK 0170000 -#define FILETYPE_INO_REG 0100000 -#define FILETYPE_INO_DIRECTORY 0040000 -#define FILETYPE_INO_SYMLINK 0120000 - -/* Bits used as offset in sector */ -#define DISK_SECTOR_BITS 9 - -/* Log2 size of ext2 block in 512 blocks. */ -#define LOG2_EXT2_BLOCK_SIZE(data) (__le32_to_cpu (data->sblock.log2_block_size) + 1) - -/* Log2 size of ext2 block in bytes. */ -#define LOG2_BLOCK_SIZE(data) (__le32_to_cpu (data->sblock.log2_block_size) + 10) - -/* The size of an ext2 block in bytes. */ -#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data)) - -/* The ext2 superblock. */ -struct ext2_sblock { - uint32_t total_inodes; - uint32_t total_blocks; - uint32_t reserved_blocks; - uint32_t free_blocks; - uint32_t free_inodes; - uint32_t first_data_block; - uint32_t log2_block_size; - uint32_t log2_fragment_size; - uint32_t blocks_per_group; - uint32_t fragments_per_group; - uint32_t inodes_per_group; - uint32_t mtime; - uint32_t utime; - uint16_t mnt_count; - uint16_t max_mnt_count; - uint16_t magic; - uint16_t fs_state; - uint16_t error_handling; - uint16_t minor_revision_level; - uint32_t lastcheck; - uint32_t checkinterval; - uint32_t creator_os; - uint32_t revision_level; - uint16_t uid_reserved; - uint16_t gid_reserved; - uint32_t first_inode; - uint16_t inode_size; - uint16_t block_group_number; - uint32_t feature_compatibility; - uint32_t feature_incompat; - uint32_t feature_ro_compat; - uint32_t unique_id[4]; - char volume_name[16]; - char last_mounted_on[64]; - uint32_t compression_info; -}; - -/* The ext2 blockgroup. */ -struct ext2_block_group { - uint32_t block_id; - uint32_t inode_id; - uint32_t inode_table_id; - uint16_t free_blocks; - uint16_t free_inodes; - uint16_t used_dir_cnt; - uint32_t reserved[3]; -}; - -/* The ext2 inode. */ -struct ext2_inode { - uint16_t mode; - uint16_t uid; - uint32_t size; - uint32_t atime; - uint32_t ctime; - uint32_t mtime; - uint32_t dtime; - uint16_t gid; - uint16_t nlinks; - uint32_t blockcnt; /* Blocks of 512 bytes!! */ - uint32_t flags; - uint32_t osd1; - union { - struct datablocks { - uint32_t dir_blocks[INDIRECT_BLOCKS]; - uint32_t indir_block; - uint32_t double_indir_block; - uint32_t tripple_indir_block; - } blocks; - char symlink[60]; - } b; - uint32_t version; - uint32_t acl; - uint32_t dir_acl; - uint32_t fragment_addr; - uint32_t osd2[3]; -}; - -/* The header of an ext2 directory entry. */ -struct ext2_dirent { - uint32_t inode; - uint16_t direntlen; - uint8_t namelen; - uint8_t filetype; -}; - -struct ext2fs_node { - struct ext2_data *data; - struct ext2_inode inode; - int ino; - int inode_read; -}; - -/* Information about a "mounted" ext2 filesystem. */ -struct ext2_data { - struct ext2_sblock sblock; - struct ext2_inode *inode; - struct ext2fs_node diropen; -}; - - -typedef struct ext2fs_node *ext2fs_node_t; - -struct ext2_data *ext2fs_root = NULL; -ext2fs_node_t ext2fs_file = NULL; -int symlinknest = 0; -uint32_t *indir1_block = NULL; -int indir1_size = 0; -int indir1_blkno = -1; -uint32_t *indir2_block = NULL; -int indir2_size = 0; -int indir2_blkno = -1; -static unsigned int inode_size; - - -static int ext2fs_blockgroup - (struct ext2_data *data, int group, struct ext2_block_group *blkgrp) { - unsigned int blkno; - unsigned int blkoff; - unsigned int desc_per_blk; - - desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group); - - blkno = __le32_to_cpu(data->sblock.first_data_block) + 1 + - group / desc_per_blk; - blkoff = (group % desc_per_blk) * sizeof(struct ext2_block_group); -#ifdef DEBUG - printf ("ext2fs read %d group descriptor (blkno %d blkoff %d)\n", - group, blkno, blkoff); -#endif - return (ext2fs_devread (blkno << LOG2_EXT2_BLOCK_SIZE(data), - blkoff, sizeof(struct ext2_block_group), (char *)blkgrp)); - -} - - -static int ext2fs_read_inode - (struct ext2_data *data, int ino, struct ext2_inode *inode) { - struct ext2_block_group blkgrp; - struct ext2_sblock *sblock = &data->sblock; - int inodes_per_block; - int status; - - unsigned int blkno; - unsigned int blkoff; - -#ifdef DEBUG - printf ("ext2fs read inode %d, inode_size %d\n", ino, inode_size); -#endif - /* It is easier to calculate if the first inode is 0. */ - ino--; - status = ext2fs_blockgroup (data, ino / __le32_to_cpu - (sblock->inodes_per_group), &blkgrp); - if (status == 0) { - return (0); - } - - inodes_per_block = EXT2_BLOCK_SIZE(data) / inode_size; - - blkno = __le32_to_cpu (blkgrp.inode_table_id) + - (ino % __le32_to_cpu (sblock->inodes_per_group)) - / inodes_per_block; - blkoff = (ino % inodes_per_block) * inode_size; -#ifdef DEBUG - printf ("ext2fs read inode blkno %d blkoff %d\n", blkno, blkoff); -#endif - /* Read the inode. */ - status = ext2fs_devread (blkno << LOG2_EXT2_BLOCK_SIZE (data), blkoff, - sizeof (struct ext2_inode), (char *) inode); - if (status == 0) { - return (0); - } - - return (1); -} - - -void ext2fs_free_node (ext2fs_node_t node, ext2fs_node_t currroot) { - if ((node != &ext2fs_root->diropen) && (node != currroot)) { - free (node); - } -} - - -static int ext2fs_read_block (ext2fs_node_t node, int fileblock) { - struct ext2_data *data = node->data; - struct ext2_inode *inode = &node->inode; - int blknr; - int blksz = EXT2_BLOCK_SIZE (data); - int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data); - int status; - - /* Direct blocks. */ - if (fileblock < INDIRECT_BLOCKS) { - blknr = __le32_to_cpu (inode->b.blocks.dir_blocks[fileblock]); - } - /* Indirect. */ - else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) { - if (indir1_block == NULL) { - indir1_block = (uint32_t *) memalign(ARCH_DMA_MINALIGN, - blksz); - if (indir1_block == NULL) { - printf ("** ext2fs read block (indir 1) malloc failed. **\n"); - return (-1); - } - indir1_size = blksz; - indir1_blkno = -1; - } - if (blksz != indir1_size) { - free (indir1_block); - indir1_block = NULL; - indir1_size = 0; - indir1_blkno = -1; - indir1_block = (uint32_t *) memalign(ARCH_DMA_MINALIGN, - blksz); - if (indir1_block == NULL) { - printf ("** ext2fs read block (indir 1) malloc failed. **\n"); - return (-1); - } - indir1_size = blksz; - } - if ((__le32_to_cpu (inode->b.blocks.indir_block) << - log2_blksz) != indir1_blkno) { - status = ext2fs_devread (__le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz, - 0, blksz, - (char *) indir1_block); - if (status == 0) { - printf ("** ext2fs read block (indir 1) failed. **\n"); - return (0); - } - indir1_blkno = - __le32_to_cpu (inode->b.blocks. - indir_block) << log2_blksz; - } - blknr = __le32_to_cpu (indir1_block - [fileblock - INDIRECT_BLOCKS]); - } - /* Double indirect. */ - else if (fileblock < - (INDIRECT_BLOCKS + (blksz / 4 * (blksz / 4 + 1)))) { - unsigned int perblock = blksz / 4; - unsigned int rblock = fileblock - (INDIRECT_BLOCKS - + blksz / 4); - - if (indir1_block == NULL) { - indir1_block = (uint32_t *) memalign(ARCH_DMA_MINALIGN, - blksz); - if (indir1_block == NULL) { - printf ("** ext2fs read block (indir 2 1) malloc failed. **\n"); - return (-1); - } - indir1_size = blksz; - indir1_blkno = -1; - } - if (blksz != indir1_size) { - free (indir1_block); - indir1_block = NULL; - indir1_size = 0; - indir1_blkno = -1; - indir1_block = (uint32_t *) memalign(ARCH_DMA_MINALIGN, - blksz); - if (indir1_block == NULL) { - printf ("** ext2fs read block (indir 2 1) malloc failed. **\n"); - return (-1); - } - indir1_size = blksz; - } - if ((__le32_to_cpu (inode->b.blocks.double_indir_block) << - log2_blksz) != indir1_blkno) { - status = ext2fs_devread (__le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz, - 0, blksz, - (char *) indir1_block); - if (status == 0) { - printf ("** ext2fs read block (indir 2 1) failed. **\n"); - return (-1); - } - indir1_blkno = - __le32_to_cpu (inode->b.blocks.double_indir_block) << log2_blksz; - } - - if (indir2_block == NULL) { - indir2_block = (uint32_t *) memalign(ARCH_DMA_MINALIGN, - blksz); - if (indir2_block == NULL) { - printf ("** ext2fs read block (indir 2 2) malloc failed. **\n"); - return (-1); - } - indir2_size = blksz; - indir2_blkno = -1; - } - if (blksz != indir2_size) { - free (indir2_block); - indir2_block = NULL; - indir2_size = 0; - indir2_blkno = -1; - indir2_block = (uint32_t *) memalign(ARCH_DMA_MINALIGN, - blksz); - if (indir2_block == NULL) { - printf ("** ext2fs read block (indir 2 2) malloc failed. **\n"); - return (-1); - } - indir2_size = blksz; - } - if ((__le32_to_cpu (indir1_block[rblock / perblock]) << - log2_blksz) != indir2_blkno) { - status = ext2fs_devread (__le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz, - 0, blksz, - (char *) indir2_block); - if (status == 0) { - printf ("** ext2fs read block (indir 2 2) failed. **\n"); - return (-1); - } - indir2_blkno = - __le32_to_cpu (indir1_block[rblock / perblock]) << log2_blksz; - } - blknr = __le32_to_cpu (indir2_block[rblock % perblock]); - } - /* Tripple indirect. */ - else { - printf ("** ext2fs doesn't support tripple indirect blocks. **\n"); - return (-1); - } -#ifdef DEBUG - printf ("ext2fs_read_block %08x\n", blknr); -#endif - return (blknr); -} - - -int ext2fs_read_file - (ext2fs_node_t node, int pos, unsigned int len, char *buf) { - int i; - int blockcnt; - int log2blocksize = LOG2_EXT2_BLOCK_SIZE (node->data); - int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS); - unsigned int filesize = __le32_to_cpu(node->inode.size); - - /* Adjust len so it we can't read past the end of the file. */ - if (len > filesize) { - len = filesize; - } - blockcnt = ((len + pos) + blocksize - 1) / blocksize; - - for (i = pos / blocksize; i < blockcnt; i++) { - int blknr; - int blockoff = pos % blocksize; - int blockend = blocksize; - - int skipfirst = 0; - - blknr = ext2fs_read_block (node, i); - if (blknr < 0) { - return (-1); - } - - /* Last block. */ - if (i == blockcnt - 1) { - blockend = (len + pos) % blocksize; - - /* The last portion is exactly blocksize. */ - if (!blockend) { - blockend = blocksize; - } - } - - /* First block. */ - if (i == pos / blocksize) { - skipfirst = blockoff; - blockend -= skipfirst; - } - - /* grab middle blocks in one go */ - if (i != pos / blocksize && i < blockcnt - 1 && blockcnt > 3) { - int oldblk = blknr; - int blocknxt = ext2fs_read_block(node, i + 1); - while (i < blockcnt - 1) { - if (blocknxt == (oldblk + 1)) { - oldblk = blocknxt; - i++; - } else { - blocknxt = ext2fs_read_block(node, i); - break; - } - blocknxt = ext2fs_read_block(node, i); - } - - if (oldblk == blknr) - blockend = blocksize; - else - blockend = (1 + blocknxt - blknr) * blocksize; - } - - blknr = blknr << log2blocksize; - - /* If the block number is 0 this block is not stored on disk but - is zero filled instead. */ - if (blknr) { - int status; - - status = ext2fs_devread (blknr, skipfirst, blockend, buf); - if (status == 0) { - return (-1); - } - } else { - memset (buf, 0, blocksize - skipfirst); - } - buf += blockend - skipfirst; - } - return (len); -} - - -static int ext2fs_iterate_dir (ext2fs_node_t dir, char *name, ext2fs_node_t * fnode, int *ftype) -{ - unsigned int fpos = 0; - int status; - struct ext2fs_node *diro = (struct ext2fs_node *) dir; - -#ifdef DEBUG - if (name != NULL) - printf ("Iterate dir %s\n", name); -#endif /* of DEBUG */ - if (!diro->inode_read) { - status = ext2fs_read_inode (diro->data, diro->ino, - &diro->inode); - if (status == 0) { - return (0); - } - } - /* Search the file. */ - while (fpos < __le32_to_cpu (diro->inode.size)) { - struct ext2_dirent dirent; - - status = ext2fs_read_file (diro, fpos, - sizeof (struct ext2_dirent), - (char *) &dirent); - if (status < 1) { - return (0); - } - if (dirent.namelen != 0) { - char filename[dirent.namelen + 1]; - ext2fs_node_t fdiro; - int type = FILETYPE_UNKNOWN; - - status = ext2fs_read_file (diro, - fpos + sizeof (struct ext2_dirent), - dirent.namelen, filename); - if (status < 1) { - return (0); - } - fdiro = malloc (sizeof (struct ext2fs_node)); - if (!fdiro) { - return (0); - } - - fdiro->data = diro->data; - fdiro->ino = __le32_to_cpu (dirent.inode); - - filename[dirent.namelen] = '\0'; - - if (dirent.filetype != FILETYPE_UNKNOWN) { - fdiro->inode_read = 0; - - if (dirent.filetype == FILETYPE_DIRECTORY) { - type = FILETYPE_DIRECTORY; - } else if (dirent.filetype == - FILETYPE_SYMLINK) { - type = FILETYPE_SYMLINK; - } else if (dirent.filetype == FILETYPE_REG) { - type = FILETYPE_REG; - } - } else { - /* The filetype can not be read from the dirent, get it from inode */ - - status = ext2fs_read_inode (diro->data, - __le32_to_cpu(dirent.inode), - &fdiro->inode); - if (status == 0) { - free (fdiro); - return (0); - } - fdiro->inode_read = 1; - - if ((__le16_to_cpu (fdiro->inode.mode) & - FILETYPE_INO_MASK) == - FILETYPE_INO_DIRECTORY) { - type = FILETYPE_DIRECTORY; - } else if ((__le16_to_cpu (fdiro->inode.mode) - & FILETYPE_INO_MASK) == - FILETYPE_INO_SYMLINK) { - type = FILETYPE_SYMLINK; - } else if ((__le16_to_cpu (fdiro->inode.mode) - & FILETYPE_INO_MASK) == - FILETYPE_INO_REG) { - type = FILETYPE_REG; - } - } -#ifdef DEBUG - printf ("iterate >%s<\n", filename); -#endif /* of DEBUG */ - if ((name != NULL) && (fnode != NULL) - && (ftype != NULL)) { - if (strcmp (filename, name) == 0) { - *ftype = type; - *fnode = fdiro; - return (1); - } - } else { - if (fdiro->inode_read == 0) { - status = ext2fs_read_inode (diro->data, - __le32_to_cpu (dirent.inode), - &fdiro->inode); - if (status == 0) { - free (fdiro); - return (0); - } - fdiro->inode_read = 1; - } - switch (type) { - case FILETYPE_DIRECTORY: - printf ("<DIR> "); - break; - case FILETYPE_SYMLINK: - printf ("<SYM> "); - break; - case FILETYPE_REG: - printf (" "); - break; - default: - printf ("< ? > "); - break; - } - printf ("%10d %s\n", - __le32_to_cpu (fdiro->inode.size), - filename); - } - free (fdiro); - } - fpos += __le16_to_cpu (dirent.direntlen); - } - return (0); -} - - -static char *ext2fs_read_symlink (ext2fs_node_t node) { - char *symlink; - struct ext2fs_node *diro = node; - int status; - - if (!diro->inode_read) { - status = ext2fs_read_inode (diro->data, diro->ino, - &diro->inode); - if (status == 0) { - return (0); - } - } - symlink = malloc (__le32_to_cpu (diro->inode.size) + 1); - if (!symlink) { - return (0); - } - /* If the filesize of the symlink is bigger than - 60 the symlink is stored in a separate block, - otherwise it is stored in the inode. */ - if (__le32_to_cpu (diro->inode.size) <= 60) { - strncpy (symlink, diro->inode.b.symlink, - __le32_to_cpu (diro->inode.size)); - } else { - status = ext2fs_read_file (diro, 0, - __le32_to_cpu (diro->inode.size), - symlink); - if (status == 0) { - free (symlink); - return (0); - } - } - symlink[__le32_to_cpu (diro->inode.size)] = '\0'; - return (symlink); -} - - -int ext2fs_find_file1 - (const char *currpath, - ext2fs_node_t currroot, ext2fs_node_t * currfound, int *foundtype) { - char fpath[strlen (currpath) + 1]; - char *name = fpath; - char *next; - int status; - int type = FILETYPE_DIRECTORY; - ext2fs_node_t currnode = currroot; - ext2fs_node_t oldnode = currroot; - - strncpy (fpath, currpath, strlen (currpath) + 1); - - /* Remove all leading slashes. */ - while (*name == '/') { - name++; - } - if (!*name) { - *currfound = currnode; - return (1); - } - - for (;;) { - int found; - - /* Extract the actual part from the pathname. */ - next = strchr (name, '/'); - if (next) { - /* Remove all leading slashes. */ - while (*next == '/') { - *(next++) = '\0'; - } - } - - /* At this point it is expected that the current node is a directory, check if this is true. */ - if (type != FILETYPE_DIRECTORY) { - ext2fs_free_node (currnode, currroot); - return (0); - } - - oldnode = currnode; - - /* Iterate over the directory. */ - found = ext2fs_iterate_dir (currnode, name, &currnode, &type); - if (found == 0) { - return (0); - } - if (found == -1) { - break; - } - - /* Read in the symlink and follow it. */ - if (type == FILETYPE_SYMLINK) { - char *symlink; - - /* Test if the symlink does not loop. */ - if (++symlinknest == 8) { - ext2fs_free_node (currnode, currroot); - ext2fs_free_node (oldnode, currroot); - return (0); - } - - symlink = ext2fs_read_symlink (currnode); - ext2fs_free_node (currnode, currroot); - - if (!symlink) { - ext2fs_free_node (oldnode, currroot); - return (0); - } -#ifdef DEBUG - printf ("Got symlink >%s<\n", symlink); -#endif /* of DEBUG */ - /* The symlink is an absolute path, go back to the root inode. */ - if (symlink[0] == '/') { - ext2fs_free_node (oldnode, currroot); - oldnode = &ext2fs_root->diropen; - } - - /* Lookup the node the symlink points to. */ - status = ext2fs_find_file1 (symlink, oldnode, - &currnode, &type); - - free (symlink); - - if (status == 0) { - ext2fs_free_node (oldnode, currroot); - return (0); - } - } - - ext2fs_free_node (oldnode, currroot); - - /* Found the node! */ - if (!next || *next == '\0') { - *currfound = currnode; - *foundtype = type; - return (1); - } - name = next; - } - return (-1); -} - - -int ext2fs_find_file - (const char *path, - ext2fs_node_t rootnode, ext2fs_node_t * foundnode, int expecttype) { - int status; - int foundtype = FILETYPE_DIRECTORY; - - - symlinknest = 0; - if (!path) { - return (0); - } - - status = ext2fs_find_file1 (path, rootnode, foundnode, &foundtype); - if (status == 0) { - return (0); - } - /* Check if the node that was found was of the expected type. */ - if ((expecttype == FILETYPE_REG) && (foundtype != expecttype)) { - return (0); - } else if ((expecttype == FILETYPE_DIRECTORY) - && (foundtype != expecttype)) { - return (0); - } - return (1); -} - - -int ext2fs_ls (const char *dirname) { - ext2fs_node_t dirnode; - int status; - - if (ext2fs_root == NULL) { - return (0); - } - - status = ext2fs_find_file (dirname, &ext2fs_root->diropen, &dirnode, - FILETYPE_DIRECTORY); - if (status != 1) { - printf ("** Can not find directory. **\n"); - return (1); - } - ext2fs_iterate_dir (dirnode, NULL, NULL, NULL); - ext2fs_free_node (dirnode, &ext2fs_root->diropen); - return (0); -} - - -int ext2fs_open (const char *filename) { - ext2fs_node_t fdiro = NULL; - int status; - int len; - - if (ext2fs_root == NULL) { - return (-1); - } - ext2fs_file = NULL; - status = ext2fs_find_file (filename, &ext2fs_root->diropen, &fdiro, - FILETYPE_REG); - if (status == 0) { - goto fail; - } - if (!fdiro->inode_read) { - status = ext2fs_read_inode (fdiro->data, fdiro->ino, - &fdiro->inode); - if (status == 0) { - goto fail; - } - } - len = __le32_to_cpu (fdiro->inode.size); - ext2fs_file = fdiro; - return (len); - -fail: - ext2fs_free_node (fdiro, &ext2fs_root->diropen); - return (-1); -} - - -int ext2fs_close (void - ) { - if ((ext2fs_file != NULL) && (ext2fs_root != NULL)) { - ext2fs_free_node (ext2fs_file, &ext2fs_root->diropen); - ext2fs_file = NULL; - } - if (ext2fs_root != NULL) { - free (ext2fs_root); - ext2fs_root = NULL; - } - if (indir1_block != NULL) { - free (indir1_block); - indir1_block = NULL; - indir1_size = 0; - indir1_blkno = -1; - } - if (indir2_block != NULL) { - free (indir2_block); - indir2_block = NULL; - indir2_size = 0; - indir2_blkno = -1; - } - return (0); -} - - -int ext2fs_read (char *buf, unsigned len) { - int status; - - if (ext2fs_root == NULL) { - return (0); - } - - if (ext2fs_file == NULL) { - return (0); - } - - status = ext2fs_read_file (ext2fs_file, 0, len, buf); - return (status); -} - - -int ext2fs_mount (unsigned part_length) { - struct ext2_data *data; - int status; - - data = malloc (sizeof (struct ext2_data)); - if (!data) { - return (0); - } - /* Read the superblock. */ - status = ext2fs_devread (1 * 2, 0, sizeof (struct ext2_sblock), - (char *) &data->sblock); - if (status == 0) { - goto fail; - } - /* Make sure this is an ext2 filesystem. */ - if (__le16_to_cpu (data->sblock.magic) != EXT2_MAGIC) { - goto fail; - } - if (__le32_to_cpu(data->sblock.revision_level == 0)) { - inode_size = 128; - } else { - inode_size = __le16_to_cpu(data->sblock.inode_size); - } -#ifdef DEBUG - printf("EXT2 rev %d, inode_size %d\n", - __le32_to_cpu(data->sblock.revision_level), inode_size); -#endif - data->diropen.data = data; - data->diropen.ino = 2; - data->diropen.inode_read = 1; - data->inode = &data->diropen.inode; - - status = ext2fs_read_inode (data, 2, data->inode); - if (status == 0) { - goto fail; - } - - ext2fs_root = data; - - return (1); - -fail: - printf ("Failed to mount ext2 filesystem...\n"); - free (data); - ext2fs_root = NULL; - return (0); -} diff --git a/fs/ext2/Makefile b/fs/ext4/Makefile index 3c65d25..82cd9ae 100644 --- a/fs/ext2/Makefile +++ b/fs/ext4/Makefile @@ -27,15 +27,18 @@ include $(TOPDIR)/config.mk -LIB = $(obj)libext2fs.o +LIB = $(obj)libext4fs.o AOBJS = -COBJS-$(CONFIG_CMD_EXT2) := ext2fs.o dev.o +COBJS-$(CONFIG_CMD_EXT4) := ext4fs.o ext4_common.o dev.o +ifndef CONFIG_CMD_EXT4 +COBJS-$(CONFIG_CMD_EXT2) := ext4fs.o ext4_common.o dev.o +endif +COBJS-$(CONFIG_CMD_EXT4_WRITE) += ext4_journal.o crc16.o SRCS := $(AOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS-y)) -#CPPFLAGS += all: $(LIB) $(AOBJS) diff --git a/fs/ext4/crc16.c b/fs/ext4/crc16.c new file mode 100644 index 0000000..3afb34d --- /dev/null +++ b/fs/ext4/crc16.c @@ -0,0 +1,62 @@ +/* + * crc16.c + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include <common.h> +#include <asm/byteorder.h> +#include <linux/stat.h> +#include "crc16.h" + +/** CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1) */ +static __u16 const crc16_table[256] = { + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 +}; + +/** + * Compute the CRC-16 for the data buffer +*/ + +unsigned int ext2fs_crc16(unsigned int crc, + const void *buffer, unsigned int len) +{ + const unsigned char *cp = buffer; + + while (len--) + crc = (((crc >> 8) & 0xffU) ^ + crc16_table[(crc ^ *cp++) & 0xffU]) & 0x0000ffffU; + return crc; +} diff --git a/fs/ext4/crc16.h b/fs/ext4/crc16.h new file mode 100644 index 0000000..5fd113a --- /dev/null +++ b/fs/ext4/crc16.h @@ -0,0 +1,16 @@ +/* + * crc16.h - CRC-16 routine + * Implements the standard CRC-16: + * Width 16 + * Poly 0x8005 (x16 + x15 + x2 + 1) + * Init 0 + * + * 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. + */ +#ifndef __CRC16_H +#define __CRC16_H +extern unsigned int ext2fs_crc16(unsigned int crc, + const void *buffer, unsigned int len); +#endif diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c new file mode 100644 index 0000000..1596a92 --- /dev/null +++ b/fs/ext4/dev.c @@ -0,0 +1,139 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar <uma.shankar@samsung.com> + * Manjunatha C Achar <a.manjunatha@samsung.com> + * + * made from existing ext2/dev.c file of Uboot + * (C) Copyright 2004 + * esd gmbh <www.esd-electronics.com> + * Reinhard Arlt <reinhard.arlt@esd-electronics.com> + * + * based on code of fs/reiserfs/dev.c by + * + * (C) Copyright 2003 - 2004 + * Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.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. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * Changelog: + * 0.1 - Newly created file for ext4fs support. Taken from + * fs/ext2/dev.c file in uboot. + */ + +#include <common.h> +#include <config.h> +#include <ext4fs.h> +#include <ext_common.h> + +unsigned long part_offset; + +static block_dev_desc_t *ext4fs_block_dev_desc; +static disk_partition_t *part_info; + +void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info) +{ + ext4fs_block_dev_desc = rbdd; + part_info = info; + part_offset = info->start; + get_fs()->total_sect = (info->size * info->blksz) / SECTOR_SIZE; +} + +int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf) +{ + ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, SECTOR_SIZE); + unsigned block_len; + + /* Check partition boundaries */ + if ((sector < 0) + || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >= + part_info->size)) { + printf("%s read outside partition %d\n", __func__, sector); + return 0; + } + + /* Get the read to the beginning of a partition */ + sector += byte_offset >> SECTOR_BITS; + byte_offset &= SECTOR_SIZE - 1; + + debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len); + + if (ext4fs_block_dev_desc == NULL) { + printf("** Invalid Block Device Descriptor (NULL)\n"); + return 0; + } + + if (byte_offset != 0) { + /* read first part which isn't aligned with start of sector */ + if (ext4fs_block_dev_desc-> + block_read(ext4fs_block_dev_desc->dev, + part_info->start + sector, 1, + (unsigned long *) sec_buf) != 1) { + printf(" ** ext2fs_devread() read error **\n"); + return 0; + } + memcpy(buf, sec_buf + byte_offset, + min(SECTOR_SIZE - byte_offset, byte_len)); + buf += min(SECTOR_SIZE - byte_offset, byte_len); + byte_len -= min(SECTOR_SIZE - byte_offset, byte_len); + sector++; + } + + if (byte_len == 0) + return 1; + + /* read sector aligned part */ + block_len = byte_len & ~(SECTOR_SIZE - 1); + + if (block_len == 0) { + ALLOC_CACHE_ALIGN_BUFFER(u8, p, SECTOR_SIZE); + + block_len = SECTOR_SIZE; + ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev, + part_info->start + sector, + 1, (unsigned long *)p); + memcpy(buf, p, byte_len); + return 1; + } + + if (ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev, + part_info->start + sector, + block_len / SECTOR_SIZE, + (unsigned long *) buf) != + block_len / SECTOR_SIZE) { + printf(" ** %s read error - block\n", __func__); + return 0; + } + block_len = byte_len & ~(SECTOR_SIZE - 1); + buf += block_len; + byte_len -= block_len; + sector += block_len / SECTOR_SIZE; + + if (byte_len != 0) { + /* read rest of data which are not in whole sector */ + if (ext4fs_block_dev_desc-> + block_read(ext4fs_block_dev_desc->dev, + part_info->start + sector, 1, + (unsigned long *) sec_buf) != 1) { + printf("* %s read error - last part\n", __func__); + return 0; + } + memcpy(buf, sec_buf, byte_len); + } + return 1; +} diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c new file mode 100644 index 0000000..3deffd5 --- /dev/null +++ b/fs/ext4/ext4_common.c @@ -0,0 +1,2228 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar <uma.shankar@samsung.com> + * Manjunatha C Achar <a.manjunatha@samsung.com> + * + * ext4ls and ext4load : Based on ext2 ls load support in Uboot. + * + * (C) Copyright 2004 + * esd gmbh <www.esd-electronics.com> + * Reinhard Arlt <reinhard.arlt@esd-electronics.com> + * + * based on code from grub2 fs/ext2.c and fs/fshelp.c by + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * + * ext4write : Based on generic ext4 protocol. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <common.h> +#include <ext_common.h> +#include <ext4fs.h> +#include <malloc.h> +#include <stddef.h> +#include <linux/stat.h> +#include <linux/time.h> +#include <asm/byteorder.h> +#include "ext4_common.h" + +struct ext2_data *ext4fs_root; +struct ext2fs_node *ext4fs_file; +uint32_t *ext4fs_indir1_block; +int ext4fs_indir1_size; +int ext4fs_indir1_blkno = -1; +uint32_t *ext4fs_indir2_block; +int ext4fs_indir2_size; +int ext4fs_indir2_blkno = -1; + +uint32_t *ext4fs_indir3_block; +int ext4fs_indir3_size; +int ext4fs_indir3_blkno = -1; +struct ext2_inode *g_parent_inode; +static int symlinknest; + +#if defined(CONFIG_CMD_EXT4_WRITE) +uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n) +{ + uint32_t res = size / n; + if (res * n != size) + res++; + + return res; +} + +void put_ext4(uint64_t off, void *buf, uint32_t size) +{ + uint64_t startblock; + uint64_t remainder; + unsigned char *temp_ptr = NULL; + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, sec_buf, SECTOR_SIZE); + struct ext_filesystem *fs = get_fs(); + + startblock = off / (uint64_t)SECTOR_SIZE; + startblock += part_offset; + remainder = off % (uint64_t)SECTOR_SIZE; + remainder &= SECTOR_SIZE - 1; + + if (fs->dev_desc == NULL) + return; + + if ((startblock + (size / SECTOR_SIZE)) > + (part_offset + fs->total_sect)) { + printf("part_offset is %lu\n", part_offset); + printf("total_sector is %llu\n", fs->total_sect); + printf("error: overflow occurs\n"); + return; + } + + if (remainder) { + if (fs->dev_desc->block_read) { + fs->dev_desc->block_read(fs->dev_desc->dev, + startblock, 1, sec_buf); + temp_ptr = sec_buf; + memcpy((temp_ptr + remainder), + (unsigned char *)buf, size); + fs->dev_desc->block_write(fs->dev_desc->dev, + startblock, 1, sec_buf); + } + } else { + if (size / SECTOR_SIZE != 0) { + fs->dev_desc->block_write(fs->dev_desc->dev, + startblock, + size / SECTOR_SIZE, + (unsigned long *)buf); + } else { + fs->dev_desc->block_read(fs->dev_desc->dev, + startblock, 1, sec_buf); + temp_ptr = sec_buf; + memcpy(temp_ptr, buf, size); + fs->dev_desc->block_write(fs->dev_desc->dev, + startblock, 1, + (unsigned long *)sec_buf); + } + } +} + +static int _get_new_inode_no(unsigned char *buffer) +{ + struct ext_filesystem *fs = get_fs(); + unsigned char input; + int operand, status; + int count = 1; + int j = 0; + + /* get the blocksize of the filesystem */ + unsigned char *ptr = buffer; + while (*ptr == 255) { + ptr++; + count += 8; + if (count > ext4fs_root->sblock.inodes_per_group) + return -1; + } + + for (j = 0; j < fs->blksz; j++) { + input = *ptr; + int i = 0; + while (i <= 7) { + operand = 1 << i; + status = input & operand; + if (status) { + i++; + count++; + } else { + *ptr |= operand; + return count; + } + } + ptr = ptr + 1; + } + + return -1; +} + +static int _get_new_blk_no(unsigned char *buffer) +{ + unsigned char input; + int operand, status; + int count = 0; + int j = 0; + unsigned char *ptr = buffer; + struct ext_filesystem *fs = get_fs(); + + if (fs->blksz != 1024) + count = 0; + else + count = 1; + + while (*ptr == 255) { + ptr++; + count += 8; + if (count == (fs->blksz * 8)) + return -1; + } + + for (j = 0; j < fs->blksz; j++) { + input = *ptr; + int i = 0; + while (i <= 7) { + operand = 1 << i; + status = input & operand; + if (status) { + i++; + count++; + } else { + *ptr |= operand; + return count; + } + } + ptr = ptr + 1; + } + + return -1; +} + +int ext4fs_set_block_bmap(long int blockno, unsigned char *buffer, int index) +{ + int i, remainder, status; + unsigned char *ptr = buffer; + unsigned char operand; + i = blockno / 8; + remainder = blockno % 8; + int blocksize = EXT2_BLOCK_SIZE(ext4fs_root); + + i = i - (index * blocksize); + if (blocksize != 1024) { + ptr = ptr + i; + operand = 1 << remainder; + status = *ptr & operand; + if (status) + return -1; + + *ptr = *ptr | operand; + return 0; + } else { + if (remainder == 0) { + ptr = ptr + i - 1; + operand = (1 << 7); + } else { + ptr = ptr + i; + operand = (1 << (remainder - 1)); + } + status = *ptr & operand; + if (status) + return -1; + + *ptr = *ptr | operand; + return 0; + } +} + +void ext4fs_reset_block_bmap(long int blockno, unsigned char *buffer, int index) +{ + int i, remainder, status; + unsigned char *ptr = buffer; + unsigned char operand; + i = blockno / 8; + remainder = blockno % 8; + int blocksize = EXT2_BLOCK_SIZE(ext4fs_root); + + i = i - (index * blocksize); + if (blocksize != 1024) { + ptr = ptr + i; + operand = (1 << remainder); + status = *ptr & operand; + if (status) + *ptr = *ptr & ~(operand); + } else { + if (remainder == 0) { + ptr = ptr + i - 1; + operand = (1 << 7); + } else { + ptr = ptr + i; + operand = (1 << (remainder - 1)); + } + status = *ptr & operand; + if (status) + *ptr = *ptr & ~(operand); + } +} + +int ext4fs_set_inode_bmap(int inode_no, unsigned char *buffer, int index) +{ + int i, remainder, status; + unsigned char *ptr = buffer; + unsigned char operand; + + inode_no -= (index * ext4fs_root->sblock.inodes_per_group); + i = inode_no / 8; + remainder = inode_no % 8; + if (remainder == 0) { + ptr = ptr + i - 1; + operand = (1 << 7); + } else { + ptr = ptr + i; + operand = (1 << (remainder - 1)); + } + status = *ptr & operand; + if (status) + return -1; + + *ptr = *ptr | operand; + + return 0; +} + +void ext4fs_reset_inode_bmap(int inode_no, unsigned char *buffer, int index) +{ + int i, remainder, status; + unsigned char *ptr = buffer; + unsigned char operand; + + inode_no -= (index * ext4fs_root->sblock.inodes_per_group); + i = inode_no / 8; + remainder = inode_no % 8; + if (remainder == 0) { + ptr = ptr + i - 1; + operand = (1 << 7); + } else { + ptr = ptr + i; + operand = (1 << (remainder - 1)); + } + status = *ptr & operand; + if (status) + *ptr = *ptr & ~(operand); +} + +int ext4fs_checksum_update(unsigned int i) +{ + struct ext2_block_group *desc; + struct ext_filesystem *fs = get_fs(); + __u16 crc = 0; + + desc = (struct ext2_block_group *)&fs->gd[i]; + if (fs->sb->feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { + int offset = offsetof(struct ext2_block_group, bg_checksum); + + crc = ext2fs_crc16(~0, fs->sb->unique_id, + sizeof(fs->sb->unique_id)); + crc = ext2fs_crc16(crc, &i, sizeof(i)); + crc = ext2fs_crc16(crc, desc, offset); + offset += sizeof(desc->bg_checksum); /* skip checksum */ + assert(offset == sizeof(*desc)); + } + + return crc; +} + +static int check_void_in_dentry(struct ext2_dirent *dir, char *filename) +{ + int dentry_length; + int sizeof_void_space; + int new_entry_byte_reqd; + short padding_factor = 0; + + if (dir->namelen % 4 != 0) + padding_factor = 4 - (dir->namelen % 4); + + dentry_length = sizeof(struct ext2_dirent) + + dir->namelen + padding_factor; + sizeof_void_space = dir->direntlen - dentry_length; + if (sizeof_void_space == 0) + return 0; + + padding_factor = 0; + if (strlen(filename) % 4 != 0) + padding_factor = 4 - (strlen(filename) % 4); + + new_entry_byte_reqd = strlen(filename) + + sizeof(struct ext2_dirent) + padding_factor; + if (sizeof_void_space >= new_entry_byte_reqd) { + dir->direntlen = dentry_length; + return sizeof_void_space; + } + + return 0; +} + +void ext4fs_update_parent_dentry(char *filename, int *p_ino, int file_type) +{ + unsigned int *zero_buffer = NULL; + char *root_first_block_buffer = NULL; + int direct_blk_idx; + long int root_blknr; + long int first_block_no_of_root = 0; + long int previous_blknr = -1; + int totalbytes = 0; + short int padding_factor = 0; + unsigned int new_entry_byte_reqd; + unsigned int last_entry_dirlen; + int sizeof_void_space = 0; + int templength = 0; + int inodeno; + int status; + struct ext_filesystem *fs = get_fs(); + /* directory entry */ + struct ext2_dirent *dir; + char *ptr = NULL; + char *temp_dir = NULL; + + zero_buffer = zalloc(fs->blksz); + if (!zero_buffer) { + printf("No Memory\n"); + return; + } + root_first_block_buffer = zalloc(fs->blksz); + if (!root_first_block_buffer) { + free(zero_buffer); + printf("No Memory\n"); + return; + } +restart: + + /* read the block no allocated to a file */ + for (direct_blk_idx = 0; direct_blk_idx < INDIRECT_BLOCKS; + direct_blk_idx++) { + root_blknr = read_allocated_block(g_parent_inode, + direct_blk_idx); + if (root_blknr == 0) { + first_block_no_of_root = previous_blknr; + break; + } + previous_blknr = root_blknr; + } + + status = ext4fs_devread(first_block_no_of_root + * fs->sect_perblk, + 0, fs->blksz, root_first_block_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(root_first_block_buffer, first_block_no_of_root)) + goto fail; + dir = (struct ext2_dirent *)root_first_block_buffer; + ptr = (char *)dir; + totalbytes = 0; + while (dir->direntlen > 0) { + /* + * blocksize-totalbytes because last directory length + * i.e. dir->direntlen is free availble space in the + * block that means it is a last entry of directory + * entry + */ + + /* traversing the each directory entry */ + if (fs->blksz - totalbytes == dir->direntlen) { + if (strlen(filename) % 4 != 0) + padding_factor = 4 - (strlen(filename) % 4); + + new_entry_byte_reqd = strlen(filename) + + sizeof(struct ext2_dirent) + padding_factor; + padding_factor = 0; + /* + * update last directory entry length to its + * length because we are creating new directory + * entry + */ + if (dir->namelen % 4 != 0) + padding_factor = 4 - (dir->namelen % 4); + + last_entry_dirlen = dir->namelen + + sizeof(struct ext2_dirent) + padding_factor; + if ((fs->blksz - totalbytes - last_entry_dirlen) < + new_entry_byte_reqd) { + printf("1st Block Full:Allocate new block\n"); + + if (direct_blk_idx == INDIRECT_BLOCKS - 1) { + printf("Directory exceeds limit\n"); + goto fail; + } + g_parent_inode->b.blocks.dir_blocks + [direct_blk_idx] = ext4fs_get_new_blk_no(); + if (g_parent_inode->b.blocks.dir_blocks + [direct_blk_idx] == -1) { + printf("no block left to assign\n"); + goto fail; + } + put_ext4(((uint64_t) + (g_parent_inode->b. + blocks.dir_blocks[direct_blk_idx] * + fs->blksz)), zero_buffer, fs->blksz); + g_parent_inode->size = + g_parent_inode->size + fs->blksz; + g_parent_inode->blockcnt = + g_parent_inode->blockcnt + fs->sect_perblk; + if (ext4fs_put_metadata + (root_first_block_buffer, + first_block_no_of_root)) + goto fail; + goto restart; + } + dir->direntlen = last_entry_dirlen; + break; + } + + templength = dir->direntlen; + totalbytes = totalbytes + templength; + sizeof_void_space = check_void_in_dentry(dir, filename); + if (sizeof_void_space) + break; + + dir = (struct ext2_dirent *)((char *)dir + templength); + ptr = (char *)dir; + } + + /* make a pointer ready for creating next directory entry */ + templength = dir->direntlen; + totalbytes = totalbytes + templength; + dir = (struct ext2_dirent *)((char *)dir + templength); + ptr = (char *)dir; + + /* get the next available inode number */ + inodeno = ext4fs_get_new_inode_no(); + if (inodeno == -1) { + printf("no inode left to assign\n"); + goto fail; + } + dir->inode = inodeno; + if (sizeof_void_space) + dir->direntlen = sizeof_void_space; + else + dir->direntlen = fs->blksz - totalbytes; + + dir->namelen = strlen(filename); + dir->filetype = FILETYPE_REG; /* regular file */ + temp_dir = (char *)dir; + temp_dir = temp_dir + sizeof(struct ext2_dirent); + memcpy(temp_dir, filename, strlen(filename)); + + *p_ino = inodeno; + + /* update or write the 1st block of root inode */ + if (ext4fs_put_metadata(root_first_block_buffer, + first_block_no_of_root)) + goto fail; + +fail: + free(zero_buffer); + free(root_first_block_buffer); +} + +static int search_dir(struct ext2_inode *parent_inode, char *dirname) +{ + int status; + int inodeno; + int totalbytes; + int templength; + int direct_blk_idx; + long int blknr; + int found = 0; + char *ptr = NULL; + unsigned char *block_buffer = NULL; + struct ext2_dirent *dir = NULL; + struct ext2_dirent *previous_dir = NULL; + struct ext_filesystem *fs = get_fs(); + + /* read the block no allocated to a file */ + for (direct_blk_idx = 0; direct_blk_idx < INDIRECT_BLOCKS; + direct_blk_idx++) { + blknr = read_allocated_block(parent_inode, direct_blk_idx); + if (blknr == 0) + goto fail; + + /* read the blocks of parenet inode */ + block_buffer = zalloc(fs->blksz); + if (!block_buffer) + goto fail; + + status = ext4fs_devread(blknr * fs->sect_perblk, + 0, fs->blksz, (char *)block_buffer); + if (status == 0) + goto fail; + + dir = (struct ext2_dirent *)block_buffer; + ptr = (char *)dir; + totalbytes = 0; + while (dir->direntlen >= 0) { + /* + * blocksize-totalbytes because last directory + * length i.e.,*dir->direntlen is free availble + * space in the block that means + * it is a last entry of directory entry + */ + if (strlen(dirname) == dir->namelen) { + if (strncmp(dirname, ptr + + sizeof(struct ext2_dirent), + dir->namelen) == 0) { + previous_dir->direntlen += + dir->direntlen; + inodeno = dir->inode; + dir->inode = 0; + found = 1; + break; + } + } + + if (fs->blksz - totalbytes == dir->direntlen) + break; + + /* traversing the each directory entry */ + templength = dir->direntlen; + totalbytes = totalbytes + templength; + previous_dir = dir; + dir = (struct ext2_dirent *)((char *)dir + templength); + ptr = (char *)dir; + } + + if (found == 1) { + free(block_buffer); + block_buffer = NULL; + return inodeno; + } + + free(block_buffer); + block_buffer = NULL; + } + +fail: + free(block_buffer); + + return -1; +} + +static int find_dir_depth(char *dirname) +{ + char *token = strtok(dirname, "/"); + int count = 0; + while (token != NULL) { + token = strtok(NULL, "/"); + count++; + } + return count + 1 + 1; + /* + * for example for string /home/temp + * depth=home(1)+temp(1)+1 extra for NULL; + * so count is 4; + */ +} + +static int parse_path(char **arr, char *dirname) +{ + char *token = strtok(dirname, "/"); + int i = 0; + + /* add root */ + arr[i] = zalloc(strlen("/") + 1); + if (!arr[i]) + return -ENOMEM; + + arr[i++] = "/"; + + /* add each path entry after root */ + while (token != NULL) { + arr[i] = zalloc(strlen(token) + 1); + if (!arr[i]) + return -ENOMEM; + memcpy(arr[i++], token, strlen(token)); + token = strtok(NULL, "/"); + } + arr[i] = NULL; + + return 0; +} + +int ext4fs_iget(int inode_no, struct ext2_inode *inode) +{ + if (ext4fs_read_inode(ext4fs_root, inode_no, inode) == 0) + return -1; + + return 0; +} + +/* + * Function: ext4fs_get_parent_inode_num + * Return Value: inode Number of the parent directory of file/Directory to be + * created + * dirname : Input parmater, input path name of the file/directory to be created + * dname : Output parameter, to be filled with the name of the directory + * extracted from dirname + */ +int ext4fs_get_parent_inode_num(const char *dirname, char *dname, int flags) +{ + int i; + int depth = 0; + int matched_inode_no; + int result_inode_no = -1; + char **ptr = NULL; + char *depth_dirname = NULL; + char *parse_dirname = NULL; + struct ext2_inode *parent_inode = NULL; + struct ext2_inode *first_inode = NULL; + struct ext2_inode temp_inode; + + if (*dirname != '/') { + printf("Please supply Absolute path\n"); + return -1; + } + + /* TODO: input validation make equivalent to linux */ + depth_dirname = zalloc(strlen(dirname) + 1); + if (!depth_dirname) + return -ENOMEM; + + memcpy(depth_dirname, dirname, strlen(dirname)); + depth = find_dir_depth(depth_dirname); + parse_dirname = zalloc(strlen(dirname) + 1); + if (!parse_dirname) + goto fail; + memcpy(parse_dirname, dirname, strlen(dirname)); + + /* allocate memory for each directory level */ + ptr = zalloc((depth) * sizeof(char *)); + if (!ptr) + goto fail; + if (parse_path(ptr, parse_dirname)) + goto fail; + parent_inode = zalloc(sizeof(struct ext2_inode)); + if (!parent_inode) + goto fail; + first_inode = zalloc(sizeof(struct ext2_inode)); + if (!first_inode) + goto fail; + memcpy(parent_inode, ext4fs_root->inode, sizeof(struct ext2_inode)); + memcpy(first_inode, parent_inode, sizeof(struct ext2_inode)); + if (flags & F_FILE) + result_inode_no = EXT2_ROOT_INO; + for (i = 1; i < depth; i++) { + matched_inode_no = search_dir(parent_inode, ptr[i]); + if (matched_inode_no == -1) { + if (ptr[i + 1] == NULL && i == 1) { + result_inode_no = EXT2_ROOT_INO; + goto end; + } else { + if (ptr[i + 1] == NULL) + break; + printf("Invalid path\n"); + result_inode_no = -1; + goto fail; + } + } else { + if (ptr[i + 1] != NULL) { + memset(parent_inode, '\0', + sizeof(struct ext2_inode)); + if (ext4fs_iget(matched_inode_no, + parent_inode)) { + result_inode_no = -1; + goto fail; + } + result_inode_no = matched_inode_no; + } else { + break; + } + } + } + +end: + if (i == 1) + matched_inode_no = search_dir(first_inode, ptr[i]); + else + matched_inode_no = search_dir(parent_inode, ptr[i]); + + if (matched_inode_no != -1) { + ext4fs_iget(matched_inode_no, &temp_inode); + if (temp_inode.mode & S_IFDIR) { + printf("It is a Directory\n"); + result_inode_no = -1; + goto fail; + } + } + + if (strlen(ptr[i]) > 256) { + result_inode_no = -1; + goto fail; + } + memcpy(dname, ptr[i], strlen(ptr[i])); + +fail: + free(depth_dirname); + free(parse_dirname); + free(ptr); + free(parent_inode); + free(first_inode); + + return result_inode_no; +} + +static int check_filename(char *filename, unsigned int blknr) +{ + unsigned int first_block_no_of_root; + int totalbytes = 0; + int templength = 0; + int status, inodeno; + int found = 0; + char *root_first_block_buffer = NULL; + char *root_first_block_addr = NULL; + struct ext2_dirent *dir = NULL; + struct ext2_dirent *previous_dir = NULL; + char *ptr = NULL; + struct ext_filesystem *fs = get_fs(); + + /* get the first block of root */ + first_block_no_of_root = blknr; + root_first_block_buffer = zalloc(fs->blksz); + if (!root_first_block_buffer) + return -ENOMEM; + root_first_block_addr = root_first_block_buffer; + status = ext4fs_devread(first_block_no_of_root * + fs->sect_perblk, 0, + fs->blksz, root_first_block_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(root_first_block_buffer, first_block_no_of_root)) + goto fail; + dir = (struct ext2_dirent *)root_first_block_buffer; + ptr = (char *)dir; + totalbytes = 0; + while (dir->direntlen >= 0) { + /* + * blocksize-totalbytes because last + * directory length i.e., *dir->direntlen + * is free availble space in the block that + * means it is a last entry of directory entry + */ + if (strlen(filename) == dir->namelen) { + if (strncmp(filename, ptr + sizeof(struct ext2_dirent), + dir->namelen) == 0) { + printf("file found deleting\n"); + previous_dir->direntlen += dir->direntlen; + inodeno = dir->inode; + dir->inode = 0; + found = 1; + break; + } + } + + if (fs->blksz - totalbytes == dir->direntlen) + break; + + /* traversing the each directory entry */ + templength = dir->direntlen; + totalbytes = totalbytes + templength; + previous_dir = dir; + dir = (struct ext2_dirent *)((char *)dir + templength); + ptr = (char *)dir; + } + + + if (found == 1) { + if (ext4fs_put_metadata(root_first_block_addr, + first_block_no_of_root)) + goto fail; + return inodeno; + } +fail: + free(root_first_block_buffer); + + return -1; +} + +int ext4fs_filename_check(char *filename) +{ + short direct_blk_idx = 0; + long int blknr = -1; + int inodeno = -1; + + /* read the block no allocated to a file */ + for (direct_blk_idx = 0; direct_blk_idx < INDIRECT_BLOCKS; + direct_blk_idx++) { + blknr = read_allocated_block(g_parent_inode, direct_blk_idx); + if (blknr == 0) + break; + inodeno = check_filename(filename, blknr); + if (inodeno != -1) + return inodeno; + } + + return -1; +} + +long int ext4fs_get_new_blk_no(void) +{ + short i; + short status; + int remainder; + unsigned int bg_idx; + static int prev_bg_bitmap_index = -1; + unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; + struct ext_filesystem *fs = get_fs(); + char *journal_buffer = zalloc(fs->blksz); + char *zero_buffer = zalloc(fs->blksz); + if (!journal_buffer || !zero_buffer) + goto fail; + struct ext2_block_group *gd = (struct ext2_block_group *)fs->gdtable; + + if (fs->first_pass_bbmap == 0) { + for (i = 0; i < fs->no_blkgrp; i++) { + if (gd[i].free_blocks) { + if (gd[i].bg_flags & EXT4_BG_BLOCK_UNINIT) { + put_ext4(((uint64_t) (gd[i].block_id * + fs->blksz)), + zero_buffer, fs->blksz); + gd[i].bg_flags = + gd[i]. + bg_flags & ~EXT4_BG_BLOCK_UNINIT; + memcpy(fs->blk_bmaps[i], zero_buffer, + fs->blksz); + } + fs->curr_blkno = + _get_new_blk_no(fs->blk_bmaps[i]); + if (fs->curr_blkno == -1) + /* if block bitmap is completely fill */ + continue; + fs->curr_blkno = fs->curr_blkno + + (i * fs->blksz * 8); + fs->first_pass_bbmap++; + gd[i].free_blocks--; + fs->sb->free_blocks--; + status = ext4fs_devread(gd[i].block_id * + fs->sect_perblk, 0, + fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, + gd[i].block_id)) + goto fail; + goto success; + } else { + debug("no space left on block group %d\n", i); + } + } + + goto fail; + } else { +restart: + fs->curr_blkno++; + /* get the blockbitmap index respective to blockno */ + if (fs->blksz != 1024) { + bg_idx = fs->curr_blkno / blk_per_grp; + } else { + bg_idx = fs->curr_blkno / blk_per_grp; + remainder = fs->curr_blkno % blk_per_grp; + if (!remainder) + bg_idx--; + } + + /* + * To skip completely filled block group bitmaps + * Optimize the block allocation + */ + if (bg_idx >= fs->no_blkgrp) + goto fail; + + if (gd[bg_idx].free_blocks == 0) { + debug("block group %u is full. Skipping\n", bg_idx); + fs->curr_blkno = fs->curr_blkno + blk_per_grp; + fs->curr_blkno--; + goto restart; + } + + if (gd[bg_idx].bg_flags & EXT4_BG_BLOCK_UNINIT) { + memset(zero_buffer, '\0', fs->blksz); + put_ext4(((uint64_t) (gd[bg_idx].block_id * fs->blksz)), + zero_buffer, fs->blksz); + memcpy(fs->blk_bmaps[bg_idx], zero_buffer, fs->blksz); + gd[bg_idx].bg_flags = gd[bg_idx].bg_flags & + ~EXT4_BG_BLOCK_UNINIT; + } + + if (ext4fs_set_block_bmap(fs->curr_blkno, fs->blk_bmaps[bg_idx], + bg_idx) != 0) { + debug("going for restart for the block no %ld %u\n", + fs->curr_blkno, bg_idx); + goto restart; + } + + /* journal backup */ + if (prev_bg_bitmap_index != bg_idx) { + memset(journal_buffer, '\0', fs->blksz); + status = ext4fs_devread(gd[bg_idx].block_id + * fs->sect_perblk, + 0, fs->blksz, journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + + prev_bg_bitmap_index = bg_idx; + } + gd[bg_idx].free_blocks--; + fs->sb->free_blocks--; + goto success; + } +success: + free(journal_buffer); + free(zero_buffer); + + return fs->curr_blkno; +fail: + free(journal_buffer); + free(zero_buffer); + + return -1; +} + +int ext4fs_get_new_inode_no(void) +{ + short i; + short status; + unsigned int ibmap_idx; + static int prev_inode_bitmap_index = -1; + unsigned int inodes_per_grp = ext4fs_root->sblock.inodes_per_group; + struct ext_filesystem *fs = get_fs(); + char *journal_buffer = zalloc(fs->blksz); + char *zero_buffer = zalloc(fs->blksz); + if (!journal_buffer || !zero_buffer) + goto fail; + struct ext2_block_group *gd = (struct ext2_block_group *)fs->gdtable; + + if (fs->first_pass_ibmap == 0) { + for (i = 0; i < fs->no_blkgrp; i++) { + if (gd[i].free_inodes) { + if (gd[i].bg_itable_unused != gd[i].free_inodes) + gd[i].bg_itable_unused = + gd[i].free_inodes; + if (gd[i].bg_flags & EXT4_BG_INODE_UNINIT) { + put_ext4(((uint64_t) + (gd[i].inode_id * fs->blksz)), + zero_buffer, fs->blksz); + gd[i].bg_flags = gd[i].bg_flags & + ~EXT4_BG_INODE_UNINIT; + memcpy(fs->inode_bmaps[i], + zero_buffer, fs->blksz); + } + fs->curr_inode_no = + _get_new_inode_no(fs->inode_bmaps[i]); + if (fs->curr_inode_no == -1) + /* if block bitmap is completely fill */ + continue; + fs->curr_inode_no = fs->curr_inode_no + + (i * inodes_per_grp); + fs->first_pass_ibmap++; + gd[i].free_inodes--; + gd[i].bg_itable_unused--; + fs->sb->free_inodes--; + status = ext4fs_devread(gd[i].inode_id * + fs->sect_perblk, 0, + fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, + gd[i].inode_id)) + goto fail; + goto success; + } else + debug("no inode left on block group %d\n", i); + } + goto fail; + } else { +restart: + fs->curr_inode_no++; + /* get the blockbitmap index respective to blockno */ + ibmap_idx = fs->curr_inode_no / inodes_per_grp; + if (gd[ibmap_idx].bg_flags & EXT4_BG_INODE_UNINIT) { + memset(zero_buffer, '\0', fs->blksz); + put_ext4(((uint64_t) (gd[ibmap_idx].inode_id * + fs->blksz)), zero_buffer, + fs->blksz); + gd[ibmap_idx].bg_flags = + gd[ibmap_idx].bg_flags & ~EXT4_BG_INODE_UNINIT; + memcpy(fs->inode_bmaps[ibmap_idx], zero_buffer, + fs->blksz); + } + + if (ext4fs_set_inode_bmap(fs->curr_inode_no, + fs->inode_bmaps[ibmap_idx], + ibmap_idx) != 0) { + debug("going for restart for the block no %d %u\n", + fs->curr_inode_no, ibmap_idx); + goto restart; + } + + /* journal backup */ + if (prev_inode_bitmap_index != ibmap_idx) { + memset(journal_buffer, '\0', fs->blksz); + status = ext4fs_devread(gd[ibmap_idx].inode_id + * fs->sect_perblk, + 0, fs->blksz, journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, + gd[ibmap_idx].inode_id)) + goto fail; + prev_inode_bitmap_index = ibmap_idx; + } + if (gd[ibmap_idx].bg_itable_unused != gd[ibmap_idx].free_inodes) + gd[ibmap_idx].bg_itable_unused = + gd[ibmap_idx].free_inodes; + gd[ibmap_idx].free_inodes--; + gd[ibmap_idx].bg_itable_unused--; + fs->sb->free_inodes--; + goto success; + } + +success: + free(journal_buffer); + free(zero_buffer); + + return fs->curr_inode_no; +fail: + free(journal_buffer); + free(zero_buffer); + + return -1; + +} + + +static void alloc_single_indirect_block(struct ext2_inode *file_inode, + unsigned int *total_remaining_blocks, + unsigned int *no_blks_reqd) +{ + short i; + short status; + long int actual_block_no; + long int si_blockno; + /* si :single indirect */ + unsigned int *si_buffer = NULL; + unsigned int *si_start_addr = NULL; + struct ext_filesystem *fs = get_fs(); + + if (*total_remaining_blocks != 0) { + si_buffer = zalloc(fs->blksz); + if (!si_buffer) { + printf("No Memory\n"); + return; + } + si_start_addr = si_buffer; + si_blockno = ext4fs_get_new_blk_no(); + if (si_blockno == -1) { + printf("no block left to assign\n"); + goto fail; + } + (*no_blks_reqd)++; + debug("SIPB %ld: %u\n", si_blockno, *total_remaining_blocks); + + status = ext4fs_devread(si_blockno * fs->sect_perblk, + 0, fs->blksz, (char *)si_buffer); + memset(si_buffer, '\0', fs->blksz); + if (status == 0) + goto fail; + + for (i = 0; i < (fs->blksz / sizeof(int)); i++) { + actual_block_no = ext4fs_get_new_blk_no(); + if (actual_block_no == -1) { + printf("no block left to assign\n"); + goto fail; + } + *si_buffer = actual_block_no; + debug("SIAB %u: %u\n", *si_buffer, + *total_remaining_blocks); + + si_buffer++; + (*total_remaining_blocks)--; + if (*total_remaining_blocks == 0) + break; + } + + /* write the block to disk */ + put_ext4(((uint64_t) (si_blockno * fs->blksz)), + si_start_addr, fs->blksz); + file_inode->b.blocks.indir_block = si_blockno; + } +fail: + free(si_start_addr); +} + +static void alloc_double_indirect_block(struct ext2_inode *file_inode, + unsigned int *total_remaining_blocks, + unsigned int *no_blks_reqd) +{ + short i; + short j; + short status; + long int actual_block_no; + /* di:double indirect */ + long int di_blockno_parent; + long int di_blockno_child; + unsigned int *di_parent_buffer = NULL; + unsigned int *di_child_buff = NULL; + unsigned int *di_block_start_addr = NULL; + unsigned int *di_child_buff_start = NULL; + struct ext_filesystem *fs = get_fs(); + + if (*total_remaining_blocks != 0) { + /* double indirect parent block connecting to inode */ + di_blockno_parent = ext4fs_get_new_blk_no(); + if (di_blockno_parent == -1) { + printf("no block left to assign\n"); + goto fail; + } + di_parent_buffer = zalloc(fs->blksz); + if (!di_parent_buffer) + goto fail; + + di_block_start_addr = di_parent_buffer; + (*no_blks_reqd)++; + debug("DIPB %ld: %u\n", di_blockno_parent, + *total_remaining_blocks); + + status = ext4fs_devread(di_blockno_parent * + fs->sect_perblk, 0, + fs->blksz, (char *)di_parent_buffer); + memset(di_parent_buffer, '\0', fs->blksz); + + /* + * start:for each double indirect parent + * block create one more block + */ + for (i = 0; i < (fs->blksz / sizeof(int)); i++) { + di_blockno_child = ext4fs_get_new_blk_no(); + if (di_blockno_child == -1) { + printf("no block left to assign\n"); + goto fail; + } + di_child_buff = zalloc(fs->blksz); + if (!di_child_buff) + goto fail; + + di_child_buff_start = di_child_buff; + *di_parent_buffer = di_blockno_child; + di_parent_buffer++; + (*no_blks_reqd)++; + debug("DICB %ld: %u\n", di_blockno_child, + *total_remaining_blocks); + + status = ext4fs_devread(di_blockno_child * + fs->sect_perblk, 0, + fs->blksz, + (char *)di_child_buff); + memset(di_child_buff, '\0', fs->blksz); + /* filling of actual datablocks for each child */ + for (j = 0; j < (fs->blksz / sizeof(int)); j++) { + actual_block_no = ext4fs_get_new_blk_no(); + if (actual_block_no == -1) { + printf("no block left to assign\n"); + goto fail; + } + *di_child_buff = actual_block_no; + debug("DIAB %ld: %u\n", actual_block_no, + *total_remaining_blocks); + + di_child_buff++; + (*total_remaining_blocks)--; + if (*total_remaining_blocks == 0) + break; + } + /* write the block table */ + put_ext4(((uint64_t) (di_blockno_child * fs->blksz)), + di_child_buff_start, fs->blksz); + free(di_child_buff_start); + di_child_buff_start = NULL; + + if (*total_remaining_blocks == 0) + break; + } + put_ext4(((uint64_t) (di_blockno_parent * fs->blksz)), + di_block_start_addr, fs->blksz); + file_inode->b.blocks.double_indir_block = di_blockno_parent; + } +fail: + free(di_block_start_addr); +} + +static void alloc_triple_indirect_block(struct ext2_inode *file_inode, + unsigned int *total_remaining_blocks, + unsigned int *no_blks_reqd) +{ + short i; + short j; + short k; + long int actual_block_no; + /* ti: Triple Indirect */ + long int ti_gp_blockno; + long int ti_parent_blockno; + long int ti_child_blockno; + unsigned int *ti_gp_buff = NULL; + unsigned int *ti_parent_buff = NULL; + unsigned int *ti_child_buff = NULL; + unsigned int *ti_gp_buff_start_addr = NULL; + unsigned int *ti_pbuff_start_addr = NULL; + unsigned int *ti_cbuff_start_addr = NULL; + struct ext_filesystem *fs = get_fs(); + if (*total_remaining_blocks != 0) { + /* triple indirect grand parent block connecting to inode */ + ti_gp_blockno = ext4fs_get_new_blk_no(); + if (ti_gp_blockno == -1) { + printf("no block left to assign\n"); + goto fail; + } + ti_gp_buff = zalloc(fs->blksz); + if (!ti_gp_buff) + goto fail; + + ti_gp_buff_start_addr = ti_gp_buff; + (*no_blks_reqd)++; + debug("TIGPB %ld: %u\n", ti_gp_blockno, + *total_remaining_blocks); + + /* for each 4 byte grand parent entry create one more block */ + for (i = 0; i < (fs->blksz / sizeof(int)); i++) { + ti_parent_blockno = ext4fs_get_new_blk_no(); + if (ti_parent_blockno == -1) { + printf("no block left to assign\n"); + goto fail; + } + ti_parent_buff = zalloc(fs->blksz); + if (!ti_parent_buff) + goto fail; + + ti_pbuff_start_addr = ti_parent_buff; + *ti_gp_buff = ti_parent_blockno; + ti_gp_buff++; + (*no_blks_reqd)++; + debug("TIPB %ld: %u\n", ti_parent_blockno, + *total_remaining_blocks); + + /* for each 4 byte entry parent create one more block */ + for (j = 0; j < (fs->blksz / sizeof(int)); j++) { + ti_child_blockno = ext4fs_get_new_blk_no(); + if (ti_child_blockno == -1) { + printf("no block left assign\n"); + goto fail; + } + ti_child_buff = zalloc(fs->blksz); + if (!ti_child_buff) + goto fail; + + ti_cbuff_start_addr = ti_child_buff; + *ti_parent_buff = ti_child_blockno; + ti_parent_buff++; + (*no_blks_reqd)++; + debug("TICB %ld: %u\n", ti_parent_blockno, + *total_remaining_blocks); + + /* fill actual datablocks for each child */ + for (k = 0; k < (fs->blksz / sizeof(int)); + k++) { + actual_block_no = + ext4fs_get_new_blk_no(); + if (actual_block_no == -1) { + printf("no block left\n"); + goto fail; + } + *ti_child_buff = actual_block_no; + debug("TIAB %ld: %u\n", actual_block_no, + *total_remaining_blocks); + + ti_child_buff++; + (*total_remaining_blocks)--; + if (*total_remaining_blocks == 0) + break; + } + /* write the child block */ + put_ext4(((uint64_t) (ti_child_blockno * + fs->blksz)), + ti_cbuff_start_addr, fs->blksz); + free(ti_cbuff_start_addr); + + if (*total_remaining_blocks == 0) + break; + } + /* write the parent block */ + put_ext4(((uint64_t) (ti_parent_blockno * fs->blksz)), + ti_pbuff_start_addr, fs->blksz); + free(ti_pbuff_start_addr); + + if (*total_remaining_blocks == 0) + break; + } + /* write the grand parent block */ + put_ext4(((uint64_t) (ti_gp_blockno * fs->blksz)), + ti_gp_buff_start_addr, fs->blksz); + file_inode->b.blocks.triple_indir_block = ti_gp_blockno; + } +fail: + free(ti_gp_buff_start_addr); +} + +void ext4fs_allocate_blocks(struct ext2_inode *file_inode, + unsigned int total_remaining_blocks, + unsigned int *total_no_of_block) +{ + short i; + long int direct_blockno; + unsigned int no_blks_reqd = 0; + + /* allocation of direct blocks */ + for (i = 0; i < INDIRECT_BLOCKS; i++) { + direct_blockno = ext4fs_get_new_blk_no(); + if (direct_blockno == -1) { + printf("no block left to assign\n"); + return; + } + file_inode->b.blocks.dir_blocks[i] = direct_blockno; + debug("DB %ld: %u\n", direct_blockno, total_remaining_blocks); + + total_remaining_blocks--; + if (total_remaining_blocks == 0) + break; + } + + alloc_single_indirect_block(file_inode, &total_remaining_blocks, + &no_blks_reqd); + alloc_double_indirect_block(file_inode, &total_remaining_blocks, + &no_blks_reqd); + alloc_triple_indirect_block(file_inode, &total_remaining_blocks, + &no_blks_reqd); + *total_no_of_block += no_blks_reqd; +} + +#endif + +static struct ext4_extent_header *ext4fs_get_extent_block + (struct ext2_data *data, char *buf, + struct ext4_extent_header *ext_block, + uint32_t fileblock, int log2_blksz) +{ + struct ext4_extent_idx *index; + unsigned long long block; + struct ext_filesystem *fs = get_fs(); + int i; + + while (1) { + index = (struct ext4_extent_idx *)(ext_block + 1); + + if (le32_to_cpu(ext_block->eh_magic) != EXT4_EXT_MAGIC) + return 0; + + if (ext_block->eh_depth == 0) + return ext_block; + i = -1; + do { + i++; + if (i >= le32_to_cpu(ext_block->eh_entries)) + break; + } while (fileblock > le32_to_cpu(index[i].ei_block)); + + if (--i < 0) + return 0; + + block = le32_to_cpu(index[i].ei_leaf_hi); + block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo); + + if (ext4fs_devread(block << log2_blksz, 0, fs->blksz, buf)) + ext_block = (struct ext4_extent_header *)buf; + else + return 0; + } +} + +static int ext4fs_blockgroup + (struct ext2_data *data, int group, struct ext2_block_group *blkgrp) +{ + long int blkno; + unsigned int blkoff, desc_per_blk; + + desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group); + + blkno = __le32_to_cpu(data->sblock.first_data_block) + 1 + + group / desc_per_blk; + blkoff = (group % desc_per_blk) * sizeof(struct ext2_block_group); + + debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n", + group, blkno, blkoff); + + return ext4fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data), + blkoff, sizeof(struct ext2_block_group), + (char *)blkgrp); +} + +int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode) +{ + struct ext2_block_group blkgrp; + struct ext2_sblock *sblock = &data->sblock; + struct ext_filesystem *fs = get_fs(); + int inodes_per_block, status; + long int blkno; + unsigned int blkoff; + + /* It is easier to calculate if the first inode is 0. */ + ino--; + status = ext4fs_blockgroup(data, ino / __le32_to_cpu + (sblock->inodes_per_group), &blkgrp); + if (status == 0) + return 0; + + inodes_per_block = EXT2_BLOCK_SIZE(data) / fs->inodesz; + blkno = __le32_to_cpu(blkgrp.inode_table_id) + + (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block; + blkoff = (ino % inodes_per_block) * fs->inodesz; + /* Read the inode. */ + status = ext4fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data), blkoff, + sizeof(struct ext2_inode), (char *)inode); + if (status == 0) + return 0; + + return 1; +} + +long int read_allocated_block(struct ext2_inode *inode, int fileblock) +{ + long int blknr; + int blksz; + int log2_blksz; + int status; + long int rblock; + long int perblock_parent; + long int perblock_child; + unsigned long long start; + /* get the blocksize of the filesystem */ + blksz = EXT2_BLOCK_SIZE(ext4fs_root); + log2_blksz = LOG2_EXT2_BLOCK_SIZE(ext4fs_root); + if (le32_to_cpu(inode->flags) & EXT4_EXTENTS_FL) { + char *buf = zalloc(blksz); + if (!buf) + return -ENOMEM; + struct ext4_extent_header *ext_block; + struct ext4_extent *extent; + int i = -1; + ext_block = ext4fs_get_extent_block(ext4fs_root, buf, + (struct ext4_extent_header + *)inode->b. + blocks.dir_blocks, + fileblock, log2_blksz); + if (!ext_block) { + printf("invalid extent block\n"); + free(buf); + return -EINVAL; + } + + extent = (struct ext4_extent *)(ext_block + 1); + + do { + i++; + if (i >= le32_to_cpu(ext_block->eh_entries)) + break; + } while (fileblock >= le32_to_cpu(extent[i].ee_block)); + if (--i >= 0) { + fileblock -= le32_to_cpu(extent[i].ee_block); + if (fileblock >= le32_to_cpu(extent[i].ee_len)) { + free(buf); + return 0; + } + + start = le32_to_cpu(extent[i].ee_start_hi); + start = (start << 32) + + le32_to_cpu(extent[i].ee_start_lo); + free(buf); + return fileblock + start; + } + + printf("Extent Error\n"); + free(buf); + return -1; + } + + /* Direct blocks. */ + if (fileblock < INDIRECT_BLOCKS) + blknr = __le32_to_cpu(inode->b.blocks.dir_blocks[fileblock]); + + /* Indirect. */ + else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) { + if (ext4fs_indir1_block == NULL) { + ext4fs_indir1_block = zalloc(blksz); + if (ext4fs_indir1_block == NULL) { + printf("** SI ext2fs read block (indir 1)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir1_size = blksz; + ext4fs_indir1_blkno = -1; + } + if (blksz != ext4fs_indir1_size) { + free(ext4fs_indir1_block); + ext4fs_indir1_block = NULL; + ext4fs_indir1_size = 0; + ext4fs_indir1_blkno = -1; + ext4fs_indir1_block = zalloc(blksz); + if (ext4fs_indir1_block == NULL) { + printf("** SI ext2fs read block (indir 1):" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir1_size = blksz; + } + if ((__le32_to_cpu(inode->b.blocks.indir_block) << + log2_blksz) != ext4fs_indir1_blkno) { + status = + ext4fs_devread(__le32_to_cpu + (inode->b.blocks. + indir_block) << log2_blksz, 0, + blksz, (char *)ext4fs_indir1_block); + if (status == 0) { + printf("** SI ext2fs read block (indir 1)" + "failed. **\n"); + return 0; + } + ext4fs_indir1_blkno = + __le32_to_cpu(inode->b.blocks. + indir_block) << log2_blksz; + } + blknr = __le32_to_cpu(ext4fs_indir1_block + [fileblock - INDIRECT_BLOCKS]); + } + /* Double indirect. */ + else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4 * + (blksz / 4 + 1)))) { + + long int perblock = blksz / 4; + long int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4); + + if (ext4fs_indir1_block == NULL) { + ext4fs_indir1_block = zalloc(blksz); + if (ext4fs_indir1_block == NULL) { + printf("** DI ext2fs read block (indir 2 1)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir1_size = blksz; + ext4fs_indir1_blkno = -1; + } + if (blksz != ext4fs_indir1_size) { + free(ext4fs_indir1_block); + ext4fs_indir1_block = NULL; + ext4fs_indir1_size = 0; + ext4fs_indir1_blkno = -1; + ext4fs_indir1_block = zalloc(blksz); + if (ext4fs_indir1_block == NULL) { + printf("** DI ext2fs read block (indir 2 1)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir1_size = blksz; + } + if ((__le32_to_cpu(inode->b.blocks.double_indir_block) << + log2_blksz) != ext4fs_indir1_blkno) { + status = + ext4fs_devread(__le32_to_cpu + (inode->b.blocks. + double_indir_block) << log2_blksz, + 0, blksz, + (char *)ext4fs_indir1_block); + if (status == 0) { + printf("** DI ext2fs read block (indir 2 1)" + "failed. **\n"); + return -1; + } + ext4fs_indir1_blkno = + __le32_to_cpu(inode->b.blocks.double_indir_block) << + log2_blksz; + } + + if (ext4fs_indir2_block == NULL) { + ext4fs_indir2_block = zalloc(blksz); + if (ext4fs_indir2_block == NULL) { + printf("** DI ext2fs read block (indir 2 2)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir2_size = blksz; + ext4fs_indir2_blkno = -1; + } + if (blksz != ext4fs_indir2_size) { + free(ext4fs_indir2_block); + ext4fs_indir2_block = NULL; + ext4fs_indir2_size = 0; + ext4fs_indir2_blkno = -1; + ext4fs_indir2_block = zalloc(blksz); + if (ext4fs_indir2_block == NULL) { + printf("** DI ext2fs read block (indir 2 2)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir2_size = blksz; + } + if ((__le32_to_cpu(ext4fs_indir1_block[rblock / perblock]) << + log2_blksz) != ext4fs_indir2_blkno) { + status = ext4fs_devread(__le32_to_cpu + (ext4fs_indir1_block + [rblock / + perblock]) << log2_blksz, 0, + blksz, + (char *)ext4fs_indir2_block); + if (status == 0) { + printf("** DI ext2fs read block (indir 2 2)" + "failed. **\n"); + return -1; + } + ext4fs_indir2_blkno = + __le32_to_cpu(ext4fs_indir1_block[rblock + / + perblock]) << + log2_blksz; + } + blknr = __le32_to_cpu(ext4fs_indir2_block[rblock % perblock]); + } + /* Tripple indirect. */ + else { + rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4 + + (blksz / 4 * blksz / 4)); + perblock_child = blksz / 4; + perblock_parent = ((blksz / 4) * (blksz / 4)); + + if (ext4fs_indir1_block == NULL) { + ext4fs_indir1_block = zalloc(blksz); + if (ext4fs_indir1_block == NULL) { + printf("** TI ext2fs read block (indir 2 1)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir1_size = blksz; + ext4fs_indir1_blkno = -1; + } + if (blksz != ext4fs_indir1_size) { + free(ext4fs_indir1_block); + ext4fs_indir1_block = NULL; + ext4fs_indir1_size = 0; + ext4fs_indir1_blkno = -1; + ext4fs_indir1_block = zalloc(blksz); + if (ext4fs_indir1_block == NULL) { + printf("** TI ext2fs read block (indir 2 1)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir1_size = blksz; + } + if ((__le32_to_cpu(inode->b.blocks.triple_indir_block) << + log2_blksz) != ext4fs_indir1_blkno) { + status = ext4fs_devread + (__le32_to_cpu(inode->b.blocks.triple_indir_block) + << log2_blksz, 0, blksz, + (char *)ext4fs_indir1_block); + if (status == 0) { + printf("** TI ext2fs read block (indir 2 1)" + "failed. **\n"); + return -1; + } + ext4fs_indir1_blkno = + __le32_to_cpu(inode->b.blocks.triple_indir_block) << + log2_blksz; + } + + if (ext4fs_indir2_block == NULL) { + ext4fs_indir2_block = zalloc(blksz); + if (ext4fs_indir2_block == NULL) { + printf("** TI ext2fs read block (indir 2 2)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir2_size = blksz; + ext4fs_indir2_blkno = -1; + } + if (blksz != ext4fs_indir2_size) { + free(ext4fs_indir2_block); + ext4fs_indir2_block = NULL; + ext4fs_indir2_size = 0; + ext4fs_indir2_blkno = -1; + ext4fs_indir2_block = zalloc(blksz); + if (ext4fs_indir2_block == NULL) { + printf("** TI ext2fs read block (indir 2 2)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir2_size = blksz; + } + if ((__le32_to_cpu(ext4fs_indir1_block[rblock / + perblock_parent]) << + log2_blksz) + != ext4fs_indir2_blkno) { + status = ext4fs_devread(__le32_to_cpu + (ext4fs_indir1_block + [rblock / + perblock_parent]) << + log2_blksz, 0, blksz, + (char *)ext4fs_indir2_block); + if (status == 0) { + printf("** TI ext2fs read block (indir 2 2)" + "failed. **\n"); + return -1; + } + ext4fs_indir2_blkno = + __le32_to_cpu(ext4fs_indir1_block[rblock / + perblock_parent]) + << log2_blksz; + } + + if (ext4fs_indir3_block == NULL) { + ext4fs_indir3_block = zalloc(blksz); + if (ext4fs_indir3_block == NULL) { + printf("** TI ext2fs read block (indir 2 2)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir3_size = blksz; + ext4fs_indir3_blkno = -1; + } + if (blksz != ext4fs_indir3_size) { + free(ext4fs_indir3_block); + ext4fs_indir3_block = NULL; + ext4fs_indir3_size = 0; + ext4fs_indir3_blkno = -1; + ext4fs_indir3_block = zalloc(blksz); + if (ext4fs_indir3_block == NULL) { + printf("** TI ext2fs read block (indir 2 2)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir3_size = blksz; + } + if ((__le32_to_cpu(ext4fs_indir2_block[rblock + / + perblock_child]) << + log2_blksz) != ext4fs_indir3_blkno) { + status = + ext4fs_devread(__le32_to_cpu + (ext4fs_indir2_block + [(rblock / perblock_child) + % (blksz / 4)]) << log2_blksz, 0, + blksz, (char *)ext4fs_indir3_block); + if (status == 0) { + printf("** TI ext2fs read block (indir 2 2)" + "failed. **\n"); + return -1; + } + ext4fs_indir3_blkno = + __le32_to_cpu(ext4fs_indir2_block[(rblock / + perblock_child) % + (blksz / + 4)]) << + log2_blksz; + } + + blknr = __le32_to_cpu(ext4fs_indir3_block + [rblock % perblock_child]); + } + debug("ext4fs_read_block %ld\n", blknr); + + return blknr; +} + +void ext4fs_close(void) +{ + if ((ext4fs_file != NULL) && (ext4fs_root != NULL)) { + ext4fs_free_node(ext4fs_file, &ext4fs_root->diropen); + ext4fs_file = NULL; + } + if (ext4fs_root != NULL) { + free(ext4fs_root); + ext4fs_root = NULL; + } + if (ext4fs_indir1_block != NULL) { + free(ext4fs_indir1_block); + ext4fs_indir1_block = NULL; + ext4fs_indir1_size = 0; + ext4fs_indir1_blkno = -1; + } + if (ext4fs_indir2_block != NULL) { + free(ext4fs_indir2_block); + ext4fs_indir2_block = NULL; + ext4fs_indir2_size = 0; + ext4fs_indir2_blkno = -1; + } + if (ext4fs_indir3_block != NULL) { + free(ext4fs_indir3_block); + ext4fs_indir3_block = NULL; + ext4fs_indir3_size = 0; + ext4fs_indir3_blkno = -1; + } +} + +int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, + struct ext2fs_node **fnode, int *ftype) +{ + unsigned int fpos = 0; + int status; + struct ext2fs_node *diro = (struct ext2fs_node *) dir; + +#ifdef DEBUG + if (name != NULL) + printf("Iterate dir %s\n", name); +#endif /* of DEBUG */ + if (!diro->inode_read) { + status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode); + if (status == 0) + return 0; + } + /* Search the file. */ + while (fpos < __le32_to_cpu(diro->inode.size)) { + struct ext2_dirent dirent; + + status = ext4fs_read_file(diro, fpos, + sizeof(struct ext2_dirent), + (char *) &dirent); + if (status < 1) + return 0; + + if (dirent.namelen != 0) { + char filename[dirent.namelen + 1]; + struct ext2fs_node *fdiro; + int type = FILETYPE_UNKNOWN; + + status = ext4fs_read_file(diro, + fpos + + sizeof(struct ext2_dirent), + dirent.namelen, filename); + if (status < 1) + return 0; + + fdiro = zalloc(sizeof(struct ext2fs_node)); + if (!fdiro) + return 0; + + fdiro->data = diro->data; + fdiro->ino = __le32_to_cpu(dirent.inode); + + filename[dirent.namelen] = '\0'; + + if (dirent.filetype != FILETYPE_UNKNOWN) { + fdiro->inode_read = 0; + + if (dirent.filetype == FILETYPE_DIRECTORY) + type = FILETYPE_DIRECTORY; + else if (dirent.filetype == FILETYPE_SYMLINK) + type = FILETYPE_SYMLINK; + else if (dirent.filetype == FILETYPE_REG) + type = FILETYPE_REG; + } else { + status = ext4fs_read_inode(diro->data, + __le32_to_cpu + (dirent.inode), + &fdiro->inode); + if (status == 0) { + free(fdiro); + return 0; + } + fdiro->inode_read = 1; + + if ((__le16_to_cpu(fdiro->inode.mode) & + FILETYPE_INO_MASK) == + FILETYPE_INO_DIRECTORY) { + type = FILETYPE_DIRECTORY; + } else if ((__le16_to_cpu(fdiro->inode.mode) + & FILETYPE_INO_MASK) == + FILETYPE_INO_SYMLINK) { + type = FILETYPE_SYMLINK; + } else if ((__le16_to_cpu(fdiro->inode.mode) + & FILETYPE_INO_MASK) == + FILETYPE_INO_REG) { + type = FILETYPE_REG; + } + } +#ifdef DEBUG + printf("iterate >%s<\n", filename); +#endif /* of DEBUG */ + if ((name != NULL) && (fnode != NULL) + && (ftype != NULL)) { + if (strcmp(filename, name) == 0) { + *ftype = type; + *fnode = fdiro; + return 1; + } + } else { + if (fdiro->inode_read == 0) { + status = ext4fs_read_inode(diro->data, + __le32_to_cpu( + dirent.inode), + &fdiro->inode); + if (status == 0) { + free(fdiro); + return 0; + } + fdiro->inode_read = 1; + } + switch (type) { + case FILETYPE_DIRECTORY: + printf("<DIR> "); + break; + case FILETYPE_SYMLINK: + printf("<SYM> "); + break; + case FILETYPE_REG: + printf(" "); + break; + default: + printf("< ? > "); + break; + } + printf("%10d %s\n", + __le32_to_cpu(fdiro->inode.size), + filename); + } + free(fdiro); + } + fpos += __le16_to_cpu(dirent.direntlen); + } + return 0; +} + +static char *ext4fs_read_symlink(struct ext2fs_node *node) +{ + char *symlink; + struct ext2fs_node *diro = node; + int status; + + if (!diro->inode_read) { + status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode); + if (status == 0) + return 0; + } + symlink = zalloc(__le32_to_cpu(diro->inode.size) + 1); + if (!symlink) + return 0; + + if (__le32_to_cpu(diro->inode.size) <= 60) { + strncpy(symlink, diro->inode.b.symlink, + __le32_to_cpu(diro->inode.size)); + } else { + status = ext4fs_read_file(diro, 0, + __le32_to_cpu(diro->inode.size), + symlink); + if (status == 0) { + free(symlink); + return 0; + } + } + symlink[__le32_to_cpu(diro->inode.size)] = '\0'; + return symlink; +} + +static int ext4fs_find_file1(const char *currpath, + struct ext2fs_node *currroot, + struct ext2fs_node **currfound, int *foundtype) +{ + char fpath[strlen(currpath) + 1]; + char *name = fpath; + char *next; + int status; + int type = FILETYPE_DIRECTORY; + struct ext2fs_node *currnode = currroot; + struct ext2fs_node *oldnode = currroot; + + strncpy(fpath, currpath, strlen(currpath) + 1); + + /* Remove all leading slashes. */ + while (*name == '/') + name++; + + if (!*name) { + *currfound = currnode; + return 1; + } + + for (;;) { + int found; + + /* Extract the actual part from the pathname. */ + next = strchr(name, '/'); + if (next) { + /* Remove all leading slashes. */ + while (*next == '/') + *(next++) = '\0'; + } + + if (type != FILETYPE_DIRECTORY) { + ext4fs_free_node(currnode, currroot); + return 0; + } + + oldnode = currnode; + + /* Iterate over the directory. */ + found = ext4fs_iterate_dir(currnode, name, &currnode, &type); + if (found == 0) + return 0; + + if (found == -1) + break; + + /* Read in the symlink and follow it. */ + if (type == FILETYPE_SYMLINK) { + char *symlink; + + /* Test if the symlink does not loop. */ + if (++symlinknest == 8) { + ext4fs_free_node(currnode, currroot); + ext4fs_free_node(oldnode, currroot); + return 0; + } + + symlink = ext4fs_read_symlink(currnode); + ext4fs_free_node(currnode, currroot); + + if (!symlink) { + ext4fs_free_node(oldnode, currroot); + return 0; + } + + debug("Got symlink >%s<\n", symlink); + + if (symlink[0] == '/') { + ext4fs_free_node(oldnode, currroot); + oldnode = &ext4fs_root->diropen; + } + + /* Lookup the node the symlink points to. */ + status = ext4fs_find_file1(symlink, oldnode, + &currnode, &type); + + free(symlink); + + if (status == 0) { + ext4fs_free_node(oldnode, currroot); + return 0; + } + } + + ext4fs_free_node(oldnode, currroot); + + /* Found the node! */ + if (!next || *next == '\0') { + *currfound = currnode; + *foundtype = type; + return 1; + } + name = next; + } + return -1; +} + +int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode, + struct ext2fs_node **foundnode, int expecttype) +{ + int status; + int foundtype = FILETYPE_DIRECTORY; + + symlinknest = 0; + if (!path) + return 0; + + status = ext4fs_find_file1(path, rootnode, foundnode, &foundtype); + if (status == 0) + return 0; + + /* Check if the node that was found was of the expected type. */ + if ((expecttype == FILETYPE_REG) && (foundtype != expecttype)) + return 0; + else if ((expecttype == FILETYPE_DIRECTORY) + && (foundtype != expecttype)) + return 0; + + return 1; +} + +int ext4fs_open(const char *filename) +{ + struct ext2fs_node *fdiro = NULL; + int status; + int len; + + if (ext4fs_root == NULL) + return -1; + + ext4fs_file = NULL; + status = ext4fs_find_file(filename, &ext4fs_root->diropen, &fdiro, + FILETYPE_REG); + if (status == 0) + goto fail; + + if (!fdiro->inode_read) { + status = ext4fs_read_inode(fdiro->data, fdiro->ino, + &fdiro->inode); + if (status == 0) + goto fail; + } + len = __le32_to_cpu(fdiro->inode.size); + ext4fs_file = fdiro; + + return len; +fail: + ext4fs_free_node(fdiro, &ext4fs_root->diropen); + + return -1; +} + +int ext4fs_mount(unsigned part_length) +{ + struct ext2_data *data; + int status; + struct ext_filesystem *fs = get_fs(); + data = zalloc(sizeof(struct ext2_data)); + if (!data) + return 0; + + /* Read the superblock. */ + status = ext4fs_devread(1 * 2, 0, sizeof(struct ext2_sblock), + (char *)&data->sblock); + + if (status == 0) + goto fail; + + /* Make sure this is an ext2 filesystem. */ + if (__le16_to_cpu(data->sblock.magic) != EXT2_MAGIC) + goto fail; + + if (__le32_to_cpu(data->sblock.revision_level == 0)) + fs->inodesz = 128; + else + fs->inodesz = __le16_to_cpu(data->sblock.inode_size); + + debug("EXT2 rev %d, inode_size %d\n", + __le32_to_cpu(data->sblock.revision_level), fs->inodesz); + + data->diropen.data = data; + data->diropen.ino = 2; + data->diropen.inode_read = 1; + data->inode = &data->diropen.inode; + + status = ext4fs_read_inode(data, 2, data->inode); + if (status == 0) + goto fail; + + ext4fs_root = data; + + return 1; +fail: + printf("Failed to mount ext2 filesystem...\n"); + free(data); + ext4fs_root = NULL; + + return 0; +} diff --git a/fs/ext4/ext4_common.h b/fs/ext4/ext4_common.h new file mode 100644 index 0000000..f728134 --- /dev/null +++ b/fs/ext4/ext4_common.h @@ -0,0 +1,92 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar <uma.shankar@samsung.com> + * Manjunatha C Achar <a.manjunatha@samsung.com> + * + * ext4ls and ext4load : based on ext2 ls load support in Uboot. + * + * (C) Copyright 2004 + * esd gmbh <www.esd-electronics.com> + * Reinhard Arlt <reinhard.arlt@esd-electronics.com> + * + * based on code from grub2 fs/ext2.c and fs/fshelp.c by + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * + * ext4write : Based on generic ext4 protocol. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __EXT4_COMMON__ +#define __EXT4_COMMON__ +#include <ext_common.h> +#include <ext4fs.h> +#include <malloc.h> +#include <asm/errno.h> +#if defined(CONFIG_CMD_EXT4_WRITE) +#include "ext4_journal.h" +#include "crc16.h" +#endif + +#define YES 1 +#define NO 0 +#define TRUE 1 +#define FALSE 0 +#define RECOVER 1 +#define SCAN 0 + +#define S_IFLNK 0120000 /* symbolic link */ +#define BLOCK_NO_ONE 1 +#define SUPERBLOCK_SECTOR 2 +#define SUPERBLOCK_SIZE 1024 +#define F_FILE 1 + +static inline void *zalloc(size_t size) +{ + void *p = memalign(ARCH_DMA_MINALIGN, size); + memset(p, 0, size); + return p; +} + +int ext4fs_read_inode(struct ext2_data *data, int ino, + struct ext2_inode *inode); +int ext4fs_read_file(struct ext2fs_node *node, int pos, + unsigned int len, char *buf); +int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode, + struct ext2fs_node **foundnode, int expecttype); +int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, + struct ext2fs_node **fnode, int *ftype); + +#if defined(CONFIG_CMD_EXT4_WRITE) +uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n); +int ext4fs_checksum_update(unsigned int i); +int ext4fs_get_parent_inode_num(const char *dirname, char *dname, int flags); +void ext4fs_update_parent_dentry(char *filename, int *p_ino, int file_type); +long int ext4fs_get_new_blk_no(void); +int ext4fs_get_new_inode_no(void); +void ext4fs_reset_block_bmap(long int blockno, unsigned char *buffer, + int index); +int ext4fs_set_block_bmap(long int blockno, unsigned char *buffer, int index); +int ext4fs_set_inode_bmap(int inode_no, unsigned char *buffer, int index); +void ext4fs_reset_inode_bmap(int inode_no, unsigned char *buffer, int index); +int ext4fs_iget(int inode_no, struct ext2_inode *inode); +void ext4fs_allocate_blocks(struct ext2_inode *file_inode, + unsigned int total_remaining_blocks, + unsigned int *total_no_of_block); +void put_ext4(uint64_t off, void *buf, uint32_t size); +#endif +#endif diff --git a/fs/ext4/ext4_journal.c b/fs/ext4/ext4_journal.c new file mode 100644 index 0000000..8a252d6 --- /dev/null +++ b/fs/ext4/ext4_journal.c @@ -0,0 +1,667 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar <uma.shankar@samsung.com> + * Manjunatha C Achar <a.manjunatha@samsung.com> + * + * Journal data structures and headers for Journaling feature of ext4 + * have been referred from JBD2 (Journaling Block device 2) + * implementation in Linux Kernel. + * Written by Stephen C. Tweedie <sct@redhat.com> + * + * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <common.h> +#include <ext4fs.h> +#include <malloc.h> +#include <ext_common.h> +#include "ext4_common.h" + +static struct revoke_blk_list *revk_blk_list; +static struct revoke_blk_list *prev_node; +static int first_node = TRUE; + +int gindex; +int gd_index; +int jrnl_blk_idx; +struct journal_log *journal_ptr[MAX_JOURNAL_ENTRIES]; +struct dirty_blocks *dirty_block_ptr[MAX_JOURNAL_ENTRIES]; + +int ext4fs_init_journal(void) +{ + int i; + char *temp = NULL; + struct ext_filesystem *fs = get_fs(); + + /* init globals */ + revk_blk_list = NULL; + prev_node = NULL; + gindex = 0; + gd_index = 0; + jrnl_blk_idx = 1; + + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + journal_ptr[i] = zalloc(sizeof(struct journal_log)); + if (!journal_ptr[i]) + goto fail; + dirty_block_ptr[i] = zalloc(sizeof(struct dirty_blocks)); + if (!dirty_block_ptr[i]) + goto fail; + journal_ptr[i]->buf = NULL; + journal_ptr[i]->blknr = -1; + + dirty_block_ptr[i]->buf = NULL; + dirty_block_ptr[i]->blknr = -1; + } + + if (fs->blksz == 4096) { + temp = zalloc(fs->blksz); + if (!temp) + goto fail; + journal_ptr[gindex]->buf = zalloc(fs->blksz); + if (!journal_ptr[gindex]->buf) + goto fail; + ext4fs_devread(0, 0, fs->blksz, temp); + memcpy(temp + SUPERBLOCK_SIZE, fs->sb, SUPERBLOCK_SIZE); + memcpy(journal_ptr[gindex]->buf, temp, fs->blksz); + journal_ptr[gindex++]->blknr = 0; + free(temp); + } else { + journal_ptr[gindex]->buf = zalloc(fs->blksz); + if (!journal_ptr[gindex]->buf) + goto fail; + memcpy(journal_ptr[gindex]->buf, fs->sb, SUPERBLOCK_SIZE); + journal_ptr[gindex++]->blknr = 1; + } + + /* Check the file system state using journal super block */ + if (ext4fs_check_journal_state(SCAN)) + goto fail; + /* Check the file system state using journal super block */ + if (ext4fs_check_journal_state(RECOVER)) + goto fail; + + return 0; +fail: + return -1; +} + +void ext4fs_dump_metadata(void) +{ + struct ext_filesystem *fs = get_fs(); + int i; + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (dirty_block_ptr[i]->blknr == -1) + break; + put_ext4((uint64_t) ((uint64_t)dirty_block_ptr[i]->blknr * + (uint64_t)fs->blksz), dirty_block_ptr[i]->buf, + fs->blksz); + } +} + +void ext4fs_free_journal(void) +{ + int i; + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (dirty_block_ptr[i]->blknr == -1) + break; + if (dirty_block_ptr[i]->buf) + free(dirty_block_ptr[i]->buf); + } + + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (journal_ptr[i]->blknr == -1) + break; + if (journal_ptr[i]->buf) + free(journal_ptr[i]->buf); + } + + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (journal_ptr[i]) + free(journal_ptr[i]); + if (dirty_block_ptr[i]) + free(dirty_block_ptr[i]); + } + gindex = 0; + gd_index = 0; + jrnl_blk_idx = 1; +} + +int ext4fs_log_gdt(char *gd_table) +{ + struct ext_filesystem *fs = get_fs(); + short i; + long int var = fs->gdtable_blkno; + for (i = 0; i < fs->no_blk_pergdt; i++) { + journal_ptr[gindex]->buf = zalloc(fs->blksz); + if (!journal_ptr[gindex]->buf) + return -ENOMEM; + memcpy(journal_ptr[gindex]->buf, gd_table, fs->blksz); + gd_table += fs->blksz; + journal_ptr[gindex++]->blknr = var++; + } + + return 0; +} + +/* + * This function stores the backup copy of meta data in RAM + * journal_buffer -- Buffer containing meta data + * blknr -- Block number on disk of the meta data buffer + */ +int ext4fs_log_journal(char *journal_buffer, long int blknr) +{ + struct ext_filesystem *fs = get_fs(); + short i; + + if (!journal_buffer) { + printf("Invalid input arguments %s\n", __func__); + return -EINVAL; + } + + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (journal_ptr[i]->blknr == -1) + break; + if (journal_ptr[i]->blknr == blknr) + return 0; + } + + journal_ptr[gindex]->buf = zalloc(fs->blksz); + if (!journal_ptr[gindex]->buf) + return -ENOMEM; + + memcpy(journal_ptr[gindex]->buf, journal_buffer, fs->blksz); + journal_ptr[gindex++]->blknr = blknr; + + return 0; +} + +/* + * This function stores the modified meta data in RAM + * metadata_buffer -- Buffer containing meta data + * blknr -- Block number on disk of the meta data buffer + */ +int ext4fs_put_metadata(char *metadata_buffer, long int blknr) +{ + struct ext_filesystem *fs = get_fs(); + if (!metadata_buffer) { + printf("Invalid input arguments %s\n", __func__); + return -EINVAL; + } + dirty_block_ptr[gd_index]->buf = zalloc(fs->blksz); + if (!dirty_block_ptr[gd_index]->buf) + return -ENOMEM; + memcpy(dirty_block_ptr[gd_index]->buf, metadata_buffer, fs->blksz); + dirty_block_ptr[gd_index++]->blknr = blknr; + + return 0; +} + +void print_revoke_blks(char *revk_blk) +{ + int offset; + int max; + long int blocknr; + struct journal_revoke_header_t *header; + + if (revk_blk == NULL) + return; + + header = (struct journal_revoke_header_t *) revk_blk; + offset = sizeof(struct journal_revoke_header_t); + max = be32_to_cpu(header->r_count); + printf("total bytes %d\n", max); + + while (offset < max) { + blocknr = be32_to_cpu(*((long int *)(revk_blk + offset))); + printf("revoke blknr is %ld\n", blocknr); + offset += 4; + } +} + +static struct revoke_blk_list *_get_node(void) +{ + struct revoke_blk_list *tmp_node; + tmp_node = zalloc(sizeof(struct revoke_blk_list)); + if (tmp_node == NULL) + return NULL; + tmp_node->content = NULL; + tmp_node->next = NULL; + + return tmp_node; +} + +void ext4fs_push_revoke_blk(char *buffer) +{ + struct revoke_blk_list *node = NULL; + struct ext_filesystem *fs = get_fs(); + if (buffer == NULL) { + printf("buffer ptr is NULL\n"); + return; + } + node = _get_node(); + if (!node) { + printf("_get_node: malloc failed\n"); + return; + } + + node->content = zalloc(fs->blksz); + if (node->content == NULL) + return; + memcpy(node->content, buffer, fs->blksz); + + if (first_node == TRUE) { + revk_blk_list = node; + prev_node = node; + first_node = FALSE; + } else { + prev_node->next = node; + prev_node = node; + } +} + +void ext4fs_free_revoke_blks(void) +{ + struct revoke_blk_list *tmp_node = revk_blk_list; + struct revoke_blk_list *next_node = NULL; + + while (tmp_node != NULL) { + if (tmp_node->content) + free(tmp_node->content); + tmp_node = tmp_node->next; + } + + tmp_node = revk_blk_list; + while (tmp_node != NULL) { + next_node = tmp_node->next; + free(tmp_node); + tmp_node = next_node; + } + + revk_blk_list = NULL; + prev_node = NULL; + first_node = TRUE; +} + +int check_blknr_for_revoke(long int blknr, int sequence_no) +{ + struct journal_revoke_header_t *header; + int offset; + int max; + long int blocknr; + char *revk_blk; + struct revoke_blk_list *tmp_revk_node = revk_blk_list; + while (tmp_revk_node != NULL) { + revk_blk = tmp_revk_node->content; + + header = (struct journal_revoke_header_t *) revk_blk; + if (sequence_no < be32_to_cpu(header->r_header.h_sequence)) { + offset = sizeof(struct journal_revoke_header_t); + max = be32_to_cpu(header->r_count); + + while (offset < max) { + blocknr = be32_to_cpu(*((long int *) + (revk_blk + offset))); + if (blocknr == blknr) + goto found; + offset += 4; + } + } + tmp_revk_node = tmp_revk_node->next; + } + + return -1; + +found: + return 0; +} + +/* + * This function parses the journal blocks and replays the + * suceessful transactions. A transaction is successfull + * if commit block is found for a descriptor block + * The tags in descriptor block contain the disk block + * numbers of the metadata to be replayed + */ +void recover_transaction(int prev_desc_logical_no) +{ + struct ext2_inode inode_journal; + struct ext_filesystem *fs = get_fs(); + struct journal_header_t *jdb; + long int blknr; + char *p_jdb; + int ofs, flags; + int i; + struct ext3_journal_block_tag *tag; + char *temp_buff = zalloc(fs->blksz); + char *metadata_buff = zalloc(fs->blksz); + if (!temp_buff || !metadata_buff) + goto fail; + i = prev_desc_logical_no; + ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, + (struct ext2_inode *)&inode_journal); + blknr = read_allocated_block((struct ext2_inode *) + &inode_journal, i); + ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff); + p_jdb = (char *)temp_buff; + jdb = (struct journal_header_t *) temp_buff; + ofs = sizeof(struct journal_header_t); + + do { + tag = (struct ext3_journal_block_tag *)&p_jdb[ofs]; + ofs += sizeof(struct ext3_journal_block_tag); + + if (ofs > fs->blksz) + break; + + flags = be32_to_cpu(tag->flags); + if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID)) + ofs += 16; + + i++; + debug("\t\ttag %u\n", be32_to_cpu(tag->block)); + if (revk_blk_list != NULL) { + if (check_blknr_for_revoke(be32_to_cpu(tag->block), + be32_to_cpu(jdb->h_sequence)) == 0) + continue; + } + blknr = read_allocated_block(&inode_journal, i); + ext4fs_devread(blknr * fs->sect_perblk, 0, + fs->blksz, metadata_buff); + put_ext4((uint64_t)(be32_to_cpu(tag->block) * fs->blksz), + metadata_buff, (uint32_t) fs->blksz); + } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG)); +fail: + free(temp_buff); + free(metadata_buff); +} + +void print_jrnl_status(int recovery_flag) +{ + if (recovery_flag == RECOVER) + printf("Journal Recovery Completed\n"); + else + printf("Journal Scan Completed\n"); +} + +int ext4fs_check_journal_state(int recovery_flag) +{ + int i; + int DB_FOUND = NO; + long int blknr; + int transaction_state = TRANSACTION_COMPLETE; + int prev_desc_logical_no = 0; + int curr_desc_logical_no = 0; + int ofs, flags, block; + struct ext2_inode inode_journal; + struct journal_superblock_t *jsb = NULL; + struct journal_header_t *jdb = NULL; + char *p_jdb = NULL; + struct ext3_journal_block_tag *tag = NULL; + char *temp_buff = NULL; + char *temp_buff1 = NULL; + struct ext_filesystem *fs = get_fs(); + + temp_buff = zalloc(fs->blksz); + if (!temp_buff) + return -ENOMEM; + temp_buff1 = zalloc(fs->blksz); + if (!temp_buff1) { + free(temp_buff); + return -ENOMEM; + } + + ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal); + blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK); + ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff); + jsb = (struct journal_superblock_t *) temp_buff; + + if (fs->sb->feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) { + if (recovery_flag == RECOVER) + printf("Recovery required\n"); + } else { + if (recovery_flag == RECOVER) + printf("File System is consistent\n"); + goto end; + } + + if (be32_to_cpu(jsb->s_start) == 0) + goto end; + + if (!(jsb->s_feature_compat & + cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM))) + jsb->s_feature_compat |= + cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM); + + i = be32_to_cpu(jsb->s_first); + while (1) { + block = be32_to_cpu(jsb->s_first); + blknr = read_allocated_block(&inode_journal, i); + memset(temp_buff1, '\0', fs->blksz); + ext4fs_devread(blknr * fs->sect_perblk, + 0, fs->blksz, temp_buff1); + jdb = (struct journal_header_t *) temp_buff1; + + if (be32_to_cpu(jdb->h_blocktype) == + EXT3_JOURNAL_DESCRIPTOR_BLOCK) { + if (be32_to_cpu(jdb->h_sequence) != + be32_to_cpu(jsb->s_sequence)) { + print_jrnl_status(recovery_flag); + break; + } + + curr_desc_logical_no = i; + if (transaction_state == TRANSACTION_COMPLETE) + transaction_state = TRANSACTION_RUNNING; + else + return -1; + p_jdb = (char *)temp_buff1; + ofs = sizeof(struct journal_header_t); + do { + tag = (struct ext3_journal_block_tag *) + &p_jdb[ofs]; + ofs += sizeof(struct ext3_journal_block_tag); + if (ofs > fs->blksz) + break; + flags = be32_to_cpu(tag->flags); + if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID)) + ofs += 16; + i++; + debug("\t\ttag %u\n", be32_to_cpu(tag->block)); + } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG)); + i++; + DB_FOUND = YES; + } else if (be32_to_cpu(jdb->h_blocktype) == + EXT3_JOURNAL_COMMIT_BLOCK) { + if (be32_to_cpu(jdb->h_sequence) != + be32_to_cpu(jsb->s_sequence)) { + print_jrnl_status(recovery_flag); + break; + } + + if (transaction_state == TRANSACTION_RUNNING || + (DB_FOUND == NO)) { + transaction_state = TRANSACTION_COMPLETE; + i++; + jsb->s_sequence = + cpu_to_be32(be32_to_cpu( + jsb->s_sequence) + 1); + } + prev_desc_logical_no = curr_desc_logical_no; + if ((recovery_flag == RECOVER) && (DB_FOUND == YES)) + recover_transaction(prev_desc_logical_no); + + DB_FOUND = NO; + } else if (be32_to_cpu(jdb->h_blocktype) == + EXT3_JOURNAL_REVOKE_BLOCK) { + if (be32_to_cpu(jdb->h_sequence) != + be32_to_cpu(jsb->s_sequence)) { + print_jrnl_status(recovery_flag); + break; + } + if (recovery_flag == SCAN) + ext4fs_push_revoke_blk((char *)jdb); + i++; + } else { + debug("Else Case\n"); + if (be32_to_cpu(jdb->h_sequence) != + be32_to_cpu(jsb->s_sequence)) { + print_jrnl_status(recovery_flag); + break; + } + } + } + +end: + if (recovery_flag == RECOVER) { + jsb->s_start = cpu_to_be32(1); + jsb->s_sequence = cpu_to_be32(be32_to_cpu(jsb->s_sequence) + 1); + /* get the superblock */ + ext4fs_devread(SUPERBLOCK_SECTOR, 0, SUPERBLOCK_SIZE, + (char *)fs->sb); + fs->sb->feature_incompat |= EXT3_FEATURE_INCOMPAT_RECOVER; + + /* Update the super block */ + put_ext4((uint64_t) (SUPERBLOCK_SIZE), + (struct ext2_sblock *)fs->sb, + (uint32_t) SUPERBLOCK_SIZE); + ext4fs_devread(SUPERBLOCK_SECTOR, 0, SUPERBLOCK_SIZE, + (char *)fs->sb); + + blknr = read_allocated_block(&inode_journal, + EXT2_JOURNAL_SUPERBLOCK); + put_ext4((uint64_t) (blknr * fs->blksz), + (struct journal_superblock_t *)temp_buff, + (uint32_t) fs->blksz); + ext4fs_free_revoke_blks(); + } + free(temp_buff); + free(temp_buff1); + + return 0; +} + +static void update_descriptor_block(long int blknr) +{ + int i; + long int jsb_blknr; + struct journal_header_t jdb; + struct ext3_journal_block_tag tag; + struct ext2_inode inode_journal; + struct journal_superblock_t *jsb = NULL; + char *buf = NULL; + char *temp = NULL; + struct ext_filesystem *fs = get_fs(); + char *temp_buff = zalloc(fs->blksz); + if (!temp_buff) + return; + + ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal); + jsb_blknr = read_allocated_block(&inode_journal, + EXT2_JOURNAL_SUPERBLOCK); + ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff); + jsb = (struct journal_superblock_t *) temp_buff; + + jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK); + jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER); + jdb.h_sequence = jsb->s_sequence; + buf = zalloc(fs->blksz); + if (!buf) { + free(temp_buff); + return; + } + temp = buf; + memcpy(buf, &jdb, sizeof(struct journal_header_t)); + temp += sizeof(struct journal_header_t); + + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (journal_ptr[i]->blknr == -1) + break; + + tag.block = cpu_to_be32(journal_ptr[i]->blknr); + tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_SAME_UUID); + memcpy(temp, &tag, sizeof(struct ext3_journal_block_tag)); + temp = temp + sizeof(struct ext3_journal_block_tag); + } + + tag.block = cpu_to_be32(journal_ptr[--i]->blknr); + tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_LAST_TAG); + memcpy(temp - sizeof(struct ext3_journal_block_tag), &tag, + sizeof(struct ext3_journal_block_tag)); + put_ext4((uint64_t) (blknr * fs->blksz), buf, (uint32_t) fs->blksz); + + free(temp_buff); + free(buf); +} + +static void update_commit_block(long int blknr) +{ + struct journal_header_t jdb; + struct ext_filesystem *fs = get_fs(); + char *buf = NULL; + struct ext2_inode inode_journal; + struct journal_superblock_t *jsb; + long int jsb_blknr; + char *temp_buff = zalloc(fs->blksz); + if (!temp_buff) + return; + + ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal); + jsb_blknr = read_allocated_block(&inode_journal, + EXT2_JOURNAL_SUPERBLOCK); + ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff); + jsb = (struct journal_superblock_t *) temp_buff; + + jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK); + jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER); + jdb.h_sequence = jsb->s_sequence; + buf = zalloc(fs->blksz); + if (!buf) { + free(temp_buff); + return; + } + memcpy(buf, &jdb, sizeof(struct journal_header_t)); + put_ext4((uint64_t) (blknr * fs->blksz), buf, (uint32_t) fs->blksz); + + free(temp_buff); + free(buf); +} + +void ext4fs_update_journal(void) +{ + struct ext2_inode inode_journal; + struct ext_filesystem *fs = get_fs(); + long int blknr; + int i; + ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal); + blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++); + update_descriptor_block(blknr); + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (journal_ptr[i]->blknr == -1) + break; + blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++); + put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), + journal_ptr[i]->buf, fs->blksz); + } + blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++); + update_commit_block(blknr); + printf("update journal finished\n"); +} diff --git a/fs/ext4/ext4_journal.h b/fs/ext4/ext4_journal.h new file mode 100644 index 0000000..acc1c516 --- /dev/null +++ b/fs/ext4/ext4_journal.h @@ -0,0 +1,141 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar <uma.shankar@samsung.com> + * Manjunatha C Achar <a.manjunatha@samsung.com> + * + * Journal data structures and headers for Journaling feature of ext4 + * have been referred from JBD2 (Journaling Block device 2) + * implementation in Linux Kernel. + * + * Written by Stephen C. Tweedie <sct@redhat.com> + * + * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __EXT4_JRNL__ +#define __EXT4_JRNL__ + +#define EXT2_JOURNAL_INO 8 /* Journal inode */ +#define EXT2_JOURNAL_SUPERBLOCK 0 /* Journal Superblock number */ + +#define JBD2_FEATURE_COMPAT_CHECKSUM 0x00000001 +#define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U +#define TRANSACTION_RUNNING 1 +#define TRANSACTION_COMPLETE 0 +#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ +#define EXT3_JOURNAL_DESCRIPTOR_BLOCK 1 +#define EXT3_JOURNAL_COMMIT_BLOCK 2 +#define EXT3_JOURNAL_SUPERBLOCK_V1 3 +#define EXT3_JOURNAL_SUPERBLOCK_V2 4 +#define EXT3_JOURNAL_REVOKE_BLOCK 5 +#define EXT3_JOURNAL_FLAG_ESCAPE 1 +#define EXT3_JOURNAL_FLAG_SAME_UUID 2 +#define EXT3_JOURNAL_FLAG_DELETED 4 +#define EXT3_JOURNAL_FLAG_LAST_TAG 8 + +/* Maximum entries in 1 journal transaction */ +#define MAX_JOURNAL_ENTRIES 100 +struct journal_log { + char *buf; + int blknr; +}; + +struct dirty_blocks { + char *buf; + int blknr; +}; + +/* Standard header for all descriptor blocks: */ +struct journal_header_t { + __u32 h_magic; + __u32 h_blocktype; + __u32 h_sequence; +}; + +/* The journal superblock. All fields are in big-endian byte order. */ +struct journal_superblock_t { + /* 0x0000 */ + struct journal_header_t s_header; + + /* Static information describing the journal */ + __u32 s_blocksize; /* journal device blocksize */ + __u32 s_maxlen; /* total blocks in journal file */ + __u32 s_first; /* first block of log information */ + + /* Dynamic information describing the current state of the log */ + __u32 s_sequence; /* first commit ID expected in log */ + __u32 s_start; /* blocknr of start of log */ + + /* Error value, as set by journal_abort(). */ + __s32 s_errno; + + /* Remaining fields are only valid in a version-2 superblock */ + __u32 s_feature_compat; /* compatible feature set */ + __u32 s_feature_incompat; /* incompatible feature set */ + __u32 s_feature_ro_compat; /* readonly-compatible feature set */ + /* 0x0030 */ + __u8 s_uuid[16]; /* 128-bit uuid for journal */ + + /* 0x0040 */ + __u32 s_nr_users; /* Nr of filesystems sharing log */ + + __u32 s_dynsuper; /* Blocknr of dynamic superblock copy */ + + /* 0x0048 */ + __u32 s_max_transaction; /* Limit of journal blocks per trans. */ + __u32 s_max_trans_data; /* Limit of data blocks per trans. */ + + /* 0x0050 */ + __u32 s_padding[44]; + + /* 0x0100 */ + __u8 s_users[16 * 48]; /* ids of all fs'es sharing the log */ + /* 0x0400 */ +} ; + +struct ext3_journal_block_tag { + uint32_t block; + uint32_t flags; +}; + +struct journal_revoke_header_t { + struct journal_header_t r_header; + int r_count; /* Count of bytes used in the block */ +}; + +struct revoke_blk_list { + char *content; /* revoke block itself */ + struct revoke_blk_list *next; +}; + +extern struct ext2_data *ext4fs_root; + +int ext4fs_init_journal(void); +int ext4fs_log_gdt(char *gd_table); +int ext4fs_check_journal_state(int recovery_flag); +int ext4fs_log_journal(char *journal_buffer, long int blknr); +int ext4fs_put_metadata(char *metadata_buffer, long int blknr); +void ext4fs_update_journal(void); +void ext4fs_dump_metadata(void); +void ext4fs_push_revoke_blk(char *buffer); +void ext4fs_free_journal(void); +void ext4fs_free_revoke_blks(void); +#endif diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c new file mode 100644 index 0000000..93dcb7e --- /dev/null +++ b/fs/ext4/ext4fs.c @@ -0,0 +1,1156 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar <uma.shankar@samsung.com> + * Manjunatha C Achar <a.manjunatha@samsung.com> + * + * ext4ls and ext4load : Based on ext2 ls and load support in Uboot. + * Ext4 read optimization taken from Open-Moko + * Qi bootloader + * + * (C) Copyright 2004 + * esd gmbh <www.esd-electronics.com> + * Reinhard Arlt <reinhard.arlt@esd-electronics.com> + * + * based on code from grub2 fs/ext2.c and fs/fshelp.c by + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * + * ext4write : Based on generic ext4 protocol. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <common.h> +#include <malloc.h> +#include <ext_common.h> +#include <ext4fs.h> +#include <linux/stat.h> +#include <linux/time.h> +#include <asm/byteorder.h> +#include "ext4_common.h" + +int ext4fs_symlinknest; +struct ext_filesystem ext_fs; + +struct ext_filesystem *get_fs(void) +{ + return &ext_fs; +} + +void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot) +{ + if ((node != &ext4fs_root->diropen) && (node != currroot)) + free(node); +} + +/* + * Taken from openmoko-kernel mailing list: By Andy green + * Optimized read file API : collects and defers contiguous sector + * reads into one potentially more efficient larger sequential read action + */ +int ext4fs_read_file(struct ext2fs_node *node, int pos, + unsigned int len, char *buf) +{ + int i; + int blockcnt; + int log2blocksize = LOG2_EXT2_BLOCK_SIZE(node->data); + int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS); + unsigned int filesize = __le32_to_cpu(node->inode.size); + int previous_block_number = -1; + int delayed_start = 0; + int delayed_extent = 0; + int delayed_skipfirst = 0; + int delayed_next = 0; + char *delayed_buf = NULL; + short status; + + /* Adjust len so it we can't read past the end of the file. */ + if (len > filesize) + len = filesize; + + blockcnt = ((len + pos) + blocksize - 1) / blocksize; + + for (i = pos / blocksize; i < blockcnt; i++) { + int blknr; + int blockoff = pos % blocksize; + int blockend = blocksize; + int skipfirst = 0; + blknr = read_allocated_block(&(node->inode), i); + if (blknr < 0) + return -1; + + blknr = blknr << log2blocksize; + + /* Last block. */ + if (i == blockcnt - 1) { + blockend = (len + pos) % blocksize; + + /* The last portion is exactly blocksize. */ + if (!blockend) + blockend = blocksize; + } + + /* First block. */ + if (i == pos / blocksize) { + skipfirst = blockoff; + blockend -= skipfirst; + } + if (blknr) { + int status; + + if (previous_block_number != -1) { + if (delayed_next == blknr) { + delayed_extent += blockend; + delayed_next += blockend >> SECTOR_BITS; + } else { /* spill */ + status = ext4fs_devread(delayed_start, + delayed_skipfirst, + delayed_extent, + delayed_buf); + if (status == 0) + return -1; + previous_block_number = blknr; + delayed_start = blknr; + delayed_extent = blockend; + delayed_skipfirst = skipfirst; + delayed_buf = buf; + delayed_next = blknr + + (blockend >> SECTOR_BITS); + } + } else { + previous_block_number = blknr; + delayed_start = blknr; + delayed_extent = blockend; + delayed_skipfirst = skipfirst; + delayed_buf = buf; + delayed_next = blknr + + (blockend >> SECTOR_BITS); + } + } else { + if (previous_block_number != -1) { + /* spill */ + status = ext4fs_devread(delayed_start, + delayed_skipfirst, + delayed_extent, + delayed_buf); + if (status == 0) + return -1; + previous_block_number = -1; + } + memset(buf, 0, blocksize - skipfirst); + } + buf += blocksize - skipfirst; + } + if (previous_block_number != -1) { + /* spill */ + status = ext4fs_devread(delayed_start, + delayed_skipfirst, delayed_extent, + delayed_buf); + if (status == 0) + return -1; + previous_block_number = -1; + } + + return len; +} + +int ext4fs_ls(const char *dirname) +{ + struct ext2fs_node *dirnode; + int status; + + if (dirname == NULL) + return 0; + + status = ext4fs_find_file(dirname, &ext4fs_root->diropen, &dirnode, + FILETYPE_DIRECTORY); + if (status != 1) { + printf("** Can not find directory. **\n"); + return 1; + } + + ext4fs_iterate_dir(dirnode, NULL, NULL, NULL); + ext4fs_free_node(dirnode, &ext4fs_root->diropen); + + return 0; +} + +int ext4fs_read(char *buf, unsigned len) +{ + if (ext4fs_root == NULL || ext4fs_file == NULL) + return 0; + + return ext4fs_read_file(ext4fs_file, 0, len, buf); +} + +#if defined(CONFIG_CMD_EXT4_WRITE) +static void ext4fs_update(void) +{ + short i; + ext4fs_update_journal(); + struct ext_filesystem *fs = get_fs(); + + /* update super block */ + put_ext4((uint64_t)(SUPERBLOCK_SIZE), + (struct ext2_sblock *)fs->sb, (uint32_t)SUPERBLOCK_SIZE); + + /* update block groups */ + for (i = 0; i < fs->no_blkgrp; i++) { + fs->gd[i].bg_checksum = ext4fs_checksum_update(i); + put_ext4((uint64_t)(fs->gd[i].block_id * fs->blksz), + fs->blk_bmaps[i], fs->blksz); + } + + /* update inode table groups */ + for (i = 0; i < fs->no_blkgrp; i++) { + put_ext4((uint64_t) (fs->gd[i].inode_id * fs->blksz), + fs->inode_bmaps[i], fs->blksz); + } + + /* update the block group descriptor table */ + put_ext4((uint64_t)(fs->gdtable_blkno * fs->blksz), + (struct ext2_block_group *)fs->gdtable, + (fs->blksz * fs->no_blk_pergdt)); + + ext4fs_dump_metadata(); + + gindex = 0; + gd_index = 0; +} + +int ext4fs_get_bgdtable(void) +{ + int status; + int grp_desc_size; + struct ext_filesystem *fs = get_fs(); + grp_desc_size = sizeof(struct ext2_block_group); + fs->no_blk_pergdt = (fs->no_blkgrp * grp_desc_size) / fs->blksz; + if ((fs->no_blkgrp * grp_desc_size) % fs->blksz) + fs->no_blk_pergdt++; + + /* allocate memory for gdtable */ + fs->gdtable = zalloc(fs->blksz * fs->no_blk_pergdt); + if (!fs->gdtable) + return -ENOMEM; + /* read the group descriptor table */ + status = ext4fs_devread(fs->gdtable_blkno * fs->sect_perblk, 0, + fs->blksz * fs->no_blk_pergdt, fs->gdtable); + if (status == 0) + goto fail; + + if (ext4fs_log_gdt(fs->gdtable)) { + printf("Error in ext4fs_log_gdt\n"); + return -1; + } + + return 0; +fail: + free(fs->gdtable); + fs->gdtable = NULL; + + return -1; +} + +static void delete_single_indirect_block(struct ext2_inode *inode) +{ + struct ext2_block_group *gd = NULL; + static int prev_bg_bmap_idx = -1; + long int blknr; + int remainder; + int bg_idx; + int status; + unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; + struct ext_filesystem *fs = get_fs(); + char *journal_buffer = zalloc(fs->blksz); + if (!journal_buffer) { + printf("No memory\n"); + return; + } + /* get block group descriptor table */ + gd = (struct ext2_block_group *)fs->gdtable; + + /* deleting the single indirect block associated with inode */ + if (inode->b.blocks.indir_block != 0) { + debug("SIPB releasing %u\n", inode->b.blocks.indir_block); + blknr = inode->b.blocks.indir_block; + if (fs->blksz != 1024) { + bg_idx = blknr / blk_per_grp; + } else { + bg_idx = blknr / blk_per_grp; + remainder = blknr % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx); + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + status = + ext4fs_devread(gd[bg_idx].block_id * + fs->sect_perblk, 0, fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal + (journal_buffer, gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + } +fail: + free(journal_buffer); +} + +static void delete_double_indirect_block(struct ext2_inode *inode) +{ + int i; + short status; + static int prev_bg_bmap_idx = -1; + long int blknr; + int remainder; + int bg_idx; + unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; + unsigned int *di_buffer = NULL; + unsigned int *DIB_start_addr = NULL; + struct ext2_block_group *gd = NULL; + struct ext_filesystem *fs = get_fs(); + char *journal_buffer = zalloc(fs->blksz); + if (!journal_buffer) { + printf("No memory\n"); + return; + } + /* get the block group descriptor table */ + gd = (struct ext2_block_group *)fs->gdtable; + + if (inode->b.blocks.double_indir_block != 0) { + di_buffer = zalloc(fs->blksz); + if (!di_buffer) { + printf("No memory\n"); + return; + } + DIB_start_addr = (unsigned int *)di_buffer; + blknr = inode->b.blocks.double_indir_block; + status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, + (char *)di_buffer); + for (i = 0; i < fs->blksz / sizeof(int); i++) { + if (*di_buffer == 0) + break; + + debug("DICB releasing %u\n", *di_buffer); + if (fs->blksz != 1024) { + bg_idx = (*di_buffer) / blk_per_grp; + } else { + bg_idx = (*di_buffer) / blk_per_grp; + remainder = (*di_buffer) % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(*di_buffer, + fs->blk_bmaps[bg_idx], bg_idx); + di_buffer++; + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + status = ext4fs_devread(gd[bg_idx].block_id + * fs->sect_perblk, 0, + fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + } + + /* removing the parent double indirect block */ + blknr = inode->b.blocks.double_indir_block; + if (fs->blksz != 1024) { + bg_idx = blknr / blk_per_grp; + } else { + bg_idx = blknr / blk_per_grp; + remainder = blknr % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx); + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + memset(journal_buffer, '\0', fs->blksz); + status = ext4fs_devread(gd[bg_idx].block_id * + fs->sect_perblk, 0, fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + debug("DIPB releasing %ld\n", blknr); + } +fail: + free(DIB_start_addr); + free(journal_buffer); +} + +static void delete_triple_indirect_block(struct ext2_inode *inode) +{ + int i, j; + short status; + static int prev_bg_bmap_idx = -1; + long int blknr; + int remainder; + int bg_idx; + unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; + unsigned int *tigp_buffer = NULL; + unsigned int *tib_start_addr = NULL; + unsigned int *tip_buffer = NULL; + unsigned int *tipb_start_addr = NULL; + struct ext2_block_group *gd = NULL; + struct ext_filesystem *fs = get_fs(); + char *journal_buffer = zalloc(fs->blksz); + if (!journal_buffer) { + printf("No memory\n"); + return; + } + /* get block group descriptor table */ + gd = (struct ext2_block_group *)fs->gdtable; + + if (inode->b.blocks.triple_indir_block != 0) { + tigp_buffer = zalloc(fs->blksz); + if (!tigp_buffer) { + printf("No memory\n"); + return; + } + tib_start_addr = (unsigned int *)tigp_buffer; + blknr = inode->b.blocks.triple_indir_block; + status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, + (char *)tigp_buffer); + for (i = 0; i < fs->blksz / sizeof(int); i++) { + if (*tigp_buffer == 0) + break; + debug("tigp buffer releasing %u\n", *tigp_buffer); + + tip_buffer = zalloc(fs->blksz); + if (!tip_buffer) + goto fail; + tipb_start_addr = (unsigned int *)tip_buffer; + status = ext4fs_devread((*tigp_buffer) * + fs->sect_perblk, 0, fs->blksz, + (char *)tip_buffer); + for (j = 0; j < fs->blksz / sizeof(int); j++) { + if (*tip_buffer == 0) + break; + if (fs->blksz != 1024) { + bg_idx = (*tip_buffer) / blk_per_grp; + } else { + bg_idx = (*tip_buffer) / blk_per_grp; + + remainder = (*tip_buffer) % blk_per_grp; + if (!remainder) + bg_idx--; + } + + ext4fs_reset_block_bmap(*tip_buffer, + fs->blk_bmaps[bg_idx], + bg_idx); + + tip_buffer++; + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + status = + ext4fs_devread(gd[bg_idx].block_id * + fs->sect_perblk, 0, + fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx]. + block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + } + free(tipb_start_addr); + tipb_start_addr = NULL; + + /* + * removing the grand parent blocks + * which is connected to inode + */ + if (fs->blksz != 1024) { + bg_idx = (*tigp_buffer) / blk_per_grp; + } else { + bg_idx = (*tigp_buffer) / blk_per_grp; + + remainder = (*tigp_buffer) % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(*tigp_buffer, + fs->blk_bmaps[bg_idx], bg_idx); + + tigp_buffer++; + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + memset(journal_buffer, '\0', fs->blksz); + status = + ext4fs_devread(gd[bg_idx].block_id * + fs->sect_perblk, 0, + fs->blksz, journal_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + } + + /* removing the grand parent triple indirect block */ + blknr = inode->b.blocks.triple_indir_block; + if (fs->blksz != 1024) { + bg_idx = blknr / blk_per_grp; + } else { + bg_idx = blknr / blk_per_grp; + remainder = blknr % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx); + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + memset(journal_buffer, '\0', fs->blksz); + status = ext4fs_devread(gd[bg_idx].block_id * + fs->sect_perblk, 0, fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + debug("tigp buffer itself releasing %ld\n", blknr); + } +fail: + free(tib_start_addr); + free(tipb_start_addr); + free(journal_buffer); +} + +static int ext4fs_delete_file(int inodeno) +{ + struct ext2_inode inode; + short status; + int i; + int remainder; + long int blknr; + int bg_idx; + int ibmap_idx; + char *read_buffer = NULL; + char *start_block_address = NULL; + unsigned int no_blocks; + + static int prev_bg_bmap_idx = -1; + unsigned int inodes_per_block; + long int blkno; + unsigned int blkoff; + unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; + unsigned int inode_per_grp = ext4fs_root->sblock.inodes_per_group; + struct ext2_inode *inode_buffer = NULL; + struct ext2_block_group *gd = NULL; + struct ext_filesystem *fs = get_fs(); + char *journal_buffer = zalloc(fs->blksz); + if (!journal_buffer) + return -ENOMEM; + /* get the block group descriptor table */ + gd = (struct ext2_block_group *)fs->gdtable; + status = ext4fs_read_inode(ext4fs_root, inodeno, &inode); + if (status == 0) + goto fail; + + /* read the block no allocated to a file */ + no_blocks = inode.size / fs->blksz; + if (inode.size % fs->blksz) + no_blocks++; + + if (le32_to_cpu(inode.flags) & EXT4_EXTENTS_FL) { + struct ext2fs_node *node_inode = + zalloc(sizeof(struct ext2fs_node)); + if (!node_inode) + goto fail; + node_inode->data = ext4fs_root; + node_inode->ino = inodeno; + node_inode->inode_read = 0; + memcpy(&(node_inode->inode), &inode, sizeof(struct ext2_inode)); + + for (i = 0; i < no_blocks; i++) { + blknr = read_allocated_block(&(node_inode->inode), i); + if (fs->blksz != 1024) { + bg_idx = blknr / blk_per_grp; + } else { + bg_idx = blknr / blk_per_grp; + remainder = blknr % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], + bg_idx); + debug("EXT4_EXTENTS Block releasing %ld: %d\n", + blknr, bg_idx); + + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + status = + ext4fs_devread(gd[bg_idx].block_id * + fs->sect_perblk, 0, + fs->blksz, journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + } + if (node_inode) { + free(node_inode); + node_inode = NULL; + } + } else { + + delete_single_indirect_block(&inode); + delete_double_indirect_block(&inode); + delete_triple_indirect_block(&inode); + + /* read the block no allocated to a file */ + no_blocks = inode.size / fs->blksz; + if (inode.size % fs->blksz) + no_blocks++; + for (i = 0; i < no_blocks; i++) { + blknr = read_allocated_block(&inode, i); + if (fs->blksz != 1024) { + bg_idx = blknr / blk_per_grp; + } else { + bg_idx = blknr / blk_per_grp; + remainder = blknr % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], + bg_idx); + debug("ActualB releasing %ld: %d\n", blknr, bg_idx); + + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + memset(journal_buffer, '\0', fs->blksz); + status = ext4fs_devread(gd[bg_idx].block_id + * fs->sect_perblk, + 0, fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + } + } + + /* from the inode no to blockno */ + inodes_per_block = fs->blksz / fs->inodesz; + ibmap_idx = inodeno / inode_per_grp; + + /* get the block no */ + inodeno--; + blkno = __le32_to_cpu(gd[ibmap_idx].inode_table_id) + + (inodeno % __le32_to_cpu(inode_per_grp)) / inodes_per_block; + + /* get the offset of the inode */ + blkoff = ((inodeno) % inodes_per_block) * fs->inodesz; + + /* read the block no containing the inode */ + read_buffer = zalloc(fs->blksz); + if (!read_buffer) + goto fail; + start_block_address = read_buffer; + status = ext4fs_devread(blkno * fs->sect_perblk, + 0, fs->blksz, read_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(read_buffer, blkno)) + goto fail; + + read_buffer = read_buffer + blkoff; + inode_buffer = (struct ext2_inode *)read_buffer; + memset(inode_buffer, '\0', sizeof(struct ext2_inode)); + + /* write the inode to original position in inode table */ + if (ext4fs_put_metadata(start_block_address, blkno)) + goto fail; + + /* update the respective inode bitmaps */ + inodeno++; + ext4fs_reset_inode_bmap(inodeno, fs->inode_bmaps[ibmap_idx], ibmap_idx); + gd[ibmap_idx].free_inodes++; + fs->sb->free_inodes++; + /* journal backup */ + memset(journal_buffer, '\0', fs->blksz); + status = ext4fs_devread(gd[ibmap_idx].inode_id * + fs->sect_perblk, 0, fs->blksz, journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, gd[ibmap_idx].inode_id)) + goto fail; + + ext4fs_update(); + ext4fs_deinit(); + + if (ext4fs_init() != 0) { + printf("error in File System init\n"); + goto fail; + } + + free(start_block_address); + free(journal_buffer); + + return 0; +fail: + free(start_block_address); + free(journal_buffer); + + return -1; +} + +int ext4fs_init(void) +{ + short status; + int i; + unsigned int real_free_blocks = 0; + struct ext_filesystem *fs = get_fs(); + + /* populate fs */ + fs->blksz = EXT2_BLOCK_SIZE(ext4fs_root); + fs->inodesz = INODE_SIZE_FILESYSTEM(ext4fs_root); + fs->sect_perblk = fs->blksz / SECTOR_SIZE; + + /* get the superblock */ + fs->sb = zalloc(SUPERBLOCK_SIZE); + if (!fs->sb) + return -ENOMEM; + if (!ext4fs_devread(SUPERBLOCK_SECTOR, 0, SUPERBLOCK_SIZE, + (char *)fs->sb)) + goto fail; + + /* init journal */ + if (ext4fs_init_journal()) + goto fail; + + /* get total no of blockgroups */ + fs->no_blkgrp = (uint32_t)ext4fs_div_roundup( + (ext4fs_root->sblock.total_blocks - + ext4fs_root->sblock.first_data_block), + ext4fs_root->sblock.blocks_per_group); + + /* get the block group descriptor table */ + fs->gdtable_blkno = ((EXT2_MIN_BLOCK_SIZE == fs->blksz) + 1); + if (ext4fs_get_bgdtable() == -1) { + printf("Error in getting the block group descriptor table\n"); + goto fail; + } + fs->gd = (struct ext2_block_group *)fs->gdtable; + + /* load all the available bitmap block of the partition */ + fs->blk_bmaps = zalloc(fs->no_blkgrp * sizeof(char *)); + if (!fs->blk_bmaps) + goto fail; + for (i = 0; i < fs->no_blkgrp; i++) { + fs->blk_bmaps[i] = zalloc(fs->blksz); + if (!fs->blk_bmaps[i]) + goto fail; + } + + for (i = 0; i < fs->no_blkgrp; i++) { + status = + ext4fs_devread(fs->gd[i].block_id * fs->sect_perblk, 0, + fs->blksz, (char *)fs->blk_bmaps[i]); + if (status == 0) + goto fail; + } + + /* load all the available inode bitmap of the partition */ + fs->inode_bmaps = zalloc(fs->no_blkgrp * sizeof(unsigned char *)); + if (!fs->inode_bmaps) + goto fail; + for (i = 0; i < fs->no_blkgrp; i++) { + fs->inode_bmaps[i] = zalloc(fs->blksz); + if (!fs->inode_bmaps[i]) + goto fail; + } + + for (i = 0; i < fs->no_blkgrp; i++) { + status = ext4fs_devread(fs->gd[i].inode_id * fs->sect_perblk, + 0, fs->blksz, + (char *)fs->inode_bmaps[i]); + if (status == 0) + goto fail; + } + + /* + * check filesystem consistency with free blocks of file system + * some time we observed that superblock freeblocks does not match + * with the blockgroups freeblocks when improper + * reboot of a linux kernel + */ + for (i = 0; i < fs->no_blkgrp; i++) + real_free_blocks = real_free_blocks + fs->gd[i].free_blocks; + if (real_free_blocks != fs->sb->free_blocks) + fs->sb->free_blocks = real_free_blocks; + + return 0; +fail: + ext4fs_deinit(); + + return -1; +} + +void ext4fs_deinit(void) +{ + int i; + struct ext2_inode inode_journal; + struct journal_superblock_t *jsb; + long int blknr; + struct ext_filesystem *fs = get_fs(); + + /* free journal */ + char *temp_buff = zalloc(fs->blksz); + if (temp_buff) { + ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, + &inode_journal); + blknr = read_allocated_block(&inode_journal, + EXT2_JOURNAL_SUPERBLOCK); + ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, + temp_buff); + jsb = (struct journal_superblock_t *)temp_buff; + jsb->s_start = cpu_to_be32(0); + put_ext4((uint64_t) (blknr * fs->blksz), + (struct journal_superblock_t *)temp_buff, fs->blksz); + free(temp_buff); + } + ext4fs_free_journal(); + + /* get the superblock */ + ext4fs_devread(SUPERBLOCK_SECTOR, 0, SUPERBLOCK_SIZE, (char *)fs->sb); + fs->sb->feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER; + put_ext4((uint64_t)(SUPERBLOCK_SIZE), + (struct ext2_sblock *)fs->sb, (uint32_t)SUPERBLOCK_SIZE); + free(fs->sb); + fs->sb = NULL; + + if (fs->blk_bmaps) { + for (i = 0; i < fs->no_blkgrp; i++) { + free(fs->blk_bmaps[i]); + fs->blk_bmaps[i] = NULL; + } + free(fs->blk_bmaps); + fs->blk_bmaps = NULL; + } + + if (fs->inode_bmaps) { + for (i = 0; i < fs->no_blkgrp; i++) { + free(fs->inode_bmaps[i]); + fs->inode_bmaps[i] = NULL; + } + free(fs->inode_bmaps); + fs->inode_bmaps = NULL; + } + + + free(fs->gdtable); + fs->gdtable = NULL; + fs->gd = NULL; + /* + * reinitiliazed the global inode and + * block bitmap first execution check variables + */ + fs->first_pass_ibmap = 0; + fs->first_pass_bbmap = 0; + fs->curr_inode_no = 0; + fs->curr_blkno = 0; +} + +static int ext4fs_write_file(struct ext2_inode *file_inode, + int pos, unsigned int len, char *buf) +{ + int i; + int blockcnt; + int log2blocksize = LOG2_EXT2_BLOCK_SIZE(ext4fs_root); + unsigned int filesize = __le32_to_cpu(file_inode->size); + struct ext_filesystem *fs = get_fs(); + int previous_block_number = -1; + int delayed_start = 0; + int delayed_extent = 0; + int delayed_skipfirst = 0; + int delayed_next = 0; + char *delayed_buf = NULL; + + /* Adjust len so it we can't read past the end of the file. */ + if (len > filesize) + len = filesize; + + blockcnt = ((len + pos) + fs->blksz - 1) / fs->blksz; + + for (i = pos / fs->blksz; i < blockcnt; i++) { + long int blknr; + int blockend = fs->blksz; + int skipfirst = 0; + blknr = read_allocated_block(file_inode, i); + if (blknr < 0) + return -1; + + blknr = blknr << log2blocksize; + + if (blknr) { + if (previous_block_number != -1) { + if (delayed_next == blknr) { + delayed_extent += blockend; + delayed_next += blockend >> SECTOR_BITS; + } else { /* spill */ + put_ext4((uint64_t) (delayed_start * + SECTOR_SIZE), + delayed_buf, + (uint32_t) delayed_extent); + previous_block_number = blknr; + delayed_start = blknr; + delayed_extent = blockend; + delayed_skipfirst = skipfirst; + delayed_buf = buf; + delayed_next = blknr + + (blockend >> SECTOR_BITS); + } + } else { + previous_block_number = blknr; + delayed_start = blknr; + delayed_extent = blockend; + delayed_skipfirst = skipfirst; + delayed_buf = buf; + delayed_next = blknr + + (blockend >> SECTOR_BITS); + } + } else { + if (previous_block_number != -1) { + /* spill */ + put_ext4((uint64_t) (delayed_start * + SECTOR_SIZE), delayed_buf, + (uint32_t) delayed_extent); + previous_block_number = -1; + } + memset(buf, 0, fs->blksz - skipfirst); + } + buf += fs->blksz - skipfirst; + } + if (previous_block_number != -1) { + /* spill */ + put_ext4((uint64_t) (delayed_start * SECTOR_SIZE), + delayed_buf, (uint32_t) delayed_extent); + previous_block_number = -1; + } + + return len; +} + +int ext4fs_write(const char *fname, unsigned char *buffer, + unsigned long sizebytes) +{ + int ret = 0; + struct ext2_inode *file_inode = NULL; + unsigned char *inode_buffer = NULL; + int parent_inodeno; + int inodeno; + time_t timestamp = 0; + + uint64_t bytes_reqd_for_file; + unsigned int blks_reqd_for_file; + unsigned int blocks_remaining; + int existing_file_inodeno; + char filename[256]; + + char *temp_ptr = NULL; + long int itable_blkno; + long int parent_itable_blkno; + long int blkoff; + struct ext2_sblock *sblock = &(ext4fs_root->sblock); + unsigned int inodes_per_block; + unsigned int ibmap_idx; + struct ext_filesystem *fs = get_fs(); + g_parent_inode = zalloc(sizeof(struct ext2_inode)); + if (!g_parent_inode) + goto fail; + + if (ext4fs_init() != 0) { + printf("error in File System init\n"); + return -1; + } + inodes_per_block = fs->blksz / fs->inodesz; + parent_inodeno = ext4fs_get_parent_inode_num(fname, filename, F_FILE); + if (parent_inodeno == -1) + goto fail; + if (ext4fs_iget(parent_inodeno, g_parent_inode)) + goto fail; + /* check if the filename is already present in root */ + existing_file_inodeno = ext4fs_filename_check(filename); + if (existing_file_inodeno != -1) { + ret = ext4fs_delete_file(existing_file_inodeno); + fs->first_pass_bbmap = 0; + fs->curr_blkno = 0; + + fs->first_pass_ibmap = 0; + fs->curr_inode_no = 0; + if (ret) + goto fail; + } + /* calucalate how many blocks required */ + bytes_reqd_for_file = sizebytes; + blks_reqd_for_file = bytes_reqd_for_file / fs->blksz; + if (bytes_reqd_for_file % fs->blksz != 0) { + blks_reqd_for_file++; + debug("total bytes for a file %u\n", blks_reqd_for_file); + } + blocks_remaining = blks_reqd_for_file; + /* test for available space in partition */ + if (fs->sb->free_blocks < blks_reqd_for_file) { + printf("Not enough space on partition !!!\n"); + goto fail; + } + + ext4fs_update_parent_dentry(filename, &inodeno, FILETYPE_REG); + /* prepare file inode */ + inode_buffer = zalloc(fs->inodesz); + if (!inode_buffer) + goto fail; + file_inode = (struct ext2_inode *)inode_buffer; + file_inode->mode = S_IFREG | S_IRWXU | + S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH; + /* ToDo: Update correct time */ + file_inode->mtime = timestamp; + file_inode->atime = timestamp; + file_inode->ctime = timestamp; + file_inode->nlinks = 1; + file_inode->size = sizebytes; + + /* Allocate data blocks */ + ext4fs_allocate_blocks(file_inode, blocks_remaining, + &blks_reqd_for_file); + file_inode->blockcnt = (blks_reqd_for_file * fs->blksz) / SECTOR_SIZE; + + temp_ptr = zalloc(fs->blksz); + if (!temp_ptr) + goto fail; + ibmap_idx = inodeno / ext4fs_root->sblock.inodes_per_group; + inodeno--; + itable_blkno = __le32_to_cpu(fs->gd[ibmap_idx].inode_table_id) + + (inodeno % __le32_to_cpu(sblock->inodes_per_group)) / + inodes_per_block; + blkoff = (inodeno % inodes_per_block) * fs->inodesz; + ext4fs_devread(itable_blkno * fs->sect_perblk, 0, fs->blksz, temp_ptr); + if (ext4fs_log_journal(temp_ptr, itable_blkno)) + goto fail; + + memcpy(temp_ptr + blkoff, inode_buffer, fs->inodesz); + if (ext4fs_put_metadata(temp_ptr, itable_blkno)) + goto fail; + /* copy the file content into data blocks */ + if (ext4fs_write_file(file_inode, 0, sizebytes, (char *)buffer) == -1) { + printf("Error in copying content\n"); + goto fail; + } + ibmap_idx = parent_inodeno / ext4fs_root->sblock.inodes_per_group; + parent_inodeno--; + parent_itable_blkno = __le32_to_cpu(fs->gd[ibmap_idx].inode_table_id) + + (parent_inodeno % + __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block; + blkoff = (parent_inodeno % inodes_per_block) * fs->inodesz; + if (parent_itable_blkno != itable_blkno) { + memset(temp_ptr, '\0', fs->blksz); + ext4fs_devread(parent_itable_blkno * fs->sect_perblk, + 0, fs->blksz, temp_ptr); + if (ext4fs_log_journal(temp_ptr, parent_itable_blkno)) + goto fail; + + memcpy(temp_ptr + blkoff, g_parent_inode, + sizeof(struct ext2_inode)); + if (ext4fs_put_metadata(temp_ptr, parent_itable_blkno)) + goto fail; + free(temp_ptr); + } else { + /* + * If parent and child fall in same inode table block + * both should be kept in 1 buffer + */ + memcpy(temp_ptr + blkoff, g_parent_inode, + sizeof(struct ext2_inode)); + gd_index--; + if (ext4fs_put_metadata(temp_ptr, itable_blkno)) + goto fail; + free(temp_ptr); + } + ext4fs_update(); + ext4fs_deinit(); + + fs->first_pass_bbmap = 0; + fs->curr_blkno = 0; + fs->first_pass_ibmap = 0; + fs->curr_inode_no = 0; + free(inode_buffer); + free(g_parent_inode); + g_parent_inode = NULL; + + return 0; +fail: + ext4fs_deinit(); + free(inode_buffer); + free(g_parent_inode); + g_parent_inode = NULL; + + return -1; +} +#endif diff --git a/fs/fat/fat.c b/fs/fat/fat.c index bc46cc5..41ae15e 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -37,7 +37,7 @@ /* * Convert a string to lowercase. */ -static void downcase (char *str) +static void downcase(char *str) { while (*str != '\0') { TOLOWER(*str); @@ -62,7 +62,7 @@ static int disk_read(__u32 block, __u32 nr_blocks, void *buf) cur_part_info.start + block, nr_blocks, buf); } -int fat_register_device (block_dev_desc_t * dev_desc, int part_no) +int fat_register_device(block_dev_desc_t * dev_desc, int part_no) { ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); @@ -127,7 +127,7 @@ int fat_register_device (block_dev_desc_t * dev_desc, int part_no) * Get the first occurence of a directory delimiter ('/' or '\') in a string. * Return index into string if found, -1 otherwise. */ -static int dirdelim (char *str) +static int dirdelim(char *str) { char *start = str; @@ -142,7 +142,7 @@ static int dirdelim (char *str) /* * Extract zero terminated short name from a directory entry. */ -static void get_name (dir_entry *dirent, char *s_name) +static void get_name(dir_entry *dirent, char *s_name) { char *ptr; @@ -171,7 +171,7 @@ static void get_name (dir_entry *dirent, char *s_name) * Get the entry at index 'entry' in a FAT (12/16/32) table. * On failure 0x00 is returned. */ -static __u32 get_fatent (fsdata *mydata, __u32 entry) +static __u32 get_fatent(fsdata *mydata, __u32 entry) { __u32 bufnum; __u32 off16, offset; @@ -207,10 +207,9 @@ static __u32 get_fatent (fsdata *mydata, __u32 entry) __u32 fatlength = mydata->fatlength; __u32 startblock = bufnum * FATBUFBLOCKS; - if (getsize > fatlength) - getsize = fatlength; + if (startblock + getsize > fatlength) + getsize = fatlength - startblock; - fatlength *= mydata->sect_size; /* We want it in bytes now */ startblock += mydata->fat_sect; /* Offset from start of disk */ if (disk_read(startblock, getsize, bufptr) < 0) { @@ -270,12 +269,10 @@ static __u32 get_fatent (fsdata *mydata, __u32 entry) * Return 0 on success, -1 otherwise. */ static int -get_cluster (fsdata *mydata, __u32 clustnum, __u8 *buffer, - unsigned long size) +get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size) { __u32 idx = 0; __u32 startsect; - __u32 nr_sect; int ret; if (clustnum > 0) { @@ -287,38 +284,60 @@ get_cluster (fsdata *mydata, __u32 clustnum, __u8 *buffer, debug("gc - clustnum: %d, startsect: %d\n", clustnum, startsect); - nr_sect = size / mydata->sect_size; - ret = disk_read(startsect, nr_sect, buffer); - if (ret != nr_sect) { - debug("Error reading data (got %d)\n", ret); - return -1; - } - if (size % mydata->sect_size) { + if ((unsigned long)buffer & (ARCH_DMA_MINALIGN - 1)) { ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, mydata->sect_size); + printf("FAT: Misaligned buffer address (%p)\n", buffer); + + while (size >= mydata->sect_size) { + ret = disk_read(startsect++, 1, tmpbuf); + if (ret != 1) { + debug("Error reading data (got %d)\n", ret); + return -1; + } + + memcpy(buffer, tmpbuf, mydata->sect_size); + buffer += mydata->sect_size; + size -= mydata->sect_size; + } + } else { idx = size / mydata->sect_size; - ret = disk_read(startsect + idx, 1, tmpbuf); + ret = disk_read(startsect, idx, buffer); + if (ret != idx) { + debug("Error reading data (got %d)\n", ret); + return -1; + } + startsect += idx; + idx *= mydata->sect_size; + buffer += idx; + size -= idx; + } + if (size) { + ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, mydata->sect_size); + + ret = disk_read(startsect, 1, tmpbuf); if (ret != 1) { debug("Error reading data (got %d)\n", ret); return -1; } - buffer += idx * mydata->sect_size; - memcpy(buffer, tmpbuf, size % mydata->sect_size); - return 0; + memcpy(buffer, tmpbuf, size); } return 0; } /* - * Read at most 'maxsize' bytes from the file associated with 'dentptr' + * Read at most 'maxsize' bytes from 'pos' in the file associated with 'dentptr' * into 'buffer'. * Return the number of bytes read or -1 on fatal errors. */ +__u8 get_contents_vfatname_block[MAX_CLUSTSIZE] + __aligned(ARCH_DMA_MINALIGN); + static long -get_contents (fsdata *mydata, dir_entry *dentptr, __u8 *buffer, - unsigned long maxsize) +get_contents(fsdata *mydata, dir_entry *dentptr, unsigned long pos, + __u8 *buffer, unsigned long maxsize) { unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0; unsigned int bytesperclust = mydata->clust_size * mydata->sect_size; @@ -328,12 +347,59 @@ get_contents (fsdata *mydata, dir_entry *dentptr, __u8 *buffer, debug("Filesize: %ld bytes\n", filesize); - if (maxsize > 0 && filesize > maxsize) - filesize = maxsize; + if (pos >= filesize) { + debug("Read position past EOF: %lu\n", pos); + return gotsize; + } + + if (maxsize > 0 && filesize > pos + maxsize) + filesize = pos + maxsize; debug("%ld bytes\n", filesize); actsize = bytesperclust; + + /* go to cluster at pos */ + while (actsize <= pos) { + curclust = get_fatent(mydata, curclust); + if (CHECK_CLUST(curclust, mydata->fatsize)) { + debug("curclust: 0x%x\n", curclust); + debug("Invalid FAT entry\n"); + return gotsize; + } + actsize += bytesperclust; + } + + /* actsize > pos */ + actsize -= bytesperclust; + filesize -= actsize; + pos -= actsize; + + /* align to beginning of next cluster if any */ + if (pos) { + actsize = min(filesize, bytesperclust); + if (get_cluster(mydata, curclust, get_contents_vfatname_block, + (int)actsize) != 0) { + printf("Error reading cluster\n"); + return -1; + } + filesize -= actsize; + actsize -= pos; + memcpy(buffer, get_contents_vfatname_block + pos, actsize); + gotsize += actsize; + if (!filesize) + return gotsize; + buffer += actsize; + + curclust = get_fatent(mydata, curclust); + if (CHECK_CLUST(curclust, mydata->fatsize)) { + debug("curclust: 0x%x\n", curclust); + debug("Invalid FAT entry\n"); + return gotsize; + } + } + + actsize = bytesperclust; endclust = curclust; do { @@ -351,21 +417,9 @@ get_contents (fsdata *mydata, dir_entry *dentptr, __u8 *buffer, actsize += bytesperclust; } - /* actsize >= file size */ - actsize -= bytesperclust; - - /* get remaining clusters */ - if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) { - printf("Error reading cluster\n"); - return -1; - } - /* get remaining bytes */ - gotsize += (int)actsize; - filesize -= actsize; - buffer += actsize; actsize = filesize; - if (get_cluster(mydata, endclust, buffer, (int)actsize) != 0) { + if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) { printf("Error reading cluster\n"); return -1; } @@ -397,7 +451,7 @@ getit: * starting at l_name[*idx]. * Return 1 if terminator (zero byte) is found, 0 otherwise. */ -static int slot2str (dir_slot *slotptr, char *l_name, int *idx) +static int slot2str(dir_slot *slotptr, char *l_name, int *idx) { int j; @@ -429,12 +483,9 @@ static int slot2str (dir_slot *slotptr, char *l_name, int *idx) * into 'retdent' * Return 0 on success, -1 otherwise. */ -__u8 get_vfatname_block[MAX_CLUSTSIZE] - __aligned(ARCH_DMA_MINALIGN); - static int -get_vfatname (fsdata *mydata, int curclust, __u8 *cluster, - dir_entry *retdent, char *l_name) +get_vfatname(fsdata *mydata, int curclust, __u8 *cluster, + dir_entry *retdent, char *l_name) { dir_entry *realdent; dir_slot *slotptr = (dir_slot *)retdent; @@ -470,13 +521,13 @@ get_vfatname (fsdata *mydata, int curclust, __u8 *cluster, return -1; } - if (get_cluster(mydata, curclust, get_vfatname_block, + if (get_cluster(mydata, curclust, get_contents_vfatname_block, mydata->clust_size * mydata->sect_size) != 0) { debug("Error: reading directory block\n"); return -1; } - slotptr2 = (dir_slot *)get_vfatname_block; + slotptr2 = (dir_slot *)get_contents_vfatname_block; while (counter > 0) { if (((slotptr2->id & ~LAST_LONG_ENTRY_MASK) & 0xff) != counter) @@ -487,7 +538,7 @@ get_vfatname (fsdata *mydata, int curclust, __u8 *cluster, /* Save the real directory entry */ realdent = (dir_entry *)slotptr2; - while ((__u8 *)slotptr2 > get_vfatname_block) { + while ((__u8 *)slotptr2 > get_contents_vfatname_block) { slotptr2--; slot2str(slotptr2, l_name, &idx); } @@ -516,7 +567,7 @@ get_vfatname (fsdata *mydata, int curclust, __u8 *cluster, } /* Calculate short name checksum */ -static __u8 mkcksum (const char *str) +static __u8 mkcksum(const char *str) { int i; @@ -537,9 +588,9 @@ static __u8 mkcksum (const char *str) __u8 get_dentfromdir_block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); -static dir_entry *get_dentfromdir (fsdata *mydata, int startsect, - char *filename, dir_entry *retdent, - int dols) +static dir_entry *get_dentfromdir(fsdata *mydata, int startsect, + char *filename, dir_entry *retdent, + int dols) { __u16 prevcksum = 0xffff; __u32 curclust = START(retdent); @@ -699,7 +750,7 @@ static dir_entry *get_dentfromdir (fsdata *mydata, int startsect, * Read boot sector and volume info from a FAT filesystem */ static int -read_bootsectandvi (boot_sector *bs, volume_info *volinfo, int *fatsize) +read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize) { __u8 *block; volume_info *vistart; @@ -716,7 +767,7 @@ read_bootsectandvi (boot_sector *bs, volume_info *volinfo, int *fatsize) return -1; } - if (disk_read (0, 1, block) < 0) { + if (disk_read(0, 1, block) < 0) { debug("Error: reading block\n"); goto fail; } @@ -766,19 +817,19 @@ exit: return ret; } -__u8 do_fat_read_block[MAX_CLUSTSIZE] +__u8 do_fat_read_at_block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); long -do_fat_read (const char *filename, void *buffer, unsigned long maxsize, - int dols) +do_fat_read_at(const char *filename, unsigned long pos, void *buffer, + unsigned long maxsize, int dols) { char fnamecopy[2048]; boot_sector bs; volume_info volinfo; fsdata datablock; fsdata *mydata = &datablock; - dir_entry *dentptr; + dir_entry *dentptr = NULL; __u16 prevcksum = 0xffff; char *subname = ""; __u32 cursect; @@ -877,19 +928,21 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize, while (1) { int i; - debug("FAT read sect=%d, clust_size=%d, DIRENTSPERBLOCK=%zd\n", - cursect, mydata->clust_size, DIRENTSPERBLOCK); + if (j == 0) { + debug("FAT read sect=%d, clust_size=%d, DIRENTSPERBLOCK=%zd\n", + cursect, mydata->clust_size, DIRENTSPERBLOCK); - if (disk_read(cursect, - (mydata->fatsize == 32) ? - (mydata->clust_size) : - PREFETCH_BLOCKS, - do_fat_read_block) < 0) { - debug("Error: reading rootdir block\n"); - goto exit; - } + if (disk_read(cursect, + (mydata->fatsize == 32) ? + (mydata->clust_size) : + PREFETCH_BLOCKS, + do_fat_read_at_block) < 0) { + debug("Error: reading rootdir block\n"); + goto exit; + } - dentptr = (dir_entry *) do_fat_read_block; + dentptr = (dir_entry *) do_fat_read_at_block; + } for (i = 0; i < DIRENTSPERBLOCK; i++) { char s_name[14], l_name[VFAT_MAXLEN_BYTES]; @@ -908,7 +961,7 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize, get_vfatname(mydata, root_cluster, - do_fat_read_block, + do_fat_read_at_block, dentptr, l_name); if (dols == LS_ROOT) { @@ -1031,28 +1084,33 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize, * completely processed. */ ++j; - int fat32_end = 0; - if ((mydata->fatsize == 32) && (j == mydata->clust_size)) { - int nxtsect = 0; - int nxt_clust = 0; + int rootdir_end = 0; + if (mydata->fatsize == 32) { + if (j == mydata->clust_size) { + int nxtsect = 0; + int nxt_clust = 0; - nxt_clust = get_fatent(mydata, root_cluster); - fat32_end = CHECK_CLUST(nxt_clust, 32); + nxt_clust = get_fatent(mydata, root_cluster); + rootdir_end = CHECK_CLUST(nxt_clust, 32); - nxtsect = mydata->data_begin + - (nxt_clust * mydata->clust_size); + nxtsect = mydata->data_begin + + (nxt_clust * mydata->clust_size); - root_cluster = nxt_clust; + root_cluster = nxt_clust; - cursect = nxtsect; - j = 0; + cursect = nxtsect; + j = 0; + } } else { - cursect++; + if (j == PREFETCH_BLOCKS) + j = 0; + + rootdir_end = (++cursect - mydata->rootdir_sect >= + rootdir_size); } /* If end of rootdir reached */ - if ((mydata->fatsize == 32 && fat32_end) || - (mydata->fatsize != 32 && j == rootdir_size)) { + if (rootdir_end) { if (dols == LS_ROOT) { printf("\n%d file(s), %d dir(s)\n\n", files, dirs); @@ -1099,14 +1157,14 @@ rootdir_done: goto exit; } - if (idx >= 0) { - if (!(dentptr->attr & ATTR_DIR)) - goto exit; + if (isdir && !(dentptr->attr & ATTR_DIR)) + goto exit; + + if (idx >= 0) subname = nextname; - } } - ret = get_contents(mydata, dentptr, buffer, maxsize); + ret = get_contents(mydata, dentptr, pos, buffer, maxsize); debug("Size: %d, got: %ld\n", FAT2CPU32(dentptr->size), ret); exit: @@ -1114,7 +1172,13 @@ exit: return ret; } -int file_fat_detectfs (void) +long +do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols) +{ + return do_fat_read_at(filename, 0, buffer, maxsize, dols); +} + +int file_fat_detectfs(void) { boot_sector bs; volume_info volinfo; @@ -1177,13 +1241,19 @@ int file_fat_detectfs (void) return 0; } -int file_fat_ls (const char *dir) +int file_fat_ls(const char *dir) { return do_fat_read(dir, NULL, 0, LS_YES); } -long file_fat_read (const char *filename, void *buffer, unsigned long maxsize) +long file_fat_read_at(const char *filename, unsigned long pos, void *buffer, + unsigned long maxsize) { printf("reading %s\n", filename); - return do_fat_read(filename, buffer, maxsize, LS_NO); + return do_fat_read_at(filename, pos, buffer, maxsize, LS_NO); +} + +long file_fat_read(const char *filename, void *buffer, unsigned long maxsize) +{ + return file_fat_read_at(filename, 0, buffer, maxsize); } diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index a6181e7..5829adf 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -328,7 +328,7 @@ static void flush_dir_table(fsdata *mydata, dir_entry **dentptr); static void fill_dir_slot(fsdata *mydata, dir_entry **dentptr, const char *l_name) { - dir_slot *slotptr = (dir_slot *)get_vfatname_block; + dir_slot *slotptr = (dir_slot *)get_contents_vfatname_block; __u8 counter = 0, checksum; int idx = 0, ret; char s_name[16]; @@ -373,7 +373,7 @@ static __u32 dir_curclust; * a slot) into 'l_name'. If successful also copy the real directory entry * into 'retdent' * If additional adjacent cluster for directory entries is read into memory, - * then 'get_vfatname_block' is copied into 'get_dentfromdir_block' and + * then 'get_contents_vfatname_block' is copied into 'get_dentfromdir_block' and * the location of the real directory entry is returned by 'retdent' * Return 0 on success, -1 otherwise. */ @@ -416,13 +416,13 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster, dir_curclust = curclust; - if (get_cluster(mydata, curclust, get_vfatname_block, + if (get_cluster(mydata, curclust, get_contents_vfatname_block, mydata->clust_size * mydata->sect_size) != 0) { debug("Error: reading directory block\n"); return -1; } - slotptr2 = (dir_slot *)get_vfatname_block; + slotptr2 = (dir_slot *)get_contents_vfatname_block; while (counter > 0) { if (((slotptr2->id & ~LAST_LONG_ENTRY_MASK) & 0xff) != counter) @@ -433,7 +433,7 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster, /* Save the real directory entry */ realdent = (dir_entry *)slotptr2; - while ((__u8 *)slotptr2 > get_vfatname_block) { + while ((__u8 *)slotptr2 > get_contents_vfatname_block) { slotptr2--; slot2str(slotptr2, l_name, &idx); } @@ -459,9 +459,9 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster, *retdent = realdent; if (slotptr2) { - memcpy(get_dentfromdir_block, get_vfatname_block, + memcpy(get_dentfromdir_block, get_contents_vfatname_block, mydata->clust_size * mydata->sect_size); - cur_position = (__u8 *)realdent - get_vfatname_block; + cur_position = (__u8 *)realdent - get_contents_vfatname_block; *retdent = (dir_entry *) &get_dentfromdir_block[cur_position]; } @@ -980,11 +980,11 @@ static int do_fat_write(const char *filename, void *buffer, if (disk_read(cursect, (mydata->fatsize == 32) ? (mydata->clust_size) : - PREFETCH_BLOCKS, do_fat_read_block) < 0) { + PREFETCH_BLOCKS, do_fat_read_at_block) < 0) { debug("Error: reading rootdir block\n"); goto exit; } - dentptr = (dir_entry *) do_fat_read_block; + dentptr = (dir_entry *) do_fat_read_at_block; name_len = strlen(filename); if (name_len >= VFAT_MAXLEN_BYTES) diff --git a/fs/reiserfs/dev.c b/fs/reiserfs/dev.c index 1facfaf..cb288d6 100644 --- a/fs/reiserfs/dev.c +++ b/fs/reiserfs/dev.c @@ -25,24 +25,13 @@ #include "reiserfs_private.h" static block_dev_desc_t *reiserfs_block_dev_desc; -static disk_partition_t part_info; +static disk_partition_t *part_info; -int reiserfs_set_blk_dev(block_dev_desc_t *rbdd, int part) +void reiserfs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info) { reiserfs_block_dev_desc = rbdd; - - if (part == 0) { - /* disk doesn't use partition table */ - part_info.start = 0; - part_info.size = rbdd->lba; - part_info.blksz = rbdd->blksz; - } else { - if (get_partition_info (reiserfs_block_dev_desc, part, &part_info)) { - return 0; - } - } - return (part_info.size); + part_info = info; } @@ -59,7 +48,7 @@ int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf) */ if (sector < 0 || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) - >= part_info.size)) { + >= part_info->size)) { /* errnum = ERR_OUTSIDE_PART; */ printf (" ** reiserfs_devread() read outside partition\n"); return 0; @@ -83,7 +72,8 @@ int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf) if (byte_offset != 0) { /* read first part which isn't aligned with start of sector */ if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev, - part_info.start+sector, 1, (unsigned long *)sec_buf) != 1) { + part_info->start + sector, 1, + (unsigned long *)sec_buf) != 1) { printf (" ** reiserfs_devread() read error\n"); return 0; } @@ -96,8 +86,8 @@ int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf) /* read sector aligned part */ block_len = byte_len & ~(SECTOR_SIZE-1); if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev, - part_info.start+sector, block_len/SECTOR_SIZE, (unsigned long *)buf) != - block_len/SECTOR_SIZE) { + part_info->start + sector, block_len/SECTOR_SIZE, + (unsigned long *)buf) != block_len/SECTOR_SIZE) { printf (" ** reiserfs_devread() read error - block\n"); return 0; } @@ -108,7 +98,8 @@ int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf) if ( byte_len != 0 ) { /* read rest of data which are not in whole sector */ if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev, - part_info.start+sector, 1, (unsigned long *)sec_buf) != 1) { + part_info->start + sector, 1, + (unsigned long *)sec_buf) != 1) { printf (" ** reiserfs_devread() read error - last part\n"); return 0; } diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c index 604eb8f..44be3f5 100644 --- a/fs/ubifs/ubifs.c +++ b/fs/ubifs/ubifs.c @@ -37,8 +37,8 @@ DECLARE_GLOBAL_DATA_PTR; static int gzip_decompress(const unsigned char *in, size_t in_len, unsigned char *out, size_t *out_len) { - unsigned long len = in_len; - return zunzip(out, *out_len, (unsigned char *)in, &len, 0, 0); + return zunzip(out, *out_len, (unsigned char *)in, + (unsigned long *)out_len, 0, 0); } /* Fake description object for the "none" compressor */ @@ -295,6 +295,7 @@ static int ubifs_finddir(struct super_block *sb, char *dirname, struct file *file; struct dentry *dentry; struct inode *dir; + int ret = 0; file = kzalloc(sizeof(struct file), 0); dentry = kzalloc(sizeof(struct dentry), 0); @@ -336,7 +337,8 @@ static int ubifs_finddir(struct super_block *sb, char *dirname, if ((strncmp(dirname, (char *)dent->name, nm.len) == 0) && (strlen(dirname) == nm.len)) { *inum = le64_to_cpu(dent->inum); - return 1; + ret = 1; + goto out_free; } /* Switch to the next entry */ @@ -355,11 +357,10 @@ static int ubifs_finddir(struct super_block *sb, char *dirname, } out: - if (err != -ENOENT) { + if (err != -ENOENT) ubifs_err("cannot find next direntry, error %d", err); - return err; - } +out_free: if (file->private_data) kfree(file->private_data); if (file) @@ -369,7 +370,7 @@ out: if (dir) free(dir); - return 0; + return ret; } static unsigned long ubifs_findfile(struct super_block *sb, char *filename) diff --git a/fs/yaffs2/Makefile b/fs/yaffs2/Makefile index 31c12af..9b29d22 100644 --- a/fs/yaffs2/Makefile +++ b/fs/yaffs2/Makefile @@ -23,7 +23,7 @@ LIB = $(obj)libyaffs2.o COBJS-$(CONFIG_YAFFS2) := \ yaffs_allocator.o yaffs_attribs.o yaffs_bitmap.o yaffs_uboot_glue.o\ yaffs_checkptrw.o yaffs_ecc.o yaffs_error.o \ - yaffsfs.o yaffs_guts.o yaffs_hweight.o yaffs_nameval.o yaffs_nand.o\ + yaffsfs.o yaffs_guts.o yaffs_nameval.o yaffs_nand.o\ yaffs_packedtags1.o yaffs_packedtags2.o yaffs_qsort.o \ yaffs_summary.o yaffs_tagscompat.o yaffs_verify.o yaffs_yaffs1.o \ yaffs_yaffs2.o yaffs_mtdif.o yaffs_mtdif2.o diff --git a/fs/yaffs2/stdio.h b/fs/yaffs2/stdio.h deleted file mode 100644 index 9f379d7..0000000 --- a/fs/yaffs2/stdio.h +++ /dev/null @@ -1 +0,0 @@ -/* Dummy header for u-boot */ diff --git a/fs/yaffs2/stdlib.h b/fs/yaffs2/stdlib.h deleted file mode 100644 index 9f379d7..0000000 --- a/fs/yaffs2/stdlib.h +++ /dev/null @@ -1 +0,0 @@ -/* Dummy header for u-boot */ diff --git a/fs/yaffs2/string.h b/fs/yaffs2/string.h deleted file mode 100644 index 6501fa7..0000000 --- a/fs/yaffs2/string.h +++ /dev/null @@ -1,4 +0,0 @@ -#include <linux/stddef.h> -#include <linux/string.h> -#include <linux/stat.h> -#include <common.h> diff --git a/fs/yaffs2/yaffs_hweight.c b/fs/yaffs2/yaffs_hweight.c deleted file mode 100644 index d96773e..0000000 --- a/fs/yaffs2/yaffs_hweight.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2011 Aleph One Ltd. - * for Toby Churchill Ltd and Brightstar Engineering - * - * Created by Charles Manning <charles@aleph1.co.uk> - * - * 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. - */ - -/* These functions have been renamed to hweightxx to match the - * equivaqlent functions in the Linux kernel. - */ - -#include "yaffs_hweight.h" - -static const char yaffs_count_bits_table[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; - -int yaffs_hweight8(u8 x) -{ - int ret_val; - ret_val = yaffs_count_bits_table[x]; - return ret_val; -} - -int yaffs_hweight32(u32 x) -{ - return yaffs_hweight8(x & 0xff) + - yaffs_hweight8((x >> 8) & 0xff) + - yaffs_hweight8((x >> 16) & 0xff) + - yaffs_hweight8((x >> 24) & 0xff); -} diff --git a/fs/yaffs2/yaffs_hweight.h b/fs/yaffs2/yaffs_hweight.h deleted file mode 100644 index 3f7c6c3..0000000 --- a/fs/yaffs2/yaffs_hweight.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * YAFFS: Yet another Flash File System . A NAND-flash specific file system. - * - * Copyright (C) 2002-2011 Aleph One Ltd. - * for Toby Churchill Ltd and Brightstar Engineering - * - * Created by Charles Manning <charles@aleph1.co.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 as - * published by the Free Software Foundation. - * - * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. - */ - -#ifndef __YAFFS_HWEIGHT_H__ -#define __YAFFS_HWEIGHT_H__ - -#include "yportenv.h" - -int yaffs_hweight8(u8 x); -int yaffs_hweight32(u32 x); - -#endif diff --git a/fs/yaffs2/yaffs_mtdif2.c b/fs/yaffs2/yaffs_mtdif2.c index b27fe56..8135bcc 100644 --- a/fs/yaffs2/yaffs_mtdif2.c +++ b/fs/yaffs2/yaffs_mtdif2.c @@ -28,7 +28,6 @@ #include "yaffs_trace.h" #include "yaffs_packedtags2.h" -#include "string.h" #define yaffs_dev_to_mtd(dev) ((struct mtd_info *)((dev)->driver_context)) #define yaffs_dev_to_lc(dev) ((struct yaffs_linux_context *)((dev)->os_context)) @@ -46,9 +45,7 @@ int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk, struct mtd_oob_ops ops; int retval = 0; - loff_t addr; - u8 local_spare[128]; struct yaffs_packed_tags2 pt; diff --git a/fs/yaffs2/yaffsfs.c b/fs/yaffs2/yaffsfs.c index 9f1397b..ac4a010 100644 --- a/fs/yaffs2/yaffsfs.c +++ b/fs/yaffs2/yaffsfs.c @@ -17,8 +17,6 @@ #include "yportenv.h" #include "yaffs_trace.h" -#include "string.h" - #define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5 #ifndef NULL diff --git a/fs/yaffs2/ydirectenv.h b/fs/yaffs2/ydirectenv.h index df0b8fb..c912b09 100644 --- a/fs/yaffs2/ydirectenv.h +++ b/fs/yaffs2/ydirectenv.h @@ -20,15 +20,14 @@ #ifndef __YDIRECTENV_H__ #define __YDIRECTENV_H__ -#include "stdlib.h" -#include "stdio.h" -#include "string.h" +#include <common.h> +#include <malloc.h> +#include <linux/compat.h> + #include "yaffs_osglue.h" -#include "yaffs_hweight.h" void yaffs_bug_fn(const char *file_name, int line_no); -#define BUG() do { yaffs_bug_fn(__FILE__, __LINE__); } while (0) #define YCHAR char @@ -47,8 +46,6 @@ void yaffs_bug_fn(const char *file_name, int line_no); #define yaffs_strncmp(a, b, c) strncmp(a, b, c) #endif -#define hweight8(x) yaffs_hweight8(x) -#define hweight32(x) yaffs_hweight32(x) void yaffs_qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *)); @@ -63,11 +60,6 @@ void yaffs_qsort(void *aa, size_t n, size_t es, #define inline __inline__ #endif -#define kmalloc(x, flags) yaffsfs_malloc(x) -#define kfree(x) yaffsfs_free(x) -#define vmalloc(x) yaffsfs_malloc(x) -#define vfree(x) yaffsfs_free(x) - #define cond_resched() do {} while (0) #define yaffs_trace(msk, fmt, ...) do { \ diff --git a/fs/yaffs2/yportenv.h b/fs/yaffs2/yportenv.h index b47a4d6..251eba0 100644 --- a/fs/yaffs2/yportenv.h +++ b/fs/yaffs2/yportenv.h @@ -17,6 +17,7 @@ #ifndef __YPORTENV_H__ #define __YPORTENV_H__ +#include <linux/types.h> /* Definition of types */ #ifdef CONFIG_YAFFS_DEFINES_TYPES diff --git a/fs/zfs/dev.c b/fs/zfs/dev.c index d68372c..36be8f5 100644 --- a/fs/zfs/dev.c +++ b/fs/zfs/dev.c @@ -26,23 +26,12 @@ #include <zfs_common.h> static block_dev_desc_t *zfs_block_dev_desc; -static disk_partition_t part_info; +static disk_partition_t *part_info; -int zfs_set_blk_dev(block_dev_desc_t *rbdd, int part) +void zfs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info) { zfs_block_dev_desc = rbdd; - - if (part == 0) { - /* disk doesn't use partition table */ - part_info.start = 0; - part_info.size = rbdd->lba; - part_info.blksz = rbdd->blksz; - } else { - if (get_partition_info(zfs_block_dev_desc, part, &part_info)) - return 0; - } - - return part_info.size; + part_info = info; } /* err */ @@ -57,7 +46,7 @@ int zfs_devread(int sector, int byte_offset, int byte_len, char *buf) */ if ((sector < 0) || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >= - part_info.size)) { + part_info->size)) { /* errnum = ERR_OUTSIDE_PART; */ printf(" ** zfs_devread() read outside partition sector %d\n", sector); return 1; @@ -79,8 +68,8 @@ int zfs_devread(int sector, int byte_offset, int byte_len, char *buf) if (byte_offset != 0) { /* read first part which isn't aligned with start of sector */ if (zfs_block_dev_desc->block_read(zfs_block_dev_desc->dev, - part_info.start + sector, 1, - (unsigned long *) sec_buf) != 1) { + part_info->start + sector, 1, + (unsigned long *)sec_buf) != 1) { printf(" ** zfs_devread() read error **\n"); return 1; } @@ -102,17 +91,15 @@ int zfs_devread(int sector, int byte_offset, int byte_len, char *buf) block_len = SECTOR_SIZE; zfs_block_dev_desc->block_read(zfs_block_dev_desc->dev, - part_info.start + sector, - 1, (unsigned long *)p); + part_info->start + sector, + 1, (unsigned long *)p); memcpy(buf, p, byte_len); return 0; } if (zfs_block_dev_desc->block_read(zfs_block_dev_desc->dev, - part_info.start + sector, - block_len / SECTOR_SIZE, - (unsigned long *) buf) != - block_len / SECTOR_SIZE) { + part_info->start + sector, block_len / SECTOR_SIZE, + (unsigned long *) buf) != block_len / SECTOR_SIZE) { printf(" ** zfs_devread() read error - block\n"); return 1; } @@ -126,7 +113,7 @@ int zfs_devread(int sector, int byte_offset, int byte_len, char *buf) /* read rest of data which are not in whole sector */ if (zfs_block_dev_desc-> block_read(zfs_block_dev_desc->dev, - part_info.start + sector, 1, + part_info->start + sector, 1, (unsigned long *) sec_buf) != 1) { printf(" ** zfs_devread() read error - last part\n"); return 1; diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index c19e16c..23c9649 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -94,4 +94,13 @@ int gpio_get_value(unsigned gpio); */ int gpio_set_value(unsigned gpio, int value); +/** + * Request a gpio. This should be called before any of the other functions + * are used on this gpio. + * + * @param gp GPIO number + * @param label User label for this GPIO + * @return 0 if ok, -1 on error + */ +int gpio_request(unsigned gpio, const char *label); #endif /* _ASM_GENERIC_GPIO_H_ */ diff --git a/include/command.h b/include/command.h index 6e1bdc2..1f06aa1 100644 --- a/include/command.h +++ b/include/command.h @@ -110,6 +110,10 @@ static inline int bootm_maybe_autostart(cmd_tbl_t *cmdtp, const char *cmd) return 0; } #endif + +extern int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, + char *const argv[]); + extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); /* diff --git a/include/common.h b/include/common.h index 55025c0..a7fb05e 100644 --- a/include/common.h +++ b/include/common.h @@ -829,6 +829,13 @@ void fputc(int file, const char c); int ftstc(int file); int fgetc(int file); +/* lib/gzip.c */ +int gzip(void *dst, unsigned long *lenp, + unsigned char *src, unsigned long srclen); +int zzip(void *dst, unsigned long *lenp, unsigned char *src, + unsigned long srclen, int stoponerr, + int (*func)(unsigned long, unsigned long)); + /* lib/net_utils.c */ #include <net.h> static inline IPaddr_t getenv_IPaddr(char *var) diff --git a/include/configs/M5373EVB.h b/include/configs/M5373EVB.h index 0d09f0e..45d1064 100644 --- a/include/configs/M5373EVB.h +++ b/include/configs/M5373EVB.h @@ -1,7 +1,7 @@ /* * Configuation settings for the Freescale MCF5373 FireEngine board. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -59,7 +59,7 @@ #define CONFIG_CMD_PING #define CONFIG_CMD_REGINFO -#ifdef NANDFLASH_SIZE +#ifdef CONFIG_NANDFLASH_SIZE # define CONFIG_CMD_NAND #endif @@ -208,7 +208,7 @@ # define CONFIG_SYS_FLASH_PROTECTION /* "Real" (hardware) sectors protection */ #endif -#ifdef NANDFLASH_SIZE +#ifdef CONFIG_NANDFLASH_SIZE # define CONFIG_SYS_MAX_NAND_DEVICE 1 # define CONFIG_SYS_NAND_BASE CONFIG_SYS_CS2_BASE # define CONFIG_SYS_NAND_SIZE 1 @@ -264,9 +264,9 @@ #define CONFIG_SYS_CS1_MASK 0x001f0001 #define CONFIG_SYS_CS1_CTRL 0x002A3780 -#ifdef NANDFLASH_SIZE +#ifdef CONFIG_NANDFLASH_SIZE #define CONFIG_SYS_CS2_BASE 0x20000000 -#define CONFIG_SYS_CS2_MASK ((NANDFLASH_SIZE << 20) | 1) +#define CONFIG_SYS_CS2_MASK ((CONFIG_NANDFLASH_SIZE << 20) | 1) #define CONFIG_SYS_CS2_CTRL 0x00001f60 #endif diff --git a/include/configs/MPC8308RDB.h b/include/configs/MPC8308RDB.h index 7f2761c..2d48dde 100644 --- a/include/configs/MPC8308RDB.h +++ b/include/configs/MPC8308RDB.h @@ -37,6 +37,24 @@ #define CONFIG_MISC_INIT_R +/* new uImage format support */ +#define CONFIG_FIT 1 +#define CONFIG_FIT_VERBOSE 1 + +#define CONFIG_MMC 1 + +#ifdef CONFIG_MMC +#define CONFIG_FSL_ESDHC +#define CONFIG_SYS_FSL_ESDHC_ADDR CONFIG_SYS_MPC83xx_ESDHC_ADDR +#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 +#define CONFIG_SYS_FSL_ESDHC_USE_PIO + +#define CONFIG_CMD_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_CMD_FAT +#define CONFIG_DOS_PARTITION +#endif + /* * On-board devices * @@ -340,6 +358,19 @@ #define CONFIG_SYS_I2C_OFFSET 0x3000 #define CONFIG_SYS_I2C2_OFFSET 0x3100 +/* + * SPI on header J8 + * + * WARNING: enabling this will break TSEC2 (connected to the Vitesse switch) + * due to a pinmux conflict between GPIO9 (SPI chip select )and the TSEC2 pins. + */ +#ifdef CONFIG_MPC8XXX_SPI +#define CONFIG_CMD_SPI +#define CONFIG_USE_SPIFLASH +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_SPANSION +#define CONFIG_CMD_SF +#endif /* * Board info - revision and where boot from diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h index 1c0eb74..3169665 100644 --- a/include/configs/P2041RDB.h +++ b/include/configs/P2041RDB.h @@ -22,7 +22,7 @@ /* * P2041 RDB board configuration file - * + * Also supports P2040 RDB */ #ifndef __CONFIG_H #define __CONFIG_H @@ -36,6 +36,15 @@ #define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc #endif +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE +/* Set 1M boot space */ +#define CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR (CONFIG_SYS_TEXT_BASE & 0xfff00000) +#define CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS \ + (0x300000000ull | CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR) +#define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc +#define CONFIG_SYS_NO_FLASH +#endif + /* High Level Configuration Options */ #define CONFIG_BOOKE #define CONFIG_E500 /* BOOKE e500 family */ @@ -73,7 +82,7 @@ #define CONFIG_ENV_OVERWRITE #ifdef CONFIG_SYS_NO_FLASH -#ifndef CONFIG_RAMBOOT_PBL +#if !defined(CONFIG_RAMBOOT_PBL) && !defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) #define CONFIG_ENV_IS_NOWHERE #endif #else @@ -104,8 +113,12 @@ #define CONFIG_ENV_IS_IN_NAND #define CONFIG_ENV_SIZE CONFIG_SYS_NAND_BLOCK_SIZE #define CONFIG_ENV_OFFSET (5 * CONFIG_SYS_NAND_BLOCK_SIZE) +#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) +#define CONFIG_ENV_IS_IN_REMOTE +#define CONFIG_ENV_ADDR 0xffe20000 +#define CONFIG_ENV_SIZE 0x2000 #elif defined(CONFIG_ENV_IS_NOWHERE) - #define CONFIG_ENV_SIZE 0x2000 +#define CONFIG_ENV_SIZE 0x2000 #else #define CONFIG_ENV_IS_IN_FLASH #define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE \ @@ -374,6 +387,35 @@ unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_SYS_SRIO2_MEM_SIZE 0x10000000 /* 256M */ /* + * for slave u-boot IMAGE instored in master memory space, + * PHYS must be aligned based on the SIZE + */ +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS 0xfef080000ull +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 0xfff80000ull +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE 0x80000 /* 512K */ +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 0x3fff80000ull +/* + * for slave UCODE and ENV instored in master memory space, + * PHYS must be aligned based on the SIZE + */ +#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS 0xfef040000ull +#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS 0x3ffe00000ull +#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE 0x40000 /* 256K */ + +/* slave core release by master*/ +#define CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET 0xe00e4 +#define CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK 0x00000001 /* release core 0 */ + +/* + * SRIO_PCIE_BOOT - SLAVE + */ +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE +#define CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR 0xFFE00000 +#define CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS \ + (0x300000000ull | CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR) +#endif + +/* * eSPI - Enhanced SPI */ #define CONFIG_FSL_ESPI @@ -485,6 +527,16 @@ unsigned long get_board_sys_clk(unsigned long dummy); #elif defined(CONFIG_NAND) #define CONFIG_SYS_QE_FMAN_FW_IN_NAND #define CONFIG_SYS_QE_FMAN_FW_ADDR (6 * CONFIG_SYS_NAND_BLOCK_SIZE) +#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) +/* + * Slave has no ucode locally, it can fetch this from remote. When implementing + * in two corenet boards, slave's ucode could be stored in master's memory + * space, the address can be mapped from slave TLB->slave LAW-> + * slave SRIO or PCIE outbound window->master inbound window-> + * master LAW->the ucode address in master's memory space. + */ +#define CONFIG_SYS_QE_FMAN_FW_IN_REMOTE +#define CONFIG_SYS_QE_FMAN_FW_ADDR 0xFFE00000 #else #define CONFIG_SYS_QE_FMAN_FW_IN_NOR #define CONFIG_SYS_QE_FMAN_FW_ADDR 0xEF000000 diff --git a/include/configs/P4080DS.h b/include/configs/P4080DS.h index 4a2e475..d6f2f5c 100644 --- a/include/configs/P4080DS.h +++ b/include/configs/P4080DS.h @@ -22,6 +22,7 @@ /* * P4080 DS board configuration file + * Also supports P4040 DS */ #define CONFIG_P4080DS #define CONFIG_PHYS_64BIT diff --git a/include/configs/P5020DS.h b/include/configs/P5020DS.h index 4afc4f1..8625f76 100644 --- a/include/configs/P5020DS.h +++ b/include/configs/P5020DS.h @@ -22,7 +22,7 @@ /* * P5020 DS board configuration file - * + * Also supports P5010 DS */ #define CONFIG_P5020DS #define CONFIG_PHYS_64BIT diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index a3752bc..263a5ad 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -193,6 +193,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_TEXT_BASE 0x402F0400 #define CONFIG_SPL_MAX_SIZE (46 * 1024) #define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR diff --git a/include/configs/am3517_crane.h b/include/configs/am3517_crane.h index f24b44d..8ddeff4 100644 --- a/include/configs/am3517_crane.h +++ b/include/configs/am3517_crane.h @@ -314,6 +314,8 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_TEXT_BASE 0x40200800 #define CONFIG_SPL_MAX_SIZE (54 * 1024) /* 8 KB for stack */ diff --git a/include/configs/am3517_evm.h b/include/configs/am3517_evm.h index 95f8d78..6980811 100644 --- a/include/configs/am3517_evm.h +++ b/include/configs/am3517_evm.h @@ -313,6 +313,8 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_TEXT_BASE 0x40200800 #define CONFIG_SPL_MAX_SIZE (54 * 1024) /* 8 KB for stack */ diff --git a/include/configs/apollon.h b/include/configs/apollon.h deleted file mode 100644 index b8ca8a8..0000000 --- a/include/configs/apollon.h +++ /dev/null @@ -1,261 +0,0 @@ -/* - * (C) Copyright 2005-2008 - * Samsung Electronics, - * Kyungmin Park <kyungmin.park@samsung.com> - * - * Configuration settings for the 2420 Samsung Apollon board. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef __CONFIG_H -#define __CONFIG_H - -/* - * High Level Configuration Options - */ -#define CONFIG_ARM1136 1 /* This is an arm1136 CPU core */ -#define CONFIG_OMAP 1 /* in a TI OMAP core */ -#define CONFIG_OMAP2420 1 /* which is in a 2420 */ -#define CONFIG_OMAP2420_APOLLON 1 -#define CONFIG_APOLLON 1 -#define CONFIG_APOLLON_PLUS 1 /* If you have apollon plus 1.x */ - -#define CONFIG_ONENAND_U_BOOT y - -/* Clock config to target*/ -#define PRCM_CONFIG_I 1 -/* #define PRCM_CONFIG_II 1 */ - -/* Boot method */ -/* uncomment if you use NOR boot */ -/* #define CONFIG_SYS_NOR_BOOT 1 */ - -/* uncomment if you use NOR on CS3 */ -/* #define CONFIG_SYS_USE_NOR 1 */ - -#ifdef CONFIG_SYS_NOR_BOOT -#undef CONFIG_SYS_USE_NOR -#define CONFIG_SYS_USE_NOR 1 -#endif - -/* uncommnet if you want to use UBI */ -#define CONFIG_SYS_USE_UBI - -#include <asm/arch/omap2420.h> /* get chip and board defs */ - -#define V_SCLK 12000000 - -/* input clock of PLL */ -/* the OMAP2420 H4 has 12MHz, 13MHz, or 19.2Mhz crystal input */ -#define CONFIG_SYS_CLK_FREQ V_SCLK - -#define CONFIG_MISC_INIT_R - -#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ -#define CONFIG_SETUP_MEMORY_TAGS 1 -#define CONFIG_INITRD_TAG 1 -#define CONFIG_REVISION_TAG 1 - -/* - * Size of malloc() pool - */ -#define CONFIG_ENV_SIZE SZ_128K /* Total Size of Environment Sector */ -#define CONFIG_ENV_SIZE_FLEX SZ_256K -#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_1M) - -/* - * Hardware drivers - */ - -/* - * SMC91c96 Etherent - */ -#define CONFIG_LAN91C96 -#define CONFIG_LAN91C96_BASE (APOLLON_CS1_BASE+0x300) -#define CONFIG_LAN91C96_EXT_PHY - -/* - * NS16550 Configuration - */ -#define V_NS16550_CLK (48000000) /* 48MHz (APLL96/2) */ - -#define CONFIG_SYS_NS16550 -#define CONFIG_SYS_NS16550_SERIAL -#define CONFIG_SYS_NS16550_REG_SIZE (-4) -#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK /* 3MHz (1.5MHz*2) */ -#define CONFIG_SYS_NS16550_COM1 OMAP2420_UART1 - -/* - * select serial console configuration - */ -#define CONFIG_SERIAL1 1 /* UART1 on H4 */ - -/* allow to overwrite serial and ethaddr */ -#define CONFIG_ENV_OVERWRITE -#define CONFIG_CONS_INDEX 1 -#define CONFIG_BAUDRATE 115200 - -/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ -#include <config_cmd_default.h> - -#define CONFIG_CMD_DHCP -#define CONFIG_CMD_DIAG -#define CONFIG_CMD_ONENAND - -#ifdef CONFIG_SYS_USE_UBI -#define CONFIG_CMD_JFFS2 -#define CONFIG_CMD_UBI -#define CONFIG_RBTREE -#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */ -#define CONFIG_MTD_PARTITIONS -#endif - -#undef CONFIG_CMD_SOURCE - -#ifndef CONFIG_SYS_USE_NOR -# undef CONFIG_CMD_FLASH -# undef CONFIG_CMD_IMLS -#endif - -#define CONFIG_BOOTP_MASK CONFIG_BOOTP_DEFAULT - -#define CONFIG_BOOTDELAY 1 - -#define CONFIG_NETMASK 255.255.255.0 -#define CONFIG_IPADDR 192.168.116.25 -#define CONFIG_SERVERIP 192.168.116.1 -#define CONFIG_BOOTFILE "uImage" -#define CONFIG_ETHADDR 00:0E:99:00:24:20 - -#ifdef CONFIG_APOLLON_PLUS -#define CONFIG_SYS_MEM "mem=64M" -#else -#define CONFIG_SYS_MEM "mem=128" -#endif - -#ifdef CONFIG_SYS_USE_UBI -#define CONFIG_SYS_UBI "ubi.mtd=4" -#else -#define CONFIG_SYS_UBI "" -#endif - -#define CONFIG_BOOTARGS "root=/dev/nfs rw " CONFIG_SYS_MEM \ - " console=ttyS0,115200n8" \ - " ip=192.168.116.25:192.168.116.1:192.168.116.1:255.255.255.0:" \ - "apollon:eth0:off nfsroot=/tftpboot/nfsroot profile=2 " \ - CONFIG_SYS_UBI - -#define CONFIG_EXTRA_ENV_SETTINGS \ - "Image=tftp 0x80008000 Image; go 0x80008000\0" \ - "zImage=tftp 0x80180000 zImage; go 0x80180000\0" \ - "uImage=tftp 0x80180000 uImage; bootm 0x80180000\0" \ - "uboot=tftp 0x80008000 u-boot.bin; go 0x80008000\0" \ - "xloader=tftp 0x80180000 x-load.bin; " \ - " cp.w 0x80180000 0x00000400 0x1000; go 0x00000400\0" \ - "syncmode50=mw.w 0x1e442 0xc0c4; mw 0x6800a060 0xe30d1201\0" \ - "syncmode=mw.w 0x1e442 0xe0f4; mw 0x6800a060 0xe30d1201\0" \ - "norboot=cp32 0x18040000 0x80008000 0x200000; go 0x80008000\0" \ - "oneboot=onenand read 0x80008000 0x40000 0x200000; go 0x80008000\0" \ - "onesyncboot=run syncmode oneboot\0" \ - "updateb=tftp 0x80180000 u-boot-onenand.bin; " \ - " onenand erase 0x0 0x20000; onenand write 0x80180000 0x0 0x20000\0" \ - "ubi=setenv bootargs ${bootargs} ubi.mtd=4 ${mtdparts}; run uImage\0" \ - "bootcmd=run uboot\0" - -/* - * Miscellaneous configurable options - */ -#define CONFIG_SYS_LONGHELP /* undef to save memory */ -#define CONFIG_SYS_PROMPT "Apollon # " -#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ -/* Print Buffer Size */ -#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) -#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ -/* Boot Argument Buffer Size */ -#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE -/* memtest works on */ -#define CONFIG_SYS_MEMTEST_START (OMAP2420_SDRC_CS0) -#define CONFIG_SYS_MEMTEST_END (OMAP2420_SDRC_CS0+SZ_31M) - -/* default load address */ -#define CONFIG_SYS_LOAD_ADDR (OMAP2420_SDRC_CS0) - -/* The 2420 has 12 GP timers, they can be driven by the SysClk (12/13/19.2) - * or by 32KHz clk, or from external sig. This rate is divided by a local - * divisor. - */ -#define CONFIG_SYS_TIMERBASE OMAP2420_GPT2 -#define CONFIG_SYS_PTV 7 /* 2^(PTV+1) */ -#define CONFIG_SYS_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CONFIG_SYS_PTV)) - -/*----------------------------------------------------------------------- - * Physical Memory Map - */ -#define CONFIG_NR_DRAM_BANKS 1 /* CS1 may or may not be populated */ -#define PHYS_SDRAM_1 OMAP2420_SDRC_CS0 -#define PHYS_SDRAM_1_SIZE SZ_128M -#define PHYS_SDRAM_2 OMAP2420_SDRC_CS1 - -/*----------------------------------------------------------------------- - * FLASH and environment organization - */ -#ifdef CONFIG_SYS_USE_NOR -/* OneNAND boot, NOR has CS3, But NOR has CS0 when NOR boot */ -# define CONFIG_SYS_FLASH_BASE 0x18000000 -# define CONFIG_SYS_MAX_FLASH_BANKS 1 -# define CONFIG_SYS_MAX_FLASH_SECT 1024 -/*----------------------------------------------------------------------- - * CFI FLASH driver setup - */ -/* Flash memory is CFI compliant */ -# define CONFIG_SYS_FLASH_CFI 1 -# define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */ -/* Use buffered writes (~10x faster) */ -/* #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 1 */ -/* Use h/w sector protection*/ -# define CONFIG_SYS_FLASH_PROTECTION 1 - -#else /* !CONFIG_SYS_USE_NOR */ -# define CONFIG_SYS_NO_FLASH 1 -#endif /* CONFIG_SYS_USE_NOR */ - -/* OneNAND boot, OneNAND has CS0, NOR boot ONeNAND has CS2 */ -#define CONFIG_SYS_ONENAND_BASE 0x00000000 -#define CONFIG_SYS_MONITOR_LEN SZ_256K /* U-Boot image size */ -#define CONFIG_ENV_IS_IN_ONENAND 1 -#define CONFIG_ENV_ADDR 0x00020000 -#define CONFIG_ENV_ADDR_FLEX 0x00040000 - -#ifdef CONFIG_SYS_USE_UBI -#define CONFIG_CMD_MTDPARTS -#define MTDIDS_DEFAULT "onenand0=onenand" -#define MTDPARTS_DEFAULT "mtdparts=onenand:128k(bootloader)," \ - "128k(params)," \ - "2m(kernel)," \ - "16m(rootfs)," \ - "32m(fs)," \ - "-(ubifs)" -#endif - -#define PHYS_SRAM 0x4020F800 -#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 -#define CONFIG_SYS_INIT_SP_ADDR PHYS_SRAM - -#endif /* __CONFIG_H */ diff --git a/include/configs/atngw100mkii.h b/include/configs/atngw100mkii.h new file mode 100644 index 0000000..f85374f --- /dev/null +++ b/include/configs/atngw100mkii.h @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2006 Atmel Corporation + * + * Copyright (C) 2012 Andreas Bießmann <andreas.devel@googlemail.com> + * + * Configuration settings for the AVR32 Network Gateway + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +#include <asm/arch/hardware.h> + +#define CONFIG_AVR32 +#define CONFIG_AT32AP +#define CONFIG_AT32AP7000 +#define CONFIG_ATNGW100MKII + +/* + * Timer clock frequency. We're using the CPU-internal COUNT register + * for this, so this is equivalent to the CPU core clock frequency + */ +#define CONFIG_SYS_HZ 1000 + +/* + * Set up the PLL to run at 140 MHz, the CPU to run at the PLL + * frequency, the HSB and PBB busses to run at 1/2 the PLL frequency + * and the PBA bus to run at 1/4 the PLL frequency. + */ +#define CONFIG_PLL +#define CONFIG_SYS_POWER_MANAGER +#define CONFIG_SYS_OSC0_HZ 20000000 +#define CONFIG_SYS_PLL0_DIV 1 +#define CONFIG_SYS_PLL0_MUL 7 +#define CONFIG_SYS_PLL0_SUPPRESS_CYCLES 16 +/* + * Set the CPU running at: + * PLL / (2^CONFIG_SYS_CLKDIV_CPU) = CPU MHz + */ +#define CONFIG_SYS_CLKDIV_CPU 0 +/* + * Set the HSB running at: + * PLL / (2^CONFIG_SYS_CLKDIV_HSB) = HSB MHz + */ +#define CONFIG_SYS_CLKDIV_HSB 1 +/* + * Set the PBA running at: + * PLL / (2^CONFIG_SYS_CLKDIV_PBA) = PBA MHz + */ +#define CONFIG_SYS_CLKDIV_PBA 2 +/* + * Set the PBB running at: + * PLL / (2^CONFIG_SYS_CLKDIV_PBB) = PBB MHz + */ +#define CONFIG_SYS_CLKDIV_PBB 1 + +/* Reserve VM regions for NOR flash, NAND flash and SDRAM */ +#define CONFIG_SYS_NR_VM_REGIONS 3 + +/* + * The PLLOPT register controls the PLL like this: + * icp = PLLOPT<2> + * ivco = PLLOPT<1:0> + * + * We want icp=1 (default) and ivco=0 (80-160 MHz) or ivco=2 (150-240MHz). + */ +#define CONFIG_SYS_PLL0_OPT 0x04 + +#define CONFIG_USART_BASE ATMEL_BASE_USART1 +#define CONFIG_USART_ID 1 + +/* User serviceable stuff */ +#define CONFIG_DOS_PARTITION + +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG + +#define CONFIG_STACKSIZE (2048) + +#define CONFIG_BAUDRATE 115200 +#define CONFIG_BOOTARGS \ + "root=mtd:main rootfstype=jffs2" +#define CONFIG_BOOTCOMMAND \ + "fsload 0x10400000 /uImage; bootm" + +/* + * Only interrupt autoboot if <space> is pressed. Otherwise, garbage + * data on the serial line may interrupt the boot sequence. + */ +#define CONFIG_BOOTDELAY 1 +#define CONFIG_AUTOBOOT +#define CONFIG_AUTOBOOT_KEYED +#define CONFIG_AUTOBOOT_PROMPT \ + "Press SPACE to abort autoboot in %d seconds\n", bootdelay +#define CONFIG_AUTOBOOT_DELAY_STR "d" +#define CONFIG_AUTOBOOT_STOP_STR " " + +/* + * After booting the board for the first time, new ethernet addresses + * should be generated and assigned to the environment variables + * "ethaddr" and "eth1addr". This is normally done during production. + */ +#define CONFIG_OVERWRITE_ETHADDR_ONCE +#define CONFIG_NET_MULTI + +/* + * BOOTP/DHCP options + */ +#define CONFIG_BOOTP_SUBNETMASK +#define CONFIG_BOOTP_GATEWAY + +/* + * Command line configuration. + */ +#include <config_cmd_default.h> + +#define CONFIG_CMD_ASKENV +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_JFFS2 +#define CONFIG_CMD_MMC +#define CONFIG_CMD_SF +#define CONFIG_CMD_SPI +#define CONFIG_CMD_MII + +#undef CONFIG_CMD_FPGA +#undef CONFIG_CMD_SETGETDCR +#undef CONFIG_CMD_XIMG + +#define CONFIG_ATMEL_USART +#define CONFIG_MACB +#define CONFIG_PORTMUX_PIO +#define CONFIG_SYS_NR_PIOS 5 +#define CONFIG_SYS_HSDRAMC +#define CONFIG_MMC +#define CONFIG_GENERIC_ATMEL_MCI +#define CONFIG_GENERIC_MMC +#define CONFIG_SYS_MMC_MAX_BLK_COUNT 1 +#define CONFIG_ATMEL_SPI + +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_ATMEL + +#define CONFIG_SYS_DCACHE_LINESZ 32 +#define CONFIG_SYS_ICACHE_LINESZ 32 + +#define CONFIG_NR_DRAM_BANKS 1 + +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_PROTECTION + +#define CONFIG_SYS_FLASH_BASE 0x00000000 +#define CONFIG_SYS_FLASH_SIZE 0x800000 +#define CONFIG_SYS_MAX_FLASH_BANKS 1 +#define CONFIG_SYS_MAX_FLASH_SECT 135 + +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE + +#define CONFIG_SYS_INTRAM_BASE INTERNAL_SRAM_BASE +#define CONFIG_SYS_INTRAM_SIZE INTERNAL_SRAM_SIZE +#define CONFIG_SYS_SDRAM_BASE EBI_SDRAM_BASE + +#define CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_SIZE 65536 +#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_SYS_FLASH_SIZE - CONFIG_ENV_SIZE) + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INTRAM_BASE + CONFIG_SYS_INTRAM_SIZE) + +#define CONFIG_SYS_MALLOC_LEN (256*1024) +#define CONFIG_SYS_DMA_ALLOC_LEN (16384) + +/* Allow 4MB for the kernel run-time image */ +#define CONFIG_SYS_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) +#define CONFIG_SYS_BOOTPARAMS_LEN (16 * 1024) + +/* Other configuration settings that shouldn't have to change all that often */ +#define CONFIG_SYS_PROMPT "U-Boot> " +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_LONGHELP + +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 0x1f00000) + +#define CONFIG_MTD_DEVICE +#define CONFIG_MTD_PARTITIONS + +#endif /* __CONFIG_H */ diff --git a/include/configs/cam_enc_4xx.h b/include/configs/cam_enc_4xx.h index 91ab812..9b56e02 100644 --- a/include/configs/cam_enc_4xx.h +++ b/include/configs/cam_enc_4xx.h @@ -215,10 +215,11 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_LIBGENERIC_SUPPORT #define CONFIG_SPL_NAND_SUPPORT #define CONFIG_SPL_NAND_SIMPLE -#define CONFIG_SPL_NAND_LOAD #define CONFIG_SYS_NAND_HW_ECC_OOBFIRST #define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_POST_MEM_SUPPORT diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h index f8f7a82..f4f9bd1 100644 --- a/include/configs/corenet_ds.h +++ b/include/configs/corenet_ds.h @@ -31,13 +31,21 @@ #ifdef CONFIG_RAMBOOT_PBL #define CONFIG_RAMBOOT_TEXT_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc +#define CONFIG_PBLPBI_CONFIG $(SRCTREE)/board/freescale/corenet_ds/pbi.cfg +#if defined(CONFIG_P3041DS) +#define CONFIG_PBLRCW_CONFIG $(SRCTREE)/board/freescale/corenet_ds/rcw_p3041ds.cfg +#elif defined(CONFIG_P4080DS) +#define CONFIG_PBLRCW_CONFIG $(SRCTREE)/board/freescale/corenet_ds/rcw_p4080ds.cfg +#elif defined(CONFIG_P5020DS) +#define CONFIG_PBLRCW_CONFIG $(SRCTREE)/board/freescale/corenet_ds/rcw_p5020ds.cfg +#endif #endif -#ifdef CONFIG_SRIOBOOT_SLAVE +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE /* Set 1M boot space */ -#define CONFIG_SYS_SRIOBOOT_SLAVE_ADDR (CONFIG_SYS_TEXT_BASE & 0xfff00000) -#define CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS \ - (0x300000000ull | CONFIG_SYS_SRIOBOOT_SLAVE_ADDR) +#define CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR (CONFIG_SYS_TEXT_BASE & 0xfff00000) +#define CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS \ + (0x300000000ull | CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR) #define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc #define CONFIG_SYS_NO_FLASH #endif @@ -77,7 +85,7 @@ #define CONFIG_ENV_OVERWRITE #ifdef CONFIG_SYS_NO_FLASH -#if !defined(CONFIG_SRIOBOOT_SLAVE) && !defined(CONFIG_RAMBOOT_PBL) +#if !defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) && !defined(CONFIG_RAMBOOT_PBL) #define CONFIG_ENV_IS_NOWHERE #endif #else @@ -108,7 +116,7 @@ #define CONFIG_ENV_IS_IN_NAND #define CONFIG_ENV_SIZE CONFIG_SYS_NAND_BLOCK_SIZE #define CONFIG_ENV_OFFSET (5 * CONFIG_SYS_NAND_BLOCK_SIZE) -#elif defined(CONFIG_SRIOBOOT_SLAVE) +#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) #define CONFIG_ENV_IS_IN_REMOTE #define CONFIG_ENV_ADDR 0xffe20000 #define CONFIG_ENV_SIZE 0x2000 @@ -186,11 +194,7 @@ #define CONFIG_DDR_SPD #define CONFIG_FSL_DDR3 -#ifdef CONFIG_P3060QDS -#define CONFIG_SYS_SPD_BUS_NUM 0 -#else #define CONFIG_SYS_SPD_BUS_NUM 1 -#endif #define SPD_EEPROM_ADDRESS1 0x51 #define SPD_EEPROM_ADDRESS2 0x52 #define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1 /* for p3041/p5010 */ @@ -389,51 +393,32 @@ #define CONFIG_SYS_SRIO2_MEM_SIZE 0x10000000 /* 256M */ /* - * SRIOBOOT - MASTER - */ -#ifdef CONFIG_SRIOBOOT_MASTER -/* master port for srioboot*/ -#define CONFIG_SRIOBOOT_MASTER_PORT 0 -/* #define CONFIG_SRIOBOOT_MASTER_PORT 1 */ -/* * for slave u-boot IMAGE instored in master memory space, * PHYS must be aligned based on the SIZE */ -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS1 0xfef080000ull -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS1 0xfff80000ull -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE 0x80000 /* 512K */ -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS2 0xfef080000ull -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS2 0x3fff80000ull +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS 0xfef080000ull +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 0xfff80000ull +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE 0x80000 /* 512K */ +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 0x3fff80000ull /* - * for slave UCODE instored in master memory space, + * for slave UCODE and ENV instored in master memory space, * PHYS must be aligned based on the SIZE */ -#define CONFIG_SRIOBOOT_SLAVE_UCODE_LAW_PHYS 0xfef020000ull -#define CONFIG_SRIOBOOT_SLAVE_UCODE_SRIO_PHYS 0x3ffe00000ull -#define CONFIG_SRIOBOOT_SLAVE_UCODE_SIZE 0x10000 /* 64K */ -/* - * for slave ENV instored in master memory space, - * PHYS must be aligned based on the SIZE - */ -#define CONFIG_SRIOBOOT_SLAVE_ENV_LAW_PHYS 0xfef060000ull -#define CONFIG_SRIOBOOT_SLAVE_ENV_SRIO_PHYS 0x3ffe20000ull -#define CONFIG_SRIOBOOT_SLAVE_ENV_SIZE 0x20000 /* 128K */ +#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS 0xfef040000ull +#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS 0x3ffe00000ull +#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE 0x40000 /* 256K */ + /* slave core release by master*/ -#define CONFIG_SRIOBOOT_SLAVE_HOLDOFF -#define CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET 0xe00e4 -#define CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK 0x00000001 /* release core 0 */ -#endif +#define CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET 0xe00e4 +#define CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK 0x00000001 /* release core 0 */ /* - * SRIOBOOT - SLAVE + * SRIO_PCIE_BOOT - SLAVE */ -#ifdef CONFIG_SRIOBOOT_SLAVE -/* slave port for srioboot */ -#define CONFIG_SRIOBOOT_SLAVE_PORT0 -/* #define CONFIG_SRIOBOOT_SLAVE_PORT1 */ -#define CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR 0xFFE00000 -#define CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS \ - (0x300000000ull | CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR) +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE +#define CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR 0xFFE00000 +#define CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS \ + (0x300000000ull | CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR) #endif /* @@ -556,13 +541,13 @@ #elif defined(CONFIG_NAND) #define CONFIG_SYS_QE_FMAN_FW_IN_NAND #define CONFIG_SYS_QE_FMAN_FW_ADDR (6 * CONFIG_SYS_NAND_BLOCK_SIZE) -#elif defined(CONFIG_SRIOBOOT_SLAVE) +#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) /* * Slave has no ucode locally, it can fetch this from remote. When implementing * in two corenet boards, slave's ucode could be stored in master's memory * space, the address can be mapped from slave TLB->slave LAW-> - * slave SRIO outbound window->master inbound window->master LAW-> - * the ucode address in master's NOR flash. + * slave SRIO or PCIE outbound window->master inbound window-> + * master LAW->the ucode address in master's memory space. */ #define CONFIG_SYS_QE_FMAN_FW_IN_REMOTE #define CONFIG_SYS_QE_FMAN_FW_ADDR 0xFFE00000 @@ -724,7 +709,7 @@ #define CONFIG_BAUDRATE 115200 -#if defined(CONFIG_P4080DS) || defined(CONFIG_P3060QDS) +#ifdef CONFIG_P4080DS #define __USB_PHY_TYPE ulpi #else #define __USB_PHY_TYPE utmi diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h index 09a9660..ddd6155 100644 --- a/include/configs/da850evm.h +++ b/include/configs/da850evm.h @@ -380,6 +380,16 @@ #ifndef CONFIG_DIRECT_NOR_BOOT /* defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_INIT +#define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SYS_TEXT_BASE - \ + CONFIG_SYS_MALLOC_LEN) +#define CONFIG_SYS_SPL_MALLOC_SIZE CONFIG_SYS_MALLOC_LEN +#define CONFIG_SPL_SPI_SUPPORT +#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SPL_SPI_LOAD +#define CONFIG_SPL_SPI_BUS 0 +#define CONFIG_SPL_SPI_CS 0 #define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_LIBCOMMON_SUPPORT #define CONFIG_SPL_LIBGENERIC_SUPPORT @@ -392,10 +402,9 @@ /* Load U-Boot Image From MMC */ #ifdef CONFIG_SPL_MMC_LOAD #define CONFIG_SPL_MMC_SUPPORT -#define CONFIG_SPL_FAT_SUPPORT #define CONFIG_SPL_LIBDISK_SUPPORT -#define CONFIG_SYS_MMC_U_BOOT_OFFS 0x75 -#define CONFIG_SYS_MMC_U_BOOT_SIZE 0x30000 +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x75 +#undef CONFIG_SPL_SPI_SUPPORT #undef CONFIG_SPL_SPI_LOAD #endif diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index de75daf..2d2ee5f 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -303,6 +303,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_LIBCOMMON_SUPPORT diff --git a/include/configs/flea3.h b/include/configs/flea3.h index 16f2d2a..46171b9 100644 --- a/include/configs/flea3.h +++ b/include/configs/flea3.h @@ -212,7 +212,6 @@ * NAND FLASH driver setup */ #define CONFIG_NAND_MXC -#define CONFIG_NAND_MXC_V1_1 #define CONFIG_MXC_NAND_REGS_BASE (NFC_BASE_ADDR) #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE (NFC_BASE_ADDR) diff --git a/include/configs/hawkboard.h b/include/configs/hawkboard.h index 73ab4c8..c0e3ed3 100644 --- a/include/configs/hawkboard.h +++ b/include/configs/hawkboard.h @@ -60,9 +60,10 @@ /* Spl */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_NAND_SUPPORT #define CONFIG_SPL_NAND_SIMPLE -#define CONFIG_SPL_NAND_LOAD #define CONFIG_SPL_LIBGENERIC_SUPPORT /* for udelay and __div64_32 for NAND */ #define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_LDSCRIPT "board/$(BOARDDIR)/u-boot-spl-hawk.lds" @@ -79,6 +80,7 @@ #define CONFIG_MAX_RAM_BANK_SIZE (512 << 20) #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 -\ GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_MONITOR_LEN 0x60000 /* memtest start addr */ #define CONFIG_SYS_MEMTEST_START (PHYS_SDRAM_1) @@ -136,7 +138,6 @@ #define CONFIG_SYS_NAND_PAGE_SIZE (2 << 10) #define CONFIG_SYS_NAND_BLOCK_SIZE (128 << 10) #define CONFIG_SYS_NAND_U_BOOT_OFFS 0xe0000 -#define CONFIG_SYS_NAND_U_BOOT_SIZE 0x60000 #define CONFIG_SYS_NAND_U_BOOT_DST 0xc1180000 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_NAND_U_BOOT_DST #define CONFIG_SYS_NAND_U_BOOT_RELOC_SP (CONFIG_SYS_NAND_U_BOOT_DST - \ diff --git a/include/configs/igep00x0.h b/include/configs/igep00x0.h index 5468a1a..b1071e8 100644 --- a/include/configs/igep00x0.h +++ b/include/configs/igep00x0.h @@ -295,6 +295,7 @@ /* SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_TEXT_BASE 0x40200800 #define CONFIG_SPL_MAX_SIZE (54 * 1024) diff --git a/include/configs/mcx.h b/include/configs/mcx.h index 733022e..359522a 100644 --- a/include/configs/mcx.h +++ b/include/configs/mcx.h @@ -359,6 +359,8 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_NAND_SOFTECC diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 1266cf7..721cd90 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -115,19 +115,11 @@ #endif /* timer */ -#ifdef XILINX_TIMER_BASEADDR -# if (XILINX_TIMER_IRQ != -1) -# define CONFIG_SYS_TIMER_0 1 +#if defined(XILINX_TIMER_BASEADDR) && defined(XILINX_TIMER_IRQ) # define CONFIG_SYS_TIMER_0_ADDR XILINX_TIMER_BASEADDR # define CONFIG_SYS_TIMER_0_IRQ XILINX_TIMER_IRQ -# define FREQUENCE XILINX_CLOCK_FREQ -# define CONFIG_SYS_TIMER_0_PRELOAD ( FREQUENCE/1000 ) -# endif -#elif XILINX_CLOCK_FREQ -# define CONFIG_XILINX_CLOCK_FREQ XILINX_CLOCK_FREQ -#else -# error BAD CLOCK FREQ #endif + /* FSL */ /* #define CONFIG_SYS_FSL_2 */ /* #define FSL_INTR_2 1 */ diff --git a/include/configs/mx35pdk.h b/include/configs/mx35pdk.h index 38b1546..69bd654 100644 --- a/include/configs/mx35pdk.h +++ b/include/configs/mx35pdk.h @@ -236,7 +236,6 @@ * NAND FLASH driver setup */ #define CONFIG_NAND_MXC -#define CONFIG_NAND_MXC_V1_1 #define CONFIG_MXC_NAND_REGS_BASE (NFC_BASE_ADDR) #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE (NFC_BASE_ADDR) diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h index 782a4c5..f79f996 100644 --- a/include/configs/omap3_beagle.h +++ b/include/configs/omap3_beagle.h @@ -391,6 +391,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_TEXT_BASE 0x40200800 #define CONFIG_SPL_MAX_SIZE (54 * 1024) /* 8 KB for stack */ diff --git a/include/configs/omap3_evm_common.h b/include/configs/omap3_evm_common.h index d9578f4..2ef3aaa 100644 --- a/include/configs/omap3_evm_common.h +++ b/include/configs/omap3_evm_common.h @@ -273,6 +273,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_TEXT_BASE 0x40200800 #define CONFIG_SPL_MAX_SIZE (54 * 1024) /* 8 KB for stack */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK diff --git a/include/configs/omap3_overo.h b/include/configs/omap3_overo.h index dd4b2c0..f6d6f75 100644 --- a/include/configs/omap3_overo.h +++ b/include/configs/omap3_overo.h @@ -293,6 +293,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_TEXT_BASE 0x40200800 #define CONFIG_SPL_MAX_SIZE (54 * 1024) /* 8 KB for stack */ diff --git a/include/configs/omap4_common.h b/include/configs/omap4_common.h index ee0c4b9..cbc9bdb 100644 --- a/include/configs/omap4_common.h +++ b/include/configs/omap4_common.h @@ -232,9 +232,11 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_TEXT_BASE 0x40304350 #define CONFIG_SPL_MAX_SIZE (38 * 1024) #define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR +#define CONFIG_SPL_DISPLAY_PRINT /* * 64 bytes before this address should be set aside for u-boot.img's diff --git a/include/configs/omap5_evm.h b/include/configs/omap5_evm.h index 4f0a6c1..743edfd 100644 --- a/include/configs/omap5_evm.h +++ b/include/configs/omap5_evm.h @@ -229,9 +229,11 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_TEXT_BASE 0x40300350 #define CONFIG_SPL_MAX_SIZE 0x19000 /* 100K */ #define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR +#define CONFIG_SPL_DISPLAY_PRINT #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 /* address 0x60000 */ #define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x200 /* 256 KB */ diff --git a/include/configs/p1_p2_rdb_pc.h b/include/configs/p1_p2_rdb_pc.h index a8882d4..b18f4a0 100644 --- a/include/configs/p1_p2_rdb_pc.h +++ b/include/configs/p1_p2_rdb_pc.h @@ -31,7 +31,7 @@ #endif #if defined(CONFIG_P1020MBG) -#define CONFIG_BOARDNAME "P1020MBG" +#define CONFIG_BOARDNAME "P1020MBG-PC" #define CONFIG_P1020 #define CONFIG_VSC7385_ENET #define CONFIG_SLIC @@ -41,7 +41,7 @@ #endif #if defined(CONFIG_P1020UTM) -#define CONFIG_BOARDNAME "P1020UTM" +#define CONFIG_BOARDNAME "P1020UTM-PC" #define CONFIG_P1020 #define __SW_BOOT_MASK 0x03 #define __SW_BOOT_NOR 0xe0 @@ -49,7 +49,7 @@ #endif #if defined(CONFIG_P1020RDB) -#define CONFIG_BOARDNAME "P1020RDB" +#define CONFIG_BOARDNAME "P1020RDB-PC" #define CONFIG_NAND_FSL_ELBC #define CONFIG_P1020 #define CONFIG_SPI_FLASH @@ -64,7 +64,7 @@ #endif #if defined(CONFIG_P1021RDB) -#define CONFIG_BOARDNAME "P1021RDB" +#define CONFIG_BOARDNAME "P1021RDB-PC" #define CONFIG_NAND_FSL_ELBC #define CONFIG_P1021 #define CONFIG_QE @@ -111,7 +111,7 @@ #endif #if defined(CONFIG_P2020RDB) -#define CONFIG_BOARDNAME "P2020RDB" +#define CONFIG_BOARDNAME "P2020RDB-PCA" #define CONFIG_NAND_FSL_ELBC #define CONFIG_P2020 #define CONFIG_SPI_FLASH diff --git a/include/configs/qemu-mips.h b/include/configs/qemu-mips.h index 306c173..b8b9705 100644 --- a/include/configs/qemu-mips.h +++ b/include/configs/qemu-mips.h @@ -100,7 +100,12 @@ */ #define CONFIG_SYS_LONGHELP /* undef to save memory */ -#define CONFIG_SYS_PROMPT "qemu-mips # " /* Monitor Command Prompt */ +/* Monitor Command Prompt */ +#if defined(CONFIG_SYS_LITTLE_ENDIAN) +#define CONFIG_SYS_PROMPT "qemu-mipsel # " +#else +#define CONFIG_SYS_PROMPT "qemu-mips # " +#endif #define CONFIG_AUTO_COMPLETE #define CONFIG_CMDLINE_EDITING diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h index a3fc465..4bb5bbc 100644 --- a/include/configs/qi_lb60.h +++ b/include/configs/qi_lb60.h @@ -11,6 +11,7 @@ #define __CONFIG_QI_LB60_H #define CONFIG_MIPS32 /* MIPS32 CPU core */ +#define CONFIG_SYS_LITTLE_ENDIAN #define CONFIG_JZSOC /* Jz SoC */ #define CONFIG_JZ4740 /* Jz4740 SoC */ #define CONFIG_NAND_JZ4740 diff --git a/include/configs/tam3517-common.h b/include/configs/tam3517-common.h index a13fd93..cbb6c7e 100644 --- a/include/configs/tam3517-common.h +++ b/include/configs/tam3517-common.h @@ -239,6 +239,8 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_CONSOLE #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_NAND_SOFTECC diff --git a/include/configs/trats.h b/include/configs/trats.h index 8a0deea..b3b5a3d 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -78,6 +78,7 @@ #define CONFIG_MMC #define CONFIG_S5P_SDHCI #define CONFIG_SDHCI +#define CONFIG_MMC_SDMA /* PWM */ #define CONFIG_PWM @@ -97,6 +98,21 @@ #undef CONFIG_CMD_ONENAND #undef CONFIG_CMD_MTDPARTS #define CONFIG_CMD_MMC +#define CONFIG_CMD_DFU + +/* FAT */ +#define CONFIG_CMD_FAT +#define CONFIG_FAT_WRITE + +/* USB Composite download gadget - g_dnl */ +#define CONFIG_USBDOWNLOAD_GADGET +#define CONFIG_DFU_FUNCTION +#define CONFIG_DFU_MMC + +/* USB Samsung's IDs */ +#define CONFIG_G_DNL_VENDOR_NUM 0x04E8 +#define CONFIG_G_DNL_PRODUCT_NUM 0x6601 +#define CONFIG_G_DNL_MANUFACTURER "Samsung" #define CONFIG_BOOTDELAY 1 #define CONFIG_ZERO_BOOTDELAY_CHECK @@ -107,6 +123,11 @@ #define CONFIG_BOOTBLOCK "10" #define CONFIG_ENV_COMMON_BOOT "${console} ${meminfo}" +#define CONFIG_DFU_ALT \ + "dfu_alt_info=" \ + "u-boot mmc 80 400;" \ + "uImage fat 0 2\0" \ + #define CONFIG_ENV_OVERWRITE #define CONFIG_SYS_CONSOLE_INFO_QUIET #define CONFIG_SYS_CONSOLE_IS_IN_ENV @@ -150,7 +171,8 @@ "mmcdev=0\0" \ "mmcbootpart=2\0" \ "mmcrootpart=3\0" \ - "opts=always_resume=1" + "opts=always_resume=1\0" \ + CONFIG_DFU_ALT /* Miscellaneous configurable options */ #define CONFIG_SYS_LONGHELP /* undef to save memory */ @@ -190,18 +212,28 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - GENERATED_GBL_DATA_SIZE) #define CONFIG_SYS_CACHELINE_SIZE 32 -#include <asm/arch/gpio.h> -/* - * I2C Settings - */ -#define CONFIG_SOFT_I2C_GPIO_SCL exynos4_gpio_part1_get_nr(b, 7) -#define CONFIG_SOFT_I2C_GPIO_SDA exynos4_gpio_part1_get_nr(b, 6) #define CONFIG_SOFT_I2C #define CONFIG_SOFT_I2C_READ_REPEATED_START +#define CONFIG_SYS_I2C_INIT_BOARD #define CONFIG_SYS_I2C_SPEED 50000 #define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS 7 +#define CONFIG_SOFT_I2C_MULTI_BUS +#define CONFIG_SYS_MAX_I2C_BUS 15 + +#include <asm/arch/gpio.h> + +/* I2C PMIC */ +#define CONFIG_SOFT_I2C_I2C5_SCL exynos4_gpio_part1_get_nr(b, 7) +#define CONFIG_SOFT_I2C_I2C5_SDA exynos4_gpio_part1_get_nr(b, 6) + +/* I2C FG */ +#define CONFIG_SOFT_I2C_I2C9_SCL exynos4_gpio_part2_get_nr(y4, 1) +#define CONFIG_SOFT_I2C_I2C9_SDA exynos4_gpio_part2_get_nr(y4, 0) + +#define CONFIG_SOFT_I2C_GPIO_SCL get_multi_scl_pin() +#define CONFIG_SOFT_I2C_GPIO_SDA get_multi_sda_pin() +#define I2C_INIT multi_i2c_init() #define CONFIG_PMIC #define CONFIG_PMIC_I2C @@ -210,6 +242,7 @@ #define CONFIG_USB_GADGET #define CONFIG_USB_GADGET_S3C_UDC_OTG #define CONFIG_USB_GADGET_DUALSPEED +#define CONFIG_USB_GADGET_VBUS_DRAW 2 /* LCD */ #define CONFIG_EXYNOS_FB diff --git a/include/configs/tricorder.h b/include/configs/tricorder.h index 63c98dc..00d02e8 100644 --- a/include/configs/tricorder.h +++ b/include/configs/tricorder.h @@ -271,6 +271,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_BOARD_INIT diff --git a/include/configs/tx25.h b/include/configs/tx25.h index c8a49bb..71b1d32 100644 --- a/include/configs/tx25.h +++ b/include/configs/tx25.h @@ -107,7 +107,6 @@ /* NAND */ #define CONFIG_NAND_MXC -#define CONFIG_NAND_MXC_V1_1 #define CONFIG_MXC_NAND_REGS_BASE (0xBB000000) #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE (0xBB000000) diff --git a/include/ddr_spd.h b/include/ddr_spd.h index a9230b9..9e74d87 100644 --- a/include/ddr_spd.h +++ b/include/ddr_spd.h @@ -221,7 +221,12 @@ typedef struct ddr3_spd_eeprom_s { unsigned char therm_ref_opt; /* 31 SDRAM Thermal and Refresh Opts */ unsigned char therm_sensor; /* 32 Module Thermal Sensor */ unsigned char device_type; /* 33 SDRAM device type */ - unsigned char res_34_59[26]; /* 34-59 Reserved, General Section */ + int8_t fine_tCK_min; /* 34 Fine offset for tCKmin */ + int8_t fine_tAA_min; /* 35 Fine offset for tAAmin */ + int8_t fine_tRCD_min; /* 36 Fine offset for tRCDmin */ + int8_t fine_tRP_min; /* 37 Fine offset for tRPmin */ + int8_t fine_tRC_min; /* 38 Fine offset for tRCmin */ + unsigned char res_39_59[21]; /* 39-59 Reserved, General Section */ /* Module-Specific Section: Bytes 60-116 */ union { diff --git a/include/dfu.h b/include/dfu.h new file mode 100644 index 0000000..5350d79 --- /dev/null +++ b/include/dfu.h @@ -0,0 +1,103 @@ +/* + * dfu.h - DFU flashable area description + * + * Copyright (C) 2012 Samsung Electronics + * authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com> + * Lukasz Majewski <l.majewski@samsung.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __DFU_ENTITY_H_ +#define __DFU_ENTITY_H_ + +#include <common.h> +#include <linux/list.h> +#include <mmc.h> + +enum dfu_device_type { + DFU_DEV_MMC = 1, + DFU_DEV_ONENAND, + DFU_DEV_NAND, +}; + +enum dfu_layout { + DFU_RAW_ADDR = 1, + DFU_FS_FAT, + DFU_FS_EXT2, + DFU_FS_EXT3, + DFU_FS_EXT4, +}; + +struct mmc_internal_data { + /* RAW programming */ + unsigned int lba_start; + unsigned int lba_size; + unsigned int lba_blk_size; + + /* FAT/EXT */ + unsigned int dev; + unsigned int part; +}; + +static inline unsigned int get_mmc_blk_size(int dev) +{ + return find_mmc_device(dev)->read_bl_len; +} + +#define DFU_NAME_SIZE 32 +#define DFU_CMD_BUF_SIZE 128 +#define DFU_DATA_BUF_SIZE (1024*1024*4) /* 4 MiB */ + +struct dfu_entity { + char name[DFU_NAME_SIZE]; + int alt; + void *dev_private; + int dev_num; + enum dfu_device_type dev_type; + enum dfu_layout layout; + + union { + struct mmc_internal_data mmc; + } data; + + int (*read_medium)(struct dfu_entity *dfu, void *buf, long *len); + int (*write_medium)(struct dfu_entity *dfu, void *buf, long *len); + + struct list_head list; +}; + +int dfu_config_entities(char *s, char *interface, int num); +void dfu_free_entities(void); +void dfu_show_entities(void); +int dfu_get_alt_number(void); +const char *dfu_get_dev_type(enum dfu_device_type t); +const char *dfu_get_layout(enum dfu_layout l); +struct dfu_entity *dfu_get_entity(int alt); +char *dfu_extract_token(char** e, int *n); + +int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num); +int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num); +/* Device specific */ +#ifdef CONFIG_DFU_MMC +extern int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s); +#else +static inline int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s) +{ + puts("MMC support not available!\n"); + return -1; +} +#endif +#endif /* __DFU_ENTITY_H_ */ diff --git a/include/environment.h b/include/environment.h index ae3f7b6..e8ab703 100644 --- a/include/environment.h +++ b/include/environment.h @@ -181,9 +181,21 @@ void env_crc_update(void); /* [re]set to the default environment */ void set_default_env(const char *s); +/* [re]set individual variables to their value in the default environment */ +int set_default_vars(int nvars, char * const vars[]); + /* Import from binary representation into hash table */ int env_import(const char *buf, int check); +/* + * Check if variable "name" can be changed from oldval to newval, + * and if so, apply the changes (e.g. baudrate). + * When (flag & H_FORCE) is set, it does not print out any error + * message and forces overwriting of write-once variables. + */ +int env_check_apply(const char *name, const char *oldval, + const char *newval, int flag); + #endif /* DO_DEPS_ONLY */ #endif /* _ENVIRONMENT_H_ */ diff --git a/include/ext2fs.h b/include/ext2fs.h deleted file mode 100644 index 163a9bb..0000000 --- a/include/ext2fs.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. - * - * (C) Copyright 2003 Sysgo Real-Time Solutions, AG <www.elinos.com> - * Pavel Bartusek <pba@sysgo.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. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* An implementation for the Ext2FS filesystem ported from GRUB. - * Some parts of this code (mainly the structures and defines) are - * from the original ext2 fs code, as found in the linux kernel. - */ - - -#define SECTOR_SIZE 0x200 -#define SECTOR_BITS 9 - -/* Error codes */ -typedef enum -{ - ERR_NONE = 0, - ERR_BAD_FILENAME, - ERR_BAD_FILETYPE, - ERR_BAD_GZIP_DATA, - ERR_BAD_GZIP_HEADER, - ERR_BAD_PART_TABLE, - ERR_BAD_VERSION, - ERR_BELOW_1MB, - ERR_BOOT_COMMAND, - ERR_BOOT_FAILURE, - ERR_BOOT_FEATURES, - ERR_DEV_FORMAT, - ERR_DEV_VALUES, - ERR_EXEC_FORMAT, - ERR_FILELENGTH, - ERR_FILE_NOT_FOUND, - ERR_FSYS_CORRUPT, - ERR_FSYS_MOUNT, - ERR_GEOM, - ERR_NEED_LX_KERNEL, - ERR_NEED_MB_KERNEL, - ERR_NO_DISK, - ERR_NO_PART, - ERR_NUMBER_PARSING, - ERR_OUTSIDE_PART, - ERR_READ, - ERR_SYMLINK_LOOP, - ERR_UNRECOGNIZED, - ERR_WONT_FIT, - ERR_WRITE, - ERR_BAD_ARGUMENT, - ERR_UNALIGNED, - ERR_PRIVILEGED, - ERR_DEV_NEED_INIT, - ERR_NO_DISK_SPACE, - ERR_NUMBER_OVERFLOW, - - MAX_ERR_NUM -} ext2fs_error_t; - - -extern int ext2fs_set_blk_dev(block_dev_desc_t *rbdd, int part); -extern int ext2fs_ls (const char *dirname); -extern int ext2fs_open (const char *filename); -extern int ext2fs_read (char *buf, unsigned len); -extern int ext2fs_mount (unsigned part_length); -extern int ext2fs_close(void); diff --git a/include/ext4fs.h b/include/ext4fs.h new file mode 100644 index 0000000..b6eedde --- /dev/null +++ b/include/ext4fs.h @@ -0,0 +1,141 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar <uma.shankar@samsung.com> + * Manjunatha C Achar <a.manjunatha@samsung.com> + * + * Ext4 Extent data structures are taken from original ext4 fs code + * as found in the linux kernel. + * + * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas <alex@clusterfs.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. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __EXT4__ +#define __EXT4__ +#include <ext_common.h> + +#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ +#define EXT4_EXT_MAGIC 0xf30a +#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 +#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 +#define EXT4_INDIRECT_BLOCKS 12 + +#define EXT4_BG_INODE_UNINIT 0x0001 +#define EXT4_BG_BLOCK_UNINIT 0x0002 +#define EXT4_BG_INODE_ZEROED 0x0004 + +/* + * ext4_inode has i_block array (60 bytes total). + * The first 12 bytes store ext4_extent_header; + * the remainder stores an array of ext4_extent. + */ + +/* + * This is the extent on-disk structure. + * It's used at the bottom of the tree. + */ +struct ext4_extent { + __le32 ee_block; /* first logical block extent covers */ + __le16 ee_len; /* number of blocks covered by extent */ + __le16 ee_start_hi; /* high 16 bits of physical block */ + __le32 ee_start_lo; /* low 32 bits of physical block */ +}; + +/* + * This is index on-disk structure. + * It's used at all the levels except the bottom. + */ +struct ext4_extent_idx { + __le32 ei_block; /* index covers logical blocks from 'block' */ + __le32 ei_leaf_lo; /* pointer to the physical block of the next * + * level. leaf or next index could be there */ + __le16 ei_leaf_hi; /* high 16 bits of physical block */ + __u16 ei_unused; +}; + +/* Each block (leaves and indexes), even inode-stored has header. */ +struct ext4_extent_header { + __le16 eh_magic; /* probably will support different formats */ + __le16 eh_entries; /* number of valid entries */ + __le16 eh_max; /* capacity of store in entries */ + __le16 eh_depth; /* has tree real underlying blocks? */ + __le32 eh_generation; /* generation of the tree */ +}; + +struct ext_filesystem { + /* Total Sector of partition */ + uint64_t total_sect; + /* Block size of partition */ + uint32_t blksz; + /* Inode size of partition */ + uint32_t inodesz; + /* Sectors per Block */ + uint32_t sect_perblk; + /* Group Descriptor Block Number */ + uint32_t gdtable_blkno; + /* Total block groups of partition */ + uint32_t no_blkgrp; + /* No of blocks required for bgdtable */ + uint32_t no_blk_pergdt; + /* Superblock */ + struct ext2_sblock *sb; + /* Block group descritpor table */ + struct ext2_block_group *gd; + char *gdtable; + + /* Block Bitmap Related */ + unsigned char **blk_bmaps; + long int curr_blkno; + uint16_t first_pass_bbmap; + + /* Inode Bitmap Related */ + unsigned char **inode_bmaps; + int curr_inode_no; + uint16_t first_pass_ibmap; + + /* Journal Related */ + + /* Block Device Descriptor */ + block_dev_desc_t *dev_desc; +}; + +extern struct ext2_data *ext4fs_root; +extern struct ext2fs_node *ext4fs_file; + +#if defined(CONFIG_CMD_EXT4_WRITE) +extern struct ext2_inode *g_parent_inode; +extern int gd_index; +extern int gindex; + +int ext4fs_init(void); +void ext4fs_deinit(void); +int ext4fs_filename_check(char *filename); +int ext4fs_write(const char *fname, unsigned char *buffer, + unsigned long sizebytes); +#endif + +struct ext_filesystem *get_fs(void); +int ext4fs_open(const char *filename); +int ext4fs_read(char *buf, unsigned len); +int ext4fs_mount(unsigned part_length); +void ext4fs_close(void); +int ext4fs_ls(const char *dirname); +void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot); +int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf); +void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info); +long int read_allocated_block(struct ext2_inode *inode, int fileblock); +#endif diff --git a/include/ext_common.h b/include/ext_common.h new file mode 100644 index 0000000..ce73857 --- /dev/null +++ b/include/ext_common.h @@ -0,0 +1,201 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar <uma.shankar@samsung.com> + * Manjunatha C Achar <a.manjunatha@samsung.com> + * + * Data structures and headers for ext4 support have been taken from + * ext2 ls load support in Uboot + * + * (C) Copyright 2004 + * esd gmbh <www.esd-electronics.com> + * Reinhard Arlt <reinhard.arlt@esd-electronics.com> + * + * based on code from grub2 fs/ext2.c and fs/fshelp.c by + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __EXT_COMMON__ +#define __EXT_COMMON__ +#include <command.h> +#define SECTOR_SIZE 0x200 +#define SECTOR_BITS 9 + +/* Magic value used to identify an ext2 filesystem. */ +#define EXT2_MAGIC 0xEF53 +/* Amount of indirect blocks in an inode. */ +#define INDIRECT_BLOCKS 12 +/* Maximum lenght of a pathname. */ +#define EXT2_PATH_MAX 4096 +/* Maximum nesting of symlinks, used to prevent a loop. */ +#define EXT2_MAX_SYMLINKCNT 8 + +/* Filetype used in directory entry. */ +#define FILETYPE_UNKNOWN 0 +#define FILETYPE_REG 1 +#define FILETYPE_DIRECTORY 2 +#define FILETYPE_SYMLINK 7 + +/* Filetype information as used in inodes. */ +#define FILETYPE_INO_MASK 0170000 +#define FILETYPE_INO_REG 0100000 +#define FILETYPE_INO_DIRECTORY 0040000 +#define FILETYPE_INO_SYMLINK 0120000 +#define EXT2_ROOT_INO 2 /* Root inode */ + +/* Bits used as offset in sector */ +#define DISK_SECTOR_BITS 9 +/* The size of an ext2 block in bytes. */ +#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data)) + +/* Log2 size of ext2 block in 512 blocks. */ +#define LOG2_EXT2_BLOCK_SIZE(data) (__le32_to_cpu \ + (data->sblock.log2_block_size) + 1) + +/* Log2 size of ext2 block in bytes. */ +#define LOG2_BLOCK_SIZE(data) (__le32_to_cpu \ + (data->sblock.log2_block_size) + 10) +#define INODE_SIZE_FILESYSTEM(data) (__le32_to_cpu \ + (data->sblock.inode_size)) + +#define EXT2_FT_DIR 2 +#define SUCCESS 1 + +/* Macro-instructions used to manage several block sizes */ +#define EXT2_MIN_BLOCK_LOG_SIZE 10 /* 1024 */ +#define EXT2_MAX_BLOCK_LOG_SIZE 16 /* 65536 */ +#define EXT2_MIN_BLOCK_SIZE (1 << EXT2_MIN_BLOCK_LOG_SIZE) +#define EXT2_MAX_BLOCK_SIZE (1 << EXT2_MAX_BLOCK_LOG_SIZE) + +/* The ext2 superblock. */ +struct ext2_sblock { + uint32_t total_inodes; + uint32_t total_blocks; + uint32_t reserved_blocks; + uint32_t free_blocks; + uint32_t free_inodes; + uint32_t first_data_block; + uint32_t log2_block_size; + uint32_t log2_fragment_size; + uint32_t blocks_per_group; + uint32_t fragments_per_group; + uint32_t inodes_per_group; + uint32_t mtime; + uint32_t utime; + uint16_t mnt_count; + uint16_t max_mnt_count; + uint16_t magic; + uint16_t fs_state; + uint16_t error_handling; + uint16_t minor_revision_level; + uint32_t lastcheck; + uint32_t checkinterval; + uint32_t creator_os; + uint32_t revision_level; + uint16_t uid_reserved; + uint16_t gid_reserved; + uint32_t first_inode; + uint16_t inode_size; + uint16_t block_group_number; + uint32_t feature_compatibility; + uint32_t feature_incompat; + uint32_t feature_ro_compat; + uint32_t unique_id[4]; + char volume_name[16]; + char last_mounted_on[64]; + uint32_t compression_info; +}; + +struct ext2_block_group { + __u32 block_id; /* Blocks bitmap block */ + __u32 inode_id; /* Inodes bitmap block */ + __u32 inode_table_id; /* Inodes table block */ + __u16 free_blocks; /* Free blocks count */ + __u16 free_inodes; /* Free inodes count */ + __u16 used_dir_cnt; /* Directories count */ + __u16 bg_flags; + __u32 bg_reserved[2]; + __u16 bg_itable_unused; /* Unused inodes count */ + __u16 bg_checksum; /* crc16(s_uuid+grouo_num+group_desc)*/ +}; + +/* The ext2 inode. */ +struct ext2_inode { + uint16_t mode; + uint16_t uid; + uint32_t size; + uint32_t atime; + uint32_t ctime; + uint32_t mtime; + uint32_t dtime; + uint16_t gid; + uint16_t nlinks; + uint32_t blockcnt; /* Blocks of 512 bytes!! */ + uint32_t flags; + uint32_t osd1; + union { + struct datablocks { + uint32_t dir_blocks[INDIRECT_BLOCKS]; + uint32_t indir_block; + uint32_t double_indir_block; + uint32_t triple_indir_block; + } blocks; + char symlink[60]; + } b; + uint32_t version; + uint32_t acl; + uint32_t dir_acl; + uint32_t fragment_addr; + uint32_t osd2[3]; +}; + +/* The header of an ext2 directory entry. */ +struct ext2_dirent { + uint32_t inode; + uint16_t direntlen; + uint8_t namelen; + uint8_t filetype; +}; + +struct ext2fs_node { + struct ext2_data *data; + struct ext2_inode inode; + int ino; + int inode_read; +}; + +/* Information about a "mounted" ext2 filesystem. */ +struct ext2_data { + struct ext2_sblock sblock; + struct ext2_inode *inode; + struct ext2fs_node diropen; +}; + +extern unsigned long part_offset; + +int do_ext2ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +int do_ext2load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]); +int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); +int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]); +int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]); +int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); +#endif diff --git a/include/fat.h b/include/fat.h index f1b4a0d..cc85b06 100644 --- a/include/fat.h +++ b/include/fat.h @@ -208,6 +208,8 @@ file_read_func file_fat_read; int file_cd(const char *path); int file_fat_detectfs(void); int file_fat_ls(const char *dir); +long file_fat_read_at(const char *filename, unsigned long pos, void *buffer, + unsigned long maxsize); long file_fat_read(const char *filename, void *buffer, unsigned long maxsize); const char *file_getfsname(int idx); int fat_register_device(block_dev_desc_t *dev_desc, int part_no); diff --git a/include/fdtdec.h b/include/fdtdec.h index 474a4b9..0b14075 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -19,6 +19,8 @@ * MA 02111-1307 USA */ +#ifndef __fdtdec_h +#define __fdtdec_h /* * This file contains convenience functions for decoding useful and @@ -383,3 +385,4 @@ int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name, */ const u8 *fdtdec_locate_byte_array(const void *blob, int node, const char *prop_name, int count); +#endif diff --git a/include/flash.h b/include/flash.h index e614d07..6d70bdd 100644 --- a/include/flash.h +++ b/include/flash.h @@ -141,6 +141,7 @@ extern flash_info_t *flash_get_info(ulong base); #define ERR_UNKNOWN_FLASH_VENDOR 32 #define ERR_UNKNOWN_FLASH_TYPE 64 #define ERR_PROG_ERROR 128 +#define ERR_ABORTED 256 /*----------------------------------------------------------------------- * Protection Flags for flash_protect(): diff --git a/include/fm_eth.h b/include/fm_eth.h index c7c6882..e56541d 100644 --- a/include/fm_eth.h +++ b/include/fm_eth.h @@ -35,6 +35,7 @@ enum fm_port { FM2_DTSEC2, FM2_DTSEC3, FM2_DTSEC4, + FM2_DTSEC5, FM2_10GEC1, NUM_FM_PORTS, }; @@ -109,6 +110,7 @@ void fman_enet_init(void); void fdt_fixup_fman_ethernet(void *fdt); phy_interface_t fm_info_get_enet_if(enum fm_port port); void fm_info_set_phy_address(enum fm_port port, int address); +int fm_info_get_phy_address(enum fm_port port); void fm_info_set_mdio(enum fm_port port, struct mii_dev *bus); void fm_disable_port(enum fm_port port); diff --git a/include/fsl_nfc.h b/include/fsl_nfc.h index 279aaa5..ff537b4 100644 --- a/include/fsl_nfc.h +++ b/include/fsl_nfc.h @@ -24,49 +24,48 @@ #define __FSL_NFC_H /* - * TODO: Use same register defs for nand_spl mxc nand driver - * and mtd mxc nand driver. + * Register map and bit definitions for the Freescale NAND Flash Controller + * present in various i.MX devices. * - * Register map and bit definitions for the Freescale NAND Flash - * Controller present in various i.MX devices. + * MX31 and MX27 have version 1, which has: + * 4 512-byte main buffers and + * 4 16-byte spare buffers + * to support up to 2K byte pagesize nand. + * Reading or writing a 2K page requires 4 FDI/FDO cycles. * - * MX31 and MX27 have version 1 which has - * 4 512 byte main buffers and - * 4 16 byte spare buffers - * to support up to 2K byte pagesize nand. - * Reading or writing a 2K page requires 4 FDI/FDO cycles. - * - * MX25 has version 1.1 which has - * 8 512 byte main buffers and - * 8 64 byte spare buffers - * to support up to 4K byte pagesize nand. - * Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle. - * Also some of registers are moved and/or changed meaning as seen below. + * MX25 and MX35 have version 2.1, which has: + * 8 512-byte main buffers and + * 8 64-byte spare buffers + * to support up to 4K byte pagesize nand. + * Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle. + * Also some of registers are moved and/or changed meaning as seen below. */ -#if defined(CONFIG_MX31) || defined(CONFIG_MX27) +#if defined(CONFIG_MX27) || defined(CONFIG_MX31) #define MXC_NFC_V1 -#elif defined(CONFIG_MX25) -#define MXC_NFC_V1_1 +#define is_mxc_nfc_1() 1 +#define is_mxc_nfc_21() 0 +#elif defined(CONFIG_MX25) || defined(CONFIG_MX35) +#define MXC_NFC_V2_1 +#define is_mxc_nfc_1() 0 +#define is_mxc_nfc_21() 1 #else -#warning "MXC NFC version not defined" +#error "MXC NFC implementation not supported" #endif #if defined(MXC_NFC_V1) #define NAND_MXC_NR_BUFS 4 #define NAND_MXC_SPARE_BUF_SIZE 16 #define NAND_MXC_REG_OFFSET 0xe00 -#define NAND_MXC_2K_MULTI_CYCLE 1 -#elif defined(MXC_NFC_V1_1) +#define NAND_MXC_2K_MULTI_CYCLE +#elif defined(MXC_NFC_V2_1) #define NAND_MXC_NR_BUFS 8 #define NAND_MXC_SPARE_BUF_SIZE 64 #define NAND_MXC_REG_OFFSET 0x1e00 -#else -#error "define CONFIG_NAND_MXC_VXXX to use the mxc spl_nand driver" #endif struct fsl_nfc_regs { - u32 main_area[NAND_MXC_NR_BUFS][512/4]; - u32 spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE/4]; + u8 main_area[NAND_MXC_NR_BUFS][0x200]; + u8 spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE]; /* * reserved size is offset of nfc registers * minus total main and spare sizes @@ -74,44 +73,43 @@ struct fsl_nfc_regs { u8 reserved1[NAND_MXC_REG_OFFSET - NAND_MXC_NR_BUFS * (512 + NAND_MXC_SPARE_BUF_SIZE)]; #if defined(MXC_NFC_V1) - u16 bufsiz; + u16 buf_size; u16 reserved2; - u16 buffer_address; - u16 flash_add; + u16 buf_addr; + u16 flash_addr; u16 flash_cmd; - u16 configuration; + u16 config; u16 ecc_status_result; - u16 ecc_rslt_main_area; - u16 ecc_rslt_spare_area; - u16 nf_wr_prot; - u16 unlock_start_blk_add; - u16 unlock_end_blk_add; - u16 nand_flash_wr_pr_st; - u16 nand_flash_config1; - u16 nand_flash_config2; -#elif defined(MXC_NFC_V1_1) + u16 rsltmain_area; + u16 rsltspare_area; + u16 wrprot; + u16 unlockstart_blkaddr; + u16 unlockend_blkaddr; + u16 nf_wrprst; + u16 config1; + u16 config2; +#elif defined(MXC_NFC_V2_1) u16 reserved2[2]; - u16 buffer_address; - u16 flash_add; + u16 buf_addr; + u16 flash_addr; u16 flash_cmd; - u16 configuration; - u16 ecc_status_result; - u16 ecc_status_result2; + u16 config; + u32 ecc_status_result; u16 spare_area_size; - u16 nf_wr_prot; + u16 wrprot; u16 reserved3[2]; - u16 nand_flash_wr_pr_st; - u16 nand_flash_config1; - u16 nand_flash_config2; + u16 nf_wrprst; + u16 config1; + u16 config2; u16 reserved4; - u16 unlock_start_blk_add0; - u16 unlock_end_blk_add0; - u16 unlock_start_blk_add1; - u16 unlock_end_blk_add1; - u16 unlock_start_blk_add2; - u16 unlock_end_blk_add2; - u16 unlock_start_blk_add3; - u16 unlock_end_blk_add3; + u16 unlockstart_blkaddr; + u16 unlockend_blkaddr; + u16 unlockstart_blkaddr1; + u16 unlockend_blkaddr1; + u16 unlockstart_blkaddr2; + u16 unlockend_blkaddr2; + u16 unlockstart_blkaddr3; + u16 unlockend_blkaddr3; #endif }; @@ -157,7 +155,7 @@ struct fsl_nfc_regs { */ #define NFC_INT 0x8000 -#ifdef MXC_NFC_V1_1 +#ifdef MXC_NFC_V2_1 #define NFC_4_8N_ECC (1 << 0) #endif #define NFC_SP_EN (1 << 2) @@ -167,5 +165,6 @@ struct fsl_nfc_regs { #define NFC_RST (1 << 6) #define NFC_CE (1 << 7) #define NFC_ONE_CYCLE (1 << 8) +#define NFC_FP_INT (1 << 11) #endif /* __FSL_NFC_H */ diff --git a/include/g_dnl.h b/include/g_dnl.h new file mode 100644 index 0000000..0ec7440 --- /dev/null +++ b/include/g_dnl.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Lukasz Majewski <l.majewski@samsung.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __G_DOWNLOAD_H_ +#define __G_DOWNLOAD_H_ + +#include <linux/usb/ch9.h> +#include <usbdescriptors.h> +#include <linux/usb/gadget.h> + +int g_dnl_register(const char *s); +void g_dnl_unregister(void); + +/* USB initialization declaration - board specific */ +void board_usb_init(void); +#endif /* __G_DOWNLOAD_H_ */ diff --git a/include/i2c.h b/include/i2c.h index 1f35acf..16f099d 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -250,4 +250,16 @@ static inline void I2C_SET_BUS(unsigned int bus) i2c_set_bus_num(bus); } +/* Multi I2C definitions */ +enum { + I2C_0, I2C_1, I2C_2, I2C_3, I2C_4, I2C_5, I2C_6, I2C_7, + I2C_8, I2C_9, I2C_10, +}; + +/* Multi I2C busses handling */ +#ifdef CONFIG_SOFT_I2C_MULTI_BUS +extern int get_multi_scl_pin(void); +extern int get_multi_sda_pin(void); +extern int multi_i2c_init(void); +#endif #endif /* _I2C_H_ */ diff --git a/include/image.h b/include/image.h index aa9daa2..e5f6649 100644 --- a/include/image.h +++ b/include/image.h @@ -164,6 +164,7 @@ #define IH_TYPE_OMAPIMAGE 12 /* TI OMAP Config Header Image */ #define IH_TYPE_AISIMAGE 13 /* TI Davinci AIS Image */ #define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image, can run from any load address */ +#define IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */ /* * Compression Types diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index dc839e7..f63e04b 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -85,8 +85,10 @@ extern void nand_wait_ready(struct mtd_info *mtd); #define NAND_CMD_RESET 0xff #define NAND_CMD_LOCK 0x2a +#define NAND_CMD_LOCK_TIGHT 0x2c #define NAND_CMD_UNLOCK1 0x23 #define NAND_CMD_UNLOCK2 0x24 +#define NAND_CMD_LOCK_STATUS 0x7a /* Extended commands for large page devices */ #define NAND_CMD_READSTART 0x30 @@ -205,9 +207,6 @@ typedef enum { #define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT) \ && (chip->page_shift > 9)) -/* Mask to zero out the chip options, which come from the id table */ -#define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR) - /* Non chip related options */ /* * Use a flash based bad block table. OOB identifier is saved in OOB area. diff --git a/include/malloc.h b/include/malloc.h index 6295929..84ecf79 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -937,6 +937,7 @@ extern ulong mem_malloc_end; extern ulong mem_malloc_brk; void mem_malloc_init(ulong start, ulong size); +void malloc_bin_reloc(void); #ifdef __cplusplus }; /* end of extern "C" */ diff --git a/include/mmc.h b/include/mmc.h index b63b2c3..a13e2bd 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -215,7 +215,6 @@ struct mmc_cmd { uint resp_type; uint cmdarg; uint response[4]; - uint flags; }; struct mmc_data { diff --git a/include/mv88e6352.h b/include/mv88e6352.h new file mode 100644 index 0000000..cdc4db7 --- /dev/null +++ b/include/mv88e6352.h @@ -0,0 +1,92 @@ +/* + * (C) Copyright 2012 + * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; 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 + */ + +#ifndef __MV886352_H +#define __MV886352_H + +#include <common.h> + +/* PHY registers */ +#define PHY(itf) (itf) + +#define PHY_CTRL 0x00 +#define PHY_100_MBPS 0x2000 +#define PHY_1_GBPS 0x0040 +#define AUTONEG_EN 0x1000 +#define AUTONEG_RST 0x0200 +#define FULL_DUPLEX 0x0100 +#define PHY_PWR_DOWN 0x0800 + +#define PHY_STATUS 0x01 +#define AN1000FIX 0x0001 + +#define PHY_SPEC_CTRL 0x10 +#define SPEC_PWR_DOWN 0x0004 +#define AUTO_MDIX_EN 0x0060 + +#define PHY_1000_CTRL 0x9 + +#define NO_ADV 0x0000 +#define ADV_1000_FDPX 0x0200 +#define ADV_1000_HDPX 0x0100 + +#define PHY_PAGE 0x16 + +#define AN1000FIX_PAGE 0x00fc + +/* PORT or MAC registers */ +#define PORT(itf) (itf+0x10) + +#define PORT_STATUS 0x00 +#define NO_PHY_DETECT 0x0000 + +#define PORT_PHY 0x01 +#define RX_RGMII_TIM 0x8000 +#define TX_RGMII_TIM 0x4000 +#define FLOW_CTRL_EN 0x0080 +#define FLOW_CTRL_FOR 0x0040 +#define LINK_VAL 0x0020 +#define LINK_FOR 0x0010 +#define FULL_DPX 0x0008 +#define FULL_DPX_FOR 0x0004 +#define NO_SPEED_FOR 0x0003 +#define SPEED_1000_FOR 0x0002 +#define SPEED_100_FOR 0x0001 +#define SPEED_10_FOR 0x0000 + +#define PORT_CTRL 0x04 +#define FORWARDING 0x0003 +#define EGRS_FLD_ALL 0x000c +#define PORT_DIS 0x0000 + +struct mv88e_sw_reg { + u8 port; + u8 reg; + u16 value; +}; + +int mv88e_sw_reset(const char *devname, u8 phy_addr); +int mv88e_sw_program(const char *devname, u8 phy_addr, + struct mv88e_sw_reg *regs, int regs_nb); + +#endif diff --git a/include/nand.h b/include/nand.h index c554c55..bbe28b2 100644 --- a/include/nand.h +++ b/include/nand.h @@ -141,11 +141,11 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); #define NAND_LOCK_STATUS_TIGHT 0x01 -#define NAND_LOCK_STATUS_LOCK 0x02 #define NAND_LOCK_STATUS_UNLOCK 0x04 -int nand_lock( nand_info_t *meminfo, int tight ); -int nand_unlock( nand_info_t *meminfo, ulong start, ulong length ); +int nand_lock(nand_info_t *meminfo, int tight); +int nand_unlock(nand_info_t *meminfo, loff_t start, size_t length, + int allexcept); int nand_get_lock_status(nand_info_t *meminfo, loff_t offset); int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst); diff --git a/include/net.h b/include/net.h index 6d2d6cd..3539336 100644 --- a/include/net.h +++ b/include/net.h @@ -102,7 +102,14 @@ extern int eth_register(struct eth_device* dev);/* Register network device */ extern int eth_unregister(struct eth_device *dev);/* Remove network device */ extern void eth_try_another(int first_restart); /* Change the device */ extern void eth_set_current(void); /* set nterface to ethcur var */ -extern struct eth_device *eth_get_dev(void); /* get the current device MAC */ +/* get the current device MAC */ +static inline __attribute__((always_inline)) +struct eth_device *eth_get_dev(void) +{ + extern struct eth_device *eth_current; + + return eth_current; +} extern struct eth_device *eth_get_dev_by_name(const char *devname); extern struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */ extern int eth_get_dev_index(void); /* get the device index */ @@ -151,6 +158,19 @@ extern int eth_rx(void); /* Check for received packets */ extern void eth_halt(void); /* stop SCC */ extern char *eth_get_name(void); /* get name of current device */ +/* Set active state */ +static inline __attribute__((always_inline)) int eth_init_state_only(bd_t *bis) +{ + eth_get_dev()->state = ETH_STATE_ACTIVE; + + return 0; +} +/* Set passive state */ +static inline __attribute__((always_inline)) void eth_halt_state_only(void) +{ + eth_get_dev()->state = ETH_STATE_PASSIVE; +} + /* * Set the hardware address for an ethernet interface based on 'eth%daddr' * environment variable (or just 'ethaddr' if eth_number is 0). @@ -529,8 +549,29 @@ extern void NetReceive(uchar *, int); #ifdef CONFIG_NETCONSOLE void NcStart(void); -int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len); +int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, + unsigned src_port, unsigned len); +#endif + +static inline __attribute__((always_inline)) int eth_is_on_demand_init(void) +{ +#ifdef CONFIG_NETCONSOLE + extern enum proto_t net_loop_last_protocol; + + return net_loop_last_protocol != NETCONS; +#else + return 1; #endif +} + +static inline void eth_set_last_protocol(int protocol) +{ +#ifdef CONFIG_NETCONSOLE + extern enum proto_t net_loop_last_protocol; + + net_loop_last_protocol = protocol; +#endif +} /* * Check if autoload is enabled. If so, use either NFS or TFTP to download diff --git a/include/netdev.h b/include/netdev.h index d1aaf0c..b8d303d 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -104,7 +104,7 @@ int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr, int txpp, int rxpp); int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags, unsigned long ctrl_addr); - +int zynq_gem_initialize(bd_t *bis, int base_addr); /* * As long as the Xilinx xps_ll_temac ethernet driver has not its own interface * exported by a public hader file, we need a global definition at this point. diff --git a/include/part.h b/include/part.h index e1478f4..27ea283 100644 --- a/include/part.h +++ b/include/part.h @@ -93,11 +93,15 @@ typedef struct disk_partition { ulong blksz; /* block size in bytes */ uchar name[32]; /* partition name */ uchar type[32]; /* string type description */ + int bootable; /* Active/Bootable flag is set */ +#ifdef CONFIG_PARTITION_UUIDS + char uuid[37]; /* filesystem UUID as string, if exists */ +#endif } disk_partition_t; /* Misc _get_dev functions */ #ifdef CONFIG_PARTITIONS -block_dev_desc_t* get_dev(char* ifname, int dev); +block_dev_desc_t *get_dev(const char *ifname, int dev); block_dev_desc_t* ide_get_dev(int dev); block_dev_desc_t* sata_get_dev(int dev); block_dev_desc_t* scsi_get_dev(int dev); @@ -111,8 +115,14 @@ int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t void print_part (block_dev_desc_t *dev_desc); void init_part (block_dev_desc_t *dev_desc); void dev_print(block_dev_desc_t *dev_desc); +int get_device(const char *ifname, const char *dev_str, + block_dev_desc_t **dev_desc); +int get_device_and_partition(const char *ifname, const char *dev_part_str, + block_dev_desc_t **dev_desc, + disk_partition_t *info, int allow_whole_dev); #else -static inline block_dev_desc_t* get_dev(char* ifname, int dev) { return NULL; } +static inline block_dev_desc_t *get_dev(const char *ifname, int dev) +{ return NULL; } static inline block_dev_desc_t* ide_get_dev(int dev) { return NULL; } static inline block_dev_desc_t* sata_get_dev(int dev) { return NULL; } static inline block_dev_desc_t* scsi_get_dev(int dev) { return NULL; } @@ -126,6 +136,15 @@ static inline int get_partition_info (block_dev_desc_t * dev_desc, int part, static inline void print_part (block_dev_desc_t *dev_desc) {} static inline void init_part (block_dev_desc_t *dev_desc) {} static inline void dev_print(block_dev_desc_t *dev_desc) {} +static inline int get_device(const char *ifname, const char *dev_str, + block_dev_desc_t **dev_desc) +{ return -1; } +static inline int get_device_and_partition(const char *ifname, + const char *dev_part_str, + block_dev_desc_t **dev_desc, + disk_partition_t *info, + int allow_whole_dev) +{ *dev_desc = NULL; return -1; } #endif #ifdef CONFIG_MAC_PARTITION diff --git a/include/pci_ids.h b/include/pci_ids.h index 6a85c06..2c6dfd4 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -364,6 +364,10 @@ #define PCI_DEVICE_ID_ATI_RS400_166 0x5a32 #define PCI_DEVICE_ID_ATI_RS400_200 0x5a33 #define PCI_DEVICE_ID_ATI_RS480 0x5950 +/* additional Radeon families */ +#define PCI_DEVICE_ID_ATI_EVERGREEN 0x9802 +#define PCI_DEVICE_ID_ATI_EVERGREEN2 0x9804 +#define PCI_DEVICE_ID_ATI_WRESTLER 0x9806 /* ATI IXP Chipset */ #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 #define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353 @@ -375,9 +379,13 @@ #define PCI_DEVICE_ID_ATI_IXP400_SATA 0x4379 #define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a #define PCI_DEVICE_ID_ATI_IXP600_SATA 0x4380 +#define PCI_DEVICE_ID_ATI_SBX00_PCI_BRIDGE 0x4384 #define PCI_DEVICE_ID_ATI_SBX00_SMBUS 0x4385 #define PCI_DEVICE_ID_ATI_IXP600_IDE 0x438c #define PCI_DEVICE_ID_ATI_IXP700_SATA 0x4390 +#define PCI_DEVICE_ID_ATI_SBX00_SATA_AHCI 0x4391 +#define PCI_DEVICE_ID_ATI_SBX00_EHCI 0x4396 +#define PCI_DEVICE_ID_ATI_SBX00_OHCI 0x4397 #define PCI_DEVICE_ID_ATI_IXP700_IDE 0x439c #define PCI_VENDOR_ID_VLSI 0x1004 @@ -2539,9 +2547,16 @@ #define PCI_DEVICE_ID_INTEL_82840_HB 0x1a21 #define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30 #define PCI_DEVICE_ID_INTEL_IOAT 0x1a38 +#define PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_MOBILE 0x1c03 +#define PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_SERIES6 0x1c02 +#define PCI_DEVICE_ID_INTEL_COUGARPOINT_HDA 0x1c20 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE 0x1e03 +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_HDA 0x1e20 +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e41 +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC 0x1d40 #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 @@ -2635,6 +2650,7 @@ #define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0 #define PCI_DEVICE_ID_INTEL_TGP_LPC 0x27bc #define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd +#define PCI_DEVICE_ID_INTEL_NM10_AHCI 0x27c1 #define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da #define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd #define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de diff --git a/include/reiserfs.h b/include/reiserfs.h index c465b3c..dc89342 100644 --- a/include/reiserfs.h +++ b/include/reiserfs.h @@ -75,7 +75,7 @@ typedef enum } reiserfs_error_t; -extern int reiserfs_set_blk_dev(block_dev_desc_t *rbdd, int part); +extern void reiserfs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info); extern int reiserfs_ls (char *dirname); extern int reiserfs_open (char *filename); extern int reiserfs_read (char *buf, unsigned len); diff --git a/include/sdhci.h b/include/sdhci.h index 9d37183..c0345ed 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -76,6 +76,8 @@ #define SDHCI_SPACE_AVAILABLE 0x00000400 #define SDHCI_DATA_AVAILABLE 0x00000800 #define SDHCI_CARD_PRESENT 0x00010000 +#define SDHCI_CARD_STATE_STABLE 0x00020000 +#define SDHCI_CARD_DETECT_PIN_LEVEL 0x00040000 #define SDHCI_WRITE_PROTECT 0x00080000 #define SDHCI_HOST_CONTROL 0x28 @@ -87,7 +89,9 @@ #define SDHCI_CTRL_ADMA1 0x08 #define SDHCI_CTRL_ADMA32 0x10 #define SDHCI_CTRL_ADMA64 0x18 -#define SDHCI_CTRL_8BITBUS 0x20 +#define SDHCI_CTRL_8BITBUS 0x20 +#define SDHCI_CTRL_CD_TEST_INS 0x40 +#define SDHCI_CTRL_CD_TEST 0x80 #define SDHCI_POWER_CONTROL 0x29 #define SDHCI_POWER_ON 0x01 @@ -219,6 +223,7 @@ #define SDHCI_QUIRK_BROKEN_R1B (1 << 2) #define SDHCI_QUIRK_NO_HISPD_BIT (1 << 3) #define SDHCI_QUIRK_BROKEN_VOLTAGE (1 << 4) +#define SDHCI_QUIRK_NO_CD (1 << 5) /* to make gcc happy */ struct sdhci_host; @@ -248,8 +253,10 @@ struct sdhci_host { unsigned int clock; struct mmc *mmc; const struct sdhci_ops *ops; + int index; void (*set_control_reg)(struct sdhci_host *host); + void (*set_clock)(int dev_index, unsigned int div); uint voltages; }; diff --git a/include/search.h b/include/search.h index ef53edb..93e1cbc 100644 --- a/include/search.h +++ b/include/search.h @@ -57,13 +57,23 @@ struct hsearch_data { struct _ENTRY *table; unsigned int size; unsigned int filled; +/* + * Callback function which will check whether the given change for variable + * "name" from "oldval" to "newval" may be applied or not, and possibly apply + * such change. + * When (flag & H_FORCE) is set, it shall not print out any error message and + * shall force overwriting of write-once variables. +.* Must return 0 for approval, 1 for denial. + */ + int (*apply)(const char *name, const char *oldval, + const char *newval, int flag); }; /* Create a new hashing table which will at most contain NEL elements. */ extern int hcreate_r(size_t __nel, struct hsearch_data *__htab); /* Destroy current internal hashing table. */ -extern void hdestroy_r(struct hsearch_data *__htab); +extern void hdestroy_r(struct hsearch_data *__htab, int do_apply); /* * Search for entry matching ITEM.key in internal hash table. If @@ -88,17 +98,25 @@ extern int hstrstr_r(const char *__match, int __last_idx, ENTRY ** __retval, struct hsearch_data *__htab); /* Search and delete entry matching ITEM.key in internal hash table. */ -extern int hdelete_r(const char *__key, struct hsearch_data *__htab); +extern int hdelete_r(const char *__key, struct hsearch_data *__htab, + int do_apply); extern ssize_t hexport_r(struct hsearch_data *__htab, const char __sep, char **__resp, size_t __size, int argc, char * const argv[]); +/* + * nvars: length of vars array + * vars: array of strings (variable names) to import (nvars == 0 means all) + * do_apply: whether to call callback function to check the new argument, + * and possibly apply changes (false means accept everything) + */ extern int himport_r(struct hsearch_data *__htab, const char *__env, size_t __size, const char __sep, - int __flag); + int __flag, int nvars, char * const vars[], int do_apply); /* Flags for himport_r() */ -#define H_NOCLEAR 1 /* do not clear hash table before importing */ +#define H_NOCLEAR (1 << 0) /* do not clear hash table before importing */ +#define H_FORCE (1 << 1) /* overwrite read-only/write-once variables */ #endif /* search.h */ diff --git a/include/serial.h b/include/serial.h index cbdf8a9..d76d6df 100644 --- a/include/serial.h +++ b/include/serial.h @@ -31,7 +31,8 @@ extern struct serial_device *default_serial_console(void); defined(CONFIG_MB86R0x) || defined(CONFIG_MPC5xxx) || \ defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) || \ defined(CONFIG_MPC86xx) || defined(CONFIG_SYS_SC520) || \ - defined(CONFIG_TEGRA20) || defined(CONFIG_SYS_COREBOOT) + defined(CONFIG_TEGRA20) || defined(CONFIG_SYS_COREBOOT) || \ + defined(CONFIG_MICROBLAZE) extern struct serial_device serial0_device; extern struct serial_device serial1_device; #if defined(CONFIG_SYS_NS16550_SERIAL) diff --git a/include/spl.h b/include/spl.h new file mode 100644 index 0000000..af94a82 --- /dev/null +++ b/include/spl.h @@ -0,0 +1,77 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _SPL_H_ +#define _SPL_H_ + +/* Platform-specific defines */ +#include <linux/compiler.h> +#include <asm/spl.h> + +/* Boot type */ +#define MMCSD_MODE_UNDEFINED 0 +#define MMCSD_MODE_RAW 1 +#define MMCSD_MODE_FAT 2 + +struct spl_image_info { + const char *name; + u8 os; + u32 load_addr; + u32 entry_point; + u32 size; + u32 flags; +}; + +#define SPL_COPY_PAYLOAD_ONLY 1 + +extern struct spl_image_info spl_image; +extern u32 *boot_params_ptr; + +/* SPL common functions */ +void preloader_console_init(void); +u32 spl_boot_device(void); +u32 spl_boot_mode(void); +void spl_parse_image_header(const struct image_header *header); +void spl_board_prepare_for_linux(void); +void __noreturn jump_to_image_linux(void *arg); +int spl_start_uboot(void); +void spl_display_print(void); + +/* NAND SPL functions */ +void spl_nand_load_image(void); + +/* NOR SPL functions */ +void spl_nor_load_image(void); + +/* MMC SPL functions */ +void spl_mmc_load_image(void); + +/* YMODEM SPL functions */ +void spl_ymodem_load_image(void); + +/* SPI SPL functions */ +void spl_spi_load_image(void); + +#ifdef CONFIG_SPL_BOARD_INIT +void spl_board_init(void); +#endif +#endif diff --git a/include/u-boot/zlib.h b/include/u-boot/zlib.h index fbb08a3..b611fe7 100644 --- a/include/u-boot/zlib.h +++ b/include/u-boot/zlib.h @@ -513,11 +513,41 @@ typedef gz_header FAR *gz_headerp; If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. - */ - -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, const char *version, - int stream_size)); - + */ + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); + + +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); /* inflate decompresses as much data as possible, and stops when the input diff --git a/include/usb/ulpi.h b/include/usb/ulpi.h index 4a23fd2..9a75c24 100644 --- a/include/usb/ulpi.h +++ b/include/usb/ulpi.h @@ -61,7 +61,7 @@ int ulpi_select_transceiver(struct ulpi_viewport *ulpi_vp, unsigned speed); * * returns 0 on success, ULPI_ERROR on failure. */ -int ulpi_enable_vbus(struct ulpi_viewport *ulpi_vp, +int ulpi_set_vbus(struct ulpi_viewport *ulpi_vp, int on, int ext_power, int ext_ind); /* diff --git a/include/usb_ether.h b/include/usb_ether.h index a7fb26b..7c7aecb 100644 --- a/include/usb_ether.h +++ b/include/usb_ether.h @@ -50,12 +50,8 @@ struct ueth_data { unsigned char protocol; /* .............. */ unsigned char irqinterval; /* Intervall for IRQ Pipe */ - /* private fields for each driver can go here if needed */ -#ifdef CONFIG_USB_ETHER_SMSC95XX - size_t rx_urb_size; /* maximum USB URB size */ - u32 mac_cr; /* MAC control register value */ - int have_hwaddr; /* 1 if we have a hardware MAC address */ -#endif + /* driver private */ + void *dev_priv; }; /* diff --git a/include/zfs_common.h b/include/zfs_common.h index 04e73d0..3bd575e 100644 --- a/include/zfs_common.h +++ b/include/zfs_common.h @@ -66,9 +66,6 @@ struct zfs_filesystem { block_dev_desc_t *dev_desc; }; - -extern block_dev_desc_t *zfs_dev_desc; - struct device_s { uint64_t part_length; }; @@ -94,8 +91,6 @@ struct zfs_dirhook_info { struct zfs_filesystem *zfsget_fs(void); -int init_fs(block_dev_desc_t *dev_desc); -void deinit_fs(block_dev_desc_t *dev_desc); int zfs_open(zfs_file_t, const char *filename); uint64_t zfs_read(zfs_file_t, char *buf, uint64_t len); struct zfs_data *zfs_mount(device_t); @@ -103,7 +98,7 @@ int zfs_close(zfs_file_t); int zfs_ls(device_t dev, const char *path, int (*hook) (const char *, const struct zfs_dirhook_info *)); int zfs_devread(int sector, int byte_offset, int byte_len, char *buf); -int zfs_set_blk_dev(block_dev_desc_t *rbdd, int part); +void zfs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info); void zfs_unmount(struct zfs_data *data); int lzjb_decompress(void *, void *, uint32_t, uint32_t); #endif diff --git a/lib/Makefile b/lib/Makefile index c60c380..45798de 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -42,6 +42,7 @@ COBJS-y += errno.o COBJS-$(CONFIG_OF_CONTROL) += fdtdec.o COBJS-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o COBJS-$(CONFIG_GZIP) += gunzip.o +COBJS-$(CONFIG_GZIP_COMPRESSED) += gzip.o COBJS-y += hashtable.o COBJS-$(CONFIG_LMB) += lmb.o COBJS-y += ldiv.o diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 69c63db..4c23f45 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -80,11 +80,16 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node, const fdt_addr_t *cell; int len; - debug("get_addr: %s\n", prop_name); + debug("%s: %s: ", __func__, prop_name); cell = fdt_getprop(blob, node, prop_name, &len); if (cell && (len == sizeof(fdt_addr_t) || - len == sizeof(fdt_addr_t) * 2)) - return fdt_addr_to_cpu(*cell); + len == sizeof(fdt_addr_t) * 2)) { + fdt_addr_t addr = fdt_addr_to_cpu(*cell); + + debug("%p\n", (void *)addr); + return addr; + } + debug("(not found)\n"); return FDT_ADDR_T_NONE; } @@ -94,10 +99,15 @@ s32 fdtdec_get_int(const void *blob, int node, const char *prop_name, const s32 *cell; int len; - debug("get_size: %s\n", prop_name); + debug("%s: %s: ", __func__, prop_name); cell = fdt_getprop(blob, node, prop_name, &len); - if (cell && len >= sizeof(s32)) - return fdt32_to_cpu(cell[0]); + if (cell && len >= sizeof(s32)) { + s32 val = fdt32_to_cpu(cell[0]); + + debug("%#x (%d)\n", val, val); + return val; + } + debug("(not found)\n"); return default_val; } @@ -329,6 +339,7 @@ int fdtdec_lookup_phandle(const void *blob, int node, const char *prop_name) const u32 *phandle; int lookup; + debug("%s: %s\n", __func__, prop_name); phandle = fdt_getprop(blob, node, prop_name, NULL); if (!phandle) return -FDT_ERR_NOTFOUND; @@ -428,7 +439,7 @@ static int fdtdec_decode_gpios(const void *blob, int node, assert(max_count > 0); prop = fdt_get_property(blob, node, prop_name, &len); if (!prop) { - debug("FDT: %s: property '%s' missing\n", __func__, prop_name); + debug("%s: property '%s' missing\n", __func__, prop_name); return -FDT_ERR_NOTFOUND; } @@ -437,7 +448,7 @@ static int fdtdec_decode_gpios(const void *blob, int node, cell = (u32 *)prop->data; len /= sizeof(u32) * 3; /* 3 cells per GPIO record */ if (len > max_count) { - debug("FDT: %s: too many GPIOs / cells for " + debug(" %s: too many GPIOs / cells for " "property '%s'\n", __func__, prop_name); return -FDT_ERR_BADLAYOUT; } diff --git a/lib/gzip.c b/lib/gzip.c new file mode 100644 index 0000000..a83f4af --- /dev/null +++ b/lib/gzip.c @@ -0,0 +1,142 @@ +/* + * (C) Copyright 2012 + * Lei Wen <leiwen@marvell.com>, Marvell Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <image.h> +#include <malloc.h> +#include <u-boot/zlib.h> +#include "zlib/zutil.h" + +#ifndef CONFIG_GZIP_COMPRESS_DEF_SZ +#define CONFIG_GZIP_COMPRESS_DEF_SZ 0x200 +#endif +#define ZALLOC_ALIGNMENT 16 + +static void *zalloc(void *x, unsigned items, unsigned size) +{ + void *p; + + size *= items; + size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); + + p = malloc (size); + + return (p); +} + +static void zfree(void *x, void *addr, unsigned nb) +{ + free (addr); +} + +int gzip(void *dst, unsigned long *lenp, + unsigned char *src, unsigned long srclen) +{ + return zzip(dst, lenp, src, srclen, 1, NULL); +} + +/* + * Compress blocks with zlib + */ +int zzip(void *dst, unsigned long *lenp, unsigned char *src, + unsigned long srclen, int stoponerr, + int (*func)(unsigned long, unsigned long)) +{ + z_stream s; + int r, flush, orig, window; + unsigned long comp_len, left_len; + + if (!srclen) + return 0; + +#ifndef CONFIG_GZIP + window = MAX_WBITS; +#else + window = 2 * MAX_WBITS; +#endif + orig = *lenp; + s.zalloc = zalloc; + s.zfree = zfree; + s.opaque = Z_NULL; + + r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED, window, + DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + ZLIB_VERSION, sizeof(z_stream)); + if (r != Z_OK) { + printf ("Error: deflateInit2_() returned %d\n", r); + return -1; + } + + while (srclen > 0) { + comp_len = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ) ? + CONFIG_GZIP_COMPRESS_DEF_SZ : srclen; + + s.next_in = src; + s.avail_in = comp_len; + flush = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ)? + Z_NO_FLUSH : Z_FINISH; + + do { + left_len = (*lenp > CONFIG_GZIP_COMPRESS_DEF_SZ) ? + CONFIG_GZIP_COMPRESS_DEF_SZ : *lenp; + s.next_out = dst; + s.avail_out = left_len; + r = deflate(&s, flush); + if (r == Z_STREAM_ERROR && stoponerr == 1) { + printf("Error: deflate() returned %d\n", r); + r = -1; + goto bail; + } + if (!func) { + dst += (left_len - s.avail_out); + *lenp -= (left_len - s.avail_out); + } else if (left_len - s.avail_out > 0) { + r = func((unsigned long)dst, + left_len - s.avail_out); + if (r < 0) + goto bail; + } + } while (s.avail_out == 0 && (*lenp > 0)); + if (s.avail_in) { + printf("Deflate failed to consume %u bytes", s.avail_in); + r = -1; + goto bail; + } + if (*lenp == 0) { + printf("Deflate need more space to compress " + "left %lu bytes\n", srclen); + r = -1; + goto bail; + } + srclen -= comp_len; + src += comp_len; + } + + r = 0; +bail: + deflateEnd(&s); + *lenp = orig - *lenp; + return r; +} diff --git a/lib/hashtable.c b/lib/hashtable.c index abd61c8..670a704 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -142,7 +142,7 @@ int hcreate_r(size_t nel, struct hsearch_data *htab) * be freed and the local static variable can be marked as not used. */ -void hdestroy_r(struct hsearch_data *htab) +void hdestroy_r(struct hsearch_data *htab, int do_apply) { int i; @@ -156,7 +156,10 @@ void hdestroy_r(struct hsearch_data *htab) for (i = 1; i <= htab->size; ++i) { if (htab->table[i].used > 0) { ENTRY *ep = &htab->table[i].entry; - + if (do_apply && htab->apply != NULL) { + /* deletion is always forced */ + htab->apply(ep->key, ep->data, NULL, H_FORCE); + } free((void *)ep->key); free(ep->data); } @@ -401,7 +404,7 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, * do that. */ -int hdelete_r(const char *key, struct hsearch_data *htab) +int hdelete_r(const char *key, struct hsearch_data *htab, int do_apply) { ENTRY e, *ep; int idx; @@ -417,7 +420,8 @@ int hdelete_r(const char *key, struct hsearch_data *htab) /* free used ENTRY */ debug("hdelete: DELETING key \"%s\"\n", key); - + if (do_apply && htab->apply != NULL) + htab->apply(ep->key, ep->data, NULL, H_FORCE); free((void *)ep->key); free(ep->data); htab->table[idx].used = -1; @@ -604,6 +608,34 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, */ /* + * Check whether variable 'name' is amongst vars[], + * and remove all instances by setting the pointer to NULL + */ +static int drop_var_from_set(const char *name, int nvars, char * vars[]) +{ + int i = 0; + int res = 0; + + /* No variables specified means process all of them */ + if (nvars == 0) + return 1; + + for (i = 0; i < nvars; i++) { + if (vars[i] == NULL) + continue; + /* If we found it, delete all of them */ + if (!strcmp(name, vars[i])) { + vars[i] = NULL; + res = 1; + } + } + if (!res) + debug("Skipping non-listed variable %s\n", name); + + return res; +} + +/* * Import linearized data into hash table. * * This is the inverse function to hexport(): it takes a linear list @@ -639,9 +671,12 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, */ int himport_r(struct hsearch_data *htab, - const char *env, size_t size, const char sep, int flag) + const char *env, size_t size, const char sep, int flag, + int nvars, char * const vars[], int do_apply) { char *data, *sp, *dp, *name, *value; + char *localvars[nvars]; + int i; /* Test for correct arguments. */ if (htab == NULL) { @@ -658,12 +693,16 @@ int himport_r(struct hsearch_data *htab, memcpy(data, env, size); dp = data; + /* make a local copy of the list of variables */ + if (nvars) + memcpy(localvars, vars, sizeof(vars[0]) * nvars); + if ((flag & H_NOCLEAR) == 0) { /* Destroy old hash table if one exists */ debug("Destroy Hash Table: %p table = %p\n", htab, htab->table); if (htab->table) - hdestroy_r(htab); + hdestroy_r(htab, do_apply); } /* @@ -726,8 +765,10 @@ int himport_r(struct hsearch_data *htab, *dp++ = '\0'; /* terminate name */ debug("DELETE CANDIDATE: \"%s\"\n", name); + if (!drop_var_from_set(name, nvars, localvars)) + continue; - if (hdelete_r(name, htab) == 0) + if (hdelete_r(name, htab, do_apply) == 0) debug("DELETE ERROR ##############################\n"); continue; @@ -743,10 +784,32 @@ int himport_r(struct hsearch_data *htab, *sp++ = '\0'; /* terminate value */ ++dp; + /* Skip variables which are not supposed to be processed */ + if (!drop_var_from_set(name, nvars, localvars)) + continue; + /* enter into hash table */ e.key = name; e.data = value; + /* if there is an apply function, check what it has to say */ + if (do_apply && htab->apply != NULL) { + debug("searching before calling cb function" + " for %s\n", name); + /* + * Search for variable in existing env, so to pass + * its previous value to the apply callback + */ + hsearch_r(e, FIND, &rv, htab); + debug("previous value was %s\n", rv ? rv->data : ""); + if (htab->apply(name, rv ? rv->data : NULL, + value, flag)) { + debug("callback function refused to set" + " variable %s, skipping it!\n", name); + continue; + } + } + hsearch_r(e, ENTER, &rv, htab); if (rv == NULL) { printf("himport_r: can't insert \"%s=%s\" into hash table\n", @@ -762,6 +825,24 @@ int himport_r(struct hsearch_data *htab, debug("INSERT: free(data = %p)\n", data); free(data); + /* process variables which were not considered */ + for (i = 0; i < nvars; i++) { + if (localvars[i] == NULL) + continue; + /* + * All variables which were not deleted from the variable list + * were not present in the imported env + * This could mean two things: + * a) if the variable was present in current env, we delete it + * b) if the variable was not present in current env, we notify + * it might be a typo + */ + if (hdelete_r(localvars[i], htab, do_apply) == 0) + printf("WARNING: '%s' neither in running nor in imported env!\n", localvars[i]); + else + printf("WARNING: '%s' not in imported env, deleting it!\n", localvars[i]); + } + debug("INSERT: done\n"); return 1; /* everything OK */ } diff --git a/lib/zlib/deflate.c b/lib/zlib/deflate.c new file mode 100644 index 0000000..9a20b70 --- /dev/null +++ b/lib/zlib/deflate.c @@ -0,0 +1,1832 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > s->w_size) { + length = s->w_size; + dictionary += dictLength - length; /* use the tail of the dictionary */ + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_BLOCK); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong complen, wraplen; + Bytef *str; + + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (strm == Z_NULL || strm->state == Z_NULL) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; + + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (s->status == FINISH_STATE && flush != Z_FINISH) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + (s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush)); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy(dest, source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy(ds, ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest encodable run. + */ + if (s->lookahead < MAX_MATCH) { + fill_window(s); + if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} diff --git a/lib/zlib/deflate.h b/lib/zlib/deflate.h new file mode 100644 index 0000000..cbf0d1e --- /dev/null +++ b/lib/zlib/deflate.h @@ -0,0 +1,342 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2010 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/lib/zlib/trees.c b/lib/zlib/trees.c new file mode 100644 index 0000000..a0078d0 --- /dev/null +++ b/lib/zlib/trees.c @@ -0,0 +1,1244 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2010 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include <ctype.h> +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1<<extra_lbits[code]); n++) { + _length_code[length++] = (uch)code; + } + } + Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + _length_code[length-1] = (uch)code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<<extra_dbits[code]); n++) { + _dist_code[dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include <stdio.h> +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, + "inconsistent bit counts"); + Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) continue; + /* Now reverse the bits */ + tree[n].Code = bi_reverse(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); + } +} + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +local void build_tree(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(value, len) + unsigned value; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= value & 1; + value >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/lib/zlib/trees.h b/lib/zlib/trees.h new file mode 100644 index 0000000..45a749f --- /dev/null +++ b/lib/zlib/trees.h @@ -0,0 +1,127 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; diff --git a/lib/zlib/zlib.c b/lib/zlib/zlib.c index 230d0df..7e15702 100644 --- a/lib/zlib/zlib.c +++ b/lib/zlib/zlib.c @@ -12,6 +12,14 @@ * - added inflateIncomp */ +#include <common.h> + +#ifdef CONFIG_GZIP_COMPRESSED +#define NO_DUMMY_DECL +#include "deflate.c" +#include "trees.c" +#endif + #include "zutil.h" #include "inftrees.h" #include "inflate.h" diff --git a/lib/zlib/zutil.h b/lib/zlib/zutil.h index 114cb74..7e05c3b 100644 --- a/lib/zlib/zutil.h +++ b/lib/zlib/zutil.h @@ -83,6 +83,10 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* The minimum and maximum match lengths */ /* functions */ +#ifdef CONFIG_GZIP_COMPRESSED +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ +# define OS_CODE 0x03 /* assume Unix */ +#endif #include <linux/string.h> #define zmemcpy memcpy diff --git a/nand_spl/board/amcc/canyonlands/ddr2_fixed.c b/nand_spl/board/amcc/canyonlands/ddr2_fixed.c index f71ecfb9..10f62cc 100644 --- a/nand_spl/board/amcc/canyonlands/ddr2_fixed.c +++ b/nand_spl/board/amcc/canyonlands/ddr2_fixed.c @@ -92,14 +92,11 @@ static void ddr_init_common(void) mtsdram(SDRAM_INITPLR11, 0x80000432); mtsdram(SDRAM_INITPLR12, 0x808103C0); mtsdram(SDRAM_INITPLR13, 0x80810040); - mtsdram(SDRAM_INITPLR14, 0x00000000); - mtsdram(SDRAM_INITPLR15, 0x00000000); mtsdram(SDRAM_RDCC, 0x40000000); mtsdram(SDRAM_RQDC, 0x80000038); mtsdram(SDRAM_RFDC, 0x00000257); mtdcr(SDRAM_R0BAS, 0x0000F800); /* MQ0_B0BAS */ - mtdcr(SDRAM_R1BAS, 0x0400F800); /* MQ0_B1BAS */ } phys_size_t initdram(int board_type) diff --git a/onenand_ipl/onenand_ipl.h b/nand_spl/board/freescale/common.c index 7ebb3e3..0e099bc 100644 --- a/onenand_ipl/onenand_ipl.h +++ b/nand_spl/board/freescale/common.c @@ -1,6 +1,6 @@ /* - * (C) Copyright 2005-2008 Samsung Electronics - * Kyungmin Park <kyungmin.park@samsung.com> + * Copyright 2012 Freescale Semiconductor, Inc. + * Author: Matthew McClintock <msm@freescale.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -9,28 +9,32 @@ * * 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA + * */ -#ifndef _ONENAND_IPL_H -#define _ONENAND_IPL_H - -#include <linux/mtd/onenand_regs.h> +#include <common.h> +#include <asm/processor.h> +#include <asm/global_data.h> -#define onenand_readw(a) readw(THIS_ONENAND(a)) -#define onenand_writew(v, a) writew(v, THIS_ONENAND(a)) +DECLARE_GLOBAL_DATA_PTR; -#define THIS_ONENAND(a) (CONFIG_SYS_ONENAND_BASE + (a)) +#ifndef CONFIG_SYS_FSL_TBCLK_DIV +#define CONFIG_SYS_FSL_TBCLK_DIV 8 +#endif -#define READ_INTERRUPT() onenand_readw(ONENAND_REG_INTERRUPT) +void udelay(unsigned long usec) +{ + u32 ticks_per_usec = gd->bus_clk / (CONFIG_SYS_FSL_TBCLK_DIV * 1000000); + u32 ticks = ticks_per_usec * usec; + u32 s = mfspr(SPRN_TBRL); -extern int (*onenand_read_page)(ulong block, ulong page, - u_char *buf, int pagesize); -extern int onenand_read_block(unsigned char *buf); -#endif + while ((mfspr(SPRN_TBRL) - s) < ticks); +} diff --git a/nand_spl/board/freescale/p1010rdb/Makefile b/nand_spl/board/freescale/p1010rdb/Makefile index 8d240ea..cdbd492 100644 --- a/nand_spl/board/freescale/p1010rdb/Makefile +++ b/nand_spl/board/freescale/p1010rdb/Makefile @@ -39,7 +39,8 @@ CFLAGS += -DCONFIG_NAND_SPL SOBJS = start.o resetvec.o ticks.o COBJS = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \ - nand_boot.o nand_boot_fsl_ifc.o ns16550.o tlb.o tlb_table.o + nand_boot.o nand_boot_fsl_ifc.o ns16550.o tlb.o tlb_table.o \ + ../common.o SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) @@ -123,6 +124,9 @@ ifneq ($(OBJTREE), $(SRCTREE)) $(obj)nand_boot.c: @rm -f $(obj)nand_boot.c ln -s $(SRCTREE)/nand_spl/board/$(BOARDDIR)/nand_boot.c $(obj)nand_boot.c +$(obj)../common.c: + @rm -f $(obj)../common.c + ln -s $(SRCTREE)/nand_spl/board/freescale/common.c $(obj)../common.c endif ######################################################################### diff --git a/nand_spl/board/freescale/p1010rdb/nand_boot.c b/nand_spl/board/freescale/p1010rdb/nand_boot.c index 16eeb61..9c35690 100644 --- a/nand_spl/board/freescale/p1010rdb/nand_boot.c +++ b/nand_spl/board/freescale/p1010rdb/nand_boot.c @@ -27,51 +27,61 @@ #include <asm/immap_85xx.h> #include <asm/fsl_ddr_sdram.h> #include <asm/fsl_law.h> +#include <asm/global_data.h> -#define udelay(x) { int j; for (j = 0; j < x * 10000; j++) isync(); } +DECLARE_GLOBAL_DATA_PTR; unsigned long ddr_freq_mhz; void sdram_init(void) { ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR; + /* mask off E bit */ + u32 svr = SVR_SOC_VER(mfspr(SPRN_SVR)); - out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL | SDRAM_CFG_32_BE); - out_be32(&ddr->cs0_bnds, CONFIG_SYS_DDR_CS0_BNDS); - out_be32(&ddr->cs0_config, CONFIG_SYS_DDR_CS0_CONFIG); - out_be32(&ddr->sdram_cfg_2, CONFIG_SYS_DDR_CONTROL_2); - out_be32(&ddr->sdram_data_init, CONFIG_SYS_DDR_DATA_INIT); + __raw_writel(CONFIG_SYS_DDR_CONTROL | SDRAM_CFG_32_BE, &ddr->sdram_cfg); + __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds); + __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config); + __raw_writel(CONFIG_SYS_DDR_CONTROL_2, &ddr->sdram_cfg_2); + __raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init); if (ddr_freq_mhz < 700) { - out_be32(&ddr->timing_cfg_3, CONFIG_SYS_DDR_TIMING_3_667); - out_be32(&ddr->timing_cfg_0, CONFIG_SYS_DDR_TIMING_0_667); - out_be32(&ddr->timing_cfg_1, CONFIG_SYS_DDR_TIMING_1_667); - out_be32(&ddr->timing_cfg_2, CONFIG_SYS_DDR_TIMING_2_667); - out_be32(&ddr->sdram_mode, CONFIG_SYS_DDR_MODE_1_667); - out_be32(&ddr->sdram_mode_2, CONFIG_SYS_DDR_MODE_2_667); - out_be32(&ddr->sdram_interval, CONFIG_SYS_DDR_INTERVAL_667); - out_be32(&ddr->sdram_clk_cntl, CONFIG_SYS_DDR_CLK_CTRL_667); - out_be32(&ddr->ddr_wrlvl_cntl, - CONFIG_SYS_DDR_WRLVL_CONTROL_667); + __raw_writel(CONFIG_SYS_DDR_TIMING_3_667, &ddr->timing_cfg_3); + __raw_writel(CONFIG_SYS_DDR_TIMING_0_667, &ddr->timing_cfg_0); + __raw_writel(CONFIG_SYS_DDR_TIMING_1_667, &ddr->timing_cfg_1); + __raw_writel(CONFIG_SYS_DDR_TIMING_2_667, &ddr->timing_cfg_2); + __raw_writel(CONFIG_SYS_DDR_MODE_1_667, &ddr->sdram_mode); + __raw_writel(CONFIG_SYS_DDR_MODE_2_667, &ddr->sdram_mode_2); + __raw_writel(CONFIG_SYS_DDR_INTERVAL_667, &ddr->sdram_interval); + __raw_writel(CONFIG_SYS_DDR_CLK_CTRL_667, &ddr->sdram_clk_cntl); + __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL_667, &ddr->ddr_wrlvl_cntl); } else { - out_be32(&ddr->timing_cfg_3, CONFIG_SYS_DDR_TIMING_3_800); - out_be32(&ddr->timing_cfg_0, CONFIG_SYS_DDR_TIMING_0_800); - out_be32(&ddr->timing_cfg_1, CONFIG_SYS_DDR_TIMING_1_800); - out_be32(&ddr->timing_cfg_2, CONFIG_SYS_DDR_TIMING_2_800); - out_be32(&ddr->sdram_mode, CONFIG_SYS_DDR_MODE_1_800); - out_be32(&ddr->sdram_mode_2, CONFIG_SYS_DDR_MODE_2_800); - out_be32(&ddr->sdram_interval, CONFIG_SYS_DDR_INTERVAL_800); - out_be32(&ddr->sdram_clk_cntl, CONFIG_SYS_DDR_CLK_CTRL_800); - out_be32(&ddr->ddr_wrlvl_cntl, - CONFIG_SYS_DDR_WRLVL_CONTROL_800); + __raw_writel(CONFIG_SYS_DDR_TIMING_3_800, &ddr->timing_cfg_3); + __raw_writel(CONFIG_SYS_DDR_TIMING_0_800, &ddr->timing_cfg_0); + __raw_writel(CONFIG_SYS_DDR_TIMING_1_800, &ddr->timing_cfg_1); + __raw_writel(CONFIG_SYS_DDR_TIMING_2_800, &ddr->timing_cfg_2); + __raw_writel(CONFIG_SYS_DDR_MODE_1_800, &ddr->sdram_mode); + __raw_writel(CONFIG_SYS_DDR_MODE_2_800, &ddr->sdram_mode_2); + __raw_writel(CONFIG_SYS_DDR_INTERVAL_800, &ddr->sdram_interval); + __raw_writel(CONFIG_SYS_DDR_CLK_CTRL_800, &ddr->sdram_clk_cntl); + __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL_800, &ddr->ddr_wrlvl_cntl); } - out_be32(&ddr->timing_cfg_4, CONFIG_SYS_DDR_TIMING_4); - out_be32(&ddr->timing_cfg_5, CONFIG_SYS_DDR_TIMING_5); - out_be32(&ddr->ddr_zq_cntl, CONFIG_SYS_DDR_ZQ_CONTROL); + __raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4); + __raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5); + __raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl); + + /* P1014 and it's derivatives support max 16bit DDR width */ + if (svr == SVR_P1014) { + __raw_writel(ddr->sdram_cfg & ~SDRAM_CFG_DBW_MASK, &ddr->sdram_cfg); + __raw_writel(ddr->sdram_cfg | SDRAM_CFG_16_BE, &ddr->sdram_cfg); + /* For CS0_BNDS we divide the start and end address by 2, so we can just + * shift the entire register to achieve the desired result and the mask + * the value so we don't write reserved fields */ + __raw_writel((CONFIG_SYS_DDR_CS0_BNDS >> 1) & 0x0fff0fff, &ddr->cs0_bnds); + } - /* mimic 500us delay, with busy isync() loop */ - udelay(100); + udelay(500); /* Let the controller go */ out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN); @@ -82,20 +92,19 @@ void sdram_init(void) void board_init_f(ulong bootflag) { u32 plat_ratio, ddr_ratio; - unsigned long bus_clk; ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; /* initialize selected port with appropriate baud rate */ plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; plat_ratio >>= 1; - bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; + gd->bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; ddr_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO; ddr_ratio = ddr_ratio >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT; ddr_freq_mhz = (CONFIG_SYS_CLK_FREQ * ddr_ratio) / 0x1000000; NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, - bus_clk / 16 / CONFIG_BAUDRATE); + gd->bus_clk / 16 / CONFIG_BAUDRATE); puts("\nNAND boot... "); diff --git a/nand_spl/board/freescale/p1023rds/Makefile b/nand_spl/board/freescale/p1023rds/Makefile index 168e868..da43521 100644 --- a/nand_spl/board/freescale/p1023rds/Makefile +++ b/nand_spl/board/freescale/p1023rds/Makefile @@ -34,7 +34,8 @@ CFLAGS += -DCONFIG_NAND_SPL SOBJS = start.o resetvec.o COBJS = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \ - nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o + nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o \ + ../common.o SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) @@ -114,6 +115,9 @@ ifneq ($(OBJTREE), $(SRCTREE)) $(obj)nand_boot.c: @rm -f $(obj)nand_boot.c ln -s $(SRCTREE)/nand_spl/board/$(BOARDDIR)/nand_boot.c $(obj)nand_boot.c +$(obj)../common.c: + @rm -f $(obj)../common.c + ln -s $(SRCTREE)/nand_spl/board/freescale/common.c $(obj)../common.c endif ######################################################################### diff --git a/nand_spl/board/freescale/p1023rds/nand_boot.c b/nand_spl/board/freescale/p1023rds/nand_boot.c index 0065c87..89e339d 100644 --- a/nand_spl/board/freescale/p1023rds/nand_boot.c +++ b/nand_spl/board/freescale/p1023rds/nand_boot.c @@ -25,6 +25,10 @@ #include <asm/io.h> #include <nand.h> #include <asm/fsl_law.h> +#include <asm/fsl_ddr_sdram.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; /* Fixed sdram init -- doesn't use serial presence detect. */ void sdram_init(void) @@ -33,40 +37,47 @@ void sdram_init(void) set_next_law(0, LAW_SIZE_2G, LAW_TRGT_IF_DDR_1); - out_be32(&ddr->cs0_bnds, CONFIG_SYS_DDR_CS0_BNDS); - out_be32(&ddr->cs0_config, CONFIG_SYS_DDR_CS0_CONFIG); - out_be32(&ddr->cs1_bnds, CONFIG_SYS_DDR_CS1_BNDS); - out_be32(&ddr->cs1_config, CONFIG_SYS_DDR_CS1_CONFIG); - out_be32(&ddr->timing_cfg_3, CONFIG_SYS_DDR_TIMING_3); - out_be32(&ddr->timing_cfg_0, CONFIG_SYS_DDR_TIMING_0); - out_be32(&ddr->timing_cfg_1, CONFIG_SYS_DDR_TIMING_1); - out_be32(&ddr->timing_cfg_2, CONFIG_SYS_DDR_TIMING_2); - out_be32(&ddr->sdram_cfg_2, CONFIG_SYS_DDR_CONTROL2); - out_be32(&ddr->sdram_mode, CONFIG_SYS_DDR_MODE_1); - out_be32(&ddr->sdram_mode_2, CONFIG_SYS_DDR_MODE_2); - out_be32(&ddr->sdram_interval, CONFIG_SYS_DDR_INTERVAL); - out_be32(&ddr->sdram_data_init, CONFIG_SYS_DDR_DATA_INIT); - out_be32(&ddr->sdram_clk_cntl, CONFIG_SYS_DDR_CLK_CTRL); - out_be32(&ddr->timing_cfg_4, CONFIG_SYS_DDR_TIMING_4); - out_be32(&ddr->timing_cfg_5, CONFIG_SYS_DDR_TIMING_5); - out_be32(&ddr->ddr_zq_cntl, CONFIG_SYS_DDR_ZQ_CNTL); - out_be32(&ddr->ddr_wrlvl_cntl, CONFIG_SYS_DDR_WRLVL_CNTL); - out_be32(&ddr->ddr_cdr1, CONFIG_SYS_DDR_CDR_1); - out_be32(&ddr->ddr_cdr2, CONFIG_SYS_DDR_CDR_2); - out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL); + __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds); + __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config); + __raw_writel(CONFIG_SYS_DDR_CS1_BNDS, &ddr->cs1_bnds); + __raw_writel(CONFIG_SYS_DDR_CS1_CONFIG, &ddr->cs1_config); + __raw_writel(CONFIG_SYS_DDR_TIMING_3, &ddr->timing_cfg_3); + __raw_writel(CONFIG_SYS_DDR_TIMING_0, &ddr->timing_cfg_0); + __raw_writel(CONFIG_SYS_DDR_TIMING_1, &ddr->timing_cfg_1); + __raw_writel(CONFIG_SYS_DDR_TIMING_2, &ddr->timing_cfg_2); + __raw_writel(CONFIG_SYS_DDR_CONTROL2, &ddr->sdram_cfg_2); + __raw_writel(CONFIG_SYS_DDR_MODE_1, &ddr->sdram_mode); + __raw_writel(CONFIG_SYS_DDR_MODE_2, &ddr->sdram_mode_2); + __raw_writel(CONFIG_SYS_DDR_INTERVAL, &ddr->sdram_interval); + __raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init); + __raw_writel(CONFIG_SYS_DDR_CLK_CTRL, &ddr->sdram_clk_cntl); + __raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4); + __raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5); + __raw_writel(CONFIG_SYS_DDR_ZQ_CNTL, &ddr->ddr_zq_cntl); + __raw_writel(CONFIG_SYS_DDR_WRLVL_CNTL, &ddr->ddr_wrlvl_cntl); + __raw_writel(CONFIG_SYS_DDR_CDR_1, &ddr->ddr_cdr1); + __raw_writel(CONFIG_SYS_DDR_CDR_2, &ddr->ddr_cdr2); + /* Set, but do not enable the memory */ + __raw_writel(CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN, &ddr->sdram_cfg); + + asm volatile("sync;isync"); + udelay(500); + + /* Let the controller go */ + out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN); } void board_init_f(ulong bootflag) { - u32 plat_ratio, bus_clk; + u32 plat_ratio; ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; /* initialize selected port with appropriate baud rate */ plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; plat_ratio >>= 1; - bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; + gd->bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, - bus_clk / 16 / CONFIG_BAUDRATE); + gd->bus_clk / 16 / CONFIG_BAUDRATE); puts("\nNAND boot... "); /* Initialize the DDR3 */ diff --git a/nand_spl/board/freescale/p1_p2_rdb_pc/Makefile b/nand_spl/board/freescale/p1_p2_rdb_pc/Makefile index 475cc49..46cf709 100644 --- a/nand_spl/board/freescale/p1_p2_rdb_pc/Makefile +++ b/nand_spl/board/freescale/p1_p2_rdb_pc/Makefile @@ -39,7 +39,8 @@ CFLAGS += -DCONFIG_NAND_SPL SOBJS = start.o resetvec.o COBJS = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \ - nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o + nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o \ + ../common.o SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) @@ -119,6 +120,9 @@ ifneq ($(OBJTREE), $(SRCTREE)) $(obj)nand_boot.c: @rm -f $(obj)nand_boot.c ln -s $(SRCTREE)/nand_spl/board/$(BOARDDIR)/nand_boot.c $(obj)nand_boot.c +$(obj)../common.c: + @rm -f $(obj)../common.c + ln -s $(SRCTREE)/nand_spl/board/freescale/common.c $(obj)../common.c endif ######################################################################### diff --git a/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c b/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c index b9796ea..4c140c1 100644 --- a/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c +++ b/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c @@ -25,11 +25,9 @@ #include <nand.h> #include <asm/fsl_law.h> #include <asm/fsl_ddr_sdram.h> +#include <asm/global_data.h> -#define udelay(x) {int i, j; \ - for (i = 0; i < x; i++) \ - for (j = 0; j < 10000; j++) \ - ; } +DECLARE_GLOBAL_DATA_PTR; /* * Fixed sdram init -- doesn't use serial presence detect. @@ -38,32 +36,32 @@ void sdram_init(void) { ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR; - out_be32(&ddr->cs0_bnds, CONFIG_SYS_DDR_CS0_BNDS); - out_be32(&ddr->cs0_config, CONFIG_SYS_DDR_CS0_CONFIG); + __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds); + __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config); #if CONFIG_CHIP_SELECTS_PER_CTRL > 1 - out_be32(&ddr->cs1_bnds, CONFIG_SYS_DDR_CS1_BNDS); - out_be32(&ddr->cs1_config, CONFIG_SYS_DDR_CS1_CONFIG); + __raw_writel(CONFIG_SYS_DDR_CS1_BNDS, &ddr->cs1_bnds); + __raw_writel(CONFIG_SYS_DDR_CS1_CONFIG, &ddr->cs1_config); #endif - out_be32(&ddr->timing_cfg_3, CONFIG_SYS_DDR_TIMING_3); - out_be32(&ddr->timing_cfg_0, CONFIG_SYS_DDR_TIMING_0); - out_be32(&ddr->timing_cfg_1, CONFIG_SYS_DDR_TIMING_1); - out_be32(&ddr->timing_cfg_2, CONFIG_SYS_DDR_TIMING_2); + __raw_writel(CONFIG_SYS_DDR_TIMING_3, &ddr->timing_cfg_3); + __raw_writel(CONFIG_SYS_DDR_TIMING_0, &ddr->timing_cfg_0); + __raw_writel(CONFIG_SYS_DDR_TIMING_1, &ddr->timing_cfg_1); + __raw_writel(CONFIG_SYS_DDR_TIMING_2, &ddr->timing_cfg_2); - out_be32(&ddr->sdram_cfg_2, CONFIG_SYS_DDR_CONTROL_2); - out_be32(&ddr->sdram_mode, CONFIG_SYS_DDR_MODE_1); - out_be32(&ddr->sdram_mode_2, CONFIG_SYS_DDR_MODE_2); + __raw_writel(CONFIG_SYS_DDR_CONTROL_2, &ddr->sdram_cfg_2); + __raw_writel(CONFIG_SYS_DDR_MODE_1, &ddr->sdram_mode); + __raw_writel(CONFIG_SYS_DDR_MODE_2, &ddr->sdram_mode_2); - out_be32(&ddr->sdram_interval, CONFIG_SYS_DDR_INTERVAL); - out_be32(&ddr->sdram_data_init, CONFIG_SYS_DDR_DATA_INIT); - out_be32(&ddr->sdram_clk_cntl, CONFIG_SYS_DDR_CLK_CTRL); + __raw_writel(CONFIG_SYS_DDR_INTERVAL, &ddr->sdram_interval); + __raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init); + __raw_writel(CONFIG_SYS_DDR_CLK_CTRL, &ddr->sdram_clk_cntl); - out_be32(&ddr->timing_cfg_4, CONFIG_SYS_DDR_TIMING_4); - out_be32(&ddr->timing_cfg_5, CONFIG_SYS_DDR_TIMING_5); - out_be32(&ddr->ddr_zq_cntl, CONFIG_SYS_DDR_ZQ_CONTROL); - out_be32(&ddr->ddr_wrlvl_cntl, CONFIG_SYS_DDR_WRLVL_CONTROL); + __raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4); + __raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5); + __raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl); + __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL, &ddr->ddr_wrlvl_cntl); /* Set, but do not enable the memory */ - out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN); + __raw_writel(CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN, &ddr->sdram_cfg); asm volatile("sync;isync"); udelay(500); @@ -76,7 +74,7 @@ void sdram_init(void) void board_init_f(ulong bootflag) { - u32 plat_ratio, bus_clk; + u32 plat_ratio; ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; #ifndef CONFIG_QE ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); @@ -85,22 +83,22 @@ void board_init_f(ulong bootflag) /* initialize selected port with appropriate baud rate */ plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; plat_ratio >>= 1; - bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; + gd->bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, - bus_clk / 16 / CONFIG_BAUDRATE); + gd->bus_clk / 16 / CONFIG_BAUDRATE); puts("\nNAND boot... "); #ifndef CONFIG_QE /* init DDR3 reset signal */ - out_be32(&pgpio->gpdir, 0x02000000); - out_be32(&pgpio->gpodr, 0x00200000); - out_be32(&pgpio->gpdat, 0x00000000); + __raw_writel(0x02000000, &pgpio->gpdir); + __raw_writel(0x00200000, &pgpio->gpodr); + __raw_writel(0x00000000, &pgpio->gpdat); udelay(1000); - out_be32(&pgpio->gpdat, 0x00200000); + __raw_writel(0x00200000, &pgpio->gpdat); udelay(1000); - out_be32(&pgpio->gpdir, 0x00000000); + __raw_writel(0x00000000, &pgpio->gpdir); #endif /* Initialize the DDR3 */ diff --git a/nand_spl/nand_boot_fsl_elbc.c b/nand_spl/nand_boot_fsl_elbc.c index 502605b..e9d6497 100644 --- a/nand_spl/nand_boot_fsl_elbc.c +++ b/nand_spl/nand_boot_fsl_elbc.c @@ -66,39 +66,42 @@ static void nand_load(unsigned int offs, int uboot_size, uchar *dst) if (large) { fmr |= FMR_ECCM; - out_be32(®s->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) | - (NAND_CMD_READSTART << FCR_CMD1_SHIFT)); - out_be32(®s->fir, - (FIR_OP_CW0 << FIR_OP0_SHIFT) | - (FIR_OP_CA << FIR_OP1_SHIFT) | - (FIR_OP_PA << FIR_OP2_SHIFT) | - (FIR_OP_CW1 << FIR_OP3_SHIFT) | - (FIR_OP_RBW << FIR_OP4_SHIFT)); + __raw_writel((NAND_CMD_READ0 << FCR_CMD0_SHIFT) | + (NAND_CMD_READSTART << FCR_CMD1_SHIFT), + ®s->fcr); + __raw_writel( + (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CA << FIR_OP1_SHIFT) | + (FIR_OP_PA << FIR_OP2_SHIFT) | + (FIR_OP_CW1 << FIR_OP3_SHIFT) | + (FIR_OP_RBW << FIR_OP4_SHIFT), + ®s->fir); } else { - out_be32(®s->fcr, NAND_CMD_READ0 << FCR_CMD0_SHIFT); - out_be32(®s->fir, - (FIR_OP_CW0 << FIR_OP0_SHIFT) | - (FIR_OP_CA << FIR_OP1_SHIFT) | - (FIR_OP_PA << FIR_OP2_SHIFT) | - (FIR_OP_RBW << FIR_OP3_SHIFT)); + __raw_writel(NAND_CMD_READ0 << FCR_CMD0_SHIFT, ®s->fcr); + __raw_writel( + (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CA << FIR_OP1_SHIFT) | + (FIR_OP_PA << FIR_OP2_SHIFT) | + (FIR_OP_RBW << FIR_OP3_SHIFT), + ®s->fir); } - out_be32(®s->fbcr, 0); - clrsetbits_be32(®s->bank[0].br, BR_DECC, BR_DECC_CHK_GEN); + __raw_writel(0, ®s->fbcr); while (pos < uboot_size) { int i = 0; - out_be32(®s->fbar, offs >> block_shift); + __raw_writel(offs >> block_shift, ®s->fbar); do { int j; unsigned int page_offs = (offs & (block_size - 1)) << 1; - out_be32(®s->ltesr, ~0); - out_be32(®s->lteatr, 0); - out_be32(®s->fpar, page_offs); - out_be32(®s->fmr, fmr); - out_be32(®s->lsor, 0); + __raw_writel(~0, ®s->ltesr); + __raw_writel(0, ®s->lteatr); + __raw_writel(page_offs, ®s->fpar); + __raw_writel(fmr, ®s->fmr); + sync(); + __raw_writel(0, ®s->lsor); nand_wait(); page_offs %= WINDOW_SIZE; diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index d6b0d9b..a40c998 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -36,50 +36,58 @@ static void nfc_wait_ready(void) { uint32_t tmp; - while (!(readw(&nfc->nand_flash_config2) & NFC_INT)) + while (!(readw(&nfc->config2) & NFC_INT)) ; /* Reset interrupt flag */ - tmp = readw(&nfc->nand_flash_config2); + tmp = readw(&nfc->config2); tmp &= ~NFC_INT; - writew(tmp, &nfc->nand_flash_config2); + writew(tmp, &nfc->config2); } -void nfc_nand_init(void) +static void nfc_nand_init(void) { -#if defined(MXC_NFC_V1_1) - int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; +#if defined(MXC_NFC_V2_1) + int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; int config1; writew(CONFIG_SYS_NAND_SPARE_SIZE / 2, &nfc->spare_area_size); /* unlocking RAM Buff */ - writew(0x2, &nfc->configuration); + writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - config1 = readw(&nfc->nand_flash_config1) | NFC_ECC_EN | 0x800; + config1 = readw(&nfc->config1) | NFC_ECC_EN | NFC_INT_MSK | + NFC_ONE_CYCLE | NFC_FP_INT; /* * if spare size is larger that 16 bytes per 512 byte hunk * then use 8 symbol correction instead of 4 */ - if ((CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page) > 16) + if (CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page > 16) config1 &= ~NFC_4_8N_ECC; else config1 |= NFC_4_8N_ECC; - writew(config1, &nfc->nand_flash_config1); + writew(config1, &nfc->config1); #elif defined(MXC_NFC_V1) /* unlocking RAM Buff */ - writew(0x2, &nfc->configuration); + writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - writew(NFC_ECC_EN, &nfc->nand_flash_config1); + writew(NFC_ECC_EN | NFC_INT_MSK, &nfc->config1); #endif } static void nfc_nand_command(unsigned short command) { writew(command, &nfc->flash_cmd); - writew(NFC_CMD, &nfc->nand_flash_config2); + writew(NFC_CMD, &nfc->config2); + nfc_wait_ready(); +} + +static void nfc_nand_address(unsigned short address) +{ + writew(address, &nfc->flash_addr); + writew(NFC_ADDR, &nfc->config2); nfc_wait_ready(); } @@ -87,58 +95,43 @@ static void nfc_nand_page_address(unsigned int page_address) { unsigned int page_count; - writew(0x00, &nfc->flash_add); - writew(NFC_ADDR, &nfc->nand_flash_config2); - nfc_wait_ready(); + nfc_nand_address(0x00); /* code only for large page flash */ - if (CONFIG_SYS_NAND_PAGE_SIZE > 512) { - writew(0x00, &nfc->flash_add); - writew(NFC_ADDR, &nfc->nand_flash_config2); - nfc_wait_ready(); - } + if (CONFIG_SYS_NAND_PAGE_SIZE > 512) + nfc_nand_address(0x00); page_count = CONFIG_SYS_NAND_SIZE / CONFIG_SYS_NAND_PAGE_SIZE; if (page_address <= page_count) { page_count--; /* transform 0x01000000 to 0x00ffffff */ do { - writew(page_address & 0xff, &nfc->flash_add); - writew(NFC_ADDR, &nfc->nand_flash_config2); - nfc_wait_ready(); + nfc_nand_address(page_address & 0xff); page_address = page_address >> 8; page_count = page_count >> 8; } while (page_count); } - writew(0x00, &nfc->flash_add); - writew(NFC_ADDR, &nfc->nand_flash_config2); - nfc_wait_ready(); + nfc_nand_address(0x00); } static void nfc_nand_data_output(void) { - int config1 = readw(&nfc->nand_flash_config1); #ifdef NAND_MXC_2K_MULTI_CYCLE int i; #endif - config1 |= NFC_ECC_EN | NFC_INT_MSK; - writew(config1, &nfc->nand_flash_config1); - writew(0, &nfc->buffer_address); - writew(NFC_OUTPUT, &nfc->nand_flash_config2); + writew(0, &nfc->buf_addr); + writew(NFC_OUTPUT, &nfc->config2); nfc_wait_ready(); #ifdef NAND_MXC_2K_MULTI_CYCLE /* * This NAND controller requires multiple input commands * for pages larger than 512 bytes. */ - for (i = 1; i < (CONFIG_SYS_NAND_PAGE_SIZE / 512); i++) { - config1 = readw(&nfc->nand_flash_config1); - config1 |= NFC_ECC_EN | NFC_INT_MSK; - writew(config1, &nfc->nand_flash_config1); - writew(i, &nfc->buffer_address); - writew(NFC_OUTPUT, &nfc->nand_flash_config2); + for (i = 1; i < CONFIG_SYS_NAND_PAGE_SIZE / 512; i++) { + writew(i, &nfc->buf_addr); + writew(NFC_OUTPUT, &nfc->config2); nfc_wait_ready(); } #endif @@ -146,16 +139,28 @@ static void nfc_nand_data_output(void) static int nfc_nand_check_ecc(void) { - return readw(&nfc->ecc_status_result); +#if defined(MXC_NFC_V1) + u16 ecc_status = readw(&nfc->ecc_status_result); + return (ecc_status & 0x3) == 2 || (ecc_status >> 2) == 2; +#elif defined(MXC_NFC_V2_1) + u32 ecc_status = readl(&nfc->ecc_status_result); + int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; + int err_limit = CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page > 16 ? 8 : 4; + int subpages = CONFIG_SYS_NAND_PAGE_SIZE / 512; + + do { + if ((ecc_status & 0xf) > err_limit) + return 1; + ecc_status >>= 4; + } while (--subpages); + + return 0; +#endif } -static int nfc_read_page(unsigned int page_address, unsigned char *buf) +static void nfc_nand_read_page(unsigned int page_address) { - int i; - u32 *src; - u32 *dst; - - writew(0, &nfc->buffer_address); /* read in first 0 buffer */ + writew(0, &nfc->buf_addr); /* read in first 0 buffer */ nfc_nand_command(NAND_CMD_READ0); nfc_nand_page_address(page_address); @@ -163,15 +168,24 @@ static int nfc_read_page(unsigned int page_address, unsigned char *buf) nfc_nand_command(NAND_CMD_READSTART); nfc_nand_data_output(); /* fill the main buffer 0 */ +} + +static int nfc_read_page(unsigned int page_address, unsigned char *buf) +{ + int i; + u32 *src; + u32 *dst; + + nfc_nand_read_page(page_address); if (nfc_nand_check_ecc()) return -1; - src = &nfc->main_area[0][0]; + src = (u32 *)&nfc->main_area[0][0]; dst = (u32 *)buf; /* main copy loop from NAND-buffer to SDRAM memory */ - for (i = 0; i < (CONFIG_SYS_NAND_PAGE_SIZE / 4); i++) { + for (i = 0; i < CONFIG_SYS_NAND_PAGE_SIZE / 4; i++) { writel(readl(src), dst); src++; dst++; @@ -188,16 +202,9 @@ static int is_badblock(int pagenumber) /* Check the first two pages for bad block markers */ for (page = pagenumber; page < pagenumber + 2; page++) { - writew(0, &nfc->buffer_address); /* read in first 0 buffer */ - nfc_nand_command(NAND_CMD_READ0); - nfc_nand_page_address(page); - - if (CONFIG_SYS_NAND_PAGE_SIZE > 512) - nfc_nand_command(NAND_CMD_READSTART); - - nfc_nand_data_output(); /* fill the main buffer 0 */ + nfc_nand_read_page(page); - src = &nfc->spare_area[0][0]; + src = (u32 *)&nfc->spare_area[0][0]; /* * IMPORTANT NOTE: The nand flash controller uses a non- @@ -230,7 +237,7 @@ static int nand_load(unsigned int from, unsigned int size, unsigned char *buf) page = from / CONFIG_SYS_NAND_PAGE_SIZE; i = 0; - while (i < (size / CONFIG_SYS_NAND_PAGE_SIZE)) { + while (i < size / CONFIG_SYS_NAND_PAGE_SIZE) { if (nfc_read_page(page, buf) < 0) return -1; diff --git a/net/bootp.c b/net/bootp.c index c9b8349..661e371 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -728,6 +728,8 @@ static void DhcpOptionsProcess(uchar *popt, struct Bootp_t *bp) memcpy(&NetOurRootPath, popt + 2, size); NetOurRootPath[size] = 0; break; + case 28: /* Ignore Broadcast Address Option */ + break; #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER) case 42: /* NTP server IP */ NetCopyIP(&NetNtpServerIP, (popt + 2)); @@ -121,12 +121,8 @@ static struct { static unsigned int eth_rcv_current, eth_rcv_last; #endif -static struct eth_device *eth_devices, *eth_current; - -struct eth_device *eth_get_dev(void) -{ - return eth_current; -} +static struct eth_device *eth_devices; +struct eth_device *eth_current; struct eth_device *eth_get_dev_by_name(const char *devname) { @@ -222,9 +218,12 @@ int eth_write_hwaddr(struct eth_device *dev, const char *base_name, } if (dev->write_hwaddr && - !eth_mac_skip(eth_number) && - is_valid_ether_addr(dev->enetaddr)) + !eth_mac_skip(eth_number)) { + if (!is_valid_ether_addr(dev->enetaddr)) + return -1; + ret = dev->write_hwaddr(dev); + } return ret; } @@ -500,10 +499,7 @@ int eth_receive(void *packet, int length) return -1; } - if (length < eth_rcv_bufs[eth_rcv_current].length) - return -1; - - length = eth_rcv_bufs[eth_rcv_current].length; + length = min(eth_rcv_bufs[eth_rcv_current].length, length); for (i = 0; i < length; i++) p[i] = eth_rcv_bufs[eth_rcv_current].data[i]; @@ -315,12 +315,15 @@ int NetLoop(enum proto_t protocol) bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); net_init(); - eth_halt(); - eth_set_current(); - if (eth_init(bd) < 0) { + if (eth_is_on_demand_init() || protocol != NETCONS) { eth_halt(); - return -1; - } + eth_set_current(); + if (eth_init(bd) < 0) { + eth_halt(); + return -1; + } + } else + eth_init_state_only(bd); restart: net_set_state(NETLOOP_CONTINUE); @@ -460,6 +463,9 @@ restart: net_cleanup_loop(); eth_halt(); + /* Invalidate the last protocol */ + eth_set_last_protocol(BOOTP); + puts("\nAbort\n"); /* include a debug print as well incase the debug messages are directed to stderr */ @@ -517,13 +523,21 @@ restart: sprintf(buf, "%lX", (unsigned long)load_addr); setenv("fileaddr", buf); } - eth_halt(); + if (protocol != NETCONS) + eth_halt(); + else + eth_halt_state_only(); + + eth_set_last_protocol(protocol); + ret = NetBootFileXferSize; debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n"); goto done; case NETLOOP_FAIL: net_cleanup_loop(); + /* Invalidate the last protocol */ + eth_set_last_protocol(BOOTP); debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n"); goto done; @@ -652,7 +666,7 @@ NetSetTimeout(ulong iv, thand_f *f) "--- NetLoop timeout handler set (%p)\n", f); timeHandler = f; timeStart = get_timer(0); - timeDelta = iv; + timeDelta = iv * CONFIG_SYS_HZ / 1000; } } @@ -1147,6 +1161,7 @@ NetReceive(uchar *inpkt, int len) #ifdef CONFIG_NETCONSOLE nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE, + ntohl(ip->ip_src), ntohs(ip->udp_dst), ntohs(ip->udp_src), ntohs(ip->udp_len) - UDP_HDR_SIZE); diff --git a/onenand_ipl/board/apollon/Makefile b/onenand_ipl/board/apollon/Makefile deleted file mode 100644 index 3bc9920..0000000 --- a/onenand_ipl/board/apollon/Makefile +++ /dev/null @@ -1,87 +0,0 @@ - -include $(TOPDIR)/config.mk -include $(TOPDIR)/onenand_ipl/board/$(BOARDDIR)/config.mk - -LDSCRIPT= $(TOPDIR)/onenand_ipl/board/$(BOARDDIR)/u-boot.onenand.lds -LDFLAGS = -Bstatic -T $(onenandobj)u-boot.lds -Ttext $(CONFIG_SYS_TEXT_BASE) $(PLATFORM_LDFLAGS) -AFLAGS += -DCONFIG_SPL_BUILD -DCONFIG_ONENAND_IPL -CFLAGS += -DCONFIG_SPL_BUILD -DCONFIG_ONENAND_IPL -OBJCFLAGS += --gap-fill=0x00 - -SOBJS := low_levelinit.o -SOBJS += start.o -COBJS := apollon.o -COBJS += onenand_read.o -COBJS += onenand_boot.o - -SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -__OBJS := $(SOBJS) $(COBJS) -LNDIR := $(OBJTREE)/onenand_ipl/board/$(BOARDDIR) - -onenandobj := $(OBJTREE)/onenand_ipl/ - -ALL = $(onenandobj)onenand-ipl $(onenandobj)onenand-ipl.bin $(onenandobj)onenand-ipl-2k.bin $(onenandobj)onenand-ipl-4k.bin - -all: $(obj).depend $(ALL) - -$(onenandobj)onenand-ipl-2k.bin: $(onenandobj)onenand-ipl - $(OBJCOPY) ${OBJCFLAGS} --pad-to=0x800 -O binary $< $@ - -$(onenandobj)onenand-ipl-4k.bin: $(onenandobj)onenand-ipl - $(OBJCOPY) ${OBJCFLAGS} --pad-to=0x1000 -O binary $< $@ - -$(onenandobj)onenand-ipl.bin: $(onenandobj)onenand-ipl - $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ - -$(onenandobj)onenand-ipl: $(OBJS) $(onenandobj)u-boot.lds - cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \ - -Map $@.map -o $@ - -$(onenandobj)u-boot.lds: $(LDSCRIPT) - $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@ - -# create symbolic links from common files - -# from cpu directory -$(obj)start.S: - @rm -f $@ - ln -s $(SRCTREE)/$(CPUDIR)/start.S $@ - -# from onenand_ipl directory -$(obj)onenand_ipl.h: - @rm -f $@ - ln -s $(SRCTREE)/onenand_ipl/onenand_ipl.h $@ - -$(obj)onenand_boot.c: $(obj)onenand_ipl.h - @rm -f $@ - ln -s $(SRCTREE)/onenand_ipl/onenand_boot.c $@ - -$(obj)onenand_read.c: $(obj)onenand_ipl.h - @rm -f $@ - ln -s $(SRCTREE)/onenand_ipl/onenand_read.c $@ - -ifneq ($(OBJTREE), $(SRCTREE)) -$(obj)apollon.c: - @rm -f $@ - ln -s $(SRCTREE)/onenand_ipl/board/$(BOARDDIR)/apollon.c $@ - -$(obj)low_levelinit.S: - @rm -f $@ - ln -s $(SRCTREE)/onenand_ipl/board/$(BOARDDIR)/low_levelinit.S $@ -endif - -######################################################################### - -$(obj)%.o: $(obj)%.S - $(CC) $(AFLAGS) -c -o $@ $< - -$(obj)%.o: $(obj)$.c - $(CC) $(CFLAGS) -c -o $@ $< - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/onenand_ipl/board/apollon/apollon.c b/onenand_ipl/board/apollon/apollon.c deleted file mode 100644 index 4936e00..0000000 --- a/onenand_ipl/board/apollon/apollon.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * (C) Copyright 2005-2008 Samsung Electronics - * Kyungmin Park <kyungmin.park@samsung.com> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include <common.h> -#include <asm/arch/mux.h> - -#define write_config_reg(reg, value) \ -do { \ - writeb(value, reg); \ -} while (0) - -/***************************************** - * Routine: board_init - * Description: Early hardware init. - *****************************************/ -int board_init(void) -{ - return 0; -} - -#ifdef CONFIG_SYS_PRINTF -/* Pin Muxing registers used for UART1 */ -/**************************************** - * Routine: muxSetupUART1 (ostboot) - * Description: Set up uart1 muxing - *****************************************/ -static void muxSetupUART1(void) -{ - /* UART1_CTS pin configuration, PIN = D21 */ - write_config_reg(CONTROL_PADCONF_UART1_CTS, 0); - /* UART1_RTS pin configuration, PIN = H21 */ - write_config_reg(CONTROL_PADCONF_UART1_RTS, 0); - /* UART1_TX pin configuration, PIN = L20 */ - write_config_reg(CONTROL_PADCONF_UART1_TX, 0); - /* UART1_RX pin configuration, PIN = T21 */ - write_config_reg(CONTROL_PADCONF_UART1_RX, 0); -} -#endif - -/********************************************************** - * Routine: s_init - * Description: Does early system init of muxing and clocks. - * - Called at time when only stack is available. - **********************************************************/ -int s_init(int skip) -{ -#ifdef CONFIG_SYS_PRINTF - muxSetupUART1(); -#endif - return 0; -} diff --git a/onenand_ipl/board/apollon/config.mk b/onenand_ipl/board/apollon/config.mk deleted file mode 100644 index 62956e8..0000000 --- a/onenand_ipl/board/apollon/config.mk +++ /dev/null @@ -1,14 +0,0 @@ -# -# (C) Copyright 2005-2008 Samsung Electronics -# Kyungmin Park <kyungmin.park@samsung.com> -# -# Samsung Apollon board with OMAP2420 (ARM1136) cpu -# -# Apollon has 1 bank of 128MB mDDR-SDRAM on CS0 -# Physical Address: -# 8000'0000 (bank0) -# 8800'0000 (bank1) -# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 -# (mem base + reserved) - -CONFIG_SYS_TEXT_BASE = 0x00000000 diff --git a/onenand_ipl/board/apollon/low_levelinit.S b/onenand_ipl/board/apollon/low_levelinit.S deleted file mode 100644 index cab4227..0000000 --- a/onenand_ipl/board/apollon/low_levelinit.S +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Board specific setup info - * - * (C) Copyright 2005-2008 Samsung Electronics - * Kyungmin Park <kyungmin.park@samsung.com> - * - * Derived from board/omap2420h4/platform.S - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <config.h> -#include <asm/arch/omap2420.h> -#include <asm/arch/mem.h> -#include <asm/arch/clocks.h> - -#define APOLLON_CS0_BASE 0x00000000 - -#ifdef PRCM_CONFIG_I -#define SDRC_ACTIM_CTRLA_0_VAL 0x7BA35907 -#define SDRC_ACTIM_CTRLB_0_VAL 0x00000013 -#define SDRC_RFR_CTRL_0_VAL 0x00044C01 - -/* GPMC */ -#define APOLLON_GPMC_CONFIG1_0 0xe30d1201 -#define APOLLON_GPMC_CONFIG2_0 0x000c1000 -#define APOLLON_GPMC_CONFIG3_0 0x00030400 -#define APOLLON_GPMC_CONFIG4_0 0x0B841006 -#define APOLLON_GPMC_CONFIG5_0 0x020F0C11 -#define APOLLON_GPMC_CONFIG6_0 0x00000000 -#define APOLLON_GPMC_CONFIG7_0 (0x00000e40 | (APOLLON_CS0_BASE >> 24)) - -#elif defined(PRCM_CONFIG_II) -#define SDRC_ACTIM_CTRLA_0_VAL 0x4A59B485 -#define SDRC_ACTIM_CTRLB_0_VAL 0x0000000C -#define SDRC_RFR_CTRL_0_VAL 0x00030001 - -/* GPMC */ -#define APOLLON_GPMC_CONFIG1_0 0xe30d1201 -#define APOLLON_GPMC_CONFIG2_0 0x00080E81 -#define APOLLON_GPMC_CONFIG3_0 0x00030400 -#define APOLLON_GPMC_CONFIG4_0 0x08041586 -#define APOLLON_GPMC_CONFIG5_0 0x020C090E -#define APOLLON_GPMC_CONFIG6_0 0x00000000 -#define APOLLON_GPMC_CONFIG7_0 (0x00000e40 | (APOLLON_CS0_BASE >> 24)) - -#else -#error "Please configure PRCM schecm" -#endif - -_TEXT_BASE: - .word CONFIG_SYS_TEXT_BASE /* sdram load addr from config.mk */ - -.globl lowlevel_init -lowlevel_init: - mov r3, r0 /* save skip information */ - - /* Disable watchdog */ - ldr r0, =WD2_BASE - ldr r1, =WD_UNLOCK1 - str r1, [r0, #WSPR] - - ldr r1, =WD_UNLOCK2 - str r1, [r0, #WSPR] - -#ifdef DEBUG_LED - /* LED0 OFF */ - ldr r0, =0x480000E5 /* ball AA10, mode 3 */ - mov r1, #0x0b - strb r1, [r0] -#endif - - /* Pin muxing for SDRC */ - mov r1, #0x00 - ldr r0, =0x480000A1 /* ball C12, mode 0 */ - strb r1, [r0] - - ldr r0, =0x48000032 /* ball D11, mode 0 */ - strb r1, [r0] - - ldr r0, =0x480000A3 /* ball B13, mode 0 */ - strb r1, [r0] - - /* SDRC setting */ - ldr r0, =OMAP2420_SDRC_BASE - ldr r1, =0x00000010 - str r1, [r0, #0x10] - - ldr r1, =0x00000100 - str r1, [r0, #0x44] - - /* SDRC CS0 configuration */ -#ifdef CONFIG_APOLLON_PLUS - ldr r1, =0x01702011 -#else - ldr r1, =0x00d04011 -#endif - str r1, [r0, #0x80] - - ldr r1, =SDRC_ACTIM_CTRLA_0_VAL - str r1, [r0, #0x9C] - - ldr r1, =SDRC_ACTIM_CTRLB_0_VAL - str r1, [r0, #0xA0] - - ldr r1, =SDRC_RFR_CTRL_0_VAL - str r1, [r0, #0xA4] - - ldr r1, =0x00000041 - str r1, [r0, #0x70] - - /* Manual command sequence */ - ldr r1, =0x00000007 - str r1, [r0, #0xA8] - - ldr r1, =0x00000000 - str r1, [r0, #0xA8] - - ldr r1, =0x00000001 - str r1, [r0, #0xA8] - - ldr r1, =0x00000002 - str r1, [r0, #0xA8] - str r1, [r0, #0xA8] - - /* - * CS0 SDRC Mode register - * Burst length = 4 - DDR memory - * Serial mode - * CAS latency = 3 - */ - ldr r1, =0x00000032 - str r1, [r0, #0x84] - - /* Note: You MUST set EMR values */ - /* EMR1 & EMR2 */ - ldr r1, =0x00000000 - str r1, [r0, #0x88] - str r1, [r0, #0x8C] - -#ifdef OLD_SDRC_DLLA_CTRL - /* SDRC_DLLA_CTRL */ - ldr r1, =0x00007306 - str r1, [r0, #0x60] - - ldr r1, =0x00007303 - str r1, [r0, #0x60] -#else - /* SDRC_DLLA_CTRL */ - ldr r1, =0x00000506 - str r1, [r0, #0x60] - - ldr r1, =0x00000503 - str r1, [r0, #0x60] -#endif - -#ifdef __BROKEN_FEATURE__ - /* SDRC_DLLB_CTRL */ - ldr r1, =0x00000506 - str r1, [r0, #0x68] - - ldr r1, =0x00000503 - str r1, [r0, #0x68] -#endif - - /* little delay after init */ - mov r2, #0x1800 -1: - subs r2, r2, #0x1 - bne 1b - - ldr sp, SRAM_STACK - str ip, [sp] /* stash old link register */ - mov ip, lr /* save link reg across call */ - mov r0, r3 /* pass skip info to s_init */ - - bl s_init /* go setup pll,mux,memory */ - - ldr ip, [sp] /* restore save ip */ - mov lr, ip /* restore link reg */ - - /* back to arch calling code */ - mov pc, lr - - /* the literal pools origin */ - .ltorg - -SRAM_STACK: - .word LOW_LEVEL_SRAM_STACK diff --git a/onenand_ipl/onenand_read.c b/onenand_ipl/onenand_read.c deleted file mode 100644 index 8d0df81..0000000 --- a/onenand_ipl/onenand_read.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * (C) Copyright 2005-2009 Samsung Electronics - * Kyungmin Park <kyungmin.park@samsung.com> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> - -#include <asm/io.h> -#include <asm/string.h> - -#include "onenand_ipl.h" - -#define onenand_block_address(block) (block) -#define onenand_sector_address(page) (page << 2) -#define onenand_buffer_address() ((1 << 3) << 8) -#define onenand_bufferram_address(block) (0) - -#ifdef __HAVE_ARCH_MEMCPY32 -extern void *memcpy32(void *dest, void *src, int size); -#endif - -int (*onenand_read_page)(ulong block, ulong page, u_char *buf, int pagesize); - -/* read a page with ECC */ -static int generic_onenand_read_page(ulong block, ulong page, - u_char * buf, int pagesize) -{ - unsigned long *base; - -#ifndef __HAVE_ARCH_MEMCPY32 - unsigned int offset, value; - unsigned long *p; -#endif - - onenand_writew(onenand_block_address(block), - ONENAND_REG_START_ADDRESS1); - - onenand_writew(onenand_bufferram_address(block), - ONENAND_REG_START_ADDRESS2); - - onenand_writew(onenand_sector_address(page), - ONENAND_REG_START_ADDRESS8); - - onenand_writew(onenand_buffer_address(), - ONENAND_REG_START_BUFFER); - - onenand_writew(ONENAND_INT_CLEAR, ONENAND_REG_INTERRUPT); - - onenand_writew(ONENAND_CMD_READ, ONENAND_REG_COMMAND); - -#ifndef __HAVE_ARCH_MEMCPY32 - p = (unsigned long *) buf; -#endif - base = (unsigned long *) (CONFIG_SYS_ONENAND_BASE + ONENAND_DATARAM); - - while (!(READ_INTERRUPT() & ONENAND_INT_READ)) - continue; - - /* Check for invalid block mark */ - if (page < 2 && (onenand_readw(ONENAND_SPARERAM) != 0xffff)) - return 1; - -#ifdef __HAVE_ARCH_MEMCPY32 - /* 32 bytes boundary memory copy */ - memcpy32(buf, base, pagesize); -#else - for (offset = 0; offset < (pagesize >> 2); offset++) { - value = *(base + offset); - *p++ = value; - } -#endif - - return 0; -} - -#ifndef CONFIG_ONENAND_START_PAGE -#define CONFIG_ONENAND_START_PAGE 1 -#endif -#define ONENAND_PAGES_PER_BLOCK 64 - -static void onenand_generic_init(int *page_is_4KiB, int *page) -{ - int dev_id, density; - - if (onenand_readw(ONENAND_REG_TECHNOLOGY)) - *page_is_4KiB = 1; - dev_id = onenand_readw(ONENAND_REG_DEVICE_ID); - density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; - density &= ONENAND_DEVICE_DENSITY_MASK; - if (density >= ONENAND_DEVICE_DENSITY_4Gb && - !(dev_id & ONENAND_DEVICE_IS_DDP)) - *page_is_4KiB = 1; -} - -/** - * onenand_read_block - Read CONFIG_SYS_MONITOR_LEN from begining - * of OneNAND, skipping bad blocks - * @return 0 on success - */ -int onenand_read_block(unsigned char *buf) -{ - int block, nblocks; - int page = CONFIG_ONENAND_START_PAGE, offset = 0; - int pagesize, erasesize, erase_shift; - int page_is_4KiB = 0; - - onenand_read_page = generic_onenand_read_page; - - onenand_generic_init(&page_is_4KiB, &page); - - if (page_is_4KiB) { - pagesize = 4096; /* OneNAND has 4KiB pagesize */ - erase_shift = 18; - } else { - pagesize = 2048; /* OneNAND has 2KiB pagesize */ - erase_shift = 17; - } - - erasesize = (1 << erase_shift); - nblocks = (CONFIG_SYS_MONITOR_LEN + erasesize - 1) >> erase_shift; - - /* NOTE: you must read page from page 1 of block 0 */ - /* read the block page by page */ - for (block = 0; block < nblocks; block++) { - for (; page < ONENAND_PAGES_PER_BLOCK; page++) { - if (onenand_read_page(block, page, buf + offset, - pagesize)) { - /* This block is bad. Skip it - * and read next block */ - offset -= page * pagesize; - nblocks++; - break; - } - offset += pagesize; - } - page = 0; - } - - return 0; -} diff --git a/spl/Makefile b/spl/Makefile index 476a5e6..d9b1c2f 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -41,6 +41,7 @@ endif LIBS-y += board/$(BOARDDIR)/lib$(BOARD).o LIBS-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/lib$(VENDOR).o +LIBS-$(CONFIG_SPL_FRAMEWORK) += common/spl/libspl.o LIBS-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/libcommon.o LIBS-$(CONFIG_SPL_LIBDISK_SUPPORT) += disk/libdisk.o LIBS-$(CONFIG_SPL_I2C_SUPPORT) += drivers/i2c/libi2c.o @@ -135,9 +136,7 @@ $(obj)u-boot-spl.bin: $(obj)u-boot-spl $(OBJCOPY) $(OBJCFLAGS) -O binary $< $@ GEN_UBOOT = \ - UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) | \ - sed -n -e 's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\ - cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) $$UNDEF_SYM $(__START) \ + cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) $(__START) \ --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \ -Map u-boot-spl.map -o u-boot-spl diff --git a/tools/Makefile b/tools/Makefile index a7d1e18..c31437e 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -92,6 +92,7 @@ OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o NOPED_OBJ_FILES-y += aisimage.o NOPED_OBJ_FILES-y += kwbimage.o +NOPED_OBJ_FILES-y += pblimage.o NOPED_OBJ_FILES-y += imximage.o NOPED_OBJ_FILES-y += omapimage.o NOPED_OBJ_FILES-y += mkenvimage.o @@ -208,6 +209,7 @@ $(obj)mkimage$(SFX): $(obj)aisimage.o \ $(obj)image.o \ $(obj)imximage.o \ $(obj)kwbimage.o \ + $(obj)pblimage.o \ $(obj)md5.o \ $(obj)mkimage.o \ $(obj)os_support.o \ diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index e292d2b..1a2c227 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -203,6 +203,17 @@ static char default_environment[] = { #if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0) "pcidelay=" MK_STR (CONFIG_PCI_BOOTDELAY) "\0" #endif +#ifdef CONFIG_ENV_VARS_UBOOT_CONFIG + "arch=" CONFIG_SYS_ARCH "\0" + "cpu=" CONFIG_SYS_CPU "\0" + "board=" CONFIG_SYS_BOARD "\0" +#ifdef CONFIG_SYS_VENDOR + "vendor=" CONFIG_SYS_VENDOR "\0" +#endif +#ifdef CONFIG_SYS_SOC + "soc=" CONFIG_SYS_SOC "\0" +#endif +#endif #ifdef CONFIG_EXTRA_ENV_SETTINGS CONFIG_EXTRA_ENV_SETTINGS #endif diff --git a/tools/mkimage.c b/tools/mkimage.c index eeb1b10..e43b09f 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -39,6 +39,7 @@ struct mkimage_params params = { .comp = IH_COMP_GZIP, .dtc = MKIMAGE_DEFAULT_DTC_OPTIONS, .imagename = "", + .imagename2 = "", }; /* @@ -150,6 +151,8 @@ main (int argc, char **argv) int retval = 0; struct image_type_params *tparams = NULL; + /* Init Freescale PBL Boot image generation/list support */ + init_pbl_image_type(); /* Init Kirkwood Boot image generation/list support */ init_kwb_image_type (); /* Init Freescale imx Boot image generation/list support */ @@ -250,6 +253,15 @@ main (int argc, char **argv) usage (); params.imagename = *++argv; goto NXTARG; + case 'R': + if (--argc <= 0) + usage(); + /* + * This entry is for the second configuration + * file, if only one is not enough. + */ + params.imagename2 = *++argv; + goto NXTARG; case 's': params.skipcpy = 1; break; @@ -440,6 +452,9 @@ NXTARG: ; break; } } + } else if (params.type == IH_TYPE_PBLIMAGE) { + /* PBL has special Image format, implements its' own */ + pbl_load_uboot(ifd, ¶ms); } else { copy_file (ifd, params.datafile, 0); } diff --git a/tools/mkimage.h b/tools/mkimage.h index 5fe1a48..ea45f5c 100644 --- a/tools/mkimage.h +++ b/tools/mkimage.h @@ -69,6 +69,7 @@ struct mkimage_params { unsigned int addr; unsigned int ep; char *imagename; + char *imagename2; char *datafile; char *imagefile; char *cmdname; @@ -147,6 +148,8 @@ void mkimage_register (struct image_type_params *tparams); * * Supported image types init functions */ +void pbl_load_uboot(int fd, struct mkimage_params *mparams); +void init_pbl_image_type(void); void init_ais_image_type(void); void init_kwb_image_type (void); void init_imx_image_type (void); diff --git a/tools/netconsole b/tools/netconsole index c8109bb..1a0ef22 100755 --- a/tools/netconsole +++ b/tools/netconsole @@ -2,7 +2,7 @@ usage() { ( - echo "Usage: $0 <board IP> [board port]" + echo "Usage: $0 <board-IP> [board-port [board-in-port]]" echo "" echo "If port is not specified, '6666' will be used" [ -z "$*" ] && exit 0 @@ -24,9 +24,13 @@ while [ -n "$1" ] ; do done ip=$1 -port=${2:-6666} +board_out_port=${2:-6666} +board_in_port=${3:-${board_out_port}} -if [ -z "${ip}" ] || [ -n "$3" ] ; then +echo Board out port: ${board_out_port} +echo Board in port: ${board_in_port} + +if [ -z "${ip}" ] || [ -n "$4" ] ; then usage "Invalid number of arguments" fi @@ -41,19 +45,19 @@ stty -icanon -echo intr ^T ( if type ncb 2>/dev/null ; then # see if ncb is in $PATH - exec ncb ${port} + exec ncb ${board_out_port} elif [ -x ${0%/*}/ncb ] ; then # maybe it's in the same dir as the netconsole script - exec ${0%/*}/ncb ${port} + exec ${0%/*}/ncb ${board_out_port} else # blah, just use regular netcat - while ${nc} -u -l -p ${port} < /dev/null ; do + while ${nc} -u -l -p ${board_out_port} < /dev/null ; do : done fi ) & pid=$! -${nc} -u ${ip} ${port} +${nc} -u ${ip} ${board_in_port} kill ${pid} 2>/dev/null diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index be40af3..0503bac 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -36,6 +36,9 @@ re_remove = re.compile('^BUG=|^TEST=|^Change-Id:|^Review URL:' # Lines which are allowed after a TEST= line re_allowed_after_test = re.compile('^Signed-off-by:') +# Signoffs +re_signoff = re.compile('^Signed-off-by:') + # The start of the cover letter re_cover = re.compile('^Cover-letter:') @@ -43,7 +46,7 @@ re_cover = re.compile('^Cover-letter:') re_series = re.compile('^Series-(\w*): *(.*)') # Commit tags that we want to collect and keep -re_tag = re.compile('^(Tested-by|Acked-by|Signed-off-by|Cc): (.*)') +re_tag = re.compile('^(Tested-by|Acked-by|Cc): (.*)') # The start of a new commit in the git log re_commit = re.compile('^commit (.*)') @@ -207,8 +210,12 @@ class PatchStream: if is_blank: # Blank line ends this change list self.in_change = 0 + elif line == '---' or re_signoff.match(line): + self.in_change = 0 + out = self.ProcessLine(line) else: - self.series.AddChange(self.in_change, self.commit, line) + if self.is_log: + self.series.AddChange(self.in_change, self.commit, line) self.skip_blank = False # Detect Series-xxx tags @@ -234,15 +241,8 @@ class PatchStream: # Detect tags in the commit message elif tag_match: - # Onlly allow a single signoff tag - if tag_match.group(1) == 'Signed-off-by': - if self.signoff: - self.warn.append('Patch has more than one Signed-off-by ' - 'tag') - self.signoff += [line] - # Remove Tested-by self, since few will take much notice - elif (tag_match.group(1) == 'Tested-by' and + if (tag_match.group(1) == 'Tested-by' and tag_match.group(2).find(os.getenv('USER') + '@') != -1): self.warn.append("Ignoring %s" % line) elif tag_match.group(1) == 'Cc': @@ -281,8 +281,6 @@ class PatchStream: # Output the tags (signeoff first), then change list out = [] - if self.signoff: - out += self.signoff log = self.series.MakeChangeLog(self.commit) out += self.FormatTags(self.tags) out += [line] + log diff --git a/tools/patman/series.py b/tools/patman/series.py index 05d9e73..ce36b23 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -114,6 +114,13 @@ class Series(dict): cc_list += gitutil.BuildEmailList(commit.tags) cc_list += gitutil.BuildEmailList(commit.cc_list) + # Skip items in To list + if 'to' in self: + try: + map(cc_list.remove, gitutil.BuildEmailList(self.to)) + except ValueError: + pass + for email in cc_list: if email == None: email = col.Color(col.YELLOW, "<alias '%s' not found>" @@ -138,26 +145,25 @@ class Series(dict): Return: The change log as a list of strings, one per line + Changes in v2: + - Jog the dial back closer to the widget + Changes in v1: - Fix the widget - Jog the dial - Changes in v2: - - Jog the dial back closer to the widget - etc. """ final = [] need_blank = False - for change in sorted(self.changes): + for change in sorted(self.changes, reverse=True): out = [] for this_commit, text in self.changes[change]: if commit and this_commit != commit: continue - if text not in out: - out.append(text) + out.append(text) if out: - out = ['Changes in v%d:' % change] + sorted(out) + out = ['Changes in v%d:' % change] + out if need_blank: out = [''] + out final += out @@ -174,12 +180,13 @@ class Series(dict): col = terminal.Color() if self.get('version'): changes_copy = dict(self.changes) - for version in range(2, int(self.version) + 1): + for version in range(1, int(self.version) + 1): if self.changes.get(version): del changes_copy[version] else: - str = 'Change log missing for v%d' % version - print col.Color(col.RED, str) + if version > 1: + str = 'Change log missing for v%d' % version + print col.Color(col.RED, str) for version in changes_copy: str = 'Change log for unknown version v%d' % version print col.Color(col.RED, str) diff --git a/tools/pblimage.c b/tools/pblimage.c new file mode 100644 index 0000000..508a747 --- /dev/null +++ b/tools/pblimage.c @@ -0,0 +1,331 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#define _GNU_SOURCE + +#include "mkimage.h" +#include <image.h> +#include "pblimage.h" + +/* + * The PBL can load up to 64 bytes at a time, so we split the U-Boot + * image into 64 byte chunks. PBL needs a command for each piece, of + * the form "81xxxxxx", where "xxxxxx" is the offset. SYS_TEXT_BASE + * is 0xFFF80000 for PBL boot, and PBL only cares about low 24-bit, + * so it starts from 0x81F80000. + */ +static uint32_t next_pbl_cmd = 0x81F80000; +/* + * need to store all bytes in memory for calculating crc32, then write the + * bytes to image file for PBL boot. + */ +static unsigned char mem_buf[600000]; +static unsigned char *pmem_buf = mem_buf; +static int pbl_size; +static char *fname = "Unknown"; +static int lineno = -1; +static struct pbl_header pblimage_header; + +static union +{ + char c[4]; + unsigned char l; +} endian_test = { {'l', '?', '?', 'b'} }; + +#define ENDIANNESS ((char)endian_test.l) + +static void generate_pbl_cmd(void) +{ + uint32_t val = next_pbl_cmd; + next_pbl_cmd += 0x40; + int i; + + for (i = 3; i >= 0; i--) { + *pmem_buf++ = (val >> (i * 8)) & 0xff; + pbl_size++; + } +} + +static void pbl_fget(size_t size, FILE *stream) +{ + unsigned char c; + int c_temp; + + while (size && (c_temp = fgetc(stream)) != EOF) { + c = (unsigned char)c_temp; + *pmem_buf++ = c; + pbl_size++; + size--; + } +} + +/* load split u-boot with PBI command 81xxxxxx. */ +static void load_uboot(FILE *fp_uboot) +{ + while (next_pbl_cmd < 0x82000000) { + generate_pbl_cmd(); + pbl_fget(64, fp_uboot); + } +} + +static void check_get_hexval(char *token) +{ + uint32_t hexval; + int i; + + if (!sscanf(token, "%x", &hexval)) { + printf("Error:%s[%d] - Invalid hex data(%s)\n", fname, + lineno, token); + exit(EXIT_FAILURE); + } + for (i = 3; i >= 0; i--) { + *pmem_buf++ = (hexval >> (i * 8)) & 0xff; + pbl_size++; + } +} + +static void pbl_parser(char *name) +{ + FILE *fd = NULL; + char *line = NULL; + char *token, *saveptr1, *saveptr2; + size_t len = 0; + + fname = name; + fd = fopen(name, "r"); + if (fd == NULL) { + printf("Error:%s - Can't open\n", fname); + exit(EXIT_FAILURE); + } + + while ((getline(&line, &len, fd)) > 0) { + lineno++; + token = strtok_r(line, "\r\n", &saveptr1); + /* drop all lines with zero tokens (= empty lines) */ + if (token == NULL) + continue; + for (line = token;; line = NULL) { + token = strtok_r(line, " \t", &saveptr2); + if (token == NULL) + break; + /* Drop all text starting with '#' as comments */ + if (token[0] == '#') + break; + check_get_hexval(token); + } + } + if (line) + free(line); + fclose(fd); +} + +static uint32_t crc_table[256]; + +static void make_crc_table(void) +{ + uint32_t mask; + int i, j; + uint32_t poly; /* polynomial exclusive-or pattern */ + + /* + * the polynomial used by PBL is 1 + x1 + x2 + x4 + x5 + x7 + x8 + x10 + * + x11 + x12 + x16 + x22 + x23 + x26 + x32. + */ + poly = 0x04c11db7; + + for (i = 0; i < 256; i++) { + mask = i << 24; + for (j = 0; j < 8; j++) { + if (mask & 0x80000000) + mask = (mask << 1) ^ poly; + else + mask <<= 1; + } + crc_table[i] = mask; + } +} + +unsigned long pbl_crc32(unsigned long crc, const char *buf, uint32_t len) +{ + uint32_t crc32_val = 0xffffffff; + uint32_t xor = 0x0; + int i; + + make_crc_table(); + + for (i = 0; i < len; i++) + crc32_val = (crc32_val << 8) ^ + crc_table[(crc32_val >> 24) ^ (*buf++ & 0xff)]; + + crc32_val = crc32_val ^ xor; + if (crc32_val < 0) { + crc32_val += 0xffffffff; + crc32_val += 1; + } + return crc32_val; +} + +static uint32_t reverse_byte(uint32_t val) +{ + uint32_t temp; + unsigned char *p1; + int j; + + temp = val; + p1 = (unsigned char *)&temp; + for (j = 3; j >= 0; j--) + *p1++ = (val >> (j * 8)) & 0xff; + return temp; +} + +/* write end command and crc command to memory. */ +static void add_end_cmd(void) +{ + uint32_t pbl_end_cmd[4] = {0x09138000, 0x00000000, + 0x091380c0, 0x00000000}; + uint32_t crc32_pbl; + int i; + unsigned char *p = (unsigned char *)&pbl_end_cmd; + + if (ENDIANNESS == 'l') { + for (i = 0; i < 4; i++) + pbl_end_cmd[i] = reverse_byte(pbl_end_cmd[i]); + } + + for (i = 0; i < 16; i++) { + *pmem_buf++ = *p++; + pbl_size++; + } + + /* Add PBI CRC command. */ + *pmem_buf++ = 0x08; + *pmem_buf++ = 0x13; + *pmem_buf++ = 0x80; + *pmem_buf++ = 0x40; + pbl_size += 4; + + /* calculated CRC32 and write it to memory. */ + crc32_pbl = pbl_crc32(0, (const char *)mem_buf, pbl_size); + *pmem_buf++ = (crc32_pbl >> 24) & 0xff; + *pmem_buf++ = (crc32_pbl >> 16) & 0xff; + *pmem_buf++ = (crc32_pbl >> 8) & 0xff; + *pmem_buf++ = (crc32_pbl) & 0xff; + pbl_size += 4; + + if ((pbl_size % 16) != 0) { + for (i = 0; i < 8; i++) { + *pmem_buf++ = 0x0; + pbl_size++; + } + } + if ((pbl_size % 16 != 0)) { + printf("Error: Bad size of image file\n"); + exit(EXIT_FAILURE); + } +} + +void pbl_load_uboot(int ifd, struct mkimage_params *params) +{ + FILE *fp_uboot; + int size; + + /* parse the rcw.cfg file. */ + pbl_parser(params->imagename); + + /* parse the pbi.cfg file. */ + pbl_parser(params->imagename2); + + fp_uboot = fopen(params->datafile, "r"); + if (fp_uboot == NULL) { + printf("Error: %s open failed\n", params->datafile); + exit(EXIT_FAILURE); + } + + load_uboot(fp_uboot); + add_end_cmd(); + fclose(fp_uboot); + lseek(ifd, 0, SEEK_SET); + + size = pbl_size; + if (write(ifd, (const void *)&mem_buf, size) != size) { + fprintf(stderr, "Write error on %s: %s\n", + params->imagefile, strerror(errno)); + exit(EXIT_FAILURE); + } +} + +static int pblimage_check_image_types(uint8_t type) +{ + if (type == IH_TYPE_PBLIMAGE) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; +} + +static int pblimage_verify_header(unsigned char *ptr, int image_size, + struct mkimage_params *params) +{ + struct pbl_header *pbl_hdr = (struct pbl_header *) ptr; + + /* Only a few checks can be done: search for magic numbers */ + if (ENDIANNESS == 'l') { + if (pbl_hdr->preamble != reverse_byte(RCW_PREAMBLE)) + return -FDT_ERR_BADSTRUCTURE; + + if (pbl_hdr->rcwheader != reverse_byte(RCW_HEADER)) + return -FDT_ERR_BADSTRUCTURE; + } else { + if (pbl_hdr->preamble != RCW_PREAMBLE) + return -FDT_ERR_BADSTRUCTURE; + + if (pbl_hdr->rcwheader != RCW_HEADER) + return -FDT_ERR_BADSTRUCTURE; + } + return 0; +} + +static void pblimage_print_header(const void *ptr) +{ + printf("Image Type: Freescale PBL Boot Image\n"); +} + +static void pblimage_set_header(void *ptr, struct stat *sbuf, int ifd, + struct mkimage_params *params) +{ + /*nothing need to do, pbl_load_uboot takes care of whole file. */ +} + +/* pblimage parameters */ +static struct image_type_params pblimage_params = { + .name = "Freescale PBL Boot Image support", + .header_size = sizeof(struct pbl_header), + .hdr = (void *)&pblimage_header, + .check_image_type = pblimage_check_image_types, + .verify_header = pblimage_verify_header, + .print_header = pblimage_print_header, + .set_header = pblimage_set_header, +}; + +void init_pbl_image_type(void) +{ + pbl_size = 0; + mkimage_register(&pblimage_params); +} diff --git a/onenand_ipl/onenand_boot.c b/tools/pblimage.h index 22baebb..514a477 100644 --- a/onenand_ipl/onenand_boot.c +++ b/tools/pblimage.h @@ -1,8 +1,5 @@ /* - * (C) Copyright 2005-2008 Samsung Electronics - * Kyungmin Park <kyungmin.park@samsung.com> - * - * Derived from x-loader + * Copyright 2012 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -14,7 +11,7 @@ * * 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 + * 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 @@ -23,26 +20,17 @@ * MA 02111-1307 USA */ -#include <common.h> - -#include "onenand_ipl.h" - -typedef int (init_fnc_t)(void); - -void start_oneboot(void) -{ - uchar *buf; - - buf = (uchar *) CONFIG_SYS_LOAD_ADDR; - - onenand_read_block(buf); +#ifndef PBLIMAGE_H +#define PBLIMAGE_H - ((init_fnc_t *)CONFIG_SYS_LOAD_ADDR)(); +#define RCW_BYTES 64 +#define RCW_PREAMBLE 0xaa55aa55 +#define RCW_HEADER 0x010e0100 - /* should never come here */ -} +struct pbl_header { + uint32_t preamble; + uint32_t rcwheader; + uint8_t rcw_data[RCW_BYTES]; +}; -void hang(void) -{ - for (;;); -} +#endif /* PBLIMAGE_H */ |