diff options
author | Tom Rini <trini@konsulko.com> | 2019-08-12 18:47:53 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2019-08-12 18:47:53 -0400 |
commit | 9c6115822e894ead72fa4c094bf718eaabb9e103 (patch) | |
tree | 4f8843a5cfbe2895a168d96dee111dd31e443b2a | |
parent | 5939afc9611e8ba4a86b96e67670b765ee27668e (diff) | |
parent | 0805fe151d8c47cfbcfddf71c0891ed4f3c10b56 (diff) | |
download | u-boot-9c6115822e894ead72fa4c094bf718eaabb9e103.zip u-boot-9c6115822e894ead72fa4c094bf718eaabb9e103.tar.gz u-boot-9c6115822e894ead72fa4c094bf718eaabb9e103.tar.bz2 |
Merge branch '2019-08-11-ti-imports'
- More DaVinci updates and fixes
- PCIe support on am65x
- Watchdog converted to DM
- Assorted other bugfixes
47 files changed, 2850 insertions, 59 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index ce1eacb..4f9056f 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -282,6 +282,7 @@ dtb-$(CONFIG_AM33XX) += \ am335x-brppt1-nand.dtb \ am335x-brppt1-spi.dtb \ am335x-brxre1.dtb \ + am335x-brsmarc1.dtb \ am335x-draco.dtb \ am335x-evm.dtb \ am335x-evmsk.dtb \ diff --git a/arch/arm/dts/am335x-brsmarc1.dts b/arch/arm/dts/am335x-brsmarc1.dts new file mode 100644 index 0000000..1a7f9a5 --- /dev/null +++ b/arch/arm/dts/am335x-brsmarc1.dts @@ -0,0 +1,416 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 B&R Industrial Automation GmbH + * http://www.br-automation.com + * + */ +/dts-v1/; + +#include "am33xx.dtsi" +#include "dt-bindings/thermal/thermal.h" + +/ { + model = "BRSMARC1 SoM"; + compatible = "ti,am33xx"; + + fset: factory-settings { + bl-version = " "; + order-no = " "; + cpu-order-no = " "; + hw-revision = " "; + serial-no = <0>; + device-id = <0x0>; + parent-id = <0x0>; + hw-variant = <0x0>; + hw-platform = <0x7>; + fram-offset = <0x100>; + fram-size = <0x1F00>; + cache-disable = <0x0>; + cpu-clock = <0x0>; + }; + + chosen { + bootargs = "console=ttyO0,115200 earlyprintk"; + stdout-path = &uart0; + }; + + aliases { + fset = &fset; + mmc = &mmc2; + spi0 = &spi0; + spi1 = &spi1; + touch0 = &burtouch0; + screen0 = &lcdscreen0; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; + + vmmcsd_fixed: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vmmcsd_fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + lcdscreen0: lcdscreen@0 { + /*backlight = <&tps_bl>; */ + compatible = "ti,tilcdc,panel"; + status = "okay"; + + 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>; + rotation = <0>; + pupdelay = <0>; + pondelay = <0>; + pwrpin = <0x000000B1>; + brightdrv = <0>; + brightfdim = <100>; + brightdef = <50>; + }; + + display-timings { + default { + clock-frequency = <0>; + hactive = <0>; + vactive = <0>; + hfront-porch = <0>; + hback-porch = <0>; + hsync-len = <0>; + vfront-porch = <0>; + vback-porch = <0>; + vsync-len = <0>; + hsync-active = <0>; + vsync-active = <0>; + pupdelay = <10>; + pondelay = <10>; + }; + }; + }; + + board_thermal: board-thermal { + polling-delay-passive = <1000>; /* milliseconds */ + polling-delay = <2500>; /* milliseconds */ + + thermal-sensors = <&cputemp>; + + trips { + crit_trip: crit-trip { + temperature = <95000>; /* millicelsius */ + hysteresis = <5000>; /* millicelsius */ + type = "critical"; + }; + }; + cooling-maps { + map0 { + trip = <&crit_trip>; + cooling-device = + <&resetc THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +}; + +&uart0 { /* console uart */ + u-boot,dm-spl; + status = "okay"; +}; + +&uart2 { /* X2X - P2P */ + status = "okay"; +}; + +&uart3 { /* RS485 */ + status = "okay"; +}; + +&uart4 { /* RS232 */ + 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"; + }; + + cputemp: temperature-sensor@48 { /* cpu temperature */ + #thermal-sensor-cells = <0>; + compatible = "nxp,pct2075"; + reg = <0x48>; + }; + + basetemp: temperature-sensor@49 { /* baseboard temperature */ + #thermal-sensor-cells = <0>; + compatible = "nxp,pct2075"; + reg = <0x49>; + }; + extrtc: rtc@51 { /* realtime clock */ + compatible = "epson,rx8571"; + reg = <0x51>; + }; + + resetc: reset-controller@60 { + compatible = "bur,rststm"; + reg = <0x60>; + + cooling-min-state = <0>; + cooling-max-state = <1>; /* reset gets fired */ + #cooling-cells = <2>; /* min followed by max */ + }; +}; + +&i2c1 { + u-boot,dm-spl; + status = "okay"; +}; + +&spi0 { + u-boot,dm-spl; + status = "okay"; + + cs-gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>, + <&gpio0 6 GPIO_ACTIVE_HIGH>, + <0>, + <0>; + + spi-max-frequency = <24000000>; + + spi_flash: spiflash@0 { + u-boot,dm-spl; + u-boot,dm-pre-reloc; + compatible = "spidev", "spi-flash"; + spi-max-frequency = <24000000>; + reg = <0>; + }; +}; + +&spi1 { + u-boot,dm-spl; + status = "okay"; + cs-gpios = <&gpio3 17 GPIO_ACTIVE_HIGH>, + <&gpio0 19 GPIO_ACTIVE_HIGH>, + <0>, + <0>; + + spi-max-frequency = <24000000>; +}; + +&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"; +}; + +&phy_sel { + rmii-clock-ext; +}; + +&cpsw_emac0 { + phy_id = <&davinci_mdio>, <1>; + phy-mode = "rmii"; + ti,ledcr = <0x0480>; +}; + +&cpsw_emac1 { + phy_id = <&davinci_mdio>, <3>; + phy-mode = "rmii"; + ti,ledcr = <0x0480>; +}; + +&mmc1 { + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <0x4>; + ti,non-removable; + ti,needs-special-hs-handling; + ti,vcc-aux-disable-is-sleep; + status = "okay"; +}; + +&mmc2 { + 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/k3-am65-main.dtsi b/arch/arm/dts/k3-am65-main.dtsi index 7d03706..0f5da9a 100644 --- a/arch/arm/dts/k3-am65-main.dtsi +++ b/arch/arm/dts/k3-am65-main.dtsi @@ -5,6 +5,9 @@ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/ */ +#include <dt-bindings/phy/phy-am654-serdes.h> +#include <dt-bindings/phy/phy.h> + &cbass_main { gic500: interrupt-controller@1800000 { compatible = "arm,gic-v3"; @@ -143,4 +146,109 @@ clocks = <&k3_clks 113 1>; power-domains = <&k3_pds 113 TI_SCI_PD_EXCLUSIVE>; }; + + scm_conf: scm_conf@100000 { + compatible = "syscon", "simple-mfd"; + reg = <0 0x00100000 0 0x1c000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x00100000 0x1c000>; + + serdes_mux: mux-controller { + compatible = "mmio-mux"; + #mux-control-cells = <1>; + mux-reg-masks = <0x4080 0x3>, /* SERDES0 lane select */ + <0x4090 0x3>; /* SERDES1 lane select */ + }; + + pcie0_mode: pcie-mode@4060 { + compatible = "syscon"; + reg = <0x00004060 0x4>; + }; + + pcie1_mode: pcie-mode@4070 { + compatible = "syscon"; + reg = <0x00004070 0x4>; + }; + + serdes0_clk: serdes_clk@4080 { + compatible = "syscon"; + reg = <0x00004080 0x4>; + }; + + serdes1_clk: serdes_clk@4090 { + compatible = "syscon"; + reg = <0x00004090 0x4>; + }; + + pcie_devid: pcie-devid@210 { + compatible = "syscon"; + reg = <0x00000210 0x4>; + }; + }; + + serdes0: serdes@900000 { + compatible = "ti,phy-am654-serdes"; + reg = <0x0 0x900000 0x0 0x2000>; + reg-names = "serdes"; + #phy-cells = <2>; + power-domains = <&k3_pds 153 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 153 4>, <&k3_clks 153 1>, <&serdes1 AM654_SERDES_LO_REFCLK>; + clock-output-names = "serdes0_cmu_refclk", "serdes0_lo_refclk", "serdes0_ro_refclk"; + assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>; + assigned-clock-parents = <&k3_clks 153 8>, <&k3_clks 153 4>; + ti,serdes-clk = <&serdes0_clk>; + mux-controls = <&serdes_mux 0>; + #clock-cells = <1>; + }; + + serdes1: serdes@910000 { + compatible = "ti,phy-am654-serdes"; + reg = <0x0 0x910000 0x0 0x2000>; + reg-names = "serdes"; + #phy-cells = <2>; + power-domains = <&k3_pds 154 TI_SCI_PD_EXCLUSIVE>; + clocks = <&serdes0 AM654_SERDES_RO_REFCLK>, <&k3_clks 154 1>, <&k3_clks 154 5>; + clock-output-names = "serdes1_cmu_refclk", "serdes1_lo_refclk", "serdes1_ro_refclk"; + assigned-clocks = <&k3_clks 154 5>, <&serdes1 AM654_SERDES_CMU_REFCLK>; + assigned-clock-parents = <&k3_clks 154 9>, <&k3_clks 154 5>; + ti,serdes-clk = <&serdes1_clk>; + mux-controls = <&serdes_mux 1>; + #clock-cells = <1>; + }; + + pcie0_rc: pcie@5500000 { + compatible = "ti,am654-pcie-rc"; + reg = <0x0 0x5500000 0x0 0x1000>, <0x0 0x5501000 0x0 0x1000>, <0x0 0x10000000 0x0 0x2000>, <0x0 0x5506000 0x0 0x1000>; + reg-names = "app", "dbics", "config", "atu"; + power-domains = <&k3_pds 120 TI_SCI_PD_EXCLUSIVE>; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x81000000 0 0 0x0 0x10020000 0 0x00010000 + 0x82000000 0 0x10030000 0x0 0x10030000 0 0x07FD0000>; + ti,syscon-pcie-id = <&pcie_devid>; + ti,syscon-pcie-mode = <&pcie0_mode>; + bus-range = <0x0 0xff>; + status = "disabled"; + device_type = "pci"; + num-lanes = <1>; + num-ob-windows = <16>; + num-viewport = <16>; + max-link-speed = <3>; + interrupts = <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie0_intc 0>, /* INT A */ + <0 0 0 2 &pcie0_intc 0>, /* INT B */ + <0 0 0 3 &pcie0_intc 0>, /* INT C */ + <0 0 0 4 &pcie0_intc 0>; /* INT D */ + msi-map = <0x0 &gic_its 0x0 0x10000>; + + pcie0_intc: legacy-interrupt-controller@1 { + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&gic500>; + interrupts = <GIC_SPI 328 IRQ_TYPE_EDGE_RISING>; + }; + }; }; diff --git a/arch/arm/dts/k3-am65.dtsi b/arch/arm/dts/k3-am65.dtsi index a3abd14..a1467a4 100644 --- a/arch/arm/dts/k3-am65.dtsi +++ b/arch/arm/dts/k3-am65.dtsi @@ -69,6 +69,7 @@ <0x00 0x00900000 0x00 0x00900000 0x00 0x00012000>, /* serdes */ <0x00 0x01000000 0x00 0x01000000 0x00 0x0af02400>, /* Most peripherals */ <0x00 0x30800000 0x00 0x30800000 0x00 0x0bc00000>, /* MAIN NAVSS */ + <0x00 0x10000000 0x00 0x10000000 0x00 0x10000000>, /* PCIe DAT */ /* MCUSS Range */ <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>, <0x00 0x40200000 0x00 0x40200000 0x00 0x00900100>, diff --git a/arch/arm/include/asm/ti-common/omap_wdt.h b/arch/arm/include/asm/ti-common/omap_wdt.h index 7d72e3a..fbc421b 100644 --- a/arch/arm/include/asm/ti-common/omap_wdt.h +++ b/arch/arm/include/asm/ti-common/omap_wdt.h @@ -56,4 +56,9 @@ struct wd_timer { unsigned int wdt_unfr; /* offset 0x100 */ }; +struct omap3_wdt_priv { + struct wd_timer *regs; + unsigned int wdt_trgr_pattern; +}; + #endif /* __OMAP_WDT_H__ */ diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c index 2ede820..7a482bd 100644 --- a/arch/arm/mach-k3/sysfw-loader.c +++ b/arch/arm/mach-k3/sysfw-loader.c @@ -251,10 +251,21 @@ void k3_sysfw_loader(void (*config_pm_done_callback)(void)) if (config_pm_done_callback) config_pm_done_callback(); - /* Output System Firmware version info */ - printf("SYSFW ABI: %d.%d (firmware rev 0x%04x '%.*s')\n", + /* + * Output System Firmware version info. Note that since the + * 'firmware_description' field is not guaranteed to be zero- + * terminated we manually add a \0 terminator if needed. Further + * note that we intentionally no longer rely on the extended + * printf() formatter '%.*s' to not having to require a more + * full-featured printf() implementation. + */ + char fw_desc[sizeof(ti_sci->version.firmware_description) + 1]; + + strncpy(fw_desc, ti_sci->version.firmware_description, + sizeof(ti_sci->version.firmware_description)); + fw_desc[sizeof(fw_desc) - 1] = '\0'; + + printf("SYSFW ABI: %d.%d (firmware rev 0x%04x '%s')\n", ti_sci->version.abi_major, ti_sci->version.abi_minor, - ti_sci->version.firmware_revision, - sizeof(ti_sci->version.firmware_description), - ti_sci->version.firmware_description); + ti_sci->version.firmware_revision, fw_desc); } diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index efe89ee..ed8056e 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -176,6 +176,7 @@ source "arch/arm/mach-omap2/omap5/Kconfig" source "arch/arm/mach-omap2/am33xx/Kconfig" source "board/BuR/brxre1/Kconfig" +source "board/BuR/brsmarc1/Kconfig" source "board/BuR/brppt1/Kconfig" source "board/siemens/draco/Kconfig" source "board/siemens/pxm2/Kconfig" diff --git a/arch/arm/mach-omap2/am33xx/Kconfig b/arch/arm/mach-omap2/am33xx/Kconfig index 9da2a16..7f6b344 100644 --- a/arch/arm/mach-omap2/am33xx/Kconfig +++ b/arch/arm/mach-omap2/am33xx/Kconfig @@ -121,6 +121,10 @@ config TARGET_BRXRE1 bool "Support BRXRE1" select BOARD_LATE_INIT +config TARGET_BRSMARC1 + bool "Support BRSMARC1" + select BOARD_LATE_INIT + config TARGET_BRPPT1 bool "Support BRPPT1" select BOARD_LATE_INIT diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c index eb8c584..734fa9d 100644 --- a/arch/arm/mach-omap2/boot-common.c +++ b/arch/arm/mach-omap2/boot-common.c @@ -207,7 +207,7 @@ void spl_board_init(void) #if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT) arch_misc_init(); #endif -#if defined(CONFIG_HW_WATCHDOG) +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) hw_watchdog_init(); #endif #ifdef CONFIG_AM33XX diff --git a/board/BuR/brsmarc1/Kconfig b/board/BuR/brsmarc1/Kconfig new file mode 100644 index 0000000..6d3d7a2 --- /dev/null +++ b/board/BuR/brsmarc1/Kconfig @@ -0,0 +1,15 @@ +if TARGET_BRSMARC1 + +config SYS_BOARD + default "brsmarc1" + +config SYS_VENDOR + default "BuR" + +config SYS_SOC + default "am33xx" + +config SYS_CONFIG_NAME + default "brsmarc1" + +endif diff --git a/board/BuR/brsmarc1/MAINTAINERS b/board/BuR/brsmarc1/MAINTAINERS new file mode 100644 index 0000000..c6dfc20 --- /dev/null +++ b/board/BuR/brsmarc1/MAINTAINERS @@ -0,0 +1,6 @@ +BRSMARC1 BOARD +M: Hannes Schmelzer <hannes.schmelzer@br-automation.com> +S: Maintained +F: board/BuR/brsmarc1/ +F: include/configs/brsmarc1.h +F: configs/brsmarc1_defconfig diff --git a/board/BuR/brsmarc1/Makefile b/board/BuR/brsmarc1/Makefile new file mode 100644 index 0000000..1c3f64d --- /dev/null +++ b/board/BuR/brsmarc1/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2019 Hannes Schmelzer <oe5hpm@oevsv.at> - +# B&R Industrial Automation GmbH - http://www.br-automation.com/ +# + +obj-$(CONFIG_SPL_BUILD) += mux.o +obj-y += ../common/br_resetc.o +obj-y += ../common/common.o +obj-y += board.o diff --git a/board/BuR/brsmarc1/board.c b/board/BuR/brsmarc1/board.c new file mode 100644 index 0000000..4c70346 --- /dev/null +++ b/board/BuR/brsmarc1/board.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * board.c + * + * Board functions for B&R BRSMARC1 Board + * + * Copyright (C) 2017 Hannes Schmelzer <oe5hpm@oevsv.at> + * B&R Industrial Automation GmbH - http://www.br-automation.com + * + */ +#include <common.h> +#include <errno.h> +#include <spl.h> +#include <asm/arch/cpu.h> +#include <asm/arch/hardware.h> +#include <asm/arch/omap.h> +#include <asm/arch/ddr_defs.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/mem.h> +#include <asm/io.h> +#include <asm/gpio.h> +#include <asm/emif.h> +#include <power/tps65217.h> +#include "../common/bur_common.h" +#include "../common/br_resetc.h" + +/* -------------------------------------------------------------------------*/ +/* -- defines for used GPIO Hardware -- */ +#define PER_RESET (2 * 32 + 0) + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_SPL_BUILD) +static const struct ddr_data ddr3_data = { + .datardsratio0 = MT41K256M16HA125E_RD_DQS, + .datawdsratio0 = MT41K256M16HA125E_WR_DQS, + .datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE, + .datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA, +}; + +static const struct cmd_control ddr3_cmd_ctrl_data = { + .cmd0csratio = MT41K256M16HA125E_RATIO, + .cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT, + + .cmd1csratio = MT41K256M16HA125E_RATIO, + .cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT, + + .cmd2csratio = MT41K256M16HA125E_RATIO, + .cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT, +}; + +static struct emif_regs ddr3_emif_reg_data = { + .sdram_config = MT41K256M16HA125E_EMIF_SDCFG, + .ref_ctrl = MT41K256M16HA125E_EMIF_SDREF, + .sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1, + .sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2, + .sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3, + .zq_config = MT41K256M16HA125E_ZQ_CFG, + .emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY, +}; + +static const struct ctrl_ioregs ddr3_ioregs = { + .cm0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, + .cm1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, + .cm2ioctl = MT41K256M16HA125E_IOCTRL_VALUE, + .dt0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, + .dt1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, +}; + +#define OSC (V_OSCK / 1000000) +const struct dpll_params dpll_ddr3 = { 400, OSC - 1, 1, -1, -1, -1, -1}; + +void am33xx_spl_board_init(void) +{ + struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; + struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP; + + int rc; + /* + * enable additional clocks of modules which are accessed later from + * VxWorks OS + */ + u32 *const clk_domains[] = { 0 }; + u32 *const clk_modules_specific[] = { + &cmwkup->wkup_adctscctrl, + &cmper->spi1clkctrl, + &cmper->dcan0clkctrl, + &cmper->dcan1clkctrl, + &cmper->timer4clkctrl, + &cmper->timer5clkctrl, + &cmper->lcdclkctrl, + &cmper->lcdcclkstctrl, + 0 + }; + do_enable_clocks(clk_domains, clk_modules_specific, 1); + + /* setup I2C */ + enable_i2c_pin_mux(); + + /* peripheral reset */ + rc = gpio_request(PER_RESET, "PER_RESET"); + if (rc != 0) + printf("cannot request PER_RESET GPIO!\n"); + + rc = gpio_direction_output(PER_RESET, 0); + if (rc != 0) + printf("cannot set PER_RESET GPIO!\n"); + + /* setup pmic */ + pmicsetup(0, 0); +} + +const struct dpll_params *get_dpll_ddr_params(void) +{ + return &dpll_ddr3; +} + +void sdram_init(void) +{ + config_ddr(400, &ddr3_ioregs, + &ddr3_data, + &ddr3_cmd_ctrl_data, + &ddr3_emif_reg_data, 0); +} +#endif /* CONFIG_SPL_BUILD */ +#if !defined(CONFIG_SPL_BUILD) + +/* decision if backlight is switched on or not on powerup */ +int board_backlightstate(void) +{ + u8 bklmask, rstcause; + int rc = 0; + + rc |= br_resetc_regget(RSTCTRL_SCRATCHREG1, &bklmask); + rc |= br_resetc_regget(RSTCTRL_ERSTCAUSE, &rstcause); + + if (rc != 0) { + printf("%s: read rstctrl failed!\n", __func__); + return 1; + } + + if ((rstcause & bklmask) != 0) + return 0; + + return 1; +} + +/* Basic board specific setup. run quite after relocation */ +int board_init(void) +{ + if (power_tps65217_init(0)) + printf("WARN: cannot setup PMIC 0x24 @ bus #0, not found!.\n"); + + return 0; +} + +#if defined(CONFIG_BOARD_LATE_INIT) + +int board_late_init(void) +{ + br_resetc_bmode(); + + return 0; +} + +#endif /* CONFIG_BOARD_LATE_INIT */ +#endif /* !CONFIG_SPL_BUILD */ diff --git a/board/BuR/brsmarc1/config.mk b/board/BuR/brsmarc1/config.mk new file mode 100644 index 0000000..0692988 --- /dev/null +++ b/board/BuR/brsmarc1/config.mk @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2019 Hannes Schmelzer <oe5hpm@oevsv.at> - +# B&R Industrial Automation GmbH - http://www.br-automation.com +# + +hw-platform-y :=$(shell echo $(CONFIG_DEFAULT_DEVICE_TREE) | sed -e 's/am335x-//') + +payload_off :=$(shell printf "%d" $(CONFIG_SYS_SPI_U_BOOT_OFFS)) + +quiet_cmd_prodbin = PRODBIN $@ $(payload_off) +cmd_prodbin = \ + dd if=/dev/zero ibs=1M count=2 2>/dev/null | tr "\000" "\377" >$@ && \ + dd conv=notrunc bs=1 if=MLO.byteswap of=$@ seek=0 2>/dev/null && \ + dd bs=1 if=u-boot-dtb.img of=$@ seek=$(payload_off) 2>/dev/null + +quiet_cmd_prodzip = SAPZIP $@ +cmd_prodzip = \ + test -d misc && rm -r misc; \ + mkdir misc && \ + cp MLO.byteswap misc/ && \ + cp spl/u-boot-spl.bin misc/ && \ + cp u-boot-dtb.img misc/ && \ + zip -9 -r $@ misc/* >/dev/null $< + +ALL-y += $(hw-platform-y)_prog.bin +ALL-y += $(hw-platform-y)_prod.zip + +$(hw-platform-y)_prog.bin: u-boot-dtb.img spl/u-boot-spl.bin + $(call if_changed,prodbin) + +$(hw-platform-y)_prod.zip: $(hw-platform-y)_prog.bin + $(call if_changed,prodzip)
\ No newline at end of file diff --git a/board/BuR/brsmarc1/mux.c b/board/BuR/brsmarc1/mux.c new file mode 100644 index 0000000..33c214d --- /dev/null +++ b/board/BuR/brsmarc1/mux.c @@ -0,0 +1,266 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * mux.c + * + * Pinmux Setting for B&R BRSMARC1 Board (HW-Rev. 1) + * + * Copyright (C) 2017 Hannes Schmelzer <hannes.schmelzer@br-automation.com> + * B&R Industrial Automation GmbH - http://www.br-automation.com + * + */ + +#include <common.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/hardware.h> +#include <asm/arch/mux.h> +#include <asm/io.h> +#include <i2c.h> + +static struct module_pin_mux spi0_pin_mux[] = { + /* SPI0_SCLK */ + {OFFSET(spi0_sclk), MODE(0) | PULLUDEN | RXACTIVE}, + /* SPI0_D0 */ + {OFFSET(spi0_d0), MODE(0) | PULLUDEN | RXACTIVE}, + /* SPI0_D1 */ + {OFFSET(spi0_d1), MODE(0) | PULLUDEN | RXACTIVE}, + /* SPI0_CS0 */ + {OFFSET(spi0_cs0), MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE}, + /* SPI0_CS1 */ + {OFFSET(spi0_cs1), MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE}, + {-1}, +}; + +static struct module_pin_mux spi1_pin_mux[] = { + /* SPI1_SCLK */ + {OFFSET(mcasp0_aclkx), MODE(3) | PULLUDEN | RXACTIVE}, + /* SPI1_D0 */ + {OFFSET(mcasp0_fsx), MODE(3) | PULLUDEN | RXACTIVE}, + /* SPI1_D1 */ + {OFFSET(mcasp0_axr0), MODE(3) | PULLUDEN | RXACTIVE}, + /* SPI1_CS0 */ + {OFFSET(mcasp0_ahclkr), MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE}, + /* SPI1_CS1 */ + {OFFSET(xdma_event_intr0), MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE}, + {-1}, +}; + +static struct module_pin_mux dcan0_pin_mux[] = { + /* DCAN0 TX */ + {OFFSET(uart1_ctsn), MODE(2) | PULLUDEN | PULLUP_EN}, + /* DCAN0 RX */ + {OFFSET(uart1_rtsn), MODE(2) | RXACTIVE}, + {-1}, +}; + +static struct module_pin_mux dcan1_pin_mux[] = { + /* DCAN1 TX */ + {OFFSET(uart0_ctsn), MODE(2) | PULLUDEN | PULLUP_EN}, + /* DCAN1 RX */ + {OFFSET(uart0_rtsn), MODE(2) | RXACTIVE}, + {-1}, +}; + +static struct module_pin_mux gpios[] = { + /* GPIO0_7 - LVDS_EN */ + {OFFSET(ecap0_in_pwm0_out), (MODE(7) | PULLUDDIS | PULLDOWN_EN)}, + /* GPIO0_20 - BKLT_PWM (timer7) */ + {OFFSET(xdma_event_intr1), (MODE(4) | PULLUDDIS | PULLDOWN_EN)}, + /* GPIO2_4 - DISON */ + {OFFSET(gpmc_wen), (MODE(7) | PULLUDDIS | PULLDOWN_EN)}, + /* GPIO1_24 - RGB_EN */ + {OFFSET(gpmc_a8), (MODE(7) | PULLUDDIS | PULLDOWN_EN)}, + /* GPIO1_28 - nPD */ + {OFFSET(gpmc_be1n), (MODE(7) | PULLUDEN | PULLUP_EN)}, + /* GPIO2_5 - Watchdog */ + {OFFSET(gpmc_be0n_cle), (MODE(7) | PULLUDDIS | PULLDOWN_EN)}, + /* GPIO2_0 - ResetOut */ + {OFFSET(gpmc_csn3), (MODE(7) | PULLUDEN | PULLUP_EN)}, + /* GPIO2_2 - BKLT_EN */ + {OFFSET(gpmc_advn_ale), (MODE(7) | PULLUDDIS | PULLDOWN_EN)}, + /* GPIO1_17 - GPIO0 */ + {OFFSET(gpmc_a1), (MODE(7) | PULLUDDIS | RXACTIVE)}, + /* GPIO1_18 - GPIO1 */ + {OFFSET(gpmc_a2), (MODE(7) | PULLUDDIS | RXACTIVE)}, + /* GPIO1_19 - GPIO2 */ + {OFFSET(gpmc_a3), (MODE(7) | PULLUDDIS | RXACTIVE)}, + /* GPIO1_22 - GPIO3 */ + {OFFSET(gpmc_a6), (MODE(7) | PULLUDDIS | RXACTIVE)}, + /* GPIO1_23 - GPIO4 */ + {OFFSET(gpmc_a7), (MODE(7) | PULLUDDIS | RXACTIVE)}, + /* GPIO1_25 - GPIO5 */ + {OFFSET(gpmc_a9), (MODE(7) | PULLUDDIS | RXACTIVE)}, + /* GPIO3_7 - GPIO6 */ + {OFFSET(emu0), (MODE(7) | PULLUDDIS | RXACTIVE)}, + /* GPIO3_8 - GPIO7 */ + {OFFSET(emu1), (MODE(7) | PULLUDDIS | RXACTIVE)}, + /* GPIO3_18 - GPIO8 */ + {OFFSET(mcasp0_aclkr), (MODE(7) | PULLUDDIS | RXACTIVE)}, + /* GPIO3_19 - GPIO9 */ + {OFFSET(mcasp0_fsr), (MODE(7) | PULLUDDIS | RXACTIVE)}, + /* GPIO3_20 - GPIO10 */ + {OFFSET(mcasp0_axr1), (MODE(7) | PULLUDDIS | RXACTIVE)}, + /* GPIO3_21 - GPIO11 */ + {OFFSET(mcasp0_ahclkx), (MODE(7) | PULLUDDIS | RXACTIVE)}, + /* GPIO2_28 - DRAM-strapping */ + {OFFSET(mmc0_dat1), (MODE(7) | PULLUDEN | PULLUP_EN)}, + /* GPIO2_4 - not routed (Pin U6) */ + {OFFSET(gpmc_wen), (MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + /* GPIO2_5 - not routed (Pin T6) */ + {OFFSET(gpmc_be0n_cle), (MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + /* GPIO2_28 - not routed (Pin G15) */ + {OFFSET(mmc0_dat1), (MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + /* GPIO3_18 - not routed (Pin B12) */ + {OFFSET(mcasp0_aclkr), (MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + {-1}, +}; + +static struct module_pin_mux uart0_pin_mux[] = { + /* UART0_RXD */ + {OFFSET(uart0_rxd), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + /* UART0_TXD */ + {OFFSET(uart0_txd), (MODE(0) | PULLUDEN)}, + {-1}, +}; + +static struct module_pin_mux uart234_pin_mux[] = { + /* UART2_RXD */ + {OFFSET(mii1_txclk), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + /* UART2_TXD */ + {OFFSET(mii1_rxclk), (MODE(1) | PULLUDEN)}, + + /* UART3_RXD */ + {OFFSET(mii1_rxd3), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + /* UART3_TXD */ + {OFFSET(mmc0_dat0), (MODE(3) | PULLUDEN)}, + /* UART3_RTS */ + {OFFSET(mmc0_cmd), (MODE(2) | PULLUDEN)}, + /* UART3_CTS */ + {OFFSET(mmc0_clk), (MODE(2) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + + /* UART4_RXD */ + {OFFSET(mii1_txd3), (MODE(3) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + /* UART4_TXD */ + {OFFSET(mii1_txd2), (MODE(3) | PULLUDEN)}, + /* UART4_RTS */ + {OFFSET(mmc0_dat2), (MODE(3) | PULLUDEN)}, + /* UART4_CTS */ + {OFFSET(mmc0_dat3), (MODE(3) | PULLUDEN | PULLUP_EN | RXACTIVE)}, + + {-1}, +}; + +static struct module_pin_mux i2c_pin_mux[] = { + /* I2C0_DATA */ + {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL)}, + /* I2C0_SCLK */ + {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL)}, + /* I2C1_DATA */ + {OFFSET(uart1_rxd), (MODE(3) | RXACTIVE | PULLUDEN | SLEWCTRL)}, + /* I2C1_SCLK */ + {OFFSET(uart1_txd), (MODE(3) | RXACTIVE | PULLUDEN | SLEWCTRL)}, + {-1}, +}; + +static struct module_pin_mux eth_pin_mux[] = { + /* ETH1 */ + {OFFSET(rmii1_refclk), MODE(0) | RXACTIVE}, /* ETH1_REFCLK */ + {OFFSET(mii1_crs), MODE(1) | RXACTIVE}, /* RMII1_CRSDV */ + {OFFSET(mii1_rxerr), MODE(1) | RXACTIVE}, /* RMII1_RXER */ + {OFFSET(mii1_txen), MODE(1)}, /* RMII1_TXEN */ + {OFFSET(mii1_rxd0), MODE(1) | RXACTIVE}, /* RMII1_RXD0 */ + {OFFSET(mii1_rxd1), MODE(1) | RXACTIVE}, /* RMII1_RXD1 */ + {OFFSET(mii1_txd0), MODE(1)}, /* RMII1_TXD0 */ + {OFFSET(mii1_txd1), MODE(1)}, /* RMII1_TXD1 */ + + /* ETH2 */ + {OFFSET(mii1_col), MODE(1) | RXACTIVE}, /* ETH2_REFCLK */ + {OFFSET(gpmc_wait0), MODE(3) | RXACTIVE}, /* RMII2_CRSDV */ + {OFFSET(gpmc_wpn), MODE(3) | RXACTIVE}, /* RMII2_RXER */ + {OFFSET(gpmc_a0), MODE(3)}, /* RMII2_TXEN */ + {OFFSET(gpmc_a11), MODE(3) | RXACTIVE}, /* RMII2_RXD0 */ + {OFFSET(gpmc_a10), MODE(3) | RXACTIVE}, /* RMII2_RXD1 */ + {OFFSET(gpmc_a5), MODE(3)}, /* RMII2_TXD0 */ + {OFFSET(gpmc_a4), MODE(3)}, /* RMII2_TXD1 */ + + /* gpio2_19, gpio 3_4, not connected on board */ + {OFFSET(mii1_rxd2), MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE}, + {OFFSET(mii1_rxdv), MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE}, + + /* ETH Management */ + {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */ + {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */ + + {-1}, +}; + +static struct module_pin_mux mmc1_pin_mux[] = { + {OFFSET(gpmc_ad7), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT7 */ + {OFFSET(gpmc_ad6), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT6 */ + {OFFSET(gpmc_ad5), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT5 */ + {OFFSET(gpmc_ad4), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT4 */ + {OFFSET(gpmc_ad3), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT3 */ + {OFFSET(gpmc_ad2), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT2 */ + {OFFSET(gpmc_ad1), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT1 */ + {OFFSET(gpmc_ad0), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT0 */ + {OFFSET(gpmc_csn1), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* MMC1_CLK */ + {OFFSET(gpmc_csn2), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* MMC1_CMD */ + {-1}, +}; + +static struct module_pin_mux lcd_pin_mux[] = { + {OFFSET(lcd_data0), (MODE(0) | PULLUDDIS)}, /* LCD-Data(0) */ + {OFFSET(lcd_data1), (MODE(0) | PULLUDDIS)}, /* LCD-Data(1) */ + {OFFSET(lcd_data2), (MODE(0) | PULLUDDIS)}, /* LCD-Data(2) */ + {OFFSET(lcd_data3), (MODE(0) | PULLUDDIS)}, /* LCD-Data(3) */ + {OFFSET(lcd_data4), (MODE(0) | PULLUDDIS)}, /* LCD-Data(4) */ + {OFFSET(lcd_data5), (MODE(0) | PULLUDDIS)}, /* LCD-Data(5) */ + {OFFSET(lcd_data6), (MODE(0) | PULLUDDIS)}, /* LCD-Data(6) */ + {OFFSET(lcd_data7), (MODE(0) | PULLUDDIS)}, /* LCD-Data(7) */ + {OFFSET(lcd_data8), (MODE(0) | PULLUDDIS)}, /* LCD-Data(8) */ + {OFFSET(lcd_data9), (MODE(0) | PULLUDDIS)}, /* LCD-Data(9) */ + {OFFSET(lcd_data10), (MODE(0) | PULLUDDIS)}, /* LCD-Data(10) */ + {OFFSET(lcd_data11), (MODE(0) | PULLUDDIS)}, /* LCD-Data(11) */ + {OFFSET(lcd_data12), (MODE(0) | PULLUDDIS)}, /* LCD-Data(12) */ + {OFFSET(lcd_data13), (MODE(0) | PULLUDDIS)}, /* LCD-Data(13) */ + {OFFSET(lcd_data14), (MODE(0) | PULLUDDIS)}, /* LCD-Data(14) */ + {OFFSET(lcd_data15), (MODE(0) | PULLUDDIS)}, /* LCD-Data(15) */ + + {OFFSET(gpmc_ad8), (MODE(1) | PULLUDDIS)}, /* LCD-Data(16) */ + {OFFSET(gpmc_ad9), (MODE(1) | PULLUDDIS)}, /* LCD-Data(17) */ + {OFFSET(gpmc_ad10), (MODE(1) | PULLUDDIS)}, /* LCD-Data(18) */ + {OFFSET(gpmc_ad11), (MODE(1) | PULLUDDIS)}, /* LCD-Data(19) */ + {OFFSET(gpmc_ad12), (MODE(1) | PULLUDDIS)}, /* LCD-Data(20) */ + {OFFSET(gpmc_ad13), (MODE(1) | PULLUDDIS)}, /* LCD-Data(21) */ + {OFFSET(gpmc_ad14), (MODE(1) | PULLUDDIS)}, /* LCD-Data(22) */ + {OFFSET(gpmc_ad15), (MODE(1) | PULLUDDIS)}, /* LCD-Data(23) */ + + {OFFSET(lcd_vsync), (MODE(0) | PULLUDDIS)}, /* LCD-VSync */ + {OFFSET(lcd_hsync), (MODE(0) | PULLUDDIS)}, /* LCD-HSync */ + {OFFSET(lcd_ac_bias_en), (MODE(0) | PULLUDDIS)},/* LCD-DE */ + {OFFSET(lcd_pclk), (MODE(0) | PULLUDDIS)}, /* LCD-CLK */ + + {-1}, +}; + +void enable_uart0_pin_mux(void) +{ + configure_module_pin_mux(uart0_pin_mux); +} + +void enable_i2c_pin_mux(void) +{ + configure_module_pin_mux(i2c_pin_mux); +} + +void enable_board_pin_mux(void) +{ + configure_module_pin_mux(eth_pin_mux); + configure_module_pin_mux(spi0_pin_mux); + configure_module_pin_mux(spi1_pin_mux); + configure_module_pin_mux(dcan0_pin_mux); + configure_module_pin_mux(dcan1_pin_mux); + configure_module_pin_mux(uart234_pin_mux); + configure_module_pin_mux(mmc1_pin_mux); + configure_module_pin_mux(lcd_pin_mux); + configure_module_pin_mux(gpios); +} diff --git a/board/davinci/da8xxevm/da850evm.c b/board/davinci/da8xxevm/da850evm.c index d9019de..b2b2fa2 100644 --- a/board/davinci/da8xxevm/da850evm.c +++ b/board/davinci/da8xxevm/da850evm.c @@ -234,7 +234,8 @@ const struct pinmux_resource pinmuxes[] = { PINMUX_ITEM(emifa_pins_cs3), PINMUX_ITEM(emifa_pins_cs4), PINMUX_ITEM(emifa_pins_nand), -#elif defined(CONFIG_USE_NOR) +#endif +#ifdef CONFIG_USE_NOR PINMUX_ITEM(emifa_pins_cs2), PINMUX_ITEM(emifa_pins_nor), #endif diff --git a/board/overo/common.c b/board/overo/common.c index fc02d66..2c4f412 100644 --- a/board/overo/common.c +++ b/board/overo/common.c @@ -17,6 +17,7 @@ #include <asm/arch/mux.h> #include <asm/arch/sys_proto.h> #include <asm/gpio.h> +#include <asm/omap_mmc.h> #include <asm/mach-types.h> DECLARE_GLOBAL_DATA_PTR; @@ -38,6 +39,31 @@ int board_init(void) return 0; } +#if defined(CONFIG_MMC) +int board_mmc_init(bd_t *bis) +{ + return omap_mmc_init(0, 0, 0, -1, -1); +} +#endif + +#if defined(CONFIG_MMC) +void board_mmc_power_init(void) +{ + twl4030_power_mmc_init(0); +} +#endif + +#if defined(CONFIG_SPL_OS_BOOT) +int spl_start_uboot(void) +{ + /* break into full u-boot on 'c' */ + if (serial_tstc() && serial_getc() == 'c') + return 1; + + return 0; +} +#endif /* CONFIG_SPL_OS_BOOT */ + #define MUX_OVERO() \ /*SDRC*/\ MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)) /*SDRC_D0*/\ diff --git a/board/overo/overo.c b/board/overo/overo.c index f13bff1..442028a 100644 --- a/board/overo/overo.c +++ b/board/overo/overo.c @@ -377,20 +377,6 @@ int board_eth_init(bd_t *bis) } #endif -#if defined(CONFIG_MMC) -int board_mmc_init(bd_t *bis) -{ - return omap_mmc_init(0, 0, 0, -1, -1); -} -#endif - -#if defined(CONFIG_MMC) -void board_mmc_power_init(void) -{ - twl4030_power_mmc_init(0); -} -#endif - #if defined(CONFIG_USB_EHCI_HCD) static struct omap_usbhs_board_data usbhs_bdata = { .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, diff --git a/board/siemens/common/factoryset.c b/board/siemens/common/factoryset.c index 049a65f..7715ddf 100644 --- a/board/siemens/common/factoryset.c +++ b/board/siemens/common/factoryset.c @@ -9,6 +9,8 @@ #include <common.h> #include <env.h> +#include <dm.h> +#include <env_internal.h> #include <i2c.h> #include <asm/io.h> #include <asm/arch/cpu.h> @@ -143,16 +145,39 @@ int factoryset_read_eeprom(int i2c_addr) int i, pages = 0, size = 0; unsigned char eeprom_buf[0x3c00], hdr[4], buf[MAX_STRING_LENGTH]; unsigned char *cp, *cp1; +#if CONFIG_IS_ENABLED(DM_I2C) + struct udevice *bus, *dev; + int ret; +#endif #if defined(CONFIG_DFU_OVER_USB) factory_dat.usb_vendor_id = CONFIG_USB_GADGET_VENDOR_NUM; factory_dat.usb_product_id = CONFIG_USB_GADGET_PRODUCT_NUM; #endif + +#if CONFIG_IS_ENABLED(DM_I2C) + ret = uclass_get_device_by_seq(UCLASS_I2C, EEPROM_I2C_BUS, &bus); + if (ret) + goto err; + + ret = dm_i2c_probe(bus, i2c_addr, 0, &dev); + if (ret) + goto err; + + ret = i2c_set_chip_offset_len(dev, 2); + if (ret) + goto err; + + ret = dm_i2c_read(dev, EEPROM_FATORYSET_OFFSET, hdr, sizeof(hdr)); + if (ret) + goto err; +#else if (i2c_probe(i2c_addr)) goto err; if (i2c_read(i2c_addr, EEPROM_FATORYSET_OFFSET, 2, hdr, sizeof(hdr))) goto err; +#endif if ((hdr[0] != 0x99) || (hdr[1] != 0x80)) { printf("FactorySet is not right in eeprom.\n"); @@ -173,16 +198,33 @@ int factoryset_read_eeprom(int i2c_addr) * data after every time we got a record from eeprom */ debug("Read eeprom page :\n"); - for (i = 0; i < pages; i++) + for (i = 0; i < pages; i++) { +#if CONFIG_IS_ENABLED(DM_I2C) + ret = dm_i2c_read(dev, (OFF_PG + i) * EEPR_PG_SZ, + eeprom_buf + (i * EEPR_PG_SZ), EEPR_PG_SZ); + if (ret) + goto err; +#else if (i2c_read(i2c_addr, (OFF_PG + i) * EEPR_PG_SZ, 2, eeprom_buf + (i * EEPR_PG_SZ), EEPR_PG_SZ)) goto err; +#endif + } - if (size % EEPR_PG_SZ) + if (size % EEPR_PG_SZ) { +#if CONFIG_IS_ENABLED(DM_I2C) + ret = dm_i2c_read(dev, (OFF_PG + pages) * EEPR_PG_SZ, + eeprom_buf + (pages * EEPR_PG_SZ), + size % EEPR_PG_SZ); + if (ret) + goto err; +#else if (i2c_read(i2c_addr, (OFF_PG + pages) * EEPR_PG_SZ, 2, eeprom_buf + (pages * EEPR_PG_SZ), (size % EEPR_PG_SZ))) goto err; +#endif + } /* we do below just for eeprom align */ for (i = 0; i < size; i++) @@ -202,6 +244,20 @@ int factoryset_read_eeprom(int i2c_addr) cp1 += 3; } +#if CONFIG_IS_ENABLED(TARGET_GIEDI) || CONFIG_IS_ENABLED(TARGET_DENEB) + /* get mac address for WLAN */ + ret = get_factory_record_val(cp, size, (uchar *)"WLAN1", (uchar *)"mac", + buf, MAX_STRING_LENGTH); + if (ret > 0) { + cp1 = buf; + for (i = 0; i < 6; i++) { + factory_dat.mac_wlan[i] = simple_strtoul((char *)cp1, + NULL, 16); + cp1 += 3; + } + } +#endif + #if defined(CONFIG_DFU_OVER_USB) /* read vid and pid for dfu mode */ if (0 <= get_factory_record_val(cp, size, (uchar *)"USBD1", @@ -264,42 +320,76 @@ err: return 1; } -static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; +static int get_mac_from_efuse(uint8_t mac[6]) +{ +#ifdef CONFIG_AM33XX + struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; + uint32_t mac_hi, mac_lo; + + mac_lo = readl(&cdev->macid0l); + mac_hi = readl(&cdev->macid0h); + + mac[0] = mac_hi & 0xFF; + mac[1] = (mac_hi & 0xFF00) >> 8; + mac[2] = (mac_hi & 0xFF0000) >> 16; + mac[3] = (mac_hi & 0xFF000000) >> 24; + mac[4] = mac_lo & 0xFF; + mac[5] = (mac_lo & 0xFF00) >> 8; +#else + /* unhandled */ + memset(mac, 0, 6); +#endif + if (!is_valid_ethaddr(mac)) { + puts("Warning: ethaddr not set by FactorySet or E-fuse. "); + puts("Set <ethaddr> variable to overcome this.\n"); + return -1; + } + return 0; +} static int factoryset_mac_env_set(void) { uint8_t mac_addr[6]; + /* Set mac from factoryset or try reading E-fuse */ debug("FactorySet: Set mac address\n"); if (is_valid_ethaddr(factory_dat.mac)) { memcpy(mac_addr, factory_dat.mac, 6); } else { - uint32_t mac_hi, mac_lo; - debug("Warning: FactorySet: <ethaddr> not set. Fallback to E-fuse\n"); - mac_lo = readl(&cdev->macid0l); - mac_hi = readl(&cdev->macid0h); - - mac_addr[0] = mac_hi & 0xFF; - mac_addr[1] = (mac_hi & 0xFF00) >> 8; - mac_addr[2] = (mac_hi & 0xFF0000) >> 16; - mac_addr[3] = (mac_hi & 0xFF000000) >> 24; - mac_addr[4] = mac_lo & 0xFF; - mac_addr[5] = (mac_lo & 0xFF00) >> 8; - if (!is_valid_ethaddr(mac_addr)) { - printf("Warning: ethaddr not set by FactorySet or E-fuse. Set <ethaddr> variable to overcome this.\n"); + if (get_mac_from_efuse(mac_addr) < 0) return -1; - } } eth_env_set_enetaddr("ethaddr", mac_addr); + +#if CONFIG_IS_ENABLED(TARGET_GIEDI) || CONFIG_IS_ENABLED(TARGET_DENEB) + eth_env_set_enetaddr("eth1addr", mac_addr); + + /* wlan mac */ + if (is_valid_ethaddr(factory_dat.mac_wlan)) + eth_env_set_enetaddr("eth2addr", factory_dat.mac_wlan); +#endif return 0; } +static void factoryset_dtb_env_set(void) +{ + /* Set ASN in environment*/ + if (factory_dat.asn[0] != 0) { + env_set("dtb_name", (char *)factory_dat.asn); + } else { + /* dtb suffix gets added in load script */ + env_set("dtb_name", "default"); + } +} + int factoryset_env_set(void) { int ret = 0; + factoryset_dtb_env_set(); + if (factoryset_mac_env_set() < 0) ret = -1; diff --git a/board/siemens/common/factoryset.h b/board/siemens/common/factoryset.h index d4e8353..261a217 100644 --- a/board/siemens/common/factoryset.h +++ b/board/siemens/common/factoryset.h @@ -11,6 +11,9 @@ struct factorysetcontainer { uchar mac[6]; +#if CONFIG_IS_ENABLED(TARGET_GIEDI) || CONFIG_IS_ENABLED(TARGET_DENEB) + uchar mac_wlan[6]; +#endif int usb_vendor_id; int usb_product_id; int pxm50; diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig index ff96f19..c0f7ccc 100644 --- a/configs/am335x_evm_defconfig +++ b/configs/am335x_evm_defconfig @@ -58,6 +58,9 @@ CONFIG_DM_SPI=y CONFIG_OMAP3_SPI=y CONFIG_TIMER=y CONFIG_OMAP_TIMER=y +CONFIG_WDT=y +CONFIG_WDT_OMAP3=y +# CONFIG_SPL_WDT is not set CONFIG_USB=y CONFIG_DM_USB=y CONFIG_DM_USB_GADGET=y diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig index d43df6a..7e33e4c 100644 --- a/configs/am65x_evm_a53_defconfig +++ b/configs/am65x_evm_a53_defconfig @@ -34,6 +34,8 @@ CONFIG_CMD_ASKENV=y CONFIG_CMD_GPT=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_REMOTEPROC=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_TIME=y # CONFIG_ISO_PARTITION is not set @@ -68,8 +70,14 @@ CONFIG_MMC_SDHCI_AM654=y CONFIG_PHY_TI=y CONFIG_PHY_FIXED=y CONFIG_DM_ETH=y +CONFIG_E1000=y +CONFIG_CMD_E1000=y CONFIG_TI_AM65_CPSW_NUSS=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCI_KEYSTONE=y CONFIG_PHY=y +CONFIG_AM654_PHY=y CONFIG_PINCTRL=y # CONFIG_PINCTRL_GENERIC is not set CONFIG_SPL_PINCTRL=y diff --git a/configs/brsmarc1_defconfig b/configs/brsmarc1_defconfig new file mode 100644 index 0000000..9066b1c --- /dev/null +++ b/configs/brsmarc1_defconfig @@ -0,0 +1,109 @@ +CONFIG_ARM=y +CONFIG_ARCH_OMAP2PLUS=y +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_AM33XX=y +CONFIG_SYS_MPUCLK=600 +CONFIG_TARGET_BRSMARC1=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_ENV_SIZE=0x10000 +CONFIG_ENV_OFFSET=0x20000 +CONFIG_SPL_SYS_MALLOC_F_LEN=0x4000 +CONFIG_SPL=y +CONFIG_ENV_SECT_SIZE=0x10000 +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI_SUPPORT=y +CONFIG_TPL_SYS_MALLOC_F_LEN=0x0 +# CONFIG_EXPERT is not set +# CONFIG_FIT is not set +CONFIG_OF_BOARD_SETUP=y +CONFIG_BOOTDELAY=0 +CONFIG_USE_BOOTCOMMAND=y +CONFIG_BOOTCOMMAND="run b_default" +CONFIG_SYS_CONSOLE_IS_IN_ENV=y +CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y +CONFIG_SYS_CONSOLE_INFO_QUIET=y +CONFIG_VERSION_VARIABLE=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_ARCH_MISC_INIT=y +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_SEPARATE_BSS=y +# CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set +CONFIG_SPL_I2C_SUPPORT=y +# CONFIG_SPL_NAND_SUPPORT is not set +CONFIG_SPL_POWER_SUPPORT=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_SPL_YMODEM_SUPPORT=y +CONFIG_HUSH_PARSER=y +# CONFIG_CMD_BOOTD is not set +CONFIG_CMD_BOOTZ=y +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_EDITENV is not set +# CONFIG_CMD_CRC32 is not set +CONFIG_CMD_CLK=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_ITEST is not set +CONFIG_CMD_DHCP=y +# CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_TIME=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="am335x-brsmarc1" +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_NETCONSOLE=y +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +# CONFIG_OF_TRANSLATE is not set +# CONFIG_SPL_BLK is not set +CONFIG_DM_GPIO=y +CONFIG_DM_I2C=y +CONFIG_MISC=y +CONFIG_DM_MMC=y +CONFIG_MMC_OMAP_HS=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SF_DEFAULT_SPEED=24000000 +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_PHY_NATSEMI=y +CONFIG_DM_ETH=y +CONFIG_DRIVER_TI_CPSW=y +CONFIG_DM_SERIAL=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_OMAP3_SPI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_MUSB_HOST=y +CONFIG_USB_MUSB_GADGET=y +CONFIG_USB_MUSB_TI=y +CONFIG_USB_STORAGE=y +CONFIG_USB_GADGET=y +# CONFIG_OMAP_WATCHDOG is not set +CONFIG_SPL_TINY_MEMSET=y +CONFIG_SHA1=y +CONFIG_SHA256=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/da850evm_direct_nor_defconfig b/configs/da850evm_direct_nor_defconfig index 2eaa29f..e889751 100644 --- a/configs/da850evm_direct_nor_defconfig +++ b/configs/da850evm_direct_nor_defconfig @@ -21,17 +21,18 @@ CONFIG_SYS_PROMPT="U-Boot > " CONFIG_CMD_IMLS=y CONFIG_CRC32_VERIFY=y CONFIG_CMD_DM=y -# CONFIG_CMD_GPIO is not set # CONFIG_CMD_GPT is not set # CONFIG_CMD_MMC is not set +CONFIG_CMD_MTD=y +CONFIG_CMD_NAND=y # CONFIG_CMD_PART is not set +# CONFIG_CMD_SF is not set # CONFIG_CMD_SPI is not set # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_TIME is not set -# CONFIG_CMD_EXT2 is not set -# CONFIG_CMD_EXT4 is not set -# CONFIG_CMD_FAT is not set -# CONFIG_CMD_FS_GENERIC is not set +CONFIG_CMD_MTDPARTS=y +CONFIG_MTDIDS_DEFAULT="nor0=physmap-flash.2,nor1=spi1.0,nand0=nand512" +CONFIG_MTDPARTS_DEFAULT="mtdparts=physmap-flash.2:1m(u-boot),128k(u-boot-env),-(spare);spi1.0:32k(SPL),480k(u-boot),64k(u-boot-env),7552k(kernel-spare),64k(MAC-Address);nand512:128k(u-boot env),512k(u-boot),128k(spl-os),8m(kernel),-(rootfs)" CONFIG_CMD_DIAG=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="da850-evm" @@ -45,12 +46,17 @@ CONFIG_SYS_I2C_DAVINCI=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_FLASH_CFI_MTD=y CONFIG_SYS_FLASH_PROTECTION=y CONFIG_SYS_FLASH_CFI=y +CONFIG_NAND=y +CONFIG_NAND_DAVINCI=y CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_MTD=y CONFIG_DM_ETH=y CONFIG_MII=y CONFIG_DRIVER_TI_EMAC=y @@ -66,7 +72,6 @@ CONFIG_DM_SPI=y CONFIG_DAVINCI_SPI=y CONFIG_USB=y CONFIG_DM_USB=y -# CONFIG_SPL_DM_USB is not set CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_DA8XX=y CONFIG_USB_MUSB_HOST=y diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index cee4d91..c66b6f3 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -518,6 +518,19 @@ int clk_get_by_id(ulong id, struct clk **clkp) return -ENOENT; } +bool clk_is_match(const struct clk *p, const struct clk *q) +{ + /* trivial case: identical struct clk's or both NULL */ + if (p == q) + return true; + + /* same device, id and data */ + if (p->dev == q->dev && p->id == q->id && p->data == q->data) + return true; + + return false; +} + UCLASS_DRIVER(clk) = { .id = UCLASS_CLK, .name = "clk", diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c index c287386..6850003 100644 --- a/drivers/core/fdtaddr.c +++ b/drivers/core/fdtaddr.c @@ -129,6 +129,23 @@ fdt_addr_t devfdt_get_addr_name(struct udevice *dev, const char *name) #endif } +fdt_addr_t devfdt_get_addr_size_name(struct udevice *dev, const char *name, + fdt_size_t *size) +{ +#if CONFIG_IS_ENABLED(OF_CONTROL) + int index; + + index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev), + "reg-names", name); + if (index < 0) + return index; + + return devfdt_get_addr_size_index(dev, index, size); +#else + return FDT_ADDR_T_NONE; +#endif +} + fdt_addr_t devfdt_get_addr(struct udevice *dev) { return devfdt_get_addr_index(dev, 0); diff --git a/drivers/core/read.c b/drivers/core/read.c index 1a044b0..8b5502d 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -82,6 +82,15 @@ fdt_addr_t dev_read_addr_index(struct udevice *dev, int index) return devfdt_get_addr_index(dev, index); } +fdt_addr_t dev_read_addr_size_index(struct udevice *dev, int index, + fdt_size_t *size) +{ + if (ofnode_is_np(dev_ofnode(dev))) + return ofnode_get_addr_size_index(dev_ofnode(dev), index, size); + else + return devfdt_get_addr_size_index(dev, index, size); +} + void *dev_remap_addr_index(struct udevice *dev, int index) { fdt_addr_t addr = dev_read_addr_index(dev, index); @@ -102,6 +111,17 @@ fdt_addr_t dev_read_addr_name(struct udevice *dev, const char *name) return dev_read_addr_index(dev, index); } +fdt_addr_t dev_read_addr_size_name(struct udevice *dev, const char *name, + fdt_size_t *size) +{ + int index = dev_read_stringlist_search(dev, "reg-names", name); + + if (index < 0) + return FDT_ADDR_T_NONE; + else + return dev_read_addr_size_index(dev, index, size); +} + void *dev_remap_addr_name(struct udevice *dev, const char *name) { fdt_addr_t addr = dev_read_addr_name(dev, name); diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 1fd29f2..62b1dc2 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -3170,6 +3170,7 @@ devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle, u32 resource_subtype; u16 resource_type; struct ti_sci_resource *res; + bool valid_set = false; int sets, i, ret; u32 *temp; @@ -3209,12 +3210,15 @@ devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle, &res->desc[i].start, &res->desc[i].num); if (ret) { - dev_err(dev, "type %d subtype %d not allocated for host %d\n", + dev_dbg(dev, "type %d subtype %d not allocated for host %d\n", resource_type, resource_subtype, handle_to_ti_sci_info(handle)->host_id); - return ERR_PTR(ret); + res->desc[i].start = 0; + res->desc[i].num = 0; + continue; } + valid_set = true; dev_dbg(dev, "res type = %d, subtype = %d, start = %d, num = %d\n", resource_type, resource_subtype, res->desc[i].start, res->desc[i].num); @@ -3226,7 +3230,10 @@ devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle, return ERR_PTR(-ENOMEM); } - return res; + if (valid_set) + return res; + + return ERR_PTR(-EINVAL); } /* Description for K2G */ diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 3fe38f7..bdfc0c1 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -145,4 +145,10 @@ config PCI_MVEBU Say Y here if you want to enable PCIe controller support on Armada XP/38x SoCs. +config PCI_KEYSTONE + bool "TI Keystone PCIe controller" + depends on DM_PCI + help + Say Y here if you want to enable PCI controller support on AM654 SoC. + endif diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index b5ebd50..e54a98b 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -38,3 +38,4 @@ obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o \ pcie_layerscape_gen4_fixup.o obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o +obj-$(CONFIG_PCI_KEYSTONE) += pcie_dw_ti.o diff --git a/drivers/pci/pcie_dw_ti.c b/drivers/pci/pcie_dw_ti.c new file mode 100644 index 0000000..b37fc2d --- /dev/null +++ b/drivers/pci/pcie_dw_ti.c @@ -0,0 +1,725 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Texas Instruments, Inc + */ + +#include <common.h> +#include <dm.h> +#include <pci.h> +#include <generic-phy.h> +#include <power-domain.h> +#include <regmap.h> +#include <syscon.h> +#include <asm/io.h> +#include <asm-generic/gpio.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define PCIE_VENDORID_MASK GENMASK(15, 0) +#define PCIE_DEVICEID_SHIFT 16 + +/* PCI DBICS registers */ +#define PCIE_CONFIG_BAR0 0x10 +#define PCIE_LINK_STATUS_REG 0x80 +#define PCIE_LINK_STATUS_SPEED_OFF 16 +#define PCIE_LINK_STATUS_SPEED_MASK (0xf << PCIE_LINK_STATUS_SPEED_OFF) +#define PCIE_LINK_STATUS_WIDTH_OFF 20 +#define PCIE_LINK_STATUS_WIDTH_MASK (0xf << PCIE_LINK_STATUS_WIDTH_OFF) + +#define PCIE_LINK_CAPABILITY 0x7c +#define PCIE_LINK_CTL_2 0xa0 +#define TARGET_LINK_SPEED_MASK 0xf +#define LINK_SPEED_GEN_1 0x1 +#define LINK_SPEED_GEN_2 0x2 +#define LINK_SPEED_GEN_3 0x3 + +#define PCIE_MISC_CONTROL_1_OFF 0x8bc +#define PCIE_DBI_RO_WR_EN BIT(0) + +#define PLR_OFFSET 0x700 +#define PCIE_PORT_DEBUG0 (PLR_OFFSET + 0x28) +#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f +#define PORT_LOGIC_LTSSM_STATE_L0 0x11 + +#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80c +#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17) + +#define PCIE_LINK_UP_TIMEOUT_MS 100 + +/* + * iATU Unroll-specific register definitions + * From 4.80 core version the address translation will be made by unroll. + * The registers are offset from atu_base + */ +#define PCIE_ATU_UNR_REGION_CTRL1 0x00 +#define PCIE_ATU_UNR_REGION_CTRL2 0x04 +#define PCIE_ATU_UNR_LOWER_BASE 0x08 +#define PCIE_ATU_UNR_UPPER_BASE 0x0c +#define PCIE_ATU_UNR_LIMIT 0x10 +#define PCIE_ATU_UNR_LOWER_TARGET 0x14 +#define PCIE_ATU_UNR_UPPER_TARGET 0x18 + +#define PCIE_ATU_REGION_INDEX1 (0x1 << 0) +#define PCIE_ATU_REGION_INDEX0 (0x0 << 0) +#define PCIE_ATU_TYPE_MEM (0x0 << 0) +#define PCIE_ATU_TYPE_IO (0x2 << 0) +#define PCIE_ATU_TYPE_CFG0 (0x4 << 0) +#define PCIE_ATU_TYPE_CFG1 (0x5 << 0) +#define PCIE_ATU_ENABLE (0x1 << 31) +#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) +#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24) +#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19) +#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) + +/* Register address builder */ +#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) ((region) << 9) + +/* Offsets from App base */ +#define PCIE_CMD_STATUS 0x04 +#define LTSSM_EN_VAL BIT(0) + +/* Parameters for the waiting for iATU enabled routine */ +#define LINK_WAIT_MAX_IATU_RETRIES 5 +#define LINK_WAIT_IATU 10000 + +#define AM654_PCIE_DEV_TYPE_MASK 0x3 +#define EP 0x0 +#define LEG_EP 0x1 +#define RC 0x2 + +/** + * struct pcie_dw_ti - TI DW PCIe controller state + * + * @app_base: The base address of application register space + * @dbics_base: The base address of dbics register space + * @cfg_base: The base address of configuration space + * @atu_base: The base address of ATU space + * @cfg_size: The size of the configuration space which is needed + * as it gets written into the PCIE_ATU_LIMIT register + * @first_busno: This driver supports multiple PCIe controllers. + * first_busno stores the bus number of the PCIe root-port + * number which may vary depending on the PCIe setup + * (PEX switches etc). + */ +struct pcie_dw_ti { + void *app_base; + void *dbi_base; + void *cfg_base; + void *atu_base; + fdt_size_t cfg_size; + int first_busno; + struct udevice *dev; + + /* IO and MEM PCI regions */ + struct pci_region io; + struct pci_region mem; +}; + +enum dw_pcie_device_mode { + DW_PCIE_UNKNOWN_TYPE, + DW_PCIE_EP_TYPE, + DW_PCIE_LEG_EP_TYPE, + DW_PCIE_RC_TYPE, +}; + +static int pcie_dw_get_link_speed(struct pcie_dw_ti *pci) +{ + return (readl(pci->dbi_base + PCIE_LINK_STATUS_REG) & + PCIE_LINK_STATUS_SPEED_MASK) >> PCIE_LINK_STATUS_SPEED_OFF; +} + +static int pcie_dw_get_link_width(struct pcie_dw_ti *pci) +{ + return (readl(pci->dbi_base + PCIE_LINK_STATUS_REG) & + PCIE_LINK_STATUS_WIDTH_MASK) >> PCIE_LINK_STATUS_WIDTH_OFF; +} + +static void dw_pcie_writel_ob_unroll(struct pcie_dw_ti *pci, u32 index, u32 reg, + u32 val) +{ + u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); + void __iomem *base = pci->atu_base; + + writel(val, base + offset + reg); +} + +static u32 dw_pcie_readl_ob_unroll(struct pcie_dw_ti *pci, u32 index, u32 reg) +{ + u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); + void __iomem *base = pci->atu_base; + + return readl(base + offset + reg); +} + +/** + * pcie_dw_prog_outbound_atu_unroll() - Configure ATU for outbound accesses + * + * @pcie: Pointer to the PCI controller state + * @index: ATU region index + * @type: ATU accsess type + * @cpu_addr: the physical address for the translation entry + * @pci_addr: the pcie bus address for the translation entry + * @size: the size of the translation entry + */ +static void pcie_dw_prog_outbound_atu_unroll(struct pcie_dw_ti *pci, int index, + int type, u64 cpu_addr, + u64 pci_addr, u32 size) +{ + u32 retries, val; + + debug("ATU programmed with: index: %d, type: %d, cpu addr: %8llx, pci addr: %8llx, size: %8x\n", + index, type, cpu_addr, pci_addr, size); + + dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_BASE, + lower_32_bits(cpu_addr)); + dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_BASE, + upper_32_bits(cpu_addr)); + dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LIMIT, + lower_32_bits(cpu_addr + size - 1)); + dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_TARGET, + lower_32_bits(pci_addr)); + dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET, + upper_32_bits(pci_addr)); + dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, + type); + dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2, + PCIE_ATU_ENABLE); + + /* + * Make sure ATU enable takes effect before any subsequent config + * and I/O accesses. + */ + for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) { + val = dw_pcie_readl_ob_unroll(pci, index, + PCIE_ATU_UNR_REGION_CTRL2); + if (val & PCIE_ATU_ENABLE) + return; + + udelay(LINK_WAIT_IATU); + } + dev_err(pci->dev, "outbound iATU is not being enabled\n"); +} + +/** + * set_cfg_address() - Configure the PCIe controller config space access + * + * @pcie: Pointer to the PCI controller state + * @d: PCI device to access + * @where: Offset in the configuration space + * + * Configures the PCIe controller to access the configuration space of + * a specific PCIe device and returns the address to use for this + * access. + * + * Return: Address that can be used to access the configation space + * of the requested device / offset + */ +static uintptr_t set_cfg_address(struct pcie_dw_ti *pcie, + pci_dev_t d, uint where) +{ + int bus = PCI_BUS(d) - pcie->first_busno; + uintptr_t va_address; + u32 atu_type; + + /* Use dbi_base for own configuration read and write */ + if (!bus) { + va_address = (uintptr_t)pcie->dbi_base; + goto out; + } + + if (bus == 1) + /* For local bus, change TLP Type field to 4. */ + atu_type = PCIE_ATU_TYPE_CFG0; + else + /* Otherwise, change TLP Type field to 5. */ + atu_type = PCIE_ATU_TYPE_CFG1; + + /* + * Not accessing root port configuration space? + * Region #0 is used for Outbound CFG space access. + * Direction = Outbound + * Region Index = 0 + */ + d = PCI_MASK_BUS(d); + d = PCI_ADD_BUS(bus, d); + pcie_dw_prog_outbound_atu_unroll(pcie, PCIE_ATU_REGION_INDEX1, + atu_type, (u64)pcie->cfg_base, + d << 8, pcie->cfg_size); + + va_address = (uintptr_t)pcie->cfg_base; + +out: + va_address += where & ~0x3; + + return va_address; +} + +/** + * pcie_dw_addr_valid() - Check for valid bus address + * + * @d: The PCI device to access + * @first_busno: Bus number of the PCIe controller root complex + * + * Return 1 (true) if the PCI device can be accessed by this controller. + * + * Return: 1 on valid, 0 on invalid + */ +static int pcie_dw_addr_valid(pci_dev_t d, int first_busno) +{ + if ((PCI_BUS(d) == first_busno) && (PCI_DEV(d) > 0)) + return 0; + if ((PCI_BUS(d) == first_busno + 1) && (PCI_DEV(d) > 0)) + return 0; + + return 1; +} + +/** + * pcie_dw_ti_read_config() - Read from configuration space + * + * @bus: Pointer to the PCI bus + * @bdf: Identifies the PCIe device to access + * @offset: The offset into the device's configuration space + * @valuep: A pointer at which to store the read value + * @size: Indicates the size of access to perform + * + * Read a value of size @size from offset @offset within the configuration + * space of the device identified by the bus, device & function numbers in @bdf + * on the PCI bus @bus. + * + * Return: 0 on success + */ +static int pcie_dw_ti_read_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + struct pcie_dw_ti *pcie = dev_get_priv(bus); + uintptr_t va_address; + ulong value; + + debug("PCIE CFG read: bdf=%2x:%2x:%2x ", + PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); + + if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) { + debug("- out of range\n"); + *valuep = pci_get_ff(size); + return 0; + } + + va_address = set_cfg_address(pcie, bdf, offset); + + value = readl(va_address); + + debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); + *valuep = pci_conv_32_to_size(value, offset, size); + + pcie_dw_prog_outbound_atu_unroll(pcie, PCIE_ATU_REGION_INDEX1, + PCIE_ATU_TYPE_IO, pcie->io.phys_start, + pcie->io.bus_start, pcie->io.size); + + return 0; +} + +/** + * pcie_dw_ti_write_config() - Write to configuration space + * + * @bus: Pointer to the PCI bus + * @bdf: Identifies the PCIe device to access + * @offset: The offset into the device's configuration space + * @value: The value to write + * @size: Indicates the size of access to perform + * + * Write the value @value of size @size from offset @offset within the + * configuration space of the device identified by the bus, device & function + * numbers in @bdf on the PCI bus @bus. + * + * Return: 0 on success + */ +static int pcie_dw_ti_write_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct pcie_dw_ti *pcie = dev_get_priv(bus); + uintptr_t va_address; + ulong old; + + debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ", + PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); + debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); + + if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) { + debug("- out of range\n"); + return 0; + } + + va_address = set_cfg_address(pcie, bdf, offset); + + old = readl(va_address); + value = pci_conv_size_to_32(old, value, offset, size); + writel(value, va_address); + + pcie_dw_prog_outbound_atu_unroll(pcie, PCIE_ATU_REGION_INDEX1, + PCIE_ATU_TYPE_IO, pcie->io.phys_start, + pcie->io.bus_start, pcie->io.size); + + return 0; +} + +static inline void dw_pcie_dbi_write_enable(struct pcie_dw_ti *pci, bool en) +{ + u32 val; + + val = readl(pci->dbi_base + PCIE_MISC_CONTROL_1_OFF); + if (en) + val |= PCIE_DBI_RO_WR_EN; + else + val &= ~PCIE_DBI_RO_WR_EN; + writel(val, pci->dbi_base + PCIE_MISC_CONTROL_1_OFF); +} + +/** + * pcie_dw_configure() - Configure link capabilities and speed + * + * @regs_base: A pointer to the PCIe controller registers + * @cap_speed: The capabilities and speed to configure + * + * Configure the link capabilities and speed in the PCIe root complex. + */ +static void pcie_dw_configure(struct pcie_dw_ti *pci, u32 cap_speed) +{ + u32 val; + + dw_pcie_dbi_write_enable(pci, true); + + val = readl(pci->dbi_base + PCIE_LINK_CAPABILITY); + val &= ~TARGET_LINK_SPEED_MASK; + val |= cap_speed; + writel(val, pci->dbi_base + PCIE_LINK_CAPABILITY); + + val = readl(pci->dbi_base + PCIE_LINK_CTL_2); + val &= ~TARGET_LINK_SPEED_MASK; + val |= cap_speed; + writel(val, pci->dbi_base + PCIE_LINK_CTL_2); + + dw_pcie_dbi_write_enable(pci, false); +} + +/** + * is_link_up() - Return the link state + * + * @regs_base: A pointer to the PCIe DBICS registers + * + * Return: 1 (true) for active line and 0 (false) for no link + */ +static int is_link_up(struct pcie_dw_ti *pci) +{ + u32 val; + + val = readl(pci->dbi_base + PCIE_PORT_DEBUG0); + val &= PORT_LOGIC_LTSSM_STATE_MASK; + + return (val == PORT_LOGIC_LTSSM_STATE_L0); +} + +/** + * wait_link_up() - Wait for the link to come up + * + * @regs_base: A pointer to the PCIe controller registers + * + * Return: 1 (true) for active line and 0 (false) for no link (timeout) + */ +static int wait_link_up(struct pcie_dw_ti *pci) +{ + unsigned long timeout; + + timeout = get_timer(0) + PCIE_LINK_UP_TIMEOUT_MS; + while (!is_link_up(pci)) { + if (get_timer(0) > timeout) + return 0; + }; + + return 1; +} + +static int pcie_dw_ti_pcie_link_up(struct pcie_dw_ti *pci, u32 cap_speed) +{ + u32 val; + + if (is_link_up(pci)) { + printf("PCI Link already up before configuration!\n"); + return 1; + } + + /* DW pre link configurations */ + pcie_dw_configure(pci, cap_speed); + + /* Initiate link training */ + val = readl(pci->app_base + PCIE_CMD_STATUS); + val |= LTSSM_EN_VAL; + writel(val, pci->app_base + PCIE_CMD_STATUS); + + /* Check that link was established */ + if (!wait_link_up(pci)) + return 0; + + /* + * Link can be established in Gen 1. still need to wait + * till MAC nagaotiation is completed + */ + udelay(100); + + return 1; +} + +/** + * pcie_dw_setup_host() - Setup the PCIe controller for RC opertaion + * + * @pcie: Pointer to the PCI controller state + * + * Configure the host BARs of the PCIe controller root port so that + * PCI(e) devices may access the system memory. + */ +static void pcie_dw_setup_host(struct pcie_dw_ti *pci) +{ + u32 val; + + /* setup RC BARs */ + writel(PCI_BASE_ADDRESS_MEM_TYPE_64, + pci->dbi_base + PCI_BASE_ADDRESS_0); + writel(0x0, pci->dbi_base + PCI_BASE_ADDRESS_1); + + /* setup interrupt pins */ + dw_pcie_dbi_write_enable(pci, true); + val = readl(pci->dbi_base + PCI_INTERRUPT_LINE); + val &= 0xffff00ff; + val |= 0x00000100; + writel(val, pci->dbi_base + PCI_INTERRUPT_LINE); + dw_pcie_dbi_write_enable(pci, false); + + /* setup bus numbers */ + val = readl(pci->dbi_base + PCI_PRIMARY_BUS); + val &= 0xff000000; + val |= 0x00ff0100; + writel(val, pci->dbi_base + PCI_PRIMARY_BUS); + + /* setup command register */ + val = readl(pci->dbi_base + PCI_COMMAND); + val &= 0xffff0000; + val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SERR; + writel(val, pci->dbi_base + PCI_COMMAND); + + /* Enable write permission for the DBI read-only register */ + dw_pcie_dbi_write_enable(pci, true); + /* program correct class for RC */ + writew(PCI_CLASS_BRIDGE_PCI, pci->dbi_base + PCI_CLASS_DEVICE); + /* Better disable write permission right after the update */ + dw_pcie_dbi_write_enable(pci, false); + + val = readl(pci->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); + val |= PORT_LOGIC_SPEED_CHANGE; + writel(val, pci->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); +} + +static int pcie_am654_set_mode(struct pcie_dw_ti *pci, + enum dw_pcie_device_mode mode) +{ + struct regmap *syscon; + u32 val; + u32 mask; + int ret; + + syscon = syscon_regmap_lookup_by_phandle(pci->dev, + "ti,syscon-pcie-mode"); + if (IS_ERR(syscon)) + return 0; + + mask = AM654_PCIE_DEV_TYPE_MASK; + + switch (mode) { + case DW_PCIE_RC_TYPE: + val = RC; + break; + case DW_PCIE_EP_TYPE: + val = EP; + break; + default: + dev_err(pci->dev, "INVALID device type %d\n", mode); + return -EINVAL; + } + + ret = regmap_update_bits(syscon, 0, mask, val); + if (ret) { + dev_err(pci->dev, "failed to set pcie mode\n"); + return ret; + } + + return 0; +} + +static int pcie_dw_init_id(struct pcie_dw_ti *pci) +{ + struct regmap *devctrl_regs; + unsigned int id; + int ret; + + devctrl_regs = syscon_regmap_lookup_by_phandle(pci->dev, + "ti,syscon-pcie-id"); + if (IS_ERR(devctrl_regs)) + return PTR_ERR(devctrl_regs); + + ret = regmap_read(devctrl_regs, 0, &id); + if (ret) + return ret; + + dw_pcie_dbi_write_enable(pci, true); + writew(id & PCIE_VENDORID_MASK, pci->dbi_base + PCI_VENDOR_ID); + writew(id >> PCIE_DEVICEID_SHIFT, pci->dbi_base + PCI_DEVICE_ID); + dw_pcie_dbi_write_enable(pci, false); + + return 0; +} + +/** + * pcie_dw_ti_probe() - Probe the PCIe bus for active link + * + * @dev: A pointer to the device being operated on + * + * Probe for an active link on the PCIe bus and configure the controller + * to enable this port. + * + * Return: 0 on success, else -ENODEV + */ +static int pcie_dw_ti_probe(struct udevice *dev) +{ + struct pcie_dw_ti *pci = dev_get_priv(dev); + struct udevice *ctlr = pci_get_controller(dev); + struct pci_controller *hose = dev_get_uclass_priv(ctlr); + struct power_domain pci_pwrdmn; + struct phy phy0, phy1; + int ret; + + ret = power_domain_get_by_index(dev, &pci_pwrdmn, 0); + if (ret) { + dev_err(dev, "failed to get power domain\n"); + return ret; + } + + ret = power_domain_on(&pci_pwrdmn); + if (ret) { + dev_err(dev, "Power domain on failed\n"); + return ret; + } + + ret = generic_phy_get_by_name(dev, "pcie-phy0", &phy0); + if (ret) { + dev_err(dev, "Unable to get phy0"); + return ret; + } + generic_phy_reset(&phy0); + generic_phy_init(&phy0); + generic_phy_power_on(&phy0); + + ret = generic_phy_get_by_name(dev, "pcie-phy1", &phy1); + if (ret) { + dev_err(dev, "Unable to get phy1"); + return ret; + } + generic_phy_reset(&phy1); + generic_phy_init(&phy1); + generic_phy_power_on(&phy1); + + pci->first_busno = dev->seq; + pci->dev = dev; + + pcie_dw_setup_host(pci); + pcie_dw_init_id(pci); + + if (device_is_compatible(dev, "ti,am654-pcie-rc")) + pcie_am654_set_mode(pci, DW_PCIE_RC_TYPE); + + if (!pcie_dw_ti_pcie_link_up(pci, LINK_SPEED_GEN_2)) { + printf("PCIE-%d: Link down\n", dev->seq); + return -ENODEV; + } + + printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev->seq, + pcie_dw_get_link_speed(pci), + pcie_dw_get_link_width(pci), + hose->first_busno); + + /* Store the IO and MEM windows settings for future use by the ATU */ + pci->io.phys_start = hose->regions[0].phys_start; /* IO base */ + pci->io.bus_start = hose->regions[0].bus_start; /* IO_bus_addr */ + pci->io.size = hose->regions[0].size; /* IO size */ + + pci->mem.phys_start = hose->regions[1].phys_start; /* MEM base */ + pci->mem.bus_start = hose->regions[1].bus_start; /* MEM_bus_addr */ + pci->mem.size = hose->regions[1].size; /* MEM size */ + + pcie_dw_prog_outbound_atu_unroll(pci, PCIE_ATU_REGION_INDEX0, + PCIE_ATU_TYPE_MEM, + pci->mem.phys_start, + pci->mem.bus_start, pci->mem.size); + + return 0; +} + +/** + * pcie_dw_ti_ofdata_to_platdata() - Translate from DT to device state + * + * @dev: A pointer to the device being operated on + * + * Translate relevant data from the device tree pertaining to device @dev into + * state that the driver will later make use of. This state is stored in the + * device's private data structure. + * + * Return: 0 on success, else -EINVAL + */ +static int pcie_dw_ti_ofdata_to_platdata(struct udevice *dev) +{ + struct pcie_dw_ti *pcie = dev_get_priv(dev); + + /* Get the controller base address */ + pcie->dbi_base = (void *)dev_read_addr_name(dev, "dbics"); + if ((fdt_addr_t)pcie->dbi_base == FDT_ADDR_T_NONE) + return -EINVAL; + + /* Get the config space base address and size */ + pcie->cfg_base = (void *)dev_read_addr_size_name(dev, "config", + &pcie->cfg_size); + if ((fdt_addr_t)pcie->cfg_base == FDT_ADDR_T_NONE) + return -EINVAL; + + /* Get the iATU base address and size */ + pcie->atu_base = (void *)dev_read_addr_name(dev, "atu"); + if ((fdt_addr_t)pcie->atu_base == FDT_ADDR_T_NONE) + return -EINVAL; + + /* Get the app base address and size */ + pcie->app_base = (void *)dev_read_addr_name(dev, "app"); + if ((fdt_addr_t)pcie->app_base == FDT_ADDR_T_NONE) + return -EINVAL; + + return 0; +} + +static const struct dm_pci_ops pcie_dw_ti_ops = { + .read_config = pcie_dw_ti_read_config, + .write_config = pcie_dw_ti_write_config, +}; + +static const struct udevice_id pcie_dw_ti_ids[] = { + { .compatible = "ti,am654-pcie-rc" }, + { } +}; + +U_BOOT_DRIVER(pcie_dw_ti) = { + .name = "pcie_dw_ti", + .id = UCLASS_PCI, + .of_match = pcie_dw_ti_ids, + .ops = &pcie_dw_ti_ops, + .ofdata_to_platdata = pcie_dw_ti_ofdata_to_platdata, + .probe = pcie_dw_ti_probe, + .priv_auto_alloc_size = sizeof(struct pcie_dw_ti), +}; diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 8209ca7..3942f03 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -108,6 +108,15 @@ config SPL_PIPE3_PHY This PHY is found on omap devices supporting SATA such as dra7, am57x and omap5 +config AM654_PHY + tristate "TI AM654 SERDES support" + depends on PHY && ARCH_K3 + select REGMAP + select SYSCON + help + This option enables support for TI AM654 SerDes PHY used for + PCIe. + config STI_USB_PHY bool "STMicroelectronics USB2 picoPHY driver for STiH407 family" depends on PHY && ARCH_STI diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index b9f5195..3157f1b 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_BCM6358_USBH_PHY) += bcm6358-usbh-phy.o obj-$(CONFIG_BCM6368_USBH_PHY) += bcm6368-usbh-phy.o obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o +obj-$(CONFIG_AM654_PHY) += phy-ti-am654.o obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o obj-$(CONFIG_PHY_RCAR_GEN3) += phy-rcar-gen3.o diff --git a/drivers/phy/phy-ti-am654.c b/drivers/phy/phy-ti-am654.c new file mode 100644 index 0000000..3949012 --- /dev/null +++ b/drivers/phy/phy-ti-am654.c @@ -0,0 +1,411 @@ +// SPDX-License-Identifier: GPL-2.0+ +/** + * PCIe SERDES driver for AM654x SoC + * + * Copyright (C) 2018 Texas Instruments + * Author: Kishon Vijay Abraham I <kishon@ti.com> + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <dm/device.h> +#include <dm/lists.h> +#include <dt-bindings/phy/phy.h> +#include <generic-phy.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <power-domain.h> +#include <regmap.h> +#include <syscon.h> + +#define CMU_R07C 0x7c +#define CMU_MASTER_CDN_O BIT(24) + +#define COMLANE_R138 0xb38 +#define CONFIG_VERSION_REG_MASK GENMASK(23, 16) +#define CONFIG_VERSION_REG_SHIFT 16 +#define VERSION 0x70 + +#define COMLANE_R190 0xb90 +#define L1_MASTER_CDN_O BIT(9) + +#define COMLANE_R194 0xb94 +#define CMU_OK_I_0 BIT(19) + +#define SERDES_CTRL 0x1fd0 +#define POR_EN BIT(29) + +#define WIZ_LANEXCTL_STS 0x1fe0 +#define TX0_ENABLE_OVL BIT(31) +#define TX0_ENABLE_MASK GENMASK(30, 29) +#define TX0_ENABLE_SHIFT 29 +#define TX0_DISABLE_STATE 0x0 +#define TX0_SLEEP_STATE 0x1 +#define TX0_SNOOZE_STATE 0x2 +#define TX0_ENABLE_STATE 0x3 +#define RX0_ENABLE_OVL BIT(15) +#define RX0_ENABLE_MASK GENMASK(14, 13) +#define RX0_ENABLE_SHIFT 13 +#define RX0_DISABLE_STATE 0x0 +#define RX0_SLEEP_STATE 0x1 +#define RX0_SNOOZE_STATE 0x2 +#define RX0_ENABLE_STATE 0x3 + +#define WIZ_PLL_CTRL 0x1ff4 +#define PLL_ENABLE_OVL BIT(31) +#define PLL_ENABLE_MASK GENMASK(30, 29) +#define PLL_ENABLE_SHIFT 29 +#define PLL_DISABLE_STATE 0x0 +#define PLL_SLEEP_STATE 0x1 +#define PLL_SNOOZE_STATE 0x2 +#define PLL_ENABLE_STATE 0x3 +#define PLL_OK BIT(28) + +#define PLL_LOCK_TIME 1000 /* in milliseconds */ +#define SLEEP_TIME 100 /* in microseconds */ + +#define LANE_USB3 0x0 +#define LANE_PCIE0_LANE0 0x1 + +#define LANE_PCIE1_LANE0 0x0 +#define LANE_PCIE0_LANE1 0x1 + +#define SERDES_NUM_CLOCKS 3 + +/* SERDES control MMR bit offsets */ +#define SERDES_CTL_LANE_FUNC_SEL_SHIFT 0 +#define SERDES_CTL_LANE_FUNC_SEL_MASK GENMASK(1, 0) +#define SERDES_CTL_CLK_SEL_SHIFT 4 +#define SERDES_CTL_CLK_SEL_MASK GENMASK(7, 4) + +/** + * struct serdes_am654_mux_clk_data - clock controller information structure + */ +struct serdes_am654_mux_clk_data { + struct regmap *regmap; + struct clk_bulk parents; +}; + +static int serdes_am654_mux_clk_probe(struct udevice *dev) +{ + struct serdes_am654_mux_clk_data *data = dev_get_priv(dev); + struct udevice *syscon; + struct regmap *regmap; + int ret; + + debug("%s(dev=%s)\n", __func__, dev->name); + + if (!data) + return -ENOMEM; + + ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, + "ti,serdes-clk", &syscon); + if (ret) { + dev_err(dev, "unable to find syscon device\n"); + return ret; + } + + regmap = syscon_get_regmap(syscon); + if (IS_ERR(regmap)) { + dev_err(dev, "Fail to get Syscon regmap\n"); + return PTR_ERR(regmap); + } + + data->regmap = regmap; + + ret = clk_get_bulk(dev, &data->parents); + if (ret) { + dev_err(dev, "Failed to obtain parent clocks\n"); + return ret; + } + + return 0; +} + +static int mux_table[SERDES_NUM_CLOCKS][3] = { + /* + * The entries represent values for selecting between + * {left input, external reference clock, right input} + * Only one of Left Output or Right Output should be used since + * both left and right output clock uses the same bits and modifying + * one clock will impact the other. + */ + { BIT(2), 0, BIT(0) }, /* Mux of CMU refclk */ + { -1, BIT(3), BIT(1) }, /* Mux of Left Output */ + { BIT(1), BIT(3) | BIT(1), -1 }, /* Mux of Right Output */ +}; + +static int serdes_am654_mux_clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct serdes_am654_mux_clk_data *data = dev_get_priv(clk->dev); + u32 val; + int i; + + debug("%s(clk=%s, parent=%s)\n", __func__, clk->dev->name, + parent->dev->name); + + /* + * Since we have the same device-tree node represent both the + * clock and serdes device, we have two devices associated with + * the serdes node. assigned-clocks for this node is processed twice, + * once for the clock device and another time for the serdes + * device. When it is processed for the clock device, it is before + * the probe for clock device has been called. We ignore this case + * and rely on assigned-clocks to be processed correctly for the + * serdes case. + */ + if (!data->regmap) + return 0; + + for (i = 0; i < data->parents.count; i++) { + if (clk_is_match(&data->parents.clks[i], parent)) + break; + } + + if (i >= data->parents.count) + return -EINVAL; + + val = mux_table[clk->id][i]; + val <<= SERDES_CTL_CLK_SEL_SHIFT; + + regmap_update_bits(data->regmap, 0, SERDES_CTL_CLK_SEL_MASK, val); + + return 0; +} + +static struct clk_ops serdes_am654_mux_clk_ops = { + .set_parent = serdes_am654_mux_clk_set_parent, +}; + +U_BOOT_DRIVER(serdes_am654_mux_clk) = { + .name = "ti-serdes-am654-mux-clk", + .id = UCLASS_CLK, + .probe = serdes_am654_mux_clk_probe, + .priv_auto_alloc_size = sizeof(struct serdes_am654_mux_clk_data), + .ops = &serdes_am654_mux_clk_ops, +}; + +struct serdes_am654 { + struct regmap *regmap; + struct regmap *serdes_ctl; +}; + +static int serdes_am654_enable_pll(struct serdes_am654 *phy) +{ + u32 mask = PLL_ENABLE_OVL | PLL_ENABLE_MASK; + u32 val = PLL_ENABLE_OVL | (PLL_ENABLE_STATE << PLL_ENABLE_SHIFT); + + regmap_update_bits(phy->regmap, WIZ_PLL_CTRL, mask, val); + + return regmap_read_poll_timeout(phy->regmap, WIZ_PLL_CTRL, val, + val & PLL_OK, 1000, PLL_LOCK_TIME); +} + +static void serdes_am654_disable_pll(struct serdes_am654 *phy) +{ + u32 mask = PLL_ENABLE_OVL | PLL_ENABLE_MASK; + + regmap_update_bits(phy->regmap, WIZ_PLL_CTRL, mask, 0); +} + +static int serdes_am654_enable_txrx(struct serdes_am654 *phy) +{ + u32 mask; + u32 val; + + /* Enable TX */ + mask = TX0_ENABLE_OVL | TX0_ENABLE_MASK; + val = TX0_ENABLE_OVL | (TX0_ENABLE_STATE << TX0_ENABLE_SHIFT); + regmap_update_bits(phy->regmap, WIZ_LANEXCTL_STS, mask, val); + + /* Enable RX */ + mask = RX0_ENABLE_OVL | RX0_ENABLE_MASK; + val = RX0_ENABLE_OVL | (RX0_ENABLE_STATE << RX0_ENABLE_SHIFT); + regmap_update_bits(phy->regmap, WIZ_LANEXCTL_STS, mask, val); + + return 0; +} + +static int serdes_am654_disable_txrx(struct serdes_am654 *phy) +{ + u32 mask; + + /* Disable TX */ + mask = TX0_ENABLE_OVL | TX0_ENABLE_MASK; + regmap_update_bits(phy->regmap, WIZ_LANEXCTL_STS, mask, 0); + + /* Disable RX */ + mask = RX0_ENABLE_OVL | RX0_ENABLE_MASK; + regmap_update_bits(phy->regmap, WIZ_LANEXCTL_STS, mask, 0); + + return 0; +} + +static int serdes_am654_power_on(struct phy *x) +{ + struct serdes_am654 *phy = dev_get_priv(x->dev); + int ret; + u32 val; + + ret = serdes_am654_enable_pll(phy); + if (ret) { + dev_err(x->dev, "Failed to enable PLL\n"); + return ret; + } + + ret = serdes_am654_enable_txrx(phy); + if (ret) { + dev_err(x->dev, "Failed to enable TX RX\n"); + return ret; + } + + return regmap_read_poll_timeout(phy->regmap, COMLANE_R194, val, + val & CMU_OK_I_0, SLEEP_TIME, + PLL_LOCK_TIME); +} + +static int serdes_am654_power_off(struct phy *x) +{ + struct serdes_am654 *phy = dev_get_priv(x->dev); + + serdes_am654_disable_txrx(phy); + serdes_am654_disable_pll(phy); + + return 0; +} + +static int serdes_am654_init(struct phy *x) +{ + struct serdes_am654 *phy = dev_get_priv(x->dev); + u32 mask; + u32 val; + + mask = CONFIG_VERSION_REG_MASK; + val = VERSION << CONFIG_VERSION_REG_SHIFT; + regmap_update_bits(phy->regmap, COMLANE_R138, mask, val); + + val = CMU_MASTER_CDN_O; + regmap_update_bits(phy->regmap, CMU_R07C, val, val); + + val = L1_MASTER_CDN_O; + regmap_update_bits(phy->regmap, COMLANE_R190, val, val); + + return 0; +} + +static int serdes_am654_reset(struct phy *x) +{ + struct serdes_am654 *phy = dev_get_priv(x->dev); + u32 val; + + val = POR_EN; + regmap_update_bits(phy->regmap, SERDES_CTRL, val, val); + mdelay(1); + regmap_update_bits(phy->regmap, SERDES_CTRL, val, 0); + + return 0; +} + +static int serdes_am654_of_xlate(struct phy *x, + struct ofnode_phandle_args *args) +{ + struct serdes_am654 *phy = dev_get_priv(x->dev); + + if (args->args_count != 2) { + dev_err(phy->dev, "Invalid DT PHY argument count: %d\n", + args->args_count); + return -EINVAL; + } + + if (args->args[0] != PHY_TYPE_PCIE) { + dev_err(phy->dev, "Unrecognized PHY type: %d\n", + args->args[0]); + return -EINVAL; + } + + x->id = args->args[0] | (args->args[1] << 16); + + /* Setup mux mode using second argument */ + regmap_update_bits(phy->serdes_ctl, 0, SERDES_CTL_LANE_FUNC_SEL_MASK, + args->args[1]); + + return 0; +} + +static int serdes_am654_bind(struct udevice *dev) +{ + int ret; + + ret = device_bind_driver_to_node(dev->parent, + "ti-serdes-am654-mux-clk", + dev_read_name(dev), dev->node, + NULL); + if (ret) { + dev_err(dev, "%s: not able to bind clock driver\n", __func__); + return ret; + } + + return 0; +} + +static int serdes_am654_probe(struct udevice *dev) +{ + struct serdes_am654 *phy = dev_get_priv(dev); + struct power_domain serdes_pwrdmn; + struct regmap *serdes_ctl; + struct regmap *map; + int ret; + + ret = regmap_init_mem(dev_ofnode(dev), &map); + if (ret) + return ret; + + phy->regmap = map; + + serdes_ctl = syscon_regmap_lookup_by_phandle(dev, "ti,serdes-clk"); + if (IS_ERR(serdes_ctl)) { + dev_err(dev, "unable to find syscon device\n"); + return PTR_ERR(serdes_ctl); + } + + phy->serdes_ctl = serdes_ctl; + + ret = power_domain_get_by_index(dev, &serdes_pwrdmn, 0); + if (ret) { + dev_err(dev, "failed to get power domain\n"); + return ret; + } + + ret = power_domain_on(&serdes_pwrdmn); + if (ret) { + dev_err(dev, "Power domain on failed\n"); + return ret; + } + + return 0; +} + +static const struct udevice_id serdes_am654_phy_ids[] = { + { + .compatible = "ti,phy-am654-serdes", + }, +}; + +static const struct phy_ops serdes_am654_phy_ops = { + .reset = serdes_am654_reset, + .init = serdes_am654_init, + .power_on = serdes_am654_power_on, + .power_off = serdes_am654_power_off, + .of_xlate = serdes_am654_of_xlate, +}; + +U_BOOT_DRIVER(am654_serdes_phy) = { + .name = "am654_serdes_phy", + .id = UCLASS_PHY, + .of_match = serdes_am654_phy_ids, + .bind = serdes_am654_bind, + .ops = &serdes_am654_phy_ops, + .probe = serdes_am654_probe, + .priv_auto_alloc_size = sizeof(struct serdes_am654), +}; diff --git a/drivers/power/domain/ti-sci-power-domain.c b/drivers/power/domain/ti-sci-power-domain.c index b9cd37b..4c4351d 100644 --- a/drivers/power/domain/ti-sci-power-domain.c +++ b/drivers/power/domain/ti-sci-power-domain.c @@ -68,8 +68,8 @@ static int ti_sci_power_domain_on(struct power_domain *pd) ret = dops->get_device(sci, pd->id); if (ret) - dev_err(power_domain->dev, "%s: get_device failed (%d)\n", - __func__, ret); + dev_err(pd->dev, "%s: get_device(%lu) failed (%d)\n", + __func__, pd->id, ret); return ret; } @@ -85,8 +85,8 @@ static int ti_sci_power_domain_off(struct power_domain *pd) ret = dops->put_device(sci, pd->id); if (ret) - dev_err(power_domain->dev, "%s: put_device failed (%d)\n", - __func__, ret); + dev_err(pd->dev, "%s: put_device(%lu) failed (%d)\n", + __func__, pd->id, ret); return ret; } diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 1e5d14c..a66a9bc 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -28,7 +28,6 @@ config OMAP_WATCHDOG bool "TI OMAP watchdog driver" depends on ARCH_OMAP2PLUS select HW_WATCHDOG - default y if AM33XX help Say Y here to enable the OMAP3+ watchdog driver. @@ -113,6 +112,14 @@ config WDT_MTK The watchdog timer is stopped when initialized. It performs full SoC reset. +config WDT_OMAP3 + bool "TI OMAP watchdog timer support" + depends on WDT && ARCH_OMAP2PLUS + default y if AM33XX + help + This enables OMAP3+ watchdog timer driver, which can be + found on some TI chipsets and inline with driver model. + config WDT_ORION bool "Orion watchdog timer support" depends on WDT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 414ba24..955caef 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o obj-$(CONFIG_WDT_MTK) += mtk_wdt.o +obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o obj-$(CONFIG_WDT_SP805) += sp805_wdt.o obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 343adb0..d5857be 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c @@ -42,10 +42,14 @@ #include <asm/io.h> #include <asm/processor.h> #include <asm/arch/cpu.h> +#include <wdt.h> +#include <dm.h> +#include <errno.h> /* Hardware timeout in seconds */ #define WDT_HW_TIMEOUT 60 +#if !CONFIG_IS_ENABLED(WDT) static unsigned int wdt_trgr_pattern = 0x1234; void hw_watchdog_reset(void) @@ -134,3 +138,120 @@ void hw_watchdog_init(void) while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR) ; } + +void watchdog_reset(void) +{ + hw_watchdog_reset(); +} + +#else + +static int omap3_wdt_reset(struct udevice *dev) +{ + struct omap3_wdt_priv *priv = dev_get_priv(dev); + + priv->wdt_trgr_pattern = 0x1234; +/* + * Somebody just triggered watchdog reset and write to WTGR register + * is in progress. It is resetting right now, no need to trigger it + * again + */ + if ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WTGR) + return 0; + + priv->wdt_trgr_pattern = ~(priv->wdt_trgr_pattern); + writel(priv->wdt_trgr_pattern, &priv->regs->wdtwtgr); +/* + * Don't wait for posted write to complete, i.e. don't check + * WDT_WWPS_PEND_WTGR bit in WWPS register. There is no writes to + * WTGR register outside of this func, and if entering it + * we see WDT_WWPS_PEND_WTGR bit set, it means watchdog reset + * was just triggered. This prevents us from wasting time in busy + * polling of WDT_WWPS_PEND_WTGR bit. + */ + return 0; +} + +static int omap3_wdt_stop(struct udevice *dev) +{ + struct omap3_wdt_priv *priv = dev_get_priv(dev); + +/* disable watchdog */ + writel(0xAAAA, &priv->regs->wdtwspr); + while (readl(&priv->regs->wdtwwps) != 0x0) + ; + writel(0x5555, &priv->regs->wdtwspr); + while (readl(&priv->regs->wdtwwps) != 0x0) + ; + return 0; +} + +static int omap3_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) +{ + struct omap3_wdt_priv *priv = dev_get_priv(dev); + u32 pre_margin = GET_WLDR_VAL(timeout_ms); +/* + * Make sure the watchdog is disabled. This is unfortunately required + * because writing to various registers with the watchdog running has no + * effect. + */ + omap3_wdt_stop(dev); + +/* initialize prescaler */ + while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WCLR) + ; + + writel(WDT_WCLR_PRE | (PTV << WDT_WCLR_PTV_OFF), &priv->regs->wdtwclr); + while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WCLR) + ; +/* just count up at 32 KHz */ + while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WLDR) + ; + + writel(pre_margin, &priv->regs->wdtwldr); + while (readl(&priv->regs->wdtwwps) & WDT_WWPS_PEND_WLDR) + ; +/* Sequence to enable the watchdog */ + writel(0xBBBB, &priv->regs->wdtwspr); + while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WSPR) + ; + + writel(0x4444, &priv->regs->wdtwspr); + while ((readl(&priv->regs->wdtwwps)) & WDT_WWPS_PEND_WSPR) + ; + + return 0; +} + +static int omap3_wdt_probe(struct udevice *dev) +{ + struct omap3_wdt_priv *priv = dev_get_priv(dev); + + priv->regs = (struct wd_timer *)devfdt_get_addr(dev); + if (!priv->regs) + return -EINVAL; + + debug("%s: Probing wdt%u\n", __func__, dev->seq); + return 0; +} + +static const struct wdt_ops omap3_wdt_ops = { + .start = omap3_wdt_start, + .stop = omap3_wdt_stop, + .reset = omap3_wdt_reset, +}; + +static const struct udevice_id omap3_wdt_ids[] = { + { .compatible = "ti,omap3-wdt" }, + { } +}; + +U_BOOT_DRIVER(omap3_wdt) = { + .name = "omap3_wdt", + .id = UCLASS_WDT, + .of_match = omap3_wdt_ids, + .ops = &omap3_wdt_ops, + .probe = omap3_wdt_probe, + .priv_auto_alloc_size = sizeof(struct omap3_wdt_priv), +}; +#endif /* !CONFIG_IS_ENABLED(WDT) */ diff --git a/include/clk.h b/include/clk.h index 2ebc905..3ca2796 100644 --- a/include/clk.h +++ b/include/clk.h @@ -333,6 +333,18 @@ int clk_disable(struct clk *clk); */ int clk_disable_bulk(struct clk_bulk *bulk); +/** + * clk_is_match - check if two clk's point to the same hardware clock + * @p: clk compared against q + * @q: clk compared against p + * + * Returns true if the two struct clk pointers both point to the same hardware + * clock node. + * + * Returns false otherwise. Note that two NULL clks are treated as matching. + */ +bool clk_is_match(const struct clk *p, const struct clk *q); + int soc_clk_dump(void); /** diff --git a/include/configs/brsmarc1.h b/include/configs/brsmarc1.h new file mode 100644 index 0000000..c184458 --- /dev/null +++ b/include/configs/brsmarc1.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * brsmarc1.h + * + * specific parts for B&R BRSMARC1 Motherboard + * + * Copyright (C) 2017 Hannes Schmelzer <oe5hpm@oevsv.at> - + * B&R Industrial Automation GmbH - http://www.br-automation.com + * + */ + +#ifndef __CONFIG_BRSMARC1_H__ +#define __CONFIG_BRSMARC1_H__ + +#include <configs/bur_cfg_common.h> +#include <configs/bur_am335x_common.h> +/* ------------------------------------------------------------------------- */ +#define CONFIG_BOARD_TYPES + +/* memory */ +#define CONFIG_SYS_MALLOC_LEN (5 * 1024 * 1024) +#define CONFIG_SYS_BOOTM_LEN (32 * 1024 * 1024) + +/* Clock Defines */ +#define V_OSCK 26000000 /* Clock output from T2 */ +#define V_SCLK (V_OSCK) + +#define CONFIG_MACH_TYPE 3589 + +#ifndef CONFIG_SPL_BUILD + +/* Default environment */ +#define CONFIG_EXTRA_ENV_SETTINGS \ +BUR_COMMON_ENV \ +"autoload=0\0" \ +"scradr=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \ +"cfgscr=mw ${dtbaddr} 0;" \ +" sf probe && sf read ${scradr} 0xC0000 0x10000 && source ${scradr};" \ +" fdt addr ${dtbaddr} || cp ${fdtcontroladdr} ${dtbaddr} 4000\0" \ +"dtbaddr=0x84000000\0" \ +"loadaddr=0x82000000\0" \ +"b_break=0\0" \ +"b_tgts_std=mmc0 mmc1 def net usb0\0" \ +"b_tgts_rcy=def net usb0\0" \ +"b_tgts_pme=net usb0 mmc0 mmc1\0" \ +"b_deftgts=if test ${b_mode} = 12; then setenv b_tgts ${b_tgts_pme};" \ +" elif test ${b_mode} = 0; then setenv b_tgts ${b_tgts_rcy};" \ +" else setenv b_tgts ${b_tgts_std}; fi\0" \ +"b_mmc0=load mmc 1 ${scradr} bootscr.img && source ${scradr}\0" \ +"b_mmc1=load mmc 1 ${loadaddr} arimg.ugz && run startsys\0" \ +"b_def=sf read ${loadaddr} 100000 700000; run startsys\0" \ +"b_net=tftp ${scradr} netscript.img && source ${scradr}\0" \ +"b_usb0=usb start && load usb 0 ${scradr} bootscr.img && source ${scradr}\0" \ +"b_default=run b_deftgts; for target in ${b_tgts};"\ +" do run b_${target}; if test ${b_break} = 1; then; exit; fi; done\0" \ +"vxargs=setenv bootargs cpsw(0,0)host:vxWorks h=${serverip}" \ +" e=${ipaddr}:${netmask} g=${gatewayip} u=vxWorksFTP pw=vxWorks\0" \ +"vxfdt=fdt addr ${dtbaddr}; fdt resize 0x8000;" \ +" fdt boardsetup\0" \ +"startsys=run vxargs && mw 0x80001100 0 && run vxfdt &&" \ +" bootm ${loadaddr} - ${dtbaddr}\0" +#endif /* !CONFIG_SPL_BUILD*/ + +/* undefine command which we not need here */ +#undef CONFIG_BOOTM_NETBSD +#undef CONFIG_BOOTM_PLAN9 +#undef CONFIG_BOOTM_RTEMS + +/* Support both device trees and ATAGs. */ +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG + +/* SPI Flash */ +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x40000 + +/* Environment */ +#define CONFIG_SYS_REDUNDAND_ENVIRONMENT +#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + \ + CONFIG_ENV_SECT_SIZE) + +#define CONFIG_CONS_INDEX 1 +#endif /* __CONFIG_BRSMARC1_H__ */ diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h index ff53613..9bd6da0 100644 --- a/include/configs/da850evm.h +++ b/include/configs/da850evm.h @@ -26,7 +26,7 @@ #define CONFIG_SYS_OSCIN_FREQ 24000000 #define CONFIG_SYS_TIMERBASE DAVINCI_TIMER0_BASE #define CONFIG_SYS_HZ_CLOCK clk_get(DAVINCI_AUXCLK_CLKID) -#define CONFIG_SKIP_LOWLEVEL_INIT +#define CONFIG_SKIP_LOWLEVEL_INIT_ONLY #ifdef CONFIG_DIRECT_NOR_BOOT #define CONFIG_ARCH_CPU_INIT @@ -192,7 +192,7 @@ #ifdef CONFIG_USE_NOR #define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of flash banks */ #define CONFIG_SYS_FLASH_SECT_SZ (128 << 10) /* 128KB */ -#define CONFIG_ENV_OFFSET (CONFIG_SYS_FLASH_SECT_SZ * 3) +#define CONFIG_ENV_OFFSET (SZ_1M) #define CONFIG_ENV_SIZE (10 << 10) /* 10KB */ #define CONFIG_SYS_FLASH_BASE DAVINCI_ASYNC_EMIF_DATA_CE2_BASE #define PHYS_FLASH_SIZE (8 << 20) /* Flash size 8MB */ diff --git a/include/dm/fdtaddr.h b/include/dm/fdtaddr.h index 3bc2599..57b326c 100644 --- a/include/dm/fdtaddr.h +++ b/include/dm/fdtaddr.h @@ -120,4 +120,22 @@ fdt_addr_t devfdt_get_addr_size_index(struct udevice *dev, int index, */ fdt_addr_t devfdt_get_addr_name(struct udevice *dev, const char *name); +/** + * devfdt_get_addr_size_name() - Get the reg property and its size for a device, + * indexed by name + * + * Returns the address and size specified in the 'reg' property of a device. + * + * @dev: Pointer to a device + * @name: the 'reg' property can hold a list of <addr, size> pairs, with the + * 'reg-names' property providing named-based identification. @index + * indicates the value to search for in 'reg-names'. + * @size: Pointer to size variable - this function returns the size + * specified in the 'reg' property here + * + * @return addr + */ +fdt_addr_t devfdt_get_addr_size_name(struct udevice *dev, const char *name, + fdt_size_t *size); + #endif diff --git a/include/dm/read.h b/include/dm/read.h index 6ecd062..0c62d62 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -145,6 +145,19 @@ int dev_read_size(struct udevice *dev, const char *propname); fdt_addr_t dev_read_addr_index(struct udevice *dev, int index); /** + * dev_read_addr_size_index() - Get the indexed reg property of a device + * + * @dev: Device to read from + * @index: the 'reg' property can hold a list of <addr, size> pairs + * and @index is used to select which one is required + * @size: place to put size value (on success) + * + * @return address or FDT_ADDR_T_NONE if not found + */ +fdt_addr_t dev_read_addr_size_index(struct udevice *dev, int index, + fdt_size_t *size); + +/** * dev_remap_addr_index() - Get the indexed reg property of a device * as a memory-mapped I/O pointer * @@ -169,6 +182,20 @@ void *dev_remap_addr_index(struct udevice *dev, int index); fdt_addr_t dev_read_addr_name(struct udevice *dev, const char* name); /** + * dev_read_addr_size_name() - Get the reg property of a device, indexed by name + * + * @dev: Device to read from + * @name: the 'reg' property can hold a list of <addr, size> pairs, with the + * 'reg-names' property providing named-based identification. @index + * indicates the value to search for in 'reg-names'. + * @size: place to put size value (on success) + * + * @return address or FDT_ADDR_T_NONE if not found + */ +fdt_addr_t dev_read_addr_size_name(struct udevice *dev, const char *name, + fdt_size_t *size); + +/** * dev_remap_addr_name() - Get the reg property of a device, indexed by name, * as a memory-mapped I/O pointer * @@ -601,12 +628,26 @@ static inline fdt_addr_t dev_read_addr_index(struct udevice *dev, int index) return devfdt_get_addr_index(dev, index); } +static inline fdt_addr_t dev_read_addr_size_index(struct udevice *dev, + int index, + fdt_size_t *size) +{ + return devfdt_get_addr_size_index(dev, index, size); +} + static inline fdt_addr_t dev_read_addr_name(struct udevice *dev, const char *name) { return devfdt_get_addr_name(dev, name); } +static inline fdt_addr_t dev_read_addr_size_name(struct udevice *dev, + const char *name, + fdt_size_t *size) +{ + return devfdt_get_addr_size_name(dev, name, size); +} + static inline fdt_addr_t dev_read_addr(struct udevice *dev) { return devfdt_get_addr(dev); diff --git a/include/dt-bindings/phy/phy-am654-serdes.h b/include/dt-bindings/phy/phy-am654-serdes.h new file mode 100644 index 0000000..e8d9017 --- /dev/null +++ b/include/dt-bindings/phy/phy-am654-serdes.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This header provides constants for AM654 SERDES. + */ + +#ifndef _DT_BINDINGS_AM654_SERDES +#define _DT_BINDINGS_AM654_SERDES + +#define AM654_SERDES_CMU_REFCLK 0 +#define AM654_SERDES_LO_REFCLK 1 +#define AM654_SERDES_RO_REFCLK 2 + +#endif /* _DT_BINDINGS_AM654_SERDES */ diff --git a/include/watchdog.h b/include/watchdog.h index 3a357de..a4a4e8e 100644 --- a/include/watchdog.h +++ b/include/watchdog.h @@ -77,7 +77,7 @@ int init_func_watchdog_reset(void); * Prototypes from $(CPU)/cpu.c. */ -#if defined(CONFIG_HW_WATCHDOG) && !defined(__ASSEMBLY__) +#if (defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)) && !defined(__ASSEMBLY__) void hw_watchdog_init(void); #endif diff --git a/test/dm/clk.c b/test/dm/clk.c index f301ecb..676ef21 100644 --- a/test/dm/clk.c +++ b/test/dm/clk.c @@ -24,6 +24,7 @@ static int dm_test_clk_base(struct unit_test_state *uts) /* Get the same clk port in 2 different ways and compare */ ut_assertok(clk_get_by_index(dev, 1, &clk_method1)); ut_assertok(clk_get_by_index_nodev(dev_ofnode(dev), 1, &clk_method2)); + ut_asserteq(clk_is_match(&clk_method1, &clk_method2), true); ut_asserteq(clk_method1.id, clk_method2.id); return 0; diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index ad85916..1fb8b5c 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -549,12 +549,14 @@ static int dm_test_fdt_remap_addr_index_flat(struct unit_test_state *uts) { struct udevice *dev; fdt_addr_t addr; + fdt_size_t size; void *paddr; ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev)); - addr = devfdt_get_addr_index(dev, 0); + addr = devfdt_get_addr_size_index(dev, 0, &size); ut_asserteq(0x8000, addr); + ut_asserteq(0x1000, size); paddr = map_physmem(addr, 0, MAP_NOCACHE); ut_assertnonnull(paddr); @@ -569,12 +571,14 @@ static int dm_test_fdt_remap_addr_name_flat(struct unit_test_state *uts) { struct udevice *dev; fdt_addr_t addr; + fdt_size_t size; void *paddr; ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev)); - addr = devfdt_get_addr_name(dev, "sandbox-dummy-0"); + addr = devfdt_get_addr_size_name(dev, "sandbox-dummy-0", &size); ut_asserteq(0x8000, addr); + ut_asserteq(0x1000, size); paddr = map_physmem(addr, 0, MAP_NOCACHE); ut_assertnonnull(paddr); @@ -609,12 +613,14 @@ static int dm_test_fdt_remap_addr_index_live(struct unit_test_state *uts) { struct udevice *dev; fdt_addr_t addr; + fdt_size_t size; void *paddr; ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev)); - addr = dev_read_addr_index(dev, 0); + addr = dev_read_addr_size_index(dev, 0, &size); ut_asserteq(0x8000, addr); + ut_asserteq(0x1000, size); paddr = map_physmem(addr, 0, MAP_NOCACHE); ut_assertnonnull(paddr); @@ -629,12 +635,14 @@ static int dm_test_fdt_remap_addr_name_live(struct unit_test_state *uts) { struct udevice *dev; fdt_addr_t addr; + fdt_size_t size; void *paddr; ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_DUMMY, 0, true, &dev)); - addr = dev_read_addr_name(dev, "sandbox-dummy-0"); + addr = dev_read_addr_size_name(dev, "sandbox-dummy-0", &size); ut_asserteq(0x8000, addr); + ut_asserteq(0x1000, size); paddr = map_physmem(addr, 0, MAP_NOCACHE); ut_assertnonnull(paddr); |