From: Tom Rini Date: Thu, 28 Feb 2019 19:22:50 +0000 (-0500) Subject: Merge branch 'master' of git://git.denx.de/u-boot-sunxi X-Git-Tag: v2019.04-rc3~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=da206916a14fc8ab8962763c47673128a29b4b9c;hp=da95ed58c4765ff23ed35753878274ef585f28b5;p=platform%2Fkernel%2Fu-boot.git Merge branch 'master' of git://git.denx.de/u-boot-sunxi - Various Bananapi fixes --- diff --git a/.gitignore b/.gitignore index 8d18d6f..3df3139 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ *.bin *.cfgout *.dtb +*.dtbo *.dtb.S *.elf *.exe diff --git a/.travis.yml b/.travis.yml index 49a7fa9..834502f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -166,7 +166,7 @@ matrix: - name: "buildman arm926ejs (non-NXP,siemens,atmel,kirkwood,spear)" env: - JOB="arm926ejs" - BUILDMAN="arm926ejs -x freescale,siemens,atmel,kirkwood,spear" + BUILDMAN="arm926ejs -x freescale,siemens,atmel,kirkwood,spear,omap" - name: "buildman atmel" env: - BUILDMAN="atmel" diff --git a/Documentation/efi.rst b/Documentation/efi.rst index 51c1de2..5337a55 100644 --- a/Documentation/efi.rst +++ b/Documentation/efi.rst @@ -9,6 +9,12 @@ Boot services .. kernel-doc:: lib/efi_loader/efi_boottime.c :internal: +Image relocation +~~~~~~~~~~~~~~~~ + +.. kernel-doc:: lib/efi_loader/efi_image_loader.c + :internal: + Runtime services ---------------- diff --git a/MAINTAINERS b/MAINTAINERS index 29449ff..4fabb75 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -114,7 +114,7 @@ F: include/configs/meson64.h N: meson ARM BROADCOM BCM283X -M: Alexander Graf +M: Matthias Brugger S: Maintained F: arch/arm/mach-bcm283x/ F: drivers/gpio/bcm2835_gpio.c @@ -453,8 +453,8 @@ F: include/dm/ F: test/dm/ EFI PAYLOAD -M: Alexander Graf -R: Heinrich Schuchardt +M: Heinrich Schuchardt +R: Alexander Graf S: Maintained T: git git://github.com/agraf/u-boot.git F: doc/README.uefi @@ -471,6 +471,8 @@ F: lib/efi*/ F: test/py/tests/test_efi* F: test/unicode_ut.c F: cmd/bootefi.c +F: cmd/efidebug.c +F: cmd/nvedit_efi.c F: tools/file2include.c FPGA diff --git a/Makefile b/Makefile index 5bc3dee..75a5c7d 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ VERSION = 2019 PATCHLEVEL = 04 SUBLEVEL = -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 NAME = # *DOCUMENTATION* diff --git a/README b/README index 1287341..6525b81 100644 --- a/README +++ b/README @@ -687,22 +687,6 @@ The following options need to be configured: as a convenience, when switching between booting from RAM and NFS. -- Pre-Boot Commands: - CONFIG_PREBOOT - - When this option is #defined, the existence of the - environment variable "preboot" will be checked - immediately before starting the CONFIG_BOOTDELAY - countdown and/or running the auto-boot command resp. - entering interactive mode. - - This feature is especially useful when "preboot" is - automatically generated or modified. For an example - see the LWMON board specific code: here "preboot" is - modified when the user holds down a certain - combination of keys on the (special) keyboard when - booting the systems - - Serial Download Echo Mode: CONFIG_LOADS_ECHO If defined to 1, all characters received during a diff --git a/arch/Kconfig b/arch/Kconfig index 35e2712..2f3d07c 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -61,6 +61,7 @@ config PPC config RISCV bool "RISC-V architecture" + select CREATE_ARCH_SYMLINK select SUPPORT_OF_CONTROL select OF_CONTROL select DM @@ -117,6 +118,7 @@ config SANDBOX imply VIRTIO_BLK imply VIRTIO_NET imply DM_SOUND + imply PCH config SH bool "SuperH architecture" @@ -160,6 +162,7 @@ config X86 imply USB_ETHER_ASIX imply USB_ETHER_SMSC95XX imply USB_HOST_ETHER + imply PCH config XTENSA bool "Xtensa architecture" diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 455f06c..ded7c11 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1083,6 +1083,32 @@ config TARGET_LS2081ARDB development platform that supports the QorIQ LS2081A/LS2041A Layerscape Architecture processor. +config TARGET_LX2160ARDB + bool "Support lx2160ardb" + select ARCH_LX2160A + select ARCH_MISC_INIT + select ARM64 + select ARMV8_MULTIENTRY + select BOARD_LATE_INIT + help + Support for NXP LX2160ARDB platform. + The lx2160ardb (LX2160A Reference design board (RDB) + is a high-performance development platform that supports the + QorIQ LX2160A/LX2120A/LX2080A Layerscape Architecture processor. + +config TARGET_LX2160AQDS + bool "Support lx2160aqds" + select ARCH_LX2160A + select ARCH_MISC_INIT + select ARM64 + select ARMV8_MULTIENTRY + select BOARD_LATE_INIT + help + Support for NXP LX2160AQDS platform. + The lx2160aqds (LX2160A QorIQ Development System (QDS) + is a high-performance development platform that supports the + QorIQ LX2160A/LX2120A/LX2080A Layerscape Architecture processor. + config TARGET_HIKEY bool "Support HiKey 96boards Consumer Edition Platform" select ARM64 @@ -1237,6 +1263,7 @@ config TARGET_LS1043AQDS select BOARD_LATE_INIT select SUPPORT_SPL imply SCSI + imply SCSI_AHCI help Support for Freescale LS1043AQDS platform. @@ -1248,7 +1275,6 @@ config TARGET_LS1043ARDB select BOARD_EARLY_INIT_F select BOARD_LATE_INIT select SUPPORT_SPL - imply SCSI help Support for Freescale LS1043ARDB platform. @@ -1555,6 +1581,7 @@ source "board/freescale/ls1046ardb/Kconfig" source "board/freescale/ls1012aqds/Kconfig" source "board/freescale/ls1012ardb/Kconfig" source "board/freescale/ls1012afrdm/Kconfig" +source "board/freescale/lx2160a/Kconfig" source "board/freescale/mx35pdk/Kconfig" source "board/freescale/s32v234evb/Kconfig" source "board/grinn/chiliboard/Kconfig" diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig index 1c12bbd..f053603 100644 --- a/arch/arm/cpu/armv8/Kconfig +++ b/arch/arm/cpu/armv8/Kconfig @@ -106,7 +106,8 @@ config PSCI_RESET !TARGET_LS1012AFRWY && \ !TARGET_LS1043ARDB && !TARGET_LS1043AQDS && \ !TARGET_LS1046ARDB && !TARGET_LS1046AQDS && \ - !TARGET_LS2081ARDB && \ + !TARGET_LS2081ARDB && !TARGET_LX2160ARDB && \ + !TARGET_LX2160AQDS && \ !ARCH_UNIPHIER && !TARGET_S32V234EVB help Most armv8 systems have PSCI support enabled in EL3, either through diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig index 01c5068..f48481f 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig +++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig @@ -2,6 +2,7 @@ config ARCH_LS1012A bool select ARMV8_SET_SMPEN select ARM_ERRATA_855873 if !TFABOOT + select FSL_LAYERSCAPE select FSL_LSCH2 select SYS_FSL_SRDS_1 select SYS_HAS_SERDES @@ -23,6 +24,7 @@ config ARCH_LS1043A bool select ARMV8_SET_SMPEN select ARM_ERRATA_855873 if !TFABOOT + select FSL_LAYERSCAPE select FSL_LSCH2 select SYS_FSL_SRDS_1 select SYS_HAS_SERDES @@ -49,13 +51,12 @@ config ARCH_LS1043A select SYS_I2C_MXC_I2C2 select SYS_I2C_MXC_I2C3 select SYS_I2C_MXC_I2C4 - imply SCSI - imply SCSI_AHCI imply CMD_PCI config ARCH_LS1046A bool select ARMV8_SET_SMPEN + select FSL_LAYERSCAPE select FSL_LSCH2 select SYS_FSL_SRDS_1 select SYS_HAS_SERDES @@ -90,6 +91,7 @@ config ARCH_LS1088A bool select ARMV8_SET_SMPEN select ARM_ERRATA_855873 if !TFABOOT + select FSL_LAYERSCAPE select FSL_LSCH3 select SYS_FSL_SRDS_1 select SYS_HAS_SERDES @@ -113,6 +115,8 @@ config ARCH_LS1088A select SYS_FSL_SRDS_1 select SYS_FSL_SRDS_2 select FSL_TZASC_1 + select FSL_TZASC_400 + select FSL_TZPC_BP147 select ARCH_EARLY_INIT_R select BOARD_EARLY_INIT_F select SYS_I2C_MXC @@ -130,6 +134,7 @@ config ARCH_LS2080A select ARM_ERRATA_828024 select ARM_ERRATA_829520 select ARM_ERRATA_833471 + select FSL_LAYERSCAPE select FSL_LSCH3 select SYS_FSL_SRDS_1 select SYS_HAS_SERDES @@ -145,6 +150,8 @@ config ARCH_LS2080A select SYS_FSL_SRDS_2 select FSL_TZASC_1 select FSL_TZASC_2 + select FSL_TZASC_400 + select FSL_TZPC_BP147 select SYS_FSL_ERRATUM_A008336 if !TFABOOT select SYS_FSL_ERRATUM_A008511 if !TFABOOT select SYS_FSL_ERRATUM_A008514 if !TFABOOT @@ -230,6 +237,9 @@ config FSL_MC_ENET menu "Layerscape architecture" depends on FSL_LSCH2 || FSL_LSCH3 +config FSL_LAYERSCAPE + bool + config FSL_PCIE_COMPAT string "PCIe compatible of Kernel DT" depends on PCIE_LAYERSCAPE @@ -346,6 +356,12 @@ config MAX_CPUS cores, count the reserved ports. This will allocate enough memory in spin table to properly handle all cores. +config EMC2305 + bool "Fan controller" + help + Enable the EMC2305 fan controller for configuration of fan + speed. + config SECURE_BOOT bool "Secure Boot" help @@ -404,6 +420,11 @@ config FSL_TZASC_1 config FSL_TZASC_2 bool +config FSL_TZASC_400 + bool + +config FSL_TZPC_BP147 + bool endmenu menu "Layerscape clock tree configuration" diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index be21685..978d46b 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -1099,15 +1099,29 @@ int arch_early_init_r(void) printf("Did not wake secondary cores\n"); } -#ifdef CONFIG_SYS_FSL_HAS_RGMII - fsl_rgmii_init(); -#endif - config_core_prefetch(); #ifdef CONFIG_SYS_HAS_SERDES fsl_serdes_init(); #endif +#ifdef CONFIG_SYS_FSL_HAS_RGMII + /* some dpmacs in armv8a based freescale layerscape SOCs can be + * configured via both serdes(sgmii, xfi, xlaui etc) bits and via + * EC*_PMUX(rgmii) bits in RCW. + * e.g. dpmac 17 and 18 in LX2160A can be configured as SGMII from + * serdes bits and as RGMII via EC1_PMUX/EC2_PMUX bits + * Now if a dpmac is enabled by serdes bits then it takes precedence + * over EC*_PMUX bits. i.e. in LX2160A if we select serdes protocol + * that configures dpmac17 as SGMII and set the EC1_PMUX as RGMII, + * then the dpmac is SGMII and not RGMII. + * + * Therefore, move the fsl_rgmii_init after fsl_serdes_init. in + * fsl_rgmii_init function of SOC, we will check if the dpmac is enabled + * or not? if it is (fsl_serdes_init has already enabled the dpmac), + * then don't enable it. + */ + fsl_rgmii_init(); +#endif #ifdef CONFIG_FMAN_ENET fman_enet_init(); #endif diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c index ab1be3f..1a747a9 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c @@ -548,12 +548,32 @@ void fsl_serdes_init(void) #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) int i , j; +#ifdef CONFIG_ARCH_LX2160A + for (i = XFI1, j = 1; i <= XFI14; i++, j++) + xfi_dpmac[i] = j; + + for (i = SGMII1, j = 1; i <= SGMII18; i++, j++) + sgmii_dpmac[i] = j; + + for (i = _25GE1, j = 1; i <= _25GE10; i++, j++) + a25gaui_dpmac[i] = j; + + for (i = _40GE1, j = 1; i <= _40GE2; i++, j++) + xlaui_dpmac[i] = j; + + for (i = _50GE1, j = 1; i <= _50GE2; i++, j++) + caui2_dpmac[i] = j; + + for (i = _100GE1, j = 1; i <= _100GE2; i++, j++) + caui4_dpmac[i] = j; +#else for (i = XFI1, j = 1; i <= XFI8; i++, j++) xfi_dpmac[i] = j; for (i = SGMII1, j = 1; i <= SGMII16; i++, j++) sgmii_dpmac[i] = j; #endif +#endif #ifdef CONFIG_SYS_FSL_SRDS_1 serdes_init(FSL_SRDS_1, diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index fbc0f8a..2a040b2 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -246,7 +246,9 @@ dtb-$(CONFIG_FSL_LSCH3) += fsl-ls2080a-qds.dtb \ fsl-ls2081a-rdb.dtb \ fsl-ls2088a-rdb-qspi.dtb \ fsl-ls1088a-rdb.dtb \ - fsl-ls1088a-qds.dtb + fsl-ls1088a-qds.dtb \ + fsl-lx2160a-rdb.dtb \ + fsl-lx2160a-qds.dtb dtb-$(CONFIG_FSL_LSCH2) += fsl-ls1043a-qds-duart.dtb \ fsl-ls1043a-qds-lpuart.dtb \ fsl-ls1043a-rdb.dtb \ diff --git a/arch/arm/dts/am335x-brxre1.dts b/arch/arm/dts/am335x-brxre1.dts new file mode 100644 index 0000000..708407d --- /dev/null +++ b/arch/arm/dts/am335x-brxre1.dts @@ -0,0 +1,371 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 B&R Industrial Automation GmbH + * http://www.br-automation.com + * + */ +/dts-v1/; + +#include "am33xx.dtsi" + +/ { + model = "BRXRE1 Panel"; + compatible = "ti,am33xx"; + + fset: factory-settings { + bl-version = " "; + order-no = " "; + cpu-order-no = " "; + hw-revision = " "; + serial-no = <0>; + device-id = <0xE681>; + parent-id = <0xE681>; + hw-variant = <0x3>; + hw-platform = <0x0>; + fram-offset = <0x1000>; + fram-size = <0x3000>; + cache-disable = <0x0>; + cpu-clock = <0x0>; + }; + chosen { + #address-cells = <1>; + #size-cells = <1>; + + bootargs = "console=ttyO0,115200 earlyprintk"; + stdout-path = &uart0; + + framebuffer: framebuffer@8fbe0000 { + display = <&lcdscreen0>; + compatible = "simple-framebuffer"; + status = "okay"; + reg = <0x8fbef000 (1024 * 600 * 4)>; + width = <1024>; + height = <600>; + stride = <(1024 * 4)>; + format = "a8r8g8b8"; + clocks = <&dpll_disp_m2_ck>, <&dpll_per_m2_ck>; + }; + }; + + aliases { + fset = &fset; + mmc = &mmc2; + spi0 = &spi0; + spi1 = &spi1; + touch0 = &burtouch0; + screen0 = &lcdscreen0; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; + + panel { + compatible = "ti,tilcdc,panel"; + status = "okay"; + }; + + vmmcsd_fixed: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vmmcsd_fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + lcdscreen0: lcdscreen@0 { + status = "okay"; + compatible = "ti,tilcdc,panel"; + + backlight = <&tps_bl>; + + panel-info { + ac-bias = <255>; + ac-bias-intrpt = <0>; + dma-burst-sz = <16>; + bpp = <32>; + fdd = <0x80>; + sync-edge = <0>; + sync-ctrl = <1>; + raster-order = <0>; + fifo-th = <0>; + }; + + display-timings { + native-mode = <&timing0>; + timing0: lcd { + clock-frequency = <9142857>; + hactive = <480>; + vactive = <272>; + hfront-porch = <8>; + hback-porch = <43>; + hsync-len = <2>; + vfront-porch = <4>; + vback-porch = <2>; + vsync-len = <10>; + hsync-active = <1>; + vsync-active = <1>; + pupdelay = <10>; + pondelay = <10>; + }; + }; + }; +}; + +&uart0 { /* console uart */ + u-boot,dm-spl; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&i2c0 { + u-boot,dm-spl; + status = "okay"; + clock-frequency = <100000>; + + tps: tps@24 { /* PMIC controller */ + u-boot,dm-spl; + reg = <0x24>; + compatible = "ti,tps65217"; + + tps_bl: backlight { + compatible = "ti,tps65217-bl"; + isel = <1>; /* 1 - ISET1, 2 ISET2 */ + fdim = <1000>; /* TPS65217_BL_FDIM_1kHZ */ + default-brightness = <50>; + }; + }; + resetc: rstpsc@75 { /* reset controller */ + compatible = "bur,rstpsc"; + reg = <0x75>; + + cooling-min-state = <0>; + cooling-max-state = <1>; /* reset gets fired */ + #cooling-cells = <2>; /* min followed by max */ + }; + rtc0: rv3029c2@56 { + status = "okay"; + #thermal-sensor-cells = <0>; + compatible = "rv3029c2"; + reg = <0x56>; + }; +}; + +&spi0 { + status = "okay"; +}; + +&spi1 { + status = "okay"; +}; + +&edma { + status = "okay"; +}; + +&cppi41dma { + status = "okay"; +}; + +&usb { + status = "okay"; +}; + +&usb_ctrl_mod { + status = "okay"; +}; + +&usb0_phy { + status = "okay"; +}; + +&usb1_phy { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "host"; +}; + +&davinci_mdio { + status = "okay"; +}; + +&mac { + status = "okay"; +}; + +&cpsw_emac0 { + phy_id = <&davinci_mdio>, <1>; + phy-mode = "mii"; +}; + +&cpsw_emac1 { + phy_id = <&davinci_mdio>, <2>; + phy-mode = "mii"; +}; + +&mmc1 { + u-boot,dm-pre-reloc; + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <0x4>; + ti,non-removable; + ti,needs-special-hs-handling; + ti,vcc-aux-disable-is-sleep; + status = "okay"; +}; + +&mmc2 { + u-boot,dm-pre-reloc; + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <0x8>; + ti,non-removable; + ti,needs-special-hs-handling; + ti,vcc-aux-disable-is-sleep; + status = "okay"; +}; + +&lcdc { + status = "okay"; + ti,no-reset-on-init; + ti,no-idle-on-init; +}; + +&elm { + status = "okay"; +}; + +&sham { + status = "okay"; +}; + +&aes { + status = "okay"; +}; + +&gpio0 { + u-boot,dm-spl; + ti,no-reset-on-init; +}; + +&gpio1 { + u-boot,dm-spl; + ti,no-reset-on-init; +}; + +&gpio2 { + u-boot,dm-spl; + ti,no-reset-on-init; +}; + +&gpio3 { + u-boot,dm-spl; + ti,no-reset-on-init; +}; + +&timer1 { /* today unused */ + status = "okay"; + ti,no-reset-on-init; + ti,no-idle-on-init; +}; + +&timer2 { /* used for vxworks primary timer device */ + status = "okay"; + ti,no-reset-on-init; + ti,no-idle-on-init; +}; + +&timer3 { /* used sysdelay and hal tsc counter*/ + status = "okay"; + ti,no-reset-on-init; + ti,no-idle-on-init; +}; + +&timer4 { /* used for PWM beeper */ + status = "okay"; + ti,no-reset-on-init; + ti,no-idle-on-init; +}; + +&timer5 { /* used for PWM backlight */ + status = "okay"; + ti,no-reset-on-init; + ti,no-idle-on-init; +}; + +&timer6 { /* used for cpsw end device */ + status = "okay"; + ti,no-reset-on-init; + ti,no-idle-on-init; +}; + +&timer7 { /* used for cpsw end device */ + status = "okay"; + ti,no-reset-on-init; + ti,no-idle-on-init; +}; + +&wdt2 { + status = "okay"; + ti,no-reset-on-init; + ti,no-idle-on-init; +}; + +&epwmss0 { + status = "okay"; +}; + +&tscadc { + status = "okay"; + + tsc { + burtouch0: burtouch@0 { + status = "okay"; + compatible = "bur,DdVxSfTouchXXX"; + bur,hwtree = "IF7"; + bur,KX0 = <0x0>; + bur,KX1 = <0x0>; + bur,KX2 = <0x0>; + bur,KY0 = <0x0>; + bur,KY1 = <0x0>; + bur,KY2 = <0x0>; + }; + }; +}; + +&dcan0 { + status = "okay"; +}; + +&dcan1 { + status = "okay"; +}; + +&sham { + status = "disabled"; +}; + +&aes { + status = "disabled"; +}; + +&rng { + status = "disabled"; +}; diff --git a/arch/arm/dts/fsl-lx2160a-qds.dts b/arch/arm/dts/fsl-lx2160a-qds.dts new file mode 100644 index 0000000..6192156 --- /dev/null +++ b/arch/arm/dts/fsl-lx2160a-qds.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0+ OR X11 +/* + * NXP LX2160AQDS device tree source + * + * Copyright 2018-2019 NXP + * + */ + +/dts-v1/; + +#include "fsl-lx2160a.dtsi" + +/ { + model = "NXP Layerscape LX2160AQDS Board"; + compatible = "fsl,lx2160aqds", "fsl,lx2160a"; +}; + diff --git a/arch/arm/dts/fsl-lx2160a-rdb.dts b/arch/arm/dts/fsl-lx2160a-rdb.dts new file mode 100644 index 0000000..4b52644 --- /dev/null +++ b/arch/arm/dts/fsl-lx2160a-rdb.dts @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0+ OR X11 +/* + * NXP LX2160ARDB device tree source + * + * Author: Priyanka Jain + * Sriram Dash + * + * Copyright 2018 NXP + * + */ + +/dts-v1/; + +#include "fsl-lx2160a.dtsi" + +/ { + model = "NXP Layerscape LX2160ARDB Board"; + compatible = "fsl,lx2160ardb", "fsl,lx2160a"; + +}; + +&esdhc0 { + status = "okay"; +}; + +&esdhc1 { + status = "okay"; +}; + +&sata0 { + status = "okay"; +}; + +&sata1 { + status = "okay"; +}; + +&sata2 { + status = "okay"; +}; + +&sata3 { + status = "okay"; +}; diff --git a/arch/arm/dts/fsl-lx2160a.dtsi b/arch/arm/dts/fsl-lx2160a.dtsi index b407dc6..510b070 100644 --- a/arch/arm/dts/fsl-lx2160a.dtsi +++ b/arch/arm/dts/fsl-lx2160a.dtsi @@ -89,7 +89,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x0 0x2110000 0x0 0x10000>; - interrupts = <0 240 0x4>; /* Level high type */ + interrupts = <0 26 0x4>; /* Level high type */ num-cs = <6>; }; @@ -115,4 +115,65 @@ interrupts = <0 81 0x4>; /* Level high type */ dr_mode = "host"; }; + + esdhc0: esdhc@2140000 { + compatible = "fsl,esdhc"; + reg = <0x0 0x2140000 0x0 0x10000>; + interrupts = <0 28 0x4>; /* Level high type */ + clocks = <&clockgen 4 1>; + voltage-ranges = <1800 1800 3300 3300>; + sdhci,auto-cmd12; + little-endian; + bus-width = <4>; + status = "disabled"; + }; + + esdhc1: esdhc@2150000 { + compatible = "fsl,esdhc"; + reg = <0x0 0x2150000 0x0 0x10000>; + interrupts = <0 63 0x4>; /* Level high type */ + clocks = <&clockgen 4 1>; + voltage-ranges = <1800 1800 3300 3300>; + sdhci,auto-cmd12; + non-removable; + little-endian; + bus-width = <4>; + status = "disabled"; + }; + + sata0: sata@3200000 { + compatible = "fsl,ls2080a-ahci"; + reg = <0x0 0x3200000 0x0 0x10000>; + interrupts = <0 133 4>; + clocks = <&clockgen 4 3>; + status = "disabled"; + + }; + + sata1: sata@3210000 { + compatible = "fsl,ls2080a-ahci"; + reg = <0x0 0x3210000 0x0 0x10000>; + interrupts = <0 136 4>; + clocks = <&clockgen 4 3>; + status = "disabled"; + + }; + + sata2: sata@3220000 { + compatible = "fsl,ls2080a-ahci"; + reg = <0x0 0x3220000 0x0 0x10000>; + interrupts = <0 97 4>; + clocks = <&clockgen 4 3>; + status = "disabled"; + + }; + + sata3: sata@3230000 { + compatible = "fsl,ls2080a-ahci"; + reg = <0x0 0x3230000 0x0 0x10000>; + interrupts = <0 100 4>; + clocks = <&clockgen 4 3>; + status = "disabled"; + + }; }; diff --git a/arch/arm/dts/logicpd-som-lv-35xx-devkit-u-boot.dtsi b/arch/arm/dts/logicpd-som-lv-35xx-devkit-u-boot.dtsi index 6445048..b3da8b1 100644 --- a/arch/arm/dts/logicpd-som-lv-35xx-devkit-u-boot.dtsi +++ b/arch/arm/dts/logicpd-som-lv-35xx-devkit-u-boot.dtsi @@ -4,6 +4,8 @@ * Logic PD - http://www.logicpd.com */ +#include "omap3-u-boot.dtsi" + / { chosen { stdout-path = &uart1; diff --git a/arch/arm/dts/logicpd-som-lv-37xx-devkit-u-boot.dtsi b/arch/arm/dts/logicpd-som-lv-37xx-devkit-u-boot.dtsi index 6445048..956199a 100644 --- a/arch/arm/dts/logicpd-som-lv-37xx-devkit-u-boot.dtsi +++ b/arch/arm/dts/logicpd-som-lv-37xx-devkit-u-boot.dtsi @@ -4,6 +4,8 @@ * Logic PD - http://www.logicpd.com */ +#include "omap3-u-boot.dtsi" + / { chosen { stdout-path = &uart1; @@ -18,10 +20,6 @@ clock-frequency = <400000>; }; -&mmc1 { - cd-gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; /* gpio_110 */ -}; - &mmc2 { status = "disabled"; }; diff --git a/arch/arm/dts/logicpd-torpedo-35xx-devkit-u-boot.dtsi b/arch/arm/dts/logicpd-torpedo-35xx-devkit-u-boot.dtsi index 41ed5d7..2c599f1 100644 --- a/arch/arm/dts/logicpd-torpedo-35xx-devkit-u-boot.dtsi +++ b/arch/arm/dts/logicpd-torpedo-35xx-devkit-u-boot.dtsi @@ -4,6 +4,8 @@ * Logic PD - http://www.logicpd.com */ +#include "omap3-u-boot.dtsi" + &i2c1 { clock-frequency = <400000>; }; diff --git a/arch/arm/dts/logicpd-torpedo-37xx-devkit-u-boot.dtsi b/arch/arm/dts/logicpd-torpedo-37xx-devkit-u-boot.dtsi index 41ed5d7..2c599f1 100644 --- a/arch/arm/dts/logicpd-torpedo-37xx-devkit-u-boot.dtsi +++ b/arch/arm/dts/logicpd-torpedo-37xx-devkit-u-boot.dtsi @@ -4,6 +4,8 @@ * Logic PD - http://www.logicpd.com */ +#include "omap3-u-boot.dtsi" + &i2c1 { clock-frequency = <400000>; }; diff --git a/arch/arm/dts/omap3-beagle-u-boot.dtsi b/arch/arm/dts/omap3-beagle-u-boot.dtsi index 41beaf0..2c03701 100644 --- a/arch/arm/dts/omap3-beagle-u-boot.dtsi +++ b/arch/arm/dts/omap3-beagle-u-boot.dtsi @@ -5,20 +5,10 @@ * (C) Copyright 2017 Derald D. Woods */ +#include "omap3-u-boot.dtsi" + / { chosen { stdout-path = &uart3; }; }; - -&uart1 { - reg-shift = <2>; -}; - -&uart2 { - reg-shift = <2>; -}; - -&uart3 { - reg-shift = <2>; -}; diff --git a/arch/arm/dts/omap3-beagle-xm-ab-u-boot.dtsi b/arch/arm/dts/omap3-beagle-xm-ab-u-boot.dtsi index 41beaf0..2c03701 100644 --- a/arch/arm/dts/omap3-beagle-xm-ab-u-boot.dtsi +++ b/arch/arm/dts/omap3-beagle-xm-ab-u-boot.dtsi @@ -5,20 +5,10 @@ * (C) Copyright 2017 Derald D. Woods */ +#include "omap3-u-boot.dtsi" + / { chosen { stdout-path = &uart3; }; }; - -&uart1 { - reg-shift = <2>; -}; - -&uart2 { - reg-shift = <2>; -}; - -&uart3 { - reg-shift = <2>; -}; diff --git a/arch/arm/dts/omap3-beagle-xm-u-boot.dtsi b/arch/arm/dts/omap3-beagle-xm-u-boot.dtsi index 41beaf0..2c03701 100644 --- a/arch/arm/dts/omap3-beagle-xm-u-boot.dtsi +++ b/arch/arm/dts/omap3-beagle-xm-u-boot.dtsi @@ -5,20 +5,10 @@ * (C) Copyright 2017 Derald D. Woods */ +#include "omap3-u-boot.dtsi" + / { chosen { stdout-path = &uart3; }; }; - -&uart1 { - reg-shift = <2>; -}; - -&uart2 { - reg-shift = <2>; -}; - -&uart3 { - reg-shift = <2>; -}; diff --git a/arch/arm/dts/omap3-evm-37xx-u-boot.dtsi b/arch/arm/dts/omap3-evm-37xx-u-boot.dtsi index de41131..b9e433f 100644 --- a/arch/arm/dts/omap3-evm-37xx-u-boot.dtsi +++ b/arch/arm/dts/omap3-evm-37xx-u-boot.dtsi @@ -5,20 +5,10 @@ * (C) Copyright 2017 Derald D. Woods */ +#include "omap3-u-boot.dtsi" + / { chosen { stdout-path = &uart1; }; }; - -&uart1 { - reg-shift = <2>; -}; - -&uart2 { - reg-shift = <2>; -}; - -&uart3 { - reg-shift = <2>; -}; diff --git a/arch/arm/dts/omap3-evm-u-boot.dtsi b/arch/arm/dts/omap3-evm-u-boot.dtsi index de41131..b9e433f 100644 --- a/arch/arm/dts/omap3-evm-u-boot.dtsi +++ b/arch/arm/dts/omap3-evm-u-boot.dtsi @@ -5,20 +5,10 @@ * (C) Copyright 2017 Derald D. Woods */ +#include "omap3-u-boot.dtsi" + / { chosen { stdout-path = &uart1; }; }; - -&uart1 { - reg-shift = <2>; -}; - -&uart2 { - reg-shift = <2>; -}; - -&uart3 { - reg-shift = <2>; -}; diff --git a/arch/arm/dts/omap3-u-boot.dtsi b/arch/arm/dts/omap3-u-boot.dtsi new file mode 100644 index 0000000..32bea6b --- /dev/null +++ b/arch/arm/dts/omap3-u-boot.dtsi @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * Based on "omap5-u-boot.dtsi" + */ + +/{ + ocp@68000000 { + u-boot,dm-spl; + + bandgap@48002524 { + u-boot,dm-spl; + }; + }; +}; + +&uart1 { + u-boot,dm-spl; + reg-shift = <2>; +}; + +&uart2 { + u-boot,dm-spl; + reg-shift = <2>; +}; + +&uart3 { + u-boot,dm-spl; + reg-shift = <2>; +}; + +&mmc1 { + u-boot,dm-spl; +}; + +&mmc2 { + u-boot,dm-spl; +}; + +&l4_core { + u-boot,dm-spl; +}; + +&scm { + u-boot,dm-spl; +}; + +&scm_conf { + u-boot,dm-spl; +}; + +&gpio1 { + u-boot,dm-spl; +}; + +&gpio2 { + u-boot,dm-spl; +}; + +&gpio3 { + u-boot,dm-spl; +}; + +&gpio4 { + u-boot,dm-spl; +}; + +&gpio5 { + u-boot,dm-spl; +}; + +&gpio6 { + u-boot,dm-spl; +}; + +&i2c1 { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/tegra124-nyan-big-u-boot.dtsi b/arch/arm/dts/tegra124-nyan-big-u-boot.dtsi index 3ff2f67..ddfeba8 100644 --- a/arch/arm/dts/tegra124-nyan-big-u-boot.dtsi +++ b/arch/arm/dts/tegra124-nyan-big-u-boot.dtsi @@ -15,7 +15,7 @@ }; spi@7000d400 { - spi-deactivate-delay = <200>; + spi-deactivate-delay = <500>; spi-max-frequency = <3000000>; cros_ec: cros-ec@0 { diff --git a/arch/arm/dts/tegra124-nyan.dtsi b/arch/arm/dts/tegra124-nyan.dtsi index 51895e4..2b28fe1 100644 --- a/arch/arm/dts/tegra124-nyan.dtsi +++ b/arch/arm/dts/tegra124-nyan.dtsi @@ -414,6 +414,7 @@ usb@7d000000 { /* Rear external USB port. */ status = "okay"; + dr_mode = "otg"; nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>; }; diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h index d4f80a2..903d509 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/config.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h @@ -26,7 +26,6 @@ #ifndef L1_CACHE_BYTES #define L1_CACHE_SHIFT 6 #define L1_CACHE_BYTES BIT(L1_CACHE_SHIFT) -#define CONFIG_FSL_TZASC_400 #endif #define CONFIG_SYS_FSL_OCRAM_BASE 0x18000000 /* initial RAM */ @@ -121,8 +120,6 @@ #define CONFIG_SYS_FSL_NUM_CC_PLLS 3 #define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 1 } #define CONFIG_GICV3 -#define CONFIG_FSL_TZPC_BP147 -#define CONFIG_FSL_TZASC_400 #define CONFIG_SYS_PAGE_SIZE 0x10000 #define SRDS_MAX_LANES 4 diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h index eaa9ed2..d62754e 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h @@ -42,7 +42,11 @@ #define CONFIG_SYS_FSL_WRIOP1_SIZE 0x100000000 #define CONFIG_SYS_FSL_AIOP1_BASE 0x4b00000000 #define CONFIG_SYS_FSL_AIOP1_SIZE 0x100000000 +#ifndef CONFIG_ARCH_LX2160A #define CONFIG_SYS_FSL_PEBUF_BASE 0x4c00000000 +#else +#define CONFIG_SYS_FSL_PEBUF_BASE 0x1c00000000 +#endif #define CONFIG_SYS_FSL_PEBUF_SIZE 0x400000000 #ifdef CONFIG_NXP_LSCH3_2 #define CONFIG_SYS_FSL_DRAM_BASE2 0x2080000000 diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h index 0535224..9fab88a 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h @@ -2,7 +2,7 @@ /* * LayerScape Internal Memory Map * - * Copyright 2017-2018 NXP + * Copyright 2017-2019 NXP * Copyright 2014 Freescale Semiconductor, Inc. */ @@ -350,6 +350,14 @@ struct ccsr_gur { #define FSL_CHASSIS3_SRDS1_REGSR 29 #define FSL_CHASSIS3_SRDS2_REGSR 29 #define FSL_CHASSIS3_SRDS3_REGSR 29 +#define FSL_CHASSIS3_RCWSR12_REGSR 12 +#define FSL_CHASSIS3_RCWSR13_REGSR 13 +#define FSL_CHASSIS3_SDHC1_BASE_PMUX_MASK 0x07000000 +#define FSL_CHASSIS3_SDHC1_BASE_PMUX_SHIFT 24 +#define FSL_CHASSIS3_SDHC2_BASE_PMUX_MASK 0x00000038 +#define FSL_CHASSIS3_SDHC2_BASE_PMUX_SHIFT 3 +#define FSL_CHASSIS3_IIC5_PMUX_MASK 0x00000E00 +#define FSL_CHASSIS3_IIC5_PMUX_SHIFT 9 #elif defined(CONFIG_ARCH_LS1088A) #define FSL_CHASSIS3_EC1_REGSR 26 #define FSL_CHASSIS3_EC2_REGSR 26 diff --git a/arch/arm/lib/cache-pl310.c b/arch/arm/lib/cache-pl310.c index 1296ba6..bbaaaa4 100644 --- a/arch/arm/lib/cache-pl310.c +++ b/arch/arm/lib/cache-pl310.c @@ -33,7 +33,7 @@ static void pl310_background_op_all_ways(u32 *op_reg) /* Invalidate all ways */ writel(way_mask, op_reg); /* Wait for all ways to be invalidated */ - while (readl(op_reg) && way_mask) + while (readl(op_reg) & way_mask) ; pl310_cache_sync(); } diff --git a/arch/arm/lib/relocate_64.S b/arch/arm/lib/relocate_64.S index 171d094..7603f52 100644 --- a/arch/arm/lib/relocate_64.S +++ b/arch/arm/lib/relocate_64.S @@ -85,6 +85,7 @@ relocate_done: isb sy 4: ldp x0, x1, [sp, #16] bl __asm_flush_dcache_range + bl __asm_flush_l3_dcache 5: ldp x29, x30, [sp],#32 ret ENDPROC(relocate_code) diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager.h b/arch/arm/mach-socfpga/include/mach/reset_manager.h index d9e0b33..42beaec 100644 --- a/arch/arm/mach-socfpga/include/mach/reset_manager.h +++ b/arch/arm/mach-socfpga/include/mach/reset_manager.h @@ -10,8 +10,6 @@ void reset_cpu(ulong addr); void socfpga_per_reset(u32 reset, int set); void socfpga_per_reset_all(void); -int socfpga_eth_reset_common(void (*resetfn)(const u8 of_reset_id, - const u8 phymode)); #define RSTMGR_CTRL_SWWARMRSTREQ_LSB 1 diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c index 78fbe28..e1adea1 100644 --- a/arch/arm/mach-socfpga/misc.c +++ b/arch/arm/mach-socfpga/misc.c @@ -120,71 +120,6 @@ int arch_cpu_init(void) return 0; } -#ifdef CONFIG_ETH_DESIGNWARE -static int dwmac_phymode_to_modereg(const char *phymode, u32 *modereg) -{ - if (!phymode) - return -EINVAL; - - if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii")) { - *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; - return 0; - } - - if (!strcmp(phymode, "rgmii")) { - *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII; - return 0; - } - - if (!strcmp(phymode, "rmii")) { - *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII; - return 0; - } - - return -EINVAL; -} - -int socfpga_eth_reset_common(void (*resetfn)(const u8 of_reset_id, - const u8 phymode)) -{ - const void *fdt = gd->fdt_blob; - struct fdtdec_phandle_args args; - const char *phy_mode; - u32 phy_modereg; - int nodes[2]; /* Max. two GMACs */ - int ret, count; - int i, node; - - count = fdtdec_find_aliases_for_id(fdt, "ethernet", - COMPAT_ALTERA_SOCFPGA_DWMAC, - nodes, ARRAY_SIZE(nodes)); - for (i = 0; i < count; i++) { - node = nodes[i]; - if (node <= 0) - continue; - - ret = fdtdec_parse_phandle_with_args(fdt, node, "resets", - "#reset-cells", 1, 0, - &args); - if (ret || (args.args_count != 1)) { - debug("GMAC%i: Failed to parse DT 'resets'!\n", i); - continue; - } - - phy_mode = fdt_getprop(fdt, node, "phy-mode", NULL); - ret = dwmac_phymode_to_modereg(phy_mode, &phy_modereg); - if (ret) { - debug("GMAC%i: Failed to parse DT 'phy-mode'!\n", i); - continue; - } - - resetfn(args.args[0], phy_modereg); - } - - return 0; -} -#endif - #ifndef CONFIG_SPL_BUILD static int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c index 04f237d..6e11ba6 100644 --- a/arch/arm/mach-socfpga/misc_gen5.c +++ b/arch/arm/mach-socfpga/misc_gen5.c @@ -54,48 +54,6 @@ static Altera_desc altera_fpga[] = { }, }; -/* - * DesignWare Ethernet initialization - */ -#ifdef CONFIG_ETH_DESIGNWARE -static void gen5_dwmac_reset(const u8 of_reset_id, const u8 phymode) -{ - u32 physhift, reset; - - if (of_reset_id == EMAC0_RESET) { - physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB; - reset = SOCFPGA_RESET(EMAC0); - } else if (of_reset_id == EMAC1_RESET) { - physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB; - reset = SOCFPGA_RESET(EMAC1); - } else { - printf("GMAC: Invalid reset ID (%i)!\n", of_reset_id); - return; - } - - /* configure to PHY interface select choosed */ - clrsetbits_le32(&sysmgr_regs->emacgrp_ctrl, - SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift, - phymode << physhift); - - /* Release the EMAC controller from reset */ - socfpga_per_reset(reset, 0); -} - -static int socfpga_eth_reset(void) -{ - /* Put all GMACs into RESET state. */ - socfpga_per_reset(SOCFPGA_RESET(EMAC0), 1); - socfpga_per_reset(SOCFPGA_RESET(EMAC1), 1); - return socfpga_eth_reset_common(gen5_dwmac_reset); -}; -#else -static int socfpga_eth_reset(void) -{ - return 0; -}; -#endif - static const struct { const u16 pn; const char *name; @@ -178,7 +136,7 @@ int arch_misc_init(void) env_set("bootmode", bsel_str[bsel].mode); if (fpga_id >= 0) env_set("fpgatype", socfpga_fpga_model[fpga_id].var); - return socfpga_eth_reset(); + return 0; } #endif diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index c45e4d7..36512a8 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -14,15 +14,19 @@ config TARGET_AX25_AE350 config TARGET_QEMU_VIRT bool "Support QEMU Virt Board" +config TARGET_SIFIVE_FU540 + bool "Support SiFive FU540 Board" + endchoice # board-specific options below source "board/AndesTech/ax25-ae350/Kconfig" source "board/emulation/qemu-riscv/Kconfig" +source "board/sifive/fu540/Kconfig" # platform-specific options below source "arch/riscv/cpu/ax25/Kconfig" -source "arch/riscv/cpu/qemu/Kconfig" +source "arch/riscv/cpu/generic/Kconfig" # architecture-specific options below diff --git a/arch/riscv/cpu/qemu/Kconfig b/arch/riscv/cpu/generic/Kconfig similarity index 91% rename from arch/riscv/cpu/qemu/Kconfig rename to arch/riscv/cpu/generic/Kconfig index f48751e..1d6ab50 100644 --- a/arch/riscv/cpu/qemu/Kconfig +++ b/arch/riscv/cpu/generic/Kconfig @@ -2,7 +2,7 @@ # # Copyright (C) 2018, Bin Meng -config QEMU_RISCV +config GENERIC_RISCV bool select ARCH_EARLY_INIT_R imply CPU diff --git a/arch/riscv/cpu/qemu/Makefile b/arch/riscv/cpu/generic/Makefile similarity index 100% rename from arch/riscv/cpu/qemu/Makefile rename to arch/riscv/cpu/generic/Makefile diff --git a/arch/riscv/cpu/qemu/cpu.c b/arch/riscv/cpu/generic/cpu.c similarity index 100% rename from arch/riscv/cpu/qemu/cpu.c rename to arch/riscv/cpu/generic/cpu.c diff --git a/arch/riscv/cpu/generic/dram.c b/arch/riscv/cpu/generic/dram.c new file mode 100644 index 0000000..b7b1207 --- /dev/null +++ b/arch/riscv/cpu/generic/dram.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + return fdtdec_setup_mem_size_base(); +} + +int dram_init_banksize(void) +{ + return fdtdec_setup_memory_banksize(); +} + +ulong board_get_usable_ram_top(ulong total_size) +{ +#ifdef CONFIG_64BIT + /* + * Ensure that we run from first 4GB so that all + * addresses used by U-Boot are 32bit addresses. + * + * This in-turn ensures that 32bit DMA capable + * devices work fine because DMA mapping APIs will + * provide 32bit DMA addresses only. + */ + if (gd->ram_top > SZ_4G) + return SZ_4G; +#endif + return gd->ram_top; +} diff --git a/arch/riscv/cpu/qemu/dram.c b/arch/riscv/cpu/qemu/dram.c deleted file mode 100644 index 84d87d2..0000000 --- a/arch/riscv/cpu/qemu/dram.c +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2018, Bin Meng - */ - -#include -#include - -int dram_init(void) -{ - return fdtdec_setup_mem_size_base(); -} - -int dram_init_banksize(void) -{ - return fdtdec_setup_memory_banksize(); -} diff --git a/arch/riscv/include/asm/arch-generic/clk.h b/arch/riscv/include/asm/arch-generic/clk.h new file mode 100644 index 0000000..1631f5f --- /dev/null +++ b/arch/riscv/include/asm/arch-generic/clk.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2019 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel + */ + +#ifndef __ASM_RISCV_ARCH_CLK_H +#define __ASM_RISCV_ARCH_CLK_H + +/* Note: This is a placeholder header for driver compilation. */ + +#endif diff --git a/arch/riscv/include/asm/config.h b/arch/riscv/include/asm/config.h index 81bc975..156cb94 100644 --- a/arch/riscv/include/asm/config.h +++ b/arch/riscv/include/asm/config.h @@ -8,5 +8,6 @@ #define _ASM_CONFIG_H_ #define CONFIG_LMB +#define CONFIG_SYS_BOOT_RAMDISK_HIGH #endif diff --git a/arch/riscv/include/asm/dma-mapping.h b/arch/riscv/include/asm/dma-mapping.h new file mode 100644 index 0000000..3d930c9 --- /dev/null +++ b/arch/riscv/include/asm/dma-mapping.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2018 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel + */ + +#ifndef __ASM_RISCV_DMA_MAPPING_H +#define __ASM_RISCV_DMA_MAPPING_H + +#include + +#define dma_mapping_error(x, y) 0 + +static inline void *dma_alloc_coherent(size_t len, unsigned long *handle) +{ + *handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len); + return (void *)*handle; +} + +static inline void dma_free_coherent(void *addr) +{ + free(addr); +} + +static inline unsigned long dma_map_single(volatile void *vaddr, size_t len, + enum dma_data_direction dir) +{ + return (unsigned long)vaddr; +} + +static inline void dma_unmap_single(volatile void *vaddr, size_t len, + unsigned long paddr) +{ +} + +#endif /* __ASM_RISCV_DMA_MAPPING_H */ diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 1d011de..87d8e5b 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -203,6 +203,14 @@ #clock-cells = <0>; clock-frequency = <1234>; }; + + clk_fixed_factor: clk-fixed-factor { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + clock-div = <3>; + clock-mult = <2>; + clocks = <&clk_fixed>; + }; }; clk_sandbox: clk-sbox { @@ -389,6 +397,7 @@ i2s: i2s { compatible = "sandbox,i2s"; #sound-dai-cells = <1>; + sandbox,silent; /* Don't emit sounds while testing */ }; misc-test { @@ -407,6 +416,10 @@ compatible = "sandbox,mmc"; }; + pch { + compatible = "sandbox,pch"; + }; + pci0: pci-controller0 { compatible = "sandbox,pci"; device_type = "pci"; diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index c724827..2d773d3 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -102,6 +102,15 @@ struct sandbox_state { ulong next_tag; /* Next address tag to allocate */ struct list_head mapmem_head; /* struct sandbox_mapmem_entry */ bool hwspinlock; /* Hardware Spinlock status */ + + /* + * This struct is getting large. + * + * Consider putting test data in driver-private structs, like + * sandbox_pch.c. + * + * If you add new members, please put them above this comment. + */ }; /* Minimum space we guarantee in the state FDT when calling read/write*/ diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 74f9618..fc52f47 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -161,4 +161,28 @@ int sandbox_get_setup_called(struct udevice *dev); */ int sandbox_get_sound_sum(struct udevice *dev); +/** + * sandbox_set_allow_beep() - Set whether the 'beep' interface is supported + * + * @dev: Device to update + * @allow: true to allow the start_beep() method, false to disallow it + */ +void sandbox_set_allow_beep(struct udevice *dev, bool allow); + +/** + * sandbox_get_beep_frequency() - Get the frequency of the current beep + * + * @dev: Device to check + * @return frequency of beep, if there is an active beep, else 0 + */ +int sandbox_get_beep_frequency(struct udevice *dev); + +/** + * sandbox_get_pch_spi_protect() - Get the PCI SPI protection status + * + * @dev: Device to check + * @return 0 if not protected, 1 if protected + */ +int sandbox_get_pch_spi_protect(struct udevice *dev); + #endif diff --git a/arch/x86/cpu/broadwell/Makefile b/arch/x86/cpu/broadwell/Makefile index a032861..d3785aa 100644 --- a/arch/x86/cpu/broadwell/Makefile +++ b/arch/x86/cpu/broadwell/Makefile @@ -2,6 +2,7 @@ # # Copyright (c) 2016 Google, Inc +obj-y += adsp.o obj-y += cpu.o obj-y += iobp.o obj-y += lpc.o diff --git a/arch/x86/cpu/broadwell/adsp.c b/arch/x86/cpu/broadwell/adsp.c new file mode 100644 index 0000000..2ac8cea --- /dev/null +++ b/arch/x86/cpu/broadwell/adsp.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for Intel Application Digital Signal Processor + * + * Copyright 2019 Google LLC + * + * Modified from coreboot file of the same name + */ + +#define LOG_CATEGORY UCLASS_SYSCON + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum pci_type_t { + LYNX_POINT, + WILDCAT_POINT, +}; + +struct broadwell_adsp_priv { + bool adsp_d3_pg_enable; + bool adsp_sram_pg_enable; + bool sio_acpi_mode; +}; + +static int broadwell_adsp_probe(struct udevice *dev) +{ + struct broadwell_adsp_priv *priv = dev_get_priv(dev); + enum pci_type_t type; + u32 bar0, bar1; + u32 tmp32; + + /* Find BAR0 and BAR1 */ + bar0 = dm_pci_read_bar32(dev, 0); + if (!bar0) + return -EINVAL; + bar1 = dm_pci_read_bar32(dev, 1); + if (!bar1) + return -EINVAL; + + /* + * Set LTR value in DSP shim LTR control register to 3ms + * SNOOP_REQ[13]=1b SNOOP_SCALE[12:10]=100b (1ms) SNOOP_VAL[9:0]=3h + */ + type = dev_get_driver_data(dev); + tmp32 = type == WILDCAT_POINT ? ADSP_SHIM_BASE_WPT : ADSP_SHIM_BASE_LPT; + writel(ADSP_SHIM_LTRC_VALUE, bar0 + tmp32); + + /* Program VDRTCTL2 D19:F0:A8[31:0] = 0x00000fff */ + dm_pci_write_config32(dev, ADSP_PCI_VDRTCTL2, ADSP_VDRTCTL2_VALUE); + + /* Program ADSP IOBP VDLDAT1 to 0x040100 */ + pch_iobp_write(ADSP_IOBP_VDLDAT1, ADSP_VDLDAT1_VALUE); + + /* Set D3 Power Gating Enable in D19:F0:A0 based on PCH type */ + dm_pci_read_config32(dev, ADSP_PCI_VDRTCTL0, &tmp32); + if (type == WILDCAT_POINT) { + if (priv->adsp_d3_pg_enable) { + tmp32 &= ~ADSP_VDRTCTL0_D3PGD_WPT; + if (priv->adsp_sram_pg_enable) + tmp32 &= ~ADSP_VDRTCTL0_D3SRAMPGD_WPT; + else + tmp32 |= ADSP_VDRTCTL0_D3SRAMPGD_WPT; + } else { + tmp32 |= ADSP_VDRTCTL0_D3PGD_WPT; + } + } else { + if (priv->adsp_d3_pg_enable) { + tmp32 &= ~ADSP_VDRTCTL0_D3PGD_LPT; + if (priv->adsp_sram_pg_enable) + tmp32 &= ~ADSP_VDRTCTL0_D3SRAMPGD_LPT; + else + tmp32 |= ADSP_VDRTCTL0_D3SRAMPGD_LPT; + } else { + tmp32 |= ADSP_VDRTCTL0_D3PGD_LPT; + } + } + dm_pci_write_config32(dev, ADSP_PCI_VDRTCTL0, tmp32); + + /* Set PSF Snoop to SA, RCBA+0x3350[10]=1b */ + setbits_le32(RCB_REG(0x3350), 1 << 10); + + /* Set DSP IOBP PMCTL 0x1e0=0x3f */ + pch_iobp_write(ADSP_IOBP_PMCTL, ADSP_PMCTL_VALUE); + + if (priv->sio_acpi_mode) { + /* Configure for ACPI mode */ + log_info("ADSP: Enable ACPI Mode IRQ3\n"); + + /* Set interrupt de-assert/assert opcode override to IRQ3 */ + pch_iobp_write(ADSP_IOBP_VDLDAT2, ADSP_IOBP_ACPI_IRQ3); + + /* Enable IRQ3 in RCBA */ + setbits_le32(RCB_REG(ACPIIRQEN), ADSP_ACPI_IRQEN); + + /* Set ACPI Interrupt Enable Bit */ + pch_iobp_update(ADSP_IOBP_PCICFGCTL, ~ADSP_PCICFGCTL_SPCBAD, + ADSP_PCICFGCTL_ACPIIE); + + /* Put ADSP in D3hot */ + clrbits_le32(bar1 + PCH_PCS, PCH_PCS_PS_D3HOT); + } else { + log_info("ADSP: Enable PCI Mode IRQ23\n"); + + /* Configure for PCI mode */ + dm_pci_write_config32(dev, PCI_INTERRUPT_LINE, ADSP_PCI_IRQ); + + /* Clear ACPI Interrupt Enable Bit */ + pch_iobp_update(ADSP_IOBP_PCICFGCTL, + ~(ADSP_PCICFGCTL_SPCBAD | + ADSP_PCICFGCTL_ACPIIE), 0); + } + + return 0; +} + +static int broadwell_adsp_ofdata_to_platdata(struct udevice *dev) +{ + struct broadwell_adsp_priv *priv = dev_get_priv(dev); + + priv->adsp_d3_pg_enable = dev_read_bool(dev, "intel,adsp-d3-pg-enable"); + priv->adsp_sram_pg_enable = dev_read_bool(dev, + "intel,adsp-sram-pg-enable"); + priv->sio_acpi_mode = dev_read_bool(dev, "intel,sio-acpi-mode"); + + return 0; +} + +static const struct udevice_id broadwell_adsp_ids[] = { + { .compatible = "intel,wildcatpoint-adsp", .data = WILDCAT_POINT }, + { } +}; + +U_BOOT_DRIVER(broadwell_adsp_drv) = { + .name = "adsp", + .id = UCLASS_SYSCON, + .ofdata_to_platdata = broadwell_adsp_ofdata_to_platdata, + .of_match = broadwell_adsp_ids, + .bind = dm_scan_fdt_dev, + .probe = broadwell_adsp_probe, +}; + +static struct pci_device_id broadwell_adsp_supported[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_WILDCATPOINT_ADSP) }, + { }, +}; + +U_BOOT_PCI_DEVICE(broadwell_adsp_drv, broadwell_adsp_supported); diff --git a/arch/x86/cpu/broadwell/pch.c b/arch/x86/cpu/broadwell/pch.c index 82506ba..73d3d3b 100644 --- a/arch/x86/cpu/broadwell/pch.c +++ b/arch/x86/cpu/broadwell/pch.c @@ -20,7 +20,9 @@ #include #include #include +#include #include +#include #define BIOS_CTRL 0xdc @@ -456,6 +458,111 @@ static void systemagent_init(void) cpu_set_power_limits(28); } +/* Enable LTR Auto Mode for D21:F1-F6 */ +static void serialio_d21_ltr(u32 bar0) +{ + /* 1. Program BAR0 + 808h[2] = 0b */ + clrbits_le32(bar0 + SIO_REG_PPR_GEN, SIO_REG_PPR_GEN_LTR_MODE_MASK); + + /* 2. Program BAR0 + 804h[1:0] = 00b */ + clrbits_le32(bar0 + SIO_REG_PPR_RST, SIO_REG_PPR_RST_ASSERT); + + /* 3. Program BAR0 + 804h[1:0] = 11b */ + setbits_le32(bar0 + SIO_REG_PPR_RST, SIO_REG_PPR_RST_ASSERT); + + /* 4. Program BAR0 + 814h[31:0] = 00000000h */ + writel(0, bar0 + SIO_REG_AUTO_LTR); +} + +/* Select I2C voltage of 1.8V or 3.3V */ +static void serialio_i2c_voltage_sel(u32 bar0, uint voltage) +{ + clrsetbits_le32(bar0 + SIO_REG_PPR_GEN, SIO_REG_PPR_GEN_VOLTAGE_MASK, + SIO_REG_PPR_GEN_VOLTAGE(voltage)); +} + +/* Put Serial IO D21:F0-F6 device into desired mode */ +static void serialio_d21_mode(int sio_index, int int_pin, bool acpi_mode) +{ + u32 portctrl = SIO_IOBP_PORTCTRL_PM_CAP_PRSNT; + + /* Snoop select 1 */ + portctrl |= SIO_IOBP_PORTCTRL_SNOOP_SELECT(1); + + /* Set interrupt pin */ + portctrl |= SIO_IOBP_PORTCTRL_INT_PIN(int_pin); + + if (acpi_mode) { + /* Enable ACPI interrupt mode */ + portctrl |= SIO_IOBP_PORTCTRL_ACPI_IRQ_EN; + } + + pch_iobp_update(SIO_IOBP_PORTCTRLX(sio_index), 0, portctrl); +} + +/* Init sequence to be run once, done as part of D21:F0 (SDMA) init */ +static void serialio_init_once(bool acpi_mode) +{ + if (acpi_mode) { + /* Enable ACPI IRQ for IRQ13, IRQ7, IRQ6, IRQ5 in RCBA */ + setbits_le32(RCB_REG(ACPIIRQEN), + 1 << 13 | 1 << 7 | 1 << 6 | 1 << 5); + } + + /* Program IOBP CB000154h[12,9:8,4:0] = 1001100011111b */ + pch_iobp_update(SIO_IOBP_GPIODF, ~0x0000131f, 0x0000131f); + + /* Program IOBP CB000180h[5:0] = 111111b (undefined register) */ + pch_iobp_update(0xcb000180, ~0x0000003f, 0x0000003f); +} + +/** + * pch_serialio_init() - set up serial I/O devices + * + * @return 0 if OK, -ve on error + */ +static int pch_serialio_init(void) +{ + struct udevice *dev, *hda; + bool acpi_mode = true; + u32 bar0, bar1; + int ret; + + ret = uclass_find_first_device(UCLASS_I2C, &dev); + if (ret) + return ret; + bar0 = dm_pci_read_bar32(dev, 0); + if (!bar0) + return -EINVAL; + bar1 = dm_pci_read_bar32(dev, 1); + if (!bar1) + return -EINVAL; + + serialio_init_once(acpi_mode); + serialio_d21_mode(SIO_ID_SDMA, SIO_PIN_INTB, acpi_mode); + + serialio_d21_ltr(bar0); + serialio_i2c_voltage_sel(bar0, 1); /* Select 1.8V always */ + serialio_d21_mode(SIO_ID_I2C0, SIO_PIN_INTC, acpi_mode); + setbits_le32(bar1 + PCH_PCS, PCH_PCS_PS_D3HOT); + + clrbits_le32(bar1 + PCH_PCS, PCH_PCS_PS_D3HOT); + + setbits_le32(bar0 + SIO_REG_PPR_CLOCK, SIO_REG_PPR_CLOCK_EN); + + /* Manually find the High-definition audio, to turn it off */ + ret = dm_pci_bus_find_bdf(PCI_BDF(0, 0x1b, 0), &hda); + if (ret) + return -ENOENT; + dm_pci_clrset_config8(hda, 0x43, 0, 0x6f); + + /* Route I/O buffers to ADSP function */ + dm_pci_clrset_config8(hda, 0x42, 0, 1 << 7 | 1 << 6); + log_debug("HDA disabled, I/O buffers routed to ADSP\n"); + + return 0; +} + static int broadwell_pch_init(struct udevice *dev) { int ret; @@ -482,6 +589,9 @@ static int broadwell_pch_init(struct udevice *dev) return ret; pch_pm_init(dev); pch_cg_init(dev); + ret = pch_serialio_init(); + if (ret) + return ret; systemagent_init(); return 0; diff --git a/arch/x86/cpu/broadwell/pinctrl_broadwell.c b/arch/x86/cpu/broadwell/pinctrl_broadwell.c index 914ecfb..aa83abb 100644 --- a/arch/x86/cpu/broadwell/pinctrl_broadwell.c +++ b/arch/x86/cpu/broadwell/pinctrl_broadwell.c @@ -16,6 +16,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -214,7 +215,7 @@ static int broadwell_pinctrl_probe(struct udevice *dev) u32 gpiobase; int ret; - ret = uclass_first_device(UCLASS_PCH, &pch); + ret = uclass_find_first_device(UCLASS_PCH, &pch); if (ret) return ret; if (!pch) diff --git a/arch/x86/cpu/ivybridge/Kconfig b/arch/x86/cpu/ivybridge/Kconfig index 5f0e608..2f42393 100644 --- a/arch/x86/cpu/ivybridge/Kconfig +++ b/arch/x86/cpu/ivybridge/Kconfig @@ -21,6 +21,7 @@ config NORTHBRIDGE_INTEL_IVYBRIDGE imply USB_EHCI_HCD imply USB_XHCI_HCD imply VIDEO_VESA + imply SOUND_IVYBRIDGE if NORTHBRIDGE_INTEL_IVYBRIDGE diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c index a78bb02..ed9bce6 100644 --- a/arch/x86/cpu/ivybridge/bd82x6x.c +++ b/arch/x86/cpu/ivybridge/bd82x6x.c @@ -20,8 +20,12 @@ DECLARE_GLOBAL_DATA_PTR; -#define GPIO_BASE 0x48 -#define BIOS_CTRL 0xdc +#define GPIO_BASE 0x48 +#define BIOS_CTRL 0xdc + +#define RCBA_AUDIO_CONFIG 0x2030 +#define RCBA_AUDIO_CONFIG_HDA BIT(31) +#define RCBA_AUDIO_CONFIG_MASK 0xfe #ifndef CONFIG_HAVE_FSP static int pch_revision_id = -1; @@ -212,10 +216,29 @@ static int bd82x6x_get_gpio_base(struct udevice *dev, u32 *gbasep) return 0; } +static int bd82x6x_ioctl(struct udevice *dev, enum pch_req_t req, void *data, + int size) +{ + u32 rcba, val; + + switch (req) { + case PCH_REQ_HDA_CONFIG: + dm_pci_read_config32(dev, PCH_RCBA, &rcba); + val = readl(rcba + RCBA_AUDIO_CONFIG); + if (!(val & RCBA_AUDIO_CONFIG_HDA)) + return -ENOENT; + + return val & RCBA_AUDIO_CONFIG_MASK; + default: + return -ENOSYS; + } +} + static const struct pch_ops bd82x6x_pch_ops = { .get_spi_base = bd82x6x_pch_get_spi_base, .set_spi_protect = bd82x6x_set_spi_protect, .get_gpio_base = bd82x6x_get_gpio_base, + .ioctl = bd82x6x_ioctl, }; static const struct udevice_id bd82x6x_ids[] = { diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c index 39bab7b..a809b82 100644 --- a/arch/x86/cpu/ivybridge/northbridge.c +++ b/arch/x86/cpu/ivybridge/northbridge.c @@ -177,6 +177,35 @@ static void sandybridge_setup_northbridge_bars(struct udevice *dev) dm_pci_write_config8(dev, PAM6, 0x33); } +/** + * sandybridge_init_iommu() - Set up IOMMU so that azalia can be used + * + * It is not obvious where these values come from. They may be undocumented. + */ +static void sandybridge_init_iommu(struct udevice *dev) +{ + u32 capid0_a; + + dm_pci_read_config32(dev, 0xe4, &capid0_a); + if (capid0_a & (1 << 23)) { + log_debug("capid0_a not needed\n"); + return; + } + + /* setup BARs */ + writel(IOMMU_BASE1 >> 32, MCHBAR_REG(0x5404)); + writel(IOMMU_BASE1 | 1, MCHBAR_REG(0x5400)); + writel(IOMMU_BASE2 >> 32, MCHBAR_REG(0x5414)); + writel(IOMMU_BASE2 | 1, MCHBAR_REG(0x5410)); + + /* lock policies */ + writel(0x80000000, IOMMU_BASE1 + 0xff0); + + /* Enable azalia sound */ + writel(0x20000000, IOMMU_BASE2 + 0xff0); + writel(0xa0000000, IOMMU_BASE2 + 0xff0); +} + static int bd82x6x_northbridge_early_init(struct udevice *dev) { const int chipset_type = SANDYBRIDGE_MOBILE; @@ -197,6 +226,9 @@ static int bd82x6x_northbridge_early_init(struct udevice *dev) sandybridge_setup_northbridge_bars(dev); + /* Setup IOMMU BARs */ + sandybridge_init_iommu(dev); + /* Device Enable */ dm_pci_write_config32(dev, DEVEN, DEVEN_HOST | DEVEN_IGD); diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts index f9f0979..c5653fe 100644 --- a/arch/x86/dts/chromebook_link.dts +++ b/arch/x86/dts/chromebook_link.dts @@ -1,6 +1,8 @@ /dts-v1/; #include +#include +#include /include/ "skeleton.dtsi" /include/ "keyboard.dtsi" @@ -372,6 +374,32 @@ compatible = "ehci-pci"; }; + hda@1b,0 { + reg = <0x0000d800 0 0 0 0>; + compatible = "intel,bd82x6x-hda"; + + /* These correspond to the Intel HDA specification */ + beep-verbs = < + 0x00170500 /* power up codec */ + 0x00270500 /* power up DAC */ + 0x00b70500 /* power up speaker */ + 0x00b70740 /* enable speaker out */ + 0x00b78d00 /* enable EAPD pin */ + 0x00b70c02 /* set EAPD pin */ + 0x0143b013>; /* beep volume */ + + codecs { + creative_codec: creative-ca0132 { + vendor-id = ; + device-id = ; + }; + intel_hdmi: hdmi { + vendor-id = ; + device-id = ; + }; + }; + }; + usb_0: usb@1d,0 { reg = <0x0000e800 0 0 0 0>; compatible = "ehci-pci"; @@ -492,3 +520,71 @@ }; }; + +&creative_codec { + verbs = < + /** + * Malcolm Setup. These correspond to the Intel HDA + * specification. + */ + 0x01570d09 0x01570c23 0x01570a01 0x01570df0 + 0x01570efe 0x01570775 0x015707d3 0x01570709 + 0x01570753 0x015707d4 0x015707ef 0x01570775 + 0x015707d3 0x01570709 0x01570702 0x01570737 + 0x01570778 0x01553cce 0x015575c9 0x01553dce + 0x0155b7c9 0x01570de8 0x01570efe 0x01570702 + 0x01570768 0x01570762 0x01553ace 0x015546c9 + 0x01553bce 0x0155e8c9 0x01570d49 0x01570c88 + 0x01570d20 0x01570e19 0x01570700 0x01571a05 + 0x01571b29 0x01571a04 0x01571b29 0x01570a01 + + /* Pin Widget Verb Table */ + + /* NID 0x01, HDA Codec Subsystem ID Verb Table: 0x144dc0c2 */ + AZALIA_SUBVENDOR(0x0, 0x144dc0c2) + + /* + * Pin Complex (NID 0x0B) Port-G Analog Unknown + * Speaker at Int N/A + */ + AZALIA_PIN_CFG(0x0, 0x0b, 0x901700f0) + + /* Pin Complex (NID 0x0C) N/C */ + AZALIA_PIN_CFG(0x0, 0x0c, 0x70f000f0) + + /* Pin Complex (NID 0x0D) N/C */ + AZALIA_PIN_CFG(0x0, 0x0d, 0x70f000f0) + + /* Pin Complex (NID 0x0E) N/C */ + AZALIA_PIN_CFG(0x0, 0x0e, 0x70f000f0) + + /* Pin Complex (NID 0x0F) N/C */ + AZALIA_PIN_CFG(0x0, 0x0f, 0x70f000f0) + + /* Pin Complex (NID 0x10) Port-D 1/8 Black HP Out at Ext Left */ + AZALIA_PIN_CFG(0x0, 0x10, 0x032110f0) + + /* Pin Complex (NID 0x11) Port-B Click Mic */ + AZALIA_PIN_CFG(0x0, 0x11, 0x90a700f0) + + /* Pin Complex (NID 0x12) Port-C Combo Jack Mic or D-Mic */ + AZALIA_PIN_CFG(0x0, 0x12, 0x03a110f0) + + /* Pin Complex (NID 0x13) What you hear */ + AZALIA_PIN_CFG(0x0, 0x13, 0x90d600f0)>; +}; + +&intel_hdmi { + verbs = < + /* NID 0x01, HDA Codec Subsystem ID Verb Table: 0x80860101 */ + AZALIA_SUBVENDOR(0x3, 0x80860101) + + /* Pin Complex (NID 0x05) Digital Out at Int HDMI */ + AZALIA_PIN_CFG(0x3, 0x05, 0x18560010) + + /* Pin Complex (NID 0x06) Digital Out at Int HDMI */ + AZALIA_PIN_CFG(0x3, 0x06, 0x18560020) + + /* Pin Complex (NID 0x07) Digital Out at Int HDMI */ + AZALIA_PIN_CFG(0x3, 0x07, 0x18560030)>; +}; diff --git a/arch/x86/dts/chromebook_samus.dts b/arch/x86/dts/chromebook_samus.dts index b58936b..ad687ce 100644 --- a/arch/x86/dts/chromebook_samus.dts +++ b/arch/x86/dts/chromebook_samus.dts @@ -494,10 +494,20 @@ intel,pre-graphics-delay = <200>; }; - me@16,0 { - reg = <0x0000b000 0 0 0 0>; - compatible = "intel,me"; - u-boot,dm-pre-reloc; + adsp@13,0 { + reg = <0x00009800 0 0 0 0>; + compatible = "intel,wildcatpoint-adsp"; + intel,adsp-d3-pg-enable = <0>; + intel,adsp-sram-pg-enable = <0>; + intel,sio-acpi-mode; + #address-cells = <1>; + #size-cells = <0>; + + i2s: shim { + compatible = "intel,broadwell-i2s"; + #sound-dai-cells = <1>; + reg = <0xfb000 0xfc000 0xfd000>; + }; }; usb_1: usb@14,0 { @@ -505,6 +515,25 @@ compatible = "xhci-pci"; }; + i2c0: i2c@15,1 { + reg = <0x0000a900 0 0 0 0>; + compatible = "snps,designware-i2c"; + #address-cells = <1>; + #size-cells = <0>; + + rt5677: rt5677@2c { + compatible = "realtek,rt5677"; + #sound-dai-cells = <1>; + reg = <0x2c>; + }; + }; + + me@16,0 { + reg = <0x0000b000 0 0 0 0>; + compatible = "intel,me"; + u-boot,dm-pre-reloc; + }; + usb_0: usb@1d,0 { status = "disabled"; reg = <0x0000e800 0 0 0 0>; @@ -626,4 +655,16 @@ }; }; + sound { + compatible = "google,samus-sound"; + codec-enable-gpio = <&gpio_b 11 GPIO_ACTIVE_HIGH>; + cpu { + sound-dai = <&i2s 0>; + }; + + codec { + sound-dai = <&rt5677 0>; + }; + }; + }; diff --git a/arch/x86/include/asm/arch-broadwell/adsp.h b/arch/x86/include/asm/arch-broadwell/adsp.h new file mode 100644 index 0000000..eb825ce --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/adsp.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Support for Intel Application Digital Signal Processor + * + * Copyright 2019 Google LLC + * + * Modified from coreboot file of the same name + */ + +#ifndef __ASM_ARCH_BROADWELL_ADSP_H +#define __ASM_ARCH_BROADWELL_ADSP_H + +#define ADSP_PCI_IRQ 23 +#define ADSP_ACPI_IRQ 3 +#define ADSP_ACPI_IRQEN BIT(3) + +#define ADSP_SHIM_BASE_LPT 0xe7000 +#define ADSP_SHIM_BASE_WPT 0xfb000 +#define ADSP_SHIM_LTRC 0xe0 +#define ADSP_SHIM_LTRC_VALUE 0x3003 +#define ADSP_SHIM_IMC 0x28 +#define ADSP_SHIM_IPCD 0x40 + +#define ADSP_PCI_VDRTCTL0 0xa0 +#define ADSP_VDRTCTL0_D3PGD_LPT BIT(1) +#define ADSP_VDRTCTL0_D3PGD_WPT BIT(0) +#define ADSP_VDRTCTL0_D3SRAMPGD_LPT BIT(2) +#define ADSP_VDRTCTL0_D3SRAMPGD_WPT BIT(1) +#define ADSP_PCI_VDRTCTL1 0xa4 +#define ADSP_PCI_VDRTCTL2 0xa8 +#define ADSP_VDRTCTL2_VALUE 0x00000fff + +#define ADSP_IOBP_VDLDAT1 0xd7000624 +#define ADSP_VDLDAT1_VALUE 0x00040100 +#define ADSP_IOBP_VDLDAT2 0xd7000628 +#define ADSP_IOBP_ACPI_IRQ3 0xd9d8 +#define ADSP_IOBP_ACPI_IRQ3I 0xd8d9 +#define ADSP_IOBP_ACPI_IRQ4 0xdbda +#define ADSP_IOBP_PMCTL 0xd70001e0 +#define ADSP_PMCTL_VALUE 0x3f +#define ADSP_IOBP_PCICFGCTL 0xd7000500 +#define ADSP_PCICFGCTL_PCICD BIT(0) +#define ADSP_PCICFGCTL_ACPIIE BIT(1) +#define ADSP_PCICFGCTL_SPCBAD BIT(7) + +#endif /* __ASM_ARCH_BROADWELL_ADSP_H */ diff --git a/arch/x86/include/asm/arch-broadwell/pch.h b/arch/x86/include/asm/arch-broadwell/pch.h index 23ccd68..23153a0 100644 --- a/arch/x86/include/asm/arch-broadwell/pch.h +++ b/arch/x86/include/asm/arch-broadwell/pch.h @@ -109,6 +109,9 @@ #define SATA_DTLE_EDGE_SHIFT 16 /* Power Management */ +#define PCH_PCS 0x84 +#define PCH_PCS_PS_D3HOT 3 + #define GEN_PMCON_1 0xa0 #define SMI_LOCK (1 << 4) #define GEN_PMCON_2 0xa2 diff --git a/arch/x86/include/asm/arch-broadwell/rcb.h b/arch/x86/include/asm/arch-broadwell/rcb.h index e7340c1..b7ce874 100644 --- a/arch/x86/include/asm/arch-broadwell/rcb.h +++ b/arch/x86/include/asm/arch-broadwell/rcb.h @@ -6,6 +6,8 @@ #ifndef __asm_arch_rcba_h #define __asm_arch_rcba_h +#define ACPIIRQEN 0x31e0 /* 32bit */ + #define PMSYNC_CONFIG 0x33c4 /* 32bit */ #define PMSYNC_CONFIG2 0x33cc /* 32bit */ diff --git a/arch/x86/include/asm/arch-broadwell/serialio.h b/arch/x86/include/asm/arch-broadwell/serialio.h new file mode 100644 index 0000000..5e98eaf --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/serialio.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Serial IO defintiions (taken from coreboot file of same name) + * + * Copyright 2019 Google LLC + */ + +#ifndef __ARCH_BROADWELL_SERIALIO_H_ +#define __ARCH_BROADWELL_SERIALIO_H_ + +/* Serial IO IOBP Registers */ +#define SIO_IOBP_PORTCTRL0 0xcb000000 /* SDIO D23:F0 */ +#define SIO_IOBP_PORTCTRL0_ACPI_IRQ_EN BIT(5) +#define SIO_IOBP_PORTCTRL0_PCI_CONF_DIS BIT(4) +#define SIO_IOBP_PORTCTRL1 0xcb000014 /* SDIO D23:F0 */ +#define SIO_IOBP_PORTCTRL1_SNOOP_SELECT(x) (((x) & 3) << 13) +#define SIO_IOBP_GPIODF 0xcb000154 +#define SIO_IOBP_GPIODF_SDIO_IDLE_DET_EN BIT(4) +#define SIO_IOBP_GPIODF_DMA_IDLE_DET_EN BIT(3) +#define SIO_IOBP_GPIODF_UART_IDLE_DET_EN BIT(2) +#define SIO_IOBP_GPIODF_I2C_IDLE_DET_EN BIT(1) +#define SIO_IOBP_GPIODF_SPI_IDLE_DET_EN BIT(0) +#define SIO_IOBP_GPIODF_UART0_BYTE_ACCESS BIT(10) +#define SIO_IOBP_GPIODF_UART1_BYTE_ACCESS BIT(11) +#define SIO_IOBP_PORTCTRL2 0xcb000240 /* DMA D21:F0 */ +#define SIO_IOBP_PORTCTRL3 0xcb000248 /* I2C0 D21:F1 */ +#define SIO_IOBP_PORTCTRL4 0xcb000250 /* I2C1 D21:F2 */ +#define SIO_IOBP_PORTCTRL5 0xcb000258 /* SPI0 D21:F3 */ +#define SIO_IOBP_PORTCTRL6 0xcb000260 /* SPI1 D21:F4 */ +#define SIO_IOBP_PORTCTRL7 0xcb000268 /* UART0 D21:F5 */ +#define SIO_IOBP_PORTCTRL8 0xcb000270 /* UART1 D21:F6 */ +#define SIO_IOBP_PORTCTRLX(x) (0xcb000240 + ((x) * 8)) +/* PORTCTRL 2-8 have the same layout */ +#define SIO_IOBP_PORTCTRL_ACPI_IRQ_EN BIT(21) +#define SIO_IOBP_PORTCTRL_PCI_CONF_DIS BIT(20) +#define SIO_IOBP_PORTCTRL_SNOOP_SELECT(x) (((x) & 3) << 18) +#define SIO_IOBP_PORTCTRL_INT_PIN(x) (((x) & 0xf) << 2) +#define SIO_IOBP_PORTCTRL_PM_CAP_PRSNT BIT(1) +#define SIO_IOBP_FUNCDIS0 0xce00aa07 /* DMA D21:F0 */ +#define SIO_IOBP_FUNCDIS1 0xce00aa47 /* I2C0 D21:F1 */ +#define SIO_IOBP_FUNCDIS2 0xce00aa87 /* I2C1 D21:F2 */ +#define SIO_IOBP_FUNCDIS3 0xce00aac7 /* SPI0 D21:F3 */ +#define SIO_IOBP_FUNCDIS4 0xce00ab07 /* SPI1 D21:F4 */ +#define SIO_IOBP_FUNCDIS5 0xce00ab47 /* UART0 D21:F5 */ +#define SIO_IOBP_FUNCDIS6 0xce00ab87 /* UART1 D21:F6 */ +#define SIO_IOBP_FUNCDIS7 0xce00ae07 /* SDIO D23:F0 */ +#define SIO_IOBP_FUNCDIS_DIS BIT(8) + +/* Serial IO Devices */ +#define SIO_ID_SDMA 0 /* D21:F0 */ +#define SIO_ID_I2C0 1 /* D21:F1 */ +#define SIO_ID_I2C1 2 /* D21:F2 */ +#define SIO_ID_SPI0 3 /* D21:F3 */ +#define SIO_ID_SPI1 4 /* D21:F4 */ +#define SIO_ID_UART0 5 /* D21:F5 */ +#define SIO_ID_UART1 6 /* D21:F6 */ +#define SIO_ID_SDIO 7 /* D23:F0 */ + +#define SIO_REG_PPR_CLOCK 0x800 +#define SIO_REG_PPR_CLOCK_EN BIT(0) +#define SIO_REG_PPR_CLOCK_UPDATE BIT(31) +#define SIO_REG_PPR_CLOCK_M_DIV 0x25a +#define SIO_REG_PPR_CLOCK_N_DIV 0x7fff +#define SIO_REG_PPR_RST 0x804 +#define SIO_REG_PPR_RST_ASSERT 0x3 +#define SIO_REG_PPR_GEN 0x808 +#define SIO_REG_PPR_GEN_LTR_MODE_MASK BIT(2) +#define SIO_REG_PPR_GEN_VOLTAGE_MASK BIT(3) +#define SIO_REG_PPR_GEN_VOLTAGE(x) ((x & 1) << 3) +#define SIO_REG_AUTO_LTR 0x814 + +#define SIO_REG_SDIO_PPR_GEN 0x1008 +#define SIO_REG_SDIO_PPR_SW_LTR 0x1010 +#define SIO_REG_SDIO_PPR_CMD12 0x3c +#define SIO_REG_SDIO_PPR_CMD12_B30 BIT(30) + +#define SIO_PIN_INTA 1 /* IRQ5 in ACPI mode */ +#define SIO_PIN_INTB 2 /* IRQ6 in ACPI mode */ +#define SIO_PIN_INTC 3 /* IRQ7 in ACPI mode */ +#define SIO_PIN_INTD 4 /* IRQ13 in ACPI mode */ + +#endif /* __ARCH_BROADWELL_SERIALIO_H_ */ diff --git a/arch/x86/include/asm/arch-ivybridge/sandybridge.h b/arch/x86/include/asm/arch-ivybridge/sandybridge.h index a96c951..a3a507f 100644 --- a/arch/x86/include/asm/arch-ivybridge/sandybridge.h +++ b/arch/x86/include/asm/arch-ivybridge/sandybridge.h @@ -43,6 +43,9 @@ /* 4 KB per PCIe device */ #define DEFAULT_PCIEXBAR CONFIG_PCIE_ECAM_BASE +#define IOMMU_BASE1 0xfed90000ULL +#define IOMMU_BASE2 0xfed91000ULL + /* Device 0:0.0 PCI configuration space (Host Bridge) */ #define EPBAR 0x40 #define MCHBAR 0x48 diff --git a/arch/x86/include/asm/i8254.h b/arch/x86/include/asm/i8254.h index 65c9761..d769daf 100644 --- a/arch/x86/include/asm/i8254.h +++ b/arch/x86/include/asm/i8254.h @@ -35,4 +35,22 @@ /* The clock frequency of the i8253/i8254 PIT */ #define PIT_TICK_RATE 1193182 +/** + * i8254_enable_beep() - Start a beep using the PCAT timer + * + * This starts beeping using the legacy i8254 timer. The beep may be silenced + * after a delay with i8254_disable_beep(). + * + * @frequency_hz: Frequency of beep in Hz + * @return 0 if OK, -EINVAL if frequency_hz is 0 + */ +int i8254_enable_beep(uint frequency_hz); + +/** + * i8254_disable_beep() - Disable the bepper + * + * This stops any existing beep + */ +void i8254_disable_beep(void); + #endif /* _ASMI386_I8954_H_ */ diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 81def0a..cf6c33c 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -57,19 +57,19 @@ * memory location directly. */ -#define readb(addr) (*(volatile unsigned char *) (addr)) -#define readw(addr) (*(volatile unsigned short *) (addr)) -#define readl(addr) (*(volatile unsigned int *) (addr)) -#define readq(addr) (*(volatile unsigned long long *) (addr)) +#define readb(addr) (*(volatile u8 *)(uintptr_t)(addr)) +#define readw(addr) (*(volatile u16 *)(uintptr_t)(addr)) +#define readl(addr) (*(volatile u32 *)(uintptr_t)(addr)) +#define readq(addr) (*(volatile u64 *)(uintptr_t)(addr)) #define __raw_readb readb #define __raw_readw readw #define __raw_readl readl #define __raw_readq readq -#define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b)) -#define writew(b,addr) (*(volatile unsigned short *) (addr) = (b)) -#define writel(b,addr) (*(volatile unsigned int *) (addr) = (b)) -#define writeq(b,addr) (*(volatile unsigned long long *) (addr) = (b)) +#define writeb(b, addr) (*(volatile u8 *)(addr) = (b)) +#define writew(b, addr) (*(volatile u16 *)(addr) = (b)) +#define writel(b, addr) (*(volatile u32 *)(addr) = (b)) +#define writeq(b, addr) (*(volatile u64 *)(addr) = (b)) #define __raw_writeb writeb #define __raw_writew writew #define __raw_writel writel diff --git a/arch/x86/lib/i8254.c b/arch/x86/lib/i8254.c index 1f10124..d022795 100644 --- a/arch/x86/lib/i8254.c +++ b/arch/x86/lib/i8254.c @@ -8,8 +8,20 @@ #include #include -#define TIMER1_VALUE 18 /* 15.6us */ -#define TIMER2_VALUE 0x0a8e /* 440Hz */ +#define TIMER1_VALUE 18 /* 15.6us */ +#define BEEP_FREQUENCY_HZ 440 +#define SYSCTL_PORTB 0x61 +#define PORTB_BEEP_ENABLE 0x3 + +static void i8254_set_beep_freq(uint frequency_hz) +{ + uint countdown; + + countdown = PIT_TICK_RATE / frequency_hz; + + outb(countdown & 0xff, PIT_BASE + PIT_T2); + outb((countdown >> 8) & 0xff, PIT_BASE + PIT_T2); +} int i8254_init(void) { @@ -29,8 +41,23 @@ int i8254_init(void) */ outb(PIT_CMD_CTR2 | PIT_CMD_BOTH | PIT_CMD_MODE3, PIT_BASE + PIT_COMMAND); - outb(TIMER2_VALUE & 0xff, PIT_BASE + PIT_T2); - outb(TIMER2_VALUE >> 8, PIT_BASE + PIT_T2); + i8254_set_beep_freq(BEEP_FREQUENCY_HZ); + + return 0; +} + +int i8254_enable_beep(uint frequency_hz) +{ + if (!frequency_hz) + return -EINVAL; + + i8254_set_beep_freq(frequency_hz); + setio_8(SYSCTL_PORTB, PORTB_BEEP_ENABLE); return 0; } + +void i8254_disable_beep(void) +{ + clrio_8(SYSCTL_PORTB, PORTB_BEEP_ENABLE); +} diff --git a/board/BuR/brxre1/MAINTAINERS b/board/BuR/brxre1/MAINTAINERS index a10d9c1..eb0fe8b 100644 --- a/board/BuR/brxre1/MAINTAINERS +++ b/board/BuR/brxre1/MAINTAINERS @@ -4,3 +4,4 @@ S: Maintained F: board/BuR/brxre1/ F: include/configs/brxre1.h F: configs/brxre1_defconfig +F: arch/arm/dts/am335x-brxre1.dts diff --git a/board/BuR/brxre1/board.c b/board/BuR/brxre1/board.c index 82c53d5..2d0ed41 100644 --- a/board/BuR/brxre1/board.c +++ b/board/BuR/brxre1/board.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include "../common/bur_common.h" @@ -48,6 +49,25 @@ DECLARE_GLOBAL_DATA_PTR; +static int rstctrl_rw(u8 reg, unsigned char rnw, void *pdat, int size) +{ + struct udevice *i2cdev; + int rc; + + rc = i2c_get_chip_for_busnum(0, RSTCTRL_ADDR, 1, &i2cdev); + if (rc >= 0) { + if (rnw) + rc = dm_i2c_read(i2cdev, reg, pdat, size); + else + rc = dm_i2c_write(i2cdev, reg, pdat, size); + } else { + printf("%s: cannot get udevice for chip 0x%02x!\n", + __func__, RSTCTRL_ADDR); + } + + return rc; +} + #if defined(CONFIG_SPL_BUILD) /* TODO: check ram-timing ! */ static const struct ddr_data ddr3_data = { @@ -89,8 +109,8 @@ const struct dpll_params dpll_ddr3 = { 400, OSC-1, 1, -1, -1, -1, -1}; void am33xx_spl_board_init(void) { - unsigned int oldspeed; unsigned short buf; + int rc; struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP; @@ -114,23 +134,19 @@ void am33xx_spl_board_init(void) }; do_enable_clocks(clk_domains, clk_modules_xre1specific, 1); /* power-OFF LCD-Display */ - gpio_direction_output(LCD_PWR, 0); + if (gpio_request(LCD_PWR, "LCD_PWR") != 0) + printf("cannot request gpio for LCD_PWR!\n"); + else if (gpio_direction_output(LCD_PWR, 0) != 0) + printf("cannot set direction output on LCD_PWR!\n"); /* setup I2C */ enable_i2c_pin_mux(); - i2c_set_bus_num(0); - i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE); - /* power-ON 3V3 via Resetcontroller */ - oldspeed = i2c_get_bus_speed(); - if (i2c_set_bus_speed(CONFIG_SYS_OMAP24_I2C_SPEED_PSOC) >= 0) { - buf = RSTCTRL_FORCE_PWR_NEN | RSTCTRL_CAN_STB; - i2c_write(RSTCTRL_ADDR, RSTCTRL_CTRLREG, 1, - (uint8_t *)&buf, sizeof(buf)); - i2c_set_bus_speed(oldspeed); - } else { - puts("ERROR: i2c_set_bus_speed failed! (turn on PWR_nEN)\n"); - } + /* power-ON 3V3 via Resetcontroller */ + buf = RSTCTRL_FORCE_PWR_NEN | RSTCTRL_CAN_STB; + rc = rstctrl_rw(RSTCTRL_CTRLREG, 0, (uint8_t *)&buf, sizeof(buf)); + if (rc != 0) + printf("ERROR: cannot write to resetc (turn on PWR_nEN)\n"); pmicsetup(0, 0); } @@ -153,7 +169,9 @@ void sdram_init(void) */ int board_init(void) { - gpmc_init(); + if (power_tps65217_init(0)) + printf("WARN: cannot setup PMIC 0x24 @ bus #0, not found!.\n"); + return 0; } @@ -164,19 +182,16 @@ int board_late_init(void) unsigned int cnt = 3; unsigned short buf = 0xAAAA; unsigned char scratchreg = 0; - unsigned int oldspeed; + int rc; /* try to read out some boot-instruction from resetcontroller */ - oldspeed = i2c_get_bus_speed(); - if (i2c_set_bus_speed(CONFIG_SYS_OMAP24_I2C_SPEED_PSOC) >= 0) { - i2c_read(RSTCTRL_ADDR, RSTCTRL_SCRATCHREG, 1, - &scratchreg, sizeof(scratchreg)); - i2c_set_bus_speed(oldspeed); - } else { - puts("ERROR: i2c_set_bus_speed failed! (scratchregister)\n"); - } + rc = rstctrl_rw(RSTCTRL_SCRATCHREG, 1, &scratchreg, sizeof(scratchreg)); + if (rc != 0) + printf("ERROR: read scratchregister (resetc) failed!\n"); - if (gpio_get_value(ESC_KEY)) { + if (gpio_request(ESC_KEY, "boot-key") != 0) { + printf("cannot request boot-key!\n"); + } else if (gpio_get_value(ESC_KEY)) { do { lcd_position_cursor(1, 8); switch (cnt) { @@ -266,14 +281,10 @@ int board_late_init(void) break; } /* write bootinfo into scratchregister of resetcontroller */ - oldspeed = i2c_get_bus_speed(); - if (i2c_set_bus_speed(CONFIG_SYS_OMAP24_I2C_SPEED_PSOC) >= 0) { - i2c_write(RSTCTRL_ADDR, RSTCTRL_SCRATCHREG, 1, - (uint8_t *)&buf, sizeof(buf)); - i2c_set_bus_speed(oldspeed); - } else { - puts("ERROR: i2c_set_bus_speed failed! (scratchregister)\n"); - } + rc = rstctrl_rw(RSTCTRL_SCRATCHREG, 0, (uint8_t *)&buf, sizeof(buf)); + if (rc != 0) + printf("ERROR: write scratchregister (resetc) failed!\n"); + /* setup othbootargs for bootvx-command (vxWorks bootline) */ char othbootargs[128]; snprintf(othbootargs, sizeof(othbootargs), diff --git a/board/BuR/common/common.c b/board/BuR/common/common.c index a1f7c44..602c571 100644 --- a/board/BuR/common/common.c +++ b/board/BuR/common/common.c @@ -181,6 +181,7 @@ void br_summaryscreen(void) void lcdpower(int on) { u32 pin, swval, i; + char buf[16] = { 0 }; pin = env_get_ulong("ds1_pwr", 16, ~0UL); @@ -191,6 +192,12 @@ void lcdpower(int on) for (i = 0; i < 3; i++) { if (pin != 0) { + snprintf(buf, sizeof(buf), "ds1_pwr#%d", i); + if (gpio_request(pin & 0x7F, buf) != 0) { + printf("%s: not able to request gpio %s", + __func__, buf); + continue; + } swval = pin & 0x80 ? 0 : 1; if (on) gpio_direction_output(pin & 0x7F, swval); diff --git a/board/broadcom/bcm963158/Kconfig b/board/broadcom/bcm963158/Kconfig index 41b6adb..08a8bc1 100644 --- a/board/broadcom/bcm963158/Kconfig +++ b/board/broadcom/bcm963158/Kconfig @@ -1,4 +1,4 @@ -if ARCH_BCM63158 +if TARGET_BCM963158 config SYS_VENDOR default "broadcom" diff --git a/board/davinci/da8xxevm/README.da850 b/board/davinci/da8xxevm/README.da850 index f24e8b5..5775b7d 100644 --- a/board/davinci/da8xxevm/README.da850 +++ b/board/davinci/da8xxevm/README.da850 @@ -88,6 +88,14 @@ In this case the commands would be simplified to: U-Boot > nand erase.part bootloader U-Boot > nand write 0xc0700000 bootloader +On the DA850-EVM, NAND can also be written with SW7:7-8 ON and + + sudo mono sfh_OMAP-L138.exe -targetType AM1808 -p /dev/ttyUSB0 \ + -flash_noubl -flashType NAND ~/src/u-boot/u-boot.ais + +To boot the DA850-EVM from NAND, SW7:5 should be switched on and all others +off. + Flashing the images to MMC ========================== If the boot pins are set to boot from mmc, the RBL will try to load the diff --git a/board/eets/pdu001/mux.c b/board/eets/pdu001/mux.c index f1d38e9..f0f9e26 100644 --- a/board/eets/pdu001/mux.c +++ b/board/eets/pdu001/mux.c @@ -8,11 +8,11 @@ */ #include +#include #include #include #include #include -#include #include "board.h" static struct module_pin_mux uart0_pin_mux[] = { diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig index 0d865ac..88d07d5 100644 --- a/board/emulation/qemu-riscv/Kconfig +++ b/board/emulation/qemu-riscv/Kconfig @@ -7,7 +7,7 @@ config SYS_VENDOR default "emulation" config SYS_CPU - default "qemu" + default "generic" config SYS_CONFIG_NAME default "qemu-riscv" @@ -18,7 +18,7 @@ config SYS_TEXT_BASE config BOARD_SPECIFIC_OPTIONS # dummy def_bool y - select QEMU_RISCV + select GENERIC_RISCV imply SYS_NS16550 imply VIRTIO_MMIO imply VIRTIO_NET diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index e3c5eae..a9d61a8 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -64,6 +64,8 @@ obj-$(CONFIG_POWER_MC34VR500) += mc34vr500.o obj-$(CONFIG_LS102XA_STREAM_ID) += ls102xa_stream_id.o +obj-$(CONFIG_EMC2305) += emc2305.o + # deal with common files for P-series corenet based devices obj-$(CONFIG_TARGET_P2041RDB) += p_corenet/ obj-$(CONFIG_TARGET_P3041DS) += p_corenet/ diff --git a/board/freescale/common/emc2305.c b/board/freescale/common/emc2305.c new file mode 100644 index 0000000..8523084 --- /dev/null +++ b/board/freescale/common/emc2305.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +#include "emc2305.h" + +DECLARE_GLOBAL_DATA_PTR; + +void set_fan_speed(u8 data) +{ + u8 index; + u8 Fan[NUM_OF_FANS] = {I2C_EMC2305_FAN1, + I2C_EMC2305_FAN2, + I2C_EMC2305_FAN3, + I2C_EMC2305_FAN4, + I2C_EMC2305_FAN5}; + + for (index = 0; index < NUM_OF_FANS; index++) { + if (i2c_write(I2C_EMC2305_ADDR, Fan[index], 1, &data, 1) != 0) { + printf("Error: failed to change fan speed @%x\n", + Fan[index]); + } + } +} + +void emc2305_init(void) +{ + u8 data; + + data = I2C_EMC2305_CMD; + if (i2c_write(I2C_EMC2305_ADDR, I2C_EMC2305_CONF, 1, &data, 1) != 0) + printf("Error: failed to configure EMC2305\n"); +} diff --git a/board/freescale/common/emc2305.h b/board/freescale/common/emc2305.h new file mode 100644 index 0000000..eddf537 --- /dev/null +++ b/board/freescale/common/emc2305.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2018 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __EMC2305_H_ +#define __EMC2305_H_ + +#define I2C_EMC2305_CONF 0x20 +#define I2C_EMC2305_FAN1 0x30 +#define I2C_EMC2305_FAN2 0x40 +#define I2C_EMC2305_FAN3 0x50 +#define I2C_EMC2305_FAN4 0x60 +#define I2C_EMC2305_FAN5 0x70 + +#define NUM_OF_FANS 5 + +void emc2305_init(void); +void set_fan_speed(u8 data); + +#endif /* __EMC2305_H_ */ diff --git a/board/freescale/common/qixis.c b/board/freescale/common/qixis.c index af3dc59..f1b98bc 100644 --- a/board/freescale/common/qixis.c +++ b/board/freescale/common/qixis.c @@ -227,8 +227,12 @@ static int qixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const ar #ifdef QIXIS_LBMAP_SD QIXIS_WRITE(rst_ctl, 0x30); QIXIS_WRITE(rcfg_ctl, 0); +#ifdef NON_EXTENDED_DUTCFG + QIXIS_WRITE(dutcfg[0], QIXIS_RCW_SRC_SD); +#else set_lbmap(QIXIS_LBMAP_SD); set_rcw_src(QIXIS_RCW_SRC_SD); +#endif QIXIS_WRITE(rcfg_ctl, 0x20); QIXIS_WRITE(rcfg_ctl, 0x21); #else diff --git a/board/freescale/lx2160a/Kconfig b/board/freescale/lx2160a/Kconfig new file mode 100644 index 0000000..122a385 --- /dev/null +++ b/board/freescale/lx2160a/Kconfig @@ -0,0 +1,34 @@ +if TARGET_LX2160ARDB + +config SYS_BOARD + default "lx2160a" + +config SYS_VENDOR + default "freescale" + +config SYS_SOC + default "fsl-layerscape" + +config SYS_CONFIG_NAME + default "lx2160ardb" + +source "board/freescale/common/Kconfig" +endif + +if TARGET_LX2160AQDS + +config SYS_BOARD + default "lx2160a" + +config SYS_VENDOR + default "freescale" + +config SYS_SOC + default "fsl-layerscape" + +config SYS_CONFIG_NAME + default "lx2160aqds" + +source "board/freescale/common/Kconfig" +endif + diff --git a/board/freescale/lx2160a/MAINTAINERS b/board/freescale/lx2160a/MAINTAINERS new file mode 100644 index 0000000..47ae04c --- /dev/null +++ b/board/freescale/lx2160a/MAINTAINERS @@ -0,0 +1,26 @@ +LX2160ARDB BOARD +M: Priyanka Jain +S: Maintained +F: board/freescale/lx2160a/ +F: include/configs/lx2160a_common.h +F: include/configs/lx2160ardb.h +F: configs/lx2160ardb_tfa_defconfig +F: arch/arm/dts/fsl-lx2160a-rdb.dts + +LX2160ARDB_SECURE_BOOT BOARD +M: Udit Agarwal +S: Maintained +F: configs/lx2160ardb_tfa_SECURE_BOOT_defconfig + +LX2160AQDS BOARD +M: Pankaj Bansal +S: Maintained +F: board/freescale/lx2160a/eth_lx2160aqds.h +F: include/configs/lx2160aqds.h +F: configs/lx2160aqds_tfa_defconfig +F: arch/arm/dts/fsl-lx2160a-qds.dts + +LX2160AQDS_SECURE_BOOT BOARD +M: Udit Agarwal +S: Maintained +F: configs/lx2160aqds_tfa_SECURE_BOOT_defconfig diff --git a/board/freescale/lx2160a/Makefile b/board/freescale/lx2160a/Makefile new file mode 100644 index 0000000..d1a621b --- /dev/null +++ b/board/freescale/lx2160a/Makefile @@ -0,0 +1,10 @@ +# +# Copyright 2018 Freescale Semiconductor +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += lx2160a.o +obj-y += ddr.o +obj-$(CONFIG_TARGET_LX2160ARDB) += eth_lx2160ardb.o +obj-$(CONFIG_TARGET_LX2160AQDS) += eth_lx2160aqds.o diff --git a/board/freescale/lx2160a/README b/board/freescale/lx2160a/README new file mode 100644 index 0000000..62fb9ea --- /dev/null +++ b/board/freescale/lx2160a/README @@ -0,0 +1,197 @@ +Overview +-------- +The LX2160A Reference Design (RDB) is a high-performance computing, +evaluation, and development platform that supports the QorIQ LX2160A +Layerscape Architecture processor and its personalities. + +LX2160A SoC Overview +-------------------------------------- +For details, please refer arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc + +LX2160ARDB board Overview +---------------------- +DDR Memory + Two ports of 72-bits (8-bits ECC) DDR4. + Each port supports four chip-selects and two DIMM + connectors. Data rate upto 3.2 GT/s. + +SERDES ports + Thress serdes controllers (24 lanes) + Serdes1: Supports two USXGMII connectors, each connected through + Aquantia AQR107 phy, two 25GbE SFP+ modules connected through an Inphi + IN112525 phy and one 40 GbE QSFP+ module connected through an Inphi + CS4223 phy. + + Serdes2: Supports one PCIe x4 (Gen1/2/3/4) connector, four SATA 3.0 + connectors + + Serdes3: Supports one PCIe x8 (Gen1/2/3/4) connector + +eSDHC + eSDHC1: Supports a SD connector for connecting SD cards + eSDHC2: Supports 128GB Micron MTFC128GAJAECE-IT eMMC + +Octal SPI (XSPI) + Supports two 64 MB onbpard octal SPI flash memories, one SPI emulator + for off-board emulation + +I2C All system devices on I2C1 multiplexed using PCA9547 multiplexer + Serial Ports + +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 + +Serial Ports Two UART ports +Ethernet Two RGMII interfaces +Debug ARM JTAG support + +Booting Options +--------------- +a) Flexspi boot +b) SD boot + +Memory map for Flexspi flash +---------------------------- +Image Flash Offset +bl2_flexspi_nor.pbl (RCW+PBI+bl2.pbl) 0x00000000 +fip.bin (bl31 + bl33(u-boot) + + header for Secure-boot(secure-boot only)) 0x00100000 +Boot firmware Environment 0x00500000 +DDR PHY Firmware (fip_ddr_all.bin) 0x00800000 +DPAA2 MC Firmware 0x00A00000 +DPAA2 DPL 0x00D00000 +DPAA2 DPC 0x00E00000 +Kernel.itb 0x01000000 + +Memory map for sd card +---------------------------- +Image SD card Offset +bl2_sd.pbl (RCW+PBI+bl2.pbl) 0x00008 +fip.bin (bl31 + bl33(u-boot) + + header for Secure-boot(secure-boot only)) 0x00800 +Boot firmware Environment 0x02800 +DDR PHY Firmware (fip_ddr_all.bin) 0x04000 +DPAA2 MC Firmware 0x05000 +DPAA2 DPL 0x06800 +DPAA2 DPC 0x07000 +Kernel.itb 0x08000 + +LX2160AQDS board Overview +---------------------- +Various Mezzanine cards and their connection for different SERDES protocols is +as below: + +SERDES1 |CARDS +----------------------------------------------------------------------- +1 |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT1 (J108) + |Connect I/O cable to IO_SLOT1(J110) + |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT2 (J111) + |Connect I/O cable to IO_SLOT2(J113) +------------------------------------------------------------------------ +3 |Mezzanine:X-M11-USXGMII (29828) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT1 (J108) + |Connect I/O cable to IO_SLOT1(J110) + |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT2 (J111) + |Connect I/O cable to IO_SLOT2(J113) +------------------------------------------------------------------------ +7 |Mezzanine:X-M11-USXGMII (29828) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT1 (J108) + |Connect I/O cable to IO_SLOT1(J110) + |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT2 (J111) + |Connect I/O cable to IO_SLOT2(J113) +------------------------------------------------------------------------ +8 |Mezzanine:X-M12-XFI (29829) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT1 (J108) + |Connect I/O cable to IO_SLOT1(J110) + |Mezzanine:X-M12-XFI (29829) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT2 (J111) + |Connect I/O cable to IO_SLOT2(J113) +------------------------------------------------------------------------ +13 |Mezzanine:X-M8-100G (29734) + |Connect Hydra Cable (HDR-198816-XX-ECUE) to SD_SLOT1 (J108) + |Connect I/O cable to IO_SLOT1(J110) + |Mezzanine:X-M8-100G (29734) + |Connect Hydra Cable (HDR-198816-XX-ECUE) to SD_SLOT2(J111) + |Connect I/O cable to IO_SLOT2(J113) +------------------------------------------------------------------------ +15 |Mezzanine:X-M8-100G (29734) + |Connect Hydra Cable (HDR-198816-XX-ECUE) to SD_SLOT1 (J108) + |Connect I/O cable to IO_SLOT1(J110) + |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT2 (J111) + |Connect I/O cable to IO_SLOT2(J113) +------------------------------------------------------------------------ +17 |Mezzanine:X-M13-25G (32133) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT1 (J108) + |Connect I/O cable to IO_SLOT1(J110) + |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT2 (J111) + |Connect I/O cable to IO_SLOT2(J113) +------------------------------------------------------------------------ +19 |Mezzanine:X-M11-USXGMII (29828), X-M13-25G (32133) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT1 (J108) + |Connect M11 I/O cable to IO_SLOT1(J110), M13 I/O cable to IO_SLOT6(J125) + |Mezzanine:X-M7-40G (29738) + |Connect Straight Cable (HDR-198816-XX-ECUE) to SD_SLOT2 (J111) + |Connect I/O cable to IO_SLOT2(J113) +------------------------------------------------------------------------ +20 |Mezzanine:X-M7-40G (29738) + |Connect Straight Cable (HDR-198816-XX-ECUE) to SD_SLOT1 (J108) + |Connect I/O cable to IO_SLOT1(J108) + |Mezzanine:X-M7-40G (29738) + |Connect Straight Cable (HDR-198816-XX-ECUE) to SD_SLOT2 (J111) + |Connect I/O cable to IO_SLOT2(J113) +------------------------------------------------------------------------ + + +SERDES2 |CARDS +----------------------------------------------------------------------- +2 |Mezzanine:X-M6-PCIE-X8 (29737) * + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT3 (J114) + |Connect Straight Cable (HDR-198816-XX-ECUE) to SD_SLOT4 (J117) + |Connect I/O cable to IO_SLOT3(J116) +------------------------------------------------------------------------ +3 |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT3 (J114) + |Connect I/O cable to IO_SLOT3(J116) + |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT4 (J117) + |Connect I/O cable to IO_SLOT4(J119) +------------------------------------------------------------------------ +5 |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT3 (J114) + |Connect I/O cable to IO_SLOT3(J116) + |Mezzanine:X-M5-SATA (29687) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT4 (J117) + |Connect I/O cable to IO_SLOT4(J119) +------------------------------------------------------------------------ +11 |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT3 (J114) + |Connect I/O cable to IO_SLOT7(J127) + |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT4 (J117) + |Connect I/O cable to IO_SLOT8(J131) +------------------------------------------------------------------------ + + +SERDES3 |CARDS +----------------------------------------------------------------------- +2 |Mezzanine:X-M6-PCIE-X8 (29737) * + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT5 (J120) + |Connect Straight Cable (HDR-198816-XX-ECUE) to SD_SLOT6 (J123) + |Connect I/O cable to IO_SLOT5(J122) +------------------------------------------------------------------------- +3 |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT5 (J120) + |Connect I/O cable to IO_SLOT5(J122) + |Mezzanine:X-M4-PCIE-SGMII (29733) + |Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT6 (J123) + |Connect I/O cable to IO_SLOT6(J125) +------------------------------------------------------------------------- + diff --git a/board/freescale/lx2160a/ddr.c b/board/freescale/lx2160a/ddr.c new file mode 100644 index 0000000..cd422bf --- /dev/null +++ b/board/freescale/lx2160a/ddr.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int fsl_initdram(void) +{ + gd->ram_size = tfa_get_dram_size(); + + if (!gd->ram_size) + gd->ram_size = fsl_ddr_sdram_size(); + + return 0; +} diff --git a/board/freescale/lx2160a/eth_lx2160aqds.c b/board/freescale/lx2160a/eth_lx2160aqds.c new file mode 100644 index 0000000..1e98d0c --- /dev/null +++ b/board/freescale/lx2160a/eth_lx2160aqds.c @@ -0,0 +1,805 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018-2019 NXP + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../common/qixis.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define EMI_NONE 0 +#define EMI1 1 /* Mdio Bus 1 */ +#define EMI2 2 /* Mdio Bus 2 */ + +#if defined(CONFIG_FSL_MC_ENET) +enum io_slot { + IO_SLOT_NONE = 0, + IO_SLOT_1, + IO_SLOT_2, + IO_SLOT_3, + IO_SLOT_4, + IO_SLOT_5, + IO_SLOT_6, + IO_SLOT_7, + IO_SLOT_8, + EMI1_RGMII1, + EMI1_RGMII2, + IO_SLOT_MAX +}; + +struct lx2160a_qds_mdio { + enum io_slot ioslot : 4; + u8 realbusnum : 4; + struct mii_dev *realbus; +}; + +/* structure explaining the phy configuration on 8 lanes of a serdes*/ +struct serdes_phy_config { + u8 serdes; /* serdes protocol */ + struct phy_config { + u8 dpmacid; + /* -1 terminated array */ + int phy_address[WRIOP_MAX_PHY_NUM + 1]; + u8 mdio_bus; + enum io_slot ioslot; + } phy_config[SRDS_MAX_LANES]; +}; + +/* Table defining the phy configuration on 8 lanes of a serdes. + * Various assumptions have been made while defining this table. + * e.g. for serdes1 protocol 19 it is being assumed that X-M11-USXGMII + * card is being used for dpmac 3-4. (X-M12-XFI could also have been used) + * And also that this card is connected to IO Slot 1 (could have been connected + * to any of the 8 IO slots (IO slot 1 - IO slot 8)). + * similarly, it is also being assumed that MDIO 1 is selected on X-M7-40G card + * used in serdes1 protocol 19 (could have selected MDIO 2) + * To override these settings "dpmac" environment variable can be used after + * defining "dpmac_override" in hwconfig environment variable. + * This table has limited serdes protocol entries. It can be expanded as per + * requirement. + */ +static const struct serdes_phy_config serdes1_phy_config[] = { + {3, {{WRIOP1_DPMAC3, {AQ_PHY_ADDR1, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC4, {AQ_PHY_ADDR2, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC5, {AQ_PHY_ADDR3, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC6, {AQ_PHY_ADDR4, -1}, + EMI1, IO_SLOT_1} } }, + {7, {{WRIOP1_DPMAC3, {AQ_PHY_ADDR1, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC4, {AQ_PHY_ADDR2, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC5, {AQ_PHY_ADDR3, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC6, {AQ_PHY_ADDR4, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC7, {SGMII_CARD_PORT1_PHY_ADDR, -1}, + EMI1, IO_SLOT_2}, + {WRIOP1_DPMAC8, {SGMII_CARD_PORT2_PHY_ADDR, -1}, + EMI1, IO_SLOT_2}, + {WRIOP1_DPMAC9, {SGMII_CARD_PORT3_PHY_ADDR, -1}, + EMI1, IO_SLOT_2}, + {WRIOP1_DPMAC10, {SGMII_CARD_PORT4_PHY_ADDR, -1}, + EMI1, IO_SLOT_2} } }, + {8, {} }, + {13, {{WRIOP1_DPMAC1, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC2, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1}, + EMI1, IO_SLOT_2} } }, + {15, {{WRIOP1_DPMAC1, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC2, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1}, + EMI1, IO_SLOT_1} } }, + {17, {{WRIOP1_DPMAC3, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC4, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC5, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC6, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1}, + EMI1, IO_SLOT_1} } }, + {19, {{WRIOP1_DPMAC2, {CORTINA_PHY_ADDR1, -1}, + EMI1, IO_SLOT_2}, + {WRIOP1_DPMAC3, {AQ_PHY_ADDR1, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC4, {AQ_PHY_ADDR2, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC5, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1}, + EMI1, IO_SLOT_6}, + {WRIOP1_DPMAC6, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1}, + EMI1, IO_SLOT_6} } }, + {20, {{WRIOP1_DPMAC1, {CORTINA_PHY_ADDR1, -1}, + EMI1, IO_SLOT_1}, + {WRIOP1_DPMAC2, {CORTINA_PHY_ADDR1, -1}, + EMI1, IO_SLOT_2} } } +}; + +static const struct serdes_phy_config serdes2_phy_config[] = { + {2, {} }, + {3, {} }, + {5, {} }, + {11, {{WRIOP1_DPMAC12, {SGMII_CARD_PORT2_PHY_ADDR, -1}, + EMI1, IO_SLOT_7}, + {WRIOP1_DPMAC17, {SGMII_CARD_PORT3_PHY_ADDR, -1}, + EMI1, IO_SLOT_7}, + {WRIOP1_DPMAC18, {SGMII_CARD_PORT4_PHY_ADDR, -1}, + EMI1, IO_SLOT_7}, + {WRIOP1_DPMAC16, {SGMII_CARD_PORT2_PHY_ADDR, -1}, + EMI1, IO_SLOT_8}, + {WRIOP1_DPMAC13, {SGMII_CARD_PORT3_PHY_ADDR, -1}, + EMI1, IO_SLOT_8}, + {WRIOP1_DPMAC14, {SGMII_CARD_PORT4_PHY_ADDR, -1}, + EMI1, IO_SLOT_8} } }, +}; + +static const struct serdes_phy_config serdes3_phy_config[] = { + {2, {} }, + {3, {} } +}; + +static inline +const struct phy_config *get_phy_config(u8 serdes, + const struct serdes_phy_config *table, + u8 table_size) +{ + int i; + + for (i = 0; i < table_size; i++) { + if (table[i].serdes == serdes) + return table[i].phy_config; + } + + return NULL; +} + +/* BRDCFG4 controls EMI routing for the board. + * Bits Function + * 7-6 EMI Interface #1 Primary Routing (CFG_MUX1_EMI1) (1.8V): + * EMI1 00= On-board PHY #1 + * 01= On-board PHY #2 + * 10= (reserved) + * 11= Slots 1..8 multiplexer and translator. + * 5-3 EMI Interface #1 Secondary Routing (CFG_MUX2_EMI1) (2.5V): + * EMI1X 000= Slot #1 + * 001= Slot #2 + * 010= Slot #3 + * 011= Slot #4 + * 100= Slot #5 + * 101= Slot #6 + * 110= Slot #7 + * 111= Slot #8 + * 2-0 EMI Interface #2 Routing (CFG_MUX_EMI2): + * EMI2 000= Slot #1 (secondary EMI) + * 001= Slot #2 (secondary EMI) + * 010= Slot #3 (secondary EMI) + * 011= Slot #4 (secondary EMI) + * 100= Slot #5 (secondary EMI) + * 101= Slot #6 (secondary EMI) + * 110= Slot #7 (secondary EMI) + * 111= Slot #8 (secondary EMI) + */ +static int lx2160a_qds_get_mdio_mux_val(u8 realbusnum, enum io_slot ioslot) +{ + switch (realbusnum) { + case EMI1: + switch (ioslot) { + case EMI1_RGMII1: + return 0; + case EMI1_RGMII2: + return 0x40; + default: + return (((ioslot - 1) << BRDCFG4_EMI1SEL_SHIFT) | 0xC0); + } + break; + case EMI2: + return ((ioslot - 1) << BRDCFG4_EMI2SEL_SHIFT); + default: + return -1; + } +} + +static void lx2160a_qds_mux_mdio(struct lx2160a_qds_mdio *priv) +{ + u8 brdcfg4, mux_val, reg; + + brdcfg4 = QIXIS_READ(brdcfg[4]); + reg = brdcfg4; + mux_val = lx2160a_qds_get_mdio_mux_val(priv->realbusnum, priv->ioslot); + + switch (priv->realbusnum) { + case EMI1: + brdcfg4 &= ~BRDCFG4_EMI1SEL_MASK; + brdcfg4 |= mux_val; + break; + case EMI2: + brdcfg4 &= ~BRDCFG4_EMI2SEL_MASK; + brdcfg4 |= mux_val; + break; + } + + if (brdcfg4 ^ reg) + QIXIS_WRITE(brdcfg[4], brdcfg4); +} + +static int lx2160a_qds_mdio_read(struct mii_dev *bus, int addr, + int devad, int regnum) +{ + struct lx2160a_qds_mdio *priv = bus->priv; + + lx2160a_qds_mux_mdio(priv); + + return priv->realbus->read(priv->realbus, addr, devad, regnum); +} + +static int lx2160a_qds_mdio_write(struct mii_dev *bus, int addr, int devad, + int regnum, u16 value) +{ + struct lx2160a_qds_mdio *priv = bus->priv; + + lx2160a_qds_mux_mdio(priv); + + return priv->realbus->write(priv->realbus, addr, devad, regnum, value); +} + +static int lx2160a_qds_mdio_reset(struct mii_dev *bus) +{ + struct lx2160a_qds_mdio *priv = bus->priv; + + return priv->realbus->reset(priv->realbus); +} + +static struct mii_dev *lx2160a_qds_mdio_init(u8 realbusnum, enum io_slot ioslot) +{ + struct lx2160a_qds_mdio *pmdio; + struct mii_dev *bus; + /*should be within MDIO_NAME_LEN*/ + char dummy_mdio_name[] = "LX2160A_QDS_MDIO1_IOSLOT1"; + + if (realbusnum == EMI2) { + if (ioslot < IO_SLOT_1 || ioslot > IO_SLOT_8) { + printf("invalid ioslot %d\n", ioslot); + return NULL; + } + } else if (realbusnum == EMI1) { + if (ioslot < IO_SLOT_1 || ioslot > EMI1_RGMII2) { + printf("invalid ioslot %d\n", ioslot); + return NULL; + } + } else { + printf("not supported real mdio bus %d\n", realbusnum); + return NULL; + } + + if (ioslot == EMI1_RGMII1) + strcpy(dummy_mdio_name, "LX2160A_QDS_MDIO1_RGMII1"); + else if (ioslot == EMI1_RGMII2) + strcpy(dummy_mdio_name, "LX2160A_QDS_MDIO1_RGMII2"); + else + sprintf(dummy_mdio_name, "LX2160A_QDS_MDIO%d_IOSLOT%d", + realbusnum, ioslot); + bus = miiphy_get_dev_by_name(dummy_mdio_name); + + if (bus) + return bus; + + bus = mdio_alloc(); + if (!bus) { + printf("Failed to allocate %s bus\n", dummy_mdio_name); + return NULL; + } + + pmdio = malloc(sizeof(*pmdio)); + if (!pmdio) { + printf("Failed to allocate %s private data\n", dummy_mdio_name); + free(bus); + return NULL; + } + + switch (realbusnum) { + case EMI1: + pmdio->realbus = + miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME); + break; + case EMI2: + pmdio->realbus = + miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME); + break; + } + + if (!pmdio->realbus) { + printf("No real mdio bus num %d found\n", realbusnum); + free(bus); + free(pmdio); + return NULL; + } + + pmdio->realbusnum = realbusnum; + pmdio->ioslot = ioslot; + bus->read = lx2160a_qds_mdio_read; + bus->write = lx2160a_qds_mdio_write; + bus->reset = lx2160a_qds_mdio_reset; + strcpy(bus->name, dummy_mdio_name); + bus->priv = pmdio; + + if (!mdio_register(bus)) + return bus; + + printf("No bus with name %s\n", dummy_mdio_name); + free(bus); + free(pmdio); + return NULL; +} + +static inline void do_phy_config(const struct phy_config *phy_config) +{ + struct mii_dev *bus; + int i, phy_num, phy_address; + + for (i = 0; i < SRDS_MAX_LANES; i++) { + if (!phy_config[i].dpmacid) + continue; + + for (phy_num = 0; + phy_num < ARRAY_SIZE(phy_config[i].phy_address); + phy_num++) { + phy_address = phy_config[i].phy_address[phy_num]; + if (phy_address == -1) + break; + wriop_set_phy_address(phy_config[i].dpmacid, + phy_num, phy_address); + } + /*Register the muxing front-ends to the MDIO buses*/ + bus = lx2160a_qds_mdio_init(phy_config[i].mdio_bus, + phy_config[i].ioslot); + if (!bus) + printf("could not get bus for mdio %d ioslot %d\n", + phy_config[i].mdio_bus, + phy_config[i].ioslot); + else + wriop_set_mdio(phy_config[i].dpmacid, bus); + } +} + +static inline void do_dpmac_config(int dpmac, const char *arg_dpmacid, + char *env_dpmac) +{ + const char *ret; + size_t len; + u8 realbusnum, ioslot; + struct mii_dev *bus; + int phy_num; + char *phystr = "phy00"; + + /*search phy in dpmac arg*/ + for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) { + sprintf(phystr, "phy%d", phy_num + 1); + ret = hwconfig_subarg_f(arg_dpmacid, phystr, &len, env_dpmac); + if (!ret) { + /*look for phy instead of phy1*/ + if (!phy_num) + ret = hwconfig_subarg_f(arg_dpmacid, "phy", + &len, env_dpmac); + if (!ret) + continue; + } + + if (len != 4 || strncmp(ret, "0x", 2)) + printf("invalid phy format in %s variable.\n" + "specify phy%d for %s in hex format e.g. 0x12\n", + env_dpmac, phy_num + 1, arg_dpmacid); + else + wriop_set_phy_address(dpmac, phy_num, + simple_strtoul(ret, NULL, 16)); + } + + /*search mdio in dpmac arg*/ + ret = hwconfig_subarg_f(arg_dpmacid, "mdio", &len, env_dpmac); + if (ret) + realbusnum = *ret - '0'; + else + realbusnum = EMI_NONE; + + if (realbusnum) { + /*search io in dpmac arg*/ + ret = hwconfig_subarg_f(arg_dpmacid, "io", &len, env_dpmac); + if (ret) + ioslot = *ret - '0'; + else + ioslot = IO_SLOT_NONE; + /*Register the muxing front-ends to the MDIO buses*/ + bus = lx2160a_qds_mdio_init(realbusnum, ioslot); + if (!bus) + printf("could not get bus for mdio %d ioslot %d\n", + realbusnum, ioslot); + else + wriop_set_mdio(dpmac, bus); + } +} + +#endif + +int board_eth_init(bd_t *bis) +{ +#if defined(CONFIG_FSL_MC_ENET) + struct memac_mdio_info mdio_info; + struct memac_mdio_controller *regs; + int i; + const char *ret; + char *env_dpmac; + char dpmacid[] = "dpmac00", srds[] = "00_00_00"; + size_t len; + struct mii_dev *bus; + const struct phy_config *phy_config; + struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 srds_s1, srds_s2, srds_s3; + + srds_s1 = in_le32(&gur->rcwsr[28]) & + FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK; + srds_s1 >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT; + + srds_s2 = in_le32(&gur->rcwsr[28]) & + FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK; + srds_s2 >>= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT; + + srds_s3 = in_le32(&gur->rcwsr[28]) & + FSL_CHASSIS3_RCWSR28_SRDS3_PRTCL_MASK; + srds_s3 >>= FSL_CHASSIS3_RCWSR28_SRDS3_PRTCL_SHIFT; + + sprintf(srds, "%d_%d_%d", srds_s1, srds_s2, srds_s3); + + regs = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO1; + mdio_info.regs = regs; + mdio_info.name = DEFAULT_WRIOP_MDIO1_NAME; + + /*Register the EMI 1*/ + fm_memac_mdio_init(bis, &mdio_info); + + regs = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO2; + mdio_info.regs = regs; + mdio_info.name = DEFAULT_WRIOP_MDIO2_NAME; + + /*Register the EMI 2*/ + fm_memac_mdio_init(bis, &mdio_info); + + /* "dpmac" environment variable can be used after + * defining "dpmac_override" in hwconfig environment variable. + */ + if (hwconfig("dpmac_override")) { + env_dpmac = env_get("dpmac"); + if (env_dpmac) { + ret = hwconfig_arg_f("srds", &len, env_dpmac); + if (ret) { + if (strncmp(ret, srds, strlen(srds))) { + printf("SERDES configuration changed.\n" + "previous: %.*s, current: %s.\n" + "update dpmac variable.\n", + (int)len, ret, srds); + } + } else { + printf("SERDES configuration not found.\n" + "Please add srds:%s in dpmac variable\n", + srds); + } + + for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) { + /* Look for dpmac1 to dpmac24(current max) arg + * in dpmac environment variable + */ + sprintf(dpmacid, "dpmac%d", i); + ret = hwconfig_arg_f(dpmacid, &len, env_dpmac); + if (ret) + do_dpmac_config(i, dpmacid, env_dpmac); + } + } else { + printf("Warning: environment dpmac not found.\n" + "DPAA network interfaces may not work\n"); + } + } else { + /*Look for phy config for serdes1 in phy config table*/ + phy_config = get_phy_config(srds_s1, serdes1_phy_config, + ARRAY_SIZE(serdes1_phy_config)); + if (!phy_config) { + printf("%s WRIOP: Unsupported SerDes1 Protocol %d\n", + __func__, srds_s1); + } else { + do_phy_config(phy_config); + } + phy_config = get_phy_config(srds_s2, serdes2_phy_config, + ARRAY_SIZE(serdes2_phy_config)); + if (!phy_config) { + printf("%s WRIOP: Unsupported SerDes2 Protocol %d\n", + __func__, srds_s2); + } else { + do_phy_config(phy_config); + } + phy_config = get_phy_config(srds_s3, serdes3_phy_config, + ARRAY_SIZE(serdes3_phy_config)); + if (!phy_config) { + printf("%s WRIOP: Unsupported SerDes3 Protocol %d\n", + __func__, srds_s3); + } else { + do_phy_config(phy_config); + } + } + + if (wriop_get_enet_if(WRIOP1_DPMAC17) == PHY_INTERFACE_MODE_RGMII_ID) { + wriop_set_phy_address(WRIOP1_DPMAC17, 0, RGMII_PHY_ADDR1); + bus = lx2160a_qds_mdio_init(EMI1, EMI1_RGMII1); + if (!bus) + printf("could not get bus for RGMII1\n"); + else + wriop_set_mdio(WRIOP1_DPMAC17, bus); + } + + if (wriop_get_enet_if(WRIOP1_DPMAC18) == PHY_INTERFACE_MODE_RGMII_ID) { + wriop_set_phy_address(WRIOP1_DPMAC18, 0, RGMII_PHY_ADDR2); + bus = lx2160a_qds_mdio_init(EMI1, EMI1_RGMII2); + if (!bus) + printf("could not get bus for RGMII2\n"); + else + wriop_set_mdio(WRIOP1_DPMAC18, bus); + } + + cpu_eth_init(bis); +#endif /* CONFIG_FMAN_ENET */ + +#ifdef CONFIG_PHY_AQUANTIA + /* + * Export functions to be used by AQ firmware + * upload application + */ + gd->jt->strcpy = strcpy; + gd->jt->mdelay = mdelay; + gd->jt->mdio_get_current_dev = mdio_get_current_dev; + gd->jt->phy_find_by_mask = phy_find_by_mask; + gd->jt->mdio_phydev_for_ethname = mdio_phydev_for_ethname; + gd->jt->miiphy_set_current_dev = miiphy_set_current_dev; +#endif + return pci_eth_init(bis); +} + +#if defined(CONFIG_RESET_PHY_R) +void reset_phy(void) +{ +#if defined(CONFIG_FSL_MC_ENET) + mc_env_boot(); +#endif +} +#endif /* CONFIG_RESET_PHY_R */ + +#if defined(CONFIG_FSL_MC_ENET) +int fdt_fixup_dpmac_phy_handle(void *fdt, int dpmac_id, int node_phandle) +{ + int offset; + int ret; + char dpmac_str[] = "dpmacs@00"; + const char *phy_string; + + offset = fdt_path_offset(fdt, "/soc/fsl-mc/dpmacs"); + + if (offset < 0) + offset = fdt_path_offset(fdt, "/fsl-mc/dpmacs"); + + if (offset < 0) { + printf("dpmacs node not found in device tree\n"); + return offset; + } + + sprintf(dpmac_str, "dpmac@%x", dpmac_id); + debug("dpmac_str = %s\n", dpmac_str); + + offset = fdt_subnode_offset(fdt, offset, dpmac_str); + if (offset < 0) { + printf("%s node not found in device tree\n", dpmac_str); + return offset; + } + + ret = fdt_appendprop_cell(fdt, offset, "phy-handle", node_phandle); + if (ret) + printf("%d@%s %d\n", __LINE__, __func__, ret); + + phy_string = phy_string_for_interface(wriop_get_enet_if(dpmac_id)); + ret = fdt_setprop_string(fdt, offset, "phy-connection-type", + phy_string); + if (ret) + printf("%d@%s %d\n", __LINE__, __func__, ret); + + return ret; +} + +int fdt_get_ioslot_offset(void *fdt, struct mii_dev *mii_dev, int fpga_offset) +{ + char mdio_ioslot_str[] = "mdio@00"; + char mdio_mux_str[] = "mdio-mux-0"; + struct lx2160a_qds_mdio *priv; + int offset, mux_val; + + /*Test if the MDIO bus is real mdio bus or muxing front end ?*/ + if (strncmp(mii_dev->name, "LX2160A_QDS_MDIO", + strlen("LX2160A_QDS_MDIO"))) + return -1; + + /*Get the real MDIO bus num and ioslot info from bus's priv data*/ + priv = mii_dev->priv; + + debug("real_bus_num = %d, ioslot = %d\n", + priv->realbusnum, priv->ioslot); + + sprintf(mdio_mux_str, "mdio-mux-%1d", priv->realbusnum); + offset = fdt_subnode_offset(fdt, fpga_offset, mdio_mux_str); + if (offset < 0) { + printf("%s node not found under node %s in device tree\n", + mdio_mux_str, fdt_get_name(fdt, fpga_offset, NULL)); + return offset; + } + + mux_val = lx2160a_qds_get_mdio_mux_val(priv->realbusnum, priv->ioslot); + sprintf(mdio_ioslot_str, "mdio@%x", (u8)mux_val); + + offset = fdt_subnode_offset(fdt, offset, mdio_ioslot_str); + if (offset < 0) { + printf("%s node not found in device tree\n", mdio_ioslot_str); + return offset; + } + + return offset; +} + +int fdt_create_phy_node(void *fdt, int offset, u8 phyaddr, int *subnodeoffset, + struct phy_device *phy_dev, int phandle) +{ + char phy_node_name[] = "ethernet-phy@00"; + char phy_id_compatible_str[] = "ethernet-phy-id0000.0000"; + int ret; + + sprintf(phy_node_name, "ethernet-phy@%x", phyaddr); + debug("phy_node_name = %s\n", phy_node_name); + + *subnodeoffset = fdt_add_subnode(fdt, offset, phy_node_name); + if (*subnodeoffset <= 0) { + printf("Could not add subnode %s\n", phy_node_name); + return *subnodeoffset; + } + + sprintf(phy_id_compatible_str, "ethernet-phy-id%04x.%04x", + phy_dev->phy_id >> 16, phy_dev->phy_id & 0xFFFF); + debug("phy_id_compatible_str %s\n", phy_id_compatible_str); + + ret = fdt_setprop_string(fdt, *subnodeoffset, "compatible", + phy_id_compatible_str); + if (ret) { + printf("%d@%s %d\n", __LINE__, __func__, ret); + goto out; + } + + if (phy_dev->is_c45) { + ret = fdt_appendprop_string(fdt, *subnodeoffset, "compatible", + "ethernet-phy-ieee802.3-c45"); + if (ret) { + printf("%d@%s %d\n", __LINE__, __func__, ret); + goto out; + } + } else { + ret = fdt_appendprop_string(fdt, *subnodeoffset, "compatible", + "ethernet-phy-ieee802.3-c22"); + if (ret) { + printf("%d@%s %d\n", __LINE__, __func__, ret); + goto out; + } + } + + ret = fdt_setprop_cell(fdt, *subnodeoffset, "reg", phyaddr); + if (ret) { + printf("%d@%s %d\n", __LINE__, __func__, ret); + goto out; + } + + ret = fdt_set_phandle(fdt, *subnodeoffset, phandle); + if (ret) { + printf("%d@%s %d\n", __LINE__, __func__, ret); + goto out; + } + +out: + if (ret) + fdt_del_node(fdt, *subnodeoffset); + + return ret; +} + +int fdt_fixup_board_phy(void *fdt) +{ + int fpga_offset, offset, subnodeoffset; + struct mii_dev *mii_dev; + struct list_head *mii_devs, *entry; + int ret, dpmac_id, phandle, i; + struct phy_device *phy_dev; + char ethname[ETH_NAME_LEN]; + phy_interface_t phy_iface; + + ret = 0; + /* we know FPGA is connected to i2c0, therefore search path directly, + * instead of compatible property, as it saves time + */ + fpga_offset = fdt_path_offset(fdt, "/soc/i2c@2000000/fpga"); + + if (fpga_offset < 0) + fpga_offset = fdt_path_offset(fdt, "/i2c@2000000/fpga"); + + if (fpga_offset < 0) { + printf("i2c@2000000/fpga node not found in device tree\n"); + return fpga_offset; + } + + phandle = fdt_alloc_phandle(fdt); + mii_devs = mdio_get_list_head(); + + list_for_each(entry, mii_devs) { + mii_dev = list_entry(entry, struct mii_dev, link); + debug("mii_dev name : %s\n", mii_dev->name); + offset = fdt_get_ioslot_offset(fdt, mii_dev, fpga_offset); + if (offset < 0) + continue; + + // Look for phy devices attached to MDIO bus muxing front end + // and create their entries with compatible being the device id + for (i = 0; i < PHY_MAX_ADDR; i++) { + phy_dev = mii_dev->phymap[i]; + if (!phy_dev) + continue; + + // TODO: use sscanf instead of loop + dpmac_id = WRIOP1_DPMAC1; + while (dpmac_id < NUM_WRIOP_PORTS) { + phy_iface = wriop_get_enet_if(dpmac_id); + snprintf(ethname, ETH_NAME_LEN, "DPMAC%d@%s", + dpmac_id, + phy_string_for_interface(phy_iface)); + if (strcmp(ethname, phy_dev->dev->name) == 0) + break; + dpmac_id++; + } + if (dpmac_id == NUM_WRIOP_PORTS) + continue; + + ret = fdt_create_phy_node(fdt, offset, i, + &subnodeoffset, + phy_dev, phandle); + if (ret) + break; + + ret = fdt_fixup_dpmac_phy_handle(fdt, + dpmac_id, phandle); + if (ret) { + fdt_del_node(fdt, subnodeoffset); + break; + } + phandle++; + } + + if (ret) + break; + } + + return ret; +} +#endif // CONFIG_FSL_MC_ENET + diff --git a/board/freescale/lx2160a/eth_lx2160ardb.c b/board/freescale/lx2160a/eth_lx2160ardb.c new file mode 100644 index 0000000..365ff73 --- /dev/null +++ b/board/freescale/lx2160a/eth_lx2160ardb.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static bool get_inphi_phy_id(struct mii_dev *bus, int addr, int devad) +{ + int phy_reg; + u32 phy_id; + + phy_reg = bus->read(bus, addr, devad, MII_PHYSID1); + phy_id = (phy_reg & 0xffff) << 16; + + phy_reg = bus->read(bus, addr, devad, MII_PHYSID2); + phy_id |= (phy_reg & 0xffff); + + if (phy_id == PHY_UID_IN112525_S03) + return true; + else + return false; +} + +int board_eth_init(bd_t *bis) +{ +#if defined(CONFIG_FSL_MC_ENET) + struct memac_mdio_info mdio_info; + struct memac_mdio_controller *reg; + int i, interface; + struct mii_dev *dev; + struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 srds_s1; + + srds_s1 = in_le32(&gur->rcwsr[28]) & + FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK; + srds_s1 >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT; + + reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO1; + mdio_info.regs = reg; + mdio_info.name = DEFAULT_WRIOP_MDIO1_NAME; + + /* Register the EMI 1 */ + fm_memac_mdio_init(bis, &mdio_info); + + reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO2; + mdio_info.regs = reg; + mdio_info.name = DEFAULT_WRIOP_MDIO2_NAME; + + /* Register the EMI 2 */ + fm_memac_mdio_init(bis, &mdio_info); + + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME); + switch (srds_s1) { + case 19: + wriop_set_phy_address(WRIOP1_DPMAC2, 0, + CORTINA_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC3, 0, + AQR107_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC4, 0, + AQR107_PHY_ADDR2); + if (get_inphi_phy_id(dev, INPHI_PHY_ADDR1, MDIO_MMD_VEND1)) { + wriop_set_phy_address(WRIOP1_DPMAC5, 0, + INPHI_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC6, 0, + INPHI_PHY_ADDR1); + } + wriop_set_phy_address(WRIOP1_DPMAC17, 0, + RGMII_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC18, 0, + RGMII_PHY_ADDR2); + break; + + case 18: + wriop_set_phy_address(WRIOP1_DPMAC7, 0, + CORTINA_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC8, 0, + CORTINA_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC9, 0, + CORTINA_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC10, 0, + CORTINA_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC3, 0, + AQR107_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC4, 0, + AQR107_PHY_ADDR2); + if (get_inphi_phy_id(dev, INPHI_PHY_ADDR1, MDIO_MMD_VEND1)) { + wriop_set_phy_address(WRIOP1_DPMAC5, 0, + INPHI_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC6, 0, + INPHI_PHY_ADDR1); + } + wriop_set_phy_address(WRIOP1_DPMAC17, 0, + RGMII_PHY_ADDR1); + wriop_set_phy_address(WRIOP1_DPMAC18, 0, + RGMII_PHY_ADDR2); + break; + + default: + printf("SerDes1 protocol 0x%x is not supported on LX2160ARDB\n", + srds_s1); + goto next; + } + + for (i = WRIOP1_DPMAC2; i <= WRIOP1_DPMAC10; i++) { + interface = wriop_get_enet_if(i); + switch (interface) { + case PHY_INTERFACE_MODE_XGMII: + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME); + wriop_set_mdio(i, dev); + break; + case PHY_INTERFACE_MODE_25G_AUI: + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME); + wriop_set_mdio(i, dev); + break; + case PHY_INTERFACE_MODE_XLAUI: + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME); + wriop_set_mdio(i, dev); + break; + default: + break; + } + } + for (i = WRIOP1_DPMAC17; i <= WRIOP1_DPMAC18; i++) { + interface = wriop_get_enet_if(i); + switch (interface) { + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME); + wriop_set_mdio(i, dev); + break; + default: + break; + } + } + +next: + cpu_eth_init(bis); +#endif /* CONFIG_FSL_MC_ENET */ + +#ifdef CONFIG_PHY_AQUANTIA + /* + * Export functions to be used by AQ firmware + * upload application + */ + gd->jt->strcpy = strcpy; + gd->jt->mdelay = mdelay; + gd->jt->mdio_get_current_dev = mdio_get_current_dev; + gd->jt->phy_find_by_mask = phy_find_by_mask; + gd->jt->mdio_phydev_for_ethname = mdio_phydev_for_ethname; + gd->jt->miiphy_set_current_dev = miiphy_set_current_dev; +#endif + return pci_eth_init(bis); +} + +#if defined(CONFIG_RESET_PHY_R) +void reset_phy(void) +{ +#if defined(CONFIG_FSL_MC_ENET) + mc_env_boot(); +#endif +} +#endif /* CONFIG_RESET_PHY_R */ + +int fdt_fixup_board_phy(void *fdt) +{ + int mdio_offset; + int ret; + struct mii_dev *dev; + + ret = 0; + + dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME); + if (!get_inphi_phy_id(dev, INPHI_PHY_ADDR1, MDIO_MMD_VEND1)) { + mdio_offset = fdt_path_offset(fdt, "/soc/mdio@0x8B97000"); + + if (mdio_offset < 0) + mdio_offset = fdt_path_offset(fdt, "/mdio@0x8B97000"); + + if (mdio_offset < 0) { + printf("mdio@0x8B9700 node not found in dts\n"); + return mdio_offset; + } + + ret = fdt_setprop_string(fdt, mdio_offset, "status", + "disabled"); + if (ret) { + printf("Could not set disable mdio@0x8B97000 %s\n", + fdt_strerror(ret)); + return ret; + } + } + + return ret; +} diff --git a/board/freescale/lx2160a/lx2160a.c b/board/freescale/lx2160a/lx2160a.c new file mode 100644 index 0000000..3875d04 --- /dev/null +++ b/board/freescale/lx2160a/lx2160a.c @@ -0,0 +1,574 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018-2019 NXP + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../common/qixis.h" +#include "../common/vid.h" +#include + +#ifdef CONFIG_EMC2305 +#include "../common/emc2305.h" +#endif + +#ifdef CONFIG_TARGET_LX2160AQDS +#define CFG_MUX_I2C_SDHC(reg, value) ((reg & 0x3f) | value) +#define SET_CFG_MUX1_SDHC1_SDHC(reg) (reg & 0x3f) +#define SET_CFG_MUX2_SDHC1_SPI(reg, value) ((reg & 0xcf) | value) +#define SET_CFG_MUX3_SDHC1_SPI(reg, value) ((reg & 0xf8) | value) +#define SET_CFG_MUX_SDHC2_DSPI(reg, value) ((reg & 0xf8) | value) +#define SET_CFG_MUX1_SDHC1_DSPI(reg, value) ((reg & 0x3f) | value) +#define SDHC1_BASE_PMUX_DSPI 2 +#define SDHC2_BASE_PMUX_DSPI 2 +#define IIC5_PMUX_SPI3 3 +#endif /* CONFIG_TARGET_LX2160AQDS */ + +DECLARE_GLOBAL_DATA_PTR; + +static struct pl01x_serial_platdata serial0 = { +#if CONFIG_CONS_INDEX == 0 + .base = CONFIG_SYS_SERIAL0, +#elif CONFIG_CONS_INDEX == 1 + .base = CONFIG_SYS_SERIAL1, +#else +#error "Unsupported console index value." +#endif + .type = TYPE_PL011, +}; + +U_BOOT_DEVICE(nxp_serial0) = { + .name = "serial_pl01x", + .platdata = &serial0, +}; + +static struct pl01x_serial_platdata serial1 = { + .base = CONFIG_SYS_SERIAL1, + .type = TYPE_PL011, +}; + +U_BOOT_DEVICE(nxp_serial1) = { + .name = "serial_pl01x", + .platdata = &serial1, +}; + +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; +} + +static void uart_get_clock(void) +{ + serial0.clock = get_serial_clock(); + serial1.clock = get_serial_clock(); +} + +int board_early_init_f(void) +{ +#ifdef CONFIG_SYS_I2C_EARLY_INIT + i2c_early_init_f(); +#endif + /* get required clock for UART IP */ + uart_get_clock(); + +#ifdef CONFIG_EMC2305 + select_i2c_ch_pca9547(I2C_MUX_CH_EMC2305); + emc2305_init(); + set_fan_speed(I2C_EMC2305_PWM); + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); +#endif + + fsl_lsch3_early_init_f(); + return 0; +} + +#if defined(CONFIG_TARGET_LX2160AQDS) +void esdhc_dspi_status_fixup(void *blob) +{ + const char esdhc0_path[] = "/soc/esdhc@2140000"; + const char esdhc1_path[] = "/soc/esdhc@2150000"; + const char dspi0_path[] = "/soc/dspi@2100000"; + const char dspi1_path[] = "/soc/dspi@2110000"; + const char dspi2_path[] = "/soc/dspi@2120000"; + + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 sdhc1_base_pmux; + u32 sdhc2_base_pmux; + u32 iic5_pmux; + + /* Check RCW field sdhc1_base_pmux to enable/disable + * esdhc0/dspi0 DT node + */ + sdhc1_base_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR12_REGSR - 1]) + & FSL_CHASSIS3_SDHC1_BASE_PMUX_MASK; + sdhc1_base_pmux >>= FSL_CHASSIS3_SDHC1_BASE_PMUX_SHIFT; + + if (sdhc1_base_pmux == SDHC1_BASE_PMUX_DSPI) { + do_fixup_by_path(blob, dspi0_path, "status", "okay", + sizeof("okay"), 1); + do_fixup_by_path(blob, esdhc0_path, "status", "disabled", + sizeof("disabled"), 1); + } else { + do_fixup_by_path(blob, esdhc0_path, "status", "okay", + sizeof("okay"), 1); + do_fixup_by_path(blob, dspi0_path, "status", "disabled", + sizeof("disabled"), 1); + } + + /* Check RCW field sdhc2_base_pmux to enable/disable + * esdhc1/dspi1 DT node + */ + sdhc2_base_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR13_REGSR - 1]) + & FSL_CHASSIS3_SDHC2_BASE_PMUX_MASK; + sdhc2_base_pmux >>= FSL_CHASSIS3_SDHC2_BASE_PMUX_SHIFT; + + if (sdhc2_base_pmux == SDHC2_BASE_PMUX_DSPI) { + do_fixup_by_path(blob, dspi1_path, "status", "okay", + sizeof("okay"), 1); + do_fixup_by_path(blob, esdhc1_path, "status", "disabled", + sizeof("disabled"), 1); + } else { + do_fixup_by_path(blob, esdhc1_path, "status", "okay", + sizeof("okay"), 1); + do_fixup_by_path(blob, dspi1_path, "status", "disabled", + sizeof("disabled"), 1); + } + + /* Check RCW field IIC5 to enable dspi2 DT node */ + iic5_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR12_REGSR - 1]) + & FSL_CHASSIS3_IIC5_PMUX_MASK; + iic5_pmux >>= FSL_CHASSIS3_IIC5_PMUX_SHIFT; + + if (iic5_pmux == IIC5_PMUX_SPI3) { + do_fixup_by_path(blob, dspi2_path, "status", "okay", + sizeof("okay"), 1); + } +} +#endif + +int esdhc_status_fixup(void *blob, const char *compat) +{ +#if defined(CONFIG_TARGET_LX2160AQDS) + /* Enable esdhc and dspi DT nodes based on RCW fields */ + esdhc_dspi_status_fixup(blob); +#else + /* Enable both esdhc DT nodes for LX2160ARDB */ + do_fixup_by_compat(blob, compat, "status", "okay", + sizeof("okay"), 1); +#endif + return 0; +} + +#if defined(CONFIG_VID) +int i2c_multiplexer_select_vid_channel(u8 channel) +{ + return select_i2c_ch_pca9547(channel); +} + +int init_func_vid(void) +{ + if (adjust_vdd(0) < 0) + printf("core voltage not adjusted\n"); + + return 0; +} +#endif + +int checkboard(void) +{ + enum boot_src src = get_boot_src(); + char buf[64]; + u8 sw; +#ifdef CONFIG_TARGET_LX2160AQDS + int clock; + static const char *const freq[] = {"100", "125", "156.25", + "161.13", "322.26", "", "", "", + "", "", "", "", "", "", "", + "100 separate SSCG"}; +#endif + + cpu_name(buf); +#ifdef CONFIG_TARGET_LX2160AQDS + printf("Board: %s-QDS, ", buf); +#else + printf("Board: %s-RDB, ", buf); +#endif + + sw = QIXIS_READ(arch); + printf("Board version: %c, boot from ", (sw & 0xf) - 1 + 'A'); + + if (src == BOOT_SOURCE_SD_MMC) { + puts("SD\n"); + } else { + sw = QIXIS_READ(brdcfg[0]); + sw = (sw >> QIXIS_XMAP_SHIFT) & QIXIS_XMAP_MASK; + switch (sw) { + case 0: + case 4: + puts("FlexSPI DEV#0\n"); + break; + case 1: + puts("FlexSPI DEV#1\n"); + break; + case 2: + case 3: + puts("FlexSPI EMU\n"); + break; + default: + printf("invalid setting, xmap: %d\n", sw); + break; + } + } +#ifdef CONFIG_TARGET_LX2160AQDS + 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)); + + puts("SERDES1 Reference : "); + sw = QIXIS_READ(brdcfg[2]); + clock = sw >> 4; + printf("Clock1 = %sMHz ", freq[clock]); + clock = sw & 0x0f; + printf("Clock2 = %sMHz", freq[clock]); + + sw = QIXIS_READ(brdcfg[3]); + puts("\nSERDES2 Reference : "); + clock = sw >> 4; + printf("Clock1 = %sMHz ", freq[clock]); + clock = sw & 0x0f; + printf("Clock2 = %sMHz", freq[clock]); + + sw = QIXIS_READ(brdcfg[12]); + puts("\nSERDES3 Reference : "); + clock = sw >> 4; + printf("Clock1 = %sMHz Clock2 = %sMHz\n", freq[clock], freq[clock]); +#else + printf("FPGA: v%d.%d\n", QIXIS_READ(scver), QIXIS_READ(tagdata)); + + puts("SERDES1 Reference: Clock1 = 161.13MHz Clock2 = 161.13MHz\n"); + puts("SERDES2 Reference: Clock1 = 100MHz Clock2 = 100MHz\n"); + puts("SERDES3 Reference: Clock1 = 100MHz Clock2 = 100Hz\n"); +#endif + return 0; +} + +#ifdef CONFIG_TARGET_LX2160AQDS +/* + * implementation of CONFIG_ESDHC_DETECT_QUIRK Macro. + */ +u8 qixis_esdhc_detect_quirk(void) +{ + /* for LX2160AQDS res1[1] @ offset 0x1A is SDHC1 Control/Status (SDHC1) + * SDHC1 Card ID: + * Specifies the type of card installed in the SDHC1 adapter slot. + * 000= (reserved) + * 001= eMMC V4.5 adapter is installed. + * 010= SD/MMC 3.3V adapter is installed. + * 011= eMMC V4.4 adapter is installed. + * 100= eMMC V5.0 adapter is installed. + * 101= MMC card/Legacy (3.3V) adapter is installed. + * 110= SDCard V2/V3 adapter installed. + * 111= no adapter is installed. + */ + return ((QIXIS_READ(res1[1]) & QIXIS_SDID_MASK) != + QIXIS_ESDHC_NO_ADAPTER); +} + +int config_board_mux(void) +{ + u8 reg11, reg5, reg13; + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 sdhc1_base_pmux; + u32 sdhc2_base_pmux; + u32 iic5_pmux; + + /* Routes {I2C2_SCL, I2C2_SDA} to SDHC1 as {SDHC1_CD_B, SDHC1_WP}. + * Routes {I2C3_SCL, I2C3_SDA} to CAN transceiver as {CAN1_TX,CAN1_RX}. + * Routes {I2C4_SCL, I2C4_SDA} to CAN transceiver as {CAN2_TX,CAN2_RX}. + * Qixis and remote systems are isolated from the I2C1 bus. + * Processor connections are still available. + * SPI2 CS2_B controls EN25S64 SPI memory device. + * SPI3 CS2_B controls EN25S64 SPI memory device. + * EC2 connects to PHY #2 using RGMII protocol. + * CLK_OUT connects to FPGA for clock measurement. + */ + + reg5 = QIXIS_READ(brdcfg[5]); + reg5 = CFG_MUX_I2C_SDHC(reg5, 0x40); + QIXIS_WRITE(brdcfg[5], reg5); + + /* Check RCW field sdhc1_base_pmux + * esdhc0 : sdhc1_base_pmux = 0 + * dspi0 : sdhc1_base_pmux = 2 + */ + sdhc1_base_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR12_REGSR - 1]) + & FSL_CHASSIS3_SDHC1_BASE_PMUX_MASK; + sdhc1_base_pmux >>= FSL_CHASSIS3_SDHC1_BASE_PMUX_SHIFT; + + if (sdhc1_base_pmux == SDHC1_BASE_PMUX_DSPI) { + reg11 = QIXIS_READ(brdcfg[11]); + reg11 = SET_CFG_MUX1_SDHC1_DSPI(reg11, 0x40); + QIXIS_WRITE(brdcfg[11], reg11); + } else { + /* - Routes {SDHC1_CMD, SDHC1_CLK } to SDHC1 adapter slot. + * {SDHC1_DAT3, SDHC1_DAT2} to SDHC1 adapter slot. + * {SDHC1_DAT1, SDHC1_DAT0} to SDHC1 adapter slot. + */ + reg11 = QIXIS_READ(brdcfg[11]); + reg11 = SET_CFG_MUX1_SDHC1_SDHC(reg11); + QIXIS_WRITE(brdcfg[11], reg11); + } + + /* Check RCW field sdhc2_base_pmux + * esdhc1 : sdhc2_base_pmux = 0 (default) + * dspi1 : sdhc2_base_pmux = 2 + */ + sdhc2_base_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR13_REGSR - 1]) + & FSL_CHASSIS3_SDHC2_BASE_PMUX_MASK; + sdhc2_base_pmux >>= FSL_CHASSIS3_SDHC2_BASE_PMUX_SHIFT; + + if (sdhc2_base_pmux == SDHC2_BASE_PMUX_DSPI) { + reg13 = QIXIS_READ(brdcfg[13]); + reg13 = SET_CFG_MUX_SDHC2_DSPI(reg13, 0x01); + QIXIS_WRITE(brdcfg[13], reg13); + } else { + reg13 = QIXIS_READ(brdcfg[13]); + reg13 = SET_CFG_MUX_SDHC2_DSPI(reg13, 0x00); + QIXIS_WRITE(brdcfg[13], reg13); + } + + /* Check RCW field IIC5 to enable dspi2 DT nodei + * dspi2: IIC5 = 3 + */ + iic5_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR12_REGSR - 1]) + & FSL_CHASSIS3_IIC5_PMUX_MASK; + iic5_pmux >>= FSL_CHASSIS3_IIC5_PMUX_SHIFT; + + if (iic5_pmux == IIC5_PMUX_SPI3) { + /* - Routes {SDHC1_DAT4} to SPI3 devices as {SPI3_M_CS0_B}. */ + reg11 = QIXIS_READ(brdcfg[11]); + reg11 = SET_CFG_MUX2_SDHC1_SPI(reg11, 0x10); + QIXIS_WRITE(brdcfg[11], reg11); + + /* - Routes {SDHC1_DAT5, SDHC1_DAT6} nowhere. + * {SDHC1_DAT7, SDHC1_DS } to {nothing, SPI3_M0_CLK }. + * {I2C5_SCL, I2C5_SDA } to {SPI3_M0_MOSI, SPI3_M0_MISO}. + */ + reg11 = QIXIS_READ(brdcfg[11]); + reg11 = SET_CFG_MUX3_SDHC1_SPI(reg11, 0x01); + QIXIS_WRITE(brdcfg[11], reg11); + } else { + /* Routes {SDHC1_DAT4} to SDHC1 adapter slot */ + reg11 = QIXIS_READ(brdcfg[11]); + reg11 = SET_CFG_MUX2_SDHC1_SPI(reg11, 0x00); + QIXIS_WRITE(brdcfg[11], reg11); + + /* - Routes {SDHC1_DAT5, SDHC1_DAT6} to SDHC1 adapter slot. + * {SDHC1_DAT7, SDHC1_DS } to SDHC1 adapter slot. + * {I2C5_SCL, I2C5_SDA } to SDHC1 adapter slot. + */ + reg11 = QIXIS_READ(brdcfg[11]); + reg11 = SET_CFG_MUX3_SDHC1_SPI(reg11, 0x00); + QIXIS_WRITE(brdcfg[11], reg11); + } + + return 0; +} +#else +int config_board_mux(void) +{ + return 0; +} +#endif + +unsigned long get_board_sys_clk(void) +{ +#ifdef CONFIG_TARGET_LX2160AQDS + u8 sysclk_conf = QIXIS_READ(brdcfg[1]); + + switch (sysclk_conf & 0x03) { + case QIXIS_SYSCLK_100: + return 100000000; + case QIXIS_SYSCLK_125: + return 125000000; + case QIXIS_SYSCLK_133: + return 133333333; + } + return 100000000; +#else + return 100000000; +#endif +} + +unsigned long get_board_ddr_clk(void) +{ +#ifdef CONFIG_TARGET_LX2160AQDS + 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 100000000; +#else + return 100000000; +#endif +} + +int board_init(void) +{ +#ifdef CONFIG_ENV_IS_NOWHERE + gd->env_addr = (ulong)&default_environment[0]; +#endif + + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); + +#ifdef CONFIG_FSL_CAAM + sec_init(); +#endif + + return 0; +} + +void detail_board_ddr_info(void) +{ + int i; + u64 ddr_size = 0; + + puts("\nDDR "); + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) + ddr_size += gd->bd->bi_dram[i].size; + print_size(ddr_size, ""); + print_ddr_info(0); +} + +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + config_board_mux(); + + return 0; +} +#endif + +#ifdef CONFIG_FSL_MC_ENET +extern int fdt_fixup_board_phy(void *fdt); + +void fdt_fixup_board_enet(void *fdt) +{ + int offset; + + offset = fdt_path_offset(fdt, "/soc/fsl-mc"); + + if (offset < 0) + offset = fdt_path_offset(fdt, "/fsl-mc"); + + if (offset < 0) { + printf("%s: fsl-mc node not found in device tree (error %d)\n", + __func__, offset); + return; + } + + if ((get_mc_boot_status() == 0) && (get_dpl_apply_status() == 0)) { + fdt_status_okay(fdt, offset); + fdt_fixup_board_phy(fdt); + } else { + fdt_status_fail(fdt, offset); + } +} + +void board_quiesce_devices(void) +{ + fsl_mc_ldpaa_exit(gd->bd); +} +#endif + +#ifdef CONFIG_OF_BOARD_SETUP + +int ft_board_setup(void *blob, bd_t *bd) +{ + int i; + u64 base[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; + + ft_cpu_setup(blob, bd); + + /* fixup DT for the three GPP DDR banks */ + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + base[i] = gd->bd->bi_dram[i].start; + size[i] = gd->bd->bi_dram[i].size; + } + +#ifdef CONFIG_RESV_RAM + /* reduce size if reserved memory is within this bank */ + if (gd->arch.resv_ram >= base[0] && + gd->arch.resv_ram < base[0] + size[0]) + size[0] = gd->arch.resv_ram - base[0]; + else if (gd->arch.resv_ram >= base[1] && + gd->arch.resv_ram < base[1] + size[1]) + size[1] = gd->arch.resv_ram - base[1]; + else if (gd->arch.resv_ram >= base[2] && + gd->arch.resv_ram < base[2] + size[2]) + size[2] = gd->arch.resv_ram - base[2]; +#endif + + fdt_fixup_memory_banks(blob, base, size, CONFIG_NR_DRAM_BANKS); + +#ifdef CONFIG_USB + fsl_fdt_fixup_dr_usb(blob, bd); +#endif + +#ifdef CONFIG_FSL_MC_ENET + fdt_fsl_mc_fixup_iommu_map_entry(blob); + fdt_fixup_board_enet(blob); +#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/logicpd/omap3som/omap3logic.c b/board/logicpd/omap3som/omap3logic.c index 144e6f6..ee77ce0 100644 --- a/board/logicpd/omap3som/omap3logic.c +++ b/board/logicpd/omap3som/omap3logic.c @@ -56,36 +56,6 @@ DECLARE_GLOBAL_DATA_PTR; #define LOGIC_MT28_OMAP35_ASYNC_GPMC_CONFIG6 0x09030000 #define LOGIC_MT28_OMAP35_ASYNC_GPMC_CONFIG7 0x00000C50 -/* This is only needed until SPL gets OF support */ -#ifdef CONFIG_SPL_BUILD -static const struct ns16550_platdata omap3logic_serial = { - .base = OMAP34XX_UART1, - .reg_shift = 2, - .clock = V_NS16550_CLK, - .fcr = UART_FCR_DEFVAL, -}; - -U_BOOT_DEVICE(omap3logic_uart) = { - "omap_serial", - &omap3logic_serial -}; - -static const struct omap_hsmmc_plat omap3_logic_mmc0_platdata = { - .base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE, - .cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_4BIT, - .cfg.f_min = 400000, - .cfg.f_max = 52000000, - .cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195, - .cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, -}; - -U_BOOT_DEVICE(omap3_logic_mmc0) = { - .name = "omap_hsmmc", - .platdata = &omap3_logic_mmc0_platdata, -}; - -#endif - #ifdef CONFIG_SPL_OS_BOOT int spl_start_uboot(void) { diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig new file mode 100644 index 0000000..6be3d88 --- /dev/null +++ b/board/sifive/fu540/Kconfig @@ -0,0 +1,42 @@ +if TARGET_SIFIVE_FU540 + +config SYS_BOARD + default "fu540" + +config SYS_VENDOR + default "sifive" + +config SYS_CPU + default "generic" + +config SYS_CONFIG_NAME + default "sifive-fu540" + +config SYS_TEXT_BASE + default 0x80000000 if !RISCV_SMODE + default 0x80200000 if RISCV_SMODE + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select GENERIC_RISCV + imply CMD_DHCP + imply CMD_EXT2 + imply CMD_EXT4 + imply CMD_FAT + imply CMD_FS_GENERIC + imply CMD_NET + imply CMD_PING + imply CLK_SIFIVE + imply CLK_SIFIVE_FU540_PRCI + imply DOS_PARTITION + imply EFI_PARTITION + imply IP_DYN + imply ISO_PARTITION + imply MACB + imply MII + imply NET_RANDOM_ETHADDR + imply PHY_LIB + imply PHY_MSCC + imply SIFIVE_SERIAL + +endif diff --git a/board/sifive/fu540/MAINTAINERS b/board/sifive/fu540/MAINTAINERS new file mode 100644 index 0000000..702d803 --- /dev/null +++ b/board/sifive/fu540/MAINTAINERS @@ -0,0 +1,9 @@ +SiFive FU540 BOARD +M: Paul Walmsley +M: Palmer Dabbelt +M: Anup Patel +M: Atish Patra +S: Maintained +F: board/sifive/fu540/ +F: include/configs/sifive-fu540.h +F: configs/sifive_fu540_defconfig diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile new file mode 100644 index 0000000..6e1862c --- /dev/null +++ b/board/sifive/fu540/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2019 Western Digital Corporation or its affiliates. + +obj-y += fu540.o diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c new file mode 100644 index 0000000..5adc4a3 --- /dev/null +++ b/board/sifive/fu540/fu540.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2019 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel + */ + +#include +#include + +int board_init(void) +{ + /* For now nothing to do here. */ + + return 0; +} diff --git a/board/ti/beagle/beagle.c b/board/ti/beagle/beagle.c index 826aace..91e0a4c 100644 --- a/board/ti/beagle/beagle.c +++ b/board/ti/beagle/beagle.c @@ -71,18 +71,6 @@ static struct { char env_setting[64]; } expansion_config; -static const struct ns16550_platdata beagle_serial = { - .base = OMAP34XX_UART3, - .reg_shift = 2, - .clock = V_NS16550_CLK, - .fcr = UART_FCR_DEFVAL, -}; - -U_BOOT_DEVICE(beagle_uart) = { - "ns16550_serial", - &beagle_serial -}; - /* * Routine: board_init * Description: Early hardware init. diff --git a/board/ti/evm/evm.c b/board/ti/evm/evm.c index c59aff5..daecb4a 100644 --- a/board/ti/evm/evm.c +++ b/board/ti/evm/evm.c @@ -40,18 +40,6 @@ DECLARE_GLOBAL_DATA_PTR; -static const struct ns16550_platdata omap3_evm_serial = { - .base = OMAP34XX_UART1, - .reg_shift = 2, - .clock = V_NS16550_CLK, - .fcr = UART_FCR_DEFVAL, -}; - -U_BOOT_DEVICE(omap3_evm_uart) = { - "ns16550_serial", - &omap3_evm_serial -}; - static u32 omap3_evm_version; u32 get_omap3_evm_rev(void) diff --git a/board/toradex/apalis-tk1/apalis-tk1.c b/board/toradex/apalis-tk1/apalis-tk1.c index d6a736d..b87e9e7 100644 --- a/board/toradex/apalis-tk1/apalis-tk1.c +++ b/board/toradex/apalis-tk1/apalis-tk1.c @@ -240,3 +240,12 @@ void tegra_pcie_board_port_reset(struct tegra_pcie_port *port) } } #endif /* CONFIG_PCI_TEGRA */ + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_request(TEGRA_GPIO(BB, 5), "BL_ON"); + gpio_direction_output(TEGRA_GPIO(BB, 5), 0); +} diff --git a/board/toradex/apalis_imx6/apalis_imx6.c b/board/toradex/apalis_imx6/apalis_imx6.c index 368db9c..d11207c 100644 --- a/board/toradex/apalis_imx6/apalis_imx6.c +++ b/board/toradex/apalis_imx6/apalis_imx6.c @@ -745,6 +745,15 @@ static void setup_display(void) gpio_direction_output(RGB_BACKLIGHTPWM_OE, 0); gpio_direction_output(RGB_BACKLIGHT_GP, 1); } + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_direction_output(RGB_BACKLIGHTPWM_GP, 1); + gpio_direction_output(RGB_BACKLIGHT_GP, 0); +} #endif /* defined(CONFIG_VIDEO_IPUV3) */ int board_early_init_f(void) diff --git a/board/toradex/apalis_t30/apalis_t30.c b/board/toradex/apalis_t30/apalis_t30.c index ace9c5b..df9bc8e 100644 --- a/board/toradex/apalis_t30/apalis_t30.c +++ b/board/toradex/apalis_t30/apalis_t30.c @@ -164,3 +164,12 @@ void tegra_pcie_board_port_reset(struct tegra_pcie_port *port) #endif /* CONFIG_APALIS_T30_PCIE_EVALBOARD_INIT */ } #endif /* CONFIG_PCI_TEGRA */ + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_request(TEGRA_GPIO(V, 2), "BKL1_ON"); + gpio_direction_output(TEGRA_GPIO(V, 2), 0); +} diff --git a/board/toradex/colibri_imx6/colibri_imx6.c b/board/toradex/colibri_imx6/colibri_imx6.c index 68c0c02..17876f2 100644 --- a/board/toradex/colibri_imx6/colibri_imx6.c +++ b/board/toradex/colibri_imx6/colibri_imx6.c @@ -622,6 +622,15 @@ static void setup_display(void) gpio_direction_output(RGB_BACKLIGHTPWM_GP, 0); gpio_direction_output(RGB_BACKLIGHT_GP, 1); } + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_direction_output(RGB_BACKLIGHTPWM_GP, 1); + gpio_direction_output(RGB_BACKLIGHT_GP, 0); +} #endif /* defined(CONFIG_VIDEO_IPUV3) */ int board_early_init_f(void) diff --git a/board/toradex/colibri_imx7/colibri_imx7.c b/board/toradex/colibri_imx7/colibri_imx7.c index 392fda9..61bf8bf 100644 --- a/board/toradex/colibri_imx7/colibri_imx7.c +++ b/board/toradex/colibri_imx7/colibri_imx7.c @@ -150,6 +150,15 @@ static int setup_lcd(void) } #endif +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_direction_output(GPIO_PWM_A, 1); + gpio_direction_output(GPIO_BL_ON, 0); +} + #ifdef CONFIG_FEC_MXC static iomux_v3_cfg_t const fec1_pads[] = { #ifndef CONFIG_COLIBRI_IMX7_EXT_PHYCLK diff --git a/board/toradex/colibri_t20/colibri_t20.c b/board/toradex/colibri_t20/colibri_t20.c index 5dd0f28..e0b27e9 100644 --- a/board/toradex/colibri_t20/colibri_t20.c +++ b/board/toradex/colibri_t20/colibri_t20.c @@ -150,4 +150,13 @@ void pin_mux_display(void) pinmux_set_func(PMUX_PINGRP_SDC, PMUX_FUNC_PWM); pinmux_tristate_disable(PMUX_PINGRP_SDC); } + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_request(TEGRA_GPIO(T, 4), "BL_ON"); + gpio_direction_output(TEGRA_GPIO(T, 4), 0); +} #endif diff --git a/board/toradex/colibri_t30/colibri_t30.c b/board/toradex/colibri_t30/colibri_t30.c index 8ea9618..b6b00e3 100644 --- a/board/toradex/colibri_t30/colibri_t30.c +++ b/board/toradex/colibri_t30/colibri_t30.c @@ -66,3 +66,12 @@ void pin_mux_usb(void) udelay(5); gpio_set_value(TEGRA_GPIO(DD, 0), 1); } + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_request(TEGRA_GPIO(V, 2), "BL_ON"); + gpio_direction_output(TEGRA_GPIO(V, 2), 0); +} diff --git a/board/toradex/colibri_vf/colibri_vf.c b/board/toradex/colibri_vf/colibri_vf.c index 19cf748..79f702f 100644 --- a/board/toradex/colibri_vf/colibri_vf.c +++ b/board/toradex/colibri_vf/colibri_vf.c @@ -38,8 +38,9 @@ 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) -#define USB_PEN_GPIO 83 +#define USB_PEN_GPIO 83 #define USB_CDET_GPIO 102 +#define PTC0_GPIO_45 45 static struct ddrmc_cr_setting colibri_vf_cr_settings[] = { /* AXI */ @@ -632,3 +633,12 @@ int board_usb_phy_mode(int port) } } #endif + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_request(PTC0_GPIO_45, "BL_ON"); + gpio_direction_output(PTC0_GPIO_45, 0); +} diff --git a/cmd/Kconfig b/cmd/Kconfig index 3ea42e4..4bcc5c4 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -420,6 +420,16 @@ config CMD_ENV_FLAGS be deleted. This command shows the variables that have special flags. +config CMD_NVEDIT_EFI + bool "env [set|print] -e - set/print UEFI variables" + depends on EFI_LOADER + default y + imply HEXDUMP + help + UEFI variables are encoded as some form of U-Boot variables. + If enabled, we are allowed to set/print UEFI variables using + "env" command with "-e" option without knowing details. + endmenu menu "Memory commands" @@ -1397,8 +1407,19 @@ config CMD_DISPLAY displayed on a simple board-specific display. Implement display_putc() to use it. +config CMD_EFIDEBUG + bool "efidebug - display/configure UEFI environment" + depends on EFI_LOADER + default n + help + Enable the 'efidebug' command which provides a subset of UEFI + shell utility with simplified functionality. It will be useful + particularly for managing boot parameters as well as examining + various EFI status for debugging. + config CMD_LED bool "led" + depends on LED default y if LED help Enable the 'led' command which allows for control of LEDs supported diff --git a/cmd/Makefile b/cmd/Makefile index 15ae4d2..acb85f4 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_CMD_ECHO) += echo.o obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o obj-$(CONFIG_CMD_EEPROM) += eeprom.o obj-$(CONFIG_EFI_STUB) += efi.o +obj-$(CONFIG_CMD_EFIDEBUG) += efidebug.o obj-$(CONFIG_CMD_ELF) += elf.o obj-$(CONFIG_HUSH_PARSER) += exit.o obj-$(CONFIG_CMD_EXT4) += ext4.o @@ -98,13 +99,14 @@ obj-$(CONFIG_CMD_MTD) += mtd.o obj-$(CONFIG_CMD_MTDPARTS) += mtdparts.o obj-$(CONFIG_CMD_NAND) += nand.o obj-$(CONFIG_CMD_NET) += net.o +obj-$(CONFIG_CMD_NVEDIT_EFI) += nvedit_efi.o obj-$(CONFIG_CMD_ONENAND) += onenand.o obj-$(CONFIG_CMD_OSD) += osd.o obj-$(CONFIG_CMD_PART) += part.o ifdef CONFIG_PCI obj-$(CONFIG_CMD_PCI) += pci.o endif -obj-y += pcmcia.o +obj-$(CONFIG_CMD_PCMCIA) += pcmcia.o obj-$(CONFIG_CMD_PINMUX) += pinmux.o obj-$(CONFIG_CMD_PXE) += pxe.o obj-$(CONFIG_CMD_WOL) += wol.o diff --git a/cmd/bootefi.c b/cmd/bootefi.c index ee685d8..3619a20 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -133,20 +133,6 @@ done: return ret; } -static efi_status_t efi_do_enter( - efi_handle_t image_handle, struct efi_system_table *st, - EFIAPI efi_status_t (*entry)( - efi_handle_t image_handle, - struct efi_system_table *st)) -{ - efi_status_t ret = EFI_LOAD_ERROR; - - if (entry) - ret = entry(image_handle, st); - st->boottime->exit(image_handle, ret, 0, NULL); - return ret; -} - /* * efi_carve_out_dt_rsv() - Carve out DT reserved memory ranges * @@ -266,9 +252,6 @@ static efi_status_t do_bootefi_exec(void *efi, struct efi_loaded_image_obj *image_obj = NULL; struct efi_loaded_image *loaded_image_info = NULL; - EFIAPI efi_status_t (*entry)(efi_handle_t image_handle, - struct efi_system_table *st); - /* * Special case for efi payload not loaded from disk, such as * 'bootefi hello' or for example payload loaded directly into @@ -300,11 +283,9 @@ static efi_status_t do_bootefi_exec(void *efi, goto err_prepare; /* Load the EFI payload */ - entry = efi_load_pe(image_obj, efi, loaded_image_info); - if (!entry) { - ret = EFI_LOAD_ERROR; + ret = efi_load_pe(image_obj, efi, loaded_image_info); + if (ret != EFI_SUCCESS) goto err_prepare; - } if (memdp) { struct efi_device_path_memory *mdp = (void *)memdp; @@ -319,14 +300,8 @@ static efi_status_t do_bootefi_exec(void *efi, "{ro,boot}(blob)0000000000000000"); /* Call our payload! */ - debug("%s: Jumping to 0x%p\n", __func__, entry); - - if (setjmp(&image_obj->exit_jmp)) { - ret = image_obj->exit_status; - goto err_prepare; - } - - ret = efi_do_enter(&image_obj->header, &systab, entry); + debug("%s: Jumping to 0x%p\n", __func__, image_obj->entry); + ret = EFI_CALL(efi_start_image(&image_obj->header, NULL, NULL)); err_prepare: /* image has returned, loaded-image obj goes *poof*: */ @@ -343,38 +318,46 @@ err_add_protocol: /** * bootefi_test_prepare() - prepare to run an EFI test * - * This sets things up so we can call EFI functions. This involves preparing - * the 'gd' pointer and setting up the load ed image data structures. + * Prepare to run a test as if it were provided by a loaded image. * - * @image_objp: loaded_image_infop: Pointer to a struct which will hold the - * loaded image object. This struct will be inited by this function before - * use. - * @loaded_image_infop: Pointer to a struct which will hold the loaded image - * info. This struct will be inited by this function before use. - * @path: File path to the test being run (often just the test name with a - * backslash before it - * @test_func: Address of the test function that is being run - * @load_options_path: U-Boot environment variable to use as load options - * @return 0 if OK, -ve on error + * @image_objp: pointer to be set to the loaded image handle + * @loaded_image_infop: pointer to be set to the loaded image protocol + * @path: dummy file path used to construct the device path + * set in the loaded image protocol + * @load_options_path: name of a U-Boot environment variable. Its value is + * set as load options in the loaded image protocol. + * Return: status code */ static efi_status_t bootefi_test_prepare (struct efi_loaded_image_obj **image_objp, - struct efi_loaded_image **loaded_image_infop, const char *path, - ulong test_func, const char *load_options_path) + struct efi_loaded_image **loaded_image_infop, const char *path, + const char *load_options_path) { + efi_status_t ret; + /* Construct a dummy device path */ - bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, - (uintptr_t)test_func, - (uintptr_t)test_func); + bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, 0, 0); if (!bootefi_device_path) return EFI_OUT_OF_RESOURCES; + bootefi_image_path = efi_dp_from_file(NULL, 0, path); - if (!bootefi_image_path) - return EFI_OUT_OF_RESOURCES; + if (!bootefi_image_path) { + ret = EFI_OUT_OF_RESOURCES; + goto failure; + } - return bootefi_run_prepare(load_options_path, bootefi_device_path, - bootefi_image_path, image_objp, - loaded_image_infop); + ret = bootefi_run_prepare(load_options_path, bootefi_device_path, + bootefi_image_path, image_objp, + loaded_image_infop); + if (ret == EFI_SUCCESS) + return ret; + + efi_free_pool(bootefi_image_path); + bootefi_image_path = NULL; +failure: + efi_free_pool(bootefi_device_path); + bootefi_device_path = NULL; + return ret; } #endif /* CONFIG_CMD_BOOTEFI_SELFTEST */ @@ -456,13 +439,13 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) struct efi_loaded_image_obj *image_obj; struct efi_loaded_image *loaded_image_info; - if (bootefi_test_prepare(&image_obj, &loaded_image_info, - "\\selftest", (uintptr_t)&efi_selftest, - "efi_selftest")) + r = bootefi_test_prepare(&image_obj, &loaded_image_info, + "\\selftest", "efi_selftest"); + if (r != EFI_SUCCESS) return CMD_RET_FAILURE; /* Execute the test */ - r = efi_selftest(&image_obj->header, &systab); + r = EFI_CALL(efi_selftest(&image_obj->header, &systab)); bootefi_run_finish(image_obj, loaded_image_info); return r != EFI_SUCCESS; } else diff --git a/cmd/date.c b/cmd/date.c index 1115b6c..7fa950a 100644 --- a/cmd/date.c +++ b/cmd/date.c @@ -159,18 +159,18 @@ int mk_date (const char *datestr, struct rtc_time *tmp) int len, val; char *ptr; - ptr = strchr (datestr,'.'); - len = strlen (datestr); + ptr = strchr(datestr, '.'); + len = strlen(datestr); /* Set seconds */ if (ptr) { int sec; - *ptr++ = '\0'; + ptr++; if ((len - (ptr - datestr)) != 2) return (-1); - len = strlen (datestr); + len -= 3; if (cnvrt2 (ptr, &sec)) return (-1); diff --git a/cmd/efidebug.c b/cmd/efidebug.c new file mode 100644 index 0000000..5072a7b --- /dev/null +++ b/cmd/efidebug.c @@ -0,0 +1,1046 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * UEFI Shell-like command + * + * Copyright (c) 2018 AKASHI Takahiro, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BS systab.boottime +#define RT systab.runtime + +/** + * efi_get_device_handle_info() - get information of UEFI device + * + * @handle: Handle of UEFI device + * @dev_path_text: Pointer to text of device path + * Return: 0 on success, -1 on failure + * + * Currently return a formatted text of device path. + */ +static int efi_get_device_handle_info(efi_handle_t handle, u16 **dev_path_text) +{ + struct efi_device_path *dp; + efi_status_t ret; + + ret = EFI_CALL(BS->open_protocol(handle, &efi_guid_device_path, + (void **)&dp, NULL /* FIXME */, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL)); + if (ret == EFI_SUCCESS) { + *dev_path_text = efi_dp_str(dp); + return 0; + } else { + return -1; + } +} + +#define EFI_HANDLE_WIDTH ((int)sizeof(efi_handle_t) * 2) + +static const char spc[] = " "; +static const char sep[] = "================"; + +/** + * do_efi_show_devices() - show UEFI devices + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "devices" sub-command. + * Show all UEFI devices and their information. + */ +static int do_efi_show_devices(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + efi_handle_t *handles; + efi_uintn_t num, i; + u16 *dev_path_text; + efi_status_t ret; + + ret = EFI_CALL(BS->locate_handle_buffer(ALL_HANDLES, NULL, NULL, + &num, &handles)); + if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; + + if (!num) + return CMD_RET_SUCCESS; + + printf("Device%.*s Device Path\n", EFI_HANDLE_WIDTH - 6, spc); + printf("%.*s ====================\n", EFI_HANDLE_WIDTH, sep); + for (i = 0; i < num; i++) { + if (!efi_get_device_handle_info(handles[i], &dev_path_text)) { + printf("%p %ls\n", handles[i], dev_path_text); + efi_free_pool(dev_path_text); + } + } + + EFI_CALL(BS->free_pool(handles)); + + return CMD_RET_SUCCESS; +} + +/** + * efi_get_driver_handle_info() - get information of UEFI driver + * + * @handle: Handle of UEFI device + * @driver_name: Driver name + * @image_path: Pointer to text of device path + * Return: 0 on success, -1 on failure + * + * Currently return no useful information as all UEFI drivers are + * built-in.. + */ +static int efi_get_driver_handle_info(efi_handle_t handle, u16 **driver_name, + u16 **image_path) +{ + struct efi_handler *handler; + struct efi_loaded_image *image; + efi_status_t ret; + + /* + * driver name + * TODO: support EFI_COMPONENT_NAME2_PROTOCOL + */ + *driver_name = NULL; + + /* image name */ + ret = efi_search_protocol(handle, &efi_guid_loaded_image, &handler); + if (ret != EFI_SUCCESS) { + *image_path = NULL; + return 0; + } + + image = handler->protocol_interface; + *image_path = efi_dp_str(image->file_path); + + return 0; +} + +/** + * do_efi_show_drivers() - show UEFI drivers + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "drivers" sub-command. + * Show all UEFI drivers and their information. + */ +static int do_efi_show_drivers(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + efi_handle_t *handles; + efi_uintn_t num, i; + u16 *driver_name, *image_path_text; + efi_status_t ret; + + ret = EFI_CALL(BS->locate_handle_buffer( + BY_PROTOCOL, &efi_guid_driver_binding_protocol, + NULL, &num, &handles)); + if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; + + if (!num) + return CMD_RET_SUCCESS; + + printf("Driver%.*s Name Image Path\n", + EFI_HANDLE_WIDTH - 6, spc); + printf("%.*s ==================== ====================\n", + EFI_HANDLE_WIDTH, sep); + for (i = 0; i < num; i++) { + if (!efi_get_driver_handle_info(handles[i], &driver_name, + &image_path_text)) { + if (image_path_text) + printf("%p %-20ls %ls\n", handles[i], + driver_name, image_path_text); + else + printf("%p %-20ls \n", + handles[i], driver_name); + EFI_CALL(BS->free_pool(driver_name)); + EFI_CALL(BS->free_pool(image_path_text)); + } + } + + EFI_CALL(BS->free_pool(handles)); + + return CMD_RET_SUCCESS; +} + +static const struct { + const char *text; + const efi_guid_t guid; +} guid_list[] = { + { + "Device Path", + DEVICE_PATH_GUID, + }, + { + "Device Path To Text", + EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID, + }, + { + "Device Path Utilities", + EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID, + }, + { + "Unicode Collation 2", + EFI_UNICODE_COLLATION_PROTOCOL2_GUID, + }, + { + "Driver Binding", + EFI_DRIVER_BINDING_PROTOCOL_GUID, + }, + { + "Simple Text Input", + EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID, + }, + { + "Simple Text Input Ex", + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID, + }, + { + "Simple Text Output", + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID, + }, + { + "Block IO", + BLOCK_IO_GUID, + }, + { + "Simple File System", + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, + }, + { + "Loaded Image", + LOADED_IMAGE_PROTOCOL_GUID, + }, + { + "GOP", + EFI_GOP_GUID, + }, +}; + +/** + * get_guid_text - get string of protocol guid + * @guid: Protocol guid + * Return: String + * + * Return string for display to represent the protocol. + */ +static const char *get_guid_text(const efi_guid_t *guid) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(guid_list); i++) + if (!guidcmp(&guid_list[i].guid, guid)) + break; + + if (i != ARRAY_SIZE(guid_list)) + return guid_list[i].text; + else + return NULL; +} + +/** + * do_efi_show_handles() - show UEFI handles + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "dh" sub-command. + * Show all UEFI handles and their information, currently all protocols + * added to handle. + */ +static int do_efi_show_handles(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + efi_handle_t *handles; + efi_guid_t **guid; + efi_uintn_t num, count, i, j; + const char *guid_text; + efi_status_t ret; + + ret = EFI_CALL(BS->locate_handle_buffer(ALL_HANDLES, NULL, NULL, + &num, &handles)); + if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; + + if (!num) + return CMD_RET_SUCCESS; + + printf("Handle%.*s Protocols\n", EFI_HANDLE_WIDTH - 6, spc); + printf("%.*s ====================\n", EFI_HANDLE_WIDTH, sep); + for (i = 0; i < num; i++) { + printf("%p", handles[i]); + ret = EFI_CALL(BS->protocols_per_handle(handles[i], &guid, + &count)); + if (ret || !count) { + putc('\n'); + continue; + } + + for (j = 0; j < count; j++) { + if (j) + printf(", "); + else + putc(' '); + + guid_text = get_guid_text(guid[j]); + if (guid_text) + puts(guid_text); + else + printf("%pUl", guid[j]); + } + putc('\n'); + } + + EFI_CALL(BS->free_pool(handles)); + + return CMD_RET_SUCCESS; +} + +/** + * do_efi_show_images() - show UEFI images + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "images" sub-command. + * Show all UEFI loaded images and their information. + */ +static int do_efi_show_images(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + efi_print_image_infos(NULL); + + return CMD_RET_SUCCESS; +} + +static const char * const efi_mem_type_string[] = { + [EFI_RESERVED_MEMORY_TYPE] = "RESERVED", + [EFI_LOADER_CODE] = "LOADER CODE", + [EFI_LOADER_DATA] = "LOADER DATA", + [EFI_BOOT_SERVICES_CODE] = "BOOT CODE", + [EFI_BOOT_SERVICES_DATA] = "BOOT DATA", + [EFI_RUNTIME_SERVICES_CODE] = "RUNTIME CODE", + [EFI_RUNTIME_SERVICES_DATA] = "RUNTIME DATA", + [EFI_CONVENTIONAL_MEMORY] = "CONVENTIONAL", + [EFI_UNUSABLE_MEMORY] = "UNUSABLE MEM", + [EFI_ACPI_RECLAIM_MEMORY] = "ACPI RECLAIM MEM", + [EFI_ACPI_MEMORY_NVS] = "ACPI NVS", + [EFI_MMAP_IO] = "IO", + [EFI_MMAP_IO_PORT] = "IO PORT", + [EFI_PAL_CODE] = "PAL", +}; + +static const struct efi_mem_attrs { + const u64 bit; + const char *text; +} efi_mem_attrs[] = { + {EFI_MEMORY_UC, "UC"}, + {EFI_MEMORY_UC, "UC"}, + {EFI_MEMORY_WC, "WC"}, + {EFI_MEMORY_WT, "WT"}, + {EFI_MEMORY_WB, "WB"}, + {EFI_MEMORY_UCE, "UCE"}, + {EFI_MEMORY_WP, "WP"}, + {EFI_MEMORY_RP, "RP"}, + {EFI_MEMORY_XP, "WP"}, + {EFI_MEMORY_NV, "NV"}, + {EFI_MEMORY_MORE_RELIABLE, "REL"}, + {EFI_MEMORY_RO, "RO"}, + {EFI_MEMORY_RUNTIME, "RT"}, +}; + +/** + * print_memory_attributes() - print memory map attributes + * @attributes: Attribute value + * + * Print memory map attributes + */ +static void print_memory_attributes(u64 attributes) +{ + int sep, i; + + for (sep = 0, i = 0; i < ARRAY_SIZE(efi_mem_attrs); i++) + if (attributes & efi_mem_attrs[i].bit) { + if (sep) { + putc('|'); + } else { + putc(' '); + sep = 1; + } + puts(efi_mem_attrs[i].text); + } +} + +#define EFI_PHYS_ADDR_WIDTH (int)(sizeof(efi_physical_addr_t) * 2) + +/** + * do_efi_show_memmap() - show UEFI memory map + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "memmap" sub-command. + * Show UEFI memory map. + */ +static int do_efi_show_memmap(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + struct efi_mem_desc *memmap = NULL, *map; + efi_uintn_t map_size = 0; + const char *type; + int i; + efi_status_t ret; + + ret = EFI_CALL(BS->get_memory_map(&map_size, memmap, NULL, NULL, NULL)); + if (ret == EFI_BUFFER_TOO_SMALL) { + map_size += sizeof(struct efi_mem_desc); /* for my own */ + ret = EFI_CALL(BS->allocate_pool(EFI_LOADER_DATA, + map_size, (void *)&memmap)); + if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; + ret = EFI_CALL(BS->get_memory_map(&map_size, memmap, + NULL, NULL, NULL)); + } + if (ret != EFI_SUCCESS) { + EFI_CALL(BS->free_pool(memmap)); + return CMD_RET_FAILURE; + } + + printf("Type Start%.*s End%.*s Attributes\n", + EFI_PHYS_ADDR_WIDTH - 5, spc, EFI_PHYS_ADDR_WIDTH - 3, spc); + printf("================ %.*s %.*s ==========\n", + EFI_PHYS_ADDR_WIDTH, sep, EFI_PHYS_ADDR_WIDTH, sep); + for (i = 0, map = memmap; i < map_size / sizeof(*map); map++, i++) { + if (map->type < EFI_MAX_MEMORY_TYPE) + type = efi_mem_type_string[map->type]; + else + type = "(unknown)"; + + printf("%-16s %.*llx-%.*llx", type, + EFI_PHYS_ADDR_WIDTH, + map->physical_start, + EFI_PHYS_ADDR_WIDTH, + map->physical_start + map->num_pages * EFI_PAGE_SIZE); + + print_memory_attributes(map->attribute); + putc('\n'); + } + + EFI_CALL(BS->free_pool(memmap)); + + return CMD_RET_SUCCESS; +} + +/** + * do_efi_boot_add() - set UEFI load option + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, + * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "boot add" sub-command. + * Create or change UEFI load option. + * - boot add