diff options
author | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2015-05-05 10:09:06 +0200 |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2015-05-05 10:09:06 +0200 |
commit | b939689c7b87773c44275a578ffc8674a867e39d (patch) | |
tree | 785d71eb0bbc707385e4456a14b21706223d99a3 | |
parent | 97840b5d1fe0960134c3553a9d9d1c1cd1be784d (diff) | |
parent | ace97d26176a3ebc9ec07738450de93eea35975c (diff) | |
download | u-boot-imx-b939689c7b87773c44275a578ffc8674a867e39d.zip u-boot-imx-b939689c7b87773c44275a578ffc8674a867e39d.tar.gz u-boot-imx-b939689c7b87773c44275a578ffc8674a867e39d.tar.bz2 |
Merge branch 'u-boot/master' into 'u-boot-arm/master'
1039 files changed, 38648 insertions, 9982 deletions
diff --git a/Licenses/README b/Licenses/README index fe6dadc..731d45c 100644 --- a/Licenses/README +++ b/Licenses/README @@ -47,7 +47,7 @@ used under the terms of either of these licenses, i. e. with SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause -you can chose between GPL-2.0+ and BSD-3-Clause licensing. +you can choose between GPL-2.0+ and BSD-3-Clause licensing. We use the SPDX Unique License Identifiers here; these are available at [2]. @@ -67,3 +67,4 @@ BSD 3-clause "New" or "Revised" License BSD-3-Clause Y bsd-3-clause.txt http:/ IBM PIBS (PowerPC Initialization and IBM-pibs ibm-pibs.txt Boot Software) license ISC License ISC Y isc.txt https://spdx.org/licenses/ISC +X11 License X11 x11.txt https://spdx.org/licenses/X11.html diff --git a/Licenses/x11.txt b/Licenses/x11.txt new file mode 100644 index 0000000..23a3c63 --- /dev/null +++ b/Licenses/x11.txt @@ -0,0 +1,25 @@ +X11 License +Copyright (C) 1996 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X +CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings in +this Software without prior written authorization from the X Consortium. + +X Window System is a trademark of X Consortium, Inc. diff --git a/MAINTAINERS b/MAINTAINERS index 26d0d27..067fb22 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -328,10 +328,11 @@ T: git git://git.denx.de/u-boot-ppc4xx.git F: arch/powerpc/cpu/ppc4xx/ NETWORK -M: Joe Hershberger <joe.hershberger@gmail.com> +M: Joe Hershberger <joe.hershberger@ni.com> S: Maintained T: git git://git.denx.de/u-boot-net.git F: drivers/net/ +F: net/ NAND FLASH M: Scott Wood <scottwood@freescale.com> @@ -651,6 +651,7 @@ libs-$(CONFIG_FMAN_ENET) += drivers/net/fm/ libs-$(CONFIG_SYS_FSL_DDR) += drivers/ddr/fsl/ libs-y += drivers/serial/ libs-y += drivers/usb/dwc3/ +libs-y += drivers/usb/emul/ libs-y += drivers/usb/eth/ libs-y += drivers/usb/gadget/ libs-y += drivers/usb/gadget/udc/ @@ -728,7 +729,7 @@ DO_STATIC_RELA = endif # Always append ALL so that arch config.mk's can add custom ones -ALL-y += u-boot.srec u-boot.bin System.map binary_size_check +ALL-y += u-boot.srec u-boot.bin System.map u-boot.cfg binary_size_check ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin ifeq ($(CONFIG_SPL_FSL_PBL),y) @@ -870,6 +871,11 @@ ifndef CONFIG_SYS_UBOOT_START CONFIG_SYS_UBOOT_START := 0 endif +# Create a file containing the configuration options the image was built with +quiet_cmd_cpp_cfg = CFG $@ +cmd_cpp_cfg = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \ + -D__ASSEMBLY__ -x assembler-with-cpp -P -dM -E -o $@ $< + MKIMAGEFLAGS_u-boot.img = -A $(ARCH) -T firmware -C none -O u-boot \ -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \ -n "U-Boot $(UBOOTRELEASE) for $(BOARD) board" @@ -900,6 +906,9 @@ u-boot.sha1: u-boot.bin u-boot.dis: u-boot $(OBJDUMP) -d $< > $@ +u-boot.cfg: include/config.h + $(call if_changed,cpp_cfg) + ifdef CONFIG_TPL SPL_PAYLOAD := tpl/u-boot-with-tpl.bin else @@ -690,6 +690,14 @@ The following options need to be configured: exists, unlike the similar options in the Linux kernel. Do not set these options unless they apply! + COUNTER_FREQUENCY + Generic timer clock source frequency. + + COUNTER_FREQUENCY_REAL + Generic timer clock source frequency if the real clock is + different from COUNTER_FREQUENCY, and can only be determined + at run time. + NOTE: The following can be machine specific errata. These do have ability to provide rudimentary version and machine specific checks, but expect no product checks. @@ -1947,6 +1955,26 @@ CBFS (Coreboot Filesystem) support the console jump but can help speed up operation when scrolling is slow. + CONFIG_LCD_ROTATION + + Sometimes, for example if the display is mounted in portrait + mode or even if it's mounted landscape but rotated by 180degree, + we need to rotate our content of the display relative to the + framebuffer, so that user can read the messages which are + printed out. + Once CONFIG_LCD_ROTATION is defined, the lcd_console will be + initialized with a given rotation from "vl_rot" out of + "vidinfo_t" which is provided by the board specific code. + The value for vl_rot is coded as following (matching to + fbcon=rotate:<n> linux-kernel commandline): + 0 = no rotation respectively 0 degree + 1 = 90 degree rotation + 2 = 180 degree rotation + 3 = 270 degree rotation + + If CONFIG_LCD_ROTATION is not defined, the console will be + initialized with 0degree rotation. + CONFIG_LCD_BMP_RLE8 Support drawing of RLE8-compressed bitmaps on the LCD. @@ -2375,6 +2403,8 @@ CBFS (Coreboot Filesystem) support - define slave for bus 3 with CONFIG_SYS_MXC_I2C3_SLAVE If those defines are not set, default value is 100000 for speed, and 0 for slave. + - enable bus 3 with CONFIG_SYS_I2C_MXC_I2C3 + - enable bus 4 with CONFIG_SYS_I2C_MXC_I2C4 - drivers/i2c/rcar_i2c.c: - activate this driver with CONFIG_SYS_I2C_RCAR @@ -3066,17 +3096,6 @@ CBFS (Coreboot Filesystem) support memories can be connected with a given cs line. Currently Xilinx Zynq qspi supports these type of connections. - CONFIG_SYS_SPI_ST_ENABLE_WP_PIN - enable the W#/Vpp signal to disable writing to the status - register on ST MICRON flashes like the N25Q128. - The status register write enable/disable bit, combined with - the W#/VPP signal provides hardware data protection for the - device as follows: When the enable/disable bit is set to 1, - and the W#/VPP signal is driven LOW, the status register - nonvolatile bits become read-only and the WRITE STATUS REGISTER - operation will not execute. The only way to exit this - hardware-protected mode is to drive W#/VPP HIGH. - - SystemACE Support: CONFIG_SYSTEMACE @@ -3198,55 +3217,6 @@ CBFS (Coreboot Filesystem) support example, some LED's) on your board. At the moment, the following checkpoints are implemented: -- Detailed boot stage timing - CONFIG_BOOTSTAGE - Define this option to get detailed timing of each stage - of the boot process. - - CONFIG_BOOTSTAGE_USER_COUNT - This is the number of available user bootstage records. - Each time you call bootstage_mark(BOOTSTAGE_ID_ALLOC, ...) - a new ID will be allocated from this stash. If you exceed - the limit, recording will stop. - - CONFIG_BOOTSTAGE_REPORT - Define this to print a report before boot, similar to this: - - Timer summary in microseconds: - Mark Elapsed Stage - 0 0 reset - 3,575,678 3,575,678 board_init_f start - 3,575,695 17 arch_cpu_init A9 - 3,575,777 82 arch_cpu_init done - 3,659,598 83,821 board_init_r start - 3,910,375 250,777 main_loop - 29,916,167 26,005,792 bootm_start - 30,361,327 445,160 start_kernel - - CONFIG_CMD_BOOTSTAGE - Add a 'bootstage' command which supports printing a report - and un/stashing of bootstage data. - - CONFIG_BOOTSTAGE_FDT - Stash the bootstage information in the FDT. A root 'bootstage' - node is created with each bootstage id as a child. Each child - has a 'name' property and either 'mark' containing the - mark time in microsecond, or 'accum' containing the - accumulated time for that bootstage id in microseconds. - For example: - - bootstage { - 154 { - name = "board_init_f"; - mark = <3575678>; - }; - 170 { - name = "lcd"; - accum = <33482>; - }; - }; - - Code in the Linux kernel can find this in /proc/devicetree. Legacy uImage format: @@ -3340,9 +3310,9 @@ Legacy uImage format: 65 net/eth.c Ethernet found. -80 common/cmd_net.c usage wrong - 80 common/cmd_net.c before calling NetLoop() - -81 common/cmd_net.c some error in NetLoop() occurred - 81 common/cmd_net.c NetLoop() back without error + 80 common/cmd_net.c before calling net_loop() + -81 common/cmd_net.c some error in net_loop() occurred + 81 common/cmd_net.c net_loop() back without error -82 common/cmd_net.c size == 0 (File with size 0 loaded) 82 common/cmd_net.c trying automatic boot 83 common/cmd_net.c running "source" command @@ -4911,6 +4881,9 @@ Low Level (hardware related) configuration options: - CONFIG_FSL_DDR_SYNC_REFRESH Enable sync of refresh for multiple controllers. +- CONFIG_FSL_DDR_BIST + Enable built-in memory test for Freescale DDR controllers. + - CONFIG_SYS_83XX_DDR_USES_CS0 Only for 83xx systems. If specified, then DDR should be configured using CS0 and CS1 instead of CS2 and CS3. diff --git a/api/api_net.c b/api/api_net.c index 7b3805e..04e4f4a 100644 --- a/api/api_net.c +++ b/api/api_net.c @@ -37,7 +37,7 @@ int dev_open_net(void *cookie) if (!dev_valid_net(cookie)) return API_ENODEV; - if (eth_init(gd->bd) < 0) + if (eth_init() < 0) return API_EIO; return 0; diff --git a/arch/Kconfig b/arch/Kconfig index 2ca5305..1102346 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -70,6 +70,12 @@ config SANDBOX select HAVE_GENERIC_BOARD select SYS_GENERIC_BOARD select SUPPORT_OF_CONTROL + select DM + select DM_SPI_FLASH + select DM_SERIAL + select DM_I2C + select DM_SPI + select DM_GPIO config SH bool "SuperH architecture" @@ -84,6 +90,9 @@ config X86 select HAVE_GENERIC_BOARD select SYS_GENERIC_BOARD select SUPPORT_OF_CONTROL + select DM + select DM_SERIAL + select DM_GPIO endchoice diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7ed0e20..00be305 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -33,6 +33,9 @@ config CPU_V7 bool select HAS_VBAR +config CPU_V7M + bool + config CPU_PXA bool @@ -47,6 +50,7 @@ config SYS_CPU default "arm1136" if CPU_ARM1136 default "arm1176" if CPU_ARM1176 default "armv7" if CPU_V7 + default "armv7m" if CPU_V7M default "pxa" if CPU_PXA default "sa1100" if CPU_SA1100 default "armv8" if ARM64 @@ -61,18 +65,6 @@ config SEMIHOSTING choice prompt "Target select" -config TARGET_INTEGRATORAP_CM720T - bool "Support integratorap_cm720t" - select CPU_ARM720T - -config TARGET_INTEGRATORAP_CM920T - bool "Support integratorap_cm920t" - select CPU_ARM920T - -config TARGET_INTEGRATORCP_CM920T - bool "Support integratorcp_cm920t" - select CPU_ARM920T - config ARCH_AT91 bool "Atmel AT91" @@ -92,14 +84,6 @@ config TARGET_SMDK2410 bool "Support smdk2410" select CPU_ARM920T -config TARGET_INTEGRATORAP_CM926EJS - bool "Support integratorap_cm926ejs" - select CPU_ARM926EJS - -config TARGET_INTEGRATORCP_CM926EJS - bool "Support integratorcp_cm926ejs" - select CPU_ARM926EJS - config TARGET_ASPENITE bool "Support aspenite" select CPU_ARM926EJS @@ -235,6 +219,8 @@ config TARGET_SPEAR600 config TARGET_STV0991 bool "Support stv0991" select CPU_V7 + select DM + select DM_SERIAL config TARGET_X600 bool "Support x600" @@ -245,10 +231,6 @@ config ARCH_VERSATILE bool "ARM Ltd. Versatile family" select CPU_ARM926EJS -config TARGET_INTEGRATORCP_CM1136 - bool "Support integratorcp_cm1136" - select CPU_ARM1136 - config TARGET_IMX31_PHYCORE bool "Support imx31_phycore" select CPU_ARM1136 @@ -293,14 +275,9 @@ config TARGET_MX35PDK config ARCH_BCM283X bool "Broadcom BCM283X family" - -config TARGET_INTEGRATORAP_CM946ES - bool "Support integratorap_cm946es" - select CPU_ARM946ES - -config TARGET_INTEGRATORCP_CM946ES - bool "Support integratorcp_cm946es" - select CPU_ARM946ES + select DM + select DM_SERIAL + select DM_GPIO config TARGET_VEXPRESS_CA15_TC2 bool "Support vexpress_ca15_tc2" @@ -330,21 +307,33 @@ config TARGET_CM_T335 bool "Support cm_t335" select CPU_V7 select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO config TARGET_PEPPER bool "Support pepper" select CPU_V7 select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO config TARGET_AM335X_IGEP0033 bool "Support am335x_igep0033" select CPU_V7 select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO config TARGET_PCM051 bool "Support pcm051" select CPU_V7 select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO config TARGET_DRACO bool "Support draco" @@ -370,11 +359,17 @@ config TARGET_PENGWYN bool "Support pengwyn" select CPU_V7 select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO config TARGET_AM335X_EVM bool "Support am335x_evm" select CPU_V7 select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO config TARGET_AM43XX_EVM bool "Support am43xx_evm" @@ -385,6 +380,8 @@ config TARGET_BAV335X bool "Support bav335x" select CPU_V7 select SUPPORT_SPL + select DM + select DM_SERIAL help The BAV335x OEM Network Processor integrates all the functions of an embedded network computer in a small, easy to use SODIMM module which @@ -419,15 +416,26 @@ config TARGET_BCMNSP config ARCH_EXYNOS bool "Samsung EXYNOS" select CPU_V7 + select DM + select DM_SPI_FLASH + select DM_SERIAL + select DM_SPI + select DM_GPIO config ARCH_S5PC1XX bool "Samsung S5PC1XX" select CPU_V7 + select DM + select DM_SERIAL + select DM_GPIO config ARCH_HIGHBANK bool "Calxeda Highbank" select CPU_V7 +config ARCH_INTEGRATOR + bool "ARM Ltd. Integrator family" + config ARCH_KEYSTONE bool "TI Keystone" select CPU_V7 @@ -517,11 +525,20 @@ config TARGET_MX6QARM2 config TARGET_MX6QSABREAUTO bool "Support mx6qsabreauto" select CPU_V7 + select DM + select DM_THERMAL config TARGET_MX6SABRESD bool "Support mx6sabresd" select CPU_V7 select SUPPORT_SPL + select DM + select DM_THERMAL + +config TARGET_MX6CUBOXI + bool "Support Solid-run mx6 boards" + select CPU_V7 + select SUPPORT_SPL config TARGET_MX6SLEVK bool "Support mx6slevk" @@ -531,6 +548,8 @@ config TARGET_MX6SXSABRESD bool "Support mx6sxsabresd" select CPU_V7 select SUPPORT_SPL + select DM + select DM_THERMAL config TARGET_GW_VENTANA bool "Support gw_ventana" @@ -591,16 +610,25 @@ config TARGET_CM_FX6 bool "Support cm_fx6" select CPU_V7 select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO config TARGET_SOCFPGA_ARRIA5 bool "Support socfpga_arria5" select CPU_V7 select SUPPORT_SPL + select DM + select DM_SPI_FLASH + select DM_SPI config TARGET_SOCFPGA_CYCLONE5 bool "Support socfpga_cyclone5" select CPU_V7 select SUPPORT_SPL + select DM + select DM_SPI_FLASH + select DM_SPI config ARCH_SUNXI bool "Support sunxi (Allwinner) SoCs" @@ -617,10 +645,15 @@ config TARGET_VF610TWR bool "Support vf610twr" select CPU_V7 -config ZYNQ +config TARGET_COLIBRI_VF + bool "Support Colibri VF50/61" + select CPU_V7 + +config ARCH_ZYNQ bool "Xilinx Zynq Platform" select CPU_V7 select SUPPORT_SPL + select DM config TARGET_XILINX_ZYNQMP bool "Support Xilinx ZynqMP Platform" @@ -632,6 +665,12 @@ config TEGRA select SPL select OF_CONTROL select CPU_V7 + select DM + select DM_SPI_FLASH + select DM_SERIAL + select DM_I2C + select DM_SPI + select DM_GPIO config TARGET_VEXPRESS64_AEMV8A bool "Support vexpress_aemv8a" @@ -656,6 +695,28 @@ config TARGET_LS2085A_SIMU select ARM64 select ARMV8_MULTIENTRY +config TARGET_LS2085AQDS + bool "Support ls2085aqds" + select ARM64 + select ARMV8_MULTIENTRY + select SUPPORT_SPL + help + Support for Freescale LS2085AQDS platform + The LS2085A Development System (QDS) is a high-performance + development platform that supports the QorIQ LS2085A + Layerscape Architecture processor. + +config TARGET_LS2085ARDB + bool "Support ls2085ardb" + select ARM64 + select ARMV8_MULTIENTRY + select SUPPORT_SPL + help + Support for Freescale LS2085ARDB platform. + The LS2085A Reference design board (RDB) is a high-performance + development platform that supports the QorIQ LS2085A + Layerscape Architecture processor. + config TARGET_LS1021AQDS bool "Support ls1021aqds" select CPU_V7 @@ -726,6 +787,13 @@ config ARCH_UNIPHIER select SUPPORT_SPL select SPL select OF_CONTROL + select DM + select DM_SERIAL + select DM_I2C + +config TARGET_STM32F429_DISCOVERY + bool "Support STM32F429 Discovery" + select CPU_V7M endchoice @@ -739,6 +807,8 @@ source "arch/arm/cpu/armv7/exynos/Kconfig" source "arch/arm/mach-highbank/Kconfig" +source "arch/arm/mach-integrator/Kconfig" + source "arch/arm/mach-keystone/Kconfig" source "arch/arm/mach-kirkwood/Kconfig" @@ -767,7 +837,7 @@ source "arch/arm/mach-uniphier/Kconfig" source "arch/arm/mach-versatile/Kconfig" -source "arch/arm/cpu/armv7/zynq/Kconfig" +source "arch/arm/mach-zynq/Kconfig" source "arch/arm/cpu/armv7/Kconfig" @@ -784,7 +854,6 @@ source "board/Marvell/db-mv784mp-gp/Kconfig" source "board/Marvell/gplugd/Kconfig" source "board/altera/socfpga/Kconfig" source "board/armadeus/apf27/Kconfig" -source "board/armltd/integrator/Kconfig" source "board/armltd/vexpress/Kconfig" source "board/armltd/vexpress64/Kconfig" source "board/bachmann/ot1200/Kconfig" @@ -807,6 +876,8 @@ source "board/denx/m53evk/Kconfig" source "board/embest/mx6boards/Kconfig" source "board/esg/ima3-mx53/Kconfig" source "board/freescale/ls2085a/Kconfig" +source "board/freescale/ls2085aqds/Kconfig" +source "board/freescale/ls2085ardb/Kconfig" source "board/freescale/ls1021aqds/Kconfig" source "board/freescale/ls1021atwr/Kconfig" source "board/freescale/mx23evk/Kconfig" @@ -856,6 +927,7 @@ source "board/siemens/draco/Kconfig" source "board/siemens/pxm2/Kconfig" source "board/siemens/rut/Kconfig" source "board/silica/pengwyn/Kconfig" +source "board/solidrun/mx6cuboxi/Kconfig" source "board/solidrun/hummingboard/Kconfig" source "board/spear/spear300/Kconfig" source "board/spear/spear310/Kconfig" @@ -864,6 +936,7 @@ source "board/spear/spear600/Kconfig" source "board/spear/x600/Kconfig" source "board/st-ericsson/snowball/Kconfig" source "board/st-ericsson/u8500/Kconfig" +source "board/st/stm32f429-discovery/Kconfig" source "board/st/stv0991/Kconfig" source "board/sunxi/Kconfig" source "board/syteco/zmx25/Kconfig" @@ -875,6 +948,7 @@ source "board/ti/ti814x/Kconfig" source "board/ti/ti816x/Kconfig" source "board/timll/devkit3250/Kconfig" source "board/toradex/colibri_pxa270/Kconfig" +source "board/toradex/colibri_vf/Kconfig" source "board/tqc/tqma6/Kconfig" source "board/trizepsiv/Kconfig" source "board/ttcontrol/vision2/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index bd4749c..2a5620d 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -55,6 +55,7 @@ machine-$(CONFIG_ORION5X) += orion5x machine-$(CONFIG_TEGRA) += tegra machine-$(CONFIG_ARCH_UNIPHIER) += uniphier machine-$(CONFIG_ARCH_VERSATILE) += versatile +machine-$(CONFIG_ARCH_ZYNQ) += zynq machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) diff --git a/arch/arm/cpu/arm720t/start.S b/arch/arm/cpu/arm720t/start.S index ec8e88d..0bb3441 100644 --- a/arch/arm/cpu/arm720t/start.S +++ b/arch/arm/cpu/arm720t/start.S @@ -9,7 +9,6 @@ #include <asm-offsets.h> #include <config.h> -#include <asm/hardware.h> /* ************************************************************************* diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index d7956e5..eb8669b 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c @@ -49,13 +49,6 @@ static const iomux_cfg_t iomux_boot[] = { MX23_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD, MX23_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD, MX23_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD, -#elif defined(CONFIG_MX28) - MX28_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD, - MX28_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD, #endif }; @@ -65,10 +58,10 @@ static uint8_t mxs_get_bootmode_index(void) int i; uint8_t masked; +#if defined(CONFIG_MX23) /* Setup IOMUX of bootmode pads to GPIO */ mxs_iomux_setup_multiple_pads(iomux_boot, ARRAY_SIZE(iomux_boot)); -#if defined(CONFIG_MX23) /* Setup bootmode pins as GPIO input */ gpio_direction_input(MX23_PAD_LCD_D00__GPIO_1_0); gpio_direction_input(MX23_PAD_LCD_D01__GPIO_1_1); @@ -83,21 +76,11 @@ static uint8_t mxs_get_bootmode_index(void) bootmode |= (gpio_get_value(MX23_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3; bootmode |= (gpio_get_value(MX23_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5; #elif defined(CONFIG_MX28) - /* Setup bootmode pins as GPIO input */ - gpio_direction_input(MX28_PAD_LCD_D00__GPIO_1_0); - gpio_direction_input(MX28_PAD_LCD_D01__GPIO_1_1); - gpio_direction_input(MX28_PAD_LCD_D02__GPIO_1_2); - gpio_direction_input(MX28_PAD_LCD_D03__GPIO_1_3); - gpio_direction_input(MX28_PAD_LCD_D04__GPIO_1_4); - gpio_direction_input(MX28_PAD_LCD_D05__GPIO_1_5); - - /* Read bootmode pads */ - bootmode |= (gpio_get_value(MX28_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D04__GPIO_1_4) ? 1 : 0) << 4; - bootmode |= (gpio_get_value(MX28_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5; + /* The global boot mode will be detected by ROM code and its value + * is stored at the fixed address 0x00019BF0 in OCRAM. + */ +#define GLOBAL_BOOT_MODE_ADDR 0x00019BF0 + bootmode = __raw_readl(GLOBAL_BOOT_MODE_ADDR); #endif for (i = 0; i < ARRAY_SIZE(mxs_boot_modes); i++) { diff --git a/arch/arm/cpu/arm926ejs/spear/cpu.c b/arch/arm/cpu/arm926ejs/spear/cpu.c index 697e094..1ce9db7 100644 --- a/arch/arm/cpu/arm926ejs/spear/cpu.c +++ b/arch/arm/cpu/arm926ejs/spear/cpu.c @@ -32,7 +32,7 @@ int arch_cpu_init(void) periph_clk_cfg |= CONFIG_SPEAR_UART48M; writel(periph_clk_cfg, &misc_p->periph_clk_cfg); #endif -#if defined(CONFIG_DESIGNWARE_ETH) +#if defined(CONFIG_ETH_DESIGNWARE) periph1_clken |= MISC_ETHENB; #endif #if defined(CONFIG_DW_UDC) diff --git a/arch/arm/cpu/arm946es/cpu.c b/arch/arm/cpu/arm946es/cpu.c index e20e5a8..5d864b9 100644 --- a/arch/arm/cpu/arm946es/cpu.c +++ b/arch/arm/cpu/arm946es/cpu.c @@ -53,7 +53,7 @@ static void cache_flush (void) asm ("mcr p15, 0, %0, c7, c6, 0": :"r" (i)); } -#ifndef CONFIG_INTEGRATOR +#ifndef CONFIG_ARCH_INTEGRATOR __attribute__((noreturn)) void reset_cpu(ulong addr __attribute__((unused))) { @@ -63,4 +63,4 @@ __attribute__((noreturn)) void reset_cpu(ulong addr __attribute__((unused))) ; } -#endif /* #ifdef CONFIG_INTEGRATOR */ +#endif /* #ifdef CONFIG_ARCH_INTEGRATOR */ diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 21fc03b..fcccd0c 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -12,7 +12,7 @@ obj-y += cache_v7.o obj-y += cpu.o cp15.o obj-y += syslib.o -ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY)$(CONFIG_SUNXI),) +ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY)$(CONFIG_SUNXI)$(CONFIG_SOCFPGA),) ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y) obj-y += lowlevel_init.o endif @@ -56,4 +56,3 @@ obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_U8500) += u8500/ obj-$(CONFIG_VF610) += vf610/ -obj-$(CONFIG_ZYNQ) += zynq/ diff --git a/arch/arm/cpu/armv7/exynos/Kconfig b/arch/arm/cpu/armv7/exynos/Kconfig index bd7540a..f6084ac 100644 --- a/arch/arm/cpu/armv7/exynos/Kconfig +++ b/arch/arm/cpu/armv7/exynos/Kconfig @@ -65,19 +65,7 @@ endchoice config SYS_SOC default "exynos" -config DM - default y - -config DM_SERIAL - default y - -config DM_SPI - default y - -config DM_SPI_FLASH - default y - -config DM_GPIO +config DM_USB default y source "board/samsung/smdkv310/Kconfig" diff --git a/arch/arm/cpu/armv7/ls102xa/clock.c b/arch/arm/cpu/armv7/ls102xa/clock.c index 8f80c61..7a337e1 100644 --- a/arch/arm/cpu/armv7/ls102xa/clock.c +++ b/arch/arm/cpu/armv7/ls102xa/clock.c @@ -20,7 +20,7 @@ void get_sys_info(struct sys_info *sys_info) { struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); #ifdef CONFIG_FSL_IFC - struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR; + struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL}; u32 ccr; #endif struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_LS1_CLK_ADDR); @@ -74,7 +74,7 @@ void get_sys_info(struct sys_info *sys_info) } #if defined(CONFIG_FSL_IFC) - ccr = in_be32(&ifc_regs->ifc_ccr); + ccr = in_be32(&ifc_regs.gregs->ifc_ccr); ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1; sys_info->freq_localbus = sys_info->freq_systembus / ccr; diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c index fef2231..653d58e 100644 --- a/arch/arm/cpu/armv7/mx6/ddr.c +++ b/arch/arm/cpu/armv7/mx6/ddr.c @@ -514,17 +514,21 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, /* MR2 */ val = (sysinfo->rtt_wr & 3) << 9 | (ddr3_cfg->SRT & 1) << 7 | ((tcwl - 3) & 3) << 3; + debug("MR2 CS%d: 0x%08x\n", cs, (u32)MR(val, 2, 3, cs)); mmdc0->mdscr = MR(val, 2, 3, cs); /* MR3 */ + debug("MR3 CS%d: 0x%08x\n", cs, (u32)MR(0, 3, 3, cs)); mmdc0->mdscr = MR(0, 3, 3, cs); /* MR1 */ val = ((sysinfo->rtt_nom & 1) ? 1 : 0) << 2 | ((sysinfo->rtt_nom & 2) ? 1 : 0) << 6; + debug("MR1 CS%d: 0x%08x\n", cs, (u32)MR(val, 1, 3, cs)); mmdc0->mdscr = MR(val, 1, 3, cs); /* MR0 */ val = ((tcl - 1) << 4) | /* CAS */ (1 << 8) | /* DLL Reset */ ((twr - 3) << 9); /* Write Recovery */ + debug("MR0 CS%d: 0x%08x\n", cs, (u32)MR(val, 0, 3, cs)); mmdc0->mdscr = MR(val, 0, 3, cs); /* ZQ calibration */ val = (1 << 10); @@ -535,10 +539,11 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, mmdc0->mdpdc = (tcke & 0x7) << 16 | 5 << 12 | /* PWDT_1: 256 cycles */ 5 << 8 | /* PWDT_0: 256 cycles */ - 1 << 7 | /* SLOW_PD */ 1 << 6 | /* BOTH_CS_PD */ (tcksrx & 0x7) << 3 | (tcksre & 0x7); + if (!sysinfo->pd_fast_exit) + mmdc0->mdpdc |= (1 << 7); /* SLOW_PD */ mmdc0->mapsr = 0x00001006; /* ADOPT power down enabled */ /* Step 11: Configure ZQ calibration: one-time and periodic 1ms */ diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index 17500f2..bbc6bed 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -159,6 +159,16 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) #ifdef CONFIG_SCSI_AHCI_PLAT void arch_preboot_os(void) { - ahci_reset(DWC_AHSATA_BASE); + ahci_reset((void __iomem *)DWC_AHSATA_BASE); +} +#endif + +#if defined(CONFIG_CMD_FASTBOOT) && !defined(CONFIG_ENV_IS_NOWHERE) +int fb_set_reboot_flag(void) +{ + printf("Setting reboot to fastboot flag ...\n"); + setenv("dofastboot", "1"); + saveenv(); + return 0; } #endif diff --git a/arch/arm/cpu/armv7/omap-common/sata.c b/arch/arm/cpu/armv7/omap-common/sata.c index d18bc50..2c2d1bc 100644 --- a/arch/arm/cpu/armv7/omap-common/sata.c +++ b/arch/arm/cpu/armv7/omap-common/sata.c @@ -69,7 +69,7 @@ int init_sata(int dev) val = TI_SATA_IDLE_NO | TI_SATA_STANDBY_NO; writel(val, TI_SATA_WRAPPER_BASE + TI_SATA_SYSCONFIG); - ret = ahci_init(DWC_AHSATA_BASE); + ret = ahci_init((void __iomem *)DWC_AHSATA_BASE); return ret; } @@ -88,6 +88,6 @@ void scsi_init(void) void scsi_bus_reset(void) { - ahci_reset(DWC_AHSATA_BASE); - ahci_init(DWC_AHSATA_BASE); + ahci_reset((void __iomem *)DWC_AHSATA_BASE); + ahci_init((void __iomem *)DWC_AHSATA_BASE); } diff --git a/arch/arm/cpu/armv7/omap-common/utils.c b/arch/arm/cpu/armv7/omap-common/utils.c index 1696c2d..df5f817 100644 --- a/arch/arm/cpu/armv7/omap-common/utils.c +++ b/arch/arm/cpu/armv7/omap-common/utils.c @@ -60,3 +60,16 @@ void __weak usb_fake_mac_from_die_id(u32 *id) eth_setenv_enetaddr("usbethaddr", device_mac); } } + +void __weak usb_set_serial_num_from_die_id(u32 *id) +{ + char serialno[72]; + uint32_t serialno_lo, serialno_hi; + + if (!getenv("serial#")) { + serialno_hi = id[0]; + serialno_lo = id[1]; + sprintf(serialno, "%08x%08x", serialno_hi, serialno_lo); + setenv("serial#", serialno); + } +} diff --git a/arch/arm/cpu/armv7/omap3/Kconfig b/arch/arm/cpu/armv7/omap3/Kconfig index 1f96498..cc82c50 100644 --- a/arch/arm/cpu/armv7/omap3/Kconfig +++ b/arch/arm/cpu/armv7/omap3/Kconfig @@ -17,6 +17,9 @@ config TARGET_OMAP3_SDP3430 config TARGET_OMAP3_BEAGLE bool "TI OMAP3 BeagleBoard" select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO config TARGET_CM_T35 bool "CompuLab CM-T3530 and CM-T3730 boards" @@ -28,6 +31,9 @@ config TARGET_CM_T3517 config TARGET_DEVKIT8000 bool "TimLL OMAP3 Devkit8000" select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO config TARGET_OMAP3_EVM bool "TI OMAP3 EVM" @@ -44,13 +50,22 @@ config TARGET_OMAP3_EVM_QUICK_NAND config TARGET_OMAP3_IGEP00X0 bool "IGEP" select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO config TARGET_OMAP3_OVERO bool "OMAP35xx Gumstix Overo" select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO config TARGET_OMAP3_ZOOM1 bool "TI Zoom1" + select DM + select DM_SERIAL + select DM_GPIO config TARGET_AM3517_CRANE bool "am3517_crane" @@ -94,18 +109,12 @@ config TARGET_TWISTER config TARGET_OMAP3_CAIRO bool "QUIPOS CAIRO" select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO endchoice -config DM - default y - -config DM_GPIO - default y if DM - -config DM_SERIAL - default y if DM - config SYS_SOC default "omap3" diff --git a/arch/arm/cpu/armv7/omap5/hw_data.c b/arch/arm/cpu/armv7/omap5/hw_data.c index e4abb25..868415d 100644 --- a/arch/arm/cpu/armv7/omap5/hw_data.c +++ b/arch/arm/cpu/armv7/omap5/hw_data.c @@ -460,7 +460,7 @@ void enable_basic_clocks(void) (*prcm)->cm_l4per_gpio6_clkctrl, (*prcm)->cm_l4per_gpio7_clkctrl, (*prcm)->cm_l4per_gpio8_clkctrl, -#ifdef CONFIG_USB_DWC3 +#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP) (*prcm)->cm_l3init_ocp2scp1_clkctrl, (*prcm)->cm_l3init_usb_otg_ss1_clkctrl, #endif @@ -495,7 +495,7 @@ void enable_basic_clocks(void) setbits_le32((*prcm)->cm_l3init_hsmmc2_clkctrl, HSMMC_CLKCTRL_CLKSEL_MASK); -#ifdef CONFIG_USB_DWC3 +#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP) /* Enable 960 MHz clock for dwc3 */ setbits_le32((*prcm)->cm_l3init_usb_otg_ss1_clkctrl, OPTFCLKEN_REFCLK960M); diff --git a/arch/arm/cpu/armv7/omap5/prcm-regs.c b/arch/arm/cpu/armv7/omap5/prcm-regs.c index 440bb40..f80d36d 100644 --- a/arch/arm/cpu/armv7/omap5/prcm-regs.c +++ b/arch/arm/cpu/armv7/omap5/prcm-regs.c @@ -440,6 +440,10 @@ struct omap_sys_ctrl_regs const dra7xx_ctrl = { .control_emif1_sdram_config_ext = 0x4AE0C144, .control_emif2_sdram_config_ext = 0x4AE0C148, .control_wkup_ldovbb_mpu_voltage_ctrl = 0x4AE0C158, + .control_std_fuse_die_id_0 = 0x4AE0C200, + .control_std_fuse_die_id_1 = 0x4AE0C208, + .control_std_fuse_die_id_2 = 0x4AE0C20C, + .control_std_fuse_die_id_3 = 0x4AE0C210, .control_padconf_mode = 0x4AE0C5A0, .control_xtal_oscillator = 0x4AE0C5A4, .control_i2c_2 = 0x4AE0C5A8, diff --git a/arch/arm/cpu/armv7/rmobile/Kconfig b/arch/arm/cpu/armv7/rmobile/Kconfig index 2b333a3..57dccec 100644 --- a/arch/arm/cpu/armv7/rmobile/Kconfig +++ b/arch/arm/cpu/armv7/rmobile/Kconfig @@ -8,24 +8,36 @@ config TARGET_ARMADILLO_800EVA config TARGET_GOSE bool "Gose board" + select DM + select DM_SERIAL config TARGET_KOELSCH bool "Koelsch board" + select DM + select DM_SERIAL config TARGET_LAGER bool "Lager board" + select DM + select DM_SERIAL config TARGET_KZM9G bool "KZM9D board" config TARGET_ALT bool "Alt board" + select DM + select DM_SERIAL config TARGET_SILK bool "Silk board" + select DM + select DM_SERIAL config TARGET_PORTER bool "Porter board" + select DM + select DM_SERIAL endchoice diff --git a/arch/arm/cpu/armv7/socfpga/Makefile b/arch/arm/cpu/armv7/socfpga/Makefile index 8b6e108..7524ef9 100644 --- a/arch/arm/cpu/armv7/socfpga/Makefile +++ b/arch/arm/cpu/armv7/socfpga/Makefile @@ -7,7 +7,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y := lowlevel_init.o obj-y += misc.o timer.o reset_manager.o system_manager.o clock_manager.o \ fpga_manager.o obj-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o scan_manager.o diff --git a/arch/arm/cpu/armv7/socfpga/lowlevel_init.S b/arch/arm/cpu/armv7/socfpga/lowlevel_init.S deleted file mode 100644 index b4d0627..0000000 --- a/arch/arm/cpu/armv7/socfpga/lowlevel_init.S +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2012 Altera Corporation <www.altera.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> - -/* Set up the platform, once the cpu has been initialized */ -.globl lowlevel_init -lowlevel_init: - - /* Remap */ -#ifdef CONFIG_SPL_BUILD - /* - * SPL : configure the remap (L3 NIC-301 GPV) - * so the on-chip RAM at lower memory instead ROM. - */ - ldr r0, =SOCFPGA_L3REGS_ADDRESS - mov r1, #0x19 - str r1, [r0] -#else - /* - * U-Boot : configure the remap (L3 NIC-301 GPV) - * so the SDRAM at lower memory instead on-chip RAM. - */ - ldr r0, =SOCFPGA_L3REGS_ADDRESS - mov r1, #0x2 - str r1, [r0] - - /* Private components security */ - - /* - * U-Boot : configure private timer, global timer and cpu - * component access as non secure for kernel stage (as required - * by kernel) - */ - mrc p15,4,r0,c15,c0,0 - add r1, r0, #0x54 - ldr r2, [r1] - orr r2, r2, #0xff - orr r2, r2, #0xf00 - str r2, [r1] -#endif /* #ifdef CONFIG_SPL_BUILD */ - mov pc, lr diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c index 7873c38..0f8b4d0 100644 --- a/arch/arm/cpu/armv7/socfpga/misc.c +++ b/arch/arm/cpu/armv7/socfpga/misc.c @@ -49,7 +49,7 @@ void enable_caches(void) /* * DesignWare Ethernet initialization */ -#ifdef CONFIG_DESIGNWARE_ETH +#ifdef CONFIG_ETH_DESIGNWARE int cpu_eth_init(bd_t *bis) { #if CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS diff --git a/arch/arm/cpu/armv7/socfpga/reset_manager.c b/arch/arm/cpu/armv7/socfpga/reset_manager.c index 25921e7..45b352b 100644 --- a/arch/arm/cpu/armv7/socfpga/reset_manager.c +++ b/arch/arm/cpu/armv7/socfpga/reset_manager.c @@ -113,3 +113,27 @@ void socfpga_spim_enable(void) clrbits_le32(reset, (1 << RSTMGR_PERMODRST_SPIM0_LSB) | (1 << RSTMGR_PERMODRST_SPIM1_LSB)); } + +/* Bring UART0 out of reset. */ +void socfpga_uart0_enable(void) +{ + const void *reset = &reset_manager_base->per_mod_reset; + + clrbits_le32(reset, 1 << RSTMGR_PERMODRST_UART0_LSB); +} + +/* Bring SDRAM controller out of reset. */ +void socfpga_sdram_enable(void) +{ + const void *reset = &reset_manager_base->per_mod_reset; + + clrbits_le32(reset, 1 << RSTMGR_PERMODRST_SDR_LSB); +} + +/* Bring OSC1 timer out of reset. */ +void socfpga_osc1timer_enable(void) +{ + const void *reset = &reset_manager_base->per_mod_reset; + + clrbits_le32(reset, 1 << RSTMGR_PERMODRST_OSC1TIMER0_LSB); +} diff --git a/arch/arm/cpu/armv7/socfpga/spl.c b/arch/arm/cpu/armv7/socfpga/spl.c index 6a8c15d..f994658 100644 --- a/arch/arm/cpu/armv7/socfpga/spl.c +++ b/arch/arm/cpu/armv7/socfpga/spl.c @@ -6,6 +6,7 @@ #include <common.h> #include <asm/io.h> +#include <asm/pl310.h> #include <asm/u-boot.h> #include <asm/utils.h> #include <image.h> @@ -15,9 +16,13 @@ #include <asm/arch/freeze_controller.h> #include <asm/arch/clock_manager.h> #include <asm/arch/scan_manager.h> +#include <asm/arch/sdram.h> DECLARE_GLOBAL_DATA_PTR; +static struct pl310_regs *const pl310 = + (struct pl310_regs *)CONFIG_SYS_PL310_BASE; + #define MAIN_VCO_BASE ( \ (CONFIG_HPS_MAINPLLGRP_VCO_DENOM << \ CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) | \ @@ -43,6 +48,31 @@ DECLARE_GLOBAL_DATA_PTR; CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET) \ ) +void board_init_f(ulong dummy) +{ + struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + unsigned long reg; + /* + * First C code to run. Clear fake OCRAM ECC first as SBE + * and DBE might triggered during power on + */ + reg = readl(&sysmgr_regs->eccgrp_ocram); + if (reg & SYSMGR_ECC_OCRAM_SERR) + writel(SYSMGR_ECC_OCRAM_SERR | SYSMGR_ECC_OCRAM_EN, + &sysmgr_regs->eccgrp_ocram); + if (reg & SYSMGR_ECC_OCRAM_DERR) + writel(SYSMGR_ECC_OCRAM_DERR | SYSMGR_ECC_OCRAM_EN, + &sysmgr_regs->eccgrp_ocram); + + memset(__bss_start, 0, __bss_end - __bss_start); + + /* Remap SDRAM to 0x0 */ + writel(0x1, &pl310->pl310_addr_filter_start); + + board_init_r(NULL, 0); +} + u32 spl_boot_device(void) { return BOOT_DEVICE_RAM; @@ -53,6 +83,7 @@ u32 spl_boot_device(void) */ void spl_board_init(void) { + unsigned long sdram_size; #ifndef CONFIG_SOCFPGA_VIRTUAL_TARGET cm_config_t cm_default_cfg = { /* main group */ @@ -144,10 +175,19 @@ void spl_board_init(void) /* freeze all IO banks */ sys_mgr_frzctrl_freeze_req(); + socfpga_sdram_enable(); + socfpga_uart0_enable(); + socfpga_osc1timer_enable(); + + timer_init(); + debug("Reconfigure Clock Manager\n"); /* reconfigure the PLLs */ cm_basic_init(&cm_default_cfg); + /* Enable bootrom to configure IOs. */ + sysmgr_enable_warmrstcfgio(); + /* configure the IOCSR / IO buffer settings */ if (scan_mgr_configure_iocsr()) hang(); @@ -165,4 +205,25 @@ void spl_board_init(void) /* enable console uart printing */ preloader_console_init(); + + if (sdram_mmr_init_full(0xffffffff) != 0) { + puts("SDRAM init failed.\n"); + hang(); + } + + debug("SDRAM: Calibrating PHY\n"); + /* SDRAM calibration */ + if (sdram_calibration_full() == 0) { + puts("SDRAM calibration failed.\n"); + hang(); + } + + sdram_size = sdram_calculate_size(); + debug("SDRAM: %ld MiB\n", sdram_size >> 20); + + /* Sanity check ensure correct SDRAM size specified */ + if (get_ram_size(0, sdram_size) != sdram_size) { + puts("SDRAM size check failed!\n"); + hang(); + } } diff --git a/arch/arm/cpu/armv7/socfpga/system_manager.c b/arch/arm/cpu/armv7/socfpga/system_manager.c index 11f7bad..8126e0d 100644 --- a/arch/arm/cpu/armv7/socfpga/system_manager.c +++ b/arch/arm/cpu/armv7/socfpga/system_manager.c @@ -66,3 +66,12 @@ void sysmgr_pinmux_init(void) populate_sysmgr_fpgaintf_module(); } + +/* + * This bit allows the bootrom to configure the IOs after a warm reset. + */ +void sysmgr_enable_warmrstcfgio(void) +{ + setbits_le32(&sysmgr_regs->romcodegrp_ctrl, + SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGIO); +} diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index c02c015..c1b4cf5 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -46,28 +46,33 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT); sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT); #endif - sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF2_UART0_TX); - sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF4_UART0_RX); +#if defined(CONFIG_MACH_SUN8I) + sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUN8I_GPF_UART0_TX); + sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUN8I_GPF_UART0_RX); +#else + sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF_UART0_TX); + sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF_UART0_RX); +#endif sunxi_gpio_set_pull(SUNXI_GPF(4), 1); #elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)) - sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB22_UART0_TX); - sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB23_UART0_RX); + sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB_UART0); + sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB_UART0); sunxi_gpio_set_pull(SUNXI_GPB(23), SUNXI_GPIO_PULL_UP); #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN5I) - sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB19_UART0_TX); - sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB20_UART0_RX); + sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB_UART0); + sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB_UART0); sunxi_gpio_set_pull(SUNXI_GPB(20), SUNXI_GPIO_PULL_UP); #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN6I) - sunxi_gpio_set_cfgpin(SUNXI_GPH(20), SUN6I_GPH20_UART0_TX); - sunxi_gpio_set_cfgpin(SUNXI_GPH(21), SUN6I_GPH21_UART0_RX); + sunxi_gpio_set_cfgpin(SUNXI_GPH(20), SUN6I_GPH_UART0); + sunxi_gpio_set_cfgpin(SUNXI_GPH(21), SUN6I_GPH_UART0); sunxi_gpio_set_pull(SUNXI_GPH(21), SUNXI_GPIO_PULL_UP); #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN5I) - sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG3_UART1_TX); - sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART1_RX); + sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG_UART1); + sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG_UART1); sunxi_gpio_set_pull(SUNXI_GPG(4), SUNXI_GPIO_PULL_UP); #elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I) - sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL2_R_UART_TX); - sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL3_R_UART_RX); + sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART); + sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART); sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP); #else #error Unsupported console port number. Please fix pin mux settings in board.c diff --git a/arch/arm/cpu/armv7/sunxi/rsb.c b/arch/arm/cpu/armv7/sunxi/rsb.c index b00befb..f115a9c 100644 --- a/arch/arm/cpu/armv7/sunxi/rsb.c +++ b/arch/arm/cpu/armv7/sunxi/rsb.c @@ -21,15 +21,15 @@ static int rsb_set_device_mode(void); static void rsb_cfg_io(void) { #ifdef CONFIG_MACH_SUN8I - sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL0_R_RSB_SCK); - sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL1_R_RSB_SDA); + sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB); + sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB); sunxi_gpio_set_pull(SUNXI_GPL(0), 1); sunxi_gpio_set_pull(SUNXI_GPL(1), 1); sunxi_gpio_set_drv(SUNXI_GPL(0), 2); sunxi_gpio_set_drv(SUNXI_GPL(1), 2); #elif defined CONFIG_MACH_SUN9I - sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN0_R_RSB_SCK); - sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN1_R_RSB_SDA); + sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN_R_RSB); + sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN_R_RSB); sunxi_gpio_set_pull(SUNXI_GPN(0), 1); sunxi_gpio_set_pull(SUNXI_GPN(1), 1); sunxi_gpio_set_drv(SUNXI_GPN(0), 2); diff --git a/arch/arm/cpu/armv7/sunxi/usbc.c b/arch/arm/cpu/armv7/sunxi/usbc.c index 524f25c..a0e9604 100644 --- a/arch/arm/cpu/armv7/sunxi/usbc.c +++ b/arch/arm/cpu/armv7/sunxi/usbc.c @@ -41,6 +41,7 @@ static struct sunxi_usbc_hcd { int usb_rst_mask; int ahb_clk_mask; int gpio_vbus; + int gpio_vbus_det; int irq; int id; } sunxi_usbc_hcd[] = { @@ -80,12 +81,6 @@ static struct sunxi_usbc_hcd { static int enabled_hcd_count; -static bool use_axp_drivebus(int index) -{ - return index == 0 && - strcmp(CONFIG_USB0_VBUS_PIN, "axp_drivebus") == 0; -} - void *sunxi_usbc_get_io_base(int index) { switch (index) { @@ -102,9 +97,6 @@ void *sunxi_usbc_get_io_base(int index) static int get_vbus_gpio(int index) { - if (use_axp_drivebus(index)) - return -1; - switch (index) { case 0: return sunxi_name_to_gpio(CONFIG_USB0_VBUS_PIN); case 1: return sunxi_name_to_gpio(CONFIG_USB1_VBUS_PIN); @@ -113,6 +105,14 @@ static int get_vbus_gpio(int index) return -1; } +static int get_vbus_detect_gpio(int index) +{ + switch (index) { + case 0: return sunxi_name_to_gpio(CONFIG_USB0_VBUS_DET); + } + return -1; +} + static void usb_phy_write(struct sunxi_usbc_hcd *sunxi_usbc, int addr, int data, int len) { @@ -192,22 +192,35 @@ void sunxi_usbc_enable_squelch_detect(int index, int enable) int sunxi_usbc_request_resources(int index) { struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index]; + int ret = 0; sunxi_usbc->gpio_vbus = get_vbus_gpio(index); - if (sunxi_usbc->gpio_vbus != -1) - return gpio_request(sunxi_usbc->gpio_vbus, "usbc_vbus"); + if (sunxi_usbc->gpio_vbus != -1) { + ret |= gpio_request(sunxi_usbc->gpio_vbus, "usbc_vbus"); + ret |= gpio_direction_output(sunxi_usbc->gpio_vbus, 0); + } + + sunxi_usbc->gpio_vbus_det = get_vbus_detect_gpio(index); + if (sunxi_usbc->gpio_vbus_det != -1) { + ret |= gpio_request(sunxi_usbc->gpio_vbus_det, "usbc_vbus_det"); + ret |= gpio_direction_input(sunxi_usbc->gpio_vbus_det); + } - return 0; + return ret; } int sunxi_usbc_free_resources(int index) { struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index]; + int ret = 0; if (sunxi_usbc->gpio_vbus != -1) - return gpio_free(sunxi_usbc->gpio_vbus); + ret |= gpio_free(sunxi_usbc->gpio_vbus); - return 0; + if (sunxi_usbc->gpio_vbus_det != -1) + ret |= gpio_free(sunxi_usbc->gpio_vbus_det); + + return ret; } void sunxi_usbc_enable(int index) @@ -258,22 +271,38 @@ void sunxi_usbc_vbus_enable(int index) { struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index]; -#ifdef AXP_DRIVEBUS - if (use_axp_drivebus(index)) - axp_drivebus_enable(); -#endif if (sunxi_usbc->gpio_vbus != -1) - gpio_direction_output(sunxi_usbc->gpio_vbus, 1); + gpio_set_value(sunxi_usbc->gpio_vbus, 1); } void sunxi_usbc_vbus_disable(int index) { struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index]; -#ifdef AXP_DRIVEBUS - if (use_axp_drivebus(index)) - axp_drivebus_disable(); -#endif if (sunxi_usbc->gpio_vbus != -1) - gpio_direction_output(sunxi_usbc->gpio_vbus, 0); + gpio_set_value(sunxi_usbc->gpio_vbus, 0); +} + +int sunxi_usbc_vbus_detect(int index) +{ + struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index]; + int err, retries = 3; + + if (sunxi_usbc->gpio_vbus_det == -1) { + eprintf("Error: invalid vbus detection pin\n"); + return -1; + } + + err = gpio_get_value(sunxi_usbc->gpio_vbus_det); + /* + * Vbus may have been provided by the board and just been turned of + * some milliseconds ago on reset, what we're measuring then is a + * residual charge on Vbus, sleep a bit and try again. + */ + while (err > 0 && retries--) { + mdelay(100); + err = gpio_get_value(sunxi_usbc->gpio_vbus_det); + } + + return err; } diff --git a/arch/arm/cpu/armv7/vf610/generic.c b/arch/arm/cpu/armv7/vf610/generic.c index 92aaad9..1bb9b8e 100644 --- a/arch/arm/cpu/armv7/vf610/generic.c +++ b/arch/arm/cpu/armv7/vf610/generic.c @@ -18,6 +18,8 @@ DECLARE_GLOBAL_DATA_PTR; #endif +static char soc_type[] = "xx0"; + #ifdef CONFIG_MXC_OCOTP void enable_ocotp_clk(unsigned char enable) { @@ -284,14 +286,37 @@ static char *get_reset_cause(void) int print_cpuinfo(void) { - printf("CPU: Freescale Vybrid VF610 at %d MHz\n", - mxc_get_clock(MXC_ARM_CLK) / 1000000); + printf("CPU: Freescale Vybrid VF%s at %d MHz\n", + soc_type, mxc_get_clock(MXC_ARM_CLK) / 1000000); printf("Reset cause: %s\n", get_reset_cause()); return 0; } #endif +int arch_cpu_init(void) +{ + struct mscm *mscm = (struct mscm *)MSCM_BASE_ADDR; + + soc_type[0] = mscm->cpxcount ? '6' : '5'; /*Dual Core => VF6x0 */ + soc_type[1] = mscm->cpxcfg1 ? '1' : '0'; /* L2 Cache => VFx10 */ + + return 0; +} + +#ifdef CONFIG_ARCH_MISC_INIT +int arch_misc_init(void) +{ + char soc[6]; + + strcat(soc, "vf"); + strcat(soc, soc_type); + setenv("soc", soc); + + return 0; +} +#endif + int cpu_eth_init(bd_t *bis) { int rc = -ENODEV; @@ -317,3 +342,19 @@ int get_clocks(void) #endif return 0; } + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ +#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) + enum dcache_option option = DCACHE_WRITETHROUGH; +#else + enum dcache_option option = DCACHE_WRITEBACK; +#endif + dcache_enable(); + icache_enable(); + + /* Enable caching on OCRAM */ + mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR, IRAM_SIZE, option); +} +#endif diff --git a/arch/arm/cpu/armv7/zynq/config.mk b/arch/arm/cpu/armv7/zynq/config.mk deleted file mode 100644 index 778a377..0000000 --- a/arch/arm/cpu/armv7/zynq/config.mk +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved. -# -# SPDX-License-Identifier: GPL-2.0 -# -# Allow NEON instructions (needed for lowlevel_init.S with GNU toolchain) -PLATFORM_RELFLAGS += -mfpu=neon diff --git a/arch/arm/cpu/armv7m/Makefile b/arch/arm/cpu/armv7m/Makefile new file mode 100644 index 0000000..b662e03 --- /dev/null +++ b/arch/arm/cpu/armv7m/Makefile @@ -0,0 +1,11 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y := start.o +obj-y += cpu.o + +obj-$(CONFIG_STM32F4) += stm32f4/ diff --git a/arch/arm/cpu/armv7m/config.mk b/arch/arm/cpu/armv7m/config.mk new file mode 100644 index 0000000..0b31e44 --- /dev/null +++ b/arch/arm/cpu/armv7m/config.mk @@ -0,0 +1,8 @@ +# +# (C) Copyright 2015 +# Kamil Lulko, <rev13@wp.pl> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +PLATFORM_CPPFLAGS += -march=armv7-m -mthumb diff --git a/arch/arm/cpu/armv7m/cpu.c b/arch/arm/cpu/armv7m/cpu.c new file mode 100644 index 0000000..d3ab862 --- /dev/null +++ b/arch/arm/cpu/armv7m/cpu.c @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2010,2011 + * Vladimir Khusainov, Emcraft Systems, vlad@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/armv7m.h> + +/* + * This is called right before passing control to + * the Linux kernel point. + */ +int cleanup_before_linux(void) +{ + return 0; +} + +/* + * Perform the low-level reset. + */ +void reset_cpu(ulong addr) +{ + /* + * Perform reset but keep priority group unchanged. + */ + writel((V7M_AIRCR_VECTKEY << V7M_AIRCR_VECTKEY_SHIFT) + | (V7M_SCB->aircr & V7M_AIRCR_PRIGROUP_MSK) + | V7M_AIRCR_SYSRESET, &V7M_SCB->aircr); +} diff --git a/arch/arm/cpu/armv7m/start.S b/arch/arm/cpu/armv7m/start.S new file mode 100644 index 0000000..e05e984 --- /dev/null +++ b/arch/arm/cpu/armv7m/start.S @@ -0,0 +1,15 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.globl reset +.type reset, %function +reset: + b _main + +.globl c_runtime_cpu_setup +c_runtime_cpu_setup: + mov pc, lr diff --git a/arch/arm/cpu/armv7m/stm32f4/Makefile b/arch/arm/cpu/armv7m/stm32f4/Makefile new file mode 100644 index 0000000..e982830 --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f4/Makefile @@ -0,0 +1,11 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2015 +# Kamil Lulko, <rev13@wp.pl> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += soc.o clock.o timer.o flash.o diff --git a/arch/arm/cpu/armv7m/stm32f4/clock.c b/arch/arm/cpu/armv7m/stm32f4/clock.c new file mode 100644 index 0000000..2eded1f --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f4/clock.c @@ -0,0 +1,209 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * (C) Copyright 2014 + * STMicroelectronics + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/stm32.h> + +#define RCC_CR_HSION (1 << 0) +#define RCC_CR_HSEON (1 << 16) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_CSSON (1 << 19) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_PLLRDY (1 << 25) + +#define RCC_PLLCFGR_PLLM_MASK 0x3F +#define RCC_PLLCFGR_PLLN_MASK 0x7FC0 +#define RCC_PLLCFGR_PLLP_MASK 0x30000 +#define RCC_PLLCFGR_PLLQ_MASK 0xF000000 +#define RCC_PLLCFGR_PLLSRC (1 << 22) +#define RCC_PLLCFGR_PLLN_SHIFT 6 +#define RCC_PLLCFGR_PLLP_SHIFT 16 +#define RCC_PLLCFGR_PLLQ_SHIFT 24 + +#define RCC_CFGR_AHB_PSC_MASK 0xF0 +#define RCC_CFGR_APB1_PSC_MASK 0x1C00 +#define RCC_CFGR_APB2_PSC_MASK 0xE000 +#define RCC_CFGR_SW0 (1 << 0) +#define RCC_CFGR_SW1 (1 << 1) +#define RCC_CFGR_SW_MASK 0x3 +#define RCC_CFGR_SW_HSI 0 +#define RCC_CFGR_SW_HSE RCC_CFGR_SW0 +#define RCC_CFGR_SW_PLL RCC_CFGR_SW1 +#define RCC_CFGR_SWS0 (1 << 2) +#define RCC_CFGR_SWS1 (1 << 3) +#define RCC_CFGR_SWS_MASK 0xC +#define RCC_CFGR_SWS_HSI 0 +#define RCC_CFGR_SWS_HSE RCC_CFGR_SWS0 +#define RCC_CFGR_SWS_PLL RCC_CFGR_SWS1 +#define RCC_CFGR_HPRE_SHIFT 4 +#define RCC_CFGR_PPRE1_SHIFT 10 +#define RCC_CFGR_PPRE2_SHIFT 13 + +#define RCC_APB1ENR_PWREN (1 << 28) + +#define PWR_CR_VOS0 (1 << 14) +#define PWR_CR_VOS1 (1 << 15) +#define PWR_CR_VOS_MASK 0xC000 +#define PWR_CR_VOS_SCALE_MODE_1 (PWR_CR_VOS0 | PWR_CR_VOS1) +#define PWR_CR_VOS_SCALE_MODE_2 (PWR_CR_VOS1) +#define PWR_CR_VOS_SCALE_MODE_3 (PWR_CR_VOS0) + +#define FLASH_ACR_WS(n) n +#define FLASH_ACR_PRFTEN (1 << 8) +#define FLASH_ACR_ICEN (1 << 9) +#define FLASH_ACR_DCEN (1 << 10) + +struct pll_psc { + u8 pll_m; + u16 pll_n; + u8 pll_p; + u8 pll_q; + u8 ahb_psc; + u8 apb1_psc; + u8 apb2_psc; +}; + +#define AHB_PSC_1 0 +#define AHB_PSC_2 0x8 +#define AHB_PSC_4 0x9 +#define AHB_PSC_8 0xA +#define AHB_PSC_16 0xB +#define AHB_PSC_64 0xC +#define AHB_PSC_128 0xD +#define AHB_PSC_256 0xE +#define AHB_PSC_512 0xF + +#define APB_PSC_1 0 +#define APB_PSC_2 0x4 +#define APB_PSC_4 0x5 +#define APB_PSC_8 0x6 +#define APB_PSC_16 0x7 + +#if !defined(CONFIG_STM32_HSE_HZ) +#error "CONFIG_STM32_HSE_HZ not defined!" +#else +#if (CONFIG_STM32_HSE_HZ == 8000000) +struct pll_psc pll_psc_168 = { + .pll_m = 8, + .pll_n = 336, + .pll_p = 2, + .pll_q = 7, + .ahb_psc = AHB_PSC_1, + .apb1_psc = APB_PSC_4, + .apb2_psc = APB_PSC_2 +}; +#else +#error "No PLL/Prescaler configuration for given CONFIG_STM32_HSE_HZ exists" +#endif +#endif + +int configure_clocks(void) +{ + /* Reset RCC configuration */ + setbits_le32(&STM32_RCC->cr, RCC_CR_HSION); + writel(0, &STM32_RCC->cfgr); /* Reset CFGR */ + clrbits_le32(&STM32_RCC->cr, (RCC_CR_HSEON | RCC_CR_CSSON + | RCC_CR_PLLON)); + writel(0x24003010, &STM32_RCC->pllcfgr); /* Reset value from RM */ + clrbits_le32(&STM32_RCC->cr, RCC_CR_HSEBYP); + writel(0, &STM32_RCC->cir); /* Disable all interrupts */ + + /* Configure for HSE+PLL operation */ + setbits_le32(&STM32_RCC->cr, RCC_CR_HSEON); + while (!(readl(&STM32_RCC->cr) & RCC_CR_HSERDY)) + ; + + /* Enable high performance mode, System frequency up to 168 MHz */ + setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_PWREN); + writel(PWR_CR_VOS_SCALE_MODE_1, &STM32_PWR->cr); + + setbits_le32(&STM32_RCC->cfgr, (( + pll_psc_168.ahb_psc << RCC_CFGR_HPRE_SHIFT) + | (pll_psc_168.apb1_psc << RCC_CFGR_PPRE1_SHIFT) + | (pll_psc_168.apb2_psc << RCC_CFGR_PPRE2_SHIFT))); + + writel(pll_psc_168.pll_m + | (pll_psc_168.pll_n << RCC_PLLCFGR_PLLN_SHIFT) + | (((pll_psc_168.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) + | (pll_psc_168.pll_q << RCC_PLLCFGR_PLLQ_SHIFT), + &STM32_RCC->pllcfgr); + setbits_le32(&STM32_RCC->pllcfgr, RCC_PLLCFGR_PLLSRC); + + setbits_le32(&STM32_RCC->cr, RCC_CR_PLLON); + + while (!(readl(&STM32_RCC->cr) & RCC_CR_PLLRDY)) + ; + + /* 5 wait states, Prefetch enabled, D-Cache enabled, I-Cache enabled */ + writel(FLASH_ACR_WS(5) | FLASH_ACR_PRFTEN | FLASH_ACR_ICEN + | FLASH_ACR_DCEN, &STM32_FLASH->acr); + + clrbits_le32(&STM32_RCC->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1)); + setbits_le32(&STM32_RCC->cfgr, RCC_CFGR_SW_PLL); + + while ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_PLL) + ; + + return 0; +} + +unsigned long clock_get(enum clock clck) +{ + u32 sysclk = 0; + u32 shift = 0; + /* Prescaler table lookups for clock computation */ + u8 ahb_psc_table[16] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9 + }; + u8 apb_psc_table[8] = { + 0, 0, 0, 0, 1, 2, 3, 4 + }; + + if ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) == + RCC_CFGR_SWS_PLL) { + u16 pllm, plln, pllp; + pllm = (readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLM_MASK); + plln = ((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLN_MASK) + >> RCC_PLLCFGR_PLLN_SHIFT); + pllp = ((((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLP_MASK) + >> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1); + sysclk = ((CONFIG_STM32_HSE_HZ / pllm) * plln) / pllp; + } + + switch (clck) { + case CLOCK_CORE: + return sysclk; + break; + case CLOCK_AHB: + shift = ahb_psc_table[( + (readl(&STM32_RCC->cfgr) & RCC_CFGR_AHB_PSC_MASK) + >> RCC_CFGR_HPRE_SHIFT)]; + return sysclk >>= shift; + break; + case CLOCK_APB1: + shift = apb_psc_table[( + (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB1_PSC_MASK) + >> RCC_CFGR_PPRE1_SHIFT)]; + return sysclk >>= shift; + break; + case CLOCK_APB2: + shift = apb_psc_table[( + (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB2_PSC_MASK) + >> RCC_CFGR_PPRE2_SHIFT)]; + return sysclk >>= shift; + break; + default: + return 0; + break; + } +} diff --git a/arch/arm/cpu/armv7m/stm32f4/flash.c b/arch/arm/cpu/armv7m/stm32f4/flash.c new file mode 100644 index 0000000..e5c6111 --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f4/flash.c @@ -0,0 +1,143 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/stm32.h> + +#define STM32_FLASH_KEY1 0x45670123 +#define STM32_FLASH_KEY2 0xCDEF89AB + +flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; + +const u32 sect_sz_kb[CONFIG_SYS_MAX_FLASH_SECT] = { + [0 ... 3] = 16 * 1024, + [4] = 64 * 1024, + [5 ... 11] = 128 * 1024 +}; + +static void stm32f4_flash_lock(u8 lock) +{ + if (lock) { + setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_LOCK); + } else { + writel(STM32_FLASH_KEY1, &STM32_FLASH->key); + writel(STM32_FLASH_KEY2, &STM32_FLASH->key); + } +} + +unsigned long flash_init(void) +{ + unsigned long total_size = 0; + u8 i, j; + + for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { + flash_info[i].flash_id = FLASH_STM32F4; + flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT; + flash_info[i].start[0] = CONFIG_SYS_FLASH_BASE + (i << 20); + flash_info[i].size = sect_sz_kb[0]; + for (j = 1; j < CONFIG_SYS_MAX_FLASH_SECT; j++) { + flash_info[i].start[j] = flash_info[i].start[j - 1] + + (sect_sz_kb[j - 1]); + flash_info[i].size += sect_sz_kb[j]; + } + total_size += flash_info[i].size; + } + + return total_size; +} + +void flash_print_info(flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf("missing or unknown FLASH type\n"); + return; + } else if (info->flash_id == FLASH_STM32F4) { + printf("STM32F4 Embedded Flash\n"); + } + + printf(" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf(" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; ++i) { + if ((i % 5) == 0) + printf("\n "); + printf(" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " "); + } + printf("\n"); + return; +} + +int flash_erase(flash_info_t *info, int first, int last) +{ + u8 bank = 0xFF; + int i; + + for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { + if (info == &flash_info[i]) { + bank = i; + break; + } + } + if (bank == 0xFF) + return -1; + + stm32f4_flash_lock(0); + + for (i = first; i <= last; i++) { + while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY) + ; + + if (bank == 0) { + setbits_le32(&STM32_FLASH->cr, + (i << STM32_FLASH_CR_SNB_OFFSET)); + } else if (bank == 1) { + setbits_le32(&STM32_FLASH->cr, + ((0x10 | i) << STM32_FLASH_CR_SNB_OFFSET)); + } else { + stm32f4_flash_lock(1); + return -1; + } + setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_SER); + setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_STRT); + + while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY) + ; + + clrbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_SER); + stm32f4_flash_lock(1); + } + + return 0; +} + +int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong i; + + while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY) + ; + + stm32f4_flash_lock(0); + + setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_PG); + /* To make things simple use byte writes only */ + for (i = 0; i < cnt; i++) { + *(uchar *)(addr + i) = src[i]; + while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY) + ; + } + clrbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_PG); + stm32f4_flash_lock(1); + + return 0; +} diff --git a/arch/arm/cpu/armv7m/stm32f4/soc.c b/arch/arm/cpu/armv7m/stm32f4/soc.c new file mode 100644 index 0000000..202a126 --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f4/soc.c @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/armv7m.h> +#include <asm/arch/stm32.h> + +u32 get_cpu_rev(void) +{ + return 0; +} + +int arch_cpu_init(void) +{ + configure_clocks(); + + /* + * Configure the memory protection unit (MPU) to allow full access to + * the whole 4GB address space. + */ + writel(0, &V7M_MPU->rnr); + writel(0, &V7M_MPU->rbar); + writel((V7M_MPU_RASR_AP_RW_RW | V7M_MPU_RASR_SIZE_4GB + | V7M_MPU_RASR_EN), &V7M_MPU->rasr); + writel(V7M_MPU_CTRL_ENABLE | V7M_MPU_CTRL_HFNMIENA, &V7M_MPU->ctrl); + + return 0; +} + +void s_init(void) +{ +} diff --git a/arch/arm/cpu/armv7m/stm32f4/timer.c b/arch/arm/cpu/armv7m/stm32f4/timer.c new file mode 100644 index 0000000..102ae6d --- /dev/null +++ b/arch/arm/cpu/armv7m/stm32f4/timer.c @@ -0,0 +1,118 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/armv7m.h> +#include <asm/arch/stm32.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define STM32_TIM2_BASE (STM32_APB1PERIPH_BASE + 0x0000) + +#define RCC_APB1ENR_TIM2EN (1 << 0) + +struct stm32_tim2_5 { + u32 cr1; + u32 cr2; + u32 smcr; + u32 dier; + u32 sr; + u32 egr; + u32 ccmr1; + u32 ccmr2; + u32 ccer; + u32 cnt; + u32 psc; + u32 arr; + u32 reserved1; + u32 ccr1; + u32 ccr2; + u32 ccr3; + u32 ccr4; + u32 reserved2; + u32 dcr; + u32 dmar; + u32 or; +}; + +#define TIM_CR1_CEN (1 << 0) + +#define TIM_EGR_UG (1 << 0) + +int timer_init(void) +{ + struct stm32_tim2_5 *tim = (struct stm32_tim2_5 *)STM32_TIM2_BASE; + + setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_TIM2EN); + + if (clock_get(CLOCK_AHB) == clock_get(CLOCK_APB1)) + writel((clock_get(CLOCK_APB1) / CONFIG_SYS_HZ_CLOCK) - 1, + &tim->psc); + else + writel(((clock_get(CLOCK_APB1) * 2) / CONFIG_SYS_HZ_CLOCK) - 1, + &tim->psc); + + writel(0xFFFFFFFF, &tim->arr); + writel(TIM_CR1_CEN, &tim->cr1); + setbits_le32(&tim->egr, TIM_EGR_UG); + + gd->arch.tbl = 0; + gd->arch.tbu = 0; + gd->arch.lastinc = 0; + + return 0; +} + +ulong get_timer(ulong base) +{ + return (get_ticks() / (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ)) - base; +} + +unsigned long long get_ticks(void) +{ + struct stm32_tim2_5 *tim = (struct stm32_tim2_5 *)STM32_TIM2_BASE; + u32 now; + + now = readl(&tim->cnt); + + if (now >= gd->arch.lastinc) + gd->arch.tbl += (now - gd->arch.lastinc); + else + gd->arch.tbl += (0xFFFFFFFF - gd->arch.lastinc) + now; + + gd->arch.lastinc = now; + + return gd->arch.tbl; +} + +void reset_timer(void) +{ + struct stm32_tim2_5 *tim = (struct stm32_tim2_5 *)STM32_TIM2_BASE; + + gd->arch.lastinc = readl(&tim->cnt); + gd->arch.tbl = 0; +} + +/* delay x useconds */ +void __udelay(ulong usec) +{ + unsigned long long start; + + start = get_ticks(); /* get current timestamp */ + while ((get_ticks() - start) < usec) + ; /* loop till time has passed */ +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ_CLOCK; +} diff --git a/arch/arm/cpu/armv8/fsl-lsch3/Makefile b/arch/arm/cpu/armv8/fsl-lsch3/Makefile index f920eeb..9f7815b 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/Makefile +++ b/arch/arm/cpu/armv8/fsl-lsch3/Makefile @@ -6,6 +6,8 @@ obj-y += cpu.o obj-y += lowlevel.o +obj-y += soc.o obj-y += speed.o +obj-$(CONFIG_SYS_HAS_SERDES) += fsl_lsch3_serdes.o ls2085a_serdes.o obj-$(CONFIG_MP) += mp.o obj-$(CONFIG_OF_LIBFDT) += fdt.o diff --git a/arch/arm/cpu/armv8/fsl-lsch3/README b/arch/arm/cpu/armv8/fsl-lsch3/README index cc47466..37f07fb 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/README +++ b/arch/arm/cpu/armv8/fsl-lsch3/README @@ -8,3 +8,141 @@ Freescale LayerScape with Chassis Generation 3 This architecture supports Freescale ARMv8 SoCs with Chassis generation 3, for example LS2085A. + +Flash Layout +============ + +(1) A typical layout of various images (including Linux and other firmware images) + is shown below considering a 32MB NOR flash device present on most + pre-silicon platforms (simulator and emulator): + + ------------------------- + | FIT Image | + | (linux + DTB + RFS) | + ------------------------- ----> 0x0120_0000 + | Debug Server FW | + ------------------------- ----> 0x00C0_0000 + | AIOP FW | + ------------------------- ----> 0x0070_0000 + | MC FW | + ------------------------- ----> 0x006C_0000 + | MC DPL Blob | + ------------------------- ----> 0x0020_0000 + | BootLoader + Env| + ------------------------- ----> 0x0000_1000 + | PBI | + ------------------------- ----> 0x0000_0080 + | RCW | + ------------------------- ----> 0x0000_0000 + + 32-MB NOR flash layout for pre-silicon platforms (simulator and emulator) + +(2) A typical layout of various images (including Linux and other firmware images) + is shown below considering a 128MB NOR flash device present on QDS and RDB + boards: + ----------------------------------------- ----> 0x5_8800_0000 --- + | .. Unused .. (7M) | | + ----------------------------------------- ----> 0x5_8790_0000 | + | FIT Image (linux + DTB + RFS) (40M) | | + ----------------------------------------- ----> 0x5_8510_0000 | + | PHY firmware (2M) | | + ----------------------------------------- ----> 0x5_84F0_0000 | 64K + | Debug Server FW (2M) | | Alt + ----------------------------------------- ----> 0x5_84D0_0000 | Bank + | AIOP FW (4M) | | + ----------------------------------------- ----> 0x5_8490_0000 (vbank4) + | MC DPC Blob (1M) | | + ----------------------------------------- ----> 0x5_8480_0000 | + | MC DPL Blob (1M) | | + ----------------------------------------- ----> 0x5_8470_0000 | + | MC FW (4M) | | + ----------------------------------------- ----> 0x5_8430_0000 | + | BootLoader Environment (1M) | | + ----------------------------------------- ----> 0x5_8420_0000 | + | BootLoader (1M) | | + ----------------------------------------- ----> 0x5_8410_0000 | + | RCW and PBI (1M) | | + ----------------------------------------- ----> 0x5_8400_0000 --- + | .. Unused .. (7M) | | + ----------------------------------------- ----> 0x5_8390_0000 | + | FIT Image (linux + DTB + RFS) (40M) | | + ----------------------------------------- ----> 0x5_8110_0000 | + | PHY firmware (2M) | | + ----------------------------------------- ----> 0x5_80F0_0000 | 64K + | Debug Server FW (2M) | | Bank + ----------------------------------------- ----> 0x5_80D0_0000 | + | AIOP FW (4M) | | + ----------------------------------------- ----> 0x5_8090_0000 (vbank0) + | MC DPC Blob (1M) | | + ----------------------------------------- ----> 0x5_8080_0000 | + | MC DPL Blob (1M) | | + ----------------------------------------- ----> 0x5_8070_0000 | + | MC FW (4M) | | + ----------------------------------------- ----> 0x5_8030_0000 | + | BootLoader Environment (1M) | | + ----------------------------------------- ----> 0x5_8020_0000 | + | BootLoader (1M) | | + ----------------------------------------- ----> 0x5_8010_0000 | + | RCW and PBI (1M) | | + ----------------------------------------- ----> 0x5_8000_0000 --- + + 128-MB NOR flash layout for QDS and RDB boards + +Environment Variables +===================== +mcboottimeout: MC boot timeout in milliseconds. If this variable is not defined + the value CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS will be assumed. + +mcmemsize: MC DRAM block size. If this variable is not defined, the value + CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE will be assumed. + +Booting from NAND +------------------- +Booting from NAND requires two images, RCW and u-boot-with-spl.bin. +The difference between NAND boot RCW image and NOR boot image is the PBI +command sequence. Below is one example for PBI commands for QDS which uses +NAND device with 2KB/page, block size 128KB. + +1) CCSR 4-byte write to 0x00e00404, data=0x00000000 +2) CCSR 4-byte write to 0x00e00400, data=0x1800a000 +The above two commands set bootloc register to 0x00000000_1800a000 where +the u-boot code will be running in OCRAM. + +3) Block Copy: SRC=0x0107, SRC_ADDR=0x00020000, DEST_ADDR=0x1800a000, +BLOCK_SIZE=0x00014000 +This command copies u-boot image from NAND device into OCRAM. The values need +to adjust accordingly. + +SRC should match the cfg_rcw_src, the reset config pins. It depends + on the NAND device. See reference manual for cfg_rcw_src. +SRC_ADDR is the offset of u-boot-with-spl.bin image in NAND device. In + the example above, 128KB. For easy maintenance, we put it at + the beginning of next block from RCW. +DEST_ADDR is fixed at 0x1800a000, matching bootloc set above. +BLOCK_SIZE is the size to be copied by PBI. + +RCW image should be written to the beginning of NAND device. Example of using +u-boot command + +nand write <rcw image in memory> 0 <size of rcw image> + +To form the NAND image, build u-boot with NAND config, for example, +ls2085aqds_nand_defconfig. The image needed is u-boot-with-spl.bin. +The u-boot image should be written to match SRC_ADDR, in above example 0x20000. + +nand write <u-boot image in memory> 200000 <size of u-boot image> + +With these two images in NAND device, the board can boot from NAND. + +Another example for RDB boards, + +1) CCSR 4-byte write to 0x00e00404, data=0x00000000 +2) CCSR 4-byte write to 0x00e00400, data=0x1800a000 +3) Block Copy: SRC=0x0119, SRC_ADDR=0x00080000, DEST_ADDR=0x1800a000, +BLOCK_SIZE=0x00014000 + +nand write <rcw image in memory> 0 <size of rcw image> +nand write <u-boot image in memory> 80000 <size of u-boot image> + +Notice the difference from QDS is SRC, SRC_ADDR and the offset of u-boot image +to match board NAND device with 4KB/page, block size 512KB. diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c index 4997487..6714577 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c @@ -10,7 +10,12 @@ #include <asm/armv8/mmu.h> #include <asm/io.h> #include <asm/arch-fsl-lsch3/immap_lsch3.h> +#include <fsl_debug_server.h> #include <fsl-mc/fsl_mc.h> +#include <asm/arch/fsl_serdes.h> +#ifdef CONFIG_FSL_ESDHC +#include <fsl_esdhc.h> +#endif #include "cpu.h" #include "mp.h" #include "speed.h" @@ -24,8 +29,9 @@ DECLARE_GLOBAL_DATA_PTR; * levels of translation tables here to cover 40-bit address space. * We use 4KB granule size, with 40 bits physical address, T0SZ=24 * Level 0 IA[39], table address @0 - * Level 1 IA[31:30], table address @01000, 0x2000 - * Level 2 IA[29:21], table address @0x3000 + * Level 1 IA[31:30], table address @0x1000, 0x2000 + * Level 2 IA[29:21], table address @0x3000, 0x4000 + * Address above 0x5000 is free for other purpose. */ #define SECTION_SHIFT_L0 39UL @@ -60,12 +66,12 @@ static inline void early_mmu_setup(void) { int el; u64 i; - u64 section_l1t0, section_l1t1, section_l2; + u64 section_l1t0, section_l1t1, section_l2t0, section_l2t1; u64 *level0_table = (u64 *)CONFIG_SYS_FSL_OCRAM_BASE; u64 *level1_table_0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x1000); u64 *level1_table_1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x2000); - u64 *level2_table = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000); - + u64 *level2_table_0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000); + u64 *level2_table_1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x4000); level0_table[0] = (u64)level1_table_0 | PMD_TYPE_TABLE; @@ -79,21 +85,25 @@ static inline void early_mmu_setup(void) */ section_l1t0 = 0; section_l1t1 = BLOCK_SIZE_L0; - section_l2 = 0; + section_l2t0 = 0; + section_l2t1 = CONFIG_SYS_FLASH_BASE; for (i = 0; i < 512; i++) { set_pgtable_section(level1_table_0, i, section_l1t0, MT_DEVICE_NGNRNE); set_pgtable_section(level1_table_1, i, section_l1t1, MT_NORMAL); - set_pgtable_section(level2_table, i, section_l2, + set_pgtable_section(level2_table_0, i, section_l2t0, + MT_DEVICE_NGNRNE); + set_pgtable_section(level2_table_1, i, section_l2t1, MT_DEVICE_NGNRNE); section_l1t0 += BLOCK_SIZE_L1; section_l1t1 += BLOCK_SIZE_L1; - section_l2 += BLOCK_SIZE_L2; + section_l2t0 += BLOCK_SIZE_L2; + section_l2t1 += BLOCK_SIZE_L2; } level1_table_0[0] = - (u64)level2_table | PMD_TYPE_TABLE; + (u64)level2_table_0 | PMD_TYPE_TABLE; level1_table_0[1] = 0x40000000 | PMD_SECT_AF | PMD_TYPE_SECT | PMD_ATTRINDX(MT_DEVICE_NGNRNE); @@ -104,17 +114,34 @@ static inline void early_mmu_setup(void) 0xc0000000 | PMD_SECT_AF | PMD_TYPE_SECT | PMD_ATTRINDX(MT_NORMAL); - /* Rewrite table to enable cache */ - set_pgtable_section(level2_table, + /* Rewerite table to enable cache for OCRAM */ + set_pgtable_section(level2_table_0, CONFIG_SYS_FSL_OCRAM_BASE >> SECTION_SHIFT_L2, CONFIG_SYS_FSL_OCRAM_BASE, MT_NORMAL); - for (i = CONFIG_SYS_IFC_BASE >> SECTION_SHIFT_L2; - i < (CONFIG_SYS_IFC_BASE + CONFIG_SYS_IFC_SIZE) - >> SECTION_SHIFT_L2; i++) { - section_l2 = i << SECTION_SHIFT_L2; - set_pgtable_section(level2_table, i, - section_l2, MT_NORMAL); + +#if defined(CONFIG_SYS_NOR0_CSPR_EARLY) && defined(CONFIG_SYS_NOR_AMASK_EARLY) + /* Rewrite table to enable cache for two entries (4MB) */ + section_l2t1 = CONFIG_SYS_IFC_BASE; + set_pgtable_section(level2_table_0, + section_l2t1 >> SECTION_SHIFT_L2, + section_l2t1, + MT_NORMAL); + section_l2t1 += BLOCK_SIZE_L2; + set_pgtable_section(level2_table_0, + section_l2t1 >> SECTION_SHIFT_L2, + section_l2t1, + MT_NORMAL); +#endif + + /* Create a mapping for 256MB IFC region to final flash location */ + level1_table_0[CONFIG_SYS_FLASH_BASE >> SECTION_SHIFT_L1] = + (u64)level2_table_1 | PMD_TYPE_TABLE; + section_l2t1 = CONFIG_SYS_IFC_BASE; + for (i = 0; i < 0x10000000 >> SECTION_SHIFT_L2; i++) { + set_pgtable_section(level2_table_1, i, + section_l2t1, MT_DEVICE_NGNRNE); + section_l2t1 += BLOCK_SIZE_L2; } el = current_el(); @@ -347,6 +374,7 @@ u32 fsl_qoriq_core_to_type(unsigned int core) #ifdef CONFIG_DISPLAY_CPUINFO int print_cpuinfo(void) { + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); struct sys_info sysinfo; char buf[32]; unsigned int i, core; @@ -370,21 +398,40 @@ int print_cpuinfo(void) printf(" DP-DDR: %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus2)); puts("\n"); + /* Display the RCW, so that no one gets confused as to what RCW + * we're actually using for this boot. + */ + puts("Reset Configuration Word (RCW):"); + for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) { + u32 rcw = in_le32(&gur->rcwsr[i]); + + if ((i % 4) == 0) + printf("\n %02x:", i * 4); + printf(" %08x", rcw); + } + puts("\n"); + return 0; } #endif +#ifdef CONFIG_FSL_ESDHC +int cpu_mmc_init(bd_t *bis) +{ + return fsl_esdhc_mmc_init(bis); +} +#endif + int cpu_eth_init(bd_t *bis) { int error = 0; #ifdef CONFIG_FSL_MC_ENET - error = mc_init(bis); + error = fsl_mc_ldpaa_init(bis); #endif return error; } - int arch_early_init_r(void) { int rv; @@ -393,5 +440,43 @@ int arch_early_init_r(void) if (rv) printf("Did not wake secondary cores\n"); +#ifdef CONFIG_SYS_HAS_SERDES + fsl_serdes_init(); +#endif + return 0; +} + +int timer_init(void) +{ + u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR; + u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR; +#ifdef COUNTER_FREQUENCY_REAL + unsigned long cntfrq = COUNTER_FREQUENCY_REAL; + + /* Update with accurate clock frequency */ + asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory"); +#endif + + /* Enable timebase for all clusters. + * It is safe to do so even some clusters are not enabled. + */ + out_le32(cltbenr, 0xf); + + /* Enable clock for timer + * This is a global setting. + */ + out_le32(cntcr, 0x1); + return 0; } + +void reset_cpu(ulong addr) +{ + u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR; + u32 val; + + /* Raise RESET_REQ_B */ + val = in_le32(rstcr); + val |= 0x02; + out_le32(rstcr, val); +} diff --git a/arch/arm/cpu/armv8/fsl-lsch3/fdt.c b/arch/arm/cpu/armv8/fsl-lsch3/fdt.c index 7eb9b6a..d370023 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/fdt.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/fdt.c @@ -7,6 +7,9 @@ #include <common.h> #include <libfdt.h> #include <fdt_support.h> +#ifdef CONFIG_FSL_ESDHC +#include <fsl_esdhc.h> +#endif #include "mp.h" #ifdef CONFIG_MP @@ -62,7 +65,11 @@ void ft_cpu_setup(void *blob, bd_t *bd) #endif #ifdef CONFIG_SYS_NS16550 - do_fixup_by_compat_u32(blob, "ns16550", + do_fixup_by_compat_u32(blob, "fsl,ns16550", "clock-frequency", CONFIG_SYS_NS16550_CLK, 1); #endif + +#if defined(CONFIG_FSL_ESDHC) + fdt_fixup_esdhc(blob, bd); +#endif } diff --git a/arch/arm/cpu/armv8/fsl-lsch3/fsl_lsch3_serdes.c b/arch/arm/cpu/armv8/fsl-lsch3/fsl_lsch3_serdes.c new file mode 100644 index 0000000..02ca126 --- /dev/null +++ b/arch/arm/cpu/armv8/fsl-lsch3/fsl_lsch3_serdes.c @@ -0,0 +1,115 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/fsl_serdes.h> +#include <asm/arch-fsl-lsch3/immap_lsch3.h> +#include <fsl-mc/ldpaa_wriop.h> + +#ifdef CONFIG_SYS_FSL_SRDS_1 +static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT]; +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 +static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT]; +#endif + +int is_serdes_configured(enum srds_prtcl device) +{ + int ret = 0; + +#ifdef CONFIG_SYS_FSL_SRDS_1 + ret |= serdes1_prtcl_map[device]; +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 + ret |= serdes2_prtcl_map[device]; +#endif + + return !!ret; +} + +int serdes_get_first_lane(u32 sd, enum srds_prtcl device) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 cfg = in_le32(&gur->rcwsr[28]); + int i; + + switch (sd) { +#ifdef CONFIG_SYS_FSL_SRDS_1 + case FSL_SRDS_1: + cfg &= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK; + cfg >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT; + break; +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 + case FSL_SRDS_2: + cfg &= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK; + cfg >>= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT; + break; +#endif + default: + printf("invalid SerDes%d\n", sd); + break; + } + /* Is serdes enabled at all? */ + if (cfg == 0) + return -ENODEV; + + for (i = 0; i < SRDS_MAX_LANES; i++) { + if (serdes_get_prtcl(sd, cfg, i) == device) + return i; + } + + return -ENODEV; +} + +void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift, + u8 serdes_prtcl_map[SERDES_PRCTL_COUNT]) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 cfg; + int lane; + + memset(serdes_prtcl_map, 0, sizeof(serdes_prtcl_map)); + + cfg = in_le32(&gur->rcwsr[28]) & sd_prctl_mask; + cfg >>= sd_prctl_shift; + printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg); + + if (!is_serdes_prtcl_valid(sd, cfg)) + printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg); + + for (lane = 0; lane < SRDS_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane); + if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT)) + debug("Unknown SerDes lane protocol %d\n", lane_prtcl); + else { + serdes_prtcl_map[lane_prtcl] = 1; +#ifdef CONFIG_FSL_MC_ENET + wriop_init_dpmac(sd, lane + 1, (int)lane_prtcl); +#endif + } + } +} + +void fsl_serdes_init(void) +{ +#ifdef CONFIG_SYS_FSL_SRDS_1 + serdes_init(FSL_SRDS_1, + CONFIG_SYS_FSL_LSCH3_SERDES_ADDR, + FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK, + FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT, + serdes1_prtcl_map); +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 + serdes_init(FSL_SRDS_2, + CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + FSL_SRDS_2 * 0x10000, + FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK, + FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT, + serdes2_prtcl_map); +#endif +} diff --git a/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S b/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S index 886576e..018c617 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S +++ b/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S @@ -15,6 +15,15 @@ ENTRY(lowlevel_init) mov x29, lr /* Save LR */ + /* Add fully-coherent masters to DVM domain */ + ldr x1, =CCI_MN_BASE + ldr x2, [x1, #CCI_MN_RNF_NODEID_LIST] + str x2, [x1, #CCI_MN_DVM_DOMAIN_CTL_SET] +1: ldr x3, [x1, #CCI_MN_DVM_DOMAIN_CTL_SET] + mvn x0, x3 + tst x0, x3 /* Wait for domain addition to complete */ + b.ne 1b + /* Set the SMMU page size in the sACR register */ ldr x1, =SMMU_BASE ldr w0, [x1, #0x10] @@ -224,6 +233,9 @@ ENTRY(secondary_boot_func) /* physical address of this cpus spin table element */ add x11, x1, x0 + ldr x0, =__real_cntfrq + ldr x0, [x0] + msr cntfrq_el0, x0 /* set with real frequency */ str x9, [x11, #16] /* LPID */ mov x4, #1 str x4, [x11, #8] /* STATUS */ @@ -275,6 +287,9 @@ ENDPROC(secondary_switch_to_el1) /* 64 bit alignment for elements accessed as data */ .align 4 + .global __real_cntfrq +__real_cntfrq: + .quad COUNTER_FREQUENCY .globl __secondary_boot_code_size .type __secondary_boot_code_size, %object /* Secondary Boot Code ends here */ diff --git a/arch/arm/cpu/armv8/fsl-lsch3/ls2085a_serdes.c b/arch/arm/cpu/armv8/fsl-lsch3/ls2085a_serdes.c new file mode 100644 index 0000000..098745b --- /dev/null +++ b/arch/arm/cpu/armv8/fsl-lsch3/ls2085a_serdes.c @@ -0,0 +1,117 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/fsl_serdes.h> +#include <asm/arch-fsl-lsch3/immap_lsch3.h> + +struct serdes_config { + u8 protocol; + u8 lanes[SRDS_MAX_LANES]; +}; + +static struct serdes_config serdes1_cfg_tbl[] = { + /* SerDes 1 */ + {0x03, {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2 } }, + {0x05, {PCIE2, PCIE2, PCIE2, PCIE2, SGMII4, SGMII3, SGMII2, SGMII1 } }, + {0x07, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2, + SGMII1 } }, + {0x09, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2, + SGMII1 } }, + {0x0A, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2, + SGMII1 } }, + {0x0C, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2, + SGMII1 } }, + {0x0E, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2, + SGMII1 } }, + {0x26, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, XFI2, XFI1 } }, + {0x28, {SGMII8, SGMII7, SGMII6, SGMII5, XFI4, XFI3, XFI2, XFI1 } }, + {0x2A, {XFI8, XFI7, XFI6, XFI5, XFI4, XFI3, XFI2, XFI1 } }, + {0x2B, {SGMII8, SGMII7, SGMII6, SGMII5, XAUI1, XAUI1, XAUI1, XAUI1 } }, + {0x32, {XAUI2, XAUI2, XAUI2, XAUI2, XAUI1, XAUI1, XAUI1, XAUI1 } }, + {0x33, {PCIE2, PCIE2, PCIE2, PCIE2, QSGMII_D, QSGMII_C, QSGMII_B, + QSGMII_A} }, + {0x35, {QSGMII_D, QSGMII_C, QSGMII_B, PCIE2, XFI4, XFI3, XFI2, XFI1 } }, + {} +}; +static struct serdes_config serdes2_cfg_tbl[] = { + /* SerDes 2 */ + {0x07, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15, + SGMII16 } }, + {0x09, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15, + SGMII16 } }, + {0x0A, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15, + SGMII16 } }, + {0x0C, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15, + SGMII16 } }, + {0x0E, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15, + SGMII16 } }, + {0x3D, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3 } }, + {0x3E, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3 } }, + {0x3F, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } }, + {0x40, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } }, + {0x41, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SATA1, SATA2 } }, + {0x42, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SATA1, SATA2 } }, + {0x43, {PCIE3, PCIE3, PCIE3, PCIE3, NONE, NONE, SATA1, SATA2 } }, + {0x44, {PCIE3, PCIE3, PCIE3, PCIE3, NONE, NONE, SATA1, SATA2 } }, + {0x45, {PCIE3, SGMII10, SGMII11, SGMII12, PCIE4, SGMII14, SGMII15, + SGMII16 } }, + {0x47, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, PCIE4, + PCIE4 } }, + {0x49, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, SATA1, + SATA2 } }, + {0x4A, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, SATA1, + SATA2 } }, + {} +}; + +static struct serdes_config *serdes_cfg_tbl[] = { + serdes1_cfg_tbl, + serdes2_cfg_tbl, +}; + +enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane) +{ + struct serdes_config *ptr; + + if (serdes >= ARRAY_SIZE(serdes_cfg_tbl)) + return 0; + + ptr = serdes_cfg_tbl[serdes]; + while (ptr->protocol) { + if (ptr->protocol == cfg) + return ptr->lanes[lane]; + ptr++; + } + + return 0; +} + +int is_serdes_prtcl_valid(int serdes, u32 prtcl) +{ + int i; + struct serdes_config *ptr; + + if (serdes >= ARRAY_SIZE(serdes_cfg_tbl)) + return 0; + + ptr = serdes_cfg_tbl[serdes]; + while (ptr->protocol) { + if (ptr->protocol == prtcl) + break; + ptr++; + } + + if (!ptr->protocol) + return 0; + + for (i = 0; i < SRDS_MAX_LANES; i++) { + if (ptr->lanes[i] != NONE) + return 1; + } + + return 0; +} diff --git a/arch/arm/cpu/armv8/fsl-lsch3/mp.c b/arch/arm/cpu/armv8/fsl-lsch3/mp.c index ce9c0c1..da7853a 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/mp.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/mp.c @@ -31,6 +31,13 @@ int fsl_lsch3_wake_seconday_cores(void) int i, timeout = 10; u64 *table = get_spin_tbl_addr(); +#ifdef COUNTER_FREQUENCY_REAL + /* update for secondary cores */ + __real_cntfrq = COUNTER_FREQUENCY_REAL; + flush_dcache_range((unsigned long)&__real_cntfrq, + (unsigned long)&__real_cntfrq + 8); +#endif + cores = cpu_mask(); /* Clear spin table so that secondary processors * observe the correct value after waking up from wfe. diff --git a/arch/arm/cpu/armv8/fsl-lsch3/mp.h b/arch/arm/cpu/armv8/fsl-lsch3/mp.h index 66144d6..c985d6a 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/mp.h +++ b/arch/arm/cpu/armv8/fsl-lsch3/mp.h @@ -26,6 +26,7 @@ #define id_to_core(x) ((x & 3) | (x >> 6)) #ifndef __ASSEMBLY__ extern u64 __spin_table[]; +extern u64 __real_cntfrq; extern u64 *secondary_boot_code; extern size_t __secondary_boot_code_size; int fsl_lsch3_wake_seconday_cores(void); diff --git a/arch/arm/cpu/armv8/fsl-lsch3/soc.c b/arch/arm/cpu/armv8/fsl-lsch3/soc.c new file mode 100644 index 0000000..2538001 --- /dev/null +++ b/arch/arm/cpu/armv8/fsl-lsch3/soc.c @@ -0,0 +1,107 @@ +/* + * Copyright 2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <fsl_ifc.h> +#include <nand.h> +#include <spl.h> +#include <asm/arch-fsl-lsch3/soc.h> +#include <asm/io.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +static void erratum_a008751(void) +{ +#ifdef CONFIG_SYS_FSL_ERRATUM_A008751 + u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE; + + writel(0x27672b2a, scfg + SCFG_USB3PRM1CR / 4); +#endif +} + +static void erratum_rcw_src(void) +{ +#if defined(CONFIG_SPL) + u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE; + u32 __iomem *dcfg_dcsr = (u32 __iomem *)DCFG_DCSR_BASE; + u32 val; + + val = in_le32(dcfg_ccsr + DCFG_PORSR1 / 4); + val &= ~DCFG_PORSR1_RCW_SRC; + val |= DCFG_PORSR1_RCW_SRC_NOR; + out_le32(dcfg_dcsr + DCFG_DCSR_PORCR1 / 4, val); +#endif +} + +#define I2C_DEBUG_REG 0x6 +#define I2C_GLITCH_EN 0x8 +/* + * This erratum requires setting glitch_en bit to enable + * digital glitch filter to improve clock stability. + */ +static void erratum_a009203(void) +{ + u8 __iomem *ptr; +#ifdef CONFIG_SYS_I2C +#ifdef I2C1_BASE_ADDR + ptr = (u8 __iomem *)(I2C1_BASE_ADDR + I2C_DEBUG_REG); + + writeb(I2C_GLITCH_EN, ptr); +#endif +#ifdef I2C2_BASE_ADDR + ptr = (u8 __iomem *)(I2C2_BASE_ADDR + I2C_DEBUG_REG); + + writeb(I2C_GLITCH_EN, ptr); +#endif +#ifdef I2C3_BASE_ADDR + ptr = (u8 __iomem *)(I2C3_BASE_ADDR + I2C_DEBUG_REG); + + writeb(I2C_GLITCH_EN, ptr); +#endif +#ifdef I2C4_BASE_ADDR + ptr = (u8 __iomem *)(I2C4_BASE_ADDR + I2C_DEBUG_REG); + + writeb(I2C_GLITCH_EN, ptr); +#endif +#endif +} + +void fsl_lsch3_early_init_f(void) +{ + erratum_a008751(); + erratum_rcw_src(); + init_early_memctl_regs(); /* tighten IFC timing */ + erratum_a009203(); +} + +#ifdef CONFIG_SPL_BUILD +void board_init_f(ulong dummy) +{ + /* Clear global data */ + memset((void *)gd, 0, sizeof(gd_t)); + + arch_cpu_init(); + board_early_init_f(); + timer_init(); + env_init(); + gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE); + + serial_init(); + console_init_f(); + dram_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + board_init_r(NULL, 0); +} + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_NAND; +} +#endif diff --git a/arch/arm/cpu/armv8/fsl-lsch3/speed.c b/arch/arm/cpu/armv8/fsl-lsch3/speed.c index 72cd999..cac4f92 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/speed.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/speed.c @@ -26,7 +26,7 @@ void get_sys_info(struct sys_info *sys_info) { struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); #ifdef CONFIG_FSL_IFC - struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR; + struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL}; u32 ccr; #endif struct ccsr_clk_cluster_group __iomem *clk_grp[2] = { @@ -86,6 +86,8 @@ void get_sys_info(struct sys_info *sys_info) sys_info->freq_systembus *= (in_le32(&gur->rcwsr[0]) >> FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_SHIFT) & FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_MASK; + /* Platform clock is half of platform PLL */ + sys_info->freq_systembus /= 2; sys_info->freq_ddrbus *= (in_le32(&gur->rcwsr[0]) >> FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_SHIFT) & FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK; @@ -102,10 +104,7 @@ void get_sys_info(struct sys_info *sys_info) offsetof(struct ccsr_clk_cluster_group, pllngsr[i%3].gsr)); ratio[i] = (in_le32(offset) >> 1) & 0x3f; - if (ratio[i] > 4) - freq_c_pll[i] = sysclk * ratio[i]; - else - freq_c_pll[i] = sys_info->freq_systembus * ratio[i]; + freq_c_pll[i] = sysclk * ratio[i]; } for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) { @@ -119,7 +118,7 @@ void get_sys_info(struct sys_info *sys_info) } #if defined(CONFIG_FSL_IFC) - ccr = in_le32(&ifc_regs->ifc_ccr); + ccr = in_le32(&ifc_regs.gregs->ifc_ccr); ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1; sys_info->freq_localbus = sys_info->freq_systembus / ccr; diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c index 223b95e..8e60bae 100644 --- a/arch/arm/cpu/armv8/generic_timer.c +++ b/arch/arm/cpu/armv8/generic_timer.c @@ -25,7 +25,18 @@ unsigned long get_tbclk(void) unsigned long timer_read_counter(void) { unsigned long cntpct; +#ifdef CONFIG_SYS_FSL_ERRATUM_A008585 + /* This erratum number needs to be confirmed to match ARM document */ + unsigned long temp; +#endif isb(); asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); +#ifdef CONFIG_SYS_FSL_ERRATUM_A008585 + asm volatile("mrs %0, cntpct_el0" : "=r" (temp)); + while (temp != cntpct) { + asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); + asm volatile("mrs %0, cntpct_el0" : "=r" (temp)); + } +#endif return cntpct; } diff --git a/arch/arm/cpu/armv8/u-boot-spl.lds b/arch/arm/cpu/armv8/u-boot-spl.lds new file mode 100644 index 0000000..4df339c --- /dev/null +++ b/arch/arm/cpu/armv8/u-boot-spl.lds @@ -0,0 +1,77 @@ +/* + * (C) Copyright 2013 + * David Feng <fenghua@phytium.com.cn> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE, + LENGTH = CONFIG_SPL_MAX_SIZE } +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SECTIONS +{ + .text : { + . = ALIGN(8); + *(.__image_copy_start) + CPUDIR/start.o (.text*) + *(.text*) + } >.sram + + .rodata : { + . = ALIGN(8); + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + } >.sram + + .data : { + . = ALIGN(8); + *(.data*) + } >.sram + + .u_boot_list : { + . = ALIGN(8); + KEEP(*(SORT(.u_boot_list*))); + } >.sram + + .image_copy_end : { + . = ALIGN(8); + *(.__image_copy_end) + } >.sram + + .end : { + . = ALIGN(8); + *(.__end) + } >.sram + + .bss_start : { + . = ALIGN(8); + KEEP(*(.__bss_start)); + } >.sdram + + .bss : { + *(.bss*) + . = ALIGN(8); + } >.sdram + + .bss_end : { + KEEP(*(.__bss_end)); + } >.sdram + + /DISCARD/ : { *(.dynsym) } + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } +} diff --git a/arch/arm/cpu/armv8/zynqmp/Makefile b/arch/arm/cpu/armv8/zynqmp/Makefile index a997e04..efab5ea 100644 --- a/arch/arm/cpu/armv8/zynqmp/Makefile +++ b/arch/arm/cpu/armv8/zynqmp/Makefile @@ -7,3 +7,4 @@ obj-y += clk.o obj-y += cpu.o +obj-$(CONFIG_MP) += mp.o diff --git a/arch/arm/cpu/armv8/zynqmp/clk.c b/arch/arm/cpu/armv8/zynqmp/clk.c index 0af619d..9218586 100644 --- a/arch/arm/cpu/armv8/zynqmp/clk.c +++ b/arch/arm/cpu/armv8/zynqmp/clk.c @@ -6,6 +6,7 @@ */ #include <common.h> +#include <asm/arch/clk.h> #include <asm/arch/hardware.h> #include <asm/arch/sys_proto.h> @@ -16,6 +17,8 @@ unsigned long get_uart_clk(int dev_id) u32 ver = zynqmp_get_silicon_version(); switch (ver) { + case ZYNQMP_CSU_VERSION_VELOCE: + return 48000; case ZYNQMP_CSU_VERSION_EP108: return 25000000; } diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c index 6fae03c..60d7d20 100644 --- a/arch/arm/cpu/armv8/zynqmp/cpu.c +++ b/arch/arm/cpu/armv8/zynqmp/cpu.c @@ -20,9 +20,175 @@ unsigned int zynqmp_get_silicon_version(void) gd->cpu_clk = get_tbclk(); switch (gd->cpu_clk) { + case 0 ... 1000000: + return ZYNQMP_CSU_VERSION_VELOCE; case 50000000: return ZYNQMP_CSU_VERSION_QEMU; } return ZYNQMP_CSU_VERSION_EP108; } + +#ifndef CONFIG_SYS_DCACHE_OFF +#include <asm/armv8/mmu.h> + +#define SECTION_SHIFT_L1 30UL +#define SECTION_SHIFT_L2 21UL +#define BLOCK_SIZE_L0 0x8000000000UL +#define BLOCK_SIZE_L1 (1 << SECTION_SHIFT_L1) +#define BLOCK_SIZE_L2 (1 << SECTION_SHIFT_L2) + +#define TCR_TG1_4K (1 << 31) +#define TCR_EPD1_DISABLE (1 << 23) +#define ZYNQMO_VA_BITS 40 +#define ZYNQMP_TCR TCR_TG1_4K | \ + TCR_EPD1_DISABLE | \ + TCR_SHARED_OUTER | \ + TCR_SHARED_INNER | \ + TCR_IRGN_WBWA | \ + TCR_ORGN_WBWA | \ + TCR_T0SZ(ZYNQMO_VA_BITS) + +#define MEMORY_ATTR PMD_SECT_AF | PMD_SECT_INNER_SHARE | \ + PMD_ATTRINDX(MT_NORMAL) | \ + PMD_TYPE_SECT +#define DEVICE_ATTR PMD_SECT_AF | PMD_SECT_PXN | \ + PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_NGNRNE) | \ + PMD_TYPE_SECT + +/* 4K size is required to place 512 entries in each level */ +#define TLB_TABLE_SIZE 0x1000 + +struct attr_tbl { + u32 num; + u64 attr; +}; + +static struct attr_tbl attr_tbll1t0[4] = { {16, 0x0}, + {8, DEVICE_ATTR}, + {32, MEMORY_ATTR}, + {456, DEVICE_ATTR} + }; +static struct attr_tbl attr_tbll2t3[4] = { {0x180, DEVICE_ATTR}, + {0x40, 0x0}, + {0x3F, DEVICE_ATTR}, + {0x1, MEMORY_ATTR} + }; + +/* + * This mmu table looks as below + * Level 0 table contains two entries to 512GB sizes. One is Level1 Table 0 + * and other Level1 Table1. + * Level1 Table0 contains entries for each 1GB from 0 to 511GB. + * Level1 Table1 contains entries for each 1GB from 512GB to 1TB. + * Level2 Table0, Level2 Table1, Level2 Table2 and Level2 Table3 contains + * entries for each 2MB starting from 0GB, 1GB, 2GB and 3GB respectively. + */ +static void zynqmp_mmu_setup(void) +{ + int el; + u32 index_attr; + u64 i, section_l1t0, section_l1t1; + u64 section_l2t0, section_l2t1, section_l2t2, section_l2t3; + u64 *level0_table = (u64 *)gd->arch.tlb_addr; + u64 *level1_table_0 = (u64 *)(gd->arch.tlb_addr + TLB_TABLE_SIZE); + u64 *level1_table_1 = (u64 *)(gd->arch.tlb_addr + (2 * TLB_TABLE_SIZE)); + u64 *level2_table_0 = (u64 *)(gd->arch.tlb_addr + (3 * TLB_TABLE_SIZE)); + u64 *level2_table_1 = (u64 *)(gd->arch.tlb_addr + (4 * TLB_TABLE_SIZE)); + u64 *level2_table_2 = (u64 *)(gd->arch.tlb_addr + (5 * TLB_TABLE_SIZE)); + u64 *level2_table_3 = (u64 *)(gd->arch.tlb_addr + (6 * TLB_TABLE_SIZE)); + + level0_table[0] = + (u64)level1_table_0 | PMD_TYPE_TABLE; + level0_table[1] = + (u64)level1_table_1 | PMD_TYPE_TABLE; + + /* + * set level 1 table 0, covering 0 to 512GB + * set level 1 table 1, covering 512GB to 1TB + */ + section_l1t0 = 0; + section_l1t1 = BLOCK_SIZE_L0; + + index_attr = 0; + for (i = 0; i < 512; i++) { + level1_table_0[i] = section_l1t0; + level1_table_0[i] |= attr_tbll1t0[index_attr].attr; + attr_tbll1t0[index_attr].num--; + if (attr_tbll1t0[index_attr].num == 0) + index_attr++; + level1_table_1[i] = section_l1t1; + level1_table_1[i] |= DEVICE_ATTR; + section_l1t0 += BLOCK_SIZE_L1; + section_l1t1 += BLOCK_SIZE_L1; + } + + level1_table_0[0] = + (u64)level2_table_0 | PMD_TYPE_TABLE; + level1_table_0[1] = + (u64)level2_table_1 | PMD_TYPE_TABLE; + level1_table_0[2] = + (u64)level2_table_2 | PMD_TYPE_TABLE; + level1_table_0[3] = + (u64)level2_table_3 | PMD_TYPE_TABLE; + + section_l2t0 = 0; + section_l2t1 = section_l2t0 + BLOCK_SIZE_L1; /* 1GB */ + section_l2t2 = section_l2t1 + BLOCK_SIZE_L1; /* 2GB */ + section_l2t3 = section_l2t2 + BLOCK_SIZE_L1; /* 3GB */ + + index_attr = 0; + + for (i = 0; i < 512; i++) { + level2_table_0[i] = section_l2t0 | MEMORY_ATTR; + level2_table_1[i] = section_l2t1 | MEMORY_ATTR; + level2_table_2[i] = section_l2t2 | DEVICE_ATTR; + level2_table_3[i] = section_l2t3 | + attr_tbll2t3[index_attr].attr; + attr_tbll2t3[index_attr].num--; + if (attr_tbll2t3[index_attr].num == 0) + index_attr++; + section_l2t0 += BLOCK_SIZE_L2; + section_l2t1 += BLOCK_SIZE_L2; + section_l2t2 += BLOCK_SIZE_L2; + section_l2t3 += BLOCK_SIZE_L2; + } + + /* flush new MMU table */ + flush_dcache_range(gd->arch.tlb_addr, + gd->arch.tlb_addr + gd->arch.tlb_size); + + /* point TTBR to the new table */ + el = current_el(); + set_ttbr_tcr_mair(el, gd->arch.tlb_addr, + ZYNQMP_TCR, MEMORY_ATTRIBUTES); + + set_sctlr(get_sctlr() | CR_M); +} + +int arch_cpu_init(void) +{ + icache_enable(); + __asm_invalidate_dcache_all(); + __asm_invalidate_tlb_all(); + return 0; +} + +/* + * This function is called from lib/board.c. + * It recreates MMU table in main memory. MMU and d-cache are enabled earlier. + * There is no need to disable d-cache for this operation. + */ +void enable_caches(void) +{ + /* The data cache is not active unless the mmu is enabled */ + if (!(get_sctlr() & CR_M)) { + invalidate_dcache_all(); + __asm_invalidate_tlb_all(); + zynqmp_mmu_setup(); + } + puts("Enabling Caches...\n"); + + set_sctlr(get_sctlr() | CR_C); +} +#endif diff --git a/arch/arm/cpu/armv8/zynqmp/mp.c b/arch/arm/cpu/armv8/zynqmp/mp.c new file mode 100644 index 0000000..17e32a7 --- /dev/null +++ b/arch/arm/cpu/armv8/zynqmp/mp.c @@ -0,0 +1,242 @@ +/* + * (C) Copyright 2014 - 2015 Xilinx, Inc. + * Michal Simek <michal.simek@xilinx.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/hardware.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> + +#define LOCK 0 +#define SPLIT 1 + +#define HALT 0 +#define RELEASE 1 + +#define ZYNQMP_BOOTADDR_HIGH_MASK 0xFFFFFFFF +#define ZYNQMP_R5_HIVEC_ADDR 0xFFFF0000 +#define ZYNQMP_R5_LOVEC_ADDR 0x0 +#define ZYNQMP_RPU_CFG_CPU_HALT_MASK 0x01 +#define ZYNQMP_RPU_CFG_HIVEC_MASK 0x04 +#define ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK 0x08 +#define ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK 0x40 +#define ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK 0x10 + +#define ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK 0x04 +#define ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK 0x01 +#define ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK 0x02 +#define ZYNQMP_CRLAPB_CPU_R5_CTRL_CLKACT_MASK 0x1000000 + +#define ZYNQMP_TCM_START_ADDRESS 0xFFE00000 +#define ZYNQMP_TCM_BOTH_SIZE 0x40000 + +#define ZYNQMP_CORE_APU0 0 +#define ZYNQMP_CORE_APU3 3 + +#define ZYNQMP_MAX_CORES 6 + +int is_core_valid(unsigned int core) +{ + if (core < ZYNQMP_MAX_CORES) + return 1; + + return 0; +} + +int cpu_reset(int nr) +{ + puts("Feature is not implemented.\n"); + return 0; +} + +static void set_r5_halt_mode(u8 halt, u8 mode) +{ + u32 tmp; + + tmp = readl(&rpu_base->rpu0_cfg); + if (halt == HALT) + tmp &= ~ZYNQMP_RPU_CFG_CPU_HALT_MASK; + else + tmp |= ZYNQMP_RPU_CFG_CPU_HALT_MASK; + writel(tmp, &rpu_base->rpu0_cfg); + + if (mode == LOCK) { + tmp = readl(&rpu_base->rpu1_cfg); + if (halt == HALT) + tmp &= ~ZYNQMP_RPU_CFG_CPU_HALT_MASK; + else + tmp |= ZYNQMP_RPU_CFG_CPU_HALT_MASK; + writel(tmp, &rpu_base->rpu1_cfg); + } +} + +static void set_r5_tcm_mode(u8 mode) +{ + u32 tmp; + + tmp = readl(&rpu_base->rpu_glbl_ctrl); + if (mode == LOCK) { + tmp &= ~ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK; + tmp |= ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK | + ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK; + } else { + tmp |= ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK; + tmp &= ~(ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK | + ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK); + } + + writel(tmp, &rpu_base->rpu_glbl_ctrl); +} + +static void set_r5_reset(u8 mode) +{ + u32 tmp; + + tmp = readl(&crlapb_base->rst_lpd_top); + tmp |= (ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK | + ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK); + + if (mode == LOCK) + tmp |= ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK; + + writel(tmp, &crlapb_base->rst_lpd_top); +} + +static void release_r5_reset(u8 mode) +{ + u32 tmp; + + tmp = readl(&crlapb_base->rst_lpd_top); + tmp &= ~(ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK | + ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK); + + if (mode == LOCK) + tmp &= ~ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK; + + writel(tmp, &crlapb_base->rst_lpd_top); +} + +static void enable_clock_r5(void) +{ + u32 tmp; + + tmp = readl(&crlapb_base->cpu_r5_ctrl); + tmp |= ZYNQMP_CRLAPB_CPU_R5_CTRL_CLKACT_MASK; + writel(tmp, &crlapb_base->cpu_r5_ctrl); + + /* Give some delay for clock + * to propogate */ + udelay(0x500); +} + +int cpu_disable(int nr) +{ + if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) { + u32 val = readl(&crfapb_base->rst_fpd_apu); + val |= 1 << nr; + writel(val, &crfapb_base->rst_fpd_apu); + } else { + set_r5_reset(LOCK); + } + + return 0; +} + +int cpu_status(int nr) +{ + if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) { + u32 addr_low = readl(((u8 *)&apu_base->rvbar_addr0_l) + nr * 8); + u32 addr_high = readl(((u8 *)&apu_base->rvbar_addr0_h) + + nr * 8); + u32 val = readl(&crfapb_base->rst_fpd_apu); + val &= 1 << nr; + printf("APU CPU%d %s - starting address HI: %x, LOW: %x\n", + nr, val ? "OFF" : "ON" , addr_high, addr_low); + } else { + u32 val = readl(&crlapb_base->rst_lpd_top); + val &= 1 << (nr - 4); + printf("RPU CPU%d %s\n", nr - 4, val ? "OFF" : "ON"); + } + + return 0; +} + +static void set_r5_start(u8 high) +{ + u32 tmp; + + tmp = readl(&rpu_base->rpu0_cfg); + if (high) + tmp |= ZYNQMP_RPU_CFG_HIVEC_MASK; + else + tmp &= ~ZYNQMP_RPU_CFG_HIVEC_MASK; + writel(tmp, &rpu_base->rpu0_cfg); + + tmp = readl(&rpu_base->rpu1_cfg); + if (high) + tmp |= ZYNQMP_RPU_CFG_HIVEC_MASK; + else + tmp &= ~ZYNQMP_RPU_CFG_HIVEC_MASK; + writel(tmp, &rpu_base->rpu1_cfg); +} + +int cpu_release(int nr, int argc, char * const argv[]) +{ + if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) { + u64 boot_addr = simple_strtoull(argv[0], NULL, 16); + /* HIGH */ + writel((u32)(boot_addr >> 32), + ((u8 *)&apu_base->rvbar_addr0_h) + nr * 8); + /* LOW */ + writel((u32)(boot_addr & ZYNQMP_BOOTADDR_HIGH_MASK), + ((u8 *)&apu_base->rvbar_addr0_l) + nr * 8); + + u32 val = readl(&crfapb_base->rst_fpd_apu); + val &= ~(1 << nr); + writel(val, &crfapb_base->rst_fpd_apu); + } else { + if (argc != 2) { + printf("Invalid number of arguments to release.\n"); + printf("<addr> <mode>-Start addr lockstep or split\n"); + return 1; + } + + u32 boot_addr = simple_strtoul(argv[0], NULL, 16); + if (!(boot_addr == ZYNQMP_R5_LOVEC_ADDR || + boot_addr == ZYNQMP_R5_HIVEC_ADDR)) { + printf("Invalid starting address 0x%x\n", boot_addr); + printf("0 or 0xffff0000 are permitted\n"); + return 1; + } + + if (!strncmp(argv[1], "lockstep", 8)) { + printf("R5 lockstep mode\n"); + set_r5_tcm_mode(LOCK); + set_r5_halt_mode(HALT, LOCK); + + if (boot_addr == 0) + set_r5_start(0); + else + set_r5_start(1); + + enable_clock_r5(); + release_r5_reset(LOCK); + set_r5_halt_mode(RELEASE, LOCK); + } else if (!strncmp(argv[1], "split", 5)) { + printf("R5 split mode\n"); + set_r5_tcm_mode(SPLIT); + set_r5_halt_mode(HALT, SPLIT); + enable_clock_r5(); + release_r5_reset(SPLIT); + set_r5_halt_mode(RELEASE, SPLIT); + } else { + printf("Unsupported mode\n"); + return 1; + } + } + + return 0; +} diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index f897e6d..46a6171 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -39,11 +39,12 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \ uniphier-ph1-pro4-ref.dtb \ uniphier-ph1-ld4-ref.dtb \ uniphier-ph1-sld8-ref.dtb -dtb-$(CONFIG_ZYNQ) += zynq-zc702.dtb \ +dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb \ zynq-zc706.dtb \ zynq-zed.dtb \ zynq-zybo.dtb \ zynq-microzed.dtb \ + zynq-picozed.dtb \ zynq-zc770-xm010.dtb \ zynq-zc770-xm012.dtb \ zynq-zc770-xm013.dtb @@ -54,6 +55,9 @@ dtb-$(CONFIG_SOCFPGA) += \ socfpga_cyclone5_socdk.dtb \ socfpga_cyclone5_socrates.dtb +dtb-$(CONFIG_LS102XA) += ls1021a-qds.dtb \ + ls1021a-twr.dtb + targets += $(dtb-y) DTC_FLAGS += -R 4 -p 0x1000 diff --git a/arch/arm/dts/exynos4210-pinctrl-uboot.dtsi b/arch/arm/dts/exynos4210-pinctrl-uboot.dtsi index f9b61ba..0ff41d0 100644 --- a/arch/arm/dts/exynos4210-pinctrl-uboot.dtsi +++ b/arch/arm/dts/exynos4210-pinctrl-uboot.dtsi @@ -2,6 +2,8 @@ * U-Boot additions to enable a generic Exynos GPIO driver * * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ */ /{ diff --git a/arch/arm/dts/exynos4x12-pinctrl-uboot.dtsi b/arch/arm/dts/exynos4x12-pinctrl-uboot.dtsi index c41d07b..8e5a6c6 100644 --- a/arch/arm/dts/exynos4x12-pinctrl-uboot.dtsi +++ b/arch/arm/dts/exynos4x12-pinctrl-uboot.dtsi @@ -2,6 +2,8 @@ * U-Boot additions to enable a generic Exynos GPIO driver * * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ */ /{ diff --git a/arch/arm/dts/exynos5250-pinctrl-uboot.dtsi b/arch/arm/dts/exynos5250-pinctrl-uboot.dtsi index 7edb0ca..068c5f6 100644 --- a/arch/arm/dts/exynos5250-pinctrl-uboot.dtsi +++ b/arch/arm/dts/exynos5250-pinctrl-uboot.dtsi @@ -2,6 +2,8 @@ * U-Boot additions to enable a generic Exynos GPIO driver * * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ */ /{ diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts index 7d8be69..e89a94f 100644 --- a/arch/arm/dts/exynos5250-snow.dts +++ b/arch/arm/dts/exynos5250-snow.dts @@ -40,9 +40,9 @@ }; i2c4: i2c@12ca0000 { - cros-ec@1e { + cros_ec: cros-ec@1e { reg = <0x1e>; - compatible = "google,cros-ec"; + compatible = "google,cros-ec-i2c"; i2c-max-frequency = <100000>; u-boot,i2c-offset-len = <0>; ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>; @@ -65,9 +65,10 @@ spi@131b0000 { spi-max-frequency = <1000000>; spi-deactivate-delay = <100>; - cros_ec: cros-ec@0 { - reg = <0>; - compatible = "google,cros-ec"; + + embedded-controller { + compatible = "google,cros-ec-i2c"; + reg = <0x1e>; spi-max-frequency = <5000000>; ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>; optimise-flash-write; @@ -133,6 +134,7 @@ ehci@12110000 { samsung,vbus-gpio = <&gpx1 1 GPIO_ACTIVE_HIGH>; + status = "okay"; }; xhci@12000000 { diff --git a/arch/arm/dts/exynos5420-peach-pit.dts b/arch/arm/dts/exynos5420-peach-pit.dts index 3ad4728..7d8fa28 100644 --- a/arch/arm/dts/exynos5420-peach-pit.dts +++ b/arch/arm/dts/exynos5420-peach-pit.dts @@ -104,12 +104,12 @@ spi@12d40000 { /* spi2 */ spi-max-frequency = <4000000>; spi-deactivate-delay = <200>; + cros_ec: cros-ec@0 { + compatible = "google,cros-ec-spi"; reg = <0>; - compatible = "google,cros-ec"; spi-half-duplex; spi-max-timeout-ms = <1100>; - spi-frame-header = <0xec>; ec-interrupt = <&gpx1 5 GPIO_ACTIVE_LOW>; /* diff --git a/arch/arm/dts/exynos54xx-pinctrl-uboot.dtsi b/arch/arm/dts/exynos54xx-pinctrl-uboot.dtsi index 5a86211..635a1b0 100644 --- a/arch/arm/dts/exynos54xx-pinctrl-uboot.dtsi +++ b/arch/arm/dts/exynos54xx-pinctrl-uboot.dtsi @@ -2,6 +2,8 @@ * U-Boot additions to enable a generic Exynos GPIO driver * * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ */ /{ diff --git a/arch/arm/dts/exynos5800-peach-pi.dts b/arch/arm/dts/exynos5800-peach-pi.dts index 494f764..8c1f616 100644 --- a/arch/arm/dts/exynos5800-peach-pi.dts +++ b/arch/arm/dts/exynos5800-peach-pi.dts @@ -97,11 +97,10 @@ spi-max-frequency = <4000000>; spi-deactivate-delay = <200>; cros_ec: cros-ec@0 { + compatible = "google,cros-ec-spi"; reg = <0>; - compatible = "google,cros-ec"; spi-half-duplex; spi-max-timeout-ms = <1100>; - spi-frame-header = <0xec>; ec-interrupt = <&gpx1 5 GPIO_ACTIVE_LOW>; /* diff --git a/arch/arm/dts/ls1021a-qds.dts b/arch/arm/dts/ls1021a-qds.dts new file mode 100644 index 0000000..8367811 --- /dev/null +++ b/arch/arm/dts/ls1021a-qds.dts @@ -0,0 +1,216 @@ +/* + * Freescale ls1021a QDS board device tree source + * + * Copyright 2013-2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; +#include "ls1021a.dtsi" + +/ { + model = "LS1021A QDS Board"; + + aliases { + enet0_rgmii_phy = &rgmii_phy1; + enet1_rgmii_phy = &rgmii_phy2; + enet2_rgmii_phy = &rgmii_phy3; + enet0_sgmii_phy = &sgmii_phy1c; + enet1_sgmii_phy = &sgmii_phy1d; + spi0 = &qspi; + spi1 = &dspi0; + }; +}; + +&dspi0 { + bus-num = <0>; + status = "okay"; + + dspiflash: at45db021d@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash"; + spi-max-frequency = <16000000>; + spi-cpol; + spi-cpha; + reg = <0>; + }; +}; + +&qspi { + bus-num = <0>; + status = "okay"; + + qflash0: s25fl128s@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash"; + spi-max-frequency = <20000000>; + reg = <0>; + }; +}; + +&i2c0 { + status = "okay"; + + pca9547: mux@77 { + reg = <0x77>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0>; + + ds3232: rtc@68 { + compatible = "dallas,ds3232"; + reg = <0x68>; + interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2>; + + ina220@40 { + compatible = "ti,ina220"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + + ina220@41 { + compatible = "ti,ina220"; + reg = <0x41>; + shunt-resistor = <1000>; + }; + }; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x3>; + + eeprom@56 { + compatible = "atmel,24c512"; + reg = <0x56>; + }; + + eeprom@57 { + compatible = "atmel,24c512"; + reg = <0x57>; + }; + + adt7461a@4c { + compatible = "adi,adt7461a"; + reg = <0x4c>; + }; + }; + }; +}; + +&ifc { + #address-cells = <2>; + #size-cells = <1>; + /* NOR, NAND Flashes and FPGA on board */ + ranges = <0x0 0x0 0x60000000 0x08000000 + 0x2 0x0 0x7e800000 0x00010000 + 0x3 0x0 0x7fb00000 0x00000100>; + status = "okay"; + + nor@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x0 0x0 0x8000000>; + bank-width = <2>; + device-width = <1>; + }; + + fpga: board-control@3,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + reg = <0x3 0x0 0x0000100>; + bank-width = <1>; + device-width = <1>; + ranges = <0 3 0 0x100>; + + mdio-mux-emi1 { + compatible = "mdio-mux-mmioreg"; + mdio-parent-bus = <&mdio0>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x54 1>; /* BRDCFG4 */ + mux-mask = <0xe0>; /* EMI1[2:0] */ + + /* Onboard PHYs */ + ls1021amdio0: mdio@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + rgmii_phy1: ethernet-phy@1 { + reg = <0x1>; + }; + }; + + ls1021amdio1: mdio@20 { + reg = <0x20>; + #address-cells = <1>; + #size-cells = <0>; + rgmii_phy2: ethernet-phy@2 { + reg = <0x2>; + }; + }; + + ls1021amdio2: mdio@40 { + reg = <0x40>; + #address-cells = <1>; + #size-cells = <0>; + rgmii_phy3: ethernet-phy@3 { + reg = <0x3>; + }; + }; + + ls1021amdio3: mdio@60 { + reg = <0x60>; + #address-cells = <1>; + #size-cells = <0>; + sgmii_phy1c: ethernet-phy@1c { + reg = <0x1c>; + }; + }; + + ls1021amdio4: mdio@80 { + reg = <0x80>; + #address-cells = <1>; + #size-cells = <0>; + sgmii_phy1d: ethernet-phy@1d { + reg = <0x1d>; + }; + }; + }; + }; +}; + +&lpuart0 { + status = "okay"; +}; + +&mdio0 { + tbi0: tbi-phy@8 { + reg = <0x8>; + device_type = "tbi-phy"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; diff --git a/arch/arm/dts/ls1021a-twr.dts b/arch/arm/dts/ls1021a-twr.dts new file mode 100644 index 0000000..0e61c07 --- /dev/null +++ b/arch/arm/dts/ls1021a-twr.dts @@ -0,0 +1,87 @@ +/* + * Freescale ls1021a TWR board device tree source + * + * Copyright 2013-2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; +#include "ls1021a.dtsi" + +/ { + model = "LS1021A TWR Board"; + + aliases { + enet2_rgmii_phy = &rgmii_phy1; + enet0_sgmii_phy = &sgmii_phy2; + enet1_sgmii_phy = &sgmii_phy0; + spi0 = &qspi; + }; +}; + +&qspi { + bus-num = <0>; + status = "okay"; + + qflash0: n25q128a13@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash"; + spi-max-frequency = <20000000>; + reg = <0>; + }; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +&ifc { + #address-cells = <2>; + #size-cells = <1>; + /* NOR Flash on board */ + ranges = <0x0 0x0 0x60000000 0x08000000>; + status = "okay"; + + nor@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x0 0x0 0x8000000>; + bank-width = <2>; + device-width = <1>; + }; +}; + +&lpuart0 { + status = "okay"; +}; + +&mdio0 { + sgmii_phy0: ethernet-phy@0 { + reg = <0x0>; + }; + rgmii_phy1: ethernet-phy@1 { + reg = <0x1>; + }; + sgmii_phy2: ethernet-phy@2 { + reg = <0x2>; + }; + tbi1: tbi-phy@1f { + reg = <0x1f>; + device_type = "tbi-phy"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; diff --git a/arch/arm/dts/ls1021a.dtsi b/arch/arm/dts/ls1021a.dtsi new file mode 100644 index 0000000..7fadd7c --- /dev/null +++ b/arch/arm/dts/ls1021a.dtsi @@ -0,0 +1,381 @@ +/* + * Freescale ls1021a SOC common device tree source + * + * Copyright 2013-2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "skeleton.dtsi" +#include <dt-bindings/interrupt-controller/arm-gic.h> + +/ { + compatible = "fsl,ls1021a"; + interrupt-parent = <&gic>; + + aliases { + serial0 = &lpuart0; + serial1 = &lpuart1; + serial2 = &lpuart2; + serial3 = &lpuart3; + serial4 = &lpuart4; + serial5 = &lpuart5; + sysclk = &sysclk; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@f00 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0xf00>; + clocks = <&cluster1_clk>; + }; + + cpu@f01 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0xf01>; + clocks = <&cluster1_clk>; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + }; + + pmu { + compatible = "arm,cortex-a7-pmu"; + interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + interrupt-parent = <&gic>; + ranges; + + gic: interrupt-controller@1400000 { + compatible = "arm,cortex-a7-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x1401000 0x1000>, + <0x1402000 0x1000>, + <0x1404000 0x2000>, + <0x1406000 0x2000>; + interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + + }; + + ifc: ifc@1530000 { + compatible = "fsl,ifc", "simple-bus"; + reg = <0x1530000 0x10000>; + interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; + }; + + dcfg: dcfg@1ee0000 { + compatible = "fsl,ls1021a-dcfg", "syscon"; + reg = <0x1ee0000 0x10000>; + big-endian; + }; + + esdhc: esdhc@1560000 { + compatible = "fsl,esdhc"; + reg = <0x1560000 0x10000>; + interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <0>; + voltage-ranges = <1800 1800 3300 3300>; + sdhci,auto-cmd12; + big-endian; + bus-width = <4>; + status = "disabled"; + }; + + scfg: scfg@1570000 { + compatible = "fsl,ls1021a-scfg", "syscon"; + reg = <0x1570000 0x10000>; + big-endian; + }; + + clockgen: clocking@1ee1000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x1ee1000 0x10000>; + + sysclk: sysclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "sysclk"; + }; + + cga_pll1: pll@800 { + compatible = "fsl,qoriq-core-pll-2.0"; + #clock-cells = <1>; + reg = <0x800 0x10>; + clocks = <&sysclk>; + clock-output-names = "cga-pll1", "cga-pll1-div2", + "cga-pll1-div4"; + }; + + platform_clk: pll@c00 { + compatible = "fsl,qoriq-core-pll-2.0"; + #clock-cells = <1>; + reg = <0xc00 0x10>; + clocks = <&sysclk>; + clock-output-names = "platform-clk", "platform-clk-div2"; + }; + + cluster1_clk: clk0c0@0 { + compatible = "fsl,qoriq-core-mux-2.0"; + #clock-cells = <0>; + reg = <0x0 0x10>; + clock-names = "pll1cga", "pll1cga-div2", "pll1cga-div4"; + clocks = <&cga_pll1 0>, <&cga_pll1 1>, <&cga_pll1 2>; + clock-output-names = "cluster1-clk"; + }; + }; + + dspi0: dspi@2100000 { + compatible = "fsl,vf610-dspi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2100000 0x10000>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "dspi"; + clocks = <&platform_clk 1>; + num-cs = <6>; + big-endian; + status = "disabled"; + }; + + dspi1: dspi@2110000 { + compatible = "fsl,vf610-dspi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2110000 0x10000>; + interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "dspi"; + clocks = <&platform_clk 1>; + num-cs = <6>; + big-endian; + status = "disabled"; + }; + + qspi: quadspi@1550000 { + compatible = "fsl,vf610-qspi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x1550000 0x10000>, + <0x40000000 0x4000000>; + num-cs = <2>; + big-endian; + status = "disabled"; + }; + + i2c0: i2c@2180000 { + compatible = "fsl,vf610-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2180000 0x10000>; + interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "i2c"; + clocks = <&platform_clk 1>; + status = "disabled"; + }; + + i2c1: i2c@2190000 { + compatible = "fsl,vf610-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2190000 0x10000>; + interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "i2c"; + clocks = <&platform_clk 1>; + status = "disabled"; + }; + + i2c2: i2c@21a0000 { + compatible = "fsl,vf610-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x21a0000 0x10000>; + interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "i2c"; + clocks = <&platform_clk 1>; + status = "disabled"; + }; + + uart0: serial@21c0500 { + compatible = "fsl,16550-FIFO64", "ns16550a"; + reg = <0x21c0500 0x100>; + interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <0>; + fifo-size = <15>; + status = "disabled"; + }; + + uart1: serial@21c0600 { + compatible = "fsl,16550-FIFO64", "ns16550a"; + reg = <0x21c0600 0x100>; + interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <0>; + fifo-size = <15>; + status = "disabled"; + }; + + uart2: serial@21d0500 { + compatible = "fsl,16550-FIFO64", "ns16550a"; + reg = <0x21d0500 0x100>; + interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <0>; + fifo-size = <15>; + status = "disabled"; + }; + + uart3: serial@21d0600 { + compatible = "fsl,16550-FIFO64", "ns16550a"; + reg = <0x21d0600 0x100>; + interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <0>; + fifo-size = <15>; + status = "disabled"; + }; + + lpuart0: serial@2950000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x2950000 0x1000>; + interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&sysclk>; + clock-names = "ipg"; + status = "disabled"; + }; + + lpuart1: serial@2960000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x2960000 0x1000>; + interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&platform_clk 1>; + clock-names = "ipg"; + status = "disabled"; + }; + + lpuart2: serial@2970000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x2970000 0x1000>; + interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&platform_clk 1>; + clock-names = "ipg"; + status = "disabled"; + }; + + lpuart3: serial@2980000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x2980000 0x1000>; + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&platform_clk 1>; + clock-names = "ipg"; + status = "disabled"; + }; + + lpuart4: serial@2990000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x2990000 0x1000>; + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&platform_clk 1>; + clock-names = "ipg"; + status = "disabled"; + }; + + lpuart5: serial@29a0000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x29a0000 0x1000>; + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&platform_clk 1>; + clock-names = "ipg"; + status = "disabled"; + }; + + wdog0: watchdog@2ad0000 { + compatible = "fsl,imx21-wdt"; + reg = <0x2ad0000 0x10000>; + interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&platform_clk 1>; + clock-names = "wdog-en"; + big-endian; + }; + + sai1: sai@2b50000 { + compatible = "fsl,vf610-sai"; + reg = <0x2b50000 0x10000>; + interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&platform_clk 1>; + clock-names = "sai"; + dma-names = "tx", "rx"; + dmas = <&edma0 1 47>, + <&edma0 1 46>; + big-endian; + status = "disabled"; + }; + + sai2: sai@2b60000 { + compatible = "fsl,vf610-sai"; + reg = <0x2b60000 0x10000>; + interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&platform_clk 1>; + clock-names = "sai"; + dma-names = "tx", "rx"; + dmas = <&edma0 1 45>, + <&edma0 1 44>; + big-endian; + status = "disabled"; + }; + + edma0: edma@2c00000 { + #dma-cells = <2>; + compatible = "fsl,vf610-edma"; + reg = <0x2c00000 0x10000>, + <0x2c10000 0x10000>, + <0x2c20000 0x10000>; + interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "edma-tx", "edma-err"; + dma-channels = <32>; + big-endian; + clock-names = "dmamux0", "dmamux1"; + clocks = <&platform_clk 1>, + <&platform_clk 1>; + }; + + mdio0: mdio@2d24000 { + compatible = "gianfar"; + device_type = "mdio"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2d24000 0x4000>; + }; + + usb@8600000 { + compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr"; + reg = <0x8600000 0x1000>; + interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>; + dr_mode = "host"; + phy_type = "ulpi"; + }; + + usb3@3100000 { + compatible = "snps,dwc3"; + reg = <0x3100000 0x10000>; + interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; + dr_mode = "host"; + }; + }; +}; diff --git a/arch/arm/dts/s5pc100-pinctrl.dtsi b/arch/arm/dts/s5pc100-pinctrl.dtsi index bd9f97c..9753869 100644 --- a/arch/arm/dts/s5pc100-pinctrl.dtsi +++ b/arch/arm/dts/s5pc100-pinctrl.dtsi @@ -2,6 +2,8 @@ * U-Boot additions to enable a generic Exynos GPIO driver * * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ */ / { diff --git a/arch/arm/dts/s5pc110-pinctrl.dtsi b/arch/arm/dts/s5pc110-pinctrl.dtsi index d21b6ab..2e9d552 100644 --- a/arch/arm/dts/s5pc110-pinctrl.dtsi +++ b/arch/arm/dts/s5pc110-pinctrl.dtsi @@ -2,6 +2,8 @@ * U-Boot additions to enable a generic Exynos GPIO driver * * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ */ / { diff --git a/arch/arm/dts/skeleton64.dtsi b/arch/arm/dts/skeleton64.dtsi new file mode 100644 index 0000000..b5d7f36 --- /dev/null +++ b/arch/arm/dts/skeleton64.dtsi @@ -0,0 +1,13 @@ +/* + * Skeleton device tree in the 64 bits version; the bare minimum + * needed to boot; just include and add a compatible value. The + * bootloader will typically populate the memory node. + */ + +/ { + #address-cells = <2>; + #size-cells = <2>; + chosen { }; + aliases { }; + memory { device_type = "memory"; reg = <0 0 0 0>; }; +}; diff --git a/arch/arm/dts/socfpga_arria5_socdk.dts b/arch/arm/dts/socfpga_arria5_socdk.dts index 4e529a1..1b86897 100644 --- a/arch/arm/dts/socfpga_arria5_socdk.dts +++ b/arch/arm/dts/socfpga_arria5_socdk.dts @@ -25,6 +25,10 @@ * to be added to the gmac1 device tree blob. */ ethernet0 = &gmac1; + + spi0 = "/spi@ff705000"; /* QSPI */ + spi1 = "/spi@fff00000"; + spi2 = "/spi@fff01000"; }; regulator_3_3v: 3-3-v-regulator { @@ -72,3 +76,23 @@ &usb1 { status = "okay"; }; + +&qspi { + status = "okay"; + + flash0: n25q00@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q00"; + reg = <0>; /* chip select */ + spi-max-frequency = <50000000>; + m25p,fast-read; + page-size = <256>; + block-size = <16>; /* 2^16, 64KB */ + read-delay = <4>; /* delay value in read data capture register */ + tshsl-ns = <50>; + tsd2d-ns = <50>; + tchsh-ns = <4>; + tslch-ns = <4>; + }; +}; diff --git a/arch/arm/dts/socfpga_cyclone5_socdk.dts b/arch/arm/dts/socfpga_cyclone5_socdk.dts index 8e1f88c..0b300b9 100644 --- a/arch/arm/dts/socfpga_cyclone5_socdk.dts +++ b/arch/arm/dts/socfpga_cyclone5_socdk.dts @@ -25,6 +25,10 @@ * to be added to the gmac1 device tree blob. */ ethernet0 = &gmac1; + + spi0 = "/spi@ff705000"; /* QSPI */ + spi1 = "/spi@fff00000"; + spi2 = "/spi@fff01000"; }; regulator_3_3v: 3-3-v-regulator { @@ -77,3 +81,23 @@ &usb1 { status = "okay"; }; + +&qspi { + status = "okay"; + + flash0: n25q00@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q00"; + reg = <0>; /* chip select */ + spi-max-frequency = <50000000>; + m25p,fast-read; + page-size = <256>; + block-size = <16>; /* 2^16, 64KB */ + read-delay = <4>; /* delay value in read data capture register */ + tshsl-ns = <50>; + tsd2d-ns = <50>; + tchsh-ns = <4>; + tslch-ns = <4>; + }; +}; diff --git a/arch/arm/dts/tegra124-nyan-big.dts b/arch/arm/dts/tegra124-nyan-big.dts index c1f35a0..9367193 100644 --- a/arch/arm/dts/tegra124-nyan-big.dts +++ b/arch/arm/dts/tegra124-nyan-big.dts @@ -230,6 +230,7 @@ usb@7d000000 { /* Rear external USB port. */ status = "okay"; + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>; }; usb-phy@7d000000 { @@ -246,6 +247,7 @@ usb@7d008000 { /* Left external USB port. */ status = "okay"; + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>; }; usb-phy@7d008000 { diff --git a/arch/arm/dts/zynq-picozed.dts b/arch/arm/dts/zynq-picozed.dts new file mode 100644 index 0000000..686b98f --- /dev/null +++ b/arch/arm/dts/zynq-picozed.dts @@ -0,0 +1,23 @@ +/* + * Avnet PicoZed board DTS + * + * Copyright (C) 2015 Xilinx, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/dts-v1/; +#include "zynq-7000.dtsi" + +/ { + model = "Zynq PicoZed Board"; + compatible = "xlnx,zynq-picozed", "xlnx,zynq-7000"; + + aliases { + serial0 = &uart1; + }; + + memory { + device_type = "memory"; + reg = <0 0x40000000>; + }; +}; diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile index 606482f..b9f1ca4 100644 --- a/arch/arm/imx-common/Makefile +++ b/arch/arm/imx-common/Makefile @@ -22,6 +22,9 @@ ifeq ($(SOC),$(filter $(SOC),mx6)) obj-$(CONFIG_CMD_SATA) += sata.o obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o endif +ifeq ($(SOC),$(filter $(SOC),vf610)) +obj-y += ddrmc-vf610.o +endif obj-$(CONFIG_CMD_BMODE) += cmd_bmode.o obj-$(CONFIG_CMD_HDMIDETECT) += cmd_hdmidet.o obj-$(CONFIG_CMD_DEKBLOB) += cmd_dek.o diff --git a/arch/arm/imx-common/ddrmc-vf610.c b/arch/arm/imx-common/ddrmc-vf610.c new file mode 100644 index 0000000..e462631 --- /dev/null +++ b/arch/arm/imx-common/ddrmc-vf610.c @@ -0,0 +1,278 @@ +/* + * Copyright 2015 Toradex, Inc. + * + * Based on vf610twr: + * Copyright 2013 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/iomux-vf610.h> +#include <asm/arch/ddrmc-vf610.h> + +void ddrmc_setup_iomux(void) +{ + static const iomux_v3_cfg_t ddr_pads[] = { + VF610_PAD_DDR_A15__DDR_A_15, + VF610_PAD_DDR_A14__DDR_A_14, + VF610_PAD_DDR_A13__DDR_A_13, + VF610_PAD_DDR_A12__DDR_A_12, + VF610_PAD_DDR_A11__DDR_A_11, + VF610_PAD_DDR_A10__DDR_A_10, + VF610_PAD_DDR_A9__DDR_A_9, + VF610_PAD_DDR_A8__DDR_A_8, + VF610_PAD_DDR_A7__DDR_A_7, + VF610_PAD_DDR_A6__DDR_A_6, + VF610_PAD_DDR_A5__DDR_A_5, + VF610_PAD_DDR_A4__DDR_A_4, + VF610_PAD_DDR_A3__DDR_A_3, + VF610_PAD_DDR_A2__DDR_A_2, + VF610_PAD_DDR_A1__DDR_A_1, + VF610_PAD_DDR_A0__DDR_A_0, + VF610_PAD_DDR_BA2__DDR_BA_2, + VF610_PAD_DDR_BA1__DDR_BA_1, + VF610_PAD_DDR_BA0__DDR_BA_0, + VF610_PAD_DDR_CAS__DDR_CAS_B, + VF610_PAD_DDR_CKE__DDR_CKE_0, + VF610_PAD_DDR_CLK__DDR_CLK_0, + VF610_PAD_DDR_CS__DDR_CS_B_0, + VF610_PAD_DDR_D15__DDR_D_15, + VF610_PAD_DDR_D14__DDR_D_14, + VF610_PAD_DDR_D13__DDR_D_13, + VF610_PAD_DDR_D12__DDR_D_12, + VF610_PAD_DDR_D11__DDR_D_11, + VF610_PAD_DDR_D10__DDR_D_10, + VF610_PAD_DDR_D9__DDR_D_9, + VF610_PAD_DDR_D8__DDR_D_8, + VF610_PAD_DDR_D7__DDR_D_7, + VF610_PAD_DDR_D6__DDR_D_6, + VF610_PAD_DDR_D5__DDR_D_5, + VF610_PAD_DDR_D4__DDR_D_4, + VF610_PAD_DDR_D3__DDR_D_3, + VF610_PAD_DDR_D2__DDR_D_2, + VF610_PAD_DDR_D1__DDR_D_1, + VF610_PAD_DDR_D0__DDR_D_0, + VF610_PAD_DDR_DQM1__DDR_DQM_1, + VF610_PAD_DDR_DQM0__DDR_DQM_0, + VF610_PAD_DDR_DQS1__DDR_DQS_1, + VF610_PAD_DDR_DQS0__DDR_DQS_0, + VF610_PAD_DDR_RAS__DDR_RAS_B, + VF610_PAD_DDR_WE__DDR_WE_B, + VF610_PAD_DDR_ODT1__DDR_ODT_0, + VF610_PAD_DDR_ODT0__DDR_ODT_1, + VF610_PAD_DDR_RESETB, + }; + + imx_iomux_v3_setup_multiple_pads(ddr_pads, ARRAY_SIZE(ddr_pads)); +} + +void ddrmc_phy_init(void) +{ + struct ddrmr_regs *ddrmr = (struct ddrmr_regs *)DDR_BASE_ADDR; + + writel(DDRMC_PHY_DQ_TIMING, &ddrmr->phy[0]); + writel(DDRMC_PHY_DQ_TIMING, &ddrmr->phy[16]); + writel(DDRMC_PHY_DQ_TIMING, &ddrmr->phy[32]); + + writel(DDRMC_PHY_DQS_TIMING, &ddrmr->phy[1]); + writel(DDRMC_PHY_DQS_TIMING, &ddrmr->phy[17]); + + writel(DDRMC_PHY_CTRL, &ddrmr->phy[2]); + writel(DDRMC_PHY_CTRL, &ddrmr->phy[18]); + writel(DDRMC_PHY_CTRL, &ddrmr->phy[34]); + + writel(DDRMC_PHY_MASTER_CTRL, &ddrmr->phy[3]); + writel(DDRMC_PHY_MASTER_CTRL, &ddrmr->phy[19]); + writel(DDRMC_PHY_MASTER_CTRL, &ddrmr->phy[35]); + + writel(DDRMC_PHY_SLAVE_CTRL, &ddrmr->phy[4]); + writel(DDRMC_PHY_SLAVE_CTRL, &ddrmr->phy[20]); + writel(DDRMC_PHY_SLAVE_CTRL, &ddrmr->phy[36]); + + /* LPDDR2 only parameter */ + writel(DDRMC_PHY_OFF, &ddrmr->phy[49]); + + writel(DDRMC_PHY50_DDR3_MODE | + DDRMC_PHY50_EN_SW_HALF_CYCLE, &ddrmr->phy[50]); + + /* Processor Pad ODT settings */ + writel(DDRMC_PHY_PROC_PAD_ODT, &ddrmr->phy[52]); +} + +static void ddrmc_ctrl_lvl_init(struct ddrmc_lvl_info *lvl) +{ + struct ddrmr_regs *ddrmr = (struct ddrmr_regs *)DDR_BASE_ADDR; + u32 cr102 = 0, cr105 = 0, cr106 = 0, cr110 = 0; + + if (lvl->wrlvl_reg_en) { + writel(DDRMC_CR97_WRLVL_EN, &ddrmr->cr[97]); + writel(DDRMC_CR98_WRLVL_DL_0(lvl->wrlvl_dl_0), &ddrmr->cr[98]); + writel(DDRMC_CR99_WRLVL_DL_1(lvl->wrlvl_dl_1), &ddrmr->cr[99]); + } + + if (lvl->rdlvl_reg_en) { + cr102 |= DDRMC_CR102_RDLVL_REG_EN; + cr105 |= DDRMC_CR105_RDLVL_DL_0(lvl->rdlvl_dl_0); + cr110 |= DDRMC_CR110_RDLVL_DL_1(lvl->rdlvl_dl_1); + } + + if (lvl->rdlvl_gt_reg_en) { + cr102 |= DDRMC_CR102_RDLVL_GT_REGEN; + cr106 |= DDRMC_CR106_RDLVL_GTDL_0(lvl->rdlvl_gt_dl_0); + cr110 |= DDRMC_CR110_RDLVL_GTDL_1(lvl->rdlvl_gt_dl_1); + } + + writel(cr102, &ddrmr->cr[102]); + writel(cr105, &ddrmr->cr[105]); + writel(cr106, &ddrmr->cr[106]); + writel(cr110, &ddrmr->cr[110]); +} + +void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings, + struct ddrmc_lvl_info *lvl, + int col_diff, int row_diff) +{ + struct ddrmr_regs *ddrmr = (struct ddrmr_regs *)DDR_BASE_ADDR; + + writel(DDRMC_CR00_DRAM_CLASS_DDR3, &ddrmr->cr[0]); + writel(DDRMC_CR02_DRAM_TINIT(timings->tinit), &ddrmr->cr[2]); + writel(DDRMC_CR10_TRST_PWRON(timings->trst_pwron), &ddrmr->cr[10]); + + writel(DDRMC_CR11_CKE_INACTIVE(timings->cke_inactive), &ddrmr->cr[11]); + writel(DDRMC_CR12_WRLAT(timings->wrlat) | + DDRMC_CR12_CASLAT_LIN(timings->caslat_lin), &ddrmr->cr[12]); + writel(DDRMC_CR13_TRC(timings->trc) | DDRMC_CR13_TRRD(timings->trrd) | + DDRMC_CR13_TCCD(timings->tccd), &ddrmr->cr[13]); + writel(DDRMC_CR14_TFAW(timings->tfaw) | DDRMC_CR14_TRP(timings->trp) | + DDRMC_CR14_TWTR(timings->twtr) | + DDRMC_CR14_TRAS_MIN(timings->tras_min), &ddrmr->cr[14]); + writel(DDRMC_CR16_TMRD(timings->tmrd) | + DDRMC_CR16_TRTP(timings->trtp), &ddrmr->cr[16]); + writel(DDRMC_CR17_TRAS_MAX(timings->tras_max) | + DDRMC_CR17_TMOD(timings->tmod), &ddrmr->cr[17]); + writel(DDRMC_CR18_TCKESR(timings->tckesr) | + DDRMC_CR18_TCKE(timings->tcke), &ddrmr->cr[18]); + + writel(DDRMC_CR20_AP_EN, &ddrmr->cr[20]); + writel(DDRMC_CR21_TRCD_INT(timings->trcd_int) | + DDRMC_CR21_CCMAP_EN, &ddrmr->cr[21]); + + writel(DDRMC_CR22_TDAL(timings->tdal), &ddrmr->cr[22]); + writel(DDRMC_CR23_BSTLEN(3) | + DDRMC_CR23_TDLL(timings->tdll), &ddrmr->cr[23]); + writel(DDRMC_CR24_TRP_AB(timings->trp_ab), &ddrmr->cr[24]); + + writel(DDRMC_CR25_TREF_EN, &ddrmr->cr[25]); + writel(DDRMC_CR26_TREF(timings->tref) | + DDRMC_CR26_TRFC(timings->trfc), &ddrmr->cr[26]); + writel(DDRMC_CR28_TREF_INT(0), &ddrmr->cr[28]); + writel(DDRMC_CR29_TPDEX(timings->tpdex), &ddrmr->cr[29]); + + writel(DDRMC_CR30_TXPDLL(timings->txpdll), &ddrmr->cr[30]); + writel(DDRMC_CR31_TXSNR(timings->txsnr) | + DDRMC_CR31_TXSR(timings->txsr), &ddrmr->cr[31]); + writel(DDRMC_CR33_EN_QK_SREF, &ddrmr->cr[33]); + writel(DDRMC_CR34_CKSRX(timings->cksrx) | + DDRMC_CR34_CKSRE(timings->cksre), &ddrmr->cr[34]); + + writel(DDRMC_CR38_FREQ_CHG_EN(0), &ddrmr->cr[38]); + writel(DDRMC_CR39_PHY_INI_COM(1024) | DDRMC_CR39_PHY_INI_STA(16) | + DDRMC_CR39_FRQ_CH_DLLOFF(2), &ddrmr->cr[39]); + + writel(DDRMC_CR41_PHY_INI_STRT_INI_DIS, &ddrmr->cr[41]); + writel(DDRMC_CR48_MR1_DA_0(70) | + DDRMC_CR48_MR0_DA_0(1056), &ddrmr->cr[48]); + + writel(DDRMC_CR66_ZQCL(timings->zqcl) | + DDRMC_CR66_ZQINIT(timings->zqinit), &ddrmr->cr[66]); + writel(DDRMC_CR67_ZQCS(timings->zqcs), &ddrmr->cr[67]); + writel(DDRMC_CR69_ZQ_ON_SREF_EX(2), &ddrmr->cr[69]); + + writel(DDRMC_CR70_REF_PER_ZQ(timings->ref_per_zq), &ddrmr->cr[70]); + writel(DDRMC_CR72_ZQCS_ROTATE(0), &ddrmr->cr[72]); + + writel(DDRMC_CR73_APREBIT(timings->aprebit) | + DDRMC_CR73_COL_DIFF(col_diff) | + DDRMC_CR73_ROW_DIFF(row_diff), &ddrmr->cr[73]); + writel(DDRMC_CR74_BANKSPLT_EN | DDRMC_CR74_ADDR_CMP_EN | + DDRMC_CR74_CMD_AGE_CNT(64) | DDRMC_CR74_AGE_CNT(64), + &ddrmr->cr[74]); + writel(DDRMC_CR75_RW_PG_EN | DDRMC_CR75_RW_EN | DDRMC_CR75_PRI_EN | + DDRMC_CR75_PLEN, &ddrmr->cr[75]); + writel(DDRMC_CR76_NQENT_ACTDIS(3) | DDRMC_CR76_D_RW_G_BKCN(3) | + DDRMC_CR76_W2R_SPLT_EN, &ddrmr->cr[76]); + writel(DDRMC_CR77_CS_MAP | DDRMC_CR77_DI_RD_INTLEAVE | + DDRMC_CR77_SWAP_EN, &ddrmr->cr[77]); + writel(DDRMC_CR78_Q_FULLNESS(7) | + DDRMC_CR78_BUR_ON_FLY_BIT(12), &ddrmr->cr[78]); + writel(DDRMC_CR79_CTLUPD_AREF(0), &ddrmr->cr[79]); + + writel(DDRMC_CR82_INT_MASK, &ddrmr->cr[82]); + + writel(DDRMC_CR87_ODT_WR_MAPCS0, &ddrmr->cr[87]); + writel(DDRMC_CR88_TODTL_CMD(4), &ddrmr->cr[88]); + writel(DDRMC_CR89_AODT_RWSMCS(2), &ddrmr->cr[89]); + + writel(DDRMC_CR91_R2W_SMCSDL(2), &ddrmr->cr[91]); + writel(DDRMC_CR96_WLMRD(timings->wlmrd) | + DDRMC_CR96_WLDQSEN(timings->wldqsen), &ddrmr->cr[96]); + + if (lvl != NULL) + ddrmc_ctrl_lvl_init(lvl); + + writel(DDRMC_CR117_AXI0_W_PRI(0) | + DDRMC_CR117_AXI0_R_PRI(0), &ddrmr->cr[117]); + writel(DDRMC_CR118_AXI1_W_PRI(1) | + DDRMC_CR118_AXI1_R_PRI(1), &ddrmr->cr[118]); + + writel(DDRMC_CR120_AXI0_PRI1_RPRI(2) | + DDRMC_CR120_AXI0_PRI0_RPRI(2), &ddrmr->cr[120]); + writel(DDRMC_CR121_AXI0_PRI3_RPRI(2) | + DDRMC_CR121_AXI0_PRI2_RPRI(2), &ddrmr->cr[121]); + writel(DDRMC_CR122_AXI1_PRI1_RPRI(1) | DDRMC_CR122_AXI1_PRI0_RPRI(1) | + DDRMC_CR122_AXI0_PRIRLX(100), &ddrmr->cr[122]); + writel(DDRMC_CR123_AXI1_P_ODR_EN | DDRMC_CR123_AXI1_PRI3_RPRI(1) | + DDRMC_CR123_AXI1_PRI2_RPRI(1), &ddrmr->cr[123]); + writel(DDRMC_CR124_AXI1_PRIRLX(100), &ddrmr->cr[124]); + + writel(DDRMC_CR126_PHY_RDLAT(8), &ddrmr->cr[126]); + writel(DDRMC_CR132_WRLAT_ADJ(5) | + DDRMC_CR132_RDLAT_ADJ(6), &ddrmr->cr[132]); + writel(DDRMC_CR137_PHYCTL_DL(2), &ddrmr->cr[137]); + writel(DDRMC_CR138_PHY_WRLV_MXDL(256) | + DDRMC_CR138_PHYDRAM_CK_EN(1), &ddrmr->cr[138]); + writel(DDRMC_CR139_PHY_WRLV_RESPLAT(4) | DDRMC_CR139_PHY_WRLV_LOAD(7) | + DDRMC_CR139_PHY_WRLV_DLL(3) | + DDRMC_CR139_PHY_WRLV_EN(3), &ddrmr->cr[139]); + writel(DDRMC_CR140_PHY_WRLV_WW(64), &ddrmr->cr[140]); + writel(DDRMC_CR143_RDLV_GAT_MXDL(1536) | + DDRMC_CR143_RDLV_MXDL(128), &ddrmr->cr[143]); + writel(DDRMC_CR144_PHY_RDLVL_RES(4) | DDRMC_CR144_PHY_RDLV_LOAD(7) | + DDRMC_CR144_PHY_RDLV_DLL(3) | + DDRMC_CR144_PHY_RDLV_EN(3), &ddrmr->cr[144]); + writel(DDRMC_CR145_PHY_RDLV_RR(64), &ddrmr->cr[145]); + writel(DDRMC_CR146_PHY_RDLVL_RESP(64), &ddrmr->cr[146]); + writel(DDRMC_CR147_RDLV_RESP_MASK(983040), &ddrmr->cr[147]); + writel(DDRMC_CR148_RDLV_GATE_RESP_MASK(983040), &ddrmr->cr[148]); + writel(DDRMC_CR151_RDLV_GAT_DQ_ZERO_CNT(1) | + DDRMC_CR151_RDLVL_DQ_ZERO_CNT(1), &ddrmr->cr[151]); + + writel(DDRMC_CR154_PAD_ZQ_EARLY_CMP_EN_TIMER(13) | + DDRMC_CR154_PAD_ZQ_MODE(1) | + DDRMC_CR154_DDR_SEL_PAD_CONTR(3) | + DDRMC_CR154_PAD_ZQ_HW_FOR(1), &ddrmr->cr[154]); + writel(DDRMC_CR155_PAD_ODT_BYTE1(2) | + DDRMC_CR155_PAD_ODT_BYTE0(2), &ddrmr->cr[155]); + writel(DDRMC_CR158_TWR(6), &ddrmr->cr[158]); + writel(DDRMC_CR161_ODT_EN(1) | DDRMC_CR161_TODTH_RD(2) | + DDRMC_CR161_TODTH_WR(2), &ddrmr->cr[161]); + + ddrmc_phy_init(); + + writel(DDRMC_CR00_DRAM_CLASS_DDR3 | DDRMC_CR00_START, &ddrmr->cr[0]); + + while (!(readl(&ddrmr->cr[80]) && 0x100)) + udelay(10); +} diff --git a/arch/arm/include/asm/arch-am33xx/mux_am43xx.h b/arch/arm/include/asm/arch-am33xx/mux_am43xx.h index 98fc2b5..2f4a3d1 100644 --- a/arch/arm/include/asm/arch-am33xx/mux_am43xx.h +++ b/arch/arm/include/asm/arch-am33xx/mux_am43xx.h @@ -137,14 +137,62 @@ struct pad_signals { int mcasp0_fsr; int mcasp0_axr1; int mcasp0_ahclkx; - int xdma_event_intr0; - int xdma_event_intr1; + int cam0_hd; + int cam0_vd; + int cam0_field; + int cam0_wen; + int cam0_pclk; + int cam0_data8; + int cam0_data9; + int cam1_data9; + int cam1_data8; + int cam1_hd; + int cam1_vd; + int cam1_pclk; + int cam1_field; + int cam1_wen; + int cam1_data0; + int cam1_data1; + int cam1_data2; + int cam1_data3; + int cam1_data4; + int cam1_data5; + int cam1_data6; + int cam1_data7; + int cam0_data0; + int cam0_data1; + int cam0_data2; + int cam0_data3; + int cam0_data4; + int cam0_data5; + int cam0_data6; + int cam0_data7; + int uart3_rxd; + int uart3_txd; + int uart3_ctsn; + int uart3_rtsn; + int gpio5_8; + int gpio5_9; + int gpio5_10; + int gpio5_11; + int gpio5_12; + int gpio5_13; + int spi4_sclk; + int spi4_d0; + int spi4_d1; + int spi4_cs0; + int spi2_sclk; + int spi2_d0; + int spi2_d1; + int spi2_cs0; + int xdma_evt_intr0; + int xdma_evt_intr1; + int clkreq; int nresetin_out; - int porz; - int nnmi; - int osc0_in; - int osc0_out; int rsvd1; + int nnmi; + int rsvd2; + int rsvd3; int tms; int tdi; int tdo; @@ -154,34 +202,11 @@ struct pad_signals { int emu1; int osc1_in; int osc1_out; - int pmic_power_en; int rtc_porz; - int rsvd2; - int ext_wakeup; - int enz_kaldo_1p8v; - int usb0_dm; - int usb0_dp; - int usb0_ce; - int usb0_id; - int usb0_vbus; + int ext_wakeup0; + int pmic_power_en0; int usb0_drvvbus; - int usb1_dm; - int usb1_dp; - int usb1_ce; - int usb1_id; - int usb1_vbus; int usb1_drvvbus; - int ddr_resetn; - int ddr_csn0; - int ddr_cke; - int ddr_ck; - int ddr_nck; - int ddr_casn; - int ddr_rasn; - int ddr_wen; - int ddr_ba0; - int ddr_ba1; - int ddr_ba2; }; #endif /* _MUX_AM43XX_H_ */ diff --git a/arch/arm/include/asm/arch-arm720t/hardware.h b/arch/arm/include/asm/arch-arm720t/hardware.h deleted file mode 100644 index 8ca42d9..0000000 --- a/arch/arm/include/asm/arch-arm720t/hardware.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __ARM7_HW_H -#define __ARM7_HW_H - -/* - * Copyright (c) 2004 Cucy Systems (http://www.cucy.com) - * Curt Brune <curt@cucy.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#if defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) -/* include IntegratorCP/CM720T specific hardware file if there was one */ -#else -#error No hardware file defined for this configuration -#endif - -#endif /* __ARM7_HW_H */ diff --git a/arch/arm/include/asm/arch-fsl-lsch3/config.h b/arch/arm/include/asm/arch-fsl-lsch3/config.h index b140c1f..ca8d38c 100644 --- a/arch/arm/include/asm/arch-fsl-lsch3/config.h +++ b/arch/arm/include/asm/arch-fsl-lsch3/config.h @@ -8,6 +8,14 @@ #define _ASM_ARMV8_FSL_LSCH3_CONFIG_ #include <fsl_ddrc_version.h> + +#define CONFIG_SYS_PAGE_SIZE 0x10000 + +#ifndef L1_CACHE_BYTES +#define L1_CACHE_SHIFT 6 +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) +#endif + #define CONFIG_MP #define CONFIG_SYS_FSL_OCRAM_BASE 0x18000000 /* initial RAM */ /* Link Definitions */ @@ -23,6 +31,7 @@ #define CONFIG_SYS_FSL_CH3_CLK_GRPA_ADDR (CONFIG_SYS_IMMR + 0x00300000) #define CONFIG_SYS_FSL_CH3_CLK_GRPB_ADDR (CONFIG_SYS_IMMR + 0x00310000) #define CONFIG_SYS_FSL_CH3_CLK_CTRL_ADDR (CONFIG_SYS_IMMR + 0x00370000) +#define CONFIG_SYS_FSL_ESDHC_ADDR (CONFIG_SYS_IMMR + 0x01140000) #define CONFIG_SYS_IFC_ADDR (CONFIG_SYS_IMMR + 0x01240000) #define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_IMMR + 0x011C0500) #define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_IMMR + 0x011C0600) @@ -30,6 +39,20 @@ #define CONFIG_SYS_FSL_PMU_CLTBENR (CONFIG_SYS_FSL_PMU_ADDR + \ 0x18A0) +#define CONFIG_SYS_FSL_WRIOP1_ADDR (CONFIG_SYS_IMMR + 0x7B80000) +#define CONFIG_SYS_FSL_WRIOP1_MDIO1 (CONFIG_SYS_FSL_WRIOP1_ADDR + 0x16000) +#define CONFIG_SYS_FSL_WRIOP1_MDIO2 (CONFIG_SYS_FSL_WRIOP1_ADDR + 0x17000) +#define CONFIG_SYS_FSL_LSCH3_SERDES_ADDR (CONFIG_SYS_IMMR + 0xEA0000) + +/* SP (Cortex-A5) related */ +#define CONFIG_SYS_FSL_SP_ADDR (CONFIG_SYS_IMMR + 0x00F00000) +#define CONFIG_SYS_FSL_SP_VSG_GIC_ADDR (CONFIG_SYS_FSL_SP_ADDR) +#define CONFIG_SYS_FSL_SP_VSG_GIC_VIGR1 (CONFIG_SYS_FSL_SP_ADDR) +#define CONFIG_SYS_FSL_SP_VSG_GIC_VIGR2 \ + (CONFIG_SYS_FSL_SP_ADDR + 0x0008) +#define CONFIG_SYS_FSL_SP_LOOPBACK_DUART \ + (CONFIG_SYS_FSL_SP_ADDR + 0x1000) + #define CONFIG_SYS_FSL_DCSR_DDR_ADDR 0x70012c000ULL #define CONFIG_SYS_FSL_DCSR_DDR2_ADDR 0x70012d000ULL #define CONFIG_SYS_FSL_DCSR_DDR3_ADDR 0x700132000ULL @@ -88,22 +111,57 @@ #define CONFIG_MAX_MEM_MAPPED CONFIG_SYS_LS2_DDR_BLOCK1_SIZE #define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_5_0 - +#define CONFIG_SYS_FSL_ESDHC_LE /* IFC */ #define CONFIG_SYS_FSL_IFC_LE +#define CONFIG_SYS_MEMAC_LITTLE_ENDIAN + +/* PCIe */ +#define CONFIG_SYS_PCIE1_ADDR (CONFIG_SYS_IMMR + 0x2400000) +#define CONFIG_SYS_PCIE2_ADDR (CONFIG_SYS_IMMR + 0x2500000) +#define CONFIG_SYS_PCIE3_ADDR (CONFIG_SYS_IMMR + 0x2600000) +#define CONFIG_SYS_PCIE4_ADDR (CONFIG_SYS_IMMR + 0x2700000) +#define CONFIG_SYS_PCIE1_PHYS_ADDR 0x1000000000ULL +#define CONFIG_SYS_PCIE2_PHYS_ADDR 0x1200000000ULL +#define CONFIG_SYS_PCIE3_PHYS_ADDR 0x1400000000ULL +#define CONFIG_SYS_PCIE4_PHYS_ADDR 0x1600000000ULL + +/* Cache Coherent Interconnect */ +#define CCI_MN_BASE 0x04000000 +#define CCI_MN_RNF_NODEID_LIST 0x180 +#define CCI_MN_DVM_DOMAIN_CTL 0x200 +#define CCI_MN_DVM_DOMAIN_CTL_SET 0x210 + +/* Device Configuration */ +#define DCFG_BASE 0x01e00000 +#define DCFG_PORSR1 0x000 +#define DCFG_PORSR1_RCW_SRC 0xff800000 +#define DCFG_PORSR1_RCW_SRC_NOR 0x12f00000 + +#define DCFG_DCSR_BASE 0X700100000ULL +#define DCFG_DCSR_PORCR1 0x000 + +/* Supplemental Configuration */ +#define SCFG_BASE 0x01fc0000 +#define SCFG_USB3PRM1CR 0x000 #ifdef CONFIG_LS2085A #define CONFIG_MAX_CPUS 16 #define CONFIG_SYS_FSL_IFC_BANK_COUNT 8 #define CONFIG_NUM_DDR_CONTROLLERS 3 #define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 1, 4, 4 } +#define CONFIG_SYS_FSL_SRDS_1 +#define CONFIG_SYS_FSL_SRDS_2 #else #error SoC not defined #endif #ifdef CONFIG_LS2085A #define CONFIG_SYS_FSL_ERRATUM_A008336 +#define CONFIG_SYS_FSL_ERRATUM_A008511 #define CONFIG_SYS_FSL_ERRATUM_A008514 +#define CONFIG_SYS_FSL_ERRATUM_A008585 +#define CONFIG_SYS_FSL_ERRATUM_A008751 #endif #endif /* _ASM_ARMV8_FSL_LSCH3_CONFIG_ */ diff --git a/arch/arm/include/asm/arch-fsl-lsch3/fsl_serdes.h b/arch/arm/include/asm/arch-fsl-lsch3/fsl_serdes.h new file mode 100644 index 0000000..2810f3f --- /dev/null +++ b/arch/arm/include/asm/arch-fsl-lsch3/fsl_serdes.h @@ -0,0 +1,67 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_SERDES_H +#define __FSL_SERDES_H + +#include <config.h> + +#define SRDS_MAX_LANES 8 + +enum srds_prtcl { + NONE = 0, + PCIE1, + PCIE2, + PCIE3, + PCIE4, + SATA1, + SATA2, + XAUI1, + XAUI2, + XFI1, + XFI2, + XFI3, + XFI4, + XFI5, + XFI6, + XFI7, + XFI8, + SGMII1, + SGMII2, + SGMII3, + SGMII4, + SGMII5, + SGMII6, + SGMII7, + SGMII8, + SGMII9, + SGMII10, + SGMII11, + SGMII12, + SGMII13, + SGMII14, + SGMII15, + SGMII16, + QSGMII_A, /* A indicates MACs 1-4 */ + QSGMII_B, /* B indicates MACs 5-8 */ + QSGMII_C, /* C indicates MACs 9-12 */ + QSGMII_D, /* D indicates MACs 12-16 */ + SERDES_PRCTL_COUNT +}; + +enum srds { + FSL_SRDS_1 = 0, + FSL_SRDS_2 = 1, +}; + +int is_serdes_configured(enum srds_prtcl device); +void fsl_serdes_init(void); + +int serdes_get_first_lane(u32 sd, enum srds_prtcl device); +enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane); +int is_serdes_prtcl_valid(int serdes, u32 prtcl); + +#endif /* __FSL_SERDES_H */ diff --git a/arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h index dd11ef7..d6bee60 100644 --- a/arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h +++ b/arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h @@ -47,6 +47,30 @@ struct ccsr_gur { u32 devdisr5; /* Device disable control 5 */ u32 devdisr6; /* Device disable control 6 */ u32 devdisr7; /* Device disable control 7 */ +#define FSL_CHASSIS3_DEVDISR2_DPMAC1 0x00000001 +#define FSL_CHASSIS3_DEVDISR2_DPMAC2 0x00000002 +#define FSL_CHASSIS3_DEVDISR2_DPMAC3 0x00000004 +#define FSL_CHASSIS3_DEVDISR2_DPMAC4 0x00000008 +#define FSL_CHASSIS3_DEVDISR2_DPMAC5 0x00000010 +#define FSL_CHASSIS3_DEVDISR2_DPMAC6 0x00000020 +#define FSL_CHASSIS3_DEVDISR2_DPMAC7 0x00000040 +#define FSL_CHASSIS3_DEVDISR2_DPMAC8 0x00000080 +#define FSL_CHASSIS3_DEVDISR2_DPMAC9 0x00000100 +#define FSL_CHASSIS3_DEVDISR2_DPMAC10 0x00000200 +#define FSL_CHASSIS3_DEVDISR2_DPMAC11 0x00000400 +#define FSL_CHASSIS3_DEVDISR2_DPMAC12 0x00000800 +#define FSL_CHASSIS3_DEVDISR2_DPMAC13 0x00001000 +#define FSL_CHASSIS3_DEVDISR2_DPMAC14 0x00002000 +#define FSL_CHASSIS3_DEVDISR2_DPMAC15 0x00004000 +#define FSL_CHASSIS3_DEVDISR2_DPMAC16 0x00008000 +#define FSL_CHASSIS3_DEVDISR2_DPMAC17 0x00010000 +#define FSL_CHASSIS3_DEVDISR2_DPMAC18 0x00020000 +#define FSL_CHASSIS3_DEVDISR2_DPMAC19 0x00040000 +#define FSL_CHASSIS3_DEVDISR2_DPMAC20 0x00080000 +#define FSL_CHASSIS3_DEVDISR2_DPMAC21 0x00100000 +#define FSL_CHASSIS3_DEVDISR2_DPMAC22 0x00200000 +#define FSL_CHASSIS3_DEVDISR2_DPMAC23 0x00400000 +#define FSL_CHASSIS3_DEVDISR2_DPMAC24 0x00800000 u8 res_08c[0x90-0x8c]; u32 coredisru; /* uppper portion for support of 64 cores */ u32 coredisrl; /* lower portion for support of 64 cores */ @@ -63,6 +87,11 @@ struct ccsr_gur { #define FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK 0x3f #define FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_SHIFT 18 #define FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_MASK 0x3f +#define FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK 0x00FF0000 +#define FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT 16 +#define FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK 0xFF000000 +#define FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT 24 + u8 res_180[0x200-0x180]; u32 scratchrw[32]; /* Scratch Read/Write */ u8 res_280[0x300-0x280]; diff --git a/arch/arm/include/asm/arch-fsl-lsch3/soc.h b/arch/arm/include/asm/arch-fsl-lsch3/soc.h new file mode 100644 index 0000000..16b723d --- /dev/null +++ b/arch/arm/include/asm/arch-fsl-lsch3/soc.h @@ -0,0 +1,8 @@ +/* + * Copyright 2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +void fsl_lsch3_early_init_f(void); + diff --git a/arch/arm/include/asm/arch-ls102xa/config.h b/arch/arm/include/asm/arch-ls102xa/config.h index 6561ce6..4dc528b 100644 --- a/arch/arm/include/asm/arch-ls102xa/config.h +++ b/arch/arm/include/asm/arch-ls102xa/config.h @@ -119,10 +119,6 @@ #define DCU_LAYER_MAX_NUM 16 -#define QE_MURAM_SIZE 0x6000UL -#define MAX_QE_RISC 1 -#define QE_NUM_OF_SNUM 28 - #define CONFIG_SYS_FSL_SRDS_1 #ifdef CONFIG_LS102XA diff --git a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h index 3a64afc..a8122c1 100644 --- a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h +++ b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h @@ -17,6 +17,9 @@ #define SOC_VER_LS1021 0x11 #define SOC_VER_LS1022 0x12 +#define SOC_MAJOR_VER_1_0 0x1 +#define SOC_MAJOR_VER_2_0 0x2 + #define CCSR_BRR_OFFSET 0xe4 #define CCSR_SCRATCHRW1_OFFSET 0x200 diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h index 8e0d7d1..c49aa62 100644 --- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h +++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h @@ -250,6 +250,7 @@ struct mx6_ddr_sysinfo { u8 mif3_mode; /* Command prediction working mode */ u8 rst_to_cke; /* Time from SDE enable to CKE rise */ u8 sde_to_rst; /* Time from SDE enable until DDR reset# is high */ + u8 pd_fast_exit;/* enable precharge powerdown fast-exit */ }; /* diff --git a/arch/arm/include/asm/arch-socfpga/reset_manager.h b/arch/arm/include/asm/arch-socfpga/reset_manager.h index 034135b..d63a285 100644 --- a/arch/arm/include/asm/arch-socfpga/reset_manager.h +++ b/arch/arm/include/asm/arch-socfpga/reset_manager.h @@ -15,6 +15,9 @@ void socfpga_bridges_reset(int enable); void socfpga_emac_reset(int enable); void socfpga_watchdog_reset(void); void socfpga_spim_enable(void); +void socfpga_uart0_enable(void); +void socfpga_sdram_enable(void); +void socfpga_osc1timer_enable(void); struct socfpga_reset_manager { u32 status; @@ -36,7 +39,10 @@ struct socfpga_reset_manager { #define RSTMGR_PERMODRST_EMAC0_LSB 0 #define RSTMGR_PERMODRST_EMAC1_LSB 1 #define RSTMGR_PERMODRST_L4WD0_LSB 6 +#define RSTMGR_PERMODRST_OSC1TIMER0_LSB 8 +#define RSTMGR_PERMODRST_UART0_LSB 16 #define RSTMGR_PERMODRST_SPIM0_LSB 18 #define RSTMGR_PERMODRST_SPIM1_LSB 19 +#define RSTMGR_PERMODRST_SDR_LSB 29 #endif /* _RESET_MANAGER_H_ */ diff --git a/arch/arm/include/asm/arch-socfpga/sdram.h b/arch/arm/include/asm/arch-socfpga/sdram.h new file mode 100644 index 0000000..4f6489d --- /dev/null +++ b/arch/arm/include/asm/arch-socfpga/sdram.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2015 Marek Vasut <marex@denx.de> + * + * FIXME: This file contains temporary stub functions and is here + * only until these functions are properly merged into + * mainline. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ARCH_SDRAM_H__ +#define __ARCH_SDRAM_H__ + +/* function declaration */ +inline unsigned long sdram_calculate_size(void) { return 0; } +inline unsigned sdram_mmr_init_full(unsigned int sdr_phy_reg) { return 0; } +inline int sdram_calibration_full(void) { return 0; } + +#endif /* __ARCH_SDRAM_H__ */ diff --git a/arch/arm/include/asm/arch-socfpga/system_manager.h b/arch/arm/include/asm/arch-socfpga/system_manager.h index 071ec4f..51d9815 100644 --- a/arch/arm/include/asm/arch-socfpga/system_manager.h +++ b/arch/arm/include/asm/arch-socfpga/system_manager.h @@ -10,6 +10,7 @@ #ifndef __ASSEMBLY__ void sysmgr_pinmux_init(void); +void sysmgr_enable_warmrstcfgio(void); /* declaration for handoff table type */ extern unsigned long sys_mgr_init_table[CONFIG_HPS_PINMUX_NUM]; diff --git a/arch/arm/include/asm/arch-stm32f4/fmc.h b/arch/arm/include/asm/arch-stm32f4/fmc.h new file mode 100644 index 0000000..4ab3031 --- /dev/null +++ b/arch/arm/include/asm/arch-stm32f4/fmc.h @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2013 + * Pavel Boldin, Emcraft Systems, paboldin@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _MACH_FMC_H_ +#define _MACH_FMC_H_ + +struct stm32_fmc_regs { + u32 sdcr1; /* Control register 1 */ + u32 sdcr2; /* Control register 2 */ + u32 sdtr1; /* Timing register 1 */ + u32 sdtr2; /* Timing register 2 */ + u32 sdcmr; /* Mode register */ + u32 sdrtr; /* Refresh timing register */ + u32 sdsr; /* Status register */ +}; + +/* + * FMC registers base + */ +#define STM32_SDRAM_FMC_BASE 0xA0000140 +#define STM32_SDRAM_FMC ((struct stm32_fmc_regs *)STM32_SDRAM_FMC_BASE) + +/* Control register SDCR */ +#define FMC_SDCR_RPIPE_SHIFT 13 /* RPIPE bit shift */ +#define FMC_SDCR_RBURST_SHIFT 12 /* RBURST bit shift */ +#define FMC_SDCR_SDCLK_SHIFT 10 /* SDRAM clock divisor shift */ +#define FMC_SDCR_WP_SHIFT 9 /* Write protection shift */ +#define FMC_SDCR_CAS_SHIFT 7 /* CAS latency shift */ +#define FMC_SDCR_NB_SHIFT 6 /* Number of banks shift */ +#define FMC_SDCR_MWID_SHIFT 4 /* Memory width shift */ +#define FMC_SDCR_NR_SHIFT 2 /* Number of row address bits shift */ +#define FMC_SDCR_NC_SHIFT 0 /* Number of col address bits shift */ + +/* Timings register SDTR */ +#define FMC_SDTR_TMRD_SHIFT 0 /* Load mode register to active */ +#define FMC_SDTR_TXSR_SHIFT 4 /* Exit self-refresh time */ +#define FMC_SDTR_TRAS_SHIFT 8 /* Self-refresh time */ +#define FMC_SDTR_TRC_SHIFT 12 /* Row cycle delay */ +#define FMC_SDTR_TWR_SHIFT 16 /* Recovery delay */ +#define FMC_SDTR_TRP_SHIFT 20 /* Row precharge delay */ +#define FMC_SDTR_TRCD_SHIFT 24 /* Row-to-column delay */ + + +#define FMC_SDCMR_NRFS_SHIFT 5 + +#define FMC_SDCMR_MODE_NORMAL 0 +#define FMC_SDCMR_MODE_START_CLOCK 1 +#define FMC_SDCMR_MODE_PRECHARGE 2 +#define FMC_SDCMR_MODE_AUTOREFRESH 3 +#define FMC_SDCMR_MODE_WRITE_MODE 4 +#define FMC_SDCMR_MODE_SELFREFRESH 5 +#define FMC_SDCMR_MODE_POWERDOWN 6 + +#define FMC_SDCMR_BANK_1 (1 << 4) +#define FMC_SDCMR_BANK_2 (1 << 3) + +#define FMC_SDCMR_MODE_REGISTER_SHIFT 9 + +#define FMC_SDSR_BUSY (1 << 5) + +#define FMC_BUSY_WAIT() do { \ + __asm__ __volatile__ ("dsb" : : : "memory"); \ + while (STM32_SDRAM_FMC->sdsr & FMC_SDSR_BUSY) \ + ; \ + } while (0) + + +#endif /* _MACH_FMC_H_ */ diff --git a/arch/arm/include/asm/arch-stm32f4/gpio.h b/arch/arm/include/asm/arch-stm32f4/gpio.h new file mode 100644 index 0000000..7cd866e --- /dev/null +++ b/arch/arm/include/asm/arch-stm32f4/gpio.h @@ -0,0 +1,116 @@ +/* + * (C) Copyright 2011 + * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _STM32_GPIO_H_ +#define _STM32_GPIO_H_ + +enum stm32_gpio_port { + STM32_GPIO_PORT_A = 0, + STM32_GPIO_PORT_B, + STM32_GPIO_PORT_C, + STM32_GPIO_PORT_D, + STM32_GPIO_PORT_E, + STM32_GPIO_PORT_F, + STM32_GPIO_PORT_G, + STM32_GPIO_PORT_H, + STM32_GPIO_PORT_I +}; + +enum stm32_gpio_pin { + STM32_GPIO_PIN_0 = 0, + STM32_GPIO_PIN_1, + STM32_GPIO_PIN_2, + STM32_GPIO_PIN_3, + STM32_GPIO_PIN_4, + STM32_GPIO_PIN_5, + STM32_GPIO_PIN_6, + STM32_GPIO_PIN_7, + STM32_GPIO_PIN_8, + STM32_GPIO_PIN_9, + STM32_GPIO_PIN_10, + STM32_GPIO_PIN_11, + STM32_GPIO_PIN_12, + STM32_GPIO_PIN_13, + STM32_GPIO_PIN_14, + STM32_GPIO_PIN_15 +}; + +enum stm32_gpio_mode { + STM32_GPIO_MODE_IN = 0, + STM32_GPIO_MODE_OUT, + STM32_GPIO_MODE_AF, + STM32_GPIO_MODE_AN +}; + +enum stm32_gpio_otype { + STM32_GPIO_OTYPE_PP = 0, + STM32_GPIO_OTYPE_OD +}; + +enum stm32_gpio_speed { + STM32_GPIO_SPEED_2M = 0, + STM32_GPIO_SPEED_25M, + STM32_GPIO_SPEED_50M, + STM32_GPIO_SPEED_100M +}; + +enum stm32_gpio_pupd { + STM32_GPIO_PUPD_NO = 0, + STM32_GPIO_PUPD_UP, + STM32_GPIO_PUPD_DOWN +}; + +enum stm32_gpio_af { + STM32_GPIO_AF0 = 0, + STM32_GPIO_AF1, + STM32_GPIO_AF2, + STM32_GPIO_AF3, + STM32_GPIO_AF4, + STM32_GPIO_AF5, + STM32_GPIO_AF6, + STM32_GPIO_AF7, + STM32_GPIO_AF8, + STM32_GPIO_AF9, + STM32_GPIO_AF10, + STM32_GPIO_AF11, + STM32_GPIO_AF12, + STM32_GPIO_AF13, + STM32_GPIO_AF14, + STM32_GPIO_AF15 +}; + +struct stm32_gpio_dsc { + enum stm32_gpio_port port; + enum stm32_gpio_pin pin; +}; + +struct stm32_gpio_ctl { + enum stm32_gpio_mode mode; + enum stm32_gpio_otype otype; + enum stm32_gpio_speed speed; + enum stm32_gpio_pupd pupd; + enum stm32_gpio_af af; +}; + +static inline unsigned stm32_gpio_to_port(unsigned gpio) +{ + return gpio / 16; +} + +static inline unsigned stm32_gpio_to_pin(unsigned gpio) +{ + return gpio % 16; +} + +int stm32_gpio_config(const struct stm32_gpio_dsc *gpio_dsc, + const struct stm32_gpio_ctl *gpio_ctl); +int stm32_gpout_set(const struct stm32_gpio_dsc *gpio_dsc, int state); + +#endif /* _STM32_GPIO_H_ */ diff --git a/arch/arm/include/asm/arch-stm32f4/stm32.h b/arch/arm/include/asm/arch-stm32f4/stm32.h new file mode 100644 index 0000000..a9f88db --- /dev/null +++ b/arch/arm/include/asm/arch-stm32f4/stm32.h @@ -0,0 +1,108 @@ +/* + * (C) Copyright 2011 + * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _MACH_STM32_H_ +#define _MACH_STM32_H_ + +/* + * Peripheral memory map + */ +#define STM32_PERIPH_BASE 0x40000000 +#define STM32_APB1PERIPH_BASE (STM32_PERIPH_BASE + 0x00000000) +#define STM32_APB2PERIPH_BASE (STM32_PERIPH_BASE + 0x00010000) +#define STM32_AHB1PERIPH_BASE (STM32_PERIPH_BASE + 0x00020000) +#define STM32_AHB2PERIPH_BASE (STM32_PERIPH_BASE + 0x10000000) + +#define STM32_BUS_MASK 0xFFFF0000 + +/* + * Register maps + */ +struct stm32_rcc_regs { + u32 cr; /* RCC clock control */ + u32 pllcfgr; /* RCC PLL configuration */ + u32 cfgr; /* RCC clock configuration */ + u32 cir; /* RCC clock interrupt */ + u32 ahb1rstr; /* RCC AHB1 peripheral reset */ + u32 ahb2rstr; /* RCC AHB2 peripheral reset */ + u32 ahb3rstr; /* RCC AHB3 peripheral reset */ + u32 rsv0; + u32 apb1rstr; /* RCC APB1 peripheral reset */ + u32 apb2rstr; /* RCC APB2 peripheral reset */ + u32 rsv1[2]; + u32 ahb1enr; /* RCC AHB1 peripheral clock enable */ + u32 ahb2enr; /* RCC AHB2 peripheral clock enable */ + u32 ahb3enr; /* RCC AHB3 peripheral clock enable */ + u32 rsv2; + u32 apb1enr; /* RCC APB1 peripheral clock enable */ + u32 apb2enr; /* RCC APB2 peripheral clock enable */ + u32 rsv3[2]; + u32 ahb1lpenr; /* RCC AHB1 periph clk enable in low pwr mode */ + u32 ahb2lpenr; /* RCC AHB2 periph clk enable in low pwr mode */ + u32 ahb3lpenr; /* RCC AHB3 periph clk enable in low pwr mode */ + u32 rsv4; + u32 apb1lpenr; /* RCC APB1 periph clk enable in low pwr mode */ + u32 apb2lpenr; /* RCC APB2 periph clk enable in low pwr mode */ + u32 rsv5[2]; + u32 bdcr; /* RCC Backup domain control */ + u32 csr; /* RCC clock control & status */ + u32 rsv6[2]; + u32 sscgr; /* RCC spread spectrum clock generation */ + u32 plli2scfgr; /* RCC PLLI2S configuration */ + u32 pllsaicfgr; + u32 dckcfgr; +}; + +struct stm32_pwr_regs { + u32 cr; + u32 csr; +}; + +struct stm32_flash_regs { + u32 acr; + u32 key; + u32 optkeyr; + u32 sr; + u32 cr; + u32 optcr; + u32 optcr1; +}; + +/* + * Registers access macros + */ +#define STM32_RCC_BASE (STM32_AHB1PERIPH_BASE + 0x3800) +#define STM32_RCC ((struct stm32_rcc_regs *)STM32_RCC_BASE) + +#define STM32_PWR_BASE (STM32_APB1PERIPH_BASE + 0x7000) +#define STM32_PWR ((struct stm32_pwr_regs *)STM32_PWR_BASE) + +#define STM32_FLASH_BASE (STM32_AHB1PERIPH_BASE + 0x3C00) +#define STM32_FLASH ((struct stm32_flash_regs *)STM32_FLASH_BASE) + +#define STM32_FLASH_SR_BSY (1 << 16) + +#define STM32_FLASH_CR_PG (1 << 0) +#define STM32_FLASH_CR_SER (1 << 1) +#define STM32_FLASH_CR_STRT (1 << 16) +#define STM32_FLASH_CR_LOCK (1 << 31) +#define STM32_FLASH_CR_SNB_OFFSET 3 + +enum clock { + CLOCK_CORE, + CLOCK_AHB, + CLOCK_APB1, + CLOCK_APB2 +}; + +int configure_clocks(void); +unsigned long clock_get(enum clock clck); + +#endif /* _MACH_STM32_H_ */ diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index dae6069..f403742 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -94,6 +94,13 @@ #define SUNXI_TWI0_BASE 0x01c2ac00 #define SUNXI_TWI1_BASE 0x01c2b000 #define SUNXI_TWI2_BASE 0x01c2b400 +#ifdef CONFIG_MACH_SUN6I +#define SUNXI_TWI3_BASE 0x01c0b800 +#endif +#ifdef CONFIG_MACH_SUN7I +#define SUNXI_TWI3_BASE 0x01c2b800 +#define SUNXI_TWI4_BASE 0x01c2c000 +#endif #define SUNXI_CAN_BASE 0x01c2bc00 diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index f2c247d..ae7cbb7 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -84,7 +84,7 @@ struct sunxi_gpio_reg { #define GPIO_CFG_INDEX(pin) (((pin) & 0x1f) >> 3) #define GPIO_CFG_OFFSET(pin) ((((pin) & 0x1f) & 0x7) << 2) -#define GPIO_DRV_INDEX(pin) (((pin) & 0x1f) >> 4) +#define GPIO_DRV_INDEX(pin) (((pin) & 0x1f) >> 4) #define GPIO_DRV_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1) #define GPIO_PULL_INDEX(pin) (((pin) & 0x1f) >> 4) @@ -142,71 +142,77 @@ enum sunxi_gpio_number { #define SUNXI_GPIO_INPUT 0 #define SUNXI_GPIO_OUTPUT 1 -#define SUNXI_GPA0_EMAC 2 -#define SUN6I_GPA0_GMAC 2 -#define SUN7I_GPA0_GMAC 5 - -#define SUNXI_GPB0_TWI0 2 - -#define SUN4I_GPB22_UART0_TX 2 -#define SUN4I_GPB23_UART0_RX 2 - -#define SUN5I_GPB19_UART0_TX 2 -#define SUN5I_GPB20_UART0_RX 2 - -#define SUNXI_GPC6_SDC2 3 - -#define SUNXI_GPD0_LCD0 2 -#define SUNXI_GPD0_LVDS0 3 - -#define SUNXI_GPF0_SDC0 2 - -#define SUNXI_GPF2_SDC0 2 - -#ifdef CONFIG_MACH_SUN8I -#define SUNXI_GPF2_UART0_TX 3 -#define SUNXI_GPF4_UART0_RX 3 -#else -#define SUNXI_GPF2_UART0_TX 4 -#define SUNXI_GPF4_UART0_RX 4 -#endif - -#define SUN4I_GPG0_SDC1 4 - -#define SUN5I_GPG3_SDC1 2 - -#define SUN5I_GPG3_UART1_TX 4 -#define SUN5I_GPG4_UART1_RX 4 - -#define SUN4I_GPH22_SDC1 5 - -#define SUN6I_GPH20_UART0_TX 2 -#define SUN6I_GPH21_UART0_RX 2 - -#define SUN4I_GPI4_SDC3 2 +#define SUNXI_GPA_EMAC 2 +#define SUN6I_GPA_GMAC 2 +#define SUN7I_GPA_GMAC 5 +#define SUN6I_GPA_SDC2 5 +#define SUN6I_GPA_SDC3 4 + +#define SUN4I_GPB_TWI0 2 +#define SUN4I_GPB_TWI1 2 +#define SUN5I_GPB_TWI1 2 +#define SUN4I_GPB_TWI2 2 +#define SUN5I_GPB_TWI2 2 +#define SUN4I_GPB_UART0 2 +#define SUN5I_GPB_UART0 2 + +#define SUNXI_GPC_SDC2 3 +#define SUN6I_GPC_SDC3 4 + +#define SUN8I_GPD_SDC1 3 +#define SUNXI_GPD_LCD0 2 +#define SUNXI_GPD_LVDS0 3 + +#define SUN5I_GPE_SDC2 3 +#define SUN8I_GPE_TWI2 3 + +#define SUNXI_GPF_SDC0 2 +#define SUNXI_GPF_UART0 4 +#define SUN8I_GPF_UART0 3 + +#define SUN4I_GPG_SDC1 4 +#define SUN5I_GPG_SDC1 2 +#define SUN6I_GPG_SDC1 2 +#define SUN8I_GPG_SDC1 2 +#define SUN6I_GPG_TWI3 2 +#define SUN5I_GPG_UART1 4 + +#define SUN4I_GPH_SDC1 5 +#define SUN6I_GPH_TWI0 2 +#define SUN8I_GPH_TWI0 2 +#define SUN6I_GPH_TWI1 2 +#define SUN8I_GPH_TWI1 2 +#define SUN6I_GPH_TWI2 2 +#define SUN6I_GPH_UART0 2 + +#define SUNXI_GPI_SDC3 2 +#define SUN7I_GPI_TWI3 3 +#define SUN7I_GPI_TWI4 3 #define SUN6I_GPL0_R_P2WI_SCK 3 #define SUN6I_GPL1_R_P2WI_SDA 3 -#define SUN8I_GPL0_R_RSB_SCK 2 -#define SUN8I_GPL1_R_RSB_SDA 2 -#define SUN8I_GPL2_R_UART_TX 2 -#define SUN8I_GPL3_R_UART_RX 2 +#define SUN8I_GPL_R_RSB 2 +#define SUN8I_GPL_R_UART 2 -#define SUN9I_GPN0_R_RSB_SCK 3 -#define SUN9I_GPN1_R_RSB_SDA 3 +#define SUN9I_GPN_R_RSB 3 /* GPIO pin pull-up/down config */ #define SUNXI_GPIO_PULL_DISABLE 0 #define SUNXI_GPIO_PULL_UP 1 #define SUNXI_GPIO_PULL_DOWN 2 +/* Virtual AXP0 GPIOs */ +#define SUNXI_GPIO_AXP0_VBUS_DETECT 8 +#define SUNXI_GPIO_AXP0_VBUS_ENABLE 9 + void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val); void sunxi_gpio_set_cfgpin(u32 pin, u32 val); int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset); int sunxi_gpio_get_cfgpin(u32 pin); int sunxi_gpio_set_drv(u32 pin, u32 val); int sunxi_gpio_set_pull(u32 pin, u32 val); +int sunxi_name_to_gpio_bank(const char *name); int sunxi_name_to_gpio(const char *name); #define name_to_gpio(name) sunxi_name_to_gpio(name) diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h index dc5406b..561cd2b 100644 --- a/arch/arm/include/asm/arch-sunxi/i2c.h +++ b/arch/arm/include/asm/arch-sunxi/i2c.h @@ -8,7 +8,22 @@ #include <asm/arch/cpu.h> -#define CONFIG_I2C_MVTWSI_BASE SUNXI_TWI0_BASE +#ifdef CONFIG_I2C0_ENABLE +#define CONFIG_I2C_MVTWSI_BASE0 SUNXI_TWI0_BASE +#endif +#ifdef CONFIG_I2C1_ENABLE +#define CONFIG_I2C_MVTWSI_BASE1 SUNXI_TWI1_BASE +#endif +#ifdef CONFIG_I2C2_ENABLE +#define CONFIG_I2C_MVTWSI_BASE2 SUNXI_TWI2_BASE +#endif +#ifdef CONFIG_I2C3_ENABLE +#define CONFIG_I2C_MVTWSI_BASE3 SUNXI_TWI3_BASE +#endif +#ifdef CONFIG_I2C4_ENABLE +#define CONFIG_I2C_MVTWSI_BASE4 SUNXI_TWI4_BASE +#endif + /* This is abp0-clk on sun4i/5i/7i / abp1-clk on sun6i/sun8i which is 24MHz */ #define CONFIG_SYS_TCLK 24000000 diff --git a/arch/arm/include/asm/arch-sunxi/usbc.h b/arch/arm/include/asm/arch-sunxi/usbc.h index 1330733..ab0f272 100644 --- a/arch/arm/include/asm/arch-sunxi/usbc.h +++ b/arch/arm/include/asm/arch-sunxi/usbc.h @@ -20,4 +20,5 @@ void sunxi_usbc_enable(int index); void sunxi_usbc_disable(int index); void sunxi_usbc_vbus_enable(int index); void sunxi_usbc_vbus_disable(int index); +int sunxi_usbc_vbus_detect(int index); void sunxi_usbc_enable_squelch_detect(int index, int enable); diff --git a/arch/arm/include/asm/arch-tegra114/hardware.h b/arch/arm/include/asm/arch-tegra114/hardware.h deleted file mode 100644 index c21fbb6..0000000 --- a/arch/arm/include/asm/arch-tegra114/hardware.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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/>. - */ - -#ifndef _TEGRA114_HARDWARE_H_ -#define _TEGRA114_HARDWARE_H_ - -/* include tegra specific hardware definitions */ - -#endif /* _TEGRA114_HARDWARE_H_ */ diff --git a/arch/arm/include/asm/arch-tegra124/hardware.h b/arch/arm/include/asm/arch-tegra124/hardware.h deleted file mode 100644 index 114fce8..0000000 --- a/arch/arm/include/asm/arch-tegra124/hardware.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * (C) Copyright 2013 - * NVIDIA Corporation <www.nvidia.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _TEGRA124_HARDWARE_H_ -#define _TEGRA124_HARDWARE_H_ - -/* - * Include Tegra-specific hardware definitions - * Nothing needed currently for Tegra124 - */ - -#endif /* _TEGRA124_HARDWARE_H_ */ diff --git a/arch/arm/include/asm/arch-tegra20/hardware.h b/arch/arm/include/asm/arch-tegra20/hardware.h deleted file mode 100644 index a295894..0000000 --- a/arch/arm/include/asm/arch-tegra20/hardware.h +++ /dev/null @@ -1,13 +0,0 @@ -/* -* (C) Copyright 2010-2011 -* NVIDIA Corporation <www.nvidia.com> -* - * SPDX-License-Identifier: GPL-2.0+ -*/ - -#ifndef __TEGRA2_HW_H -#define __TEGRA2_HW_H - -/* include tegra specific hardware definitions */ - -#endif /* __TEGRA2_HW_H */ diff --git a/arch/arm/include/asm/arch-tegra30/hardware.h b/arch/arm/include/asm/arch-tegra30/hardware.h deleted file mode 100644 index b1a5aa9..0000000 --- a/arch/arm/include/asm/arch-tegra30/hardware.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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/>. - */ - -#ifndef _TEGRA30_HARDWARE_H_ -#define _TEGRA30_HARDWARE_H_ - -/* include tegra specific hardware definitions */ - -#endif /* _TEGRA30-HARDWARE_H_ */ diff --git a/arch/arm/include/asm/arch-vf610/crm_regs.h b/arch/arm/include/asm/arch-vf610/crm_regs.h index 724682c..bc6db2a 100644 --- a/arch/arm/include/asm/arch-vf610/crm_regs.h +++ b/arch/arm/include/asm/arch-vf610/crm_regs.h @@ -189,6 +189,7 @@ struct anadig_reg { #define CCM_REG_CTRL_MASK 0xffffffff #define CCM_CCGR0_UART0_CTRL_MASK (0x3 << 14) #define CCM_CCGR0_UART1_CTRL_MASK (0x3 << 16) +#define CCM_CCGR1_USBC0_CTRL_MASK (0x3 << 8) #define CCM_CCGR1_PIT_CTRL_MASK (0x3 << 14) #define CCM_CCGR1_WDOGA5_CTRL_MASK (0x3 << 28) #define CCM_CCGR2_QSPI0_CTRL_MASK (0x3 << 8) @@ -199,6 +200,7 @@ struct anadig_reg { #define CCM_CCGR2_PORTD_CTRL_MASK (0x3 << 24) #define CCM_CCGR2_PORTE_CTRL_MASK (0x3 << 26) #define CCM_CCGR3_ANADIG_CTRL_MASK 0x3 +#define CCM_CCGR3_SCSC_CTRL_MASK (0x3 << 4) #define CCM_CCGR4_WKUP_CTRL_MASK (0x3 << 20) #define CCM_CCGR4_CCM_CTRL_MASK (0x3 << 22) #define CCM_CCGR4_GPC_CTRL_MASK (0x3 << 24) @@ -206,14 +208,23 @@ struct anadig_reg { #define CCM_CCGR6_OCOTP_CTRL_MASK (0x3 << 10) #define CCM_CCGR6_DDRMC_CTRL_MASK (0x3 << 28) #define CCM_CCGR7_SDHC1_CTRL_MASK (0x3 << 4) +#define CCM_CCGR7_USBC1_CTRL_MASK (0x3 << 8) #define CCM_CCGR9_FEC0_CTRL_MASK 0x3 #define CCM_CCGR9_FEC1_CTRL_MASK (0x3 << 2) #define CCM_CCGR10_NFC_CTRL_MASK 0x3 +#define ANADIG_PLL7_CTRL_BYPASS (1 << 16) +#define ANADIG_PLL7_CTRL_ENABLE (1 << 13) +#define ANADIG_PLL7_CTRL_POWERDOWN (1 << 12) +#define ANADIG_PLL7_CTRL_DIV_SELECT (1 << 1) #define ANADIG_PLL5_CTRL_BYPASS (1 << 16) #define ANADIG_PLL5_CTRL_ENABLE (1 << 13) #define ANADIG_PLL5_CTRL_POWERDOWN (1 << 12) #define ANADIG_PLL5_CTRL_DIV_SELECT 1 +#define ANADIG_PLL3_CTRL_BYPASS (1 << 16) +#define ANADIG_PLL3_CTRL_ENABLE (1 << 13) +#define ANADIG_PLL3_CTRL_POWERDOWN (1 << 12) +#define ANADIG_PLL3_CTRL_DIV_SELECT (1 << 1) #define ANADIG_PLL2_CTRL_ENABLE (1 << 13) #define ANADIG_PLL2_CTRL_POWERDOWN (1 << 12) #define ANADIG_PLL2_CTRL_DIV_SELECT 1 diff --git a/arch/arm/include/asm/arch-vf610/ddrmc-vf610.h b/arch/arm/include/asm/arch-vf610/ddrmc-vf610.h new file mode 100644 index 0000000..6730cde --- /dev/null +++ b/arch/arm/include/asm/arch-vf610/ddrmc-vf610.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015 + * Toradex, Inc. + * + * Authors: Stefan Agner + * Sanchayan Maity + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_VF610_DDRMC_H +#define __ASM_ARCH_VF610_DDRMC_H + +struct ddrmc_lvl_info { + u16 wrlvl_reg_en; + u16 wrlvl_dl_0; + u16 wrlvl_dl_1; + u16 rdlvl_gt_reg_en; + u16 rdlvl_gt_dl_0; + u16 rdlvl_gt_dl_1; + u16 rdlvl_reg_en; + u16 rdlvl_dl_0; + u16 rdlvl_dl_1; +}; + +struct ddr3_jedec_timings { + u8 tinit; + u32 trst_pwron; + u32 cke_inactive; + u8 wrlat; + u8 caslat_lin; + u8 trc; + u8 trrd; + u8 tccd; + u8 tfaw; + u8 trp; + u8 twtr; + u8 tras_min; + u8 tmrd; + u8 trtp; + u32 tras_max; + u8 tmod; + u8 tckesr; + u8 tcke; + u8 trcd_int; + u8 tdal; + u16 tdll; + u8 trp_ab; + u16 tref; + u8 trfc; + u8 tpdex; + u8 txpdll; + u8 txsnr; + u16 txsr; + u8 cksrx; + u8 cksre; + u16 zqcl; + u16 zqinit; + u8 zqcs; + u8 ref_per_zq; + u8 aprebit; + u8 wlmrd; + u8 wldqsen; +}; + +void ddrmc_setup_iomux(void); +void ddrmc_phy_init(void); +void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings, + struct ddrmc_lvl_info *lvl, + int col_diff, int row_diff); + +#endif diff --git a/arch/arm/include/asm/arch-vf610/imx-regs.h b/arch/arm/include/asm/arch-vf610/imx-regs.h index 6b10bdf..a7d765a 100644 --- a/arch/arm/include/asm/arch-vf610/imx-regs.h +++ b/arch/arm/include/asm/arch-vf610/imx-regs.h @@ -52,6 +52,7 @@ #define SAI2_BASE_ADDR (AIPS0_BASE_ADDR + 0x00031000) #define SAI3_BASE_ADDR (AIPS0_BASE_ADDR + 0x00032000) #define CRC_BASE_ADDR (AIPS0_BASE_ADDR + 0x00033000) +#define USBC0_BASE_ADDR (AIPS0_BASE_ADDR + 0x00034000) #define PDB_BASE_ADDR (AIPS0_BASE_ADDR + 0x00036000) #define PIT_BASE_ADDR (AIPS0_BASE_ADDR + 0x00037000) #define FTM0_BASE_ADDR (AIPS0_BASE_ADDR + 0x00038000) @@ -65,7 +66,9 @@ #define QSPI0_BASE_ADDR (AIPS0_BASE_ADDR + 0x00044000) #define IOMUXC_BASE_ADDR (AIPS0_BASE_ADDR + 0x00048000) #define ANADIG_BASE_ADDR (AIPS0_BASE_ADDR + 0x00050000) -#define SCSCM_BASE_ADDR (AIPS0_BASE_ADDR + 0x00052000) +#define USB_PHY0_BASE_ADDR (AIPS0_BASE_ADDR + 0x00050800) +#define USB_PHY1_BASE_ADDR (AIPS0_BASE_ADDR + 0x00050C00) +#define SCSC_BASE_ADDR (AIPS0_BASE_ADDR + 0x00052000) #define ASRC_BASE_ADDR (AIPS0_BASE_ADDR + 0x00060000) #define SPDIF_BASE_ADDR (AIPS0_BASE_ADDR + 0x00061000) #define ESAI_BASE_ADDR (AIPS0_BASE_ADDR + 0x00062000) @@ -84,6 +87,7 @@ #define DDR_BASE_ADDR (AIPS1_BASE_ADDR + 0x0002E000) #define ESDHC0_BASE_ADDR (AIPS1_BASE_ADDR + 0x00031000) #define ESDHC1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00032000) +#define USBC1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00034000) #define ENET_BASE_ADDR (AIPS1_BASE_ADDR + 0x00050000) #define ENET1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00051000) #define NFC_BASE_ADDR (AIPS1_BASE_ADDR + 0x00060000) @@ -196,8 +200,8 @@ #define DDRMC_CR96_WLMRD(v) (((v) & 0x3f) << 8) #define DDRMC_CR96_WLDQSEN(v) ((v) & 0x3f) #define DDRMC_CR97_WRLVL_EN (1 << 24) -#define DDRMC_CR98_WRLVL_DL_0 (0) -#define DDRMC_CR99_WRLVL_DL_1 (0) +#define DDRMC_CR98_WRLVL_DL_0(v) ((v) & 0xffff) +#define DDRMC_CR99_WRLVL_DL_1(v) ((v) & 0xffff) #define DDRMC_CR102_RDLVL_GT_REGEN (1 << 16) #define DDRMC_CR102_RDLVL_REG_EN (1 << 8) #define DDRMC_CR105_RDLVL_DL_0(v) (((v) & 0xff) << 8) @@ -263,6 +267,14 @@ #define SRC_SRSR_WDOG_M4 (0x1 << 4) #define SRC_SRSR_WDOG_A5 (0x1 << 3) #define SRC_SRSR_POR_RST (0x1 << 0) +#define SRC_SBMR2_BMOD_MASK (0x3 << 24) +#define SRC_SBMR2_BMOD_SHIFT 24 +#define SRC_SBMR2_BMOD_FUSES 0x0 +#define SRC_SBMR2_BMOD_SERIAL 0x1 +#define SRC_SBMR2_BMOD_RCON 0x2 + +/* Slow Clock Source Controller Module (SCSC) */ +#define SCSC_SOSC_CTR_SOSC_EN 0x1 #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__)) #include <asm/types.h> @@ -448,6 +460,24 @@ struct mscm_ir { u16 rsvd3[848]; }; +/* SCSC */ +struct scsc_reg { + u32 sirc_ctr; + u32 sosc_ctr; +}; + +/* MSCM */ +struct mscm { + u32 cpxtype; + u32 cpxnum; + u32 cpxmaster; + u32 cpxcount; + u32 cpxcfg0; + u32 cpxcfg1; + u32 cpxcfg2; + u32 cpxcfg3; +}; + #endif /* __ASSEMBLER__*/ #endif /* __ASM_ARCH_IMX_REGS_H__ */ diff --git a/arch/arm/include/asm/arch-zynq/gpio.h b/arch/arm/include/asm/arch-zynq/gpio.h deleted file mode 100644 index a26ae87..0000000 --- a/arch/arm/include/asm/arch-zynq/gpio.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright (c) 2013 Xilinx, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _ZYNQ_GPIO_H -#define _ZYNQ_GPIO_H - -#endif /* _ZYNQ_GPIO_H */ diff --git a/arch/arm/include/asm/arch-zynqmp/gpio.h b/arch/arm/include/asm/arch-zynqmp/gpio.h new file mode 100644 index 0000000..098bbde --- /dev/null +++ b/arch/arm/include/asm/arch-zynqmp/gpio.h @@ -0,0 +1,12 @@ +/* + * Copyright 2015 Xilinx, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ARCH_ZYNQMP_GPIO_H +#define __ARCH_ZYNQMP_GPIO_H + +/* Empty file - sdhci requires this. */ + +#endif diff --git a/arch/arm/include/asm/arch-zynqmp/hardware.h b/arch/arm/include/asm/arch-zynqmp/hardware.h index 97fb49a..c9dc49d 100644 --- a/arch/arm/include/asm/arch-zynqmp/hardware.h +++ b/arch/arm/include/asm/arch-zynqmp/hardware.h @@ -11,6 +11,12 @@ #define ZYNQ_SERIAL_BASEADDR0 0xFF000000 #define ZYNQ_SERIAL_BASEADDR1 0xFF001000 +#define ZYNQ_SPI_BASEADDR0 0xFF040000 +#define ZYNQ_SPI_BASEADDR1 0xFF050000 + +#define ZYNQ_I2C_BASEADDR0 0xFF020000 +#define ZYNQ_I2C_BASEADDR1 0xFF030000 + #define ZYNQ_SDHCI_BASEADDR0 0xFF160000 #define ZYNQ_SDHCI_BASEADDR1 0xFF170000 @@ -18,11 +24,15 @@ #define ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT 0x1000000 struct crlapb_regs { - u32 reserved0[74]; + u32 reserved0[36]; + u32 cpu_r5_ctrl; /* 0x90 */ + u32 reserved1[37]; u32 timestamp_ref_ctrl; /* 0x128 */ - u32 reserved0_1[53]; + u32 reserved2[53]; u32 boot_mode; /* 0x200 */ - u32 reserved1[26]; + u32 reserved3[14]; + u32 rst_lpd_top; /* 0x23C */ + u32 reserved4[26]; }; #define crlapb_base ((struct crlapb_regs *)ZYNQMP_CRL_APB_BASEADDR) @@ -41,12 +51,47 @@ struct iou_scntr { /* Bootmode setting values */ #define BOOT_MODES_MASK 0x0000000F -#define SD_MODE 0x00000005 +#define SD_MODE 0x00000003 +#define EMMC_MODE 0x00000006 #define JTAG_MODE 0x00000000 +#define ZYNQMP_RPU_BASEADDR 0xFF9A0000 + +struct rpu_regs { + u32 rpu_glbl_ctrl; + u32 reserved0[63]; + u32 rpu0_cfg; /* 0x100 */ + u32 reserved1[63]; + u32 rpu1_cfg; /* 0x200 */ +}; + +#define rpu_base ((struct rpu_regs *)ZYNQMP_RPU_BASEADDR) + +#define ZYNQMP_CRF_APB_BASEADDR 0xFD1A0000 + +struct crfapb_regs { + u32 reserved0[65]; + u32 rst_fpd_apu; /* 0x104 */ + u32 reserved1; +}; + +#define crfapb_base ((struct crfapb_regs *)ZYNQMP_CRF_APB_BASEADDR) + +#define ZYNQMP_APU_BASEADDR 0xFD5C0000 + +struct apu_regs { + u32 reserved0[16]; + u32 rvbar_addr0_l; /* 0x40 */ + u32 rvbar_addr0_h; /* 0x44 */ + u32 reserved1[20]; +}; + +#define apu_base ((struct apu_regs *)ZYNQMP_APU_BASEADDR) + /* Board version value */ #define ZYNQMP_CSU_VERSION_SILICON 0x0 #define ZYNQMP_CSU_VERSION_EP108 0x1 +#define ZYNQMP_CSU_VERSION_VELOCE 0x2 #define ZYNQMP_CSU_VERSION_QEMU 0x3 #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/armv7m.h b/arch/arm/include/asm/armv7m.h new file mode 100644 index 0000000..d2aa1c4 --- /dev/null +++ b/arch/arm/include/asm/armv7m.h @@ -0,0 +1,60 @@ +/* + * (C) Copyright 2010,2011 + * Vladimir Khusainov, Emcraft Systems, vlad@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef ARMV7M_H +#define ARMV7M_H + +#if defined(__ASSEMBLY__) +.syntax unified +.thumb +#endif + +#define V7M_SCB_BASE 0xE000ED00 +#define V7M_MPU_BASE 0xE000ED90 + +#define V7M_SCB_VTOR 0x08 + +#if !defined(__ASSEMBLY__) +struct v7m_scb { + uint32_t cpuid; /* CPUID Base Register */ + uint32_t icsr; /* Interrupt Control and State Register */ + uint32_t vtor; /* Vector Table Offset Register */ + uint32_t aircr; /* App Interrupt and Reset Control Register */ +}; +#define V7M_SCB ((struct v7m_scb *)V7M_SCB_BASE) + +#define V7M_AIRCR_VECTKEY 0x5fa +#define V7M_AIRCR_VECTKEY_SHIFT 16 +#define V7M_AIRCR_ENDIAN (1 << 15) +#define V7M_AIRCR_PRIGROUP_SHIFT 8 +#define V7M_AIRCR_PRIGROUP_MSK (0x7 << V7M_AIRCR_PRIGROUP_SHIFT) +#define V7M_AIRCR_SYSRESET (1 << 2) + +#define V7M_ICSR_VECTACT_MSK 0xFF + +struct v7m_mpu { + uint32_t type; /* Type Register */ + uint32_t ctrl; /* Control Register */ + uint32_t rnr; /* Region Number Register */ + uint32_t rbar; /* Region Base Address Register */ + uint32_t rasr; /* Region Attribute and Size Register */ +}; +#define V7M_MPU ((struct v7m_mpu *)V7M_MPU_BASE) + +#define V7M_MPU_CTRL_ENABLE (1 << 0) +#define V7M_MPU_CTRL_HFNMIENA (1 << 1) + +#define V7M_MPU_RASR_EN (1 << 0) +#define V7M_MPU_RASR_SIZE_BITS 1 +#define V7M_MPU_RASR_SIZE_4GB (31 << V7M_MPU_RASR_SIZE_BITS) +#define V7M_MPU_RASR_AP_RW_RW (3 << 24) + +#endif /* !defined(__ASSEMBLY__) */ +#endif /* ARMV7M_H */ diff --git a/arch/arm/include/asm/fsl_secure_boot.h b/arch/arm/include/asm/fsl_secure_boot.h new file mode 100644 index 0000000..f097c81 --- /dev/null +++ b/arch/arm/include/asm/fsl_secure_boot.h @@ -0,0 +1,25 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_SECURE_BOOT_H +#define __FSL_SECURE_BOOT_H + +#ifdef CONFIG_SECURE_BOOT +#ifndef CONFIG_FIT_SIGNATURE + +#define CONFIG_EXTRA_ENV \ + "setenv fdt_high 0xcfffffff;" \ + "setenv initrd_high 0xcfffffff;" \ + "setenv hwconfig \'fsl_ddr:ctlr_intlv=null,bank_intlv=null\';" + +/* The address needs to be modified according to NOR memory map */ +#define CONFIG_BOOTSCRIPT_HDR_ADDR 0x600a0000 + +#include <config_fsl_secboot.h> +#endif +#endif + +#endif diff --git a/arch/arm/include/asm/imx-common/regs-usbphy.h b/arch/arm/include/asm/imx-common/regs-usbphy.h new file mode 100644 index 0000000..220e45f --- /dev/null +++ b/arch/arm/include/asm/imx-common/regs-usbphy.h @@ -0,0 +1,26 @@ +/* + * Freescale USB PHY Register Definitions + * + * SPDX-License-Identifier: GPL-2.0+ + * + */ + +#ifndef __REGS_USBPHY_H__ +#define __REGS_USBPHY_H__ + +#define USBPHY_CTRL 0x00000030 +#define USBPHY_CTRL_SET 0x00000034 +#define USBPHY_CTRL_CLR 0x00000038 +#define USBPHY_CTRL_TOG 0x0000003C +#define USBPHY_PWD 0x00000000 +#define USBPHY_TX 0x00000010 +#define USBPHY_RX 0x00000020 +#define USBPHY_DEBUG 0x00000050 + +#define USBPHY_CTRL_ENUTMILEVEL2 (1 << 14) +#define USBPHY_CTRL_ENUTMILEVEL3 (1 << 15) +#define USBPHY_CTRL_OTG_ID (1 << 27) +#define USBPHY_CTRL_CLKGATE (1 << 30) +#define USBPHY_CTRL_SFTRST (1 << 31) + +#endif /* __REGS_USBPHY_H__ */ diff --git a/arch/arm/include/asm/imx-common/video.h b/arch/arm/include/asm/imx-common/video.h index 1a907d4..cad5f86 100644 --- a/arch/arm/include/asm/imx-common/video.h +++ b/arch/arm/include/asm/imx-common/video.h @@ -26,4 +26,5 @@ extern struct display_info_t const displays[]; extern size_t display_count; #endif +int ipu_set_ldb_clock(int rate); #endif diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h index c424a22..5afe791 100644 --- a/arch/arm/include/asm/mach-types.h +++ b/arch/arm/include/asm/mach-types.h @@ -1108,6 +1108,7 @@ extern unsigned int __machine_arch_type; #define MACH_TYPE_KZM9G 4140 #define MACH_TYPE_COLIBRI_T30 4493 #define MACH_TYPE_APALIS_T30 4513 +#define MACH_TYPE_OMAPL138_LCDK 2495 #ifdef CONFIG_ARCH_EBSA110 # ifdef machine_arch_type diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index c8c3e71..b0296fb 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -362,6 +362,10 @@ struct omap_sys_ctrl_regs { u32 control_core_control_io1; u32 control_core_control_io2; u32 control_id_code; + u32 control_std_fuse_die_id_0; + u32 control_std_fuse_die_id_1; + u32 control_std_fuse_die_id_2; + u32 control_std_fuse_die_id_3; u32 control_std_fuse_opp_bgap; u32 control_ldosram_iva_voltage_ctrl; u32 control_ldosram_mpu_voltage_ctrl; @@ -578,6 +582,7 @@ void abb_setup(u32 fuse, u32 ldovbb, u32 setup, u32 control, s8 abb_setup_ldovbb(u32 fuse, u32 ldovbb); void usb_fake_mac_from_die_id(u32 *id); +void usb_set_serial_num_from_die_id(u32 *id); void omap_smc1(u32 service, u32 val); diff --git a/arch/arm/include/asm/pcie_layerscape.h b/arch/arm/include/asm/pcie_layerscape.h deleted file mode 100644 index fb08578..0000000 --- a/arch/arm/include/asm/pcie_layerscape.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2014 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __PCIE_LAYERSCAPE_H_ -#define __PCIE_LAYERSCAPE_H_ - -void pci_init_board(void); -void ft_pcie_setup(void *blob, bd_t *bd); - -#endif diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index da8ed72..0e1ad0e 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -8,7 +8,9 @@ lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _ashldi3.o _ashrdi3.o _divsi3.o \ _lshrdi3.o _modsi3.o _udivsi3.o _umodsi3.o div0.o -ifdef CONFIG_ARM64 +ifdef CONFIG_CPU_V7M +obj-y += vectors_m.o crt0.o +else ifdef CONFIG_ARM64 obj-y += crt0_64.o else obj-y += vectors.o crt0.o @@ -36,7 +38,9 @@ obj-$(CONFIG_SEMIHOSTING) += semihosting.o obj-y += sections.o obj-y += stack.o -ifdef CONFIG_ARM64 +ifdef CONFIG_CPU_V7M +obj-y += interrupts_m.o +else ifdef CONFIG_ARM64 obj-y += gic_64.o obj-y += interrupts_64.o else diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index f606255..37ea6e9 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -644,7 +644,7 @@ void board_init_r(gd_t *id, ulong dest_addr) #endif #if defined(CONFIG_CMD_NET) puts("Net: "); - eth_initialize(gd->bd); + eth_initialize(); #if defined(CONFIG_RESET_PHY_R) debug("Reset Ethernet PHY\n"); reset_phy(); diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 2d6b676..b1bff8c 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -18,6 +18,7 @@ #include <u-boot/zlib.h> #include <asm/byteorder.h> #include <libfdt.h> +#include <mapmem.h> #include <fdt_support.h> #include <asm/bootm.h> #include <asm/secure.h> diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S index 92d3732..afd4f10 100644 --- a/arch/arm/lib/crt0.S +++ b/arch/arm/lib/crt0.S @@ -9,6 +9,9 @@ #include <config.h> #include <asm-offsets.h> #include <linux/linkage.h> +#ifdef CONFIG_CPU_V7M +#include <asm/armv7m.h> +#endif /* * This file handles the target-independent stages of the U-Boot @@ -66,15 +69,30 @@ ENTRY(_main) #else ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif +#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */ + mov r3, sp + bic r3, r3, #7 + mov sp, r3 +#else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ +#endif mov r2, sp sub sp, sp, #GD_SIZE /* allocate one GD above SP */ +#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */ + mov r3, sp + bic r3, r3, #7 + mov sp, r3 +#else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ +#endif mov r9, sp /* GD is above SP */ mov r1, sp mov r0, #0 clr_gd: cmp r1, r2 /* while not at end of GD */ +#if defined(CONFIG_CPU_V7M) + itt lo +#endif strlo r0, [r1] /* clear 32-bit GD word */ addlo r1, r1, #4 /* move to next */ blo clr_gd @@ -94,13 +112,22 @@ clr_gd: */ ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */ +#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */ + mov r3, sp + bic r3, r3, #7 + mov sp, r3 +#else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ +#endif ldr r9, [r9, #GD_BD] /* r9 = gd->bd */ sub r9, r9, #GD_SIZE /* new GD is below bd */ adr lr, here ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */ add lr, lr, r0 +#if defined(CONFIG_CPU_V7M) + orr lr, #1 /* As required by Thumb-only */ +#endif ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ b relocate_code here: @@ -134,6 +161,9 @@ here: mov r2, #0x00000000 /* prepare zero to clear BSS */ clbss_l:cmp r0, r1 /* while not at end of BSS */ +#if defined(CONFIG_CPU_V7M) + itt lo +#endif strlo r2, [r0] /* clear 32-bit BSS word */ addlo r0, r0, #4 /* move to next */ blo clbss_l diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S index 1654011..bc9c53c 100644 --- a/arch/arm/lib/crt0_64.S +++ b/arch/arm/lib/crt0_64.S @@ -61,7 +61,11 @@ ENTRY(_main) /* * Set up initial C runtime environment and call board_init_f(0). */ +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) + ldr x0, =(CONFIG_SPL_STACK) +#else ldr x0, =(CONFIG_SYS_INIT_SP_ADDR) +#endif sub x18, x0, #GD_SIZE /* allocate one GD above SP */ bic x18, x18, #0x7 /* 8-byte alignment for GD */ zero_gd: @@ -77,6 +81,7 @@ zero_gd: mov x0, #0 bl board_init_f +#if !defined(CONFIG_SPL_BUILD) /* * Set up intermediate environment (new sp and gd) and call * relocate_code(addr_moni). Trick here is that we'll return @@ -119,4 +124,6 @@ clear_loop: /* NOTREACHED - board_init_r() does not return */ +#endif /* !CONFIG_SPL_BUILD */ + ENDPROC(_main) diff --git a/arch/arm/lib/interrupts_m.c b/arch/arm/lib/interrupts_m.c new file mode 100644 index 0000000..89ce493 --- /dev/null +++ b/arch/arm/lib/interrupts_m.c @@ -0,0 +1,95 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +/* + * Upon exception entry ARMv7-M processors automatically save stack + * frames containing some registers. For simplicity initial + * implementation uses only this auto-saved stack frame. + * This does not contain complete register set dump, + * only R0-R3, R12, LR, PC and xPSR are saved. + */ + +struct autosave_regs { + long uregs[8]; +}; + +#define ARM_XPSR uregs[7] +#define ARM_PC uregs[6] +#define ARM_LR uregs[5] +#define ARM_R12 uregs[4] +#define ARM_R3 uregs[3] +#define ARM_R2 uregs[2] +#define ARM_R1 uregs[1] +#define ARM_R0 uregs[0] + +int interrupt_init(void) +{ + return 0; +} + +void enable_interrupts(void) +{ + return; +} + +int disable_interrupts(void) +{ + return 0; +} + +void dump_regs(struct autosave_regs *regs) +{ + printf("pc : %08lx lr : %08lx xPSR : %08lx\n", + regs->ARM_PC, regs->ARM_LR, regs->ARM_XPSR); + printf("r12 : %08lx r3 : %08lx r2 : %08lx\n" + "r1 : %08lx r0 : %08lx\n", + regs->ARM_R12, regs->ARM_R3, regs->ARM_R2, + regs->ARM_R1, regs->ARM_R0); +} + +void bad_mode(void) +{ + panic("Resetting CPU ...\n"); + reset_cpu(0); +} + +void do_hard_fault(struct autosave_regs *autosave_regs) +{ + printf("Hard fault\n"); + dump_regs(autosave_regs); + bad_mode(); +} + +void do_mm_fault(struct autosave_regs *autosave_regs) +{ + printf("Memory management fault\n"); + dump_regs(autosave_regs); + bad_mode(); +} + +void do_bus_fault(struct autosave_regs *autosave_regs) +{ + printf("Bus fault\n"); + dump_regs(autosave_regs); + bad_mode(); +} + +void do_usage_fault(struct autosave_regs *autosave_regs) +{ + printf("Usage fault\n"); + dump_regs(autosave_regs); + bad_mode(); +} + +void do_invalid_entry(struct autosave_regs *autosave_regs) +{ + printf("Exception\n"); + dump_regs(autosave_regs); + bad_mode(); +} diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S index 92f5314..475d503 100644 --- a/arch/arm/lib/relocate.S +++ b/arch/arm/lib/relocate.S @@ -9,6 +9,9 @@ #include <asm-offsets.h> #include <config.h> #include <linux/linkage.h> +#ifdef CONFIG_CPU_V7M +#include <asm/armv7m.h> +#endif /* * Default/weak exception vectors relocation routine @@ -23,6 +26,15 @@ ENTRY(relocate_vectors) +#ifdef CONFIG_CPU_V7M + /* + * On ARMv7-M we only have to write the new vector address + * to VTOR register. + */ + ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ + ldr r1, =V7M_SCB_BASE + str r0, [r1, V7M_SCB_VTOR] +#else #ifdef CONFIG_HAS_VBAR /* * If the ARM processor has the security extensions, @@ -47,6 +59,7 @@ ENTRY(relocate_vectors) ldmia r0!, {r2-r8,r10} stmia r1!, {r2-r8,r10} #endif +#endif bx lr ENDPROC(relocate_vectors) diff --git a/arch/arm/lib/vectors_m.S b/arch/arm/lib/vectors_m.S new file mode 100644 index 0000000..abc7f88 --- /dev/null +++ b/arch/arm/lib/vectors_m.S @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/armv7m.h> +#include <linux/linkage.h> + +.type __hard_fault_entry, %function +__hard_fault_entry: + mov r0, sp @ pass auto-saved registers as argument + b do_hard_fault + +.type __mm_fault_entry, %function +__mm_fault_entry: + mov r0, sp @ pass auto-saved registers as argument + b do_mm_fault + +.type __bus_fault_entry, %function +__bus_fault_entry: + mov r0, sp @ pass auto-saved registers as argument + b do_bus_fault + +.type __usage_fault_entry, %function +__usage_fault_entry: + mov r0, sp @ pass auto-saved registers as argument + b do_usage_fault + +.type __invalid_entry, %function +__invalid_entry: + mov r0, sp @ pass auto-saved registers as argument + b do_invalid_entry + + .section .vectors +ENTRY(_start) + .long CONFIG_SYS_INIT_SP_ADDR @ 0 - Reset stack pointer + .long reset @ 1 - Reset + .long __invalid_entry @ 2 - NMI + .long __hard_fault_entry @ 3 - HardFault + .long __mm_fault_entry @ 4 - MemManage + .long __bus_fault_entry @ 5 - BusFault + .long __usage_fault_entry @ 6 - UsageFault + .long __invalid_entry @ 7 - Reserved + .long __invalid_entry @ 8 - Reserved + .long __invalid_entry @ 9 - Reserved + .long __invalid_entry @ 10 - Reserved + .long __invalid_entry @ 11 - SVCall + .long __invalid_entry @ 12 - Debug Monitor + .long __invalid_entry @ 13 - Reserved + .long __invalid_entry @ 14 - PendSV + .long __invalid_entry @ 15 - SysTick + .rept 255 - 16 + .long __invalid_entry @ 16..255 - External Interrupts + .endr diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 30c4e17..b660a5b 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -30,6 +30,9 @@ config TARGET_TNY_A9260 config TARGET_SNAPPER9260 bool "Support snapper9260" select CPU_ARM926EJS + select DM + select DM_SERIAL + select DM_GPIO config TARGET_AFEB9260 bool "Support afeb9260" diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig index 0c04c30..c740180 100644 --- a/arch/arm/mach-bcm283x/Kconfig +++ b/arch/arm/mach-bcm283x/Kconfig @@ -14,15 +14,6 @@ config TARGET_RPI_2 endchoice -config DM - default y - -config DM_SERIAL - default y - -config DM_GPIO - default y - config PHYS_TO_BUS default y diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index 6827721..3ef55d3 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -21,6 +21,10 @@ config TARGET_CAM_ENC_4XX bool "CAM ENC 4xx board" select SUPPORT_SPL +config TARGET_OMAPL138_LCDK + bool "OMAPL138 LCDK" + select SUPPORT_SPL + config TARGET_DAVINCI_DM355EVM bool "DM355 EVM board" diff --git a/arch/arm/mach-davinci/misc.c b/arch/arm/mach-davinci/misc.c index e18bdfc..e699d61 100644 --- a/arch/arm/mach-davinci/misc.c +++ b/arch/arm/mach-davinci/misc.c @@ -49,7 +49,7 @@ int dvevm_read_mac_address(uint8_t *buf) goto i2cerr; /* Check that MAC address is valid. */ - if (!is_valid_ether_addr(buf)) + if (!is_valid_ethaddr(buf)) goto err; return 1; /* Found */ diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig new file mode 100644 index 0000000..8ffc544 --- /dev/null +++ b/arch/arm/mach-integrator/Kconfig @@ -0,0 +1,54 @@ +menu "Integrator Options" + depends on ARCH_INTEGRATOR + +choice + prompt "Integrator platform select" + +config ARCH_INTEGRATOR_AP + bool "Support Integrator/AP platform" + +config ARCH_INTEGRATOR_CP + bool "Support Integrator/CP platform" + select ARCH_CINTEGRATOR + +endchoice + +config ARCH_CINTEGRATOR + bool + +choice + prompt "Integrator core module select" + +config CM720T + bool "Core Module for ARM720T" + select CPU_ARM720T + +config CM920T + bool "Core Module for ARM920T" + select CPU_ARM920T + +config CM926EJ_S + bool "Core Module for ARM926EJ-STM" + select CPU_ARM926EJS + +config CM946ES + bool "Core Module for ARM946E-STM" + select CPU_ARM946ES + +config CM1136 + bool "Core Module for ARM1136JF-STM" + select CPU_ARM1136 + +endchoice + +config SYS_BOARD + default "integrator" + +config SYS_VENDOR + default "armltd" + +config SYS_CONFIG_NAME + default "integratorap" if ARCH_INTEGRATOR_AP + default "integratorcp" if ARCH_INTEGRATOR_CP + +endmenu diff --git a/arch/arm/mach-kirkwood/include/mach/config.h b/arch/arm/mach-kirkwood/include/mach/config.h index e77ac40..d049395 100644 --- a/arch/arm/mach-kirkwood/include/mach/config.h +++ b/arch/arm/mach-kirkwood/include/mach/config.h @@ -44,7 +44,7 @@ #define CONFIG_SYS_INIT_SP_ADDR 0xC8012000 #define CONFIG_NR_DRAM_BANKS_MAX 2 -#define CONFIG_I2C_MVTWSI_BASE KW_TWSI_BASE +#define CONFIG_I2C_MVTWSI_BASE0 KW_TWSI_BASE #define MV_UART_CONSOLE_BASE KW_UART0_BASE #define MV_SATA_BASE KW_SATA_BASE #define MV_SATA_PORT0_OFFSET KW_SATA_PORT0_OFFSET diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index fce1c1d..8bab594 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -23,27 +23,9 @@ config SYS_MALLOC_F_LEN config USE_PRIVATE_LIBGCC default y -config DM - default y - config SPL_DM default y -config DM_SERIAL - default y - -config DM_SPI - default y - -config DM_SPI_FLASH - default y - -config DM_I2C - default y - -config DM_GPIO - default y - source "arch/arm/mach-tegra/tegra20/Kconfig" source "arch/arm/mach-tegra/tegra30/Kconfig" source "arch/arm/mach-tegra/tegra114/Kconfig" diff --git a/arch/arm/cpu/armv7/zynq/Kconfig b/arch/arm/mach-zynq/Kconfig index 3a52535..1046ece 100644 --- a/arch/arm/cpu/armv7/zynq/Kconfig +++ b/arch/arm/mach-zynq/Kconfig @@ -1,4 +1,4 @@ -if ZYNQ +if ARCH_ZYNQ choice prompt "Xilinx Zynq board select" @@ -9,6 +9,9 @@ config TARGET_ZYNQ_ZED config TARGET_ZYNQ_MICROZED bool "Zynq MicroZed" +config TARGET_ZYNQ_PICOZED + bool "Zynq PicoZed" + config TARGET_ZYNQ_ZC70X bool "Zynq ZC702/ZC706 Board" @@ -32,6 +35,7 @@ config SYS_SOC config SYS_CONFIG_NAME default "zynq_zed" if TARGET_ZYNQ_ZED default "zynq_microzed" if TARGET_ZYNQ_MICROZED + default "zynq_picozed" if TARGET_ZYNQ_PICOZED default "zynq_zc70x" if TARGET_ZYNQ_ZC70X default "zynq_zc770" if TARGET_ZYNQ_ZC770 default "zynq_zybo" if TARGET_ZYNQ_ZYBO diff --git a/arch/arm/cpu/armv7/zynq/Makefile b/arch/arm/mach-zynq/Makefile index 901f2ce..bf29b4d 100644 --- a/arch/arm/cpu/armv7/zynq/Makefile +++ b/arch/arm/mach-zynq/Makefile @@ -14,4 +14,5 @@ obj-y += ddrc.o obj-y += slcr.o obj-y += clk.o obj-y += lowlevel_init.o +AFLAGS_lowlevel_init.o := -mfpu=neon obj-$(CONFIG_SPL_BUILD) += spl.o diff --git a/arch/arm/cpu/armv7/zynq/clk.c b/arch/arm/mach-zynq/clk.c index d2885dc..d2885dc 100644 --- a/arch/arm/cpu/armv7/zynq/clk.c +++ b/arch/arm/mach-zynq/clk.c diff --git a/arch/arm/cpu/armv7/zynq/cpu.c b/arch/arm/mach-zynq/cpu.c index 914b1fe..914b1fe 100644 --- a/arch/arm/cpu/armv7/zynq/cpu.c +++ b/arch/arm/mach-zynq/cpu.c diff --git a/arch/arm/cpu/armv7/zynq/ddrc.c b/arch/arm/mach-zynq/ddrc.c index 5b20acc..5b20acc 100644 --- a/arch/arm/cpu/armv7/zynq/ddrc.c +++ b/arch/arm/mach-zynq/ddrc.c diff --git a/arch/arm/include/asm/arch-zynq/clk.h b/arch/arm/mach-zynq/include/mach/clk.h index 250c5bc..250c5bc 100644 --- a/arch/arm/include/asm/arch-zynq/clk.h +++ b/arch/arm/mach-zynq/include/mach/clk.h diff --git a/arch/arm/mach-zynq/include/mach/gpio.h b/arch/arm/mach-zynq/include/mach/gpio.h new file mode 100644 index 0000000..9e1e7da --- /dev/null +++ b/arch/arm/mach-zynq/include/mach/gpio.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013 Xilinx, Inc. + * Copyright (c) 2015 DAVE Embedded Systems + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ZYNQ_GPIO_H +#define _ZYNQ_GPIO_H + +#define ZYNQ_GPIO_BASE_ADDRESS 0xE000A000 + +/* Maximum banks */ +#define ZYNQ_GPIO_MAX_BANK 4 + +#define ZYNQ_GPIO_BANK0_NGPIO 32 +#define ZYNQ_GPIO_BANK1_NGPIO 22 +#define ZYNQ_GPIO_BANK2_NGPIO 32 +#define ZYNQ_GPIO_BANK3_NGPIO 32 + +#define ZYNQ_GPIO_NR_GPIOS (ZYNQ_GPIO_BANK0_NGPIO + \ + ZYNQ_GPIO_BANK1_NGPIO + \ + ZYNQ_GPIO_BANK2_NGPIO + \ + ZYNQ_GPIO_BANK3_NGPIO) + +#define ZYNQ_GPIO_BANK0_PIN_MIN 0 +#define ZYNQ_GPIO_BANK0_PIN_MAX (ZYNQ_GPIO_BANK0_PIN_MIN + \ + ZYNQ_GPIO_BANK0_NGPIO - 1) +#define ZYNQ_GPIO_BANK1_PIN_MIN (ZYNQ_GPIO_BANK0_PIN_MAX + 1) +#define ZYNQ_GPIO_BANK1_PIN_MAX (ZYNQ_GPIO_BANK1_PIN_MIN + \ + ZYNQ_GPIO_BANK1_NGPIO - 1) +#define ZYNQ_GPIO_BANK2_PIN_MIN (ZYNQ_GPIO_BANK1_PIN_MAX + 1) +#define ZYNQ_GPIO_BANK2_PIN_MAX (ZYNQ_GPIO_BANK2_PIN_MIN + \ + ZYNQ_GPIO_BANK2_NGPIO - 1) +#define ZYNQ_GPIO_BANK3_PIN_MIN (ZYNQ_GPIO_BANK2_PIN_MAX + 1) +#define ZYNQ_GPIO_BANK3_PIN_MAX (ZYNQ_GPIO_BANK3_PIN_MIN + \ + ZYNQ_GPIO_BANK3_NGPIO - 1) + +/* Register offsets for the GPIO device */ +/* LSW Mask & Data -WO */ +#define ZYNQ_GPIO_DATA_LSW_OFFSET(BANK) (0x000 + (8 * BANK)) +/* MSW Mask & Data -WO */ +#define ZYNQ_GPIO_DATA_MSW_OFFSET(BANK) (0x004 + (8 * BANK)) +/* Data Register-RW */ +#define ZYNQ_GPIO_DATA_RO_OFFSET(BANK) (0x060 + (4 * BANK)) +/* Direction mode reg-RW */ +#define ZYNQ_GPIO_DIRM_OFFSET(BANK) (0x204 + (0x40 * BANK)) +/* Output enable reg-RW */ +#define ZYNQ_GPIO_OUTEN_OFFSET(BANK) (0x208 + (0x40 * BANK)) +/* Interrupt mask reg-RO */ +#define ZYNQ_GPIO_INTMASK_OFFSET(BANK) (0x20C + (0x40 * BANK)) +/* Interrupt enable reg-WO */ +#define ZYNQ_GPIO_INTEN_OFFSET(BANK) (0x210 + (0x40 * BANK)) +/* Interrupt disable reg-WO */ +#define ZYNQ_GPIO_INTDIS_OFFSET(BANK) (0x214 + (0x40 * BANK)) +/* Interrupt status reg-RO */ +#define ZYNQ_GPIO_INTSTS_OFFSET(BANK) (0x218 + (0x40 * BANK)) +/* Interrupt type reg-RW */ +#define ZYNQ_GPIO_INTTYPE_OFFSET(BANK) (0x21C + (0x40 * BANK)) +/* Interrupt polarity reg-RW */ +#define ZYNQ_GPIO_INTPOL_OFFSET(BANK) (0x220 + (0x40 * BANK)) +/* Interrupt on any, reg-RW */ +#define ZYNQ_GPIO_INTANY_OFFSET(BANK) (0x224 + (0x40 * BANK)) + +/* Disable all interrupts mask */ +#define ZYNQ_GPIO_IXR_DISABLE_ALL 0xFFFFFFFF + +/* Mid pin number of a bank */ +#define ZYNQ_GPIO_MID_PIN_NUM 16 + +/* GPIO upper 16 bit mask */ +#define ZYNQ_GPIO_UPPER_MASK 0xFFFF0000 + +#define BIT(x) (1<<x) + +#endif /* _ZYNQ_GPIO_H */ diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/mach-zynq/include/mach/hardware.h index e2e0b73..e2e0b73 100644 --- a/arch/arm/include/asm/arch-zynq/hardware.h +++ b/arch/arm/mach-zynq/include/mach/hardware.h diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/mach-zynq/include/mach/sys_proto.h index 9d50e24..9d50e24 100644 --- a/arch/arm/include/asm/arch-zynq/sys_proto.h +++ b/arch/arm/mach-zynq/include/mach/sys_proto.h diff --git a/arch/arm/cpu/armv7/zynq/lowlevel_init.S b/arch/arm/mach-zynq/lowlevel_init.S index 6d714b7..6d714b7 100644 --- a/arch/arm/cpu/armv7/zynq/lowlevel_init.S +++ b/arch/arm/mach-zynq/lowlevel_init.S diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/mach-zynq/slcr.c index 2521589..05f4099 100644 --- a/arch/arm/cpu/armv7/zynq/slcr.c +++ b/arch/arm/mach-zynq/slcr.c @@ -129,11 +129,18 @@ out: void zynq_slcr_devcfg_disable(void) { + u32 reg_val; + zynq_slcr_unlock(); /* Disable AXI interface by asserting FPGA resets */ writel(0xF, &slcr_base->fpga_rst_ctrl); + /* Disable Level shifters before setting PS-PL */ + reg_val = readl(&slcr_base->lvl_shftr_en); + reg_val &= ~0xF; + writel(reg_val, &slcr_base->lvl_shftr_en); + /* Set Level Shifters DT618760 */ writel(0xA, &slcr_base->lvl_shftr_en); diff --git a/arch/arm/cpu/armv7/zynq/spl.c b/arch/arm/mach-zynq/spl.c index b80c357..13025f0 100644 --- a/arch/arm/cpu/armv7/zynq/spl.c +++ b/arch/arm/mach-zynq/spl.c @@ -85,6 +85,6 @@ __weak void ps7_init(void) { /* * This function is overridden by the one in - * board/xilinx/zynq/ps7_init.c, if it exists. + * board/xilinx/zynq/ps7_init_gpl.c, if it exists. */ } diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/mach-zynq/timer.c index 303dbcf..5ed9642 100644 --- a/arch/arm/cpu/armv7/zynq/timer.c +++ b/arch/arm/mach-zynq/timer.c @@ -93,7 +93,9 @@ ulong get_timer_masked(void) gd->arch.tbl += gd->arch.lastinc - now; } else { /* We have an overflow ... */ - gd->arch.tbl += gd->arch.lastinc + TIMER_LOAD_VAL - now + 1; + gd->arch.tbl += gd->arch.lastinc + (TIMER_LOAD_VAL / + (gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) - + now + 1; } gd->arch.lastinc = now; diff --git a/arch/arm/cpu/armv7/zynq/u-boot-spl.lds b/arch/arm/mach-zynq/u-boot-spl.lds index 0f2f756..0f2f756 100644 --- a/arch/arm/cpu/armv7/zynq/u-boot-spl.lds +++ b/arch/arm/mach-zynq/u-boot-spl.lds diff --git a/arch/arm/cpu/armv7/zynq/u-boot.lds b/arch/arm/mach-zynq/u-boot.lds index 4dc9bb0..4dc9bb0 100644 --- a/arch/arm/cpu/armv7/zynq/u-boot.lds +++ b/arch/arm/mach-zynq/u-boot.lds diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index 99aa96e..aacfcbf 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -244,7 +244,7 @@ void board_init_r(gd_t *new_gd, ulong dest_addr) #endif #if defined(CONFIG_CMD_NET) puts("Net: "); - eth_initialize(gd->bd); + eth_initialize(); #endif #ifdef CONFIG_GENERIC_ATMEL_MCI diff --git a/arch/m68k/cpu/u-boot.lds b/arch/m68k/cpu/u-boot.lds new file mode 100644 index 0000000..d8dc715 --- /dev/null +++ b/arch/m68k/cpu/u-boot.lds @@ -0,0 +1,91 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * (C) Copyright 2015 + * Angelo Dureghello, Sysam Firmware, angelo@sysam.it + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> + +OUTPUT_ARCH(m68k) + +#ifndef LDS_BOARD_TEXT +#define LDS_BOARD_TEXT +#endif + +SECTIONS +{ + .text : + { + CPUDIR/start.o (.text*) + LDS_BOARD_TEXT + + *(.text*) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + + .reloc : + { + __got_start = .; + KEEP(*(.got)) + __got_end = .; + _GOT2_TABLE_ = .; + KEEP(*(.got2)) + _FIXUP_TABLE_ = .; + KEEP(*(.fixup)) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data*) + *(.sdata*) + } + _edata = .; + PROVIDE (edata = .); + + . = .; + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss (NOLOAD) : + { + _sbss = .; + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } + __bss_end = . ; + PROVIDE (end = .); +} diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index bc4283d..b0a8a43 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -141,15 +141,12 @@ config MIPS_BOOT_ENV_LEGACY The address of the enviroment is stored in register $a2. config MIPS_BOOT_FDT - bool "Hand over a flattened device tree to Linux kernel (INCOMPLETE)" + bool "Hand over a flattened device tree to Linux kernel" default n help Enable this option if you want U-Boot to hand over a flattened - device tree to the kernel. - - Note: the final hand over to the kernel is not yet implemented. After - the community agreed on the MIPS boot interface for device trees, - the corresponding code will be added. + device tree to the kernel. According to UHI register $a0 will be set + to -2 and the FDT address is stored in $a1. endmenu diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index d9d8396..e289799 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -317,7 +317,11 @@ static void boot_jump_linux(bootm_headers_t *images) bootstage_report(); #endif - kernel(linux_argc, (ulong)linux_argv, (ulong)linux_env, linux_extra); + if (images->ft_len) + kernel(-2, (ulong)images->ft_addr, 0, 0); + else + kernel(linux_argc, (ulong)linux_argv, (ulong)linux_env, + linux_extra); } int do_bootm_linux(int flag, int argc, char * const argv[], diff --git a/arch/mips/mach-au1x00/au1x00_eth.c b/arch/mips/mach-au1x00/au1x00_eth.c index 39c5b6b..d6ebe07 100644 --- a/arch/mips/mach-au1x00/au1x00_eth.c +++ b/arch/mips/mach-au1x00/au1x00_eth.c @@ -187,13 +187,14 @@ static int au1x00_recv(struct eth_device* dev){ if(status&RX_ERROR){ printf("Rx error 0x%x\n", status); - } - else{ + } else { /* Pass the packet up to the protocol layers. */ - NetReceive(NetRxPackets[next_rx], length - 4); + net_process_received_packet(net_rx_packets[next_rx], + length - 4); } - fifo_rx[next_rx].addr = (virt_to_phys(NetRxPackets[next_rx]))|RX_DMA_ENABLE; + fifo_rx[next_rx].addr = + (virt_to_phys(net_rx_packets[next_rx])) | RX_DMA_ENABLE; next_rx++; if(next_rx>=NO_OF_FIFOS){ @@ -234,11 +235,12 @@ static int au1x00_init(struct eth_device* dev, bd_t * bd){ for(i=0;i<NO_OF_FIFOS;i++){ fifo_tx[i].len = 0; fifo_tx[i].addr = virt_to_phys(&txbuf[0]); - fifo_rx[i].addr = (virt_to_phys(NetRxPackets[i]))|RX_DMA_ENABLE; + fifo_rx[i].addr = (virt_to_phys(net_rx_packets[i])) | + RX_DMA_ENABLE; } /* Put mac addr in little endian */ -#define ea eth_get_dev()->enetaddr +#define ea eth_get_ethaddr() *mac_addr_high = (ea[5] << 8) | (ea[4] ) ; *mac_addr_low = (ea[3] << 24) | (ea[2] << 16) | (ea[1] << 8) | (ea[0] ) ; diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c index 4c06a48..24a09bc 100644 --- a/arch/nds32/lib/board.c +++ b/arch/nds32/lib/board.c @@ -383,7 +383,7 @@ void board_init_r(gd_t *id, ulong dest_addr) #if defined(CONFIG_CMD_NET) puts("Net: "); - eth_initialize(gd->bd); + eth_initialize(); #if defined(CONFIG_RESET_PHY_R) debug("Reset Ethernet PHY\n"); reset_phy(); diff --git a/arch/openrisc/lib/board.c b/arch/openrisc/lib/board.c index 2346685..c26cc8f 100644 --- a/arch/openrisc/lib/board.c +++ b/arch/openrisc/lib/board.c @@ -128,7 +128,7 @@ void board_init(void) #if defined(CONFIG_CMD_NET) puts("NET: "); - eth_initialize(bd); + eth_initialize(); #endif /* main_loop */ diff --git a/arch/powerpc/cpu/mpc8260/ether_fcc.c b/arch/powerpc/cpu/mpc8260/ether_fcc.c index f9f15b5..30ea3de 100644 --- a/arch/powerpc/cpu/mpc8260/ether_fcc.c +++ b/arch/powerpc/cpu/mpc8260/ether_fcc.c @@ -183,7 +183,7 @@ static int fec_recv(struct eth_device* dev) } else { /* Pass the packet up to the protocol layers. */ - NetReceive(NetRxPackets[rxIdx], length - 4); + net_process_received_packet(net_rx_packets[rxIdx], length - 4); } @@ -243,7 +243,7 @@ static int fec_init(struct eth_device* dev, bd_t *bis) { rtx.rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; rtx.rxbd[i].cbd_datlen = 0; - rtx.rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i]; + rtx.rxbd[i].cbd_bufaddr = (uint)net_rx_packets[i]; } rtx.rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; @@ -299,7 +299,7 @@ static int fec_init(struct eth_device* dev, bd_t *bis) * it unique by setting a few bits in the upper byte of the * non-static part of the address. */ -#define ea eth_get_dev()->enetaddr +#define ea eth_get_ethaddr() pram_ptr->fen_paddrh = (ea[5] << 8) + ea[4]; pram_ptr->fen_paddrm = (ea[3] << 8) + ea[2]; pram_ptr->fen_paddrl = (ea[1] << 8) + ea[0]; @@ -637,7 +637,7 @@ eth_loopback_test (void) puts ("FCC Ethernet External loopback test\n"); - eth_getenv_enetaddr("ethaddr", NetOurEther); + eth_getenv_enetaddr("ethaddr", net_ethaddr); /* * global initialisations for all FCC channels @@ -720,8 +720,8 @@ eth_loopback_test (void) bdp->cbd_sc = BD_ENET_TX_READY | BD_ENET_TX_PAD | \ BD_ENET_TX_LAST | BD_ENET_TX_TC; - memset ((void *)bp, patbytes[i], ELBT_BUFSZ); - NetSetEther (bp, NetBcastAddr, 0x8000); + memset((void *)bp, patbytes[i], ELBT_BUFSZ); + net_set_ether(bp, net_bcast_ethaddr, 0x8000); } ecp->txbd[ELBT_NTXBD - 1].cbd_sc |= BD_ENET_TX_WRAP; @@ -799,11 +799,9 @@ eth_loopback_test (void) * So, far we have only been given one Ethernet address. We use * the same address for all channels */ -#define ea NetOurEther - fpp->fen_paddrh = (ea[5] << 8) + ea[4]; - fpp->fen_paddrm = (ea[3] << 8) + ea[2]; - fpp->fen_paddrl = (ea[1] << 8) + ea[0]; -#undef ea + fpp->fen_paddrh = (net_ethaddr[5] << 8) + net_ethaddr[4]; + fpp->fen_paddrm = (net_ethaddr[3] << 8) + net_ethaddr[2]; + fpp->fen_paddrl = (net_ethaddr[1] << 8) + net_ethaddr[0]; fpp->fen_minflr = PKT_MINBUF_SIZE; /* min frame len register */ /* @@ -1016,7 +1014,7 @@ eth_loopback_test (void) &ecp->rxbufs[i][0]; ours = memcmp (ehp->et_src, \ - NetOurEther, 6); + net_ethaddr, 6); prot = swap16 (ehp->et_protlen); tb = prot & 0x8000; diff --git a/arch/powerpc/cpu/mpc8260/ether_scc.c b/arch/powerpc/cpu/mpc8260/ether_scc.c index c988def..5ba8bed 100644 --- a/arch/powerpc/cpu/mpc8260/ether_scc.c +++ b/arch/powerpc/cpu/mpc8260/ether_scc.c @@ -146,7 +146,7 @@ static int sec_rx(struct eth_device *dev) else { /* Pass the packet up to the protocol layers. */ - NetReceive(NetRxPackets[rxIdx], length - 4); + net_process_received_packet(net_rx_packets[rxIdx], length - 4); } @@ -263,7 +263,7 @@ static int sec_init(struct eth_device *dev, bd_t *bis) { rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; rtx->rxbd[i].cbd_datlen = 0; /* Reset */ - rtx->rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i]; + rtx->rxbd[i].cbd_bufaddr = (uint)net_rx_packets[i]; } rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; diff --git a/arch/powerpc/cpu/mpc83xx/Kconfig b/arch/powerpc/cpu/mpc83xx/Kconfig index 4d6cb09..88a3bd6 100644 --- a/arch/powerpc/cpu/mpc83xx/Kconfig +++ b/arch/powerpc/cpu/mpc83xx/Kconfig @@ -49,6 +49,7 @@ config TARGET_MPC837XERDB config TARGET_IDS8313 bool "Support ids8313" + select DM config TARGET_KM8360 bool "Support km8360" diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c index 5ca9bf5..235a635 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c @@ -15,7 +15,7 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_A003399_NOR_WORKAROUND void setup_ifc(void) { - struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR; + struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL}; u32 _mas0, _mas1, _mas2, _mas3, _mas7; phys_addr_t flash_phys = CONFIG_SYS_FLASH_BASE_PHYS; @@ -70,9 +70,9 @@ void setup_ifc(void) #endif /* Change flash's physical address */ - ifc_out32(&(ifc_regs->cspr_cs[0].cspr), CONFIG_SYS_CSPR0); - ifc_out32(&(ifc_regs->csor_cs[0].csor), CONFIG_SYS_CSOR0); - ifc_out32(&(ifc_regs->amask_cs[0].amask), CONFIG_SYS_AMASK0); + ifc_out32(&(ifc_regs.gregs->cspr_cs[0].cspr), CONFIG_SYS_CSPR0); + ifc_out32(&(ifc_regs.gregs->csor_cs[0].csor), CONFIG_SYS_CSOR0); + ifc_out32(&(ifc_regs.gregs->amask_cs[0].amask), CONFIG_SYS_AMASK0); return ; } diff --git a/arch/powerpc/cpu/mpc85xx/ether_fcc.c b/arch/powerpc/cpu/mpc85xx/ether_fcc.c index 166dc9e..14358ae 100644 --- a/arch/powerpc/cpu/mpc85xx/ether_fcc.c +++ b/arch/powerpc/cpu/mpc85xx/ether_fcc.c @@ -186,7 +186,7 @@ static int fec_recv(struct eth_device* dev) } else { /* Pass the packet up to the protocol layers. */ - NetReceive(NetRxPackets[rxIdx], length - 4); + net_process_received_packet(net_rx_packets[rxIdx], length - 4); } @@ -263,7 +263,7 @@ static int fec_init(struct eth_device* dev, bd_t *bis) { rtx.rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; rtx.rxbd[i].cbd_datlen = 0; - rtx.rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i]; + rtx.rxbd[i].cbd_bufaddr = (uint)net_rx_packets[i]; } rtx.rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; @@ -338,7 +338,7 @@ static int fec_init(struct eth_device* dev, bd_t *bis) * it unique by setting a few bits in the upper byte of the * non-static part of the address. */ -#define ea eth_get_dev()->enetaddr +#define ea eth_get_ethaddr() pram_ptr->fen_paddrh = (ea[5] << 8) + ea[4]; pram_ptr->fen_paddrm = (ea[3] << 8) + ea[2]; pram_ptr->fen_paddrl = (ea[1] << 8) + ea[0]; diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index e24b857..321ade2 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -28,7 +28,7 @@ void get_sys_info(sys_info_t *sys_info) { volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); #ifdef CONFIG_FSL_IFC - struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR; + struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL}; u32 ccr; #endif #ifdef CONFIG_FSL_CORENET @@ -597,7 +597,7 @@ void get_sys_info(sys_info_t *sys_info) #endif #if defined(CONFIG_FSL_IFC) - ccr = ifc_in32(&ifc_regs->ifc_ccr); + ccr = ifc_in32(&ifc_regs.gregs->ifc_ccr); ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1; sys_info->freq_localbus = sys_info->freq_systembus / ccr; diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index d8c9fb6..28f04ee 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -252,39 +252,36 @@ l2_disabled: lis r1,CONFIG_SYS_MONITOR_BASE@h mtspr IVPR,r1 - lis r3,(CONFIG_SYS_MONITOR_BASE & 0xffff)@h - ori r3,r3,(CONFIG_SYS_MONITOR_BASE & 0xffff)@l - - addi r4,r3,CriticalInput - _start + _START_OFFSET + li r4,CriticalInput@l mtspr IVOR0,r4 /* 0: Critical input */ - addi r4,r3,MachineCheck - _start + _START_OFFSET + li r4,MachineCheck@l mtspr IVOR1,r4 /* 1: Machine check */ - addi r4,r3,DataStorage - _start + _START_OFFSET + li r4,DataStorage@l mtspr IVOR2,r4 /* 2: Data storage */ - addi r4,r3,InstStorage - _start + _START_OFFSET + li r4,InstStorage@l mtspr IVOR3,r4 /* 3: Instruction storage */ - addi r4,r3,ExtInterrupt - _start + _START_OFFSET + li r4,ExtInterrupt@l mtspr IVOR4,r4 /* 4: External interrupt */ - addi r4,r3,Alignment - _start + _START_OFFSET + li r4,Alignment@l mtspr IVOR5,r4 /* 5: Alignment */ - addi r4,r3,ProgramCheck - _start + _START_OFFSET + li r4,ProgramCheck@l mtspr IVOR6,r4 /* 6: Program check */ - addi r4,r3,FPUnavailable - _start + _START_OFFSET + li r4,FPUnavailable@l mtspr IVOR7,r4 /* 7: floating point unavailable */ - addi r4,r3,SystemCall - _start + _START_OFFSET + li r4,SystemCall@l mtspr IVOR8,r4 /* 8: System call */ /* 9: Auxiliary processor unavailable(unsupported) */ - addi r4,r3,Decrementer - _start + _START_OFFSET + li r4,Decrementer@l mtspr IVOR10,r4 /* 10: Decrementer */ - addi r4,r3,IntervalTimer - _start + _START_OFFSET + li r4,IntervalTimer@l mtspr IVOR11,r4 /* 11: Interval timer */ - addi r4,r3,WatchdogTimer - _start + _START_OFFSET + li r4,WatchdogTimer@l mtspr IVOR12,r4 /* 12: Watchdog timer */ - addi r4,r3,DataTLBError - _start + _START_OFFSET + li r4,DataTLBError@l mtspr IVOR13,r4 /* 13: Data TLB error */ - addi r4,r3,InstructionTLBError - _start + _START_OFFSET + li r4,InstructionTLBError@l mtspr IVOR14,r4 /* 14: Instruction TLB error */ - addi r4,r3,DebugBreakpoint - _start + _START_OFFSET + li r4,DebugBreakpoint@l mtspr IVOR15,r4 /* 15: Debug */ #endif @@ -1121,7 +1118,7 @@ switch_as: /*--------------------------------------------------------------*/ lis r3,CONFIG_SYS_MONITOR_BASE@h ori r3,r3,CONFIG_SYS_MONITOR_BASE@l - addi r3,r3,_start_cont - _start + _START_OFFSET + addi r3,r3,_start_cont - _start mtlr r3 blr #endif @@ -1165,7 +1162,6 @@ _start_cont: /* NOTREACHED - board_init_f() does not return */ #ifndef MINIMAL_SPL - . = EXC_OFF_SYS_RESET .globl _start_of_vectors _start_of_vectors: @@ -1185,7 +1181,6 @@ _start_of_vectors: STD_EXCEPTION(0x0500, ExtInterrupt, ExtIntException) /* Alignment exception. */ - . = 0x0600 Alignment: EXCEPTION_PROLOG(SRR0, SRR1) mfspr r4,DAR @@ -1193,87 +1188,20 @@ Alignment: mfspr r5,DSISR stw r5,_DSISR(r21) addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE) + EXC_XFER_TEMPLATE(0x600, Alignment, AlignmentException, + MSR_KERNEL, COPY_EE) /* Program check exception */ - . = 0x0700 ProgramCheck: EXCEPTION_PROLOG(SRR0, SRR1) addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException, + EXC_XFER_TEMPLATE(0x700, ProgramCheck, ProgramCheckException, MSR_KERNEL, COPY_EE) /* No FPU on MPC85xx. This exception is not supposed to happen. */ STD_EXCEPTION(0x0800, FPUnavailable, UnknownException) - - . = 0x0900 -/* - * r0 - SYSCALL number - * r3-... arguments - */ -SystemCall: - addis r11,r0,0 /* get functions table addr */ - ori r11,r11,0 /* Note: this code is patched in trap_init */ - addis r12,r0,0 /* get number of functions */ - ori r12,r12,0 - - cmplw 0,r0,r12 - bge 1f - - rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */ - add r11,r11,r0 - lwz r11,0(r11) - - li r20,0xd00-4 /* Get stack pointer */ - lwz r12,0(r20) - subi r12,r12,12 /* Adjust stack pointer */ - li r0,0xc00+_end_back-SystemCall - cmplw 0,r0,r12 /* Check stack overflow */ - bgt 1f - stw r12,0(r20) - - mflr r0 - stw r0,0(r12) - mfspr r0,SRR0 - stw r0,4(r12) - mfspr r0,SRR1 - stw r0,8(r12) - - li r12,0xc00+_back-SystemCall - mtlr r12 - mtspr SRR0,r11 - -1: SYNC - rfi -_back: - - mfmsr r11 /* Disable interrupts */ - li r12,0 - ori r12,r12,MSR_EE - andc r11,r11,r12 - SYNC /* Some chip revs need this... */ - mtmsr r11 - SYNC - - li r12,0xd00-4 /* restore regs */ - lwz r12,0(r12) - - lwz r11,0(r12) - mtlr r11 - lwz r11,4(r12) - mtspr SRR0,r11 - lwz r11,8(r12) - mtspr SRR1,r11 - - addi r12,r12,12 /* Adjust stack pointer */ - li r20,0xd00-4 - stw r12,0(r20) - - SYNC - rfi -_end_back: - + STD_EXCEPTION(0x0900, SystemCall, UnknownException) STD_EXCEPTION(0x0a00, Decrementer, timer_interrupt) STD_EXCEPTION(0x0b00, IntervalTimer, UnknownException) STD_EXCEPTION(0x0c00, WatchdogTimer, UnknownException) @@ -1293,32 +1221,22 @@ _end_of_vectors: * This code finishes saving the registers to the exception frame * and jumps to the appropriate handler for the exception. * Register r21 is pointer into trap frame, r1 has new stack pointer. + * r23 is the address of the handler. */ .globl transfer_to_handler transfer_to_handler: - stw r22,_NIP(r21) - lis r22,MSR_POW@h - andc r23,r23,r22 - stw r23,_MSR(r21) SAVE_GPR(7, r21) SAVE_4GPRS(8, r21) SAVE_8GPRS(12, r21) SAVE_8GPRS(24, r21) - mflr r23 - andi. r24,r23,0x3f00 /* get vector offset */ - stw r24,TRAP(r21) li r22,0 stw r22,RESULT(r21) mtspr SPRG2,r22 /* r1 is now kernel sp */ - lwz r24,0(r23) /* virtual address of handler */ - lwz r23,4(r23) /* where to go when done */ - mtspr SRR0,r24 - mtspr SRR1,r20 - mtlr r23 - SYNC - rfi /* jump to handler, enable MMU */ + mtctr r23 /* virtual address of handler */ + mtmsr r20 + bctrl int_return: mfmsr r28 /* Disable interrupts */ @@ -1350,66 +1268,6 @@ int_return: SYNC rfi -crit_return: - mfmsr r28 /* Disable interrupts */ - li r4,0 - ori r4,r4,MSR_EE - andc r28,r28,r4 - SYNC /* Some chip revs need this... */ - mtmsr r28 - SYNC - lwz r2,_CTR(r1) - lwz r0,_LINK(r1) - mtctr r2 - mtlr r0 - lwz r2,_XER(r1) - lwz r0,_CCR(r1) - mtspr XER,r2 - mtcrf 0xFF,r0 - REST_10GPRS(3, r1) - REST_10GPRS(13, r1) - REST_8GPRS(23, r1) - REST_GPR(31, r1) - lwz r2,_NIP(r1) /* Restore environment */ - lwz r0,_MSR(r1) - mtspr SPRN_CSRR0,r2 - mtspr SPRN_CSRR1,r0 - lwz r0,GPR0(r1) - lwz r2,GPR2(r1) - lwz r1,GPR1(r1) - SYNC - rfci - -mck_return: - mfmsr r28 /* Disable interrupts */ - li r4,0 - ori r4,r4,MSR_EE - andc r28,r28,r4 - SYNC /* Some chip revs need this... */ - mtmsr r28 - SYNC - lwz r2,_CTR(r1) - lwz r0,_LINK(r1) - mtctr r2 - mtlr r0 - lwz r2,_XER(r1) - lwz r0,_CCR(r1) - mtspr XER,r2 - mtcrf 0xFF,r0 - REST_10GPRS(3, r1) - REST_10GPRS(13, r1) - REST_8GPRS(23, r1) - REST_GPR(31, r1) - lwz r2,_NIP(r1) /* Restore environment */ - lwz r0,_MSR(r1) - mtspr SPRN_MCSRR0,r2 - mtspr SPRN_MCSRR1,r0 - lwz r0,GPR0(r1) - lwz r2,GPR2(r1) - lwz r1,GPR1(r1) - SYNC - rfmci - /* Cache functions. */ .globl flush_icache @@ -1494,11 +1352,6 @@ dcache_status: andi. r3,r3,L1CSR0_DCE blr - .globl get_pir -get_pir: - mfspr r3,PIR - blr - .globl get_pvr get_pvr: mfspr r3,PVR @@ -1509,11 +1362,6 @@ get_svr: mfspr r3,SVR blr - .globl wr_tcr -wr_tcr: - mtspr TCR,r3 - blr - /*------------------------------------------------------------------------------- */ /* Function: in8 */ /* Description: Input 8 bits */ @@ -1728,7 +1576,7 @@ relocate_code: * initialization, now running from RAM. */ - addi r0,r10,in_ram - _start + _START_OFFSET + addi r0,r10,in_ram - _start /* * As IVPR is going to point RAM address, @@ -1816,89 +1664,41 @@ clear_bss: */ .globl trap_init trap_init: - mflr r4 /* save link register */ - GET_GOT - lwz r7,GOT(_start_of_vectors) - lwz r8,GOT(_end_of_vectors) - - li r9,0x100 /* reset vector always at 0x100 */ - - cmplw 0,r7,r8 - bgelr /* return if r7>=r8 - just in case */ -1: - lwz r0,0(r7) - stw r0,0(r9) - addi r7,r7,4 - addi r9,r9,4 - cmplw 0,r7,r8 - bne 1b + /* Update IVORs as per relocation */ + mtspr IVPR,r3 - /* - * relocate `hdlr' and `int_return' entries - */ - li r7,.L_CriticalInput - _start + _START_OFFSET - bl trap_reloc - li r7,.L_MachineCheck - _start + _START_OFFSET - bl trap_reloc - li r7,.L_DataStorage - _start + _START_OFFSET - bl trap_reloc - li r7,.L_InstStorage - _start + _START_OFFSET - bl trap_reloc - li r7,.L_ExtInterrupt - _start + _START_OFFSET - bl trap_reloc - li r7,.L_Alignment - _start + _START_OFFSET - bl trap_reloc - li r7,.L_ProgramCheck - _start + _START_OFFSET - bl trap_reloc - li r7,.L_FPUnavailable - _start + _START_OFFSET - bl trap_reloc - li r7,.L_Decrementer - _start + _START_OFFSET - bl trap_reloc - li r7,.L_IntervalTimer - _start + _START_OFFSET - li r8,_end_of_vectors - _start + _START_OFFSET -2: - bl trap_reloc - addi r7,r7,0x100 /* next exception vector */ - cmplw 0,r7,r8 - blt 2b - - /* Update IVORs as per relocated vector table address */ - li r7,0x0100 - mtspr IVOR0,r7 /* 0: Critical input */ - li r7,0x0200 - mtspr IVOR1,r7 /* 1: Machine check */ - li r7,0x0300 - mtspr IVOR2,r7 /* 2: Data storage */ - li r7,0x0400 - mtspr IVOR3,r7 /* 3: Instruction storage */ - li r7,0x0500 - mtspr IVOR4,r7 /* 4: External interrupt */ - li r7,0x0600 - mtspr IVOR5,r7 /* 5: Alignment */ - li r7,0x0700 - mtspr IVOR6,r7 /* 6: Program check */ - li r7,0x0800 - mtspr IVOR7,r7 /* 7: floating point unavailable */ - li r7,0x0900 - mtspr IVOR8,r7 /* 8: System call */ + li r4,CriticalInput@l + mtspr IVOR0,r4 /* 0: Critical input */ + li r4,MachineCheck@l + mtspr IVOR1,r4 /* 1: Machine check */ + li r4,DataStorage@l + mtspr IVOR2,r4 /* 2: Data storage */ + li r4,InstStorage@l + mtspr IVOR3,r4 /* 3: Instruction storage */ + li r4,ExtInterrupt@l + mtspr IVOR4,r4 /* 4: External interrupt */ + li r4,Alignment@l + mtspr IVOR5,r4 /* 5: Alignment */ + li r4,ProgramCheck@l + mtspr IVOR6,r4 /* 6: Program check */ + li r4,FPUnavailable@l + mtspr IVOR7,r4 /* 7: floating point unavailable */ + li r4,SystemCall@l + mtspr IVOR8,r4 /* 8: System call */ /* 9: Auxiliary processor unavailable(unsupported) */ - li r7,0x0a00 - mtspr IVOR10,r7 /* 10: Decrementer */ - li r7,0x0b00 - mtspr IVOR11,r7 /* 11: Interval timer */ - li r7,0x0c00 - mtspr IVOR12,r7 /* 12: Watchdog timer */ - li r7,0x0d00 - mtspr IVOR13,r7 /* 13: Data TLB error */ - li r7,0x0e00 - mtspr IVOR14,r7 /* 14: Instruction TLB error */ - li r7,0x0f00 - mtspr IVOR15,r7 /* 15: Debug */ - - lis r7,0x0 - mtspr IVPR,r7 - - mtlr r4 /* restore link register */ + li r4,Decrementer@l + mtspr IVOR10,r4 /* 10: Decrementer */ + li r4,IntervalTimer@l + mtspr IVOR11,r4 /* 11: Interval timer */ + li r4,WatchdogTimer@l + mtspr IVOR12,r4 /* 12: Watchdog timer */ + li r4,DataTLBError@l + mtspr IVOR13,r4 /* 13: Data TLB error */ + li r4,InstructionTLBError@l + mtspr IVOR14,r4 /* 14: Instruction TLB error */ + li r4,DebugBreakpoint@l + mtspr IVOR15,r4 /* 15: Debug */ + blr .globl unlock_ram_in_cache diff --git a/arch/powerpc/cpu/mpc8xx/fec.c b/arch/powerpc/cpu/mpc8xx/fec.c index 22b8ec7..2e19603 100644 --- a/arch/powerpc/cpu/mpc8xx/fec.c +++ b/arch/powerpc/cpu/mpc8xx/fec.c @@ -247,21 +247,21 @@ static int fec_recv (struct eth_device *dev) rtx->rxbd[rxIdx].cbd_sc); #endif } else { - uchar *rx = NetRxPackets[rxIdx]; + uchar *rx = net_rx_packets[rxIdx]; length -= 4; #if defined(CONFIG_CMD_CDP) - if ((rx[0] & 1) != 0 - && memcmp ((uchar *) rx, NetBcastAddr, 6) != 0 - && !is_cdp_packet((uchar *)rx)) + if ((rx[0] & 1) != 0 && + memcmp((uchar *)rx, net_bcast_ethaddr, 6) != 0 && + !is_cdp_packet((uchar *)rx)) rx = NULL; #endif /* * Pass the packet up to the protocol layers. */ if (rx != NULL) - NetReceive (rx, length); + net_process_received_packet(rx, length); } /* Give the buffer back to the FEC. */ @@ -576,7 +576,7 @@ static int fec_init (struct eth_device *dev, bd_t * bd) for (i = 0; i < PKTBUFSRX; i++) { rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; rtx->rxbd[i].cbd_datlen = 0; /* Reset */ - rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i]; + rtx->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i]; } rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; diff --git a/arch/powerpc/cpu/mpc8xx/scc.c b/arch/powerpc/cpu/mpc8xx/scc.c index 251966b..5498440 100644 --- a/arch/powerpc/cpu/mpc8xx/scc.c +++ b/arch/powerpc/cpu/mpc8xx/scc.c @@ -159,7 +159,8 @@ static int scc_recv (struct eth_device *dev) #endif } else { /* Pass the packet up to the protocol layers. */ - NetReceive (NetRxPackets[rxIdx], length - 4); + net_process_received_packet(net_rx_packets[rxIdx], + length - 4); } @@ -280,7 +281,7 @@ static int scc_init (struct eth_device *dev, bd_t * bis) for (i = 0; i < PKTBUFSRX; i++) { rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; rtx->rxbd[i].cbd_datlen = 0; /* Reset */ - rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i]; + rtx->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i]; } rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; @@ -339,7 +340,7 @@ static int scc_init (struct eth_device *dev, bd_t * bis) pram_ptr->sen_gaddr3 = 0x0; /* Group Address Filter 3 (unused) */ pram_ptr->sen_gaddr4 = 0x0; /* Group Address Filter 4 (unused) */ -#define ea eth_get_dev()->enetaddr +#define ea eth_get_ethaddr() pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4]; pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2]; pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0]; diff --git a/arch/powerpc/cpu/ppc4xx/Kconfig b/arch/powerpc/cpu/ppc4xx/Kconfig index 9e52d3f..89cb3e9 100644 --- a/arch/powerpc/cpu/ppc4xx/Kconfig +++ b/arch/powerpc/cpu/ppc4xx/Kconfig @@ -43,6 +43,8 @@ config TARGET_BUBINGA config TARGET_CANYONLANDS bool "Support canyonlands" + select DM + select DM_SERIAL config TARGET_EBONY bool "Support ebony" diff --git a/arch/powerpc/include/asm/fsl_errata.h b/arch/powerpc/include/asm/fsl_errata.h index 61c6d70..4861e3bf 100644 --- a/arch/powerpc/include/asm/fsl_errata.h +++ b/arch/powerpc/include/asm/fsl_errata.h @@ -45,7 +45,7 @@ static inline bool has_erratum_a007186(void) return IS_SVR_REV(svr, 2, 0); case SVR_T2081: case SVR_T2080: - return IS_SVR_REV(svr, 1, 0); + return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 1, 1); } return false; diff --git a/arch/powerpc/include/asm/fsl_secure_boot.h b/arch/powerpc/include/asm/fsl_secure_boot.h index 49f6814..8f794ef 100644 --- a/arch/powerpc/include/asm/fsl_secure_boot.h +++ b/arch/powerpc/include/asm/fsl_secure_boot.h @@ -67,5 +67,24 @@ #define CONFIG_FSL_ISBC_KEY_EXT #endif +#ifndef CONFIG_FIT_SIGNATURE +/* The bootscript header address is different for B4860 because the NOR + * mapping is different on B4 due to reduced NOR size. + */ +#if defined(CONFIG_B4860QDS) +#define CONFIG_BOOTSCRIPT_HDR_ADDR 0xecc00000 +#elif defined(CONFIG_FSL_CORENET) +#define CONFIG_BOOTSCRIPT_HDR_ADDR 0xe8e00000 +#elif defined(CONFIG_BSC9132QDS) +#define CONFIG_BOOTSCRIPT_HDR_ADDR 0x88020000 +#elif defined(CONFIG_C29XPCIE) +#define CONFIG_BOOTSCRIPT_HDR_ADDR 0xec020000 +#else +#define CONFIG_BOOTSCRIPT_HDR_ADDR 0xee020000 +#endif + +#include <config_fsl_secboot.h> +#endif + #endif #endif diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index 91645d3..5ea29cc 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -890,7 +890,7 @@ void board_init_r(gd_t *id, ulong dest_addr) #if defined(CONFIG_CMD_NET) WATCHDOG_RESET(); puts("Net: "); - eth_initialize(bd); + eth_initialize(); #endif #if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R) diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig index 2098b9c..8aac96f 100644 --- a/arch/sandbox/Kconfig +++ b/arch/sandbox/Kconfig @@ -10,28 +10,26 @@ config SYS_BOARD config SYS_CONFIG_NAME default "sandbox" -config DM - default y - -config DM_GPIO - default y - -config DM_SERIAL +config DM_TEST default y -config DM_CROS_EC - default y +config PCI + bool "PCI support" + help + Enable support for PCI (Peripheral Interconnect Bus), a type of bus + used on some devices to allow the CPU to communicate with its + peripherals. -config DM_SPI +config NET default y -config DM_SPI_FLASH +config NETDEVICES default y -config DM_I2C +config DM_ETH default y -config DM_TEST +config ETH_SANDBOX_RAW default y endmenu diff --git a/arch/sandbox/cpu/Makefile b/arch/sandbox/cpu/Makefile index 7d4410c..1b42fee 100644 --- a/arch/sandbox/cpu/Makefile +++ b/arch/sandbox/cpu/Makefile @@ -8,6 +8,7 @@ # obj-y := cpu.o os.o start.o state.o +obj-$(CONFIG_ETH_SANDBOX_RAW) += eth-raw-os.o obj-$(CONFIG_SANDBOX_SDL) += sdl.o # os.c is build in the system environment, so needs standard includes @@ -20,3 +21,12 @@ $(obj)/os.o: $(src)/os.c FORCE $(call if_changed_dep,cc_os.o) $(obj)/sdl.o: $(src)/sdl.c FORCE $(call if_changed_dep,cc_os.o) + +# eth-raw-os.c is built in the system env, so needs standard includes +# CFLAGS_REMOVE_eth-raw-os.o cannot be used to drop header include path +quiet_cmd_cc_eth-raw-os.o = CC $(quiet_modtag) $@ +cmd_cc_eth-raw-os.o = $(CC) $(filter-out -nostdinc, \ + $(patsubst -I%,-idirafter%,$(c_flags))) -c -o $@ $< + +$(obj)/eth-raw-os.o: $(src)/eth-raw-os.c FORCE + $(call if_changed_dep,cc_eth-raw-os.o) diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index 1aa397c..168f2ef 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -2,14 +2,24 @@ * Copyright (c) 2011 The Chromium OS Authors. * SPDX-License-Identifier: GPL-2.0+ */ - +#define DEBUG #include <common.h> #include <dm/root.h> #include <os.h> +#include <asm/io.h> #include <asm/state.h> DECLARE_GLOBAL_DATA_PTR; +/* Enable access to PCI memory with map_sysmem() */ +static bool enable_pci_map; + +#ifdef CONFIG_PCI +/* Last device that was mapped into memory, and length of mapping */ +static struct udevice *map_dev; +unsigned long map_len; +#endif + void reset_cpu(ulong ignored) { if (state_uninit()) @@ -40,26 +50,44 @@ unsigned long __attribute__((no_instrument_function)) timer_get_us(void) return os_get_nsec() / 1000; } -int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +int cleanup_before_linux(void) { - if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { - bootstage_mark(BOOTSTAGE_ID_RUN_OS); - printf("## Transferring control to Linux (at address %08lx)...\n", - images->ep); - reset_cpu(0); + return 0; +} + +void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) +{ +#ifdef CONFIG_PCI + unsigned long plen = len; + void *ptr; + + map_dev = NULL; + if (enable_pci_map && !pci_map_physmem(paddr, &len, &map_dev, &ptr)) { + if (plen != len) { + printf("%s: Warning: partial map at %x, wanted %lx, got %lx\n", + __func__, paddr, len, plen); + } + map_len = len; + return ptr; } +#endif - return 0; + return (void *)(gd->arch.ram_buf + paddr); } -int cleanup_before_linux(void) +void unmap_physmem(const void *vaddr, unsigned long flags) { - return 0; +#ifdef CONFIG_PCI + if (map_dev) { + pci_unmap_physmem(vaddr, map_len, map_dev); + map_dev = NULL; + } +#endif } -void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) +void sandbox_set_enable_pci_map(int enable) { - return (void *)(gd->arch.ram_buf + paddr); + enable_pci_map = enable; } phys_addr_t map_to_sysmem(const void *ptr) @@ -70,3 +98,43 @@ phys_addr_t map_to_sysmem(const void *ptr) void flush_dcache_range(unsigned long start, unsigned long stop) { } + +int sandbox_read_fdt_from_file(void) +{ + struct sandbox_state *state = state_get_current(); + const char *fname = state->fdt_fname; + void *blob; + loff_t size; + int err; + int fd; + + blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); + if (!state->fdt_fname) { + err = fdt_create_empty_tree(blob, 256); + if (!err) + goto done; + printf("Unable to create empty FDT: %s\n", fdt_strerror(err)); + return -EINVAL; + } + + err = os_get_filesize(fname, &size); + if (err < 0) { + printf("Failed to file FDT file '%s'\n", fname); + return err; + } + fd = os_open(fname, OS_O_RDONLY); + if (fd < 0) { + printf("Failed to open FDT file '%s'\n", fname); + return -EACCES; + } + if (os_read(fd, blob, size) != size) { + os_close(fd); + return -EIO; + } + os_close(fd); + +done: + gd->fdt_blob = blob; + + return 0; +} diff --git a/arch/sandbox/cpu/eth-raw-os.c b/arch/sandbox/cpu/eth-raw-os.c new file mode 100644 index 0000000..b76a731 --- /dev/null +++ b/arch/sandbox/cpu/eth-raw-os.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2015 National Instruments + * + * (C) Copyright 2015 + * Joe Hershberger <joe.hershberger@ni.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <asm/eth-raw-os.h> +#include <errno.h> +#include <fcntl.h> +#include <net/if.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/udp.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <unistd.h> + +#include <arpa/inet.h> +#include <linux/if_ether.h> +#include <linux/if_packet.h> + +static int _raw_packet_start(const char *ifname, unsigned char *ethmac, + struct eth_sandbox_raw_priv *priv) +{ + struct sockaddr_ll *device; + struct packet_mreq mr; + int ret; + int flags; + + /* Prepare device struct */ + priv->device = malloc(sizeof(struct sockaddr_ll)); + if (priv->device == NULL) + return -ENOMEM; + device = priv->device; + memset(device, 0, sizeof(struct sockaddr_ll)); + device->sll_ifindex = if_nametoindex(ifname); + device->sll_family = AF_PACKET; + memcpy(device->sll_addr, ethmac, 6); + device->sll_halen = htons(6); + + /* Open socket */ + priv->sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + if (priv->sd < 0) { + printf("Failed to open socket: %d %s\n", errno, + strerror(errno)); + return -errno; + } + /* Bind to the specified interface */ + ret = setsockopt(priv->sd, SOL_SOCKET, SO_BINDTODEVICE, ifname, + strlen(ifname) + 1); + if (ret < 0) { + printf("Failed to bind to '%s': %d %s\n", ifname, errno, + strerror(errno)); + return -errno; + } + + /* Make the socket non-blocking */ + flags = fcntl(priv->sd, F_GETFL, 0); + fcntl(priv->sd, F_SETFL, flags | O_NONBLOCK); + + /* Enable promiscuous mode to receive responses meant for us */ + mr.mr_ifindex = device->sll_ifindex; + mr.mr_type = PACKET_MR_PROMISC; + ret = setsockopt(priv->sd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, + &mr, sizeof(mr)); + if (ret < 0) { + struct ifreq ifr; + + printf("Failed to set promiscuous mode: %d %s\n" + "Falling back to the old \"flags\" way...\n", + errno, strerror(errno)); + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + if (ioctl(priv->sd, SIOCGIFFLAGS, &ifr) < 0) { + printf("Failed to read flags: %d %s\n", errno, + strerror(errno)); + return -errno; + } + ifr.ifr_flags |= IFF_PROMISC; + if (ioctl(priv->sd, SIOCSIFFLAGS, &ifr) < 0) { + printf("Failed to write flags: %d %s\n", errno, + strerror(errno)); + return -errno; + } + } + return 0; +} + +static int _local_inet_start(struct eth_sandbox_raw_priv *priv) +{ + struct sockaddr_in *device; + int ret; + int flags; + int one = 1; + + /* Prepare device struct */ + priv->device = malloc(sizeof(struct sockaddr_in)); + if (priv->device == NULL) + return -ENOMEM; + device = priv->device; + memset(device, 0, sizeof(struct sockaddr_in)); + device->sin_family = AF_INET; + device->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + /** + * Open socket + * Since we specify UDP here, any incoming ICMP packets will + * not be received, so things like ping will not work on this + * localhost interface. + */ + priv->sd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP); + if (priv->sd < 0) { + printf("Failed to open socket: %d %s\n", errno, + strerror(errno)); + return -errno; + } + + /* Make the socket non-blocking */ + flags = fcntl(priv->sd, F_GETFL, 0); + fcntl(priv->sd, F_SETFL, flags | O_NONBLOCK); + + /* Include the UDP/IP headers on send and receive */ + ret = setsockopt(priv->sd, IPPROTO_IP, IP_HDRINCL, &one, + sizeof(one)); + if (ret < 0) { + printf("Failed to set header include option: %d %s\n", errno, + strerror(errno)); + return -errno; + } + priv->local_bind_sd = -1; + priv->local_bind_udp_port = 0; + return 0; +} + +int sandbox_eth_raw_os_start(const char *ifname, unsigned char *ethmac, + struct eth_sandbox_raw_priv *priv) +{ + if (priv->local) + return _local_inet_start(priv); + else + return _raw_packet_start(ifname, ethmac, priv); +} + +int sandbox_eth_raw_os_send(void *packet, int length, + struct eth_sandbox_raw_priv *priv) +{ + int retval; + struct udphdr *udph = packet + sizeof(struct iphdr); + + if (!priv->sd || !priv->device) + return -EINVAL; + + /* + * This block of code came about when testing tftp on the localhost + * interface. When using the RAW AF_INET API, the network stack is still + * in play responding to incoming traffic based on open "ports". Since + * it is raw (at the IP layer, no Ethernet) the network stack tells the + * TFTP server that the port it responded to is closed. This causes the + * TFTP transfer to be aborted. This block of code inspects the outgoing + * packet as formulated by the u-boot network stack to determine the + * source port (that the TFTP server will send packets back to) and + * opens a typical UDP socket on that port, thus preventing the network + * stack from sending that ICMP message claiming that the port has no + * bound socket. + */ + if (priv->local && (priv->local_bind_sd == -1 || + priv->local_bind_udp_port != udph->source)) { + struct iphdr *iph = packet; + struct sockaddr_in addr; + + if (priv->local_bind_sd != -1) + close(priv->local_bind_sd); + + /* A normal UDP socket is required to bind */ + priv->local_bind_sd = socket(AF_INET, SOCK_DGRAM, 0); + if (priv->local_bind_sd < 0) { + printf("Failed to open bind sd: %d %s\n", errno, + strerror(errno)); + return -errno; + } + priv->local_bind_udp_port = udph->source; + + /** + * Bind the UDP port that we intend to use as our source port + * so that the kernel will not send an ICMP port unreachable + * message to the server + */ + addr.sin_family = AF_INET; + addr.sin_port = udph->source; + addr.sin_addr.s_addr = iph->saddr; + retval = bind(priv->local_bind_sd, &addr, sizeof(addr)); + if (retval < 0) + printf("Failed to bind: %d %s\n", errno, + strerror(errno)); + } + + retval = sendto(priv->sd, packet, length, 0, + (struct sockaddr *)priv->device, + sizeof(struct sockaddr_ll)); + if (retval < 0) { + printf("Failed to send packet: %d %s\n", errno, + strerror(errno)); + return -errno; + } + return retval; +} + +int sandbox_eth_raw_os_recv(void *packet, int *length, + const struct eth_sandbox_raw_priv *priv) +{ + int retval; + int saddr_size; + + if (!priv->sd || !priv->device) + return -EINVAL; + saddr_size = sizeof(struct sockaddr); + retval = recvfrom(priv->sd, packet, 1536, 0, + (struct sockaddr *)priv->device, + (socklen_t *)&saddr_size); + *length = 0; + if (retval >= 0) { + *length = retval; + return 0; + } + /* The socket is non-blocking, so expect EAGAIN when there is no data */ + if (errno == EAGAIN) + return 0; + return -errno; +} + +void sandbox_eth_raw_os_stop(struct eth_sandbox_raw_priv *priv) +{ + free(priv->device); + priv->device = NULL; + close(priv->sd); + priv->sd = -1; + if (priv->local) { + if (priv->local_bind_sd != -1) + close(priv->local_bind_sd); + priv->local_bind_sd = -1; + priv->local_bind_udp_port = 0; + } +} diff --git a/arch/sandbox/dts/cros-ec-keyboard.dtsi b/arch/sandbox/dts/cros-ec-keyboard.dtsi new file mode 100644 index 0000000..9c7fb0a --- /dev/null +++ b/arch/sandbox/dts/cros-ec-keyboard.dtsi @@ -0,0 +1,105 @@ +/* + * Keyboard dts fragment for devices that use cros-ec-keyboard + * + * Copyright (c) 2014 Google, 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 <dt-bindings/input/input.h> + +&cros_ec { + keyboard-controller { + compatible = "google,cros-ec-keyb"; + keypad,num-rows = <8>; + keypad,num-columns = <13>; + google,needs-ghost-filter; + + linux,keymap = < + MATRIX_KEY(0x00, 0x01, KEY_LEFTMETA) + MATRIX_KEY(0x00, 0x02, KEY_F1) + MATRIX_KEY(0x00, 0x03, KEY_B) + MATRIX_KEY(0x00, 0x04, KEY_F10) + MATRIX_KEY(0x00, 0x06, KEY_N) + MATRIX_KEY(0x00, 0x08, KEY_EQUAL) + MATRIX_KEY(0x00, 0x0a, KEY_RIGHTALT) + + MATRIX_KEY(0x01, 0x01, KEY_ESC) + MATRIX_KEY(0x01, 0x02, KEY_F4) + MATRIX_KEY(0x01, 0x03, KEY_G) + MATRIX_KEY(0x01, 0x04, KEY_F7) + MATRIX_KEY(0x01, 0x06, KEY_H) + MATRIX_KEY(0x01, 0x08, KEY_APOSTROPHE) + MATRIX_KEY(0x01, 0x09, KEY_F9) + MATRIX_KEY(0x01, 0x0b, KEY_BACKSPACE) + + MATRIX_KEY(0x02, 0x00, KEY_LEFTCTRL) + MATRIX_KEY(0x02, 0x01, KEY_TAB) + MATRIX_KEY(0x02, 0x02, KEY_F3) + MATRIX_KEY(0x02, 0x03, KEY_T) + MATRIX_KEY(0x02, 0x04, KEY_F6) + MATRIX_KEY(0x02, 0x05, KEY_RIGHTBRACE) + MATRIX_KEY(0x02, 0x06, KEY_Y) + MATRIX_KEY(0x02, 0x07, KEY_102ND) + MATRIX_KEY(0x02, 0x08, KEY_LEFTBRACE) + MATRIX_KEY(0x02, 0x09, KEY_F8) + + MATRIX_KEY(0x03, 0x01, KEY_GRAVE) + MATRIX_KEY(0x03, 0x02, KEY_F2) + MATRIX_KEY(0x03, 0x03, KEY_5) + MATRIX_KEY(0x03, 0x04, KEY_F5) + MATRIX_KEY(0x03, 0x06, KEY_6) + MATRIX_KEY(0x03, 0x08, KEY_MINUS) + MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH) + + MATRIX_KEY(0x04, 0x00, KEY_RIGHTCTRL) + MATRIX_KEY(0x04, 0x01, KEY_A) + MATRIX_KEY(0x04, 0x02, KEY_D) + MATRIX_KEY(0x04, 0x03, KEY_F) + MATRIX_KEY(0x04, 0x04, KEY_S) + MATRIX_KEY(0x04, 0x05, KEY_K) + MATRIX_KEY(0x04, 0x06, KEY_J) + MATRIX_KEY(0x04, 0x08, KEY_SEMICOLON) + MATRIX_KEY(0x04, 0x09, KEY_L) + MATRIX_KEY(0x04, 0x0a, KEY_BACKSLASH) + MATRIX_KEY(0x04, 0x0b, KEY_ENTER) + + MATRIX_KEY(0x05, 0x01, KEY_Z) + MATRIX_KEY(0x05, 0x02, KEY_C) + MATRIX_KEY(0x05, 0x03, KEY_V) + MATRIX_KEY(0x05, 0x04, KEY_X) + MATRIX_KEY(0x05, 0x05, KEY_COMMA) + MATRIX_KEY(0x05, 0x06, KEY_M) + MATRIX_KEY(0x05, 0x07, KEY_LEFTSHIFT) + MATRIX_KEY(0x05, 0x08, KEY_SLASH) + MATRIX_KEY(0x05, 0x09, KEY_DOT) + MATRIX_KEY(0x05, 0x0b, KEY_SPACE) + + MATRIX_KEY(0x06, 0x01, KEY_1) + MATRIX_KEY(0x06, 0x02, KEY_3) + MATRIX_KEY(0x06, 0x03, KEY_4) + MATRIX_KEY(0x06, 0x04, KEY_2) + MATRIX_KEY(0x06, 0x05, KEY_8) + MATRIX_KEY(0x06, 0x06, KEY_7) + MATRIX_KEY(0x06, 0x08, KEY_0) + MATRIX_KEY(0x06, 0x09, KEY_9) + MATRIX_KEY(0x06, 0x0a, KEY_LEFTALT) + MATRIX_KEY(0x06, 0x0b, KEY_DOWN) + MATRIX_KEY(0x06, 0x0c, KEY_RIGHT) + + MATRIX_KEY(0x07, 0x01, KEY_Q) + MATRIX_KEY(0x07, 0x02, KEY_E) + MATRIX_KEY(0x07, 0x03, KEY_R) + MATRIX_KEY(0x07, 0x04, KEY_W) + MATRIX_KEY(0x07, 0x05, KEY_I) + MATRIX_KEY(0x07, 0x06, KEY_U) + MATRIX_KEY(0x07, 0x07, KEY_RIGHTSHIFT) + MATRIX_KEY(0x07, 0x08, KEY_P) + MATRIX_KEY(0x07, 0x09, KEY_O) + MATRIX_KEY(0x07, 0x0b, KEY_UP) + MATRIX_KEY(0x07, 0x0c, KEY_LEFT) + >; + }; +}; diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts index 9ce31bf..efa2097 100644 --- a/arch/sandbox/dts/sandbox.dts +++ b/arch/sandbox/dts/sandbox.dts @@ -1,8 +1,15 @@ /dts-v1/; +#define USB_CLASS_HUB 9 + / { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; + + aliases { + eth5 = "/eth@90000000"; + pci0 = &pci; + }; chosen { stdout-path = "/serial"; @@ -32,36 +39,31 @@ sides = <6>; }; - host@0 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "sandbox,host-emulation"; - cros-ec@0 { - reg = <0>; - compatible = "google,cros-ec"; + cros_ec: cros-ec@0 { + reg = <0 0>; + compatible = "google,cros-ec-sandbox"; - /* - * This describes the flash memory within the EC. Note - * that the STM32L flash erases to 0, not 0xff. - */ + /* + * This describes the flash memory within the EC. Note + * that the STM32L flash erases to 0, not 0xff. + */ + #address-cells = <1>; + #size-cells = <1>; + flash@8000000 { + reg = <0x08000000 0x20000>; + erase-value = <0>; #address-cells = <1>; #size-cells = <1>; - flash@8000000 { - reg = <0x08000000 0x20000>; - erase-value = <0>; - #address-cells = <1>; - #size-cells = <1>; - /* Information for sandbox */ - ro { - reg = <0 0xf000>; - }; - wp-ro { - reg = <0xf000 0x1000>; - }; - rw { - reg = <0x10000 0x10000>; - }; + /* Information for sandbox */ + ro { + reg = <0 0xf000>; + }; + wp-ro { + reg = <0xf000 0x1000>; + }; + rw { + reg = <0x10000 0x10000>; }; }; }; @@ -72,59 +74,6 @@ yres = <600>; }; - cros-ec-keyb { - compatible = "google,cros-ec-keyb"; - keypad,num-rows = <8>; - keypad,num-columns = <13>; - google,ghost-filter; - /* - * Keymap entries take the form of 0xRRCCKKKK where - * RR=Row CC=Column KKKK=Key Code - * The values below are for a US keyboard layout and - * are taken from the Linux driver. Note that the - * 102ND key is not used for US keyboards. - */ - linux,keymap = < - /* CAPSLCK F1 B F10 */ - 0x0001003a 0x0002003b 0x00030030 0x00040044 - /* N = R_ALT ESC */ - 0x00060031 0x0008000d 0x000a0064 0x01010001 - /* F4 G F7 H */ - 0x0102003e 0x01030022 0x01040041 0x01060023 - /* ' F9 BKSPACE L_CTRL */ - 0x01080028 0x01090043 0x010b000e 0x0200001d - /* TAB F3 T F6 */ - 0x0201000f 0x0202003d 0x02030014 0x02040040 - /* ] Y 102ND [ */ - 0x0205001b 0x02060015 0x02070056 0x0208001a - /* F8 GRAVE F2 5 */ - 0x02090042 0x03010029 0x0302003c 0x03030006 - /* F5 6 - \ */ - 0x0304003f 0x03060007 0x0308000c 0x030b002b - /* R_CTRL A D F */ - 0x04000061 0x0401001e 0x04020020 0x04030021 - /* S K J ; */ - 0x0404001f 0x04050025 0x04060024 0x04080027 - /* L ENTER Z C */ - 0x04090026 0x040b001c 0x0501002c 0x0502002e - /* V X , M */ - 0x0503002f 0x0504002d 0x05050033 0x05060032 - /* L_SHIFT / . SPACE */ - 0x0507002a 0x05080035 0x05090034 0x050B0039 - /* 1 3 4 2 */ - 0x06010002 0x06020004 0x06030005 0x06040003 - /* 8 7 0 9 */ - 0x06050009 0x06060008 0x0608000b 0x0609000a - /* L_ALT DOWN RIGHT Q */ - 0x060a0038 0x060b006c 0x060c006a 0x07010010 - /* E R W I */ - 0x07020012 0x07030013 0x07040011 0x07050017 - /* U R_SHIFT P O */ - 0x07060016 0x07070036 0x07080019 0x07090018 - /* UP LEFT */ - 0x070b0067 0x070c0069>; - }; - gpio_a: gpios@0 { gpio-controller; compatible = "sandbox,gpio"; @@ -144,7 +93,7 @@ i2c@0 { #address-cells = <1>; #size-cells = <0>; - reg = <0>; + reg = <0 0>; compatible = "sandbox,i2c"; clock-frequency = <400000>; eeprom@2c { @@ -161,10 +110,10 @@ spi@0 { #address-cells = <1>; #size-cells = <0>; - reg = <0>; + reg = <0 0>; compatible = "sandbox,spi"; cs-gpios = <0>, <&gpio_a 0>; - flash@0 { + firmware_storage_spi: flash@0 { reg = <0>; compatible = "spansion,m25p16", "sandbox,spi-flash"; spi-max-frequency = <40000000>; @@ -172,13 +121,77 @@ }; }; - cros-ec@0 { - compatible = "google,cros-ec"; - #address-cells = <1>; - #size-cells = <1>; - firmware_storage_spi: flash@0 { - reg = <0 0x400000>; + pci: pci-controller { + compatible = "sandbox,pci"; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000 + 0x01000000 0 0x20000000 0x20000000 0 0x2000>; + pci@1f,0 { + compatible = "pci-generic"; + reg = <0xf800 0 0 0 0>; + emul@1f,0 { + compatible = "sandbox,swap-case"; + }; + }; + }; + + eth@10002000 { + compatible = "sandbox,eth"; + reg = <0x10002000 0x1000>; + fake-host-hwaddr = [00 00 66 44 22 00]; + }; + + eth@80000000 { + compatible = "sandbox,eth-raw"; + reg = <0x80000000 0x1000>; + host-raw-interface = "eth0"; + }; + + eth@90000000 { + compatible = "sandbox,eth-raw"; + reg = <0x90000000 0x1000>; + host-raw-interface = "lo"; + }; + + usb@0 { + compatible = "sandbox,usb"; + status = "disabled"; + hub { + compatible = "sandbox,usb-hub"; + #address-cells = <1>; + #size-cells = <0>; + flash-stick { + reg = <0>; + compatible = "sandbox,usb-flash"; + }; }; }; + usb@1 { + compatible = "sandbox,usb"; + hub { + compatible = "usb-hub"; + usb,device-class = <USB_CLASS_HUB>; + hub-emul { + compatible = "sandbox,usb-hub"; + #address-cells = <1>; + #size-cells = <0>; + flash-stick { + reg = <0>; + compatible = "sandbox,usb-flash"; + sandbox,filepath = "flash.bin"; + }; + }; + }; + }; + + usb@2 { + compatible = "sandbox,usb"; + status = "disabled"; + }; + }; + +#include "cros-ec-keyboard.dtsi" diff --git a/arch/sandbox/include/asm/bitops.h b/arch/sandbox/include/asm/bitops.h index e807c4e..f1a7aee 100644 --- a/arch/sandbox/include/asm/bitops.h +++ b/arch/sandbox/include/asm/bitops.h @@ -1,6 +1,8 @@ /* * Copyright (c) 2011 The Chromium OS Authors. * + * Modified from Linux arch/arm/include/asm/bitops.h + * * Copyright 1995, Russell King. * Various bits and pieces copyrights include: * Linus Torvalds (test_bit). diff --git a/arch/sandbox/include/asm/eth-raw-os.h b/arch/sandbox/include/asm/eth-raw-os.h new file mode 100644 index 0000000..ed4b2e2 --- /dev/null +++ b/arch/sandbox/include/asm/eth-raw-os.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015 National Instruments + * + * (C) Copyright 2015 + * Joe Hershberger <joe.hershberger@ni.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ETH_RAW_OS_H +#define __ETH_RAW_OS_H + +/** + * struct eth_sandbox_raw_priv - raw socket session + * + * sd: socket descriptor - the open socket during a session + * device: struct sockaddr_ll - the host interface packets move to/from + * local: 1 or 0 to select the local interface ('lo') or not + * local_bindsd: socket descriptor to prevent the kernel from sending + * a message to the server claiming the port is + * unreachable + * local_bind_udp_port: The UDP port number that we bound to + */ +struct eth_sandbox_raw_priv { + int sd; + void *device; + int local; + int local_bind_sd; + unsigned short local_bind_udp_port; +}; + +int sandbox_eth_raw_os_start(const char *ifname, unsigned char *ethmac, + struct eth_sandbox_raw_priv *priv); +int sandbox_eth_raw_os_send(void *packet, int length, + struct eth_sandbox_raw_priv *priv); +int sandbox_eth_raw_os_recv(void *packet, int *length, + const struct eth_sandbox_raw_priv *priv); +void sandbox_eth_raw_os_stop(struct eth_sandbox_raw_priv *priv); + +#endif /* __ETH_RAW_OS_H */ diff --git a/arch/sandbox/include/asm/eth.h b/arch/sandbox/include/asm/eth.h new file mode 100644 index 0000000..4b79ede --- /dev/null +++ b/arch/sandbox/include/asm/eth.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2015 National Instruments + * + * (C) Copyright 2015 + * Joe Hershberger <joe.hershberger@ni.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ETH_H +#define __ETH_H + +void sandbox_eth_disable_response(int index, bool disable); + +#endif /* __ETH_H */ diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h index 895fcb8..5b87fde 100644 --- a/arch/sandbox/include/asm/io.h +++ b/arch/sandbox/include/asm/io.h @@ -22,10 +22,7 @@ void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags); /* * Take down a mapping set up by map_physmem(). */ -static inline void unmap_physmem(void *vaddr, unsigned long flags) -{ - -} +void unmap_physmem(const void *vaddr, unsigned long flags); /* For sandbox, we want addresses to point into our RAM buffer */ static inline void *map_sysmem(phys_addr_t paddr, unsigned long len) @@ -33,8 +30,10 @@ static inline void *map_sysmem(phys_addr_t paddr, unsigned long len) return map_physmem(paddr, len, MAP_WRBACK); } +/* Remove a previous mapping */ static inline void unmap_sysmem(const void *vaddr) { + unmap_physmem(vaddr, MAP_WRBACK); } /* Map from a pointer to our RAM buffer */ @@ -48,6 +47,15 @@ phys_addr_t map_to_sysmem(const void *ptr); #define writew(v, addr) #define writel(v, addr) +/* I/O access functions */ +int inl(unsigned int addr); +int inw(unsigned int addr); +int inb(unsigned int addr); + +void outl(unsigned int value, unsigned int addr); +void outw(unsigned int value, unsigned int addr); +void outb(unsigned int value, unsigned int addr); + #include <iotrace.h> #endif diff --git a/arch/sandbox/include/asm/processor.h b/arch/sandbox/include/asm/processor.h new file mode 100644 index 0000000..3c1794e --- /dev/null +++ b/arch/sandbox/include/asm/processor.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_PROCESSOR_H +#define _ASM_PROCESSOR_H + +/* This file is required for PCI */ + +#endif diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 25a0c85..8e490e9 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -10,7 +10,12 @@ #define __ASM_TEST_H /* The sandbox driver always permits an I2C device with this address */ -#define SANDBOX_I2C_TEST_ADDR 0x59 +#define SANDBOX_I2C_TEST_ADDR 0x59 + +#define SANDBOX_PCI_VENDOR_ID 0x1234 +#define SANDBOX_PCI_DEVICE_ID 0x5678 +#define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM +#define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL enum sandbox_i2c_eeprom_test_mode { SIE_TEST_MODE_NONE, diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h index 770ab5c..da87cc3 100644 --- a/arch/sandbox/include/asm/u-boot-sandbox.h +++ b/arch/sandbox/include/asm/u-boot-sandbox.h @@ -27,4 +27,60 @@ int cleanup_before_linux(void); /* drivers/video/sandbox_sdl.c */ int sandbox_lcd_sdl_early_init(void); +/** + * pci_map_physmem() - map a PCI device into memory + * + * This is used on sandbox to map a device into memory so that it can be + * used with normal memory access. After this call, some part of the device's + * internal structure becomes visible. + * + * This function is normally called from sandbox's map_sysmem() automatically. + * + * @paddr: Physical memory address, normally corresponding to a PCI BAR + * @lenp: On entry, the size of the area to map, On exit it is updated + * to the size actually mapped, which may be less if the device + * has less space + * @devp: Returns the device which mapped into this space + * @ptrp: Returns a pointer to the mapped address. The device's space + * can be accessed as @lenp bytes starting here + * @return 0 if OK, -ve on error + */ +int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp, + struct udevice **devp, void **ptrp); + +/** + * pci_unmap_physmem() - undo a memory mapping + * + * This must be called after pci_map_physmem() to undo the mapping. + * + * @paddr: Physical memory address, as passed to pci_map_physmem() + * @len: Size of area mapped, as returned by pci_map_physmem() + * @dev: Device to unmap, as returned by pci_map_physmem() + * @return 0 if OK, -ve on error + */ +int pci_unmap_physmem(const void *addr, unsigned long len, + struct udevice *dev); + +/** + * sandbox_set_enable_pci_map() - Enable / disable PCI address mapping + * + * Since address mapping involves calling every driver, provide a way to + * enable and disable this. It can be handled automatically by the emulator + * uclass, which knows if any emulators are currently active. + * + * If this is disabled, pci_map_physmem() will not be called from + * map_sysmem(). + * + * @enable: 0 to disable, 1 to enable + */ +void sandbox_set_enable_pci_map(int enable); + +/** + * sandbox_read_fdt_from_file() - Read a device tree from a file + * + * Read a device tree file from a host file and set it up for use as the + * control FDT. + */ +int sandbox_read_fdt_from_file(void); + #endif /* _U_BOOT_SANDBOX_H_ */ diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile index 4c1a38d..96761e2 100644 --- a/arch/sandbox/lib/Makefile +++ b/arch/sandbox/lib/Makefile @@ -7,5 +7,6 @@ # SPDX-License-Identifier: GPL-2.0+ # - obj-y += interrupts.o +obj-$(CONFIG_PCI) += pci_io.o +obj-$(CONFIG_CMD_BOOTM) += bootm.o diff --git a/arch/sandbox/lib/bootm.c b/arch/sandbox/lib/bootm.c new file mode 100644 index 0000000..d49c927 --- /dev/null +++ b/arch/sandbox/lib/bootm.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (c) 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk> + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define LINUX_ARM_ZIMAGE_MAGIC 0x016f2818 + +struct arm_z_header { + uint32_t code[9]; + uint32_t zi_magic; + uint32_t zi_start; + uint32_t zi_end; +} __attribute__ ((__packed__)); + +int bootz_setup(ulong image, ulong *start, ulong *end) +{ + uint8_t *zimage = map_sysmem(image, 0); + struct arm_z_header *arm_hdr = (struct arm_z_header *)zimage; + int ret = 0; + + if (memcmp(zimage + 0x202, "HdrS", 4) == 0) { + uint8_t setup_sects = *(zimage + 0x1f1); + uint32_t syssize = + le32_to_cpu(*(uint32_t *)(zimage + 0x1f4)); + + *start = 0; + *end = (setup_sects + 1) * 512 + syssize * 16; + + printf("setting up X86 zImage [ %ld - %ld ]\n", + *start, *end); + } else if (le32_to_cpu(arm_hdr->zi_magic) == LINUX_ARM_ZIMAGE_MAGIC) { + *start = le32_to_cpu(arm_hdr->zi_start); + *end = le32_to_cpu(arm_hdr->zi_end); + + printf("setting up ARM zImage [ %ld - %ld ]\n", + *start, *end); + } else { + printf("Unrecognized zImage\n"); + ret = 1; + } + + unmap_sysmem((void *)image); + + return ret; +} + +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +{ + if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { + bootstage_mark(BOOTSTAGE_ID_RUN_OS); + printf("## Transferring control to Linux (at address %08lx)...\n", + images->ep); + reset_cpu(0); + } + + return 0; +} diff --git a/arch/sandbox/lib/pci_io.c b/arch/sandbox/lib/pci_io.c new file mode 100644 index 0000000..0de124f --- /dev/null +++ b/arch/sandbox/lib/pci_io.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2014 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * IO space access commands. + */ + +#include <common.h> +#include <command.h> +#include <dm.h> +#include <asm/io.h> + +int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp, + struct udevice **devp, void **ptrp) +{ + struct udevice *dev; + int ret; + + *ptrp = 0; + for (uclass_first_device(UCLASS_PCI_EMUL, &dev); + dev; + uclass_next_device(&dev)) { + struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev); + + if (!ops || !ops->map_physmem) + continue; + ret = (ops->map_physmem)(dev, paddr, lenp, ptrp); + if (ret) + continue; + *devp = dev; + return 0; + } + + debug("%s: failed: addr=%x\n", __func__, paddr); + return -ENOSYS; +} + +int pci_unmap_physmem(const void *vaddr, unsigned long len, + struct udevice *dev) +{ + struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev); + + if (!ops || !ops->unmap_physmem) + return -ENOSYS; + return (ops->unmap_physmem)(dev, vaddr, len); +} + +static int pci_io_read(unsigned int addr, ulong *valuep, pci_size_t size) +{ + struct udevice *dev; + int ret; + + *valuep = pci_get_ff(size); + for (uclass_first_device(UCLASS_PCI_EMUL, &dev); + dev; + uclass_next_device(&dev)) { + struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev); + + if (ops && ops->read_io) { + ret = (ops->read_io)(dev, addr, valuep, size); + if (!ret) + return 0; + } + } + + debug("%s: failed: addr=%x\n", __func__, addr); + return -ENOSYS; +} + +static int pci_io_write(unsigned int addr, ulong value, pci_size_t size) +{ + struct udevice *dev; + int ret; + + for (uclass_first_device(UCLASS_PCI_EMUL, &dev); + dev; + uclass_next_device(&dev)) { + struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev); + + if (ops && ops->write_io) { + ret = (ops->write_io)(dev, addr, value, size); + if (!ret) + return 0; + } + } + + debug("%s: failed: addr=%x, value=%lx\n", __func__, addr, value); + return -ENOSYS; +} + +int inl(unsigned int addr) +{ + unsigned long value; + int ret; + + ret = pci_io_read(addr, &value, PCI_SIZE_32); + + return ret ? 0 : value; +} + +int inw(unsigned int addr) +{ + unsigned long value; + int ret; + + ret = pci_io_read(addr, &value, PCI_SIZE_16); + + return ret ? 0 : value; +} + +int inb(unsigned int addr) +{ + unsigned long value; + int ret; + + ret = pci_io_read(addr, &value, PCI_SIZE_8); + + return ret ? 0 : value; +} + +void outl(unsigned int value, unsigned int addr) +{ + pci_io_write(addr, value, PCI_SIZE_32); +} + +void outw(unsigned int value, unsigned int addr) +{ + pci_io_write(addr, value, PCI_SIZE_16); +} + +void outb(unsigned int value, unsigned int addr) +{ + pci_io_write(addr, value, PCI_SIZE_8); +} diff --git a/arch/sh/lib/board.c b/arch/sh/lib/board.c index 1eb7afb..6dad3c7 100644 --- a/arch/sh/lib/board.c +++ b/arch/sh/lib/board.c @@ -178,7 +178,7 @@ void sh_generic_init(void) #endif #if defined(CONFIG_CMD_NET) puts("Net: "); - eth_initialize(gd->bd); + eth_initialize(); #endif /* CONFIG_CMD_NET */ while (1) { diff --git a/arch/sparc/lib/board.c b/arch/sparc/lib/board.c index b311a94..d2ac6bc 100644 --- a/arch/sparc/lib/board.c +++ b/arch/sparc/lib/board.c @@ -351,7 +351,7 @@ void board_init_f(ulong bootflag) #if defined(CONFIG_CMD_NET) WATCHDOG_RESET(); puts("Net: "); - eth_initialize(bd); + eth_initialize(); #endif #if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index da27115..3f1401a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -7,6 +7,9 @@ config SYS_ARCH config USE_PRIVATE_LIBGCC default y +config SYS_VSNPRINTF + default y + choice prompt "Target select" @@ -32,6 +35,20 @@ config TARGET_CHROMEBOOK_LINK and it provides a 2560x1700 high resolution touch-enabled LCD display. +config TARGET_CHROMEBOX_PANTHER + bool "Support Chromebox panther (not available)" + select n + help + Note: At present this must be used with Coreboot. See README.x86 + for instructions. + + This is the Asus Chromebox CN60 released in 2014. It uses an Intel + Haswell Celeron 2955U Dual Core CPU with 2GB of SDRAM. It has a + Lynx Point platform controller hub, PCIe WiFi and Bluetooth. It also + includes a USB SD reader, four USB3 ports, display port and HDMI + video output and a 16GB SATA solid state drive. There is no Chrome + OS EC on this model. + config TARGET_CROWNBAY bool "Support Intel Crown Bay CRB" help @@ -67,13 +84,10 @@ config TARGET_GALILEO endchoice -config DM - default y - -config DM_GPIO +config DM_SPI default y -config DM_SERIAL +config DM_SPI_FLASH default y config SYS_MALLOC_F_LEN @@ -432,6 +446,8 @@ source "board/coreboot/coreboot/Kconfig" source "board/google/chromebook_link/Kconfig" +source "board/google/chromebox_panther/Kconfig" + source "board/intel/crownbay/Kconfig" source "board/intel/minnowmax/Kconfig" @@ -452,4 +468,13 @@ config PCIE_ECAM_BASE assigned to PCI devices - i.e. the memory and prefetch regions, as passed to pci_set_region(). +config BOOTSTAGE + default y + +config BOOTSTAGE_REPORT + default y + +config CMD_BOOTSTAGE + default y + endmenu diff --git a/arch/x86/cpu/baytrail/early_uart.c b/arch/x86/cpu/baytrail/early_uart.c index 4199210..b64a3a9 100644 --- a/arch/x86/cpu/baytrail/early_uart.c +++ b/arch/x86/cpu/baytrail/early_uart.c @@ -50,7 +50,7 @@ static void score_select_func(int pad, int func) writel(reg, pconf0_addr); } -static void pci_write_config32(int dev, unsigned int where, u32 value) +static void x86_pci_write_config32(int dev, unsigned int where, u32 value) { unsigned long addr; @@ -62,7 +62,8 @@ static void pci_write_config32(int dev, unsigned int where, u32 value) int setup_early_uart(void) { /* Enable the legacy UART hardware. */ - pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT, 1); + x86_pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT, + 1); /* * Set up the pads to the UART function. This allows the signals to diff --git a/arch/x86/cpu/coreboot/pci.c b/arch/x86/cpu/coreboot/pci.c index c9983f1..fa415dd 100644 --- a/arch/x86/cpu/coreboot/pci.c +++ b/arch/x86/cpu/coreboot/pci.c @@ -10,58 +10,27 @@ */ #include <common.h> +#include <dm.h> +#include <errno.h> #include <pci.h> +#include <asm/io.h> #include <asm/pci.h> DECLARE_GLOBAL_DATA_PTR; -static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev, - struct pci_config_table *table) -{ - u8 secondary; - hose->read_byte(hose, dev, PCI_SECONDARY_BUS, &secondary); - hose->last_busno = max(hose->last_busno, (int)secondary); - pci_hose_scan_bus(hose, secondary); -} - -static struct pci_config_table pci_coreboot_config_table[] = { - /* vendor, device, class, bus, dev, func */ - { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI, - PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, &config_pci_bridge }, - {} +static const struct dm_pci_ops pci_x86_ops = { + .read_config = pci_x86_read_config, + .write_config = pci_x86_write_config, }; -void board_pci_setup_hose(struct pci_controller *hose) -{ - hose->config_table = pci_coreboot_config_table; - hose->first_busno = 0; - hose->last_busno = 0; - - /* PCI memory space */ - pci_set_region(hose->regions + 0, - CONFIG_PCI_MEM_BUS, - CONFIG_PCI_MEM_PHYS, - CONFIG_PCI_MEM_SIZE, - PCI_REGION_MEM); - - /* PCI IO space */ - pci_set_region(hose->regions + 1, - CONFIG_PCI_IO_BUS, - CONFIG_PCI_IO_PHYS, - CONFIG_PCI_IO_SIZE, - PCI_REGION_IO); - - pci_set_region(hose->regions + 2, - CONFIG_PCI_PREF_BUS, - CONFIG_PCI_PREF_PHYS, - CONFIG_PCI_PREF_SIZE, - PCI_REGION_PREFETCH); - - pci_set_region(hose->regions + 3, - 0, - 0, - gd->ram_size, - PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); +static const struct udevice_id pci_x86_ids[] = { + { .compatible = "pci-x86" }, + { } +}; - hose->region_count = 4; -} +U_BOOT_DRIVER(pci_x86_drv) = { + .name = "pci_x86", + .id = UCLASS_PCI, + .of_match = pci_x86_ids, + .ops = &pci_x86_ops, +}; diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c index e98a230..9c3ab81 100644 --- a/arch/x86/cpu/coreboot/sdram.c +++ b/arch/x86/cpu/coreboot/sdram.c @@ -90,7 +90,8 @@ int dram_init(void) struct memrange *memrange = &lib_sysinfo.memrange[i]; unsigned long long end = memrange->base + memrange->size; - if (memrange->type == CB_MEM_RAM && end > ram_size) + if (memrange->type == CB_MEM_RAM && end > ram_size && + memrange->base < (1ULL << 32)) ram_size = end; } gd->ram_size = ram_size; @@ -108,7 +109,8 @@ void dram_init_banksize(void) for (i = 0, j = 0; i < lib_sysinfo.n_memranges; i++) { struct memrange *memrange = &lib_sysinfo.memrange[i]; - if (memrange->type == CB_MEM_RAM) { + if (memrange->type == CB_MEM_RAM && + memrange->base < (1ULL << 32)) { gd->bd->bi_dram[j].start = memrange->base; gd->bd->bi_dram[j].size = memrange->size; j++; diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index ed7905c..a9ca50b 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -163,7 +163,7 @@ void setup_gdt(gd_t *id, u64 *gdt_addr) int __weak x86_cleanup_before_linux(void) { #ifdef CONFIG_BOOTSTAGE_STASH - bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH, + bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR, CONFIG_BOOTSTAGE_STASH_SIZE); #endif diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c index 65a17d3..ca8cccf 100644 --- a/arch/x86/cpu/ivybridge/bd82x6x.c +++ b/arch/x86/cpu/ivybridge/bd82x6x.c @@ -5,6 +5,7 @@ */ #include <common.h> +#include <dm.h> #include <errno.h> #include <fdtdec.h> #include <malloc.h> @@ -22,36 +23,36 @@ void bd82x6x_pci_init(pci_dev_t dev) debug("bd82x6x PCI init.\n"); /* Enable Bus Master */ - reg16 = pci_read_config16(dev, PCI_COMMAND); + reg16 = x86_pci_read_config16(dev, PCI_COMMAND); reg16 |= PCI_COMMAND_MASTER; - pci_write_config16(dev, PCI_COMMAND, reg16); + x86_pci_write_config16(dev, PCI_COMMAND, reg16); /* This device has no interrupt */ - pci_write_config8(dev, INTR, 0xff); + x86_pci_write_config8(dev, INTR, 0xff); /* disable parity error response and SERR */ - reg16 = pci_read_config16(dev, BCTRL); + reg16 = x86_pci_read_config16(dev, BCTRL); reg16 &= ~(1 << 0); reg16 &= ~(1 << 1); - pci_write_config16(dev, BCTRL, reg16); + x86_pci_write_config16(dev, BCTRL, reg16); /* Master Latency Count must be set to 0x04! */ - reg8 = pci_read_config8(dev, SMLT); + reg8 = x86_pci_read_config8(dev, SMLT); reg8 &= 0x07; reg8 |= (0x04 << 3); - pci_write_config8(dev, SMLT, reg8); + x86_pci_write_config8(dev, SMLT, reg8); /* Will this improve throughput of bus masters? */ - pci_write_config8(dev, PCI_MIN_GNT, 0x06); + x86_pci_write_config8(dev, PCI_MIN_GNT, 0x06); /* Clear errors in status registers */ - reg16 = pci_read_config16(dev, PSTS); + reg16 = x86_pci_read_config16(dev, PSTS); /* reg16 |= 0xf900; */ - pci_write_config16(dev, PSTS, reg16); + x86_pci_write_config16(dev, PSTS, reg16); - reg16 = pci_read_config16(dev, SECSTS); + reg16 = x86_pci_read_config16(dev, SECSTS); /* reg16 |= 0xf900; */ - pci_write_config16(dev, SECSTS, reg16); + x86_pci_write_config16(dev, SECSTS, reg16); } #define PCI_BRIDGE_UPDATE_COMMAND @@ -59,7 +60,7 @@ void bd82x6x_pci_dev_enable_resources(pci_dev_t dev) { uint16_t command; - command = pci_read_config16(dev, PCI_COMMAND); + command = x86_pci_read_config16(dev, PCI_COMMAND); command |= PCI_COMMAND_IO; #ifdef PCI_BRIDGE_UPDATE_COMMAND /* @@ -67,7 +68,7 @@ void bd82x6x_pci_dev_enable_resources(pci_dev_t dev) * ROM and APICs to become invisible. */ debug("%x cmd <- %02x\n", dev, command); - pci_write_config16(dev, PCI_COMMAND, command); + x86_pci_write_config16(dev, PCI_COMMAND, command); #else printf("%s cmd <- %02x (NOT WRITTEN!)\n", dev_path(dev), command); #endif @@ -77,16 +78,16 @@ void bd82x6x_pci_bus_enable_resources(pci_dev_t dev) { uint16_t ctrl; - ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL); + ctrl = x86_pci_read_config16(dev, PCI_BRIDGE_CONTROL); ctrl |= PCI_COMMAND_IO; ctrl |= PCI_BRIDGE_CTL_VGA; debug("%x bridge ctrl <- %04x\n", dev, ctrl); - pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl); + x86_pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl); bd82x6x_pci_dev_enable_resources(dev); } -int bd82x6x_init_pci_devices(void) +static int bd82x6x_probe(struct udevice *dev) { const void *blob = gd->fdt_blob; struct pci_controller *hose; @@ -144,3 +145,15 @@ int bd82x6x_init(void) return 0; } + +static const struct udevice_id bd82x6x_ids[] = { + { .compatible = "intel,bd82x6x" }, + { } +}; + +U_BOOT_DRIVER(bd82x6x_drv) = { + .name = "bd82x6x", + .id = UCLASS_PCH, + .of_match = bd82x6x_ids, + .probe = bd82x6x_probe, +}; diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c index e925310..37f3731 100644 --- a/arch/x86/cpu/ivybridge/cpu.c +++ b/arch/x86/cpu/ivybridge/cpu.c @@ -12,6 +12,7 @@ */ #include <common.h> +#include <dm.h> #include <errno.h> #include <fdtdec.h> #include <asm/cpu.h> @@ -116,23 +117,32 @@ static void set_spi_speed(void) int arch_cpu_init(void) { + post_code(POST_CPU_INIT); + timer_set_base(rdtsc()); + + return x86_cpu_init_f(); +} + +int arch_cpu_init_dm(void) +{ const void *blob = gd->fdt_blob; struct pci_controller *hose; + struct udevice *bus; int node; int ret; - post_code(POST_CPU_INIT); - timer_set_base(rdtsc()); - - ret = x86_cpu_init_f(); + post_code(0x70); + ret = uclass_get_device(UCLASS_PCI, 0, &bus); + post_code(0x71); if (ret) return ret; + post_code(0x72); + hose = dev_get_uclass_priv(bus); - ret = pci_early_init_hose(&hose); - if (ret) - return ret; + /* TODO(sjg@chromium.org): Get rid of gd->hose */ + gd->hose = hose; - node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_LPC); + node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_PCH); if (node < 0) return -ENOENT; ret = lpc_early_init(gd->fdt_blob, node, PCH_LPC_DEV); @@ -167,21 +177,21 @@ static int enable_smbus(void) dev = PCI_BDF(0x0, 0x1f, 0x3); /* Check to make sure we've got the right device. */ - value = pci_read_config16(dev, 0x0); + value = x86_pci_read_config16(dev, 0x0); if (value != 0x8086) { printf("SMBus controller not found\n"); return -ENOSYS; } /* Set SMBus I/O base. */ - pci_write_config32(dev, SMB_BASE, - SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO); + x86_pci_write_config32(dev, SMB_BASE, + SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO); /* Set SMBus enable. */ - pci_write_config8(dev, HOSTC, HST_EN); + x86_pci_write_config8(dev, HOSTC, HST_EN); /* Set SMBus I/O space enable. */ - pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO); + x86_pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO); /* Disable interrupt generation. */ outb(0, SMBUS_IO_BASE + SMBHSTCTL); @@ -214,25 +224,25 @@ static void enable_usb_bar(void) u32 cmd; /* USB Controller 1 */ - pci_write_config32(usb0, PCI_BASE_ADDRESS_0, - PCH_EHCI0_TEMP_BAR0); - cmd = pci_read_config32(usb0, PCI_COMMAND); + x86_pci_write_config32(usb0, PCI_BASE_ADDRESS_0, + PCH_EHCI0_TEMP_BAR0); + cmd = x86_pci_read_config32(usb0, PCI_COMMAND); cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - pci_write_config32(usb0, PCI_COMMAND, cmd); + x86_pci_write_config32(usb0, PCI_COMMAND, cmd); /* USB Controller 1 */ - pci_write_config32(usb1, PCI_BASE_ADDRESS_0, - PCH_EHCI1_TEMP_BAR0); - cmd = pci_read_config32(usb1, PCI_COMMAND); + x86_pci_write_config32(usb1, PCI_BASE_ADDRESS_0, + PCH_EHCI1_TEMP_BAR0); + cmd = x86_pci_read_config32(usb1, PCI_COMMAND); cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - pci_write_config32(usb1, PCI_COMMAND, cmd); + x86_pci_write_config32(usb1, PCI_COMMAND, cmd); /* USB3 Controller */ - pci_write_config32(usb3, PCI_BASE_ADDRESS_0, - PCH_XHCI_TEMP_BAR0); - cmd = pci_read_config32(usb3, PCI_COMMAND); + x86_pci_write_config32(usb3, PCI_BASE_ADDRESS_0, + PCH_XHCI_TEMP_BAR0); + cmd = x86_pci_read_config32(usb3, PCI_COMMAND); cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - pci_write_config32(usb3, PCI_COMMAND, cmd); + x86_pci_write_config32(usb3, PCI_COMMAND, cmd); } static int report_bist_failure(void) @@ -320,8 +330,8 @@ int print_cpuinfo(void) gd->arch.pei_boot_mode = boot_mode; /* TODO: Move this to the board or driver */ - pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1); - pci_write_config32(PCH_LPC_DEV, GPIO_CNTL, 0x10); + x86_pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1); + x86_pci_write_config32(PCH_LPC_DEV, GPIO_CNTL, 0x10); /* Print processor name */ name = cpu_get_name(processor_name); diff --git a/arch/x86/cpu/ivybridge/early_init.c b/arch/x86/cpu/ivybridge/early_init.c index eb8f613..9ca008e 100644 --- a/arch/x86/cpu/ivybridge/early_init.c +++ b/arch/x86/cpu/ivybridge/early_init.c @@ -17,10 +17,10 @@ static void sandybridge_setup_bars(pci_dev_t pch_dev, pci_dev_t lpc_dev) { /* Setting up Southbridge. In the northbridge code. */ debug("Setting up static southbridge registers\n"); - pci_write_config32(lpc_dev, PCH_RCBA_BASE, DEFAULT_RCBA | 1); + x86_pci_write_config32(lpc_dev, PCH_RCBA_BASE, DEFAULT_RCBA | 1); - pci_write_config32(lpc_dev, PMBASE, DEFAULT_PMBASE | 1); - pci_write_config8(lpc_dev, ACPI_CNTL, 0x80); /* Enable ACPI BAR */ + x86_pci_write_config32(lpc_dev, PMBASE, DEFAULT_PMBASE | 1); + x86_pci_write_config8(lpc_dev, ACPI_CNTL, 0x80); /* Enable ACPI BAR */ debug("Disabling watchdog reboot\n"); setbits_le32(RCB_REG(GCS), 1 >> 5); /* No reset */ @@ -28,25 +28,27 @@ static void sandybridge_setup_bars(pci_dev_t pch_dev, pci_dev_t lpc_dev) /* Set up all hardcoded northbridge BARs */ debug("Setting up static registers\n"); - pci_write_config32(pch_dev, EPBAR, DEFAULT_EPBAR | 1); - pci_write_config32(pch_dev, EPBAR + 4, (0LL + DEFAULT_EPBAR) >> 32); - pci_write_config32(pch_dev, MCHBAR, DEFAULT_MCHBAR | 1); - pci_write_config32(pch_dev, MCHBAR + 4, (0LL + DEFAULT_MCHBAR) >> 32); + x86_pci_write_config32(pch_dev, EPBAR, DEFAULT_EPBAR | 1); + x86_pci_write_config32(pch_dev, EPBAR + 4, (0LL + DEFAULT_EPBAR) >> 32); + x86_pci_write_config32(pch_dev, MCHBAR, DEFAULT_MCHBAR | 1); + x86_pci_write_config32(pch_dev, MCHBAR + 4, + (0LL + DEFAULT_MCHBAR) >> 32); /* 64MB - busses 0-63 */ - pci_write_config32(pch_dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5); - pci_write_config32(pch_dev, PCIEXBAR + 4, - (0LL + DEFAULT_PCIEXBAR) >> 32); - pci_write_config32(pch_dev, DMIBAR, DEFAULT_DMIBAR | 1); - pci_write_config32(pch_dev, DMIBAR + 4, (0LL + DEFAULT_DMIBAR) >> 32); + x86_pci_write_config32(pch_dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5); + x86_pci_write_config32(pch_dev, PCIEXBAR + 4, + (0LL + DEFAULT_PCIEXBAR) >> 32); + x86_pci_write_config32(pch_dev, DMIBAR, DEFAULT_DMIBAR | 1); + x86_pci_write_config32(pch_dev, DMIBAR + 4, + (0LL + DEFAULT_DMIBAR) >> 32); /* Set C0000-FFFFF to access RAM on both reads and writes */ - pci_write_config8(pch_dev, PAM0, 0x30); - pci_write_config8(pch_dev, PAM1, 0x33); - pci_write_config8(pch_dev, PAM2, 0x33); - pci_write_config8(pch_dev, PAM3, 0x33); - pci_write_config8(pch_dev, PAM4, 0x33); - pci_write_config8(pch_dev, PAM5, 0x33); - pci_write_config8(pch_dev, PAM6, 0x33); + x86_pci_write_config8(pch_dev, PAM0, 0x30); + x86_pci_write_config8(pch_dev, PAM1, 0x33); + x86_pci_write_config8(pch_dev, PAM2, 0x33); + x86_pci_write_config8(pch_dev, PAM3, 0x33); + x86_pci_write_config8(pch_dev, PAM4, 0x33); + x86_pci_write_config8(pch_dev, PAM5, 0x33); + x86_pci_write_config8(pch_dev, PAM6, 0x33); } static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev) @@ -55,7 +57,7 @@ static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev) u16 reg16; u8 reg8; - reg16 = pci_read_config16(video_dev, PCI_DEVICE_ID); + reg16 = x86_pci_read_config16(video_dev, PCI_DEVICE_ID); switch (reg16) { case 0x0102: /* GT1 Desktop */ case 0x0106: /* GT1 Mobile */ @@ -75,7 +77,7 @@ static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev) debug("Initialising Graphics\n"); /* Setup IGD memory by setting GGC[7:3] = 1 for 32MB */ - reg16 = pci_read_config16(pch_dev, GGC); + reg16 = x86_pci_read_config16(pch_dev, GGC); reg16 &= ~0x00f8; reg16 |= 1 << 3; /* Program GTT memory by setting GGC[9:8] = 2MB */ @@ -83,13 +85,13 @@ static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev) reg16 |= 2 << 8; /* Enable VGA decode */ reg16 &= ~0x0002; - pci_write_config16(pch_dev, GGC, reg16); + x86_pci_write_config16(pch_dev, GGC, reg16); /* Enable 256MB aperture */ - reg8 = pci_read_config8(video_dev, MSAC); + reg8 = x86_pci_read_config8(video_dev, MSAC); reg8 &= ~0x06; reg8 |= 0x02; - pci_write_config8(video_dev, MSAC, reg8); + x86_pci_write_config8(video_dev, MSAC, reg8); /* Erratum workarounds */ reg32 = readl(MCHBAR_REG(0x5f00)); @@ -124,22 +126,22 @@ void sandybridge_early_init(int chipset_type) u8 reg8; /* Device ID Override Enable should be done very early */ - capid0_a = pci_read_config32(pch_dev, 0xe4); + capid0_a = x86_pci_read_config32(pch_dev, 0xe4); if (capid0_a & (1 << 10)) { - reg8 = pci_read_config8(pch_dev, 0xf3); + reg8 = x86_pci_read_config8(pch_dev, 0xf3); reg8 &= ~7; /* Clear 2:0 */ if (chipset_type == SANDYBRIDGE_MOBILE) reg8 |= 1; /* Set bit 0 */ - pci_write_config8(pch_dev, 0xf3, reg8); + x86_pci_write_config8(pch_dev, 0xf3, reg8); } /* Setup all BARs required for early PCIe and raminit */ sandybridge_setup_bars(pch_dev, lpc_dev); /* Device Enable */ - pci_write_config32(pch_dev, DEVEN, DEVEN_HOST | DEVEN_IGD); + x86_pci_write_config32(pch_dev, DEVEN, DEVEN_HOST | DEVEN_IGD); sandybridge_setup_graphics(pch_dev, video_dev); } diff --git a/arch/x86/cpu/ivybridge/early_me.c b/arch/x86/cpu/ivybridge/early_me.c index b24dea1..356bbb4 100644 --- a/arch/x86/cpu/ivybridge/early_me.c +++ b/arch/x86/cpu/ivybridge/early_me.c @@ -29,7 +29,7 @@ static inline void pci_read_dword_ptr(void *ptr, int offset) { u32 dword; - dword = pci_read_config32(PCH_ME_DEV, offset); + dword = x86_pci_read_config32(PCH_ME_DEV, offset); memcpy(ptr, &dword, sizeof(dword)); } @@ -37,7 +37,7 @@ static inline void pci_write_dword_ptr(void *ptr, int offset) { u32 dword = 0; memcpy(&dword, ptr, sizeof(dword)); - pci_write_config32(PCH_ME_DEV, offset, dword); + x86_pci_write_config32(PCH_ME_DEV, offset, dword); } void intel_early_me_status(void) @@ -101,7 +101,7 @@ static inline void set_global_reset(int enable) { u32 etr3; - etr3 = pci_read_config32(PCH_LPC_DEV, ETR3); + etr3 = x86_pci_read_config32(PCH_LPC_DEV, ETR3); /* Clear CF9 Without Resume Well Reset Enable */ etr3 &= ~ETR3_CWORWRE; @@ -112,7 +112,7 @@ static inline void set_global_reset(int enable) else etr3 &= ~ETR3_CF9GR; - pci_write_config32(PCH_LPC_DEV, ETR3, etr3); + x86_pci_write_config32(PCH_LPC_DEV, ETR3, etr3); } int intel_early_me_init_done(u8 status) @@ -127,8 +127,8 @@ int intel_early_me_init_done(u8 status) }; /* MEBASE from MESEG_BASE[35:20] */ - mebase_l = pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L); - mebase_h = pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H); + mebase_l = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L); + mebase_h = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H); mebase_h &= 0xf; did.uma_base = (mebase_l >> 20) | (mebase_h << 12); diff --git a/arch/x86/cpu/ivybridge/gma.c b/arch/x86/cpu/ivybridge/gma.c index 821ea25..ea169b0 100644 --- a/arch/x86/cpu/ivybridge/gma.c +++ b/arch/x86/cpu/ivybridge/gma.c @@ -741,9 +741,9 @@ int gma_func0_init(pci_dev_t dev, struct pci_controller *hose, int ret; /* IGD needs to be Bus Master */ - reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 = x86_pci_read_config32(dev, PCI_COMMAND); reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; - pci_write_config32(dev, PCI_COMMAND, reg32); + x86_pci_write_config32(dev, PCI_COMMAND, reg32); /* Use write-combining for the graphics memory, 256MB */ base = pci_read_bar32(hose, dev, 2); diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c index 43fdd31..bc1a0f0 100644 --- a/arch/x86/cpu/ivybridge/lpc.c +++ b/arch/x86/cpu/ivybridge/lpc.c @@ -7,6 +7,7 @@ */ #include <common.h> +#include <dm.h> #include <errno.h> #include <fdtdec.h> #include <rtc.h> @@ -29,7 +30,7 @@ static int pch_enable_apic(pci_dev_t dev) int i; /* Enable ACPI I/O and power management. Set SCI IRQ to IRQ9 */ - pci_write_config8(dev, ACPI_CNTL, 0x80); + x86_pci_write_config8(dev, ACPI_CNTL, 0x80); writel(0, IO_APIC_INDEX); writel(1 << 25, IO_APIC_DATA); @@ -72,9 +73,9 @@ static void pch_enable_serial_irqs(pci_dev_t dev) /* Set packet length and toggle silent mode bit for one frame. */ value = (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0); #ifdef CONFIG_SERIRQ_CONTINUOUS_MODE - pci_write_config8(dev, SERIRQ_CNTL, value); + x86_pci_write_config8(dev, SERIRQ_CNTL, value); #else - pci_write_config8(dev, SERIRQ_CNTL, value | (1 << 6)); + x86_pci_write_config8(dev, SERIRQ_CNTL, value | (1 << 6)); #endif } @@ -86,15 +87,15 @@ static int pch_pirq_init(const void *blob, int node, pci_dev_t dev) sizeof(route))) return -EINVAL; ptr = route; - pci_write_config8(dev, PIRQA_ROUT, *ptr++); - pci_write_config8(dev, PIRQB_ROUT, *ptr++); - pci_write_config8(dev, PIRQC_ROUT, *ptr++); - pci_write_config8(dev, PIRQD_ROUT, *ptr++); + x86_pci_write_config8(dev, PIRQA_ROUT, *ptr++); + x86_pci_write_config8(dev, PIRQB_ROUT, *ptr++); + x86_pci_write_config8(dev, PIRQC_ROUT, *ptr++); + x86_pci_write_config8(dev, PIRQD_ROUT, *ptr++); - pci_write_config8(dev, PIRQE_ROUT, *ptr++); - pci_write_config8(dev, PIRQF_ROUT, *ptr++); - pci_write_config8(dev, PIRQG_ROUT, *ptr++); - pci_write_config8(dev, PIRQH_ROUT, *ptr++); + x86_pci_write_config8(dev, PIRQE_ROUT, *ptr++); + x86_pci_write_config8(dev, PIRQF_ROUT, *ptr++); + x86_pci_write_config8(dev, PIRQG_ROUT, *ptr++); + x86_pci_write_config8(dev, PIRQH_ROUT, *ptr++); /* * TODO(sjg@chromium.org): U-Boot does not set up the interrupts @@ -116,7 +117,7 @@ static int pch_gpi_routing(const void *blob, int node, pci_dev_t dev) for (reg = 0, gpi = 0; gpi < ARRAY_SIZE(route); gpi++) reg |= route[gpi] << (gpi * 2); - pci_write_config32(dev, 0xb8, reg); + x86_pci_write_config32(dev, 0xb8, reg); return 0; } @@ -141,7 +142,7 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev) */ pwr_on = MAINBOARD_POWER_ON; - reg16 = pci_read_config16(dev, GEN_PMCON_3); + reg16 = x86_pci_read_config16(dev, GEN_PMCON_3); reg16 &= 0xfffe; switch (pwr_on) { case MAINBOARD_POWER_OFF: @@ -168,7 +169,7 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev) reg16 |= (1 << 12); /* Disable SLP stretch after SUS well */ - pci_write_config16(dev, GEN_PMCON_3, reg16); + x86_pci_write_config16(dev, GEN_PMCON_3, reg16); debug("Set power %s after power failure.\n", state); /* Set up NMI on errors. */ @@ -192,21 +193,21 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev) outb(reg8, 0x70); /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */ - reg16 = pci_read_config16(dev, GEN_PMCON_1); + reg16 = x86_pci_read_config16(dev, GEN_PMCON_1); reg16 &= ~(3 << 0); /* SMI# rate 1 minute */ reg16 &= ~(1 << 10); /* Disable BIOS_PCI_EXP_EN for native PME */ #if DEBUG_PERIODIC_SMIS /* Set DEBUG_PERIODIC_SMIS in pch.h to debug using periodic SMIs */ reg16 |= (3 << 0); /* Periodic SMI every 8s */ #endif - pci_write_config16(dev, GEN_PMCON_1, reg16); + x86_pci_write_config16(dev, GEN_PMCON_1, reg16); /* Set the board's GPI routing. */ ret = pch_gpi_routing(blob, node, dev); if (ret) return ret; - pmbase = pci_read_config16(dev, 0x40) & 0xfffe; + pmbase = x86_pci_read_config16(dev, 0x40) & 0xfffe; writel(pmbase + GPE0_EN, fdtdec_get_int(blob, node, "intel,gpe0-enable", 0)); @@ -231,11 +232,11 @@ static void pch_rtc_init(pci_dev_t dev) int rtc_failed; u8 reg8; - reg8 = pci_read_config8(dev, GEN_PMCON_3); + reg8 = x86_pci_read_config8(dev, GEN_PMCON_3); rtc_failed = reg8 & RTC_BATTERY_DEAD; if (rtc_failed) { reg8 &= ~RTC_BATTERY_DEAD; - pci_write_config8(dev, GEN_PMCON_3, reg8); + x86_pci_write_config8(dev, GEN_PMCON_3, reg8); } debug("rtc_failed = 0x%x\n", rtc_failed); @@ -258,7 +259,7 @@ static void pch_rtc_init(pci_dev_t dev) static void cpt_pm_init(pci_dev_t dev) { debug("CougarPoint PM init\n"); - pci_write_config8(dev, 0xa9, 0x47); + x86_pci_write_config8(dev, 0xa9, 0x47); setbits_le32(RCB_REG(0x2238), (1 << 6) | (1 << 0)); setbits_le32(RCB_REG(0x228c), 1 << 0); @@ -302,7 +303,7 @@ static void cpt_pm_init(pci_dev_t dev) static void ppt_pm_init(pci_dev_t dev) { debug("PantherPoint PM init\n"); - pci_write_config8(dev, 0xa9, 0x47); + x86_pci_write_config8(dev, 0xa9, 0x47); setbits_le32(RCB_REG(0x2238), 1 << 0); setbits_le32(RCB_REG(0x228c), 1 << 0); setbits_le16(RCB_REG(0x1100), (1 << 13) | (1 << 14)); @@ -356,9 +357,9 @@ static void enable_clock_gating(pci_dev_t dev) setbits_le32(RCB_REG(0x2234), 0xf); - reg16 = pci_read_config16(dev, GEN_PMCON_1); + reg16 = x86_pci_read_config16(dev, GEN_PMCON_1); reg16 |= (1 << 2) | (1 << 11); - pci_write_config16(dev, GEN_PMCON_1, reg16); + x86_pci_write_config16(dev, GEN_PMCON_1, reg16); pch_iobp_update(0xEB007F07, ~0UL, (1 << 31)); pch_iobp_update(0xEB004000, ~0UL, (1 << 7)); @@ -412,15 +413,15 @@ static void pch_lock_smm(pci_dev_t dev) #if TEST_SMM_FLASH_LOCKDOWN /* Now try this: */ debug("Locking BIOS to RO... "); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ + reg8 = x86_pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off", (reg8 & 1) ? "rw" : "ro"); reg8 &= ~(1 << 0); /* clear BIOSWE */ - pci_write_config8(dev, 0xdc, reg8); + x86_pci_write_config8(dev, 0xdc, reg8); reg8 |= (1 << 1); /* set BLE */ - pci_write_config8(dev, 0xdc, reg8); + x86_pci_write_config8(dev, 0xdc, reg8); debug("ok.\n"); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ + reg8 = x86_pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off", (reg8 & 1) ? "rw" : "ro"); @@ -428,9 +429,9 @@ static void pch_lock_smm(pci_dev_t dev) writeb(0, 0xfff00000); debug("Testing:\n"); reg8 |= (1 << 0); /* set BIOSWE */ - pci_write_config8(dev, 0xdc, reg8); + x86_pci_write_config8(dev, 0xdc, reg8); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ + reg8 = x86_pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off", (reg8 & 1) ? "rw" : "ro"); debug("Done.\n"); @@ -443,9 +444,9 @@ static void pch_disable_smm_only_flashing(pci_dev_t dev) u8 reg8; debug("Enabling BIOS updates outside of SMM... "); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ + reg8 = x86_pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ reg8 &= ~(1 << 5); - pci_write_config8(dev, 0xdc, reg8); + x86_pci_write_config8(dev, 0xdc, reg8); } static void pch_fixups(pci_dev_t dev) @@ -453,9 +454,9 @@ static void pch_fixups(pci_dev_t dev) u8 gen_pmcon_2; /* Indicate DRAM init done for MRC S3 to know it can resume */ - gen_pmcon_2 = pci_read_config8(dev, GEN_PMCON_2); + gen_pmcon_2 = x86_pci_read_config8(dev, GEN_PMCON_2); gen_pmcon_2 |= (1 << 7); - pci_write_config8(dev, GEN_PMCON_2, gen_pmcon_2); + x86_pci_write_config8(dev, GEN_PMCON_2, gen_pmcon_2); /* Enable DMI ASPM in the PCH */ clrbits_le32(RCB_REG(0x2304), 1 << 10); @@ -478,10 +479,10 @@ int lpc_early_init(const void *blob, int node, pci_dev_t dev) return -EINVAL; /* Set COM1/COM2 decode range */ - pci_write_config16(dev, LPC_IO_DEC, 0x0010); + x86_pci_write_config16(dev, LPC_IO_DEC, 0x0010); /* Enable PS/2 Keyboard/Mouse, EC areas and COM1 */ - pci_write_config16(dev, LPC_EN, KBC_LPC_EN | MC_LPC_EN | + x86_pci_write_config16(dev, LPC_EN, KBC_LPC_EN | MC_LPC_EN | GAMEL_LPC_EN | COMA_LPC_EN); /* Write all registers but use 0 if we run out of data */ @@ -491,7 +492,7 @@ int lpc_early_init(const void *blob, int node, pci_dev_t dev) if (i < count) reg = ptr->base | PCI_COMMAND_IO | (ptr->size << 16); - pci_write_config32(dev, LPC_GENX_DEC(i), reg); + x86_pci_write_config32(dev, LPC_GENX_DEC(i), reg); } return 0; @@ -509,12 +510,12 @@ int lpc_init(struct pci_controller *hose, pci_dev_t dev) pci_write_bar32(hose, dev, 3, 0x800); pci_write_bar32(hose, dev, 4, 0x900); - node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_LPC); + node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_PCH); if (node < 0) return -ENOENT; /* Set the value for PCI command register. */ - pci_write_config16(dev, PCI_COMMAND, 0x000f); + x86_pci_write_config16(dev, PCI_COMMAND, 0x000f); /* IO APIC initialization. */ pch_enable_apic(dev); @@ -567,3 +568,14 @@ void lpc_enable(pci_dev_t dev) writew(0x0010, RCB_REG(DISPBDF)); setbits_le32(RCB_REG(FD2), PCH_ENABLE_DBDF); } + +static const struct udevice_id bd82x6x_lpc_ids[] = { + { .compatible = "intel,bd82x6x-lpc" }, + { } +}; + +U_BOOT_DRIVER(bd82x6x_lpc_drv) = { + .name = "lpc", + .id = UCLASS_LPC, + .of_match = bd82x6x_lpc_ids, +}; diff --git a/arch/x86/cpu/ivybridge/mrccache.c b/arch/x86/cpu/ivybridge/mrccache.c index 0f1a64b..9205494 100644 --- a/arch/x86/cpu/ivybridge/mrccache.c +++ b/arch/x86/cpu/ivybridge/mrccache.c @@ -105,7 +105,7 @@ static struct mrc_data_container *find_next_mrc_cache(struct fmap_entry *entry, return cache; } -int mrccache_update(struct spi_flash *sf, struct fmap_entry *entry, +int mrccache_update(struct udevice *sf, struct fmap_entry *entry, struct mrc_data_container *cur) { struct mrc_data_container *cache; @@ -135,7 +135,7 @@ int mrccache_update(struct spi_flash *sf, struct fmap_entry *entry, debug("Erasing the MRC cache region of %x bytes at %x\n", entry->length, entry->offset); - ret = spi_flash_erase(sf, entry->offset, entry->length); + ret = spi_flash_erase_dm(sf, entry->offset, entry->length); if (ret) { debug("Failed to erase flash region\n"); return ret; @@ -146,7 +146,8 @@ int mrccache_update(struct spi_flash *sf, struct fmap_entry *entry, /* Write the data out */ offset = (ulong)cache - base_addr + entry->offset; debug("Write MRC cache update to flash at %lx\n", offset); - ret = spi_flash_write(sf, offset, cur->data_size + sizeof(*cur), cur); + ret = spi_flash_write_dm(sf, offset, cur->data_size + sizeof(*cur), + cur); if (ret) { debug("Failed to write to SPI flash\n"); return ret; diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c index c50b5de..e95e60e 100644 --- a/arch/x86/cpu/ivybridge/northbridge.c +++ b/arch/x86/cpu/ivybridge/northbridge.c @@ -30,7 +30,7 @@ int bridge_silicon_revision(void) result = cpuid(1); stepping = result.eax & 0xf; dev = PCI_BDF(0, 0, 0); - bridge_id = pci_read_config16(dev, PCI_DEVICE_ID) & 0xf0; + bridge_id = x86_pci_read_config16(dev, PCI_DEVICE_ID) & 0xf0; bridge_revision_id = bridge_id | stepping; } @@ -55,7 +55,7 @@ static int get_pcie_bar(u32 *base, u32 *len) *base = 0; *len = 0; - pciexbar_reg = pci_read_config32(dev, PCIEXBAR); + pciexbar_reg = x86_pci_read_config32(dev, PCIEXBAR); if (!(pciexbar_reg & (1 << 0))) return 0; @@ -170,7 +170,7 @@ void northbridge_init(pci_dev_t dev) void northbridge_enable(pci_dev_t dev) { #if CONFIG_HAVE_ACPI_RESUME - switch (pci_read_config32(dev, SKPAD)) { + switch (x86_pci_read_config32(dev, SKPAD)) { case 0xcafebabe: debug("Normal boot.\n"); apci_set_slp_type(0); diff --git a/arch/x86/cpu/ivybridge/pch.c b/arch/x86/cpu/ivybridge/pch.c index fa04d48..bbab646 100644 --- a/arch/x86/cpu/ivybridge/pch.c +++ b/arch/x86/cpu/ivybridge/pch.c @@ -21,7 +21,7 @@ int pch_silicon_revision(void) dev = PCH_LPC_DEV; if (pch_revision_id < 0) - pch_revision_id = pci_read_config8(dev, PCI_REVISION_ID); + pch_revision_id = x86_pci_read_config8(dev, PCI_REVISION_ID); return pch_revision_id; } @@ -32,7 +32,7 @@ int pch_silicon_type(void) dev = PCH_LPC_DEV; if (pch_type < 0) - pch_type = pci_read_config8(dev, PCI_DEVICE_ID + 1); + pch_type = x86_pci_read_config8(dev, PCI_DEVICE_ID + 1); return pch_type; } diff --git a/arch/x86/cpu/ivybridge/pci.c b/arch/x86/cpu/ivybridge/pci.c index 452d1c3..5e90f30 100644 --- a/arch/x86/cpu/ivybridge/pci.c +++ b/arch/x86/cpu/ivybridge/pci.c @@ -10,69 +10,30 @@ */ #include <common.h> +#include <dm.h> #include <pci.h> #include <asm/pci.h> +#include <asm/post.h> #include <asm/arch/bd82x6x.h> #include <asm/arch/pch.h> -static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev, - struct pci_config_table *table) -{ - u8 secondary; - - hose->read_byte(hose, dev, PCI_SECONDARY_BUS, &secondary); - if (secondary != 0) - pci_hose_scan_bus(hose, secondary); -} - -static struct pci_config_table pci_ivybridge_config_table[] = { - /* vendor, device, class, bus, dev, func */ - { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI, - PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, &config_pci_bridge }, - {} -}; - -void board_pci_setup_hose(struct pci_controller *hose) -{ - hose->config_table = pci_ivybridge_config_table; - hose->first_busno = 0; - hose->last_busno = 0; - - /* PCI memory space */ - pci_set_region(hose->regions + 0, - CONFIG_PCI_MEM_BUS, - CONFIG_PCI_MEM_PHYS, - CONFIG_PCI_MEM_SIZE, - PCI_REGION_MEM); - - /* PCI IO space */ - pci_set_region(hose->regions + 1, - CONFIG_PCI_IO_BUS, - CONFIG_PCI_IO_PHYS, - CONFIG_PCI_IO_SIZE, - PCI_REGION_IO); - - pci_set_region(hose->regions + 2, - CONFIG_PCI_PREF_BUS, - CONFIG_PCI_PREF_PHYS, - CONFIG_PCI_PREF_SIZE, - PCI_REGION_PREFETCH); - - hose->region_count = 3; -} - -int board_pci_pre_scan(struct pci_controller *hose) +static int pci_ivybridge_probe(struct udevice *bus) { + struct pci_controller *hose = dev_get_uclass_priv(bus); pci_dev_t dev; u16 reg16; + if (!(gd->flags & GD_FLG_RELOC)) + return 0; + post_code(0x50); bd82x6x_init(); + post_code(0x51); reg16 = 0xff; dev = PCH_DEV; - reg16 = pci_read_config16(dev, PCI_COMMAND); + reg16 = x86_pci_read_config16(dev, PCI_COMMAND); reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - pci_write_config16(dev, PCI_COMMAND, reg16); + x86_pci_write_config16(dev, PCI_COMMAND, reg16); /* * Clear non-reserved bits in status register. @@ -82,19 +43,25 @@ int board_pci_pre_scan(struct pci_controller *hose) pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08); pci_write_bar32(hose, dev, 0, 0xf0000000); + post_code(0x52); return 0; } -int board_pci_post_scan(struct pci_controller *hose) -{ - int ret; +static const struct dm_pci_ops pci_ivybridge_ops = { + .read_config = pci_x86_read_config, + .write_config = pci_x86_write_config, +}; - ret = bd82x6x_init_pci_devices(); - if (ret) { - printf("bd82x6x_init_pci_devices() failed: %d\n", ret); - return ret; - } +static const struct udevice_id pci_ivybridge_ids[] = { + { .compatible = "intel,pci-ivybridge" }, + { } +}; - return 0; -} +U_BOOT_DRIVER(pci_ivybridge_drv) = { + .name = "pci_ivybridge", + .id = UCLASS_PCI, + .of_match = pci_ivybridge_ids, + .ops = &pci_ivybridge_ops, + .probe = pci_ivybridge_probe, +}; diff --git a/arch/x86/cpu/ivybridge/report_platform.c b/arch/x86/cpu/ivybridge/report_platform.c index 69e31b3..4493870 100644 --- a/arch/x86/cpu/ivybridge/report_platform.c +++ b/arch/x86/cpu/ivybridge/report_platform.c @@ -70,14 +70,14 @@ static void report_pch_info(void) u16 dev_id; uint8_t rev_id; - dev_id = pci_read_config16(PCH_LPC_DEV, 2); + dev_id = x86_pci_read_config16(PCH_LPC_DEV, 2); for (i = 0; i < ARRAY_SIZE(pch_table); i++) { if (pch_table[i].dev_id == dev_id) { pch_type = pch_table[i].dev_name; break; } } - rev_id = pci_read_config8(PCH_LPC_DEV, 8); + rev_id = x86_pci_read_config8(PCH_LPC_DEV, 8); debug("PCH type: %s, device id: %x, rev id %x\n", pch_type, dev_id, rev_id); } diff --git a/arch/x86/cpu/ivybridge/sata.c b/arch/x86/cpu/ivybridge/sata.c index bbcd47d..e7bf03c 100644 --- a/arch/x86/cpu/ivybridge/sata.c +++ b/arch/x86/cpu/ivybridge/sata.c @@ -14,14 +14,14 @@ static inline u32 sir_read(pci_dev_t dev, int idx) { - pci_write_config32(dev, SATA_SIRI, idx); - return pci_read_config32(dev, SATA_SIRD); + x86_pci_write_config32(dev, SATA_SIRI, idx); + return x86_pci_read_config32(dev, SATA_SIRD); } static inline void sir_write(pci_dev_t dev, int idx, u32 value) { - pci_write_config32(dev, SATA_SIRI, idx); - pci_write_config32(dev, SATA_SIRD, value); + x86_pci_write_config32(dev, SATA_SIRI, idx); + x86_pci_write_config32(dev, SATA_SIRD, value); } static void common_sata_init(pci_dev_t dev, unsigned int port_map) @@ -31,17 +31,17 @@ static void common_sata_init(pci_dev_t dev, unsigned int port_map) /* Set IDE I/O Configuration */ reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0; - pci_write_config32(dev, IDE_CONFIG, reg32); + x86_pci_write_config32(dev, IDE_CONFIG, reg32); /* Port enable */ - reg16 = pci_read_config16(dev, 0x92); + reg16 = x86_pci_read_config16(dev, 0x92); reg16 &= ~0x3f; reg16 |= port_map; - pci_write_config16(dev, 0x92, reg16); + x86_pci_write_config16(dev, 0x92, reg16); /* SATA Initialization register */ port_map &= 0xff; - pci_write_config32(dev, 0x94, ((port_map ^ 0x3f) << 24) | 0x183); + x86_pci_write_config32(dev, 0x94, ((port_map ^ 0x3f) << 24) | 0x183); } void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node) @@ -60,7 +60,7 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node) "sata_interface_speed_support", 0); /* Enable BARs */ - pci_write_config16(dev, PCI_COMMAND, 0x0007); + x86_pci_write_config16(dev, PCI_COMMAND, 0x0007); mode = fdt_getprop(blob, node, "intel,sata-mode", NULL); if (!mode || !strcmp(mode, "ahci")) { @@ -69,18 +69,18 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node) debug("SATA: Controller in AHCI mode\n"); /* Set Interrupt Line, Interrupt Pin is set by D31IP.PIP */ - pci_write_config8(dev, INTR_LN, 0x0a); + x86_pci_write_config8(dev, INTR_LN, 0x0a); /* Set timings */ - pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE | + x86_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE | IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS | IDE_PPE0 | IDE_IE0 | IDE_TIME0); - pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE | + x86_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE | IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS); /* Sync DMA */ - pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0); - pci_write_config16(dev, IDE_SDMA_TIM, 0x0001); + x86_pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0); + x86_pci_write_config16(dev, IDE_SDMA_TIM, 0x0001); common_sata_init(dev, 0x8000 | port_map); @@ -115,22 +115,22 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node) /* No AHCI: clear AHCI base */ pci_write_bar32(hose, dev, 5, 0x00000000); /* And without AHCI BAR no memory decoding */ - reg16 = pci_read_config16(dev, PCI_COMMAND); + reg16 = x86_pci_read_config16(dev, PCI_COMMAND); reg16 &= ~PCI_COMMAND_MEMORY; - pci_write_config16(dev, PCI_COMMAND, reg16); + x86_pci_write_config16(dev, PCI_COMMAND, reg16); - pci_write_config8(dev, 0x09, 0x80); + x86_pci_write_config8(dev, 0x09, 0x80); /* Set timings */ - pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE | + x86_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE | IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS); - pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE | + x86_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE | IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS | IDE_PPE0 | IDE_IE0 | IDE_TIME0); /* Sync DMA */ - pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0); - pci_write_config16(dev, IDE_SDMA_TIM, 0x0200); + x86_pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0); + x86_pci_write_config16(dev, IDE_SDMA_TIM, 0x0200); common_sata_init(dev, port_map); } else { @@ -140,31 +140,32 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node) pci_write_bar32(hose, dev, 5, 0x00000000); /* And without AHCI BAR no memory decoding */ - reg16 = pci_read_config16(dev, PCI_COMMAND); + reg16 = x86_pci_read_config16(dev, PCI_COMMAND); reg16 &= ~PCI_COMMAND_MEMORY; - pci_write_config16(dev, PCI_COMMAND, reg16); + x86_pci_write_config16(dev, PCI_COMMAND, reg16); /* * Native mode capable on both primary and secondary (0xa) * OR'ed with enabled (0x50) = 0xf */ - pci_write_config8(dev, 0x09, 0x8f); + x86_pci_write_config8(dev, 0x09, 0x8f); /* Set Interrupt Line */ /* Interrupt Pin is set by D31IP.PIP */ - pci_write_config8(dev, INTR_LN, 0xff); + x86_pci_write_config8(dev, INTR_LN, 0xff); /* Set timings */ - pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE | + x86_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE | IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS | IDE_PPE0 | IDE_IE0 | IDE_TIME0); - pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE | + x86_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE | IDE_SITRE | IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0); /* Sync DMA */ - pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0); - pci_write_config16(dev, IDE_SDMA_TIM, 0x0201); + x86_pci_write_config16(dev, IDE_SDMA_CNT, + IDE_SSDE0 | IDE_PSDE0); + x86_pci_write_config16(dev, IDE_SDMA_TIM, 0x0201); common_sata_init(dev, port_map); } @@ -221,5 +222,5 @@ void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node) port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0); map |= (port_map ^ 0x3f) << 8; - pci_write_config16(dev, 0x90, map); + x86_pci_write_config16(dev, 0x90, map); } diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c index 766b385..9a6da37 100644 --- a/arch/x86/cpu/ivybridge/sdram.c +++ b/arch/x86/cpu/ivybridge/sdram.c @@ -89,11 +89,12 @@ void dram_init_banksize(void) } } -static int get_mrc_entry(struct spi_flash **sfp, struct fmap_entry *entry) +static int get_mrc_entry(struct udevice **devp, struct fmap_entry *entry) { const void *blob = gd->fdt_blob; int node, spi_node, mrc_node; int upto; + int ret; /* Find the flash chip within the SPI controller node */ upto = 0; @@ -112,10 +113,13 @@ static int get_mrc_entry(struct spi_flash **sfp, struct fmap_entry *entry) if (fdtdec_read_fmap_entry(blob, mrc_node, "rm-mrc-cache", entry)) return -EINVAL; - if (sfp) { - *sfp = spi_flash_probe_fdt(blob, node, spi_node); - if (!*sfp) - return -EBADF; + if (devp) { + debug("getting sf\n"); + ret = uclass_get_device_by_of_offset(UCLASS_SPI_FLASH, node, + devp); + debug("ret = %d\n", ret); + if (ret) + return ret; } return 0; @@ -246,7 +250,7 @@ static int sdram_save_mrc_data(void) { struct mrc_data_container *data; struct fmap_entry entry; - struct spi_flash *sf; + struct udevice *sf; int ret; if (!gd->arch.mrc_output_len) @@ -266,7 +270,6 @@ static int sdram_save_mrc_data(void) free(data); err_data: - spi_flash_free(sf); err_entry: if (ret) debug("%s: Failed: %d\n", __func__, ret); @@ -444,7 +447,7 @@ int sdram_initialise(struct pei_data *pei_data) * Send ME init done for SandyBridge here. This is done inside the * SystemAgent binary on IvyBridge */ - done = pci_read_config32(PCH_DEV, PCI_DEVICE_ID); + done = x86_pci_read_config32(PCH_DEV, PCI_DEVICE_ID); done &= BASE_REV_MASK; if (BASE_REV_SNB == done) intel_early_me_init_done(ME_INIT_STATUS_SUCCESS); @@ -615,24 +618,24 @@ static int sdram_find(pci_dev_t dev) */ /* Top of Upper Usable DRAM, including remap */ - touud = pci_read_config32(dev, TOUUD+4); + touud = x86_pci_read_config32(dev, TOUUD+4); touud <<= 32; - touud |= pci_read_config32(dev, TOUUD); + touud |= x86_pci_read_config32(dev, TOUUD); /* Top of Lower Usable DRAM */ - tolud = pci_read_config32(dev, TOLUD); + tolud = x86_pci_read_config32(dev, TOLUD); /* Top of Memory - does not account for any UMA */ - tom = pci_read_config32(dev, 0xa4); + tom = x86_pci_read_config32(dev, 0xa4); tom <<= 32; - tom |= pci_read_config32(dev, 0xa0); + tom |= x86_pci_read_config32(dev, 0xa0); debug("TOUUD %llx TOLUD %08x TOM %llx\n", touud, tolud, tom); /* ME UMA needs excluding if total memory <4GB */ - me_base = pci_read_config32(dev, 0x74); + me_base = x86_pci_read_config32(dev, 0x74); me_base <<= 32; - me_base |= pci_read_config32(dev, 0x70); + me_base |= x86_pci_read_config32(dev, 0x70); debug("MEBASE %llx\n", me_base); @@ -650,7 +653,7 @@ static int sdram_find(pci_dev_t dev) } /* Graphics memory comes next */ - ggc = pci_read_config16(dev, GGC); + ggc = x86_pci_read_config16(dev, GGC); if (!(ggc & 2)) { debug("IGD decoded, subtracting "); @@ -670,7 +673,7 @@ static int sdram_find(pci_dev_t dev) } /* Calculate TSEG size from its base which must be below GTT */ - tseg_base = pci_read_config32(dev, 0xb8); + tseg_base = x86_pci_read_config32(dev, 0xb8); uma_size = (uma_memory_base - tseg_base) >> 10; tomk -= uma_size; uma_memory_base = tomk * 1024ULL; diff --git a/arch/x86/cpu/ivybridge/usb_ehci.c b/arch/x86/cpu/ivybridge/usb_ehci.c index 291c971..da11aee 100644 --- a/arch/x86/cpu/ivybridge/usb_ehci.c +++ b/arch/x86/cpu/ivybridge/usb_ehci.c @@ -20,10 +20,10 @@ void bd82x6x_usb_ehci_init(pci_dev_t dev) writel(reg32, RCB_REG(0x35b0)); debug("EHCI: Setting up controller.. "); - reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 = x86_pci_read_config32(dev, PCI_COMMAND); reg32 |= PCI_COMMAND_MASTER; /* reg32 |= PCI_COMMAND_SERR; */ - pci_write_config32(dev, PCI_COMMAND, reg32); + x86_pci_write_config32(dev, PCI_COMMAND, reg32); debug("done.\n"); } diff --git a/arch/x86/cpu/ivybridge/usb_xhci.c b/arch/x86/cpu/ivybridge/usb_xhci.c index 4a32a7e..f77b804 100644 --- a/arch/x86/cpu/ivybridge/usb_xhci.c +++ b/arch/x86/cpu/ivybridge/usb_xhci.c @@ -16,17 +16,17 @@ void bd82x6x_usb_xhci_init(pci_dev_t dev) debug("XHCI: Setting up controller.. "); /* lock overcurrent map */ - reg32 = pci_read_config32(dev, 0x44); + reg32 = x86_pci_read_config32(dev, 0x44); reg32 |= 1; - pci_write_config32(dev, 0x44, reg32); + x86_pci_write_config32(dev, 0x44, reg32); /* Enable clock gating */ - reg32 = pci_read_config32(dev, 0x40); + reg32 = x86_pci_read_config32(dev, 0x40); reg32 &= ~((1 << 20) | (1 << 21)); reg32 |= (1 << 19) | (1 << 18) | (1 << 17); reg32 |= (1 << 10) | (1 << 9) | (1 << 8); reg32 |= (1 << 31); /* lock */ - pci_write_config32(dev, 0x40, reg32); + x86_pci_write_config32(dev, 0x40, reg32); debug("done.\n"); } diff --git a/arch/x86/cpu/pci.c b/arch/x86/cpu/pci.c index ab1aaaa..e23b233 100644 --- a/arch/x86/cpu/pci.c +++ b/arch/x86/cpu/pci.c @@ -10,9 +10,11 @@ */ #include <common.h> +#include <dm.h> #include <errno.h> #include <malloc.h> #include <pci.h> +#include <asm/io.h> #include <asm/pci.h> DECLARE_GLOBAL_DATA_PTR; @@ -70,7 +72,7 @@ static struct pci_controller *get_hose(void) return pci_bus_to_hose(0); } -unsigned int pci_read_config8(pci_dev_t dev, unsigned where) +unsigned int x86_pci_read_config8(pci_dev_t dev, unsigned where) { uint8_t value; @@ -79,7 +81,7 @@ unsigned int pci_read_config8(pci_dev_t dev, unsigned where) return value; } -unsigned int pci_read_config16(pci_dev_t dev, unsigned where) +unsigned int x86_pci_read_config16(pci_dev_t dev, unsigned where) { uint16_t value; @@ -88,7 +90,7 @@ unsigned int pci_read_config16(pci_dev_t dev, unsigned where) return value; } -unsigned int pci_read_config32(pci_dev_t dev, unsigned where) +unsigned int x86_pci_read_config32(pci_dev_t dev, unsigned where) { uint32_t value; @@ -97,17 +99,55 @@ unsigned int pci_read_config32(pci_dev_t dev, unsigned where) return value; } -void pci_write_config8(pci_dev_t dev, unsigned where, unsigned value) +void x86_pci_write_config8(pci_dev_t dev, unsigned where, unsigned value) { pci_hose_write_config_byte(get_hose(), dev, where, value); } -void pci_write_config16(pci_dev_t dev, unsigned where, unsigned value) +void x86_pci_write_config16(pci_dev_t dev, unsigned where, unsigned value) { pci_hose_write_config_word(get_hose(), dev, where, value); } -void pci_write_config32(pci_dev_t dev, unsigned where, unsigned value) +void x86_pci_write_config32(pci_dev_t dev, unsigned where, unsigned value) { pci_hose_write_config_dword(get_hose(), dev, where, value); } + +int pci_x86_read_config(struct udevice *bus, pci_dev_t bdf, uint offset, + ulong *valuep, enum pci_size_t size) +{ + outl(bdf | (offset & 0xfc) | PCI_CFG_EN, PCI_REG_ADDR); + switch (size) { + case PCI_SIZE_8: + *valuep = inb(PCI_REG_DATA + (offset & 3)); + break; + case PCI_SIZE_16: + *valuep = inw(PCI_REG_DATA + (offset & 2)); + break; + case PCI_SIZE_32: + *valuep = inl(PCI_REG_DATA); + break; + } + + return 0; +} + +int pci_x86_write_config(struct udevice *bus, pci_dev_t bdf, uint offset, + ulong value, enum pci_size_t size) +{ + outl(bdf | (offset & 0xfc) | PCI_CFG_EN, PCI_REG_ADDR); + switch (size) { + case PCI_SIZE_8: + outb(value, PCI_REG_DATA + (offset & 3)); + break; + case PCI_SIZE_16: + outw(value, PCI_REG_DATA + (offset & 2)); + break; + case PCI_SIZE_32: + outl(value, PCI_REG_DATA); + break; + } + + return 0; +} diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index 25edcf7..e4b19c2 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -30,9 +30,9 @@ static void unprotect_spi_flash(void) { u32 bc; - bc = pci_read_config32(QUARK_LEGACY_BRIDGE, 0xd8); + bc = x86_pci_read_config32(QUARK_LEGACY_BRIDGE, 0xd8); bc |= 0x1; /* unprotect the flash */ - pci_write_config32(QUARK_LEGACY_BRIDGE, 0xd8, bc); + x86_pci_write_config32(QUARK_LEGACY_BRIDGE, 0xd8, bc); } static void quark_setup_bars(void) diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index 30ab725..b7236e7 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -16,9 +16,9 @@ static void unprotect_spi_flash(void) { u32 bc; - bc = pci_read_config32(PCH_LPC_DEV, 0xd8); + bc = x86_pci_read_config32(PCH_LPC_DEV, 0xd8); bc |= 0x1; /* unprotect the flash */ - pci_write_config32(PCH_LPC_DEV, 0xd8, bc); + x86_pci_write_config32(PCH_LPC_DEV, 0xd8, bc); } int arch_cpu_init(void) diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index 7a66133..431bbd8 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -1,4 +1,5 @@ dtb-y += chromebook_link.dtb \ + chromebox_panther.dtb \ crownbay.dtb \ galileo.dtb \ minnowmax.dtb diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts index 45ada61..b450c3c 100644 --- a/arch/x86/dts/chromebook_link.dts +++ b/arch/x86/dts/chromebook_link.dts @@ -8,7 +8,7 @@ compatible = "google,link", "intel,celeron-ivybridge"; aliases { - spi0 = "/spi"; + spi0 = "/pci/pch/spi"; }; config { @@ -151,27 +151,14 @@ }; }; - spi { - #address-cells = <1>; - #size-cells = <0>; - compatible = "intel,ich-spi"; - spi-flash@0 { - #size-cells = <1>; - #address-cells = <1>; - reg = <0>; - compatible = "winbond,w25q64", "spi-flash"; - memory-map = <0xff800000 0x00800000>; - rw-mrc-cache { - label = "rw-mrc-cache"; - /* Alignment: 4k (for updating) */ - reg = <0x003e0000 0x00010000>; - type = "wiped"; - wipe-value = [ff]; - }; - }; - }; - pci { + compatible = "intel,pci-ivybridge", "pci-x86"; + #address-cells = <3>; + #size-cells = <2>; + u-boot,dm-pre-reloc; + ranges = <0x02000000 0x0 0xe0000000 0xe0000000 0 0x10000000 + 0x42000000 0x0 0xd0000000 0xd0000000 0 0x10000000 + 0x01000000 0x0 0x1000 0x1000 0 0xefff>; sata { compatible = "intel,pantherpoint-ahci"; intel,sata-mode = "ahci"; @@ -192,8 +179,10 @@ intel,pch-backlight = <0x04000000>; }; - lpc { - compatible = "intel,lpc"; + pch { + reg = <0x0000f800 0 0 0 0>; + compatible = "intel,bd82x6x"; + u-boot,dm-pre-reloc; #address-cells = <1>; #size-cells = <1>; gen-dec = <0x800 0xfc 0x900 0xfc>; @@ -204,17 +193,44 @@ 1 0 0 0 0 0 0 0>; /* Enable EC SMI source */ intel,alt-gp-smi-enable = <0x0100>; + spi { + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,ich-spi"; + spi-flash@0 { + #size-cells = <1>; + #address-cells = <1>; + reg = <0>; + compatible = "winbond,w25q64", + "spi-flash"; + memory-map = <0xff800000 0x00800000>; + rw-mrc-cache { + label = "rw-mrc-cache"; + reg = <0x003e0000 0x00010000>; + type = "wiped"; + wipe-value = [ff]; + }; + }; + }; - cros-ec@200 { - compatible = "google,cros-ec"; - reg = <0x204 1 0x200 1 0x880 0x80>; - - /* Describes the flash memory within the EC */ + lpc { + compatible = "intel,bd82x6x-lpc"; #address-cells = <1>; - #size-cells = <1>; - flash@8000000 { - reg = <0x08000000 0x20000>; - erase-value = <0xff>; + #size-cells = <0>; + cros-ec@200 { + compatible = "google,cros-ec"; + reg = <0x204 1 0x200 1 0x880 0x80>; + + /* + * Describes the flash memory within + * the EC + */ + #address-cells = <1>; + #size-cells = <1>; + flash@8000000 { + reg = <0x08000000 0x20000>; + erase-value = <0xff>; + }; }; }; }; diff --git a/arch/x86/dts/chromebox_panther.dts b/arch/x86/dts/chromebox_panther.dts new file mode 100644 index 0000000..4eccefd --- /dev/null +++ b/arch/x86/dts/chromebox_panther.dts @@ -0,0 +1,64 @@ +/dts-v1/; + +/include/ "skeleton.dtsi" +/include/ "serial.dtsi" + +/ { + model = "Google Panther"; + compatible = "google,panther", "intel,haswell"; + + aliases { + spi0 = "/spi"; + }; + + config { + silent-console = <0>; + no-keyboard; + }; + + gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x10>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x30 0x10>; + bank-name = "B"; + }; + + gpioc { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x40 0x10>; + bank-name = "C"; + }; + + chosen { + stdout-path = "/serial"; + }; + + spi { + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,ich-spi"; + spi-flash@0 { + #size-cells = <1>; + #address-cells = <1>; + reg = <0>; + compatible = "winbond,w25q64", "spi-flash"; + memory-map = <0xff800000 0x00800000>; + rw-mrc-cache { + label = "rw-mrc-cache"; + /* Alignment: 4k (for updating) */ + reg = <0x003e0000 0x00010000>; + type = "wiped"; + wipe-value = [ff]; + }; + }; + }; + +}; diff --git a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h index e1d9a9b..5ae32f7 100644 --- a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h +++ b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h @@ -12,7 +12,6 @@ void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node); void bd82x6x_pci_init(pci_dev_t dev); void bd82x6x_usb_ehci_init(pci_dev_t dev); void bd82x6x_usb_xhci_init(pci_dev_t dev); -int bd82x6x_init_pci_devices(void); int gma_func0_init(pci_dev_t dev, struct pci_controller *hose, const void *blob, int node); int bd82x6x_init(void); diff --git a/arch/x86/include/asm/arch-ivybridge/mrccache.h b/arch/x86/include/asm/arch-ivybridge/mrccache.h index 968b2ef..1d50ebb 100644 --- a/arch/x86/include/asm/arch-ivybridge/mrccache.h +++ b/arch/x86/include/asm/arch-ivybridge/mrccache.h @@ -20,7 +20,7 @@ __packed struct mrc_data_container { }; struct fmap_entry; -struct spi_flash; +struct udevice; /** * mrccache_find_current() - find the latest MRC cache record @@ -45,7 +45,7 @@ struct mrc_data_container *mrccache_find_current(struct fmap_entry *entry); * @return 0 if updated, -EEXIST if the record is the same as the latest * record, other error if SPI write failed */ -int mrccache_update(struct spi_flash *sf, struct fmap_entry *entry, +int mrccache_update(struct udevice *sf, struct fmap_entry *entry, struct mrc_data_container *cur); #endif diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index a153dd1..a1969ed 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -8,6 +8,8 @@ #ifndef _PCI_I386_H_ #define _PCI_I386_H_ +#include <pci.h> + /* bus mapping constants (used for PCI core initialization) */ #define PCI_REG_ADDR 0xcf8 #define PCI_REG_DATA 0xcfc @@ -48,13 +50,19 @@ int board_pci_post_scan(struct pci_controller *hose); * Simple PCI access routines - these work from either the early PCI hose * or the 'real' one, created after U-Boot has memory available */ -unsigned int pci_read_config8(pci_dev_t dev, unsigned where); -unsigned int pci_read_config16(pci_dev_t dev, unsigned where); -unsigned int pci_read_config32(pci_dev_t dev, unsigned where); +unsigned int x86_pci_read_config8(pci_dev_t dev, unsigned where); +unsigned int x86_pci_read_config16(pci_dev_t dev, unsigned where); +unsigned int x86_pci_read_config32(pci_dev_t dev, unsigned where); + +void x86_pci_write_config8(pci_dev_t dev, unsigned where, unsigned value); +void x86_pci_write_config16(pci_dev_t dev, unsigned where, unsigned value); +void x86_pci_write_config32(pci_dev_t dev, unsigned where, unsigned value); + +int pci_x86_read_config(struct udevice *bus, pci_dev_t bdf, uint offset, + ulong *valuep, enum pci_size_t size); -void pci_write_config8(pci_dev_t dev, unsigned where, unsigned value); -void pci_write_config16(pci_dev_t dev, unsigned where, unsigned value); -void pci_write_config32(pci_dev_t dev, unsigned where, unsigned value); +int pci_x86_write_config(struct udevice *bus, pci_dev_t bdf, uint offset, + ulong value, enum pci_size_t size); #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index c17f7f0..6c571dd 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -14,10 +14,14 @@ obj-$(CONFIG_HAVE_FSP) += cmd_hob.o obj-y += gcc.o obj-y += init_helpers.o obj-y += interrupts.o +obj-y += lpc-uclass.o obj-y += cmd_mtrr.o obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o +ifndef CONFIG_DM_PCI obj-$(CONFIG_PCI) += pci_type1.o +endif +obj-y += pch-uclass.o obj-y += relocate.o obj-y += physmem.o obj-$(CONFIG_X86_RAMTEST) += ramtest.o diff --git a/arch/x86/lib/bios_interrupts.c b/arch/x86/lib/bios_interrupts.c index b0e2ecb..290990a 100644 --- a/arch/x86/lib/bios_interrupts.c +++ b/arch/x86/lib/bios_interrupts.c @@ -172,28 +172,28 @@ int int1a_handler(void) } switch (func) { case 0xb108: /* Read Config Byte */ - byte = pci_read_config8(dev, reg); + byte = x86_pci_read_config8(dev, reg); M.x86.R_ECX = byte; break; case 0xb109: /* Read Config Word */ - word = pci_read_config16(dev, reg); + word = x86_pci_read_config16(dev, reg); M.x86.R_ECX = word; break; case 0xb10a: /* Read Config Dword */ - dword = pci_read_config32(dev, reg); + dword = x86_pci_read_config32(dev, reg); M.x86.R_ECX = dword; break; case 0xb10b: /* Write Config Byte */ byte = M.x86.R_ECX; - pci_write_config8(dev, reg, byte); + x86_pci_write_config8(dev, reg, byte); break; case 0xb10c: /* Write Config Word */ word = M.x86.R_ECX; - pci_write_config16(dev, reg, word); + x86_pci_write_config16(dev, reg, word); break; case 0xb10d: /* Write Config Dword */ dword = M.x86.R_ECX; - pci_write_config32(dev, reg, dword); + x86_pci_write_config32(dev, reg, dword); break; } diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index 5097ca2..4fd47fc 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -89,11 +89,3 @@ int init_bd_struct_r(void) return 0; } - -int init_func_spi(void) -{ - puts("SPI: "); - spi_init(); - puts("ready\n"); - return 0; -} diff --git a/arch/x86/lib/lpc-uclass.c b/arch/x86/lib/lpc-uclass.c new file mode 100644 index 0000000..6aeb4d4 --- /dev/null +++ b/arch/x86/lib/lpc-uclass.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <dm/root.h> + +static int lpc_uclass_post_bind(struct udevice *bus) +{ + /* + * Scan the device tree for devices + * + * Before relocation, only bind devices marked for pre-relocation + * use. + */ + return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset, + gd->flags & GD_FLG_RELOC ? false : true); +} + +UCLASS_DRIVER(lpc) = { + .id = UCLASS_LPC, + .name = "lpc", + .post_bind = lpc_uclass_post_bind, +}; diff --git a/arch/x86/lib/pch-uclass.c b/arch/x86/lib/pch-uclass.c new file mode 100644 index 0000000..d1082e1 --- /dev/null +++ b/arch/x86/lib/pch-uclass.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <dm/root.h> + +static int pch_uclass_post_bind(struct udevice *bus) +{ + /* + * Scan the device tree for devices + * + * Before relocation, only bind devices marked for pre-relocation + * use. + */ + return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset, + gd->flags & GD_FLG_RELOC ? false : true); +} + +UCLASS_DRIVER(pch) = { + .id = UCLASS_PCH, + .name = "pch", + .post_bind = pch_uclass_post_bind, +}; diff --git a/board/BuR/common/common.c b/board/BuR/common/common.c index ccaa9c6..23a98e4 100644 --- a/board/BuR/common/common.c +++ b/board/BuR/common/common.c @@ -33,13 +33,14 @@ #endif #include "bur_common.h" #include "../../../drivers/video/am335x-fb.h" +#include <nand.h> static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_USE_FDT - #define FDTPROP(a, b, c) fdt_getprop_u32_default((void *)a, b, c, ~0UL) + #define FDTPROP(b, c) fdt_getprop_u32_default(gd->fdt_blob, b, c, ~0UL) #define PATHTIM "/panel/display-timings/default" #define PATHINF "/panel/panel-info" #endif @@ -50,51 +51,50 @@ int load_lcdtiming(struct am335x_lcdpanel *panel) { struct am335x_lcdpanel pnltmp; #ifdef CONFIG_USE_FDT - u32 dtbaddr = getenv_ulong("dtbaddr", 16, ~0UL); u32 dtbprop; - if (dtbaddr == ~0UL) { - puts("load_lcdtiming: failed to get 'dtbaddr' from env!\n"); + if (gd->fdt_blob == NULL) { + printf("%s: don't have a valid gd->fdt_blob!\n", __func__); return -1; } memcpy(&pnltmp, (void *)panel, sizeof(struct am335x_lcdpanel)); - pnltmp.hactive = FDTPROP(dtbaddr, PATHTIM, "hactive"); - pnltmp.vactive = FDTPROP(dtbaddr, PATHTIM, "vactive"); - pnltmp.bpp = FDTPROP(dtbaddr, PATHINF, "bpp"); - pnltmp.hfp = FDTPROP(dtbaddr, PATHTIM, "hfront-porch"); - pnltmp.hbp = FDTPROP(dtbaddr, PATHTIM, "hback-porch"); - pnltmp.hsw = FDTPROP(dtbaddr, PATHTIM, "hsync-len"); - pnltmp.vfp = FDTPROP(dtbaddr, PATHTIM, "vfront-porch"); - pnltmp.vbp = FDTPROP(dtbaddr, PATHTIM, "vback-porch"); - pnltmp.vsw = FDTPROP(dtbaddr, PATHTIM, "vsync-len"); - pnltmp.pup_delay = FDTPROP(dtbaddr, PATHTIM, "pupdelay"); - pnltmp.pon_delay = FDTPROP(dtbaddr, PATHTIM, "pondelay"); + pnltmp.hactive = FDTPROP(PATHTIM, "hactive"); + pnltmp.vactive = FDTPROP(PATHTIM, "vactive"); + pnltmp.bpp = FDTPROP(PATHINF, "bpp"); + pnltmp.hfp = FDTPROP(PATHTIM, "hfront-porch"); + pnltmp.hbp = FDTPROP(PATHTIM, "hback-porch"); + pnltmp.hsw = FDTPROP(PATHTIM, "hsync-len"); + pnltmp.vfp = FDTPROP(PATHTIM, "vfront-porch"); + pnltmp.vbp = FDTPROP(PATHTIM, "vback-porch"); + pnltmp.vsw = FDTPROP(PATHTIM, "vsync-len"); + pnltmp.pup_delay = FDTPROP(PATHTIM, "pupdelay"); + pnltmp.pon_delay = FDTPROP(PATHTIM, "pondelay"); /* calc. proper clk-divisor */ - dtbprop = FDTPROP(dtbaddr, PATHTIM, "clock-frequency"); + dtbprop = FDTPROP(PATHTIM, "clock-frequency"); if (dtbprop != ~0UL) pnltmp.pxl_clk_div = 192000000 / dtbprop; else pnltmp.pxl_clk_div = ~0UL; /* check polarity of control-signals */ - dtbprop = FDTPROP(dtbaddr, PATHTIM, "hsync-active"); + dtbprop = FDTPROP(PATHTIM, "hsync-active"); if (dtbprop == 0) pnltmp.pol |= HSYNC_INVERT; - dtbprop = FDTPROP(dtbaddr, PATHTIM, "vsync-active"); + dtbprop = FDTPROP(PATHTIM, "vsync-active"); if (dtbprop == 0) pnltmp.pol |= VSYNC_INVERT; - dtbprop = FDTPROP(dtbaddr, PATHINF, "sync-ctrl"); + dtbprop = FDTPROP(PATHINF, "sync-ctrl"); if (dtbprop == 1) pnltmp.pol |= HSVS_CONTROL; - dtbprop = FDTPROP(dtbaddr, PATHINF, "sync-edge"); + dtbprop = FDTPROP(PATHINF, "sync-edge"); if (dtbprop == 1) pnltmp.pol |= HSVS_RISEFALL; - dtbprop = FDTPROP(dtbaddr, PATHTIM, "pixelclk-active"); + dtbprop = FDTPROP(PATHTIM, "pixelclk-active"); if (dtbprop == 0) pnltmp.pol |= PXCLK_INVERT; - dtbprop = FDTPROP(dtbaddr, PATHTIM, "de-active"); + dtbprop = FDTPROP(PATHTIM, "de-active"); if (dtbprop == 0) pnltmp.pol |= DE_INVERT; #else @@ -160,14 +160,24 @@ int load_lcdtiming(struct am335x_lcdpanel *panel) #ifdef CONFIG_USE_FDT static int load_devicetree(void) { + int rc; + loff_t dtbsize; + u32 dtbaddr = getenv_ulong("dtbaddr", 16, 0UL); + + if (dtbaddr == 0) { + printf("%s: don't have a valid <dtbaddr> in env!\n", __func__); + return -1; + } +#ifdef CONFIG_NAND + dtbsize = 0x20000; + rc = nand_read_skip_bad(&nand_info[0], 0x40000, (size_t *)&dtbsize, + NULL, 0x20000, (u_char *)dtbaddr); +#else char *dtbname = getenv("dtb"); char *dtbdev = getenv("dtbdev"); char *dtppart = getenv("dtbpart"); - u32 dtbaddr = getenv_ulong("dtbaddr", 16, ~0UL); - loff_t dtbsize; - - if (!dtbdev || !dtbdev) { - puts("load_devicetree: <dtbdev>/<dtbpart> missing.\n"); + if (!dtbdev || !dtbdev || !dtbname) { + printf("%s: <dtbdev>/<dtbpart>/<dtb> missing.\n", __func__); return -1; } @@ -175,18 +185,17 @@ static int load_devicetree(void) puts("load_devicetree: set_blk_dev failed.\n"); return -1; } - if (dtbname && dtbaddr != ~0UL) { - if (fs_read(dtbname, dtbaddr, 0, 0, &dtbsize) == 0) { - gd->fdt_blob = (void *)dtbaddr; - gd->fdt_size = dtbsize; - debug("loaded %d bytes of dtb onto 0x%08x\n", - (u32)dtbsize, dtbaddr); - return dtbsize; - } - puts("load_devicetree: load dtb failed,file does not exist!\n"); + rc = fs_read(dtbname, (u32)dtbaddr, 0, 0, &dtbsize); +#endif + if (rc == 0) { + gd->fdt_blob = (void *)dtbaddr; + gd->fdt_size = dtbsize; + debug("loaded %d bytes of dtb onto 0x%08x\n", + (u32)dtbsize, (u32)gd->fdt_blob); + return dtbsize; } - puts("load_devicetree: <dtb>/<dtbaddr> missing!\n"); + printf("%s: load dtb failed!\n", __func__); return -1; } @@ -196,27 +205,26 @@ static const char *dtbmacaddr(u32 ifno) char enet[16]; const char *mac; const char *path; - u32 dtbaddr = getenv_ulong("dtbaddr", 16, ~0UL); - if (dtbaddr == ~0UL) { - puts("dtbmacaddr: failed to get 'dtbaddr' from env!\n"); + if (gd->fdt_blob == NULL) { + printf("%s: don't have a valid gd->fdt_blob!\n", __func__); return NULL; } - node = fdt_path_offset((void *)dtbaddr, "/aliases"); + node = fdt_path_offset(gd->fdt_blob, "/aliases"); if (node < 0) return NULL; sprintf(enet, "ethernet%d", ifno); - path = fdt_getprop((void *)dtbaddr, node, enet, NULL); + path = fdt_getprop(gd->fdt_blob, node, enet, NULL); if (!path) { printf("no alias for %s\n", enet); return NULL; } - node = fdt_path_offset((void *)dtbaddr, path); - mac = fdt_getprop((void *)dtbaddr, node, "mac-address", &len); - if (mac && is_valid_ether_addr((u8 *)mac)) + node = fdt_path_offset(gd->fdt_blob, path); + mac = fdt_getprop(gd->fdt_blob, node, "mac-address", &len); + if (mac && is_valid_ethaddr((u8 *)mac)) return mac; return NULL; @@ -226,15 +234,14 @@ static void br_summaryscreen_printdtb(char *prefix, char *name, char *suffix) { - u32 dtbaddr = getenv_ulong("dtbaddr", 16, ~0UL); char buf[32] = { 0 }; const char *nodep = buf; char *mac = 0; int nodeoffset; int len; - if (dtbaddr == ~0UL) { - puts("br_summaryscreen: failed to get 'dtbaddr' from env!\n"); + if (gd->fdt_blob == NULL) { + printf("%s: don't have a valid gd->fdt_blob!\n", __func__); return; } @@ -247,13 +254,13 @@ static void br_summaryscreen_printdtb(char *prefix, if (mac) sprintf(buf, "%pM", mac); } else { - nodeoffset = fdt_path_offset((void *)dtbaddr, + nodeoffset = fdt_path_offset(gd->fdt_blob, "/factory-settings"); if (nodeoffset < 0) { puts("no 'factory-settings' in dtb!\n"); return; } - nodep = fdt_getprop((void *)dtbaddr, nodeoffset, name, &len); + nodep = fdt_getprop(gd->fdt_blob, nodeoffset, name, &len); } if (nodep && strlen(nodep) > 1) lcd_printf("%s %s %s", prefix, nodep, suffix); @@ -318,13 +325,11 @@ void lcdpower(int on) { u32 pin, swval, i; #ifdef CONFIG_USE_FDT - u32 dtbaddr = getenv_ulong("dtbaddr", 16, ~0UL); - - if (dtbaddr == ~0UL) { - puts("lcdpower: failed to get 'dtbaddr' from env!\n"); + if (gd->fdt_blob == NULL) { + printf("%s: don't have a valid gd->fdt_blob!\n", __func__); return; } - pin = FDTPROP(dtbaddr, PATHINF, "pwrpin"); + pin = FDTPROP(PATHINF, "pwrpin"); #else pin = getenv_ulong("ds1_pwr", 16, ~0UL); #endif @@ -385,15 +390,13 @@ void lcd_ctrl_init(void *lcdbase) void lcd_enable(void) { #ifdef CONFIG_USE_FDT - u32 dtbaddr = getenv_ulong("dtbaddr", 16, ~0UL); - - if (dtbaddr == ~0UL) { - puts("lcdpower: failed to get 'dtbaddr' from env!\n"); + if (gd->fdt_blob == NULL) { + printf("%s: don't have a valid gd->fdt_blob!\n", __func__); return; } - unsigned int driver = FDTPROP(dtbaddr, PATHINF, "brightdrv"); - unsigned int bright = FDTPROP(dtbaddr, PATHINF, "brightdef"); - unsigned int pwmfrq = FDTPROP(dtbaddr, PATHINF, "brightfdim"); + unsigned int driver = FDTPROP(PATHINF, "brightdrv"); + unsigned int bright = FDTPROP(PATHINF, "brightdef"); + unsigned int pwmfrq = FDTPROP(PATHINF, "brightfdim"); #else unsigned int driver = getenv_ulong("ds1_bright_drv", 16, 0UL); unsigned int bright = getenv_ulong("ds1_bright_def", 10, 50); @@ -595,7 +598,7 @@ int board_eth_init(bd_t *bis) #endif if (!mac) { printf("<ethaddr> not set. validating E-fuse MAC ... "); - if (is_valid_ether_addr((const u8 *)mac_addr)) + if (is_valid_ethaddr((const u8 *)mac_addr)) mac = (const char *)mac_addr; } diff --git a/board/BuR/tseries/board.c b/board/BuR/tseries/board.c index 89e989f..d1d698e 100644 --- a/board/BuR/tseries/board.c +++ b/board/BuR/tseries/board.c @@ -128,6 +128,9 @@ void am33xx_spl_board_init(void) i2c_set_bus_num(0); i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE); pmicsetup(0); + + gpio_direction_output(64+29, 1); /* switch NAND_RnB to GPMC_WAIT1 */ + gpio_direction_output(64+28, 1); /* switch MII2_CRS to GPMC_WAIT0 */ } const struct dpll_params *get_dpll_ddr_params(void) diff --git a/board/BuR/tseries/mux.c b/board/BuR/tseries/mux.c index ac7e885..c5dc4b7 100644 --- a/board/BuR/tseries/mux.c +++ b/board/BuR/tseries/mux.c @@ -17,8 +17,10 @@ #include <i2c.h> static struct module_pin_mux uart0_pin_mux[] = { + /* UART0_RTS */ + {OFFSET(uart0_rtsn), (MODE(0) | PULLUDEN)}, /* UART0_CTS */ - {OFFSET(uart0_ctsn), (MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + {OFFSET(uart0_ctsn), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* UART0_RXD */ {OFFSET(uart0_rxd), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* UART0_TXD */ @@ -26,9 +28,13 @@ static struct module_pin_mux uart0_pin_mux[] = { {-1}, }; static struct module_pin_mux uart1_pin_mux[] = { - /* UART0_RXD */ + /* UART1_RTS as I2C2-SCL */ + {OFFSET(uart1_rtsn), (MODE(3) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + /* UART1_CTS as I2C2-SDA */ + {OFFSET(uart1_ctsn), (MODE(3) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + /* UART1_RXD */ {OFFSET(uart1_rxd), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, - /* UART0_TXD */ + /* UART1_TXD */ {OFFSET(uart1_txd), (MODE(0) | PULLUDEN)}, {-1}, }; @@ -123,7 +129,7 @@ static struct module_pin_mux nand_pin_mux[] = { {OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD5 */ {OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD6 */ {OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD7 */ - {OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */ + {OFFSET(gpmc_clk), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */ {OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN | RXACTIVE)}, /* NAND_WPN */ {OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)}, /* NAND_CS0 */ {OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)}, /* NAND_ADV_ALE */ diff --git a/board/BuS/eb_cpu5282/u-boot.lds b/board/BuS/eb_cpu5282/u-boot.lds deleted file mode 100644 index 0df2a0a..0000000 --- a/board/BuS/eb_cpu5282/u-boot.lds +++ /dev/null @@ -1,82 +0,0 @@ -/* - * (C) Copyright 2000-2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - .text : - { - arch/m68k/cpu/mcf52x2/start.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/BuS/eb_cpux9k2/cpux9k2.c b/board/BuS/eb_cpux9k2/cpux9k2.c index 76ad7c4..3880a06 100644 --- a/board/BuS/eb_cpux9k2/cpux9k2.c +++ b/board/BuS/eb_cpux9k2/cpux9k2.c @@ -111,7 +111,7 @@ int misc_init_r(void) void reset_phy(void) { udelay(10000); - eth_init(gd->bd); + eth_init(); } #endif diff --git a/board/BuS/vl_ma2sc/vl_ma2sc.c b/board/BuS/vl_ma2sc/vl_ma2sc.c index da39c86..e4e1a85 100644 --- a/board/BuS/vl_ma2sc/vl_ma2sc.c +++ b/board/BuS/vl_ma2sc/vl_ma2sc.c @@ -280,7 +280,7 @@ void reset_phy(void) * Initialize ethernet HW addr prior to starting Linux, * needed for nfsroot */ - eth_init(gd->bd); + eth_init(); #endif } #endif diff --git a/board/ait/cam_enc_4xx/cam_enc_4xx.c b/board/ait/cam_enc_4xx/cam_enc_4xx.c index 290dc19..c5687ba 100644 --- a/board/ait/cam_enc_4xx/cam_enc_4xx.c +++ b/board/ait/cam_enc_4xx/cam_enc_4xx.c @@ -70,7 +70,7 @@ static int cam_enc_4xx_check_network(void) if (!s) return -EINVAL; - if (!is_valid_ether_addr((const u8 *)s)) + if (!is_valid_ethaddr((const u8 *)s)) return -EINVAL; s = getenv("ipaddr"); diff --git a/board/alphaproject/ap_sh4a_4a/ap_sh4a_4a.c b/board/alphaproject/ap_sh4a_4a/ap_sh4a_4a.c index b81a68d..e65befc 100644 --- a/board/alphaproject/ap_sh4a_4a/ap_sh4a_4a.c +++ b/board/alphaproject/ap_sh4a_4a/ap_sh4a_4a.c @@ -167,7 +167,7 @@ int board_late_init(void) /* Read MAC address */ i2c_read(0x50, 0x0, 0, mac, 6); - if (is_valid_ether_addr(mac)) + if (is_valid_ethaddr(mac)) eth_setenv_enetaddr("ethaddr", mac); return 0; diff --git a/board/altera/socfpga/pinmux_config.c b/board/altera/socfpga/pinmux_config.c index 61cdc73..7e7a184 100644 --- a/board/altera/socfpga/pinmux_config.c +++ b/board/altera/socfpga/pinmux_config.c @@ -54,8 +54,8 @@ unsigned long sys_mgr_init_table[CONFIG_HPS_PINMUX_NUM] = { 2, /* GENERALIO14 */ 0, /* GENERALIO15 */ 0, /* GENERALIO16 */ - 0, /* GENERALIO17 */ - 0, /* GENERALIO18 */ + 2, /* GENERALIO17 */ + 2, /* GENERALIO18 */ 0, /* GENERALIO19 */ 0, /* GENERALIO20 */ 0, /* GENERALIO21 */ diff --git a/board/altera/socfpga/pll_config.h b/board/altera/socfpga/pll_config.h index 8130fa4..7cd25df 100644 --- a/board/altera/socfpga/pll_config.h +++ b/board/altera/socfpga/pll_config.h @@ -36,7 +36,7 @@ /* Peripheral PLL */ #define CONFIG_HPS_PERPLLGRP_VCO_DENOM (1) -#define CONFIG_HPS_PERPLLGRP_VCO_NUMER (39) +#define CONFIG_HPS_PERPLLGRP_VCO_NUMER (79) /* * To tell where is the VCOs source: * 0 = EOSC1 diff --git a/board/altera/socfpga/socfpga.c b/board/altera/socfpga/socfpga.c index 20d2216..a1dbc49 100644 --- a/board/altera/socfpga/socfpga.c +++ b/board/altera/socfpga/socfpga.c @@ -18,6 +18,8 @@ DECLARE_GLOBAL_DATA_PTR; +void s_init(void) {} + /* * Miscellaneous platform dependent initialisations */ diff --git a/board/amcc/canyonlands/Kconfig b/board/amcc/canyonlands/Kconfig index 46efa7a..ef66ad4 100644 --- a/board/amcc/canyonlands/Kconfig +++ b/board/amcc/canyonlands/Kconfig @@ -33,10 +33,4 @@ config DISPLAY_BOARDINFO bool default y -config DM - default y - -config DM_SERIAL - default y - endif diff --git a/board/armltd/integrator/Kconfig b/board/armltd/integrator/Kconfig deleted file mode 100644 index 6153b5d..0000000 --- a/board/armltd/integrator/Kconfig +++ /dev/null @@ -1,103 +0,0 @@ -if TARGET_INTEGRATORAP_CM720T - -config SYS_BOARD - default "integrator" - -config SYS_VENDOR - default "armltd" - -config SYS_CONFIG_NAME - default "integratorap" - -endif - -if TARGET_INTEGRATORAP_CM920T - -config SYS_BOARD - default "integrator" - -config SYS_VENDOR - default "armltd" - -config SYS_CONFIG_NAME - default "integratorap" - -endif - -if TARGET_INTEGRATORCP_CM920T - -config SYS_BOARD - default "integrator" - -config SYS_VENDOR - default "armltd" - -config SYS_CONFIG_NAME - default "integratorcp" - -endif - -if TARGET_INTEGRATORAP_CM926EJS - -config SYS_BOARD - default "integrator" - -config SYS_VENDOR - default "armltd" - -config SYS_CONFIG_NAME - default "integratorap" - -endif - -if TARGET_INTEGRATORCP_CM926EJS - -config SYS_BOARD - default "integrator" - -config SYS_VENDOR - default "armltd" - -config SYS_CONFIG_NAME - default "integratorcp" - -endif - -if TARGET_INTEGRATORCP_CM1136 - -config SYS_BOARD - default "integrator" - -config SYS_VENDOR - default "armltd" - -config SYS_CONFIG_NAME - default "integratorcp" - -endif - -if TARGET_INTEGRATORAP_CM946ES - -config SYS_BOARD - default "integrator" - -config SYS_VENDOR - default "armltd" - -config SYS_CONFIG_NAME - default "integratorap" - -endif - -if TARGET_INTEGRATORCP_CM946ES - -config SYS_BOARD - default "integrator" - -config SYS_VENDOR - default "armltd" - -config SYS_CONFIG_NAME - default "integratorcp" - -endif diff --git a/board/armltd/integrator/integrator.c b/board/armltd/integrator/integrator.c index f0fe0fd..e94ac85 100644 --- a/board/armltd/integrator/integrator.c +++ b/board/armltd/integrator/integrator.c @@ -54,8 +54,6 @@ int board_init (void) /* adress of boot parameters */ gd->bd->bi_boot_params = 0x00000100; - gd->flags = 0; - #ifdef CONFIG_CM_REMAP extern void cm_remap(void); cm_remap(); /* remaps writeable memory to 0x00000000 */ diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c index 13dd667..7cb4e00 100644 --- a/board/armltd/vexpress64/vexpress64.c +++ b/board/armltd/vexpress64/vexpress64.c @@ -19,7 +19,7 @@ DECLARE_GLOBAL_DATA_PTR; static const struct pl01x_serial_platdata serial_platdata = { .base = V2M_UART0, .type = TYPE_PL011, - .clock = 2400 * 1000, + .clock = CONFIG_PL011_CLOCK, }; U_BOOT_DEVICE(vexpress_serials) = { diff --git a/board/astro/mcf5373l/u-boot.lds b/board/astro/mcf5373l/u-boot.lds deleted file mode 100644 index 8ef0620..0000000 --- a/board/astro/mcf5373l/u-boot.lds +++ /dev/null @@ -1,86 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf532x/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss : - { - _sbss = .; - *(.sbss*) - *(.bss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/atmel/at91sam9261ek/at91sam9261ek.c b/board/atmel/at91sam9261ek/at91sam9261ek.c index a301d72..5250474 100644 --- a/board/atmel/at91sam9261ek/at91sam9261ek.c +++ b/board/atmel/at91sam9261ek/at91sam9261ek.c @@ -275,7 +275,7 @@ void reset_phy(void) * Initialize ethernet HW addr prior to starting Linux, * needed for nfsroot */ - eth_init(gd->bd); + eth_init(); #endif } #endif diff --git a/board/bct-brettl2/bct-brettl2.c b/board/bct-brettl2/bct-brettl2.c index 6be9b18..1f0dfb4 100644 --- a/board/bct-brettl2/bct-brettl2.c +++ b/board/bct-brettl2/bct-brettl2.c @@ -32,7 +32,7 @@ int checkboard(void) static void board_init_enetaddr(uchar *mac_addr) { puts("Warning: Generating 'random' MAC address\n"); - eth_random_addr(mac_addr); + net_random_ethaddr(mac_addr); eth_setenv_enetaddr("ethaddr", mac_addr); } diff --git a/board/bf518f-ezbrd/bf518f-ezbrd.c b/board/bf518f-ezbrd/bf518f-ezbrd.c index 3a94a57..8ecfbb2 100644 --- a/board/bf518f-ezbrd/bf518f-ezbrd.c +++ b/board/bf518f-ezbrd/bf518f-ezbrd.c @@ -39,7 +39,7 @@ static void board_init_enetaddr(uchar *mac_addr) if (USE_MAC_IN_FLASH) { /* we cram the MAC in the last flash sector */ uchar *board_mac_addr = (uchar *)0x203F0096; - if (is_valid_ether_addr(board_mac_addr)) { + if (is_valid_ethaddr(board_mac_addr)) { memcpy(mac_addr, board_mac_addr, 6); valid_mac = true; } @@ -47,7 +47,7 @@ static void board_init_enetaddr(uchar *mac_addr) if (!valid_mac) { puts("Warning: Generating 'random' MAC address\n"); - eth_random_addr(mac_addr); + net_random_ethaddr(mac_addr); } eth_setenv_enetaddr("ethaddr", mac_addr); diff --git a/board/bf526-ezbrd/bf526-ezbrd.c b/board/bf526-ezbrd/bf526-ezbrd.c index 368d6be..0a88491 100644 --- a/board/bf526-ezbrd/bf526-ezbrd.c +++ b/board/bf526-ezbrd/bf526-ezbrd.c @@ -36,7 +36,7 @@ static void board_init_enetaddr(uchar *mac_addr) if (USE_MAC_IN_FLASH) { /* we cram the MAC in the last flash sector */ uchar *board_mac_addr = (uchar *)0x203F0096; - if (is_valid_ether_addr(board_mac_addr)) { + if (is_valid_ethaddr(board_mac_addr)) { memcpy(mac_addr, board_mac_addr, 6); valid_mac = true; } @@ -44,7 +44,7 @@ static void board_init_enetaddr(uchar *mac_addr) if (!valid_mac) { puts("Warning: Generating 'random' MAC address\n"); - eth_random_addr(mac_addr); + net_random_ethaddr(mac_addr); } eth_setenv_enetaddr("ethaddr", mac_addr); diff --git a/board/bf527-ezkit/bf527-ezkit.c b/board/bf527-ezkit/bf527-ezkit.c index 88e1869..257775f 100644 --- a/board/bf527-ezkit/bf527-ezkit.c +++ b/board/bf527-ezkit/bf527-ezkit.c @@ -40,13 +40,13 @@ static void board_init_enetaddr(uchar *mac_addr) for (ret = 0; ret < 6; ++ret) mac_addr[ret] = otp_mac_p[5 - ret]; - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) valid_mac = true; } if (!valid_mac) { puts("Warning: Generating 'random' MAC address\n"); - eth_random_addr(mac_addr); + net_random_ethaddr(mac_addr); } eth_setenv_enetaddr("ethaddr", mac_addr); diff --git a/board/bf537-minotaur/bf537-minotaur.c b/board/bf537-minotaur/bf537-minotaur.c index ca61ef9..71b4293 100644 --- a/board/bf537-minotaur/bf537-minotaur.c +++ b/board/bf537-minotaur/bf537-minotaur.c @@ -26,7 +26,7 @@ int checkboard(void) static void board_init_enetaddr(uchar *mac_addr) { puts("Warning: Generating 'random' MAC address\n"); - eth_random_addr(mac_addr); + net_random_ethaddr(mac_addr); eth_setenv_enetaddr("ethaddr", mac_addr); } diff --git a/board/bf537-pnav/bf537-pnav.c b/board/bf537-pnav/bf537-pnav.c index df00110..93522df 100644 --- a/board/bf537-pnav/bf537-pnav.c +++ b/board/bf537-pnav/bf537-pnav.c @@ -26,7 +26,7 @@ int checkboard(void) static void board_init_enetaddr(uchar *mac_addr) { puts("Warning: Generating 'random' MAC address\n"); - eth_random_addr(mac_addr); + net_random_ethaddr(mac_addr); eth_setenv_enetaddr("ethaddr", mac_addr); } diff --git a/board/bf537-srv1/bf537-srv1.c b/board/bf537-srv1/bf537-srv1.c index 725296a..6581028 100644 --- a/board/bf537-srv1/bf537-srv1.c +++ b/board/bf537-srv1/bf537-srv1.c @@ -26,7 +26,7 @@ int checkboard(void) static void board_init_enetaddr(uchar *mac_addr) { puts("Warning: Generating 'random' MAC address\n"); - eth_random_addr(mac_addr); + net_random_ethaddr(mac_addr); eth_setenv_enetaddr("ethaddr", mac_addr); } diff --git a/board/bf537-stamp/bf537-stamp.c b/board/bf537-stamp/bf537-stamp.c index 32045a9..66e5492 100644 --- a/board/bf537-stamp/bf537-stamp.c +++ b/board/bf537-stamp/bf537-stamp.c @@ -39,7 +39,7 @@ static void board_init_enetaddr(uchar *mac_addr) if (USE_MAC_IN_FLASH) { /* we cram the MAC in the last flash sector */ uchar *board_mac_addr = (uchar *)0x203F0000; - if (is_valid_ether_addr(board_mac_addr)) { + if (is_valid_ethaddr(board_mac_addr)) { memcpy(mac_addr, board_mac_addr, 6); valid_mac = true; } @@ -47,7 +47,7 @@ static void board_init_enetaddr(uchar *mac_addr) if (!valid_mac) { puts("Warning: Generating 'random' MAC address\n"); - eth_random_addr(mac_addr); + net_random_ethaddr(mac_addr); } eth_setenv_enetaddr("ethaddr", mac_addr); diff --git a/board/bf609-ezkit/bf609-ezkit.c b/board/bf609-ezkit/bf609-ezkit.c index 43a4330..86da028 100644 --- a/board/bf609-ezkit/bf609-ezkit.c +++ b/board/bf609-ezkit/bf609-ezkit.c @@ -33,7 +33,7 @@ int board_early_init_f(void) return 0; } -#ifdef CONFIG_DESIGNWARE_ETH +#ifdef CONFIG_ETH_DESIGNWARE int board_eth_init(bd_t *bis) { int ret = 0; diff --git a/board/birdland/bav335x/board.c b/board/birdland/bav335x/board.c index d1e1c8c..32ff7a4 100644 --- a/board/birdland/bav335x/board.c +++ b/board/birdland/bav335x/board.c @@ -384,7 +384,7 @@ int board_eth_init(bd_t *bis) ecode = read_eeprom(&header); /* if we have a valid EE, get mac address from there */ if ((ecode == 0) && - is_valid_ether_addr((const u8 *)&header.mac_addr[0][0])) { + is_valid_ethaddr((const u8 *)&header.mac_addr[0][0])) { memcpy(mac_addr, (const void *)&header.mac_addr[0][0], 6); } @@ -395,7 +395,7 @@ int board_eth_init(bd_t *bis) if (!getenv("ethaddr")) { printf("<ethaddr> not set. Validating first E-fuse MAC\n"); - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("ethaddr", mac_addr); } diff --git a/board/buffalo/lsxl/lsxl.c b/board/buffalo/lsxl/lsxl.c index b0d49c4..487875c 100644 --- a/board/buffalo/lsxl/lsxl.c +++ b/board/buffalo/lsxl/lsxl.c @@ -232,7 +232,7 @@ static void rescue_mode(void) printf("Entering rescue mode..\n"); #ifdef CONFIG_RANDOM_MACADDR if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { - eth_random_addr(enetaddr); + net_random_ethaddr(enetaddr); if (eth_setenv_enetaddr("ethaddr", enetaddr)) { printf("Failed to set ethernet address\n"); set_led(LED_ALARM_BLINKING); diff --git a/board/cm-bf527/cm-bf527.c b/board/cm-bf527/cm-bf527.c index 1533eb9..2871fa2 100644 --- a/board/cm-bf527/cm-bf527.c +++ b/board/cm-bf527/cm-bf527.c @@ -39,13 +39,13 @@ static void board_init_enetaddr(uchar *mac_addr) for (ret = 0; ret < 6; ++ret) mac_addr[ret] = otp_mac_p[5 - ret]; - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) valid_mac = true; } if (!valid_mac) { puts("Warning: Generating 'random' MAC address\n"); - eth_random_addr(mac_addr); + net_random_ethaddr(mac_addr); } eth_setenv_enetaddr("ethaddr", mac_addr); diff --git a/board/cm-bf537e/cm-bf537e.c b/board/cm-bf537e/cm-bf537e.c index e79f90f..902611e 100644 --- a/board/cm-bf537e/cm-bf537e.c +++ b/board/cm-bf537e/cm-bf537e.c @@ -31,7 +31,7 @@ static void board_init_enetaddr(char *var) return; printf("Warning: %s: generating 'random' MAC address\n", var); - eth_random_addr(enetaddr); + net_random_ethaddr(enetaddr); eth_setenv_enetaddr(var, enetaddr); } diff --git a/board/cm-bf537u/cm-bf537u.c b/board/cm-bf537u/cm-bf537u.c index 632cbda..69bffd7 100644 --- a/board/cm-bf537u/cm-bf537u.c +++ b/board/cm-bf537u/cm-bf537u.c @@ -31,7 +31,7 @@ static void board_init_enetaddr(char *var) return; printf("Warning: %s: generating 'random' MAC address\n", var); - eth_random_addr(enetaddr); + net_random_ethaddr(enetaddr); eth_setenv_enetaddr(var, enetaddr); } diff --git a/board/cobra5272/u-boot.lds b/board/cobra5272/u-boot.lds deleted file mode 100644 index e91b7e1..0000000 --- a/board/cobra5272/u-boot.lds +++ /dev/null @@ -1,85 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - .text : - { - arch/m68k/cpu/mcf52x2/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index ae6945b..7a1bbaf 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -425,7 +425,7 @@ static int handle_mac_address(char *env_var, uint eeprom_bus) if (rc) return rc; - if (!is_valid_ether_addr(enetaddr)) + if (!is_valid_ethaddr(enetaddr)) return -1; return eth_setenv_enetaddr(env_var, enetaddr); diff --git a/board/compulab/cm_t335/Kconfig b/board/compulab/cm_t335/Kconfig index 3a8f304..683efde 100644 --- a/board/compulab/cm_t335/Kconfig +++ b/board/compulab/cm_t335/Kconfig @@ -12,13 +12,4 @@ config SYS_SOC config SYS_CONFIG_NAME default "cm_t335" -config DM - default y - -config DM_GPIO - default y - -config DM_SERIAL - default y - endif diff --git a/board/compulab/cm_t335/cm_t335.c b/board/compulab/cm_t335/cm_t335.c index 592ef3d..428aee6 100644 --- a/board/compulab/cm_t335/cm_t335.c +++ b/board/compulab/cm_t335/cm_t335.c @@ -114,7 +114,7 @@ static int handle_mac_address(void) if (rv) get_efuse_mac_addr(enetaddr); - if (!is_valid_ether_addr(enetaddr)) + if (!is_valid_ethaddr(enetaddr)) return -1; return eth_setenv_enetaddr("ethaddr", enetaddr); diff --git a/board/compulab/cm_t35/cm_t35.c b/board/compulab/cm_t35/cm_t35.c index c4ea8ea..374edbc 100644 --- a/board/compulab/cm_t35/cm_t35.c +++ b/board/compulab/cm_t35/cm_t35.c @@ -441,7 +441,7 @@ static int handle_mac_address(void) if (rc) return rc; - if (!is_valid_ether_addr(enetaddr)) + if (!is_valid_ethaddr(enetaddr)) return -1; return eth_setenv_enetaddr("ethaddr", enetaddr); diff --git a/board/compulab/cm_t3517/cm_t3517.c b/board/compulab/cm_t3517/cm_t3517.c index 624cf4c..03b2bad 100644 --- a/board/compulab/cm_t3517/cm_t3517.c +++ b/board/compulab/cm_t3517/cm_t3517.c @@ -132,7 +132,7 @@ static int am3517_get_efuse_enetaddr(u8 *enetaddr) enetaddr[4] = (u8)((lsb >> 8) & 0xff); enetaddr[5] = (u8)(lsb & 0xff); - return is_valid_ether_addr(enetaddr); + return is_valid_ethaddr(enetaddr); } static inline int cm_t3517_init_emac(bd_t *bis) @@ -170,7 +170,7 @@ static int cm_t3517_handle_mac_address(void) return ret; } - if (!is_valid_ether_addr(enetaddr)) + if (!is_valid_ethaddr(enetaddr)) return -1; return eth_setenv_enetaddr("ethaddr", enetaddr); diff --git a/board/compulab/cm_t54/cm_t54.c b/board/compulab/cm_t54/cm_t54.c index fdea909..fad0551 100644 --- a/board/compulab/cm_t54/cm_t54.c +++ b/board/compulab/cm_t54/cm_t54.c @@ -166,10 +166,10 @@ static int handle_mac_address(void) return 0; ret = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS); - if (ret || !is_valid_ether_addr(enetaddr)) + if (ret || !is_valid_ethaddr(enetaddr)) generate_mac_addr(enetaddr); - if (!is_valid_ether_addr(enetaddr)) + if (!is_valid_ethaddr(enetaddr)) return -1; return eth_setenv_enetaddr("usbethaddr", enetaddr); diff --git a/board/coreboot/coreboot/coreboot.c b/board/coreboot/coreboot/coreboot.c index e076ea6..7110f35 100644 --- a/board/coreboot/coreboot/coreboot.c +++ b/board/coreboot/coreboot/coreboot.c @@ -10,11 +10,6 @@ int arch_early_init_r(void) { -#ifdef CONFIG_CROS_EC - if (cros_ec_board_init()) - return -1; -#endif - return 0; } diff --git a/board/davinci/da8xxevm/Kconfig b/board/davinci/da8xxevm/Kconfig index 1108e4b..33bfcc3 100644 --- a/board/davinci/da8xxevm/Kconfig +++ b/board/davinci/da8xxevm/Kconfig @@ -23,3 +23,16 @@ config SYS_CONFIG_NAME default "da850evm" endif + +if TARGET_OMAPL138_LCDK + +config SYS_BOARD + default "da8xxevm" + +config SYS_VENDOR + default "davinci" + +config SYS_CONFIG_NAME + default "omapl138_lcdk" + +endif diff --git a/board/davinci/da8xxevm/MAINTAINERS b/board/davinci/da8xxevm/MAINTAINERS index 10c4e2f..f32ce66 100644 --- a/board/davinci/da8xxevm/MAINTAINERS +++ b/board/davinci/da8xxevm/MAINTAINERS @@ -12,3 +12,9 @@ F: include/configs/da850evm.h F: configs/da850_am18xxevm_defconfig F: configs/da850evm_defconfig F: configs/da850evm_direct_nor_defconfig + +OMAPL138_LCDK BOARD +M: Peter Howard <phoward@gme.net.au> +S: Maintained +F: include/configs/omap1l38_lcdk.h +F: configs/omapl138_lcdk_defconfig diff --git a/board/davinci/da8xxevm/Makefile b/board/davinci/da8xxevm/Makefile index 4da509b..93e1f1d 100644 --- a/board/davinci/da8xxevm/Makefile +++ b/board/davinci/da8xxevm/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += da830evm.o obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += da850evm.o +obj-$(CONFIG_MACH_OMAPL138_LCDK) += omapl138_lcdk.o diff --git a/board/davinci/da8xxevm/README.omapl138-lcdk b/board/davinci/da8xxevm/README.omapl138-lcdk new file mode 100644 index 0000000..ea0c53d --- /dev/null +++ b/board/davinci/da8xxevm/README.omapl138-lcdk @@ -0,0 +1,28 @@ +Summary +======= +This README assumes you have read README.da850. It contains some additional +information specific to building the omapl138-lcdk. The AIS file as generated +by the build is, currently, not useable due to differences in the flash +available on this board, as compared to the da850evm boards. + +Flash Differences +================= +Refer to the discussion in [1] for more detail - basically the da850evm uses +SPI flash whereas the lcdk uses NAND flash to store the bootloader, and +the support isn't there in the SPL code. + +It should be possible to add the support in the SPL code should someone be +sufficiently motivated. + +Using the built image +===================== +The output image to use is u-boot.bin. This needs to be converted to an +AIS file as described in [1] and then flashed using the utitilty linked to +there and also described in README.da850. You _may_ be able to write using +u-boot itself, but the commands in README.da850 won't work as they write to +SPI rather than NAND. + +Links +===== +[1] + http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/t/386829
\ No newline at end of file diff --git a/board/davinci/da8xxevm/da850evm.c b/board/davinci/da8xxevm/da850evm.c index b9ca38e..b82385a 100644 --- a/board/davinci/da8xxevm/da850evm.c +++ b/board/davinci/da8xxevm/da850evm.c @@ -145,7 +145,7 @@ int misc_init_r(void) */ if (!enetaddr_found) { if (!spi_mac_read) { - if (is_valid_ether_addr(buff)) { + if (is_valid_ethaddr(buff)) { if (eth_setenv_enetaddr("ethaddr", buff)) { printf("Warning: Failed to " "set MAC address from SPI flash\n"); @@ -160,8 +160,8 @@ int misc_init_r(void) * MAC address present in environment compare it with * the MAC address in SPI flash and warn on mismatch */ - if (!spi_mac_read && is_valid_ether_addr(buff) && - memcmp(env_enetaddr, buff, 6)) + if (!spi_mac_read && is_valid_ethaddr(buff) && + memcmp(env_enetaddr, buff, 6)) printf("Warning: MAC address in SPI flash don't match " "with the MAC address in the environment\n"); printf("Default using MAC address from environment\n"); diff --git a/board/davinci/da8xxevm/omapl138_lcdk.c b/board/davinci/da8xxevm/omapl138_lcdk.c new file mode 100644 index 0000000..bef2570 --- /dev/null +++ b/board/davinci/da8xxevm/omapl138_lcdk.c @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * Based on da850evm.c. Original Copyrights follow: + * + * Copyright (C) 2009 Nick Thompson, GE Fanuc, Ltd. <nick.thompson@gefanuc.com> + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 <i2c.h> +#include <net.h> +#include <netdev.h> +#include <spi.h> +#include <spi_flash.h> +#include <asm/arch/hardware.h> +#include <asm/ti-common/davinci_nand.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/davinci_misc.h> +#ifdef CONFIG_DAVINCI_MMC +#include <mmc.h> +#include <asm/arch/sdmmc_defs.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; + +#define pinmux(x) (&davinci_syscfg_regs->pinmux[x]) + +#ifdef CONFIG_DAVINCI_MMC +/* MMC0 pin muxer settings */ +const struct pinmux_config mmc0_pins[] = { + /* GP0[11] is required for SD to work on Rev 3 EVMs */ + { pinmux(0), 8, 4 }, /* GP0[11] */ + { pinmux(10), 2, 0 }, /* MMCSD0_CLK */ + { pinmux(10), 2, 1 }, /* MMCSD0_CMD */ + { pinmux(10), 2, 2 }, /* MMCSD0_DAT_0 */ + { pinmux(10), 2, 3 }, /* MMCSD0_DAT_1 */ + { pinmux(10), 2, 4 }, /* MMCSD0_DAT_2 */ + { pinmux(10), 2, 5 }, /* MMCSD0_DAT_3 */ + /* LCDK supports only 4-bit mode, remaining pins are not configured */ +}; +#endif + +/* UART pin muxer settings */ +static const struct pinmux_config uart_pins[] = { + { pinmux(0), 4, 6 }, + { pinmux(0), 4, 7 }, + { pinmux(4), 2, 4 }, + { pinmux(4), 2, 5 } +}; + +#ifdef CONFIG_DRIVER_TI_EMAC +static const struct pinmux_config emac_pins[] = { + { pinmux(2), 8, 1 }, + { pinmux(2), 8, 2 }, + { pinmux(2), 8, 3 }, + { pinmux(2), 8, 4 }, + { pinmux(2), 8, 5 }, + { pinmux(2), 8, 6 }, + { pinmux(2), 8, 7 }, + { pinmux(3), 8, 0 }, + { pinmux(3), 8, 1 }, + { pinmux(3), 8, 2 }, + { pinmux(3), 8, 3 }, + { pinmux(3), 8, 4 }, + { pinmux(3), 8, 5 }, + { pinmux(3), 8, 6 }, + { pinmux(3), 8, 7 }, + { pinmux(4), 8, 0 }, + { pinmux(4), 8, 1 } +}; +#endif /* CONFIG_DRIVER_TI_EMAC */ + +/* I2C pin muxer settings */ +static const struct pinmux_config i2c_pins[] = { + { pinmux(4), 2, 2 }, + { pinmux(4), 2, 3 } +}; + +#ifdef CONFIG_NAND_DAVINCI +const struct pinmux_config nand_pins[] = { + { pinmux(7), 1, 1 }, + { pinmux(7), 1, 2 }, + { pinmux(7), 1, 4 }, + { pinmux(7), 1, 5 }, + { pinmux(8), 1, 0 }, + { pinmux(8), 1, 1 }, + { pinmux(8), 1, 2 }, + { pinmux(8), 1, 3 }, + { pinmux(8), 1, 4 }, + { pinmux(8), 1, 5 }, + { pinmux(8), 1, 6 }, + { pinmux(8), 1, 7 }, + { pinmux(9), 1, 0 }, + { pinmux(9), 1, 1 }, + { pinmux(9), 1, 2 }, + { pinmux(9), 1, 3 }, + { pinmux(9), 1, 4 }, + { pinmux(9), 1, 5 }, + { pinmux(9), 1, 6 }, + { pinmux(9), 1, 7 }, + { pinmux(12), 1, 5 }, + { pinmux(12), 1, 6 } +}; + +#endif + +#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII +#define HAS_RMII 1 +#else +#define HAS_RMII 0 +#endif + +const struct pinmux_resource pinmuxes[] = { + PINMUX_ITEM(uart_pins), + PINMUX_ITEM(i2c_pins), +#ifdef CONFIG_NAND_DAVINCI + PINMUX_ITEM(nand_pins), +#endif +}; + +const int pinmuxes_size = ARRAY_SIZE(pinmuxes); + +const struct lpsc_resource lpsc[] = { + { DAVINCI_LPSC_AEMIF }, /* NAND, NOR */ + { DAVINCI_LPSC_SPI1 }, /* Serial Flash */ + { DAVINCI_LPSC_EMAC }, /* image download */ + { DAVINCI_LPSC_UART2 }, /* console */ + { DAVINCI_LPSC_GPIO }, +#ifdef CONFIG_DAVINCI_MMC + { DAVINCI_LPSC_MMC_SD }, +#endif +}; + +const int lpsc_size = ARRAY_SIZE(lpsc); + +#ifndef CONFIG_DA850_EVM_MAX_CPU_CLK +#define CONFIG_DA850_EVM_MAX_CPU_CLK 456000000 +#endif + +/* + * get_board_rev() - setup to pass kernel board revision information + * Returns: + * bit[0-3] Maximum cpu clock rate supported by onboard SoC + * 0000b - 300 MHz + * 0001b - 372 MHz + * 0010b - 408 MHz + * 0011b - 456 MHz + */ +u32 get_board_rev(void) +{ + return 0; +} + +int board_early_init_f(void) +{ + /* + * Power on required peripherals + * ARM does not have access by default to PSC0 and PSC1 + * assuming here that the DSP bootloader has set the IOPU + * such that PSC access is available to ARM + */ + if (da8xx_configure_lpsc_items(lpsc, ARRAY_SIZE(lpsc))) + return 1; + + return 0; +} + +int board_init(void) +{ +#ifndef CONFIG_USE_IRQ + irq_init(); +#endif + + /* arch number of the board */ + gd->bd->bi_arch_number = MACH_TYPE_OMAPL138_LCDK; + + /* address of boot parameters */ + gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; + + + /* setup the SUSPSRC for ARM to control emulation suspend */ + writel(readl(&davinci_syscfg_regs->suspsrc) & + ~(DAVINCI_SYSCFG_SUSPSRC_EMAC | DAVINCI_SYSCFG_SUSPSRC_I2C | + DAVINCI_SYSCFG_SUSPSRC_SPI1 | DAVINCI_SYSCFG_SUSPSRC_TIMER0 | + DAVINCI_SYSCFG_SUSPSRC_UART2), + &davinci_syscfg_regs->suspsrc); + + /* configure pinmux settings */ + if (davinci_configure_pin_mux_items(pinmuxes, ARRAY_SIZE(pinmuxes))) + return 1; + +#ifdef CONFIG_NAND_DAVINCI + /* + * NAND CS setup - cycle counts based on da850evm NAND timings in the + * Linux kernel @ 25MHz EMIFA + */ + writel((DAVINCI_ABCR_WSETUP(15) | + DAVINCI_ABCR_WSTROBE(63) | + DAVINCI_ABCR_WHOLD(7) | + DAVINCI_ABCR_RSETUP(15) | + DAVINCI_ABCR_RSTROBE(63) | + DAVINCI_ABCR_RHOLD(7) | + DAVINCI_ABCR_TA(3) | + DAVINCI_ABCR_ASIZE_16BIT), + &davinci_emif_regs->ab2cr); /* CS3 */ +#endif + + +#ifdef CONFIG_DAVINCI_MMC + if (davinci_configure_pin_mux(mmc0_pins, ARRAY_SIZE(mmc0_pins)) != 0) + return 1; +#endif + +#ifdef CONFIG_DRIVER_TI_EMAC + if (davinci_configure_pin_mux(emac_pins, ARRAY_SIZE(emac_pins)) != 0) + return 1; + davinci_emac_mii_mode_sel(HAS_RMII); +#endif /* CONFIG_DRIVER_TI_EMAC */ + + /* enable the console UART */ + writel((DAVINCI_UART_PWREMU_MGMT_FREE | DAVINCI_UART_PWREMU_MGMT_URRST | + DAVINCI_UART_PWREMU_MGMT_UTRST), + &davinci_uart2_ctrl_regs->pwremu_mgmt); + + return 0; +} + +#ifdef CONFIG_DRIVER_TI_EMAC + +/* + * Initializes on-board ethernet controllers. + */ +int board_eth_init(bd_t *bis) +{ + if (!davinci_emac_initialize()) { + printf("Error: Ethernet init failed!\n"); + return -1; + } + + return 0; +} + +#endif /* CONFIG_DRIVER_TI_EMAC */ + +#define CFG_MAC_ADDR_SPI_BUS 0 +#define CFG_MAC_ADDR_SPI_CS 0 +#define CFG_MAC_ADDR_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED +#define CFG_MAC_ADDR_SPI_MODE SPI_MODE_3 + +#define CFG_MAC_ADDR_OFFSET (flash->size - SZ_64K) + +static int get_mac_addr(u8 *addr) +{ + /* Need to find a way to get MAC ADDRESS */ + return 0; +} + +void dsp_lpsc_on(unsigned domain, unsigned int id) +{ + dv_reg_p mdstat, mdctl, ptstat, ptcmd; + struct davinci_psc_regs *psc_regs; + + psc_regs = davinci_psc0_regs; + mdstat = &psc_regs->psc0.mdstat[id]; + mdctl = &psc_regs->psc0.mdctl[id]; + ptstat = &psc_regs->ptstat; + ptcmd = &psc_regs->ptcmd; + + while (*ptstat & (0x1 << domain)) + ; + + if ((*mdstat & 0x1f) == 0x03) + return; /* Already on and enabled */ + + *mdctl |= 0x03; + + *ptcmd = 0x1 << domain; + + while (*ptstat & (0x1 << domain)) + ; + while ((*mdstat & 0x1f) != 0x03) + ; /* Probably an overkill... */ +} + +static void dspwake(void) +{ + unsigned *resetvect = (unsigned *)DAVINCI_L3CBARAM_BASE; + + /* if the device is ARM only, return */ + if ((REG(CHIP_REV_ID_REG) & 0x3f) == 0x10) + return; + + if (!strcmp(getenv("dspwake"), "no")) + return; + + *resetvect++ = 0x1E000; /* DSP Idle */ + /* clear out the next 10 words as NOP */ + memset(resetvect, 0, sizeof(unsigned) * 10); + + /* setup the DSP reset vector */ + REG(HOST1CFG) = DAVINCI_L3CBARAM_BASE; + + dsp_lpsc_on(1, DAVINCI_LPSC_GEM); + REG(PSC0_MDCTL + (15 * 4)) |= 0x100; +} + +#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII +/** + * rmii_hw_init + * + */ +int rmii_hw_init(void) +{ + return 0; +} +#endif /* CONFIG_DRIVER_TI_EMAC_USE_RMII */ + +int misc_init_r(void) +{ + uint8_t tmp[20], addr[10]; + + + if (getenv("ethaddr") == NULL) { + /* Read Ethernet MAC address from EEPROM */ + if (dvevm_read_mac_address(addr)) { + /* Set Ethernet MAC address from EEPROM */ + davinci_sync_env_enetaddr(addr); + } else { + get_mac_addr(addr); + } + + if (is_multicast_ethaddr(addr) || is_zero_ethaddr(addr)) { + printf("Invalid MAC address read.\n"); + return -EINVAL; + } + sprintf((char *)tmp, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], + addr[1], addr[2], addr[3], addr[4], addr[5]); + + setenv("ethaddr", (char *)tmp); + } +#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII + /* Select RMII fucntion through the expander */ + if (rmii_hw_init()) + printf("RMII hardware init failed!!!\n"); +#endif + + dspwake(); + + return 0; +} + +#ifdef CONFIG_DAVINCI_MMC +static struct davinci_mmc mmc_sd0 = { + .reg_base = (struct davinci_mmc_regs *)DAVINCI_MMC_SD0_BASE, + .host_caps = MMC_MODE_4BIT, /* DA850 supports only 4-bit SD/MMC */ + .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, + .version = MMC_CTLR_VERSION_2, +}; + +int board_mmc_init(bd_t *bis) +{ + mmc_sd0.input_clk = clk_get(DAVINCI_MMCSD_CLKID); + + /* Add slot-0 to mmc subsystem */ + return davinci_mmc_init(bis, &mmc_sd0); +} +#endif diff --git a/board/dnp5370/dnp5370.c b/board/dnp5370/dnp5370.c index df721c9..655fcac 100644 --- a/board/dnp5370/dnp5370.c +++ b/board/dnp5370/dnp5370.c @@ -46,7 +46,7 @@ static void board_init_enetaddr(uchar *mac_addr) if (USE_MAC_IN_FLASH) { /* we cram the MAC in the last flash sector */ uchar *board_mac_addr = (uchar *)0x202F0000; - if (is_valid_ether_addr(board_mac_addr)) { + if (is_valid_ethaddr(board_mac_addr)) { memcpy(mac_addr, board_mac_addr, 6); valid_mac = true; } @@ -54,7 +54,7 @@ static void board_init_enetaddr(uchar *mac_addr) if (!valid_mac) { puts("Warning: Generating 'random' MAC address\n"); - eth_random_addr(mac_addr); + net_random_ethaddr(mac_addr); } eth_setenv_enetaddr("ethaddr", mac_addr); diff --git a/board/egnite/ethernut5/ethernut5.c b/board/egnite/ethernut5/ethernut5.c index b45213c..67d3984 100644 --- a/board/egnite/ethernut5/ethernut5.c +++ b/board/egnite/ethernut5/ethernut5.c @@ -204,7 +204,7 @@ int board_eth_init(bd_t *bis) miiphy_write(devname, 0, MII_BMCR, BMCR_RESET); } /* Sync environment with network devices, needed for nfsroot. */ - return eth_init(gd->bd); + return eth_init(); } #endif diff --git a/board/freescale/bsc9132qds/bsc9132qds.c b/board/freescale/bsc9132qds/bsc9132qds.c index 36a68db..586dacc 100644 --- a/board/freescale/bsc9132qds/bsc9132qds.c +++ b/board/freescale/bsc9132qds/bsc9132qds.c @@ -36,9 +36,9 @@ DECLARE_GLOBAL_DATA_PTR; int board_early_init_f(void) { - struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR; + struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL}; - setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT); + setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT); return 0; } diff --git a/board/freescale/c29xpcie/c29xpcie.c b/board/freescale/c29xpcie/c29xpcie.c index d7577096..f42d373 100644 --- a/board/freescale/c29xpcie/c29xpcie.c +++ b/board/freescale/c29xpcie/c29xpcie.c @@ -38,10 +38,10 @@ int checkboard(void) int board_early_init_f(void) { - struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR; + struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL}; /* Clock configuration to access CPLD using IFC(GPCM) */ - setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT); + setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT); return 0; } diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 7181cac..87d0578 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -74,8 +74,7 @@ obj-$(CONFIG_P5040DS) += p_corenet/ obj-$(CONFIG_LS102XA_NS_ACCESS) += ns_access.o ifdef CONFIG_SECURE_BOOT -obj-y += fsl_validate.o -obj-$(CONFIG_CMD_ESBC_VALIDATE) += cmd_esbc_validate.o +obj-$(CONFIG_CMD_ESBC_VALIDATE) += fsl_validate.o cmd_esbc_validate.o endif endif diff --git a/board/freescale/common/arm_sleep.c b/board/freescale/common/arm_sleep.c index 8edf878..c06b862 100644 --- a/board/freescale/common/arm_sleep.c +++ b/board/freescale/common/arm_sleep.c @@ -19,6 +19,9 @@ #endif #include "sleep.h" +#ifdef CONFIG_U_QE +#include "../../../drivers/qe/qe.h" +#endif DECLARE_GLOBAL_DATA_PTR; @@ -72,6 +75,9 @@ static void dp_resume_prepare(void) board_sleep_prepare(); armv7_init_nonsec(); cleanup_before_linux(); +#ifdef CONFIG_U_QE + u_qe_resume(); +#endif } int fsl_dp_resume(void) diff --git a/board/freescale/common/cmd_esbc_validate.c b/board/freescale/common/cmd_esbc_validate.c index 8500ba5..8bbe85b 100644 --- a/board/freescale/common/cmd_esbc_validate.c +++ b/board/freescale/common/cmd_esbc_validate.c @@ -8,6 +8,16 @@ #include <command.h> #include <fsl_validate.h> +static int do_esbc_halt(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + printf("Core is entering spin loop.\n"); +loop: + goto loop; + + return 0; +} + static int do_esbc_validate(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -32,3 +42,9 @@ U_BOOT_CMD( "Validates signature on a given image using RSA verification", esbc_validate_help_text ); + +U_BOOT_CMD( + esbc_halt, 1, 0, do_esbc_halt, + "Put the core in spin loop ", + "" +); diff --git a/board/freescale/common/mpc85xx_sleep.c b/board/freescale/common/mpc85xx_sleep.c index f924e7f..9e4132c 100644 --- a/board/freescale/common/mpc85xx_sleep.c +++ b/board/freescale/common/mpc85xx_sleep.c @@ -7,6 +7,9 @@ #include <common.h> #include <asm/immap_85xx.h> #include "sleep.h" +#ifdef CONFIG_U_QE +#include "../../../drivers/qe/qe.h" +#endif DECLARE_GLOBAL_DATA_PTR; @@ -65,6 +68,11 @@ static void dp_resume_prepare(void) disable_cpc_sram(); #endif enable_cpc(); + +#ifdef CONFIG_U_QE + u_qe_resume(); +#endif + } int fsl_dp_resume(void) diff --git a/board/freescale/common/qixis.c b/board/freescale/common/qixis.c index a49e300..9f6b0e7 100644 --- a/board/freescale/common/qixis.c +++ b/board/freescale/common/qixis.c @@ -138,24 +138,23 @@ void qixis_bank_reset(void) QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_START); } -/* Set the boot bank to the power-on default bank */ -void clear_altbank(void) +static void __maybe_unused set_lbmap(int lbmap) { u8 reg; reg = QIXIS_READ(brdcfg[0]); - reg = (reg & ~QIXIS_LBMAP_MASK) | QIXIS_LBMAP_DFLTBANK; + reg = (reg & ~QIXIS_LBMAP_MASK) | lbmap; QIXIS_WRITE(brdcfg[0], reg); } -/* Set the boot bank to the alternate bank */ -void set_altbank(void) +static void __maybe_unused set_rcw_src(int rcw_src) { u8 reg; - reg = QIXIS_READ(brdcfg[0]); - reg = (reg & ~QIXIS_LBMAP_MASK) | QIXIS_LBMAP_ALTBANK; - QIXIS_WRITE(brdcfg[0], reg); + reg = QIXIS_READ(dutcfg[1]); + reg = (reg & ~1) | (rcw_src & 1); + QIXIS_WRITE(dutcfg[1], reg); + QIXIS_WRITE(dutcfg[0], (rcw_src >> 1) & 0xff); } static void qixis_dump_regs(void) @@ -201,11 +200,22 @@ int qixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int i; if (argc <= 1) { - clear_altbank(); + set_lbmap(QIXIS_LBMAP_DFLTBANK); qixis_reset(); } else if (strcmp(argv[1], "altbank") == 0) { - set_altbank(); + set_lbmap(QIXIS_LBMAP_ALTBANK); qixis_bank_reset(); + } else if (strcmp(argv[1], "nand") == 0) { +#ifdef QIXIS_LBMAP_NAND + QIXIS_WRITE(rst_ctl, 0x30); + QIXIS_WRITE(rcfg_ctl, 0); + set_lbmap(QIXIS_LBMAP_NAND); + set_rcw_src(QIXIS_RCW_SRC_NAND); + QIXIS_WRITE(rcfg_ctl, 0x20); + QIXIS_WRITE(rcfg_ctl, 0x21); +#else + printf("Not implemented\n"); +#endif } else if (strcmp(argv[1], "watchdog") == 0) { static char *period[9] = {"2s", "4s", "8s", "16s", "32s", "1min", "2min", "4min", "8min"}; @@ -244,6 +254,7 @@ U_BOOT_CMD( "Reset the board using the FPGA sequencer", "- hard reset to default bank\n" "qixis_reset altbank - reset to alternate bank\n" + "qixis_reset nand - reset to nand\n" "qixis watchdog <watchdog_period> - set the watchdog period\n" " period: 1s 2s 4s 8s 16s 32s 1min 2min 4min 8min\n" "qixis_reset dump - display the QIXIS registers\n" diff --git a/board/freescale/ls1021aqds/MAINTAINERS b/board/freescale/ls1021aqds/MAINTAINERS index 661526b..820d322 100644 --- a/board/freescale/ls1021aqds/MAINTAINERS +++ b/board/freescale/ls1021aqds/MAINTAINERS @@ -5,6 +5,7 @@ F: board/freescale/ls1021aqds/ F: include/configs/ls1021aqds.h F: configs/ls1021aqds_nor_defconfig F: configs/ls1021aqds_ddr4_nor_defconfig +F: configs/ls1021aqds_ddr4_nor_lpuart_defconfig F: configs/ls1021aqds_nor_SECURE_BOOT_defconfig F: configs/ls1021aqds_nor_lpuart_defconfig F: configs/ls1021aqds_sdcard_defconfig diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c index 722b88f..92f613a 100644 --- a/board/freescale/ls1021aqds/ls1021aqds.c +++ b/board/freescale/ls1021aqds/ls1021aqds.c @@ -12,7 +12,6 @@ #include <asm/arch/clock.h> #include <asm/arch/fsl_serdes.h> #include <asm/arch/ls102xa_stream_id.h> -#include <asm/pcie_layerscape.h> #include <hwconfig.h> #include <mmc.h> #include <fsl_esdhc.h> @@ -138,6 +137,17 @@ unsigned long get_board_ddr_clk(void) return 66666666; } +unsigned int get_soc_major_rev(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + unsigned int svr, major; + + svr = in_be32(&gur->svr); + major = SVR_MAJ(svr); + + return major; +} + int select_i2c_ch_pca9547(u8 ch) { int ret; @@ -181,6 +191,7 @@ int board_early_init_f(void) { struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + unsigned int major; #ifdef CONFIG_TSEC_ENET out_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR); @@ -205,19 +216,22 @@ int board_early_init_f(void) out_le32(&cci->slave[4].snoop_ctrl, CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); - /* - * Set CCI-400 Slave interface S1, S2 Shareable Override Register - * All transactions are treated as non-shareable - */ - out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE); - out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE); - - /* Workaround for the issue that DDR could not respond to - * barrier transaction which is generated by executing DSB/ISB - * instruction. Set CCI-400 control override register to - * terminate the barrier transaction. After DDR is initialized, - * allow barrier transaction to DDR again */ - out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); + major = get_soc_major_rev(); + if (major == SOC_MAJOR_VER_1_0) { + /* + * Set CCI-400 Slave interface S1, S2 Shareable Override + * Register All transactions are treated as non-shareable + */ + out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE); + out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE); + + /* Workaround for the issue that DDR could not respond to + * barrier transaction which is generated by executing DSB/ISB + * instruction. Set CCI-400 control override register to + * terminate the barrier transaction. After DDR is initialized, + * allow barrier transaction to DDR again */ + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); + } #if defined(CONFIG_DEEP_SLEEP) if (is_warm_boot()) @@ -231,6 +245,7 @@ int board_early_init_f(void) void board_init_f(ulong dummy) { struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + unsigned int major; #ifdef CONFIG_NAND_BOOT struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; @@ -267,7 +282,10 @@ void board_init_f(ulong dummy) #ifdef CONFIG_SPL_I2C_SUPPORT i2c_init_all(); #endif - out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); + + major = get_soc_major_rev(); + if (major == SOC_MAJOR_VER_1_0) + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); dram_init(); @@ -548,10 +566,14 @@ struct smmu_stream_id dev_stream_id[] = { int board_init(void) { struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + unsigned int major; - /* Set CCI-400 control override register to - * enable barrier transaction */ - out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER); + major = get_soc_major_rev(); + if (major == SOC_MAJOR_VER_1_0) { + /* Set CCI-400 control override register to + * enable barrier transaction */ + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER); + } select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); @@ -580,10 +602,15 @@ int board_init(void) void board_sleep_prepare(void) { struct ccsr_cci400 __iomem *cci = (void *)CONFIG_SYS_CCI400_ADDR; + unsigned int major; + + major = get_soc_major_rev(); + if (major == SOC_MAJOR_VER_1_0) { + /* Set CCI-400 control override register to + * enable barrier transaction */ + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER); + } - /* Set CCI-400 control override register to - * enable barrier transaction */ - out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER); #ifdef CONFIG_LS102XA_NS_ACCESS enable_devices_ns_access(ns_dev, ARRAY_SIZE(ns_dev)); @@ -595,8 +622,8 @@ int ft_board_setup(void *blob, bd_t *bd) { ft_cpu_setup(blob, bd); -#ifdef CONFIG_PCIE_LAYERSCAPE - ft_pcie_setup(blob, bd); +#ifdef CONFIG_PCI + ft_pci_setup(blob, bd); #endif return 0; diff --git a/board/freescale/ls1021atwr/ls1021atwr.c b/board/freescale/ls1021atwr/ls1021atwr.c index fb8525f..ed5bd27 100644 --- a/board/freescale/ls1021atwr/ls1021atwr.c +++ b/board/freescale/ls1021atwr/ls1021atwr.c @@ -12,7 +12,7 @@ #include <asm/arch/clock.h> #include <asm/arch/fsl_serdes.h> #include <asm/arch/ls102xa_stream_id.h> -#include <asm/pcie_layerscape.h> +#include <hwconfig.h> #include <mmc.h> #include <fsl_esdhc.h> #include <fsl_ifc.h> @@ -54,6 +54,17 @@ DECLARE_GLOBAL_DATA_PTR; #define KEEP_STATUS 0x0 #define NEED_RESET 0x1 +#define SOFT_MUX_ON_I2C3_IFC 0x2 +#define SOFT_MUX_ON_CAN3_USB2 0x8 +#define SOFT_MUX_ON_QE_LCD 0x10 + +#define PIN_I2C3_IFC_MUX_I2C3 0x0 +#define PIN_I2C3_IFC_MUX_IFC 0x1 +#define PIN_CAN3_USB2_MUX_USB2 0x0 +#define PIN_CAN3_USB2_MUX_CAN3 0x1 +#define PIN_QE_LCD_MUX_LCD 0x0 +#define PIN_QE_LCD_MUX_QE 0x1 + struct cpld_data { u8 cpld_ver; /* cpld revision */ u8 cpld_ver_sub; /* cpld sub revision */ @@ -122,6 +133,17 @@ int checkboard(void) return 0; } +unsigned int get_soc_major_rev(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + unsigned int svr, major; + + svr = in_be32(&gur->svr); + major = SVR_MAJ(svr); + + return major; +} + void ddrmc_init(void) { struct ccsr_ddr *ddr = (struct ccsr_ddr *)CONFIG_SYS_FSL_DDR_ADDR; @@ -260,10 +282,73 @@ int config_serdes_mux(void) } #endif +#ifndef CONFIG_QSPI_BOOT +int config_board_mux(void) +{ + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + int conflict_flag; + + conflict_flag = 0; + if (hwconfig("i2c3")) { + conflict_flag++; + cpld_data->soft_mux_on |= SOFT_MUX_ON_I2C3_IFC; + cpld_data->i2c3_ifc_mux = PIN_I2C3_IFC_MUX_I2C3; + } + + if (hwconfig("ifc")) { + conflict_flag++; + /* some signals can not enable simultaneous*/ + if (conflict_flag > 1) + goto conflict; + cpld_data->soft_mux_on |= SOFT_MUX_ON_I2C3_IFC; + cpld_data->i2c3_ifc_mux = PIN_I2C3_IFC_MUX_IFC; + } + + conflict_flag = 0; + if (hwconfig("usb2")) { + conflict_flag++; + cpld_data->soft_mux_on |= SOFT_MUX_ON_CAN3_USB2; + cpld_data->can3_usb2_mux = PIN_CAN3_USB2_MUX_USB2; + } + + if (hwconfig("can3")) { + conflict_flag++; + /* some signals can not enable simultaneous*/ + if (conflict_flag > 1) + goto conflict; + cpld_data->soft_mux_on |= SOFT_MUX_ON_CAN3_USB2; + cpld_data->can3_usb2_mux = PIN_CAN3_USB2_MUX_CAN3; + } + + conflict_flag = 0; + if (hwconfig("lcd")) { + conflict_flag++; + cpld_data->soft_mux_on |= SOFT_MUX_ON_QE_LCD; + cpld_data->qe_lcd_mux = PIN_QE_LCD_MUX_LCD; + } + + if (hwconfig("qe")) { + conflict_flag++; + /* some signals can not enable simultaneous*/ + if (conflict_flag > 1) + goto conflict; + cpld_data->soft_mux_on |= SOFT_MUX_ON_QE_LCD; + cpld_data->qe_lcd_mux = PIN_QE_LCD_MUX_QE; + } + + return 0; + +conflict: + printf("WARNING: pin conflict! MUX setting may failed!\n"); + return 0; +} +#endif + int board_early_init_f(void) { struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + unsigned int major; #ifdef CONFIG_TSEC_ENET out_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR); @@ -289,12 +374,15 @@ int board_early_init_f(void) out_le32(&cci->slave[4].snoop_ctrl, CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); - /* - * Set CCI-400 Slave interface S1, S2 Shareable Override Register - * All transactions are treated as non-shareable - */ - out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE); - out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE); + major = get_soc_major_rev(); + if (major == SOC_MAJOR_VER_1_0) { + /* + * Set CCI-400 Slave interface S1, S2 Shareable Override + * Register All transactions are treated as non-shareable + */ + out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE); + out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE); + } return 0; } @@ -465,6 +553,10 @@ int board_init(void) #if defined(CONFIG_MISC_INIT_R) int misc_init_r(void) { +#ifndef CONFIG_QSPI_BOOT + config_board_mux(); +#endif + #ifdef CONFIG_FSL_CAAM return sec_init(); #endif @@ -475,8 +567,8 @@ int ft_board_setup(void *blob, bd_t *bd) { ft_cpu_setup(blob, bd); -#ifdef CONFIG_PCIE_LAYERSCAPE - ft_pcie_setup(blob, bd); +#ifdef CONFIG_PCI + ft_pci_setup(blob, bd); #endif return 0; diff --git a/board/freescale/ls2085a/ls2085a.c b/board/freescale/ls2085a/ls2085a.c index 519d61c..dd0acf2 100644 --- a/board/freescale/ls2085a/ls2085a.c +++ b/board/freescale/ls2085a/ls2085a.c @@ -12,8 +12,10 @@ #include <asm/io.h> #include <fdt_support.h> #include <libfdt.h> +#include <fsl_debug_server.h> #include <fsl-mc/fsl_mc.h> #include <environment.h> +#include <asm/arch-fsl-lsch3/soc.h> DECLARE_GLOBAL_DATA_PTR; @@ -30,8 +32,7 @@ int board_init(void) int board_early_init_f(void) { - init_early_memctl_regs(); /* tighten IFC timing */ - + fsl_lsch3_early_init_f(); return 0; } @@ -54,29 +55,32 @@ int dram_init(void) return 0; } -int timer_init(void) +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) { - u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR; - u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR; - - /* Enable timebase for all clusters. - * It is safe to do so even some clusters are not enabled. - */ - out_le32(cltbenr, 0xf); - - /* Enable clock for timer - * This is a global setting. - */ - out_le32(cntcr, 0x1); +#ifdef CONFIG_FSL_DEBUG_SERVER + debug_server_init(); +#endif return 0; } +#endif -/* - * Board specific reset that is system reset. - */ -void reset_cpu(ulong addr) +unsigned long get_dram_size_to_hide(void) { + unsigned long dram_to_hide = 0; + +/* Carve the Debug Server private DRAM block from the end of DRAM */ +#ifdef CONFIG_FSL_DEBUG_SERVER + dram_to_hide += debug_server_get_dram_block_size(); +#endif + +/* Carve the MC private DRAM block from the end of DRAM */ +#ifdef CONFIG_FSL_MC_ENET + dram_to_hide += mc_get_dram_block_size(); +#endif + + return dram_to_hide; } int board_eth_init(bd_t *bis) @@ -135,6 +139,7 @@ int ft_board_setup(void *blob, bd_t *bd) #ifdef CONFIG_FSL_MC_ENET fdt_fixup_board_enet(blob); + fsl_mc_ldpaa_exit(bd); #endif return 0; diff --git a/board/freescale/ls2085aqds/Kconfig b/board/freescale/ls2085aqds/Kconfig new file mode 100644 index 0000000..deb640d --- /dev/null +++ b/board/freescale/ls2085aqds/Kconfig @@ -0,0 +1,16 @@ + +if TARGET_LS2085AQDS + +config SYS_BOARD + default "ls2085aqds" + +config SYS_VENDOR + default "freescale" + +config SYS_SOC + default "fsl-lsch3" + +config SYS_CONFIG_NAME + default "ls2085aqds" + +endif diff --git a/board/freescale/ls2085aqds/MAINTAINERS b/board/freescale/ls2085aqds/MAINTAINERS new file mode 100644 index 0000000..fbed672 --- /dev/null +++ b/board/freescale/ls2085aqds/MAINTAINERS @@ -0,0 +1,8 @@ +LS2085A BOARD +M: Prabhakar Kushwaha <prabhakar@freescale.com> +S: Maintained +F: board/freescale/ls2085aqds/ +F: board/freescale/ls2085a/ls2085aqds.c +F: include/configs/ls2085aqds.h +F: configs/ls2085aqds_defconfig +F: configs/ls2085aqds_nand_defconfig diff --git a/board/freescale/ls2085aqds/Makefile b/board/freescale/ls2085aqds/Makefile new file mode 100644 index 0000000..da69a7d --- /dev/null +++ b/board/freescale/ls2085aqds/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2015 Freescale Semiconductor +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ls2085aqds.o +obj-y += ddr.o +obj-y += eth.o diff --git a/board/freescale/ls2085aqds/README b/board/freescale/ls2085aqds/README new file mode 100644 index 0000000..fb3938e --- /dev/null +++ b/board/freescale/ls2085aqds/README @@ -0,0 +1,129 @@ +Overview +-------- +The LS2085A Development System (QDS) is a high-performance computing, +evaluation, and development platform that supports the QorIQ LS2085A +Layerscape Architecture processor. The LS2085AQDS provides validation and +SW development platform for the Freescale LS2085A processor series, with +a complete debugging environment. + +LS2085A SoC Overview +------------------ +The LS2085A integrated multicore processor combines eight ARM Cortex-A57 +processor cores with high-performance data path acceleration logic and network +and peripheral bus interfaces required for networking, telecom/datacom, +wireless infrastructure, and mil/aerospace applications. + +The LS2085A SoC includes the following function and features: + + - Eight 64-bit ARM Cortex-A57 CPUs + - 1 MB platform cache with ECC + - Two 64-bit DDR4 SDRAM memory controllers with ECC and interleaving support + - One secondary 32-bit DDR4 SDRAM memory controller, intended for use by + the AIOP + - Data path acceleration architecture (DPAA2) incorporating acceleration for + the following functions: + - Packet parsing, classification, and distribution (WRIOP) + - Queue and Hardware buffer management for scheduling, packet sequencing, and + congestion management, buffer allocation and de-allocation (QBMan) + - Cryptography acceleration (SEC) at up to 10 Gbps + - RegEx pattern matching acceleration (PME) at up to 10 Gbps + - Decompression/compression acceleration (DCE) at up to 20 Gbps + - Accelerated I/O processing (AIOP) at up to 20 Gbps + - QDMA engine + - 16 SerDes lanes at up to 10.3125 GHz + - Ethernet interfaces + - Up to eight 10 Gbps Ethernet MACs + - Up to eight 1 / 2.5 Gbps Ethernet MACs + - High-speed peripheral interfaces + - Four PCIe 3.0 controllers, one supporting SR-IOV + - Additional peripheral interfaces + - Two serial ATA (SATA 3.0) controllers + - Two high-speed USB 3.0 controllers with integrated PHY + - Enhanced secure digital host controller (eSDXC/eMMC) + - Serial peripheral interface (SPI) controller + - Quad Serial Peripheral Interface (QSPI) Controller + - Four I2C controllers + - Two DUARTs + - Integrated flash controller (IFC 2.0) supporting NAND and NOR flash + - Support for hardware virtualization and partitioning enforcement + - QorIQ platform's trust architecture 3.0 + - Service processor (SP) provides pre-boot initialization and secure-boot + capabilities + + LS2085AQDS board Overview + ----------------------- + - SERDES Connections, 16 lanes supporting: + - PCI Express - 3.0 + - SGMII, SGMII 2.5 + - QSGMII + - SATA 3.0 + - XAUI + - XFI + - DDR Controller + - Two ports of 72-bits (8-bits ECC) DDR4. Each port supports four + chip-selects and two DIMM connectors. Support is up to 2133MT/s. + - One port of 40-bits (8-bits ECC) DDR4 which supports four chip-selects + and two DIMM connectors. Support is up to 1600MT/s. + -IFC/Local Bus + - IFC rev. 2.0 implementation supporting Little Endian connection scheme. + - One in-socket 128 MB NOR flash 16-bit data bus + - One 512 MB NAND flash with ECC support + - IFC Test Port + - PromJet Port + - FPGA connection + - USB 3.0 + - Two high speed USB 3.0 ports + - First USB 3.0 port configured as Host with Type-A connector + - Second USB 3.0 port configured as OTG with micro-AB connector + - SDHC: PCIe x1 Right Angle connector for supporting following cards + - 1/4-/8-bit SD/MMC Legacy CARD supporting 3.3V devices only + - 1-/4-/8-bit SD/MMC Card supporting 1.8V devices only + - 4-bit eMMC Card Rev 4.4 (1.8V only) + - 8-bit eMMC Card Rev 4.5 (1.8V only) + - SD Card Rev 2.0 and Rev 3.0 + - DSPI: 3 high-speed flash Memory for storage + - 16 MB high-speed flash Memory for boot code and storage (up to 108MHz) + - 8 MB high-speed flash Memory (up to 104 MHz) + - 512 MB low-speed flash Memory (up to 40 MHz) + - QSPI: via NAND/QSPI Card + - 4 I2C controllers + - Two SATA onboard connectors + - UART + - Two 4-pin (HW control) or four 2-pin (SW control) serial ports at up to 115.2 Kbit/s + - Two DB9 D-Type connectors supporting one Serial port each + - ARM JTAG support + +Memory map from core's view +---------------------------- +0x00_0000_0000 .. 0x00_000F_FFFF Boot Rom +0x00_0100_0000 .. 0x00_0FFF_FFFF CCSR +0x00_1800_0000 .. 0x00_181F_FFFF OCRAM +0x00_3000_0000 .. 0x00_3FFF_FFFF IFC region #1 +0x00_8000_0000 .. 0x00_FFFF_FFFF DDR region #1 +0x05_1000_0000 .. 0x05_FFFF_FFFF IFC region #2 +0x80_8000_0000 .. 0xFF_FFFF_FFFF DDR region #2 + +Other addresses are either reserved, or not used directly by u-boot. +This list should be updated when more addresses are used. + +IFC region map from core's view +------------------------------- +During boot i.e. IFC Region #1:- + 0x30000000 - 0x37ffffff : 128MB : NOR flash + 0x38000000 - 0x3BFFFFFF : 64MB : Promjet + 0x3C000000 - 0x40000000 : 64MB : FPGA etc + +After relocate to DDR i.e. IFC Region #2:- + 0x5_1000_0000..0x5_1fff_ffff Memory Hole + 0x5_2000_0000..0x5_3fff_ffff IFC CSx (FPGA, NAND and others 512MB) + 0x5_4000_0000..0x5_7fff_ffff ASIC or others 1GB + 0x5_8000_0000..0x5_bfff_ffff IFC CS0 1GB (NOR/Promjet) + 0x5_C000_0000..0x5_ffff_ffff IFC CS1 1GB (NOR/Promjet) + +Booting Options +--------------- +a) Promjet Boot +b) NOR boot +c) NAND boot +d) SD boot +e) QSPI boot diff --git a/board/freescale/ls2085aqds/ddr.c b/board/freescale/ls2085aqds/ddr.c new file mode 100644 index 0000000..8d71ae1 --- /dev/null +++ b/board/freescale/ls2085aqds/ddr.c @@ -0,0 +1,196 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <fsl_ddr_sdram.h> +#include <fsl_ddr_dimm_params.h> +#include "ddr.h" + +DECLARE_GLOBAL_DATA_PTR; + +void fsl_ddr_board_options(memctl_options_t *popts, + dimm_params_t *pdimm, + unsigned int ctrl_num) +{ + u8 dq_mapping_0, dq_mapping_2, dq_mapping_3; + const struct board_specific_parameters *pbsp, *pbsp_highest = NULL; + ulong ddr_freq; + int slot; + + if (ctrl_num > 2) { + printf("Not supported controller number %d\n", ctrl_num); + return; + } + + for (slot = 0; slot < CONFIG_DIMM_SLOTS_PER_CTLR; slot++) { + if (pdimm[slot].n_ranks) + break; + } + + if (slot >= CONFIG_DIMM_SLOTS_PER_CTLR) + return; + + /* + * we use identical timing for all slots. If needed, change the code + * to pbsp = rdimms[ctrl_num] or pbsp = udimms[ctrl_num]; + */ + if (popts->registered_dimm_en) + pbsp = rdimms[ctrl_num]; + else + pbsp = udimms[ctrl_num]; + + + /* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr + * freqency and n_banks specified in board_specific_parameters table. + */ + ddr_freq = get_ddr_freq(ctrl_num) / 1000000; + while (pbsp->datarate_mhz_high) { + if (pbsp->n_ranks == pdimm[slot].n_ranks && + (pdimm[slot].rank_density >> 30) >= pbsp->rank_gb) { + if (ddr_freq <= pbsp->datarate_mhz_high) { + popts->clk_adjust = pbsp->clk_adjust; + popts->wrlvl_start = pbsp->wrlvl_start; + popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2; + popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3; + 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->clk_adjust = pbsp_highest->clk_adjust; + popts->wrlvl_start = pbsp_highest->wrlvl_start; + popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2; + popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3; + } else { + panic("DIMM is not supported by this board"); + } +found: + debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n" + "\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x, wrlvl_ctrl_3 0x%x\n", + pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb, + pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2, + pbsp->wrlvl_ctl_3); + + if (ctrl_num == CONFIG_DP_DDR_CTRL) { + /* force DDR bus width to 32 bits */ + popts->data_bus_width = 1; + popts->otf_burst_chop_en = 0; + popts->burst_length = DDR_BL8; + popts->bstopre = 0; /* enable auto precharge */ + /* + * Layout optimization results byte mapping + * Byte 0 -> Byte ECC + * Byte 1 -> Byte 3 + * Byte 2 -> Byte 2 + * Byte 3 -> Byte 1 + * Byte ECC -> Byte 0 + */ + dq_mapping_0 = pdimm[slot].dq_mapping[0]; + dq_mapping_2 = pdimm[slot].dq_mapping[2]; + dq_mapping_3 = pdimm[slot].dq_mapping[3]; + pdimm[slot].dq_mapping[0] = pdimm[slot].dq_mapping[8]; + pdimm[slot].dq_mapping[1] = pdimm[slot].dq_mapping[9]; + pdimm[slot].dq_mapping[2] = pdimm[slot].dq_mapping[6]; + pdimm[slot].dq_mapping[3] = pdimm[slot].dq_mapping[7]; + pdimm[slot].dq_mapping[6] = dq_mapping_2; + pdimm[slot].dq_mapping[7] = dq_mapping_3; + pdimm[slot].dq_mapping[8] = dq_mapping_0; + pdimm[slot].dq_mapping[9] = 0; + pdimm[slot].dq_mapping[10] = 0; + pdimm[slot].dq_mapping[11] = 0; + pdimm[slot].dq_mapping[12] = 0; + pdimm[slot].dq_mapping[13] = 0; + pdimm[slot].dq_mapping[14] = 0; + pdimm[slot].dq_mapping[15] = 0; + pdimm[slot].dq_mapping[16] = 0; + pdimm[slot].dq_mapping[17] = 0; + } + /* To work at higher than 1333MT/s */ + popts->half_strength_driver_enable = 0; + /* + * Write leveling override + */ + popts->wrlvl_override = 1; + popts->wrlvl_sample = 0x0; /* 32 clocks */ + + /* + * Rtt and Rtt_WR override + */ + popts->rtt_override = 0; + + /* Enable ZQ calibration */ + popts->zq_en = 1; + + if (ddr_freq < 2350) { + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | + DDR_CDR1_ODT(DDR_CDR_ODT_60ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) | + DDR_CDR2_VREF_RANGE_2; + } else { + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | + DDR_CDR1_ODT(DDR_CDR_ODT_100ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_100ohm) | + DDR_CDR2_VREF_RANGE_2; + } +} + +phys_size_t initdram(int board_type) +{ + phys_size_t dram_size; + +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) + return fsl_ddr_sdram_size(); +#else + puts("Initializing DDR....using SPD\n"); + + dram_size = fsl_ddr_sdram(); +#endif + + return dram_size; +} + +void dram_init_banksize(void) +{ +#ifdef CONFIG_SYS_DP_DDR_BASE_PHY + phys_size_t dp_ddr_size; +#endif + + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) { + gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; + gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE; + gd->bd->bi_dram[1].size = gd->ram_size - + CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; + } else { + gd->bd->bi_dram[0].size = gd->ram_size; + } + +#ifdef CONFIG_SYS_DP_DDR_BASE_PHY + /* initialize DP-DDR here */ + puts("DP-DDR: "); + /* + * DDR controller use 0 as the base address for binding. + * It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access. + */ + dp_ddr_size = fsl_other_ddr_sdram(CONFIG_SYS_DP_DDR_BASE_PHY, + CONFIG_DP_DDR_CTRL, + CONFIG_DP_DDR_NUM_CTRLS, + CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR, + NULL, NULL, NULL); + if (dp_ddr_size) { + gd->bd->bi_dram[2].start = CONFIG_SYS_DP_DDR_BASE; + gd->bd->bi_dram[2].size = dp_ddr_size; + } else { + puts("Not detected"); + } +#endif +} diff --git a/board/freescale/ls2085aqds/ddr.h b/board/freescale/ls2085aqds/ddr.h new file mode 100644 index 0000000..b76ea61 --- /dev/null +++ b/board/freescale/ls2085aqds/ddr.h @@ -0,0 +1,92 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __DDR_H__ +#define __DDR_H__ +struct board_specific_parameters { + u32 n_ranks; + u32 datarate_mhz_high; + u32 rank_gb; + u32 clk_adjust; + u32 wrlvl_start; + u32 wrlvl_ctl_2; + u32 wrlvl_ctl_3; +}; + +/* + * These tables contain 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_parameters udimm0[] = { + /* + * memory controller 0 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 + */ + {2, 1350, 0, 4, 6, 0x0708090B, 0x0C0D0E09,}, + {2, 1666, 0, 4, 7, 0x08090A0C, 0x0D0F100B,}, + {2, 1900, 0, 4, 7, 0x09090B0D, 0x0E10120B,}, + {2, 2300, 0, 4, 8, 0x090A0C0F, 0x1012130C,}, + {} +}; + +/* DP-DDR DIMM */ +static const struct board_specific_parameters udimm2[] = { + /* + * memory controller 2 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 + */ + {2, 1350, 0, 4, 0xd, 0x0C0A0A00, 0x00000009,}, + {2, 1666, 0, 4, 0xd, 0x0C0A0A00, 0x00000009,}, + {2, 1900, 0, 4, 0xe, 0x0D0C0B00, 0x0000000A,}, + {2, 2200, 0, 4, 0xe, 0x0D0C0B00, 0x0000000A,}, + {} +}; + +static const struct board_specific_parameters rdimm0[] = { + /* + * memory controller 0 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 + */ + {2, 1350, 0, 4, 6, 0x0708090B, 0x0C0D0E09,}, + {2, 1666, 0, 4, 7, 0x08090A0C, 0x0D0F100B,}, + {2, 1900, 0, 4, 7, 0x09090B0D, 0x0E10120B,}, + {2, 2200, 0, 4, 8, 0x090A0C0F, 0x1012130C,}, + {} +}; + +/* DP-DDR DIMM */ +static const struct board_specific_parameters rdimm2[] = { + /* + * memory controller 2 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 + */ + {2, 1350, 0, 4, 6, 0x0708090B, 0x0C0D0E09,}, + {2, 1666, 0, 4, 7, 0x0B0A090C, 0x0D0F100B,}, + {2, 1900, 0, 4, 7, 0x09090B0D, 0x0E10120B,}, + {2, 2200, 0, 4, 8, 0x090A0C0F, 0x1012130C,}, + {} +}; + +static const struct board_specific_parameters *udimms[] = { + udimm0, + udimm0, + udimm2, +}; + +static const struct board_specific_parameters *rdimms[] = { + rdimm0, + rdimm0, + rdimm2, +}; + + +#endif diff --git a/board/freescale/ls2085aqds/eth.c b/board/freescale/ls2085aqds/eth.c new file mode 100644 index 0000000..5ba4770 --- /dev/null +++ b/board/freescale/ls2085aqds/eth.c @@ -0,0 +1,380 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <netdev.h> +#include <asm/io.h> +#include <asm/arch/fsl_serdes.h> +#include <asm/arch-fsl-lsch3/immap_lsch3.h> +#include <fsl_mdio.h> +#include <malloc.h> +#include <fm_eth.h> +#include <fsl-mc/ldpaa_wriop.h> + +#include "../common/qixis.h" + +#include "ls2085aqds_qixis.h" + + +#ifdef CONFIG_FSL_MC_ENET + /* - In LS2085A there are only 16 SERDES lanes, spread across 2 SERDES banks. + * Bank 1 -> Lanes A, B, C, D, E, F, G, H + * Bank 2 -> Lanes A,B, C, D, E, F, G, H + */ + + /* Mapping of 16 SERDES lanes to LS2085A QDS 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_fsm2[] = { + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs + * housed. + */ +static int riser_phy_addr[] = { + SGMII_CARD_PORT1_PHY_ADDR, + SGMII_CARD_PORT2_PHY_ADDR, + SGMII_CARD_PORT3_PHY_ADDR, + SGMII_CARD_PORT4_PHY_ADDR, +}; + +/* Slot2 does not have EMI connections */ +#define EMI_NONE 0xFFFFFFFF +#define EMI1_SLOT1 0 +#define EMI1_SLOT2 1 +#define EMI1_SLOT3 2 +#define EMI1_SLOT4 3 +#define EMI1_SLOT5 4 +#define EMI1_SLOT6 5 +#define EMI2 6 +#define SFP_TX 1 + +static const char * const mdio_names[] = { + "LS2085A_QDS_MDIO0", + "LS2085A_QDS_MDIO1", + "LS2085A_QDS_MDIO2", + "LS2085A_QDS_MDIO3", + "LS2085A_QDS_MDIO4", + "LS2085A_QDS_MDIO5", + DEFAULT_WRIOP_MDIO2_NAME, +}; + +struct ls2085a_qds_mdio { + u8 muxval; + struct mii_dev *realbus; +}; + +static const char *ls2085a_qds_mdio_name_for_muxval(u8 muxval) +{ + return mdio_names[muxval]; +} + +struct mii_dev *mii_dev_for_muxval(u8 muxval) +{ + struct mii_dev *bus; + const char *name = ls2085a_qds_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; +} + +static void ls2085a_qds_enable_SFP_TX(u8 muxval) +{ + u8 brdcfg9; + + brdcfg9 = QIXIS_READ(brdcfg[9]); + brdcfg9 &= ~BRDCFG9_SFPTX_MASK; + brdcfg9 |= (muxval << BRDCFG9_SFPTX_SHIFT); + QIXIS_WRITE(brdcfg[9], brdcfg9); +} + +static void ls2085a_qds_mux_mdio(u8 muxval) +{ + u8 brdcfg4; + + if (muxval <= 5) { + brdcfg4 = QIXIS_READ(brdcfg[4]); + brdcfg4 &= ~BRDCFG4_EMISEL_MASK; + brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT); + QIXIS_WRITE(brdcfg[4], brdcfg4); + } +} + +static int ls2085a_qds_mdio_read(struct mii_dev *bus, int addr, + int devad, int regnum) +{ + struct ls2085a_qds_mdio *priv = bus->priv; + + ls2085a_qds_mux_mdio(priv->muxval); + + return priv->realbus->read(priv->realbus, addr, devad, regnum); +} + +static int ls2085a_qds_mdio_write(struct mii_dev *bus, int addr, int devad, + int regnum, u16 value) +{ + struct ls2085a_qds_mdio *priv = bus->priv; + + ls2085a_qds_mux_mdio(priv->muxval); + + return priv->realbus->write(priv->realbus, addr, devad, regnum, value); +} + +static int ls2085a_qds_mdio_reset(struct mii_dev *bus) +{ + struct ls2085a_qds_mdio *priv = bus->priv; + + return priv->realbus->reset(priv->realbus); +} + +static int ls2085a_qds_mdio_init(char *realbusname, u8 muxval) +{ + struct ls2085a_qds_mdio *pmdio; + struct mii_dev *bus = mdio_alloc(); + + if (!bus) { + printf("Failed to allocate ls2085a_qds MDIO bus\n"); + return -1; + } + + pmdio = malloc(sizeof(*pmdio)); + if (!pmdio) { + printf("Failed to allocate ls2085a_qds private data\n"); + free(bus); + return -1; + } + + bus->read = ls2085a_qds_mdio_read; + bus->write = ls2085a_qds_mdio_write; + bus->reset = ls2085a_qds_mdio_reset; + sprintf(bus->name, ls2085a_qds_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); +} + +/* + * Initialize the dpmac_info array. + * + */ +static void initialize_dpmac_to_slot(void) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) & + FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK) + >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT; + int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) & + FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK) + >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT; + + + switch (serdes1_prtcl) { + case 0x2A: + printf("qds: WRIOP: Supported SerDes Protocol 0x%02x\n", + serdes1_prtcl); + break; + default: + printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n", + serdes1_prtcl); + break; + } + + switch (serdes2_prtcl) { + case 0x07: + case 0x08: + printf("qds: WRIOP: Supported SerDes Protocol 0x%02x\n", + serdes2_prtcl); + lane_to_slot_fsm2[0] = EMI1_SLOT4; + lane_to_slot_fsm2[1] = EMI1_SLOT4; + lane_to_slot_fsm2[2] = EMI1_SLOT4; + lane_to_slot_fsm2[3] = EMI1_SLOT4; + /* No MDIO physical connection */ + lane_to_slot_fsm2[4] = EMI1_SLOT6; + lane_to_slot_fsm2[5] = EMI1_SLOT6; + lane_to_slot_fsm2[6] = EMI1_SLOT6; + lane_to_slot_fsm2[7] = EMI1_SLOT6; + break; + default: + printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n", + serdes2_prtcl); + break; + } +} + +void ls2085a_handle_phy_interface_sgmii(int dpmac_id) +{ + int lane, slot; + struct mii_dev *bus; + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) & + FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK) + >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT; + int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) & + FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK) + >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT; + + switch (serdes1_prtcl) { + } + + switch (serdes2_prtcl) { + case 0x07: + case 0x08: + lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 + + (dpmac_id - 9)); + slot = lane_to_slot_fsm2[lane]; + + switch (++slot) { + case 1: + break; + case 3: + break; + case 4: + /* Slot housing a SGMII riser card? */ + wriop_set_phy_address(dpmac_id, + riser_phy_addr[dpmac_id - 9]); + dpmac_info[dpmac_id].board_mux = EMI1_SLOT4; + bus = mii_dev_for_muxval(EMI1_SLOT4); + wriop_set_mdio(dpmac_id, bus); + dpmac_info[dpmac_id].phydev = phy_connect( + dpmac_info[dpmac_id].bus, + dpmac_info[dpmac_id].phy_addr, + NULL, + dpmac_info[dpmac_id].enet_if); + phy_config(dpmac_info[dpmac_id].phydev); + break; + case 5: + break; + case 6: + /* Slot housing a SGMII riser card? */ + wriop_set_phy_address(dpmac_id, + riser_phy_addr[dpmac_id - 13]); + dpmac_info[dpmac_id].board_mux = EMI1_SLOT6; + bus = mii_dev_for_muxval(EMI1_SLOT6); + wriop_set_mdio(dpmac_id, bus); + break; + } + break; + default: + printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n", + serdes2_prtcl); + break; + } +} +void ls2085a_handle_phy_interface_xsgmii(int i) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) & + FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK) + >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT; + + switch (serdes1_prtcl) { + case 0x2A: + /* + * XFI does not need a PHY to work, but to avoid U-boot use + * default PHY address which is zero to a MAC when it found + * a MAC has no PHY address, we give a PHY address to XFI + * MAC, and should not use a real XAUI PHY address, since + * MDIO can access it successfully, and then MDIO thinks + * the XAUI card is used for the XFI MAC, which will cause + * error. + */ + wriop_set_phy_address(i, i + 4); + ls2085a_qds_enable_SFP_TX(SFP_TX); + + break; + default: + printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n", + serdes1_prtcl); + break; + } +} +#endif + +int board_eth_init(bd_t *bis) +{ + int error; +#ifdef CONFIG_FSL_MC_ENET + struct memac_mdio_info *memac_mdio0_info; + struct memac_mdio_info *memac_mdio1_info; + unsigned int i; + + initialize_dpmac_to_slot(); + + memac_mdio0_info = (struct memac_mdio_info *)malloc( + sizeof(struct memac_mdio_info)); + memac_mdio0_info->regs = + (struct memac_mdio_controller *) + CONFIG_SYS_FSL_WRIOP1_MDIO1; + memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME; + + /* Register the real MDIO1 bus */ + fm_memac_mdio_init(bis, memac_mdio0_info); + + memac_mdio1_info = (struct memac_mdio_info *)malloc( + sizeof(struct memac_mdio_info)); + memac_mdio1_info->regs = + (struct memac_mdio_controller *) + CONFIG_SYS_FSL_WRIOP1_MDIO2; + memac_mdio1_info->name = DEFAULT_WRIOP_MDIO2_NAME; + + /* Register the real MDIO2 bus */ + fm_memac_mdio_init(bis, memac_mdio1_info); + + /* Register the muxing front-ends to the MDIO buses */ + ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1); + ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT2); + ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT3); + ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT4); + ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT5); + ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT6); + + ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO2_NAME, EMI2); + + for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { + switch (wriop_get_enet_if(i)) { + case PHY_INTERFACE_MODE_QSGMII: + break; + case PHY_INTERFACE_MODE_SGMII: + ls2085a_handle_phy_interface_sgmii(i); + break; + case PHY_INTERFACE_MODE_XGMII: + ls2085a_handle_phy_interface_xsgmii(i); + break; + default: + break; + } + } + + error = cpu_eth_init(bis); +#endif + error = pci_eth_init(bis); + return error; +} diff --git a/board/freescale/ls2085aqds/ls2085aqds.c b/board/freescale/ls2085aqds/ls2085aqds.c new file mode 100644 index 0000000..6a22122 --- /dev/null +++ b/board/freescale/ls2085aqds/ls2085aqds.c @@ -0,0 +1,274 @@ +/* + * Copyright 2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <malloc.h> +#include <errno.h> +#include <netdev.h> +#include <fsl_ifc.h> +#include <fsl_ddr.h> +#include <asm/io.h> +#include <fdt_support.h> +#include <libfdt.h> +#include <fsl_debug_server.h> +#include <fsl-mc/fsl_mc.h> +#include <environment.h> +#include <i2c.h> +#include <asm/arch-fsl-lsch3/soc.h> + +#include "../common/qixis.h" +#include "ls2085aqds_qixis.h" + +DECLARE_GLOBAL_DATA_PTR; + +unsigned long long get_qixis_addr(void) +{ + unsigned long long addr; + + if (gd->flags & GD_FLG_RELOC) + addr = QIXIS_BASE_PHYS; + else + addr = QIXIS_BASE_PHYS_EARLY; + + /* + * IFC address under 256MB is mapped to 0x30000000, any address above + * is mapped to 0x5_10000000 up to 4GB. + */ + addr = addr > 0x10000000 ? addr + 0x500000000ULL : addr + 0x30000000; + + return addr; +} + +int checkboard(void) +{ + char buf[64]; + u8 sw; + static const char *const freq[] = {"100", "125", "156.25", + "100 separate SSCG"}; + int clock; + + sw = QIXIS_READ(arch); + printf("Board: %s, ", CONFIG_IDENT_STRING); + printf("Board Arch: V%d, ", sw >> 4); + printf("Board version: %c, boot from ", (sw & 0xf) + 'A' - 1); + + 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 if (sw == 0x15) + printf("IFCCard\n"); + else + printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH); + + printf("FPGA: v%d (%s), build %d", + (int)QIXIS_READ(scver), qixis_read_tag(buf), + (int)qixis_read_minor()); + /* the timestamp string contains "\n" at the end */ + printf(" on %s", qixis_read_time(buf)); + + /* + * Display the actual SERDES reference clocks as configured by the + * dip switches on the board. Note that the SWx registers could + * technically be set to force the reference clocks to match the + * values that the SERDES expects (or vice versa). For now, however, + * we just display both values and hope the user notices when they + * don't match. + */ + puts("SERDES1 Reference : "); + sw = QIXIS_READ(brdcfg[2]); + clock = (sw >> 6) & 3; + printf("Clock1 = %sMHz ", freq[clock]); + clock = (sw >> 4) & 3; + printf("Clock2 = %sMHz", freq[clock]); + + puts("\nSERDES2 Reference : "); + clock = (sw >> 2) & 3; + printf("Clock1 = %sMHz ", freq[clock]); + clock = (sw >> 0) & 3; + printf("Clock2 = %sMHz\n", freq[clock]); + + return 0; +} + +unsigned long get_board_sys_clk(void) +{ + u8 sysclk_conf = QIXIS_READ(brdcfg[1]); + + switch (sysclk_conf & 0x0F) { + case QIXIS_SYSCLK_83: + return 83333333; + case QIXIS_SYSCLK_100: + return 100000000; + case QIXIS_SYSCLK_125: + return 125000000; + case QIXIS_SYSCLK_133: + return 133333333; + case QIXIS_SYSCLK_150: + return 150000000; + case QIXIS_SYSCLK_160: + return 160000000; + case QIXIS_SYSCLK_166: + return 166666666; + } + return 66666666; +} + +unsigned long get_board_ddr_clk(void) +{ + u8 ddrclk_conf = QIXIS_READ(brdcfg[1]); + + switch ((ddrclk_conf & 0x30) >> 4) { + case QIXIS_DDRCLK_100: + return 100000000; + case QIXIS_DDRCLK_125: + return 125000000; + case QIXIS_DDRCLK_133: + return 133333333; + } + return 66666666; +} + +int select_i2c_ch_pca9547(u8 ch) +{ + int ret; + + ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1); + if (ret) { + puts("PCA: failed to select proper channel\n"); + return ret; + } + + return 0; +} + +int board_init(void) +{ + init_final_memctl_regs(); + +#ifdef CONFIG_ENV_IS_NOWHERE + gd->env_addr = (ulong)&default_environment[0]; +#endif + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); + + return 0; +} + +int board_early_init_f(void) +{ + fsl_lsch3_early_init_f(); + return 0; +} + +void detail_board_ddr_info(void) +{ + puts("\nDDR "); + print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, ""); + print_ddr_info(0); + if (gd->bd->bi_dram[2].size) { + puts("\nDP-DDR "); + print_size(gd->bd->bi_dram[2].size, ""); + print_ddr_info(CONFIG_DP_DDR_CTRL); + } +} + +int dram_init(void) +{ + gd->ram_size = initdram(0); + + return 0; +} + +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ +#ifdef CONFIG_FSL_DEBUG_SERVER + debug_server_init(); +#endif + + return 0; +} +#endif + +unsigned long get_dram_size_to_hide(void) +{ + unsigned long dram_to_hide = 0; + +/* Carve the Debug Server private DRAM block from the end of DRAM */ +#ifdef CONFIG_FSL_DEBUG_SERVER + dram_to_hide += debug_server_get_dram_block_size(); +#endif + +/* Carve the MC private DRAM block from the end of DRAM */ +#ifdef CONFIG_FSL_MC_ENET + dram_to_hide += mc_get_dram_block_size(); +#endif + + return dram_to_hide; +} + +#ifdef CONFIG_FSL_MC_ENET +void fdt_fixup_board_enet(void *fdt) +{ + int offset; + + offset = fdt_path_offset(fdt, "/fsl-mc"); + + if (offset < 0) + offset = fdt_path_offset(fdt, "/fsl,dprc@0"); + + if (offset < 0) { + printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n", + __func__, offset); + return; + } + + if (get_mc_boot_status() == 0) + fdt_status_okay(fdt, offset); + else + fdt_status_fail(fdt, offset); +} +#endif + +#ifdef CONFIG_OF_BOARD_SETUP +int ft_board_setup(void *blob, bd_t *bd) +{ + phys_addr_t base; + phys_size_t size; + + ft_cpu_setup(blob, bd); + + /* limit the memory size to bank 1 until Linux can handle 40-bit PA */ + base = getenv_bootm_low(); + size = getenv_bootm_size(); + fdt_fixup_memory(blob, (u64)base, (u64)size); + +#ifdef CONFIG_FSL_MC_ENET + fdt_fixup_board_enet(blob); + fsl_mc_ldpaa_exit(bd); +#endif + + return 0; +} +#endif + +void qixis_dump_switch(void) +{ + int i, nr_of_cfgsw; + + QIXIS_WRITE(cms[0], 0x00); + nr_of_cfgsw = QIXIS_READ(cms[1]); + + puts("DIP switch settings dump:\n"); + for (i = 1; i <= nr_of_cfgsw; i++) { + QIXIS_WRITE(cms[0], i); + printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1])); + } +} diff --git a/board/freescale/ls2085aqds/ls2085aqds_qixis.h b/board/freescale/ls2085aqds/ls2085aqds_qixis.h new file mode 100644 index 0000000..e281e5f --- /dev/null +++ b/board/freescale/ls2085aqds/ls2085aqds_qixis.h @@ -0,0 +1,30 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __LS2_QDS_QIXIS_H__ +#define __LS2_QDS_QIXIS_H__ + +/* SYSCLK */ +#define QIXIS_SYSCLK_66 0x0 +#define QIXIS_SYSCLK_83 0x1 +#define QIXIS_SYSCLK_100 0x2 +#define QIXIS_SYSCLK_125 0x3 +#define QIXIS_SYSCLK_133 0x4 +#define QIXIS_SYSCLK_150 0x5 +#define QIXIS_SYSCLK_160 0x6 +#define QIXIS_SYSCLK_166 0x7 + +/* DDRCLK */ +#define QIXIS_DDRCLK_66 0x0 +#define QIXIS_DDRCLK_100 0x1 +#define QIXIS_DDRCLK_125 0x2 +#define QIXIS_DDRCLK_133 0x3 + +#define BRDCFG4_EMISEL_MASK 0xE0 +#define BRDCFG4_EMISEL_SHIFT 5 +#define BRDCFG9_SFPTX_MASK 0x10 +#define BRDCFG9_SFPTX_SHIFT 4 +#endif /*__LS2_QDS_QIXIS_H__*/ diff --git a/board/freescale/ls2085ardb/Kconfig b/board/freescale/ls2085ardb/Kconfig new file mode 100644 index 0000000..85a3dcd --- /dev/null +++ b/board/freescale/ls2085ardb/Kconfig @@ -0,0 +1,16 @@ + +if TARGET_LS2085ARDB + +config SYS_BOARD + default "ls2085ardb" + +config SYS_VENDOR + default "freescale" + +config SYS_SOC + default "fsl-lsch3" + +config SYS_CONFIG_NAME + default "ls2085ardb" + +endif diff --git a/board/freescale/ls2085ardb/MAINTAINERS b/board/freescale/ls2085ardb/MAINTAINERS new file mode 100644 index 0000000..d5cce40 --- /dev/null +++ b/board/freescale/ls2085ardb/MAINTAINERS @@ -0,0 +1,8 @@ +LS2085A BOARD +M: Prabhakar Kushwaha <prabhakar@freescale.com> +S: Maintained +F: board/freescale/ls2085ardb/ +F: board/freescale/ls2085a/ls2085ardb.c +F: include/configs/ls2085ardb.h +F: configs/ls2085ardb_defconfig +F: configs/ls2085ardb_nand_defconfig diff --git a/board/freescale/ls2085ardb/Makefile b/board/freescale/ls2085ardb/Makefile new file mode 100644 index 0000000..0bfe21c --- /dev/null +++ b/board/freescale/ls2085ardb/Makefile @@ -0,0 +1,8 @@ +# +# Copyright 2015 Freescale Semiconductor +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ls2085ardb.o +obj-y += ddr.o diff --git a/board/freescale/ls2085ardb/README b/board/freescale/ls2085ardb/README new file mode 100644 index 0000000..cfd5185 --- /dev/null +++ b/board/freescale/ls2085ardb/README @@ -0,0 +1,109 @@ +Overview +-------- +The LS2085A Reference Design (RDB) is a high-performance computing, +evaluation, and development platform that supports the QorIQ LS2085A +Layerscape Architecture processor. + +LS2085A SoC Overview +------------------ +The LS2085A integrated multicore processor combines eight ARM Cortex-A57 +processor cores with high-performance data path acceleration logic and network +and peripheral bus interfaces required for networking, telecom/datacom, +wireless infrastructure, and mil/aerospace applications. + +The LS2085A SoC includes the following function and features: + + - Eight 64-bit ARM Cortex-A57 CPUs + - 1 MB platform cache with ECC + - Two 64-bit DDR4 SDRAM memory controllers with ECC and interleaving support + - One secondary 32-bit DDR4 SDRAM memory controller, intended for use by + the AIOP + - Data path acceleration architecture (DPAA2) incorporating acceleration for + the following functions: + - Packet parsing, classification, and distribution (WRIOP) + - Queue and Hardware buffer management for scheduling, packet sequencing, and + congestion management, buffer allocation and de-allocation (QBMan) + - Cryptography acceleration (SEC) at up to 10 Gbps + - RegEx pattern matching acceleration (PME) at up to 10 Gbps + - Decompression/compression acceleration (DCE) at up to 20 Gbps + - Accelerated I/O processing (AIOP) at up to 20 Gbps + - QDMA engine + - 16 SerDes lanes at up to 10.3125 GHz + - Ethernet interfaces + - Up to eight 10 Gbps Ethernet MACs + - Up to eight 1 / 2.5 Gbps Ethernet MACs + - High-speed peripheral interfaces + - Four PCIe 3.0 controllers, one supporting SR-IOV + - Additional peripheral interfaces + - Two serial ATA (SATA 3.0) controllers + - Two high-speed USB 3.0 controllers with integrated PHY + - Enhanced secure digital host controller (eSDXC/eMMC) + - Serial peripheral interface (SPI) controller + - Quad Serial Peripheral Interface (QSPI) Controller + - Four I2C controllers + - Two DUARTs + - Integrated flash controller (IFC 2.0) supporting NAND and NOR flash + - Support for hardware virtualization and partitioning enforcement + - QorIQ platform's trust architecture 3.0 + - Service processor (SP) provides pre-boot initialization and secure-boot + capabilities + + LS2085ARDB board Overview + ----------------------- + - SERDES Connections, 16 lanes supporting: + - PCI Express - 3.0 + - SATA 3.0 + - XFI + - DDR Controller + - Two ports of 72-bits (8-bits ECC) DDR4. Each port supports four + chip-selects and two DIMM connectors. Support is up to 2133MT/s. + - One port of 40-bits (8-bits ECC) DDR4 which supports four chip-selects + and two DIMM connectors. Support is up to 1600MT/s. + -IFC/Local Bus + - IFC rev. 2.0 implementation supporting Little Endian connection scheme. + - 128 MB NOR flash 16-bit data bus + - One 2 GB NAND flash with ECC support + - CPLD connection + - USB 3.0 + - Two high speed USB 3.0 ports + - First USB 3.0 port configured as Host with Type-A connector + - Second USB 3.0 port configured as OTG with micro-AB connector + - SDHC adapter + - SD Card Rev 2.0 and Rev 3.0 + - DSPI + - 128 MB high-speed flash Memory for boot code and storage (up to 108MHz) + - 4 I2C controllers + - Two SATA onboard connectors + - UART + - ARM JTAG support + +Memory map from core's view +---------------------------- +0x00_0000_0000 .. 0x00_000F_FFFF Boot Rom +0x00_0100_0000 .. 0x00_0FFF_FFFF CCSR +0x00_1800_0000 .. 0x00_181F_FFFF OCRAM +0x00_3000_0000 .. 0x00_3FFF_FFFF IFC region #1 +0x00_8000_0000 .. 0x00_FFFF_FFFF DDR region #1 +0x05_1000_0000 .. 0x05_FFFF_FFFF IFC region #2 +0x80_8000_0000 .. 0xFF_FFFF_FFFF DDR region #2 + +Other addresses are either reserved, or not used directly by u-boot. +This list should be updated when more addresses are used. + +IFC region map from core's view +------------------------------- +During boot i.e. IFC Region #1:- + 0x30000000 - 0x37ffffff : 128MB : NOR flash + 0x3C000000 - 0x40000000 : 64MB : CPLD + +After relocate to DDR i.e. IFC Region #2:- + 0x5_1000_0000..0x5_1fff_ffff Memory Hole + 0x5_2000_0000..0x5_3fff_ffff IFC CSx (CPLD, NAND and others 512MB) + 0x5_4000_0000..0x5_7fff_ffff ASIC or others 1GB + 0x5_8000_0000..0x5_bfff_ffff IFC CS0 1GB (NOR/Promjet) + 0x5_C000_0000..0x5_ffff_ffff IFC CS1 1GB (NOR/Promjet) + +Booting Options +--------------- +a) NOR boot +b) NAND boot diff --git a/board/freescale/ls2085ardb/ddr.c b/board/freescale/ls2085ardb/ddr.c new file mode 100644 index 0000000..8d71ae1 --- /dev/null +++ b/board/freescale/ls2085ardb/ddr.c @@ -0,0 +1,196 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <fsl_ddr_sdram.h> +#include <fsl_ddr_dimm_params.h> +#include "ddr.h" + +DECLARE_GLOBAL_DATA_PTR; + +void fsl_ddr_board_options(memctl_options_t *popts, + dimm_params_t *pdimm, + unsigned int ctrl_num) +{ + u8 dq_mapping_0, dq_mapping_2, dq_mapping_3; + const struct board_specific_parameters *pbsp, *pbsp_highest = NULL; + ulong ddr_freq; + int slot; + + if (ctrl_num > 2) { + printf("Not supported controller number %d\n", ctrl_num); + return; + } + + for (slot = 0; slot < CONFIG_DIMM_SLOTS_PER_CTLR; slot++) { + if (pdimm[slot].n_ranks) + break; + } + + if (slot >= CONFIG_DIMM_SLOTS_PER_CTLR) + return; + + /* + * we use identical timing for all slots. If needed, change the code + * to pbsp = rdimms[ctrl_num] or pbsp = udimms[ctrl_num]; + */ + if (popts->registered_dimm_en) + pbsp = rdimms[ctrl_num]; + else + pbsp = udimms[ctrl_num]; + + + /* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr + * freqency and n_banks specified in board_specific_parameters table. + */ + ddr_freq = get_ddr_freq(ctrl_num) / 1000000; + while (pbsp->datarate_mhz_high) { + if (pbsp->n_ranks == pdimm[slot].n_ranks && + (pdimm[slot].rank_density >> 30) >= pbsp->rank_gb) { + if (ddr_freq <= pbsp->datarate_mhz_high) { + popts->clk_adjust = pbsp->clk_adjust; + popts->wrlvl_start = pbsp->wrlvl_start; + popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2; + popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3; + 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->clk_adjust = pbsp_highest->clk_adjust; + popts->wrlvl_start = pbsp_highest->wrlvl_start; + popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2; + popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3; + } else { + panic("DIMM is not supported by this board"); + } +found: + debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n" + "\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x, wrlvl_ctrl_3 0x%x\n", + pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb, + pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2, + pbsp->wrlvl_ctl_3); + + if (ctrl_num == CONFIG_DP_DDR_CTRL) { + /* force DDR bus width to 32 bits */ + popts->data_bus_width = 1; + popts->otf_burst_chop_en = 0; + popts->burst_length = DDR_BL8; + popts->bstopre = 0; /* enable auto precharge */ + /* + * Layout optimization results byte mapping + * Byte 0 -> Byte ECC + * Byte 1 -> Byte 3 + * Byte 2 -> Byte 2 + * Byte 3 -> Byte 1 + * Byte ECC -> Byte 0 + */ + dq_mapping_0 = pdimm[slot].dq_mapping[0]; + dq_mapping_2 = pdimm[slot].dq_mapping[2]; + dq_mapping_3 = pdimm[slot].dq_mapping[3]; + pdimm[slot].dq_mapping[0] = pdimm[slot].dq_mapping[8]; + pdimm[slot].dq_mapping[1] = pdimm[slot].dq_mapping[9]; + pdimm[slot].dq_mapping[2] = pdimm[slot].dq_mapping[6]; + pdimm[slot].dq_mapping[3] = pdimm[slot].dq_mapping[7]; + pdimm[slot].dq_mapping[6] = dq_mapping_2; + pdimm[slot].dq_mapping[7] = dq_mapping_3; + pdimm[slot].dq_mapping[8] = dq_mapping_0; + pdimm[slot].dq_mapping[9] = 0; + pdimm[slot].dq_mapping[10] = 0; + pdimm[slot].dq_mapping[11] = 0; + pdimm[slot].dq_mapping[12] = 0; + pdimm[slot].dq_mapping[13] = 0; + pdimm[slot].dq_mapping[14] = 0; + pdimm[slot].dq_mapping[15] = 0; + pdimm[slot].dq_mapping[16] = 0; + pdimm[slot].dq_mapping[17] = 0; + } + /* To work at higher than 1333MT/s */ + popts->half_strength_driver_enable = 0; + /* + * Write leveling override + */ + popts->wrlvl_override = 1; + popts->wrlvl_sample = 0x0; /* 32 clocks */ + + /* + * Rtt and Rtt_WR override + */ + popts->rtt_override = 0; + + /* Enable ZQ calibration */ + popts->zq_en = 1; + + if (ddr_freq < 2350) { + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | + DDR_CDR1_ODT(DDR_CDR_ODT_60ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) | + DDR_CDR2_VREF_RANGE_2; + } else { + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | + DDR_CDR1_ODT(DDR_CDR_ODT_100ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_100ohm) | + DDR_CDR2_VREF_RANGE_2; + } +} + +phys_size_t initdram(int board_type) +{ + phys_size_t dram_size; + +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) + return fsl_ddr_sdram_size(); +#else + puts("Initializing DDR....using SPD\n"); + + dram_size = fsl_ddr_sdram(); +#endif + + return dram_size; +} + +void dram_init_banksize(void) +{ +#ifdef CONFIG_SYS_DP_DDR_BASE_PHY + phys_size_t dp_ddr_size; +#endif + + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) { + gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; + gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE; + gd->bd->bi_dram[1].size = gd->ram_size - + CONFIG_SYS_LS2_DDR_BLOCK1_SIZE; + } else { + gd->bd->bi_dram[0].size = gd->ram_size; + } + +#ifdef CONFIG_SYS_DP_DDR_BASE_PHY + /* initialize DP-DDR here */ + puts("DP-DDR: "); + /* + * DDR controller use 0 as the base address for binding. + * It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access. + */ + dp_ddr_size = fsl_other_ddr_sdram(CONFIG_SYS_DP_DDR_BASE_PHY, + CONFIG_DP_DDR_CTRL, + CONFIG_DP_DDR_NUM_CTRLS, + CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR, + NULL, NULL, NULL); + if (dp_ddr_size) { + gd->bd->bi_dram[2].start = CONFIG_SYS_DP_DDR_BASE; + gd->bd->bi_dram[2].size = dp_ddr_size; + } else { + puts("Not detected"); + } +#endif +} diff --git a/board/freescale/ls2085ardb/ddr.h b/board/freescale/ls2085ardb/ddr.h new file mode 100644 index 0000000..bda9d4a --- /dev/null +++ b/board/freescale/ls2085ardb/ddr.h @@ -0,0 +1,92 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __DDR_H__ +#define __DDR_H__ +struct board_specific_parameters { + u32 n_ranks; + u32 datarate_mhz_high; + u32 rank_gb; + u32 clk_adjust; + u32 wrlvl_start; + u32 wrlvl_ctl_2; + u32 wrlvl_ctl_3; +}; + +/* + * These tables contain 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_parameters udimm0[] = { + /* + * memory controller 0 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 + */ + {2, 1350, 0, 4, 6, 0x0708090B, 0x0C0D0E09,}, + {2, 1666, 0, 4, 8, 0x08090B0D, 0x0E10100C,}, + {2, 1900, 0, 4, 8, 0x090A0C0E, 0x1012120D,}, + {2, 2300, 0, 4, 9, 0x0A0B0C10, 0x1114140E,}, + {} +}; + +/* DP-DDR DIMM */ +static const struct board_specific_parameters udimm2[] = { + /* + * memory controller 2 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 + */ + {2, 1350, 0, 4, 0xd, 0x0C0A0A00, 0x00000009,}, + {2, 1666, 0, 4, 0xd, 0x0C0A0A00, 0x00000009,}, + {2, 1900, 0, 4, 0xe, 0x0D0C0B00, 0x0000000A,}, + {2, 2200, 0, 4, 0xe, 0x0D0C0B00, 0x0000000A,}, + {} +}; + +static const struct board_specific_parameters rdimm0[] = { + /* + * memory controller 0 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 + */ + {2, 1350, 0, 4, 6, 0x0708090B, 0x0C0D0E09,}, + {2, 1666, 0, 4, 7, 0x08090A0C, 0x0D0F100B,}, + {2, 1900, 0, 4, 7, 0x09090B0D, 0x0E10120B,}, + {2, 2200, 0, 4, 8, 0x090A0C0F, 0x1012130C,}, + {} +}; + +/* DP-DDR DIMM */ +static const struct board_specific_parameters rdimm2[] = { + /* + * memory controller 2 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 + */ + {2, 1350, 0, 4, 6, 0x0708090B, 0x0C0D0E09,}, + {2, 1666, 0, 4, 7, 0x0B0A090C, 0x0D0F100B,}, + {2, 1900, 0, 4, 7, 0x09090B0D, 0x0E10120B,}, + {2, 2200, 0, 4, 8, 0x090A0C0F, 0x1012130C,}, + {} +}; + +static const struct board_specific_parameters *udimms[] = { + udimm0, + udimm0, + udimm2, +}; + +static const struct board_specific_parameters *rdimms[] = { + rdimm0, + rdimm0, + rdimm2, +}; + + +#endif diff --git a/board/freescale/ls2085ardb/ls2085ardb.c b/board/freescale/ls2085ardb/ls2085ardb.c new file mode 100644 index 0000000..d05f2bc --- /dev/null +++ b/board/freescale/ls2085ardb/ls2085ardb.c @@ -0,0 +1,249 @@ +/* + * Copyright 2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <malloc.h> +#include <errno.h> +#include <netdev.h> +#include <fsl_ifc.h> +#include <fsl_ddr.h> +#include <asm/io.h> +#include <fdt_support.h> +#include <libfdt.h> +#include <fsl_debug_server.h> +#include <fsl-mc/fsl_mc.h> +#include <environment.h> +#include <i2c.h> +#include <asm/arch-fsl-lsch3/soc.h> + +#include "../common/qixis.h" +#include "ls2085ardb_qixis.h" + +DECLARE_GLOBAL_DATA_PTR; + +unsigned long long get_qixis_addr(void) +{ + unsigned long long addr; + + if (gd->flags & GD_FLG_RELOC) + addr = QIXIS_BASE_PHYS; + else + addr = QIXIS_BASE_PHYS_EARLY; + + /* + * IFC address under 256MB is mapped to 0x30000000, any address above + * is mapped to 0x5_10000000 up to 4GB. + */ + addr = addr > 0x10000000 ? addr + 0x500000000ULL : addr + 0x30000000; + + return addr; +} + +int checkboard(void) +{ + u8 sw; + + sw = QIXIS_READ(arch); + printf("Board: %s, ", CONFIG_IDENT_STRING); + printf("Board Arch: V%d, ", sw >> 4); + printf("Board version: %c, boot from ", (sw & 0xf) + 'A' - 1); + + sw = QIXIS_READ(brdcfg[0]); + sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT; + + if (sw < 0x8) + printf("vBank: %d\n", sw); + else if (sw == 0x9) + puts("NAND\n"); + else + printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH); + + printf("FPGA: v%d.%d\n", QIXIS_READ(scver), QIXIS_READ(tagdata)); + + puts("SERDES1 Reference : "); + printf("Clock1 = 156.25MHz "); + printf("Clock2 = 156.25MHz"); + + puts("\nSERDES2 Reference : "); + printf("Clock1 = 100MHz "); + printf("Clock2 = 100MHz\n"); + + return 0; +} + +unsigned long get_board_sys_clk(void) +{ + u8 sysclk_conf = QIXIS_READ(brdcfg[1]); + + switch (sysclk_conf & 0x0F) { + case QIXIS_SYSCLK_83: + return 83333333; + case QIXIS_SYSCLK_100: + return 100000000; + case QIXIS_SYSCLK_125: + return 125000000; + case QIXIS_SYSCLK_133: + return 133333333; + case QIXIS_SYSCLK_150: + return 150000000; + case QIXIS_SYSCLK_160: + return 160000000; + case QIXIS_SYSCLK_166: + return 166666666; + } + return 66666666; +} + +int select_i2c_ch_pca9547(u8 ch) +{ + int ret; + + ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1); + if (ret) { + puts("PCA: failed to select proper channel\n"); + return ret; + } + + return 0; +} + +int board_init(void) +{ + init_final_memctl_regs(); + +#ifdef CONFIG_ENV_IS_NOWHERE + gd->env_addr = (ulong)&default_environment[0]; +#endif + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); + + QIXIS_WRITE(rst_ctl, QIXIS_RST_CTL_RESET_EN); + + return 0; +} + +int board_early_init_f(void) +{ + fsl_lsch3_early_init_f(); + return 0; +} + +void detail_board_ddr_info(void) +{ + puts("\nDDR "); + print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, ""); + print_ddr_info(0); + if (gd->bd->bi_dram[2].size) { + puts("\nDP-DDR "); + print_size(gd->bd->bi_dram[2].size, ""); + print_ddr_info(CONFIG_DP_DDR_CTRL); + } +} + +int dram_init(void) +{ + gd->ram_size = initdram(0); + + return 0; +} + +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ +#ifdef CONFIG_FSL_DEBUG_SERVER + debug_server_init(); +#endif + + return 0; +} +#endif + +unsigned long get_dram_size_to_hide(void) +{ + unsigned long dram_to_hide = 0; + +/* Carve the Debug Server private DRAM block from the end of DRAM */ +#ifdef CONFIG_FSL_DEBUG_SERVER + dram_to_hide += debug_server_get_dram_block_size(); +#endif + +/* Carve the MC private DRAM block from the end of DRAM */ +#ifdef CONFIG_FSL_MC_ENET + dram_to_hide += mc_get_dram_block_size(); +#endif + + return dram_to_hide; +} + +int board_eth_init(bd_t *bis) +{ + int error = 0; + +#ifdef CONFIG_FSL_MC_ENET + error = cpu_eth_init(bis); +#endif + + error = pci_eth_init(bis); + + return error; +} + +#ifdef CONFIG_FSL_MC_ENET +void fdt_fixup_board_enet(void *fdt) +{ + int offset; + + offset = fdt_path_offset(fdt, "/fsl-mc"); + + if (offset < 0) + offset = fdt_path_offset(fdt, "/fsl,dprc@0"); + + if (offset < 0) { + printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n", + __func__, offset); + return; + } + + if (get_mc_boot_status() == 0) + fdt_status_okay(fdt, offset); + else + fdt_status_fail(fdt, offset); +} +#endif + +#ifdef CONFIG_OF_BOARD_SETUP +int ft_board_setup(void *blob, bd_t *bd) +{ + phys_addr_t base; + phys_size_t size; + + ft_cpu_setup(blob, bd); + + /* limit the memory size to bank 1 until Linux can handle 40-bit PA */ + base = getenv_bootm_low(); + size = getenv_bootm_size(); + fdt_fixup_memory(blob, (u64)base, (u64)size); + +#ifdef CONFIG_FSL_MC_ENET + fdt_fixup_board_enet(blob); + fsl_mc_ldpaa_exit(bd); +#endif + + return 0; +} +#endif + +void qixis_dump_switch(void) +{ + int i, nr_of_cfgsw; + + QIXIS_WRITE(cms[0], 0x00); + nr_of_cfgsw = QIXIS_READ(cms[1]); + + puts("DIP switch settings dump:\n"); + for (i = 1; i <= nr_of_cfgsw; i++) { + QIXIS_WRITE(cms[0], i); + printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1])); + } +} diff --git a/board/freescale/ls2085ardb/ls2085ardb_qixis.h b/board/freescale/ls2085ardb/ls2085ardb_qixis.h new file mode 100644 index 0000000..cb60c00 --- /dev/null +++ b/board/freescale/ls2085ardb/ls2085ardb_qixis.h @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __LS2_RDB_QIXIS_H__ +#define __LS2_RDB_QIXIS_H__ + +/* SYSCLK */ +#define QIXIS_SYSCLK_66 0x0 +#define QIXIS_SYSCLK_83 0x1 +#define QIXIS_SYSCLK_100 0x2 +#define QIXIS_SYSCLK_125 0x3 +#define QIXIS_SYSCLK_133 0x4 +#define QIXIS_SYSCLK_150 0x5 +#define QIXIS_SYSCLK_160 0x6 +#define QIXIS_SYSCLK_166 0x7 + +#endif /*__LS2_RDB_QIXIS_H__*/ diff --git a/board/freescale/m5208evbe/u-boot.lds b/board/freescale/m5208evbe/u-boot.lds deleted file mode 100644 index 8b1a59d..0000000 --- a/board/freescale/m5208evbe/u-boot.lds +++ /dev/null @@ -1,86 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf52x2/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.sbss*) - *(.bss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m52277evb/u-boot.lds b/board/freescale/m52277evb/u-boot.lds deleted file mode 100644 index 70121d9..0000000 --- a/board/freescale/m52277evb/u-boot.lds +++ /dev/null @@ -1,85 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf5227x/start.o (.text*) - arch/m68k/cpu/mcf5227x/built-in.o (.text*) - arch/m68k/lib/built-in.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.sbss*) - *(.bss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m5235evb/u-boot.lds b/board/freescale/m5235evb/u-boot.lds deleted file mode 100644 index ccfb5d6..0000000 --- a/board/freescale/m5235evb/u-boot.lds +++ /dev/null @@ -1,85 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - .text : - { - arch/m68k/cpu/mcf523x/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m5249evb/u-boot.lds b/board/freescale/m5249evb/u-boot.lds deleted file mode 100644 index e91b7e1..0000000 --- a/board/freescale/m5249evb/u-boot.lds +++ /dev/null @@ -1,85 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - .text : - { - arch/m68k/cpu/mcf52x2/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m5253demo/u-boot.lds b/board/freescale/m5253demo/u-boot.lds deleted file mode 100644 index cd3d70a..0000000 --- a/board/freescale/m5253demo/u-boot.lds +++ /dev/null @@ -1,86 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf52x2/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss : - { - _sbss = .; - *(.sbss*) - *(.bss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m5253evbe/u-boot.lds b/board/freescale/m5253evbe/u-boot.lds deleted file mode 100644 index e91b7e1..0000000 --- a/board/freescale/m5253evbe/u-boot.lds +++ /dev/null @@ -1,85 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - .text : - { - arch/m68k/cpu/mcf52x2/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m5272c3/u-boot.lds b/board/freescale/m5272c3/u-boot.lds deleted file mode 100644 index e91b7e1..0000000 --- a/board/freescale/m5272c3/u-boot.lds +++ /dev/null @@ -1,85 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - .text : - { - arch/m68k/cpu/mcf52x2/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m5275evb/u-boot.lds b/board/freescale/m5275evb/u-boot.lds deleted file mode 100644 index 3112cbe..0000000 --- a/board/freescale/m5275evb/u-boot.lds +++ /dev/null @@ -1,85 +0,0 @@ -/* - * (C) Copyright 2000-2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - .text : - { - arch/m68k/cpu/mcf52x2/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m5282evb/u-boot.lds b/board/freescale/m5282evb/u-boot.lds deleted file mode 100644 index ce62ee9..0000000 --- a/board/freescale/m5282evb/u-boot.lds +++ /dev/null @@ -1,85 +0,0 @@ -/* - * (C) Copyright 2000-2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - .text : - { - arch/m68k/cpu/mcf52x2/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m53017evb/u-boot.lds b/board/freescale/m53017evb/u-boot.lds deleted file mode 100644 index b1cae59..0000000 --- a/board/freescale/m53017evb/u-boot.lds +++ /dev/null @@ -1,86 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf532x/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.sbss*) - *(.bss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m5329evb/u-boot.lds b/board/freescale/m5329evb/u-boot.lds deleted file mode 100644 index 097ac2e..0000000 --- a/board/freescale/m5329evb/u-boot.lds +++ /dev/null @@ -1,86 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf532x/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.sbss*) - *(.bss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m5373evb/u-boot.lds b/board/freescale/m5373evb/u-boot.lds deleted file mode 100644 index 8ef0620..0000000 --- a/board/freescale/m5373evb/u-boot.lds +++ /dev/null @@ -1,86 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf532x/start.o (.text*) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss : - { - _sbss = .; - *(.sbss*) - *(.bss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m54418twr/u-boot.lds b/board/freescale/m54418twr/u-boot.lds deleted file mode 100644 index 5679d49..0000000 --- a/board/freescale/m54418twr/u-boot.lds +++ /dev/null @@ -1,83 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf5445x/start.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m54451evb/u-boot.lds b/board/freescale/m54451evb/u-boot.lds deleted file mode 100644 index 413ca53..0000000 --- a/board/freescale/m54451evb/u-boot.lds +++ /dev/null @@ -1,83 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf5445x/start.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m54455evb/u-boot.lds b/board/freescale/m54455evb/u-boot.lds deleted file mode 100644 index 5679d49..0000000 --- a/board/freescale/m54455evb/u-boot.lds +++ /dev/null @@ -1,83 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf5445x/start.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m547xevb/u-boot.lds b/board/freescale/m547xevb/u-boot.lds deleted file mode 100644 index e2ffae4..0000000 --- a/board/freescale/m547xevb/u-boot.lds +++ /dev/null @@ -1,83 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf547x_8x/start.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/m548xevb/u-boot.lds b/board/freescale/m548xevb/u-boot.lds deleted file mode 100644 index cd6aed6..0000000 --- a/board/freescale/m548xevb/u-boot.lds +++ /dev/null @@ -1,83 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf547x_8x/start.o (.text*) - - *(.text*) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data*) - *(.sdata*) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.bss*) - *(.sbss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c index bb2dd96..23f8f6b 100644 --- a/board/freescale/mx6sabresd/mx6sabresd.c +++ b/board/freescale/mx6sabresd/mx6sabresd.c @@ -753,10 +753,11 @@ const struct mx6_mmdc_calibration mx6_mmcd_calib = { .p1_mpwrdlctl = 0x48254A36, }; +/* MT41K128M16JT-125 */ static struct mx6_ddr3_cfg mem_ddr = { .mem_speed = 1600, - .density = 4, - .width = 64, + .density = 2, + .width = 16, .banks = 8, .rowaddr = 14, .coladdr = 10, @@ -798,18 +799,14 @@ static void spl_dram_init(void) { struct mx6_ddr_sysinfo sysinfo = { /* width of data bus:0=16,1=32,2=64 */ - .dsize = mem_ddr.width/32, + .dsize = 2, /* config for full 4GB range so that get_mem_size() works */ .cs_density = 32, /* 32Gb per CS */ /* single chip select */ .ncs = 1, .cs1_mirror = 0, .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */ -#ifdef RTT_NOM_120OHM - .rtt_nom = 2 /*DDR3_RTT_120_OHM*/, /* RTT_Nom = RZQ/2 */ -#else .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */ -#endif .walat = 1, /* Write additional latency */ .ralat = 5, /* Read additional latency */ .mif3_mode = 3, /* Command prediction working mode */ @@ -818,7 +815,7 @@ static void spl_dram_init(void) .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ }; - mx6dq_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs); + mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs); mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr); } diff --git a/board/freescale/p1010rdb/p1010rdb.c b/board/freescale/p1010rdb/p1010rdb.c index 1cf0ab7..ebffe9a 100644 --- a/board/freescale/p1010rdb/p1010rdb.c +++ b/board/freescale/p1010rdb/p1010rdb.c @@ -77,10 +77,9 @@ struct cpld_data { int board_early_init_f(void) { ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); - struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR; - + struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL}; /* Clock configuration to access CPLD using IFC(GPCM) */ - setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT); + setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT); /* * Reset PCIe slots via GPIO4 */ diff --git a/board/freescale/p1010rdb/spl.c b/board/freescale/p1010rdb/spl.c index 11bd9cf..ee873b0 100644 --- a/board/freescale/p1010rdb/spl.c +++ b/board/freescale/p1010rdb/spl.c @@ -23,12 +23,12 @@ void board_init_f(ulong bootflag) { u32 plat_ratio; ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; - struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR; + struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL}; console_init_f(); /* Clock configuration to access CPLD using IFC(GPCM) */ - setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT); + setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT); #ifdef CONFIG_P1010RDB_PB setbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_GPIO01_DRVVBUS); diff --git a/board/freescale/t208xrdb/ddr.h b/board/freescale/t208xrdb/ddr.h index b6d4062..08cbb60 100644 --- a/board/freescale/t208xrdb/ddr.h +++ b/board/freescale/t208xrdb/ddr.h @@ -32,12 +32,12 @@ static const struct board_specific_parameters udimm0[] = { {2, 1500, 2, 5, 6, 0x07070809, 0x0a0b0b09}, {2, 1600, 2, 5, 8, 0x0808070b, 0x0c0d0e0a}, {2, 1700, 2, 4, 7, 0x080a0a0c, 0x0c0d0e0a}, - {2, 1900, 2, 5, 9, 0x0a0b0c0e, 0x0f10120c}, + {2, 1900, 0, 5, 7, 0x0808080c, 0x0b0c0c09}, {1, 1200, 2, 5, 7, 0x0808090a, 0x0b0c0c0a}, {1, 1500, 2, 5, 6, 0x07070809, 0x0a0b0b09}, {1, 1600, 2, 5, 8, 0x0808070b, 0x0c0d0e0a}, {1, 1700, 2, 4, 7, 0x080a0a0c, 0x0c0d0e0a}, - {1, 1900, 2, 5, 9, 0x0a0b0c0e, 0x0f10120c}, + {1, 1900, 0, 5, 7, 0x0808080c, 0x0b0c0c09}, {} }; diff --git a/board/freescale/t208xrdb/t208xrdb.c b/board/freescale/t208xrdb/t208xrdb.c index 341453b..ad393df 100644 --- a/board/freescale/t208xrdb/t208xrdb.c +++ b/board/freescale/t208xrdb/t208xrdb.c @@ -19,6 +19,7 @@ #include <fm_eth.h> #include "t208xrdb.h" #include "cpld.h" +#include "../common/vid.h" DECLARE_GLOBAL_DATA_PTR; @@ -85,6 +86,12 @@ int board_early_init_r(void) setup_portals(); #endif + /* + * Adjust core voltage according to voltage ID + * This function changes I2C mux to channel 2. + */ + if (adjust_vdd(0)) + printf("Warning: Adjusting core voltage failed.\n"); return 0; } diff --git a/board/freescale/vf610twr/vf610twr.c b/board/freescale/vf610twr/vf610twr.c index b634965..4160acd 100644 --- a/board/freescale/vf610twr/vf610twr.c +++ b/board/freescale/vf610twr/vf610twr.c @@ -8,6 +8,7 @@ #include <asm/io.h> #include <asm/arch/imx-regs.h> #include <asm/arch/iomux-vf610.h> +#include <asm/arch/ddrmc-vf610.h> #include <asm/arch/crm_regs.h> #include <asm/arch/clock.h> #include <mmc.h> @@ -27,240 +28,63 @@ DECLARE_GLOBAL_DATA_PTR; #define ENET_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \ PAD_CTL_DSE_50ohm | PAD_CTL_OBE_IBE_ENABLE) -void setup_iomux_ddr(void) +int dram_init(void) { - static const iomux_v3_cfg_t ddr_pads[] = { - VF610_PAD_DDR_A15__DDR_A_15, - VF610_PAD_DDR_A14__DDR_A_14, - VF610_PAD_DDR_A13__DDR_A_13, - VF610_PAD_DDR_A12__DDR_A_12, - VF610_PAD_DDR_A11__DDR_A_11, - VF610_PAD_DDR_A10__DDR_A_10, - VF610_PAD_DDR_A9__DDR_A_9, - VF610_PAD_DDR_A8__DDR_A_8, - VF610_PAD_DDR_A7__DDR_A_7, - VF610_PAD_DDR_A6__DDR_A_6, - VF610_PAD_DDR_A5__DDR_A_5, - VF610_PAD_DDR_A4__DDR_A_4, - VF610_PAD_DDR_A3__DDR_A_3, - VF610_PAD_DDR_A2__DDR_A_2, - VF610_PAD_DDR_A1__DDR_A_1, - VF610_PAD_DDR_A0__DDR_A_0, - VF610_PAD_DDR_BA2__DDR_BA_2, - VF610_PAD_DDR_BA1__DDR_BA_1, - VF610_PAD_DDR_BA0__DDR_BA_0, - VF610_PAD_DDR_CAS__DDR_CAS_B, - VF610_PAD_DDR_CKE__DDR_CKE_0, - VF610_PAD_DDR_CLK__DDR_CLK_0, - VF610_PAD_DDR_CS__DDR_CS_B_0, - VF610_PAD_DDR_D15__DDR_D_15, - VF610_PAD_DDR_D14__DDR_D_14, - VF610_PAD_DDR_D13__DDR_D_13, - VF610_PAD_DDR_D12__DDR_D_12, - VF610_PAD_DDR_D11__DDR_D_11, - VF610_PAD_DDR_D10__DDR_D_10, - VF610_PAD_DDR_D9__DDR_D_9, - VF610_PAD_DDR_D8__DDR_D_8, - VF610_PAD_DDR_D7__DDR_D_7, - VF610_PAD_DDR_D6__DDR_D_6, - VF610_PAD_DDR_D5__DDR_D_5, - VF610_PAD_DDR_D4__DDR_D_4, - VF610_PAD_DDR_D3__DDR_D_3, - VF610_PAD_DDR_D2__DDR_D_2, - VF610_PAD_DDR_D1__DDR_D_1, - VF610_PAD_DDR_D0__DDR_D_0, - VF610_PAD_DDR_DQM1__DDR_DQM_1, - VF610_PAD_DDR_DQM0__DDR_DQM_0, - VF610_PAD_DDR_DQS1__DDR_DQS_1, - VF610_PAD_DDR_DQS0__DDR_DQS_0, - VF610_PAD_DDR_RAS__DDR_RAS_B, - VF610_PAD_DDR_WE__DDR_WE_B, - VF610_PAD_DDR_ODT1__DDR_ODT_0, - VF610_PAD_DDR_ODT0__DDR_ODT_1, - VF610_PAD_DDR_RESETB, + struct ddrmc_lvl_info lvl = { + .wrlvl_reg_en = 1, + .wrlvl_dl_0 = 0, + .wrlvl_dl_1 = 0, + .rdlvl_gt_reg_en = 1, + .rdlvl_gt_dl_0 = 4, + .rdlvl_gt_dl_1 = 4, + .rdlvl_reg_en = 1, + .rdlvl_dl_0 = 0, + .rdlvl_dl_1 = 0, }; - imx_iomux_v3_setup_multiple_pads(ddr_pads, ARRAY_SIZE(ddr_pads)); -} - -void ddr_phy_init(void) -{ - struct ddrmr_regs *ddrmr = (struct ddrmr_regs *)DDR_BASE_ADDR; - - writel(DDRMC_PHY_DQ_TIMING, &ddrmr->phy[0]); - writel(DDRMC_PHY_DQ_TIMING, &ddrmr->phy[16]); - writel(DDRMC_PHY_DQ_TIMING, &ddrmr->phy[32]); - - writel(DDRMC_PHY_DQS_TIMING, &ddrmr->phy[1]); - writel(DDRMC_PHY_DQS_TIMING, &ddrmr->phy[17]); - - writel(DDRMC_PHY_CTRL, &ddrmr->phy[2]); - writel(DDRMC_PHY_CTRL, &ddrmr->phy[18]); - writel(DDRMC_PHY_CTRL, &ddrmr->phy[34]); - - writel(DDRMC_PHY_MASTER_CTRL, &ddrmr->phy[3]); - writel(DDRMC_PHY_MASTER_CTRL, &ddrmr->phy[19]); - writel(DDRMC_PHY_MASTER_CTRL, &ddrmr->phy[35]); - - writel(DDRMC_PHY_SLAVE_CTRL, &ddrmr->phy[4]); - writel(DDRMC_PHY_SLAVE_CTRL, &ddrmr->phy[20]); - writel(DDRMC_PHY_SLAVE_CTRL, &ddrmr->phy[36]); - - /* LPDDR2 only parameter */ - writel(DDRMC_PHY_OFF, &ddrmr->phy[49]); - - writel(DDRMC_PHY50_DDR3_MODE | DDRMC_PHY50_EN_SW_HALF_CYCLE, - &ddrmr->phy[50]); - - /* Processor Pad ODT settings */ - writel(DDRMC_PHY_PROC_PAD_ODT, &ddrmr->phy[52]); -} - -void ddr_ctrl_init(void) -{ - struct ddrmr_regs *ddrmr = (struct ddrmr_regs *)DDR_BASE_ADDR; - - writel(DDRMC_CR00_DRAM_CLASS_DDR3, &ddrmr->cr[0]); - writel(DDRMC_CR02_DRAM_TINIT(32), &ddrmr->cr[2]); - writel(DDRMC_CR10_TRST_PWRON(80000), &ddrmr->cr[10]); - - writel(DDRMC_CR11_CKE_INACTIVE(200000), &ddrmr->cr[11]); - writel(DDRMC_CR12_WRLAT(5) | DDRMC_CR12_CASLAT_LIN(12), &ddrmr->cr[12]); - writel(DDRMC_CR13_TRC(21) | DDRMC_CR13_TRRD(4) | DDRMC_CR13_TCCD(4), - &ddrmr->cr[13]); - writel(DDRMC_CR14_TFAW(20) | DDRMC_CR14_TRP(6) | DDRMC_CR14_TWTR(4) | - DDRMC_CR14_TRAS_MIN(15), &ddrmr->cr[14]); - writel(DDRMC_CR16_TMRD(4) | DDRMC_CR16_TRTP(4), &ddrmr->cr[16]); - writel(DDRMC_CR17_TRAS_MAX(28080) | DDRMC_CR17_TMOD(12), - &ddrmr->cr[17]); - writel(DDRMC_CR18_TCKESR(4) | DDRMC_CR18_TCKE(3), &ddrmr->cr[18]); - - writel(DDRMC_CR20_AP_EN, &ddrmr->cr[20]); - writel(DDRMC_CR21_TRCD_INT(6) | DDRMC_CR21_CCMAP_EN, &ddrmr->cr[21]); - - writel(DDRMC_CR22_TDAL(12), &ddrmr->cr[22]); - writel(DDRMC_CR23_BSTLEN(3) | DDRMC_CR23_TDLL(512), &ddrmr->cr[23]); - writel(DDRMC_CR24_TRP_AB(6), &ddrmr->cr[24]); - - writel(DDRMC_CR25_TREF_EN, &ddrmr->cr[25]); - writel(DDRMC_CR26_TREF(3120) | DDRMC_CR26_TRFC(44), &ddrmr->cr[26]); - writel(DDRMC_CR28_TREF_INT(0), &ddrmr->cr[28]); - writel(DDRMC_CR29_TPDEX(3), &ddrmr->cr[29]); - - writel(DDRMC_CR30_TXPDLL(10), &ddrmr->cr[30]); - writel(DDRMC_CR31_TXSNR(48) | DDRMC_CR31_TXSR(468), &ddrmr->cr[31]); - writel(DDRMC_CR33_EN_QK_SREF, &ddrmr->cr[33]); - writel(DDRMC_CR34_CKSRX(5) | DDRMC_CR34_CKSRE(5), &ddrmr->cr[34]); - - writel(DDRMC_CR38_FREQ_CHG_EN(0), &ddrmr->cr[38]); - writel(DDRMC_CR39_PHY_INI_COM(1024) | DDRMC_CR39_PHY_INI_STA(16) | - DDRMC_CR39_FRQ_CH_DLLOFF(2), &ddrmr->cr[39]); - - writel(DDRMC_CR41_PHY_INI_STRT_INI_DIS, &ddrmr->cr[41]); - writel(DDRMC_CR48_MR1_DA_0(70) | DDRMC_CR48_MR0_DA_0(1056), - &ddrmr->cr[48]); - - writel(DDRMC_CR66_ZQCL(256) | DDRMC_CR66_ZQINIT(512), &ddrmr->cr[66]); - writel(DDRMC_CR67_ZQCS(64), &ddrmr->cr[67]); - writel(DDRMC_CR69_ZQ_ON_SREF_EX(2), &ddrmr->cr[69]); - - writel(DDRMC_CR70_REF_PER_ZQ(64), &ddrmr->cr[70]); - writel(DDRMC_CR72_ZQCS_ROTATE(0), &ddrmr->cr[72]); - - writel(DDRMC_CR73_APREBIT(10) | DDRMC_CR73_COL_DIFF(1) | - DDRMC_CR73_ROW_DIFF(3), &ddrmr->cr[73]); - writel(DDRMC_CR74_BANKSPLT_EN | DDRMC_CR74_ADDR_CMP_EN | - DDRMC_CR74_CMD_AGE_CNT(64) | DDRMC_CR74_AGE_CNT(64), - &ddrmr->cr[74]); - writel(DDRMC_CR75_RW_PG_EN | DDRMC_CR75_RW_EN | DDRMC_CR75_PRI_EN | - DDRMC_CR75_PLEN, &ddrmr->cr[75]); - writel(DDRMC_CR76_NQENT_ACTDIS(3) | DDRMC_CR76_D_RW_G_BKCN(3) | - DDRMC_CR76_W2R_SPLT_EN, &ddrmr->cr[76]); - writel(DDRMC_CR77_CS_MAP | DDRMC_CR77_DI_RD_INTLEAVE | - DDRMC_CR77_SWAP_EN, &ddrmr->cr[77]); - writel(DDRMC_CR78_Q_FULLNESS(7) | DDRMC_CR78_BUR_ON_FLY_BIT(12), - &ddrmr->cr[78]); - writel(DDRMC_CR79_CTLUPD_AREF(0), &ddrmr->cr[79]); - - writel(DDRMC_CR82_INT_MASK, &ddrmr->cr[82]); - - writel(DDRMC_CR87_ODT_WR_MAPCS0, &ddrmr->cr[87]); - writel(DDRMC_CR88_TODTL_CMD(4), &ddrmr->cr[88]); - writel(DDRMC_CR89_AODT_RWSMCS(2), &ddrmr->cr[89]); - - writel(DDRMC_CR91_R2W_SMCSDL(2), &ddrmr->cr[91]); - writel(DDRMC_CR96_WLMRD(40) | DDRMC_CR96_WLDQSEN(25), &ddrmr->cr[96]); - writel(DDRMC_CR97_WRLVL_EN, &ddrmr->cr[97]); - writel(DDRMC_CR98_WRLVL_DL_0, &ddrmr->cr[98]); - writel(DDRMC_CR99_WRLVL_DL_1, &ddrmr->cr[99]); - - writel(DDRMC_CR102_RDLVL_GT_REGEN | DDRMC_CR102_RDLVL_REG_EN, - &ddrmr->cr[102]); - - writel(DDRMC_CR105_RDLVL_DL_0(0), &ddrmr->cr[105]); - writel(DDRMC_CR106_RDLVL_GTDL_0(4), &ddrmr->cr[106]); - writel(DDRMC_CR110_RDLVL_GTDL_1(4), &ddrmr->cr[110]); - writel(DDRMC_CR114_RDLVL_GTDL_2(0), &ddrmr->cr[114]); - writel(DDRMC_CR115_RDLVL_GTDL_2(0), &ddrmr->cr[115]); - - writel(DDRMC_CR117_AXI0_W_PRI(0) | DDRMC_CR117_AXI0_R_PRI(0), - &ddrmr->cr[117]); - writel(DDRMC_CR118_AXI1_W_PRI(1) | DDRMC_CR118_AXI1_R_PRI(1), - &ddrmr->cr[118]); - - writel(DDRMC_CR120_AXI0_PRI1_RPRI(2) | DDRMC_CR120_AXI0_PRI0_RPRI(2), - &ddrmr->cr[120]); - writel(DDRMC_CR121_AXI0_PRI3_RPRI(2) | DDRMC_CR121_AXI0_PRI2_RPRI(2), - &ddrmr->cr[121]); - writel(DDRMC_CR122_AXI1_PRI1_RPRI(1) | DDRMC_CR122_AXI1_PRI0_RPRI(1) | - DDRMC_CR122_AXI0_PRIRLX(100), &ddrmr->cr[122]); - writel(DDRMC_CR123_AXI1_P_ODR_EN | DDRMC_CR123_AXI1_PRI3_RPRI(1) | - DDRMC_CR123_AXI1_PRI2_RPRI(1), &ddrmr->cr[123]); - writel(DDRMC_CR124_AXI1_PRIRLX(100), &ddrmr->cr[124]); - - writel(DDRMC_CR126_PHY_RDLAT(8), &ddrmr->cr[126]); - writel(DDRMC_CR132_WRLAT_ADJ(5) | DDRMC_CR132_RDLAT_ADJ(6), - &ddrmr->cr[132]); - writel(DDRMC_CR137_PHYCTL_DL(2), &ddrmr->cr[137]); - writel(DDRMC_CR138_PHY_WRLV_MXDL(256) | DDRMC_CR138_PHYDRAM_CK_EN(1), - &ddrmr->cr[138]); - writel(DDRMC_CR139_PHY_WRLV_RESPLAT(4) | DDRMC_CR139_PHY_WRLV_LOAD(7) | - DDRMC_CR139_PHY_WRLV_DLL(3) | DDRMC_CR139_PHY_WRLV_EN(3), - &ddrmr->cr[139]); - writel(DDRMC_CR140_PHY_WRLV_WW(64), &ddrmr->cr[140]); - writel(DDRMC_CR143_RDLV_GAT_MXDL(1536) | DDRMC_CR143_RDLV_MXDL(128), - &ddrmr->cr[143]); - writel(DDRMC_CR144_PHY_RDLVL_RES(4) | DDRMC_CR144_PHY_RDLV_LOAD(7) | - DDRMC_CR144_PHY_RDLV_DLL(3) | DDRMC_CR144_PHY_RDLV_EN(3), - &ddrmr->cr[144]); - writel(DDRMC_CR145_PHY_RDLV_RR(64), &ddrmr->cr[145]); - writel(DDRMC_CR146_PHY_RDLVL_RESP(64), &ddrmr->cr[146]); - writel(DDRMC_CR147_RDLV_RESP_MASK(983040), &ddrmr->cr[147]); - writel(DDRMC_CR148_RDLV_GATE_RESP_MASK(983040), &ddrmr->cr[148]); - writel(DDRMC_CR151_RDLV_GAT_DQ_ZERO_CNT(1) | - DDRMC_CR151_RDLVL_DQ_ZERO_CNT(1), &ddrmr->cr[151]); - - writel(DDRMC_CR154_PAD_ZQ_EARLY_CMP_EN_TIMER(13) | - DDRMC_CR154_PAD_ZQ_MODE(1) | DDRMC_CR154_DDR_SEL_PAD_CONTR(3) | - DDRMC_CR154_PAD_ZQ_HW_FOR(1), &ddrmr->cr[154]); - writel(DDRMC_CR155_PAD_ODT_BYTE1(2) | DDRMC_CR155_PAD_ODT_BYTE0(2), - &ddrmr->cr[155]); - writel(DDRMC_CR158_TWR(6), &ddrmr->cr[158]); - writel(DDRMC_CR161_ODT_EN(1) | DDRMC_CR161_TODTH_RD(2) | - DDRMC_CR161_TODTH_WR(2), &ddrmr->cr[161]); - - ddr_phy_init(); - - writel(DDRMC_CR00_DRAM_CLASS_DDR3 | DDRMC_CR00_START, &ddrmr->cr[0]); - - udelay(200); -} + static const struct ddr3_jedec_timings timings = { + .tinit = 5, + .trst_pwron = 80000, + .cke_inactive = 200000, + .wrlat = 5, + .caslat_lin = 12, + .trc = 21, + .trrd = 4, + .tccd = 4, + .tfaw = 20, + .trp = 6, + .twtr = 4, + .tras_min = 15, + .tmrd = 4, + .trtp = 4, + .tras_max = 28080, + .tmod = 12, + .tckesr = 4, + .tcke = 3, + .trcd_int = 6, + .tdal = 12, + .tdll = 512, + .trp_ab = 6, + .tref = 3120, + .trfc = 44, + .tpdex = 3, + .txpdll = 10, + .txsnr = 48, + .txsr = 468, + .cksrx = 5, + .cksre = 5, + .zqcl = 256, + .zqinit = 512, + .zqcs = 64, + .ref_per_zq = 64, + .aprebit = 10, + .wlmrd = 40, + .wldqsen = 25, + }; -int dram_init(void) -{ - setup_iomux_ddr(); + ddrmc_setup_iomux(); - ddr_ctrl_init(); + ddrmc_ctrl_init_ddr3(&timings, &lvl, 1, 3); gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); return 0; @@ -403,7 +227,7 @@ static void clock_init(void) CCM_CCGR2_PORTD_CTRL_MASK | CCM_CCGR2_PORTE_CTRL_MASK | CCM_CCGR2_QSPI0_CTRL_MASK); clrsetbits_le32(&ccm->ccgr3, CCM_REG_CTRL_MASK, - CCM_CCGR3_ANADIG_CTRL_MASK); + CCM_CCGR3_ANADIG_CTRL_MASK | CCM_CCGR3_SCSC_CTRL_MASK); clrsetbits_le32(&ccm->ccgr4, CCM_REG_CTRL_MASK, CCM_CCGR4_WKUP_CTRL_MASK | CCM_CCGR4_CCM_CTRL_MASK | CCM_CCGR4_GPC_CTRL_MASK | CCM_CCGR4_I2C0_CTRL_MASK); @@ -484,9 +308,20 @@ int board_early_init_f(void) int board_init(void) { + struct scsc_reg *scsc = (struct scsc_reg *)SCSC_BASE_ADDR; + /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + /* + * Enable external 32K Oscillator + * + * The internal clock experiences significant drift + * so we must use the external oscillator in order + * to maintain correct time in the hwclock + */ + setbits_le32(&scsc->sosc_ctr, SCSC_SOSC_CTR_SOSC_EN); + return 0; } diff --git a/board/gateworks/gw_ventana/eeprom.c b/board/gateworks/gw_ventana/eeprom.c index ab3bab8..ba15969 100644 --- a/board/gateworks/gw_ventana/eeprom.c +++ b/board/gateworks/gw_ventana/eeprom.c @@ -81,8 +81,14 @@ read_eeprom(int bus, struct ventana_board_info *info) type = GW54xx; break; case '5': - type = GW552x; - break; + if (info->model[4] == '1') { + type = GW551x; + break; + } else if (info->model[4] == '2') { + type = GW552x; + break; + } + /* fall through */ default: printf("EEPROM: Unknown model in EEPROM: %s\n", info->model); type = GW_UNKNOWN; diff --git a/board/gateworks/gw_ventana/gsc.c b/board/gateworks/gw_ventana/gsc.c index a34a9a8..718e165 100644 --- a/board/gateworks/gw_ventana/gsc.c +++ b/board/gateworks/gw_ventana/gsc.c @@ -13,8 +13,6 @@ #include "gsc.h" -#define MINMAX(n, percent) ((n)*(100-percent)/100), ((n)*(100+percent)/100) - /* * The Gateworks System Controller will fail to ACK a master transaction if * it is busy, which can occur during its 1HZ timer tick while reading ADC's. @@ -61,9 +59,7 @@ int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) return ret; } -#ifdef CONFIG_CMD_GSC -static void read_hwmon(const char *name, uint reg, uint size, uint low, - uint high) +static void read_hwmon(const char *name, uint reg, uint size) { unsigned char buf[3]; uint ui; @@ -75,59 +71,121 @@ static void read_hwmon(const char *name, uint reg, uint size, uint low, } else { ui = buf[0] | (buf[1]<<8) | (buf[2]<<16); if (ui == 0xffffff) - printf("invalid"); - else if (ui < low) - printf("%d Failed - Low", ui); - else if (ui > high) - printf("%d Failed - High", ui); + puts("invalid\n"); else - printf("%d", ui); + printf("%d\n", ui); } - puts("\n"); } -int do_gsc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +int gsc_info(int verbose) { const char *model = getenv("model"); + unsigned char buf[16]; i2c_set_bus_num(0); - read_hwmon("Temp", GSC_HWMON_TEMP, 2, 0, 9000); - read_hwmon("VIN", GSC_HWMON_VIN, 3, 8000, 60000); - read_hwmon("VBATT", GSC_HWMON_VBATT, 3, 1800, 3500); - read_hwmon("VDD_3P3", GSC_HWMON_VDD_3P3, 3, MINMAX(3300, 10)); - read_hwmon("VDD_HIGH", GSC_HWMON_VDD_HIGH, 3, MINMAX(3000, 10)); - read_hwmon("VDD_DDR", GSC_HWMON_VDD_DDR, 3, MINMAX(1500, 10)); - read_hwmon("VDD_5P0", GSC_HWMON_VDD_5P0, 3, MINMAX(5000, 10)); - read_hwmon("VDD_2P5", GSC_HWMON_VDD_2P5, 3, MINMAX(2500, 10)); - read_hwmon("VDD_1P8", GSC_HWMON_VDD_1P8, 3, MINMAX(1800, 10)); + if (gsc_i2c_read(GSC_SC_ADDR, 0, 1, buf, 16)) + return CMD_RET_FAILURE; + + printf("GSC: v%d", buf[GSC_SC_FWVER]); + printf(" 0x%04x", buf[GSC_SC_FWCRC] | buf[GSC_SC_FWCRC+1]<<8); + printf(" WDT:%sabled", (buf[GSC_SC_CTRL1] & (1<<GSC_SC_CTRL1_WDEN)) + ? "en" : "dis"); + if (buf[GSC_SC_STATUS] & (1 << GSC_SC_IRQ_WATCHDOG)) { + buf[GSC_SC_STATUS] &= ~(1 << GSC_SC_IRQ_WATCHDOG); + puts(" WDT_RESET"); + gsc_i2c_write(GSC_SC_ADDR, GSC_SC_STATUS, 1, + &buf[GSC_SC_STATUS], 1); + } + puts("\n"); + if (!verbose) + return CMD_RET_SUCCESS; + read_hwmon("Temp", GSC_HWMON_TEMP, 2); + read_hwmon("VIN", GSC_HWMON_VIN, 3); + read_hwmon("VBATT", GSC_HWMON_VBATT, 3); + read_hwmon("VDD_3P3", GSC_HWMON_VDD_3P3, 3); + read_hwmon("VDD_ARM", GSC_HWMON_VDD_CORE, 3); + read_hwmon("VDD_SOC", GSC_HWMON_VDD_SOC, 3); + read_hwmon("VDD_HIGH", GSC_HWMON_VDD_HIGH, 3); + read_hwmon("VDD_DDR", GSC_HWMON_VDD_DDR, 3); + read_hwmon("VDD_5P0", GSC_HWMON_VDD_5P0, 3); + read_hwmon("VDD_2P5", GSC_HWMON_VDD_2P5, 3); + read_hwmon("VDD_1P8", GSC_HWMON_VDD_1P8, 3); + read_hwmon("VDD_IO2", GSC_HWMON_VDD_IO2, 3); switch (model[3]) { case '1': /* GW51xx */ - read_hwmon("VDD_CORE", GSC_HWMON_VDD_CORE, 3, MINMAX(1175, 10)); - read_hwmon("VDD_SOC", GSC_HWMON_VDD_SOC, 3, MINMAX(1175, 10)); + read_hwmon("VDD_IO3", GSC_HWMON_VDD_IO4, 3); /* -C rev */ break; case '2': /* GW52xx */ + break; case '3': /* GW53xx */ - read_hwmon("VDD_CORE", GSC_HWMON_VDD_CORE, 3, MINMAX(1175, 10)); - read_hwmon("VDD_SOC", GSC_HWMON_VDD_SOC, 3, MINMAX(1175, 10)); - read_hwmon("VDD_1P0", GSC_HWMON_VDD_1P0, 3, MINMAX(1000, 10)); + read_hwmon("VDD_IO4", GSC_HWMON_VDD_IO4, 3); /* -C rev */ + read_hwmon("VDD_GPS", GSC_HWMON_VDD_IO3, 3); break; case '4': /* GW54xx */ - read_hwmon("VDD_CORE", GSC_HWMON_VDD_CORE, 3, MINMAX(1375, 10)); - read_hwmon("VDD_SOC", GSC_HWMON_VDD_SOC, 3, MINMAX(1375, 10)); - read_hwmon("VDD_1P0", GSC_HWMON_VDD_1P0, 3, MINMAX(1000, 10)); + read_hwmon("VDD_IO3", GSC_HWMON_VDD_IO4, 3); /* -C rev */ + read_hwmon("VDD_GPS", GSC_HWMON_VDD_IO3, 3); break; case '5': /* GW55xx */ - read_hwmon("VDD_CORE", GSC_HWMON_VDD_CORE, 3, MINMAX(1175, 10)); - read_hwmon("VDD_SOC", GSC_HWMON_VDD_SOC, 3, MINMAX(1175, 10)); break; } return 0; } -U_BOOT_CMD(gsc, 1, 1, do_gsc, - "GSC test", - "" -); +#ifdef CONFIG_CMD_GSC +static int do_gsc_wd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unsigned char reg; + + if (argc < 2) + return CMD_RET_USAGE; + + if (strcasecmp(argv[1], "enable") == 0) { + int timeout = 0; + + if (argc > 2) + timeout = simple_strtoul(argv[2], NULL, 10); + i2c_set_bus_num(0); + if (gsc_i2c_read(GSC_SC_ADDR, GSC_SC_CTRL1, 1, ®, 1)) + return CMD_RET_FAILURE; + reg &= ~((1 << GSC_SC_CTRL1_WDEN) | (1 << GSC_SC_CTRL1_WDTIME)); + if (timeout == 60) + reg |= (1 << GSC_SC_CTRL1_WDTIME); + else + timeout = 30; + reg |= (1 << GSC_SC_CTRL1_WDEN); + if (gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, 1, ®, 1)) + return CMD_RET_FAILURE; + printf("GSC Watchdog enabled with timeout=%d seconds\n", + timeout); + } else if (strcasecmp(argv[1], "disable") == 0) { + i2c_set_bus_num(0); + if (gsc_i2c_read(GSC_SC_ADDR, GSC_SC_CTRL1, 1, ®, 1)) + return CMD_RET_FAILURE; + reg &= ~((1 << GSC_SC_CTRL1_WDEN) | (1 << GSC_SC_CTRL1_WDTIME)); + if (gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, 1, ®, 1)) + return CMD_RET_FAILURE; + printf("GSC Watchdog disabled\n"); + } else { + return CMD_RET_USAGE; + } + return CMD_RET_SUCCESS; +} + +static int do_gsc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc < 2) + return gsc_info(1); + + if (strcasecmp(argv[1], "wd") == 0) + return do_gsc_wd(cmdtp, flag, --argc, ++argv); + + return CMD_RET_USAGE; +} + +U_BOOT_CMD( + gsc, 4, 1, do_gsc, "GSC configuration", + "[wd enable [30|60]]|[wd disable]\n" + ); #endif /* CONFIG_CMD_GSC */ diff --git a/board/gateworks/gw_ventana/gsc.h b/board/gateworks/gw_ventana/gsc.h index da970c3..2d4969e 100644 --- a/board/gateworks/gw_ventana/gsc.h +++ b/board/gateworks/gw_ventana/gsc.h @@ -19,12 +19,15 @@ enum { GSC_SC_CTRL0 = 0x00, GSC_SC_CTRL1 = 0x01, GSC_SC_STATUS = 0x0a, + GSC_SC_FWCRC = 0x0c, GSC_SC_FWVER = 0x0e, }; /* System Controller Control1 bits */ enum { - GSC_SC_CTRL1_WDDIS = 7, /* 1 = disable watchdog */ + GSC_SC_CTRL1_WDTIME = 4, /* 1 = 60s timeout, 0 = 30s timeout */ + GSC_SC_CTRL1_WDEN = 5, /* 1 = enable, 0 = disable */ + GSC_SC_CTRL1_WDDIS = 7, /* 1 = disable boot watchdog */ }; /* System Controller Interrupt bits */ @@ -50,8 +53,10 @@ enum { GSC_HWMON_VDD_DDR = 0x17, GSC_HWMON_VDD_SOC = 0x11, GSC_HWMON_VDD_1P8 = 0x1d, + GSC_HWMON_VDD_IO2 = 0x20, GSC_HWMON_VDD_2P5 = 0x23, - GSC_HWMON_VDD_1P0 = 0x20, + GSC_HWMON_VDD_IO3 = 0x26, + GSC_HWMON_VDD_IO4 = 0x29, }; /* @@ -60,5 +65,6 @@ enum { */ int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len); int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len); +int gsc_info(int verbose); #endif diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c index bb08cd2..1e54912 100644 --- a/board/gateworks/gw_ventana/gw_ventana.c +++ b/board/gateworks/gw_ventana/gw_ventana.c @@ -89,16 +89,16 @@ DECLARE_GLOBAL_DATA_PTR; */ struct ventana_board_info ventana_info; -int board_type; +static int board_type; /* UART1: Function varies per baseboard */ -iomux_v3_cfg_t const uart1_pads[] = { +static iomux_v3_cfg_t const uart1_pads[] = { IOMUX_PADS(PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), IOMUX_PADS(PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), }; /* UART2: Serial Console */ -iomux_v3_cfg_t const uart2_pads[] = { +static iomux_v3_cfg_t const uart2_pads[] = { IOMUX_PADS(PAD_SD4_DAT7__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), IOMUX_PADS(PAD_SD4_DAT4__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), }; @@ -106,7 +106,7 @@ iomux_v3_cfg_t const uart2_pads[] = { #define PC MUX_PAD_CTRL(I2C_PAD_CTRL) /* I2C1: GSC */ -struct i2c_pads_info mx6q_i2c_pad_info0 = { +static struct i2c_pads_info mx6q_i2c_pad_info0 = { .scl = { .i2c_mode = MX6Q_PAD_EIM_D21__I2C1_SCL | PC, .gpio_mode = MX6Q_PAD_EIM_D21__GPIO3_IO21 | PC, @@ -118,7 +118,7 @@ struct i2c_pads_info mx6q_i2c_pad_info0 = { .gp = IMX_GPIO_NR(3, 28) } }; -struct i2c_pads_info mx6dl_i2c_pad_info0 = { +static struct i2c_pads_info mx6dl_i2c_pad_info0 = { .scl = { .i2c_mode = MX6DL_PAD_EIM_D21__I2C1_SCL | PC, .gpio_mode = MX6DL_PAD_EIM_D21__GPIO3_IO21 | PC, @@ -132,7 +132,7 @@ struct i2c_pads_info mx6dl_i2c_pad_info0 = { }; /* I2C2: PMIC/PCIe Switch/PCIe Clock/Mezz */ -struct i2c_pads_info mx6q_i2c_pad_info1 = { +static struct i2c_pads_info mx6q_i2c_pad_info1 = { .scl = { .i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | PC, .gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 | PC, @@ -144,7 +144,7 @@ struct i2c_pads_info mx6q_i2c_pad_info1 = { .gp = IMX_GPIO_NR(4, 13) } }; -struct i2c_pads_info mx6dl_i2c_pad_info1 = { +static struct i2c_pads_info mx6dl_i2c_pad_info1 = { .scl = { .i2c_mode = MX6DL_PAD_KEY_COL3__I2C2_SCL | PC, .gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12 | PC, @@ -158,7 +158,7 @@ struct i2c_pads_info mx6dl_i2c_pad_info1 = { }; /* I2C3: Misc/Expansion */ -struct i2c_pads_info mx6q_i2c_pad_info2 = { +static struct i2c_pads_info mx6q_i2c_pad_info2 = { .scl = { .i2c_mode = MX6Q_PAD_GPIO_3__I2C3_SCL | PC, .gpio_mode = MX6Q_PAD_GPIO_3__GPIO1_IO03 | PC, @@ -170,7 +170,7 @@ struct i2c_pads_info mx6q_i2c_pad_info2 = { .gp = IMX_GPIO_NR(1, 6) } }; -struct i2c_pads_info mx6dl_i2c_pad_info2 = { +static struct i2c_pads_info mx6dl_i2c_pad_info2 = { .scl = { .i2c_mode = MX6DL_PAD_GPIO_3__I2C3_SCL | PC, .gpio_mode = MX6DL_PAD_GPIO_3__GPIO1_IO03 | PC, @@ -184,7 +184,7 @@ struct i2c_pads_info mx6dl_i2c_pad_info2 = { }; /* MMC */ -iomux_v3_cfg_t const usdhc3_pads[] = { +static iomux_v3_cfg_t const usdhc3_pads[] = { IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), @@ -196,7 +196,7 @@ iomux_v3_cfg_t const usdhc3_pads[] = { }; /* ENET */ -iomux_v3_cfg_t const enet_pads[] = { +static iomux_v3_cfg_t const enet_pads[] = { IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)), IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)), IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), @@ -220,7 +220,7 @@ iomux_v3_cfg_t const enet_pads[] = { }; /* NAND */ -iomux_v3_cfg_t const nfc_pads[] = { +static iomux_v3_cfg_t const nfc_pads[] = { IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL)), IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NO_PAD_CTRL)), IOMUX_PADS(PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NO_PAD_CTRL)), @@ -285,7 +285,7 @@ static void setup_iomux_uart(void) } #ifdef CONFIG_USB_EHCI_MX6 -iomux_v3_cfg_t const usb_pads[] = { +static iomux_v3_cfg_t const usb_pads[] = { IOMUX_PADS(PAD_GPIO_1__USB_OTG_ID | DIO_PAD_CFG), IOMUX_PADS(PAD_KEY_COL4__USB_OTG_OC | DIO_PAD_CFG), /* OTG PWR */ @@ -328,7 +328,7 @@ int board_ehci_power(int port, int on) #endif /* CONFIG_USB_EHCI_MX6 */ #ifdef CONFIG_FSL_ESDHC -struct fsl_esdhc_cfg usdhc_cfg = { USDHC3_BASE_ADDR }; +static struct fsl_esdhc_cfg usdhc_cfg = { USDHC3_BASE_ADDR }; int board_mmc_getcd(struct mmc *mmc) { @@ -397,11 +397,15 @@ int board_phy_config(struct phy_device *phydev) int board_eth_init(bd_t *bis) { - setup_iomux_enet(); - #ifdef CONFIG_FEC_MXC - if (board_type != GW552x) + if (board_type != GW551x && board_type != GW552x) { + setup_iomux_enet(); cpu_eth_init(bis); + } +#endif + +#ifdef CONFIG_E1000 + e1000_initialize(bis); #endif #ifdef CONFIG_CI_UDC @@ -409,6 +413,15 @@ int board_eth_init(bd_t *bis) usb_eth_initialize(bis); #endif + /* default to the first detected enet dev */ + if (!getenv("ethprime")) { + struct eth_device *dev = eth_get_dev_by_index(0); + if (dev) { + setenv("ethprime", dev->name); + printf("set ethprime to %s\n", getenv("ethprime")); + } + } + return 0; } @@ -482,6 +495,48 @@ struct display_info_t const displays[] = {{ .vsync_len = 10, .sync = FB_SYNC_EXT, .vmode = FB_VMODE_NONINTERLACED +} }, { + /* DLC700JMG-T-4 */ + .bus = 0, + .addr = 0, + .detect = NULL, + .enable = enable_lvds, + .pixfmt = IPU_PIX_FMT_LVDS666, + .mode = { + .name = "DLC700JMGT4", + .refresh = 60, + .xres = 1024, /* 1024x600active pixels */ + .yres = 600, + .pixclock = 15385, /* 64MHz */ + .left_margin = 220, + .right_margin = 40, + .upper_margin = 21, + .lower_margin = 7, + .hsync_len = 60, + .vsync_len = 10, + .sync = FB_SYNC_EXT, + .vmode = FB_VMODE_NONINTERLACED +} }, { + /* DLC800FIG-T-3 */ + .bus = 0, + .addr = 0, + .detect = NULL, + .enable = enable_lvds, + .pixfmt = IPU_PIX_FMT_LVDS666, + .mode = { + .name = "DLC800FIGT3", + .refresh = 60, + .xres = 1024, /* 1024x768 active pixels */ + .yres = 768, + .pixclock = 15385, /* 64MHz */ + .left_margin = 220, + .right_margin = 40, + .upper_margin = 21, + .lower_margin = 7, + .hsync_len = 60, + .vsync_len = 10, + .sync = FB_SYNC_EXT, + .vmode = FB_VMODE_NONINTERLACED } } }; size_t display_count = ARRAY_SIZE(displays); @@ -614,6 +669,8 @@ static iomux_v3_cfg_t const gw52xx_gpio_pads[] = { IOMUX_PADS(PAD_EIM_D31__GPIO3_IO31 | DIO_PAD_CFG), /* PCI_RST# */ IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29 | DIO_PAD_CFG), + /* PCI_RST# (GW522x) */ + IOMUX_PADS(PAD_EIM_D23__GPIO3_IO23 | DIO_PAD_CFG), /* PCIESKT_WDIS# */ IOMUX_PADS(PAD_GPIO_17__GPIO7_IO12 | DIO_PAD_CFG), }; @@ -658,8 +715,6 @@ static iomux_v3_cfg_t const gw54xx_gpio_pads[] = { IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(IRQ_PAD_CTRL)), /* DIOI2C_DIS# */ IOMUX_PADS(PAD_GPIO_19__GPIO4_IO05 | DIO_PAD_CFG), - /* PCICK_SSON */ - IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20 | DIO_PAD_CFG), /* PCI_RST# */ IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29 | DIO_PAD_CFG), /* VID_EN */ @@ -668,6 +723,15 @@ static iomux_v3_cfg_t const gw54xx_gpio_pads[] = { IOMUX_PADS(PAD_DISP0_DAT23__GPIO5_IO17 | DIO_PAD_CFG), }; +static iomux_v3_cfg_t const gw551x_gpio_pads[] = { + /* PANLED# */ + IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | DIO_PAD_CFG), + /* PCI_RST# */ + IOMUX_PADS(PAD_GPIO_0__GPIO1_IO00 | DIO_PAD_CFG), + /* PCIESKT_WDIS# */ + IOMUX_PADS(PAD_GPIO_17__GPIO7_IO12 | DIO_PAD_CFG), +}; + static iomux_v3_cfg_t const gw552x_gpio_pads[] = { /* PANLEDG# */ IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | DIO_PAD_CFG), @@ -709,6 +773,7 @@ struct ventana { int num_pads; /* DIO pinmux/val */ struct dio_cfg dio_cfg[4]; + int num_gpios; /* various gpios (0 if non-existent) */ int leds[3]; int pcie_rst; @@ -723,7 +788,7 @@ struct ventana { int wdis; }; -struct ventana gpio_cfg[] = { +static struct ventana gpio_cfg[] = { /* GW5400proto */ { .gpio_pads = gw54xx_gpio_pads, @@ -754,6 +819,7 @@ struct ventana gpio_cfg[] = { 4 }, }, + .num_gpios = 4, .leds = { IMX_GPIO_NR(4, 6), IMX_GPIO_NR(4, 10), @@ -797,6 +863,7 @@ struct ventana gpio_cfg[] = { 4 }, }, + .num_gpios = 4, .leds = { IMX_GPIO_NR(4, 6), IMX_GPIO_NR(4, 10), @@ -839,6 +906,7 @@ struct ventana gpio_cfg[] = { 0 }, }, + .num_gpios = 4, .leds = { IMX_GPIO_NR(4, 6), IMX_GPIO_NR(4, 7), @@ -883,6 +951,7 @@ struct ventana gpio_cfg[] = { 0 }, }, + .num_gpios = 4, .leds = { IMX_GPIO_NR(4, 6), IMX_GPIO_NR(4, 7), @@ -926,6 +995,7 @@ struct ventana gpio_cfg[] = { 4 }, }, + .num_gpios = 4, .leds = { IMX_GPIO_NR(4, 6), IMX_GPIO_NR(4, 7), @@ -941,10 +1011,10 @@ struct ventana gpio_cfg[] = { .wdis = IMX_GPIO_NR(5, 17), }, - /* GW552x */ + /* GW551x */ { - .gpio_pads = gw552x_gpio_pads, - .num_pads = ARRAY_SIZE(gw552x_gpio_pads)/2, + .gpio_pads = gw551x_gpio_pads, + .num_pads = ARRAY_SIZE(gw551x_gpio_pads)/2, .dio_cfg = { { { IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) }, @@ -965,18 +1035,46 @@ struct ventana gpio_cfg[] = { 3 }, { - { IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20) }, - IMX_GPIO_NR(2, 10), - { 0, 0 }, - 0 + { IOMUX_PADS(PAD_SD1_CMD__GPIO1_IO18) }, + IMX_GPIO_NR(1, 18), + { IOMUX_PADS(PAD_SD1_CMD__PWM4_OUT) }, + 4 + }, + }, + .num_gpios = 2, + .leds = { + IMX_GPIO_NR(4, 7), + }, + .pcie_rst = IMX_GPIO_NR(1, 0), + .wdis = IMX_GPIO_NR(7, 12), + }, + + /* GW552x */ + { + .gpio_pads = gw552x_gpio_pads, + .num_pads = ARRAY_SIZE(gw552x_gpio_pads)/2, + .dio_cfg = { + { + { IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) }, + IMX_GPIO_NR(1, 19), + { IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) }, + 2 + }, + { + { IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) }, + IMX_GPIO_NR(1, 17), + { IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) }, + 3 }, }, + .num_gpios = 4, .leds = { IMX_GPIO_NR(4, 6), IMX_GPIO_NR(4, 7), IMX_GPIO_NR(4, 15), }, .pcie_rst = IMX_GPIO_NR(1, 29), + .wdis = IMX_GPIO_NR(7, 12), }, }; @@ -1014,22 +1112,32 @@ int power_init_board(void) p = pmic_get("LTC3676_PMIC"); if (p && !pmic_probe(p)) { puts("PMIC: LTC3676\n"); - /* set board-specific scalar to 1225mV for IMX6Q@1GHz */ - if (is_cpu_type(MXC_CPU_MX6Q)) { - /* mask PGOOD during SW1 transition */ - reg = 0x1d | LTC3676_PGOOD_MASK; - pmic_reg_write(p, LTC3676_DVB1B, reg); - /* set SW1 (VDD_SOC) to 1259mV */ - reg = 0x1d; - pmic_reg_write(p, LTC3676_DVB1A, reg); - - /* mask PGOOD during SW3 transition */ - reg = 0x1d | LTC3676_PGOOD_MASK; - pmic_reg_write(p, LTC3676_DVB3B, reg); - /*set SW3 (VDD_ARM) to 1259mV */ - reg = 0x1d; - pmic_reg_write(p, LTC3676_DVB3A, reg); - } + /* + * set board-specific scalar for max CPU frequency + * per CPU based on the LDO enabled Operating Ranges + * defined in the respective IMX6DQ and IMX6SDL + * datasheets. The voltage resulting from the R1/R2 + * feedback inputs on Ventana is 1308mV. Note that this + * is a bit shy of the Vmin of 1350mV in the datasheet + * for LDO enabled mode but is as high as we can go. + * + * We will rely on an OS kernel driver to properly + * regulate these per CPU operating point and use LDO + * bypass mode when using the higher frequency + * operating points to compensate as LDO bypass mode + * allows the rails be 125mV lower. + */ + /* mask PGOOD during SW1 transition */ + pmic_reg_write(p, LTC3676_DVB1B, + 0x1f | LTC3676_PGOOD_MASK); + /* set SW1 (VDD_SOC) */ + pmic_reg_write(p, LTC3676_DVB1A, 0x1f); + + /* mask PGOOD during SW3 transition */ + pmic_reg_write(p, LTC3676_DVB3B, + 0x1f | LTC3676_PGOOD_MASK); + /* set SW3 (VDD_ARM) */ + pmic_reg_write(p, LTC3676_DVB3A, 0x1f); } } @@ -1062,6 +1170,10 @@ static void setup_board_gpio(int board) } #if !defined(CONFIG_CMD_PCI) + /* GW522x Uses GPIO3_IO23 for PCIE_RST# */ + if (board_type == GW52xx && info->model[4] == '2') + gpio_cfg[board].pcie_rst = IMX_GPIO_NR(3, 23); + /* assert PCI_RST# (released by OS when clock is valid) */ gpio_direction_output(gpio_cfg[board].pcie_rst, 0); #endif @@ -1100,7 +1212,9 @@ static void setup_board_gpio(int board) /* USBOTG Select (PCISKT or FrontPanel) */ if (gpio_cfg[board].usb_sel) - gpio_direction_output(gpio_cfg[board].usb_sel, 0); + gpio_direction_output(gpio_cfg[board].usb_sel, + (hwconfig("usb_pcisel")) ? 1 : 0); + /* PCISKT_WDIS# (Wireless disable GPIO to miniPCIe sockets) */ if (gpio_cfg[board].wdis) @@ -1115,6 +1229,8 @@ static void setup_board_gpio(int board) iomux_v3_cfg_t ctrl = DIO_PAD_CFG; unsigned cputype = is_cpu_type(MXC_CPU_MX6Q) ? 0 : 1; + if (!cfg->gpio_padmux[0] && !cfg->gpio_padmux[1]) + continue; sprintf(arg, "dio%d", i); if (!hwconfig(arg)) continue; @@ -1320,15 +1436,8 @@ int checkboard(void) return 0; /* Display GSC firmware revision/CRC/status */ - i2c_set_bus_num(CONFIG_I2C_GSC); - if (!gsc_i2c_read(GSC_SC_ADDR, GSC_SC_FWVER, 1, buf, 1)) { - printf("GSC: v%d", buf[0]); - if (!gsc_i2c_read(GSC_SC_ADDR, GSC_SC_STATUS, 1, buf, 4)) { - printf(" 0x%04x", buf[2] | buf[3]<<8); /* CRC */ - printf(" 0x%02x", buf[0]); /* irq status */ - } - puts("\n"); - } + gsc_info(0); + /* Display RTC */ if (!gsc_i2c_read(GSC_RTC_ADDR, 0x00, 1, buf, 4)) { printf("RTC: %d\n", @@ -1407,7 +1516,7 @@ int misc_init_r(void) sprintf(fdt, "%s-%s.dtb", cputype, str); setenv("fdt_file1", fdt); } - if (board_type != GW552x) + if (board_type != GW551x && board_type != GW552x) str[4] = 'x'; str[5] = 'x'; str[6] = 0; @@ -1430,6 +1539,10 @@ int misc_init_r(void) /* board serial-number */ sprintf(str, "%6d", info->serial); setenv("serial#", str); + + /* memory MB */ + sprintf(str, "%d", (int) (gd->ram_size >> 20)); + setenv("mem_mb", str); } @@ -1461,19 +1574,48 @@ int misc_init_r(void) } else { puts("Error: could not disable GSC Watchdog\n"); } - if (!gsc_i2c_read(GSC_SC_ADDR, GSC_SC_STATUS, 1, ®, 1)) { - if (reg & (1 << GSC_SC_IRQ_WATCHDOG)) { /* watchdog timeout */ - puts("GSC boot watchdog timeout detected\n"); - reg &= ~(1 << GSC_SC_IRQ_WATCHDOG); /* clear flag */ - gsc_i2c_write(GSC_SC_ADDR, GSC_SC_STATUS, 1, ®, 1); - } - } return 0; } #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +static int ft_sethdmiinfmt(void *blob, char *mode) +{ + int off; + + if (!mode) + return -EINVAL; + + off = fdt_node_offset_by_compatible(blob, -1, "nxp,tda1997x"); + if (off < 0) + return off; + + if (0 == strcasecmp(mode, "yuv422bt656")) { + u8 cfg[] = { 0x00, 0x00, 0x00, 0x82, 0x81, 0x00, + 0x00, 0x00, 0x00 }; + mode = "422_ccir"; + fdt_setprop(blob, off, "vidout_fmt", mode, strlen(mode) + 1); + fdt_setprop_u32(blob, off, "vidout_trc", 1); + fdt_setprop_u32(blob, off, "vidout_blc", 1); + fdt_setprop(blob, off, "vidout_portcfg", cfg, sizeof(cfg)); + printf(" set HDMI input mode to %s\n", mode); + } else if (0 == strcasecmp(mode, "yuv422smp")) { + u8 cfg[] = { 0x00, 0x00, 0x00, 0x88, 0x87, 0x00, + 0x82, 0x81, 0x00 }; + mode = "422_smp"; + fdt_setprop(blob, off, "vidout_fmt", mode, strlen(mode) + 1); + fdt_setprop_u32(blob, off, "vidout_trc", 0); + fdt_setprop_u32(blob, off, "vidout_blc", 0); + fdt_setprop(blob, off, "vidout_portcfg", cfg, sizeof(cfg)); + printf(" set HDMI input mode to %s\n", mode); + } else { + return -EINVAL; + } + + return 0; +} + /* * called prior to booting kernel or by 'fdt boardsetup' command * @@ -1492,6 +1634,17 @@ int ft_board_setup(void *blob, bd_t *bd) { "fsl,imx6q-gpmi-nand", MTD_DEV_TYPE_NAND, }, /* NAND flash */ }; const char *model = getenv("model"); + const char *display = getenv("display"); + int i; + char rev = 0; + + /* determine board revision */ + for (i = sizeof(ventana_info.model) - 1; i > 0; i--) { + if (ventana_info.model[i] >= 'A') { + rev = ventana_info.model[i]; + break; + } + } if (getenv("fdt_noauto")) { puts(" Skiping ft_board_setup (fdt_noauto defined)\n"); @@ -1502,6 +1655,13 @@ int ft_board_setup(void *blob, bd_t *bd) puts(" Updating MTD partitions...\n"); fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); + /* Update display timings from display env var */ + if (display) { + if (fdt_fixup_display(blob, fdt_get_alias(blob, "lvds0"), + display) >= 0) + printf(" Set display timings for %s...\n", display); + } + if (!model) { puts("invalid board info: Leaving FDT fully enabled\n"); return 0; @@ -1516,6 +1676,91 @@ int ft_board_setup(void *blob, bd_t *bd) fdt_setprop(blob, 0, "board", info->model, strlen((const char *)info->model) + 1); + /* set desired digital video capture format */ + ft_sethdmiinfmt(blob, getenv("hdmiinfmt")); + + /* + * disable serial2 node for GW54xx for compatibility with older + * 3.10.x kernel that improperly had this node enabled in the DT + */ + if (board_type == GW54xx) { + i = fdt_path_offset(blob, + "/soc/aips-bus@02100000/serial@021ec000"); + if (i) + fdt_del_node(blob, i); + } + + /* + * disable wdog1/wdog2 nodes for GW51xx below revC to work around + * errata causing wdog timer to be unreliable. + */ + if (board_type == GW51xx && rev >= 'A' && rev < 'C') { + i = fdt_path_offset(blob, + "/soc/aips-bus@02000000/wdog@020bc000"); + if (i) + fdt_status_disabled(blob, i); + } + + /* GW522x Uses GPIO3_IO23 instead of GPIO1_IO29 */ + else if (board_type == GW52xx && info->model[4] == '2') { + u32 handle = 0; + u32 *range = NULL; + + i = fdt_node_offset_by_compatible(blob, -1, "fsl,imx6q-pcie"); + if (i) + range = (u32 *)fdt_getprop(blob, i, "reset-gpio", + NULL); + + if (range) { + i = fdt_path_offset(blob, + "/soc/aips-bus@02000000/gpio@020a4000"); + if (i) + handle = fdt_get_phandle(blob, i); + if (handle) { + range[0] = cpu_to_fdt32(handle); + range[1] = cpu_to_fdt32(23); + } + } + } + + /* + * isolate CSI0_DATA_EN for GW551x below revB to work around + * errata causing non functional digital video in (it is not hooked up) + */ + else if (board_type == GW551x && rev == 'A') { + u32 *range = NULL; + int len; + const u32 *handle = NULL; + + i = fdt_node_offset_by_compatible(blob, -1, + "fsl,imx-tda1997x-video"); + if (i) + handle = fdt_getprop(blob, i, "pinctrl-0", NULL); + if (handle) + i = fdt_node_offset_by_phandle(blob, + fdt32_to_cpu(*handle)); + if (i) + range = (u32 *)fdt_getprop(blob, i, "fsl,pins", &len); + if (range) { + len /= sizeof(u32); + for (i = 0; i < len; i += 6) { + u32 mux_reg = fdt32_to_cpu(range[i+0]); + u32 conf_reg = fdt32_to_cpu(range[i+1]); + /* mux PAD_CSI0_DATA_EN to GPIO */ + if (is_cpu_type(MXC_CPU_MX6Q) && + mux_reg == 0x260 && conf_reg == 0x630) + range[i+3] = cpu_to_fdt32(0x5); + else if (!is_cpu_type(MXC_CPU_MX6Q) && + mux_reg == 0x08c && conf_reg == 0x3a0) + range[i+3] = cpu_to_fdt32(0x5); + } + fdt_setprop_inplace(blob, i, "fsl,pins", range, len); + } + + /* set BT656 video format */ + ft_sethdmiinfmt(blob, "yuv422bt656"); + } + /* * Peripheral Config: * remove nodes by alias path if EEPROM config tells us the diff --git a/board/gateworks/gw_ventana/gw_ventana_spl.c b/board/gateworks/gw_ventana/gw_ventana_spl.c index 9712812..0c0fee3 100644 --- a/board/gateworks/gw_ventana/gw_ventana_spl.c +++ b/board/gateworks/gw_ventana/gw_ventana_spl.c @@ -188,7 +188,21 @@ struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = { .grp_b7ds = 0x00000030, }; -/* MT41K128M16JT-125 */ +/* MT41K64M16JT-125 (1Gb density) */ +static struct mx6_ddr3_cfg mt41k64m16jt_125 = { + .mem_speed = 1600, + .density = 1, + .width = 16, + .banks = 8, + .rowaddr = 13, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +/* MT41K128M16JT-125 (2Gb density) */ static struct mx6_ddr3_cfg mt41k128m16jt_125 = { .mem_speed = 1600, .density = 2, @@ -202,7 +216,7 @@ static struct mx6_ddr3_cfg mt41k128m16jt_125 = { .trasmin = 3500, }; -/* MT41K256M16HA-125 */ +/* MT41K256M16HA-125 (4Gb density) */ static struct mx6_ddr3_cfg mt41k256m16ha_125 = { .mem_speed = 1600, .density = 4, @@ -219,6 +233,44 @@ static struct mx6_ddr3_cfg mt41k256m16ha_125 = { /* * calibration - these are the various CPU/DDR3 combinations we support */ +static struct mx6_mmdc_calibration mx6sdl_64x16_mmdc_calib = { + /* write leveling calibration determine */ + .p0_mpwldectrl0 = 0x004C004E, + .p0_mpwldectrl1 = 0x00440044, + /* Read DQS Gating calibration */ + .p0_mpdgctrl0 = 0x42440247, + .p0_mpdgctrl1 = 0x02310232, + /* Read Calibration: DQS delay relative to DQ read access */ + .p0_mprddlctl = 0x45424746, + /* Write Calibration: DQ/DM delay relative to DQS write access */ + .p0_mpwrdlctl = 0x33382C31, +}; + +static struct mx6_mmdc_calibration mx6dq_256x16_mmdc_calib = { + /* write leveling calibration determine */ + .p0_mpwldectrl0 = 0x001B0016, + .p0_mpwldectrl1 = 0x000C000E, + /* Read DQS Gating calibration */ + .p0_mpdgctrl0 = 0x4324033A, + .p0_mpdgctrl1 = 0x00000000, + /* Read Calibration: DQS delay relative to DQ read access */ + .p0_mprddlctl = 0x40403438, + /* Write Calibration: DQ/DM delay relative to DQS write access */ + .p0_mpwrdlctl = 0x40403D36, +}; + +static struct mx6_mmdc_calibration mx6sdl_256x16_mmdc_calib = { + /* write leveling calibration determine */ + .p0_mpwldectrl0 = 0x00420043, + .p0_mpwldectrl1 = 0x0016001A, + /* Read DQS Gating calibration */ + .p0_mpdgctrl0 = 0x4238023B, + .p0_mpdgctrl1 = 0x00000000, + /* Read Calibration: DQS delay relative to DQ read access */ + .p0_mprddlctl = 0x40404849, + /* Write Calibration: DQ/DM delay relative to DQS write access */ + .p0_mpwrdlctl = 0x40402E2F, +}; static struct mx6_mmdc_calibration mx6dq_128x32_mmdc_calib = { /* write leveling calibration determine */ @@ -297,6 +349,19 @@ static struct mx6_mmdc_calibration mx6dq_256x32_mmdc_calib = { .p0_mpwrdlctl = 0x32363934, }; +static struct mx6_mmdc_calibration mx6sdl_256x32_mmdc_calib = { + /* write leveling calibration determine */ + .p0_mpwldectrl0 = 0X00480047, + .p0_mpwldectrl1 = 0X003D003F, + /* Read DQS Gating calibration */ + .p0_mpdgctrl0 = 0X423E0241, + .p0_mpdgctrl1 = 0X022B022C, + /* Read Calibration: DQS delay relative to DQ read access */ + .p0_mprddlctl = 0X49454A4A, + /* Write Calibration: DQ/DM delay relative to DQS write access */ + .p0_mpwrdlctl = 0X2E372C32, +}; + static struct mx6_mmdc_calibration mx6dq_256x64_mmdc_calib = { /* write leveling calibration determine */ .p0_mpwldectrl0 = 0X00220021, @@ -340,6 +405,7 @@ static void spl_dram_init(int width, int size_mb, int board_model) .bi_on = 1, /* Bank interleaving enabled */ .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + .pd_fast_exit = 1, /* enable precharge power-down fast exit */ }; /* @@ -349,25 +415,60 @@ static void spl_dram_init(int width, int size_mb, int board_model) * mx6_ddr_sysinfo - board-specific memory architecture (width/cs/etc) * mx6_ddr_cfg - chip specific timing/layout details */ - if (width == 32 && size_mb == 512) { + if (width == 16 && size_mb == 128) { + mem = &mt41k64m16jt_125; + if (is_cpu_type(MXC_CPU_MX6Q)) + ; + else + calib = &mx6sdl_64x16_mmdc_calib; + debug("1gB density\n"); + } else if (width == 16 && size_mb == 256) { + /* 1x 2Gb density chip - same calib as 2x 2Gb */ mem = &mt41k128m16jt_125; if (is_cpu_type(MXC_CPU_MX6Q)) calib = &mx6dq_128x32_mmdc_calib; else calib = &mx6sdl_128x32_mmdc_calib; debug("2gB density\n"); - } else if (width == 64 && size_mb == 1024) { + } else if (width == 16 && size_mb == 512) { + mem = &mt41k256m16ha_125; + if (is_cpu_type(MXC_CPU_MX6Q)) + calib = &mx6dq_256x16_mmdc_calib; + else + calib = &mx6sdl_256x16_mmdc_calib; + debug("4gB density\n"); + } else if (width == 32 && size_mb == 256) { + /* Same calib as width==16, size==128 */ + mem = &mt41k64m16jt_125; + if (is_cpu_type(MXC_CPU_MX6Q)) + ; + else + calib = &mx6sdl_64x16_mmdc_calib; + debug("1gB density\n"); + } else if (width == 32 && size_mb == 512) { mem = &mt41k128m16jt_125; if (is_cpu_type(MXC_CPU_MX6Q)) - calib = &mx6dq_128x64_mmdc_calib; + calib = &mx6dq_128x32_mmdc_calib; else - calib = &mx6sdl_128x64_mmdc_calib; + calib = &mx6sdl_128x32_mmdc_calib; debug("2gB density\n"); - } else if (width == 32 && size_mb == 1024) { + } else if (width == 32 && size_mb == 1024) { mem = &mt41k256m16ha_125; if (is_cpu_type(MXC_CPU_MX6Q)) calib = &mx6dq_256x32_mmdc_calib; + else + calib = &mx6sdl_256x32_mmdc_calib; debug("4gB density\n"); + } else if (width == 64 && size_mb == 512) { + mem = &mt41k64m16jt_125; + debug("1gB density\n"); + } else if (width == 64 && size_mb == 1024) { + mem = &mt41k128m16jt_125; + if (is_cpu_type(MXC_CPU_MX6Q)) + calib = &mx6dq_128x64_mmdc_calib; + else + calib = &mx6sdl_128x64_mmdc_calib; + debug("2gB density\n"); } else if (width == 64 && size_mb == 2048) { mem = &mt41k256m16ha_125; if (is_cpu_type(MXC_CPU_MX6Q)) @@ -375,12 +476,14 @@ static void spl_dram_init(int width, int size_mb, int board_model) debug("4gB density\n"); } - if (!mem) { - puts("Error: Invalid Memory Configuration\n"); - hang(); - } - if (!calib) { - puts("Error: Invalid Board Calibration Configuration\n"); + if (!(mem && calib)) { + puts("Error: Invalid Calibration/Board Configuration\n"); + printf("MEM : %s\n", mem ? "OKAY" : "NULL"); + printf("CALIB : %s\n", calib ? "OKAY" : "NULL"); + printf("CPUTYPE: %s\n", + is_cpu_type(MXC_CPU_MX6Q) ? "IMX6Q" : "IMX6DL"); + printf("SIZE_MB: %d\n", size_mb); + printf("WIDTH : %d\n", width); hang(); } diff --git a/board/gateworks/gw_ventana/ventana_eeprom.h b/board/gateworks/gw_ventana/ventana_eeprom.h index af12711..daff375 100644 --- a/board/gateworks/gw_ventana/ventana_eeprom.h +++ b/board/gateworks/gw_ventana/ventana_eeprom.h @@ -109,6 +109,7 @@ enum { GW52xx, GW53xx, GW54xx, + GW551x, GW552x, GW_UNKNOWN, GW_BADCRC, diff --git a/board/genesi/mx51_efikamx/efikamx-usb.c b/board/genesi/mx51_efikamx/efikamx-usb.c index 0b43101..9dfd249 100644 --- a/board/genesi/mx51_efikamx/efikamx-usb.c +++ b/board/genesi/mx51_efikamx/efikamx-usb.c @@ -173,7 +173,9 @@ int board_ehci_hcd_init(int port) return 0; } -void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg) +/* This overrides a weak function */ +void mx5_ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg, + uint32_t *reg) { uint32_t port = OTG_BASE_ADDR + (0x200 * CONFIG_MXC_USB_PORT); struct usb_ehci *ehci = (struct usb_ehci *)port; diff --git a/board/google/chromebook_link/link.c b/board/google/chromebook_link/link.c index 9978e92..1b97a8f 100644 --- a/board/google/chromebook_link/link.c +++ b/board/google/chromebook_link/link.c @@ -6,6 +6,7 @@ #include <common.h> #include <cros_ec.h> +#include <dm.h> #include <asm/gpio.h> #include <asm/io.h> #include <asm/pci.h> @@ -13,8 +14,13 @@ int arch_early_init_r(void) { - if (cros_ec_board_init()) - return -1; + struct udevice *dev; + int ret; + + /* Make sure the platform controller hub is up and running */ + ret = uclass_get_device(UCLASS_PCH, 0, &dev); + if (ret) + return ret; return 0; } diff --git a/board/google/chromebox_panther/Kconfig b/board/google/chromebox_panther/Kconfig new file mode 100644 index 0000000..11df55a --- /dev/null +++ b/board/google/chromebox_panther/Kconfig @@ -0,0 +1,34 @@ +if TARGET_CHROMEBOX_PANTHER + +config SYS_BOARD + default "chromebox_panther" + +config SYS_VENDOR + default "google" + +config SYS_SOC + default "ivybridge" + +config SYS_CONFIG_NAME + default "chromebox_panther" + +# Panther actually uses haswell, not ivybridge, so this is just a placeholder +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select X86_RESET_VECTOR + select CPU_INTEL_SOCKET_RPGA989 + select NORTHBRIDGE_INTEL_IVYBRIDGE + select SOUTHBRIDGE_INTEL_C216 + select HAVE_ACPI_RESUME + select MARK_GRAPHICS_MEM_WRCOMB + select BOARD_ROMSIZE_KB_8192 + +config SYS_CAR_ADDR + hex + default 0xff7e0000 + +config SYS_CAR_SIZE + hex + default 0x20000 + +endif diff --git a/board/google/chromebox_panther/MAINTAINERS b/board/google/chromebox_panther/MAINTAINERS new file mode 100644 index 0000000..c88774b --- /dev/null +++ b/board/google/chromebox_panther/MAINTAINERS @@ -0,0 +1,6 @@ +CHROMEBOX PANTHER BOARD +M: Simon Glass <sjg@chromium.org> +S: Maintained +F: board/google/chromebook_panther/ +F: include/configs/chromebox_panther.h +F: configs/chromebox_panther_defconfig diff --git a/board/google/chromebox_panther/Makefile b/board/google/chromebox_panther/Makefile new file mode 100644 index 0000000..ce8820f --- /dev/null +++ b/board/google/chromebox_panther/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (c) 2015 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += panther.o diff --git a/board/google/chromebox_panther/panther.c b/board/google/chromebox_panther/panther.c new file mode 100644 index 0000000..d492a03 --- /dev/null +++ b/board/google/chromebox_panther/panther.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/pch.h> + +int arch_early_init_r(void) +{ + return 0; +} + +int board_early_init_f(void) +{ + return 0; +} + +void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio) +{ +} diff --git a/board/gumstix/pepper/Kconfig b/board/gumstix/pepper/Kconfig index 750db85..6f94612 100644 --- a/board/gumstix/pepper/Kconfig +++ b/board/gumstix/pepper/Kconfig @@ -12,13 +12,4 @@ config SYS_SOC config SYS_CONFIG_NAME default "pepper" -config DM - default y - -config DM_GPIO - default y - -config DM_SERIAL - default y - endif diff --git a/board/gumstix/pepper/board.c b/board/gumstix/pepper/board.c index f644f81..beb2fac 100644 --- a/board/gumstix/pepper/board.c +++ b/board/gumstix/pepper/board.c @@ -165,7 +165,7 @@ int board_eth_init(bd_t *bis) mac_addr[3] = (mac_hi & 0xFF000000) >> 24; mac_addr[4] = mac_lo & 0xFF; mac_addr[5] = (mac_lo & 0xFF00) >> 8; - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("ethaddr", mac_addr); } diff --git a/board/highbank/highbank.c b/board/highbank/highbank.c index fc2385c..ba1beb5 100644 --- a/board/highbank/highbank.c +++ b/board/highbank/highbank.c @@ -57,7 +57,7 @@ void scsi_init(void) u32 reg = readl(HB_SREG_A9_PWRDOM_STAT); if (reg & PWRDOM_STAT_SATA) { - ahci_init(HB_AHCI_BASE); + ahci_init((void __iomem *)HB_AHCI_BASE); scsi_scan(1); } } diff --git a/board/ifm/ac14xx/ac14xx.c b/board/ifm/ac14xx/ac14xx.c index 5d2ab2f..72932ca 100644 --- a/board/ifm/ac14xx/ac14xx.c +++ b/board/ifm/ac14xx/ac14xx.c @@ -225,7 +225,7 @@ int mac_read_from_eeprom(void) break; } - if (mac && is_valid_ether_addr(mac)) { + if (mac && is_valid_ethaddr(mac)) { eth_setenv_enetaddr("ethaddr", mac); if (mac_diag) { mac_txt = getenv("ethaddr"); diff --git a/board/ip04/ip04.c b/board/ip04/ip04.c index ae52633..d20500f 100644 --- a/board/ip04/ip04.c +++ b/board/ip04/ip04.c @@ -32,7 +32,7 @@ int misc_init_r(void) uchar enetaddr[6]; if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { puts("Warning: Generating 'random' MAC address\n"); - eth_random_addr(enetaddr); + net_random_ethaddr(enetaddr); eth_setenv_enetaddr("ethaddr", enetaddr); } diff --git a/board/isee/igep0033/Kconfig b/board/isee/igep0033/Kconfig index 9a8421e..e989e4b 100644 --- a/board/isee/igep0033/Kconfig +++ b/board/isee/igep0033/Kconfig @@ -12,13 +12,4 @@ config SYS_SOC config SYS_CONFIG_NAME default "am335x_igep0033" -config DM - default y - -config DM_GPIO - default y - -config DM_SERIAL - default y - endif diff --git a/board/isee/igep0033/board.c b/board/isee/igep0033/board.c index 9f8fcf2..5fea7ff 100644 --- a/board/isee/igep0033/board.c +++ b/board/isee/igep0033/board.c @@ -156,7 +156,7 @@ int board_eth_init(bd_t *bis) mac_addr[3] = (mac_hi & 0xFF000000) >> 24; mac_addr[4] = mac_lo & 0xFF; mac_addr[5] = (mac_lo & 0xFF00) >> 8; - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("ethaddr", mac_addr); } diff --git a/board/phytec/pcm051/Kconfig b/board/phytec/pcm051/Kconfig index bb98715..2cc0d88 100644 --- a/board/phytec/pcm051/Kconfig +++ b/board/phytec/pcm051/Kconfig @@ -12,13 +12,4 @@ config SYS_SOC config SYS_CONFIG_NAME default "pcm051" -config DM - default y - -config DM_GPIO - default y - -config DM_SERIAL - default y - endif diff --git a/board/phytec/pcm051/board.c b/board/phytec/pcm051/board.c index 1071662..1bf9d73 100644 --- a/board/phytec/pcm051/board.c +++ b/board/phytec/pcm051/board.c @@ -228,7 +228,7 @@ int board_eth_init(bd_t *bis) mac_addr[4] = mac_lo & 0xFF; mac_addr[5] = (mac_lo & 0xFF00) >> 8; - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("ethaddr", mac_addr); else goto try_usbether; diff --git a/board/renesas/r0p7734/r0p7734.c b/board/renesas/r0p7734/r0p7734.c index 5687ad4..2e31ba6 100644 --- a/board/renesas/r0p7734/r0p7734.c +++ b/board/renesas/r0p7734/r0p7734.c @@ -55,7 +55,7 @@ int board_late_init(void) /* Read MAC address */ i2c_read(0x50, 0x10, 0, mac, 6); - if (is_valid_ether_addr(mac)) + if (is_valid_ethaddr(mac)) eth_setenv_enetaddr("ethaddr", mac); return 0; diff --git a/board/ronetix/pm9261/pm9261.c b/board/ronetix/pm9261/pm9261.c index 1f7679a..b96f745 100644 --- a/board/ronetix/pm9261/pm9261.c +++ b/board/ronetix/pm9261/pm9261.c @@ -288,7 +288,7 @@ void reset_phy(void) * Initialize ethernet HW addr prior to starting Linux, * needed for nfsroot */ - eth_init(gd->bd); + eth_init(); #endif } #endif diff --git a/board/ronetix/pm9g45/pm9g45.c b/board/ronetix/pm9g45/pm9g45.c index 15aa4ac..efc4133 100644 --- a/board/ronetix/pm9g45/pm9g45.c +++ b/board/ronetix/pm9g45/pm9g45.c @@ -166,7 +166,7 @@ void reset_phy(void) * Initialize ethernet HW addr prior to starting Linux, * needed for nfsroot */ - eth_init(gd->bd); + eth_init(); #endif } #endif diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index 0979868..9be2950 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -330,18 +330,6 @@ int board_late_init(void) } #endif -int arch_early_init_r(void) -{ -#ifdef CONFIG_CROS_EC - if (cros_ec_board_init()) { - printf("%s: Failed to init EC\n", __func__); - return 0; - } -#endif - - return 0; -} - #ifdef CONFIG_MISC_INIT_R int misc_init_r(void) { diff --git a/board/samsung/goni/Kconfig b/board/samsung/goni/Kconfig index 006e864..cbbf5a9 100644 --- a/board/samsung/goni/Kconfig +++ b/board/samsung/goni/Kconfig @@ -12,13 +12,4 @@ config SYS_SOC config SYS_CONFIG_NAME default "s5p_goni" -config DM - default y - -config DM_GPIO - default y - -config DM_SERIAL - default y - endif diff --git a/board/samsung/smdk5420/Kconfig b/board/samsung/smdk5420/Kconfig index 576abae..a9d62ff 100644 --- a/board/samsung/smdk5420/Kconfig +++ b/board/samsung/smdk5420/Kconfig @@ -22,9 +22,6 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "peach-pi" -config DM_CROS_EC - default y - endif if TARGET_PEACH_PIT @@ -38,9 +35,6 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "peach-pit" -config DM_CROS_EC - default y - endif if TARGET_SMDK5420 diff --git a/board/samsung/smdkc100/Kconfig b/board/samsung/smdkc100/Kconfig index ea87166..d2157b4 100644 --- a/board/samsung/smdkc100/Kconfig +++ b/board/samsung/smdkc100/Kconfig @@ -12,13 +12,4 @@ config SYS_SOC config SYS_CONFIG_NAME default "smdkc100" -config DM - default y - -config DM_GPIO - default y - -config DM_SERIAL - default y - endif diff --git a/board/sandbox/README.sandbox b/board/sandbox/README.sandbox index 3c0df17..08489e3 100644 --- a/board/sandbox/README.sandbox +++ b/board/sandbox/README.sandbox @@ -173,16 +173,16 @@ U-Boot sandbox supports these emulations: - Chrome OS EC - GPIO - Host filesystem (access files on the host from within U-Boot) +- I2C - Keyboard (Chrome OS) - LCD +- Network - Serial (for console only) - Sound (incomplete - see sandbox_sdl_sound_init() for details) - SPI - SPI flash - TPM (Trusted Platform Module) -Notable omissions are networking and I2C. - A wide range of commands is implemented. Filesystems which use a block device are supported. @@ -190,6 +190,80 @@ Also sandbox uses generic board (CONFIG_SYS_GENERIC_BOARD) and supports driver model (CONFIG_DM) and associated commands. +Linux RAW Networking Bridge +--------------------------- + +The sandbox_eth_raw driver bridges traffic between the bottom of the network +stack and the RAW sockets API in Linux. This allows much of the U-Boot network +functionality to be tested in sandbox against real network traffic. + +For Ethernet network adapters, the bridge utilizes the RAW AF_PACKET API. This +is needed to get access to the lowest level of the network stack in Linux. This +means that all of the Ethernet frame is included. This allows the U-Boot network +stack to be fully used. In other words, nothing about the Linux network stack is +involved in forming the packets that end up on the wire. To receive the +responses to packets sent from U-Boot the network interface has to be set to +promiscuous mode so that the network card won't filter out packets not destined +for its configured (on Linux) MAC address. + +The RAW sockets Ethernet API requires elevated privileges in Linux. You can +either run as root, or you can add the capability needed like so: + +sudo /sbin/setcap "CAP_NET_RAW+ep" /path/to/u-boot + +The default device tree for sandbox includes an entry for eth0 on the sandbox +host machine whose alias is "eth1". The following are a few examples of network +operations being tested on the eth0 interface. + +sudo /path/to/u-boot -D + +DHCP +.... + +set autoload no +set ethact eth1 +dhcp + +PING +.... + +set autoload no +set ethact eth1 +dhcp +ping $gatewayip + +TFTP +.... + +set autoload no +set ethact eth1 +dhcp +set serverip WWW.XXX.YYY.ZZZ +tftpboot u-boot.bin + +The bridge also support (to a lesser extent) the localhost inderface, 'lo'. + +The 'lo' interface cannot use the RAW AF_PACKET API because the lo interface +doesn't support Ethernet-level traffic. It is a higher-level interface that is +expected only to be used at the AF_INET level of the API. As such, the most raw +we can get on that interface is the RAW AF_INET API on UDP. This allows us to +set the IP_HDRINCL option to include everything except the Ethernet header in +the packets we send and receive. + +Because only UDP is supported, ICMP traffic will not work, so expect that ping +commands will time out. + +The default device tree for sandbox includes an entry for lo on the sandbox +host machine whose alias is "eth5". The following is an example of a network +operation being tested on the lo interface. + +TFTP +.... + +set ethact eth5 +tftpboot u-boot.bin + + SPI Emulation ------------- diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c index e4d4e02..2227f1c 100644 --- a/board/sandbox/sandbox.c +++ b/board/sandbox/sandbox.c @@ -53,18 +53,6 @@ int board_early_init_f(void) } #endif -int arch_early_init_r(void) -{ -#ifdef CONFIG_CROS_EC - if (cros_ec_board_init()) { - printf("%s: Failed to init EC\n", __func__); - return 0; - } -#endif - - return 0; -} - #ifdef CONFIG_BOARD_LATE_INIT int board_late_init(void) { diff --git a/board/siemens/common/factoryset.c b/board/siemens/common/factoryset.c index 7baac3d..d81f548 100644 --- a/board/siemens/common/factoryset.c +++ b/board/siemens/common/factoryset.c @@ -271,7 +271,7 @@ static int factoryset_mac_setenv(void) uint8_t mac_addr[6]; debug("FactorySet: Set mac address\n"); - if (is_valid_ether_addr(factory_dat.mac)) { + if (is_valid_ethaddr(factory_dat.mac)) { memcpy(mac_addr, factory_dat.mac, 6); } else { uint32_t mac_hi, mac_lo; @@ -286,7 +286,7 @@ static int factoryset_mac_setenv(void) mac_addr[3] = (mac_hi & 0xFF000000) >> 24; mac_addr[4] = mac_lo & 0xFF; mac_addr[5] = (mac_lo & 0xFF00) >> 8; - if (!is_valid_ether_addr(mac_addr)) { + if (!is_valid_ethaddr(mac_addr)) { printf("Warning: ethaddr not set by FactorySet or E-fuse. Set <ethaddr> variable to overcome this.\n"); return -1; } diff --git a/board/siemens/pxm2/board.c b/board/siemens/pxm2/board.c index 264ba02..4d8ba3c 100644 --- a/board/siemens/pxm2/board.c +++ b/board/siemens/pxm2/board.c @@ -222,7 +222,7 @@ int board_eth_init(bd_t *bis) struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; #ifdef CONFIG_FACTORYSET int rv; - if (!is_valid_ether_addr(factory_dat.mac)) + if (!is_valid_ethaddr(factory_dat.mac)) printf("Error: no valid mac address\n"); else eth_setenv_enetaddr("ethaddr", factory_dat.mac); diff --git a/board/silica/pengwyn/Kconfig b/board/silica/pengwyn/Kconfig index 2e9a2b3..f2e1098 100644 --- a/board/silica/pengwyn/Kconfig +++ b/board/silica/pengwyn/Kconfig @@ -12,13 +12,4 @@ config SYS_SOC config SYS_CONFIG_NAME default "pengwyn" -config DM - default y - -config DM_GPIO - default y - -config DM_SERIAL - default y - endif diff --git a/board/silica/pengwyn/board.c b/board/silica/pengwyn/board.c index ee88b6f..815c9a7 100644 --- a/board/silica/pengwyn/board.c +++ b/board/silica/pengwyn/board.c @@ -189,7 +189,7 @@ int board_eth_init(bd_t *bis) mac_addr[4] = mac_lo & 0xFF; mac_addr[5] = (mac_lo & 0xFF00) >> 8; - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("ethaddr", mac_addr); else return n; diff --git a/board/solidrun/mx6cuboxi/Kconfig b/board/solidrun/mx6cuboxi/Kconfig new file mode 100644 index 0000000..31d88b2 --- /dev/null +++ b/board/solidrun/mx6cuboxi/Kconfig @@ -0,0 +1,15 @@ +if TARGET_MX6CUBOXI + +config SYS_BOARD + default "mx6cuboxi" + +config SYS_VENDOR + default "solidrun" + +config SYS_SOC + default "mx6" + +config SYS_CONFIG_NAME + default "mx6cuboxi" + +endif diff --git a/board/solidrun/mx6cuboxi/MAINTAINERS b/board/solidrun/mx6cuboxi/MAINTAINERS new file mode 100644 index 0000000..a3506c2 --- /dev/null +++ b/board/solidrun/mx6cuboxi/MAINTAINERS @@ -0,0 +1,6 @@ +MX6CUBOXI BOARD +M: Fabio Estevam <fabio.estevam@freescale.com> +S: Maintained +F: board/solidrun/mx6cuboxi/ +F: include/configs/mx6cuboxi.h +F: configs/mx6cuboxi_defconfig diff --git a/board/solidrun/mx6cuboxi/Makefile b/board/solidrun/mx6cuboxi/Makefile new file mode 100644 index 0000000..df425ac --- /dev/null +++ b/board/solidrun/mx6cuboxi/Makefile @@ -0,0 +1,9 @@ +# +# Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de> +# +# (C) Copyright 2011 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := mx6cuboxi.o diff --git a/board/solidrun/mx6cuboxi/README b/board/solidrun/mx6cuboxi/README new file mode 100644 index 0000000..3050c48 --- /dev/null +++ b/board/solidrun/mx6cuboxi/README @@ -0,0 +1,21 @@ +How to use U-boot on Solid-run mx6 hummingboard +----------------------------------------------- + +- Build U-boot for hummingboard: + +$ make mrproper +$ make mx6cuboxi_defconfig +$ make + +This will generate the SPL image called SPL and the u-boot.img. + +- Flash the SPL image into the SD card: + +sudo dd if=SPL of=/dev/mmcblk0 bs=1k seek=1; sync + +- Flash the u-boot.img image into the SD card: + +sudo dd if=u-boot.img of=/dev/mmcblk0 bs=1k seek=69; sync + +- Insert the SD card in the hummingboard, power it up and U-boot messages +should come up. diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c new file mode 100644 index 0000000..d3a32c1 --- /dev/null +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -0,0 +1,510 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * Author: Fabio Estevam <fabio.estevam@freescale.com> + * + * Copyright (C) 2013 Jon Nettleton <jon.nettleton@gmail.com> + * + * Based on SPL code from Solidrun tree, which is: + * Author: Tungyi Lin <tungyilin1127@gmail.com> + * + * Derived from EDM_CF_IMX6 code by TechNexion,Inc + * Ported to SolidRun microSOM by Rabeeh Khoury <rabeeh@solid-run.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/arch/clock.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/iomux.h> +#include <asm/arch/mx6-pins.h> +#include <asm/errno.h> +#include <asm/gpio.h> +#include <asm/imx-common/iomux-v3.h> +#include <mmc.h> +#include <fsl_esdhc.h> +#include <miiphy.h> +#include <netdev.h> +#include <asm/arch/crm_regs.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +#define ENET_PAD_CTRL_PD (PAD_CTL_PUS_100K_DOWN | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +#define ENET_PAD_CTRL_CLK ((PAD_CTL_PUS_100K_UP & ~PAD_CTL_PKE) | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) + +#define ETH_PHY_RESET IMX_GPIO_NR(4, 15) + +int dram_init(void) +{ + gd->ram_size = imx_ddr_size(); + return 0; +} + +static iomux_v3_cfg_t const uart1_pads[] = { + IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), + IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), +}; + +static iomux_v3_cfg_t const usdhc2_pads[] = { + IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), +}; + +static iomux_v3_cfg_t const hb_cbi_sense[] = { + /* These pins are for sensing if it is a CuBox-i or a HummingBoard */ + IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(UART_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA4__GPIO3_IO04 | MUX_PAD_CTRL(UART_PAD_CTRL)), +}; + +static void setup_iomux_uart(void) +{ + SETUP_IOMUX_PADS(uart1_pads); +} + +static struct fsl_esdhc_cfg usdhc_cfg[1] = { + {USDHC2_BASE_ADDR}, +}; + +int board_mmc_getcd(struct mmc *mmc) +{ + return 1; /* uSDHC2 is always present */ +} + +int board_mmc_init(bd_t *bis) +{ + SETUP_IOMUX_PADS(usdhc2_pads); + usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR; + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; + + return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); +} + +static iomux_v3_cfg_t const enet_pads[] = { + IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)), + /* AR8035 reset */ + IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)), + /* AR8035 interrupt */ + IOMUX_PADS(PAD_DI0_PIN2__GPIO4_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL)), + /* GPIO16 -> AR8035 25MHz */ + IOMUX_PADS(PAD_GPIO_16__ENET_REF_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)), + /* AR8035 CLK_25M --> ENET_REF_CLK (V22) */ + IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL_CLK)), + IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)), + IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)), + IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)), +}; + +static void setup_iomux_enet(void) +{ + SETUP_IOMUX_PADS(enet_pads); + + gpio_direction_output(ETH_PHY_RESET, 0); + mdelay(2); + gpio_set_value(ETH_PHY_RESET, 1); +} + +int board_phy_config(struct phy_device *phydev) +{ + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} + +int board_eth_init(bd_t *bis) +{ + struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; + + int ret = enable_fec_anatop_clock(ENET_25MHZ); + if (ret) + return ret; + + /* set gpr1[ENET_CLK_SEL] */ + setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK); + + setup_iomux_enet(); + + return cpu_eth_init(bis); +} + +int board_early_init_f(void) +{ + setup_iomux_uart(); + return 0; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + + return 0; +} + +static bool is_hummingboard(void) +{ + int val1, val2; + + SETUP_IOMUX_PADS(hb_cbi_sense); + + gpio_direction_input(IMX_GPIO_NR(4, 9)); + gpio_direction_input(IMX_GPIO_NR(3, 4)); + + val1 = gpio_get_value(IMX_GPIO_NR(4, 9)); + val2 = gpio_get_value(IMX_GPIO_NR(3, 4)); + + /* + * Machine selection - + * Machine val1, val2 + * ------------------------- + * HB rev 3.x x 0 + * CBi 0 1 + * HB 1 1 + */ + + if (val2 == 0) + return true; + else if (val1 == 0) + return false; + else + return true; +} + +int checkboard(void) +{ + if (is_hummingboard()) + puts("Board: MX6 Hummingboard\n"); + else + puts("Board: MX6 Cubox-i\n"); + + return 0; +} + +static bool is_mx6q(void) +{ + if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) + return true; + else + return false; +} + +int board_late_init(void) +{ +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + if (is_hummingboard()) + setenv("board_name", "HUMMINGBOARD"); + else + setenv("board_name", "CUBOXI"); + + if (is_mx6q()) + setenv("board_rev", "MX6Q"); + else + setenv("board_rev", "MX6DL"); +#endif + + return 0; +} + +#ifdef CONFIG_SPL_BUILD +#include <asm/arch/mx6-ddr.h> +static const struct mx6dq_iomux_ddr_regs mx6q_ddr_ioregs = { + .dram_sdclk_0 = 0x00020030, + .dram_sdclk_1 = 0x00020030, + .dram_cas = 0x00020030, + .dram_ras = 0x00020030, + .dram_reset = 0x00020030, + .dram_sdcke0 = 0x00003000, + .dram_sdcke1 = 0x00003000, + .dram_sdba2 = 0x00000000, + .dram_sdodt0 = 0x00003030, + .dram_sdodt1 = 0x00003030, + .dram_sdqs0 = 0x00000030, + .dram_sdqs1 = 0x00000030, + .dram_sdqs2 = 0x00000030, + .dram_sdqs3 = 0x00000030, + .dram_sdqs4 = 0x00000030, + .dram_sdqs5 = 0x00000030, + .dram_sdqs6 = 0x00000030, + .dram_sdqs7 = 0x00000030, + .dram_dqm0 = 0x00020030, + .dram_dqm1 = 0x00020030, + .dram_dqm2 = 0x00020030, + .dram_dqm3 = 0x00020030, + .dram_dqm4 = 0x00020030, + .dram_dqm5 = 0x00020030, + .dram_dqm6 = 0x00020030, + .dram_dqm7 = 0x00020030, +}; + +static const struct mx6sdl_iomux_ddr_regs mx6dl_ddr_ioregs = { + .dram_sdclk_0 = 0x00000028, + .dram_sdclk_1 = 0x00000028, + .dram_cas = 0x00000028, + .dram_ras = 0x00000028, + .dram_reset = 0x000c0028, + .dram_sdcke0 = 0x00003000, + .dram_sdcke1 = 0x00003000, + .dram_sdba2 = 0x00000000, + .dram_sdodt0 = 0x00003030, + .dram_sdodt1 = 0x00003030, + .dram_sdqs0 = 0x00000028, + .dram_sdqs1 = 0x00000028, + .dram_sdqs2 = 0x00000028, + .dram_sdqs3 = 0x00000028, + .dram_sdqs4 = 0x00000028, + .dram_sdqs5 = 0x00000028, + .dram_sdqs6 = 0x00000028, + .dram_sdqs7 = 0x00000028, + .dram_dqm0 = 0x00000028, + .dram_dqm1 = 0x00000028, + .dram_dqm2 = 0x00000028, + .dram_dqm3 = 0x00000028, + .dram_dqm4 = 0x00000028, + .dram_dqm5 = 0x00000028, + .dram_dqm6 = 0x00000028, + .dram_dqm7 = 0x00000028, +}; + +static const struct mx6dq_iomux_grp_regs mx6q_grp_ioregs = { + .grp_ddr_type = 0x000C0000, + .grp_ddrmode_ctl = 0x00020000, + .grp_ddrpke = 0x00000000, + .grp_addds = 0x00000030, + .grp_ctlds = 0x00000030, + .grp_ddrmode = 0x00020000, + .grp_b0ds = 0x00000030, + .grp_b1ds = 0x00000030, + .grp_b2ds = 0x00000030, + .grp_b3ds = 0x00000030, + .grp_b4ds = 0x00000030, + .grp_b5ds = 0x00000030, + .grp_b6ds = 0x00000030, + .grp_b7ds = 0x00000030, +}; + +static const struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = { + .grp_ddr_type = 0x000c0000, + .grp_ddrmode_ctl = 0x00020000, + .grp_ddrpke = 0x00000000, + .grp_addds = 0x00000028, + .grp_ctlds = 0x00000028, + .grp_ddrmode = 0x00020000, + .grp_b0ds = 0x00000028, + .grp_b1ds = 0x00000028, + .grp_b2ds = 0x00000028, + .grp_b3ds = 0x00000028, + .grp_b4ds = 0x00000028, + .grp_b5ds = 0x00000028, + .grp_b6ds = 0x00000028, + .grp_b7ds = 0x00000028, +}; + +/* microSOM with Dual processor and 1GB memory */ +static const struct mx6_mmdc_calibration mx6q_1g_mmcd_calib = { + .p0_mpwldectrl0 = 0x00000000, + .p0_mpwldectrl1 = 0x00000000, + .p1_mpwldectrl0 = 0x00000000, + .p1_mpwldectrl1 = 0x00000000, + .p0_mpdgctrl0 = 0x0314031c, + .p0_mpdgctrl1 = 0x023e0304, + .p1_mpdgctrl0 = 0x03240330, + .p1_mpdgctrl1 = 0x03180260, + .p0_mprddlctl = 0x3630323c, + .p1_mprddlctl = 0x3436283a, + .p0_mpwrdlctl = 0x36344038, + .p1_mpwrdlctl = 0x422a423c, +}; + +/* microSOM with Quad processor and 2GB memory */ +static const struct mx6_mmdc_calibration mx6q_2g_mmcd_calib = { + .p0_mpwldectrl0 = 0x00000000, + .p0_mpwldectrl1 = 0x00000000, + .p1_mpwldectrl0 = 0x00000000, + .p1_mpwldectrl1 = 0x00000000, + .p0_mpdgctrl0 = 0x0314031c, + .p0_mpdgctrl1 = 0x023e0304, + .p1_mpdgctrl0 = 0x03240330, + .p1_mpdgctrl1 = 0x03180260, + .p0_mprddlctl = 0x3630323c, + .p1_mprddlctl = 0x3436283a, + .p0_mpwrdlctl = 0x36344038, + .p1_mpwrdlctl = 0x422a423c, +}; + +/* microSOM with Solo processor and 512MB memory */ +static const struct mx6_mmdc_calibration mx6dl_512m_mmcd_calib = { + .p0_mpwldectrl0 = 0x0045004D, + .p0_mpwldectrl1 = 0x003A0047, + .p0_mpdgctrl0 = 0x023C0224, + .p0_mpdgctrl1 = 0x02000220, + .p0_mprddlctl = 0x44444846, + .p0_mpwrdlctl = 0x32343032, +}; + +/* microSOM with Dual lite processor and 1GB memory */ +static const struct mx6_mmdc_calibration mx6dl_1g_mmcd_calib = { + .p0_mpwldectrl0 = 0x0045004D, + .p0_mpwldectrl1 = 0x003A0047, + .p1_mpwldectrl0 = 0x001F001F, + .p1_mpwldectrl1 = 0x00210035, + .p0_mpdgctrl0 = 0x023C0224, + .p0_mpdgctrl1 = 0x02000220, + .p1_mpdgctrl0 = 0x02200220, + .p1_mpdgctrl1 = 0x02000220, + .p0_mprddlctl = 0x44444846, + .p1_mprddlctl = 0x4042463C, + .p0_mpwrdlctl = 0x32343032, + .p1_mpwrdlctl = 0x36363430, +}; + +static struct mx6_ddr3_cfg mem_ddr_2g = { + .mem_speed = 1600, + .density = 2, + .width = 16, + .banks = 8, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, + .SRT = 1, +}; + +static struct mx6_ddr3_cfg mem_ddr_4g = { + .mem_speed = 1600, + .density = 4, + .width = 16, + .banks = 8, + .rowaddr = 15, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + writel(0x00C03F3F, &ccm->CCGR0); + writel(0x0030FC03, &ccm->CCGR1); + writel(0x0FFFC000, &ccm->CCGR2); + writel(0x3FF00000, &ccm->CCGR3); + writel(0x00FFF300, &ccm->CCGR4); + writel(0x0F0000C3, &ccm->CCGR5); + writel(0x000003FF, &ccm->CCGR6); +} + +static void gpr_init(void) +{ + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + + /* enable AXI cache for VDOA/VPU/IPU */ + writel(0xF00000CF, &iomux->gpr[4]); + /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ + writel(0x007F007F, &iomux->gpr[6]); + writel(0x007F007F, &iomux->gpr[7]); +} + +/* + * This section requires the differentiation between Solidrun mx6 boards, but + * for now, it will configure only for the mx6dual hummingboard version. + */ +static void spl_dram_init(int width) +{ + struct mx6_ddr_sysinfo sysinfo = { + /* width of data bus: 0=16, 1=32, 2=64 */ + .dsize = width / 32, + /* config for full 4GB range so that get_mem_size() works */ + .cs_density = 32, /* 32Gb per CS */ + .ncs = 1, /* single chip select */ + .cs1_mirror = 0, + .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */ + .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */ + .walat = 1, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + }; + + if (is_cpu_type(MXC_CPU_MX6D) || is_cpu_type(MXC_CPU_MX6Q)) + mx6dq_dram_iocfg(width, &mx6q_ddr_ioregs, &mx6q_grp_ioregs); + else + mx6sdl_dram_iocfg(width, &mx6dl_ddr_ioregs, &mx6sdl_grp_ioregs); + + if (is_cpu_type(MXC_CPU_MX6D)) + mx6_dram_cfg(&sysinfo, &mx6q_1g_mmcd_calib, &mem_ddr_2g); + else if (is_cpu_type(MXC_CPU_MX6Q)) + mx6_dram_cfg(&sysinfo, &mx6q_2g_mmcd_calib, &mem_ddr_4g); + else if (is_cpu_type(MXC_CPU_MX6DL)) + mx6_dram_cfg(&sysinfo, &mx6q_1g_mmcd_calib, &mem_ddr_2g); + else if (is_cpu_type(MXC_CPU_MX6SOLO)) + mx6_dram_cfg(&sysinfo, &mx6dl_512m_mmcd_calib, &mem_ddr_2g); +} + +void board_init_f(ulong dummy) +{ + /* setup AIPS and disable watchdog */ + arch_cpu_init(); + + ccgr_init(); + gpr_init(); + + /* iomux and setup of i2c */ + board_early_init_f(); + + /* setup GP timer */ + timer_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* DDR initialization */ + if (is_cpu_type(MXC_CPU_MX6SOLO)) + spl_dram_init(32); + else + spl_dram_init(64); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} +#endif diff --git a/board/spear/spear300/spear300.c b/board/spear/spear300/spear300.c index 6b6bd9f..396b5bd 100644 --- a/board/spear/spear300/spear300.c +++ b/board/spear/spear300/spear300.c @@ -51,7 +51,7 @@ int board_eth_init(bd_t *bis) { int ret = 0; -#if defined(CONFIG_DESIGNWARE_ETH) +#if defined(CONFIG_ETH_DESIGNWARE) u32 interface = PHY_INTERFACE_MODE_MII; if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0) ret++; diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c index a4c6a8e..6f39ef1 100644 --- a/board/spear/spear310/spear310.c +++ b/board/spear/spear310/spear310.c @@ -52,7 +52,7 @@ int board_eth_init(bd_t *bis) { int ret = 0; -#if defined(CONFIG_DESIGNWARE_ETH) +#if defined(CONFIG_ETH_DESIGNWARE) u32 interface = PHY_INTERFACE_MODE_MII; if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0) ret++; diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c index ab732a7..52196af 100644 --- a/board/spear/spear320/spear320.c +++ b/board/spear/spear320/spear320.c @@ -63,7 +63,7 @@ int board_eth_init(bd_t *bis) { int ret = 0; -#if defined(CONFIG_DESIGNWARE_ETH) +#if defined(CONFIG_ETH_DESIGNWARE) u32 interface = PHY_INTERFACE_MODE_MII; if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0) ret++; diff --git a/board/spear/spear600/spear600.c b/board/spear/spear600/spear600.c index 8472002..fc0918f 100644 --- a/board/spear/spear600/spear600.c +++ b/board/spear/spear600/spear600.c @@ -46,7 +46,7 @@ int board_eth_init(bd_t *bis) { int ret = 0; -#if defined(CONFIG_DESIGNWARE_ETH) +#if defined(CONFIG_ETH_DESIGNWARE) u32 interface = PHY_INTERFACE_MODE_MII; #if defined(CONFIG_DW_AUTONEG) interface = PHY_INTERFACE_MODE_GMII; diff --git a/board/st/stm32f429-discovery/Kconfig b/board/st/stm32f429-discovery/Kconfig new file mode 100644 index 0000000..e73d11b --- /dev/null +++ b/board/st/stm32f429-discovery/Kconfig @@ -0,0 +1,19 @@ +if TARGET_STM32F429_DISCOVERY + +config SYS_BOARD + string + default "stm32f429-discovery" + +config SYS_VENDOR + string + default "st" + +config SYS_SOC + string + default "stm32f4" + +config SYS_CONFIG_NAME + string + default "stm32f429-discovery" + +endif diff --git a/board/st/stm32f429-discovery/MAINTAINERS b/board/st/stm32f429-discovery/MAINTAINERS new file mode 100644 index 0000000..78b0d28 --- /dev/null +++ b/board/st/stm32f429-discovery/MAINTAINERS @@ -0,0 +1,5 @@ +M: Kamil Lulko <rev13@wp.pl> +S: Maintained +F: board/st/stm32f429-discovery/ +F: include/configs/stm32f429-discovery.h +F: configs/stm32f429-discovery_defconfig diff --git a/board/st/stm32f429-discovery/Makefile b/board/st/stm32f429-discovery/Makefile new file mode 100644 index 0000000..7e764e3 --- /dev/null +++ b/board/st/stm32f429-discovery/Makefile @@ -0,0 +1,12 @@ +# +# (C) Copyright 2000-2004 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2015 +# Kamil Lulko, <rev13@wp.pl> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := stm32f429-discovery.o +obj-y += led.o diff --git a/board/st/stm32f429-discovery/led.c b/board/st/stm32f429-discovery/led.c new file mode 100644 index 0000000..306e550 --- /dev/null +++ b/board/st/stm32f429-discovery/led.c @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm-generic/gpio.h> + +void coloured_LED_init(void) +{ + gpio_direction_output(CONFIG_RED_LED, 0); + gpio_direction_output(CONFIG_GREEN_LED, 0); +} + +void red_led_off(void) +{ + gpio_set_value(CONFIG_RED_LED, 0); +} + +void green_led_off(void) +{ + gpio_set_value(CONFIG_GREEN_LED, 0); +} + +void red_led_on(void) +{ + gpio_set_value(CONFIG_RED_LED, 1); +} + +void green_led_on(void) +{ + gpio_set_value(CONFIG_GREEN_LED, 1); +} diff --git a/board/st/stm32f429-discovery/stm32f429-discovery.c b/board/st/stm32f429-discovery/stm32f429-discovery.c new file mode 100644 index 0000000..2c4830f --- /dev/null +++ b/board/st/stm32f429-discovery/stm32f429-discovery.c @@ -0,0 +1,287 @@ +/* + * (C) Copyright 2011, 2012, 2013 + * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com + * Alexander Potashev, Emcraft Systems, aspotashev@emcraft.com + * Vladimir Khusainov, Emcraft Systems, vlad@emcraft.com + * Pavel Boldin, Emcraft Systems, paboldin@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/armv7m.h> +#include <asm/arch/stm32.h> +#include <asm/arch/gpio.h> +#include <asm/arch/fmc.h> + +DECLARE_GLOBAL_DATA_PTR; + +const struct stm32_gpio_ctl gpio_ctl_gpout = { + .mode = STM32_GPIO_MODE_OUT, + .otype = STM32_GPIO_OTYPE_PP, + .speed = STM32_GPIO_SPEED_50M, + .pupd = STM32_GPIO_PUPD_NO, + .af = STM32_GPIO_AF0 +}; + +const struct stm32_gpio_ctl gpio_ctl_usart = { + .mode = STM32_GPIO_MODE_AF, + .otype = STM32_GPIO_OTYPE_PP, + .speed = STM32_GPIO_SPEED_50M, + .pupd = STM32_GPIO_PUPD_UP, + .af = STM32_GPIO_AF7 +}; + +static const struct stm32_gpio_dsc usart1_gpio[] = { + {STM32_GPIO_PORT_A, STM32_GPIO_PIN_9}, /* TX */ + {STM32_GPIO_PORT_A, STM32_GPIO_PIN_10}, /* RX */ +}; + +int uart1_setup_gpio(void) +{ + int i; + int rv = 0; + + for (i = 0; i < ARRAY_SIZE(usart1_gpio); i++) { + rv = stm32_gpio_config(&usart1_gpio[i], &gpio_ctl_usart); + if (rv) + goto out; + } + +out: + return rv; +} + +const struct stm32_gpio_ctl gpio_ctl_fmc = { + .mode = STM32_GPIO_MODE_AF, + .otype = STM32_GPIO_OTYPE_PP, + .speed = STM32_GPIO_SPEED_100M, + .pupd = STM32_GPIO_PUPD_NO, + .af = STM32_GPIO_AF12 +}; + +static const struct stm32_gpio_dsc ext_ram_fmc_gpio[] = { + /* Chip is LQFP144, see DM00077036.pdf for details */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_10}, /* 79, FMC_D15 */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_9}, /* 78, FMC_D14 */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_8}, /* 77, FMC_D13 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_15}, /* 68, FMC_D12 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_14}, /* 67, FMC_D11 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_13}, /* 66, FMC_D10 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_12}, /* 65, FMC_D9 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_11}, /* 64, FMC_D8 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_10}, /* 63, FMC_D7 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_9}, /* 60, FMC_D6 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_8}, /* 59, FMC_D5 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_7}, /* 58, FMC_D4 */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_1}, /* 115, FMC_D3 */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_0}, /* 114, FMC_D2 */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_15}, /* 86, FMC_D1 */ + {STM32_GPIO_PORT_D, STM32_GPIO_PIN_14}, /* 85, FMC_D0 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_1}, /* 142, FMC_NBL1 */ + {STM32_GPIO_PORT_E, STM32_GPIO_PIN_0}, /* 141, FMC_NBL0 */ + {STM32_GPIO_PORT_G, STM32_GPIO_PIN_5}, /* 90, FMC_A15, BA1 */ + {STM32_GPIO_PORT_G, STM32_GPIO_PIN_4}, /* 89, FMC_A14, BA0 */ + {STM32_GPIO_PORT_G, STM32_GPIO_PIN_1}, /* 57, FMC_A11 */ + {STM32_GPIO_PORT_G, STM32_GPIO_PIN_0}, /* 56, FMC_A10 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_15}, /* 55, FMC_A9 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_14}, /* 54, FMC_A8 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_13}, /* 53, FMC_A7 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_12}, /* 50, FMC_A6 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_5}, /* 15, FMC_A5 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_4}, /* 14, FMC_A4 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_3}, /* 13, FMC_A3 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_2}, /* 12, FMC_A2 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_1}, /* 11, FMC_A1 */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_0}, /* 10, FMC_A0 */ + {STM32_GPIO_PORT_B, STM32_GPIO_PIN_6}, /* 136, SDRAM_NE */ + {STM32_GPIO_PORT_F, STM32_GPIO_PIN_11}, /* 49, SDRAM_NRAS */ + {STM32_GPIO_PORT_G, STM32_GPIO_PIN_15}, /* 132, SDRAM_NCAS */ + {STM32_GPIO_PORT_C, STM32_GPIO_PIN_0}, /* 26, SDRAM_NWE */ + {STM32_GPIO_PORT_B, STM32_GPIO_PIN_5}, /* 135, SDRAM_CKE */ + {STM32_GPIO_PORT_G, STM32_GPIO_PIN_8}, /* 93, SDRAM_CLK */ +}; + +static int fmc_setup_gpio(void) +{ + int rv = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(ext_ram_fmc_gpio); i++) { + rv = stm32_gpio_config(&ext_ram_fmc_gpio[i], + &gpio_ctl_fmc); + if (rv) + goto out; + } + +out: + return rv; +} + +/* + * STM32 RCC FMC specific definitions + */ +#define STM32_RCC_ENR_FMC (1 << 0) /* FMC module clock */ + +static inline u32 _ns2clk(u32 ns, u32 freq) +{ + u32 tmp = freq/1000000; + return (tmp * ns) / 1000; +} + +#define NS2CLK(ns) (_ns2clk(ns, freq)) + +/* + * Following are timings for IS42S16400J, from corresponding datasheet + */ +#define SDRAM_CAS 3 /* 3 cycles */ +#define SDRAM_NB 1 /* Number of banks */ +#define SDRAM_MWID 1 /* 16 bit memory */ + +#define SDRAM_NR 0x1 /* 12-bit row */ +#define SDRAM_NC 0x0 /* 8-bit col */ +#define SDRAM_RBURST 0x1 /* Single read requests always as bursts */ +#define SDRAM_RPIPE 0x0 /* No HCLK clock cycle delay */ + +#define SDRAM_TRRD (NS2CLK(14) - 1) +#define SDRAM_TRCD (NS2CLK(15) - 1) +#define SDRAM_TRP (NS2CLK(15) - 1) +#define SDRAM_TRAS (NS2CLK(42) - 1) +#define SDRAM_TRC (NS2CLK(63) - 1) +#define SDRAM_TRFC (NS2CLK(63) - 1) +#define SDRAM_TCDL (1 - 1) +#define SDRAM_TRDL (2 - 1) +#define SDRAM_TBDL (1 - 1) +#define SDRAM_TREF 1386 +#define SDRAM_TCCD (1 - 1) + +#define SDRAM_TXSR (NS2CLK(70) - 1)/* Row cycle time after precharge */ +#define SDRAM_TMRD (3 - 1) /* Page 10, Mode Register Set */ + +/* Last data-in to row precharge, need also comply ineq from RM 37.7.5 */ +#define SDRAM_TWR max(\ + (int)max((int)SDRAM_TRDL, (int)(SDRAM_TRAS - SDRAM_TRCD - 1)), \ + (int)(SDRAM_TRC - SDRAM_TRCD - SDRAM_TRP - 2)\ +) + +#define SDRAM_MODE_BL_SHIFT 0 +#define SDRAM_MODE_CAS_SHIFT 4 +#define SDRAM_MODE_BL 0 +#define SDRAM_MODE_CAS SDRAM_CAS + +int dram_init(void) +{ + u32 freq; + int rv; + + rv = fmc_setup_gpio(); + if (rv) + return rv; + + setbits_le32(&STM32_RCC->ahb3enr, STM32_RCC_ENR_FMC); + + /* + * Get frequency for NS2CLK calculation. + */ + freq = clock_get(CLOCK_AHB) / CONFIG_SYS_RAM_FREQ_DIV; + + writel(CONFIG_SYS_RAM_FREQ_DIV << FMC_SDCR_SDCLK_SHIFT + | SDRAM_RPIPE << FMC_SDCR_RPIPE_SHIFT + | SDRAM_RBURST << FMC_SDCR_RBURST_SHIFT, + &STM32_SDRAM_FMC->sdcr1); + + writel(CONFIG_SYS_RAM_FREQ_DIV << FMC_SDCR_SDCLK_SHIFT + | SDRAM_CAS << FMC_SDCR_CAS_SHIFT + | SDRAM_NB << FMC_SDCR_NB_SHIFT + | SDRAM_MWID << FMC_SDCR_MWID_SHIFT + | SDRAM_NR << FMC_SDCR_NR_SHIFT + | SDRAM_NC << FMC_SDCR_NC_SHIFT + | SDRAM_RPIPE << FMC_SDCR_RPIPE_SHIFT + | SDRAM_RBURST << FMC_SDCR_RBURST_SHIFT, + &STM32_SDRAM_FMC->sdcr2); + + writel(SDRAM_TRP << FMC_SDTR_TRP_SHIFT + | SDRAM_TRC << FMC_SDTR_TRC_SHIFT, + &STM32_SDRAM_FMC->sdtr1); + + writel(SDRAM_TRCD << FMC_SDTR_TRCD_SHIFT + | SDRAM_TRP << FMC_SDTR_TRP_SHIFT + | SDRAM_TWR << FMC_SDTR_TWR_SHIFT + | SDRAM_TRC << FMC_SDTR_TRC_SHIFT + | SDRAM_TRAS << FMC_SDTR_TRAS_SHIFT + | SDRAM_TXSR << FMC_SDTR_TXSR_SHIFT + | SDRAM_TMRD << FMC_SDTR_TMRD_SHIFT, + &STM32_SDRAM_FMC->sdtr2); + + writel(FMC_SDCMR_BANK_2 | FMC_SDCMR_MODE_START_CLOCK, + &STM32_SDRAM_FMC->sdcmr); + + udelay(200); /* 200 us delay, page 10, "Power-Up" */ + FMC_BUSY_WAIT(); + + writel(FMC_SDCMR_BANK_2 | FMC_SDCMR_MODE_PRECHARGE, + &STM32_SDRAM_FMC->sdcmr); + + udelay(100); + FMC_BUSY_WAIT(); + + writel((FMC_SDCMR_BANK_2 | FMC_SDCMR_MODE_AUTOREFRESH + | 7 << FMC_SDCMR_NRFS_SHIFT), &STM32_SDRAM_FMC->sdcmr); + + udelay(100); + FMC_BUSY_WAIT(); + + writel(FMC_SDCMR_BANK_2 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT + | SDRAM_MODE_CAS << SDRAM_MODE_CAS_SHIFT) + << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE, + &STM32_SDRAM_FMC->sdcmr); + + udelay(100); + + FMC_BUSY_WAIT(); + + writel(FMC_SDCMR_BANK_2 | FMC_SDCMR_MODE_NORMAL, + &STM32_SDRAM_FMC->sdcmr); + + FMC_BUSY_WAIT(); + + /* Refresh timer */ + writel(SDRAM_TREF, &STM32_SDRAM_FMC->sdrtr); + + /* + * Fill in global info with description of SRAM configuration + */ + gd->bd->bi_dram[0].start = CONFIG_SYS_RAM_BASE; + gd->bd->bi_dram[0].size = CONFIG_SYS_RAM_SIZE; + + gd->ram_size = CONFIG_SYS_RAM_SIZE; + + return rv; +} + +u32 get_board_rev(void) +{ + return 0; +} + +int board_early_init_f(void) +{ + int res; + + res = uart1_setup_gpio(); + if (res) + return res; + + return 0; +} + +int board_init(void) +{ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + + return 0; +} diff --git a/board/st/stv0991/stv0991.c b/board/st/stv0991/stv0991.c index f465699..38f6e1d 100644 --- a/board/st/stv0991/stv0991.c +++ b/board/st/stv0991/stv0991.c @@ -94,7 +94,7 @@ int board_eth_init(bd_t *bis) { int ret = 0; -#if defined(CONFIG_DESIGNWARE_ETH) +#if defined(CONFIG_ETH_DESIGNWARE) u32 interface = PHY_INTERFACE_MODE_MII; if (designware_initialize(GMAC_BASE_ADDR, interface) >= 0) ret++; diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 2fcab60..88e3358 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -212,6 +212,25 @@ config MMC3_CD_PIN ---help--- See MMC0_CD_PIN help text. +config MMC1_PINS + string "Pins for mmc1" + default "" + ---help--- + Set the pins used for mmc1, when applicable. This takes a string in the + format understood by sunxi_name_to_gpio_bank, e.g. PH for port H. + +config MMC2_PINS + string "Pins for mmc2" + default "" + ---help--- + See MMC1_PINS help text. + +config MMC3_PINS + string "Pins for mmc3" + default "" + ---help--- + See MMC1_PINS help text. + config MMC_SUNXI_SLOT_EXTRA int "mmc extra slot number" default -1 @@ -229,7 +248,6 @@ config USB0_VBUS_PIN config USB0_VBUS_DET string "Vbus detect pin for usb0 (otg)" - depends on USB_MUSB_SUNXI default "" ---help--- Set the Vbus detect pin for usb0 (otg). This takes a string in the @@ -251,6 +269,44 @@ config USB2_VBUS_PIN ---help--- See USB1_VBUS_PIN help text. +config I2C0_ENABLE + bool "Enable I2C/TWI controller 0" + default y if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I + default n if MACH_SUN6I || MACH_SUN8I + ---help--- + This allows enabling I2C/TWI controller 0 by muxing its pins, enabling + its clock and setting up the bus. This is especially useful on devices + with slaves connected to the bus or with pins exposed through e.g. an + expansion port/header. + +config I2C1_ENABLE + bool "Enable I2C/TWI controller 1" + default n + ---help--- + See I2C0_ENABLE help text. + +config I2C2_ENABLE + bool "Enable I2C/TWI controller 2" + default n + ---help--- + See I2C0_ENABLE help text. + +if MACH_SUN6I || MACH_SUN7I +config I2C3_ENABLE + bool "Enable I2C/TWI controller 3" + default n + ---help--- + See I2C0_ENABLE help text. +endif + +if MACH_SUN7I +config I2C4_ENABLE + bool "Enable I2C/TWI controller 4" + default n + ---help--- + See I2C0_ENABLE help text. +endif + config VIDEO boolean "Enable graphical uboot console on HDMI, LCD or VGA" default y diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index be48213..75e8b5a 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -42,15 +42,18 @@ F: configs/Ippo_q8h_v1_2_defconfig A20-OLINUXINO-LIME BOARD M: FUKAUMI Naoki <naobsd@gmail.com> S: Maintained -F: board/sunxi/dram_a20_olinuxino_l.c F: configs/A20-OLinuXino-Lime_defconfig A20-OLINUXINO-LIME2 BOARD M: Iain Paton <ipaton0@gmail.com> S: Maintained -F: board/sunxi/dram_a20_olinuxino_l2.c F: configs/A20-OLinuXino-Lime2_defconfig +AINOL AW1 BOARD +M: Paul Kocialkowski <contact@paulk.fr> +S: Maintained +F: configs/Ainol_AW1_defconfig + AMPE A76 BOARD M: Paul Kocialkowski <contact@paulk.fr> S: Maintained @@ -84,11 +87,20 @@ M: Chen-Yu Tsai <wens@csie.org> S: Maintained F: configs/Hummingbird_A31_defconfig -INET-86VS BOARD +INET 3F BOARD +M: Paul Kocialkowski <contact@paulk.fr> +S: Maintained +F: configs/iNet_3F_defconfig + +INET 3W BOARD +M: Paul Kocialkowski <contact@paulk.fr> +S: Maintained +F: configs/iNet_3W_defconfig + +INET 86VS BOARD M: Michal Suchanek <hramrach@gmail.com> S: Maintained -F: board/sunxi/dram_inet_86vs.c -F: configs/Inet_86VS_defconfig +F: configs/iNet_86VS_defconfig IPPO-Q8H-V5 BOARD M: Chen-Yu Tsai <wens@csie.org> @@ -120,6 +132,11 @@ M: Ian Campbell <ijc@hellion.org.uk> S: Maintained F: configs/Mele_M5_defconfig +MIXTILE-LOFTQ BOARD +M: Phil Han <pengphei@sina.com> +S: Maintained +F: configs/mixtile_loftq_defconfig + MK808C BOARD M: Marcus Cooper <codekipper@gmail.com> S: Maintained @@ -144,3 +161,8 @@ WEXLER-TAB7200 BOARD M: Aleksei Mamlin <mamlinav@gmail.com> S: Maintained F: configs/Wexler_TAB7200_defconfig + +YONES TOPTECH BD1078 BOARD +M: Paul Kocialkowski <contact@paulk.fr> +S: Maintained +F: configs/Yones_Toptech_BD1078_defconfig diff --git a/board/sunxi/ahci.c b/board/sunxi/ahci.c index b7f0dda..6d51b9b 100644 --- a/board/sunxi/ahci.c +++ b/board/sunxi/ahci.c @@ -83,5 +83,5 @@ void scsi_init(void) if (sunxi_ahci_phy_init(SUNXI_SATA_BASE) < 0) return; - ahci_init(SUNXI_SATA_BASE); + ahci_init((void __iomem *)SUNXI_SATA_BASE); } diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 808bf82..dda50b5 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -71,42 +71,163 @@ int dram_init(void) static void mmc_pinmux_setup(int sdc) { unsigned int pin; + __maybe_unused int pins; switch (sdc) { case 0: - /* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-PF5 */ + /* SDC0: PF0-PF5 */ for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) { - sunxi_gpio_set_cfgpin(pin, SUNXI_GPF0_SDC0); + sunxi_gpio_set_cfgpin(pin, SUNXI_GPF_SDC0); sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); sunxi_gpio_set_drv(pin, 2); } break; case 1: - /* CMD-PG3, CLK-PG4, D0~D3-PG5-8 */ + pins = sunxi_name_to_gpio_bank(CONFIG_MMC1_PINS); + +#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) + if (pins == SUNXI_GPIO_H) { + /* SDC1: PH22-PH-27 */ + for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) { + sunxi_gpio_set_cfgpin(pin, SUN4I_GPH_SDC1); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + } else { + /* SDC1: PG0-PG5 */ + for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) { + sunxi_gpio_set_cfgpin(pin, SUN4I_GPG_SDC1); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + } +#elif defined(CONFIG_MACH_SUN5I) + /* SDC1: PG3-PG8 */ for (pin = SUNXI_GPG(3); pin <= SUNXI_GPG(8); pin++) { - sunxi_gpio_set_cfgpin(pin, SUN5I_GPG3_SDC1); + sunxi_gpio_set_cfgpin(pin, SUN5I_GPG_SDC1); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } +#elif defined(CONFIG_MACH_SUN6I) + /* SDC1: PG0-PG5 */ + for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) { + sunxi_gpio_set_cfgpin(pin, SUN6I_GPG_SDC1); sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); sunxi_gpio_set_drv(pin, 2); } +#elif defined(CONFIG_MACH_SUN8I) + if (pins == SUNXI_GPIO_D) { + /* SDC1: PD2-PD7 */ + for (pin = SUNXI_GPD(2); pin <= SUNXI_GPD(7); pin++) { + sunxi_gpio_set_cfgpin(pin, SUN8I_GPD_SDC1); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + } else { + /* SDC1: PG0-PG5 */ + for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) { + sunxi_gpio_set_cfgpin(pin, SUN8I_GPG_SDC1); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + } +#endif break; case 2: - /* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-PC11 */ + pins = sunxi_name_to_gpio_bank(CONFIG_MMC2_PINS); + +#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) + /* SDC2: PC6-PC11 */ for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) { - sunxi_gpio_set_cfgpin(pin, SUNXI_GPC6_SDC2); + sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } +#elif defined(CONFIG_MACH_SUN5I) + if (pins == SUNXI_GPIO_E) { + /* SDC2: PE4-PE9 */ + for (pin = SUNXI_GPE(4); pin <= SUNXI_GPD(9); pin++) { + sunxi_gpio_set_cfgpin(pin, SUN5I_GPE_SDC2); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + } else { + /* SDC2: PC6-PC15 */ + for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { + sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + } +#elif defined(CONFIG_MACH_SUN6I) + if (pins == SUNXI_GPIO_A) { + /* SDC2: PA9-PA14 */ + for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) { + sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC2); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + } else { + /* SDC2: PC6-PC15, PC24 */ + for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { + sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + + sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2); + sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(SUNXI_GPC(24), 2); + } +#elif defined(CONFIG_MACH_SUN8I) + /* SDC2: PC5-PC6, PC8-PC16 */ + for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) { + sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + + for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(16); pin++) { + sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2); sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); sunxi_gpio_set_drv(pin, 2); } +#endif break; case 3: - /* CMD-PI4, CLK-PI5, D0~D3-PI6~9 : 2 */ + pins = sunxi_name_to_gpio_bank(CONFIG_MMC3_PINS); + +#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) + /* SDC3: PI4-PI9 */ for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) { - sunxi_gpio_set_cfgpin(pin, SUN4I_GPI4_SDC3); + sunxi_gpio_set_cfgpin(pin, SUNXI_GPI_SDC3); sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); sunxi_gpio_set_drv(pin, 2); } +#elif defined(CONFIG_MACH_SUN6I) + if (pins == SUNXI_GPIO_A) { + /* SDC3: PA9-PA14 */ + for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) { + sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC3); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + } else { + /* SDC3: PC6-PC15, PC24 */ + for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) { + sunxi_gpio_set_cfgpin(pin, SUN6I_GPC_SDC3); + sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(pin, 2); + } + + sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUN6I_GPC_SDC3); + sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP); + sunxi_gpio_set_drv(SUNXI_GPC(24), 2); + } +#endif break; default: @@ -155,9 +276,82 @@ int board_mmc_init(bd_t *bis) void i2c_init_board(void) { - sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUNXI_GPB0_TWI0); - sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUNXI_GPB0_TWI0); +#ifdef CONFIG_I2C0_ENABLE +#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I) + sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN4I_GPB_TWI0); + sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN4I_GPB_TWI0); + clock_twi_onoff(0, 1); +#elif defined(CONFIG_MACH_SUN6I) + sunxi_gpio_set_cfgpin(SUNXI_GPH(14), SUN6I_GPH_TWI0); + sunxi_gpio_set_cfgpin(SUNXI_GPH(15), SUN6I_GPH_TWI0); + clock_twi_onoff(0, 1); +#elif defined(CONFIG_MACH_SUN8I) + sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0); + sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0); clock_twi_onoff(0, 1); +#endif +#endif + +#ifdef CONFIG_I2C1_ENABLE +#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) + sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN4I_GPB_TWI1); + sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN4I_GPB_TWI1); + clock_twi_onoff(1, 1); +#elif defined(CONFIG_MACH_SUN5I) + sunxi_gpio_set_cfgpin(SUNXI_GPB(15), SUN5I_GPB_TWI1); + sunxi_gpio_set_cfgpin(SUNXI_GPB(16), SUN5I_GPB_TWI1); + clock_twi_onoff(1, 1); +#elif defined(CONFIG_MACH_SUN6I) + sunxi_gpio_set_cfgpin(SUNXI_GPH(16), SUN6I_GPH_TWI1); + sunxi_gpio_set_cfgpin(SUNXI_GPH(17), SUN6I_GPH_TWI1); + clock_twi_onoff(1, 1); +#elif defined(CONFIG_MACH_SUN8I) + sunxi_gpio_set_cfgpin(SUNXI_GPH(4), SUN8I_GPH_TWI1); + sunxi_gpio_set_cfgpin(SUNXI_GPH(5), SUN8I_GPH_TWI1); + clock_twi_onoff(1, 1); +#endif +#endif + +#ifdef CONFIG_I2C2_ENABLE +#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) + sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN4I_GPB_TWI2); + sunxi_gpio_set_cfgpin(SUNXI_GPB(21), SUN4I_GPB_TWI2); + clock_twi_onoff(2, 1); +#elif defined(CONFIG_MACH_SUN5I) + sunxi_gpio_set_cfgpin(SUNXI_GPB(17), SUN5I_GPB_TWI2); + sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN5I_GPB_TWI2); + clock_twi_onoff(2, 1); +#elif defined(CONFIG_MACH_SUN6I) + sunxi_gpio_set_cfgpin(SUNXI_GPH(18), SUN6I_GPH_TWI2); + sunxi_gpio_set_cfgpin(SUNXI_GPH(19), SUN6I_GPH_TWI2); + clock_twi_onoff(2, 1); +#elif defined(CONFIG_MACH_SUN8I) + sunxi_gpio_set_cfgpin(SUNXI_GPE(12), SUN8I_GPE_TWI2); + sunxi_gpio_set_cfgpin(SUNXI_GPE(13), SUN8I_GPE_TWI2); + clock_twi_onoff(2, 1); +#endif +#endif + +#ifdef CONFIG_I2C3_ENABLE +#if defined(CONFIG_MACH_SUN6I) + sunxi_gpio_set_cfgpin(SUNXI_GPG(10), SUN6I_GPG_TWI3); + sunxi_gpio_set_cfgpin(SUNXI_GPG(11), SUN6I_GPG_TWI3); + clock_twi_onoff(3, 1); +#elif defined(CONFIG_MACH_SUN7I) + sunxi_gpio_set_cfgpin(SUNXI_GPI(0), SUN7I_GPI_TWI3); + sunxi_gpio_set_cfgpin(SUNXI_GPI(1), SUN7I_GPI_TWI3); + clock_twi_onoff(3, 1); +#endif +#endif + +#ifdef CONFIG_I2C4_ENABLE +#if defined(CONFIG_MACH_SUN7I) + sunxi_gpio_set_cfgpin(SUNXI_GPI(2), SUN7I_GPI_TWI4); + sunxi_gpio_set_cfgpin(SUNXI_GPI(3), SUN7I_GPI_TWI4); + clock_twi_onoff(4, 1); +#endif +#endif + #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD) soft_i2c_gpio_sda = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SDA); soft_i2c_gpio_scl = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SCL); @@ -241,23 +435,41 @@ static struct musb_hdrc_platform_data musb_plat = { }; #endif +#ifdef CONFIG_USB_GADGET +int g_dnl_board_usb_cable_connected(void) +{ + return sunxi_usbc_vbus_detect(0); +} +#endif + #ifdef CONFIG_MISC_INIT_R int misc_init_r(void) { + char serial_string[17] = { 0 }; unsigned int sid[4]; + uint8_t mac_addr[6]; + int ret; + + ret = sunxi_get_sid(sid); + if (ret == 0 && sid[0] != 0 && sid[3] != 0) { + if (!getenv("ethaddr")) { + /* Non OUI / registered MAC address */ + mac_addr[0] = 0x02; + mac_addr[1] = (sid[0] >> 0) & 0xff; + mac_addr[2] = (sid[3] >> 24) & 0xff; + mac_addr[3] = (sid[3] >> 16) & 0xff; + mac_addr[4] = (sid[3] >> 8) & 0xff; + mac_addr[5] = (sid[3] >> 0) & 0xff; + + eth_setenv_enetaddr("ethaddr", mac_addr); + } - if (!getenv("ethaddr") && sunxi_get_sid(sid) == 0 && - sid[0] != 0 && sid[3] != 0) { - uint8_t mac_addr[6]; - - mac_addr[0] = 0x02; /* Non OUI / registered MAC address */ - mac_addr[1] = (sid[0] >> 0) & 0xff; - mac_addr[2] = (sid[3] >> 24) & 0xff; - mac_addr[3] = (sid[3] >> 16) & 0xff; - mac_addr[4] = (sid[3] >> 8) & 0xff; - mac_addr[5] = (sid[3] >> 0) & 0xff; + if (!getenv("serial#")) { + snprintf(serial_string, sizeof(serial_string), + "%08x%08x", sid[0], sid[3]); - eth_setenv_enetaddr("ethaddr", mac_addr); + setenv("serial#", serial_string); + } } #if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET) diff --git a/board/sunxi/gmac.c b/board/sunxi/gmac.c index 8849132..d90eed4 100644 --- a/board/sunxi/gmac.c +++ b/board/sunxi/gmac.c @@ -39,52 +39,56 @@ int sunxi_gmac_initialize(bd_t *bis) if (pin == SUNXI_GPA(9) || pin == SUNXI_GPA(14)) continue; #endif - sunxi_gpio_set_cfgpin(pin, SUN7I_GPA0_GMAC); + sunxi_gpio_set_cfgpin(pin, SUN7I_GPA_GMAC); sunxi_gpio_set_drv(pin, 3); } #elif defined CONFIG_RGMII /* Configure sun6i RGMII mode pin mux settings */ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(3); pin++) { - sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC); + sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC); sunxi_gpio_set_drv(pin, 3); } for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) { - sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC); + sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC); sunxi_gpio_set_drv(pin, 3); } for (pin = SUNXI_GPA(19); pin <= SUNXI_GPA(20); pin++) { - sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC); + sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC); sunxi_gpio_set_drv(pin, 3); } for (pin = SUNXI_GPA(25); pin <= SUNXI_GPA(27); pin++) { - sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC); + sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC); sunxi_gpio_set_drv(pin, 3); } #elif defined CONFIG_GMII /* Configure sun6i GMII mode pin mux settings */ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(27); pin++) { - sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC); + sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC); sunxi_gpio_set_drv(pin, 2); } #else /* Configure sun6i MII mode pin mux settings */ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(3); pin++) - sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC); + sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC); for (pin = SUNXI_GPA(8); pin <= SUNXI_GPA(9); pin++) - sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC); + sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC); for (pin = SUNXI_GPA(11); pin <= SUNXI_GPA(14); pin++) - sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC); + sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC); for (pin = SUNXI_GPA(19); pin <= SUNXI_GPA(24); pin++) - sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC); + sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC); for (pin = SUNXI_GPA(26); pin <= SUNXI_GPA(27); pin++) - sunxi_gpio_set_cfgpin(pin, SUN6I_GPA0_GMAC); + sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC); #endif -#ifdef CONFIG_RGMII +#ifdef CONFIG_DM_ETH + return 0; +#else +# ifdef CONFIG_RGMII return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_RGMII); -#elif defined CONFIG_GMII +# elif defined CONFIG_GMII return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_GMII); -#else +# else return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_MII); +# endif #endif } diff --git a/board/sysam/amcore/u-boot.lds b/board/sysam/amcore/u-boot.lds deleted file mode 100644 index 2f7a241..0000000 --- a/board/sysam/amcore/u-boot.lds +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Linker script for Sysam AMCORE board - * - * (C) Copyright 2014 Angelo Dureghello <angelo@sysam.it> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -OUTPUT_ARCH(m68k) - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - .text : - { - arch/m68k/cpu/mcf530x/start.o (.text) - - . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text) - - *(.text) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) - } - - /* Read-write section, merged into data segment: */ - . = (. + 0x00FF) & 0xFFFFFF00; - _erotext = .; - PROVIDE (erotext = .); - - .reloc : - { - __got_start = .; - KEEP(*(.got)) - __got_end = .; - _GOT2_TABLE_ = .; - KEEP(*(.got2)) - _FIXUP_TABLE_ = .; - KEEP(*(.fixup)) - } - __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; - __fixup_entries = (. - _FIXUP_TABLE_)>>2; - - .data : - { - *(.data) - *(.sdata) - } - _edata = .; - PROVIDE (edata = .); - - . = .; - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = .; - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(256); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); - __init_end = .; - - __bss_start = .; - .bss (NOLOAD) : - { - _sbss = .; - *(.sbss*) - *(.bss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - } - __bss_end = . ; - PROVIDE (end = .); -} diff --git a/board/tcm-bf518/tcm-bf518.c b/board/tcm-bf518/tcm-bf518.c index 5d25fcd..3fa7d97 100644 --- a/board/tcm-bf518/tcm-bf518.c +++ b/board/tcm-bf518/tcm-bf518.c @@ -39,14 +39,14 @@ static void board_init_enetaddr(uchar *mac_addr) for (ret = 0; ret < 6; ++ret) mac_addr[ret] = otp_mac_p[5 - ret]; - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) valid_mac = true; } #endif if (!valid_mac) { puts("Warning: Generating 'random' MAC address\n"); - eth_random_addr(mac_addr); + net_random_ethaddr(mac_addr); } eth_setenv_enetaddr("ethaddr", mac_addr); diff --git a/board/tcm-bf537/tcm-bf537.c b/board/tcm-bf537/tcm-bf537.c index a4f0f71..2531a44 100644 --- a/board/tcm-bf537/tcm-bf537.c +++ b/board/tcm-bf537/tcm-bf537.c @@ -31,7 +31,7 @@ static void board_init_enetaddr(char *var) return; printf("Warning: %s: generating 'random' MAC address\n", var); - eth_random_addr(enetaddr); + net_random_ethaddr(enetaddr); eth_setenv_enetaddr(var, enetaddr); } diff --git a/board/ti/am335x/Kconfig b/board/ti/am335x/Kconfig index 7cb006f..49b73ab 100644 --- a/board/ti/am335x/Kconfig +++ b/board/ti/am335x/Kconfig @@ -38,13 +38,4 @@ config NOR_BOOT as the ROM only partially sets up pinmux. We also default to using NOR for environment. -config DM - default y - -config DM_GPIO - default y if DM - -config DM_SERIAL - default y if DM - endif diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c index 0739e60..96245a3 100644 --- a/board/ti/am335x/board.c +++ b/board/ti/am335x/board.c @@ -593,7 +593,7 @@ int board_eth_init(bd_t *bis) if (!getenv("ethaddr")) { printf("<ethaddr> not set. Validating first E-fuse MAC\n"); - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("ethaddr", mac_addr); } @@ -609,7 +609,7 @@ int board_eth_init(bd_t *bis) mac_addr[5] = (mac_lo & 0xFF00) >> 8; if (!getenv("eth1addr")) { - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("eth1addr", mac_addr); } @@ -658,7 +658,7 @@ int board_eth_init(bd_t *bis) #endif #if defined(CONFIG_USB_ETHER) && \ (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USBETH_SUPPORT)) - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("usbnet_devaddr", mac_addr); rv = usb_eth_initialize(bis); diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c index ddf4c5f..4aae230 100644 --- a/board/ti/am43xx/board.c +++ b/board/ti/am43xx/board.c @@ -802,7 +802,7 @@ int board_eth_init(bd_t *bis) if (!getenv("ethaddr")) { puts("<ethaddr> not set. Validating first E-fuse MAC\n"); - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("ethaddr", mac_addr); } @@ -816,7 +816,7 @@ int board_eth_init(bd_t *bis) mac_addr[5] = (mac_lo & 0xFF00) >> 8; if (!getenv("eth1addr")) { - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("eth1addr", mac_addr); } diff --git a/board/ti/beagle_x15/board.c b/board/ti/beagle_x15/board.c index 3a7e04d..ffcd531 100644 --- a/board/ti/beagle_x15/board.c +++ b/board/ti/beagle_x15/board.c @@ -356,7 +356,7 @@ int board_eth_init(bd_t *bis) if (!getenv("ethaddr")) { printf("<ethaddr> not set. Validating first E-fuse MAC\n"); - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("ethaddr", mac_addr); } @@ -370,7 +370,7 @@ int board_eth_init(bd_t *bis) mac_addr[5] = mac_lo & 0xFF; if (!getenv("eth1addr")) { - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("eth1addr", mac_addr); } @@ -385,13 +385,3 @@ int board_eth_init(bd_t *bis) return ret; } #endif - -#ifdef CONFIG_USB_XHCI_OMAP -int board_usb_init(int index, enum usb_init_type init) -{ - setbits_le32((*prcm)->cm_l3init_usb_otg_ss_clkctrl, - OTG_SS_CLKCTRL_MODULEMODE_HW | OPTFCLKEN_REFCLK960M); - - return 0; -} -#endif diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c index 3089fa2..d464855 100644 --- a/board/ti/dra7xx/evm.c +++ b/board/ti/dra7xx/evm.c @@ -93,10 +93,16 @@ int board_init(void) int board_late_init(void) { #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + u32 id[4]; + if (omap_revision() == DRA722_ES1_0) setenv("board_name", "dra72x"); else setenv("board_name", "dra7xx"); + + id[0] = readl((*ctrl)->control_std_fuse_die_id_0); + id[1] = readl((*ctrl)->control_std_fuse_die_id_1); + usb_set_serial_num_from_die_id(id); #endif return 0; } @@ -341,7 +347,7 @@ int board_eth_init(bd_t *bis) if (!getenv("ethaddr")) { printf("<ethaddr> not set. Validating first E-fuse MAC\n"); - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("ethaddr", mac_addr); } @@ -355,7 +361,7 @@ int board_eth_init(bd_t *bis) mac_addr[5] = mac_lo & 0xFF; if (!getenv("eth1addr")) { - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("eth1addr", mac_addr); } diff --git a/board/ti/ti814x/evm.c b/board/ti/ti814x/evm.c index 54b3dfb..e406dab 100644 --- a/board/ti/ti814x/evm.c +++ b/board/ti/ti814x/evm.c @@ -178,7 +178,7 @@ int board_eth_init(bd_t *bis) mac_addr[4] = mac_lo & 0xFF; mac_addr[5] = (mac_lo & 0xFF00) >> 8; - if (is_valid_ether_addr(mac_addr)) + if (is_valid_ethaddr(mac_addr)) eth_setenv_enetaddr("ethaddr", mac_addr); else printf("Unable to read MAC address. Set <ethaddr>\n"); diff --git a/board/toradex/colibri_vf/Kconfig b/board/toradex/colibri_vf/Kconfig new file mode 100644 index 0000000..2c3cb30 --- /dev/null +++ b/board/toradex/colibri_vf/Kconfig @@ -0,0 +1,18 @@ +if TARGET_COLIBRI_VF + +config SYS_CPU + default "armv7" + +config SYS_BOARD + default "colibri_vf" + +config SYS_VENDOR + default "toradex" + +config SYS_SOC + default "vf610" + +config SYS_CONFIG_NAME + default "colibri_vf" + +endif diff --git a/board/toradex/colibri_vf/MAINTAINERS b/board/toradex/colibri_vf/MAINTAINERS new file mode 100644 index 0000000..551c575 --- /dev/null +++ b/board/toradex/colibri_vf/MAINTAINERS @@ -0,0 +1,6 @@ +Colibri VFxx +M: Stefan Agner <stefan.agner@toradex.com> +S: Maintained +F: board/toradex/colibri_vf/ +F: include/configs/colibri_vf.h +F: configs/colibri_vf_defconfig diff --git a/board/toradex/colibri_vf/Makefile b/board/toradex/colibri_vf/Makefile new file mode 100644 index 0000000..c7e5134 --- /dev/null +++ b/board/toradex/colibri_vf/Makefile @@ -0,0 +1,7 @@ +# +# Copyright 2013 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := colibri_vf.o diff --git a/board/toradex/colibri_vf/colibri_vf.c b/board/toradex/colibri_vf/colibri_vf.c new file mode 100644 index 0000000..31ebb19 --- /dev/null +++ b/board/toradex/colibri_vf/colibri_vf.c @@ -0,0 +1,385 @@ +/* + * Copyright 2015 Toradex, Inc. + * + * Based on vf610twr.c: + * Copyright 2013 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/iomux-vf610.h> +#include <asm/arch/ddrmc-vf610.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/clock.h> +#include <mmc.h> +#include <fsl_esdhc.h> +#include <miiphy.h> +#include <netdev.h> +#include <i2c.h> +#include <g_dnl.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_25ohm | PAD_CTL_OBE_IBE_ENABLE) + +#define ESDHC_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_HIGH | \ + PAD_CTL_DSE_20ohm | PAD_CTL_OBE_IBE_ENABLE) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \ + PAD_CTL_DSE_50ohm | PAD_CTL_OBE_IBE_ENABLE) + +int dram_init(void) +{ + static const struct ddr3_jedec_timings timings = { + .tinit = 5, + .trst_pwron = 80000, + .cke_inactive = 200000, + .wrlat = 5, + .caslat_lin = 12, + .trc = 21, + .trrd = 4, + .tccd = 4, + .tfaw = 20, + .trp = 6, + .twtr = 4, + .tras_min = 15, + .tmrd = 4, + .trtp = 4, + .tras_max = 28080, + .tmod = 12, + .tckesr = 4, + .tcke = 3, + .trcd_int = 6, + .tdal = 12, + .tdll = 512, + .trp_ab = 6, + .tref = 3120, + .trfc = 64, + .tpdex = 3, + .txpdll = 10, + .txsnr = 48, + .txsr = 468, + .cksrx = 5, + .cksre = 5, + .zqcl = 256, + .zqinit = 512, + .zqcs = 64, + .ref_per_zq = 64, + .aprebit = 10, + .wlmrd = 40, + .wldqsen = 25, + }; + + ddrmc_setup_iomux(); + + ddrmc_ctrl_init_ddr3(&timings, NULL, 1, 2); + gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + + return 0; +} + +static void setup_iomux_uart(void) +{ + static const iomux_v3_cfg_t uart_pads[] = { + NEW_PAD_CTRL(VF610_PAD_PTB4__UART1_TX, UART_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTB5__UART1_RX, UART_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTB10__UART0_TX, UART_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTB11__UART0_RX, UART_PAD_CTRL), + }; + + imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); +} + +static void setup_iomux_enet(void) +{ + static const iomux_v3_cfg_t enet0_pads[] = { + NEW_PAD_CTRL(VF610_PAD_PTA6__RMII0_CLKOUT, ENET_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTC10__RMII1_MDIO, ENET_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTC9__RMII1_MDC, ENET_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTC11__RMII1_CRS_DV, ENET_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTC12__RMII1_RD1, ENET_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTC13__RMII1_RD0, ENET_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTC14__RMII1_RXER, ENET_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTC15__RMII1_TD1, ENET_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTC16__RMII1_TD0, ENET_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTC17__RMII1_TXEN, ENET_PAD_CTRL), + }; + + imx_iomux_v3_setup_multiple_pads(enet0_pads, ARRAY_SIZE(enet0_pads)); +} + +static void setup_iomux_i2c(void) +{ + static const iomux_v3_cfg_t i2c0_pads[] = { + VF610_PAD_PTB14__I2C0_SCL, + VF610_PAD_PTB15__I2C0_SDA, + }; + + imx_iomux_v3_setup_multiple_pads(i2c0_pads, ARRAY_SIZE(i2c0_pads)); +} + +#ifdef CONFIG_NAND_VF610_NFC +static void setup_iomux_nfc(void) +{ + static const iomux_v3_cfg_t nfc_pads[] = { + VF610_PAD_PTD23__NF_IO7, + VF610_PAD_PTD22__NF_IO6, + VF610_PAD_PTD21__NF_IO5, + VF610_PAD_PTD20__NF_IO4, + VF610_PAD_PTD19__NF_IO3, + VF610_PAD_PTD18__NF_IO2, + VF610_PAD_PTD17__NF_IO1, + VF610_PAD_PTD16__NF_IO0, + VF610_PAD_PTB24__NF_WE_B, + VF610_PAD_PTB25__NF_CE0_B, + VF610_PAD_PTB27__NF_RE_B, + VF610_PAD_PTC26__NF_RB_B, + VF610_PAD_PTC27__NF_ALE, + VF610_PAD_PTC28__NF_CLE + }; + + imx_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads)); +} +#endif + +#ifdef CONFIG_FSL_ESDHC +struct fsl_esdhc_cfg esdhc_cfg[1] = { + {ESDHC1_BASE_ADDR}, +}; + +int board_mmc_getcd(struct mmc *mmc) +{ + /* eSDHC1 is always present */ + return 1; +} + +int board_mmc_init(bd_t *bis) +{ + static const iomux_v3_cfg_t esdhc1_pads[] = { + NEW_PAD_CTRL(VF610_PAD_PTA24__ESDHC1_CLK, ESDHC_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTA25__ESDHC1_CMD, ESDHC_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTA26__ESDHC1_DAT0, ESDHC_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTA27__ESDHC1_DAT1, ESDHC_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTA28__ESDHC1_DAT2, ESDHC_PAD_CTRL), + NEW_PAD_CTRL(VF610_PAD_PTA29__ESDHC1_DAT3, ESDHC_PAD_CTRL), + }; + + esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + + imx_iomux_v3_setup_multiple_pads( + esdhc1_pads, ARRAY_SIZE(esdhc1_pads)); + + return fsl_esdhc_initialize(bis, &esdhc_cfg[0]); +} +#endif + +static inline int is_colibri_vf61(void) +{ + struct mscm *mscm = (struct mscm *)MSCM_BASE_ADDR; + + /* + * Detect board type by Level 2 Cache: VF50 don't have any + * Level 2 Cache. + */ + return !!mscm->cpxcfg1; +} + +static void clock_init(void) +{ + struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR; + struct anadig_reg *anadig = (struct anadig_reg *)ANADIG_BASE_ADDR; + u32 pfd_clk_sel, ddr_clk_sel; + + clrsetbits_le32(&ccm->ccgr0, CCM_REG_CTRL_MASK, + CCM_CCGR0_UART0_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr1, CCM_REG_CTRL_MASK, + CCM_CCGR1_PIT_CTRL_MASK | CCM_CCGR1_WDOGA5_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr2, CCM_REG_CTRL_MASK, + CCM_CCGR2_IOMUXC_CTRL_MASK | CCM_CCGR2_PORTA_CTRL_MASK | + CCM_CCGR2_PORTB_CTRL_MASK | CCM_CCGR2_PORTC_CTRL_MASK | + CCM_CCGR2_PORTD_CTRL_MASK | CCM_CCGR2_PORTE_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr3, CCM_REG_CTRL_MASK, + CCM_CCGR3_ANADIG_CTRL_MASK | CCM_CCGR3_SCSC_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr4, CCM_REG_CTRL_MASK, + CCM_CCGR4_WKUP_CTRL_MASK | CCM_CCGR4_CCM_CTRL_MASK | + CCM_CCGR4_GPC_CTRL_MASK | CCM_CCGR4_I2C0_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr6, CCM_REG_CTRL_MASK, + CCM_CCGR6_OCOTP_CTRL_MASK | CCM_CCGR6_DDRMC_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr7, CCM_REG_CTRL_MASK, + CCM_CCGR7_SDHC1_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr9, CCM_REG_CTRL_MASK, + CCM_CCGR9_FEC0_CTRL_MASK | CCM_CCGR9_FEC1_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr10, CCM_REG_CTRL_MASK, + CCM_CCGR10_NFC_CTRL_MASK); + +#ifdef CONFIG_CI_UDC + setbits_le32(&ccm->ccgr1, CCM_CCGR1_USBC0_CTRL_MASK); +#endif + +#ifdef CONFIG_USB_EHCI + setbits_le32(&ccm->ccgr7, CCM_CCGR7_USBC1_CTRL_MASK); +#endif + + clrsetbits_le32(&anadig->pll5_ctrl, ANADIG_PLL5_CTRL_BYPASS | + ANADIG_PLL5_CTRL_POWERDOWN, ANADIG_PLL5_CTRL_ENABLE | + ANADIG_PLL5_CTRL_DIV_SELECT); + + if (is_colibri_vf61()) { + clrsetbits_le32(&anadig->pll2_ctrl, ANADIG_PLL5_CTRL_BYPASS | + ANADIG_PLL2_CTRL_POWERDOWN, + ANADIG_PLL2_CTRL_ENABLE | + ANADIG_PLL2_CTRL_DIV_SELECT); + } + + clrsetbits_le32(&anadig->pll1_ctrl, ANADIG_PLL1_CTRL_POWERDOWN, + ANADIG_PLL1_CTRL_ENABLE | ANADIG_PLL1_CTRL_DIV_SELECT); + + clrsetbits_le32(&ccm->ccr, CCM_CCR_OSCNT_MASK, + CCM_CCR_FIRC_EN | CCM_CCR_OSCNT(5)); + + /* See "Typical PLL Configuration" */ + if (is_colibri_vf61()) { + pfd_clk_sel = CCM_CCSR_PLL1_PFD_CLK_SEL(1); + ddr_clk_sel = CCM_CCSR_DDRC_CLK_SEL(0); + } else { + pfd_clk_sel = CCM_CCSR_PLL1_PFD_CLK_SEL(3); + ddr_clk_sel = CCM_CCSR_DDRC_CLK_SEL(1); + } + + clrsetbits_le32(&ccm->ccsr, CCM_REG_CTRL_MASK, pfd_clk_sel | + CCM_CCSR_PLL2_PFD4_EN | CCM_CCSR_PLL2_PFD3_EN | + CCM_CCSR_PLL2_PFD2_EN | CCM_CCSR_PLL2_PFD1_EN | + CCM_CCSR_PLL1_PFD4_EN | CCM_CCSR_PLL1_PFD3_EN | + CCM_CCSR_PLL1_PFD2_EN | CCM_CCSR_PLL1_PFD1_EN | + ddr_clk_sel | CCM_CCSR_FAST_CLK_SEL(1) | + CCM_CCSR_SYS_CLK_SEL(4)); + + clrsetbits_le32(&ccm->cacrr, CCM_REG_CTRL_MASK, + CCM_CACRR_IPG_CLK_DIV(1) | CCM_CACRR_BUS_CLK_DIV(2) | + CCM_CACRR_ARM_CLK_DIV(0)); + clrsetbits_le32(&ccm->cscmr1, CCM_REG_CTRL_MASK, + CCM_CSCMR1_ESDHC1_CLK_SEL(3) | + CCM_CSCMR1_NFC_CLK_SEL(0)); + clrsetbits_le32(&ccm->cscdr1, CCM_REG_CTRL_MASK, + CCM_CSCDR1_RMII_CLK_EN); + clrsetbits_le32(&ccm->cscdr2, CCM_REG_CTRL_MASK, + CCM_CSCDR2_ESDHC1_EN | CCM_CSCDR2_ESDHC1_CLK_DIV(0) | + CCM_CSCDR2_NFC_EN); + clrsetbits_le32(&ccm->cscdr3, CCM_REG_CTRL_MASK, + CCM_CSCDR3_NFC_PRE_DIV(5)); + clrsetbits_le32(&ccm->cscmr2, CCM_REG_CTRL_MASK, + CCM_CSCMR2_RMII_CLK_SEL(2)); +} + +static void mscm_init(void) +{ + struct mscm_ir *mscmir = (struct mscm_ir *)MSCM_IR_BASE_ADDR; + int i; + + for (i = 0; i < MSCM_IRSPRC_NUM; i++) + writew(MSCM_IRSPRC_CP0_EN, &mscmir->irsprc[i]); +} + +int board_phy_config(struct phy_device *phydev) +{ + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} + +int board_early_init_f(void) +{ + clock_init(); + mscm_init(); + + setup_iomux_uart(); + setup_iomux_enet(); + setup_iomux_i2c(); +#ifdef CONFIG_NAND_VF610_NFC + setup_iomux_nfc(); +#endif + + return 0; +} + +#ifdef CONFIG_BOARD_LATE_INIT +int board_late_init(void) +{ + struct src *src = (struct src *)SRC_BASE_ADDR; + + /* Default memory arguments */ + if (!getenv("memargs")) { + switch (gd->ram_size) { + case 0x08000000: + /* 128 MB */ + setenv("memargs", "mem=128M"); + break; + case 0x10000000: + /* 256 MB */ + setenv("memargs", "mem=256M"); + break; + default: + printf("Failed detecting RAM size.\n"); + } + } + + if (((src->sbmr2 & SRC_SBMR2_BMOD_MASK) >> SRC_SBMR2_BMOD_SHIFT) + == SRC_SBMR2_BMOD_SERIAL) { + printf("Serial Downloader recovery mode, disable autoboot\n"); + setenv("bootdelay", "-1"); + } + + return 0; +} +#endif /* CONFIG_BOARD_LATE_INIT */ + +int board_init(void) +{ + struct scsc_reg *scsc = (struct scsc_reg *)SCSC_BASE_ADDR; + + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + + /* + * Enable external 32K Oscillator + * + * The internal clock experiences significant drift + * so we must use the external oscillator in order + * to maintain correct time in the hwclock + */ + + setbits_le32(&scsc->sosc_ctr, SCSC_SOSC_CTR_SOSC_EN); + + return 0; +} + +int checkboard(void) +{ + if (is_colibri_vf61()) + puts("Board: Colibri VF61\n"); + else + puts("Board: Colibri VF50\n"); + + return 0; +} + +int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name) +{ + unsigned short usb_pid; + + put_unaligned(CONFIG_TRDX_VID, &dev->idVendor); + + if (is_colibri_vf61()) + usb_pid = CONFIG_TRDX_PID_COLIBRI_VF61IT; + else + usb_pid = CONFIG_TRDX_PID_COLIBRI_VF50IT; + + put_unaligned(usb_pid, &dev->idProduct); + + return 0; +} diff --git a/board/toradex/colibri_vf/imximage.cfg b/board/toradex/colibri_vf/imximage.cfg new file mode 100644 index 0000000..8c52886 --- /dev/null +++ b/board/toradex/colibri_vf/imximage.cfg @@ -0,0 +1,17 @@ +/* + * Copyright 2014 Toradex, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Refer docs/README.imxmage for more details about how-to configure + * and create imximage boot image + * + * The syntax is taken as close as possible with the kwbimage + */ +#include <asm/imx-common/imximage.cfg> + +/* image version */ +IMAGE_VERSION 2 + +/* Boot Offset 0x400, valid for both SD and NAND boot */ +BOOT_OFFSET FLASH_OFFSET_STANDARD diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index 3110405..375cd0b 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -109,7 +109,7 @@ int board_eth_init(bd_t *bis) XILINX_AXIDMA_BASEADDR); #endif -#ifdef CONFIG_XILINX_EMACLITE +#if defined(CONFIG_XILINX_EMACLITE) && defined(XILINX_EMACLITE_BASEADDR) u32 txpp = 0; u32 rxpp = 0; # ifdef CONFIG_XILINX_EMACLITE_TX_PING_PONG diff --git a/board/xilinx/zynq/.gitignore b/board/xilinx/zynq/.gitignore index 7c36bc9..c455361 100644 --- a/board/xilinx/zynq/.gitignore +++ b/board/xilinx/zynq/.gitignore @@ -1,2 +1 @@ -ps7_init.[ch] ps7_init_gpl.[ch] diff --git a/board/xilinx/zynq/Makefile b/board/xilinx/zynq/Makefile index 3b1eb4f..054c3d8 100644 --- a/board/xilinx/zynq/Makefile +++ b/board/xilinx/zynq/Makefile @@ -9,9 +9,7 @@ obj-y := board.o # Please copy ps7_init_gpl.c/h from hw project to this directory obj-$(CONFIG_SPL_BUILD) += \ - $(if $(wildcard $(srctree)/$(src)/ps7_init_gpl.c), ps7_init_gpl.o, \ - $(if $(wildcard $(srctree)/$(src)/ps7_init.c), ps7_init.o legacy.o)) + $(if $(wildcard $(srctree)/$(src)/ps7_init_gpl.c), ps7_init_gpl.o) # Suppress "warning: function declaration isn't a prototype" CFLAGS_REMOVE_ps7_init_gpl.o := -Wstrict-prototypes -CFLAGS_REMOVE_ps7_init.o := -Wstrict-prototypes diff --git a/board/xilinx/zynq/legacy.c b/board/xilinx/zynq/legacy.c deleted file mode 100644 index 4ae913e..0000000 --- a/board/xilinx/zynq/legacy.c +++ /dev/null @@ -1,2 +0,0 @@ - -#warning usage of ps7_init files is deprecated please use ps7_init_gpl diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 1325bca..f5ff64d 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -56,14 +56,18 @@ int board_mmc_init(bd_t *bd) { int ret = 0; + u32 ver = zynqmp_get_silicon_version(); + + if (ver != ZYNQMP_CSU_VERSION_VELOCE) { #if defined(CONFIG_ZYNQ_SDHCI) # if defined(CONFIG_ZYNQ_SDHCI0) - ret = zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR0); + ret = zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR0); # endif # if defined(CONFIG_ZYNQ_SDHCI1) - ret |= zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR1); + ret |= zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR1); # endif #endif + } return ret; } @@ -79,6 +83,7 @@ int board_late_init(void) switch (bootmode) { case SD_MODE: + case EMMC_MODE: setenv("modeboot", "sdboot"); break; default: diff --git a/common/Kconfig b/common/Kconfig index 4cde4b0..5d7e48a 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -300,11 +300,6 @@ config CMD_DNS help Lookup the IP of a hostname -config CMD_DNS - bool "dns" - help - Lookup the IP of a hostname - config CMD_LINK_LOCAL bool "linklocal" help @@ -339,6 +334,122 @@ config CMD_SETGETDCR getidcr - Get a register value via indirect DCR addressing setidcr - Set a register value via indirect DCR addressing +config CMD_SOUND + bool "sound" + depends on SOUND + help + This provides basic access to the U-Boot's sound support. The main + feature is to play a beep. + + sound init - set up sound system + sound play - play a sound + +endmenu + +menu "Boot timing" + +config BOOTSTAGE + bool "Boot timing and reporting" + help + Enable recording of boot time while booting. To use it, insert + calls to bootstage_mark() with a suitable BOOTSTAGE_ID from + bootstage.h. Only a single entry is recorded for each ID. You can + give the entry a name with bootstage_mark_name(). You can also + record elapsed time in a particular stage using bootstage_start() + before starting and bootstage_accum() when finished. Bootstage will + add up all the accumated time and report it. + + Normally, IDs are defined in bootstage.h but a small number of + additional 'user' IDs can be used but passing BOOTSTAGE_ID_ALLOC + as the ID. + + Calls to show_boot_progress() wil also result in log entries but + these will not have names. + +config BOOTSTAGE_REPORT + bool "Display a detailed boot timing report before booting the OS" + depends on BOOTSTAGE + help + Enable output of a boot time report just before the OS is booted. + This shows how long it took U-Boot to go through each stage of the + boot process. The report looks something like this: + + Timer summary in microseconds: + Mark Elapsed Stage + 0 0 reset + 3,575,678 3,575,678 board_init_f start + 3,575,695 17 arch_cpu_init A9 + 3,575,777 82 arch_cpu_init done + 3,659,598 83,821 board_init_r start + 3,910,375 250,777 main_loop + 29,916,167 26,005,792 bootm_start + 30,361,327 445,160 start_kernel + +config BOOTSTAGE_USER_COUNT + hex "Number of boot ID numbers available for user use" + default 20 + help + This is the number of available user bootstage records. + Each time you call bootstage_mark(BOOTSTAGE_ID_ALLOC, ...) + a new ID will be allocated from this stash. If you exceed + the limit, recording will stop. + +config CMD_BOOTSTAGE + bool "Enable the 'bootstage' command" + depends on BOOTSTAGE + help + Add a 'bootstage' command which supports printing a report + and un/stashing of bootstage data. + +config BOOTSTAGE_FDT + bool "Store boot timing information in the OS device tree" + depends on BOOTSTAGE + help + Stash the bootstage information in the FDT. A root 'bootstage' + node is created with each bootstage id as a child. Each child + has a 'name' property and either 'mark' containing the + mark time in microsecond, or 'accum' containing the + accumulated time for that bootstage id in microseconds. + For example: + + bootstage { + 154 { + name = "board_init_f"; + mark = <3575678>; + }; + 170 { + name = "lcd"; + accum = <33482>; + }; + }; + + Code in the Linux kernel can find this in /proc/devicetree. + +config BOOTSTAGE_STASH + bool "Stash the boot timing information in memory before booting OS" + depends on BOOTSTAGE + help + Some OSes do not support device tree. Bootstage can instead write + the boot timing information in a binary format at a given address. + This happens through a call to bootstage_stash(), typically in + the CPU's cleanup_before_linux() function. You can use the + 'bootstage stash' and 'bootstage unstash' commands to do this on + the command line. + +config BOOTSTAGE_STASH_ADDR + hex "Address to stash boot timing information" + default 0 + help + Provide an address which will not be overwritten by the OS when it + starts, so that it can read this information when ready. + +config BOOTSTAGE_STASH_SIZE + hex "Size of boot timing stash region" + default 4096 + help + This should be large enough to hold the bootstage stash. A value of + 4096 (4KiB) is normally plenty. + endmenu endmenu diff --git a/common/Makefile b/common/Makefile index 252fbf1..fba3830 100644 --- a/common/Makefile +++ b/common/Makefile @@ -152,7 +152,7 @@ obj-$(CONFIG_CMD_PXE) += cmd_pxe.o obj-$(CONFIG_CMD_READ) += cmd_read.o obj-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o obj-$(CONFIG_CMD_REISER) += cmd_reiser.o -obj-$(CONFIG_SANDBOX) += cmd_sandbox.o +obj-$(CONFIG_SANDBOX) += cmd_host.o obj-$(CONFIG_CMD_SATA) += cmd_sata.o obj-$(CONFIG_CMD_SF) += cmd_sf.o obj-$(CONFIG_CMD_SCSI) += cmd_scsi.o @@ -201,6 +201,7 @@ obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-y += splash.o obj-$(CONFIG_SPLASH_SOURCE) += splash_source.o obj-$(CONFIG_LCD) += lcd.o lcd_console.o +obj-$(CONFIG_LCD_ROTATION) += lcd_console_rotation.o obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o obj-$(CONFIG_LYNXKDI) += lynxkdi.o obj-$(CONFIG_MENU) += menu.o diff --git a/common/board_f.c b/common/board_f.c index cb956b8..322e070 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -23,6 +23,8 @@ #include <i2c.h> #include <initcall.h> #include <logbuff.h> +#include <malloc.h> +#include <mapmem.h> /* TODO: Can we move these into arch/ headers? */ #ifdef CONFIG_8xx @@ -281,49 +283,6 @@ __weak int arch_cpu_init(void) return 0; } -#ifdef CONFIG_OF_HOSTFILE - -static int read_fdt_from_file(void) -{ - struct sandbox_state *state = state_get_current(); - const char *fname = state->fdt_fname; - void *blob; - loff_t size; - int err; - int fd; - - blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); - if (!state->fdt_fname) { - err = fdt_create_empty_tree(blob, 256); - if (!err) - goto done; - printf("Unable to create empty FDT: %s\n", fdt_strerror(err)); - return -EINVAL; - } - - err = os_get_filesize(fname, &size); - if (err < 0) { - printf("Failed to file FDT file '%s'\n", fname); - return err; - } - fd = os_open(fname, OS_O_RDONLY); - if (fd < 0) { - printf("Failed to open FDT file '%s'\n", fname); - return -EACCES; - } - if (os_read(fd, blob, size) != size) { - os_close(fd); - return -EIO; - } - os_close(fd); - -done: - gd->fdt_blob = blob; - - return 0; -} -#endif - #ifdef CONFIG_SANDBOX static int setup_ram_buf(void) { @@ -336,28 +295,6 @@ static int setup_ram_buf(void) } #endif -static int setup_fdt(void) -{ -#ifdef CONFIG_OF_CONTROL -# ifdef CONFIG_OF_EMBED - /* Get a pointer to the FDT */ - gd->fdt_blob = __dtb_dt_begin; -# elif defined CONFIG_OF_SEPARATE - /* FDT is at end of image */ - gd->fdt_blob = (ulong *)&_end; -# elif defined(CONFIG_OF_HOSTFILE) - if (read_fdt_from_file()) { - puts("Failed to read control FDT\n"); - return -1; - } -# endif - /* Allow the early environment to override the fdt address */ - gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, - (uintptr_t)gd->fdt_blob); -#endif - return 0; -} - /* Get the top of usable RAM */ __weak ulong board_get_usable_ram_top(ulong total_size) { @@ -785,17 +722,6 @@ static int mark_bootstage(void) return 0; } -static int initf_malloc(void) -{ -#ifdef CONFIG_SYS_MALLOC_F_LEN - assert(gd->malloc_base); /* Set up by crt0.S */ - gd->malloc_limit = gd->malloc_base + CONFIG_SYS_MALLOC_F_LEN; - gd->malloc_ptr = 0; -#endif - - return 0; -} - static int initf_dm(void) { #if defined(CONFIG_DM) && defined(CONFIG_SYS_MALLOC_F_LEN) @@ -815,12 +741,19 @@ __weak int reserve_arch(void) return 0; } +__weak int arch_cpu_init_dm(void) +{ + return 0; +} + static init_fnc_t init_sequence_f[] = { #ifdef CONFIG_SANDBOX setup_ram_buf, #endif setup_mon_len, - setup_fdt, +#ifdef CONFIG_OF_CONTROL + fdtdec_setup, +#endif #ifdef CONFIG_TRACE trace_early_init, #endif @@ -831,10 +764,8 @@ static init_fnc_t init_sequence_f[] = { #endif arch_cpu_init, /* basic arch cpu dependent setup */ mark_bootstage, -#ifdef CONFIG_OF_CONTROL - fdtdec_check_fdt, -#endif initf_dm, + arch_cpu_init_dm, #if defined(CONFIG_BOARD_EARLY_INIT_F) board_early_init_f, #endif diff --git a/common/board_r.c b/common/board_r.c index 0335f6b..307124e 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -33,6 +33,7 @@ #endif #include <logbuff.h> #include <malloc.h> +#include <mapmem.h> #ifdef CONFIG_BITBANGMII #include <miiphy.h> #endif @@ -230,7 +231,9 @@ static int initr_unlock_ram_in_cache(void) #ifdef CONFIG_PCI static int initr_pci(void) { +#ifndef CONFIG_DM_PCI pci_init(); +#endif return 0; } @@ -587,7 +590,7 @@ static int initr_bbmii(void) static int initr_net(void) { puts("Net: "); - eth_initialize(gd->bd); + eth_initialize(); #if defined(CONFIG_RESET_PHY_R) debug("Reset Ethernet PHY\n"); reset_phy(); @@ -699,6 +702,12 @@ init_fnc_t init_sequence_r[] = { /* TODO: could x86/PPC have this also perhaps? */ #ifdef CONFIG_ARM initr_caches, + /* Note: For Freescale LS2 SoCs, new MMU table is created in DDR. + * A temporary mapping of IFC high region is since removed, + * so environmental variables in NOR flash is not availble + * until board_init() is called below to remap IFC to high + * region. + */ #endif initr_reloc_global_data, #if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500) @@ -777,9 +786,6 @@ init_fnc_t init_sequence_r[] = { #ifdef CONFIG_PPC initr_spi, #endif -#if defined(CONFIG_X86) && defined(CONFIG_SPI) - init_func_spi, -#endif #ifdef CONFIG_CMD_NAND initr_nand, #endif diff --git a/common/bootm.c b/common/bootm.c index 34f60bb..6842029 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -13,6 +13,7 @@ #include <fdt_support.h> #include <lmb.h> #include <malloc.h> +#include <mapmem.h> #include <asm/io.h> #include <linux/lzo.h> #include <lzma/LzmaTypes.h> diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index aa81da2..f16d5c7 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -34,6 +34,7 @@ static void print_eth(int idx) printf("%-12s= %s\n", name, val); } +#ifndef CONFIG_DM_ETH __maybe_unused static void print_eths(void) { @@ -52,6 +53,7 @@ static void print_eths(void) printf("current eth = %s\n", eth_get_name()); printf("ip_addr = %s\n", getenv("ipaddr")); } +#endif __maybe_unused static void print_lnum(const char *name, unsigned long long value) @@ -375,7 +377,7 @@ static int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, print_num("-> size", bd->bi_dram[i].size); } -#if defined(CONFIG_CMD_NET) +#if defined(CONFIG_CMD_NET) && !defined(CONFIG_DM_ETH) print_eths(); #endif printf("baudrate = %u bps\n", gd->baudrate); diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 4f77f22..6b6aca6 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -16,6 +16,7 @@ #include <image.h> #include <lmb.h> #include <malloc.h> +#include <mapmem.h> #include <nand.h> #include <asm/byteorder.h> #include <linux/compiler.h> diff --git a/common/cmd_bootstage.c b/common/cmd_bootstage.c index 106894a..788ab16 100644 --- a/common/cmd_bootstage.c +++ b/common/cmd_bootstage.c @@ -6,11 +6,6 @@ #include <common.h> -#ifndef CONFIG_BOOTSTAGE_STASH -#define CONFIG_BOOTSTAGE_STASH -1UL -#define CONFIG_BOOTSTAGE_STASH_SIZE -1 -#endif - static int do_bootstage_report(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -24,7 +19,7 @@ static int get_base_size(int argc, char * const argv[], ulong *basep, { char *endp; - *basep = CONFIG_BOOTSTAGE_STASH; + *basep = CONFIG_BOOTSTAGE_STASH_ADDR; *sizep = CONFIG_BOOTSTAGE_STASH_SIZE; if (argc < 2) return 0; diff --git a/common/cmd_date.c b/common/cmd_date.c index e349166..4a653e5 100644 --- a/common/cmd_date.c +++ b/common/cmd_date.c @@ -27,6 +27,8 @@ static const char * const weekdays[] = { int mk_date (const char *, struct rtc_time *); +static struct rtc_time default_tm = { 0, 0, 0, 1, 1, 2000, 6, 0, 0 }; + static int do_date(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct rtc_time tm; @@ -47,6 +49,9 @@ static int do_date(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (strcmp(argv[1],"reset") == 0) { puts ("Reset RTC...\n"); rtc_reset (); + rcode = rtc_set(&default_tm); + if (rcode) + puts("## Failed to set date after RTC reset\n"); } else { /* initialize tm with current time */ rcode = rtc_get (&tm); diff --git a/common/cmd_demo.c b/common/cmd_demo.c index 8a10bdf..209dc4a 100644 --- a/common/cmd_demo.c +++ b/common/cmd_demo.c @@ -9,6 +9,7 @@ #include <common.h> #include <dm-demo.h> +#include <mapmem.h> #include <asm/io.h> struct udevice *demo_dev; diff --git a/common/cmd_elf.c b/common/cmd_elf.c index c745371..22475dc 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -170,7 +170,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * Check to see if we need to tftp the image ourselves before starting */ if ((argc == 2) && (strcmp(argv[1], "tftp") == 0)) { - if (NetLoop(TFTPGET) <= 0) + if (net_loop(TFTPGET) <= 0) return 1; printf("Automatic boot of VxWorks image at address 0x%08lx ...\n", addr); diff --git a/common/cmd_fat.c b/common/cmd_fat.c index c00fb28..aae993d 100644 --- a/common/cmd_fat.c +++ b/common/cmd_fat.c @@ -14,6 +14,7 @@ #include <net.h> #include <ata.h> #include <asm/io.h> +#include <mapmem.h> #include <part.h> #include <fat.h> #include <fs.h> diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 48b3e70..682b655 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -15,6 +15,7 @@ #include <asm/global_data.h> #include <libfdt.h> #include <fdt_support.h> +#include <mapmem.h> #include <asm/io.h> #define MAX_LEVEL 32 /* how deeply nested we will go */ diff --git a/common/cmd_host.c b/common/cmd_host.c new file mode 100644 index 0000000..ba1460e --- /dev/null +++ b/common/cmd_host.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2012, Google Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <fs.h> +#include <part.h> +#include <sandboxblockdev.h> +#include <asm/errno.h> + +static int host_curr_device = -1; + +static int do_host_load(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return do_load(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX); +} + +static int do_host_ls(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX); +} + +static int do_host_save(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX); +} + +static int do_host_bind(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + if (argc < 2 || argc > 3) + return CMD_RET_USAGE; + char *ep; + char *dev_str = argv[1]; + char *file = argc >= 3 ? argv[2] : NULL; + int dev = simple_strtoul(dev_str, &ep, 16); + if (*ep) { + printf("** Bad device specification %s **\n", dev_str); + return CMD_RET_USAGE; + } + return host_dev_bind(dev, file); +} + +static int do_host_info(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + if (argc < 1 || argc > 2) + return CMD_RET_USAGE; + int min_dev = 0; + int max_dev = CONFIG_HOST_MAX_DEVICES - 1; + if (argc >= 2) { + char *ep; + char *dev_str = argv[1]; + int dev = simple_strtoul(dev_str, &ep, 16); + if (*ep) { + printf("** Bad device specification %s **\n", dev_str); + return CMD_RET_USAGE; + } + min_dev = dev; + max_dev = dev; + } + int dev; + printf("%3s %12s %s\n", "dev", "blocks", "path"); + for (dev = min_dev; dev <= max_dev; dev++) { + block_dev_desc_t *blk_dev; + int ret; + + printf("%3d ", dev); + ret = host_get_dev_err(dev, &blk_dev); + if (ret) { + if (ret == -ENOENT) + puts("Not bound to a backing file\n"); + else if (ret == -ENODEV) + puts("Invalid host device number\n"); + + continue; + } + struct host_block_dev *host_dev = blk_dev->priv; + printf("%12lu %s\n", (unsigned long)blk_dev->lba, + host_dev->filename); + } + return 0; +} + +static int do_host_dev(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + int dev; + char *ep; + block_dev_desc_t *blk_dev; + int ret; + + if (argc < 1 || argc > 3) + return CMD_RET_USAGE; + + if (argc == 1) { + if (host_curr_device < 0) { + printf("No current host device\n"); + return 1; + } + printf("Current host device %d\n", host_curr_device); + return 0; + } + + dev = simple_strtoul(argv[1], &ep, 16); + if (*ep) { + printf("** Bad device specification %s **\n", argv[2]); + return CMD_RET_USAGE; + } + + ret = host_get_dev_err(dev, &blk_dev); + if (ret) { + if (ret == -ENOENT) + puts("Not bound to a backing file\n"); + else if (ret == -ENODEV) + puts("Invalid host device number\n"); + + return 1; + } + + host_curr_device = dev; + return 0; +} + +static cmd_tbl_t cmd_host_sub[] = { + U_BOOT_CMD_MKENT(load, 7, 0, do_host_load, "", ""), + U_BOOT_CMD_MKENT(ls, 3, 0, do_host_ls, "", ""), + U_BOOT_CMD_MKENT(save, 6, 0, do_host_save, "", ""), + U_BOOT_CMD_MKENT(bind, 3, 0, do_host_bind, "", ""), + U_BOOT_CMD_MKENT(info, 3, 0, do_host_info, "", ""), + U_BOOT_CMD_MKENT(dev, 0, 1, do_host_dev, "", ""), +}; + +static int do_host(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + cmd_tbl_t *c; + + /* Skip past 'host' */ + argc--; + argv++; + + c = find_cmd_tbl(argv[0], cmd_host_sub, + ARRAY_SIZE(cmd_host_sub)); + + if (c) + return c->cmd(cmdtp, flag, argc, argv); + else + return CMD_RET_USAGE; +} + +U_BOOT_CMD( + sb, 8, 1, do_host, + "Deprecated: use 'host' command instead.", "" +); + +U_BOOT_CMD( + host, 8, 1, do_host, + "Miscellaneous host commands", + "load hostfs - <addr> <filename> [<bytes> <offset>] - " + "load a file from host\n" + "host ls hostfs - <filename> - list files on host\n" + "host save hostfs - <addr> <filename> <bytes> [<offset>] - " + "save a file to host\n" + "host bind <dev> [<filename>] - bind \"host\" device to file\n" + "host info [<dev>] - show device binding & info\n" + "host dev [<dev>] - Set or retrieve the current host device\n" + "host commands use the \"hostfs\" device. The \"host\" device is used\n" + "with standard IO commands such as fatls or ext2load" +); diff --git a/common/cmd_led.c b/common/cmd_led.c index 172bc30..b0f1a61 100644 --- a/common/cmd_led.c +++ b/common/cmd_led.c @@ -39,6 +39,12 @@ static const led_tbl_t led_commands[] = { #ifdef STATUS_LED_BIT3 { "3", STATUS_LED_BIT3, NULL, NULL, NULL }, #endif +#ifdef STATUS_LED_BIT4 + { "4", STATUS_LED_BIT4, NULL, NULL, NULL }, +#endif +#ifdef STATUS_LED_BIT5 + { "5", STATUS_LED_BIT5, NULL, NULL, NULL }, +#endif #endif #ifdef STATUS_LED_GREEN { "green", STATUS_LED_GREEN, green_led_off, green_led_on, NULL }, @@ -55,30 +61,39 @@ static const led_tbl_t led_commands[] = { { NULL, 0, NULL, NULL, NULL } }; -enum led_cmd { LED_ON, LED_OFF, LED_TOGGLE }; +enum led_cmd { LED_ON, LED_OFF, LED_TOGGLE, LED_BLINK }; enum led_cmd get_led_cmd(char *var) { - if (strcmp(var, "off") == 0) { + if (strcmp(var, "off") == 0) return LED_OFF; - } - if (strcmp(var, "on") == 0) { + if (strcmp(var, "on") == 0) return LED_ON; - } if (strcmp(var, "toggle") == 0) return LED_TOGGLE; + if (strcmp(var, "blink") == 0) + return LED_BLINK; + return -1; } +/* + * LED drivers providing a blinking LED functionality, like the + * PCA9551, can override this empty weak function + */ +void __weak __led_blink(led_id_t mask, int freq) +{ +} + int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int i, match = 0; enum led_cmd cmd; + int freq; /* Validate arguments */ - if ((argc != 3)) { + if ((argc < 3) || (argc > 4)) return CMD_RET_USAGE; - } cmd = get_led_cmd(argv[2]); if (cmd < 0) { @@ -109,6 +124,13 @@ int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) led_commands[i].toggle(); else __led_toggle(led_commands[i].mask); + break; + case LED_BLINK: + if (argc != 4) + return CMD_RET_USAGE; + + freq = simple_strtoul(argv[3], NULL, 10); + __led_blink(led_commands[i].mask, freq); } /* Need to set only 1 led if led_name wasn't 'all' */ if (strcmp("all", argv[1]) != 0) @@ -125,7 +147,7 @@ int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } U_BOOT_CMD( - led, 3, 1, do_led, + led, 4, 1, do_led, "[" #ifdef CONFIG_BOARD_SPECIFIC_LED #ifdef STATUS_LED_BIT @@ -140,6 +162,12 @@ U_BOOT_CMD( #ifdef STATUS_LED_BIT3 "3|" #endif +#ifdef STATUS_LED_BIT4 + "4|" +#endif +#ifdef STATUS_LED_BIT5 + "5|" +#endif #endif #ifdef STATUS_LED_GREEN "green|" @@ -153,6 +181,6 @@ U_BOOT_CMD( #ifdef STATUS_LED_BLUE "blue|" #endif - "all] [on|off|toggle]", - "[led_name] [on|off|toggle] sets or clears led(s)" + "all] [on|off|toggle|blink] [blink-freq in ms]", + "[led_name] [on|off|toggle|blink] sets or clears led(s)" ); diff --git a/common/cmd_lzmadec.c b/common/cmd_lzmadec.c index 7b0b3fd..1ad9ed6 100644 --- a/common/cmd_lzmadec.c +++ b/common/cmd_lzmadec.c @@ -12,6 +12,7 @@ #include <common.h> #include <command.h> +#include <mapmem.h> #include <asm/io.h> #include <lzma/LzmaTools.h> diff --git a/common/cmd_md5sum.c b/common/cmd_md5sum.c index d22ace5..23bb81e 100644 --- a/common/cmd_md5sum.c +++ b/common/cmd_md5sum.c @@ -10,6 +10,7 @@ #include <common.h> #include <command.h> +#include <mapmem.h> #include <u-boot/md5.h> #include <asm/io.h> diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 3f85c1a..5d8c9e6 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -20,6 +20,7 @@ #endif #include <hash.h> #include <inttypes.h> +#include <mapmem.h> #include <watchdog.h> #include <asm/io.h> #include <linux/compiler.h> @@ -35,9 +36,9 @@ static int mod_mem(cmd_tbl_t *, int, int, int, char * const []); /* Display values from last command. * Memory modify remembered values are different from display memory. */ -static uint dp_last_addr, dp_last_size; -static uint dp_last_length = 0x40; -static uint mm_last_addr, mm_last_size; +static ulong dp_last_addr, dp_last_size; +static ulong dp_last_length = 0x40; +static ulong mm_last_addr, mm_last_size; static ulong base_address = 0; @@ -165,7 +166,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #endif ulong addr, count; int size; - void *buf; + void *buf, *start; ulong bytes; if ((argc < 3) || (argc > 4)) @@ -197,7 +198,8 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } bytes = size * count; - buf = map_sysmem(addr, bytes); + start = map_sysmem(addr, bytes); + buf = start; while (count-- > 0) { if (size == 4) *((u32 *)buf) = (u32)writeval; @@ -211,7 +213,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) *((u8 *)buf) = (u8)writeval; buf += size; } - unmap_sysmem(buf); + unmap_sysmem(start); return 0; } diff --git a/common/cmd_mii.c b/common/cmd_mii.c index 7c4a57a..5e9079d 100644 --- a/common/cmd_mii.c +++ b/common/cmd_mii.c @@ -249,6 +249,7 @@ static uint last_addr_lo; static uint last_addr_hi; static uint last_reg_lo; static uint last_reg_hi; +static uint last_mask; static void extract_range( char * input, @@ -272,7 +273,7 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char op[2]; unsigned char addrlo, addrhi, reglo, reghi; unsigned char addr, reg; - unsigned short data; + unsigned short data, mask; int rcode = 0; const char *devname; @@ -294,6 +295,7 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) reglo = last_reg_lo; reghi = last_reg_hi; data = last_data; + mask = last_mask; if ((flag & CMD_FLAG_REPEAT) == 0) { op[0] = argv[1][0]; @@ -307,7 +309,9 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (argc >= 4) extract_range(argv[3], ®lo, ®hi); if (argc >= 5) - data = simple_strtoul (argv[4], NULL, 16); + data = simple_strtoul(argv[4], NULL, 16); + if (argc >= 6) + mask = simple_strtoul(argv[5], NULL, 16); } /* use current device */ @@ -375,6 +379,28 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } } } + } else if (op[0] == 'm') { + for (addr = addrlo; addr <= addrhi; addr++) { + for (reg = reglo; reg <= reghi; reg++) { + unsigned short val = 0; + if (miiphy_read(devname, addr, + reg, &val)) { + printf("Error reading from the PHY"); + printf(" addr=%02x", addr); + printf(" reg=%02x\n", reg); + rcode = 1; + } else { + val = (val & ~mask) | (data & mask); + if (miiphy_write(devname, addr, + reg, val)) { + printf("Error writing to the PHY"); + printf(" addr=%02x", addr); + printf(" reg=%02x\n", reg); + rcode = 1; + } + } + } + } } else if (strncmp(op, "du", 2) == 0) { ushort regs[6]; int ok = 1; @@ -417,6 +443,7 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) last_reg_lo = reglo; last_reg_hi = reghi; last_data = data; + last_mask = mask; return rcode; } @@ -424,13 +451,15 @@ static int do_mii(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /***************************************************/ U_BOOT_CMD( - mii, 5, 1, do_mii, + mii, 6, 1, do_mii, "MII utility commands", - "device - list available devices\n" - "mii device <devname> - set current device\n" - "mii info <addr> - display MII PHY info\n" - "mii read <addr> <reg> - read MII PHY <addr> register <reg>\n" - "mii write <addr> <reg> <data> - write MII PHY <addr> register <reg>\n" - "mii dump <addr> <reg> - pretty-print <addr> <reg> (0-5 only)\n" + "device - list available devices\n" + "mii device <devname> - set current device\n" + "mii info <addr> - display MII PHY info\n" + "mii read <addr> <reg> - read MII PHY <addr> register <reg>\n" + "mii write <addr> <reg> <data> - write MII PHY <addr> register <reg>\n" + "mii modify <addr> <reg> <data> <mask> - modify MII PHY <addr> register <reg>\n" + " updating bits identified in <mask>\n" + "mii dump <addr> <reg> - pretty-print <addr> <reg> (0-5 only)\n" "Addr and/or reg may be ranges, e.g. 2-7." ); diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 17fa7ea..9433c80 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -394,9 +394,12 @@ static void nand_print_and_set_info(int idx) printf("%dx ", chip->numchips); printf("%s, sector size %u KiB\n", nand->name, nand->erasesize >> 10); - printf(" Page size %8d b\n", nand->writesize); - printf(" OOB size %8d b\n", nand->oobsize); - printf(" Erase size %8d b\n", nand->erasesize); + printf(" Page size %8d b\n", nand->writesize); + printf(" OOB size %8d b\n", nand->oobsize); + printf(" Erase size %8d b\n", nand->erasesize); + printf(" subpagesize %8d b\n", chip->subpagesize); + printf(" options 0x%8x\n", chip->options); + printf(" bbt options 0x%8x\n", chip->bbt_options); /* Set geometry info */ setenv_hex("nand_writesize", nand->writesize); diff --git a/common/cmd_net.c b/common/cmd_net.c index 09489d4..b2f3c7b 100644 --- a/common/cmd_net.c +++ b/common/cmd_net.c @@ -44,10 +44,7 @@ U_BOOT_CMD( #ifdef CONFIG_CMD_TFTPPUT int do_tftpput(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int ret; - - ret = netboot_common(TFTPPUT, cmdtp, argc, argv); - return ret; + return netboot_common(TFTPPUT, cmdtp, argc, argv); } U_BOOT_CMD( @@ -117,24 +114,24 @@ static void netboot_update_env(void) { char tmp[22]; - if (NetOurGatewayIP) { - ip_to_string(NetOurGatewayIP, tmp); + if (net_gateway.s_addr) { + ip_to_string(net_gateway, tmp); setenv("gatewayip", tmp); } - if (NetOurSubnetMask) { - ip_to_string(NetOurSubnetMask, tmp); + if (net_netmask.s_addr) { + ip_to_string(net_netmask, tmp); setenv("netmask", tmp); } - if (NetOurHostName[0]) - setenv("hostname", NetOurHostName); + if (net_hostname[0]) + setenv("hostname", net_hostname); - if (NetOurRootPath[0]) - setenv("rootpath", NetOurRootPath); + if (net_root_path[0]) + setenv("rootpath", net_root_path); - if (NetOurIP) { - ip_to_string(NetOurIP, tmp); + if (net_ip.s_addr) { + ip_to_string(net_ip, tmp); setenv("ipaddr", tmp); } #if !defined(CONFIG_BOOTP_SERVERIP) @@ -142,35 +139,33 @@ static void netboot_update_env(void) * Only attempt to change serverip if net/bootp.c:BootpCopyNetParams() * could have set it */ - if (NetServerIP) { - ip_to_string(NetServerIP, tmp); + if (net_server_ip.s_addr) { + ip_to_string(net_server_ip, tmp); setenv("serverip", tmp); } #endif - if (NetOurDNSIP) { - ip_to_string(NetOurDNSIP, tmp); + if (net_dns_server.s_addr) { + ip_to_string(net_dns_server, tmp); setenv("dnsip", tmp); } #if defined(CONFIG_BOOTP_DNS2) - if (NetOurDNS2IP) { - ip_to_string(NetOurDNS2IP, tmp); + if (net_dns_server2.s_addr) { + ip_to_string(net_dns_server2, tmp); setenv("dnsip2", tmp); } #endif - if (NetOurNISDomain[0]) - setenv("domain", NetOurNISDomain); + if (net_nis_domain[0]) + setenv("domain", net_nis_domain); -#if defined(CONFIG_CMD_SNTP) \ - && defined(CONFIG_BOOTP_TIMEOFFSET) - if (NetTimeOffset) { - sprintf(tmp, "%d", NetTimeOffset); +#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET) + if (net_ntp_time_offset) { + sprintf(tmp, "%d", net_ntp_time_offset); setenv("timeoffset", tmp); } #endif -#if defined(CONFIG_CMD_SNTP) \ - && defined(CONFIG_BOOTP_NTPSERVER) - if (NetNtpServerIP) { - ip_to_string(NetNtpServerIP, tmp); +#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER) + if (net_ntp_server.s_addr) { + ip_to_string(net_ntp_server, tmp); setenv("ntpserverip", tmp); } #endif @@ -186,9 +181,9 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc, ulong addr; /* pre-set load_addr */ - if ((s = getenv("loadaddr")) != NULL) { + s = getenv("loadaddr"); + if (s != NULL) load_addr = simple_strtoul(s, NULL, 16); - } switch (argc) { case 1: @@ -204,22 +199,26 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc, if (end == (argv[1] + strlen(argv[1]))) load_addr = addr; else - copy_filename(BootFile, argv[1], sizeof(BootFile)); + copy_filename(net_boot_file_name, argv[1], + sizeof(net_boot_file_name)); break; - case 3: load_addr = simple_strtoul(argv[1], NULL, 16); - copy_filename(BootFile, argv[2], sizeof(BootFile)); + case 3: + load_addr = simple_strtoul(argv[1], NULL, 16); + copy_filename(net_boot_file_name, argv[2], + sizeof(net_boot_file_name)); break; #ifdef CONFIG_CMD_TFTPPUT case 4: if (strict_strtoul(argv[1], 16, &save_addr) < 0 || - strict_strtoul(argv[2], 16, &save_size) < 0) { + strict_strtoul(argv[2], 16, &save_size) < 0) { printf("Invalid address/size\n"); - return cmd_usage(cmdtp); + return CMD_RET_USAGE; } - copy_filename(BootFile, argv[3], sizeof(BootFile)); + copy_filename(net_boot_file_name, argv[3], + sizeof(net_boot_file_name)); break; #endif default: @@ -228,19 +227,20 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc, } bootstage_mark(BOOTSTAGE_ID_NET_START); - if ((size = NetLoop(proto)) < 0) { + size = net_loop(proto); + if (size < 0) { bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK); - return 1; + return CMD_RET_FAILURE; } bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK); - /* NetLoop ok, update environment */ + /* net_loop ok, update environment */ netboot_update_env(); /* done if no file was loaded (no errors though) */ if (size == 0) { bootstage_error(BOOTSTAGE_ID_NET_LOADED); - return 0; + return CMD_RET_SUCCESS; } /* flush cache */ @@ -250,10 +250,10 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc, rcode = bootm_maybe_autostart(cmdtp, argv[0]); - if (rcode < 0) - bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR); - else + if (rcode == CMD_RET_SUCCESS) bootstage_mark(BOOTSTAGE_ID_NET_DONE); + else + bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR); return rcode; } @@ -261,20 +261,20 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc, static int do_ping(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { if (argc < 2) - return -1; + return CMD_RET_USAGE; - NetPingIP = string_to_ip(argv[1]); - if (NetPingIP == 0) + net_ping_ip = string_to_ip(argv[1]); + if (net_ping_ip.s_addr == 0) return CMD_RET_USAGE; - if (NetLoop(PING) < 0) { + if (net_loop(PING) < 0) { printf("ping failed; host %s is not alive\n", argv[1]); - return 1; + return CMD_RET_FAILURE; } printf("host %s is alive\n", argv[1]); - return 0; + return CMD_RET_SUCCESS; } U_BOOT_CMD( @@ -290,35 +290,35 @@ static void cdp_update_env(void) { char tmp[16]; - if (CDPApplianceVLAN != htons(-1)) { - printf("CDP offered appliance VLAN %d\n", ntohs(CDPApplianceVLAN)); - VLAN_to_string(CDPApplianceVLAN, tmp); + if (cdp_appliance_vlan != htons(-1)) { + printf("CDP offered appliance VLAN %d\n", + ntohs(cdp_appliance_vlan)); + vlan_to_string(cdp_appliance_vlan, tmp); setenv("vlan", tmp); - NetOurVLAN = CDPApplianceVLAN; + net_our_vlan = cdp_appliance_vlan; } - if (CDPNativeVLAN != htons(-1)) { - printf("CDP offered native VLAN %d\n", ntohs(CDPNativeVLAN)); - VLAN_to_string(CDPNativeVLAN, tmp); + if (cdp_native_vlan != htons(-1)) { + printf("CDP offered native VLAN %d\n", ntohs(cdp_native_vlan)); + vlan_to_string(cdp_native_vlan, tmp); setenv("nvlan", tmp); - NetOurNativeVLAN = CDPNativeVLAN; + net_native_vlan = cdp_native_vlan; } - } int do_cdp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int r; - r = NetLoop(CDP); + r = net_loop(CDP); if (r < 0) { printf("cdp failed; perhaps not a CISCO switch?\n"); - return 1; + return CMD_RET_FAILURE; } cdp_update_env(); - return 0; + return CMD_RET_SUCCESS; } U_BOOT_CMD( @@ -334,32 +334,32 @@ int do_sntp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char *toff; if (argc < 2) { - NetNtpServerIP = getenv_IPaddr("ntpserverip"); - if (NetNtpServerIP == 0) { + net_ntp_server = getenv_ip("ntpserverip"); + if (net_ntp_server.s_addr == 0) { printf("ntpserverip not set\n"); - return (1); + return CMD_RET_FAILURE; } } else { - NetNtpServerIP = string_to_ip(argv[1]); - if (NetNtpServerIP == 0) { + net_ntp_server = string_to_ip(argv[1]); + if (net_ntp_server.s_addr == 0) { printf("Bad NTP server IP address\n"); - return (1); + return CMD_RET_FAILURE; } } toff = getenv("timeoffset"); if (toff == NULL) - NetTimeOffset = 0; + net_ntp_time_offset = 0; else - NetTimeOffset = simple_strtol(toff, NULL, 10); + net_ntp_time_offset = simple_strtol(toff, NULL, 10); - if (NetLoop(SNTP) < 0) { + if (net_loop(SNTP) < 0) { printf("SNTP failed: host %pI4 not responding\n", - &NetNtpServerIP); - return 1; + &net_ntp_server); + return CMD_RET_FAILURE; } - return 0; + return CMD_RET_SUCCESS; } U_BOOT_CMD( @@ -389,22 +389,22 @@ int do_dns(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) */ if (strlen(argv[1]) >= 255) { printf("dns error: hostname too long\n"); - return 1; + return CMD_RET_FAILURE; } - NetDNSResolve = argv[1]; + net_dns_resolve = argv[1]; if (argc == 3) - NetDNSenvvar = argv[2]; + net_dns_env_var = argv[2]; else - NetDNSenvvar = NULL; + net_dns_env_var = NULL; - if (NetLoop(DNS) < 0) { + if (net_loop(DNS) < 0) { printf("dns lookup of %s failed, check setup\n", argv[1]); - return 1; + return CMD_RET_FAILURE; } - return 0; + return CMD_RET_SUCCESS; } U_BOOT_CMD( @@ -421,21 +421,21 @@ static int do_link_local(cmd_tbl_t *cmdtp, int flag, int argc, { char tmp[22]; - if (NetLoop(LINKLOCAL) < 0) - return 1; + if (net_loop(LINKLOCAL) < 0) + return CMD_RET_FAILURE; - NetOurGatewayIP = 0; - ip_to_string(NetOurGatewayIP, tmp); + net_gateway.s_addr = 0; + ip_to_string(net_gateway, tmp); setenv("gatewayip", tmp); - ip_to_string(NetOurSubnetMask, tmp); + ip_to_string(net_netmask, tmp); setenv("netmask", tmp); - ip_to_string(NetOurIP, tmp); + ip_to_string(net_ip, tmp); setenv("ipaddr", tmp); setenv("llipaddr", tmp); /* store this for next time */ - return 0; + return CMD_RET_SUCCESS; } U_BOOT_CMD( diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 855808c..be792ae 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -31,6 +31,7 @@ #include <search.h> #include <errno.h> #include <malloc.h> +#include <mapmem.h> #include <watchdog.h> #include <linux/stddef.h> #include <asm/byteorder.h> diff --git a/common/cmd_pci.c b/common/cmd_pci.c index e3a77e3..dcecef8 100644 --- a/common/cmd_pci.c +++ b/common/cmd_pci.c @@ -48,6 +48,7 @@ void pciinfo(int BusNum, int ShortPCIListing) unsigned char HeaderType; unsigned short VendorID; pci_dev_t dev; + int ret; if (!hose) return; @@ -74,7 +75,10 @@ void pciinfo(int BusNum, int ShortPCIListing) if (pci_skip_dev(hose, dev)) continue; - pci_read_config_word(dev, PCI_VENDOR_ID, &VendorID); + ret = pci_read_config_word(dev, PCI_VENDOR_ID, + &VendorID); + if (ret) + goto error; if ((VendorID == 0xFFFF) || (VendorID == 0x0000)) continue; @@ -91,8 +95,12 @@ void pciinfo(int BusNum, int ShortPCIListing) BusNum, Device, Function); pci_header_show(dev); } - } - } + } + } + + return; +error: + printf("Cannot read bus configuration: %d\n", ret); } diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c index 7e32c95..4cbb2b1 100644 --- a/common/cmd_pxe.c +++ b/common/cmd_pxe.c @@ -8,11 +8,13 @@ #include <common.h> #include <command.h> #include <malloc.h> +#include <mapmem.h> #include <linux/string.h> #include <linux/ctype.h> #include <errno.h> #include <linux/list.h> #include <fs.h> +#include <asm/io.h> #include "menu.h" #include "cli.h" @@ -188,11 +190,12 @@ static int do_get_any(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr) * * Returns 1 for success, or < 0 on error. */ -static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr) +static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, + unsigned long file_addr) { size_t path_len; char relfile[MAX_TFTP_PATH_LEN+1]; - char addr_buf[10]; + char addr_buf[18]; int err; err = get_bootfile_path(file_path, relfile, sizeof(relfile)); @@ -215,7 +218,7 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr) printf("Retrieving file: %s\n", relfile); - sprintf(addr_buf, "%p", file_addr); + sprintf(addr_buf, "%lx", file_addr); return do_getfile(cmdtp, relfile, addr_buf); } @@ -227,11 +230,13 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr) * * Returns 1 on success, or < 0 for error. */ -static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr) +static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, + unsigned long file_addr) { unsigned long config_file_size; char *tftp_filesize; int err; + char *buf; err = get_relfile(cmdtp, file_path, file_addr); @@ -250,7 +255,9 @@ static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr if (strict_strtoul(tftp_filesize, 16, &config_file_size) < 0) return -EINVAL; - *(char *)(file_addr + config_file_size) = '\0'; + buf = map_sysmem(file_addr + config_file_size, 1); + *buf = '\0'; + unmap_sysmem(buf); return 1; } @@ -266,7 +273,8 @@ static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr * * Returns 1 on success or < 0 on error. */ -static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_addr_r) +static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, + unsigned long pxefile_addr_r) { size_t base_len = strlen(PXELINUX_DIR); char path[MAX_TFTP_PATH_LEN+1]; @@ -287,7 +295,7 @@ static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_a * * Returns 1 on success or < 0 on error. */ -static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r) +static int pxe_uuid_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r) { char *uuid_str; @@ -305,7 +313,7 @@ static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r) * * Returns 1 on success or < 0 on error. */ -static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r) +static int pxe_mac_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r) { char mac_str[21]; int err; @@ -325,12 +333,12 @@ static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r) * * Returns 1 on success or < 0 on error. */ -static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, void *pxefile_addr_r) +static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r) { char ip_addr[9]; int mask_pos, err; - sprintf(ip_addr, "%08X", ntohl(NetOurIP)); + sprintf(ip_addr, "%08X", ntohl(net_ip.s_addr)); for (mask_pos = 7; mask_pos >= 0; mask_pos--) { err = get_pxelinux_path(cmdtp, ip_addr, pxefile_addr_r); @@ -384,9 +392,9 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * Keep trying paths until we successfully get a file we're looking * for. */ - if (pxe_uuid_path(cmdtp, (void *)pxefile_addr_r) > 0 || - pxe_mac_path(cmdtp, (void *)pxefile_addr_r) > 0 || - pxe_ipaddr_paths(cmdtp, (void *)pxefile_addr_r) > 0) { + if (pxe_uuid_path(cmdtp, pxefile_addr_r) > 0 || + pxe_mac_path(cmdtp, pxefile_addr_r) > 0 || + pxe_ipaddr_paths(cmdtp, pxefile_addr_r) > 0) { printf("Config file found\n"); return 0; @@ -394,7 +402,7 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) while (pxe_default_paths[i]) { if (get_pxelinux_path(cmdtp, pxe_default_paths[i], - (void *)pxefile_addr_r) > 0) { + pxefile_addr_r) > 0) { printf("Config file found\n"); return 0; } @@ -427,7 +435,7 @@ static int get_relfile_envaddr(cmd_tbl_t *cmdtp, const char *file_path, const ch if (strict_strtoul(envaddr, 16, &file_addr) < 0) return -EINVAL; - return get_relfile(cmdtp, file_path, (void *)file_addr); + return get_relfile(cmdtp, file_path, file_addr); } /* @@ -790,6 +798,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) else do_bootz(cmdtp, 0, bootm_argc, bootm_argv); #endif + unmap_sysmem(buf); return 1; } @@ -1054,7 +1063,8 @@ static int parse_integer(char **c, int *dst) return 1; } -static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level); +static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base, + struct pxe_menu *cfg, int nest_level); /* * Parse an include statement, and retrieve and parse the file it mentions. @@ -1064,12 +1074,14 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in * include, nest_level has already been incremented and doesn't need to be * incremented here. */ -static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base, +static int handle_include(cmd_tbl_t *cmdtp, char **c, unsigned long base, struct pxe_menu *cfg, int nest_level) { char *include_path; char *s = *c; int err; + char *buf; + int ret; err = parse_sliteral(c, &include_path); @@ -1086,20 +1098,25 @@ static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base, return err; } - return parse_pxefile_top(cmdtp, base, cfg, nest_level); + buf = map_sysmem(base, 0); + ret = parse_pxefile_top(cmdtp, buf, base, cfg, nest_level); + unmap_sysmem(buf); + + return ret; } /* * Parse lines that begin with 'menu'. * - * b and nest are provided to handle the 'menu include' case. + * base and nest are provided to handle the 'menu include' case. * - * b should be the address where the file currently being parsed is stored. + * base should point to a location where it's safe to store the included file. * * nest_level should be 1 when parsing the top level pxe file, 2 when parsing * a file it includes, 3 when parsing a file included by that file, and so on. */ -static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b, int nest_level) +static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, + unsigned long base, int nest_level) { struct token t; char *s = *c; @@ -1114,7 +1131,7 @@ static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b, break; case T_INCLUDE: - err = handle_include(cmdtp, c, b + strlen(b) + 1, cfg, + err = handle_include(cmdtp, c, base, cfg, nest_level + 1); break; @@ -1281,7 +1298,8 @@ static int parse_label(char **c, struct pxe_menu *cfg) * * Returns 1 on success, < 0 on error. */ -static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level) +static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base, + struct pxe_menu *cfg, int nest_level) { struct token t; char *s, *b, *label_name; @@ -1303,7 +1321,9 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in switch (t.type) { case T_MENU: cfg->prompt = 1; - err = parse_menu(cmdtp, &p, cfg, b, nest_level); + err = parse_menu(cmdtp, &p, cfg, + base + ALIGN(strlen(b) + 1, 4), + nest_level); break; case T_TIMEOUT: @@ -1328,8 +1348,9 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in break; case T_INCLUDE: - err = handle_include(cmdtp, &p, b + ALIGN(strlen(b), 4), cfg, - nest_level + 1); + err = handle_include(cmdtp, &p, + base + ALIGN(strlen(b), 4), cfg, + nest_level + 1); break; case T_PROMPT: @@ -1385,9 +1406,11 @@ static void destroy_pxe_menu(struct pxe_menu *cfg) * files it includes). The resulting pxe_menu struct can be free()'d by using * the destroy_pxe_menu() function. */ -static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg) +static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, unsigned long menucfg) { struct pxe_menu *cfg; + char *buf; + int r; cfg = malloc(sizeof(struct pxe_menu)); @@ -1398,7 +1421,11 @@ static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg) INIT_LIST_HEAD(&cfg->labels); - if (parse_pxefile_top(cmdtp, menucfg, cfg, 1) < 0) { + buf = map_sysmem(menucfg, 0); + r = parse_pxefile_top(cmdtp, buf, menucfg, cfg, 1); + unmap_sysmem(buf); + + if (r < 0) { destroy_pxe_menu(cfg); return NULL; } @@ -1556,7 +1583,7 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r)); + cfg = parse_pxefile(cmdtp, pxefile_addr_r); if (cfg == NULL) { printf("Error parsing config file\n"); @@ -1567,7 +1594,7 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) destroy_pxe_menu(cfg); - copy_filename(BootFile, "", sizeof(BootFile)); + copy_filename(net_boot_file_name, "", sizeof(net_boot_file_name)); return 0; } @@ -1663,12 +1690,12 @@ static int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - if (get_pxe_file(cmdtp, filename, (void *)pxefile_addr_r) < 0) { + if (get_pxe_file(cmdtp, filename, pxefile_addr_r) < 0) { printf("Error reading config file\n"); return 1; } - cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r)); + cfg = parse_pxefile(cmdtp, pxefile_addr_r); if (cfg == NULL) { printf("Error parsing config file\n"); diff --git a/common/cmd_sandbox.c b/common/cmd_sandbox.c deleted file mode 100644 index 4286969..0000000 --- a/common/cmd_sandbox.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2012, Google Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <fs.h> -#include <part.h> -#include <sandboxblockdev.h> -#include <asm/errno.h> - -static int do_sandbox_load(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) -{ - return do_load(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX); -} - -static int do_sandbox_ls(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) -{ - return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX); -} - -static int do_sandbox_save(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) -{ - return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX); -} - -static int do_sandbox_bind(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) -{ - if (argc < 2 || argc > 3) - return CMD_RET_USAGE; - char *ep; - char *dev_str = argv[1]; - char *file = argc >= 3 ? argv[2] : NULL; - int dev = simple_strtoul(dev_str, &ep, 16); - if (*ep) { - printf("** Bad device specification %s **\n", dev_str); - return CMD_RET_USAGE; - } - return host_dev_bind(dev, file); -} - -static int do_sandbox_info(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) -{ - if (argc < 1 || argc > 2) - return CMD_RET_USAGE; - int min_dev = 0; - int max_dev = CONFIG_HOST_MAX_DEVICES - 1; - if (argc >= 2) { - char *ep; - char *dev_str = argv[1]; - int dev = simple_strtoul(dev_str, &ep, 16); - if (*ep) { - printf("** Bad device specification %s **\n", dev_str); - return CMD_RET_USAGE; - } - min_dev = dev; - max_dev = dev; - } - int dev; - printf("%3s %12s %s\n", "dev", "blocks", "path"); - for (dev = min_dev; dev <= max_dev; dev++) { - block_dev_desc_t *blk_dev; - int ret; - - printf("%3d ", dev); - ret = host_get_dev_err(dev, &blk_dev); - if (ret) { - if (ret == -ENOENT) - puts("Not bound to a backing file\n"); - else if (ret == -ENODEV) - puts("Invalid host device number\n"); - - continue; - } - struct host_block_dev *host_dev = blk_dev->priv; - printf("%12lu %s\n", (unsigned long)blk_dev->lba, - host_dev->filename); - } - return 0; -} - -static cmd_tbl_t cmd_sandbox_sub[] = { - U_BOOT_CMD_MKENT(load, 7, 0, do_sandbox_load, "", ""), - U_BOOT_CMD_MKENT(ls, 3, 0, do_sandbox_ls, "", ""), - U_BOOT_CMD_MKENT(save, 6, 0, do_sandbox_save, "", ""), - U_BOOT_CMD_MKENT(bind, 3, 0, do_sandbox_bind, "", ""), - U_BOOT_CMD_MKENT(info, 3, 0, do_sandbox_info, "", ""), -}; - -static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) -{ - cmd_tbl_t *c; - - /* Skip past 'sandbox' */ - argc--; - argv++; - - c = find_cmd_tbl(argv[0], cmd_sandbox_sub, - ARRAY_SIZE(cmd_sandbox_sub)); - - if (c) - return c->cmd(cmdtp, flag, argc, argv); - else - return CMD_RET_USAGE; -} - -U_BOOT_CMD( - sb, 8, 1, do_sandbox, - "Miscellaneous sandbox commands", - "load hostfs - <addr> <filename> [<bytes> <offset>] - " - "load a file from host\n" - "sb ls hostfs - <filename> - list files on host\n" - "sb save hostfs - <addr> <filename> <bytes> [<offset>] - " - "save a file to host\n" - "sb bind <dev> [<filename>] - bind \"host\" device to file\n" - "sb info [<dev>] - show device binding & info\n" - "sb commands use the \"hostfs\" device. The \"host\" device is used\n" - "with standard IO commands such as fatls or ext2load" -); diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index a0a62eb..f80f549 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -37,7 +37,7 @@ #define SCSI_DEV_LIST {SCSI_VEND_ID, SCSI_DEV_ID} #endif -#ifdef CONFIG_PCI +#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT) const struct pci_device_id scsi_device_list[] = { SCSI_DEV_LIST }; #endif static ccb tempccb; /* temporary scsi command buffer */ @@ -179,7 +179,7 @@ int scsi_get_disk_count(void) return scsi_max_devs; } -#ifdef CONFIG_PCI +#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT) void scsi_init(void) { int busdevfunc; diff --git a/common/cmd_sf.c b/common/cmd_sf.c index 5c788e9..342021d 100644 --- a/common/cmd_sf.c +++ b/common/cmd_sf.c @@ -10,6 +10,7 @@ #include <div64.h> #include <dm.h> #include <malloc.h> +#include <mapmem.h> #include <spi.h> #include <spi_flash.h> @@ -130,7 +131,7 @@ static int do_spi_flash_probe(int argc, char * const argv[]) return 1; } - flash = new->uclass_priv; + flash = dev_get_uclass_priv(new); #else new = spi_flash_probe(bus, cs, speed, mode); if (!new) { @@ -163,6 +164,8 @@ static int do_spi_flash_probe(int argc, char * const argv[]) static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset, size_t len, const char *buf, char *cmp_buf, size_t *skipped) { + char *ptr = (char *)buf; + debug("offset=%#x, sector_size=%#x, len=%#zx\n", offset, flash->sector_size, len); /* Read the entire sector so to allow for rewriting */ @@ -178,16 +181,14 @@ static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset, /* Erase the entire sector */ if (spi_flash_erase(flash, offset, flash->sector_size)) return "erase"; - /* Write the initial part of the block from the source */ - if (spi_flash_write(flash, offset, len, buf)) - return "write"; - /* If it's a partial sector, rewrite the existing part */ + /* If it's a partial sector, copy the data into the temp-buffer */ if (len != flash->sector_size) { - /* Rewrite the original data to the end of the sector */ - if (spi_flash_write(flash, offset + len, - flash->sector_size - len, &cmp_buf[len])) - return "write"; + memcpy(cmp_buf, buf, len); + ptr = cmp_buf; } + /* Write one complete sector */ + if (spi_flash_write(flash, offset, flash->sector_size, ptr)) + return "write"; return NULL; } diff --git a/common/cmd_source.c b/common/cmd_source.c index 6881bc9..d2a881d 100644 --- a/common/cmd_source.c +++ b/common/cmd_source.c @@ -19,6 +19,7 @@ #include <command.h> #include <image.h> #include <malloc.h> +#include <mapmem.h> #include <asm/byteorder.h> #include <asm/io.h> #if defined(CONFIG_8xx) diff --git a/common/cmd_trace.c b/common/cmd_trace.c index 8c630e6..1e62a1a 100644 --- a/common/cmd_trace.c +++ b/common/cmd_trace.c @@ -6,6 +6,7 @@ #include <common.h> #include <command.h> +#include <mapmem.h> #include <trace.h> #include <asm/io.h> diff --git a/common/cmd_unzip.c b/common/cmd_unzip.c index b02c69e..0686be6 100644 --- a/common/cmd_unzip.c +++ b/common/cmd_unzip.c @@ -39,3 +39,50 @@ U_BOOT_CMD( "unzip a memory region", "srcaddr dstaddr [dstsize]" ); + +static int do_gzwrite(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + block_dev_desc_t *bdev; + int ret; + unsigned char *addr; + unsigned long length; + unsigned long writebuf = 1<<20; + u64 startoffs = 0; + u64 szexpected = 0; + + if (argc < 5) + return CMD_RET_USAGE; + ret = get_device(argv[1], argv[2], &bdev); + if (ret < 0) + return CMD_RET_FAILURE; + + addr = (unsigned char *)simple_strtoul(argv[3], NULL, 16); + length = simple_strtoul(argv[4], NULL, 16); + + if (5 < argc) { + writebuf = simple_strtoul(argv[5], NULL, 16); + if (6 < argc) { + startoffs = simple_strtoull(argv[6], NULL, 16); + if (7 < argc) + szexpected = simple_strtoull(argv[7], + NULL, 16); + } + } + + ret = gzwrite(addr, length, bdev, writebuf, startoffs, szexpected); + + return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + gzwrite, 8, 0, do_gzwrite, + "unzip and write memory to block device", + "<interface> <dev> <addr> length [wbuf=1M [offs=0 [outsize=0]]]\n" + "\twbuf is the size in bytes (hex) of write buffer\n" + "\t\tand should be padded to erase size for SSDs\n" + "\toffs is the output start offset in bytes (hex)\n" + "\toutsize is the size of the expected output (hex bytes)\n" + "\t\tand is required for files with uncompressed lengths\n" + "\t\t4 GiB or larger\n" +); diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 27813f0..eab55cd 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -2,6 +2,9 @@ * (C) Copyright 2001 * Denis Peter, MPL AG Switzerland * + * Adapted for U-Boot driver model + * (C) Copyright 2015 Google, Inc + * * Most of this source has been derived from the Linux USB * project. * @@ -10,6 +13,7 @@ #include <common.h> #include <command.h> +#include <dm.h> #include <asm/byteorder.h> #include <asm/unaligned.h> #include <part.h> @@ -252,18 +256,57 @@ static void usb_display_config(struct usb_device *dev) printf("\n"); } +/* + * With driver model this isn't right since we can have multiple controllers + * and the device numbering starts at 1 on each bus. + * TODO(sjg@chromium.org): Add a way to specify the controller/bus. + */ static struct usb_device *usb_find_device(int devnum) { - struct usb_device *dev; +#ifdef CONFIG_DM_USB + struct usb_device *udev; + struct udevice *hub; + struct uclass *uc; + int ret; + + /* Device addresses start at 1 */ + devnum++; + ret = uclass_get(UCLASS_USB_HUB, &uc); + if (ret) + return NULL; + + uclass_foreach_dev(hub, uc) { + struct udevice *dev; + + if (!device_active(hub)) + continue; + udev = dev_get_parentdata(hub); + if (udev->devnum == devnum) + return udev; + + for (device_find_first_child(hub, &dev); + dev; + device_find_next_child(&dev)) { + if (!device_active(hub)) + continue; + + udev = dev_get_parentdata(dev); + if (udev->devnum == devnum) + return udev; + } + } +#else + struct usb_device *udev; int d; for (d = 0; d < USB_MAX_DEVICE; d++) { - dev = usb_get_dev_index(d); - if (dev == NULL) + udev = usb_get_dev_index(d); + if (udev == NULL) return NULL; - if (dev->devnum == devnum) - return dev; + if (udev->devnum == devnum) + return udev; } +#endif return NULL; } @@ -293,20 +336,31 @@ static inline char *portspeed(int speed) /* shows the device tree recursively */ static void usb_show_tree_graph(struct usb_device *dev, char *pre) { - int i, index; + int index; int has_child, last_child; index = strlen(pre); printf(" %s", pre); +#ifdef CONFIG_DM_USB + has_child = device_has_active_children(dev->dev); +#else /* check if the device has connected children */ + int i; + has_child = 0; for (i = 0; i < dev->maxchild; i++) { if (dev->children[i] != NULL) has_child = 1; } +#endif /* check if we are the last one */ - last_child = 1; - if (dev->parent != NULL) { +#ifdef CONFIG_DM_USB + last_child = device_is_last_sibling(dev->dev); +#else + last_child = (dev->parent != NULL); +#endif + if (last_child) { +#ifndef CONFIG_DM_USB for (i = 0; i < dev->parent->maxchild; i++) { /* search for children */ if (dev->parent->children[i] == dev) { @@ -322,9 +376,10 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre) } /* while */ } /* device found */ } /* for all children of the parent */ +#endif printf("\b+-"); /* correct last child */ - if (last_child) + if (last_child && index) pre[index-1] = ' '; } /* if not root hub */ else @@ -340,6 +395,26 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre) if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial)) printf(" %s %s %s %s\n", pre, dev->mf, dev->prod, dev->serial); printf(" %s\n", pre); +#ifdef CONFIG_DM_USB + struct udevice *child; + + for (device_find_first_child(dev->dev, &child); + child; + device_find_next_child(&child)) { + struct usb_device *udev; + + if (!device_active(child)) + continue; + + udev = dev_get_parentdata(child); + + /* Ignore emulators, we only want real devices */ + if (device_get_uclass_id(child) != UCLASS_USB_EMUL) { + usb_show_tree_graph(udev, pre); + pre[index] = 0; + } + } +#else if (dev->maxchild > 0) { for (i = 0; i < dev->maxchild; i++) { if (dev->children[i] != NULL) { @@ -348,6 +423,7 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre) } } } +#endif } /* main routine for the tree command */ @@ -355,7 +431,7 @@ static void usb_show_tree(struct usb_device *dev) { char preamble[32]; - memset(preamble, 0, 32); + memset(preamble, '\0', sizeof(preamble)); usb_show_tree_graph(dev, &preamble[0]); } @@ -448,10 +524,13 @@ static void do_usb_start(void) if (usb_init() < 0) return; + /* Driver model will probe the devices as they are found */ +#ifndef CONFIG_DM_USB #ifdef CONFIG_USB_STORAGE /* try to recognize storage devices immediately */ usb_stor_curr_dev = usb_stor_scan(1); #endif +#endif #ifdef CONFIG_USB_HOST_ETHER /* try to recognize ethernet devices immediately */ usb_ether_curr_dev = usb_host_eth_scan(1); @@ -461,14 +540,50 @@ static void do_usb_start(void) #endif } +#ifdef CONFIG_DM_USB +static void show_info(struct udevice *dev) +{ + struct udevice *child; + struct usb_device *udev; + + udev = dev_get_parentdata(dev); + usb_display_desc(udev); + usb_display_config(udev); + for (device_find_first_child(dev, &child); + child; + device_find_next_child(&child)) { + if (device_active(child)) + show_info(child); + } +} + +static int usb_device_info(void) +{ + struct udevice *bus; + + for (uclass_first_device(UCLASS_USB, &bus); + bus; + uclass_next_device(&bus)) { + struct udevice *hub; + + device_find_first_child(bus, &hub); + if (device_get_uclass_id(hub) == UCLASS_USB_HUB && + device_active(hub)) { + show_info(hub); + } + } + + return 0; +} +#endif + /****************************************************************************** * usb command intepreter */ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - + struct usb_device *udev = NULL; int i; - struct usb_device *dev = NULL; extern char usb_started; #ifdef CONFIG_USB_STORAGE block_dev_desc_t *stor_dev; @@ -508,36 +623,63 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } if (strncmp(argv[1], "tree", 4) == 0) { puts("USB device tree:\n"); +#ifdef CONFIG_DM_USB + struct udevice *bus; + + for (uclass_first_device(UCLASS_USB, &bus); + bus; + uclass_next_device(&bus)) { + struct usb_device *udev; + struct udevice *hub; + + device_find_first_child(bus, &hub); + if (device_get_uclass_id(hub) == UCLASS_USB_HUB && + device_active(hub)) { + udev = dev_get_parentdata(hub); + usb_show_tree(udev); + } + } +#else for (i = 0; i < USB_MAX_DEVICE; i++) { - dev = usb_get_dev_index(i); - if (dev == NULL) + udev = usb_get_dev_index(i); + if (udev == NULL) break; - if (dev->parent == NULL) - usb_show_tree(dev); + if (udev->parent == NULL) + usb_show_tree(udev); } +#endif return 0; } if (strncmp(argv[1], "inf", 3) == 0) { - int d; if (argc == 2) { +#ifdef CONFIG_DM_USB + usb_device_info(); +#else + int d; for (d = 0; d < USB_MAX_DEVICE; d++) { - dev = usb_get_dev_index(d); - if (dev == NULL) + udev = usb_get_dev_index(d); + if (udev == NULL) break; - usb_display_desc(dev); - usb_display_config(dev); + usb_display_desc(udev); + usb_display_config(udev); } +#endif return 0; } else { + /* + * With driver model this isn't right since we can + * have multiple controllers and the device numbering + * starts at 1 on each bus. + */ i = simple_strtoul(argv[2], NULL, 10); printf("config for device %d\n", i); - dev = usb_find_device(i); - if (dev == NULL) { + udev = usb_find_device(i); + if (udev == NULL) { printf("*** No device available ***\n"); return 0; } else { - usb_display_desc(dev); - usb_display_config(dev); + usb_display_desc(udev); + usb_display_config(udev); } } return 0; @@ -546,13 +688,13 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (argc < 5) return CMD_RET_USAGE; i = simple_strtoul(argv[2], NULL, 10); - dev = usb_find_device(i); - if (dev == NULL) { + udev = usb_find_device(i); + if (udev == NULL) { printf("Device %d does not exist.\n", i); return 1; } i = simple_strtoul(argv[3], NULL, 10); - return usb_test(dev, i, argv[4]); + return usb_test(udev, i, argv[4]); } #ifdef CONFIG_USB_STORAGE if (strncmp(argv[1], "stor", 4) == 0) diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index 64b9186..8b8645c 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -15,6 +15,7 @@ #include <common.h> #include <command.h> #include <image.h> +#include <mapmem.h> #include <watchdog.h> #if defined(CONFIG_BZIP2) #include <bzlib.h> diff --git a/common/cros_ec.c b/common/cros_ec.c index bb299bc..7a4f785 100644 --- a/common/cros_ec.c +++ b/common/cros_ec.c @@ -15,18 +15,8 @@ DECLARE_GLOBAL_DATA_PTR; -#ifndef CONFIG_DM_CROS_EC -struct local_info { - struct cros_ec_dev *cros_ec_dev; /* Pointer to cros_ec device */ - int cros_ec_err; /* Error for cros_ec, 0 if ok */ -}; - -static struct local_info local; -#endif - struct cros_ec_dev *board_get_cros_ec_dev(void) { -#ifdef CONFIG_DM_CROS_EC struct udevice *dev; int ret; @@ -35,31 +25,11 @@ struct cros_ec_dev *board_get_cros_ec_dev(void) debug("%s: Error %d\n", __func__, ret); return NULL; } - return dev->uclass_priv; -#else - return local.cros_ec_dev; -#endif -} - -static int board_init_cros_ec_devices(const void *blob) -{ -#ifndef CONFIG_DM_CROS_EC - local.cros_ec_err = cros_ec_init(blob, &local.cros_ec_dev); - if (local.cros_ec_err) - return -1; /* Will report in board_late_init() */ -#endif - - return 0; -} - -int cros_ec_board_init(void) -{ - return board_init_cros_ec_devices(gd->fdt_blob); + return dev_get_uclass_priv(dev); } int cros_ec_get_error(void) { -#ifdef CONFIG_DM_CROS_EC struct udevice *dev; int ret; @@ -68,7 +38,4 @@ int cros_ec_get_error(void) return ret; return 0; -#else - return local.cros_ec_err; -#endif } diff --git a/common/dlmalloc.c b/common/dlmalloc.c index b2ce063..b5bb051 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -3261,6 +3261,17 @@ int mALLOPt(param_number, value) int param_number; int value; } } +int initf_malloc(void) +{ +#ifdef CONFIG_SYS_MALLOC_F_LEN + assert(gd->malloc_base); /* Set up by crt0.S */ + gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; + gd->malloc_ptr = 0; +#endif + + return 0; +} + /* History: diff --git a/common/fdt_support.c b/common/fdt_support.c index 8266bca..c5ed5ad 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -1560,3 +1560,32 @@ int fdt_setup_simplefb_node(void *fdt, int node, u64 base_address, u32 width, return 0; } + +/* + * Update native-mode in display-timings from display environment variable. + * The node to update are specified by path. + */ +int fdt_fixup_display(void *blob, const char *path, const char *display) +{ + int off, toff; + + if (!display || !path) + return -FDT_ERR_NOTFOUND; + + toff = fdt_path_offset(blob, path); + if (toff >= 0) + toff = fdt_subnode_offset(blob, toff, "display-timings"); + if (toff < 0) + return toff; + + for (off = fdt_first_subnode(blob, toff); + off >= 0; + off = fdt_next_subnode(blob, off)) { + uint32_t h = fdt_get_phandle(blob, off); + debug("%s:0x%x\n", fdt_get_name(blob, off, NULL), + fdt32_to_cpu(h)); + if (strcasecmp(fdt_get_name(blob, off, NULL), display) == 0) + return fdt_setprop_u32(blob, toff, "native-mode", h); + } + return toff; +} diff --git a/common/hash.c b/common/hash.c index 9e9f84b..c94c98b 100644 --- a/common/hash.c +++ b/common/hash.c @@ -14,6 +14,7 @@ #include <common.h> #include <command.h> #include <malloc.h> +#include <mapmem.h> #include <hw_sha.h> #include <asm/io.h> #include <asm/errno.h> diff --git a/common/image-fdt.c b/common/image-fdt.c index d9e4728..7e2da7b 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -14,6 +14,7 @@ #include <errno.h> #include <image.h> #include <libfdt.h> +#include <mapmem.h> #include <asm/io.h> #ifndef CONFIG_SYS_FDT_PAD diff --git a/common/image-fit.c b/common/image-fit.c index 778d2a1..4eb4d42 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -16,6 +16,7 @@ #else #include <common.h> #include <errno.h> +#include <mapmem.h> #include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; #endif /* !USE_HOSTCC*/ diff --git a/common/image.c b/common/image.c index 162b682..abc0d89 100644 --- a/common/image.c +++ b/common/image.c @@ -27,6 +27,7 @@ #include <environment.h> #include <image.h> +#include <mapmem.h> #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) #include <libfdt.h> diff --git a/common/iotrace.c b/common/iotrace.c index ced426e..2725563 100644 --- a/common/iotrace.c +++ b/common/iotrace.c @@ -7,6 +7,7 @@ #define IOTRACE_IMPL #include <common.h> +#include <mapmem.h> #include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/common/lcd.c b/common/lcd.c index f33942c..055c366 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -15,6 +15,7 @@ #include <linux/types.h> #include <stdio_dev.h> #include <lcd.h> +#include <mapmem.h> #include <watchdog.h> #include <asm/unaligned.h> #include <splash.h> @@ -167,7 +168,6 @@ int drv_lcd_init(void) void lcd_clear(void) { - short console_rows, console_cols; int bg_color; char *s; ulong addr; @@ -211,16 +211,14 @@ void lcd_clear(void) } #endif #endif + /* setup text-console */ + debug("[LCD] setting up console...\n"); + lcd_init_console(lcd_base, + panel_info.vl_col, + panel_info.vl_row, + panel_info.vl_rot); /* Paint the logo and retrieve LCD base address */ debug("[LCD] Drawing the logo...\n"); -#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) - console_rows = (panel_info.vl_row - BMP_LOGO_HEIGHT); - console_rows /= VIDEO_FONT_HEIGHT; -#else - console_rows = panel_info.vl_row / VIDEO_FONT_HEIGHT; -#endif - console_cols = panel_info.vl_col / VIDEO_FONT_WIDTH; - lcd_init_console(lcd_base, console_rows, console_cols); if (do_splash) { s = getenv("splashimage"); if (s) { @@ -236,7 +234,8 @@ void lcd_clear(void) lcd_logo(); #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) addr = (ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length; - lcd_init_console((void *)addr, console_rows, console_cols); + lcd_init_console((void *)addr, panel_info.vl_row, + panel_info.vl_col, panel_info.vl_rot); #endif lcd_sync(); } diff --git a/common/lcd_console.c b/common/lcd_console.c index 8bf83b9..bb0d7c5 100644 --- a/common/lcd_console.c +++ b/common/lcd_console.c @@ -1,7 +1,8 @@ /* - * (C) Copyright 2001-2014 + * (C) Copyright 2001-2015 * DENX Software Engineering -- wd@denx.de * Compulab Ltd - http://compulab.co.il/ + * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com * * SPDX-License-Identifier: GPL-2.0+ */ @@ -9,142 +10,150 @@ #include <common.h> #include <lcd.h> #include <video_font.h> /* Get font data, width and height */ +#if defined(CONFIG_LCD_LOGO) +#include <bmp_logo.h> +#endif -#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length) -#define CONSOLE_ROW_FIRST lcd_console_address -#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * console_rows) - -static short console_curr_col; -static short console_curr_row; -static short console_cols; -static short console_rows; -static void *lcd_console_address; - -void lcd_init_console(void *address, int rows, int cols) -{ - console_curr_col = 0; - console_curr_row = 0; - console_cols = cols; - console_rows = rows; - lcd_console_address = address; -} +static struct console_t cons; void lcd_set_col(short col) { - console_curr_col = col; + cons.curr_col = col; } void lcd_set_row(short row) { - console_curr_row = row; + cons.curr_row = row; } void lcd_position_cursor(unsigned col, unsigned row) { - console_curr_col = min_t(short, col, console_cols - 1); - console_curr_row = min_t(short, row, console_rows - 1); + cons.curr_col = min_t(short, col, cons.cols - 1); + cons.curr_row = min_t(short, row, cons.rows - 1); } int lcd_get_screen_rows(void) { - return console_rows; + return cons.rows; } int lcd_get_screen_columns(void) { - return console_cols; + return cons.cols; } -static void lcd_drawchars(ushort x, ushort y, uchar *str, int count) +static void lcd_putc_xy0(struct console_t *pcons, ushort x, ushort y, char c) { - uchar *dest; - ushort row; - int fg_color, bg_color; + int fg_color = lcd_getfgcolor(); + int bg_color = lcd_getbgcolor(); + int i, row; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + y * pcons->lcdsizex + + x; + + for (row = 0; row < VIDEO_FONT_HEIGHT; row++) { + uchar bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row]; + for (i = 0; i < VIDEO_FONT_WIDTH; ++i) { + *dst++ = (bits & 0x80) ? fg_color : bg_color; + bits <<= 1; + } + dst += (pcons->lcdsizex - VIDEO_FONT_WIDTH); + } +} - dest = (uchar *)(lcd_console_address + - y * lcd_line_length + x * NBITS(LCD_BPP) / 8); +static inline void console_setrow0(struct console_t *pcons, u32 row, int clr) +{ + int i; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + row * VIDEO_FONT_HEIGHT * + pcons->lcdsizex; - for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) { - uchar *s = str; - int i; -#if LCD_BPP == LCD_COLOR16 - ushort *d = (ushort *)dest; -#elif LCD_BPP == LCD_COLOR32 - u32 *d = (u32 *)dest; -#else - uchar *d = dest; -#endif + for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++) + *dst++ = clr; +} - fg_color = lcd_getfgcolor(); - bg_color = lcd_getbgcolor(); - for (i = 0; i < count; ++i) { - uchar c, bits; +static inline void console_moverow0(struct console_t *pcons, + u32 rowdst, u32 rowsrc) +{ + int i; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + rowdst * VIDEO_FONT_HEIGHT * + pcons->lcdsizex; - c = *s++; - bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row]; + fbptr_t *src = (fbptr_t *)pcons->fbbase + + rowsrc * VIDEO_FONT_HEIGHT * + pcons->lcdsizex; - for (c = 0; c < 8; ++c) { - *d++ = (bits & 0x80) ? fg_color : bg_color; - bits <<= 1; - } - } - } + for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++) + *dst++ = *src++; } -static inline void lcd_putc_xy(ushort x, ushort y, uchar c) +static inline void console_back(void) { - lcd_drawchars(x, y, &c, 1); + if (--cons.curr_col < 0) { + cons.curr_col = cons.cols - 1; + if (--cons.curr_row < 0) + cons.curr_row = 0; + } + + cons.fp_putc_xy(&cons, + cons.curr_col * VIDEO_FONT_WIDTH, + cons.curr_row * VIDEO_FONT_HEIGHT, ' '); } -static void console_scrollup(void) +static inline void console_newline(void) { const int rows = CONFIG_CONSOLE_SCROLL_LINES; int bg_color = lcd_getbgcolor(); + int i; - /* Copy up rows ignoring those that will be overwritten */ - memcpy(CONSOLE_ROW_FIRST, - lcd_console_address + CONSOLE_ROW_SIZE * rows, - CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows); + cons.curr_col = 0; - /* Clear the last rows */ -#if (LCD_BPP != LCD_COLOR32) - memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows, - bg_color, CONSOLE_ROW_SIZE * rows); -#else - u32 *ppix = lcd_console_address + - CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows; - u32 i; - for (i = 0; - i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix); - i++) { - *ppix++ = bg_color; + /* Check if we need to scroll the terminal */ + if (++cons.curr_row >= cons.rows) { + for (i = 0; i < cons.rows-rows; i++) + cons.fp_console_moverow(&cons, i, i+rows); + for (i = 0; i < rows; i++) + cons.fp_console_setrow(&cons, cons.rows-i-1, bg_color); + cons.curr_row -= rows; } -#endif lcd_sync(); - console_curr_row -= rows; } -static inline void console_back(void) +void console_calc_rowcol(struct console_t *pcons, u32 sizex, u32 sizey) { - if (--console_curr_col < 0) { - console_curr_col = console_cols - 1; - if (--console_curr_row < 0) - console_curr_row = 0; - } + pcons->cols = sizex / VIDEO_FONT_WIDTH; +#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) + pcons->rows = (pcons->lcdsizey - BMP_LOGO_HEIGHT); + pcons->rows /= VIDEO_FONT_HEIGHT; +#else + pcons->rows = sizey / VIDEO_FONT_HEIGHT; +#endif +} - lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH, - console_curr_row * VIDEO_FONT_HEIGHT, ' '); +void __weak lcd_init_console_rot(struct console_t *pcons) +{ + return; } -static inline void console_newline(void) +void lcd_init_console(void *address, int vl_cols, int vl_rows, int vl_rot) { - console_curr_col = 0; + memset(&cons, 0, sizeof(cons)); + cons.fbbase = address; - /* Check if we need to scroll the terminal */ - if (++console_curr_row >= console_rows) - console_scrollup(); - else - lcd_sync(); + cons.lcdsizex = vl_cols; + cons.lcdsizey = vl_rows; + cons.lcdrot = vl_rot; + + cons.fp_putc_xy = &lcd_putc_xy0; + cons.fp_console_moverow = &console_moverow0; + cons.fp_console_setrow = &console_setrow0; + console_calc_rowcol(&cons, cons.lcdsizex, cons.lcdsizey); + + lcd_init_console_rot(&cons); + + debug("lcd_console: have %d/%d col/rws on scr %dx%d (%d deg rotated)\n", + cons.cols, cons.rows, cons.lcdsizex, cons.lcdsizey, vl_rot); } void lcd_putc(const char c) @@ -157,18 +166,17 @@ void lcd_putc(const char c) switch (c) { case '\r': - console_curr_col = 0; - + cons.curr_col = 0; return; case '\n': console_newline(); return; case '\t': /* Tab (8 chars alignment) */ - console_curr_col += 8; - console_curr_col &= ~7; + cons.curr_col += 8; + cons.curr_col &= ~7; - if (console_curr_col >= console_cols) + if (cons.curr_col >= cons.cols) console_newline(); return; @@ -177,9 +185,10 @@ void lcd_putc(const char c) return; default: - lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH, - console_curr_row * VIDEO_FONT_HEIGHT, c); - if (++console_curr_col >= console_cols) + cons.fp_putc_xy(&cons, + cons.curr_col * VIDEO_FONT_WIDTH, + cons.curr_row * VIDEO_FONT_HEIGHT, c); + if (++cons.curr_col >= cons.cols) console_newline(); } } diff --git a/common/lcd_console_rotation.c b/common/lcd_console_rotation.c new file mode 100644 index 0000000..7aac521 --- /dev/null +++ b/common/lcd_console_rotation.c @@ -0,0 +1,195 @@ +/* + * (C) Copyright 2015 + * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <lcd.h> +#include <video_font.h> /* Get font data, width and height */ + +static void lcd_putc_xy90(struct console_t *pcons, ushort x, ushort y, char c) +{ + int fg_color = lcd_getfgcolor(); + int bg_color = lcd_getbgcolor(); + int col, i; + + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + (x+1) * pcons->lcdsizex - + y; + + uchar msk = 0x80; + uchar *pfont = video_fontdata + c * VIDEO_FONT_HEIGHT; + for (col = 0; col < VIDEO_FONT_WIDTH; ++col) { + for (i = 0; i < VIDEO_FONT_HEIGHT; ++i) + *dst-- = (*(pfont + i) & msk) ? fg_color : bg_color; + msk >>= 1; + dst += (pcons->lcdsizex + VIDEO_FONT_HEIGHT); + } +} + +static inline void console_setrow90(struct console_t *pcons, u32 row, int clr) +{ + int i, j; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + pcons->lcdsizex - + row*VIDEO_FONT_HEIGHT+1; + + for (j = 0; j < pcons->lcdsizey; j++) { + for (i = 0; i < VIDEO_FONT_HEIGHT; i++) + *dst-- = clr; + dst += (pcons->lcdsizex + VIDEO_FONT_HEIGHT); + } +} + +static inline void console_moverow90(struct console_t *pcons, + u32 rowdst, u32 rowsrc) +{ + int i, j; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + pcons->lcdsizex - + (rowdst*VIDEO_FONT_HEIGHT+1); + + fbptr_t *src = (fbptr_t *)pcons->fbbase + + pcons->lcdsizex - + (rowsrc*VIDEO_FONT_HEIGHT+1); + + for (j = 0; j < pcons->lcdsizey; j++) { + for (i = 0; i < VIDEO_FONT_HEIGHT; i++) + *dst-- = *src--; + src += (pcons->lcdsizex + VIDEO_FONT_HEIGHT); + dst += (pcons->lcdsizex + VIDEO_FONT_HEIGHT); + } +} +static void lcd_putc_xy180(struct console_t *pcons, ushort x, ushort y, char c) +{ + int fg_color = lcd_getfgcolor(); + int bg_color = lcd_getbgcolor(); + int i, row; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + pcons->lcdsizex + + pcons->lcdsizey * pcons->lcdsizex - + y * pcons->lcdsizex - + (x+1); + + for (row = 0; row < VIDEO_FONT_HEIGHT; row++) { + uchar bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row]; + + for (i = 0; i < VIDEO_FONT_WIDTH; ++i) { + *dst-- = (bits & 0x80) ? fg_color : bg_color; + bits <<= 1; + } + dst -= (pcons->lcdsizex - VIDEO_FONT_WIDTH); + } +} + +static inline void console_setrow180(struct console_t *pcons, u32 row, int clr) +{ + int i; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + (pcons->rows-row-1) * VIDEO_FONT_HEIGHT * + pcons->lcdsizex; + + for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++) + *dst++ = clr; +} + +static inline void console_moverow180(struct console_t *pcons, + u32 rowdst, u32 rowsrc) +{ + int i; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + (pcons->rows-rowdst-1) * VIDEO_FONT_HEIGHT * + pcons->lcdsizex; + + fbptr_t *src = (fbptr_t *)pcons->fbbase + + (pcons->rows-rowsrc-1) * VIDEO_FONT_HEIGHT * + pcons->lcdsizex; + + for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++) + *dst++ = *src++; +} + +static void lcd_putc_xy270(struct console_t *pcons, ushort x, ushort y, char c) +{ + int fg_color = lcd_getfgcolor(); + int bg_color = lcd_getbgcolor(); + int i, col; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + pcons->lcdsizey * pcons->lcdsizex - + (x+1) * pcons->lcdsizex + + y; + + uchar msk = 0x80; + uchar *pfont = video_fontdata + c * VIDEO_FONT_HEIGHT; + for (col = 0; col < VIDEO_FONT_WIDTH; ++col) { + for (i = 0; i < VIDEO_FONT_HEIGHT; ++i) + *dst++ = (*(pfont + i) & msk) ? fg_color : bg_color; + msk >>= 1; + dst -= (pcons->lcdsizex + VIDEO_FONT_HEIGHT); + } +} + +static inline void console_setrow270(struct console_t *pcons, u32 row, int clr) +{ + int i, j; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + row*VIDEO_FONT_HEIGHT; + + for (j = 0; j < pcons->lcdsizey; j++) { + for (i = 0; i < VIDEO_FONT_HEIGHT; i++) + *dst++ = clr; + dst += (pcons->lcdsizex - VIDEO_FONT_HEIGHT); + } +} + +static inline void console_moverow270(struct console_t *pcons, + u32 rowdst, u32 rowsrc) +{ + int i, j; + fbptr_t *dst = (fbptr_t *)pcons->fbbase + + rowdst*VIDEO_FONT_HEIGHT; + + fbptr_t *src = (fbptr_t *)pcons->fbbase + + rowsrc*VIDEO_FONT_HEIGHT; + + for (j = 0; j < pcons->lcdsizey; j++) { + for (i = 0; i < VIDEO_FONT_HEIGHT; i++) + *dst++ = *src++; + src += (pcons->lcdsizex - VIDEO_FONT_HEIGHT); + dst += (pcons->lcdsizex - VIDEO_FONT_HEIGHT); + } +} + +static void console_calc_rowcol_rot(struct console_t *pcons) +{ + if (pcons->lcdrot == 1 || pcons->lcdrot == 3) + console_calc_rowcol(pcons, pcons->lcdsizey, pcons->lcdsizex); + else + console_calc_rowcol(pcons, pcons->lcdsizex, pcons->lcdsizey); +} + +void lcd_init_console_rot(struct console_t *pcons) +{ + if (pcons->lcdrot == 0) { + return; + } else if (pcons->lcdrot == 1) { + pcons->fp_putc_xy = &lcd_putc_xy90; + pcons->fp_console_moverow = &console_moverow90; + pcons->fp_console_setrow = &console_setrow90; + } else if (pcons->lcdrot == 2) { + pcons->fp_putc_xy = &lcd_putc_xy180; + pcons->fp_console_moverow = &console_moverow180; + pcons->fp_console_setrow = &console_setrow180; + } else if (pcons->lcdrot == 3) { + pcons->fp_putc_xy = &lcd_putc_xy270; + pcons->fp_console_moverow = &console_moverow270; + pcons->fp_console_setrow = &console_setrow270; + } else { + printf("%s: invalid framebuffer rotation (%d)!\n", + __func__, pcons->lcdrot); + return; + } + console_calc_rowcol_rot(pcons); +} diff --git a/common/malloc_simple.c b/common/malloc_simple.c index 64ae036..d445199 100644 --- a/common/malloc_simple.c +++ b/common/malloc_simple.c @@ -8,6 +8,7 @@ #include <common.h> #include <malloc.h> +#include <mapmem.h> #include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/common/miiphyutil.c b/common/miiphyutil.c index 74812e6..c88c28a 100644 --- a/common/miiphyutil.c +++ b/common/miiphyutil.c @@ -11,6 +11,7 @@ */ #include <common.h> +#include <dm.h> #include <miiphy.h> #include <phy.h> diff --git a/common/spl/spl.c b/common/spl/spl.c index 8e1fb40..690c9b0 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -125,7 +125,7 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) typedef void __noreturn (*image_entry_noargs_t)(void); image_entry_noargs_t image_entry = - (image_entry_noargs_t) spl_image->entry_point; + (image_entry_noargs_t)(unsigned long)spl_image->entry_point; debug("image entry point: 0x%X\n", spl_image->entry_point); image_entry(); @@ -151,6 +151,8 @@ static void spl_ram_load_image(void) void board_init_r(gd_t *dummy1, ulong dummy2) { u32 boot_device; + int ret; + debug(">>spl:board_init_r()\n"); #if defined(CONFIG_SYS_SPL_MALLOC_START) @@ -158,12 +160,24 @@ void board_init_r(gd_t *dummy1, ulong dummy2) CONFIG_SYS_SPL_MALLOC_SIZE); gd->flags |= GD_FLG_FULL_MALLOC_INIT; #elif defined(CONFIG_SYS_MALLOC_F_LEN) - gd->malloc_limit = gd->malloc_base + CONFIG_SYS_MALLOC_F_LEN; + gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; gd->malloc_ptr = 0; #endif -#ifdef CONFIG_SPL_DM - dm_init_and_scan(true); -#endif + if (IS_ENABLED(CONFIG_OF_CONTROL) && + !IS_ENABLED(CONFIG_SPL_DISABLE_OF_CONTROL)) { + ret = fdtdec_setup(); + if (ret) { + debug("fdtdec_setup() returned error %d\n", ret); + hang(); + } + } + if (IS_ENABLED(CONFIG_SPL_DM)) { + ret = dm_init_and_scan(true); + if (ret) { + debug("dm_init_and_scan() returned error %d\n", ret); + hang(); + } + } #ifndef CONFIG_PPC /* diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c index b7801cb..b8c369d 100644 --- a/common/spl/spl_nand.c +++ b/common/spl/spl_nand.c @@ -91,7 +91,7 @@ void spl_nand_load_image(void) sizeof(*header), (void *)header); spl_parse_image_header(header); nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); + spl_image.size, (void *)(unsigned long)spl_image.load_addr); nand_deselect(); } #endif diff --git a/common/spl/spl_net.c b/common/spl/spl_net.c index ff53705..217a435 100644 --- a/common/spl/spl_net.c +++ b/common/spl/spl_net.c @@ -21,14 +21,14 @@ void spl_net_load_image(const char *device) env_relocate(); setenv("autoload", "yes"); load_addr = CONFIG_SYS_TEXT_BASE - sizeof(struct image_header); - rv = eth_initialize(gd->bd); + rv = eth_initialize(); if (rv == 0) { printf("No Ethernet devices found\n"); hang(); } if (device) setenv("ethact", device); - rv = NetLoop(BOOTP); + rv = net_loop(BOOTP); if (rv < 0) { printf("Problem booting with BOOTP\n"); hang(); diff --git a/common/update.c b/common/update.c index cc830a7..1c6aa18 100644 --- a/common/update.c +++ b/common/update.c @@ -39,8 +39,8 @@ #define CONFIG_UPDATE_TFTP_CNT_MAX 0 #endif -extern ulong TftpRRQTimeoutMSecs; -extern int TftpRRQTimeoutCountMax; +extern ulong tftp_timeout_ms; +extern int tftp_timeout_count_max; extern flash_info_t flash_info[]; extern ulong load_addr; @@ -55,22 +55,22 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr) rv = 0; /* save used globals and env variable */ - saved_timeout_msecs = TftpRRQTimeoutMSecs; - saved_timeout_count = TftpRRQTimeoutCountMax; + saved_timeout_msecs = tftp_timeout_ms; + saved_timeout_count = tftp_timeout_count_max; saved_netretry = strdup(getenv("netretry")); - saved_bootfile = strdup(BootFile); + saved_bootfile = strdup(net_boot_file_name); /* set timeouts for auto-update */ - TftpRRQTimeoutMSecs = msec_max; - TftpRRQTimeoutCountMax = cnt_max; + tftp_timeout_ms = msec_max; + tftp_timeout_count_max = cnt_max; /* we don't want to retry the connection if errors occur */ setenv("netretry", "no"); /* download the update file */ load_addr = addr; - copy_filename(BootFile, filename, sizeof(BootFile)); - size = NetLoop(TFTPGET); + copy_filename(net_boot_file_name, filename, sizeof(net_boot_file_name)); + size = net_loop(TFTPGET); if (size < 0) rv = 1; @@ -78,15 +78,16 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr) flush_cache(addr, size); /* restore changed globals and env variable */ - TftpRRQTimeoutMSecs = saved_timeout_msecs; - TftpRRQTimeoutCountMax = saved_timeout_count; + tftp_timeout_ms = saved_timeout_msecs; + tftp_timeout_count_max = saved_timeout_count; setenv("netretry", saved_netretry); if (saved_netretry != NULL) free(saved_netretry); if (saved_bootfile != NULL) { - copy_filename(BootFile, saved_bootfile, sizeof(BootFile)); + copy_filename(net_boot_file_name, saved_bootfile, + sizeof(net_boot_file_name)); free(saved_bootfile); } diff --git a/common/usb.c b/common/usb.c index d94640a..a4820d3 100644 --- a/common/usb.c +++ b/common/usb.c @@ -28,6 +28,7 @@ */ #include <common.h> #include <command.h> +#include <dm.h> #include <asm/processor.h> #include <linux/compiler.h> #include <linux/ctype.h> @@ -41,12 +42,13 @@ #define USB_BUFSIZ 512 -static struct usb_device usb_dev[USB_MAX_DEVICE]; -static int dev_index; static int asynch_allowed; - char usb_started; /* flag for the started/stopped USB status */ +#ifndef CONFIG_DM_USB +static struct usb_device usb_dev[USB_MAX_DEVICE]; +static int dev_index; + #ifndef CONFIG_USB_MAX_CONTROLLER_COUNT #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 #endif @@ -94,8 +96,8 @@ int usb_init(void) controllers_initialized++; start_index = dev_index; printf("scanning bus %d for devices... ", i); - dev = usb_alloc_new_device(ctrl); - if (!dev) + ret = usb_alloc_new_device(ctrl, &dev); + if (ret) break; /* @@ -104,7 +106,7 @@ int usb_init(void) */ ret = usb_new_device(dev); if (ret) - usb_free_device(); + usb_free_device(dev->controller); if (start_index == dev_index) { puts("No USB Device found\n"); @@ -158,6 +160,7 @@ int usb_disable_asynch(int disable) asynch_allowed = !disable; return old_value; } +#endif /* !CONFIG_DM_USB */ /*------------------------------------------------------------------- @@ -821,6 +824,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) * the USB device are static allocated [USB_MAX_DEVICE]. */ +#ifndef CONFIG_DM_USB /* returns a pointer to the device with the index [index]. * if the device is not assigned (dev->devnum==-1) returns NULL @@ -833,16 +837,13 @@ struct usb_device *usb_get_dev_index(int index) return &usb_dev[index]; } -/* returns a pointer of a new device structure or NULL, if - * no device struct is available - */ -struct usb_device *usb_alloc_new_device(void *controller) +int usb_alloc_new_device(struct udevice *controller, struct usb_device **devp) { int i; debug("New Device %d\n", dev_index); if (dev_index == USB_MAX_DEVICE) { printf("ERROR, too many USB Devices, max=%d\n", USB_MAX_DEVICE); - return NULL; + return -ENOSPC; } /* default Address is 0, real addresses start with 1 */ usb_dev[dev_index].devnum = dev_index + 1; @@ -852,7 +853,9 @@ struct usb_device *usb_alloc_new_device(void *controller) usb_dev[dev_index].parent = NULL; usb_dev[dev_index].controller = controller; dev_index++; - return &usb_dev[dev_index - 1]; + *devp = &usb_dev[dev_index - 1]; + + return 0; } /* @@ -860,7 +863,7 @@ struct usb_device *usb_alloc_new_device(void *controller) * Called in error cases where configuring a newly attached * device fails for some reason. */ -void usb_free_device(void) +void usb_free_device(struct udevice *controller) { dev_index--; debug("Freeing device node: %d\n", dev_index); @@ -878,123 +881,101 @@ __weak int usb_alloc_device(struct usb_device *udev) { return 0; } -/* - * By the time we get here, the device has gotten a new device ID - * and is in the default state. We need to identify the thing and - * get the ball rolling.. - * - * Returns 0 for success, != 0 for error. - */ -int usb_new_device(struct usb_device *dev) +#endif /* !CONFIG_DM_USB */ + +#ifndef CONFIG_DM_USB +int usb_legacy_port_reset(struct usb_device *hub, int portnr) { - int addr, err; - int tmp; - ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ); + if (hub) { + unsigned short portstatus; + int err; - /* - * Allocate usb 3.0 device context. - * USB 3.0 (xHCI) protocol tries to allocate device slot - * and related data structures first. This call does that. - * Refer to sec 4.3.2 in xHCI spec rev1.0 - */ - if (usb_alloc_device(dev)) { - printf("Cannot allocate device context to get SLOT_ID\n"); - return -EINVAL; + /* reset the port for the second time */ + err = legacy_hub_port_reset(hub, portnr - 1, &portstatus); + if (err < 0) { + printf("\n Couldn't reset port %i\n", portnr); + return err; + } + } else { + usb_reset_root_port(); } - /* We still haven't set the Address yet */ - addr = dev->devnum; - dev->devnum = 0; + return 0; +} +#endif -#ifdef CONFIG_LEGACY_USB_INIT_SEQ - /* this is the old and known way of initializing devices, it is - * different than what Windows and Linux are doing. Windows and Linux - * both retrieve 64 bytes while reading the device descriptor - * Several USB stick devices report ERR: CTL_TIMEOUT, caused by an - * invalid header while reading 8 bytes as device descriptor. */ - dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */ - dev->maxpacketsize = PACKET_SIZE_8; - dev->epmaxpacketin[0] = 8; - dev->epmaxpacketout[0] = 8; - - err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, tmpbuf, 8); - if (err < 8) { - printf("\n USB device not responding, " \ - "giving up (status=%lX)\n", dev->status); - return -EIO; +static int get_descriptor_len(struct usb_device *dev, int len, int expect_len) +{ + __maybe_unused struct usb_device_descriptor *desc; + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ); + int err; + + desc = (struct usb_device_descriptor *)tmpbuf; + + err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, len); + if (err < expect_len) { + if (err < 0) { + printf("unable to get device descriptor (error=%d)\n", + err); + return err; + } else { + printf("USB device descriptor short read (expected %i, got %i)\n", + expect_len, err); + return -EIO; + } } - memcpy(&dev->descriptor, tmpbuf, 8); -#else - /* This is a Windows scheme of initialization sequence, with double + memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor)); + + return 0; +} + +static int usb_setup_descriptor(struct usb_device *dev, bool do_read) +{ + __maybe_unused struct usb_device_descriptor *desc; + + /* + * This is a Windows scheme of initialization sequence, with double * reset of the device (Linux uses the same sequence) * Some equipment is said to work only with such init sequence; this * patch is based on the work by Alan Stern: * http://sourceforge.net/mailarchive/forum.php? * thread_id=5729457&forum_id=5398 */ - __maybe_unused struct usb_device_descriptor *desc; - struct usb_device *parent = dev->parent; - unsigned short portstatus; - /* send 64-byte GET-DEVICE-DESCRIPTOR request. Since the descriptor is + /* + * send 64-byte GET-DEVICE-DESCRIPTOR request. Since the descriptor is * only 18 bytes long, this will terminate with a short packet. But if * the maxpacket size is 8 or 16 the device may be waiting to transmit * some more, or keeps on retransmitting the 8 byte header. */ - desc = (struct usb_device_descriptor *)tmpbuf; dev->descriptor.bMaxPacketSize0 = 64; /* Start off at 64 bytes */ /* Default to 64 byte max packet size */ dev->maxpacketsize = PACKET_SIZE_64; dev->epmaxpacketin[0] = 64; dev->epmaxpacketout[0] = 64; - /* - * XHCI needs to issue a Address device command to setup - * proper device context structures, before it can interact - * with the device. So a get_descriptor will fail before any - * of that is done for XHCI unlike EHCI. - */ -#ifndef CONFIG_USB_XHCI - err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64); - /* - * Validate we've received only at least 8 bytes, not that we've - * received the entire descriptor. The reasoning is: - * - The code only uses fields in the first 8 bytes, so that's all we - * need to have fetched at this stage. - * - The smallest maxpacket size is 8 bytes. Before we know the actual - * maxpacket the device uses, the USB controller may only accept a - * single packet. Consequently we are only guaranteed to receive 1 - * packet (at least 8 bytes) even in a non-error case. - * - * At least the DWC2 controller needs to be programmed with the number - * of packets in addition to the number of bytes. A request for 64 - * bytes of data with the maxpacket guessed as 64 (above) yields a - * request for 1 packet. - */ - if (err < 8) { - debug("usb_new_device: usb_get_descriptor() failed\n"); - return -EIO; - } - - dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0; - /* - * Fetch the device class, driver can use this info - * to differentiate between HUB and DEVICE. - */ - dev->descriptor.bDeviceClass = desc->bDeviceClass; -#endif + if (do_read) { + int err; - if (parent) { - /* reset the port for the second time */ - err = hub_port_reset(dev->parent, dev->portnr - 1, &portstatus); - if (err < 0) { - printf("\n Couldn't reset port %i\n", dev->portnr); - return -EIO; - } - } else { - usb_reset_root_port(); + /* + * Validate we've received only at least 8 bytes, not that we've + * received the entire descriptor. The reasoning is: + * - The code only uses fields in the first 8 bytes, so that's all we + * need to have fetched at this stage. + * - The smallest maxpacket size is 8 bytes. Before we know the actual + * maxpacket the device uses, the USB controller may only accept a + * single packet. Consequently we are only guaranteed to receive 1 + * packet (at least 8 bytes) even in a non-error case. + * + * At least the DWC2 controller needs to be programmed with the number + * of packets in addition to the number of bytes. A request for 64 + * bytes of data with the maxpacket guessed as 64 (above) yields a + * request for 1 packet. + */ + err = get_descriptor_len(dev, 64, 8); + if (err) + return err; } -#endif dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0; dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; @@ -1015,6 +996,33 @@ int usb_new_device(struct usb_device *dev) printf("usb_new_device: invalid max packet size\n"); return -EIO; } + + return 0; +} + +static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read, + struct usb_device *parent, int portnr) +{ + int err; + + /* + * Allocate usb 3.0 device context. + * USB 3.0 (xHCI) protocol tries to allocate device slot + * and related data structures first. This call does that. + * Refer to sec 4.3.2 in xHCI spec rev1.0 + */ + err = usb_alloc_device(dev); + if (err) { + printf("Cannot allocate device context to get SLOT_ID\n"); + return err; + } + err = usb_setup_descriptor(dev, do_read); + if (err) + return err; + err = usb_legacy_port_reset(parent, portnr); + if (err) + return err; + dev->devnum = addr; err = usb_set_address(dev); /* set address */ @@ -1022,45 +1030,49 @@ int usb_new_device(struct usb_device *dev) if (err < 0) { printf("\n USB device not accepting new address " \ "(error=%lX)\n", dev->status); - return -EIO; + return err; } mdelay(10); /* Let the SET_ADDRESS settle */ - tmp = sizeof(dev->descriptor); + return 0; +} + +int usb_select_config(struct usb_device *dev) +{ + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ); + int err; + + err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE); + if (err) + return err; - err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, - tmpbuf, sizeof(dev->descriptor)); - if (err < tmp) { - if (err < 0) - printf("unable to get device descriptor (error=%d)\n", - err); - else - printf("USB device descriptor short read " \ - "(expected %i, got %i)\n", tmp, err); - return -EIO; - } - memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor)); /* correct le values */ le16_to_cpus(&dev->descriptor.bcdUSB); le16_to_cpus(&dev->descriptor.idVendor); le16_to_cpus(&dev->descriptor.idProduct); le16_to_cpus(&dev->descriptor.bcdDevice); + /* only support for one config for now */ err = usb_get_configuration_no(dev, tmpbuf, 0); if (err < 0) { printf("usb_new_device: Cannot read configuration, " \ "skipping device %04x:%04x\n", dev->descriptor.idVendor, dev->descriptor.idProduct); - return -EIO; + return err; } usb_parse_config(dev, tmpbuf, 0); usb_set_maxpacket(dev); - /* we set the default configuration here */ - if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) { + /* + * we set the default configuration here + * This seems premature. If the driver wants a different configuration + * it will need to select itself. + */ + err = usb_set_configuration(dev, dev->config.desc.bConfigurationValue); + if (err < 0) { printf("failed to set default configuration " \ "len %d, status %lX\n", dev->act_len, dev->status); - return -EIO; + return err; } debug("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n", dev->descriptor.iManufacturer, dev->descriptor.iProduct, @@ -1080,11 +1092,63 @@ int usb_new_device(struct usb_device *dev) debug("Manufacturer %s\n", dev->mf); debug("Product %s\n", dev->prod); debug("SerialNumber %s\n", dev->serial); - /* now prode if the device is a hub */ - usb_hub_probe(dev, 0); + return 0; } +int usb_setup_device(struct usb_device *dev, bool do_read, + struct usb_device *parent, int portnr) +{ + int addr; + int ret; + + /* We still haven't set the Address yet */ + addr = dev->devnum; + dev->devnum = 0; + + ret = usb_prepare_device(dev, addr, do_read, parent, portnr); + if (ret) + return ret; + ret = usb_select_config(dev); + + return ret; +} + +#ifndef CONFIG_DM_USB +/* + * By the time we get here, the device has gotten a new device ID + * and is in the default state. We need to identify the thing and + * get the ball rolling.. + * + * Returns 0 for success, != 0 for error. + */ +int usb_new_device(struct usb_device *dev) +{ + bool do_read = true; + int err; + + /* + * XHCI needs to issue a Address device command to setup + * proper device context structures, before it can interact + * with the device. So a get_descriptor will fail before any + * of that is done for XHCI unlike EHCI. + */ +#ifdef CONFIG_USB_XHCI + do_read = false; +#endif + err = usb_setup_device(dev, do_read, dev->parent, dev->portnr); + if (err) + return err; + + /* Now probe if the device is a hub */ + err = usb_hub_probe(dev, 0); + if (err < 0) + return err; + + return 0; +} +#endif + __weak int board_usb_init(int index, enum usb_init_type init) { @@ -1096,4 +1160,14 @@ int board_usb_cleanup(int index, enum usb_init_type init) { return 0; } + +bool usb_device_has_child_on_port(struct usb_device *parent, int port) +{ +#ifdef CONFIG_DM_USB + return false; +#else + return parent->children[port] != NULL; +#endif +} + /* EOF */ diff --git a/common/usb_hub.c b/common/usb_hub.c index f54a404..c9be530 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -24,11 +24,16 @@ #include <common.h> #include <command.h> +#include <dm.h> +#include <errno.h> #include <asm/processor.h> #include <asm/unaligned.h> #include <linux/ctype.h> #include <asm/byteorder.h> #include <asm/unaligned.h> +#include <dm/root.h> + +DECLARE_GLOBAL_DATA_PTR; #include <usb.h> #ifdef CONFIG_4xx @@ -37,6 +42,7 @@ #define USB_BUFSIZ 512 +/* TODO(sjg@chromium.org): Remove this when CONFIG_DM_USB is defined */ static struct usb_hub_device hub_dev[USB_MAX_HUB]; static int usb_hub_index; @@ -148,14 +154,19 @@ static inline char *portspeed(int portstatus) return speed_str; } -int hub_port_reset(struct usb_device *dev, int port, +int legacy_hub_port_reset(struct usb_device *dev, int port, unsigned short *portstat) { int tries; ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); unsigned short portstatus, portchange; - debug("hub_port_reset: resetting port %d...\n", port); +#ifdef CONFIG_DM_USB + debug("%s: resetting '%s' port %d...\n", __func__, dev->dev->name, + port + 1); +#else + debug("%s: resetting port %d...\n", __func__, port + 1); +#endif for (tries = 0; tries < MAX_TRIES; tries++) { usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET); @@ -213,17 +224,26 @@ int hub_port_reset(struct usb_device *dev, int port, return 0; } +#ifdef CONFIG_DM_USB +int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat) +{ + struct usb_device *udev = dev_get_parentdata(dev); -void usb_hub_port_connect_change(struct usb_device *dev, int port) + return legacy_hub_port_reset(udev, port, portstat); +} +#endif + +int usb_hub_port_connect_change(struct usb_device *dev, int port) { - struct usb_device *usb; ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); unsigned short portstatus; + int ret, speed; /* Check status */ - if (usb_get_port_status(dev, port + 1, portsts) < 0) { + ret = usb_get_port_status(dev, port + 1, portsts); + if (ret < 0) { debug("get_port_status failed\n"); - return; + return ret; } portstatus = le16_to_cpu(portsts->wPortStatus); @@ -237,51 +257,70 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port) /* Disconnect any existing devices under this port */ if (((!(portstatus & USB_PORT_STAT_CONNECTION)) && - (!(portstatus & USB_PORT_STAT_ENABLE))) || (dev->children[port])) { + (!(portstatus & USB_PORT_STAT_ENABLE))) || + usb_device_has_child_on_port(dev, port)) { debug("usb_disconnect(&hub->children[port]);\n"); /* Return now if nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) - return; + return -ENOTCONN; } mdelay(200); /* Reset the port */ - if (hub_port_reset(dev, port, &portstatus) < 0) { + ret = legacy_hub_port_reset(dev, port, &portstatus); + if (ret < 0) { printf("cannot reset port %i!?\n", port + 1); - return; + return ret; } mdelay(200); - /* Allocate a new device struct for it */ - usb = usb_alloc_new_device(dev->controller); - switch (portstatus & USB_PORT_STAT_SPEED_MASK) { case USB_PORT_STAT_SUPER_SPEED: - usb->speed = USB_SPEED_SUPER; + speed = USB_SPEED_SUPER; break; case USB_PORT_STAT_HIGH_SPEED: - usb->speed = USB_SPEED_HIGH; + speed = USB_SPEED_HIGH; break; case USB_PORT_STAT_LOW_SPEED: - usb->speed = USB_SPEED_LOW; + speed = USB_SPEED_LOW; break; default: - usb->speed = USB_SPEED_FULL; + speed = USB_SPEED_FULL; break; } +#ifdef CONFIG_DM_USB + struct udevice *child; + + ret = usb_scan_device(dev->dev, port + 1, speed, &child); +#else + struct usb_device *usb; + + ret = usb_alloc_new_device(dev->controller, &usb); + if (ret) { + printf("cannot create new device: ret=%d", ret); + return ret; + } + dev->children[port] = usb; + usb->speed = speed; usb->parent = dev; usb->portnr = port + 1; /* Run it through the hoops (find a driver, etc) */ - if (usb_new_device(usb)) { + ret = usb_new_device(usb); + if (ret < 0) { /* Woops, disable the port */ - usb_free_device(); + usb_free_device(dev->controller); dev->children[port] = NULL; + } +#endif + if (ret < 0) { debug("hub: disabling port %d\n", port + 1); usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE); } + + return ret; } @@ -294,27 +333,30 @@ static int usb_hub_configure(struct usb_device *dev) struct usb_hub_descriptor *descriptor; struct usb_hub_device *hub; __maybe_unused struct usb_hub_status *hubsts; + int ret; /* "allocate" Hub device */ hub = usb_hub_allocate(); if (hub == NULL) - return -1; + return -ENOMEM; hub->pusb_dev = dev; /* Get the the hub descriptor */ - if (usb_get_hub_descriptor(dev, buffer, 4) < 0) { + ret = usb_get_hub_descriptor(dev, buffer, 4); + if (ret < 0) { debug("usb_hub_configure: failed to get hub " \ "descriptor, giving up %lX\n", dev->status); - return -1; + return ret; } descriptor = (struct usb_hub_descriptor *)buffer; length = min_t(int, descriptor->bLength, sizeof(struct usb_hub_descriptor)); - if (usb_get_hub_descriptor(dev, buffer, length) < 0) { + ret = usb_get_hub_descriptor(dev, buffer, length); + if (ret < 0) { debug("usb_hub_configure: failed to get hub " \ "descriptor 2nd giving up %lX\n", dev->status); - return -1; + return ret; } memcpy((unsigned char *)&hub->desc, buffer, length); /* adjust 16bit values */ @@ -382,13 +424,14 @@ static int usb_hub_configure(struct usb_device *dev) if (sizeof(struct usb_hub_status) > USB_BUFSIZ) { debug("usb_hub_configure: failed to get Status - " \ "too long: %d\n", descriptor->bLength); - return -1; + return -EFBIG; } - if (usb_get_hub_status(dev, buffer) < 0) { + ret = usb_get_hub_status(dev, buffer); + if (ret < 0) { debug("usb_hub_configure: failed to get Status %lX\n", dev->status); - return -1; + return ret; } #ifdef DEBUG @@ -420,6 +463,11 @@ static int usb_hub_configure(struct usb_device *dev) int ret; ulong start = get_timer(0); +#ifdef CONFIG_DM_USB + debug("\n\nScanning '%s' port %d\n", dev->dev->name, i + 1); +#else + debug("\n\nScanning port %d\n", i + 1); +#endif /* * Wait for (whichever finishes first) * - A maximum of 10 seconds @@ -469,7 +517,7 @@ static int usb_hub_configure(struct usb_device *dev) * them again. Works at least with mouse driver */ if (!(portstatus & USB_PORT_STAT_ENABLE) && (portstatus & USB_PORT_STAT_CONNECTION) && - ((dev->children[i]))) { + usb_device_has_child_on_port(dev, i)) { debug("already running port %i " \ "disabled by hub (EMI?), " \ "re-enabling...\n", i + 1); @@ -500,33 +548,107 @@ static int usb_hub_configure(struct usb_device *dev) return 0; } -int usb_hub_probe(struct usb_device *dev, int ifnum) +static int usb_hub_check(struct usb_device *dev, int ifnum) { struct usb_interface *iface; - struct usb_endpoint_descriptor *ep; - int ret; + struct usb_endpoint_descriptor *ep = NULL; iface = &dev->config.if_desc[ifnum]; /* Is it a hub? */ if (iface->desc.bInterfaceClass != USB_CLASS_HUB) - return 0; + goto err; /* Some hubs have a subclass of 1, which AFAICT according to the */ /* specs is not defined, but it works */ if ((iface->desc.bInterfaceSubClass != 0) && (iface->desc.bInterfaceSubClass != 1)) - return 0; + goto err; /* Multiple endpoints? What kind of mutant ninja-hub is this? */ if (iface->desc.bNumEndpoints != 1) - return 0; + goto err; ep = &iface->ep_desc[0]; /* Output endpoint? Curiousier and curiousier.. */ if (!(ep->bEndpointAddress & USB_DIR_IN)) - return 0; + goto err; /* If it's not an interrupt endpoint, we'd better punt! */ if ((ep->bmAttributes & 3) != 3) - return 0; + goto err; /* We found a hub */ debug("USB hub found\n"); + return 0; + +err: + debug("USB hub not found: bInterfaceClass=%d, bInterfaceSubClass=%d, bNumEndpoints=%d\n", + iface->desc.bInterfaceClass, iface->desc.bInterfaceSubClass, + iface->desc.bNumEndpoints); + if (ep) { + debug(" bEndpointAddress=%#x, bmAttributes=%d", + ep->bEndpointAddress, ep->bmAttributes); + } + + return -ENOENT; +} + +int usb_hub_probe(struct usb_device *dev, int ifnum) +{ + int ret; + + ret = usb_hub_check(dev, ifnum); + if (ret) + return 0; ret = usb_hub_configure(dev); return ret; } + +#ifdef CONFIG_DM_USB +int usb_hub_scan(struct udevice *hub) +{ + struct usb_device *udev = dev_get_parentdata(hub); + + return usb_hub_configure(udev); +} + +static int usb_hub_post_bind(struct udevice *dev) +{ + /* Scan the bus for devices */ + return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); +} + +static int usb_hub_post_probe(struct udevice *dev) +{ + debug("%s\n", __func__); + return usb_hub_scan(dev); +} + +static const struct udevice_id usb_hub_ids[] = { + { .compatible = "usb-hub" }, + { } +}; + +U_BOOT_DRIVER(usb_generic_hub) = { + .name = "usb_hub", + .id = UCLASS_USB_HUB, + .of_match = usb_hub_ids, + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; + +UCLASS_DRIVER(usb_hub) = { + .id = UCLASS_USB_HUB, + .name = "usb_hub", + .post_bind = usb_hub_post_bind, + .post_probe = usb_hub_post_probe, + .child_pre_probe = usb_child_pre_probe, + .per_child_auto_alloc_size = sizeof(struct usb_device), + .per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata), +}; + +static const struct usb_device_id hub_id_table[] = { + { + .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS, + .bDeviceClass = USB_CLASS_HUB + }, + { } /* Terminating entry */ +}; + +USB_DEVICE(usb_generic_hub, hub_id_table); + +#endif diff --git a/common/usb_kbd.c b/common/usb_kbd.c index ecc3085..24a1a56 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -8,6 +8,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <dm.h> #include <errno.h> #include <malloc.h> #include <stdio_dev.h> @@ -471,60 +472,104 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) return 1; } +static int probe_usb_keyboard(struct usb_device *dev) +{ + char *stdinname; + struct stdio_dev usb_kbd_dev; + int error; + + /* Try probing the keyboard */ + if (usb_kbd_probe(dev, 0) != 1) + return -ENOENT; + + /* Register the keyboard */ + debug("USB KBD: register.\n"); + memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev)); + strcpy(usb_kbd_dev.name, DEVNAME); + usb_kbd_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; + usb_kbd_dev.getc = usb_kbd_getc; + usb_kbd_dev.tstc = usb_kbd_testc; + usb_kbd_dev.priv = (void *)dev; + error = stdio_register(&usb_kbd_dev); + if (error) + return error; + + stdinname = getenv("stdin"); +#ifdef CONFIG_CONSOLE_MUX + error = iomux_doenv(stdin, stdinname); + if (error) + return error; +#else + /* Check if this is the standard input device. */ + if (strcmp(stdinname, DEVNAME)) + return 1; + + /* Reassign the console */ + if (overwrite_console()) + return 1; + + error = console_assign(stdin, DEVNAME); + if (error) + return error; +#endif + + return 0; +} + /* Search for keyboard and register it if found. */ int drv_usb_kbd_init(void) { - struct stdio_dev usb_kbd_dev; - struct usb_device *dev; - char *stdinname = getenv("stdin"); int error, i; + debug("%s: Probing for keyboard\n", __func__); +#ifdef CONFIG_DM_USB + /* + * TODO: We should add USB_DEVICE() declarations to each USB ethernet + * driver and then most of this file can be removed. + */ + struct udevice *bus; + struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_USB, &uc); + if (ret) + return ret; + uclass_foreach_dev(bus, uc) { + for (i = 0; i < USB_MAX_DEVICE; i++) { + struct usb_device *dev; + + dev = usb_get_dev_index(bus, i); /* get device */ + debug("i=%d, %p\n", i, dev); + if (!dev) + break; /* no more devices available */ + + error = probe_usb_keyboard(dev); + if (!error) + return 1; + if (error && error != -ENOENT) + return error; + } /* for */ + } +#else /* Scan all USB Devices */ for (i = 0; i < USB_MAX_DEVICE; i++) { + struct usb_device *dev; + /* Get USB device. */ dev = usb_get_dev_index(i); if (!dev) - return -1; + break; if (dev->devnum == -1) continue; - /* Try probing the keyboard */ - if (usb_kbd_probe(dev, 0) != 1) - continue; - - /* Register the keyboard */ - debug("USB KBD: register.\n"); - memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev)); - strcpy(usb_kbd_dev.name, DEVNAME); - usb_kbd_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; - usb_kbd_dev.getc = usb_kbd_getc; - usb_kbd_dev.tstc = usb_kbd_testc; - usb_kbd_dev.priv = (void *)dev; - error = stdio_register(&usb_kbd_dev); - if (error) - return error; - -#ifdef CONFIG_CONSOLE_MUX - error = iomux_doenv(stdin, stdinname); - if (error) - return error; -#else - /* Check if this is the standard input device. */ - if (strcmp(stdinname, DEVNAME)) - return 1; - - /* Reassign the console */ - if (overwrite_console()) + error = probe_usb_keyboard(dev); + if (!error) return 1; - - error = console_assign(stdin, DEVNAME); - if (error) + if (error && error != -ENOENT) return error; -#endif - - return 1; } +#endif /* No USB Keyboard found */ return -1; diff --git a/common/usb_storage.c b/common/usb_storage.c index a4ca7a5..cc9b3e3 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -9,6 +9,8 @@ * * Adapted for U-Boot: * (C) Copyright 2001 Denis Peter, MPL AG Switzerland + * Driver model conversion: + * (C) Copyright 2015 Google, Inc * * For BBB support (C) Copyright 2003 * Gary Jennejohn, DENX Software Engineering <garyj@denx.de> @@ -33,9 +35,13 @@ #include <common.h> #include <command.h> +#include <dm.h> +#include <errno.h> #include <inttypes.h> +#include <mapmem.h> #include <asm/byteorder.h> #include <asm/processor.h> +#include <dm/device-internal.h> #include <part.h> #include <usb.h> @@ -56,49 +62,8 @@ static const unsigned char us_direction[256/8] = { #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1) static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN))); - -/* - * CBI style - */ - -#define US_CBI_ADSC 0 - -/* - * BULK only - */ -#define US_BBB_RESET 0xff -#define US_BBB_GET_MAX_LUN 0xfe - -/* Command Block Wrapper */ -typedef struct { - __u32 dCBWSignature; -# define CBWSIGNATURE 0x43425355 - __u32 dCBWTag; - __u32 dCBWDataTransferLength; - __u8 bCBWFlags; -# define CBWFLAGS_OUT 0x00 -# define CBWFLAGS_IN 0x80 - __u8 bCBWLUN; - __u8 bCDBLength; -# define CBWCDBLENGTH 16 - __u8 CBWCDB[CBWCDBLENGTH]; -} umass_bbb_cbw_t; -#define UMASS_BBB_CBW_SIZE 31 static __u32 CBWTag; -/* Command Status Wrapper */ -typedef struct { - __u32 dCSWSignature; -# define CSWSIGNATURE 0x53425355 - __u32 dCSWTag; - __u32 dCSWDataResidue; - __u8 bCSWStatus; -# define CSWSTATUS_GOOD 0x0 -# define CSWSTATUS_FAILED 0x1 -# define CSWSTATUS_PHASE 0x2 -} umass_bbb_csw_t; -#define UMASS_BBB_CSW_SIZE 13 - #define USB_MAX_STOR_DEV 5 static int usb_max_devs; /* number of highest available usb device */ @@ -145,7 +110,6 @@ struct us_data { static struct us_data usb_stor[USB_MAX_STOR_DEV]; - #define USB_STOR_TRANSPORT_GOOD 0 #define USB_STOR_TRANSPORT_FAILED -1 #define USB_STOR_TRANSPORT_ERROR -2 @@ -158,7 +122,6 @@ unsigned long usb_stor_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer); unsigned long usb_stor_write(int device, lbaint_t blknr, lbaint_t blkcnt, const void *buffer); -struct usb_device * usb_get_dev_index(int index); void uhci_show_temp_int_td(void); #ifdef CONFIG_PARTITIONS @@ -208,30 +171,61 @@ static unsigned int usb_get_max_lun(struct us_data *us) return (len > 0) ? *result : 0; } -static int usb_storage_register(struct usb_device *dev, unsigned char iface) +static int usb_stor_probe_device(struct usb_device *dev) { - int lun, max_lun, start = usb_max_devs; - int nb_dev = 0; - - if (!usb_storage_probe(dev, iface, &usb_stor[usb_max_devs])) - return nb_dev; - - /* - * OK, it's a storage device. Iterate over its LUNs - * and populate `usb_dev_desc'. - */ - max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]); - for (lun = 0; lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV; lun++) { - usb_dev_desc[usb_max_devs].lun = lun; - if (usb_stor_get_info(dev, &usb_stor[start], - &usb_dev_desc[usb_max_devs]) == 1) { - nb_dev++; + if (dev == NULL) + return -ENOENT; /* no more devices available */ + + debug("\n\nProbing for storage\n"); + if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) { + /* OK, it's a storage device. Iterate over its LUNs + * and populate `usb_dev_desc'. + */ + int lun, max_lun, start = usb_max_devs; + + max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]); + for (lun = 0; + lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV; + lun++) { + struct block_dev_desc *blkdev; + + blkdev = &usb_dev_desc[usb_max_devs]; + memset(blkdev, '\0', sizeof(block_dev_desc_t)); + blkdev->if_type = IF_TYPE_USB; + blkdev->dev = usb_max_devs; + blkdev->part_type = PART_TYPE_UNKNOWN; + blkdev->target = 0xff; + blkdev->type = DEV_TYPE_UNKNOWN; + blkdev->block_read = usb_stor_read; + blkdev->block_write = usb_stor_write; + blkdev->lun = lun; + blkdev->priv = dev; + + if (usb_stor_get_info(dev, &usb_stor[start], + &usb_dev_desc[usb_max_devs]) == + 1) { + usb_max_devs++; + debug("%s: Found device %p\n", __func__, dev); + } } } - return nb_dev; + /* if storage device */ + if (usb_max_devs == USB_MAX_STOR_DEV) { + printf("max USB Storage Device reached: %d stopping\n", + usb_max_devs); + return -ENOSPC; + } + + return 0; +} + +void usb_stor_reset(void) +{ + usb_max_devs = 0; } +#ifndef CONFIG_DM_USB /******************************************************************************* * scan the usb and reports device info * to the user if mode = 1 @@ -239,42 +233,21 @@ static int usb_storage_register(struct usb_device *dev, unsigned char iface) */ int usb_stor_scan(int mode) { - unsigned char i, iface; - struct usb_device *dev; + unsigned char i; if (mode == 1) printf(" scanning usb for storage devices... "); usb_disable_asynch(1); /* asynch transfer not allowed */ - for (i = 0; i < USB_MAX_STOR_DEV; i++) { - memset(&usb_dev_desc[i], 0, sizeof(block_dev_desc_t)); - usb_dev_desc[i].if_type = IF_TYPE_USB; - usb_dev_desc[i].dev = i; - usb_dev_desc[i].part_type = PART_TYPE_UNKNOWN; - usb_dev_desc[i].target = 0xff; - usb_dev_desc[i].type = DEV_TYPE_UNKNOWN; - usb_dev_desc[i].block_read = usb_stor_read; - usb_dev_desc[i].block_write = usb_stor_write; - } - - usb_max_devs = 0; + usb_stor_reset(); for (i = 0; i < USB_MAX_DEVICE; i++) { + struct usb_device *dev; + dev = usb_get_dev_index(i); /* get device */ debug("i=%d\n", i); - if (dev == NULL) - break; /* no more devices available */ - - for (iface = 0; iface < dev->config.no_of_if; iface++) { - usb_max_devs += usb_storage_register(dev, iface); - } - - /* if storage device */ - if (usb_max_devs == USB_MAX_STOR_DEV) { - printf("max USB Storage Device reached: %d stopping\n", - usb_max_devs); + if (usb_stor_probe_device(dev)) break; - } } /* for */ usb_disable_asynch(0); /* asynch transfer allowed */ @@ -283,6 +256,7 @@ int usb_stor_scan(int mode) return 0; return -1; } +#endif static int usb_stor_irq(struct usb_device *dev) { @@ -347,8 +321,9 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length) /* set up the transfer loop */ do { /* transfer the data */ - debug("Bulk xfer %p(%d) try #%d\n", - buf, this_xfer, 11 - maxtry); + debug("Bulk xfer 0x%lx(%d) try #%d\n", + (ulong)map_to_sysmem(buf), this_xfer, + 11 - maxtry); result = usb_bulk_msg(us->pusb_dev, pipe, buf, this_xfer, &partial, USB_CNTL_TIMEOUT * 5); @@ -494,7 +469,7 @@ static int usb_stor_BBB_comdat(ccb *srb, struct us_data *us) int actlen; int dir_in; unsigned int pipe; - ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1); + ALLOC_CACHE_ALIGN_BUFFER(struct umass_bbb_cbw, cbw, 1); dir_in = US_DIRECTION(srb->cmd[0]); @@ -670,7 +645,7 @@ static int usb_stor_BBB_transport(ccb *srb, struct us_data *us) int dir_in; int actlen, data_actlen; unsigned int pipe, pipein, pipeout; - ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1); + ALLOC_CACHE_ALIGN_BUFFER(struct umass_bbb_csw, csw, 1); #ifdef BBB_XPORT_TRACE unsigned char *ptr; int index; @@ -1059,7 +1034,7 @@ unsigned long usb_stor_read(int device, lbaint_t blknr, unsigned short smallblks; struct usb_device *dev; struct us_data *ss; - int retry, i; + int retry; ccb *srb = &usb_ccb; if (blkcnt == 0) @@ -1067,14 +1042,11 @@ unsigned long usb_stor_read(int device, lbaint_t blknr, device &= 0xff; /* Setup device */ - debug("\nusb_read: dev %d \n", device); - dev = NULL; - for (i = 0; i < USB_MAX_DEVICE; i++) { - dev = usb_get_dev_index(i); - if (dev == NULL) - return 0; - if (dev->devnum == usb_dev_desc[device].target) - break; + debug("\nusb_read: dev %d\n", device); + dev = usb_dev_desc[device].priv; + if (!dev) { + debug("%s: No device\n", __func__); + return 0; } ss = (struct us_data *)dev->privptr; @@ -1132,7 +1104,7 @@ unsigned long usb_stor_write(int device, lbaint_t blknr, unsigned short smallblks; struct usb_device *dev; struct us_data *ss; - int retry, i; + int retry; ccb *srb = &usb_ccb; if (blkcnt == 0) @@ -1140,15 +1112,10 @@ unsigned long usb_stor_write(int device, lbaint_t blknr, device &= 0xff; /* Setup device */ - debug("\nusb_write: dev %d \n", device); - dev = NULL; - for (i = 0; i < USB_MAX_DEVICE; i++) { - dev = usb_get_dev_index(i); - if (dev == NULL) - return 0; - if (dev->devnum == usb_dev_desc[device].target) - break; - } + debug("\nusb_write: dev %d\n", device); + dev = usb_dev_desc[device].priv; + if (!dev) + return 0; ss = (struct us_data *)dev->privptr; usb_disable_asynch(1); /* asynch transfer not allowed */ @@ -1232,6 +1199,7 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum, iface->desc.bInterfaceClass != USB_CLASS_MASS_STORAGE || iface->desc.bInterfaceSubClass < US_SC_MIN || iface->desc.bInterfaceSubClass > US_SC_MAX) { + debug("Not mass storage\n"); /* if it's not a mass storage, we go no further */ return 0; } @@ -1358,8 +1326,10 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss, pccb->lun = dev_desc->lun; debug(" address %d\n", dev_desc->target); - if (usb_inquiry(pccb, ss)) + if (usb_inquiry(pccb, ss)) { + debug("%s: usb_inquiry() failed\n", __func__); return -1; + } perq = usb_stor_buf[0]; modi = usb_stor_buf[1]; @@ -1369,6 +1339,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss, * they would not respond to test_unit_ready . */ if (((perq & 0x1f) == 0x1f) || ((perq & 0x1f) == 0x0d)) { + debug("%s: unknown/unsupported device\n", __func__); return 0; } if ((modi&0x80) == 0x80) { @@ -1431,3 +1402,46 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss, debug("partype: %d\n", dev_desc->part_type); return 1; } + +#ifdef CONFIG_DM_USB + +static int usb_mass_storage_probe(struct udevice *dev) +{ + struct usb_device *udev = dev_get_parentdata(dev); + int ret; + + usb_disable_asynch(1); /* asynch transfer not allowed */ + ret = usb_stor_probe_device(udev); + usb_disable_asynch(0); /* asynch transfer allowed */ + + return ret; +} + +static const struct udevice_id usb_mass_storage_ids[] = { + { .compatible = "usb-mass-storage" }, + { } +}; + +U_BOOT_DRIVER(usb_mass_storage) = { + .name = "usb_mass_storage", + .id = UCLASS_MASS_STORAGE, + .of_match = usb_mass_storage_ids, + .probe = usb_mass_storage_probe, +}; + +UCLASS_DRIVER(usb_mass_storage) = { + .id = UCLASS_MASS_STORAGE, + .name = "usb_mass_storage", +}; + +static const struct usb_device_id mass_storage_id_table[] = { + { + .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, + .bInterfaceClass = USB_CLASS_MASS_STORAGE + }, + { } /* Terminating entry */ +}; + +USB_DEVICE(usb_mass_storage, mass_storage_id_table); + +#endif diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig index 8c76360..f7231c6 100644 --- a/configs/A20-OLinuXino-Lime2_defconfig +++ b/configs/A20-OLinuXino-Lime2_defconfig @@ -1,9 +1,15 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI" CONFIG_FDTFILE="sun7i-a20-olinuxino-lime2.dtb" +CONFIG_MMC0_CD_PIN="PH1" +CONFIG_USB0_VBUS_PIN="PC17" +CONFIG_USB0_VBUS_DET="PH5" CONFIG_ARM=y CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=480 CONFIG_DRAM_ZQ=127 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/A20-OLinuXino-Lime_defconfig b/configs/A20-OLinuXino-Lime_defconfig index 8d71d5f..7868d6e 100644 --- a/configs/A20-OLinuXino-Lime_defconfig +++ b/configs/A20-OLinuXino-Lime_defconfig @@ -7,3 +7,6 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=480 CONFIG_DRAM_ZQ=127 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/A20-OLinuXino_MICRO_defconfig b/configs/A20-OLinuXino_MICRO_defconfig index 377bd46..11fb760 100644 --- a/configs/A20-OLinuXino_MICRO_defconfig +++ b/configs/A20-OLinuXino_MICRO_defconfig @@ -11,3 +11,6 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=384 CONFIG_DRAM_ZQ=127 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Ainol_AW1_defconfig b/configs/Ainol_AW1_defconfig new file mode 100644 index 0000000..e5c2e21 --- /dev/null +++ b/configs/Ainol_AW1_defconfig @@ -0,0 +1,22 @@ +# The Ainol AW1 is an A20 based tablet with a 800x480 lcd screen, sdio wifi, +# volume up/down and home buttons, micro-sd slot, micro usb (otg), headphones +# connector and a SPCI modem connector. +# +# Also see: http://linux-sunxi.org/Ainol_AW1 +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" +CONFIG_FDTFILE="sun7i-a20-ainol-aw1.dtb" +CONFIG_MMC0_CD_PIN="PH1" +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB0_VBUS_PIN="PB9" +CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:40000,le:87,ri:112,up:38,lo:141,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_POWER="PH8" +CONFIG_VIDEO_LCD_BL_EN="PH7" +CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN7I=y +CONFIG_DRAM_CLK=432 +CONFIG_DRAM_ZQ=123 +CONFIG_DRAM_EMR1=4 diff --git a/configs/Ampe_A76_defconfig b/configs/Ampe_A76_defconfig index af8aefa..af7638d 100644 --- a/configs/Ampe_A76_defconfig +++ b/configs/Ampe_A76_defconfig @@ -1,9 +1,10 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER" CONFIG_FDTFILE="sun5i-a13-ampe-a76.dtb" +CONFIG_MMC0_CD_PIN="PG0" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="PG12" -CONFIG_USB0_VBUS_DET="PG01" +CONFIG_USB0_VBUS_DET="PG1" CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:82,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_POWER="AXP0-0" CONFIG_VIDEO_LCD_BL_EN="AXP0-1" diff --git a/configs/Bananapi_defconfig b/configs/Bananapi_defconfig index bad6081..36a8671 100644 --- a/configs/Bananapi_defconfig +++ b/configs/Bananapi_defconfig @@ -8,3 +8,6 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=432 CONFIG_DRAM_ZQ=127 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Bananapro_defconfig b/configs/Bananapro_defconfig index 2274c80..236a992 100644 --- a/configs/Bananapro_defconfig +++ b/configs/Bananapro_defconfig @@ -10,3 +10,6 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=432 CONFIG_DRAM_ZQ=127 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/CSQ_CS908_defconfig b/configs/CSQ_CS908_defconfig index ec84acb..776636e 100644 --- a/configs/CSQ_CS908_defconfig +++ b/configs/CSQ_CS908_defconfig @@ -13,3 +13,6 @@ CONFIG_AXP221_ALDO1_VOLT=3300 # No Vbus gpio for either usb CONFIG_USB1_VBUS_PIN="" CONFIG_USB2_VBUS_PIN="" +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Colombus_defconfig b/configs/Colombus_defconfig index d6aad5e..810c88f 100644 --- a/configs/Colombus_defconfig +++ b/configs/Colombus_defconfig @@ -10,3 +10,6 @@ CONFIG_DRAM_ZQ=251 CONFIG_AXP221_ALDO1_VOLT=3300 # No Vbus gpio for usb1 CONFIG_USB1_VBUS_PIN="" +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Cubieboard2_defconfig b/configs/Cubieboard2_defconfig index 05b11a0..7f65c1d 100644 --- a/configs/Cubieboard2_defconfig +++ b/configs/Cubieboard2_defconfig @@ -1,9 +1,13 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI" CONFIG_FDTFILE="sun7i-a20-cubieboard2.dtb" +CONFIG_MMC0_CD_PIN="PH1" CONFIG_ARM=y CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=480 CONFIG_DRAM_ZQ=127 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig index fa48331..b8418f7 100644 --- a/configs/Cubietruck_defconfig +++ b/configs/Cubietruck_defconfig @@ -9,3 +9,6 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=432 CONFIG_DRAM_ZQ=127 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Hummingbird_A31_defconfig b/configs/Hummingbird_A31_defconfig index 7fd5a2a..8a11e09 100644 --- a/configs/Hummingbird_A31_defconfig +++ b/configs/Hummingbird_A31_defconfig @@ -14,3 +14,6 @@ CONFIG_AXP221_ALDO1_VOLT=3300 CONFIG_USB1_VBUS_PIN="PH24" # No Vbus gpio for usb2 CONFIG_USB2_VBUS_PIN="" +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Ippo_q8h_v1_2_defconfig b/configs/Ippo_q8h_v1_2_defconfig index 0c88edd..e003b4c 100644 --- a/configs/Ippo_q8h_v1_2_defconfig +++ b/configs/Ippo_q8h_v1_2_defconfig @@ -2,8 +2,8 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" CONFIG_FDTFILE="sun8i-a23-ippo-q8h-v1.2.dtb" CONFIG_USB_MUSB_SUNXI=y -CONFIG_USB0_VBUS_PIN="axp_drivebus" -CONFIG_USB0_VBUS_DET="axp_vbus_detect" +CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE" +CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:167,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_DCLK_PHASE=0 CONFIG_VIDEO_LCD_POWER="PH7" diff --git a/configs/Ippo_q8h_v5_defconfig b/configs/Ippo_q8h_v5_defconfig index 16ba03b..87d898e 100644 --- a/configs/Ippo_q8h_v5_defconfig +++ b/configs/Ippo_q8h_v5_defconfig @@ -2,8 +2,8 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" CONFIG_FDTFILE="sun8i-a23-ippo-q8h-v5.dtb" CONFIG_USB_MUSB_SUNXI=y -CONFIG_USB0_VBUS_PIN="axp_drivebus" -CONFIG_USB0_VBUS_DET="axp_vbus_detect" +CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE" +CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:168,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_DCLK_PHASE=0 CONFIG_VIDEO_LCD_POWER="PH7" diff --git a/configs/Linksprite_pcDuino3_Nano_defconfig b/configs/Linksprite_pcDuino3_Nano_defconfig index 15a883a..9d171bd 100644 --- a/configs/Linksprite_pcDuino3_Nano_defconfig +++ b/configs/Linksprite_pcDuino3_Nano_defconfig @@ -9,3 +9,6 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=408 CONFIG_DRAM_ZQ=122 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Linksprite_pcDuino3_defconfig b/configs/Linksprite_pcDuino3_defconfig index e642069..e5aabdb 100644 --- a/configs/Linksprite_pcDuino3_defconfig +++ b/configs/Linksprite_pcDuino3_defconfig @@ -7,3 +7,14 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=480 CONFIG_DRAM_ZQ=122 CONFIG_DRAM_EMR1=4 +CONFIG_DM=y +CONFIG_DM_GPIO=y +CONFIG_DM_SERIAL=y +CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3" +CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y +CONFIG_OF_SEPARATE=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y +CONFIG_DM_ETH=y diff --git a/configs/Linksprite_pcDuino3_fdt_defconfig b/configs/Linksprite_pcDuino3_fdt_defconfig deleted file mode 100644 index 7690d1e..0000000 --- a/configs/Linksprite_pcDuino3_fdt_defconfig +++ /dev/null @@ -1,15 +0,0 @@ -CONFIG_SPL=y -CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPH(2),USB_EHCI" -CONFIG_FDTFILE="sun7i-a20-pcduino3.dtb" -CONFIG_DM=y -CONFIG_DM_GPIO=y -CONFIG_DM_SERIAL=y -CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3" -CONFIG_OF_CONTROL=y -CONFIG_OF_SEPARATE=y -CONFIG_ARM=y -CONFIG_ARCH_SUNXI=y -CONFIG_MACH_SUN7I=y -CONFIG_DRAM_CLK=480 -CONFIG_DRAM_ZQ=122 -CONFIG_DRAM_EMR1=4 diff --git a/configs/Mele_I7_defconfig b/configs/Mele_I7_defconfig index 0e9a950..e91d507 100644 --- a/configs/Mele_I7_defconfig +++ b/configs/Mele_I7_defconfig @@ -24,3 +24,6 @@ CONFIG_AXP221_ALDO1_VOLT=3300 CONFIG_USB1_VBUS_PIN="PC27" # No Vbus gpio for usb2 CONFIG_USB2_VBUS_PIN="" +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Mele_M3_defconfig b/configs/Mele_M3_defconfig index a28e0a0..a74dd2d 100644 --- a/configs/Mele_M3_defconfig +++ b/configs/Mele_M3_defconfig @@ -10,3 +10,6 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=384 CONFIG_DRAM_ZQ=127 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Mele_M5_defconfig b/configs/Mele_M5_defconfig index 1442318..d0f0425 100644 --- a/configs/Mele_M5_defconfig +++ b/configs/Mele_M5_defconfig @@ -11,3 +11,6 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=432 CONFIG_DRAM_ZQ=122 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Mele_M9_defconfig b/configs/Mele_M9_defconfig index f9d4ccc..592322d 100644 --- a/configs/Mele_M9_defconfig +++ b/configs/Mele_M9_defconfig @@ -18,3 +18,6 @@ CONFIG_AXP221_ALDO1_VOLT=3300 CONFIG_USB1_VBUS_PIN="PC27" # No Vbus gpio for usb2 CONFIG_USB2_VBUS_PIN="" +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Orangepi_defconfig b/configs/Orangepi_defconfig index 0c39f70..5bf9cac 100644 --- a/configs/Orangepi_defconfig +++ b/configs/Orangepi_defconfig @@ -18,3 +18,6 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=432 CONFIG_DRAM_ZQ=127 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Orangepi_mini_defconfig b/configs/Orangepi_mini_defconfig index 733e07f..fce0555 100644 --- a/configs/Orangepi_mini_defconfig +++ b/configs/Orangepi_mini_defconfig @@ -21,3 +21,6 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=432 CONFIG_DRAM_ZQ=127 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/TZX-Q8-713B7_defconfig b/configs/TZX-Q8-713B7_defconfig index 4ff4542..0953554 100644 --- a/configs/TZX-Q8-713B7_defconfig +++ b/configs/TZX-Q8-713B7_defconfig @@ -1,6 +1,7 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER" CONFIG_FDTFILE="sun5i-a13-tzx-q8-713b7.dtb" +CONFIG_MMC0_CD_PIN="PG0" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="PG12" CONFIG_USB0_VBUS_DET="PG1" diff --git a/configs/Wits_Pro_A20_DKT_defconfig b/configs/Wits_Pro_A20_DKT_defconfig index 9147ead..92c33b3 100644 --- a/configs/Wits_Pro_A20_DKT_defconfig +++ b/configs/Wits_Pro_A20_DKT_defconfig @@ -13,3 +13,6 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=384 CONFIG_DRAM_ZQ=127 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/Yones_Toptech_BD1078_defconfig b/configs/Yones_Toptech_BD1078_defconfig new file mode 100644 index 0000000..00ede67 --- /dev/null +++ b/configs/Yones_Toptech_BD1078_defconfig @@ -0,0 +1,29 @@ +# The Yones Toptech BD1078 is an A20 based 10" tablet with a 1024x600 lcd +# screen, volume up/down and back buttons, headphones jack, mini hdmi, micro +# usb (otg), micro usb (host), external micro-sd slot and a separate internal +# micro-sd slot. +# +# Also see: http://linux-sunxi.org/Yones_Toptech_BD1078 +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" +CONFIG_FDTFILE="sun7i-a20-yones-toptech-bd1078.dtb" +CONFIG_MMC_SUNXI_SLOT_EXTRA=1 +CONFIG_MMC0_CD_PIN="PH1" +CONFIG_MMC1_CD_PIN="PH2" +CONFIG_MMC1_PINS="PH" +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB0_VBUS_PIN="PB9" +CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:24,pclk_khz:63000,le:32,ri:287,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_DCLK_PHASE=0 +CONFIG_VIDEO_LCD_PANEL_LVDS=y +CONFIG_VIDEO_LCD_POWER="PH8" +CONFIG_VIDEO_LCD_BL_EN="PH7" +CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW=n +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN7I=y +CONFIG_DRAM_CLK=408 +CONFIG_DRAM_ZQ=127 +CONFIG_DRAM_EMR1=4 diff --git a/configs/alt_defconfig b/configs/alt_defconfig index ff87230..0a18409 100644 --- a/configs/alt_defconfig +++ b/configs/alt_defconfig @@ -1,6 +1,4 @@ CONFIG_ARM=y CONFIG_RMOBILE=y CONFIG_TARGET_ALT=y -CONFIG_DM=y -CONFIG_DM_SERIAL=y CONFIG_SH_SDHI=y diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig index 0e39c7d..e4ffe5f 100644 --- a/configs/am335x_boneblack_vboot_defconfig +++ b/configs/am335x_boneblack_vboot_defconfig @@ -9,4 +9,3 @@ CONFIG_DEFAULT_DEVICE_TREE="am335x-boneblack" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y -CONFIG_DM=y diff --git a/configs/am3517_crane_defconfig b/configs/am3517_crane_defconfig index 72cc2d7..cd16724 100644 --- a/configs/am3517_crane_defconfig +++ b/configs/am3517_crane_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_AM3517_CRANE=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/am3517_evm_defconfig b/configs/am3517_evm_defconfig index 6d6b0d2..daf1ae4 100644 --- a/configs/am3517_evm_defconfig +++ b/configs/am3517_evm_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_AM3517_EVM=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/arndale_defconfig b/configs/arndale_defconfig index 4aa14af..21d5f4a 100644 --- a/configs/arndale_defconfig +++ b/configs/arndale_defconfig @@ -3,3 +3,9 @@ CONFIG_ARM=y CONFIG_ARCH_EXYNOS=y CONFIG_TARGET_ARNDALE=y CONFIG_DEFAULT_DEVICE_TREE="exynos5250-arndale" +CONFIG_SOUND=y +CONFIG_CMD_SOUND=y +CONFIG_I2S=y +CONFIG_I2S_SAMSUNG=y +CONFIG_SOUND_MAX98095=y +CONFIG_SOUND_WM8994=y diff --git a/configs/axs101_defconfig b/configs/axs101_defconfig index e5e1d87..c97628d 100644 --- a/configs/axs101_defconfig +++ b/configs/axs101_defconfig @@ -4,3 +4,6 @@ CONFIG_ARC_CACHE_LINE_SHIFT=5 CONFIG_TARGET_AXS101=y CONFIG_SYS_TEXT_BASE=0x81000000 CONFIG_SYS_CLK_FREQ=750000000 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/axs103_defconfig b/configs/axs103_defconfig index 7d662ad..e92fd7c 100644 --- a/configs/axs103_defconfig +++ b/configs/axs103_defconfig @@ -3,3 +3,6 @@ CONFIG_ISA_ARCV2=y CONFIG_TARGET_AXS101=y CONFIG_SYS_TEXT_BASE=0x81000000 CONFIG_SYS_CLK_FREQ=50000000 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/bf609-ezkit_defconfig b/configs/bf609-ezkit_defconfig index 2bfb6a5..96f746e 100644 --- a/configs/bf609-ezkit_defconfig +++ b/configs/bf609-ezkit_defconfig @@ -1,2 +1,5 @@ CONFIG_BLACKFIN=y CONFIG_TARGET_BF609_EZKIT=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/birdland_bav335a_defconfig b/configs/birdland_bav335a_defconfig index 54ac4d1..43a4206 100644 --- a/configs/birdland_bav335a_defconfig +++ b/configs/birdland_bav335a_defconfig @@ -1,8 +1,5 @@ CONFIG_ARM=y CONFIG_TARGET_BAV335X=y -CONFIG_DM=y -CONFIG_DM_SERIAL=y -CONFIG_SYS_MALLOC_F=y CONFIG_BAV_VERSION=1 CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1" diff --git a/configs/birdland_bav335b_defconfig b/configs/birdland_bav335b_defconfig index 9046553..7206e8e 100644 --- a/configs/birdland_bav335b_defconfig +++ b/configs/birdland_bav335b_defconfig @@ -1,8 +1,5 @@ CONFIG_ARM=y CONFIG_TARGET_BAV335X=y -CONFIG_DM=y -CONFIG_DM_SERIAL=y -CONFIG_SYS_MALLOC_F=y CONFIG_BAV_VERSION=2 CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1" diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig index 2f0c714..fe2610a 100644 --- a/configs/chromebook_link_defconfig +++ b/configs/chromebook_link_defconfig @@ -9,3 +9,5 @@ CONFIG_SMM_TSEG_SIZE=0x800000 CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y +CONFIG_DM_PCI=y +CONFIG_CROS_EC_LPC=y diff --git a/configs/chromebox_panther_defconfig b/configs/chromebox_panther_defconfig new file mode 100644 index 0000000..0613cd6 --- /dev/null +++ b/configs/chromebox_panther_defconfig @@ -0,0 +1,12 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0xfff00000" +CONFIG_X86=y +CONFIG_TARGET_CHROMEBOX_PANTHER=y +CONFIG_OF_CONTROL=y +CONFIG_OF_SEPARATE=y +CONFIG_DEFAULT_DEVICE_TREE="chromebox_panther" +CONFIG_HAVE_MRC=y +CONFIG_SMM_TSEG_SIZE=0x800000 +CONFIG_VIDEO_VESA=y +CONFIG_FRAMEBUFFER_SET_VESA_MODE=y +CONFIG_FRAMEBUFFER_VESA_MODE_11A=y +CONFIG_DM_PCI=y diff --git a/configs/cm_fx6_defconfig b/configs/cm_fx6_defconfig index f10a5c2..c83a0e8 100644 --- a/configs/cm_fx6_defconfig +++ b/configs/cm_fx6_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6QDL,SPL" CONFIG_ARM=y CONFIG_TARGET_CM_FX6=y -CONFIG_DM=y -CONFIG_DM_GPIO=y -CONFIG_DM_SERIAL=y diff --git a/configs/cm_t3517_defconfig b/configs/cm_t3517_defconfig index 5c40b90..2d05ffb 100644 --- a/configs/cm_t3517_defconfig +++ b/configs/cm_t3517_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=n CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_CM_T3517=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/cm_t35_defconfig b/configs/cm_t35_defconfig index 4a99263..63a85b4 100644 --- a/configs/cm_t35_defconfig +++ b/configs/cm_t35_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_CM_T35=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/colibri_vf_defconfig b/configs/colibri_vf_defconfig new file mode 100644 index 0000000..cef5a9e --- /dev/null +++ b/configs/colibri_vf_defconfig @@ -0,0 +1,3 @@ +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/toradex/colibri_vf/imximage.cfg,ENV_IS_IN_NAND,IMX_NAND" +CONFIG_ARM=y +CONFIG_TARGET_COLIBRI_VF=y diff --git a/configs/coreboot-x86_defconfig b/configs/coreboot-x86_defconfig index 3cc034a..0249172 100644 --- a/configs/coreboot-x86_defconfig +++ b/configs/coreboot-x86_defconfig @@ -2,3 +2,4 @@ CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0x01110000" CONFIG_X86=y CONFIG_TARGET_COREBOOT=y CONFIG_OF_CONTROL=y +CONFIG_DM_PCI=y diff --git a/configs/devkit8000_defconfig b/configs/devkit8000_defconfig index 9756461..84a1a25 100644 --- a/configs/devkit8000_defconfig +++ b/configs/devkit8000_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_DEVKIT8000=y -CONFIG_DM=y -CONFIG_DM_SERIAL=y -CONFIG_DM_GPIO=y diff --git a/configs/dig297_defconfig b/configs/dig297_defconfig index 0d18290..95bc353 100644 --- a/configs/dig297_defconfig +++ b/configs/dig297_defconfig @@ -1,6 +1,3 @@ CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_DIG297=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/eco5pk_defconfig b/configs/eco5pk_defconfig index fbe6335..8587c51 100644 --- a/configs/eco5pk_defconfig +++ b/configs/eco5pk_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_ECO5PK=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/galileo_defconfig b/configs/galileo_defconfig index f208651..9b0f969 100644 --- a/configs/galileo_defconfig +++ b/configs/galileo_defconfig @@ -4,3 +4,6 @@ CONFIG_TARGET_GALILEO=y CONFIG_OF_CONTROL=y CONFIG_OF_SEPARATE=y CONFIG_DEFAULT_DEVICE_TREE="galileo" +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/gose_defconfig b/configs/gose_defconfig index 353f854..b6054f7 100644 --- a/configs/gose_defconfig +++ b/configs/gose_defconfig @@ -1,6 +1,4 @@ CONFIG_ARM=y CONFIG_RMOBILE=y CONFIG_TARGET_GOSE=y -CONFIG_DM=y -CONFIG_DM_SERIAL=y CONFIG_SH_SDHI=y diff --git a/configs/i12-tvbox_defconfig b/configs/i12-tvbox_defconfig index 157997f..b10f4d0 100644 --- a/configs/i12-tvbox_defconfig +++ b/configs/i12-tvbox_defconfig @@ -7,3 +7,6 @@ CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=384 CONFIG_DRAM_ZQ=127 CONFIG_DRAM_EMR1=4 +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/iNet_3F_defconfig b/configs/iNet_3F_defconfig new file mode 100644 index 0000000..4225b85 --- /dev/null +++ b/configs/iNet_3F_defconfig @@ -0,0 +1,20 @@ +# The iNet 3F is an A10 tablet with 1GiB RAM and a 1024x768 screen. +# Also see: http://linux-sunxi.org/INet_3F +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" +CONFIG_FDTFILE="sun4i-a10-inet-3f.dtb" +CONFIG_MMC0_CD_PIN="PH1" +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB0_VBUS_PIN="PB9" +CONFIG_USB0_VBUS_DET="PH5" +CONFIG_VIDEO_LCD_MODE="x:1024,y:768,depth:18,pclk_khz:100000,le:799,ri:260,up:15,lo:16,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_PANEL_LVDS=y +CONFIG_VIDEO_LCD_POWER="PH8" +CONFIG_VIDEO_LCD_BL_EN="PH7" +CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN4I=y +CONFIG_DRAM_CLK=432 +CONFIG_DRAM_ZQ=123 +CONFIG_DRAM_EMR1=4 diff --git a/configs/iNet_3W_defconfig b/configs/iNet_3W_defconfig new file mode 100644 index 0000000..0a8e0f5 --- /dev/null +++ b/configs/iNet_3W_defconfig @@ -0,0 +1,19 @@ +# The iNet 3W is an A10 tablet with 1GiB RAM and a 1024x768 screen. +# Also see: http://linux-sunxi.org/INet_3W +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" +CONFIG_FDTFILE="sun4i-a10-inet-3w.dtb" +CONFIG_MMC0_CD_PIN="PH20" +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB0_VBUS_PIN="PB9" +CONFIG_USB0_VBUS_DET="PH5" +CONFIG_VIDEO_LCD_MODE="x:1024,y:768,depth:24,pclk_khz:65000,le:159,ri:160,up:22,lo:15,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_POWER="PH8" +CONFIG_VIDEO_LCD_BL_EN="PH7" +CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN4I=y +CONFIG_DRAM_CLK=408 +CONFIG_DRAM_ZQ=127 +CONFIG_DRAM_EMR1=4 diff --git a/configs/Inet_86VS_defconfig b/configs/iNet_86VS_defconfig index e5c103f..e5c103f 100644 --- a/configs/Inet_86VS_defconfig +++ b/configs/iNet_86VS_defconfig diff --git a/configs/ids8313_defconfig b/configs/ids8313_defconfig index 0950ec8..8479cd4 100644 --- a/configs/ids8313_defconfig +++ b/configs/ids8313_defconfig @@ -4,4 +4,3 @@ CONFIG_MPC83xx=y CONFIG_FIT=y CONFIG_FIT_SIGNATURE=y CONFIG_TARGET_IDS8313=y -CONFIG_DM=y diff --git a/configs/integratorap_cm720t_defconfig b/configs/integratorap_cm720t_defconfig index 0bb7b08..fc0dc67 100644 --- a/configs/integratorap_cm720t_defconfig +++ b/configs/integratorap_cm720t_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="CM720T" CONFIG_ARM=y -CONFIG_TARGET_INTEGRATORAP_CM720T=y +CONFIG_ARCH_INTEGRATOR=y +CONFIG_ARCH_INTEGRATOR_AP=y +CONFIG_CM720T=y diff --git a/configs/integratorap_cm920t_defconfig b/configs/integratorap_cm920t_defconfig index fb925d5..eb6afb9 100644 --- a/configs/integratorap_cm920t_defconfig +++ b/configs/integratorap_cm920t_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="CM920T" CONFIG_ARM=y -CONFIG_TARGET_INTEGRATORAP_CM920T=y +CONFIG_ARCH_INTEGRATOR=y +CONFIG_ARCH_INTEGRATOR_AP=y +CONFIG_CM920T=y diff --git a/configs/integratorap_cm926ejs_defconfig b/configs/integratorap_cm926ejs_defconfig index 308a1e6..8667fcb 100644 --- a/configs/integratorap_cm926ejs_defconfig +++ b/configs/integratorap_cm926ejs_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="CM926EJ_S" CONFIG_ARM=y -CONFIG_TARGET_INTEGRATORAP_CM926EJS=y +CONFIG_ARCH_INTEGRATOR=y +CONFIG_ARCH_INTEGRATOR_AP=y +CONFIG_CM926EJ_S=y diff --git a/configs/integratorap_cm946es_defconfig b/configs/integratorap_cm946es_defconfig index d1b9db5..1e8c157 100644 --- a/configs/integratorap_cm946es_defconfig +++ b/configs/integratorap_cm946es_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="CM946ES" CONFIG_ARM=y -CONFIG_TARGET_INTEGRATORAP_CM946ES=y +CONFIG_ARCH_INTEGRATOR=y +CONFIG_ARCH_INTEGRATOR_AP=y +CONFIG_CM946ES=y diff --git a/configs/integratorcp_cm1136_defconfig b/configs/integratorcp_cm1136_defconfig index 3feb656..f039470 100644 --- a/configs/integratorcp_cm1136_defconfig +++ b/configs/integratorcp_cm1136_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="CM1136" CONFIG_ARM=y -CONFIG_TARGET_INTEGRATORCP_CM1136=y +CONFIG_ARCH_INTEGRATOR=y +CONFIG_ARCH_INTEGRATOR_CP=y +CONFIG_CM1136=y diff --git a/configs/integratorcp_cm920t_defconfig b/configs/integratorcp_cm920t_defconfig index f304bbe..cb364a1 100644 --- a/configs/integratorcp_cm920t_defconfig +++ b/configs/integratorcp_cm920t_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="CM920T" CONFIG_ARM=y -CONFIG_TARGET_INTEGRATORCP_CM920T=y +CONFIG_ARCH_INTEGRATOR=y +CONFIG_ARCH_INTEGRATOR_CP=y +CONFIG_CM920T=y diff --git a/configs/integratorcp_cm926ejs_defconfig b/configs/integratorcp_cm926ejs_defconfig index a8d762b..32ea7b9 100644 --- a/configs/integratorcp_cm926ejs_defconfig +++ b/configs/integratorcp_cm926ejs_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="CM924EJ_S" CONFIG_ARM=y -CONFIG_TARGET_INTEGRATORCP_CM926EJS=y +CONFIG_ARCH_INTEGRATOR=y +CONFIG_ARCH_INTEGRATOR_CP=y +CONFIG_CM926EJ_S=y diff --git a/configs/integratorcp_cm946es_defconfig b/configs/integratorcp_cm946es_defconfig index 2e67dbc..e7fc706 100644 --- a/configs/integratorcp_cm946es_defconfig +++ b/configs/integratorcp_cm946es_defconfig @@ -1,3 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="CM946ES" CONFIG_ARM=y -CONFIG_TARGET_INTEGRATORCP_CM946ES=y +CONFIG_ARCH_INTEGRATOR=y +CONFIG_ARCH_INTEGRATOR_CP=y +CONFIG_CM946ES=y diff --git a/configs/koelsch_defconfig b/configs/koelsch_defconfig index b1e3529..7ab2bfd 100644 --- a/configs/koelsch_defconfig +++ b/configs/koelsch_defconfig @@ -1,6 +1,4 @@ CONFIG_ARM=y CONFIG_RMOBILE=y CONFIG_TARGET_KOELSCH=y -CONFIG_DM=y -CONFIG_DM_SERIAL=y CONFIG_SH_SDHI=y diff --git a/configs/lager_defconfig b/configs/lager_defconfig index 950b037..08adfe3 100644 --- a/configs/lager_defconfig +++ b/configs/lager_defconfig @@ -1,6 +1,4 @@ CONFIG_ARM=y CONFIG_RMOBILE=y CONFIG_TARGET_LAGER=y -CONFIG_DM=y -CONFIG_DM_SERIAL=y CONFIG_SH_SDHI=y diff --git a/configs/ls1021aqds_ddr4_nor_lpuart_defconfig b/configs/ls1021aqds_ddr4_nor_lpuart_defconfig new file mode 100644 index 0000000..4d2714b --- /dev/null +++ b/configs/ls1021aqds_ddr4_nor_lpuart_defconfig @@ -0,0 +1,3 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4,LPUART" +CONFIG_ARM=y +CONFIG_TARGET_LS1021AQDS=y diff --git a/configs/ls2085aqds_defconfig b/configs/ls2085aqds_defconfig new file mode 100644 index 0000000..e3a17a3 --- /dev/null +++ b/configs/ls2085aqds_defconfig @@ -0,0 +1,3 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4" +CONFIG_ARM=y +CONFIG_TARGET_LS2085AQDS=y diff --git a/configs/ls2085aqds_nand_defconfig b/configs/ls2085aqds_nand_defconfig new file mode 100644 index 0000000..f84a426 --- /dev/null +++ b/configs/ls2085aqds_nand_defconfig @@ -0,0 +1,4 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4,NAND" +CONFIG_SPL=y +CONFIG_ARM=y +CONFIG_TARGET_LS2085AQDS=y diff --git a/configs/ls2085ardb_defconfig b/configs/ls2085ardb_defconfig new file mode 100644 index 0000000..6b64f71 --- /dev/null +++ b/configs/ls2085ardb_defconfig @@ -0,0 +1,3 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4" +CONFIG_ARM=y +CONFIG_TARGET_LS2085ARDB=y diff --git a/configs/ls2085ardb_nand_defconfig b/configs/ls2085ardb_nand_defconfig new file mode 100644 index 0000000..74812f7 --- /dev/null +++ b/configs/ls2085ardb_nand_defconfig @@ -0,0 +1,4 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4,NAND" +CONFIG_SPL=y +CONFIG_ARM=y +CONFIG_TARGET_LS2085ARDB=y diff --git a/configs/mcx_defconfig b/configs/mcx_defconfig index 2f61858..4abf34d 100644 --- a/configs/mcx_defconfig +++ b/configs/mcx_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_MCX=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/mixtile_loftq_defconfig b/configs/mixtile_loftq_defconfig new file mode 100644 index 0000000..8275df8 --- /dev/null +++ b/configs/mixtile_loftq_defconfig @@ -0,0 +1,24 @@ +# The Mixtile LOFT-Q is an A31 based board with 2G RAM, 8G EMMC, sdio wifi, +# 1Gbit ethernet, HDMI display, toslink audio plug, 4 USB2.0 port, external +# USB2SATA connector, sd card plug, 3x60 external fpic expansion connector, +# NXP JN5168 zigbee gw, remote support. +# +# Also see http://focalcrest.com/en/pc.html#pro02 +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="USB_EHCI,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPA(21)" +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN6I=y +CONFIG_DRAM_CLK=312 +CONFIG_DRAM_ZQ=251 +CONFIG_MMC_SUNXI_SLOT=0 +CONFIG_MMC_SUNXI_SLOT_EXTRA=2 +# Wifi power +CONFIG_AXP221_ALDO1_VOLT=3300 +# Vbus gpio for usb1 +CONFIG_USB1_VBUS_PIN="PH24" +# No Vbus gpio for usb2 +CONFIG_USB2_VBUS_PIN="" +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/mt_ventoux_defconfig b/configs/mt_ventoux_defconfig index 5b1da8c..fd4f649 100644 --- a/configs/mt_ventoux_defconfig +++ b/configs/mt_ventoux_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_MT_VENTOUX=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/mx6cuboxi_defconfig b/configs/mx6cuboxi_defconfig new file mode 100644 index 0000000..4c2f0e0 --- /dev/null +++ b/configs/mx6cuboxi_defconfig @@ -0,0 +1,6 @@ +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6QDL" +CONFIG_ARM=y +CONFIG_TARGET_MX6CUBOXI=y +CONFIG_DM=y +CONFIG_DM_THERMAL=y diff --git a/configs/mx6dlsabreauto_defconfig b/configs/mx6dlsabreauto_defconfig index 8bc5e8b..b649935 100644 --- a/configs/mx6dlsabreauto_defconfig +++ b/configs/mx6dlsabreauto_defconfig @@ -1,5 +1,3 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6qsabreauto/mx6dl.cfg,MX6DL" CONFIG_ARM=y CONFIG_TARGET_MX6QSABREAUTO=y -CONFIG_DM=y -CONFIG_DM_THERMAL=y diff --git a/configs/mx6dlsabresd_defconfig b/configs/mx6dlsabresd_defconfig index cde0d70..b333e59 100644 --- a/configs/mx6dlsabresd_defconfig +++ b/configs/mx6dlsabresd_defconfig @@ -3,5 +3,3 @@ CONFIG_ARM=y CONFIG_TARGET_MX6SABRESD=y CONFIG_SYS_MALLOC_F=y CONFIG_SYS_MALLOC_F_LEN=0x400 -CONFIG_DM=y -CONFIG_DM_THERMAL=y diff --git a/configs/mx6qsabreauto_defconfig b/configs/mx6qsabreauto_defconfig index ba9e512..7d86700 100644 --- a/configs/mx6qsabreauto_defconfig +++ b/configs/mx6qsabreauto_defconfig @@ -1,5 +1,3 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6qsabreauto/imximage.cfg,MX6Q" CONFIG_ARM=y CONFIG_TARGET_MX6QSABREAUTO=y -CONFIG_DM=y -CONFIG_DM_THERMAL=y diff --git a/configs/mx6qsabresd_defconfig b/configs/mx6qsabresd_defconfig index 1764b39..67c1b77 100644 --- a/configs/mx6qsabresd_defconfig +++ b/configs/mx6qsabresd_defconfig @@ -1,5 +1,3 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sabresd/mx6q_4x_mt41j128.cfg,MX6Q" CONFIG_ARM=y CONFIG_TARGET_MX6SABRESD=y -CONFIG_DM=y -CONFIG_DM_THERMAL=y diff --git a/configs/mx6sabresd_spl_defconfig b/configs/mx6sabresd_spl_defconfig index 16a947e..7f563cd 100644 --- a/configs/mx6sabresd_spl_defconfig +++ b/configs/mx6sabresd_spl_defconfig @@ -2,5 +2,3 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6Q" CONFIG_ARM=y CONFIG_TARGET_MX6SABRESD=y -CONFIG_DM=y -CONFIG_DM_THERMAL=y diff --git a/configs/mx6sxsabresd_defconfig b/configs/mx6sxsabresd_defconfig index 5c862cf..f23d48f 100644 --- a/configs/mx6sxsabresd_defconfig +++ b/configs/mx6sxsabresd_defconfig @@ -1,5 +1,3 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sxsabresd/imximage.cfg,MX6SX" CONFIG_ARM=y CONFIG_TARGET_MX6SXSABRESD=y -CONFIG_DM=y -CONFIG_DM_THERMAL=y diff --git a/configs/mx6sxsabresd_spl_defconfig b/configs/mx6sxsabresd_spl_defconfig index de3d98f..b5e0635 100644 --- a/configs/mx6sxsabresd_spl_defconfig +++ b/configs/mx6sxsabresd_spl_defconfig @@ -2,5 +2,3 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6SX" CONFIG_ARM=y CONFIG_TARGET_MX6SXSABRESD=y -CONFIG_DM=y -CONFIG_DM_THERMAL=y diff --git a/configs/nokia_rx51_defconfig b/configs/nokia_rx51_defconfig index 20a51e1..e03f586 100644 --- a/configs/nokia_rx51_defconfig +++ b/configs/nokia_rx51_defconfig @@ -1,6 +1,3 @@ CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_NOKIA_RX51=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/omap3_beagle_defconfig b/configs/omap3_beagle_defconfig index 5106821..2a3cc66 100644 --- a/configs/omap3_beagle_defconfig +++ b/configs/omap3_beagle_defconfig @@ -3,6 +3,3 @@ CONFIG_SYS_EXTRA_OPTIONS="NAND" CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_OMAP3_BEAGLE=y -CONFIG_DM=y -CONFIG_DM_GPIO=y -CONFIG_DM_SERIAL=y diff --git a/configs/omap3_evm_defconfig b/configs/omap3_evm_defconfig index fb4a800..91c290b 100644 --- a/configs/omap3_evm_defconfig +++ b/configs/omap3_evm_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_OMAP3_EVM=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/omap3_evm_quick_mmc_defconfig b/configs/omap3_evm_quick_mmc_defconfig index d4594cb..12005bf 100644 --- a/configs/omap3_evm_quick_mmc_defconfig +++ b/configs/omap3_evm_quick_mmc_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_OMAP3_EVM_QUICK_MMC=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/omap3_evm_quick_nand_defconfig b/configs/omap3_evm_quick_nand_defconfig index 1a78a6e..5cc9512 100644 --- a/configs/omap3_evm_quick_nand_defconfig +++ b/configs/omap3_evm_quick_nand_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_OMAP3_EVM_QUICK_NAND=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/omap3_ha_defconfig b/configs/omap3_ha_defconfig index 344eca5..250890b 100644 --- a/configs/omap3_ha_defconfig +++ b/configs/omap3_ha_defconfig @@ -3,6 +3,3 @@ CONFIG_SYS_EXTRA_OPTIONS="SYS_BOARD_OMAP3_HA" CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_TAO3530=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/omap3_logic_defconfig b/configs/omap3_logic_defconfig index 790ccba..5f2c063 100644 --- a/configs/omap3_logic_defconfig +++ b/configs/omap3_logic_defconfig @@ -1,6 +1,3 @@ CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_OMAP3_LOGIC=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/omap3_mvblx_defconfig b/configs/omap3_mvblx_defconfig index b75f513..fb6edc2 100644 --- a/configs/omap3_mvblx_defconfig +++ b/configs/omap3_mvblx_defconfig @@ -1,6 +1,3 @@ CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_OMAP3_MVBLX=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/omap3_pandora_defconfig b/configs/omap3_pandora_defconfig index dd0f17c..bf28537 100644 --- a/configs/omap3_pandora_defconfig +++ b/configs/omap3_pandora_defconfig @@ -1,6 +1,3 @@ CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_OMAP3_PANDORA=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/omap3_sdp3430_defconfig b/configs/omap3_sdp3430_defconfig index b3a8745..1172c2a 100644 --- a/configs/omap3_sdp3430_defconfig +++ b/configs/omap3_sdp3430_defconfig @@ -1,6 +1,3 @@ CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_OMAP3_SDP3430=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/omapl138_lcdk_defconfig b/configs/omapl138_lcdk_defconfig new file mode 100644 index 0000000..8f19721 --- /dev/null +++ b/configs/omapl138_lcdk_defconfig @@ -0,0 +1,3 @@ +CONFIG_ARM=y +CONFIG_ARCH_DAVINCI=y +CONFIG_TARGET_OMAPL138_LCDK=y diff --git a/configs/ph1_ld4_defconfig b/configs/ph1_ld4_defconfig index aa1805b..036e2d1 100644 --- a/configs/ph1_ld4_defconfig +++ b/configs/ph1_ld4_defconfig @@ -1,9 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_UNIPHIER=y -CONFIG_DM=y -CONFIG_DM_SERIAL=y CONFIG_SPL_DM=y -CONFIG_DM_I2C=y CONFIG_MACH_PH1_LD4=y CONFIG_PFC_MICRO_SUPPORT_CARD=y CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-ld4-ref" diff --git a/configs/ph1_pro4_defconfig b/configs/ph1_pro4_defconfig index 194f7a5..9a010ee 100644 --- a/configs/ph1_pro4_defconfig +++ b/configs/ph1_pro4_defconfig @@ -1,9 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_UNIPHIER=y -CONFIG_DM=y -CONFIG_DM_SERIAL=y CONFIG_SPL_DM=y -CONFIG_DM_I2C=y CONFIG_MACH_PH1_PRO4=y CONFIG_PFC_MICRO_SUPPORT_CARD=y CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-pro4-ref" diff --git a/configs/ph1_sld8_defconfig b/configs/ph1_sld8_defconfig index e7e7fff..29fe0e8 100644 --- a/configs/ph1_sld8_defconfig +++ b/configs/ph1_sld8_defconfig @@ -1,9 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_UNIPHIER=y -CONFIG_DM=y -CONFIG_DM_SERIAL=y CONFIG_SPL_DM=y -CONFIG_DM_I2C=y CONFIG_MACH_PH1_SLD8=y CONFIG_PFC_MICRO_SUPPORT_CARD=y CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-sld8-ref" diff --git a/configs/porter_defconfig b/configs/porter_defconfig index 8d594d9..a7b044e 100644 --- a/configs/porter_defconfig +++ b/configs/porter_defconfig @@ -1,6 +1,4 @@ CONFIG_ARM=y CONFIG_RMOBILE=y CONFIG_TARGET_PORTER=y -CONFIG_DM=y -CONFIG_DM_SERIAL=y CONFIG_SH_SDHI=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index a216039..5de7fbe 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -3,10 +3,26 @@ CONFIG_OF_HOSTFILE=y CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y -CONFIG_DM=y CONFIG_DEFAULT_DEVICE_TREE="sandbox" CONFIG_CROS_EC=y -CONFIG_DM_CROS_EC=y CONFIG_CROS_EC_SANDBOX=y CONFIG_CROS_EC_KEYB=y CONFIG_CMD_CROS_EC=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCI_SANDBOX=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EMUL=y +CONFIG_USB_STORAGE=y +CONFIG_BOOTSTAGE=y +CONFIG_BOOTSTAGE_REPORT=y +CONFIG_SANDBOX_GPIO=y +CONFIG_SYS_VSNPRINTF=y +CONFIG_SYS_I2C_SANDBOX=y +CONFIG_SANDBOX_SPI=y +CONFIG_SPI_FLASH_SANDBOX=y +CONFIG_TPM_TIS_SANDBOX=y +CONFIG_SOUND=y +CONFIG_CMD_SOUND=y +CONFIG_SOUND_SANDBOX=y diff --git a/configs/silk_defconfig b/configs/silk_defconfig index 23d4f58..3c6f16e 100644 --- a/configs/silk_defconfig +++ b/configs/silk_defconfig @@ -1,6 +1,4 @@ CONFIG_ARM=y CONFIG_RMOBILE=y CONFIG_TARGET_SILK=y -CONFIG_DM=y -CONFIG_DM_SERIAL=y CONFIG_SH_SDHI=y diff --git a/configs/smdk5250_defconfig b/configs/smdk5250_defconfig index efc738b..0e7b868 100644 --- a/configs/smdk5250_defconfig +++ b/configs/smdk5250_defconfig @@ -3,3 +3,9 @@ CONFIG_ARM=y CONFIG_ARCH_EXYNOS=y CONFIG_TARGET_SMDK5250=y CONFIG_DEFAULT_DEVICE_TREE="exynos5250-smdk5250" +CONFIG_SOUND=y +CONFIG_CMD_SOUND=y +CONFIG_I2S=y +CONFIG_I2S_SAMSUNG=y +CONFIG_SOUND_MAX98095=y +CONFIG_SOUND_WM8994=y diff --git a/configs/snapper9260_defconfig b/configs/snapper9260_defconfig index 576d9c5..5c8850a 100644 --- a/configs/snapper9260_defconfig +++ b/configs/snapper9260_defconfig @@ -2,6 +2,3 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9260" CONFIG_ARM=y CONFIG_ARCH_AT91=y CONFIG_TARGET_SNAPPER9260=y -CONFIG_DM=y -CONFIG_DM_GPIO=y -CONFIG_DM_SERIAL=y diff --git a/configs/snapper9g20_defconfig b/configs/snapper9g20_defconfig index 07a2643..9270b8d 100644 --- a/configs/snapper9g20_defconfig +++ b/configs/snapper9g20_defconfig @@ -2,6 +2,3 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20" CONFIG_ARM=y CONFIG_ARCH_AT91=y CONFIG_TARGET_SNAPPER9260=y -CONFIG_DM=y -CONFIG_DM_GPIO=y -CONFIG_DM_SERIAL=y diff --git a/configs/snow_defconfig b/configs/snow_defconfig index 2b0d6fa..6c76f4d 100644 --- a/configs/snow_defconfig +++ b/configs/snow_defconfig @@ -4,7 +4,12 @@ CONFIG_ARCH_EXYNOS=y CONFIG_TARGET_SNOW=y CONFIG_DEFAULT_DEVICE_TREE="exynos5250-snow" CONFIG_CROS_EC=y -CONFIG_DM_CROS_EC=y CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_KEYB=y CONFIG_CMD_CROS_EC=y +CONFIG_SOUND=y +CONFIG_CMD_SOUND=y +CONFIG_I2S=y +CONFIG_I2S_SAMSUNG=y +CONFIG_SOUND_MAX98095=y +CONFIG_SOUND_WM8994=y diff --git a/configs/socfpga_arria5_defconfig b/configs/socfpga_arria5_defconfig index 87d6007..52032e5 100644 --- a/configs/socfpga_arria5_defconfig +++ b/configs/socfpga_arria5_defconfig @@ -3,6 +3,3 @@ CONFIG_ARM=y CONFIG_TARGET_SOCFPGA_ARRIA5=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="socfpga_arria5_socdk" -CONFIG_DM=y -CONFIG_DM_SPI=y -CONFIG_DM_SPI_FLASH=y diff --git a/configs/socfpga_cyclone5_defconfig b/configs/socfpga_cyclone5_defconfig index 0ebfbfc..6c982ab 100644 --- a/configs/socfpga_cyclone5_defconfig +++ b/configs/socfpga_cyclone5_defconfig @@ -3,6 +3,6 @@ CONFIG_ARM=y CONFIG_TARGET_SOCFPGA_CYCLONE5=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="socfpga_cyclone5_socdk" -CONFIG_DM=y -CONFIG_DM_SPI=y -CONFIG_DM_SPI_FLASH=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/socfpga_socrates_defconfig b/configs/socfpga_socrates_defconfig index 873b721..c81ab0f 100644 --- a/configs/socfpga_socrates_defconfig +++ b/configs/socfpga_socrates_defconfig @@ -3,6 +3,6 @@ CONFIG_ARM=y CONFIG_TARGET_SOCFPGA_CYCLONE5=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="socfpga_cyclone5_socrates" -CONFIG_DM=y -CONFIG_DM_SPI=y -CONFIG_DM_SPI_FLASH=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear300_defconfig b/configs/spear300_defconfig index 25a08df..df0b190 100644 --- a/configs/spear300_defconfig +++ b/configs/spear300_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear300" CONFIG_ARM=y CONFIG_TARGET_SPEAR300=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear300_nand_defconfig b/configs/spear300_nand_defconfig index a4b70e8..a49492c 100644 --- a/configs/spear300_nand_defconfig +++ b/configs/spear300_nand_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear300,nand" CONFIG_ARM=y CONFIG_TARGET_SPEAR300=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear300_usbtty_defconfig b/configs/spear300_usbtty_defconfig index d750cf4..3d60d7f 100644 --- a/configs/spear300_usbtty_defconfig +++ b/configs/spear300_usbtty_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear300,usbtty" CONFIG_ARM=y CONFIG_TARGET_SPEAR300=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear300_usbtty_nand_defconfig b/configs/spear300_usbtty_nand_defconfig index 8bafdb5..ffe4f59 100644 --- a/configs/spear300_usbtty_nand_defconfig +++ b/configs/spear300_usbtty_nand_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear300,usbtty,nand" CONFIG_ARM=y CONFIG_TARGET_SPEAR300=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear310_defconfig b/configs/spear310_defconfig index 8a9ec85..16a6bc3 100644 --- a/configs/spear310_defconfig +++ b/configs/spear310_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear310" CONFIG_ARM=y CONFIG_TARGET_SPEAR310=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear310_nand_defconfig b/configs/spear310_nand_defconfig index 1439ac5..05e3c96 100644 --- a/configs/spear310_nand_defconfig +++ b/configs/spear310_nand_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear310,nand" CONFIG_ARM=y CONFIG_TARGET_SPEAR310=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear310_pnor_defconfig b/configs/spear310_pnor_defconfig index 19604b3..384cb54 100644 --- a/configs/spear310_pnor_defconfig +++ b/configs/spear310_pnor_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear310,FLASH_PNOR" CONFIG_ARM=y CONFIG_TARGET_SPEAR310=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear310_usbtty_defconfig b/configs/spear310_usbtty_defconfig index 6342a56..0115f2c 100644 --- a/configs/spear310_usbtty_defconfig +++ b/configs/spear310_usbtty_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear310,usbtty" CONFIG_ARM=y CONFIG_TARGET_SPEAR310=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear310_usbtty_nand_defconfig b/configs/spear310_usbtty_nand_defconfig index 5b9f1f6..2d82b66 100644 --- a/configs/spear310_usbtty_nand_defconfig +++ b/configs/spear310_usbtty_nand_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear310,usbtty,nand" CONFIG_ARM=y CONFIG_TARGET_SPEAR310=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear310_usbtty_pnor_defconfig b/configs/spear310_usbtty_pnor_defconfig index 0567936..579df36 100644 --- a/configs/spear310_usbtty_pnor_defconfig +++ b/configs/spear310_usbtty_pnor_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear310,usbtty,FLASH_PNOR" CONFIG_ARM=y CONFIG_TARGET_SPEAR310=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear320_defconfig b/configs/spear320_defconfig index 3d91bb1..7bd51a8 100644 --- a/configs/spear320_defconfig +++ b/configs/spear320_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear320" CONFIG_ARM=y CONFIG_TARGET_SPEAR320=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear320_nand_defconfig b/configs/spear320_nand_defconfig index fd0f908..d7c995c 100644 --- a/configs/spear320_nand_defconfig +++ b/configs/spear320_nand_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear320,nand" CONFIG_ARM=y CONFIG_TARGET_SPEAR320=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear320_pnor_defconfig b/configs/spear320_pnor_defconfig index 6cce316..a56a4e0 100644 --- a/configs/spear320_pnor_defconfig +++ b/configs/spear320_pnor_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear320,FLASH_PNOR" CONFIG_ARM=y CONFIG_TARGET_SPEAR320=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear320_usbtty_defconfig b/configs/spear320_usbtty_defconfig index 7ad3d84..c2fb481 100644 --- a/configs/spear320_usbtty_defconfig +++ b/configs/spear320_usbtty_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear320,usbtty" CONFIG_ARM=y CONFIG_TARGET_SPEAR320=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear320_usbtty_nand_defconfig b/configs/spear320_usbtty_nand_defconfig index a5ad90b..98368ed 100644 --- a/configs/spear320_usbtty_nand_defconfig +++ b/configs/spear320_usbtty_nand_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear320,usbtty,nand" CONFIG_ARM=y CONFIG_TARGET_SPEAR320=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear320_usbtty_pnor_defconfig b/configs/spear320_usbtty_pnor_defconfig index 6b110ef..e428d25 100644 --- a/configs/spear320_usbtty_pnor_defconfig +++ b/configs/spear320_usbtty_pnor_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear320,usbtty,FLASH_PNOR" CONFIG_ARM=y CONFIG_TARGET_SPEAR320=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear600_defconfig b/configs/spear600_defconfig index f1cb0aa..dae0d59 100644 --- a/configs/spear600_defconfig +++ b/configs/spear600_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear600" CONFIG_ARM=y CONFIG_TARGET_SPEAR600=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear600_nand_defconfig b/configs/spear600_nand_defconfig index 172c187..cdd98fc 100644 --- a/configs/spear600_nand_defconfig +++ b/configs/spear600_nand_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear600,nand" CONFIG_ARM=y CONFIG_TARGET_SPEAR600=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear600_usbtty_defconfig b/configs/spear600_usbtty_defconfig index cf8b0ec..1e28edf 100644 --- a/configs/spear600_usbtty_defconfig +++ b/configs/spear600_usbtty_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear600,usbtty" CONFIG_ARM=y CONFIG_TARGET_SPEAR600=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/spear600_usbtty_nand_defconfig b/configs/spear600_usbtty_nand_defconfig index 8bd2f07..2f8fd5e 100644 --- a/configs/spear600_usbtty_nand_defconfig +++ b/configs/spear600_usbtty_nand_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="spear600,usbtty,nand" CONFIG_ARM=y CONFIG_TARGET_SPEAR600=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/stm32f429-discovery_defconfig b/configs/stm32f429-discovery_defconfig new file mode 100644 index 0000000..6d74d73 --- /dev/null +++ b/configs/stm32f429-discovery_defconfig @@ -0,0 +1,2 @@ +CONFIG_ARM=y +CONFIG_TARGET_STM32F429_DISCOVERY=y diff --git a/configs/stv0991_defconfig b/configs/stv0991_defconfig index e8cf311..76ba41b 100644 --- a/configs/stv0991_defconfig +++ b/configs/stv0991_defconfig @@ -2,5 +2,6 @@ CONFIG_SYS_EXTRA_OPTIONS="stv0991" CONFIG_ARM=y CONFIG_TARGET_STV0991=y CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_DM=y -CONFIG_DM_SERIAL=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/tao3530_defconfig b/configs/tao3530_defconfig index 077dc89..86ba4cd 100644 --- a/configs/tao3530_defconfig +++ b/configs/tao3530_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_TAO3530=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/tb100_defconfig b/configs/tb100_defconfig index 59f09d9..aed9210 100644 --- a/configs/tb100_defconfig +++ b/configs/tb100_defconfig @@ -8,3 +8,6 @@ CONFIG_SYS_TEXT_BASE=0x84000000 CONFIG_SYS_CLK_FREQ=500000000 CONFIG_OF_CONTROL=y CONFIG_OF_EMBED=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/tricorder_defconfig b/configs/tricorder_defconfig index 745ebc8..e307c65 100644 --- a/configs/tricorder_defconfig +++ b/configs/tricorder_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_TRICORDER=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/tricorder_flash_defconfig b/configs/tricorder_flash_defconfig index cc93566..de6c16e 100644 --- a/configs/tricorder_flash_defconfig +++ b/configs/tricorder_flash_defconfig @@ -3,6 +3,3 @@ CONFIG_SYS_EXTRA_OPTIONS="FLASHCARD" CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_TRICORDER=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/twister_defconfig b/configs/twister_defconfig index 5e7250a..344369d 100644 --- a/configs/twister_defconfig +++ b/configs/twister_defconfig @@ -2,6 +2,3 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_TWISTER=y -CONFIG_DM=n -CONFIG_DM_SERIAL=n -CONFIG_DM_GPIO=n diff --git a/configs/x600_defconfig b/configs/x600_defconfig index c8bec67..7cd239b 100644 --- a/configs/x600_defconfig +++ b/configs/x600_defconfig @@ -1,3 +1,6 @@ CONFIG_SPL=y CONFIG_ARM=y CONFIG_TARGET_X600=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_NETDEVICES=y +CONFIG_NET=y diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig index b6bca82..40d675f 100644 --- a/configs/zynq_microzed_defconfig +++ b/configs/zynq_microzed_defconfig @@ -1,11 +1,10 @@ CONFIG_SPL=y CONFIG_ARM=y -CONFIG_ZYNQ=y +CONFIG_ARCH_ZYNQ=y CONFIG_TARGET_ZYNQ_MICROZED=y CONFIG_OF_CONTROL=y # CONFIG_SYS_MALLOC_F is not set CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y -CONFIG_DM=y CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed" diff --git a/configs/zynq_picozed_defconfig b/configs/zynq_picozed_defconfig new file mode 100644 index 0000000..61852cb --- /dev/null +++ b/configs/zynq_picozed_defconfig @@ -0,0 +1,6 @@ +CONFIG_SPL=y +CONFIG_ARM=y +CONFIG_ARCH_ZYNQ=y +CONFIG_TARGET_ZYNQ_PICOZED=y +CONFIG_OF_CONTROL=n +CONFIG_DEFAULT_DEVICE_TREE="zynq-picozed" diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig index 44f3ae0..7c3cb2d 100644 --- a/configs/zynq_zc70x_defconfig +++ b/configs/zynq_zc70x_defconfig @@ -1,6 +1,6 @@ CONFIG_SPL=y CONFIG_ARM=y -CONFIG_ZYNQ=y +CONFIG_ARCH_ZYNQ=y CONFIG_TARGET_ZYNQ_ZC70X=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702" @@ -8,4 +8,3 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y -CONFIG_DM=y diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig index d689857..36b95fa 100644 --- a/configs/zynq_zc770_xm010_defconfig +++ b/configs/zynq_zc770_xm010_defconfig @@ -1,7 +1,7 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010" CONFIG_ARM=y -CONFIG_ZYNQ=y +CONFIG_ARCH_ZYNQ=y CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010" @@ -9,4 +9,3 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y -CONFIG_DM=y diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig index 9745d21..6c5eecc 100644 --- a/configs/zynq_zc770_xm012_defconfig +++ b/configs/zynq_zc770_xm012_defconfig @@ -1,7 +1,7 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012" CONFIG_ARM=y -CONFIG_ZYNQ=y +CONFIG_ARCH_ZYNQ=y CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012" @@ -9,4 +9,3 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y -CONFIG_DM=y diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig index 924efb4..eabc106 100644 --- a/configs/zynq_zc770_xm013_defconfig +++ b/configs/zynq_zc770_xm013_defconfig @@ -1,7 +1,7 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013" CONFIG_ARM=y -CONFIG_ZYNQ=y +CONFIG_ARCH_ZYNQ=y CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013" @@ -9,4 +9,3 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y -CONFIG_DM=y diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig index 01fa723..b2b4b99 100644 --- a/configs/zynq_zed_defconfig +++ b/configs/zynq_zed_defconfig @@ -1,6 +1,6 @@ CONFIG_SPL=y CONFIG_ARM=y -CONFIG_ZYNQ=y +CONFIG_ARCH_ZYNQ=y CONFIG_TARGET_ZYNQ_ZED=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zed" @@ -8,4 +8,3 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zed" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y -CONFIG_DM=y diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig index f1001f1..da55320 100644 --- a/configs/zynq_zybo_defconfig +++ b/configs/zynq_zybo_defconfig @@ -1,6 +1,6 @@ CONFIG_SPL=y CONFIG_ARM=y -CONFIG_ZYNQ=y +CONFIG_ARCH_ZYNQ=y CONFIG_TARGET_ZYNQ_ZYBO=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo" @@ -8,4 +8,3 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y -CONFIG_DM=y diff --git a/doc/README.drivers.eth b/doc/README.drivers.eth index 42af442..1a9a23b 100644 --- a/doc/README.drivers.eth +++ b/doc/README.drivers.eth @@ -1,3 +1,9 @@ +!!! WARNING !!! + +This guide describes to the old way of doing things. No new Ethernet drivers +should be implemented this way. All new drivers should be written against the +U-Boot core driver model. See doc/driver-model/README.txt + ----------------------- Ethernet Driver Guide ----------------------- @@ -135,11 +141,11 @@ function can be called multiple times in a row. The recv function should process packets as long as the hardware has them readily available before returning. i.e. you should drain the hardware fifo. -For each packet you receive, you should call the NetReceive() function on it +For each packet you receive, you should call the net_process_received_packet() function on it along with the packet length. The common code sets up packet buffers for you -already in the .bss (NetRxPackets), so there should be no need to allocate your -own. This doesn't mean you must use the NetRxPackets array however; you're -free to call the NetReceive() function with any buffer you wish. So the pseudo +already in the .bss (net_rx_packets), so there should be no need to allocate your +own. This doesn't mean you must use the net_rx_packets array however; you're +free to call the net_process_received_packet() function with any buffer you wish. So the pseudo code here would look something like: int ape_recv(struct eth_device *dev) { @@ -147,9 +153,9 @@ int ape_recv(struct eth_device *dev) ... while (packets_are_available()) { ... - length = ape_get_packet(&NetRxPackets[i]); + length = ape_get_packet(&net_rx_packets[i]); ... - NetReceive(&NetRxPackets[i], length); + net_process_received_packet(&net_rx_packets[i], length); ... if (++i >= PKTBUFSRX) i = 0; diff --git a/doc/README.enetaddr b/doc/README.enetaddr index 1eaeaf9..0fafd2c 100644 --- a/doc/README.enetaddr +++ b/doc/README.enetaddr @@ -87,7 +87,7 @@ eth_parse_enetaddr(addr, enetaddr); Look up an environment variable and convert the stored address. If the address is valid, then the function returns 1. Otherwise, the function returns 0. In all cases, the enetaddr memory is initialized. If the env var is not found, -then it is set to all zeros. The common function is_valid_ether_addr() is used +then it is set to all zeros. The common function is_valid_ethaddr() is used to determine address validity. uchar enetaddr[6]; if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { diff --git a/doc/README.fdt-control b/doc/README.fdt-control index d8fe4a8..e6d5ed0 100644 --- a/doc/README.fdt-control +++ b/doc/README.fdt-control @@ -171,6 +171,22 @@ After board configuration is done, fdt supported u-boot can be build in two ways $ make DEVICE_TREE=<dts-file-name> +Configuration Options +--------------------- + +A number of run-time configuration options are provided in the /config node +of the control device tree. You can access these using fdtdec_get_config_int(), +fdtdec_get_config_bool() and fdtdec_get_config_string(). + +Available options are: + +silent-console + If present and non-zero, the console is silenced by default on boot. + +no-keyboard + Tells U-Boot not to expect an attached keyboard with a VGA console + + Limitations ----------- diff --git a/doc/README.link-local b/doc/README.link-local index 9586eca..148b498 100644 --- a/doc/README.link-local +++ b/doc/README.link-local @@ -32,11 +32,11 @@ after successful negotiation to enable network access. ------------- RFC3927 requires that addresses are continuously checked to -avoid conflicts, however this can only happen when the NetLoop +avoid conflicts, however this can only happen when the net_loop is getting called. It is possible for a conflict to go undetected until a command that accesses the network is executed. -Using NetConsole is one way to ensure that NetLoop is always +Using NetConsole is one way to ensure that net_loop is always processing packets and monitoring for conflicts. This is also not a concern if the feature is use to connect diff --git a/doc/device-tree-bindings/i2c/i2c-gpio.txt b/doc/device-tree-bindings/i2c/i2c-gpio.txt new file mode 100644 index 0000000..ba56ed5 --- /dev/null +++ b/doc/device-tree-bindings/i2c/i2c-gpio.txt @@ -0,0 +1,37 @@ +I2C gpio device binding +======================= + +Driver: +- drivers/i2c/i2c-gpio.c + +Software i2c device-tree node properties: +Required: +* #address-cells = <1>; +* #size-cells = <0>; +* compatible = "i2c-gpio"; +* gpios = <sda ...>, <scl ...>; + +Optional: +* i2c-gpio,delay-us = <5>; + The resulting transfer speed can be adjusted by setting the delay[us] + between gpio-toggle operations. Speed [Hz] = 1000000 / 4 * udelay[us], + It not defined, then default is 5us (~50KHz). + +Example: + +i2c-gpio@1 { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "i2c-gpio"; + gpios = <&gpd1 0 GPIO_ACTIVE_HIGH>, /* SDA */ + <&gpd1 1 GPIO_ACTIVE_HIGH>; /* CLK */ + + i2c-gpio,delay-us = <5>; + + some_device@5 { + compatible = "some_device"; + reg = <0x5>; + ... + }; +}; diff --git a/doc/device-tree-bindings/net/allwinner,sun4i-emac.txt b/doc/device-tree-bindings/net/allwinner,sun4i-emac.txt new file mode 100644 index 0000000..10640b1 --- /dev/null +++ b/doc/device-tree-bindings/net/allwinner,sun4i-emac.txt @@ -0,0 +1,19 @@ +* Allwinner EMAC ethernet controller + +Required properties: +- compatible: should be "allwinner,sun4i-a10-emac" (Deprecated: + "allwinner,sun4i-emac") +- reg: address and length of the register set for the device. +- interrupts: interrupt for the device +- phy: see ethernet.txt file in the same directory. +- clocks: A phandle to the reference clock for this device + +Example: + +emac: ethernet@01c0b000 { + compatible = "allwinner,sun4i-a10-emac"; + reg = <0x01c0b000 0x1000>; + interrupts = <55>; + clocks = <&ahb_gates 17>; + phy = <&phy0>; +}; diff --git a/doc/device-tree-bindings/net/allwinner,sun4i-mdio.txt b/doc/device-tree-bindings/net/allwinner,sun4i-mdio.txt new file mode 100644 index 0000000..4ec5641 --- /dev/null +++ b/doc/device-tree-bindings/net/allwinner,sun4i-mdio.txt @@ -0,0 +1,27 @@ +* Allwinner A10 MDIO Ethernet Controller interface + +Required properties: +- compatible: should be "allwinner,sun4i-a10-mdio" + (Deprecated: "allwinner,sun4i-mdio"). +- reg: address and length of the register set for the device. + +Optional properties: +- phy-supply: phandle to a regulator if the PHY needs one + +Example at the SoC level: +mdio@01c0b080 { + compatible = "allwinner,sun4i-a10-mdio"; + reg = <0x01c0b080 0x14>; + #address-cells = <1>; + #size-cells = <0>; +}; + +And at the board level: + +mdio@01c0b080 { + phy-supply = <®_emac_3v3>; + + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; diff --git a/doc/device-tree-bindings/net/allwinner,sun7i-a20-gmac.txt b/doc/device-tree-bindings/net/allwinner,sun7i-a20-gmac.txt new file mode 100644 index 0000000..ea4d752 --- /dev/null +++ b/doc/device-tree-bindings/net/allwinner,sun7i-a20-gmac.txt @@ -0,0 +1,27 @@ +* Allwinner GMAC ethernet controller + +This device is a platform glue layer for stmmac. +Please see stmmac.txt for the other unchanged properties. + +Required properties: + - compatible: Should be "allwinner,sun7i-a20-gmac" + - clocks: Should contain the GMAC main clock, and tx clock + The tx clock type should be "allwinner,sun7i-a20-gmac-clk" + - clock-names: Should contain the clock names "stmmaceth", + and "allwinner_gmac_tx" + +Optional properties: +- phy-supply: phandle to a regulator if the PHY needs one + +Examples: + + gmac: ethernet@01c50000 { + compatible = "allwinner,sun7i-a20-gmac"; + reg = <0x01c50000 0x10000>, + <0x01c20164 0x4>; + interrupts = <0 85 1>; + interrupt-names = "macirq"; + clocks = <&ahb_gates 49>, <&gmac_tx>; + clock-names = "stmmaceth", "allwinner_gmac_tx"; + phy-mode = "mii"; + }; diff --git a/doc/device-tree-bindings/net/ethernet.txt b/doc/device-tree-bindings/net/ethernet.txt new file mode 100644 index 0000000..3fc3605 --- /dev/null +++ b/doc/device-tree-bindings/net/ethernet.txt @@ -0,0 +1,25 @@ +The following properties are common to the Ethernet controllers: + +- local-mac-address: array of 6 bytes, specifies the MAC address that was + assigned to the network device; +- mac-address: array of 6 bytes, specifies the MAC address that was last used by + the boot program; should be used in cases where the MAC address assigned to + the device by the boot program is different from the "local-mac-address" + property; +- max-speed: number, specifies maximum speed in Mbit/s supported by the device; +- max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than + the maximum frame size (there's contradiction in ePAPR). +- phy-mode: string, operation mode of the PHY interface; supported values are + "mii", "gmii", "sgmii", "qsgmii", "tbi", "rev-mii", "rmii", "rgmii", "rgmii-id", + "rgmii-rxid", "rgmii-txid", "rtbi", "smii", "xgmii"; this is now a de-facto + standard property; +- phy-connection-type: the same as "phy-mode" property but described in ePAPR; +- phy-handle: phandle, specifies a reference to a node representing a PHY + device; this property is described in ePAPR and so preferred; +- phy: the same as "phy-handle" property, not recommended for new bindings. +- phy-device: the same as "phy-handle" property, not recommended for new + bindings. + +Child nodes of the Ethernet controller are typically the individual PHY devices +connected via the MDIO bus (sometimes the MDIO bus controller is separate). +They are described in the phy.txt file in this same directory. diff --git a/doc/device-tree-bindings/net/stmmac.txt b/doc/device-tree-bindings/net/stmmac.txt new file mode 100644 index 0000000..5f02517 --- /dev/null +++ b/doc/device-tree-bindings/net/stmmac.txt @@ -0,0 +1,63 @@ +* STMicroelectronics 10/100/1000 Ethernet driver (GMAC) + +Required properties: +- compatible: Should be "snps,dwmac-<ip_version>" "snps,dwmac" + For backwards compatibility: "st,spear600-gmac" is also supported. +- reg: Address and length of the register set for the device +- interrupt-parent: Should be the phandle for the interrupt controller + that services interrupts for this device +- interrupts: Should contain the STMMAC interrupts +- interrupt-names: Should contain the interrupt names "macirq" + "eth_wake_irq" if this interrupt is supported in the "interrupts" + property +- phy-mode: See ethernet.txt file in the same directory. +- snps,reset-gpio gpio number for phy reset. +- snps,reset-active-low boolean flag to indicate if phy reset is active low. +- snps,reset-delays-us is triplet of delays + The 1st cell is reset pre-delay in micro seconds. + The 2nd cell is reset pulse in micro seconds. + The 3rd cell is reset post-delay in micro seconds. +- snps,pbl Programmable Burst Length +- snps,fixed-burst Program the DMA to use the fixed burst mode +- snps,mixed-burst Program the DMA to use the mixed burst mode +- snps,force_thresh_dma_mode Force DMA to use the threshold mode for + both tx and rx +- snps,force_sf_dma_mode Force DMA to use the Store and Forward + mode for both tx and rx. This flag is + ignored if force_thresh_dma_mode is set. +- snps,multicast-filter-bins: Number of multicast filter hash bins + supported by this device instance +- snps,perfect-filter-entries: Number of perfect filter entries supported + by this device instance + +Optional properties: +- resets: Should contain a phandle to the STMMAC reset signal, if any +- reset-names: Should contain the reset signal name "stmmaceth", if a + reset phandle is given +- max-frame-size: See ethernet.txt file in the same directory +- clocks: If present, the first clock should be the GMAC main clock, + further clocks may be specified in derived bindings. +- clock-names: One name for each entry in the clocks property, the + first one should be "stmmaceth". +- clk_ptp_ref: this is the PTP reference clock; in case of the PTP is + available this clock is used for programming the Timestamp Addend Register. + If not passed then the system clock will be used and this is fine on some + platforms. +- snps,burst_len: The AXI burst lenth value of the AXI BUS MODE register. + +Examples: + + gmac0: ethernet@e0800000 { + compatible = "st,spear600-gmac"; + reg = <0xe0800000 0x8000>; + interrupt-parent = <&vic1>; + interrupts = <24 23>; + interrupt-names = "macirq", "eth_wake_irq"; + mac-address = [000000000000]; /* Filled in by U-Boot */ + max-frame-size = <3800>; + phy-mode = "gmii"; + snps,multicast-filter-bins = <256>; + snps,perfect-filter-entries = <128>; + clocks = <&clock>; + clock-names = "stmmaceth"; + }; diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt index f83264d..f0276b1 100644 --- a/doc/driver-model/README.txt +++ b/doc/driver-model/README.txt @@ -95,43 +95,82 @@ are provided in test/dm. To run them, try: You should see something like this: <...U-Boot banner...> - Running 29 driver model tests + Running 53 driver model tests Test: dm_test_autobind Test: dm_test_autoprobe + Test: dm_test_bus_child_post_bind + Test: dm_test_bus_child_post_bind_uclass + Test: dm_test_bus_child_pre_probe_uclass Test: dm_test_bus_children - Device 'd-test': seq 3 is in use by 'b-test' - Device 'c-test@0': seq 0 is in use by 'a-test' - Device 'c-test@1': seq 1 is in use by 'd-test' + Device 'c-test@0': seq 0 is in use by 'd-test' + Device 'c-test@1': seq 1 is in use by 'f-test' Test: dm_test_bus_children_funcs Test: dm_test_bus_children_iterators Test: dm_test_bus_parent_data + Test: dm_test_bus_parent_data_uclass Test: dm_test_bus_parent_ops + Test: dm_test_bus_parent_platdata + Test: dm_test_bus_parent_platdata_uclass Test: dm_test_children + Test: dm_test_device_get_uclass_id + Test: dm_test_eth + Using eth@10002000 device + Using eth@10003000 device + Using eth@10004000 device + Test: dm_test_eth_alias + Using eth@10002000 device + Using eth@10004000 device + Using eth@10002000 device + Using eth@10003000 device + Test: dm_test_eth_prime + Using eth@10003000 device + Using eth@10002000 device + Test: dm_test_eth_rotate + + Error: eth@10004000 address not set. + + Error: eth@10004000 address not set. + Using eth@10002000 device + + Error: eth@10004000 address not set. + + Error: eth@10004000 address not set. + Using eth@10004000 device Test: dm_test_fdt - Device 'd-test': seq 3 is in use by 'b-test' Test: dm_test_fdt_offset Test: dm_test_fdt_pre_reloc Test: dm_test_fdt_uclass_seq - Device 'd-test': seq 3 is in use by 'b-test' - Device 'a-test': seq 0 is in use by 'd-test' Test: dm_test_gpio extra-gpios: get_value: error: gpio b5 not reserved Test: dm_test_gpio_anon Test: dm_test_gpio_copy Test: dm_test_gpio_leak extra-gpios: get_value: error: gpio b5 not reserved + Test: dm_test_gpio_phandles Test: dm_test_gpio_requestf + Test: dm_test_i2c_bytewise + Test: dm_test_i2c_find + Test: dm_test_i2c_offset + Test: dm_test_i2c_offset_len + Test: dm_test_i2c_probe_empty + Test: dm_test_i2c_read_write + Test: dm_test_i2c_speed Test: dm_test_leak Test: dm_test_lifecycle + Test: dm_test_net_retry + Using eth@10004000 device + Using eth@10002000 device + Using eth@10004000 device Test: dm_test_operations Test: dm_test_ordering + Test: dm_test_pci_base + Test: dm_test_pci_swapcase Test: dm_test_platdata Test: dm_test_pre_reloc Test: dm_test_remove Test: dm_test_spi_find Invalid chip select 0:0 (err=-19) SF: Failed to get idcodes - Device 'name-emul': seq 0 is in use by 'name-emul' SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB Test: dm_test_spi_flash 2097152 bytes written in 0 ms @@ -150,6 +189,9 @@ You should see something like this: SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB Test: dm_test_uclass Test: dm_test_uclass_before_ready + Test: dm_test_usb_base + Test: dm_test_usb_flash + USB-1: scanning bus 1 for devices... 2 USB Device(s) found Failures: 0 diff --git a/doc/driver-model/pci-info.txt b/doc/driver-model/pci-info.txt new file mode 100644 index 0000000..63efcb7 --- /dev/null +++ b/doc/driver-model/pci-info.txt @@ -0,0 +1,70 @@ +PCI with Driver Model +===================== + +How busses are scanned +---------------------- + +Any config read will end up at pci_read_config(). This uses +uclass_get_device_by_seq() to get the PCI bus for a particular bus number. +Bus number 0 will need to be requested first, and the alias in the device +tree file will point to the correct device: + + + aliases { + pci0 = &pci; + }; + + pci: pci-controller { + compatible = "sandbox,pci"; + ... + }; + + +If there is no alias the devices will be numbered sequentially in the device +tree. + +The call to uclass_get_device by seq() will cause the PCI bus to be probed. +This does a scan of the bus to locate available devices. These devices are +bound to their appropriate driver if available. If there is no driver, then +they are bound to a generic PCI driver which does nothing. + +After probing a bus, the available devices will appear in the device tree +under that bus. + +Note that this is all done on a lazy basis, as needed, so until something is +touched on PCI it will not be probed. + +PCI devices can appear in the device tree. If they do this serves to specify +the driver to use for the device. In this case they will be bound at +start-up. + + +Sandbox +------- + +With sandbox we need a device emulator for each device on the bus since there +is no real PCI bus. This works by looking in the device tree node for a +driver. For example: + + + pci@1f,0 { + compatible = "pci-generic"; + reg = <0xf800 0 0 0 0>; + emul@1f,0 { + compatible = "sandbox,swap-case"; + }; + }; + +This means that there is a 'sandbox,swap-case' driver at that bus position. +Note that the first cell in the 'reg' value is the bus/device/function. See +PCI_BDF() for the encoding (it is also specified in the IEEE Std 1275-1994 +PCI bus binding document, v2.1) + +When this bus is scanned we will end up with something like this: + +`- * pci-controller @ 05c660c8, 0 + `- pci@1f,0 @ 05c661c8, 63488 + `- emul@1f,0 @ 05c662c8 + +When accesses go to the pci@1f,0 device they are forwarded to its child, the +emulator. diff --git a/doc/driver-model/usb-info.txt b/doc/driver-model/usb-info.txt new file mode 100644 index 0000000..66f2dae --- /dev/null +++ b/doc/driver-model/usb-info.txt @@ -0,0 +1,415 @@ +How USB works with driver model +=============================== + +Introduction +------------ + +Driver model USB support makes use of existing features but changes how +drivers are found. This document provides some information intended to help +understand how things work with USB in U-Boot when driver model is enabled. + + +Enabling driver model for USB +----------------------------- + +A new CONFIG_DM_USB option is provided to enable driver model for USB. This +causes the USB uclass to be included, and drops the equivalent code in +usb.c. In particular the usb_init() function is then implemented by the +uclass. + + +Support for EHCI and XHCI +------------------------- + +So far OHCI is not supported. Both EHCI and XHCI drivers should be declared +as drivers in the USB uclass. For example: + +static const struct udevice_id ehci_usb_ids[] = { + { .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 }, + { .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 }, + { .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 }, + { } +}; + +U_BOOT_DRIVER(usb_ehci) = { + .name = "ehci_tegra", + .id = UCLASS_USB, + .of_match = ehci_usb_ids, + .ofdata_to_platdata = ehci_usb_ofdata_to_platdata, + .probe = tegra_ehci_usb_probe, + .remove = tegra_ehci_usb_remove, + .ops = &ehci_usb_ops, + .platdata_auto_alloc_size = sizeof(struct usb_platdata), + .priv_auto_alloc_size = sizeof(struct fdt_usb), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; + +Here ehci_usb_ids is used to list the controllers that the driver supports. +Each has its own data value. Controllers must be in the UCLASS_USB uclass. + +The ofdata_to_platdata() method allows the controller driver to grab any +necessary settings from the device tree. + +The ops here are ehci_usb_ops. All EHCI drivers will use these same ops in +most cases, since they are all EHCI-compatible. For EHCI there are also some +special operations that can be overridden when calling ehci_register(). + +The driver can use priv_auto_alloc_size to set the size of its private data. +This can hold run-time information needed by the driver for operation. It +exists when the device is probed (not when it is bound) and is removed when +the driver is removed. + +Note that usb_platdata is currently only used to deal with setting up a bus +in USB device mode (OTG operation). It can be omitted if that is not +supported. + +The driver's probe() method should do the basic controller init and then +call ehci_register() to register itself as an EHCI device. It should call +ehci_deregister() in the remove() method. Registering a new EHCI device +does not by itself cause the bus to be scanned. + +The old ehci_hcd_init() function is no-longer used. Nor is it necessary to +set up the USB controllers from board init code. When 'usb start' is used, +each controller will be probed and its bus scanned. + +XHCI works in a similar way. + + +Data structures +--------------- + +The following primary data structures are in use: + +- struct usb_device + This holds information about a device on the bus. All devices have + this structure, even the root hub. The controller itself does not + have this structure. You can access it for a device 'dev' with + dev_get_parentdata(dev). It matches the old structure except that the + parent and child information is not present (since driver model + handles that). Once the device is set up, you can find the device + descriptor and current configuration descriptor in this structure. + +- struct usb_platdata + This holds platform data for a controller. So far this is only used + as a work-around for controllers which can act as USB devices in OTG + mode, since the gadget framework does not use driver model. + +- struct usb_dev_platdata + This holds platform data for a device. You can access it for a + device 'dev' with dev_get_parent_platdata(dev). It holds the device + address and speed - anything that can be determined before the device + driver is actually set up. When probing the bus this structure is + used to provide essential information to the device driver. + +- struct usb_bus_priv + This is private information for each controller, maintained by the + controller uclass. It is mostly used to keep track of the next + device address to use. + +Of these, only struct usb_device was used prior to driver model. + + +USB buses +--------- + +Given a controller, you know the bus - it is the one attached to the +controller. Each controller handles exactly one bus. Every controller has a +root hub attached to it. This hub, which is itself a USB device, can provide +one or more 'ports' to which additional devices can be attached. It is +possible to power up a hub and find out which of its ports have devices +attached. + +Devices are given addresses starting at 1. The root hub is always address 1, +and from there the devices are numbered in sequence. The USB uclass takes +care of this numbering automatically during enumeration. + +USB devices are enumerated by finding a device on a particular hub, and +setting its address to the next available address. The USB bus stretches out +in a tree structure, potentially with multiple hubs each with several ports +and perhaps other hubs. Some hubs will have their own power since otherwise +the 5V 500mA power supplied by the controller will not be sufficient to run +very many devices. + +Enumeration in U-Boot takes a long time since devices are probed one at a +time, and each is given sufficient time to wake up and announce itself. The +timeouts are set for the slowest device. + +Up to 127 devices can be on each bus. USB has four bus speeds: low +(1.5Mbps), full (12Mbps), high (480Mbps) which is only available with USB2 +and newer (EHCI), and super (5Gbps) which is only available with USB3 and +newer (XHCI). If you connect a super-speed device to a high-speed hub, you +will only get high-speed. + + +USB operations +-------------- + +As before driver model, messages can be sent using submit_bulk_msg() and the +like. These are now implemented by the USB uclass and route through the +controller drivers. Note that messages are not sent to the driver of the +device itself - i.e. they don't pass down the stack to the controller. +U-Boot simply finds the controller to which the device is attached, and sends +the message there with an appropriate 'pipe' value so it can be addressed +properly. Having said that, the USB device which should receive the message +is passed in to the driver methods, for use by sandbox. This design decision +is open for review and the code impact of changing it is small since the +methods are typically implemented by the EHCI and XHCI stacks. + +Controller drivers (in UCLASS_USB) themselves provide methods for sending +each message type. For XHCI an additional alloc_device() method is provided +since XHCI needs to allocate a device context before it can even read the +device's descriptor. + +These methods use a 'pipe' which is a collection of bit fields used to +describe the type of message, direction of transfer and the intended +recipient (device number). + + +USB Devices +----------- + +USB devices are found using a simple algorithm which works through the +available hubs in a depth-first search. Devices can be in any uclass, but +are attached to a parent hub (or controller in the case of the root hub) and +so have parent data attached to them (this is struct usb_device). + +By the time the device's probe() method is called, it is enumerated and is +ready to talk to the host. + +The enumeration process needs to work out which driver to attach to each USB +device. It does this by examining the device class, interface class, vendor +ID, product ID, etc. See struct usb_driver_entry for how drivers are matched +with USB devices - you can use the USB_DEVICE() macro to declare a USB +driver. For example, usb_storage.c defines a USB_DEVICE() to handle storage +devices, and it will be used for all USB devices which match. + + + +Technical details on enumeration flow +------------------------------------- + +It is useful to understand precisely how a USB bus is enumerating to avoid +confusion when dealing with USB devices. + +Device initialisation happens roughly like this: + +- At some point the 'usb start' command is run +- This calls usb_init() which works through each controller in turn +- The controller is probed(). This does no enumeration. +- Then usb_scan_bus() is called. This calls usb_scan_device() to scan the +(only) device that is attached to the controller - a root hub +- usb_scan_device() sets up a fake struct usb_device and calls +usb_setup_device(), passing the port number to be scanned, in this case port +0 +- usb_setup_device() first calls usb_prepare_device() to set the device +address, then usb_select_config() to select the first configuration +- at this point the device is enumerated but we do not have a real struct +udevice for it. But we do have the descriptor in struct usb_device so we can +use this to figure out what driver to use +- back in usb_scan_device(), we call usb_find_child() to try to find an +existing device which matches the one we just found on the bus. This can +happen if the device is mentioned in the device tree, or if we previously +scanned the bus and so the device was created before +- if usb_find_child() does not find an existing device, we call +usb_find_and_bind_driver() which tries to bind one +- usb_find_and_bind_driver() searches all available USB drivers (declared +with USB_DEVICE()). If it finds a match it binds that driver to create a new +device. +- If it does not, it binds a generic driver. A generic driver is good enough +to allow access to the device (sending it packets, etc.) but all +functionality will need to be implemented outside the driver model. +- in any case, when usb_find_child() and/or usb_find_and_bind_driver() are +done, we have a device with the correct uclass. At this point we want to +probe the device +- first we store basic information about the new device (address, port, +speed) in its parent platform data. We cannot store it its private data +since that will not exist until the device is probed. +- then we call device_probe() which probes the device +- the first probe step is actually the USB controller's (or USB hubs's) +child_pre_probe() method. This gets called before anything else and is +intended to set up a child device ready to be used with its parent bus. For +USB this calls usb_child_pre_probe() which grabs the information that was +stored in the parent platform data and stores it in the parent private data +(which is struct usb_device, a real one this time). It then calls +usb_select_config() again to make sure that everything about the device is +set up +- note that we have called usb_select_config() twice. This is inefficient +but the alternative is to store additional information in the platform data. +The time taken is minimal and this way is simpler +- at this point the device is set up and ready for use so far as the USB +subsystem is concerned +- the device's probe() method is then called. It can send messages and do +whatever else it wants to make the device work. + +Note that the first device is always a root hub, and this must be scanned to +find any devices. The above steps will have created a hub (UCLASS_USB_HUB), +given it address 1 and set the configuration. + +For hubs, the hub uclass has a post_probe() method. This means that after +any hub is probed, the uclass gets to do some processing. In this case +usb_hub_post_probe() is called, and the following steps take place: + +- usb_hub_post_probe() calls usb_hub_scan() to scan the hub, which in turn +calls usb_hub_configure() +- hub power is enabled +- we loop through each port on the hub, performing the same steps for each +- first, check if there is a device present. This happens in +usb_hub_port_connect_change(). If so, then usb_scan_device() is called to +scan the device, passing the appropriate port number. +- you will recognise usb_scan_device() from the steps above. It sets up the +device ready for use. If it is a hub, it will scan that hub before it +continues here (recursively, depth-first) +- once all hub ports are scanned in this way, the hub is ready for use and +all of its downstream devices also +- additional controllers are scanned in the same way + +The above method has some nice properties: + +- the bus enumeration happens by virtue of driver model's natural device flow +- most logic is in the USB controller and hub uclasses; the actual device +drivers do not need to know they are on a USB bus, at least so far as +enumeration goes +- hub scanning happens automatically after a hub is probed + + +Hubs +---- + +USB hubs are scanned as in the section above. While hubs have their own +uclass, they share some common elements with controllers: + +- they both attach private data to their children (struct usb_device, +accessible for a child with dev_get_parentdata(child)) +- they both use usb_child_pre_probe() to set up their children as proper USB +devices + + +Example - Mass Storage +---------------------- + +As an example of a USB device driver, see usb_storage.c. It uses its own +uclass and declares itself as follows: + +U_BOOT_DRIVER(usb_mass_storage) = { + .name = "usb_mass_storage", + .id = UCLASS_MASS_STORAGE, + .of_match = usb_mass_storage_ids, + .probe = usb_mass_storage_probe, +}; + +static const struct usb_device_id mass_storage_id_table[] = { + { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, + .bInterfaceClass = USB_CLASS_MASS_STORAGE}, + { } /* Terminating entry */ +}; + +USB_DEVICE(usb_mass_storage, mass_storage_id_table); + +The USB_DEVICE() macro attaches the given table of matching information to +the given driver. Note that the driver is declared in U_BOOT_DRIVER() as +'usb_mass_storage' and this must match the first parameter of USB_DEVICE. + +When usb_find_and_bind_driver() is called on a USB device with the +bInterfaceClass value of USB_CLASS_MASS_STORAGE, it will automatically find +this driver and use it. + + +Counter-example: USB Ethernet +----------------------------- + +As an example of the old way of doing things, see usb_ether.c. When the bus +is scanned, all Ethernet devices will be created as generic USB devices (in +uclass UCLASS_USB_DEV_GENERIC). Then, when the scan is completed, +usb_host_eth_scan() will be called. This looks through all the devices on +each bus and manually figures out which are Ethernet devices in the ways of +yore. + +In fact, usb_ether should be moved to driver model. Each USB Ethernet driver +(e.g drivers/usb/eth/asix.c) should include a USB_DEVICE() declaration, so +that it will be found as part of normal USB enumeration. Then, instead of a +generic USB driver, a real (driver-model-aware) driver will be used. Since +Ethernet now supports driver model, this should be fairly easy to achieve, +and then usb_ether.c and the usb_host_eth_scan() will melt away. + + +Sandbox +------- + +All driver model uclasses must have tests and USB is no exception. To +achieve this, a sandbox USB controller is provided. This can make use of +emulation drivers which pretend to be USB devices. Emulations are provided +for a hub and a flash stick. These are enough to create a pretend USB bus +(defined by the sandbox device tree sandbox.dts) which can be scanned and +used. + +Tests in test/dm/usb.c make use of this feature. It allows much of the USB +stack to be tested without real hardware being needed. + +Here is an example device tree fragment: + + usb@1 { + compatible = "sandbox,usb"; + hub { + compatible = "usb-hub"; + usb,device-class = <USB_CLASS_HUB>; + hub-emul { + compatible = "sandbox,usb-hub"; + #address-cells = <1>; + #size-cells = <0>; + flash-stick { + reg = <0>; + compatible = "sandbox,usb-flash"; + sandbox,filepath = "flash.bin"; + }; + }; + }; + }; + +This defines a single controller, containing a root hub (which is required). +The hub is emulated by a hub emulator, and the emulated hub has a single +flash stick to emulate on one of its ports. + +When 'usb start' is used, the following 'dm tree' output will be available: + + usb [ + ] `-- usb@1 + usb_hub [ + ] `-- hub + usb_emul [ + ] |-- hub-emul + usb_emul [ + ] | `-- flash-stick + usb_mass_st [ + ] `-- usb_mass_storage + + +This may look confusing. Most of it mirrors the device tree, but the +'usb_mass_storage' device is not in the device tree. This is created by +usb_find_and_bind_driver() based on the USB_DRIVER in usb_storage.c. While +'flash-stick' is the emulation device, 'usb_mass_storage' is the real U-Boot +USB device driver that talks to it. + + +Future work +----------- + +It is pretty uncommon to have a large USB bus with lots of hubs on an +embedded system. In fact anything other than a root hub is uncommon. Still +it would be possible to speed up enumeration in two ways: + +- breadth-first search would allow devices to be reset and probed in +parallel to some extent +- enumeration could be lazy, in the sense that we could enumerate just the +root hub at first, then only progress to the next 'level' when a device is +used that we cannot find. This could be made easier if the devices were +statically declared in the device tree (which is acceptable for production +boards where the same, known, things are on each bus). + +But in common cases the current algorithm is sufficient. + +Other things that need doing: +- Convert usb_ether to use driver model as described above +- Test that keyboards work (and convert to driver model) +- Move the USB gadget framework to driver model +- Implement OHCI in driver model +- Implement USB PHYs in driver model +- Work out a clever way to provide lazy init for USB devices + +-- +Simon Glass <sjg@chromium.org> +23-Mar-15 diff --git a/doc/git-mailrc b/doc/git-mailrc index 5f8438e..174109f 100644 --- a/doc/git-mailrc +++ b/doc/git-mailrc @@ -24,7 +24,7 @@ alias ijc Ian Campbell <ijc+uboot@hellion.org.uk> alias iwamatsu Nobuhiro Iwamatsu <iwamatsu@nigauri.org> alias jagan Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com> alias jasonjin Jason Jin <jason.jin@freescale.com> -alias jhersh Joe Hershberger <joe.hershberger@gmail.com> +alias jhersh Joe Hershberger <joe.hershberger@ni.com> alias jwrdegoede Hans de Goede <hdegoede@redhat.com> alias kimphill Kim Phillips <kim.phillips@freescale.com> alias luka Luka Perkov <luka.perkov@sartura.hr> @@ -113,6 +113,7 @@ alias x86 uboot, sjg, gruss alias dm uboot, sjg alias cfi uboot, stroese alias dfu uboot, lukma +alias eth uboot, jhersh alias kerneldoc uboot, marex alias fdt uboot, sjg alias i2c uboot, hs @@ -120,6 +121,7 @@ alias kconfig uboot, masahiro alias mmc uboot, panto alias nand uboot, scottwood alias net uboot, jhersh +alias phy uboot, jhersh alias spi uboot, jagan alias ubi uboot, hs alias usb uboot, marex diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index 88b90e0..6508648 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -137,10 +137,10 @@ static void sunxi_dma_init(volatile u8 *port_mmio) } #endif -int ahci_reset(u32 base) +int ahci_reset(void __iomem *base) { int i = 1000; - u32 host_ctl_reg = base + HOST_CTL; + u32 __iomem *host_ctl_reg = base + HOST_CTL; u32 tmp = readl(host_ctl_reg); /* global controller reset */ if ((tmp & HOST_RESET) == 0) @@ -419,8 +419,9 @@ static int ahci_init_one(pci_dev_t pdev) probe_ent->pio_mask = 0x1f; probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */ - pci_read_config_dword(pdev, PCI_BASE_ADDRESS_5, &probe_ent->mmio_base); - debug("ahci mmio_base=0x%08x\n", probe_ent->mmio_base); + probe_ent->mmio_base = pci_map_bar(pdev, PCI_BASE_ADDRESS_5, + PCI_REGION_MEM); + debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base); /* Take from kernel: * JMicron-specific fixup: @@ -939,7 +940,7 @@ void scsi_low_level_init(int busdevfunc) } #ifdef CONFIG_SCSI_AHCI_PLAT -int ahci_init(u32 base) +int ahci_init(void __iomem *base) { int i, rc = 0; u32 linkmap; diff --git a/drivers/block/dwc_ahsata.c b/drivers/block/dwc_ahsata.c index 01a4148..cf3ef6b 100644 --- a/drivers/block/dwc_ahsata.c +++ b/drivers/block/dwc_ahsata.c @@ -343,7 +343,7 @@ static int ahci_init_one(int pdev) | ATA_FLAG_PIO_DMA | ATA_FLAG_NO_ATAPI; - probe_ent->mmio_base = CONFIG_DWC_AHSATA_BASE_ADDR; + probe_ent->mmio_base = (void __iomem *)CONFIG_DWC_AHSATA_BASE_ADDR; /* initialize adapter */ rc = ahci_host_init(probe_ent); diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 75d182d..2861b43 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -46,3 +46,12 @@ config DM_STDIO Normally serial drivers register with stdio so that they can be used as normal output devices. In SPL we don't normally use stdio, so we can omit this feature. + +config DM_SEQ_ALIAS + bool "Support numbered aliases in device tree" + depends on DM + default y + help + Most boards will have a '/aliases' node containing the path to + numbered devices (e.g. serial0 = &serial0). This feature can be + disabled if it is not required, to save code space in SPL. diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index 3a5f48d..6a16b4f 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -66,7 +66,7 @@ static int device_chld_remove(struct udevice *dev) int device_unbind(struct udevice *dev) { - struct driver *drv; + const struct driver *drv; int ret; if (!dev) @@ -92,6 +92,10 @@ int device_unbind(struct udevice *dev) free(dev->platdata); dev->platdata = NULL; } + if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) { + free(dev->uclass_platdata); + dev->uclass_platdata = NULL; + } if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { free(dev->parent_platdata); dev->parent_platdata = NULL; @@ -139,7 +143,7 @@ void device_free(struct udevice *dev) int device_remove(struct udevice *dev) { - struct driver *drv; + const struct driver *drv; int ret; if (!dev) diff --git a/drivers/core/device.c b/drivers/core/device.c index 73c3e07..85fd1fc 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -24,12 +24,13 @@ DECLARE_GLOBAL_DATA_PTR; -int device_bind(struct udevice *parent, struct driver *drv, const char *name, - void *platdata, int of_offset, struct udevice **devp) +int device_bind(struct udevice *parent, const struct driver *drv, + const char *name, void *platdata, int of_offset, + struct udevice **devp) { struct udevice *dev; struct uclass *uc; - int ret = 0; + int size, ret = 0; *devp = NULL; if (!name) @@ -55,21 +56,23 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, dev->seq = -1; dev->req_seq = -1; -#ifdef CONFIG_OF_CONTROL - /* - * Some devices, such as a SPI bus, I2C bus and serial ports are - * numbered using aliases. - * - * This is just a 'requested' sequence, and will be - * resolved (and ->seq updated) when the device is probed. - */ - if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) { - if (uc->uc_drv->name && of_offset != -1) { - fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name, - of_offset, &dev->req_seq); + if (IS_ENABLED(CONFIG_OF_CONTROL) && IS_ENABLED(CONFIG_DM_SEQ_ALIAS)) { + /* + * Some devices, such as a SPI bus, I2C bus and serial ports + * are numbered using aliases. + * + * This is just a 'requested' sequence, and will be + * resolved (and ->seq updated) when the device is probed. + */ + if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) { + if (uc->uc_drv->name && of_offset != -1) { + fdtdec_get_alias_seq(gd->fdt_blob, + uc->uc_drv->name, of_offset, + &dev->req_seq); + } } } -#endif + if (!dev->platdata && drv->platdata_auto_alloc_size) { dev->flags |= DM_FLAG_ALLOC_PDATA; dev->platdata = calloc(1, drv->platdata_auto_alloc_size); @@ -78,9 +81,19 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, goto fail_alloc1; } } - if (parent) { - int size = parent->driver->per_child_platdata_auto_alloc_size; + size = uc->uc_drv->per_device_platdata_auto_alloc_size; + if (size) { + dev->flags |= DM_FLAG_ALLOC_UCLASS_PDATA; + dev->uclass_platdata = calloc(1, size); + if (!dev->uclass_platdata) { + ret = -ENOMEM; + goto fail_alloc2; + } + } + + if (parent) { + size = parent->driver->per_child_platdata_auto_alloc_size; if (!size) { size = parent->uclass->uc_drv-> per_child_platdata_auto_alloc_size; @@ -90,7 +103,7 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, dev->parent_platdata = calloc(1, size); if (!dev->parent_platdata) { ret = -ENOMEM; - goto fail_alloc2; + goto fail_alloc3; } } } @@ -122,21 +135,32 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, return 0; fail_child_post_bind: - if (drv->unbind && drv->unbind(dev)) { - dm_warn("unbind() method failed on dev '%s' on error path\n", - dev->name); + if (IS_ENABLED(CONFIG_DM_DEVICE_REMOVE)) { + if (drv->unbind && drv->unbind(dev)) { + dm_warn("unbind() method failed on dev '%s' on error path\n", + dev->name); + } } fail_bind: - if (uclass_unbind_device(dev)) { - dm_warn("Failed to unbind dev '%s' on error path\n", - dev->name); + if (IS_ENABLED(CONFIG_DM_DEVICE_REMOVE)) { + if (uclass_unbind_device(dev)) { + dm_warn("Failed to unbind dev '%s' on error path\n", + dev->name); + } } fail_uclass_bind: - list_del(&dev->sibling_node); - if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { - free(dev->parent_platdata); - dev->parent_platdata = NULL; + if (IS_ENABLED(CONFIG_DM_DEVICE_REMOVE)) { + list_del(&dev->sibling_node); + if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { + free(dev->parent_platdata); + dev->parent_platdata = NULL; + } + } +fail_alloc3: + if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) { + free(dev->uclass_platdata); + dev->uclass_platdata = NULL; } fail_alloc2: if (dev->flags & DM_FLAG_ALLOC_PDATA) { @@ -164,9 +188,24 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only, -1, devp); } +static void *alloc_priv(int size, uint flags) +{ + void *priv; + + if (flags & DM_FLAG_ALLOC_PRIV_DMA) { + priv = memalign(ARCH_DMA_MINALIGN, size); + if (priv) + memset(priv, '\0', size); + } else { + priv = calloc(1, size); + } + + return priv; +} + int device_probe_child(struct udevice *dev, void *parent_priv) { - struct driver *drv; + const struct driver *drv; int size = 0; int ret; int seq; @@ -182,7 +221,7 @@ int device_probe_child(struct udevice *dev, void *parent_priv) /* Allocate private data if requested */ if (drv->priv_auto_alloc_size) { - dev->priv = calloc(1, drv->priv_auto_alloc_size); + dev->priv = alloc_priv(drv->priv_auto_alloc_size, drv->flags); if (!dev->priv) { ret = -ENOMEM; goto fail; @@ -206,7 +245,7 @@ int device_probe_child(struct udevice *dev, void *parent_priv) per_child_auto_alloc_size; } if (size) { - dev->parent_priv = calloc(1, size); + dev->parent_priv = alloc_priv(size, drv->flags); if (!dev->parent_priv) { ret = -ENOMEM; goto fail; @@ -227,7 +266,9 @@ int device_probe_child(struct udevice *dev, void *parent_priv) } dev->seq = seq; - ret = uclass_pre_probe_child(dev); + dev->flags |= DM_FLAG_ACTIVATED; + + ret = uclass_pre_probe_device(dev); if (ret) goto fail; @@ -243,19 +284,18 @@ int device_probe_child(struct udevice *dev, void *parent_priv) goto fail; } + dev->flags |= DM_FLAG_ACTIVATED; if (drv->probe) { ret = drv->probe(dev); - if (ret) + if (ret) { + dev->flags &= ~DM_FLAG_ACTIVATED; goto fail; + } } - dev->flags |= DM_FLAG_ACTIVATED; - ret = uclass_post_probe_device(dev); - if (ret) { - dev->flags &= ~DM_FLAG_ACTIVATED; + if (ret) goto fail_uclass; - } return 0; fail_uclass: @@ -264,6 +304,8 @@ fail_uclass: __func__, dev->name); } fail: + dev->flags &= ~DM_FLAG_ACTIVATED; + dev->seq = -1; device_free(dev); @@ -295,6 +337,16 @@ void *dev_get_parent_platdata(struct udevice *dev) return dev->parent_platdata; } +void *dev_get_uclass_platdata(struct udevice *dev) +{ + if (!dev) { + dm_warn("%s: null device", __func__); + return NULL; + } + + return dev->uclass_platdata; +} + void *dev_get_priv(struct udevice *dev) { if (!dev) { @@ -305,6 +357,16 @@ void *dev_get_priv(struct udevice *dev) return dev->priv; } +void *dev_get_uclass_priv(struct udevice *dev) +{ + if (!dev) { + dm_warn("%s: null device\n", __func__); + return NULL; + } + + return dev->uclass_priv; +} + void *dev_get_parentdata(struct udevice *dev) { if (!dev) { @@ -440,9 +502,17 @@ struct udevice *dev_get_parent(struct udevice *child) return child->parent; } -ulong dev_get_of_data(struct udevice *dev) +ulong dev_get_driver_data(struct udevice *dev) { - return dev->of_id->data; + return dev->driver_data; +} + +const void *dev_get_driver_ops(struct udevice *dev) +{ + if (!dev || !dev->driver->ops) + return NULL; + + return dev->driver->ops; } enum uclass_id device_get_uclass_id(struct udevice *dev) @@ -450,6 +520,14 @@ enum uclass_id device_get_uclass_id(struct udevice *dev) return dev->uclass->uc_drv->id; } +const char *dev_get_uclass_name(struct udevice *dev) +{ + if (!dev) + return NULL; + + return dev->uclass->uc_drv->name; +} + #ifdef CONFIG_OF_CONTROL fdt_addr_t dev_get_addr(struct udevice *dev) { @@ -461,3 +539,31 @@ fdt_addr_t dev_get_addr(struct udevice *dev) return FDT_ADDR_T_NONE; } #endif + +bool device_has_children(struct udevice *dev) +{ + return !list_empty(&dev->child_head); +} + +bool device_has_active_children(struct udevice *dev) +{ + struct udevice *child; + + for (device_find_first_child(dev, &child); + child; + device_find_next_child(&child)) { + if (device_active(child)) + return true; + } + + return false; +} + +bool device_is_last_sibling(struct udevice *dev) +{ + struct udevice *parent = dev->parent; + + if (!parent) + return false; + return list_is_last(&dev->sibling_node, &parent->child_head); +} diff --git a/drivers/core/lists.c b/drivers/core/lists.c index ff115c4..647e390 100644 --- a/drivers/core/lists.c +++ b/drivers/core/lists.c @@ -168,7 +168,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset, dm_warn("Error binding driver '%s'\n", entry->name); return ret; } else { - dev->of_id = id; + dev->driver_data = id->data; found = true; if (devp) *devp = dev; diff --git a/drivers/core/root.c b/drivers/core/root.c index 9b5c6bb..12d0460 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -197,13 +197,15 @@ int dm_init_and_scan(bool pre_reloc_only) debug("dm_scan_platdata() failed: %d\n", ret); return ret; } -#ifdef CONFIG_OF_CONTROL - ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only); - if (ret) { - debug("dm_scan_fdt() failed: %d\n", ret); - return ret; + + if (OF_CONTROL) { + ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only); + if (ret) { + debug("dm_scan_fdt() failed: %d\n", ret); + return ret; + } } -#endif + ret = dm_scan_other(pre_reloc_only); if (ret) return ret; diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 289a5d2..7de8173 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -99,10 +99,18 @@ fail_mem: int uclass_destroy(struct uclass *uc) { struct uclass_driver *uc_drv; - struct udevice *dev, *tmp; + struct udevice *dev; int ret; - list_for_each_entry_safe(dev, tmp, &uc->dev_head, uclass_node) { + /* + * We cannot use list_for_each_entry_safe() here. If a device in this + * uclass has a child device also in this uclass, it will be also be + * unbound (by the recursion in the call to device_unbind() below). + * We can loop until the list is empty. + */ + while (!list_empty(&uc->dev_head)) { + dev = list_first_entry(&uc->dev_head, struct udevice, + uclass_node); ret = device_remove(dev); if (ret) return ret; @@ -156,6 +164,60 @@ int uclass_find_device(enum uclass_id id, int index, struct udevice **devp) return -ENODEV; } +int uclass_find_first_device(enum uclass_id id, struct udevice **devp) +{ + struct uclass *uc; + int ret; + + *devp = NULL; + ret = uclass_get(id, &uc); + if (ret) + return ret; + if (list_empty(&uc->dev_head)) + return 0; + + *devp = list_first_entry(&uc->dev_head, struct udevice, uclass_node); + + return 0; +} + +int uclass_find_next_device(struct udevice **devp) +{ + struct udevice *dev = *devp; + + *devp = NULL; + if (list_is_last(&dev->uclass_node, &dev->uclass->dev_head)) + return 0; + + *devp = list_entry(dev->uclass_node.next, struct udevice, uclass_node); + + return 0; +} + +int uclass_find_device_by_name(enum uclass_id id, const char *name, + struct udevice **devp) +{ + struct uclass *uc; + struct udevice *dev; + int ret; + + *devp = NULL; + if (!name) + return -EINVAL; + ret = uclass_get(id, &uc); + if (ret) + return ret; + + list_for_each_entry(dev, &uc->dev_head, uclass_node) { + if (!strncmp(dev->name, name, strlen(name))) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq, bool find_req_seq, struct udevice **devp) { @@ -209,22 +271,13 @@ static int uclass_find_device_by_of_offset(enum uclass_id id, int node, return -ENODEV; } -/** - * uclass_get_device_tail() - handle the end of a get_device call - * - * This handles returning an error or probing a device as needed. - * - * @dev: Device that needs to be probed - * @ret: Error to return. If non-zero then the device is not probed - * @devp: Returns the value of 'dev' if there is no error - * @return ret, if non-zero, else the result of the device_probe() call - */ -static int uclass_get_device_tail(struct udevice *dev, int ret, +int uclass_get_device_tail(struct udevice *dev, int ret, struct udevice **devp) { if (ret) return ret; + assert(dev); ret = device_probe(dev); if (ret) return ret; @@ -244,6 +297,17 @@ int uclass_get_device(enum uclass_id id, int index, struct udevice **devp) return uclass_get_device_tail(dev, ret, devp); } +int uclass_get_device_by_name(enum uclass_id id, const char *name, + struct udevice **devp) +{ + struct udevice *dev; + int ret; + + *devp = NULL; + ret = uclass_find_device_by_name(id, name, &dev); + return uclass_get_device_tail(dev, ret, devp); +} + int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp) { struct udevice *dev; @@ -274,24 +338,14 @@ int uclass_get_device_by_of_offset(enum uclass_id id, int node, int uclass_first_device(enum uclass_id id, struct udevice **devp) { - struct uclass *uc; struct udevice *dev; int ret; *devp = NULL; - ret = uclass_get(id, &uc); - if (ret) - return ret; - if (list_empty(&uc->dev_head)) + ret = uclass_find_first_device(id, &dev); + if (!dev) return 0; - - dev = list_first_entry(&uc->dev_head, struct udevice, uclass_node); - ret = device_probe(dev); - if (ret) - return ret; - *devp = dev; - - return 0; + return uclass_get_device_tail(dev, ret, devp); } int uclass_next_device(struct udevice **devp) @@ -300,17 +354,10 @@ int uclass_next_device(struct udevice **devp) int ret; *devp = NULL; - if (list_is_last(&dev->uclass_node, &dev->uclass->dev_head)) + ret = uclass_find_next_device(&dev); + if (!dev) return 0; - - dev = list_entry(dev->uclass_node.next, struct udevice, - uclass_node); - ret = device_probe(dev); - if (ret) - return ret; - *devp = dev; - - return 0; + return uclass_get_device_tail(dev, ret, devp); } int uclass_bind_device(struct udevice *dev) @@ -344,6 +391,7 @@ err: return ret; } +#ifdef CONFIG_DM_DEVICE_REMOVE int uclass_unbind_device(struct udevice *dev) { struct uclass *uc; @@ -359,6 +407,7 @@ int uclass_unbind_device(struct udevice *dev) list_del(&dev->uclass_node); return 0; } +#endif int uclass_resolve_seq(struct udevice *dev) { @@ -391,9 +440,17 @@ int uclass_resolve_seq(struct udevice *dev) return seq; } -int uclass_pre_probe_child(struct udevice *dev) +int uclass_pre_probe_device(struct udevice *dev) { struct uclass_driver *uc_drv; + int ret; + + uc_drv = dev->uclass->uc_drv; + if (uc_drv->pre_probe) { + ret = uc_drv->pre_probe(dev); + if (ret) + return ret; + } if (!dev->parent) return 0; @@ -414,6 +471,7 @@ int uclass_post_probe_device(struct udevice *dev) return 0; } +#ifdef CONFIG_DM_DEVICE_REMOVE int uclass_pre_remove_device(struct udevice *dev) { struct uclass_driver *uc_drv; @@ -435,3 +493,4 @@ int uclass_pre_remove_device(struct udevice *dev) return 0; } +#endif diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index 690e73d..8367c95 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -313,7 +313,10 @@ static void set_timing_cfg_0(const unsigned int ctrl_num, #ifdef CONFIG_SYS_FSL_DDR4 /* tXP=max(4nCK, 6ns) */ int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */ - trwt_mclk = 2; + unsigned int data_rate = get_ddr_freq(ctrl_num); + + /* for faster clock, need more time for data setup */ + trwt_mclk = (data_rate/1000000 > 1900) ? 3 : 2; twrt_mclk = 1; act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp); pre_pd_exit_mclk = act_pd_exit_mclk; @@ -338,7 +341,7 @@ static void set_timing_cfg_0(const unsigned int ctrl_num, */ txp = max((int)mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000)); - ip_rev = fsl_ddr_get_version(); + ip_rev = fsl_ddr_get_version(ctrl_num); if (ip_rev >= 0x40700) { /* * MRS_CYC = max(tMRD, tMOD) @@ -544,7 +547,7 @@ static void set_timing_cfg_1(const unsigned int ctrl_num, * we need set extend bit for it at * TIMING_CFG_3[EXT_CASLAT] */ - if (fsl_ddr_get_version() <= 0x40400) + if (fsl_ddr_get_version(ctrl_num) <= 0x40400) caslat_ctrl = 2 * cas_latency - 1; else caslat_ctrl = (cas_latency - 1) << 1; @@ -1113,16 +1116,32 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr, int i; unsigned short esdmode4 = 0; /* Extended SDRAM mode 4 */ unsigned short esdmode5; /* Extended SDRAM mode 5 */ + int rtt_park = 0; - esdmode5 = 0x00000400; /* Data mask enabled */ + if (ddr->cs[0].config & SDRAM_CS_CONFIG_EN) { + esdmode5 = 0x00000500; /* Data mask enable, RTT_PARK CS0 */ + rtt_park = 1; + } else { + esdmode5 = 0x00000400; /* Data mask enabled */ + } ddr->ddr_sdram_mode_9 = (0 | ((esdmode4 & 0xffff) << 16) | ((esdmode5 & 0xffff) << 0) ); + + /* only mode_9 use 0x500, others use 0x400 */ + debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9); if (unq_mrs_en) { /* unique mode registers are supported */ for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { + if (!rtt_park && + (ddr->cs[i].config & SDRAM_CS_CONFIG_EN)) { + esdmode5 |= 0x00000500; /* RTT_PARK */ + rtt_park = 1; + } else { + esdmode5 = 0x00000400; + } switch (i) { case 1: ddr->ddr_sdram_mode_11 = (0 @@ -1747,9 +1766,17 @@ static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) { unsigned int clk_adjust; /* Clock adjust */ + unsigned int ss_en = 0; /* Source synchronous enable */ +#if defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) + /* Per FSL Application Note: AN2805 */ + ss_en = 1; +#endif clk_adjust = popts->clk_adjust; - ddr->ddr_sdram_clk_cntl = (clk_adjust & 0xF) << 23; + ddr->ddr_sdram_clk_cntl = (0 + | ((ss_en & 0x1) << 31) + | ((clk_adjust & 0xF) << 23) + ); debug("FSLDDR: clk_cntl = 0x%08x\n", ddr->ddr_sdram_clk_cntl); } @@ -1962,31 +1989,41 @@ static void set_ddr_dq_mapping(fsl_ddr_cfg_regs_t *ddr, const dimm_params_t *dimm_params) { unsigned int acc_ecc_en = (ddr->ddr_sdram_cfg >> 2) & 0x1; + int i; + + for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { + if (dimm_params[i].n_ranks) + break; + } + if (i >= CONFIG_DIMM_SLOTS_PER_CTLR) { + puts("DDR error: no DIMM found!\n"); + return; + } - ddr->dq_map_0 = ((dimm_params->dq_mapping[0] & 0x3F) << 26) | - ((dimm_params->dq_mapping[1] & 0x3F) << 20) | - ((dimm_params->dq_mapping[2] & 0x3F) << 14) | - ((dimm_params->dq_mapping[3] & 0x3F) << 8) | - ((dimm_params->dq_mapping[4] & 0x3F) << 2); + ddr->dq_map_0 = ((dimm_params[i].dq_mapping[0] & 0x3F) << 26) | + ((dimm_params[i].dq_mapping[1] & 0x3F) << 20) | + ((dimm_params[i].dq_mapping[2] & 0x3F) << 14) | + ((dimm_params[i].dq_mapping[3] & 0x3F) << 8) | + ((dimm_params[i].dq_mapping[4] & 0x3F) << 2); - ddr->dq_map_1 = ((dimm_params->dq_mapping[5] & 0x3F) << 26) | - ((dimm_params->dq_mapping[6] & 0x3F) << 20) | - ((dimm_params->dq_mapping[7] & 0x3F) << 14) | - ((dimm_params->dq_mapping[10] & 0x3F) << 8) | - ((dimm_params->dq_mapping[11] & 0x3F) << 2); + ddr->dq_map_1 = ((dimm_params[i].dq_mapping[5] & 0x3F) << 26) | + ((dimm_params[i].dq_mapping[6] & 0x3F) << 20) | + ((dimm_params[i].dq_mapping[7] & 0x3F) << 14) | + ((dimm_params[i].dq_mapping[10] & 0x3F) << 8) | + ((dimm_params[i].dq_mapping[11] & 0x3F) << 2); - ddr->dq_map_2 = ((dimm_params->dq_mapping[12] & 0x3F) << 26) | - ((dimm_params->dq_mapping[13] & 0x3F) << 20) | - ((dimm_params->dq_mapping[14] & 0x3F) << 14) | - ((dimm_params->dq_mapping[15] & 0x3F) << 8) | - ((dimm_params->dq_mapping[16] & 0x3F) << 2); + ddr->dq_map_2 = ((dimm_params[i].dq_mapping[12] & 0x3F) << 26) | + ((dimm_params[i].dq_mapping[13] & 0x3F) << 20) | + ((dimm_params[i].dq_mapping[14] & 0x3F) << 14) | + ((dimm_params[i].dq_mapping[15] & 0x3F) << 8) | + ((dimm_params[i].dq_mapping[16] & 0x3F) << 2); /* dq_map for ECC[4:7] is set to 0 if accumulated ECC is enabled */ - ddr->dq_map_3 = ((dimm_params->dq_mapping[17] & 0x3F) << 26) | - ((dimm_params->dq_mapping[8] & 0x3F) << 20) | + ddr->dq_map_3 = ((dimm_params[i].dq_mapping[17] & 0x3F) << 26) | + ((dimm_params[i].dq_mapping[8] & 0x3F) << 20) | (acc_ecc_en ? 0 : - (dimm_params->dq_mapping[9] & 0x3F) << 14) | - dimm_params->dq_mapping_ors; + (dimm_params[i].dq_mapping[9] & 0x3F) << 14) | + dimm_params[i].dq_mapping_ors; debug("FSLDDR: dq_map_0 = 0x%08x\n", ddr->dq_map_0); debug("FSLDDR: dq_map_1 = 0x%08x\n", ddr->dq_map_1); @@ -2349,7 +2386,7 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num, set_ddr_cdr1(ddr, popts); set_ddr_cdr2(ddr, popts); set_ddr_sdram_cfg(ddr, popts, common_dimm); - ip_rev = fsl_ddr_get_version(); + ip_rev = fsl_ddr_get_version(ctrl_num); if (ip_rev > 0x40400) unq_mrs_en = 1; diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index bbfb4ee..42834ca 100644 --- a/drivers/ddr/fsl/ddr4_dimm_params.c +++ b/drivers/ddr/fsl/ddr4_dimm_params.c @@ -135,7 +135,8 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, if (spd->mem_type) { if (spd->mem_type != SPD_MEMTYPE_DDR4) { - printf("DIMM %u: is not a DDR4 SPD.\n", dimm_number); + printf("Ctrl %u DIMM %u: is not a DDR4 SPD.\n", + ctrl_num, dimm_number); return 1; } } else { diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index d9fce7d..49e4688 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -1,5 +1,5 @@ /* - * Copyright 2014 Freescale Semiconductor, Inc. + * Copyright 2014-2015 Freescale Semiconductor, Inc. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -11,6 +11,22 @@ #include <fsl_immap.h> #include <fsl_ddr.h> +#ifdef CONFIG_SYS_FSL_ERRATUM_A008511 +static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits) +{ + int timeout = 1000; + + ddr_out32(ptr, value); + + while (ddr_in32(ptr) & bits) { + udelay(100); + timeout--; + } + if (timeout <= 0) + puts("Error: A007865 wait for clear timeout.\n"); +} +#endif /* CONFIG_SYS_FSL_ERRATUM_A008511 */ + #if (CONFIG_CHIP_SELECTS_PER_CTRL > 4) #error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL #endif @@ -36,6 +52,16 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, defined(CONFIG_SYS_FSL_ERRATUM_A008514) u32 *eddrtqcr1; #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A008511 + u32 temp32, mr6; +#endif +#ifdef CONFIG_FSL_DDR_BIST + u32 mtcr, err_detect, err_sbe; + u32 cs0_bnds, cs1_bnds, cs2_bnds, cs3_bnds, cs0_config; +#endif +#ifdef CONFIG_FSL_DDR_BIST + char buffer[CONFIG_SYS_CBSIZE]; +#endif switch (ctrl_num) { case 0: @@ -214,6 +240,21 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, ddr_setbits32(ddr->debug[28], 0x9 << 20); #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A008511 + /* Part 1 of 2 */ + /* This erraum only applies to verion 5.2.0 */ + if (fsl_ddr_get_version(ctrl_num) == 0x50200) { + /* Disable DRAM VRef training */ + ddr_out32(&ddr->ddr_cdr2, + regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN); + /* Disable deskew */ + ddr_out32(&ddr->debug[28], 0x400); + /* Disable D_INIT */ + ddr_out32(&ddr->sdram_cfg_2, + regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT); + ddr_out32(&ddr->debug[25], 0x9000); + } +#endif /* * For RDIMMs, JEDEC spec requires clocks to be stable before reset is * deasserted. Clocks start when any chip select is enabled and clock @@ -261,6 +302,66 @@ step2: mb(); isb(); +#ifdef CONFIG_SYS_FSL_ERRATUM_A008511 + /* Part 2 of 2 */ + /* This erraum only applies to verion 5.2.0 */ + if (fsl_ddr_get_version(ctrl_num) == 0x50200) { + /* Wait for idle */ + timeout = 200; + while (!(ddr_in32(&ddr->debug[1]) & 0x2) && + (timeout > 0)) { + udelay(100); + timeout--; + } + if (timeout <= 0) { + printf("Controler %d timeout, debug_2 = %x\n", + ctrl_num, ddr_in32(&ddr->debug[1])); + } + /* Set VREF */ + for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { + if (!(regs->cs[i].config & SDRAM_CS_CONFIG_EN)) + continue; + + mr6 = (regs->ddr_sdram_mode_10 >> 16) | + MD_CNTL_MD_EN | + MD_CNTL_CS_SEL(i) | + MD_CNTL_MD_SEL(6) | + 0x00200000; + temp32 = mr6 | 0xc0; + set_wait_for_bits_clear(&ddr->sdram_md_cntl, + temp32, MD_CNTL_MD_EN); + udelay(1); + debug("MR6 = 0x%08x\n", temp32); + temp32 = mr6 | 0xf0; + set_wait_for_bits_clear(&ddr->sdram_md_cntl, + temp32, MD_CNTL_MD_EN); + udelay(1); + debug("MR6 = 0x%08x\n", temp32); + temp32 = mr6 | 0x70; + set_wait_for_bits_clear(&ddr->sdram_md_cntl, + temp32, MD_CNTL_MD_EN); + udelay(1); + debug("MR6 = 0x%08x\n", temp32); + } + ddr_out32(&ddr->sdram_md_cntl, 0); + ddr_out32(&ddr->debug[28], 0); /* Enable deskew */ + ddr_out32(&ddr->debug[1], 0x400); /* restart deskew */ + /* wait for idle */ + timeout = 200; + while (!(ddr_in32(&ddr->debug[1]) & 0x2) && + (timeout > 0)) { + udelay(100); + timeout--; + } + if (timeout <= 0) { + printf("Controler %d timeout, debug_2 = %x\n", + ctrl_num, ddr_in32(&ddr->debug[1])); + } + /* Restore D_INIT */ + ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); + } +#endif /* CONFIG_SYS_FSL_ERRATUM_A008511 */ + total_gb_size_per_controller = 0; for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { if (!(regs->cs[i].config & 0x80000000)) @@ -309,4 +410,70 @@ step2: ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg); } #endif + +#ifdef CONFIG_FSL_DDR_BIST +#define BIST_PATTERN1 0xFFFFFFFF +#define BIST_PATTERN2 0x0 +#define BIST_CR 0x80010000 +#define BIST_CR_EN 0x80000000 +#define BIST_CR_STAT 0x00000001 +#define CTLR_INTLV_MASK 0x20000000 + /* Perform build-in test on memory. Three-way interleaving is not yet + * supported by this code. */ + if (getenv_f("ddr_bist", buffer, CONFIG_SYS_CBSIZE) >= 0) { + puts("Running BIST test. This will take a while..."); + cs0_config = ddr_in32(&ddr->cs0_config); + if (cs0_config & CTLR_INTLV_MASK) { + cs0_bnds = ddr_in32(&cs0_bnds); + cs1_bnds = ddr_in32(&cs1_bnds); + cs2_bnds = ddr_in32(&cs2_bnds); + cs3_bnds = ddr_in32(&cs3_bnds); + /* set bnds to non-interleaving */ + ddr_out32(&cs0_bnds, (cs0_bnds & 0xfffefffe) >> 1); + ddr_out32(&cs1_bnds, (cs1_bnds & 0xfffefffe) >> 1); + ddr_out32(&cs2_bnds, (cs2_bnds & 0xfffefffe) >> 1); + ddr_out32(&cs3_bnds, (cs3_bnds & 0xfffefffe) >> 1); + } + ddr_out32(&ddr->mtp1, BIST_PATTERN1); + ddr_out32(&ddr->mtp2, BIST_PATTERN1); + ddr_out32(&ddr->mtp3, BIST_PATTERN2); + ddr_out32(&ddr->mtp4, BIST_PATTERN2); + ddr_out32(&ddr->mtp5, BIST_PATTERN1); + ddr_out32(&ddr->mtp6, BIST_PATTERN1); + ddr_out32(&ddr->mtp7, BIST_PATTERN2); + ddr_out32(&ddr->mtp8, BIST_PATTERN2); + ddr_out32(&ddr->mtp9, BIST_PATTERN1); + ddr_out32(&ddr->mtp10, BIST_PATTERN2); + mtcr = BIST_CR; + ddr_out32(&ddr->mtcr, mtcr); + timeout = 100; + while (timeout > 0 && (mtcr & BIST_CR_EN)) { + mdelay(1000); + timeout--; + mtcr = ddr_in32(&ddr->mtcr); + } + if (timeout <= 0) + puts("Timeout\n"); + else + puts("Done\n"); + err_detect = ddr_in32(&ddr->err_detect); + err_sbe = ddr_in32(&ddr->err_sbe); + if (mtcr & BIST_CR_STAT) { + printf("BIST test failed on controller %d.\n", + ctrl_num); + } + if (err_detect || (err_sbe & 0xffff)) { + printf("ECC error detected on controller %d.\n", + ctrl_num); + } + + if (cs0_config & CTLR_INTLV_MASK) { + /* restore bnds registers */ + ddr_out32(&cs0_bnds, cs0_bnds); + ddr_out32(&cs1_bnds, cs1_bnds); + ddr_out32(&cs2_bnds, cs2_bnds); + ddr_out32(&cs3_bnds, cs3_bnds); + } + } +#endif } diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c index 32ba6d8..d23e6e5 100644 --- a/drivers/ddr/fsl/interactive.c +++ b/drivers/ddr/fsl/interactive.c @@ -205,6 +205,8 @@ static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo, #define DIMM_PARM(x) {#x, offsetof(dimm_params_t, x), \ sizeof((dimm_params_t *)0)->x, 0} +#define DIMM_PARM_HEX(x) {#x, offsetof(dimm_params_t, x), \ + sizeof((dimm_params_t *)0)->x, 1} static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo, unsigned int ctrl_num, @@ -220,6 +222,7 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo, DIMM_PARM(primary_sdram_width), DIMM_PARM(ec_sdram_width), DIMM_PARM(registered_dimm), + DIMM_PARM(mirrored_dimm), DIMM_PARM(device_width), DIMM_PARM(n_row_addr), @@ -274,7 +277,27 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo, DIMM_PARM(tdqsq_max_ps), DIMM_PARM(tqhs_ps), #endif - +#ifdef CONFIG_SYS_FSL_DDR4 + DIMM_PARM_HEX(dq_mapping[0]), + DIMM_PARM_HEX(dq_mapping[1]), + DIMM_PARM_HEX(dq_mapping[2]), + DIMM_PARM_HEX(dq_mapping[3]), + DIMM_PARM_HEX(dq_mapping[4]), + DIMM_PARM_HEX(dq_mapping[5]), + DIMM_PARM_HEX(dq_mapping[6]), + DIMM_PARM_HEX(dq_mapping[7]), + DIMM_PARM_HEX(dq_mapping[8]), + DIMM_PARM_HEX(dq_mapping[9]), + DIMM_PARM_HEX(dq_mapping[10]), + DIMM_PARM_HEX(dq_mapping[11]), + DIMM_PARM_HEX(dq_mapping[12]), + DIMM_PARM_HEX(dq_mapping[13]), + DIMM_PARM_HEX(dq_mapping[14]), + DIMM_PARM_HEX(dq_mapping[15]), + DIMM_PARM_HEX(dq_mapping[16]), + DIMM_PARM_HEX(dq_mapping[17]), + DIMM_PARM(dq_mapping_ors), +#endif DIMM_PARM(rank_density), DIMM_PARM(capacity), DIMM_PARM(base_address), @@ -296,6 +319,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm) DIMM_PARM(primary_sdram_width), DIMM_PARM(ec_sdram_width), DIMM_PARM(registered_dimm), + DIMM_PARM(mirrored_dimm), DIMM_PARM(device_width), DIMM_PARM(n_row_addr), @@ -314,6 +338,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm) DIMM_PARM(tckmax_ps), DIMM_PARM(caslat_x), + DIMM_PARM_HEX(caslat_x), DIMM_PARM(taa_ps), DIMM_PARM(caslat_x_minus_1), DIMM_PARM(caslat_x_minus_2), @@ -322,6 +347,9 @@ static void print_dimm_parameters(const dimm_params_t *pdimm) DIMM_PARM(trcd_ps), DIMM_PARM(trp_ps), DIMM_PARM(tras_ps), +#if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3) + DIMM_PARM(tfaw_ps), +#endif #ifdef CONFIG_SYS_FSL_DDR4 DIMM_PARM(trfc1_ps), DIMM_PARM(trfc2_ps), @@ -347,6 +375,27 @@ static void print_dimm_parameters(const dimm_params_t *pdimm) DIMM_PARM(tdqsq_max_ps), DIMM_PARM(tqhs_ps), #endif +#ifdef CONFIG_SYS_FSL_DDR4 + DIMM_PARM_HEX(dq_mapping[0]), + DIMM_PARM_HEX(dq_mapping[1]), + DIMM_PARM_HEX(dq_mapping[2]), + DIMM_PARM_HEX(dq_mapping[3]), + DIMM_PARM_HEX(dq_mapping[4]), + DIMM_PARM_HEX(dq_mapping[5]), + DIMM_PARM_HEX(dq_mapping[6]), + DIMM_PARM_HEX(dq_mapping[7]), + DIMM_PARM_HEX(dq_mapping[8]), + DIMM_PARM_HEX(dq_mapping[9]), + DIMM_PARM_HEX(dq_mapping[10]), + DIMM_PARM_HEX(dq_mapping[11]), + DIMM_PARM_HEX(dq_mapping[12]), + DIMM_PARM_HEX(dq_mapping[13]), + DIMM_PARM_HEX(dq_mapping[14]), + DIMM_PARM_HEX(dq_mapping[15]), + DIMM_PARM_HEX(dq_mapping[16]), + DIMM_PARM_HEX(dq_mapping[17]), + DIMM_PARM(dq_mapping_ors), +#endif }; static const unsigned int n_opts = ARRAY_SIZE(options); @@ -463,7 +512,7 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo, CTRL_OPTIONS_CS(3, odt_rd_cfg), CTRL_OPTIONS_CS(3, odt_wr_cfg), #endif -#if defined(CONFIG_SYS_FSL_DDR3) +#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) CTRL_OPTIONS_CS(0, odt_rtt_norm), CTRL_OPTIONS_CS(0, odt_rtt_wr), #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) @@ -753,7 +802,7 @@ static void print_memctl_options(const memctl_options_t *popts) CTRL_OPTIONS_CS(3, odt_rd_cfg), CTRL_OPTIONS_CS(3, odt_wr_cfg), #endif -#if defined(CONFIG_SYS_FSL_DDR3) +#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) CTRL_OPTIONS_CS(0, odt_rtt_norm), CTRL_OPTIONS_CS(0, odt_rtt_wr), #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) @@ -795,6 +844,7 @@ static void print_memctl_options(const memctl_options_t *popts) CTRL_OPTIONS(twot_en), CTRL_OPTIONS(threet_en), CTRL_OPTIONS(registered_dimm_en), + CTRL_OPTIONS(mirrored_dimm), CTRL_OPTIONS(ap_en), CTRL_OPTIONS(x4_en), CTRL_OPTIONS(bstopre), diff --git a/drivers/ddr/fsl/lc_common_dimm_params.c b/drivers/ddr/fsl/lc_common_dimm_params.c index b295344..b12eeb9 100644 --- a/drivers/ddr/fsl/lc_common_dimm_params.c +++ b/drivers/ddr/fsl/lc_common_dimm_params.c @@ -22,7 +22,7 @@ compute_cas_latency(const unsigned int ctrl_num, unsigned int common_caslat; unsigned int caslat_actual; unsigned int retry = 16; - unsigned int tmp; + unsigned int tmp = ~0; const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); #ifdef CONFIG_SYS_FSL_DDR3 const unsigned int taamax = 20000; @@ -31,8 +31,7 @@ compute_cas_latency(const unsigned int ctrl_num, #endif /* compute the common CAS latency supported between slots */ - tmp = dimm_params[0].caslat_x; - for (i = 1; i < number_of_dimms; i++) { + for (i = 0; i < number_of_dimms; i++) { if (dimm_params[i].n_ranks) tmp &= dimm_params[i].caslat_x; } diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index b72b242..fa22383 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -453,7 +453,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, retval = compute_dimm_parameters( i, spd, pdimm, j); #ifdef CONFIG_SYS_DDR_RAW_TIMING - if (!i && !j && retval) { + if (!j && retval) { printf("SPD error on controller %d! " "Trying fallback to raw timing " "calculation\n", i); diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c index 5beb11b..3b30fa2 100644 --- a/drivers/ddr/fsl/options.c +++ b/drivers/ddr/fsl/options.c @@ -728,7 +728,12 @@ unsigned int populate_memctl_options(int all_dimms_registered, /* Choose ddr controller address mirror mode */ #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) - popts->mirrored_dimm = pdimm[0].mirrored_dimm; + for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { + if (pdimm[i].n_ranks) { + popts->mirrored_dimm = pdimm[i].mirrored_dimm; + break; + } + } #endif /* Global Timing Parameters. */ diff --git a/drivers/ddr/fsl/util.c b/drivers/ddr/fsl/util.c index 664081b..ce55aea 100644 --- a/drivers/ddr/fsl/util.c +++ b/drivers/ddr/fsl/util.c @@ -23,12 +23,34 @@ #define ULL_8FS 0xFFFFFFFFULL -u32 fsl_ddr_get_version(void) +u32 fsl_ddr_get_version(unsigned int ctrl_num) { struct ccsr_ddr __iomem *ddr; u32 ver_major_minor_errata; - ddr = (void *)_DDR_ADDR; + switch (ctrl_num) { + case 0: + ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; + break; +#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) + case 1: + ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; + break; +#endif +#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) + case 2: + ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; + break; +#endif +#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) + case 3: + ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; + break; +#endif + default: + printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num); + return 0; + } ver_major_minor_errata = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8; ver_major_minor_errata |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8; @@ -212,7 +234,7 @@ void print_ddr_info(unsigned int start_ctrl) /* Calculate CAS latency based on timing cfg values */ cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf); - if (fsl_ddr_get_version() <= 0x40400) + if (fsl_ddr_get_version(0) <= 0x40400) cas_lat += 1; else cas_lat += 2; diff --git a/drivers/demo/demo-simple.c b/drivers/demo/demo-simple.c index 2bcb7df..f069748 100644 --- a/drivers/demo/demo-simple.c +++ b/drivers/demo/demo-simple.c @@ -10,6 +10,7 @@ #include <common.h> #include <dm.h> #include <dm-demo.h> +#include <mapmem.h> #include <asm/io.h> static int simple_hello(struct udevice *dev, int ch) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 7b5178a..0840a30 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -14,3 +14,24 @@ config LPC32XX_GPIO default n help Support for the LPC32XX GPIO driver. + +config SANDBOX_GPIO + bool "Enable sandbox GPIO driver" + depends on SANDBOX && DM && DM_GPIO + help + This driver supports some simulated GPIOs which can be adjusted + using 'back door' functions like sandbox_gpio_set_value(). Then the + GPIOs can be inspected through the normal get_get_value() + interface. The purpose of this is to allow GPIOs to be used as + normal in sandbox, perhaps with test code actually driving the + behaviour of those GPIOs. + +config SANDBOX_GPIO_COUNT + int "Number of sandbox GPIOs" + depends on SANDBOX_GPIO + default 128 + help + The sandbox driver can support any number of GPIOs. Generally these + are specified using the device tree. But you can also have a number + of 'anonymous' GPIOs that do not belong to any device or bank. + Select a suitable value depending on your needs. diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 85f71c5..fb40e09 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -42,3 +42,5 @@ obj-$(CONFIG_TCA642X) += tca642x.o oby-$(CONFIG_SX151X) += sx151x.o obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o obj-$(CONFIG_LPC32XX_GPIO) += lpc32xx_gpio.o +obj-$(CONFIG_STM32_GPIO) += stm32_gpio.o +obj-$(CONFIG_ZYNQ_GPIO) += zynq_gpio.o diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c index 22fbd63..75a32ee 100644 --- a/drivers/gpio/at91_gpio.c +++ b/drivers/gpio/at91_gpio.c @@ -511,7 +511,7 @@ static int at91_gpio_probe(struct udevice *dev) { struct at91_port_priv *port = dev_get_priv(dev); struct at91_port_platdata *plat = dev_get_platdata(dev); - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); uc_priv->bank_name = plat->bank_name; uc_priv->gpio_count = GPIO_PER_BANK; diff --git a/drivers/gpio/bcm2835_gpio.c b/drivers/gpio/bcm2835_gpio.c index 0244c01..fbc641d 100644 --- a/drivers/gpio/bcm2835_gpio.c +++ b/drivers/gpio/bcm2835_gpio.c @@ -105,7 +105,7 @@ static int bcm2835_gpio_probe(struct udevice *dev) { struct bcm2835_gpios *gpios = dev_get_priv(dev); struct bcm2835_gpio_platdata *plat = dev_get_platdata(dev); - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); uc_priv->bank_name = "GPIO"; uc_priv->gpio_count = BCM2835_GPIO_COUNT; diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index a69bbd2..381868b 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -34,7 +34,7 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc) for (ret = uclass_first_device(UCLASS_GPIO, &dev); dev; ret = uclass_next_device(&dev)) { - uc_priv = dev->uclass_priv; + uc_priv = dev_get_uclass_priv(dev); if (gpio >= uc_priv->gpio_base && gpio < uc_priv->gpio_base + uc_priv->gpio_count) { desc->dev = dev; @@ -65,7 +65,7 @@ int gpio_lookup_name(const char *name, struct udevice **devp, ret = uclass_next_device(&dev)) { int len; - uc_priv = dev->uclass_priv; + uc_priv = dev_get_uclass_priv(dev); if (numeric != -1) { offset = numeric - uc_priv->gpio_base; /* Allow GPIOs to be numbered from 0 */ @@ -116,7 +116,7 @@ static int dm_gpio_request(struct gpio_desc *desc, const char *label) char *str; int ret; - uc_priv = dev->uclass_priv; + uc_priv = dev_get_uclass_priv(dev); if (uc_priv->name[desc->offset]) return -EBUSY; str = strdup(label); @@ -195,7 +195,7 @@ int _dm_gpio_free(struct udevice *dev, uint offset) struct gpio_dev_priv *uc_priv; int ret; - uc_priv = dev->uclass_priv; + uc_priv = dev_get_uclass_priv(dev); if (!uc_priv->name[offset]) return -ENXIO; if (gpio_get_ops(dev)->free) { @@ -232,7 +232,7 @@ int gpio_free(unsigned gpio) static int check_reserved(struct gpio_desc *desc, const char *func) { - struct gpio_dev_priv *uc_priv = desc->dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc->dev); if (!uc_priv->name[desc->offset]) { printf("%s: %s: error: gpio %s%d not reserved\n", @@ -402,7 +402,7 @@ const char *gpio_get_bank_info(struct udevice *dev, int *bit_count) struct gpio_dev_priv *priv; /* Must be called on an active device */ - priv = dev->uclass_priv; + priv = dev_get_uclass_priv(dev); assert(priv); *bit_count = priv->gpio_count; @@ -420,7 +420,7 @@ static const char * const gpio_function[GPIOF_COUNT] = { int get_function(struct udevice *dev, int offset, bool skip_unused, const char **namep) { - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct dm_gpio_ops *ops = gpio_get_ops(dev); BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); @@ -468,7 +468,7 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize) BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); *buf = 0; - priv = dev->uclass_priv; + priv = dev_get_uclass_priv(dev); ret = gpio_get_raw_function(dev, offset, NULL); if (ret < 0) return ret; @@ -590,11 +590,7 @@ int gpio_request_list_by_name_nodev(const void *blob, int node, int count; int ret; - for (count = 0; ; count++) { - if (count >= max_count) { - ret = -ENOSPC; - goto err; - } + for (count = 0; count < max_count; count++) { ret = _gpio_request_by_name_nodev(blob, node, list_name, count, &desc[count], flags, true); if (ret == -ENOENT) @@ -680,7 +676,7 @@ static int gpio_renumber(struct udevice *removed_dev) base = 0; uclass_foreach_dev(dev, uc) { if (device_active(dev) && dev != removed_dev) { - uc_priv = dev->uclass_priv; + uc_priv = dev_get_uclass_priv(dev); uc_priv->gpio_base = base; base += uc_priv->gpio_count; } @@ -689,9 +685,21 @@ static int gpio_renumber(struct udevice *removed_dev) return 0; } +int gpio_get_number(struct gpio_desc *desc) +{ + struct udevice *dev = desc->dev; + struct gpio_dev_priv *uc_priv; + + if (!dev) + return -1; + uc_priv = dev->uclass_priv; + + return uc_priv->gpio_base + desc->offset; +} + static int gpio_post_probe(struct udevice *dev) { - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *)); if (!uc_priv->name) @@ -702,7 +710,7 @@ static int gpio_post_probe(struct udevice *dev) static int gpio_pre_remove(struct udevice *dev) { - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); int i; for (i = 0; i < uc_priv->gpio_count; i++) { diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c index 7720cc3..7e679a0 100644 --- a/drivers/gpio/intel_ich6_gpio.c +++ b/drivers/gpio/intel_ich6_gpio.c @@ -64,13 +64,13 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) pci_dev = PCI_BDF(0, 0x1f, 0); /* Is the device present? */ - tmpword = pci_read_config16(pci_dev, PCI_VENDOR_ID); + tmpword = x86_pci_read_config16(pci_dev, PCI_VENDOR_ID); if (tmpword != PCI_VENDOR_ID_INTEL) { debug("%s: wrong VendorID\n", __func__); return -ENODEV; } - tmpword = pci_read_config16(pci_dev, PCI_DEVICE_ID); + tmpword = x86_pci_read_config16(pci_dev, PCI_DEVICE_ID); debug("Found %04x:%04x\n", PCI_VENDOR_ID_INTEL, tmpword); /* * We'd like to validate the Device ID too, but pretty much any @@ -80,34 +80,34 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) */ /* I/O should already be enabled (it's a RO bit). */ - tmpword = pci_read_config16(pci_dev, PCI_COMMAND); + tmpword = x86_pci_read_config16(pci_dev, PCI_COMMAND); if (!(tmpword & PCI_COMMAND_IO)) { debug("%s: device IO not enabled\n", __func__); return -ENODEV; } /* Header Type must be normal (bits 6-0 only; see spec.) */ - tmpbyte = pci_read_config8(pci_dev, PCI_HEADER_TYPE); + tmpbyte = x86_pci_read_config8(pci_dev, PCI_HEADER_TYPE); if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) { debug("%s: invalid Header type\n", __func__); return -ENODEV; } /* Base Class must be a bridge device */ - tmpbyte = pci_read_config8(pci_dev, PCI_CLASS_CODE); + tmpbyte = x86_pci_read_config8(pci_dev, PCI_CLASS_CODE); if (tmpbyte != PCI_CLASS_CODE_BRIDGE) { debug("%s: invalid class\n", __func__); return -ENODEV; } /* Sub Class must be ISA */ - tmpbyte = pci_read_config8(pci_dev, PCI_CLASS_SUB_CODE); + tmpbyte = x86_pci_read_config8(pci_dev, PCI_CLASS_SUB_CODE); if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) { debug("%s: invalid subclass\n", __func__); return -ENODEV; } /* Programming Interface must be 0x00 (no others exist) */ - tmpbyte = pci_read_config8(pci_dev, PCI_CLASS_PROG); + tmpbyte = x86_pci_read_config8(pci_dev, PCI_CLASS_PROG); if (tmpbyte != 0x00) { debug("%s: invalid interface type\n", __func__); return -ENODEV; @@ -123,7 +123,7 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) * while on the Ivybridge the bit0 is used to indicate it is an * I/O space. */ - tmplong = pci_read_config32(pci_dev, PCI_CFG_GPIOBASE); + tmplong = x86_pci_read_config32(pci_dev, PCI_CFG_GPIOBASE); if (tmplong == 0x00000000 || tmplong == 0xffffffff) { debug("%s: unexpected GPIOBASE value\n", __func__); return -ENODEV; @@ -151,7 +151,7 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) static int ich6_gpio_probe(struct udevice *dev) { struct ich6_bank_platdata *plat = dev_get_platdata(dev); - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct ich6_bank_priv *bank = dev_get_priv(dev); if (gd->arch.gpio_map) { diff --git a/drivers/gpio/mvgpio.h b/drivers/gpio/mvgpio.h index a3f17a0..1de7395 100644 --- a/drivers/gpio/mvgpio.h +++ b/drivers/gpio/mvgpio.h @@ -14,9 +14,8 @@ #include <common.h> -#ifdef CONFIG_SHEEVA_88SV331xV5 /* - * GPIO Register map for SHEEVA 88SV331xV5 + * GPIO Register map for Marvell SOCs */ struct gpio_reg { u32 gplr; /* Pin Level Register - 0x0000 */ @@ -51,8 +50,5 @@ struct gpio_reg { u32 pad12[2]; u32 apmask; /* Bitwise Mask of Edge Detect Register - 0x009C */ }; -#else -#error "CPU core subversion not defined" -#endif #endif /* __MVGPIO_H__ */ diff --git a/drivers/gpio/mvmfp.c b/drivers/gpio/mvmfp.c index 97bbe99..43ecf66 100644 --- a/drivers/gpio/mvmfp.c +++ b/drivers/gpio/mvmfp.c @@ -43,18 +43,8 @@ void mfp_config(u32 *mfp_cfgs) /* Write a mfg register as per configuration */ val = 0; - if (cfg_val & MFP_AF_FLAG) - /* Abstract and program Afternate-Func Selection */ - val |= cfg_val & MFP_AF_MASK; - if (cfg_val & MFP_EDGE_FLAG) - /* Abstract and program Edge configuration */ - val |= cfg_val & MFP_LPM_EDGE_MASK; - if (cfg_val & MFP_DRIVE_FLAG) - /* Abstract and program Drive configuration */ - val |= cfg_val & MFP_DRIVE_MASK; - if (cfg_val & MFP_PULL_FLAG) - /* Abstract and program Pullup/down configuration */ - val |= cfg_val & MFP_PULL_MASK; + if (cfg_val & MFP_VALUE_MASK) + val |= cfg_val & MFP_VALUE_MASK; writel(val, p_mfpr); } while (1); diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c index 815407b..2012f99 100644 --- a/drivers/gpio/mxc_gpio.c +++ b/drivers/gpio/mxc_gpio.c @@ -266,7 +266,7 @@ static int mxc_gpio_probe(struct udevice *dev) { struct mxc_bank_info *bank = dev_get_priv(dev); struct mxc_gpio_plat *plat = dev_get_platdata(dev); - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); int banknum; char name[18], *str; diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c index 19fc451..0a1e124 100644 --- a/drivers/gpio/omap_gpio.c +++ b/drivers/gpio/omap_gpio.c @@ -309,7 +309,7 @@ static int omap_gpio_probe(struct udevice *dev) { struct gpio_bank *bank = dev_get_priv(dev); struct omap_gpio_platdata *plat = dev_get_platdata(dev); - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); char name[18], *str; sprintf(name, "GPIO%d_", plat->bank_index); diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c index 0a245ba..49b1054 100644 --- a/drivers/gpio/s5p_gpio.c +++ b/drivers/gpio/s5p_gpio.c @@ -296,7 +296,7 @@ static const struct dm_gpio_ops gpio_exynos_ops = { static int gpio_exynos_probe(struct udevice *dev) { - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct exynos_bank_info *priv = dev->priv; struct exynos_gpio_platdata *plat = dev->platdata; diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c index d564c25..a9b1efc 100644 --- a/drivers/gpio/sandbox.c +++ b/drivers/gpio/sandbox.c @@ -24,7 +24,7 @@ struct gpio_state { /* Access routines for GPIO state */ static u8 *get_gpio_flags(struct udevice *dev, unsigned offset) { - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct gpio_state *state = dev_get_priv(dev); if (offset >= uc_priv->gpio_count) { @@ -160,7 +160,7 @@ static const struct dm_gpio_ops gpio_sandbox_ops = { static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev) { - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "num-gpios", 0); @@ -172,7 +172,7 @@ static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev) static int gpio_sandbox_probe(struct udevice *dev) { - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); if (dev->of_offset == -1) { /* Tell the uclass how many GPIOs we have */ diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c new file mode 100644 index 0000000..d3497e9 --- /dev/null +++ b/drivers/gpio/stm32_gpio.c @@ -0,0 +1,199 @@ +/* + * (C) Copyright 2011 + * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/stm32.h> +#include <asm/arch/gpio.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define STM32_GPIOA_BASE (STM32_AHB1PERIPH_BASE + 0x0000) +#define STM32_GPIOB_BASE (STM32_AHB1PERIPH_BASE + 0x0400) +#define STM32_GPIOC_BASE (STM32_AHB1PERIPH_BASE + 0x0800) +#define STM32_GPIOD_BASE (STM32_AHB1PERIPH_BASE + 0x0C00) +#define STM32_GPIOE_BASE (STM32_AHB1PERIPH_BASE + 0x1000) +#define STM32_GPIOF_BASE (STM32_AHB1PERIPH_BASE + 0x1400) +#define STM32_GPIOG_BASE (STM32_AHB1PERIPH_BASE + 0x1800) +#define STM32_GPIOH_BASE (STM32_AHB1PERIPH_BASE + 0x1C00) +#define STM32_GPIOI_BASE (STM32_AHB1PERIPH_BASE + 0x2000) + +static const unsigned long io_base[] = { + STM32_GPIOA_BASE, STM32_GPIOB_BASE, STM32_GPIOC_BASE, + STM32_GPIOD_BASE, STM32_GPIOE_BASE, STM32_GPIOF_BASE, + STM32_GPIOG_BASE, STM32_GPIOH_BASE, STM32_GPIOI_BASE +}; + +struct stm32_gpio_regs { + u32 moder; /* GPIO port mode */ + u32 otyper; /* GPIO port output type */ + u32 ospeedr; /* GPIO port output speed */ + u32 pupdr; /* GPIO port pull-up/pull-down */ + u32 idr; /* GPIO port input data */ + u32 odr; /* GPIO port output data */ + u32 bsrr; /* GPIO port bit set/reset */ + u32 lckr; /* GPIO port configuration lock */ + u32 afr[2]; /* GPIO alternate function */ +}; + +#define CHECK_DSC(x) (!x || x->port > 8 || x->pin > 15) +#define CHECK_CTL(x) (!x || x->af > 15 || x->mode > 3 || x->otype > 1 || \ + x->pupd > 2 || x->speed > 3) + +int stm32_gpio_config(const struct stm32_gpio_dsc *dsc, + const struct stm32_gpio_ctl *ctl) +{ + struct stm32_gpio_regs *gpio_regs; + u32 i; + int rv; + + if (CHECK_DSC(dsc)) { + rv = -EINVAL; + goto out; + } + if (CHECK_CTL(ctl)) { + rv = -EINVAL; + goto out; + } + + gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; + + setbits_le32(&STM32_RCC->ahb1enr, 1 << dsc->port); + + i = (dsc->pin & 0x07) * 4; + clrbits_le32(&gpio_regs->afr[dsc->pin >> 3], (0xF << i)); + setbits_le32(&gpio_regs->afr[dsc->pin >> 3], ctl->af << i); + + i = dsc->pin * 2; + + clrbits_le32(&gpio_regs->moder, (0x3 << i)); + setbits_le32(&gpio_regs->moder, ctl->mode << i); + + clrbits_le32(&gpio_regs->otyper, (0x3 << i)); + setbits_le32(&gpio_regs->otyper, ctl->otype << i); + + clrbits_le32(&gpio_regs->ospeedr, (0x3 << i)); + setbits_le32(&gpio_regs->ospeedr, ctl->speed << i); + + clrbits_le32(&gpio_regs->pupdr, (0x3 << i)); + setbits_le32(&gpio_regs->pupdr, ctl->pupd << i); + + rv = 0; +out: + return rv; +} + +int stm32_gpout_set(const struct stm32_gpio_dsc *dsc, int state) +{ + struct stm32_gpio_regs *gpio_regs; + int rv; + + if (CHECK_DSC(dsc)) { + rv = -EINVAL; + goto out; + } + + gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; + + if (state) + writel(1 << dsc->pin, &gpio_regs->bsrr); + else + writel(1 << (dsc->pin + 16), &gpio_regs->bsrr); + + rv = 0; +out: + return rv; +} + +int stm32_gpin_get(const struct stm32_gpio_dsc *dsc) +{ + struct stm32_gpio_regs *gpio_regs; + int rv; + + if (CHECK_DSC(dsc)) { + rv = -EINVAL; + goto out; + } + + gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; + rv = readl(&gpio_regs->idr) & (1 << dsc->pin); +out: + return rv; +} + +/* Common GPIO API */ + +int gpio_request(unsigned gpio, const char *label) +{ + return 0; +} + +int gpio_free(unsigned gpio) +{ + return 0; +} + +int gpio_direction_input(unsigned gpio) +{ + struct stm32_gpio_dsc dsc; + struct stm32_gpio_ctl ctl; + + dsc.port = stm32_gpio_to_port(gpio); + dsc.pin = stm32_gpio_to_pin(gpio); + ctl.af = STM32_GPIO_AF0; + ctl.mode = STM32_GPIO_MODE_IN; + ctl.pupd = STM32_GPIO_PUPD_NO; + ctl.speed = STM32_GPIO_SPEED_50M; + + return stm32_gpio_config(&dsc, &ctl); +} + +int gpio_direction_output(unsigned gpio, int value) +{ + struct stm32_gpio_dsc dsc; + struct stm32_gpio_ctl ctl; + int res; + + dsc.port = stm32_gpio_to_port(gpio); + dsc.pin = stm32_gpio_to_pin(gpio); + ctl.af = STM32_GPIO_AF0; + ctl.mode = STM32_GPIO_MODE_OUT; + ctl.otype = STM32_GPIO_OTYPE_PP; + ctl.pupd = STM32_GPIO_PUPD_NO; + ctl.speed = STM32_GPIO_SPEED_50M; + + res = stm32_gpio_config(&dsc, &ctl); + if (res < 0) + goto out; + res = stm32_gpout_set(&dsc, value); +out: + return res; +} + +int gpio_get_value(unsigned gpio) +{ + struct stm32_gpio_dsc dsc; + + dsc.port = stm32_gpio_to_port(gpio); + dsc.pin = stm32_gpio_to_pin(gpio); + + return stm32_gpin_get(&dsc); +} + +int gpio_set_value(unsigned gpio, int value) +{ + struct stm32_gpio_dsc dsc; + + dsc.port = stm32_gpio_to_port(gpio); + dsc.pin = stm32_gpio_to_pin(gpio); + + return stm32_gpout_set(&dsc, value); +} diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 6296092..cf5c624 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -21,6 +21,9 @@ #ifdef CONFIG_AXP209_POWER #include <axp209.h> #endif +#ifdef CONFIG_AXP221_POWER +#include <axp221.h> +#endif DECLARE_GLOBAL_DATA_PTR; @@ -115,6 +118,20 @@ int gpio_set_value(unsigned gpio, int value) return sunxi_gpio_output(gpio, value); } +int sunxi_name_to_gpio_bank(const char *name) +{ + int group = 0; + + if (*name == 'P' || *name == 'p') + name++; + if (*name >= 'A') { + group = *name - (*name > 'a' ? 'a' : 'A'); + return group; + } + + return -1; +} + int sunxi_name_to_gpio(const char *name) { int group = 0; @@ -125,6 +142,12 @@ int sunxi_name_to_gpio(const char *name) #ifdef AXP_GPIO if (strncasecmp(name, "AXP0-", 5) == 0) { name += 5; + if (strcmp(name, "VBUS-DETECT") == 0) + return SUNXI_GPIO_AXP0_START + + SUNXI_GPIO_AXP0_VBUS_DETECT; + if (strcmp(name, "VBUS-ENABLE") == 0) + return SUNXI_GPIO_AXP0_START + + SUNXI_GPIO_AXP0_VBUS_ENABLE; pin = simple_strtol(name, &eptr, 10); if (!*name || *eptr) return -1; @@ -238,7 +261,7 @@ static char *gpio_bank_name(int bank) static int gpio_sunxi_probe(struct udevice *dev) { struct sunxi_gpio_platdata *plat = dev_get_platdata(dev); - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); /* Tell the uclass how many GPIOs we have */ if (plat) { diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c index f870cdb..8017e35 100644 --- a/drivers/gpio/tegra_gpio.c +++ b/drivers/gpio/tegra_gpio.c @@ -295,7 +295,7 @@ static const struct udevice_id tegra_gpio_ids[] = { static int gpio_tegra_probe(struct udevice *dev) { - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct tegra_port_info *priv = dev->priv; struct tegra_gpio_platdata *plat = dev->platdata; diff --git a/drivers/gpio/zynq_gpio.c b/drivers/gpio/zynq_gpio.c new file mode 100644 index 0000000..83a2c46 --- /dev/null +++ b/drivers/gpio/zynq_gpio.c @@ -0,0 +1,220 @@ +/* + * Xilinx Zynq GPIO device driver + * + * Copyright (C) 2015 DAVE Embedded Systems <devel@dave.eu> + * + * Most of code taken from linux kernel driver (linux/drivers/gpio/gpio-zynq.c) + * Copyright (C) 2009 - 2014 Xilinx, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <asm/errno.h> + +/** + * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank + * for a given pin in the GPIO device + * @pin_num: gpio pin number within the device + * @bank_num: an output parameter used to return the bank number of the gpio + * pin + * @bank_pin_num: an output parameter used to return pin number within a bank + * for the given gpio pin + * + * Returns the bank number and pin offset within the bank. + */ +static inline void zynq_gpio_get_bank_pin(unsigned int pin_num, + unsigned int *bank_num, + unsigned int *bank_pin_num) +{ + switch (pin_num) { + case ZYNQ_GPIO_BANK0_PIN_MIN ... ZYNQ_GPIO_BANK0_PIN_MAX: + *bank_num = 0; + *bank_pin_num = pin_num; + break; + case ZYNQ_GPIO_BANK1_PIN_MIN ... ZYNQ_GPIO_BANK1_PIN_MAX: + *bank_num = 1; + *bank_pin_num = pin_num - ZYNQ_GPIO_BANK1_PIN_MIN; + break; + case ZYNQ_GPIO_BANK2_PIN_MIN ... ZYNQ_GPIO_BANK2_PIN_MAX: + *bank_num = 2; + *bank_pin_num = pin_num - ZYNQ_GPIO_BANK2_PIN_MIN; + break; + case ZYNQ_GPIO_BANK3_PIN_MIN ... ZYNQ_GPIO_BANK3_PIN_MAX: + *bank_num = 3; + *bank_pin_num = pin_num - ZYNQ_GPIO_BANK3_PIN_MIN; + break; + default: + printf("invalid GPIO pin number: %u\n", pin_num); + *bank_num = 0; + *bank_pin_num = 0; + break; + } +} + +int gpio_is_valid(unsigned gpio) +{ + return (gpio >= 0) && (gpio < ZYNQ_GPIO_NR_GPIOS); +} + +static int check_gpio(unsigned gpio) +{ + if (!gpio_is_valid(gpio)) { + printf("ERROR : check_gpio: invalid GPIO %d\n", gpio); + return -1; + } + return 0; +} + +/** + * gpio_get_value - Get the state of the specified pin of GPIO device + * @gpio: gpio pin number within the device + * + * This function reads the state of the specified pin of the GPIO device. + * + * Return: 0 if the pin is low, 1 if pin is high. + */ +int gpio_get_value(unsigned gpio) +{ + u32 data; + unsigned int bank_num, bank_pin_num; + + if (check_gpio(gpio) < 0) + return -1; + + zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); + + data = readl(ZYNQ_GPIO_BASE_ADDRESS + + ZYNQ_GPIO_DATA_RO_OFFSET(bank_num)); + + return (data >> bank_pin_num) & 1; +} + +/** + * gpio_set_value - Modify the value of the pin with specified value + * @gpio: gpio pin number within the device + * @value: value used to modify the value of the specified pin + * + * This function calculates the register offset (i.e to lower 16 bits or + * upper 16 bits) based on the given pin number and sets the value of a + * gpio pin to the specified value. The value is either 0 or non-zero. + */ +int gpio_set_value(unsigned gpio, int value) +{ + unsigned int reg_offset, bank_num, bank_pin_num; + + if (check_gpio(gpio) < 0) + return -1; + + zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); + + if (bank_pin_num >= ZYNQ_GPIO_MID_PIN_NUM) { + /* only 16 data bits in bit maskable reg */ + bank_pin_num -= ZYNQ_GPIO_MID_PIN_NUM; + reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num); + } else { + reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num); + } + + /* + * get the 32 bit value to be written to the mask/data register where + * the upper 16 bits is the mask and lower 16 bits is the data + */ + value = !!value; + value = ~(1 << (bank_pin_num + ZYNQ_GPIO_MID_PIN_NUM)) & + ((value << bank_pin_num) | ZYNQ_GPIO_UPPER_MASK); + + writel(value, ZYNQ_GPIO_BASE_ADDRESS + reg_offset); + + return 0; +} + +/** + * gpio_direction_input - Set the direction of the specified GPIO pin as input + * @gpio: gpio pin number within the device + * + * This function uses the read-modify-write sequence to set the direction of + * the gpio pin as input. + * + * Return: -1 if invalid gpio specified, 0 if successul + */ +int gpio_direction_input(unsigned gpio) +{ + u32 reg; + unsigned int bank_num, bank_pin_num; + + if (check_gpio(gpio) < 0) + return -1; + + zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); + + /* bank 0 pins 7 and 8 are special and cannot be used as inputs */ + if (bank_num == 0 && (bank_pin_num == 7 || bank_pin_num == 8)) + return -1; + + /* clear the bit in direction mode reg to set the pin as input */ + reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); + reg &= ~BIT(bank_pin_num); + writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); + + return 0; +} + +/** + * gpio_direction_output - Set the direction of the specified GPIO pin as output + * @gpio: gpio pin number within the device + * @value: value to be written to specified pin + * + * This function sets the direction of specified GPIO pin as output, configures + * the Output Enable register for the pin and uses zynq_gpio_set to set + * the value of the pin to the value specified. + * + * Return: 0 always + */ +int gpio_direction_output(unsigned gpio, int value) +{ + u32 reg; + unsigned int bank_num, bank_pin_num; + + if (check_gpio(gpio) < 0) + return -1; + + zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); + + /* set the GPIO pin as output */ + reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); + reg |= BIT(bank_pin_num); + writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); + + /* configure the output enable reg for the pin */ + reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_OUTEN_OFFSET(bank_num)); + reg |= BIT(bank_pin_num); + writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_OUTEN_OFFSET(bank_num)); + + /* set the state of the pin */ + gpio_set_value(gpio, value); + return 0; +} + +/** + * Request a gpio before using it. + * + * NOTE: Argument 'label' is unused. + */ +int gpio_request(unsigned gpio, const char *label) +{ + if (check_gpio(gpio) < 0) + return -1; + + return 0; +} + +/** + * Reset and free the gpio after using it. + */ +int gpio_free(unsigned gpio) +{ + return 0; +} diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 692810d..ba43019 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -2,16 +2,13 @@ config DM_I2C bool "Enable Driver Model for I2C drivers" depends on DM help - Enable driver model for I2C. This SPI flash interface - (spi_flash_probe(), spi_flash_write(), etc.) is then - implemented by the SPI flash uclass. There is one standard - SPI flash driver which knows how to probe most chips - supported by U-Boot. The uclass interface is defined in - include/spi_flash.h, but is currently fully compatible - with the old interface to avoid confusion and duplication - during the transition parent. SPI and SPI flash must be - enabled together (it is not possible to use driver model - for one and not the other). + Enable driver model for I2C. The I2C uclass interface: probe, read, + write and speed, is implemented with the bus drivers operations, + which provide methods for bus setting and data transfer. Each chip + device (bus child) info is kept as parent platdata. The interface + is defined in include/i2c.h. When i2c bus driver supports the i2c + uclass, but the device drivers not, then DM_I2C_COMPAT config can + be used as compatibility layer. config DM_I2C_COMPAT bool "Enable I2C compatibility layer" @@ -22,6 +19,45 @@ config DM_I2C_COMPAT to convert all code for a board in a single commit. It should not be enabled for any board in an official release. +config DM_I2C_GPIO + bool "Enable Driver Model for software emulated I2C bus driver" + depends on DM_I2C && DM_GPIO + help + Enable the i2c bus driver emulation by using the GPIOs. The bus GPIO + configuration is given by the device tree. Kernel-style device tree + bindings are supported. + Binding info: doc/device-tree-bindings/i2c/i2c-gpio.txt + +config SYS_I2C_SANDBOX + bool "Sandbox I2C driver" + depends on SANDBOX && DM_I2C + help + Enable I2C support for sandbox. This is an emulation of a real I2C + bus. Devices can be attached to the bus using the device tree + which specifies the driver to use. As an example, see this device + tree fragment from sandbox.dts. It shows that the I2C bus has a + single EEPROM at address 0x2c (7-bit address) which is emulated by + the driver for "sandbox,i2c-eeprom", which is in + drivers/misc/i2c_eeprom_emul.c. + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + compatible = "sandbox,i2c"; + clock-frequency = <400000>; + eeprom@2c { + reg = <0x2c>; + compatible = "i2c-eeprom"; + emul { + compatible = "sandbox,i2c-eeprom"; + sandbox,filename = "i2c.bin"; + sandbox,size = <128>; + }; + }; + }; + + config SYS_I2C_UNIPHIER bool "UniPhier I2C driver" depends on ARCH_UNIPHIER && DM_I2C diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 26ea854..d9e912f 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -6,6 +6,7 @@ # obj-$(CONFIG_DM_I2C) += i2c-uclass.o obj-$(CONFIG_DM_I2C_COMPAT) += i2c-uclass-compat.o +obj-$(CONFIG_DM_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o obj-$(CONFIG_I2C_MV) += mv_i2c.o diff --git a/drivers/i2c/i2c-gpio.c b/drivers/i2c/i2c-gpio.c new file mode 100644 index 0000000..ed899d4 --- /dev/null +++ b/drivers/i2c/i2c-gpio.c @@ -0,0 +1,346 @@ +/* + * (C) Copyright 2015, Samsung Electronics + * Przemyslaw Marczak <p.marczak@samsung.com> + * + * This file is based on: drivers/i2c/soft-i2c.c, + * with added driver-model support and code cleanup. + */ +#include <common.h> +#include <errno.h> +#include <dm.h> +#include <i2c.h> +#include <asm/gpio.h> + +#define DEFAULT_UDELAY 5 +#define RETRIES 0 +#define I2C_ACK 0 +#define I2C_NOACK 1 + +DECLARE_GLOBAL_DATA_PTR; + +enum { + PIN_SDA = 0, + PIN_SCL, + PIN_COUNT, +}; + +struct i2c_gpio_bus { + /** + * udelay - delay [us] between GPIO toggle operations, + * which is 1/4 of I2C speed clock period. + */ + int udelay; + /* sda, scl */ + struct gpio_desc gpios[PIN_COUNT]; +}; + +static int i2c_gpio_sda_get(struct gpio_desc *sda) +{ + return dm_gpio_get_value(sda); +} + +static void i2c_gpio_sda_set(struct gpio_desc *sda, int bit) +{ + if (bit) { + dm_gpio_set_dir_flags(sda, GPIOD_IS_IN); + } else { + dm_gpio_set_dir_flags(sda, GPIOD_IS_OUT); + dm_gpio_set_value(sda, 0); + } +} + +static void i2c_gpio_scl_set(struct gpio_desc *scl, int bit) +{ + dm_gpio_set_dir_flags(scl, GPIOD_IS_OUT); + dm_gpio_set_value(scl, bit); +} + +static void i2c_gpio_write_bit(struct gpio_desc *scl, struct gpio_desc *sda, + int delay, uchar bit) +{ + i2c_gpio_scl_set(scl, 0); + udelay(delay); + i2c_gpio_sda_set(sda, bit); + udelay(delay); + i2c_gpio_scl_set(scl, 1); + udelay(2 * delay); +} + +static int i2c_gpio_read_bit(struct gpio_desc *scl, struct gpio_desc *sda, + int delay) +{ + int value; + + i2c_gpio_scl_set(scl, 1); + udelay(delay); + value = i2c_gpio_sda_get(sda); + udelay(delay); + i2c_gpio_scl_set(scl, 0); + udelay(2 * delay); + + return value; +} + +/* START: High -> Low on SDA while SCL is High */ +static void i2c_gpio_send_start(struct gpio_desc *scl, struct gpio_desc *sda, + int delay) +{ + udelay(delay); + i2c_gpio_sda_set(sda, 1); + udelay(delay); + i2c_gpio_scl_set(scl, 1); + udelay(delay); + i2c_gpio_sda_set(sda, 0); + udelay(delay); +} + +/* STOP: Low -> High on SDA while SCL is High */ +static void i2c_gpio_send_stop(struct gpio_desc *scl, struct gpio_desc *sda, + int delay) +{ + i2c_gpio_scl_set(scl, 0); + udelay(delay); + i2c_gpio_sda_set(sda, 0); + udelay(delay); + i2c_gpio_scl_set(scl, 1); + udelay(delay); + i2c_gpio_sda_set(sda, 1); + udelay(delay); +} + +/* ack should be I2C_ACK or I2C_NOACK */ +static void i2c_gpio_send_ack(struct gpio_desc *scl, struct gpio_desc *sda, + int delay, int ack) +{ + i2c_gpio_write_bit(scl, sda, delay, ack); + i2c_gpio_scl_set(scl, 0); + udelay(delay); +} + +/** + * Send a reset sequence consisting of 9 clocks with the data signal high + * to clock any confused device back into an idle state. Also send a + * <stop> at the end of the sequence for belts & suspenders. + */ +static void i2c_gpio_send_reset(struct gpio_desc *scl, struct gpio_desc *sda, + int delay) +{ + int j; + + for (j = 0; j < 9; j++) + i2c_gpio_write_bit(scl, sda, delay, 1); + + i2c_gpio_send_stop(scl, sda, delay); +} + +/* Set sda high with low clock, before reading slave data */ +static void i2c_gpio_sda_high(struct gpio_desc *scl, struct gpio_desc *sda, + int delay) +{ + i2c_gpio_scl_set(scl, 0); + udelay(delay); + i2c_gpio_sda_set(sda, 1); + udelay(delay); +} + +/* Send 8 bits and look for an acknowledgement */ +static int i2c_gpio_write_byte(struct gpio_desc *scl, struct gpio_desc *sda, + int delay, uchar data) +{ + int j; + int nack; + + for (j = 0; j < 8; j++) { + i2c_gpio_write_bit(scl, sda, delay, data & 0x80); + data <<= 1; + } + + udelay(delay); + + /* Look for an <ACK>(negative logic) and return it */ + i2c_gpio_sda_high(scl, sda, delay); + nack = i2c_gpio_read_bit(scl, sda, delay); + + return nack; /* not a nack is an ack */ +} + +/** + * if ack == I2C_ACK, ACK the byte so can continue reading, else + * send I2C_NOACK to end the read. + */ +static uchar i2c_gpio_read_byte(struct gpio_desc *scl, struct gpio_desc *sda, + int delay, int ack) +{ + int data; + int j; + + i2c_gpio_sda_high(scl, sda, delay); + data = 0; + for (j = 0; j < 8; j++) { + data <<= 1; + data |= i2c_gpio_read_bit(scl, sda, delay); + } + i2c_gpio_send_ack(scl, sda, delay, ack); + + return data; +} + +/* send start and the slave chip address */ +int i2c_send_slave_addr(struct gpio_desc *scl, struct gpio_desc *sda, int delay, + uchar chip) +{ + i2c_gpio_send_start(scl, sda, delay); + + if (i2c_gpio_write_byte(scl, sda, delay, chip)) { + i2c_gpio_send_stop(scl, sda, delay); + return -EIO; + } + + return 0; +} + +static int i2c_gpio_write_data(struct i2c_gpio_bus *bus, uchar chip, + uchar *buffer, int len, + bool end_with_repeated_start) +{ + struct gpio_desc *scl = &bus->gpios[PIN_SCL]; + struct gpio_desc *sda = &bus->gpios[PIN_SDA]; + unsigned int delay = bus->udelay; + int failures = 0; + + debug("%s: chip %x buffer %p len %d\n", __func__, chip, buffer, len); + + if (i2c_send_slave_addr(scl, sda, delay, chip << 1)) { + debug("i2c_write, no chip responded %02X\n", chip); + return -EIO; + } + + while (len-- > 0) { + if (i2c_gpio_write_byte(scl, sda, delay, *buffer++)) + failures++; + } + + if (!end_with_repeated_start) { + i2c_gpio_send_stop(scl, sda, delay); + return failures; + } + + if (i2c_send_slave_addr(scl, sda, delay, (chip << 1) | 0x1)) { + debug("i2c_write, no chip responded %02X\n", chip); + return -EIO; + } + + return failures; +} + +static int i2c_gpio_read_data(struct i2c_gpio_bus *bus, uchar chip, + uchar *buffer, int len) +{ + struct gpio_desc *scl = &bus->gpios[PIN_SCL]; + struct gpio_desc *sda = &bus->gpios[PIN_SDA]; + unsigned int delay = bus->udelay; + + debug("%s: chip %x buffer: %p len %d\n", __func__, chip, buffer, len); + + while (len-- > 0) + *buffer++ = i2c_gpio_read_byte(scl, sda, delay, len == 0); + + i2c_gpio_send_stop(scl, sda, delay); + + return 0; +} + +static int i2c_gpio_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs) +{ + struct i2c_gpio_bus *bus = dev_get_priv(dev); + int ret; + + for (; nmsgs > 0; nmsgs--, msg++) { + bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD); + + if (msg->flags & I2C_M_RD) { + ret = i2c_gpio_read_data(bus, msg->addr, msg->buf, + msg->len); + } else { + ret = i2c_gpio_write_data(bus, msg->addr, msg->buf, + msg->len, next_is_read); + } + + if (ret) + return -EREMOTEIO; + } + + return 0; +} + +static int i2c_gpio_probe(struct udevice *dev, uint chip, uint chip_flags) +{ + struct i2c_gpio_bus *bus = dev_get_priv(dev); + struct gpio_desc *scl = &bus->gpios[PIN_SCL]; + struct gpio_desc *sda = &bus->gpios[PIN_SDA]; + unsigned int delay = bus->udelay; + int ret; + + i2c_gpio_send_start(scl, sda, delay); + ret = i2c_gpio_write_byte(scl, sda, delay, (chip << 1) | 0); + i2c_gpio_send_stop(scl, sda, delay); + + debug("%s: bus: %d (%s) chip: %x flags: %x ret: %d\n", + __func__, dev->seq, dev->name, chip, chip_flags, ret); + + return ret; +} + +static int i2c_gpio_set_bus_speed(struct udevice *dev, unsigned int speed_hz) +{ + struct i2c_gpio_bus *bus = dev_get_priv(dev); + struct gpio_desc *scl = &bus->gpios[PIN_SCL]; + struct gpio_desc *sda = &bus->gpios[PIN_SDA]; + + bus->udelay = 1000000 / (speed_hz << 2); + + i2c_gpio_send_reset(scl, sda, bus->udelay); + + return 0; +} + +static int i2c_gpio_ofdata_to_platdata(struct udevice *dev) +{ + struct i2c_gpio_bus *bus = dev_get_priv(dev); + const void *blob = gd->fdt_blob; + int node = dev->of_offset; + int ret; + + ret = gpio_request_list_by_name(dev, "gpios", bus->gpios, + ARRAY_SIZE(bus->gpios), 0); + if (ret < 0) + goto error; + + bus->udelay = fdtdec_get_int(blob, node, "i2c-gpio,delay-us", + DEFAULT_UDELAY); + + return 0; +error: + error("Can't get %s gpios! Error: %d", dev->name, ret); + return ret; +} + +static const struct dm_i2c_ops i2c_gpio_ops = { + .xfer = i2c_gpio_xfer, + .probe_chip = i2c_gpio_probe, + .set_bus_speed = i2c_gpio_set_bus_speed, +}; + +static const struct udevice_id i2c_gpio_ids[] = { + { .compatible = "i2c-gpio" }, + { } +}; + +U_BOOT_DRIVER(i2c_gpio) = { + .name = "i2c-gpio", + .id = UCLASS_I2C, + .of_match = i2c_gpio_ids, + .ofdata_to_platdata = i2c_gpio_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct i2c_gpio_bus), + .ops = &i2c_gpio_ops, +}; diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index b890806..f2e95c0 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -330,7 +330,7 @@ int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags, int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) { struct dm_i2c_ops *ops = i2c_get_ops(bus); - struct dm_i2c_bus *i2c = bus->uclass_priv; + struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus); int ret; /* @@ -351,7 +351,7 @@ int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) int dm_i2c_get_bus_speed(struct udevice *bus) { struct dm_i2c_ops *ops = i2c_get_ops(bus); - struct dm_i2c_bus *i2c = bus->uclass_priv; + struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus); if (!ops->get_bus_speed) return i2c->speed_hz; @@ -432,7 +432,7 @@ int i2c_chip_ofdata_to_platdata(const void *blob, int node, static int i2c_post_probe(struct udevice *dev) { - struct dm_i2c_bus *i2c = dev->uclass_priv; + struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev); i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "clock-frequency", 100000); diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c index fd28c17..d29dd45 100644 --- a/drivers/i2c/i2c-uniphier-f.c +++ b/drivers/i2c/i2c-uniphier-f.c @@ -14,6 +14,7 @@ #include <dm/root.h> #include <i2c.h> #include <fdtdec.h> +#include <mapmem.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/drivers/i2c/i2c-uniphier.c b/drivers/i2c/i2c-uniphier.c index 666272d..c4972ff 100644 --- a/drivers/i2c/i2c-uniphier.c +++ b/drivers/i2c/i2c-uniphier.c @@ -14,6 +14,7 @@ #include <dm/root.h> #include <i2c.h> #include <fdtdec.h> +#include <mapmem.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index 6f6edd5..f20d1b2 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -14,7 +14,7 @@ #include <asm/io.h> /* - * include a file that will provide CONFIG_I2C_MVTWSI_BASE + * include a file that will provide CONFIG_I2C_MVTWSI_BASE* * and possibly other settings */ @@ -91,11 +91,39 @@ struct mvtwsi_registers { #define MVTWSI_STATUS_IDLE 0xF8 /* - * The single instance of the controller we'll be dealing with + * MVTWSI controller base */ -static struct mvtwsi_registers *twsi = - (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE; +static struct mvtwsi_registers *twsi_get_base(struct i2c_adapter *adap) +{ + switch (adap->hwadapnr) { +#ifdef CONFIG_I2C_MVTWSI_BASE0 + case 0: + return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE0; +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE1 + case 1: + return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE1; +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE2 + case 2: + return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE2; +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE3 + case 3: + return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE3; +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE4 + case 4: + return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE4; +#endif + default: + printf("Missing mvtwsi controller %d base\n", adap->hwadapnr); + break; + } + + return NULL; +} /* * Returned statuses are 0 for success and nonzero otherwise. @@ -117,8 +145,9 @@ static struct mvtwsi_registers *twsi = * Wait for IFLG to raise, or return 'timeout'; then if status is as expected, * return 0 (ok) or return 'wrong status'. */ -static int twsi_wait(int expected_status) +static int twsi_wait(struct i2c_adapter *adap, int expected_status) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); int control, status; int timeout = 1000; @@ -153,35 +182,40 @@ static u8 twsi_control_flags = MVTWSI_CONTROL_TWSIEN; * Assert the START condition, either in a single I2C transaction * or inside back-to-back ones (repeated starts). */ -static int twsi_start(int expected_status) +static int twsi_start(struct i2c_adapter *adap, int expected_status) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); + /* globally set TWSIEN in case it was not */ twsi_control_flags |= MVTWSI_CONTROL_TWSIEN; /* assert START */ writel(twsi_control_flags | MVTWSI_CONTROL_START, &twsi->control); /* wait for controller to process START */ - return twsi_wait(expected_status); + return twsi_wait(adap, expected_status); } /* * Send a byte (i2c address or data). */ -static int twsi_send(u8 byte, int expected_status) +static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); + /* put byte in data register for sending */ writel(byte, &twsi->data); /* clear any pending interrupt -- that'll cause sending */ writel(twsi_control_flags, &twsi->control); /* wait for controller to receive byte and check ACK */ - return twsi_wait(expected_status); + return twsi_wait(adap, expected_status); } /* * Receive a byte. * Global mvtwsi_control_flags variable says if we should ack or nak. */ -static int twsi_recv(u8 *byte) +static int twsi_recv(struct i2c_adapter *adap, u8 *byte) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); int expected_status, status; /* compute expected status based on ACK bit in global control flags */ @@ -192,7 +226,7 @@ static int twsi_recv(u8 *byte) /* acknowledge *previous state* and launch receive */ writel(twsi_control_flags, &twsi->control); /* wait for controller to receive byte and assert ACK or NAK */ - status = twsi_wait(expected_status); + status = twsi_wait(adap, expected_status); /* if we did receive expected byte then store it */ if (status == 0) *byte = readl(&twsi->data); @@ -204,8 +238,9 @@ static int twsi_recv(u8 *byte) * Assert the STOP condition. * This is also used to force the bus back in idle (SDA=SCL=1). */ -static int twsi_stop(int status) +static int twsi_stop(struct i2c_adapter *adap, int status) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); int control, stop_status; int timeout = 1000; @@ -244,6 +279,7 @@ static unsigned int twsi_calc_freq(const int n, const int m) */ static void twsi_reset(struct i2c_adapter *adap) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); /* ensure controller will be enabled by any twsi*() function */ twsi_control_flags = MVTWSI_CONTROL_TWSIEN; /* reset controller */ @@ -259,6 +295,7 @@ static void twsi_reset(struct i2c_adapter *adap) static unsigned int twsi_i2c_set_bus_speed(struct i2c_adapter *adap, unsigned int requested_speed) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); unsigned int tmp_speed, highest_speed, n, m; unsigned int baud = 0x44; /* baudrate at controller reset */ @@ -281,6 +318,8 @@ static unsigned int twsi_i2c_set_bus_speed(struct i2c_adapter *adap, static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); + /* reset controller */ twsi_reset(adap); /* set speed */ @@ -289,7 +328,7 @@ static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) writel(slaveadd, &twsi->slave_address); writel(0, &twsi->xtnd_slave_addr); /* assert STOP but don't care for the result */ - (void) twsi_stop(0); + (void) twsi_stop(adap, 0); } /* @@ -297,7 +336,8 @@ static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) * Common to i2c_probe, i2c_read and i2c_write. * Expected address status will derive from direction bit (bit 0) in addr. */ -static int i2c_begin(int expected_start_status, u8 addr) +static int i2c_begin(struct i2c_adapter *adap, int expected_start_status, + u8 addr) { int status, expected_addr_status; @@ -307,10 +347,10 @@ static int i2c_begin(int expected_start_status, u8 addr) else /* writing */ expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK; /* assert START */ - status = twsi_start(expected_start_status); + status = twsi_start(adap, expected_start_status); /* send out the address if the start went well */ if (status == 0) - status = twsi_send(addr, expected_addr_status); + status = twsi_send(adap, addr, expected_addr_status); /* return ok or status of first failure to caller */ return status; } @@ -325,12 +365,12 @@ static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip) int status; /* begin i2c read */ - status = i2c_begin(MVTWSI_STATUS_START, (chip << 1) | 1); + status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1); /* dummy read was accepted: receive byte but NAK it. */ if (status == 0) - status = twsi_recv(&dummy_byte); + status = twsi_recv(adap, &dummy_byte); /* Stop transaction */ - twsi_stop(0); + twsi_stop(adap, 0); /* return 0 or status of first failure */ return status; } @@ -351,15 +391,15 @@ static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, int status; /* begin i2c write to send the address bytes */ - status = i2c_begin(MVTWSI_STATUS_START, (chip << 1)); + status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1)); /* send addr bytes */ while ((status == 0) && alen--) - status = twsi_send(addr >> (8*alen), + status = twsi_send(adap, addr >> (8*alen), MVTWSI_STATUS_DATA_W_ACK); /* begin i2c read to receive eeprom data bytes */ if (status == 0) - status = i2c_begin( - MVTWSI_STATUS_REPEATED_START, (chip << 1) | 1); + status = i2c_begin(adap, MVTWSI_STATUS_REPEATED_START, + (chip << 1) | 1); /* prepare ACK if at least one byte must be received */ if (length > 0) twsi_control_flags |= MVTWSI_CONTROL_ACK; @@ -369,10 +409,10 @@ static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, if (length == 0) twsi_control_flags &= ~MVTWSI_CONTROL_ACK; /* read current byte */ - status = twsi_recv(data++); + status = twsi_recv(adap, data++); } /* Stop transaction */ - status = twsi_stop(status); + status = twsi_stop(adap, status); /* return 0 or status of first failure */ return status; } @@ -387,21 +427,51 @@ static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, int status; /* begin i2c write to send the eeprom adress bytes then data bytes */ - status = i2c_begin(MVTWSI_STATUS_START, (chip << 1)); + status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1)); /* send addr bytes */ while ((status == 0) && alen--) - status = twsi_send(addr >> (8*alen), + status = twsi_send(adap, addr >> (8*alen), MVTWSI_STATUS_DATA_W_ACK); /* send data bytes */ while ((status == 0) && (length-- > 0)) - status = twsi_send(*(data++), MVTWSI_STATUS_DATA_W_ACK); + status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK); /* Stop transaction */ - status = twsi_stop(status); + status = twsi_stop(adap, status); /* return 0 or status of first failure */ return status; } +#ifdef CONFIG_I2C_MVTWSI_BASE0 U_BOOT_I2C_ADAP_COMPLETE(twsi0, twsi_i2c_init, twsi_i2c_probe, twsi_i2c_read, twsi_i2c_write, twsi_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 0) +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE1 +U_BOOT_I2C_ADAP_COMPLETE(twsi1, twsi_i2c_init, twsi_i2c_probe, + twsi_i2c_read, twsi_i2c_write, + twsi_i2c_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 1) + +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE2 +U_BOOT_I2C_ADAP_COMPLETE(twsi2, twsi_i2c_init, twsi_i2c_probe, + twsi_i2c_read, twsi_i2c_write, + twsi_i2c_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 2) + +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE3 +U_BOOT_I2C_ADAP_COMPLETE(twsi3, twsi_i2c_init, twsi_i2c_probe, + twsi_i2c_read, twsi_i2c_write, + twsi_i2c_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 3) + +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE4 +U_BOOT_I2C_ADAP_COMPLETE(twsi4, twsi_i2c_init, twsi_i2c_probe, + twsi_i2c_read, twsi_i2c_write, + twsi_i2c_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 4) + +#endif diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index fc5ee35..42782cb 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -114,6 +114,9 @@ static u16 i2c_clk_div[50][2] = { #ifndef CONFIG_SYS_MXC_I2C3_SPEED #define CONFIG_SYS_MXC_I2C3_SPEED 100000 #endif +#ifndef CONFIG_SYS_MXC_I2C4_SPEED +#define CONFIG_SYS_MXC_I2C4_SPEED 100000 +#endif #ifndef CONFIG_SYS_MXC_I2C1_SLAVE #define CONFIG_SYS_MXC_I2C1_SLAVE 0 @@ -124,6 +127,9 @@ static u16 i2c_clk_div[50][2] = { #ifndef CONFIG_SYS_MXC_I2C3_SLAVE #define CONFIG_SYS_MXC_I2C3_SLAVE 0 #endif +#ifndef CONFIG_SYS_MXC_I2C4_SLAVE +#define CONFIG_SYS_MXC_I2C4_SLAVE 0 +#endif /* @@ -543,12 +549,17 @@ U_BOOT_I2C_ADAP_COMPLETE(mxc1, mxc_i2c_init, mxc_i2c_probe, mxc_i2c_set_bus_speed, CONFIG_SYS_MXC_I2C2_SPEED, CONFIG_SYS_MXC_I2C2_SLAVE, 1) -#if defined(CONFIG_MX31) || defined(CONFIG_MX35) ||\ - defined(CONFIG_MX51) || defined(CONFIG_MX53) ||\ - defined(CONFIG_MX6) || defined(CONFIG_LS102XA) +#ifdef CONFIG_SYS_I2C_MXC_I2C3 U_BOOT_I2C_ADAP_COMPLETE(mxc2, mxc_i2c_init, mxc_i2c_probe, mxc_i2c_read, mxc_i2c_write, mxc_i2c_set_bus_speed, CONFIG_SYS_MXC_I2C3_SPEED, CONFIG_SYS_MXC_I2C3_SLAVE, 2) #endif +#ifdef CONFIG_SYS_I2C_MXC_I2C4 +U_BOOT_I2C_ADAP_COMPLETE(mxc3, mxc_i2c_init, mxc_i2c_probe, + mxc_i2c_read, mxc_i2c_write, + mxc_i2c_set_bus_speed, + CONFIG_SYS_MXC_I2C4_SPEED, + CONFIG_SYS_MXC_I2C4_SLAVE, 3) +#endif diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index b4ee33f..27ff587 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -1348,7 +1348,7 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); int node, flags; - i2c_bus->is_highspeed = dev->of_id->data; + i2c_bus->is_highspeed = dev_get_driver_data(dev); node = dev->of_offset; if (i2c_bus->is_highspeed) { diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c index a943aa6..d6adc0f 100644 --- a/drivers/i2c/sandbox_i2c.c +++ b/drivers/i2c/sandbox_i2c.c @@ -50,7 +50,7 @@ static int get_emul(struct udevice *dev, struct udevice **devp, static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) { - struct dm_i2c_bus *i2c = bus->uclass_priv; + struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus); struct dm_i2c_ops *ops; struct udevice *emul, *dev; bool is_read; diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c index f414287..fc95646 100644 --- a/drivers/i2c/tegra_i2c.c +++ b/drivers/i2c/tegra_i2c.c @@ -338,7 +338,7 @@ static int tegra_i2c_probe(struct udevice *dev) bool is_dvc; i2c_bus->id = dev->seq; - i2c_bus->type = dev_get_of_data(dev); + i2c_bus->type = dev_get_driver_data(dev); i2c_bus->regs = (struct i2c_ctlr *)fdtdec_get_addr(blob, node, "reg"); /* @@ -360,7 +360,7 @@ static int tegra_i2c_probe(struct udevice *dev) if (i2c_bus->periph_id == -1) return -EINVAL; - is_dvc = dev_get_of_data(dev) == TYPE_DVC; + is_dvc = dev_get_driver_data(dev) == TYPE_DVC; if (is_dvc) { i2c_bus->control = &((struct dvc_ctlr *)i2c_bus->regs)->control; @@ -469,7 +469,7 @@ int tegra_i2c_get_dvc_bus(struct udevice **busp) for (uclass_first_device(UCLASS_I2C, &bus); bus; uclass_next_device(&bus)) { - if (dev_get_of_data(bus) == TYPE_DVC) { + if (dev_get_driver_data(bus) == TYPE_DVC) { *busp = bus; return 0; } diff --git a/drivers/input/cros_ec_keyb.c b/drivers/input/cros_ec_keyb.c index 49ee7b2..a31aa77 100644 --- a/drivers/input/cros_ec_keyb.c +++ b/drivers/input/cros_ec_keyb.c @@ -198,7 +198,7 @@ static int cros_ec_keyb_decode_fdt(const void *blob, int node, return -1; } config->ghost_filter = fdtdec_get_bool(blob, node, - "google,ghost-filter"); + "google,needs-ghost-filter"); return 0; } diff --git a/drivers/input/i8042.c b/drivers/input/i8042.c index ca1604c..1769c5e 100644 --- a/drivers/input/i8042.c +++ b/drivers/input/i8042.c @@ -698,7 +698,14 @@ static int kbd_reset(void) /* Enable Keyboard */ out8(I8042_COMMAND_REG, 0xae); + if (kbd_input_empty() == 0) + return -1; + + out8(I8042_COMMAND_REG, 0x60); + if (kbd_input_empty() == 0) + return -1; + out8(I8042_DATA_REG, 0xf4); if (kbd_input_empty() == 0) return -1; diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 36a8f0d..0e571d9 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -35,6 +35,15 @@ config CROS_EC_LPC through a legacy port interface, so on x86 machines the main function of the EC is power and thermal management. +config CROS_EC_SANDBOX + bool "Enable Chrome OS EC sandbox driver" + depends on CROS_EC && SANDBOX + help + Enable a sandbox emulation of the Chrome OS EC. This supports + keyboard (use the -l flag to enable the LCD), verified boot context, + EC flash read/write/erase support and a few other things. It is + enough to perform a Chrome OS verified boot on sandbox. + config CROS_EC_SPI bool "Enable Chrome OS EC SPI driver" depends on CROS_EC @@ -44,16 +53,6 @@ config CROS_EC_SPI provides a faster and more robust interface than I2C but the bugs are less interesting. -config DM_CROS_EC - bool "Enable Driver Model for Chrome OS EC" - depends on DM - help - Enable driver model for the Chrome OS EC interface. This - allows the cros_ec SPI driver to operate with CONFIG_DM_SPI - but otherwise makes few changes. Since cros_ec also supports - LPC (which doesn't support driver model yet), a full - conversion is not yet possible. - config CONFIG_FSL_SEC_MON bool "Enable FSL SEC_MON Driver" help diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 6028cd4..25630c3 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o obj-$(CONFIG_CROS_EC_I2C) += cros_ec_i2c.o obj-$(CONFIG_CROS_EC_SANDBOX) += cros_ec_sandbox.o obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o +obj-$(CONFIG_FSL_DEBUG_SERVER) += fsl_debug_server.o obj-$(CONFIG_FSL_IIM) += fsl_iim.o obj-$(CONFIG_GPIO_LED) += gpio_led.o obj-$(CONFIG_I2C_EEPROM) += i2c_eeprom.o @@ -26,6 +27,7 @@ obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o endif obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o obj-$(CONFIG_STATUS_LED) += status_led.o +obj-$(CONFIG_SANDBOX) += swap_case.o obj-$(CONFIG_TWL4030_LED) += twl4030_led.o obj-$(CONFIG_FSL_IFC) += fsl_ifc.o obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 5846e76..982bac7 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -41,10 +41,6 @@ enum { CROS_EC_CMD_HASH_TIMEOUT_MS = 2000, }; -#ifndef CONFIG_DM_CROS_EC -static struct cros_ec_dev static_dev, *last_dev; -#endif - DECLARE_GLOBAL_DATA_PTR; /* Note: depends on enum ec_current_image */ @@ -211,9 +207,7 @@ static int send_command_proto3(struct cros_ec_dev *dev, const void *dout, int dout_len, uint8_t **dinp, int din_len) { -#ifdef CONFIG_DM_CROS_EC struct dm_cros_ec_ops *ops; -#endif int out_bytes, in_bytes; int rv; @@ -228,28 +222,8 @@ static int send_command_proto3(struct cros_ec_dev *dev, if (in_bytes < 0) return in_bytes; -#ifdef CONFIG_DM_CROS_EC ops = dm_cros_ec_get_ops(dev->dev); rv = ops->packet ? ops->packet(dev->dev, out_bytes, in_bytes) : -ENOSYS; -#else - switch (dev->interface) { -#ifdef CONFIG_CROS_EC_SPI - case CROS_EC_IF_SPI: - rv = cros_ec_spi_packet(dev, out_bytes, in_bytes); - break; -#endif -#ifdef CONFIG_CROS_EC_SANDBOX - case CROS_EC_IF_SANDBOX: - rv = cros_ec_sandbox_packet(dev, out_bytes, in_bytes); - break; -#endif - case CROS_EC_IF_NONE: - /* TODO: support protocol 3 for LPC, I2C; for now fall through */ - default: - debug("%s: Unsupported interface\n", __func__); - rv = -1; - } -#endif if (rv < 0) return rv; @@ -261,9 +235,7 @@ static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, const void *dout, int dout_len, uint8_t **dinp, int din_len) { -#ifdef CONFIG_DM_CROS_EC struct dm_cros_ec_ops *ops; -#endif int ret = -1; /* Handle protocol version 3 support */ @@ -272,38 +244,9 @@ static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, dout, dout_len, dinp, din_len); } -#ifdef CONFIG_DM_CROS_EC ops = dm_cros_ec_get_ops(dev->dev); ret = ops->command(dev->dev, cmd, cmd_version, (const uint8_t *)dout, dout_len, dinp, din_len); -#else - switch (dev->interface) { -#ifdef CONFIG_CROS_EC_SPI - case CROS_EC_IF_SPI: - ret = cros_ec_spi_command(dev, cmd, cmd_version, - (const uint8_t *)dout, dout_len, - dinp, din_len); - break; -#endif -#ifdef CONFIG_CROS_EC_I2C - case CROS_EC_IF_I2C: - ret = cros_ec_i2c_command(dev, cmd, cmd_version, - (const uint8_t *)dout, dout_len, - dinp, din_len); - break; -#endif -#ifdef CONFIG_CROS_EC_LPC - case CROS_EC_IF_LPC: - ret = cros_ec_lpc_command(dev, cmd, cmd_version, - (const uint8_t *)dout, dout_len, - dinp, din_len); - break; -#endif - case CROS_EC_IF_NONE: - default: - ret = -1; - } -#endif return ret; } @@ -681,11 +624,15 @@ static int cros_ec_check_version(struct cros_ec_dev *dev) struct ec_params_hello req; struct ec_response_hello *resp; -#ifdef CONFIG_CROS_EC_LPC - /* LPC has its own way of doing this */ - if (dev->interface == CROS_EC_IF_LPC) - return cros_ec_lpc_check_version(dev); -#endif + struct dm_cros_ec_ops *ops; + int ret; + + ops = dm_cros_ec_get_ops(dev->dev); + if (ops->check_version) { + ret = ops->check_version(dev->dev); + if (ret) + return ret; + } /* * TODO(sjg@chromium.org). @@ -1015,79 +962,9 @@ int cros_ec_get_ldo(struct cros_ec_dev *dev, uint8_t index, uint8_t *state) return 0; } -#ifndef CONFIG_DM_CROS_EC -/** - * Decode EC interface details from the device tree and allocate a suitable - * device. - * - * @param blob Device tree blob - * @param node Node to decode from - * @param devp Returns a pointer to the new allocated device - * @return 0 if ok, -1 on error - */ -static int cros_ec_decode_fdt(const void *blob, int node, - struct cros_ec_dev **devp) -{ - enum fdt_compat_id compat; - struct cros_ec_dev *dev; - int parent; - - /* See what type of parent we are inside (this is expensive) */ - parent = fdt_parent_offset(blob, node); - if (parent < 0) { - debug("%s: Cannot find node parent\n", __func__); - return -1; - } - - dev = &static_dev; - dev->node = node; - dev->parent_node = parent; - - compat = fdtdec_lookup(blob, parent); - switch (compat) { -#ifdef CONFIG_CROS_EC_SPI - case COMPAT_SAMSUNG_EXYNOS_SPI: - dev->interface = CROS_EC_IF_SPI; - if (cros_ec_spi_decode_fdt(dev, blob)) - return -1; - break; -#endif -#ifdef CONFIG_CROS_EC_I2C - case COMPAT_SAMSUNG_S3C2440_I2C: - dev->interface = CROS_EC_IF_I2C; - if (cros_ec_i2c_decode_fdt(dev, blob)) - return -1; - break; -#endif -#ifdef CONFIG_CROS_EC_LPC - case COMPAT_INTEL_LPC: - dev->interface = CROS_EC_IF_LPC; - break; -#endif -#ifdef CONFIG_CROS_EC_SANDBOX - case COMPAT_SANDBOX_HOST_EMULATION: - dev->interface = CROS_EC_IF_SANDBOX; - break; -#endif - default: - debug("%s: Unknown compat id %d\n", __func__, compat); - return -1; - } - - gpio_request_by_name_nodev(blob, node, "ec-interrupt", 0, &dev->ec_int, - GPIOD_IS_IN); - dev->optimise_flash_write = fdtdec_get_bool(blob, node, - "optimise-flash-write"); - *devp = dev; - - return 0; -} -#endif - -#ifdef CONFIG_DM_CROS_EC int cros_ec_register(struct udevice *dev) { - struct cros_ec_dev *cdev = dev->uclass_priv; + struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); const void *blob = gd->fdt_blob; int node = dev->of_offset; char id[MSG_BYTES]; @@ -1113,94 +990,6 @@ int cros_ec_register(struct udevice *dev) return 0; } -#else -int cros_ec_init(const void *blob, struct cros_ec_dev **cros_ecp) -{ - struct cros_ec_dev *dev; - char id[MSG_BYTES]; -#ifdef CONFIG_DM_CROS_EC - struct udevice *udev; - int ret; - - ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev); - if (!ret) - device_remove(udev); - ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev); - if (ret) - return ret; - dev = udev->uclass_priv; - return 0; -#else - int node = 0; - - *cros_ecp = NULL; - do { - node = fdtdec_next_compatible(blob, node, - COMPAT_GOOGLE_CROS_EC); - if (node < 0) { - debug("%s: Node not found\n", __func__); - return 0; - } - } while (!fdtdec_get_is_enabled(blob, node)); - - if (cros_ec_decode_fdt(blob, node, &dev)) { - debug("%s: Failed to decode device.\n", __func__); - return -CROS_EC_ERR_FDT_DECODE; - } - - switch (dev->interface) { -#ifdef CONFIG_CROS_EC_SPI - case CROS_EC_IF_SPI: - if (cros_ec_spi_init(dev, blob)) { - debug("%s: Could not setup SPI interface\n", __func__); - return -CROS_EC_ERR_DEV_INIT; - } - break; -#endif -#ifdef CONFIG_CROS_EC_I2C - case CROS_EC_IF_I2C: - if (cros_ec_i2c_init(dev, blob)) - return -CROS_EC_ERR_DEV_INIT; - break; -#endif -#ifdef CONFIG_CROS_EC_LPC - case CROS_EC_IF_LPC: - if (cros_ec_lpc_init(dev, blob)) - return -CROS_EC_ERR_DEV_INIT; - break; -#endif -#ifdef CONFIG_CROS_EC_SANDBOX - case CROS_EC_IF_SANDBOX: - if (cros_ec_sandbox_init(dev, blob)) - return -CROS_EC_ERR_DEV_INIT; - break; -#endif - case CROS_EC_IF_NONE: - default: - return 0; - } -#endif - - if (cros_ec_check_version(dev)) { - debug("%s: Could not detect CROS-EC version\n", __func__); - return -CROS_EC_ERR_CHECK_VERSION; - } - - if (cros_ec_read_id(dev, id, sizeof(id))) { - debug("%s: Could not read KBC ID\n", __func__); - return -CROS_EC_ERR_READ_ID; - } - - /* Remember this device for use by the cros_ec command */ - *cros_ecp = dev; -#ifndef CONFIG_DM_CROS_EC - last_dev = dev; -#endif - debug("Google Chrome EC CROS-EC driver ready, id '%s'\n", id); - - return 0; -} -#endif int cros_ec_decode_region(int argc, char * const argv[]) { @@ -1583,9 +1372,7 @@ static int cros_ec_i2c_passthrough(struct cros_ec_dev *dev, int flag, static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct cros_ec_dev *dev; -#ifdef CONFIG_DM_CROS_EC struct udevice *udev; -#endif const char *cmd; int ret = 0; @@ -1594,31 +1381,24 @@ static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) cmd = argv[1]; if (0 == strcmp("init", cmd)) { -#ifndef CONFIG_DM_CROS_EC - ret = cros_ec_init(gd->fdt_blob, &dev); + /* Remove any existing device */ + ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev); + if (!ret) + device_remove(udev); + ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev); if (ret) { printf("Could not init cros_ec device (err %d)\n", ret); return 1; } -#endif return 0; } -#ifdef CONFIG_DM_CROS_EC ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev); if (ret) { printf("Cannot get cros-ec device (err=%d)\n", ret); return 1; } - dev = udev->uclass_priv; -#else - /* Just use the last allocated device; there should be only one */ - if (!last_dev) { - printf("No CROS-EC device available\n"); - return 1; - } - dev = last_dev; -#endif + dev = dev_get_uclass_priv(udev); if (0 == strcmp("id", cmd)) { char id[MSG_BYTES]; @@ -1876,10 +1656,8 @@ U_BOOT_CMD( ); #endif -#ifdef CONFIG_DM_CROS_EC UCLASS_DRIVER(cros_ec) = { .id = UCLASS_CROS_EC, .name = "cros_ec", .per_device_auto_alloc_size = sizeof(struct cros_ec_dev), }; -#endif diff --git a/drivers/misc/cros_ec_i2c.c b/drivers/misc/cros_ec_i2c.c index f9bc975..3de18b2 100644 --- a/drivers/misc/cros_ec_i2c.c +++ b/drivers/misc/cros_ec_i2c.c @@ -28,7 +28,7 @@ static int cros_ec_i2c_command(struct udevice *udev, uint8_t cmd, int cmd_version, const uint8_t *dout, int dout_len, uint8_t **dinp, int din_len) { - struct cros_ec_dev *dev = udev->uclass_priv; + struct cros_ec_dev *dev = dev_get_uclass_priv(udev); /* version8, cmd8, arglen8, out8[dout_len], csum8 */ int out_bytes = dout_len + 4; /* response8, arglen8, in8[din_len], checksum8 */ @@ -139,12 +139,12 @@ static struct dm_cros_ec_ops cros_ec_ops = { }; static const struct udevice_id cros_ec_ids[] = { - { .compatible = "google,cros-ec" }, + { .compatible = "google,cros-ec-i2c" }, { } }; U_BOOT_DRIVER(cros_ec_i2c) = { - .name = "cros_ec", + .name = "cros_ec_i2c", .id = UCLASS_CROS_EC, .of_match = cros_ec_ids, .probe = cros_ec_probe, diff --git a/drivers/misc/cros_ec_lpc.c b/drivers/misc/cros_ec_lpc.c index 07624a1..7837841 100644 --- a/drivers/misc/cros_ec_lpc.c +++ b/drivers/misc/cros_ec_lpc.c @@ -14,6 +14,7 @@ */ #include <common.h> +#include <dm.h> #include <command.h> #include <cros_ec.h> #include <asm/io.h> @@ -40,10 +41,11 @@ static int wait_for_sync(struct cros_ec_dev *dev) return 0; } -int cros_ec_lpc_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, +int cros_ec_lpc_command(struct udevice *udev, uint8_t cmd, int cmd_version, const uint8_t *dout, int dout_len, uint8_t **dinp, int din_len) { + struct cros_ec_dev *dev = dev_get_uclass_priv(udev); const int cmd_addr = EC_LPC_ADDR_HOST_CMD; const int data_addr = EC_LPC_ADDR_HOST_DATA; const int args_addr = EC_LPC_ADDR_HOST_ARGS; @@ -178,7 +180,7 @@ int cros_ec_lpc_init(struct cros_ec_dev *dev, const void *blob) * seeing whether the EC sets the EC_HOST_ARGS_FLAG_FROM_HOST flag * in args when it responds. */ -int cros_ec_lpc_check_version(struct cros_ec_dev *dev) +static int cros_ec_lpc_check_version(struct udevice *dev) { if (inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID) == 'E' && inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1) @@ -192,3 +194,26 @@ int cros_ec_lpc_check_version(struct cros_ec_dev *dev) printf("%s: ERROR: old EC interface not supported\n", __func__); return -1; } + +static int cros_ec_probe(struct udevice *dev) +{ + return cros_ec_register(dev); +} + +static struct dm_cros_ec_ops cros_ec_ops = { + .command = cros_ec_lpc_command, + .check_version = cros_ec_lpc_check_version, +}; + +static const struct udevice_id cros_ec_ids[] = { + { .compatible = "google,cros-ec-lpc" }, + { } +}; + +U_BOOT_DRIVER(cros_ec_lpc) = { + .name = "cros_ec_lpc", + .id = UCLASS_CROS_EC, + .of_match = cros_ec_ids, + .probe = cros_ec_probe, + .ops = &cros_ec_ops, +}; diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c index 99cc529..df41e82 100644 --- a/drivers/misc/cros_ec_sandbox.c +++ b/drivers/misc/cros_ec_sandbox.c @@ -467,17 +467,10 @@ static int process_cmd(struct ec_state *ec, return len; } -#ifdef CONFIG_DM_CROS_EC int cros_ec_sandbox_packet(struct udevice *udev, int out_bytes, int in_bytes) { - struct cros_ec_dev *dev = udev->uclass_priv; + struct cros_ec_dev *dev = dev_get_uclass_priv(udev); struct ec_state *ec = dev_get_priv(dev->dev); -#else -int cros_ec_sandbox_packet(struct cros_ec_dev *dev, int out_bytes, - int in_bytes) -{ - struct ec_state *ec = &s_state; -#endif struct ec_host_request *req_hdr = (struct ec_host_request *)dev->dout; const void *req_data = req_hdr + 1; struct ec_host_response *resp_hdr = (struct ec_host_response *)dev->din; @@ -500,18 +493,9 @@ int cros_ec_sandbox_packet(struct cros_ec_dev *dev, int out_bytes, return in_bytes; } -int cros_ec_sandbox_decode_fdt(struct cros_ec_dev *dev, const void *blob) -{ - return 0; -} - void cros_ec_check_keyboard(struct cros_ec_dev *dev) { -#ifdef CONFIG_DM_CROS_EC struct ec_state *ec = dev_get_priv(dev->dev); -#else - struct ec_state *ec = &s_state; -#endif ulong start; printf("Press keys for EC to detect on reset (ESC=recovery)..."); @@ -525,7 +509,6 @@ void cros_ec_check_keyboard(struct cros_ec_dev *dev) } } -#ifdef CONFIG_DM_CROS_EC int cros_ec_probe(struct udevice *dev) { struct ec_state *ec = dev->priv; @@ -569,76 +552,20 @@ int cros_ec_probe(struct udevice *dev) return cros_ec_register(dev); } -#else - -/** - * Initialize sandbox EC emulation. - * - * @param dev CROS_EC device - * @param blob Device tree blob - * @return 0 if ok, -1 on error - */ -int cros_ec_sandbox_init(struct cros_ec_dev *dev, const void *blob) -{ - struct ec_state *ec = &s_state; - int node; - int err; - - node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC); - if (node < 0) { - debug("Failed to find chrome-ec node'\n"); - return -1; - } - - err = cros_ec_decode_ec_flash(blob, node, &ec->ec_config); - if (err) - return err; - - node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC_KEYB); - if (node < 0) { - debug("%s: No cros_ec keyboard found\n", __func__); - } else if (keyscan_read_fdt_matrix(ec, blob, node)) { - debug("%s: Could not read key matrix\n", __func__); - return -1; - } - - /* If we loaded EC data, check that the length matches */ - if (ec->flash_data && - ec->flash_data_len != ec->ec_config.flash.length) { - printf("EC data length is %x, expected %x, discarding data\n", - ec->flash_data_len, ec->ec_config.flash.length); - os_free(ec->flash_data); - ec->flash_data = NULL; - } - - /* Otherwise allocate the memory */ - if (!ec->flash_data) { - ec->flash_data_len = ec->ec_config.flash.length; - ec->flash_data = os_malloc(ec->flash_data_len); - if (!ec->flash_data) - return -ENOMEM; - } - - return 0; -} -#endif - -#ifdef CONFIG_DM_CROS_EC struct dm_cros_ec_ops cros_ec_ops = { .packet = cros_ec_sandbox_packet, }; static const struct udevice_id cros_ec_ids[] = { - { .compatible = "google,cros-ec" }, + { .compatible = "google,cros-ec-sandbox" }, { } }; U_BOOT_DRIVER(cros_ec_sandbox) = { - .name = "cros_ec", + .name = "cros_ec_sandbox", .id = UCLASS_CROS_EC, .of_match = cros_ec_ids, .probe = cros_ec_probe, .priv_auto_alloc_size = sizeof(struct ec_state), .ops = &cros_ec_ops, }; -#endif diff --git a/drivers/misc/cros_ec_spi.c b/drivers/misc/cros_ec_spi.c index 9359c56..ac2ee86 100644 --- a/drivers/misc/cros_ec_spi.c +++ b/drivers/misc/cros_ec_spi.c @@ -23,7 +23,7 @@ DECLARE_GLOBAL_DATA_PTR; int cros_ec_spi_packet(struct udevice *udev, int out_bytes, int in_bytes) { - struct cros_ec_dev *dev = udev->uclass_priv; + struct cros_ec_dev *dev = dev_get_uclass_priv(udev); struct spi_slave *slave = dev_get_parentdata(dev->dev); int rv; @@ -66,7 +66,7 @@ int cros_ec_spi_command(struct udevice *udev, uint8_t cmd, int cmd_version, const uint8_t *dout, int dout_len, uint8_t **dinp, int din_len) { - struct cros_ec_dev *dev = udev->uclass_priv; + struct cros_ec_dev *dev = dev_get_uclass_priv(udev); struct spi_slave *slave = dev_get_parentdata(dev->dev); int in_bytes = din_len + 4; /* status, length, checksum, trailer */ uint8_t *out; @@ -165,12 +165,12 @@ static struct dm_cros_ec_ops cros_ec_ops = { }; static const struct udevice_id cros_ec_ids[] = { - { .compatible = "google,cros-ec" }, + { .compatible = "google,cros-ec-spi" }, { } }; U_BOOT_DRIVER(cros_ec_spi) = { - .name = "cros_ec", + .name = "cros_ec_spi", .id = UCLASS_CROS_EC, .of_match = cros_ec_ids, .probe = cros_ec_probe, diff --git a/drivers/misc/fsl_debug_server.c b/drivers/misc/fsl_debug_server.c new file mode 100644 index 0000000..e080fe6 --- /dev/null +++ b/drivers/misc/fsl_debug_server.c @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <asm/io.h> +#include <asm/system.h> +#include <asm/arch-fsl-lsch3/immap_lsch3.h> + +#include <fsl_debug_server.h> + +DECLARE_GLOBAL_DATA_PTR; +static int debug_server_ver_info_maj, debug_server_ver_info_min; + +/** + * Copying Debug Server firmware to DDR + */ +static int debug_server_copy_image(const char *title, u64 image_addr, + u32 image_size, u64 debug_server_ram_addr) +{ + debug("%s copied to address %p\n", title, + (void *)debug_server_ram_addr); + memcpy((void *)debug_server_ram_addr, (void *)image_addr, image_size); + + return 0; +} + +/** + * Debug Server FIT image parser checks if the image is in FIT + * format, verifies integrity of the image and calculates + * raw image address and size values. + * + * Returns 0 if success and -1 if any of the above mentioned + * task fail. + **/ +int debug_server_parse_firmware_fit_image(const void **raw_image_addr, + size_t *raw_image_size) +{ + int format; + void *fit_hdr; + int node_offset; + const void *data; + size_t size; + const char *uname = "firmware"; + char *desc; + char *debug_server_ver_info; + char *debug_server_ver_info_major, *debug_server_ver_info_minor; + + /* Check if the image is in NOR flash */ +#ifdef CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR + fit_hdr = (void *)CONFIG_SYS_DEBUG_SERVER_FW_ADDR; +#else +#error "CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR not defined" +#endif + + /* Check if Image is in FIT format */ + format = genimg_get_format(fit_hdr); + if (format != IMAGE_FORMAT_FIT) { + printf("Error! Not a FIT image\n"); + goto out_error; + } + + if (!fit_check_format(fit_hdr)) { + printf("Error! Bad FIT image format\n"); + goto out_error; + } + + node_offset = fit_image_get_node(fit_hdr, uname); + if (node_offset < 0) { + printf("Error! Can not find %s subimage\n", uname); + goto out_error; + } + + /* Verify Debug Server firmware image */ + if (!fit_image_verify(fit_hdr, node_offset)) { + printf("Error! Bad Debug Server firmware hash"); + goto out_error; + } + + if (fit_get_desc(fit_hdr, node_offset, &desc) < 0) { + printf("Error! Failed to get Debug Server fw description"); + goto out_error; + } + + debug_server_ver_info = strstr(desc, "Version"); + debug_server_ver_info_major = strtok(debug_server_ver_info, "."); + debug_server_ver_info_minor = strtok(NULL, "."); + + debug_server_ver_info_maj = + simple_strtoul(debug_server_ver_info_major, NULL, 10); + debug_server_ver_info_min = + simple_strtoul(debug_server_ver_info_minor, NULL, 10); + + /* Debug server version checking */ + if ((debug_server_ver_info_maj < DEBUG_SERVER_VER_MAJOR) || + (debug_server_ver_info_min < DEBUG_SERVER_VER_MINOR)) { + printf("Debug server FW mismatches the min version required\n"); + printf("Expected:%d.%d, Got %d.%d\n", + DEBUG_SERVER_VER_MAJOR, DEBUG_SERVER_VER_MINOR, + debug_server_ver_info_maj, + debug_server_ver_info_min); + goto out_error; + } + + /* Get address and size of raw image */ + fit_image_get_data(fit_hdr, node_offset, &data, &size); + + *raw_image_addr = data; + *raw_image_size = size; + + return 0; + +out_error: + return -1; +} + +/** + * Return the actual size of the Debug Server private DRAM block. + * + * NOTE: For now this function always returns the minimum required size, + * However, in the future, the actual size may be obtained from an environment + * variable. + */ +unsigned long debug_server_get_dram_block_size(void) +{ + return CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE; +} + +int debug_server_init(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + int error, timeout = CONFIG_SYS_DEBUG_SERVER_TIMEOUT; + int debug_server_boot_status; + u64 debug_server_ram_addr, debug_server_ram_size; + const void *raw_image_addr; + size_t raw_image_size = 0; + + debug("debug_server_init called\n"); + /* + * The Debug Server private DRAM block was already carved at the end of + * DRAM by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE: + */ + debug_server_ram_size = debug_server_get_dram_block_size(); + if (gd->bd->bi_dram[1].start) + debug_server_ram_addr = + gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size; + else + debug_server_ram_addr = + gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; + + error = debug_server_parse_firmware_fit_image(&raw_image_addr, + &raw_image_size); + if (error != 0) + goto out; + + debug("debug server (ram addr = 0x%llx, ram size = 0x%llx)\n", + debug_server_ram_addr, debug_server_ram_size); + /* + * Load the Debug Server FW at the beginning of the Debug Server + * private DRAM block: + */ + debug_server_copy_image("Debug Server Firmware", + (u64)raw_image_addr, raw_image_size, + debug_server_ram_addr); + + /* flush dcache */ + flush_dcache_range((unsigned long)debug_server_ram_addr, + (unsigned long)debug_server_ram_addr + + (unsigned long)debug_server_ram_size); + + /* + * Tell SP that the Debug Server FW is about to be launched. Before that + * populate the following: + * 1. Write the size allocated to SP Memory region into Bits {31:16} of + * SCRATCHRW5. + * 2. Write the start address of the SP memory regions into + * SCRATCHRW5 (Bits {15:0}, contain most significant bits, Bits + * {47:32} of the SP Memory Region physical start address + * (SoC address)) and SCRATCHRW6 (Bits {31:0}). + * 3. To know the Debug Server FW boot status, set bit 0 of SCRATCHRW11 + * to 1. The Debug Server sets this to 0 to indicate a + * successul boot. + * 4. Wakeup SP by writing 0x1F to VSG GIC reg VIGR2. + */ + + /* 512 MB */ + out_le32(&gur->scratchrw[5 - 1], + (u32)((u64)debug_server_ram_addr >> 32) | (0x000D << 16)); + out_le32(&gur->scratchrw[6 - 1], + ((u32)debug_server_ram_addr) & 0xFFFFFFFF); + + out_le32(&gur->scratchrw[11 - 1], DEBUG_SERVER_INIT_STATUS); + /* Allow the changes to reflect in GUR block */ + mb(); + + /* + * Program VGIC to raise an interrupt to SP + */ + out_le32(CONFIG_SYS_FSL_SP_VSG_GIC_VIGR2, 0x1F); + /* Allow the changes to reflect in VIGR2 */ + mb(); + + dmb(); + debug("Polling for Debug server to launch ...\n"); + + while (1) { + debug_server_boot_status = in_le32(&gur->scratchrw[11 - 1]); + if (!(debug_server_boot_status & DEBUG_SERVER_INIT_STATUS_MASK)) + break; + + udelay(1); /* throttle polling */ + if (timeout-- <= 0) + break; + } + + if (timeout <= 0) { + printf("Debug Server FW timed out (boot status: 0x%x)\n", + debug_server_boot_status); + error = -ETIMEDOUT; + goto out; + } + + if (debug_server_boot_status & DEBUG_SERVER_INIT_STATUS_MASK) { + printf("Debug server FW error'ed out (boot status: 0x%x)\n", + debug_server_boot_status); + error = -ENODEV; + goto out; + } + + printf("Debug server booted\n"); + printf("Detected firmware %d.%d, (boot status: 0x0%x)\n", + debug_server_ver_info_maj, debug_server_ver_info_min, + debug_server_boot_status); + +out: + if (error != 0) + debug_server_boot_status = -error; + else + debug_server_boot_status = 0; + + return debug_server_boot_status; +} + diff --git a/drivers/misc/fsl_ifc.c b/drivers/misc/fsl_ifc.c index 3902e9f..a33efdb 100644 --- a/drivers/misc/fsl_ifc.c +++ b/drivers/misc/fsl_ifc.c @@ -168,4 +168,25 @@ void init_final_memctl_regs(void) #ifdef CONFIG_SYS_CSPR0_FINAL set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0_FINAL); #endif +#ifdef CONFIG_SYS_AMASK0_FINAL + set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0); +#endif +#ifdef CONFIG_SYS_CSPR1_FINAL + set_ifc_cspr(IFC_CS1, CONFIG_SYS_CSPR1_FINAL); +#endif +#ifdef CONFIG_SYS_AMASK1_FINAL + set_ifc_amask(IFC_CS1, CONFIG_SYS_AMASK1_FINAL); +#endif +#ifdef CONFIG_SYS_CSPR2_FINAL + set_ifc_cspr(IFC_CS2, CONFIG_SYS_CSPR2_FINAL); +#endif +#ifdef CONFIG_SYS_AMASK2_FINAL + set_ifc_amask(IFC_CS2, CONFIG_SYS_AMASK2); +#endif +#ifdef CONFIG_SYS_CSPR3_FINAL + set_ifc_cspr(IFC_CS3, CONFIG_SYS_CSPR3_FINAL); +#endif +#ifdef CONFIG_SYS_AMASK3_FINAL + set_ifc_amask(IFC_CS3, CONFIG_SYS_AMASK3); +#endif } diff --git a/drivers/misc/status_led.c b/drivers/misc/status_led.c index ed9adb2..9869d98 100644 --- a/drivers/misc/status_led.c +++ b/drivers/misc/status_led.c @@ -53,6 +53,20 @@ led_dev_t led_dev[] = { 0, }, #endif +#if defined(STATUS_LED_BIT4) + { STATUS_LED_BIT4, + STATUS_LED_STATE4, + STATUS_LED_PERIOD4, + 0, + }, +#endif +#if defined(STATUS_LED_BIT5) + { STATUS_LED_BIT5, + STATUS_LED_STATE5, + STATUS_LED_PERIOD5, + 0, + }, +#endif }; #define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t)) diff --git a/drivers/misc/swap_case.c b/drivers/misc/swap_case.c new file mode 100644 index 0000000..f6028ba --- /dev/null +++ b/drivers/misc/swap_case.c @@ -0,0 +1,285 @@ +/* + * PCI emulation device which swaps the case of text + * + * Copyright (c) 2014 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <pci.h> +#include <asm/test.h> +#include <linux/ctype.h> + +/** + * struct swap_case_platdata - platform data for this device + * + * @command: Current PCI command value + * @bar: Current base address values + */ +struct swap_case_platdata { + u16 command; + u32 bar[2]; +}; + +#define offset_to_barnum(offset) \ + (((offset) - PCI_BASE_ADDRESS_0) / sizeof(u32)) + +enum { + MEM_TEXT_SIZE = 0x100, +}; + +enum swap_case_op { + OP_TO_LOWER, + OP_TO_UPPER, + OP_SWAP, +}; + +static struct pci_bar { + int type; + u32 size; +} barinfo[] = { + { PCI_BASE_ADDRESS_SPACE_IO, 1 }, + { PCI_BASE_ADDRESS_MEM_TYPE_32, MEM_TEXT_SIZE }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, +}; + +struct swap_case_priv { + enum swap_case_op op; + char mem_text[MEM_TEXT_SIZE]; +}; + +static int sandbox_swap_case_get_devfn(struct udevice *dev) +{ + struct pci_child_platdata *plat = dev_get_parent_platdata(dev); + + return plat->devfn; +} + +static int sandbox_swap_case_read_config(struct udevice *emul, uint offset, + ulong *valuep, enum pci_size_t size) +{ + struct swap_case_platdata *plat = dev_get_platdata(emul); + + switch (offset) { + case PCI_COMMAND: + *valuep = plat->command; + break; + case PCI_HEADER_TYPE: + *valuep = 0; + break; + case PCI_VENDOR_ID: + *valuep = SANDBOX_PCI_VENDOR_ID; + break; + case PCI_DEVICE_ID: + *valuep = SANDBOX_PCI_DEVICE_ID; + break; + case PCI_CLASS_DEVICE: + if (size == PCI_SIZE_8) { + *valuep = SANDBOX_PCI_CLASS_SUB_CODE; + } else { + *valuep = (SANDBOX_PCI_CLASS_CODE << 8) | + SANDBOX_PCI_CLASS_SUB_CODE; + } + break; + case PCI_CLASS_CODE: + *valuep = SANDBOX_PCI_CLASS_CODE; + break; + case PCI_BASE_ADDRESS_0: + case PCI_BASE_ADDRESS_1: + case PCI_BASE_ADDRESS_2: + case PCI_BASE_ADDRESS_3: + case PCI_BASE_ADDRESS_4: + case PCI_BASE_ADDRESS_5: { + int barnum; + u32 *bar, result; + + barnum = offset_to_barnum(offset); + bar = &plat->bar[barnum]; + + result = *bar; + if (*bar == 0xffffffff) { + if (barinfo[barnum].type) { + result = (~(barinfo[barnum].size - 1) & + PCI_BASE_ADDRESS_IO_MASK) | + PCI_BASE_ADDRESS_SPACE_IO; + } else { + result = (~(barinfo[barnum].size - 1) & + PCI_BASE_ADDRESS_MEM_MASK) | + PCI_BASE_ADDRESS_MEM_TYPE_32; + } + } + debug("r bar %d=%x\n", barnum, result); + *valuep = result; + break; + } + } + + return 0; +} + +static int sandbox_swap_case_write_config(struct udevice *emul, uint offset, + ulong value, enum pci_size_t size) +{ + struct swap_case_platdata *plat = dev_get_platdata(emul); + + switch (offset) { + case PCI_COMMAND: + plat->command = value; + break; + case PCI_BASE_ADDRESS_0: + case PCI_BASE_ADDRESS_1: { + int barnum; + u32 *bar; + + barnum = offset_to_barnum(offset); + bar = &plat->bar[barnum]; + + debug("w bar %d=%lx\n", barnum, value); + *bar = value; + break; + } + } + + return 0; +} + +static int sandbox_swap_case_find_bar(struct udevice *emul, unsigned int addr, + int *barnump, unsigned int *offsetp) +{ + struct swap_case_platdata *plat = dev_get_platdata(emul); + int barnum; + + for (barnum = 0; barnum < ARRAY_SIZE(barinfo); barnum++) { + unsigned int size = barinfo[barnum].size; + + if (addr >= plat->bar[barnum] && + addr < plat->bar[barnum] + size) { + *barnump = barnum; + *offsetp = addr - plat->bar[barnum]; + return 0; + } + } + *barnump = -1; + + return -ENOENT; +} + +static void sandbox_swap_case_do_op(enum swap_case_op op, char *str, int len) +{ + for (; len > 0; len--, str++) { + switch (op) { + case OP_TO_UPPER: + *str = toupper(*str); + break; + case OP_TO_LOWER: + *str = tolower(*str); + break; + case OP_SWAP: + if (isupper(*str)) + *str = tolower(*str); + else + *str = toupper(*str); + break; + } + } +} + +int sandbox_swap_case_read_io(struct udevice *dev, unsigned int addr, + ulong *valuep, enum pci_size_t size) +{ + struct swap_case_priv *priv = dev_get_priv(dev); + unsigned int offset; + int barnum; + int ret; + + ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset); + if (ret) + return ret; + + if (barnum == 0 && offset == 0) + *valuep = (*valuep & ~0xff) | priv->op; + + return 0; +} + +int sandbox_swap_case_write_io(struct udevice *dev, unsigned int addr, + ulong value, enum pci_size_t size) +{ + struct swap_case_priv *priv = dev_get_priv(dev); + unsigned int offset; + int barnum; + int ret; + + ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset); + if (ret) + return ret; + if (barnum == 0 && offset == 0) + priv->op = value; + + return 0; +} + +static int sandbox_swap_case_map_physmem(struct udevice *dev, + phys_addr_t addr, unsigned long *lenp, void **ptrp) +{ + struct swap_case_priv *priv = dev_get_priv(dev); + unsigned int offset, avail; + int barnum; + int ret; + + ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset); + if (ret) + return ret; + if (barnum == 1) { + *ptrp = priv->mem_text + offset; + avail = barinfo[1].size - offset; + if (avail > barinfo[1].size) + *lenp = 0; + else + *lenp = min(*lenp, (ulong)avail); + + return 0; + } + + return -ENOENT; +} + +static int sandbox_swap_case_unmap_physmem(struct udevice *dev, + const void *vaddr, unsigned long len) +{ + struct swap_case_priv *priv = dev_get_priv(dev); + + sandbox_swap_case_do_op(priv->op, (void *)vaddr, len); + + return 0; +} + +struct dm_pci_emul_ops sandbox_swap_case_emul_ops = { + .get_devfn = sandbox_swap_case_get_devfn, + .read_config = sandbox_swap_case_read_config, + .write_config = sandbox_swap_case_write_config, + .read_io = sandbox_swap_case_read_io, + .write_io = sandbox_swap_case_write_io, + .map_physmem = sandbox_swap_case_map_physmem, + .unmap_physmem = sandbox_swap_case_unmap_physmem, +}; + +static const struct udevice_id sandbox_swap_case_ids[] = { + { .compatible = "sandbox,swap-case" }, + { } +}; + +U_BOOT_DRIVER(sandbox_swap_case_emul) = { + .name = "sandbox_swap_case_emul", + .id = UCLASS_PCI_EMUL, + .of_match = sandbox_swap_case_ids, + .ops = &sandbox_swap_case_emul_ops, + .priv_auto_alloc_size = sizeof(struct swap_case_priv), + .platdata_auto_alloc_size = sizeof(struct swap_case_platdata), +}; diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index db4d251..10ec216 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -105,7 +105,8 @@ static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data) else if (cmd->resp_type & MMC_RSP_PRESENT) xfertyp |= XFERTYP_RSPTYP_48; -#if defined(CONFIG_MX53) || defined(CONFIG_PPC_T4240) || defined(CONFIG_LS102XA) +#if defined(CONFIG_MX53) || defined(CONFIG_PPC_T4240) || \ + defined(CONFIG_LS102XA) || defined(CONFIG_LS2085A) if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) xfertyp |= XFERTYP_CMDTYP_ABORT; #endif @@ -183,7 +184,9 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) int timeout; struct fsl_esdhc_cfg *cfg = mmc->priv; struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; - +#ifdef CONFIG_LS2085A + dma_addr_t addr; +#endif uint wml_value; wml_value = data->blocksize/4; @@ -194,8 +197,16 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) esdhc_clrsetbits32(®s->wml, WML_RD_WML_MASK, wml_value); #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO +#ifdef CONFIG_LS2085A + addr = virt_to_phys((void *)(data->dest)); + if (upper_32_bits(addr)) + printf("Error found for upper 32 bits\n"); + else + esdhc_write32(®s->dsaddr, lower_32_bits(addr)); +#else esdhc_write32(®s->dsaddr, (u32)data->dest); #endif +#endif } else { #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO flush_dcache_range((ulong)data->src, @@ -212,8 +223,16 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) esdhc_clrsetbits32(®s->wml, WML_WR_WML_MASK, wml_value << 16); #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO +#ifdef CONFIG_LS2085A + addr = virt_to_phys((void *)(data->src)); + if (upper_32_bits(addr)) + printf("Error found for upper 32 bits\n"); + else + esdhc_write32(®s->dsaddr, lower_32_bits(addr)); +#else esdhc_write32(®s->dsaddr, (u32)data->src); #endif +#endif } esdhc_write32(®s->blkattr, data->blocks << 16 | data->blocksize); @@ -259,10 +278,23 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) static void check_and_invalidate_dcache_range (struct mmc_cmd *cmd, struct mmc_data *data) { +#ifdef CONFIG_LS2085A + unsigned start = 0; +#else unsigned start = (unsigned)data->dest ; +#endif unsigned size = roundup(ARCH_DMA_MINALIGN, data->blocks*data->blocksize); unsigned end = start+size ; +#ifdef CONFIG_LS2085A + dma_addr_t addr; + + addr = virt_to_phys((void *)(data->dest)); + if (upper_32_bits(addr)) + printf("Error found for upper 32 bits\n"); + else + start = lower_32_bits(addr); +#endif invalidate_dcache_range(start, end); } #endif diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index 7887f11..d4f3882 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -25,7 +25,7 @@ int zynq_sdhci_init(phys_addr_t regbase) host->name = "zynq_sdhci"; host->ioaddr = (void *)regbase; - host->quirks = SDHCI_QUIRK_NO_CD | SDHCI_QUIRK_WAIT_SEND_CMD | + host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B; host->version = sdhci_readw(host, SDHCI_HOST_VERSION); diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 7903eeb..79fa88b 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -46,7 +46,7 @@ struct fsl_ifc_ctrl { struct fsl_ifc_mtd *chips[MAX_BANKS]; /* device info */ - struct fsl_ifc *regs; + struct fsl_ifc regs; uint8_t __iomem *addr; /* Address of assigned IFC buffer */ unsigned int cs_nand; /* On which chipsel NAND is connected */ unsigned int page; /* Last page written to / read from */ @@ -225,7 +225,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) struct nand_chip *chip = mtd->priv; struct fsl_ifc_mtd *priv = chip->priv; struct fsl_ifc_ctrl *ctrl = priv->ctrl; - struct fsl_ifc *ifc = ctrl->regs; + struct fsl_ifc_runtime *ifc = ctrl->regs.rregs; int buf_num; ctrl->page = page_addr; @@ -289,10 +289,10 @@ static int fsl_ifc_run_command(struct mtd_info *mtd) struct nand_chip *chip = mtd->priv; struct fsl_ifc_mtd *priv = chip->priv; struct fsl_ifc_ctrl *ctrl = priv->ctrl; - struct fsl_ifc *ifc = ctrl->regs; + struct fsl_ifc_runtime *ifc = ctrl->regs.rregs; u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; u32 time_start; - u32 eccstat[4] = {0}; + u32 eccstat[8] = {0}; int i; /* set the chip select for NAND Transaction */ @@ -325,8 +325,15 @@ static int fsl_ifc_run_command(struct mtd_info *mtd) int sector = bufnum * chip->ecc.steps; int sector_end = sector + chip->ecc.steps - 1; - for (i = sector / 4; i <= sector_end / 4; i++) + for (i = sector / 4; i <= sector_end / 4; i++) { + if (i >= ARRAY_SIZE(eccstat)) { + printf("%s: eccstat too small for %d\n", + __func__, i); + return -EIO; + } + eccstat[i] = ifc_in32(&ifc->ifc_nand.nand_eccstat[i]); + } for (i = sector; i <= sector_end; i++) { errors = check_read_ecc(mtd, ctrl, eccstat, i); @@ -362,7 +369,7 @@ static void fsl_ifc_do_read(struct nand_chip *chip, { struct fsl_ifc_mtd *priv = chip->priv; struct fsl_ifc_ctrl *ctrl = priv->ctrl; - struct fsl_ifc *ifc = ctrl->regs; + struct fsl_ifc_runtime *ifc = ctrl->regs.rregs; /* Program FIR/IFC_NAND_FCR0 for Small/Large page */ if (mtd->writesize > 512) { @@ -400,7 +407,7 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, struct nand_chip *chip = mtd->priv; struct fsl_ifc_mtd *priv = chip->priv; struct fsl_ifc_ctrl *ctrl = priv->ctrl; - struct fsl_ifc *ifc = ctrl->regs; + struct fsl_ifc_runtime *ifc = ctrl->regs.rregs; /* clear the read buffer */ ctrl->read_bytes = 0; @@ -690,7 +697,7 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) { struct fsl_ifc_mtd *priv = chip->priv; struct fsl_ifc_ctrl *ctrl = priv->ctrl; - struct fsl_ifc *ifc = ctrl->regs; + struct fsl_ifc_runtime *ifc = ctrl->regs.rregs; u32 nand_fsr; if (ctrl->status != IFC_NAND_EVTER_STAT_OPC) @@ -747,24 +754,33 @@ static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip, static void fsl_ifc_ctrl_init(void) { + uint32_t ver = 0; ifc_ctrl = kzalloc(sizeof(*ifc_ctrl), GFP_KERNEL); if (!ifc_ctrl) return; - ifc_ctrl->regs = IFC_BASE_ADDR; + ifc_ctrl->regs.gregs = IFC_FCM_BASE_ADDR; + + ver = ifc_in32(&ifc_ctrl->regs.gregs->ifc_rev); + if (ver >= FSL_IFC_V2_0_0) + ifc_ctrl->regs.rregs = + (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_64KOFFSET; + else + ifc_ctrl->regs.rregs = + (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_4KOFFSET; /* clear event registers */ - ifc_out32(&ifc_ctrl->regs->ifc_nand.nand_evter_stat, ~0U); - ifc_out32(&ifc_ctrl->regs->ifc_nand.pgrdcmpl_evt_stat, ~0U); + ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.nand_evter_stat, ~0U); + ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.pgrdcmpl_evt_stat, ~0U); /* Enable error and event for any detected errors */ - ifc_out32(&ifc_ctrl->regs->ifc_nand.nand_evter_en, + ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.nand_evter_en, IFC_NAND_EVTER_EN_OPC_EN | IFC_NAND_EVTER_EN_PGRDCMPL_EN | IFC_NAND_EVTER_EN_FTOER_EN | IFC_NAND_EVTER_EN_WPER_EN); - ifc_out32(&ifc_ctrl->regs->ifc_nand.ncfgr, 0x0); + ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.ncfgr, 0x0); } static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip) @@ -773,7 +789,7 @@ static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip) static int fsl_ifc_sram_init(uint32_t ver) { - struct fsl_ifc *ifc = ifc_ctrl->regs; + struct fsl_ifc_runtime *ifc = ifc_ctrl->regs.rregs; uint32_t cs = 0, csor = 0, csor_8k = 0, csor_ext = 0; uint32_t ncfgr = 0; u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; @@ -799,13 +815,13 @@ static int fsl_ifc_sram_init(uint32_t ver) cs = ifc_ctrl->cs_nand >> IFC_NAND_CSEL_SHIFT; /* Save CSOR and CSOR_ext */ - csor = ifc_in32(&ifc_ctrl->regs->csor_cs[cs].csor); - csor_ext = ifc_in32(&ifc_ctrl->regs->csor_cs[cs].csor_ext); + csor = ifc_in32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor); + csor_ext = ifc_in32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor_ext); /* chage PageSize 8K and SpareSize 1K*/ csor_8k = (csor & ~(CSOR_NAND_PGS_MASK)) | 0x0018C000; - ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor, csor_8k); - ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, 0x0000400); + ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor, csor_8k); + ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor_ext, 0x0000400); /* READID */ ifc_out32(&ifc->ifc_nand.nand_fir0, @@ -845,8 +861,8 @@ static int fsl_ifc_sram_init(uint32_t ver) ifc_out32(&ifc->ifc_nand.nand_evter_stat, ifc_ctrl->status); /* Restore CSOR and CSOR_ext */ - ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor, csor); - ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, csor_ext); + ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor, csor); + ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor_ext, csor_ext); return 0; } @@ -857,6 +873,7 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr) struct nand_chip *nand; struct fsl_ifc_mtd *priv; struct nand_ecclayout *layout; + struct fsl_ifc_fcm *gregs = NULL; uint32_t cspr = 0, csor = 0, ver = 0; int ret = 0; @@ -872,14 +889,15 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr) priv->ctrl = ifc_ctrl; priv->vbase = addr; + gregs = ifc_ctrl->regs.gregs; /* Find which chip select it is connected to. */ for (priv->bank = 0; priv->bank < MAX_BANKS; priv->bank++) { phys_addr_t phys_addr = virt_to_phys(addr); - cspr = ifc_in32(&ifc_ctrl->regs->cspr_cs[priv->bank].cspr); - csor = ifc_in32(&ifc_ctrl->regs->csor_cs[priv->bank].csor); + cspr = ifc_in32(&gregs->cspr_cs[priv->bank].cspr); + csor = ifc_in32(&gregs->csor_cs[priv->bank].csor); if ((cspr & CSPR_V) && (cspr & CSPR_MSEL) == CSPR_MSEL_NAND && (cspr & CSPR_BA) == CSPR_PHYS_ADDR(phys_addr)) { @@ -998,7 +1016,7 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr) nand->ecc.mode = NAND_ECC_SOFT; } - ver = ifc_in32(&ifc_ctrl->regs->ifc_rev); + ver = ifc_in32(&gregs->ifc_rev); if (ver >= FSL_IFC_V1_1_0) ret = fsl_ifc_sram_init(ver); if (ret) diff --git a/drivers/mtd/nand/fsl_ifc_spl.c b/drivers/mtd/nand/fsl_ifc_spl.c index fb827c5..fccbfb5 100644 --- a/drivers/mtd/nand/fsl_ifc_spl.c +++ b/drivers/mtd/nand/fsl_ifc_spl.c @@ -48,11 +48,25 @@ static inline int check_read_ecc(uchar *buf, u32 *eccstat, return 0; } +static inline struct fsl_ifc_runtime *runtime_regs_address(void) +{ + struct fsl_ifc regs = {(void *)CONFIG_SYS_IFC_ADDR, NULL}; + int ver = 0; + + ver = ifc_in32(®s.gregs->ifc_rev); + if (ver >= FSL_IFC_V2_0_0) + regs.rregs = (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_64KOFFSET; + else + regs.rregs = (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_4KOFFSET; + + return regs.rregs; +} + static inline void nand_wait(uchar *buf, int bufnum, int page_size) { - struct fsl_ifc *ifc = IFC_BASE_ADDR; + struct fsl_ifc_runtime *ifc = runtime_regs_address(); u32 status; - u32 eccstat[4]; + u32 eccstat[8]; int bufperpage = page_size / 512; int bufnum_end, i; @@ -90,7 +104,8 @@ static inline int bad_block(uchar *marker, int port_size) int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst) { - struct fsl_ifc *ifc = IFC_BASE_ADDR; + struct fsl_ifc_fcm *gregs = (void *)CONFIG_SYS_IFC_ADDR; + struct fsl_ifc_runtime *ifc = NULL; uchar *buf = (uchar *)CONFIG_SYS_NAND_BASE; int page_size; int port_size; @@ -107,6 +122,8 @@ int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst) int pg_no; uchar *dst = vdst; + ifc = runtime_regs_address(); + /* Get NAND Flash configuration */ csor = CONFIG_SYS_NAND_CSOR; cspr = CONFIG_SYS_NAND_CSPR; @@ -130,7 +147,7 @@ int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst) bad_marker = 5; } - ver = ifc_in32(&ifc->ifc_rev); + ver = ifc_in32(&gregs->ifc_rev); if (ver >= FSL_IFC_V2_0_0) bufnum_mask = (bufnum_mask * 2) + 1; diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index 2dc46b4..ac6d09f 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -1,6 +1,6 @@ config DM_SPI_FLASH bool "Enable Driver Model for SPI flash" - depends on DM && SPI + depends on DM && DM_SPI help Enable driver model for SPI flash. This SPI flash interface (spi_flash_probe(), spi_flash_write(), etc.) is then @@ -12,3 +12,13 @@ config DM_SPI_FLASH during the transition parent. SPI and SPI flash must be enabled together (it is not possible to use driver model for one and not the other). + +config SPI_FLASH_SANDBOX + bool "Support sandbox SPI flash device" + depends on SANDBOX && DM_SPI_FLASH + help + Since sandbox cannot access real devices, an emulation mechanism is + provided instead. Drivers can be connected up to the sandbox SPI + bus (see CONFIG_SANDBOX_SPI) and SPI traffic will be routed to this + device. Typically the contents of the emulated SPI flash device is + stored in a file on the host filesystem. diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c index 376d815..4b25902 100644 --- a/drivers/mtd/spi/sf-uclass.c +++ b/drivers/mtd/spi/sf-uclass.c @@ -11,6 +11,22 @@ #include <dm/device-internal.h> #include "sf_internal.h" +int spi_flash_read_dm(struct udevice *dev, u32 offset, size_t len, void *buf) +{ + return sf_get_ops(dev)->read(dev, offset, len, buf); +} + +int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len, + const void *buf) +{ + return sf_get_ops(dev)->write(dev, offset, len, buf); +} + +int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len) +{ + return sf_get_ops(dev)->erase(dev, offset, len); +} + /* * TODO(sjg@chromium.org): This is an old-style function. We should remove * it when all SPI flash drivers use dm @@ -23,7 +39,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, if (spi_flash_probe_bus_cs(bus, cs, max_hz, spi_mode, &dev)) return NULL; - return dev->uclass_priv; + return dev_get_uclass_priv(dev); } void spi_flash_free(struct spi_flash *flash) diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 785f7a9..4158e13 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -97,10 +97,6 @@ enum { #define STATUS_QEB_MXIC (1 << 6) #define STATUS_PEC (1 << 7) -#ifdef CONFIG_SYS_SPI_ST_ENABLE_WP_PIN -#define STATUS_SRWD (1 << 7) /* SR write protect */ -#endif - /* Flash timeout values */ #define SPI_FLASH_PROG_TIMEOUT (2 * CONFIG_SYS_HZ) #define SPI_FLASH_PAGE_ERASE_TIMEOUT (5 * CONFIG_SYS_HZ) @@ -123,7 +119,8 @@ int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, * @name: Device name ([MANUFLETTER][DEVTYPE][DENSITY][EXTRAINFO]) * @jedec: Device jedec ID (0x[1byte_manuf_id][2byte_dev_id]) * @ext_jedec: Device ext_jedec ID - * @sector_size: Sector size of this device + * @sector_size: Isn't necessarily a sector size from vendor, + * the size listed here is what works with CMD_ERASE_64K * @nr_sectors: No.of sectors on this device * @e_rd_cmd: Enum list for read commands * @flags: Important param, for flash specific behaviour diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 34bc54e..38592f5 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -154,21 +154,17 @@ static void spi_flash_dual_flash(struct spi_flash *flash, u32 *addr) } #endif -int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout) +static int spi_flash_poll_status(struct spi_slave *spi, unsigned long timeout, + u8 cmd, u8 poll_bit) { - struct spi_slave *spi = flash->spi; unsigned long timebase; unsigned long flags = SPI_XFER_BEGIN; int ret; u8 status; u8 check_status = 0x0; - u8 poll_bit = STATUS_WIP; - u8 cmd = flash->poll_cmd; - if (cmd == CMD_FLAG_STATUS) { - poll_bit = STATUS_PEC; + if (cmd == CMD_FLAG_STATUS) check_status = poll_bit; - } #ifdef CONFIG_SF_DUAL_FLASH if (spi->flags & SPI_XFER_U_PAGE) @@ -204,6 +200,28 @@ int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout) return -1; } +int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout) +{ + struct spi_slave *spi = flash->spi; + int ret; + u8 poll_bit = STATUS_WIP; + u8 cmd = CMD_READ_STATUS; + + ret = spi_flash_poll_status(spi, timeout, cmd, poll_bit); + if (ret < 0) + return ret; + + if (flash->poll_cmd == CMD_FLAG_STATUS) { + poll_bit = STATUS_PEC; + cmd = CMD_FLAG_STATUS; + ret = spi_flash_poll_status(spi, timeout, cmd, poll_bit); + if (ret < 0) + return ret; + } + + return 0; +} + int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd, size_t cmd_len, const void *buf, size_t buf_len) { diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 4103723..201471c 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -13,6 +13,7 @@ #include <errno.h> #include <fdtdec.h> #include <malloc.h> +#include <mapmem.h> #include <spi.h> #include <spi_flash.h> #include <asm/io.h> @@ -131,6 +132,9 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode, flash->name = params->name; flash->memory_map = spi->memory_map; flash->dual_flash = flash->spi->option; +#ifdef CONFIG_DM_SPI_FLASH + flash->flags = params->flags; +#endif /* Assign spi_flash ops */ #ifndef CONFIG_DM_SPI_FLASH @@ -183,6 +187,9 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode, flash->erase_size = flash->sector_size; } + /* Now erase size becomes valid sector size */ + flash->sector_size = flash->erase_size; + /* Look for the fastest read cmd */ cmd = fls(params->e_rd_cmd & flash->spi->op_mode_rx); if (cmd) { @@ -287,34 +294,6 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) } #endif /* CONFIG_OF_CONTROL */ -#ifdef CONFIG_SYS_SPI_ST_ENABLE_WP_PIN -/* enable the W#/Vpp signal to disable writing to the status register */ -static int spi_enable_wp_pin(struct spi_flash *flash) -{ - u8 status; - int ret; - - ret = spi_flash_cmd_read_status(flash, &status); - if (ret < 0) - return ret; - - ret = spi_flash_cmd_write_status(flash, STATUS_SRWD); - if (ret < 0) - return ret; - - ret = spi_flash_cmd_write_disable(flash); - if (ret < 0) - return ret; - - return 0; -} -#else -static int spi_enable_wp_pin(struct spi_flash *flash) -{ - return 0; -} -#endif - /** * spi_flash_probe_slave() - Probe for a SPI flash device on a bus * @@ -393,8 +372,6 @@ int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash) puts(" Full access #define CONFIG_SPI_FLASH_BAR\n"); } #endif - if (spi_enable_wp_pin(flash)) - puts("Enable WP pin failed\n"); /* Release spi bus */ spi_release_bus(spi); @@ -433,6 +410,8 @@ struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs, struct spi_slave *bus; bus = spi_setup_slave(busnum, cs, max_hz, spi_mode); + if (!bus) + return NULL; return spi_flash_probe_tail(bus); } @@ -443,6 +422,8 @@ struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node, struct spi_slave *bus; bus = spi_setup_slave_fdt(blob, slave_node, spi_node); + if (!bus) + return NULL; return spi_flash_probe_tail(bus); } #endif @@ -458,7 +439,7 @@ void spi_flash_free(struct spi_flash *flash) static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len, void *buf) { - struct spi_flash *flash = dev->uclass_priv; + struct spi_flash *flash = dev_get_uclass_priv(dev); return spi_flash_cmd_read_ops(flash, offset, len, buf); } @@ -466,14 +447,23 @@ static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len, int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len, const void *buf) { - struct spi_flash *flash = dev->uclass_priv; + struct spi_flash *flash = dev_get_uclass_priv(dev); + +#if defined(CONFIG_SPI_FLASH_SST) + if (flash->flags & SST_WR) { + if (flash->spi->op_mode_tx & SPI_OPM_TX_BP) + return sst_write_bp(flash, offset, len, buf); + else + return sst_write_wp(flash, offset, len, buf); + } +#endif return spi_flash_cmd_write_ops(flash, offset, len, buf); } int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len) { - struct spi_flash *flash = dev->uclass_priv; + struct spi_flash *flash = dev_get_uclass_priv(dev); return spi_flash_cmd_erase_ops(flash, offset, len); } @@ -484,7 +474,7 @@ int spi_flash_std_probe(struct udevice *dev) struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); struct spi_flash *flash; - flash = dev->uclass_priv; + flash = dev_get_uclass_priv(dev); flash->dev = dev; debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs); return spi_flash_probe_slave(slave, flash); diff --git a/drivers/net/4xx_enet.c b/drivers/net/4xx_enet.c index 381ec42..3c30f42 100644 --- a/drivers/net/4xx_enet.c +++ b/drivers/net/4xx_enet.c @@ -1350,7 +1350,7 @@ get_speed: for (i = 0; i < NUM_RX_BUFF; i++) { hw_p->rx[i].ctrl = 0; hw_p->rx[i].data_len = 0; - hw_p->rx[i].data_ptr = (char *)NetRxPackets[i]; + hw_p->rx[i].data_ptr = (char *)net_rx_packets[i]; if ((NUM_RX_BUFF - 1) == i) hw_p->rx[i].ctrl |= MAL_RX_CTRL_WRAP; hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR; @@ -1719,8 +1719,6 @@ static void mal_err (struct eth_device *dev, unsigned long isr, unsigned long uic, unsigned long maldef, unsigned long mal_errr) { - EMAC_4XX_HW_PST hw_p = dev->priv; - mtdcr (MAL0_ESR, isr); /* clear interrupt */ /* clear DE interrupt */ @@ -1728,10 +1726,11 @@ static void mal_err (struct eth_device *dev, unsigned long isr, mtdcr (MAL0_RXDEIR, 0x80000000); #ifdef INFO_4XX_ENET - printf ("\nMAL error occured.... ISR = %lx UIC = = %lx MAL_DEF = %lx MAL_ERR= %lx \n", isr, uic, maldef, mal_errr); + printf("\nMAL error occured.... ISR = %lx UIC = = %lx MAL_DEF = %lx MAL_ERR= %lx\n", + isr, uic, maldef, mal_errr); #endif - eth_init (hw_p->bis); /* start again... */ + eth_init(); /* start again... */ } /*-----------------------------------------------------------------------------+ @@ -1859,13 +1858,17 @@ static int ppc_4xx_eth_rx (struct eth_device *dev) length = hw_p->rx[user_index].data_len & 0x0fff; - /* Pass the packet up to the protocol layers. */ - /* NetReceive(NetRxPackets[rxIdx], length - 4); */ - /* NetReceive(NetRxPackets[i], length); */ + /* + * Pass the packet up to the protocol layers. + * net_process_received_packet(net_rx_packets[rxIdx], + * length - 4); + * net_process_received_packet(net_rx_packets[i], length); + */ invalidate_dcache_range((u32)hw_p->rx[user_index].data_ptr, (u32)hw_p->rx[user_index].data_ptr + length - 4); - NetReceive (NetRxPackets[user_index], length - 4); + net_process_received_packet(net_rx_packets[user_index], + length - 4); /* Free Recv Buffer */ hw_p->rx[user_index].ctrl |= MAL_RX_CTRL_EMPTY; /* Free rx buffer descriptor queue */ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index e69de29..973258a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -0,0 +1,49 @@ +config DM_ETH + bool "Enable Driver Model for Ethernet drivers" + depends on DM + help + Enable driver model for Ethernet. + + The eth_*() interface will be implemented by the UC_ETH class + This is currently implemented in net/eth.c + Look in include/net.h for details. + +menuconfig NETDEVICES + bool "Network device support" + depends on NET + help + You must select Y to enable any network device support + Generally if you have any networking support this is a given + + If unsure, say Y + +if NETDEVICES + +config ETH_SANDBOX + depends on DM_ETH && SANDBOX + default y + bool "Sandbox: Mocked Ethernet driver" + help + This driver simply responds with fake ARP replies and ping + replies that are used to verify network stack functionality + + This driver is particularly useful in the test/dm/eth.c tests + +config ETH_SANDBOX_RAW + depends on DM_ETH && SANDBOX + default y + bool "Sandbox: Bridge to Linux Raw Sockets" + help + This driver is a bridge from the bottom of the network stack + in U-Boot to the RAW AF_PACKET API in Linux. This allows real + network traffic to be tested from within sandbox. See + board/sandbox/README.sandbox for more details. + +config ETH_DESIGNWARE + bool "Synopsys Designware Ethernet MAC" + help + This MAC is present in SoCs from various vendors. It supports + 100Mbit and 1 Gbit operation. You must enable CONFIG_PHYLIB to + provide the PHY (physical media interface). + +endif # NETDEVICES diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 5a5269a..150470c 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -16,7 +16,7 @@ obj-$(CONFIG_BFIN_MAC) += bfin_mac.o obj-$(CONFIG_CALXEDA_XGMAC) += calxedaxgmac.o obj-$(CONFIG_CS8900) += cs8900.o obj-$(CONFIG_TULIP) += dc2114x.o -obj-$(CONFIG_DESIGNWARE_ETH) += designware.o +obj-$(CONFIG_ETH_DESIGNWARE) += designware.o obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o obj-$(CONFIG_DNET) += dnet.o obj-$(CONFIG_E1000) += e1000.o @@ -51,6 +51,8 @@ obj-$(CONFIG_PCH_GBE) += pch_gbe.o obj-$(CONFIG_PCNET) += pcnet.o obj-$(CONFIG_RTL8139) += rtl8139.o obj-$(CONFIG_RTL8169) += rtl8169.o +obj-$(CONFIG_ETH_SANDBOX) += sandbox.o +obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw.o obj-$(CONFIG_SH_ETHER) += sh_eth.o obj-$(CONFIG_SMC91111) += smc91111.o obj-$(CONFIG_SMC911X) += smc911x.o @@ -67,4 +69,6 @@ obj-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \ xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o obj-$(CONFIG_ZYNQ_GEM) += zynq_gem.o obj-$(CONFIG_FSL_MC_ENET) += fsl-mc/ +obj-$(CONFIG_FSL_MC_ENET) += ldpaa_eth/ +obj-$(CONFIG_FSL_MEMAC) += fm/memac_phy.o obj-$(CONFIG_VSC9953) += vsc9953.o diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c index de517f8..c4fd6ec 100644 --- a/drivers/net/altera_tse.c +++ b/drivers/net/altera_tse.c @@ -303,16 +303,17 @@ static int tse_eth_rx(struct eth_device *dev) ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) { debug("got packet\n"); packet_length = rx_desc->actual_bytes_transferred; - NetReceive(NetRxPackets[0], packet_length); + net_process_received_packet(net_rx_packets[0], packet_length); /* start descriptor again */ - flush_dcache_range((unsigned long)(NetRxPackets[0]), - (unsigned long)(NetRxPackets[0]) + PKTSIZE_ALIGN); + flush_dcache_range((unsigned long)(net_rx_packets[0]), + (unsigned long)(net_rx_packets[0] + + PKTSIZE_ALIGN)); alt_sgdma_construct_descriptor_burst( (volatile struct alt_sgdma_descriptor *)&rx_desc[0], (volatile struct alt_sgdma_descriptor *)&rx_desc[1], (unsigned int)0x0, /* read addr */ - (unsigned int *)NetRxPackets[0], + (unsigned int *)net_rx_packets[0], 0x0, /* length or EOP */ 0x0, /* gen eop */ 0x0, /* read fixed */ @@ -835,13 +836,13 @@ static int tse_eth_init(struct eth_device *dev, bd_t * bd) 0x0 /* channel */ ); debug("Configuring rx desc\n"); - flush_dcache_range((unsigned long)(NetRxPackets[0]), - (unsigned long)(NetRxPackets[0]) + PKTSIZE_ALIGN); + flush_dcache_range((unsigned long)(net_rx_packets[0]), + (unsigned long)(net_rx_packets[0]) + PKTSIZE_ALIGN); alt_sgdma_construct_descriptor_burst( (volatile struct alt_sgdma_descriptor *)&rx_desc[0], (volatile struct alt_sgdma_descriptor *)&rx_desc[1], (unsigned int)0x0, /* read addr */ - (unsigned int *)NetRxPackets[0], + (unsigned int *)net_rx_packets[0], 0x0, /* length or EOP */ 0x0, /* gen eop */ 0x0, /* read fixed */ diff --git a/drivers/net/armada100_fec.c b/drivers/net/armada100_fec.c index a8da6b1..e6a6252 100644 --- a/drivers/net/armada100_fec.c +++ b/drivers/net/armada100_fec.c @@ -639,15 +639,16 @@ static int armdfec_recv(struct eth_device *dev) } else { /* !!! call higher layer processing */ debug("ARMD100 FEC: (%s) Sending Received packet to" - " upper layer (NetReceive)\n", __func__); + " upper layer (net_process_received_packet)\n", __func__); /* * let the upper layer handle the packet, subtract offset * as two dummy bytes are added in received buffer see * PORT_CONFIG_EXT register bit TWO_Byte_Stuff_Mode bit. */ - NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET), - (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET)); + net_process_received_packet( + p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET, + (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET)); } /* * free these descriptors and point next in the ring diff --git a/drivers/net/at91_emac.c b/drivers/net/at91_emac.c index 64d4c56..d51e098 100644 --- a/drivers/net/at91_emac.c +++ b/drivers/net/at91_emac.c @@ -352,7 +352,7 @@ static int at91emac_init(struct eth_device *netdev, bd_t *bd) /* Init Ethernet buffers */ for (i = 0; i < RBF_FRAMEMAX; i++) { - dev->rbfdt[i].addr = (unsigned long) NetRxPackets[i]; + dev->rbfdt[i].addr = (unsigned long) net_rx_packets[i]; dev->rbfdt[i].size = 0; } dev->rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP; @@ -420,7 +420,7 @@ static int at91emac_recv(struct eth_device *netdev) rbfp = &dev->rbfdt[dev->rbindex]; while (rbfp->addr & RBF_OWNER) { size = rbfp->size & RBF_SIZE; - NetReceive(NetRxPackets[dev->rbindex], size); + net_process_received_packet(net_rx_packets[dev->rbindex], size); debug_cond(DEBUG_AT91EMAC, "Recv[%ld]: %d bytes @ %lx\n", dev->rbindex, size, rbfp->addr); diff --git a/drivers/net/ax88180.c b/drivers/net/ax88180.c index 7f0cfe5..ded9e06 100644 --- a/drivers/net/ax88180.c +++ b/drivers/net/ax88180.c @@ -192,9 +192,9 @@ static void ax88180_rx_handler (struct eth_device *dev) unsigned short rxcurt_ptr, rxbound_ptr, next_ptr; int i; #if defined (CONFIG_DRIVER_AX88180_16BIT) - unsigned short *rxdata = (unsigned short *)NetRxPackets[0]; + unsigned short *rxdata = (unsigned short *)net_rx_packets[0]; #else - unsigned long *rxdata = (unsigned long *)NetRxPackets[0]; + unsigned long *rxdata = (unsigned long *)net_rx_packets[0]; #endif unsigned short count; @@ -237,7 +237,7 @@ static void ax88180_rx_handler (struct eth_device *dev) OUTW (dev, RX_STOP_READ, RXINDICATOR); /* Pass the packet up to the protocol layers. */ - NetReceive (NetRxPackets[0], data_size); + net_process_received_packet(net_rx_packets[0], data_size); OUTW (dev, rxbound_ptr, RXBOUND); diff --git a/drivers/net/bcm-sf2-eth.c b/drivers/net/bcm-sf2-eth.c index 5252d49..51d5146 100644 --- a/drivers/net/bcm-sf2-eth.c +++ b/drivers/net/bcm-sf2-eth.c @@ -103,7 +103,7 @@ static int bcm_sf2_eth_send(struct eth_device *dev, void *packet, int length) static int bcm_sf2_eth_receive(struct eth_device *dev) { struct eth_dma *dma = &(((struct eth_info *)(dev->priv))->dma); - uint8_t *buf = (uint8_t *)NetRxPackets[0]; + uint8_t *buf = (uint8_t *)net_rx_packets[0]; int rcvlen; int rc = 0; int i = 0; @@ -124,11 +124,11 @@ static int bcm_sf2_eth_receive(struct eth_device *dev) debug("recieved\n"); /* Forward received packet to uboot network handler */ - NetReceive(buf, rcvlen); + net_process_received_packet(buf, rcvlen); if (++i >= PKTBUFSRX) i = 0; - buf = NetRxPackets[i]; + buf = net_rx_packets[i]; } } diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 0c2d2ef..61cb1b0 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -189,8 +189,8 @@ static int bfin_EMAC_recv(struct eth_device *dev) debug("%s: len = %d\n", __func__, length - 4); - NetRxPackets[rxIdx] = rxbuf[rxIdx]->FrmData->Dest; - NetReceive(NetRxPackets[rxIdx], length - 4); + net_rx_packets[rxIdx] = rxbuf[rxIdx]->FrmData->Dest; + net_process_received_packet(net_rx_packets[rxIdx], length - 4); bfin_write_DMA1_IRQ_STATUS(DMA_DONE | DMA_ERR); rxbuf[rxIdx]->StatusWord = 0x00000000; if ((rxIdx + 1) >= PKTBUFSRX) diff --git a/drivers/net/calxedaxgmac.c b/drivers/net/calxedaxgmac.c index ff94865..c02b397 100644 --- a/drivers/net/calxedaxgmac.c +++ b/drivers/net/calxedaxgmac.c @@ -466,7 +466,7 @@ static int xgmac_rx(struct eth_device *dev) length = desc_get_rx_frame_len(rxdesc); - NetReceive(desc_get_buf_addr(rxdesc), length); + net_process_received_packet(desc_get_buf_addr(rxdesc), length); /* set descriptor back to owned by XGMAC */ desc_set_rx_owner(rxdesc); diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index 52f8da6..fb4d621 100644 --- a/drivers/net/cpsw.c +++ b/drivers/net/cpsw.c @@ -289,7 +289,7 @@ static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr) addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8); } -static inline void cpsw_ale_set_addr(u32 *ale_entry, u8 *addr) +static inline void cpsw_ale_set_addr(u32 *ale_entry, const u8 *addr) { int i; @@ -321,7 +321,7 @@ static int cpsw_ale_write(struct cpsw_priv *priv, int idx, u32 *ale_entry) return idx; } -static int cpsw_ale_match_addr(struct cpsw_priv *priv, u8* addr) +static int cpsw_ale_match_addr(struct cpsw_priv *priv, const u8 *addr) { u32 ale_entry[ALE_ENTRY_WORDS]; int type, idx; @@ -374,7 +374,7 @@ static int cpsw_ale_find_ageable(struct cpsw_priv *priv) return -ENOENT; } -static int cpsw_ale_add_ucast(struct cpsw_priv *priv, u8 *addr, +static int cpsw_ale_add_ucast(struct cpsw_priv *priv, const u8 *addr, int port, int flags) { u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; @@ -399,7 +399,8 @@ static int cpsw_ale_add_ucast(struct cpsw_priv *priv, u8 *addr, return 0; } -static int cpsw_ale_add_mcast(struct cpsw_priv *priv, u8 *addr, int port_mask) +static int cpsw_ale_add_mcast(struct cpsw_priv *priv, const u8 *addr, + int port_mask) { u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; int idx, mask; @@ -644,7 +645,7 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv) slave_port = cpsw_get_slave_port(priv, slave->slave_num); cpsw_ale_port_state(priv, slave_port, ALE_PORT_STATE_FORWARD); - cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << slave_port); + cpsw_ale_add_mcast(priv, net_bcast_ethaddr, 1 << slave_port); priv->phy_mask |= 1 << slave->data->phy_addr; } @@ -773,7 +774,7 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis) cpsw_ale_add_ucast(priv, priv->dev->enetaddr, priv->host_port, ALE_SECURE); - cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << priv->host_port); + cpsw_ale_add_mcast(priv, net_bcast_ethaddr, 1 << priv->host_port); for_active_slave(slave, priv) cpsw_slave_init(slave, priv); @@ -845,7 +846,7 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis) /* submit rx descs */ for (i = 0; i < PKTBUFSRX; i++) { - ret = cpdma_submit(priv, &priv->rx_chan, NetRxPackets[i], + ret = cpdma_submit(priv, &priv->rx_chan, net_rx_packets[i], PKTSIZE); if (ret < 0) { printf("error %d submitting rx desc\n", ret); @@ -904,7 +905,7 @@ static int cpsw_recv(struct eth_device *dev) while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) { invalidate_dcache_range((unsigned long)buffer, (unsigned long)buffer + PKTSIZE_ALIGN); - NetReceive(buffer, len); + net_process_received_packet(buffer, len); cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE); } diff --git a/drivers/net/cs8900.c b/drivers/net/cs8900.c index 84963c1..0713464 100644 --- a/drivers/net/cs8900.c +++ b/drivers/net/cs8900.c @@ -188,14 +188,13 @@ static int cs8900_recv(struct eth_device *dev) if (rxlen > PKTSIZE_ALIGN + PKTALIGN) debug("packet too big!\n"); - for (addr = (u16 *) NetRxPackets[0], i = rxlen >> 1; i > 0; - i--) + for (addr = (u16 *)net_rx_packets[0], i = rxlen >> 1; i > 0; i--) *addr++ = REG_READ(&priv->regs->rtdata); if (rxlen & 1) *addr++ = REG_READ(&priv->regs->rtdata); /* Pass the packet up to the protocol layers. */ - NetReceive (NetRxPackets[0], rxlen); + net_process_received_packet(net_rx_packets[0], rxlen); return rxlen; } diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 08bc1af..427ad3e 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -700,8 +700,9 @@ static int davinci_eth_rcv_packet (struct eth_device *dev) unsigned long tmp = (unsigned long)rx_curr_desc->buffer; invalidate_dcache_range(tmp, tmp + EMAC_RXBUF_SIZE); - NetReceive (rx_curr_desc->buffer, - (rx_curr_desc->buff_off_len & 0xffff)); + net_process_received_packet( + rx_curr_desc->buffer, + rx_curr_desc->buff_off_len & 0xffff); ret = rx_curr_desc->buff_off_len & 0xffff; } diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 799839c..8245cf5 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -333,9 +333,11 @@ static int dc21x4x_init(struct eth_device* dev, bd_t* bis) for (i = 0; i < NUM_RX_DESC; i++) { rx_ring[i].status = cpu_to_le32(R_OWN); rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ); - rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i])); + rx_ring[i].buf = cpu_to_le32( + phys_to_bus((u32)net_rx_packets[i])); #ifdef CONFIG_TULIP_FIX_DAVICOM - rx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &rx_ring[(i+1) % NUM_RX_DESC])); + rx_ring[i].next = cpu_to_le32( + phys_to_bus((u32)&rx_ring[(i + 1) % NUM_RX_DESC])); #else rx_ring[i].next = 0; #endif @@ -448,7 +450,8 @@ static int dc21x4x_recv(struct eth_device* dev) /* Pass the packet up to the protocol * layers. */ - NetReceive(NetRxPackets[rx_new], length - 4); + net_process_received_packet( + net_rx_packets[rx_new], length - 4); } /* Change buffer ownership for this frame, back diff --git a/drivers/net/designware.c b/drivers/net/designware.c index cc01604..07281a6 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -6,10 +6,12 @@ */ /* - * Designware ethernet IP driver for u-boot + * Designware ethernet IP driver for U-Boot */ #include <common.h> +#include <dm.h> +#include <errno.h> #include <miiphy.h> #include <malloc.h> #include <linux/compiler.h> @@ -17,6 +19,8 @@ #include <asm/io.h> #include "designware.h" +DECLARE_GLOBAL_DATA_PTR; + #if !defined(CONFIG_PHYLIB) # error "DesignWare Ether MAC requires PHYLIB - missing CONFIG_PHYLIB" #endif @@ -40,7 +44,7 @@ static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) udelay(10); }; - return -1; + return -ETIMEDOUT; } static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, @@ -49,7 +53,7 @@ static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, struct eth_mac_regs *mac_p = bus->priv; ulong start; u16 miiaddr; - int ret = -1, timeout = CONFIG_MDIO_TIMEOUT; + int ret = -ETIMEDOUT, timeout = CONFIG_MDIO_TIMEOUT; writel(val, &mac_p->miidata); miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | @@ -69,27 +73,26 @@ static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, return ret; } -static int dw_mdio_init(char *name, struct eth_mac_regs *mac_regs_p) +static int dw_mdio_init(const char *name, struct eth_mac_regs *mac_regs_p) { struct mii_dev *bus = mdio_alloc(); if (!bus) { printf("Failed to allocate MDIO bus\n"); - return -1; + return -ENOMEM; } bus->read = dw_mdio_read; bus->write = dw_mdio_write; - sprintf(bus->name, name); + snprintf(bus->name, sizeof(bus->name), name); bus->priv = (void *)mac_regs_p; return mdio_register(bus); } -static void tx_descs_init(struct eth_device *dev) +static void tx_descs_init(struct dw_eth_dev *priv) { - struct dw_eth_dev *priv = dev->priv; struct eth_dma_regs *dma_p = priv->dma_regs_p; struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0]; char *txbuffs = &priv->txbuffs[0]; @@ -128,9 +131,8 @@ static void tx_descs_init(struct eth_device *dev) priv->tx_currdescnum = 0; } -static void rx_descs_init(struct eth_device *dev) +static void rx_descs_init(struct dw_eth_dev *priv) { - struct dw_eth_dev *priv = dev->priv; struct eth_dma_regs *dma_p = priv->dma_regs_p; struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0]; char *rxbuffs = &priv->rxbuffs[0]; @@ -170,12 +172,10 @@ static void rx_descs_init(struct eth_device *dev) priv->rx_currdescnum = 0; } -static int dw_write_hwaddr(struct eth_device *dev) +static int _dw_write_hwaddr(struct dw_eth_dev *priv, u8 *mac_id) { - struct dw_eth_dev *priv = dev->priv; struct eth_mac_regs *mac_p = priv->mac_regs_p; u32 macid_lo, macid_hi; - u8 *mac_id = &dev->enetaddr[0]; macid_lo = mac_id[0] + (mac_id[1] << 8) + (mac_id[2] << 16) + (mac_id[3] << 24); @@ -213,9 +213,8 @@ static void dw_adjust_link(struct eth_mac_regs *mac_p, (phydev->port == PORT_FIBRE) ? ", fiber mode" : ""); } -static void dw_eth_halt(struct eth_device *dev) +static void _dw_eth_halt(struct dw_eth_dev *priv) { - struct dw_eth_dev *priv = dev->priv; struct eth_mac_regs *mac_p = priv->mac_regs_p; struct eth_dma_regs *dma_p = priv->dma_regs_p; @@ -225,12 +224,12 @@ static void dw_eth_halt(struct eth_device *dev) phy_shutdown(priv->phydev); } -static int dw_eth_init(struct eth_device *dev, bd_t *bis) +static int _dw_eth_init(struct dw_eth_dev *priv, u8 *enetaddr) { - struct dw_eth_dev *priv = dev->priv; struct eth_mac_regs *mac_p = priv->mac_regs_p; struct eth_dma_regs *dma_p = priv->dma_regs_p; unsigned int start; + int ret; writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode); @@ -238,7 +237,7 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis) while (readl(&dma_p->busmode) & DMAMAC_SRST) { if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) { printf("DMA reset timeout\n"); - return -1; + return -ETIMEDOUT; } mdelay(100); @@ -246,10 +245,10 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis) /* Soft reset above clears HW address registers. * So we have to set it here once again */ - dw_write_hwaddr(dev); + _dw_write_hwaddr(priv, enetaddr); - rx_descs_init(dev); - tx_descs_init(dev); + rx_descs_init(priv); + tx_descs_init(priv); writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode); @@ -268,25 +267,25 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis) #endif /* Start up the PHY */ - if (phy_startup(priv->phydev)) { + ret = phy_startup(priv->phydev); + if (ret) { printf("Could not initialize PHY %s\n", priv->phydev->dev->name); - return -1; + return ret; } dw_adjust_link(mac_p, priv->phydev); if (!priv->phydev->link) - return -1; + return -EIO; writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf); return 0; } -static int dw_eth_send(struct eth_device *dev, void *packet, int length) +static int _dw_eth_send(struct dw_eth_dev *priv, void *packet, int length) { - struct dw_eth_dev *priv = dev->priv; struct eth_dma_regs *dma_p = priv->dma_regs_p; u32 desc_num = priv->tx_currdescnum; struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num]; @@ -309,7 +308,7 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) /* Check if the descriptor is owned by CPU */ if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) { printf("CPU not owner of tx frame\n"); - return -1; + return -EPERM; } memcpy(desc_p->dmamac_addr, packet, length); @@ -347,12 +346,11 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) return 0; } -static int dw_eth_recv(struct eth_device *dev) +static int _dw_eth_recv(struct dw_eth_dev *priv, uchar **packetp) { - struct dw_eth_dev *priv = dev->priv; u32 status, desc_num = priv->rx_currdescnum; struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; - int length = 0; + int length = -EAGAIN; uint32_t desc_start = (uint32_t)desc_p; uint32_t desc_end = desc_start + roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); @@ -373,31 +371,39 @@ static int dw_eth_recv(struct eth_device *dev) /* Invalidate received data */ data_end = data_start + roundup(length, ARCH_DMA_MINALIGN); invalidate_dcache_range(data_start, data_end); + *packetp = desc_p->dmamac_addr; + } - NetReceive(desc_p->dmamac_addr, length); + return length; +} - /* - * Make the current descriptor valid again and go to - * the next one - */ - desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; +static int _dw_free_pkt(struct dw_eth_dev *priv) +{ + u32 desc_num = priv->rx_currdescnum; + struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; + uint32_t desc_start = (uint32_t)desc_p; + uint32_t desc_end = desc_start + + roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); - /* Flush only status field - others weren't changed */ - flush_dcache_range(desc_start, desc_end); + /* + * Make the current descriptor valid again and go to + * the next one + */ + desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; - /* Test the wrap-around condition. */ - if (++desc_num >= CONFIG_RX_DESCR_NUM) - desc_num = 0; - } + /* Flush only status field - others weren't changed */ + flush_dcache_range(desc_start, desc_end); + /* Test the wrap-around condition. */ + if (++desc_num >= CONFIG_RX_DESCR_NUM) + desc_num = 0; priv->rx_currdescnum = desc_num; - return length; + return 0; } -static int dw_phy_init(struct eth_device *dev) +static int dw_phy_init(struct dw_eth_dev *priv, void *dev) { - struct dw_eth_dev *priv = dev->priv; struct phy_device *phydev; int mask = 0xffffffff; @@ -407,7 +413,7 @@ static int dw_phy_init(struct eth_device *dev) phydev = phy_find_by_mask(priv->bus, mask, priv->interface); if (!phydev) - return -1; + return -ENODEV; phy_connect_dev(phydev, dev); @@ -417,7 +423,43 @@ static int dw_phy_init(struct eth_device *dev) priv->phydev = phydev; phy_config(phydev); - return 1; + return 0; +} + +#ifndef CONFIG_DM_ETH +static int dw_eth_init(struct eth_device *dev, bd_t *bis) +{ + return _dw_eth_init(dev->priv, dev->enetaddr); +} + +static int dw_eth_send(struct eth_device *dev, void *packet, int length) +{ + return _dw_eth_send(dev->priv, packet, length); +} + +static int dw_eth_recv(struct eth_device *dev) +{ + uchar *packet; + int length; + + length = _dw_eth_recv(dev->priv, &packet); + if (length == -EAGAIN) + return 0; + net_process_received_packet(packet, length); + + _dw_free_pkt(dev->priv); + + return 0; +} + +static void dw_eth_halt(struct eth_device *dev) +{ + return _dw_eth_halt(dev->priv); +} + +static int dw_write_hwaddr(struct eth_device *dev) +{ + return _dw_write_hwaddr(dev->priv, dev->enetaddr); } int designware_initialize(ulong base_addr, u32 interface) @@ -465,5 +507,117 @@ int designware_initialize(ulong base_addr, u32 interface) dw_mdio_init(dev->name, priv->mac_regs_p); priv->bus = miiphy_get_dev_by_name(dev->name); - return dw_phy_init(dev); + return dw_phy_init(priv, dev); +} +#endif + +#ifdef CONFIG_DM_ETH +static int designware_eth_start(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + + return _dw_eth_init(dev->priv, pdata->enetaddr); +} + +static int designware_eth_send(struct udevice *dev, void *packet, int length) +{ + struct dw_eth_dev *priv = dev_get_priv(dev); + + return _dw_eth_send(priv, packet, length); +} + +static int designware_eth_recv(struct udevice *dev, uchar **packetp) +{ + struct dw_eth_dev *priv = dev_get_priv(dev); + + return _dw_eth_recv(priv, packetp); +} + +static int designware_eth_free_pkt(struct udevice *dev, uchar *packet, + int length) +{ + struct dw_eth_dev *priv = dev_get_priv(dev); + + return _dw_free_pkt(priv); +} + +static void designware_eth_stop(struct udevice *dev) +{ + struct dw_eth_dev *priv = dev_get_priv(dev); + + return _dw_eth_halt(priv); +} + +static int designware_eth_write_hwaddr(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct dw_eth_dev *priv = dev_get_priv(dev); + + return _dw_write_hwaddr(priv, pdata->enetaddr); +} + +static int designware_eth_probe(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct dw_eth_dev *priv = dev_get_priv(dev); + int ret; + + debug("%s, iobase=%lx, priv=%p\n", __func__, pdata->iobase, priv); + priv->mac_regs_p = (struct eth_mac_regs *)pdata->iobase; + priv->dma_regs_p = (struct eth_dma_regs *)(pdata->iobase + + DW_DMA_BASE_OFFSET); + priv->interface = pdata->phy_interface; + + dw_mdio_init(dev->name, priv->mac_regs_p); + priv->bus = miiphy_get_dev_by_name(dev->name); + + ret = dw_phy_init(priv, dev); + debug("%s, ret=%d\n", __func__, ret); + + return ret; } + +static const struct eth_ops designware_eth_ops = { + .start = designware_eth_start, + .send = designware_eth_send, + .recv = designware_eth_recv, + .free_pkt = designware_eth_free_pkt, + .stop = designware_eth_stop, + .write_hwaddr = designware_eth_write_hwaddr, +}; + +static int designware_eth_ofdata_to_platdata(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + const char *phy_mode; + + pdata->iobase = dev_get_addr(dev); + pdata->phy_interface = -1; + phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL); + if (phy_mode) + pdata->phy_interface = phy_get_interface_by_name(phy_mode); + if (pdata->phy_interface == -1) { + debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); + return -EINVAL; + } + + return 0; +} + +static const struct udevice_id designware_eth_ids[] = { + { .compatible = "allwinner,sun7i-a20-gmac" }, + { } +}; + +U_BOOT_DRIVER(eth_sandbox) = { + .name = "eth_designware", + .id = UCLASS_ETH, + .of_match = designware_eth_ids, + .ofdata_to_platdata = designware_eth_ofdata_to_platdata, + .probe = designware_eth_probe, + .ops = &designware_eth_ops, + .priv_auto_alloc_size = sizeof(struct dw_eth_dev), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif diff --git a/drivers/net/designware.h b/drivers/net/designware.h index 49d900c..4b9ec39 100644 --- a/drivers/net/designware.h +++ b/drivers/net/designware.h @@ -228,8 +228,9 @@ struct dw_eth_dev { struct eth_mac_regs *mac_regs_p; struct eth_dma_regs *dma_regs_p; - +#ifndef CONFIG_DM_ETH struct eth_device *dev; +#endif struct phy_device *phydev; struct mii_dev *bus; }; diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 4de9d41..ccd2131 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -342,10 +342,10 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd) DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS); printf("MAC: %pM\n", dev->enetaddr); - if (!is_valid_ether_addr(dev->enetaddr)) { + if (!is_valid_ethaddr(dev->enetaddr)) { #ifdef CONFIG_RANDOM_MACADDR printf("Bad MAC address (uninitialized EEPROM?), randomizing\n"); - eth_random_addr(dev->enetaddr); + net_random_ethaddr(dev->enetaddr); printf("MAC: %pM\n", dev->enetaddr); #else printf("WARNING: Bad MAC address (uninitialized EEPROM?)\n"); @@ -464,7 +464,8 @@ static void dm9000_halt(struct eth_device *netdev) */ static int dm9000_rx(struct eth_device *netdev) { - u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0]; + u8 rxbyte; + u8 *rdptr = (u8 *)net_rx_packets[0]; u16 RxStatus, RxLen = 0; struct board_info *db = &dm9000_info; @@ -525,7 +526,7 @@ static int dm9000_rx(struct eth_device *netdev) DM9000_DMP_PACKET(__func__ , rdptr, RxLen); DM9000_DBG("passing packet to upper layer\n"); - NetReceive(NetRxPackets[0], RxLen); + net_process_received_packet(net_rx_packets[0], RxLen); } } return 0; diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c index 944a0c0..933d1fc 100644 --- a/drivers/net/dnet.c +++ b/drivers/net/dnet.c @@ -188,12 +188,13 @@ static int dnet_recv(struct eth_device *netdev) if (cmd_word & 0xDF180000) printf("%s packet receive error %x\n", __func__, cmd_word); - data_ptr = (unsigned int *) NetRxPackets[0]; + data_ptr = (unsigned int *)net_rx_packets[0]; for (i = 0; i < (pkt_len + 3) >> 2; i++) *data_ptr++ = readl(&dnet->regs->RX_DATA_FIFO); - NetReceive(NetRxPackets[0], pkt_len + 5); /* ok + 5 ?? */ + /* ok + 5 ?? */ + net_process_received_packet(net_rx_packets[0], pkt_len + 5); return 0; } diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index cd44222..96e6bb0 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -1197,7 +1197,7 @@ e1000_read_mac_addr(struct eth_device *nic) nic->enetaddr[5] ^= 1; #ifdef CONFIG_E1000_FALLBACK_MAC - if (!is_valid_ether_addr(nic->enetaddr)) { + if (!is_valid_ethaddr(nic->enetaddr)) { unsigned char fb_mac[NODE_ADDRESS_SIZE] = CONFIG_E1000_FALLBACK_MAC; memcpy (nic->enetaddr, fb_mac, NODE_ADDRESS_SIZE); @@ -2174,7 +2174,7 @@ e1000_copper_link_preconfig(struct e1000_hw *hw) DEBUGOUT("Error, did not detect valid phy.\n"); return ret_val; } - DEBUGOUT("Phy ID = %x \n", hw->phy_id); + DEBUGOUT("Phy ID = %x\n", hw->phy_id); /* Set PHY to class A mode (if necessary) */ ret_val = e1000_set_phy_mode(hw); @@ -3485,11 +3485,11 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) * some "sticky" (latched) bits. */ if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { - DEBUGOUT("PHY Read Error \n"); + DEBUGOUT("PHY Read Error\n"); return -E1000_ERR_PHY; } if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { - DEBUGOUT("PHY Read Error \n"); + DEBUGOUT("PHY Read Error\n"); return -E1000_ERR_PHY; } @@ -5152,13 +5152,13 @@ e1000_poll(struct eth_device *nic) if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD) return 0; - /*DEBUGOUT("recv: packet len=%d \n", rd->length); */ + /* DEBUGOUT("recv: packet len=%d\n", rd->length); */ /* Packet received, make sure the data are re-loaded from RAM. */ len = le32_to_cpu(rd->length); invalidate_dcache_range((unsigned long)packet, (unsigned long)packet + roundup(len, ARCH_DMA_MINALIGN)); - NetReceive((uchar *)packet, len); + net_process_received_packet((uchar *)packet, len); fill_rx(hw); return 1; } diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index a23a585..f2cd32c 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -674,7 +674,8 @@ static int eepro100_recv (struct eth_device *dev) /* Pass the packet up to the protocol * layers. */ - NetReceive((u8 *)rx_ring[rx_next].data, length); + net_process_received_packet((u8 *)rx_ring[rx_next].data, + length); } else { /* There was an error. */ diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index ec33764..59ea11c 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -21,8 +21,8 @@ * enc_miiphy_read(), enc_miiphy_write(), enc_write_hwaddr(), * enc_init(), enc_recv(), enc_send(), enc_halt() * ALL other functions assume that the bus has already been claimed! - * Since NetReceive() might call enc_send() in return, the bus must be - * released, NetReceive() called and claimed again. + * Since net_process_received_packet() might call enc_send() in return, the bus + * must be released, net_process_received_packet() called and claimed again. */ /* @@ -415,7 +415,7 @@ static void enc_reset_rx_call(enc_dev_t *enc) */ static void enc_receive(enc_dev_t *enc) { - u8 *packet = (u8 *)NetRxPackets[0]; + u8 *packet = (u8 *)net_rx_packets[0]; u16 pkt_len; u16 copy_len; u16 status; @@ -468,11 +468,12 @@ static void enc_receive(enc_dev_t *enc) continue; } /* - * Because NetReceive() might call enc_send(), we need to - * release the SPI bus, call NetReceive(), reclaim the bus + * Because net_process_received_packet() might call enc_send(), + * we need to release the SPI bus, call + * net_process_received_packet(), reclaim the bus. */ enc_release_bus(enc); - NetReceive(packet, pkt_len); + net_process_received_packet(packet, pkt_len); if (enc_claim_bus(enc)) return; (void)enc_r8(enc, CTL_REG_EIR); diff --git a/drivers/net/ep93xx_eth.c b/drivers/net/ep93xx_eth.c index 1c09f10..a3721c5 100644 --- a/drivers/net/ep93xx_eth.c +++ b/drivers/net/ep93xx_eth.c @@ -53,7 +53,7 @@ static void dump_dev(struct eth_device *dev) printf(" rx_sq.end %p\n", priv->rx_sq.end); for (i = 0; i < NUMRXDESC; i++) - printf(" rx_buffer[%2.d] %p\n", i, NetRxPackets[i]); + printf(" rx_buffer[%2.d] %p\n", i, net_rx_packets[i]); printf(" tx_dq.base %p\n", priv->tx_dq.base); printf(" tx_dq.current %p\n", priv->tx_dq.current); @@ -237,7 +237,7 @@ static int ep93xx_eth_open(struct eth_device *dev, bd_t *bd) */ for (i = 0; i < NUMRXDESC; i++) { /* set buffer address */ - (priv->rx_dq.base + i)->word1 = (uint32_t)NetRxPackets[i]; + (priv->rx_dq.base + i)->word1 = (uint32_t)net_rx_packets[i]; /* set buffer length, clear buffer index and NSOF */ (priv->rx_dq.base + i)->word2 = PKTSIZE_ALIGN; @@ -310,15 +310,16 @@ static int ep93xx_eth_rcv_packet(struct eth_device *dev) /* * We have a good frame. Extract the frame's length * from the current rx_status_queue entry, and copy - * the frame's data into NetRxPackets[] of the + * the frame's data into net_rx_packets[] of the * protocol stack. We track the total number of * bytes in the frame (nbytes_frame) which will be * used when we pass the data off to the protocol - * layer via NetReceive(). + * layer via net_process_received_packet(). */ len = RX_STATUS_FRAME_LEN(priv->rx_sq.current); - NetReceive((uchar *)priv->rx_dq.current->word1, len); + net_process_received_packet( + (uchar *)priv->rx_dq.current->word1, len); debug("reporting %d bytes...\n", len); } else { diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 46c82bb..edb3c80 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -267,7 +267,7 @@ static int ethoc_init_ring(struct eth_device *dev) bd.stat = RX_BD_EMPTY | RX_BD_IRQ; for (i = 0; i < priv->num_rx; i++) { - bd.addr = (u32)NetRxPackets[i]; + bd.addr = (u32)net_rx_packets[i]; if (i == priv->num_rx - 1) bd.stat |= RX_BD_WRAP; @@ -372,7 +372,7 @@ static int ethoc_rx(struct eth_device *dev, int limit) if (ethoc_update_rx_stats(&bd) == 0) { int size = bd.stat >> 16; size -= 4; /* strip the CRC */ - NetReceive((void *)bd.addr, size); + net_process_received_packet((void *)bd.addr, size); } /* clear the buffer descriptor so it can be reused */ diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index b572470..9225d37 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -357,7 +357,7 @@ static int fec_get_hwaddr(struct eth_device *dev, int dev_id, unsigned char *mac) { imx_get_mac_from_fuse(dev_id, mac); - return !is_valid_ether_addr(mac); + return !is_valid_ethaddr(mac); } static int fec_set_hwaddr(struct eth_device *dev) @@ -852,7 +852,7 @@ static int fec_recv(struct eth_device *dev) swap_packet((uint32_t *)frame->data, frame_length); #endif memcpy(buff, frame->data, frame_length); - NetReceive(buff, frame_length); + net_process_received_packet(buff, frame_length); len = frame_length; } else { if (bd_status & FEC_RBD_ERR) diff --git a/drivers/net/fm/eth.c b/drivers/net/fm/eth.c index 1d1089d..d7a37f3 100644 --- a/drivers/net/fm/eth.c +++ b/drivers/net/fm/eth.c @@ -15,7 +15,7 @@ #include <phy.h> #include <asm/fsl_dtsec.h> #include <asm/fsl_tgec.h> -#include <asm/fsl_memac.h> +#include <fsl_memac.h> #include "fm.h" @@ -530,7 +530,7 @@ static int fm_eth_recv(struct eth_device *dev) if (!(status & RxBD_ERROR)) { data = (u8 *)rxbd->buf_ptr_lo; len = rxbd->len; - NetReceive(data, len); + net_process_received_packet(data, len); } else { printf("%s: Rx error\n", dev->name); return 0; diff --git a/drivers/net/fm/memac.c b/drivers/net/fm/memac.c index 60e898c..81a64bf 100644 --- a/drivers/net/fm/memac.c +++ b/drivers/net/fm/memac.c @@ -12,7 +12,7 @@ #include <phy.h> #include <asm/types.h> #include <asm/io.h> -#include <asm/fsl_memac.h> +#include <fsl_memac.h> #include "fm.h" diff --git a/drivers/net/fm/memac_phy.c b/drivers/net/fm/memac_phy.c index a155d89..4ab78e6 100644 --- a/drivers/net/fm/memac_phy.c +++ b/drivers/net/fm/memac_phy.c @@ -10,9 +10,28 @@ #include <miiphy.h> #include <phy.h> #include <asm/io.h> -#include <asm/fsl_memac.h> +#include <fsl_memac.h> #include <fm_eth.h> +#ifdef CONFIG_SYS_MEMAC_LITTLE_ENDIAN +#define memac_out_32(a, v) out_le32(a, v) +#define memac_clrbits_32(a, v) clrbits_le32(a, v) +#define memac_setbits_32(a, v) setbits_le32(a, v) +#else +#define memac_out_32(a, v) out_be32(a, v) +#define memac_clrbits_32(a, v) clrbits_be32(a, v) +#define memac_setbits_32(a, v) setbits_be32(a, v) +#endif + +static u32 memac_in_32(u32 *reg) +{ +#ifdef CONFIG_SYS_MEMAC_LITTLE_ENDIAN + return in_le32(reg); +#else + return in_be32(reg); +#endif +} + /* * Write value to the PHY for this device to the register at regnum, waiting * until the write is done before it returns. All PHY configuration has to be @@ -28,31 +47,31 @@ int memac_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr, if (dev_addr == MDIO_DEVAD_NONE) { c45 = 0; /* clause 22 */ dev_addr = regnum & 0x1f; - clrbits_be32(®s->mdio_stat, MDIO_STAT_ENC); + memac_clrbits_32(®s->mdio_stat, MDIO_STAT_ENC); } else - setbits_be32(®s->mdio_stat, MDIO_STAT_ENC); + memac_setbits_32(®s->mdio_stat, MDIO_STAT_ENC); /* Wait till the bus is free */ - while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) + while ((memac_in_32(®s->mdio_stat)) & MDIO_STAT_BSY) ; /* Set the port and dev addr */ mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr); - out_be32(®s->mdio_ctl, mdio_ctl); + memac_out_32(®s->mdio_ctl, mdio_ctl); /* Set the register address */ if (c45) - out_be32(®s->mdio_addr, regnum & 0xffff); + memac_out_32(®s->mdio_addr, regnum & 0xffff); /* Wait till the bus is free */ - while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) + while ((memac_in_32(®s->mdio_stat)) & MDIO_STAT_BSY) ; /* Write the value to the register */ - out_be32(®s->mdio_data, MDIO_DATA(value)); + memac_out_32(®s->mdio_data, MDIO_DATA(value)); /* Wait till the MDIO write is complete */ - while ((in_be32(®s->mdio_data)) & MDIO_DATA_BSY) + while ((memac_in_32(®s->mdio_data)) & MDIO_DATA_BSY) ; return 0; @@ -75,39 +94,39 @@ int memac_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr, return 0xffff; c45 = 0; /* clause 22 */ dev_addr = regnum & 0x1f; - clrbits_be32(®s->mdio_stat, MDIO_STAT_ENC); + memac_clrbits_32(®s->mdio_stat, MDIO_STAT_ENC); } else - setbits_be32(®s->mdio_stat, MDIO_STAT_ENC); + memac_setbits_32(®s->mdio_stat, MDIO_STAT_ENC); /* Wait till the bus is free */ - while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) + while ((memac_in_32(®s->mdio_stat)) & MDIO_STAT_BSY) ; /* Set the Port and Device Addrs */ mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr); - out_be32(®s->mdio_ctl, mdio_ctl); + memac_out_32(®s->mdio_ctl, mdio_ctl); /* Set the register address */ if (c45) - out_be32(®s->mdio_addr, regnum & 0xffff); + memac_out_32(®s->mdio_addr, regnum & 0xffff); /* Wait till the bus is free */ - while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) + while ((memac_in_32(®s->mdio_stat)) & MDIO_STAT_BSY) ; /* Initiate the read */ mdio_ctl |= MDIO_CTL_READ; - out_be32(®s->mdio_ctl, mdio_ctl); + memac_out_32(®s->mdio_ctl, mdio_ctl); /* Wait till the MDIO write is complete */ - while ((in_be32(®s->mdio_data)) & MDIO_DATA_BSY) + while ((memac_in_32(®s->mdio_data)) & MDIO_DATA_BSY) ; /* Return all Fs if nothing was there */ - if (in_be32(®s->mdio_stat) & MDIO_STAT_RD_ER) + if (memac_in_32(®s->mdio_stat) & MDIO_STAT_RD_ER) return 0xffff; - return in_be32(®s->mdio_data) & 0xffff; + return memac_in_32(®s->mdio_data) & 0xffff; } int memac_mdio_reset(struct mii_dev *bus) @@ -143,8 +162,9 @@ int fm_memac_mdio_init(bd_t *bis, struct memac_mdio_info *info) * like T2080QDS, this bit default is '0', which leads to MDIO failure * on XAUI PHY, so set this bit definitely. */ - setbits_be32(&((struct memac_mdio_controller *)info->regs)->mdio_stat, - MDIO_STAT_CLKDIV(258) | MDIO_STAT_NEG); + memac_setbits_32( + &((struct memac_mdio_controller *)info->regs)->mdio_stat, + MDIO_STAT_CLKDIV(258) | MDIO_STAT_NEG); return mdio_register(bus); } diff --git a/drivers/net/fsl-mc/Makefile b/drivers/net/fsl-mc/Makefile index 206ac6b..7563a5f 100644 --- a/drivers/net/fsl-mc/Makefile +++ b/drivers/net/fsl-mc/Makefile @@ -7,4 +7,8 @@ # Layerscape MC driver obj-y += mc.o \ mc_sys.o \ - dpmng.o + dpmng.o \ + dprc.o \ + dpbp.o \ + dpni.o +obj-y += dpio/ diff --git a/drivers/net/fsl-mc/dpbp.c b/drivers/net/fsl-mc/dpbp.c new file mode 100644 index 0000000..3853e58 --- /dev/null +++ b/drivers/net/fsl-mc/dpbp.c @@ -0,0 +1,102 @@ +/* + * Freescale Layerscape MC I/O wrapper + * + * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. + * Author: German Rivera <German.Rivera@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <fsl-mc/fsl_mc_sys.h> +#include <fsl-mc/fsl_mc_cmd.h> +#include <fsl-mc/fsl_dpbp.h> + +int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN, + MC_CMD_PRI_LOW, 0); + DPBP_CMD_OPEN(cmd, dpbp_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *token = MC_CMD_HDR_READ_TOKEN(cmd.header); + + return err; +} + +int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, MC_CMD_PRI_HIGH, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpbp_enable(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpbp_disable(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpbp_reset(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpbp_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpbp_attr *attr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_ATTR, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPBP_RSP_GET_ATTRIBUTES(cmd, attr); + + return 0; +} diff --git a/drivers/net/fsl-mc/dpio/Makefile b/drivers/net/fsl-mc/dpio/Makefile new file mode 100644 index 0000000..1ccefc0 --- /dev/null +++ b/drivers/net/fsl-mc/dpio/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2014 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +# Layerscape MC DPIO driver +obj-y += dpio.o \ + qbman_portal.o diff --git a/drivers/net/fsl-mc/dpio/dpio.c b/drivers/net/fsl-mc/dpio/dpio.c new file mode 100644 index 0000000..b07eff7 --- /dev/null +++ b/drivers/net/fsl-mc/dpio/dpio.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2013-2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <fsl-mc/fsl_mc_sys.h> +#include <fsl-mc/fsl_mc_cmd.h> +#include <fsl-mc/fsl_dpio.h> + +int dpio_open(struct fsl_mc_io *mc_io, int dpio_id, uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPIO_CMDID_OPEN, + MC_CMD_PRI_LOW, 0); + DPIO_CMD_OPEN(cmd, dpio_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *token = MC_CMD_HDR_READ_TOKEN(cmd.header); + + return 0; +} + +int dpio_close(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLOSE, + MC_CMD_PRI_HIGH, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpio_enable(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPIO_CMDID_ENABLE, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpio_disable(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPIO_CMDID_DISABLE, + MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpio_reset(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPIO_CMDID_RESET, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpio_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpio_attr *attr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_ATTR, + MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPIO_RSP_GET_ATTR(cmd, attr); + + return 0; +} diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.c b/drivers/net/fsl-mc/dpio/qbman_portal.c new file mode 100644 index 0000000..dd2a7de --- /dev/null +++ b/drivers/net/fsl-mc/dpio/qbman_portal.c @@ -0,0 +1,593 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "qbman_portal.h" + +/* QBMan portal management command codes */ +#define QBMAN_MC_ACQUIRE 0x30 +#define QBMAN_WQCHAN_CONFIGURE 0x46 + +/* CINH register offsets */ +#define QBMAN_CINH_SWP_EQAR 0x8c0 +#define QBMAN_CINH_SWP_DCAP 0xac0 +#define QBMAN_CINH_SWP_SDQCR 0xb00 +#define QBMAN_CINH_SWP_RAR 0xcc0 + +/* CENA register offsets */ +#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((uint32_t)(n) << 6)) +#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((uint32_t)(n) << 6)) +#define QBMAN_CENA_SWP_RCR(n) (0x400 + ((uint32_t)(n) << 6)) +#define QBMAN_CENA_SWP_CR 0x600 +#define QBMAN_CENA_SWP_RR(vb) (0x700 + ((uint32_t)(vb) >> 1)) +#define QBMAN_CENA_SWP_VDQCR 0x780 + +/* Reverse mapping of QBMAN_CENA_SWP_DQRR() */ +#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0xff) >> 6) + +/*******************************/ +/* Pre-defined attribute codes */ +/*******************************/ + +struct qb_attr_code code_generic_verb = QB_CODE(0, 0, 7); +struct qb_attr_code code_generic_rslt = QB_CODE(0, 8, 8); + +/*************************/ +/* SDQCR attribute codes */ +/*************************/ + +/* we put these here because at least some of them are required by + * qbman_swp_init() */ +struct qb_attr_code code_sdqcr_dct = QB_CODE(0, 24, 2); +struct qb_attr_code code_sdqcr_fc = QB_CODE(0, 29, 1); +struct qb_attr_code code_sdqcr_tok = QB_CODE(0, 16, 8); +#define CODE_SDQCR_DQSRC(n) QB_CODE(0, n, 1) +enum qbman_sdqcr_dct { + qbman_sdqcr_dct_null = 0, + qbman_sdqcr_dct_prio_ics, + qbman_sdqcr_dct_active_ics, + qbman_sdqcr_dct_active +}; +enum qbman_sdqcr_fc { + qbman_sdqcr_fc_one = 0, + qbman_sdqcr_fc_up_to_3 = 1 +}; + +/*********************************/ +/* Portal constructor/destructor */ +/*********************************/ + +/* Software portals should always be in the power-on state when we initialise, + * due to the CCSR-based portal reset functionality that MC has. */ +struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) +{ + int ret; + struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL); + + if (!p) + return NULL; + p->desc = d; +#ifdef QBMAN_CHECKING + p->mc.check = swp_mc_can_start; +#endif + p->mc.valid_bit = QB_VALID_BIT; + p->sdq = 0; + qb_attr_code_encode(&code_sdqcr_dct, &p->sdq, qbman_sdqcr_dct_prio_ics); + qb_attr_code_encode(&code_sdqcr_fc, &p->sdq, qbman_sdqcr_fc_up_to_3); + qb_attr_code_encode(&code_sdqcr_tok, &p->sdq, 0xbb); + p->vdq.busy = 0; /* TODO: convert to atomic_t */ + p->vdq.valid_bit = QB_VALID_BIT; + p->dqrr.next_idx = 0; + p->dqrr.valid_bit = QB_VALID_BIT; + ret = qbman_swp_sys_init(&p->sys, d); + if (ret) { + free(p); + printf("qbman_swp_sys_init() failed %d\n", ret); + return NULL; + } + qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, p->sdq); + return p; +} + +/***********************/ +/* Management commands */ +/***********************/ + +/* + * Internal code common to all types of management commands. + */ + +void *qbman_swp_mc_start(struct qbman_swp *p) +{ + void *ret; +#ifdef QBMAN_CHECKING + BUG_ON(p->mc.check != swp_mc_can_start); +#endif + ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR); +#ifdef QBMAN_CHECKING + if (!ret) + p->mc.check = swp_mc_can_submit; +#endif + return ret; +} + +void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb) +{ + uint32_t *v = cmd; +#ifdef QBMAN_CHECKING + BUG_ON(!p->mc.check != swp_mc_can_submit); +#endif + lwsync(); + /* TBD: "|=" is going to hurt performance. Need to move as many fields + * out of word zero, and for those that remain, the "OR" needs to occur + * at the caller side. This debug check helps to catch cases where the + * caller wants to OR but has forgotten to do so. */ + BUG_ON((*v & cmd_verb) != *v); + *v = cmd_verb | p->mc.valid_bit; + qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd); + /* TODO: add prefetch support for GPP */ +#ifdef QBMAN_CHECKING + p->mc.check = swp_mc_can_poll; +#endif +} + +void *qbman_swp_mc_result(struct qbman_swp *p) +{ + uint32_t *ret, verb; +#ifdef QBMAN_CHECKING + BUG_ON(p->mc.check != swp_mc_can_poll); +#endif + ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR(p->mc.valid_bit)); + /* Remove the valid-bit - command completed iff the rest is non-zero */ + verb = ret[0] & ~QB_VALID_BIT; + if (!verb) + return NULL; +#ifdef QBMAN_CHECKING + p->mc.check = swp_mc_can_start; +#endif + p->mc.valid_bit ^= QB_VALID_BIT; + return ret; +} + +/***********/ +/* Enqueue */ +/***********/ + +/* These should be const, eventually */ +static struct qb_attr_code code_eq_cmd = QB_CODE(0, 0, 2); +static struct qb_attr_code code_eq_orp_en = QB_CODE(0, 2, 1); +static struct qb_attr_code code_eq_tgt_id = QB_CODE(2, 0, 24); +/* static struct qb_attr_code code_eq_tag = QB_CODE(3, 0, 32); */ +static struct qb_attr_code code_eq_qd_en = QB_CODE(0, 4, 1); +static struct qb_attr_code code_eq_qd_bin = QB_CODE(4, 0, 16); +static struct qb_attr_code code_eq_qd_pri = QB_CODE(4, 16, 4); +static struct qb_attr_code code_eq_rsp_stash = QB_CODE(5, 16, 1); +static struct qb_attr_code code_eq_rsp_lo = QB_CODE(6, 0, 32); +static struct qb_attr_code code_eq_rsp_hi = QB_CODE(7, 0, 32); + +enum qbman_eq_cmd_e { + /* No enqueue, primarily for plugging ORP gaps for dropped frames */ + qbman_eq_cmd_empty, + /* DMA an enqueue response once complete */ + qbman_eq_cmd_respond, + /* DMA an enqueue response only if the enqueue fails */ + qbman_eq_cmd_respond_reject +}; + +void qbman_eq_desc_clear(struct qbman_eq_desc *d) +{ + memset(d, 0, sizeof(*d)); +} + +void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success) +{ + uint32_t *cl = qb_cl(d); + + qb_attr_code_encode(&code_eq_orp_en, cl, 0); + qb_attr_code_encode(&code_eq_cmd, cl, + respond_success ? qbman_eq_cmd_respond : + qbman_eq_cmd_respond_reject); +} + +void qbman_eq_desc_set_response(struct qbman_eq_desc *d, + dma_addr_t storage_phys, + int stash) +{ + uint32_t *cl = qb_cl(d); + + qb_attr_code_encode(&code_eq_rsp_lo, cl, lower32(storage_phys)); + qb_attr_code_encode(&code_eq_rsp_hi, cl, upper32(storage_phys)); + qb_attr_code_encode(&code_eq_rsp_stash, cl, !!stash); +} + + +void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid, + uint32_t qd_bin, uint32_t qd_prio) +{ + uint32_t *cl = qb_cl(d); + + qb_attr_code_encode(&code_eq_qd_en, cl, 1); + qb_attr_code_encode(&code_eq_tgt_id, cl, qdid); + qb_attr_code_encode(&code_eq_qd_bin, cl, qd_bin); + qb_attr_code_encode(&code_eq_qd_pri, cl, qd_prio); +} + +#define EQAR_IDX(eqar) ((eqar) & 0x7) +#define EQAR_VB(eqar) ((eqar) & 0x80) +#define EQAR_SUCCESS(eqar) ((eqar) & 0x100) + +int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d, + const struct qbman_fd *fd) +{ + uint32_t *p; + const uint32_t *cl = qb_cl(d); + uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR); + debug("EQAR=%08x\n", eqar); + if (!EQAR_SUCCESS(eqar)) + return -EBUSY; + p = qbman_cena_write_start(&s->sys, + QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar))); + word_copy(&p[1], &cl[1], 7); + word_copy(&p[8], fd, sizeof(*fd) >> 2); + lwsync(); + /* Set the verb byte, have to substitute in the valid-bit */ + p[0] = cl[0] | EQAR_VB(eqar); + qbman_cena_write_complete(&s->sys, + QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)), + p); + return 0; +} + +/***************************/ +/* Volatile (pull) dequeue */ +/***************************/ + +/* These should be const, eventually */ +static struct qb_attr_code code_pull_dct = QB_CODE(0, 0, 2); +static struct qb_attr_code code_pull_dt = QB_CODE(0, 2, 2); +static struct qb_attr_code code_pull_rls = QB_CODE(0, 4, 1); +static struct qb_attr_code code_pull_stash = QB_CODE(0, 5, 1); +static struct qb_attr_code code_pull_numframes = QB_CODE(0, 8, 4); +static struct qb_attr_code code_pull_token = QB_CODE(0, 16, 8); +static struct qb_attr_code code_pull_dqsource = QB_CODE(1, 0, 24); +static struct qb_attr_code code_pull_rsp_lo = QB_CODE(2, 0, 32); +static struct qb_attr_code code_pull_rsp_hi = QB_CODE(3, 0, 32); + +enum qb_pull_dt_e { + qb_pull_dt_channel, + qb_pull_dt_workqueue, + qb_pull_dt_framequeue +}; + +void qbman_pull_desc_clear(struct qbman_pull_desc *d) +{ + memset(d, 0, sizeof(*d)); +} + +void qbman_pull_desc_set_storage(struct qbman_pull_desc *d, + struct ldpaa_dq *storage, + dma_addr_t storage_phys, + int stash) +{ + uint32_t *cl = qb_cl(d); + + /* Squiggle the pointer 'storage' into the extra 2 words of the + * descriptor (which aren't copied to the hw command) */ + *(void **)&cl[4] = storage; + if (!storage) { + qb_attr_code_encode(&code_pull_rls, cl, 0); + return; + } + qb_attr_code_encode(&code_pull_rls, cl, 1); + qb_attr_code_encode(&code_pull_stash, cl, !!stash); + qb_attr_code_encode(&code_pull_rsp_lo, cl, lower32(storage_phys)); + qb_attr_code_encode(&code_pull_rsp_hi, cl, upper32(storage_phys)); +} + +void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes) +{ + uint32_t *cl = qb_cl(d); + + BUG_ON(!numframes || (numframes > 16)); + qb_attr_code_encode(&code_pull_numframes, cl, + (uint32_t)(numframes - 1)); +} + +void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token) +{ + uint32_t *cl = qb_cl(d); + + qb_attr_code_encode(&code_pull_token, cl, token); +} + +void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid) +{ + uint32_t *cl = qb_cl(d); + + qb_attr_code_encode(&code_pull_dct, cl, 1); + qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_framequeue); + qb_attr_code_encode(&code_pull_dqsource, cl, fqid); +} + +int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d) +{ + uint32_t *p; + uint32_t *cl = qb_cl(d); + + /* TODO: convert to atomic_t */ + if (s->vdq.busy) + return -EBUSY; + s->vdq.busy = 1; + s->vdq.storage = *(void **)&cl[4]; + s->vdq.token = qb_attr_code_decode(&code_pull_token, cl); + p = qbman_cena_write_start(&s->sys, QBMAN_CENA_SWP_VDQCR); + word_copy(&p[1], &cl[1], 3); + lwsync(); + /* Set the verb byte, have to substitute in the valid-bit */ + p[0] = cl[0] | s->vdq.valid_bit; + s->vdq.valid_bit ^= QB_VALID_BIT; + qbman_cena_write_complete(&s->sys, QBMAN_CENA_SWP_VDQCR, p); + return 0; +} + +/****************/ +/* Polling DQRR */ +/****************/ + +static struct qb_attr_code code_dqrr_verb = QB_CODE(0, 0, 8); +static struct qb_attr_code code_dqrr_response = QB_CODE(0, 0, 7); +static struct qb_attr_code code_dqrr_stat = QB_CODE(0, 8, 8); + +#define QBMAN_DQRR_RESPONSE_DQ 0x60 +#define QBMAN_DQRR_RESPONSE_FQRN 0x21 +#define QBMAN_DQRR_RESPONSE_FQRNI 0x22 +#define QBMAN_DQRR_RESPONSE_FQPN 0x24 +#define QBMAN_DQRR_RESPONSE_FQDAN 0x25 +#define QBMAN_DQRR_RESPONSE_CDAN 0x26 +#define QBMAN_DQRR_RESPONSE_CSCN_MEM 0x27 +#define QBMAN_DQRR_RESPONSE_CGCU 0x28 +#define QBMAN_DQRR_RESPONSE_BPSCN 0x29 +#define QBMAN_DQRR_RESPONSE_CSCN_WQ 0x2a + + +/* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry + * only once, so repeated calls can return a sequence of DQRR entries, without + * requiring they be consumed immediately or in any particular order. */ +const struct ldpaa_dq *qbman_swp_dqrr_next(struct qbman_swp *s) +{ + uint32_t verb; + uint32_t response_verb; + const struct ldpaa_dq *dq = qbman_cena_read(&s->sys, + QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); + const uint32_t *p = qb_cl(dq); + + verb = qb_attr_code_decode(&code_dqrr_verb, p); + /* If the valid-bit isn't of the expected polarity, nothing there */ + if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) { + qbman_cena_invalidate_prefetch(&s->sys, + QBMAN_CENA_SWP_DQRR( + s->dqrr.next_idx)); + return NULL; + } + /* There's something there. Move "next_idx" attention to the next ring + * entry (and prefetch it) before returning what we found. */ + s->dqrr.next_idx++; + s->dqrr.next_idx &= 3; /* Wrap around at 4 */ + /* TODO: it's possible to do all this without conditionals, optimise it + * later. */ + if (!s->dqrr.next_idx) + s->dqrr.valid_bit ^= QB_VALID_BIT; + /* VDQCR "no longer busy" hook - if VDQCR shows "busy" and this is a + * VDQCR result, mark it as non-busy. */ + if (s->vdq.busy) { + uint32_t flags = ldpaa_dq_flags(dq); + + response_verb = qb_attr_code_decode(&code_dqrr_response, &verb); + if ((response_verb == QBMAN_DQRR_RESPONSE_DQ) && + (flags & LDPAA_DQ_STAT_VOLATILE)) + s->vdq.busy = 0; + } + qbman_cena_invalidate_prefetch(&s->sys, + QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); + return dq; +} + +/* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */ +void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct ldpaa_dq *dq) +{ + qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq)); +} + +/*********************************/ +/* Polling user-provided storage */ +/*********************************/ + +void qbman_dq_entry_set_oldtoken(struct ldpaa_dq *dq, + unsigned int num_entries, + uint8_t oldtoken) +{ + memset(dq, oldtoken, num_entries * sizeof(*dq)); +} + +int qbman_dq_entry_has_newtoken(struct qbman_swp *s, + const struct ldpaa_dq *dq, + uint8_t newtoken) +{ + /* To avoid converting the little-endian DQ entry to host-endian prior + * to us knowing whether there is a valid entry or not (and run the + * risk of corrupting the incoming hardware LE write), we detect in + * hardware endianness rather than host. This means we need a different + * "code" depending on whether we are BE or LE in software, which is + * where DQRR_TOK_OFFSET comes in... */ + static struct qb_attr_code code_dqrr_tok_detect = + QB_CODE(0, DQRR_TOK_OFFSET, 8); + /* The user trying to poll for a result treats "dq" as const. It is + * however the same address that was provided to us non-const in the + * first place, for directing hardware DMA to. So we can cast away the + * const because it is mutable from our perspective. */ + uint32_t *p = qb_cl((struct ldpaa_dq *)dq); + uint32_t token; + + token = qb_attr_code_decode(&code_dqrr_tok_detect, &p[1]); + if (token != newtoken) + return 0; + + /* Only now do we convert from hardware to host endianness. Also, as we + * are returning success, the user has promised not to call us again, so + * there's no risk of us converting the endianness twice... */ + make_le32_n(p, 16); + + /* VDQCR "no longer busy" hook - not quite the same as DQRR, because the + * fact "VDQCR" shows busy doesn't mean that the result we're looking at + * is from the same command. Eg. we may be looking at our 10th dequeue + * result from our first VDQCR command, yet the second dequeue command + * could have been kicked off already, after seeing the 1st result. Ie. + * the result we're looking at is not necessarily proof that we can + * reset "busy". We instead base the decision on whether the current + * result is sitting at the first 'storage' location of the busy + * command. */ + if (s->vdq.busy && (s->vdq.storage == dq)) + s->vdq.busy = 0; + return 1; +} + +/********************************/ +/* Categorising dequeue entries */ +/********************************/ + +static inline int __qbman_dq_entry_is_x(const struct ldpaa_dq *dq, uint32_t x) +{ + const uint32_t *p = qb_cl(dq); + uint32_t response_verb = qb_attr_code_decode(&code_dqrr_response, p); + + return response_verb == x; +} + +int qbman_dq_entry_is_DQ(const struct ldpaa_dq *dq) +{ + return __qbman_dq_entry_is_x(dq, QBMAN_DQRR_RESPONSE_DQ); +} + +/*********************************/ +/* Parsing frame dequeue results */ +/*********************************/ + +/* These APIs assume qbman_dq_entry_is_DQ() is TRUE */ + +uint32_t ldpaa_dq_flags(const struct ldpaa_dq *dq) +{ + const uint32_t *p = qb_cl(dq); + + return qb_attr_code_decode(&code_dqrr_stat, p); +} + +const struct dpaa_fd *ldpaa_dq_fd(const struct ldpaa_dq *dq) +{ + const uint32_t *p = qb_cl(dq); + + return (const struct dpaa_fd *)&p[8]; +} + +/******************/ +/* Buffer release */ +/******************/ + +/* These should be const, eventually */ +/* static struct qb_attr_code code_release_num = QB_CODE(0, 0, 3); */ +static struct qb_attr_code code_release_set_me = QB_CODE(0, 5, 1); +static struct qb_attr_code code_release_bpid = QB_CODE(0, 16, 16); + +void qbman_release_desc_clear(struct qbman_release_desc *d) +{ + uint32_t *cl; + + memset(d, 0, sizeof(*d)); + cl = qb_cl(d); + qb_attr_code_encode(&code_release_set_me, cl, 1); +} + +void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint32_t bpid) +{ + uint32_t *cl = qb_cl(d); + + qb_attr_code_encode(&code_release_bpid, cl, bpid); +} + +#define RAR_IDX(rar) ((rar) & 0x7) +#define RAR_VB(rar) ((rar) & 0x80) +#define RAR_SUCCESS(rar) ((rar) & 0x100) + +int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d, + const uint64_t *buffers, unsigned int num_buffers) +{ + uint32_t *p; + const uint32_t *cl = qb_cl(d); + uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR); + debug("RAR=%08x\n", rar); + if (!RAR_SUCCESS(rar)) + return -EBUSY; + BUG_ON(!num_buffers || (num_buffers > 7)); + /* Start the release command */ + p = qbman_cena_write_start(&s->sys, + QBMAN_CENA_SWP_RCR(RAR_IDX(rar))); + /* Copy the caller's buffer pointers to the command */ + u64_to_le32_copy(&p[2], buffers, num_buffers); + lwsync(); + /* Set the verb byte, have to substitute in the valid-bit and the number + * of buffers. */ + p[0] = cl[0] | RAR_VB(rar) | num_buffers; + qbman_cena_write_complete(&s->sys, + QBMAN_CENA_SWP_RCR(RAR_IDX(rar)), + p); + return 0; +} + +/*******************/ +/* Buffer acquires */ +/*******************/ + +/* These should be const, eventually */ +static struct qb_attr_code code_acquire_bpid = QB_CODE(0, 16, 16); +static struct qb_attr_code code_acquire_num = QB_CODE(1, 0, 3); +static struct qb_attr_code code_acquire_r_num = QB_CODE(1, 0, 3); + +int qbman_swp_acquire(struct qbman_swp *s, uint32_t bpid, uint64_t *buffers, + unsigned int num_buffers) +{ + uint32_t *p; + uint32_t verb, rslt, num; + + BUG_ON(!num_buffers || (num_buffers > 7)); + + /* Start the management command */ + p = qbman_swp_mc_start(s); + + if (!p) + return -EBUSY; + + /* Encode the caller-provided attributes */ + qb_attr_code_encode(&code_acquire_bpid, p, bpid); + qb_attr_code_encode(&code_acquire_num, p, num_buffers); + + /* Complete the management command */ + p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_MC_ACQUIRE); + + /* Decode the outcome */ + verb = qb_attr_code_decode(&code_generic_verb, p); + rslt = qb_attr_code_decode(&code_generic_rslt, p); + num = qb_attr_code_decode(&code_acquire_r_num, p); + BUG_ON(verb != QBMAN_MC_ACQUIRE); + + /* Determine success or failure */ + if (unlikely(rslt != QBMAN_MC_RSLT_OK)) { + printf("Acquire buffers from BPID 0x%x failed, code=0x%02x\n", + bpid, rslt); + return -EIO; + } + BUG_ON(num > num_buffers); + /* Copy the acquired buffers to the caller's array */ + u64_from_le32_copy(buffers, &p[2], num); + return (int)num; +} diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.h b/drivers/net/fsl-mc/dpio/qbman_portal.h new file mode 100644 index 0000000..bb67c3b --- /dev/null +++ b/drivers/net/fsl-mc/dpio/qbman_portal.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "qbman_private.h" +#include <fsl-mc/fsl_qbman_portal.h> +#include <fsl-mc/fsl_dpaa_fd.h> + +/* All QBMan command and result structures use this "valid bit" encoding */ +#define QB_VALID_BIT ((uint32_t)0x80) + +/* Management command result codes */ +#define QBMAN_MC_RSLT_OK 0xf0 + +/* --------------------- */ +/* portal data structure */ +/* --------------------- */ + +struct qbman_swp { + const struct qbman_swp_desc *desc; + /* The qbman_sys (ie. arch/OS-specific) support code can put anything it + * needs in here. */ + struct qbman_swp_sys sys; + /* Management commands */ + struct { +#ifdef QBMAN_CHECKING + enum swp_mc_check { + swp_mc_can_start, /* call __qbman_swp_mc_start() */ + swp_mc_can_submit, /* call __qbman_swp_mc_submit() */ + swp_mc_can_poll, /* call __qbman_swp_mc_result() */ + } check; +#endif + uint32_t valid_bit; /* 0x00 or 0x80 */ + } mc; + /* Push dequeues */ + uint32_t sdq; + /* Volatile dequeues */ + struct { + /* VDQCR supports a "1 deep pipeline", meaning that if you know + * the last-submitted command is already executing in the + * hardware (as evidenced by at least 1 valid dequeue result), + * you can write another dequeue command to the register, the + * hardware will start executing it as soon as the + * already-executing command terminates. (This minimises latency + * and stalls.) With that in mind, this "busy" variable refers + * to whether or not a command can be submitted, not whether or + * not a previously-submitted command is still executing. In + * other words, once proof is seen that the previously-submitted + * command is executing, "vdq" is no longer "busy". TODO: + * convert this to "atomic_t" so that it is thread-safe (without + * locking). */ + int busy; + uint32_t valid_bit; /* 0x00 or 0x80 */ + /* We need to determine when vdq is no longer busy. This depends + * on whether the "busy" (last-submitted) dequeue command is + * targetting DQRR or main-memory, and detected is based on the + * presence of the dequeue command's "token" showing up in + * dequeue entries in DQRR or main-memory (respectively). Debug + * builds will, when submitting vdq commands, verify that the + * dequeue result location is not already equal to the command's + * token value. */ + struct ldpaa_dq *storage; /* NULL if DQRR */ + uint32_t token; + } vdq; + /* DQRR */ + struct { + uint32_t next_idx; + uint32_t valid_bit; + } dqrr; +}; + +/* -------------------------- */ +/* portal management commands */ +/* -------------------------- */ + +/* Different management commands all use this common base layer of code to issue + * commands and poll for results. The first function returns a pointer to where + * the caller should fill in their MC command (though they should ignore the + * verb byte), the second function commits merges in the caller-supplied command + * verb (which should not include the valid-bit) and submits the command to + * hardware, and the third function checks for a completed response (returns + * non-NULL if only if the response is complete). */ +void *qbman_swp_mc_start(struct qbman_swp *p); +void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb); +void *qbman_swp_mc_result(struct qbman_swp *p); + +/* Wraps up submit + poll-for-result */ +static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd, + uint32_t cmd_verb) +{ + int loopvar; + + qbman_swp_mc_submit(swp, cmd, cmd_verb); + DBG_POLL_START(loopvar); + do { + DBG_POLL_CHECK(loopvar); + cmd = qbman_swp_mc_result(swp); + } while (!cmd); + return cmd; +} + +/* ------------ */ +/* qb_attr_code */ +/* ------------ */ + +/* This struct locates a sub-field within a QBMan portal (CENA) cacheline which + * is either serving as a configuration command or a query result. The + * representation is inherently little-endian, as the indexing of the words is + * itself little-endian in nature and layerscape is little endian for anything + * that crosses a word boundary too (64-bit fields are the obvious examples). + */ +struct qb_attr_code { + unsigned int word; /* which uint32_t[] array member encodes the field */ + unsigned int lsoffset; /* encoding offset from ls-bit */ + unsigned int width; /* encoding width. (bool must be 1.) */ +}; + +/* Macros to define codes */ +#define QB_CODE(a, b, c) { a, b, c} + +/* decode a field from a cacheline */ +static inline uint32_t qb_attr_code_decode(const struct qb_attr_code *code, + const uint32_t *cacheline) +{ + return d32_uint32_t(code->lsoffset, code->width, cacheline[code->word]); +} + +/* encode a field to a cacheline */ +static inline void qb_attr_code_encode(const struct qb_attr_code *code, + uint32_t *cacheline, uint32_t val) +{ + cacheline[code->word] = + r32_uint32_t(code->lsoffset, code->width, cacheline[code->word]) + | e32_uint32_t(code->lsoffset, code->width, val); +} + +/* ---------------------- */ +/* Descriptors/cachelines */ +/* ---------------------- */ + +/* To avoid needless dynamic allocation, the driver API often gives the caller + * a "descriptor" type that the caller can instantiate however they like. + * Ultimately though, it is just a cacheline of binary storage (or something + * smaller when it is known that the descriptor doesn't need all 64 bytes) for + * holding pre-formatted pieces of harware commands. The performance-critical + * code can then copy these descriptors directly into hardware command + * registers more efficiently than trying to construct/format commands + * on-the-fly. The API user sees the descriptor as an array of 32-bit words in + * order for the compiler to know its size, but the internal details are not + * exposed. The following macro is used within the driver for converting *any* + * descriptor pointer to a usable array pointer. The use of a macro (instead of + * an inline) is necessary to work with different descriptor types and to work + * correctly with const and non-const inputs (and similarly-qualified outputs). + */ +#define qb_cl(d) (&(d)->dont_manipulate_directly[0]) diff --git a/drivers/net/fsl-mc/dpio/qbman_private.h b/drivers/net/fsl-mc/dpio/qbman_private.h new file mode 100644 index 0000000..2d2556b --- /dev/null +++ b/drivers/net/fsl-mc/dpio/qbman_private.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* Perform extra checking */ +#include <common.h> +#include <errno.h> +#include <asm/io.h> +#include <linux/types.h> +#include <linux/compat.h> +#include <malloc.h> +#include <fsl-mc/fsl_qbman_base.h> + +#define QBMAN_CHECKING + +/* Any time there is a register interface which we poll on, this provides a + * "break after x iterations" scheme for it. It's handy for debugging, eg. + * where you don't want millions of lines of log output from a polling loop + * that won't, because such things tend to drown out the earlier log output + * that might explain what caused the problem. (NB: put ";" after each macro!) + * TODO: we should probably remove this once we're done sanitising the + * simulator... + */ +#define DBG_POLL_START(loopvar) (loopvar = 10) +#define DBG_POLL_CHECK(loopvar) \ + do {if (!(loopvar--)) BUG_ON(NULL == "DBG_POLL_CHECK"); } while (0) + +/* For CCSR or portal-CINH registers that contain fields at arbitrary offsets + * and widths, these macro-generated encode/decode/isolate/remove inlines can + * be used. + * + * Eg. to "d"ecode a 14-bit field out of a register (into a "uint16_t" type), + * where the field is located 3 bits "up" from the least-significant bit of the + * register (ie. the field location within the 32-bit register corresponds to a + * mask of 0x0001fff8), you would do; + * uint16_t field = d32_uint16_t(3, 14, reg_value); + * + * Or to "e"ncode a 1-bit boolean value (input type is "int", zero is FALSE, + * non-zero is TRUE, so must convert all non-zero inputs to 1, hence the "!!" + * operator) into a register at bit location 0x00080000 (19 bits "in" from the + * LS bit), do; + * reg_value |= e32_int(19, 1, !!field); + * + * If you wish to read-modify-write a register, such that you leave the 14-bit + * field as-is but have all other fields set to zero, then "i"solate the 14-bit + * value using; + * reg_value = i32_uint16_t(3, 14, reg_value); + * + * Alternatively, you could "r"emove the 1-bit boolean field (setting it to + * zero) but leaving all other fields as-is; + * reg_val = r32_int(19, 1, reg_value); + * + */ +#define MAKE_MASK32(width) (width == 32 ? 0xffffffff : \ + (uint32_t)((1 << width) - 1)) +#define DECLARE_CODEC32(t) \ +static inline uint32_t e32_##t(uint32_t lsoffset, uint32_t width, t val) \ +{ \ + BUG_ON(width > (sizeof(t) * 8)); \ + return ((uint32_t)val & MAKE_MASK32(width)) << lsoffset; \ +} \ +static inline t d32_##t(uint32_t lsoffset, uint32_t width, uint32_t val) \ +{ \ + BUG_ON(width > (sizeof(t) * 8)); \ + return (t)((val >> lsoffset) & MAKE_MASK32(width)); \ +} \ +static inline uint32_t i32_##t(uint32_t lsoffset, uint32_t width, \ + uint32_t val) \ +{ \ + BUG_ON(width > (sizeof(t) * 8)); \ + return e32_##t(lsoffset, width, d32_##t(lsoffset, width, val)); \ +} \ +static inline uint32_t r32_##t(uint32_t lsoffset, uint32_t width, \ + uint32_t val) \ +{ \ + BUG_ON(width > (sizeof(t) * 8)); \ + return ~(MAKE_MASK32(width) << lsoffset) & val; \ +} +DECLARE_CODEC32(uint32_t) +DECLARE_CODEC32(uint16_t) +DECLARE_CODEC32(uint8_t) +DECLARE_CODEC32(int) + + /*********************/ + /* Debugging assists */ + /*********************/ + +static inline void __hexdump(unsigned long start, unsigned long end, + unsigned long p, size_t sz, const unsigned char *c) +{ + while (start < end) { + unsigned int pos = 0; + char buf[64]; + int nl = 0; + + pos += sprintf(buf + pos, "%08lx: ", start); + do { + if ((start < p) || (start >= (p + sz))) + pos += sprintf(buf + pos, ".."); + else + pos += sprintf(buf + pos, "%02x", *(c++)); + if (!(++start & 15)) { + buf[pos++] = '\n'; + nl = 1; + } else { + nl = 0; + if (!(start & 1)) + buf[pos++] = ' '; + if (!(start & 3)) + buf[pos++] = ' '; + } + } while (start & 15); + if (!nl) + buf[pos++] = '\n'; + buf[pos] = '\0'; + debug("%s", buf); + } +} +static inline void hexdump(const void *ptr, size_t sz) +{ + unsigned long p = (unsigned long)ptr; + unsigned long start = p & ~(unsigned long)15; + unsigned long end = (p + sz + 15) & ~(unsigned long)15; + const unsigned char *c = ptr; + + __hexdump(start, end, p, sz, c); +} + +#if defined(__BIG_ENDIAN) +#define DQRR_TOK_OFFSET 0 +#else +#define DQRR_TOK_OFFSET 24 +#endif + +/* Similarly-named functions */ +#define upper32(a) upper_32_bits(a) +#define lower32(a) lower_32_bits(a) + + /****************/ + /* arch assists */ + /****************/ + +static inline void dcbz(void *ptr) +{ + uint32_t *p = ptr; + BUG_ON((unsigned long)ptr & 63); + p[0] = 0; + p[1] = 0; + p[2] = 0; + p[3] = 0; + p[4] = 0; + p[5] = 0; + p[6] = 0; + p[7] = 0; + p[8] = 0; + p[9] = 0; + p[10] = 0; + p[11] = 0; + p[12] = 0; + p[13] = 0; + p[14] = 0; + p[15] = 0; +} + +#define lwsync() + +#include "qbman_sys.h" diff --git a/drivers/net/fsl-mc/dpio/qbman_sys.h b/drivers/net/fsl-mc/dpio/qbman_sys.h new file mode 100644 index 0000000..235d641 --- /dev/null +++ b/drivers/net/fsl-mc/dpio/qbman_sys.h @@ -0,0 +1,290 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* qbman_sys_decl.h and qbman_sys.h are the two platform-specific files in the + * driver. They are only included via qbman_private.h, which is itself a + * platform-independent file and is included by all the other driver source. + * + * qbman_sys_decl.h is included prior to all other declarations and logic, and + * it exists to provide compatibility with any linux interfaces our + * single-source driver code is dependent on (eg. kmalloc). Ie. this file + * provides linux compatibility. + * + * This qbman_sys.h header, on the other hand, is included *after* any common + * and platform-neutral declarations and logic in qbman_private.h, and exists to + * implement any platform-specific logic of the qbman driver itself. Ie. it is + * *not* to provide linux compatibility. + */ + +/* Trace the 3 different classes of read/write access to QBMan. #undef as + * required. */ +#undef QBMAN_CCSR_TRACE +#undef QBMAN_CINH_TRACE +#undef QBMAN_CENA_TRACE + +/* Temporarily define this to get around the fact that cache enabled mapping is + * not working right now. Will remove this after uboot could map the cache + * enabled portal memory. + */ +#define QBMAN_CINH_ONLY + +static inline void word_copy(void *d, const void *s, unsigned int cnt) +{ + uint32_t *dd = d; + const uint32_t *ss = s; + + while (cnt--) + *(dd++) = *(ss++); +} + +/* Currently, the CENA support code expects each 32-bit word to be written in + * host order, and these are converted to hardware (little-endian) order on + * command submission. However, 64-bit quantities are must be written (and read) + * as two 32-bit words with the least-significant word first, irrespective of + * host endianness. */ +static inline void u64_to_le32_copy(void *d, const uint64_t *s, + unsigned int cnt) +{ + uint32_t *dd = d; + const uint32_t *ss = (const uint32_t *)s; + + while (cnt--) { + /* TBD: the toolchain was choking on the use of 64-bit types up + * until recently so this works entirely with 32-bit variables. + * When 64-bit types become usable again, investigate better + * ways of doing this. */ +#if defined(__BIG_ENDIAN) + *(dd++) = ss[1]; + *(dd++) = ss[0]; + ss += 2; +#else + *(dd++) = *(ss++); + *(dd++) = *(ss++); +#endif + } +} +static inline void u64_from_le32_copy(uint64_t *d, const void *s, + unsigned int cnt) +{ + const uint32_t *ss = s; + uint32_t *dd = (uint32_t *)d; + + while (cnt--) { +#if defined(__BIG_ENDIAN) + dd[1] = *(ss++); + dd[0] = *(ss++); + dd += 2; +#else + *(dd++) = *(ss++); + *(dd++) = *(ss++); +#endif + } +} + +/* Convert a host-native 32bit value into little endian */ +#if defined(__BIG_ENDIAN) +static inline uint32_t make_le32(uint32_t val) +{ + return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | + ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); +} +#else +#define make_le32(val) (val) +#endif +static inline void make_le32_n(uint32_t *val, unsigned int num) +{ + while (num--) { + *val = make_le32(*val); + val++; + } +} + + /******************/ + /* Portal access */ + /******************/ +struct qbman_swp_sys { + /* On GPP, the sys support for qbman_swp is here. The CENA region isi + * not an mmap() of the real portal registers, but an allocated + * place-holder, because the actual writes/reads to/from the portal are + * marshalled from these allocated areas using QBMan's "MC access + * registers". CINH accesses are atomic so there's no need for a + * place-holder. */ + void *cena; + void __iomem *addr_cena; + void __iomem *addr_cinh; +}; + +/* P_OFFSET is (ACCESS_CMD,0,12) - offset within the portal + * C is (ACCESS_CMD,12,1) - is inhibited? (0==CENA, 1==CINH) + * SWP_IDX is (ACCESS_CMD,16,10) - Software portal index + * P is (ACCESS_CMD,28,1) - (0==special portal, 1==any portal) + * T is (ACCESS_CMD,29,1) - Command type (0==READ, 1==WRITE) + * E is (ACCESS_CMD,31,1) - Command execute (1 to issue, poll for 0==complete) + */ + +static inline void qbman_cinh_write(struct qbman_swp_sys *s, uint32_t offset, + uint32_t val) +{ + __raw_writel(val, s->addr_cinh + offset); +#ifdef QBMAN_CINH_TRACE + pr_info("qbman_cinh_write(%p:0x%03x) 0x%08x\n", + s->addr_cinh, offset, val); +#endif +} + +static inline uint32_t qbman_cinh_read(struct qbman_swp_sys *s, uint32_t offset) +{ + uint32_t reg = __raw_readl(s->addr_cinh + offset); + +#ifdef QBMAN_CINH_TRACE + pr_info("qbman_cinh_read(%p:0x%03x) 0x%08x\n", + s->addr_cinh, offset, reg); +#endif + return reg; +} + +static inline void *qbman_cena_write_start(struct qbman_swp_sys *s, + uint32_t offset) +{ + void *shadow = s->cena + offset; + +#ifdef QBMAN_CENA_TRACE + pr_info("qbman_cena_write_start(%p:0x%03x) %p\n", + s->addr_cena, offset, shadow); +#endif + BUG_ON(offset & 63); + dcbz(shadow); + return shadow; +} + +static inline void qbman_cena_write_complete(struct qbman_swp_sys *s, + uint32_t offset, void *cmd) +{ + const uint32_t *shadow = cmd; + int loop; + +#ifdef QBMAN_CENA_TRACE + pr_info("qbman_cena_write_complete(%p:0x%03x) %p\n", + s->addr_cena, offset, shadow); + hexdump(cmd, 64); +#endif + for (loop = 15; loop >= 0; loop--) +#ifdef QBMAN_CINH_ONLY + __raw_writel(shadow[loop], s->addr_cinh + + offset + loop * 4); +#else + __raw_writel(shadow[loop], s->addr_cena + + offset + loop * 4); +#endif +} + +static inline void *qbman_cena_read(struct qbman_swp_sys *s, uint32_t offset) +{ + uint32_t *shadow = s->cena + offset; + unsigned int loop; + +#ifdef QBMAN_CENA_TRACE + pr_info("qbman_cena_read(%p:0x%03x) %p\n", + s->addr_cena, offset, shadow); +#endif + + for (loop = 0; loop < 16; loop++) +#ifdef QBMAN_CINH_ONLY + shadow[loop] = __raw_readl(s->addr_cinh + offset + + loop * 4); +#else + shadow[loop] = __raw_readl(s->addr_cena + offset + + loop * 4); +#endif +#ifdef QBMAN_CENA_TRACE + hexdump(shadow, 64); +#endif + return shadow; +} + +static inline void qbman_cena_invalidate_prefetch(struct qbman_swp_sys *s, + uint32_t offset) +{ +} + + /******************/ + /* Portal support */ + /******************/ + +/* The SWP_CFG portal register is special, in that it is used by the + * platform-specific code rather than the platform-independent code in + * qbman_portal.c. So use of it is declared locally here. */ +#define QBMAN_CINH_SWP_CFG 0xd00 + +/* For MC portal use, we always configure with + * DQRR_MF is (SWP_CFG,20,3) - DQRR max fill (<- 0x4) + * EST is (SWP_CFG,16,3) - EQCR_CI stashing threshold (<- 0x0) + * RPM is (SWP_CFG,12,2) - RCR production notification mode (<- 0x3) + * DCM is (SWP_CFG,10,2) - DQRR consumption notification mode (<- 0x2) + * EPM is (SWP_CFG,8,2) - EQCR production notification mode (<- 0x3) + * SD is (SWP_CFG,5,1) - memory stashing drop enable (<- FALSE) + * SP is (SWP_CFG,4,1) - memory stashing priority (<- TRUE) + * SE is (SWP_CFG,3,1) - memory stashing enable (<- 0x0) + * DP is (SWP_CFG,2,1) - dequeue stashing priority (<- TRUE) + * DE is (SWP_CFG,1,1) - dequeue stashing enable (<- 0x0) + * EP is (SWP_CFG,0,1) - EQCR_CI stashing priority (<- FALSE) + */ +static inline uint32_t qbman_set_swp_cfg(uint8_t max_fill, uint8_t wn, + uint8_t est, uint8_t rpm, uint8_t dcm, + uint8_t epm, int sd, int sp, int se, + int dp, int de, int ep) +{ + uint32_t reg; + + reg = e32_uint8_t(20, 3, max_fill) | e32_uint8_t(16, 3, est) | + e32_uint8_t(12, 2, rpm) | e32_uint8_t(10, 2, dcm) | + e32_uint8_t(8, 2, epm) | e32_int(5, 1, sd) | + e32_int(4, 1, sp) | e32_int(3, 1, se) | e32_int(2, 1, dp) | + e32_int(1, 1, de) | e32_int(0, 1, ep) | e32_uint8_t(14, 1, wn); + return reg; +} + +static inline int qbman_swp_sys_init(struct qbman_swp_sys *s, + const struct qbman_swp_desc *d) +{ + uint32_t reg; + + s->addr_cena = d->cena_bar; + s->addr_cinh = d->cinh_bar; + s->cena = (void *)valloc(CONFIG_SYS_PAGE_SIZE); + memset((void *)s->cena, 0x00, CONFIG_SYS_PAGE_SIZE); + if (!s->cena) { + printf("Could not allocate page for cena shadow\n"); + return -1; + } + +#ifdef QBMAN_CHECKING + /* We should never be asked to initialise for a portal that isn't in + * the power-on state. (Ie. don't forget to reset portals when they are + * decommissioned!) + */ + reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG); + BUG_ON(reg); +#endif +#ifdef QBMAN_CINH_ONLY + reg = qbman_set_swp_cfg(4, 1, 0, 3, 2, 3, 0, 1, 0, 1, 0, 0); +#else + reg = qbman_set_swp_cfg(4, 0, 0, 3, 2, 3, 0, 1, 0, 1, 0, 0); +#endif + qbman_cinh_write(s, QBMAN_CINH_SWP_CFG, reg); + reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG); + if (!reg) { + printf("The portal is not enabled!\n"); + free(s->cena); + return -1; + } + return 0; +} + +static inline void qbman_swp_sys_finish(struct qbman_swp_sys *s) +{ + free((void *)s->cena); +} diff --git a/drivers/net/fsl-mc/dpmng.c b/drivers/net/fsl-mc/dpmng.c index cc14c7b..01ee112 100644 --- a/drivers/net/fsl-mc/dpmng.c +++ b/drivers/net/fsl-mc/dpmng.c @@ -1,4 +1,4 @@ -/* Copyright 2014 Freescale Semiconductor Inc. +/* Copyright 2013-2015 Freescale Semiconductor Inc. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -26,66 +26,3 @@ int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info) return 0; } - -int dpmng_reset_aiop(struct fsl_mc_io *mc_io, int container_id, - int aiop_tile_id) -{ - struct mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_AIOP, - MC_CMD_PRI_LOW, 0); - DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -int dpmng_load_aiop(struct fsl_mc_io *mc_io, - int container_id, - int aiop_tile_id, - uint64_t img_iova, - uint32_t img_size) -{ - struct mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMNG_CMDID_LOAD_AIOP, - MC_CMD_PRI_LOW, - 0); - DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size, - img_iova); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -int dpmng_run_aiop(struct fsl_mc_io *mc_io, - int container_id, - int aiop_tile_id, - const struct dpmng_aiop_run_cfg *cfg) -{ - struct mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RUN_AIOP, - MC_CMD_PRI_LOW, - 0); - DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} - -int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io) -{ - struct mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_MC_PORTAL, - MC_CMD_PRI_LOW, - 0); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -} diff --git a/drivers/net/fsl-mc/dpni.c b/drivers/net/fsl-mc/dpni.c new file mode 100644 index 0000000..b384401 --- /dev/null +++ b/drivers/net/fsl-mc/dpni.c @@ -0,0 +1,506 @@ +/* + * Copyright (C) 2013-2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <fsl-mc/fsl_mc_sys.h> +#include <fsl-mc/fsl_mc_cmd.h> +#include <fsl-mc/fsl_dpni.h> + +int dpni_open(struct fsl_mc_io *mc_io, int dpni_id, uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN, + MC_CMD_PRI_LOW, 0); + DPNI_CMD_OPEN(cmd, dpni_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *token = MC_CMD_HDR_READ_TOKEN(cmd.header); + + return 0; +} + +int dpni_close(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE, + MC_CMD_PRI_HIGH, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_set_pools(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dpni_pools_cfg *cfg) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS, + MC_CMD_PRI_LOW, + token); + DPNI_CMD_SET_POOLS(cmd, cfg); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_enable(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_disable(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE, + MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_reset(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpni_attr *attr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR, + MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPNI_RSP_GET_ATTR(cmd, attr); + + return 0; +} + +int dpni_get_rx_buffer_layout(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpni_buffer_layout *layout) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_RX_BUFFER_LAYOUT, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPNI_RSP_GET_RX_BUFFER_LAYOUT(cmd, layout); + + return 0; +} + +int dpni_set_rx_buffer_layout(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dpni_buffer_layout *layout) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_BUFFER_LAYOUT, + MC_CMD_PRI_LOW, token); + DPNI_CMD_SET_RX_BUFFER_LAYOUT(cmd, layout); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_get_tx_buffer_layout(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpni_buffer_layout *layout) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_BUFFER_LAYOUT, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPNI_RSP_GET_TX_BUFFER_LAYOUT(cmd, layout); + + return 0; +} + +int dpni_set_tx_buffer_layout(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dpni_buffer_layout *layout) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_BUFFER_LAYOUT, + MC_CMD_PRI_LOW, token); + DPNI_CMD_SET_TX_BUFFER_LAYOUT(cmd, layout); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_get_tx_conf_buffer_layout(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpni_buffer_layout *layout) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_CONF_BUFFER_LAYOUT, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPNI_RSP_GET_TX_CONF_BUFFER_LAYOUT(cmd, layout); + + return 0; +} + +int dpni_set_tx_conf_buffer_layout(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dpni_buffer_layout *layout) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONF_BUFFER_LAYOUT, + MC_CMD_PRI_LOW, token); + DPNI_CMD_SET_TX_CONF_BUFFER_LAYOUT(cmd, layout); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_get_qdid(struct fsl_mc_io *mc_io, uint16_t token, uint16_t *qdid) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID, + MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPNI_RSP_GET_QDID(cmd, *qdid); + + return 0; +} + +int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io, + uint16_t token, + uint16_t *data_offset) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_DATA_OFFSET, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPNI_RSP_GET_TX_DATA_OFFSET(cmd, *data_offset); + + return 0; +} + +int dpni_get_counter(struct fsl_mc_io *mc_io, + uint16_t token, + enum dpni_counter counter, + uint64_t *value) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_COUNTER, + MC_CMD_PRI_LOW, token); + DPNI_CMD_GET_COUNTER(cmd, counter); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPNI_RSP_GET_COUNTER(cmd, *value); + + return 0; +} + +int dpni_set_counter(struct fsl_mc_io *mc_io, + uint16_t token, + enum dpni_counter counter, + uint64_t value) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_COUNTER, + MC_CMD_PRI_LOW, token); + DPNI_CMD_SET_COUNTER(cmd, counter, value); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_set_link_cfg(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpni_link_cfg *cfg) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG, + MC_CMD_PRI_LOW, token); + DPNI_CMD_SET_LINK_CFG(cmd, cfg); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_get_link_state(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpni_link_state *state) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPNI_RSP_GET_LINK_STATE(cmd, state); + + return 0; +} + + +int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io, + uint16_t token, + const uint8_t mac_addr[6]) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC, + MC_CMD_PRI_LOW, token); + DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t mac_addr[6]) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr); + + return 0; +} + +int dpni_add_mac_addr(struct fsl_mc_io *mc_io, + uint16_t token, + const uint8_t mac_addr[6]) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_MAC_ADDR, + MC_CMD_PRI_LOW, token); + DPNI_CMD_ADD_MAC_ADDR(cmd, mac_addr); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_remove_mac_addr(struct fsl_mc_io *mc_io, + uint16_t token, + const uint8_t mac_addr[6]) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_MAC_ADDR, + MC_CMD_PRI_LOW, token); + DPNI_CMD_REMOVE_MAC_ADDR(cmd, mac_addr); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_set_tx_flow(struct fsl_mc_io *mc_io, + uint16_t token, + uint16_t *flow_id, + const struct dpni_tx_flow_cfg *cfg) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_FLOW, + MC_CMD_PRI_LOW, token); + DPNI_CMD_SET_TX_FLOW(cmd, *flow_id, cfg); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPNI_RSP_SET_TX_FLOW(cmd, *flow_id); + + return 0; +} + +int dpni_get_tx_flow(struct fsl_mc_io *mc_io, + uint16_t token, + uint16_t flow_id, + struct dpni_tx_flow_attr *attr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_FLOW, + MC_CMD_PRI_LOW, token); + DPNI_CMD_GET_TX_FLOW(cmd, flow_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPNI_RSP_GET_TX_FLOW(cmd, attr); + + return 0; +} + +int dpni_set_rx_flow(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t tc_id, + uint16_t flow_id, + const struct dpni_queue_cfg *cfg) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_FLOW, + MC_CMD_PRI_LOW, token); + DPNI_CMD_SET_RX_FLOW(cmd, tc_id, flow_id, cfg); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpni_get_rx_flow(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t tc_id, + uint16_t flow_id, + struct dpni_queue_attr *attr) +{ + struct mc_command cmd = { 0 }; + int err; + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_RX_FLOW, + MC_CMD_PRI_LOW, token); + DPNI_CMD_GET_RX_FLOW(cmd, tc_id, flow_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPNI_RSP_GET_RX_FLOW(cmd, attr); + + return 0; +} diff --git a/drivers/net/fsl-mc/dprc.c b/drivers/net/fsl-mc/dprc.c new file mode 100644 index 0000000..d481200 --- /dev/null +++ b/drivers/net/fsl-mc/dprc.c @@ -0,0 +1,283 @@ +/* + * Freescale Layerscape MC I/O wrapper + * + * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. + * Author: German Rivera <German.Rivera@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <fsl-mc/fsl_mc_sys.h> +#include <fsl-mc/fsl_mc_cmd.h> +#include <fsl-mc/fsl_dprc.h> + +int dprc_get_container_id(struct fsl_mc_io *mc_io, int *container_id) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID, + MC_CMD_PRI_LOW, 0); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPRC_RSP_GET_CONTAINER_ID(cmd, *container_id); + + return 0; +} + +int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, MC_CMD_PRI_LOW, + 0); + DPRC_CMD_OPEN(cmd, container_id); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *token = MC_CMD_HDR_READ_TOKEN(cmd.header); + + return 0; +} + +int dprc_close(struct fsl_mc_io *mc_io, uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, MC_CMD_PRI_HIGH, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_reset_container(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_RESET_CONT, + MC_CMD_PRI_LOW, token); + DPRC_CMD_RESET_CONTAINER(cmd, child_container_id); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dprc_attributes *attr) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR, + MC_CMD_PRI_LOW, + token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPRC_RSP_GET_ATTRIBUTES(cmd, attr); + + return 0; +} + +int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT, + MC_CMD_PRI_LOW, token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPRC_RSP_GET_OBJ_COUNT(cmd, *obj_count); + + return 0; +} + +int dprc_get_obj(struct fsl_mc_io *mc_io, + uint16_t token, + int obj_index, + struct dprc_obj_desc *obj_desc) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ, + MC_CMD_PRI_LOW, + token); + DPRC_CMD_GET_OBJ(cmd, obj_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPRC_RSP_GET_OBJ(cmd, obj_desc); + + return 0; +} + +int dprc_get_res_count(struct fsl_mc_io *mc_io, + uint16_t token, + char *type, + int *res_count) +{ + struct mc_command cmd = { 0 }; + int err; + + *res_count = 0; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_COUNT, + MC_CMD_PRI_LOW, token); + DPRC_CMD_GET_RES_COUNT(cmd, type); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPRC_RSP_GET_RES_COUNT(cmd, *res_count); + + return 0; +} + +int dprc_get_res_ids(struct fsl_mc_io *mc_io, + uint16_t token, + char *type, + struct dprc_res_ids_range_desc *range_desc) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_IDS, + MC_CMD_PRI_LOW, token); + DPRC_CMD_GET_RES_IDS(cmd, range_desc, type); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPRC_RSP_GET_RES_IDS(cmd, range_desc); + + return 0; +} + +int dprc_get_obj_region(struct fsl_mc_io *mc_io, + uint16_t token, + char *obj_type, + int obj_id, + uint8_t region_index, + struct dprc_region_desc *region_desc) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG, + MC_CMD_PRI_LOW, token); + DPRC_CMD_GET_OBJ_REGION(cmd, obj_type, obj_id, region_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPRC_RSP_GET_OBJ_REGION(cmd, region_desc); + + return 0; +} + +int dprc_connect(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint1, + const struct dprc_endpoint *endpoint2) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_CONNECT, + MC_CMD_PRI_LOW, + token); + DPRC_CMD_CONNECT(cmd, endpoint1, endpoint2); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_disconnect(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_DISCONNECT, + MC_CMD_PRI_LOW, + token); + DPRC_CMD_DISCONNECT(cmd, endpoint); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dprc_get_connection(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint1, + struct dprc_endpoint *endpoint2, + int *state) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION, + MC_CMD_PRI_LOW, + token); + DPRC_CMD_GET_CONNECTION(cmd, endpoint1); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPRC_RSP_GET_CONNECTION(cmd, endpoint2, *state); + + return 0; +} diff --git a/drivers/net/fsl-mc/fsl_dpmng_cmd.h b/drivers/net/fsl-mc/fsl_dpmng_cmd.h index c9fe021..33f84f3 100644 --- a/drivers/net/fsl-mc/fsl_dpmng_cmd.h +++ b/drivers/net/fsl-mc/fsl_dpmng_cmd.h @@ -1,4 +1,4 @@ -/* Copyright 2014 Freescale Semiconductor Inc. +/* Copyright 2013-2015 Freescale Semiconductor Inc. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -7,10 +7,6 @@ /* Command IDs */ #define DPMNG_CMDID_GET_VERSION 0x831 -#define DPMNG_CMDID_RESET_AIOP 0x832 -#define DPMNG_CMDID_LOAD_AIOP 0x833 -#define DPMNG_CMDID_RUN_AIOP 0x834 -#define DPMNG_CMDID_RESET_MC_PORTAL 0x835 /* cmd, param, offset, width, type, arg_name */ #define DPMNG_RSP_GET_VERSION(cmd, mc_ver_info) \ @@ -20,30 +16,4 @@ do { \ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, mc_ver_info->minor); \ } while (0) -/* cmd, param, offset, width, type, arg_name */ -#define DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id) \ -do { \ - MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \ - MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \ -} while (0) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size, \ - img_iova) \ -do { \ - MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \ - MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \ - MC_CMD_OP(cmd, 1, 0, 32, uint32_t, img_size); \ - MC_CMD_OP(cmd, 2, 0, 64, uint64_t, img_iova); \ -} while (0) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg) \ -do { \ - MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \ - MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \ - MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->cores_mask); \ - MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options); \ -} while (0) - #endif /* __FSL_DPMNG_CMD_H */ diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index 74b0085..c5c44bc 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -3,16 +3,75 @@ * * SPDX-License-Identifier: GPL-2.0+ */ - #include <errno.h> #include <asm/io.h> #include <fsl-mc/fsl_mc.h> #include <fsl-mc/fsl_mc_sys.h> +#include <fsl-mc/fsl_mc_private.h> #include <fsl-mc/fsl_dpmng.h> +#include <fsl_debug_server.h> +#include <fsl-mc/fsl_dprc.h> +#include <fsl-mc/fsl_dpio.h> +#include <fsl-mc/fsl_qbman_portal.h> + +#define MC_RAM_BASE_ADDR_ALIGNMENT (512UL * 1024 * 1024) +#define MC_RAM_BASE_ADDR_ALIGNMENT_MASK (~(MC_RAM_BASE_ADDR_ALIGNMENT - 1)) +#define MC_RAM_SIZE_ALIGNMENT (256UL * 1024 * 1024) + +#define MC_MEM_SIZE_ENV_VAR "mcmemsize" +#define MC_BOOT_TIMEOUT_ENV_VAR "mcboottimeout" DECLARE_GLOBAL_DATA_PTR; static int mc_boot_status; +struct fsl_mc_io *dflt_mc_io = NULL; +uint16_t dflt_dprc_handle = 0; +struct fsl_dpbp_obj *dflt_dpbp = NULL; +struct fsl_dpio_obj *dflt_dpio = NULL; +uint16_t dflt_dpio_handle = 0; + +#ifdef DEBUG +void dump_ram_words(const char *title, void *addr) +{ + int i; + uint32_t *words = addr; + + printf("Dumping beginning of %s (%p):\n", title, addr); + for (i = 0; i < 16; i++) + printf("%#x ", words[i]); + printf("\n"); +} + +void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs) +{ + printf("MC CCSR registers:\n" + "reg_gcr1 %#x\n" + "reg_gsr %#x\n" + "reg_sicbalr %#x\n" + "reg_sicbahr %#x\n" + "reg_sicapr %#x\n" + "reg_mcfbalr %#x\n" + "reg_mcfbahr %#x\n" + "reg_mcfapr %#x\n" + "reg_psr %#x\n", + mc_ccsr_regs->reg_gcr1, + mc_ccsr_regs->reg_gsr, + mc_ccsr_regs->reg_sicbalr, + mc_ccsr_regs->reg_sicbahr, + mc_ccsr_regs->reg_sicapr, + mc_ccsr_regs->reg_mcfbalr, + mc_ccsr_regs->reg_mcfbahr, + mc_ccsr_regs->reg_mcfapr, + mc_ccsr_regs->reg_psr); +} +#else + +#define dump_ram_words(title, addr) +#define dump_mc_ccsr_regs(mc_ccsr_regs) + +#endif /* DEBUG */ + +#ifndef CONFIG_SYS_LS_MC_FW_IN_DDR /** * Copying MC firmware or DPL image to DDR */ @@ -21,6 +80,7 @@ static int mc_copy_image(const char *title, { debug("%s copied to address %p\n", title, (void *)mc_ram_addr); memcpy((void *)mc_ram_addr, (void *)image_addr, image_size); + flush_dcache_range(mc_ram_addr, mc_ram_addr + image_size); return 0; } @@ -82,23 +142,254 @@ int parse_mc_firmware_fit_image(const void **raw_image_addr, return 0; } +#endif + +/* + * Calculates the values to be used to specify the address range + * for the MC private DRAM block, in the MCFBALR/MCFBAHR registers. + * It returns the highest 512MB-aligned address within the given + * address range, in '*aligned_base_addr', and the number of 256 MiB + * blocks in it, in 'num_256mb_blocks'. + */ +static int calculate_mc_private_ram_params(u64 mc_private_ram_start_addr, + size_t mc_ram_size, + u64 *aligned_base_addr, + u8 *num_256mb_blocks) +{ + u64 addr; + u16 num_blocks; + + if (mc_ram_size % MC_RAM_SIZE_ALIGNMENT != 0) { + printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n", + mc_ram_size); + return -EINVAL; + } + + num_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT; + if (num_blocks < 1 || num_blocks > 0xff) { + printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n", + mc_ram_size); + return -EINVAL; + } + + addr = (mc_private_ram_start_addr + mc_ram_size - 1) & + MC_RAM_BASE_ADDR_ALIGNMENT_MASK; + + if (addr < mc_private_ram_start_addr) { + printf("fsl-mc: ERROR: bad start address %#llx\n", + mc_private_ram_start_addr); + return -EFAULT; + } + + *aligned_base_addr = addr; + *num_256mb_blocks = num_blocks; + return 0; +} + +static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size) +{ + u64 mc_dpc_offset; +#ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR + int error; + void *dpc_fdt_hdr; + int dpc_size; +#endif + +#ifdef CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET + BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET & 0x3) != 0 || + CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET > 0xffffffff); + + mc_dpc_offset = CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET; +#else +#error "CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET not defined" +#endif + + /* + * Load the MC DPC blob in the MC private DRAM block: + */ +#ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR + printf("MC DPC is preloaded to %#llx\n", mc_ram_addr + mc_dpc_offset); +#else + /* + * Get address and size of the DPC blob stored in flash: + */ +#ifdef CONFIG_SYS_LS_MC_DPC_IN_NOR + dpc_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPC_ADDR; +#else +#error "No CONFIG_SYS_LS_MC_DPC_IN_xxx defined" +#endif + + error = fdt_check_header(dpc_fdt_hdr); + if (error != 0) { + /* + * Don't return with error here, since the MC firmware can + * still boot without a DPC + */ + printf("fsl-mc: WARNING: No DPC image found\n"); + return 0; + } + + dpc_size = fdt_totalsize(dpc_fdt_hdr); + if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) { + printf("fsl-mc: ERROR: Bad DPC image (too large: %d)\n", + dpc_size); + return -EINVAL; + } + + mc_copy_image("MC DPC blob", + (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset); +#endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */ + + dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset)); + return 0; +} -int mc_init(bd_t *bis) +static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size) +{ + u64 mc_dpl_offset; +#ifndef CONFIG_SYS_LS_MC_DPL_IN_DDR + int error; + void *dpl_fdt_hdr; + int dpl_size; +#endif + +#ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET + BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || + CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff); + + mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET; +#else +#error "CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET not defined" +#endif + + /* + * Load the MC DPL blob in the MC private DRAM block: + */ +#ifdef CONFIG_SYS_LS_MC_DPL_IN_DDR + printf("MC DPL is preloaded to %#llx\n", mc_ram_addr + mc_dpl_offset); +#else + /* + * Get address and size of the DPL blob stored in flash: + */ +#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR + dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR; +#else +#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined" +#endif + + error = fdt_check_header(dpl_fdt_hdr); + if (error != 0) { + printf("fsl-mc: ERROR: Bad DPL image (bad header)\n"); + return error; + } + + dpl_size = fdt_totalsize(dpl_fdt_hdr); + if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) { + printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n", + dpl_size); + return -EINVAL; + } + + mc_copy_image("MC DPL blob", + (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset); +#endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */ + + dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset)); + return 0; +} + +/** + * Return the MC boot timeout value in milliseconds + */ +static unsigned long get_mc_boot_timeout_ms(void) +{ + unsigned long timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; + + char *timeout_ms_env_var = getenv(MC_BOOT_TIMEOUT_ENV_VAR); + + if (timeout_ms_env_var) { + timeout_ms = simple_strtoul(timeout_ms_env_var, NULL, 10); + if (timeout_ms == 0) { + printf("fsl-mc: WARNING: Invalid value for \'" + MC_BOOT_TIMEOUT_ENV_VAR + "\' environment variable: %lu\n", + timeout_ms); + + timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS; + } + } + + return timeout_ms; +} + +static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr) +{ + u32 reg_gsr; + u32 mc_fw_boot_status; + unsigned long timeout_ms = get_mc_boot_timeout_ms(); + struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; + + dmb(); + debug("Polling mc_ccsr_regs->reg_gsr ...\n"); + assert(timeout_ms > 0); + for (;;) { + udelay(1000); /* throttle polling */ + reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr); + mc_fw_boot_status = (reg_gsr & GSR_FS_MASK); + if (mc_fw_boot_status & 0x1) + break; + + timeout_ms--; + if (timeout_ms == 0) + break; + } + + if (timeout_ms == 0) { + if (booting_mc) + printf("fsl-mc: timeout booting management complex firmware\n"); + else + printf("fsl-mc: timeout deploying data path layout\n"); + + /* TODO: Get an error status from an MC CCSR register */ + return -ETIMEDOUT; + } + + if (mc_fw_boot_status != 0x1) { + /* + * TODO: Identify critical errors from the GSR register's FS + * field and for those errors, set error to -ENODEV or other + * appropriate errno, so that the status property is set to + * failure in the fsl,dprc device tree node. + */ + if (booting_mc) { + printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n", + reg_gsr); + } else { + printf("fsl-mc: WARNING: Data path layout deployed with error (GSR: %#x)\n", + reg_gsr); + } + } + + *final_reg_gsr = reg_gsr; + return 0; +} + +int mc_init(void) { int error = 0; - int timeout = 200000; + int portal_id = 0; struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; u64 mc_ram_addr; - u64 mc_dpl_offset; u32 reg_gsr; - u32 mc_fw_boot_status; - void *dpl_fdt_hdr; - int dpl_size; + u32 reg_mcfbalr; +#ifndef CONFIG_SYS_LS_MC_FW_IN_DDR const void *raw_image_addr; size_t raw_image_size = 0; - struct fsl_mc_io mc_io; - int portal_id; +#endif struct mc_version mc_ver_info; + u64 mc_ram_aligned_base_addr; + u8 mc_ram_num_256mb_blocks; + size_t mc_ram_size = mc_get_dram_block_size(); /* * The MC private DRAM block was already carved at the end of DRAM @@ -112,6 +403,20 @@ int mc_init(bd_t *bis) gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; } +#ifdef CONFIG_FSL_DEBUG_SERVER + /* + * FIXME: I don't think this is right. See get_dram_size_to_hide() + */ + mc_ram_addr -= debug_server_get_dram_block_size(); +#endif + + error = calculate_mc_private_ram_params(mc_ram_addr, + mc_ram_size, + &mc_ram_aligned_base_addr, + &mc_ram_num_256mb_blocks); + if (error != 0) + goto out; + /* * Management Complex cores should be held at reset out of POR. * U-boot should be the first software to touch MC. To be safe, @@ -127,6 +432,9 @@ int mc_init(bd_t *bis) out_le32(&mc_ccsr_regs->reg_gcr1, 0); dmb(); +#ifdef CONFIG_SYS_LS_MC_FW_IN_DDR + printf("MC firmware is preloaded to %#llx\n", mc_ram_addr); +#else error = parse_mc_firmware_fit_image(&raw_image_addr, &raw_image_size); if (error != 0) goto out; @@ -135,83 +443,34 @@ int mc_init(bd_t *bis) */ mc_copy_image("MC Firmware", (u64)raw_image_addr, raw_image_size, mc_ram_addr); - - /* - * Get address and size of the DPL blob stored in flash: - */ -#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR - dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR; -#else -#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined" #endif + dump_ram_words("firmware", (void *)mc_ram_addr); - error = fdt_check_header(dpl_fdt_hdr); - if (error != 0) { - printf("fsl-mc: ERROR: Bad DPL image (bad header)\n"); - goto out; - } - - dpl_size = fdt_totalsize(dpl_fdt_hdr); - if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) { - printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n", - dpl_size); - error = -EINVAL; + error = load_mc_dpc(mc_ram_addr, mc_ram_size); + if (error != 0) goto out; - } - /* - * Calculate offset in the MC private DRAM block at which the MC DPL - * blob is to be placed: - */ -#ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET - BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || - CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff); - - mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET; -#else - mc_dpl_offset = mc_get_dram_block_size() - - roundup(CONFIG_SYS_LS_MC_DPL_MAX_LENGTH, 4096); - - if ((mc_dpl_offset & 0x3) != 0 || mc_dpl_offset > 0xffffffff) { - printf("%s: Invalid MC DPL offset: %llu\n", - __func__, mc_dpl_offset); - error = -EINVAL; + error = load_mc_dpl(mc_ram_addr, mc_ram_size); + if (error != 0) goto out; - } -#endif - - /* - * Load the MC DPL blob at the far end of the MC private DRAM block: - * - * TODO: Should we place the DPL at a different location to match - * assumptions of MC firmware about its memory layout? - */ - mc_copy_image("MC DPL blob", - (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset); debug("mc_ccsr_regs %p\n", mc_ccsr_regs); + dump_mc_ccsr_regs(mc_ccsr_regs); /* - * Tell MC where the MC Firmware image was loaded in DDR: + * Tell MC what is the address range of the DRAM block assigned to it: */ - out_le32(&mc_ccsr_regs->reg_mcfbalr, (u32)mc_ram_addr); - out_le32(&mc_ccsr_regs->reg_mcfbahr, (u32)((u64)mc_ram_addr >> 32)); + reg_mcfbalr = (u32)mc_ram_aligned_base_addr | + (mc_ram_num_256mb_blocks - 1); + out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr); + out_le32(&mc_ccsr_regs->reg_mcfbahr, + (u32)(mc_ram_aligned_base_addr >> 32)); out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK); /* - * Tell MC where the DPL blob was loaded in DDR, by indicating - * its offset relative to the beginning of the DDR block - * allocated to the MC firmware. The MC firmware is responsible - * for checking that there is no overlap between the DPL blob - * and the runtime heap and stack of the MC firmware itself. - * - * NOTE: bits [31:2] of this offset need to be stored in bits [29:0] of - * the GSR MC CCSR register. So, this offset is assumed to be 4-byte - * aligned. - * Care must be taken not to write 1s into bits 31 and 30 of the GSR in - * this case as the SoC COP or PIC will be signaled. + * Tell the MC that we want delayed DPL deployment. */ - out_le32(&mc_ccsr_regs->reg_gsr, (u32)(mc_dpl_offset >> 2)); + out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00); printf("\nfsl-mc: Booting Management Complex ...\n"); @@ -219,38 +478,9 @@ int mc_init(bd_t *bis) * Deassert reset and release MC core 0 to run */ out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST); - dmb(); - debug("Polling mc_ccsr_regs->reg_gsr ...\n"); - - for (;;) { - reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr); - mc_fw_boot_status = (reg_gsr & GSR_FS_MASK); - if (mc_fw_boot_status & 0x1) - break; - - udelay(1000); /* throttle polling */ - if (timeout-- <= 0) - break; - } - - if (timeout <= 0) { - printf("fsl-mc: timeout booting management complex firmware\n"); - - /* TODO: Get an error status from an MC CCSR register */ - error = -ETIMEDOUT; + error = wait_for_mc(true, ®_gsr); + if (error != 0) goto out; - } - - if (mc_fw_boot_status != 0x1) { - /* - * TODO: Identify critical errors from the GSR register's FS - * field and for those errors, set error to -ENODEV or other - * appropriate errno, so that the status property is set to - * failure in the fsl,dprc device tree node. - */ - printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n", - reg_gsr); - } /* * TODO: need to obtain the portal_id for the root container from the @@ -259,13 +489,20 @@ int mc_init(bd_t *bis) portal_id = 0; /* - * Check that the MC firmware is responding portal commands: + * Initialize the global default MC portal + * And check that the MC firmware is responding portal commands: */ - mc_io.mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); + dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io)); + if (!dflt_mc_io) { + printf(" No memory: malloc() failed\n"); + return -ENOMEM; + } + + dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n", - portal_id, mc_io.mmio_regs); + portal_id, dflt_mc_io->mmio_regs); - error = mc_get_version(&mc_io, &mc_ver_info); + error = mc_get_version(dflt_mc_io, &mc_ver_info); if (error != 0) { printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n", error); @@ -282,7 +519,16 @@ int mc_init(bd_t *bis) printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n", mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision, - mc_fw_boot_status); + reg_gsr & GSR_FS_MASK); + + /* + * Tell the MC to deploy the DPL: + */ + out_le32(&mc_ccsr_regs->reg_gsr, 0x0); + printf("\nfsl-mc: Deploying data path layout ...\n"); + error = wait_for_mc(false, ®_gsr); + if (error != 0) + goto out; out: if (error != 0) mc_boot_status = -error; @@ -299,12 +545,242 @@ int get_mc_boot_status(void) /** * Return the actual size of the MC private DRAM block. - * - * NOTE: For now this function always returns the minimum required size, - * However, in the future, the actual size may be obtained from an environment - * variable. */ unsigned long mc_get_dram_block_size(void) { - return CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; + unsigned long dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; + + char *dram_block_size_env_var = getenv(MC_MEM_SIZE_ENV_VAR); + + if (dram_block_size_env_var) { + dram_block_size = simple_strtoul(dram_block_size_env_var, NULL, + 10); + + if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) { + printf("fsl-mc: WARNING: Invalid value for \'" + MC_MEM_SIZE_ENV_VAR + "\' environment variable: %lu\n", + dram_block_size); + + dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; + } + } + + return dram_block_size; +} + +int dpio_init(struct dprc_obj_desc obj_desc) +{ + struct qbman_swp_desc p_des; + struct dpio_attr attr; + int err = 0; + + dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj)); + if (!dflt_dpio) { + printf(" No memory: malloc() failed\n"); + return -ENOMEM; + } + + dflt_dpio->dpio_id = obj_desc.id; + + err = dpio_open(dflt_mc_io, obj_desc.id, &dflt_dpio_handle); + if (err) { + printf("dpio_open() failed\n"); + goto err_open; + } + + err = dpio_get_attributes(dflt_mc_io, dflt_dpio_handle, &attr); + if (err) { + printf("dpio_get_attributes() failed %d\n", err); + goto err_get_attr; + } + + err = dpio_enable(dflt_mc_io, dflt_dpio_handle); + if (err) { + printf("dpio_enable() failed %d\n", err); + goto err_get_enable; + } + debug("ce_paddr=0x%llx, ci_paddr=0x%llx, portalid=%d, prios=%d\n", + attr.qbman_portal_ce_paddr, + attr.qbman_portal_ci_paddr, + attr.qbman_portal_id, + attr.num_priorities); + + p_des.cena_bar = (void *)attr.qbman_portal_ce_paddr; + p_des.cinh_bar = (void *)attr.qbman_portal_ci_paddr; + + dflt_dpio->sw_portal = qbman_swp_init(&p_des); + if (dflt_dpio->sw_portal == NULL) { + printf("qbman_swp_init() failed\n"); + goto err_get_swp_init; + } + return 0; + +err_get_swp_init: +err_get_enable: + dpio_disable(dflt_mc_io, dflt_dpio_handle); +err_get_attr: + dpio_close(dflt_mc_io, dflt_dpio_handle); +err_open: + free(dflt_dpio); + return err; +} + +int dpbp_init(struct dprc_obj_desc obj_desc) +{ + dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj)); + if (!dflt_dpbp) { + printf(" No memory: malloc() failed\n"); + return -ENOMEM; + } + dflt_dpbp->dpbp_attr.id = obj_desc.id; + + return 0; +} + +int dprc_init_container_obj(struct dprc_obj_desc obj_desc, uint16_t dprc_handle) +{ + int error = 0, state = 0; + struct dprc_endpoint dpni_endpoint, dpmac_endpoint; + if (!strcmp(obj_desc.type, "dpbp")) { + if (!dflt_dpbp) { + error = dpbp_init(obj_desc); + if (error < 0) + printf("dpbp_init failed\n"); + } + } else if (!strcmp(obj_desc.type, "dpio")) { + if (!dflt_dpio) { + error = dpio_init(obj_desc); + if (error < 0) + printf("dpio_init failed\n"); + } + } else if (!strcmp(obj_desc.type, "dpni")) { + strcpy(dpni_endpoint.type, obj_desc.type); + dpni_endpoint.id = obj_desc.id; + error = dprc_get_connection(dflt_mc_io, dprc_handle, + &dpni_endpoint, &dpmac_endpoint, &state); + if (!strcmp(dpmac_endpoint.type, "dpmac")) + error = ldpaa_eth_init(obj_desc); + if (error < 0) + printf("ldpaa_eth_init failed\n"); + } + + return error; +} + +int dprc_scan_container_obj(uint16_t dprc_handle, char *obj_type, int i) +{ + int error = 0; + struct dprc_obj_desc obj_desc; + + memset((void *)&obj_desc, 0x00, sizeof(struct dprc_obj_desc)); + + error = dprc_get_obj(dflt_mc_io, dprc_handle, + i, &obj_desc); + if (error < 0) { + printf("dprc_get_obj(i=%d) failed: %d\n", + i, error); + return error; + } + + if (!strcmp(obj_desc.type, obj_type)) { + debug("Discovered object: type %s, id %d, req %s\n", + obj_desc.type, obj_desc.id, obj_type); + + error = dprc_init_container_obj(obj_desc, dprc_handle); + if (error < 0) { + printf("dprc_init_container_obj(i=%d) failed: %d\n", + i, error); + return error; + } + } + + return error; +} + +int fsl_mc_ldpaa_init(bd_t *bis) +{ + int i, error = 0; + int dprc_opened = 0, container_id; + int num_child_objects = 0; + + error = mc_init(); + if (error < 0) + goto error; + + error = dprc_get_container_id(dflt_mc_io, &container_id); + if (error < 0) { + printf("dprc_get_container_id() failed: %d\n", error); + goto error; + } + + debug("fsl-mc: Container id=0x%x\n", container_id); + + error = dprc_open(dflt_mc_io, container_id, &dflt_dprc_handle); + if (error < 0) { + printf("dprc_open() failed: %d\n", error); + goto error; + } + dprc_opened = true; + + error = dprc_get_obj_count(dflt_mc_io, + dflt_dprc_handle, + &num_child_objects); + if (error < 0) { + printf("dprc_get_obj_count() failed: %d\n", error); + goto error; + } + debug("Total child in container %d = %d\n", container_id, + num_child_objects); + + if (num_child_objects != 0) { + /* + * Discover objects currently in the DPRC container in the MC: + */ + for (i = 0; i < num_child_objects; i++) + error = dprc_scan_container_obj(dflt_dprc_handle, + "dpbp", i); + + for (i = 0; i < num_child_objects; i++) + error = dprc_scan_container_obj(dflt_dprc_handle, + "dpio", i); + + for (i = 0; i < num_child_objects; i++) + error = dprc_scan_container_obj(dflt_dprc_handle, + "dpni", i); + } +error: + if (dprc_opened) + dprc_close(dflt_mc_io, dflt_dprc_handle); + + return error; +} + +void fsl_mc_ldpaa_exit(bd_t *bis) +{ + int err; + + if (get_mc_boot_status() == 0) { + err = dpio_disable(dflt_mc_io, dflt_dpio_handle); + if (err < 0) { + printf("dpio_disable() failed: %d\n", err); + return; + } + err = dpio_reset(dflt_mc_io, dflt_dpio_handle); + if (err < 0) { + printf("dpio_reset() failed: %d\n", err); + return; + } + err = dpio_close(dflt_mc_io, dflt_dpio_handle); + if (err < 0) { + printf("dpio_close() failed: %d\n", err); + return; + } + + free(dflt_dpio); + free(dflt_dpbp); + } + + if (dflt_mc_io) + free(dflt_mc_io); } diff --git a/drivers/net/fsl-mc/mc_sys.c b/drivers/net/fsl-mc/mc_sys.c index 7c8e003..3fc1f98 100644 --- a/drivers/net/fsl-mc/mc_sys.c +++ b/drivers/net/fsl-mc/mc_sys.c @@ -1,7 +1,7 @@ /* * Freescale Layerscape MC I/O wrapper * - * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. * Author: German Rivera <German.Rivera@freescale.com> * * SPDX-License-Identifier: GPL-2.0+ @@ -32,7 +32,7 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) { enum mc_cmd_status status; - int timeout = 2000; + int timeout = 6000; mc_write_command(mc_io->mmio_regs, cmd); @@ -52,7 +52,7 @@ int mc_send_command(struct fsl_mc_io *mc_io, if (status != MC_CMD_STATUS_OK) { printf("Error: MC command failed (portal: %p, obj handle: %#x, command: %#x, status: %#x)\n", mc_io->mmio_regs, - (unsigned int)MC_CMD_HDR_READ_AUTHID(cmd->header), + (unsigned int)MC_CMD_HDR_READ_TOKEN(cmd->header), (unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header), (unsigned int)status); diff --git a/drivers/net/fsl_mcdmafec.c b/drivers/net/fsl_mcdmafec.c index 6391f9b..792534b 100644 --- a/drivers/net/fsl_mcdmafec.c +++ b/drivers/net/fsl_mcdmafec.c @@ -244,7 +244,7 @@ static int fec_recv(struct eth_device *dev) struct fec_info_dma *info = dev->priv; volatile fecdma_t *fecp = (fecdma_t *) (info->iobase); - cbd_t *pRbd = &info->rxbd[info->rxIdx]; + cbd_t *prbd = &info->rxbd[info->rxIdx]; u32 ievent; int frame_length, len = 0; @@ -276,26 +276,27 @@ static int fec_recv(struct eth_device *dev) } } - if (!(pRbd->cbd_sc & BD_ENET_RX_EMPTY)) { - if ((pRbd->cbd_sc & BD_ENET_RX_LAST) - && !(pRbd->cbd_sc & BD_ENET_RX_ERR) - && ((pRbd->cbd_datlen - 4) > 14)) { + if (!(prbd->cbd_sc & BD_ENET_RX_EMPTY)) { + if ((prbd->cbd_sc & BD_ENET_RX_LAST) && + !(prbd->cbd_sc & BD_ENET_RX_ERR) && + ((prbd->cbd_datlen - 4) > 14)) { /* Get buffer address and size */ - frame_length = pRbd->cbd_datlen - 4; + frame_length = prbd->cbd_datlen - 4; /* Fill the buffer and pass it to upper layers */ - NetReceive((uchar *)pRbd->cbd_bufaddr, frame_length); + net_process_received_packet((uchar *)prbd->cbd_bufaddr, + frame_length); len = frame_length; } /* Reset buffer descriptor as empty */ if ((info->rxIdx) == (PKTBUFSRX - 1)) - pRbd->cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY); + prbd->cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY); else - pRbd->cbd_sc = BD_ENET_RX_EMPTY; + prbd->cbd_sc = BD_ENET_RX_EMPTY; - pRbd->cbd_datlen = PKTSIZE_ALIGN; + prbd->cbd_datlen = PKTSIZE_ALIGN; /* Now, we have an empty RxBD, restart the DMA receive task */ MCD_continDma(info->rxTask); @@ -399,7 +400,7 @@ static int fec_init(struct eth_device *dev, bd_t * bd) for (i = 0; i < PKTBUFSRX; i++) { info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; info->rxbd[i].cbd_datlen = PKTSIZE_ALIGN; - info->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i]; + info->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i]; } info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c index 8519314..515f0b2 100644 --- a/drivers/net/ftgmac100.c +++ b/drivers/net/ftgmac100.c @@ -423,7 +423,7 @@ static int ftgmac100_init(struct eth_device *dev, bd_t *bd) for (i = 0; i < PKTBUFSRX; i++) { /* RXBUF_BADR */ if (!rxdes[i].rxdes2) { - buf = NetRxPackets[i]; + buf = net_rx_packets[i]; rxdes[i].rxdes3 = virt_to_phys(buf); rxdes[i].rxdes2 = (uint)buf; } @@ -493,7 +493,7 @@ static int ftgmac100_recv(struct eth_device *dev) dma_map_single((void *)curr_des->rxdes2, rxlen, DMA_FROM_DEVICE); /* pass the packet up to the protocol layers. */ - NetReceive((void *)curr_des->rxdes2, rxlen); + net_process_received_packet((void *)curr_des->rxdes2, rxlen); /* release buffer to DMA */ curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY; diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c index 3e148db..bd94f83 100644 --- a/drivers/net/ftmac100.c +++ b/drivers/net/ftmac100.c @@ -102,7 +102,7 @@ static int ftmac100_init (struct eth_device *dev, bd_t *bd) for (i = 0; i < PKTBUFSRX; i++) { /* RXBUF_BADR */ - rxdes[i].rxdes2 = (unsigned int)NetRxPackets[i]; + rxdes[i].rxdes2 = (unsigned int)net_rx_packets[i]; rxdes[i].rxdes1 |= FTMAC100_RXDES1_RXBUF_SIZE (PKTSIZE_ALIGN); rxdes[i].rxdes0 = FTMAC100_RXDES0_RXDMA_OWN; } @@ -164,7 +164,7 @@ static int ftmac100_recv (struct eth_device *dev) /* pass the packet up to the protocol layers. */ - NetReceive ((void *)curr_des->rxdes2, rxlen); + net_process_received_packet((void *)curr_des->rxdes2, rxlen); /* release buffer to DMA */ diff --git a/drivers/net/ftmac110.c b/drivers/net/ftmac110.c index 98c4f09..4bae9ad 100644 --- a/drivers/net/ftmac110.c +++ b/drivers/net/ftmac110.c @@ -347,7 +347,7 @@ static int ftmac110_recv(struct eth_device *dev) printf("ftmac110: rx error\n"); } else { dma_map_single(buf, len, DMA_FROM_DEVICE); - NetReceive(buf, len); + net_process_received_packet(buf, len); rlen += len; } @@ -425,7 +425,7 @@ int ftmac110_initialize(bd_t *bis) dev->recv = ftmac110_recv; if (!eth_getenv_enetaddr_by_index("eth", card_nr, dev->enetaddr)) - eth_random_addr(dev->enetaddr); + net_random_ethaddr(dev->enetaddr); /* allocate tx descriptors (it must be 16 bytes aligned) */ chip->txd = dma_alloc_coherent( diff --git a/drivers/net/greth.c b/drivers/net/greth.c index c817af4..a93b37a 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -533,7 +533,7 @@ int greth_recv(struct eth_device *dev) sparc_dcache_flush_all(); /* pass packet on to network subsystem */ - NetReceive((void *)d, len); + net_process_received_packet((void *)d, len); /* bump stats counters */ greth->stats.rx_packets++; diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c index 35f1a57..0c5fdee 100644 --- a/drivers/net/keystone_net.c +++ b/drivers/net/keystone_net.c @@ -505,7 +505,7 @@ static int keystone2_eth_rcv_packet(struct eth_device *dev) if (hd == NULL) return 0; - NetReceive((uchar *)pkt, pkt_size); + net_process_received_packet((uchar *)pkt, pkt_size); ksnav_release_rxhd(&netcp_pktdma, hd); diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index 05e5b14..5b4c5b0 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c @@ -321,8 +321,8 @@ static void ks_rcv(struct eth_device *dev, uchar **pv_data) /* read data block including CRC 4 bytes */ ks_read_qmu(dev, (u16 *)(*pv_data), frame_hdr->len); - /* NetRxPackets buffer size is ok (*pv_data pointer) */ - NetReceive(*pv_data, frame_hdr->len); + /* net_rx_packets buffer size is ok (*pv_data) */ + net_process_received_packet(*pv_data, frame_hdr->len); pv_data++; } else { ks_wrreg16(dev, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF)); @@ -573,7 +573,7 @@ static int ks8851_mll_recv(struct eth_device *dev) ks_wrreg16(dev, KS_ISR, status); if ((status & IRQ_RXI)) - ks_rcv(dev, (uchar **)NetRxPackets); + ks_rcv(dev, (uchar **)net_rx_packets); if ((status & IRQ_LDI)) { u16 pmecr = ks_rdreg16(dev, KS_PMECR); diff --git a/drivers/net/lan91c96.c b/drivers/net/lan91c96.c index 229658a..495c088 100644 --- a/drivers/net/lan91c96.c +++ b/drivers/net/lan91c96.c @@ -568,29 +568,30 @@ static int smc_rcv(struct eth_device *dev) to send the DWORDs or the bytes first, or some mixture. A mixture might improve already slow PIO performance */ - SMC_insl(dev, LAN91C96_DATA_HIGH, NetRxPackets[0], - packet_length >> 2); + SMC_insl(dev, LAN91C96_DATA_HIGH, net_rx_packets[0], + packet_length >> 2); /* read the left over bytes */ if (packet_length & 3) { int i; - byte *tail = (byte *) (NetRxPackets[0] + (packet_length & ~3)); + byte *tail = (byte *)(net_rx_packets[0] + + (packet_length & ~3)); dword leftover = SMC_inl(dev, LAN91C96_DATA_HIGH); for (i = 0; i < (packet_length & 3); i++) *tail++ = (byte) (leftover >> (8 * i)) & 0xff; } #else - PRINTK3 (" Reading %d words and %d byte(s) \n", - (packet_length >> 1), packet_length & 1); - SMC_insw(dev, LAN91C96_DATA_HIGH, NetRxPackets[0], - packet_length >> 1); + PRINTK3(" Reading %d words and %d byte(s)\n", + (packet_length >> 1), packet_length & 1); + SMC_insw(dev, LAN91C96_DATA_HIGH, net_rx_packets[0], + packet_length >> 1); #endif /* USE_32_BIT */ #if SMC_DEBUG > 2 printf ("Receiving Packet\n"); - print_packet((byte *)NetRxPackets[0], packet_length); + print_packet((byte *)net_rx_packets[0], packet_length); #endif } else { /* error ... */ @@ -609,7 +610,7 @@ static int smc_rcv(struct eth_device *dev) if (!is_error) { /* Pass the packet up to the protocol layers. */ - NetReceive (NetRxPackets[0], packet_length); + net_process_received_packet(net_rx_packets[0], packet_length); return packet_length; } else { return 0; diff --git a/drivers/net/ldpaa_eth/Makefile b/drivers/net/ldpaa_eth/Makefile new file mode 100644 index 0000000..c37633f --- /dev/null +++ b/drivers/net/ldpaa_eth/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2014 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ldpaa_wriop.o +obj-y += ldpaa_eth.o +obj-$(CONFIG_LS2085A) += ls2085a.o diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c new file mode 100644 index 0000000..d4be1ba --- /dev/null +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -0,0 +1,710 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/types.h> +#include <malloc.h> +#include <net.h> +#include <hwconfig.h> +#include <phy.h> +#include <linux/compat.h> + +#include "ldpaa_eth.h" + +#undef CONFIG_PHYLIB +static int init_phy(struct eth_device *dev) +{ + /*TODO for external PHY */ + + return 0; +} + +static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv, + const struct dpaa_fd *fd) +{ + u64 fd_addr; + uint16_t fd_offset; + uint32_t fd_length; + struct ldpaa_fas *fas; + uint32_t status, err; + struct qbman_release_desc releasedesc; + struct qbman_swp *swp = dflt_dpio->sw_portal; + + fd_addr = ldpaa_fd_get_addr(fd); + fd_offset = ldpaa_fd_get_offset(fd); + fd_length = ldpaa_fd_get_len(fd); + + debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length); + + if (fd->simple.frc & LDPAA_FD_FRC_FASV) { + /* Read the frame annotation status word and check for errors */ + fas = (struct ldpaa_fas *) + ((uint8_t *)(fd_addr) + + priv->buf_layout.private_data_size); + status = le32_to_cpu(fas->status); + if (status & LDPAA_ETH_RX_ERR_MASK) { + printf("Rx frame error(s): 0x%08x\n", + status & LDPAA_ETH_RX_ERR_MASK); + goto error; + } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) { + printf("Unsupported feature in bitmask: 0x%08x\n", + status & LDPAA_ETH_RX_UNSUPP_MASK); + goto error; + } + } + + debug("Rx frame: To Upper layer\n"); + net_process_received_packet((uint8_t *)(fd_addr) + fd_offset, + fd_length); + +error: + flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE); + qbman_release_desc_clear(&releasedesc); + qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); + do { + /* Release buffer into the QBMAN */ + err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); + } while (err == -EBUSY); + return; +} + +static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev) +{ + struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; + const struct ldpaa_dq *dq; + const struct dpaa_fd *fd; + int i = 5, err = 0, status, loop = 20; + static struct qbman_pull_desc pulldesc; + struct qbman_swp *swp = dflt_dpio->sw_portal; + + while (--i) { + qbman_pull_desc_clear(&pulldesc); + qbman_pull_desc_set_numframes(&pulldesc, 1); + qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid); + + err = qbman_swp_pull(swp, &pulldesc); + if (err < 0) { + printf("Dequeue frames error:0x%08x\n", err); + continue; + } + + do { + loop--; + dq = qbman_swp_dqrr_next(swp); + + if (!loop) + break; + } while (!dq); + + if (dq) { + /* Check for valid frame. If not sent a consume + * confirmation to QBMAN otherwise give it to NADK + * application and then send consume confirmation to + * QBMAN. + */ + status = (uint8_t)ldpaa_dq_flags(dq); + if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { + debug("Dequeue RX frames:"); + debug("No frame delivered\n"); + + qbman_swp_dqrr_consume(swp, dq); + break; + } + + fd = ldpaa_dq_fd(dq); + + /* Obtain FD and process it */ + ldpaa_eth_rx(priv, fd); + qbman_swp_dqrr_consume(swp, dq); + break; + } + } + + return err; +} + +static void ldpaa_eth_tx_conf(struct ldpaa_eth_priv *priv, + const struct dpaa_fd *fd) +{ + uint64_t fd_addr; + struct ldpaa_fas *fas; + uint32_t status, err; + struct qbman_release_desc releasedesc; + struct qbman_swp *swp = dflt_dpio->sw_portal; + + fd_addr = ldpaa_fd_get_addr(fd); + + + debug("TX Conf frame:data addr=0x%p\n", (u64 *)fd_addr); + + /* Check the status from the Frame Annotation */ + if (fd->simple.frc & LDPAA_FD_FRC_FASV) { + fas = (struct ldpaa_fas *) + ((uint8_t *)(fd_addr) + + priv->buf_layout.private_data_size); + status = le32_to_cpu(fas->status); + if (status & LDPAA_ETH_TXCONF_ERR_MASK) { + printf("TxConf frame error(s): 0x%08x\n", + status & LDPAA_ETH_TXCONF_ERR_MASK); + } + } + + qbman_release_desc_clear(&releasedesc); + qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid); + do { + /* Release buffer into the QBMAN */ + err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1); + } while (err == -EBUSY); +} + +static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv) +{ + const struct ldpaa_dq *dq; + const struct dpaa_fd *fd; + int err = 0; + int i = 5, status, loop = 20; + static struct qbman_pull_desc pulldesc; + struct qbman_swp *swp = dflt_dpio->sw_portal; + + while (--i) { + qbman_pull_desc_clear(&pulldesc); + qbman_pull_desc_set_numframes(&pulldesc, 1); + qbman_pull_desc_set_fq(&pulldesc, priv->tx_conf_fqid); + + err = qbman_swp_pull(swp, &pulldesc); + if (err < 0) { + printf("Dequeue TX conf frames error:0x%08x\n", err); + continue; + } + + do { + loop--; + dq = qbman_swp_dqrr_next(swp); + + if (!loop) + break; + } while (!dq); + + if (dq) { + /* Check for valid frame. If not sent a consume + * confirmation to QBMAN otherwise give it to NADK + * application and then send consume confirmation to + * QBMAN. + */ + status = (uint8_t)ldpaa_dq_flags(dq); + if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) { + debug("Dequeue TX conf frames:"); + debug("No frame is delivered\n"); + + qbman_swp_dqrr_consume(swp, dq); + break; + } + fd = ldpaa_dq_fd(dq); + + ldpaa_eth_tx_conf(priv, fd); + qbman_swp_dqrr_consume(swp, dq); + break; + } + } + + return err; +} + +static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len) +{ + struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; + struct dpaa_fd fd; + u64 buffer_start; + int data_offset, err; + struct qbman_swp *swp = dflt_dpio->sw_portal; + struct qbman_eq_desc ed; + + /* Setup the FD fields */ + memset(&fd, 0, sizeof(fd)); + + data_offset = priv->tx_data_offset; + + do { + err = qbman_swp_acquire(dflt_dpio->sw_portal, + dflt_dpbp->dpbp_attr.bpid, + &buffer_start, 1); + } while (err == -EBUSY); + + if (err < 0) { + printf("qbman_swp_acquire() failed\n"); + return -ENOMEM; + } + + debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start); + + memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len); + + flush_dcache_range(buffer_start, buffer_start + + LDPAA_ETH_RX_BUFFER_SIZE); + + ldpaa_fd_set_addr(&fd, (u64)buffer_start); + ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset)); + ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid); + ldpaa_fd_set_len(&fd, len); + + fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA | + LDPAA_FD_CTRL_PTV1; + + qbman_eq_desc_clear(&ed); + qbman_eq_desc_set_no_orp(&ed, 0); + qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0); + err = qbman_swp_enqueue(swp, &ed, (const struct qbman_fd *)(&fd)); + if (err < 0) + printf("error enqueueing Tx frame\n"); + + mdelay(1); + + err = ldpaa_eth_pull_dequeue_tx_conf(priv); + if (err < 0) + printf("error Tx Conf frame\n"); + + return err; +} + +static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) +{ + struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; + struct dpni_queue_attr rx_queue_attr; + struct dpni_tx_flow_attr tx_flow_attr; + uint8_t mac_addr[6]; + int err; + + if (net_dev->state == ETH_STATE_ACTIVE) + return 0; + + /* DPNI initialization */ + err = ldpaa_dpni_setup(priv); + if (err < 0) + goto err_dpni_setup; + + err = ldpaa_dpbp_setup(); + if (err < 0) + goto err_dpbp_setup; + + /* DPNI binding DPBP */ + err = ldpaa_dpni_bind(priv); + if (err) + goto err_bind; + + err = dpni_get_primary_mac_addr(dflt_mc_io, priv->dpni_handle, + mac_addr); + if (err) { + printf("dpni_get_primary_mac_addr() failed\n"); + return err; + } + + memcpy(net_dev->enetaddr, mac_addr, 0x6); + + /* setup the MAC address */ + if (net_dev->enetaddr[0] & 0x01) { + printf("%s: MacAddress is multcast address\n", __func__); + return 1; + } + +#ifdef CONFIG_PHYLIB + /* TODO Check this path */ + err = phy_startup(priv->phydev); + if (err) { + printf("%s: Could not initialize\n", priv->phydev->dev->name); + return err; + } +#else + priv->phydev->speed = SPEED_1000; + priv->phydev->link = 1; + priv->phydev->duplex = DUPLEX_FULL; +#endif + + err = dpni_enable(dflt_mc_io, priv->dpni_handle); + if (err < 0) { + printf("dpni_enable() failed\n"); + return err; + } + + /* TODO: support multiple Rx flows */ + err = dpni_get_rx_flow(dflt_mc_io, priv->dpni_handle, 0, 0, + &rx_queue_attr); + if (err) { + printf("dpni_get_rx_flow() failed\n"); + goto err_rx_flow; + } + + priv->rx_dflt_fqid = rx_queue_attr.fqid; + + err = dpni_get_qdid(dflt_mc_io, priv->dpni_handle, &priv->tx_qdid); + if (err) { + printf("dpni_get_qdid() failed\n"); + goto err_qdid; + } + + err = dpni_get_tx_flow(dflt_mc_io, priv->dpni_handle, priv->tx_flow_id, + &tx_flow_attr); + if (err) { + printf("dpni_get_tx_flow() failed\n"); + goto err_tx_flow; + } + + priv->tx_conf_fqid = tx_flow_attr.conf_err_attr.queue_attr.fqid; + + if (!priv->phydev->link) + printf("%s: No link.\n", priv->phydev->dev->name); + + return priv->phydev->link ? 0 : -1; + +err_tx_flow: +err_qdid: +err_rx_flow: + dpni_disable(dflt_mc_io, priv->dpni_handle); +err_bind: + ldpaa_dpbp_free(); +err_dpbp_setup: + dpni_close(dflt_mc_io, priv->dpni_handle); +err_dpni_setup: + return err; +} + +static void ldpaa_eth_stop(struct eth_device *net_dev) +{ + struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; + int err = 0; + + if ((net_dev->state == ETH_STATE_PASSIVE) || + (net_dev->state == ETH_STATE_INIT)) + return; + /* Stop Tx and Rx traffic */ + err = dpni_disable(dflt_mc_io, priv->dpni_handle); + if (err < 0) + printf("dpni_disable() failed\n"); + +#ifdef CONFIG_PHYLIB + phy_shutdown(priv->phydev); +#endif + + ldpaa_dpbp_free(); + dpni_reset(dflt_mc_io, priv->dpni_handle); + dpni_close(dflt_mc_io, priv->dpni_handle); +} + +static void ldpaa_dpbp_drain_cnt(int count) +{ + uint64_t buf_array[7]; + void *addr; + int ret, i; + + BUG_ON(count > 7); + + do { + ret = qbman_swp_acquire(dflt_dpio->sw_portal, + dflt_dpbp->dpbp_attr.bpid, + buf_array, count); + if (ret < 0) { + printf("qbman_swp_acquire() failed\n"); + return; + } + for (i = 0; i < ret; i++) { + addr = (void *)buf_array[i]; + debug("Free: buffer addr =0x%p\n", addr); + free(addr); + } + } while (ret); +} + +static void ldpaa_dpbp_drain(void) +{ + int i; + for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) + ldpaa_dpbp_drain_cnt(7); +} + +static int ldpaa_bp_add_7(uint16_t bpid) +{ + uint64_t buf_array[7]; + u8 *addr; + int i; + struct qbman_release_desc rd; + + for (i = 0; i < 7; i++) { + addr = memalign(L1_CACHE_BYTES, LDPAA_ETH_RX_BUFFER_SIZE); + if (!addr) { + printf("addr allocation failed\n"); + goto err_alloc; + } + memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE); + flush_dcache_range((u64)addr, + (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE)); + + buf_array[i] = (uint64_t)addr; + debug("Release: buffer addr =0x%p\n", addr); + } + +release_bufs: + /* In case the portal is busy, retry until successful. + * This function is guaranteed to succeed in a reasonable amount + * of time. + */ + + do { + mdelay(1); + qbman_release_desc_clear(&rd); + qbman_release_desc_set_bpid(&rd, bpid); + } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i)); + + return i; + +err_alloc: + if (i) + goto release_bufs; + + return 0; +} + +static int ldpaa_dpbp_seed(uint16_t bpid) +{ + int i; + int count; + + for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) { + count = ldpaa_bp_add_7(bpid); + if (count < 7) + printf("Buffer Seed= %d\n", count); + } + + return 0; +} + +static int ldpaa_dpbp_setup(void) +{ + int err; + + err = dpbp_open(dflt_mc_io, dflt_dpbp->dpbp_attr.id, + &dflt_dpbp->dpbp_handle); + if (err) { + printf("dpbp_open() failed\n"); + goto err_open; + } + + err = dpbp_enable(dflt_mc_io, dflt_dpbp->dpbp_handle); + if (err) { + printf("dpbp_enable() failed\n"); + goto err_enable; + } + + err = dpbp_get_attributes(dflt_mc_io, dflt_dpbp->dpbp_handle, + &dflt_dpbp->dpbp_attr); + if (err) { + printf("dpbp_get_attributes() failed\n"); + goto err_get_attr; + } + + err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid); + if (err) { + printf("Buffer seeding failed for DPBP %d (bpid=%d)\n", + dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid); + goto err_seed; + } + + return 0; + +err_seed: +err_get_attr: + dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle); +err_enable: + dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle); +err_open: + return err; +} + +static void ldpaa_dpbp_free(void) +{ + ldpaa_dpbp_drain(); + dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle); + dpbp_reset(dflt_mc_io, dflt_dpbp->dpbp_handle); + dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle); +} + +static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv) +{ + int err; + + /* and get a handle for the DPNI this interface is associate with */ + err = dpni_open(dflt_mc_io, priv->dpni_id, &priv->dpni_handle); + if (err) { + printf("dpni_open() failed\n"); + goto err_open; + } + + err = dpni_get_attributes(dflt_mc_io, priv->dpni_handle, + &priv->dpni_attrs); + if (err) { + printf("dpni_get_attributes() failed (err=%d)\n", err); + goto err_get_attr; + } + + /* Configure our buffers' layout */ + priv->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT | + DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | + DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; + priv->buf_layout.pass_parser_result = true; + priv->buf_layout.pass_frame_status = true; + priv->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE; + /* ...rx, ... */ + err = dpni_set_rx_buffer_layout(dflt_mc_io, priv->dpni_handle, + &priv->buf_layout); + if (err) { + printf("dpni_set_rx_buffer_layout() failed"); + goto err_buf_layout; + } + + /* ... tx, ... */ + priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PARSER_RESULT; + err = dpni_set_tx_buffer_layout(dflt_mc_io, priv->dpni_handle, + &priv->buf_layout); + if (err) { + printf("dpni_set_tx_buffer_layout() failed"); + goto err_buf_layout; + } + + /* ... tx-confirm. */ + priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; + err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, priv->dpni_handle, + &priv->buf_layout); + if (err) { + printf("dpni_set_tx_conf_buffer_layout() failed"); + goto err_buf_layout; + } + + /* Now that we've set our tx buffer layout, retrieve the minimum + * required tx data offset. + */ + err = dpni_get_tx_data_offset(dflt_mc_io, priv->dpni_handle, + &priv->tx_data_offset); + if (err) { + printf("dpni_get_tx_data_offset() failed\n"); + goto err_data_offset; + } + + /* Warn in case TX data offset is not multiple of 64 bytes. */ + WARN_ON(priv->tx_data_offset % 64); + + /* Accomodate SWA space. */ + priv->tx_data_offset += LDPAA_ETH_SWA_SIZE; + debug("priv->tx_data_offset=%d\n", priv->tx_data_offset); + + return 0; + +err_data_offset: +err_buf_layout: +err_get_attr: + dpni_close(dflt_mc_io, priv->dpni_handle); +err_open: + return err; +} + +static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv) +{ + struct dpni_pools_cfg pools_params; + struct dpni_tx_flow_cfg dflt_tx_flow; + int err = 0; + + pools_params.num_dpbp = 1; + pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id; + pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE; + err = dpni_set_pools(dflt_mc_io, priv->dpni_handle, &pools_params); + if (err) { + printf("dpni_set_pools() failed\n"); + return err; + } + + priv->tx_flow_id = DPNI_NEW_FLOW_ID; + memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow)); + + err = dpni_set_tx_flow(dflt_mc_io, priv->dpni_handle, + &priv->tx_flow_id, &dflt_tx_flow); + if (err) { + printf("dpni_set_tx_flow() failed\n"); + return err; + } + + return 0; +} + +static int ldpaa_eth_netdev_init(struct eth_device *net_dev) +{ + int err; + struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; + + sprintf(net_dev->name, "DPNI%d", priv->dpni_id); + + net_dev->iobase = 0; + net_dev->init = ldpaa_eth_open; + net_dev->halt = ldpaa_eth_stop; + net_dev->send = ldpaa_eth_tx; + net_dev->recv = ldpaa_eth_pull_dequeue_rx; +/* + TODO: PHY MDIO information + priv->bus = info->bus; + priv->phyaddr = info->phy_addr; + priv->enet_if = info->enet_if; +*/ + + if (init_phy(net_dev)) + return 0; + + err = eth_register(net_dev); + if (err < 0) { + printf("eth_register() = %d\n", err); + return err; + } + + return 0; +} + +int ldpaa_eth_init(struct dprc_obj_desc obj_desc) +{ + struct eth_device *net_dev = NULL; + struct ldpaa_eth_priv *priv = NULL; + int err = 0; + + + /* Net device */ + net_dev = (struct eth_device *)malloc(sizeof(struct eth_device)); + if (!net_dev) { + printf("eth_device malloc() failed\n"); + return -ENOMEM; + } + memset(net_dev, 0, sizeof(struct eth_device)); + + /* alloc the ldpaa ethernet private struct */ + priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv)); + if (!priv) { + printf("ldpaa_eth_priv malloc() failed\n"); + return -ENOMEM; + } + memset(priv, 0, sizeof(struct ldpaa_eth_priv)); + + net_dev->priv = (void *)priv; + priv->net_dev = (struct eth_device *)net_dev; + priv->dpni_id = obj_desc.id; + + err = ldpaa_eth_netdev_init(net_dev); + if (err) + goto err_netdev_init; + + debug("ldpaa ethernet: Probed interface %s\n", net_dev->name); + return 0; + +err_netdev_init: + free(priv); + net_dev->priv = NULL; + free(net_dev); + + return err; +} diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.h b/drivers/net/ldpaa_eth/ldpaa_eth.h new file mode 100644 index 0000000..3107ab6 --- /dev/null +++ b/drivers/net/ldpaa_eth/ldpaa_eth.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __LDPAA_ETH_H +#define __LDPAA_ETH_H + +#include <linux/netdevice.h> +#include <fsl-mc/fsl_mc.h> +#include <fsl-mc/fsl_dpaa_fd.h> +#include <fsl-mc/fsl_dprc.h> +#include <fsl-mc/fsl_dpni.h> +#include <fsl-mc/fsl_dpbp.h> +#include <fsl-mc/fsl_dpio.h> +#include <fsl-mc/fsl_qbman_portal.h> +#include <fsl-mc/fsl_mc_private.h> + + +enum ldpaa_eth_type { + LDPAA_ETH_1G_E, + LDPAA_ETH_10G_E, +}; + +/* Arbitrary values for now, but we'll need to tune */ +#define LDPAA_ETH_NUM_BUFS (2 * 7) +#define LDPAA_ETH_REFILL_THRESH (LDPAA_ETH_NUM_BUFS/2) +#define LDPAA_ETH_RX_BUFFER_SIZE 2048 + +/* Hardware requires alignment for ingress/egress buffer addresses + * and ingress buffer lengths. + */ +#define LDPAA_ETH_BUF_ALIGN 64 + +/* So far we're only accomodating a skb backpointer in the frame's + * software annotation, but the hardware options are either 0 or 64. + */ +#define LDPAA_ETH_SWA_SIZE 64 + +/* Annotation valid bits in FD FRC */ +#define LDPAA_FD_FRC_FASV 0x8000 +#define LDPAA_FD_FRC_FAEADV 0x4000 +#define LDPAA_FD_FRC_FAPRV 0x2000 +#define LDPAA_FD_FRC_FAIADV 0x1000 +#define LDPAA_FD_FRC_FASWOV 0x0800 +#define LDPAA_FD_FRC_FAICFDV 0x0400 + +/* Annotation bits in FD CTRL */ +#define LDPAA_FD_CTRL_ASAL 0x00020000 /* ASAL = 128 */ +#define LDPAA_FD_CTRL_PTA 0x00800000 +#define LDPAA_FD_CTRL_PTV1 0x00400000 + +/* TODO: we may want to move this and other WRIOP related defines + * to a separate header + */ +/* Frame annotation status */ +struct ldpaa_fas { + u8 reserved; + u8 ppid; + __le16 ifpid; + __le32 status; +} __packed; + +/* Debug frame, otherwise supposed to be discarded */ +#define LDPAA_ETH_FAS_DISC 0x80000000 +/* MACSEC frame */ +#define LDPAA_ETH_FAS_MS 0x40000000 +#define LDPAA_ETH_FAS_PTP 0x08000000 +/* Ethernet multicast frame */ +#define LDPAA_ETH_FAS_MC 0x04000000 +/* Ethernet broadcast frame */ +#define LDPAA_ETH_FAS_BC 0x02000000 +#define LDPAA_ETH_FAS_KSE 0x00040000 +#define LDPAA_ETH_FAS_EOFHE 0x00020000 +#define LDPAA_ETH_FAS_MNLE 0x00010000 +#define LDPAA_ETH_FAS_TIDE 0x00008000 +#define LDPAA_ETH_FAS_PIEE 0x00004000 +/* Frame length error */ +#define LDPAA_ETH_FAS_FLE 0x00002000 +/* Frame physical error; our favourite pastime */ +#define LDPAA_ETH_FAS_FPE 0x00001000 +#define LDPAA_ETH_FAS_PTE 0x00000080 +#define LDPAA_ETH_FAS_ISP 0x00000040 +#define LDPAA_ETH_FAS_PHE 0x00000020 +#define LDPAA_ETH_FAS_BLE 0x00000010 +/* L3 csum validation performed */ +#define LDPAA_ETH_FAS_L3CV 0x00000008 +/* L3 csum error */ +#define LDPAA_ETH_FAS_L3CE 0x00000004 +/* L4 csum validation performed */ +#define LDPAA_ETH_FAS_L4CV 0x00000002 +/* L4 csum error */ +#define LDPAA_ETH_FAS_L4CE 0x00000001 +/* These bits always signal errors */ +#define LDPAA_ETH_RX_ERR_MASK (LDPAA_ETH_FAS_DISC | \ + LDPAA_ETH_FAS_KSE | \ + LDPAA_ETH_FAS_EOFHE | \ + LDPAA_ETH_FAS_MNLE | \ + LDPAA_ETH_FAS_TIDE | \ + LDPAA_ETH_FAS_PIEE | \ + LDPAA_ETH_FAS_FLE | \ + LDPAA_ETH_FAS_FPE | \ + LDPAA_ETH_FAS_PTE | \ + LDPAA_ETH_FAS_ISP | \ + LDPAA_ETH_FAS_PHE | \ + LDPAA_ETH_FAS_BLE | \ + LDPAA_ETH_FAS_L3CE | \ + LDPAA_ETH_FAS_L4CE) +/* Unsupported features in the ingress */ +#define LDPAA_ETH_RX_UNSUPP_MASK LDPAA_ETH_FAS_MS +/* TODO trim down the bitmask; not all of them apply to Tx-confirm */ +#define LDPAA_ETH_TXCONF_ERR_MASK (LDPAA_ETH_FAS_KSE | \ + LDPAA_ETH_FAS_EOFHE | \ + LDPAA_ETH_FAS_MNLE | \ + LDPAA_ETH_FAS_TIDE) + +struct ldpaa_eth_priv { + struct eth_device *net_dev; + int dpni_id; + uint16_t dpni_handle; + struct dpni_attr dpni_attrs; + /* Insofar as the MC is concerned, we're using one layout on all 3 types + * of buffers (Rx, Tx, Tx-Conf). + */ + struct dpni_buffer_layout buf_layout; + uint16_t tx_data_offset; + + uint32_t rx_dflt_fqid; + uint16_t tx_qdid; + uint32_t tx_conf_fqid; + uint16_t tx_flow_id; + + enum ldpaa_eth_type type; /* 1G or 10G ethernet */ + struct phy_device *phydev; +}; + +extern struct fsl_mc_io *dflt_mc_io; +extern struct fsl_dpbp_obj *dflt_dpbp; +extern struct fsl_dpio_obj *dflt_dpio; + +static void ldpaa_dpbp_drain_cnt(int count); +static void ldpaa_dpbp_drain(void); +static int ldpaa_dpbp_seed(uint16_t bpid); +static void ldpaa_dpbp_free(void); +static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv); +static int ldpaa_dpbp_setup(void); +static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv); +#endif /* __LDPAA_H */ diff --git a/drivers/net/ldpaa_eth/ldpaa_wriop.c b/drivers/net/ldpaa_eth/ldpaa_wriop.c new file mode 100644 index 0000000..926057a --- /dev/null +++ b/drivers/net/ldpaa_eth/ldpaa_wriop.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/types.h> +#include <malloc.h> +#include <net.h> +#include <linux/compat.h> +#include <asm/arch/fsl_serdes.h> +#include <fsl-mc/ldpaa_wriop.h> + +struct wriop_dpmac_info dpmac_info[NUM_WRIOP_PORTS]; + +__weak phy_interface_t wriop_dpmac_enet_if(int dpmac_id, int lane_prtc) +{ + return PHY_INTERFACE_MODE_NONE; +} + +void wriop_init_dpmac(int sd, int dpmac_id, int lane_prtcl) +{ + phy_interface_t enet_if; + int index = dpmac_id + sd * 8; + + dpmac_info[index].enabled = 0; + dpmac_info[index].id = 0; + dpmac_info[index].enet_if = PHY_INTERFACE_MODE_NONE; + + enet_if = wriop_dpmac_enet_if(index, lane_prtcl); + if (enet_if != PHY_INTERFACE_MODE_NONE) { + dpmac_info[index].enabled = 1; + dpmac_info[index].id = index; + dpmac_info[index].enet_if = enet_if; + } +} + +/*TODO what it do */ +static int wriop_dpmac_to_index(int dpmac_id) +{ + int i; + + for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { + if (dpmac_info[i].id == dpmac_id) + return i; + } + + return -1; +} + +void wriop_disable_dpmac(int dpmac_id) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return; + + dpmac_info[i].enabled = 0; + wriop_dpmac_disable(dpmac_id); +} + +void wriop_enable_dpmac(int dpmac_id) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return; + + dpmac_info[i].enabled = 1; + wriop_dpmac_enable(dpmac_id); +} + +void wriop_set_mdio(int dpmac_id, struct mii_dev *bus) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return; + + dpmac_info[i].bus = bus; +} + +struct mii_dev *wriop_get_mdio(int dpmac_id) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return NULL; + + return dpmac_info[i].bus; +} + +void wriop_set_phy_address(int dpmac_id, int address) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return; + + dpmac_info[i].phy_addr = address; +} + +int wriop_get_phy_address(int dpmac_id) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return -1; + + return dpmac_info[i].phy_addr; +} + +void wriop_set_phy_dev(int dpmac_id, struct phy_device *phydev) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return; + + dpmac_info[i].phydev = phydev; +} + +struct phy_device *wriop_get_phy_dev(int dpmac_id) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return NULL; + + return dpmac_info[i].phydev; +} + +phy_interface_t wriop_get_enet_if(int dpmac_id) +{ + int i = wriop_dpmac_to_index(dpmac_id); + + if (i == -1) + return PHY_INTERFACE_MODE_NONE; + + if (dpmac_info[i].enabled) + return dpmac_info[i].enet_if; + + return PHY_INTERFACE_MODE_NONE; +} diff --git a/drivers/net/ldpaa_eth/ls2085a.c b/drivers/net/ldpaa_eth/ls2085a.c new file mode 100644 index 0000000..6b7960a --- /dev/null +++ b/drivers/net/ldpaa_eth/ls2085a.c @@ -0,0 +1,83 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <phy.h> +#include <fsl-mc/ldpaa_wriop.h> +#include <asm/io.h> +#include <asm/arch-fsl-lsch3/immap_lsch3.h> +#include <asm/arch/fsl_serdes.h> +#include <fsl-mc/ldpaa_wriop.h> + +u32 dpmac_to_devdisr[] = { + [WRIOP1_DPMAC1] = FSL_CHASSIS3_DEVDISR2_DPMAC1, + [WRIOP1_DPMAC2] = FSL_CHASSIS3_DEVDISR2_DPMAC2, + [WRIOP1_DPMAC3] = FSL_CHASSIS3_DEVDISR2_DPMAC3, + [WRIOP1_DPMAC4] = FSL_CHASSIS3_DEVDISR2_DPMAC4, + [WRIOP1_DPMAC5] = FSL_CHASSIS3_DEVDISR2_DPMAC5, + [WRIOP1_DPMAC6] = FSL_CHASSIS3_DEVDISR2_DPMAC6, + [WRIOP1_DPMAC7] = FSL_CHASSIS3_DEVDISR2_DPMAC7, + [WRIOP1_DPMAC8] = FSL_CHASSIS3_DEVDISR2_DPMAC8, + [WRIOP1_DPMAC9] = FSL_CHASSIS3_DEVDISR2_DPMAC9, + [WRIOP1_DPMAC10] = FSL_CHASSIS3_DEVDISR2_DPMAC10, + [WRIOP1_DPMAC11] = FSL_CHASSIS3_DEVDISR2_DPMAC11, + [WRIOP1_DPMAC12] = FSL_CHASSIS3_DEVDISR2_DPMAC12, + [WRIOP1_DPMAC13] = FSL_CHASSIS3_DEVDISR2_DPMAC13, + [WRIOP1_DPMAC14] = FSL_CHASSIS3_DEVDISR2_DPMAC14, + [WRIOP1_DPMAC15] = FSL_CHASSIS3_DEVDISR2_DPMAC15, + [WRIOP1_DPMAC16] = FSL_CHASSIS3_DEVDISR2_DPMAC16, + [WRIOP1_DPMAC17] = FSL_CHASSIS3_DEVDISR2_DPMAC17, + [WRIOP1_DPMAC18] = FSL_CHASSIS3_DEVDISR2_DPMAC18, + [WRIOP1_DPMAC19] = FSL_CHASSIS3_DEVDISR2_DPMAC19, + [WRIOP1_DPMAC20] = FSL_CHASSIS3_DEVDISR2_DPMAC20, + [WRIOP1_DPMAC21] = FSL_CHASSIS3_DEVDISR2_DPMAC21, + [WRIOP1_DPMAC22] = FSL_CHASSIS3_DEVDISR2_DPMAC22, + [WRIOP1_DPMAC23] = FSL_CHASSIS3_DEVDISR2_DPMAC23, + [WRIOP1_DPMAC24] = FSL_CHASSIS3_DEVDISR2_DPMAC24, +}; + +static int is_device_disabled(int dpmac_id) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + u32 devdisr2 = in_le32(&gur->devdisr2); + + return dpmac_to_devdisr[dpmac_id] & devdisr2; +} + +void wriop_dpmac_disable(int dpmac_id) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + + setbits_le32(&gur->devdisr2, dpmac_to_devdisr[dpmac_id]); +} + +void wriop_dpmac_enable(int dpmac_id) +{ + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + + clrbits_le32(&gur->devdisr2, dpmac_to_devdisr[dpmac_id]); +} + +phy_interface_t wriop_dpmac_enet_if(int dpmac_id, int lane_prtcl) +{ + enum srds_prtcl; + + if (is_device_disabled(dpmac_id + 1)) + return PHY_INTERFACE_MODE_NONE; + + if (lane_prtcl >= SGMII1 && lane_prtcl <= SGMII16) + return PHY_INTERFACE_MODE_SGMII; + + if (lane_prtcl >= XFI1 && lane_prtcl <= XFI8) + return PHY_INTERFACE_MODE_XGMII; + + if (lane_prtcl >= XAUI1 && lane_prtcl <= XAUI2) + return PHY_INTERFACE_MODE_XGMII; + + if (lane_prtcl >= QSGMII_A && lane_prtcl <= QSGMII_D) + return PHY_INTERFACE_MODE_QSGMII; + + return PHY_INTERFACE_MODE_NONE; +} diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index fcadf0c..8dcbb4a 100644 --- a/drivers/net/lpc32xx_eth.c +++ b/drivers/net/lpc32xx_eth.c @@ -419,10 +419,12 @@ static int lpc32xx_eth_recv(struct eth_device *dev) rx_index = readl(®s->rxconsumeindex); /* if data was valid, pass it on */ - if (!(bufs->rx_stat[rx_index].statusinfo & RX_STAT_ERRORS)) - NetReceive(&(bufs->rx_buf[rx_index*PKTSIZE_ALIGN]), - (bufs->rx_stat[rx_index].statusinfo - & RX_STAT_RXSIZE) + 1); + if (!(bufs->rx_stat[rx_index].statusinfo & RX_STAT_ERRORS)) { + net_process_received_packet( + &(bufs->rx_buf[rx_index * PKTSIZE_ALIGN]), + (bufs->rx_stat[rx_index].statusinfo + & RX_STAT_RXSIZE) + 1); + } /* pass receive slot back to DMA engine */ rx_index = (rx_index + 1) % RX_BUF_COUNT; diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 170ff06..4e1a7fe 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -347,14 +347,14 @@ static int macb_recv(struct eth_device *netdev) headlen = 128 * (MACB_RX_RING_SIZE - macb->rx_tail); taillen = length - headlen; - memcpy((void *)NetRxPackets[0], + memcpy((void *)net_rx_packets[0], buffer, headlen); - memcpy((void *)NetRxPackets[0] + headlen, + memcpy((void *)net_rx_packets[0] + headlen, macb->rx_buffer, taillen); - buffer = (void *)NetRxPackets[0]; + buffer = (void *)net_rx_packets[0]; } - NetReceive(buffer, length); + net_process_received_packet(buffer, length); if (++rx_tail >= MACB_RX_RING_SIZE) rx_tail = 0; reclaim_rx_buffers(macb, rx_tail); @@ -595,7 +595,7 @@ static int macb_init(struct eth_device *netdev, bd_t *bd) } /* update the ethaddr */ - if (is_valid_ether_addr(netdev->enetaddr)) { + if (is_valid_ethaddr(netdev->enetaddr)) { macb_write_hwaddr(netdev); } else { printf("%s: mac address is not valid\n", netdev->name); diff --git a/drivers/net/mcffec.c b/drivers/net/mcffec.c index 7c4b210..fd73099 100644 --- a/drivers/net/mcffec.c +++ b/drivers/net/mcffec.c @@ -219,7 +219,8 @@ int fec_recv(struct eth_device *dev) length -= 4; /* Pass the packet up to the protocol layers. */ - NetReceive(NetRxPackets[info->rxIdx], length); + net_process_received_packet(net_rx_packets[info->rxIdx], + length); fecp->eir |= FEC_EIR_RXF; } @@ -477,7 +478,7 @@ int fec_init(struct eth_device *dev, bd_t * bd) for (i = 0; i < PKTBUFSRX; i++) { info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; info->rxbd[i].cbd_datlen = 0; /* Reset */ - info->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i]; + info->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i]; } info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; diff --git a/drivers/net/mpc512x_fec.c b/drivers/net/mpc512x_fec.c index 427e0b8..22ea114 100644 --- a/drivers/net/mpc512x_fec.c +++ b/drivers/net/mpc512x_fec.c @@ -591,7 +591,8 @@ static int mpc512x_fec_recv (struct eth_device *dev) rx_buff_idx = frame_length; if (pRbd->status & FEC_RBD_LAST) { - NetReceive ((uchar*)rx_buff, frame_length); + net_process_received_packet((uchar *)rx_buff, + frame_length); rx_buff_idx = 0; } } diff --git a/drivers/net/mpc5xxx_fec.c b/drivers/net/mpc5xxx_fec.c index d2a8ae0..2ebd176 100644 --- a/drivers/net/mpc5xxx_fec.c +++ b/drivers/net/mpc5xxx_fec.c @@ -859,7 +859,7 @@ static int mpc5xxx_fec_recv(struct eth_device *dev) */ memcpy(buff, frame->head, 14); memcpy(buff + 14, frame->data, frame_length); - NetReceive(buff, frame_length); + net_process_received_packet(buff, frame_length); len = frame_length; } /* diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c index 6b31a82..ab5aa68 100644 --- a/drivers/net/mvgbe.c +++ b/drivers/net/mvgbe.c @@ -66,12 +66,12 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data) /* check parameters */ if (phy_adr > PHYADR_MASK) { printf("Err..(%s) Invalid PHY address %d\n", - __FUNCTION__, phy_adr); + __func__, phy_adr); return -EFAULT; } if (reg_ofs > PHYREG_MASK) { printf("Err..(%s) Invalid register offset %d\n", - __FUNCTION__, reg_ofs); + __func__, reg_ofs); return -EFAULT; } @@ -81,7 +81,7 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data) /* read smi register */ smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG); if (timeout-- == 0) { - printf("Err..(%s) SMI busy timeout\n", __FUNCTION__); + printf("Err..(%s) SMI busy timeout\n", __func__); return -EFAULT; } } while (smi_reg & MVGBE_PHY_SMI_BUSY_MASK); @@ -102,7 +102,7 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data) smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG); if (timeout-- == 0) { printf("Err..(%s) SMI read ready timeout\n", - __FUNCTION__); + __func__); return -EFAULT; } } while (!(smi_reg & MVGBE_PHY_SMI_READ_VALID_MASK)); @@ -113,8 +113,8 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data) *data = (u16) (MVGBE_REG_RD(MVGBE_SMI_REG) & MVGBE_PHY_SMI_DATA_MASK); - debug("%s:(adr %d, off %d) value= %04x\n", __FUNCTION__, phy_adr, - reg_ofs, *data); + debug("%s:(adr %d, off %d) value= %04x\n", __func__, phy_adr, reg_ofs, + *data); return 0; } @@ -142,11 +142,11 @@ static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data) /* check parameters */ if (phy_adr > PHYADR_MASK) { - printf("Err..(%s) Invalid phy address\n", __FUNCTION__); + printf("Err..(%s) Invalid phy address\n", __func__); return -EINVAL; } if (reg_ofs > PHYREG_MASK) { - printf("Err..(%s) Invalid register offset\n", __FUNCTION__); + printf("Err..(%s) Invalid register offset\n", __func__); return -EINVAL; } @@ -156,7 +156,7 @@ static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data) /* read smi register */ smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG); if (timeout-- == 0) { - printf("Err..(%s) SMI busy timeout\n", __FUNCTION__); + printf("Err..(%s) SMI busy timeout\n", __func__); return -ETIME; } } while (smi_reg & MVGBE_PHY_SMI_BUSY_MASK); @@ -583,7 +583,7 @@ static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize) if ((cmd_sts & (MVGBE_ERROR_SUMMARY | MVGBE_TX_LAST_FRAME)) == (MVGBE_ERROR_SUMMARY | MVGBE_TX_LAST_FRAME) && cmd_sts & (MVGBE_UR_ERROR | MVGBE_RL_ERROR)) { - printf("Err..(%s) in xmit packet\n", __FUNCTION__); + printf("Err..(%s) in xmit packet\n", __func__); return -1; } cmd_sts = readl(&p_txdesc->cmd_sts); @@ -604,14 +604,14 @@ static int mvgbe_recv(struct eth_device *dev) if (timeout < MVGBE_PHY_SMI_TIMEOUT) timeout++; else { - debug("%s time out...\n", __FUNCTION__); + debug("%s time out...\n", __func__); return -1; } } while (readl(&p_rxdesc_curr->cmd_sts) & MVGBE_BUFFER_OWNED_BY_DMA); if (p_rxdesc_curr->byte_cnt != 0) { debug("%s: Received %d byte Packet @ 0x%x (cmd_sts= %08x)\n", - __FUNCTION__, (u32) p_rxdesc_curr->byte_cnt, + __func__, (u32) p_rxdesc_curr->byte_cnt, (u32) p_rxdesc_curr->buf_ptr, (u32) p_rxdesc_curr->cmd_sts); } @@ -628,21 +628,24 @@ static int mvgbe_recv(struct eth_device *dev) != (MVGBE_RX_FIRST_DESC | MVGBE_RX_LAST_DESC)) { printf("Err..(%s) Dropping packet spread on" - " multiple descriptors\n", __FUNCTION__); + " multiple descriptors\n", __func__); } else if (cmd_sts & MVGBE_ERROR_SUMMARY) { printf("Err..(%s) Dropping packet with errors\n", - __FUNCTION__); + __func__); } else { /* !!! call higher layer processing */ debug("%s: Sending Received packet to" - " upper layer (NetReceive)\n", __FUNCTION__); + " upper layer (net_process_received_packet)\n", + __func__); /* let the upper layer handle the packet */ - NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET), - (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET)); + net_process_received_packet((p_rxdesc_curr->buf_ptr + + RX_BUF_OFFSET), + (int)(p_rxdesc_curr->byte_cnt - + RX_BUF_OFFSET)); } /* * free these descriptors and point next in the ring @@ -747,7 +750,7 @@ error2: free(dmvgbe); error1: printf("Err.. %s Failed to allocate memory\n", - __FUNCTION__); + __func__); return -1; } @@ -767,7 +770,7 @@ error1: #endif default: /* this should never happen */ printf("Err..(%s) Invalid device number %d\n", - __FUNCTION__, devnum); + __func__, devnum); return -1; } diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c index a2a69b4..efaae16 100644 --- a/drivers/net/mvneta.c +++ b/drivers/net/mvneta.c @@ -1572,7 +1572,7 @@ static int mvneta_recv(struct eth_device *dev) * No cache invalidation needed here, since the rx_buffer's are * located in a uncached memory region */ - NetReceive(data, rx_bytes); + net_process_received_packet(data, rx_bytes); } /* Update rxq management counters */ diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 04743bd..0ed9bb5 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -841,7 +841,8 @@ natsemi_poll(struct eth_device *dev) rx_status); retstat = 0; } else { /* give packet to higher level routine */ - NetReceive((rxb + cur_rx * RX_BUF_SIZE), length); + net_process_received_packet((rxb + cur_rx * RX_BUF_SIZE), + length); retstat = 1; } diff --git a/drivers/net/ne2000_base.c b/drivers/net/ne2000_base.c index ef35922..07a7cec 100644 --- a/drivers/net/ne2000_base.c +++ b/drivers/net/ne2000_base.c @@ -665,7 +665,7 @@ void uboot_push_packet_len(int len) { dp83902a_recv(&pbuf[0], len); /*Just pass it to the upper layer*/ - NetReceive(&pbuf[0], len); + net_process_received_packet(&pbuf[0], len); } void uboot_push_tx_done(int key, int val) { diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 677c89f..31042a6 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -23,7 +23,7 @@ static int input_recursion; static int output_recursion; static int net_timeout; static uchar nc_ether[6]; /* server enet address */ -static IPaddr_t nc_ip; /* server ip */ +static struct in_addr nc_ip; /* server ip */ 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 */ @@ -35,42 +35,43 @@ static int output_packet_len; enum proto_t net_loop_last_protocol = BOOTP; static void nc_wait_arp_handler(uchar *pkt, unsigned dest, - IPaddr_t sip, unsigned src, + struct in_addr sip, unsigned src, unsigned len) { net_set_state(NETLOOP_SUCCESS); /* got arp reply - quit net loop */ } -static void nc_handler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, - unsigned len) +static void nc_handler(uchar *pkt, unsigned dest, struct in_addr sip, + unsigned src, unsigned len) { if (input_size) net_set_state(NETLOOP_SUCCESS); /* got input - quit net loop */ } -static void nc_timeout(void) +static void nc_timeout_handler(void) { net_set_state(NETLOOP_SUCCESS); } -static int is_broadcast(IPaddr_t ip) +static int is_broadcast(struct in_addr ip) { - static IPaddr_t netmask; - static IPaddr_t our_ip; + static struct in_addr netmask; + static struct in_addr 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"); + netmask = getenv_ip("netmask"); + our_ip = getenv_ip("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 */ + return (ip.s_addr == ~0 || /* 255.255.255.255 (global bcast) */ + ((netmask.s_addr & our_ip.s_addr) == + (netmask.s_addr & ip.s_addr) && /* on the same net and */ + (netmask.s_addr | ip.s_addr) == ~0)); /* bcast to our net */ } static int refresh_settings_from_env(void) @@ -82,16 +83,17 @@ static int refresh_settings_from_env(void) /* update only when the environment has changed */ if (env_changed_id != env_id) { if (getenv("ncip")) { - nc_ip = getenv_IPaddr("ncip"); - if (!nc_ip) + nc_ip = getenv_ip("ncip"); + if (!nc_ip.s_addr) 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 */ + } else { + nc_ip.s_addr = ~0; /* ncip is not set, so broadcast */ + } p = getenv("ncoutport"); if (p != NULL) @@ -111,27 +113,28 @@ static int refresh_settings_from_env(void) } /** - * Called from NetLoop in net/net.c before each packet + * Called from net_loop in net/net.c before each packet */ -void NcStart(void) +void nc_start(void) { refresh_settings_from_env(); - if (!output_packet_len || memcmp(nc_ether, NetEtherNullAddr, 6)) { + if (!output_packet_len || memcmp(nc_ether, net_null_ethaddr, 6)) { /* going to check for input packet */ net_set_udp_handler(nc_handler); - NetSetTimeout(net_timeout, nc_timeout); + net_set_timeout_handler(net_timeout, nc_timeout_handler); } else { /* send arp request */ uchar *pkt; net_set_arp_handler(nc_wait_arp_handler); - pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; + pkt = (uchar *)net_tx_packet + net_eth_hdr_size() + + IP_UDP_HDR_SIZE; memcpy(pkt, output_packet, output_packet_len); - NetSendUDPPacket(nc_ether, nc_ip, nc_out_port, nc_in_port, - output_packet_len); + net_send_udp_packet(nc_ether, nc_ip, nc_out_port, nc_in_port, + output_packet_len); } } -int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, +int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port, unsigned src_port, unsigned len) { int end, chunk; @@ -139,7 +142,7 @@ int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, if (dest_port != nc_in_port || !len) return 0; /* not for us */ - if (src_ip != nc_ip && !is_broadcast(nc_ip)) + if (src_ip.s_addr != nc_ip.s_addr && !is_broadcast(nc_ip)) return 0; /* not from our client */ debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt); @@ -171,7 +174,7 @@ static void nc_send_packet(const char *buf, int len) int inited = 0; uchar *pkt; uchar *ether; - IPaddr_t ip; + struct in_addr ip; debug_cond(DEBUG_DEV_PKT, "output: \"%*.*s\"\n", len, len, buf); @@ -179,13 +182,13 @@ static void nc_send_packet(const char *buf, int len) if (eth == NULL) return; - if (!memcmp(nc_ether, NetEtherNullAddr, 6)) { + if (!memcmp(nc_ether, net_null_ethaddr, 6)) { if (eth->state == ETH_STATE_ACTIVE) return; /* inside net loop */ output_packet = buf; output_packet_len = len; input_recursion = 1; - NetLoop(NETCONS); /* wait for arp reply and send packet */ + net_loop(NETCONS); /* wait for arp reply and send packet */ input_recursion = 0; output_packet_len = 0; return; @@ -193,19 +196,20 @@ static void nc_send_packet(const char *buf, int len) if (eth->state != ETH_STATE_ACTIVE) { if (eth_is_on_demand_init()) { - if (eth_init(gd->bd) < 0) + if (eth_init() < 0) return; eth_set_last_protocol(NETCONS); - } else - eth_init_state_only(gd->bd); + } else { + eth_init_state_only(); + } inited = 1; } - pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; + pkt = (uchar *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE; memcpy(pkt, buf, len); ether = nc_ether; ip = nc_ip; - NetSendUDPPacket(ether, ip, nc_out_port, nc_in_port, len); + net_send_udp_packet(ether, ip, nc_out_port, nc_in_port, len); if (inited) { if (eth_is_on_demand_init()) @@ -215,7 +219,7 @@ static void nc_send_packet(const char *buf, int len) } } -static int nc_start(struct stdio_dev *dev) +static int nc_stdio_start(struct stdio_dev *dev) { int retval; @@ -228,14 +232,14 @@ static int nc_start(struct stdio_dev *dev) /* * Initialize the static IP settings and buffer pointers - * incase we call NetSendUDPPacket before NetLoop + * incase we call net_send_udp_packet before net_loop */ net_init(); return 0; } -static void nc_putc(struct stdio_dev *dev, char c) +static void nc_stdio_putc(struct stdio_dev *dev, char c) { if (output_recursion) return; @@ -246,7 +250,7 @@ static void nc_putc(struct stdio_dev *dev, char c) output_recursion = 0; } -static void nc_puts(struct stdio_dev *dev, const char *s) +static void nc_stdio_puts(struct stdio_dev *dev, const char *s) { int len; @@ -265,7 +269,7 @@ static void nc_puts(struct stdio_dev *dev, const char *s) output_recursion = 0; } -static int nc_getc(struct stdio_dev *dev) +static int nc_stdio_getc(struct stdio_dev *dev) { uchar c; @@ -273,7 +277,7 @@ static int nc_getc(struct stdio_dev *dev) net_timeout = 0; /* no timeout */ while (!input_size) - NetLoop(NETCONS); + net_loop(NETCONS); input_recursion = 0; @@ -286,7 +290,7 @@ static int nc_getc(struct stdio_dev *dev) return c; } -static int nc_tstc(struct stdio_dev *dev) +static int nc_stdio_tstc(struct stdio_dev *dev) { struct eth_device *eth; @@ -303,7 +307,7 @@ static int nc_tstc(struct stdio_dev *dev) input_recursion = 1; net_timeout = 1; - NetLoop(NETCONS); /* kind of poll */ + net_loop(NETCONS); /* kind of poll */ input_recursion = 0; @@ -319,11 +323,11 @@ int drv_nc_init(void) strcpy(dev.name, "nc"); dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; - dev.start = nc_start; - dev.putc = nc_putc; - dev.puts = nc_puts; - dev.getc = nc_getc; - dev.tstc = nc_tstc; + dev.start = nc_stdio_start; + dev.putc = nc_stdio_putc; + dev.puts = nc_stdio_puts; + dev.getc = nc_stdio_getc; + dev.tstc = nc_stdio_tstc; rc = stdio_register(&dev); diff --git a/drivers/net/ns8382x.c b/drivers/net/ns8382x.c index cfe1f34..f941c15 100644 --- a/drivers/net/ns8382x.c +++ b/drivers/net/ns8382x.c @@ -809,11 +809,13 @@ ns8382x_poll(struct eth_device *dev) if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) { /* corrupted packet received */ - printf("ns8382x_poll: Corrupted packet, status:%lx\n", rx_status); + printf("ns8382x_poll: Corrupted packet, status:%lx\n", + rx_status); retstat = 0; } else { /* give packet to higher level routine */ - NetReceive((rxb + cur_rx * RX_BUF_SIZE), length); + net_process_received_packet((rxb + cur_rx * RX_BUF_SIZE), + length); retstat = 1; } diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c index 976848d..a03bdc0 100644 --- a/drivers/net/pch_gbe.c +++ b/drivers/net/pch_gbe.c @@ -297,7 +297,7 @@ static int pch_gbe_recv(struct eth_device *dev) buffer_addr = pci_mem_to_phys(priv->bdf, rx_desc->buffer_addr); length = rx_desc->rx_words_eob - 3 - ETH_FCS_LEN; - NetReceive((uchar *)buffer_addr, length); + net_process_received_packet((uchar *)buffer_addr, length); /* Test the wrap-around condition */ if (++priv->rx_idx >= PCH_GBE_DESC_NUM) @@ -446,7 +446,7 @@ int pch_gbe_register(bd_t *bis) dev->iobase = iobase; priv->mac_regs = (struct pch_gbe_regs *)iobase; - sprintf(dev->name, "pch_gbe.%x", iobase); + sprintf(dev->name, "pch_gbe"); /* Read MAC address from SROM and initialize dev->enetaddr with it */ pch_gbe_mac_read(priv->mac_regs, dev->enetaddr); diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 237fbba..cfcb1b4 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -507,7 +507,7 @@ static int pcnet_recv (struct eth_device *dev) buf = (*lp->rx_buf)[lp->cur_rx]; invalidate_dcache_range((unsigned long)buf, (unsigned long)buf + pkt_len); - NetReceive(buf, pkt_len); + net_process_received_packet(buf, pkt_len); PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n", lp->cur_rx, pkt_len, buf); } diff --git a/drivers/net/phy/cortina.c b/drivers/net/phy/cortina.c index 254f056..3a2b3bb 100644 --- a/drivers/net/phy/cortina.c +++ b/drivers/net/phy/cortina.c @@ -186,8 +186,8 @@ void cs4340_upload_firmware(struct phy_device *phydev) while (*addr != 0x0a) { line_temp[i++] = *addr++; if (0x50 < i) { - printf("Not found Cortina PHY ucode at 0x%x\n", - CONFIG_CORTINA_FW_ADDR); + printf("Not found Cortina PHY ucode at 0x%p\n", + (char *)CONFIG_CORTINA_FW_ADDR); return; } } diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 1815b29..49f444a 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -22,6 +22,16 @@ static struct phy_driver KSZ804_driver = { .shutdown = &genphy_shutdown, }; +static struct phy_driver KSZ8081_driver = { + .name = "Micrel KSZ8081", + .uid = 0x221560, + .mask = 0xfffff0, + .features = PHY_BASIC_FEATURES, + .config = &genphy_config, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + /** * KSZ8895 */ @@ -272,6 +282,7 @@ static struct phy_driver ksz9031_driver = { int phy_micrel_init(void) { phy_register(&KSZ804_driver); + phy_register(&KSZ8081_driver); #ifdef CONFIG_PHY_MICREL_KSZ9021 phy_register(&ksz9021_driver); #else diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index df7e945..f5221a3 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -11,6 +11,7 @@ #include <config.h> #include <common.h> +#include <dm.h> #include <malloc.h> #include <net.h> #include <command.h> @@ -581,7 +582,7 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr, * Description: Reads the ID registers of the PHY at @addr on the * @bus, stores it in @phy_id and returns zero on success. */ -static int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id) +int __weak get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id) { int phy_reg; @@ -754,7 +755,11 @@ struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask, return get_phy_device_by_mask(bus, phy_mask, interface); } +#ifdef CONFIG_DM_ETH +void phy_connect_dev(struct phy_device *phydev, struct udevice *dev) +#else void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev) +#endif { /* Soft Reset the PHY */ phy_reset(phydev); @@ -767,8 +772,13 @@ void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev) debug("%s connected to %s\n", dev->name, phydev->drv->name); } +#ifdef CONFIG_DM_ETH +struct phy_device *phy_connect(struct mii_dev *bus, int addr, + struct udevice *dev, phy_interface_t interface) +#else struct phy_device *phy_connect(struct mii_dev *bus, int addr, struct eth_device *dev, phy_interface_t interface) +#endif { struct phy_device *phydev; @@ -813,3 +823,15 @@ int phy_shutdown(struct phy_device *phydev) return 0; } + +int phy_get_interface_by_name(const char *str) +{ + int i; + + for (i = 0; i < PHY_INTERFACE_MODE_COUNT; i++) { + if (!strcmp(str, phy_interface_strings[i])) + return i; + } + + return -1; +} diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index a3ace68..ee97079 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: GPL-2.0+ * - * Copyright 2010-2011 Freescale Semiconductor, Inc. + * Copyright 2010-2011, 2015 Freescale Semiconductor, Inc. * author Andy Fleming */ #include <config.h> @@ -21,12 +21,28 @@ #define MIIM_RTL8211x_PHYSTAT_SPDDONE 0x0800 #define MIIM_RTL8211x_PHYSTAT_LINK 0x0400 +/* RTL8211x PHY Interrupt Enable Register */ +#define MIIM_RTL8211x_PHY_INER 0x12 +#define MIIM_RTL8211x_PHY_INTR_ENA 0x9f01 +#define MIIM_RTL8211x_PHY_INTR_DIS 0x0000 + +/* RTL8211x PHY Interrupt Status Register */ +#define MIIM_RTL8211x_PHY_INSR 0x13 /* RealTek RTL8211x */ static int rtl8211x_config(struct phy_device *phydev) { phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); + /* mask interrupt at init; if the interrupt is + * needed indeed, it should be explicitly enabled + */ + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER, + MIIM_RTL8211x_PHY_INTR_DIS); + + /* read interrupt status just to clear it */ + phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER); + genphy_config_aneg(phydev); return 0; diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 208ce5c..ea52343 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -504,11 +504,11 @@ static int rtl_poll(struct eth_device *dev) memcpy(rxdata, rx_ring + ring_offs + 4, semi_count); memcpy(&(rxdata[semi_count]), rx_ring, rx_size-4-semi_count); - NetReceive(rxdata, length); + net_process_received_packet(rxdata, length); debug_cond(DEBUG_RX, "rx packet %d+%d bytes", semi_count, rx_size-4-semi_count); } else { - NetReceive(rx_ring + ring_offs + 4, length); + net_process_received_packet(rx_ring + ring_offs + 4, length); debug_cond(DEBUG_RX, "rx packet %d bytes", rx_size-4); } flush_cache((unsigned long)rx_ring, RX_BUF_LEN); diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index cea6701..958488c 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -55,7 +55,7 @@ #define drv_version "v1.5" #define drv_date "01-17-2004" -static u32 ioaddr; +static unsigned long ioaddr; /* Condensed operations for readability. */ #define currticks() get_timer(0) @@ -92,19 +92,21 @@ static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; #define TX_TIMEOUT (6*HZ) /* write/read MMIO register. Notice: {read,write}[wl] do the necessary swapping */ -#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) -#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) -#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) -#define RTL_R8(reg) readb (ioaddr + (reg)) -#define RTL_R16(reg) readw (ioaddr + (reg)) -#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) +#define RTL_W8(reg, val8) writeb((val8), ioaddr + (reg)) +#define RTL_W16(reg, val16) writew((val16), ioaddr + (reg)) +#define RTL_W32(reg, val32) writel((val32), ioaddr + (reg)) +#define RTL_R8(reg) readb(ioaddr + (reg)) +#define RTL_R16(reg) readw(ioaddr + (reg)) +#define RTL_R32(reg) readl(ioaddr + (reg)) #define ETH_FRAME_LEN MAX_ETH_FRAME_SIZE #define ETH_ALEN MAC_ADDR_LEN #define ETH_ZLEN 60 -#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, (pci_addr_t)a) -#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, (phys_addr_t)a) +#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)(unsigned long)dev->priv, \ + (pci_addr_t)(unsigned long)a) +#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)(unsigned long)dev->priv, \ + (phys_addr_t)a) enum RTL8169_registers { MAC0 = 0, /* Ethernet hardware address. */ @@ -538,7 +540,7 @@ static int rtl_recv(struct eth_device *dev) cpu_to_le32(bus_to_phys(tpc->RxBufferRing[cur_rx])); rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]); - NetReceive(rxdata, length); + net_process_received_packet(rxdata, length); } else { puts("Error Rx"); } @@ -852,7 +854,7 @@ static int rtl_init(struct eth_device *dev, bd_t *bis) #ifdef DEBUG_RTL8169 /* Print out some hardware info */ - printf("%s: at ioaddr 0x%x\n", dev->name, ioaddr); + printf("%s: at ioaddr 0x%lx\n", dev->name, ioaddr); #endif /* if TBI is not endbled */ @@ -1004,7 +1006,7 @@ int rtl8169_initialize(bd_t *bis) memset(dev, 0, sizeof(*dev)); sprintf (dev->name, "RTL8169#%d", card_number); - dev->priv = (void *) devno; + dev->priv = (void *)(unsigned long)devno; dev->iobase = (int)pci_mem_to_phys(devno, iobase); dev->init = rtl_reset; diff --git a/drivers/net/sandbox-raw.c b/drivers/net/sandbox-raw.c new file mode 100644 index 0000000..45c3b18 --- /dev/null +++ b/drivers/net/sandbox-raw.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2015 National Instruments + * + * (C) Copyright 2015 + * Joe Hershberger <joe.hershberger@ni.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <asm/eth-raw-os.h> +#include <common.h> +#include <dm.h> +#include <malloc.h> +#include <net.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int reply_arp; +static struct in_addr arp_ip; + +static int sb_eth_raw_start(struct udevice *dev) +{ + struct eth_sandbox_raw_priv *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + const char *interface; + + debug("eth_sandbox_raw: Start\n"); + + interface = fdt_getprop(gd->fdt_blob, dev->of_offset, + "host-raw-interface", NULL); + if (interface == NULL) + return -EINVAL; + + if (strcmp(interface, "lo") == 0) { + priv->local = 1; + setenv("ipaddr", "127.0.0.1"); + setenv("serverip", "127.0.0.1"); + } + return sandbox_eth_raw_os_start(interface, pdata->enetaddr, priv); +} + +static int sb_eth_raw_send(struct udevice *dev, void *packet, int length) +{ + struct eth_sandbox_raw_priv *priv = dev_get_priv(dev); + + debug("eth_sandbox_raw: Send packet %d\n", length); + + if (priv->local) { + struct ethernet_hdr *eth = packet; + + if (ntohs(eth->et_protlen) == PROT_ARP) { + struct arp_hdr *arp = packet + ETHER_HDR_SIZE; + + /** + * localhost works on a higher-level API in Linux than + * ARP packets, so fake it + */ + arp_ip = net_read_ip(&arp->ar_tpa); + reply_arp = 1; + return 0; + } + packet += ETHER_HDR_SIZE; + length -= ETHER_HDR_SIZE; + } + return sandbox_eth_raw_os_send(packet, length, priv); +} + +static int sb_eth_raw_recv(struct udevice *dev, uchar **packetp) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct eth_sandbox_raw_priv *priv = dev_get_priv(dev); + int retval = 0; + int length; + + if (reply_arp) { + struct arp_hdr *arp = (void *)net_rx_packets[0] + + ETHER_HDR_SIZE; + + /* + * Fake an ARP response. The u-boot network stack is sending an + * ARP request (to find the MAC address to address the actual + * packet to) and requires an ARP response to continue. Since + * this is the localhost interface, there is no Etherent level + * traffic at all, so there is no way to send an ARP request or + * to get a response. For this reason we fake the response to + * make the u-boot network stack happy. + */ + arp->ar_hrd = htons(ARP_ETHER); + arp->ar_pro = htons(PROT_IP); + arp->ar_hln = ARP_HLEN; + arp->ar_pln = ARP_PLEN; + arp->ar_op = htons(ARPOP_REPLY); + /* Any non-zero MAC address will work */ + memset(&arp->ar_sha, 0x01, ARP_HLEN); + /* Use whatever IP we were looking for (always 127.0.0.1?) */ + net_write_ip(&arp->ar_spa, arp_ip); + memcpy(&arp->ar_tha, pdata->enetaddr, ARP_HLEN); + net_write_ip(&arp->ar_tpa, net_ip); + length = ARP_HDR_SIZE; + } else { + /* If local, the Ethernet header won't be included; skip it */ + uchar *pktptr = priv->local ? + net_rx_packets[0] + ETHER_HDR_SIZE : net_rx_packets[0]; + + retval = sandbox_eth_raw_os_recv(pktptr, &length, priv); + } + + if (!retval && length) { + if (priv->local) { + struct ethernet_hdr *eth = (void *)net_rx_packets[0]; + + /* Fill in enough of the missing Ethernet header */ + memcpy(eth->et_dest, pdata->enetaddr, ARP_HLEN); + memset(eth->et_src, 0x01, ARP_HLEN); + eth->et_protlen = htons(reply_arp ? PROT_ARP : PROT_IP); + reply_arp = 0; + length += ETHER_HDR_SIZE; + } + + debug("eth_sandbox_raw: received packet %d\n", + length); + *packetp = net_rx_packets[0]; + return length; + } + return retval; +} + +static void sb_eth_raw_stop(struct udevice *dev) +{ + struct eth_sandbox_raw_priv *priv = dev_get_priv(dev); + + debug("eth_sandbox_raw: Stop\n"); + + sandbox_eth_raw_os_stop(priv); +} + +static const struct eth_ops sb_eth_raw_ops = { + .start = sb_eth_raw_start, + .send = sb_eth_raw_send, + .recv = sb_eth_raw_recv, + .stop = sb_eth_raw_stop, +}; + +static int sb_eth_raw_ofdata_to_platdata(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + + pdata->iobase = dev_get_addr(dev); + return 0; +} + +static const struct udevice_id sb_eth_raw_ids[] = { + { .compatible = "sandbox,eth-raw" }, + { } +}; + +U_BOOT_DRIVER(eth_sandbox_raw) = { + .name = "eth_sandbox_raw", + .id = UCLASS_ETH, + .of_match = sb_eth_raw_ids, + .ofdata_to_platdata = sb_eth_raw_ofdata_to_platdata, + .ops = &sb_eth_raw_ops, + .priv_auto_alloc_size = sizeof(struct eth_sandbox_raw_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), +}; diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c new file mode 100644 index 0000000..e239ff4 --- /dev/null +++ b/drivers/net/sandbox.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2015 National Instruments + * + * (C) Copyright 2015 + * Joe Hershberger <joe.hershberger@ni.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <malloc.h> +#include <net.h> + +DECLARE_GLOBAL_DATA_PTR; + +/** + * struct eth_sandbox_priv - memory for sandbox mock driver + * + * fake_host_hwaddr: MAC address of mocked machine + * fake_host_ipaddr: IP address of mocked machine + * recv_packet_buffer: buffer of the packet returned as received + * recv_packet_length: length of the packet returned as received + */ +struct eth_sandbox_priv { + uchar fake_host_hwaddr[ARP_HLEN]; + struct in_addr fake_host_ipaddr; + uchar *recv_packet_buffer; + int recv_packet_length; +}; + +static bool disabled[8] = {false}; + +/* + * sandbox_eth_disable_response() + * + * index - The alias index (also DM seq number) + * disable - If non-zero, ignore sent packets and don't send mock response + */ +void sandbox_eth_disable_response(int index, bool disable) +{ + disabled[index] = disable; +} + +static int sb_eth_start(struct udevice *dev) +{ + struct eth_sandbox_priv *priv = dev_get_priv(dev); + + debug("eth_sandbox: Start\n"); + + fdtdec_get_byte_array(gd->fdt_blob, dev->of_offset, "fake-host-hwaddr", + priv->fake_host_hwaddr, ARP_HLEN); + priv->recv_packet_buffer = net_rx_packets[0]; + return 0; +} + +static int sb_eth_send(struct udevice *dev, void *packet, int length) +{ + struct eth_sandbox_priv *priv = dev_get_priv(dev); + struct ethernet_hdr *eth = packet; + + debug("eth_sandbox: Send packet %d\n", length); + + if (dev->seq >= 0 && dev->seq < ARRAY_SIZE(disabled) && + disabled[dev->seq]) + return 0; + + if (ntohs(eth->et_protlen) == PROT_ARP) { + struct arp_hdr *arp = packet + ETHER_HDR_SIZE; + + if (ntohs(arp->ar_op) == ARPOP_REQUEST) { + struct ethernet_hdr *eth_recv; + struct arp_hdr *arp_recv; + + /* store this as the assumed IP of the fake host */ + priv->fake_host_ipaddr = net_read_ip(&arp->ar_tpa); + /* Formulate a fake response */ + eth_recv = (void *)priv->recv_packet_buffer; + memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN); + memcpy(eth_recv->et_src, priv->fake_host_hwaddr, + ARP_HLEN); + eth_recv->et_protlen = htons(PROT_ARP); + + arp_recv = (void *)priv->recv_packet_buffer + + ETHER_HDR_SIZE; + arp_recv->ar_hrd = htons(ARP_ETHER); + arp_recv->ar_pro = htons(PROT_IP); + arp_recv->ar_hln = ARP_HLEN; + arp_recv->ar_pln = ARP_PLEN; + arp_recv->ar_op = htons(ARPOP_REPLY); + memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, + ARP_HLEN); + net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr); + memcpy(&arp_recv->ar_tha, &arp->ar_sha, ARP_HLEN); + net_copy_ip(&arp_recv->ar_tpa, &arp->ar_spa); + + priv->recv_packet_length = ETHER_HDR_SIZE + + ARP_HDR_SIZE; + } + } else if (ntohs(eth->et_protlen) == PROT_IP) { + struct ip_udp_hdr *ip = packet + ETHER_HDR_SIZE; + + if (ip->ip_p == IPPROTO_ICMP) { + struct icmp_hdr *icmp = (struct icmp_hdr *)&ip->udp_src; + + if (icmp->type == ICMP_ECHO_REQUEST) { + struct ethernet_hdr *eth_recv; + struct ip_udp_hdr *ipr; + struct icmp_hdr *icmpr; + + /* reply to the ping */ + memcpy(priv->recv_packet_buffer, packet, + length); + eth_recv = (void *)priv->recv_packet_buffer; + ipr = (void *)priv->recv_packet_buffer + + ETHER_HDR_SIZE; + icmpr = (struct icmp_hdr *)&ipr->udp_src; + memcpy(eth_recv->et_dest, eth->et_src, + ARP_HLEN); + memcpy(eth_recv->et_src, priv->fake_host_hwaddr, + ARP_HLEN); + ipr->ip_sum = 0; + ipr->ip_off = 0; + net_copy_ip((void *)&ipr->ip_dst, &ip->ip_src); + net_write_ip((void *)&ipr->ip_src, + priv->fake_host_ipaddr); + ipr->ip_sum = compute_ip_checksum(ipr, + IP_HDR_SIZE); + + icmpr->type = ICMP_ECHO_REPLY; + icmpr->checksum = 0; + icmpr->checksum = compute_ip_checksum(icmpr, + ICMP_HDR_SIZE); + + priv->recv_packet_length = length; + } + } + } + + return 0; +} + +static int sb_eth_recv(struct udevice *dev, uchar **packetp) +{ + struct eth_sandbox_priv *priv = dev_get_priv(dev); + + if (priv->recv_packet_length) { + int lcl_recv_packet_length = priv->recv_packet_length; + + debug("eth_sandbox: received packet %d\n", + priv->recv_packet_length); + priv->recv_packet_length = 0; + *packetp = priv->recv_packet_buffer; + return lcl_recv_packet_length; + } + return 0; +} + +static void sb_eth_stop(struct udevice *dev) +{ + debug("eth_sandbox: Stop\n"); +} + +static int sb_eth_write_hwaddr(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + + debug("eth_sandbox %s: Write HW ADDR - %pM\n", dev->name, + pdata->enetaddr); + return 0; +} + +static const struct eth_ops sb_eth_ops = { + .start = sb_eth_start, + .send = sb_eth_send, + .recv = sb_eth_recv, + .stop = sb_eth_stop, + .write_hwaddr = sb_eth_write_hwaddr, +}; + +static int sb_eth_remove(struct udevice *dev) +{ + return 0; +} + +static int sb_eth_ofdata_to_platdata(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + + pdata->iobase = dev_get_addr(dev); + return 0; +} + +static const struct udevice_id sb_eth_ids[] = { + { .compatible = "sandbox,eth" }, + { } +}; + +U_BOOT_DRIVER(eth_sandbox) = { + .name = "eth_sandbox", + .id = UCLASS_ETH, + .of_match = sb_eth_ids, + .ofdata_to_platdata = sb_eth_ofdata_to_platdata, + .remove = sb_eth_remove, + .ops = &sb_eth_ops, + .priv_auto_alloc_size = sizeof(struct eth_sandbox_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), +}; diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 4bf493e..a320b4d 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -127,7 +127,7 @@ int sh_eth_recv(struct eth_device *dev) packet = (uchar *) ADDR_TO_P2(port_info->rx_desc_cur->rd2); invalidate_cache(packet, len); - NetReceive(packet, len); + net_process_received_packet(packet, len); } /* Make current descriptor available again */ diff --git a/drivers/net/smc91111.c b/drivers/net/smc91111.c index 57c667a..ade14cd 100644 --- a/drivers/net/smc91111.c +++ b/drivers/net/smc91111.c @@ -756,35 +756,35 @@ static int smc_rcv(struct eth_device *dev) #ifdef USE_32_BIT - PRINTK3(" Reading %d dwords (and %d bytes) \n", + PRINTK3(" Reading %d dwords (and %d bytes)\n", packet_length >> 2, packet_length & 3 ); /* QUESTION: Like in the TX routine, do I want to send the DWORDs or the bytes first, or some mixture. A mixture might improve already slow PIO performance */ - SMC_insl( dev, SMC91111_DATA_REG, NetRxPackets[0], - packet_length >> 2 ); + SMC_insl(dev, SMC91111_DATA_REG, net_rx_packets[0], + packet_length >> 2); /* read the left over bytes */ if (packet_length & 3) { int i; - byte *tail = (byte *)(NetRxPackets[0] + + byte *tail = (byte *)(net_rx_packets[0] + (packet_length & ~3)); dword leftover = SMC_inl(dev, SMC91111_DATA_REG); for (i=0; i<(packet_length & 3); i++) *tail++ = (byte) (leftover >> (8*i)) & 0xff; } #else - PRINTK3(" Reading %d words and %d byte(s) \n", + PRINTK3(" Reading %d words and %d byte(s)\n", (packet_length >> 1 ), packet_length & 1 ); - SMC_insw(dev, SMC91111_DATA_REG , NetRxPackets[0], - packet_length >> 1); + SMC_insw(dev, SMC91111_DATA_REG , net_rx_packets[0], + packet_length >> 1); #endif /* USE_32_BIT */ #if SMC_DEBUG > 2 printf("Receiving Packet\n"); - print_packet( NetRxPackets[0], packet_length ); + print_packet(net_rx_packets[0], packet_length); #endif } else { /* error ... */ @@ -815,7 +815,7 @@ static int smc_rcv(struct eth_device *dev) if (!is_error) { /* Pass the packet up to the protocol layers. */ - NetReceive(NetRxPackets[0], packet_length); + net_process_received_packet(net_rx_packets[0], packet_length); return packet_length; } else { return 0; diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 5959672..c85a178 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -192,7 +192,7 @@ static void smc911x_halt(struct eth_device *dev) static int smc911x_rx(struct eth_device *dev) { - u32 *data = (u32 *)NetRxPackets[0]; + u32 *data = (u32 *)net_rx_packets[0]; u32 pktlen, tmplen; u32 status; @@ -211,7 +211,7 @@ static int smc911x_rx(struct eth_device *dev) ": dropped bad packet. Status: 0x%08x\n", status); else - NetReceive(NetRxPackets[0], pktlen); + net_process_received_packet(net_rx_packets[0], pktlen); } return 0; diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c index 5a06d68..7b31f8c 100644 --- a/drivers/net/sunxi_emac.c +++ b/drivers/net/sunxi_emac.c @@ -437,10 +437,10 @@ static int sunxi_emac_eth_recv(struct eth_device *dev) printf("Received packet is too big (len=%d)\n", rx_len); } else { emac_inblk_32bit((void *)®s->rx_io_data, - NetRxPackets[0], rx_len); + net_rx_packets[0], rx_len); /* Pass to upper layer */ - NetReceive(NetRxPackets[0], rx_len); + net_process_received_packet(net_rx_packets[0], rx_len); return rx_len; } } @@ -497,7 +497,7 @@ int sunxi_emac_initialize(void) /* Configure pin mux settings for MII Ethernet */ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) - sunxi_gpio_set_cfgpin(pin, SUNXI_GPA0_EMAC); + sunxi_gpio_set_cfgpin(pin, SUNXI_GPA_EMAC); /* Set up clock gating */ setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_EMAC); diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index dcdba4e..42d0374 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -287,7 +287,7 @@ void redundant_init(struct eth_device *dev) } } - if (!memcmp(pkt, (void *)NetRxPackets[rx_idx], sizeof(pkt))) + if (!memcmp(pkt, (void *)net_rx_packets[rx_idx], sizeof(pkt))) fail = 0; out_be16(&rxbd[rx_idx].length, 0); @@ -343,7 +343,7 @@ static void startup_tsec(struct eth_device *dev) for (i = 0; i < PKTBUFSRX; i++) { out_be16(&rxbd[i].status, RXBD_EMPTY); out_be16(&rxbd[i].length, 0); - out_be32(&rxbd[i].bufptr, (u32)NetRxPackets[i]); + out_be32(&rxbd[i].bufptr, (u32)net_rx_packets[i]); } status = in_be16(&rxbd[PKTBUFSRX - 1].status); out_be16(&rxbd[PKTBUFSRX - 1].status, status | RXBD_WRAP); @@ -430,7 +430,8 @@ static int tsec_recv(struct eth_device *dev) /* Send the packet up if there were no errors */ if (!(status & RXBD_STATS)) - NetReceive(NetRxPackets[rx_idx], length - 4); + net_process_received_packet(net_rx_packets[rx_idx], + length - 4); else printf("Got error %x\n", (status & RXBD_STATS)); diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index 72b8159..9da59a0 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -804,11 +804,11 @@ static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis) rx_descr_current = rx_descr; for (index = 0; index < NUM_RX_DESC; index++) { /* make sure the receive buffers are not in cache */ - invalidate_dcache_range((unsigned long)NetRxPackets[index], - (unsigned long)NetRxPackets[index] + + invalidate_dcache_range((unsigned long)net_rx_packets[index], + (unsigned long)net_rx_packets[index] + RX_BUFFER_SIZE); rx_descr->start_addr0 = - cpu_to_le32((vuint32) NetRxPackets[index]); + cpu_to_le32((vuint32) net_rx_packets[index]); rx_descr->start_addr1 = 0; rx_descr->next_descr_addr0 = cpu_to_le32((vuint32) (rx_descr + 1)); @@ -966,7 +966,7 @@ static int tsi108_eth_recv (struct eth_device *dev) /*** process packet ***/ buffer = (uchar *)(le32_to_cpu(rx_descr->start_addr0)); - NetReceive(buffer, length); + net_process_received_packet(buffer, length); invalidate_dcache_range ((unsigned long)buffer, (unsigned long)buffer + diff --git a/drivers/net/uli526x.c b/drivers/net/uli526x.c index 9526faa..47cdb85 100644 --- a/drivers/net/uli526x.c +++ b/drivers/net/uli526x.c @@ -587,7 +587,8 @@ static int uli526x_rx_packet(struct eth_device *dev) __FUNCTION__, i, rxptr->rx_buf_ptr[i]); #endif - NetReceive((uchar *)rxptr->rx_buf_ptr, rxlen); + net_process_received_packet( + (uchar *)rxptr->rx_buf_ptr, rxlen); uli526x_reuse_buf(rxptr); } else { @@ -709,7 +710,7 @@ static void allocate_rx_buffer(struct uli526x_board_info *db) u32 addr; for (index = 0; index < RX_DESC_CNT; index++) { - addr = (u32)NetRxPackets[index]; + addr = (u32)net_rx_packets[index]; addr += (16 - (addr & 15)); rxptr->rx_buf_ptr = (char *) addr; rxptr->rdes2 = cpu_to_le32(addr); diff --git a/drivers/net/vsc9953.c b/drivers/net/vsc9953.c index 9fc3c18..fed7358 100644 --- a/drivers/net/vsc9953.c +++ b/drivers/net/vsc9953.c @@ -9,7 +9,7 @@ #include <asm/io.h> #include <asm/fsl_serdes.h> #include <fm_eth.h> -#include <asm/fsl_memac.h> +#include <fsl_memac.h> #include <vsc9953.h> static struct vsc9953_info vsc9953_l2sw = { diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 262b67b..df053fe 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -556,7 +556,7 @@ static int axiemac_recv(struct eth_device *dev) #endif /* Pass the received frame up for processing */ if (length) - NetReceive(rxframe, length); + net_process_received_packet(rxframe, length); #ifdef DEBUG /* It is useful to clear buffer to be sure that it is consistent */ diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 2a5cc44..c9afa99 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -322,7 +322,7 @@ static int emaclite_recv(struct eth_device *dev) out_be32 (baseaddress + XEL_RSR_OFFSET, reg); debug("Packet receive from 0x%x, length %dB\n", baseaddress, length); - NetReceive((uchar *) etherrxbuff, length); + net_process_received_packet((uchar *)etherrxbuff, length); return length; } diff --git a/drivers/net/xilinx_ll_temac_fifo.c b/drivers/net/xilinx_ll_temac_fifo.c index b8993cd..78319d7 100644 --- a/drivers/net/xilinx_ll_temac_fifo.c +++ b/drivers/net/xilinx_ll_temac_fifo.c @@ -48,7 +48,7 @@ int ll_temac_reset_fifo(struct eth_device *dev) int ll_temac_recv_fifo(struct eth_device *dev) { int i, length = 0; - u32 *buf = (u32 *)NetRxPackets[0]; + u32 *buf = (u32 *)net_rx_packets[0]; struct ll_temac *ll_temac = dev->priv; struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr; @@ -93,7 +93,7 @@ int ll_temac_recv_fifo(struct eth_device *dev) for (i = 0; i < length; i += 4) *buf++ = in_be32(&fifo_ctrl->rdfd); - NetReceive(NetRxPackets[0], length); + net_process_received_packet(net_rx_packets[0], length); } return 0; diff --git a/drivers/net/xilinx_ll_temac_sdma.c b/drivers/net/xilinx_ll_temac_sdma.c index 32a822e..07c5f6b 100644 --- a/drivers/net/xilinx_ll_temac_sdma.c +++ b/drivers/net/xilinx_ll_temac_sdma.c @@ -180,7 +180,7 @@ int ll_temac_init_sdma(struct eth_device *dev) memset(rx_dp, 0, sizeof(*rx_dp)); rx_dp->next_p = rx_dp; rx_dp->buf_len = PKTSIZE_ALIGN; - rx_dp->phys_buf_p = (u8 *)NetRxPackets[i]; + rx_dp->phys_buf_p = (u8 *)net_rx_packets[i]; flush_cache((u32)rx_dp->phys_buf_p, PKTSIZE_ALIGN); } flush_cache((u32)cdmac_bd.rx, sizeof(cdmac_bd.rx)); @@ -316,7 +316,7 @@ int ll_temac_recv_sdma(struct eth_device *dev) ll_temac->out32(ra[RX_TAILDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); if (length > 0 && pb_idx != -1) - NetReceive(NetRxPackets[pb_idx], length); + net_process_received_packet(net_rx_packets[pb_idx], length); return 0; } diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 430e228..c723dbb 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -439,7 +439,7 @@ static int zynq_gem_recv(struct eth_device *dev) u32 size = roundup(frame_len, ARCH_DMA_MINALIGN); invalidate_dcache_range(addr, addr + size); - NetReceive((u8 *)addr, frame_len); + net_process_received_packet((u8 *)addr, frame_len); if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) priv->rx_first_buf = priv->rxbd_current; @@ -513,7 +513,8 @@ int zynq_gem_initialize(bd_t *bis, phys_addr_t base_addr, /* Align bd_space to 1MB */ bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE); - mmu_set_region_dcache_behaviour((u32)bd_space, BD_SPACE, DCACHE_OFF); + mmu_set_region_dcache_behaviour((phys_addr_t)bd_space, + BD_SPACE, DCACHE_OFF); /* Initialize the bd spaces for tx and rx bd's */ priv->tx_bd = (struct emac_bd *)bd_space; diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index e69de29..167d405 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -0,0 +1,22 @@ +menu "PCI" + +config DM_PCI + bool "Enable driver mode for PCI" + depends on DM + help + Use driver model for PCI. Driver model is the new method for + orgnising devices in U-Boot. For PCI, driver model keeps track of + available PCI devices, allows scanning of PCI buses and provides + device configuration support. + +config PCI_SANDBOX + bool "Sandbox PCI support" + depends on SANDBOX && DM_PCI + help + Support PCI on sandbox, as an emulated bus. This permits testing of + PCI feature such as bus scanning, device configuration and device + access. The available (emulated) devices are defined statically in + the device tree but the normal PCI scan technique is used to find + then. + +endmenu diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 50b7be5..adc238f 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -5,8 +5,17 @@ # SPDX-License-Identifier: GPL-2.0+ # +ifneq ($(CONFIG_DM_PCI),) +obj-$(CONFIG_PCI) += pci-uclass.o pci_compat.o +obj-$(CONFIG_PCI_SANDBOX) += pci_sandbox.o +obj-$(CONFIG_SANDBOX) += pci-emul-uclass.o +obj-$(CONFIG_X86) += pci_x86.o +else +obj-$(CONFIG_PCI) += pci.o +endif +obj-$(CONFIG_PCI) += pci_common.o pci_auto.o pci_rom.o + obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o -obj-$(CONFIG_PCI) += pci.o pci_auto.o pci_rom.o obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o obj-$(CONFIG_PCI_MSC01) += pci_msc01.o diff --git a/drivers/pci/pci-emul-uclass.c b/drivers/pci/pci-emul-uclass.c new file mode 100644 index 0000000..0f8e3c9 --- /dev/null +++ b/drivers/pci/pci-emul-uclass.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <fdtdec.h> +#include <libfdt.h> +#include <pci.h> +#include <dm/lists.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct sandbox_pci_priv { + int dev_count; +}; + +int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, + struct udevice **emulp) +{ + struct udevice *dev; + int ret; + + ret = pci_bus_find_devfn(bus, find_devfn, &dev); + if (ret) { + debug("%s: Could not find emulator for dev %x\n", __func__, + find_devfn); + return ret; + } + + ret = device_find_first_child(dev, emulp); + if (ret) + return ret; + + return *emulp ? 0 : -ENODEV; +} + +static int sandbox_pci_emul_post_probe(struct udevice *dev) +{ + struct sandbox_pci_priv *priv = dev->uclass->priv; + + priv->dev_count++; + sandbox_set_enable_pci_map(true); + + return 0; +} + +static int sandbox_pci_emul_pre_remove(struct udevice *dev) +{ + struct sandbox_pci_priv *priv = dev->uclass->priv; + + priv->dev_count--; + sandbox_set_enable_pci_map(priv->dev_count > 0); + + return 0; +} + +UCLASS_DRIVER(pci_emul) = { + .id = UCLASS_PCI_EMUL, + .name = "pci_emul", + .post_probe = sandbox_pci_emul_post_probe, + .pre_remove = sandbox_pci_emul_pre_remove, + .priv_auto_alloc_size = sizeof(struct sandbox_pci_priv), +}; diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c new file mode 100644 index 0000000..d48d865 --- /dev/null +++ b/drivers/pci/pci-uclass.c @@ -0,0 +1,639 @@ +/* + * Copyright (c) 2014 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <inttypes.h> +#include <pci.h> +#include <dm/lists.h> +#include <dm/root.h> +#include <dm/device-internal.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct pci_controller *pci_bus_to_hose(int busnum) +{ + struct udevice *bus; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus); + if (ret) { + debug("%s: Cannot get bus %d: ret=%d\n", __func__, busnum, ret); + return NULL; + } + return dev_get_uclass_priv(bus); +} + +/** + * pci_get_bus_max() - returns the bus number of the last active bus + * + * @return last bus number, or -1 if no active buses + */ +static int pci_get_bus_max(void) +{ + struct udevice *bus; + struct uclass *uc; + int ret = -1; + + ret = uclass_get(UCLASS_PCI, &uc); + uclass_foreach_dev(bus, uc) { + if (bus->seq > ret) + ret = bus->seq; + } + + debug("%s: ret=%d\n", __func__, ret); + + return ret; +} + +int pci_last_busno(void) +{ + struct pci_controller *hose; + struct udevice *bus; + struct uclass *uc; + int ret; + + debug("pci_last_busno\n"); + ret = uclass_get(UCLASS_PCI, &uc); + if (ret || list_empty(&uc->dev_head)) + return -1; + + /* Probe the last bus */ + bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node); + debug("bus = %p, %s\n", bus, bus->name); + assert(bus); + ret = device_probe(bus); + if (ret) + return ret; + + /* If that bus has bridges, we may have new buses now. Get the last */ + bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node); + hose = dev_get_uclass_priv(bus); + debug("bus = %s, hose = %p\n", bus->name, hose); + + return hose->last_busno; +} + +int pci_get_ff(enum pci_size_t size) +{ + switch (size) { + case PCI_SIZE_8: + return 0xff; + case PCI_SIZE_16: + return 0xffff; + default: + return 0xffffffff; + } +} + +int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn, + struct udevice **devp) +{ + struct udevice *dev; + + for (device_find_first_child(bus, &dev); + dev; + device_find_next_child(&dev)) { + struct pci_child_platdata *pplat; + + pplat = dev_get_parent_platdata(dev); + if (pplat && pplat->devfn == find_devfn) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + +int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp) +{ + struct udevice *bus; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus); + if (ret) + return ret; + return pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), devp); +} + +static int pci_device_matches_ids(struct udevice *dev, + struct pci_device_id *ids) +{ + struct pci_child_platdata *pplat; + int i; + + pplat = dev_get_parent_platdata(dev); + if (!pplat) + return -EINVAL; + for (i = 0; ids[i].vendor != 0; i++) { + if (pplat->vendor == ids[i].vendor && + pplat->device == ids[i].device) + return i; + } + + return -EINVAL; +} + +int pci_bus_find_devices(struct udevice *bus, struct pci_device_id *ids, + int *indexp, struct udevice **devp) +{ + struct udevice *dev; + + /* Scan all devices on this bus */ + for (device_find_first_child(bus, &dev); + dev; + device_find_next_child(&dev)) { + if (pci_device_matches_ids(dev, ids) >= 0) { + if ((*indexp)-- <= 0) { + *devp = dev; + return 0; + } + } + } + + return -ENODEV; +} + +int pci_find_device_id(struct pci_device_id *ids, int index, + struct udevice **devp) +{ + struct udevice *bus; + + /* Scan all known buses */ + for (uclass_first_device(UCLASS_PCI, &bus); + bus; + uclass_next_device(&bus)) { + if (!pci_bus_find_devices(bus, ids, &index, devp)) + return 0; + } + *devp = NULL; + + return -ENODEV; +} + +int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset, + unsigned long value, enum pci_size_t size) +{ + struct dm_pci_ops *ops; + + ops = pci_get_ops(bus); + if (!ops->write_config) + return -ENOSYS; + return ops->write_config(bus, bdf, offset, value, size); +} + +int pci_write_config(pci_dev_t bdf, int offset, unsigned long value, + enum pci_size_t size) +{ + struct udevice *bus; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus); + if (ret) + return ret; + + return pci_bus_write_config(bus, PCI_MASK_BUS(bdf), offset, value, + size); +} + +int pci_write_config32(pci_dev_t bdf, int offset, u32 value) +{ + return pci_write_config(bdf, offset, value, PCI_SIZE_32); +} + +int pci_write_config16(pci_dev_t bdf, int offset, u16 value) +{ + return pci_write_config(bdf, offset, value, PCI_SIZE_16); +} + +int pci_write_config8(pci_dev_t bdf, int offset, u8 value) +{ + return pci_write_config(bdf, offset, value, PCI_SIZE_8); +} + +int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset, + unsigned long *valuep, enum pci_size_t size) +{ + struct dm_pci_ops *ops; + + ops = pci_get_ops(bus); + if (!ops->read_config) + return -ENOSYS; + return ops->read_config(bus, bdf, offset, valuep, size); +} + +int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep, + enum pci_size_t size) +{ + struct udevice *bus; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus); + if (ret) + return ret; + + return pci_bus_read_config(bus, PCI_MASK_BUS(bdf), offset, valuep, + size); +} + +int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep) +{ + unsigned long value; + int ret; + + ret = pci_read_config(bdf, offset, &value, PCI_SIZE_32); + if (ret) + return ret; + *valuep = value; + + return 0; +} + +int pci_read_config16(pci_dev_t bdf, int offset, u16 *valuep) +{ + unsigned long value; + int ret; + + ret = pci_read_config(bdf, offset, &value, PCI_SIZE_16); + if (ret) + return ret; + *valuep = value; + + return 0; +} + +int pci_read_config8(pci_dev_t bdf, int offset, u8 *valuep) +{ + unsigned long value; + int ret; + + ret = pci_read_config(bdf, offset, &value, PCI_SIZE_8); + if (ret) + return ret; + *valuep = value; + + return 0; +} + +int pci_auto_config_devices(struct udevice *bus) +{ + struct pci_controller *hose = bus->uclass_priv; + unsigned int sub_bus; + struct udevice *dev; + int ret; + + sub_bus = bus->seq; + debug("%s: start\n", __func__); + pciauto_config_init(hose); + for (ret = device_find_first_child(bus, &dev); + !ret && dev; + ret = device_find_next_child(&dev)) { + struct pci_child_platdata *pplat; + + pplat = dev_get_parent_platdata(dev); + unsigned int max_bus; + pci_dev_t bdf; + + bdf = PCI_ADD_BUS(bus->seq, pplat->devfn); + debug("%s: device %s\n", __func__, dev->name); + max_bus = pciauto_config_device(hose, bdf); + sub_bus = max(sub_bus, max_bus); + } + debug("%s: done\n", __func__); + + return sub_bus; +} + +int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf) +{ + struct udevice *parent, *bus; + int sub_bus; + int ret; + + debug("%s\n", __func__); + parent = hose->bus; + + /* Find the bus within the parent */ + ret = pci_bus_find_devfn(parent, bdf, &bus); + if (ret) { + debug("%s: Cannot find device %x on bus %s: %d\n", __func__, + bdf, parent->name, ret); + return ret; + } + + sub_bus = pci_get_bus_max() + 1; + debug("%s: bus = %d/%s\n", __func__, sub_bus, bus->name); + pciauto_prescan_setup_bridge(hose, bdf, bus->seq); + + ret = device_probe(bus); + if (ret) { + debug("%s: Cannot probe bus bus %s: %d\n", __func__, bus->name, + ret); + return ret; + } + if (sub_bus != bus->seq) { + printf("%s: Internal error, bus '%s' got seq %d, expected %d\n", + __func__, bus->name, bus->seq, sub_bus); + return -EPIPE; + } + sub_bus = pci_get_bus_max(); + pciauto_postscan_setup_bridge(hose, bdf, sub_bus); + + return sub_bus; +} + +int pci_bind_bus_devices(struct udevice *bus) +{ + ulong vendor, device; + ulong header_type; + pci_dev_t devfn, end; + bool found_multi; + int ret; + + found_multi = false; + end = PCI_DEVFN(PCI_MAX_PCI_DEVICES - 1, PCI_MAX_PCI_FUNCTIONS - 1); + for (devfn = PCI_DEVFN(0, 0); devfn < end; devfn += PCI_DEVFN(0, 1)) { + struct pci_child_platdata *pplat; + struct udevice *dev; + ulong class; + + if (PCI_FUNC(devfn) && !found_multi) + continue; + /* Check only the first access, we don't expect problems */ + ret = pci_bus_read_config(bus, devfn, PCI_HEADER_TYPE, + &header_type, PCI_SIZE_8); + if (ret) + goto error; + pci_bus_read_config(bus, devfn, PCI_VENDOR_ID, &vendor, + PCI_SIZE_16); + if (vendor == 0xffff || vendor == 0x0000) + continue; + + if (!PCI_FUNC(devfn)) + found_multi = header_type & 0x80; + + debug("%s: bus %d/%s: found device %x, function %d\n", __func__, + bus->seq, bus->name, PCI_DEV(devfn), PCI_FUNC(devfn)); + pci_bus_read_config(bus, devfn, PCI_DEVICE_ID, &device, + PCI_SIZE_16); + pci_bus_read_config(bus, devfn, PCI_CLASS_DEVICE, &class, + PCI_SIZE_16); + + /* Find this device in the device tree */ + ret = pci_bus_find_devfn(bus, devfn, &dev); + + /* If nothing in the device tree, bind a generic device */ + if (ret == -ENODEV) { + char name[30], *str; + const char *drv; + + sprintf(name, "pci_%x:%x.%x", bus->seq, + PCI_DEV(devfn), PCI_FUNC(devfn)); + str = strdup(name); + if (!str) + return -ENOMEM; + drv = class == PCI_CLASS_BRIDGE_PCI ? + "pci_bridge_drv" : "pci_generic_drv"; + ret = device_bind_driver(bus, drv, str, &dev); + } + if (ret) + return ret; + + /* Update the platform data */ + pplat = dev_get_parent_platdata(dev); + pplat->devfn = devfn; + pplat->vendor = vendor; + pplat->device = device; + pplat->class = class; + } + + return 0; +error: + printf("Cannot read bus configuration: %d\n", ret); + + return ret; +} + +static int pci_uclass_post_bind(struct udevice *bus) +{ + /* + * Scan the device tree for devices. This does not probe the PCI bus, + * as this is not permitted while binding. It just finds devices + * mentioned in the device tree. + * + * Before relocation, only bind devices marked for pre-relocation + * use. + */ + return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset, + gd->flags & GD_FLG_RELOC ? false : true); +} + +static int decode_regions(struct pci_controller *hose, const void *blob, + int parent_node, int node) +{ + int pci_addr_cells, addr_cells, size_cells; + int cells_per_record; + const u32 *prop; + int len; + int i; + + prop = fdt_getprop(blob, node, "ranges", &len); + if (!prop) + return -EINVAL; + pci_addr_cells = fdt_address_cells(blob, node); + addr_cells = fdt_address_cells(blob, parent_node); + size_cells = fdt_size_cells(blob, node); + + /* PCI addresses are always 3-cells */ + len /= sizeof(u32); + cells_per_record = pci_addr_cells + addr_cells + size_cells; + hose->region_count = 0; + debug("%s: len=%d, cells_per_record=%d\n", __func__, len, + cells_per_record); + for (i = 0; i < MAX_PCI_REGIONS; i++, len -= cells_per_record) { + u64 pci_addr, addr, size; + int space_code; + u32 flags; + int type; + + if (len < cells_per_record) + break; + flags = fdt32_to_cpu(prop[0]); + space_code = (flags >> 24) & 3; + pci_addr = fdtdec_get_number(prop + 1, 2); + prop += pci_addr_cells; + addr = fdtdec_get_number(prop, addr_cells); + prop += addr_cells; + size = fdtdec_get_number(prop, size_cells); + prop += size_cells; + debug("%s: region %d, pci_addr=%" PRIx64 ", addr=%" PRIx64 + ", size=%" PRIx64 ", space_code=%d\n", __func__, + hose->region_count, pci_addr, addr, size, space_code); + if (space_code & 2) { + type = flags & (1U << 30) ? PCI_REGION_PREFETCH : + PCI_REGION_MEM; + } else if (space_code & 1) { + type = PCI_REGION_IO; + } else { + continue; + } + debug(" - type=%d\n", type); + pci_set_region(hose->regions + hose->region_count++, pci_addr, + addr, size, type); + } + + /* Add a region for our local memory */ + pci_set_region(hose->regions + hose->region_count++, 0, 0, + gd->ram_size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + return 0; +} + +static int pci_uclass_pre_probe(struct udevice *bus) +{ + struct pci_controller *hose; + int ret; + + debug("%s, bus=%d/%s, parent=%s\n", __func__, bus->seq, bus->name, + bus->parent->name); + hose = bus->uclass_priv; + + /* For bridges, use the top-level PCI controller */ + if (device_get_uclass_id(bus->parent) == UCLASS_ROOT) { + hose->ctlr = bus; + ret = decode_regions(hose, gd->fdt_blob, bus->parent->of_offset, + bus->of_offset); + if (ret) { + debug("%s: Cannot decode regions\n", __func__); + return ret; + } + } else { + struct pci_controller *parent_hose; + + parent_hose = dev_get_uclass_priv(bus->parent); + hose->ctlr = parent_hose->bus; + } + hose->bus = bus; + hose->first_busno = bus->seq; + hose->last_busno = bus->seq; + + return 0; +} + +static int pci_uclass_post_probe(struct udevice *bus) +{ + int ret; + + /* Don't scan buses before relocation */ + if (!(gd->flags & GD_FLG_RELOC)) + return 0; + + debug("%s: probing bus %d\n", __func__, bus->seq); + ret = pci_bind_bus_devices(bus); + if (ret) + return ret; + +#ifdef CONFIG_PCI_PNP + ret = pci_auto_config_devices(bus); +#endif + + return ret < 0 ? ret : 0; +} + +static int pci_uclass_child_post_bind(struct udevice *dev) +{ + struct pci_child_platdata *pplat; + struct fdt_pci_addr addr; + int ret; + + if (dev->of_offset == -1) + return 0; + + /* + * We could read vendor, device, class if available. But for now we + * just check the address. + */ + pplat = dev_get_parent_platdata(dev); + ret = fdtdec_get_pci_addr(gd->fdt_blob, dev->of_offset, + FDT_PCI_SPACE_CONFIG, "reg", &addr); + + if (ret) { + if (ret != -ENOENT) + return -EINVAL; + } else { + /* extract the bdf from fdt_pci_addr */ + pplat->devfn = addr.phys_hi & 0xffff00; + } + + return 0; +} + +int pci_bridge_read_config(struct udevice *bus, pci_dev_t devfn, uint offset, + ulong *valuep, enum pci_size_t size) +{ + struct pci_controller *hose = bus->uclass_priv; + pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn); + + return pci_bus_read_config(hose->ctlr, bdf, offset, valuep, size); +} + +int pci_bridge_write_config(struct udevice *bus, pci_dev_t devfn, uint offset, + ulong value, enum pci_size_t size) +{ + struct pci_controller *hose = bus->uclass_priv; + pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn); + + return pci_bus_write_config(hose->ctlr, bdf, offset, value, size); +} + +UCLASS_DRIVER(pci) = { + .id = UCLASS_PCI, + .name = "pci", + .post_bind = pci_uclass_post_bind, + .pre_probe = pci_uclass_pre_probe, + .post_probe = pci_uclass_post_probe, + .child_post_bind = pci_uclass_child_post_bind, + .per_device_auto_alloc_size = sizeof(struct pci_controller), + .per_child_platdata_auto_alloc_size = + sizeof(struct pci_child_platdata), +}; + +static const struct dm_pci_ops pci_bridge_ops = { + .read_config = pci_bridge_read_config, + .write_config = pci_bridge_write_config, +}; + +static const struct udevice_id pci_bridge_ids[] = { + { .compatible = "pci-bridge" }, + { } +}; + +U_BOOT_DRIVER(pci_bridge_drv) = { + .name = "pci_bridge_drv", + .id = UCLASS_PCI, + .of_match = pci_bridge_ids, + .ops = &pci_bridge_ops, +}; + +UCLASS_DRIVER(pci_generic) = { + .id = UCLASS_PCI_GENERIC, + .name = "pci_generic", +}; + +static const struct udevice_id pci_generic_ids[] = { + { .compatible = "pci-generic" }, + { } +}; + +U_BOOT_DRIVER(pci_generic_drv) = { + .name = "pci_generic_drv", + .id = UCLASS_PCI_GENERIC, + .of_match = pci_generic_ids, +}; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e1296ca..3babd94 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -101,25 +101,6 @@ PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02) PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff) PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff) -/* Get a virtual address associated with a BAR region */ -void *pci_map_bar(pci_dev_t pdev, int bar, int flags) -{ - pci_addr_t pci_bus_addr; - u32 bar_response; - - /* read BAR address */ - pci_read_config_dword(pdev, bar, &bar_response); - pci_bus_addr = (pci_addr_t)(bar_response & ~0xf); - - /* - * Pass "0" as the length argument to pci_bus_to_virt. The arg - * isn't actualy used on any platform because u-boot assumes a static - * linear mapping. In the future, this could read the BAR size - * and pass that as the size if needed. - */ - return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE); -} - /* * */ @@ -187,106 +168,22 @@ int pci_last_busno(void) pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) { struct pci_controller * hose; - u16 vendor, device; - u8 header_type; pci_dev_t bdf; - int i, bus, found_multi = 0; + int bus; for (hose = pci_get_hose_head(); hose; hose = hose->next) { #ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE - for (bus = hose->last_busno; bus >= hose->first_busno; bus--) + for (bus = hose->last_busno; bus >= hose->first_busno; bus--) { #else - for (bus = hose->first_busno; bus <= hose->last_busno; bus++) + for (bus = hose->first_busno; bus <= hose->last_busno; bus++) { #endif - for (bdf = PCI_BDF(bus, 0, 0); - bdf < PCI_BDF(bus + 1, 0, 0); - bdf += PCI_BDF(0, 0, 1)) { - if (pci_skip_dev(hose, bdf)) - continue; - - if (!PCI_FUNC(bdf)) { - pci_read_config_byte(bdf, - PCI_HEADER_TYPE, - &header_type); - - found_multi = header_type & 0x80; - } else { - if (!found_multi) - continue; - } - - pci_read_config_word(bdf, - PCI_VENDOR_ID, - &vendor); - pci_read_config_word(bdf, - PCI_DEVICE_ID, - &device); - - for (i = 0; ids[i].vendor != 0; i++) { - if (vendor == ids[i].vendor && - device == ids[i].device) { - if (index <= 0) - return bdf; - - index--; - } - } - } - } - - return -1; -} - -pci_dev_t pci_find_class(uint find_class, int index) -{ - int bus; - int devnum; - pci_dev_t bdf; - uint32_t class; - - for (bus = 0; bus <= pci_last_busno(); bus++) { - for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) { - pci_read_config_dword(PCI_BDF(bus, devnum, 0), - PCI_CLASS_REVISION, &class); - if (class >> 16 == 0xffff) - continue; - - for (bdf = PCI_BDF(bus, devnum, 0); - bdf <= PCI_BDF(bus, devnum, - PCI_MAX_PCI_FUNCTIONS - 1); - bdf += PCI_BDF(0, 0, 1)) { - pci_read_config_dword(bdf, PCI_CLASS_REVISION, - &class); - class >>= 8; - - if (class != find_class) - continue; - /* - * Decrement the index. We want to return the - * correct device, so index is 0 for the first - * matching device, 1 for the second, etc. - */ - if (index) { - index--; - continue; - } - /* Return index'th controller. */ + bdf = pci_hose_find_devices(hose, bus, ids, &index); + if (bdf != -1) return bdf; - } } } - return -ENODEV; -} - -pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index) -{ - struct pci_device_id ids[2] = { {}, {0, 0} }; - - ids[0].vendor = vendor; - ids[0].device = device; - - return pci_find_devices(ids, index); + return -1; } /* @@ -355,87 +252,6 @@ pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose, return bus_addr; } -int __pci_hose_bus_to_phys(struct pci_controller *hose, - pci_addr_t bus_addr, - unsigned long flags, - unsigned long skip_mask, - phys_addr_t *pa) -{ - struct pci_region *res; - int i; - - for (i = 0; i < hose->region_count; i++) { - res = &hose->regions[i]; - - if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0) - continue; - - if (res->flags & skip_mask) - continue; - - if (bus_addr >= res->bus_start && - (bus_addr - res->bus_start) < res->size) { - *pa = (bus_addr - res->bus_start + res->phys_start); - return 0; - } - } - - return 1; -} - -phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose, - pci_addr_t bus_addr, - unsigned long flags) -{ - phys_addr_t phys_addr = 0; - int ret; - - if (!hose) { - 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 ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) { - ret = __pci_hose_bus_to_phys(hose, bus_addr, - flags, PCI_REGION_SYS_MEMORY, &phys_addr); - if (!ret) - return phys_addr; - } - - 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"); - - return phys_addr; -} - -void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum, - u32 addr_and_ctrl) -{ - int bar; - - bar = PCI_BASE_ADDRESS_0 + barnum * 4; - pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl); -} - -u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum) -{ - u32 addr; - int bar; - - bar = PCI_BASE_ADDRESS_0 + barnum * 4; - pci_hose_read_config_dword(hose, dev, bar, &addr); - if (addr & PCI_BASE_ADDRESS_SPACE_IO) - return addr & PCI_BASE_ADDRESS_IO_MASK; - else - return addr & PCI_BASE_ADDRESS_MEM_MASK; -} - int pci_hose_config_device(struct pci_controller *hose, pci_dev_t dev, unsigned long io, @@ -576,91 +392,6 @@ void pci_cfgfunc_do_nothing(struct pci_controller *hose, */ extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev); -#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI_SCAN_SHOW) -const char * pci_class_str(u8 class) -{ - switch (class) { - case PCI_CLASS_NOT_DEFINED: - return "Build before PCI Rev2.0"; - break; - case PCI_BASE_CLASS_STORAGE: - return "Mass storage controller"; - break; - case PCI_BASE_CLASS_NETWORK: - return "Network controller"; - break; - case PCI_BASE_CLASS_DISPLAY: - return "Display controller"; - break; - case PCI_BASE_CLASS_MULTIMEDIA: - return "Multimedia device"; - break; - case PCI_BASE_CLASS_MEMORY: - return "Memory controller"; - break; - case PCI_BASE_CLASS_BRIDGE: - return "Bridge device"; - break; - case PCI_BASE_CLASS_COMMUNICATION: - return "Simple comm. controller"; - break; - case PCI_BASE_CLASS_SYSTEM: - return "Base system peripheral"; - break; - case PCI_BASE_CLASS_INPUT: - return "Input device"; - break; - case PCI_BASE_CLASS_DOCKING: - return "Docking station"; - break; - case PCI_BASE_CLASS_PROCESSOR: - return "Processor"; - break; - case PCI_BASE_CLASS_SERIAL: - return "Serial bus controller"; - break; - case PCI_BASE_CLASS_INTELLIGENT: - return "Intelligent controller"; - break; - case PCI_BASE_CLASS_SATELLITE: - return "Satellite controller"; - break; - case PCI_BASE_CLASS_CRYPT: - return "Cryptographic device"; - break; - case PCI_BASE_CLASS_SIGNAL_PROCESSING: - return "DSP"; - break; - case PCI_CLASS_OTHERS: - return "Does not fit any class"; - break; - default: - return "???"; - break; - }; -} -#endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */ - -__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) -{ - /* - * Check if pci device should be skipped in configuration - */ - if (dev == PCI_BDF(hose->first_busno, 0, 0)) { -#if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */ - /* - * Only skip configuration if "pciconfighost" is not set - */ - if (getenv("pciconfighost") == NULL) - return 1; -#else - return 1; -#endif - } - - return 0; -} - #ifdef CONFIG_PCI_SCAN_SHOW __weak int pci_print_dev(struct pci_controller *hose, pci_dev_t dev) { diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 378efbf..e8da977 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -432,13 +432,20 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) switch (class) { case PCI_CLASS_BRIDGE_PCI: - hose->current_busno++; + DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", + PCI_DEV(dev)); + 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)); - +#ifdef CONFIG_DM_PCI + n = dm_pci_hose_probe_bus(hose, dev); + if (n < 0) + return n; + sub_bus = (unsigned int)n; +#else /* Passing in current_busno allows for sibling P2P bridges */ + hose->current_busno++; pciauto_prescan_setup_bridge(hose, dev, hose->current_busno); /* * need to figure out if this is a subordinate bridge on the bus @@ -451,6 +458,7 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) pciauto_postscan_setup_bridge(hose, dev, sub_bus); sub_bus = hose->current_busno; +#endif break; case PCI_CLASS_STORAGE_IDE: @@ -475,7 +483,9 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n", PCI_DEV(dev)); +#ifndef CONFIG_DM_PCI hose->current_busno++; +#endif break; #if defined(CONFIG_PCIAUTO_SKIP_HOST_BRIDGE) diff --git a/drivers/pci/pci_common.c b/drivers/pci/pci_common.c new file mode 100644 index 0000000..24c66bb --- /dev/null +++ b/drivers/pci/pci_common.c @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2014 Google, Inc + * + * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Andreas Heppel <aheppel@sysgo.de> + * + * (C) Copyright 2002, 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <pci.h> +#include <asm/io.h> + +const char *pci_class_str(u8 class) +{ + switch (class) { + case PCI_CLASS_NOT_DEFINED: + return "Build before PCI Rev2.0"; + break; + case PCI_BASE_CLASS_STORAGE: + return "Mass storage controller"; + break; + case PCI_BASE_CLASS_NETWORK: + return "Network controller"; + break; + case PCI_BASE_CLASS_DISPLAY: + return "Display controller"; + break; + case PCI_BASE_CLASS_MULTIMEDIA: + return "Multimedia device"; + break; + case PCI_BASE_CLASS_MEMORY: + return "Memory controller"; + break; + case PCI_BASE_CLASS_BRIDGE: + return "Bridge device"; + break; + case PCI_BASE_CLASS_COMMUNICATION: + return "Simple comm. controller"; + break; + case PCI_BASE_CLASS_SYSTEM: + return "Base system peripheral"; + break; + case PCI_BASE_CLASS_INPUT: + return "Input device"; + break; + case PCI_BASE_CLASS_DOCKING: + return "Docking station"; + break; + case PCI_BASE_CLASS_PROCESSOR: + return "Processor"; + break; + case PCI_BASE_CLASS_SERIAL: + return "Serial bus controller"; + break; + case PCI_BASE_CLASS_INTELLIGENT: + return "Intelligent controller"; + break; + case PCI_BASE_CLASS_SATELLITE: + return "Satellite controller"; + break; + case PCI_BASE_CLASS_CRYPT: + return "Cryptographic device"; + break; + case PCI_BASE_CLASS_SIGNAL_PROCESSING: + return "DSP"; + break; + case PCI_CLASS_OTHERS: + return "Does not fit any class"; + break; + default: + return "???"; + break; + }; +} + +pci_dev_t pci_find_class(uint find_class, int index) +{ + int bus; + int devnum; + pci_dev_t bdf; + uint32_t class; + + for (bus = 0; bus <= pci_last_busno(); bus++) { + for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) { + pci_read_config_dword(PCI_BDF(bus, devnum, 0), + PCI_CLASS_REVISION, &class); + if (class >> 16 == 0xffff) + continue; + + for (bdf = PCI_BDF(bus, devnum, 0); + bdf <= PCI_BDF(bus, devnum, + PCI_MAX_PCI_FUNCTIONS - 1); + bdf += PCI_BDF(0, 0, 1)) { + pci_read_config_dword(bdf, PCI_CLASS_REVISION, + &class); + class >>= 8; + + if (class != find_class) + continue; + /* + * Decrement the index. We want to return the + * correct device, so index is 0 for the first + * matching device, 1 for the second, etc. + */ + if (index) { + index--; + continue; + } + /* Return index'th controller. */ + return bdf; + } + } + } + + return -ENODEV; +} + +__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) +{ + /* + * Check if pci device should be skipped in configuration + */ + if (dev == PCI_BDF(hose->first_busno, 0, 0)) { +#if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */ + /* + * Only skip configuration if "pciconfighost" is not set + */ + if (getenv("pciconfighost") == NULL) + return 1; +#else + return 1; +#endif + } + + return 0; +} + +/* Get a virtual address associated with a BAR region */ +void *pci_map_bar(pci_dev_t pdev, int bar, int flags) +{ + pci_addr_t pci_bus_addr; + u32 bar_response; + + /* read BAR address */ + pci_read_config_dword(pdev, bar, &bar_response); + pci_bus_addr = (pci_addr_t)(bar_response & ~0xf); + + /* + * Pass "0" as the length argument to pci_bus_to_virt. The arg + * isn't actualy used on any platform because u-boot assumes a static + * linear mapping. In the future, this could read the BAR size + * and pass that as the size if needed. + */ + return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE); +} + +void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum, + u32 addr_and_ctrl) +{ + int bar; + + bar = PCI_BASE_ADDRESS_0 + barnum * 4; + pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl); +} + +u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum) +{ + u32 addr; + int bar; + + bar = PCI_BASE_ADDRESS_0 + barnum * 4; + pci_hose_read_config_dword(hose, dev, bar, &addr); + if (addr & PCI_BASE_ADDRESS_SPACE_IO) + return addr & PCI_BASE_ADDRESS_IO_MASK; + else + return addr & PCI_BASE_ADDRESS_MEM_MASK; +} + +int __pci_hose_bus_to_phys(struct pci_controller *hose, + pci_addr_t bus_addr, + unsigned long flags, + unsigned long skip_mask, + phys_addr_t *pa) +{ + struct pci_region *res; + int i; + + for (i = 0; i < hose->region_count; i++) { + res = &hose->regions[i]; + + if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0) + continue; + + if (res->flags & skip_mask) + continue; + + if (bus_addr >= res->bus_start && + (bus_addr - res->bus_start) < res->size) { + *pa = (bus_addr - res->bus_start + res->phys_start); + return 0; + } + } + + return 1; +} + +phys_addr_t pci_hose_bus_to_phys(struct pci_controller *hose, + pci_addr_t bus_addr, + unsigned long flags) +{ + phys_addr_t phys_addr = 0; + int ret; + + if (!hose) { + 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 ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) { + ret = __pci_hose_bus_to_phys(hose, bus_addr, + flags, PCI_REGION_SYS_MEMORY, &phys_addr); + if (!ret) + return phys_addr; + } + + 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"); + + return phys_addr; +} + +pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index) +{ + struct pci_device_id ids[2] = { {}, {0, 0} }; + + ids[0].vendor = vendor; + ids[0].device = device; + + return pci_find_devices(ids, index); +} + +pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum, + struct pci_device_id *ids, int *indexp) +{ + int found_multi = 0; + u16 vendor, device; + u8 header_type; + pci_dev_t bdf; + int i; + + for (bdf = PCI_BDF(busnum, 0, 0); + bdf < PCI_BDF(busnum + 1, 0, 0); + bdf += PCI_BDF(0, 0, 1)) { + if (pci_skip_dev(hose, bdf)) + continue; + + if (!PCI_FUNC(bdf)) { + pci_read_config_byte(bdf, PCI_HEADER_TYPE, + &header_type); + found_multi = header_type & 0x80; + } else { + if (!found_multi) + continue; + } + + pci_read_config_word(bdf, PCI_VENDOR_ID, &vendor); + pci_read_config_word(bdf, PCI_DEVICE_ID, &device); + + for (i = 0; ids[i].vendor != 0; i++) { + if (vendor == ids[i].vendor && + device == ids[i].device) { + if ((*indexp) <= 0) + return bdf; + + (*indexp)--; + } + } + } + + return -1; +} diff --git a/drivers/pci/pci_compat.c b/drivers/pci/pci_compat.c new file mode 100644 index 0000000..d6938c1 --- /dev/null +++ b/drivers/pci/pci_compat.c @@ -0,0 +1,43 @@ +/* + * Compatibility functions for pre-driver-model code + * + * Copyright (C) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#define DEBUG +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <malloc.h> +#include <pci.h> +#include <dm/device-internal.h> +#include <dm/lists.h> + +#define PCI_HOSE_OP(rw, name, size, type) \ +int pci_hose_##rw##_config_##name(struct pci_controller *hose, \ + pci_dev_t dev, \ + int offset, type value) \ +{ \ + return pci_##rw##_config##size(dev, offset, value); \ +} + +PCI_HOSE_OP(read, byte, 8, u8 *) +PCI_HOSE_OP(read, word, 16, u16 *) +PCI_HOSE_OP(read, dword, 32, u32 *) +PCI_HOSE_OP(write, byte, 8, u8) +PCI_HOSE_OP(write, word, 16, u16) +PCI_HOSE_OP(write, dword, 32, u32) + +pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) +{ + struct pci_child_platdata *pplat; + struct udevice *bus, *dev; + + if (pci_find_device_id(ids, index, &dev)) + return -1; + bus = dev->parent; + pplat = dev_get_parent_platdata(dev); + + return PCI_ADD_BUS(bus->seq, pplat->devfn); +} diff --git a/drivers/pci/pci_sandbox.c b/drivers/pci/pci_sandbox.c new file mode 100644 index 0000000..6de5130 --- /dev/null +++ b/drivers/pci/pci_sandbox.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <fdtdec.h> +#include <inttypes.h> +#include <pci.h> +#include <dm/root.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int sandbox_pci_write_config(struct udevice *bus, pci_dev_t devfn, + uint offset, ulong value, + enum pci_size_t size) +{ + struct dm_pci_emul_ops *ops; + struct udevice *emul; + int ret; + + ret = sandbox_pci_get_emul(bus, devfn, &emul); + if (ret) + return ret == -ENODEV ? 0 : ret; + ops = pci_get_emul_ops(emul); + if (!ops || !ops->write_config) + return -ENOSYS; + + return ops->write_config(emul, offset, value, size); +} + +static int sandbox_pci_read_config(struct udevice *bus, pci_dev_t devfn, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + struct dm_pci_emul_ops *ops; + struct udevice *emul; + int ret; + + /* Prepare the default response */ + *valuep = pci_get_ff(size); + ret = sandbox_pci_get_emul(bus, devfn, &emul); + if (ret) + return ret == -ENODEV ? 0 : ret; + ops = pci_get_emul_ops(emul); + if (!ops || !ops->read_config) + return -ENOSYS; + + return ops->read_config(emul, offset, valuep, size); +} + +static int sandbox_pci_child_post_bind(struct udevice *dev) +{ + /* Attach an emulator if we can */ + return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); +} + +static const struct dm_pci_ops sandbox_pci_ops = { + .read_config = sandbox_pci_read_config, + .write_config = sandbox_pci_write_config, +}; + +static const struct udevice_id sandbox_pci_ids[] = { + { .compatible = "sandbox,pci" }, + { } +}; + +U_BOOT_DRIVER(pci_sandbox) = { + .name = "pci_sandbox", + .id = UCLASS_PCI, + .of_match = sandbox_pci_ids, + .ops = &sandbox_pci_ops, + .child_post_bind = sandbox_pci_child_post_bind, + .per_child_platdata_auto_alloc_size = + sizeof(struct pci_child_platdata), +}; diff --git a/drivers/pci/pci_x86.c b/drivers/pci/pci_x86.c new file mode 100644 index 0000000..901bdca --- /dev/null +++ b/drivers/pci/pci_x86.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <pci.h> + +static const struct dm_pci_ops x86_pci_ops = { +}; + +static const struct udevice_id x86_pci_ids[] = { + { .compatible = "x86,pci" }, + { } +}; + +U_BOOT_DRIVER(pci_x86) = { + .name = "pci_x86", + .id = UCLASS_PCI, + .of_match = x86_pci_ids, + .ops = &x86_pci_ops, +}; diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index bcad8f2..402c519 100644 --- a/drivers/pci/pcie_layerscape.c +++ b/drivers/pci/pcie_layerscape.c @@ -11,7 +11,6 @@ #include <asm/io.h> #include <errno.h> #include <malloc.h> -#include <asm/pcie_layerscape.h> #ifndef CONFIG_SYS_PCI_MEMORY_BUS #define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE @@ -50,11 +49,20 @@ #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) #define PCIE_ATU_UPPER_TARGET 0x91C +/* LUT registers */ +#define PCIE_LUT_BASE 0x80000 +#define PCIE_LUT_DBG 0x7FC + +#define PCIE_DBI_RO_WR_EN 0x8bc + #define PCIE_LINK_CAP 0x7c #define PCIE_LINK_SPEED_MASK 0xf #define PCIE_LINK_STA 0x82 -#define PCIE_DBI_SIZE (4 * 1024) /* 4K */ +#define LTSSM_STATE_MASK 0x3f +#define LTSSM_PCIE_L0 0x11 /* L0 state */ + +#define PCIE_DBI_SIZE 0x100000 /* 1M */ struct ls_pcie { int idx; @@ -104,8 +112,6 @@ struct ls_pcie_info { /* PEX1/2 Misc Ports Status Register */ #define LTSSM_STATE_SHIFT 20 -#define LTSSM_STATE_MASK 0x3f -#define LTSSM_PCIE_L0 0x11 /* L0 state */ static int ls_pcie_link_state(struct ls_pcie *pcie) { @@ -122,18 +128,18 @@ static int ls_pcie_link_state(struct ls_pcie *pcie) return 1; } #else -#define PCIE_LDBG 0x7FC - static int ls_pcie_link_state(struct ls_pcie *pcie) { u32 state; - state = readl(pcie->dbi + PCIE_LDBG); - if (state) - return 1; + state = readl(pcie->dbi + PCIE_LUT_BASE + PCIE_LUT_DBG) & + LTSSM_STATE_MASK; + if (state < LTSSM_PCIE_L0) { + debug("....PCIe link error. LTSSM=0x%02x.\n", state); + return 0; + } - debug("....PCIe link error.\n"); - return 0; + return 1; } #endif @@ -149,7 +155,11 @@ static int ls_pcie_link_up(struct ls_pcie *pcie) /* Try to download speed to gen1 */ cap = readl(pcie->dbi + PCIE_LINK_CAP); writel((cap & (~PCIE_LINK_SPEED_MASK)) | 1, pcie->dbi + PCIE_LINK_CAP); - udelay(2000); + /* + * Notice: the following delay has critical impact on link training + * if too short (<30ms) the link doesn't get up. + */ + mdelay(100); state = ls_pcie_link_state(pcie); if (state) return state; @@ -251,6 +261,10 @@ static int ls_pcie_addr_valid(struct pci_controller *hose, pci_dev_t d) if (PCI_DEV(d) > 0) return -EINVAL; + /* Controller does not support multi-function in RC mode */ + if ((PCI_BUS(d) == hose->first_busno) && (PCI_FUNC(d) > 0)) + return -EINVAL; + return 0; } @@ -327,8 +341,12 @@ static void ls_pcie_setup_ctrl(struct ls_pcie *pcie, pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0); /* program correct class for RC */ + writel(1, pcie->dbi + PCIE_DBI_RO_WR_EN); pci_hose_write_config_word(hose, dev, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_PCI); +#ifndef CONFIG_LS102XA + writel(0, pcie->dbi + PCIE_DBI_RO_WR_EN); +#endif } int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info) @@ -417,9 +435,9 @@ int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info) } /* Print the negotiated PCIe link width */ - pci_hose_read_config_word(hose, dev, PCIE_LINK_STA, &temp16); - printf("x%d gen%d, regs @ 0x%lx\n", (temp16 & 0x3f0) >> 4, - (temp16 & 0xf), info->regs); + pci_hose_read_config_word(hose, pdev, PCIE_LINK_STA, &temp16); + printf("x%d gen%d, regs @ 0x%lx\n", (temp16 & 0x3f0) >> 4, + (temp16 & 0xf), info->regs); if (ep_mode) return busno; @@ -486,7 +504,7 @@ static void ft_pcie_ls_setup(void *blob, const char *pci_compat, fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); } -void ft_pcie_setup(void *blob, bd_t *bd) +void ft_pci_setup(void *blob, bd_t *bd) { #ifdef CONFIG_PCIE1 ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE1_ADDR, PCIE1); @@ -506,7 +524,7 @@ void ft_pcie_setup(void *blob, bd_t *bd) } #else -void ft_pcie_setup(void *blob, bd_t *bd) +void ft_pci_setup(void *blob, bd_t *bd) { } #endif diff --git a/drivers/power/axp152.c b/drivers/power/axp152.c index 27c2c4c..740a3b4 100644 --- a/drivers/power/axp152.c +++ b/drivers/power/axp152.c @@ -8,17 +8,6 @@ #include <i2c.h> #include <axp152.h> -enum axp152_reg { - AXP152_CHIP_VERSION = 0x3, - AXP152_DCDC2_VOLTAGE = 0x23, - AXP152_DCDC3_VOLTAGE = 0x27, - AXP152_DCDC4_VOLTAGE = 0x2B, - AXP152_LDO2_VOLTAGE = 0x2A, - AXP152_SHUTDOWN = 0x32, -}; - -#define AXP152_POWEROFF (1 << 7) - static int axp152_write(enum axp152_reg reg, u8 val) { return i2c_write(0x30, reg, 1, &val, 1); diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c index f8c9b77..1d7be49 100644 --- a/drivers/power/axp209.c +++ b/drivers/power/axp209.c @@ -7,45 +7,9 @@ #include <common.h> #include <i2c.h> +#include <asm/arch/gpio.h> #include <axp209.h> -enum axp209_reg { - AXP209_POWER_STATUS = 0x00, - AXP209_CHIP_VERSION = 0x03, - AXP209_DCDC2_VOLTAGE = 0x23, - AXP209_DCDC3_VOLTAGE = 0x27, - AXP209_LDO24_VOLTAGE = 0x28, - AXP209_LDO3_VOLTAGE = 0x29, - AXP209_IRQ_ENABLE1 = 0x40, - AXP209_IRQ_ENABLE2 = 0x41, - AXP209_IRQ_ENABLE3 = 0x42, - AXP209_IRQ_ENABLE4 = 0x43, - AXP209_IRQ_ENABLE5 = 0x44, - AXP209_IRQ_STATUS5 = 0x4c, - AXP209_SHUTDOWN = 0x32, - AXP209_GPIO0_CTRL = 0x90, - AXP209_GPIO1_CTRL = 0x92, - AXP209_GPIO2_CTRL = 0x93, - AXP209_GPIO_STATE = 0x94, - AXP209_GPIO3_CTRL = 0x95, -}; - -#define AXP209_POWER_STATUS_ON_BY_DC (1 << 0) - -#define AXP209_IRQ5_PEK_UP (1 << 6) -#define AXP209_IRQ5_PEK_DOWN (1 << 5) - -#define AXP209_POWEROFF (1 << 7) - -#define AXP209_GPIO_OUTPUT_LOW 0x00 /* Drive pin low */ -#define AXP209_GPIO_OUTPUT_HIGH 0x01 /* Drive pin high */ -#define AXP209_GPIO_INPUT 0x02 /* Float pin */ - -/* GPIO3 is different from the others */ -#define AXP209_GPIO3_OUTPUT_LOW 0x00 /* Drive pin low, Output mode */ -#define AXP209_GPIO3_OUTPUT_HIGH 0x02 /* Float pin, Output mode */ -#define AXP209_GPIO3_INPUT 0x06 /* Float pin, Input mode */ - static int axp209_write(enum axp209_reg reg, u8 val) { return i2c_write(0x34, reg, 1, &val, 1); @@ -205,6 +169,9 @@ static u8 axp209_get_gpio_ctrl_reg(unsigned int pin) int axp_gpio_direction_input(unsigned int pin) { + if (pin == SUNXI_GPIO_AXP0_VBUS_DETECT) + return 0; + u8 reg = axp209_get_gpio_ctrl_reg(pin); /* GPIO3 is "special" */ u8 val = (pin == 3) ? AXP209_GPIO3_INPUT : AXP209_GPIO_INPUT; @@ -232,7 +199,10 @@ int axp_gpio_get_value(unsigned int pin) u8 val, mask; int rc; - if (pin == 3) { + if (pin == SUNXI_GPIO_AXP0_VBUS_DETECT) { + rc = axp209_read(AXP209_POWER_STATUS, &val); + mask = AXP209_POWER_STATUS_VBUS_USABLE; + } else if (pin == 3) { rc = axp209_read(AXP209_GPIO3_CTRL, &val); mask = 1; } else { diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c index c2c3988..dc3a7f1 100644 --- a/drivers/power/axp221.c +++ b/drivers/power/axp221.c @@ -14,6 +14,7 @@ #include <errno.h> #include <asm/arch/p2wi.h> #include <asm/arch/rsb.h> +#include <asm/arch/gpio.h> #include <axp221.h> /* @@ -385,54 +386,66 @@ int axp221_get_sid(unsigned int *sid) return 0; } -int axp_get_vbus(void) +int axp_gpio_direction_input(unsigned int pin) { - int ret; - u8 val; - - ret = axp221_init(); - if (ret) - return ret; - - ret = pmic_bus_read(AXP221_POWER_STATUS, &val); - if (ret) - return ret; - - return (val & AXP221_POWER_STATUS_VBUS_USABLE) ? 1 : 0; + switch (pin) { + case SUNXI_GPIO_AXP0_VBUS_DETECT: + return 0; + default: + return -EINVAL; + } } -static int axp_drivebus_setup(void) +int axp_gpio_direction_output(unsigned int pin, unsigned int val) { int ret; - ret = axp221_init(); - if (ret) - return ret; + switch (pin) { + case SUNXI_GPIO_AXP0_VBUS_ENABLE: + ret = axp221_clrbits(AXP221_MISC_CTRL, + AXP221_MISC_CTRL_N_VBUSEN_FUNC); + if (ret) + return ret; - /* Set N_VBUSEN pin to output / DRIVEBUS function */ - return axp221_clrbits(AXP221_MISC_CTRL, AXP221_MISC_CTRL_N_VBUSEN_FUNC); + return axp_gpio_set_value(pin, val); + default: + return -EINVAL; + } } -int axp_drivebus_enable(void) +int axp_gpio_get_value(unsigned int pin) { int ret; + u8 val; - ret = axp_drivebus_setup(); - if (ret) - return ret; + switch (pin) { + case SUNXI_GPIO_AXP0_VBUS_DETECT: + ret = pmic_bus_read(AXP221_POWER_STATUS, &val); + if (ret) + return ret; - /* Set DRIVEBUS high */ - return axp221_setbits(AXP221_VBUS_IPSOUT, AXP221_VBUS_IPSOUT_DRIVEBUS); + return !!(val & AXP221_POWER_STATUS_VBUS_AVAIL); + default: + return -EINVAL; + } } -int axp_drivebus_disable(void) +int axp_gpio_set_value(unsigned int pin, unsigned int val) { int ret; - ret = axp_drivebus_setup(); - if (ret) - return ret; + switch (pin) { + case SUNXI_GPIO_AXP0_VBUS_ENABLE: + if (val) + ret = axp221_setbits(AXP221_VBUS_IPSOUT, + AXP221_VBUS_IPSOUT_DRIVEBUS); + else + ret = axp221_clrbits(AXP221_VBUS_IPSOUT, + AXP221_VBUS_IPSOUT_DRIVEBUS); - /* Set DRIVEBUS low */ - return axp221_clrbits(AXP221_VBUS_IPSOUT, AXP221_VBUS_IPSOUT_DRIVEBUS); + if (ret) + return ret; + } + + return 0; } diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c index d24651b..84e1433 100644 --- a/drivers/qe/qe.c +++ b/drivers/qe/qe.c @@ -196,6 +196,18 @@ void u_qe_init(void) } #endif +#ifdef CONFIG_U_QE +void u_qe_resume(void) +{ + qe_map_t *qe_immrr; + uint qe_base = CONFIG_SYS_IMMR + QE_IMMR_OFFSET; /* QE immr base */ + qe_immrr = (qe_map_t *)qe_base; + + u_qe_firmware_resume((const void *)CONFIG_SYS_QE_FW_ADDR, qe_immrr); + out_be32(&qe_immrr->iram.iready, QE_IRAM_READY); +} +#endif + void qe_reset(void) { qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID, @@ -580,6 +592,76 @@ int u_qe_upload_firmware(const struct qe_firmware *firmware) } #endif +#ifdef CONFIG_U_QE +int u_qe_firmware_resume(const struct qe_firmware *firmware, qe_map_t *qe_immrr) +{ + unsigned int i; + unsigned int j; + const struct qe_header *hdr; + const u32 *code; +#ifdef CONFIG_DEEP_SLEEP +#ifdef CONFIG_PPC + ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); +#else + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; +#endif +#endif + + if (!firmware) + return -EINVAL; + + hdr = &firmware->header; + + /* Check the magic */ + if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || + (hdr->magic[2] != 'F')) { +#ifdef CONFIG_DEEP_SLEEP + setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE); +#endif + return -EPERM; + } + + /* + * If the microcode calls for it, split the I-RAM. + */ + if (!firmware->split) { + out_be16(&qe_immrr->cp.cercr, + in_be16(&qe_immrr->cp.cercr) | QE_CP_CERCR_CIR); + } + + /* Loop through each microcode. */ + for (i = 0; i < firmware->count; i++) { + const struct qe_microcode *ucode = &firmware->microcode[i]; + + /* Upload a microcode if it's present */ + if (!ucode->code_offset) + return 0; + + code = (const void *)firmware + be32_to_cpu(ucode->code_offset); + + /* Use auto-increment */ + out_be32(&qe_immrr->iram.iadd, be32_to_cpu(ucode->iram_offset) | + QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR); + + for (i = 0; i < be32_to_cpu(ucode->count); i++) + out_be32(&qe_immrr->iram.idata, be32_to_cpu(code[i])); + + /* Program the traps for this processor */ + for (j = 0; j < 16; j++) { + u32 trap = be32_to_cpu(ucode->traps[j]); + + if (trap) + out_be32(&qe_immrr->rsp[i].tibcr[j], trap); + } + + /* Enable traps */ + out_be32(&qe_immrr->rsp[i].eccr, be32_to_cpu(ucode->eccr)); + } + + return 0; +} +#endif + struct qe_firmware_info *qe_get_firmware_info(void) { return qe_firmware_uploaded ? &qe_firmware_info : NULL; diff --git a/drivers/qe/qe.h b/drivers/qe/qe.h index 33878f8..77b18e9 100644 --- a/drivers/qe/qe.h +++ b/drivers/qe/qe.h @@ -11,6 +11,9 @@ #define __QE_H__ #include "common.h" +#ifdef CONFIG_U_QE +#include <linux/immap_qe.h> +#endif #define QE_NUM_OF_BRGS 16 #define UCC_MAX_NUM 8 @@ -288,6 +291,9 @@ void qe_reset(void); #ifdef CONFIG_U_QE void u_qe_init(void); int u_qe_upload_firmware(const struct qe_firmware *firmware); +void u_qe_resume(void); +int u_qe_firmware_resume(const struct qe_firmware *firmware, + qe_map_t *qe_immrr); #endif #endif /* __QE_H__ */ diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c index c91f084..e0ab04a 100644 --- a/drivers/qe/uec.c +++ b/drivers/qe/uec.c @@ -1333,7 +1333,7 @@ static int uec_recv(struct eth_device* dev) if (!(status & RxBD_ERROR)) { data = BD_DATA(bd); len = BD_LENGTH(bd); - NetReceive(data, len); + net_process_received_packet(data, len); } else { printf("%s: Rx error\n", dev->name); } diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 1686a1f..54e6f26 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -66,6 +66,16 @@ config DEBUG_UART_CLOCK A default should be provided by your board, but if not you will need to use the correct value here. +config DEBUG_UART_SHIFT + int "UART register shift" + depends on DEBUG_UART + default 0 if DEBUG_UART + help + Some UARTs (notably ns16550) support different register layouts + where the registers are spaced either as bytes, words or some other + value. Use this value to specify the shift to use, where 0=byte + registers, 2=32-bit word registers, etc. + config UNIPHIER_SERIAL bool "UniPhier on-chip UART support" depends on ARCH_UNIPHIER && DM_SERIAL diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index b385852..d183eed 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o obj-$(CONFIG_X86_SERIAL) += serial_x86.o +obj-$(CONFIG_STM32_SERIAL) += serial_stm32.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_USB_TTY) += usbtty.o diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 03beab5..3d376d7 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -8,6 +8,7 @@ #include <dm.h> #include <errno.h> #include <fdtdec.h> +#include <mapmem.h> #include <ns16550.h> #include <serial.h> #include <watchdog.h> @@ -56,7 +57,7 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_DM_SERIAL -static inline void serial_out_shift(unsigned char *addr, int shift, int value) +static inline void serial_out_shift(void *addr, int shift, int value) { #ifdef CONFIG_SYS_NS16550_PORT_MAPPED outb(value, (ulong)addr); @@ -71,7 +72,7 @@ static inline void serial_out_shift(unsigned char *addr, int shift, int value) #endif } -static inline int serial_in_shift(unsigned char *addr, int shift) +static inline int serial_in_shift(void *addr, int shift) { #ifdef CONFIG_SYS_NS16550_PORT_MAPPED return inb((ulong)addr); @@ -113,9 +114,11 @@ static int ns16550_readb(NS16550_t port, int offset) /* We can clean these up once everything is moved to driver model */ #define serial_out(value, addr) \ - ns16550_writeb(com_port, addr - (unsigned char *)com_port, value) + ns16550_writeb(com_port, \ + (unsigned char *)addr - (unsigned char *)com_port, value) #define serial_in(addr) \ - ns16550_readb(com_port, addr - (unsigned char *)com_port) + ns16550_readb(com_port, \ + (unsigned char *)addr - (unsigned char *)com_port) #endif static inline int calc_divisor(NS16550_t port, int clock, int baudrate) @@ -172,7 +175,6 @@ void NS16550_init(NS16550_t com_port, int baud_divisor) defined(CONFIG_TI81XX) || defined(CONFIG_AM43XX) serial_out(0x7, &com_port->mdr1); /* mode select reset TL16C750*/ #endif - NS16550_setbrg(com_port, 0); serial_out(UART_MCRVAL, &com_port->mcr); serial_out(UART_FCRVAL, &com_port->fcr); if (baud_divisor != -1) @@ -253,15 +255,19 @@ void debug_uart_init(void) */ baud_divisor = calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE); - - serial_out_shift(&com_port->ier, 0, CONFIG_SYS_NS16550_IER); - serial_out_shift(&com_port->mcr, 0, UART_MCRVAL); - serial_out_shift(&com_port->fcr, 0, UART_FCRVAL); - - serial_out_shift(&com_port->lcr, 0, UART_LCR_BKSE | UART_LCRVAL); - serial_out_shift(&com_port->dll, 0, baud_divisor & 0xff); - serial_out_shift(&com_port->dlm, 0, (baud_divisor >> 8) & 0xff); - serial_out_shift(&com_port->lcr, 0, UART_LCRVAL); + serial_out_shift(&com_port->ier, CONFIG_DEBUG_UART_SHIFT, + CONFIG_SYS_NS16550_IER); + serial_out_shift(&com_port->mcr, CONFIG_DEBUG_UART_SHIFT, UART_MCRVAL); + serial_out_shift(&com_port->fcr, CONFIG_DEBUG_UART_SHIFT, UART_FCRVAL); + + serial_out_shift(&com_port->lcr, CONFIG_DEBUG_UART_SHIFT, + UART_LCR_BKSE | UART_LCRVAL); + serial_out_shift(&com_port->dll, CONFIG_DEBUG_UART_SHIFT, + baud_divisor & 0xff); + serial_out_shift(&com_port->dlm, CONFIG_DEBUG_UART_SHIFT, + (baud_divisor >> 8) & 0xff); + serial_out_shift(&com_port->lcr, CONFIG_DEBUG_UART_SHIFT, + UART_LCRVAL); } static inline void _debug_uart_putc(int ch) @@ -270,7 +276,7 @@ static inline void _debug_uart_putc(int ch) while (!(serial_in_shift(&com_port->lsr, 0) & UART_LSR_THRE)) ; - serial_out_shift(&com_port->thr, 0, ch); + serial_out_shift(&com_port->thr, CONFIG_DEBUG_UART_SHIFT, ch); } DEBUG_UART_FUNCS diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 2de3737..b8c2f48 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -70,7 +70,7 @@ static void serial_find_console_or_panic(void) if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) && uclass_get_device(UCLASS_SERIAL, INDEX, &dev) && (uclass_first_device(UCLASS_SERIAL, &dev) || !dev)) - panic("No serial driver found"); + panic_str("No serial driver found"); #undef INDEX gd->cur_serial_dev = dev; } @@ -251,7 +251,7 @@ static int serial_post_probe(struct udevice *dev) { struct dm_serial_ops *ops = serial_get_ops(dev); #ifdef CONFIG_DM_STDIO - struct serial_dev_priv *upriv = dev->uclass_priv; + struct serial_dev_priv *upriv = dev_get_uclass_priv(dev); struct stdio_dev sdev; #endif int ret; @@ -299,7 +299,7 @@ static int serial_post_probe(struct udevice *dev) static int serial_pre_remove(struct udevice *dev) { #ifdef CONFIG_SYS_STDIO_DEREGISTER - struct serial_dev_priv *upriv = dev->uclass_priv; + struct serial_dev_priv *upriv = dev_get_uclass_priv(dev); if (stdio_deregister_dev(upriv->sdev, 0)) return -EPERM; diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index 9f78492..699c410 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -154,6 +154,7 @@ serial_initfunc(sa1100_serial_initialize); serial_initfunc(sandbox_serial_initialize); serial_initfunc(sconsole_serial_initialize); serial_initfunc(sh_serial_initialize); +serial_initfunc(stm32_serial_initialize); serial_initfunc(uartlite_serial_initialize); serial_initfunc(zynq_serial_initialize); @@ -246,6 +247,7 @@ void serial_initialize(void) sandbox_serial_initialize(); sconsole_serial_initialize(); sh_serial_initialize(); + stm32_serial_initialize(); uartlite_serial_initialize(); zynq_serial_initialize(); diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index 75eb6bd..2124161 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -95,7 +95,7 @@ static int pl01x_generic_serial_init(struct pl01x_regs *regs, return 0; } -static int set_line_control(struct pl01x_regs *regs) +static int pl011_set_line_control(struct pl01x_regs *regs) { unsigned int lcr; /* @@ -129,6 +129,9 @@ static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type, case TYPE_PL010: { unsigned int divisor; + /* disable everything */ + writel(0, ®s->pl010_cr); + switch (baudrate) { case 9600: divisor = UART_PL010_BAUD_9600; @@ -152,6 +155,12 @@ static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type, writel((divisor & 0xf00) >> 8, ®s->pl010_lcrm); writel(divisor & 0xff, ®s->pl010_lcrl); + /* + * Set line control for the PL010 to be 8 bits, 1 stop bit, + * no parity, fifo enabled + */ + writel(UART_PL010_LCRH_WLEN_8 | UART_PL010_LCRH_FEN, + ®s->pl010_lcrh); /* Finally, enable the UART */ writel(UART_PL010_CR_UARTEN, ®s->pl010_cr); break; @@ -178,7 +187,7 @@ static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type, writel(divider, ®s->pl011_ibrd); writel(fraction, ®s->pl011_fbrd); - set_line_control(regs); + pl011_set_line_control(regs); /* Finally, enable the UART */ writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE | UART_PL011_CR_RTS, ®s->pl011_cr); diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c new file mode 100644 index 0000000..3c80096 --- /dev/null +++ b/drivers/serial/serial_stm32.c @@ -0,0 +1,117 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <serial.h> +#include <asm/arch/stm32.h> + +#define STM32_USART1_BASE (STM32_APB2PERIPH_BASE + 0x1000) +#define RCC_APB2ENR_USART1EN (1 << 4) + +#define USART_BASE STM32_USART1_BASE +#define RCC_USART_ENABLE RCC_APB2ENR_USART1EN + +struct stm32_serial { + u32 sr; + u32 dr; + u32 brr; + u32 cr1; + u32 cr2; + u32 cr3; + u32 gtpr; +}; + +#define USART_CR1_RE (1 << 2) +#define USART_CR1_TE (1 << 3) +#define USART_CR1_UE (1 << 13) + +#define USART_SR_FLAG_RXNE (1 << 5) +#define USART_SR_FLAG_TXE (1 << 7) + +#define USART_BRR_F_MASK 0xF +#define USART_BRR_M_SHIFT 4 +#define USART_BRR_M_MASK 0xFFF0 + +DECLARE_GLOBAL_DATA_PTR; + +static void stm32_serial_setbrg(void) +{ + serial_init(); +} + +static int stm32_serial_init(void) +{ + struct stm32_serial *usart = (struct stm32_serial *)USART_BASE; + u32 clock, int_div, frac_div, tmp; + + if ((USART_BASE & STM32_BUS_MASK) == STM32_APB1PERIPH_BASE) { + setbits_le32(&STM32_RCC->apb1enr, RCC_USART_ENABLE); + clock = clock_get(CLOCK_APB1); + } else if ((USART_BASE & STM32_BUS_MASK) == STM32_APB2PERIPH_BASE) { + setbits_le32(&STM32_RCC->apb2enr, RCC_USART_ENABLE); + clock = clock_get(CLOCK_APB2); + } else { + return -1; + } + + int_div = (25 * clock) / (4 * gd->baudrate); + tmp = ((int_div / 100) << USART_BRR_M_SHIFT) & USART_BRR_M_MASK; + frac_div = int_div - (100 * (tmp >> USART_BRR_M_SHIFT)); + tmp |= (((frac_div * 16) + 50) / 100) & USART_BRR_F_MASK; + + writel(tmp, &usart->brr); + setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE); + + return 0; +} + +static int stm32_serial_getc(void) +{ + struct stm32_serial *usart = (struct stm32_serial *)USART_BASE; + while ((readl(&usart->sr) & USART_SR_FLAG_RXNE) == 0) + ; + return readl(&usart->dr); +} + +static void stm32_serial_putc(const char c) +{ + struct stm32_serial *usart = (struct stm32_serial *)USART_BASE; + while ((readl(&usart->sr) & USART_SR_FLAG_TXE) == 0) + ; + writel(c, &usart->dr); +} + +static int stm32_serial_tstc(void) +{ + struct stm32_serial *usart = (struct stm32_serial *)USART_BASE; + u8 ret; + + ret = readl(&usart->sr) & USART_SR_FLAG_RXNE; + return ret; +} + +static struct serial_device stm32_serial_drv = { + .name = "stm32_serial", + .start = stm32_serial_init, + .stop = NULL, + .setbrg = stm32_serial_setbrg, + .putc = stm32_serial_putc, + .puts = default_serial_puts, + .getc = stm32_serial_getc, + .tstc = stm32_serial_tstc, +}; + +void stm32_serial_initialize(void) +{ + serial_register(&stm32_serial_drv); +} + +__weak struct serial_device *default_serial_console(void) +{ + return &stm32_serial_drv; +} diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c index 98e3b81..74547eb 100644 --- a/drivers/serial/serial_uniphier.c +++ b/drivers/serial/serial_uniphier.c @@ -11,6 +11,7 @@ #include <asm/errno.h> #include <dm/device.h> #include <dm/platform_data/serial-uniphier.h> +#include <mapmem.h> #include <serial.h> #include <fdtdec.h> diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c index 3e2b8dc..9278763 100644 --- a/drivers/serial/serial_zynq.c +++ b/drivers/serial/serial_zynq.c @@ -48,10 +48,16 @@ static void uart_zynq_serial_setbrg(const int port) /* Calculation results. */ unsigned int calc_bauderror, bdiv, bgen; unsigned long calc_baud = 0; - unsigned long baud = gd->baudrate; + unsigned long baud; unsigned long clock = get_uart_clk(port); struct uart_zynq *regs = uart_zynq_ports[port]; + /* Covering case where input clock is so slow */ + if (clock < 1000000 && gd->baudrate > 4800) + gd->baudrate = 4800; + + baud = gd->baudrate; + /* master clock * Baud rate = ------------------ * bgen * (bdiv + 1) diff --git a/drivers/sound/Kconfig b/drivers/sound/Kconfig index e69de29..3b96e84 100644 --- a/drivers/sound/Kconfig +++ b/drivers/sound/Kconfig @@ -0,0 +1,55 @@ +config SOUND + bool "Enable sound support" + help + Support making sounds through an audio codec. This is normally a + beep at a chosen frequency for a selected length of time. However + the drivers support playing arbitrary sound samples using a + PCM interface. + + Note: At present the sound setup is somewhat tangled up in that the + audio codecs are called from the sound-i2s code. This could be + converted to driver model. + +config I2S + bool "Enable I2S support" + depends on SOUND + help + I2S is a serial bus often used to transmit audio data from the + SoC to the audio codec. This option enables sound support using + I2S. It calls either of the two supported codecs (no use is made + of driver model at present). + +config I2S_SAMSUNG + bool "Enable I2C support for Samsung SoCs" + depends on SOUND + help + Samsung Exynos SoCs support an I2S interface for sending audio + data to an audio codec. This option enables support for this, + using one of the available audio codec drivers. Enabling this + option provides an implementation for sound_init() and + sound_play(). + +config SOUND_MAX98095 + bool "Support Maxim max98095 audio codec" + depends on I2S_SAMSUNG + help + Enable the max98095 audio codec. This is connected via I2S for + audio data and I2C for codec control. At present it only works + with the Samsung I2S driver. + +config SOUND_SANDBOX + bool "Support sandbox emulated audio codec" + depends on SANDBOX && SOUND + help + U-Boot sandbox can emulate a sound device using SDL, playing the + sound on the host machine. This option implements the sound_init() + and sound_play() functions for sandbox. Note that you must install + the SDL libraries for this to work. + +config SOUND_WM8994 + bool "Support Wolfson Micro wm8994 audio codec" + depends on I2S_SAMSUNG + help + Enable the wm8994 audio codec. This is connected via I2S for + audio data and I2C for codec control. At present it only works + with the Samsung I2S driver. diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 7ae2727..357a335 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -10,3 +10,44 @@ config DM_SPI as 'parent data' to every slave on each bus. Slaves typically use driver-private data instead of extending the spi_slave structure. + +config SANDBOX_SPI + bool "Sandbox SPI driver" + depends on SANDBOX && DM + help + Enable SPI support for sandbox. This is an emulation of a real SPI + bus. Devices can be attached to the bus using the device tree + which specifies the driver to use. As an example, see this device + tree fragment from sandbox.dts. It shows that the SPI bus has a + single flash device on chip select 0 which is emulated by the driver + for "sandbox,spi-flash", which is in drivers/mtd/spi/sandbox.c. + + spi@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + compatible = "sandbox,spi"; + cs-gpios = <0>, <&gpio_a 0>; + flash@0 { + reg = <0>; + compatible = "spansion,m25p16", "sandbox,spi-flash"; + spi-max-frequency = <40000000>; + sandbox,filename = "spi.bin"; + }; + }; + +config DESIGNWARE_SPI + bool "Designware SPI driver" + depends on DM_SPI + help + Enable the Designware SPI driver. This driver can be used to + access the SPI NOR flash on platforms embedding this Designware + IP core. + +config CADENCE_QSPI + bool "Cadence QSPI driver" + depends on DM_SPI + help + Enable the Cadence Quad-SPI (QSPI) driver. This driver can be + used to access the SPI NOR flash on platforms embedding this + Cadence IP core. diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index ce6f1cc..e288692 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -50,3 +50,4 @@ obj-$(CONFIG_TI_QSPI) += ti_qspi.o obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o obj-$(CONFIG_ZYNQ_SPI) += zynq_spi.o obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o +obj-$(CONFIG_FSL_DSPI) += fsl_dspi.o diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c index a46d8c1..67f6b2d 100644 --- a/drivers/spi/exynos_spi.c +++ b/drivers/spi/exynos_spi.c @@ -296,8 +296,9 @@ static int exynos_spi_probe(struct udevice *bus) return 0; } -static int exynos_spi_claim_bus(struct udevice *bus) +static int exynos_spi_claim_bus(struct udevice *dev) { + struct udevice *bus = dev->parent; struct exynos_spi_priv *priv = dev_get_priv(bus); exynos_pinmux_config(priv->periph_id, PINMUX_FLAG_NONE); @@ -308,8 +309,9 @@ static int exynos_spi_claim_bus(struct udevice *bus) return 0; } -static int exynos_spi_release_bus(struct udevice *bus) +static int exynos_spi_release_bus(struct udevice *dev) { + struct udevice *bus = dev->parent; struct exynos_spi_priv *priv = dev_get_priv(bus); spi_flush_fifo(priv->regs); diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c new file mode 100644 index 0000000..6476f91 --- /dev/null +++ b/drivers/spi/fsl_dspi.c @@ -0,0 +1,737 @@ +/* + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2009, 2015 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * Chao Fu (B44548@freescale.com) + * Haikun Wang (B53464@freescale.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <dm.h> +#include <errno.h> +#include <common.h> +#include <spi.h> +#include <malloc.h> +#include <asm/io.h> +#include <fdtdec.h> +#ifndef CONFIG_M68K +#include <asm/arch/clock.h> +#endif +#include <fsl_dspi.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* fsl_dspi_platdata flags */ +#define DSPI_FLAG_REGMAP_ENDIAN_BIG (1 << 0) + +/* idle data value */ +#define DSPI_IDLE_VAL 0x0 + +/* max chipselect signals number */ +#define FSL_DSPI_MAX_CHIPSELECT 6 + +/* default SCK frequency, unit: HZ */ +#define FSL_DSPI_DEFAULT_SCK_FREQ 10000000 + +/* tx/rx data wait timeout value, unit: us */ +#define DSPI_TXRX_WAIT_TIMEOUT 1000000 + +/* CTAR register pre-configure value */ +#define DSPI_CTAR_DEFAULT_VALUE (DSPI_CTAR_TRSZ(7) | \ + DSPI_CTAR_PCSSCK_1CLK | \ + DSPI_CTAR_PASC(0) | \ + DSPI_CTAR_PDT(0) | \ + DSPI_CTAR_CSSCK(0) | \ + DSPI_CTAR_ASC(0) | \ + DSPI_CTAR_DT(0)) + +/* CTAR register pre-configure mask */ +#define DSPI_CTAR_SET_MODE_MASK (DSPI_CTAR_TRSZ(15) | \ + DSPI_CTAR_PCSSCK(3) | \ + DSPI_CTAR_PASC(3) | \ + DSPI_CTAR_PDT(3) | \ + DSPI_CTAR_CSSCK(15) | \ + DSPI_CTAR_ASC(15) | \ + DSPI_CTAR_DT(15)) + +/** + * struct fsl_dspi_platdata - platform data for Freescale DSPI + * + * @flags: Flags for DSPI DSPI_FLAG_... + * @speed_hz: Default SCK frequency + * @num_chipselect: Number of DSPI chipselect signals + * @regs_addr: Base address of DSPI registers + */ +struct fsl_dspi_platdata { + uint flags; + uint speed_hz; + uint num_chipselect; + fdt_addr_t regs_addr; +}; + +/** + * struct fsl_dspi_priv - private data for Freescale DSPI + * + * @flags: Flags for DSPI DSPI_FLAG_... + * @mode: SPI mode to use for slave device (see SPI mode flags) + * @mcr_val: MCR register configure value + * @bus_clk: DSPI input clk frequency + * @speed_hz: Default SCK frequency + * @charbit: How many bits in every transfer + * @num_chipselect: Number of DSPI chipselect signals + * @ctar_val: CTAR register configure value of per chipselect slave device + * @regs: Point to DSPI register structure for I/O access + */ +struct fsl_dspi_priv { + uint flags; + uint mode; + uint mcr_val; + uint bus_clk; + uint speed_hz; + uint charbit; + uint num_chipselect; + uint ctar_val[FSL_DSPI_MAX_CHIPSELECT]; + struct dspi *regs; +}; + +#ifndef CONFIG_DM_SPI +struct fsl_dspi { + struct spi_slave slave; + struct fsl_dspi_priv priv; +}; +#endif + +__weak void cpu_dspi_port_conf(void) +{ +} + +__weak int cpu_dspi_claim_bus(uint bus, uint cs) +{ + return 0; +} + +__weak void cpu_dspi_release_bus(uint bus, uint cs) +{ +} + +static uint dspi_read32(uint flags, uint *addr) +{ + return flags & DSPI_FLAG_REGMAP_ENDIAN_BIG ? + in_be32(addr) : in_le32(addr); +} + +static void dspi_write32(uint flags, uint *addr, uint val) +{ + flags & DSPI_FLAG_REGMAP_ENDIAN_BIG ? + out_be32(addr, val) : out_le32(addr, val); +} + +static void dspi_halt(struct fsl_dspi_priv *priv, u8 halt) +{ + uint mcr_val; + + mcr_val = dspi_read32(priv->flags, &priv->regs->mcr); + + if (halt) + mcr_val |= DSPI_MCR_HALT; + else + mcr_val &= ~DSPI_MCR_HALT; + + dspi_write32(priv->flags, &priv->regs->mcr, mcr_val); +} + +static void fsl_dspi_init_mcr(struct fsl_dspi_priv *priv, uint cfg_val) +{ + /* halt DSPI module */ + dspi_halt(priv, 1); + + dspi_write32(priv->flags, &priv->regs->mcr, cfg_val); + + /* resume module */ + dspi_halt(priv, 0); + + priv->mcr_val = cfg_val; +} + +static void fsl_dspi_cfg_cs_active_state(struct fsl_dspi_priv *priv, + uint cs, uint state) +{ + uint mcr_val; + + dspi_halt(priv, 1); + + mcr_val = dspi_read32(priv->flags, &priv->regs->mcr); + if (state & SPI_CS_HIGH) + /* CSx inactive state is low */ + mcr_val &= ~DSPI_MCR_PCSIS(cs); + else + /* CSx inactive state is high */ + mcr_val |= DSPI_MCR_PCSIS(cs); + dspi_write32(priv->flags, &priv->regs->mcr, mcr_val); + + dspi_halt(priv, 0); +} + +static int fsl_dspi_cfg_ctar_mode(struct fsl_dspi_priv *priv, + uint cs, uint mode) +{ + uint bus_setup; + + bus_setup = dspi_read32(priv->flags, &priv->regs->ctar[0]); + + bus_setup &= ~DSPI_CTAR_SET_MODE_MASK; + bus_setup |= priv->ctar_val[cs]; + bus_setup &= ~(DSPI_CTAR_CPOL | DSPI_CTAR_CPHA | DSPI_CTAR_LSBFE); + + if (mode & SPI_CPOL) + bus_setup |= DSPI_CTAR_CPOL; + if (mode & SPI_CPHA) + bus_setup |= DSPI_CTAR_CPHA; + if (mode & SPI_LSB_FIRST) + bus_setup |= DSPI_CTAR_LSBFE; + + dspi_write32(priv->flags, &priv->regs->ctar[0], bus_setup); + + priv->charbit = + ((dspi_read32(priv->flags, &priv->regs->ctar[0]) & + DSPI_CTAR_TRSZ(15)) == DSPI_CTAR_TRSZ(15)) ? 16 : 8; + + return 0; +} + +static void fsl_dspi_clr_fifo(struct fsl_dspi_priv *priv) +{ + uint mcr_val; + + dspi_halt(priv, 1); + mcr_val = dspi_read32(priv->flags, &priv->regs->mcr); + /* flush RX and TX FIFO */ + mcr_val |= (DSPI_MCR_CTXF | DSPI_MCR_CRXF); + dspi_write32(priv->flags, &priv->regs->mcr, mcr_val); + dspi_halt(priv, 0); +} + +static void dspi_tx(struct fsl_dspi_priv *priv, u32 ctrl, u16 data) +{ + int timeout = DSPI_TXRX_WAIT_TIMEOUT; + + /* wait for empty entries in TXFIFO or timeout */ + while (DSPI_SR_TXCTR(dspi_read32(priv->flags, &priv->regs->sr)) >= 4 && + timeout--) + udelay(1); + + if (timeout >= 0) + dspi_write32(priv->flags, &priv->regs->tfr, (ctrl | data)); + else + debug("dspi_tx: waiting timeout!\n"); +} + +static u16 dspi_rx(struct fsl_dspi_priv *priv) +{ + int timeout = DSPI_TXRX_WAIT_TIMEOUT; + + /* wait for valid entries in RXFIFO or timeout */ + while (DSPI_SR_RXCTR(dspi_read32(priv->flags, &priv->regs->sr)) == 0 && + timeout--) + udelay(1); + + if (timeout >= 0) + return (u16)DSPI_RFR_RXDATA( + dspi_read32(priv->flags, &priv->regs->rfr)); + else { + debug("dspi_rx: waiting timeout!\n"); + return (u16)(~0); + } +} + +static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + u16 *spi_rd16 = NULL, *spi_wr16 = NULL; + u8 *spi_rd = NULL, *spi_wr = NULL; + static u32 ctrl; + uint len = bitlen >> 3; + + if (priv->charbit == 16) { + bitlen >>= 1; + spi_wr16 = (u16 *)dout; + spi_rd16 = (u16 *)din; + } else { + spi_wr = (u8 *)dout; + spi_rd = (u8 *)din; + } + + if ((flags & SPI_XFER_BEGIN) == SPI_XFER_BEGIN) + ctrl |= DSPI_TFR_CONT; + + ctrl = ctrl & DSPI_TFR_CONT; + ctrl = ctrl | DSPI_TFR_CTAS(0) | DSPI_TFR_PCS(cs); + + if (len > 1) { + int tmp_len = len - 1; + while (tmp_len--) { + if (dout != NULL) { + if (priv->charbit == 16) + dspi_tx(priv, ctrl, *spi_wr16++); + else + dspi_tx(priv, ctrl, *spi_wr++); + dspi_rx(priv); + } + + if (din != NULL) { + dspi_tx(priv, ctrl, DSPI_IDLE_VAL); + if (priv->charbit == 16) + *spi_rd16++ = dspi_rx(priv); + else + *spi_rd++ = dspi_rx(priv); + } + } + + len = 1; /* remaining byte */ + } + + if ((flags & SPI_XFER_END) == SPI_XFER_END) + ctrl &= ~DSPI_TFR_CONT; + + if (len) { + if (dout != NULL) { + if (priv->charbit == 16) + dspi_tx(priv, ctrl, *spi_wr16); + else + dspi_tx(priv, ctrl, *spi_wr); + dspi_rx(priv); + } + + if (din != NULL) { + dspi_tx(priv, ctrl, DSPI_IDLE_VAL); + if (priv->charbit == 16) + *spi_rd16 = dspi_rx(priv); + else + *spi_rd = dspi_rx(priv); + } + } else { + /* dummy read */ + dspi_tx(priv, ctrl, DSPI_IDLE_VAL); + dspi_rx(priv); + } + + return 0; +} + +/** + * Calculate the divide value between input clk frequency and expected SCK frequency + * Formula: SCK = (clkrate/pbr) x ((1+dbr)/br) + * Dbr: use default value 0 + * + * @pbr: return Baud Rate Prescaler value + * @br: return Baud Rate Scaler value + * @speed_hz: expected SCK frequency + * @clkrate: input clk frequency + */ +static int fsl_dspi_hz_to_spi_baud(int *pbr, int *br, + int speed_hz, uint clkrate) +{ + /* Valid baud rate pre-scaler values */ + int pbr_tbl[4] = {2, 3, 5, 7}; + int brs[16] = {2, 4, 6, 8, + 16, 32, 64, 128, + 256, 512, 1024, 2048, + 4096, 8192, 16384, 32768}; + int temp, i = 0, j = 0; + + temp = clkrate / speed_hz; + + for (i = 0; i < ARRAY_SIZE(pbr_tbl); i++) + for (j = 0; j < ARRAY_SIZE(brs); j++) { + if (pbr_tbl[i] * brs[j] >= temp) { + *pbr = i; + *br = j; + return 0; + } + } + + debug("Can not find valid baud rate,speed_hz is %d, ", speed_hz); + debug("clkrate is %d, we use the max prescaler value.\n", clkrate); + + *pbr = ARRAY_SIZE(pbr_tbl) - 1; + *br = ARRAY_SIZE(brs) - 1; + return -EINVAL; +} + +static int fsl_dspi_cfg_speed(struct fsl_dspi_priv *priv, uint speed) +{ + int ret; + uint bus_setup; + int best_i, best_j, bus_clk; + + bus_clk = priv->bus_clk; + + debug("DSPI set_speed: expected SCK speed %u, bus_clk %u.\n", + speed, bus_clk); + + bus_setup = dspi_read32(priv->flags, &priv->regs->ctar[0]); + bus_setup &= ~(DSPI_CTAR_DBR | DSPI_CTAR_PBR(0x3) | DSPI_CTAR_BR(0xf)); + + ret = fsl_dspi_hz_to_spi_baud(&best_i, &best_j, speed, bus_clk); + if (ret) { + speed = priv->speed_hz; + debug("DSPI set_speed use default SCK rate %u.\n", speed); + fsl_dspi_hz_to_spi_baud(&best_i, &best_j, speed, bus_clk); + } + + bus_setup |= (DSPI_CTAR_PBR(best_i) | DSPI_CTAR_BR(best_j)); + dspi_write32(priv->flags, &priv->regs->ctar[0], bus_setup); + + priv->speed_hz = speed; + + return 0; +} +#ifndef CONFIG_DM_SPI +void spi_init(void) +{ + /* Nothing to do */ +} + +void spi_init_f(void) +{ + /* Nothing to do */ +} + +void spi_init_r(void) +{ + /* Nothing to do */ +} + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + if (((cs >= 0) && (cs < 8)) && ((bus >= 0) && (bus < 8))) + return 1; + else + return 0; +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct fsl_dspi *dspi; + uint mcr_cfg_val; + + dspi = spi_alloc_slave(struct fsl_dspi, bus, cs); + if (!dspi) + return NULL; + + cpu_dspi_port_conf(); + +#ifdef CONFIG_SYS_FSL_DSPI_BE + dspi->priv.flags |= DSPI_FLAG_REGMAP_ENDIAN_BIG; +#endif + + dspi->priv.regs = (struct dspi *)MMAP_DSPI; + +#ifdef CONFIG_M68K + dspi->priv.bus_clk = gd->bus_clk; +#else + dspi->priv.bus_clk = mxc_get_clock(MXC_DSPI_CLK); +#endif + dspi->priv.speed_hz = FSL_DSPI_DEFAULT_SCK_FREQ; + + /* default: all CS signals inactive state is high */ + mcr_cfg_val = DSPI_MCR_MSTR | DSPI_MCR_PCSIS_MASK | + DSPI_MCR_CRXF | DSPI_MCR_CTXF; + fsl_dspi_init_mcr(&dspi->priv, mcr_cfg_val); + + for (i = 0; i < FSL_DSPI_MAX_CHIPSELECT; i++) + dspi->priv.ctar_val[i] = DSPI_CTAR_DEFAULT_VALUE; + +#ifdef CONFIG_SYS_DSPI_CTAR0 + if (FSL_DSPI_MAX_CHIPSELECT > 0) + dspi->priv.ctar_val[0] = CONFIG_SYS_DSPI_CTAR0; +#endif +#ifdef CONFIG_SYS_DSPI_CTAR1 + if (FSL_DSPI_MAX_CHIPSELECT > 1) + dspi->priv.ctar_val[1] = CONFIG_SYS_DSPI_CTAR1; +#endif +#ifdef CONFIG_SYS_DSPI_CTAR2 + if (FSL_DSPI_MAX_CHIPSELECT > 2) + dspi->priv.ctar_val[2] = CONFIG_SYS_DSPI_CTAR2; +#endif +#ifdef CONFIG_SYS_DSPI_CTAR3 + if (FSL_DSPI_MAX_CHIPSELECT > 3) + dspi->priv.ctar_val[3] = CONFIG_SYS_DSPI_CTAR3; +#endif +#ifdef CONFIG_SYS_DSPI_CTAR4 + if (FSL_DSPI_MAX_CHIPSELECT > 4) + dspi->priv.ctar_val[4] = CONFIG_SYS_DSPI_CTAR4; +#endif +#ifdef CONFIG_SYS_DSPI_CTAR5 + if (FSL_DSPI_MAX_CHIPSELECT > 5) + dspi->priv.ctar_val[5] = CONFIG_SYS_DSPI_CTAR5; +#endif +#ifdef CONFIG_SYS_DSPI_CTAR6 + if (FSL_DSPI_MAX_CHIPSELECT > 6) + dspi->priv.ctar_val[6] = CONFIG_SYS_DSPI_CTAR6; +#endif +#ifdef CONFIG_SYS_DSPI_CTAR7 + if (FSL_DSPI_MAX_CHIPSELECT > 7) + dspi->priv.ctar_val[7] = CONFIG_SYS_DSPI_CTAR7; +#endif + + fsl_dspi_cfg_speed(&dspi->priv, max_hz); + + /* configure transfer mode */ + fsl_dspi_cfg_ctar_mode(&dspi->priv, cs, mode); + + /* configure active state of CSX */ + fsl_dspi_cfg_cs_active_state(&dspi->priv, cs, mode); + + return &dspi->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + free(slave); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + uint sr_val; + struct fsl_dspi *dspi = (struct fsl_dspi *)slave; + + cpu_dspi_claim_bus(slave->bus, slave->cs); + + fsl_dspi_clr_fifo(&dspi->priv); + + /* check module TX and RX status */ + sr_val = dspi_read32(dspi->priv.flags, &dspi->priv.regs->sr); + if ((sr_val & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) { + debug("DSPI RX/TX not ready!\n"); + return -EIO; + } + + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + struct fsl_dspi *dspi = (struct fsl_dspi *)slave; + + dspi_halt(&dspi->priv, 1); + cpu_dspi_release_bus(slave->bus.slave->cs); +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + struct fsl_dspi *dspi = (struct fsl_dspi *)slave; + return dspi_xfer(&dspi->priv, slave->cs, bitlen, dout, din, flags); +} +#else +static int fsl_dspi_child_pre_probe(struct udevice *dev) +{ + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); + struct fsl_dspi_priv *priv = dev_get_priv(dev->parent); + + if (slave_plat->cs >= priv->num_chipselect) { + debug("DSPI invalid chipselect number %d(max %d)!\n", + slave_plat->cs, priv->num_chipselect - 1); + return -EINVAL; + } + + priv->ctar_val[slave_plat->cs] = DSPI_CTAR_DEFAULT_VALUE; + + debug("DSPI pre_probe slave device on CS %u, max_hz %u, mode 0x%x.\n", + slave_plat->cs, slave_plat->max_hz, slave_plat->mode); + + return 0; +} + +static int fsl_dspi_probe(struct udevice *bus) +{ + struct fsl_dspi_platdata *plat = dev_get_platdata(bus); + struct fsl_dspi_priv *priv = dev_get_priv(bus); + struct dm_spi_bus *dm_spi_bus; + uint mcr_cfg_val; + + dm_spi_bus = bus->uclass_priv; + + /* cpu speical pin muxing configure */ + cpu_dspi_port_conf(); + + /* get input clk frequency */ + priv->regs = (struct dspi *)plat->regs_addr; + priv->flags = plat->flags; +#ifdef CONFIG_M68K + priv->bus_clk = gd->bus_clk; +#else + priv->bus_clk = mxc_get_clock(MXC_DSPI_CLK); +#endif + priv->num_chipselect = plat->num_chipselect; + priv->speed_hz = plat->speed_hz; + /* frame data length in bits, default 8bits */ + priv->charbit = 8; + + dm_spi_bus->max_hz = plat->speed_hz; + + /* default: all CS signals inactive state is high */ + mcr_cfg_val = DSPI_MCR_MSTR | DSPI_MCR_PCSIS_MASK | + DSPI_MCR_CRXF | DSPI_MCR_CTXF; + fsl_dspi_init_mcr(priv, mcr_cfg_val); + + debug("%s probe done, bus-num %d.\n", bus->name, bus->seq); + + return 0; +} + +static int fsl_dspi_claim_bus(struct udevice *dev) +{ + uint sr_val; + struct fsl_dspi_priv *priv; + struct udevice *bus = dev->parent; + struct dm_spi_slave_platdata *slave_plat = + dev_get_parent_platdata(dev); + + priv = dev_get_priv(bus); + + /* processor special prepartion work */ + cpu_dspi_claim_bus(bus->seq, slave_plat->cs); + + /* configure transfer mode */ + fsl_dspi_cfg_ctar_mode(priv, slave_plat->cs, priv->mode); + + /* configure active state of CSX */ + fsl_dspi_cfg_cs_active_state(priv, slave_plat->cs, + priv->mode); + + fsl_dspi_clr_fifo(priv); + + /* check module TX and RX status */ + sr_val = dspi_read32(priv->flags, &priv->regs->sr); + if ((sr_val & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) { + debug("DSPI RX/TX not ready!\n"); + return -EIO; + } + + return 0; +} + +static int fsl_dspi_release_bus(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct fsl_dspi_priv *priv = dev_get_priv(bus); + struct dm_spi_slave_platdata *slave_plat = + dev_get_parent_platdata(dev); + + /* halt module */ + dspi_halt(priv, 1); + + /* processor special release work */ + cpu_dspi_release_bus(bus->seq, slave_plat->cs); + + return 0; +} + +/** + * This function doesn't do anything except help with debugging + */ +static int fsl_dspi_bind(struct udevice *bus) +{ + debug("%s assigned req_seq %d.\n", bus->name, bus->req_seq); + return 0; +} + +static int fsl_dspi_ofdata_to_platdata(struct udevice *bus) +{ + fdt_addr_t addr; + struct fsl_dspi_platdata *plat = bus->platdata; + const void *blob = gd->fdt_blob; + int node = bus->of_offset; + + if (fdtdec_get_bool(blob, node, "big-endian")) + plat->flags |= DSPI_FLAG_REGMAP_ENDIAN_BIG; + + plat->num_chipselect = + fdtdec_get_int(blob, node, "num-cs", FSL_DSPI_MAX_CHIPSELECT); + + addr = fdtdec_get_addr(blob, node, "reg"); + if (addr == FDT_ADDR_T_NONE) { + debug("DSPI: Can't get base address or size\n"); + return -ENOMEM; + } + plat->regs_addr = addr; + + plat->speed_hz = fdtdec_get_int(blob, + node, "spi-max-frequency", FSL_DSPI_DEFAULT_SCK_FREQ); + + debug("DSPI: regs=0x%x, max-frequency=%d, endianess=%s, num-cs=%d\n", + plat->regs_addr, plat->speed_hz, + plat->flags & DSPI_FLAG_REGMAP_ENDIAN_BIG ? "be" : "le", + plat->num_chipselect); + + return 0; +} + +static int fsl_dspi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct fsl_dspi_priv *priv; + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + return dspi_xfer(priv, slave_plat->cs, bitlen, dout, din, flags); +} + +static int fsl_dspi_set_speed(struct udevice *bus, uint speed) +{ + struct fsl_dspi_priv *priv = dev_get_priv(bus); + + return fsl_dspi_cfg_speed(priv, speed); +} + +static int fsl_dspi_set_mode(struct udevice *bus, uint mode) +{ + struct fsl_dspi_priv *priv = dev_get_priv(bus); + + debug("DSPI set_mode: mode 0x%x.\n", mode); + + /* + * We store some chipselect special configure value in priv->ctar_val, + * and we can't get the correct chipselect number here, + * so just store mode value. + * Do really configuration when claim_bus. + */ + priv->mode = mode; + + return 0; +} + +static const struct dm_spi_ops fsl_dspi_ops = { + .claim_bus = fsl_dspi_claim_bus, + .release_bus = fsl_dspi_release_bus, + .xfer = fsl_dspi_xfer, + .set_speed = fsl_dspi_set_speed, + .set_mode = fsl_dspi_set_mode, +}; + +static const struct udevice_id fsl_dspi_ids[] = { + { .compatible = "fsl,vf610-dspi" }, + { } +}; + +U_BOOT_DRIVER(fsl_dspi) = { + .name = "fsl_dspi", + .id = UCLASS_SPI, + .of_match = fsl_dspi_ids, + .ops = &fsl_dspi_ops, + .ofdata_to_platdata = fsl_dspi_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct fsl_dspi_platdata), + .priv_auto_alloc_size = sizeof(struct fsl_dspi_priv), + .probe = fsl_dspi_probe, + .child_pre_probe = fsl_dspi_child_pre_probe, + .bind = fsl_dspi_bind, +}; +#endif diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index 5e0b069..868df5f 100644 --- a/drivers/spi/fsl_qspi.c +++ b/drivers/spi/fsl_qspi.c @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 Freescale Semiconductor, Inc. + * Copyright 2013-2015 Freescale Semiconductor, Inc. * * Freescale Quad Serial Peripheral Interface (QSPI) driver * @@ -11,8 +11,12 @@ #include <spi.h> #include <asm/io.h> #include <linux/sizes.h> +#include <dm.h> +#include <errno.h> #include "fsl_qspi.h" +DECLARE_GLOBAL_DATA_PTR; + #define RX_BUFFER_SIZE 0x80 #ifdef CONFIG_MX6SX #define TX_BUFFER_SIZE 0x200 @@ -63,35 +67,85 @@ #define QSPI_CMD_PP_4B 0x12 /* Page program (up to 256 bytes) */ #define QSPI_CMD_SE_4B 0xdc /* Sector erase (usually 64KiB) */ -#ifdef CONFIG_SYS_FSL_QSPI_LE -#define qspi_read32 in_le32 -#define qspi_write32 out_le32 -#elif defined(CONFIG_SYS_FSL_QSPI_BE) -#define qspi_read32 in_be32 -#define qspi_write32 out_be32 -#endif +/* fsl_qspi_platdata flags */ +#define QSPI_FLAG_REGMAP_ENDIAN_BIG (1 << 0) -static unsigned long spi_bases[] = { - QSPI0_BASE_ADDR, -#ifdef CONFIG_MX6SX - QSPI1_BASE_ADDR, -#endif -}; +/* default SCK frequency, unit: HZ */ +#define FSL_QSPI_DEFAULT_SCK_FREQ 50000000 -static unsigned long amba_bases[] = { - QSPI0_AMBA_BASE, -#ifdef CONFIG_MX6SX - QSPI1_AMBA_BASE, +/* QSPI max chipselect signals number */ +#define FSL_QSPI_MAX_CHIPSELECT_NUM 4 + +#ifdef CONFIG_DM_SPI +/** + * struct fsl_qspi_platdata - platform data for Freescale QSPI + * + * @flags: Flags for QSPI QSPI_FLAG_... + * @speed_hz: Default SCK frequency + * @reg_base: Base address of QSPI registers + * @amba_base: Base address of QSPI memory mapping + * @amba_total_size: size of QSPI memory mapping + * @flash_num: Number of active slave devices + * @num_chipselect: Number of QSPI chipselect signals + */ +struct fsl_qspi_platdata { + u32 flags; + u32 speed_hz; + u32 reg_base; + u32 amba_base; + u32 amba_total_size; + u32 flash_num; + u32 num_chipselect; +}; #endif + +/** + * struct fsl_qspi_priv - private data for Freescale QSPI + * + * @flags: Flags for QSPI QSPI_FLAG_... + * @bus_clk: QSPI input clk frequency + * @speed_hz: Default SCK frequency + * @cur_seqid: current LUT table sequence id + * @sf_addr: flash access offset + * @amba_base: Base address of QSPI memory mapping of every CS + * @amba_total_size: size of QSPI memory mapping + * @cur_amba_base: Base address of QSPI memory mapping of current CS + * @flash_num: Number of active slave devices + * @num_chipselect: Number of QSPI chipselect signals + * @regs: Point to QSPI register structure for I/O access + */ +struct fsl_qspi_priv { + u32 flags; + u32 bus_clk; + u32 speed_hz; + u32 cur_seqid; + u32 sf_addr; + u32 amba_base[FSL_QSPI_MAX_CHIPSELECT_NUM]; + u32 amba_total_size; + u32 cur_amba_base; + u32 flash_num; + u32 num_chipselect; + struct fsl_qspi_regs *regs; }; +#ifndef CONFIG_DM_SPI struct fsl_qspi { struct spi_slave slave; - unsigned long reg_base; - unsigned long amba_base; - u32 sf_addr; - u8 cur_seqid; + struct fsl_qspi_priv priv; }; +#endif + +static u32 qspi_read32(u32 flags, u32 *addr) +{ + return flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ? + in_be32(addr) : in_le32(addr); +} + +static void qspi_write32(u32 flags, u32 *addr, u32 val) +{ + flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ? + out_be32(addr, val) : out_le32(addr, val); +} /* QSPI support swapping the flash read/write data * in hardware for LS102xA, but not for VF610 */ @@ -104,131 +158,135 @@ static inline u32 qspi_endian_xchg(u32 data) #endif } -static inline struct fsl_qspi *to_qspi_spi(struct spi_slave *slave) -{ - return container_of(slave, struct fsl_qspi, slave); -} - -static void qspi_set_lut(struct fsl_qspi *qspi) +static void qspi_set_lut(struct fsl_qspi_priv *priv) { - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; + struct fsl_qspi_regs *regs = priv->regs; u32 lut_base; /* Unlock the LUT */ - qspi_write32(®s->lutkey, LUT_KEY_VALUE); - qspi_write32(®s->lckcr, QSPI_LCKCR_UNLOCK); + qspi_write32(priv->flags, ®s->lutkey, LUT_KEY_VALUE); + qspi_write32(priv->flags, ®s->lckcr, QSPI_LCKCR_UNLOCK); /* Write Enable */ lut_base = SEQID_WREN * 4; - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_WREN) | + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_WREN) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD)); - qspi_write32(®s->lut[lut_base + 1], 0); - qspi_write32(®s->lut[lut_base + 2], 0); - qspi_write32(®s->lut[lut_base + 3], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* Fast Read */ lut_base = SEQID_FAST_READ * 4; #ifdef CONFIG_SPI_FLASH_BAR - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_FAST_READ) | - PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | + qspi_write32(priv->flags, ®s->lut[lut_base], + OPRND0(QSPI_CMD_FAST_READ) | PAD0(LUT_PAD1) | + INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); #else if (FSL_QSPI_FLASH_SIZE <= SZ_16M) - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_FAST_READ) | - PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | - PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); + qspi_write32(priv->flags, ®s->lut[lut_base], + OPRND0(QSPI_CMD_FAST_READ) | PAD0(LUT_PAD1) | + INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | + PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); else - qspi_write32(®s->lut[lut_base], + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_FAST_READ_4B) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); #endif - qspi_write32(®s->lut[lut_base + 1], OPRND0(8) | PAD0(LUT_PAD1) | - INSTR0(LUT_DUMMY) | OPRND1(RX_BUFFER_SIZE) | PAD1(LUT_PAD1) | - INSTR1(LUT_READ)); - qspi_write32(®s->lut[lut_base + 2], 0); - qspi_write32(®s->lut[lut_base + 3], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 1], + OPRND0(8) | PAD0(LUT_PAD1) | INSTR0(LUT_DUMMY) | + OPRND1(RX_BUFFER_SIZE) | PAD1(LUT_PAD1) | + INSTR1(LUT_READ)); + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* Read Status */ lut_base = SEQID_RDSR * 4; - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_RDSR) | + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_RDSR) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) | PAD1(LUT_PAD1) | INSTR1(LUT_READ)); - qspi_write32(®s->lut[lut_base + 1], 0); - qspi_write32(®s->lut[lut_base + 2], 0); - qspi_write32(®s->lut[lut_base + 3], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* Erase a sector */ lut_base = SEQID_SE * 4; #ifdef CONFIG_SPI_FLASH_BAR - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_SE) | + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_SE) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); #else if (FSL_QSPI_FLASH_SIZE <= SZ_16M) - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_SE) | - PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | - PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); + qspi_write32(priv->flags, ®s->lut[lut_base], + OPRND0(QSPI_CMD_SE) | PAD0(LUT_PAD1) | + INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | + PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); else - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_SE_4B) | - PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | - PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); + qspi_write32(priv->flags, ®s->lut[lut_base], + OPRND0(QSPI_CMD_SE_4B) | PAD0(LUT_PAD1) | + INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | + PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); #endif - qspi_write32(®s->lut[lut_base + 1], 0); - qspi_write32(®s->lut[lut_base + 2], 0); - qspi_write32(®s->lut[lut_base + 3], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* Erase the whole chip */ lut_base = SEQID_CHIP_ERASE * 4; - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_CHIP_ERASE) | - PAD0(LUT_PAD1) | INSTR0(LUT_CMD)); - qspi_write32(®s->lut[lut_base + 1], 0); - qspi_write32(®s->lut[lut_base + 2], 0); - qspi_write32(®s->lut[lut_base + 3], 0); + qspi_write32(priv->flags, ®s->lut[lut_base], + OPRND0(QSPI_CMD_CHIP_ERASE) | + PAD0(LUT_PAD1) | INSTR0(LUT_CMD)); + qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* Page Program */ lut_base = SEQID_PP * 4; #ifdef CONFIG_SPI_FLASH_BAR - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_PP) | + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_PP) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); #else if (FSL_QSPI_FLASH_SIZE <= SZ_16M) - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_PP) | - PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | - PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); + qspi_write32(priv->flags, ®s->lut[lut_base], + OPRND0(QSPI_CMD_PP) | PAD0(LUT_PAD1) | + INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | + PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); else - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_PP_4B) | - PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | - PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); + qspi_write32(priv->flags, ®s->lut[lut_base], + OPRND0(QSPI_CMD_PP_4B) | PAD0(LUT_PAD1) | + INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | + PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); #endif #ifdef CONFIG_MX6SX /* * To MX6SX, OPRND0(TX_BUFFER_SIZE) can not work correctly. * So, Use IDATSZ in IPCR to determine the size and here set 0. */ - qspi_write32(®s->lut[lut_base + 1], OPRND0(0) | + qspi_write32(priv->flags, ®s->lut[lut_base + 1], OPRND0(0) | PAD0(LUT_PAD1) | INSTR0(LUT_WRITE)); #else - qspi_write32(®s->lut[lut_base + 1], OPRND0(TX_BUFFER_SIZE) | - PAD0(LUT_PAD1) | INSTR0(LUT_WRITE)); + qspi_write32(priv->flags, ®s->lut[lut_base + 1], + OPRND0(TX_BUFFER_SIZE) | + PAD0(LUT_PAD1) | INSTR0(LUT_WRITE)); #endif - qspi_write32(®s->lut[lut_base + 2], 0); - qspi_write32(®s->lut[lut_base + 3], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* READ ID */ lut_base = SEQID_RDID * 4; - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_RDID) | + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_RDID) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(8) | PAD1(LUT_PAD1) | INSTR1(LUT_READ)); - qspi_write32(®s->lut[lut_base + 1], 0); - qspi_write32(®s->lut[lut_base + 2], 0); - qspi_write32(®s->lut[lut_base + 3], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); /* SUB SECTOR 4K ERASE */ lut_base = SEQID_BE_4K * 4; - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_BE_4K) | + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_BE_4K) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) | PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); @@ -239,28 +297,28 @@ static void qspi_set_lut(struct fsl_qspi *qspi) * initialization. */ lut_base = SEQID_BRRD * 4; - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_BRRD) | + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_BRRD) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) | PAD1(LUT_PAD1) | INSTR1(LUT_READ)); lut_base = SEQID_BRWR * 4; - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_BRWR) | + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_BRWR) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) | PAD1(LUT_PAD1) | INSTR1(LUT_WRITE)); lut_base = SEQID_RDEAR * 4; - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_RDEAR) | + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_RDEAR) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) | PAD1(LUT_PAD1) | INSTR1(LUT_READ)); lut_base = SEQID_WREAR * 4; - qspi_write32(®s->lut[lut_base], OPRND0(QSPI_CMD_WREAR) | + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_WREAR) | PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) | PAD1(LUT_PAD1) | INSTR1(LUT_WRITE)); #endif /* Lock the LUT */ - qspi_write32(®s->lutkey, LUT_KEY_VALUE); - qspi_write32(®s->lckcr, QSPI_LCKCR_LOCK); + qspi_write32(priv->flags, ®s->lutkey, LUT_KEY_VALUE); + qspi_write32(priv->flags, ®s->lckcr, QSPI_LCKCR_LOCK); } #if defined(CONFIG_SYS_FSL_QSPI_AHB) @@ -270,14 +328,14 @@ static void qspi_set_lut(struct fsl_qspi *qspi) * the wrong data. The spec tells us reset the AHB domain and Serial Flash * domain at the same time. */ -static inline void qspi_ahb_invalid(struct fsl_qspi *q) +static inline void qspi_ahb_invalid(struct fsl_qspi_priv *priv) { - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)q->reg_base; + struct fsl_qspi_regs *regs = priv->regs; u32 reg; - reg = qspi_read32(®s->mcr); + reg = qspi_read32(priv->flags, ®s->mcr); reg |= QSPI_MCR_SWRSTHD_MASK | QSPI_MCR_SWRSTSD_MASK; - qspi_write32(®s->mcr, reg); + qspi_write32(priv->flags, ®s->mcr, reg); /* * The minimum delay : 1 AHB + 2 SFCK clocks. @@ -286,46 +344,48 @@ static inline void qspi_ahb_invalid(struct fsl_qspi *q) udelay(1); reg &= ~(QSPI_MCR_SWRSTHD_MASK | QSPI_MCR_SWRSTSD_MASK); - qspi_write32(®s->mcr, reg); + qspi_write32(priv->flags, ®s->mcr, reg); } /* Read out the data from the AHB buffer. */ -static inline void qspi_ahb_read(struct fsl_qspi *q, u8 *rxbuf, int len) +static inline void qspi_ahb_read(struct fsl_qspi_priv *priv, u8 *rxbuf, int len) { - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)q->reg_base; + struct fsl_qspi_regs *regs = priv->regs; u32 mcr_reg; - mcr_reg = qspi_read32(®s->mcr); + mcr_reg = qspi_read32(priv->flags, ®s->mcr); - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | + qspi_write32(priv->flags, ®s->mcr, + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); /* Read out the data directly from the AHB buffer. */ - memcpy(rxbuf, (u8 *)(q->amba_base + q->sf_addr), len); + memcpy(rxbuf, (u8 *)(priv->cur_amba_base + priv->sf_addr), len); - qspi_write32(®s->mcr, mcr_reg); + qspi_write32(priv->flags, ®s->mcr, mcr_reg); } -static void qspi_enable_ddr_mode(struct fsl_qspi_regs *regs) +static void qspi_enable_ddr_mode(struct fsl_qspi_priv *priv) { u32 reg, reg2; + struct fsl_qspi_regs *regs = priv->regs; - reg = qspi_read32(®s->mcr); + reg = qspi_read32(priv->flags, ®s->mcr); /* Disable the module */ - qspi_write32(®s->mcr, reg | QSPI_MCR_MDIS_MASK); + qspi_write32(priv->flags, ®s->mcr, reg | QSPI_MCR_MDIS_MASK); /* Set the Sampling Register for DDR */ - reg2 = qspi_read32(®s->smpr); + reg2 = qspi_read32(priv->flags, ®s->smpr); reg2 &= ~QSPI_SMPR_DDRSMP_MASK; reg2 |= (2 << QSPI_SMPR_DDRSMP_SHIFT); - qspi_write32(®s->smpr, reg2); + qspi_write32(priv->flags, ®s->smpr, reg2); /* Enable the module again (enable the DDR too) */ reg |= QSPI_MCR_DDR_EN_MASK; /* Enable bit 29 for imx6sx */ reg |= (1 << 29); - qspi_write32(®s->mcr, reg); + qspi_write32(priv->flags, ®s->mcr, reg); } /* @@ -341,180 +401,103 @@ static void qspi_enable_ddr_mode(struct fsl_qspi_regs *regs) * causes the controller to clear the buffer, and use the sequence pointed * by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash. */ -static void qspi_init_ahb_read(struct fsl_qspi_regs *regs) +static void qspi_init_ahb_read(struct fsl_qspi_priv *priv) { + struct fsl_qspi_regs *regs = priv->regs; + /* AHB configuration for access buffer 0/1/2 .*/ - qspi_write32(®s->buf0cr, QSPI_BUFXCR_INVALID_MSTRID); - qspi_write32(®s->buf1cr, QSPI_BUFXCR_INVALID_MSTRID); - qspi_write32(®s->buf2cr, QSPI_BUFXCR_INVALID_MSTRID); - qspi_write32(®s->buf3cr, QSPI_BUF3CR_ALLMST_MASK | + qspi_write32(priv->flags, ®s->buf0cr, QSPI_BUFXCR_INVALID_MSTRID); + qspi_write32(priv->flags, ®s->buf1cr, QSPI_BUFXCR_INVALID_MSTRID); + qspi_write32(priv->flags, ®s->buf2cr, QSPI_BUFXCR_INVALID_MSTRID); + qspi_write32(priv->flags, ®s->buf3cr, QSPI_BUF3CR_ALLMST_MASK | (0x80 << QSPI_BUF3CR_ADATSZ_SHIFT)); /* We only use the buffer3 */ - qspi_write32(®s->buf0ind, 0); - qspi_write32(®s->buf1ind, 0); - qspi_write32(®s->buf2ind, 0); + qspi_write32(priv->flags, ®s->buf0ind, 0); + qspi_write32(priv->flags, ®s->buf1ind, 0); + qspi_write32(priv->flags, ®s->buf2ind, 0); /* * Set the default lut sequence for AHB Read. * Parallel mode is disabled. */ - qspi_write32(®s->bfgencr, + qspi_write32(priv->flags, ®s->bfgencr, SEQID_FAST_READ << QSPI_BFGENCR_SEQID_SHIFT); /*Enable DDR Mode*/ - qspi_enable_ddr_mode(regs); + qspi_enable_ddr_mode(priv); } #endif -void spi_init() -{ - /* do nothing */ -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct fsl_qspi *qspi; - struct fsl_qspi_regs *regs; - u32 smpr_val; - u32 total_size; - - if (bus >= ARRAY_SIZE(spi_bases)) - return NULL; - - if (cs >= FSL_QSPI_FLASH_NUM) - return NULL; - - qspi = spi_alloc_slave(struct fsl_qspi, bus, cs); - if (!qspi) - return NULL; - - qspi->reg_base = spi_bases[bus]; - /* - * According cs, use different amba_base to choose the - * corresponding flash devices. - * - * If not, only one flash device is used even if passing - * different cs using `sf probe` - */ - qspi->amba_base = amba_bases[bus] + cs * FSL_QSPI_FLASH_SIZE; - - qspi->slave.max_write_size = TX_BUFFER_SIZE; - - regs = (struct fsl_qspi_regs *)qspi->reg_base; - qspi_write32(®s->mcr, QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK); - - smpr_val = qspi_read32(®s->smpr); - qspi_write32(®s->smpr, smpr_val & ~(QSPI_SMPR_FSDLY_MASK | - QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK)); - qspi_write32(®s->mcr, QSPI_MCR_RESERVED_MASK); - - total_size = FSL_QSPI_FLASH_SIZE * FSL_QSPI_FLASH_NUM; - /* - * Any read access to non-implemented addresses will provide - * undefined results. - * - * In case single die flash devices, TOP_ADDR_MEMA2 and - * TOP_ADDR_MEMB2 should be initialized/programmed to - * TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect, - * setting the size of these devices to 0. This would ensure - * that the complete memory map is assigned to only one flash device. - */ - qspi_write32(®s->sfa1ad, FSL_QSPI_FLASH_SIZE | amba_bases[bus]); - qspi_write32(®s->sfa2ad, FSL_QSPI_FLASH_SIZE | amba_bases[bus]); - qspi_write32(®s->sfb1ad, total_size | amba_bases[bus]); - qspi_write32(®s->sfb2ad, total_size | amba_bases[bus]); - - qspi_set_lut(qspi); - - smpr_val = qspi_read32(®s->smpr); - smpr_val &= ~QSPI_SMPR_DDRSMP_MASK; - qspi_write32(®s->smpr, smpr_val); - qspi_write32(®s->mcr, QSPI_MCR_RESERVED_MASK); - -#ifdef CONFIG_SYS_FSL_QSPI_AHB - qspi_init_ahb_read(regs); -#endif - return &qspi->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct fsl_qspi *qspi = to_qspi_spi(slave); - - free(qspi); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - return 0; -} - #ifdef CONFIG_SPI_FLASH_BAR /* Bank register read/write, EAR register read/write */ -static void qspi_op_rdbank(struct fsl_qspi *qspi, u8 *rxbuf, u32 len) +static void qspi_op_rdbank(struct fsl_qspi_priv *priv, u8 *rxbuf, u32 len) { - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; + struct fsl_qspi_regs *regs = priv->regs; u32 reg, mcr_reg, data, seqid; - mcr_reg = qspi_read32(®s->mcr); - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | + mcr_reg = qspi_read32(priv->flags, ®s->mcr); + qspi_write32(priv->flags, ®s->mcr, + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); - qspi_write32(®s->rbct, QSPI_RBCT_RXBRD_USEIPS); + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); - qspi_write32(®s->sfar, qspi->amba_base); + qspi_write32(priv->flags, ®s->sfar, priv->cur_amba_base); - if (qspi->cur_seqid == QSPI_CMD_BRRD) + if (priv->cur_seqid == QSPI_CMD_BRRD) seqid = SEQID_BRRD; else seqid = SEQID_RDEAR; - qspi_write32(®s->ipcr, (seqid << QSPI_IPCR_SEQID_SHIFT) | len); + qspi_write32(priv->flags, ®s->ipcr, + (seqid << QSPI_IPCR_SEQID_SHIFT) | len); /* Wait previous command complete */ - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) ; while (1) { - reg = qspi_read32(®s->rbsr); + reg = qspi_read32(priv->flags, ®s->rbsr); if (reg & QSPI_RBSR_RDBFL_MASK) { - data = qspi_read32(®s->rbdr[0]); + data = qspi_read32(priv->flags, ®s->rbdr[0]); data = qspi_endian_xchg(data); memcpy(rxbuf, &data, len); - qspi_write32(®s->mcr, qspi_read32(®s->mcr) | + qspi_write32(priv->flags, ®s->mcr, + qspi_read32(priv->flags, ®s->mcr) | QSPI_MCR_CLR_RXF_MASK); break; } } - qspi_write32(®s->mcr, mcr_reg); + qspi_write32(priv->flags, ®s->mcr, mcr_reg); } #endif -static void qspi_op_rdid(struct fsl_qspi *qspi, u32 *rxbuf, u32 len) +static void qspi_op_rdid(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len) { - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; + struct fsl_qspi_regs *regs = priv->regs; u32 mcr_reg, rbsr_reg, data; int i, size; - mcr_reg = qspi_read32(®s->mcr); - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | - QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); - qspi_write32(®s->rbct, QSPI_RBCT_RXBRD_USEIPS); + mcr_reg = qspi_read32(priv->flags, ®s->mcr); + qspi_write32(priv->flags, ®s->mcr, + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | + QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); - qspi_write32(®s->sfar, qspi->amba_base); + qspi_write32(priv->flags, ®s->sfar, priv->cur_amba_base); - qspi_write32(®s->ipcr, (SEQID_RDID << QSPI_IPCR_SEQID_SHIFT) | 0); - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) + qspi_write32(priv->flags, ®s->ipcr, + (SEQID_RDID << QSPI_IPCR_SEQID_SHIFT) | 0); + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) ; i = 0; size = len; while ((RX_BUFFER_SIZE >= size) && (size > 0)) { - rbsr_reg = qspi_read32(®s->rbsr); + rbsr_reg = qspi_read32(priv->flags, ®s->rbsr); if (rbsr_reg & QSPI_RBSR_RDBFL_MASK) { - data = qspi_read32(®s->rbdr[i]); + data = qspi_read32(priv->flags, ®s->rbdr[i]); data = qspi_endian_xchg(data); memcpy(rxbuf, &data, 4); rxbuf++; @@ -523,34 +506,36 @@ static void qspi_op_rdid(struct fsl_qspi *qspi, u32 *rxbuf, u32 len) } } - qspi_write32(®s->mcr, mcr_reg); + qspi_write32(priv->flags, ®s->mcr, mcr_reg); } #ifndef CONFIG_SYS_FSL_QSPI_AHB /* If not use AHB read, read data from ip interface */ -static void qspi_op_read(struct fsl_qspi *qspi, u32 *rxbuf, u32 len) +static void qspi_op_read(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len) { - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; + struct fsl_qspi_regs *regs = priv->regs; u32 mcr_reg, data; int i, size; u32 to_or_from; - mcr_reg = qspi_read32(®s->mcr); - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | - QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); - qspi_write32(®s->rbct, QSPI_RBCT_RXBRD_USEIPS); + mcr_reg = qspi_read32(priv->flags, ®s->mcr); + qspi_write32(priv->flags, ®s->mcr, + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | + QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); - to_or_from = qspi->sf_addr + qspi->amba_base; + to_or_from = priv->sf_addr + priv->cur_amba_base; while (len > 0) { - qspi_write32(®s->sfar, to_or_from); + qspi_write32(priv->flags, ®s->sfar, to_or_from); size = (len > RX_BUFFER_SIZE) ? RX_BUFFER_SIZE : len; - qspi_write32(®s->ipcr, - (SEQID_FAST_READ << QSPI_IPCR_SEQID_SHIFT) | size); - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) + qspi_write32(priv->flags, ®s->ipcr, + (SEQID_FAST_READ << QSPI_IPCR_SEQID_SHIFT) | + size); + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) ; to_or_from += size; @@ -558,66 +543,69 @@ static void qspi_op_read(struct fsl_qspi *qspi, u32 *rxbuf, u32 len) i = 0; while ((RX_BUFFER_SIZE >= size) && (size > 0)) { - data = qspi_read32(®s->rbdr[i]); + data = qspi_read32(priv->flags, ®s->rbdr[i]); data = qspi_endian_xchg(data); memcpy(rxbuf, &data, 4); rxbuf++; size -= 4; i++; } - qspi_write32(®s->mcr, qspi_read32(®s->mcr) | - QSPI_MCR_CLR_RXF_MASK); + qspi_write32(priv->flags, ®s->mcr, + qspi_read32(priv->flags, ®s->mcr) | + QSPI_MCR_CLR_RXF_MASK); } - qspi_write32(®s->mcr, mcr_reg); + qspi_write32(priv->flags, ®s->mcr, mcr_reg); } #endif -static void qspi_op_write(struct fsl_qspi *qspi, u8 *txbuf, u32 len) +static void qspi_op_write(struct fsl_qspi_priv *priv, u8 *txbuf, u32 len) { - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; + struct fsl_qspi_regs *regs = priv->regs; u32 mcr_reg, data, reg, status_reg, seqid; int i, size, tx_size; u32 to_or_from = 0; - mcr_reg = qspi_read32(®s->mcr); - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | - QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); - qspi_write32(®s->rbct, QSPI_RBCT_RXBRD_USEIPS); + mcr_reg = qspi_read32(priv->flags, ®s->mcr); + qspi_write32(priv->flags, ®s->mcr, + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | + QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); status_reg = 0; while ((status_reg & FLASH_STATUS_WEL) != FLASH_STATUS_WEL) { - qspi_write32(®s->ipcr, - (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0); - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) + qspi_write32(priv->flags, ®s->ipcr, + (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0); + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) ; - qspi_write32(®s->ipcr, - (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 1); - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) + qspi_write32(priv->flags, ®s->ipcr, + (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 1); + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) ; - reg = qspi_read32(®s->rbsr); + reg = qspi_read32(priv->flags, ®s->rbsr); if (reg & QSPI_RBSR_RDBFL_MASK) { - status_reg = qspi_read32(®s->rbdr[0]); + status_reg = qspi_read32(priv->flags, ®s->rbdr[0]); status_reg = qspi_endian_xchg(status_reg); } - qspi_write32(®s->mcr, - qspi_read32(®s->mcr) | QSPI_MCR_CLR_RXF_MASK); + qspi_write32(priv->flags, ®s->mcr, + qspi_read32(priv->flags, ®s->mcr) | + QSPI_MCR_CLR_RXF_MASK); } /* Default is page programming */ seqid = SEQID_PP; #ifdef CONFIG_SPI_FLASH_BAR - if (qspi->cur_seqid == QSPI_CMD_BRWR) + if (priv->cur_seqid == QSPI_CMD_BRWR) seqid = SEQID_BRWR; - else if (qspi->cur_seqid == QSPI_CMD_WREAR) + else if (priv->cur_seqid == QSPI_CMD_WREAR) seqid = SEQID_WREAR; #endif - to_or_from = qspi->sf_addr + qspi->amba_base; + to_or_from = priv->sf_addr + priv->cur_amba_base; - qspi_write32(®s->sfar, to_or_from); + qspi_write32(priv->flags, ®s->sfar, to_or_from); tx_size = (len > TX_BUFFER_SIZE) ? TX_BUFFER_SIZE : len; @@ -626,7 +614,7 @@ static void qspi_op_write(struct fsl_qspi *qspi, u8 *txbuf, u32 len) for (i = 0; i < size; i++) { memcpy(&data, txbuf, 4); data = qspi_endian_xchg(data); - qspi_write32(®s->tbdr, data); + qspi_write32(priv->flags, ®s->tbdr, data); txbuf += 4; } @@ -635,146 +623,273 @@ static void qspi_op_write(struct fsl_qspi *qspi, u8 *txbuf, u32 len) data = 0; memcpy(&data, txbuf, size); data = qspi_endian_xchg(data); - qspi_write32(®s->tbdr, data); + qspi_write32(priv->flags, ®s->tbdr, data); } - qspi_write32(®s->ipcr, (seqid << QSPI_IPCR_SEQID_SHIFT) | tx_size); - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) + qspi_write32(priv->flags, ®s->ipcr, + (seqid << QSPI_IPCR_SEQID_SHIFT) | tx_size); + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) ; - qspi_write32(®s->mcr, mcr_reg); + qspi_write32(priv->flags, ®s->mcr, mcr_reg); } -static void qspi_op_rdsr(struct fsl_qspi *qspi, u32 *rxbuf) +static void qspi_op_rdsr(struct fsl_qspi_priv *priv, u32 *rxbuf) { - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; + struct fsl_qspi_regs *regs = priv->regs; u32 mcr_reg, reg, data; - mcr_reg = qspi_read32(®s->mcr); - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | - QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); - qspi_write32(®s->rbct, QSPI_RBCT_RXBRD_USEIPS); + mcr_reg = qspi_read32(priv->flags, ®s->mcr); + qspi_write32(priv->flags, ®s->mcr, + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | + QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); - qspi_write32(®s->sfar, qspi->amba_base); + qspi_write32(priv->flags, ®s->sfar, priv->cur_amba_base); - qspi_write32(®s->ipcr, - (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 0); - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) + qspi_write32(priv->flags, ®s->ipcr, + (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 0); + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) ; while (1) { - reg = qspi_read32(®s->rbsr); + reg = qspi_read32(priv->flags, ®s->rbsr); if (reg & QSPI_RBSR_RDBFL_MASK) { - data = qspi_read32(®s->rbdr[0]); + data = qspi_read32(priv->flags, ®s->rbdr[0]); data = qspi_endian_xchg(data); memcpy(rxbuf, &data, 4); - qspi_write32(®s->mcr, qspi_read32(®s->mcr) | - QSPI_MCR_CLR_RXF_MASK); + qspi_write32(priv->flags, ®s->mcr, + qspi_read32(priv->flags, ®s->mcr) | + QSPI_MCR_CLR_RXF_MASK); break; } } - qspi_write32(®s->mcr, mcr_reg); + qspi_write32(priv->flags, ®s->mcr, mcr_reg); } -static void qspi_op_erase(struct fsl_qspi *qspi) +static void qspi_op_erase(struct fsl_qspi_priv *priv) { - struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base; + struct fsl_qspi_regs *regs = priv->regs; u32 mcr_reg; u32 to_or_from = 0; - mcr_reg = qspi_read32(®s->mcr); - qspi_write32(®s->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | - QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); - qspi_write32(®s->rbct, QSPI_RBCT_RXBRD_USEIPS); + mcr_reg = qspi_read32(priv->flags, ®s->mcr); + qspi_write32(priv->flags, ®s->mcr, + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | + QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE); + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); - to_or_from = qspi->sf_addr + qspi->amba_base; - qspi_write32(®s->sfar, to_or_from); + to_or_from = priv->sf_addr + priv->cur_amba_base; + qspi_write32(priv->flags, ®s->sfar, to_or_from); - qspi_write32(®s->ipcr, - (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0); - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) + qspi_write32(priv->flags, ®s->ipcr, + (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0); + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) ; - if (qspi->cur_seqid == QSPI_CMD_SE) { - qspi_write32(®s->ipcr, + if (priv->cur_seqid == QSPI_CMD_SE) { + qspi_write32(priv->flags, ®s->ipcr, (SEQID_SE << QSPI_IPCR_SEQID_SHIFT) | 0); - } else if (qspi->cur_seqid == QSPI_CMD_BE_4K) { - qspi_write32(®s->ipcr, + } else if (priv->cur_seqid == QSPI_CMD_BE_4K) { + qspi_write32(priv->flags, ®s->ipcr, (SEQID_BE_4K << QSPI_IPCR_SEQID_SHIFT) | 0); } - while (qspi_read32(®s->sr) & QSPI_SR_BUSY_MASK) + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) ; - qspi_write32(®s->mcr, mcr_reg); + qspi_write32(priv->flags, ®s->mcr, mcr_reg); } -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, +int qspi_xfer(struct fsl_qspi_priv *priv, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { - struct fsl_qspi *qspi = to_qspi_spi(slave); u32 bytes = DIV_ROUND_UP(bitlen, 8); static u32 wr_sfaddr; u32 txbuf; if (dout) { if (flags & SPI_XFER_BEGIN) { - qspi->cur_seqid = *(u8 *)dout; + priv->cur_seqid = *(u8 *)dout; memcpy(&txbuf, dout, 4); } if (flags == SPI_XFER_END) { - qspi->sf_addr = wr_sfaddr; - qspi_op_write(qspi, (u8 *)dout, bytes); + priv->sf_addr = wr_sfaddr; + qspi_op_write(priv, (u8 *)dout, bytes); return 0; } - if (qspi->cur_seqid == QSPI_CMD_FAST_READ) { - qspi->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK; - } else if ((qspi->cur_seqid == QSPI_CMD_SE) || - (qspi->cur_seqid == QSPI_CMD_BE_4K)) { - qspi->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK; - qspi_op_erase(qspi); - } else if (qspi->cur_seqid == QSPI_CMD_PP) + if (priv->cur_seqid == QSPI_CMD_FAST_READ) { + priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK; + } else if ((priv->cur_seqid == QSPI_CMD_SE) || + (priv->cur_seqid == QSPI_CMD_BE_4K)) { + priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK; + qspi_op_erase(priv); + } else if (priv->cur_seqid == QSPI_CMD_PP) { wr_sfaddr = swab32(txbuf) & OFFSET_BITS_MASK; + } else if ((priv->cur_seqid == QSPI_CMD_BRWR) || + (priv->cur_seqid == QSPI_CMD_WREAR)) { #ifdef CONFIG_SPI_FLASH_BAR - else if ((qspi->cur_seqid == QSPI_CMD_BRWR) || - (qspi->cur_seqid == QSPI_CMD_WREAR)) { wr_sfaddr = 0; - } #endif + } } if (din) { - if (qspi->cur_seqid == QSPI_CMD_FAST_READ) { + if (priv->cur_seqid == QSPI_CMD_FAST_READ) { #ifdef CONFIG_SYS_FSL_QSPI_AHB - qspi_ahb_read(qspi, din, bytes); + qspi_ahb_read(priv, din, bytes); #else - qspi_op_read(qspi, din, bytes); + qspi_op_read(priv, din, bytes); #endif - } - else if (qspi->cur_seqid == QSPI_CMD_RDID) - qspi_op_rdid(qspi, din, bytes); - else if (qspi->cur_seqid == QSPI_CMD_RDSR) - qspi_op_rdsr(qspi, din); + } else if (priv->cur_seqid == QSPI_CMD_RDID) + qspi_op_rdid(priv, din, bytes); + else if (priv->cur_seqid == QSPI_CMD_RDSR) + qspi_op_rdsr(priv, din); #ifdef CONFIG_SPI_FLASH_BAR - else if ((qspi->cur_seqid == QSPI_CMD_BRRD) || - (qspi->cur_seqid == QSPI_CMD_RDEAR)) { - qspi->sf_addr = 0; - qspi_op_rdbank(qspi, din, bytes); + else if ((priv->cur_seqid == QSPI_CMD_BRRD) || + (priv->cur_seqid == QSPI_CMD_RDEAR)) { + priv->sf_addr = 0; + qspi_op_rdbank(priv, din, bytes); } #endif } #ifdef CONFIG_SYS_FSL_QSPI_AHB - if ((qspi->cur_seqid == QSPI_CMD_SE) || - (qspi->cur_seqid == QSPI_CMD_PP) || - (qspi->cur_seqid == QSPI_CMD_BE_4K) || - (qspi->cur_seqid == QSPI_CMD_WREAR) || - (qspi->cur_seqid == QSPI_CMD_BRWR)) - qspi_ahb_invalid(qspi); + if ((priv->cur_seqid == QSPI_CMD_SE) || + (priv->cur_seqid == QSPI_CMD_PP) || + (priv->cur_seqid == QSPI_CMD_BE_4K) || + (priv->cur_seqid == QSPI_CMD_WREAR) || + (priv->cur_seqid == QSPI_CMD_BRWR)) + qspi_ahb_invalid(priv); +#endif + + return 0; +} + +void qspi_module_disable(struct fsl_qspi_priv *priv, u8 disable) +{ + u32 mcr_val; + + mcr_val = qspi_read32(priv->flags, &priv->regs->mcr); + if (disable) + mcr_val |= QSPI_MCR_MDIS_MASK; + else + mcr_val &= ~QSPI_MCR_MDIS_MASK; + qspi_write32(priv->flags, &priv->regs->mcr, mcr_val); +} + +void qspi_cfg_smpr(struct fsl_qspi_priv *priv, u32 clear_bits, u32 set_bits) +{ + u32 smpr_val; + + smpr_val = qspi_read32(priv->flags, &priv->regs->smpr); + smpr_val &= ~clear_bits; + smpr_val |= set_bits; + qspi_write32(priv->flags, &priv->regs->smpr, smpr_val); +} +#ifndef CONFIG_DM_SPI +static unsigned long spi_bases[] = { + QSPI0_BASE_ADDR, +#ifdef CONFIG_MX6SX + QSPI1_BASE_ADDR, +#endif +}; + +static unsigned long amba_bases[] = { + QSPI0_AMBA_BASE, +#ifdef CONFIG_MX6SX + QSPI1_AMBA_BASE, +#endif +}; + +static inline struct fsl_qspi *to_qspi_spi(struct spi_slave *slave) +{ + return container_of(slave, struct fsl_qspi, slave); +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct fsl_qspi *qspi; + struct fsl_qspi_regs *regs; + u32 total_size; + + if (bus >= ARRAY_SIZE(spi_bases)) + return NULL; + + if (cs >= FSL_QSPI_FLASH_NUM) + return NULL; + + qspi = spi_alloc_slave(struct fsl_qspi, bus, cs); + if (!qspi) + return NULL; + +#ifdef CONFIG_SYS_FSL_QSPI_BE + qspi->priv.flags |= QSPI_FLAG_REGMAP_ENDIAN_BIG; +#endif + + regs = (struct fsl_qspi_regs *)spi_bases[bus]; + qspi->priv.regs = regs; + /* + * According cs, use different amba_base to choose the + * corresponding flash devices. + * + * If not, only one flash device is used even if passing + * different cs using `sf probe` + */ + qspi->priv.cur_amba_base = amba_bases[bus] + cs * FSL_QSPI_FLASH_SIZE; + + qspi->slave.max_write_size = TX_BUFFER_SIZE; + + qspi_write32(qspi->priv.flags, ®s->mcr, + QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK); + + qspi_cfg_smpr(&qspi->priv, + ~(QSPI_SMPR_FSDLY_MASK | QSPI_SMPR_DDRSMP_MASK | + QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK), 0); + + total_size = FSL_QSPI_FLASH_SIZE * FSL_QSPI_FLASH_NUM; + /* + * Any read access to non-implemented addresses will provide + * undefined results. + * + * In case single die flash devices, TOP_ADDR_MEMA2 and + * TOP_ADDR_MEMB2 should be initialized/programmed to + * TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect, + * setting the size of these devices to 0. This would ensure + * that the complete memory map is assigned to only one flash device. + */ + qspi_write32(qspi->priv.flags, ®s->sfa1ad, + FSL_QSPI_FLASH_SIZE | amba_bases[bus]); + qspi_write32(qspi->priv.flags, ®s->sfa2ad, + FSL_QSPI_FLASH_SIZE | amba_bases[bus]); + qspi_write32(qspi->priv.flags, ®s->sfb1ad, + total_size | amba_bases[bus]); + qspi_write32(qspi->priv.flags, ®s->sfb2ad, + total_size | amba_bases[bus]); + + qspi_set_lut(&qspi->priv); + +#ifdef CONFIG_SYS_FSL_QSPI_AHB + qspi_init_ahb_read(&qspi->priv); #endif + qspi_module_disable(&qspi->priv, 0); + + return &qspi->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct fsl_qspi *qspi = to_qspi_spi(slave); + + free(qspi); +} + +int spi_claim_bus(struct spi_slave *slave) +{ return 0; } @@ -782,3 +897,215 @@ void spi_release_bus(struct spi_slave *slave) { /* Nothing to do */ } + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct fsl_qspi *qspi = to_qspi_spi(slave); + + return qspi_xfer(&qspi->priv, bitlen, dout, din, flags); +} + +void spi_init(void) +{ + /* Nothing to do */ +} +#else +static int fsl_qspi_child_pre_probe(struct udevice *dev) +{ + struct spi_slave *slave = dev_get_parentdata(dev); + + slave->max_write_size = TX_BUFFER_SIZE; + + return 0; +} + +static int fsl_qspi_probe(struct udevice *bus) +{ + u32 total_size; + struct fsl_qspi_platdata *plat = dev_get_platdata(bus); + struct fsl_qspi_priv *priv = dev_get_priv(bus); + struct dm_spi_bus *dm_spi_bus; + + dm_spi_bus = bus->uclass_priv; + + dm_spi_bus->max_hz = plat->speed_hz; + + priv->regs = (struct fsl_qspi_regs *)plat->reg_base; + priv->flags = plat->flags; + + priv->speed_hz = plat->speed_hz; + priv->amba_base[0] = plat->amba_base; + priv->amba_total_size = plat->amba_total_size; + priv->flash_num = plat->flash_num; + priv->num_chipselect = plat->num_chipselect; + + qspi_write32(priv->flags, &priv->regs->mcr, + QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK); + + qspi_cfg_smpr(priv, ~(QSPI_SMPR_FSDLY_MASK | QSPI_SMPR_DDRSMP_MASK | + QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK), 0); + + total_size = FSL_QSPI_FLASH_SIZE * FSL_QSPI_FLASH_NUM; + /* + * Any read access to non-implemented addresses will provide + * undefined results. + * + * In case single die flash devices, TOP_ADDR_MEMA2 and + * TOP_ADDR_MEMB2 should be initialized/programmed to + * TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect, + * setting the size of these devices to 0. This would ensure + * that the complete memory map is assigned to only one flash device. + */ + qspi_write32(priv->flags, &priv->regs->sfa1ad, + FSL_QSPI_FLASH_SIZE | priv->amba_base[0]); + qspi_write32(priv->flags, &priv->regs->sfa2ad, + FSL_QSPI_FLASH_SIZE | priv->amba_base[0]); + qspi_write32(priv->flags, &priv->regs->sfb1ad, + total_size | priv->amba_base[0]); + qspi_write32(priv->flags, &priv->regs->sfb2ad, + total_size | priv->amba_base[0]); + + qspi_set_lut(priv); + +#ifdef CONFIG_SYS_FSL_QSPI_AHB + qspi_init_ahb_read(priv); +#endif + + qspi_module_disable(priv, 0); + + return 0; +} + +static int fsl_qspi_ofdata_to_platdata(struct udevice *bus) +{ + struct reg_data { + u32 addr; + u32 size; + } regs_data[2]; + struct fsl_qspi_platdata *plat = bus->platdata; + const void *blob = gd->fdt_blob; + int node = bus->of_offset; + int ret, flash_num = 0, subnode; + + if (fdtdec_get_bool(blob, node, "big-endian")) + plat->flags |= QSPI_FLAG_REGMAP_ENDIAN_BIG; + + ret = fdtdec_get_int_array(blob, node, "reg", (u32 *)regs_data, + sizeof(regs_data)/sizeof(u32)); + if (ret) { + debug("Error: can't get base addresses (ret = %d)!\n", ret); + return -ENOMEM; + } + + /* Count flash numbers */ + fdt_for_each_subnode(blob, subnode, node) + ++flash_num; + + if (flash_num == 0) { + debug("Error: Missing flashes!\n"); + return -ENODEV; + } + + plat->speed_hz = fdtdec_get_int(blob, node, "spi-max-frequency", + FSL_QSPI_DEFAULT_SCK_FREQ); + plat->num_chipselect = fdtdec_get_int(blob, node, "num-cs", + FSL_QSPI_MAX_CHIPSELECT_NUM); + + plat->reg_base = regs_data[0].addr; + plat->amba_base = regs_data[1].addr; + plat->amba_total_size = regs_data[1].size; + plat->flash_num = flash_num; + + debug("%s: regs=<0x%x> <0x%x, 0x%x>, max-frequency=%d, endianess=%s\n", + __func__, + plat->reg_base, + plat->amba_base, + plat->amba_total_size, + plat->speed_hz, + plat->flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ? "be" : "le" + ); + + return 0; +} + +static int fsl_qspi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct fsl_qspi_priv *priv; + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + return qspi_xfer(priv, bitlen, dout, din, flags); +} + +static int fsl_qspi_claim_bus(struct udevice *dev) +{ + struct fsl_qspi_priv *priv; + struct udevice *bus; + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); + + bus = dev->parent; + priv = dev_get_priv(bus); + + priv->cur_amba_base = + priv->amba_base[0] + FSL_QSPI_FLASH_SIZE * slave_plat->cs; + + qspi_module_disable(priv, 0); + + return 0; +} + +static int fsl_qspi_release_bus(struct udevice *dev) +{ + struct fsl_qspi_priv *priv; + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + qspi_module_disable(priv, 1); + + return 0; +} + +static int fsl_qspi_set_speed(struct udevice *bus, uint speed) +{ + /* Nothing to do */ + return 0; +} + +static int fsl_qspi_set_mode(struct udevice *bus, uint mode) +{ + /* Nothing to do */ + return 0; +} + +static const struct dm_spi_ops fsl_qspi_ops = { + .claim_bus = fsl_qspi_claim_bus, + .release_bus = fsl_qspi_release_bus, + .xfer = fsl_qspi_xfer, + .set_speed = fsl_qspi_set_speed, + .set_mode = fsl_qspi_set_mode, +}; + +static const struct udevice_id fsl_qspi_ids[] = { + { .compatible = "fsl,vf610-qspi" }, + { .compatible = "fsl,imx6sx-qspi" }, + { } +}; + +U_BOOT_DRIVER(fsl_qspi) = { + .name = "fsl_qspi", + .id = UCLASS_SPI, + .of_match = fsl_qspi_ids, + .ops = &fsl_qspi_ops, + .ofdata_to_platdata = fsl_qspi_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct fsl_qspi_platdata), + .priv_auto_alloc_size = sizeof(struct fsl_qspi_priv), + .probe = fsl_qspi_probe, + .child_pre_probe = fsl_qspi_child_pre_probe, +}; +#endif diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index 194e882..50354fd 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -7,6 +7,7 @@ */ #include <common.h> +#include <dm.h> #include <errno.h> #include <malloc.h> #include <spi.h> @@ -19,154 +20,99 @@ #define SPI_OPCODE_WREN 0x06 #define SPI_OPCODE_FAST_READ 0x0b -struct ich_ctlr { +struct ich_spi_platdata { pci_dev_t dev; /* PCI device number */ int ich_version; /* Controller version, 7 or 9 */ bool use_sbase; /* Use SBASE instead of RCB */ +}; + +struct ich_spi_priv { int ichspi_lock; int locked; - uint8_t *opmenu; + int opmenu; int menubytes; void *base; /* Base of register set */ - uint16_t *preop; - uint16_t *optype; - uint32_t *addr; - uint8_t *data; + int preop; + int optype; + int addr; + int data; unsigned databytes; - uint8_t *status; - uint16_t *control; - uint32_t *bbar; + int status; + int control; + int bbar; uint32_t *pr; /* only for ich9 */ - uint8_t *speed; /* pointer to speed control */ + int speed; /* pointer to speed control */ ulong max_speed; /* Maximum bus speed in MHz */ + ulong cur_speed; /* Current bus speed */ + struct spi_trans trans; /* current transaction in progress */ }; -struct ich_ctlr ctlr; - -static inline struct ich_spi_slave *to_ich_spi(struct spi_slave *slave) -{ - return container_of(slave, struct ich_spi_slave, slave); -} - -static unsigned int ich_reg(const void *addr) -{ - return (unsigned)(addr - ctlr.base) & 0xffff; -} - -static u8 ich_readb(const void *addr) +static u8 ich_readb(struct ich_spi_priv *priv, int reg) { - u8 value = readb(addr); + u8 value = readb(priv->base + reg); - debug("read %2.2x from %4.4x\n", value, ich_reg(addr)); + debug("read %2.2x from %4.4x\n", value, reg); return value; } -static u16 ich_readw(const void *addr) +static u16 ich_readw(struct ich_spi_priv *priv, int reg) { - u16 value = readw(addr); + u16 value = readw(priv->base + reg); - debug("read %4.4x from %4.4x\n", value, ich_reg(addr)); + debug("read %4.4x from %4.4x\n", value, reg); return value; } -static u32 ich_readl(const void *addr) +static u32 ich_readl(struct ich_spi_priv *priv, int reg) { - u32 value = readl(addr); + u32 value = readl(priv->base + reg); - debug("read %8.8x from %4.4x\n", value, ich_reg(addr)); + debug("read %8.8x from %4.4x\n", value, reg); return value; } -static void ich_writeb(u8 value, void *addr) +static void ich_writeb(struct ich_spi_priv *priv, u8 value, int reg) { - writeb(value, addr); - debug("wrote %2.2x to %4.4x\n", value, ich_reg(addr)); + writeb(value, priv->base + reg); + debug("wrote %2.2x to %4.4x\n", value, reg); } -static void ich_writew(u16 value, void *addr) +static void ich_writew(struct ich_spi_priv *priv, u16 value, int reg) { - writew(value, addr); - debug("wrote %4.4x to %4.4x\n", value, ich_reg(addr)); + writew(value, priv->base + reg); + debug("wrote %4.4x to %4.4x\n", value, reg); } -static void ich_writel(u32 value, void *addr) +static void ich_writel(struct ich_spi_priv *priv, u32 value, int reg) { - writel(value, addr); - debug("wrote %8.8x to %4.4x\n", value, ich_reg(addr)); + writel(value, priv->base + reg); + debug("wrote %8.8x to %4.4x\n", value, reg); } -static void write_reg(const void *value, void *dest, uint32_t size) +static void write_reg(struct ich_spi_priv *priv, const void *value, + int dest_reg, uint32_t size) { - memcpy_toio(dest, value, size); + memcpy_toio(priv->base + dest_reg, value, size); } -static void read_reg(const void *src, void *value, uint32_t size) +static void read_reg(struct ich_spi_priv *priv, int src_reg, void *value, + uint32_t size) { - memcpy_fromio(value, src, size); + memcpy_fromio(value, priv->base + src_reg, size); } -static void ich_set_bbar(struct ich_ctlr *ctlr, uint32_t minaddr) +static void ich_set_bbar(struct ich_spi_priv *ctlr, uint32_t minaddr) { const uint32_t bbar_mask = 0x00ffff00; uint32_t ichspi_bbar; minaddr &= bbar_mask; - ichspi_bbar = ich_readl(ctlr->bbar) & ~bbar_mask; + ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask; ichspi_bbar |= minaddr; - ich_writel(ichspi_bbar, ctlr->bbar); -} - -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - puts("spi_cs_is_valid used but not implemented\n"); - return 0; -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct ich_spi_slave *ich; - - ich = spi_alloc_slave(struct ich_spi_slave, bus, cs); - if (!ich) { - puts("ICH SPI: Out of memory\n"); - return NULL; - } - - /* - * Yes this controller can only write a small number of bytes at - * once! The limit is typically 64 bytes. - */ - ich->slave.max_write_size = ctlr.databytes; - ich->speed = max_hz; - - /* - * ICH 7 SPI controller only supports array read command - * and byte program command for SST flash - */ - if (ctlr.ich_version == 7 || ctlr.use_sbase) { - ich->slave.op_mode_rx = SPI_OPM_RX_AS; - ich->slave.op_mode_tx = SPI_OPM_TX_BP; - } - - return &ich->slave; -} - -struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node, - int spi_node) -{ - /* We only support a single SPI at present */ - return spi_setup_slave(0, 0, 20000000, 0); -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct ich_spi_slave *ich = to_ich_spi(slave); - - free(ich); + ich_writel(ctlr, ichspi_bbar, ctlr->bbar); } /* @@ -185,7 +131,8 @@ static int get_ich_version(uint16_t device_id) device_id <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) || (device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN && device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX) || - device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC) + device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC || + device_id == PCI_DEVICE_ID_INTEL_LYNXPOINT_LPC) return 9; return 0; @@ -208,7 +155,7 @@ static int ich9_can_do_33mhz(pci_dev_t dev) return speed == 1; } -static int ich_find_spi_controller(struct ich_ctlr *ich) +static int ich_find_spi_controller(struct ich_spi_platdata *ich) { int last_bus = pci_last_busno(); int bus; @@ -241,131 +188,77 @@ static int ich_find_spi_controller(struct ich_ctlr *ich) return -ENODEV; } -static int ich_init_controller(struct ich_ctlr *ctlr) +static int ich_init_controller(struct ich_spi_platdata *plat, + struct ich_spi_priv *ctlr) { uint8_t *rcrb; /* Root Complex Register Block */ uint32_t rcba; /* Root Complex Base Address */ uint32_t sbase_addr; uint8_t *sbase; - pci_read_config_dword(ctlr->dev, 0xf0, &rcba); + pci_read_config_dword(plat->dev, 0xf0, &rcba); /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */ rcrb = (uint8_t *)(rcba & 0xffffc000); /* SBASE is similar */ - pci_read_config_dword(ctlr->dev, 0x54, &sbase_addr); + pci_read_config_dword(plat->dev, 0x54, &sbase_addr); sbase = (uint8_t *)(sbase_addr & 0xfffffe00); - if (ctlr->ich_version == 7) { + if (plat->ich_version == 7) { struct ich7_spi_regs *ich7_spi; ich7_spi = (struct ich7_spi_regs *)(rcrb + 0x3020); - ctlr->ichspi_lock = ich_readw(&ich7_spi->spis) & SPIS_LOCK; - ctlr->opmenu = ich7_spi->opmenu; + ctlr->ichspi_lock = readw(&ich7_spi->spis) & SPIS_LOCK; + ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu); ctlr->menubytes = sizeof(ich7_spi->opmenu); - ctlr->optype = &ich7_spi->optype; - ctlr->addr = &ich7_spi->spia; - ctlr->data = (uint8_t *)ich7_spi->spid; + ctlr->optype = offsetof(struct ich7_spi_regs, optype); + ctlr->addr = offsetof(struct ich7_spi_regs, spia); + ctlr->data = offsetof(struct ich7_spi_regs, spid); ctlr->databytes = sizeof(ich7_spi->spid); - ctlr->status = (uint8_t *)&ich7_spi->spis; - ctlr->control = &ich7_spi->spic; - ctlr->bbar = &ich7_spi->bbar; - ctlr->preop = &ich7_spi->preop; + ctlr->status = offsetof(struct ich7_spi_regs, spis); + ctlr->control = offsetof(struct ich7_spi_regs, spic); + ctlr->bbar = offsetof(struct ich7_spi_regs, bbar); + ctlr->preop = offsetof(struct ich7_spi_regs, preop); ctlr->base = ich7_spi; - } else if (ctlr->ich_version == 9) { + } else if (plat->ich_version == 9) { struct ich9_spi_regs *ich9_spi; - if (ctlr->use_sbase) + if (plat->use_sbase) ich9_spi = (struct ich9_spi_regs *)sbase; else ich9_spi = (struct ich9_spi_regs *)(rcrb + 0x3800); - ctlr->ichspi_lock = ich_readw(&ich9_spi->hsfs) & HSFS_FLOCKDN; - ctlr->opmenu = ich9_spi->opmenu; + ctlr->ichspi_lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN; + ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu); ctlr->menubytes = sizeof(ich9_spi->opmenu); - ctlr->optype = &ich9_spi->optype; - ctlr->addr = &ich9_spi->faddr; - ctlr->data = (uint8_t *)ich9_spi->fdata; + ctlr->optype = offsetof(struct ich9_spi_regs, optype); + ctlr->addr = offsetof(struct ich9_spi_regs, faddr); + ctlr->data = offsetof(struct ich9_spi_regs, fdata); ctlr->databytes = sizeof(ich9_spi->fdata); - ctlr->status = &ich9_spi->ssfs; - ctlr->control = (uint16_t *)ich9_spi->ssfc; - ctlr->speed = ich9_spi->ssfc + 2; - ctlr->bbar = &ich9_spi->bbar; - ctlr->preop = &ich9_spi->preop; + ctlr->status = offsetof(struct ich9_spi_regs, ssfs); + ctlr->control = offsetof(struct ich9_spi_regs, ssfc); + ctlr->speed = ctlr->control + 2; + ctlr->bbar = offsetof(struct ich9_spi_regs, bbar); + ctlr->preop = offsetof(struct ich9_spi_regs, preop); ctlr->pr = &ich9_spi->pr[0]; ctlr->base = ich9_spi; } else { - debug("ICH SPI: Unrecognized ICH version %d.\n", - ctlr->ich_version); - return -1; + debug("ICH SPI: Unrecognised ICH version %d\n", + plat->ich_version); + return -EINVAL; } /* Work out the maximum speed we can support */ ctlr->max_speed = 20000000; - if (ctlr->ich_version == 9 && ich9_can_do_33mhz(ctlr->dev)) + if (plat->ich_version == 9 && ich9_can_do_33mhz(plat->dev)) ctlr->max_speed = 33000000; debug("ICH SPI: Version %d detected at %p, speed %ld\n", - ctlr->ich_version, ctlr->base, ctlr->max_speed); + plat->ich_version, ctlr->base, ctlr->max_speed); ich_set_bbar(ctlr, 0); return 0; } -void spi_init(void) -{ - uint8_t bios_cntl; - - if (ich_find_spi_controller(&ctlr)) { - printf("ICH SPI: Cannot find device\n"); - return; - } - - if (ich_init_controller(&ctlr)) { - printf("ICH SPI: Cannot setup controller\n"); - return; - } - - /* - * Disable the BIOS write protect so write commands are allowed. On - * v9, deassert SMM BIOS Write Protect Disable. - */ - if (ctlr.use_sbase) { - struct ich9_spi_regs *ich9_spi; - - ich9_spi = (struct ich9_spi_regs *)ctlr.base; - bios_cntl = ich_readb(&ich9_spi->bcr); - bios_cntl &= ~(1 << 5); /* clear Enable InSMM_STS (EISS) */ - bios_cntl |= 1; /* Write Protect Disable (WPD) */ - ich_writeb(bios_cntl, &ich9_spi->bcr); - } else { - pci_read_config_byte(ctlr.dev, 0xdc, &bios_cntl); - if (ctlr.ich_version == 9) - bios_cntl &= ~(1 << 5); - pci_write_config_byte(ctlr.dev, 0xdc, bios_cntl | 0x1); - } -} - -int spi_claim_bus(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -void spi_cs_activate(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - static inline void spi_use_out(struct spi_trans *trans, unsigned bytes) { trans->out += bytes; @@ -411,19 +304,19 @@ static void spi_setup_type(struct spi_trans *trans, int data_bytes) } } -static int spi_setup_opcode(struct spi_trans *trans) +static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans) { uint16_t optypes; - uint8_t opmenu[ctlr.menubytes]; + uint8_t opmenu[ctlr->menubytes]; trans->opcode = trans->out[0]; spi_use_out(trans, 1); - if (!ctlr.ichspi_lock) { + if (!ctlr->ichspi_lock) { /* The lock is off, so just use index 0. */ - ich_writeb(trans->opcode, ctlr.opmenu); - optypes = ich_readw(ctlr.optype); + ich_writeb(ctlr, trans->opcode, ctlr->opmenu); + optypes = ich_readw(ctlr, ctlr->optype); optypes = (optypes & 0xfffc) | (trans->type & 0x3); - ich_writew(optypes, ctlr.optype); + ich_writew(ctlr, optypes, ctlr->optype); return 0; } else { /* The lock is on. See if what we need is on the menu. */ @@ -434,20 +327,20 @@ static int spi_setup_opcode(struct spi_trans *trans) if (trans->opcode == SPI_OPCODE_WREN) return 0; - read_reg(ctlr.opmenu, opmenu, sizeof(opmenu)); - for (opcode_index = 0; opcode_index < ctlr.menubytes; + read_reg(ctlr, ctlr->opmenu, opmenu, sizeof(opmenu)); + for (opcode_index = 0; opcode_index < ctlr->menubytes; opcode_index++) { if (opmenu[opcode_index] == trans->opcode) break; } - if (opcode_index == ctlr.menubytes) { + if (opcode_index == ctlr->menubytes) { printf("ICH SPI: Opcode %x not found\n", trans->opcode); - return -1; + return -EINVAL; } - optypes = ich_readw(ctlr.optype); + optypes = ich_readw(ctlr, ctlr->optype); optype = (optypes >> (opcode_index * 2)) & 0x3; if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && @@ -458,7 +351,7 @@ static int spi_setup_opcode(struct spi_trans *trans) if (optype != trans->type) { printf("ICH SPI: Transaction doesn't fit type %d\n", optype); - return -1; + return -ENOSPC; } return opcode_index; } @@ -480,7 +373,7 @@ static int spi_setup_offset(struct spi_trans *trans) return 1; default: printf("Unrecognized SPI transaction type %#x\n", trans->type); - return -1; + return -EPROTO; } } @@ -491,16 +384,19 @@ static int spi_setup_offset(struct spi_trans *trans) * * Return the last read status value on success or -1 on failure. */ -static int ich_status_poll(u16 bitmask, int wait_til_set) +static int ich_status_poll(struct ich_spi_priv *ctlr, u16 bitmask, + int wait_til_set) { int timeout = 600000; /* This will result in 6s */ u16 status = 0; while (timeout--) { - status = ich_readw(ctlr.status); + status = ich_readw(ctlr, ctlr->status); if (wait_til_set ^ ((status & bitmask) == 0)) { - if (wait_til_set) - ich_writew((status & bitmask), ctlr.status); + if (wait_til_set) { + ich_writew(ctlr, status & bitmask, + ctlr->status); + } return status; } udelay(10); @@ -508,30 +404,28 @@ static int ich_status_poll(u16 bitmask, int wait_til_set) printf("ICH SPI: SCIP timeout, read %x, expected %x\n", status, bitmask); - return -1; + return -ETIMEDOUT; } -/* -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bitsout, void *din, unsigned int bitsin) -*/ -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, - void *din, unsigned long flags) +static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) { - struct ich_spi_slave *ich = to_ich_spi(slave); + struct udevice *bus = dev_get_parent(dev); + struct ich_spi_priv *ctlr = dev_get_priv(bus); uint16_t control; int16_t opcode_index; int with_address; int status; int bytes = bitlen / 8; - struct spi_trans *trans = &ich->trans; + struct spi_trans *trans = &ctlr->trans; unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END); int using_cmd = 0; + int ret; /* Ee don't support writing partial bytes. */ if (bitlen % 8) { debug("ICH SPI: Accessing partial bytes not supported\n"); - return -1; + return -EPROTONOSUPPORT; } /* An empty end transaction can be ignored */ @@ -545,7 +439,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, if (dout && type == SPI_XFER_BEGIN) { if (bytes > ICH_MAX_CMD_LEN) { debug("ICH SPI: Command length limit exceeded\n"); - return -1; + return -ENOSPC; } memcpy(trans->cmd, dout, bytes); trans->cmd_len = bytes; @@ -576,21 +470,22 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, /* There has to always at least be an opcode. */ if (!trans->bytesout) { debug("ICH SPI: No opcode for transfer\n"); - return -1; + return -EPROTO; } - if (ich_status_poll(SPIS_SCIP, 0) == -1) - return -1; + ret = ich_status_poll(ctlr, SPIS_SCIP, 0); + if (ret < 0) + return ret; - ich_writew(SPIS_CDS | SPIS_FCERR, ctlr.status); + ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); spi_setup_type(trans, using_cmd ? bytes : 0); - opcode_index = spi_setup_opcode(trans); + opcode_index = spi_setup_opcode(ctlr, trans); if (opcode_index < 0) - return -1; + return -EINVAL; with_address = spi_setup_offset(trans); if (with_address < 0) - return -1; + return -EINVAL; if (trans->opcode == SPI_OPCODE_WREN) { /* @@ -598,20 +493,20 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, * in order to prevent the Management Engine from * issuing a transaction between WREN and DATA. */ - if (!ctlr.ichspi_lock) - ich_writew(trans->opcode, ctlr.preop); + if (!ctlr->ichspi_lock) + ich_writew(ctlr, trans->opcode, ctlr->preop); return 0; } - if (ctlr.speed && ctlr.max_speed >= 33000000) { + if (ctlr->speed && ctlr->max_speed >= 33000000) { int byte; - byte = ich_readb(ctlr.speed); - if (ich->speed >= 33000000) + byte = ich_readb(ctlr, ctlr->speed); + if (ctlr->cur_speed >= 33000000) byte |= SSFC_SCF_33MHZ; else byte &= ~SSFC_SCF_33MHZ; - ich_writeb(byte, ctlr.speed); + ich_writeb(ctlr, byte, ctlr->speed); } /* See if we have used up the command data */ @@ -622,35 +517,36 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, } /* Preset control fields */ - control = ich_readw(ctlr.control); + control = ich_readw(ctlr, ctlr->control); control &= ~SSFC_RESERVED; control = SPIC_SCGO | ((opcode_index & 0x07) << 4); /* Issue atomic preop cycle if needed */ - if (ich_readw(ctlr.preop)) + if (ich_readw(ctlr, ctlr->preop)) control |= SPIC_ACS; if (!trans->bytesout && !trans->bytesin) { /* SPI addresses are 24 bit only */ - if (with_address) - ich_writel(trans->offset & 0x00FFFFFF, ctlr.addr); - + if (with_address) { + ich_writel(ctlr, trans->offset & 0x00FFFFFF, + ctlr->addr); + } /* * This is a 'no data' command (like Write Enable), its * bitesout size was 1, decremented to zero while executing * spi_setup_opcode() above. Tell the chip to send the * command. */ - ich_writew(control, ctlr.control); + ich_writew(ctlr, control, ctlr->control); /* wait for the result */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; + status = ich_status_poll(ctlr, SPIS_CDS | SPIS_FCERR, 1); + if (status < 0) + return status; if (status & SPIS_FCERR) { debug("ICH SPI: Command transaction error\n"); - return -1; + return -EIO; } return 0; @@ -663,9 +559,9 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, * and followed by other SPI commands, and this sequence is controlled * by the SPI chip driver. */ - if (trans->bytesout > ctlr.databytes) { + if (trans->bytesout > ctlr->databytes) { debug("ICH SPI: Too much to write. This should be prevented by the driver's max_write_size?\n"); - return -1; + return -EPROTO; } /* @@ -676,41 +572,41 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, uint32_t data_length; /* SPI addresses are 24 bit only */ - ich_writel(trans->offset & 0x00FFFFFF, ctlr.addr); + ich_writel(ctlr, trans->offset & 0x00FFFFFF, ctlr->addr); if (trans->bytesout) - data_length = min(trans->bytesout, ctlr.databytes); + data_length = min(trans->bytesout, ctlr->databytes); else - data_length = min(trans->bytesin, ctlr.databytes); + data_length = min(trans->bytesin, ctlr->databytes); /* Program data into FDATA0 to N */ if (trans->bytesout) { - write_reg(trans->out, ctlr.data, data_length); + write_reg(ctlr, trans->out, ctlr->data, data_length); spi_use_out(trans, data_length); if (with_address) trans->offset += data_length; } /* Add proper control fields' values */ - control &= ~((ctlr.databytes - 1) << 8); + control &= ~((ctlr->databytes - 1) << 8); control |= SPIC_DS; control |= (data_length - 1) << 8; /* write it */ - ich_writew(control, ctlr.control); + ich_writew(ctlr, control, ctlr->control); /* Wait for Cycle Done Status or Flash Cycle Error. */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; + status = ich_status_poll(ctlr, SPIS_CDS | SPIS_FCERR, 1); + if (status < 0) + return status; if (status & SPIS_FCERR) { debug("ICH SPI: Data transaction error\n"); - return -1; + return -EIO; } if (trans->bytesin) { - read_reg(ctlr.data, trans->in, data_length); + read_reg(ctlr, ctlr->data, trans->in, data_length); spi_use_in(trans, data_length); if (with_address) trans->offset += data_length; @@ -718,7 +614,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, } /* Clear atomic preop now that xfer is done */ - ich_writew(0, ctlr.preop); + ich_writew(ctlr, 0, ctlr->preop); return 0; } @@ -730,15 +626,18 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, * don't actually take effect until the HSFS[FLOCKDN] bit is set, but that's * done elsewhere. */ -int spi_write_protect_region(uint32_t lower_limit, uint32_t length, int hint) +int spi_write_protect_region(struct udevice *dev, uint32_t lower_limit, + uint32_t length, int hint) { + struct udevice *bus = dev->parent; + struct ich_spi_priv *ctlr = dev_get_priv(bus); uint32_t tmplong; uint32_t upper_limit; - if (!ctlr.pr) { + if (!ctlr->pr) { printf("%s: operation not supported on this chipset\n", __func__); - return -1; + return -ENOSYS; } if (length == 0 || @@ -746,7 +645,7 @@ int spi_write_protect_region(uint32_t lower_limit, uint32_t length, int hint) hint < 0 || hint > 4) { printf("%s(0x%x, 0x%x, %d): invalid args\n", __func__, lower_limit, length, hint); - return -1; + return -EPERM; } upper_limit = lower_limit + length - 1; @@ -765,8 +664,121 @@ int spi_write_protect_region(uint32_t lower_limit, uint32_t length, int hint) ((lower_limit & 0x01fff000) >> 12); printf("%s: writing 0x%08x to %p\n", __func__, tmplong, - &ctlr.pr[hint]); - ctlr.pr[hint] = tmplong; + &ctlr->pr[hint]); + ctlr->pr[hint] = tmplong; + + return 0; +} + +static int ich_spi_probe(struct udevice *bus) +{ + struct ich_spi_platdata *plat = dev_get_platdata(bus); + struct ich_spi_priv *priv = dev_get_priv(bus); + uint8_t bios_cntl; + int ret; + + ret = ich_init_controller(plat, priv); + if (ret) + return ret; + /* + * Disable the BIOS write protect so write commands are allowed. On + * v9, deassert SMM BIOS Write Protect Disable. + */ + if (plat->use_sbase) { + struct ich9_spi_regs *ich9_spi; + + ich9_spi = priv->base; + bios_cntl = ich_readb(priv, ich9_spi->bcr); + bios_cntl &= ~(1 << 5); /* clear Enable InSMM_STS (EISS) */ + bios_cntl |= 1; /* Write Protect Disable (WPD) */ + ich_writeb(priv, bios_cntl, ich9_spi->bcr); + } else { + pci_read_config_byte(plat->dev, 0xdc, &bios_cntl); + if (plat->ich_version == 9) + bios_cntl &= ~(1 << 5); + pci_write_config_byte(plat->dev, 0xdc, bios_cntl | 0x1); + } + + priv->cur_speed = priv->max_speed; + + return 0; +} + +static int ich_spi_ofdata_to_platdata(struct udevice *bus) +{ + struct ich_spi_platdata *plat = dev_get_platdata(bus); + int ret; + + ret = ich_find_spi_controller(plat); + if (ret) + return ret; return 0; } + +static int ich_spi_set_speed(struct udevice *bus, uint speed) +{ + struct ich_spi_priv *priv = dev_get_priv(bus); + + priv->cur_speed = speed; + + return 0; +} + +static int ich_spi_set_mode(struct udevice *bus, uint mode) +{ + debug("%s: mode=%d\n", __func__, mode); + + return 0; +} + +static int ich_spi_child_pre_probe(struct udevice *dev) +{ + struct udevice *bus = dev_get_parent(dev); + struct ich_spi_platdata *plat = dev_get_platdata(bus); + struct ich_spi_priv *priv = dev_get_priv(bus); + struct spi_slave *slave = dev_get_parentdata(dev); + + /* + * Yes this controller can only write a small number of bytes at + * once! The limit is typically 64 bytes. + */ + slave->max_write_size = priv->databytes; + /* + * ICH 7 SPI controller only supports array read command + * and byte program command for SST flash + */ + if (plat->ich_version == 7) { + slave->op_mode_rx = SPI_OPM_RX_AS; + slave->op_mode_tx = SPI_OPM_TX_BP; + } + + return 0; +} + +static const struct dm_spi_ops ich_spi_ops = { + .xfer = ich_spi_xfer, + .set_speed = ich_spi_set_speed, + .set_mode = ich_spi_set_mode, + /* + * cs_info is not needed, since we require all chip selects to be + * in the device tree explicitly + */ +}; + +static const struct udevice_id ich_spi_ids[] = { + { .compatible = "intel,ich-spi" }, + { } +}; + +U_BOOT_DRIVER(ich_spi) = { + .name = "ich_spi", + .id = UCLASS_SPI, + .of_match = ich_spi_ids, + .ops = &ich_spi_ops, + .ofdata_to_platdata = ich_spi_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct ich_spi_platdata), + .priv_auto_alloc_size = sizeof(struct ich_spi_priv), + .child_pre_probe = ich_spi_child_pre_probe, + .probe = ich_spi_probe, +}; diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c index 651e46e..85f9e85 100644 --- a/drivers/spi/omap3_spi.c +++ b/drivers/spi/omap3_spi.c @@ -20,7 +20,7 @@ #include <asm/io.h> #include "omap3_spi.h" -#define SPI_WAIT_TIMEOUT 3000000 +#define SPI_WAIT_TIMEOUT 10 static void spi_reset(struct omap3_spi_slave *ds) { @@ -227,7 +227,7 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp, { struct omap3_spi_slave *ds = to_omap3_spi(slave); int i; - int timeout = SPI_WAIT_TIMEOUT; + ulong start; int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); /* Enable the channel */ @@ -241,9 +241,10 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp, for (i = 0; i < len; i++) { /* wait till TX register is empty (TXS == 1) */ + start = get_timer(0); while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & OMAP3_MCSPI_CHSTAT_TXS)) { - if (--timeout <= 0) { + if (get_timer(start) > SPI_WAIT_TIMEOUT) { printf("SPI TXS timed out, status=0x%08x\n", readl(&ds->regs->channel[ds->slave.cs].chstat)); return -1; @@ -280,7 +281,7 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp, { struct omap3_spi_slave *ds = to_omap3_spi(slave); int i; - int timeout = SPI_WAIT_TIMEOUT; + ulong start; int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); /* Enable the channel */ @@ -295,10 +296,11 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp, writel(0, &ds->regs->channel[ds->slave.cs].tx); for (i = 0; i < len; i++) { + start = get_timer(0); /* Wait till RX register contains data (RXS == 1) */ while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & OMAP3_MCSPI_CHSTAT_RXS)) { - if (--timeout <= 0) { + if (get_timer(start) > SPI_WAIT_TIMEOUT) { printf("SPI RXS timed out, status=0x%08x\n", readl(&ds->regs->channel[ds->slave.cs].chstat)); return -1; @@ -332,7 +334,7 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len, const void *txp, void *rxp, unsigned long flags) { struct omap3_spi_slave *ds = to_omap3_spi(slave); - int timeout = SPI_WAIT_TIMEOUT; + ulong start; int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); int irqstatus = readl(&ds->regs->irqstatus); int i=0; @@ -350,9 +352,10 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len, for (i=0; i < len; i++){ /* Write: wait for TX empty (TXS == 1)*/ irqstatus |= (1<< (4*(ds->slave.bus))); + start = get_timer(0); while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & OMAP3_MCSPI_CHSTAT_TXS)) { - if (--timeout <= 0) { + if (get_timer(start) > SPI_WAIT_TIMEOUT) { printf("SPI TXS timed out, status=0x%08x\n", readl(&ds->regs->channel[ds->slave.cs].chstat)); return -1; @@ -368,9 +371,10 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len, writel(((u8 *)txp)[i], tx); /*Read: wait for RX containing data (RXS == 1)*/ + start = get_timer(0); while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & OMAP3_MCSPI_CHSTAT_RXS)) { - if (--timeout <= 0) { + if (get_timer(start) > SPI_WAIT_TIMEOUT) { printf("SPI RXS timed out, status=0x%08x\n", readl(&ds->regs->channel[ds->slave.cs].chstat)); return -1; diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 63a6217..83fe8e0 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -50,7 +50,7 @@ int spi_claim_bus(struct spi_slave *slave) struct udevice *dev = slave->dev; struct udevice *bus = dev->parent; struct dm_spi_ops *ops = spi_get_ops(bus); - struct dm_spi_bus *spi = bus->uclass_priv; + struct dm_spi_bus *spi = dev_get_uclass_priv(bus); int speed; int ret; @@ -67,7 +67,7 @@ int spi_claim_bus(struct spi_slave *slave) if (ret) return ret; - return ops->claim_bus ? ops->claim_bus(bus) : 0; + return ops->claim_bus ? ops->claim_bus(dev) : 0; } void spi_release_bus(struct spi_slave *slave) @@ -77,7 +77,7 @@ void spi_release_bus(struct spi_slave *slave) struct dm_spi_ops *ops = spi_get_ops(bus); if (ops->release_bus) - ops->release_bus(bus); + ops->release_bus(dev); } int spi_xfer(struct spi_slave *slave, unsigned int bitlen, @@ -110,7 +110,7 @@ int spi_child_post_bind(struct udevice *dev) int spi_post_probe(struct udevice *bus) { - struct dm_spi_bus *spi = bus->uclass_priv; + struct dm_spi_bus *spi = dev_get_uclass_priv(bus); spi->max_hz = fdtdec_get_int(gd->fdt_blob, bus->of_offset, "spi-max-frequency", 0); diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c index 53ff9ea..4bec663 100644 --- a/drivers/spi/tegra114_spi.c +++ b/drivers/spi/tegra114_spi.c @@ -153,8 +153,9 @@ static int tegra114_spi_probe(struct udevice *bus) return 0; } -static int tegra114_spi_claim_bus(struct udevice *bus) +static int tegra114_spi_claim_bus(struct udevice *dev) { + struct udevice *bus = dev->parent; struct tegra114_spi_priv *priv = dev_get_priv(bus); struct spi_regs *regs = priv->regs; diff --git a/drivers/spi/tegra20_sflash.c b/drivers/spi/tegra20_sflash.c index 78c74cd..82c1b84 100644 --- a/drivers/spi/tegra20_sflash.c +++ b/drivers/spi/tegra20_sflash.c @@ -125,8 +125,9 @@ static int tegra20_sflash_probe(struct udevice *bus) return 0; } -static int tegra20_sflash_claim_bus(struct udevice *bus) +static int tegra20_sflash_claim_bus(struct udevice *dev) { + struct udevice *bus = dev->parent; struct tegra20_sflash_priv *priv = dev_get_priv(bus); struct spi_regs *regs = priv->regs; u32 reg; diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c index 597d6ad..f6fb89b 100644 --- a/drivers/spi/tegra20_slink.c +++ b/drivers/spi/tegra20_slink.c @@ -141,8 +141,9 @@ static int tegra30_spi_probe(struct udevice *bus) return 0; } -static int tegra30_spi_claim_bus(struct udevice *bus) +static int tegra30_spi_claim_bus(struct udevice *dev) { + struct udevice *bus = dev->parent; struct tegra30_spi_priv *priv = dev_get_priv(bus); struct spi_regs *regs = priv->regs; u32 reg; diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c index 5da8759..e9129da 100644 --- a/drivers/spi/zynq_spi.c +++ b/drivers/spi/zynq_spi.c @@ -227,9 +227,6 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, debug("spi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n", slave->bus, slave->cs, bitlen, len, flags); - if (bitlen == 0) - return -1; - if (bitlen % 8) { debug("spi_xfer: Non byte aligned SPI transfer\n"); return -1; diff --git a/drivers/tpm/Kconfig b/drivers/tpm/Kconfig index e69de29..f408b8a 100644 --- a/drivers/tpm/Kconfig +++ b/drivers/tpm/Kconfig @@ -0,0 +1,7 @@ +config TPM_TIS_SANDBOX + bool "Enable sandbox TPM driver" + help + This driver emulates a TPM, providing access to base functions + such as reading and writing TPM private data. This is enough to + support Chrome OS verified boot. Extend functionality is not + implemented. diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index b4a9442..637ef3d 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -35,8 +35,24 @@ config USB if USB +config DM_USB + bool "Enable driver model for USB" + depends on USB && DM + help + Enable driver model for USB. The USB interface is then implemented + by the USB uclass. Multiple USB controllers of different types + (XHCI, EHCI) can be attached and used. The 'usb' command works as + normal. OCHI is not supported at present. + + Much of the code is shared but with this option enabled the USB + uclass takes care of device enumeration. USB devices can be + declared with the USB_DEVICE() macro and will be automatically + probed when found on the bus. + source "drivers/usb/host/Kconfig" +source "drivers/usb/emul/Kconfig" + config USB_STORAGE bool "USB Mass Storage support" ---help--- diff --git a/drivers/usb/emul/Kconfig b/drivers/usb/emul/Kconfig new file mode 100644 index 0000000..ae1ab23 --- /dev/null +++ b/drivers/usb/emul/Kconfig @@ -0,0 +1,8 @@ +config USB_EMUL + bool "Support for USB device emulation" + depends on DM_USB && SANDBOX + help + Since sandbox does not have access to a real USB bus, it is possible + to use device emulators instead. This allows testing of the USB + stack on sandbox without needing a real device, or any host machine + USB resources. diff --git a/drivers/usb/emul/Makefile b/drivers/usb/emul/Makefile new file mode 100644 index 0000000..8fd83d5 --- /dev/null +++ b/drivers/usb/emul/Makefile @@ -0,0 +1,10 @@ +# +# (C) Copyright 2015 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_USB_EMUL) += sandbox_flash.o +obj-$(CONFIG_USB_EMUL) += sandbox_hub.o +obj-$(CONFIG_USB_EMUL) += usb-emul-uclass.o diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c new file mode 100644 index 0000000..6e0808d --- /dev/null +++ b/drivers/usb/emul/sandbox_flash.c @@ -0,0 +1,423 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <os.h> +#include <scsi.h> +#include <usb.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * This driver emulates a flash stick using the UFI command specification and + * the BBB (bulk/bulk/bulk) protocol. It supports only a single logical unit + * number (LUN 0). + */ + +enum { + SANDBOX_FLASH_EP_OUT = 1, /* endpoints */ + SANDBOX_FLASH_EP_IN = 2, + SANDBOX_FLASH_BLOCK_LEN = 512, +}; + +enum cmd_phase { + PHASE_START, + PHASE_DATA, + PHASE_STATUS, +}; + +/** + * struct sandbox_flash_priv - private state for this driver + * + * @error: true if there is an error condition + * @alloc_len: Allocation length from the last incoming command + * @transfer_len: Transfer length from CBW header + * @read_len: Number of blocks of data left in the current read command + * @tag: Tag value from last command + * @fd: File descriptor of backing file + * @file_size: Size of file in bytes + * @status_buff: Data buffer for outgoing status + * @buff_used: Number of bytes ready to transfer back to host + * @buff: Data buffer for outgoing data + */ +struct sandbox_flash_priv { + bool error; + int alloc_len; + int transfer_len; + int read_len; + enum cmd_phase phase; + u32 tag; + int fd; + loff_t file_size; + struct umass_bbb_csw status; + int buff_used; + u8 buff[512]; +}; + +struct sandbox_flash_plat { + const char *pathname; +}; + +struct scsi_inquiry_resp { + u8 type; + u8 flags; + u8 version; + u8 data_format; + u8 additional_len; + u8 spare[3]; + char vendor[8]; + char product[16]; + char revision[4]; +}; + +struct scsi_read_capacity_resp { + u32 last_block_addr; + u32 block_len; +}; + +struct __packed scsi_read10_req { + u8 cmd; + u8 lun_flags; + u32 lba; + u8 spare; + u16 transfer_len; + u8 spare2[3]; +}; + +enum { + STRINGID_MANUFACTURER = 1, + STRINGID_PRODUCT, + STRINGID_SERIAL, + + STRINGID_COUNT, +}; + +static struct usb_string flash_strings[] = { + {STRINGID_MANUFACTURER, "sandbox"}, + {STRINGID_PRODUCT, "flash"}, + {STRINGID_SERIAL, "2345"}, + {}, +}; + +static struct usb_device_descriptor flash_device_desc = { + .bLength = sizeof(flash_device_desc), + .bDescriptorType = USB_DT_DEVICE, + + .bcdUSB = __constant_cpu_to_le16(0x0200), + + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + + .idVendor = __constant_cpu_to_le16(0x1234), + .idProduct = __constant_cpu_to_le16(0x5678), + .iManufacturer = STRINGID_MANUFACTURER, + .iProduct = STRINGID_PRODUCT, + .iSerialNumber = STRINGID_SERIAL, + .bNumConfigurations = 1, +}; + +static struct usb_config_descriptor flash_config0 = { + .bLength = sizeof(flash_config0), + .bDescriptorType = USB_DT_CONFIG, + + /* wTotalLength is set up by usb-emul-uclass */ + .bNumInterfaces = 1, + .bConfigurationValue = 0, + .iConfiguration = 0, + .bmAttributes = 1 << 7, + .bMaxPower = 50, +}; + +static struct usb_interface_descriptor flash_interface0 = { + .bLength = sizeof(flash_interface0), + .bDescriptorType = USB_DT_INTERFACE, + + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_MASS_STORAGE, + .bInterfaceSubClass = US_SC_UFI, + .bInterfaceProtocol = US_PR_BULK, + .iInterface = 0, +}; + +static struct usb_endpoint_descriptor flash_endpoint0_out = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = SANDBOX_FLASH_EP_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = __constant_cpu_to_le16(1024), + .bInterval = 0, +}; + +static struct usb_endpoint_descriptor flash_endpoint1_in = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = SANDBOX_FLASH_EP_IN | USB_ENDPOINT_DIR_MASK, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = __constant_cpu_to_le16(1024), + .bInterval = 0, +}; + +static void *flash_desc_list[] = { + &flash_device_desc, + &flash_config0, + &flash_interface0, + &flash_endpoint0_out, + &flash_endpoint1_in, + NULL, +}; + +static int sandbox_flash_control(struct udevice *dev, struct usb_device *udev, + unsigned long pipe, void *buff, int len, + struct devrequest *setup) +{ + struct sandbox_flash_priv *priv = dev_get_priv(dev); + + if (pipe == usb_rcvctrlpipe(udev, 0)) { + switch (setup->request) { + case US_BBB_RESET: + priv->error = false; + return 0; + case US_BBB_GET_MAX_LUN: + *(char *)buff = '\0'; + return 1; + default: + debug("request=%x\n", setup->request); + break; + } + } + debug("pipe=%lx\n", pipe); + + return -EIO; +} + +static void setup_fail_response(struct sandbox_flash_priv *priv) +{ + struct umass_bbb_csw *csw = &priv->status; + + csw->dCSWSignature = CSWSIGNATURE; + csw->dCSWTag = priv->tag; + csw->dCSWDataResidue = 0; + csw->bCSWStatus = CSWSTATUS_FAILED; + priv->buff_used = 0; +} + +/** + * setup_response() - set up a response to send back to the host + * + * @priv: Sandbox flash private data + * @resp: Response to send, or NULL if none + * @size: Size of response + */ +static void setup_response(struct sandbox_flash_priv *priv, void *resp, + int size) +{ + struct umass_bbb_csw *csw = &priv->status; + + csw->dCSWSignature = CSWSIGNATURE; + csw->dCSWTag = priv->tag; + csw->dCSWDataResidue = 0; + csw->bCSWStatus = CSWSTATUS_GOOD; + + assert(!resp || resp == priv->buff); + priv->buff_used = size; +} + +static void handle_read(struct sandbox_flash_priv *priv, ulong lba, + ulong transfer_len) +{ + debug("%s: lba=%lx, transfer_len=%lx\n", __func__, lba, transfer_len); + if (priv->fd != -1) { + os_lseek(priv->fd, lba * SANDBOX_FLASH_BLOCK_LEN, OS_SEEK_SET); + priv->read_len = transfer_len; + setup_response(priv, priv->buff, + transfer_len * SANDBOX_FLASH_BLOCK_LEN); + } else { + setup_fail_response(priv); + } +} + +static int handle_ufi_command(struct sandbox_flash_priv *priv, const void *buff, + int len) +{ + const struct SCSI_cmd_block *req = buff; + + switch (*req->cmd) { + case SCSI_INQUIRY: { + struct scsi_inquiry_resp *resp = (void *)priv->buff; + + priv->alloc_len = req->cmd[4]; + memset(resp, '\0', sizeof(*resp)); + resp->data_format = 1; + resp->additional_len = 0x1f; + strncpy(resp->vendor, + flash_strings[STRINGID_MANUFACTURER - 1].s, + sizeof(resp->vendor)); + strncpy(resp->product, flash_strings[STRINGID_PRODUCT - 1].s, + sizeof(resp->product)); + strncpy(resp->revision, "1.0", sizeof(resp->revision)); + setup_response(priv, resp, sizeof(*resp)); + break; + } + case SCSI_TST_U_RDY: + setup_response(priv, NULL, 0); + break; + case SCSI_RD_CAPAC: { + struct scsi_read_capacity_resp *resp = (void *)priv->buff; + uint blocks; + + if (priv->file_size) + blocks = priv->file_size / SANDBOX_FLASH_BLOCK_LEN - 1; + else + blocks = 0; + resp->last_block_addr = cpu_to_be32(blocks); + resp->block_len = cpu_to_be32(SANDBOX_FLASH_BLOCK_LEN); + setup_response(priv, resp, sizeof(*resp)); + break; + } + case SCSI_READ10: { + struct scsi_read10_req *req = (void *)buff; + + handle_read(priv, be32_to_cpu(req->lba), + be16_to_cpu(req->transfer_len)); + break; + } + default: + debug("Command not supported: %x\n", req->cmd[0]); + return -EPROTONOSUPPORT; + } + + priv->phase = priv->transfer_len ? PHASE_DATA : PHASE_STATUS; + return 0; +} + +static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, + unsigned long pipe, void *buff, int len) +{ + struct sandbox_flash_priv *priv = dev_get_priv(dev); + int ep = usb_pipeendpoint(pipe); + struct umass_bbb_cbw *cbw = buff; + + debug("%s: dev=%s, pipe=%lx, ep=%x, len=%x, phase=%d\n", __func__, + dev->name, pipe, ep, len, priv->phase); + switch (ep) { + case SANDBOX_FLASH_EP_OUT: + switch (priv->phase) { + case PHASE_START: + priv->alloc_len = 0; + priv->read_len = 0; + if (priv->error || len != UMASS_BBB_CBW_SIZE || + cbw->dCBWSignature != CBWSIGNATURE) + goto err; + if ((cbw->bCBWFlags & CBWFLAGS_SBZ) || + cbw->bCBWLUN != 0) + goto err; + if (cbw->bCDBLength < 1 || cbw->bCDBLength >= 0x10) + goto err; + priv->transfer_len = cbw->dCBWDataTransferLength; + priv->tag = cbw->dCBWTag; + return handle_ufi_command(priv, cbw->CBWCDB, + cbw->bCDBLength); + case PHASE_DATA: + debug("data out\n"); + break; + default: + break; + } + case SANDBOX_FLASH_EP_IN: + switch (priv->phase) { + case PHASE_DATA: + debug("data in, len=%x, alloc_len=%x, priv->read_len=%x\n", + len, priv->alloc_len, priv->read_len); + if (priv->read_len) { + ulong bytes_read; + + bytes_read = os_read(priv->fd, buff, len); + if (bytes_read != len) + return -EIO; + priv->read_len -= len / SANDBOX_FLASH_BLOCK_LEN; + if (!priv->read_len) + priv->phase = PHASE_STATUS; + } else { + if (priv->alloc_len && len > priv->alloc_len) + len = priv->alloc_len; + memcpy(buff, priv->buff, len); + priv->phase = PHASE_STATUS; + } + return len; + case PHASE_STATUS: + debug("status in, len=%x\n", len); + if (len > sizeof(priv->status)) + len = sizeof(priv->status); + memcpy(buff, &priv->status, len); + priv->phase = PHASE_START; + return len; + default: + break; + } + } +err: + priv->error = true; + debug("%s: Detected transfer error\n", __func__); + return 0; +} + +static int sandbox_flash_ofdata_to_platdata(struct udevice *dev) +{ + struct sandbox_flash_plat *plat = dev_get_platdata(dev); + const void *blob = gd->fdt_blob; + + plat->pathname = fdt_getprop(blob, dev->of_offset, "sandbox,filepath", + NULL); + + return 0; +} + +static int sandbox_flash_bind(struct udevice *dev) +{ + return usb_emul_setup_device(dev, PACKET_SIZE_64, flash_strings, + flash_desc_list); +} + +static int sandbox_flash_probe(struct udevice *dev) +{ + struct sandbox_flash_plat *plat = dev_get_platdata(dev); + struct sandbox_flash_priv *priv = dev_get_priv(dev); + + priv->fd = os_open(plat->pathname, OS_O_RDONLY); + if (priv->fd != -1) + return os_get_filesize(plat->pathname, &priv->file_size); + + return 0; +} + +static const struct dm_usb_ops sandbox_usb_flash_ops = { + .control = sandbox_flash_control, + .bulk = sandbox_flash_bulk, +}; + +static const struct udevice_id sandbox_usb_flash_ids[] = { + { .compatible = "sandbox,usb-flash" }, + { } +}; + +U_BOOT_DRIVER(usb_sandbox_flash) = { + .name = "usb_sandbox_flash", + .id = UCLASS_USB_EMUL, + .of_match = sandbox_usb_flash_ids, + .bind = sandbox_flash_bind, + .probe = sandbox_flash_probe, + .ofdata_to_platdata = sandbox_flash_ofdata_to_platdata, + .ops = &sandbox_usb_flash_ops, + .priv_auto_alloc_size = sizeof(struct sandbox_flash_priv), + .platdata_auto_alloc_size = sizeof(struct sandbox_flash_plat), +}; diff --git a/drivers/usb/emul/sandbox_hub.c b/drivers/usb/emul/sandbox_hub.c new file mode 100644 index 0000000..baf8bdc --- /dev/null +++ b/drivers/usb/emul/sandbox_hub.c @@ -0,0 +1,304 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <usb.h> +#include <dm/device-internal.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* We only support up to 8 */ +#define SANDBOX_NUM_PORTS 2 + +struct sandbox_hub_platdata { + struct usb_dev_platdata plat; + int port; /* Port number (numbered from 0) */ +}; + +enum { + STRING_MANUFACTURER = 1, + STRING_PRODUCT, + STRING_SERIAL, + + STRING_count, +}; + +static struct usb_string hub_strings[] = { + {STRING_MANUFACTURER, "sandbox"}, + {STRING_PRODUCT, "hub"}, + {STRING_SERIAL, "2345"}, + {}, +}; + +static struct usb_device_descriptor hub_device_desc = { + .bLength = sizeof(hub_device_desc), + .bDescriptorType = USB_DT_DEVICE, + + .bcdUSB = __constant_cpu_to_le16(0x0200), + + .bDeviceClass = USB_CLASS_HUB, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + + .idVendor = __constant_cpu_to_le16(0x1234), + .idProduct = __constant_cpu_to_le16(0x5678), + .iManufacturer = STRING_MANUFACTURER, + .iProduct = STRING_PRODUCT, + .iSerialNumber = STRING_SERIAL, + .bNumConfigurations = 1, +}; + +static struct usb_config_descriptor hub_config1 = { + .bLength = sizeof(hub_config1), + .bDescriptorType = USB_DT_CONFIG, + + /* wTotalLength is set up by usb-emul-uclass */ + .bNumInterfaces = 1, + .bConfigurationValue = 0, + .iConfiguration = 0, + .bmAttributes = 1 << 7, + .bMaxPower = 50, +}; + +static struct usb_interface_descriptor hub_interface0 = { + .bLength = sizeof(hub_interface0), + .bDescriptorType = USB_DT_INTERFACE, + + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_HUB, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = US_PR_CB, + .iInterface = 0, +}; + +static struct usb_endpoint_descriptor hub_endpoint0_in = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = 1 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = __constant_cpu_to_le16(1024), + .bInterval = 0, +}; + +static struct usb_hub_descriptor hub_desc = { + .bLength = sizeof(hub_desc), + .bDescriptorType = USB_DT_HUB, + .bNbrPorts = SANDBOX_NUM_PORTS, + .wHubCharacteristics = __constant_cpu_to_le16(1 << 0 | 1 << 3 | + 1 << 7), + .bPwrOn2PwrGood = 2, + .bHubContrCurrent = 5, + .DeviceRemovable = {0, 0xff}, /* all ports removeable */ +#if SANDBOX_NUM_PORTS > 8 +#error "This code sets up an incorrect mask" +#endif +}; + +static void *hub_desc_list[] = { + &hub_device_desc, + &hub_config1, + &hub_interface0, + &hub_endpoint0_in, + &hub_desc, + NULL, +}; + +struct sandbox_hub_priv { + int status[SANDBOX_NUM_PORTS]; + int change[SANDBOX_NUM_PORTS]; +}; + +static struct udevice *hub_find_device(struct udevice *hub, int port) +{ + struct udevice *dev; + + for (device_find_first_child(hub, &dev); + dev; + device_find_next_child(&dev)) { + struct sandbox_hub_platdata *plat; + + plat = dev_get_parent_platdata(dev); + if (plat->port == port) + return dev; + } + + return NULL; +} + +static int clrset_post_state(struct udevice *hub, int port, int clear, int set) +{ + struct sandbox_hub_priv *priv = dev_get_priv(hub); + int *status = &priv->status[port]; + int *change = &priv->change[port]; + int ret = 0; + + if ((clear | set) & USB_PORT_STAT_POWER) { + struct udevice *dev = hub_find_device(hub, port); + + if (dev) { + if (set & USB_PORT_STAT_POWER) { + ret = device_probe(dev); + debug("%s: %s: power on, probed, ret=%d\n", + __func__, dev->name, ret); + if (!ret) { + set |= USB_PORT_STAT_CONNECTION | + USB_PORT_STAT_ENABLE; + } + + } else if (clear & USB_PORT_STAT_POWER) { + debug("%s: %s: power off, removed, ret=%d\n", + __func__, dev->name, ret); + ret = device_remove(dev); + clear |= USB_PORT_STAT_CONNECTION; + } + } + } + *change |= *status & clear; + *change |= ~*status & set; + *change &= 0x1f; + *status = (*status & ~clear) | set; + + return ret; +} + +static int sandbox_hub_submit_control_msg(struct udevice *bus, + struct usb_device *udev, + unsigned long pipe, + void *buffer, int length, + struct devrequest *setup) +{ + struct sandbox_hub_priv *priv = dev_get_priv(bus); + int ret = 0; + + if (pipe == usb_rcvctrlpipe(udev, 0)) { + switch (setup->requesttype) { + case USB_RT_HUB | USB_DIR_IN: + switch (setup->request) { + case USB_REQ_GET_STATUS: { + struct usb_hub_status *hubsts = buffer; + + hubsts->wHubStatus = 0; + hubsts->wHubChange = 0; + udev->status = 0; + udev->act_len = sizeof(*hubsts); + return 0; + } + default: + debug("%s: rx ctl requesttype=%x, request=%x\n", + __func__, setup->requesttype, + setup->request); + break; + } + case USB_RT_PORT | USB_DIR_IN: + switch (setup->request) { + case USB_REQ_GET_STATUS: { + struct usb_port_status *portsts = buffer; + int port; + + port = (setup->index & USB_HUB_PORT_MASK) - 1; + portsts->wPortStatus = priv->status[port]; + portsts->wPortChange = priv->change[port]; + udev->status = 0; + udev->act_len = sizeof(*portsts); + return 0; + } + } + default: + debug("%s: rx ctl requesttype=%x, request=%x\n", + __func__, setup->requesttype, setup->request); + break; + } + } else if (pipe == usb_sndctrlpipe(udev, 0)) { + switch (setup->requesttype) { + case USB_RT_PORT: + switch (setup->request) { + case USB_REQ_SET_FEATURE: { + int port; + + port = (setup->index & USB_HUB_PORT_MASK) - 1; + debug("set feature port=%x, feature=%x\n", + port, setup->value); + if (setup->value < USB_PORT_FEAT_C_CONNECTION) { + ret = clrset_post_state(bus, port, 0, + 1 << setup->value); + } else { + debug(" ** Invalid feature\n"); + } + return ret; + } + case USB_REQ_CLEAR_FEATURE: { + int port; + + port = (setup->index & USB_HUB_PORT_MASK) - 1; + debug("clear feature port=%x, feature=%x\n", + port, setup->value); + if (setup->value < USB_PORT_FEAT_C_CONNECTION) { + ret = clrset_post_state(bus, port, + 1 << setup->value, 0); + } else { + priv->change[port] &= 1 << + (setup->value - 16); + } + udev->status = 0; + return 0; + } + default: + debug("%s: tx ctl requesttype=%x, request=%x\n", + __func__, setup->requesttype, + setup->request); + break; + } + default: + debug("%s: tx ctl requesttype=%x, request=%x\n", + __func__, setup->requesttype, setup->request); + break; + } + } + debug("pipe=%lx\n", pipe); + + return -EIO; +} + +static int sandbox_hub_bind(struct udevice *dev) +{ + return usb_emul_setup_device(dev, PACKET_SIZE_64, hub_strings, + hub_desc_list); +} + +static int sandbox_child_post_bind(struct udevice *dev) +{ + struct sandbox_hub_platdata *plat = dev_get_parent_platdata(dev); + + plat->port = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1); + + return 0; +} + +static const struct dm_usb_ops sandbox_usb_hub_ops = { + .control = sandbox_hub_submit_control_msg, +}; + +static const struct udevice_id sandbox_usb_hub_ids[] = { + { .compatible = "sandbox,usb-hub" }, + { } +}; + +U_BOOT_DRIVER(usb_sandbox_hub) = { + .name = "usb_sandbox_hub", + .id = UCLASS_USB_EMUL, + .of_match = sandbox_usb_hub_ids, + .bind = sandbox_hub_bind, + .ops = &sandbox_usb_hub_ops, + .priv_auto_alloc_size = sizeof(struct sandbox_hub_priv), + .per_child_platdata_auto_alloc_size = + sizeof(struct sandbox_hub_platdata), + .child_post_bind = sandbox_child_post_bind, +}; diff --git a/drivers/usb/emul/usb-emul-uclass.c b/drivers/usb/emul/usb-emul-uclass.c new file mode 100644 index 0000000..205f2c5 --- /dev/null +++ b/drivers/usb/emul/usb-emul-uclass.c @@ -0,0 +1,263 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <usb.h> +#include <dm/root.h> +#include <dm/device-internal.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int copy_to_unicode(char *buff, int length, const char *str) +{ + int ptr; + int i; + + if (length < 2) + return 0; + buff[1] = USB_DT_STRING; + for (ptr = 2, i = 0; ptr + 1 < length && *str; i++, ptr += 2) { + buff[ptr] = str[i]; + buff[ptr + 1] = 0; + } + buff[0] = ptr; + + return ptr; +} + +static int usb_emul_get_string(struct usb_string *strings, int index, + char *buff, int length) +{ + if (index == 0) { + char *desc = buff; + + desc[0] = 4; + desc[1] = USB_DT_STRING; + desc[2] = 0x09; + desc[3] = 0x14; + return 4; + } else if (strings) { + struct usb_string *ptr; + + for (ptr = strings; ptr->s; ptr++) { + if (ptr->id == index) + return copy_to_unicode(buff, length, ptr->s); + } + } + + return -EINVAL; +} + +static struct usb_generic_descriptor **find_descriptor( + struct usb_generic_descriptor **ptr, int type, int index) +{ + debug("%s: type=%x, index=%d\n", __func__, type, index); + for (; *ptr; ptr++) { + if ((*ptr)->bDescriptorType != type) + continue; + switch (type) { + case USB_DT_CONFIG: { + struct usb_config_descriptor *cdesc; + + cdesc = (struct usb_config_descriptor *)*ptr; + if (cdesc && cdesc->bConfigurationValue == index) + return ptr; + break; + } + default: + return ptr; + } + } + debug("%s: config ptr=%p\n", __func__, *ptr); + + return ptr; +} + +static int usb_emul_get_descriptor(struct usb_dev_platdata *plat, int value, + void *buffer, int length) +{ + struct usb_generic_descriptor **ptr; + int type = value >> 8; + int index = value & 0xff; + int upto, todo; + + debug("%s: type=%d, index=%d, plat=%p\n", __func__, type, index, plat); + if (type == USB_DT_STRING) { + return usb_emul_get_string(plat->strings, index, buffer, + length); + } + + ptr = find_descriptor((struct usb_generic_descriptor **)plat->desc_list, + type, index); + if (!ptr) { + debug("%s: Could not find descriptor type %d, index %d\n", + __func__, type, index); + return -ENOENT; + } + for (upto = 0; *ptr && upto < length; ptr++, upto += todo) { + todo = min(length - upto, (int)(*ptr)->bLength); + + memcpy(buffer + upto, *ptr, todo); + } + + return upto ? upto : length ? -EIO : 0; +} + +int usb_emul_find(struct udevice *bus, ulong pipe, struct udevice **emulp) +{ + int devnum = usb_pipedevice(pipe); + struct udevice *dev; + struct uclass *uc; + int ret; + + *emulp = NULL; + ret = uclass_get(UCLASS_USB_EMUL, &uc); + if (ret) + return ret; + uclass_foreach_dev(dev, uc) { + struct usb_dev_platdata *udev = dev_get_parent_platdata(dev); + + if (udev->devnum == devnum) { + debug("%s: Found emulator '%s', addr %d\n", __func__, + dev->name, udev->devnum); + *emulp = dev; + return 0; + } + } + + debug("%s: No emulator found, addr %d\n", __func__, devnum); + return -ENOENT; +} + +int usb_emul_control(struct udevice *emul, struct usb_device *udev, + unsigned long pipe, void *buffer, int length, + struct devrequest *setup) +{ + struct dm_usb_ops *ops = usb_get_emul_ops(emul); + struct usb_dev_platdata *plat; + int ret; + + /* We permit getting the descriptor before we are probed */ + plat = dev_get_parent_platdata(emul); + if (!ops->control) + return -ENOSYS; + debug("%s: dev=%s\n", __func__, emul->name); + if (pipe == usb_rcvctrlpipe(udev, 0)) { + switch (setup->request) { + case USB_REQ_GET_DESCRIPTOR: { + return usb_emul_get_descriptor(plat, setup->value, + buffer, length); + } + default: + ret = device_probe(emul); + if (ret) + return ret; + return ops->control(emul, udev, pipe, buffer, length, + setup); + } + } else if (pipe == usb_snddefctrl(udev)) { + switch (setup->request) { + case USB_REQ_SET_ADDRESS: + debug(" ** set address %s %d\n", emul->name, + setup->value); + plat->devnum = setup->value; + return 0; + default: + debug("requestsend =%x\n", setup->request); + break; + } + } else if (pipe == usb_sndctrlpipe(udev, 0)) { + switch (setup->request) { + case USB_REQ_SET_CONFIGURATION: + plat->configno = setup->value; + return 0; + default: + ret = device_probe(emul); + if (ret) + return ret; + return ops->control(emul, udev, pipe, buffer, length, + setup); + } + } + debug("pipe=%lx\n", pipe); + + return -EIO; +} + +int usb_emul_bulk(struct udevice *emul, struct usb_device *udev, + unsigned long pipe, void *buffer, int length) +{ + struct dm_usb_ops *ops = usb_get_emul_ops(emul); + int ret; + + /* We permit getting the descriptor before we are probed */ + if (!ops->bulk) + return -ENOSYS; + debug("%s: dev=%s\n", __func__, emul->name); + ret = device_probe(emul); + if (ret) + return ret; + return ops->bulk(emul, udev, pipe, buffer, length); +} + +int usb_emul_setup_device(struct udevice *dev, int maxpacketsize, + struct usb_string *strings, void **desc_list) +{ + struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); + struct usb_generic_descriptor **ptr; + struct usb_config_descriptor *cdesc; + int upto; + + plat->strings = strings; + plat->desc_list = (struct usb_generic_descriptor **)desc_list; + + /* Fill in wTotalLength for each configuration descriptor */ + ptr = plat->desc_list; + for (cdesc = NULL, upto = 0; *ptr; upto += (*ptr)->bLength, ptr++) { + debug(" - upto=%d, type=%d\n", upto, (*ptr)->bDescriptorType); + if ((*ptr)->bDescriptorType == USB_DT_CONFIG) { + if (cdesc) { + cdesc->wTotalLength = upto; + debug("%s: config %d length %d\n", __func__, + cdesc->bConfigurationValue, + cdesc->bLength); + } + cdesc = (struct usb_config_descriptor *)*ptr; + upto = 0; + } + } + if (cdesc) { + cdesc->wTotalLength = upto; + debug("%s: config %d length %d\n", __func__, + cdesc->bConfigurationValue, cdesc->wTotalLength); + } + + return 0; +} + +int usb_emul_post_bind(struct udevice *dev) +{ + /* Scan the bus for devices */ + return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); +} + +void usb_emul_reset(struct udevice *dev) +{ + struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); + + plat->devnum = 0; + plat->configno = 0; +} + +UCLASS_DRIVER(usb_emul) = { + .id = UCLASS_USB_EMUL, + .name = "usb_emul", + .post_bind = usb_emul_post_bind, + .per_child_auto_alloc_size = sizeof(struct usb_device), + .per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata), +}; diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c index 1cd179b..c8697ae 100644 --- a/drivers/usb/eth/asix.c +++ b/drivers/usb/eth/asix.c @@ -534,7 +534,8 @@ static int asix_recv(struct eth_device *eth) } /* Notify net stack */ - NetReceive(buf_ptr + sizeof(packet_len), packet_len); + net_process_received_packet(buf_ptr + sizeof(packet_len), + packet_len); /* Adjust for next iteration. Packets are padded to 16-bits */ if (packet_len & 1) diff --git a/drivers/usb/eth/asix88179.c b/drivers/usb/eth/asix88179.c index 0ef85db..94dfe85 100644 --- a/drivers/usb/eth/asix88179.c +++ b/drivers/usb/eth/asix88179.c @@ -558,7 +558,7 @@ static int asix_recv(struct eth_device *eth) frame_pos += 2; - NetReceive(recv_buf + frame_pos, pkt_len); + net_process_received_packet(recv_buf + frame_pos, pkt_len); pkt_hdr++; frame_pos += ((pkt_len + 7) & 0xFFF8)-2; diff --git a/drivers/usb/eth/mcs7830.c b/drivers/usb/eth/mcs7830.c index 8e738d4..c1b7086 100644 --- a/drivers/usb/eth/mcs7830.c +++ b/drivers/usb/eth/mcs7830.c @@ -600,7 +600,7 @@ static int mcs7830_recv(struct eth_device *eth) if (sts == STAT_RX_FRAME_CORRECT) { debug("%s() got a frame, len=%d\n", __func__, gotlen); - NetReceive(buf, gotlen); + net_process_received_packet(buf, gotlen); return 0; } diff --git a/drivers/usb/eth/smsc95xx.c b/drivers/usb/eth/smsc95xx.c index 6bca34d..a7e50d6 100644 --- a/drivers/usb/eth/smsc95xx.c +++ b/drivers/usb/eth/smsc95xx.c @@ -355,7 +355,7 @@ static int smsc95xx_init_mac_address(struct eth_device *eth, /* try reading mac address from EEPROM */ if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, eth->enetaddr) == 0) { - if (is_valid_ether_addr(eth->enetaddr)) { + if (is_valid_ethaddr(eth->enetaddr)) { /* eeprom values are valid so use them */ debug("MAC address read from EEPROM\n"); return 0; @@ -760,7 +760,8 @@ static int smsc95xx_recv(struct eth_device *eth) } /* Notify net stack */ - NetReceive(buf_ptr + sizeof(packet_len), packet_len - 4); + net_process_received_packet(buf_ptr + sizeof(packet_len), + packet_len - 4); /* Adjust for next iteration */ actual_len -= sizeof(packet_len) + packet_len; diff --git a/drivers/usb/eth/usb_ether.c b/drivers/usb/eth/usb_ether.c index 7cb96e3..c72b7e4 100644 --- a/drivers/usb/eth/usb_ether.c +++ b/drivers/usb/eth/usb_ether.c @@ -5,7 +5,9 @@ */ #include <common.h> +#include <dm.h> #include <usb.h> +#include <dm/device-internal.h> #include "usb_ether.h" @@ -118,8 +120,6 @@ static void probe_valid_drivers(struct usb_device *dev) int usb_host_eth_scan(int mode) { int i, old_async; - struct usb_device *dev; - if (mode == 1) printf(" scanning usb for ethernet devices... "); @@ -138,23 +138,59 @@ int usb_host_eth_scan(int mode) } usb_max_eth_dev = 0; +#ifdef CONFIG_DM_USB + /* + * TODO: We should add USB_DEVICE() declarations to each USB ethernet + * driver and then most of this file can be removed. + */ + struct udevice *bus; + struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_USB, &uc); + if (ret) + return ret; + uclass_foreach_dev(bus, uc) { + for (i = 0; i < USB_MAX_DEVICE; i++) { + struct usb_device *dev; + + dev = usb_get_dev_index(bus, i); /* get device */ + debug("i=%d, %s\n", i, dev ? dev->dev->name : "(done)"); + if (!dev) + break; /* no more devices available */ + + /* + * find valid usb_ether driver for this device, + * if any + */ + probe_valid_drivers(dev); + + /* check limit */ + if (usb_max_eth_dev == USB_MAX_ETH_DEV) + break; + } /* for */ + } +#else for (i = 0; i < USB_MAX_DEVICE; i++) { + struct usb_device *dev; + dev = usb_get_dev_index(i); /* get device */ debug("i=%d\n", i); - if (dev == NULL) + if (!dev) break; /* no more devices available */ /* find valid usb_ether driver for this device, if any */ probe_valid_drivers(dev); /* check limit */ - if (usb_max_eth_dev == USB_MAX_ETH_DEV) { - printf("max USB Ethernet Device reached: %d stopping\n", - usb_max_eth_dev); + if (usb_max_eth_dev == USB_MAX_ETH_DEV) break; - } } /* for */ - +#endif + if (usb_max_eth_dev == USB_MAX_ETH_DEV) { + printf("max USB Ethernet Device reached: %d stopping\n", + usb_max_eth_dev); + } usb_disable_asynch(old_async); /* restore asynch value */ printf("%d Ethernet Device(s) found\n", usb_max_eth_dev); if (usb_max_eth_dev > 0) diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c index 3b7024c..22d288c 100644 --- a/drivers/usb/gadget/ci_udc.c +++ b/drivers/usb/gadget/ci_udc.c @@ -883,7 +883,11 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) if (driver->speed != USB_SPEED_FULL && driver->speed != USB_SPEED_HIGH) return -EINVAL; +#ifdef CONFIG_DM_USB + ret = usb_setup_ehci_gadget(&controller.ctrl); +#else ret = usb_lowlevel_init(0, USB_INIT_DEVICE, (void **)&controller.ctrl); +#endif if (ret) return ret; diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 7e3b3ed..141ff8b 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -1522,7 +1522,7 @@ static int rx_submit(struct eth_dev *dev, struct usb_request *req, * RNDIS headers involve variable numbers of LE32 values. */ - req->buf = (u8 *) NetRxPackets[0]; + req->buf = (u8 *)net_rx_packets[0]; req->length = size; req->complete = rx_complete; @@ -1645,13 +1645,13 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) if (!eth_is_promisc (dev)) { u8 *dest = skb->data; - if (is_multicast_ether_addr(dest)) { + if (is_multicast_ethaddr(dest)) { u16 type; /* ignores USB_CDC_PACKET_TYPE_MULTICAST and host * SET_ETHERNET_MULTICAST_FILTERS requests */ - if (is_broadcast_ether_addr(dest)) + if (is_broadcast_ethaddr(dest)) type = USB_CDC_PACKET_TYPE_BROADCAST; else type = USB_CDC_PACKET_TYPE_ALL_MULTICAST; @@ -1942,7 +1942,7 @@ static int is_eth_addr_valid(char *str) } /* Now check the contents. */ - return is_valid_ether_addr(ea); + return is_valid_ethaddr(ea); } return 0; } @@ -1971,7 +1971,7 @@ static int get_ether_addr(const char *str, u8 *dev_addr) num |= (nibble(*str++)); dev_addr[i] = num; } - if (is_valid_ether_addr(dev_addr)) + if (is_valid_ethaddr(dev_addr)) return 0; } return 1; @@ -2446,7 +2446,8 @@ static int usb_eth_recv(struct eth_device *netdev) if (packet_received) { debug("%s: packet received\n", __func__); if (dev->rx_req) { - NetReceive(NetRxPackets[0], dev->rx_req->length); + net_process_received_packet(net_rx_packets[0], + dev->rx_req->length); packet_received = 0; rx_submit(dev, dev->rx_req, 0); diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index eb6f34b..3b57e56 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -5,6 +5,11 @@ # SPDX-License-Identifier: GPL-2.0+ # +ifdef CONFIG_DM_USB +obj-$(CONFIG_CMD_USB) += usb-uclass.o +obj-$(CONFIG_SANDBOX) += usb-sandbox.o +endif + # ohci obj-$(CONFIG_USB_OHCI_NEW) += ohci-hcd.o obj-$(CONFIG_USB_ATMEL) += ohci-at91.o @@ -39,6 +44,7 @@ obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_UNIPHIER) += ehci-uniphier.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o +obj-$(CONFIG_USB_EHCI_VF) += ehci-vf.o obj-$(CONFIG_USB_EHCI_RMOBILE) += ehci-rmobile.o obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index f3c077d..86cf631 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -8,6 +8,7 @@ */ #include <common.h> +#include <dm.h> #include <fdtdec.h> #include <libfdt.h> #include <malloc.h> @@ -24,19 +25,73 @@ /* Declare global data pointer */ DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_DM_USB +struct exynos_ehci_platdata { + struct usb_platdata usb_plat; + fdt_addr_t hcd_base; + fdt_addr_t phy_base; + struct gpio_desc vbus_gpio; +}; +#endif + /** * Contains pointers to register base addresses * for the usb controller. */ struct exynos_ehci { + struct ehci_ctrl ctrl; struct exynos_usb_phy *usb; struct ehci_hccr *hcd; +#ifndef CONFIG_DM_USB struct gpio_desc vbus_gpio; +#endif }; +#ifndef CONFIG_DM_USB static struct exynos_ehci exynos; +#endif -#ifdef CONFIG_OF_CONTROL +#ifdef CONFIG_DM_USB +static int ehci_usb_ofdata_to_platdata(struct udevice *dev) +{ + struct exynos_ehci_platdata *plat = dev_get_platdata(dev); + const void *blob = gd->fdt_blob; + unsigned int node; + int depth; + + /* + * Get the base address for XHCI controller from the device node + */ + plat->hcd_base = dev_get_addr(dev); + if (plat->hcd_base == FDT_ADDR_T_NONE) { + debug("Can't get the XHCI register base address\n"); + return -ENXIO; + } + + depth = 0; + node = fdtdec_next_compatible_subnode(blob, dev->of_offset, + COMPAT_SAMSUNG_EXYNOS_USB_PHY, &depth); + if (node <= 0) { + debug("XHCI: Can't get device node for usb3-phy controller\n"); + return -ENODEV; + } + + /* + * Get the base address for usbphy from the device node + */ + plat->phy_base = fdtdec_get_addr(blob, node, "reg"); + if (plat->phy_base == FDT_ADDR_T_NONE) { + debug("Can't get the usbphy register address\n"); + return -ENXIO; + } + + /* Vbus gpio */ + gpio_request_by_name(dev, "samsung,vbus-gpio", 0, + &plat->vbus_gpio, GPIOD_IS_OUT); + + return 0; +} +#else static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos) { fdt_addr_t addr; @@ -215,6 +270,7 @@ static void reset_usb_phy(struct exynos_usb_phy *usb) set_usbhost_phy_ctrl(POWER_USB_HOST_PHY_CTRL_DISABLE); } +#ifndef CONFIG_DM_USB /* * EHCI-initialization * Create the appropriate control structures to manage @@ -268,3 +324,57 @@ int ehci_hcd_stop(int index) return 0; } +#endif + +#ifdef CONFIG_DM_USB +static int ehci_usb_probe(struct udevice *dev) +{ + struct exynos_ehci_platdata *plat = dev_get_platdata(dev); + struct exynos_ehci *ctx = dev_get_priv(dev); + struct ehci_hcor *hcor; + + ctx->hcd = (struct ehci_hccr *)plat->hcd_base; + ctx->usb = (struct exynos_usb_phy *)plat->phy_base; + hcor = (struct ehci_hcor *)((uint32_t)ctx->hcd + + HC_LENGTH(ehci_readl(&ctx->hcd->cr_capbase))); + + /* setup the Vbus gpio here */ + if (dm_gpio_is_valid(&plat->vbus_gpio)) + dm_gpio_set_value(&plat->vbus_gpio, 1); + + setup_usb_phy(ctx->usb); + + return ehci_register(dev, ctx->hcd, hcor, NULL, 0, USB_INIT_HOST); +} + +static int ehci_usb_remove(struct udevice *dev) +{ + struct exynos_ehci *ctx = dev_get_priv(dev); + int ret; + + ret = ehci_deregister(dev); + if (ret) + return ret; + reset_usb_phy(ctx->usb); + + return 0; +} + +static const struct udevice_id ehci_usb_ids[] = { + { .compatible = "samsung,exynos-ehci" }, + { } +}; + +U_BOOT_DRIVER(usb_ehci) = { + .name = "ehci_exynos", + .id = UCLASS_USB, + .of_match = ehci_usb_ids, + .ofdata_to_platdata = ehci_usb_ofdata_to_platdata, + .probe = ehci_usb_probe, + .remove = ehci_usb_remove, + .ops = &ehci_usb_ops, + .priv_auto_alloc_size = sizeof(struct exynos_ehci), + .platdata_auto_alloc_size = sizeof(struct exynos_ehci_platdata), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif diff --git a/drivers/usb/host/ehci-faraday.c b/drivers/usb/host/ehci-faraday.c index 3b761bc..821222c 100644 --- a/drivers/usb/host/ehci-faraday.c +++ b/drivers/usb/host/ehci-faraday.c @@ -29,6 +29,59 @@ static inline int ehci_is_fotg2xx(union ehci_faraday_regs *regs) return !readl(®s->usb.easstr); } +void faraday_ehci_set_usbmode(struct ehci_ctrl *ctrl) +{ + /* nothing needs to be done */ +} + +int faraday_ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg) +{ + int spd, ret = PORTSC_PSPD_HS; + union ehci_faraday_regs *regs; + + ret = (void __iomem *)((ulong)ctrl->hcor - 0x10); + if (ehci_is_fotg2xx(regs)) + spd = OTGCSR_SPD(readl(®s->otg.otgcsr)); + else + spd = BMCSR_SPD(readl(®s->usb.bmcsr)); + + switch (spd) { + case 0: /* full speed */ + ret = PORTSC_PSPD_FS; + break; + case 1: /* low speed */ + ret = PORTSC_PSPD_LS; + break; + case 2: /* high speed */ + ret = PORTSC_PSPD_HS; + break; + default: + printf("ehci-faraday: invalid device speed\n"); + break; + } + + return ret; +} + +uint32_t *faraday_ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port) +{ + /* Faraday EHCI has one and only one portsc register */ + if (port) { + /* Printing the message would cause a scan failure! */ + debug("The request port(%d) is not configured\n", port); + return NULL; + } + + /* Faraday EHCI PORTSC register offset is 0x20 from hcor */ + return (uint32_t *)((uint8_t *)ctrl->hcor + 0x20); +} + +static const struct ehci_ops faraday_ehci_ops = { + .set_usb_mode = faraday_ehci_set_usbmode, + .get_port_speed = faraday_ehci_get_port_speed, + .get_portsc_register = faraday_ehci_get_portsc_register, +}; + /* * Create the appropriate control structures to manage * a new EHCI host controller. @@ -43,6 +96,7 @@ int ehci_hcd_init(int index, enum usb_init_type init, if (index < 0 || index >= ARRAY_SIZE(base_list)) return -1; + ehci_set_controller_priv(index, NULL, &faraday_ehci_ops); regs = (void __iomem *)base_list[index]; hccr = (struct ehci_hccr *)®s->usb.hccr; hcor = (struct ehci_hcor *)®s->usb.hcor; @@ -87,61 +141,3 @@ int ehci_hcd_stop(int index) { return 0; } - -/* - * This ehci_set_usbmode() overrides the weak function - * in "ehci-hcd.c". - */ -void ehci_set_usbmode(int index) -{ - /* nothing needs to be done */ -} - -/* - * This ehci_get_port_speed() overrides the weak function - * in "ehci-hcd.c". - */ -int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg) -{ - int spd, ret = PORTSC_PSPD_HS; - union ehci_faraday_regs *regs = (void __iomem *)((ulong)hcor - 0x10); - - if (ehci_is_fotg2xx(regs)) - spd = OTGCSR_SPD(readl(®s->otg.otgcsr)); - else - spd = BMCSR_SPD(readl(®s->usb.bmcsr)); - - switch (spd) { - case 0: /* full speed */ - ret = PORTSC_PSPD_FS; - break; - case 1: /* low speed */ - ret = PORTSC_PSPD_LS; - break; - case 2: /* high speed */ - ret = PORTSC_PSPD_HS; - break; - default: - printf("ehci-faraday: invalid device speed\n"); - break; - } - - return ret; -} - -/* - * This ehci_get_portsc_register() overrides the weak function - * in "ehci-hcd.c". - */ -uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port) -{ - /* Faraday EHCI has one and only one portsc register */ - if (port) { - /* Printing the message would cause a scan failure! */ - debug("The request port(%d) is not configured\n", port); - return NULL; - } - - /* Faraday EHCI PORTSC register offset is 0x20 from hcor */ - return (uint32_t *)((uint8_t *)hcor + 0x20); -} diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 5d4288d..2dca524 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -259,10 +259,11 @@ static int fdt_fixup_usb_erratum(void *blob, const char *prop_erratum, void fdt_fixup_dr_usb(void *blob, bd_t *bd) { static const char * const modes[] = { "host", "peripheral", "otg" }; - static const char * const phys[] = { "ulpi", "utmi" }; + static const char * const phys[] = { "ulpi", "utmi", "utmi_dual" }; int usb_erratum_a006261_off = -1; int usb_erratum_a007075_off = -1; int usb_erratum_a007792_off = -1; + int usb_erratum_a005697_off = -1; int usb_mode_off = -1; int usb_phy_off = -1; char str[5]; @@ -303,6 +304,9 @@ void fdt_fixup_dr_usb(void *blob, bd_t *bd) dr_phy_type = phys[phy_idx]; } + if (has_dual_phy()) + dr_phy_type = phys[2]; + usb_mode_off = fdt_fixup_usb_mode_phy_type(blob, dr_mode_type, NULL, usb_mode_off); @@ -325,6 +329,7 @@ void fdt_fixup_dr_usb(void *blob, bd_t *bd) if (usb_erratum_a006261_off < 0) return; } + if (has_erratum_a007075()) { usb_erratum_a007075_off = fdt_fixup_usb_erratum (blob, @@ -333,6 +338,7 @@ void fdt_fixup_dr_usb(void *blob, bd_t *bd) if (usb_erratum_a007075_off < 0) return; } + if (has_erratum_a007792()) { usb_erratum_a007792_off = fdt_fixup_usb_erratum (blob, @@ -341,6 +347,14 @@ void fdt_fixup_dr_usb(void *blob, bd_t *bd) if (usb_erratum_a007792_off < 0) return; } + if (has_erratum_a005697()) { + usb_erratum_a005697_off = fdt_fixup_usb_erratum + (blob, + "fsl,usb-erratum-a005697", + usb_erratum_a005697_off); + if (usb_erratum_a005697_off < 0) + return; + } } } #endif diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 86f1646..bd9861d 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -21,6 +21,7 @@ * MA 02111-1307 USA */ #include <common.h> +#include <dm.h> #include <errno.h> #include <asm/byteorder.h> #include <asm/unaligned.h> @@ -42,7 +43,9 @@ */ #define HCHALT_TIMEOUT (8 * 1000) +#ifndef CONFIG_DM_USB static struct ehci_ctrl ehcic[CONFIG_USB_MAX_CONTROLLER_COUNT]; +#endif #define ALIGN_END_ADDR(type, ptr, size) \ ((unsigned long)(ptr) + roundup((size) * sizeof(type), USB_DMA_MINALIGN)) @@ -119,17 +122,33 @@ static struct descriptor { #define ehci_is_TDI() (0) #endif -__weak int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg) +static struct ehci_ctrl *ehci_get_ctrl(struct usb_device *udev) +{ +#ifdef CONFIG_DM_USB + struct udevice *dev; + + /* Find the USB controller */ + for (dev = udev->dev; + device_get_uclass_id(dev) != UCLASS_USB; + dev = dev->parent) + ; + return dev_get_priv(dev); +#else + return udev->controller; +#endif +} + +static int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg) { return PORTSC_PSPD(reg); } -__weak void ehci_set_usbmode(int index) +static void ehci_set_usbmode(struct ehci_ctrl *ctrl) { uint32_t tmp; uint32_t *reg_ptr; - reg_ptr = (uint32_t *)((u8 *)&ehcic[index].hcor->or_usbcmd + USBMODE); + reg_ptr = (uint32_t *)((u8 *)&ctrl->hcor->or_usbcmd + USBMODE); tmp = ehci_readl(reg_ptr); tmp |= USBMODE_CM_HC; #if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN) @@ -138,11 +157,23 @@ __weak void ehci_set_usbmode(int index) ehci_writel(reg_ptr, tmp); } -__weak void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg) +static void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg, + uint32_t *reg) { mdelay(50); } +static uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port) +{ + if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) { + /* Printing the message would cause a scan failure! */ + debug("The request port(%u) is not configured\n", port); + return NULL; + } + + return (uint32_t *)&ctrl->hcor->or_portsc[port]; +} + static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec) { uint32_t result; @@ -159,15 +190,15 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec) return -1; } -static int ehci_reset(int index) +static int ehci_reset(struct ehci_ctrl *ctrl) { uint32_t cmd; int ret = 0; - cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd); + cmd = ehci_readl(&ctrl->hcor->or_usbcmd); cmd = (cmd & ~CMD_RUN) | CMD_RESET; - ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd); - ret = handshake((uint32_t *)&ehcic[index].hcor->or_usbcmd, + ehci_writel(&ctrl->hcor->or_usbcmd, cmd); + ret = handshake((uint32_t *)&ctrl->hcor->or_usbcmd, CMD_RESET, 0, 250 * 1000); if (ret < 0) { printf("EHCI fail to reset\n"); @@ -175,13 +206,13 @@ static int ehci_reset(int index) } if (ehci_is_TDI()) - ehci_set_usbmode(index); + ctrl->ops.set_usb_mode(ctrl); #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH - cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning); + cmd = ehci_readl(&ctrl->hcor->or_txfilltuning); cmd &= ~TXFIFO_THRESH_MASK; cmd |= TXFIFO_THRESH(CONFIG_USB_EHCI_TXFIFO_THRESH); - ehci_writel(&ehcic[index].hcor->or_txfilltuning, cmd); + ehci_writel(&ctrl->hcor->or_txfilltuning, cmd); #endif out: return ret; @@ -264,12 +295,13 @@ static inline u8 ehci_encode_speed(enum usb_device_speed speed) return QH_FULL_SPEED; } -static void ehci_update_endpt2_dev_n_port(struct usb_device *dev, +static void ehci_update_endpt2_dev_n_port(struct usb_device *udev, struct QH *qh) { struct usb_device *ttdev; + int parent_devnum; - if (dev->speed != USB_SPEED_LOW && dev->speed != USB_SPEED_FULL) + if (udev->speed != USB_SPEED_LOW && udev->speed != USB_SPEED_FULL) return; /* @@ -277,14 +309,35 @@ static void ehci_update_endpt2_dev_n_port(struct usb_device *dev, * the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs * in the tree before that one! */ - ttdev = dev; +#ifdef CONFIG_DM_USB + struct udevice *parent; + + for (ttdev = udev; ; ) { + struct udevice *dev = ttdev->dev; + + if (dev->parent && + device_get_uclass_id(dev->parent) == UCLASS_USB_HUB) + parent = dev->parent; + else + parent = NULL; + if (!parent) + return; + ttdev = dev_get_parentdata(parent); + if (!ttdev->speed != USB_SPEED_HIGH) + break; + } + parent_devnum = ttdev->devnum; +#else + ttdev = udev; while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH) ttdev = ttdev->parent; if (!ttdev->parent) return; + parent_devnum = ttdev->parent->devnum; +#endif qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) | - QH_ENDPT2_HUBADDR(ttdev->parent->devnum)); + QH_ENDPT2_HUBADDR(parent_devnum)); } static int @@ -303,7 +356,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, uint32_t cmd; int timeout; int ret = 0; - struct ehci_ctrl *ctrl = dev->controller; + struct ehci_ctrl *ctrl = ehci_get_ctrl(dev); debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe, buffer, length, req); @@ -649,20 +702,8 @@ fail: return -1; } -__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port) -{ - if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) { - /* Printing the message would cause a scan failure! */ - debug("The request port(%u) is not configured\n", port); - return NULL; - } - - return (uint32_t *)&hcor->or_portsc[port]; -} - -int -ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, - int length, struct devrequest *req) +static int ehci_submit_root(struct usb_device *dev, unsigned long pipe, + void *buffer, int length, struct devrequest *req) { uint8_t tmpbuf[4]; u16 typeReq; @@ -671,7 +712,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, uint32_t reg; uint32_t *status_reg; int port = le16_to_cpu(req->index) & 0xff; - struct ehci_ctrl *ctrl = dev->controller; + struct ehci_ctrl *ctrl = ehci_get_ctrl(dev); srclen = 0; @@ -686,7 +727,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8): case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8): case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8): - status_reg = ehci_get_portsc_register(ctrl->hcor, port - 1); + status_reg = ctrl->ops.get_portsc_register(ctrl, port - 1); if (!status_reg) return -1; break; @@ -781,7 +822,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, tmpbuf[1] |= USB_PORT_STAT_POWER >> 8; if (ehci_is_TDI()) { - switch (ehci_get_port_speed(ctrl->hcor, reg)) { + switch (ctrl->ops.get_port_speed(ctrl, reg)) { case PORTSC_PSPD_FS: break; case PORTSC_PSPD_LS: @@ -843,7 +884,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, * usb 2.0 specification say 50 ms resets on * root */ - ehci_powerup_fixup(status_reg, ®); + ctrl->ops.powerup_fixup(ctrl, status_reg, ®); ehci_writel(status_reg, reg & ~EHCI_PS_PR); /* @@ -930,41 +971,59 @@ unknown: return -1; } -int usb_lowlevel_stop(int index) +const struct ehci_ops default_ehci_ops = { + .set_usb_mode = ehci_set_usbmode, + .get_port_speed = ehci_get_port_speed, + .powerup_fixup = ehci_powerup_fixup, + .get_portsc_register = ehci_get_portsc_register, +}; + +static void ehci_setup_ops(struct ehci_ctrl *ctrl, const struct ehci_ops *ops) { - ehci_shutdown(&ehcic[index]); - return ehci_hcd_stop(index); + if (!ops) { + ctrl->ops = default_ehci_ops; + } else { + ctrl->ops = *ops; + if (!ctrl->ops.set_usb_mode) + ctrl->ops.set_usb_mode = ehci_set_usbmode; + if (!ctrl->ops.get_port_speed) + ctrl->ops.get_port_speed = ehci_get_port_speed; + if (!ctrl->ops.powerup_fixup) + ctrl->ops.powerup_fixup = ehci_powerup_fixup; + if (!ctrl->ops.get_portsc_register) + ctrl->ops.get_portsc_register = + ehci_get_portsc_register; + } } -int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +#ifndef CONFIG_DM_USB +void ehci_set_controller_priv(int index, void *priv, const struct ehci_ops *ops) +{ + struct ehci_ctrl *ctrl = &ehcic[index]; + + ctrl->priv = priv; + ehci_setup_ops(ctrl, ops); +} + +void *ehci_get_controller_priv(int index) +{ + return ehcic[index].priv; +} +#endif + +static int ehci_common_init(struct ehci_ctrl *ctrl, uint tweaks) { - uint32_t reg; - uint32_t cmd; struct QH *qh_list; struct QH *periodic; + uint32_t reg; + uint32_t cmd; int i; - int rc; - - rc = ehci_hcd_init(index, init, &ehcic[index].hccr, &ehcic[index].hcor); - if (rc) - return rc; - if (init == USB_INIT_DEVICE) - goto done; - /* EHCI spec section 4.1 */ - if (ehci_reset(index)) - return -1; - -#if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET) - rc = ehci_hcd_init(index, init, &ehcic[index].hccr, &ehcic[index].hcor); - if (rc) - return rc; -#endif /* Set the high address word (aka segment) for 64-bit controller */ - if (ehci_readl(&ehcic[index].hccr->cr_hccparams) & 1) - ehci_writel(&ehcic[index].hcor->or_ctrldssegment, 0); + if (ehci_readl(&ctrl->hccr->cr_hccparams) & 1) + ehci_writel(&ctrl->hcor->or_ctrldssegment, 0); - qh_list = &ehcic[index].qh_list; + qh_list = &ctrl->qh_list; /* Set head of reclaim list */ memset(qh_list, 0, sizeof(*qh_list)); @@ -980,14 +1039,14 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) ALIGN_END_ADDR(struct QH, qh_list, 1)); /* Set async. queue head pointer. */ - ehci_writel(&ehcic[index].hcor->or_asynclistaddr, (unsigned long)qh_list); + ehci_writel(&ctrl->hcor->or_asynclistaddr, (unsigned long)qh_list); /* * Set up periodic list * Step 1: Parent QH for all periodic transfers. */ - ehcic[index].periodic_schedules = 0; - periodic = &ehcic[index].periodic_queue; + ctrl->periodic_schedules = 0; + periodic = &ctrl->periodic_queue; memset(periodic, 0, sizeof(*periodic)); periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE); periodic->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); @@ -1005,25 +1064,25 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) * Split Transactions will be spread across microframes using * S-mask and C-mask. */ - if (ehcic[index].periodic_list == NULL) - ehcic[index].periodic_list = memalign(4096, 1024 * 4); + if (ctrl->periodic_list == NULL) + ctrl->periodic_list = memalign(4096, 1024 * 4); - if (!ehcic[index].periodic_list) + if (!ctrl->periodic_list) return -ENOMEM; for (i = 0; i < 1024; i++) { - ehcic[index].periodic_list[i] = cpu_to_hc32((unsigned long)periodic + ctrl->periodic_list[i] = cpu_to_hc32((unsigned long)periodic | QH_LINK_TYPE_QH); } - flush_dcache_range((unsigned long)ehcic[index].periodic_list, - ALIGN_END_ADDR(uint32_t, ehcic[index].periodic_list, + flush_dcache_range((unsigned long)ctrl->periodic_list, + ALIGN_END_ADDR(uint32_t, ctrl->periodic_list, 1024)); /* Set periodic list base address */ - ehci_writel(&ehcic[index].hcor->or_periodiclistbase, - (unsigned long)ehcic[index].periodic_list); + ehci_writel(&ctrl->hcor->or_periodiclistbase, + (unsigned long)ctrl->periodic_list); - reg = ehci_readl(&ehcic[index].hccr->cr_hcsparams); + reg = ehci_readl(&ctrl->hccr->cr_hcsparams); descriptor.hub.bNbrPorts = HCS_N_PORTS(reg); debug("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts); /* Port Indicators */ @@ -1036,37 +1095,81 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) | 0x01, &descriptor.hub.wHubCharacteristics); /* Start the host controller. */ - cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd); + cmd = ehci_readl(&ctrl->hcor->or_usbcmd); /* * Philips, Intel, and maybe others need CMD_RUN before the * root hub will detect new devices (why?); NEC doesn't */ cmd &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); cmd |= CMD_RUN; - ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd); + ehci_writel(&ctrl->hcor->or_usbcmd, cmd); -#ifndef CONFIG_USB_EHCI_FARADAY - /* take control over the ports */ - cmd = ehci_readl(&ehcic[index].hcor->or_configflag); - cmd |= FLAG_CF; - ehci_writel(&ehcic[index].hcor->or_configflag, cmd); -#endif + if (!(tweaks & EHCI_TWEAK_NO_INIT_CF)) { + /* take control over the ports */ + cmd = ehci_readl(&ctrl->hcor->or_configflag); + cmd |= FLAG_CF; + ehci_writel(&ctrl->hcor->or_configflag, cmd); + } /* unblock posted write */ - cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd); + cmd = ehci_readl(&ctrl->hcor->or_usbcmd); mdelay(5); - reg = HC_VERSION(ehci_readl(&ehcic[index].hccr->cr_capbase)); + reg = HC_VERSION(ehci_readl(&ctrl->hccr->cr_capbase)); printf("USB EHCI %x.%02x\n", reg >> 8, reg & 0xff); - ehcic[index].rootdev = 0; + return 0; +} + +#ifndef CONFIG_DM_USB +int usb_lowlevel_stop(int index) +{ + ehci_shutdown(&ehcic[index]); + return ehci_hcd_stop(index); +} + +int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +{ + struct ehci_ctrl *ctrl = &ehcic[index]; + uint tweaks = 0; + int rc; + + /** + * Set ops to default_ehci_ops, ehci_hcd_init should call + * ehci_set_controller_priv to change any of these function pointers. + */ + ctrl->ops = default_ehci_ops; + + rc = ehci_hcd_init(index, init, &ctrl->hccr, &ctrl->hcor); + if (rc) + return rc; + if (init == USB_INIT_DEVICE) + goto done; + + /* EHCI spec section 4.1 */ + if (ehci_reset(ctrl)) + return -1; + +#if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET) + rc = ehci_hcd_init(index, init, &ctrl->hccr, &ctrl->hcor); + if (rc) + return rc; +#endif +#ifdef CONFIG_USB_EHCI_FARADAY + tweaks |= EHCI_TWEAK_NO_INIT_CF; +#endif + rc = ehci_common_init(ctrl, tweaks); + if (rc) + return rc; + + ctrl->rootdev = 0; done: *controller = &ehcic[index]; return 0; } +#endif -int -submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int length) +static int _ehci_submit_bulk_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int length) { if (usb_pipetype(pipe) != PIPE_BULK) { @@ -1076,11 +1179,11 @@ submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, return ehci_submit_async(dev, pipe, buffer, length, NULL); } -int -submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int length, struct devrequest *setup) +static int _ehci_submit_control_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int length, + struct devrequest *setup) { - struct ehci_ctrl *ctrl = dev->controller; + struct ehci_ctrl *ctrl = ehci_get_ctrl(dev); if (usb_pipetype(pipe) != PIPE_CONTROL) { debug("non-control pipe (type=%lu)", usb_pipetype(pipe)); @@ -1150,7 +1253,7 @@ struct int_queue * create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize, int elementsize, void *buffer, int interval) { - struct ehci_ctrl *ctrl = dev->controller; + struct ehci_ctrl *ctrl = ehci_get_ctrl(dev); struct int_queue *result = NULL; int i; @@ -1342,7 +1445,7 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue) int destroy_int_queue(struct usb_device *dev, struct int_queue *queue) { - struct ehci_ctrl *ctrl = dev->controller; + struct ehci_ctrl *ctrl = ehci_get_ctrl(dev); int result = -1; unsigned long timeout; @@ -1386,9 +1489,8 @@ out: return result; } -int -submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int length, int interval) +static int _ehci_submit_int_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int length, int interval) { void *backbuffer; struct int_queue *queue; @@ -1423,3 +1525,98 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, /* everything worked out fine */ return result; } + +#ifndef CONFIG_DM_USB +int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int length) +{ + return _ehci_submit_bulk_msg(dev, pipe, buffer, length); +} + +int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int length, struct devrequest *setup) +{ + return _ehci_submit_control_msg(dev, pipe, buffer, length, setup); +} + +int submit_int_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int length, int interval) +{ + return _ehci_submit_int_msg(dev, pipe, buffer, length, interval); +} +#endif + +#ifdef CONFIG_DM_USB +static int ehci_submit_control_msg(struct udevice *dev, struct usb_device *udev, + unsigned long pipe, void *buffer, int length, + struct devrequest *setup) +{ + debug("%s: dev='%s', udev=%p, udev->dev='%s', portnr=%d\n", __func__, + dev->name, udev, udev->dev->name, udev->portnr); + + return _ehci_submit_control_msg(udev, pipe, buffer, length, setup); +} + +static int ehci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev, + unsigned long pipe, void *buffer, int length) +{ + debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); + return _ehci_submit_bulk_msg(udev, pipe, buffer, length); +} + +static int ehci_submit_int_msg(struct udevice *dev, struct usb_device *udev, + unsigned long pipe, void *buffer, int length, + int interval) +{ + debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); + return _ehci_submit_int_msg(udev, pipe, buffer, length, interval); +} + +int ehci_register(struct udevice *dev, struct ehci_hccr *hccr, + struct ehci_hcor *hcor, const struct ehci_ops *ops, + uint tweaks, enum usb_init_type init) +{ + struct ehci_ctrl *ctrl = dev_get_priv(dev); + int ret; + + debug("%s: dev='%s', ctrl=%p, hccr=%p, hcor=%p, init=%d\n", __func__, + dev->name, ctrl, hccr, hcor, init); + + ehci_setup_ops(ctrl, ops); + ctrl->hccr = hccr; + ctrl->hcor = hcor; + ctrl->priv = ctrl; + + if (init == USB_INIT_DEVICE) + goto done; + ret = ehci_reset(ctrl); + if (ret) + goto err; + + ret = ehci_common_init(ctrl, tweaks); + if (ret) + goto err; +done: + return 0; +err: + free(ctrl); + debug("%s: failed, ret=%d\n", __func__, ret); + return ret; +} + +int ehci_deregister(struct udevice *dev) +{ + struct ehci_ctrl *ctrl = dev_get_priv(dev); + + ehci_shutdown(ctrl); + + return 0; +} + +struct dm_usb_ops ehci_usb_ops = { + .control = ehci_submit_control_msg, + .bulk = ehci_submit_bulk_msg, + .interrupt = ehci_submit_int_msg, +}; + +#endif diff --git a/drivers/usb/host/ehci-mx5.c b/drivers/usb/host/ehci-mx5.c index 7566c61..d319962 100644 --- a/drivers/usb/host/ehci-mx5.c +++ b/drivers/usb/host/ehci-mx5.c @@ -218,11 +218,23 @@ void __weak board_ehci_hcd_postinit(struct usb_ehci *ehci, int port) { } +__weak void mx5_ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg, + uint32_t *reg) +{ + mdelay(50); +} + +static const struct ehci_ops mx5_ehci_ops = { + .powerup_fixup = mx5_ehci_powerup_fixup, +}; + int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { struct usb_ehci *ehci; + /* The only user for this is efikamx-usb */ + ehci_set_controller_priv(index, NULL, &mx5_ehci_ops); set_usboh3_clk(); enable_usboh3_clk(true); set_usb_phy_clk(); diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index c6bfbe3..27705d6 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -7,6 +7,7 @@ */ #include <common.h> +#include <dm.h> #include <asm/errno.h> #include <asm/io.h> #include <asm-generic/gpio.h> @@ -20,6 +21,8 @@ #include "ehci.h" +DECLARE_GLOBAL_DATA_PTR; + #define USB1_ADDR_MASK 0xFFFF0000 #define HOSTPC1_DEVLC 0x84 @@ -32,9 +35,11 @@ #endif #endif +#ifndef CONFIG_DM_USB enum { USB_PORTS_MAX = 3, /* Maximum ports we allow */ }; +#endif /* Parameters we need for USB */ enum { @@ -61,14 +66,26 @@ enum dr_mode { DR_MODE_OTG, /* supports both */ }; +enum usb_ctlr_type { + USB_CTLR_T20, + USB_CTLR_T30, + USB_CTLR_T114, + + USB_CTRL_COUNT, +}; + /* Information about a USB port */ struct fdt_usb { + struct ehci_ctrl ehci; struct usb_ctlr *reg; /* address of registers in physical memory */ unsigned utmi:1; /* 1 if port has external tranceiver, else 0 */ unsigned ulpi:1; /* 1 if port has external ULPI transceiver */ unsigned enabled:1; /* 1 to enable, 0 to disable */ unsigned has_legacy_mode:1; /* 1 if this port has legacy mode */ +#ifndef CONFIG_DM_USB unsigned initialized:1; /* has this port already been initialized? */ +#endif + enum usb_ctlr_type type; enum usb_init_type init_type; enum dr_mode dr_mode; /* dual role mode */ enum periph_id periph_id;/* peripheral id */ @@ -76,10 +93,10 @@ struct fdt_usb { struct gpio_desc phy_reset_gpio; /* GPIO to reset ULPI phy */ }; +#ifndef CONFIG_DM_USB static struct fdt_usb port[USB_PORTS_MAX]; /* List of valid USB ports */ static unsigned port_count; /* Number of available ports */ -/* Port that needs to clear CSC after Port Reset */ -static u32 port_addr_clear_csc; +#endif /* * This table has USB timing parameters for each Oscillator frequency we @@ -156,13 +173,14 @@ static const u8 utmip_elastic_limit = 16; static const u8 utmip_hs_sync_start_delay = 9; struct fdt_usb_controller { + /* TODO(sjg@chromium.org): Remove when we only use driver model */ int compat; /* flag to determine whether controller supports hostpc register */ u32 has_hostpc:1; const unsigned *pll_parameter; }; -static struct fdt_usb_controller fdt_usb_controllers[] = { +static struct fdt_usb_controller fdt_usb_controllers[USB_CTRL_COUNT] = { { .compat = COMPAT_NVIDIA_TEGRA20_USB, .has_hostpc = 0, @@ -180,40 +198,36 @@ static struct fdt_usb_controller fdt_usb_controllers[] = { }, }; -static struct fdt_usb_controller *controller; - /* * A known hardware issue where Connect Status Change bit of PORTSC register * of USB1 controller will be set after Port Reset. * We have to clear it in order for later device enumeration to proceed. - * This ehci_powerup_fixup overrides the weak function ehci_powerup_fixup - * in "ehci-hcd.c". */ -void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg) +static void tegra_ehci_powerup_fixup(struct ehci_ctrl *ctrl, + uint32_t *status_reg, uint32_t *reg) { + struct fdt_usb *config = ctrl->priv; + struct fdt_usb_controller *controller; + + controller = &fdt_usb_controllers[config->type]; mdelay(50); /* This is to avoid PORT_ENABLE bit to be cleared in "ehci-hcd.c". */ if (controller->has_hostpc) *reg |= EHCI_PS_PE; - if (((unsigned long)status_reg & TEGRA_USB_ADDR_MASK) != port_addr_clear_csc) + if (!config->has_legacy_mode) return; /* For EHCI_PS_CSC to be cleared in ehci_hcd.c */ if (ehci_readl(status_reg) & EHCI_PS_CSC) *reg |= EHCI_PS_CSC; } -/* - * This ehci_set_usbmode overrides the weak function ehci_set_usbmode - * in "ehci-hcd.c". - */ -void ehci_set_usbmode(int index) +static void tegra_ehci_set_usbmode(struct ehci_ctrl *ctrl) { - struct fdt_usb *config; + struct fdt_usb *config = ctrl->priv; struct usb_ctlr *usbctlr; uint32_t tmp; - config = &port[index]; usbctlr = config->reg; tmp = ehci_readl(&usbctlr->usb_mode); @@ -221,17 +235,17 @@ void ehci_set_usbmode(int index) ehci_writel(&usbctlr->usb_mode, tmp); } -/* - * This ehci_get_port_speed overrides the weak function ehci_get_port_speed - * in "ehci-hcd.c". - */ -int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg) +static int tegra_ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg) { + struct fdt_usb *config = ctrl->priv; + struct fdt_usb_controller *controller; uint32_t tmp; uint32_t *reg_ptr; + controller = &fdt_usb_controllers[config->type]; if (controller->has_hostpc) { - reg_ptr = (uint32_t *)((u8 *)&hcor->or_usbcmd + HOSTPC1_DEVLC); + reg_ptr = (uint32_t *)((u8 *)&ctrl->hcor->or_usbcmd + + HOSTPC1_DEVLC); tmp = ehci_readl(reg_ptr); return HOSTPC1_PSPD(tmp); } else @@ -263,7 +277,8 @@ static void set_up_vbus(struct fdt_usb *config, enum usb_init_type init) } } -void usbf_reset_controller(struct fdt_usb *config, struct usb_ctlr *usbctlr) +static void usbf_reset_controller(struct fdt_usb *config, + struct usb_ctlr *usbctlr) { /* Reset the USB controller with 2us delay */ reset_periph(config->periph_id, 2); @@ -283,7 +298,7 @@ void usbf_reset_controller(struct fdt_usb *config, struct usb_ctlr *usbctlr) setbits_le32(&usbctlr->susp_ctrl, UTMIP_PHY_ENB); } -static const unsigned *get_pll_timing(void) +static const unsigned *get_pll_timing(struct fdt_usb_controller *controller) { const unsigned *timing; @@ -330,6 +345,7 @@ static void init_phy_mux(struct fdt_usb *config, uint pts, static int init_utmi_usb_controller(struct fdt_usb *config, enum usb_init_type init) { + struct fdt_usb_controller *controller; u32 b_sess_valid_mask, val; int loop_count; const unsigned *timing; @@ -362,11 +378,14 @@ static int init_utmi_usb_controller(struct fdt_usb *config, VBUS_SENSE_CTL_MASK, VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT); + controller = &fdt_usb_controllers[config->type]; + debug("controller=%p, type=%d\n", controller, config->type); + /* * PLL Delay CONFIGURATION settings. The following parameters control * the bring up of the plls. */ - timing = get_pll_timing(); + timing = get_pll_timing(controller); if (!controller->has_hostpc) { val = readl(&usbctlr->utmip_misc_cfg1); @@ -517,7 +536,7 @@ static int init_utmi_usb_controller(struct fdt_usb *config, udelay(1); } if (!loop_count) - return -1; + return -ETIMEDOUT; /* Disable ICUSB FS/LS transceiver */ clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1); @@ -560,6 +579,7 @@ static int init_ulpi_usb_controller(struct fdt_usb *config, int loop_count; struct ulpi_viewport ulpi_vp; struct usb_ctlr *usbctlr = config->reg; + int ret; /* set up ULPI reference clock on pllp_out4 */ clock_enable(PERIPH_ID_DEV2_OUT); @@ -605,9 +625,10 @@ static int init_ulpi_usb_controller(struct fdt_usb *config, ulpi_vp.port_num = 0; ulpi_vp.viewport_addr = (u32)&usbctlr->ulpi_viewport; - if (ulpi_init(&ulpi_vp)) { + ret = ulpi_init(&ulpi_vp); + if (ret) { printf("Tegra ULPI viewport init failed\n"); - return -1; + return ret; } ulpi_set_vbus(&ulpi_vp, 1, 1); @@ -624,7 +645,7 @@ static int init_ulpi_usb_controller(struct fdt_usb *config, udelay(1); } if (!loop_count) - return -1; + return -ETIMEDOUT; clrbits_le32(&usbctlr->susp_ctrl, USB_SUSP_CLR); return 0; @@ -635,7 +656,7 @@ static int init_ulpi_usb_controller(struct fdt_usb *config, { printf("No code to set up ULPI controller, please enable" "CONFIG_USB_ULPI and CONFIG_USB_ULPI_VIEWPORT"); - return -1; + return -ENOSYS; } #endif @@ -662,7 +683,7 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config) else { debug("%s: Cannot decode dr_mode '%s'\n", __func__, mode); - return -FDT_ERR_NOTFOUND; + return -EINVAL; } } else { config->dr_mode = DR_MODE_HOST; @@ -674,12 +695,10 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config) config->enabled = fdtdec_get_is_enabled(blob, node); config->has_legacy_mode = fdtdec_get_bool(blob, node, "nvidia,has-legacy-mode"); - if (config->has_legacy_mode) - port_addr_clear_csc = (unsigned long)config->reg; config->periph_id = clock_decode_periph_id(blob, node); if (config->periph_id == PERIPH_ID_NONE) { debug("%s: Missing/invalid peripheral ID\n", __func__); - return -FDT_ERR_NOTFOUND; + return -EINVAL; } gpio_request_by_name_nodev(blob, node, "nvidia,vbus-gpio", 0, &config->vbus_gpio, GPIOD_IS_OUT); @@ -695,16 +714,101 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config) return 0; } +int usb_common_init(struct fdt_usb *config, enum usb_init_type init) +{ + int ret = 0; + + switch (init) { + case USB_INIT_HOST: + switch (config->dr_mode) { + case DR_MODE_HOST: + case DR_MODE_OTG: + break; + default: + printf("tegrausb: Invalid dr_mode %d for host mode\n", + config->dr_mode); + return -1; + } + break; + case USB_INIT_DEVICE: + if (config->periph_id != PERIPH_ID_USBD) { + printf("tegrausb: Device mode only supported on first USB controller\n"); + return -1; + } + if (!config->utmi) { + printf("tegrausb: Device mode only supported with UTMI PHY\n"); + return -1; + } + switch (config->dr_mode) { + case DR_MODE_DEVICE: + case DR_MODE_OTG: + break; + default: + printf("tegrausb: Invalid dr_mode %d for device mode\n", + config->dr_mode); + return -1; + } + break; + default: + printf("tegrausb: Unknown USB_INIT_* %d\n", init); + return -1; + } + +#ifndef CONFIG_DM_USB + /* skip init, if the port is already initialized */ + if (config->initialized && config->init_type == init) + return 0; +#endif + + debug("%d, %d\n", config->utmi, config->ulpi); + if (config->utmi) + ret = init_utmi_usb_controller(config, init); + else if (config->ulpi) + ret = init_ulpi_usb_controller(config, init); + if (ret) + return ret; + + set_up_vbus(config, init); + + config->init_type = init; + + return 0; +} + +void usb_common_uninit(struct fdt_usb *priv) +{ + struct usb_ctlr *usbctlr; + + usbctlr = priv->reg; + + /* Stop controller */ + writel(0, &usbctlr->usb_cmd); + udelay(1000); + + /* Initiate controller reset */ + writel(2, &usbctlr->usb_cmd); + udelay(1000); +} + +static const struct ehci_ops tegra_ehci_ops = { + .set_usb_mode = tegra_ehci_set_usbmode, + .get_port_speed = tegra_ehci_get_port_speed, + .powerup_fixup = tegra_ehci_powerup_fixup, +}; + +#ifndef CONFIG_DM_USB /* * process_usb_nodes() - Process a list of USB nodes, adding them to our list * of USB ports. * @blob: fdt blob * @node_list: list of nodes to process (any <=0 are ignored) * @count: number of nodes to process + * @id: controller type (enum usb_ctlr_type) * * Return: 0 - ok, -1 - error */ -static int process_usb_nodes(const void *blob, int node_list[], int count) +static int process_usb_nodes(const void *blob, int node_list[], int count, + enum usb_ctlr_type id) { struct fdt_usb config; int node, i; @@ -728,9 +832,11 @@ static int process_usb_nodes(const void *blob, int node_list[], int count) return -1; } if (!clk_done) { - config_clock(get_pll_timing()); + config_clock(get_pll_timing( + &fdt_usb_controllers[id])); clk_done = 1; } + config.type = id; config.initialized = 0; /* add new USB port to the list of available ports */ @@ -747,20 +853,17 @@ int usb_process_devicetree(const void *blob) int i; for (i = 0; i < ARRAY_SIZE(fdt_usb_controllers); i++) { - controller = &fdt_usb_controllers[i]; - count = fdtdec_find_aliases_for_id(blob, "usb", - controller->compat, node_list, USB_PORTS_MAX); + fdt_usb_controllers[i].compat, node_list, + USB_PORTS_MAX); if (count) { - err = process_usb_nodes(blob, node_list, count); + err = process_usb_nodes(blob, node_list, count, i); if (err) printf("%s: Error processing USB node!\n", __func__); return err; } } - if (i == ARRAY_SIZE(fdt_usb_controllers)) - controller = NULL; return err; } @@ -780,68 +883,22 @@ int ehci_hcd_init(int index, enum usb_init_type init, { struct fdt_usb *config; struct usb_ctlr *usbctlr; + int ret; if (index >= port_count) return -1; config = &port[index]; + ehci_set_controller_priv(index, config, &tegra_ehci_ops); - switch (init) { - case USB_INIT_HOST: - switch (config->dr_mode) { - case DR_MODE_HOST: - case DR_MODE_OTG: - break; - default: - printf("tegrausb: Invalid dr_mode %d for host mode\n", - config->dr_mode); - return -1; - } - break; - case USB_INIT_DEVICE: - if (config->periph_id != PERIPH_ID_USBD) { - printf("tegrausb: Device mode only supported on first USB controller\n"); - return -1; - } - if (!config->utmi) { - printf("tegrausb: Device mode only supported with UTMI PHY\n"); - return -1; - } - switch (config->dr_mode) { - case DR_MODE_DEVICE: - case DR_MODE_OTG: - break; - default: - printf("tegrausb: Invalid dr_mode %d for device mode\n", - config->dr_mode); - return -1; - } - break; - default: - printf("tegrausb: Unknown USB_INIT_* %d\n", init); - return -1; - } - - /* skip init, if the port is already initialized */ - if (config->initialized && config->init_type == init) - goto success; - - if (config->utmi && init_utmi_usb_controller(config, init)) { - printf("tegrausb: Cannot init port %d\n", index); - return -1; - } - - if (config->ulpi && init_ulpi_usb_controller(config, init)) { + ret = usb_common_init(config, init); + if (ret) { printf("tegrausb: Cannot init port %d\n", index); - return -1; + return ret; } - set_up_vbus(config, init); - config->initialized = 1; - config->init_type = init; -success: usbctlr = config->reg; *hccr = (struct ehci_hccr *)&usbctlr->cap_length; *hcor = (struct ehci_hcor *)&usbctlr->usb_cmd; @@ -854,19 +911,80 @@ success: */ int ehci_hcd_stop(int index) { - struct usb_ctlr *usbctlr; + usb_common_uninit(&port[index]); - usbctlr = port[index].reg; + port[index].initialized = 0; - /* Stop controller */ - writel(0, &usbctlr->usb_cmd); - udelay(1000); + return 0; +} +#endif /* !CONFIG_DM_USB */ - /* Initiate controller reset */ - writel(2, &usbctlr->usb_cmd); - udelay(1000); +#ifdef CONFIG_DM_USB +static int ehci_usb_ofdata_to_platdata(struct udevice *dev) +{ + struct fdt_usb *priv = dev_get_priv(dev); + int ret; - port[index].initialized = 0; + ret = fdt_decode_usb(gd->fdt_blob, dev->of_offset, priv); + if (ret) + return ret; + + priv->type = dev_get_driver_data(dev); + + return 0; +} + +static int ehci_usb_probe(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + struct fdt_usb *priv = dev_get_priv(dev); + struct ehci_hccr *hccr; + struct ehci_hcor *hcor; + static bool clk_done; + int ret; + + ret = usb_common_init(priv, plat->init_type); + if (ret) + return ret; + hccr = (struct ehci_hccr *)&priv->reg->cap_length; + hcor = (struct ehci_hcor *)&priv->reg->usb_cmd; + if (!clk_done) { + config_clock(get_pll_timing(&fdt_usb_controllers[priv->type])); + clk_done = true; + } + + return ehci_register(dev, hccr, hcor, &tegra_ehci_ops, 0, + plat->init_type); +} + +static int ehci_usb_remove(struct udevice *dev) +{ + int ret; + + ret = ehci_deregister(dev); + if (ret) + return ret; return 0; } + +static const struct udevice_id ehci_usb_ids[] = { + { .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 }, + { .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 }, + { .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 }, + { } +}; + +U_BOOT_DRIVER(usb_ehci) = { + .name = "ehci_tegra", + .id = UCLASS_USB, + .of_match = ehci_usb_ids, + .ofdata_to_platdata = ehci_usb_ofdata_to_platdata, + .probe = ehci_usb_probe, + .remove = ehci_usb_remove, + .ops = &ehci_usb_ops, + .platdata_auto_alloc_size = sizeof(struct usb_platdata), + .priv_auto_alloc_size = sizeof(struct fdt_usb), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c new file mode 100644 index 0000000..5454855 --- /dev/null +++ b/drivers/usb/host/ehci-vf.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2015 Sanchayan Maity <sanchayan.maity@toradex.com> + * Copyright (C) 2015 Toradex AG + * + * Based on ehci-mx6 driver + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <usb.h> +#include <errno.h> +#include <linux/compiler.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/crm_regs.h> +#include <asm/imx-common/iomux-v3.h> +#include <asm/imx-common/regs-usbphy.h> +#include <usb/ehci-fsl.h> + +#include "ehci.h" + +#define USB_NC_REG_OFFSET 0x00000800 + +#define ANADIG_PLL_CTRL_EN_USB_CLKS (1 << 6) + +#define UCTRL_OVER_CUR_POL (1 << 8) /* OTG Polarity of Overcurrent */ +#define UCTRL_OVER_CUR_DIS (1 << 7) /* Disable OTG Overcurrent Detection */ + +/* USBCMD */ +#define UCMD_RUN_STOP (1 << 0) /* controller run/stop */ +#define UCMD_RESET (1 << 1) /* controller reset */ + +static const unsigned phy_bases[] = { + USB_PHY0_BASE_ADDR, + USB_PHY1_BASE_ADDR, +}; + +static const unsigned nc_reg_bases[] = { + USBC0_BASE_ADDR, + USBC1_BASE_ADDR, +}; + +static void usb_internal_phy_clock_gate(int index) +{ + void __iomem *phy_reg; + + phy_reg = (void __iomem *)phy_bases[index]; + clrbits_le32(phy_reg + USBPHY_CTRL, USBPHY_CTRL_CLKGATE); +} + +static void usb_power_config(int index) +{ + struct anadig_reg __iomem *anadig = + (struct anadig_reg __iomem *)ANADIG_BASE_ADDR; + void __iomem *pll_ctrl; + + switch (index) { + case 0: + pll_ctrl = &anadig->pll3_ctrl; + clrbits_le32(pll_ctrl, ANADIG_PLL3_CTRL_BYPASS); + setbits_le32(pll_ctrl, ANADIG_PLL3_CTRL_ENABLE + | ANADIG_PLL3_CTRL_POWERDOWN + | ANADIG_PLL_CTRL_EN_USB_CLKS); + break; + case 1: + pll_ctrl = &anadig->pll7_ctrl; + clrbits_le32(pll_ctrl, ANADIG_PLL7_CTRL_BYPASS); + setbits_le32(pll_ctrl, ANADIG_PLL7_CTRL_ENABLE + | ANADIG_PLL7_CTRL_POWERDOWN + | ANADIG_PLL_CTRL_EN_USB_CLKS); + break; + default: + return; + } +} + +static void usb_phy_enable(int index, struct usb_ehci *ehci) +{ + void __iomem *phy_reg; + void __iomem *phy_ctrl; + void __iomem *usb_cmd; + + phy_reg = (void __iomem *)phy_bases[index]; + phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL); + usb_cmd = (void __iomem *)&ehci->usbcmd; + + /* Stop then Reset */ + clrbits_le32(usb_cmd, UCMD_RUN_STOP); + while (readl(usb_cmd) & UCMD_RUN_STOP) + ; + + setbits_le32(usb_cmd, UCMD_RESET); + while (readl(usb_cmd) & UCMD_RESET) + ; + + /* Reset USBPHY module */ + setbits_le32(phy_ctrl, USBPHY_CTRL_SFTRST); + udelay(10); + + /* Remove CLKGATE and SFTRST */ + clrbits_le32(phy_ctrl, USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST); + udelay(10); + + /* Power up the PHY */ + writel(0, phy_reg + USBPHY_PWD); + + /* Enable FS/LS device */ + setbits_le32(phy_ctrl, USBPHY_CTRL_ENUTMILEVEL2 | + USBPHY_CTRL_ENUTMILEVEL3); +} + +static void usb_oc_config(int index) +{ + void __iomem *ctrl; + + ctrl = (void __iomem *)(nc_reg_bases[index] + USB_NC_REG_OFFSET); + + setbits_le32(ctrl, UCTRL_OVER_CUR_POL); + setbits_le32(ctrl, UCTRL_OVER_CUR_DIS); +} + +int ehci_hcd_init(int index, enum usb_init_type init, + struct ehci_hccr **hccr, struct ehci_hcor **hcor) +{ + struct usb_ehci *ehci; + + if (index >= ARRAY_SIZE(nc_reg_bases)) + return -EINVAL; + + if (init == USB_INIT_DEVICE && index == 1) + return -ENODEV; + if (init == USB_INIT_HOST && index == 0) + return -ENODEV; + + ehci = (struct usb_ehci *)nc_reg_bases[index]; + + usb_power_config(index); + usb_oc_config(index); + usb_internal_phy_clock_gate(index); + usb_phy_enable(index, ehci); + + *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); + *hcor = (struct ehci_hcor *)((uint32_t)*hccr + + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); + + if (init == USB_INIT_DEVICE) { + setbits_le32(&ehci->usbmode, CM_DEVICE); + writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc); + setbits_le32(&ehci->portsc, USB_EN); + } else if (init == USB_INIT_HOST) { + setbits_le32(&ehci->usbmode, CM_HOST); + writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc); + setbits_le32(&ehci->portsc, USB_EN); + } + + return 0; +} + +int ehci_hcd_stop(int index) +{ + return 0; +} diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 79aecd4..774282d 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -238,6 +238,22 @@ struct QH { }; }; +/* Tweak flags for EHCI, used to control operation */ +enum { + /* don't use or_configflag in init */ + EHCI_TWEAK_NO_INIT_CF = 1 << 0, +}; + +struct ehci_ctrl; + +struct ehci_ops { + void (*set_usb_mode)(struct ehci_ctrl *ctrl); + int (*get_port_speed)(struct ehci_ctrl *ctrl, uint32_t reg); + void (*powerup_fixup)(struct ehci_ctrl *ctrl, uint32_t *status_reg, + uint32_t *reg); + uint32_t *(*get_portsc_register)(struct ehci_ctrl *ctrl, int port); +}; + struct ehci_ctrl { struct ehci_hccr *hccr; /* R/O registers, not need for volatile */ struct ehci_hcor *hcor; @@ -248,11 +264,42 @@ struct ehci_ctrl { uint32_t *periodic_list; int periodic_schedules; int ntds; + struct ehci_ops ops; + void *priv; /* client's private data */ }; +/** + * ehci_set_controller_info() - Set up private data for the controller + * + * This function can be called in ehci_hcd_init() to tell the EHCI layer + * about the controller's private data pointer. Then in the above functions + * this can be accessed given the struct ehci_ctrl pointer. Also special + * EHCI operation methods can be provided if required + * + * @index: Controller number to set + * @priv: Controller pointer + * @ops: Controller operations, or NULL to use default + */ +void ehci_set_controller_priv(int index, void *priv, + const struct ehci_ops *ops); + +/** + * ehci_get_controller_priv() - Get controller private data + * + * @index Controller number to get + * @return controller pointer for this index + */ +void *ehci_get_controller_priv(int index); + /* Low level init functions */ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, struct ehci_hcor **hcor); int ehci_hcd_stop(int index); +int ehci_register(struct udevice *dev, struct ehci_hccr *hccr, + struct ehci_hcor *hcor, const struct ehci_ops *ops, + uint tweaks, enum usb_init_type init); +int ehci_deregister(struct udevice *dev); +extern struct dm_usb_ops ehci_usb_ops; + #endif /* USB_EHCI_H */ diff --git a/drivers/usb/host/usb-sandbox.c b/drivers/usb/host/usb-sandbox.c new file mode 100644 index 0000000..c5f9822 --- /dev/null +++ b/drivers/usb/host/usb-sandbox.c @@ -0,0 +1,117 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <usb.h> +#include <dm/root.h> + +DECLARE_GLOBAL_DATA_PTR; + +static void usbmon_trace(struct udevice *bus, ulong pipe, + struct devrequest *setup, struct udevice *emul) +{ + static const char types[] = "ZICB"; + int type; + + type = (pipe & USB_PIPE_TYPE_MASK) >> USB_PIPE_TYPE_SHIFT; + debug("0 0 S %c%c:%d:%03ld:%ld", types[type], + pipe & USB_DIR_IN ? 'i' : 'o', + bus->seq, + (pipe & USB_PIPE_DEV_MASK) >> USB_PIPE_DEV_SHIFT, + (pipe & USB_PIPE_EP_MASK) >> USB_PIPE_EP_SHIFT); + if (setup) { + debug(" s %02x %02x %04x %04x %04x", setup->requesttype, + setup->request, setup->value, setup->index, + setup->length); + } + debug(" %s", emul ? emul->name : "(no emul found)"); + + debug("\n"); +} + +static int sandbox_submit_control(struct udevice *bus, + struct usb_device *udev, + unsigned long pipe, + void *buffer, int length, + struct devrequest *setup) +{ + struct udevice *emul; + int ret; + + /* Just use child of dev as emulator? */ + debug("%s: bus=%s\n", __func__, bus->name); + ret = usb_emul_find(bus, pipe, &emul); + usbmon_trace(bus, pipe, setup, emul); + if (ret) + return ret; + ret = usb_emul_control(emul, udev, pipe, buffer, length, setup); + if (ret < 0) { + debug("ret=%d\n", ret); + udev->status = ret; + udev->act_len = 0; + } else { + udev->status = 0; + udev->act_len = ret; + } + + return ret; +} + +static int sandbox_submit_bulk(struct udevice *bus, struct usb_device *udev, + unsigned long pipe, void *buffer, int length) +{ + struct udevice *emul; + int ret; + + /* Just use child of dev as emulator? */ + debug("%s: bus=%s\n", __func__, bus->name); + ret = usb_emul_find(bus, pipe, &emul); + usbmon_trace(bus, pipe, NULL, emul); + if (ret) + return ret; + ret = usb_emul_bulk(emul, udev, pipe, buffer, length); + if (ret < 0) { + debug("ret=%d\n", ret); + udev->status = ret; + udev->act_len = 0; + } else { + udev->status = 0; + udev->act_len = ret; + } + + return ret; +} + +static int sandbox_alloc_device(struct udevice *dev, struct usb_device *udev) +{ + return 0; +} + +static int sandbox_usb_probe(struct udevice *dev) +{ + return 0; +} + +static const struct dm_usb_ops sandbox_usb_ops = { + .control = sandbox_submit_control, + .bulk = sandbox_submit_bulk, + .alloc_device = sandbox_alloc_device, +}; + +static const struct udevice_id sandbox_usb_ids[] = { + { .compatible = "sandbox,usb" }, + { } +}; + +U_BOOT_DRIVER(usb_sandbox) = { + .name = "usb_sandbox", + .id = UCLASS_USB, + .of_match = sandbox_usb_ids, + .probe = sandbox_usb_probe, + .ops = &sandbox_usb_ops, +}; diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c new file mode 100644 index 0000000..714bc0e --- /dev/null +++ b/drivers/usb/host/usb-uclass.c @@ -0,0 +1,645 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * usb_match_device() modified from Linux kernel v4.0. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <usb.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dm/root.h> +#include <dm/uclass-internal.h> + +DECLARE_GLOBAL_DATA_PTR; + +extern bool usb_started; /* flag for the started/stopped USB status */ +static bool asynch_allowed; + +int usb_disable_asynch(int disable) +{ + int old_value = asynch_allowed; + + asynch_allowed = !disable; + return old_value; +} + +int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer, + int length, int interval) +{ + struct udevice *bus = udev->controller_dev; + struct dm_usb_ops *ops = usb_get_ops(bus); + + if (!ops->interrupt) + return -ENOSYS; + + return ops->interrupt(bus, udev, pipe, buffer, length, interval); +} + +int submit_control_msg(struct usb_device *udev, unsigned long pipe, + void *buffer, int length, struct devrequest *setup) +{ + struct udevice *bus = udev->controller_dev; + struct dm_usb_ops *ops = usb_get_ops(bus); + + if (!ops->control) + return -ENOSYS; + + return ops->control(bus, udev, pipe, buffer, length, setup); +} + +int submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer, + int length) +{ + struct udevice *bus = udev->controller_dev; + struct dm_usb_ops *ops = usb_get_ops(bus); + + if (!ops->bulk) + return -ENOSYS; + + return ops->bulk(bus, udev, pipe, buffer, length); +} + +int usb_alloc_device(struct usb_device *udev) +{ + struct udevice *bus = udev->controller_dev; + struct dm_usb_ops *ops = usb_get_ops(bus); + + /* This is only requird by some controllers - current XHCI */ + if (!ops->alloc_device) + return 0; + + return ops->alloc_device(bus, udev); +} + +int usb_stop(void) +{ + struct udevice *bus; + struct uclass *uc; + int err = 0, ret; + + /* De-activate any devices that have been activated */ + ret = uclass_get(UCLASS_USB, &uc); + if (ret) + return ret; + uclass_foreach_dev(bus, uc) { + ret = device_remove(bus); + if (ret && !err) + err = ret; + } + +#ifdef CONFIG_SANDBOX + struct udevice *dev; + + /* Reset all enulation devices */ + ret = uclass_get(UCLASS_USB_EMUL, &uc); + if (ret) + return ret; + + uclass_foreach_dev(dev, uc) + usb_emul_reset(dev); +#endif + usb_stor_reset(); + usb_hub_reset(); + usb_started = 0; + + return err; +} + +static int usb_scan_bus(struct udevice *bus, bool recurse) +{ + struct usb_bus_priv *priv; + struct udevice *dev; + int ret; + + priv = dev_get_uclass_priv(bus); + + assert(recurse); /* TODO: Support non-recusive */ + + ret = usb_scan_device(bus, 0, USB_SPEED_FULL, &dev); + if (ret) + return ret; + + return priv->next_addr; +} + +int usb_init(void) +{ + int controllers_initialized = 0; + struct udevice *bus; + struct uclass *uc; + int count = 0; + int ret; + + asynch_allowed = 1; + usb_hub_reset(); + + ret = uclass_get(UCLASS_USB, &uc); + if (ret) + return ret; + + uclass_foreach_dev(bus, uc) { + /* init low_level USB */ + count++; + printf("USB"); + printf("%d: ", bus->seq); + ret = device_probe(bus); + if (ret == -ENODEV) { /* No such device. */ + puts("Port not available.\n"); + controllers_initialized++; + continue; + } + + if (ret) { /* Other error. */ + printf("probe failed, error %d\n", ret); + continue; + } + /* + * lowlevel init is OK, now scan the bus for devices + * i.e. search HUBs and configure them + */ + controllers_initialized++; + printf("scanning bus %d for devices... ", bus->seq); + debug("\n"); + ret = usb_scan_bus(bus, true); + if (ret < 0) + printf("failed, error %d\n", ret); + else if (!ret) + printf("No USB Device found\n"); + else + printf("%d USB Device(s) found\n", ret); + usb_started = true; + } + + debug("scan end\n"); + /* if we were not able to find at least one working bus, bail out */ + if (!count) + printf("No controllers found\n"); + else if (controllers_initialized == 0) + printf("USB error: all controllers failed lowlevel init\n"); + + return usb_started ? 0 : -1; +} + +int usb_reset_root_port(void) +{ + return -ENOSYS; +} + +static struct usb_device *find_child_devnum(struct udevice *parent, int devnum) +{ + struct usb_device *udev; + struct udevice *dev; + + if (!device_active(parent)) + return NULL; + udev = dev_get_parentdata(parent); + if (udev->devnum == devnum) + return udev; + + for (device_find_first_child(parent, &dev); + dev; + device_find_next_child(&dev)) { + udev = find_child_devnum(dev, devnum); + if (udev) + return udev; + } + + return NULL; +} + +struct usb_device *usb_get_dev_index(struct udevice *bus, int index) +{ + struct udevice *hub; + int devnum = index + 1; /* Addresses are allocated from 1 on USB */ + + device_find_first_child(bus, &hub); + if (device_get_uclass_id(hub) == UCLASS_USB_HUB) + return find_child_devnum(hub, devnum); + + return NULL; +} + +int usb_post_bind(struct udevice *dev) +{ + /* Scan the bus for devices */ + return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); +} + +int usb_port_reset(struct usb_device *parent, int portnr) +{ + unsigned short portstatus; + int ret; + + debug("%s: start\n", __func__); + + if (parent) { + /* reset the port for the second time */ + assert(portnr > 0); + debug("%s: reset %d\n", __func__, portnr - 1); + ret = legacy_hub_port_reset(parent, portnr - 1, &portstatus); + if (ret < 0) { + printf("\n Couldn't reset port %i\n", portnr); + return ret; + } + } else { + debug("%s: reset root\n", __func__); + usb_reset_root_port(); + } + + return 0; +} + +int usb_legacy_port_reset(struct usb_device *parent, int portnr) +{ + return usb_port_reset(parent, portnr); +} + +int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp) +{ + struct usb_platdata *plat; + struct udevice *dev; + int ret; + + /* Find the old device and remove it */ + ret = uclass_find_device_by_seq(UCLASS_USB, 0, true, &dev); + if (ret) + return ret; + ret = device_remove(dev); + if (ret) + return ret; + + plat = dev_get_platdata(dev); + plat->init_type = USB_INIT_DEVICE; + ret = device_probe(dev); + if (ret) + return ret; + *ctlrp = dev_get_priv(dev); + + return 0; +} + +/* returns 0 if no match, 1 if match */ +int usb_match_device(const struct usb_device_descriptor *desc, + const struct usb_device_id *id) +{ + if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && + id->idVendor != le16_to_cpu(desc->idVendor)) + return 0; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && + id->idProduct != le16_to_cpu(desc->idProduct)) + return 0; + + /* No need to test id->bcdDevice_lo != 0, since 0 is never + greater than any unsigned number. */ + if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) && + (id->bcdDevice_lo > le16_to_cpu(desc->bcdDevice))) + return 0; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) && + (id->bcdDevice_hi < le16_to_cpu(desc->bcdDevice))) + return 0; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) && + (id->bDeviceClass != desc->bDeviceClass)) + return 0; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && + (id->bDeviceSubClass != desc->bDeviceSubClass)) + return 0; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && + (id->bDeviceProtocol != desc->bDeviceProtocol)) + return 0; + + return 1; +} + +/* returns 0 if no match, 1 if match */ +int usb_match_one_id_intf(const struct usb_device_descriptor *desc, + const struct usb_interface_descriptor *int_desc, + const struct usb_device_id *id) +{ + /* The interface class, subclass, protocol and number should never be + * checked for a match if the device class is Vendor Specific, + * unless the match record specifies the Vendor ID. */ + if (desc->bDeviceClass == USB_CLASS_VENDOR_SPEC && + !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && + (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS | + USB_DEVICE_ID_MATCH_INT_PROTOCOL | + USB_DEVICE_ID_MATCH_INT_NUMBER))) + return 0; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && + (id->bInterfaceClass != int_desc->bInterfaceClass)) + return 0; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) && + (id->bInterfaceSubClass != int_desc->bInterfaceSubClass)) + return 0; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) && + (id->bInterfaceProtocol != int_desc->bInterfaceProtocol)) + return 0; + + if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) && + (id->bInterfaceNumber != int_desc->bInterfaceNumber)) + return 0; + + return 1; +} + +/* returns 0 if no match, 1 if match */ +int usb_match_one_id(struct usb_device_descriptor *desc, + struct usb_interface_descriptor *int_desc, + const struct usb_device_id *id) +{ + if (!usb_match_device(desc, id)) + return 0; + + return usb_match_one_id_intf(desc, int_desc, id); +} + +/** + * usb_find_and_bind_driver() - Find and bind the right USB driver + * + * This only looks at certain fields in the descriptor. + */ +static int usb_find_and_bind_driver(struct udevice *parent, + struct usb_device_descriptor *desc, + struct usb_interface_descriptor *iface, + int bus_seq, int devnum, + struct udevice **devp) +{ + struct usb_driver_entry *start, *entry; + int n_ents; + int ret; + char name[30], *str; + + *devp = NULL; + debug("%s: Searching for driver\n", __func__); + start = ll_entry_start(struct usb_driver_entry, usb_driver_entry); + n_ents = ll_entry_count(struct usb_driver_entry, usb_driver_entry); + for (entry = start; entry != start + n_ents; entry++) { + const struct usb_device_id *id; + struct udevice *dev; + const struct driver *drv; + struct usb_dev_platdata *plat; + + for (id = entry->match; id->match_flags; id++) { + if (!usb_match_one_id(desc, iface, id)) + continue; + + drv = entry->driver; + /* + * We could pass the descriptor to the driver as + * platdata (instead of NULL) and allow its bind() + * method to return -ENOENT if it doesn't support this + * device. That way we could continue the search to + * find another driver. For now this doesn't seem + * necesssary, so just bind the first match. + */ + ret = device_bind(parent, drv, drv->name, NULL, -1, + &dev); + if (ret) + goto error; + debug("%s: Match found: %s\n", __func__, drv->name); + dev->driver_data = id->driver_info; + plat = dev_get_parent_platdata(dev); + plat->id = *id; + *devp = dev; + return 0; + } + } + + /* Bind a generic driver so that the device can be used */ + snprintf(name, sizeof(name), "generic_bus_%x_dev_%x", bus_seq, devnum); + str = strdup(name); + if (!str) + return -ENOMEM; + ret = device_bind_driver(parent, "usb_dev_generic_drv", str, devp); + +error: + debug("%s: No match found: %d\n", __func__, ret); + return ret; +} + +/** + * usb_find_child() - Find an existing device which matches our needs + * + * + */ +static int usb_find_child(struct udevice *parent, + struct usb_device_descriptor *desc, + struct usb_interface_descriptor *iface, + struct udevice **devp) +{ + struct udevice *dev; + + *devp = NULL; + for (device_find_first_child(parent, &dev); + dev; + device_find_next_child(&dev)) { + struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); + + /* If this device is already in use, skip it */ + if (device_active(dev)) + continue; + debug(" %s: name='%s', plat=%d, desc=%d\n", __func__, + dev->name, plat->id.bDeviceClass, desc->bDeviceClass); + if (usb_match_one_id(desc, iface, &plat->id)) { + *devp = dev; + return 0; + } + } + + return -ENOENT; +} + +int usb_scan_device(struct udevice *parent, int port, + enum usb_device_speed speed, struct udevice **devp) +{ + struct udevice *dev; + bool created = false; + struct usb_dev_platdata *plat; + struct usb_bus_priv *priv; + struct usb_device *parent_udev; + int ret; + ALLOC_CACHE_ALIGN_BUFFER(struct usb_device, udev, 1); + struct usb_interface_descriptor *iface = &udev->config.if_desc[0].desc; + + *devp = NULL; + memset(udev, '\0', sizeof(*udev)); + ret = usb_get_bus(parent, &udev->controller_dev); + if (ret) + return ret; + priv = dev_get_uclass_priv(udev->controller_dev); + + /* + * Somewhat nasty, this. We create a local device and use the normal + * USB stack to read its descriptor. Then we know what type of device + * to create for real. + * + * udev->dev is set to the parent, since we don't have a real device + * yet. The USB stack should not access udev.dev anyway, except perhaps + * to find the controller, and the controller will either be @parent, + * or some parent of @parent. + * + * Another option might be to create the device as a generic USB + * device, then morph it into the correct one when we know what it + * should be. This means that a generic USB device would morph into + * a network controller, or a USB flash stick, for example. However, + * we don't support such morphing and it isn't clear that it would + * be easy to do. + * + * Yet another option is to split out the USB stack parts of udev + * into something like a 'struct urb' (as Linux does) which can exist + * independently of any device. This feels cleaner, but calls for quite + * a big change to the USB stack. + * + * For now, the approach is to set up an empty udev, read its + * descriptor and assign it an address, then bind a real device and + * stash the resulting information into the device's parent + * platform data. Then when we probe it, usb_child_pre_probe() is called + * and it will pull the information out of the stash. + */ + udev->dev = parent; + udev->speed = speed; + udev->devnum = priv->next_addr + 1; + udev->portnr = port; + debug("Calling usb_setup_device(), portnr=%d\n", udev->portnr); + parent_udev = device_get_uclass_id(parent) == UCLASS_USB_HUB ? + dev_get_parentdata(parent) : NULL; + ret = usb_setup_device(udev, priv->desc_before_addr, parent_udev, port); + debug("read_descriptor for '%s': ret=%d\n", parent->name, ret); + if (ret) + return ret; + ret = usb_find_child(parent, &udev->descriptor, iface, &dev); + debug("** usb_find_child returns %d\n", ret); + if (ret) { + if (ret != -ENOENT) + return ret; + ret = usb_find_and_bind_driver(parent, &udev->descriptor, iface, + udev->controller_dev->seq, + udev->devnum, &dev); + if (ret) + return ret; + created = true; + } + plat = dev_get_parent_platdata(dev); + debug("%s: Probing '%s', plat=%p\n", __func__, dev->name, plat); + plat->devnum = udev->devnum; + plat->speed = udev->speed; + plat->slot_id = udev->slot_id; + plat->portnr = port; + debug("** device '%s': stashing slot_id=%d\n", dev->name, + plat->slot_id); + priv->next_addr++; + ret = device_probe(dev); + if (ret) { + debug("%s: Device '%s' probe failed\n", __func__, dev->name); + priv->next_addr--; + if (created) + device_unbind(dev); + return ret; + } + *devp = dev; + + return 0; +} + +int usb_child_post_bind(struct udevice *dev) +{ + struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); + const void *blob = gd->fdt_blob; + int val; + + if (dev->of_offset == -1) + return 0; + + /* We only support matching a few things */ + val = fdtdec_get_int(blob, dev->of_offset, "usb,device-class", -1); + if (val != -1) { + plat->id.match_flags |= USB_DEVICE_ID_MATCH_DEV_CLASS; + plat->id.bDeviceClass = val; + } + val = fdtdec_get_int(blob, dev->of_offset, "usb,interface-class", -1); + if (val != -1) { + plat->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS; + plat->id.bInterfaceClass = val; + } + + return 0; +} + +int usb_get_bus(struct udevice *dev, struct udevice **busp) +{ + struct udevice *bus; + + *busp = NULL; + for (bus = dev; bus && device_get_uclass_id(bus) != UCLASS_USB; ) + bus = bus->parent; + if (!bus) { + /* By design this cannot happen */ + assert(bus); + debug("USB HUB '%s' does not have a controller\n", dev->name); + return -EXDEV; + } + *busp = bus; + + return 0; +} + +int usb_child_pre_probe(struct udevice *dev) +{ + struct udevice *bus; + struct usb_device *udev = dev_get_parentdata(dev); + struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); + int ret; + + ret = usb_get_bus(dev, &bus); + if (ret) + return ret; + udev->controller_dev = bus; + udev->dev = dev; + udev->devnum = plat->devnum; + udev->slot_id = plat->slot_id; + udev->portnr = plat->portnr; + udev->speed = plat->speed; + debug("** device '%s': getting slot_id=%d\n", dev->name, plat->slot_id); + + ret = usb_select_config(udev); + if (ret) + return ret; + + return 0; +} + +UCLASS_DRIVER(usb) = { + .id = UCLASS_USB, + .name = "usb", + .flags = DM_UC_FLAG_SEQ_ALIAS, + .post_bind = usb_post_bind, + .per_child_auto_alloc_size = sizeof(struct usb_device), + .per_device_auto_alloc_size = sizeof(struct usb_bus_priv), + .child_post_bind = usb_child_post_bind, + .child_pre_probe = usb_child_pre_probe, + .per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata), +}; + +UCLASS_DRIVER(usb_dev_generic) = { + .id = UCLASS_USB_DEV_GENERIC, + .name = "usb_dev_generic", +}; + +U_BOOT_DRIVER(usb_dev_generic_drv) = { + .id = UCLASS_USB_DEV_GENERIC, + .name = "usb_dev_generic_drv", +}; diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c index 3f86fdc..23c7ecc 100644 --- a/drivers/usb/host/xhci-exynos5.c +++ b/drivers/usb/host/xhci-exynos5.c @@ -14,6 +14,7 @@ */ #include <common.h> +#include <dm.h> #include <fdtdec.h> #include <libfdt.h> #include <malloc.h> @@ -32,20 +33,76 @@ /* Declare global data pointer */ DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_DM_USB +struct exynos_xhci_platdata { + fdt_addr_t hcd_base; + fdt_addr_t phy_base; + struct gpio_desc vbus_gpio; +}; +#endif + /** * Contains pointers to register base addresses * for the usb controller. */ struct exynos_xhci { +#ifdef CONFIG_DM_USB + struct usb_platdata usb_plat; +#endif + struct xhci_ctrl ctrl; struct exynos_usb3_phy *usb3_phy; struct xhci_hccr *hcd; struct dwc3 *dwc3_reg; +#ifndef CONFIG_DM_USB struct gpio_desc vbus_gpio; +#endif }; +#ifndef CONFIG_DM_USB static struct exynos_xhci exynos; +#endif -#ifdef CONFIG_OF_CONTROL +#ifdef CONFIG_DM_USB +static int xhci_usb_ofdata_to_platdata(struct udevice *dev) +{ + struct exynos_xhci_platdata *plat = dev_get_platdata(dev); + const void *blob = gd->fdt_blob; + unsigned int node; + int depth; + + /* + * Get the base address for XHCI controller from the device node + */ + plat->hcd_base = fdtdec_get_addr(blob, dev->of_offset, "reg"); + if (plat->hcd_base == FDT_ADDR_T_NONE) { + debug("Can't get the XHCI register base address\n"); + return -ENXIO; + } + + depth = 0; + node = fdtdec_next_compatible_subnode(blob, dev->of_offset, + COMPAT_SAMSUNG_EXYNOS5_USB3_PHY, &depth); + if (node <= 0) { + debug("XHCI: Can't get device node for usb3-phy controller\n"); + return -ENODEV; + } + + /* + * Get the base address for usbphy from the device node + */ + plat->phy_base = fdtdec_get_addr(blob, node, "reg"); + if (plat->phy_base == FDT_ADDR_T_NONE) { + debug("Can't get the usbphy register address\n"); + return -ENXIO; + } + + /* Vbus gpio */ + gpio_request_by_name(dev, "samsung,vbus-gpio", 0, + &plat->vbus_gpio, GPIOD_IS_OUT); + + return 0; +} +#else static int exynos_usb3_parse_dt(const void *blob, struct exynos_xhci *exynos) { fdt_addr_t addr; @@ -283,6 +340,7 @@ static void exynos_xhci_core_exit(struct exynos_xhci *exynos) exynos5_usb3_phy_exit(exynos->usb3_phy); } +#ifndef CONFIG_DM_USB int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor) { struct exynos_xhci *ctx = &exynos; @@ -326,3 +384,63 @@ void xhci_hcd_stop(int index) exynos_xhci_core_exit(ctx); } +#endif + +#ifdef CONFIG_DM_USB +static int xhci_usb_probe(struct udevice *dev) +{ + struct exynos_xhci_platdata *plat = dev_get_platdata(dev); + struct exynos_xhci *ctx = dev_get_priv(dev); + struct xhci_hcor *hcor; + int ret; + + ctx->hcd = (struct xhci_hccr *)plat->hcd_base; + ctx->usb3_phy = (struct exynos_usb3_phy *)plat->phy_base; + ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET); + hcor = (struct xhci_hcor *)((uint32_t)ctx->hcd + + HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase))); + + /* setup the Vbus gpio here */ + if (dm_gpio_is_valid(&plat->vbus_gpio)) + dm_gpio_set_value(&plat->vbus_gpio, 1); + + ret = exynos_xhci_core_init(ctx); + if (ret) { + puts("XHCI: failed to initialize controller\n"); + return -EINVAL; + } + + return xhci_register(dev, ctx->hcd, hcor); +} + +static int xhci_usb_remove(struct udevice *dev) +{ + struct exynos_xhci *ctx = dev_get_priv(dev); + int ret; + + ret = xhci_deregister(dev); + if (ret) + return ret; + exynos_xhci_core_exit(ctx); + + return 0; +} + +static const struct udevice_id xhci_usb_ids[] = { + { .compatible = "samsung,exynos5250-xhci" }, + { } +}; + +U_BOOT_DRIVER(usb_xhci) = { + .name = "xhci_exynos", + .id = UCLASS_USB, + .of_match = xhci_usb_ids, + .ofdata_to_platdata = xhci_usb_ofdata_to_platdata, + .probe = xhci_usb_probe, + .remove = xhci_usb_remove, + .ops = &xhci_usb_ops, + .platdata_auto_alloc_size = sizeof(struct exynos_xhci_platdata), + .priv_auto_alloc_size = sizeof(struct exynos_xhci), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 10f11cd..3744452 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -15,6 +15,7 @@ */ #include <common.h> +#include <dm.h> #include <asm/byteorder.h> #include <usb.h> #include <malloc.h> @@ -352,12 +353,10 @@ static struct xhci_container_ctx * @param udev pointer to USB deivce structure * @return 0 on success else -1 on failure */ -int xhci_alloc_virt_device(struct usb_device *udev) +int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id) { u64 byte_64 = 0; - unsigned int slot_id = udev->slot_id; struct xhci_virt_device *virt_dev; - struct xhci_ctrl *ctrl = udev->controller; /* Slot ID 0 is reserved */ if (ctrl->devs[slot_id]) { @@ -627,17 +626,16 @@ void xhci_slot_copy(struct xhci_ctrl *ctrl, struct xhci_container_ctx *in_ctx, * @param udev pointer to the Device Data Structure * @return returns negative value on failure else 0 on success */ -void xhci_setup_addressable_virt_dev(struct usb_device *udev) +void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id, + int speed, int hop_portnr) { - struct usb_device *hop = udev; struct xhci_virt_device *virt_dev; struct xhci_ep_ctx *ep0_ctx; struct xhci_slot_ctx *slot_ctx; u32 port_num = 0; u64 trb_64 = 0; - struct xhci_ctrl *ctrl = udev->controller; - virt_dev = ctrl->devs[udev->slot_id]; + virt_dev = ctrl->devs[slot_id]; BUG_ON(!virt_dev); @@ -648,7 +646,7 @@ void xhci_setup_addressable_virt_dev(struct usb_device *udev) /* Only the control endpoint is valid - one endpoint context */ slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | 0); - switch (udev->speed) { + switch (speed) { case USB_SPEED_SUPER: slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SS); break; @@ -666,11 +664,7 @@ void xhci_setup_addressable_virt_dev(struct usb_device *udev) BUG(); } - /* Extract the root hub port number */ - if (hop->parent) - while (hop->parent->parent) - hop = hop->parent; - port_num = hop->portnr; + port_num = hop_portnr; debug("port_num = %d\n", port_num); slot_ctx->dev_info2 |= @@ -680,9 +674,9 @@ void xhci_setup_addressable_virt_dev(struct usb_device *udev) /* Step 4 - ring already allocated */ /* Step 5 */ ep0_ctx->ep_info2 = cpu_to_le32(CTRL_EP << EP_TYPE_SHIFT); - debug("SPEED = %d\n", udev->speed); + debug("SPEED = %d\n", speed); - switch (udev->speed) { + switch (speed) { case USB_SPEED_SUPER: ep0_ctx->ep_info2 |= cpu_to_le32(((512 & MAX_PACKET_MASK) << MAX_PACKET_SHIFT)); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index f3759d4..5a1391f 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -353,7 +353,7 @@ static void giveback_first_trb(struct usb_device *udev, int ep_index, int start_cycle, struct xhci_generic_trb *start_trb) { - struct xhci_ctrl *ctrl = udev->controller; + struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); /* * Pass all the TRBs to the hardware at once and make sure this write @@ -477,7 +477,7 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected) */ static void abort_td(struct usb_device *udev, int ep_index) { - struct xhci_ctrl *ctrl = udev->controller; + struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); struct xhci_ring *ring = ctrl->devs[udev->slot_id]->eps[ep_index].ring; union xhci_trb *event; u32 field; @@ -554,7 +554,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, int start_cycle; u32 field = 0; u32 length_field = 0; - struct xhci_ctrl *ctrl = udev->controller; + struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); int slot_id = udev->slot_id; int ep_index; struct xhci_virt_device *virt_dev; @@ -748,7 +748,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, u32 length_field; u64 buf_64 = 0; struct xhci_generic_trb *start_trb; - struct xhci_ctrl *ctrl = udev->controller; + struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); int slot_id = udev->slot_id; int ep_index; u32 trb_fields[4]; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index f8b5ce4..0b09643 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -21,6 +21,7 @@ */ #include <common.h> +#include <dm.h> #include <asm/byteorder.h> #include <usb.h> #include <malloc.h> @@ -108,7 +109,25 @@ static struct descriptor { }, }; +#ifndef CONFIG_DM_USB static struct xhci_ctrl xhcic[CONFIG_USB_MAX_CONTROLLER_COUNT]; +#endif + +struct xhci_ctrl *xhci_get_ctrl(struct usb_device *udev) +{ +#ifdef CONFIG_DM_USB + struct udevice *dev; + + /* Find the USB controller */ + for (dev = udev->dev; + device_get_uclass_id(dev) != UCLASS_USB; + dev = dev->parent) + ; + return dev_get_priv(dev); +#else + return udev->controller; +#endif +} /** * Waits for as per specified amount of time @@ -250,7 +269,7 @@ static int xhci_configure_endpoints(struct usb_device *udev, bool ctx_change) { struct xhci_container_ctx *in_ctx; struct xhci_virt_device *virt_dev; - struct xhci_ctrl *ctrl = udev->controller; + struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); union xhci_trb *event; virt_dev = ctrl->devs[udev->slot_id]; @@ -298,7 +317,7 @@ static int xhci_set_configuration(struct usb_device *udev) int ep_index; unsigned int dir; unsigned int ep_type; - struct xhci_ctrl *ctrl = udev->controller; + struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); int num_of_ep; int ep_flag = 0; u64 trb_64 = 0; @@ -379,10 +398,10 @@ static int xhci_set_configuration(struct usb_device *udev) * @param udev pointer to the Device Data Structure * @return 0 if successful else error code on failure */ -static int xhci_address_device(struct usb_device *udev) +static int xhci_address_device(struct usb_device *udev, int root_portnr) { int ret = 0; - struct xhci_ctrl *ctrl = udev->controller; + struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); struct xhci_slot_ctx *slot_ctx; struct xhci_input_control_ctx *ctrl_ctx; struct xhci_virt_device *virt_dev; @@ -395,8 +414,9 @@ static int xhci_address_device(struct usb_device *udev) * This is the first Set Address since device plug-in * so setting up the slot context. */ - debug("Setting up addressable devices\n"); - xhci_setup_addressable_virt_dev(udev); + debug("Setting up addressable devices %p\n", ctrl->dcbaa); + xhci_setup_addressable_virt_dev(ctrl, udev->slot_id, udev->speed, + root_portnr); ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); @@ -461,10 +481,10 @@ static int xhci_address_device(struct usb_device *udev) * @param udev pointer to the Device Data Structure * @return Returns 0 on succes else return error code on failure */ -int usb_alloc_device(struct usb_device *udev) +int _xhci_alloc_device(struct usb_device *udev) { + struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); union xhci_trb *event; - struct xhci_ctrl *ctrl = udev->controller; int ret; /* @@ -486,7 +506,7 @@ int usb_alloc_device(struct usb_device *udev) xhci_acknowledge_event(ctrl); - ret = xhci_alloc_virt_device(udev); + ret = xhci_alloc_virt_device(ctrl, udev->slot_id); if (ret < 0) { /* * TODO: Unsuccessful Address Device command shall leave @@ -499,6 +519,13 @@ int usb_alloc_device(struct usb_device *udev) return 0; } +#ifndef CONFIG_DM_USB +int usb_alloc_device(struct usb_device *udev) +{ + return _xhci_alloc_device(udev); +} +#endif + /* * Full speed devices may have a max packet size greater than 8 bytes, but the * USB core doesn't know that until it reads the first 8 bytes of the @@ -510,7 +537,7 @@ int usb_alloc_device(struct usb_device *udev) */ int xhci_check_maxpacket(struct usb_device *udev) { - struct xhci_ctrl *ctrl = udev->controller; + struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); unsigned int slot_id = udev->slot_id; int ep_index = 0; /* control endpoint */ struct xhci_container_ctx *in_ctx; @@ -640,7 +667,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe, int len, srclen; uint32_t reg; volatile uint32_t *status_reg; - struct xhci_ctrl *ctrl = udev->controller; + struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); struct xhci_hcor *hcor = ctrl->hcor; if ((req->requesttype & USB_RT_PORT) && @@ -677,7 +704,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe, srclen = 4; break; case 1: /* Vendor String */ - srcptr = "\16\3u\0-\0b\0o\0o\0t\0"; + srcptr = "\16\3U\0-\0B\0o\0o\0t\0"; srclen = 14; break; case 2: /* Product Name */ @@ -858,9 +885,8 @@ unknown: * @param interval interval of the interrupt * @return 0 */ -int -submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer, - int length, int interval) +static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe, + void *buffer, int length, int interval) { /* * TODO: Not addressing any interrupt type transfer requests @@ -878,9 +904,8 @@ submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer, * @param length length of the buffer * @return returns 0 if successful else -1 on failure */ -int -submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer, - int length) +static int _xhci_submit_bulk_msg(struct usb_device *udev, unsigned long pipe, + void *buffer, int length) { if (usb_pipetype(pipe) != PIPE_BULK) { printf("non-bulk pipe (type=%lu)", usb_pipetype(pipe)); @@ -898,13 +923,14 @@ submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer, * @param buffer buffer to be read/written based on the request * @param length length of the buffer * @param setup Request type + * @param root_portnr Root port number that this device is on * @return returns 0 if successful else -1 on failure */ -int -submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer, - int length, struct devrequest *setup) +static int _xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe, + void *buffer, int length, + struct devrequest *setup, int root_portnr) { - struct xhci_ctrl *ctrl = udev->controller; + struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); int ret = 0; if (usb_pipetype(pipe) != PIPE_CONTROL) { @@ -916,7 +942,7 @@ submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer, return xhci_submit_root(udev, pipe, buffer, setup); if (setup->request == USB_REQ_SET_ADDRESS) - return xhci_address_device(udev); + return xhci_address_device(udev, root_portnr); if (setup->request == USB_REQ_SET_CONFIGURATION) { ret = xhci_set_configuration(udev); @@ -929,33 +955,16 @@ submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer, return xhci_ctrl_tx(udev, pipe, setup, length, buffer); } -/** - * Intialises the XHCI host controller - * and allocates the necessary data structures - * - * @param index index to the host controller data structure - * @return pointer to the intialised controller - */ -int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +static int xhci_lowlevel_init(struct xhci_ctrl *ctrl) { + struct xhci_hccr *hccr; + struct xhci_hcor *hcor; uint32_t val; uint32_t val2; uint32_t reg; - struct xhci_hccr *hccr; - struct xhci_hcor *hcor; - struct xhci_ctrl *ctrl; - - if (xhci_hcd_init(index, &hccr, (struct xhci_hcor **)&hcor) != 0) - return -ENODEV; - - if (xhci_reset(hcor) != 0) - return -ENODEV; - - ctrl = &xhcic[index]; - - ctrl->hccr = hccr; - ctrl->hcor = hcor; + hccr = ctrl->hccr; + hcor = ctrl->hcor; /* * Program the Number of Device Slots Enabled field in the CONFIG * register with the max value of slots the HC can handle. @@ -997,11 +1006,82 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) reg = HC_VERSION(xhci_readl(&hccr->cr_capbase)); printf("USB XHCI %x.%02x\n", reg >> 8, reg & 0xff); - *controller = &xhcic[index]; + return 0; +} + +static int xhci_lowlevel_stop(struct xhci_ctrl *ctrl) +{ + u32 temp; + + xhci_reset(ctrl->hcor); + + debug("// Disabling event ring interrupts\n"); + temp = xhci_readl(&ctrl->hcor->or_usbsts); + xhci_writel(&ctrl->hcor->or_usbsts, temp & ~STS_EINT); + temp = xhci_readl(&ctrl->ir_set->irq_pending); + xhci_writel(&ctrl->ir_set->irq_pending, ER_IRQ_DISABLE(temp)); return 0; } +#ifndef CONFIG_DM_USB +int submit_control_msg(struct usb_device *udev, unsigned long pipe, + void *buffer, int length, struct devrequest *setup) +{ + struct usb_device *hop = udev; + + if (hop->parent) + while (hop->parent->parent) + hop = hop->parent; + + return _xhci_submit_control_msg(udev, pipe, buffer, length, setup, + hop->portnr); +} + +int submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer, + int length) +{ + return _xhci_submit_bulk_msg(udev, pipe, buffer, length); +} + +int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer, + int length, int interval) +{ + return _xhci_submit_int_msg(udev, pipe, buffer, length, interval); +} + +/** + * Intialises the XHCI host controller + * and allocates the necessary data structures + * + * @param index index to the host controller data structure + * @return pointer to the intialised controller + */ +int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +{ + struct xhci_hccr *hccr; + struct xhci_hcor *hcor; + struct xhci_ctrl *ctrl; + int ret; + + if (xhci_hcd_init(index, &hccr, (struct xhci_hcor **)&hcor) != 0) + return -ENODEV; + + if (xhci_reset(hcor) != 0) + return -ENODEV; + + ctrl = &xhcic[index]; + + ctrl->hccr = hccr; + ctrl->hcor = hcor; + + ret = xhci_lowlevel_init(ctrl); + + *controller = &xhcic[index]; + + return ret; +} + /** * Stops the XHCI host controller * and cleans up all the related data structures @@ -1012,19 +1092,143 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) int usb_lowlevel_stop(int index) { struct xhci_ctrl *ctrl = (xhcic + index); - u32 temp; - xhci_reset(ctrl->hcor); + xhci_lowlevel_stop(ctrl); + xhci_hcd_stop(index); + xhci_cleanup(ctrl); - debug("// Disabling event ring interrupts\n"); - temp = xhci_readl(&ctrl->hcor->or_usbsts); - xhci_writel(&ctrl->hcor->or_usbsts, temp & ~STS_EINT); - temp = xhci_readl(&ctrl->ir_set->irq_pending); - xhci_writel(&ctrl->ir_set->irq_pending, ER_IRQ_DISABLE(temp)); + return 0; +} +#endif /* CONFIG_DM_USB */ - xhci_hcd_stop(index); +#ifdef CONFIG_DM_USB +/* +static struct usb_device *get_usb_device(struct udevice *dev) +{ + struct usb_device *udev; + if (device_get_uclass_id(dev) == UCLASS_USB) + udev = dev_get_uclass_priv(dev); + else + udev = dev_get_parentdata(dev); + + return udev; +} +*/ +static bool is_root_hub(struct udevice *dev) +{ + if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) + return true; + + return false; +} + +static int xhci_submit_control_msg(struct udevice *dev, struct usb_device *udev, + unsigned long pipe, void *buffer, int length, + struct devrequest *setup) +{ + struct usb_device *uhop; + struct udevice *hub; + int root_portnr = 0; + + debug("%s: dev='%s', udev=%p, udev->dev='%s', portnr=%d\n", __func__, + dev->name, udev, udev->dev->name, udev->portnr); + hub = udev->dev; + if (device_get_uclass_id(hub) == UCLASS_USB_HUB) { + /* Figure out our port number on the root hub */ + if (is_root_hub(hub)) { + root_portnr = udev->portnr; + } else { + while (!is_root_hub(hub->parent)) + hub = hub->parent; + uhop = dev_get_parentdata(hub); + root_portnr = uhop->portnr; + } + } +/* + struct usb_device *hop = udev; + + if (hop->parent) + while (hop->parent->parent) + hop = hop->parent; +*/ + return _xhci_submit_control_msg(udev, pipe, buffer, length, setup, + root_portnr); +} + +static int xhci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev, + unsigned long pipe, void *buffer, int length) +{ + debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); + return _xhci_submit_bulk_msg(udev, pipe, buffer, length); +} + +static int xhci_submit_int_msg(struct udevice *dev, struct usb_device *udev, + unsigned long pipe, void *buffer, int length, + int interval) +{ + debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); + return _xhci_submit_int_msg(udev, pipe, buffer, length, interval); +} + +static int xhci_alloc_device(struct udevice *dev, struct usb_device *udev) +{ + debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); + return _xhci_alloc_device(udev); +} + +int xhci_register(struct udevice *dev, struct xhci_hccr *hccr, + struct xhci_hcor *hcor) +{ + struct xhci_ctrl *ctrl = dev_get_priv(dev); + struct usb_bus_priv *priv = dev_get_uclass_priv(dev); + int ret; + + debug("%s: dev='%s', ctrl=%p, hccr=%p, hcor=%p\n", __func__, dev->name, + ctrl, hccr, hcor); + + ctrl->dev = dev; + + /* + * XHCI needs to issue a Address device command to setup + * proper device context structures, before it can interact + * with the device. So a get_descriptor will fail before any + * of that is done for XHCI unlike EHCI. + */ + priv->desc_before_addr = false; + + ret = xhci_reset(hcor); + if (ret) + goto err; + + ctrl->hccr = hccr; + ctrl->hcor = hcor; + ret = xhci_lowlevel_init(ctrl); + if (ret) + goto err; + + return 0; +err: + free(ctrl); + debug("%s: failed, ret=%d\n", __func__, ret); + return ret; +} + +int xhci_deregister(struct udevice *dev) +{ + struct xhci_ctrl *ctrl = dev_get_priv(dev); + + xhci_lowlevel_stop(ctrl); xhci_cleanup(ctrl); return 0; } + +struct dm_usb_ops xhci_usb_ops = { + .control = xhci_submit_control_msg, + .bulk = xhci_submit_bulk_msg, + .interrupt = xhci_submit_int_msg, + .alloc_device = xhci_alloc_device, +}; + +#endif diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 0951e87..2afa386 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1209,6 +1209,9 @@ void xhci_hcd_stop(int index); #define XHCI_STS_CNR (1 << 11) struct xhci_ctrl { +#ifdef CONFIG_DM_USB + struct udevice *dev; +#endif struct xhci_hccr *hccr; /* R/O registers, not need for volatile */ struct xhci_hcor *hcor; struct xhci_doorbell_array *dba; @@ -1241,7 +1244,8 @@ void xhci_endpoint_copy(struct xhci_ctrl *ctrl, void xhci_slot_copy(struct xhci_ctrl *ctrl, struct xhci_container_ctx *in_ctx, struct xhci_container_ctx *out_ctx); -void xhci_setup_addressable_virt_dev(struct usb_device *udev); +void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id, + int speed, int hop_portnr); void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr, u32 slot_id, u32 ep_index, trb_type cmd); void xhci_acknowledge_event(struct xhci_ctrl *ctrl); @@ -1255,8 +1259,31 @@ void xhci_flush_cache(uintptr_t addr, u32 type_len); void xhci_inval_cache(uintptr_t addr, u32 type_len); void xhci_cleanup(struct xhci_ctrl *ctrl); struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, bool link_trbs); -int xhci_alloc_virt_device(struct usb_device *udev); +int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id); int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr, struct xhci_hcor *hcor); +/** + * xhci_deregister() - Unregister an XHCI controller + * + * @dev: Controller device + * @return 0 if registered, -ve on error + */ +int xhci_deregister(struct udevice *dev); + +/** + * xhci_register() - Register a new XHCI controller + * + * @dev: Controller device + * @hccr: Host controller control registers + * @hcor: Not sure what this means + * @return 0 if registered, -ve on error + */ +int xhci_register(struct udevice *dev, struct xhci_hccr *hccr, + struct xhci_hcor *hcor); + +extern struct dm_usb_ops xhci_usb_ops; + +struct xhci_ctrl *xhci_get_ctrl(struct usb_device *udev); + #endif /* HOST_XHCI_H_ */ diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c index 053d945..7d90ebc 100644 --- a/drivers/usb/musb-new/musb_uboot.c +++ b/drivers/usb/musb-new/musb_uboot.c @@ -180,7 +180,7 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue) return NULL; /* URB still pending */ } -void usb_reset_root_port(void) +int usb_reset_root_port(void) { void *mbase = host->mregs; u8 power; @@ -208,6 +208,8 @@ void usb_reset_root_port(void) (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ? USB_SPEED_FULL : USB_SPEED_LOW; mdelay((host_speed == USB_SPEED_LOW) ? 200 : 50); + + return 0; } int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index 90aaec6..c9a6a16 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -235,52 +235,19 @@ static int sunxi_musb_init(struct musb *musb) pr_debug("%s():\n", __func__); - if (is_host_enabled(musb)) { - int vbus_det = sunxi_name_to_gpio(CONFIG_USB0_VBUS_DET); - -#ifdef AXP_VBUS_DETECT - if (!strcmp(CONFIG_USB0_VBUS_DET, "axp_vbus_detect")) { - err = axp_get_vbus(); - if (err < 0) - return err; - } else { -#endif - if (vbus_det == -1) { - eprintf("Error invalid Vusb-det pin\n"); - return -EINVAL; - } - - err = gpio_request(vbus_det, "vbus0_det"); - if (err) - return err; - - err = gpio_direction_input(vbus_det); - if (err) { - gpio_free(vbus_det); - return err; - } - - err = gpio_get_value(vbus_det); - if (err < 0) { - gpio_free(vbus_det); - return -EIO; - } - - gpio_free(vbus_det); -#ifdef AXP_VBUS_DETECT - } -#endif + err = sunxi_usbc_request_resources(0); + if (err) + return err; + if (is_host_enabled(musb)) { + err = sunxi_usbc_vbus_detect(0); if (err) { eprintf("Error: A charger is plugged into the OTG\n"); + sunxi_usbc_free_resources(0); return -EIO; } } - err = sunxi_usbc_request_resources(0); - if (err) - return err; - musb->isr = sunxi_musb_interrupt; sunxi_usbc_enable(0); diff --git a/drivers/usb/phy/omap_usb_phy.c b/drivers/usb/phy/omap_usb_phy.c index 52a3664..63d9301 100644 --- a/drivers/usb/phy/omap_usb_phy.c +++ b/drivers/usb/phy/omap_usb_phy.c @@ -131,17 +131,6 @@ static void omap_enable_usb3_phy(struct omap_xhci *omap) { u32 val; - /* Setting OCP2SCP1 register */ - setbits_le32((*prcm)->cm_l3init_ocp2scp1_clkctrl, - OCP2SCP1_CLKCTRL_MODULEMODE_HW); - - /* Turn on 32K AON clk */ - setbits_le32((*prcm)->cm_coreaon_usb_phy_core_clkctrl, - USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K); - - /* Setting CM_L3INIT_CLKSTCTRL to 0x0 i.e NO sleep */ - writel(0x0, (*prcm)->cm_l3init_clkstctrl); - val = (USBOTGSS_DMADISABLE | USBOTGSS_STANDBYMODE_SMRT_WKUP | USBOTGSS_IDLEMODE_NOIDLE); @@ -169,11 +158,6 @@ static void omap_enable_usb3_phy(struct omap_xhci *omap) writel(val, &omap->otg_wrapper->irqstatus_1); val = readl(&omap->otg_wrapper->irqstatus_0); writel(val, &omap->otg_wrapper->irqstatus_0); - - /* Enable the USB OTG Super speed clocks */ - val = (OPTFCLKEN_REFCLK960M | OTG_SS_CLKCTRL_MODULEMODE_HW); - setbits_le32((*prcm)->cm_l3init_usb_otg_ss_clkctrl, val); - }; #endif /* CONFIG_OMAP_USB3PHY1_HOST */ diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 22a316b..f64918e 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -45,5 +45,6 @@ obj-$(CONFIG_VIDEO_TEGRA) += tegra.o obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o obj-$(CONFIG_VIDEO_VESA) += vesa_fb.o obj-$(CONFIG_FORMIKE) += formike.o +obj-$(CONFIG_LG4573) += lg4573.o obj-$(CONFIG_AM335X_LCD) += am335x-fb.o obj-$(CONFIG_VIDEO_PARADE) += parade.o diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index a81affa..f4231b8 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -87,6 +87,7 @@ */ #include <common.h> +#include <fdtdec.h> #include <version.h> #include <malloc.h> #include <linux/compiler.h> @@ -2251,6 +2252,7 @@ int drv_video_init(void) { int skip_dev_init; struct stdio_dev console_dev; + bool have_keyboard; /* Check if video initialization should be skipped */ if (board_video_skip()) @@ -2262,11 +2264,20 @@ int drv_video_init(void) if (board_cfb_skip()) return 0; +#if defined(CONFIG_VGA_AS_SINGLE_DEVICE) + have_keyboard = false; +#elif defined(CONFIG_OF_CONTROL) + have_keyboard = !fdtdec_get_config_bool(gd->fdt_blob, + "u-boot,no-keyboard"); +#else + have_keyboard = true; +#endif + if (have_keyboard) { + debug("KBD: Keyboard init ...\n"); #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE) - debug("KBD: Keyboard init ...\n"); - skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1); + skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1); #endif - + } if (skip_dev_init) return 0; @@ -2279,11 +2290,13 @@ int drv_video_init(void) console_dev.puts = video_puts; /* 'puts' function */ #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE) - /* Also init console device */ - console_dev.flags |= DEV_FLAGS_INPUT; - console_dev.tstc = VIDEO_TSTC_FCT; /* 'tstc' function */ - console_dev.getc = VIDEO_GETC_FCT; /* 'getc' function */ -#endif /* CONFIG_VGA_AS_SINGLE_DEVICE */ + if (have_keyboard) { + /* Also init console device */ + console_dev.flags |= DEV_FLAGS_INPUT; + console_dev.tstc = VIDEO_TSTC_FCT; /* 'tstc' function */ + console_dev.getc = VIDEO_GETC_FCT; /* 'getc' function */ + } +#endif if (stdio_register(&console_dev) != 0) return 0; diff --git a/drivers/video/ipu.h b/drivers/video/ipu.h index 091b58f..348be58 100644 --- a/drivers/video/ipu.h +++ b/drivers/video/ipu.h @@ -265,5 +265,4 @@ int ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt, void ipu_dp_uninit(ipu_channel_t channel); void ipu_dp_dc_disable(ipu_channel_t channel, unsigned char swap); ipu_color_space_t format_to_colorspace(uint32_t fmt); - #endif diff --git a/drivers/video/ipu_common.c b/drivers/video/ipu_common.c index 5873531..9f85102 100644 --- a/drivers/video/ipu_common.c +++ b/drivers/video/ipu_common.c @@ -210,9 +210,13 @@ static struct clk ipu_clk = { .usecount = 0, }; +#if !defined CONFIG_SYS_LDB_CLOCK +#define CONFIG_SYS_LDB_CLOCK 65000000 +#endif + static struct clk ldb_clk = { .name = "ldb_clk", - .rate = 65000000, + .rate = CONFIG_SYS_LDB_CLOCK, .usecount = 0, }; @@ -1194,3 +1198,11 @@ ipu_color_space_t format_to_colorspace(uint32_t fmt) } return RGB; } + +/* should be removed when clk framework is availiable */ +int ipu_set_ldb_clock(int rate) +{ + ldb_clk.rate = rate; + + return 0; +} diff --git a/drivers/video/lg4573.c b/drivers/video/lg4573.c new file mode 100644 index 0000000..43670fc --- /dev/null +++ b/drivers/video/lg4573.c @@ -0,0 +1,231 @@ +/* + * LCD: LG4573, TFT 4.3", 480x800, RGB24 + * LCD initialization via SPI + * + * SPDX-License-Identifier: GPL-2.0 + * + */ +#include <common.h> +#include <errno.h> +#include <spi.h> + +#define PWR_ON_DELAY_MSECS 120 + +static int lb043wv_spi_write_u16(struct spi_slave *spi, u16 val) +{ + unsigned long flags = SPI_XFER_BEGIN; + unsigned short buf16 = htons(val); + int ret = 0; + + flags |= SPI_XFER_END; + + ret = spi_xfer(spi, 16, &buf16, NULL, flags); + if (ret) + debug("%s: Failed to send: %d\n", __func__, ret); + + return ret; +} + +static void lb043wv_spi_write_u16_array(struct spi_slave *spi, u16 *buff, + int size) +{ + int i; + + for (i = 0; i < size; i++) + lb043wv_spi_write_u16(spi, buff[i]); +} + +static void lb043wv_display_mode_settings(struct spi_slave *spi) +{ + static u16 display_mode_settings[] = { + 0x703A, + 0x7270, + 0x70B1, + 0x7208, + 0x723B, + 0x720F, + 0x70B2, + 0x7200, + 0x72C8, + 0x70B3, + 0x7200, + 0x70B4, + 0x7200, + 0x70B5, + 0x7242, + 0x7210, + 0x7210, + 0x7200, + 0x7220, + 0x70B6, + 0x720B, + 0x720F, + 0x723C, + 0x7213, + 0x7213, + 0x72E8, + 0x70B7, + 0x7246, + 0x7206, + 0x720C, + 0x7200, + 0x7200, + }; + + debug("transfer display mode settings\n"); + lb043wv_spi_write_u16_array(spi, display_mode_settings, + ARRAY_SIZE(display_mode_settings)); +} + +static void lb043wv_power_settings(struct spi_slave *spi) +{ + static u16 power_settings[] = { + 0x70C0, + 0x7201, + 0x7211, + 0x70C3, + 0x7207, + 0x7203, + 0x7204, + 0x7204, + 0x7204, + 0x70C4, + 0x7212, + 0x7224, + 0x7218, + 0x7218, + 0x7202, + 0x7249, + 0x70C5, + 0x726F, + 0x70C6, + 0x7241, + 0x7263, + }; + + debug("transfer power settings\n"); + lb043wv_spi_write_u16_array(spi, power_settings, + ARRAY_SIZE(power_settings)); +} + +static void lb043wv_gamma_settings(struct spi_slave *spi) +{ + static u16 gamma_settings[] = { + 0x70D0, + 0x7203, + 0x7207, + 0x7273, + 0x7235, + 0x7200, + 0x7201, + 0x7220, + 0x7200, + 0x7203, + 0x70D1, + 0x7203, + 0x7207, + 0x7273, + 0x7235, + 0x7200, + 0x7201, + 0x7220, + 0x7200, + 0x7203, + 0x70D2, + 0x7203, + 0x7207, + 0x7273, + 0x7235, + 0x7200, + 0x7201, + 0x7220, + 0x7200, + 0x7203, + 0x70D3, + 0x7203, + 0x7207, + 0x7273, + 0x7235, + 0x7200, + 0x7201, + 0x7220, + 0x7200, + 0x7203, + 0x70D4, + 0x7203, + 0x7207, + 0x7273, + 0x7235, + 0x7200, + 0x7201, + 0x7220, + 0x7200, + 0x7203, + 0x70D5, + 0x7203, + 0x7207, + 0x7273, + 0x7235, + 0x7200, + 0x7201, + 0x7220, + 0x7200, + 0x7203, + }; + + debug("transfer gamma settings\n"); + lb043wv_spi_write_u16_array(spi, gamma_settings, + ARRAY_SIZE(gamma_settings)); +} + +static void lb043wv_display_on(struct spi_slave *spi) +{ + static u16 sleep_out = 0x7011; + static u16 display_on = 0x7029; + + lb043wv_spi_write_u16(spi, sleep_out); + mdelay(PWR_ON_DELAY_MSECS); + lb043wv_spi_write_u16(spi, display_on); +} + +int lg4573_spi_startup(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int spi_mode) +{ + struct spi_slave *spi; + int ret; + + spi = spi_setup_slave(bus, cs, max_hz, spi_mode); + if (!spi) { + debug("%s: Failed to set up slave\n", __func__); + return -1; + } + + ret = spi_claim_bus(spi); + if (ret) { + debug("%s: Failed to claim SPI bus: %d\n", __func__, ret); + goto err_claim_bus; + } + + lb043wv_display_mode_settings(spi); + lb043wv_power_settings(spi); + lb043wv_gamma_settings(spi); + + lb043wv_display_on(spi); + return 0; +err_claim_bus: + spi_free_slave(spi); + return -1; +} + +static int do_lgset(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + lg4573_spi_startup(0, 0, 10000000, SPI_MODE_0); + return 0; +} + +U_BOOT_CMD( + lgset, 2, 1, do_lgset, + "set lgdisplay", + "" +); diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index 4e12150..d2341b0 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -665,10 +665,10 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode, for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++) #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL - sunxi_gpio_set_cfgpin(pin, SUNXI_GPD0_LCD0); + sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0); #endif #ifdef CONFIG_VIDEO_LCD_IF_LVDS - sunxi_gpio_set_cfgpin(pin, SUNXI_GPD0_LVDS0); + sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LVDS0); #endif sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double); @@ -779,8 +779,8 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode, &lcdc->tcon1_timing_sync); if (use_portd_hvsync) { - sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD0_LCD0); - sunxi_gpio_set_cfgpin(SUNXI_GPD(27), SUNXI_GPD0_LCD0); + sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD_LCD0); + sunxi_gpio_set_cfgpin(SUNXI_GPD(27), SUNXI_GPD_LCD0); val = 0; if (mode->sync & FB_SYNC_HOR_HIGH_ACT) diff --git a/dts/Kconfig b/dts/Kconfig index ca5bd6f..957f5c7 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -1,9 +1,6 @@ # # Device Tree Control # -# TODO: -# This feature is not currently supported for SPL, -# but this restriction should be removed in the future. config SUPPORT_OF_CONTROL bool @@ -17,6 +14,14 @@ config OF_CONTROL This feature provides for run-time configuration of U-Boot via a flattened device tree. +config SPL_DISABLE_OF_CONTROL + bool "Disable run-time configuration via Device Tree in SPL" + depends on OF_CONTROL + help + Some boards use device tree in U-Boot but only have 4KB of SRAM + which is not enough to support device tree. Enable this option to + allow such boards to be supported by U-Boot SPL. + choice prompt "Provider of DTB for DT control" depends on OF_CONTROL @@ -17,6 +17,7 @@ #include <config.h> #include <errno.h> #include <common.h> +#include <mapmem.h> #include <part.h> #include <ext4fs.h> #include <fat.h> diff --git a/fs/sandbox/sandboxfs.c b/fs/sandbox/sandboxfs.c index a920bc0..5acfc03 100644 --- a/fs/sandbox/sandboxfs.c +++ b/fs/sandbox/sandboxfs.c @@ -10,7 +10,11 @@ int sandbox_fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info) { - return 0; + /* + * Only accept a NULL block_dev_desc_t for the sandbox, which is when + * hostfs interface is used + */ + return rbdd != NULL; } int sandbox_fs_read_at(const char *filename, loff_t pos, void *buffer, diff --git a/include/ahci.h b/include/ahci.h index e8dee53..6d91712 100644 --- a/include/ahci.h +++ b/include/ahci.h @@ -151,7 +151,7 @@ struct ahci_probe_ent { u32 hard_port_no; u32 host_flags; u32 host_set_flags; - u32 mmio_base; + void __iomem *mmio_base; u32 pio_mask; u32 udma_mask; u32 flags; @@ -160,7 +160,7 @@ struct ahci_probe_ent { u32 link_port_map; /*linkup port map*/ }; -int ahci_init(u32 base); -int ahci_reset(u32 base); +int ahci_init(void __iomem *base); +int ahci_reset(void __iomem *base); #endif diff --git a/include/atmel_lcd.h b/include/atmel_lcd.h index fa8aa29..6993128 100644 --- a/include/atmel_lcd.h +++ b/include/atmel_lcd.h @@ -13,7 +13,8 @@ typedef struct vidinfo { ushort vl_col; /* Number of columns (i.e. 640) */ ushort vl_row; /* Number of rows (i.e. 480) */ - u_long vl_clk; /* pixel clock in ps */ + ushort vl_rot; /* Rotation of Display (0, 1, 2, 3) */ + u_long vl_clk; /* pixel clock in ps */ /* LCD configuration register */ u_long vl_sync; /* Horizontal / vertical sync */ diff --git a/include/axp152.h b/include/axp152.h index 3e5ccbd..9d205f8 100644 --- a/include/axp152.h +++ b/include/axp152.h @@ -3,6 +3,18 @@ * * SPDX-License-Identifier: GPL-2.0+ */ + +enum axp152_reg { + AXP152_CHIP_VERSION = 0x3, + AXP152_DCDC2_VOLTAGE = 0x23, + AXP152_DCDC3_VOLTAGE = 0x27, + AXP152_DCDC4_VOLTAGE = 0x2B, + AXP152_LDO2_VOLTAGE = 0x2A, + AXP152_SHUTDOWN = 0x32, +}; + +#define AXP152_POWEROFF (1 << 7) + int axp152_set_dcdc2(int mvolt); int axp152_set_dcdc3(int mvolt); int axp152_set_dcdc4(int mvolt); diff --git a/include/axp209.h b/include/axp209.h index 0436249..d36da41 100644 --- a/include/axp209.h +++ b/include/axp209.h @@ -4,6 +4,44 @@ * SPDX-License-Identifier: GPL-2.0+ */ +enum axp209_reg { + AXP209_POWER_STATUS = 0x00, + AXP209_CHIP_VERSION = 0x03, + AXP209_DCDC2_VOLTAGE = 0x23, + AXP209_DCDC3_VOLTAGE = 0x27, + AXP209_LDO24_VOLTAGE = 0x28, + AXP209_LDO3_VOLTAGE = 0x29, + AXP209_IRQ_ENABLE1 = 0x40, + AXP209_IRQ_ENABLE2 = 0x41, + AXP209_IRQ_ENABLE3 = 0x42, + AXP209_IRQ_ENABLE4 = 0x43, + AXP209_IRQ_ENABLE5 = 0x44, + AXP209_IRQ_STATUS5 = 0x4c, + AXP209_SHUTDOWN = 0x32, + AXP209_GPIO0_CTRL = 0x90, + AXP209_GPIO1_CTRL = 0x92, + AXP209_GPIO2_CTRL = 0x93, + AXP209_GPIO_STATE = 0x94, + AXP209_GPIO3_CTRL = 0x95, +}; + +#define AXP209_POWER_STATUS_ON_BY_DC (1 << 0) +#define AXP209_POWER_STATUS_VBUS_USABLE (1 << 4) + +#define AXP209_IRQ5_PEK_UP (1 << 6) +#define AXP209_IRQ5_PEK_DOWN (1 << 5) + +#define AXP209_POWEROFF (1 << 7) + +#define AXP209_GPIO_OUTPUT_LOW 0x00 /* Drive pin low */ +#define AXP209_GPIO_OUTPUT_HIGH 0x01 /* Drive pin high */ +#define AXP209_GPIO_INPUT 0x02 /* Float pin */ + +/* GPIO3 is different from the others */ +#define AXP209_GPIO3_OUTPUT_LOW 0x00 /* Drive pin low, Output mode */ +#define AXP209_GPIO3_OUTPUT_HIGH 0x02 /* Float pin, Output mode */ +#define AXP209_GPIO3_INPUT 0x06 /* Float pin, Input mode */ + #define AXP_GPIO extern int axp209_set_dcdc2(int mvolt); diff --git a/include/axp221.h b/include/axp221.h index be6058e..0aac04d 100644 --- a/include/axp221.h +++ b/include/axp221.h @@ -62,11 +62,7 @@ /* Page 1 addresses */ #define AXP221_SID 0x20 -/* We support vbus detection */ -#define AXP_VBUS_DETECT - -/* We support drivebus control */ -#define AXP_DRIVEBUS +#define AXP_GPIO int axp221_set_dcdc1(unsigned int mvolt); int axp221_set_dcdc2(unsigned int mvolt); @@ -83,6 +79,8 @@ int axp221_set_aldo3(unsigned int mvolt); int axp221_set_eldo(int eldo_num, unsigned int mvolt); int axp221_init(void); int axp221_get_sid(unsigned int *sid); -int axp_get_vbus(void); -int axp_drivebus_enable(void); -int axp_drivebus_disable(void); + +int axp_gpio_direction_input(unsigned int pin); +int axp_gpio_direction_output(unsigned int pin, unsigned int val); +int axp_gpio_get_value(unsigned int pin); +int axp_gpio_set_value(unsigned int pin, unsigned int val); diff --git a/include/bootstage.h b/include/bootstage.h index 0276cb3..be44014 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -11,7 +11,7 @@ #ifndef _BOOTSTAGE_H #define _BOOTSTAGE_H -/* The number of boot stage records available for the user */ +/* Define this for host tools */ #ifndef CONFIG_BOOTSTAGE_USER_COUNT #define CONFIG_BOOTSTAGE_USER_COUNT 20 #endif diff --git a/include/common.h b/include/common.h index 6df05b8..cde3474 100644 --- a/include/common.h +++ b/include/common.h @@ -253,6 +253,17 @@ int update_flash_size(int flash_size); int arch_early_init_r(void); /** + * arch_cpu_init_dm() - init CPU after driver model is available + * + * This is called immediately after driver model is available before + * relocation. This is similar to arch_cpu_init() but is able to reference + * devices + * + * @return 0 if OK, -ve on error + */ +int arch_cpu_init_dm(void); + +/** * Reserve all necessary stacks * * This is used in generic board init sequence in common/board_f.c. Each @@ -471,7 +482,6 @@ int testdram(void); defined(CONFIG_8xx) uint get_immr (uint); #endif -uint get_pir (void); #if defined(CONFIG_MPC5xxx) uint get_svr (void); #endif @@ -733,6 +743,45 @@ int gunzip(void *, int, unsigned char *, unsigned long *); int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp, int stoponerr, int offset); +/** + * gzwrite progress indicators: defined weak to allow board-specific + * overrides: + * + * gzwrite_progress_init called on startup + * gzwrite_progress called during decompress/write loop + * gzwrite_progress_finish called at end of loop to + * indicate success (retcode=0) or failure + */ +void gzwrite_progress_init(u64 expected_size); + +void gzwrite_progress(int iteration, + u64 bytes_written, + u64 total_bytes); + +void gzwrite_progress_finish(int retcode, + u64 totalwritten, + u64 totalsize, + u32 expected_crc, + u32 calculated_crc); + +/** + * decompress and write gzipped image from memory to block device + * + * @param src compressed image address + * @param len compressed image length in bytes + * @param dev block device descriptor + * @param szwritebuf bytes per write (pad to erase size) + * @param startoffs offset in bytes of first write + * @param szexpected expected uncompressed length + * may be zero to use gzip trailer + * for files under 4GiB + */ +int gzwrite(unsigned char *src, int len, + struct block_dev_desc *dev, + unsigned long szwritebuf, + u64 startoffs, + u64 szexpected); + /* lib/qsort.c */ void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); @@ -815,7 +864,7 @@ int zzip(void *dst, unsigned long *lenp, unsigned char *src, /* lib/net_utils.c */ #include <net.h> -static inline IPaddr_t getenv_IPaddr(char *var) +static inline struct in_addr getenv_ip(char *var) { return string_to_ip(getenv(var)); } @@ -847,23 +896,6 @@ int cpu_disable(int nr); int cpu_release(int nr, int argc, char * const argv[]); #endif -/* Define a null map_sysmem() if the architecture doesn't use it */ -# ifndef CONFIG_ARCH_MAP_SYSMEM -static inline void *map_sysmem(phys_addr_t paddr, unsigned long len) -{ - return (void *)(uintptr_t)paddr; -} - -static inline void unmap_sysmem(const void *vaddr) -{ -} - -static inline phys_addr_t map_to_sysmem(const void *ptr) -{ - return (phys_addr_t)(uintptr_t)ptr; -} -# endif - #endif /* __ASSEMBLY__ */ #ifdef CONFIG_PPC diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index d71e58d..3a360ca4 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -48,6 +48,18 @@ #define BOOTENV_DEV_NAME_BLKDEV(devtypeu, devtypel, instance) \ #devtypel #instance " " +#ifdef CONFIG_SANDBOX +#define BOOTENV_SHARED_HOST BOOTENV_SHARED_BLKDEV(host) +#define BOOTENV_DEV_HOST BOOTENV_DEV_BLKDEV +#define BOOTENV_DEV_NAME_HOST BOOTENV_DEV_NAME_BLKDEV +#else +#define BOOTENV_SHARED_HOST +#define BOOTENV_DEV_HOST \ + BOOT_TARGET_DEVICES_references_HOST_without_CONFIG_SANDBOX +#define BOOTENV_DEV_NAME_HOST \ + BOOT_TARGET_DEVICES_references_HOST_without_CONFIG_SANDBOX +#endif + #ifdef CONFIG_CMD_MMC #define BOOTENV_SHARED_MMC BOOTENV_SHARED_BLKDEV(mmc) #define BOOTENV_DEV_MMC BOOTENV_DEV_BLKDEV @@ -167,6 +179,7 @@ #define BOOTENV_DEV(devtypeu, devtypel, instance) \ BOOTENV_DEV_##devtypeu(devtypeu, devtypel, instance) #define BOOTENV \ + BOOTENV_SHARED_HOST \ BOOTENV_SHARED_MMC \ BOOTENV_SHARED_USB \ BOOTENV_SHARED_SATA \ diff --git a/include/config_distro_defaults.h b/include/config_distro_defaults.h index 8237239..5eea5cf 100644 --- a/include/config_distro_defaults.h +++ b/include/config_distro_defaults.h @@ -29,6 +29,10 @@ #else #define CONFIG_BOOTP_VCI_STRING "U-boot.arm" #endif +#elif defined(__i386__) +#define CONFIG_BOOTP_PXE_CLIENTARCH 0x0 +#elif defined(__x86_64__) +#define CONFIG_BOOTP_PXE_CLIENTARCH 0x9 #endif #define CONFIG_OF_LIBFDT diff --git a/include/config_fsl_secboot.h b/include/config_fsl_secboot.h new file mode 100644 index 0000000..050b157 --- /dev/null +++ b/include/config_fsl_secboot.h @@ -0,0 +1,89 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_FSL_SECBOOT_H +#define __CONFIG_FSL_SECBOOT_H + +#ifdef CONFIG_SECURE_BOOT + +#ifndef CONFIG_CMD_ESBC_VALIDATE +#define CONFIG_CMD_ESBC_VALIDATE +#endif + +#ifndef CONFIG_EXTRA_ENV +#define CONFIG_EXTRA_ENV "" +#endif + +/* + * Control should not reach back to uboot after validation of images + * for secure boot flow and therefore bootscript should have + * the bootm command. If control reaches back to uboot anyhow + * after validating images, core should just spin. + */ + +/* + * Define the key hash for boot script here if public/private key pair used to + * sign bootscript are different from the SRK hash put in the fuse + * Example of defining KEY_HASH is + * #define CONFIG_BOOTSCRIPT_KEY_HASH \ + * "41066b564c6ffcef40ccbc1e0a5d0d519604000c785d97bbefd25e4d288d1c8b" + */ + +#ifdef CONFIG_BOOTSCRIPT_KEY_HASH +#define CONFIG_SECBOOT \ + "setenv bs_hdraddr " __stringify(CONFIG_BOOTSCRIPT_HDR_ADDR)";" \ + "setenv bootargs \'root=/dev/ram rw console=ttyS0,115200 " \ + "ramdisk_size=600000\';" \ + CONFIG_EXTRA_ENV \ + "esbc_validate $bs_hdraddr " \ + __stringify(CONFIG_BOOTSCRIPT_KEY_HASH)";" \ + "source $img_addr;" \ + "esbc_halt\0" +#else +#define CONFIG_SECBOOT \ + "setenv bs_hdraddr " __stringify(CONFIG_BOOTSCRIPT_HDR_ADDR)";" \ + "setenv bootargs \'root=/dev/ram rw console=ttyS0,115200 " \ + "ramdisk_size=600000\';" \ + CONFIG_EXTRA_ENV \ + "esbc_validate $bs_hdraddr;" \ + "source $img_addr;" \ + "esbc_halt\0" +#endif + +/* For secure boot flow, default environment used will be used */ +#if defined(CONFIG_SYS_RAMBOOT) +#if defined(CONFIG_RAMBOOT_SPIFLASH) +#undef CONFIG_ENV_IS_IN_SPI_FLASH +#elif defined(CONFIG_RAMBOOT_NAND) +#undef CONFIG_ENV_IS_IN_NAND +#elif defined(CONFIG_RAMBOOT_SDCARD) +#undef CONFIG_ENV_IS_IN_MMC +#endif +#else /*CONFIG_SYS_RAMBOOT*/ +#undef CONFIG_ENV_IS_IN_FLASH +#endif + +#define CONFIG_ENV_IS_NOWHERE + +/* + * We don't want boot delay for secure boot flow + * before autoboot starts + */ +#undef CONFIG_BOOTDELAY +#define CONFIG_BOOTDELAY 0 +#undef CONFIG_BOOTCOMMAND +#define CONFIG_BOOTCOMMAND CONFIG_SECBOOT + +/* + * CONFIG_ZERO_BOOTDELAY_CHECK should not be defined for + * secure boot flow as defining this would enable a user to + * reach uboot prompt by pressing some key before start of + * autoboot + */ +#undef CONFIG_ZERO_BOOTDELAY_CHECK + +#endif +#endif diff --git a/include/config_uncmd_spl.h b/include/config_uncmd_spl.h index a9106f4..38cb0e8 100644 --- a/include/config_uncmd_spl.h +++ b/include/config_uncmd_spl.h @@ -31,6 +31,7 @@ #undef CONFIG_DM_WARN #undef CONFIG_DM_DEVICE_REMOVE +#undef CONFIG_DM_SEQ_ALIAS #undef CONFIG_DM_STDIO #endif /* CONFIG_SPL_BUILD */ diff --git a/include/configs/M5208EVBE.h b/include/configs/M5208EVBE.h index 9390464..7eac03b 100644 --- a/include/configs/M5208EVBE.h +++ b/include/configs/M5208EVBE.h @@ -180,6 +180,10 @@ #define CONFIG_ENV_SECT_SIZE 0x2000 #define CONFIG_ENV_IS_IN_FLASH 1 +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text*); + /* Cache Configuration */ #define CONFIG_SYS_CACHELINE_SIZE 16 diff --git a/include/configs/M52277EVB.h b/include/configs/M52277EVB.h index e9424b4..ce33ba4 100644 --- a/include/configs/M52277EVB.h +++ b/include/configs/M52277EVB.h @@ -267,6 +267,10 @@ # define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_CS0_BASE } #endif +#define LDS_BOARD_TEXT \ + arch/m68k/cpu/mcf5227x/built-in.o (.text*) \ + arch/m68k/lib/built-in.o (.text*) + /* * This is setting for JFFS2 support in u-boot. * NOTE: Enable CONFIG_CMD_JFFS2 for JFFS2 support. diff --git a/include/configs/M5235EVB.h b/include/configs/M5235EVB.h index 883347b..4bba815 100644 --- a/include/configs/M5235EVB.h +++ b/include/configs/M5235EVB.h @@ -199,6 +199,11 @@ * Environment is embedded in u-boot in the second sector of the flash */ #define CONFIG_ENV_IS_IN_FLASH 1 + +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text); + #ifdef NORFLASH_PS32BIT # define CONFIG_ENV_OFFSET (0x8000) # define CONFIG_ENV_SIZE 0x4000 diff --git a/include/configs/M5249EVB.h b/include/configs/M5249EVB.h index 60e5b45..6167ea1 100644 --- a/include/configs/M5249EVB.h +++ b/include/configs/M5249EVB.h @@ -91,6 +91,11 @@ #define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET #define CONFIG_ENV_IS_IN_FLASH 1 + +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text); + #define CONFIG_ENV_OFFSET 0x4000 /* Address of Environment Sector*/ #define CONFIG_ENV_SIZE 0x2000 /* Total Size of Environment Sector */ #define CONFIG_ENV_SECT_SIZE 0x2000 /* see README - env sector total size */ diff --git a/include/configs/M5253DEMO.h b/include/configs/M5253DEMO.h index 7421b57..5d97874 100644 --- a/include/configs/M5253DEMO.h +++ b/include/configs/M5253DEMO.h @@ -32,6 +32,10 @@ # define CONFIG_ENV_IS_IN_FLASH 1 #endif +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text*); + /* * Command line configuration. */ diff --git a/include/configs/M5253EVBE.h b/include/configs/M5253EVBE.h index 8fd3907..64dc64d 100644 --- a/include/configs/M5253EVBE.h +++ b/include/configs/M5253EVBE.h @@ -33,6 +33,11 @@ #define CONFIG_ENV_IS_IN_FLASH 1 #endif +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text) + + /* * BOOTP options */ diff --git a/include/configs/M5272C3.h b/include/configs/M5272C3.h index 2c056b1..159d2f8 100644 --- a/include/configs/M5272C3.h +++ b/include/configs/M5272C3.h @@ -41,6 +41,10 @@ #define CONFIG_ENV_IS_IN_FLASH 1 #endif +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text); + /* * BOOTP options */ diff --git a/include/configs/M5275EVB.h b/include/configs/M5275EVB.h index 7eb3172..14ccddb 100644 --- a/include/configs/M5275EVB.h +++ b/include/configs/M5275EVB.h @@ -42,6 +42,10 @@ #define CONFIG_ENV_IS_IN_FLASH 1 #endif +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text); + /* * BOOTP options */ diff --git a/include/configs/M5282EVB.h b/include/configs/M5282EVB.h index 569ad42..bc740ae 100644 --- a/include/configs/M5282EVB.h +++ b/include/configs/M5282EVB.h @@ -32,6 +32,10 @@ #define CONFIG_ENV_SIZE 0x2000 #define CONFIG_ENV_IS_IN_FLASH 1 +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text*); + /* * BOOTP options */ diff --git a/include/configs/M53017EVB.h b/include/configs/M53017EVB.h index e3fa856..0829708 100644 --- a/include/configs/M53017EVB.h +++ b/include/configs/M53017EVB.h @@ -205,6 +205,10 @@ #define CONFIG_ENV_SECT_SIZE 0x8000 #define CONFIG_ENV_IS_IN_FLASH 1 +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text*) + /*----------------------------------------------------------------------- * Cache Configuration */ diff --git a/include/configs/M5329EVB.h b/include/configs/M5329EVB.h index 795f359..a42b5f6 100644 --- a/include/configs/M5329EVB.h +++ b/include/configs/M5329EVB.h @@ -209,6 +209,10 @@ #define CONFIG_ENV_SECT_SIZE 0x2000 #define CONFIG_ENV_IS_IN_FLASH 1 +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text*); + /*----------------------------------------------------------------------- * Cache Configuration */ diff --git a/include/configs/M5373EVB.h b/include/configs/M5373EVB.h index d75b43c..c142dfb 100644 --- a/include/configs/M5373EVB.h +++ b/include/configs/M5373EVB.h @@ -209,6 +209,10 @@ #define CONFIG_ENV_SECT_SIZE 0x2000 #define CONFIG_ENV_IS_IN_FLASH 1 +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text*); + /*----------------------------------------------------------------------- * Cache Configuration */ diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index a0d7d52..9f755e5 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -255,7 +255,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) #define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET -#define CONFIG_SYS_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Mon */ +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) /* Reserve 512 kB for Mon */ #define CONFIG_SYS_MALLOC_LEN (1024 * 1024) /* Reserved for malloc */ /* Serial Port */ @@ -602,7 +602,8 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); */ #ifndef CONFIG_SYS_RAMBOOT #define CONFIG_ENV_IS_IN_FLASH 1 - #define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE + 0x60000) + #define CONFIG_ENV_ADDR \ + (CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) #define CONFIG_ENV_SECT_SIZE 0x10000 /* 64K(one sector) for env */ #else #define CONFIG_ENV_IS_NOWHERE 1 /* Store ENV in memory only */ diff --git a/include/configs/T208xRDB.h b/include/configs/T208xRDB.h index faaf22c..107efdc 100644 --- a/include/configs/T208xRDB.h +++ b/include/configs/T208xRDB.h @@ -140,6 +140,11 @@ #define CONFIG_MEM_INIT_VALUE 0xdeadbeef #endif +#define CONFIG_CMD_MEMTEST +#define CONFIG_SYS_MEMTEST_START 0x00200000 /* memtest works on */ +#define CONFIG_SYS_MEMTEST_END 0x00400000 +#define CONFIG_SYS_ALT_MEMTEST + #ifndef CONFIG_SYS_NO_FLASH #define CONFIG_FLASH_CFI_DRIVER #define CONFIG_SYS_FLASH_CFI @@ -448,6 +453,17 @@ unsigned long get_board_ddr_clk(void); #define I2C_MUX_PCA_ADDR_SEC2 0x76 /* I2C bus multiplexer,secondary 2 */ #define I2C_MUX_CH_DEFAULT 0x8 +#define I2C_MUX_CH_VOL_MONITOR 0xa + +#define CONFIG_VID_FLS_ENV "t208xrdb_vdd_mv" +#ifndef CONFIG_SPL_BUILD +#define CONFIG_VID +#endif +#define CONFIG_VOL_MONITOR_IR36021_SET +#define CONFIG_VOL_MONITOR_IR36021_READ +/* The lowest and highest voltage allowed for T208xRDB */ +#define VDD_MV_MIN 819 +#define VDD_MV_MAX 1212 /* * RapidIO @@ -646,8 +662,8 @@ unsigned long get_board_ddr_clk(void); #ifdef CONFIG_SYS_DPAA_FMAN #define CONFIG_FMAN_ENET #define CONFIG_PHYLIB_10G +#define CONFIG_PHY_AQUANTIA #define CONFIG_PHY_CORTINA -#define CONFIG_PHY_AQ1202 #define CONFIG_PHY_REALTEK #define CONFIG_CORTINA_FW_LENGTH 0x40000 #define RGMII_PHY1_ADDR 0x01 /* RealTek RTL8211E */ diff --git a/include/configs/T4240RDB.h b/include/configs/T4240RDB.h index c1ad35a..957a436 100644 --- a/include/configs/T4240RDB.h +++ b/include/configs/T4240RDB.h @@ -638,6 +638,7 @@ unsigned long get_board_ddr_clk(void); #define CONFIG_PHYLIB_10G #define CONFIG_PHY_VITESSE #define CONFIG_PHY_CORTINA +#define CONFIG_SYS_CORTINA_FW_IN_NOR #define CONFIG_CORTINA_FW_ADDR 0xefe00000 #define CONFIG_CORTINA_FW_LENGTH 0x40000 #define CONFIG_PHY_TERANETICS diff --git a/include/configs/amcore.h b/include/configs/amcore.h index 229fa5a..5a06311 100644 --- a/include/configs/amcore.h +++ b/include/configs/amcore.h @@ -98,6 +98,10 @@ #define CONFIG_ENV_SIZE 0x1000 #define CONFIG_ENV_SECT_SIZE 0x1000 +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text*); + /* memory map space for linux boot data */ #define CONFIG_SYS_BOOTMAPSZ (8 << 20) diff --git a/include/configs/aristainetos.h b/include/configs/aristainetos.h index 3066fd0..cc26790 100644 --- a/include/configs/aristainetos.h +++ b/include/configs/aristainetos.h @@ -262,6 +262,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 #define CONFIG_SYS_I2C_SLAVE 0x7f #define CONFIG_SYS_I2C_NOPROBES { {0, 0x00} } diff --git a/include/configs/astro_mcf5373l.h b/include/configs/astro_mcf5373l.h index de837cf..7b9ff8f 100644 --- a/include/configs/astro_mcf5373l.h +++ b/include/configs/astro_mcf5373l.h @@ -343,6 +343,10 @@ #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 1 #define CONFIG_SYS_FLASH_CFI_NONBLOCK 1 +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text*) + #if ENABLE_JFFS /* JFFS Partition offset set */ #define CONFIG_SYS_JFFS2_FIRST_BANK 0 diff --git a/include/configs/axs101.h b/include/configs/axs101.h index 8a7095c..389f75b 100644 --- a/include/configs/axs101.h +++ b/include/configs/axs101.h @@ -116,7 +116,6 @@ /* * Ethernet configuration */ -#define CONFIG_DESIGNWARE_ETH #define CONFIG_DW_AUTONEG #define CONFIG_NET_MULTI diff --git a/include/configs/bf609-ezkit.h b/include/configs/bf609-ezkit.h index 878009f..7507d57 100644 --- a/include/configs/bf609-ezkit.h +++ b/include/configs/bf609-ezkit.h @@ -71,7 +71,6 @@ #define CONFIG_NETCONSOLE #define CONFIG_NET_MULTI #define CONFIG_HOSTNAME "bf609-ezkit" -#define CONFIG_DESIGNWARE_ETH #define CONFIG_PHY_ADDR 1 #define CONFIG_DW_PORTS 1 #define CONFIG_DW_ALTDESCRIPTOR diff --git a/include/configs/chromebook_link.h b/include/configs/chromebook_link.h index 7b460e8..5265787 100644 --- a/include/configs/chromebook_link.h +++ b/include/configs/chromebook_link.h @@ -14,65 +14,6 @@ #define __CONFIG_H #include <configs/x86-common.h> - - -#define CONFIG_SYS_MONITOR_LEN (1 << 20) - -#define CONFIG_DCACHE_RAM_MRC_VAR_SIZE 0x4000 -#define CONFIG_BOARD_EARLY_INIT_F -#define CONFIG_MISC_INIT_R - -#define CONFIG_NR_DRAM_BANKS 8 -#define CONFIG_X86_MRC_ADDR 0xfffa0000 -#define CONFIG_CACHE_MRC_SIZE_KB 512 - -#define CONFIG_X86_SERIAL - -#define CONFIG_SCSI_DEV_LIST {PCI_VENDOR_ID_INTEL, \ - PCI_DEVICE_ID_INTEL_NM10_AHCI}, \ - {PCI_VENDOR_ID_INTEL, \ - PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_MOBILE}, \ - {PCI_VENDOR_ID_INTEL, \ - PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_SERIES6}, \ - {PCI_VENDOR_ID_INTEL, \ - PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE} - -#define CONFIG_X86_OPTION_ROM_FILE pci8086,0166.bin -#define CONFIG_X86_OPTION_ROM_ADDR 0xfff90000 - -#define CONFIG_PCI_MEM_BUS 0xe0000000 -#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS -#define CONFIG_PCI_MEM_SIZE 0x10000000 - -#define CONFIG_PCI_PREF_BUS 0xd0000000 -#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS -#define CONFIG_PCI_PREF_SIZE 0x10000000 - -#define CONFIG_PCI_IO_BUS 0x1000 -#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS -#define CONFIG_PCI_IO_SIZE 0xefff - -#define CONFIG_SYS_EARLY_PCI_INIT -#define CONFIG_PCI_PNP - -#define CONFIG_BIOSEMU -#define VIDEO_IO_OFFSET 0 -#define CONFIG_X86EMU_RAW_IO - -#define CONFIG_CROS_EC -#define CONFIG_CROS_EC_LPC -#define CONFIG_CMD_CROS_EC -#define CONFIG_ARCH_EARLY_INIT_R - -#undef CONFIG_ENV_IS_NOWHERE -#undef CONFIG_ENV_SIZE -#define CONFIG_ENV_SIZE 0x1000 -#define CONFIG_ENV_SECT_SIZE 0x1000 -#define CONFIG_ENV_IS_IN_SPI_FLASH -#define CONFIG_ENV_OFFSET 0x003f8000 - -#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \ - "stdout=vga,serial\0" \ - "stderr=vga,serial\0" +#include <configs/x86-chromebook.h> #endif /* __CONFIG_H */ diff --git a/include/configs/chromebox_panther.h b/include/configs/chromebox_panther.h new file mode 100644 index 0000000..00fe26d --- /dev/null +++ b/include/configs/chromebox_panther.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include <configs/x86-common.h> +#include <configs/x86-chromebook.h> + +#define CONFIG_RTL8169 +/* Avoid a warning in the Realtek Ethernet driver */ +#define CONFIG_SYS_CACHELINE_SIZE 16 + +#endif /* __CONFIG_H */ diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index 4207504..d6e5a2b 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -245,6 +245,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 #define CONFIG_SYS_MXC_I2C3_SPEED 400000 diff --git a/include/configs/cobra5272.h b/include/configs/cobra5272.h index b9f0b0b..38fcc40 100644 --- a/include/configs/cobra5272.h +++ b/include/configs/cobra5272.h @@ -104,6 +104,9 @@ #define CONFIG_ENV_IS_IN_FLASH 1 #endif +#define LDS_BOARD_TEXT \ + . = DEFINED(env_offset) ? env_offset : .; \ + common/env_embedded.o (.text); /* * BOOTP options diff --git a/include/configs/colibri_vf.h b/include/configs/colibri_vf.h new file mode 100644 index 0000000..414600a --- /dev/null +++ b/include/configs/colibri_vf.h @@ -0,0 +1,271 @@ +/* + * Copyright 2015 Toradex, Inc. + * + * Configuration settings for the Toradex VF50/VF61 module. + * + * Based on vf610twr.h: + * Copyright 2013 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include <asm/arch/imx-regs.h> +#include <config_cmd_default.h> + +#define CONFIG_VF610 +#define CONFIG_SYS_THUMB_BUILD +#define CONFIG_USE_ARCH_MEMCPY +#define CONFIG_USE_ARCH_MEMSET + +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_ARCH_MISC_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +#define CONFIG_SKIP_LOWLEVEL_INIT + +#define CONFIG_CMD_FUSE +#ifdef CONFIG_CMD_FUSE +#define CONFIG_MXC_OCOTP +#endif + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024) + +#define CONFIG_BOARD_EARLY_INIT_F + +#define CONFIG_FSL_LPUART +#define LPUART_BASE UART0_BASE + +/* Allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +#define CONFIG_VERSION_VARIABLE +#define CONFIG_SYS_UART_PORT (0) +#define CONFIG_BAUDRATE 115200 +#define CONFIG_CMD_ASKENV + +/* NAND support */ +#define CONFIG_CMD_NAND +#define CONFIG_NAND_VF610_NFC +#define CONFIG_SYS_NAND_SELF_INIT +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_SYS_NAND_BASE NFC_BASE_ADDR + +/* Dynamic MTD partition support */ +#define CONFIG_CMD_MTDPARTS /* Enable 'mtdparts' command line support */ +#define CONFIG_MTD_PARTITIONS +#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */ +#define MTDIDS_DEFAULT "nand0=vf610_nfc" +#define MTDPARTS_DEFAULT "mtdparts=vf610_nfc:" \ + "128k(vf-bcb)ro," \ + "1408k(u-boot)ro," \ + "512k(u-boot-env)," \ + "-(ubi)" + +#undef CONFIG_CMD_IMLS + +#define CONFIG_MMC +#define CONFIG_FSL_ESDHC +#define CONFIG_SYS_FSL_ESDHC_ADDR 0 +#define CONFIG_SYS_FSL_ESDHC_NUM 1 + +#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 + +#define CONFIG_CMD_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_CMD_FAT +#define CONFIG_CMD_EXT3 +#define CONFIG_CMD_EXT4 +#define CONFIG_DOS_PARTITION + +#define CONFIG_RBTREE +#define CONFIG_LZO +#define CONFIG_CMD_FS_GENERIC +#define CONFIG_CMD_BOOTZ +#define CONFIG_CMD_UBI +#define CONFIG_MTD_UBI_FASTMAP +#define CONFIG_CMD_UBIFS /* increases size by almost 60 KB */ + +#define CONFIG_CMD_PING +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_MII +#define CONFIG_CMD_NET +#define CONFIG_FEC_MXC +#define CONFIG_MII +#define IMX_FEC_BASE ENET1_BASE_ADDR +#define CONFIG_FEC_XCV_TYPE RMII +#define CONFIG_FEC_MXC_PHYADDR 0 +#define CONFIG_PHYLIB +#define CONFIG_PHY_MICREL + +#define CONFIG_IPADDR 192.168.10.2 +#define CONFIG_NETMASK 255.255.255.0 +#define CONFIG_SERVERIP 192.168.10.1 + +#define CONFIG_BOOTDELAY 1 +#define CONFIG_BOARD_LATE_INIT + +#define CONFIG_LOADADDR 0x80008000 +#define CONFIG_FDTADDR 0x84000000 + +/* We boot from the gfxRAM area of the OCRAM. */ +#define CONFIG_SYS_TEXT_BASE 0x3f408000 +#define CONFIG_BOARD_SIZE_LIMIT 524288 + +#define SD_BOOTCMD \ + "sdargs=root=/dev/mmcblk0p2 rw rootwait\0" \ + "sdboot=run setup; setenv bootargs ${defargs} ${sdargs} ${mtdparts} " \ + "${setupargs} ${vidargs}; echo Booting from MMC/SD card...; " \ + "load mmc 0:2 ${kernel_addr_r} /boot/${kernel_file} && " \ + "load mmc 0:2 ${fdt_addr_r} /boot/${soc}-colibri-${fdt_board}.dtb && " \ + "bootz ${kernel_addr_r} - ${fdt_addr_r}\0" \ + +#define NFS_BOOTCMD \ + "nfsargs=ip=:::::eth0: root=/dev/nfs\0" \ + "nfsboot=run setup; " \ + "setenv bootargs ${defargs} ${nfsargs} ${mtdparts} " \ + "${setupargs} ${vidargs}; echo Booting from NFS...;" \ + "dhcp ${kernel_addr_r} && " \ + "tftp ${fdt_addr_r} ${soc}-colibri-${fdt_board}.dtb && " \ + "bootz ${kernel_addr_r} - ${fdt_addr_r}\0" \ + +#define UBI_BOOTCMD \ + "ubiargs=ubi.mtd=ubi root=ubi0:rootfs rootfstype=ubifs " \ + "ubi.fm_autoconvert=1\0" \ + "ubiboot=run setup; " \ + "setenv bootargs ${defargs} ${ubiargs} ${mtdparts} " \ + "${setupargs} ${vidargs}; echo Booting from NAND...; " \ + "ubi part ubi && ubifsmount ubi0:rootfs && " \ + "ubifsload ${kernel_addr_r} /boot/${kernel_file} && " \ + "ubifsload ${fdt_addr_r} /boot/${soc}-colibri-${fdt_board}.dtb && " \ + "bootz ${kernel_addr_r} - ${fdt_addr_r}\0" \ + +#define CONFIG_BOOTCOMMAND "run ubiboot; run sdboot; run nfsboot" + +#define DFU_ALT_NAND_INFO "vf-bcb part 0,1;u-boot part 0,2;ubi part 0,4" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "kernel_addr_r=0x82000000\0" \ + "fdt_addr_r=0x84000000\0" \ + "kernel_file=zImage\0" \ + "fdt_file=${soc}-colibri-${fdt_board}.dtb\0" \ + "fdt_board=eval-v3\0" \ + "defargs=\0" \ + "console=ttyLP0\0" \ + "setup=setenv setupargs " \ + "console=tty1 console=${console}" \ + ",${baudrate}n8 ${memargs}\0" \ + "setsdupdate=mmc rescan && set interface mmc && " \ + "fatload ${interface} 0:1 ${loadaddr} flash_blk.img && " \ + "source ${loadaddr}\0" \ + "setusbupdate=usb start && set interface usb && " \ + "fatload ${interface} 0:1 ${loadaddr} flash_blk.img && " \ + "source ${loadaddr}\0" \ + "setupdate=run setsdupdate || run setusbupdate\0" \ + "mtdparts=" MTDPARTS_DEFAULT "\0" \ + "dfu_alt_info=" DFU_ALT_NAND_INFO "\0" \ + SD_BOOTCMD \ + NFS_BOOTCMD \ + UBI_BOOTCMD + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_SYS_PROMPT "Colibri VFxx # " +#undef CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE \ + (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + +#define CONFIG_CMD_MEMTEST +#define CONFIG_SYS_MEMTEST_START 0x80010000 +#define CONFIG_SYS_MEMTEST_END 0x87C00000 + +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR +#define CONFIG_SYS_HZ 1000 +#define CONFIG_CMDLINE_EDITING + +/* + * Stack sizes + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128 * 1024) /* regular stack */ + +/* Physical memory map */ +#define CONFIG_NR_DRAM_BANKS 1 +#define PHYS_SDRAM (0x80000000) +#define PHYS_SDRAM_SIZE (256 * 1024 * 1024) + +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM +#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE + +#define CONFIG_SYS_INIT_SP_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) + +/* Environment organization */ +#define CONFIG_SYS_NO_FLASH + +#ifdef CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_ENV_OFFSET (12 * 64 * 1024) +#define CONFIG_ENV_SIZE (8 * 1024) +#endif + +#ifdef CONFIG_ENV_IS_IN_NAND +#define CONFIG_ENV_SIZE (64 * 2048) +#define CONFIG_ENV_RANGE (4 * 64 * 2048) +#define CONFIG_ENV_OFFSET (12 * 64 * 2048) +#endif + +#define CONFIG_OF_LIBFDT +#define CONFIG_CMD_BOOTZ + +#define CONFIG_SYS_NO_FLASH + +#define CONFIG_SYS_CACHELINE_SIZE 32 + +/* USB Host Support */ +#define CONFIG_CMD_USB +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_VF +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2 +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET + +/* USB Client Support */ +#define CONFIG_USB_GADGET +#define CONFIG_CI_UDC +#define CONFIG_USB_GADGET_DUALSPEED +#define CONFIG_USB_GADGET_VBUS_DRAW 2 +#define CONFIG_TRDX_VID 0x1B67 +#define CONFIG_TRDX_PID_COLIBRI_VF50 0x0016 +#define CONFIG_TRDX_PID_COLIBRI_VF61 0x0017 +#define CONFIG_TRDX_PID_COLIBRI_VF61IT 0x0018 +#define CONFIG_TRDX_PID_COLIBRI_VF50IT 0x0019 +#define CONFIG_G_DNL_MANUFACTURER "Toradex" +#define CONFIG_G_DNL_VENDOR_NUM CONFIG_TRDX_VID +#define CONFIG_G_DNL_PRODUCT_NUM CONFIG_TRDX_PID_COLIBRI_VF50 + +/* USB DFU */ +#define CONFIG_USBDOWNLOAD_GADGET +#define CONFIG_CMD_DFU +#define CONFIG_DFU_FUNCTION +#define CONFIG_DFU_NAND +#define CONFIG_DFU_MMC +#define CONFIG_SYS_DFU_DATA_BUF_SIZE (1024 * 1024) + +/* USB Storage */ +#define CONFIG_USB_STORAGE +#define CONFIG_USB_GADGET_MASS_STORAGE +#define CONFIG_CMD_USB_MASS_STORAGE + +#endif /* __CONFIG_H */ diff --git a/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h index 1683a15..4dd7b11 100644 --- a/include/configs/db-mv784mp-gp.h +++ b/include/configs/db-mv784mp-gp.h @@ -37,7 +37,7 @@ /* I2C */ #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MVTWSI -#define CONFIG_I2C_MVTWSI_BASE MVEBU_TWSI_BASE +#define CONFIG_I2C_MVTWSI_BASE0 MVEBU_TWSI_BASE #define CONFIG_SYS_I2C_SLAVE 0x0 #define CONFIG_SYS_I2C_SPEED 100000 diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h index e78cc69..d79612b 100644 --- a/include/configs/dra7xx_evm.h +++ b/include/configs/dra7xx_evm.h @@ -84,6 +84,14 @@ DFU_ALT_INFO_EMMC \ DFU_ALT_INFO_RAM +/* Fastboot */ +#define CONFIG_CMD_FASTBOOT +#define CONFIG_ANDROID_BOOT_IMAGE +#define CONFIG_USB_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR +#define CONFIG_USB_FASTBOOT_BUF_SIZE 0x2F000000 +#define CONFIG_FASTBOOT_FLASH +#define CONFIG_FASTBOOT_FLASH_MMC_DEV 1 + #include <configs/ti_omap5_common.h> /* Enhance our eMMC support / experience. */ @@ -182,8 +190,8 @@ #define CONFIG_USBDOWNLOAD_GADGET #define CONFIG_USB_GADGET_VBUS_DRAW 2 #define CONFIG_G_DNL_MANUFACTURER "Texas Instruments" -#define CONFIG_G_DNL_VENDOR_NUM 0x0403 -#define CONFIG_G_DNL_PRODUCT_NUM 0xBD00 +#define CONFIG_G_DNL_VENDOR_NUM 0x0451 +#define CONFIG_G_DNL_PRODUCT_NUM 0xd022 #define CONFIG_USB_GADGET_DUALSPEED /* USB Device Firmware Update support */ diff --git a/include/configs/edminiv2.h b/include/configs/edminiv2.h index 5ce01fb..bd08740 100644 --- a/include/configs/edminiv2.h +++ b/include/configs/edminiv2.h @@ -208,7 +208,7 @@ #ifdef CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MVTWSI -#define CONFIG_I2C_MVTWSI_BASE ORION5X_TWSI_BASE +#define CONFIG_I2C_MVTWSI_BASE0 ORION5X_TWSI_BASE #define CONFIG_SYS_I2C_SLAVE 0x0 #define CONFIG_SYS_I2C_SPEED 100000 #endif diff --git a/include/configs/embestmx6boards.h b/include/configs/embestmx6boards.h index b4b3ae8..e9f5bed 100644 --- a/include/configs/embestmx6boards.h +++ b/include/configs/embestmx6boards.h @@ -55,6 +55,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 /* USB Configs */ diff --git a/include/configs/exynos5250-common.h b/include/configs/exynos5250-common.h index ae0e5ff..95e96ec 100644 --- a/include/configs/exynos5250-common.h +++ b/include/configs/exynos5250-common.h @@ -28,16 +28,6 @@ #define CONFIG_SYS_INIT_SP_ADDR CONFIG_IRAM_STACK -/* Sound */ -#define CONFIG_CMD_SOUND -#ifdef CONFIG_CMD_SOUND -#define CONFIG_SOUND -#define CONFIG_I2S_SAMSUNG -#define CONFIG_I2S -#define CONFIG_SOUND_MAX98095 -#define CONFIG_SOUND_WM8994 -#endif - /* I2C */ #define CONFIG_MAX_I2C_NUM 8 diff --git a/include/configs/exynos5420-common.h b/include/configs/exynos5420-common.h index b42dab7..3b1ac2c 100644 --- a/include/configs/exynos5420-common.h +++ b/include/configs/exynos5420-common.h @@ -15,8 +15,6 @@ #include <configs/exynos5-common.h> -#define CONFIG_ARCH_EARLY_INIT_R - #define MACH_TYPE_SMDK5420 8002 #define CONFIG_MACH_TYPE MACH_TYPE_SMDK5420 diff --git a/include/configs/flea3.h b/include/configs/flea3.h index 854ae90..5f7cad8 100644 --- a/include/configs/flea3.h +++ b/include/configs/flea3.h @@ -52,6 +52,7 @@ */ #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_SPD_BUS_NUM 2 /* I2C3 */ #define CONFIG_SYS_MXC_I2C3_SLAVE 0xfe #define CONFIG_MXC_SPI diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h index 620f950..fcfc1b3 100644 --- a/include/configs/gw_ventana.h +++ b/include/configs/gw_ventana.h @@ -95,9 +95,11 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 #define CONFIG_I2C_GSC 0 #define CONFIG_I2C_PMIC 1 +#define CONFIG_I2C_EDID /* MMC Configs */ #define CONFIG_FSL_ESDHC @@ -111,15 +113,12 @@ /* Filesystem support */ #define CONFIG_CMD_EXT2 +#define CONFIG_CMD_EXT4 +#define CONFIG_CMD_EXT4_WRITE #define CONFIG_CMD_FAT #define CONFIG_CMD_UBIFS #define CONFIG_DOS_PARTITION -/* Network config - Allow larger/faster download for TFTP/NFS */ -#define CONFIG_IP_DEFRAG -#define CONFIG_TFTP_BLOCKSIZE 4096 -#define CONFIG_NFS_READ_SIZE 4096 - /* * SATA Configs */ @@ -179,10 +178,10 @@ /* Ethernet support */ #define CONFIG_FEC_MXC +#define CONFIG_E1000 #define CONFIG_MII #define IMX_FEC_BASE ENET_BASE_ADDR #define CONFIG_FEC_XCV_TYPE RGMII -#define CONFIG_ETHPRIME "FEC" #define CONFIG_FEC_MXC_PHYADDR 0 #define CONFIG_PHYLIB #define CONFIG_ARP_TIMEOUT 200UL @@ -208,6 +207,18 @@ #define CONFIG_NETCONSOLE #define CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP +/* USB Mass Storage Gadget */ +#define CONFIG_USB_GADGET +#define CONFIG_CMD_USB_MASS_STORAGE +#define CONFIG_USB_GADGET_MASS_STORAGE +#define CONFIG_USBDOWNLOAD_GADGET +#define CONFIG_USB_GADGET_VBUS_DRAW 2 + +/* Netchip IDs */ +#define CONFIG_G_DNL_VENDOR_NUM 0x0525 +#define CONFIG_G_DNL_PRODUCT_NUM 0xa4a5 +#define CONFIG_G_DNL_MANUFACTURER "Gateworks" + /* Framebuffer and LCD */ #define CONFIG_VIDEO #define CONFIG_VIDEO_IPUV3 @@ -316,6 +327,7 @@ "dio0:mode=gpio;dio1:mode=gpio;dio2:mode=gpio;dio3:mode=gpio\0" \ #define CONFIG_EXTRA_ENV_SETTINGS_COMMON \ + "usb_pgood_delay=2000\0" \ "console=ttymxc1\0" \ "bootdevs=usb mmc sata flash\0" \ HWCONFIG_DEFAULT \ @@ -326,28 +338,30 @@ \ "fdt_high=0xffffffff\0" \ "fdt_addr=0x18000000\0" \ + "initrd_high=0xffffffff\0" \ + "bootdir=boot\0" \ "loadfdt=" \ - "if ${fsload} ${fdt_addr} boot/${fdt_file}; then " \ - "echo Loaded DTB from boot/${fdt_file}; " \ - "elif ${fsload} ${fdt_addr} boot/${fdt_file1}; then " \ - "echo Loaded DTB from boot/${fdt_file1}; " \ - "elif ${fsload} ${fdt_addr} boot/${fdt_file2}; then " \ - "echo Loaded DTB from boot/${fdt_file2}; " \ + "if ${fsload} ${fdt_addr} ${bootdir}/${fdt_file}; then " \ + "echo Loaded DTB from ${bootdir}/${fdt_file}; " \ + "elif ${fsload} ${fdt_addr} ${bootdir}/${fdt_file1}; then " \ + "echo Loaded DTB from ${bootdir}/${fdt_file1}; " \ + "elif ${fsload} ${fdt_addr} ${bootdir}/${fdt_file2}; then " \ + "echo Loaded DTB from ${bootdir}/${fdt_file2}; " \ "fi\0" \ \ - "script=boot/6x_bootscript-ventana\0" \ + "script=6x_bootscript-ventana\0" \ "loadscript=" \ - "if ${fsload} ${loadaddr} ${script}; then " \ + "if ${fsload} ${loadaddr} ${bootdir}/${script}; then " \ "source; " \ "fi\0" \ \ - "uimage=boot/uImage\0" \ + "uimage=uImage\0" \ "mmc_root=/dev/mmcblk0p1 rootfstype=ext4 rootwait rw\0" \ "mmc_boot=" \ "setenv fsload 'ext2load mmc 0:1'; " \ "mmc dev 0 && mmc rescan && " \ "run loadscript; " \ - "if ${fsload} ${loadaddr} ${uimage}; then " \ + "if ${fsload} ${loadaddr} ${bootdir}/${uimage}; then " \ "setenv bootargs console=${console},${baudrate} " \ "root=/dev/mmcblk0p1 rootfstype=ext4 " \ "rootwait rw ${video} ${extra}; " \ @@ -361,7 +375,7 @@ "sata_boot=" \ "setenv fsload 'ext2load sata 0:1'; sata init && " \ "run loadscript; " \ - "if ${fsload} ${loadaddr} ${uimage}; then " \ + "if ${fsload} ${loadaddr} ${bootdir}/${uimage}; then " \ "setenv bootargs console=${console},${baudrate} " \ "root=/dev/sda1 rootfstype=ext4 " \ "rootwait rw ${video} ${extra}; " \ @@ -374,7 +388,7 @@ "usb_boot=" \ "setenv fsload 'ext2load usb 0:1'; usb start && usb dev 0 && " \ "run loadscript; " \ - "if ${fsload} ${loadaddr} ${uimage}; then " \ + "if ${fsload} ${loadaddr} ${bootdir}/${uimage}; then " \ "setenv bootargs console=${console},${baudrate} " \ "root=/dev/sda1 rootfstype=ext4 " \ "rootwait rw ${video} ${extra}; " \ @@ -417,8 +431,8 @@ #else #define CONFIG_EXTRA_ENV_SETTINGS \ CONFIG_EXTRA_ENV_SETTINGS_COMMON \ - "image_rootfs=openwrt-imx6-ventana-rootfs.ubi\0" \ \ + "image_rootfs=openwrt-imx6-ventana-rootfs.ubi\0" \ "nand_update=echo Updating NAND from ${serverip}:${image_rootfs}...; " \ "tftp ${loadaddr} ${image_rootfs} && " \ "nand erase.part rootfs && " \ @@ -426,12 +440,21 @@ \ "flash_boot=" \ "setenv fsload 'ubifsload'; " \ - "ubi part rootfs && ubifsmount ubi0:rootfs; " \ + "ubi part rootfs; " \ + "if ubi check boot; then " \ + "ubifsmount ubi0:boot; " \ + "setenv root ubi0:rootfs ubi.mtd=2 " \ + "rootfstype=squashfs,ubifs; " \ + "setenv bootdir; " \ + "elif ubi check rootfs; then " \ + "ubifsmount ubi0:rootfs; " \ + "setenv root ubi0:rootfs ubi.mtd=2 " \ + "rootfstype=ubifs; " \ + "fi; " \ "run loadscript; " \ - "if ${fsload} ${loadaddr} ${uimage}; then " \ + "if ${fsload} ${loadaddr} ${bootdir}/${uimage}; then " \ "setenv bootargs console=${console},${baudrate} " \ - "root=ubi0:rootfs ubi.mtd=2 " \ - "rootfstype=ubifs ${video} ${extra}; " \ + "root=${root} ${video} ${extra}; " \ "if run loadfdt && fdt addr ${fdt_addr}; then " \ "ubifsumount; " \ "bootm ${loadaddr} - ${fdt_addr}; " \ diff --git a/include/configs/imx31_phycore.h b/include/configs/imx31_phycore.h index 49039d6..db197f3 100644 --- a/include/configs/imx31_phycore.h +++ b/include/configs/imx31_phycore.h @@ -38,6 +38,7 @@ #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_CLK_OFFSET I2C2_CLK_OFFSET #define CONFIG_MXC_UART diff --git a/include/configs/integrator-common.h b/include/configs/integrator-common.h index 4362925..12c7382 100644 --- a/include/configs/integrator-common.h +++ b/include/configs/integrator-common.h @@ -7,8 +7,6 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#define CONFIG_INTEGRATOR - #define CONFIG_SYS_TEXT_BASE 0x01000000 #define CONFIG_SYS_MEMTEST_START 0x100000 #define CONFIG_SYS_MEMTEST_END 0x10000000 diff --git a/include/configs/integratorap.h b/include/configs/integratorap.h index e168c8c..8439db7 100644 --- a/include/configs/integratorap.h +++ b/include/configs/integratorap.h @@ -18,7 +18,6 @@ #include "integrator-common.h" /* Integrator/AP-specific configuration */ -#define CONFIG_ARCH_INTEGRATOR #define CONFIG_SYS_HZ_CLOCK 24000000 /* Timer 1 is clocked at 24Mhz */ /* diff --git a/include/configs/integratorcp.h b/include/configs/integratorcp.h index 7c1ef24..7518b60 100644 --- a/include/configs/integratorcp.h +++ b/include/configs/integratorcp.h @@ -18,7 +18,6 @@ #include "integrator-common.h" /* Integrator CP-specific configuration */ -#define CONFIG_ARCH_CINTEGRATOR #define CONFIG_SYS_HZ_CLOCK 1000000 /* Timer 1 is clocked at 1Mhz */ /* diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h index 5de416d..9a8fd50 100644 --- a/include/configs/ls1021aqds.h +++ b/include/configs/ls1021aqds.h @@ -389,6 +389,7 @@ unsigned long get_board_ddr_clk(void); #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ /* * I2C bus multiplexer @@ -655,6 +656,7 @@ unsigned long get_board_ddr_clk(void); #ifdef CONFIG_SECURE_BOOT #define CONFIG_CMD_BLOB +#include <asm/fsl_secure_boot.h> #endif #endif diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h index a13876b..729205f 100644 --- a/include/configs/ls1021atwr.h +++ b/include/configs/ls1021atwr.h @@ -205,6 +205,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ /* EEPROM */ #ifndef CONFIG_SD_BOOT diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index e0435cc..e270fc8 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -19,8 +19,20 @@ #define CONFIG_ARM_ERRATA_828024 #define CONFIG_ARM_ERRATA_826974 +#include <asm/arch-fsl-lsch3/config.h> +#if (defined(CONFIG_SYS_FSL_SRDS_1) || defined(CONFIG_SYS_FSL_SRDS_2)) +#define CONFIG_SYS_HAS_SERDES +#endif + +/* We need architecture specific misc initializations */ +#define CONFIG_ARCH_MISC_INIT + /* Link Definitions */ -#define CONFIG_SYS_TEXT_BASE 0x30001000 +#ifdef CONFIG_SPL +#define CONFIG_SYS_TEXT_BASE 0x80400000 +#else +#define CONFIG_SYS_TEXT_BASE 0x30100000 +#endif #ifdef CONFIG_EMU #define CONFIG_SYS_NO_FLASH @@ -39,13 +51,13 @@ #define CONFIG_FIT #define CONFIG_FIT_VERBOSE /* enable fit_format_{error,warning}() */ +#ifndef CONFIG_SPL #define CONFIG_FSL_DDR_INTERACTIVE /* Interactive debugging */ +#endif #ifndef CONFIG_SYS_FSL_DDR4 #define CONFIG_SYS_FSL_DDR3 /* Use DDR3 memory */ #define CONFIG_SYS_DDR_RAW_TIMING #endif -#define CONFIG_DIMM_SLOTS_PER_CTLR 1 -#define CONFIG_CHIP_SELECTS_PER_CTRL 4 #define CONFIG_SYS_FSL_DDR_INTLV_256B /* force 256 byte interleaving */ @@ -69,23 +81,26 @@ #define CONFIG_SYS_DP_DDR_BASE_PHY 0 #define CONFIG_DP_DDR_CTRL 2 #define CONFIG_DP_DDR_NUM_CTRLS 1 -#define CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR 1 /* Generic Timer Definitions */ -#define COUNTER_FREQUENCY 12000000 /* 12MHz */ +/* + * This is not an accurate number. It is used in start.S. The frequency + * will be udpated later when get_bus_freq(0) is available. + */ +#define COUNTER_FREQUENCY 25000000 /* 25MHz */ /* Size of malloc() pool */ -#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128 * 1024) +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2048 * 1024) /* I2C */ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC -#define CONFIG_SYS_MXC_I2C1_SPEED 40000000 -#define CONFIG_SYS_MXC_I2C2_SPEED 40000000 +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ +#define CONFIG_SYS_I2C_MXC_I2C4 /* enable I2C bus 4 */ /* Serial Port */ -#define CONFIG_CONS_INDEX 2 +#define CONFIG_CONS_INDEX 1 #define CONFIG_SYS_NS16550 #define CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550_REG_SIZE 1 @@ -96,131 +111,98 @@ /* IFC */ #define CONFIG_FSL_IFC -#define CONFIG_SYS_NOR0_CSPR_EXT (0x0) -#define CONFIG_SYS_NOR_AMASK IFC_AMASK(128*1024*1024) + /* - * During booting, CS0 needs to be at the region of 0x30000000, i.e. the IFC - * address 0. But this region is limited to 256MB. To accommodate bigger NOR - * flash and other devices, we will map CS0 to 0x580000000 after relocation. + * During booting, IFC is mapped at the region of 0x30000000. + * But this region is limited to 256MB. To accommodate NOR, promjet + * and FPGA. This region is divided as below: + * 0x30000000 - 0x37ffffff : 128MB : NOR flash + * 0x38000000 - 0x3BFFFFFF : 64MB : Promjet + * 0x3C000000 - 0x40000000 : 64MB : FPGA etc + * + * To accommodate bigger NOR flash and other devices, we will map IFC + * chip selects to as below: + * 0x5_1000_0000..0x5_1fff_ffff Memory Hole + * 0x5_2000_0000..0x5_3fff_ffff IFC CSx (FPGA, NAND and others 512MB) + * 0x5_4000_0000..0x5_7fff_ffff ASIC or others 1GB + * 0x5_8000_0000..0x5_bfff_ffff IFC CS0 1GB (NOR/Promjet) + * 0x5_C000_0000..0x5_ffff_ffff IFC CS1 1GB (NOR/Promjet) + * + * For e.g. NOR flash at CS0 will be mapped to 0x580000000 after relocation. * CONFIG_SYS_FLASH_BASE has the final address (core view) * CONFIG_SYS_FLASH_BASE_PHYS has the final address (IFC view) * CONFIG_SYS_FLASH_BASE_PHYS_EARLY has the temporary IFC address * CONFIG_SYS_TEXT_BASE is linked to 0x30000000 for booting */ + #define CONFIG_SYS_FLASH_BASE 0x580000000ULL #define CONFIG_SYS_FLASH_BASE_PHYS 0x80000000 #define CONFIG_SYS_FLASH_BASE_PHYS_EARLY 0x00000000 -/* - * NOR Flash Timing Params - */ -#define CONFIG_SYS_NOR0_CSPR \ - (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \ - CSPR_PORT_SIZE_16 | \ - CSPR_MSEL_NOR | \ - CSPR_V) -#define CONFIG_SYS_NOR0_CSPR_EARLY \ - (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS_EARLY) | \ - CSPR_PORT_SIZE_16 | \ - CSPR_MSEL_NOR | \ - CSPR_V) -#define CONFIG_SYS_NOR_CSOR CSOR_NOR_ADM_SHIFT(12) -#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x1) | \ - FTIM0_NOR_TEADC(0x1) | \ - FTIM0_NOR_TEAHC(0x1)) -#define CONFIG_SYS_NOR_FTIM1 (FTIM1_NOR_TACO(0x1) | \ - FTIM1_NOR_TRAD_NOR(0x1)) -#define CONFIG_SYS_NOR_FTIM2 (FTIM2_NOR_TCS(0x0) | \ - FTIM2_NOR_TCH(0x0) | \ - FTIM2_NOR_TWP(0x1)) -#define CONFIG_SYS_NOR_FTIM3 0x04000000 -#define CONFIG_SYS_IFC_CCR 0x01000000 +#define CONFIG_SYS_FLASH1_BASE_PHYS 0xC0000000 +#define CONFIG_SYS_FLASH1_BASE_PHYS_EARLY 0x8000000 #ifndef CONFIG_SYS_NO_FLASH #define CONFIG_FLASH_CFI_DRIVER #define CONFIG_SYS_FLASH_CFI #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE #define CONFIG_SYS_FLASH_QUIET_TEST -#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */ - -#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* number of banks */ -#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */ -#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ -#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ +#endif -#define CONFIG_SYS_FLASH_EMPTY_INFO -#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE } +#ifndef __ASSEMBLY__ +unsigned long long get_qixis_addr(void); #endif +#define QIXIS_BASE get_qixis_addr() +#define QIXIS_BASE_PHYS 0x20000000 +#define QIXIS_BASE_PHYS_EARLY 0xC000000 +#define QIXIS_STAT_PRES1 0xb +#define QIXIS_SDID_MASK 0x07 +#define QIXIS_ESDHC_NO_ADAPTER 0x7 + +#define CONFIG_SYS_NAND_BASE 0x530000000ULL +#define CONFIG_SYS_NAND_BASE_PHYS 0x30000000 -#define CONFIG_NAND_FSL_IFC -#define CONFIG_SYS_NAND_MAX_ECCPOS 256 -#define CONFIG_SYS_NAND_MAX_OOBFREE 2 -#define CONFIG_SYS_NAND_BASE 0x520000000 -#define CONFIG_SYS_NAND_BASE_PHYS 0x20000000 - -#define CONFIG_SYS_NAND_CSPR_EXT (0x0) -#define CONFIG_SYS_NAND_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \ - | CSPR_PORT_SIZE_8 /* Port Size = 8 bit */ \ - | CSPR_MSEL_NAND /* MSEL = NAND */ \ - | CSPR_V) -#define CONFIG_SYS_NAND_AMASK IFC_AMASK(64 * 1024) - -#define CONFIG_SYS_NAND_CSOR (CSOR_NAND_ECC_ENC_EN /* ECC on encode */ \ - | CSOR_NAND_ECC_DEC_EN /* ECC on decode */ \ - | CSOR_NAND_ECC_MODE_4 /* 4-bit ECC */ \ - | CSOR_NAND_RAL_3 /* RAL = 2Byes */ \ - | CSOR_NAND_PGS_2K /* Page Size = 2K */ \ - | CSOR_NAND_SPRZ_64/* Spare size = 64 */ \ - | CSOR_NAND_PB(64)) /*Pages Per Block = 64*/ - -#define CONFIG_SYS_NAND_ONFI_DETECTION - -/* ONFI NAND Flash mode0 Timing Params */ -#define CONFIG_SYS_NAND_FTIM0 (FTIM0_NAND_TCCST(0x07) | \ - FTIM0_NAND_TWP(0x18) | \ - FTIM0_NAND_TWCHT(0x07) | \ - FTIM0_NAND_TWH(0x0a)) -#define CONFIG_SYS_NAND_FTIM1 (FTIM1_NAND_TADLE(0x32) | \ - FTIM1_NAND_TWBE(0x39) | \ - FTIM1_NAND_TRR(0x0e) | \ - FTIM1_NAND_TRP(0x18)) -#define CONFIG_SYS_NAND_FTIM2 (FTIM2_NAND_TRAD(0x0f) | \ - FTIM2_NAND_TREH(0x0a) | \ - FTIM2_NAND_TWHRE(0x1e)) -#define CONFIG_SYS_NAND_FTIM3 0x0 - -#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE } -#define CONFIG_SYS_MAX_NAND_DEVICE 1 -#define CONFIG_CMD_NAND - -#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024) - -#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT -#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR_EARLY -#define CONFIG_SYS_CSPR0_FINAL CONFIG_SYS_NOR0_CSPR -#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK -#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR -#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0 -#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1 -#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2 -#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3 +/* Debug Server firmware */ +#define CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024) +/* 2 sec timeout */ +#define CONFIG_SYS_DEBUG_SERVER_TIMEOUT (2 * 1000 * 1000) /* MC firmware */ #define CONFIG_FSL_MC_ENET #define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024) -#define CONFIG_SYS_LS_MC_FW_IN_NOR -#define CONFIG_SYS_LS_MC_FW_ADDR 0x580200000ULL -#define CONFIG_SYS_LS_MC_DPL_IN_NOR -#define CONFIG_SYS_LS_MC_DPL_ADDR 0x5806C0000ULL /* TODO Actual DPL max length needs to be confirmed with the MC FW team */ -#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH (256 * 1024) -#define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0xe00000 - -/* Carve the MC private DRAM block from the end of DRAM */ -#ifdef CONFIG_FSL_MC_ENET -#define CONFIG_SYS_MEM_TOP_HIDE mc_get_dram_block_size() +#define CONFIG_SYS_LS_MC_DPC_MAX_LENGTH 0x20000 +#define CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET 0x00F00000 +#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH 0x20000 +#define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0x00F20000 + +/* Carve out a DDR region which will not be used by u-boot/Linux */ +#if defined(CONFIG_FSL_MC_ENET) || defined(CONFIG_FSL_DEBUG_SERVER) +#define CONFIG_SYS_MEM_TOP_HIDE get_dram_size_to_hide() #endif +/* PCIe */ +#define CONFIG_PCIE1 /* PCIE controler 1 */ +#define CONFIG_PCIE2 /* PCIE controler 2 */ +#define CONFIG_PCIE3 /* PCIE controler 3 */ +#define CONFIG_PCIE4 /* PCIE controler 4 */ +#define FSL_PCIE_COMPAT "fsl,20851a-pcie" + +#define CONFIG_SYS_PCI_64BIT + +#define CONFIG_SYS_PCIE_CFG0_PHYS_OFF 0x00000000 +#define CONFIG_SYS_PCIE_CFG0_SIZE 0x00001000 /* 4k */ +#define CONFIG_SYS_PCIE_CFG1_PHYS_OFF 0x00001000 +#define CONFIG_SYS_PCIE_CFG1_SIZE 0x00001000 /* 4k */ + +#define CONFIG_SYS_PCIE_IO_BUS 0x00000000 +#define CONFIG_SYS_PCIE_IO_PHYS_OFF 0x00010000 +#define CONFIG_SYS_PCIE_IO_SIZE 0x00010000 /* 64k */ + +#define CONFIG_SYS_PCIE_MEM_BUS 0x40000000 +#define CONFIG_SYS_PCIE_MEM_PHYS_OFF 0x40000000 +#define CONFIG_SYS_PCIE_MEM_SIZE 0x40000000 /* 1G */ + /* Command line configuration */ #define CONFIG_CMD_CACHE #define CONFIG_CMD_BDI @@ -228,6 +210,7 @@ #define CONFIG_CMD_ENV #define CONFIG_CMD_FLASH #define CONFIG_CMD_IMI +#define CONFIG_CMD_LOADB #define CONFIG_CMD_MEMORY #define CONFIG_CMD_MII #define CONFIG_CMD_NET @@ -237,8 +220,6 @@ #define CONFIG_CMD_BOOTD #define CONFIG_CMD_ECHO #define CONFIG_CMD_SOURCE -#define CONFIG_CMD_FAT -#define CONFIG_DOS_PARTITION /* Miscellaneous configurable options */ #define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_DDR_SDRAM_BASE + 0x10000000) @@ -247,9 +228,6 @@ /* Physical Memory Map */ /* fixme: these need to be checked against the board */ #define CONFIG_CHIP_SELECTS_PER_CTRL 4 -#define CONFIG_SYS_CLK_FREQ 100000000 -#define CONFIG_DDR_CLK_FREQ 133333333 - #define CONFIG_NR_DRAM_BANKS 3 @@ -265,7 +243,7 @@ "kernel_addr=0x100000\0" \ "ramdisk_addr=0x800000\0" \ "ramdisk_size=0x2000000\0" \ - "fdt_high=0xffffffffffffffff\0" \ + "fdt_high=0xa0000000\0" \ "initrd_high=0xffffffffffffffff\0" \ "kernel_start=0x581200000\0" \ "kernel_load=0xa0000000\0" \ @@ -278,15 +256,11 @@ "hugepages=16" #define CONFIG_BOOTCOMMAND "cp.b $kernel_start $kernel_load " \ "$kernel_size && bootm $kernel_load" -#define CONFIG_BOOTDELAY 1 - -/* Store environment at top of flash */ -#define CONFIG_ENV_IS_NOWHERE 1 -#define CONFIG_ENV_SIZE 0x1000 +#define CONFIG_BOOTDELAY 10 /* Monitor Command Prompt */ #define CONFIG_SYS_CBSIZE 512 /* Console I/O Buffer Size */ -#define CONFIG_SYS_PROMPT "> " +#define CONFIG_SYS_PROMPT "=> " #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ sizeof(CONFIG_SYS_PROMPT) + 16) #define CONFIG_SYS_HUSH_PARSER @@ -294,10 +268,36 @@ #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot args buffer */ #define CONFIG_SYS_LONGHELP #define CONFIG_CMDLINE_EDITING 1 +#define CONFIG_AUTO_COMPLETE #define CONFIG_SYS_MAXARGS 64 /* max command args */ #ifndef __ASSEMBLY__ -unsigned long mc_get_dram_block_size(void); +unsigned long get_dram_size_to_hide(void); #endif +#define CONFIG_PANIC_HANG /* do not reset board on panic */ + +#define CONFIG_SPL_BSS_START_ADDR 0x80100000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x00100000 +#define CONFIG_SPL_DRIVERS_MISC_SUPPORT +#define CONFIG_SPL_ENV_SUPPORT +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_I2C_SUPPORT +#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv8/u-boot-spl.lds" +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_MAX_SIZE 0x16000 +#define CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT +#define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_STACK (CONFIG_SYS_FSL_OCRAM_BASE + 0x9ff0) +#define CONFIG_SPL_TARGET "u-boot-with-spl.bin" +#define CONFIG_SPL_TEXT_BASE 0x1800a000 + +#define CONFIG_SYS_NAND_U_BOOT_DST 0x80400000 +#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_NAND_U_BOOT_DST +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00100000 +#define CONFIG_SYS_SPL_MALLOC_START 0x80200000 +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) + #endif /* __LS2_COMMON_H */ diff --git a/include/configs/ls2085a_emu.h b/include/configs/ls2085a_emu.h index a02d694..2d68e1b 100644 --- a/include/configs/ls2085a_emu.h +++ b/include/configs/ls2085a_emu.h @@ -12,6 +12,12 @@ #define CONFIG_IDENT_STRING " LS2085A-EMU" #define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-EMU" +#define CONFIG_SYS_CLK_FREQ 100000000 +#define CONFIG_DDR_CLK_FREQ 133333333 + +#define CONFIG_SYS_MXC_I2C1_SPEED 40000000 +#define CONFIG_SYS_MXC_I2C2_SPEED 40000000 + #define CONFIG_DDR_SPD #define CONFIG_SYS_FSL_DDR_EMU /* Support emulator */ #define SPD_EEPROM_ADDRESS1 0x51 @@ -19,6 +25,65 @@ #define SPD_EEPROM_ADDRESS3 0x53 #define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1 #define CONFIG_SYS_SPD_BUS_NUM 1 /* SPD on I2C bus 1 */ +#define CONFIG_DIMM_SLOTS_PER_CTLR 1 +#define CONFIG_CHIP_SELECTS_PER_CTRL 4 +#define CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR 1 #define CONFIG_FSL_DDR_SYNC_REFRESH + +#define CONFIG_SYS_NOR0_CSPR_EXT (0x0) +#define CONFIG_SYS_NOR_AMASK IFC_AMASK(128*1024*1024) +/* + * NOR Flash Timing Params + */ +#define CONFIG_SYS_NOR0_CSPR \ + (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR0_CSPR_EARLY \ + (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS_EARLY) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR_CSOR CSOR_NOR_ADM_SHIFT(12) +#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x1) | \ + FTIM0_NOR_TEADC(0x1) | \ + FTIM0_NOR_TEAHC(0x1)) +#define CONFIG_SYS_NOR_FTIM1 (FTIM1_NOR_TACO(0x1) | \ + FTIM1_NOR_TRAD_NOR(0x1)) +#define CONFIG_SYS_NOR_FTIM2 (FTIM2_NOR_TCS(0x0) | \ + FTIM2_NOR_TCH(0x0) | \ + FTIM2_NOR_TWP(0x1)) +#define CONFIG_SYS_NOR_FTIM3 0x04000000 +#define CONFIG_SYS_IFC_CCR 0x01000000 + +#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT +#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR_EARLY +#define CONFIG_SYS_CSPR0_FINAL CONFIG_SYS_NOR0_CSPR +#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3 + +/* Debug Server firmware */ +#define CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR +#define CONFIG_SYS_DEBUG_SERVER_FW_ADDR 0x580C00000ULL + +/* + * This trick allows users to load MC images into DDR directly without + * copying from NOR flash. It dramatically improves speed. + */ +#define CONFIG_SYS_LS_MC_FW_IN_DDR +#define CONFIG_SYS_LS_MC_DPL_IN_DDR +#define CONFIG_SYS_LS_MC_DPC_IN_DDR + +#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 200000 + +/* Store environment at top of flash */ +#define CONFIG_ENV_IS_NOWHERE 1 +#define CONFIG_ENV_SIZE 0x1000 + #endif /* __LS2_EMU_H */ diff --git a/include/configs/ls2085a_simu.h b/include/configs/ls2085a_simu.h index af34f3f..d0d2eed 100644 --- a/include/configs/ls2085a_simu.h +++ b/include/configs/ls2085a_simu.h @@ -12,10 +12,112 @@ #define CONFIG_IDENT_STRING " LS2085A-SIMU" #define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-SIMU" +#define CONFIG_SYS_CLK_FREQ 100000000 +#define CONFIG_DDR_CLK_FREQ 133333333 + +#define CONFIG_SYS_MXC_I2C1_SPEED 40000000 +#define CONFIG_SYS_MXC_I2C2_SPEED 40000000 + +#define CONFIG_DIMM_SLOTS_PER_CTLR 1 +#define CONFIG_CHIP_SELECTS_PER_CTRL 4 +#define CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR 1 + /* SMSC 91C111 ethernet configuration */ #define CONFIG_SMC91111 #define CONFIG_SMC91111_BASE (0x2210000) +#define CONFIG_SYS_NOR0_CSPR_EXT (0x0) +#define CONFIG_SYS_NOR_AMASK IFC_AMASK(128*1024*1024) + +/* + * NOR Flash Timing Params + */ +#define CONFIG_SYS_NOR0_CSPR \ + (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR0_CSPR_EARLY \ + (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS_EARLY) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR_CSOR CSOR_NOR_ADM_SHIFT(12) +#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x1) | \ + FTIM0_NOR_TEADC(0x1) | \ + FTIM0_NOR_TEAHC(0x1)) +#define CONFIG_SYS_NOR_FTIM1 (FTIM1_NOR_TACO(0x1) | \ + FTIM1_NOR_TRAD_NOR(0x1)) +#define CONFIG_SYS_NOR_FTIM2 (FTIM2_NOR_TCS(0x0) | \ + FTIM2_NOR_TCH(0x0) | \ + FTIM2_NOR_TWP(0x1)) +#define CONFIG_SYS_NOR_FTIM3 0x04000000 +#define CONFIG_SYS_IFC_CCR 0x01000000 + +#ifndef CONFIG_SYS_NO_FLASH +#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */ + +#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* number of banks */ +#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */ +#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ + +#define CONFIG_SYS_FLASH_EMPTY_INFO +#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE } +#endif + +#define CONFIG_NAND_FSL_IFC +#define CONFIG_SYS_NAND_MAX_ECCPOS 256 +#define CONFIG_SYS_NAND_MAX_OOBFREE 2 + + +#define CONFIG_SYS_NAND_CSPR_EXT (0x0) +#define CONFIG_SYS_NAND_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \ + | CSPR_PORT_SIZE_8 /* Port Size = 8 bit */ \ + | CSPR_MSEL_NAND /* MSEL = NAND */ \ + | CSPR_V) +#define CONFIG_SYS_NAND_AMASK IFC_AMASK(64 * 1024) + +#define CONFIG_SYS_NAND_CSOR (CSOR_NAND_ECC_ENC_EN /* ECC on encode */ \ + | CSOR_NAND_ECC_DEC_EN /* ECC on decode */ \ + | CSOR_NAND_ECC_MODE_4 /* 4-bit ECC */ \ + | CSOR_NAND_RAL_3 /* RAL = 2Byes */ \ + | CSOR_NAND_PGS_2K /* Page Size = 2K */ \ + | CSOR_NAND_SPRZ_64/* Spare size = 64 */ \ + | CSOR_NAND_PB(64)) /*Pages Per Block = 64*/ + +#define CONFIG_SYS_NAND_ONFI_DETECTION + +/* ONFI NAND Flash mode0 Timing Params */ +#define CONFIG_SYS_NAND_FTIM0 (FTIM0_NAND_TCCST(0x07) | \ + FTIM0_NAND_TWP(0x18) | \ + FTIM0_NAND_TWCHT(0x07) | \ + FTIM0_NAND_TWH(0x0a)) +#define CONFIG_SYS_NAND_FTIM1 (FTIM1_NAND_TADLE(0x32) | \ + FTIM1_NAND_TWBE(0x39) | \ + FTIM1_NAND_TRR(0x0e) | \ + FTIM1_NAND_TRP(0x18)) +#define CONFIG_SYS_NAND_FTIM2 (FTIM2_NAND_TRAD(0x0f) | \ + FTIM2_NAND_TREH(0x0a) | \ + FTIM2_NAND_TWHRE(0x1e)) +#define CONFIG_SYS_NAND_FTIM3 0x0 + +#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE } +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_MTD_NAND_VERIFY_WRITE +#define CONFIG_CMD_NAND + +#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024) + +#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT +#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR_EARLY +#define CONFIG_SYS_CSPR0_FINAL CONFIG_SYS_NOR0_CSPR +#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3 #define CONFIG_SYS_CSPR1_EXT CONFIG_SYS_NAND_CSPR_EXT #define CONFIG_SYS_CSPR1 CONFIG_SYS_NAND_CSPR #define CONFIG_SYS_AMASK1 CONFIG_SYS_NAND_AMASK @@ -25,4 +127,24 @@ #define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_NAND_FTIM2 #define CONFIG_SYS_CS1_FTIM3 CONFIG_SYS_NAND_FTIM3 +/* Debug Server firmware */ +#define CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR +#define CONFIG_SYS_DEBUG_SERVER_FW_ADDR 0x580C00000ULL + +/* MC firmware */ +#define CONFIG_SYS_LS_MC_FW_IN_NOR +#define CONFIG_SYS_LS_MC_FW_ADDR 0x580200000ULL + +#define CONFIG_SYS_LS_MC_DPL_IN_NOR +#define CONFIG_SYS_LS_MC_DPL_ADDR 0x5806C0000ULL + +#define CONFIG_SYS_LS_MC_DPC_IN_NOR +#define CONFIG_SYS_LS_MC_DPC_ADDR 0x5806F8000ULL + +#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 200000 + +/* Store environment at top of flash */ +#define CONFIG_ENV_IS_NOWHERE 1 +#define CONFIG_ENV_SIZE 0x1000 + #endif /* __LS2_SIMU_H */ diff --git a/include/configs/ls2085aqds.h b/include/configs/ls2085aqds.h new file mode 100644 index 0000000..711d529 --- /dev/null +++ b/include/configs/ls2085aqds.h @@ -0,0 +1,359 @@ +/* + * Copyright 2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __LS2_QDS_H +#define __LS2_QDS_H + +#include "ls2085a_common.h" +#include <config_cmd_default.h> + +#define CONFIG_IDENT_STRING " LS2085A-QDS" +#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-QDS" + +#define CONFIG_DISPLAY_BOARDINFO + +#ifndef __ASSEMBLY__ +unsigned long get_board_sys_clk(void); +unsigned long get_board_ddr_clk(void); +#endif + +#define CONFIG_SYS_CLK_FREQ get_board_sys_clk() +#define CONFIG_DDR_CLK_FREQ get_board_ddr_clk() +#define COUNTER_FREQUENCY_REAL (CONFIG_SYS_CLK_FREQ/4) + +#define CONFIG_DDR_SPD +#define CONFIG_DDR_ECC +#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER +#define CONFIG_MEM_INIT_VALUE 0xdeadbeef +#define SPD_EEPROM_ADDRESS1 0x51 +#define SPD_EEPROM_ADDRESS2 0x52 +#define SPD_EEPROM_ADDRESS3 0x53 +#define SPD_EEPROM_ADDRESS4 0x54 +#define SPD_EEPROM_ADDRESS5 0x55 +#define SPD_EEPROM_ADDRESS6 0x56 /* dummy address */ +#define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1 +#define CONFIG_SYS_SPD_BUS_NUM 0 /* SPD on I2C bus 0 */ +#define CONFIG_DIMM_SLOTS_PER_CTLR 2 +#define CONFIG_CHIP_SELECTS_PER_CTRL 4 +#define CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR 1 +#define CONFIG_FSL_DDR_BIST /* enable built-in memory test */ + +/* undefined CONFIG_FSL_DDR_SYNC_REFRESH for simulator */ + +#define CONFIG_SYS_NOR0_CSPR_EXT (0x0) +#define CONFIG_SYS_NOR_AMASK IFC_AMASK(128*1024*1024) +#define CONFIG_SYS_NOR_AMASK_EARLY IFC_AMASK(64*1024*1024) + +#define CONFIG_SYS_NOR0_CSPR \ + (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR0_CSPR_EARLY \ + (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS_EARLY) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR1_CSPR \ + (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH1_BASE_PHYS) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR1_CSPR_EARLY \ + (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH1_BASE_PHYS_EARLY) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR_CSOR CSOR_NOR_ADM_SHIFT(12) +#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x4) | \ + FTIM0_NOR_TEADC(0x5) | \ + FTIM0_NOR_TEAHC(0x5)) +#define CONFIG_SYS_NOR_FTIM1 (FTIM1_NOR_TACO(0x35) | \ + FTIM1_NOR_TRAD_NOR(0x1a) |\ + FTIM1_NOR_TSEQRAD_NOR(0x13)) +#define CONFIG_SYS_NOR_FTIM2 (FTIM2_NOR_TCS(0x4) | \ + FTIM2_NOR_TCH(0x4) | \ + FTIM2_NOR_TWPH(0x0E) | \ + FTIM2_NOR_TWP(0x1c)) +#define CONFIG_SYS_NOR_FTIM3 0x04000000 +#define CONFIG_SYS_IFC_CCR 0x01000000 + +#ifndef CONFIG_SYS_NO_FLASH +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE +#define CONFIG_SYS_FLASH_QUIET_TEST +#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */ + +#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* number of banks */ +#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */ +#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ + +#define CONFIG_SYS_FLASH_EMPTY_INFO +#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE,\ + CONFIG_SYS_FLASH_BASE + 0x40000000} +#endif + +#define CONFIG_NAND_FSL_IFC +#define CONFIG_SYS_NAND_MAX_ECCPOS 256 +#define CONFIG_SYS_NAND_MAX_OOBFREE 2 + + +#define CONFIG_SYS_NAND_CSPR_EXT (0x0) +#define CONFIG_SYS_NAND_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \ + | CSPR_PORT_SIZE_8 /* Port Size = 8 bit */ \ + | CSPR_MSEL_NAND /* MSEL = NAND */ \ + | CSPR_V) +#define CONFIG_SYS_NAND_AMASK IFC_AMASK(64 * 1024) + +#define CONFIG_SYS_NAND_CSOR (CSOR_NAND_ECC_ENC_EN /* ECC on encode */ \ + | CSOR_NAND_ECC_DEC_EN /* ECC on decode */ \ + | CSOR_NAND_ECC_MODE_4 /* 4-bit ECC */ \ + | CSOR_NAND_RAL_3 /* RAL = 3Byes */ \ + | CSOR_NAND_PGS_2K /* Page Size = 2K */ \ + | CSOR_NAND_SPRZ_64/* Spare size = 64 */ \ + | CSOR_NAND_PB(64)) /*Pages Per Block = 64*/ + +#define CONFIG_SYS_NAND_ONFI_DETECTION + +/* ONFI NAND Flash mode0 Timing Params */ +#define CONFIG_SYS_NAND_FTIM0 (FTIM0_NAND_TCCST(0x07) | \ + FTIM0_NAND_TWP(0x18) | \ + FTIM0_NAND_TWCHT(0x07) | \ + FTIM0_NAND_TWH(0x0a)) +#define CONFIG_SYS_NAND_FTIM1 (FTIM1_NAND_TADLE(0x32) | \ + FTIM1_NAND_TWBE(0x39) | \ + FTIM1_NAND_TRR(0x0e) | \ + FTIM1_NAND_TRP(0x18)) +#define CONFIG_SYS_NAND_FTIM2 (FTIM2_NAND_TRAD(0x0f) | \ + FTIM2_NAND_TREH(0x0a) | \ + FTIM2_NAND_TWHRE(0x1e)) +#define CONFIG_SYS_NAND_FTIM3 0x0 + +#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE } +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_MTD_NAND_VERIFY_WRITE +#define CONFIG_CMD_NAND + +#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024) + +#define CONFIG_FSL_QIXIS /* use common QIXIS code */ +#define QIXIS_LBMAP_SWITCH 0x06 +#define QIXIS_LBMAP_MASK 0x0f +#define QIXIS_LBMAP_SHIFT 0 +#define QIXIS_LBMAP_DFLTBANK 0x00 +#define QIXIS_LBMAP_ALTBANK 0x04 +#define QIXIS_LBMAP_NAND 0x09 +#define QIXIS_RST_CTL_RESET 0x31 +#define QIXIS_RCFG_CTL_RECONFIG_IDLE 0x20 +#define QIXIS_RCFG_CTL_RECONFIG_START 0x21 +#define QIXIS_RCFG_CTL_WATCHDOG_ENBLE 0x08 +#define QIXIS_RCW_SRC_NAND 0x107 +#define QIXIS_RST_FORCE_MEM 0x01 + +#define CONFIG_SYS_CSPR3_EXT (0x0) +#define CONFIG_SYS_CSPR3 (CSPR_PHYS_ADDR(QIXIS_BASE_PHYS_EARLY) \ + | CSPR_PORT_SIZE_8 \ + | CSPR_MSEL_GPCM \ + | CSPR_V) +#define CONFIG_SYS_CSPR3_FINAL (CSPR_PHYS_ADDR(QIXIS_BASE_PHYS) \ + | CSPR_PORT_SIZE_8 \ + | CSPR_MSEL_GPCM \ + | CSPR_V) + +#define CONFIG_SYS_AMASK3 IFC_AMASK(64*1024) +#define CONFIG_SYS_CSOR3 CSOR_GPCM_ADM_SHIFT(12) +/* QIXIS Timing parameters for IFC CS3 */ +#define CONFIG_SYS_CS3_FTIM0 (FTIM0_GPCM_TACSE(0x0e) | \ + FTIM0_GPCM_TEADC(0x0e) | \ + FTIM0_GPCM_TEAHC(0x0e)) +#define CONFIG_SYS_CS3_FTIM1 (FTIM1_GPCM_TACO(0xff) | \ + FTIM1_GPCM_TRAD(0x3f)) +#define CONFIG_SYS_CS3_FTIM2 (FTIM2_GPCM_TCS(0xf) | \ + FTIM2_GPCM_TCH(0xf) | \ + FTIM2_GPCM_TWP(0x3E)) +#define CONFIG_SYS_CS3_FTIM3 0x0 + +#if defined(CONFIG_SPL) && defined(CONFIG_NAND) +#define CONFIG_SYS_CSPR1_EXT CONFIG_SYS_NOR0_CSPR_EXT +#define CONFIG_SYS_CSPR1 CONFIG_SYS_NOR0_CSPR_EARLY +#define CONFIG_SYS_CSPR1_FINAL CONFIG_SYS_NOR0_CSPR +#define CONFIG_SYS_AMASK1 CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR1 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS1_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS1_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS1_FTIM3 CONFIG_SYS_NOR_FTIM3 +#define CONFIG_SYS_CSPR2_EXT CONFIG_SYS_NOR0_CSPR_EXT +#define CONFIG_SYS_CSPR2 CONFIG_SYS_NOR1_CSPR_EARLY +#define CONFIG_SYS_CSPR2_FINAL CONFIG_SYS_NOR1_CSPR +#define CONFIG_SYS_AMASK2 CONFIG_SYS_NOR_AMASK_EARLY +#define CONFIG_SYS_AMASK2_FINAL CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR2 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS2_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS2_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS2_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_NOR_FTIM3 +#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NAND_CSPR_EXT +#define CONFIG_SYS_CSPR0 CONFIG_SYS_NAND_CSPR +#define CONFIG_SYS_AMASK0 CONFIG_SYS_NAND_AMASK +#define CONFIG_SYS_CSOR0 CONFIG_SYS_NAND_CSOR +#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NAND_FTIM0 +#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NAND_FTIM1 +#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NAND_FTIM2 +#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NAND_FTIM3 + +#define CONFIG_ENV_IS_IN_NAND +#define CONFIG_ENV_OFFSET (896 * 1024) +#define CONFIG_ENV_SECT_SIZE 0x20000 +#define CONFIG_ENV_SIZE 0x2000 +#define CONFIG_SPL_PAD_TO 0x20000 +#define CONFIG_SYS_NAND_U_BOOT_OFFS (256 * 1024) +#define CONFIG_SYS_NAND_U_BOOT_SIZE (512 * 1024) +#else +#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT +#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR_EARLY +#define CONFIG_SYS_CSPR0_FINAL CONFIG_SYS_NOR0_CSPR +#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3 +#define CONFIG_SYS_CSPR1_EXT CONFIG_SYS_NOR0_CSPR_EXT +#define CONFIG_SYS_CSPR1 CONFIG_SYS_NOR1_CSPR_EARLY +#define CONFIG_SYS_CSPR1_FINAL CONFIG_SYS_NOR1_CSPR +#define CONFIG_SYS_AMASK1 CONFIG_SYS_NOR_AMASK_EARLY +#define CONFIG_SYS_AMASK1_FINAL CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR1 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS1_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS1_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS1_FTIM3 CONFIG_SYS_NOR_FTIM3 +#define CONFIG_SYS_CSPR2_EXT CONFIG_SYS_NAND_CSPR_EXT +#define CONFIG_SYS_CSPR2 CONFIG_SYS_NAND_CSPR +#define CONFIG_SYS_AMASK2 CONFIG_SYS_NAND_AMASK +#define CONFIG_SYS_CSOR2 CONFIG_SYS_NAND_CSOR +#define CONFIG_SYS_CS2_FTIM0 CONFIG_SYS_NAND_FTIM0 +#define CONFIG_SYS_CS2_FTIM1 CONFIG_SYS_NAND_FTIM1 +#define CONFIG_SYS_CS2_FTIM2 CONFIG_SYS_NAND_FTIM2 +#define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_NAND_FTIM3 + +#define CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x200000) +#define CONFIG_ENV_SECT_SIZE 0x20000 +#define CONFIG_ENV_SIZE 0x2000 +#endif + +/* Debug Server firmware */ +#define CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR +#define CONFIG_SYS_DEBUG_SERVER_FW_ADDR 0x580D00000ULL + +/* MC firmware */ +#define CONFIG_SYS_LS_MC_FW_IN_NOR +#define CONFIG_SYS_LS_MC_FW_ADDR 0x580300000ULL + +#define CONFIG_SYS_LS_MC_DPL_IN_NOR +#define CONFIG_SYS_LS_MC_DPL_ADDR 0x580700000ULL + +#define CONFIG_SYS_LS_MC_DPC_IN_NOR +#define CONFIG_SYS_LS_MC_DPC_ADDR 0x580800000ULL + +#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000 + +/* + * I2C + */ +#define I2C_MUX_PCA_ADDR 0x77 +#define I2C_MUX_PCA_ADDR_PRI 0x77 /* Primary Mux*/ + +/* I2C bus multiplexer */ +#define I2C_MUX_CH_DEFAULT 0x8 + +/* + * MMC + */ +#ifdef CONFIG_MMC +#define CONFIG_ESDHC_DETECT_QUIRK ((readb(QIXIS_BASE + QIXIS_STAT_PRES1) & \ + QIXIS_SDID_MASK) != QIXIS_ESDHC_NO_ADAPTER) +#endif + +/* + * RTC configuration + */ +#define RTC +#define CONFIG_RTC_DS3231 1 +#define CONFIG_SYS_I2C_RTC_ADDR 0x68 + +/* EEPROM */ +#define CONFIG_ID_EEPROM +#define CONFIG_CMD_EEPROM +#define CONFIG_SYS_I2C_EEPROM_NXID +#define CONFIG_SYS_EEPROM_BUS_NUM 0 +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x57 +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 3 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 5 + +#define CONFIG_FSL_MEMAC +#define CONFIG_PCI /* Enable PCIE */ +#define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */ + +#ifdef CONFIG_PCI +#define CONFIG_NET_MULTI +#define CONFIG_PCI_PNP +#define CONFIG_E1000 +#define CONFIG_PCI_SCAN_SHOW +#define CONFIG_CMD_PCI +#define CONFIG_CMD_NET +#endif + +/* MMC */ +#define CONFIG_MMC +#ifdef CONFIG_MMC +#define CONFIG_CMD_MMC +#define CONFIG_FSL_ESDHC +#define CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33 +#define CONFIG_GENERIC_MMC +#define CONFIG_CMD_FAT +#define CONFIG_DOS_PARTITION +#endif + +/* Initial environment variables */ +#undef CONFIG_EXTRA_ENV_SETTINGS +#define CONFIG_EXTRA_ENV_SETTINGS \ + "hwconfig=fsl_ddr:bank_intlv=auto\0" \ + "loadaddr=0x80100000\0" \ + "kernel_addr=0x100000\0" \ + "ramdisk_addr=0x800000\0" \ + "ramdisk_size=0x2000000\0" \ + "fdt_high=0xa0000000\0" \ + "initrd_high=0xffffffffffffffff\0" \ + "kernel_start=0x581100000\0" \ + "kernel_load=0xa0000000\0" \ + "kernel_size=0x1000000\0" + +#ifdef CONFIG_FSL_MC_ENET +#define CONFIG_FSL_MEMAC +#define CONFIG_PHYLIB +#define CONFIG_PHYLIB_10G +#define CONFIG_CMD_MII +#define CONFIG_PHY_VITESSE +#define CONFIG_PHY_REALTEK +#define CONFIG_PHY_TERANETICS +#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 CONFIG_MII /* MII PHY management */ +#define CONFIG_ETHPRIME "DPNI1" +#define CONFIG_PHY_GIGE /* Include GbE speed/duplex detection */ + +#endif + +#endif /* __LS2_QDS_H */ diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h new file mode 100644 index 0000000..d1c2548 --- /dev/null +++ b/include/configs/ls2085ardb.h @@ -0,0 +1,305 @@ +/* + * Copyright 2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __LS2_RDB_H +#define __LS2_RDB_H + +#include "ls2085a_common.h" +#include <config_cmd_default.h> + +#define CONFIG_IDENT_STRING " LS2085A-RDB" +#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-RDB" + +#undef CONFIG_CONS_INDEX +#define CONFIG_CONS_INDEX 2 + +#define CONFIG_DISPLAY_BOARDINFO + +#ifndef __ASSEMBLY__ +unsigned long get_board_sys_clk(void); +#endif + +#define CONFIG_SYS_CLK_FREQ get_board_sys_clk() +#define CONFIG_DDR_CLK_FREQ 133333333 +#define COUNTER_FREQUENCY_REAL (CONFIG_SYS_CLK_FREQ/4) + +#define CONFIG_DDR_SPD +#define CONFIG_DDR_ECC +#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER +#define CONFIG_MEM_INIT_VALUE 0xdeadbeef +#define SPD_EEPROM_ADDRESS1 0x51 +#define SPD_EEPROM_ADDRESS2 0x52 +#define SPD_EEPROM_ADDRESS3 0x54 +#define SPD_EEPROM_ADDRESS4 0x53 /* Board error */ +#define SPD_EEPROM_ADDRESS5 0x55 +#define SPD_EEPROM_ADDRESS6 0x56 /* dummy address */ +#define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1 +#define CONFIG_SYS_SPD_BUS_NUM 0 /* SPD on I2C bus 0 */ +#define CONFIG_DIMM_SLOTS_PER_CTLR 2 +#define CONFIG_CHIP_SELECTS_PER_CTRL 4 +#define CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR 1 +#define CONFIG_FSL_DDR_BIST /* enable built-in memory test */ + +/* undefined CONFIG_FSL_DDR_SYNC_REFRESH for simulator */ + +#define CONFIG_SYS_NOR0_CSPR_EXT (0x0) +#define CONFIG_SYS_NOR_AMASK IFC_AMASK(128*1024*1024) +#define CONFIG_SYS_NOR_AMASK_EARLY IFC_AMASK(64*1024*1024) + +#define CONFIG_SYS_NOR0_CSPR \ + (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR0_CSPR_EARLY \ + (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS_EARLY) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR_CSOR CSOR_NOR_ADM_SHIFT(12) +#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x4) | \ + FTIM0_NOR_TEADC(0x5) | \ + FTIM0_NOR_TEAHC(0x5)) +#define CONFIG_SYS_NOR_FTIM1 (FTIM1_NOR_TACO(0x35) | \ + FTIM1_NOR_TRAD_NOR(0x1a) |\ + FTIM1_NOR_TSEQRAD_NOR(0x13)) +#define CONFIG_SYS_NOR_FTIM2 (FTIM2_NOR_TCS(0x4) | \ + FTIM2_NOR_TCH(0x4) | \ + FTIM2_NOR_TWPH(0x0E) | \ + FTIM2_NOR_TWP(0x1c)) +#define CONFIG_SYS_NOR_FTIM3 0x04000000 +#define CONFIG_SYS_IFC_CCR 0x01000000 + +#ifndef CONFIG_SYS_NO_FLASH +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE +#define CONFIG_SYS_FLASH_QUIET_TEST +#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */ + +#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* number of banks */ +#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */ +#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ + +#define CONFIG_SYS_FLASH_EMPTY_INFO +#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE,\ + CONFIG_SYS_FLASH_BASE + 0x40000000} +#endif + +#define CONFIG_NAND_FSL_IFC +#define CONFIG_SYS_NAND_MAX_ECCPOS 256 +#define CONFIG_SYS_NAND_MAX_OOBFREE 2 + + +#define CONFIG_SYS_NAND_CSPR_EXT (0x0) +#define CONFIG_SYS_NAND_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \ + | CSPR_PORT_SIZE_8 /* Port Size = 8 bit */ \ + | CSPR_MSEL_NAND /* MSEL = NAND */ \ + | CSPR_V) +#define CONFIG_SYS_NAND_AMASK IFC_AMASK(64 * 1024) + +#define CONFIG_SYS_NAND_CSOR (CSOR_NAND_ECC_ENC_EN /* ECC on encode */ \ + | CSOR_NAND_ECC_DEC_EN /* ECC on decode */ \ + | CSOR_NAND_ECC_MODE_4 /* 4-bit ECC */ \ + | CSOR_NAND_RAL_3 /* RAL = 3Byes */ \ + | CSOR_NAND_PGS_4K /* Page Size = 4K */ \ + | CSOR_NAND_SPRZ_224 /* Spare size = 224 */ \ + | CSOR_NAND_PB(128)) /* Pages Per Block 128*/ + +#define CONFIG_SYS_NAND_ONFI_DETECTION + +/* ONFI NAND Flash mode0 Timing Params */ +#define CONFIG_SYS_NAND_FTIM0 (FTIM0_NAND_TCCST(0x0e) | \ + FTIM0_NAND_TWP(0x30) | \ + FTIM0_NAND_TWCHT(0x0e) | \ + FTIM0_NAND_TWH(0x14)) +#define CONFIG_SYS_NAND_FTIM1 (FTIM1_NAND_TADLE(0x64) | \ + FTIM1_NAND_TWBE(0xab) | \ + FTIM1_NAND_TRR(0x1c) | \ + FTIM1_NAND_TRP(0x30)) +#define CONFIG_SYS_NAND_FTIM2 (FTIM2_NAND_TRAD(0x1e) | \ + FTIM2_NAND_TREH(0x14) | \ + FTIM2_NAND_TWHRE(0x3c)) +#define CONFIG_SYS_NAND_FTIM3 0x0 + +#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE } +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_MTD_NAND_VERIFY_WRITE +#define CONFIG_CMD_NAND + +#define CONFIG_SYS_NAND_BLOCK_SIZE (512 * 1024) + +#define CONFIG_FSL_QIXIS /* use common QIXIS code */ +#define QIXIS_LBMAP_SWITCH 0x06 +#define QIXIS_LBMAP_MASK 0x0f +#define QIXIS_LBMAP_SHIFT 0 +#define QIXIS_LBMAP_DFLTBANK 0x00 +#define QIXIS_LBMAP_ALTBANK 0x04 +#define QIXIS_LBMAP_NAND 0x09 +#define QIXIS_RST_CTL_RESET 0x31 +#define QIXIS_RST_CTL_RESET_EN 0x30 +#define QIXIS_RCFG_CTL_RECONFIG_IDLE 0x20 +#define QIXIS_RCFG_CTL_RECONFIG_START 0x21 +#define QIXIS_RCFG_CTL_WATCHDOG_ENBLE 0x08 +#define QIXIS_RCW_SRC_NAND 0x119 +#define QIXIS_RST_FORCE_MEM 0x01 + +#define CONFIG_SYS_CSPR3_EXT (0x0) +#define CONFIG_SYS_CSPR3 (CSPR_PHYS_ADDR(QIXIS_BASE_PHYS_EARLY) \ + | CSPR_PORT_SIZE_8 \ + | CSPR_MSEL_GPCM \ + | CSPR_V) +#define CONFIG_SYS_CSPR3_FINAL (CSPR_PHYS_ADDR(QIXIS_BASE_PHYS) \ + | CSPR_PORT_SIZE_8 \ + | CSPR_MSEL_GPCM \ + | CSPR_V) + +#define CONFIG_SYS_AMASK3 IFC_AMASK(64*1024) +#define CONFIG_SYS_CSOR3 CSOR_GPCM_ADM_SHIFT(12) +/* QIXIS Timing parameters for IFC CS3 */ +#define CONFIG_SYS_CS3_FTIM0 (FTIM0_GPCM_TACSE(0x0e) | \ + FTIM0_GPCM_TEADC(0x0e) | \ + FTIM0_GPCM_TEAHC(0x0e)) +#define CONFIG_SYS_CS3_FTIM1 (FTIM1_GPCM_TACO(0xff) | \ + FTIM1_GPCM_TRAD(0x3f)) +#define CONFIG_SYS_CS3_FTIM2 (FTIM2_GPCM_TCS(0xf) | \ + FTIM2_GPCM_TCH(0xf) | \ + FTIM2_GPCM_TWP(0x3E)) +#define CONFIG_SYS_CS3_FTIM3 0x0 + +#if defined(CONFIG_SPL) && defined(CONFIG_NAND) +#define CONFIG_SYS_CSPR2_EXT CONFIG_SYS_NOR0_CSPR_EXT +#define CONFIG_SYS_CSPR2 CONFIG_SYS_NOR0_CSPR_EARLY +#define CONFIG_SYS_CSPR2_FINAL CONFIG_SYS_NOR0_CSPR +#define CONFIG_SYS_AMASK2 CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR2 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS2_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS2_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS2_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_NOR_FTIM3 +#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NAND_CSPR_EXT +#define CONFIG_SYS_CSPR0 CONFIG_SYS_NAND_CSPR +#define CONFIG_SYS_AMASK0 CONFIG_SYS_NAND_AMASK +#define CONFIG_SYS_CSOR0 CONFIG_SYS_NAND_CSOR +#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NAND_FTIM0 +#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NAND_FTIM1 +#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NAND_FTIM2 +#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NAND_FTIM3 + +#define CONFIG_ENV_IS_IN_NAND +#define CONFIG_ENV_OFFSET (2048 * 1024) +#define CONFIG_ENV_SECT_SIZE 0x20000 +#define CONFIG_ENV_SIZE 0x2000 +#define CONFIG_SPL_PAD_TO 0x80000 +#define CONFIG_SYS_NAND_U_BOOT_OFFS (1024 * 1024) +#define CONFIG_SYS_NAND_U_BOOT_SIZE (512 * 1024) +#else +#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT +#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR_EARLY +#define CONFIG_SYS_CSPR0_FINAL CONFIG_SYS_NOR0_CSPR +#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3 +#define CONFIG_SYS_CSPR2_EXT CONFIG_SYS_NAND_CSPR_EXT +#define CONFIG_SYS_CSPR2 CONFIG_SYS_NAND_CSPR +#define CONFIG_SYS_AMASK2 CONFIG_SYS_NAND_AMASK +#define CONFIG_SYS_CSOR2 CONFIG_SYS_NAND_CSOR +#define CONFIG_SYS_CS2_FTIM0 CONFIG_SYS_NAND_FTIM0 +#define CONFIG_SYS_CS2_FTIM1 CONFIG_SYS_NAND_FTIM1 +#define CONFIG_SYS_CS2_FTIM2 CONFIG_SYS_NAND_FTIM2 +#define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_NAND_FTIM3 + +#define CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x200000) +#define CONFIG_ENV_SECT_SIZE 0x20000 +#define CONFIG_ENV_SIZE 0x2000 +#endif + +/* Debug Server firmware */ +#define CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR +#define CONFIG_SYS_DEBUG_SERVER_FW_ADDR 0x580D00000ULL + +/* MC firmware */ +#define CONFIG_SYS_LS_MC_FW_IN_NOR +#define CONFIG_SYS_LS_MC_FW_ADDR 0x580300000ULL + +#define CONFIG_SYS_LS_MC_DPL_IN_NOR +#define CONFIG_SYS_LS_MC_DPL_ADDR 0x580700000ULL + +#define CONFIG_SYS_LS_MC_DPC_IN_NOR +#define CONFIG_SYS_LS_MC_DPC_ADDR 0x580800000ULL + +#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000 + +/* + * I2C + */ +#define I2C_MUX_PCA_ADDR 0x77 +#define I2C_MUX_PCA_ADDR_PRI 0x77 /* Primary Mux*/ + +/* I2C bus multiplexer */ +#define I2C_MUX_CH_DEFAULT 0x8 + +/* + * RTC configuration + */ +#define RTC +#define CONFIG_RTC_DS3231 1 +#define CONFIG_SYS_I2C_RTC_ADDR 0x68 + +/* EEPROM */ +#define CONFIG_ID_EEPROM +#define CONFIG_CMD_EEPROM +#define CONFIG_SYS_I2C_EEPROM_NXID +#define CONFIG_SYS_EEPROM_BUS_NUM 0 +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x57 +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 3 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 5 + +#define CONFIG_FSL_MEMAC +#define CONFIG_PCI /* Enable PCIE */ +#define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */ + +#ifdef CONFIG_PCI +#define CONFIG_NET_MULTI +#define CONFIG_PCI_PNP +#define CONFIG_E1000 +#define CONFIG_PCI_SCAN_SHOW +#define CONFIG_CMD_PCI +#define CONFIG_CMD_NET +#endif + +/* MMC */ +#define CONFIG_MMC +#ifdef CONFIG_MMC +#define CONFIG_CMD_MMC +#define CONFIG_FSL_ESDHC +#define CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33 +#define CONFIG_GENERIC_MMC +#define CONFIG_CMD_FAT +#define CONFIG_DOS_PARTITION +#endif + +/* Initial environment variables */ +#undef CONFIG_EXTRA_ENV_SETTINGS +#define CONFIG_EXTRA_ENV_SETTINGS \ + "hwconfig=fsl_ddr:bank_intlv=auto\0" \ + "loadaddr=0x80100000\0" \ + "kernel_addr=0x100000\0" \ + "ramdisk_addr=0x800000\0" \ + "ramdisk_size=0x2000000\0" \ + "fdt_high=0xa0000000\0" \ + "initrd_high=0xffffffffffffffff\0" \ + "kernel_start=0x581100000\0" \ + "kernel_load=0xa0000000\0" \ + "kernel_size=0x1000000\0" + +#endif /* __LS2_RDB_H */ diff --git a/include/configs/m53evk.h b/include/configs/m53evk.h index c133ba9..c348d38 100644 --- a/include/configs/m53evk.h +++ b/include/configs/m53evk.h @@ -176,6 +176,7 @@ #ifdef CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_RTC_BUS_NUM 1 /* I2C2 */ #endif diff --git a/include/configs/maxbcm.h b/include/configs/maxbcm.h index 5999d60..e909623 100644 --- a/include/configs/maxbcm.h +++ b/include/configs/maxbcm.h @@ -35,7 +35,7 @@ /* I2C */ #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MVTWSI -#define CONFIG_I2C_MVTWSI_BASE MVEBU_TWSI_BASE +#define CONFIG_I2C_MVTWSI_BASE0 MVEBU_TWSI_BASE #define CONFIG_SYS_I2C_SLAVE 0x0 #define CONFIG_SYS_I2C_SPEED 100000 diff --git a/include/configs/mx35pdk.h b/include/configs/mx35pdk.h index f8cd39d..244a9ab 100644 --- a/include/configs/mx35pdk.h +++ b/include/configs/mx35pdk.h @@ -42,6 +42,7 @@ */ #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_MXC_SPI #define CONFIG_MXC_GPIO diff --git a/include/configs/mx53ard.h b/include/configs/mx53ard.h index 9b003fc..7c3dc20 100644 --- a/include/configs/mx53ard.h +++ b/include/configs/mx53ard.h @@ -48,6 +48,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ /* MMC Configs */ #define CONFIG_FSL_ESDHC diff --git a/include/configs/mx53evk.h b/include/configs/mx53evk.h index fb2072d..22a9fc4 100644 --- a/include/configs/mx53evk.h +++ b/include/configs/mx53evk.h @@ -41,6 +41,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ /* PMIC Configs */ #define CONFIG_POWER diff --git a/include/configs/mx53loco.h b/include/configs/mx53loco.h index 3551e02..a56e72e 100644 --- a/include/configs/mx53loco.h +++ b/include/configs/mx53loco.h @@ -76,6 +76,7 @@ /* I2C Configs */ #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ /* PMIC Controller */ #define CONFIG_POWER diff --git a/include/configs/mx53smd.h b/include/configs/mx53smd.h index 3da0ef4..0785491 100644 --- a/include/configs/mx53smd.h +++ b/include/configs/mx53smd.h @@ -38,6 +38,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ /* MMC Configs */ #define CONFIG_FSL_ESDHC diff --git a/include/configs/mx6cuboxi.h b/include/configs/mx6cuboxi.h new file mode 100644 index 0000000..b569f34 --- /dev/null +++ b/include/configs/mx6cuboxi.h @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * Configuration settings for the SolidRun mx6 based boards + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __MX6CUBOXI_CONFIG_H +#define __MX6CUBOXI_CONFIG_H + +#include <linux/sizes.h> +#include <asm/arch/imx-regs.h> +#include <asm/imx-common/gpio.h> +#include "mx6_common.h" + +#define CONFIG_MX6 +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_MMC_SUPPORT +#include "imx6_spl.h" + +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG +#define CONFIG_IMX6_THERMAL +#define CONFIG_SYS_GENERIC_BOARD + +#define CONFIG_SYS_MALLOC_LEN (2 * SZ_1M) +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT +#define CONFIG_MXC_GPIO +#define CONFIG_MXC_UART +#define CONFIG_CMD_FUSE +#define CONFIG_MXC_OCOTP + +/* MMC Configs */ +#define CONFIG_FSL_ESDHC +#define CONFIG_FSL_USDHC +#define CONFIG_SYS_FSL_ESDHC_ADDR USDHC2_BASE_ADDR +#define CONFIG_MMC +#define CONFIG_CMD_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_BOUNCE_BUFFER +#define CONFIG_CMD_EXT4 +#define CONFIG_CMD_EXT4_WRITE +#define CONFIG_CMD_FAT +#define CONFIG_DOS_PARTITION + +/* Ethernet Configuration */ +#define CONFIG_FEC_MXC +#define CONFIG_CMD_PING +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_MII +#define CONFIG_CMD_NET +#define CONFIG_MII +#define IMX_FEC_BASE ENET_BASE_ADDR +#define CONFIG_FEC_XCV_TYPE RGMII +#define CONFIG_FEC_MXC_PHYADDR 0 +#define CONFIG_PHYLIB +#define CONFIG_PHY_ATHEROS + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE +#define CONFIG_CONS_INDEX 1 +#define CONFIG_BAUDRATE 115200 + +#define CONFIG_SYS_NO_FLASH + +/* Command definition */ +#include <config_cmd_default.h> + +#define CONFIG_CMD_BOOTZ +#define CONFIG_CMD_SETEXPR + +#define CONFIG_BOOTDELAY 1 + +#define CONFIG_LOADADDR 0x12000000 +#define CONFIG_SYS_TEXT_BASE 0x17800000 + +#define CONFIG_MXC_UART_BASE UART1_BASE +#define CONFIG_CONSOLE_DEV "ttymxc0" +#define CONFIG_MMCROOT "/dev/mmcblk0p2" +#define CONFIG_SYS_FSL_USDHC_NUM 1 +#define CONFIG_SYS_MMC_ENV_DEV 0 /* SDHC2 */ + +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +#define CONFIG_EXTRA_ENV_SETTINGS \ + "script=boot.scr\0" \ + "image=zImage\0" \ + "fdtfile=undefined\0" \ + "fdt_addr_r=0x18000000\0" \ + "boot_fdt=try\0" \ + "ip_dyn=yes\0" \ + "console=" CONFIG_CONSOLE_DEV "\0" \ + "bootm_size=0x10000000\0" \ + "mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV) "\0" \ + "mmcpart=1\0" \ + "mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \ + "update_sd_firmware=" \ + "if test ${ip_dyn} = yes; then " \ + "setenv get_cmd dhcp; " \ + "else " \ + "setenv get_cmd tftp; " \ + "fi; " \ + "if mmc dev ${mmcdev}; then " \ + "if ${get_cmd} ${update_sd_firmware_filename}; then " \ + "setexpr fw_sz ${filesize} / 0x200; " \ + "setexpr fw_sz ${fw_sz} + 1; " \ + "mmc write ${loadaddr} 0x2 ${fw_sz}; " \ + "fi; " \ + "fi\0" \ + "mmcargs=setenv bootargs console=${console},${baudrate} " \ + "root=${mmcroot}\0" \ + "loadbootscript=" \ + "fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \ + "bootscript=echo Running bootscript from mmc ...; " \ + "source\0" \ + "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ + "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr_r} ${fdtfile}\0" \ + "mmcboot=echo Booting from mmc ...; " \ + "run mmcargs; " \ + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ + "if run loadfdt; then " \ + "bootz ${loadaddr} - ${fdt_addr_r}; " \ + "else " \ + "if test ${boot_fdt} = try; then " \ + "bootz; " \ + "else " \ + "echo WARN: Cannot load the DT; " \ + "fi; " \ + "fi; " \ + "else " \ + "bootz; " \ + "fi;\0" \ + "netargs=setenv bootargs console=${console},${baudrate} " \ + "root=/dev/nfs " \ + "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \ + "netboot=echo Booting from net ...; " \ + "run netargs; " \ + "if test ${ip_dyn} = yes; then " \ + "setenv get_cmd dhcp; " \ + "else " \ + "setenv get_cmd tftp; " \ + "fi; " \ + "${get_cmd} ${image}; " \ + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ + "if ${get_cmd} ${fdt_addr_r} ${fdtfile}; then " \ + "bootz ${loadaddr} - ${fdt_addr_r}; " \ + "else " \ + "if test ${boot_fdt} = try; then " \ + "bootz; " \ + "else " \ + "echo WARN: Cannot load the DT; " \ + "fi; " \ + "fi; " \ + "else " \ + "bootz; " \ + "fi;\0" \ + "findfdt="\ + "if test $board_name = HUMMINGBOARD && test $board_rev = MX6Q ; then " \ + "setenv fdtfile imx6q-hummingboard.dtb; fi; " \ + "if test $board_name = HUMMINGBOARD && test $board_rev = MX6DL ; then " \ + "setenv fdtfile imx6dl-hummingboard.dtb; fi; " \ + "if test $board_name = CUBOXI && test $board_rev = MX6Q ; then " \ + "setenv fdtfile imx6q-cubox-i.dtb; fi; " \ + "if test $board_name = CUBOXI && test $board_rev = MX6DL ; then " \ + "setenv fdtfile imx6dl-cubox-i.dtb; fi; " \ + "if test $fdtfile = undefined; then " \ + "echo WARNING: Could not determine dtb to use; fi; \0" \ + +#define CONFIG_BOOTCOMMAND \ + "run findfdt; " \ + "mmc dev ${mmcdev};" \ + "if mmc rescan; then " \ + "if run loadbootscript; then " \ + "run bootscript; " \ + "else " \ + "if run loadimage; then " \ + "run mmcboot; " \ + "else run netboot; " \ + "fi; " \ + "fi; " \ + "else run netboot; fi" + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_HUSH_PARSER +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +#define CONFIG_CMDLINE_EDITING + +/* Physical Memory Map */ +#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_SYS_SDRAM_BASE MMDC0_ARB_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE + +#define CONFIG_SYS_INIT_SP_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) + +/* Environment organization */ +#define CONFIG_ENV_SIZE (8 * 1024) +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_ENV_OFFSET (8 * 64 * 1024) + +#define CONFIG_OF_LIBFDT +#define CONFIG_CMD_CACHE + +#endif /* __MX6CUBOXI_CONFIG_H */ diff --git a/include/configs/mx6qsabreauto.h b/include/configs/mx6qsabreauto.h index 51042ca..2260344 100644 --- a/include/configs/mx6qsabreauto.h +++ b/include/configs/mx6qsabreauto.h @@ -56,6 +56,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 /* NAND flash command */ diff --git a/include/configs/mx6sabresd.h b/include/configs/mx6sabresd.h index 99d9d4d..dab2fd2 100644 --- a/include/configs/mx6sabresd.h +++ b/include/configs/mx6sabresd.h @@ -52,6 +52,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 /* PMIC */ diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h index dad49f9..cd023de 100644 --- a/include/configs/mx6slevk.h +++ b/include/configs/mx6slevk.h @@ -52,6 +52,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 /* PMIC */ diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h index a29d62f..248303c 100644 --- a/include/configs/mx6sxsabresd.h +++ b/include/configs/mx6sxsabresd.h @@ -176,6 +176,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 /* PMIC */ diff --git a/include/configs/nitrogen6x.h b/include/configs/nitrogen6x.h index 8ef4b73..eaa2c2c 100644 --- a/include/configs/nitrogen6x.h +++ b/include/configs/nitrogen6x.h @@ -63,6 +63,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 #define CONFIG_I2C_EDID @@ -142,6 +143,9 @@ #define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE #define CONFIG_VIDEO_BMP_RLE8 #define CONFIG_SPLASH_SCREEN +#define CONFIG_SPLASH_SCREEN_ALIGN +#define CONFIG_VIDEO_BMP_GZIP +#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE (6 * 1024 * 1024) #define CONFIG_BMP_16BPP #define CONFIG_IPUV3_CLK 260000000 #define CONFIG_CMD_HDMIDETECT diff --git a/include/configs/novena.h b/include/configs/novena.h index 3809c6c..5f83469 100644 --- a/include/configs/novena.h +++ b/include/configs/novena.h @@ -141,6 +141,7 @@ /* I2C */ #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_I2C_MULTI_BUS #define CONFIG_I2C_MXC #define CONFIG_SYS_I2C_SPEED 100000 diff --git a/include/configs/omapl138_lcdk.h b/include/configs/omapl138_lcdk.h new file mode 100644 index 0000000..68b4010 --- /dev/null +++ b/include/configs/omapl138_lcdk.h @@ -0,0 +1,330 @@ +/* + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * Based on davinci_dvevm.h. Original Copyrights follow: + * + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* + * Board + */ +#define CONFIG_DRIVER_TI_EMAC +#undef CONFIG_USE_SPIFLASH +#undef CONFIG_SYS_USE_NOR +#define CONFIG_USE_NAND + +/* + * SoC Configuration + */ +#define CONFIG_MACH_OMAPL138_LCDK +#define CONFIG_ARM926EJS /* arm926ejs CPU core */ +#define CONFIG_SOC_DA8XX /* TI DA8xx SoC */ +#define CONFIG_SYS_CLK_FREQ clk_get(DAVINCI_ARM_CLKID) +#define CONFIG_SYS_OSCIN_FREQ 24000000 +#define CONFIG_SYS_TIMERBASE DAVINCI_TIMER0_BASE +#define CONFIG_SYS_HZ_CLOCK clk_get(DAVINCI_AUXCLK_CLKID) +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SKIP_LOWLEVEL_INIT +#define CONFIG_SYS_TEXT_BASE 0xc1080000 + +/* + * Memory Info + */ +#define CONFIG_SYS_MALLOC_LEN (0x10000 + 1*1024*1024) /* malloc() len */ +#define PHYS_SDRAM_1 DAVINCI_DDR_EMIF_DATA_BASE /* DDR Start */ +#define PHYS_SDRAM_1_SIZE (128 << 20) /* SDRAM size 128MB */ +#define CONFIG_MAX_RAM_BANK_SIZE (512 << 20) /* max size from SPRS586*/ + +/* memtest start addr */ +#define CONFIG_SYS_MEMTEST_START (PHYS_SDRAM_1 + 0x2000000) + +/* memtest will be run on 16MB */ +#define CONFIG_SYS_MEMTEST_END (PHYS_SDRAM_1 + 0x2000000 + 16*1024*1024) + +#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ +#define CONFIG_STACKSIZE (256*1024) /* regular stack */ + +#define CONFIG_SYS_DA850_SYSCFG_SUSPSRC ( \ + DAVINCI_SYSCFG_SUSPSRC_TIMER0 | \ + DAVINCI_SYSCFG_SUSPSRC_SPI1 | \ + DAVINCI_SYSCFG_SUSPSRC_UART2 | \ + DAVINCI_SYSCFG_SUSPSRC_EMAC | \ + DAVINCI_SYSCFG_SUSPSRC_I2C) + +/* + * PLL configuration + */ +#define CONFIG_SYS_DV_CLKMODE 0 +#define CONFIG_SYS_DA850_PLL0_POSTDIV 1 +#define CONFIG_SYS_DA850_PLL0_PLLDIV1 0x8000 +#define CONFIG_SYS_DA850_PLL0_PLLDIV2 0x8001 +#define CONFIG_SYS_DA850_PLL0_PLLDIV3 0x8002 +#define CONFIG_SYS_DA850_PLL0_PLLDIV4 0x8003 +#define CONFIG_SYS_DA850_PLL0_PLLDIV5 0x8002 +#define CONFIG_SYS_DA850_PLL0_PLLDIV6 CONFIG_SYS_DA850_PLL0_PLLDIV1 +#define CONFIG_SYS_DA850_PLL0_PLLDIV7 0x8005 + +#define CONFIG_SYS_DA850_PLL1_POSTDIV 1 +#define CONFIG_SYS_DA850_PLL1_PLLDIV1 0x8000 +#define CONFIG_SYS_DA850_PLL1_PLLDIV2 0x8001 +#define CONFIG_SYS_DA850_PLL1_PLLDIV3 0x8003 + +#define CONFIG_SYS_DA850_PLL0_PLLM 24 +#define CONFIG_SYS_DA850_PLL1_PLLM 21 + +/* + * Serial Driver info + */ +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE -4 /* NS16550 register size */ +#define CONFIG_SYS_NS16550_COM1 DAVINCI_UART2_BASE /* Base address of UART2 */ +#define CONFIG_SYS_NS16550_CLK clk_get(DAVINCI_UART2_CLKID) +#define CONFIG_CONS_INDEX 1 /* use UART0 for console */ +#define CONFIG_BAUDRATE 115200 /* Default baud rate */ +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +#define CONFIG_SPI +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_STMICRO +#define CONFIG_SPI_FLASH_WINBOND +#define CONFIG_DAVINCI_SPI +#define CONFIG_SYS_SPI_BASE DAVINCI_SPI1_BASE +#define CONFIG_SYS_SPI_CLK clk_get(DAVINCI_SPI1_CLKID) +#define CONFIG_SF_DEFAULT_SPEED 30000000 +#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED + +#ifdef CONFIG_USE_SPIFLASH +#define CONFIG_SPL_SPI_SUPPORT +#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SPL_SPI_LOAD +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x8000 +#define CONFIG_SYS_SPI_U_BOOT_SIZE 0x30000 +#endif + +/* + * I2C Configuration + */ +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_DAVINCI +#define CONFIG_SYS_DAVINCI_I2C_SPEED 25000 +#define CONFIG_SYS_DAVINCI_I2C_SLAVE 10 /* Bogus, master-only in U-Boot */ +#define CONFIG_SYS_I2C_EXPANDER_ADDR 0x20 + +/* + * Flash & Environment + */ +#ifdef CONFIG_USE_NAND +#undef CONFIG_ENV_IS_IN_FLASH +#define CONFIG_NAND_DAVINCI +#define CONFIG_SYS_NO_FLASH +#define CONFIG_ENV_IS_IN_NAND /* U-Boot env in NAND Flash */ +#define CONFIG_ENV_OFFSET 0x0 /* Block 0--not used by bootcode */ +#define CONFIG_ENV_SIZE (128 << 9) +#define CONFIG_SYS_NAND_USE_FLASH_BBT +#define CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST +#define CONFIG_SYS_NAND_PAGE_2K +#define CONFIG_SYS_NAND_BUSWIDTH_16_BIT +#define CONFIG_SYS_NAND_CS 3 +#define CONFIG_SYS_NAND_BASE DAVINCI_ASYNC_EMIF_DATA_CE3_BASE +#define CONFIG_SYS_CLE_MASK 0x10 +#define CONFIG_SYS_ALE_MASK 0x8 +#undef CONFIG_SYS_NAND_HW_ECC +#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ +#define NAND_MAX_CHIPS 1 +#endif + +#ifdef CONFIG_SYS_USE_NOR +#define CONFIG_ENV_IS_IN_FLASH +#undef CONFIG_SYS_NO_FLASH +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_SYS_FLASH_PROTECTION +#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of flash banks */ +#define CONFIG_SYS_FLASH_SECT_SZ (128 << 10) /* 128KB */ +#define CONFIG_ENV_OFFSET (CONFIG_SYS_FLASH_SECT_SZ * 3) +#define CONFIG_ENV_SIZE (128 << 10) +#define CONFIG_SYS_FLASH_BASE DAVINCI_ASYNC_EMIF_DATA_CE2_BASE +#define PHYS_FLASH_SIZE (8 << 20) /* Flash size 8MB */ +#define CONFIG_SYS_MAX_FLASH_SECT ((PHYS_FLASH_SIZE/CONFIG_SYS_FLASH_SECT_SZ)\ + + 3) +#define CONFIG_ENV_SECT_SIZE CONFIG_SYS_FLASH_SECT_SZ +#endif + +#ifdef CONFIG_USE_SPIFLASH +#undef CONFIG_ENV_IS_IN_FLASH +#undef CONFIG_ENV_IS_IN_NAND +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_SIZE (64 << 10) +#define CONFIG_ENV_OFFSET (256 << 10) +#define CONFIG_ENV_SECT_SIZE (64 << 10) +#define CONFIG_SYS_NO_FLASH +#endif + +/* + * Network & Ethernet Configuration + */ +#ifdef CONFIG_DRIVER_TI_EMAC +#define CONFIG_EMAC_MDIO_PHY_NUM 7 +#define CONFIG_MII +#undef CONFIG_DRIVER_TI_EMAC_USE_RMII +#define CONFIG_BOOTP_DEFAULT +#define CONFIG_BOOTP_DNS +#define CONFIG_BOOTP_DNS2 +#define CONFIG_BOOTP_SEND_HOSTNAME +#define CONFIG_NET_RETRY_COUNT 10 +#define CONFIG_NET_MULTI +#endif + +/* + * U-Boot general configuration + */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_MISC_INIT_R +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOOTFILE "uImage" /* Boot file name */ +#define CONFIG_SYS_PROMPT "U-Boot > " /* Command Prompt */ +#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Args Buffer Size */ +#define CONFIG_SYS_LOAD_ADDR (PHYS_SDRAM_1 + 0x700000) +#define CONFIG_VERSION_VARIABLE +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_HUSH_PARSER +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_CMDLINE_EDITING +#define CONFIG_SYS_LONGHELP +#define CONFIG_CRC32_VERIFY +#define CONFIG_MX_CYCLIC +#define CONFIG_OF_LIBFDT + +/* + * Linux Information + */ +#define LINUX_BOOT_PARAM_ADDR (PHYS_SDRAM_1 + 0x100) +#define CONFIG_CMDLINE_TAG +#define CONFIG_REVISION_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_BOOTARGS "console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootwait ip=off" +#define CONFIG_BOOTCOMMAND "if mmc rescan 0; then if fatload mmc 0 0xc0600000 boot.scr; then source 0xc0600000; else fatload mmc 0 0xc0700000 uImage; bootm c0700000; fi; else sf probe 0; sf read 0xc0700000 0x80000 0x220000; bootm 0xc0700000; fi" +#define CONFIG_BOOTDELAY 3 + +/* + * U-Boot commands + */ +#include <config_cmd_default.h> +#define CONFIG_CMD_ENV +#define CONFIG_CMD_ASKENV +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_DIAG +#define CONFIG_CMD_MII +#define CONFIG_CMD_PING +#define CONFIG_CMD_SAVES +#define CONFIG_CMD_MEMORY +#ifdef CONFIG_CMD_BDI +#define CONFIG_CLOCKS +#endif + +#ifndef CONFIG_DRIVER_TI_EMAC +#undef CONFIG_CMD_NET +#undef CONFIG_CMD_DHCP +#undef CONFIG_CMD_MII +#undef CONFIG_CMD_PING +#endif + +#ifdef CONFIG_USE_NAND +#undef CONFIG_CMD_FLASH +#undef CONFIG_CMD_IMLS +#define CONFIG_CMD_NAND + +#define CONFIG_CMD_MTDPARTS +#define CONFIG_MTD_DEVICE +#define CONFIG_MTD_PARTITIONS +#define CONFIG_LZO +#define CONFIG_RBTREE +#define CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS +#endif + +#ifdef CONFIG_USE_SPIFLASH +#undef CONFIG_CMD_IMLS +#undef CONFIG_CMD_FLASH +#define CONFIG_CMD_SPI +#define CONFIG_CMD_SF +#define CONFIG_CMD_SAVEENV +#endif + +#if !defined(CONFIG_USE_NAND) && \ + !defined(CONFIG_SYS_USE_NOR) && \ + !defined(CONFIG_USE_SPIFLASH) +#define CONFIG_ENV_IS_NOWHERE +#define CONFIG_SYS_NO_FLASH +#define CONFIG_ENV_SIZE (16 << 10) +#undef CONFIG_CMD_IMLS +#undef CONFIG_CMD_ENV +#endif + +/* SD/MMC */ +#define CONFIG_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_DAVINCI_MMC + +#ifdef CONFIG_MMC +#define CONFIG_DOS_PARTITION +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_MMC +#undef CONFIG_ENV_IS_IN_MMC +#endif + +#ifdef CONFIG_ENV_IS_IN_MMC +#undef CONFIG_ENV_SIZE +#undef CONFIG_ENV_OFFSET +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KiB */ +#define CONFIG_ENV_OFFSET (51 << 9) /* Sector 51 */ +#undef CONFIG_ENV_IS_IN_FLASH +#undef CONFIG_ENV_IS_IN_NAND +#undef CONFIG_ENV_IS_IN_SPI_FLASH +#endif + +#ifndef CONFIG_DIRECT_NOR_BOOT +/* defines for 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_SERIAL_SUPPORT +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_LDSCRIPT "board/$(BOARDDIR)/u-boot-spl-da850evm.lds" +#define CONFIG_SPL_STACK 0x8001ff00 +#define CONFIG_SPL_TEXT_BASE 0x80000000 +#define CONFIG_SPL_MAX_FOOTPRINT 32768 +#define CONFIG_SPL_PAD_TO 32768 +#endif + +/* additions for new relocation code, must added to all boards */ +#define CONFIG_SYS_SDRAM_BASE 0xc0000000 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \ + GENERATED_GBL_DATA_SIZE) +#endif /* __CONFIG_H */ diff --git a/include/configs/ot1200.h b/include/configs/ot1200.h index 3c60b4f..200f40a 100644 --- a/include/configs/ot1200.h +++ b/include/configs/ot1200.h @@ -62,6 +62,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 /* OCOTP Configs */ diff --git a/include/configs/platinum.h b/include/configs/platinum.h index 134bb45..91ffc7c 100644 --- a/include/configs/platinum.h +++ b/include/configs/platinum.h @@ -62,6 +62,7 @@ /* I2C config */ #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 /* MMC config */ diff --git a/include/configs/qemu-ppce500.h b/include/configs/qemu-ppce500.h index 763a47a..7071849 100644 --- a/include/configs/qemu-ppce500.h +++ b/include/configs/qemu-ppce500.h @@ -50,8 +50,14 @@ /* Physical address should be a function call */ #ifndef __ASSEMBLY__ extern unsigned long long get_phys_ccsrbar_addr_early(void); +#define CONFIG_SYS_CCSRBAR_PHYS_HIGH (get_phys_ccsrbar_addr_early() >> 32) +#define CONFIG_SYS_CCSRBAR_PHYS_LOW get_phys_ccsrbar_addr_early() +#else +#define CONFIG_SYS_CCSRBAR_PHYS_HIGH 0x0 +#define CONFIG_SYS_CCSRBAR_PHYS_LOW CONFIG_SYS_CCSRBAR #endif -#define CONFIG_SYS_CCSR_DO_NOT_RELOCATE + +#define CONFIG_PHYS_64BIT /* Virtual address range for PCI region maps */ #define CONFIG_SYS_PCI_MAP_START 0x80000000 diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index febbfb6..3bf45a2 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -21,9 +21,6 @@ #define CONFIG_SYS_TIMER_RATE 1000000 -#define CONFIG_BOOTSTAGE -#define CONFIG_BOOTSTAGE_REPORT - #define CONFIG_SYS_STDIO_DEREGISTER /* Number of bits in a C 'long' on this architecture */ @@ -34,6 +31,10 @@ #define CONFIG_CMD_FDT #define CONFIG_ANDROID_BOOT_IMAGE +#define CONFIG_CMD_PCI +#define CONFIG_PCI_PNP +#define CONFIG_CMD_IO + #define CONFIG_FS_FAT #define CONFIG_FAT_WRITE #define CONFIG_FS_EXT4 @@ -47,15 +48,12 @@ #define CONFIG_CMD_FS_GENERIC #define CONFIG_CMD_MD5SUM -#define CONFIG_SYS_VSNPRINTF - #define CONFIG_CMD_GPIO -#define CONFIG_SANDBOX_GPIO -#define CONFIG_SANDBOX_GPIO_COUNT 128 #define CONFIG_CMD_GPT #define CONFIG_PARTITION_UUIDS #define CONFIG_EFI_PARTITION +#define CONFIG_DOS_PARTITION /* * Size of malloc() pool, before and after relocation @@ -75,13 +73,11 @@ #define CONFIG_CMDLINE_EDITING #define CONFIG_COMMAND_HISTORY #define CONFIG_AUTO_COMPLETE -#define CONFIG_BOOTDELAY 3 #define CONFIG_ENV_SIZE 8192 #define CONFIG_ENV_IS_NOWHERE /* SPI - enable all SPI flash types for testing purposes */ -#define CONFIG_SANDBOX_SPI #define CONFIG_CMD_SF #define CONFIG_CMD_SF_TEST #define CONFIG_CMD_SPI @@ -90,14 +86,12 @@ #define CONFIG_SPI_FLASH_EON #define CONFIG_SPI_FLASH_GIGADEVICE #define CONFIG_SPI_FLASH_MACRONIX -#define CONFIG_SPI_FLASH_SANDBOX #define CONFIG_SPI_FLASH_SPANSION #define CONFIG_SPI_FLASH_SST #define CONFIG_SPI_FLASH_STMICRO #define CONFIG_SPI_FLASH_WINBOND #define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C_SANDBOX #define CONFIG_I2C_EDID #define CONFIG_I2C_EEPROM @@ -125,29 +119,42 @@ /* include default commands */ #include <config_cmd_default.h> - -/* We don't have networking support yet */ -#undef CONFIG_CMD_NET -#undef CONFIG_CMD_NFS +#include <config_distro_defaults.h> + +#define BOOT_TARGET_DEVICES(func) \ + func(HOST, host, 1) \ + func(HOST, host, 0) + +#include <config_distro_bootcmd.h> + +#define CONFIG_KEEP_SERVERADDR +#define CONFIG_UDP_CHECKSUM +#define CONFIG_CMD_LINK_LOCAL +#define CONFIG_CMD_CDP +#define CONFIG_CMD_DNS +#define CONFIG_CMD_SNTP +#define CONFIG_TIMESTAMP +#define CONFIG_CMD_RARP +#define CONFIG_BOOTP_DNS +#define CONFIG_BOOTP_DNS2 +#define CONFIG_BOOTP_SEND_HOSTNAME +#define CONFIG_BOOTP_SERVERIP +#define CONFIG_IP_DEFRAG + +/* Can't boot elf images */ +#undef CONFIG_CMD_ELF #define CONFIG_CMD_HASH #define CONFIG_HASH_VERIFY #define CONFIG_SHA1 #define CONFIG_SHA256 -#define CONFIG_TPM_TIS_SANDBOX - #define CONFIG_CMD_SANDBOX #define CONFIG_BOOTARGS "" -#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_BOARD_LATE_INIT -#define CONFIG_SOUND -#define CONFIG_SOUND_SANDBOX -#define CONFIG_CMD_SOUND - #ifndef SANDBOX_NO_SDL #define CONFIG_SANDBOX_SDL #endif @@ -165,23 +172,40 @@ #define CONFIG_KEYBOARD -#define CONFIG_EXTRA_ENV_SETTINGS "stdin=serial,cros-ec-keyb\0" \ +#define SANDBOX_SERIAL_SETTINGS "stdin=serial,cros-ec-keyb\0" \ "stdout=serial,lcd\0" \ "stderr=serial,lcd\0" #else - -#define CONFIG_EXTRA_ENV_SETTINGS "stdin=serial\0" \ +#define SANDBOX_SERIAL_SETTINGS "stdin=serial\0" \ "stdout=serial,lcd\0" \ "stderr=serial,lcd\0" #endif +#define SANDBOX_ETH_SETTINGS "ethaddr=00:00:11:22:33:44\0" \ + "eth1addr=00:00:11:22:33:45\0" \ + "eth5addr=00:00:11:22:33:46\0" \ + "ipaddr=1.2.3.4\0" + +#define MEM_LAYOUT_ENV_SETTINGS \ + "bootm_size=0x10000000\0" \ + "kernel_addr_r=0x1000000\0" \ + "fdt_addr_r=0xc00000\0" \ + "ramdisk_addr_r=0x2000000\0" \ + "scriptaddr=0x1000\0" \ + "pxefile_addr_r=0x2000\0" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + SANDBOX_SERIAL_SETTINGS \ + SANDBOX_ETH_SETTINGS \ + BOOTENV \ + MEM_LAYOUT_ENV_SETTINGS + #define CONFIG_GZIP_COMPRESSED #define CONFIG_BZIP2 #define CONFIG_LZO #define CONFIG_LZMA -#define CONFIG_TPM_TIS_SANDBOX - #define CONFIG_CMD_LZMADEC +#define CONFIG_CMD_USB #endif diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index 3b06d30..08381e3 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -22,7 +22,6 @@ #define CONFIG_POWER_MAX77686 #define CONFIG_BOARD_COMMON -#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_USB_XHCI #define CONFIG_USB_XHCI_EXYNOS diff --git a/include/configs/snow.h b/include/configs/snow.h index fe802f2..a2fb3f9 100644 --- a/include/configs/snow.h +++ b/include/configs/snow.h @@ -23,10 +23,11 @@ #define CONFIG_POWER_TPS65090_I2C #define CONFIG_BOARD_COMMON -#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_USB_XHCI +#define CONFIG_USB_EHCI #define CONFIG_USB_XHCI_EXYNOS +#define CONFIG_USB_EHCI_EXYNOS #define CONFIG_SYS_PROMPT "snow # " #define CONFIG_IDENT_STRING " for snow" diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h index 6d93472..41bb52b 100644 --- a/include/configs/socfpga_common.h +++ b/include/configs/socfpga_common.h @@ -40,7 +40,7 @@ #define CONFIG_SYS_MEMTEST_END PHYS_SDRAM_1_SIZE #define CONFIG_SYS_INIT_RAM_ADDR 0xFFFF0000 -#define CONFIG_SYS_INIT_RAM_SIZE (0x10000 - 0x100) +#define CONFIG_SYS_INIT_RAM_SIZE (0x10000 - CONFIG_SYS_SPL_MALLOC_SIZE) #define CONFIG_SYS_INIT_SP_ADDR \ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE - \ GENERATED_GBL_DATA_SIZE) @@ -99,7 +99,6 @@ * Ethernet on SoC (EMAC) */ #if defined(CONFIG_CMD_NET) && !defined(CONFIG_SOCFPGA_VIRTUAL_TARGET) -#define CONFIG_DESIGNWARE_ETH #define CONFIG_NET_MULTI #define CONFIG_DW_ALTDESCRIPTOR #define CONFIG_MII @@ -293,6 +292,7 @@ unsigned int cm_get_qspi_controller_clk_hz(void); #define CONFIG_SPL_TEXT_BASE CONFIG_SYS_INIT_RAM_ADDR #define CONFIG_SYS_SPL_MALLOC_START CONFIG_SYS_INIT_SP_ADDR #define CONFIG_SYS_SPL_MALLOC_SIZE (5 * 1024) +#define CONFIG_SPL_MAX_SIZE (64 * 1024) #define CHUNKSZ_CRC32 (1 * 1024) /* FIXME: ewww */ #define CONFIG_CRC32_VERIFY @@ -305,6 +305,11 @@ unsigned int cm_get_qspi_controller_clk_hz(void); #define CONFIG_SPL_WATCHDOG_SUPPORT #define CONFIG_SPL_SERIAL_SUPPORT +/* + * Stack setup + */ +#define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR + #ifdef CONFIG_SPL_BUILD #undef CONFIG_PARTITIONS #endif diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h index 16281f5..409cf54 100644 --- a/include/configs/spear-common.h +++ b/include/configs/spear-common.h @@ -18,7 +18,6 @@ /* Ethernet driver configuration */ #define CONFIG_MII -#define CONFIG_DESIGNWARE_ETH #define CONFIG_NET_MULTI #define CONFIG_PHYLIB #define CONFIG_PHY_RESET_DELAY 10000 /* in usec */ diff --git a/include/configs/stm32f429-discovery.h b/include/configs/stm32f429-discovery.h new file mode 100644 index 0000000..7f569fd --- /dev/null +++ b/include/configs/stm32f429-discovery.h @@ -0,0 +1,106 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, <rev13@wp.pl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CONFIG_STM32F4 +#define CONFIG_STM32F4DISCOVERY +#define CONFIG_SYS_GENERIC_BOARD + +#define CONFIG_OF_LIBFDT + +#define CONFIG_BOARD_EARLY_INIT_F + +#define CONFIG_SYS_FLASH_BASE 0x08000000 + +#define CONFIG_SYS_INIT_SP_ADDR 0x10010000 +#define CONFIG_SYS_TEXT_BASE 0x08000000 + +#define CONFIG_SYS_ICACHE_OFF +#define CONFIG_SYS_DCACHE_OFF + +/* + * Configuration of the external SDRAM memory + */ +#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_SYS_RAM_SIZE (8 << 20) +#define CONFIG_SYS_RAM_CS 1 +#define CONFIG_SYS_RAM_FREQ_DIV 2 +#define CONFIG_SYS_RAM_BASE 0xD0000000 +#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_RAM_BASE +#define CONFIG_SYS_LOAD_ADDR 0xD0400000 +#define CONFIG_LOADADDR 0xD0400000 + +#define CONFIG_SYS_MAX_FLASH_SECT 12 +#define CONFIG_SYS_MAX_FLASH_BANKS 2 + +#define CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_OFFSET (256 << 10) +#define CONFIG_ENV_SECT_SIZE (128 << 10) +#define CONFIG_ENV_SIZE (8 << 10) + +#define CONFIG_BOARD_SPECIFIC_LED +#define CONFIG_RED_LED 110 +#define CONFIG_GREEN_LED 109 + +#define CONFIG_STM32_GPIO +#define CONFIG_STM32_SERIAL + +#define CONFIG_STM32_USART1 + +#define CONFIG_STM32_HSE_HZ 8000000 + +#define CONFIG_SYS_HZ_CLOCK 1000000 /* Timer is clocked at 1MHz */ + +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG + +#define CONFIG_SYS_CBSIZE 1024 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE \ + + sizeof(CONFIG_SYS_PROMPT) + 16) + +#define CONFIG_SYS_MAXARGS 16 + +#define CONFIG_SYS_MALLOC_LEN (2 << 20) + +#define CONFIG_STACKSIZE (64 << 10) + +#define CONFIG_BAUDRATE 115200 +#define CONFIG_BOOTARGS \ + "console=ttystm0,115200 earlyprintk consoleblank=0 ignore_loglevel" +#define CONFIG_BOOTCOMMAND \ + "run bootcmd_romfs" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "bootargs_romfs=uclinux.physaddr=0x08180000 root=/dev/mtdblock0\0" \ + "bootcmd_romfs=setenv bootargs ${bootargs} ${bootargs_romfs};" \ + "bootm 0x08044000 - 0x08042000\0" + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_AUTOBOOT + +/* + * Command line configuration. + */ +#include <config_cmd_default.h> + +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_HUSH_PARSER +#define CONFIG_SYS_PROMPT "U-Boot > " +#define CONFIG_AUTO_COMPLETE +#define CONFIG_CMDLINE_EDITING + +#define CONFIG_CMD_FLASH +#define CONFIG_CMD_SAVEENV +#define CONFIG_CMD_MEM +#define CONFIG_CMD_MISC +#define CONFIG_CMD_TIMER + +#endif /* __CONFIG_H */ diff --git a/include/configs/stv0991.h b/include/configs/stv0991.h index 156e0fa..ab1e61c 100644 --- a/include/configs/stv0991.h +++ b/include/configs/stv0991.h @@ -55,7 +55,6 @@ #define CONFIG_MII #define CONFIG_PHYLIB #define CONFIG_CMD_NET -#define CONFIG_DESIGNWARE_ETH #define CONFIG_DW_ALTDESCRIPTOR #define CONFIG_PHY_MICREL diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 1f7a1cb..365d9a5 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -196,7 +196,11 @@ #endif #define CONFIG_SYS_I2C +#if defined CONFIG_I2C0_ENABLE || defined CONFIG_I2C1_ENABLE || \ + defined CONFIG_I2C2_ENABLE || defined CONFIG_I2C3_ENABLE || \ + defined CONFIG_I2C4_ENABLE #define CONFIG_SYS_I2C_MVTWSI +#endif #define CONFIG_SYS_I2C_SPEED 400000 #define CONFIG_SYS_I2C_SLAVE 0x7f @@ -284,7 +288,6 @@ extern int soft_i2c_gpio_scl; #endif #ifdef CONFIG_SUNXI_GMAC -#define CONFIG_DESIGNWARE_ETH /* GMAC can use designware driver */ #define CONFIG_DW_AUTONEG #define CONFIG_PHY_GIGE /* GMAC can use gigabit PHY */ #define CONFIG_PHY_ADDR 1 diff --git a/include/configs/tb100.h b/include/configs/tb100.h index 501449a..b2b4b10 100644 --- a/include/configs/tb100.h +++ b/include/configs/tb100.h @@ -62,7 +62,6 @@ /* * Ethernet configuration */ -#define CONFIG_DESIGNWARE_ETH #define ETH0_BASE_ADDRESS 0xFE100000 #define ETH1_BASE_ADDRESS 0xFE110000 diff --git a/include/configs/tbs2910.h b/include/configs/tbs2910.h index 7089378..3a88f22 100644 --- a/include/configs/tbs2910.h +++ b/include/configs/tbs2910.h @@ -199,6 +199,7 @@ #ifdef CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 #define CONFIG_I2C_EDID #endif diff --git a/include/configs/ti_omap5_common.h b/include/configs/ti_omap5_common.h index 7957a73..f2be8d5 100644 --- a/include/configs/ti_omap5_common.h +++ b/include/configs/ti_omap5_common.h @@ -144,13 +144,20 @@ "loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile};\0" \ DFUARGS \ + #define CONFIG_BOOTCOMMAND \ + "if test ${dofastboot} -eq 1; then " \ + "echo Boot fastboot requested, resetting dofastboot ...;" \ + "setenv dofastboot 0; saveenv;" \ + "echo Booting into fastboot ...; fastboot;" \ + "fi;" \ "run findfdt; " \ "run mmcboot;" \ "setenv mmcdev 1; " \ "setenv bootpart 1:2; " \ "setenv mmcroot /dev/mmcblk0p2 rw; " \ "run mmcboot;" \ + "" /* diff --git a/include/configs/titanium.h b/include/configs/titanium.h index f9e00c5..320d76c 100644 --- a/include/configs/titanium.h +++ b/include/configs/titanium.h @@ -44,6 +44,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 /* MMC Configs */ diff --git a/include/configs/tqma6.h b/include/configs/tqma6.h index a099687..012fa1c 100644 --- a/include/configs/tqma6.h +++ b/include/configs/tqma6.h @@ -35,16 +35,6 @@ #define PHYS_SDRAM_SIZE (1024u * SZ_1M) #endif -#if defined(CONFIG_MBA6) - -#if defined(CONFIG_MX6DL) || defined(CONFIG_MX6S) -#define CONFIG_DEFAULT_FDT_FILE "imx6dl-mba6x.dtb" -#elif defined(CONFIG_MX6Q) || defined(CONFIG_MX6Q) -#define CONFIG_DEFAULT_FDT_FILE "imx6q-mba6x.dtb" -#endif - -#endif - #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_SYS_GENERIC_BOARD @@ -80,16 +70,12 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_I2C_MULTI_BUS #define CONFIG_SYS_I2C_SPEED 100000 /* I2C SYSMON (LM75) */ #define CONFIG_DTT_LM75 -#if defined(CONFIG_MBA6) -#define CONFIG_DTT_SENSORS { 0, 1 } -#else -#define CONFIG_DTT_SENSORS { 0 } -#endif #define CONFIG_DTT_MAX_TEMP 70 #define CONFIG_DTT_MIN_TEMP -30 #define CONFIG_DTT_HYSTERESIS 3 @@ -147,38 +133,12 @@ #define CONFIG_PHYLIB #define CONFIG_MII -#if defined(CONFIG_MBA6) - -#define CONFIG_FEC_XCV_TYPE RGMII -#define CONFIG_ETHPRIME "FEC" - -#define CONFIG_FEC_MXC_PHYADDR 0x03 -#define CONFIG_PHY_MICREL -#define CONFIG_PHY_KSZ9031 - -#else - -#error "define PHY to use for your baseboard" - -#endif - #define CONFIG_ARP_TIMEOUT 200UL /* Network config - Allow larger/faster download for TFTP/NFS */ #define CONFIG_IP_DEFRAG #define CONFIG_TFTP_BLOCKSIZE 4096 #define CONFIG_NFS_READ_SIZE 4096 -#if defined(CONFIG_MBA6) - -#define CONFIG_MXC_UART_BASE UART2_BASE -#define CONFIG_CONSOLE_DEV "ttymxc1" - -#else - -#error "define baseboard specific things (uart, number of SD-card slots)" - -#endif - /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE #define CONFIG_CONS_INDEX 1 @@ -492,4 +452,20 @@ #define CONFIG_CMD_CACHE #endif +/* + * All the defines above are for the TQMa6 SoM + * + * Now include the baseboard specific configuration + */ +#ifdef CONFIG_MBA6 +#include "tqma6_mba6.h" +#else +#error "No baseboard for the TQMa6 defined!" +#endif + +/* Support at least the sensor on TQMa6 SOM */ +#if !defined(CONFIG_DTT_SENSORS) +#define CONFIG_DTT_SENSORS { 0 } +#endif + #endif /* __CONFIG_H */ diff --git a/include/configs/tqma6_mba6.h b/include/configs/tqma6_mba6.h new file mode 100644 index 0000000..88c0067 --- /dev/null +++ b/include/configs/tqma6_mba6.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2013, 2014 Markus Niebel <Markus.Niebel@tq-group.com> + * + * Configuration settings for the TQ Systems TQMa6<Q,S> module. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_TQMA6_MBA6_H +#define __CONFIG_TQMA6_MBA6_H + +#if defined(CONFIG_MX6DL) || defined(CONFIG_MX6S) +#define CONFIG_DEFAULT_FDT_FILE "imx6dl-mba6x.dtb" +#elif defined(CONFIG_MX6Q) || defined(CONFIG_MX6Q) +#define CONFIG_DEFAULT_FDT_FILE "imx6q-mba6x.dtb" +#endif + +#define CONFIG_DTT_SENSORS { 0, 1 } + +#define CONFIG_FEC_XCV_TYPE RGMII +#define CONFIG_ETHPRIME "FEC" + +#define CONFIG_FEC_MXC_PHYADDR 0x03 +#define CONFIG_PHY_MICREL +#define CONFIG_PHY_KSZ9031 + +#define CONFIG_MXC_UART_BASE UART2_BASE +#define CONFIG_CONSOLE_DEV "ttymxc1" + +#endif /* __CONFIG_TQMA6_MBA6_H */ diff --git a/include/configs/tseries.h b/include/configs/tseries.h index a6c7d5f..1e41a12 100644 --- a/include/configs/tseries.h +++ b/include/configs/tseries.h @@ -23,6 +23,8 @@ #define CONFIG_HW_WATCHDOG #define CONFIG_OMAP_WATCHDOG #define CONFIG_SPL_WATCHDOG_SUPPORT + +#define CONFIG_SPL_GPIO_SUPPORT /* Bootcount using the RTC block */ #define CONFIG_SYS_BOOTCOUNT_ADDR 0x44E3E000 #define CONFIG_BOOTCOUNT_LIMIT @@ -103,15 +105,16 @@ "mtdparts=" MTDPARTS_DEFAULT "\0" \ "nandargs=setenv bootargs console=${console} " \ "${optargs} " \ - "root=${nandroot} " \ - "rootfstype=${nandrootfstype}\0" \ - "nandroot=ubi0:rootfs rw ubi.mtd=8,2048\0" \ - "nandrootfstype=ubifs rootwait=1\0" \ - "nandimgsize=0x500000\0" \ - "nandboot=echo Booting from nand ...; " \ + "root=mtd6 " \ + "rootfstype=jffs2\0" \ + "kernelsize=0x400000\0" \ + "nandboot=echo booting from nand ...; " \ "run nandargs; " \ - "nand read ${loadaddr} kernel ${nandimgsize}; " \ - "bootz ${loadaddr}\0" + "nand read ${loadaddr} kernel ${kernelsize}; " \ + "bootz ${loadaddr} - ${dtbaddr}\0" \ + "defboot=run nandboot\0" \ + "bootlimit=1\0" \ + "altbootcmd=run usbscript\0" #else #define NANDARGS "" #endif /* CONFIG_NAND */ @@ -231,15 +234,15 @@ MMCARGS #define MTDIDS_DEFAULT "nand0=omap2-nand.0" #define MTDPARTS_DEFAULT "mtdparts=omap2-nand.0:" \ - "128k(SPL)," \ - "128k(SPL.backup1)," \ - "128k(SPL.backup2)," \ - "128k(SPL.backup3)," \ - "512k(u-boot)," \ - "128k(u-boot-spl-os)," \ + "128k(MLO)," \ + "128k(MLO.backup)," \ + "128k(dtb)," \ "128k(u-boot-env)," \ - "5m(kernel),"\ - "-(rootfs)" + "512k(u-boot)," \ + "4m(kernel),"\ + "128m(rootfs),"\ + "-(user)" +#define CONFIG_NAND_OMAP_GPMC_WSCFG 1 #endif /* CONFIG_NAND */ /* USB configuration */ @@ -298,7 +301,7 @@ MMCARGS #else #define CONFIG_ENV_IS_IN_NAND #endif -#define CONFIG_ENV_OFFSET 0x120000 /* TODO: Adresse definieren */ +#define CONFIG_ENV_OFFSET 0x60000 #define CONFIG_SYS_ENV_SECT_SIZE CONFIG_ENV_SIZE #else #error "no storage for Environment defined!" diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h index 3fda20a..032010b 100644 --- a/include/configs/vexpress_aemv8a.h +++ b/include/configs/vexpress_aemv8a.h @@ -8,10 +8,9 @@ #ifndef __VEXPRESS_AEMV8A_H #define __VEXPRESS_AEMV8A_H -#define CONFIG_DM - -/* We use generic board for v8 Versatile Express */ +/* We use generic board and device manager for v8 Versatile Express */ #define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_DM #ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP #ifndef CONFIG_SEMIHOSTING @@ -134,27 +133,16 @@ #endif /* PL011 Serial Configuration */ -#define CONFIG_BAUDRATE 115200 -#ifdef CONFIG_DM #define CONFIG_DM_SERIAL -#define CONFIG_PL01X_SERIAL -#else -#define CONFIG_SYS_SERIAL0 V2M_UART0 -#define CONFIG_SYS_SERIAL1 V2M_UART1 +#define CONFIG_BAUDRATE 115200 #define CONFIG_CONS_INDEX 0 +#define CONFIG_PL01X_SERIAL #define CONFIG_PL011_SERIAL #ifdef CONFIG_TARGET_VEXPRESS64_JUNO #define CONFIG_PL011_CLOCK 7273800 #else #define CONFIG_PL011_CLOCK 24000000 #endif -#define CONFIG_PL01x_PORTS {(void *)CONFIG_SYS_SERIAL0, \ - (void *)CONFIG_SYS_SERIAL1} -#endif - -#define CONFIG_BAUDRATE 115200 -#define CONFIG_SYS_SERIAL0 V2M_UART0 -#define CONFIG_SYS_SERIAL1 V2M_UART1 /* Command line configuration */ #define CONFIG_MENU diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h index b586803..b2c3614 100644 --- a/include/configs/wandboard.h +++ b/include/configs/wandboard.h @@ -62,6 +62,7 @@ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 /* MMC Configuration */ diff --git a/include/configs/woodburn_common.h b/include/configs/woodburn_common.h index 48b8692..d0895cf 100644 --- a/include/configs/woodburn_common.h +++ b/include/configs/woodburn_common.h @@ -47,6 +47,7 @@ */ #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_SPD_BUS_NUM 0 #define CONFIG_MXC_SPI #define CONFIG_MXC_GPIO diff --git a/include/configs/x600.h b/include/configs/x600.h index 241bf65..27a66a5 100644 --- a/include/configs/x600.h +++ b/include/configs/x600.h @@ -74,7 +74,6 @@ /* Ethernet config options */ #define CONFIG_MII -#define CONFIG_DESIGNWARE_ETH #define CONFIG_NET_MULTI #define CONFIG_PHYLIB #define CONFIG_PHY_RESET_DELAY 10000 /* in usec */ diff --git a/include/configs/x86-chromebook.h b/include/configs/x86-chromebook.h new file mode 100644 index 0000000..b6a76fe --- /dev/null +++ b/include/configs/x86-chromebook.h @@ -0,0 +1,68 @@ +/* + * + * Copyright (c) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _X86_CHROMEBOOK_H +#define _X86_CHROMEBOOK_H + +#define CONFIG_SYS_MONITOR_LEN (1 << 20) + +#define CONFIG_DCACHE_RAM_MRC_VAR_SIZE 0x4000 +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_MISC_INIT_R + +#define CONFIG_NR_DRAM_BANKS 8 +#define CONFIG_X86_MRC_ADDR 0xfffa0000 +#define CONFIG_CACHE_MRC_SIZE_KB 512 + +#define CONFIG_X86_SERIAL + +#define CONFIG_SCSI_DEV_LIST \ + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_NM10_AHCI}, \ + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_MOBILE}, \ + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_SERIES6}, \ + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE}, \ + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_AHCI} + +#define CONFIG_X86_OPTION_ROM_FILE pci8086,0166.bin +#define CONFIG_X86_OPTION_ROM_ADDR 0xfff90000 + +#define CONFIG_PCI_MEM_BUS 0xe0000000 +#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS +#define CONFIG_PCI_MEM_SIZE 0x10000000 + +#define CONFIG_PCI_PREF_BUS 0xd0000000 +#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS +#define CONFIG_PCI_PREF_SIZE 0x10000000 + +#define CONFIG_PCI_IO_BUS 0x1000 +#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS +#define CONFIG_PCI_IO_SIZE 0xefff + +#define CONFIG_SYS_EARLY_PCI_INIT +#define CONFIG_PCI_PNP + +#define CONFIG_BIOSEMU +#define VIDEO_IO_OFFSET 0 +#define CONFIG_X86EMU_RAW_IO + +#define CONFIG_CROS_EC +#define CONFIG_CROS_EC_LPC +#define CONFIG_CMD_CROS_EC +#define CONFIG_ARCH_EARLY_INIT_R + +#undef CONFIG_ENV_IS_NOWHERE +#undef CONFIG_ENV_SIZE +#define CONFIG_ENV_SIZE 0x1000 +#define CONFIG_ENV_SECT_SIZE 0x1000 +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_OFFSET 0x003f8000 + +#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \ + "stdout=vga,serial\0" \ + "stderr=vga,serial\0" + +#endif diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index b7dd63e..9571c65 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -16,7 +16,6 @@ * (easy to change) */ #define CONFIG_SHOW_BOOT_PROGRESS -#define CONFIG_SYS_VSNPRINTF #define CONFIG_ZBOOT_32 #define CONFIG_PHYSMEM #define CONFIG_DISPLAY_BOARDINFO_LATE @@ -204,7 +203,6 @@ #define CONFIG_CMD_SF_TEST #define CONFIG_CMD_SPI #define CONFIG_SPI -#define CONFIG_OF_SPI_FLASH /*----------------------------------------------------------------------- * Environment configuration @@ -238,9 +236,6 @@ #define CONFIG_BOOTP_GATEWAY #define CONFIG_BOOTP_HOSTNAME -#define CONFIG_BOOTSTAGE -#define CONFIG_CMD_BOOTSTAGE - #define CONFIG_CMD_USB /* Default environment */ diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h index 511ecca..880d29c 100644 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@ -36,7 +36,7 @@ #define CPU_RELEASE_ADDR 0xFFFFFF0 /* Cache Definitions */ -#define CONFIG_SYS_DCACHE_OFF +#define CONFIG_SYS_CACHELINE_SIZE 64 #define CONFIG_IDENT_STRING " Xilinx ZynqMP" @@ -61,13 +61,25 @@ #define CONFIG_SYS_BAUDRATE_TABLE \ { 4800, 9600, 19200, 38400, 57600, 115200 } +#define CONFIG_ZYNQ_SDHCI0 + /* Command line configuration */ #define CONFIG_CMD_ENV #define CONFIG_CMD_EXT2 #define CONFIG_CMD_EXT4 #define CONFIG_CMD_FAT +#define CONFIG_CMD_FS_GENERIC #define CONFIG_CMD_MEMORY #define CONFIG_DOS_PARTITION +#define CONFIG_CMD_ELF +#define CONFIG_MP + +/* SPI */ +#ifdef CONFIG_ZYNQ_SPI +# define CONFIG_SPI_FLASH +# define CONFIG_SPI_FLASH_SST +# define CONFIG_CMD_SF +#endif #if defined(CONFIG_ZYNQ_SDHCI0) || defined(CONFIG_ZYNQ_SDHCI1) # define CONFIG_MMC @@ -90,8 +102,8 @@ "kernel_addr=0x80000\0" \ "fdt_addr=0x7000000\0" \ "fdt_high=0x10000000\0" \ - "sdboot=mmcinfo && fatload mmc 0:0 $fdt_addr system.dtb && " \ - "fatload mmc 0:0 $kernel_addr Image && booti $kernel_addr - $fdt_addr\0" + "sdboot=mmcinfo && load mmc 0:0 $fdt_addr system.dtb && " \ + "load mmc 0:0 $kernel_addr Image && booti $kernel_addr - $fdt_addr\0" #define CONFIG_BOOTARGS "setenv bootargs console=ttyPS0,${baudrate} " \ "earlycon=cdns,mmio,0xff000000,${baudrate}n8" @@ -117,6 +129,29 @@ #define CONFIG_CMDLINE_EDITING #define CONFIG_SYS_MAXARGS 64 +#define CONFIG_ZYNQ_I2C0 +#define CONFIG_SYS_I2C_ZYNQ + +/* I2C */ +#if defined(CONFIG_SYS_I2C_ZYNQ) +# define CONFIG_CMD_I2C +# define CONFIG_SYS_I2C +# define CONFIG_SYS_I2C_ZYNQ_SPEED 100000 +# define CONFIG_SYS_I2C_ZYNQ_SLAVE 0 +#endif + +#define CONFIG_ZYNQMP_EEPROM + +/* EEPROM */ +#ifdef CONFIG_ZYNQMP_EEPROM +# define CONFIG_CMD_EEPROM +# define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 +# define CONFIG_SYS_I2C_EEPROM_ADDR 0x54 +# define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 4 +# define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 5 +# define CONFIG_SYS_EEPROM_SIZE (64 * 1024) +#endif + #define CONFIG_FIT #define CONFIG_FIT_VERBOSE /* enable fit_format_{error,warning}() */ diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index a7c6dce..926b381 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -38,6 +38,9 @@ # define CONFIG_ZYNQ_SERIAL #endif +#define CONFIG_ZYNQ_GPIO +#define CONFIG_CMD_GPIO + /* Ethernet driver */ #if defined(CONFIG_ZYNQ_GEM0) || defined(CONFIG_ZYNQ_GEM1) # define CONFIG_NET_MULTI @@ -290,7 +293,7 @@ # define CONFIG_SYS_MMC_MAX_DEVICE 1 #endif -#define CONFIG_SYS_LDSCRIPT "arch/arm/cpu/armv7/zynq/u-boot.lds" +#define CONFIG_SYS_LDSCRIPT "arch/arm/mach-zynq/u-boot.lds" /* Commands */ #include <config_cmd_default.h> @@ -308,7 +311,7 @@ #define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_BOARD_INIT -#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/zynq/u-boot-spl.lds" +#define CONFIG_SPL_LDSCRIPT "arch/arm/mach-zynq/u-boot-spl.lds" /* MMC support */ #ifdef CONFIG_ZYNQ_SDHCI0 diff --git a/include/configs/zynq_picozed.h b/include/configs/zynq_picozed.h new file mode 100644 index 0000000..d116e05 --- /dev/null +++ b/include/configs/zynq_picozed.h @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2015 Xilinx, Inc. + * + * Configuration for PicoZed + * See zynq-common.h for Zynq common configs + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_ZYNQ_PICOZED_H +#define __CONFIG_ZYNQ_PICOZED_H + +#define CONFIG_SYS_SDRAM_SIZE (1024 * 1024 * 1024) + +#define CONFIG_ZYNQ_SERIAL_UART1 +#define CONFIG_ZYNQ_GEM0 +#define CONFIG_ZYNQ_GEM_PHY_ADDR0 0 + +#define CONFIG_SYS_NO_FLASH + +#define CONFIG_ZYNQ_SDHCI1 +#define CONFIG_ZYNQ_USB +#define CONFIG_ZYNQ_BOOT_FREEBSD + +#include <configs/zynq-common.h> + +#endif /* __CONFIG_ZYNQ_PICOZED_H */ diff --git a/include/cros_ec.h b/include/cros_ec.h index 8457c80..3b2be2c 100644 --- a/include/cros_ec.h +++ b/include/cros_ec.h @@ -15,31 +15,9 @@ #include <cros_ec_message.h> #include <asm/gpio.h> -#ifndef CONFIG_DM_CROS_EC -/* Which interface is the device on? */ -enum cros_ec_interface_t { - CROS_EC_IF_NONE, - CROS_EC_IF_SPI, - CROS_EC_IF_I2C, - CROS_EC_IF_LPC, /* Intel Low Pin Count interface */ - CROS_EC_IF_SANDBOX, -}; -#endif - /* Our configuration information */ struct cros_ec_dev { -#ifdef CONFIG_DM_CROS_EC struct udevice *dev; /* Transport device */ -#else - enum cros_ec_interface_t interface; - struct spi_slave *spi; /* Our SPI slave, if using SPI */ - int node; /* Our node */ - int parent_node; /* Our parent node (interface) */ - unsigned int cs; /* Our chip select */ - unsigned int addr; /* Device address (for I2C) */ - unsigned int bus_num; /* Bus number (for I2C) */ - unsigned int max_frequency; /* Maximum interface frequency */ -#endif struct gpio_desc ec_int; /* GPIO used as EC interrupt line */ int protocol_version; /* Protocol version to use */ int optimise_flash_write; /* Don't write erased flash blocks */ @@ -240,8 +218,6 @@ int cros_ec_flash_update_rw(struct cros_ec_dev *dev, */ struct cros_ec_dev *board_get_cros_ec_dev(void); -#ifdef CONFIG_DM_CROS_EC - struct dm_cros_ec_ops { int (*check_version)(struct udevice *dev); int (*command)(struct udevice *dev, uint8_t cmd, int cmd_version, @@ -255,112 +231,6 @@ struct dm_cros_ec_ops { int cros_ec_register(struct udevice *dev); -#else /* !CONFIG_DM_CROS_EC */ - -/* Internal interfaces */ -int cros_ec_i2c_init(struct cros_ec_dev *dev, const void *blob); -int cros_ec_spi_init(struct cros_ec_dev *dev, const void *blob); -int cros_ec_lpc_init(struct cros_ec_dev *dev, const void *blob); -int cros_ec_sandbox_init(struct cros_ec_dev *dev, const void *blob); - -/** - * Read information from the fdt for the i2c cros_ec interface - * - * @param dev CROS-EC device - * @param blob Device tree blob - * @return 0 if ok, -1 if we failed to read all required information - */ -int cros_ec_i2c_decode_fdt(struct cros_ec_dev *dev, const void *blob); - -/** - * Read information from the fdt for the spi cros_ec interface - * - * @param dev CROS-EC device - * @param blob Device tree blob - * @return 0 if ok, -1 if we failed to read all required information - */ -int cros_ec_spi_decode_fdt(struct cros_ec_dev *dev, const void *blob); - -/** - * Read information from the fdt for the sandbox cros_ec interface - * - * @param dev CROS-EC device - * @param blob Device tree blob - * @return 0 if ok, -1 if we failed to read all required information - */ -int cros_ec_sandbox_decode_fdt(struct cros_ec_dev *dev, const void *blob); - -/** - * Check whether the LPC interface supports new-style commands. - * - * LPC has its own way of doing this, which involves checking LPC values - * visible to the host. Do this, and update dev->protocol_version accordingly. - * - * @param dev CROS-EC device to check - */ -int cros_ec_lpc_check_version(struct cros_ec_dev *dev); - -/** - * Send a command to an I2C CROS-EC device and return the reply. - * - * This rather complicated function deals with sending both old-style and - * new-style commands. The old ones have just a command byte and arguments. - * The new ones have version, command, arg-len, [args], chksum so are 3 bytes - * longer. - * - * The device's internal input/output buffers are used. - * - * @param dev CROS-EC device - * @param cmd Command to send (EC_CMD_...) - * @param cmd_version Version of command to send (EC_VER_...) - * @param dout Output data (may be NULL If dout_len=0) - * @param dout_len Size of output data in bytes - * @param dinp Returns pointer to response data - * @param din_len Maximum size of response in bytes - * @return number of bytes in response, or -1 on error - */ -int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, - const uint8_t *dout, int dout_len, - uint8_t **dinp, int din_len); - -/** - * Send a command to a LPC CROS-EC device and return the reply. - * - * The device's internal input/output buffers are used. - * - * @param dev CROS-EC device - * @param cmd Command to send (EC_CMD_...) - * @param cmd_version Version of command to send (EC_VER_...) - * @param dout Output data (may be NULL If dout_len=0) - * @param dout_len Size of output data in bytes - * @param dinp Returns pointer to response data - * @param din_len Maximum size of response in bytes - * @return number of bytes in response, or -1 on error - */ -int cros_ec_lpc_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, - const uint8_t *dout, int dout_len, - uint8_t **dinp, int din_len); - -int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, - const uint8_t *dout, int dout_len, - uint8_t **dinp, int din_len); - -/** - * Send a packet to a CROS-EC device and return the response packet. - * - * Expects the request packet to be stored in dev->dout. Stores the response - * packet in dev->din. - * - * @param dev CROS-EC device - * @param out_bytes Size of request packet to output - * @param in_bytes Maximum size of response packet to receive - * @return number of bytes in response packet, or <0 on error - */ -int cros_ec_spi_packet(struct cros_ec_dev *dev, int out_bytes, int in_bytes); -int cros_ec_sandbox_packet(struct cros_ec_dev *dev, int out_bytes, - int in_bytes); -#endif - /** * Dump a block of data for a command. * @@ -493,13 +363,6 @@ int cros_ec_set_ldo(struct cros_ec_dev *dev, uint8_t index, uint8_t state); int cros_ec_get_ldo(struct cros_ec_dev *dev, uint8_t index, uint8_t *state); /** - * Initialize the Chrome OS EC at board initialization time. - * - * @return 0 if ok, -ve on error - */ -int cros_ec_board_init(void); - -/** * Get access to the error reported when cros_ec_board_init() was called * * This permits delayed reporting of the EC error if it failed during diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h index e2418fe..687462b 100644 --- a/include/dm/device-internal.h +++ b/include/dm/device-internal.h @@ -34,7 +34,7 @@ struct udevice; * @devp: Returns a pointer to the bound device * @return 0 if OK, -ve on error */ -int device_bind(struct udevice *parent, struct driver *drv, +int device_bind(struct udevice *parent, const struct driver *drv, const char *name, void *platdata, int of_offset, struct udevice **devp); diff --git a/include/dm/device.h b/include/dm/device.h index 7a48eb8..18296bb 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -30,6 +30,12 @@ struct driver_info; /* DM is responsible for allocating and freeing parent_platdata */ #define DM_FLAG_ALLOC_PARENT_PDATA (1 << 3) +/* DM is responsible for allocating and freeing uclass_platdata */ +#define DM_FLAG_ALLOC_UCLASS_PDATA (1 << 4) + +/* Allocate driver private data on a DMA boundary */ +#define DM_FLAG_ALLOC_PRIV_DMA (1 << 5) + /** * struct udevice - An instance of a driver * @@ -51,8 +57,10 @@ struct driver_info; * @name: Name of device, typically the FDT node name * @platdata: Configuration data for this device * @parent_platdata: The parent bus's configuration data for this device + * @uclass_platdata: The uclass's configuration data for this device * @of_offset: Device tree node offset for this device (- for none) - * @of_id: Pointer to the udevice_id structure which created the device + * @driver_data: Driver data word for the entry that matched this device with + * its driver * @parent: Parent of this device, or NULL for the top level device * @priv: Private data for this device * @uclass: Pointer to uclass for this device @@ -67,12 +75,13 @@ struct driver_info; * when the device is probed and will be unique within the device's uclass. */ struct udevice { - struct driver *driver; + const struct driver *driver; const char *name; void *platdata; void *parent_platdata; + void *uclass_platdata; int of_offset; - const struct udevice_id *of_id; + ulong driver_data; struct udevice *parent; void *priv; struct uclass *uclass; @@ -206,6 +215,16 @@ void *dev_get_platdata(struct udevice *dev); void *dev_get_parent_platdata(struct udevice *dev); /** + * dev_get_uclass_platdata() - Get the uclass platform data for a device + * + * This checks that dev is not NULL, but no other checks for now + * + * @dev Device to check + * @return uclass's platform data, or NULL if none + */ +void *dev_get_uclass_platdata(struct udevice *dev); + +/** * dev_get_parentdata() - Get the parent data for a device * * The parent data is data stored in the device but owned by the parent. @@ -238,13 +257,39 @@ void *dev_get_priv(struct udevice *dev); struct udevice *dev_get_parent(struct udevice *child); /** - * dev_get_of_data() - get the device tree data used to bind a device + * dev_get_uclass_priv() - Get the private uclass data for a device + * + * This checks that dev is not NULL, but no other checks for now + * + * @dev Device to check + * @return private uclass data for this device, or NULL if none + */ +void *dev_get_uclass_priv(struct udevice *dev); + +/** + * dev_get_driver_data() - get the driver data used to bind a device * * When a device is bound using a device tree node, it matches a * particular compatible string as in struct udevice_id. This function - * returns the associated data value for that compatible string + * returns the associated data value for that compatible string. This is + * the 'data' field in struct udevice_id. + * + * For USB devices, this is the driver_info field in struct usb_device_id. + * + * @dev: Device to check */ -ulong dev_get_of_data(struct udevice *dev); +ulong dev_get_driver_data(struct udevice *dev); + +/** + * dev_get_driver_ops() - get the device's driver's operations + * + * This checks that dev is not NULL, and returns the pointer to device's + * driver's operations. + * + * @dev: Device to check + * @return void pointer to driver's operations or NULL for NULL-dev or NULL-ops + */ +const void *dev_get_driver_ops(struct udevice *dev); /* * device_get_uclass_id() - return the uclass ID of a device @@ -254,6 +299,16 @@ ulong dev_get_of_data(struct udevice *dev); */ enum uclass_id device_get_uclass_id(struct udevice *dev); +/* + * dev_get_uclass_name() - return the uclass name of a device + * + * This checks that dev is not NULL. + * + * @dev: Device to check + * @return pointer to the uclass name for the device + */ +const char *dev_get_uclass_name(struct udevice *dev); + /** * device_get_child() - Get the child of a device by index * @@ -361,4 +416,34 @@ int device_find_next_child(struct udevice **devp); */ fdt_addr_t dev_get_addr(struct udevice *dev); +/** + * device_has_children() - check if a device has any children + * + * @dev: Device to check + * @return true if the device has one or more children + */ +bool device_has_children(struct udevice *dev); + +/** + * device_has_active_children() - check if a device has any active children + * + * @dev: Device to check + * @return true if the device has one or more children and at least one of + * them is active (probed). + */ +bool device_has_active_children(struct udevice *dev); + +/** + * device_is_last_sibling() - check if a device is the last sibling + * + * This function can be useful for display purposes, when special action needs + * to be taken when displaying the last sibling. This can happen when a tree + * view of devices is being displayed. + * + * @dev: Device to check + * @return true if there are no more siblings after this one - i.e. is it + * last in the list. + */ +bool device_is_last_sibling(struct udevice *dev); + #endif diff --git a/include/dm/test.h b/include/dm/test.h index 707c69e..f03fbcb 100644 --- a/include/dm/test.h +++ b/include/dm/test.h @@ -44,6 +44,7 @@ enum { /* For uclass */ DM_TEST_OP_POST_BIND, DM_TEST_OP_PRE_UNBIND, + DM_TEST_OP_PRE_PROBE, DM_TEST_OP_POST_PROBE, DM_TEST_OP_PRE_REMOVE, DM_TEST_OP_INIT, @@ -97,6 +98,26 @@ struct dm_test_parent_data { int flag; }; +/* Test values for test device's uclass platform data */ +enum { + TEST_UC_PDATA_INTVAL1 = 2, + TEST_UC_PDATA_INTVAL2 = 334, + TEST_UC_PDATA_INTVAL3 = 789452, +}; + +/** + * struct dm_test_uclass_platda - uclass's information on each device + * + * @intval1: set to TEST_UC_PDATA_INTVAL1 in .post_bind method of test uclass + * @intval2: set to TEST_UC_PDATA_INTVAL2 in .post_bind method of test uclass + * @intval3: set to TEST_UC_PDATA_INTVAL3 in .post_bind method of test uclass + */ +struct dm_test_perdev_uc_pdata { + int intval1; + int intval2; + int intval3; +}; + /* * Operation counts for the test driver, used to check that each method is * called correctly @@ -204,12 +225,13 @@ void dm_leak_check_start(struct dm_test_state *dms); /** - * dm_test_main() - Run all the tests + * dm_test_main() - Run all or one of the tests * - * This runs all available driver model tests + * This runs all available driver model tests, or a selected one * + * @test_name: Name of test to run, or NULL for all * @return 0 if OK, -ve on error */ -int dm_test_main(void); +int dm_test_main(const char *test_name); #endif diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 91bb90d..fddfd35 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -20,6 +20,8 @@ enum uclass_id { UCLASS_TEST_BUS, UCLASS_SPI_EMUL, /* sandbox SPI device emulator */ UCLASS_I2C_EMUL, /* sandbox I2C device emulator */ + UCLASS_PCI_EMUL, /* sandbox PCI device emulator */ + UCLASS_USB_EMUL, /* sandbox USB bus device emulator */ UCLASS_SIMPLE_BUS, /* U-Boot uclasses start here */ @@ -34,6 +36,15 @@ enum uclass_id { UCLASS_I2C_GENERIC, /* Generic I2C device */ UCLASS_I2C_EEPROM, /* I2C EEPROM device */ UCLASS_MOD_EXP, /* RSA Mod Exp device */ + UCLASS_PCI, /* PCI bus */ + UCLASS_PCI_GENERIC, /* Generic PCI bus device */ + UCLASS_PCH, /* x86 platform controller hub */ + UCLASS_ETH, /* Ethernet device */ + UCLASS_LPC, /* x86 'low pin count' interface */ + UCLASS_USB, /* USB bus */ + UCLASS_USB_HUB, /* USB hub */ + UCLASS_USB_DEV_GENERIC, /* USB generic device */ + UCLASS_MASS_STORAGE, /* Mass storage device */ UCLASS_COUNT, UCLASS_INVALID = -1, diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h index f2f254a..9b68508 100644 --- a/include/dm/uclass-internal.h +++ b/include/dm/uclass-internal.h @@ -11,12 +11,25 @@ #define _DM_UCLASS_INTERNAL_H /** + * uclass_get_device_tail() - handle the end of a get_device call + * + * This handles returning an error or probing a device as needed. + * + * @dev: Device that needs to be probed + * @ret: Error to return. If non-zero then the device is not probed + * @devp: Returns the value of 'dev' if there is no error + * @return ret, if non-zero, else the result of the device_probe() call + */ +int uclass_get_device_tail(struct udevice *dev, int ret, struct udevice **devp); + +/** * uclass_find_device() - Return n-th child of uclass * @id: Id number of the uclass * @index: Position of the child in uclass's list * #devp: Returns pointer to device, or NULL on error * - * The device is not prepared for use - this is an internal function + * The device is not prepared for use - this is an internal function. + * The function uclass_get_device_tail() can be used to probe the device. * * @return the uclass pointer of a child at the given index or * return NULL on error. @@ -24,6 +37,68 @@ int uclass_find_device(enum uclass_id id, int index, struct udevice **devp); /** + * uclass_find_first_device() - Return the first device in a uclass + * @id: Id number of the uclass + * #devp: Returns pointer to device, or NULL on error + * + * The device is not prepared for use - this is an internal function. + * The function uclass_get_device_tail() can be used to probe the device. + * + * @return 0 if OK (found or not found), -1 on error + */ +int uclass_find_first_device(enum uclass_id id, struct udevice **devp); + +/** + * uclass_find_next_device() - Return the next device in a uclass + * @devp: On entry, pointer to device to lookup. On exit, returns pointer + * to the next device in the same uclass, or NULL if none + * + * The device is not prepared for use - this is an internal function. + * The function uclass_get_device_tail() can be used to probe the device. + * + * @return 0 if OK (found or not found), -1 on error + */ +int uclass_find_next_device(struct udevice **devp); + +/** + * uclass_find_device_by_name() - Find uclass device based on ID and name + * + * This searches for a device with the exactly given name. + * + * The device is NOT probed, it is merely returned. + * + * @id: ID to look up + * @name: name of a device to find + * @devp: Returns pointer to device (the first one with the name) + * @return 0 if OK, -ve on error + */ +int uclass_find_device_by_name(enum uclass_id id, const char *name, + struct udevice **devp); + +/** + * uclass_find_device_by_seq() - Find uclass device based on ID and sequence + * + * This searches for a device with the given seq or req_seq. + * + * For seq, if an active device has this sequence it will be returned. + * If there is no such device then this will return -ENODEV. + * + * For req_seq, if a device (whether activated or not) has this req_seq + * value, that device will be returned. This is a strong indication that + * the device will receive that sequence when activated. + * + * The device is NOT probed, it is merely returned. + * + * @id: ID to look up + * @seq_or_req_seq: Sequence number to find (0=first) + * @find_req_seq: true to find req_seq, false to find seq + * @devp: Returns pointer to device (there is only one per for each seq) + * @return 0 if OK, -ve on error + */ +int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq, + bool find_req_seq, struct udevice **devp); + +/** * uclass_bind_device() - Associate device with a uclass * * Connect the device into uclass's list of devices. @@ -41,18 +116,23 @@ int uclass_bind_device(struct udevice *dev); * @dev: Pointer to the device * #return 0 on success, -ve on error */ +#ifdef CONFIG_DM_DEVICE_REMOVE int uclass_unbind_device(struct udevice *dev); +#else +static inline int uclass_unbind_device(struct udevice *dev) { return 0; } +#endif /** - * uclass_pre_probe_child() - Deal with a child that is about to be probed + * uclass_pre_probe_device() - Deal with a device that is about to be probed * * Perform any pre-processing that is needed by the uclass before it can be - * probed. + * probed. This includes the uclass' pre-probe() method and the parent + * uclass' child_pre_probe() method. * * @dev: Pointer to the device * #return 0 on success, -ve on error */ -int uclass_pre_probe_child(struct udevice *dev); +int uclass_pre_probe_device(struct udevice *dev); /** * uclass_post_probe_device() - Deal with a device that has just been probed @@ -73,7 +153,11 @@ int uclass_post_probe_device(struct udevice *dev); * @dev: Pointer to the device * #return 0 on success, -ve on error */ +#ifdef CONFIG_DM_DEVICE_REMOVE int uclass_pre_remove_device(struct udevice *dev); +#else +static inline int uclass_pre_remove_device(struct udevice *dev) { return 0; } +#endif /** * uclass_find() - Find uclass by its id @@ -93,27 +177,4 @@ struct uclass *uclass_find(enum uclass_id key); */ int uclass_destroy(struct uclass *uc); -/** - * uclass_find_device_by_seq() - Find uclass device based on ID and sequence - * - * This searches for a device with the given seq or req_seq. - * - * For seq, if an active device has this sequence it will be returned. - * If there is no such device then this will return -ENODEV. - * - * For req_seq, if a device (whether activated or not) has this req_seq - * value, that device will be returned. This is a strong indication that - * the device will receive that sequence when activated. - * - * The device is NOT probed, it is merely returned. - * - * @id: ID to look up - * @seq_or_req_seq: Sequence number to find (0=first) - * @find_req_seq: true to find req_seq, false to find seq - * @devp: Returns pointer to device (there is only one per for each seq) - * @return 0 if OK, -ve on error - */ -int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq, - bool find_req_seq, struct udevice **devp); - #endif diff --git a/include/dm/uclass.h b/include/dm/uclass.h index d6c40c6..4cfc0df 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -53,6 +53,7 @@ struct udevice; * @id: ID number of this uclass * @post_bind: Called after a new device is bound to this uclass * @pre_unbind: Called before a device is unbound from this uclass + * @pre_probe: Called before a new device is probed * @post_probe: Called after a new device is probed * @pre_remove: Called before a device is removed * @child_post_bind: Called after a child is bound to a device in this uclass @@ -64,6 +65,9 @@ struct udevice; * @per_device_auto_alloc_size: Each device can hold private data owned * by the uclass. If required this will be automatically allocated if this * value is non-zero. + * @per_device_platdata_auto_alloc_size: Each device can hold platform data + * owned by the uclass as 'dev->uclass_platdata'. If the value is non-zero, + * then this will be automatically allocated. * @per_child_auto_alloc_size: Each child device (of a parent in this * uclass) can hold parent data for the device/uclass. This value is only * used as a falback if this member is 0 in the driver. @@ -80,6 +84,7 @@ struct uclass_driver { enum uclass_id id; int (*post_bind)(struct udevice *dev); int (*pre_unbind)(struct udevice *dev); + int (*pre_probe)(struct udevice *dev); int (*post_probe)(struct udevice *dev); int (*pre_remove)(struct udevice *dev); int (*child_post_bind)(struct udevice *dev); @@ -88,6 +93,7 @@ struct uclass_driver { int (*destroy)(struct uclass *class); int priv_auto_alloc_size; int per_device_auto_alloc_size; + int per_device_platdata_auto_alloc_size; int per_child_auto_alloc_size; int per_child_platdata_auto_alloc_size; const void *ops; @@ -124,6 +130,21 @@ int uclass_get(enum uclass_id key, struct uclass **ucp); int uclass_get_device(enum uclass_id id, int index, struct udevice **devp); /** + * uclass_get_device_by_name() - Get a uclass device by it's name + * + * This searches the devices in the uclass for one with the exactly given name. + * + * The device is probed to activate it ready for use. + * + * @id: ID to look up + * @name: name of a device to get + * @devp: Returns pointer to device (the first one with the name) + * @return 0 if OK, -ve on error + */ +int uclass_get_device_by_name(enum uclass_id id, const char *name, + struct udevice **devp); + +/** * uclass_get_device_by_seq() - Get a uclass device based on an ID and sequence * * If an active device has this sequence it will be returned. If there is no diff --git a/include/exynos_lcd.h b/include/exynos_lcd.h index cf389da..3969a6a 100644 --- a/include/exynos_lcd.h +++ b/include/exynos_lcd.h @@ -25,6 +25,7 @@ enum exynos_fb_rgb_mode_t { typedef struct vidinfo { ushort vl_col; /* Number of columns (i.e. 640) */ ushort vl_row; /* Number of rows (i.e. 480) */ + ushort vl_rot; /* Rotation of Display (0, 1, 2, 3) */ ushort vl_width; /* Width of display area in millimeters */ ushort vl_height; /* Height of display area in millimeters */ diff --git a/include/fdt_support.h b/include/fdt_support.h index ae5e8a3..5d4f28d 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -47,6 +47,19 @@ int fdt_find_and_setprop(void *fdt, const char *node, const char *prop, const void *val, int len, int create); void fdt_fixup_qe_firmware(void *fdt); +/** + * Update native-mode property of display-timings node to the phandle + * of the timings matching a display by name (case insensitive). + * + * see kernel Documentation/devicetree/bindings/video/display-timing.txt + * + * @param blob FDT blob to update + * @param path path within dt + * @param display name of display timing to match + * @return 0 if ok, or -FDT_ERR_... on error + */ +int fdt_fixup_display(void *blob, const char *path, const char *display); + #if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_MPH_USB) void fdt_fixup_dr_usb(void *blob, bd_t *bd); #else diff --git a/include/fdtdec.h b/include/fdtdec.h index 11a7b86..6590470 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -41,6 +41,16 @@ struct fdt_memory { fdt_addr_t end; }; +#ifdef CONFIG_OF_CONTROL +# if defined(CONFIG_SPL_BUILD) && defined(SPL_DISABLE_OF_CONTROL) +# define OF_CONTROL 0 +# else +# define OF_CONTROL 1 +# endif +#else +# define OF_CONTROL 0 +#endif + /* * Information about a resource. start is the first address of the resource * and end is the last address (inclusive). The length of the resource will @@ -134,7 +144,6 @@ enum fdt_compat_id { COMPAT_SAMSUNG_S3C2440_I2C, /* Exynos I2C Controller */ COMPAT_SAMSUNG_EXYNOS5_SOUND, /* Exynos Sound */ COMPAT_WOLFSON_WM8994_CODEC, /* Wolfson WM8994 Sound Codec */ - COMPAT_GOOGLE_CROS_EC, /* Google CROS_EC Protocol */ COMPAT_GOOGLE_CROS_EC_KEYB, /* Google CROS_EC Keyboard */ COMPAT_SAMSUNG_EXYNOS_EHCI, /* Exynos EHCI controller */ COMPAT_SAMSUNG_EXYNOS5_XHCI, /* Exynos5 XHCI controller */ @@ -153,13 +162,11 @@ enum fdt_compat_id { COMPAT_INFINEON_SLB9635_TPM, /* Infineon SLB9635 TPM */ COMPAT_INFINEON_SLB9645_TPM, /* Infineon SLB9645 TPM */ COMPAT_SAMSUNG_EXYNOS5_I2C, /* Exynos5 High Speed I2C Controller */ - COMPAT_SANDBOX_HOST_EMULATION, /* Sandbox emulation of a function */ COMPAT_SANDBOX_LCD_SDL, /* Sandbox LCD emulation with SDL */ COMPAT_TI_TPS65090, /* Texas Instrument TPS65090 */ COMPAT_NXP_PTN3460, /* NXP PTN3460 DP/LVDS bridge */ COMPAT_SAMSUNG_EXYNOS_SYSMMU, /* Exynos sysmmu */ COMPAT_PARADE_PS8625, /* Parade PS8622 EDP->LVDS bridge */ - COMPAT_INTEL_LPC, /* Intel Low Pin Count I/F */ COMPAT_INTEL_MICROCODE, /* Intel microcode update */ COMPAT_MEMORY_SPD, /* Memory SPD information */ COMPAT_INTEL_PANTHERPOINT_AHCI, /* Intel Pantherpoint AHCI */ @@ -169,6 +176,7 @@ enum fdt_compat_id { COMPAT_INTEL_ICH_SPI, /* Intel ICH7/9 SPI controller */ COMPAT_INTEL_QRK_MRC, /* Intel Quark MRC */ COMPAT_SOCIONEXT_XHCI, /* Socionext UniPhier xHCI */ + COMPAT_INTEL_PCH, /* Intel PCH */ COMPAT_COUNT, }; @@ -327,7 +335,9 @@ fdt_addr_t fdtdec_get_addr_size(const void *blob, int node, * @param type pci address type (FDT_PCI_SPACE_xxx) * @param prop_name name of property to find * @param addr returns pci address in the form of fdt_pci_addr - * @return 0 if ok, negative on error + * @return 0 if ok, -ENOENT if the property did not exist, -EINVAL if the + * format of the property was invalid, -ENXIO if the requested + * address type was not found */ int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type, const char *prop_name, struct fdt_pci_addr *addr); @@ -389,6 +399,17 @@ s32 fdtdec_get_int(const void *blob, int node, const char *prop_name, s32 default_val); /** + * Get a variable-sized number from a property + * + * This reads a number from one or more cells. + * + * @param ptr Pointer to property + * @param cells Number of cells containing the number + * @return the value in the cells + */ +u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells); + +/** * Look up a 64-bit integer property in a node and return it. The property * must have at least 8 bytes of data (2 cells). The first two cells are * concatenated to form a 8 bytes value, where the first cell is top half and @@ -782,4 +803,10 @@ int fdt_get_named_resource(const void *fdt, int node, const char *property, int fdtdec_decode_memory_region(const void *blob, int node, const char *mem_type, const char *suffix, fdt_addr_t *basep, fdt_size_t *sizep); + +/** + * Set up the device tree ready for use + */ +int fdtdec_setup(void); + #endif diff --git a/include/flash.h b/include/flash.h index 30aa080..48aa3a5 100644 --- a/include/flash.h +++ b/include/flash.h @@ -459,6 +459,8 @@ extern flash_info_t *flash_get_info(ulong base); #define FLASH_S29GL064M 0x00F0 /* Spansion S29GL064M-R6 */ #define FLASH_S29GL128N 0x00F1 /* Spansion S29GL128N */ +#define FLASH_STM32F4 0x00F2 /* STM32F4 Embedded Flash */ + #define FLASH_UNKNOWN 0xFFFF /* unknown flash type */ diff --git a/include/fsl-mc/fsl_dpaa_fd.h b/include/fsl-mc/fsl_dpaa_fd.h new file mode 100644 index 0000000..6d0ffa8 --- /dev/null +++ b/include/fsl-mc/fsl_dpaa_fd.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __FSL_DPAA_FD_H +#define __FSL_DPAA_FD_H + +/* Place-holder for FDs, we represent it via the simplest form that we need for + * now. Different overlays may be needed to support different options, etc. (It + * is impractical to define One True Struct, because the resulting encoding + * routines (lots of read-modify-writes) would be worst-case performance whether + * or not circumstances required them.) */ +struct dpaa_fd { + union { + u32 words[8]; + struct dpaa_fd_simple { + u32 addr_lo; + u32 addr_hi; + u32 len; + /* offset in the MS 16 bits, BPID in the LS 16 bits */ + u32 bpid_offset; + u32 frc; /* frame context */ + /* "err", "va", "cbmt", "asal", [...] */ + u32 ctrl; + /* flow context */ + u32 flc_lo; + u32 flc_hi; + } simple; + }; +}; + +enum dpaa_fd_format { + dpaa_fd_single = 0, + dpaa_fd_list, + dpaa_fd_sg +}; + +static inline u64 ldpaa_fd_get_addr(const struct dpaa_fd *fd) +{ + return (u64)((((uint64_t)fd->simple.addr_hi) << 32) + + fd->simple.addr_lo); +} + +static inline void ldpaa_fd_set_addr(struct dpaa_fd *fd, u64 addr) +{ + fd->simple.addr_hi = upper_32_bits(addr); + fd->simple.addr_lo = lower_32_bits(addr); +} + +static inline u32 ldpaa_fd_get_len(const struct dpaa_fd *fd) +{ + return fd->simple.len; +} + +static inline void ldpaa_fd_set_len(struct dpaa_fd *fd, u32 len) +{ + fd->simple.len = len; +} + +static inline uint16_t ldpaa_fd_get_offset(const struct dpaa_fd *fd) +{ + return (uint16_t)(fd->simple.bpid_offset >> 16) & 0x0FFF; +} + +static inline void ldpaa_fd_set_offset(struct dpaa_fd *fd, uint16_t offset) +{ + fd->simple.bpid_offset &= 0xF000FFFF; + fd->simple.bpid_offset |= (u32)offset << 16; +} + +static inline uint16_t ldpaa_fd_get_bpid(const struct dpaa_fd *fd) +{ + return (uint16_t)(fd->simple.bpid_offset & 0xFFFF); +} + +static inline void ldpaa_fd_set_bpid(struct dpaa_fd *fd, uint16_t bpid) +{ + fd->simple.bpid_offset &= 0xFFFF0000; + fd->simple.bpid_offset |= (u32)bpid; +} + +/* When frames are dequeued, the FDs show up inside "dequeue" result structures + * (if at all, not all dequeue results contain valid FDs). This structure type + * is intentionally defined without internal detail, and the only reason it + * isn't declared opaquely (without size) is to allow the user to provide + * suitably-sized (and aligned) memory for these entries. */ +struct ldpaa_dq { + uint32_t dont_manipulate_directly[16]; +}; + +/* Parsing frame dequeue results */ +#define LDPAA_DQ_STAT_FQEMPTY 0x80 +#define LDPAA_DQ_STAT_HELDACTIVE 0x40 +#define LDPAA_DQ_STAT_FORCEELIGIBLE 0x20 +#define LDPAA_DQ_STAT_VALIDFRAME 0x10 +#define LDPAA_DQ_STAT_ODPVALID 0x04 +#define LDPAA_DQ_STAT_VOLATILE 0x02 +#define LDPAA_DQ_STAT_EXPIRED 0x01 +uint32_t ldpaa_dq_flags(const struct ldpaa_dq *); +static inline int ldpaa_dq_is_pull(const struct ldpaa_dq *dq) +{ + return (int)(ldpaa_dq_flags(dq) & LDPAA_DQ_STAT_VOLATILE); +} +static inline int ldpaa_dq_is_pull_complete( + const struct ldpaa_dq *dq) +{ + return (int)(ldpaa_dq_flags(dq) & LDPAA_DQ_STAT_EXPIRED); +} +/* seqnum/odpid are valid only if VALIDFRAME and ODPVALID flags are TRUE */ +uint16_t ldpaa_dq_seqnum(const struct ldpaa_dq *); +uint16_t ldpaa_dq_odpid(const struct ldpaa_dq *); +uint32_t ldpaa_dq_fqid(const struct ldpaa_dq *); +uint32_t ldpaa_dq_byte_count(const struct ldpaa_dq *); +uint32_t ldpaa_dq_frame_count(const struct ldpaa_dq *); +uint32_t ldpaa_dq_fqd_ctx_hi(const struct ldpaa_dq *); +uint32_t ldpaa_dq_fqd_ctx_lo(const struct ldpaa_dq *); +/* get the Frame Descriptor */ +const struct dpaa_fd *ldpaa_dq_fd(const struct ldpaa_dq *); + +#endif /* __FSL_DPAA_FD_H */ diff --git a/include/fsl-mc/fsl_dpbp.h b/include/fsl-mc/fsl_dpbp.h new file mode 100644 index 0000000..7f0075c --- /dev/null +++ b/include/fsl-mc/fsl_dpbp.h @@ -0,0 +1,143 @@ +/* + * Freescale Layerscape MC I/O wrapper + * + * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. + * Author: German Rivera <German.Rivera@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/*! + * @file fsl_dpbp.h + * @brief Data Path Buffer Pool API + */ +#ifndef __FSL_DPBP_H +#define __FSL_DPBP_H + +/* DPBP Version */ +#define DPBP_VER_MAJOR 2 +#define DPBP_VER_MINOR 0 + +/* Command IDs */ +#define DPBP_CMDID_CLOSE 0x800 +#define DPBP_CMDID_OPEN 0x804 + +#define DPBP_CMDID_ENABLE 0x002 +#define DPBP_CMDID_DISABLE 0x003 +#define DPBP_CMDID_GET_ATTR 0x004 +#define DPBP_CMDID_RESET 0x005 + +/* cmd, param, offset, width, type, arg_name */ +#define DPBP_CMD_OPEN(cmd, dpbp_id) \ + MC_CMD_OP(cmd, 0, 0, 32, int, dpbp_id) + +/* cmd, param, offset, width, type, arg_name */ +#define DPBP_RSP_GET_ATTRIBUTES(cmd, attr) \ +do { \ + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, attr->bpid); \ + MC_RSP_OP(cmd, 0, 32, 32, int, attr->id);\ + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->version.major);\ + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->version.minor);\ +} while (0) + +/* Data Path Buffer Pool API + * Contains initialization APIs and runtime control APIs for DPBP + */ + +struct fsl_mc_io; + +/** + * dpbp_open() - Open a control session for the specified object. + * @mc_io: Pointer to MC portal's I/O object + * @dpbp_id: DPBP unique ID + * @token: Returned token; use in subsequent API calls + * + * This function can be used to open a control session for an + * already created object; an object may have been declared in + * the DPL or by calling the dpbp_create function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent commands for + * this specific object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token); + +/** + * dpbp_close() - Close the control session of the object + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * + * After this function is called, no further operations are + * allowed on the object without opening a new control session. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * dpbp_enable() - Enable the DPBP. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * + * Return: '0' on Success; Error code otherwise. + */ + +int dpbp_enable(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * dpbp_disable() - Disable the DPBP. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_disable(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * dpbp_reset() - Reset the DPBP, returns the object to initial state. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_reset(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * struct dpbp_attr - Structure representing DPBP attributes + * @id: DPBP object ID + * @version: DPBP version + * @bpid: Hardware buffer pool ID; should be used as an argument in + * acquire/release operations on buffers + */ +struct dpbp_attr { + int id; + /** + * struct version - Structure representing DPBP version + * @major: DPBP major version + * @minor: DPBP minor version + */ + struct { + uint16_t major; + uint16_t minor; + } version; + uint16_t bpid; +}; + + +/** + * dpbp_get_attributes - Retrieve DPBP attributes. + * + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPBP object + * @attr: Returned object's attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpbp_attr *attr); + +/** @} */ + +#endif /* __FSL_DPBP_H */ diff --git a/include/fsl-mc/fsl_dpio.h b/include/fsl-mc/fsl_dpio.h new file mode 100644 index 0000000..e84b419 --- /dev/null +++ b/include/fsl-mc/fsl_dpio.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2013-2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _FSL_DPIO_H +#define _FSL_DPIO_H + +/* DPIO Version */ +#define DPIO_VER_MAJOR 2 +#define DPIO_VER_MINOR 1 + +/* Command IDs */ +#define DPIO_CMDID_CLOSE 0x800 +#define DPIO_CMDID_OPEN 0x803 + +#define DPIO_CMDID_ENABLE 0x002 +#define DPIO_CMDID_DISABLE 0x003 +#define DPIO_CMDID_GET_ATTR 0x004 +#define DPIO_CMDID_RESET 0x005 + +/* cmd, param, offset, width, type, arg_name */ +#define DPIO_CMD_OPEN(cmd, dpio_id) \ + MC_CMD_OP(cmd, 0, 0, 32, int, dpio_id) + +/* cmd, param, offset, width, type, arg_name */ +#define DPIO_RSP_GET_ATTR(cmd, attr) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\ + MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qbman_portal_id);\ + MC_RSP_OP(cmd, 0, 48, 8, uint8_t, attr->num_priorities);\ + MC_RSP_OP(cmd, 0, 56, 4, enum dpio_channel_mode, attr->channel_mode);\ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_paddr);\ + MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_paddr);\ + MC_RSP_OP(cmd, 3, 0, 16, uint16_t, attr->version.major);\ + MC_RSP_OP(cmd, 3, 16, 16, uint16_t, attr->version.minor);\ +} while (0) + +/* Data Path I/O Portal API + * Contains initialization APIs and runtime control APIs for DPIO + */ + +struct fsl_mc_io; +/** + * dpio_open() - Open a control session for the specified object + * @mc_io: Pointer to MC portal's I/O object + * @dpio_id: DPIO unique ID + * @token: Returned token; use in subsequent API calls + * + * This function can be used to open a control session for an + * already created object; an object may have been declared in + * the DPL or by calling the dpio_create() function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent commands for + * this specific object. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpio_open(struct fsl_mc_io *mc_io, int dpio_id, uint16_t *token); + +/** + * dpio_open() - Open a control session for the specified object + * @mc_io: Pointer to MC portal's I/O object + * @dpio_id: DPIO unique ID + * @token: Returned token; use in subsequent API calls + * + * This function can be used to open a control session for an + * already created object; an object may have been declared in + * the DPL or by calling the dpio_create() function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent commands for + * this specific object. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpio_close(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * enum dpio_channel_mode - DPIO notification channel mode + * @DPIO_NO_CHANNEL: No support for notification channel + * @DPIO_LOCAL_CHANNEL: Notifications on data availability can be received by a + * dedicated channel in the DPIO; user should point the queue's + * destination in the relevant interface to this DPIO + */ +enum dpio_channel_mode { + DPIO_NO_CHANNEL = 0, + DPIO_LOCAL_CHANNEL = 1, +}; + +/** + * dpio_enable() - Enable the DPIO, allow I/O portal operations. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPIO object + * + * Return: '0' on Success; Error code otherwise + */ +int dpio_enable(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * dpio_disable() - Disable the DPIO, stop any I/O portal operation. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPIO object + * + * Return: '0' on Success; Error code otherwise + */ +int dpio_disable(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * dpio_reset() - Reset the DPIO, returns the object to initial state. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPIO object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpio_reset(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * struct dpio_attr - Structure representing DPIO attributes + * @id: DPIO object ID + * @version: DPIO version + * @qbman_portal_ce_paddr: Physical address of the software portal + * cache-enabled area + * @qbman_portal_ci_paddr: Physical address of the software portal + * cache-inhibited area + * @qbman_portal_id: Software portal ID + * @channel_mode: Notification channel mode + * @num_priorities: Number of priorities for the notification channel (1-8); + * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL' + */ +struct dpio_attr { + int id; + /** + * struct version - DPIO version + * @major: DPIO major version + * @minor: DPIO minor version + */ + struct { + uint16_t major; + uint16_t minor; + } version; + uint64_t qbman_portal_ce_paddr; + uint64_t qbman_portal_ci_paddr; + uint16_t qbman_portal_id; + enum dpio_channel_mode channel_mode; + uint8_t num_priorities; +}; + +/** + * dpio_get_attributes() - Retrieve DPIO attributes + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPIO object + * @attr: Returned object's attributes + * + * Return: '0' on Success; Error code otherwise + */ +int dpio_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpio_attr *attr); + +#endif /* _FSL_DPIO_H */ diff --git a/include/fsl-mc/fsl_dpmng.h b/include/fsl-mc/fsl_dpmng.h index c2e1ddd..986e7c8 100644 --- a/include/fsl-mc/fsl_dpmng.h +++ b/include/fsl-mc/fsl_dpmng.h @@ -1,121 +1,44 @@ -/* Copyright 2014 Freescale Semiconductor Inc. +/* Copyright 2013-2015 Freescale Semiconductor Inc. * * SPDX-License-Identifier: GPL-2.0+ */ -/*! - * @file fsl_dpmng.h - * @brief Management Complex General API - */ - #ifndef __FSL_DPMNG_H #define __FSL_DPMNG_H -/*! - * @Group grp_dpmng Management Complex General API - * - * @brief Contains general API for the Management Complex firmware - * @{ +/* Management Complex General API + * Contains general API for the Management Complex firmware */ struct fsl_mc_io; /** - * @brief Management Complex firmware version information + * Management Complex firmware version information */ -#define MC_VER_MAJOR 4 +#define MC_VER_MAJOR 6 #define MC_VER_MINOR 0 +/** + * struct mc_versoin + * @major: Major version number: incremented on API compatibility changes + * @minor: Minor version number: incremented on API additions (that are + * backward compatible); reset when major version is incremented + * @revision: Internal revision number: incremented on implementation changes + * and/or bug fixes that have no impact on API + */ struct mc_version { uint32_t major; - /*!< Major version number: incremented on API compatibility changes */ uint32_t minor; - /*!< Minor version number: incremented on API additions (that are - * backward compatible); reset when major version is incremented - */ uint32_t revision; - /*!< Internal revision number: incremented on implementation changes - * and/or bug fixes that have no impact on API - */ }; /** - * @brief Retrieves the Management Complex firmware version information - * - * @param[in] mc_io Pointer to opaque I/O object - * @param[out] mc_ver_info Pointer to version information structure + * mc_get_version() - Retrieves the Management Complex firmware + * version information + * @mc_io: Pointer to opaque I/O object + * @mc_ver_info: Returned version information structure * - * @returns '0' on Success; Error code otherwise. + * Return: '0' on Success; Error code otherwise. */ int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info); -/** - * @brief Resets an AIOP tile - * - * @param[in] mc_io Pointer to opaque I/O object - * @param[in] container_id AIOP container ID - * @param[in] aiop_tile_id AIOP tile ID to reset - * - * @returns '0' on Success; Error code otherwise. - */ -int dpmng_reset_aiop(struct fsl_mc_io *mc_io, - int container_id, - int aiop_tile_id); - -/** - * @brief Loads an image to AIOP tile - * - * @param[in] mc_io Pointer to opaque I/O object - * @param[in] container_id AIOP container ID - * @param[in] aiop_tile_id AIOP tile ID to reset - * @param[in] img_iova I/O virtual address of AIOP ELF image - * @param[in] img_size Size of AIOP ELF image in memory (in bytes) - * - * @returns '0' on Success; Error code otherwise. - */ -int dpmng_load_aiop(struct fsl_mc_io *mc_io, - int container_id, - int aiop_tile_id, - uint64_t img_iova, - uint32_t img_size); - -/** - * @brief AIOP run configuration - */ -struct dpmng_aiop_run_cfg { - uint32_t cores_mask; - /*!< Mask of AIOP cores to run (core 0 in most significant bit) */ - uint64_t options; - /*!< Execution options (currently none defined) */ -}; - -/** - * @brief Starts AIOP tile execution - * - * @param[in] mc_io Pointer to MC portal's I/O object - * @param[in] container_id AIOP container ID - * @param[in] aiop_tile_id AIOP tile ID to reset - * @param[in] cfg AIOP run configuration - * - * @returns '0' on Success; Error code otherwise. - */ -int dpmng_run_aiop(struct fsl_mc_io *mc_io, - int container_id, - int aiop_tile_id, - const struct dpmng_aiop_run_cfg *cfg); - -/** - * @brief Resets MC portal - * - * This function closes all object handles (tokens) that are currently - * open in the MC portal on which the command is submitted. This allows - * cleanup of stale handles that belong to non-functional user processes. - * - * @param[in] mc_io Pointer to MC portal's I/O object - * - * @returns '0' on Success; Error code otherwise. - */ -int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io); - -/** @} */ - #endif /* __FSL_DPMNG_H */ diff --git a/include/fsl-mc/fsl_dpni.h b/include/fsl-mc/fsl_dpni.h new file mode 100644 index 0000000..67c087d --- /dev/null +++ b/include/fsl-mc/fsl_dpni.h @@ -0,0 +1,1093 @@ +/* + * Copyright (C) 2013-2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _FSL_DPNI_H +#define _FSL_DPNI_H + +/* DPNI Version */ +#define DPNI_VER_MAJOR 4 +#define DPNI_VER_MINOR 0 + +/* Command IDs */ +#define DPNI_CMDID_OPEN 0x801 +#define DPNI_CMDID_CLOSE 0x800 + +#define DPNI_CMDID_ENABLE 0x002 +#define DPNI_CMDID_DISABLE 0x003 +#define DPNI_CMDID_GET_ATTR 0x004 +#define DPNI_CMDID_RESET 0x005 + +#define DPNI_CMDID_SET_POOLS 0x200 +#define DPNI_CMDID_GET_RX_BUFFER_LAYOUT 0x201 +#define DPNI_CMDID_SET_RX_BUFFER_LAYOUT 0x202 +#define DPNI_CMDID_GET_TX_BUFFER_LAYOUT 0x203 +#define DPNI_CMDID_SET_TX_BUFFER_LAYOUT 0x204 +#define DPNI_CMDID_SET_TX_CONF_BUFFER_LAYOUT 0x205 +#define DPNI_CMDID_GET_TX_CONF_BUFFER_LAYOUT 0x206 + +#define DPNI_CMDID_GET_QDID 0x210 +#define DPNI_CMDID_GET_TX_DATA_OFFSET 0x212 +#define DPNI_CMDID_GET_COUNTER 0x213 +#define DPNI_CMDID_SET_COUNTER 0x214 +#define DPNI_CMDID_GET_LINK_STATE 0x215 +#define DPNI_CMDID_SET_LINK_CFG 0x21A + +#define DPNI_CMDID_SET_PRIM_MAC 0x224 +#define DPNI_CMDID_GET_PRIM_MAC 0x225 +#define DPNI_CMDID_ADD_MAC_ADDR 0x226 +#define DPNI_CMDID_REMOVE_MAC_ADDR 0x227 + +#define DPNI_CMDID_SET_TX_FLOW 0x236 +#define DPNI_CMDID_GET_TX_FLOW 0x237 +#define DPNI_CMDID_SET_RX_FLOW 0x238 +#define DPNI_CMDID_GET_RX_FLOW 0x239 + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_OPEN(cmd, dpni_id) \ + MC_CMD_OP(cmd, 0, 0, 32, int, dpni_id) + + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_SET_POOLS(cmd, cfg) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \ + MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \ + MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\ + MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \ + MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\ + MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \ + MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\ + MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \ + MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\ + MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \ + MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\ + MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \ + MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\ + MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \ + MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\ + MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \ + MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_RSP_GET_ATTR(cmd, attr) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\ + MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->max_tcs); \ + MC_RSP_OP(cmd, 0, 40, 8, uint8_t, attr->max_senders); \ + MC_RSP_OP(cmd, 0, 48, 8, enum net_prot, attr->start_hdr); \ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->options); \ + MC_RSP_OP(cmd, 2, 0, 8, uint8_t, attr->max_unicast_filters); \ + MC_RSP_OP(cmd, 2, 8, 8, uint8_t, attr->max_multicast_filters);\ + MC_RSP_OP(cmd, 2, 16, 8, uint8_t, attr->max_vlan_filters); \ + MC_RSP_OP(cmd, 2, 24, 8, uint8_t, attr->max_qos_entries); \ + MC_RSP_OP(cmd, 2, 32, 8, uint8_t, attr->max_qos_key_size); \ + MC_RSP_OP(cmd, 2, 40, 8, uint8_t, attr->max_dist_key_size); \ + MC_RSP_OP(cmd, 3, 0, 8, uint8_t, attr->max_dist_per_tc[0]); \ + MC_RSP_OP(cmd, 3, 8, 8, uint8_t, attr->max_dist_per_tc[1]); \ + MC_RSP_OP(cmd, 3, 16, 8, uint8_t, attr->max_dist_per_tc[2]); \ + MC_RSP_OP(cmd, 3, 24, 8, uint8_t, attr->max_dist_per_tc[3]); \ + MC_RSP_OP(cmd, 3, 32, 8, uint8_t, attr->max_dist_per_tc[4]); \ + MC_RSP_OP(cmd, 3, 40, 8, uint8_t, attr->max_dist_per_tc[5]); \ + MC_RSP_OP(cmd, 3, 48, 8, uint8_t, attr->max_dist_per_tc[6]); \ + MC_RSP_OP(cmd, 3, 56, 8, uint8_t, attr->max_dist_per_tc[7]); \ + MC_RSP_OP(cmd, 4, 0, 16, uint16_t, \ + attr->ipr_cfg.max_reass_frm_size); \ + MC_RSP_OP(cmd, 4, 16, 16, uint16_t, \ + attr->ipr_cfg.min_frag_size_ipv4); \ + MC_RSP_OP(cmd, 4, 32, 16, uint16_t, \ + attr->ipr_cfg.min_frag_size_ipv6); \ + MC_RSP_OP(cmd, 5, 0, 16, uint16_t, \ + attr->ipr_cfg.max_open_frames_ipv4); \ + MC_RSP_OP(cmd, 5, 16, 16, uint16_t, \ + attr->ipr_cfg.max_open_frames_ipv6); \ + MC_RSP_OP(cmd, 5, 32, 16, uint16_t, attr->version.major);\ + MC_RSP_OP(cmd, 5, 48, 16, uint16_t, attr->version.minor);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_RSP_GET_RX_BUFFER_LAYOUT(cmd, layout) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \ + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \ + MC_RSP_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \ + MC_RSP_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \ + MC_RSP_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \ + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \ + MC_RSP_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_SET_RX_BUFFER_LAYOUT(cmd, layout) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \ + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \ + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, layout->options); \ + MC_CMD_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \ + MC_CMD_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \ + MC_CMD_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \ + MC_CMD_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \ + MC_CMD_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_RSP_GET_TX_BUFFER_LAYOUT(cmd, layout) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \ + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \ + MC_RSP_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \ + MC_RSP_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \ + MC_RSP_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \ + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \ + MC_RSP_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_SET_TX_BUFFER_LAYOUT(cmd, layout) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \ + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \ + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, layout->options); \ + MC_CMD_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \ + MC_CMD_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \ + MC_CMD_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \ + MC_CMD_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \ + MC_CMD_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_RSP_GET_TX_CONF_BUFFER_LAYOUT(cmd, layout) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \ + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \ + MC_RSP_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \ + MC_RSP_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \ + MC_RSP_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \ + MC_RSP_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \ + MC_RSP_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_SET_TX_CONF_BUFFER_LAYOUT(cmd, layout) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \ + MC_CMD_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \ + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, layout->options); \ + MC_CMD_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \ + MC_CMD_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \ + MC_CMD_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \ + MC_CMD_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \ + MC_CMD_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_RSP_GET_QDID(cmd, qdid) \ + MC_RSP_OP(cmd, 0, 0, 16, uint16_t, qdid) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_RSP_GET_TX_DATA_OFFSET(cmd, data_offset) \ + MC_RSP_OP(cmd, 0, 0, 16, uint16_t, data_offset) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_GET_COUNTER(cmd, counter) \ + MC_CMD_OP(cmd, 0, 0, 16, enum dpni_counter, counter) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_RSP_GET_COUNTER(cmd, value) \ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, value) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_SET_COUNTER(cmd, counter, value) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 16, enum dpni_counter, counter); \ + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, value); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_SET_LINK_CFG(cmd, cfg) \ +do { \ + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->rate);\ + MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_RSP_GET_LINK_STATE(cmd, state) \ +do { \ + MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, state->rate);\ + MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\ +} while (0) + + + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr) \ +do { \ + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \ + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \ + MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \ + MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \ + MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr) \ +do { \ + MC_RSP_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \ + MC_RSP_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \ + MC_RSP_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \ + MC_RSP_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \ + MC_RSP_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \ + MC_RSP_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_ADD_MAC_ADDR(cmd, mac_addr) \ +do { \ + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \ + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \ + MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \ + MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \ + MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_REMOVE_MAC_ADDR(cmd, mac_addr) \ +do { \ + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \ + MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \ + MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \ + MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \ + MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_SET_TX_FLOW(cmd, flow_id, cfg) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, int, \ + cfg->conf_err_cfg.queue_cfg.dest_cfg.dest_id);\ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, \ + cfg->conf_err_cfg.queue_cfg.dest_cfg.priority);\ + MC_CMD_OP(cmd, 0, 40, 2, enum dpni_dest, \ + cfg->conf_err_cfg.queue_cfg.dest_cfg.dest_type);\ + MC_CMD_OP(cmd, 0, 42, 1, int, cfg->conf_err_cfg.errors_only);\ + MC_CMD_OP(cmd, 0, 43, 1, int, cfg->l3_chksum_gen);\ + MC_CMD_OP(cmd, 0, 44, 1, int, cfg->l4_chksum_gen);\ + MC_CMD_OP(cmd, 0, 45, 1, int, \ + cfg->conf_err_cfg.use_default_queue);\ + MC_CMD_OP(cmd, 0, 48, 16, uint16_t, flow_id);\ + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, \ + cfg->conf_err_cfg.queue_cfg.user_ctx);\ + MC_CMD_OP(cmd, 2, 0, 32, uint32_t, cfg->options);\ + MC_CMD_OP(cmd, 2, 32, 32, uint32_t, \ + cfg->conf_err_cfg.queue_cfg.options);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_RSP_SET_TX_FLOW(cmd, flow_id) \ + MC_RSP_OP(cmd, 0, 48, 16, uint16_t, flow_id) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_GET_TX_FLOW(cmd, flow_id) \ + MC_CMD_OP(cmd, 0, 48, 16, uint16_t, flow_id) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_RSP_GET_TX_FLOW(cmd, attr) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 32, int, \ + attr->conf_err_attr.queue_attr.dest_cfg.dest_id);\ + MC_RSP_OP(cmd, 0, 32, 8, uint8_t, \ + attr->conf_err_attr.queue_attr.dest_cfg.priority);\ + MC_RSP_OP(cmd, 0, 40, 2, enum dpni_dest, \ + attr->conf_err_attr.queue_attr.dest_cfg.dest_type);\ + MC_RSP_OP(cmd, 0, 42, 1, int, attr->conf_err_attr.errors_only);\ + MC_RSP_OP(cmd, 0, 43, 1, int, attr->l3_chksum_gen);\ + MC_RSP_OP(cmd, 0, 44, 1, int, attr->l4_chksum_gen);\ + MC_RSP_OP(cmd, 0, 45, 1, int, \ + attr->conf_err_attr.use_default_queue);\ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, \ + attr->conf_err_attr.queue_attr.user_ctx);\ + MC_RSP_OP(cmd, 2, 32, 32, uint32_t, \ + attr->conf_err_attr.queue_attr.fqid);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_SET_RX_FLOW(cmd, tc_id, flow_id, cfg) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, int, cfg->dest_cfg.dest_id); \ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->dest_cfg.priority);\ + MC_CMD_OP(cmd, 0, 40, 2, enum dpni_dest, cfg->dest_cfg.dest_type);\ + MC_CMD_OP(cmd, 0, 48, 16, uint16_t, flow_id); \ + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->user_ctx); \ + MC_CMD_OP(cmd, 2, 16, 8, uint8_t, tc_id); \ + MC_CMD_OP(cmd, 2, 32, 32, uint32_t, cfg->options); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_CMD_GET_RX_FLOW(cmd, tc_id, flow_id) \ +do { \ + MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id); \ + MC_CMD_OP(cmd, 0, 48, 16, uint16_t, flow_id); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPNI_RSP_GET_RX_FLOW(cmd, attr) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 32, int, attr->dest_cfg.dest_id); \ + MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->dest_cfg.priority);\ + MC_RSP_OP(cmd, 0, 40, 2, enum dpni_dest, attr->dest_cfg.dest_type); \ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->user_ctx); \ + MC_RSP_OP(cmd, 2, 32, 32, uint32_t, attr->fqid); \ +} while (0) + +enum net_prot { + NET_PROT_NONE = 0, + NET_PROT_PAYLOAD, + NET_PROT_ETH, + NET_PROT_VLAN, + NET_PROT_IPV4, + NET_PROT_IPV6, + NET_PROT_IP, + NET_PROT_TCP, + NET_PROT_UDP, + NET_PROT_UDP_LITE, + NET_PROT_IPHC, + NET_PROT_SCTP, + NET_PROT_SCTP_CHUNK_DATA, + NET_PROT_PPPOE, + NET_PROT_PPP, + NET_PROT_PPPMUX, + NET_PROT_PPPMUX_SUBFRM, + NET_PROT_L2TPV2, + NET_PROT_L2TPV3_CTRL, + NET_PROT_L2TPV3_SESS, + NET_PROT_LLC, + NET_PROT_LLC_SNAP, + NET_PROT_NLPID, + NET_PROT_SNAP, + NET_PROT_MPLS, + NET_PROT_IPSEC_AH, + NET_PROT_IPSEC_ESP, + NET_PROT_UDP_ENC_ESP, /* RFC 3948 */ + NET_PROT_MACSEC, + NET_PROT_GRE, + NET_PROT_MINENCAP, + NET_PROT_DCCP, + NET_PROT_ICMP, + NET_PROT_IGMP, + NET_PROT_ARP, + NET_PROT_CAPWAP_DATA, + NET_PROT_CAPWAP_CTRL, + NET_PROT_RFC2684, + NET_PROT_ICMPV6, + NET_PROT_FCOE, + NET_PROT_FIP, + NET_PROT_ISCSI, + NET_PROT_GTP, + NET_PROT_USER_DEFINED_L2, + NET_PROT_USER_DEFINED_L3, + NET_PROT_USER_DEFINED_L4, + NET_PROT_USER_DEFINED_L5, + NET_PROT_USER_DEFINED_SHIM1, + NET_PROT_USER_DEFINED_SHIM2, + + NET_PROT_DUMMY_LAST +}; + +/* Data Path Network Interface API + * Contains initialization APIs and runtime control APIs for DPNI + */ + +struct fsl_mc_io; + +/* General DPNI macros */ + +/* Maximum number of traffic classes */ +#define DPNI_MAX_TC 8 +/* Maximum number of buffer pools per DPNI */ +#define DPNI_MAX_DPBP 8 + +/* All traffic classes considered; see dpni_set_rx_flow() */ +#define DPNI_ALL_TCS (uint8_t)(-1) +/* All flows within traffic class considered; see dpni_set_rx_flow() */ +#define DPNI_ALL_TC_FLOWS (uint16_t)(-1) +/* Generate new flow ID; see dpni_set_tx_flow() */ +#define DPNI_NEW_FLOW_ID (uint16_t)(-1) + +/** + * dpni_open() - Open a control session for the specified object + * @mc_io: Pointer to MC portal's I/O object + * @dpni_id: DPNI unique ID + * @token: Returned token; use in subsequent API calls + * + * This function can be used to open a control session for an + * already created object; an object may have been declared in + * the DPL or by calling the dpni_create() function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent commands for + * this specific object. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_open(struct fsl_mc_io *mc_io, int dpni_id, uint16_t *token); + +/** + * dpni_close() - Close the control session of the object + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * + * After this function is called, no further operations are + * allowed on the object without opening a new control session. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_close(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * struct dpni_ipr_cfg - Structure representing IP reassembly configuration + * @max_reass_frm_size: Maximum size of the reassembled frame + * @min_frag_size_ipv4: Minimum fragment size of IPv4 fragments + * @min_frag_size_ipv6: Minimum fragment size of IPv6 fragments + * @max_open_frames_ipv4: Maximum concurrent IPv4 packets in reassembly process + * @max_open_frames_ipv6: Maximum concurrent IPv6 packets in reassembly process + */ +struct dpni_ipr_cfg { + uint16_t max_reass_frm_size; + uint16_t min_frag_size_ipv4; + uint16_t min_frag_size_ipv6; + uint16_t max_open_frames_ipv4; + uint16_t max_open_frames_ipv6; +}; + +/** + * struct dpni_pools_cfg - Structure representing buffer pools configuration + * @num_dpbp: Number of DPBPs + * @pools: Array of buffer pools parameters; The number of valid entries + * must match 'num_dpbp' value + */ +struct dpni_pools_cfg { + uint8_t num_dpbp; + /** + * struct pools - Buffer pools parameters + * @dpbp_id: DPBP object ID + * @buffer_size: Buffer size + */ + struct { + int dpbp_id; + uint16_t buffer_size; + } pools[DPNI_MAX_DPBP]; +}; + +/** + * dpni_set_pools() - Set buffer pools configuration + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @cfg: Buffer pools configuration + * + * mandatory for DPNI operation + * warning:Allowed only when DPNI is disabled + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_set_pools(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dpni_pools_cfg *cfg); + +/** + * dpni_enable() - Enable the DPNI, allow sending and receiving frames. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_enable(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * dpni_disable() - Disable the DPNI, stop sending and receiving frames. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_disable(struct fsl_mc_io *mc_io, uint16_t token); + + +/** + * @dpni_reset() - Reset the DPNI, returns the object to initial state. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_reset(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * struct dpni_attr - Structure representing DPNI attributes + * @id: DPNI object ID + * @version: DPNI version + * @start_hdr: Indicates the packet starting header for parsing + * @options: Mask of available options; reflects the value as was given in + * object's creation + * @max_senders: Maximum number of different senders; used as the number + * of dedicated Tx flows; + * @max_tcs: Maximum number of traffic classes (for both Tx and Rx) + * @max_dist_per_tc: Maximum distribution size per Rx traffic class; + * Set to the required value minus 1 + * @max_unicast_filters: Maximum number of unicast filters + * @max_multicast_filters: Maximum number of multicast filters + * @max_vlan_filters: Maximum number of VLAN filters + * @max_qos_entries: if 'max_tcs > 1', declares the maximum entries in QoS table + * @max_qos_key_size: Maximum key size for the QoS look-up + * @max_dist_key_size: Maximum key size for the distribution look-up + * @ipr_cfg: IP reassembly configuration + */ +struct dpni_attr { + int id; + /** + * struct version - DPNI version + * @major: DPNI major version + * @minor: DPNI minor version + */ + struct { + uint16_t major; + uint16_t minor; + } version; + enum net_prot start_hdr; + uint64_t options; + uint8_t max_senders; + uint8_t max_tcs; + uint8_t max_dist_per_tc[DPNI_MAX_TC]; + uint8_t max_unicast_filters; + uint8_t max_multicast_filters; + uint8_t max_vlan_filters; + uint8_t max_qos_entries; + uint8_t max_qos_key_size; + uint8_t max_dist_key_size; + struct dpni_ipr_cfg ipr_cfg; +}; +/** + * dpni_get_attributes() - Retrieve DPNI attributes. + * @mc_io: Pointer to MC portal's I/O objec + * @token: Token of DPNI object + * @attr: Returned object's attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpni_attr *attr); + +/* DPNI buffer layout modification options */ + +/* Select to modify the time-stamp setting */ +#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP 0x00000001 +/* Select to modify the parser-result setting; not applicable for Tx */ +#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT 0x00000002 +/* Select to modify the frame-status setting */ +#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS 0x00000004 +/* Select to modify the private-data-size setting */ +#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE 0x00000008 +/* Select to modify the data-alignment setting */ +#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN 0x00000010 +/* Select to modify the data-head-room setting */ +#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM 0x00000020 +/*!< Select to modify the data-tail-room setting */ +#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM 0x00000040 + +/** + * struct dpni_buffer_layout - Structure representing DPNI buffer layout + * @options: Flags representing the suggested modifications to the buffer + * layout; Use any combination of 'DPNI_BUF_LAYOUT_OPT_<X>' flags + * @pass_timestamp: Pass timestamp value + * @pass_parser_result: Pass parser results + * @pass_frame_status: Pass frame status + * @private_data_size: Size kept for private data (in bytes) + * @data_align: Data alignment + * @data_head_room: Data head room + * @data_tail_room: Data tail room + */ +struct dpni_buffer_layout { + uint32_t options; + int pass_timestamp; + int pass_parser_result; + int pass_frame_status; + uint16_t private_data_size; + uint16_t data_align; + uint16_t data_head_room; + uint16_t data_tail_room; +}; + +/** + * dpni_get_rx_buffer_layout() - Retrieve Rx buffer layout attributes. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @layout: Returns buffer layout attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_get_rx_buffer_layout(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpni_buffer_layout *layout); +/** + * dpni_set_rx_buffer_layout() - Set Rx buffer layout configuration. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @layout: Buffer layout configuration + * + * Return: '0' on Success; Error code otherwise. + * + * @warning Allowed only when DPNI is disabled + */ +int dpni_set_rx_buffer_layout(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dpni_buffer_layout *layout); + +/** + * dpni_get_tx_buffer_layout() - Retrieve Tx buffer layout attributes. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @layout: Returns buffer layout attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_get_tx_buffer_layout(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpni_buffer_layout *layout); + +/** + * @brief Set Tx buffer layout configuration. + * + * @param[in] mc_io Pointer to MC portal's I/O object + * @param[in] token Token of DPNI object + * @param[in] layout Buffer layout configuration + * + * @returns '0' on Success; Error code otherwise. + * + * @warning Allowed only when DPNI is disabled + */ +int dpni_set_tx_buffer_layout(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dpni_buffer_layout *layout); +/** + * dpni_get_tx_conf_buffer_layout() - Retrieve Tx confirmation buffer layout + * attributes. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @layout: Returns buffer layout attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_get_tx_conf_buffer_layout(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpni_buffer_layout *layout); +/** + * dpni_set_tx_conf_buffer_layout() - Set Tx confirmation buffer layout + * configuration. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @layout: Buffer layout configuration + * + * Return: '0' on Success; Error code otherwise. + * + * @warning Allowed only when DPNI is disabled + */ +int dpni_set_tx_conf_buffer_layout(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dpni_buffer_layout *layout); +/** + * dpni_get_spid() - Get the AIOP storage profile ID associated with the DPNI + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @spid: Returned aiop storage-profile ID + * + * Return: '0' on Success; Error code otherwise. + * + * @warning Only relevant for DPNI that belongs to AIOP container. + */ +int dpni_get_qdid(struct fsl_mc_io *mc_io, uint16_t token, uint16_t *qdid); + +/** + * dpni_get_tx_data_offset() - Get the Tx data offset (from start of buffer) + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @data_offset: Tx data offset (from start of buffer) + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io, + uint16_t token, + uint16_t *data_offset); + +/** + * enum dpni_counter - DPNI counter types + * @DPNI_CNT_ING_FRAME: Counts ingress frames + * @DPNI_CNT_ING_BYTE: Counts ingress bytes + * @DPNI_CNT_ING_FRAME_DROP: Counts ingress frames dropped due to explicit + * 'drop' setting + * @DPNI_CNT_ING_FRAME_DISCARD: Counts ingress frames discarded due to errors + * @DPNI_CNT_ING_MCAST_FRAME: Counts ingress multicast frames + * @DPNI_CNT_ING_MCAST_BYTE: Counts ingress multicast bytes + * @DPNI_CNT_ING_BCAST_FRAME: Counts ingress broadcast frames + * @DPNI_CNT_ING_BCAST_BYTES: Counts ingress broadcast bytes + * @DPNI_CNT_EGR_FRAME: Counts egress frames + * @DPNI_CNT_EGR_BYTE: Counts egress bytes + * @DPNI_CNT_EGR_FRAME_DISCARD: Counts egress frames discarded due to errors + */ +enum dpni_counter { + DPNI_CNT_ING_FRAME = 0x0, + DPNI_CNT_ING_BYTE = 0x1, + DPNI_CNT_ING_FRAME_DROP = 0x2, + DPNI_CNT_ING_FRAME_DISCARD = 0x3, + DPNI_CNT_ING_MCAST_FRAME = 0x4, + DPNI_CNT_ING_MCAST_BYTE = 0x5, + DPNI_CNT_ING_BCAST_FRAME = 0x6, + DPNI_CNT_ING_BCAST_BYTES = 0x7, + DPNI_CNT_EGR_FRAME = 0x8, + DPNI_CNT_EGR_BYTE = 0x9, + DPNI_CNT_EGR_FRAME_DISCARD = 0xa +}; + +/** + * dpni_get_counter() - Read a specific DPNI counter + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @counter: The requested counter + * @value: Returned counter's current value + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_get_counter(struct fsl_mc_io *mc_io, + uint16_t token, + enum dpni_counter counter, + uint64_t *value); + +/** + * dpni_set_counter() - Set (or clear) a specific DPNI counter + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @counter: The requested counter + * @value: New counter value; typically pass '0' for resetting + * the counter. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_set_counter(struct fsl_mc_io *mc_io, + uint16_t token, + enum dpni_counter counter, + uint64_t value); +/** + * struct - Structure representing DPNI link configuration + * @rate: Rate + * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values + */ +struct dpni_link_cfg { + uint64_t rate; + uint64_t options; +}; + +/** + * dpni_set_link_cfg() - set the link configuration. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @cfg: Link configuration + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_set_link_cfg(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpni_link_cfg *cfg); + +/** + * struct dpni_link_state - Structure representing DPNI link state + * @rate: Rate + * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values + * @up: Link state; '0' for down, '1' for up + */ +struct dpni_link_state { + uint64_t rate; + uint64_t options; + int up; +}; + +/** + * dpni_get_link_state() - Return the link state (either up or down) + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @state: Returned link state; + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_get_link_state(struct fsl_mc_io *mc_io, + uint16_t token, + struct dpni_link_state *state); + +/** + * dpni_set_primary_mac_addr() - Set the primary MAC address + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @mac_addr: MAC address to set as primary address + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io, + uint16_t token, + const uint8_t mac_addr[6]); +/** + * dpni_get_primary_mac_addr() - Get the primary MAC address + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @mac_addr: Returned MAC address + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t mac_addr[6]); +/** + * dpni_add_mac_addr() - Add MAC address filter + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @mac_addr: MAC address to add + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_add_mac_addr(struct fsl_mc_io *mc_io, + uint16_t token, + const uint8_t mac_addr[6]); + +/** + * dpni_remove_mac_addr() - Remove MAC address filter + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @mac_addr: MAC address to remove + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_remove_mac_addr(struct fsl_mc_io *mc_io, + uint16_t token, + const uint8_t mac_addr[6]); + +/** + * enum dpni_dest - DPNI destination types + * DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and + * does not generate FQDAN notifications; user is expected to + * dequeue from the queue based on polling or other user-defined + * method + * @DPNI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN + * notifications to the specified DPIO; user is expected to dequeue + * from the queue only after notification is received + * @DPNI_DEST_DPCON: The queue is set in schedule mode and does not generate + * FQDAN notifications, but is connected to the specified DPCON + * object; user is expected to dequeue from the DPCON channel + */ +enum dpni_dest { + DPNI_DEST_NONE = 0, + DPNI_DEST_DPIO = 1, + DPNI_DEST_DPCON = 2 +}; + +/** + * struct dpni_dest_cfg - Structure representing DPNI destination parameters + * @dest_type: Destination type + * @dest_id: Either DPIO ID or DPCON ID, depending on the destination type + * @priority: Priority selection within the DPIO or DPCON channel; valid values + * are 0-1 or 0-7, depending on the number of priorities in that + * channel; not relevant for 'DPNI_DEST_NONE' option + */ +struct dpni_dest_cfg { + enum dpni_dest dest_type; + int dest_id; + uint8_t priority; +}; + +/* DPNI queue modification options */ + +/* Select to modify the user's context associated with the queue */ +#define DPNI_QUEUE_OPT_USER_CTX 0x00000001 +/* Select to modify the queue's destination */ +#define DPNI_QUEUE_OPT_DEST 0x00000002 + +/** + * struct dpni_queue_cfg - Structure representing queue configuration + * @options: Flags representing the suggested modifications to the queue; + * Use any combination of 'DPNI_QUEUE_OPT_<X>' flags + * @user_ctx: User context value provided in the frame descriptor of each + * dequeued frame; valid only if 'DPNI_QUEUE_OPT_USER_CTX' + * is contained in 'options' + * @dest_cfg: Queue destination parameters; + * valid only if 'DPNI_QUEUE_OPT_DEST' is contained in 'options' + */ +struct dpni_queue_cfg { + uint32_t options; + uint64_t user_ctx; + struct dpni_dest_cfg dest_cfg; +}; + +/** + * struct dpni_queue_attr - Structure representing queue attributes + * @user_ctx: User context value provided in the frame descriptor of each + * dequeued frame + * @dest_cfg: Queue destination configuration + * @fqid: Virtual fqid value to be used for dequeue operations + */ +struct dpni_queue_attr { + uint64_t user_ctx; + struct dpni_dest_cfg dest_cfg; + uint32_t fqid; +}; + +/* DPNI Tx flow modification options */ + +/* Select to modify the settings for dedicate Tx confirmation/error */ +#define DPNI_TX_FLOW_OPT_TX_CONF_ERROR 0x00000001 +/*!< Select to modify the Tx confirmation and/or error setting */ +#define DPNI_TX_FLOW_OPT_ONLY_TX_ERROR 0x00000002 +/*!< Select to modify the queue configuration */ +#define DPNI_TX_FLOW_OPT_QUEUE 0x00000004 +/*!< Select to modify the L3 checksum generation setting */ +#define DPNI_TX_FLOW_OPT_L3_CHKSUM_GEN 0x00000010 +/*!< Select to modify the L4 checksum generation setting */ +#define DPNI_TX_FLOW_OPT_L4_CHKSUM_GEN 0x00000020 + +/** + * struct dpni_tx_flow_cfg - Structure representing Tx flow configuration + * @options: Flags representing the suggested modifications to the Tx flow; + * Use any combination 'DPNI_TX_FLOW_OPT_<X>' flags + * @conf_err_cfg: Tx confirmation and error configuration; these settings are + * ignored if 'DPNI_OPT_PRIVATE_TX_CONF_ERROR_DISABLED' was set at + * DPNI creation + * @l3_chksum_gen: Set to '1' to enable L3 checksum generation; '0' to disable; + * valid only if 'DPNI_TX_FLOW_OPT_L3_CHKSUM_GEN' is contained in + * 'options' + * @l4_chksum_gen: Set to '1' to enable L4 checksum generation; '0' to disable; + * valid only if 'DPNI_TX_FLOW_OPT_L4_CHKSUM_GEN' is contained in + * 'options' + */ +struct dpni_tx_flow_cfg { + uint32_t options; + /** + * struct cnf_err_cfg - Tx confirmation and error configuration + * @use_default_queue: Set to '1' to use the common (default) Tx + * confirmation and error queue; Set to '0' to use the + * private Tx confirmation and error queue; valid only if + * 'DPNI_TX_FLOW_OPT_TX_CONF_ERROR' is contained in + * 'options' + * @errors_only: Set to '1' to report back only error frames; + * Set to '0' to confirm transmission/error for all + * transmitted frames; + * valid only if 'DPNI_TX_FLOW_OPT_ONLY_TX_ERROR' is + * contained in 'options' and 'use_default_queue = 0'; + * @queue_cfg: Queue configuration; valid only if + * 'DPNI_TX_FLOW_OPT_QUEUE' is contained in 'options' + */ + struct { + int use_default_queue; + int errors_only; + struct dpni_queue_cfg queue_cfg; + } conf_err_cfg; + int l3_chksum_gen; + int l4_chksum_gen; +}; + +/** + * dpni_set_tx_flow() - Set Tx flow configuration + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @flow_id: Provides (or returns) the sender's flow ID; + * for each new sender set (*flow_id) to + * 'DPNI_NEW_FLOW_ID' to generate a new flow_id; + * this ID should be used as the QDBIN argument + * in enqueue operations + * @cfg: Tx flow configuration + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_set_tx_flow(struct fsl_mc_io *mc_io, + uint16_t token, + uint16_t *flow_id, + const struct dpni_tx_flow_cfg *cfg); + +/** + * struct dpni_tx_flow_attr - Structure representing Tx flow attributes + * @conf_err_attr: Tx confirmation and error attributes + * @l3_chksum_gen: '1' if L3 checksum generation is enabled; '0' if disabled + * @l4_chksum_gen: '1' if L4 checksum generation is enabled; '0' if disabled + */ +struct dpni_tx_flow_attr { + /** + * struct conf_err_attr - Tx confirmation and error attributes + * @use_default_queue: '1' if using common (default) Tx confirmation and + * error queue; + * '0' if using private Tx confirmation and error + * queue + * @errors_only: '1' if only error frames are reported back; '0' if all + * transmitted frames are confirmed + * @queue_attr: Queue attributes + */ + struct { + int use_default_queue; + int errors_only; + struct dpni_queue_attr queue_attr; + } conf_err_attr; + int l3_chksum_gen; + int l4_chksum_gen; +}; + +/** + * dpni_get_tx_flow() - Get Tx flow attributes + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @flow_id: The sender's flow ID, as returned by the + * dpni_set_tx_flow() function + * @attr: Returned Tx flow attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_get_tx_flow(struct fsl_mc_io *mc_io, + uint16_t token, + uint16_t flow_id, + struct dpni_tx_flow_attr *attr); + +/** + * dpni_set_rx_flow() - Set Rx flow configuration + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @tc_id: Traffic class selection (0-7); + * use 'DPNI_ALL_TCS' to set all TCs and all flows + * @flow_id Rx flow id within the traffic class; use + * 'DPNI_ALL_TC_FLOWS' to set all flows within + * this tc_id; ignored if tc_id is set to + * 'DPNI_ALL_TCS'; + * @cfg: Rx flow configuration + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_set_rx_flow(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t tc_id, + uint16_t flow_id, + const struct dpni_queue_cfg *cfg); + +/** + * dpni_get_rx_flow() - Get Rx flow attributes + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPNI object + * @tc_id: Traffic class selection (0-7) + * @flow_id: Rx flow id within the traffic class + * @attr: Returned Rx flow attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_get_rx_flow(struct fsl_mc_io *mc_io, + uint16_t token, + uint8_t tc_id, + uint16_t flow_id, + struct dpni_queue_attr *attr); + +#endif /* _FSL_DPNI_H */ diff --git a/include/fsl-mc/fsl_dprc.h b/include/fsl-mc/fsl_dprc.h new file mode 100644 index 0000000..f837e89 --- /dev/null +++ b/include/fsl-mc/fsl_dprc.h @@ -0,0 +1,659 @@ +/* + * Freescale Layerscape MC I/O wrapper + * + * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. + * Author: German Rivera <German.Rivera@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _FSL_DPRC_H +#define _FSL_DPRC_H + +/* DPRC Version */ +#define DPRC_VER_MAJOR 2 +#define DPRC_VER_MINOR 0 + +/* Command IDs */ +#define DPRC_CMDID_CLOSE 0x800 +#define DPRC_CMDID_OPEN 0x805 + +#define DPRC_CMDID_GET_ATTR 0x004 +#define DPRC_CMDID_RESET_CONT 0x005 + +#define DPRC_CMDID_GET_CONT_ID 0x830 +#define DPRC_CMDID_GET_OBJ_COUNT 0x159 +#define DPRC_CMDID_GET_OBJ 0x15A +#define DPRC_CMDID_GET_RES_COUNT 0x15B +#define DPRC_CMDID_GET_RES_IDS 0x15C +#define DPRC_CMDID_GET_OBJ_REG 0x15E + +#define DPRC_CMDID_CONNECT 0x167 +#define DPRC_CMDID_DISCONNECT 0x168 +#define DPRC_CMDID_GET_CONNECTION 0x16C + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_RSP_GET_CONTAINER_ID(cmd, container_id) \ + MC_RSP_OP(cmd, 0, 0, 32, int, container_id) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_CMD_OPEN(cmd, container_id) \ + MC_CMD_OP(cmd, 0, 0, 32, int, container_id) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_CMD_RESET_CONTAINER(cmd, child_container_id) \ + MC_CMD_OP(cmd, 0, 0, 32, int, child_container_id) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_RSP_GET_ATTRIBUTES(cmd, attr) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 32, int, attr->container_id); \ + MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->icid); \ + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, attr->options);\ + MC_RSP_OP(cmd, 1, 32, 32, int, attr->portal_id); \ + MC_RSP_OP(cmd, 2, 0, 16, uint16_t, attr->version.major);\ + MC_RSP_OP(cmd, 2, 16, 16, uint16_t, attr->version.minor);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_RSP_GET_OBJ_COUNT(cmd, obj_count) \ + MC_RSP_OP(cmd, 0, 32, 32, int, obj_count) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_CMD_GET_OBJ(cmd, obj_index) \ + MC_CMD_OP(cmd, 0, 0, 32, int, obj_index) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_RSP_GET_OBJ(cmd, obj_desc) \ +do { \ + MC_RSP_OP(cmd, 0, 32, 32, int, obj_desc->id); \ + MC_RSP_OP(cmd, 1, 0, 16, uint16_t, obj_desc->vendor); \ + MC_RSP_OP(cmd, 1, 16, 8, uint8_t, obj_desc->irq_count); \ + MC_RSP_OP(cmd, 1, 24, 8, uint8_t, obj_desc->region_count); \ + MC_RSP_OP(cmd, 1, 32, 32, uint32_t, obj_desc->state);\ + MC_RSP_OP(cmd, 2, 0, 16, uint16_t, obj_desc->ver_major);\ + MC_RSP_OP(cmd, 2, 16, 16, uint16_t, obj_desc->ver_minor);\ + MC_RSP_OP(cmd, 3, 0, 8, char, obj_desc->type[0]);\ + MC_RSP_OP(cmd, 3, 8, 8, char, obj_desc->type[1]);\ + MC_RSP_OP(cmd, 3, 16, 8, char, obj_desc->type[2]);\ + MC_RSP_OP(cmd, 3, 24, 8, char, obj_desc->type[3]);\ + MC_RSP_OP(cmd, 3, 32, 8, char, obj_desc->type[4]);\ + MC_RSP_OP(cmd, 3, 40, 8, char, obj_desc->type[5]);\ + MC_RSP_OP(cmd, 3, 48, 8, char, obj_desc->type[6]);\ + MC_RSP_OP(cmd, 3, 56, 8, char, obj_desc->type[7]);\ + MC_RSP_OP(cmd, 4, 0, 8, char, obj_desc->type[8]);\ + MC_RSP_OP(cmd, 4, 8, 8, char, obj_desc->type[9]);\ + MC_RSP_OP(cmd, 4, 16, 8, char, obj_desc->type[10]);\ + MC_RSP_OP(cmd, 4, 24, 8, char, obj_desc->type[11]);\ + MC_RSP_OP(cmd, 4, 32, 8, char, obj_desc->type[12]);\ + MC_RSP_OP(cmd, 4, 40, 8, char, obj_desc->type[13]);\ + MC_RSP_OP(cmd, 4, 48, 8, char, obj_desc->type[14]);\ + MC_RSP_OP(cmd, 4, 56, 8, char, obj_desc->type[15]);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_CMD_GET_RES_COUNT(cmd, type) \ +do { \ + MC_CMD_OP(cmd, 1, 0, 8, char, type[0]);\ + MC_CMD_OP(cmd, 1, 8, 8, char, type[1]);\ + MC_CMD_OP(cmd, 1, 16, 8, char, type[2]);\ + MC_CMD_OP(cmd, 1, 24, 8, char, type[3]);\ + MC_CMD_OP(cmd, 1, 32, 8, char, type[4]);\ + MC_CMD_OP(cmd, 1, 40, 8, char, type[5]);\ + MC_CMD_OP(cmd, 1, 48, 8, char, type[6]);\ + MC_CMD_OP(cmd, 1, 56, 8, char, type[7]);\ + MC_CMD_OP(cmd, 2, 0, 8, char, type[8]);\ + MC_CMD_OP(cmd, 2, 8, 8, char, type[9]);\ + MC_CMD_OP(cmd, 2, 16, 8, char, type[10]);\ + MC_CMD_OP(cmd, 2, 24, 8, char, type[11]);\ + MC_CMD_OP(cmd, 2, 32, 8, char, type[12]);\ + MC_CMD_OP(cmd, 2, 40, 8, char, type[13]);\ + MC_CMD_OP(cmd, 2, 48, 8, char, type[14]);\ + MC_CMD_OP(cmd, 2, 56, 8, char, type[15]);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_RSP_GET_RES_COUNT(cmd, res_count) \ + MC_RSP_OP(cmd, 0, 0, 32, int, res_count) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_CMD_GET_RES_IDS(cmd, range_desc, type) \ +do { \ + MC_CMD_OP(cmd, 0, 42, 7, enum dprc_iter_status, \ + range_desc->iter_status); \ + MC_CMD_OP(cmd, 1, 0, 32, int, range_desc->base_id); \ + MC_CMD_OP(cmd, 1, 32, 32, int, range_desc->last_id);\ + MC_CMD_OP(cmd, 2, 0, 8, char, type[0]);\ + MC_CMD_OP(cmd, 2, 8, 8, char, type[1]);\ + MC_CMD_OP(cmd, 2, 16, 8, char, type[2]);\ + MC_CMD_OP(cmd, 2, 24, 8, char, type[3]);\ + MC_CMD_OP(cmd, 2, 32, 8, char, type[4]);\ + MC_CMD_OP(cmd, 2, 40, 8, char, type[5]);\ + MC_CMD_OP(cmd, 2, 48, 8, char, type[6]);\ + MC_CMD_OP(cmd, 2, 56, 8, char, type[7]);\ + MC_CMD_OP(cmd, 3, 0, 8, char, type[8]);\ + MC_CMD_OP(cmd, 3, 8, 8, char, type[9]);\ + MC_CMD_OP(cmd, 3, 16, 8, char, type[10]);\ + MC_CMD_OP(cmd, 3, 24, 8, char, type[11]);\ + MC_CMD_OP(cmd, 3, 32, 8, char, type[12]);\ + MC_CMD_OP(cmd, 3, 40, 8, char, type[13]);\ + MC_CMD_OP(cmd, 3, 48, 8, char, type[14]);\ + MC_CMD_OP(cmd, 3, 56, 8, char, type[15]);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_RSP_GET_RES_IDS(cmd, range_desc) \ +do { \ + MC_RSP_OP(cmd, 0, 42, 7, enum dprc_iter_status, \ + range_desc->iter_status);\ + MC_RSP_OP(cmd, 1, 0, 32, int, range_desc->base_id); \ + MC_RSP_OP(cmd, 1, 32, 32, int, range_desc->last_id);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_CMD_GET_OBJ_REGION(cmd, obj_type, obj_id, region_index) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, int, obj_id); \ + MC_CMD_OP(cmd, 0, 48, 8, uint8_t, region_index);\ + MC_CMD_OP(cmd, 3, 0, 8, char, obj_type[0]);\ + MC_CMD_OP(cmd, 3, 8, 8, char, obj_type[1]);\ + MC_CMD_OP(cmd, 3, 16, 8, char, obj_type[2]);\ + MC_CMD_OP(cmd, 3, 24, 8, char, obj_type[3]);\ + MC_CMD_OP(cmd, 3, 32, 8, char, obj_type[4]);\ + MC_CMD_OP(cmd, 3, 40, 8, char, obj_type[5]);\ + MC_CMD_OP(cmd, 3, 48, 8, char, obj_type[6]);\ + MC_CMD_OP(cmd, 3, 56, 8, char, obj_type[7]);\ + MC_CMD_OP(cmd, 4, 0, 8, char, obj_type[8]);\ + MC_CMD_OP(cmd, 4, 8, 8, char, obj_type[9]);\ + MC_CMD_OP(cmd, 4, 16, 8, char, obj_type[10]);\ + MC_CMD_OP(cmd, 4, 24, 8, char, obj_type[11]);\ + MC_CMD_OP(cmd, 4, 32, 8, char, obj_type[12]);\ + MC_CMD_OP(cmd, 4, 40, 8, char, obj_type[13]);\ + MC_CMD_OP(cmd, 4, 48, 8, char, obj_type[14]);\ + MC_CMD_OP(cmd, 4, 56, 8, char, obj_type[15]);\ +} while (0) + +/* param, offset, width, type, arg_name */ +#define DPRC_RSP_GET_OBJ_REGION(cmd, region_desc) \ +do { \ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, region_desc->base_paddr);\ + MC_RSP_OP(cmd, 2, 0, 32, uint32_t, region_desc->size); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_CMD_CONNECT(cmd, endpoint1, endpoint2) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, int, endpoint1->id); \ + MC_CMD_OP(cmd, 0, 32, 32, int, endpoint1->interface_id); \ + MC_CMD_OP(cmd, 1, 0, 32, int, endpoint2->id); \ + MC_CMD_OP(cmd, 1, 32, 32, int, endpoint2->interface_id); \ + MC_CMD_OP(cmd, 2, 0, 8, char, endpoint1->type[0]); \ + MC_CMD_OP(cmd, 2, 8, 8, char, endpoint1->type[1]); \ + MC_CMD_OP(cmd, 2, 16, 8, char, endpoint1->type[2]); \ + MC_CMD_OP(cmd, 2, 24, 8, char, endpoint1->type[3]); \ + MC_CMD_OP(cmd, 2, 32, 8, char, endpoint1->type[4]); \ + MC_CMD_OP(cmd, 2, 40, 8, char, endpoint1->type[5]); \ + MC_CMD_OP(cmd, 2, 48, 8, char, endpoint1->type[6]); \ + MC_CMD_OP(cmd, 2, 56, 8, char, endpoint1->type[7]); \ + MC_CMD_OP(cmd, 3, 0, 8, char, endpoint1->type[8]); \ + MC_CMD_OP(cmd, 3, 8, 8, char, endpoint1->type[9]); \ + MC_CMD_OP(cmd, 3, 16, 8, char, endpoint1->type[10]); \ + MC_CMD_OP(cmd, 3, 24, 8, char, endpoint1->type[11]); \ + MC_CMD_OP(cmd, 3, 32, 8, char, endpoint1->type[12]); \ + MC_CMD_OP(cmd, 3, 40, 8, char, endpoint1->type[13]); \ + MC_CMD_OP(cmd, 3, 48, 8, char, endpoint1->type[14]); \ + MC_CMD_OP(cmd, 3, 56, 8, char, endpoint1->type[15]); \ + MC_CMD_OP(cmd, 5, 0, 8, char, endpoint2->type[0]); \ + MC_CMD_OP(cmd, 5, 8, 8, char, endpoint2->type[1]); \ + MC_CMD_OP(cmd, 5, 16, 8, char, endpoint2->type[2]); \ + MC_CMD_OP(cmd, 5, 24, 8, char, endpoint2->type[3]); \ + MC_CMD_OP(cmd, 5, 32, 8, char, endpoint2->type[4]); \ + MC_CMD_OP(cmd, 5, 40, 8, char, endpoint2->type[5]); \ + MC_CMD_OP(cmd, 5, 48, 8, char, endpoint2->type[6]); \ + MC_CMD_OP(cmd, 5, 56, 8, char, endpoint2->type[7]); \ + MC_CMD_OP(cmd, 6, 0, 8, char, endpoint2->type[8]); \ + MC_CMD_OP(cmd, 6, 8, 8, char, endpoint2->type[9]); \ + MC_CMD_OP(cmd, 6, 16, 8, char, endpoint2->type[10]); \ + MC_CMD_OP(cmd, 6, 24, 8, char, endpoint2->type[11]); \ + MC_CMD_OP(cmd, 6, 32, 8, char, endpoint2->type[12]); \ + MC_CMD_OP(cmd, 6, 40, 8, char, endpoint2->type[13]); \ + MC_CMD_OP(cmd, 6, 48, 8, char, endpoint2->type[14]); \ + MC_CMD_OP(cmd, 6, 56, 8, char, endpoint2->type[15]); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_CMD_DISCONNECT(cmd, endpoint) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, int, endpoint->id); \ + MC_CMD_OP(cmd, 0, 32, 32, int, endpoint->interface_id); \ + MC_CMD_OP(cmd, 1, 0, 8, char, endpoint->type[0]); \ + MC_CMD_OP(cmd, 1, 8, 8, char, endpoint->type[1]); \ + MC_CMD_OP(cmd, 1, 16, 8, char, endpoint->type[2]); \ + MC_CMD_OP(cmd, 1, 24, 8, char, endpoint->type[3]); \ + MC_CMD_OP(cmd, 1, 32, 8, char, endpoint->type[4]); \ + MC_CMD_OP(cmd, 1, 40, 8, char, endpoint->type[5]); \ + MC_CMD_OP(cmd, 1, 48, 8, char, endpoint->type[6]); \ + MC_CMD_OP(cmd, 1, 56, 8, char, endpoint->type[7]); \ + MC_CMD_OP(cmd, 2, 0, 8, char, endpoint->type[8]); \ + MC_CMD_OP(cmd, 2, 8, 8, char, endpoint->type[9]); \ + MC_CMD_OP(cmd, 2, 16, 8, char, endpoint->type[10]); \ + MC_CMD_OP(cmd, 2, 24, 8, char, endpoint->type[11]); \ + MC_CMD_OP(cmd, 2, 32, 8, char, endpoint->type[12]); \ + MC_CMD_OP(cmd, 2, 40, 8, char, endpoint->type[13]); \ + MC_CMD_OP(cmd, 2, 48, 8, char, endpoint->type[14]); \ + MC_CMD_OP(cmd, 2, 56, 8, char, endpoint->type[15]); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_CMD_GET_CONNECTION(cmd, endpoint1) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, int, endpoint1->id); \ + MC_CMD_OP(cmd, 0, 32, 32, int, endpoint1->interface_id); \ + MC_CMD_OP(cmd, 1, 0, 8, char, endpoint1->type[0]); \ + MC_CMD_OP(cmd, 1, 8, 8, char, endpoint1->type[1]); \ + MC_CMD_OP(cmd, 1, 16, 8, char, endpoint1->type[2]); \ + MC_CMD_OP(cmd, 1, 24, 8, char, endpoint1->type[3]); \ + MC_CMD_OP(cmd, 1, 32, 8, char, endpoint1->type[4]); \ + MC_CMD_OP(cmd, 1, 40, 8, char, endpoint1->type[5]); \ + MC_CMD_OP(cmd, 1, 48, 8, char, endpoint1->type[6]); \ + MC_CMD_OP(cmd, 1, 56, 8, char, endpoint1->type[7]); \ + MC_CMD_OP(cmd, 2, 0, 8, char, endpoint1->type[8]); \ + MC_CMD_OP(cmd, 2, 8, 8, char, endpoint1->type[9]); \ + MC_CMD_OP(cmd, 2, 16, 8, char, endpoint1->type[10]); \ + MC_CMD_OP(cmd, 2, 24, 8, char, endpoint1->type[11]); \ + MC_CMD_OP(cmd, 2, 32, 8, char, endpoint1->type[12]); \ + MC_CMD_OP(cmd, 2, 40, 8, char, endpoint1->type[13]); \ + MC_CMD_OP(cmd, 2, 48, 8, char, endpoint1->type[14]); \ + MC_CMD_OP(cmd, 2, 56, 8, char, endpoint1->type[15]); \ +} while (0) + + +/* cmd, param, offset, width, type, arg_name */ +#define DPRC_RSP_GET_CONNECTION(cmd, endpoint2, state) \ +do { \ + MC_RSP_OP(cmd, 3, 0, 32, int, endpoint2->id); \ + MC_RSP_OP(cmd, 3, 32, 32, int, endpoint2->interface_id); \ + MC_RSP_OP(cmd, 4, 0, 8, char, endpoint2->type[0]); \ + MC_RSP_OP(cmd, 4, 8, 8, char, endpoint2->type[1]); \ + MC_RSP_OP(cmd, 4, 16, 8, char, endpoint2->type[2]); \ + MC_RSP_OP(cmd, 4, 24, 8, char, endpoint2->type[3]); \ + MC_RSP_OP(cmd, 4, 32, 8, char, endpoint2->type[4]); \ + MC_RSP_OP(cmd, 4, 40, 8, char, endpoint2->type[5]); \ + MC_RSP_OP(cmd, 4, 48, 8, char, endpoint2->type[6]); \ + MC_RSP_OP(cmd, 4, 56, 8, char, endpoint2->type[7]); \ + MC_RSP_OP(cmd, 5, 0, 8, char, endpoint2->type[8]); \ + MC_RSP_OP(cmd, 5, 8, 8, char, endpoint2->type[9]); \ + MC_RSP_OP(cmd, 5, 16, 8, char, endpoint2->type[10]); \ + MC_RSP_OP(cmd, 5, 24, 8, char, endpoint2->type[11]); \ + MC_RSP_OP(cmd, 5, 32, 8, char, endpoint2->type[12]); \ + MC_RSP_OP(cmd, 5, 40, 8, char, endpoint2->type[13]); \ + MC_RSP_OP(cmd, 5, 48, 8, char, endpoint2->type[14]); \ + MC_RSP_OP(cmd, 5, 56, 8, char, endpoint2->type[15]); \ + MC_RSP_OP(cmd, 6, 0, 32, int, state); \ +} while (0) + +/* Data Path Resource Container API + * Contains DPRC API for managing and querying DPAA resources + */ +struct fsl_mc_io; + +/** + * Set this value as the icid value in dprc_cfg structure when creating a + * container, in case the ICID is not selected by the user and should be + * allocated by the DPRC from the pool of ICIDs. + */ +#define DPRC_GET_ICID_FROM_POOL (uint16_t)(~(0)) + +/** + * Set this value as the portal_id value in dprc_cfg structure when creating a + * container, in case the portal ID is not specifically selected by the + * user and should be allocated by the DPRC from the pool of portal ids. + */ +#define DPRC_GET_PORTAL_ID_FROM_POOL (int)(~(0)) + +/** + * dprc_get_container_id() - Get container ID associated with a given portal. + * @mc_io: Pointer to MC portal's I/O object + * @container_id: Requested container ID + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_container_id(struct fsl_mc_io *mc_io, int *container_id); + +/** + * dprc_open() - Open DPRC object for use + * @mc_io: Pointer to MC portal's I/O object + * @container_id: Container ID to open + * @token: Returned token of DPRC object + * + * Return: '0' on Success; Error code otherwise. + * + * @warning Required before any operation on the object. + */ +int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token); + +/** + * dprc_close() - Close the control session of the object + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * + * After this function is called, no further operations are + * allowed on the object without opening a new control session. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_close(struct fsl_mc_io *mc_io, uint16_t token); + +/** + * Container general options + * + * These options may be selected at container creation by the container creator + * and can be retrieved using dprc_get_attributes() + */ + +/* Spawn Policy Option allowed - Indicates that the new container is allowed + * to spawn and have its own child containers. + */ +#define DPRC_CFG_OPT_SPAWN_ALLOWED 0x00000001 + +/* General Container allocation policy - Indicates that the new container is + * allowed to allocate requested resources from its parent container; if not + * set, the container is only allowed to use resources in its own pools; Note + * that this is a container's global policy, but the parent container may + * override it and set specific quota per resource type. + */ +#define DPRC_CFG_OPT_ALLOC_ALLOWED 0x00000002 + +/* Object initialization allowed - software context associated with this + * container is allowed to invoke object initialization operations. + */ +#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004 + +/* Topology change allowed - software context associated with this + * container is allowed to invoke topology operations, such as attach/detach + * of network objects. + */ +#define DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED 0x00000008 + +/* IOMMU bypass - indicates whether objects of this container are permitted + * to bypass the IOMMU. + */ +#define DPRC_CFG_OPT_IOMMU_BYPASS 0x00000010 + +/* AIOP - Indicates that container belongs to AIOP. */ +#define DPRC_CFG_OPT_AIOP 0x00000020 + +/** + * struct dprc_cfg - Container configuration options + * @icid: Container's ICID; if set to 'DPRC_GET_ICID_FROM_POOL', a free + * ICID value is allocated by the DPRC + * @portal_id: Portal ID; if set to 'DPRC_GET_PORTAL_ID_FROM_POOL', a free + * portal ID is allocated by the DPRC + * @options: Combination of 'DPRC_CFG_OPT_<X>' options + */ +struct dprc_cfg { + uint16_t icid; + int portal_id; + uint64_t options; +}; + +/** + * dprc_reset_container - Reset child container. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @child_container_id: ID of the container to reset + * + * In case a software context crashes or becomes non-responsive, the parent + * may wish to reset its resources container before the software context is + * restarted. + * + * This routine informs all objects assigned to the child container that the + * container is being reset, so they may perform any cleanup operations that are + * needed. All objects handles that were owned by the child container shall be + * closed. + * + * Note that such request may be submitted even if the child software context + * has not crashed, but the resulting object cleanup operations will not be + * aware of that. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_reset_container(struct fsl_mc_io *mc_io, + uint16_t token, + int child_container_id); + +/** + * struct dprc_attributes - Container attributes + * @container_id: Container's ID + * @icid: Container's ICID + * @portal_id: Container's portal ID + * @options: Container's options as set at container's creation + * @version: DPRC version + */ +struct dprc_attributes { + int container_id; + uint16_t icid; + int portal_id; + uint64_t options; + /** + * struct version - DPRC version + * @major: DPRC major version + * @minor: DPRC minor version + */ + struct { + uint16_t major; + uint16_t minor; + } version; +}; + +/** + * dprc_get_attributes() - Obtains container attributes + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @attributes Returned container attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_attributes(struct fsl_mc_io *mc_io, + uint16_t token, + struct dprc_attributes *attributes); + +/** + * dprc_get_obj_count() - Obtains the number of objects in the DPRC + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @obj_count: Number of objects assigned to the DPRC + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count); + +/* Objects Attributes Flags */ + +/* Opened state - Indicates that an object is open by at least one owner */ +#define DPRC_OBJ_STATE_OPEN 0x00000001 +/* Plugged state - Indicates that the object is plugged */ +#define DPRC_OBJ_STATE_PLUGGED 0x00000002 + +/** + * struct dprc_obj_desc - Object descriptor, returned from dprc_get_obj() + * @type: Type of object: NULL terminated string + * @id: ID of logical object resource + * @vendor: Object vendor identifier + * @ver_major: Major version number + * @ver_minor: Minor version number + * @irq_count: Number of interrupts supported by the object + * @region_count: Number of mappable regions supported by the object + * @state: Object state: combination of DPRC_OBJ_STATE_ states + */ +struct dprc_obj_desc { + char type[16]; + int id; + uint16_t vendor; + uint16_t ver_major; + uint16_t ver_minor; + uint8_t irq_count; + uint8_t region_count; + uint32_t state; +}; + +/** + * dprc_get_obj() - Get general information on an object + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @obj_index: Index of the object to be queried (< obj_count) + * @obj_desc: Returns the requested object descriptor + * + * The object descriptors are retrieved one by one by incrementing + * obj_index up to (not including) the value of obj_count returned + * from dprc_get_obj_count(). dprc_get_obj_count() must + * be called prior to dprc_get_obj(). + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_obj(struct fsl_mc_io *mc_io, + uint16_t token, + int obj_index, + struct dprc_obj_desc *obj_desc); + +/** + * dprc_get_res_count() - Obtains the number of free resources that are assigned + * to this container, by pool type + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @type: pool type + * @res_count: Returned number of free resources of the given + * resource type that are assigned to this DPRC + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_res_count(struct fsl_mc_io *mc_io, + uint16_t token, + char *type, + int *res_count); + +/** + * enum dprc_iter_status - Iteration status + * @DPRC_ITER_STATUS_FIRST: Perform first iteration + * @DPRC_ITER_STATUS_MORE: Indicates more/next iteration is needed + * @DPRC_ITER_STATUS_LAST: Indicates last iteration + */ +enum dprc_iter_status { + DPRC_ITER_STATUS_FIRST = 0, + DPRC_ITER_STATUS_MORE = 1, + DPRC_ITER_STATUS_LAST = 2 +}; + +/** + * struct dprc_res_ids_range_desc - Resource ID range descriptor + * @base_id: Base resource ID of this range + * @last_id: Last resource ID of this range + * @iter_status: Iteration status - should be set to DPRC_ITER_STATUS_FIRST at + * first iteration; while the returned marker is DPRC_ITER_STATUS_MORE, + * additional iterations are needed, until the returned marker is + * DPRC_ITER_STATUS_LAST + */ +struct dprc_res_ids_range_desc { + int base_id; + int last_id; + enum dprc_iter_status iter_status; +}; + +/** + * dprc_get_res_ids() - Obtains IDs of free resources in the container + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @type: pool type + * @range_desc: range descriptor + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_res_ids(struct fsl_mc_io *mc_io, + uint16_t token, + char *type, + struct dprc_res_ids_range_desc *range_desc); + +/** + * struct dprc_region_desc - Mappable region descriptor + * @base_paddr: Region base physical address + * @size: Region size (in bytes) + */ +struct dprc_region_desc { + uint64_t base_paddr; + uint32_t size; +}; + +/** + * dprc_get_obj_region() - Get region information for a specified object. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @obj_type; Object type as returned in dprc_get_obj() + * @obj_id: Unique object instance as returned in dprc_get_obj() + * @region_index: The specific region to query + * @region_desc: Returns the requested region descriptor + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_obj_region(struct fsl_mc_io *mc_io, + uint16_t token, + char *obj_type, + int obj_id, + uint8_t region_index, + struct dprc_region_desc *region_desc); +/** + * struct dprc_endpoint - Endpoint description for link connect/disconnect + * operations + * @type: Endpoint object type: NULL terminated string + * @id: Endpoint object ID + * @interface_id: Interface ID; should be set for endpoints with multiple + * interfaces ("dpsw", "dpdmux"); for others, always set to 0 + */ +struct dprc_endpoint { + char type[16]; + int id; + int interface_id; +}; + +/** + * dprc_connect() - Connect two endpoints to create a network link between them + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @endpoint1: Endpoint 1 configuration parameters + * @endpoint2: Endpoint 2 configuration parameters + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_connect(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint1, + const struct dprc_endpoint *endpoint2); + +/** + * dprc_disconnect() - Disconnect one endpoint to remove its network connection + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @endpoint: Endpoint configuration parameters + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_disconnect(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint); + +/** +* dprc_get_connection() - Get connected endpoint and link status if connection +* exists. +* @mc_io Pointer to MC portal's I/O object +* @token Token of DPRC object +* @endpoint1 Endpoint 1 configuration parameters +* @endpoint2 Returned endpoint 2 configuration parameters +* @state: Returned link state: 1 - link is up, 0 - link is down +* +* Return: '0' on Success; -ENAVAIL if connection does not exist. +*/ +int dprc_get_connection(struct fsl_mc_io *mc_io, + uint16_t token, + const struct dprc_endpoint *endpoint1, + struct dprc_endpoint *endpoint2, + int *state); + +#endif /* _FSL_DPRC_H */ diff --git a/include/fsl-mc/fsl_mc.h b/include/fsl-mc/fsl_mc.h index b9f089e..ec24415 100644 --- a/include/fsl-mc/fsl_mc.h +++ b/include/fsl-mc/fsl_mc.h @@ -53,7 +53,8 @@ struct mc_ccsr_registers { u32 reg_error[]; }; -int mc_init(bd_t *bis); - int get_mc_boot_status(void); +unsigned long mc_get_dram_block_size(void); +int fsl_mc_ldpaa_init(bd_t *bis); +void fsl_mc_ldpaa_exit(bd_t *bis); #endif diff --git a/include/fsl-mc/fsl_mc_cmd.h b/include/fsl-mc/fsl_mc_cmd.h index e7fcb5b..cb39c39 100644 --- a/include/fsl-mc/fsl_mc_cmd.h +++ b/include/fsl-mc/fsl_mc_cmd.h @@ -1,4 +1,4 @@ -/* Copyright 2014 Freescale Semiconductor Inc. +/* Copyright 2013-2015 Freescale Semiconductor Inc. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -41,9 +41,9 @@ enum mc_cmd_status { #define MC_CMD_HDR_CMDID_O 52 /* Command ID field offset */ #define MC_CMD_HDR_CMDID_S 12 /* Command ID field size */ -#define MC_CMD_HDR_AUTHID_O 38 /* Authentication ID field offset */ -#define MC_CMD_HDR_AUTHID_S 10 /* Authentication ID field size */ #define MC_CMD_HDR_STATUS_O 16 /* Status field offset */ +#define MC_CMD_HDR_TOKEN_O 38 /* Token field offset */ +#define MC_CMD_HDR_TOKEN_S 10 /* Token field size */ #define MC_CMD_HDR_STATUS_S 8 /* Status field size*/ #define MC_CMD_HDR_PRI_O 15 /* Priority field offset */ #define MC_CMD_HDR_PRI_S 1 /* Priority field size */ @@ -52,12 +52,15 @@ enum mc_cmd_status { ((enum mc_cmd_status)u64_dec((_hdr), \ MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S)) -#define MC_CMD_HDR_READ_AUTHID(_hdr) \ - ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S)) +#define MC_CMD_HDR_READ_TOKEN(_hdr) \ + ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S)) #define MC_CMD_PRI_LOW 0 /*!< Low Priority command indication */ #define MC_CMD_PRI_HIGH 1 /*!< High Priority command indication */ +#define MC_EXT_OP(_ext, _param, _offset, _width, _type, _arg) \ + ((_ext)[_param] |= u64_enc((_offset), (_width), _arg)) + #define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \ ((_cmd).params[_param] |= u64_enc((_offset), (_width), _arg)) @@ -66,12 +69,12 @@ enum mc_cmd_status { static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id, uint8_t priority, - uint16_t auth_id) + uint16_t token) { uint64_t hdr; hdr = u64_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id); - hdr |= u64_enc(MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S, auth_id); + hdr |= u64_enc(MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S, token); hdr |= u64_enc(MC_CMD_HDR_PRI_O, MC_CMD_HDR_PRI_S, priority); hdr |= u64_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S, MC_CMD_STATUS_READY); diff --git a/include/fsl-mc/fsl_mc_private.h b/include/fsl-mc/fsl_mc_private.h new file mode 100644 index 0000000..9f06978 --- /dev/null +++ b/include/fsl-mc/fsl_mc_private.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _FSL_MC_PRIVATE_H_ +#define _FSL_MC_PRIVATE_H_ + +#include <errno.h> +#include <malloc.h> +#include <asm/io.h> +#include <linux/compat.h> +#include <linux/types.h> +#include <linux/stringify.h> + +#include <fsl-mc/fsl_mc_sys.h> +#include <fsl-mc/fsl_mc_cmd.h> +#include <fsl-mc/fsl_dprc.h> +#include <fsl-mc/fsl_dpbp.h> + +extern struct fsl_mc_io *dflt_mc_io; + +/** + * struct dpbp_node - DPBP strucuture + * @uint16_t handle: DPBP object handle + * @int dpbp_id: DPBP id + */ +struct fsl_dpbp_obj { + uint16_t dpbp_handle; + struct dpbp_attr dpbp_attr; +}; + +extern struct fsl_dpbp_obj *dflt_dpbp; + +/** + * struct fsl_dpio_obj - DPIO strucuture + * @int dpio_id: DPIO id + * @struct qbman_swp *sw_portal: SW portal object + */ +struct fsl_dpio_obj { + int dpio_id; + struct qbman_swp *sw_portal; /** SW portal object */ +}; + +extern struct fsl_dpio_obj *dflt_dpio; + +int mc_init(void); +int ldpaa_eth_init(struct dprc_obj_desc obj_desc); +#endif /* _FSL_MC_PRIVATE_H_ */ diff --git a/include/fsl-mc/fsl_qbman_base.h b/include/fsl-mc/fsl_qbman_base.h new file mode 100644 index 0000000..c92cbe1 --- /dev/null +++ b/include/fsl-mc/fsl_qbman_base.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _FSL_QBMAN_BASE_H +#define _FSL_QBMAN_BASE_H + +/* Descriptor for a QBMan instance on the SoC. On partitions/targets that do not + * control this QBMan instance, these values may simply be place-holders. The + * idea is simply that we be able to distinguish between them, eg. so that SWP + * descriptors can identify which QBMan instance they belong to. */ +struct qbman_block_desc { + void *ccsr_reg_bar; /* CCSR register map */ + int irq_rerr; /* Recoverable error interrupt line */ + int irq_nrerr; /* Non-recoverable error interrupt line */ +}; + +/* Descriptor for a QBMan software portal, expressed in terms that make sense to + * the user context. Ie. on MC, this information is likely to be true-physical, + * and instantiated statically at compile-time. On GPP, this information is + * likely to be obtained via "discovery" over a partition's "layerscape bus" + * (ie. in response to a MC portal command), and would take into account any + * virtualisation of the GPP user's address space and/or interrupt numbering. */ +struct qbman_swp_desc { + const struct qbman_block_desc *block; /* The QBMan instance */ + void *cena_bar; /* Cache-enabled portal register map */ + void *cinh_bar; /* Cache-inhibited portal register map */ +}; + +/* Driver object for managing a QBMan portal */ +struct qbman_swp; + +/* Place-holder for FDs, we represent it via the simplest form that we need for + * now. Different overlays may be needed to support different options, etc. (It + * is impractical to define One True Struct, because the resulting encoding + * routines (lots of read-modify-writes) would be worst-case performance whether + * or not circumstances required them.) + * + * Note, as with all data-structures exchanged between software and hardware (be + * they located in the portal register map or DMA'd to and from main-memory), + * the driver ensures that the caller of the driver API sees the data-structures + * in host-endianness. "struct qbman_fd" is no exception. The 32-bit words + * contained within this structure are represented in host-endianness, even if + * hardware always treats them as little-endian. As such, if any of these fields + * are interpreted in a binary (rather than numerical) fashion by hardware + * blocks (eg. accelerators), then the user should be careful. We illustrate + * with an example; + * + * Suppose the desired behaviour of an accelerator is controlled by the "frc" + * field of the FDs that are sent to it. Suppose also that the behaviour desired + * by the user corresponds to an "frc" value which is expressed as the literal + * sequence of bytes 0xfe, 0xed, 0xab, and 0xba. So "frc" should be the 32-bit + * value in which 0xfe is the first byte and 0xba is the last byte, and as + * hardware is little-endian, this amounts to a 32-bit "value" of 0xbaabedfe. If + * the software is little-endian also, this can simply be achieved by setting + * frc=0xbaabedfe. On the other hand, if software is big-endian, it should set + * frc=0xfeedabba! The best away of avoiding trouble with this sort of thing is + * to treat the 32-bit words as numerical values, in which the offset of a field + * from the beginning of the first byte (as required or generated by hardware) + * is numerically encoded by a left-shift (ie. by raising the field to a + * corresponding power of 2). Ie. in the current example, software could set + * "frc" in the following way, and it would work correctly on both little-endian + * and big-endian operation; + * fd.frc = (0xfe << 0) | (0xed << 8) | (0xab << 16) | (0xba << 24); + */ +struct qbman_fd { + union { + uint32_t words[8]; + struct qbman_fd_simple { + uint32_t addr_lo; + uint32_t addr_hi; + uint32_t len; + /* offset in the MS 16 bits, BPID in the LS 16 bits */ + uint32_t bpid_offset; + uint32_t frc; /* frame context */ + /* "err", "va", "cbmt", "asal", [...] */ + uint32_t ctrl; + /* flow context */ + uint32_t flc_lo; + uint32_t flc_hi; + } simple; + }; +}; + +#endif /* !_FSL_QBMAN_BASE_H */ diff --git a/include/fsl-mc/fsl_qbman_portal.h b/include/fsl-mc/fsl_qbman_portal.h new file mode 100644 index 0000000..2aadad8 --- /dev/null +++ b/include/fsl-mc/fsl_qbman_portal.h @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _FSL_QBMAN_PORTAL_H +#define _FSL_QBMAN_PORTAL_H + +#include <fsl-mc/fsl_qbman_base.h> + +/* Create and destroy a functional object representing the given QBMan portal + * descriptor. */ +struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *); + + /************/ + /* Dequeues */ + /************/ + +/* See the QBMan driver API documentation for details on the enqueue + * mechanisms. NB: the use of a 'ldpaa_' prefix for this type is because it is + * primarily used by the "DPIO" layer that sits above (and hides) the QBMan + * driver. The structure is defined in the DPIO interface, but to avoid circular + * dependencies we just pre/re-declare it here opaquely. */ +struct ldpaa_dq; + + +/* ------------------- */ +/* Pull-mode dequeuing */ +/* ------------------- */ + +struct qbman_pull_desc { + uint32_t dont_manipulate_directly[6]; +}; + +/* Clear the contents of a descriptor to default/starting state. */ +void qbman_pull_desc_clear(struct qbman_pull_desc *); +/* If not called, or if called with 'storage' as NULL, the result pull dequeues + * will produce results to DQRR. If 'storage' is non-NULL, then results are + * produced to the given memory location (using the physical/DMA address which + * the caller provides in 'storage_phys'), and 'stash' controls whether or not + * those writes to main-memory express a cache-warming attribute. */ +void qbman_pull_desc_set_storage(struct qbman_pull_desc *, + struct ldpaa_dq *storage, + dma_addr_t storage_phys, + int stash); +/* numframes must be between 1 and 16, inclusive */ +void qbman_pull_desc_set_numframes(struct qbman_pull_desc *, uint8_t numframes); +/* token is the value that shows up in the dequeue results that can be used to + * detect when the results have been published, and is not really used when + * dequeue results go to DQRR. The easiest technique is to zero result "storage" + * before issuing a pull dequeue, and use any non-zero 'token' value. */ +void qbman_pull_desc_set_token(struct qbman_pull_desc *, uint8_t token); +/* Exactly one of the following descriptor "actions" should be set. (Calling any + * one of these will replace the effect of any prior call to one of these.) + * - pull dequeue from the given frame queue (FQ) + * - pull dequeue from any FQ in the given work queue (WQ) + * - pull dequeue from any FQ in any WQ in the given channel + */ +void qbman_pull_desc_set_fq(struct qbman_pull_desc *, uint32_t fqid); + +/* Issue the pull dequeue command */ +int qbman_swp_pull(struct qbman_swp *, struct qbman_pull_desc *); + +/* -------------------------------- */ +/* Polling DQRR for dequeue results */ +/* -------------------------------- */ + +/* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry + * only once, so repeated calls can return a sequence of DQRR entries, without + * requiring they be consumed immediately or in any particular order. */ +const struct ldpaa_dq *qbman_swp_dqrr_next(struct qbman_swp *); +/* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */ +void qbman_swp_dqrr_consume(struct qbman_swp *, const struct ldpaa_dq *); + +/* ------------------------------------------------- */ +/* Polling user-provided storage for dequeue results */ +/* ------------------------------------------------- */ + +/* Only used for user-provided storage of dequeue results, not DQRR. Prior to + * being used, the storage must set "oldtoken", so that the driver notices when + * hardware has filled it in with results using a "newtoken". NB, for efficiency + * purposes, the driver will perform any required endianness conversion to + * ensure that the user's dequeue result storage is in host-endian format + * (whether or not that is the same as the little-endian format that hardware + * DMA'd to the user's storage). As such, once the user has called + * qbman_dq_entry_has_newtoken() and been returned a valid dequeue result, they + * should not call it again on the same memory location (except of course if + * another dequeue command has been executed to produce a new result to that + * location). + */ +void qbman_dq_entry_set_oldtoken(struct ldpaa_dq *, + unsigned int num_entries, + uint8_t oldtoken); +int qbman_dq_entry_has_newtoken(struct qbman_swp *, + const struct ldpaa_dq *, + uint8_t newtoken); + +/* -------------------------------------------------------- */ +/* Parsing dequeue entries (DQRR and user-provided storage) */ +/* -------------------------------------------------------- */ + +/* DQRR entries may contain non-dequeue results, ie. notifications */ +int qbman_dq_entry_is_DQ(const struct ldpaa_dq *); + + /************/ + /* Enqueues */ + /************/ + +struct qbman_eq_desc { + uint32_t dont_manipulate_directly[8]; +}; + + +/* Clear the contents of a descriptor to default/starting state. */ +void qbman_eq_desc_clear(struct qbman_eq_desc *); +/* Exactly one of the following descriptor "actions" should be set. (Calling + * any one of these will replace the effect of any prior call to one of these.) + * - enqueue without order-restoration + * - enqueue with order-restoration + * - fill a hole in the order-restoration sequence, without any enqueue + * - advance NESN (Next Expected Sequence Number), without any enqueue + * 'respond_success' indicates whether an enqueue response should be DMA'd + * after success (otherwise a response is DMA'd only after failure). + * 'incomplete' indicates that other fragments of the same 'seqnum' are yet to + * be enqueued. + */ +void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *, int respond_success); +void qbman_eq_desc_set_response(struct qbman_eq_desc *, + dma_addr_t storage_phys, + int stash); +/* token is the value that shows up in an enqueue response that can be used to + * detect when the results have been published. The easiest technique is to zero + * result "storage" before issuing an enqueue, and use any non-zero 'token' + * value. */ +void qbman_eq_desc_set_token(struct qbman_eq_desc *, uint8_t token); +/* Exactly one of the following descriptor "targets" should be set. (Calling any + * one of these will replace the effect of any prior call to one of these.) + * - enqueue to a frame queue + * - enqueue to a queuing destination + * Note, that none of these will have any affect if the "action" type has been + * set to "orp_hole" or "orp_nesn". + */ +void qbman_eq_desc_set_fq(struct qbman_eq_desc *, uint32_t fqid); +void qbman_eq_desc_set_qd(struct qbman_eq_desc *, uint32_t qdid, + uint32_t qd_bin, uint32_t qd_prio); + +/* Issue an enqueue command. ('fd' should only be NULL if the "action" of the + * descriptor is "orp_hole" or "orp_nesn".) */ +int qbman_swp_enqueue(struct qbman_swp *, const struct qbman_eq_desc *, + const struct qbman_fd *fd); + + /*******************/ + /* Buffer releases */ + /*******************/ + +struct qbman_release_desc { + uint32_t dont_manipulate_directly[1]; +}; + +/* Clear the contents of a descriptor to default/starting state. */ +void qbman_release_desc_clear(struct qbman_release_desc *); +/* Set the ID of the buffer pool to release to */ +void qbman_release_desc_set_bpid(struct qbman_release_desc *, uint32_t bpid); +/* Issue a release command. 'num_buffers' must be less than 8. */ +int qbman_swp_release(struct qbman_swp *, const struct qbman_release_desc *, + const uint64_t *buffers, unsigned int num_buffers); + + /*******************/ + /* Buffer acquires */ + /*******************/ + +int qbman_swp_acquire(struct qbman_swp *, uint32_t bpid, uint64_t *buffers, + unsigned int num_buffers); +#endif /* !_FSL_QBMAN_PORTAL_H */ diff --git a/include/fsl-mc/ldpaa_wriop.h b/include/fsl-mc/ldpaa_wriop.h new file mode 100644 index 0000000..ca8e440 --- /dev/null +++ b/include/fsl-mc/ldpaa_wriop.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __LDPAA_WRIOP_H +#define __LDPAA_WRIOP_H + + #include <phy.h> + +enum wriop_port { + WRIOP1_DPMAC1 = 1, + WRIOP1_DPMAC2, + WRIOP1_DPMAC3, + WRIOP1_DPMAC4, + WRIOP1_DPMAC5, + WRIOP1_DPMAC6, + WRIOP1_DPMAC7, + WRIOP1_DPMAC8, + WRIOP1_DPMAC9, + WRIOP1_DPMAC10, + WRIOP1_DPMAC11, + WRIOP1_DPMAC12, + WRIOP1_DPMAC13, + WRIOP1_DPMAC14, + WRIOP1_DPMAC15, + WRIOP1_DPMAC16, + WRIOP1_DPMAC17, + WRIOP1_DPMAC18, + WRIOP1_DPMAC19, + WRIOP1_DPMAC20, + WRIOP1_DPMAC21, + WRIOP1_DPMAC22, + WRIOP1_DPMAC23, + WRIOP1_DPMAC24, + NUM_WRIOP_PORTS, +}; + +struct wriop_dpmac_info { + u8 enabled; + u8 id; + u8 phy_addr; + u8 board_mux; + void *phy_regs; + phy_interface_t enet_if; + struct phy_device *phydev; + struct mii_dev *bus; +}; + +extern struct wriop_dpmac_info dpmac_info[NUM_WRIOP_PORTS]; + +#define DEFAULT_WRIOP_MDIO1_NAME "FSL_MDIO0" +#define DEFAULT_WRIOP_MDIO2_NAME "FSL_MDIO1" + +void wriop_init_dpmac(int, int, int); +void wriop_disable_dpmac(int); +void wriop_enable_dpmac(int); +void wriop_set_mdio(int, struct mii_dev *); +struct mii_dev *wriop_get_mdio(int); +void wriop_set_phy_address(int, int); +int wriop_get_phy_address(int); +void wriop_set_phy_dev(int, struct phy_device *); +struct phy_device *wriop_get_phy_dev(int); +phy_interface_t wriop_get_enet_if(int); + +void wriop_dpmac_disable(int); +void wriop_dpmac_enable(int); +phy_interface_t wriop_dpmac_enet_if(int, int); +#endif /* __LDPAA_WRIOP_H */ diff --git a/include/fsl_ddr.h b/include/fsl_ddr.h index feccef9..4099a74 100644 --- a/include/fsl_ddr.h +++ b/include/fsl_ddr.h @@ -34,9 +34,7 @@ #define ddr_clrsetbits32(a, clear, set) clrsetbits_be32(a, clear, set) #endif -#define _DDR_ADDR CONFIG_SYS_FSL_DDR_ADDR - -u32 fsl_ddr_get_version(void); +u32 fsl_ddr_get_version(unsigned int ctrl_num); #if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM) /* diff --git a/include/fsl_ddr_sdram.h b/include/fsl_ddr_sdram.h index 095b33e..e5b6e03 100644 --- a/include/fsl_ddr_sdram.h +++ b/include/fsl_ddr_sdram.h @@ -155,6 +155,8 @@ typedef struct ddr4_spd_eeprom_s generic_spd_eeprom_t; #define MD_CNTL_CKE_CNTL_HIGH 0x00200000 #define MD_CNTL_WRCW 0x00080000 #define MD_CNTL_MD_VALUE(x) (x & 0x0000FFFF) +#define MD_CNTL_CS_SEL(x) (((x) & 0x7) << 28) +#define MD_CNTL_MD_SEL(x) (((x) & 0xf) << 24) /* DDR_CDR1 */ #define DDR_CDR1_DHC_EN 0x80000000 @@ -165,6 +167,7 @@ typedef struct ddr4_spd_eeprom_s generic_spd_eeprom_t; #define DDR_CDR2_ODT(x) (x & DDR_CDR2_ODT_MASK) #define DDR_CDR2_VREF_OVRD(x) (0x00008080 | ((((x) - 37) & 0x3F) << 8)) #define DDR_CDR2_VREF_TRAIN_EN 0x00000080 +#define DDR_CDR2_VREF_RANGE_2 0x00000040 #if (defined(CONFIG_SYS_FSL_DDR_VER) && \ (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7)) diff --git a/include/fsl_debug_server.h b/include/fsl_debug_server.h new file mode 100644 index 0000000..28d8adb --- /dev/null +++ b/include/fsl_debug_server.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_DBG_SERVER_H__ +#define __FSL_DBG_SERVER_H__ + +#include <asm/io.h> +#include <common.h> + +/* + * Define Debug Server firmware version information + */ + +/* Major version number: incremented on API compatibility changes */ +#define DEBUG_SERVER_VER_MAJOR 0 + +/* Minor version number: incremented on API additions (backward + * compatible); reset when major version is incremented. + */ +#define DEBUG_SERVER_VER_MINOR 1 + +#define DEBUG_SERVER_INIT_STATUS (1 << 0) +#define DEBUG_SERVER_INIT_STATUS_MASK (0x00000001) + +int debug_server_init(void); +unsigned long debug_server_get_dram_block_size(void); + +#endif /* __FSL_DBG_SERVER_H__ */ + diff --git a/include/fsl_dspi.h b/include/fsl_dspi.h new file mode 100644 index 0000000..b569b4d --- /dev/null +++ b/include/fsl_dspi.h @@ -0,0 +1,150 @@ +/* + * Freescale DSPI Module Defines + * + * Copyright (C) 2004-2007, 2015 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * Chao Fu (B44548@freesacle.com) + * Haikun Wang (B53464@freescale.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _FSL_DSPI_H_ +#define _FSL_DSPI_H_ + +/* DMA Serial Peripheral Interface (DSPI) */ +struct dspi { + u32 mcr; /* 0x00 */ + u32 resv0; /* 0x04 */ + u32 tcr; /* 0x08 */ + u32 ctar[8]; /* 0x0C - 0x28 */ + u32 sr; /* 0x2C */ + u32 irsr; /* 0x30 */ + u32 tfr; /* 0x34 - PUSHR */ + u32 rfr; /* 0x38 - POPR */ +#ifdef CONFIG_MCF547x_8x + u32 tfdr[4]; /* 0x3C */ + u8 resv2[0x30]; /* 0x40 */ + u32 rfdr[4]; /* 0x7C */ +#else + u32 tfdr[16]; /* 0x3C */ + u32 rfdr[16]; /* 0x7C */ +#endif +}; + +/* Module configuration */ +#define DSPI_MCR_MSTR 0x80000000 +#define DSPI_MCR_CSCK 0x40000000 +#define DSPI_MCR_DCONF(x) (((x) & 0x03) << 28) +#define DSPI_MCR_FRZ 0x08000000 +#define DSPI_MCR_MTFE 0x04000000 +#define DSPI_MCR_PCSSE 0x02000000 +#define DSPI_MCR_ROOE 0x01000000 +#define DSPI_MCR_PCSIS(x) (1 << (16 + (x))) +#define DSPI_MCR_PCSIS_MASK (0xff << 16) +#define DSPI_MCR_CSIS7 0x00800000 +#define DSPI_MCR_CSIS6 0x00400000 +#define DSPI_MCR_CSIS5 0x00200000 +#define DSPI_MCR_CSIS4 0x00100000 +#define DSPI_MCR_CSIS3 0x00080000 +#define DSPI_MCR_CSIS2 0x00040000 +#define DSPI_MCR_CSIS1 0x00020000 +#define DSPI_MCR_CSIS0 0x00010000 +#define DSPI_MCR_DOZE 0x00008000 +#define DSPI_MCR_MDIS 0x00004000 +#define DSPI_MCR_DTXF 0x00002000 +#define DSPI_MCR_DRXF 0x00001000 +#define DSPI_MCR_CTXF 0x00000800 +#define DSPI_MCR_CRXF 0x00000400 +#define DSPI_MCR_SMPL_PT(x) (((x) & 0x03) << 8) +#define DSPI_MCR_FCPCS 0x00000001 +#define DSPI_MCR_PES 0x00000001 +#define DSPI_MCR_HALT 0x00000001 + +/* Transfer count */ +#define DSPI_TCR_SPI_TCNT(x) (((x) & 0x0000FFFF) << 16) + +/* Clock and transfer attributes */ +#define DSPI_CTAR(x) (0x0c + (x * 4)) +#define DSPI_CTAR_DBR 0x80000000 +#define DSPI_CTAR_TRSZ(x) (((x) & 0x0F) << 27) +#define DSPI_CTAR_CPOL 0x04000000 +#define DSPI_CTAR_CPHA 0x02000000 +#define DSPI_CTAR_LSBFE 0x01000000 +#define DSPI_CTAR_PCSSCK(x) (((x) & 0x03) << 22) +#define DSPI_CTAR_PCSSCK_7CLK 0x00A00000 +#define DSPI_CTAR_PCSSCK_5CLK 0x00800000 +#define DSPI_CTAR_PCSSCK_3CLK 0x00400000 +#define DSPI_CTAR_PCSSCK_1CLK 0x00000000 +#define DSPI_CTAR_PASC(x) (((x) & 0x03) << 20) +#define DSPI_CTAR_PASC_7CLK 0x00300000 +#define DSPI_CTAR_PASC_5CLK 0x00200000 +#define DSPI_CTAR_PASC_3CLK 0x00100000 +#define DSPI_CTAR_PASC_1CLK 0x00000000 +#define DSPI_CTAR_PDT(x) (((x) & 0x03) << 18) +#define DSPI_CTAR_PDT_7CLK 0x000A0000 +#define DSPI_CTAR_PDT_5CLK 0x00080000 +#define DSPI_CTAR_PDT_3CLK 0x00040000 +#define DSPI_CTAR_PDT_1CLK 0x00000000 +#define DSPI_CTAR_PBR(x) (((x) & 0x03) << 16) +#define DSPI_CTAR_PBR_7CLK 0x00030000 +#define DSPI_CTAR_PBR_5CLK 0x00020000 +#define DSPI_CTAR_PBR_3CLK 0x00010000 +#define DSPI_CTAR_PBR_1CLK 0x00000000 +#define DSPI_CTAR_CSSCK(x) (((x) & 0x0F) << 12) +#define DSPI_CTAR_ASC(x) (((x) & 0x0F) << 8) +#define DSPI_CTAR_DT(x) (((x) & 0x0F) << 4) +#define DSPI_CTAR_BR(x) ((x) & 0x0F) + +/* Status */ +#define DSPI_SR_TCF 0x80000000 +#define DSPI_SR_TXRXS 0x40000000 +#define DSPI_SR_EOQF 0x10000000 +#define DSPI_SR_TFUF 0x08000000 +#define DSPI_SR_TFFF 0x02000000 +#define DSPI_SR_RFOF 0x00080000 +#define DSPI_SR_RFDF 0x00020000 +#define DSPI_SR_TXCTR(x) (((x) & 0x0000F000) >> 12) +#define DSPI_SR_TXPTR(x) (((x) & 0x00000F00) >> 8) +#define DSPI_SR_RXCTR(x) (((x) & 0x000000F0) >> 4) +#define DSPI_SR_RXPTR(x) ((x) & 0x0000000F) + +/* DMA/interrupt request selct and enable */ +#define DSPI_IRSR_TCFE 0x80000000 +#define DSPI_IRSR_EOQFE 0x10000000 +#define DSPI_IRSR_TFUFE 0x08000000 +#define DSPI_IRSR_TFFFE 0x02000000 +#define DSPI_IRSR_TFFFS 0x01000000 +#define DSPI_IRSR_RFOFE 0x00080000 +#define DSPI_IRSR_RFDFE 0x00020000 +#define DSPI_IRSR_RFDFS 0x00010000 + +/* Transfer control - 32-bit access */ +#define DSPI_TFR_PCS(x) (((1 << x) & 0x0000003f) << 16) +#define DSPI_TFR_CONT 0x80000000 +#define DSPI_TFR_CTAS(x) (((x) & 0x07) << 28) +#define DSPI_TFR_EOQ 0x08000000 +#define DSPI_TFR_CTCNT 0x04000000 +#define DSPI_TFR_CS7 0x00800000 +#define DSPI_TFR_CS6 0x00400000 +#define DSPI_TFR_CS5 0x00200000 +#define DSPI_TFR_CS4 0x00100000 +#define DSPI_TFR_CS3 0x00080000 +#define DSPI_TFR_CS2 0x00040000 +#define DSPI_TFR_CS1 0x00020000 +#define DSPI_TFR_CS0 0x00010000 + +/* Transfer Fifo */ +#define DSPI_TFR_TXDATA(x) ((x) & 0x0000FFFF) + +/* Bit definitions and macros for DRFR */ +#define DSPI_RFR_RXDATA(x) ((x) & 0x0000FFFF) + +/* Bit definitions and macros for DTFDR group */ +#define DSPI_TFDR_TXDATA(x) ((x) & 0x0000FFFF) +#define DSPI_TFDR_TXCMD(x) (((x) & 0x0000FFFF) << 16) + +/* Bit definitions and macros for DRFDR group */ +#define DSPI_RFDR_RXDATA(x) ((x) & 0x0000FFFF) + +#endif /* _FSL_DSPI_H_ */ diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h index 57295b4..41bf05b 100644 --- a/include/fsl_esdhc.h +++ b/include/fsl_esdhc.h @@ -158,7 +158,11 @@ #define ESDHC_VENDORSPEC_VSELECT 0x00000002 /* Use 1.8V */ struct fsl_esdhc_cfg { +#ifdef CONFIG_LS2085A + u64 esdhc_base; +#else u32 esdhc_base; +#endif u32 sdhc_clk; u8 max_bus_width; struct mmc_config cfg; diff --git a/include/fsl_ifc.h b/include/fsl_ifc.h index 11474b7..a7ddd5f 100644 --- a/include/fsl_ifc.h +++ b/include/fsl_ifc.h @@ -790,24 +790,36 @@ extern void print_ifc_regs(void); extern void init_early_memctl_regs(void); void init_final_memctl_regs(void); -#define IFC_BASE_ADDR ((struct fsl_ifc *)CONFIG_SYS_IFC_ADDR) - -#define get_ifc_cspr_ext(i) (ifc_in32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr_ext)) -#define get_ifc_cspr(i) (ifc_in32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr)) -#define get_ifc_csor_ext(i) (ifc_in32(&(IFC_BASE_ADDR)->csor_cs[i].csor_ext)) -#define get_ifc_csor(i) (ifc_in32(&(IFC_BASE_ADDR)->csor_cs[i].csor)) -#define get_ifc_amask(i) (ifc_in32(&(IFC_BASE_ADDR)->amask_cs[i].amask)) -#define get_ifc_ftim(i, j) (ifc_in32(&(IFC_BASE_ADDR)->ftim_cs[i].ftim[j])) - -#define set_ifc_cspr_ext(i, v) \ - (ifc_out32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr_ext, v)) -#define set_ifc_cspr(i, v) (ifc_out32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr, v)) -#define set_ifc_csor_ext(i, v) \ - (ifc_out32(&(IFC_BASE_ADDR)->csor_cs[i].csor_ext, v)) -#define set_ifc_csor(i, v) (ifc_out32(&(IFC_BASE_ADDR)->csor_cs[i].csor, v)) -#define set_ifc_amask(i, v) (ifc_out32(&(IFC_BASE_ADDR)->amask_cs[i].amask, v)) -#define set_ifc_ftim(i, j, v) \ - (ifc_out32(&(IFC_BASE_ADDR)->ftim_cs[i].ftim[j], v)) +#define IFC_RREGS_4KOFFSET (4*1024) +#define IFC_RREGS_64KOFFSET (64*1024) + +#define IFC_FCM_BASE_ADDR \ + ((struct fsl_ifc_fcm *)CONFIG_SYS_IFC_ADDR) + +#define get_ifc_cspr_ext(i) \ + (ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext)) +#define get_ifc_cspr(i) \ + (ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr)) +#define get_ifc_csor_ext(i) \ + (ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext)) +#define get_ifc_csor(i) \ + (ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor)) +#define get_ifc_amask(i) \ + (ifc_in32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask)) +#define get_ifc_ftim(i, j) \ + (ifc_in32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j])) +#define set_ifc_cspr_ext(i, v) \ + (ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext, v)) +#define set_ifc_cspr(i, v) \ + (ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr, v)) +#define set_ifc_csor_ext(i, v) \ + (ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext, v)) +#define set_ifc_csor(i, v) \ + (ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor, v)) +#define set_ifc_amask(i, v) \ + (ifc_out32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask, v)) +#define set_ifc_ftim(i, j, v) \ + (ifc_out32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j], v)) enum ifc_chip_sel { IFC_CS0, @@ -869,20 +881,26 @@ struct fsl_ifc_nand { u32 nand_evter_en; u32 res17[0x2]; u32 nand_evter_intr_en; - u32 res18[0x2]; + u32 nand_vol_addr_stat; + u32 res18; u32 nand_erattr0; u32 nand_erattr1; u32 res19[0x10]; u32 nand_fsr; - u32 res20; - u32 nand_eccstat[4]; - u32 res21[0x20]; + u32 res20[0x3]; + u32 nand_eccstat[6]; + u32 res21[0x1c]; u32 nanndcr; u32 res22[0x2]; u32 nand_autoboot_trgr; u32 res23; u32 nand_mdr; - u32 res24[0x5C]; + u32 res24[0x1c]; + u32 nand_dll_lowcfg0; + u32 nand_dll_lowcfg1; + u32 res25; + u32 nand_dll_lowstat; + u32 res26[0x3C]; }; /* @@ -917,7 +935,6 @@ struct fsl_ifc_gpcm { u32 gpcm_erattr1; u32 gpcm_erattr2; u32 gpcm_stat; - u32 res4[0x1F3]; }; #ifdef CONFIG_SYS_FSL_IFC_BANK_COUNT @@ -965,9 +982,11 @@ struct fsl_ifc_ftim { }; /* - * IFC Controller Registers + * IFC Controller Global Registers + * FCM - Flash control machine */ -struct fsl_ifc { + +struct fsl_ifc_fcm { u32 ifc_rev; u32 res1[0x2]; struct fsl_ifc_cspr cspr_cs[CONFIG_SYS_FSL_IFC_BANK_COUNT]; @@ -979,7 +998,8 @@ struct fsl_ifc { struct fsl_ifc_ftim ftim_cs[CONFIG_SYS_FSL_IFC_BANK_COUNT]; u8 res5[IFC_FTIM_REG_LEN - IFC_FTIM_USED_LEN]; u32 rb_stat; - u32 res6[0x2]; + u32 rb_map; + u32 wp_map; u32 ifc_gcr; u32 res7[0x2]; u32 cm_evter_stat; @@ -993,12 +1013,20 @@ struct fsl_ifc { u32 res11[0x2]; u32 ifc_ccr; u32 ifc_csr; - u32 res12[0x2EB]; + u32 ddr_ccr_low; +}; + +struct fsl_ifc_runtime { struct fsl_ifc_nand ifc_nand; struct fsl_ifc_nor ifc_nor; struct fsl_ifc_gpcm ifc_gpcm; }; +struct fsl_ifc { + struct fsl_ifc_fcm *gregs; + struct fsl_ifc_runtime *rregs; +}; + #ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A002769 #undef CSPR_MSEL_NOR #define CSPR_MSEL_NOR CSPR_MSEL_GPCM diff --git a/arch/powerpc/include/asm/fsl_memac.h b/include/fsl_memac.h index bed2a40..bed2a40 100644 --- a/arch/powerpc/include/asm/fsl_memac.h +++ b/include/fsl_memac.h diff --git a/include/fsl_usb.h b/include/fsl_usb.h index d251f5d..33d9f03 100644 --- a/include/fsl_usb.h +++ b/include/fsl_usb.h @@ -87,6 +87,33 @@ struct ccsr_usb_phy { /* USB Erratum Checking code */ #ifdef CONFIG_PPC +static inline bool has_dual_phy(void) +{ + u32 svr = get_svr(); + u32 soc = SVR_SOC_VER(svr); + + switch (soc) { + case SVR_T1023: + case SVR_T1024: + case SVR_T1013: + case SVR_T1014: + return IS_SVR_REV(svr, 1, 0); + case SVR_T1040: + case SVR_T1042: + case SVR_T1020: + case SVR_T1022: + case SVR_T2080: + case SVR_T2081: + return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 1, 1); + case SVR_T4240: + case SVR_T4160: + case SVR_T4080: + return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 2, 0); + } + + return false; +} + static inline bool has_erratum_a006261(void) { u32 svr = get_svr(); @@ -155,8 +182,13 @@ static inline bool has_erratum_a007792(void) case SVR_T4240: case SVR_T4160: return IS_SVR_REV(svr, 2, 0); - case SVR_T1040: + case SVR_T1024: + case SVR_T1023: return IS_SVR_REV(svr, 1, 0); + case SVR_T1040: + case SVR_T1042: + case SVR_T1020: + case SVR_T1022: case SVR_T2080: case SVR_T2081: return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 1, 1); @@ -164,7 +196,25 @@ static inline bool has_erratum_a007792(void) return false; } +static inline bool has_erratum_a005697(void) +{ + u32 svr = get_svr(); + u32 soc = SVR_SOC_VER(svr); + + switch (soc) { + case SVR_9131: + case SVR_9132: + return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 1, 1); + } + return false; +} + #else +static inline bool has_dual_phy(void) +{ + return false; +} + static inline bool has_erratum_a006261(void) { return false; @@ -184,5 +234,10 @@ static inline bool has_erratum_a007792(void) { return false; } + +static inline bool has_erratum_a005697(void) +{ + return false; +} #endif #endif /*_ASM_FSL_USB_H_ */ diff --git a/include/i2c.h b/include/i2c.h index 31b0389..6fd73fa 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -64,8 +64,8 @@ struct dm_i2c_chip { * bus can operate at different speeds (measured in Hz, typically 100KHz * or 400KHz). * - * To obtain this structure, use bus->uclass_priv where bus is the I2C - * bus udevice. + * To obtain this structure, use dev_get_uclass_priv(bus) where bus is the + * I2C bus udevice. * * @speed_hz: Bus speed in hertz (typically 100000) */ @@ -340,7 +340,7 @@ struct dm_i2c_ops { * The bus speed value will be updated by the uclass if this function * does not return an error. This method is optional - if it is not * provided then the driver can read the speed from - * bus->uclass_priv->speed_hz + * dev_get_uclass_priv(bus)->speed_hz * * @bus: Bus to adjust * @speed: Requested speed in Hz @@ -354,7 +354,7 @@ struct dm_i2c_ops { * Normally this can be provided by the uclass, but if you want your * driver to check the bus speed by looking at the hardware, you can * implement that here. This method is optional. This method would - * normally be expected to return bus->uclass_priv->speed_hz. + * normally be expected to return dev_get_uclass_priv(bus)->speed_hz. * * @bus: Bus to check * @return speed of selected I2C bus in Hz, -ve on error diff --git a/include/lcd.h b/include/lcd.h index f049fd3..59202b7 100644 --- a/include/lcd.h +++ b/include/lcd.h @@ -51,6 +51,7 @@ void lcd_set_flush_dcache(int flush); typedef struct vidinfo { ushort vl_col; /* Number of columns (i.e. 160) */ ushort vl_row; /* Number of rows (i.e. 100) */ + ushort vl_rot; /* Rotation of Display (0, 1, 2, 3) */ u_char vl_bpix; /* Bits per pixel, 0 = 1 */ ushort *cmap; /* Pointer to the colormap */ void *priv; /* Pointer to driver-specific data */ @@ -196,6 +197,14 @@ void lcd_sync(void); #define CONSOLE_COLOR_WHITE 0xffff /* Must remain last / highest */ #endif /* color definitions */ +#if LCD_BPP == LCD_COLOR16 +#define fbptr_t ushort +#elif LCD_BPP == LCD_COLOR32 +#define fbptr_t u32 +#else +#define fbptr_t uchar +#endif + #ifndef PAGE_SIZE #define PAGE_SIZE 4096 #endif diff --git a/include/lcd_console.h b/include/lcd_console.h index 429214d..2e0f56f 100644 --- a/include/lcd_console.h +++ b/include/lcd_console.h @@ -9,6 +9,26 @@ #define CONFIG_CONSOLE_SCROLL_LINES 1 #endif +struct console_t { + short curr_col, curr_row; + short cols, rows; + void *fbbase; + u32 lcdsizex, lcdsizey, lcdrot; + void (*fp_putc_xy)(struct console_t *pcons, ushort x, ushort y, char c); + void (*fp_console_moverow)(struct console_t *pcons, + u32 rowdst, u32 rowsrc); + void (*fp_console_setrow)(struct console_t *pcons, u32 row, int clr); +}; + +/** + * console_calc_rowcol() - calculate available rows / columns wihtin a given + * screen-size based on used VIDEO_FONT. + * + * @pcons: Pointer to struct console_t + * @sizex: size X of the screen in pixel + * @sizey: size Y of the screen in pixel + */ +void console_calc_rowcol(struct console_t *pcons, u32 sizex, u32 sizey); /** * lcd_init_console() - Initialize lcd console parameters * @@ -16,11 +36,11 @@ * console has. * * @address: Console base address - * @rows: Number of rows in the console - * @cols: Number of columns in the console + * @vl_rows: Number of rows in the console + * @vl_cols: Number of columns in the console + * @vl_rot: Rotation of display in degree (0 - 90 - 180 - 270) counterlockwise */ -void lcd_init_console(void *address, int rows, int cols); - +void lcd_init_console(void *address, int vl_cols, int vl_rows, int vl_rot); /** * lcd_set_col() - Set the number of the current lcd console column * diff --git a/include/linker_lists.h b/include/linker_lists.h index 940c871..b22d169 100644 --- a/include/linker_lists.h +++ b/include/linker_lists.h @@ -103,6 +103,16 @@ */ /** + * ll_sym() - Access a linker-generated array entry + * @_type: Data type of the entry + * @_name: Name of the entry + * @_list: name of the list. Should contain only characters allowed + * in a C variable name! + */ +#define llsym(_type, _name, _list) \ + ((_type *)&_u_boot_list_2_##_list##_2_##_name) + +/** * ll_entry_declare() - Declare linker-generated array entry * @_type: Data type of the entry * @_name: Name of the entry diff --git a/include/linux/immap_qe.h b/include/linux/immap_qe.h index b317dcb..6d1f88e 100644 --- a/include/linux/immap_qe.h +++ b/include/linux/immap_qe.h @@ -24,6 +24,18 @@ #endif #endif +#ifdef CONFIG_LS102XA +#define QE_MURAM_SIZE 0x6000UL +#define MAX_QE_RISC 1 +#define QE_NUM_OF_SNUM 28 +#endif + +#ifdef CONFIG_PPC +#define QE_IMMR_OFFSET 0x00140000 +#else +#define QE_IMMR_OFFSET 0x01400000 +#endif + /* QE I-RAM */ typedef struct qe_iram { u32 iadd; /* I-RAM Address Register */ diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h index bd48704..822fca0 100644 --- a/include/linux/usb/ch9.h +++ b/include/linux/usb/ch9.h @@ -379,6 +379,11 @@ struct usb_endpoint_descriptor { #define USB_DT_ENDPOINT_SIZE 7 #define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ +/* Used to access common fields */ +struct usb_generic_descriptor { + __u8 bLength; + __u8 bDescriptorType; +}; /* * Endpoints @@ -1002,4 +1007,17 @@ struct usb_set_sel_req { */ #define USB_SELF_POWER_VBUS_MAX_DRAW 100 +/** + * struct usb_string - wraps a C string and its USB id + * @id:the (nonzero) ID for this string + * @s:the string, in UTF-8 encoding + * + * If you're using usb_gadget_get_string(), use this to wrap a string + * together with its ID. + */ +struct usb_string { + u8 id; + const char *s; +}; + #endif /* __LINUX_USB_CH9_H */ diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 230f47d..4adf35e 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -859,19 +859,6 @@ void usb_del_gadget_udc(struct usb_gadget *gadget); /* utility to simplify dealing with string descriptors */ /** - * struct usb_string - wraps a C string and its USB id - * @id:the (nonzero) ID for this string - * @s:the string, in UTF-8 encoding - * - * If you're using usb_gadget_get_string(), use this to wrap a string - * together with its ID. - */ -struct usb_string { - u8 id; - const char *s; -}; - -/** * struct usb_gadget_strings - a set of USB strings in a given language * @language:identifies the strings' language (0x0409 for en-us) * @strings:array of strings with their ids diff --git a/include/malloc.h b/include/malloc.h index 5df6348..f4da9e6 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -906,6 +906,9 @@ void *realloc_simple(void *ptr, size_t size); #endif +/* Set up pre-relocation malloc() ready for use */ +int initf_malloc(void); + /* Public routines */ /* Simple versions which can be used when space is tight */ diff --git a/include/mapmem.h b/include/mapmem.h new file mode 100644 index 0000000..42ef3e8 --- /dev/null +++ b/include/mapmem.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015 National Instruments + * + * (C) Copyright 2015 + * Joe Hershberger <joe.hershberger@ni.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __MAPMEM_H +#define __MAPMEM_H + +/* Define a null map_sysmem() if the architecture doesn't use it */ +# ifdef CONFIG_ARCH_MAP_SYSMEM +#include <asm/io.h> +# else +static inline void *map_sysmem(phys_addr_t paddr, unsigned long len) +{ + return (void *)(uintptr_t)paddr; +} + +static inline void unmap_sysmem(const void *vaddr) +{ +} + +static inline phys_addr_t map_to_sysmem(const void *ptr) +{ + return (phys_addr_t)(uintptr_t)ptr; +} +# endif + +#endif /* __MAPMEM_H */ diff --git a/include/mpc823_lcd.h b/include/mpc823_lcd.h index 7e210e3..cc72cde 100644 --- a/include/mpc823_lcd.h +++ b/include/mpc823_lcd.h @@ -16,6 +16,7 @@ typedef struct vidinfo { ushort vl_col; /* Number of columns (i.e. 640) */ ushort vl_row; /* Number of rows (i.e. 480) */ + ushort vl_rot; /* Rotation of Display (0, 1, 2, 3) */ ushort vl_width; /* Width of display area in millimeters */ ushort vl_height; /* Height of display area in millimeters */ diff --git a/include/mpc85xx.h b/include/mpc85xx.h index 11d8985..3753e47 100644 --- a/include/mpc85xx.h +++ b/include/mpc85xx.h @@ -6,10 +6,6 @@ #ifndef __MPC85xx_H__ #define __MPC85xx_H__ -/* define for common ppc_asm.tmpl */ -#define EXC_OFF_SYS_RESET 0x100 /* System reset */ -#define _START_OFFSET 0 - #if defined(CONFIG_E500) #include <e500.h> #endif diff --git a/include/mvmfp.h b/include/mvmfp.h index 961d799..e61e92d 100644 --- a/include/mvmfp.h +++ b/include/mvmfp.h @@ -21,61 +21,77 @@ /* * MFP configuration is represented by a 32-bit unsigned integer */ -#define MFP(_off, _pull, _pF, _drv, _dF, _edge, _eF, _afn, _aF) ( \ +#ifdef CONFIG_MVMFP_V2 +#define MFP(_off, _pull, _drv, _slp, _edge, _sleep, _afn) ( \ + /* bits 31..16 - MFP Register Offset */ (((_off) & 0xffff) << 16) | \ + /* bits 15..13 - Run Mode Pull State */ (((_pull) & 0x7) << 13) | \ + /* bit 12..11 - Driver Strength */ (((_drv) & 0x3) << 11) | \ + /* bits 10 - pad driver */ (((_slp) & 0x1) << 10) | \ + /* bit 09..07 - sleep mode */ (((_sleep) & 0xe) << 6) | \ + /* bits 06..04 - Edge Detection */ (((_edge) & 0x7) << 4) | \ + /* bits 03 - sleep mode */ (((_sleep) & 0x1) << 3) | \ + /* bits 02..00 - Alt-fun select */ ((_afn) & 0x7)) +#else +#define MFP(_off, _pull, _drv, _slp, _edge, _sleep, _afn) ( \ /* bits 31..16 - MFP Register Offset */ (((_off) & 0xffff) << 16) | \ /* bits 15..13 - Run Mode Pull State */ (((_pull) & 0x7) << 13) | \ /* bit 12 - Unused */ \ /* bits 11..10 - Driver Strength */ (((_drv) & 0x3) << 10) | \ - /* bit 09 - Pull State flag */ (((_pF) & 0x1) << 9) | \ - /* bit 08 - Drv-strength flag */ (((_dF) & 0x1) << 8) | \ - /* bit 07 - Edge-det flag */ (((_eF) & 0x1) << 7) | \ + /* bit 09..07 - sleep mode */ (((_sleep) & 0xe) << 6) | \ /* bits 06..04 - Edge Detection */ (((_edge) & 0x7) << 4) | \ - /* bits 03..00 - Alt-fun flag */ (((_aF) & 0x1) << 3) | \ - /* bits Alternate-fun select */ ((_afn) & 0x7)) + /* bits 03 - sleep mode */ (((_sleep) & 0x1) << 3) | \ + /* bits 02..00 - Alt-fun select */ ((_afn) & 0x7)) +#endif /* * to facilitate the definition, the following macros are provided * * offset, pull,pF, drv,dF, edge,eF ,afn,aF */ -#define MFP_OFFSET_MASK MFP(0xffff, 0,0, 0,0, 0,0, 0,0) -#define MFP_REG(x) MFP(x, 0,0, 0,0, 0,0, 0,0) +#define MFP_OFFSET_MASK MFP(0xffff, 0, 0, 0, 0, 0, 0) +#define MFP_REG(x) MFP(x, 0, 0, 0, 0, 0, 0) #define MFP_REG_GET_OFFSET(x) ((x & MFP_OFFSET_MASK) >> 16) -#define MFP_AF_FLAG MFP(0x0000, 0,0, 0,0, 0,0, 0,1) -#define MFP_DRIVE_FLAG MFP(0x0000, 0,0, 0,1, 0,0, 0,0) -#define MFP_EDGE_FLAG MFP(0x0000, 0,0, 0,0, 0,1, 0,0) -#define MFP_PULL_FLAG MFP(0x0000, 0,1, 0,0, 0,0, 0,0) +#define MFP_AF0 MFP(0x0000, 0, 0, 0, 0, 0, 0) +#define MFP_AF1 MFP(0x0000, 0, 0, 0, 0, 0, 1) +#define MFP_AF2 MFP(0x0000, 0, 0, 0, 0, 0, 2) +#define MFP_AF3 MFP(0x0000, 0, 0, 0, 0, 0, 3) +#define MFP_AF4 MFP(0x0000, 0, 0, 0, 0, 0, 4) +#define MFP_AF5 MFP(0x0000, 0, 0, 0, 0, 0, 5) +#define MFP_AF6 MFP(0x0000, 0, 0, 0, 0, 0, 6) +#define MFP_AF7 MFP(0x0000, 0, 0, 0, 0, 0, 7) +#define MFP_AF_MASK MFP(0x0000, 0, 0, 0, 0, 0, 7) + +#define MFP_SLEEP_CTRL2 MFP(0x0000, 0, 0, 0, 0, 1, 0) +#define MFP_SLEEP_DIR MFP(0x0000, 0, 0, 0, 0, 2, 0) +#define MFP_SLEEP_DATA MFP(0x0000, 0, 0, 0, 0, 4, 0) +#define MFP_SLEEP_CTRL MFP(0x0000, 0, 0, 0, 0, 8, 0) +#define MFP_SLEEP_MASK MFP(0x0000, 0, 0, 0, 0, 0xf, 0) -#define MFP_AF0 MFP(0x0000, 0,0, 0,0, 0,0, 0,1) -#define MFP_AF1 MFP(0x0000, 0,0, 0,0, 0,0, 1,1) -#define MFP_AF2 MFP(0x0000, 0,0, 0,0, 0,0, 2,1) -#define MFP_AF3 MFP(0x0000, 0,0, 0,0, 0,0, 3,1) -#define MFP_AF4 MFP(0x0000, 0,0, 0,0, 0,0, 4,1) -#define MFP_AF5 MFP(0x0000, 0,0, 0,0, 0,0, 5,1) -#define MFP_AF6 MFP(0x0000, 0,0, 0,0, 0,0, 6,1) -#define MFP_AF7 MFP(0x0000, 0,0, 0,0, 0,0, 7,1) -#define MFP_AF_MASK MFP(0x0000, 0,0, 0,0, 0,0, 7,0) +#define MFP_LPM_EDGE_NONE MFP(0x0000, 0, 0, 0, 4, 0, 0) +#define MFP_LPM_EDGE_RISE MFP(0x0000, 0, 0, 0, 1, 0, 0) +#define MFP_LPM_EDGE_FALL MFP(0x0000, 0, 0, 0, 2, 0, 0) +#define MFP_LPM_EDGE_BOTH MFP(0x0000, 0, 0, 0, 3, 0, 0) +#define MFP_LPM_EDGE_MASK MFP(0x0000, 0, 0, 0, 7, 0, 0) -#define MFP_LPM_EDGE_NONE MFP(0x0000, 0,0, 0,0, 0,1, 0,0) -#define MFP_LPM_EDGE_RISE MFP(0x0000, 0,0, 0,0, 1,1, 0,0) -#define MFP_LPM_EDGE_FALL MFP(0x0000, 0,0, 0,0, 2,1, 0,0) -#define MFP_LPM_EDGE_BOTH MFP(0x0000, 0,0, 0,0, 3,1, 0,0) -#define MFP_LPM_EDGE_MASK MFP(0x0000, 0,0, 0,0, 3,0, 0,0) +#define MFP_SLP_DI MFP(0x0000, 0, 0, 1, 0, 0, 0) -#define MFP_DRIVE_VERY_SLOW MFP(0x0000, 0,0, 0,1, 0,0, 0,0) -#define MFP_DRIVE_SLOW MFP(0x0000, 0,0, 1,1, 0,0, 0,0) -#define MFP_DRIVE_MEDIUM MFP(0x0000, 0,0, 2,1, 0,0, 0,0) -#define MFP_DRIVE_FAST MFP(0x0000, 0,0, 3,1, 0,0, 0,0) -#define MFP_DRIVE_MASK MFP(0x0000, 0,0, 3,0, 0,0, 0,0) +#define MFP_DRIVE_VERY_SLOW MFP(0x0000, 0, 0, 0, 0, 0, 0) +#define MFP_DRIVE_SLOW MFP(0x0000, 0, 1, 0, 0, 0, 0) +#define MFP_DRIVE_MEDIUM MFP(0x0000, 0, 2, 0, 0, 0, 0) +#define MFP_DRIVE_FAST MFP(0x0000, 0, 3, 0, 0, 0, 0) +#define MFP_DRIVE_MASK MFP(0x0000, 0, 3, 0, 0, 0, 0) -#define MFP_PULL_NONE MFP(0x0000, 0,1, 0,0, 0,0, 0,0) -#define MFP_PULL_LOW MFP(0x0000, 1,1, 0,0, 0,0, 0,0) -#define MFP_PULL_HIGH MFP(0x0000, 2,1, 0,0, 0,0, 0,0) -#define MFP_PULL_BOTH MFP(0x0000, 3,1, 0,0, 0,0, 0,0) -#define MFP_PULL_FLOAT MFP(0x0000, 4,1, 0,0, 0,0, 0,0) -#define MFP_PULL_MASK MFP(0x0000, 7,0, 0,0, 0,0, 0,0) +#define MFP_PULL_NONE MFP(0x0000, 0, 0, 0, 0, 0, 0) +#define MFP_PULL_LOW MFP(0x0000, 5, 0, 0, 0, 0, 0) +#define MFP_PULL_HIGH MFP(0x0000, 6, 0, 0, 0, 0, 0) +#define MFP_PULL_BOTH MFP(0x0000, 7, 0, 0, 0, 0, 0) +#define MFP_PULL_FLOAT MFP(0x0000, 4, 0, 0, 0, 0, 0) +#define MFP_PULL_MASK MFP(0x0000, 7, 0, 0, 0, 0, 0) +#define MFP_VALUE_MASK (MFP_PULL_MASK | MFP_DRIVE_MASK | MFP_SLP_DI \ + | MFP_LPM_EDGE_MASK | MFP_SLEEP_MASK \ + | MFP_AF_MASK) #define MFP_EOC 0xffffffff /* indicates end-of-conf */ /* Functions */ diff --git a/include/net.h b/include/net.h index 237c932..d17173d 100644 --- a/include/net.h +++ b/include/net.h @@ -39,8 +39,9 @@ #define PKTALIGN ARCH_DMA_MINALIGN /* IPv4 addresses are always 32 bits in size */ -typedef __be32 IPaddr_t; - +struct in_addr { + __be32 s_addr; +}; /** * An incoming packet handler. @@ -51,7 +52,7 @@ typedef __be32 IPaddr_t; * @param len packet length */ typedef void rxhand_f(uchar *pkt, unsigned dport, - IPaddr_t sip, unsigned sport, + struct in_addr sip, unsigned sport, unsigned len); /** @@ -65,7 +66,7 @@ typedef void rxhand_f(uchar *pkt, unsigned dport, * @param len packet length */ typedef void rxhand_icmp_f(unsigned type, unsigned code, unsigned dport, - IPaddr_t sip, unsigned sport, uchar *pkt, unsigned len); + struct in_addr sip, unsigned sport, uchar *pkt, unsigned len); /* * A timeout handler. Called after time interval has expired. @@ -78,32 +79,94 @@ enum eth_state_t { ETH_STATE_ACTIVE }; +#ifdef CONFIG_DM_ETH +/** + * struct eth_pdata - Platform data for Ethernet MAC controllers + * + * @iobase: The base address of the hardware registers + * @enetaddr: The Ethernet MAC address that is loaded from EEPROM or env + * @phy_interface: PHY interface to use - see PHY_INTERFACE_MODE_... + */ +struct eth_pdata { + phys_addr_t iobase; + unsigned char enetaddr[6]; + int phy_interface; +}; + +/** + * struct eth_ops - functions of Ethernet MAC controllers + * + * start: Prepare the hardware to send and receive packets + * send: Send the bytes passed in "packet" as a packet on the wire + * recv: Check if the hardware received a packet. If so, set the pointer to the + * packet buffer in the packetp parameter. If not, return an error or 0 to + * indicate that the hardware receive FIFO is empty. If 0 is returned, the + * network stack will not process the empty packet, but free_pkt() will be + * called if supplied + * free_pkt: Give the driver an opportunity to manage its packet buffer memory + * when the network stack is finished processing it. This will only be + * called when no error was returned from recv - optional + * stop: Stop the hardware from looking for packets - may be called even if + * state == PASSIVE + * mcast: Join or leave a multicast group (for TFTP) - optional + * write_hwaddr: Write a MAC address to the hardware (used to pass it to Linux + * on some platforms like ARM). This function expects the + * eth_pdata::enetaddr field to be populated - optional + * read_rom_hwaddr: Some devices have a backup of the MAC address stored in a + * ROM on the board. This is how the driver should expose it + * to the network stack. This function should fill in the + * eth_pdata::enetaddr field - optional + */ +struct eth_ops { + int (*start)(struct udevice *dev); + int (*send)(struct udevice *dev, void *packet, int length); + int (*recv)(struct udevice *dev, uchar **packetp); + int (*free_pkt)(struct udevice *dev, uchar *packet, int length); + void (*stop)(struct udevice *dev); +#ifdef CONFIG_MCAST_TFTP + int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join); +#endif + int (*write_hwaddr)(struct udevice *dev); + int (*read_rom_hwaddr)(struct udevice *dev); +}; + +#define eth_get_ops(dev) ((struct eth_ops *)(dev)->driver->ops) + +struct udevice *eth_get_dev(void); /* get the current device */ +/* + * The devname can be either an exact name given by the driver or device tree + * or it can be an alias of the form "eth%d" + */ +struct udevice *eth_get_dev_by_name(const char *devname); +unsigned char *eth_get_ethaddr(void); /* get the current device MAC */ +/* Used only when NetConsole is enabled */ +int eth_init_state_only(void); /* Set active state */ +void eth_halt_state_only(void); /* Set passive state */ +#endif + +#ifndef CONFIG_DM_ETH struct eth_device { char name[16]; unsigned char enetaddr[6]; phys_addr_t iobase; int state; - int (*init) (struct eth_device *, bd_t *); - int (*send) (struct eth_device *, void *packet, int length); - int (*recv) (struct eth_device *); - void (*halt) (struct eth_device *); + int (*init)(struct eth_device *, bd_t *); + int (*send)(struct eth_device *, void *packet, int length); + int (*recv)(struct eth_device *); + void (*halt)(struct eth_device *); #ifdef CONFIG_MCAST_TFTP - int (*mcast) (struct eth_device *, const u8 *enetaddr, u8 set); + int (*mcast)(struct eth_device *, const u8 *enetaddr, u8 set); #endif - int (*write_hwaddr) (struct eth_device *); + int (*write_hwaddr)(struct eth_device *); struct eth_device *next; int index; void *priv; }; -extern int eth_initialize(bd_t *bis); /* Initialize network subsystem */ -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 */ +int eth_register(struct eth_device *dev);/* Register network device */ +int eth_unregister(struct eth_device *dev);/* Remove network device */ -/* get the current device MAC */ extern struct eth_device *eth_current; static inline __attribute__((always_inline)) @@ -111,39 +174,19 @@ struct eth_device *eth_get_dev(void) { 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 */ -extern void eth_parse_enetaddr(const char *addr, uchar *enetaddr); -extern int eth_getenv_enetaddr(char *name, uchar *enetaddr); -extern int eth_setenv_enetaddr(char *name, const uchar *enetaddr); +struct eth_device *eth_get_dev_by_name(const char *devname); +struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */ -/* - * Get the hardware address for an ethernet interface . - * Args: - * base_name - base name for device (normally "eth") - * index - device index number (0 for first) - * enetaddr - returns 6 byte hardware address - * Returns: - * Return true if the address is valid. - */ -extern int eth_getenv_enetaddr_by_index(const char *base_name, int index, - uchar *enetaddr); - -extern int usb_eth_initialize(bd_t *bi); -extern int eth_init(bd_t *bis); /* Initialize the device */ -extern int eth_send(void *packet, int length); /* Send a packet */ - -#ifdef CONFIG_API -extern int eth_receive(void *packet, int length); /* Receive a packet*/ -extern void (*push_packet)(void *packet, int length); -#endif -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 */ +/* get the current device MAC */ +static inline unsigned char *eth_get_ethaddr(void) +{ + if (eth_current) + return eth_current->enetaddr; + return NULL; +} /* Set active state */ -static inline __attribute__((always_inline)) int eth_init_state_only(bd_t *bis) +static inline __attribute__((always_inline)) int eth_init_state_only(void) { eth_get_dev()->state = ETH_STATE_ACTIVE; @@ -167,8 +210,43 @@ static inline __attribute__((always_inline)) void eth_halt_state_only(void) int eth_write_hwaddr(struct eth_device *dev, const char *base_name, int eth_number); +int usb_eth_initialize(bd_t *bi); +#endif + +int eth_initialize(void); /* Initialize network subsystem */ +void eth_try_another(int first_restart); /* Change the device */ +void eth_set_current(void); /* set nterface to ethcur var */ + +int eth_get_dev_index(void); /* get the device index */ +void eth_parse_enetaddr(const char *addr, uchar *enetaddr); +int eth_getenv_enetaddr(char *name, uchar *enetaddr); +int eth_setenv_enetaddr(char *name, const uchar *enetaddr); + +/* + * Get the hardware address for an ethernet interface . + * Args: + * base_name - base name for device (normally "eth") + * index - device index number (0 for first) + * enetaddr - returns 6 byte hardware address + * Returns: + * Return true if the address is valid. + */ +int eth_getenv_enetaddr_by_index(const char *base_name, int index, + uchar *enetaddr); + +int eth_init(void); /* Initialize the device */ +int eth_send(void *packet, int length); /* Send a packet */ + +#ifdef CONFIG_API +int eth_receive(void *packet, int length); /* Receive a packet*/ +extern void (*push_packet)(void *packet, int length); +#endif +int eth_rx(void); /* Check for received packets */ +void eth_halt(void); /* stop SCC */ +const char *eth_get_name(void); /* get name of current device */ + #ifdef CONFIG_MCAST_TFTP -int eth_mcast_join(IPaddr_t mcast_addr, u8 join); +int eth_mcast_join(struct in_addr mcast_addr, int join); u32 ether_crc(size_t len, unsigned char const *p); #endif @@ -183,9 +261,9 @@ u32 ether_crc(size_t len, unsigned char const *p); */ struct ethernet_hdr { - uchar et_dest[6]; /* Destination node */ - uchar et_src[6]; /* Source node */ - ushort et_protlen; /* Protocol or length */ + u8 et_dest[6]; /* Destination node */ + u8 et_src[6]; /* Source node */ + u16 et_protlen; /* Protocol or length */ }; /* Ethernet header size */ @@ -194,16 +272,16 @@ struct ethernet_hdr { #define ETH_FCS_LEN 4 /* Octets in the FCS */ struct e802_hdr { - uchar et_dest[6]; /* Destination node */ - uchar et_src[6]; /* Source node */ - ushort et_protlen; /* Protocol or length */ - uchar et_dsap; /* 802 DSAP */ - uchar et_ssap; /* 802 SSAP */ - uchar et_ctl; /* 802 control */ - uchar et_snap1; /* SNAP */ - uchar et_snap2; - uchar et_snap3; - ushort et_prot; /* 802 protocol */ + u8 et_dest[6]; /* Destination node */ + u8 et_src[6]; /* Source node */ + u16 et_protlen; /* Protocol or length */ + u8 et_dsap; /* 802 DSAP */ + u8 et_ssap; /* 802 SSAP */ + u8 et_ctl; /* 802 control */ + u8 et_snap1; /* SNAP */ + u8 et_snap2; + u8 et_snap3; + u16 et_prot; /* 802 protocol */ }; /* 802 + SNAP + ethernet header size */ @@ -213,11 +291,11 @@ struct e802_hdr { * Virtual LAN Ethernet header */ struct vlan_ethernet_hdr { - uchar vet_dest[6]; /* Destination node */ - uchar vet_src[6]; /* Source node */ - ushort vet_vlan_type; /* PROT_VLAN */ - ushort vet_tag; /* TAG of VLAN */ - ushort vet_type; /* protocol type */ + u8 vet_dest[6]; /* Destination node */ + u8 vet_src[6]; /* Source node */ + u16 vet_vlan_type; /* PROT_VLAN */ + u16 vet_tag; /* TAG of VLAN */ + u16 vet_type; /* protocol type */ }; /* VLAN Ethernet header size */ @@ -235,16 +313,16 @@ struct vlan_ethernet_hdr { * Internet Protocol (IP) header. */ struct ip_hdr { - uchar ip_hl_v; /* header length and version */ - uchar ip_tos; /* type of service */ - ushort ip_len; /* total length */ - ushort ip_id; /* identification */ - ushort ip_off; /* fragment offset field */ - uchar ip_ttl; /* time to live */ - uchar ip_p; /* protocol */ - ushort ip_sum; /* checksum */ - IPaddr_t ip_src; /* Source IP address */ - IPaddr_t ip_dst; /* Destination IP address */ + u8 ip_hl_v; /* header length and version */ + u8 ip_tos; /* type of service */ + u16 ip_len; /* total length */ + u16 ip_id; /* identification */ + u16 ip_off; /* fragment offset field */ + u8 ip_ttl; /* time to live */ + u8 ip_p; /* protocol */ + u16 ip_sum; /* checksum */ + struct in_addr ip_src; /* Source IP address */ + struct in_addr ip_dst; /* Destination IP address */ }; #define IP_OFFS 0x1fff /* ip offset *= 8 */ @@ -259,20 +337,20 @@ struct ip_hdr { * Internet Protocol (IP) + UDP header. */ struct ip_udp_hdr { - uchar ip_hl_v; /* header length and version */ - uchar ip_tos; /* type of service */ - ushort ip_len; /* total length */ - ushort ip_id; /* identification */ - ushort ip_off; /* fragment offset field */ - uchar ip_ttl; /* time to live */ - uchar ip_p; /* protocol */ - ushort ip_sum; /* checksum */ - IPaddr_t ip_src; /* Source IP address */ - IPaddr_t ip_dst; /* Destination IP address */ - ushort udp_src; /* UDP source port */ - ushort udp_dst; /* UDP destination port */ - ushort udp_len; /* Length of UDP packet */ - ushort udp_xsum; /* Checksum */ + u8 ip_hl_v; /* header length and version */ + u8 ip_tos; /* type of service */ + u16 ip_len; /* total length */ + u16 ip_id; /* identification */ + u16 ip_off; /* fragment offset field */ + u8 ip_ttl; /* time to live */ + u8 ip_p; /* protocol */ + u16 ip_sum; /* checksum */ + struct in_addr ip_src; /* Source IP address */ + struct in_addr ip_dst; /* Destination IP address */ + u16 udp_src; /* UDP source port */ + u16 udp_dst; /* UDP destination port */ + u16 udp_len; /* Length of UDP packet */ + u16 udp_xsum; /* Checksum */ }; #define IP_UDP_HDR_SIZE (sizeof(struct ip_udp_hdr)) @@ -282,14 +360,14 @@ struct ip_udp_hdr { * Address Resolution Protocol (ARP) header. */ struct arp_hdr { - ushort ar_hrd; /* Format of hardware address */ + u16 ar_hrd; /* Format of hardware address */ # define ARP_ETHER 1 /* Ethernet hardware address */ - ushort ar_pro; /* Format of protocol address */ - uchar ar_hln; /* Length of hardware address */ + u16 ar_pro; /* Format of protocol address */ + u8 ar_hln; /* Length of hardware address */ # define ARP_HLEN 6 - uchar ar_pln; /* Length of protocol address */ + u8 ar_pln; /* Length of protocol address */ # define ARP_PLEN 4 - ushort ar_op; /* Operation */ + u16 ar_op; /* Operation */ # define ARPOP_REQUEST 1 /* Request to resolve address */ # define ARPOP_REPLY 2 /* Response to previous request */ @@ -301,16 +379,16 @@ struct arp_hdr { * the sizes above, and are defined as appropriate for * specific hardware/protocol combinations. */ - uchar ar_data[0]; + u8 ar_data[0]; #define ar_sha ar_data[0] #define ar_spa ar_data[ARP_HLEN] #define ar_tha ar_data[ARP_HLEN + ARP_PLEN] #define ar_tpa ar_data[ARP_HLEN + ARP_PLEN + ARP_HLEN] #if 0 - uchar ar_sha[]; /* Sender hardware address */ - uchar ar_spa[]; /* Sender protocol address */ - uchar ar_tha[]; /* Target hardware address */ - uchar ar_tpa[]; /* Target protocol address */ + u8 ar_sha[]; /* Sender hardware address */ + u8 ar_spa[]; /* Sender protocol address */ + u8 ar_tha[]; /* Target hardware address */ + u8 ar_tpa[]; /* Target protocol address */ #endif /* 0 */ }; @@ -332,20 +410,20 @@ struct arp_hdr { #define ICMP_NOT_REACH_PORT 3 /* Port unreachable */ struct icmp_hdr { - uchar type; - uchar code; - ushort checksum; + u8 type; + u8 code; + u16 checksum; union { struct { - ushort id; - ushort sequence; + u16 id; + u16 sequence; } echo; - ulong gateway; + u32 gateway; struct { - ushort unused; - ushort mtu; + u16 unused; + u16 mtu; } frag; - uchar data[0]; + u8 data[0]; } un; }; @@ -383,105 +461,104 @@ struct icmp_hdr { * * Note: * - * All variables of type IPaddr_t are stored in NETWORK byte order + * All variables of type struct in_addr are stored in NETWORK byte order * (big endian). */ /* net.c */ /** BOOTP EXTENTIONS **/ -extern IPaddr_t NetOurGatewayIP; /* Our gateway IP address */ -extern IPaddr_t NetOurSubnetMask; /* Our subnet mask (0 = unknown) */ -extern IPaddr_t NetOurDNSIP; /* Our Domain Name Server (0 = unknown) */ +extern struct in_addr net_gateway; /* Our gateway IP address */ +extern struct in_addr net_netmask; /* Our subnet mask (0 = unknown) */ +/* Our Domain Name Server (0 = unknown) */ +extern struct in_addr net_dns_server; #if defined(CONFIG_BOOTP_DNS2) -extern IPaddr_t NetOurDNS2IP; /* Our 2nd Domain Name Server (0 = unknown) */ +/* Our 2nd Domain Name Server (0 = unknown) */ +extern struct in_addr net_dns_server2; #endif -extern char NetOurNISDomain[32]; /* Our NIS domain */ -extern char NetOurHostName[32]; /* Our hostname */ -extern char NetOurRootPath[64]; /* Our root path */ -extern ushort NetBootFileSize; /* Our boot file size in blocks */ +extern char net_nis_domain[32]; /* Our IS domain */ +extern char net_hostname[32]; /* Our hostname */ +extern char net_root_path[64]; /* Our root path */ /** END OF BOOTP EXTENTIONS **/ -extern ulong NetBootFileXferSize; /* size of bootfile in bytes */ -extern uchar NetOurEther[6]; /* Our ethernet address */ -extern uchar NetServerEther[6]; /* Boot server enet address */ -extern IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ -extern IPaddr_t NetServerIP; /* Server IP addr (0 = unknown) */ -extern uchar *NetTxPacket; /* THE transmit packet */ -extern uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets */ -extern uchar *NetRxPacket; /* Current receive packet */ -extern int NetRxPacketLen; /* Current rx packet length */ -extern unsigned NetIPID; /* IP ID (counting) */ -extern uchar NetBcastAddr[6]; /* Ethernet boardcast address */ -extern uchar NetEtherNullAddr[6]; +extern u8 net_ethaddr[6]; /* Our ethernet address */ +extern u8 net_server_ethaddr[6]; /* Boot server enet address */ +extern struct in_addr net_ip; /* Our IP addr (0 = unknown) */ +extern struct in_addr net_server_ip; /* Server IP addr (0 = unknown) */ +extern uchar *net_tx_packet; /* THE transmit packet */ +extern uchar *net_rx_packets[PKTBUFSRX]; /* Receive packets */ +extern uchar *net_rx_packet; /* Current receive packet */ +extern int net_rx_packet_len; /* Current rx packet length */ +extern const u8 net_bcast_ethaddr[6]; /* Ethernet broadcast address */ +extern const u8 net_null_ethaddr[6]; #define VLAN_NONE 4095 /* untagged */ #define VLAN_IDMASK 0x0fff /* mask of valid vlan id */ -extern ushort NetOurVLAN; /* Our VLAN */ -extern ushort NetOurNativeVLAN; /* Our Native VLAN */ +extern ushort net_our_vlan; /* Our VLAN */ +extern ushort net_native_vlan; /* Our Native VLAN */ -extern int NetRestartWrap; /* Tried all network devices */ +extern int net_restart_wrap; /* Tried all network devices */ enum proto_t { BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP, TFTPSRV, TFTPPUT, LINKLOCAL }; -/* from net/net.c */ -extern char BootFile[128]; /* Boot File name */ +extern char net_boot_file_name[128];/* Boot File name */ +/* The actual transferred size of the bootfile (in bytes) */ +extern u32 net_boot_file_size; +/* Boot file size in blocks as reported by the DHCP server */ +extern u32 net_boot_file_expected_size_in_blocks; #if defined(CONFIG_CMD_DNS) -extern char *NetDNSResolve; /* The host to resolve */ -extern char *NetDNSenvvar; /* the env var to put the ip into */ +extern char *net_dns_resolve; /* The host to resolve */ +extern char *net_dns_env_var; /* the env var to put the ip into */ #endif #if defined(CONFIG_CMD_PING) -extern IPaddr_t NetPingIP; /* the ip address to ping */ +extern struct in_addr net_ping_ip; /* the ip address to ping */ #endif #if defined(CONFIG_CMD_CDP) /* when CDP completes these hold the return values */ -extern ushort CDPNativeVLAN; /* CDP returned native VLAN */ -extern ushort CDPApplianceVLAN; /* CDP returned appliance VLAN */ +extern ushort cdp_native_vlan; /* CDP returned native VLAN */ +extern ushort cdp_appliance_vlan; /* CDP returned appliance VLAN */ /* * Check for a CDP packet by examining the received MAC address field */ -static inline int is_cdp_packet(const uchar *et_addr) +static inline int is_cdp_packet(const uchar *ethaddr) { - extern const uchar NetCDPAddr[6]; + extern const u8 net_cdp_ethaddr[6]; - return memcmp(et_addr, NetCDPAddr, 6) == 0; + return memcmp(ethaddr, net_cdp_ethaddr, 6) == 0; } #endif #if defined(CONFIG_CMD_SNTP) -extern IPaddr_t NetNtpServerIP; /* the ip address to NTP */ -extern int NetTimeOffset; /* offset time from UTC */ +extern struct in_addr net_ntp_server; /* the ip address to NTP */ +extern int net_ntp_time_offset; /* offset time from UTC */ #endif #if defined(CONFIG_MCAST_TFTP) -extern IPaddr_t Mcast_addr; +extern struct in_addr net_mcast_addr; #endif /* Initialize the network adapter */ -extern void net_init(void); -extern int NetLoop(enum proto_t); - -/* Shutdown adapters and cleanup */ -extern void NetStop(void); +void net_init(void); +int net_loop(enum proto_t); /* Load failed. Start again. */ -extern void NetStartAgain(void); +int net_start_again(void); /* Get size of the ethernet header when we send */ -extern int NetEthHdrSize(void); +int net_eth_hdr_size(void); /* Set ethernet header; returns the size of the header */ -extern int NetSetEther(uchar *, uchar *, uint); -extern int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot); +int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot); +int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot); /* Set IP header */ -extern void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source); -extern void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, +void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source); +void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport, int sport, int len); /** @@ -515,12 +592,12 @@ unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new_sum); int ip_checksum_ok(const void *addr, unsigned nbytes); /* Callbacks */ -extern rxhand_f *net_get_udp_handler(void); /* Get UDP RX packet handler */ -extern void net_set_udp_handler(rxhand_f *); /* Set UDP RX packet handler */ -extern rxhand_f *net_get_arp_handler(void); /* Get ARP RX packet handler */ -extern void net_set_arp_handler(rxhand_f *); /* Set ARP RX packet handler */ -extern void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */ -extern void NetSetTimeout(ulong, thand_f *);/* Set timeout handler */ +rxhand_f *net_get_udp_handler(void); /* Get UDP RX packet handler */ +void net_set_udp_handler(rxhand_f *); /* Set UDP RX packet handler */ +rxhand_f *net_get_arp_handler(void); /* Get ARP RX packet handler */ +void net_set_arp_handler(rxhand_f *); /* Set ARP RX packet handler */ +void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */ +void net_set_timeout_handler(ulong, thand_f *);/* Set timeout handler */ /* Network loop state */ enum net_loop_state { @@ -538,13 +615,14 @@ static inline void net_set_state(enum net_loop_state state) } /* Transmit a packet */ -static inline void NetSendPacket(uchar *pkt, int len) +static inline void net_send_packet(uchar *pkt, int len) { + /* Currently no way to return errors from eth_send() */ (void) eth_send(pkt, len); } /* - * Transmit "NetTxPacket" as UDP packet, performing ARP request if needed + * Transmit "net_tx_packet" as UDP packet, performing ARP request if needed * (ether will be populated) * * @param ether Raw packet buffer @@ -553,15 +631,15 @@ static inline void NetSendPacket(uchar *pkt, int len) * @param sport Source UDP port * @param payload_len Length of data after the UDP header */ -extern int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, +int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport, int payload_len); /* Processes a received packet */ -extern void NetReceive(uchar *, int); +void net_process_received_packet(uchar *in_packet, int len); #ifdef CONFIG_NETCONSOLE -void NcStart(void); -int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, +void nc_start(void); +int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port, unsigned src_port, unsigned len); #endif @@ -599,78 +677,78 @@ void net_auto_load(void); * footprint in our tests. */ /* return IP *in network byteorder* */ -static inline IPaddr_t NetReadIP(void *from) +static inline struct in_addr net_read_ip(void *from) { - IPaddr_t ip; + struct in_addr ip; memcpy((void *)&ip, (void *)from, sizeof(ip)); return ip; } /* return ulong *in network byteorder* */ -static inline ulong NetReadLong(ulong *from) +static inline u32 net_read_u32(u32 *from) { - ulong l; + u32 l; memcpy((void *)&l, (void *)from, sizeof(l)); return l; } /* write IP *in network byteorder* */ -static inline void NetWriteIP(void *to, IPaddr_t ip) +static inline void net_write_ip(void *to, struct in_addr ip) { memcpy(to, (void *)&ip, sizeof(ip)); } /* copy IP */ -static inline void NetCopyIP(void *to, void *from) +static inline void net_copy_ip(void *to, void *from) { - memcpy((void *)to, from, sizeof(IPaddr_t)); + memcpy((void *)to, from, sizeof(struct in_addr)); } /* copy ulong */ -static inline void NetCopyLong(ulong *to, ulong *from) +static inline void net_copy_u32(u32 *to, u32 *from) { - memcpy((void *)to, (void *)from, sizeof(ulong)); + memcpy((void *)to, (void *)from, sizeof(u32)); } /** - * is_zero_ether_addr - Determine if give Ethernet address is all zeros. + * is_zero_ethaddr - Determine if give Ethernet address is all zeros. * @addr: Pointer to a six-byte array containing the Ethernet address * * Return true if the address is all zeroes. */ -static inline int is_zero_ether_addr(const u8 *addr) +static inline int is_zero_ethaddr(const u8 *addr) { return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]); } /** - * is_multicast_ether_addr - Determine if the Ethernet address is a multicast. + * is_multicast_ethaddr - Determine if the Ethernet address is a multicast. * @addr: Pointer to a six-byte array containing the Ethernet address * * Return true if the address is a multicast address. * By definition the broadcast address is also a multicast address. */ -static inline int is_multicast_ether_addr(const u8 *addr) +static inline int is_multicast_ethaddr(const u8 *addr) { return 0x01 & addr[0]; } /* - * is_broadcast_ether_addr - Determine if the Ethernet address is broadcast + * is_broadcast_ethaddr - Determine if the Ethernet address is broadcast * @addr: Pointer to a six-byte array containing the Ethernet address * * Return true if the address is the broadcast address. */ -static inline int is_broadcast_ether_addr(const u8 *addr) +static inline int is_broadcast_ethaddr(const u8 *addr) { return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff; } /* - * is_valid_ether_addr - Determine if the given Ethernet address is valid + * is_valid_ethaddr - Determine if the given Ethernet address is valid * @addr: Pointer to a six-byte array containing the Ethernet address * * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not @@ -678,21 +756,21 @@ static inline int is_broadcast_ether_addr(const u8 *addr) * * Return true if the address is valid. */ -static inline int is_valid_ether_addr(const u8 *addr) +static inline int is_valid_ethaddr(const u8 *addr) { /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to * explicitly check for it here. */ - return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr); + return !is_multicast_ethaddr(addr) && !is_zero_ethaddr(addr); } /** - * eth_random_addr - Generate software assigned random Ethernet address + * net_random_ethaddr - Generate software assigned random Ethernet address * @addr: Pointer to a six-byte array containing the Ethernet address * * Generate a random Ethernet address (MAC) that is not multicast * and has the local assigned bit set. */ -static inline void eth_random_addr(uchar *addr) +static inline void net_random_ethaddr(uchar *addr) { int i; unsigned int seed = get_timer(0); @@ -705,28 +783,28 @@ static inline void eth_random_addr(uchar *addr) } /* Convert an IP address to a string */ -extern void ip_to_string(IPaddr_t x, char *s); +void ip_to_string(struct in_addr x, char *s); /* Convert a string to ip address */ -extern IPaddr_t string_to_ip(const char *s); +struct in_addr string_to_ip(const char *s); /* Convert a VLAN id to a string */ -extern void VLAN_to_string(ushort x, char *s); +void vlan_to_string(ushort x, char *s); /* Convert a string to a vlan id */ -extern ushort string_to_VLAN(const char *s); +ushort string_to_vlan(const char *s); /* read a VLAN id from an environment variable */ -extern ushort getenv_VLAN(char *); +ushort getenv_vlan(char *); /* copy a filename (allow for "..." notation, limit length) */ -extern void copy_filename(char *dst, const char *src, int size); +void copy_filename(char *dst, const char *src, int size); /* get a random source port */ -extern unsigned int random_port(void); +unsigned int random_port(void); /* Update U-Boot over TFTP */ -extern int update_tftp(ulong addr); +int update_tftp(ulong addr); /**********************************************************************/ diff --git a/include/os.h b/include/os.h index e3645e0..a758f09 100644 --- a/include/os.h +++ b/include/os.h @@ -64,7 +64,7 @@ off_t os_lseek(int fd, off_t offset, int whence); * Access to the OS open() system call * * \param pathname Pathname of file to open - * \param flags Flags, like O_RDONLY, O_RDWR + * \param flags Flags, like OS_O_RDONLY, OS_O_RDWR * \return file descriptor, or -1 on error */ int os_open(const char *pathname, int flags); diff --git a/include/pci.h b/include/pci.h index 004a048..07b1e9a 100644 --- a/include/pci.h +++ b/include/pci.h @@ -457,12 +457,15 @@ static inline void pci_set_region(struct pci_region *reg, typedef int pci_dev_t; -#define PCI_BUS(d) (((d) >> 16) & 0xff) -#define PCI_DEV(d) (((d) >> 11) & 0x1f) -#define PCI_FUNC(d) (((d) >> 8) & 0x7) -#define PCI_BDF(b,d,f) ((b) << 16 | (d) << 11 | (f) << 8) - -#define PCI_ANY_ID (~0) +#define PCI_BUS(d) (((d) >> 16) & 0xff) +#define PCI_DEV(d) (((d) >> 11) & 0x1f) +#define PCI_FUNC(d) (((d) >> 8) & 0x7) +#define PCI_DEVFN(d, f) ((d) << 11 | (f) << 8) +#define PCI_MASK_BUS(bdf) ((bdf) & 0xffff) +#define PCI_ADD_BUS(bus, devfn) (((bus) << 16) | (devfn)) +#define PCI_BDF(b, d, f) ((b) << 16 | PCI_DEVFN(d, f)) +#define PCI_VENDEV(v, d) (((v) << 16) | (d)) +#define PCI_ANY_ID (~0) struct pci_device_id { unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */ @@ -495,7 +498,12 @@ extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev * Structure of a PCI controller (host bridge) */ struct pci_controller { +#ifdef CONFIG_DM_PCI + struct udevice *bus; + struct udevice *ctlr; +#else struct pci_controller *next; +#endif int first_busno; int last_busno; @@ -511,7 +519,7 @@ struct pci_controller { struct pci_config_table *config_table; void (*fixup_irq)(struct pci_controller *, pci_dev_t); - +#ifndef CONFIG_DM_PCI /* Low-level architecture-dependent routines */ int (*read_byte)(struct pci_controller*, pci_dev_t, int where, u8 *); int (*read_word)(struct pci_controller*, pci_dev_t, int where, u16 *); @@ -519,17 +527,21 @@ struct pci_controller { int (*write_byte)(struct pci_controller*, pci_dev_t, int where, u8); int (*write_word)(struct pci_controller*, pci_dev_t, int where, u16); int (*write_dword)(struct pci_controller*, pci_dev_t, int where, u32); +#endif /* Used by auto config */ struct pci_region *pci_mem, *pci_io, *pci_prefetch; /* Used by ppc405 autoconfig*/ struct pci_region *pci_fb; +#ifndef CONFIG_DM_PCI int current_busno; void *priv_data; +#endif }; +#ifndef CONFIG_DM_PCI static inline void pci_set_ops(struct pci_controller *hose, int (*read_byte)(struct pci_controller*, pci_dev_t, int where, u8 *), @@ -550,6 +562,7 @@ static inline void pci_set_ops(struct pci_controller *hose, hose->write_word = write_word; hose->write_dword = write_dword; } +#endif #ifdef CONFIG_PCI_INDIRECT_BRIDGE extern void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data); @@ -602,12 +615,14 @@ extern int pci_hose_write_config_word(struct pci_controller *hose, extern int pci_hose_write_config_dword(struct pci_controller *hose, pci_dev_t dev, int where, u32 val); +#ifndef CONFIG_DM_PCI extern int pci_read_config_byte(pci_dev_t dev, int where, u8 *val); extern int pci_read_config_word(pci_dev_t dev, int where, u16 *val); extern int pci_read_config_dword(pci_dev_t dev, int where, u32 *val); extern int pci_write_config_byte(pci_dev_t dev, int where, u8 val); extern int pci_write_config_word(pci_dev_t dev, int where, u16 val); extern int pci_write_config_dword(pci_dev_t dev, int where, u32 val); +#endif extern int pci_hose_read_config_byte_via_dword(struct pci_controller *hose, pci_dev_t dev, int where, u8 *val); @@ -705,5 +720,387 @@ u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum); */ int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev); +/** + * pci_hose_find_devices() - Find devices by vendor/device ID + * + * @hose: PCI hose to search + * @busnum: Bus number to search + * @ids: PCI vendor/device IDs to look for, terminated by 0, 0 record + * @indexp: Pointer to device index to find. To find the first matching + * device, pass 0; to find the second, pass 1, etc. This + * parameter is decremented for each non-matching device so + * can be called repeatedly. + */ +pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum, + struct pci_device_id *ids, int *indexp); + +/* Access sizes for PCI reads and writes */ +enum pci_size_t { + PCI_SIZE_8, + PCI_SIZE_16, + PCI_SIZE_32, +}; + +struct udevice; + +#ifdef CONFIG_DM_PCI +/** + * struct pci_child_platdata - information stored about each PCI device + * + * Every device on a PCI bus has this per-child data. + * + * It can be accessed using dev_get_parentdata(dev) if dev->parent is a + * PCI bus (i.e. UCLASS_PCI) + * + * @devfn: Encoded device and function index - see PCI_DEVFN() + * @vendor: PCI vendor ID (see pci_ids.h) + * @device: PCI device ID (see pci_ids.h) + * @class: PCI class, 3 bytes: (base, sub, prog-if) + */ +struct pci_child_platdata { + int devfn; + unsigned short vendor; + unsigned short device; + unsigned int class; +}; + +/* PCI bus operations */ +struct dm_pci_ops { + /** + * read_config() - Read a PCI configuration value + * + * PCI buses must support reading and writing configuration values + * so that the bus can be scanned and its devices configured. + * + * Normally PCI_BUS(@bdf) is the same as @bus->seq, but not always. + * If bridges exist it is possible to use the top-level bus to + * access a sub-bus. In that case @bus will be the top-level bus + * and PCI_BUS(bdf) will be a different (higher) value + * + * @bus: Bus to read from + * @bdf: Bus, device and function to read + * @offset: Byte offset within the device's configuration space + * @valuep: Place to put the returned value + * @size: Access size + * @return 0 if OK, -ve on error + */ + int (*read_config)(struct udevice *bus, pci_dev_t bdf, uint offset, + ulong *valuep, enum pci_size_t size); + /** + * write_config() - Write a PCI configuration value + * + * @bus: Bus to write to + * @bdf: Bus, device and function to write + * @offset: Byte offset within the device's configuration space + * @value: Value to write + * @size: Access size + * @return 0 if OK, -ve on error + */ + int (*write_config)(struct udevice *bus, pci_dev_t bdf, uint offset, + ulong value, enum pci_size_t size); +}; + +/* Get access to a PCI bus' operations */ +#define pci_get_ops(dev) ((struct dm_pci_ops *)(dev)->driver->ops) + +/** + * pci_bind_bus_devices() - scan a PCI bus and bind devices + * + * Scan a PCI bus looking for devices. Bind each one that is found. If + * devices are already bound that match the scanned devices, just update the + * child data so that the device can be used correctly (this happens when + * the device tree describes devices we expect to see on the bus). + * + * Devices that are bound in this way will use a generic PCI driver which + * does nothing. The device can still be accessed but will not provide any + * driver interface. + * + * @bus: Bus containing devices to bind + * @return 0 if OK, -ve on error + */ +int pci_bind_bus_devices(struct udevice *bus); + +/** + * pci_auto_config_devices() - configure bus devices ready for use + * + * This works through all devices on a bus by scanning the driver model + * data structures (normally these have been set up by pci_bind_bus_devices() + * earlier). + * + * Space is allocated for each PCI base address register (BAR) so that the + * devices are mapped into memory and I/O space ready for use. + * + * @bus: Bus containing devices to bind + * @return 0 if OK, -ve on error + */ +int pci_auto_config_devices(struct udevice *bus); + +/** + * pci_bus_find_bdf() - Find a device given its PCI bus address + * + * @bdf: PCI device address: bus, device and function -see PCI_BDF() + * @devp: Returns the device for this address, if found + * @return 0 if OK, -ENODEV if not found + */ +int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp); + +/** + * pci_bus_find_devfn() - Find a device on a bus + * + * @find_devfn: PCI device address (device and function only) + * @devp: Returns the device for this address, if found + * @return 0 if OK, -ENODEV if not found + */ +int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn, + struct udevice **devp); + +/** + * pci_get_ff() - Returns a mask for the given access size + * + * @size: Access size + * @return 0xff for PCI_SIZE_8, 0xffff for PCI_SIZE_16, 0xffffffff for + * PCI_SIZE_32 + */ +int pci_get_ff(enum pci_size_t size); + +/** + * pci_bus_find_devices () - Find devices on a bus + * + * @bus: Bus to search + * @ids: PCI vendor/device IDs to look for, terminated by 0, 0 record + * @indexp: Pointer to device index to find. To find the first matching + * device, pass 0; to find the second, pass 1, etc. This + * parameter is decremented for each non-matching device so + * can be called repeatedly. + * @devp: Returns matching device if found + * @return 0 if found, -ENODEV if not + */ +int pci_bus_find_devices(struct udevice *bus, struct pci_device_id *ids, + int *indexp, struct udevice **devp); + +/** + * pci_find_device_id() - Find a device on any bus + * + * @ids: PCI vendor/device IDs to look for, terminated by 0, 0 record + * @index: Index number of device to find, 0 for the first match, 1 for + * the second, etc. + * @devp: Returns matching device if found + * @return 0 if found, -ENODEV if not + */ +int pci_find_device_id(struct pci_device_id *ids, int index, + struct udevice **devp); + +/** + * dm_pci_hose_probe_bus() - probe a subordinate bus, scanning it for devices + * + * This probes the given bus which causes it to be scanned for devices. The + * devices will be bound but not probed. + * + * @hose specifies the PCI hose that will be used for the scan. This is + * always a top-level bus with uclass UCLASS_PCI. The bus to scan is + * in @bdf, and is a subordinate bus reachable from @hose. + * + * @hose: PCI hose to scan + * @bdf: PCI bus address to scan (PCI_BUS(bdf) is the bus number) + * @return 0 if OK, -ve on error + */ +int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf); + +/** + * pci_bus_read_config() - Read a configuration value from a device + * + * TODO(sjg@chromium.org): We should be able to pass just a device and have + * it do the right thing. It would be good to have that function also. + * + * @bus: Bus to read from + * @bdf: PCI device address: bus, device and function -see PCI_BDF() + * @valuep: Place to put the returned value + * @size: Access size + * @return 0 if OK, -ve on error + */ +int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset, + unsigned long *valuep, enum pci_size_t size); + +/** + * pci_bus_write_config() - Write a configuration value to a device + * + * @bus: Bus to write from + * @bdf: PCI device address: bus, device and function -see PCI_BDF() + * @value: Value to write + * @size: Access size + * @return 0 if OK, -ve on error + */ +int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset, + unsigned long value, enum pci_size_t size); + +/* + * The following functions provide access to the above without needing the + * size parameter. We are trying to encourage the use of the 8/16/32-style + * functions, rather than byte/word/dword. But both are supported. + */ +int pci_write_config32(pci_dev_t pcidev, int offset, u32 value); + +/* Compatibility with old naming */ +static inline int pci_write_config_dword(pci_dev_t pcidev, int offset, + u32 value) +{ + return pci_write_config32(pcidev, offset, value); +} + +int pci_write_config16(pci_dev_t pcidev, int offset, u16 value); + +/* Compatibility with old naming */ +static inline int pci_write_config_word(pci_dev_t pcidev, int offset, + u16 value) +{ + return pci_write_config16(pcidev, offset, value); +} + +int pci_write_config8(pci_dev_t pcidev, int offset, u8 value); + +/* Compatibility with old naming */ +static inline int pci_write_config_byte(pci_dev_t pcidev, int offset, + u8 value) +{ + return pci_write_config8(pcidev, offset, value); +} + +int pci_read_config32(pci_dev_t pcidev, int offset, u32 *valuep); + +/* Compatibility with old naming */ +static inline int pci_read_config_dword(pci_dev_t pcidev, int offset, + u32 *valuep) +{ + return pci_read_config32(pcidev, offset, valuep); +} + +int pci_read_config16(pci_dev_t pcidev, int offset, u16 *valuep); + +/* Compatibility with old naming */ +static inline int pci_read_config_word(pci_dev_t pcidev, int offset, + u16 *valuep) +{ + return pci_read_config16(pcidev, offset, valuep); +} + +int pci_read_config8(pci_dev_t pcidev, int offset, u8 *valuep); + +/* Compatibility with old naming */ +static inline int pci_read_config_byte(pci_dev_t pcidev, int offset, + u8 *valuep) +{ + return pci_read_config8(pcidev, offset, valuep); +} + +/** + * struct dm_pci_emul_ops - PCI device emulator operations + */ +struct dm_pci_emul_ops { + /** + * get_devfn(): Check which device and function this emulators + * + * @dev: device to check + * @return the device and function this emulates, or -ve on error + */ + int (*get_devfn)(struct udevice *dev); + /** + * read_config() - Read a PCI configuration value + * + * @dev: Emulated device to read from + * @offset: Byte offset within the device's configuration space + * @valuep: Place to put the returned value + * @size: Access size + * @return 0 if OK, -ve on error + */ + int (*read_config)(struct udevice *dev, uint offset, ulong *valuep, + enum pci_size_t size); + /** + * write_config() - Write a PCI configuration value + * + * @dev: Emulated device to write to + * @offset: Byte offset within the device's configuration space + * @value: Value to write + * @size: Access size + * @return 0 if OK, -ve on error + */ + int (*write_config)(struct udevice *dev, uint offset, ulong value, + enum pci_size_t size); + /** + * read_io() - Read a PCI I/O value + * + * @dev: Emulated device to read from + * @addr: I/O address to read + * @valuep: Place to put the returned value + * @size: Access size + * @return 0 if OK, -ENOENT if @addr is not mapped by this device, + * other -ve value on error + */ + int (*read_io)(struct udevice *dev, unsigned int addr, ulong *valuep, + enum pci_size_t size); + /** + * write_io() - Write a PCI I/O value + * + * @dev: Emulated device to write from + * @addr: I/O address to write + * @value: Value to write + * @size: Access size + * @return 0 if OK, -ENOENT if @addr is not mapped by this device, + * other -ve value on error + */ + int (*write_io)(struct udevice *dev, unsigned int addr, + ulong value, enum pci_size_t size); + /** + * map_physmem() - Map a device into sandbox memory + * + * @dev: Emulated device to map + * @addr: Memory address, normally corresponding to a PCI BAR. + * The device should have been configured to have a BAR + * at this address. + * @lenp: On entry, the size of the area to map, On exit it is + * updated to the size actually mapped, which may be less + * if the device has less space + * @ptrp: Returns a pointer to the mapped address. The device's + * space can be accessed as @lenp bytes starting here + * @return 0 if OK, -ENOENT if @addr is not mapped by this device, + * other -ve value on error + */ + int (*map_physmem)(struct udevice *dev, phys_addr_t addr, + unsigned long *lenp, void **ptrp); + /** + * unmap_physmem() - undo a memory mapping + * + * This must be called after map_physmem() to undo the mapping. + * Some devices can use this to check what has been written into + * their mapped memory and perform an operations they require on it. + * In this way, map/unmap can be used as a sort of handshake between + * the emulated device and its users. + * + * @dev: Emuated device to unmap + * @vaddr: Mapped memory address, as passed to map_physmem() + * @len: Size of area mapped, as returned by map_physmem() + * @return 0 if OK, -ve on error + */ + int (*unmap_physmem)(struct udevice *dev, const void *vaddr, + unsigned long len); +}; + +/* Get access to a PCI device emulator's operations */ +#define pci_get_emul_ops(dev) ((struct dm_pci_emul_ops *)(dev)->driver->ops) + +/** + * sandbox_pci_get_emul() - Get the emulation device for a PCI device + * + * Searches for a suitable emulator for the given PCI bus device + * + * @bus: PCI bus to search + * @find_devfn: PCI device and function address (PCI_DEVFN()) + * @emulp: Returns emulated device if found + * @return 0 if found, -ENODEV if not found + */ +int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, + struct udevice **emulp); + +#endif + #endif /* __ASSEMBLY__ */ #endif /* _PCI_H */ diff --git a/include/pci_ids.h b/include/pci_ids.h index dc2ca21..2e66851 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -3016,6 +3016,8 @@ #define PCI_DEVICE_ID_INTEL_TCF_UART_2 0x8813 #define PCI_DEVICE_ID_INTEL_TCF_UART_3 0x8814 #define PCI_DEVICE_ID_INTEL_IXP2800 0x9004 +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_AHCI 0x9c03 +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LPC 0x9c45 #define PCI_DEVICE_ID_INTEL_S21152BB 0xb152 #define PCI_VENDOR_ID_SCALEMP 0x8686 diff --git a/include/phy.h b/include/phy.h index d117fc1..3f826b6 100644 --- a/include/phy.h +++ b/include/phy.h @@ -51,7 +51,9 @@ typedef enum { PHY_INTERFACE_MODE_RGMII_TXID, PHY_INTERFACE_MODE_RTBI, PHY_INTERFACE_MODE_XGMII, - PHY_INTERFACE_MODE_NONE /* Must be last */ + PHY_INTERFACE_MODE_NONE, /* Must be last */ + + PHY_INTERFACE_MODE_COUNT, } phy_interface_t; static const char *phy_interface_strings[] = { @@ -142,7 +144,11 @@ struct phy_device { struct phy_driver *drv; void *priv; +#ifdef CONFIG_DM_ETH + struct udevice *dev; +#else struct eth_device *dev; +#endif /* forced speed & duplex (no autoneg) * partner speed & duplex & pause (autoneg) @@ -205,10 +211,17 @@ int phy_init(void); int phy_reset(struct phy_device *phydev); struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask, phy_interface_t interface); +#ifdef CONFIG_DM_ETH +void phy_connect_dev(struct phy_device *phydev, struct udevice *dev); +struct phy_device *phy_connect(struct mii_dev *bus, int addr, + struct udevice *dev, + phy_interface_t interface); +#else void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev); struct phy_device *phy_connect(struct mii_dev *bus, int addr, struct eth_device *dev, phy_interface_t interface); +#endif int phy_startup(struct phy_device *phydev); int phy_config(struct phy_device *phydev); int phy_shutdown(struct phy_device *phydev); @@ -241,6 +254,15 @@ int phy_teranetics_init(void); int phy_vitesse_init(void); int board_phy_config(struct phy_device *phydev); +int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id); + +/** + * phy_get_interface_by_name() - Look up a PHY interface name + * + * @str: PHY interface name, e.g. "mii" + * @return PHY_INTERFACE_MODE_... value, or -1 if not found + */ +int phy_get_interface_by_name(const char *str); /* PHY UIDs for various PHYs that are referenced in external code */ #define PHY_UID_CS4340 0x13e51002 diff --git a/include/power/pfuze100_pmic.h b/include/power/pfuze100_pmic.h index 07199b4..8e7a22d 100644 --- a/include/power/pfuze100_pmic.h +++ b/include/power/pfuze100_pmic.h @@ -180,7 +180,7 @@ enum { #define LDOB_3_30V 15 #define LDO_VOL_MASK 0xf -#define LDO_EN 4 +#define LDO_EN (1 << 4) /* * Boost Regulator diff --git a/include/ppc_asm.tmpl b/include/ppc_asm.tmpl index 36d5975..ba166eb 100644 --- a/include/ppc_asm.tmpl +++ b/include/ppc_asm.tmpl @@ -12,6 +12,8 @@ #ifndef __PPC_ASM_TMPL__ #define __PPC_ASM_TMPL__ +#include <config.h> + /*************************************************************************** * * These definitions simplify the ugly declarations necessary for GOT @@ -243,6 +245,45 @@ */ #define COPY_EE(d, s) rlwimi d,s,0,16,16 #define NOCOPY(d, s) + +#ifdef CONFIG_E500 +#define EXC_XFER_TEMPLATE(n, label, hdlr, msr, copyee) \ + stw r22,_NIP(r21); \ + stw r23,_MSR(r21); \ + li r23,n; \ + stw r23,TRAP(r21); \ + li r20,msr; \ + copyee(r20,r23); \ + rlwimi r20,r23,0,25,25; \ + mtmsr r20; \ + bl 1f; \ +1: mflr r23; \ + addis r23,r23,(hdlr - 1b)@ha; \ + addi r23,r23,(hdlr - 1b)@l; \ + b transfer_to_handler + +#define STD_EXCEPTION(n, label, hdlr) \ +label: \ + EXCEPTION_PROLOG(SRR0, SRR1); \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + EXC_XFER_TEMPLATE(n, label, hdlr, MSR_KERNEL, NOCOPY) \ + +#define CRIT_EXCEPTION(n, label, hdlr) \ +label: \ + EXCEPTION_PROLOG(CSRR0, CSRR1); \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + EXC_XFER_TEMPLATE(n, label, hdlr, \ + MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE), NOCOPY) \ + +#define MCK_EXCEPTION(n, label, hdlr) \ +label: \ + EXCEPTION_PROLOG(MCSRR0, MCSRR1); \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + EXC_XFER_TEMPLATE(n, label, hdlr, \ + MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE), NOCOPY) \ + +#else /* !E500 */ + #define EXC_XFER_TEMPLATE(label, hdlr, msr, copyee) \ bl 1f; \ 1: mflr r20; \ @@ -280,4 +321,5 @@ label: \ EXC_XFER_TEMPLATE(label, hdlr, \ MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE), NOCOPY) \ +#endif /* !E500 */ #endif /* __PPC_ASM_TMPL__ */ diff --git a/include/pxa_lcd.h b/include/pxa_lcd.h index 723f6ab..1ea3717 100644 --- a/include/pxa_lcd.h +++ b/include/pxa_lcd.h @@ -48,6 +48,7 @@ struct pxafb_info { typedef struct vidinfo { ushort vl_col; /* Number of columns (i.e. 640) */ ushort vl_row; /* Number of rows (i.e. 480) */ + ushort vl_rot; /* Rotation of Display (0, 1, 2, 3) */ ushort vl_width; /* Width of display area in millimeters */ ushort vl_height; /* Height of display area in millimeters */ diff --git a/include/spi.h b/include/spi.h index c58e453..9495ca5 100644 --- a/include/spi.h +++ b/include/spi.h @@ -38,11 +38,12 @@ /* SPI RX operation modes */ #define SPI_OPM_RX_AS (1 << 0) -#define SPI_OPM_RX_DOUT (1 << 1) -#define SPI_OPM_RX_DIO (1 << 2) -#define SPI_OPM_RX_QOF (1 << 3) -#define SPI_OPM_RX_QIOF (1 << 4) -#define SPI_OPM_RX_EXTN (SPI_OPM_RX_AS | SPI_OPM_RX_DOUT | \ +#define SPI_OPM_RX_AF (1 << 1) +#define SPI_OPM_RX_DOUT (1 << 2) +#define SPI_OPM_RX_DIO (1 << 3) +#define SPI_OPM_RX_QOF (1 << 4) +#define SPI_OPM_RX_QIOF (1 << 5) +#define SPI_OPM_RX_EXTN (SPI_OPM_RX_AS | SPI_OPM_RX_AF | SPI_OPM_RX_DOUT | \ SPI_OPM_RX_DIO | SPI_OPM_RX_QOF | \ SPI_OPM_RX_QIOF) @@ -385,12 +386,12 @@ struct dm_spi_ops { * allowed to claim the same bus for several slaves without releasing * the bus in between. * - * @bus: The SPI slave + * @dev: The SPI slave * * Returns: 0 if the bus was claimed successfully, or a negative value * if it wasn't. */ - int (*claim_bus)(struct udevice *bus); + int (*claim_bus)(struct udevice *dev); /** * Release the SPI bus @@ -399,9 +400,9 @@ struct dm_spi_ops { * all transfers have finished. It may disable any SPI hardware as * appropriate. * - * @bus: The SPI slave + * @dev: The SPI slave */ - int (*release_bus)(struct udevice *bus); + int (*release_bus)(struct udevice *dev); /** * Set the word length for SPI transactions @@ -413,7 +414,7 @@ struct dm_spi_ops { * * Returns: 0 on success, -ve on failure. */ - int (*set_wordlen)(struct udevice *bus, unsigned int wordlen); + int (*set_wordlen)(struct udevice *dev, unsigned int wordlen); /** * SPI transfer diff --git a/include/spi_flash.h b/include/spi_flash.h index 5913b39..f2814ef 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -62,11 +62,10 @@ struct spi_slave; * return 0 - Success, 1 - Failure */ struct spi_flash { -#ifdef CONFIG_DM_SPI_FLASH struct spi_slave *spi; +#ifdef CONFIG_DM_SPI_FLASH struct udevice *dev; -#else - struct spi_slave *spi; + u16 flags; #endif const char *name; u8 dual_flash; @@ -91,13 +90,13 @@ struct spi_flash { #ifndef CONFIG_DM_SPI_FLASH /* * These are not strictly needed for driver model, but keep them here - * whilt the transition is in progress. + * while the transition is in progress. * * Normally each driver would provide its own operations, but for * SPI flash most chips use the same algorithms. One approach is * to create a 'common' SPI flash device which knows how to talk * to most devices, and then allow other drivers to be used instead - * if requird, perhaps with a way of scanning through the list to + * if required, perhaps with a way of scanning through the list to * find the driver that matches the device. */ int (*read)(struct spi_flash *flash, u32 offset, size_t len, void *buf); @@ -118,6 +117,41 @@ struct dm_spi_flash_ops { #define sf_get_ops(dev) ((struct dm_spi_flash_ops *)(dev)->driver->ops) #ifdef CONFIG_DM_SPI_FLASH +/** + * spi_flash_read_dm() - Read data from SPI flash + * + * @dev: SPI flash device + * @offset: Offset into device in bytes to read from + * @len: Number of bytes to read + * @buf: Buffer to put the data that is read + * @return 0 if OK, -ve on error + */ +int spi_flash_read_dm(struct udevice *dev, u32 offset, size_t len, void *buf); + +/** + * spi_flash_write_dm() - Write data to SPI flash + * + * @dev: SPI flash device + * @offset: Offset into device in bytes to write to + * @len: Number of bytes to write + * @buf: Buffer containing bytes to write + * @return 0 if OK, -ve on error + */ +int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len, + const void *buf); + +/** + * spi_flash_erase_dm() - Erase blocks of the SPI flash + * + * Note that @len must be a muiltiple of the flash sector size. + * + * @dev: SPI flash device + * @offset: Offset into device in bytes to start erasing + * @len: Number of bytes to erase + * @return 0 if OK, -ve on error + */ +int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len); + int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs, unsigned int max_hz, unsigned int spi_mode, struct udevice **devp); @@ -132,21 +166,21 @@ void spi_flash_free(struct spi_flash *flash); int spi_flash_remove(struct udevice *flash); static inline int spi_flash_read(struct spi_flash *flash, u32 offset, - size_t len, void *buf) + size_t len, void *buf) { - return sf_get_ops(flash->dev)->read(flash->dev, offset, len, buf); + return spi_flash_read_dm(flash->dev, offset, len, buf); } static inline int spi_flash_write(struct spi_flash *flash, u32 offset, - size_t len, const void *buf) + size_t len, const void *buf) { - return sf_get_ops(flash->dev)->write(flash->dev, offset, len, buf); + return spi_flash_write_dm(flash->dev, offset, len, buf); } static inline int spi_flash_erase(struct spi_flash *flash, u32 offset, - size_t len) + size_t len) { - return sf_get_ops(flash->dev)->erase(flash->dev, offset, len); + return spi_flash_erase_dm(flash->dev, offset, len); } struct sandbox_state; diff --git a/include/status_led.h b/include/status_led.h index 27f4bdf..a5e35df 100644 --- a/include/status_led.h +++ b/include/status_led.h @@ -105,6 +105,7 @@ typedef unsigned long led_id_t; extern void __led_toggle (led_id_t mask); extern void __led_init (led_id_t mask, int state); extern void __led_set (led_id_t mask, int state); +void __led_blink(led_id_t mask, int freq); #else # error Status LED configuration missing #endif diff --git a/include/usb.h b/include/usb.h index 2c3d506..1984e8f 100644 --- a/include/usb.h +++ b/include/usb.h @@ -2,6 +2,9 @@ * (C) Copyright 2001 * Denis Peter, MPL AG Switzerland * + * Adapted for U-Boot driver model + * (C) Copyright 2015 Google, Inc + * * SPDX-License-Identifier: GPL-2.0+ * Note: Part of this code has been derived from linux * @@ -9,6 +12,7 @@ #ifndef _USB_H_ #define _USB_H_ +#include <fdtdec.h> #include <usb_defs.h> #include <linux/usb/ch9.h> #include <asm/cache.h> @@ -85,6 +89,19 @@ enum { PACKET_SIZE_64 = 3, }; +/** + * struct usb_device - information about a USB device + * + * With driver model both UCLASS_USB (the USB controllers) and UCLASS_USB_HUB + * (the hubs) have this as parent data. Hubs are children of controllers or + * other hubs and there is always a single root hub for each controller. + * Therefore struct usb_device can always be accessed with + * dev_get_parentdata(dev), where dev is a USB device. + * + * Pointers exist for obtaining both the device (could be any uclass) and + * controller (UCLASS_USB) from this structure. The controller does not have + * a struct usb_device since it is not a device. + */ struct usb_device { int devnum; /* Device number on USB bus */ int speed; /* full/low/high */ @@ -123,13 +140,19 @@ struct usb_device { unsigned long int_pending; /* 1 bit per ep, used by int_queue */ int act_len; /* transfered bytes */ int maxchild; /* Number of ports if hub */ - int portnr; + int portnr; /* Port number, 1=first */ +#ifndef CONFIG_DM_USB + /* parent hub, or NULL if this is the root hub */ struct usb_device *parent; struct usb_device *children[USB_MAXCHILDREN]; - void *controller; /* hardware controller private data */ +#endif /* slot_id - for xHCI enabled devices */ unsigned int slot_id; +#ifdef CONFIG_DM_USB + struct udevice *dev; /* Pointer to associated device */ + struct udevice *controller_dev; /* Pointer to associated controller */ +#endif }; struct int_queue; @@ -156,12 +179,14 @@ enum usb_init_type { defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \ defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \ defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_MUSB_SUNXI) || \ - defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_DWC2) + defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_DWC2) || \ + defined(CONFIG_USB_EMUL) int usb_lowlevel_init(int index, enum usb_init_type init, void **controller); int usb_lowlevel_stop(int index); -#ifdef CONFIG_MUSB_HOST -void usb_reset_root_port(void); + +#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_DM_USB) +int usb_reset_root_port(void); #else #define usb_reset_root_port() #endif @@ -245,7 +270,6 @@ int usb_stop(void); /* stop the USB Controller */ int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol); int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id); -struct usb_device *usb_get_dev_index(int index); int usb_control_msg(struct usb_device *dev, unsigned int pipe, unsigned char request, unsigned char requesttype, unsigned short value, unsigned short index, @@ -389,6 +413,113 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate); ((usb_pipeendpoint(pipe) * 2) - \ (usb_pipein(pipe) ? 0 : 1)) +/** + * struct usb_device_id - identifies USB devices for probing and hotplugging + * @match_flags: Bit mask controlling which of the other fields are used to + * match against new devices. Any field except for driver_info may be + * used, although some only make sense in conjunction with other fields. + * This is usually set by a USB_DEVICE_*() macro, which sets all + * other fields in this structure except for driver_info. + * @idVendor: USB vendor ID for a device; numbers are assigned + * by the USB forum to its members. + * @idProduct: Vendor-assigned product ID. + * @bcdDevice_lo: Low end of range of vendor-assigned product version numbers. + * This is also used to identify individual product versions, for + * a range consisting of a single device. + * @bcdDevice_hi: High end of version number range. The range of product + * versions is inclusive. + * @bDeviceClass: Class of device; numbers are assigned + * by the USB forum. Products may choose to implement classes, + * or be vendor-specific. Device classes specify behavior of all + * the interfaces on a device. + * @bDeviceSubClass: Subclass of device; associated with bDeviceClass. + * @bDeviceProtocol: Protocol of device; associated with bDeviceClass. + * @bInterfaceClass: Class of interface; numbers are assigned + * by the USB forum. Products may choose to implement classes, + * or be vendor-specific. Interface classes specify behavior only + * of a given interface; other interfaces may support other classes. + * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass. + * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass. + * @bInterfaceNumber: Number of interface; composite devices may use + * fixed interface numbers to differentiate between vendor-specific + * interfaces. + * @driver_info: Holds information used by the driver. Usually it holds + * a pointer to a descriptor understood by the driver, or perhaps + * device flags. + * + * In most cases, drivers will create a table of device IDs by using + * USB_DEVICE(), or similar macros designed for that purpose. + * They will then export it to userspace using MODULE_DEVICE_TABLE(), + * and provide it to the USB core through their usb_driver structure. + * + * See the usb_match_id() function for information about how matches are + * performed. Briefly, you will normally use one of several macros to help + * construct these entries. Each entry you provide will either identify + * one or more specific products, or will identify a class of products + * which have agreed to behave the same. You should put the more specific + * matches towards the beginning of your table, so that driver_info can + * record quirks of specific products. + */ +struct usb_device_id { + /* which fields to match against? */ + u16 match_flags; + + /* Used for product specific matches; range is inclusive */ + u16 idVendor; + u16 idProduct; + u16 bcdDevice_lo; + u16 bcdDevice_hi; + + /* Used for device class matches */ + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + + /* Used for interface class matches */ + u8 bInterfaceClass; + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; + + /* Used for vendor-specific interface matches */ + u8 bInterfaceNumber; + + /* not matched against */ + ulong driver_info; +}; + +/* Some useful macros to use to create struct usb_device_id */ +#define USB_DEVICE_ID_MATCH_VENDOR 0x0001 +#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002 +#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004 +#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008 +#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010 +#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020 +#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040 +#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080 +#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 +#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 +#define USB_DEVICE_ID_MATCH_INT_NUMBER 0x0400 + +/* Match anything, indicates this is a valid entry even if everything is 0 */ +#define USB_DEVICE_ID_MATCH_NONE 0x0800 +#define USB_DEVICE_ID_MATCH_ALL 0x07ff + +/** + * struct usb_driver_entry - Matches a driver to its usb_device_ids + * @compatible: Compatible string + * @data: Data for this compatible string + */ +struct usb_driver_entry { + struct driver *driver; + const struct usb_device_id *match; +}; + +#define USB_DEVICE(__name, __match) \ + ll_entry_declare(struct usb_driver_entry, __name, usb_driver_entry) = {\ + .driver = llsym(struct driver, __name, driver), \ + .match = __match, \ + } + /************************************************************************* * Hub Stuff */ @@ -423,15 +554,360 @@ struct usb_hub_device { struct usb_hub_descriptor desc; }; +#ifdef CONFIG_DM_USB +/** + * struct usb_platdata - Platform data about a USB controller + * + * Given a USB controller (UCLASS_USB) dev this is dev_get_platdata(dev) + */ +struct usb_platdata { + enum usb_init_type init_type; +}; + +/** + * struct usb_dev_platdata - Platform data about a USB device + * + * Given a USB device dev this structure is dev_get_parent_platdata(dev). + * This is used by sandbox to provide emulation data also. + * + * @id: ID used to match this device + * @speed: Stores the speed associated with a USB device + * @devnum: Device address on the USB bus + * @slot_id: USB3 slot ID, which is separate from the device address + * @portnr: Port number of this device on its parent hub, numbered from 1 + * (0 mean this device is the root hub) + * @strings: List of descriptor strings (for sandbox emulation purposes) + * @desc_list: List of descriptors (for sandbox emulation purposes) + */ +struct usb_dev_platdata { + struct usb_device_id id; + enum usb_device_speed speed; + int devnum; + int slot_id; + int portnr; /* Hub port number, 1..n */ +#ifdef CONFIG_SANDBOX + struct usb_string *strings; + /* NULL-terminated list of descriptor pointers */ + struct usb_generic_descriptor **desc_list; +#endif + int configno; +}; + +/** + * struct usb_bus_priv - information about the USB controller + * + * Given a USB controller (UCLASS_USB) 'dev', this is + * dev_get_uclass_priv(dev). + * + * @next_addr: Next device address to allocate minus 1. Incremented by 1 + * each time a new device address is set, so this holds the + * number of devices on the bus + * @desc_before_addr: true if we can read a device descriptor before it + * has been assigned an address. For XHCI this is not possible + * so this will be false. + */ +struct usb_bus_priv { + int next_addr; + bool desc_before_addr; +}; + +/** + * struct dm_usb_ops - USB controller operations + * + * This defines the operations supoorted on a USB controller. Common + * arguments are: + * + * @bus: USB bus (i.e. controller), which is in UCLASS_USB. + * @udev: USB device parent data. Controllers are not expected to need + * this, since the device address on the bus is encoded in @pipe. + * It is used for sandbox, and can be handy for debugging and + * logging. + * @pipe: An assortment of bitfields which provide address and packet + * type information. See create_pipe() above for encoding + * details + * @buffer: A buffer to use for sending/receiving. This should be + * DMA-aligned. + * @length: Buffer length in bytes + */ +struct dm_usb_ops { + /** + * control() - Send a control message + * + * Most parameters are as above. + * + * @setup: Additional setup information required by the message + */ + int (*control)(struct udevice *bus, struct usb_device *udev, + unsigned long pipe, void *buffer, int length, + struct devrequest *setup); + /** + * bulk() - Send a bulk message + * + * Parameters are as above. + */ + int (*bulk)(struct udevice *bus, struct usb_device *udev, + unsigned long pipe, void *buffer, int length); + /** + * interrupt() - Send an interrupt message + * + * Most parameters are as above. + * + * @interval: Interrupt interval + */ + int (*interrupt)(struct udevice *bus, struct usb_device *udev, + unsigned long pipe, void *buffer, int length, + int interval); + /** + * alloc_device() - Allocate a new device context (XHCI) + * + * Before sending packets to a new device on an XHCI bus, a device + * context must be created. If this method is not NULL it will be + * called before the device is enumerated (even before its descriptor + * is read). This should be NULL for EHCI, which does not need this. + */ + int (*alloc_device)(struct udevice *bus, struct usb_device *udev); +}; + +#define usb_get_ops(dev) ((struct dm_usb_ops *)(dev)->driver->ops) +#define usb_get_emul_ops(dev) ((struct dm_usb_ops *)(dev)->driver->ops) + +#ifdef CONFIG_MUSB_HOST +int usb_reset_root_port(void); +#endif + +/** + * usb_get_dev_index() - look up a device index number + * + * Look up devices using their index number (starting at 0). This works since + * in U-Boot device addresses are allocated starting at 1 with no gaps. + * + * TODO(sjg@chromium.org): Remove this function when usb_ether.c is modified + * to work better with driver model. + * + * @bus: USB bus to check + * @index: Index number of device to find (0=first). This is just the + * device address less 1. + */ +struct usb_device *usb_get_dev_index(struct udevice *bus, int index); + +/** + * usb_legacy_port_reset() - Legacy function to reset a hub port + * + * @hub: Hub device + * @portnr: Port number (1=first) + */ +int usb_legacy_port_reset(struct usb_device *hub, int portnr); + +/** + * usb_setup_device() - set up a device ready for use + * + * @dev: USB device pointer. This need not be a real device - it is + * common for it to just be a local variable with its ->dev + * member (i.e. @dev->dev) set to the parent device + * @do_read: true to read the device descriptor before an address is set + * (should be false for XHCI buses, true otherwise) + * @parent: Parent device (either UCLASS_USB or UCLASS_USB_HUB) + * @portnr: Port number on hub (1=first) or 0 for none + * @return 0 if OK, -ve on error */ +int usb_setup_device(struct usb_device *dev, bool do_read, + struct usb_device *parent, int portnr); + +/** + * usb_hub_scan() - Scan a hub and find its devices + * + * @hub: Hub device to scan + */ +int usb_hub_scan(struct udevice *hub); + +/** + * usb_scan_device() - Scan a device on a bus + * + * Scan a device on a bus. It has already been detected and is ready to + * be enumerated. This may be either the root hub (@parent is a bus) or a + * normal device (@parent is a hub) + * + * @parent: Parent device + * @port: Hub port number (numbered from 1) + * @speed: USB speed to use for this device + * @devp: Returns pointer to device if all is well + * @return 0 if OK, -ve on error + */ +int usb_scan_device(struct udevice *parent, int port, + enum usb_device_speed speed, struct udevice **devp); + +/** + * usb_get_bus() - Find the bus for a device + * + * Search up through parents to find the bus this device is connected to. This + * will be a device with uclass UCLASS_USB. + * + * @dev: Device to check + * @busp: Returns bus, or NULL if not found + * @return 0 if OK, -EXDEV is somehow this bus does not have a controller (this + * indicates a critical error in the USB stack + */ +int usb_get_bus(struct udevice *dev, struct udevice **busp); + +/** + * usb_select_config() - Set up a device ready for use + * + * This function assumes that the device already has an address and a driver + * bound, and is ready to be set up. + * + * This re-reads the device and configuration descriptors and sets the + * configuration + * + * @dev: Device to set up + */ +int usb_select_config(struct usb_device *dev); + +/** + * usb_child_pre_probe() - Pre-probe function for USB devices + * + * This is called on all children of hubs and USB controllers (i.e. UCLASS_USB + * and UCLASS_USB_HUB) when a new device is about to be probed. It sets up the + * device from the saved platform data and calls usb_select_config() to + * finish set up. + * + * Once this is done, the device's normal driver can take over, knowing the + * device is accessible on the USB bus. + * + * This function is for use only by the internal USB stack. + * + * @dev: Device to set up + */ +int usb_child_pre_probe(struct udevice *dev); + +struct ehci_ctrl; + +/** + * usb_setup_ehci_gadget() - Set up a USB device as a gadget + * + * TODO(sjg@chromium.org): Tidy this up when USB gadgets can use driver model + * + * This provides a way to tell a controller to start up as a USB device + * instead of as a host. It is untested. + */ +int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp); + +/** + * usb_stor_reset() - Prepare to scan USB storage devices + * + * Empty the list of USB storage devices in preparation for scanning them. + * This must be called before a USB scan. + */ +void usb_stor_reset(void); + +#else /* !CONFIG_DM_USB */ + +struct usb_device *usb_get_dev_index(int index); + +#endif + +bool usb_device_has_child_on_port(struct usb_device *parent, int port); + int usb_hub_probe(struct usb_device *dev, int ifnum); void usb_hub_reset(void); -int hub_port_reset(struct usb_device *dev, int port, + +/** + * legacy_hub_port_reset() - reset a port given its usb_device pointer + * + * Reset a hub port and see if a device is present on that port, providing + * sufficient time for it to show itself. The port status is returned. + * + * With driver model this moves to hub_port_reset() and is passed a struct + * udevice. + * + * @dev: USB device to reset + * @port: Port number to reset (note ports are numbered from 0 here) + * @portstat: Returns port status + */ +int legacy_hub_port_reset(struct usb_device *dev, int port, unsigned short *portstat); -struct usb_device *usb_alloc_new_device(void *controller); +int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat); + +/** + * usb_alloc_new_device() - Allocate a new device + * + * @devp: returns a pointer of a new device structure. With driver model this + * is a device pointer, but with legacy USB this pointer is + * driver-specific. + * @return 0 if OK, -ENOSPC if we have found out of room for new devices + */ +int usb_alloc_new_device(struct udevice *controller, struct usb_device **devp); + +/** + * usb_free_device() - Free a partially-inited device + * + * This is an internal function. It is used to reverse the action of + * usb_alloc_new_device() when we hit a problem during init. + */ +void usb_free_device(struct udevice *controller); int usb_new_device(struct usb_device *dev); -void usb_free_device(void); + int usb_alloc_device(struct usb_device *dev); +/** + * usb_emul_setup_device() - Set up a new USB device emulation + * + * This is normally called when a new emulation device is bound. It tells + * the USB emulation uclass about the features of the emulator. + * + * @dev: Emulation device + * @maxpacketsize: Maximum packet size (e.g. PACKET_SIZE_64) + * @strings: List of USB string descriptors, terminated by a NULL + * entry + * @desc_list: List of points or USB descriptors, terminated by NULL. + * The first entry must be struct usb_device_descriptor, + * and others follow on after that. + * @return 0 if OK, -ve on error + */ +int usb_emul_setup_device(struct udevice *dev, int maxpacketsize, + struct usb_string *strings, void **desc_list); + +/** + * usb_emul_control() - Send a control packet to an emulator + * + * @emul: Emulator device + * @udev: USB device (which the emulator is causing to appear) + * See struct dm_usb_ops for details on other parameters + * @return 0 if OK, -ve on error + */ +int usb_emul_control(struct udevice *emul, struct usb_device *udev, + unsigned long pipe, void *buffer, int length, + struct devrequest *setup); + +/** + * usb_emul_bulk() - Send a bulk packet to an emulator + * + * @emul: Emulator device + * @udev: USB device (which the emulator is causing to appear) + * See struct dm_usb_ops for details on other parameters + * @return 0 if OK, -ve on error + */ +int usb_emul_bulk(struct udevice *emul, struct usb_device *udev, + unsigned long pipe, void *buffer, int length); + +/** + * usb_emul_find() - Find an emulator for a particular device + * + * Check @pipe to find a device number on bus @bus and return it. + * + * @bus: USB bus (controller) + * @pipe: Describes pipe being used, and includes the device number + * @emulp: Returns pointer to emulator, or NULL if not found + * @return 0 if found, -ve on error + */ +int usb_emul_find(struct udevice *bus, ulong pipe, struct udevice **emulp); + +/** + * usb_emul_reset() - Reset all emulators ready for use + * + * Clear out any address information in the emulators and make then ready for + * a new USB scan + */ +void usb_emul_reset(struct udevice *dev); + #endif /*_USB_H_ */ diff --git a/include/usb_defs.h b/include/usb_defs.h index 236a5ec..8214ba9 100644 --- a/include/usb_defs.h +++ b/include/usb_defs.h @@ -165,12 +165,14 @@ #define USB_TEST_MODE_FORCE_ENABLE 0x05 -/* "pipe" definitions */ - -#define PIPE_ISOCHRONOUS 0 -#define PIPE_INTERRUPT 1 -#define PIPE_CONTROL 2 -#define PIPE_BULK 3 +/* + * "pipe" definitions, use unsigned so we can compare reliably, since this + * value is shifted up to bits 30/31. + */ +#define PIPE_ISOCHRONOUS 0U +#define PIPE_INTERRUPT 1U +#define PIPE_CONTROL 2U +#define PIPE_BULK 3U #define PIPE_DEVEP_MASK 0x0007ff00 #define USB_ISOCHRONOUS 0 @@ -178,6 +180,15 @@ #define USB_CONTROL 2 #define USB_BULK 3 +#define USB_PIPE_TYPE_SHIFT 30 +#define USB_PIPE_TYPE_MASK (3 << USB_PIPE_TYPE_SHIFT) + +#define USB_PIPE_DEV_SHIFT 8 +#define USB_PIPE_DEV_MASK (0x7f << USB_PIPE_DEV_SHIFT) + +#define USB_PIPE_EP_SHIFT 15 +#define USB_PIPE_EP_MASK (0xf << USB_PIPE_EP_SHIFT) + /* USB-status codes: */ #define USB_ST_ACTIVE 0x1 /* TD is active */ #define USB_ST_STALLED 0x2 /* TD is stalled */ @@ -286,4 +297,49 @@ #define HUB_CHANGE_LOCAL_POWER 0x0001 #define HUB_CHANGE_OVERCURRENT 0x0002 +/* Mask for wIndex in get/set port feature */ +#define USB_HUB_PORT_MASK 0xf + +/* + * CBI style + */ + +#define US_CBI_ADSC 0 + +/* Command Block Wrapper */ +struct umass_bbb_cbw { + __u32 dCBWSignature; +# define CBWSIGNATURE 0x43425355 + __u32 dCBWTag; + __u32 dCBWDataTransferLength; + __u8 bCBWFlags; +# define CBWFLAGS_OUT 0x00 +# define CBWFLAGS_IN 0x80 +# define CBWFLAGS_SBZ 0x7f + __u8 bCBWLUN; + __u8 bCDBLength; +# define CBWCDBLENGTH 16 + __u8 CBWCDB[CBWCDBLENGTH]; +}; +#define UMASS_BBB_CBW_SIZE 31 + +/* Command Status Wrapper */ +struct umass_bbb_csw { + __u32 dCSWSignature; +# define CSWSIGNATURE 0x53425355 + __u32 dCSWTag; + __u32 dCSWDataResidue; + __u8 bCSWStatus; +# define CSWSTATUS_GOOD 0x0 +# define CSWSTATUS_FAILED 0x1 +# define CSWSTATUS_PHASE 0x2 +}; +#define UMASS_BBB_CSW_SIZE 13 + +/* + * BULK only + */ +#define US_BBB_RESET 0xff +#define US_BBB_GET_MAX_LUN 0xfe + #endif /*_USB_DEFS_H_ */ diff --git a/include/video.h b/include/video.h index 673aa2e..65e4ec1 100644 --- a/include/video.h +++ b/include/video.h @@ -69,4 +69,8 @@ void video_clear(void); int kwh043st20_f01_spi_startup(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int spi_mode); #endif +#if defined(CONFIG_LG4573) +int lg4573_spi_startup(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int spi_mode); +#endif #endif diff --git a/include/vsprintf.h b/include/vsprintf.h index 5624482..09c8abd 100644 --- a/include/vsprintf.h +++ b/include/vsprintf.h @@ -39,10 +39,33 @@ int strict_strtoul(const char *cp, unsigned int base, unsigned long *res); unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base); long simple_strtol(const char *cp, char **endp, unsigned int base); + +/** + * panic() - Print a message and reset/hang + * + * Prints a message on the console(s) and then resets. If CONFIG_PANIC_HANG is + * defined, then it will hang instead of reseting. + * + * @param fmt: printf() format string for message, which should not include + * \n, followed by arguments + */ void panic(const char *fmt, ...) __attribute__ ((format (__printf__, 1, 2), noreturn)); /** + * panic_str() - Print a message and reset/hang + * + * Prints a message on the console(s) and then resets. If CONFIG_PANIC_HANG is + * defined, then it will hang instead of reseting. + * + * This function can be used instead of panic() when your board does not + * already use printf(), * to keep code size small. + * + * @param fmt: string to display, which should not include \n + */ +void panic_str(const char *str) __attribute__ ((noreturn)); + +/** * Format a string and place it in a buffer * * @param buf The buffer to place the result into diff --git a/lib/Kconfig b/lib/Kconfig index c9d2767..d7fd219 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -27,6 +27,15 @@ config SYS_HZ get_timer() must operate in milliseconds and this option must be set to 1000. +config SYS_VSNPRINTF + bool "Enable safe version of sprintf()" + help + Since sprintf() can overflow its buffer, it is common to use + snprintf() instead, which knows the buffer size and can avoid + overflow. However, this does increase code size slightly (for + Thumb-2, about 420 bytes). Enable this option for safety when + using sprintf() with data you do not control. + source lib/rsa/Kconfig menu "Hashing Support" diff --git a/lib/Makefile b/lib/Makefile index 07d175f..97ed398 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -44,6 +44,12 @@ obj-$(CONFIG_BITREVERSE) += bitrev.o obj-y += list_sort.o endif +ifndef CONFIG_SPL_DISABLE_OF_CONTROL +obj-$(CONFIG_OF_LIBFDT) += libfdt/ +obj-$(CONFIG_OF_CONTROL) += fdtdec_common.o +obj-$(CONFIG_OF_CONTROL) += fdtdec.o +endif + ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 1a0268a..80b897a 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -9,6 +9,7 @@ #include <serial.h> #include <libfdt.h> #include <fdtdec.h> +#include <asm/sections.h> #include <linux/ctype.h> DECLARE_GLOBAL_DATA_PTR; @@ -42,7 +43,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"), COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"), COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"), - COMPAT(GOOGLE_CROS_EC, "google,cros-ec"), COMPAT(GOOGLE_CROS_EC_KEYB, "google,cros-ec-keyb"), COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"), COMPAT(SAMSUNG_EXYNOS5_XHCI, "samsung,exynos5250-xhci"), @@ -61,13 +61,11 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(INFINEON_SLB9635_TPM, "infineon,slb9635-tpm"), COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645-tpm"), COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"), - COMPAT(SANDBOX_HOST_EMULATION, "sandbox,host-emulation"), COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"), COMPAT(TI_TPS65090, "ti,tps65090"), COMPAT(COMPAT_NXP_PTN3460, "nxp,ptn3460"), COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"), COMPAT(PARADE_PS8625, "parade,ps8625"), - COMPAT(COMPAT_INTEL_LPC, "intel,lpc"), COMPAT(INTEL_MICROCODE, "intel,microcode"), COMPAT(MEMORY_SPD, "memory-spd"), COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"), @@ -77,6 +75,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(INTEL_ICH_SPI, "intel,ich-spi"), COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"), COMPAT(SOCIONEXT_XHCI, "socionext,uniphier-xhci"), + COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"), }; const char *fdtdec_get_compatible(enum fdt_compat_id id) @@ -160,8 +159,10 @@ int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type, } } - if (i == num) + if (i == num) { + ret = -ENXIO; goto fail; + } return 0; } else { @@ -565,9 +566,11 @@ int fdtdec_prepare_fdt(void) { if (!gd->fdt_blob || ((uintptr_t)gd->fdt_blob & 3) || fdt_check_header(gd->fdt_blob)) { - printf("No valid FDT found - please append one to U-Boot " - "binary, use u-boot-dtb.bin or define " - "CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n"); +#ifdef CONFIG_SPL_BUILD + puts("Missing DTB\n"); +#else + puts("No valid device tree binary found - please append one to U-Boot binary, use u-boot-dtb.bin or define CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n"); +#endif return -1; } return 0; @@ -918,7 +921,7 @@ int fdtdec_read_fmap_entry(const void *blob, int node, const char *name, return 0; } -static u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells) +u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells) { u64 number = 0; @@ -1035,4 +1038,34 @@ int fdtdec_decode_memory_region(const void *blob, int config_node, return 0; } + +int fdtdec_setup(void) +{ +#ifdef CONFIG_OF_CONTROL +# ifdef CONFIG_OF_EMBED + /* Get a pointer to the FDT */ + gd->fdt_blob = __dtb_dt_begin; +# elif defined CONFIG_OF_SEPARATE +# ifdef CONFIG_SPL_BUILD + /* FDT is at end of BSS */ + gd->fdt_blob = (ulong *)&__bss_end; +# else + /* FDT is at end of image */ + gd->fdt_blob = (ulong *)&_end; #endif +# elif defined(CONFIG_OF_HOSTFILE) + if (sandbox_read_fdt_from_file()) { + puts("Failed to read control FDT\n"); + return -1; + } +# endif +# ifndef CONFIG_SPL_BUILD + /* Allow the early environment to override the fdt address */ + gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, + (uintptr_t)gd->fdt_blob); +# endif +#endif + return fdtdec_prepare_fdt(); +} + +#endif /* !USE_HOSTCC */ diff --git a/lib/gunzip.c b/lib/gunzip.c index f469fcb..4128a18 100644 --- a/lib/gunzip.c +++ b/lib/gunzip.c @@ -11,7 +11,10 @@ #include <image.h> #include <malloc.h> #include <u-boot/zlib.h> +#include <div64.h> +#define HEADER0 '\x1f' +#define HEADER1 '\x8b' #define ZALLOC_ALIGNMENT 16 #define HEAD_CRC 2 #define EXTRA_FIELD 4 @@ -66,6 +69,196 @@ int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp) return zunzip(dst, dstlen, src, lenp, 1, i); } +__weak +void gzwrite_progress_init(u64 expectedsize) +{ + putc('\n'); +} + +__weak +void gzwrite_progress(int iteration, + u64 bytes_written, + u64 total_bytes) +{ + if (0 == (iteration & 3)) + printf("%llu/%llu\r", bytes_written, total_bytes); +} + +__weak +void gzwrite_progress_finish(int returnval, + u64 bytes_written, + u64 total_bytes, + u32 expected_crc, + u32 calculated_crc) +{ + if (0 == returnval) { + printf("\n\t%llu bytes, crc 0x%08x\n", + total_bytes, calculated_crc); + } else { + printf("\n\tuncompressed %llu of %llu\n" + "\tcrcs == 0x%08x/0x%08x\n", + bytes_written, total_bytes, + expected_crc, calculated_crc); + } +} + +int gzwrite(unsigned char *src, int len, + struct block_dev_desc *dev, + unsigned long szwritebuf, + u64 startoffs, + u64 szexpected) +{ + int i, flags; + z_stream s; + int r = 0; + unsigned char *writebuf; + unsigned crc = 0; + u64 totalfilled = 0; + lbaint_t blksperbuf, outblock; + u32 expected_crc; + u32 payload_size; + int iteration = 0; + + if (!szwritebuf || + (szwritebuf % dev->blksz) || + (szwritebuf < dev->blksz)) { + printf("%s: size %lu not a multiple of %lu\n", + __func__, szwritebuf, dev->blksz); + return -1; + } + + if (startoffs & (dev->blksz-1)) { + printf("%s: start offset %llu not a multiple of %lu\n", + __func__, startoffs, dev->blksz); + return -1; + } + + blksperbuf = szwritebuf / dev->blksz; + outblock = lldiv(startoffs, dev->blksz); + + /* skip header */ + i = 10; + flags = src[3]; + if (src[2] != DEFLATED || (flags & RESERVED) != 0) { + puts("Error: Bad gzipped data\n"); + return -1; + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << 8); + if ((flags & ORIG_NAME) != 0) + while (src[i++] != 0) + ; + if ((flags & COMMENT) != 0) + while (src[i++] != 0) + ; + if ((flags & HEAD_CRC) != 0) + i += 2; + + if (i >= len-8) { + puts("Error: gunzip out of data in header"); + return -1; + } + + payload_size = len - i - 8; + + memcpy(&expected_crc, src + len - 8, sizeof(expected_crc)); + expected_crc = le32_to_cpu(expected_crc); + u32 szuncompressed; + memcpy(&szuncompressed, src + len - 4, sizeof(szuncompressed)); + if (szexpected == 0) { + szexpected = le32_to_cpu(szuncompressed); + } else if (szuncompressed != (u32)szexpected) { + printf("size of %llx doesn't match trailer low bits %x\n", + szexpected, szuncompressed); + return -1; + } + if (lldiv(szexpected, dev->blksz) > (dev->lba - outblock)) { + printf("%s: uncompressed size %llu exceeds device size\n", + __func__, szexpected); + return -1; + } + + gzwrite_progress_init(szexpected); + + s.zalloc = gzalloc; + s.zfree = gzfree; + + r = inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf("Error: inflateInit2() returned %d\n", r); + return -1; + } + + s.next_in = src + i; + s.avail_in = payload_size+8; + writebuf = (unsigned char *)malloc(szwritebuf); + + /* decompress until deflate stream ends or end of file */ + do { + if (s.avail_in == 0) { + printf("%s: weird termination with result %d\n", + __func__, r); + break; + } + + /* run inflate() on input until output buffer not full */ + do { + unsigned long blocks_written; + int numfilled; + lbaint_t writeblocks; + + s.avail_out = szwritebuf; + s.next_out = writebuf; + r = inflate(&s, Z_SYNC_FLUSH); + if ((r != Z_OK) && + (r != Z_STREAM_END)) { + printf("Error: inflate() returned %d\n", r); + goto out; + } + numfilled = szwritebuf - s.avail_out; + crc = crc32(crc, writebuf, numfilled); + totalfilled += numfilled; + if (numfilled < szwritebuf) { + writeblocks = (numfilled+dev->blksz-1) + / dev->blksz; + memset(writebuf+numfilled, 0, + dev->blksz-(numfilled%dev->blksz)); + } else { + writeblocks = blksperbuf; + } + + gzwrite_progress(iteration++, + totalfilled, + szexpected); + blocks_written = dev->block_write(dev->dev, + outblock, + writeblocks, + writebuf); + outblock += blocks_written; + if (ctrlc()) { + puts("abort\n"); + goto out; + } + WATCHDOG_RESET(); + } while (s.avail_out == 0); + /* done when inflate() says it's done */ + } while (r != Z_STREAM_END); + + if ((szexpected != totalfilled) || + (crc != expected_crc)) + r = -1; + else + r = 0; + +out: + gzwrite_progress_finish(r, totalfilled, szexpected, + expected_crc, crc); + free(writebuf); + inflateEnd(&s); + + return r; +} + /* * Uncompress blocks compressed with zlib without headers */ @@ -81,7 +274,7 @@ int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp, r = inflateInit2(&s, -MAX_WBITS); if (r != Z_OK) { - printf ("Error: inflateInit2() returned %d\n", r); + printf("Error: inflateInit2() returned %d\n", r); return -1; } s.next_in = src + offset; diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c index 03733e5..44fc0aa 100644 --- a/lib/libfdt/fdt_ro.c +++ b/lib/libfdt/fdt_ro.c @@ -113,6 +113,25 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); } +/* + * Find the next of path seperator, note we need to search for both '/' and ':' + * and then take the first one so that we do the rigth thing for e.g. + * "foo/bar:option" and "bar:option/otheroption", both of which happen, so + * first searching for either ':' or '/' does not work. + */ +static const char *fdt_path_next_seperator(const char *path) +{ + const char *sep1 = strchr(path, '/'); + const char *sep2 = strchr(path, ':'); + + if (sep1 && sep2) + return (sep1 < sep2) ? sep1 : sep2; + else if (sep1) + return sep1; + else + return sep2; +} + int fdt_path_offset(const void *fdt, const char *path) { const char *end = path + strlen(path); @@ -123,7 +142,7 @@ int fdt_path_offset(const void *fdt, const char *path) /* see if we have an alias */ if (*path != '/') { - const char *q = strchr(path, '/'); + const char *q = fdt_path_next_seperator(path); if (!q) q = end; @@ -141,9 +160,9 @@ int fdt_path_offset(const void *fdt, const char *path) while (*p == '/') p++; - if (! *p) + if (*p == '\0' || *p == ':') return offset; - q = strchr(p, '/'); + q = fdt_path_next_seperator(p); if (! q) q = end; diff --git a/lib/net_utils.c b/lib/net_utils.c index 8d66163..cfae842 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -12,23 +12,25 @@ #include <common.h> -IPaddr_t string_to_ip(const char *s) +struct in_addr string_to_ip(const char *s) { - IPaddr_t addr; + struct in_addr addr; char *e; int i; + addr.s_addr = 0; if (s == NULL) - return(0); + return addr; - for (addr=0, i=0; i<4; ++i) { + for (addr.s_addr = 0, i = 0; i < 4; ++i) { ulong val = s ? simple_strtoul(s, &e, 10) : 0; - addr <<= 8; - addr |= (val & 0xFF); + addr.s_addr <<= 8; + addr.s_addr |= (val & 0xFF); if (s) { s = (*e) ? e+1 : e; } } - return (htonl(addr)); + addr.s_addr = htonl(addr.s_addr); + return addr; } diff --git a/lib/trace.c b/lib/trace.c index 711e5b5..ad5e07b 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -5,6 +5,7 @@ */ #include <common.h> +#include <mapmem.h> #include <trace.h> #include <asm/io.h> #include <asm/sections.h> diff --git a/lib/vsprintf.c b/lib/vsprintf.c index e0f2648..bedc865 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -842,13 +842,11 @@ int sprintf(char *buf, const char *fmt, ...) return i; } -void panic(const char *fmt, ...) +static void panic_finish(void) __attribute__ ((noreturn)); + +static void panic_finish(void) { - va_list args; - va_start(args, fmt); - vprintf(fmt, args); putc('\n'); - va_end(args); #if defined(CONFIG_PANIC_HANG) hang(); #else @@ -859,6 +857,21 @@ void panic(const char *fmt, ...) ; } +void panic_str(const char *str) +{ + puts(str); + panic_finish(); +} + +void panic(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + panic_finish(); +} + void __assert_fail(const char *assertion, const char *file, unsigned line, const char *function) { @@ -27,43 +27,43 @@ # define ARP_TIMEOUT_COUNT CONFIG_NET_RETRY_COUNT #endif -IPaddr_t NetArpWaitPacketIP; -static IPaddr_t NetArpWaitReplyIP; +struct in_addr net_arp_wait_packet_ip; +static struct in_addr net_arp_wait_reply_ip; /* MAC address of waiting packet's destination */ -uchar *NetArpWaitPacketMAC; -int NetArpWaitTxPacketSize; -ulong NetArpWaitTimerStart; -int NetArpWaitTry; +uchar *arp_wait_packet_ethaddr; +int arp_wait_tx_packet_size; +ulong arp_wait_timer_start; +int arp_wait_try; -static uchar *NetArpTxPacket; /* THE ARP transmit packet */ -static uchar NetArpPacketBuf[PKTSIZE_ALIGN + PKTALIGN]; +static uchar *arp_tx_packet; /* THE ARP transmit packet */ +static uchar arp_tx_packet_buf[PKTSIZE_ALIGN + PKTALIGN]; -void ArpInit(void) +void arp_init(void) { /* XXX problem with bss workaround */ - NetArpWaitPacketMAC = NULL; - NetArpWaitPacketIP = 0; - NetArpWaitReplyIP = 0; - NetArpWaitTxPacketSize = 0; - NetArpTxPacket = &NetArpPacketBuf[0] + (PKTALIGN - 1); - NetArpTxPacket -= (ulong)NetArpTxPacket % PKTALIGN; + arp_wait_packet_ethaddr = NULL; + net_arp_wait_packet_ip.s_addr = 0; + net_arp_wait_reply_ip.s_addr = 0; + arp_wait_tx_packet_size = 0; + arp_tx_packet = &arp_tx_packet_buf[0] + (PKTALIGN - 1); + arp_tx_packet -= (ulong)arp_tx_packet % PKTALIGN; } -void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther, - IPaddr_t targetIP) +void arp_raw_request(struct in_addr source_ip, const uchar *target_ethaddr, + struct in_addr target_ip) { uchar *pkt; struct arp_hdr *arp; int eth_hdr_size; - debug_cond(DEBUG_DEV_PKT, "ARP broadcast %d\n", NetArpWaitTry); + debug_cond(DEBUG_DEV_PKT, "ARP broadcast %d\n", arp_wait_try); - pkt = NetArpTxPacket; + pkt = arp_tx_packet; - eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_ARP); + eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_ARP); pkt += eth_hdr_size; - arp = (struct arp_hdr *) pkt; + arp = (struct arp_hdr *)pkt; arp->ar_hrd = htons(ARP_ETHER); arp->ar_pro = htons(PROT_IP); @@ -71,59 +71,59 @@ void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther, arp->ar_pln = ARP_PLEN; arp->ar_op = htons(ARPOP_REQUEST); - memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN); /* source ET addr */ - NetWriteIP(&arp->ar_spa, sourceIP); /* source IP addr */ - memcpy(&arp->ar_tha, targetEther, ARP_HLEN); /* target ET addr */ - NetWriteIP(&arp->ar_tpa, targetIP); /* target IP addr */ + memcpy(&arp->ar_sha, net_ethaddr, ARP_HLEN); /* source ET addr */ + net_write_ip(&arp->ar_spa, source_ip); /* source IP addr */ + memcpy(&arp->ar_tha, target_ethaddr, ARP_HLEN); /* target ET addr */ + net_write_ip(&arp->ar_tpa, target_ip); /* target IP addr */ - NetSendPacket(NetArpTxPacket, eth_hdr_size + ARP_HDR_SIZE); + net_send_packet(arp_tx_packet, eth_hdr_size + ARP_HDR_SIZE); } -void ArpRequest(void) +void arp_request(void) { - if ((NetArpWaitPacketIP & NetOurSubnetMask) != - (NetOurIP & NetOurSubnetMask)) { - if (NetOurGatewayIP == 0) { + if ((net_arp_wait_packet_ip.s_addr & net_netmask.s_addr) != + (net_ip.s_addr & net_netmask.s_addr)) { + if (net_gateway.s_addr == 0) { puts("## Warning: gatewayip needed but not set\n"); - NetArpWaitReplyIP = NetArpWaitPacketIP; + net_arp_wait_reply_ip = net_arp_wait_packet_ip; } else { - NetArpWaitReplyIP = NetOurGatewayIP; + net_arp_wait_reply_ip = net_gateway; } } else { - NetArpWaitReplyIP = NetArpWaitPacketIP; + net_arp_wait_reply_ip = net_arp_wait_packet_ip; } - arp_raw_request(NetOurIP, NetEtherNullAddr, NetArpWaitReplyIP); + arp_raw_request(net_ip, net_null_ethaddr, net_arp_wait_reply_ip); } -void ArpTimeoutCheck(void) +void arp_timeout_check(void) { ulong t; - if (!NetArpWaitPacketIP) + if (!net_arp_wait_packet_ip.s_addr) return; t = get_timer(0); /* check for arp timeout */ - if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT) { - NetArpWaitTry++; + if ((t - arp_wait_timer_start) > ARP_TIMEOUT) { + arp_wait_try++; - if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) { + if (arp_wait_try >= ARP_TIMEOUT_COUNT) { puts("\nARP Retry count exceeded; starting again\n"); - NetArpWaitTry = 0; - NetStartAgain(); + arp_wait_try = 0; + net_start_again(); } else { - NetArpWaitTimerStart = t; - ArpRequest(); + arp_wait_timer_start = t; + arp_request(); } } } -void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) +void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) { struct arp_hdr *arp; - IPaddr_t reply_ip_addr; + struct in_addr reply_ip_addr; uchar *pkt; int eth_hdr_size; @@ -152,10 +152,10 @@ void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) if (arp->ar_pln != ARP_PLEN) return; - if (NetOurIP == 0) + if (net_ip.s_addr == 0) return; - if (NetReadIP(&arp->ar_tpa) != NetOurIP) + if (net_read_ip(&arp->ar_tpa).s_addr != net_ip.s_addr) return; switch (ntohs(arp->ar_op)) { @@ -167,9 +167,9 @@ void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) pkt += eth_hdr_size; arp->ar_op = htons(ARPOP_REPLY); memcpy(&arp->ar_tha, &arp->ar_sha, ARP_HLEN); - NetCopyIP(&arp->ar_tpa, &arp->ar_spa); - memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN); - NetCopyIP(&arp->ar_spa, &NetOurIP); + net_copy_ip(&arp->ar_tpa, &arp->ar_spa); + memcpy(&arp->ar_sha, net_ethaddr, ARP_HLEN); + net_copy_ip(&arp->ar_spa, &net_ip); #ifdef CONFIG_CMD_LINK_LOCAL /* @@ -180,53 +180,52 @@ void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) * reply to ARP request so that our reply will overwrite * the arp-proxy's instead of the other way around. */ - if ((NetReadIP(&arp->ar_tpa) & NetOurSubnetMask) != - (NetReadIP(&arp->ar_spa) & NetOurSubnetMask)) + if ((net_read_ip(&arp->ar_tpa).s_addr & net_netmask.s_addr) != + (net_read_ip(&arp->ar_spa).s_addr & net_netmask.s_addr)) udelay(5000); #endif - NetSendPacket((uchar *)et, eth_hdr_size + ARP_HDR_SIZE); + net_send_packet((uchar *)et, eth_hdr_size + ARP_HDR_SIZE); return; case ARPOP_REPLY: /* arp reply */ /* are we waiting for a reply */ - if (!NetArpWaitPacketIP) + if (!net_arp_wait_packet_ip.s_addr) break; #ifdef CONFIG_KEEP_SERVERADDR - if (NetServerIP == NetArpWaitPacketIP) { + if (net_server_ip.s_addr == net_arp_wait_packet_ip.s_addr) { char buf[20]; sprintf(buf, "%pM", &arp->ar_sha); setenv("serveraddr", buf); } #endif - reply_ip_addr = NetReadIP(&arp->ar_spa); + reply_ip_addr = net_read_ip(&arp->ar_spa); /* matched waiting packet's address */ - if (reply_ip_addr == NetArpWaitReplyIP) { + if (reply_ip_addr.s_addr == net_arp_wait_reply_ip.s_addr) { debug_cond(DEBUG_DEV_PKT, - "Got ARP REPLY, set eth addr (%pM)\n", - arp->ar_data); + "Got ARP REPLY, set eth addr (%pM)\n", + arp->ar_data); /* save address for later use */ - if (NetArpWaitPacketMAC != NULL) - memcpy(NetArpWaitPacketMAC, + if (arp_wait_packet_ethaddr != NULL) + memcpy(arp_wait_packet_ethaddr, &arp->ar_sha, ARP_HLEN); net_get_arp_handler()((uchar *)arp, 0, reply_ip_addr, - 0, len); + 0, len); /* set the mac address in the waiting packet's header and transmit it */ - memcpy(((struct ethernet_hdr *)NetTxPacket)->et_dest, - &arp->ar_sha, ARP_HLEN); - NetSendPacket(NetTxPacket, NetArpWaitTxPacketSize); + memcpy(((struct ethernet_hdr *)net_tx_packet)->et_dest, + &arp->ar_sha, ARP_HLEN); + net_send_packet(net_tx_packet, arp_wait_tx_packet_size); /* no arp request pending now */ - NetArpWaitPacketIP = 0; - NetArpWaitTxPacketSize = 0; - NetArpWaitPacketMAC = NULL; - + net_arp_wait_packet_ip.s_addr = 0; + arp_wait_tx_packet_size = 0; + arp_wait_packet_ethaddr = NULL; } return; default: @@ -14,18 +14,18 @@ #include <common.h> -extern IPaddr_t NetArpWaitPacketIP; +extern struct in_addr net_arp_wait_packet_ip; /* MAC address of waiting packet's destination */ -extern uchar *NetArpWaitPacketMAC; -extern int NetArpWaitTxPacketSize; -extern ulong NetArpWaitTimerStart; -extern int NetArpWaitTry; +extern uchar *arp_wait_packet_ethaddr; +extern int arp_wait_tx_packet_size; +extern ulong arp_wait_timer_start; +extern int arp_wait_try; -void ArpInit(void); -void ArpRequest(void); -void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther, - IPaddr_t targetIP); -void ArpTimeoutCheck(void); -void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len); +void arp_init(void); +void arp_request(void); +void arp_raw_request(struct in_addr source_ip, const uchar *targetEther, + struct in_addr target_ip); +void arp_timeout_check(void); +void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len); #endif /* __ARP_H__ */ diff --git a/net/bootp.c b/net/bootp.c index 8106601..43466af 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -51,18 +51,21 @@ #define CONFIG_BOOTP_ID_CACHE_SIZE 4 #endif -ulong bootp_ids[CONFIG_BOOTP_ID_CACHE_SIZE]; +u32 bootp_ids[CONFIG_BOOTP_ID_CACHE_SIZE]; unsigned int bootp_num_ids; -int BootpTry; +int bootp_try; ulong bootp_start; ulong bootp_timeout; +char net_nis_domain[32] = {0,}; /* Our NIS domain */ +char net_hostname[32] = {0,}; /* Our hostname */ +char net_root_path[64] = {0,}; /* Our bootpath */ #if defined(CONFIG_CMD_DHCP) static dhcp_state_t dhcp_state = INIT; -static unsigned long dhcp_leasetime; -static IPaddr_t NetDHCPServerIP; -static void DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, - unsigned len); +static u32 dhcp_leasetime; +static struct in_addr dhcp_server_ip; +static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip, + unsigned src, unsigned len); /* For Debug */ #if 0 @@ -106,14 +109,14 @@ static bool bootp_match_id(ulong id) return false; } -static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len) +static int check_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len) { - struct Bootp_t *bp = (struct Bootp_t *) pkt; + struct bootp_hdr *bp = (struct bootp_hdr *)pkt; int retval = 0; if (dest != PORT_BOOTPC || src != PORT_BOOTPS) retval = -1; - else if (len < sizeof(struct Bootp_t) - OPT_FIELD_SIZE) + else if (len < sizeof(struct bootp_hdr) - OPT_FIELD_SIZE) retval = -2; else if (bp->bp_op != OP_BOOTREQUEST && bp->bp_op != OP_BOOTREPLY && @@ -125,7 +128,7 @@ static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len) retval = -4; else if (bp->bp_hlen != HWL_ETHER) retval = -5; - else if (!bootp_match_id(NetReadLong((ulong *)&bp->bp_id))) + else if (!bootp_match_id(net_read_u32(&bp->bp_id))) retval = -6; debug("Filtering pkt = %d\n", retval); @@ -136,28 +139,30 @@ static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len) /* * Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet */ -static void BootpCopyNetParams(struct Bootp_t *bp) +static void store_net_params(struct bootp_hdr *bp) { #if !defined(CONFIG_BOOTP_SERVERIP) - IPaddr_t tmp_ip; + struct in_addr tmp_ip; - NetCopyIP(&tmp_ip, &bp->bp_siaddr); - if (tmp_ip != 0) - NetCopyIP(&NetServerIP, &bp->bp_siaddr); - memcpy(NetServerEther, ((struct ethernet_hdr *)NetRxPacket)->et_src, 6); + net_copy_ip(&tmp_ip, &bp->bp_siaddr); + if (tmp_ip.s_addr != 0) + net_copy_ip(&net_server_ip, &bp->bp_siaddr); + memcpy(net_server_ethaddr, + ((struct ethernet_hdr *)net_rx_packet)->et_src, 6); if (strlen(bp->bp_file) > 0) - copy_filename(BootFile, bp->bp_file, sizeof(BootFile)); + copy_filename(net_boot_file_name, bp->bp_file, + sizeof(net_boot_file_name)); - debug("Bootfile: %s\n", BootFile); + debug("net_boot_file_name: %s\n", net_boot_file_name); /* Propagate to environment: * don't delete exising entry when BOOTP / DHCP reply does * not contain a new value */ - if (*BootFile) - setenv("bootfile", BootFile); + if (*net_boot_file_name) + setenv("bootfile", net_boot_file_name); #endif - NetCopyIP(&NetOurIP, &bp->bp_yiaddr); + net_copy_ip(&net_ip, &bp->bp_yiaddr); } static int truncate_sz(const char *name, int maxlen, int curlen) @@ -172,38 +177,40 @@ static int truncate_sz(const char *name, int maxlen, int curlen) #if !defined(CONFIG_CMD_DHCP) -static void BootpVendorFieldProcess(u8 *ext) +static void bootp_process_vendor_field(u8 *ext) { int size = *(ext + 1); debug("[BOOTP] Processing extension %d... (%d bytes)\n", *ext, - *(ext + 1)); + *(ext + 1)); - NetBootFileSize = 0; + net_boot_file_expected_size_in_blocks = 0; switch (*ext) { /* Fixed length fields */ case 1: /* Subnet mask */ - if (NetOurSubnetMask == 0) - NetCopyIP(&NetOurSubnetMask, (IPaddr_t *) (ext + 2)); + if (net_netmask.s_addr == 0) + net_copy_ip(&net_netmask, (struct in_addr *)(ext + 2)); break; case 2: /* Time offset - Not yet supported */ break; /* Variable length fields */ case 3: /* Gateways list */ - if (NetOurGatewayIP == 0) - NetCopyIP(&NetOurGatewayIP, (IPaddr_t *) (ext + 2)); + if (net_gateway.s_addr == 0) + net_copy_ip(&net_gateway, (struct in_addr *)(ext + 2)); break; case 4: /* Time server - Not yet supported */ break; case 5: /* IEN-116 name server - Not yet supported */ break; case 6: - if (NetOurDNSIP == 0) - NetCopyIP(&NetOurDNSIP, (IPaddr_t *) (ext + 2)); + if (net_dns_server.s_addr == 0) + net_copy_ip(&net_dns_server, + (struct in_addr *)(ext + 2)); #if defined(CONFIG_BOOTP_DNS2) - if ((NetOurDNS2IP == 0) && (size > 4)) - NetCopyIP(&NetOurDNS2IP, (IPaddr_t *) (ext + 2 + 4)); + if ((net_dns_server2.s_addr == 0) && (size > 4)) + net_copy_ip(&net_dns_server2, + (struct in_addr *)(ext + 2 + 4)); #endif break; case 7: /* Log server - Not yet supported */ @@ -217,18 +224,20 @@ static void BootpVendorFieldProcess(u8 *ext) case 11: /* RPL server - Not yet supported */ break; case 12: /* Host name */ - if (NetOurHostName[0] == 0) { + if (net_hostname[0] == 0) { size = truncate_sz("Host Name", - sizeof(NetOurHostName), size); - memcpy(&NetOurHostName, ext + 2, size); - NetOurHostName[size] = 0; + sizeof(net_hostname), size); + memcpy(&net_hostname, ext + 2, size); + net_hostname[size] = 0; } break; case 13: /* Boot file size */ if (size == 2) - NetBootFileSize = ntohs(*(ushort *) (ext + 2)); + net_boot_file_expected_size_in_blocks = + ntohs(*(ushort *)(ext + 2)); else if (size == 4) - NetBootFileSize = ntohl(*(ulong *) (ext + 2)); + net_boot_file_expected_size_in_blocks = + ntohl(*(ulong *)(ext + 2)); break; case 14: /* Merit dump file - Not yet supported */ break; @@ -237,11 +246,11 @@ static void BootpVendorFieldProcess(u8 *ext) case 16: /* Swap server - Not yet supported */ break; case 17: /* Root path */ - if (NetOurRootPath[0] == 0) { + if (net_root_path[0] == 0) { size = truncate_sz("Root Path", - sizeof(NetOurRootPath), size); - memcpy(&NetOurRootPath, ext + 2, size); - NetOurRootPath[size] = 0; + sizeof(net_root_path), size); + memcpy(&net_root_path, ext + 2, size); + net_root_path[size] = 0; } break; case 18: /* Extension path - Not yet supported */ @@ -253,16 +262,16 @@ static void BootpVendorFieldProcess(u8 *ext) break; /* IP host layer fields */ case 40: /* NIS Domain name */ - if (NetOurNISDomain[0] == 0) { + if (net_nis_domain[0] == 0) { size = truncate_sz("NIS Domain Name", - sizeof(NetOurNISDomain), size); - memcpy(&NetOurNISDomain, ext + 2, size); - NetOurNISDomain[size] = 0; + sizeof(net_nis_domain), size); + memcpy(&net_nis_domain, ext + 2, size); + net_nis_domain[size] = 0; } break; #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER) case 42: /* NTP server IP */ - NetCopyIP(&NetNtpServerIP, (IPaddr_t *) (ext + 2)); + net_copy_ip(&net_ntp_server, (struct in_addr *)(ext + 2)); break; #endif /* Application layer fields */ @@ -276,7 +285,7 @@ static void BootpVendorFieldProcess(u8 *ext) } } -static void BootpVendorProcess(u8 *ext, int size) +static void bootp_process_vendor(u8 *ext, int size) { u8 *end = ext + size; @@ -290,54 +299,51 @@ static void BootpVendorProcess(u8 *ext, int size) ext += ext[1] + 2; if (ext <= end) - BootpVendorFieldProcess(opt); + bootp_process_vendor_field(opt); } } debug("[BOOTP] Received fields:\n"); - if (NetOurSubnetMask) - debug("NetOurSubnetMask : %pI4\n", &NetOurSubnetMask); + if (net_netmask.s_addr) + debug("net_netmask : %pI4\n", &net_netmask); - if (NetOurGatewayIP) - debug("NetOurGatewayIP : %pI4", &NetOurGatewayIP); + if (net_gateway.s_addr) + debug("net_gateway : %pI4", &net_gateway); - if (NetBootFileSize) - debug("NetBootFileSize : %d\n", NetBootFileSize); + if (net_boot_file_expected_size_in_blocks) + debug("net_boot_file_expected_size_in_blocks : %d\n", + net_boot_file_expected_size_in_blocks); - if (NetOurHostName[0]) - debug("NetOurHostName : %s\n", NetOurHostName); + if (net_hostname[0]) + debug("net_hostname : %s\n", net_hostname); - if (NetOurRootPath[0]) - debug("NetOurRootPath : %s\n", NetOurRootPath); + if (net_root_path[0]) + debug("net_root_path : %s\n", net_root_path); - if (NetOurNISDomain[0]) - debug("NetOurNISDomain : %s\n", NetOurNISDomain); - - if (NetBootFileSize) - debug("NetBootFileSize: %d\n", NetBootFileSize); + if (net_nis_domain[0]) + debug("net_nis_domain : %s\n", net_nis_domain); #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER) - if (NetNtpServerIP) - debug("NetNtpServerIP : %pI4\n", &NetNtpServerIP); + if (net_ntp_server) + debug("net_ntp_server : %pI4\n", &net_ntp_server); #endif } /* * Handle a BOOTP received packet. */ -static void -BootpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, - unsigned len) +static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip, + unsigned src, unsigned len) { - struct Bootp_t *bp; + struct bootp_hdr *bp; debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n", - src, dest, len, sizeof(struct Bootp_t)); + src, dest, len, sizeof(struct bootp_hdr)); - bp = (struct Bootp_t *)pkt; + bp = (struct bootp_hdr *)pkt; /* Filter out pkts we don't want */ - if (BootpCheckPkt(pkt, dest, src, len)) + if (check_packet(pkt, dest, src, len)) return; /* @@ -347,13 +353,13 @@ BootpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF); #endif - BootpCopyNetParams(bp); /* Store net parameters from reply */ + store_net_params(bp); /* Store net parameters from reply */ /* Retrieve extended information (we must parse the vendor area) */ - if (NetReadLong((ulong *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) - BootpVendorProcess((uchar *)&bp->bp_vend[4], len); + if (net_read_u32((u32 *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) + bootp_process_vendor((uchar *)&bp->bp_vend[4], len); - NetSetTimeout(0, (thand_f *)0); + net_set_timeout_handler(0, (thand_f *)0); bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP, "bootp_stop"); debug("Got good BOOTP\n"); @@ -365,8 +371,7 @@ BootpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, /* * Timeout on BOOTP/DHCP request. */ -static void -BootpTimeout(void) +static void bootp_timeout_handler(void) { ulong time_taken = get_timer(bootp_start); @@ -376,14 +381,14 @@ BootpTimeout(void) net_set_state(NETLOOP_FAIL); #else puts("\nRetry time exceeded; starting again\n"); - NetStartAgain(); + net_start_again(); #endif } else { bootp_timeout *= 2; if (bootp_timeout > 2000) bootp_timeout = 2000; - NetSetTimeout(bootp_timeout, BootpTimeout); - BootpRequest(); + net_set_timeout_handler(bootp_timeout, bootp_timeout_handler); + bootp_request(); } } @@ -400,8 +405,8 @@ BootpTimeout(void) * Initialize BOOTP extension fields in the request. */ #if defined(CONFIG_CMD_DHCP) -static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID, - IPaddr_t RequestedIP) +static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip, + struct in_addr requested_ip) { u8 *start = e; u8 *cnt; @@ -431,8 +436,8 @@ static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID, *e++ = (576 - 312 + OPT_FIELD_SIZE) >> 8; *e++ = (576 - 312 + OPT_FIELD_SIZE) & 0xff; - if (ServerID) { - int tmp = ntohl(ServerID); + if (server_ip.s_addr) { + int tmp = ntohl(server_ip.s_addr); *e++ = 54; /* ServerID */ *e++ = 4; @@ -442,8 +447,8 @@ static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID, *e++ = tmp & 0xff; } - if (RequestedIP) { - int tmp = ntohl(RequestedIP); + if (requested_ip.s_addr) { + int tmp = ntohl(requested_ip.s_addr); *e++ = 50; /* Requested IP */ *e++ = 4; @@ -561,7 +566,7 @@ static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID, /* * Warning: no field size check - change CONFIG_BOOTP_* at your own risk! */ -static int BootpExtended(u8 *e) +static int bootp_extended(u8 *e) { u8 *start = e; @@ -643,25 +648,26 @@ static int BootpExtended(u8 *e) } #endif -void BootpReset(void) +void bootp_reset(void) { bootp_num_ids = 0; - BootpTry = 0; + bootp_try = 0; bootp_start = get_timer(0); bootp_timeout = 250; } -void -BootpRequest(void) +void bootp_request(void) { uchar *pkt, *iphdr; - struct Bootp_t *bp; + struct bootp_hdr *bp; int extlen, pktlen, iplen; int eth_hdr_size; #ifdef CONFIG_BOOTP_RANDOM_DELAY ulong rand_ms; #endif - ulong BootpID; + u32 bootp_id; + struct in_addr zero_ip; + struct in_addr bcast_ip; bootstage_mark_name(BOOTSTAGE_ID_BOOTP_START, "bootp_start"); #if defined(CONFIG_CMD_DHCP) @@ -669,11 +675,11 @@ BootpRequest(void) #endif #ifdef CONFIG_BOOTP_RANDOM_DELAY /* Random BOOTP delay */ - if (BootpTry == 0) + if (bootp_try == 0) srand_mac(); - if (BootpTry <= 2) /* Start with max 1024 * 1ms */ - rand_ms = rand() >> (22 - BootpTry); + if (bootp_try <= 2) /* Start with max 1024 * 1ms */ + rand_ms = rand() >> (22 - bootp_try); else /* After 3rd BOOTP request max 8192 * 1ms */ rand_ms = rand() >> 19; @@ -682,11 +688,11 @@ BootpRequest(void) #endif /* CONFIG_BOOTP_RANDOM_DELAY */ - printf("BOOTP broadcast %d\n", ++BootpTry); - pkt = NetTxPacket; + printf("BOOTP broadcast %d\n", ++bootp_try); + pkt = net_tx_packet; memset((void *)pkt, 0, PKTSIZE); - eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_IP); + eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_IP); pkt += eth_hdr_size; /* @@ -697,42 +703,44 @@ BootpRequest(void) * C. Hallinan, DS4.COM, Inc. */ /* net_set_udp_header(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, - sizeof (struct Bootp_t)); */ + sizeof (struct bootp_hdr)); */ iphdr = pkt; /* We need this later for net_set_udp_header() */ pkt += IP_UDP_HDR_SIZE; - bp = (struct Bootp_t *)pkt; + bp = (struct bootp_hdr *)pkt; bp->bp_op = OP_BOOTREQUEST; bp->bp_htype = HWT_ETHER; bp->bp_hlen = HWL_ETHER; bp->bp_hops = 0; bp->bp_secs = htons(get_timer(0) / 1000); - NetWriteIP(&bp->bp_ciaddr, 0); - NetWriteIP(&bp->bp_yiaddr, 0); - NetWriteIP(&bp->bp_siaddr, 0); - NetWriteIP(&bp->bp_giaddr, 0); - memcpy(bp->bp_chaddr, NetOurEther, 6); - copy_filename(bp->bp_file, BootFile, sizeof(bp->bp_file)); + zero_ip.s_addr = 0; + net_write_ip(&bp->bp_ciaddr, zero_ip); + net_write_ip(&bp->bp_yiaddr, zero_ip); + net_write_ip(&bp->bp_siaddr, zero_ip); + net_write_ip(&bp->bp_giaddr, zero_ip); + memcpy(bp->bp_chaddr, net_ethaddr, 6); + copy_filename(bp->bp_file, net_boot_file_name, sizeof(bp->bp_file)); /* Request additional information from the BOOTP/DHCP server */ #if defined(CONFIG_CMD_DHCP) - extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0); + extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_DISCOVER, zero_ip, + zero_ip); #else - extlen = BootpExtended((u8 *)bp->bp_vend); + extlen = bootp_extended((u8 *)bp->bp_vend); #endif /* * Bootp ID is the lower 4 bytes of our ethernet address * plus the current time in ms. */ - BootpID = ((ulong)NetOurEther[2] << 24) - | ((ulong)NetOurEther[3] << 16) - | ((ulong)NetOurEther[4] << 8) - | (ulong)NetOurEther[5]; - BootpID += get_timer(0); - BootpID = htonl(BootpID); - bootp_add_id(BootpID); - NetCopyLong(&bp->bp_id, &BootpID); + bootp_id = ((u32)net_ethaddr[2] << 24) + | ((u32)net_ethaddr[3] << 16) + | ((u32)net_ethaddr[4] << 8) + | (u32)net_ethaddr[5]; + bootp_id += get_timer(0); + bootp_id = htonl(bootp_id); + bootp_add_id(bootp_id); + net_copy_u32(&bp->bp_id, &bootp_id); /* * Calculate proper packet lengths taking into account the @@ -740,20 +748,21 @@ BootpRequest(void) */ iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen; pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen; - net_set_udp_header(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen); - NetSetTimeout(bootp_timeout, BootpTimeout); + bcast_ip.s_addr = 0xFFFFFFFFL; + net_set_udp_header(iphdr, bcast_ip, PORT_BOOTPS, PORT_BOOTPC, iplen); + net_set_timeout_handler(bootp_timeout, bootp_timeout_handler); #if defined(CONFIG_CMD_DHCP) dhcp_state = SELECTING; - net_set_udp_handler(DhcpHandler); + net_set_udp_handler(dhcp_handler); #else - net_set_udp_handler(BootpHandler); + net_set_udp_handler(bootp_handler); #endif - NetSendPacket(NetTxPacket, pktlen); + net_send_packet(net_tx_packet, pktlen); } #if defined(CONFIG_CMD_DHCP) -static void DhcpOptionsProcess(uchar *popt, struct Bootp_t *bp) +static void dhcp_process_options(uchar *popt, struct bootp_hdr *bp) { uchar *end = popt + BOOTP_HDR_SIZE; int oplen, size; @@ -765,53 +774,53 @@ static void DhcpOptionsProcess(uchar *popt, struct Bootp_t *bp) oplen = *(popt + 1); switch (*popt) { case 1: - NetCopyIP(&NetOurSubnetMask, (popt + 2)); + net_copy_ip(&net_netmask, (popt + 2)); break; #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET) case 2: /* Time offset */ - to_ptr = &NetTimeOffset; - NetCopyLong((ulong *)to_ptr, (ulong *)(popt + 2)); - NetTimeOffset = ntohl(NetTimeOffset); + to_ptr = &net_ntp_time_offset; + net_copy_u32((u32 *)to_ptr, (u32 *)(popt + 2)); + net_ntp_time_offset = ntohl(net_ntp_time_offset); break; #endif case 3: - NetCopyIP(&NetOurGatewayIP, (popt + 2)); + net_copy_ip(&net_gateway, (popt + 2)); break; case 6: - NetCopyIP(&NetOurDNSIP, (popt + 2)); + net_copy_ip(&net_dns_server, (popt + 2)); #if defined(CONFIG_BOOTP_DNS2) if (*(popt + 1) > 4) - NetCopyIP(&NetOurDNS2IP, (popt + 2 + 4)); + net_copy_ip(&net_dns_server2, (popt + 2 + 4)); #endif break; case 12: size = truncate_sz("Host Name", - sizeof(NetOurHostName), oplen); - memcpy(&NetOurHostName, popt + 2, size); - NetOurHostName[size] = 0; + sizeof(net_hostname), oplen); + memcpy(&net_hostname, popt + 2, size); + net_hostname[size] = 0; break; case 15: /* Ignore Domain Name Option */ break; case 17: size = truncate_sz("Root Path", - sizeof(NetOurRootPath), oplen); - memcpy(&NetOurRootPath, popt + 2, size); - NetOurRootPath[size] = 0; + sizeof(net_root_path), oplen); + memcpy(&net_root_path, popt + 2, size); + net_root_path[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)); + net_copy_ip(&net_ntp_server, (popt + 2)); break; #endif case 51: - NetCopyLong(&dhcp_leasetime, (ulong *) (popt + 2)); + net_copy_u32(&dhcp_leasetime, (u32 *)(popt + 2)); break; case 53: /* Ignore Message Type Option */ break; case 54: - NetCopyIP(&NetDHCPServerIP, (popt + 2)); + net_copy_ip(&dhcp_server_ip, (popt + 2)); break; case 58: /* Ignore Renewal Time Option */ break; @@ -840,7 +849,7 @@ static void DhcpOptionsProcess(uchar *popt, struct Bootp_t *bp) * to me */ printf("*** WARNING: using vendor " - "optional boot file\n"); + "optional boot file\n"); memcpy(bp->bp_file, popt + 2, size); bp->bp_file[size] = '\0'; } @@ -851,16 +860,16 @@ static void DhcpOptionsProcess(uchar *popt, struct Bootp_t *bp) break; #endif printf("*** Unhandled DHCP Option in OFFER/ACK:" - " %d\n", *popt); + " %d\n", *popt); break; } popt += oplen + 2; /* Process next option */ } } -static int DhcpMessageType(unsigned char *popt) +static int dhcp_message_type(unsigned char *popt) { - if (NetReadLong((ulong *)popt) != htonl(BOOTP_VENDOR_MAGIC)) + if (net_read_u32((u32 *)popt) != htonl(BOOTP_VENDOR_MAGIC)) return -1; popt += 4; @@ -872,25 +881,27 @@ static int DhcpMessageType(unsigned char *popt) return -1; } -static void DhcpSendRequestPkt(struct Bootp_t *bp_offer) +static void dhcp_send_request_packet(struct bootp_hdr *bp_offer) { uchar *pkt, *iphdr; - struct Bootp_t *bp; + struct bootp_hdr *bp; int pktlen, iplen, extlen; int eth_hdr_size; - IPaddr_t OfferedIP; + struct in_addr offered_ip; + struct in_addr zero_ip; + struct in_addr bcast_ip; - debug("DhcpSendRequestPkt: Sending DHCPREQUEST\n"); - pkt = NetTxPacket; + debug("dhcp_send_request_packet: Sending DHCPREQUEST\n"); + pkt = net_tx_packet; memset((void *)pkt, 0, PKTSIZE); - eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_IP); + eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_IP); pkt += eth_hdr_size; iphdr = pkt; /* We'll need this later to set proper pkt size */ pkt += IP_UDP_HDR_SIZE; - bp = (struct Bootp_t *)pkt; + bp = (struct bootp_hdr *)pkt; bp->bp_op = OP_BOOTREQUEST; bp->bp_htype = HWT_ETHER; bp->bp_hlen = HWL_ETHER; @@ -903,54 +914,55 @@ static void DhcpSendRequestPkt(struct Bootp_t *bp_offer) * RFC3046 requires Relay Agents to discard packets with * nonzero and offered giaddr */ - NetWriteIP(&bp->bp_giaddr, 0); + zero_ip.s_addr = 0; + net_write_ip(&bp->bp_giaddr, zero_ip); - memcpy(bp->bp_chaddr, NetOurEther, 6); + memcpy(bp->bp_chaddr, net_ethaddr, 6); /* * ID is the id of the OFFER packet */ - NetCopyLong(&bp->bp_id, &bp_offer->bp_id); + net_copy_u32(&bp->bp_id, &bp_offer->bp_id); /* * Copy options from OFFER packet if present */ /* Copy offered IP into the parameters request list */ - NetCopyIP(&OfferedIP, &bp_offer->bp_yiaddr); - extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_REQUEST, - NetDHCPServerIP, OfferedIP); + net_copy_ip(&offered_ip, &bp_offer->bp_yiaddr); + extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_REQUEST, + dhcp_server_ip, offered_ip); iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen; pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen; - net_set_udp_header(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen); + bcast_ip.s_addr = 0xFFFFFFFFL; + net_set_udp_header(iphdr, bcast_ip, PORT_BOOTPS, PORT_BOOTPC, iplen); #ifdef CONFIG_BOOTP_DHCP_REQUEST_DELAY udelay(CONFIG_BOOTP_DHCP_REQUEST_DELAY); #endif /* CONFIG_BOOTP_DHCP_REQUEST_DELAY */ debug("Transmitting DHCPREQUEST packet: len = %d\n", pktlen); - NetSendPacket(NetTxPacket, pktlen); + net_send_packet(net_tx_packet, pktlen); } /* * Handle DHCP received packets. */ -static void -DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, - unsigned len) +static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip, + unsigned src, unsigned len) { - struct Bootp_t *bp = (struct Bootp_t *)pkt; + struct bootp_hdr *bp = (struct bootp_hdr *)pkt; debug("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n", - src, dest, len, dhcp_state); + src, dest, len, dhcp_state); /* Filter out pkts we don't want */ - if (BootpCheckPkt(pkt, dest, src, len)) + if (check_packet(pkt, dest, src, len)) return; - debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state:" - " %d\n", src, dest, len, dhcp_state); + debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: " + "%d\n", src, dest, len, dhcp_state); switch (dhcp_state) { case SELECTING: @@ -970,12 +982,12 @@ DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, debug("TRANSITIONING TO REQUESTING STATE\n"); dhcp_state = REQUESTING; - if (NetReadLong((ulong *)&bp->bp_vend[0]) == + if (net_read_u32((u32 *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) - DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp); + dhcp_process_options((u8 *)&bp->bp_vend[4], bp); - NetSetTimeout(5000, BootpTimeout); - DhcpSendRequestPkt(bp); + net_set_timeout_handler(5000, bootp_timeout_handler); + dhcp_send_request_packet(bp); #ifdef CONFIG_SYS_BOOTFILE_PREFIX } #endif /* CONFIG_SYS_BOOTFILE_PREFIX */ @@ -985,17 +997,17 @@ DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, case REQUESTING: debug("DHCP State: REQUESTING\n"); - if (DhcpMessageType((u8 *)bp->bp_vend) == DHCP_ACK) { - if (NetReadLong((ulong *)&bp->bp_vend[0]) == + if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK) { + if (net_read_u32((u32 *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) - DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp); + dhcp_process_options((u8 *)&bp->bp_vend[4], bp); /* Store net params from reply */ - BootpCopyNetParams(bp); + store_net_params(bp); dhcp_state = BOUND; printf("DHCP client bound to address %pI4 (%lu ms)\n", - &NetOurIP, get_timer(bootp_start)); + &net_ip, get_timer(bootp_start)); bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP, - "bootp_stop"); + "bootp_stop"); net_auto_load(); return; @@ -1008,11 +1020,10 @@ DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, puts("DHCP: INVALID STATE\n"); break; } - } -void DhcpRequest(void) +void dhcp_request(void) { - BootpRequest(); + bootp_request(); } #endif /* CONFIG_CMD_DHCP */ diff --git a/net/bootp.h b/net/bootp.h index 3b95a0a..fcb0a64 100644 --- a/net/bootp.h +++ b/net/bootp.h @@ -29,29 +29,29 @@ extern u8 *dhcp_vendorex_proc(u8 *e); /*rtn next e if mine,else NULL */ #define OPT_FIELD_SIZE 64 #endif -struct Bootp_t { - uchar bp_op; /* Operation */ +struct bootp_hdr { + u8 bp_op; /* Operation */ # define OP_BOOTREQUEST 1 # define OP_BOOTREPLY 2 - uchar bp_htype; /* Hardware type */ + u8 bp_htype; /* Hardware type */ # define HWT_ETHER 1 - uchar bp_hlen; /* Hardware address length */ + u8 bp_hlen; /* Hardware address length */ # define HWL_ETHER 6 - uchar bp_hops; /* Hop count (gateway thing) */ - ulong bp_id; /* Transaction ID */ - ushort bp_secs; /* Seconds since boot */ - ushort bp_spare1; /* Alignment */ - IPaddr_t bp_ciaddr; /* Client IP address */ - IPaddr_t bp_yiaddr; /* Your (client) IP address */ - IPaddr_t bp_siaddr; /* Server IP address */ - IPaddr_t bp_giaddr; /* Gateway IP address */ - uchar bp_chaddr[16]; /* Client hardware address */ + u8 bp_hops; /* Hop count (gateway thing) */ + u32 bp_id; /* Transaction ID */ + u16 bp_secs; /* Seconds since boot */ + u16 bp_spare1; /* Alignment */ + struct in_addr bp_ciaddr; /* Client IP address */ + struct in_addr bp_yiaddr; /* Your (client) IP address */ + struct in_addr bp_siaddr; /* Server IP address */ + struct in_addr bp_giaddr; /* Gateway IP address */ + u8 bp_chaddr[16]; /* Client hardware address */ char bp_sname[64]; /* Server host name */ char bp_file[128]; /* Boot file name */ char bp_vend[OPT_FIELD_SIZE]; /* Vendor information */ }; -#define BOOTP_HDR_SIZE sizeof(struct Bootp_t) +#define BOOTP_HDR_SIZE sizeof(struct bootp_hdr) /**********************************************************************/ /* @@ -59,17 +59,16 @@ struct Bootp_t { */ /* bootp.c */ -extern ulong BootpID; /* ID of cur BOOTP request */ -extern char BootFile[128]; /* Boot file name */ -extern int BootpTry; +extern u32 bootp_id; /* ID of cur BOOTP request */ +extern int bootp_try; /* Send a BOOTP request */ -extern void BootpReset(void); -extern void BootpRequest(void); +void bootp_reset(void); +void bootp_request(void); /****************** DHCP Support *********************/ -extern void DhcpRequest(void); +void dhcp_request(void); /* DHCP States */ typedef enum { INIT, @@ -18,7 +18,7 @@ #include "cdp.h" /* Ethernet bcast address */ -const uchar NetCDPAddr[6] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc }; +const u8 net_cdp_ethaddr[6] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc }; #define CDP_DEVICE_ID_TLV 0x0001 #define CDP_ADDRESS_TLV 0x0002 @@ -36,17 +36,16 @@ const uchar NetCDPAddr[6] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc }; #define CDP_TIMEOUT 250UL /* one packet every 250ms */ -static int CDPSeq; -static int CDPOK; +static int cdp_seq; +static int cdp_ok; -ushort CDPNativeVLAN; -ushort CDPApplianceVLAN; +ushort cdp_native_vlan; +ushort cdp_appliance_vlan; -static const uchar CDP_SNAP_hdr[8] = { +static const uchar cdp_snap_hdr[8] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x0C, 0x20, 0x00 }; -static ushort -CDP_compute_csum(const uchar *buff, ushort len) +static ushort cdp_compute_csum(const uchar *buff, ushort len) { ushort csum; int odd; @@ -104,8 +103,7 @@ CDP_compute_csum(const uchar *buff, ushort len) return csum; } -static int -CDPSendTrigger(void) +static int cdp_send_trigger(void) { uchar *pkt; ushort *s; @@ -118,20 +116,20 @@ CDPSendTrigger(void) char buf[32]; #endif - pkt = NetTxPacket; + pkt = net_tx_packet; et = (struct ethernet_hdr *)pkt; /* NOTE: trigger sent not on any VLAN */ /* form ethernet header */ - memcpy(et->et_dest, NetCDPAddr, 6); - memcpy(et->et_src, NetOurEther, 6); + memcpy(et->et_dest, net_cdp_ethaddr, 6); + memcpy(et->et_src, net_ethaddr, 6); pkt += ETHER_HDR_SIZE; /* SNAP header */ - memcpy((uchar *)pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)); - pkt += sizeof(CDP_SNAP_hdr); + memcpy((uchar *)pkt, cdp_snap_hdr, sizeof(cdp_snap_hdr)); + pkt += sizeof(cdp_snap_hdr); /* CDP header */ *pkt++ = 0x02; /* CDP version 2 */ @@ -145,7 +143,7 @@ CDPSendTrigger(void) #ifdef CONFIG_CDP_DEVICE_ID *s++ = htons(CDP_DEVICE_ID_TLV); *s++ = htons(CONFIG_CDP_DEVICE_ID); - sprintf(buf, CONFIG_CDP_DEVICE_ID_PREFIX "%pm", NetOurEther); + sprintf(buf, CONFIG_CDP_DEVICE_ID_PREFIX "%pm", net_ethaddr); memcpy((uchar *)s, buf, 16); s += 16 / 2; #endif @@ -207,34 +205,33 @@ CDPSendTrigger(void) #endif /* length of ethernet packet */ - len = (uchar *)s - ((uchar *)NetTxPacket + ETHER_HDR_SIZE); + len = (uchar *)s - ((uchar *)net_tx_packet + ETHER_HDR_SIZE); et->et_protlen = htons(len); - len = ETHER_HDR_SIZE + sizeof(CDP_SNAP_hdr); - chksum = CDP_compute_csum((uchar *)NetTxPacket + len, - (uchar *)s - (NetTxPacket + len)); + len = ETHER_HDR_SIZE + sizeof(cdp_snap_hdr); + chksum = cdp_compute_csum((uchar *)net_tx_packet + len, + (uchar *)s - (net_tx_packet + len)); if (chksum == 0) chksum = 0xFFFF; *cp = htons(chksum); - NetSendPacket(NetTxPacket, (uchar *)s - NetTxPacket); + net_send_packet(net_tx_packet, (uchar *)s - net_tx_packet); return 0; } -static void -CDPTimeout(void) +static void cdp_timeout_handler(void) { - CDPSeq++; + cdp_seq++; - if (CDPSeq < 3) { - NetSetTimeout(CDP_TIMEOUT, CDPTimeout); - CDPSendTrigger(); + if (cdp_seq < 3) { + net_set_timeout_handler(CDP_TIMEOUT, cdp_timeout_handler); + cdp_send_trigger(); return; } /* if not OK try again */ - if (!CDPOK) - NetStartAgain(); + if (!cdp_ok) + net_start_again(); else net_set_state(NETLOOP_SUCCESS); } @@ -247,15 +244,15 @@ void cdp_receive(const uchar *pkt, unsigned len) ushort vlan, nvlan; /* minimum size? */ - if (len < sizeof(CDP_SNAP_hdr) + 4) + if (len < sizeof(cdp_snap_hdr) + 4) goto pkt_short; /* check for valid CDP SNAP header */ - if (memcmp(pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)) != 0) + if (memcmp(pkt, cdp_snap_hdr, sizeof(cdp_snap_hdr)) != 0) return; - pkt += sizeof(CDP_SNAP_hdr); - len -= sizeof(CDP_SNAP_hdr); + pkt += sizeof(cdp_snap_hdr); + len -= sizeof(cdp_snap_hdr); /* Version of CDP protocol must be >= 2 and TTL != 0 */ if (pkt[0] < 0x02 || pkt[1] == 0) @@ -269,7 +266,7 @@ void cdp_receive(const uchar *pkt, unsigned len) printf("**WARNING: CDP packet received with a protocol version " "%d > 2\n", pkt[0] & 0xff); - if (CDP_compute_csum(pkt, len) != 0) + if (cdp_compute_csum(pkt, len) != 0) return; pkt += 4; @@ -340,28 +337,27 @@ void cdp_receive(const uchar *pkt, unsigned len) } } - CDPApplianceVLAN = vlan; - CDPNativeVLAN = nvlan; + cdp_appliance_vlan = vlan; + cdp_native_vlan = nvlan; - CDPOK = 1; + cdp_ok = 1; return; - pkt_short: +pkt_short: printf("** CDP packet is too short\n"); return; } -void -CDPStart(void) +void cdp_start(void) { printf("Using %s device\n", eth_get_name()); - CDPSeq = 0; - CDPOK = 0; + cdp_seq = 0; + cdp_ok = 0; - CDPNativeVLAN = htons(-1); - CDPApplianceVLAN = htons(-1); + cdp_native_vlan = htons(-1); + cdp_appliance_vlan = htons(-1); - NetSetTimeout(CDP_TIMEOUT, CDPTimeout); + net_set_timeout_handler(CDP_TIMEOUT, cdp_timeout_handler); - CDPSendTrigger(); + cdp_send_trigger(); } @@ -14,7 +14,7 @@ #ifndef __CDP_H__ #define __CDP_H__ -void CDPStart(void); +void cdp_start(void); /* Process a received CDP packet */ void cdp_receive(const uchar *pkt, unsigned len); @@ -5,7 +5,7 @@ * Copyright (c) 2009 Robin Getz <rgetz@blackfin.uclinux.org> * * This is a simple DNS implementation for U-Boot. It will use the first IP - * in the DNS response as NetServerIP. This can then be used for any other + * in the DNS response as net_server_ip. This can then be used for any other * network related activities. * * The packet handling is partly based on TADNS, original copyrights @@ -29,13 +29,12 @@ #include "dns.h" -char *NetDNSResolve; /* The host to resolve */ -char *NetDNSenvvar; /* The envvar to store the answer in */ +char *net_dns_resolve; /* The host to resolve */ +char *net_dns_env_var; /* The envvar to store the answer in */ -static int DnsOurPort; +static int dns_our_port; -static void -DnsSend(void) +static void dns_send(void) { struct header *header; int n, name_len; @@ -44,11 +43,12 @@ DnsSend(void) const char *name; enum dns_query_type qtype = DNS_A_RECORD; - name = NetDNSResolve; - pkt = p = (uchar *)(NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE); + name = net_dns_resolve; + pkt = (uchar *)(net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE); + p = pkt; /* Prepare DNS packet header */ - header = (struct header *) pkt; + header = (struct header *)pkt; header->tid = 1; header->flags = htons(0x100); /* standard query */ header->nqueries = htons(1); /* Just one query */ @@ -58,7 +58,7 @@ DnsSend(void) /* Encode DNS name */ name_len = strlen(name); - p = (uchar *) &header->data; /* For encoding host name into packet */ + p = (uchar *)&header->data; /* For encoding host name into packet */ do { s = strchr(name, '.'); @@ -87,41 +87,40 @@ DnsSend(void) n = p - pkt; /* Total packet length */ debug("Packet size %d\n", n); - DnsOurPort = random_port(); + dns_our_port = random_port(); - NetSendUDPPacket(NetServerEther, NetOurDNSIP, DNS_SERVICE_PORT, - DnsOurPort, n); + net_send_udp_packet(net_server_ethaddr, net_dns_server, + DNS_SERVICE_PORT, dns_our_port, n); debug("DNS packet sent\n"); } -static void -DnsTimeout(void) +static void dns_timeout_handler(void) { puts("Timeout\n"); net_set_state(NETLOOP_FAIL); } -static void -DnsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len) +static void dns_handler(uchar *pkt, unsigned dest, struct in_addr sip, + unsigned src, unsigned len) { struct header *header; const unsigned char *p, *e, *s; u16 type, i; int found, stop, dlen; - char IPStr[22]; - IPaddr_t IPAddress; + char ip_str[22]; + struct in_addr ip_addr; debug("%s\n", __func__); - if (dest != DnsOurPort) + if (dest != dns_our_port) return; for (i = 0; i < len; i += 4) debug("0x%p - 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", - pkt+i, pkt[i], pkt[i+1], pkt[i+2], pkt[i+3]); + pkt+i, pkt[i], pkt[i+1], pkt[i+2], pkt[i+3]); /* We sent one query. We want to have a single answer: */ - header = (struct header *) pkt; + header = (struct header *)pkt; if (ntohs(header->nqueries) != 1) return; @@ -150,7 +149,6 @@ DnsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len) /* Loop through the answers, we want A type answer */ for (found = stop = 0; !stop && &p[12] < e; ) { - /* Skip possible name in CNAME answer */ if (*p != 0xc0) { while (*p && &p[12] < e) @@ -169,7 +167,8 @@ DnsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len) p += 12 + dlen; } else if (type == DNS_A_RECORD) { debug("Found A-record\n"); - found = stop = 1; + found = 1; + stop = 1; } else { debug("Unknown type\n"); stop = 1; @@ -177,33 +176,32 @@ DnsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len) } if (found && &p[12] < e) { - dlen = get_unaligned_be16(p+10); p += 12; - memcpy(&IPAddress, p, 4); + memcpy(&ip_addr, p, 4); if (p + dlen <= e) { - ip_to_string(IPAddress, IPStr); - printf("%s\n", IPStr); - if (NetDNSenvvar) - setenv(NetDNSenvvar, IPStr); - } else + ip_to_string(ip_addr, ip_str); + printf("%s\n", ip_str); + if (net_dns_env_var) + setenv(net_dns_env_var, ip_str); + } else { puts("server responded with invalid IP number\n"); + } } net_set_state(NETLOOP_SUCCESS); } -void -DnsStart(void) +void dns_start(void) { debug("%s\n", __func__); - NetSetTimeout(DNS_TIMEOUT, DnsTimeout); - net_set_udp_handler(DnsHandler); + net_set_timeout_handler(DNS_TIMEOUT, dns_timeout_handler); + net_set_udp_handler(dns_handler); /* Clear a previous MAC address, the server IP might have changed. */ - memset(NetServerEther, 0, sizeof(NetServerEther)); + memset(net_server_ethaddr, 0, sizeof(net_server_ethaddr)); - DnsSend(); + dns_send(); } @@ -31,6 +31,6 @@ struct header { unsigned char data[1]; /* Data, variable length */ }; -extern void DnsStart(void); /* Begin DNS */ +void dns_start(void); /* Begin DNS */ #endif @@ -1,16 +1,21 @@ /* - * (C) Copyright 2001-2010 + * (C) Copyright 2001-2015 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * Joe Hershberger, National Instruments * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> #include <command.h> +#include <dm.h> #include <net.h> #include <miiphy.h> #include <phy.h> #include <asm/errno.h> +#include <dm/device-internal.h> + +DECLARE_GLOBAL_DATA_PTR; void eth_parse_enetaddr(const char *addr, uchar *enetaddr) { @@ -27,7 +32,7 @@ void eth_parse_enetaddr(const char *addr, uchar *enetaddr) int eth_getenv_enetaddr(char *name, uchar *enetaddr) { eth_parse_enetaddr(getenv(name), enetaddr); - return is_valid_ether_addr(enetaddr); + return is_valid_ethaddr(enetaddr); } int eth_setenv_enetaddr(char *name, const uchar *enetaddr) @@ -55,15 +60,28 @@ static inline int eth_setenv_enetaddr_by_index(const char *base_name, int index, return eth_setenv_enetaddr(enetvar, enetaddr); } +static void eth_env_init(void) +{ + const char *s; + + s = getenv("bootfile"); + if (s != NULL) + copy_filename(net_boot_file_name, s, + sizeof(net_boot_file_name)); +} static int eth_mac_skip(int index) { char enetvar[15]; char *skip_state; + sprintf(enetvar, index ? "eth%dmacskip" : "ethmacskip", index); - return ((skip_state = getenv(enetvar)) != NULL); + skip_state = getenv(enetvar); + return skip_state != NULL; } +static void eth_current_changed(void); + /* * CPU and board-specific Ethernet initializations. Aliased function * signals caller to move on @@ -75,6 +93,472 @@ static int __def_eth_init(bd_t *bis) int cpu_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init"))); int board_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init"))); +static void eth_common_init(void) +{ + bootstage_mark(BOOTSTAGE_ID_NET_ETH_START); +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) + miiphy_init(); +#endif + +#ifdef CONFIG_PHYLIB + phy_init(); +#endif + + eth_env_init(); + + /* + * If board-specific initialization exists, call it. + * If not, call a CPU-specific one + */ + if (board_eth_init != __def_eth_init) { + if (board_eth_init(gd->bd) < 0) + printf("Board Net Initialization Failed\n"); + } else if (cpu_eth_init != __def_eth_init) { + if (cpu_eth_init(gd->bd) < 0) + printf("CPU Net Initialization Failed\n"); + } else { + printf("Net Initialization Skipped\n"); + } +} + +#ifdef CONFIG_DM_ETH +/** + * struct eth_device_priv - private structure for each Ethernet device + * + * @state: The state of the Ethernet MAC driver (defined by enum eth_state_t) + */ +struct eth_device_priv { + enum eth_state_t state; +}; + +/** + * struct eth_uclass_priv - The structure attached to the uclass itself + * + * @current: The Ethernet device that the network functions are using + */ +struct eth_uclass_priv { + struct udevice *current; +}; + +/* eth_errno - This stores the most recent failure code from DM functions */ +static int eth_errno; + +static struct eth_uclass_priv *eth_get_uclass_priv(void) +{ + struct uclass *uc; + + uclass_get(UCLASS_ETH, &uc); + assert(uc); + return uc->priv; +} + +static void eth_set_current_to_next(void) +{ + struct eth_uclass_priv *uc_priv; + + uc_priv = eth_get_uclass_priv(); + if (uc_priv->current) + uclass_next_device(&uc_priv->current); + if (!uc_priv->current) + uclass_first_device(UCLASS_ETH, &uc_priv->current); +} + +/* + * Typically this will simply return the active device. + * In the case where the most recent active device was unset, this will attempt + * to return the first device. If that device doesn't exist or fails to probe, + * this function will return NULL. + */ +struct udevice *eth_get_dev(void) +{ + struct eth_uclass_priv *uc_priv; + + uc_priv = eth_get_uclass_priv(); + if (!uc_priv->current) + eth_errno = uclass_first_device(UCLASS_ETH, + &uc_priv->current); + return uc_priv->current; +} + +/* + * Typically this will just store a device pointer. + * In case it was not probed, we will attempt to do so. + * dev may be NULL to unset the active device. + */ +static void eth_set_dev(struct udevice *dev) +{ + if (dev && !device_active(dev)) + eth_errno = device_probe(dev); + eth_get_uclass_priv()->current = dev; +} + +/* + * Find the udevice that either has the name passed in as devname or has an + * alias named devname. + */ +struct udevice *eth_get_dev_by_name(const char *devname) +{ + int seq = -1; + char *endp = NULL; + const char *startp = NULL; + struct udevice *it; + struct uclass *uc; + + /* Must be longer than 3 to be an alias */ + if (strlen(devname) > strlen("eth")) { + startp = devname + strlen("eth"); + seq = simple_strtoul(startp, &endp, 10); + } + + uclass_get(UCLASS_ETH, &uc); + uclass_foreach_dev(it, uc) { + /* + * We need the seq to be valid, so try to probe it. + * If the probe fails, the seq will not match since it will be + * -1 instead of what we are looking for. + * We don't care about errors from probe here. Either they won't + * match an alias or it will match a literal name and we'll pick + * up the error when we try to probe again in eth_set_dev(). + */ + device_probe(it); + /* + * Check for the name or the sequence number to match + */ + if (strcmp(it->name, devname) == 0 || + (endp > startp && it->seq == seq)) + return it; + } + + return NULL; +} + +unsigned char *eth_get_ethaddr(void) +{ + struct eth_pdata *pdata; + + if (eth_get_dev()) { + pdata = eth_get_dev()->platdata; + return pdata->enetaddr; + } + + return NULL; +} + +/* Set active state without calling start on the driver */ +int eth_init_state_only(void) +{ + struct udevice *current; + struct eth_device_priv *priv; + + current = eth_get_dev(); + if (!current || !device_active(current)) + return -EINVAL; + + priv = current->uclass_priv; + priv->state = ETH_STATE_ACTIVE; + + return 0; +} + +/* Set passive state without calling stop on the driver */ +void eth_halt_state_only(void) +{ + struct udevice *current; + struct eth_device_priv *priv; + + current = eth_get_dev(); + if (!current || !device_active(current)) + return; + + priv = current->uclass_priv; + priv->state = ETH_STATE_PASSIVE; +} + +int eth_get_dev_index(void) +{ + if (eth_get_dev()) + return eth_get_dev()->seq; + return -1; +} + +int eth_init(void) +{ + struct udevice *current; + struct udevice *old_current; + int ret = -ENODEV; + + current = eth_get_dev(); + if (!current) { + printf("No ethernet found.\n"); + return -ENODEV; + } + + old_current = current; + do { + debug("Trying %s\n", current->name); + + if (device_active(current)) { + uchar env_enetaddr[6]; + struct eth_pdata *pdata = current->platdata; + + /* Sync environment with network device */ + if (eth_getenv_enetaddr_by_index("eth", current->seq, + env_enetaddr)) + memcpy(pdata->enetaddr, env_enetaddr, 6); + else + memset(pdata->enetaddr, 0, 6); + + ret = eth_get_ops(current)->start(current); + if (ret >= 0) { + struct eth_device_priv *priv = + current->uclass_priv; + + priv->state = ETH_STATE_ACTIVE; + return 0; + } + } else { + ret = eth_errno; + } + + debug("FAIL\n"); + + /* + * If ethrotate is enabled, this will change "current", + * otherwise we will drop out of this while loop immediately + */ + eth_try_another(0); + /* This will ensure the new "current" attempted to probe */ + current = eth_get_dev(); + } while (old_current != current); + + return ret; +} + +void eth_halt(void) +{ + struct udevice *current; + struct eth_device_priv *priv; + + current = eth_get_dev(); + if (!current || !device_active(current)) + return; + + eth_get_ops(current)->stop(current); + priv = current->uclass_priv; + priv->state = ETH_STATE_PASSIVE; +} + +int eth_send(void *packet, int length) +{ + struct udevice *current; + int ret; + + current = eth_get_dev(); + if (!current) + return -ENODEV; + + if (!device_active(current)) + return -EINVAL; + + ret = eth_get_ops(current)->send(current, packet, length); + if (ret < 0) { + /* We cannot completely return the error at present */ + debug("%s: send() returned error %d\n", __func__, ret); + } + return ret; +} + +int eth_rx(void) +{ + struct udevice *current; + uchar *packet; + int ret; + int i; + + current = eth_get_dev(); + if (!current) + return -ENODEV; + + if (!device_active(current)) + return -EINVAL; + + /* Process up to 32 packets at one time */ + for (i = 0; i < 32; i++) { + ret = eth_get_ops(current)->recv(current, &packet); + if (ret > 0) + net_process_received_packet(packet, ret); + if (ret >= 0 && eth_get_ops(current)->free_pkt) + eth_get_ops(current)->free_pkt(current, packet, ret); + if (ret <= 0) + break; + } + if (ret == -EAGAIN) + ret = 0; + if (ret < 0) { + /* We cannot completely return the error at present */ + debug("%s: recv() returned error %d\n", __func__, ret); + } + return ret; +} + +static int eth_write_hwaddr(struct udevice *dev) +{ + struct eth_pdata *pdata = dev->platdata; + int ret = 0; + + if (!dev || !device_active(dev)) + return -EINVAL; + + /* seq is valid since the device is active */ + if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev->seq)) { + if (!is_valid_ethaddr(pdata->enetaddr)) { + printf("\nError: %s address %pM illegal value\n", + dev->name, pdata->enetaddr); + return -EINVAL; + } + + ret = eth_get_ops(dev)->write_hwaddr(dev); + if (ret) + printf("\nWarning: %s failed to set MAC address\n", + dev->name); + } + + return ret; +} + +int eth_initialize(void) +{ + int num_devices = 0; + struct udevice *dev; + + eth_common_init(); + + /* + * Devices need to write the hwaddr even if not started so that Linux + * will have access to the hwaddr that u-boot stored for the device. + * This is accomplished by attempting to probe each device and calling + * their write_hwaddr() operation. + */ + uclass_first_device(UCLASS_ETH, &dev); + if (!dev) { + printf("No ethernet found.\n"); + bootstage_error(BOOTSTAGE_ID_NET_ETH_START); + } else { + char *ethprime = getenv("ethprime"); + struct udevice *prime_dev = NULL; + + if (ethprime) + prime_dev = eth_get_dev_by_name(ethprime); + if (prime_dev) { + eth_set_dev(prime_dev); + eth_current_changed(); + } else { + eth_set_dev(NULL); + } + + bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT); + do { + if (num_devices) + printf(", "); + + printf("eth%d: %s", dev->seq, dev->name); + + if (ethprime && dev == prime_dev) + printf(" [PRIME]"); + + eth_write_hwaddr(dev); + + uclass_next_device(&dev); + num_devices++; + } while (dev); + + putc('\n'); + } + + return num_devices; +} + +static int eth_post_bind(struct udevice *dev) +{ + if (strchr(dev->name, ' ')) { + printf("\nError: eth device name \"%s\" has a space!\n", + dev->name); + return -EINVAL; + } + + return 0; +} + +static int eth_pre_unbind(struct udevice *dev) +{ + /* Don't hang onto a pointer that is going away */ + if (dev == eth_get_uclass_priv()->current) + eth_set_dev(NULL); + + return 0; +} + +static int eth_post_probe(struct udevice *dev) +{ + struct eth_device_priv *priv = dev->uclass_priv; + struct eth_pdata *pdata = dev->platdata; + unsigned char env_enetaddr[6]; + + priv->state = ETH_STATE_INIT; + + /* Check if the device has a MAC address in ROM */ + if (eth_get_ops(dev)->read_rom_hwaddr) + eth_get_ops(dev)->read_rom_hwaddr(dev); + + eth_getenv_enetaddr_by_index("eth", dev->seq, env_enetaddr); + if (!is_zero_ethaddr(env_enetaddr)) { + if (!is_zero_ethaddr(pdata->enetaddr) && + memcmp(pdata->enetaddr, env_enetaddr, 6)) { + printf("\nWarning: %s MAC addresses don't match:\n", + dev->name); + printf("Address in SROM is %pM\n", + pdata->enetaddr); + printf("Address in environment is %pM\n", + env_enetaddr); + } + + /* Override the ROM MAC address */ + memcpy(pdata->enetaddr, env_enetaddr, 6); + } else if (is_valid_ethaddr(pdata->enetaddr)) { + eth_setenv_enetaddr_by_index("eth", dev->seq, pdata->enetaddr); + printf("\nWarning: %s using MAC address from ROM\n", + dev->name); + } else if (is_zero_ethaddr(pdata->enetaddr)) { + printf("\nError: %s address not set.\n", + dev->name); + return -EINVAL; + } + + return 0; +} + +static int eth_pre_remove(struct udevice *dev) +{ + eth_get_ops(dev)->stop(dev); + + return 0; +} + +UCLASS_DRIVER(eth) = { + .name = "eth", + .id = UCLASS_ETH, + .post_bind = eth_post_bind, + .pre_unbind = eth_pre_unbind, + .post_probe = eth_post_probe, + .pre_remove = eth_pre_remove, + .priv_auto_alloc_size = sizeof(struct eth_uclass_priv), + .per_device_auto_alloc_size = sizeof(struct eth_device_priv), + .flags = DM_UC_FLAG_SEQ_ALIAS, +}; +#endif + +#ifndef CONFIG_DM_ETH + #ifdef CONFIG_API static struct { uchar data[PKTSIZE]; @@ -87,6 +571,16 @@ static unsigned int eth_rcv_current, eth_rcv_last; static struct eth_device *eth_devices; struct eth_device *eth_current; +static void eth_set_current_to_next(void) +{ + eth_current = eth_current->next; +} + +static void eth_set_dev(struct eth_device *dev) +{ + eth_current = dev; +} + struct eth_device *eth_get_dev_by_name(const char *devname) { struct eth_device *dev, *target_dev; @@ -137,27 +631,6 @@ int eth_get_dev_index(void) return eth_current->index; } -static void eth_current_changed(void) -{ - char *act = getenv("ethact"); - /* update current ethernet name */ - if (eth_current) { - if (act == NULL || strcmp(act, eth_current->name) != 0) - setenv("ethact", eth_current->name); - } - /* - * remove the variable completely if there is no active - * interface - */ - else if (act != NULL) - setenv("ethact", NULL); -} - -static int eth_address_set(unsigned char *addr) -{ - return memcmp(addr, "\0\0\0\0\0\0", 6); -} - int eth_write_hwaddr(struct eth_device *dev, const char *base_name, int eth_number) { @@ -166,39 +639,40 @@ int eth_write_hwaddr(struct eth_device *dev, const char *base_name, eth_getenv_enetaddr_by_index(base_name, eth_number, env_enetaddr); - if (eth_address_set(env_enetaddr)) { - if (eth_address_set(dev->enetaddr) && - memcmp(dev->enetaddr, env_enetaddr, 6)) { + if (!is_zero_ethaddr(env_enetaddr)) { + if (!is_zero_ethaddr(dev->enetaddr) && + memcmp(dev->enetaddr, env_enetaddr, 6)) { printf("\nWarning: %s MAC addresses don't match:\n", - dev->name); + dev->name); printf("Address in SROM is %pM\n", - dev->enetaddr); + dev->enetaddr); printf("Address in environment is %pM\n", - env_enetaddr); + env_enetaddr); } memcpy(dev->enetaddr, env_enetaddr, 6); - } else if (is_valid_ether_addr(dev->enetaddr)) { + } else if (is_valid_ethaddr(dev->enetaddr)) { eth_setenv_enetaddr_by_index(base_name, eth_number, dev->enetaddr); printf("\nWarning: %s using MAC address from net device\n", - dev->name); - } else if (!(eth_address_set(dev->enetaddr))) { + dev->name); + } else if (is_zero_ethaddr(dev->enetaddr)) { printf("\nError: %s address not set.\n", dev->name); return -EINVAL; } if (dev->write_hwaddr && !eth_mac_skip(eth_number)) { - if (!is_valid_ether_addr(dev->enetaddr)) { + if (!is_valid_ethaddr(dev->enetaddr)) { printf("\nError: %s address %pM illegal value\n", - dev->name, dev->enetaddr); + dev->name, dev->enetaddr); return -EINVAL; } ret = dev->write_hwaddr(dev); if (ret) - printf("\nWarning: %s failed to set MAC address\n", dev->name); + printf("\nWarning: %s failed to set MAC address\n", + dev->name); } return ret; @@ -212,7 +686,8 @@ int eth_register(struct eth_device *dev) assert(strlen(dev->name) < sizeof(dev->name)); if (!eth_devices) { - eth_current = eth_devices = dev; + eth_devices = dev; + eth_current = dev; eth_current_changed(); } else { for (d = eth_devices; d->next != eth_devices; d = d->next) @@ -233,7 +708,7 @@ int eth_unregister(struct eth_device *dev) /* No device */ if (!eth_devices) - return -1; + return -ENODEV; for (cur = eth_devices; cur->next != eth_devices && cur->next != dev; cur = cur->next) @@ -241,7 +716,7 @@ int eth_unregister(struct eth_device *dev) /* Device not found */ if (cur->next != dev) - return -1; + return -ENODEV; cur->next = dev->next; @@ -256,43 +731,13 @@ int eth_unregister(struct eth_device *dev) return 0; } -static void eth_env_init(bd_t *bis) -{ - const char *s; - - if ((s = getenv("bootfile")) != NULL) - copy_filename(BootFile, s, sizeof(BootFile)); -} - -int eth_initialize(bd_t *bis) +int eth_initialize(void) { int num_devices = 0; + eth_devices = NULL; eth_current = NULL; - - bootstage_mark(BOOTSTAGE_ID_NET_ETH_START); -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) - miiphy_init(); -#endif - -#ifdef CONFIG_PHYLIB - phy_init(); -#endif - - eth_env_init(bis); - - /* - * If board-specific initialization exists, call it. - * If not, call a CPU-specific one - */ - if (board_eth_init != __def_eth_init) { - if (board_eth_init(bis) < 0) - printf("Board Net Initialization Failed\n"); - } else if (cpu_eth_init != __def_eth_init) { - if (cpu_eth_init(bis) < 0) - printf("CPU Net Initialization Failed\n"); - } else - printf("Net Initialization Skipped\n"); + eth_common_init(); if (!eth_devices) { puts("No ethernet found.\n"); @@ -335,14 +780,14 @@ int eth_initialize(bd_t *bis) * mcast_addr: multicast ipaddr from which multicast Mac is made * join: 1=join, 0=leave. */ -int eth_mcast_join(IPaddr_t mcast_ip, u8 join) +int eth_mcast_join(struct in_addr mcast_ip, int join) { u8 mcast_mac[6]; if (!eth_current || !eth_current->mcast) return -1; - mcast_mac[5] = htonl(mcast_ip) & 0xff; - mcast_mac[4] = (htonl(mcast_ip)>>8) & 0xff; - mcast_mac[3] = (htonl(mcast_ip)>>16) & 0x7f; + mcast_mac[5] = htonl(mcast_ip.s_addr) & 0xff; + mcast_mac[4] = (htonl(mcast_ip.s_addr)>>8) & 0xff; + mcast_mac[3] = (htonl(mcast_ip.s_addr)>>16) & 0x7f; mcast_mac[2] = 0x5e; mcast_mac[1] = 0x0; mcast_mac[0] = 0x1; @@ -376,13 +821,13 @@ u32 ether_crc(size_t len, unsigned char const *p) #endif -int eth_init(bd_t *bis) +int eth_init(void) { struct eth_device *old_current, *dev; if (!eth_current) { puts("No ethernet found.\n"); - return -1; + return -ENODEV; } /* Sync environment with network devices */ @@ -401,7 +846,7 @@ int eth_init(bd_t *bis) do { debug("Trying %s\n", eth_current->name); - if (eth_current->init(eth_current, bis) >= 0) { + if (eth_current->init(eth_current, gd->bd) >= 0) { eth_current->state = ETH_STATE_ACTIVE; return 0; @@ -411,7 +856,7 @@ int eth_init(bd_t *bis) eth_try_another(0); } while (old_current != eth_current); - return -1; + return -ETIMEDOUT; } void eth_halt(void) @@ -427,7 +872,7 @@ void eth_halt(void) int eth_send(void *packet, int length) { if (!eth_current) - return -1; + return -ENODEV; return eth_current->send(eth_current, packet, length); } @@ -435,10 +880,11 @@ int eth_send(void *packet, int length) int eth_rx(void) { if (!eth_current) - return -1; + return -ENODEV; return eth_current->recv(eth_current); } +#endif /* ifndef CONFIG_DM_ETH */ #ifdef CONFIG_API static void eth_save_packet(void *packet, int length) @@ -484,9 +930,25 @@ int eth_receive(void *packet, int length) } #endif /* CONFIG_API */ +static void eth_current_changed(void) +{ + char *act = getenv("ethact"); + /* update current ethernet name */ + if (eth_get_dev()) { + if (act == NULL || strcmp(act, eth_get_name()) != 0) + setenv("ethact", eth_get_name()); + } + /* + * remove the variable completely if there is no active + * interface + */ + else if (act != NULL) + setenv("ethact", NULL); +} + void eth_try_another(int first_restart) { - static struct eth_device *first_failed; + static void *first_failed; char *ethrotate; /* @@ -497,48 +959,50 @@ void eth_try_another(int first_restart) if ((ethrotate != NULL) && (strcmp(ethrotate, "no") == 0)) return; - if (!eth_current) + if (!eth_get_dev()) return; if (first_restart) - first_failed = eth_current; + first_failed = eth_get_dev(); - eth_current = eth_current->next; + eth_set_current_to_next(); eth_current_changed(); - if (first_failed == eth_current) - NetRestartWrap = 1; + if (first_failed == eth_get_dev()) + net_restart_wrap = 1; } void eth_set_current(void) { static char *act; static int env_changed_id; - struct eth_device *old_current; int env_id; - if (!eth_current) /* XXX no current */ - return; - env_id = get_env_id(); if ((act == NULL) || (env_changed_id != env_id)) { act = getenv("ethact"); env_changed_id = env_id; } - if (act != NULL) { - old_current = eth_current; - do { - if (strcmp(eth_current->name, act) == 0) - return; - eth_current = eth_current->next; - } while (old_current != eth_current); + + if (act == NULL) { + char *ethprime = getenv("ethprime"); + void *dev = NULL; + + if (ethprime) + dev = eth_get_dev_by_name(ethprime); + if (dev) + eth_set_dev(dev); + else + eth_set_dev(NULL); + } else { + eth_set_dev(eth_get_dev_by_name(act)); } eth_current_changed(); } -char *eth_get_name(void) +const char *eth_get_name(void) { - return eth_current ? eth_current->name : "unknown"; + return eth_get_dev() ? eth_get_dev()->name : "unknown"; } diff --git a/net/link_local.c b/net/link_local.c index 4152fae..27851b6 100644 --- a/net/link_local.c +++ b/net/link_local.c @@ -49,7 +49,7 @@ static enum ll_state_t { DISABLED } state = DISABLED; -static IPaddr_t ip; +static struct in_addr ip; static int timeout_ms = -1; static unsigned deadline_ms; static unsigned conflicts; @@ -64,14 +64,16 @@ static void link_local_timeout(void); * Pick a random link local IP address on 169.254/16, except that * the first and last 256 addresses are reserved. */ -static IPaddr_t pick(void) +static struct in_addr pick(void) { unsigned tmp; + struct in_addr ip; do { tmp = rand_r(&seed) & IN_CLASSB_HOST; } while (tmp > (IN_CLASSB_HOST - 0x0200)); - return (IPaddr_t) htonl((LINKLOCAL_ADDR + 0x0100) + tmp); + ip.s_addr = htonl((LINKLOCAL_ADDR + 0x0100) + tmp); + return ip; } /** @@ -95,23 +97,24 @@ static void configure_wait(void) deadline_ms = MONOTONIC_MS() + timeout_ms; debug_cond(DEBUG_DEV_PKT, "...wait %d %s nprobes=%u, nclaims=%u\n", - timeout_ms, eth_get_name(), nprobes, nclaims); + timeout_ms, eth_get_name(), nprobes, nclaims); - NetSetTimeout(timeout_ms, link_local_timeout); + net_set_timeout_handler(timeout_ms, link_local_timeout); } void link_local_start(void) { - ip = getenv_IPaddr("llipaddr"); - if (ip != 0 && (ntohl(ip) & IN_CLASSB_NET) != LINKLOCAL_ADDR) { + ip = getenv_ip("llipaddr"); + if (ip.s_addr != 0 && + (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR) { puts("invalid link address"); net_set_state(NETLOOP_FAIL); return; } - NetOurSubnetMask = IN_CLASSB_NET; + net_netmask.s_addr = IN_CLASSB_NET; seed = seed_mac(); - if (ip == 0) + if (ip.s_addr == 0) ip = pick(); state = PROBE; @@ -131,10 +134,12 @@ static void link_local_timeout(void) /* timeouts in the PROBE state mean no conflicting ARP packets have been received, so we can progress through the states */ if (nprobes < PROBE_NUM) { + struct in_addr zero_ip = {.s_addr = 0}; + nprobes++; debug_cond(DEBUG_LL_STATE, "probe/%u %s@%pI4\n", - nprobes, eth_get_name(), &ip); - arp_raw_request(0, NetEtherNullAddr, ip); + nprobes, eth_get_name(), &ip); + arp_raw_request(zero_ip, net_null_ethaddr, ip); timeout_ms = PROBE_MIN * 1000; timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); } else { @@ -142,8 +147,8 @@ static void link_local_timeout(void) state = ANNOUNCE; nclaims = 0; debug_cond(DEBUG_LL_STATE, "announce/%u %s@%pI4\n", - nclaims, eth_get_name(), &ip); - arp_raw_request(ip, NetOurEther, ip); + nclaims, eth_get_name(), &ip); + arp_raw_request(ip, net_ethaddr, ip); timeout_ms = ANNOUNCE_INTERVAL * 1000; } break; @@ -154,8 +159,8 @@ static void link_local_timeout(void) state = ANNOUNCE; nclaims = 0; debug_cond(DEBUG_LL_STATE, "announce/%u %s@%pI4\n", - nclaims, eth_get_name(), &ip); - arp_raw_request(ip, NetOurEther, ip); + nclaims, eth_get_name(), &ip); + arp_raw_request(ip, net_ethaddr, ip); timeout_ms = ANNOUNCE_INTERVAL * 1000; break; case ANNOUNCE: @@ -165,19 +170,19 @@ static void link_local_timeout(void) if (nclaims < ANNOUNCE_NUM) { nclaims++; debug_cond(DEBUG_LL_STATE, "announce/%u %s@%pI4\n", - nclaims, eth_get_name(), &ip); - arp_raw_request(ip, NetOurEther, ip); + nclaims, eth_get_name(), &ip); + arp_raw_request(ip, net_ethaddr, ip); timeout_ms = ANNOUNCE_INTERVAL * 1000; } else { /* Switch to monitor state */ state = MONITOR; printf("Successfully assigned %pI4\n", &ip); - NetCopyIP(&NetOurIP, &ip); + net_copy_ip(&net_ip, &ip); ready = 1; conflicts = 0; timeout_ms = -1; /* Never timeout in the monitor state */ - NetSetTimeout(0, NULL); + net_set_timeout_handler(0, NULL); /* NOTE: all other exit paths should deconfig ... */ net_set_state(NETLOOP_SUCCESS); @@ -206,7 +211,7 @@ void link_local_receive_arp(struct arp_hdr *arp, int len) { int source_ip_conflict; int target_ip_conflict; - IPaddr_t null_ip = 0; + struct in_addr null_ip = {.s_addr = 0}; if (state == DISABLED) return; @@ -219,7 +224,7 @@ void link_local_receive_arp(struct arp_hdr *arp, int len) /* Current time is greater than the expected timeout time. This should never happen */ debug_cond(DEBUG_LL_STATE, - "missed an expected timeout\n"); + "missed an expected timeout\n"); timeout_ms = 0; } else { debug_cond(DEBUG_INT_STATE, "adjusting timeout\n"); @@ -234,9 +239,8 @@ void link_local_receive_arp(struct arp_hdr *arp, int len) * FIXME: links routinely go down; */ bb_error_msg("iface %s is down", eth_get_name()); - if (ready) { + if (ready) run(argv, "deconfig", &ip); - } return EXIT_FAILURE; } continue; @@ -244,18 +248,17 @@ void link_local_receive_arp(struct arp_hdr *arp, int len) #endif debug_cond(DEBUG_INT_STATE, "%s recv arp type=%d, op=%d,\n", - eth_get_name(), ntohs(arp->ar_pro), - ntohs(arp->ar_op)); + eth_get_name(), ntohs(arp->ar_pro), + ntohs(arp->ar_op)); debug_cond(DEBUG_INT_STATE, "\tsource=%pM %pI4\n", - &arp->ar_sha, - &arp->ar_spa); + &arp->ar_sha, + &arp->ar_spa); debug_cond(DEBUG_INT_STATE, "\ttarget=%pM %pI4\n", - &arp->ar_tha, - &arp->ar_tpa); + &arp->ar_tha, + &arp->ar_tpa); - if (arp->ar_op != htons(ARPOP_REQUEST) - && arp->ar_op != htons(ARPOP_REPLY) - ) { + if (arp->ar_op != htons(ARPOP_REQUEST) && + arp->ar_op != htons(ARPOP_REPLY)) { configure_wait(); return; } @@ -263,11 +266,9 @@ void link_local_receive_arp(struct arp_hdr *arp, int len) source_ip_conflict = 0; target_ip_conflict = 0; - if (memcmp(&arp->ar_spa, &ip, ARP_PLEN) == 0 - && memcmp(&arp->ar_sha, NetOurEther, ARP_HLEN) != 0 - ) { + if (memcmp(&arp->ar_spa, &ip, ARP_PLEN) == 0 && + memcmp(&arp->ar_sha, net_ethaddr, ARP_HLEN) != 0) source_ip_conflict = 1; - } /* * According to RFC 3927, section 2.2.1: @@ -279,13 +280,13 @@ void link_local_receive_arp(struct arp_hdr *arp, int len) if (arp->ar_op == htons(ARPOP_REQUEST) && memcmp(&arp->ar_spa, &null_ip, ARP_PLEN) == 0 && memcmp(&arp->ar_tpa, &ip, ARP_PLEN) == 0 && - memcmp(&arp->ar_sha, NetOurEther, ARP_HLEN) != 0) { + memcmp(&arp->ar_sha, net_ethaddr, ARP_HLEN) != 0) { target_ip_conflict = 1; } debug_cond(DEBUG_NET_PKT, - "state = %d, source ip conflict = %d, target ip conflict = " - "%d\n", state, source_ip_conflict, target_ip_conflict); + "state = %d, source ip conflict = %d, target ip conflict = " + "%d\n", state, source_ip_conflict, target_ip_conflict); switch (state) { case PROBE: case ANNOUNCE: @@ -313,7 +314,7 @@ void link_local_receive_arp(struct arp_hdr *arp, int len) debug("monitor conflict -- defending\n"); state = DEFEND; timeout_ms = DEFEND_INTERVAL * 1000; - arp_raw_request(ip, NetOurEther, ip); + arp_raw_request(ip, net_ethaddr, ip); } break; case DEFEND: @@ -322,7 +323,7 @@ void link_local_receive_arp(struct arp_hdr *arp, int len) state = PROBE; debug("defend conflict -- starting over\n"); ready = 0; - NetOurIP = 0; + net_ip.s_addr = 0; /* restart the whole protocol */ ip = pick(); @@ -84,6 +84,7 @@ #include <common.h> #include <command.h> #include <environment.h> +#include <errno.h> #include <net.h> #if defined(CONFIG_STATUS_LED) #include <miiphy.h> @@ -111,82 +112,74 @@ DECLARE_GLOBAL_DATA_PTR; /** BOOTP EXTENTIONS **/ /* Our subnet mask (0=unknown) */ -IPaddr_t NetOurSubnetMask; +struct in_addr net_netmask; /* Our gateways IP address */ -IPaddr_t NetOurGatewayIP; +struct in_addr net_gateway; /* Our DNS IP address */ -IPaddr_t NetOurDNSIP; +struct in_addr net_dns_server; #if defined(CONFIG_BOOTP_DNS2) /* Our 2nd DNS IP address */ -IPaddr_t NetOurDNS2IP; +struct in_addr net_dns_server2; #endif -/* Our NIS domain */ -char NetOurNISDomain[32] = {0,}; -/* Our hostname */ -char NetOurHostName[32] = {0,}; -/* Our bootpath */ -char NetOurRootPath[64] = {0,}; -/* Our bootfile size in blocks */ -ushort NetBootFileSize; #ifdef CONFIG_MCAST_TFTP /* Multicast TFTP */ -IPaddr_t Mcast_addr; +struct in_addr net_mcast_addr; #endif /** END OF BOOTP EXTENTIONS **/ -/* The actual transferred size of the bootfile (in bytes) */ -ulong NetBootFileXferSize; /* Our ethernet address */ -uchar NetOurEther[6]; +u8 net_ethaddr[6]; /* Boot server enet address */ -uchar NetServerEther[6]; +u8 net_server_ethaddr[6]; /* Our IP addr (0 = unknown) */ -IPaddr_t NetOurIP; +struct in_addr net_ip; /* Server IP addr (0 = unknown) */ -IPaddr_t NetServerIP; +struct in_addr net_server_ip; /* Current receive packet */ -uchar *NetRxPacket; +uchar *net_rx_packet; /* Current rx packet length */ -int NetRxPacketLen; +int net_rx_packet_len; /* IP packet ID */ -unsigned NetIPID; +static unsigned net_ip_id; /* Ethernet bcast address */ -uchar NetBcastAddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -uchar NetEtherNullAddr[6]; +const u8 net_bcast_ethaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +const u8 net_null_ethaddr[6]; #ifdef CONFIG_API -void (*push_packet)(void *, int len) = 0; +void (*push_packet)(void *, int len) = 0; #endif /* Network loop state */ enum net_loop_state net_state; /* Tried all network devices */ -int NetRestartWrap; +int net_restart_wrap; /* Network loop restarted */ -static int NetRestarted; +static int net_restarted; /* At least one device configured */ -static int NetDevExists; +static int net_dev_exists; /* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */ /* default is without VLAN */ -ushort NetOurVLAN = 0xFFFF; +ushort net_our_vlan = 0xFFFF; /* ditto */ -ushort NetOurNativeVLAN = 0xFFFF; +ushort net_native_vlan = 0xFFFF; /* Boot File name */ -char BootFile[128]; +char net_boot_file_name[128]; +/* The actual transferred size of the bootfile (in bytes) */ +u32 net_boot_file_size; +/* Boot file size in blocks as reported by the DHCP server */ +u32 net_boot_file_expected_size_in_blocks; #if defined(CONFIG_CMD_SNTP) /* NTP server IP address */ -IPaddr_t NetNtpServerIP; +struct in_addr net_ntp_server; /* offset time from UTC */ -int NetTimeOffset; +int net_ntp_time_offset; #endif -static uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN]; - -/* Receive packet */ -uchar *NetRxPackets[PKTBUFSRX]; - +static uchar net_pkt_buf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN]; +/* Receive packets */ +uchar *net_rx_packets[PKTBUFSRX]; /* Current UDP RX packet handler */ static rxhand_f *udp_packet_handler; /* Current ARP RX packet handler */ @@ -196,17 +189,17 @@ static rxhand_f *arp_packet_handler; static rxhand_icmp_f *packet_icmp_handler; #endif /* Current timeout handler */ -static thand_f *timeHandler; +static thand_f *time_handler; /* Time base value */ -static ulong timeStart; +static ulong time_start; /* Current timeout value */ -static ulong timeDelta; +static ulong time_delta; /* THE transmit packet */ -uchar *NetTxPacket; +uchar *net_tx_packet; static int net_check_prereq(enum proto_t protocol); -static int NetTryCount; +static int net_try_count; int __maybe_unused net_busy_flag; @@ -218,7 +211,8 @@ static int on_bootfile(const char *name, const char *value, enum env_op op, switch (op) { case env_op_create: case env_op_overwrite: - copy_filename(BootFile, value, sizeof(BootFile)); + copy_filename(net_boot_file_name, value, + sizeof(net_boot_file_name)); break; default: break; @@ -241,7 +235,7 @@ void net_auto_load(void) /* * Use NFS to load the bootfile. */ - NfsStart(); + nfs_start(); return; } #endif @@ -253,29 +247,29 @@ void net_auto_load(void) net_set_state(NETLOOP_SUCCESS); return; } - TftpStart(TFTPGET); + tftp_start(TFTPGET); } -static void NetInitLoop(void) +static void net_init_loop(void) { static int env_changed_id; int env_id = get_env_id(); /* update only when the environment has changed */ if (env_changed_id != env_id) { - NetOurIP = getenv_IPaddr("ipaddr"); - NetOurGatewayIP = getenv_IPaddr("gatewayip"); - NetOurSubnetMask = getenv_IPaddr("netmask"); - NetServerIP = getenv_IPaddr("serverip"); - NetOurNativeVLAN = getenv_VLAN("nvlan"); - NetOurVLAN = getenv_VLAN("vlan"); + net_ip = getenv_ip("ipaddr"); + net_gateway = getenv_ip("gatewayip"); + net_netmask = getenv_ip("netmask"); + net_server_ip = getenv_ip("serverip"); + net_native_vlan = getenv_vlan("nvlan"); + net_our_vlan = getenv_vlan("vlan"); #if defined(CONFIG_CMD_DNS) - NetOurDNSIP = getenv_IPaddr("dnsip"); + net_dns_server = getenv_ip("dnsip"); #endif env_changed_id = env_id; } if (eth_get_dev()) - memcpy(NetOurEther, eth_get_dev()->enetaddr, 6); + memcpy(net_ethaddr, eth_get_ethaddr(), 6); return; } @@ -284,7 +278,7 @@ static void net_clear_handlers(void) { net_set_udp_handler(NULL); net_set_arp_handler(NULL); - NetSetTimeout(0, NULL); + net_set_timeout_handler(0, NULL); } static void net_cleanup_loop(void) @@ -302,19 +296,20 @@ void net_init(void) */ int i; - NetTxPacket = &PktBuf[0] + (PKTALIGN - 1); - NetTxPacket -= (ulong)NetTxPacket % PKTALIGN; - for (i = 0; i < PKTBUFSRX; i++) - NetRxPackets[i] = NetTxPacket + (i + 1) * PKTSIZE_ALIGN; - - ArpInit(); + net_tx_packet = &net_pkt_buf[0] + (PKTALIGN - 1); + net_tx_packet -= (ulong)net_tx_packet % PKTALIGN; + for (i = 0; i < PKTBUFSRX; i++) { + net_rx_packets[i] = net_tx_packet + + (i + 1) * PKTSIZE_ALIGN; + } + arp_init(); net_clear_handlers(); /* Only need to setup buffer pointers once. */ first_call = 0; } - NetInitLoop(); + net_init_loop(); } /**********************************************************************/ @@ -322,28 +317,28 @@ void net_init(void) * Main network processing loop. */ -int NetLoop(enum proto_t protocol) +int net_loop(enum proto_t protocol) { - bd_t *bd = gd->bd; - int ret = -1; + int ret = -EINVAL; - NetRestarted = 0; - NetDevExists = 0; - NetTryCount = 1; - debug_cond(DEBUG_INT_STATE, "--- NetLoop Entry\n"); + net_restarted = 0; + net_dev_exists = 0; + net_try_count = 1; + debug_cond(DEBUG_INT_STATE, "--- net_loop Entry\n"); bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); net_init(); if (eth_is_on_demand_init() || protocol != NETCONS) { eth_halt(); eth_set_current(); - if (eth_init(bd) < 0) { + ret = eth_init(); + if (ret < 0) { eth_halt(); - return -1; + return ret; } - } else - eth_init_state_only(bd); - + } else { + eth_init_state_only(); + } restart: #ifdef CONFIG_USB_KEYBOARD net_busy_flag = 0; @@ -355,54 +350,54 @@ restart: * here on, this code is a state machine driven by received * packets and timer events. */ - debug_cond(DEBUG_INT_STATE, "--- NetLoop Init\n"); - NetInitLoop(); + debug_cond(DEBUG_INT_STATE, "--- net_loop Init\n"); + net_init_loop(); switch (net_check_prereq(protocol)) { case 1: /* network not configured */ eth_halt(); - return -1; + return -ENODEV; case 2: /* network device not configured */ break; case 0: - NetDevExists = 1; - NetBootFileXferSize = 0; + net_dev_exists = 1; + net_boot_file_size = 0; switch (protocol) { case TFTPGET: #ifdef CONFIG_CMD_TFTPPUT case TFTPPUT: #endif /* always use ARP to get server ethernet address */ - TftpStart(protocol); + tftp_start(protocol); break; #ifdef CONFIG_CMD_TFTPSRV case TFTPSRV: - TftpStartServer(); + tftp_start_server(); break; #endif #if defined(CONFIG_CMD_DHCP) case DHCP: - BootpReset(); - NetOurIP = 0; - DhcpRequest(); /* Basically same as BOOTP */ + bootp_reset(); + net_ip.s_addr = 0; + dhcp_request(); /* Basically same as BOOTP */ break; #endif case BOOTP: - BootpReset(); - NetOurIP = 0; - BootpRequest(); + bootp_reset(); + net_ip.s_addr = 0; + bootp_request(); break; #if defined(CONFIG_CMD_RARP) case RARP: - RarpTry = 0; - NetOurIP = 0; - RarpRequest(); + rarp_try = 0; + net_ip.s_addr = 0; + rarp_request(); break; #endif #if defined(CONFIG_CMD_PING) @@ -412,27 +407,27 @@ restart: #endif #if defined(CONFIG_CMD_NFS) case NFS: - NfsStart(); + nfs_start(); break; #endif #if defined(CONFIG_CMD_CDP) case CDP: - CDPStart(); + cdp_start(); break; #endif -#if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD) +#if defined(CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD) case NETCONS: - NcStart(); + nc_start(); break; #endif #if defined(CONFIG_CMD_SNTP) case SNTP: - SntpStart(); + sntp_start(); break; #endif #if defined(CONFIG_CMD_DNS) case DNS: - DnsStart(); + dns_start(); break; #endif #if defined(CONFIG_CMD_LINK_LOCAL) @@ -476,6 +471,8 @@ restart: /* * Check the ethernet for a new packet. The ethernet * receive routine will process it. + * Most drivers return the most recent packet size, but not + * errors that may have happened. */ eth_rx(); @@ -484,7 +481,7 @@ restart: */ if (ctrlc()) { /* cancel any ARP that may not have completed */ - NetArpWaitPacketIP = 0; + net_arp_wait_packet_ip.s_addr = 0; net_cleanup_loop(); eth_halt(); @@ -494,17 +491,18 @@ restart: puts("\nAbort\n"); /* include a debug print as well incase the debug messages are directed to stderr */ - debug_cond(DEBUG_INT_STATE, "--- NetLoop Abort!\n"); + debug_cond(DEBUG_INT_STATE, "--- net_loop Abort!\n"); goto done; } - ArpTimeoutCheck(); + arp_timeout_check(); /* * Check for a timeout, and run the timeout handler * if we have one. */ - if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) { + if (time_handler && + ((get_timer(0) - time_start) > time_delta)) { thand_f *x; #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) @@ -515,33 +513,32 @@ restart: * Echo the inverted link state to the fault LED. */ if (miiphy_link(eth_get_dev()->name, - CONFIG_SYS_FAULT_MII_ADDR)) { + CONFIG_SYS_FAULT_MII_ADDR)) status_led_set(STATUS_LED_RED, STATUS_LED_OFF); - } else { + else status_led_set(STATUS_LED_RED, STATUS_LED_ON); - } #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */ #endif /* CONFIG_MII, ... */ - debug_cond(DEBUG_INT_STATE, "--- NetLoop timeout\n"); - x = timeHandler; - timeHandler = (thand_f *)0; + debug_cond(DEBUG_INT_STATE, "--- net_loop timeout\n"); + x = time_handler; + time_handler = (thand_f *)0; (*x)(); } + if (net_state == NETLOOP_FAIL) + ret = net_start_again(); switch (net_state) { - case NETLOOP_RESTART: - NetRestarted = 1; + net_restarted = 1; goto restart; case NETLOOP_SUCCESS: net_cleanup_loop(); - if (NetBootFileXferSize > 0) { - printf("Bytes transferred = %ld (%lx hex)\n", - NetBootFileXferSize, - NetBootFileXferSize); - setenv_hex("filesize", NetBootFileXferSize); + if (net_boot_file_size > 0) { + printf("Bytes transferred = %d (%x hex)\n", + net_boot_file_size, net_boot_file_size); + setenv_hex("filesize", net_boot_file_size); setenv_hex("fileaddr", load_addr); } if (protocol != NETCONS) @@ -551,15 +548,15 @@ restart: eth_set_last_protocol(protocol); - ret = NetBootFileXferSize; - debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n"); + ret = net_boot_file_size; + debug_cond(DEBUG_INT_STATE, "--- net_loop 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"); + debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!\n"); goto done; case NETLOOP_CONTINUE: @@ -581,17 +578,17 @@ done: /**********************************************************************/ -static void -startAgainTimeout(void) +static void start_again_timeout_handler(void) { net_set_state(NETLOOP_RESTART); } -void NetStartAgain(void) +int net_start_again(void) { char *nretry; int retry_forever = 0; unsigned long retrycnt = 0; + int ret; nretry = getenv("netretry"); if (nretry) { @@ -603,26 +600,33 @@ void NetStartAgain(void) retrycnt = 1; else retrycnt = simple_strtoul(nretry, NULL, 0); - } else - retry_forever = 1; + } else { + retrycnt = 0; + retry_forever = 0; + } - if ((!retry_forever) && (NetTryCount >= retrycnt)) { + if ((!retry_forever) && (net_try_count >= retrycnt)) { eth_halt(); net_set_state(NETLOOP_FAIL); - return; + /* + * We don't provide a way for the protocol to return an error, + * but this is almost always the reason. + */ + return -ETIMEDOUT; } - NetTryCount++; + net_try_count++; eth_halt(); #if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER) - eth_try_another(!NetRestarted); + eth_try_another(!net_restarted); #endif - eth_init(gd->bd); - if (NetRestartWrap) { - NetRestartWrap = 0; - if (NetDevExists) { - NetSetTimeout(10000UL, startAgainTimeout); + ret = eth_init(); + if (net_restart_wrap) { + net_restart_wrap = 0; + if (net_dev_exists) { + net_set_timeout_handler(10000UL, + start_again_timeout_handler); net_set_udp_handler(NULL); } else { net_set_state(NETLOOP_FAIL); @@ -630,6 +634,7 @@ void NetStartAgain(void) } else { net_set_state(NETLOOP_RESTART); } + return ret; } /**********************************************************************/ @@ -638,7 +643,7 @@ void NetStartAgain(void) */ static void dummy_handler(uchar *pkt, unsigned dport, - IPaddr_t sip, unsigned sport, + struct in_addr sip, unsigned sport, unsigned len) { } @@ -650,7 +655,7 @@ rxhand_f *net_get_udp_handler(void) void net_set_udp_handler(rxhand_f *f) { - debug_cond(DEBUG_INT_STATE, "--- NetLoop UDP handler set (%p)\n", f); + debug_cond(DEBUG_INT_STATE, "--- net_loop UDP handler set (%p)\n", f); if (f == NULL) udp_packet_handler = dummy_handler; else @@ -664,7 +669,7 @@ rxhand_f *net_get_arp_handler(void) void net_set_arp_handler(rxhand_f *f) { - debug_cond(DEBUG_INT_STATE, "--- NetLoop ARP handler set (%p)\n", f); + debug_cond(DEBUG_INT_STATE, "--- net_loop ARP handler set (%p)\n", f); if (f == NULL) arp_packet_handler = dummy_handler; else @@ -678,69 +683,68 @@ void net_set_icmp_handler(rxhand_icmp_f *f) } #endif -void -NetSetTimeout(ulong iv, thand_f *f) +void net_set_timeout_handler(ulong iv, thand_f *f) { if (iv == 0) { debug_cond(DEBUG_INT_STATE, - "--- NetLoop timeout handler cancelled\n"); - timeHandler = (thand_f *)0; + "--- net_loop timeout handler cancelled\n"); + time_handler = (thand_f *)0; } else { debug_cond(DEBUG_INT_STATE, - "--- NetLoop timeout handler set (%p)\n", f); - timeHandler = f; - timeStart = get_timer(0); - timeDelta = iv * CONFIG_SYS_HZ / 1000; + "--- net_loop timeout handler set (%p)\n", f); + time_handler = f; + time_start = get_timer(0); + time_delta = iv * CONFIG_SYS_HZ / 1000; } } -int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, +int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport, int payload_len) { uchar *pkt; int eth_hdr_size; int pkt_hdr_size; - /* make sure the NetTxPacket is initialized (NetInit() was called) */ - assert(NetTxPacket != NULL); - if (NetTxPacket == NULL) + /* make sure the net_tx_packet is initialized (net_init() was called) */ + assert(net_tx_packet != NULL); + if (net_tx_packet == NULL) return -1; /* convert to new style broadcast */ - if (dest == 0) - dest = 0xFFFFFFFF; + if (dest.s_addr == 0) + dest.s_addr = 0xFFFFFFFF; /* if broadcast, make the ether address a broadcast and don't do ARP */ - if (dest == 0xFFFFFFFF) - ether = NetBcastAddr; + if (dest.s_addr == 0xFFFFFFFF) + ether = (uchar *)net_bcast_ethaddr; - pkt = (uchar *)NetTxPacket; + pkt = (uchar *)net_tx_packet; - eth_hdr_size = NetSetEther(pkt, ether, PROT_IP); + eth_hdr_size = net_set_ether(pkt, ether, PROT_IP); pkt += eth_hdr_size; net_set_udp_header(pkt, dest, dport, sport, payload_len); pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE; /* if MAC address was not discovered yet, do an ARP request */ - if (memcmp(ether, NetEtherNullAddr, 6) == 0) { + if (memcmp(ether, net_null_ethaddr, 6) == 0) { debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &dest); /* save the ip and eth addr for the packet to send after arp */ - NetArpWaitPacketIP = dest; - NetArpWaitPacketMAC = ether; + net_arp_wait_packet_ip = dest; + arp_wait_packet_ethaddr = ether; /* size of the waiting packet */ - NetArpWaitTxPacketSize = pkt_hdr_size + payload_len; + arp_wait_tx_packet_size = pkt_hdr_size + payload_len; /* and do the ARP request */ - NetArpWaitTry = 1; - NetArpWaitTimerStart = get_timer(0); - ArpRequest(); + arp_wait_try = 1; + arp_wait_timer_start = get_timer(0); + arp_request(); return 1; /* waiting */ } else { debug_cond(DEBUG_DEV_PKT, "sending UDP to %pI4/%pM\n", - &dest, ether); - NetSendPacket(NetTxPacket, pkt_hdr_size + payload_len); + &dest, ether); + net_send_packet(net_tx_packet, pkt_hdr_size + payload_len); return 0; /* transmitted */ } } @@ -778,7 +782,7 @@ struct hole { u16 unused; }; -static struct ip_udp_hdr *__NetDefragment(struct ip_udp_hdr *ip, int *lenp) +static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp) { static uchar pkt_buff[IP_PKTSIZE] __aligned(PKTALIGN); static u16 first_hole, total_len; @@ -898,17 +902,19 @@ static struct ip_udp_hdr *__NetDefragment(struct ip_udp_hdr *ip, int *lenp) return localip; } -static inline struct ip_udp_hdr *NetDefragment(struct ip_udp_hdr *ip, int *lenp) +static inline struct ip_udp_hdr *net_defragment(struct ip_udp_hdr *ip, + int *lenp) { u16 ip_off = ntohs(ip->ip_off); if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG))) return ip; /* not a fragment */ - return __NetDefragment(ip, lenp); + return __net_defragment(ip, lenp); } #else /* !CONFIG_IP_DEFRAG */ -static inline struct ip_udp_hdr *NetDefragment(struct ip_udp_hdr *ip, int *lenp) +static inline struct ip_udp_hdr *net_defragment(struct ip_udp_hdr *ip, + int *lenp) { u16 ip_off = ntohs(ip->ip_off); if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG))) @@ -924,7 +930,7 @@ static inline struct ip_udp_hdr *NetDefragment(struct ip_udp_hdr *ip, int *lenp) * @parma ip IP packet containing the ICMP */ static void receive_icmp(struct ip_udp_hdr *ip, int len, - IPaddr_t src_ip, struct ethernet_hdr *et) + struct in_addr src_ip, struct ethernet_hdr *et) { struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src; @@ -933,7 +939,7 @@ static void receive_icmp(struct ip_udp_hdr *ip, int len, if (icmph->code != ICMP_REDIR_HOST) return; printf(" ICMP Host Redirect to %pI4 ", - &icmph->un.gateway); + &icmph->un.gateway); break; default: #if defined(CONFIG_CMD_PING) @@ -942,20 +948,20 @@ static void receive_icmp(struct ip_udp_hdr *ip, int len, #ifdef CONFIG_CMD_TFTPPUT if (packet_icmp_handler) packet_icmp_handler(icmph->type, icmph->code, - ntohs(ip->udp_dst), src_ip, ntohs(ip->udp_src), - icmph->un.data, ntohs(ip->udp_len)); + ntohs(ip->udp_dst), src_ip, + ntohs(ip->udp_src), icmph->un.data, + ntohs(ip->udp_len)); #endif break; } } -void -NetReceive(uchar *inpkt, int len) +void net_process_received_packet(uchar *in_packet, int len) { struct ethernet_hdr *et; struct ip_udp_hdr *ip; - IPaddr_t dst_ip; - IPaddr_t src_ip; + struct in_addr dst_ip; + struct in_addr src_ip; int eth_proto; #if defined(CONFIG_CMD_CDP) int iscdp; @@ -964,9 +970,9 @@ NetReceive(uchar *inpkt, int len) debug_cond(DEBUG_NET_PKT, "packet received\n"); - NetRxPacket = inpkt; - NetRxPacketLen = len; - et = (struct ethernet_hdr *)inpkt; + net_rx_packet = in_packet; + net_rx_packet_len = len; + et = (struct ethernet_hdr *)in_packet; /* too small packet? */ if (len < ETHER_HDR_SIZE) @@ -974,7 +980,7 @@ NetReceive(uchar *inpkt, int len) #ifdef CONFIG_API if (push_packet) { - (*push_packet)(inpkt, len); + (*push_packet)(in_packet, len); return; } #endif @@ -984,10 +990,10 @@ NetReceive(uchar *inpkt, int len) iscdp = is_cdp_packet(et->et_dest); #endif - myvlanid = ntohs(NetOurVLAN); + myvlanid = ntohs(net_our_vlan); if (myvlanid == (ushort)-1) myvlanid = VLAN_NONE; - mynvlanid = ntohs(NetOurNativeVLAN); + mynvlanid = ntohs(net_native_vlan); if (mynvlanid == (ushort)-1) mynvlanid = VLAN_NONE; @@ -1001,11 +1007,11 @@ NetReceive(uchar *inpkt, int len) */ eth_proto = ntohs(et802->et_prot); - ip = (struct ip_udp_hdr *)(inpkt + E802_HDR_SIZE); + ip = (struct ip_udp_hdr *)(in_packet + E802_HDR_SIZE); len -= E802_HDR_SIZE; } else if (eth_proto != PROT_VLAN) { /* normal packet */ - ip = (struct ip_udp_hdr *)(inpkt + ETHER_HDR_SIZE); + ip = (struct ip_udp_hdr *)(in_packet + ETHER_HDR_SIZE); len -= ETHER_HDR_SIZE; } else { /* VLAN packet */ @@ -1019,7 +1025,7 @@ NetReceive(uchar *inpkt, int len) return; /* if no VLAN active */ - if ((ntohs(NetOurVLAN) & VLAN_IDMASK) == VLAN_NONE + if ((ntohs(net_our_vlan) & VLAN_IDMASK) == VLAN_NONE #if defined(CONFIG_CMD_CDP) && iscdp == 0 #endif @@ -1030,7 +1036,7 @@ NetReceive(uchar *inpkt, int len) vlanid = cti & VLAN_IDMASK; eth_proto = ntohs(vet->vet_type); - ip = (struct ip_udp_hdr *)(inpkt + VLAN_ETHER_HDR_SIZE); + ip = (struct ip_udp_hdr *)(in_packet + VLAN_ETHER_HDR_SIZE); len -= VLAN_ETHER_HDR_SIZE; } @@ -1052,9 +1058,8 @@ NetReceive(uchar *inpkt, int len) } switch (eth_proto) { - case PROT_ARP: - ArpReceive(et, ip, len); + arp_receive(et, ip, len); break; #ifdef CONFIG_CMD_RARP @@ -1067,7 +1072,7 @@ NetReceive(uchar *inpkt, int len) /* Before we start poking the header, make sure it is there */ if (len < IP_UDP_HDR_SIZE) { debug("len bad %d < %lu\n", len, - (ulong)IP_UDP_HDR_SIZE); + (ulong)IP_UDP_HDR_SIZE); return; } /* Check the packet length */ @@ -1077,7 +1082,7 @@ NetReceive(uchar *inpkt, int len) } len = ntohs(ip->ip_len); debug_cond(DEBUG_NET_PKT, "len=%d, v=%02x\n", - len, ip->ip_hl_v & 0xff); + len, ip->ip_hl_v & 0xff); /* Can't deal with anything except IPv4 */ if ((ip->ip_hl_v & 0xf0) != 0x40) @@ -1091,21 +1096,22 @@ NetReceive(uchar *inpkt, int len) return; } /* If it is not for us, ignore it */ - dst_ip = NetReadIP(&ip->ip_dst); - if (NetOurIP && dst_ip != NetOurIP && dst_ip != 0xFFFFFFFF) { + dst_ip = net_read_ip(&ip->ip_dst); + if (net_ip.s_addr && dst_ip.s_addr != net_ip.s_addr && + dst_ip.s_addr != 0xFFFFFFFF) { #ifdef CONFIG_MCAST_TFTP - if (Mcast_addr != dst_ip) + if (net_mcast_addr != dst_ip) #endif return; } /* Read source IP address for later use */ - src_ip = NetReadIP(&ip->ip_src); + src_ip = net_read_ip(&ip->ip_src); /* * The function returns the unchanged packet if it's not * a fragment, and either the complete packet or NULL if * it is a fragment (if !CONFIG_IP_DEFRAG, it returns NULL) */ - ip = NetDefragment(ip, &len); + ip = net_defragment(ip, &len); if (!ip) return; /* @@ -1137,8 +1143,8 @@ NetReceive(uchar *inpkt, int len) } debug_cond(DEBUG_DEV_PKT, - "received UDP (to=%pI4, from=%pI4, len=%d)\n", - &dst_ip, &src_ip, len); + "received UDP (to=%pI4, from=%pI4, len=%d)\n", + &dst_ip, &src_ip, len); #ifdef CONFIG_UDP_CHECKSUM if (ip->udp_xsum != 0) { @@ -1148,13 +1154,13 @@ NetReceive(uchar *inpkt, int len) xsum = ip->ip_p; xsum += (ntohs(ip->udp_len)); - xsum += (ntohl(ip->ip_src) >> 16) & 0x0000ffff; - xsum += (ntohl(ip->ip_src) >> 0) & 0x0000ffff; - xsum += (ntohl(ip->ip_dst) >> 16) & 0x0000ffff; - xsum += (ntohl(ip->ip_dst) >> 0) & 0x0000ffff; + xsum += (ntohl(ip->ip_src.s_addr) >> 16) & 0x0000ffff; + xsum += (ntohl(ip->ip_src.s_addr) >> 0) & 0x0000ffff; + xsum += (ntohl(ip->ip_dst.s_addr) >> 16) & 0x0000ffff; + xsum += (ntohl(ip->ip_dst.s_addr) >> 0) & 0x0000ffff; sumlen = ntohs(ip->udp_len); - sumptr = (ushort *) &(ip->udp_src); + sumptr = (ushort *)&(ip->udp_src); while (sumlen > 1) { ushort sumdata; @@ -1166,7 +1172,7 @@ NetReceive(uchar *inpkt, int len) if (sumlen > 0) { ushort sumdata; - sumdata = *(unsigned char *) sumptr; + sumdata = *(unsigned char *)sumptr; sumdata = (sumdata << 8) & 0xff00; xsum += sumdata; } @@ -1176,33 +1182,31 @@ NetReceive(uchar *inpkt, int len) } if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) { printf(" UDP wrong checksum %08lx %08x\n", - xsum, ntohs(ip->udp_xsum)); + xsum, ntohs(ip->udp_xsum)); return; } } #endif - -#if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD) +#if defined(CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD) nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE, - src_ip, - ntohs(ip->udp_dst), - ntohs(ip->udp_src), - ntohs(ip->udp_len) - UDP_HDR_SIZE); + src_ip, + ntohs(ip->udp_dst), + ntohs(ip->udp_src), + ntohs(ip->udp_len) - UDP_HDR_SIZE); #endif /* - * IP header OK. Pass the packet to the current handler. + * IP header OK. Pass the packet to the current handler. */ (*udp_packet_handler)((uchar *)ip + IP_UDP_HDR_SIZE, - ntohs(ip->udp_dst), - src_ip, - ntohs(ip->udp_src), - ntohs(ip->udp_len) - UDP_HDR_SIZE); + ntohs(ip->udp_dst), + src_ip, + ntohs(ip->udp_src), + ntohs(ip->udp_len) - UDP_HDR_SIZE); break; } } - /**********************************************************************/ static int net_check_prereq(enum proto_t protocol) @@ -1211,7 +1215,7 @@ static int net_check_prereq(enum proto_t protocol) /* Fall through */ #if defined(CONFIG_CMD_PING) case PING: - if (NetPingIP == 0) { + if (net_ping_ip.s_addr == 0) { puts("*** ERROR: ping address not given\n"); return 1; } @@ -1219,7 +1223,7 @@ static int net_check_prereq(enum proto_t protocol) #endif #if defined(CONFIG_CMD_SNTP) case SNTP: - if (NetNtpServerIP == 0) { + if (net_ntp_server.s_addr == 0) { puts("*** ERROR: NTP server address not given\n"); return 1; } @@ -1227,7 +1231,7 @@ static int net_check_prereq(enum proto_t protocol) #endif #if defined(CONFIG_CMD_DNS) case DNS: - if (NetOurDNSIP == 0) { + if (net_dns_server.s_addr == 0) { puts("*** ERROR: DNS server address not given\n"); return 1; } @@ -1236,9 +1240,10 @@ static int net_check_prereq(enum proto_t protocol) #if defined(CONFIG_CMD_NFS) case NFS: #endif + /* Fall through */ case TFTPGET: case TFTPPUT: - if (NetServerIP == 0) { + if (net_server_ip.s_addr == 0) { puts("*** ERROR: `serverip' not set\n"); return 1; } @@ -1250,7 +1255,7 @@ common: case NETCONS: case TFTPSRV: - if (NetOurIP == 0) { + if (net_ip.s_addr == 0) { puts("*** ERROR: `ipaddr' not set\n"); return 1; } @@ -1263,7 +1268,7 @@ common: case CDP: case DHCP: case LINKLOCAL: - if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) { + if (memcmp(net_ethaddr, "\0\0\0\0\0\0", 6) == 0) { int num = eth_get_dev_index(); switch (num) { @@ -1275,11 +1280,11 @@ common: break; default: printf("*** ERROR: `eth%daddr' not set\n", - num); + num); break; } - NetStartAgain(); + net_start_again(); return 2; } /* Fall through */ @@ -1291,11 +1296,11 @@ common: /**********************************************************************/ int -NetEthHdrSize(void) +net_eth_hdr_size(void) { ushort myvlanid; - myvlanid = ntohs(NetOurVLAN); + myvlanid = ntohs(net_our_vlan); if (myvlanid == (ushort)-1) myvlanid = VLAN_NONE; @@ -1303,18 +1308,17 @@ NetEthHdrSize(void) VLAN_ETHER_HDR_SIZE; } -int -NetSetEther(uchar *xet, uchar * addr, uint prot) +int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot) { struct ethernet_hdr *et = (struct ethernet_hdr *)xet; ushort myvlanid; - myvlanid = ntohs(NetOurVLAN); + myvlanid = ntohs(net_our_vlan); if (myvlanid == (ushort)-1) myvlanid = VLAN_NONE; - memcpy(et->et_dest, addr, 6); - memcpy(et->et_src, NetOurEther, 6); + memcpy(et->et_dest, dest_ethaddr, 6); + memcpy(et->et_src, net_ethaddr, 6); if ((myvlanid & VLAN_IDMASK) == VLAN_NONE) { et->et_protlen = htons(prot); return ETHER_HDR_SIZE; @@ -1334,7 +1338,7 @@ int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot) ushort protlen; memcpy(et->et_dest, addr, 6); - memcpy(et->et_src, NetOurEther, 6); + memcpy(et->et_src, net_ethaddr, 6); protlen = ntohs(et->et_protlen); if (protlen == PROT_VLAN) { struct vlan_ethernet_hdr *vet = @@ -1352,7 +1356,7 @@ int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot) } } -void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source) +void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source) { struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt; @@ -1363,17 +1367,17 @@ void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source) ip->ip_hl_v = 0x45; ip->ip_tos = 0; ip->ip_len = htons(IP_HDR_SIZE); - ip->ip_id = htons(NetIPID++); + ip->ip_id = htons(net_ip_id++); ip->ip_off = htons(IP_FLAGS_DFRAG); /* Don't fragment */ ip->ip_ttl = 255; ip->ip_sum = 0; /* already in network byte order */ - NetCopyIP((void *)&ip->ip_src, &source); + net_copy_ip((void *)&ip->ip_src, &source); /* already in network byte order */ - NetCopyIP((void *)&ip->ip_dst, &dest); + net_copy_ip((void *)&ip->ip_dst, &dest); } -void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, int sport, +void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport, int sport, int len) { struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt; @@ -1386,7 +1390,7 @@ void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, int sport, if (len & 1) pkt[IP_UDP_HDR_SIZE + len] = 0; - net_set_ip_header(pkt, dest, NetOurIP); + net_set_ip_header(pkt, dest, net_ip); ip->ip_len = htons(IP_UDP_HDR_SIZE + len); ip->ip_p = IPPROTO_UDP; ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE); @@ -1423,17 +1427,18 @@ unsigned int random_port(void) } #endif -void ip_to_string(IPaddr_t x, char *s) +void ip_to_string(struct in_addr x, char *s) { - x = ntohl(x); + x.s_addr = ntohl(x.s_addr); sprintf(s, "%d.%d.%d.%d", - (int) ((x >> 24) & 0xff), - (int) ((x >> 16) & 0xff), - (int) ((x >> 8) & 0xff), (int) ((x >> 0) & 0xff) + (int) ((x.s_addr >> 24) & 0xff), + (int) ((x.s_addr >> 16) & 0xff), + (int) ((x.s_addr >> 8) & 0xff), + (int) ((x.s_addr >> 0) & 0xff) ); } -void VLAN_to_string(ushort x, char *s) +void vlan_to_string(ushort x, char *s) { x = ntohs(x); @@ -1446,7 +1451,7 @@ void VLAN_to_string(ushort x, char *s) sprintf(s, "%d", x & VLAN_IDMASK); } -ushort string_to_VLAN(const char *s) +ushort string_to_vlan(const char *s) { ushort id; @@ -1461,7 +1466,7 @@ ushort string_to_VLAN(const char *s) return htons(id); } -ushort getenv_VLAN(char *var) +ushort getenv_vlan(char *var) { - return string_to_VLAN(getenv(var)); + return string_to_vlan(getenv(var)); } @@ -26,6 +26,7 @@ #include <command.h> #include <net.h> #include <malloc.h> +#include <mapmem.h> #include "nfs.h" #include "bootp.h" @@ -50,12 +51,12 @@ static char dirfh[NFS_FHSIZE]; /* file handle of directory */ static char filefh[NFS_FHSIZE]; /* file handle of kernel image */ static enum net_loop_state nfs_download_state; -static IPaddr_t NfsServerIP; -static int NfsSrvMountPort; -static int NfsSrvNfsPort; -static int NfsOurPort; -static int NfsTimeoutCount; -static int NfsState; +static struct in_addr nfs_server_ip; +static int nfs_server_mount_port; +static int nfs_server_port; +static int nfs_our_port; +static int nfs_timeout_count; +static int nfs_state; #define STATE_PRCLOOKUP_PROG_MOUNT_REQ 1 #define STATE_PRCLOOKUP_PROG_NFS_REQ 2 #define STATE_MOUNT_REQ 3 @@ -69,8 +70,7 @@ static char *nfs_filename; static char *nfs_path; static char nfs_path_buff[2048]; -static inline int -store_block(uchar *src, unsigned offset, unsigned len) +static inline int store_block(uchar *src, unsigned offset, unsigned len) { ulong newsize = offset + len; #ifdef CONFIG_SYS_DIRECT_FLASH_NFS @@ -93,16 +93,18 @@ store_block(uchar *src, unsigned offset, unsigned len) } else #endif /* CONFIG_SYS_DIRECT_FLASH_NFS */ { - (void)memcpy((void *)(load_addr + offset), src, len); + void *ptr = map_sysmem(load_addr + offset, len); + + memcpy(ptr, src, len); + unmap_sysmem(ptr); } - if (NetBootFileXferSize < (offset+len)) - NetBootFileXferSize = newsize; + if (net_boot_file_size < (offset + len)) + net_boot_file_size = newsize; return 0; } -static char* -basename(char *path) +static char *basename(char *path) { char *fname; @@ -117,8 +119,7 @@ basename(char *path) return fname; } -static char* -dirname(char *path) +static char *dirname(char *path) { char *fname; @@ -174,8 +175,7 @@ static long *rpc_add_credentials(long *p) /************************************************************************** RPC_LOOKUP - Lookup RPC Port numbers **************************************************************************/ -static void -rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen) +static void rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen) { struct rpc_t pkt; unsigned long id; @@ -197,25 +197,24 @@ rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen) pktlen = (char *)p + datalen*sizeof(uint32_t) - (char *)&pkt; - memcpy((char *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE, - (char *)&pkt, pktlen); + memcpy((char *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE, + (char *)&pkt, pktlen); if (rpc_prog == PROG_PORTMAP) sport = SUNRPC_PORT; else if (rpc_prog == PROG_MOUNT) - sport = NfsSrvMountPort; + sport = nfs_server_mount_port; else - sport = NfsSrvNfsPort; + sport = nfs_server_port; - NetSendUDPPacket(NetServerEther, NfsServerIP, sport, NfsOurPort, - pktlen); + net_send_udp_packet(net_server_ethaddr, nfs_server_ip, sport, + nfs_our_port, pktlen); } /************************************************************************** RPC_LOOKUP - Lookup RPC Port numbers **************************************************************************/ -static void -rpc_lookup_req(int prog, int ver) +static void rpc_lookup_req(int prog, int ver) { uint32_t data[16]; @@ -232,8 +231,7 @@ rpc_lookup_req(int prog, int ver) /************************************************************************** NFS_MOUNT - Mount an NFS Filesystem **************************************************************************/ -static void -nfs_mount_req(char *path) +static void nfs_mount_req(char *path) { uint32_t data[1024]; uint32_t *p; @@ -259,14 +257,13 @@ nfs_mount_req(char *path) /************************************************************************** NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server **************************************************************************/ -static void -nfs_umountall_req(void) +static void nfs_umountall_req(void) { uint32_t data[1024]; uint32_t *p; int len; - if ((NfsSrvMountPort == -1) || (!fs_mounted)) + if ((nfs_server_mount_port == -1) || (!fs_mounted)) /* Nothing mounted, nothing to umount */ return; @@ -285,8 +282,7 @@ nfs_umountall_req(void) * In case of successful readlink(), the dirname is manipulated, * so that inside the nfs() function a recursion can be done. **************************************************************************/ -static void -nfs_readlink_req(void) +static void nfs_readlink_req(void) { uint32_t data[1024]; uint32_t *p; @@ -306,8 +302,7 @@ nfs_readlink_req(void) /************************************************************************** NFS_LOOKUP - Lookup Pathname **************************************************************************/ -static void -nfs_lookup_req(char *fname) +static void nfs_lookup_req(char *fname) { uint32_t data[1024]; uint32_t *p; @@ -335,8 +330,7 @@ nfs_lookup_req(char *fname) /************************************************************************** NFS_READ - Read File on NFS Server **************************************************************************/ -static void -nfs_read_req(int offset, int readlen) +static void nfs_read_req(int offset, int readlen) { uint32_t data[1024]; uint32_t *p; @@ -359,13 +353,11 @@ nfs_read_req(int offset, int readlen) /************************************************************************** RPC request dispatcher **************************************************************************/ - -static void -NfsSend(void) +static void nfs_send(void) { debug("%s\n", __func__); - switch (NfsState) { + switch (nfs_state) { case STATE_PRCLOOKUP_PROG_MOUNT_REQ: rpc_lookup_req(PROG_MOUNT, 1); break; @@ -394,8 +386,7 @@ NfsSend(void) Handlers for the reply from server **************************************************************************/ -static int -rpc_lookup_reply(int prog, uchar *pkt, unsigned len) +static int rpc_lookup_reply(int prog, uchar *pkt, unsigned len) { struct rpc_t rpc_pkt; @@ -415,18 +406,17 @@ rpc_lookup_reply(int prog, uchar *pkt, unsigned len) switch (prog) { case PROG_MOUNT: - NfsSrvMountPort = ntohl(rpc_pkt.u.reply.data[0]); + nfs_server_mount_port = ntohl(rpc_pkt.u.reply.data[0]); break; case PROG_NFS: - NfsSrvNfsPort = ntohl(rpc_pkt.u.reply.data[0]); + nfs_server_port = ntohl(rpc_pkt.u.reply.data[0]); break; } return 0; } -static int -nfs_mount_reply(uchar *pkt, unsigned len) +static int nfs_mount_reply(uchar *pkt, unsigned len) { struct rpc_t rpc_pkt; @@ -451,8 +441,7 @@ nfs_mount_reply(uchar *pkt, unsigned len) return 0; } -static int -nfs_umountall_reply(uchar *pkt, unsigned len) +static int nfs_umountall_reply(uchar *pkt, unsigned len) { struct rpc_t rpc_pkt; @@ -476,8 +465,7 @@ nfs_umountall_reply(uchar *pkt, unsigned len) return 0; } -static int -nfs_lookup_reply(uchar *pkt, unsigned len) +static int nfs_lookup_reply(uchar *pkt, unsigned len) { struct rpc_t rpc_pkt; @@ -501,8 +489,7 @@ nfs_lookup_reply(uchar *pkt, unsigned len) return 0; } -static int -nfs_readlink_reply(uchar *pkt, unsigned len) +static int nfs_readlink_reply(uchar *pkt, unsigned len) { struct rpc_t rpc_pkt; int rlen; @@ -529,7 +516,7 @@ nfs_readlink_reply(uchar *pkt, unsigned len) strcat(nfs_path, "/"); pathlen = strlen(nfs_path); memcpy(nfs_path + pathlen, (uchar *)&(rpc_pkt.u.reply.data[2]), - rlen); + rlen); nfs_path[pathlen + rlen] = 0; } else { memcpy(nfs_path, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen); @@ -538,8 +525,7 @@ nfs_readlink_reply(uchar *pkt, unsigned len) return 0; } -static int -nfs_read_reply(uchar *pkt, unsigned len) +static int nfs_read_reply(uchar *pkt, unsigned len) { struct rpc_t rpc_pkt; int rlen; @@ -581,67 +567,66 @@ nfs_read_reply(uchar *pkt, unsigned len) /************************************************************************** Interfaces of U-BOOT **************************************************************************/ - -static void -NfsTimeout(void) +static void nfs_timeout_handler(void) { - if (++NfsTimeoutCount > NFS_RETRY_COUNT) { + if (++nfs_timeout_count > NFS_RETRY_COUNT) { puts("\nRetry count exceeded; starting again\n"); - NetStartAgain(); + net_start_again(); } else { puts("T "); - NetSetTimeout(nfs_timeout + NFS_TIMEOUT * NfsTimeoutCount, - NfsTimeout); - NfsSend(); + net_set_timeout_handler(nfs_timeout + + NFS_TIMEOUT * nfs_timeout_count, + nfs_timeout_handler); + nfs_send(); } } -static void -NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len) +static void nfs_handler(uchar *pkt, unsigned dest, struct in_addr sip, + unsigned src, unsigned len) { int rlen; int reply; debug("%s\n", __func__); - if (dest != NfsOurPort) + if (dest != nfs_our_port) return; - switch (NfsState) { + switch (nfs_state) { case STATE_PRCLOOKUP_PROG_MOUNT_REQ: if (rpc_lookup_reply(PROG_MOUNT, pkt, len) == -NFS_RPC_DROP) break; - NfsState = STATE_PRCLOOKUP_PROG_NFS_REQ; - NfsSend(); + nfs_state = STATE_PRCLOOKUP_PROG_NFS_REQ; + nfs_send(); break; case STATE_PRCLOOKUP_PROG_NFS_REQ: if (rpc_lookup_reply(PROG_NFS, pkt, len) == -NFS_RPC_DROP) break; - NfsState = STATE_MOUNT_REQ; - NfsSend(); + nfs_state = STATE_MOUNT_REQ; + nfs_send(); break; case STATE_MOUNT_REQ: reply = nfs_mount_reply(pkt, len); - if (reply == -NFS_RPC_DROP) + if (reply == -NFS_RPC_DROP) { break; - else if (reply == -NFS_RPC_ERR) { + } else if (reply == -NFS_RPC_ERR) { puts("*** ERROR: Cannot mount\n"); /* just to be sure... */ - NfsState = STATE_UMOUNT_REQ; - NfsSend(); + nfs_state = STATE_UMOUNT_REQ; + nfs_send(); } else { - NfsState = STATE_LOOKUP_REQ; - NfsSend(); + nfs_state = STATE_LOOKUP_REQ; + nfs_send(); } break; case STATE_UMOUNT_REQ: reply = nfs_umountall_reply(pkt, len); - if (reply == -NFS_RPC_DROP) + if (reply == -NFS_RPC_DROP) { break; - else if (reply == -NFS_RPC_ERR) { + } else if (reply == -NFS_RPC_ERR) { puts("*** ERROR: Cannot umount\n"); net_set_state(NETLOOP_FAIL); } else { @@ -652,66 +637,65 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len) case STATE_LOOKUP_REQ: reply = nfs_lookup_reply(pkt, len); - if (reply == -NFS_RPC_DROP) + if (reply == -NFS_RPC_DROP) { break; - else if (reply == -NFS_RPC_ERR) { + } else if (reply == -NFS_RPC_ERR) { puts("*** ERROR: File lookup fail\n"); - NfsState = STATE_UMOUNT_REQ; - NfsSend(); + nfs_state = STATE_UMOUNT_REQ; + nfs_send(); } else { - NfsState = STATE_READ_REQ; + nfs_state = STATE_READ_REQ; nfs_offset = 0; nfs_len = NFS_READ_SIZE; - NfsSend(); + nfs_send(); } break; case STATE_READLINK_REQ: reply = nfs_readlink_reply(pkt, len); - if (reply == -NFS_RPC_DROP) + if (reply == -NFS_RPC_DROP) { break; - else if (reply == -NFS_RPC_ERR) { + } else if (reply == -NFS_RPC_ERR) { puts("*** ERROR: Symlink fail\n"); - NfsState = STATE_UMOUNT_REQ; - NfsSend(); + nfs_state = STATE_UMOUNT_REQ; + nfs_send(); } else { debug("Symlink --> %s\n", nfs_path); nfs_filename = basename(nfs_path); nfs_path = dirname(nfs_path); - NfsState = STATE_MOUNT_REQ; - NfsSend(); + nfs_state = STATE_MOUNT_REQ; + nfs_send(); } break; case STATE_READ_REQ: rlen = nfs_read_reply(pkt, len); - NetSetTimeout(nfs_timeout, NfsTimeout); + net_set_timeout_handler(nfs_timeout, nfs_timeout_handler); if (rlen > 0) { nfs_offset += rlen; - NfsSend(); + nfs_send(); } else if ((rlen == -NFSERR_ISDIR) || (rlen == -NFSERR_INVAL)) { /* symbolic link */ - NfsState = STATE_READLINK_REQ; - NfsSend(); + nfs_state = STATE_READLINK_REQ; + nfs_send(); } else { if (!rlen) nfs_download_state = NETLOOP_SUCCESS; - NfsState = STATE_UMOUNT_REQ; - NfsSend(); + nfs_state = STATE_UMOUNT_REQ; + nfs_send(); } break; } } -void -NfsStart(void) +void nfs_start(void) { debug("%s\n", __func__); nfs_download_state = NETLOOP_FAIL; - NfsServerIP = NetServerIP; + nfs_server_ip = net_server_ip; nfs_path = (char *)nfs_path_buff; if (nfs_path == NULL) { @@ -720,27 +704,27 @@ NfsStart(void) return; } - if (BootFile[0] == '\0') { + if (net_boot_file_name[0] == '\0') { sprintf(default_filename, "/nfsroot/%02X%02X%02X%02X.img", - NetOurIP & 0xFF, - (NetOurIP >> 8) & 0xFF, - (NetOurIP >> 16) & 0xFF, - (NetOurIP >> 24) & 0xFF); + net_ip.s_addr & 0xFF, + (net_ip.s_addr >> 8) & 0xFF, + (net_ip.s_addr >> 16) & 0xFF, + (net_ip.s_addr >> 24) & 0xFF); strcpy(nfs_path, default_filename); printf("*** Warning: no boot file name; using '%s'\n", - nfs_path); + nfs_path); } else { - char *p = BootFile; + char *p = net_boot_file_name; p = strchr(p, ':'); if (p != NULL) { - NfsServerIP = string_to_ip(BootFile); + nfs_server_ip = string_to_ip(net_boot_file_name); ++p; strcpy(nfs_path, p); } else { - strcpy(nfs_path, BootFile); + strcpy(nfs_path, net_boot_file_name); } } @@ -749,39 +733,42 @@ NfsStart(void) printf("Using %s device\n", eth_get_name()); - printf("File transfer via NFS from server %pI4" - "; our IP address is %pI4", &NfsServerIP, &NetOurIP); + printf("File transfer via NFS from server %pI4; our IP address is %pI4", + &nfs_server_ip, &net_ip); /* Check if we need to send across this subnet */ - if (NetOurGatewayIP && NetOurSubnetMask) { - IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; - IPaddr_t ServerNet = NetServerIP & NetOurSubnetMask; + if (net_gateway.s_addr && net_netmask.s_addr) { + struct in_addr our_net; + struct in_addr server_net; - if (OurNet != ServerNet) + our_net.s_addr = net_ip.s_addr & net_netmask.s_addr; + server_net.s_addr = net_server_ip.s_addr & net_netmask.s_addr; + if (our_net.s_addr != server_net.s_addr) printf("; sending through gateway %pI4", - &NetOurGatewayIP); + &net_gateway); } printf("\nFilename '%s/%s'.", nfs_path, nfs_filename); - if (NetBootFileSize) { - printf(" Size is 0x%x Bytes = ", NetBootFileSize<<9); - print_size(NetBootFileSize<<9, ""); + if (net_boot_file_expected_size_in_blocks) { + printf(" Size is 0x%x Bytes = ", + net_boot_file_expected_size_in_blocks << 9); + print_size(net_boot_file_expected_size_in_blocks << 9, ""); } printf("\nLoad address: 0x%lx\n" "Loading: *\b", load_addr); - NetSetTimeout(nfs_timeout, NfsTimeout); - net_set_udp_handler(NfsHandler); + net_set_timeout_handler(nfs_timeout, nfs_timeout_handler); + net_set_udp_handler(nfs_handler); - NfsTimeoutCount = 0; - NfsState = STATE_PRCLOOKUP_PROG_MOUNT_REQ; + nfs_timeout_count = 0; + nfs_state = STATE_PRCLOOKUP_PROG_MOUNT_REQ; - /*NfsOurPort = 4096 + (get_ticks() % 3072);*/ + /*nfs_our_port = 4096 + (get_ticks() % 3072);*/ /*FIX ME !!!*/ - NfsOurPort = 1000; + nfs_our_port = 1000; /* zero out server ether in case the server ip has changed */ - memset(NetServerEther, 0, 6); + memset(net_server_ethaddr, 0, 6); - NfsSend(); + nfs_send(); } @@ -69,7 +69,7 @@ struct rpc_t { } reply; } u; }; -extern void NfsStart(void); /* Begin NFS */ +void nfs_start(void); /* Begin NFS */ /**********************************************************************/ @@ -12,12 +12,12 @@ #include "ping.h" #include "arp.h" -static ushort PingSeqNo; +static ushort ping_seq_number; /* The ip address to ping */ -IPaddr_t NetPingIP; +struct in_addr net_ping_ip; -static void set_icmp_header(uchar *pkt, IPaddr_t dest) +static void set_icmp_header(uchar *pkt, struct in_addr dest) { /* * Construct an IP and ICMP header. @@ -25,7 +25,7 @@ static void set_icmp_header(uchar *pkt, IPaddr_t dest) struct ip_hdr *ip = (struct ip_hdr *)pkt; struct icmp_hdr *icmp = (struct icmp_hdr *)(pkt + IP_HDR_SIZE); - net_set_ip_header(pkt, dest, NetOurIP); + net_set_ip_header(pkt, dest, net_ip); ip->ip_len = htons(IP_ICMP_HDR_SIZE); ip->ip_p = IPPROTO_ICMP; @@ -35,7 +35,7 @@ static void set_icmp_header(uchar *pkt, IPaddr_t dest) icmp->code = 0; icmp->checksum = 0; icmp->un.echo.id = 0; - icmp->un.echo.sequence = htons(PingSeqNo++); + icmp->un.echo.sequence = htons(ping_seq_number++); icmp->checksum = compute_ip_checksum(icmp, ICMP_HDR_SIZE); } @@ -46,26 +46,26 @@ static int ping_send(void) /* XXX always send arp request */ - debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &NetPingIP); + debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &net_ping_ip); - NetArpWaitPacketIP = NetPingIP; + net_arp_wait_packet_ip = net_ping_ip; - eth_hdr_size = NetSetEther(NetTxPacket, NetEtherNullAddr, PROT_IP); - pkt = (uchar *)NetTxPacket + eth_hdr_size; + eth_hdr_size = net_set_ether(net_tx_packet, net_null_ethaddr, PROT_IP); + pkt = (uchar *)net_tx_packet + eth_hdr_size; - set_icmp_header(pkt, NetPingIP); + set_icmp_header(pkt, net_ping_ip); /* size of the waiting packet */ - NetArpWaitTxPacketSize = eth_hdr_size + IP_ICMP_HDR_SIZE; + arp_wait_tx_packet_size = eth_hdr_size + IP_ICMP_HDR_SIZE; /* and do the ARP request */ - NetArpWaitTry = 1; - NetArpWaitTimerStart = get_timer(0); - ArpRequest(); + arp_wait_try = 1; + arp_wait_timer_start = get_timer(0); + arp_request(); return 1; /* waiting */ } -static void ping_timeout(void) +static void ping_timeout_handler(void) { eth_halt(); net_set_state(NETLOOP_FAIL); /* we did not get the reply */ @@ -74,7 +74,7 @@ static void ping_timeout(void) void ping_start(void) { printf("Using %s device\n", eth_get_name()); - NetSetTimeout(10000UL, ping_timeout); + net_set_timeout_handler(10000UL, ping_timeout_handler); ping_send(); } @@ -82,31 +82,32 @@ void ping_start(void) void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) { struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src; - IPaddr_t src_ip; + struct in_addr src_ip; int eth_hdr_size; switch (icmph->type) { case ICMP_ECHO_REPLY: - src_ip = NetReadIP((void *)&ip->ip_src); - if (src_ip == NetPingIP) + src_ip = net_read_ip((void *)&ip->ip_src); + if (src_ip.s_addr == net_ping_ip.s_addr) net_set_state(NETLOOP_SUCCESS); return; case ICMP_ECHO_REQUEST: eth_hdr_size = net_update_ether(et, et->et_src, PROT_IP); - debug_cond(DEBUG_DEV_PKT, "Got ICMP ECHO REQUEST, return " - "%d bytes\n", eth_hdr_size + len); + debug_cond(DEBUG_DEV_PKT, + "Got ICMP ECHO REQUEST, return %d bytes\n", + eth_hdr_size + len); ip->ip_sum = 0; ip->ip_off = 0; - NetCopyIP((void *)&ip->ip_dst, &ip->ip_src); - NetCopyIP((void *)&ip->ip_src, &NetOurIP); + net_copy_ip((void *)&ip->ip_dst, &ip->ip_src); + net_copy_ip((void *)&ip->ip_src, &net_ip); ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE); icmph->type = ICMP_ECHO_REPLY; icmph->checksum = 0; icmph->checksum = compute_ip_checksum(icmph, len - IP_HDR_SIZE); - NetSendPacket((uchar *)et, eth_hdr_size + len); + net_send_packet((uchar *)et, eth_hdr_size + len); return; /* default: return;*/ @@ -20,7 +20,7 @@ #define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) #endif -int RarpTry; +int rarp_try; /* * Handle a RARP received packet. @@ -37,16 +37,15 @@ void rarp_receive(struct ip_udp_hdr *ip, unsigned len) } if ((ntohs(arp->ar_op) != RARPOP_REPLY) || - (ntohs(arp->ar_hrd) != ARP_ETHER) || - (ntohs(arp->ar_pro) != PROT_IP) || - (arp->ar_hln != 6) || (arp->ar_pln != 4)) { - + (ntohs(arp->ar_hrd) != ARP_ETHER) || + (ntohs(arp->ar_pro) != PROT_IP) || + (arp->ar_hln != 6) || (arp->ar_pln != 4)) { puts("invalid RARP header\n"); } else { - NetCopyIP(&NetOurIP, &arp->ar_data[16]); - if (NetServerIP == 0) - NetCopyIP(&NetServerIP, &arp->ar_data[6]); - memcpy(NetServerEther, &arp->ar_data[0], 6); + net_copy_ip(&net_ip, &arp->ar_data[16]); + if (net_server_ip.s_addr == 0) + net_copy_ip(&net_server_ip, &arp->ar_data[6]); + memcpy(net_server_ethaddr, &arp->ar_data[0], 6); debug_cond(DEBUG_DEV_PKT, "Got good RARP\n"); net_auto_load(); } @@ -56,28 +55,28 @@ void rarp_receive(struct ip_udp_hdr *ip, unsigned len) /* * Timeout on BOOTP request. */ -static void RarpTimeout(void) +static void rarp_timeout_handler(void) { - if (RarpTry >= TIMEOUT_COUNT) { + if (rarp_try >= TIMEOUT_COUNT) { puts("\nRetry count exceeded; starting again\n"); - NetStartAgain(); + net_start_again(); } else { - NetSetTimeout(TIMEOUT, RarpTimeout); - RarpRequest(); + net_set_timeout_handler(TIMEOUT, rarp_timeout_handler); + rarp_request(); } } -void RarpRequest(void) +void rarp_request(void) { uchar *pkt; struct arp_hdr *rarp; int eth_hdr_size; - printf("RARP broadcast %d\n", ++RarpTry); - pkt = NetTxPacket; + printf("RARP broadcast %d\n", ++rarp_try); + pkt = net_tx_packet; - eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_RARP); + eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_RARP); pkt += eth_hdr_size; rarp = (struct arp_hdr *)pkt; @@ -87,14 +86,14 @@ void RarpRequest(void) rarp->ar_hln = 6; rarp->ar_pln = 4; rarp->ar_op = htons(RARPOP_REQUEST); - memcpy(&rarp->ar_data[0], NetOurEther, 6); /* source ET addr */ - memcpy(&rarp->ar_data[6], &NetOurIP, 4); /* source IP addr */ + memcpy(&rarp->ar_data[0], net_ethaddr, 6); /* source ET addr */ + memcpy(&rarp->ar_data[6], &net_ip, 4); /* source IP addr */ /* dest ET addr = source ET addr ??*/ - memcpy(&rarp->ar_data[10], NetOurEther, 6); + memcpy(&rarp->ar_data[10], net_ethaddr, 6); /* dest IP addr set to broadcast */ memset(&rarp->ar_data[16], 0xff, 4); - NetSendPacket(NetTxPacket, eth_hdr_size + ARP_HDR_SIZE); + net_send_packet(net_tx_packet, eth_hdr_size + ARP_HDR_SIZE); - NetSetTimeout(TIMEOUT, RarpTimeout); + net_set_timeout_handler(TIMEOUT, rarp_timeout_handler); } @@ -17,11 +17,11 @@ * Global functions and variables. */ -extern int RarpTry; +extern int rarp_try; /* Process the receipt of a RARP packet */ -extern void rarp_receive(struct ip_udp_hdr *ip, unsigned len); -extern void RarpRequest(void); /* Send a RARP request */ +void rarp_receive(struct ip_udp_hdr *ip, unsigned len); +void rarp_request(void); /* Send a RARP request */ /**********************************************************************/ @@ -14,10 +14,9 @@ #define SNTP_TIMEOUT 10000UL -static int SntpOurPort; +static int sntp_our_port; -static void -SntpSend(void) +static void sntp_send(void) { struct sntp_pkt_t pkt; int pktlen = SNTP_PACKET_LEN; @@ -31,62 +30,63 @@ SntpSend(void) pkt.vn = NTP_VERSION; pkt.mode = NTP_MODE_CLIENT; - memcpy((char *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE, - (char *)&pkt, pktlen); + memcpy((char *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE, + (char *)&pkt, pktlen); - SntpOurPort = 10000 + (get_timer(0) % 4096); + sntp_our_port = 10000 + (get_timer(0) % 4096); sport = NTP_SERVICE_PORT; - NetSendUDPPacket(NetServerEther, NetNtpServerIP, sport, SntpOurPort, - pktlen); + net_send_udp_packet(net_server_ethaddr, net_ntp_server, sport, + sntp_our_port, pktlen); } -static void -SntpTimeout(void) +static void sntp_timeout_handler(void) { puts("Timeout\n"); net_set_state(NETLOOP_FAIL); return; } -static void -SntpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, - unsigned len) +static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip, + unsigned src, unsigned len) { +#ifdef CONFIG_TIMESTAMP struct sntp_pkt_t *rpktp = (struct sntp_pkt_t *)pkt; struct rtc_time tm; ulong seconds; +#endif debug("%s\n", __func__); - if (dest != SntpOurPort) + if (dest != sntp_our_port) return; +#ifdef CONFIG_TIMESTAMP /* - * As the RTC's used in U-Boot sepport second resolution only + * As the RTC's used in U-Boot support second resolution only * we simply ignore the sub-second field. */ memcpy(&seconds, &rpktp->transmit_timestamp, sizeof(ulong)); - to_tm(ntohl(seconds) - 2208988800UL + NetTimeOffset, &tm); + to_tm(ntohl(seconds) - 2208988800UL + net_ntp_time_offset, &tm); #if defined(CONFIG_CMD_DATE) rtc_set(&tm); #endif printf("Date: %4d-%02d-%02d Time: %2d:%02d:%02d\n", - tm.tm_year, tm.tm_mon, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); +#endif net_set_state(NETLOOP_SUCCESS); } -void -SntpStart(void) +void sntp_start(void) { debug("%s\n", __func__); - NetSetTimeout(SNTP_TIMEOUT, SntpTimeout); - net_set_udp_handler(SntpHandler); - memset(NetServerEther, 0, sizeof(NetServerEther)); + net_set_timeout_handler(SNTP_TIMEOUT, sntp_timeout_handler); + net_set_udp_handler(sntp_handler); + memset(net_server_ethaddr, 0, sizeof(net_server_ethaddr)); - SntpSend(); + sntp_send(); } @@ -53,6 +53,6 @@ struct sntp_pkt_t { unsigned long long transmit_timestamp; }; -extern void SntpStart(void); /* Begin SNTP */ +void sntp_start(void); /* Begin SNTP */ #endif /* __SNTP_H__ */ @@ -8,6 +8,7 @@ #include <common.h> #include <command.h> +#include <mapmem.h> #include <net.h> #include "tftp.h" #include "bootp.h" @@ -38,21 +39,21 @@ #define TFTP_ERROR 5 #define TFTP_OACK 6 -static ulong TftpTimeoutMSecs = TIMEOUT; -static int TftpTimeoutCountMax = TIMEOUT_COUNT; +static ulong timeout_ms = TIMEOUT; +static int timeout_count_max = TIMEOUT_COUNT; static ulong time_start; /* Record time we started tftp */ /* * These globals govern the timeout behavior when attempting a connection to a - * TFTP server. TftpRRQTimeoutMSecs specifies the number of milliseconds to + * TFTP server. tftp_timeout_ms specifies the number of milliseconds to * wait for the server to respond to initial connection. Second global, - * TftpRRQTimeoutCountMax, gives the number of such connection retries. - * TftpRRQTimeoutCountMax must be non-negative and TftpRRQTimeoutMSecs must be + * tftp_timeout_count_max, gives the number of such connection retries. + * tftp_timeout_count_max must be non-negative and tftp_timeout_ms must be * positive. The globals are meant to be set (and restored) by code needing * non-standard timeout behavior when initiating a TFTP transfer. */ -ulong TftpRRQTimeoutMSecs = TIMEOUT; -int TftpRRQTimeoutCountMax = TIMEOUT_COUNT; +ulong tftp_timeout_ms = TIMEOUT; +int tftp_timeout_count_max = TIMEOUT_COUNT; enum { TFTP_ERR_UNDEFINED = 0, @@ -64,32 +65,34 @@ enum { TFTP_ERR_FILE_ALREADY_EXISTS = 6, }; -static IPaddr_t TftpRemoteIP; +static struct in_addr tftp_remote_ip; /* The UDP port at their end */ -static int TftpRemotePort; +static int tftp_remote_port; /* The UDP port at our end */ -static int TftpOurPort; -static int TftpTimeoutCount; +static int tftp_our_port; +static int timeout_count; /* packet sequence number */ -static ulong TftpBlock; +static ulong tftp_cur_block; /* last packet sequence number received */ -static ulong TftpLastBlock; +static ulong tftp_prev_block; /* count of sequence number wraparounds */ -static ulong TftpBlockWrap; +static ulong tftp_block_wrap; /* memory offset due to wrapping */ -static ulong TftpBlockWrapOffset; -static int TftpState; +static ulong tftp_block_wrap_offset; +static int tftp_state; #ifdef CONFIG_TFTP_TSIZE /* The file size reported by the server */ -static int TftpTsize; +static int tftp_tsize; /* The number of hashes we printed */ -static short TftpNumchars; +static short tftp_tsize_num_hash; #endif #ifdef CONFIG_CMD_TFTPPUT -static int TftpWriting; /* 1 if writing, else 0 */ -static int TftpFinalBlock; /* 1 if we have sent the last block */ +/* 1 if writing, else 0 */ +static int tftp_put_active; +/* 1 if we have sent the last block */ +static int tftp_put_final_block_sent; #else -#define TftpWriting 0 +#define tftp_put_active 0 #endif #define STATE_SEND_RRQ 1 @@ -127,39 +130,42 @@ static char tftp_filename[MAX_LEN]; #define TFTP_MTU_BLOCKSIZE 1468 #endif -static unsigned short TftpBlkSize = TFTP_BLOCK_SIZE; -static unsigned short TftpBlkSizeOption = TFTP_MTU_BLOCKSIZE; +static unsigned short tftp_block_size = TFTP_BLOCK_SIZE; +static unsigned short tftp_block_size_option = TFTP_MTU_BLOCKSIZE; #ifdef CONFIG_MCAST_TFTP #include <malloc.h> #define MTFTP_BITMAPSIZE 0x1000 -static unsigned *Bitmap; -static int PrevBitmapHole, Mapsize = MTFTP_BITMAPSIZE; -static uchar ProhibitMcast, MasterClient; -static uchar Multicast; -static int Mcast_port; -static ulong TftpEndingBlock; /* can get 'last' block before done..*/ +static unsigned *tftp_mcast_bitmap; +static int tftp_mcast_prev_hole; +static int tftp_mcast_bitmap_size = MTFTP_BITMAPSIZE; +static int tftp_mcast_disabled; +static int tftp_mcast_master_client; +static int tftp_mcast_active; +static int tftp_mcast_port; +/* can get 'last' block before done..*/ +static ulong tftp_mcast_ending_block; static void parse_multicast_oack(char *pkt, int len); -static void -mcast_cleanup(void) +static void mcast_cleanup(void) { - if (Mcast_addr) - eth_mcast_join(Mcast_addr, 0); - if (Bitmap) - free(Bitmap); - Bitmap = NULL; - Mcast_addr = Multicast = Mcast_port = 0; - TftpEndingBlock = -1; + if (net_mcast_addr) + eth_mcast_join(net_mcast_addr, 0); + if (tftp_mcast_bitmap) + free(tftp_mcast_bitmap); + tftp_mcast_bitmap = NULL; + net_mcast_addr.s_addr = 0; + tftp_mcast_active = 0; + tftp_mcast_port = 0; + tftp_mcast_ending_block = -1; } #endif /* CONFIG_MCAST_TFTP */ -static inline void -store_block(int block, uchar *src, unsigned len) +static inline void store_block(int block, uchar *src, unsigned len) { - ulong offset = block * TftpBlkSize + TftpBlockWrapOffset; + ulong offset = block * tftp_block_size + tftp_block_wrap_offset; ulong newsize = offset + len; #ifdef CONFIG_SYS_DIRECT_FLASH_TFTP int i, rc = 0; @@ -184,25 +190,28 @@ store_block(int block, uchar *src, unsigned len) } else #endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */ { - (void)memcpy((void *)(load_addr + offset), src, len); + void *ptr = map_sysmem(load_addr + offset, len); + + memcpy(ptr, src, len); + unmap_sysmem(ptr); } #ifdef CONFIG_MCAST_TFTP - if (Multicast) - ext2_set_bit(block, Bitmap); + if (tftp_mcast_active) + ext2_set_bit(block, tftp_mcast_bitmap); #endif - if (NetBootFileXferSize < newsize) - NetBootFileXferSize = newsize; + if (net_boot_file_size < newsize) + net_boot_file_size = newsize; } /* Clear our state ready for a new transfer */ static void new_transfer(void) { - TftpLastBlock = 0; - TftpBlockWrap = 0; - TftpBlockWrapOffset = 0; + tftp_prev_block = 0; + tftp_block_wrap = 0; + tftp_block_wrap_offset = 0; #ifdef CONFIG_CMD_TFTPPUT - TftpFinalBlock = 0; + tftp_put_final_block_sent = 0; #endif } @@ -218,38 +227,39 @@ static void new_transfer(void) static int load_block(unsigned block, uchar *dst, unsigned len) { /* We may want to get the final block from the previous set */ - ulong offset = ((int)block - 1) * len + TftpBlockWrapOffset; + ulong offset = ((int)block - 1) * len + tftp_block_wrap_offset; ulong tosend = len; - tosend = min(NetBootFileXferSize - offset, tosend); + tosend = min(net_boot_file_size - offset, tosend); (void)memcpy(dst, (void *)(save_addr + offset), tosend); debug("%s: block=%d, offset=%ld, len=%d, tosend=%ld\n", __func__, - block, offset, len, tosend); + block, offset, len, tosend); return tosend; } #endif -static void TftpSend(void); -static void TftpTimeout(void); +static void tftp_send(void); +static void tftp_timeout_handler(void); /**********************************************************************/ static void show_block_marker(void) { #ifdef CONFIG_TFTP_TSIZE - if (TftpTsize) { - ulong pos = TftpBlock * TftpBlkSize + TftpBlockWrapOffset; + if (tftp_tsize) { + ulong pos = tftp_cur_block * tftp_block_size + + tftp_block_wrap_offset; - while (TftpNumchars < pos * 50 / TftpTsize) { + while (tftp_tsize_num_hash < pos * 50 / tftp_tsize) { putc('#'); - TftpNumchars++; + tftp_tsize_num_hash++; } } else #endif { - if (((TftpBlock - 1) % 10) == 0) + if (((tftp_cur_block - 1) % 10) == 0) putc('#'); - else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0) + else if ((tftp_cur_block % (10 * HASHES_PER_LINE)) == 0) puts("\n\t "); } } @@ -265,7 +275,7 @@ static void restart(const char *msg) #ifdef CONFIG_MCAST_TFTP mcast_cleanup(); #endif - NetStartAgain(); + net_start_again(); } /* @@ -281,10 +291,10 @@ static void update_block_number(void) * number of 0 this means that there was a wrap * around of the (16 bit) counter. */ - if (TftpBlock == 0 && TftpLastBlock != 0) { - TftpBlockWrap++; - TftpBlockWrapOffset += TftpBlkSize * TFTP_SEQUENCE_SIZE; - TftpTimeoutCount = 0; /* we've done well, reset thhe timeout */ + if (tftp_cur_block == 0 && tftp_prev_block != 0) { + tftp_block_wrap++; + tftp_block_wrap_offset += tftp_block_size * TFTP_SEQUENCE_SIZE; + timeout_count = 0; /* we've done well, reset the timeout */ } else { show_block_marker(); } @@ -295,25 +305,24 @@ static void tftp_complete(void) { #ifdef CONFIG_TFTP_TSIZE /* Print hash marks for the last packet received */ - while (TftpTsize && TftpNumchars < 49) { + while (tftp_tsize && tftp_tsize_num_hash < 49) { putc('#'); - TftpNumchars++; + tftp_tsize_num_hash++; } puts(" "); - print_size(TftpTsize, ""); + print_size(tftp_tsize, ""); #endif time_start = get_timer(time_start); if (time_start > 0) { puts("\n\t "); /* Line up with "Loading: " */ - print_size(NetBootFileXferSize / + print_size(net_boot_file_size / time_start * 1000, "/s"); } puts("\ndone\n"); net_set_state(NETLOOP_SUCCESS); } -static void -TftpSend(void) +static void tftp_send(void) { uchar *pkt; uchar *xp; @@ -322,24 +331,23 @@ TftpSend(void) #ifdef CONFIG_MCAST_TFTP /* Multicast TFTP.. non-MasterClients do not ACK data. */ - if (Multicast - && (TftpState == STATE_DATA) - && (MasterClient == 0)) + if (tftp_mcast_active && tftp_state == STATE_DATA && + tftp_mcast_master_client == 0) return; #endif /* * We will always be sending some sort of packet, so * cobble together the packet headers now. */ - pkt = NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; + pkt = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE; - switch (TftpState) { + switch (tftp_state) { case STATE_SEND_RRQ: case STATE_SEND_WRQ: xp = pkt; s = (ushort *)pkt; #ifdef CONFIG_CMD_TFTPPUT - *s++ = htons(TftpState == STATE_SEND_RRQ ? TFTP_RRQ : + *s++ = htons(tftp_state == STATE_SEND_RRQ ? TFTP_RRQ : TFTP_WRQ); #else *s++ = htons(TFTP_RRQ); @@ -351,23 +359,23 @@ TftpSend(void) pkt += 5 /*strlen("octet")*/ + 1; strcpy((char *)pkt, "timeout"); pkt += 7 /*strlen("timeout")*/ + 1; - sprintf((char *)pkt, "%lu", TftpTimeoutMSecs / 1000); + sprintf((char *)pkt, "%lu", timeout_ms / 1000); debug("send option \"timeout %s\"\n", (char *)pkt); pkt += strlen((char *)pkt) + 1; #ifdef CONFIG_TFTP_TSIZE - pkt += sprintf((char *)pkt, "tsize%c%lu%c", - 0, NetBootFileXferSize, 0); + pkt += sprintf((char *)pkt, "tsize%c%u%c", + 0, net_boot_file_size, 0); #endif /* try for more effic. blk size */ pkt += sprintf((char *)pkt, "blksize%c%d%c", - 0, TftpBlkSizeOption, 0); + 0, tftp_block_size_option, 0); #ifdef CONFIG_MCAST_TFTP /* Check all preconditions before even trying the option */ - if (!ProhibitMcast) { - Bitmap = malloc(Mapsize); - if (Bitmap && eth_get_dev()->mcast) { - free(Bitmap); - Bitmap = NULL; + if (!tftp_mcast_disabled) { + tftp_mcast_bitmap = malloc(tftp_mcast_bitmap_size); + if (tftp_mcast_bitmap && eth_get_dev()->mcast) { + free(tftp_mcast_bitmap); + tftp_mcast_bitmap = NULL; pkt += sprintf((char *)pkt, "multicast%c%c", 0, 0); } @@ -378,11 +386,12 @@ TftpSend(void) case STATE_OACK: #ifdef CONFIG_MCAST_TFTP - /* My turn! Start at where I need blocks I missed.*/ - if (Multicast) - TftpBlock = ext2_find_next_zero_bit(Bitmap, - (Mapsize*8), 0); - /*..falling..*/ + /* My turn! Start at where I need blocks I missed. */ + if (tftp_mcast_active) + tftp_cur_block = ext2_find_next_zero_bit( + tftp_mcast_bitmap, + tftp_mcast_bitmap_size * 8, 0); + /* fall through */ #endif case STATE_RECV_WRQ: @@ -390,16 +399,16 @@ TftpSend(void) xp = pkt; s = (ushort *)pkt; s[0] = htons(TFTP_ACK); - s[1] = htons(TftpBlock); + s[1] = htons(tftp_cur_block); pkt = (uchar *)(s + 2); #ifdef CONFIG_CMD_TFTPPUT - if (TftpWriting) { - int toload = TftpBlkSize; - int loaded = load_block(TftpBlock, pkt, toload); + if (tftp_put_active) { + int toload = tftp_block_size; + int loaded = load_block(tftp_cur_block, pkt, toload); s[0] = htons(TFTP_DATA); pkt += loaded; - TftpFinalBlock = (loaded < toload); + tftp_put_final_block_sent = (loaded < toload); } #endif len = pkt - xp; @@ -429,13 +438,14 @@ TftpSend(void) break; } - NetSendUDPPacket(NetServerEther, TftpRemoteIP, TftpRemotePort, - TftpOurPort, len); + net_send_udp_packet(net_server_ethaddr, tftp_remote_ip, + tftp_remote_port, tftp_our_port, len); } #ifdef CONFIG_CMD_TFTPPUT static void icmp_handler(unsigned type, unsigned code, unsigned dest, - IPaddr_t sip, unsigned src, uchar *pkt, unsigned len) + struct in_addr sip, unsigned src, uchar *pkt, + unsigned len) { if (type == ICMP_NOT_REACH && code == ICMP_NOT_REACH_PORT) { /* Oh dear the other end has gone away */ @@ -444,23 +454,22 @@ static void icmp_handler(unsigned type, unsigned code, unsigned dest, } #endif -static void -TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, - unsigned len) +static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip, + unsigned src, unsigned len) { __be16 proto; __be16 *s; int i; - if (dest != TftpOurPort) { + if (dest != tftp_our_port) { #ifdef CONFIG_MCAST_TFTP - if (Multicast - && (!Mcast_port || (dest != Mcast_port))) + if (tftp_mcast_active && + (!tftp_mcast_port || dest != tftp_mcast_port)) #endif return; } - if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort && - TftpState != STATE_RECV_WRQ && TftpState != STATE_SEND_WRQ) + if (tftp_state != STATE_SEND_RRQ && src != tftp_remote_port && + tftp_state != STATE_RECV_WRQ && tftp_state != STATE_SEND_WRQ) return; if (len < 2) @@ -471,14 +480,13 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, proto = *s++; pkt = (uchar *)s; switch (ntohs(proto)) { - case TFTP_RRQ: break; case TFTP_ACK: #ifdef CONFIG_CMD_TFTPPUT - if (TftpWriting) { - if (TftpFinalBlock) { + if (tftp_put_active) { + if (tftp_put_final_block_sent) { tftp_complete(); } else { /* @@ -486,12 +494,12 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, * count to wrap just like the other end! */ int block = ntohs(*s); - int ack_ok = (TftpBlock == block); + int ack_ok = (tftp_cur_block == block); - TftpBlock = (unsigned short)(block + 1); + tftp_cur_block = (unsigned short)(block + 1); update_block_number(); if (ack_ok) - TftpSend(); /* Send next data block */ + tftp_send(); /* Send next data block */ } } #endif @@ -503,102 +511,99 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, #ifdef CONFIG_CMD_TFTPSRV case TFTP_WRQ: debug("Got WRQ\n"); - TftpRemoteIP = sip; - TftpRemotePort = src; - TftpOurPort = 1024 + (get_timer(0) % 3072); + tftp_remote_ip = sip; + tftp_remote_port = src; + tftp_our_port = 1024 + (get_timer(0) % 3072); new_transfer(); - TftpSend(); /* Send ACK(0) */ + tftp_send(); /* Send ACK(0) */ break; #endif case TFTP_OACK: debug("Got OACK: %s %s\n", - pkt, - pkt + strlen((char *)pkt) + 1); - TftpState = STATE_OACK; - TftpRemotePort = src; + pkt, pkt + strlen((char *)pkt) + 1); + tftp_state = STATE_OACK; + tftp_remote_port = src; /* * Check for 'blksize' option. * Careful: "i" is signed, "len" is unsigned, thus * something like "len-8" may give a *huge* number */ for (i = 0; i+8 < len; i++) { - if (strcmp((char *)pkt+i, "blksize") == 0) { - TftpBlkSize = (unsigned short) - simple_strtoul((char *)pkt+i+8, NULL, - 10); + if (strcmp((char *)pkt + i, "blksize") == 0) { + tftp_block_size = (unsigned short) + simple_strtoul((char *)pkt + i + 8, + NULL, 10); debug("Blocksize ack: %s, %d\n", - (char *)pkt+i+8, TftpBlkSize); + (char *)pkt + i + 8, tftp_block_size); } #ifdef CONFIG_TFTP_TSIZE if (strcmp((char *)pkt+i, "tsize") == 0) { - TftpTsize = simple_strtoul((char *)pkt+i+6, + tftp_tsize = simple_strtoul((char *)pkt + i + 6, NULL, 10); debug("size = %s, %d\n", - (char *)pkt+i+6, TftpTsize); + (char *)pkt + i + 6, tftp_tsize); } #endif } #ifdef CONFIG_MCAST_TFTP - parse_multicast_oack((char *)pkt, len-1); - if ((Multicast) && (!MasterClient)) - TftpState = STATE_DATA; /* passive.. */ + parse_multicast_oack((char *)pkt, len - 1); + if ((tftp_mcast_active) && (!tftp_mcast_master_client)) + tftp_state = STATE_DATA; /* passive.. */ else #endif #ifdef CONFIG_CMD_TFTPPUT - if (TftpWriting) { + if (tftp_put_active) { /* Get ready to send the first block */ - TftpState = STATE_DATA; - TftpBlock++; + tftp_state = STATE_DATA; + tftp_cur_block++; } #endif - TftpSend(); /* Send ACK or first data block */ + tftp_send(); /* Send ACK or first data block */ break; case TFTP_DATA: if (len < 2) return; len -= 2; - TftpBlock = ntohs(*(__be16 *)pkt); + tftp_cur_block = ntohs(*(__be16 *)pkt); update_block_number(); - if (TftpState == STATE_SEND_RRQ) + if (tftp_state == STATE_SEND_RRQ) debug("Server did not acknowledge timeout option!\n"); - if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK || - TftpState == STATE_RECV_WRQ) { + if (tftp_state == STATE_SEND_RRQ || tftp_state == STATE_OACK || + tftp_state == STATE_RECV_WRQ) { /* first block received */ - TftpState = STATE_DATA; - TftpRemotePort = src; + tftp_state = STATE_DATA; + tftp_remote_port = src; new_transfer(); #ifdef CONFIG_MCAST_TFTP - if (Multicast) { /* start!=1 common if mcast */ - TftpLastBlock = TftpBlock - 1; + if (tftp_mcast_active) { /* start!=1 common if mcast */ + tftp_prev_block = tftp_cur_block - 1; } else #endif - if (TftpBlock != 1) { /* Assertion */ - printf("\nTFTP error: " - "First block is not block 1 (%ld)\n" - "Starting again\n\n", - TftpBlock); - NetStartAgain(); + if (tftp_cur_block != 1) { /* Assertion */ + puts("\nTFTP error: "); + printf("First block is not block 1 (%ld)\n", + tftp_cur_block); + puts("Starting again\n\n"); + net_start_again(); break; } } - if (TftpBlock == TftpLastBlock) { - /* - * Same block again; ignore it. - */ + if (tftp_cur_block == tftp_prev_block) { + /* Same block again; ignore it. */ break; } - TftpLastBlock = TftpBlock; - TftpTimeoutCountMax = TIMEOUT_COUNT; - NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); + tftp_prev_block = tftp_cur_block; + timeout_count_max = TIMEOUT_COUNT; + net_set_timeout_handler(timeout_ms, tftp_timeout_handler); - store_block(TftpBlock - 1, pkt + 2, len); + store_block(tftp_cur_block - 1, pkt + 2, len); /* * Acknowledge the block just received, which will prompt @@ -608,39 +613,41 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, /* if I am the MasterClient, actively calculate what my next * needed block is; else I'm passive; not ACKING */ - if (Multicast) { - if (len < TftpBlkSize) { - TftpEndingBlock = TftpBlock; - } else if (MasterClient) { - TftpBlock = PrevBitmapHole = - ext2_find_next_zero_bit( - Bitmap, - (Mapsize*8), - PrevBitmapHole); - if (TftpBlock > ((Mapsize*8) - 1)) { - printf("tftpfile too big\n"); + if (tftp_mcast_active) { + if (len < tftp_block_size) { + tftp_mcast_ending_block = tftp_cur_block; + } else if (tftp_mcast_master_client) { + tftp_mcast_prev_hole = ext2_find_next_zero_bit( + tftp_mcast_bitmap, + tftp_mcast_bitmap_size * 8, + tftp_mcast_prev_hole); + tftp_cur_block = tftp_mcast_prev_hole; + if (tftp_cur_block > + ((tftp_mcast_bitmap_size * 8) - 1)) { + debug("tftpfile too big\n"); /* try to double it and retry */ - Mapsize <<= 1; + tftp_mcast_bitmap_size <<= 1; mcast_cleanup(); - NetStartAgain(); + net_start_again(); return; } - TftpLastBlock = TftpBlock; + tftp_prev_block = tftp_cur_block; } } #endif - TftpSend(); + tftp_send(); #ifdef CONFIG_MCAST_TFTP - if (Multicast) { - if (MasterClient && (TftpBlock >= TftpEndingBlock)) { + if (tftp_mcast_active) { + if (tftp_mcast_master_client && + (tftp_cur_block >= tftp_mcast_ending_block)) { puts("\nMulticast tftp done\n"); mcast_cleanup(); net_set_state(NETLOOP_SUCCESS); } } else #endif - if (len < TftpBlkSize) + if (len < tftp_block_size) tftp_complete(); break; @@ -665,7 +672,7 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, #ifdef CONFIG_MCAST_TFTP mcast_cleanup(); #endif - NetStartAgain(); + net_start_again(); break; } break; @@ -673,21 +680,20 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, } -static void -TftpTimeout(void) +static void tftp_timeout_handler(void) { - if (++TftpTimeoutCount > TftpTimeoutCountMax) { + if (++timeout_count > timeout_count_max) { restart("Retry count exceeded"); } else { puts("T "); - NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); - if (TftpState != STATE_RECV_WRQ) - TftpSend(); + net_set_timeout_handler(timeout_ms, tftp_timeout_handler); + if (tftp_state != STATE_RECV_WRQ) + tftp_send(); } } -void TftpStart(enum proto_t protocol) +void tftp_start(enum proto_t protocol) { char *ep; /* Environment pointer */ @@ -697,45 +703,44 @@ void TftpStart(enum proto_t protocol) */ ep = getenv("tftpblocksize"); if (ep != NULL) - TftpBlkSizeOption = simple_strtol(ep, NULL, 10); + tftp_block_size_option = simple_strtol(ep, NULL, 10); ep = getenv("tftptimeout"); if (ep != NULL) - TftpTimeoutMSecs = simple_strtol(ep, NULL, 10); + timeout_ms = simple_strtol(ep, NULL, 10); - if (TftpTimeoutMSecs < 1000) { - printf("TFTP timeout (%ld ms) too low, " - "set minimum = 1000 ms\n", - TftpTimeoutMSecs); - TftpTimeoutMSecs = 1000; + if (timeout_ms < 1000) { + printf("TFTP timeout (%ld ms) too low, set min = 1000 ms\n", + timeout_ms); + timeout_ms = 1000; } debug("TFTP blocksize = %i, timeout = %ld ms\n", - TftpBlkSizeOption, TftpTimeoutMSecs); + tftp_block_size_option, timeout_ms); - TftpRemoteIP = NetServerIP; - if (BootFile[0] == '\0') { + tftp_remote_ip = net_server_ip; + if (net_boot_file_name[0] == '\0') { sprintf(default_filename, "%02X%02X%02X%02X.img", - NetOurIP & 0xFF, - (NetOurIP >> 8) & 0xFF, - (NetOurIP >> 16) & 0xFF, - (NetOurIP >> 24) & 0xFF); + net_ip.s_addr & 0xFF, + (net_ip.s_addr >> 8) & 0xFF, + (net_ip.s_addr >> 16) & 0xFF, + (net_ip.s_addr >> 24) & 0xFF); strncpy(tftp_filename, default_filename, MAX_LEN); - tftp_filename[MAX_LEN-1] = 0; + tftp_filename[MAX_LEN - 1] = 0; printf("*** Warning: no boot file name; using '%s'\n", - tftp_filename); + tftp_filename); } else { - char *p = strchr(BootFile, ':'); + char *p = strchr(net_boot_file_name, ':'); if (p == NULL) { - strncpy(tftp_filename, BootFile, MAX_LEN); - tftp_filename[MAX_LEN-1] = 0; + strncpy(tftp_filename, net_boot_file_name, MAX_LEN); + tftp_filename[MAX_LEN - 1] = 0; } else { - TftpRemoteIP = string_to_ip(BootFile); + tftp_remote_ip = string_to_ip(net_boot_file_name); strncpy(tftp_filename, p + 1, MAX_LEN); - tftp_filename[MAX_LEN-1] = 0; + tftp_filename[MAX_LEN - 1] = 0; } } @@ -744,124 +749,127 @@ void TftpStart(enum proto_t protocol) #ifdef CONFIG_CMD_TFTPPUT protocol == TFTPPUT ? "to" : "from", #else - "from", + "from", #endif - &TftpRemoteIP, &NetOurIP); + &tftp_remote_ip, &net_ip); /* Check if we need to send across this subnet */ - if (NetOurGatewayIP && NetOurSubnetMask) { - IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; - IPaddr_t RemoteNet = TftpRemoteIP & NetOurSubnetMask; - - if (OurNet != RemoteNet) - printf("; sending through gateway %pI4", - &NetOurGatewayIP); + if (net_gateway.s_addr && net_netmask.s_addr) { + struct in_addr our_net; + struct in_addr remote_net; + + our_net.s_addr = net_ip.s_addr & net_netmask.s_addr; + remote_net.s_addr = tftp_remote_ip.s_addr & net_netmask.s_addr; + if (our_net.s_addr != remote_net.s_addr) + printf("; sending through gateway %pI4", &net_gateway); } putc('\n'); printf("Filename '%s'.", tftp_filename); - if (NetBootFileSize) { - printf(" Size is 0x%x Bytes = ", NetBootFileSize<<9); - print_size(NetBootFileSize<<9, ""); + if (net_boot_file_expected_size_in_blocks) { + printf(" Size is 0x%x Bytes = ", + net_boot_file_expected_size_in_blocks << 9); + print_size(net_boot_file_expected_size_in_blocks << 9, ""); } putc('\n'); #ifdef CONFIG_CMD_TFTPPUT - TftpWriting = (protocol == TFTPPUT); - if (TftpWriting) { + tftp_put_active = (protocol == TFTPPUT); + if (tftp_put_active) { printf("Save address: 0x%lx\n", save_addr); printf("Save size: 0x%lx\n", save_size); - NetBootFileXferSize = save_size; + net_boot_file_size = save_size; puts("Saving: *\b"); - TftpState = STATE_SEND_WRQ; + tftp_state = STATE_SEND_WRQ; new_transfer(); } else #endif { printf("Load address: 0x%lx\n", load_addr); puts("Loading: *\b"); - TftpState = STATE_SEND_RRQ; + tftp_state = STATE_SEND_RRQ; } time_start = get_timer(0); - TftpTimeoutCountMax = TftpRRQTimeoutCountMax; + timeout_count_max = tftp_timeout_count_max; - NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); - net_set_udp_handler(TftpHandler); + net_set_timeout_handler(timeout_ms, tftp_timeout_handler); + net_set_udp_handler(tftp_handler); #ifdef CONFIG_CMD_TFTPPUT net_set_icmp_handler(icmp_handler); #endif - TftpRemotePort = WELL_KNOWN_PORT; - TftpTimeoutCount = 0; + tftp_remote_port = WELL_KNOWN_PORT; + timeout_count = 0; /* Use a pseudo-random port unless a specific port is set */ - TftpOurPort = 1024 + (get_timer(0) % 3072); + tftp_our_port = 1024 + (get_timer(0) % 3072); #ifdef CONFIG_TFTP_PORT ep = getenv("tftpdstp"); if (ep != NULL) - TftpRemotePort = simple_strtol(ep, NULL, 10); + tftp_remote_port = simple_strtol(ep, NULL, 10); ep = getenv("tftpsrcp"); if (ep != NULL) - TftpOurPort = simple_strtol(ep, NULL, 10); + tftp_our_port = simple_strtol(ep, NULL, 10); #endif - TftpBlock = 0; + tftp_cur_block = 0; /* zero out server ether in case the server ip has changed */ - memset(NetServerEther, 0, 6); - /* Revert TftpBlkSize to dflt */ - TftpBlkSize = TFTP_BLOCK_SIZE; + memset(net_server_ethaddr, 0, 6); + /* Revert tftp_block_size to dflt */ + tftp_block_size = TFTP_BLOCK_SIZE; #ifdef CONFIG_MCAST_TFTP mcast_cleanup(); #endif #ifdef CONFIG_TFTP_TSIZE - TftpTsize = 0; - TftpNumchars = 0; + tftp_tsize = 0; + tftp_tsize_num_hash = 0; #endif - TftpSend(); + tftp_send(); } #ifdef CONFIG_CMD_TFTPSRV -void -TftpStartServer(void) +void tftp_start_server(void) { tftp_filename[0] = 0; printf("Using %s device\n", eth_get_name()); - printf("Listening for TFTP transfer on %pI4\n", &NetOurIP); + printf("Listening for TFTP transfer on %pI4\n", &net_ip); printf("Load address: 0x%lx\n", load_addr); puts("Loading: *\b"); - TftpTimeoutCountMax = TIMEOUT_COUNT; - TftpTimeoutCount = 0; - TftpTimeoutMSecs = TIMEOUT; - NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); + timeout_count_max = TIMEOUT_COUNT; + timeout_count = 0; + timeout_ms = TIMEOUT; + net_set_timeout_handler(timeout_ms, tftp_timeout_handler); - /* Revert TftpBlkSize to dflt */ - TftpBlkSize = TFTP_BLOCK_SIZE; - TftpBlock = 0; - TftpOurPort = WELL_KNOWN_PORT; + /* Revert tftp_block_size to dflt */ + tftp_block_size = TFTP_BLOCK_SIZE; + tftp_cur_block = 0; + tftp_our_port = WELL_KNOWN_PORT; #ifdef CONFIG_TFTP_TSIZE - TftpTsize = 0; - TftpNumchars = 0; + tftp_tsize = 0; + tftp_tsize_num_hash = 0; #endif - TftpState = STATE_RECV_WRQ; - net_set_udp_handler(TftpHandler); + tftp_state = STATE_RECV_WRQ; + net_set_udp_handler(tftp_handler); /* zero out server ether in case the server ip has changed */ - memset(NetServerEther, 0, 6); + memset(net_server_ethaddr, 0, 6); } #endif /* CONFIG_CMD_TFTPSRV */ #ifdef CONFIG_MCAST_TFTP -/* Credits: atftp project. +/* + * Credits: atftp project. */ -/* pick up BcastAddr, Port, and whether I am [now] the master-client. * +/* + * Pick up BcastAddr, Port, and whether I am [now] the master-client. * Frame: * +-------+-----------+---+-------~~-------+---+ * | opc | multicast | 0 | addr, port, mc | 0 | @@ -876,75 +884,80 @@ TftpStartServer(void) static void parse_multicast_oack(char *pkt, int len) { int i; - IPaddr_t addr; - char *mc_adr, *port, *mc; - - mc_adr = port = mc = NULL; + struct in_addr addr; + char *mc_adr; + char *port; + char *mc; + + mc_adr = NULL; + port = NULL; + mc = NULL; /* march along looking for 'multicast\0', which has to start at least * 14 bytes back from the end. */ - for (i = 0; i < len-14; i++) - if (strcmp(pkt+i, "multicast") == 0) + for (i = 0; i < len - 14; i++) + if (strcmp(pkt + i, "multicast") == 0) break; - if (i >= (len-14)) /* non-Multicast OACK, ign. */ + if (i >= (len - 14)) /* non-Multicast OACK, ign. */ return; i += 10; /* strlen multicast */ - mc_adr = pkt+i; + mc_adr = pkt + i; for (; i < len; i++) { - if (*(pkt+i) == ',') { - *(pkt+i) = '\0'; + if (*(pkt + i) == ',') { + *(pkt + i) = '\0'; if (port) { - mc = pkt+i+1; + mc = pkt + i + 1; break; } else { - port = pkt+i+1; + port = pkt + i + 1; } } } if (!port || !mc_adr || !mc) return; - if (Multicast && MasterClient) { + if (tftp_mcast_active && tftp_mcast_master_client) { printf("I got a OACK as master Client, WRONG!\n"); return; } /* ..I now accept packets destined for this MCAST addr, port */ - if (!Multicast) { - if (Bitmap) { + if (!tftp_mcast_active) { + if (tftp_mcast_bitmap) { printf("Internal failure! no mcast.\n"); - free(Bitmap); - Bitmap = NULL; - ProhibitMcast = 1; - return ; + free(tftp_mcast_bitmap); + tftp_mcast_bitmap = NULL; + tftp_mcast_disabled = 1; + return; } /* I malloc instead of pre-declare; so that if the file ends * up being too big for this bitmap I can retry */ - Bitmap = malloc(Mapsize); - if (!Bitmap) { - printf("No Bitmap, no multicast. Sorry.\n"); - ProhibitMcast = 1; + tftp_mcast_bitmap = malloc(tftp_mcast_bitmap_size); + if (!tftp_mcast_bitmap) { + printf("No bitmap, no multicast. Sorry.\n"); + tftp_mcast_disabled = 1; return; } - memset(Bitmap, 0, Mapsize); - PrevBitmapHole = 0; - Multicast = 1; + memset(tftp_mcast_bitmap, 0, tftp_mcast_bitmap_size); + tftp_mcast_prev_hole = 0; + tftp_mcast_active = 1; } addr = string_to_ip(mc_adr); - if (Mcast_addr != addr) { - if (Mcast_addr) - eth_mcast_join(Mcast_addr, 0); - Mcast_addr = addr; - if (eth_mcast_join(Mcast_addr, 1)) { + if (net_mcast_addr.s_addr != addr.s_addr) { + if (net_mcast_addr.s_addr) + eth_mcast_join(net_mcast_addr, 0); + net_mcast_addr = addr; + if (eth_mcast_join(net_mcast_addr, 1)) { printf("Fail to set mcast, revert to TFTP\n"); - ProhibitMcast = 1; + tftp_mcast_disabled = 1; mcast_cleanup(); - NetStartAgain(); + net_start_again(); } } - MasterClient = (unsigned char)simple_strtoul((char *)mc, NULL, 10); - Mcast_port = (unsigned short)simple_strtoul(port, NULL, 10); - printf("Multicast: %s:%d [%d]\n", mc_adr, Mcast_port, MasterClient); + tftp_mcast_master_client = simple_strtoul((char *)mc, NULL, 10); + tftp_mcast_port = (unsigned short)simple_strtoul(port, NULL, 10); + printf("Multicast: %s:%d [%d]\n", mc_adr, tftp_mcast_port, + tftp_mcast_master_client); return; } @@ -16,14 +16,14 @@ */ /* tftp.c */ -void TftpStart(enum proto_t protocol); /* Begin TFTP get/put */ +void tftp_start(enum proto_t protocol); /* Begin TFTP get/put */ #ifdef CONFIG_CMD_TFTPSRV -extern void TftpStartServer(void); /* Wait for incoming TFTP put */ +void tftp_start_server(void); /* Wait for incoming TFTP put */ #endif -extern ulong TftpRRQTimeoutMSecs; -extern int TftpRRQTimeoutCountMax; +extern ulong tftp_timeout_ms; +extern int tftp_timeout_count_max; /**********************************************************************/ diff --git a/post/cpu/mpc8xx/ether.c b/post/cpu/mpc8xx/ether.c index 3a8b483..1b75eb6 100644 --- a/post/cpu/mpc8xx/ether.c +++ b/post/cpu/mpc8xx/ether.c @@ -212,7 +212,7 @@ static void scc_init (int scc_index) for (i = 0; i < PKTBUFSRX; i++) { rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; rtx->rxbd[i].cbd_datlen = 0; /* Reset */ - rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i]; + rtx->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i]; } rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; @@ -405,8 +405,8 @@ static int scc_recv (int index, void *packet, int max_length) if (!(rtx->rxbd[rxIdx].cbd_sc & 0x003f)) { length = rtx->rxbd[rxIdx].cbd_datlen - 4; memcpy (packet, - (void *) (NetRxPackets[rxIdx]), - length < max_length ? length : max_length); + (void *)(net_rx_packets[rxIdx]), + length < max_length ? length : max_length); } /* Give the buffer back to the SCC. */ diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index fcacb7f..ea67137 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -149,7 +149,7 @@ endif boot.bin: $(obj)/u-boot-spl.bin $(call if_changed,mkimage) -ALL-y += $(obj)/$(SPL_BIN).bin +ALL-y += $(obj)/$(SPL_BIN).bin $(obj)/$(SPL_BIN).cfg ifdef CONFIG_SAMSUNG ALL-y += $(obj)/$(BOARD)-spl.bin @@ -165,6 +165,13 @@ endif all: $(ALL-y) +quiet_cmd_cpp_cfg = CFG $@ +cmd_cpp_cfg = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \ + -D__ASSEMBLY__ -x assembler-with-cpp -P -dM -E -o $@ $< + +$(obj)/$(SPL_BIN).cfg: include/config.h + $(call if_changed,cpp_cfg) + ifdef CONFIG_SAMSUNG ifdef CONFIG_VAR_SIZE_SPL VAR_SIZE_PARAM = --vs diff --git a/test/compression.c b/test/compression.c index ea2e4ad..7ef3a8c 100644 --- a/test/compression.c +++ b/test/compression.c @@ -10,6 +10,7 @@ #include <bootm.h> #include <command.h> #include <malloc.h> +#include <mapmem.h> #include <asm/io.h> #include <u-boot/zlib.h> diff --git a/test/dm/Makefile b/test/dm/Makefile index 612aa95..fd9e29f 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -17,8 +17,11 @@ obj-$(CONFIG_DM_TEST) += ut.o obj-$(CONFIG_DM_TEST) += core.o obj-$(CONFIG_DM_TEST) += ut.o ifneq ($(CONFIG_SANDBOX),) +obj-$(CONFIG_DM_ETH) += eth.o obj-$(CONFIG_DM_GPIO) += gpio.o -obj-$(CONFIG_DM_SPI) += spi.o -obj-$(CONFIG_DM_SPI_FLASH) += sf.o obj-$(CONFIG_DM_I2C) += i2c.o +obj-$(CONFIG_DM_PCI) += pci.o +obj-$(CONFIG_DM_SPI_FLASH) += sf.o +obj-$(CONFIG_DM_SPI) += spi.o +obj-$(CONFIG_DM_USB) += usb.o endif diff --git a/test/dm/bus.c b/test/dm/bus.c index faffe6a..116a52d 100644 --- a/test/dm/bus.c +++ b/test/dm/bus.c @@ -273,20 +273,22 @@ DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); /* As above but the size is controlled by the uclass */ static int dm_test_bus_parent_data_uclass(struct dm_test_state *dms) { + struct driver *drv; struct udevice *bus; int size; int ret; /* Set the driver size to 0 so that the uclass size is used */ ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); - size = bus->driver->per_child_auto_alloc_size; + drv = (struct driver *)bus->driver; + size = drv->per_child_auto_alloc_size; bus->uclass->uc_drv->per_child_auto_alloc_size = size; - bus->driver->per_child_auto_alloc_size = 0; + drv->per_child_auto_alloc_size = 0; ret = test_bus_parent_data(dms); if (ret) return ret; bus->uclass->uc_drv->per_child_auto_alloc_size = 0; - bus->driver->per_child_auto_alloc_size = size; + drv->per_child_auto_alloc_size = size; return 0; } @@ -414,19 +416,21 @@ DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); static int dm_test_bus_parent_platdata_uclass(struct dm_test_state *dms) { struct udevice *bus; + struct driver *drv; int size; int ret; /* Set the driver size to 0 so that the uclass size is used */ ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); - size = bus->driver->per_child_platdata_auto_alloc_size; + drv = (struct driver *)bus->driver; + size = drv->per_child_platdata_auto_alloc_size; bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size; - bus->driver->per_child_platdata_auto_alloc_size = 0; + drv->per_child_platdata_auto_alloc_size = 0; ret = test_bus_parent_platdata(dms); if (ret) return ret; bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0; - bus->driver->per_child_platdata_auto_alloc_size = size; + drv->per_child_platdata_auto_alloc_size = size; return 0; } diff --git a/test/dm/cmd_dm.c b/test/dm/cmd_dm.c index 79a674e..2f527e9 100644 --- a/test/dm/cmd_dm.c +++ b/test/dm/cmd_dm.c @@ -10,6 +10,7 @@ #include <common.h> #include <dm.h> #include <malloc.h> +#include <mapmem.h> #include <errno.h> #include <asm/io.h> #include <dm/root.h> @@ -77,8 +78,8 @@ static void dm_display_line(struct udevice *dev) printf("- %c %s @ %08lx", dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ', dev->name, (ulong)map_to_sysmem(dev)); - if (dev->req_seq != -1) - printf(", %d", dev->req_seq); + if (dev->seq != -1 || dev->req_seq != -1) + printf(", seq %d, (req %d)", dev->seq, dev->req_seq); puts("\n"); } @@ -112,7 +113,12 @@ static int do_dm_dump_uclass(cmd_tbl_t *cmdtp, int flag, int argc, static int do_dm_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - return dm_test_main(); + const char *test_name = NULL; + + if (argc > 0) + test_name = argv[0]; + + return dm_test_main(test_name); } #define TEST_HELP "\ndm test Run tests" #else @@ -132,7 +138,7 @@ static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) cmd_tbl_t *test_cmd; int ret; - if (argc != 2) + if (argc < 2) return CMD_RET_USAGE; test_cmd = find_cmd_tbl(argv[1], test_commands, ARRAY_SIZE(test_commands)); @@ -147,7 +153,7 @@ static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } U_BOOT_CMD( - dm, 2, 1, do_dm, + dm, 3, 1, do_dm, "Driver model low level access", "tree Dump driver model tree ('*' = activated)\n" "dm uclass Dump list of instances for each uclass" diff --git a/test/dm/core.c b/test/dm/core.c index eccda09..91be1e5 100644 --- a/test/dm/core.c +++ b/test/dm/core.c @@ -129,6 +129,61 @@ static int dm_test_autobind(struct dm_test_state *dms) } DM_TEST(dm_test_autobind, 0); +/* Test that binding with uclass platdata allocation occurs correctly */ +static int dm_test_autobind_uclass_pdata_alloc(struct dm_test_state *dms) +{ + struct dm_test_perdev_uc_pdata *uc_pdata; + struct udevice *dev; + struct uclass *uc; + + ut_assertok(uclass_get(UCLASS_TEST, &uc)); + ut_assert(uc); + + /** + * Test if test uclass driver requires allocation for the uclass + * platform data and then check the dev->uclass_platdata pointer. + */ + ut_assert(uc->uc_drv->per_device_platdata_auto_alloc_size); + + for (uclass_find_first_device(UCLASS_TEST, &dev); + dev; + uclass_find_next_device(&dev)) { + ut_assert(dev); + + uc_pdata = dev_get_uclass_platdata(dev); + ut_assert(uc_pdata); + } + + return 0; +} +DM_TEST(dm_test_autobind_uclass_pdata_alloc, DM_TESTF_SCAN_PDATA); + +/* Test that binding with uclass platdata setting occurs correctly */ +static int dm_test_autobind_uclass_pdata_valid(struct dm_test_state *dms) +{ + struct dm_test_perdev_uc_pdata *uc_pdata; + struct udevice *dev; + + /** + * In the test_postbind() method of test uclass driver, the uclass + * platform data should be set to three test int values - test it. + */ + for (uclass_find_first_device(UCLASS_TEST, &dev); + dev; + uclass_find_next_device(&dev)) { + ut_assert(dev); + + uc_pdata = dev_get_uclass_platdata(dev); + ut_assert(uc_pdata); + ut_assert(uc_pdata->intval1 == TEST_UC_PDATA_INTVAL1); + ut_assert(uc_pdata->intval2 == TEST_UC_PDATA_INTVAL2); + ut_assert(uc_pdata->intval3 == TEST_UC_PDATA_INTVAL3); + } + + return 0; +} +DM_TEST(dm_test_autobind_uclass_pdata_valid, DM_TESTF_SCAN_PDATA); + /* Test that autoprobe finds all the expected devices */ static int dm_test_autoprobe(struct dm_test_state *dms) { @@ -141,6 +196,7 @@ static int dm_test_autoprobe(struct dm_test_state *dms) ut_assert(uc); ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]); + ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]); ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]); /* The root device should not be activated until needed */ @@ -167,8 +223,12 @@ static int dm_test_autoprobe(struct dm_test_state *dms) ut_assert(dms->root->flags & DM_FLAG_ACTIVATED); } - /* Our 3 dm_test_infox children should be passed to post_probe */ + /* + * Our 3 dm_test_info children should be passed to pre_probe and + * post_probe + */ ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]); + ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]); /* Also we can check the per-device data */ expected_base_add = 0; @@ -179,7 +239,7 @@ static int dm_test_autoprobe(struct dm_test_state *dms) ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev)); ut_assert(dev); - priv = dev->uclass_priv; + priv = dev_get_uclass_priv(dev); ut_assert(priv); ut_asserteq(expected_base_add, priv->base_add); @@ -591,14 +651,130 @@ static int dm_test_uclass_before_ready(struct dm_test_state *dms) ut_assertok(uclass_get(UCLASS_TEST, &uc)); - memset(gd, '\0', sizeof(*gd)); + gd->dm_root = NULL; + gd->dm_root_f = NULL; + memset(&gd->uclass_root, '\0', sizeof(gd->uclass_root)); + ut_asserteq_ptr(NULL, uclass_find(UCLASS_TEST)); return 0; } - DM_TEST(dm_test_uclass_before_ready, 0); +static int dm_test_uclass_devices_find(struct dm_test_state *dms) +{ + struct udevice *dev; + int ret; + + for (ret = uclass_find_first_device(UCLASS_TEST, &dev); + dev; + ret = uclass_find_next_device(&dev)) { + ut_assert(!ret); + ut_assert(dev); + } + + return 0; +} +DM_TEST(dm_test_uclass_devices_find, DM_TESTF_SCAN_PDATA); + +static int dm_test_uclass_devices_find_by_name(struct dm_test_state *dms) +{ + struct udevice *finddev; + struct udevice *testdev; + int findret, ret; + + /* + * For each test device found in fdt like: "a-test", "b-test", etc., + * use its name and try to find it by uclass_find_device_by_name(). + * Then, on success check if: + * - current 'testdev' name is equal to the returned 'finddev' name + * - current 'testdev' pointer is equal to the returned 'finddev' + * + * We assume that, each uclass's device name is unique, so if not, then + * this will fail on checking condition: testdev == finddev, since the + * uclass_find_device_by_name(), returns the first device by given name. + */ + for (ret = uclass_find_first_device(UCLASS_TEST_FDT, &testdev); + testdev; + ret = uclass_find_next_device(&testdev)) { + ut_assertok(ret); + ut_assert(testdev); + + findret = uclass_find_device_by_name(UCLASS_TEST_FDT, + testdev->name, + &finddev); + + ut_assertok(findret); + ut_assert(testdev); + ut_asserteq_str(testdev->name, finddev->name); + ut_asserteq_ptr(testdev, finddev); + } + + return 0; +} +DM_TEST(dm_test_uclass_devices_find_by_name, DM_TESTF_SCAN_FDT); + +static int dm_test_uclass_devices_get(struct dm_test_state *dms) +{ + struct udevice *dev; + int ret; + + for (ret = uclass_first_device(UCLASS_TEST, &dev); + dev; + ret = uclass_next_device(&dev)) { + ut_assert(!ret); + ut_assert(dev); + ut_assert(device_active(dev)); + } + + return 0; +} +DM_TEST(dm_test_uclass_devices_get, DM_TESTF_SCAN_PDATA); + +static int dm_test_uclass_devices_get_by_name(struct dm_test_state *dms) +{ + struct udevice *finddev; + struct udevice *testdev; + int ret, findret; + + /* + * For each test device found in fdt like: "a-test", "b-test", etc., + * use its name and try to get it by uclass_get_device_by_name(). + * On success check if: + * - returned finddev' is active + * - current 'testdev' name is equal to the returned 'finddev' name + * - current 'testdev' pointer is equal to the returned 'finddev' + * + * We asserts that the 'testdev' is active on each loop entry, so we + * could be sure that the 'finddev' is activated too, but for sure + * we check it again. + * + * We assume that, each uclass's device name is unique, so if not, then + * this will fail on checking condition: testdev == finddev, since the + * uclass_get_device_by_name(), returns the first device by given name. + */ + for (ret = uclass_first_device(UCLASS_TEST_FDT, &testdev); + testdev; + ret = uclass_next_device(&testdev)) { + ut_assertok(ret); + ut_assert(testdev); + ut_assert(device_active(testdev)); + + findret = uclass_get_device_by_name(UCLASS_TEST_FDT, + testdev->name, + &finddev); + + ut_assertok(findret); + ut_assert(finddev); + ut_assert(device_active(finddev)); + ut_asserteq_str(testdev->name, finddev->name); + ut_asserteq_ptr(testdev, finddev); + } + + return 0; +} +DM_TEST(dm_test_uclass_devices_get_by_name, DM_TESTF_SCAN_FDT); + static int dm_test_device_get_uclass_id(struct dm_test_state *dms) { struct udevice *dev; diff --git a/test/dm/eth.c b/test/dm/eth.c new file mode 100644 index 0000000..4891f3a --- /dev/null +++ b/test/dm/eth.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2015 National Instruments + * + * (C) Copyright 2015 + * Joe Hershberger <joe.hershberger@ni.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <dm/test.h> +#include <dm/ut.h> +#include <fdtdec.h> +#include <malloc.h> +#include <net.h> +#include <asm/eth.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int dm_test_eth(struct dm_test_state *dms) +{ + net_ping_ip = string_to_ip("1.1.2.2"); + + setenv("ethact", "eth@10002000"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10002000", getenv("ethact")); + + setenv("ethact", "eth@10003000"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10003000", getenv("ethact")); + + setenv("ethact", "eth@10004000"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10004000", getenv("ethact")); + + return 0; +} +DM_TEST(dm_test_eth, DM_TESTF_SCAN_FDT); + +static int dm_test_eth_alias(struct dm_test_state *dms) +{ + net_ping_ip = string_to_ip("1.1.2.2"); + setenv("ethact", "eth0"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10002000", getenv("ethact")); + + setenv("ethact", "eth1"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10004000", getenv("ethact")); + + /* Expected to fail since eth2 is not defined in the device tree */ + setenv("ethact", "eth2"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10002000", getenv("ethact")); + + setenv("ethact", "eth5"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10003000", getenv("ethact")); + + return 0; +} +DM_TEST(dm_test_eth_alias, DM_TESTF_SCAN_FDT); + +static int dm_test_eth_prime(struct dm_test_state *dms) +{ + net_ping_ip = string_to_ip("1.1.2.2"); + + /* Expected to be "eth@10003000" because of ethprime variable */ + setenv("ethact", NULL); + setenv("ethprime", "eth5"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10003000", getenv("ethact")); + + /* Expected to be "eth@10002000" because it is first */ + setenv("ethact", NULL); + setenv("ethprime", NULL); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10002000", getenv("ethact")); + + return 0; +} +DM_TEST(dm_test_eth_prime, DM_TESTF_SCAN_FDT); + +static int dm_test_eth_rotate(struct dm_test_state *dms) +{ + char ethaddr[18]; + + /* Invalidate eth1's MAC address */ + net_ping_ip = string_to_ip("1.1.2.2"); + strcpy(ethaddr, getenv("eth1addr")); + setenv("eth1addr", NULL); + + /* Make sure that the default is to rotate to the next interface */ + setenv("ethact", "eth@10004000"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10002000", getenv("ethact")); + + /* If ethrotate is no, then we should fail on a bad MAC */ + setenv("ethact", "eth@10004000"); + setenv("ethrotate", "no"); + ut_asserteq(-EINVAL, net_loop(PING)); + ut_asserteq_str("eth@10004000", getenv("ethact")); + + /* Restore the env */ + setenv("eth1addr", ethaddr); + setenv("ethrotate", NULL); + + /* Invalidate eth0's MAC address */ + strcpy(ethaddr, getenv("ethaddr")); + setenv(".flags", "ethaddr"); + setenv("ethaddr", NULL); + + /* Make sure we can skip invalid devices */ + setenv("ethact", "eth@10004000"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10004000", getenv("ethact")); + + /* Restore the env */ + setenv("ethaddr", ethaddr); + setenv(".flags", NULL); + + return 0; +} +DM_TEST(dm_test_eth_rotate, DM_TESTF_SCAN_FDT); + +static int dm_test_net_retry(struct dm_test_state *dms) +{ + net_ping_ip = string_to_ip("1.1.2.2"); + + /* + * eth1 is disabled and netretry is yes, so the ping should succeed and + * the active device should be eth0 + */ + sandbox_eth_disable_response(1, true); + setenv("ethact", "eth@10004000"); + setenv("netretry", "yes"); + ut_assertok(net_loop(PING)); + ut_asserteq_str("eth@10002000", getenv("ethact")); + + /* + * eth1 is disabled and netretry is no, so the ping should fail and the + * active device should be eth1 + */ + setenv("ethact", "eth@10004000"); + setenv("netretry", "no"); + ut_asserteq(-ETIMEDOUT, net_loop(PING)); + ut_asserteq_str("eth@10004000", getenv("ethact")); + + /* Restore the env */ + setenv("netretry", NULL); + sandbox_eth_disable_response(1, false); + + return 0; +} +DM_TEST(dm_test_net_retry, DM_TESTF_SCAN_FDT); diff --git a/test/dm/pci.c b/test/dm/pci.c new file mode 100644 index 0000000..6c63fa4 --- /dev/null +++ b/test/dm/pci.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <asm/io.h> +#include <dm/test.h> +#include <dm/ut.h> + +/* Test that sandbox PCI works correctly */ +static int dm_test_pci_base(struct dm_test_state *dms) +{ + struct udevice *bus; + + ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus)); + + return 0; +} +DM_TEST(dm_test_pci_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that we can use the swapcase device correctly */ +static int dm_test_pci_swapcase(struct dm_test_state *dms) +{ + pci_dev_t pci_dev = PCI_BDF(0, 0x1f, 0); + struct pci_controller *hose; + struct udevice *bus, *swap; + ulong io_addr, mem_addr; + char *ptr; + + /* Check that asking for the device automatically fires up PCI */ + ut_assertok(uclass_get_device(UCLASS_PCI_EMUL, 0, &swap)); + + ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus)); + hose = dev_get_uclass_priv(bus); + + /* First test I/O */ + io_addr = pci_read_bar32(hose, pci_dev, 0); + outb(2, io_addr); + ut_asserteq(2, inb(io_addr)); + + /* + * Now test memory mapping - note we must unmap and remap to cause + * the swapcase emulation to see our data and response. + */ + mem_addr = pci_read_bar32(hose, pci_dev, 1); + ptr = map_sysmem(mem_addr, 20); + strcpy(ptr, "This is a TesT"); + unmap_sysmem(ptr); + + ptr = map_sysmem(mem_addr, 20); + ut_asserteq_str("tHIS IS A tESt", ptr); + unmap_sysmem(ptr); + + return 0; +} +DM_TEST(dm_test_pci_swapcase, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/test-dm.sh b/test/dm/test-dm.sh index 8ebc392..6158f68 100755 --- a/test/dm/test-dm.sh +++ b/test/dm/test-dm.sh @@ -10,5 +10,8 @@ dtc -I dts -O dtb test/dm/test.dts -o test/dm/test.dtb make O=sandbox sandbox_config || die "Cannot configure U-Boot" make O=sandbox -s -j${NUM_CPUS} || die "Cannot build U-Boot" dd if=/dev/zero of=spi.bin bs=1M count=2 +echo -n "this is a test" > testflash.bin +dd if=/dev/zero bs=1M count=4 >>testflash.bin ./sandbox/u-boot -d test/dm/test.dtb -c "dm test" rm spi.bin +rm testflash.bin diff --git a/test/dm/test-main.c b/test/dm/test-main.c index 90ca810..a47bb37 100644 --- a/test/dm/test-main.c +++ b/test/dm/test-main.c @@ -65,7 +65,7 @@ static int dm_test_destroy(struct dm_test_state *dms) return 0; } -int dm_test_main(void) +int dm_test_main(const char *test_name) { struct dm_test *tests = ll_entry_start(struct dm_test, dm_test); const int n_ents = ll_entry_count(struct dm_test, dm_test); @@ -83,9 +83,12 @@ int dm_test_main(void) ut_assert(gd->fdt_blob); } - printf("Running %d driver model tests\n", n_ents); + if (!test_name) + printf("Running %d driver model tests\n", n_ents); for (test = tests; test < tests + n_ents; test++) { + if (test_name && strcmp(test_name, test->name)) + continue; printf("Test: %s\n", test->name); ut_assertok(dm_test_init(dms)); diff --git a/test/dm/test-uclass.c b/test/dm/test-uclass.c index 017e097..4ae75ef 100644 --- a/test/dm/test-uclass.c +++ b/test/dm/test-uclass.c @@ -30,7 +30,17 @@ int test_ping(struct udevice *dev, int pingval, int *pingret) static int test_post_bind(struct udevice *dev) { + struct dm_test_perdev_uc_pdata *uc_pdata; + dm_testdrv_op_count[DM_TEST_OP_POST_BIND]++; + ut_assert(!device_active(dev)); + + uc_pdata = dev_get_uclass_platdata(dev); + ut_assert(uc_pdata); + + uc_pdata->intval1 = TEST_UC_PDATA_INTVAL1; + uc_pdata->intval2 = TEST_UC_PDATA_INTVAL2; + uc_pdata->intval3 = TEST_UC_PDATA_INTVAL3; return 0; } @@ -42,12 +52,23 @@ static int test_pre_unbind(struct udevice *dev) return 0; } +static int test_pre_probe(struct udevice *dev) +{ + struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev); + + dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]++; + ut_assert(priv); + ut_assert(device_active(dev)); + + return 0; +} + static int test_post_probe(struct udevice *dev) { struct udevice *prev = list_entry(dev->uclass_node.prev, struct udevice, uclass_node); - struct dm_test_uclass_perdev_priv *priv = dev->uclass_priv; + struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev); struct uclass *uc = dev->uclass; dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]++; @@ -58,7 +79,7 @@ static int test_post_probe(struct udevice *dev) return 0; if (&prev->uclass_node != &uc->dev_head) { struct dm_test_uclass_perdev_priv *prev_uc_priv - = prev->uclass_priv; + = dev_get_uclass_priv(prev); struct dm_test_pdata *pdata = prev->platdata; ut_assert(pdata); @@ -96,10 +117,13 @@ UCLASS_DRIVER(test) = { .id = UCLASS_TEST, .post_bind = test_post_bind, .pre_unbind = test_pre_unbind, + .pre_probe = test_pre_probe, .post_probe = test_post_probe, .pre_remove = test_pre_remove, .init = test_init, .destroy = test_destroy, .priv_auto_alloc_size = sizeof(struct dm_test_uclass_priv), .per_device_auto_alloc_size = sizeof(struct dm_test_uclass_perdev_priv), + .per_device_platdata_auto_alloc_size = + sizeof(struct dm_test_perdev_uc_pdata), }; diff --git a/test/dm/test.dts b/test/dm/test.dts index 84024a4..d0c40be 100644 --- a/test/dm/test.dts +++ b/test/dm/test.dts @@ -10,6 +10,7 @@ console = &uart0; i2c0 = "/i2c@0"; spi0 = "/spi@0"; + pci0 = &pci; testfdt6 = "/e-test"; testbus3 = "/some-bus"; testfdt0 = "/some-bus/c-test@0"; @@ -17,6 +18,11 @@ testfdt3 = "/b-test"; testfdt5 = "/some-bus/c-test@5"; testfdt8 = "/a-test"; + eth0 = "/eth@10002000"; + eth5 = ð_5; + usb0 = &usb_0; + usb1 = &usb_1; + usb2 = &usb_2; }; uart0: serial { @@ -135,6 +141,22 @@ }; }; + pci: pci-controller { + compatible = "sandbox,pci"; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000 + 0x01000000 0 0x20000000 0x20000000 0 0x2000>; + pci@1f,0 { + compatible = "pci-generic"; + reg = <0xf800 0 0 0 0>; + emul@1f,0 { + compatible = "sandbox,swap-case"; + }; + }; + }; + spi@0 { #address-cells = <1>; #size-cells = <0>; @@ -149,4 +171,60 @@ }; }; + eth@10002000 { + compatible = "sandbox,eth"; + reg = <0x10002000 0x1000>; + fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x00>; + }; + + eth_5: eth@10003000 { + compatible = "sandbox,eth"; + reg = <0x10003000 0x1000>; + fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x11>; + }; + + eth@10004000 { + compatible = "sandbox,eth"; + reg = <0x10004000 0x1000>; + fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x22>; + }; + + usb_0: usb@0 { + compatible = "sandbox,usb"; + status = "disabled"; + hub { + compatible = "sandbox,usb-hub"; + #address-cells = <1>; + #size-cells = <0>; + flash-stick { + reg = <0>; + compatible = "sandbox,usb-flash"; + }; + }; + }; + + usb_1: usb@1 { + compatible = "sandbox,usb"; + hub { + compatible = "usb-hub"; + usb,device-class = <9>; + hub-emul { + compatible = "sandbox,usb-hub"; + #address-cells = <1>; + #size-cells = <0>; + flash-stick { + reg = <0>; + compatible = "sandbox,usb-flash"; + sandbox,filepath = "testflash.bin"; + }; + + }; + }; + }; + + usb_2: usb@2 { + compatible = "sandbox,usb"; + status = "disabled"; + }; + }; diff --git a/test/dm/usb.c b/test/dm/usb.c new file mode 100644 index 0000000..6ea86d7 --- /dev/null +++ b/test/dm/usb.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <usb.h> +#include <asm/io.h> +#include <dm/test.h> +#include <dm/ut.h> + +/* Test that sandbox USB works correctly */ +static int dm_test_usb_base(struct dm_test_state *dms) +{ + struct udevice *bus; + + ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus)); + ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus)); + ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus)); + + return 0; +} +DM_TEST(dm_test_usb_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* + * Test that we can use the flash stick. This is more of a functional test. It + * covers scanning the bug, setting up a hub and a flash stick and reading + * data from the flash stick. + */ +static int dm_test_usb_flash(struct dm_test_state *dms) +{ + struct udevice *dev; + block_dev_desc_t *dev_desc; + char cmp[1024]; + + ut_assertok(usb_init()); + ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev)); + ut_assertok(get_device("usb", "0", &dev_desc)); + + /* Read a few blocks and look for the string we expect */ + ut_asserteq(512, dev_desc->blksz); + memset(cmp, '\0', sizeof(cmp)); + ut_asserteq(2, dev_desc->block_read(dev_desc->dev, 0, 2, cmp)); + ut_assertok(strcmp(cmp, "this is a test")); + + return 0; +} +DM_TEST(dm_test_usb_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/tools/buildman/README b/tools/buildman/README index e870d54..8ecdd8f 100644 --- a/tools/buildman/README +++ b/tools/buildman/README @@ -348,7 +348,7 @@ At the time of writing, U-Boot has these architectures: arc, arm, avr32, blackfin, m68k, microblaze, mips, nds32, nios2, openrisc powerpc, sandbox, sh, sparc, x86 -Of these, only arc, microblaze and nds32 are not available at kernel.org.. +Of these, only arc and nds32 are not available at kernel.org.. How to run it diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py index 54f3292..c7d3c86 100644 --- a/tools/buildman/builder.py +++ b/tools/buildman/builder.py @@ -96,6 +96,13 @@ OUTCOME_OK, OUTCOME_WARNING, OUTCOME_ERROR, OUTCOME_UNKNOWN = range(4) # Translate a commit subject into a valid filename trans_valid_chars = string.maketrans("/: ", "---") +CONFIG_FILENAMES = [ + '.config', '.config-spl', '.config-tpl', + 'autoconf.mk', 'autoconf-spl.mk', 'autoconf-tpl.mk', + 'autoconf.h', 'autoconf-spl.h','autoconf-tpl.h', + 'u-boot.cfg', 'u-boot-spl.cfg', 'u-boot-tpl.cfg' +] + class Builder: """Class for building U-Boot for a particular commit. @@ -166,12 +173,17 @@ class Builder: value is itself a dictionary: key: function name value: Size of function in bytes + config: Dictionary keyed by filename - e.g. '.config'. Each + value is itself a dictionary: + key: config name + value: config value """ - def __init__(self, rc, err_lines, sizes, func_sizes): + def __init__(self, rc, err_lines, sizes, func_sizes, config): self.rc = rc self.err_lines = err_lines self.sizes = sizes self.func_sizes = func_sizes + self.config = config def __init__(self, toolchains, base_dir, git_dir, num_threads, num_jobs, gnu_make='make', checkout=True, show_unknown=True, step=1, @@ -254,7 +266,7 @@ class Builder: def SetDisplayOptions(self, show_errors=False, show_sizes=False, show_detail=False, show_bloat=False, - list_error_boards=False): + list_error_boards=False, show_config=False): """Setup display options for the builder. show_errors: True to show summarised error/warning info @@ -262,12 +274,14 @@ class Builder: show_detail: Show detail for each board show_bloat: Show detail for each function list_error_boards: Show the boards which caused each error/warning + show_config: Show config deltas """ self._show_errors = show_errors self._show_sizes = show_sizes self._show_detail = show_detail self._show_bloat = show_bloat self._list_error_boards = list_error_boards + self._show_config = show_config def _AddTimestamp(self): """Add a new timestamp to the list and record the build period. @@ -335,6 +349,9 @@ class Builder: cmd = [self.gnu_make] + list(args) result = command.RunPipe([cmd], capture=True, capture_stderr=True, cwd=cwd, raise_on_error=False, **kwargs) + if self.verbose_build: + result.stdout = '%s\n' % (' '.join(cmd)) + result.stdout + result.combined = '%s\n' % (' '.join(cmd)) + result.combined return result def ProcessResult(self, result): @@ -516,13 +533,50 @@ class Builder: sym[name] = sym.get(name, 0) + int(size, 16) return sym - def GetBuildOutcome(self, commit_upto, target, read_func_sizes): + def _ProcessConfig(self, fname): + """Read in a .config, autoconf.mk or autoconf.h file + + This function handles all config file types. It ignores comments and + any #defines which don't start with CONFIG_. + + Args: + fname: Filename to read + + Returns: + Dictionary: + key: Config name (e.g. CONFIG_DM) + value: Config value (e.g. 1) + """ + config = {} + if os.path.exists(fname): + with open(fname) as fd: + for line in fd: + line = line.strip() + if line.startswith('#define'): + values = line[8:].split(' ', 1) + if len(values) > 1: + key, value = values + else: + key = values[0] + value = '' + if not key.startswith('CONFIG_'): + continue + elif not line or line[0] in ['#', '*', '/']: + continue + else: + key, value = line.split('=', 1) + config[key] = value + return config + + def GetBuildOutcome(self, commit_upto, target, read_func_sizes, + read_config): """Work out the outcome of a build. Args: commit_upto: Commit number to check (0..n-1) target: Target board to check read_func_sizes: True to read function size information + read_config: True to read .config and autoconf.h files Returns: Outcome object @@ -531,6 +585,7 @@ class Builder: sizes_file = self.GetSizesFile(commit_upto, target) sizes = {} func_sizes = {} + config = {} if os.path.exists(done_file): with open(done_file, 'r') as fd: return_code = int(fd.readline()) @@ -574,17 +629,25 @@ class Builder: '') func_sizes[dict_name] = self.ReadFuncSizes(fname, fd) - return Builder.Outcome(rc, err_lines, sizes, func_sizes) + if read_config: + output_dir = self.GetBuildDir(commit_upto, target) + for name in CONFIG_FILENAMES: + fname = os.path.join(output_dir, name) + config[name] = self._ProcessConfig(fname) + + return Builder.Outcome(rc, err_lines, sizes, func_sizes, config) - return Builder.Outcome(OUTCOME_UNKNOWN, [], {}, {}) + return Builder.Outcome(OUTCOME_UNKNOWN, [], {}, {}, {}) - def GetResultSummary(self, boards_selected, commit_upto, read_func_sizes): + def GetResultSummary(self, boards_selected, commit_upto, read_func_sizes, + read_config): """Calculate a summary of the results of building a commit. Args: board_selected: Dict containing boards to summarise commit_upto: Commit number to summarize (0..self.count-1) read_func_sizes: True to read function size information + read_config: True to read .config and autoconf.h files Returns: Tuple: @@ -596,6 +659,10 @@ class Builder: List containing a summary of warning lines Dict keyed by error line, containing a list of the Board objects with that warning + Dictionary keyed by filename - e.g. '.config'. Each + value is itself a dictionary: + key: config name + value: config value """ def AddLine(lines_summary, lines_boards, line, board): line = line.rstrip() @@ -610,10 +677,13 @@ class Builder: err_lines_boards = {} warn_lines_summary = [] warn_lines_boards = {} + config = {} + for fname in CONFIG_FILENAMES: + config[fname] = {} for board in boards_selected.itervalues(): outcome = self.GetBuildOutcome(commit_upto, board.target, - read_func_sizes) + read_func_sizes, read_config) board_dict[board.target] = outcome last_func = None last_was_warning = False @@ -639,8 +709,14 @@ class Builder: line, board) last_was_warning = is_warning last_func = None + for fname in CONFIG_FILENAMES: + config[fname] = {} + if outcome.config: + for key, value in outcome.config[fname].iteritems(): + config[fname][key] = value + return (board_dict, err_lines_summary, err_lines_boards, - warn_lines_summary, warn_lines_boards) + warn_lines_summary, warn_lines_boards, config) def AddOutcome(self, board_dict, arch_list, changes, char, color): """Add an output to our list of outcomes for each architecture @@ -693,11 +769,14 @@ class Builder: """ self._base_board_dict = {} for board in board_selected: - self._base_board_dict[board] = Builder.Outcome(0, [], [], {}) + self._base_board_dict[board] = Builder.Outcome(0, [], [], {}, {}) self._base_err_lines = [] self._base_warn_lines = [] self._base_err_line_boards = {} self._base_warn_line_boards = {} + self._base_config = {} + for fname in CONFIG_FILENAMES: + self._base_config[fname] = {} def PrintFuncSizeDetail(self, fname, old, new): grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0 @@ -892,7 +971,8 @@ class Builder: def PrintResultSummary(self, board_selected, board_dict, err_lines, err_line_boards, warn_lines, warn_line_boards, - show_sizes, show_detail, show_bloat): + config, show_sizes, show_detail, show_bloat, + show_config): """Compare results with the base results and display delta. Only boards mentioned in board_selected will be considered. This @@ -913,9 +993,14 @@ class Builder: none, or we don't want to print errors warn_line_boards: Dict keyed by warning line, containing a list of the Board objects with that warning + config: Dictionary keyed by filename - e.g. '.config'. Each + value is itself a dictionary: + key: config name + value: config value show_sizes: Show image size deltas show_detail: Show detail for each board show_bloat: Show detail for each function + show_config: Show config changes """ def _BoardList(line, line_boards): """Helper function to get a line of boards containing a line @@ -950,6 +1035,48 @@ class Builder: _BoardList(line, base_line_boards) + line) return better_lines, worse_lines + def _CalcConfig(delta, name, config): + """Calculate configuration changes + + Args: + delta: Type of the delta, e.g. '+' + name: name of the file which changed (e.g. .config) + config: configuration change dictionary + key: config name + value: config value + Returns: + String containing the configuration changes which can be + printed + """ + out = '' + for key in sorted(config.keys()): + out += '%s=%s ' % (key, config[key]) + return '%5s %s: %s' % (delta, name, out) + + def _ShowConfig(name, config_plus, config_minus, config_change): + """Show changes in configuration + + Args: + config_plus: configurations added, dictionary + key: config name + value: config value + config_minus: configurations removed, dictionary + key: config name + value: config value + config_change: configurations changed, dictionary + key: config name + value: config value + """ + if config_plus: + Print(_CalcConfig('+', name, config_plus), + colour=self.col.GREEN) + if config_minus: + Print(_CalcConfig('-', name, config_minus), + colour=self.col.RED) + if config_change: + Print(_CalcConfig('+/-', name, config_change), + colour=self.col.YELLOW) + better = [] # List of boards fixed since last commit worse = [] # List of new broken boards since last commit new = [] # List of boards that didn't exist last time @@ -1010,12 +1137,42 @@ class Builder: self.PrintSizeSummary(board_selected, board_dict, show_detail, show_bloat) + if show_config: + all_config_plus = {} + all_config_minus = {} + all_config_change = {} + for name in CONFIG_FILENAMES: + if not config[name]: + continue + config_plus = {} + config_minus = {} + config_change = {} + base = self._base_config[name] + for key, value in config[name].iteritems(): + if key not in base: + config_plus[key] = value + all_config_plus[key] = value + for key, value in base.iteritems(): + if key not in config[name]: + config_minus[key] = value + all_config_minus[key] = value + for key, value in base.iteritems(): + new_value = base[key] + if key in config[name] and value != new_value: + desc = '%s -> %s' % (value, new_value) + config_change[key] = desc + all_config_change[key] = desc + _ShowConfig(name, config_plus, config_minus, config_change) + _ShowConfig('all', all_config_plus, all_config_minus, + all_config_change) + # Save our updated information for the next call to this function self._base_board_dict = board_dict self._base_err_lines = err_lines self._base_warn_lines = warn_lines self._base_err_line_boards = err_line_boards self._base_warn_line_boards = warn_line_boards + self._base_config = config # Get a list of boards that did not get built, if needed not_built = [] @@ -1028,9 +1185,10 @@ class Builder: def ProduceResultSummary(self, commit_upto, commits, board_selected): (board_dict, err_lines, err_line_boards, warn_lines, - warn_line_boards) = self.GetResultSummary( + warn_line_boards, config) = self.GetResultSummary( board_selected, commit_upto, - read_func_sizes=self._show_bloat) + read_func_sizes=self._show_bloat, + read_config=self._show_config) if commits: msg = '%02d: %s' % (commit_upto + 1, commits[commit_upto].subject) @@ -1038,7 +1196,8 @@ class Builder: self.PrintResultSummary(board_selected, board_dict, err_lines if self._show_errors else [], err_line_boards, warn_lines if self._show_errors else [], warn_line_boards, - self._show_sizes, self._show_detail, self._show_bloat) + config, self._show_sizes, self._show_detail, + self._show_bloat, self._show_config) def ShowSummary(self, commits, board_selected): """Show a build summary for U-Boot for a given board list. diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py index efb62f1..ce1cfdd 100644 --- a/tools/buildman/builderthread.py +++ b/tools/buildman/builderthread.py @@ -12,6 +12,8 @@ import threading import command import gitutil +RETURN_CODE_RETRY = -1 + def Mkdir(dirname, parents = False): """Make a directory if it doesn't already exist. @@ -145,7 +147,11 @@ class BuilderThread(threading.Thread): # Get the return code from that build and use it with open(done_file, 'r') as fd: result.return_code = int(fd.readline()) - if will_build: + + # Check the signal that the build needs to be retried + if result.return_code == RETURN_CODE_RETRY: + will_build = True + elif will_build: err_file = self.builder.GetErrFile(commit_upto, brd.target) if os.path.exists(err_file) and os.stat(err_file).st_size: result.stderr = 'bad' @@ -197,7 +203,9 @@ class BuilderThread(threading.Thread): src_dir = os.getcwd() else: args.append('O=build') - if not self.builder.verbose_build: + if self.builder.verbose_build: + args.append('V=1') + else: args.append('-s') if self.builder.num_jobs is not None: args.extend(['-j', str(self.builder.num_jobs)]) @@ -209,14 +217,17 @@ class BuilderThread(threading.Thread): if do_config: result = self.Make(commit, brd, 'mrproper', cwd, 'mrproper', *args, env=env) + config_out = result.combined result = self.Make(commit, brd, 'config', cwd, *(args + config_args), env=env) - config_out = result.combined + config_out += result.combined do_config = False # No need to configure next time if result.return_code == 0: result = self.Make(commit, brd, 'build', cwd, *args, env=env) result.stderr = result.stderr.replace(src_dir + '/', '') + if self.builder.verbose_build: + result.stdout = config_out + result.stdout else: result.return_code = 1 result.stderr = 'No tool chain for %s\n' % brd.arch @@ -240,9 +251,10 @@ class BuilderThread(threading.Thread): if result.return_code < 0: return - # Aborted? - if result.stderr and 'No child processes' in result.stderr: - return + # If we think this might have been aborted with Ctrl-C, record the + # failure but not that we are 'done' with this board. A retry may fix + # it. + maybe_aborted = result.stderr and 'No child processes' in result.stderr if result.already_done: return @@ -272,7 +284,11 @@ class BuilderThread(threading.Thread): done_file = self.builder.GetDoneFile(result.commit_upto, result.brd.target) with open(done_file, 'w') as fd: - fd.write('%s' % result.return_code) + if maybe_aborted: + # Special code to indicate we need to retry + fd.write('%s' % RETURN_CODE_RETRY) + else: + fd.write('%s' % result.return_code) with open(os.path.join(build_dir, 'toolchain'), 'w') as fd: print >>fd, 'gcc', result.toolchain.gcc print >>fd, 'path', result.toolchain.path @@ -331,16 +347,37 @@ class BuilderThread(threading.Thread): with open(sizes, 'w') as fd: print >>fd, '\n'.join(lines) + # Write out the configuration files, with a special case for SPL + for dirname in ['', 'spl', 'tpl']: + self.CopyFiles(result.out_dir, build_dir, dirname, ['u-boot.cfg', + 'spl/u-boot-spl.cfg', 'tpl/u-boot-tpl.cfg', '.config', + 'include/autoconf.mk', 'include/generated/autoconf.h']) + # Now write the actual build output if keep_outputs: - patterns = ['u-boot', '*.bin', 'u-boot.dtb', '*.map', '*.img', - 'include/autoconf.mk', 'spl/u-boot-spl', - 'spl/u-boot-spl.bin'] - for pattern in patterns: - file_list = glob.glob(os.path.join(result.out_dir, pattern)) - for fname in file_list: - shutil.copy(fname, build_dir) + self.CopyFiles(result.out_dir, build_dir, '', ['u-boot*', '*.bin', + '*.map', '*.img', 'MLO', 'include/autoconf.mk', + 'spl/u-boot-spl*']) + def CopyFiles(self, out_dir, build_dir, dirname, patterns): + """Copy files from the build directory to the output. + + Args: + out_dir: Path to output directory containing the files + build_dir: Place to copy the files + dirname: Source directory, '' for normal U-Boot, 'spl' for SPL + patterns: A list of filenames (strings) to copy, each relative + to the build directory + """ + for pattern in patterns: + file_list = glob.glob(os.path.join(out_dir, dirname, pattern)) + for fname in file_list: + target = os.path.basename(fname) + if dirname: + base, ext = os.path.splitext(target) + if ext: + target = '%s-%s%s' % (base, dirname, ext) + shutil.copy(fname, os.path.join(build_dir, target)) def RunJob(self, job): """Run a single job diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py index e8a6dad..916ea57 100644 --- a/tools/buildman/cmdline.py +++ b/tools/buildman/cmdline.py @@ -16,7 +16,7 @@ def ParseArgs(): """ parser = OptionParser() parser.add_option('-b', '--branch', type='string', - help='Branch name to build') + help='Branch name to build, or range of commits to build') parser.add_option('-B', '--bloat', dest='show_bloat', action='store_true', default=False, help='Show changes in function code size for each board') @@ -53,6 +53,8 @@ def ParseArgs(): default=None, help='Number of jobs to run at once (passed to make)') parser.add_option('-k', '--keep-outputs', action='store_true', default=False, help='Keep all build output files (e.g. binaries)') + parser.add_option('-K', '--show-config', action='store_true', + default=False, help='Show configuration changes in summary (both board config files and Kconfig)') parser.add_option('-l', '--list-error-boards', action='store_true', default=False, help='Show a list of boards next to each error/warning') parser.add_option('--list-tool-chains', action='store_true', default=False, diff --git a/tools/buildman/control.py b/tools/buildman/control.py index 720b978..8b3cd30 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -282,7 +282,8 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None, options.show_detail = True builder.SetDisplayOptions(options.show_errors, options.show_sizes, options.show_detail, options.show_bloat, - options.list_error_boards) + options.list_error_boards, + options.show_config) if options.summary: builder.ShowSummary(commits, board_selected) else: diff --git a/tools/buildman/test.py b/tools/buildman/test.py index 7642d94..d8f3c81 100644 --- a/tools/buildman/test.py +++ b/tools/buildman/test.py @@ -411,7 +411,7 @@ class TestBuild(unittest.TestCase): def testToolchainDownload(self): """Test that we can download toolchains""" - self.assertEqual('https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.6.3/x86_64-gcc-4.6.3-nolibc_arm-unknown-linux-gnueabi.tar.xz', + self.assertEqual('https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.9.0/x86_64-gcc-4.9.0-nolibc_arm-unknown-linux-gnueabi.tar.xz', self.toolchains.LocateArchUrl('arm')) diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index 051da11..e33e105 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -339,7 +339,7 @@ class Toolchains: """ arch = command.OutputOneLine('uname', '-m') base = 'https://www.kernel.org/pub/tools/crosstool/files/bin' - versions = ['4.6.3', '4.6.2', '4.5.1', '4.2.4'] + versions = ['4.9.0', '4.6.3', '4.6.2', '4.5.1', '4.2.4'] links = [] for version in versions: url = '%s/%s/%s/' % (base, arch, version) diff --git a/tools/patman/README b/tools/patman/README index 7d039e8..27ec90a 100644 --- a/tools/patman/README +++ b/tools/patman/README @@ -154,7 +154,11 @@ Series-version: n Series-prefix: prefix Sets the subject prefix. Normally empty but it can be RFC for - RFC patches, or RESEND if you are being ignored. + RFC patches, or RESEND if you are being ignored. The patch subject + is like [RFC PATCH] or [RESEND PATCH]. + In the meantime, git format.subjectprefix option will be added as + well. If your format.subjectprefix is set to InternalProject, then + the patch shows like: [InternalProject][RFC/RESEND PATCH] Series-name: name Sets the name of the series. You don't need to have a name, and diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py index 4c2c35b..9e739d8 100644 --- a/tools/patman/gitutil.py +++ b/tools/patman/gitutil.py @@ -545,6 +545,17 @@ def GetDefaultUserEmail(): uemail = command.OutputOneLine('git', 'config', '--global', 'user.email') return uemail +def GetDefaultSubjectPrefix(): + """Gets the format.subjectprefix from local .git/config file. + + Returns: + Subject prefix found in local .git/config file, or None if none + """ + sub_prefix = command.OutputOneLine('git', 'config', 'format.subjectprefix', + raise_on_error=False) + + return sub_prefix + def Setup(): """Set up git utils, by reading the alias files.""" # Check for a git alias file also diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index 8c3a0ec..6d3c41f 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -3,6 +3,7 @@ # SPDX-License-Identifier: GPL-2.0+ # +import math import os import re import shutil @@ -468,8 +469,10 @@ def InsertCoverLetter(fname, series, count): prefix = series.GetPatchPrefix() for line in lines: if line.startswith('Subject:'): - # TODO: if more than 10 patches this should save 00/xx, not 0/xx - line = 'Subject: [%s 0/%d] %s\n' % (prefix, count, text[0]) + # if more than 10 or 100 patches, it should say 00/xx, 000/xxx, etc + zero_repeat = int(math.log10(count)) + 1 + zero = '0' * zero_repeat + line = 'Subject: [%s %s/%d] %s\n' % (prefix, zero, count, text[0]) # Insert our cover letter elif line.startswith('*** BLURB HERE ***'): diff --git a/tools/patman/series.py b/tools/patman/series.py index 60ebc76..a17a7d1 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -254,6 +254,12 @@ class Series(dict): Return: Patch string, like 'RFC PATCH v5' or just 'PATCH' """ + git_prefix = gitutil.GetDefaultSubjectPrefix() + if git_prefix: + git_prefix = '%s][' % git_prefix + else: + git_prefix = '' + version = '' if self.get('version'): version = ' v%s' % self['version'] @@ -262,4 +268,4 @@ class Series(dict): prefix = '' if self.get('prefix'): prefix = '%s ' % self['prefix'] - return '%sPATCH%s' % (prefix, version) + return '%s%sPATCH%s' % (git_prefix, prefix, version) |