diff options
391 files changed, 16455 insertions, 2336 deletions
diff --git a/.travis.yml b/.travis.yml index fe2dfce9bf3..321fd793a75 100644 --- a/.travis.yml +++ b/.travis.yml @@ -336,6 +336,10 @@ matrix: - name: "Check for configs without MAINTAINERS entry" script: - if [ `./tools/genboardscfg.py -f 2>&1 | wc -l` -ne 0 ]; then exit 1; fi + # Ensure host tools build + - name: "Build tools-only" + script: + - make tools-only_config tools-only -j$(nproc) # test/py - name: "test/py sandbox" @@ -126,6 +126,7 @@ config SYS_BOOT_GET_KBD config SYS_MALLOC_F bool "Enable malloc() pool before relocation" default y if DM + help Before relocation, memory is very limited on many platforms. Still, we can provide a small malloc() pool if needed. Driver model in @@ -136,6 +137,7 @@ config SYS_MALLOC_F_LEN hex "Size of malloc() pool before relocation" depends on SYS_MALLOC_F default 0x1000 if AM33XX + default 0x2800 if SANDBOX default 0x400 help Before relocation, memory is very limited on many platforms. Still, diff --git a/MAINTAINERS b/MAINTAINERS index 0cec39c542d..ae825014bda 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -512,6 +512,24 @@ S: Maintained T: git git://git.denx.de/u-boot-mips.git F: arch/mips/ +MIPS MSCC +M: Gregory CLEMENT <gregory.clement@bootlin.com> +M: Lars Povlsen <lars.povlsen@microchip.com> +M: Horatiu Vultur <horatiu.vultur@microchip.com> +S: Maintained +F: arch/mips/mach-mscc/ +F: arch/mips/dts/luton* +F: arch/mips/dts/mscc* +F: arch/mips/dts/ocelot* +F: board/mscc/ +F: configs/mscc* +F: include/configs/vcoreiii.h + +MIPS JZ4780 +M: Ezequiel Garcia <ezequiel@collabora.com> +S: Maintained +F: arch/mips/mach-jz47xx/ + MMC M: Jaehoon Chung <jh80.chung@samsung.com> S: Maintained @@ -719,5 +737,6 @@ L: u-boot@lists.denx.de Q: http://patchwork.ozlabs.org/project/uboot/list/ S: Maintained T: git git://git.denx.de/u-boot.git +F: configs/tools-only_defconfig F: * F: */ @@ -3,7 +3,7 @@ VERSION = 2019 PATCHLEVEL = 01 SUBLEVEL = -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 NAME = # *DOCUMENTATION* @@ -724,8 +724,7 @@ libs-y += common/ libs-y += env/ libs-$(CONFIG_API) += api/ libs-$(CONFIG_HAS_POST) += post/ -libs-y += test/ -libs-y += test/dm/ +libs-$(CONFIG_UNIT_TEST) += test/ test/dm/ libs-$(CONFIG_UT_ENV) += test/env/ libs-$(CONFIG_UT_OVERLAY) += test/overlay/ @@ -913,47 +912,47 @@ cmd_cfgcheck = $(srctree)/scripts/check-config.sh $2 \ all: $(ALL-y) cfg ifeq ($(CONFIG_DM_I2C_COMPAT)$(CONFIG_SANDBOX),y) - @echo "===================== WARNING ======================" - @echo "This board uses CONFIG_DM_I2C_COMPAT. Please remove" - @echo "(possibly in a subsequent patch in your series)" - @echo "before sending patches to the mailing list." - @echo "====================================================" + @echo >&2 "===================== WARNING ======================" + @echo >&2 "This board uses CONFIG_DM_I2C_COMPAT. Please remove" + @echo >&2 "(possibly in a subsequent patch in your series)" + @echo >&2 "before sending patches to the mailing list." + @echo >&2 "====================================================" endif ifeq ($(CONFIG_MMC),y) ifneq ($(CONFIG_DM_MMC)$(CONFIG_OF_CONTROL)$(CONFIG_BLK),yyy) - @echo "===================== WARNING ======================" - @echo "This board does not use CONFIG_DM_MMC. Please update" - @echo "the board to use CONFIG_DM_MMC before the v2019.04 release." - @echo "Failure to update by the deadline may result in board removal." - @echo "See doc/driver-model/MIGRATION.txt for more info." - @echo "====================================================" + @echo >&2 "===================== WARNING ======================" + @echo >&2 "This board does not use CONFIG_DM_MMC. Please update" + @echo >&2 "the board to use CONFIG_DM_MMC before the v2019.04 release." + @echo >&2 "Failure to update by the deadline may result in board removal." + @echo >&2 "See doc/driver-model/MIGRATION.txt for more info." + @echo >&2 "====================================================" endif endif ifeq ($(CONFIG_USB),y) ifneq ($(CONFIG_DM_USB)$(CONFIG_OF_CONTROL)$(CONFIG_BLK),yyy) - @echo "===================== WARNING ======================" - @echo "This board does not use CONFIG_DM_USB. Please update" - @echo "the board to use CONFIG_DM_USB before the v2019.07 release." - @echo "Failure to update by the deadline may result in board removal." - @echo "See doc/driver-model/MIGRATION.txt for more info." - @echo "====================================================" + @echo >&2 "===================== WARNING ======================" + @echo >&2 "This board does not use CONFIG_DM_USB. Please update" + @echo >&2 "the board to use CONFIG_DM_USB before the v2019.07 release." + @echo >&2 "Failure to update by the deadline may result in board removal." + @echo >&2 "See doc/driver-model/MIGRATION.txt for more info." + @echo >&2 "====================================================" endif endif ifeq ($(CONFIG_LIBATA)$(CONFIG_DM_SCSI)$(CONFIG_MVSATA_IDE),y) - @echo "===================== WARNING ======================" - @echo "This board does not use CONFIG_DM_SCSI. Please update" - @echo "the storage controller to use CONFIG_DM_SCSI before the v2019.07 release." - @echo "Failure to update by the deadline may result in board removal." - @echo "See doc/driver-model/MIGRATION.txt for more info." - @echo "====================================================" + @echo >&2 "===================== WARNING ======================" + @echo >&2 "This board does not use CONFIG_DM_SCSI. Please update" + @echo >&2 "the storage controller to use CONFIG_DM_SCSI before the v2019.07 release." + @echo >&2 "Failure to update by the deadline may result in board removal." + @echo >&2 "See doc/driver-model/MIGRATION.txt for more info." + @echo >&2 "====================================================" endif ifeq ($(CONFIG_OF_EMBED),y) - @echo "===================== WARNING ======================" - @echo "CONFIG_OF_EMBED is enabled. This option should only" - @echo "be used for debugging purposes. Please use" - @echo "CONFIG_OF_SEPARATE for boards in mainline." - @echo "See doc/README.fdt-control for more info." - @echo "====================================================" + @echo >&2 "===================== WARNING ======================" + @echo >&2 "CONFIG_OF_EMBED is enabled. This option should only" + @echo >&2 "be used for debugging purposes. Please use" + @echo >&2 "CONFIG_OF_SEPARATE for boards in mainline." + @echo >&2 "See doc/README.fdt-control for more info." + @echo >&2 "====================================================" endif @# Check that this build does not use CONFIG options that we do not @# know about unless they are in Kconfig. All the existing CONFIG diff --git a/api/api_storage.c b/api/api_storage.c index 8aeeda2715f..2b90c18aaec 100644 --- a/api/api_storage.c +++ b/api/api_storage.c @@ -99,6 +99,7 @@ static int dev_stor_get(int type, int *more, struct device_info *di) { struct blk_desc *dd; int found = 0; + int found_last = 0; int i = 0; /* Wasn't configured for this type, return 0 directly */ @@ -111,9 +112,13 @@ static int dev_stor_get(int type, int *more, struct device_info *di) if (di->cookie == (void *)blk_get_dev(specs[type].name, i)) { i += 1; + found_last = 1; break; } } + + if (!found_last) + i = 0; } for (; i < specs[type].max_dev; i++) { diff --git a/arch/Kconfig b/arch/Kconfig index 947070fdd35..35e2712fce9 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -116,6 +116,7 @@ config SANDBOX imply VIRTIO_SANDBOX imply VIRTIO_BLK imply VIRTIO_NET + imply DM_SOUND config SH bool "SuperH architecture" diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index ad494ec3efd..dda4e594914 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -53,6 +53,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rk3399-puma-ddr1600.dtb \ rk3399-puma-ddr1866.dtb \ rk3399-rock960.dtb \ + rv1108-elgin-r1.dtb \ rv1108-evb.dtb dtb-$(CONFIG_ARCH_MESON) += \ meson-gxbb-nanopi-k2.dtb \ diff --git a/arch/arm/dts/am4372-generic-u-boot.dtsi b/arch/arm/dts/am4372-generic-u-boot.dtsi index d485679de41..6ba5c164924 100644 --- a/arch/arm/dts/am4372-generic-u-boot.dtsi +++ b/arch/arm/dts/am4372-generic-u-boot.dtsi @@ -3,6 +3,8 @@ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ */ +#include "am4372-u-boot.dtsi" + /{ ocp { u-boot,dm-pre-reloc; diff --git a/arch/arm/dts/am4372-u-boot.dtsi b/arch/arm/dts/am4372-u-boot.dtsi new file mode 100644 index 00000000000..99922ca0307 --- /dev/null +++ b/arch/arm/dts/am4372-u-boot.dtsi @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + */ + +&am43xx_control_usb2phy1 { + compatible = "ti,control-phy-usb2-am437", "syscon"; +}; + +&am43xx_control_usb2phy2 { + compatible = "ti,control-phy-usb2-am437", "syscon"; +}; + +&ocp2scp0 { + compatible = "ti,am437x-ocp2scp", "ti,omap-ocp2scp", "simple-bus"; +}; + +&ocp2scp1 { + compatible = "ti,am437x-ocp2scp", "ti,omap-ocp2scp", "simple-bus"; +}; + +&dwc3_1 { + u-boot,dm-spl; +}; + +&usb1 { + u-boot,dm-spl; +}; + +&usb2_phy1 { + u-boot,dm-spl; +}; + +&am43xx_control_usb2phy1 { + u-boot,dm-spl; +}; + +&ocp2scp0 { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/am437x-gp-evm-u-boot.dtsi b/arch/arm/dts/am437x-gp-evm-u-boot.dtsi index 03a1c1dd39a..d950d32f177 100644 --- a/arch/arm/dts/am437x-gp-evm-u-boot.dtsi +++ b/arch/arm/dts/am437x-gp-evm-u-boot.dtsi @@ -7,6 +7,8 @@ * Based on "dra7.dtsi" */ +#include "am4372-u-boot.dtsi" + /{ ocp { u-boot,dm-spl; diff --git a/arch/arm/dts/am437x-idk-evm-u-boot.dtsi b/arch/arm/dts/am437x-idk-evm-u-boot.dtsi index 0a3d79a372e..3aa9195e44d 100644 --- a/arch/arm/dts/am437x-idk-evm-u-boot.dtsi +++ b/arch/arm/dts/am437x-idk-evm-u-boot.dtsi @@ -3,6 +3,8 @@ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ */ +#include "am4372-u-boot.dtsi" + /{ ocp { u-boot,dm-spl; diff --git a/arch/arm/dts/am437x-sk-evm-u-boot.dtsi b/arch/arm/dts/am437x-sk-evm-u-boot.dtsi index 0a3d79a372e..3aa9195e44d 100644 --- a/arch/arm/dts/am437x-sk-evm-u-boot.dtsi +++ b/arch/arm/dts/am437x-sk-evm-u-boot.dtsi @@ -3,6 +3,8 @@ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ */ +#include "am4372-u-boot.dtsi" + /{ ocp { u-boot,dm-spl; diff --git a/arch/arm/dts/exynos5250-smdk5250.dts b/arch/arm/dts/exynos5250-smdk5250.dts index 8b695442b1a..e542a790761 100644 --- a/arch/arm/dts/exynos5250-smdk5250.dts +++ b/arch/arm/dts/exynos5250-smdk5250.dts @@ -60,9 +60,26 @@ }; i2c@12C70000 { - soundcodec@1a { + wm8994: soundcodec@1a { reg = <0x1a>; - compatible = "wolfson,wm8994-codec"; + u-boot,i2c-offset-len = <2>; + compatible = "wolfson,wm8994"; + #sound-dai-cells = <1>; + }; + }; + + sound { + compatible = "google,smdk5250-audio-wm8994"; + + samsung,model = "SMDK5250-I2S-WM8994"; + samsung,audio-codec = <&wm8994>; + + cpu { + sound-dai = <&i2s0 0>; + }; + + codec { + sound-dai = <&wm8994 0>; }; }; diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts index 29c13c1257e..7587dc0ff24 100644 --- a/arch/arm/dts/exynos5250-snow.dts +++ b/arch/arm/dts/exynos5250-snow.dts @@ -40,7 +40,6 @@ mmc3 = "/mmc@12230000"; serial0 = "/serial@12C30000"; console = "/serial@12C30000"; - i2s = "/sound@3830000"; }; memory { @@ -88,7 +87,7 @@ ro-boot { label = "u-boot"; - reg = <0x6000 0x9a000>; + reg = <0x6000 0xb0000>; read-only; type = "blob boot,dtb"; required; @@ -214,9 +213,10 @@ }; }; - soundcodec@22 { - reg = <0x22>; - compatible = "maxim,max98095-codec"; + max98095: codec@11 { + compatible = "maxim,max98095"; + reg = <0x11>; + #sound-dai-cells = <1>; }; }; @@ -273,9 +273,20 @@ }; }; - sound@3830000 { - samsung,codec-type = "max98095"; + sound { + compatible = "google,snow-audio-max98095"; + + samsung,model = "Snow-I2S-MAX98095"; + samsung,audio-codec = <&max98095>; codec-enable-gpio = <&gpx1 7 GPIO_ACTIVE_HIGH>; + + cpu { + sound-dai = <&i2s0 0>; + }; + + codec { + sound-dai = <&max98095 0>; + }; }; sound@12d60000 { diff --git a/arch/arm/dts/exynos5250-spring.dts b/arch/arm/dts/exynos5250-spring.dts index 7633d36874f..191e12af6a1 100644 --- a/arch/arm/dts/exynos5250-spring.dts +++ b/arch/arm/dts/exynos5250-spring.dts @@ -34,7 +34,6 @@ mmc0 = "/mmc@12200000"; serial0 = "/serial@12C30000"; console = "/serial@12C30000"; - i2s = "/sound@3830000"; }; memory { @@ -639,10 +638,27 @@ }; }; - soundcodec@20 { - reg = <0x20>; - compatible = "maxim,max98088-codec"; + max98095: soundcodec@10 { + reg = <0x10>; + compatible = "maxim,max98095"; + #sound-dai-cells = <1>; }; + + sound { + compatible = "google,spring-audio-max98095"; + + samsung,model = "Spring-I2S-MAX98095"; + samsung,audio-codec = <&max98095>; + + cpu { + sound-dai = <&i2s0 0>; + }; + + codec { + sound-dai = <&max98095 0>; + }; + }; + }; #include "cros-ec-keyboard.dtsi" diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi index 502c687802e..66c5b6dca95 100644 --- a/arch/arm/dts/exynos5250.dtsi +++ b/arch/arm/dts/exynos5250.dtsi @@ -78,9 +78,12 @@ #size-cells = <0>; }; - sound@3830000 { - compatible = "samsung,exynos-sound"; - reg = <0x3830000 0x50>; + i2s0: i2s@3830000 { + compatible = "samsung,s5pv210-i2s"; + reg = <0x03830000 0x100>; + samsung,idma-addr = <0x03000000>; + #clock-cells = <1>; + #sound-dai-cells = <1>; samsung,i2s-epll-clock-frequency = <192000000>; samsung,i2s-sampling-rate = <48000>; samsung,i2s-bits-per-sample = <16>; @@ -90,9 +93,11 @@ samsung,i2s-id = <0>; }; - sound@12d60000 { - compatible = "samsung,exynos-sound"; + i2s1: i2s@12d60000 { + compatible = "samsung,s5pv210-i2s"; reg = <0x12d60000 0x20>; + #clock-cells = <1>; + #sound-dai-cells = <1>; samsung,i2s-epll-clock-frequency = <192000000>; samsung,i2s-sampling-rate = <48000>; samsung,i2s-bits-per-sample = <16>; diff --git a/arch/arm/dts/exynos5420-peach-pit.dts b/arch/arm/dts/exynos5420-peach-pit.dts index c86f9d9035d..4a96a18110a 100644 --- a/arch/arm/dts/exynos5420-peach-pit.dts +++ b/arch/arm/dts/exynos5420-peach-pit.dts @@ -67,12 +67,28 @@ }; }; + sound { + compatible = "google,peach-audio-max98090"; + + samsung,model = "PEACH-I2S-MAX98090"; + samsung,audio-codec = <&max98090>; + + cpu { + sound-dai = <&i2s0 0>; + }; + + codec { + sound-dai = <&max98090 0>; + }; + }; + i2c@12CD0000 { /* i2c7 */ clock-frequency = <100000>; - soundcodec@20 { - reg = <0x20>; - compatible = "maxim,max98090-codec"; - }; + max98090: soundcodec@10 { + reg = <0x10>; + compatible = "maxim,max98090"; + #sound-dai-cells = <1>; + }; edp-lvds-bridge@48 { compatible = "parade,ps8625"; diff --git a/arch/arm/dts/exynos5420-smdk5420.dts b/arch/arm/dts/exynos5420-smdk5420.dts index cab5ddb61fa..7a5da674fbe 100644 --- a/arch/arm/dts/exynos5420-smdk5420.dts +++ b/arch/arm/dts/exynos5420-smdk5420.dts @@ -82,9 +82,26 @@ }; i2c@12C70000 { - soundcodec@1a { + wm8994: soundcodec@1a { reg = <0x1a>; - compatible = "wolfson,wm8994-codec"; + u-boot,i2c-offset-len = <2>; + compatible = "wolfson,wm8994"; + #sound-dai-cells = <1>; + }; + }; + + sound { + compatible = "samsung,smdk5420-audio-wm8994"; + + samsung,model = "Snow-I2S-MAX98095"; + samsung,audio-codec = <&wm8994>; + + cpu { + sound-dai = <&i2s0 0>; + }; + + codec { + sound-dai = <&wm8994 0>; }; }; diff --git a/arch/arm/dts/exynos54xx.dtsi b/arch/arm/dts/exynos54xx.dtsi index 09bef56e6c2..221da8b4850 100644 --- a/arch/arm/dts/exynos54xx.dtsi +++ b/arch/arm/dts/exynos54xx.dtsi @@ -104,6 +104,20 @@ interrupts = <0 203 0>; }; + i2s0: i2s@3830000 { + compatible = "samsung,s5pv210-i2s"; + reg = <0x03830000 0x100>; + #sound-dai-cells = <1>; + samsung,idma-addr = <0x03000000>; + samsung,i2s-epll-clock-frequency = <192000000>; + samsung,i2s-sampling-rate = <48000>; + samsung,i2s-bits-per-sample = <16>; + samsung,i2s-channels = <2>; + samsung,i2s-lr-clk-framesize = <256>; + samsung,i2s-bit-clk-framesize = <32>; + samsung,i2s-id = <0>; + }; + mmc@12200000 { samsung,bus-width = <8>; samsung,timing = <1 3 3>; diff --git a/arch/arm/dts/exynos5800-peach-pi.dts b/arch/arm/dts/exynos5800-peach-pi.dts index 7498519d6c6..63c0b186e42 100644 --- a/arch/arm/dts/exynos5800-peach-pi.dts +++ b/arch/arm/dts/exynos5800-peach-pi.dts @@ -79,12 +79,28 @@ }; }; + sound { + compatible = "google,peach-audio-max98090"; + + samsung,model = "PEACH-I2S-MAX98090"; + samsung,audio-codec = <&max98090>; + + cpu { + sound-dai = <&i2s0 0>; + }; + + codec { + sound-dai = <&max98090 0>; + }; + }; + i2c@12CD0000 { /* i2c7 */ clock-frequency = <100000>; - soundcodec@20 { - reg = <0x20>; - compatible = "maxim,max98090-codec"; - }; + max98090: soundcodec@10 { + reg = <0x10>; + compatible = "maxim,max98090"; + #sound-dai-cells = <1>; + }; }; sound@3830000 { diff --git a/arch/arm/dts/hi3798cv200-u-boot.dtsi b/arch/arm/dts/hi3798cv200-u-boot.dtsi index 709ae1cbc9f..7844c5208c5 100644 --- a/arch/arm/dts/hi3798cv200-u-boot.dtsi +++ b/arch/arm/dts/hi3798cv200-u-boot.dtsi @@ -17,12 +17,6 @@ }; &uart0 { - status = "disabled"; + clock = <75000000>; + status = "okay"; }; - -/{ - chosen { - stdout-path = ""; - }; -}; - diff --git a/arch/arm/dts/keystone-k2g-evm.dts b/arch/arm/dts/keystone-k2g-evm.dts index ad746c73110..6c9de25b944 100644 --- a/arch/arm/dts/keystone-k2g-evm.dts +++ b/arch/arm/dts/keystone-k2g-evm.dts @@ -33,6 +33,34 @@ }; }; +&keystone_usb0 { + status = "okay"; +}; + +&usb0_phy { + status = "okay"; + compatible = "nop-phy"; +}; + +&usb0 { + dr_mode = "host"; + status = "okay"; +}; + +&keystone_usb1 { + status = "okay"; +}; + +&usb1_phy { + compatible = "nop-phy"; + status = "okay"; +}; + +&usb1 { + dr_mode = "peripheral"; + status = "okay"; +}; + &gbe0 { phy-handle = <ðphy0>; }; diff --git a/arch/arm/dts/keystone-k2g.dtsi b/arch/arm/dts/keystone-k2g.dtsi index bbbb9874c87..ede71181206 100644 --- a/arch/arm/dts/keystone-k2g.dtsi +++ b/arch/arm/dts/keystone-k2g.dtsi @@ -201,5 +201,61 @@ status = "disabled"; clock-names = "fck"; }; + + usb0_phy: usb-phy@0 { + compatible = "usb-nop-xceiv"; + status = "disabled"; + }; + + keystone_usb0: keystone-dwc3@2680000 { + compatible = "ti,keystone-dwc3"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x2680000 0x10000>; + interrupts = <GIC_SPI 128 IRQ_TYPE_EDGE_RISING>; + ranges; + dma-coherent; + dma-ranges; + status = "disabled"; + /*power-domains = <&k2g_pds 0x0016>;*/ + + usb0: usb@2690000 { + compatible = "snps,dwc3"; + reg = <0x2690000 0x10000>; + interrupts = <GIC_SPI 128 IRQ_TYPE_EDGE_RISING>; + maximum-speed = "high-speed"; + dr_mode = "otg"; + /*usb-phy = <&usb0_phy>;*/ + status = "disabled"; + }; + }; + + usb1_phy: usb-phy@1 { + compatible = "usb-nop-xceiv"; + status = "disabled"; + }; + + keystone_usb1: keystone-dwc3@2580000 { + compatible = "ti,keystone-dwc3"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x2580000 0x10000>; + interrupts = <GIC_SPI 144 IRQ_TYPE_EDGE_RISING>; + ranges; + dma-coherent; + dma-ranges; + status = "disabled"; + /*power-domains = <&k2g_pds 0x0017>;*/ + + usb1: usb@2590000 { + compatible = "snps,dwc3"; + reg = <0x2590000 0x10000>; + interrupts = <GIC_SPI 144 IRQ_TYPE_EDGE_RISING>; + maximum-speed = "high-speed"; + dr_mode = "otg"; + /*usb-phy = <&usb1_phy>;*/ + status = "disabled"; + }; + }; }; }; diff --git a/arch/arm/dts/meson-axg-s400-u-boot.dtsi b/arch/arm/dts/meson-axg-s400-u-boot.dtsi new file mode 100644 index 00000000000..c46eb3f38dc --- /dev/null +++ b/arch/arm/dts/meson-axg-s400-u-boot.dtsi @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 Amlogic, Inc. All rights reserved. + */ + +/* wifi module */ +&sd_emmc_b { + status = "disabled"; +}; + +/* emmc storage */ +&sd_emmc_c { + status = "okay"; +}; diff --git a/arch/arm/dts/rk3288-evb.dtsi b/arch/arm/dts/rk3288-evb.dtsi index ce75bd5d28e..04902c0bd3f 100644 --- a/arch/arm/dts/rk3288-evb.dtsi +++ b/arch/arm/dts/rk3288-evb.dtsi @@ -150,8 +150,6 @@ num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>; - vmmc-supply = <&vcc_io>; - vqmmc-supply = <&vcc_flash>; status = "okay"; }; diff --git a/arch/arm/dts/rk3399-puma.dtsi b/arch/arm/dts/rk3399-puma.dtsi index ba9bb4c5994..9a61fbb4536 100644 --- a/arch/arm/dts/rk3399-puma.dtsi +++ b/arch/arm/dts/rk3399-puma.dtsi @@ -95,6 +95,8 @@ regulator-name = "usbhub_enable"; enable-active-low; gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&host_vbus_drv>; regulator-boot-on; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; @@ -146,16 +148,6 @@ regulator-always-on; }; - vcc5v0_host: vcc5v0-host-regulator { - compatible = "regulator-fixed"; - enable-active-low; - gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&host_vbus_drv>; - regulator-name = "vcc5v0_host"; - regulator-always-on; - }; - vcc5v0_sys: vcc5v0-sys { compatible = "regulator-fixed"; regulator-name = "vcc5v0_sys"; diff --git a/arch/arm/dts/rv1108-elgin-r1.dts b/arch/arm/dts/rv1108-elgin-r1.dts new file mode 100644 index 00000000000..32b95940b07 --- /dev/null +++ b/arch/arm/dts/rv1108-elgin-r1.dts @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2016 Rockchip Electronics Co., Ltd + */ + +/dts-v1/; + +#include "rv1108.dtsi" + +/ { + model = "Elgin RV1108 R1 board"; + compatible = "elgin,rv1108-elgin", "rockchip,rv1108"; + + memory@60000000 { + device_type = "memory"; + reg = <0x60000000 0x08000000>; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; +}; + +&emmc { + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; + bus-width = <8>; + cap-mmc-highspeed; + disable-wp; + non-removable; + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&uart2 { + status = "okay"; +}; + +&usb20_otg { + status = "okay"; +}; diff --git a/arch/arm/dts/uniphier-ld11.dtsi b/arch/arm/dts/uniphier-ld11.dtsi index d63b56e944d..31ba52b14e9 100644 --- a/arch/arm/dts/uniphier-ld11.dtsi +++ b/arch/arm/dts/uniphier-ld11.dtsi @@ -116,6 +116,28 @@ #size-cells = <1>; ranges = <0 0 0 0xffffffff>; + spi0: spi@54006000 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006000 0x100>; + interrupts = <0 39 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi0>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + + spi1: spi@54006100 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006100 0x100>; + interrupts = <0 216 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; status = "disabled"; @@ -432,6 +454,8 @@ <&mio_clk 12>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>, <&mio_rst 12>; + phy-names = "usb"; + phys = <&usb_phy0>; has-transaction-translator; }; @@ -446,6 +470,8 @@ <&mio_clk 13>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>, <&mio_rst 13>; + phy-names = "usb"; + phys = <&usb_phy1>; has-transaction-translator; }; @@ -460,6 +486,8 @@ <&mio_clk 14>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>, <&mio_rst 14>; + phy-names = "usb"; + phys = <&usb_phy2>; has-transaction-translator; }; @@ -488,6 +516,27 @@ pinctrl: pinctrl { compatible = "socionext,uniphier-ld11-pinctrl"; }; + + usb-phy { + compatible = "socionext,uniphier-ld11-usb2-phy"; + #address-cells = <1>; + #size-cells = <0>; + + usb_phy0: phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + + usb_phy1: phy@1 { + reg = <1>; + #phy-cells = <0>; + }; + + usb_phy2: phy@2 { + reg = <2>; + #phy-cells = <0>; + }; + }; }; soc-glue@5f900000 { @@ -571,7 +620,8 @@ interrupts = <0 65 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nand>; - clocks = <&sys_clk 2>; + clock-names = "nand", "nand_x", "ecc"; + clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>; resets = <&sys_rst 2>; }; }; diff --git a/arch/arm/dts/uniphier-ld20-global.dts b/arch/arm/dts/uniphier-ld20-global.dts index 1a5e7c24b90..9ca692ed1b2 100644 --- a/arch/arm/dts/uniphier-ld20-global.dts +++ b/arch/arm/dts/uniphier-ld20-global.dts @@ -145,6 +145,10 @@ }; }; +&usb { + status = "okay"; +}; + &nand { status = "okay"; }; diff --git a/arch/arm/dts/uniphier-ld20-ref.dts b/arch/arm/dts/uniphier-ld20-ref.dts index 440c2e6a638..406244a5c8e 100644 --- a/arch/arm/dts/uniphier-ld20-ref.dts +++ b/arch/arm/dts/uniphier-ld20-ref.dts @@ -75,3 +75,7 @@ drive-strength = <9>; }; }; + +&usb { + status = "okay"; +}; diff --git a/arch/arm/dts/uniphier-ld20.dtsi b/arch/arm/dts/uniphier-ld20.dtsi index 99704970394..b9ed613ace9 100644 --- a/arch/arm/dts/uniphier-ld20.dtsi +++ b/arch/arm/dts/uniphier-ld20.dtsi @@ -224,6 +224,50 @@ #size-cells = <1>; ranges = <0 0 0 0xffffffff>; + spi0: spi@54006000 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006000 0x100>; + interrupts = <0 39 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi0>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + + spi1: spi@54006100 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006100 0x100>; + interrupts = <0 216 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + + spi2: spi@54006200 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006200 0x100>; + interrupts = <0 229 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi2>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + + spi3: spi@54006300 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006300 0x100>; + interrupts = <0 230 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi3>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; status = "disabled"; @@ -567,6 +611,50 @@ efuse@200 { compatible = "socionext,uniphier-efuse"; reg = <0x200 0x68>; + #address-cells = <1>; + #size-cells = <1>; + + /* USB cells */ + usb_rterm0: trim@54,4 { + reg = <0x54 1>; + bits = <4 2>; + }; + usb_rterm1: trim@55,4 { + reg = <0x55 1>; + bits = <4 2>; + }; + usb_rterm2: trim@58,4 { + reg = <0x58 1>; + bits = <4 2>; + }; + usb_rterm3: trim@59,4 { + reg = <0x59 1>; + bits = <4 2>; + }; + usb_sel_t0: trim@54,0 { + reg = <0x54 1>; + bits = <0 4>; + }; + usb_sel_t1: trim@55,0 { + reg = <0x55 1>; + bits = <0 4>; + }; + usb_sel_t2: trim@58,0 { + reg = <0x58 1>; + bits = <0 4>; + }; + usb_sel_t3: trim@59,0 { + reg = <0x59 1>; + bits = <0 4>; + }; + usb_hs_i0: trim@56,0 { + reg = <0x56 1>; + bits = <0 4>; + }; + usb_hs_i2: trim@5a,0 { + reg = <0x5a 1>; + bits = <0 4>; + }; }; }; @@ -634,6 +722,157 @@ }; }; + _usb: usb@65a00000 { + compatible = "socionext,uniphier-dwc3", "snps,dwc3"; + status = "disabled"; + reg = <0x65a00000 0xcd00>; + interrupt-names = "host"; + interrupts = <0 134 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb1>, + <&pinctrl_usb2>, <&pinctrl_usb3>; + clock-names = "ref", "bus_early", "suspend"; + clocks = <&sys_clk 14>, <&sys_clk 14>, <&sys_clk 14>; + resets = <&usb_rst 15>; + phys = <&usb_hsphy0>, <&usb_hsphy1>, + <&usb_hsphy2>, <&usb_hsphy3>, + <&usb_ssphy0>, <&usb_ssphy1>; + dr_mode = "host"; + }; + + usb-glue@65b00000 { + compatible = "socionext,uniphier-ld20-dwc3-glue", + "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x65b00000 0x400>; + + usb_rst: reset@0 { + compatible = "socionext,uniphier-ld20-usb3-reset"; + reg = <0x0 0x4>; + #reset-cells = <1>; + clock-names = "link"; + clocks = <&sys_clk 14>; + reset-names = "link"; + resets = <&sys_rst 14>; + }; + + usb_vbus0: regulator@100 { + compatible = "socionext,uniphier-ld20-usb3-regulator"; + reg = <0x100 0x10>; + clock-names = "link"; + clocks = <&sys_clk 14>; + reset-names = "link"; + resets = <&sys_rst 14>; + }; + + usb_vbus1: regulator@110 { + compatible = "socionext,uniphier-ld20-usb3-regulator"; + reg = <0x110 0x10>; + clock-names = "link"; + clocks = <&sys_clk 14>; + reset-names = "link"; + resets = <&sys_rst 14>; + }; + + usb_vbus2: regulator@120 { + compatible = "socionext,uniphier-ld20-usb3-regulator"; + reg = <0x120 0x10>; + clock-names = "link"; + clocks = <&sys_clk 14>; + reset-names = "link"; + resets = <&sys_rst 14>; + }; + + usb_vbus3: regulator@130 { + compatible = "socionext,uniphier-ld20-usb3-regulator"; + reg = <0x130 0x10>; + clock-names = "link"; + clocks = <&sys_clk 14>; + reset-names = "link"; + resets = <&sys_rst 14>; + }; + + usb_hsphy0: hs-phy@200 { + compatible = "socionext,uniphier-ld20-usb3-hsphy"; + reg = <0x200 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 14>, <&sys_clk 16>; + reset-names = "link", "phy"; + resets = <&sys_rst 14>, <&sys_rst 16>; + vbus-supply = <&usb_vbus0>; + nvmem-cell-names = "rterm", "sel_t", "hs_i"; + nvmem-cells = <&usb_rterm0>, <&usb_sel_t0>, + <&usb_hs_i0>; + }; + + usb_hsphy1: hs-phy@210 { + compatible = "socionext,uniphier-ld20-usb3-hsphy"; + reg = <0x210 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 14>, <&sys_clk 16>; + reset-names = "link", "phy"; + resets = <&sys_rst 14>, <&sys_rst 16>; + vbus-supply = <&usb_vbus1>; + nvmem-cell-names = "rterm", "sel_t", "hs_i"; + nvmem-cells = <&usb_rterm1>, <&usb_sel_t1>, + <&usb_hs_i0>; + }; + + usb_hsphy2: hs-phy@220 { + compatible = "socionext,uniphier-ld20-usb3-hsphy"; + reg = <0x220 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 14>, <&sys_clk 17>; + reset-names = "link", "phy"; + resets = <&sys_rst 14>, <&sys_rst 17>; + vbus-supply = <&usb_vbus2>; + nvmem-cell-names = "rterm", "sel_t", "hs_i"; + nvmem-cells = <&usb_rterm2>, <&usb_sel_t2>, + <&usb_hs_i2>; + }; + + usb_hsphy3: hs-phy@230 { + compatible = "socionext,uniphier-ld20-usb3-hsphy"; + reg = <0x230 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 14>, <&sys_clk 17>; + reset-names = "link", "phy"; + resets = <&sys_rst 14>, <&sys_rst 17>; + vbus-supply = <&usb_vbus3>; + nvmem-cell-names = "rterm", "sel_t", "hs_i"; + nvmem-cells = <&usb_rterm3>, <&usb_sel_t3>, + <&usb_hs_i2>; + }; + + usb_ssphy0: ss-phy@300 { + compatible = "socionext,uniphier-ld20-usb3-ssphy"; + reg = <0x300 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 14>, <&sys_clk 18>; + reset-names = "link", "phy"; + resets = <&sys_rst 14>, <&sys_rst 18>; + vbus-supply = <&usb_vbus0>; + }; + + usb_ssphy1: ss-phy@310 { + compatible = "socionext,uniphier-ld20-usb3-ssphy"; + reg = <0x310 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 14>, <&sys_clk 19>; + reset-names = "link", "phy"; + resets = <&sys_rst 14>, <&sys_rst 19>; + vbus-supply = <&usb_vbus1>; + }; + }; + + /* FIXME: U-Boot own node */ usb: usb@65b00000 { compatible = "socionext,uniphier-ld20-dwc3"; reg = <0x65b00000 0x1000>; @@ -660,7 +899,8 @@ interrupts = <0 65 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nand>; - clocks = <&sys_clk 2>; + clock-names = "nand", "nand_x", "ecc"; + clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>; resets = <&sys_rst 2>; }; }; diff --git a/arch/arm/dts/uniphier-ld4.dtsi b/arch/arm/dts/uniphier-ld4.dtsi index f505f643f76..b73d594b6dc 100644 --- a/arch/arm/dts/uniphier-ld4.dtsi +++ b/arch/arm/dts/uniphier-ld4.dtsi @@ -63,6 +63,17 @@ cache-level = <2>; }; + spi: spi@54006000 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006000 0x100>; + interrupts = <0 39 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi0>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; status = "disabled"; @@ -381,7 +392,8 @@ interrupts = <0 65 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nand2cs>; - clocks = <&sys_clk 2>; + clock-names = "nand", "nand_x", "ecc"; + clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>; resets = <&sys_rst 2>; }; }; diff --git a/arch/arm/dts/uniphier-pinctrl.dtsi b/arch/arm/dts/uniphier-pinctrl.dtsi index aeb47b0ffe9..1fee5ffbfb9 100644 --- a/arch/arm/dts/uniphier-pinctrl.dtsi +++ b/arch/arm/dts/uniphier-pinctrl.dtsi @@ -131,6 +131,26 @@ function = "sd1"; }; + pinctrl_spi0: spi0 { + groups = "spi0"; + function = "spi0"; + }; + + pinctrl_spi1: spi1 { + groups = "spi1"; + function = "spi1"; + }; + + pinctrl_spi2: spi2 { + groups = "spi2"; + function = "spi2"; + }; + + pinctrl_spi3: spi3 { + groups = "spi3"; + function = "spi3"; + }; + pinctrl_system_bus: system-bus { groups = "system_bus", "system_bus_cs1"; function = "system_bus"; diff --git a/arch/arm/dts/uniphier-pro4-ace.dts b/arch/arm/dts/uniphier-pro4-ace.dts index bff90c256b6..ce8ea7b79bb 100644 --- a/arch/arm/dts/uniphier-pro4-ace.dts +++ b/arch/arm/dts/uniphier-pro4-ace.dts @@ -73,11 +73,11 @@ status = "okay"; }; -&usb0 { +&usb2 { status = "okay"; }; -&usb1 { +&usb3 { status = "okay"; }; @@ -92,10 +92,10 @@ }; }; -&usb2 { +&usb0 { status = "okay"; }; -&usb3 { +&usb1 { status = "okay"; }; diff --git a/arch/arm/dts/uniphier-pro4-sanji.dts b/arch/arm/dts/uniphier-pro4-sanji.dts index 7f5b957f98e..686dd3af7e9 100644 --- a/arch/arm/dts/uniphier-pro4-sanji.dts +++ b/arch/arm/dts/uniphier-pro4-sanji.dts @@ -68,11 +68,11 @@ status = "okay"; }; -&usb0 { +&usb2 { status = "okay"; }; -&usb1 { +&usb3 { status = "okay"; }; @@ -87,10 +87,10 @@ }; }; -&usb2 { +&usb0 { status = "okay"; }; -&usb3 { +&usb1 { status = "okay"; }; diff --git a/arch/arm/dts/uniphier-pro4.dtsi b/arch/arm/dts/uniphier-pro4.dtsi index 8974844541c..ef342088e1c 100644 --- a/arch/arm/dts/uniphier-pro4.dtsi +++ b/arch/arm/dts/uniphier-pro4.dtsi @@ -71,6 +71,17 @@ cache-level = <2>; }; + spi0: spi@54006000 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006000 0x100>; + interrupts = <0 39 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi0>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; status = "disabled"; @@ -317,6 +328,8 @@ <&mio_clk 12>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>, <&mio_rst 12>; + phy-names = "usb"; + phys = <&usb_phy0>; has-transaction-translator; }; @@ -331,6 +344,8 @@ <&mio_clk 13>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>, <&mio_rst 13>; + phy-names = "usb"; + phys = <&usb_phy1>; has-transaction-translator; }; @@ -342,6 +357,34 @@ pinctrl: pinctrl { compatible = "socionext,uniphier-pro4-pinctrl"; }; + + usb-phy { + compatible = "socionext,uniphier-pro4-usb2-phy"; + #address-cells = <1>; + #size-cells = <0>; + + usb_phy0: phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + + usb_phy1: phy@1 { + reg = <1>; + #phy-cells = <0>; + }; + + usb_phy2: phy@2 { + reg = <2>; + #phy-cells = <0>; + vbus-supply = <&usb0_vbus>; + }; + + usb_phy3: phy@3 { + reg = <3>; + #phy-cells = <0>; + vbus-supply = <&usb1_vbus>; + }; + }; }; soc-glue@5f900000 { @@ -434,6 +477,60 @@ }; }; + _usb0: usb@65a00000 { + compatible = "socionext,uniphier-dwc3", "snps,dwc3"; + status = "disabled"; + reg = <0x65a00000 0xcd00>; + interrupt-names = "host", "peripheral"; + interrupts = <0 134 4>, <0 135 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0>; + clock-names = "ref", "bus_early", "suspend"; + clocks = <&sys_clk 12>, <&sys_clk 12>, <&sys_clk 12>; + resets = <&usb0_rst 4>; + phys = <&usb_phy2>, <&usb0_ssphy>; + dr_mode = "host"; + }; + + usb-glue@65b00000 { + compatible = "socionext,uniphier-pro4-dwc3-glue", + "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x65b00000 0x100>; + + usb0_vbus: regulator@0 { + compatible = "socionext,uniphier-pro4-usb3-regulator"; + reg = <0 0x10>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 14>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 14>; + }; + + usb0_ssphy: ss-phy@10 { + compatible = "socionext,uniphier-pro4-usb3-ssphy"; + reg = <0x10 0x10>; + #phy-cells = <0>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 14>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 14>; + vbus-supply = <&usb0_vbus>; + }; + + usb0_rst: reset@40 { + compatible = "socionext,uniphier-pro4-usb3-reset"; + reg = <0x40 0x4>; + #reset-cells = <1>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 14>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 14>; + }; + }; + + /* FIXME: U-Boot own node */ usb0: usb@65b00000 { compatible = "socionext,uniphier-pro4-dwc3"; status = "disabled"; @@ -452,6 +549,49 @@ }; }; + _usb1: usb@65c00000 { + compatible = "socionext,uniphier-dwc3", "snps,dwc3"; + status = "disabled"; + reg = <0x65c00000 0xcd00>; + interrupt-names = "host", "peripheral"; + interrupts = <0 137 4>, <0 138 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1>; + clock-names = "ref", "bus_early", "suspend"; + clocks = <&sys_clk 12>, <&sys_clk 12>, <&sys_clk 12>; + resets = <&usb1_rst 4>; + phys = <&usb_phy3>; + dr_mode = "host"; + }; + + usb-glue@65d00000 { + compatible = "socionext,uniphier-pro4-dwc3-glue", + "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x65d00000 0x100>; + + usb1_vbus: regulator@0 { + compatible = "socionext,uniphier-pro4-usb3-regulator"; + reg = <0 0x10>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 15>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 15>; + }; + + usb1_rst: reset@40 { + compatible = "socionext,uniphier-pro4-usb3-reset"; + reg = <0x40 0x4>; + #reset-cells = <1>; + clock-names = "gio", "link"; + clocks = <&sys_clk 12>, <&sys_clk 15>; + reset-names = "gio", "link"; + resets = <&sys_rst 12>, <&sys_rst 15>; + }; + }; + + /* FIXME: U-Boot own node */ usb1: usb@65d00000 { compatible = "socionext,uniphier-pro4-dwc3"; status = "disabled"; @@ -478,7 +618,8 @@ interrupts = <0 65 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nand>; - clocks = <&sys_clk 2>; + clock-names = "nand", "nand_x", "ecc"; + clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>; resets = <&sys_rst 2>; }; }; diff --git a/arch/arm/dts/uniphier-pro5.dtsi b/arch/arm/dts/uniphier-pro5.dtsi index 6e0ea7976e0..9cad79d0860 100644 --- a/arch/arm/dts/uniphier-pro5.dtsi +++ b/arch/arm/dts/uniphier-pro5.dtsi @@ -156,6 +156,28 @@ cache-level = <3>; }; + spi0: spi@54006000 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006000 0x100>; + interrupts = <0 39 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi0>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + + spi1: spi@54006100 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006100 0x100>; + interrupts = <0 216 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; status = "disabled"; @@ -475,7 +497,8 @@ interrupts = <0 65 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nand2cs>; - clocks = <&sys_clk 2>; + clock-names = "nand", "nand_x", "ecc"; + clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>; resets = <&sys_rst 2>; }; diff --git a/arch/arm/dts/uniphier-pxs2.dtsi b/arch/arm/dts/uniphier-pxs2.dtsi index 63c1c2ce605..fa25ffd97f6 100644 --- a/arch/arm/dts/uniphier-pxs2.dtsi +++ b/arch/arm/dts/uniphier-pxs2.dtsi @@ -167,6 +167,28 @@ cache-level = <2>; }; + spi0: spi@54006000 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006000 0x100>; + interrupts = <0 39 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi0>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + + spi1: spi@54006100 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006100 0x100>; + interrupts = <0 216 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; status = "disabled"; @@ -557,6 +579,103 @@ }; }; + _usb0: usb@65a00000 { + compatible = "socionext,uniphier-dwc3", "snps,dwc3"; + status = "disabled"; + reg = <0x65a00000 0xcd00>; + interrupt-names = "host", "peripheral"; + interrupts = <0 134 4>, <0 135 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb2>; + clock-names = "ref", "bus_early", "suspend"; + clocks = <&sys_clk 14>, <&sys_clk 14>, <&sys_clk 14>; + resets = <&usb0_rst 15>; + phys = <&usb0_hsphy0>, <&usb0_hsphy1>, + <&usb0_ssphy0>, <&usb0_ssphy1>; + dr_mode = "host"; + }; + + usb-glue@65b00000 { + compatible = "socionext,uniphier-pxs2-dwc3-glue", + "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x65b00000 0x400>; + + usb0_rst: reset@0 { + compatible = "socionext,uniphier-pxs2-usb3-reset"; + reg = <0x0 0x4>; + #reset-cells = <1>; + clock-names = "link"; + clocks = <&sys_clk 14>; + reset-names = "link"; + resets = <&sys_rst 14>; + }; + + usb0_vbus0: regulator@100 { + compatible = "socionext,uniphier-pxs2-usb3-regulator"; + reg = <0x100 0x10>; + clock-names = "link"; + clocks = <&sys_clk 14>; + reset-names = "link"; + resets = <&sys_rst 14>; + }; + + usb0_vbus1: regulator@110 { + compatible = "socionext,uniphier-pxs2-usb3-regulator"; + reg = <0x110 0x10>; + clock-names = "link"; + clocks = <&sys_clk 14>; + reset-names = "link"; + resets = <&sys_rst 14>; + }; + + usb0_hsphy0: hs-phy@200 { + compatible = "socionext,uniphier-pxs2-usb3-hsphy"; + reg = <0x200 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 14>, <&sys_clk 16>; + reset-names = "link", "phy"; + resets = <&sys_rst 14>, <&sys_rst 16>; + vbus-supply = <&usb0_vbus0>; + }; + + usb0_hsphy1: hs-phy@210 { + compatible = "socionext,uniphier-pxs2-usb3-hsphy"; + reg = <0x210 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 14>, <&sys_clk 16>; + reset-names = "link", "phy"; + resets = <&sys_rst 14>, <&sys_rst 16>; + vbus-supply = <&usb0_vbus1>; + }; + + usb0_ssphy0: ss-phy@300 { + compatible = "socionext,uniphier-pxs2-usb3-ssphy"; + reg = <0x300 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 14>, <&sys_clk 17>; + reset-names = "link", "phy"; + resets = <&sys_rst 14>, <&sys_rst 17>; + vbus-supply = <&usb0_vbus0>; + }; + + usb0_ssphy1: ss-phy@310 { + compatible = "socionext,uniphier-pxs2-usb3-ssphy"; + reg = <0x310 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 14>, <&sys_clk 18>; + reset-names = "link", "phy"; + resets = <&sys_rst 14>, <&sys_rst 18>; + vbus-supply = <&usb0_vbus1>; + }; + }; + + /* FIXME: U-Boot own node */ usb0: usb@65b00000 { compatible = "socionext,uniphier-pxs2-dwc3"; status = "disabled"; @@ -575,6 +694,91 @@ }; }; + _usb1: usb@65c00000 { + compatible = "socionext,uniphier-dwc3", "snps,dwc3"; + status = "disabled"; + reg = <0x65c00000 0xcd00>; + interrupt-names = "host", "peripheral"; + interrupts = <0 137 4>, <0 138 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1>, <&pinctrl_usb3>; + clock-names = "ref", "bus_early", "suspend"; + clocks = <&sys_clk 15>, <&sys_clk 15>, <&sys_clk 15>; + resets = <&usb1_rst 15>; + phys = <&usb1_hsphy0>, <&usb1_hsphy1>, <&usb1_ssphy0>; + dr_mode = "host"; + }; + + usb-glue@65d00000 { + compatible = "socionext,uniphier-pxs2-dwc3-glue", + "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x65d00000 0x400>; + + usb1_rst: reset@0 { + compatible = "socionext,uniphier-pxs2-usb3-reset"; + reg = <0x0 0x4>; + #reset-cells = <1>; + clock-names = "link"; + clocks = <&sys_clk 15>; + reset-names = "link"; + resets = <&sys_rst 15>; + }; + + usb1_vbus0: regulator@100 { + compatible = "socionext,uniphier-pxs2-usb3-regulator"; + reg = <0x100 0x10>; + clock-names = "link"; + clocks = <&sys_clk 15>; + reset-names = "link"; + resets = <&sys_rst 15>; + }; + + usb1_vbus1: regulator@110 { + compatible = "socionext,uniphier-pxs2-usb3-regulator"; + reg = <0x110 0x10>; + clock-names = "link"; + clocks = <&sys_clk 15>; + reset-names = "link"; + resets = <&sys_rst 15>; + }; + + usb1_hsphy0: hs-phy@200 { + compatible = "socionext,uniphier-pxs2-usb3-hsphy"; + reg = <0x200 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 15>, <&sys_clk 20>; + reset-names = "link", "phy"; + resets = <&sys_rst 15>, <&sys_rst 20>; + vbus-supply = <&usb1_vbus0>; + }; + + usb1_hsphy1: hs-phy@210 { + compatible = "socionext,uniphier-pxs2-usb3-hsphy"; + reg = <0x210 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 15>, <&sys_clk 20>; + reset-names = "link", "phy"; + resets = <&sys_rst 15>, <&sys_rst 20>; + vbus-supply = <&usb1_vbus1>; + }; + + usb1_ssphy0: ss-phy@300 { + compatible = "socionext,uniphier-pxs2-usb3-ssphy"; + reg = <0x300 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 15>, <&sys_clk 21>; + reset-names = "link", "phy"; + resets = <&sys_rst 15>, <&sys_rst 21>; + vbus-supply = <&usb1_vbus0>; + }; + }; + + /* FIXME: U-Boot own node */ usb1: usb@65d00000 { compatible = "socionext,uniphier-pxs2-dwc3"; status = "disabled"; @@ -601,7 +805,8 @@ interrupts = <0 65 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nand2cs>; - clocks = <&sys_clk 2>; + clock-names = "nand", "nand_x", "ecc"; + clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>; resets = <&sys_rst 2>; }; }; diff --git a/arch/arm/dts/uniphier-pxs3.dtsi b/arch/arm/dts/uniphier-pxs3.dtsi index daf74531e44..f629c6a862f 100644 --- a/arch/arm/dts/uniphier-pxs3.dtsi +++ b/arch/arm/dts/uniphier-pxs3.dtsi @@ -144,6 +144,28 @@ #size-cells = <1>; ranges = <0 0 0 0xffffffff>; + spi0: spi@54006000 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006000 0x100>; + interrupts = <0 39 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi0>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + + spi1: spi@54006100 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006100 0x100>; + interrupts = <0 216 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; status = "disabled"; @@ -384,6 +406,50 @@ efuse@200 { compatible = "socionext,uniphier-efuse"; reg = <0x200 0x68>; + #address-cells = <1>; + #size-cells = <1>; + + /* USB cells */ + usb_rterm0: trim@54,4 { + reg = <0x54 1>; + bits = <4 2>; + }; + usb_rterm1: trim@55,4 { + reg = <0x55 1>; + bits = <4 2>; + }; + usb_rterm2: trim@58,4 { + reg = <0x58 1>; + bits = <4 2>; + }; + usb_rterm3: trim@59,4 { + reg = <0x59 1>; + bits = <4 2>; + }; + usb_sel_t0: trim@54,0 { + reg = <0x54 1>; + bits = <0 4>; + }; + usb_sel_t1: trim@55,0 { + reg = <0x55 1>; + bits = <0 4>; + }; + usb_sel_t2: trim@58,0 { + reg = <0x58 1>; + bits = <0 4>; + }; + usb_sel_t3: trim@59,0 { + reg = <0x59 1>; + bits = <0 4>; + }; + usb_hs_i0: trim@56,0 { + reg = <0x56 1>; + bits = <0 4>; + }; + usb_hs_i2: trim@5a,0 { + reg = <0x5a 1>; + bits = <0 4>; + }; }; }; @@ -465,6 +531,109 @@ }; }; + _usb0: usb@65a00000 { + compatible = "socionext,uniphier-dwc3", "snps,dwc3"; + status = "disabled"; + reg = <0x65a00000 0xcd00>; + interrupt-names = "host", "peripheral"; + interrupts = <0 134 4>, <0 135 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb2>; + clock-names = "ref", "bus_early", "suspend"; + clocks = <&sys_clk 12>, <&sys_clk 12>, <&sys_clk 12>; + resets = <&usb0_rst 15>; + phys = <&usb0_hsphy0>, <&usb0_hsphy1>, + <&usb0_ssphy0>, <&usb0_ssphy1>; + dr_mode = "host"; + }; + + usb-glue@65b00000 { + compatible = "socionext,uniphier-pxs3-dwc3-glue", + "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x65b00000 0x400>; + + usb0_rst: reset@0 { + compatible = "socionext,uniphier-pxs3-usb3-reset"; + reg = <0x0 0x4>; + #reset-cells = <1>; + clock-names = "link"; + clocks = <&sys_clk 12>; + reset-names = "link"; + resets = <&sys_rst 12>; + }; + + usb0_vbus0: regulator@100 { + compatible = "socionext,uniphier-pxs3-usb3-regulator"; + reg = <0x100 0x10>; + clock-names = "link"; + clocks = <&sys_clk 12>; + reset-names = "link"; + resets = <&sys_rst 12>; + }; + + usb0_vbus1: regulator@110 { + compatible = "socionext,uniphier-pxs3-usb3-regulator"; + reg = <0x110 0x10>; + clock-names = "link"; + clocks = <&sys_clk 12>; + reset-names = "link"; + resets = <&sys_rst 12>; + }; + + usb0_hsphy0: hs-phy@200 { + compatible = "socionext,uniphier-pxs3-usb3-hsphy"; + reg = <0x200 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 12>, <&sys_clk 16>; + reset-names = "link", "phy"; + resets = <&sys_rst 12>, <&sys_rst 16>; + vbus-supply = <&usb0_vbus0>; + nvmem-cell-names = "rterm", "sel_t", "hs_i"; + nvmem-cells = <&usb_rterm0>, <&usb_sel_t0>, + <&usb_hs_i0>; + }; + + usb0_hsphy1: hs-phy@210 { + compatible = "socionext,uniphier-pxs3-usb3-hsphy"; + reg = <0x210 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 12>, <&sys_clk 16>; + reset-names = "link", "phy"; + resets = <&sys_rst 12>, <&sys_rst 16>; + vbus-supply = <&usb0_vbus1>; + nvmem-cell-names = "rterm", "sel_t", "hs_i"; + nvmem-cells = <&usb_rterm1>, <&usb_sel_t1>, + <&usb_hs_i0>; + }; + + usb0_ssphy0: ss-phy@300 { + compatible = "socionext,uniphier-pxs3-usb3-ssphy"; + reg = <0x300 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 12>, <&sys_clk 17>; + reset-names = "link", "phy"; + resets = <&sys_rst 12>, <&sys_rst 17>; + vbus-supply = <&usb0_vbus0>; + }; + + usb0_ssphy1: ss-phy@310 { + compatible = "socionext,uniphier-pxs3-usb3-ssphy"; + reg = <0x310 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy"; + clocks = <&sys_clk 12>, <&sys_clk 18>; + reset-names = "link", "phy"; + resets = <&sys_rst 12>, <&sys_rst 18>; + vbus-supply = <&usb0_vbus1>; + }; + }; + + /* FIXME: U-Boot own node */ usb0: usb@65b00000 { compatible = "socionext,uniphier-pxs3-dwc3"; status = "disabled"; @@ -483,6 +652,101 @@ }; }; + _usb1: usb@65c00000 { + compatible = "socionext,uniphier-dwc3", "snps,dwc3"; + status = "disabled"; + reg = <0x65c00000 0xcd00>; + interrupt-names = "host", "peripheral"; + interrupts = <0 137 4>, <0 138 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1>, <&pinctrl_usb3>; + clock-names = "ref", "bus_early", "suspend"; + clocks = <&sys_clk 13>, <&sys_clk 13>, <&sys_clk 13>; + resets = <&usb1_rst 15>; + phys = <&usb1_hsphy0>, <&usb1_hsphy1>, + <&usb1_ssphy0>; + dr_mode = "host"; + }; + + usb-glue@65d00000 { + compatible = "socionext,uniphier-pxs3-dwc3-glue", + "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x65d00000 0x400>; + + usb1_rst: reset@0 { + compatible = "socionext,uniphier-pxs3-usb3-reset"; + reg = <0x0 0x4>; + #reset-cells = <1>; + clock-names = "link"; + clocks = <&sys_clk 13>; + reset-names = "link"; + resets = <&sys_rst 13>; + }; + + usb1_vbus0: regulator@100 { + compatible = "socionext,uniphier-pxs3-usb3-regulator"; + reg = <0x100 0x10>; + clock-names = "link"; + clocks = <&sys_clk 13>; + reset-names = "link"; + resets = <&sys_rst 13>; + }; + + usb1_vbus1: regulator@110 { + compatible = "socionext,uniphier-pxs3-usb3-regulator"; + reg = <0x110 0x10>; + clock-names = "link"; + clocks = <&sys_clk 13>; + reset-names = "link"; + resets = <&sys_rst 13>; + }; + + usb1_hsphy0: hs-phy@200 { + compatible = "socionext,uniphier-pxs3-usb3-hsphy"; + reg = <0x200 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy", "phy-ext"; + clocks = <&sys_clk 13>, <&sys_clk 20>, + <&sys_clk 14>; + reset-names = "link", "phy"; + resets = <&sys_rst 13>, <&sys_rst 20>; + vbus-supply = <&usb1_vbus0>; + nvmem-cell-names = "rterm", "sel_t", "hs_i"; + nvmem-cells = <&usb_rterm2>, <&usb_sel_t2>, + <&usb_hs_i2>; + }; + + usb1_hsphy1: hs-phy@210 { + compatible = "socionext,uniphier-pxs3-usb3-hsphy"; + reg = <0x210 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy", "phy-ext"; + clocks = <&sys_clk 13>, <&sys_clk 20>, + <&sys_clk 14>; + reset-names = "link", "phy"; + resets = <&sys_rst 13>, <&sys_rst 20>; + vbus-supply = <&usb1_vbus1>; + nvmem-cell-names = "rterm", "sel_t", "hs_i"; + nvmem-cells = <&usb_rterm3>, <&usb_sel_t3>, + <&usb_hs_i2>; + }; + + usb1_ssphy0: ss-phy@300 { + compatible = "socionext,uniphier-pxs3-usb3-ssphy"; + reg = <0x300 0x10>; + #phy-cells = <0>; + clock-names = "link", "phy", "phy-ext"; + clocks = <&sys_clk 13>, <&sys_clk 21>, + <&sys_clk 14>; + reset-names = "link", "phy"; + resets = <&sys_rst 13>, <&sys_rst 21>; + vbus-supply = <&usb1_vbus0>; + }; + }; + + /* FIXME: U-Boot own node */ usb1: usb@65d00000 { compatible = "socionext,uniphier-pxs3-dwc3"; status = "disabled"; @@ -509,7 +773,8 @@ interrupts = <0 65 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nand>; - clocks = <&sys_clk 2>; + clock-names = "nand", "nand_x", "ecc"; + clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>; resets = <&sys_rst 2>; }; }; diff --git a/arch/arm/dts/uniphier-sld8.dtsi b/arch/arm/dts/uniphier-sld8.dtsi index 437265bb739..f7fcf6b4599 100644 --- a/arch/arm/dts/uniphier-sld8.dtsi +++ b/arch/arm/dts/uniphier-sld8.dtsi @@ -63,6 +63,17 @@ cache-level = <2>; }; + spi: spi@54006000 { + compatible = "socionext,uniphier-scssi"; + status = "disabled"; + reg = <0x54006000 0x100>; + interrupts = <0 39 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi0>; + clocks = <&peri_clk 11>; + resets = <&peri_rst 11>; + }; + serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; status = "disabled"; @@ -385,7 +396,8 @@ interrupts = <0 65 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nand2cs>; - clocks = <&sys_clk 2>; + clock-names = "nand", "nand_x", "ecc"; + clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>; resets = <&sys_rst 2>; }; }; diff --git a/arch/arm/include/asm/omap_musb.h b/arch/arm/include/asm/omap_musb.h index 875f1002af8..b40ea005bec 100644 --- a/arch/arm/include/asm/omap_musb.h +++ b/arch/arm/include/asm/omap_musb.h @@ -7,6 +7,7 @@ #ifndef __ASM_ARM_OMAP_MUSB_H #define __ASM_ARM_OMAP_MUSB_H +#include <linux/usb/musb.h> extern struct musb_platform_ops musb_dsps_ops; extern const struct musb_platform_ops am35x_ops; @@ -21,4 +22,11 @@ struct omap_musb_board_data { }; enum musb_interface {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI}; + +struct ti_musb_platdata { + void *base; + void *ctrl_mod_base; + struct musb_hdrc_platform_data plat; +}; + #endif /* __ASM_ARM_OMAP_MUSB_H */ diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c index 6a3cd44b5d3..73aa4cdad32 100644 --- a/arch/arm/mach-exynos/clock.c +++ b/arch/arm/mach-exynos/clock.c @@ -345,7 +345,7 @@ static struct clk_bit_info *get_clk_bit_info(int peripheral) int i; struct clk_bit_info *info; - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) info = exynos542x_bit_info; else info = exynos5_bit_info; @@ -557,7 +557,7 @@ static unsigned long exynos542x_get_periph_rate(int peripheral) unsigned long clock_get_periph_rate(int peripheral) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) return exynos542x_get_periph_rate(peripheral); return exynos5_get_periph_rate(peripheral); } else { @@ -1317,6 +1317,19 @@ int exynos5_set_epll_clk(unsigned long rate) return 0; } +static int exynos5420_set_i2s_clk_source(void) +{ + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + + setbits_le32(&clk->src_top6, EXYNOS5420_CLK_SRC_MOUT_EPLL); + clrsetbits_le32(&clk->src_mau, EXYNOS5420_AUDIO0_SEL_MASK, + (EXYNOS5420_CLK_SRC_SCLK_EPLL)); + setbits_le32(EXYNOS5_AUDIOSS_BASE, 1 << 0); + + return 0; +} + int exynos5_set_i2s_clk_source(unsigned int i2s_id) { struct exynos5_clock *clk = @@ -1575,7 +1588,7 @@ static unsigned long exynos4_get_i2c_clk(void) unsigned long get_pll_clk(int pllreg) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) return exynos542x_get_pll_clk(pllreg); return exynos5_get_pll_clk(pllreg); } else if (cpu_is_exynos4()) { @@ -1691,7 +1704,7 @@ void set_mmc_clk(int dev_index, unsigned int div) div -= 1; if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) exynos5420_set_mmc_clk(dev_index, div); else exynos5_set_mmc_clk(dev_index, div); @@ -1739,7 +1752,7 @@ void set_mipi_clk(void) int set_spi_clk(int periph_id, unsigned int rate) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) return exynos5420_set_spi_clk(periph_id, rate); return exynos5_set_spi_clk(periph_id, rate); } @@ -1758,8 +1771,12 @@ int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq, int set_i2s_clk_source(unsigned int i2s_id) { - if (cpu_is_exynos5()) - return exynos5_set_i2s_clk_source(i2s_id); + if (cpu_is_exynos5()) { + if (proid_is_exynos542x()) + return exynos5420_set_i2s_clk_source(); + else + return exynos5_set_i2s_clk_source(i2s_id); + } return 0; } diff --git a/arch/arm/mach-exynos/clock_init_exynos5.c b/arch/arm/mach-exynos/clock_init_exynos5.c index e63ef645239..1cb8d391e7c 100644 --- a/arch/arm/mach-exynos/clock_init_exynos5.c +++ b/arch/arm/mach-exynos/clock_init_exynos5.c @@ -968,7 +968,7 @@ static void exynos5420_system_clock_init(void) void system_clock_init(void) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) exynos5420_system_clock_init(); else exynos5250_system_clock_init(); diff --git a/arch/arm/mach-exynos/common_setup.h b/arch/arm/mach-exynos/common_setup.h index 2829fb269ed..4e3702b9285 100644 --- a/arch/arm/mach-exynos/common_setup.h +++ b/arch/arm/mach-exynos/common_setup.h @@ -78,7 +78,7 @@ static inline void configure_l2_ctlr(void) CACHE_TAG_RAM_LATENCY_2_CYCLES | CACHE_DATA_RAM_LATENCY_2_CYCLES; - if (proid_is_exynos5420() || proid_is_exynos5422()) { + if (proid_is_exynos542x()) { val |= CACHE_ECC_AND_PARITY | CACHE_TAG_RAM_LATENCY_3_CYCLES | CACHE_DATA_RAM_LATENCY_3_CYCLES; @@ -97,7 +97,7 @@ static inline void configure_l2_actlr(void) { uint32_t val; - if (proid_is_exynos5420() || proid_is_exynos5422()) { + if (proid_is_exynos542x()) { mrc_l2_aux_ctlr(val); val |= CACHE_ENABLE_FORCE_L2_LOGIC | CACHE_DISABLE_CLEAN_EVICT; diff --git a/arch/arm/mach-exynos/include/mach/clock.h b/arch/arm/mach-exynos/include/mach/clock.h index edf62bdf853..e4c706adeac 100644 --- a/arch/arm/mach-exynos/include/mach/clock.h +++ b/arch/arm/mach-exynos/include/mach/clock.h @@ -1370,10 +1370,13 @@ struct set_epll_con_val { #define AUDIO_1_RATIO_MASK 0x0f #define AUDIO0_SEL_MASK 0xf +#define EXYNOS5420_AUDIO0_SEL_MASK (0x3 << 28) #define AUDIO1_SEL_MASK 0xf #define CLK_SRC_SCLK_EPLL 0x7 +#define EXYNOS5420_CLK_SRC_SCLK_EPLL (0x6 << 28) #define CLK_SRC_MOUT_EPLL (1<<12) +#define EXYNOS5420_CLK_SRC_MOUT_EPLL BIT(20) #define AUDIO_CLKMUX_ASS (1<<0) /* CON0 bit-fields */ diff --git a/arch/arm/mach-exynos/include/mach/cpu.h b/arch/arm/mach-exynos/include/mach/cpu.h index aeb3755fe6b..766edeeb298 100644 --- a/arch/arm/mach-exynos/include/mach/cpu.h +++ b/arch/arm/mach-exynos/include/mach/cpu.h @@ -268,6 +268,8 @@ IS_EXYNOS_TYPE(exynos5250, 0x5250) IS_EXYNOS_TYPE(exynos5420, 0x5420) IS_EXYNOS_TYPE(exynos5422, 0x5422) +#define proid_is_exynos542x() (proid_is_exynos5420() || proid_is_exynos5422()) + #define SAMSUNG_BASE(device, base) \ static inline unsigned long __attribute__((no_instrument_function)) \ samsung_get_base_##device(void) \ @@ -277,7 +279,7 @@ static inline unsigned long __attribute__((no_instrument_function)) \ return EXYNOS4X12_##base; \ return EXYNOS4_##base; \ } else if (cpu_is_exynos5()) { \ - if (proid_is_exynos5420() || proid_is_exynos5422()) \ + if (proid_is_exynos542x()) \ return EXYNOS5420_##base; \ return EXYNOS5_##base; \ } \ diff --git a/arch/arm/mach-exynos/include/mach/gpio.h b/arch/arm/mach-exynos/include/mach/gpio.h index 272e00bae8f..f9975d7919f 100644 --- a/arch/arm/mach-exynos/include/mach/gpio.h +++ b/arch/arm/mach-exynos/include/mach/gpio.h @@ -1397,7 +1397,7 @@ static struct gpio_info exynos5420_gpio_data[EXYNOS5420_GPIO_NUM_PARTS] = { static inline struct gpio_info *get_gpio_data(void) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) return exynos5420_gpio_data; else return exynos5_gpio_data; @@ -1414,7 +1414,7 @@ static inline struct gpio_info *get_gpio_data(void) static inline unsigned int get_bank_num(void) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) return EXYNOS5420_GPIO_NUM_PARTS; else return EXYNOS5_GPIO_NUM_PARTS; diff --git a/arch/arm/mach-exynos/pinmux.c b/arch/arm/mach-exynos/pinmux.c index f6743ca0f6e..b24f1bb8f4f 100644 --- a/arch/arm/mach-exynos/pinmux.c +++ b/arch/arm/mach-exynos/pinmux.c @@ -378,6 +378,20 @@ static void exynos5_i2s_config(int peripheral) } } +static void exynos5420_i2s_config(int peripheral) +{ + int i; + + switch (peripheral) { + case PERIPH_ID_I2S0: + for (i = 0; i < 5; i++) + gpio_cfg_pin(EXYNOS5420_GPIO_Z0 + i, + S5P_GPIO_FUNC(0x02)); + break; + } +} + + void exynos5_spi_config(int peripheral) { int cfg = 0, pin = 0, i; @@ -550,6 +564,9 @@ static int exynos5420_pinmux_config(int peripheral, int flags) case PERIPH_ID_I2C10: exynos5420_i2c_config(peripheral); break; + case PERIPH_ID_I2S0: + exynos5420_i2s_config(peripheral); + break; case PERIPH_ID_PWM0: gpio_cfg_pin(EXYNOS5420_GPIO_B20, S5P_GPIO_FUNC(2)); break; @@ -863,7 +880,7 @@ static int exynos4x12_pinmux_config(int peripheral, int flags) int exynos_pinmux_config(int peripheral, int flags) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) return exynos5420_pinmux_config(peripheral, flags); else if (proid_is_exynos5250()) return exynos5_pinmux_config(peripheral, flags); diff --git a/arch/arm/mach-exynos/power.c b/arch/arm/mach-exynos/power.c index 63c410aceff..f2a6c00dd62 100644 --- a/arch/arm/mach-exynos/power.c +++ b/arch/arm/mach-exynos/power.c @@ -124,7 +124,7 @@ static void exynos5420_set_usbdev_phy_ctrl(unsigned int enable) void set_usbdrd_phy_ctrl(unsigned int enable) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5422()) + if (proid_is_exynos542x()) exynos5420_set_usbdev_phy_ctrl(enable); else exynos5_set_usbdrd_phy_ctrl(enable); diff --git a/arch/arm/mach-k3/config.mk b/arch/arm/mach-k3/config.mk index 7fc0b3f3576..be00d79fb03 100644 --- a/arch/arm/mach-k3/config.mk +++ b/arch/arm/mach-k3/config.mk @@ -37,7 +37,7 @@ cmd_gencert = cat $(srctree)/tools/k3_x509template.txt | sed $(SED_OPTS) > u-boo ifeq ($(CONFIG_SYS_K3_KEY), "") KEY=u-boot-spl-eckey.pem else -KEY=$(patsubst "%",%,$(CONFIG_SYS_K3_KEY)) +KEY=$(patsubst "%",$(srctree)/%,$(CONFIG_SYS_K3_KEY)) endif u-boot-spl-eckey.pem: FORCE diff --git a/arch/arm/mach-mediatek/mt7629/lowlevel_init.S b/arch/arm/mach-mediatek/mt7629/lowlevel_init.S index 90dd4ea48e4..3375796b797 100644 --- a/arch/arm/mach-mediatek/mt7629/lowlevel_init.S +++ b/arch/arm/mach-mediatek/mt7629/lowlevel_init.S @@ -5,6 +5,14 @@ #include <linux/linkage.h> +#define WAIT_CODE_SRAM_BASE 0x0010ff00 + +#define SLAVE_JUMP_REG 0x10202034 +#define SLAVE1_MAGIC_REG 0x10202038 +#define SLAVE1_MAGIC_NUM 0x534c4131 + +#define GIC_CPU_BASE 0x10320000 + ENTRY(lowlevel_init) #ifndef CONFIG_SPL_BUILD @@ -28,6 +36,7 @@ ENTRY(lowlevel_init) mrc p15, 0, r0, c0, c0, 5 ands r1, r0, #0x40000000 bne go @ Go if UP + /* read slave CPU number */ ands r0, r0, #0x0f beq go @ Go if core0 on primary core tile b secondary @@ -37,14 +46,41 @@ go: mov pc, lr secondary: - /* read slave CPU number into r0 firstly */ - mrc p15, 0, r0, c0, c0, 5 - and r0, r0, #0x0f + /* enable GIC as cores will be waken up by IPI */ + ldr r2, =GIC_CPU_BASE + mov r1, #0xf0 + str r1, [r2, #4] + mov r1, #1 + str r1, [r2, #0] + + ldr r1, [r2] + orr r1, #1 + str r1, [r2] + + /* copy wait code into SRAM */ + ldr r0, =slave_cpu_wait + ldm r0, {r1 - r8} @ slave_cpu_wait has eight insns + ldr r0, =WAIT_CODE_SRAM_BASE + stm r0, {r1 - r8} + + /* pass args to slave_cpu_wait */ + ldr r0, =SLAVE1_MAGIC_REG + ldr r1, =SLAVE1_MAGIC_NUM + + /* jump to wait code in SRAM */ + ldr pc, =WAIT_CODE_SRAM_BASE -loop: - dsb - isb - wfi @Zzz... - b loop #endif ENDPROC(lowlevel_init) + +/* This function will be copied into SRAM */ +ENTRY(slave_cpu_wait) + wfi + ldr r2, [r0] + cmp r2, r1 + bne slave_cpu_wait + movw r0, #:lower16:SLAVE_JUMP_REG + movt r0, #:upper16:SLAVE_JUMP_REG + ldr r1, [r0] + mov pc, r1 +ENDPROC(slave_cpu_wait) diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c index aa1be8ebabc..919d05c88c7 100644 --- a/arch/arm/mach-mvebu/cpu.c +++ b/arch/arm/mach-mvebu/cpu.c @@ -283,10 +283,8 @@ int print_cpuinfo(void) * and sets the correct windows sizes and base addresses accordingly. * * These values are set in the scratch registers by the Marvell - * DDR3 training code, which is executed by the BootROM before the - * main payload (U-Boot) is executed. This training code is currently - * only available in the Marvell U-Boot version. It needs to be - * ported to mainline U-Boot SPL at some point. + * DDR3 training code, which is executed by the SPL before the + * main payload (U-Boot) is executed. */ static void update_sdram_window_sizes(void) { diff --git a/arch/arm/mach-omap2/am33xx/board.c b/arch/arm/mach-omap2/am33xx/board.c index 2fc364d112a..62158a95925 100644 --- a/arch/arm/mach-omap2/am33xx/board.c +++ b/arch/arm/mach-omap2/am33xx/board.c @@ -174,7 +174,55 @@ int cpu_mmc_init(bd_t *bis) /* AM33XX has two MUSB controllers which can be host or gadget */ #if (defined(CONFIG_USB_MUSB_GADGET) || defined(CONFIG_USB_MUSB_HOST)) && \ (defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1)) && \ - (!defined(CONFIG_DM_USB)) + (!CONFIG_IS_ENABLED(DM_USB) || !CONFIG_IS_ENABLED(OF_CONTROL)) && \ + (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_MUSB_NEW_SUPPORT)) + +static struct musb_hdrc_config musb_config = { + .multipoint = 1, + .dyn_fifo = 1, + .num_eps = 16, + .ram_bits = 12, +}; + +#if CONFIG_IS_ENABLED(DM_USB) && !CONFIG_IS_ENABLED(OF_CONTROL) +static struct ti_musb_platdata usb0 = { + .base = (void *)USB0_OTG_BASE, + .ctrl_mod_base = &((struct ctrl_dev *)CTRL_DEVICE_BASE)->usb_ctrl0, + .plat = { + .config = &musb_config, + .power = 50, + .platform_ops = &musb_dsps_ops, + }, +}; + +static struct ti_musb_platdata usb1 = { + .base = (void *)USB1_OTG_BASE, + .ctrl_mod_base = &((struct ctrl_dev *)CTRL_DEVICE_BASE)->usb_ctrl1, + .plat = { + .config = &musb_config, + .power = 50, + .platform_ops = &musb_dsps_ops, + }, +}; + +U_BOOT_DEVICES(am33xx_usbs) = { +#if CONFIG_AM335X_USB0_MODE == MUSB_PERIPHERAL + { "ti-musb-peripheral", &usb0 }, +#elif CONFIG_AM335X_USB0_MODE == MUSB_HOST + { "ti-musb-host", &usb0 }, +#endif +#if CONFIG_AM335X_USB1_MODE == MUSB_PERIPHERAL + { "ti-musb-peripheral", &usb1 }, +#elif CONFIG_AM335X_USB1_MODE == MUSB_HOST + { "ti-musb-host", &usb1 }, +#endif +}; + +int arch_misc_init(void) +{ + return 0; +} +#else static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; /* USB 2.0 PHY Control */ @@ -193,13 +241,6 @@ static void am33xx_usb_set_phy_power(u8 on, u32 *reg_addr) } } -static struct musb_hdrc_config musb_config = { - .multipoint = 1, - .dyn_fifo = 1, - .num_eps = 16, - .ram_bits = 12, -}; - #ifdef CONFIG_AM335X_USB0 static void am33xx_otg0_set_phy_power(struct udevice *dev, u8 on) { @@ -250,6 +291,7 @@ int arch_misc_init(void) #endif return 0; } +#endif #else /* CONFIG_USB_MUSB_* && CONFIG_AM335X_USB* && !CONFIG_DM_USB */ diff --git a/arch/arm/mach-omap2/omap3/Kconfig b/arch/arm/mach-omap2/omap3/Kconfig index e0d02fb4e59..0286b0daa33 100644 --- a/arch/arm/mach-omap2/omap3/Kconfig +++ b/arch/arm/mach-omap2/omap3/Kconfig @@ -3,18 +3,23 @@ if OMAP34XX # We only enable the clocks for the GPIO banks that a given board requies. config OMAP3_GPIO_2 bool + default y if CMD_GPIO config OMAP3_GPIO_3 bool + default y if CMD_GPIO config OMAP3_GPIO_4 bool + default y if CMD_GPIO config OMAP3_GPIO_5 bool + default y if CMD_GPIO config OMAP3_GPIO_6 bool + default y if CMD_GPIO choice prompt "OMAP3 board select" diff --git a/arch/arm/mach-omap2/omap3/clock.c b/arch/arm/mach-omap2/omap3/clock.c index 9a03bfa9d3b..cb9e91ebc3b 100644 --- a/arch/arm/mach-omap2/omap3/clock.c +++ b/arch/arm/mach-omap2/omap3/clock.c @@ -750,23 +750,23 @@ void per_clocks_enable(void) setbits_le32(&prcm_base->iclken_per, 0x00000800); #endif -#if (CONFIG_IS_ENABLED(OMAP3_GPIO_2) || CONFIG_IS_ENABLED(CMD_GPIO)) +#if defined(CONFIG_OMAP3_GPIO_2) setbits_le32(&prcm_base->fclken_per, 0x00002000); setbits_le32(&prcm_base->iclken_per, 0x00002000); #endif -#if (CONFIG_IS_ENABLED(OMAP3_GPIO_3) || CONFIG_IS_ENABLED(CMD_GPIO)) +#if defined(CONFIG_OMAP3_GPIO_3) setbits_le32(&prcm_base->fclken_per, 0x00004000); setbits_le32(&prcm_base->iclken_per, 0x00004000); #endif -#if (CONFIG_IS_ENABLED(OMAP3_GPIO_4) || CONFIG_IS_ENABLED(CMD_GPIO)) +#if defined(CONFIG_OMAP3_GPIO_4) setbits_le32(&prcm_base->fclken_per, 0x00008000); setbits_le32(&prcm_base->iclken_per, 0x00008000); #endif -#if (CONFIG_IS_ENABLED(OMAP3_GPIO_5) || CONFIG_IS_ENABLED(CMD_GPIO)) +#if defined(CONFIG_OMAP3_GPIO_5) setbits_le32(&prcm_base->fclken_per, 0x00010000); setbits_le32(&prcm_base->iclken_per, 0x00010000); #endif -#if (CONFIG_IS_ENABLED(OMAP3_GPIO_6) || CONFIG_IS_ENABLED(CMD_GPIO)) +#if defined(CONFIG_OMAP3_GPIO_6) setbits_le32(&prcm_base->fclken_per, 0x00020000); setbits_le32(&prcm_base->iclken_per, 0x00020000); #endif diff --git a/arch/arm/mach-rockchip/rv1108/Kconfig b/arch/arm/mach-rockchip/rv1108/Kconfig index e6cba66578d..8883aeae7a4 100644 --- a/arch/arm/mach-rockchip/rv1108/Kconfig +++ b/arch/arm/mach-rockchip/rv1108/Kconfig @@ -17,6 +17,11 @@ config TARGET_EVB_RV1108 * 10/100 Mbps Ethernet * camera interface compatible with imx323 / ov2710 / ov4689 +config TARGET_ELGIN_RV1108 + bool "ELGIN_RV1108" + help + RV1108 ELGIN is a board based on the Rockchip RV1108. + config SYS_SOC default "rockchip" @@ -24,5 +29,6 @@ config SYS_MALLOC_F_LEN default 0x400 source board/rockchip/evb_rv1108/Kconfig +source board/elgin/elgin_rv1108/Kconfig endif diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index 06f8527aa44..5e87371f8ca 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -35,6 +35,7 @@ config TARGET_SOCFPGA_STRATIX10 select ARMV8_MULTIENTRY select ARMV8_SET_SMPEN select ARMV8_SPIN_TABLE + select FPGA_STRATIX10 choice prompt "Altera SOCFPGA board select" diff --git a/arch/arm/mach-socfpga/include/mach/mailbox_s10.h b/arch/arm/mach-socfpga/include/mach/mailbox_s10.h index 81a609d2f82..ae728a5df5f 100644 --- a/arch/arm/mach-socfpga/include/mach/mailbox_s10.h +++ b/arch/arm/mach-socfpga/include/mach/mailbox_s10.h @@ -107,6 +107,12 @@ enum ALT_SDM_MBOX_RESP_CODE { #define RECONFIG_STATUS_PIN_STATUS 2 #define RECONFIG_STATUS_SOFTFUNC_STATUS 3 +/* Macros for specifying number of arguments in mailbox command */ +#define MBOX_NUM_ARGS(n, b) (((n) & 0xFF) << (b)) +#define MBOX_DIRECT_COUNT(n) MBOX_NUM_ARGS((n), 0) +#define MBOX_ARG_DESC_COUNT(n) MBOX_NUM_ARGS((n), 8) +#define MBOX_RESP_DESC_COUNT(n) MBOX_NUM_ARGS((n), 16) + #define MBOX_CFGSTAT_STATE_IDLE 0x00000000 #define MBOX_CFGSTAT_STATE_CONFIG 0x10000000 #define MBOX_CFGSTAT_STATE_FAILACK 0x08000000 @@ -140,5 +146,6 @@ int mbox_qspi_open(void); #endif int mbox_reset_cold(void); - +int mbox_get_fpga_config_status(u32 cmd); +int mbox_get_fpga_config_status_psci(u32 cmd); #endif /* _MAILBOX_S10_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h index 26609927c83..86d5d2b62b0 100644 --- a/arch/arm/mach-socfpga/include/mach/misc.h +++ b/arch/arm/mach-socfpga/include/mach/misc.h @@ -18,9 +18,9 @@ struct bsel { extern struct bsel bsel_str[]; #ifdef CONFIG_FPGA -void socfpga_fpga_add(void); +void socfpga_fpga_add(void *fpga_desc); #else -static inline void socfpga_fpga_add(void) {} +inline void socfpga_fpga_add(void *fpga_desc) {} #endif #ifdef CONFIG_TARGET_SOCFPGA_GEN5 diff --git a/arch/arm/mach-socfpga/mailbox_s10.c b/arch/arm/mach-socfpga/mailbox_s10.c index 0d906c3480f..3c332239361 100644 --- a/arch/arm/mach-socfpga/mailbox_s10.c +++ b/arch/arm/mach-socfpga/mailbox_s10.c @@ -342,6 +342,54 @@ int mbox_reset_cold(void) return 0; } +/* Accepted commands: CONFIG_STATUS or RECONFIG_STATUS */ +static __always_inline int mbox_get_fpga_config_status_common(u32 cmd) +{ + u32 reconfig_status_resp_len; + u32 reconfig_status_resp[RECONFIG_STATUS_RESPONSE_LEN]; + int ret; + + reconfig_status_resp_len = RECONFIG_STATUS_RESPONSE_LEN; + ret = mbox_send_cmd_common(MBOX_ID_UBOOT, cmd, + MBOX_CMD_DIRECT, 0, NULL, 0, + &reconfig_status_resp_len, + reconfig_status_resp); + + if (ret) + return ret; + + /* Check for any error */ + ret = reconfig_status_resp[RECONFIG_STATUS_STATE]; + if (ret && ret != MBOX_CFGSTAT_STATE_CONFIG) + return ret; + + /* Make sure nStatus is not 0 */ + ret = reconfig_status_resp[RECONFIG_STATUS_PIN_STATUS]; + if (!(ret & RCF_PIN_STATUS_NSTATUS)) + return MBOX_CFGSTAT_STATE_ERROR_HARDWARE; + + ret = reconfig_status_resp[RECONFIG_STATUS_SOFTFUNC_STATUS]; + if (ret & RCF_SOFTFUNC_STATUS_SEU_ERROR) + return MBOX_CFGSTAT_STATE_ERROR_HARDWARE; + + if ((ret & RCF_SOFTFUNC_STATUS_CONF_DONE) && + (ret & RCF_SOFTFUNC_STATUS_INIT_DONE) && + !reconfig_status_resp[RECONFIG_STATUS_STATE]) + return 0; /* configuration success */ + + return MBOX_CFGSTAT_STATE_CONFIG; +} + +int mbox_get_fpga_config_status(u32 cmd) +{ + return mbox_get_fpga_config_status_common(cmd); +} + +int __secure mbox_get_fpga_config_status_psci(u32 cmd) +{ + return mbox_get_fpga_config_status_common(cmd); +} + int mbox_send_cmd(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg, u8 urgent, u32 *resp_buf_len, u32 *resp_buf) { diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c index a4f6d5c1ac9..78fbe287244 100644 --- a/arch/arm/mach-socfpga/misc.c +++ b/arch/arm/mach-socfpga/misc.c @@ -88,33 +88,11 @@ int overwrite_console(void) #endif #ifdef CONFIG_FPGA -/* - * FPGA programming support for SoC FPGA Cyclone V - */ -static Altera_desc altera_fpga[] = { - { - /* Family */ - Altera_SoCFPGA, - /* Interface type */ - fast_passive_parallel, - /* No limitation as additional data will be ignored */ - -1, - /* No device function table */ - NULL, - /* Base interface address specified in driver */ - NULL, - /* No cookie implementation */ - 0 - }, -}; - /* add device descriptor to FPGA device table */ -void socfpga_fpga_add(void) +void socfpga_fpga_add(void *fpga_desc) { - int i; fpga_init(); - for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) - fpga_add(fpga_altera, &altera_fpga[i]); + fpga_add(fpga_altera, fpga_desc); } #endif diff --git a/arch/arm/mach-socfpga/misc_arria10.c b/arch/arm/mach-socfpga/misc_arria10.c index f347ae857e0..63b8c75d31d 100644 --- a/arch/arm/mach-socfpga/misc_arria10.c +++ b/arch/arm/mach-socfpga/misc_arria10.c @@ -30,6 +30,27 @@ static struct socfpga_system_manager *sysmgr_regs = (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + +/* + * FPGA programming support for SoC FPGA Arria 10 + */ +static Altera_desc altera_fpga[] = { + { + /* Family */ + Altera_SoCFPGA, + /* Interface type */ + fast_passive_parallel, + /* No limitation as additional data will be ignored */ + -1, + /* No device function table */ + NULL, + /* Base interface address specified in driver */ + NULL, + /* No cookie implementation */ + 0 + }, +}; + #if defined(CONFIG_SPL_BUILD) static struct pl310_regs *const pl310 = (struct pl310_regs *)CONFIG_SYS_PL310_BASE; @@ -73,7 +94,7 @@ void socfpga_sdram_remap_zero(void) int arch_early_init_r(void) { /* Add device descriptor to FPGA device table */ - socfpga_fpga_add(); + socfpga_fpga_add(&altera_fpga[0]); return 0; } diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c index 5fa40937c40..04f237d100c 100644 --- a/arch/arm/mach-socfpga/misc_gen5.c +++ b/arch/arm/mach-socfpga/misc_gen5.c @@ -35,6 +35,26 @@ static struct scu_registers *scu_regs = (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS; /* + * FPGA programming support for SoC FPGA Cyclone V + */ +static Altera_desc altera_fpga[] = { + { + /* Family */ + Altera_SoCFPGA, + /* Interface type */ + fast_passive_parallel, + /* No limitation as additional data will be ignored */ + -1, + /* No device function table */ + NULL, + /* Base interface address specified in driver */ + NULL, + /* No cookie implementation */ + 0 + }, +}; + +/* * DesignWare Ethernet initialization */ #ifdef CONFIG_ETH_DESIGNWARE @@ -221,7 +241,7 @@ int arch_early_init_r(void) socfpga_sdram_remap_zero(); /* Add device descriptor to FPGA device table */ - socfpga_fpga_add(); + socfpga_fpga_add(&altera_fpga[0]); #ifdef CONFIG_DESIGNWARE_SPI /* Get Designware SPI controller out of reset */ diff --git a/arch/arm/mach-socfpga/misc_s10.c b/arch/arm/mach-socfpga/misc_s10.c index e599362f145..113eace650e 100644 --- a/arch/arm/mach-socfpga/misc_s10.c +++ b/arch/arm/mach-socfpga/misc_s10.c @@ -25,6 +25,26 @@ static struct socfpga_system_manager *sysmgr_regs = (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; /* + * FPGA programming support for SoC FPGA Stratix 10 + */ +static Altera_desc altera_fpga[] = { + { + /* Family */ + Intel_FPGA_Stratix10, + /* Interface type */ + secure_device_manager_mailbox, + /* No limitation as additional data will be ignored */ + -1, + /* No device function table */ + NULL, + /* Base interface address specified in driver */ + NULL, + /* No cookie implementation */ + 0 + }, +}; + +/* * DesignWare Ethernet initialization */ #ifdef CONFIG_ETH_DESIGNWARE @@ -125,6 +145,8 @@ int arch_misc_init(void) int arch_early_init_r(void) { + socfpga_fpga_add(&altera_fpga[0]); + return 0; } diff --git a/arch/arm/mach-uniphier/board_late_init.c b/arch/arm/mach-uniphier/board_late_init.c index 1b871c62ced..972dbe8ae55 100644 --- a/arch/arm/mach-uniphier/board_late_init.c +++ b/arch/arm/mach-uniphier/board_late_init.c @@ -66,20 +66,20 @@ int board_late_init(void) switch (uniphier_boot_device_raw()) { case BOOT_DEVICE_MMC1: printf("eMMC Boot"); - env_set("bootcmd", "run bootcmd_mmc0; run distro_bootcmd"); + env_set("bootdev", "emmc"); break; case BOOT_DEVICE_NAND: printf("NAND Boot"); - env_set("bootcmd", "run bootcmd_ubifs0; run distro_bootcmd"); + env_set("bootdev", "nand"); nand_denali_wp_disable(); break; case BOOT_DEVICE_NOR: printf("NOR Boot"); - env_set("bootcmd", "run tftpboot; run distro_bootcmd"); + env_set("bootdev", "nor"); break; case BOOT_DEVICE_USB: printf("USB Boot"); - env_set("bootcmd", "run bootcmd_usb0; run distro_bootcmd"); + env_set("bootdev", "usb"); break; default: printf("Unknown"); diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1b1b1d7d003..194f4f349ed 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -59,6 +59,11 @@ config ARCH_ATH79 select OF_CONTROL imply CMD_DM +config ARCH_MSCC + bool "Support MSCC VCore-III" + select OF_CONTROL + select DM + config ARCH_BMIPS bool "Support BMIPS SoCs" select CLK @@ -79,7 +84,7 @@ config ARCH_MT7620 select DM_SERIAL imply DM_SPI imply DM_SPI_FLASH - select ARCH_MISC_INIT if WATCHDOG + select ARCH_MISC_INIT select MIPS_TUNE_24KC select OF_CONTROL select ROM_EXCEPTION_VECTORS @@ -88,6 +93,12 @@ config ARCH_MT7620 select SUPPORTS_LITTLE_ENDIAN select SYSRESET +config ARCH_JZ47XX + bool "Support Ingenic JZ47xx" + select SUPPORT_SPL + select OF_CONTROL + select DM + config MACH_PIC32 bool "Support Microchip PIC32" select DM @@ -138,7 +149,9 @@ source "board/imgtec/xilfpga/Kconfig" source "board/micronas/vct/Kconfig" source "board/qemu-mips/Kconfig" source "arch/mips/mach-ath79/Kconfig" +source "arch/mips/mach-mscc/Kconfig" source "arch/mips/mach-bmips/Kconfig" +source "arch/mips/mach-jz47xx/Kconfig" source "arch/mips/mach-pic32/Kconfig" source "arch/mips/mach-mt7620/Kconfig" diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 802244a06e5..029d290f1e0 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -13,8 +13,10 @@ libs-y += arch/mips/lib/ machine-$(CONFIG_ARCH_ATH79) += ath79 machine-$(CONFIG_ARCH_BMIPS) += bmips +machine-$(CONFIG_ARCH_JZ47XX) += jz47xx machine-$(CONFIG_MACH_PIC32) += pic32 machine-$(CONFIG_ARCH_MT7620) += mt7620 +machine-$(CONFIG_ARCH_MSCC) += mscc machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y)) libs-y += $(machdirs) diff --git a/arch/mips/cpu/cpu.c b/arch/mips/cpu/cpu.c index 5c56ab0289e..a403ff729b1 100644 --- a/arch/mips/cpu/cpu.c +++ b/arch/mips/cpu/cpu.c @@ -28,16 +28,6 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #endif -void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) -{ - write_c0_entrylo0(low0); - write_c0_pagemask(pagemask); - write_c0_entrylo1(low1); - write_c0_entryhi(hi); - write_c0_index(index); - tlb_write_indexed(); -} - int arch_cpu_init(void) { mips_cache_probe(); diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile index b447141f871..647d2bf0d53 100644 --- a/arch/mips/dts/Makefile +++ b/arch/mips/dts/Makefile @@ -16,6 +16,7 @@ dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb dtb-$(CONFIG_BOARD_NETGEAR_DGND3700V2) += netgear,dgnd3700v2.dtb dtb-$(CONFIG_BOARD_SAGEM_FAST1704) += sagem,f@st1704.dtb dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb +dtb-$(CONFIG_TARGET_JZ4780_CI20) += ci20.dtb targets += $(dtb-y) diff --git a/arch/mips/dts/ar933x.dtsi b/arch/mips/dts/ar933x.dtsi index 85fb14b13bd..37354324fe0 100644 --- a/arch/mips/dts/ar933x.dtsi +++ b/arch/mips/dts/ar933x.dtsi @@ -3,7 +3,6 @@ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com> */ -#include <dt-bindings/interrupt-controller/irq.h> #include "skeleton.dtsi" / { @@ -68,7 +67,6 @@ uart0: uart@18020000 { compatible = "qca,ar9330-uart"; reg = <0x18020000 0x20>; - interrupts = <128 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -103,7 +101,6 @@ spi0: spi@1f000000 { compatible = "qca,ar7100-spi"; reg = <0x1f000000 0x10>; - interrupts = <129 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; diff --git a/arch/mips/dts/brcm,bcm6318.dtsi b/arch/mips/dts/brcm,bcm6318.dtsi index f75988be129..d678dab242b 100644 --- a/arch/mips/dts/brcm,bcm6318.dtsi +++ b/arch/mips/dts/brcm,bcm6318.dtsi @@ -4,6 +4,7 @@ */ #include <dt-bindings/clock/bcm6318-clock.h> +#include <dt-bindings/dma/bcm6318-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/power-domain/bcm6318-power-domain.h> #include <dt-bindings/reset/bcm6318-reset.h> @@ -54,6 +55,12 @@ reg = <0x10000004 0x4>; #clock-cells = <1>; }; + + ubus_clk: ubus-clk { + compatible = "brcm,bcm6345-clk"; + reg = <0x10000008 0x4>; + #clock-cells = <1>; + }; }; ubus { @@ -182,5 +189,36 @@ status = "disabled"; }; + + enet: ethernet@10080000 { + compatible = "brcm,bcm6368-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x10080000 0x8000>; + clocks = <&periph_clk BCM6318_CLK_ROBOSW250>, + <&periph_clk BCM6318_CLK_ROBOSW025>, + <&ubus_clk BCM6318_UCLK_ROBOSW>; + resets = <&periph_rst BCM6318_RST_ENETSW>, + <&periph_rst BCM6318_RST_EPHY>; + dmas = <&iudma BCM6318_DMA_ENETSW_RX>, + <&iudma BCM6318_DMA_ENETSW_TX>; + dma-names = "rx", + "tx"; + brcm,num-ports = <5>; + + status = "disabled"; + }; + + iudma: dma-controller@10088000 { + compatible = "brcm,bcm6368-iudma"; + reg = <0x10088000 0x80>, + <0x10088200 0x80>, + <0x10088400 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + }; }; }; diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi index 62c440e6759..f8a72ef535d 100644 --- a/arch/mips/dts/brcm,bcm63268.dtsi +++ b/arch/mips/dts/brcm,bcm63268.dtsi @@ -4,6 +4,7 @@ */ #include <dt-bindings/clock/bcm63268-clock.h> +#include <dt-bindings/dma/bcm63268-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/power-domain/bcm63268-power-domain.h> #include <dt-bindings/reset/bcm63268-reset.h> @@ -217,5 +218,42 @@ reg = <0x10003000 0x894>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller@1000d800 { + compatible = "brcm,bcm6368-iudma"; + reg = <0x1000d800 0x80>, + <0x1000da00 0x80>, + <0x1000dc00 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + }; + + enet: ethernet@10700000 { + compatible = "brcm,bcm6368-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x10700000 0x10000>; + clocks = <&periph_clk BCM63268_CLK_GMAC>, + <&periph_clk BCM63268_CLK_ROBOSW>, + <&periph_clk BCM63268_CLK_ROBOSW250>, + <&timer_clk BCM63268_TCLK_EPHY1>, + <&timer_clk BCM63268_TCLK_EPHY2>, + <&timer_clk BCM63268_TCLK_EPHY3>, + <&timer_clk BCM63268_TCLK_GPHY>; + resets = <&periph_rst BCM63268_RST_ENETSW>, + <&periph_rst BCM63268_RST_EPHY>, + <&periph_rst BCM63268_RST_GPHY>; + dmas = <&iudma BCM63268_DMA_ENETSW_RX>, + <&iudma BCM63268_DMA_ENETSW_TX>; + dma-names = "rx", + "tx"; + brcm,rgmii-override; + brcm,rgmii-timing; + + status = "disabled"; + }; }; }; diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi index e00a2950e22..50beed4171a 100644 --- a/arch/mips/dts/brcm,bcm6328.dtsi +++ b/arch/mips/dts/brcm,bcm6328.dtsi @@ -4,6 +4,7 @@ */ #include <dt-bindings/clock/bcm6328-clock.h> +#include <dt-bindings/dma/bcm6328-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/power-domain/bcm6328-power-domain.h> #include <dt-bindings/reset/bcm6328-reset.h> @@ -187,5 +188,34 @@ reg = <0x10003000 0x864>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller@1000d800 { + compatible = "brcm,bcm6368-iudma"; + reg = <0x1000d800 0x80>, + <0x1000da00 0x80>, + <0x1000dc00 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + }; + + enet: ethernet@10e00000 { + compatible = "brcm,bcm6368-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x10e00000 0x10000>; + clocks = <&periph_clk BCM6328_CLK_ROBOSW>; + resets = <&periph_rst BCM6328_RST_ENETSW>, + <&periph_rst BCM6328_RST_EPHY>; + dmas = <&iudma BCM6328_DMA_ENETSW_RX>, + <&iudma BCM6328_DMA_ENETSW_TX>; + dma-names = "rx", + "tx"; + brcm,num-ports = <5>; + + status = "disabled"; + }; }; }; diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi index bbd58cf803d..c547e949ddc 100644 --- a/arch/mips/dts/brcm,bcm6338.dtsi +++ b/arch/mips/dts/brcm,bcm6338.dtsi @@ -4,6 +4,7 @@ */ #include <dt-bindings/clock/bcm6338-clock.h> +#include <dt-bindings/dma/bcm6338-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6338-reset.h> #include "skeleton.dtsi" @@ -130,5 +131,33 @@ reg = <0xfffe3100 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller@fffe2400 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe2400 0x1c>, + <0xfffe2500 0x60>, + <0xfffe2600 0x60>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <6>; + resets = <&periph_rst BCM6338_RST_DMAMEM>; + }; + + enet: ethernet@fffe2800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe2800 0x2dc>; + clocks = <&periph_clk BCM6338_CLK_ENET>; + resets = <&periph_rst BCM6338_RST_ENET>; + dmas = <&iudma BCM6338_DMA_ENET_RX>, + <&iudma BCM6338_DMA_ENET_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; }; }; diff --git a/arch/mips/dts/brcm,bcm6348.dtsi b/arch/mips/dts/brcm,bcm6348.dtsi index cc80bbc808d..79e7bd892bc 100644 --- a/arch/mips/dts/brcm,bcm6348.dtsi +++ b/arch/mips/dts/brcm,bcm6348.dtsi @@ -4,6 +4,7 @@ */ #include <dt-bindings/clock/bcm6348-clock.h> +#include <dt-bindings/dma/bcm6348-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6348-reset.h> #include "skeleton.dtsi" @@ -159,5 +160,46 @@ reg = <0xfffe2300 0x38>; u-boot,dm-pre-reloc; }; + + enet0: ethernet@fffe6000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6000 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET0_RX>, + <&iudma BCM6348_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet@fffe6800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6800 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET1_RX>, + <&iudma BCM6348_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + iudma: dma-controller@fffe7000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe7000 0x1c>, + <0xfffe7100 0x40>, + <0xfffe7200 0x40>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <4>; + clocks = <&periph_clk BCM6348_CLK_ENET>; + resets = <&periph_rst BCM6348_RST_ENET>, + <&periph_rst BCM6348_RST_DMAMEM>; + }; }; }; diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi index 0617b46e926..5e9c9ad7698 100644 --- a/arch/mips/dts/brcm,bcm6358.dtsi +++ b/arch/mips/dts/brcm,bcm6358.dtsi @@ -4,6 +4,7 @@ */ #include <dt-bindings/clock/bcm6358-clock.h> +#include <dt-bindings/dma/bcm6358-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6358-reset.h> #include "skeleton.dtsi" @@ -190,5 +191,50 @@ status = "disabled"; }; + + enet0: ethernet@fffe4000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4000 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET0>; + dmas = <&iudma BCM6358_DMA_ENET0_RX>, + <&iudma BCM6358_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet@fffe4800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4800 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET1>; + dmas = <&iudma BCM6358_DMA_ENET1_RX>, + <&iudma BCM6358_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + iudma: dma-controller@fffe5000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe5000 0x24>, + <0xfffe5100 0x80>, + <0xfffe5200 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + clocks = <&periph_clk BCM6358_CLK_EMUSB>, + <&periph_clk BCM6358_CLK_USBSU>, + <&periph_clk BCM6358_CLK_EPHY>; + resets = <&periph_rst BCM6358_RST_ENET>, + <&periph_rst BCM6358_RST_EPHY>; + }; }; }; diff --git a/arch/mips/dts/brcm,bcm6362.dtsi b/arch/mips/dts/brcm,bcm6362.dtsi index 3047b82b219..c77b80a4cca 100644 --- a/arch/mips/dts/brcm,bcm6362.dtsi +++ b/arch/mips/dts/brcm,bcm6362.dtsi @@ -4,6 +4,7 @@ */ #include <dt-bindings/clock/bcm6362-clock.h> +#include <dt-bindings/dma/bcm6362-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/power-domain/bcm6362-power-domain.h> #include <dt-bindings/reset/bcm6362-reset.h> @@ -211,5 +212,36 @@ reg = <0x10003000 0x864>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller@1000d800 { + compatible = "brcm,bcm6368-iudma"; + reg = <0x1000d800 0x80>, + <0x1000da00 0x80>, + <0x1000dc00 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + }; + + enet: ethernet@10e00000 { + compatible = "brcm,bcm6368-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x10e00000 0x10000>; + clocks = <&periph_clk BCM6362_CLK_SWPKT_USB>, + <&periph_clk BCM6362_CLK_SWPKT_SAR>, + <&periph_clk BCM6362_CLK_ROBOSW>; + resets = <&periph_rst BCM6362_RST_ENETSW>, + <&periph_rst BCM6362_RST_EPHY>; + dmas = <&iudma BCM6362_DMA_ENETSW_RX>, + <&iudma BCM6362_DMA_ENETSW_TX>; + dma-names = "rx", + "tx"; + brcm,num-ports = <6>; + + status = "disabled"; + }; }; }; diff --git a/arch/mips/dts/brcm,bcm6368.dtsi b/arch/mips/dts/brcm,bcm6368.dtsi index 65d769ab4f2..89590d6ff9f 100644 --- a/arch/mips/dts/brcm,bcm6368.dtsi +++ b/arch/mips/dts/brcm,bcm6368.dtsi @@ -4,6 +4,7 @@ */ #include <dt-bindings/clock/bcm6368-clock.h> +#include <dt-bindings/dma/bcm6368-dma.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/reset/bcm6368-reset.h> #include "skeleton.dtsi" @@ -192,5 +193,36 @@ status = "disabled"; }; + + iudma: dma-controller@10006800 { + compatible = "brcm,bcm6368-iudma"; + reg = <0x10006800 0x80>, + <0x10006a00 0x80>, + <0x10006c00 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + }; + + enet: ethernet@10f00000 { + compatible = "brcm,bcm6368-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x10f00000 0x10000>; + clocks = <&periph_clk BCM6368_CLK_SWPKT_USB>, + <&periph_clk BCM6368_CLK_SWPKT_SAR>, + <&periph_clk BCM6368_CLK_ROBOSW>; + resets = <&periph_rst BCM6368_RST_SWITCH>, + <&periph_rst BCM6368_RST_EPHY>; + dmas = <&iudma BCM6368_DMA_ENETSW_RX>, + <&iudma BCM6368_DMA_ENETSW_TX>; + dma-names = "rx", + "tx"; + brcm,num-ports = <6>; + + status = "disabled"; + }; }; }; diff --git a/arch/mips/dts/ci20.dts b/arch/mips/dts/ci20.dts new file mode 100644 index 00000000000..8d6417af73e --- /dev/null +++ b/arch/mips/dts/ci20.dts @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +#include "jz4780.dtsi" + +/ { + compatible = "img,ci20", "ingenic,jz4780"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial3 = &uart3; + serial4 = &uart4; + }; + + chosen { + stdout-path = "serial4:115200n8"; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x10000000 + 0x30000000 0x30000000>; + }; +}; + +&ext { + clock-frequency = <48000000>; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&nemc { + status = "okay"; + + nandc: nand-controller@1 { + compatible = "ingenic,jz4780-nand"; + reg = <1 0 0x1000000>; + + #address-cells = <1>; + #size-cells = <0>; + + ingenic,bch-controller = <&bch>; + + ingenic,nemc-tAS = <10>; + ingenic,nemc-tAH = <5>; + ingenic,nemc-tBP = <10>; + ingenic,nemc-tAW = <15>; + ingenic,nemc-tSTRV = <100>; + + nand@1 { + reg = <1>; + + nand-ecc-step-size = <1024>; + nand-ecc-strength = <24>; + nand-ecc-mode = "hw"; + nand-on-flash-bbt; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <2>; + #size-cells = <2>; + + partition@0 { + label = "u-boot-spl"; + reg = <0x0 0x0 0x0 0x800000>; + }; + + partition@0x800000 { + label = "u-boot"; + reg = <0x0 0x800000 0x0 0x200000>; + }; + + partition@0xa00000 { + label = "u-boot-env"; + reg = <0x0 0xa00000 0x0 0x200000>; + }; + + partition@0xc00000 { + label = "boot"; + reg = <0x0 0xc00000 0x0 0x4000000>; + }; + + partition@0x8c00000 { + label = "system"; + reg = <0x0 0x4c00000 0x1 0xfb400000>; + }; + }; + }; + }; +}; + +&bch { + status = "okay"; +}; + +&mmc0 { + bus-width = <4>; + max-frequency = <50000000>; + status = "okay"; +}; + +&mmc1 { + bus-width = <4>; + max-frequency = <50000000>; + status = "okay"; +}; diff --git a/arch/mips/dts/comtrend,ar-5315u.dts b/arch/mips/dts/comtrend,ar-5315u.dts index 45570189d0b..eb60aaa8d5f 100644 --- a/arch/mips/dts/comtrend,ar-5315u.dts +++ b/arch/mips/dts/comtrend,ar-5315u.dts @@ -24,6 +24,38 @@ status = "okay"; }; +&enet { + status = "okay"; + + port@0 { + compatible = "brcm,enetsw-port"; + reg = <0>; + label = "fe4"; + brcm,phy-id = <1>; + }; + + port@1 { + compatible = "brcm,enetsw-port"; + reg = <1>; + label = "fe3"; + brcm,phy-id = <2>; + }; + + port@2 { + compatible = "brcm,enetsw-port"; + reg = <2>; + label = "fe2"; + brcm,phy-id = <3>; + }; + + port@3 { + compatible = "brcm,enetsw-port"; + reg = <3>; + label = "fe1"; + brcm,phy-id = <4>; + }; +}; + &leds { status = "okay"; diff --git a/arch/mips/dts/comtrend,ar-5387un.dts b/arch/mips/dts/comtrend,ar-5387un.dts index e993b5cd89d..03e3851ab15 100644 --- a/arch/mips/dts/comtrend,ar-5387un.dts +++ b/arch/mips/dts/comtrend,ar-5387un.dts @@ -24,6 +24,38 @@ status = "okay"; }; +&enet { + status = "okay"; + + port@0 { + compatible = "brcm,enetsw-port"; + reg = <0>; + label = "fe1"; + brcm,phy-id = <1>; + }; + + port@1 { + compatible = "brcm,enetsw-port"; + reg = <1>; + label = "fe2"; + brcm,phy-id = <2>; + }; + + port@2 { + compatible = "brcm,enetsw-port"; + reg = <2>; + label = "fe3"; + brcm,phy-id = <3>; + }; + + port@3 { + compatible = "brcm,enetsw-port"; + reg = <3>; + label = "fe4"; + brcm,phy-id = <4>; + }; +}; + &leds { status = "okay"; diff --git a/arch/mips/dts/comtrend,ct-5361.dts b/arch/mips/dts/comtrend,ct-5361.dts index 25747ca95d7..f6b8a94e255 100644 --- a/arch/mips/dts/comtrend,ct-5361.dts +++ b/arch/mips/dts/comtrend,ct-5361.dts @@ -34,6 +34,18 @@ }; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; }; diff --git a/arch/mips/dts/comtrend,vr-3032u.dts b/arch/mips/dts/comtrend,vr-3032u.dts index 8c6a4a1eac9..512cb52de30 100644 --- a/arch/mips/dts/comtrend,vr-3032u.dts +++ b/arch/mips/dts/comtrend,vr-3032u.dts @@ -24,6 +24,38 @@ status = "okay"; }; +&enet { + status = "okay"; + + port@0 { + compatible = "brcm,enetsw-port"; + reg = <0>; + label = "fe2"; + brcm,phy-id = <1>; + }; + + port@1 { + compatible = "brcm,enetsw-port"; + reg = <1>; + label = "fe3"; + brcm,phy-id = <2>; + }; + + port@2 { + compatible = "brcm,enetsw-port"; + reg = <2>; + label = "fe4"; + brcm,phy-id = <3>; + }; + + port@3 { + compatible = "brcm,enetsw-port"; + reg = <3>; + label = "fe1"; + brcm,phy-id = <4>; + }; +}; + &leds { status = "okay"; brcm,serial-leds; diff --git a/arch/mips/dts/comtrend,wap-5813n.dts b/arch/mips/dts/comtrend,wap-5813n.dts index bd41dab9f8e..7e835b28d2c 100644 --- a/arch/mips/dts/comtrend,wap-5813n.dts +++ b/arch/mips/dts/comtrend,wap-5813n.dts @@ -54,6 +54,20 @@ status = "okay"; }; +&enet { + status = "okay"; + + port@4 { + compatible = "brcm,enetsw-port"; + reg = <4>; + label = "rgmii"; + brcm,phy-id = <0xff>; + speed = <1000>; + full-duplex; + bypass-link; + }; +}; + &gpio0 { status = "okay"; }; diff --git a/arch/mips/dts/huawei,hg556a.dts b/arch/mips/dts/huawei,hg556a.dts index 60455c2ff8a..6a7fc1df4b9 100644 --- a/arch/mips/dts/huawei,hg556a.dts +++ b/arch/mips/dts/huawei,hg556a.dts @@ -93,6 +93,18 @@ status = "okay"; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; }; diff --git a/arch/mips/dts/jz4780.dtsi b/arch/mips/dts/jz4780.dtsi new file mode 100644 index 00000000000..f62a7a95f88 --- /dev/null +++ b/arch/mips/dts/jz4780.dtsi @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <dt-bindings/clock/jz4780-cgu.h> + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ingenic,jz4780"; + + cpuintc: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + intc: interrupt-controller@10001000 { + compatible = "ingenic,jz4780-intc"; + reg = <0x10001000 0x50>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; + + ext: ext { + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + + rtc: rtc { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + cgu: jz4780-cgu@10000000 { + compatible = "ingenic,jz4780-cgu"; + reg = <0x10000000 0x100>; + + clocks = <&ext>, <&rtc>; + clock-names = "ext", "rtc"; + + #clock-cells = <1>; + }; + + mmc0: mmc@13450000 { + compatible = "ingenic,jz4780-mmc"; + reg = <0x13450000 0x1000>; + + status = "disabled"; + + clocks = <&cgu JZ4780_CLK_MSC0>; + clock-names = "mmc"; + }; + + mmc1: mmc@13460000 { + compatible = "ingenic,jz4780-mmc"; + reg = <0x13460000 0x1000>; + + clocks = <&cgu JZ4780_CLK_MSC1>; + clock-names = "mmc"; + + status = "disabled"; + }; + + uart0: serial@10030000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10030000 0x100>; + reg-shift = <2>; + + interrupt-parent = <&intc>; + interrupts = <51>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART0>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + uart1: serial@10031000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10031000 0x100>; + reg-shift = <2>; + + interrupt-parent = <&intc>; + interrupts = <50>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART1>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + uart2: serial@10032000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10032000 0x100>; + reg-shift = <2>; + + interrupt-parent = <&intc>; + interrupts = <49>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART2>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + uart3: serial@10033000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10033000 0x100>; + reg-shift = <2>; + + interrupt-parent = <&intc>; + interrupts = <48>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART3>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + uart4: serial@10034000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10034000 0x100>; + reg-shift = <2>; + + interrupt-parent = <&intc>; + interrupts = <34>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART4>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + nemc: nemc@13410000 { + compatible = "ingenic,jz4780-nemc"; + reg = <0x13410000 0x10000>; + #address-cells = <2>; + #size-cells = <1>; + ranges = <1 0 0x1b000000 0x1000000 + 2 0 0x1a000000 0x1000000 + 3 0 0x19000000 0x1000000 + 4 0 0x18000000 0x1000000 + 5 0 0x17000000 0x1000000 + 6 0 0x16000000 0x1000000>; + + clocks = <&cgu JZ4780_CLK_NEMC>; + + status = "disabled"; + }; + + bch: bch@134d0000 { + compatible = "ingenic,jz4780-bch"; + reg = <0x134d0000 0x10000>; + + clocks = <&cgu JZ4780_CLK_BCH>; + + status = "disabled"; + }; +}; diff --git a/arch/mips/dts/luton_pcb091.dts b/arch/mips/dts/luton_pcb091.dts new file mode 100644 index 00000000000..74f9274c218 --- /dev/null +++ b/arch/mips/dts/luton_pcb091.dts @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,luton.dtsi" + +/ { + model = "Luton10 PCB091 Reference Board"; + compatible = "mscc,luton-pcb091", "mscc,luton"; + + aliases { + serial0 = &uart0; + spi0 = &spi0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + spi-flash@0 { + compatible = "spi-flash"; + spi-max-frequency = <18000000>; /* input clock */ + reg = <0>; /* CS0 */ + spi-cs-high; + }; +}; + diff --git a/arch/mips/dts/mscc,luton.dtsi b/arch/mips/dts/mscc,luton.dtsi new file mode 100644 index 00000000000..6a4ad2a5be0 --- /dev/null +++ b/arch/mips/dts/mscc,luton.dtsi @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <dt-bindings/gpio/gpio.h> + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mscc,luton"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "mips,mips24KEc"; + device_type = "cpu"; + reg = <0>; + }; + }; + + aliases { + serial0 = &uart0; + }; + + ahb_clk: ahb-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <208333333>; + }; + + ahb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x60000000 0x10200000>; + + uart0: serial@10100000 { + pinctrl-0 = <&uart_pins>; + pinctrl-names = "default"; + + compatible = "ns16550a"; + reg = <0x10100000 0x20>; + clocks = <&ahb_clk>; + reg-io-width = <4>; + reg-shift = <2>; + + status = "disabled"; + }; + + gpio: pinctrl@70068 { + compatible = "mscc,luton-pinctrl"; + reg = <0x70068 0x68>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&gpio 0 0 32>; + + uart_pins: uart-pins { + pins = "GPIO_30", "GPIO_31"; + function = "uart"; + }; + + }; + + gpio_spi_bitbang: gpio@10000064 { + compatible = "mscc,spi-bitbang-gpio"; + reg = <0x10000064 0x4>; + gpio-controller; + #gpio-cells = <2>; + + }; + + spi0: spi-bitbang { + compatible = "spi-gpio"; + status = "okay"; + gpio-sck = <&gpio_spi_bitbang 6 0>; + gpio-miso = <&gpio_spi_bitbang 0 0>; + gpio-mosi = <&gpio_spi_bitbang 5 0>; + cs-gpios = <&gpio_spi_bitbang 1 0>; + num-chipselects = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; diff --git a/arch/mips/dts/mscc,ocelot.dtsi b/arch/mips/dts/mscc,ocelot.dtsi new file mode 100644 index 00000000000..87b47362855 --- /dev/null +++ b/arch/mips/dts/mscc,ocelot.dtsi @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mscc,ocelot"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "mips,mips24KEc"; + device_type = "cpu"; + clocks = <&cpu_clk>; + reg = <0>; + }; + }; + + aliases { + serial0 = &uart0; + }; + + cpuintc: interrupt-controller@0 { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + cpu_clk: cpu-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <500000000>; + }; + + ahb_clk: ahb-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + }; + + ahb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x70000000 0x2000000>; + + interrupt-parent = <&intc>; + + cpu_ctrl: syscon@0 { + compatible = "mscc,ocelot-cpu-syscon", "syscon"; + reg = <0x0 0x2c>; + }; + + intc: interrupt-controller@70 { + compatible = "mscc,ocelot-icpu-intr"; + reg = <0x70 0x70>; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; + + uart0: serial@100000 { + pinctrl-0 = <&uart_pins>; + pinctrl-names = "default"; + compatible = "ns16550a"; + reg = <0x100000 0x20>; + interrupts = <6>; + clocks = <&ahb_clk>; + reg-io-width = <4>; + reg-shift = <2>; + + status = "disabled"; + }; + + uart2: serial@100800 { + pinctrl-0 = <&uart2_pins>; + pinctrl-names = "default"; + compatible = "ns16550a"; + reg = <0x100800 0x20>; + interrupts = <7>; + clocks = <&ahb_clk>; + reg-io-width = <4>; + reg-shift = <2>; + + status = "disabled"; + }; + + spi0: spi-master@101000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dw-apb-ssi"; + reg = <0x101000 0x40>; + num-chipselect = <4>; + bus-num = <0>; + reg-io-width = <4>; + reg-shift = <2>; + spi-max-frequency = <18000000>; /* input clock */ + clocks = <&ahb_clk>; + + status = "disabled"; + }; + + reset@1070008 { + compatible = "mscc,ocelot-chip-reset"; + reg = <0x1070008 0x4>; + }; + + gpio: pinctrl@1070034 { + compatible = "mscc,ocelot-pinctrl"; + reg = <0x1070034 0x68>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&gpio 0 0 22>; + + uart_pins: uart-pins { + pins = "GPIO_6", "GPIO_7"; + function = "uart"; + }; + + uart2_pins: uart2-pins { + pins = "GPIO_12", "GPIO_13"; + function = "uart2"; + }; + + spi_cs1_pin: spi-cs1-pin { + pins = "GPIO_8"; + function = "si"; + }; + + spi_cs2_pin: spi-cs2-pin { + pins = "GPIO_9"; + function = "si"; + }; + + spi_cs3_pin: spi-cs3-pin { + pins = "GPIO_16"; + function = "si"; + }; + + spi_cs4_pin: spi-cs4-pin { + pins = "GPIO_17"; + function = "si"; + }; + }; + }; +}; diff --git a/arch/mips/dts/mscc,ocelot_pcb.dtsi b/arch/mips/dts/mscc,ocelot_pcb.dtsi new file mode 100644 index 00000000000..90725d3b941 --- /dev/null +++ b/arch/mips/dts/mscc,ocelot_pcb.dtsi @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,ocelot.dtsi" + +/ { + compatible = "mscc,ocelot"; + + aliases { + spi0 = &spi0; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + pinctrl-0 = <&spi_cs1_pin>; + pinctrl-names = "default"; + + spi-flash@0 { + compatible = "spi-flash"; + spi-max-frequency = <18000000>; /* input clock */ + reg = <0>; /* CS0 */ + }; + + spi-nand@1 { + compatible = "spi-nand"; + spi-max-frequency = <18000000>; /* input clock */ + reg = <1>; /* CS1 */ + }; +}; diff --git a/arch/mips/dts/netgear,dgnd3700v2.dts b/arch/mips/dts/netgear,dgnd3700v2.dts index 322d1567ffd..2b72491f0b2 100644 --- a/arch/mips/dts/netgear,dgnd3700v2.dts +++ b/arch/mips/dts/netgear,dgnd3700v2.dts @@ -43,6 +43,20 @@ status = "okay"; }; +&enet { + status = "okay"; + + port@4 { + compatible = "brcm,enetsw-port"; + reg = <4>; + label = "rgmii"; + brcm,phy-id = <0xff>; + speed = <1000>; + full-duplex; + bypass-link; + }; +}; + &gpio0 { status = "okay"; }; diff --git a/arch/mips/dts/nexys4ddr.dts b/arch/mips/dts/nexys4ddr.dts index e254ab1eaaf..6de8584ea79 100644 --- a/arch/mips/dts/nexys4ddr.dts +++ b/arch/mips/dts/nexys4ddr.dts @@ -40,7 +40,6 @@ #address-cells = <1>; #size-cells = <0>; phy0: phy@1 { - compatible = <0x0007c0f0 0xfffffff0>; device_type = "ethernet-phy"; reg = <1>; } ; diff --git a/arch/mips/dts/ocelot_pcb120.dts b/arch/mips/dts/ocelot_pcb120.dts new file mode 100644 index 00000000000..47d305a6141 --- /dev/null +++ b/arch/mips/dts/ocelot_pcb120.dts @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,ocelot_pcb.dtsi" + +/ { + model = "Ocelot PCB120 Reference Board"; + compatible = "mscc,ocelot-pcb120", "mscc,ocelot"; +}; diff --git a/arch/mips/dts/ocelot_pcb123.dts b/arch/mips/dts/ocelot_pcb123.dts new file mode 100644 index 00000000000..17d8d326cea --- /dev/null +++ b/arch/mips/dts/ocelot_pcb123.dts @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,ocelot_pcb.dtsi" + +/ { + model = "Ocelot PCB123 Reference Board"; + compatible = "mscc,ocelot-pcb123", "mscc,ocelot"; +}; diff --git a/arch/mips/dts/qca953x.dtsi b/arch/mips/dts/qca953x.dtsi index 599e809c479..ba29ea287e2 100644 --- a/arch/mips/dts/qca953x.dtsi +++ b/arch/mips/dts/qca953x.dtsi @@ -3,7 +3,6 @@ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com> */ -#include <dt-bindings/interrupt-controller/irq.h> #include "skeleton.dtsi" / { @@ -63,7 +62,6 @@ reg = <0x18020000 0x20>; reg-shift = <2>; clock-frequency = <25000000>; - interrupts = <128 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -72,7 +70,6 @@ spi0: spi@1f000000 { compatible = "qca,ar7100-spi"; reg = <0x1f000000 0x10>; - interrupts = <129 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; diff --git a/arch/mips/dts/sagem,f@st1704.dts b/arch/mips/dts/sagem,f@st1704.dts index 5300f8b6df9..ec6846dd9f2 100644 --- a/arch/mips/dts/sagem,f@st1704.dts +++ b/arch/mips/dts/sagem,f@st1704.dts @@ -39,6 +39,18 @@ }; }; +&enet { + status = "okay"; + phy = <&enetphy>; + phy-mode = "mii"; + + enetphy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio { status = "okay"; }; diff --git a/arch/mips/dts/sfr,nb4-ser.dts b/arch/mips/dts/sfr,nb4-ser.dts index bdc6f8ae455..dfbc4148dcd 100644 --- a/arch/mips/dts/sfr,nb4-ser.dts +++ b/arch/mips/dts/sfr,nb4-ser.dts @@ -53,6 +53,30 @@ status = "okay"; }; +&enet0 { + status = "okay"; + phy = <&enet0phy>; + phy-mode = "internal"; + + enet0phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; }; diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h index 3161875441c..98b67ccc8ec 100644 --- a/arch/mips/include/asm/cacheops.h +++ b/arch/mips/include/asm/cacheops.h @@ -19,6 +19,25 @@ static inline void mips_cache(int op, const volatile void *addr) #endif } +#define MIPS32_WHICH_ICACHE 0x0 +#define MIPS32_FETCH_AND_LOCK 0x7 + +#define ICACHE_LOAD_LOCK (MIPS32_WHICH_ICACHE | (MIPS32_FETCH_AND_LOCK << 2)) + +/* Prefetch and lock instructions into cache */ +static inline void icache_lock(void *func, size_t len) +{ + int i, lines = ((len - 1) / ARCH_DMA_MINALIGN) + 1; + + for (i = 0; i < lines; i++) { + asm volatile (" cache %0, %1(%2)" + : /* No Output */ + : "I" ICACHE_LOAD_LOCK, + "n" (i * ARCH_DMA_MINALIGN), + "r" (func) + : /* No Clobbers */); + } +} #endif /* !__ASSEMBLY__ */ /* diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 48fa1f1f7f4..f80311e64e8 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -1013,9 +1013,7 @@ do { \ #define __read_64bit_c0_split(source, sel) \ ({ \ unsigned long long __val; \ - unsigned long __flags; \ \ - local_irq_save(__flags); \ if (sel == 0) \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ @@ -1034,16 +1032,12 @@ do { \ "dsra\t%L0, %L0, 32\n\t" \ ".set\tmips0" \ : "=r" (__val)); \ - local_irq_restore(__flags); \ \ __val; \ }) #define __write_64bit_c0_split(source, sel, val) \ do { \ - unsigned long __flags; \ - \ - local_irq_save(__flags); \ if (sel == 0) \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ @@ -1064,7 +1058,6 @@ do { \ "dmtc0\t%L0, " #source ", " #sel "\n\t" \ ".set\tmips0" \ : : "r" (val)); \ - local_irq_restore(__flags); \ } while (0) #define __readx_32bit_c0_register(source) \ @@ -2005,6 +1998,17 @@ static inline unsigned int get_ebase_cpunum(void) return read_c0_ebase() & 0x3ff; } +static inline void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, + u32 low1) +{ + write_c0_entrylo0(low0); + write_c0_pagemask(pagemask); + write_c0_entrylo1(low1); + write_c0_entryhi(hi); + write_c0_index(index); + tlb_write_indexed(); +} + #endif /* !__ASSEMBLY__ */ #endif /* _ASM_MIPSREGS_H */ diff --git a/arch/mips/include/asm/spl.h b/arch/mips/include/asm/spl.h new file mode 100644 index 00000000000..0a847edec89 --- /dev/null +++ b/arch/mips/include/asm/spl.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + */ +#ifndef _ASM_SPL_H_ +#define _ASM_SPL_H_ + +enum { + BOOT_DEVICE_RAM, + BOOT_DEVICE_MMC1, + BOOT_DEVICE_MMC2, + BOOT_DEVICE_MMC2_2, + BOOT_DEVICE_NAND, + BOOT_DEVICE_ONENAND, + BOOT_DEVICE_NOR, + BOOT_DEVICE_UART, + BOOT_DEVICE_SPI, + BOOT_DEVICE_USB, + BOOT_DEVICE_SATA, + BOOT_DEVICE_I2C, + BOOT_DEVICE_BOARD, + BOOT_DEVICE_DFU, + BOOT_DEVICE_XIP, + BOOT_DEVICE_BOOTROM, + BOOT_DEVICE_NONE +}; + +#ifndef CONFIG_DM +extern gd_t gdata; +#endif + +#endif diff --git a/arch/mips/mach-jz47xx/Kconfig b/arch/mips/mach-jz47xx/Kconfig new file mode 100644 index 00000000000..dcaac016286 --- /dev/null +++ b/arch/mips/mach-jz47xx/Kconfig @@ -0,0 +1,26 @@ +menu "Ingenic JZ47xx platforms" + depends on ARCH_JZ47XX + +config SYS_SOC + default "jz47xx" + +config SOC_JZ4780 + bool + select SUPPORTS_LITTLE_ENDIAN + select SUPPORTS_CPU_MIPS32_R1 + select SUPPORTS_CPU_MIPS32_R2 + help + Support for Ingenic JZ4780 family SoCs. + +choice + prompt "Board select" + +config TARGET_JZ4780_CI20 + bool "Creator CI20 Reference Board" + select SOC_JZ4780 + +endchoice + +source "board/imgtec/ci20/Kconfig" + +endmenu diff --git a/arch/mips/mach-jz47xx/Makefile b/arch/mips/mach-jz47xx/Makefile new file mode 100644 index 00000000000..dbb8229f785 --- /dev/null +++ b/arch/mips/mach-jz47xx/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ + +extra-$(CONFIG_SPL_BUILD) := start.o + +obj-$(CONFIG_SOC_JZ4780) += jz4780/ diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780.h b/arch/mips/mach-jz47xx/include/mach/jz4780.h new file mode 100644 index 00000000000..4422e503ed2 --- /dev/null +++ b/arch/mips/mach-jz47xx/include/mach/jz4780.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * JZ4780 definitions + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + */ + +#ifndef __JZ4780_H__ +#define __JZ4780_H__ + +/* AHB0 BUS Devices */ +#define DDRC_BASE 0xb3010000 + +/* AHB2 BUS Devices */ +#define NEMC_BASE 0xb3410000 +#define BCH_BASE 0xb34d0000 + +/* APB BUS Devices */ +#define CPM_BASE 0xb0000000 +#define TCU_BASE 0xb0002000 +#define WDT_BASE 0xb0002000 +#define GPIO_BASE 0xb0010000 +#define UART0_BASE 0xb0030000 +#define UART1_BASE 0xb0031000 +#define UART2_BASE 0xb0032000 +#define UART3_BASE 0xb0033000 +#define MSC0_BASE 0xb3450000 +#define MSC1_BASE 0xb3460000 +#define MSC2_BASE 0xb3470000 + +/* + * GPIO + */ +/* n = 0,1,2,3,4,5 */ +#define GPIO_PXPIN(n) (0x00 + (n) * 0x100) +#define GPIO_PXINT(n) (0x10 + (n) * 0x100) +#define GPIO_PXINTS(n) (0x14 + (n) * 0x100) +#define GPIO_PXINTC(n) (0x18 + (n) * 0x100) +#define GPIO_PXMASK(n) (0x20 + (n) * 0x100) +#define GPIO_PXMASKS(n) (0x24 + (n) * 0x100) +#define GPIO_PXMASKC(n) (0x28 + (n) * 0x100) +#define GPIO_PXPAT1(n) (0x30 + (n) * 0x100) +#define GPIO_PXPAT1S(n) (0x34 + (n) * 0x100) +#define GPIO_PXPAT1C(n) (0x38 + (n) * 0x100) +#define GPIO_PXPAT0(n) (0x40 + (n) * 0x100) +#define GPIO_PXPAT0S(n) (0x44 + (n) * 0x100) +#define GPIO_PXPAT0C(n) (0x48 + (n) * 0x100) +#define GPIO_PXFLG(n) (0x50 + (n) * 0x100) +#define GPIO_PXFLGC(n) (0x54 + (n) * 0x100) +#define GPIO_PXOEN(n) (0x60 + (n) * 0x100) +#define GPIO_PXOENS(n) (0x64 + (n) * 0x100) +#define GPIO_PXOENC(n) (0x68 + (n) * 0x100) +#define GPIO_PXPEN(n) (0x70 + (n) * 0x100) +#define GPIO_PXPENS(n) (0x74 + (n) * 0x100) +#define GPIO_PXPENC(n) (0x78 + (n) * 0x100) +#define GPIO_PXDS(n) (0x80 + (n) * 0x100) +#define GPIO_PXDSS(n) (0x84 + (n) * 0x100) +#define GPIO_PXDSC(n) (0x88 + (n) * 0x100) + +/* PLL setup */ +#define JZ4780_SYS_EXTAL 48000000 +#define JZ4780_SYS_MEM_SPEED (CONFIG_SYS_MHZ * 1000000) +#define JZ4780_SYS_MEM_DIV 3 +#define JZ4780_SYS_AUDIO_SPEED (768 * 1000000) + +#define JZ4780_APLL_M 1 +#define JZ4780_APLL_N 1 +#define JZ4780_APLL_OD 1 + +#define JZ4780_MPLL_M (JZ4780_SYS_MEM_SPEED / JZ4780_SYS_EXTAL * 2) +#define JZ4780_MPLL_N 2 +#define JZ4780_MPLL_OD 1 + +#define JZ4780_EPLL_M (JZ4780_SYS_AUDIO_SPEED * 2 / JZ4780_SYS_EXTAL) +#define JZ4780_EPLL_N 1 +#define JZ4780_EPLL_OD 2 + +#define JZ4780_VPLL_M ((888 * 1000000) * 2 / JZ4780_SYS_EXTAL) +#define JZ4780_VPLL_N 1 +#define JZ4780_VPLL_OD 2 + +#ifndef __ASSEMBLY__ + +u32 sdram_size(int bank); + +const u32 jz4780_clk_get_efuse_clk(void); +void jz4780_clk_ungate_ethernet(void); +void jz4780_clk_ungate_mmc(void); +void jz4780_clk_ungate_uart(const unsigned int uart); + +void jz4780_efuse_read(size_t addr, size_t count, u8 *buf); +void jz4780_efuse_init(u32 ahb2_rate); + +void jz4780_tcu_wdt_start(void); + +#ifdef CONFIG_SPL_BUILD +int jz_mmc_init(void __iomem *base); +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __JZ4780_H__ */ diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h b/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h new file mode 100644 index 00000000000..92d431bd041 --- /dev/null +++ b/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h @@ -0,0 +1,456 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * JZ4780 DDR initialization - parameters definitions + * + * Copyright (c) 2015 Imagination Technologies + * Author: Matt Redfearn <matt.redfearn.com> + */ + +#ifndef __JZ4780_DRAM_H__ +#define __JZ4780_DRAM_H__ + +/* + * DDR + */ +#define DDRC_ST 0x0 +#define DDRC_CFG 0x4 +#define DDRC_CTRL 0x8 +#define DDRC_LMR 0xc +#define DDRC_REFCNT 0x18 +#define DDRC_DQS 0x1c +#define DDRC_DQS_ADJ 0x20 +#define DDRC_MMAP0 0x24 +#define DDRC_MMAP1 0x28 +#define DDRC_MDELAY 0x2c +#define DDRC_CKEL 0x30 +#define DDRC_PMEMCTRL0 0x54 +#define DDRC_PMEMCTRL1 0x50 +#define DDRC_PMEMCTRL2 0x58 +#define DDRC_PMEMCTRL3 0x5c + +#define DDRC_TIMING(n) (0x60 + 4 * (n)) +#define DDRC_REMMAP(n) (0x9c + 4 * (n)) + +/* + * DDR PHY + */ +#define DDR_MEM_PHY_BASE 0x20000000 +#define DDR_PHY_OFFSET 0x1000 + +#define DDRP_PIR 0x4 +#define DDRP_PGCR 0x8 +#define DDRP_PGSR 0xc + +#define DDRP_PTR0 0x18 +#define DDRP_PTR1 0x1c +#define DDRP_PTR2 0x20 + +#define DDRP_ACIOCR 0x24 +#define DDRP_DXCCR 0x28 +#define DDRP_DSGCR 0x2c +#define DDRP_DCR 0x30 + +#define DDRP_DTPR0 0x34 +#define DDRP_DTPR1 0x38 +#define DDRP_DTPR2 0x3c +#define DDRP_MR0 0x40 +#define DDRP_MR1 0x44 +#define DDRP_MR2 0x48 +#define DDRP_MR3 0x4c + +#define DDRP_ODTCR 0x50 +#define DDRP_DTAR 0x54 +#define DDRP_DTDR0 0x58 +#define DDRP_DTDR1 0x5c + +#define DDRP_DCUAR 0xc0 +#define DDRP_DCUDR 0xc4 +#define DDRP_DCURR 0xc8 +#define DDRP_DCULR 0xcc +#define DDRP_DCUGCR 0xd0 +#define DDRP_DCUTPR 0xd4 +#define DDRP_DCUSR0 0xd8 +#define DDRP_DCUSR1 0xdc + +#define DDRP_ZQXCR0(n) (0x180 + ((n) * 0x10)) +#define DDRP_ZQXCR1(n) (0x184 + ((n) * 0x10)) +#define DDRP_ZQXSR0(n) (0x188 + ((n) * 0x10)) +#define DDRP_ZQXSR1(n) (0x18c + ((n) * 0x10)) + +#define DDRP_DXGCR(n) (0x1c0 + ((n) * 0x40)) +#define DDRP_DXGSR0(n) (0x1c4 + ((n) * 0x40)) +#define DDRP_DXGSR1(n) (0x1c8 + ((n) * 0x40)) +#define DDRP_DXDQSTR(n) (0x1d4 + ((n) * 0x40)) + +/* DDRC Status Register */ +#define DDRC_ST_ENDIAN BIT(7) +#define DDRC_ST_DPDN BIT(5) +#define DDRC_ST_PDN BIT(4) +#define DDRC_ST_AREF BIT(3) +#define DDRC_ST_SREF BIT(2) +#define DDRC_ST_CKE1 BIT(1) +#define DDRC_ST_CKE0 BIT(0) + +/* DDRC Configure Register */ +#define DDRC_CFG_ROW1_BIT 27 +#define DDRC_CFG_ROW1_MASK (0x7 << DDRC_CFG_ROW1_BIT) +#define DDRC_CFG_COL1_BIT 24 +#define DDRC_CFG_COL1_MASK (0x7 << DDRC_CFG_COL1_BIT) +#define DDRC_CFG_BA1 BIT(23) +#define DDRC_CFG_IMBA BIT(22) +#define DDRC_CFG_BL_8 BIT(21) + +#define DDRC_CFG_TYPE_BIT 17 +#define DDRC_CFG_TYPE_MASK (0x7 << DDRC_CFG_TYPE_BIT) +#define DDRC_CFG_TYPE_DDR1 (2 << DDRC_CFG_TYPE_BIT) +#define DDRC_CFG_TYPE_MDDR (3 << DDRC_CFG_TYPE_BIT) +#define DDRC_CFG_TYPE_DDR2 (4 << DDRC_CFG_TYPE_BIT) +#define DDRC_CFG_TYPE_LPDDR2 (5 << DDRC_CFG_TYPE_BIT) +#define DDRC_CFG_TYPE_DDR3 (6 << DDRC_CFG_TYPE_BIT) + +#define DDRC_CFG_ODT_EN BIT(16) + +#define DDRC_CFG_MPRT BIT(15) + +#define DDRC_CFG_ROW_BIT 11 +#define DDRC_CFG_ROW_MASK (0x7 << DDRC_CFG_ROW_BIT) +#define DDRC_CFG_ROW_12 (0 << DDRC_CFG_ROW_BIT) +#define DDRC_CFG_ROW_13 (1 << DDRC_CFG_ROW_BIT) +#define DDRC_CFG_ROW_14 (2 << DDRC_CFG_ROW_BIT) + +#define DDRC_CFG_COL_BIT 8 +#define DDRC_CFG_COL_MASK (0x7 << DDRC_CFG_COL_BIT) +#define DDRC_CFG_COL_8 (0 << DDRC_CFG_COL_BIT) +#define DDRC_CFG_COL_9 (1 << DDRC_CFG_COL_BIT) +#define DDRC_CFG_COL_10 (2 << DDRC_CFG_COL_BIT) +#define DDRC_CFG_COL_11 (3 << DDRC_CFG_COL_BIT) + +#define DDRC_CFG_CS1EN BIT(7) +#define DDRC_CFG_CS0EN BIT(6) +#define DDRC_CFG_CL_BIT 2 +#define DDRC_CFG_CL_MASK (0xf << DDRC_CFG_CL_BIT) +#define DDRC_CFG_CL_3 (0 << DDRC_CFG_CL_BIT) +#define DDRC_CFG_CL_4 (1 << DDRC_CFG_CL_BIT) +#define DDRC_CFG_CL_5 (2 << DDRC_CFG_CL_BIT) +#define DDRC_CFG_CL_6 (3 << DDRC_CFG_CL_BIT) + +#define DDRC_CFG_BA BIT(1) +#define DDRC_CFG_DW BIT(0) + +/* DDRC Control Register */ +#define DDRC_CTRL_DFI_RST BIT(23) +#define DDRC_CTRL_DLL_RST BIT(22) +#define DDRC_CTRL_CTL_RST BIT(21) +#define DDRC_CTRL_CFG_RST BIT(20) +#define DDRC_CTRL_ACTPD BIT(15) +#define DDRC_CTRL_PDT_BIT 12 +#define DDRC_CTRL_PDT_MASK (0x7 << DDRC_CTRL_PDT_BIT) +#define DDRC_CTRL_PDT_DIS (0 << DDRC_CTRL_PDT_BIT) +#define DDRC_CTRL_PDT_8 (1 << DDRC_CTRL_PDT_BIT) +#define DDRC_CTRL_PDT_16 (2 << DDRC_CTRL_PDT_BIT) +#define DDRC_CTRL_PDT_32 (3 << DDRC_CTRL_PDT_BIT) +#define DDRC_CTRL_PDT_64 (4 << DDRC_CTRL_PDT_BIT) +#define DDRC_CTRL_PDT_128 (5 << DDRC_CTRL_PDT_BIT) + +#define DDRC_CTRL_PRET_BIT 8 +#define DDRC_CTRL_PRET_MASK (0x7 << DDRC_CTRL_PRET_BIT) +#define DDRC_CTRL_PRET_DIS (0 << DDRC_CTRL_PRET_BIT) +#define DDRC_CTRL_PRET_8 (1 << DDRC_CTRL_PRET_BIT) +#define DDRC_CTRL_PRET_16 (2 << DDRC_CTRL_PRET_BIT) +#define DDRC_CTRL_PRET_32 (3 << DDRC_CTRL_PRET_BIT) +#define DDRC_CTRL_PRET_64 (4 << DDRC_CTRL_PRET_BIT) +#define DDRC_CTRL_PRET_128 (5 << DDRC_CTRL_PRET_BIT) + +#define DDRC_CTRL_DPD BIT(6) +#define DDRC_CTRL_SR BIT(5) +#define DDRC_CTRL_UNALIGN BIT(4) +#define DDRC_CTRL_ALH BIT(3) +#define DDRC_CTRL_RDC BIT(2) +#define DDRC_CTRL_CKE BIT(1) +#define DDRC_CTRL_RESET BIT(0) + +/* DDRC Load-Mode-Register */ +#define DDRC_LMR_DDR_ADDR_BIT 16 +#define DDRC_LMR_DDR_ADDR_MASK (0x3fff << DDRC_LMR_DDR_ADDR_BIT) + +#define DDRC_LMR_BA_BIT 8 +#define DDRC_LMR_BA_MASK (0x7 << DDRC_LMR_BA_BIT) +/* For DDR2 */ +#define DDRC_LMR_BA_MRS (0 << DDRC_LMR_BA_BIT) +#define DDRC_LMR_BA_EMRS1 (1 << DDRC_LMR_BA_BIT) +#define DDRC_LMR_BA_EMRS2 (2 << DDRC_LMR_BA_BIT) +#define DDRC_LMR_BA_EMRS3 (3 << DDRC_LMR_BA_BIT) +/* For mobile DDR */ +#define DDRC_LMR_BA_M_MRS (0 << DDRC_LMR_BA_BIT) +#define DDRC_LMR_BA_M_EMRS (2 << DDRC_LMR_BA_BIT) +#define DDRC_LMR_BA_M_SR (1 << DDRC_LMR_BA_BIT) +/* For Normal DDR1 */ +#define DDRC_LMR_BA_N_MRS (0 << DDRC_LMR_BA_BIT) +#define DDRC_LMR_BA_N_EMRS (1 << DDRC_LMR_BA_BIT) + +#define DDRC_LMR_CMD_BIT 4 +#define DDRC_LMR_CMD_MASK (0x3 << DDRC_LMR_CMD_BIT) +#define DDRC_LMR_CMD_PREC (0 << DDRC_LMR_CMD_BIT) +#define DDRC_LMR_CMD_AUREF (1 << DDRC_LMR_CMD_BIT) +#define DDRC_LMR_CMD_LMR (2 << DDRC_LMR_CMD_BIT) + +#define DDRC_LMR_START BIT(0) + +/* DDRC Timing Config Register 1 */ +#define DDRC_TIMING1_TRTP_BIT 24 +#define DDRC_TIMING1_TRTP_MASK (0x3f << DDRC_TIMING1_TRTP_BIT) +#define DDRC_TIMING1_TWTR_BIT 16 +#define DDRC_TIMING1_TWTR_MASK (0x3f << DDRC_TIMING1_TWTR_BIT) +#define DDRC_TIMING1_TWTR_1 (0 << DDRC_TIMING1_TWTR_BIT) +#define DDRC_TIMING1_TWTR_2 (1 << DDRC_TIMING1_TWTR_BIT) +#define DDRC_TIMING1_TWTR_3 (2 << DDRC_TIMING1_TWTR_BIT) +#define DDRC_TIMING1_TWTR_4 (3 << DDRC_TIMING1_TWTR_BIT) +#define DDRC_TIMING1_TWR_BIT 8 +#define DDRC_TIMING1_TWR_MASK (0x3f << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWR_1 (0 << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWR_2 (1 << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWR_3 (2 << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWR_4 (3 << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWR_5 (4 << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWR_6 (5 << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWL_BIT 0 +#define DDRC_TIMING1_TWL_MASK (0x3f << DDRC_TIMING1_TWL_BIT) + +/* DDRC Timing Config Register 2 */ +#define DDRC_TIMING2_TCCD_BIT 24 +#define DDRC_TIMING2_TCCD_MASK (0x3f << DDRC_TIMING2_TCCD_BIT) +#define DDRC_TIMING2_TRAS_BIT 16 +#define DDRC_TIMING2_TRAS_MASK (0x3f << DDRC_TIMING2_TRAS_BIT) +#define DDRC_TIMING2_TRCD_BIT 8 +#define DDRC_TIMING2_TRCD_MASK (0x3f << DDRC_TIMING2_TRCD_BIT) +#define DDRC_TIMING2_TRL_BIT 0 +#define DDRC_TIMING2_TRL_MASK (0x3f << DDRC_TIMING2_TRL_BIT) + +/* DDRC Timing Config Register 3 */ +#define DDRC_TIMING3_ONUM 27 +#define DDRC_TIMING3_TCKSRE_BIT 24 +#define DDRC_TIMING3_TCKSRE_MASK (0x3f << DDRC_TIMING3_TCKSRE_BIT) +#define DDRC_TIMING3_TRP_BIT 16 +#define DDRC_TIMING3_TRP_MASK (0x3f << DDRC_TIMING3_TRP_BIT) +#define DDRC_TIMING3_TRRD_BIT 8 +#define DDRC_TIMING3_TRRD_MASK (0x3f << DDRC_TIMING3_TRRD_BIT) +#define DDRC_TIMING3_TRRD_DISABLE (0 << DDRC_TIMING3_TRRD_BIT) +#define DDRC_TIMING3_TRRD_2 (1 << DDRC_TIMING3_TRRD_BIT) +#define DDRC_TIMING3_TRRD_3 (2 << DDRC_TIMING3_TRRD_BIT) +#define DDRC_TIMING3_TRRD_4 (3 << DDRC_TIMING3_TRRD_BIT) +#define DDRC_TIMING3_TRC_BIT 0 +#define DDRC_TIMING3_TRC_MASK (0x3f << DDRC_TIMING3_TRC_BIT) + +/* DDRC Timing Config Register 4 */ +#define DDRC_TIMING4_TRFC_BIT 24 +#define DDRC_TIMING4_TRFC_MASK (0x3f << DDRC_TIMING4_TRFC_BIT) +#define DDRC_TIMING4_TEXTRW_BIT 21 +#define DDRC_TIMING4_TEXTRW_MASK (0x7 << DDRC_TIMING4_TEXTRW_BIT) +#define DDRC_TIMING4_TRWCOV_BIT 19 +#define DDRC_TIMING4_TRWCOV_MASK (0x3 << DDRC_TIMING4_TRWCOV_BIT) +#define DDRC_TIMING4_TCKE_BIT 16 +#define DDRC_TIMING4_TCKE_MASK (0x7 << DDRC_TIMING4_TCKE_BIT) +#define DDRC_TIMING4_TMINSR_BIT 8 +#define DDRC_TIMING4_TMINSR_MASK (0xf << DDRC_TIMING4_TMINSR_BIT) +#define DDRC_TIMING4_TXP_BIT 4 +#define DDRC_TIMING4_TXP_MASK (0x7 << DDRC_TIMING4_TXP_BIT) +#define DDRC_TIMING4_TMRD_BIT 0 +#define DDRC_TIMING4_TMRD_MASK (0x3 << DDRC_TIMING4_TMRD_BIT) + +/* DDRC Timing Config Register 5 */ +#define DDRC_TIMING5_TCTLUPD_BIT 24 +#define DDRC_TIMING4_TCTLUPD_MASK (0x3f << DDRC_TIMING5_TCTLUDP_BIT) +#define DDRC_TIMING5_TRTW_BIT 16 +#define DDRC_TIMING5_TRTW_MASK (0x3f << DDRC_TIMING5_TRTW_BIT) +#define DDRC_TIMING5_TRDLAT_BIT 8 +#define DDRC_TIMING5_TRDLAT_MASK (0x3f << DDRC_TIMING5_TRDLAT_BIT) +#define DDRC_TIMING5_TWDLAT_BIT 0 +#define DDRC_TIMING5_TWDLAT_MASK (0x3f << DDRC_TIMING5_TWDLAT_BIT) + +/* DDRC Timing Config Register 6 */ +#define DDRC_TIMING6_TXSRD_BIT 24 +#define DDRC_TIMING6_TXSRD_MASK (0x3f << DDRC_TIMING6_TXSRD_BIT) +#define DDRC_TIMING6_TFAW_BIT 16 +#define DDRC_TIMING6_TFAW_MASK (0x3f << DDRC_TIMING6_TFAW_BIT) +#define DDRC_TIMING6_TCFGW_BIT 8 +#define DDRC_TIMING6_TCFGW_MASK (0x3f << DDRC_TIMING6_TCFGW_BIT) +#define DDRC_TIMING6_TCFGR_BIT 0 +#define DDRC_TIMING6_TCFGR_MASK (0x3f << DDRC_TIMING6_TCFGR_BIT) + +/* DDRC Auto-Refresh Counter */ +#define DDRC_REFCNT_CON_BIT 16 +#define DDRC_REFCNT_CON_MASK (0xff << DDRC_REFCNT_CON_BIT) +#define DDRC_REFCNT_CNT_BIT 8 +#define DDRC_REFCNT_CNT_MASK (0xff << DDRC_REFCNT_CNT_BIT) +#define DDRC_REFCNT_CLKDIV_BIT 1 +#define DDRC_REFCNT_CLKDIV_MASK (0x7 << DDRC_REFCNT_CLKDIV_BIT) +#define DDRC_REFCNT_REF_EN BIT(0) + +/* DDRC DQS Delay Control Register */ +#define DDRC_DQS_ERROR BIT(29) +#define DDRC_DQS_READY BIT(28) +#define DDRC_DQS_AUTO BIT(23) +#define DDRC_DQS_DET BIT(24) +#define DDRC_DQS_SRDET BIT(25) +#define DDRC_DQS_CLKD_BIT 16 +#define DDRC_DQS_CLKD_MASK (0x3f << DDRC_DQS_CLKD_BIT) +#define DDRC_DQS_WDQS_BIT 8 +#define DDRC_DQS_WDQS_MASK (0x3f << DDRC_DQS_WDQS_BIT) +#define DDRC_DQS_RDQS_BIT 0 +#define DDRC_DQS_RDQS_MASK (0x3f << DDRC_DQS_RDQS_BIT) + +/* DDRC DQS Delay Adjust Register */ +#define DDRC_DQS_ADJWDQS_BIT 8 +#define DDRC_DQS_ADJWDQS_MASK (0x1f << DDRC_DQS_ADJWDQS_BIT) +#define DDRC_DQS_ADJRDQS_BIT 0 +#define DDRC_DQS_ADJRDQS_MASK (0x1f << DDRC_DQS_ADJRDQS_BIT) + +/* DDRC Memory Map Config Register */ +#define DDRC_MMAP_BASE_BIT 8 +#define DDRC_MMAP_BASE_MASK (0xff << DDRC_MMAP_BASE_BIT) +#define DDRC_MMAP_MASK_BIT 0 +#define DDRC_MMAP_MASK_MASK (0xff << DDRC_MMAP_MASK_BIT) + +#define DDRC_MMAP0_BASE (0x20 << DDRC_MMAP_BASE_BIT) +#define DDRC_MMAP1_BASE_64M (0x24 << DDRC_MMAP_BASE_BIT) +#define DDRC_MMAP1_BASE_128M (0x28 << DDRC_MMAP_BASE_BIT) +#define DDRC_MMAP1_BASE_256M (0x30 << DDRC_MMAP_BASE_BIT) + +#define DDRC_MMAP_MASK_64_64 (0xfc << DDRC_MMAP_MASK_BIT) +#define DDRC_MMAP_MASK_128_128 (0xf8 << DDRC_MMAP_MASK_BIT) +#define DDRC_MMAP_MASK_256_256 (0xf0 << DDRC_MMAP_MASK_BIT) + +/* DDRP PHY Initialization Register */ +#define DDRP_PIR_INIT BIT(0) +#define DDRP_PIR_DLLSRST BIT(1) +#define DDRP_PIR_DLLLOCK BIT(2) +#define DDRP_PIR_ZCAL BIT(3) +#define DDRP_PIR_ITMSRST BIT(4) +#define DDRP_PIR_DRAMRST BIT(5) +#define DDRP_PIR_DRAMINT BIT(6) +#define DDRP_PIR_QSTRN BIT(7) +#define DDRP_PIR_EYETRN BIT(8) +#define DDRP_PIR_DLLBYP BIT(17) +/* DDRP PHY General Configurate Register */ +#define DDRP_PGCR_ITMDMD BIT(0) +#define DDRP_PGCR_DQSCFG BIT(1) +#define DDRP_PGCR_DFTCMP BIT(2) +#define DDRP_PGCR_DFTLMT_BIT 3 +#define DDRP_PGCR_DTOSEL_BIT 5 +#define DDRP_PGCR_CKEN_BIT 9 +#define DDRP_PGCR_CKDV_BIT 12 +#define DDRP_PGCR_CKINV BIT(14) +#define DDRP_PGCR_RANKEN_BIT 18 +#define DDRP_PGCR_ZCKSEL_32 (2 << 22) +#define DDRP_PGCR_PDDISDX BIT(24) +/* DDRP PHY General Status Register */ +#define DDRP_PGSR_IDONE BIT(0) +#define DDRP_PGSR_DLDONE BIT(1) +#define DDRP_PGSR_ZCDONE BIT(2) +#define DDRP_PGSR_DIDONE BIT(3) +#define DDRP_PGSR_DTDONE BIT(4) +#define DDRP_PGSR_DTERR BIT(5) +#define DDRP_PGSR_DTIERR BIT(6) +#define DDRP_PGSR_DFTEERR BIT(7) +/* DDRP DRAM Configuration Register */ +#define DDRP_DCR_TYPE_BIT 0 +#define DDRP_DCR_TYPE_MASK (0x7 << DDRP_DCR_TYPE_BIT) +#define DDRP_DCR_TYPE_MDDR (0 << DDRP_DCR_TYPE_BIT) +#define DDRP_DCR_TYPE_DDR (1 << DDRP_DCR_TYPE_BIT) +#define DDRP_DCR_TYPE_DDR2 (2 << DDRP_DCR_TYPE_BIT) +#define DDRP_DCR_TYPE_DDR3 (3 << DDRP_DCR_TYPE_BIT) +#define DDRP_DCR_TYPE_LPDDR2 (4 << DDRP_DCR_TYPE_BIT) +#define DDRP_DCR_DDR8BNK_BIT 3 +#define DDRP_DCR_DDR8BNK_MASK (1 << DDRP_DCR_DDR8BNK_BIT) +#define DDRP_DCR_DDR8BNK (1 << DDRP_DCR_DDR8BNK_BIT) +#define DDRP_DCR_DDR8BNK_DIS (0 << DDRP_DCR_DDR8BNK_BIT) + +#define DRP_DTRP1_RTODT BIT(11) + +#define DDRP_DXGCR_DXEN BIT(0) + +#define DDRP_ZQXCR_ZDEN_BIT 28 +#define DDRP_ZQXCR_ZDEN (1 << DDRP_ZQXCR_ZDEN_BIT) +#define DDRP_ZQXCR_PULLUP_IMPE_BIT 5 +#define DDRP_ZQXCR_PULLDOWN_IMPE_BIT 0 + +/* DDR3 Mode Register Set */ +#define DDR3_MR0_BL_BIT 0 +#define DDR3_MR0_BL_MASK (3 << DDR3_MR0_BL_BIT) +#define DDR3_MR0_BL_8 (0 << DDR3_MR0_BL_BIT) +#define DDR3_MR0_BL_fly (1 << DDR3_MR0_BL_BIT) +#define DDR3_MR0_BL_4 (2 << DDR3_MR0_BL_BIT) +#define DDR3_MR0_BT_BIT 3 +#define DDR3_MR0_BT_MASK (1 << DDR3_MR0_BT_BIT) +#define DDR3_MR0_BT_SEQ (0 << DDR3_MR0_BT_BIT) +#define DDR3_MR0_BT_INTER (1 << DDR3_MR0_BT_BIT) +#define DDR3_MR0_WR_BIT 9 + +#define DDR3_MR1_DLL_DISABLE 1 +#define DDR3_MR1_DIC_6 (0 << 5 | 0 << 1) +#define DDR3_MR1_DIC_7 (0 << 5 | BIT(1)) +#define DDR3_MR1_RTT_DIS (0 << 9 | 0 << 6 | 0 << 2) +#define DDR3_MR1_RTT_4 (0 << 9 | 0 << 6 | BIT(2)) +#define DDR3_MR1_RTT_2 (0 << 9 | BIT(6) | 0 << 2) +#define DDR3_MR1_RTT_6 (0 << 9 | BIT(6) | BIT(2)) +#define DDR3_MR1_RTT_12 (BIT(9) | 0 << 6 | 0 << 2) +#define DDR3_MR1_RTT_8 (BIT(9) | 0 << 6 | BIT(2)) + +#define DDR3_MR2_CWL_BIT 3 + +/* Parameters common to all RAM devices used */ + +/* Chip Select */ +/* CSEN : whether a ddr chip exists 0 - un-used, 1 - used */ +#define DDR_CS0EN 1 +/* CSEN : whether a ddr chip exists 0 - un-used, 1 - used */ +#define DDR_CS1EN 0 + +/* ROW : 12 to 18 row address, 1G only 512MB */ +#define DDR_ROW 15 +/* COL : 8 to 14 column address */ +#define DDR_COL 10 +/* Banks each chip: 0-4bank, 1-8bank */ +#define DDR_BANK8 1 +/* 0 - 16-bit data width, 1 - 32-bit data width */ +#define DDR_DW32 1 + +/* Refresh period: 64ms / 32768 = 1.95 us , 2 ^ 15 = 32768 */ +#define DDR_tREFI 7800 +/* Clock Divider */ +#define DDR_CLK_DIV 1 + +/* DDR3 Burst length: 0 - 8 burst, 2 - 4 burst , 1 - 4 or 8 (on the fly) */ +#define DDR_BL 8 + +/* CAS latency: 5 to 14, tCK */ +#define DDR_CL 6 +/* DDR3 only: CAS Write Latency, 5 to 8 */ +#define DDR_tCWL (DDR_CL - 1) + +/* Structure representing per-RAM type configuration */ + +struct jz4780_ddr_config { + u32 timing[6]; /* Timing1..6 register value */ + + /* DDR PHY control */ + u16 mr0; /* Mode Register 0 */ + u16 mr1; /* Mode Register 1 */ + + u32 ptr0; /* PHY Timing Register 0 */ + u32 ptr1; /* PHY Timing Register 1 */ + u32 ptr2; /* PHY Timing Register 1 */ + + u32 dtpr0; /* DRAM Timing Parameters Register 0 */ + u32 dtpr1; /* DRAM Timing Parameters Register 1 */ + u32 dtpr2; /* DRAM Timing Parameters Register 2 */ + + u8 pullup; /* PHY pullup impedance */ + u8 pulldn; /* PHY pulldown impedance */ +}; + +void pll_init(void); +void sdram_init(void); + +#endif /* __JZ4780_DRAM_H__ */ + diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h b/arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h new file mode 100644 index 00000000000..37f0892f7ba --- /dev/null +++ b/arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __JZ4780_GPIO_H__ +#define __JZ4780_GPIO_H__ + +#define JZ_GPIO(bank, pin) ((32 * (bank)) + (pin)) + +int jz47xx_gpio_get_value(unsigned int gpio); +void jz47xx_gpio_direction_input(unsigned int gpio); +void jz47xx_gpio_direction_output(unsigned int gpio, int value); + +#endif diff --git a/arch/mips/mach-jz47xx/jz4780/Makefile b/arch/mips/mach-jz47xx/jz4780/Makefile new file mode 100644 index 00000000000..5b3c3543272 --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-y := gpio.o jz4780.o pll.o reset.o sdram.o timer.o diff --git a/arch/mips/mach-jz47xx/jz4780/TODO b/arch/mips/mach-jz47xx/jz4780/TODO new file mode 100644 index 00000000000..99ad6225b0c --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/TODO @@ -0,0 +1,4 @@ +- dm gpio driver +- ethernet driver for the dm9000 +- reduce the hundreds of definitions of register addresses to the ones really needed in assembly or SPL. +- define the remaining register base addresses as physical addresses and establish a mapping with ioremap_nocache() diff --git a/arch/mips/mach-jz47xx/jz4780/gpio.c b/arch/mips/mach-jz47xx/jz4780/gpio.c new file mode 100644 index 00000000000..cee2328ab1e --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/gpio.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <config.h> +#include <common.h> +#include <asm/io.h> +#include <mach/jz4780.h> + +int jz47xx_gpio_get_value(unsigned int gpio) +{ + void __iomem *gpio_regs = (void __iomem *)GPIO_BASE; + int port = gpio / 32; + int pin = gpio % 32; + + return readl(gpio_regs + GPIO_PXPIN(port)) & BIT(pin); +} + +void jz47xx_gpio_direction_input(unsigned int gpio) +{ + void __iomem *gpio_regs = (void __iomem *)GPIO_BASE; + int port = gpio / 32; + int pin = gpio % 32; + + writel(BIT(pin), gpio_regs + GPIO_PXINTC(port)); + writel(BIT(pin), gpio_regs + GPIO_PXMASKS(port)); + writel(BIT(pin), gpio_regs + GPIO_PXPAT1S(port)); +} + +void jz47xx_gpio_direction_output(unsigned int gpio, int value) +{ + void __iomem *gpio_regs = (void __iomem *)GPIO_BASE; + int port = gpio / 32; + int pin = gpio % 32; + + writel(BIT(pin), gpio_regs + GPIO_PXINTC(port)); + writel(BIT(pin), gpio_regs + GPIO_PXMASKS(port)); + writel(BIT(pin), gpio_regs + GPIO_PXPAT1C(port)); + writel(BIT(pin), gpio_regs + + (value ? GPIO_PXPAT0S(port) : GPIO_PXPAT0C(port))); +} diff --git a/arch/mips/mach-jz47xx/jz4780/jz4780.c b/arch/mips/mach-jz47xx/jz4780/jz4780.c new file mode 100644 index 00000000000..dbd328cb49f --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/jz4780.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * JZ4780 common routines + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + */ + +#include <config.h> +#include <common.h> +#include <asm/io.h> +#include <asm/sections.h> +#include <mach/jz4780.h> +#include <mach/jz4780_dram.h> +#include <mmc.h> +#include <spl.h> + +#ifdef CONFIG_SPL_BUILD +/* Pointer to the global data structure for SPL */ +DECLARE_GLOBAL_DATA_PTR; +gd_t gdata __attribute__ ((section(".bss"))); + +void board_init_f(ulong dummy) +{ + typedef void __noreturn (*image_entry_noargs_t)(void); + struct mmc *mmc; + unsigned long count; + struct image_header *header; + int ret; + + /* Set global data pointer */ + gd = &gdata; + + timer_init(); + pll_init(); + sdram_init(); + enable_caches(); + + /* Clear the BSS */ + memset(__bss_start, 0, (char *)&__bss_end - __bss_start); + + gd->flags |= GD_FLG_SPL_INIT; + + ret = mmc_initialize(NULL); + if (ret) + hang(); + + mmc = find_mmc_device(BOOT_DEVICE_MMC1); + if (ret) + hang(); + + ret = mmc_init(mmc); + if (ret) + hang(); + + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct image_header)); + + count = blk_dread(mmc_get_blk_desc(mmc), + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, + 0x800, header); + if (count == 0) + hang(); + + image_entry_noargs_t image_entry = + (image_entry_noargs_t)CONFIG_SYS_TEXT_BASE; + + image_entry(); + + hang(); +} +#endif /* CONFIG_SPL_BUILD */ + +ulong board_get_usable_ram_top(ulong total_size) +{ + return CONFIG_SYS_SDRAM_BASE + (256 * 1024 * 1024); +} + +int print_cpuinfo(void) +{ + printf("CPU: Ingenic JZ4780\n"); + return 0; +} diff --git a/arch/mips/mach-jz47xx/jz4780/pll.c b/arch/mips/mach-jz47xx/jz4780/pll.c new file mode 100644 index 00000000000..9a46198f364 --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/pll.c @@ -0,0 +1,530 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * JZ4780 PLL setup + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + */ + +#include <config.h> +#include <common.h> +#include <asm/io.h> +#include <mach/jz4780.h> + +#define CPM_CPCCR 0x00 +#define CPM_LCR 0x04 +#define CPM_RSR 0x08 +#define CPM_CPPCR 0x0c +#define CPM_CPAPCR 0x10 +#define CPM_CPMPCR 0x14 +#define CPM_CPEPCR 0x18 +#define CPM_CPVPCR 0x1c +#define CPM_CLKGR0 0x20 +#define CPM_OPCR 0x24 +#define CPM_CLKGR1 0x28 +#define CPM_DDCDR 0x2c +#define CPM_VPUCDR 0x30 +#define CPM_CPSPR 0x34 +#define CPM_CPSPPR 0x38 +#define CPM_USBPCR 0x3c +#define CPM_USBRDT 0x40 +#define CPM_USBVBFIL 0x44 +#define CPM_USBPCR1 0x48 +#define CPM_USBCDR 0x50 +#define CPM_LPCDR 0x54 +#define CPM_I2SCDR 0x60 +#define CPM_LPCDR1 0x64 +#define CPM_MSCCDR 0x68 +#define CPM_UHCCDR 0x6c +#define CPM_SSICDR 0x74 +#define CPM_CIMCDR 0x7c +#define CPM_PCMCDR 0x84 +#define CPM_GPUCDR 0x88 +#define CPM_HDMICDR 0x8c +#define CPM_I2S1CDR 0xa0 +#define CPM_MSCCDR1 0xa4 +#define CPM_MSCCDR2 0xa8 +#define CPM_BCHCDR 0xac +#define CPM_SPCR0 0xb8 +#define CPM_SPCR1 0xbc +#define CPM_CPCSR 0xd4 +#define CPM_PSWCST(n) ((0x4 * (n)) + 0x90) + +/* Clock control register */ +#define CPM_CPCCR_SEL_SRC_BIT 30 +#define CPM_CPCCR_SEL_SRC_MASK (0x3 << CPM_CPCCR_SEL_SRC_BIT) +#define CPM_SRC_SEL_STOP 0 +#define CPM_SRC_SEL_APLL 1 +#define CPM_SRC_SEL_EXCLK 2 +#define CPM_SRC_SEL_RTCLK 3 +#define CPM_CPCCR_SEL_CPLL_BIT 28 +#define CPM_CPCCR_SEL_CPLL_MASK (0x3 << CPM_CPCCR_SEL_CPLL_BIT) +#define CPM_CPCCR_SEL_H0PLL_BIT 26 +#define CPM_CPCCR_SEL_H0PLL_MASK (0x3 << CPM_CPCCR_SEL_H0PLL_BIT) +#define CPM_CPCCR_SEL_H2PLL_BIT 24 +#define CPM_CPCCR_SEL_H2PLL_MASK (0x3 << CPM_CPCCR_SEL_H2PLL_BIT) +#define CPM_PLL_SEL_STOP 0 +#define CPM_PLL_SEL_SRC 1 +#define CPM_PLL_SEL_MPLL 2 +#define CPM_PLL_SEL_EPLL 3 +#define CPM_CPCCR_CE_CPU (0x1 << 22) +#define CPM_CPCCR_CE_AHB0 (0x1 << 21) +#define CPM_CPCCR_CE_AHB2 (0x1 << 20) +#define CPM_CPCCR_PDIV_BIT 16 +#define CPM_CPCCR_PDIV_MASK (0xf << CPM_CPCCR_PDIV_BIT) +#define CPM_CPCCR_H2DIV_BIT 12 +#define CPM_CPCCR_H2DIV_MASK (0xf << CPM_CPCCR_H2DIV_BIT) +#define CPM_CPCCR_H0DIV_BIT 8 +#define CPM_CPCCR_H0DIV_MASK (0x0f << CPM_CPCCR_H0DIV_BIT) +#define CPM_CPCCR_L2DIV_BIT 4 +#define CPM_CPCCR_L2DIV_MASK (0x0f << CPM_CPCCR_L2DIV_BIT) +#define CPM_CPCCR_CDIV_BIT 0 +#define CPM_CPCCR_CDIV_MASK (0x0f << CPM_CPCCR_CDIV_BIT) + +/* Clock Status register */ +#define CPM_CPCSR_H2DIV_BUSY BIT(2) +#define CPM_CPCSR_H0DIV_BUSY BIT(1) +#define CPM_CPCSR_CDIV_BUSY BIT(0) + +/* PLL control register */ +#define CPM_CPPCR_PLLST_BIT 0 +#define CPM_CPPCR_PLLST_MASK (0xff << CPM_CPPCR_PLLST_BIT) + +/* XPLL control register */ +#define CPM_CPXPCR_XPLLM_BIT 19 +#define CPM_CPXPCR_XPLLM_MASK (0x1fff << CPM_CPXPCR_XPLLM_BIT) +#define CPM_CPXPCR_XPLLN_BIT 13 +#define CPM_CPXPCR_XPLLN_MASK (0x3f << CPM_CPXPCR_XPLLN_BIT) +#define CPM_CPXPCR_XPLLOD_BIT 9 +#define CPM_CPXPCR_XPLLOD_MASK (0xf << CPM_CPXPCR_XPLLOD_BIT) +#define CPM_CPXPCR_XLOCK BIT(6) +#define CPM_CPXPCR_XPLL_ON BIT(4) +#define CPM_CPXPCR_XF_MODE BIT(3) +#define CPM_CPXPCR_XPLLBP BIT(1) +#define CPM_CPXPCR_XPLLEN BIT(0) + +/* CPM scratch protected register */ +#define CPM_CPSPPR_BIT 0 +#define CPM_CPSPPR_MASK (0xffff << CPM_CPSPPR_BIT) + +/* USB parameter control register */ +#define CPM_USBPCR_USB_MODE BIT(31) /* 1: OTG, 0: UDC*/ +#define CPM_USBPCR_AVLD_REG BIT(30) +#define CPM_USBPCR_IDPULLUP_MASK_BIT 28 +#define CPM_USBPCR_IDPULLUP_MASK_MASK (0x02 << IDPULLUP_MASK_BIT) +#define CPM_USBPCR_INCR_MASK BIT(27) +#define CPM_USBPCR_CLK12_EN BIT(26) +#define CPM_USBPCR_COMMONONN BIT(25) +#define CPM_USBPCR_VBUSVLDEXT BIT(24) +#define CPM_USBPCR_VBUSVLDEXTSEL BIT(23) +#define CPM_USBPCR_POR BIT(22) +#define CPM_USBPCR_SIDDQ BIT(21) +#define CPM_USBPCR_OTG_DISABLE BIT(20) +#define CPM_USBPCR_COMPDISTUNE_BIT 17 +#define CPM_USBPCR_COMPDISTUNE_MASK (0x07 << COMPDISTUNE_BIT) +#define CPM_USBPCR_OTGTUNE_BIT 14 +#define CPM_USBPCR_OTGTUNE_MASK (0x07 << OTGTUNE_BIT) +#define CPM_USBPCR_SQRXTUNE_BIT 11 +#define CPM_USBPCR_SQRXTUNE_MASK (0x7x << SQRXTUNE_BIT) +#define CPM_USBPCR_TXFSLSTUNE_BIT 7 +#define CPM_USBPCR_TXFSLSTUNE_MASK (0x0f << TXFSLSTUNE_BIT) +#define CPM_USBPCR_TXPREEMPHTUNE BIT(6) +#define CPM_USBPCR_TXRISETUNE_BIT 4 +#define CPM_USBPCR_TXRISETUNE_MASK (0x03 << TXRISETUNE_BIT) +#define CPM_USBPCR_TXVREFTUNE_BIT 0 +#define CPM_USBPCR_TXVREFTUNE_MASK (0x0f << TXVREFTUNE_BIT) + +/* DDR memory clock divider register */ +#define CPM_DDRCDR_DCS_BIT 30 +#define CPM_DDRCDR_DCS_MASK (0x3 << CPM_DDRCDR_DCS_BIT) +#define CPM_DDRCDR_DCS_STOP (0x0 << CPM_DDRCDR_DCS_BIT) +#define CPM_DDRCDR_DCS_SRC (0x1 << CPM_DDRCDR_DCS_BIT) +#define CPM_DDRCDR_DCS_MPLL (0x2 << CPM_DDRCDR_DCS_BIT) +#define CPM_DDRCDR_CE_DDR BIT(29) +#define CPM_DDRCDR_DDR_BUSY BIT(28) +#define CPM_DDRCDR_DDR_STOP BIT(27) +#define CPM_DDRCDR_DDRDIV_BIT 0 +#define CPM_DDRCDR_DDRDIV_MASK (0xf << CPM_DDRCDR_DDRDIV_BIT) + +/* USB reset detect timer register */ +#define CPM_USBRDT_VBFIL_LD_EN BIT(25) +#define CPM_USBRDT_IDDIG_EN BIT(24) +#define CPM_USBRDT_IDDIG_REG BIT(23) +#define CPM_USBRDT_USBRDT_BIT 0 +#define CPM_USBRDT_USBRDT_MASK (0x7fffff << CPM_USBRDT_USBRDT_BIT) + +/* USB OTG PHY clock divider register */ +#define CPM_USBCDR_UCS BIT(31) +#define CPM_USBCDR_UPCS BIT(30) +#define CPM_USBCDR_CEUSB BIT(29) +#define CPM_USBCDR_USB_BUSY BIT(28) +#define CPM_USBCDR_OTGDIV_BIT 0 +#define CPM_USBCDR_OTGDIV_MASK (0xff << CPM_USBCDR_OTGDIV_BIT) + +/* I2S device clock divider register */ +#define CPM_I2SCDR_I2CS BIT(31) +#define CPM_I2SCDR_I2PCS BIT(30) +#define CPM_I2SCDR_I2SDIV_BIT 0 +#define CPM_I2SCDR_I2SDIV_MASK (0x1ff << CPM_I2SCDR_I2SDIV_BIT) + +/* LCD0 pix clock divider register */ +#define CPM_LPCDR_LPCS_BIT 30 +#define CPM_LPCDR_LPCS_MASK (0x3 << CPM_LPCDR_LPCS_BIT) +#define CPM_LPCDR_CELCD BIT(28) +#define CPM_LPCDR_LCD_BUSY BIT(27) +#define CPM_LPCDR_LCD_STOP BIT(26) +#define CPM_LPCDR_PIXDIV_BIT 0 +#define CPM_LPCDR_PIXDIV_MASK (0xff << CPM_LPCDR_PIXDIV_BIT) + +/* MSC clock divider register */ +#define CPM_MSCCDR_MPCS_BIT 30 +#define CPM_MSCCDR_MPCS_MASK (3 << CPM_MSCCDR_MPCS_BIT) +#define CPM_MSCCDR_MPCS_STOP (0x0 << CPM_MSCCDR_MPCS_BIT) +#define CPM_MSCCDR_MPCS_SRC (0x1 << CPM_MSCCDR_MPCS_BIT) +#define CPM_MSCCDR_MPCS_MPLL (0x2 << CPM_MSCCDR_MPCS_BIT) +#define CPM_MSCCDR_CE BIT(29) +#define CPM_MSCCDR_MSC_BUSY BIT(28) +#define CPM_MSCCDR_MSC_STOP BIT(27) +#define CPM_MSCCDR_MSC_CLK0_SEL BIT(15) +#define CPM_MSCCDR_MSCDIV_BIT 0 +#define CPM_MSCCDR_MSCDIV_MASK (0xff << CPM_MSCCDR_MSCDIV_BIT) + +/* UHC 48M clock divider register */ +#define CPM_UHCCDR_UHCS_BIT 30 +#define CPM_UHCCDR_UHCS_MASK (0x3 << CPM_UHCCDR_UHCS_BIT) +#define CPM_UHCCDR_UHCS_SRC (0x0 << CPM_UHCCDR_UHCS_BIT) +#define CPM_UHCCDR_UHCS_MPLL (0x1 << CPM_UHCCDR_UHCS_BIT) +#define CPM_UHCCDR_UHCS_EPLL (0x2 << CPM_UHCCDR_UHCS_BIT) +#define CPM_UHCCDR_UHCS_OTG (0x3 << CPM_UHCCDR_UHCS_BIT) +#define CPM_UHCCDR_CE_UHC BIT(29) +#define CPM_UHCCDR_UHC_BUSY BIT(28) +#define CPM_UHCCDR_UHC_STOP BIT(27) +#define CPM_UHCCDR_UHCDIV_BIT 0 +#define CPM_UHCCDR_UHCDIV_MASK (0xff << CPM_UHCCDR_UHCDIV_BIT) + +/* SSI clock divider register */ +#define CPM_SSICDR_SCS BIT(31) +#define CPM_SSICDR_SSIDIV_BIT 0 +#define CPM_SSICDR_SSIDIV_MASK (0x3f << CPM_SSICDR_SSIDIV_BIT) + +/* CIM MCLK clock divider register */ +#define CPM_CIMCDR_CIMDIV_BIT 0 +#define CPM_CIMCDR_CIMDIV_MASK (0xff << CPM_CIMCDR_CIMDIV_BIT) + +/* GPS clock divider register */ +#define CPM_GPSCDR_GPCS BIT(31) +#define CPM_GPSCDR_GPSDIV_BIT 0 +#define CPM_GSPCDR_GPSDIV_MASK (0xf << CPM_GPSCDR_GPSDIV_BIT) + +/* PCM device clock divider register */ +#define CPM_PCMCDR_PCMS BIT(31) +#define CPM_PCMCDR_PCMPCS BIT(30) +#define CPM_PCMCDR_PCMDIV_BIT 0 +#define CPM_PCMCDR_PCMDIV_MASK (0x1ff << CPM_PCMCDR_PCMDIV_BIT) + +/* GPU clock divider register */ +#define CPM_GPUCDR_GPCS BIT(31) +#define CPM_GPUCDR_GPUDIV_BIT 0 +#define CPM_GPUCDR_GPUDIV_MASK (0x7 << CPM_GPUCDR_GPUDIV_BIT) + +/* HDMI clock divider register */ +#define CPM_HDMICDR_HPCS_BIT 30 +#define CPM_HDMICDR_HPCS_MASK (0x3 << CPM_HDMICDR_HPCS_BIT) +#define CPM_HDMICDR_CEHDMI BIT(29) +#define CPM_HDMICDR_HDMI_BUSY BIT(28) +#define CPM_HDMICDR_HDMI_STOP BIT(26) +#define CPM_HDMICDR_HDMIDIV_BIT 0 +#define CPM_HDMICDR_HDMIDIV_MASK (0xff << CPM_HDMICDR_HDMIDIV_BIT) + +/* Low Power Control Register */ +#define CPM_LCR_PD_SCPU BIT(31) +#define CPM_LCR_PD_VPU BIT(30) +#define CPM_LCR_PD_GPU BIT(29) +#define CPM_LCR_PD_GPS BIT(28) +#define CPM_LCR_SCPUS BIT(27) +#define CPM_LCR_VPUS BIT(26) +#define CPM_LCR_GPUS BIT(25) +#define CPM_LCR_GPSS BIT(24) +#define CPM_LCR_GPU_IDLE BIT(20) +#define CPM_LCR_PST_BIT 8 +#define CPM_LCR_PST_MASK (0xfff << CPM_LCR_PST_BIT) +#define CPM_LCR_DOZE_DUTY_BIT 3 +#define CPM_LCR_DOZE_DUTY_MASK (0x1f << CPM_LCR_DOZE_DUTY_BIT) +#define CPM_LCR_DOZE_ON BIT(2) +#define CPM_LCR_LPM_BIT 0 +#define CPM_LCR_LPM_MASK (0x3 << CPM_LCR_LPM_BIT) +#define CPM_LCR_LPM_IDLE (0x0 << CPM_LCR_LPM_BIT) +#define CPM_LCR_LPM_SLEEP (0x1 << CPM_LCR_LPM_BIT) + +/* Clock Gate Register0 */ +#define CPM_CLKGR0_DDR1 BIT(31) +#define CPM_CLKGR0_DDR0 BIT(30) +#define CPM_CLKGR0_IPU BIT(29) +#define CPM_CLKGR0_LCD1 BIT(28) +#define CPM_CLKGR0_LCD BIT(27) +#define CPM_CLKGR0_CIM BIT(26) +#define CPM_CLKGR0_I2C2 BIT(25) +#define CPM_CLKGR0_UHC BIT(24) +#define CPM_CLKGR0_MAC BIT(23) +#define CPM_CLKGR0_GPS BIT(22) +#define CPM_CLKGR0_PDMAC BIT(21) +#define CPM_CLKGR0_SSI2 BIT(20) +#define CPM_CLKGR0_SSI1 BIT(19) +#define CPM_CLKGR0_UART3 BIT(18) +#define CPM_CLKGR0_UART2 BIT(17) +#define CPM_CLKGR0_UART1 BIT(16) +#define CPM_CLKGR0_UART0 BIT(15) +#define CPM_CLKGR0_SADC BIT(14) +#define CPM_CLKGR0_KBC BIT(13) +#define CPM_CLKGR0_MSC2 BIT(12) +#define CPM_CLKGR0_MSC1 BIT(11) +#define CPM_CLKGR0_OWI BIT(10) +#define CPM_CLKGR0_TSSI BIT(9) +#define CPM_CLKGR0_AIC BIT(8) +#define CPM_CLKGR0_SCC BIT(7) +#define CPM_CLKGR0_I2C1 BIT(6) +#define CPM_CLKGR0_I2C0 BIT(5) +#define CPM_CLKGR0_SSI0 BIT(4) +#define CPM_CLKGR0_MSC0 BIT(3) +#define CPM_CLKGR0_OTG BIT(2) +#define CPM_CLKGR0_BCH BIT(1) +#define CPM_CLKGR0_NEMC BIT(0) + +/* Clock Gate Register1 */ +#define CPM_CLKGR1_P1 BIT(15) +#define CPM_CLKGR1_X2D BIT(14) +#define CPM_CLKGR1_DES BIT(13) +#define CPM_CLKGR1_I2C4 BIT(12) +#define CPM_CLKGR1_AHB BIT(11) +#define CPM_CLKGR1_UART4 BIT(10) +#define CPM_CLKGR1_HDMI BIT(9) +#define CPM_CLKGR1_OTG1 BIT(8) +#define CPM_CLKGR1_GPVLC BIT(7) +#define CPM_CLKGR1_AIC1 BIT(6) +#define CPM_CLKGR1_COMPRES BIT(5) +#define CPM_CLKGR1_GPU BIT(4) +#define CPM_CLKGR1_PCM BIT(3) +#define CPM_CLKGR1_VPU BIT(2) +#define CPM_CLKGR1_TSSI1 BIT(1) +#define CPM_CLKGR1_I2C3 BIT(0) + +/* Oscillator and Power Control Register */ +#define CPM_OPCR_O1ST_BIT 8 +#define CPM_OPCR_O1ST_MASK (0xff << CPM_OPCR_O1ST_BIT) +#define CPM_OPCR_SPENDN BIT(7) +#define CPM_OPCR_GPSEN BIT(6) +#define CPM_OPCR_SPENDH BIT(5) +#define CPM_OPCR_O1SE BIT(4) +#define CPM_OPCR_ERCS BIT(2) /* 0: select EXCLK/512 clock, 1: RTCLK clock */ +#define CPM_OPCR_USBM BIT(0) /* 0: select EXCLK/512 clock, 1: RTCLK clock */ + +/* Reset Status Register */ +#define CPM_RSR_P0R BIT(2) +#define CPM_RSR_WR BIT(1) +#define CPM_RSR_PR BIT(0) + +/* BCH clock divider register */ +#define CPM_BCHCDR_BPCS_BIT 30 +#define CPM_BCHCDR_BPCS_MASK (0x3 << CPM_BCHCDR_BPCS_BIT) +#define CPM_BCHCDR_BPCS_STOP (0X0 << CPM_BCHCDR_BPCS_BIT) +#define CPM_BCHCDR_BPCS_SRC_CLK (0x1 << CPM_BCHCDR_BPCS_BIT) +#define CPM_BCHCDR_BPCS_MPLL (0x2 << CPM_BCHCDR_BPCS_BIT) +#define CPM_BCHCDR_BPCS_EPLL (0x3 << CPM_BCHCDR_BPCS_BIT) +#define CPM_BCHCDR_CE_BCH BIT(29) +#define CPM_BCHCDR_BCH_BUSY BIT(28) +#define CPM_BCHCDR_BCH_STOP BIT(27) +#define CPM_BCHCDR_BCHCDR_BIT 0 +#define CPM_BCHCDR_BCHCDR_MASK (0x7 << CPM_BCHCDR_BCHCDR_BIT) + +/* CPM scratch pad protected register(CPSPPR) */ +#define CPSPPR_CPSPR_WRITABLE 0x00005a5a +#define RECOVERY_SIGNATURE 0x1a1a /* means "RECY" */ +#define RECOVERY_SIGNATURE_SEC 0x800 /* means "RECY" */ + +#define REBOOT_SIGNATURE 0x3535 /* means reboot */ + +/* XPLL control register */ +#define XLOCK (1 << 6) +#define XPLL_ON (1 << 4) +#define XF_MODE (1 << 3) +#define XPLLBP (1 << 1) +#define XPLLEN (1 << 0) + +enum PLLS { + EXTCLK = 0, + APLL, + MPLL, + EPLL, + VPLL, +}; + +#define M_N_OD(m, n, od) \ + ((((m) - 1) << 19) | (((n) - 1) << 13) | (((od) - 1) << 9)) + +struct cgu_pll_select { + u8 reg; + u8 pll; + u8 pll_shift; +}; + +static void pll_init_one(int pll, int m, int n, int od) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + void __iomem *pll_reg = cpm_regs + CPM_CPAPCR + ((pll - 1) * 4); + + setbits_le32(pll_reg, M_N_OD(m, n, od) | XPLLEN); + + /* FIXME */ + while (!(readl(pll_reg) & XPLL_ON)) + ; +} + +static void cpu_mux_select(int pll) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + u32 clk_ctrl; + unsigned int selectplls[] = { + CPM_PLL_SEL_STOP, + CPM_PLL_SEL_SRC, + CPM_PLL_SEL_MPLL, + CPM_PLL_SEL_EPLL + }; + + /* Init CPU, L2CACHE, AHB0, AHB2, APB clock */ + clk_ctrl = CPM_CPCCR_CE_CPU | CPM_CPCCR_CE_AHB0 | CPM_CPCCR_CE_AHB2 | + ((6 - 1) << CPM_CPCCR_H2DIV_BIT) | + ((3 - 1) << CPM_CPCCR_H0DIV_BIT) | + ((2 - 1) << CPM_CPCCR_L2DIV_BIT) | + ((1 - 1) << CPM_CPCCR_CDIV_BIT); + + if (CONFIG_SYS_MHZ >= 1000) + clk_ctrl |= (12 - 1) << CPM_CPCCR_PDIV_BIT; + else + clk_ctrl |= (6 - 1) << CPM_CPCCR_PDIV_BIT; + + clrsetbits_le32(cpm_regs + CPM_CPCCR, 0x00ffffff, clk_ctrl); + + while (readl(cpm_regs + CPM_CPCSR) & (CPM_CPCSR_CDIV_BUSY | + CPM_CPCSR_H0DIV_BUSY | CPM_CPCSR_H2DIV_BUSY)) + ; + + clk_ctrl = (selectplls[pll] << CPM_CPCCR_SEL_CPLL_BIT) | + (selectplls[MPLL] << CPM_CPCCR_SEL_H0PLL_BIT) | + (selectplls[MPLL] << CPM_CPCCR_SEL_H2PLL_BIT); + if (pll == APLL) + clk_ctrl |= CPM_PLL_SEL_SRC << CPM_CPCCR_SEL_SRC_BIT; + else + clk_ctrl |= CPM_SRC_SEL_EXCLK << CPM_CPCCR_SEL_SRC_BIT; + + clrsetbits_le32(cpm_regs + CPM_CPCCR, 0xff << 24, clk_ctrl); +} + +static void ddr_mux_select(int pll) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + int selectplls[] = { CPM_DDRCDR_DCS_STOP, + CPM_DDRCDR_DCS_SRC, + CPM_DDRCDR_DCS_MPLL}; + + writel(selectplls[pll] | CPM_DDRCDR_CE_DDR | (JZ4780_SYS_MEM_DIV - 1), + cpm_regs + CPM_DDCDR); + + while (readl(cpm_regs + CPM_DDCDR) & CPM_DDRCDR_DDR_BUSY) + ; + + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_DDR0); + + mdelay(200); +} + +static void cgu_mux_init(struct cgu_pll_select *cgu, unsigned int num) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + unsigned int selectplls[] = {0, 1, 2, 3, 2, 6}; + int i; + + for (i = 0; i < num; i++) + writel(selectplls[cgu[i].pll] << cgu[i].pll_shift, + cpm_regs + cgu[i].reg); +} + +void pll_init(void) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + struct cgu_pll_select cgu_mux[] = { + { CPM_MSCCDR, MPLL, 30 }, + { CPM_LPCDR, VPLL, 30 }, + { CPM_LPCDR1, VPLL, 30 }, + { CPM_GPUCDR, MPLL, 30 }, + { CPM_HDMICDR, VPLL, 30 }, + { CPM_I2SCDR, EPLL, 30 }, + { CPM_BCHCDR, MPLL, 30 }, + { CPM_VPUCDR, 0x1, 30 }, + { CPM_UHCCDR, 0x3, 30 }, + { CPM_CIMCDR, 0x1, 31 }, + { CPM_PCMCDR, 0x5, 29 }, + { CPM_SSICDR, 0x3, 30 }, + }; + + /* PLL stable time set to default -- 1ms */ + clrsetbits_le32(cpm_regs + CPM_CPPCR, 0xfffff, (16 << 8) | 0x20); + + pll_init_one(APLL, JZ4780_APLL_M, JZ4780_APLL_N, JZ4780_APLL_OD); + pll_init_one(MPLL, JZ4780_MPLL_M, JZ4780_MPLL_N, JZ4780_MPLL_OD); + pll_init_one(VPLL, JZ4780_VPLL_M, JZ4780_VPLL_N, JZ4780_VPLL_OD); + pll_init_one(EPLL, JZ4780_EPLL_M, JZ4780_EPLL_N, JZ4780_EPLL_OD); + + cpu_mux_select(MPLL); + ddr_mux_select(MPLL); + cgu_mux_init(cgu_mux, ARRAY_SIZE(cgu_mux)); +} + +const u32 jz4780_clk_get_efuse_clk(void) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + u32 cpccr = readl(cpm_regs + CPM_CPCCR); + u32 ahb2_div = ((cpccr & CPM_CPCCR_H2DIV_MASK) >> + CPM_CPCCR_H2DIV_BIT) + 1; + return JZ4780_SYS_MEM_SPEED / ahb2_div; +} + +void jz4780_clk_ungate_ethernet(void) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_MAC); + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_NEMC); +} + +void jz4780_clk_ungate_mmc(void) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + u32 msc_cdr = JZ4780_SYS_MEM_SPEED / 24000000 / 2 - 1; + + msc_cdr |= CPM_MSCCDR_MPCS_MPLL | CPM_MSCCDR_CE; + writel(msc_cdr, cpm_regs + CPM_MSCCDR); + writel(msc_cdr, cpm_regs + CPM_MSCCDR1); + writel(msc_cdr, cpm_regs + CPM_MSCCDR2); + + /* The wait_for_bit() won't fit, thus unbounded loop here. */ + while (readl(cpm_regs + CPM_MSCCDR1) & CPM_MSCCDR_MSC_BUSY) + ; +} + +void jz4780_clk_ungate_uart(const unsigned int uart) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + + if (uart == 0) + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART0); + else if (uart == 1) + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART1); + else if (uart == 2) + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART2); + else if (uart == 3) + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART3); + else if (uart == 4) + clrbits_le32(cpm_regs + CPM_CLKGR1, CPM_CLKGR1_UART4); + else + printf("%s[%i]: Invalid UART %d\n", __func__, __LINE__, uart); +} diff --git a/arch/mips/mach-jz47xx/jz4780/reset.c b/arch/mips/mach-jz47xx/jz4780/reset.c new file mode 100644 index 00000000000..73af34721f2 --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/reset.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * JZ4780 common routines + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + */ + +#include <config.h> +#include <common.h> +#include <asm/io.h> +#include <mach/jz4780.h> + +/* WDT */ +#define WDT_TDR 0x00 +#define WDT_TCER 0x04 +#define WDT_TCNT 0x08 +#define WDT_TCSR 0x0C + +/* Register definition */ +#define WDT_TCSR_PRESCALE_BIT 3 +#define WDT_TCSR_PRESCALE_MASK (0x7 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE1 (0x0 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE4 (0x1 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE16 (0x2 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE64 (0x3 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE256 (0x4 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE1024 (0x5 << WDT_TCSR_PRESCALE_BIT) +#define WDT_TCSR_EXT_EN BIT(2) +#define WDT_TCSR_RTC_EN BIT(1) +#define WDT_TCSR_PCK_EN BIT(0) + +#define WDT_TCER_TCEN BIT(0) + +void _machine_restart(void) +{ + void __iomem *wdt_regs = (void __iomem *)WDT_BASE; + + /* EXTAL as the timer clock input. */ + writew(WDT_TCSR_PRESCALE1 | WDT_TCSR_EXT_EN, wdt_regs + WDT_TCSR); + + /* Reset the WDT counter and timeout. */ + writew(0, wdt_regs + WDT_TCNT); + writew(0, wdt_regs + WDT_TDR); + + jz4780_tcu_wdt_start(); + + /* WDT start */ + writeb(WDT_TCER_TCEN, wdt_regs + WDT_TCER); + + for (;;) + ; +} diff --git a/arch/mips/mach-jz47xx/jz4780/sdram.c b/arch/mips/mach-jz47xx/jz4780/sdram.c new file mode 100644 index 00000000000..5b25c8d0021 --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/sdram.c @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * JZ4780 DDR initialization + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * Based on spl/common/{jz4780_ddr,jz_ddr3_init}.c from X-Boot + * Copyright (c) 2006-2013 Ingenic Semiconductor + */ + +#include <common.h> +#include <asm/io.h> +#include <mach/jz4780.h> +#include <mach/jz4780_dram.h> + +static const u32 get_mem_clk(void) +{ + const u32 mpll_out = ((u64)JZ4780_SYS_EXTAL * JZ4780_MPLL_M) / + (JZ4780_MPLL_N * JZ4780_MPLL_OD); + return mpll_out / JZ4780_SYS_MEM_DIV; +} + +u32 sdram_size(int cs) +{ + u32 dw = DDR_DW32 ? 4 : 2; + u32 banks = DDR_BANK8 ? 8 : 4; + u32 size = 0; + + if ((cs == 0) && DDR_CS0EN) { + size = (1 << (DDR_ROW + DDR_COL)) * dw * banks; + if (DDR_CS1EN && (size > 0x20000000)) + size = 0x20000000; + } else if ((cs == 1) && DDR_CS1EN) { + size = (1 << (DDR_ROW + DDR_COL)) * dw * banks; + } + + return size; +} + +static void ddr_cfg_init(void) +{ + void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE; + u32 ddrc_cfg, tmp; + + tmp = DDR_CL; + if (tmp) + tmp--; + if (tmp > 4) + tmp = 4; + + ddrc_cfg = DDRC_CFG_TYPE_DDR3 | DDRC_CFG_IMBA | + DDR_DW32 | DDRC_CFG_MPRT | ((tmp | 0x8) << 2) | + ((DDR_ROW - 12) << 11) | ((DDR_COL - 8) << 8) | + (DDR_CS0EN << 6) | (DDR_BANK8 << 1) | + ((DDR_ROW - 12) << 27) | ((DDR_COL - 8) << 24) | + (DDR_CS1EN << 7) | (DDR_BANK8 << 23); + + if (DDR_BL > 4) + ddrc_cfg |= BIT(21); + + writel(ddrc_cfg, ddr_ctl_regs + DDRC_CFG); +} + +static void ddr_phy_init(const struct jz4780_ddr_config *ddr_config) +{ + void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE; + void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET; + unsigned int count = 0, i; + u32 reg, mask; + + writel(DDRP_DCR_TYPE_DDR3 | (DDR_BANK8 << 3), ddr_phy_regs + DDRP_DCR); + + writel(ddr_config->mr0, ddr_phy_regs + DDRP_MR0); + writel(ddr_config->mr1, ddr_phy_regs + DDRP_MR1); + writel(0, ddr_phy_regs + DDRP_ODTCR); + writel(0, ddr_phy_regs + DDRP_MR2); + + writel(ddr_config->ptr0, ddr_phy_regs + DDRP_PTR0); + writel(ddr_config->ptr1, ddr_phy_regs + DDRP_PTR1); + writel(ddr_config->ptr2, ddr_phy_regs + DDRP_PTR2); + + writel(ddr_config->dtpr0, ddr_phy_regs + DDRP_DTPR0); + writel(ddr_config->dtpr1, ddr_phy_regs + DDRP_DTPR1); + writel(ddr_config->dtpr2, ddr_phy_regs + DDRP_DTPR2); + + writel(DDRP_PGCR_DQSCFG | (7 << DDRP_PGCR_CKEN_BIT) | + (2 << DDRP_PGCR_CKDV_BIT) | + (DDR_CS0EN | (DDR_CS1EN << 1)) << DDRP_PGCR_RANKEN_BIT | + DDRP_PGCR_ZCKSEL_32 | DDRP_PGCR_PDDISDX, + ddr_phy_regs + DDRP_PGCR); + + for (i = 0; i < 8; i++) + clrbits_le32(ddr_phy_regs + DDRP_DXGCR(i), 0x3 << 9); + + count = 0; + mask = DDRP_PGSR_IDONE | DDRP_PGSR_DLDONE | DDRP_PGSR_ZCDONE; + for (;;) { + reg = readl(ddr_phy_regs + DDRP_PGSR); + if ((reg == mask) || (reg == 0x1f)) + break; + if (count++ == 10000) + hang(); + } + + /* DQS extension and early set to 1 */ + clrsetbits_le32(ddr_phy_regs + DDRP_DSGCR, 0x7E << 4, 0x12 << 4); + + /* 500 pull up and 500 pull down */ + clrsetbits_le32(ddr_phy_regs + DDRP_DXCCR, 0xFF << 4, 0xC4 << 4); + + /* Initialise phy */ + writel(DDRP_PIR_INIT | DDRP_PIR_DRAMINT | DDRP_PIR_DRAMRST, + ddr_phy_regs + DDRP_PIR); + + count = 0; + mask |= DDRP_PGSR_DIDONE; + for (;;) { + reg = readl(ddr_phy_regs + DDRP_PGSR); + if ((reg == mask) || (reg == 0x1f)) + break; + if (count++ == 20000) + hang(); + } + + writel(DDRP_PIR_INIT | DDRP_PIR_QSTRN, ddr_phy_regs + DDRP_PIR); + + count = 0; + mask |= DDRP_PGSR_DTDONE; + for (;;) { + reg = readl(ddr_phy_regs + DDRP_PGSR); + if (reg == mask) + break; + if (count++ != 50000) + continue; + reg &= DDRP_PGSR_DTDONE | DDRP_PGSR_DTERR | DDRP_PGSR_DTIERR; + if (reg) + hang(); + count = 0; + } + + /* Override impedance */ + clrsetbits_le32(ddr_phy_regs + DDRP_ZQXCR0(0), 0x3ff, + ((ddr_config->pullup & 0x1f) << DDRP_ZQXCR_PULLUP_IMPE_BIT) | + ((ddr_config->pulldn & 0x1f) << DDRP_ZQXCR_PULLDOWN_IMPE_BIT) | + DDRP_ZQXCR_ZDEN); +} + +#define JZBIT(bit) ((bit % 4) * 8) +#define JZMASK(bit) (0x1f << JZBIT(bit)) + +static void remap_swap(int a, int b) +{ + void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE; + u32 remmap[2], tmp[2]; + + remmap[0] = readl(ddr_ctl_regs + DDRC_REMMAP(a / 4)); + remmap[1] = readl(ddr_ctl_regs + DDRC_REMMAP(b / 4)); + + tmp[0] = (remmap[0] & JZMASK(a)) >> JZBIT(a); + tmp[1] = (remmap[1] & JZMASK(b)) >> JZBIT(b); + + remmap[0] &= ~JZMASK(a); + remmap[1] &= ~JZMASK(b); + + writel(remmap[0] | (tmp[1] << JZBIT(a)), + ddr_ctl_regs + DDRC_REMMAP(a / 4)); + writel(remmap[1] | (tmp[0] << JZBIT(b)), + ddr_ctl_regs + DDRC_REMMAP(b / 4)); +} + +static void mem_remap(void) +{ + u32 start = (DDR_ROW + DDR_COL + (DDR_DW32 ? 4 : 2) / 2) - 12; + u32 num = DDR_BANK8 ? 3 : 2; + + if (DDR_CS0EN && DDR_CS1EN) + num++; + + for (; num > 0; num--) + remap_swap(0 + num - 1, start + num - 1); +} + +/* Fetch DRAM config from board file */ +__weak const struct jz4780_ddr_config *jz4780_get_ddr_config(void) +{ + return NULL; +} + +void sdram_init(void) +{ + const struct jz4780_ddr_config *ddr_config = jz4780_get_ddr_config(); + void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE; + void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET; + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + u32 mem_clk, tmp, i; + u32 mem_base0, mem_base1; + u32 mem_mask0, mem_mask1; + u32 mem_size0, mem_size1; + + if (!ddr_config) + hang(); + + /* Reset DLL in DDR PHY */ + writel(0x3, cpm_regs + 0xd0); + mdelay(400); + writel(0x1, cpm_regs + 0xd0); + mdelay(400); + + /* Enter reset */ + writel(0xf << 20, ddr_ctl_regs + DDRC_CTRL); + + mem_clk = get_mem_clk(); + + tmp = 1000000000 / mem_clk; + if (1000000000 % mem_clk) + tmp++; + tmp = DDR_tREFI / tmp; + tmp = tmp / (16 * (1 << DDR_CLK_DIV)) - 1; + if (tmp > 0xff) + tmp = 0xff; + if (tmp < 1) + tmp = 1; + + writel(0x0, ddr_ctl_regs + DDRC_CTRL); + + writel(0x150000, ddr_phy_regs + DDRP_DTAR); + ddr_phy_init(ddr_config); + + writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL); + writel(0x0, ddr_ctl_regs + DDRC_CTRL); + + ddr_cfg_init(); + + for (i = 0; i < 6; i++) + writel(ddr_config->timing[i], ddr_ctl_regs + DDRC_TIMING(i)); + + mem_size0 = sdram_size(0); + mem_size1 = sdram_size(1); + + if (!mem_size1 && mem_size0 > 0x20000000) { + mem_base0 = 0x0; + mem_mask0 = ~(((mem_size0 * 2) >> 24) - 1) & DDRC_MMAP_MASK_MASK; + } else { + mem_base0 = (DDR_MEM_PHY_BASE >> 24) & 0xff; + mem_mask0 = ~((mem_size0 >> 24) - 1) & DDRC_MMAP_MASK_MASK; + } + + if (mem_size1) { + mem_mask1 = ~((mem_size1 >> 24) - 1) & DDRC_MMAP_MASK_MASK; + mem_base1 = ((DDR_MEM_PHY_BASE + mem_size0) >> 24) & 0xff; + } else { + mem_mask1 = 0; + mem_base1 = 0xff; + } + + writel(mem_base0 << DDRC_MMAP_BASE_BIT | mem_mask0, + ddr_ctl_regs + DDRC_MMAP0); + writel(mem_base1 << DDRC_MMAP_BASE_BIT | mem_mask1, + ddr_ctl_regs + DDRC_MMAP1); + writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL); + writel((DDR_CLK_DIV << 1) | DDRC_REFCNT_REF_EN | + (tmp << DDRC_REFCNT_CON_BIT), + ddr_ctl_regs + DDRC_REFCNT); + writel((1 << 15) | (4 << 12) | (1 << 11) | (1 << 8) | (0 << 6) | + (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1), + ddr_ctl_regs + DDRC_CTRL); + mem_remap(); + clrbits_le32(ddr_ctl_regs + DDRC_ST, 0x40); +} diff --git a/arch/mips/mach-jz47xx/jz4780/timer.c b/arch/mips/mach-jz47xx/jz4780/timer.c new file mode 100644 index 00000000000..a689b9d71ac --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/timer.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * JZ4780 timer + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + */ + +#include <config.h> +#include <common.h> +#include <div64.h> +#include <asm/io.h> +#include <asm/mipsregs.h> +#include <mach/jz4780.h> + +#define TCU_TSR 0x1C /* Timer Stop Register */ +#define TCU_TSSR 0x2C /* Timer Stop Set Register */ +#define TCU_TSCR 0x3C /* Timer Stop Clear Register */ +#define TCU_TER 0x10 /* Timer Counter Enable Register */ +#define TCU_TESR 0x14 /* Timer Counter Enable Set Register */ +#define TCU_TECR 0x18 /* Timer Counter Enable Clear Register */ +#define TCU_TFR 0x20 /* Timer Flag Register */ +#define TCU_TFSR 0x24 /* Timer Flag Set Register */ +#define TCU_TFCR 0x28 /* Timer Flag Clear Register */ +#define TCU_TMR 0x30 /* Timer Mask Register */ +#define TCU_TMSR 0x34 /* Timer Mask Set Register */ +#define TCU_TMCR 0x38 /* Timer Mask Clear Register */ +/* n = 0,1,2,3,4,5 */ +#define TCU_TDFR(n) (0x40 + (n) * 0x10) /* Timer Data Full Reg */ +#define TCU_TDHR(n) (0x44 + (n) * 0x10) /* Timer Data Half Reg */ +#define TCU_TCNT(n) (0x48 + (n) * 0x10) /* Timer Counter Reg */ +#define TCU_TCSR(n) (0x4C + (n) * 0x10) /* Timer Control Reg */ + +#define TCU_OSTCNTL 0xe4 +#define TCU_OSTCNTH 0xe8 +#define TCU_OSTCSR 0xec +#define TCU_OSTCNTHBUF 0xfc + +/* Register definitions */ +#define TCU_TCSR_PWM_SD BIT(9) +#define TCU_TCSR_PWM_INITL_HIGH BIT(8) +#define TCU_TCSR_PWM_EN BIT(7) +#define TCU_TCSR_PRESCALE_BIT 3 +#define TCU_TCSR_PRESCALE_MASK (0x7 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_PRESCALE1 (0x0 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_PRESCALE4 (0x1 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_PRESCALE16 (0x2 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_PRESCALE64 (0x3 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_PRESCALE256 (0x4 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_PRESCALE1024 (0x5 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_EXT_EN BIT(2) +#define TCU_TCSR_RTC_EN BIT(1) +#define TCU_TCSR_PCK_EN BIT(0) + +#define TCU_TER_TCEN5 BIT(5) +#define TCU_TER_TCEN4 BIT(4) +#define TCU_TER_TCEN3 BIT(3) +#define TCU_TER_TCEN2 BIT(2) +#define TCU_TER_TCEN1 BIT(1) +#define TCU_TER_TCEN0 BIT(0) + +#define TCU_TESR_TCST5 BIT(5) +#define TCU_TESR_TCST4 BIT(4) +#define TCU_TESR_TCST3 BIT(3) +#define TCU_TESR_TCST2 BIT(2) +#define TCU_TESR_TCST1 BIT(1) +#define TCU_TESR_TCST0 BIT(0) + +#define TCU_TECR_TCCL5 BIT(5) +#define TCU_TECR_TCCL4 BIT(4) +#define TCU_TECR_TCCL3 BIT(3) +#define TCU_TECR_TCCL2 BIT(2) +#define TCU_TECR_TCCL1 BIT(1) +#define TCU_TECR_TCCL0 BIT(0) + +#define TCU_TFR_HFLAG5 BIT(21) +#define TCU_TFR_HFLAG4 BIT(20) +#define TCU_TFR_HFLAG3 BIT(19) +#define TCU_TFR_HFLAG2 BIT(18) +#define TCU_TFR_HFLAG1 BIT(17) +#define TCU_TFR_HFLAG0 BIT(16) +#define TCU_TFR_FFLAG5 BIT(5) +#define TCU_TFR_FFLAG4 BIT(4) +#define TCU_TFR_FFLAG3 BIT(3) +#define TCU_TFR_FFLAG2 BIT(2) +#define TCU_TFR_FFLAG1 BIT(1) +#define TCU_TFR_FFLAG0 BIT(0) + +#define TCU_TFSR_HFLAG5 BIT(21) +#define TCU_TFSR_HFLAG4 BIT(20) +#define TCU_TFSR_HFLAG3 BIT(19) +#define TCU_TFSR_HFLAG2 BIT(18) +#define TCU_TFSR_HFLAG1 BIT(17) +#define TCU_TFSR_HFLAG0 BIT(16) +#define TCU_TFSR_FFLAG5 BIT(5) +#define TCU_TFSR_FFLAG4 BIT(4) +#define TCU_TFSR_FFLAG3 BIT(3) +#define TCU_TFSR_FFLAG2 BIT(2) +#define TCU_TFSR_FFLAG1 BIT(1) +#define TCU_TFSR_FFLAG0 BIT(0) + +#define TCU_TFCR_HFLAG5 BIT(21) +#define TCU_TFCR_HFLAG4 BIT(20) +#define TCU_TFCR_HFLAG3 BIT(19) +#define TCU_TFCR_HFLAG2 BIT(18) +#define TCU_TFCR_HFLAG1 BIT(17) +#define TCU_TFCR_HFLAG0 BIT(16) +#define TCU_TFCR_FFLAG5 BIT(5) +#define TCU_TFCR_FFLAG4 BIT(4) +#define TCU_TFCR_FFLAG3 BIT(3) +#define TCU_TFCR_FFLAG2 BIT(2) +#define TCU_TFCR_FFLAG1 BIT(1) +#define TCU_TFCR_FFLAG0 BIT(0) + +#define TCU_TMR_HMASK5 BIT(21) +#define TCU_TMR_HMASK4 BIT(20) +#define TCU_TMR_HMASK3 BIT(19) +#define TCU_TMR_HMASK2 BIT(18) +#define TCU_TMR_HMASK1 BIT(17) +#define TCU_TMR_HMASK0 BIT(16) +#define TCU_TMR_FMASK5 BIT(5) +#define TCU_TMR_FMASK4 BIT(4) +#define TCU_TMR_FMASK3 BIT(3) +#define TCU_TMR_FMASK2 BIT(2) +#define TCU_TMR_FMASK1 BIT(1) +#define TCU_TMR_FMASK0 BIT(0) + +#define TCU_TMSR_HMST5 BIT(21) +#define TCU_TMSR_HMST4 BIT(20) +#define TCU_TMSR_HMST3 BIT(19) +#define TCU_TMSR_HMST2 BIT(18) +#define TCU_TMSR_HMST1 BIT(17) +#define TCU_TMSR_HMST0 BIT(16) +#define TCU_TMSR_FMST5 BIT(5) +#define TCU_TMSR_FMST4 BIT(4) +#define TCU_TMSR_FMST3 BIT(3) +#define TCU_TMSR_FMST2 BIT(2) +#define TCU_TMSR_FMST1 BIT(1) +#define TCU_TMSR_FMST0 BIT(0) + +#define TCU_TMCR_HMCL5 BIT(21) +#define TCU_TMCR_HMCL4 BIT(20) +#define TCU_TMCR_HMCL3 BIT(19) +#define TCU_TMCR_HMCL2 BIT(18) +#define TCU_TMCR_HMCL1 BIT(17) +#define TCU_TMCR_HMCL0 BIT(16) +#define TCU_TMCR_FMCL5 BIT(5) +#define TCU_TMCR_FMCL4 BIT(4) +#define TCU_TMCR_FMCL3 BIT(3) +#define TCU_TMCR_FMCL2 BIT(2) +#define TCU_TMCR_FMCL1 BIT(1) +#define TCU_TMCR_FMCL0 BIT(0) + +#define TCU_TSR_WDTS BIT(16) +#define TCU_TSR_STOP5 BIT(5) +#define TCU_TSR_STOP4 BIT(4) +#define TCU_TSR_STOP3 BIT(3) +#define TCU_TSR_STOP2 BIT(2) +#define TCU_TSR_STOP1 BIT(1) +#define TCU_TSR_STOP0 BIT(0) + +#define TCU_TSSR_WDTSS BIT(16) +#define TCU_TSSR_STPS5 BIT(5) +#define TCU_TSSR_STPS4 BIT(4) +#define TCU_TSSR_STPS3 BIT(3) +#define TCU_TSSR_STPS2 BIT(2) +#define TCU_TSSR_STPS1 BIT(1) +#define TCU_TSSR_STPS0 BIT(0) + +#define TCU_TSSR_WDTSC BIT(16) +#define TCU_TSSR_STPC5 BIT(5) +#define TCU_TSSR_STPC4 BIT(4) +#define TCU_TSSR_STPC3 BIT(3) +#define TCU_TSSR_STPC2 BIT(2) +#define TCU_TSSR_STPC1 BIT(1) +#define TCU_TSSR_STPC0 BIT(0) + +#define TER_OSTEN BIT(15) + +#define OSTCSR_CNT_MD BIT(15) +#define OSTCSR_SD BIT(9) +#define OSTCSR_PRESCALE_16 (0x2 << 3) +#define OSTCSR_EXT_EN BIT(2) + +int timer_init(void) +{ + void __iomem *regs = (void __iomem *)TCU_BASE; + + writel(OSTCSR_SD, regs + TCU_OSTCSR); + reset_timer(); + writel(OSTCSR_CNT_MD | OSTCSR_EXT_EN | OSTCSR_PRESCALE_16, + regs + TCU_OSTCSR); + writew(TER_OSTEN, regs + TCU_TESR); + return 0; +} + +void reset_timer(void) +{ + void __iomem *regs = (void __iomem *)TCU_BASE; + + writel(0, regs + TCU_OSTCNTH); + writel(0, regs + TCU_OSTCNTL); +} + +static u64 get_timer64(void) +{ + void __iomem *regs = (void __iomem *)TCU_BASE; + u32 low = readl(regs + TCU_OSTCNTL); + u32 high = readl(regs + TCU_OSTCNTHBUF); + + return ((u64)high << 32) | low; +} + +ulong get_timer(ulong base) +{ + return lldiv(get_timer64(), 3000) - base; +} + +void __udelay(unsigned long usec) +{ + /* OST count increments at 3MHz */ + u64 end = get_timer64() + ((u64)usec * 3); + + while (get_timer64() < end) + ; +} + +unsigned long long get_ticks(void) +{ + return get_timer64(); +} + +void jz4780_tcu_wdt_start(void) +{ + void __iomem *tcu_regs = (void __iomem *)TCU_BASE; + + /* Enable WDT clock */ + writel(TCU_TSSR_WDTSC, tcu_regs + TCU_TSCR); +} diff --git a/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds b/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds new file mode 100644 index 00000000000..347cabc4505 --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\ + LENGTH = CONFIG_SPL_MAX_SIZE } +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_ARCH(mips) +ENTRY(_start) +SECTIONS +{ + .text : + { + __image_copy_start = .; + arch/mips/mach-jz47xx/start.o (.text*) + *(.text*) + } >.sram + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram + + . = ALIGN(4); + __image_copy_end = .; + + .bss : { + . = ALIGN(4); + __bss_start = .; + *(.sbss.*) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + __bss_end = .; + } >.sdram + + /DISCARD/ : { + *(.dynbss) + *(.dynstr) + *(.dynamic) + *(.interp) + *(.hash) + *(.gnu.*) + *(.plt) + *(.got.plt) + *(.rel.plt) + *(.rel.dyn) + } +} diff --git a/arch/mips/mach-jz47xx/start.S b/arch/mips/mach-jz47xx/start.S new file mode 100644 index 00000000000..760d0215493 --- /dev/null +++ b/arch/mips/mach-jz47xx/start.S @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Startup Code for MIPS32 XBURST CPU-core + * + * Copyright (c) 2010 Xiangfu Liu <xiangfu@sharism.cc> + */ + +#include <config.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/cacheops.h> +#include <asm/cache.h> +#include <mach/jz4780.h> + + .set noreorder + + .globl _start + .text +_start: +#ifdef CONFIG_SPL_BUILD + + /* magic value ("MSPL") */ + .word 0x4d53504c + + /* Invalidate BTB */ + mfc0 t0, CP0_CONFIG, 7 + nop + ori t0, 2 + mtc0 t0, CP0_CONFIG, 7 + nop + + /* + * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1 + */ + li t0, 0x0040FC04 + mtc0 t0, CP0_STATUS + + /* CAUSE register */ + /* IV=1, use the specical interrupt vector (0x200) */ + li t1, 0x00800000 + mtc0 t1, CP0_CAUSE + +#ifdef CONFIG_SOC_JZ4780 + /* enable bridge radical mode */ + la t0, CPM_BASE + lw t1, 0x24(t0) + ori t1, t1, 0x22 + sw t1, 0x24(t0) +#endif + + /* Set up stack */ + li sp, CONFIG_SPL_STACK + + b board_init_f + nop + +#ifdef CONFIG_SOC_JZ4780 + + .globl enable_caches + .ent enable_caches +enable_caches: + mtc0 zero, CP0_TAGLO + mtc0 zero, CP0_TAGHI + + li t0, KSEG0 + addu t1, t0, CONFIG_SYS_DCACHE_SIZE +1: + cache INDEX_STORE_TAG_D, 0(t0) + bne t0, t1, 1b + addiu t0, t0, CONFIG_SYS_CACHELINE_SIZE + + li t0, KSEG0 + addu t1, t0, CONFIG_SYS_ICACHE_SIZE +2: + cache INDEX_STORE_TAG_I, 0(t0) + bne t0, t1, 2b + addiu t0, t0, CONFIG_SYS_CACHELINE_SIZE + + /* Invalidate BTB */ + mfc0 t0, CP0_CONFIG, 7 + nop + ori t0, 2 + mtc0 t0, CP0_CONFIG, 7 + nop + + /* Enable caches */ + li t0, CONF_CM_CACHABLE_NONCOHERENT + mtc0 t0, CP0_CONFIG + nop + + jr ra + nop + + .end enable_caches + +#endif /* CONFIG_SOC_JZ4780 */ +#endif /* !CONFIG_SPL_BUILD */ diff --git a/arch/mips/mach-mscc/Kconfig b/arch/mips/mach-mscc/Kconfig new file mode 100644 index 00000000000..0e35b77c9db --- /dev/null +++ b/arch/mips/mach-mscc/Kconfig @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +menu "MSCC VCore-III platforms" + depends on ARCH_MSCC + +config SOC_VCOREIII + select MIPS_TUNE_24KC + select ROM_EXCEPTION_VECTORS + select SUPPORTS_BIG_ENDIAN + select SUPPORTS_CPU_MIPS32_R1 + select SUPPORTS_CPU_MIPS32_R2 + select SUPPORTS_LITTLE_ENDIAN + bool + +config SYS_SOC + default "mscc" + +config SOC_OCELOT + bool + select SOC_VCOREIII + help + This supports MSCC Ocelot family of SOCs. + +config SOC_LUTON + bool + select SOC_VCOREIII + help + This supports MSCC Luton family of SOCs. + +config SYS_CONFIG_NAME + default "vcoreiii" + +choice + prompt "Board select" + +config TARGET_OCELOT_PCB120 + bool "MSCC PCB120 Reference Board (aka VSC5635EV)" + select SOC_OCELOT + help + When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to + ocelot_pcb120 + +config TARGET_OCELOT_PCB123 + bool "MSCC PCB123 Reference Board (aka VSC7514EV))" + select SOC_OCELOT + help + When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to + ocelot_pcb123 + +config TARGET_LUTON_PCB091 + bool "MSCC PCB091 Reference Board" + select SOC_LUTON + select MSCC_BITBANG_SPI_GPIO + help + When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to + luton_pcb091 +endchoice + +choice + prompt "DDR type" + +config DDRTYPE_H5TQ4G63MFR + bool "Hynix H5TQ4G63MFR-PBC (4Gbit, DDR3-800, 256Mbitx16)" + +config DDRTYPE_MT41K256M16 + bool "Micron MT41K256M16 (4Gbit, DDR3L-800, 256Mbitx16)" + +config DDRTYPE_H5TQ1G63BFA + bool "Hynix H5TQ1G63BFA (1Gbit DDR3, x16)" + +config DDRTYPE_MT41J128M16HA + bool "Micron MT41J128M16HA-15E:D (2Gbit DDR3, x16)" + +config DDRTYPE_MT41K128M16JT + bool "Micron MT41K128M16JT-125 (2Gbit DDR3L, 128Mbitx16)" + +config DDRTYPE_MT47H128M8HQ + bool "Micron MT47H128M8-3 (1Gbit, DDR-533@CL4 @ 4.80ns 16Mbisx8x8)" + +endchoice + +source "board/mscc/ocelot/Kconfig" + +source "board/mscc/luton/Kconfig" + +endmenu diff --git a/arch/mips/mach-mscc/Makefile b/arch/mips/mach-mscc/Makefile new file mode 100644 index 00000000000..6c60f26ca43 --- /dev/null +++ b/arch/mips/mach-mscc/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +CFLAGS_cpu.o += -finline-limit=64000 + +obj-y += cpu.o dram.o reset.o lowlevel_init.o +obj-$(CONFIG_SOC_LUTON) += lowlevel_init_luton.o diff --git a/arch/mips/mach-mscc/cpu.c b/arch/mips/mach-mscc/cpu.c new file mode 100644 index 00000000000..5be8ff69d5d --- /dev/null +++ b/arch/mips/mach-mscc/cpu.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> + +#include <asm/io.h> +#include <asm/types.h> + +#include <mach/tlb.h> +#include <mach/ddr.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if CONFIG_SYS_SDRAM_SIZE <= SZ_64M +#define MSCC_RAM_TLB_SIZE SZ_64M +#define MSCC_ATTRIB2 MMU_REGIO_INVAL +#elif CONFIG_SYS_SDRAM_SIZE <= SZ_128M +#define MSCC_RAM_TLB_SIZE SZ_64M +#define MSCC_ATTRIB2 MMU_REGIO_RW +#elif CONFIG_SYS_SDRAM_SIZE <= SZ_256M +#define MSCC_RAM_TLB_SIZE SZ_256M +#define MSCC_ATTRIB2 MMU_REGIO_INVAL +#elif CONFIG_SYS_SDRAM_SIZE <= SZ_512M +#define MSCC_RAM_TLB_SIZE SZ_256M +#define MSCC_ATTRIB2 MMU_REGIO_RW +#else +#define MSCC_RAM_TLB_SIZE SZ_512M +#define MSCC_ATTRIB2 MMU_REGIO_RW +#endif + +/* NOTE: lowlevel_init() function does not have access to the + * stack. Thus, all called functions must be inlined, and (any) local + * variables must be kept in registers. + */ +void vcoreiii_tlb_init(void) +{ + register int tlbix = 0; + + /* + * Unlike most of the MIPS based SoCs, the IO register address + * are not in KSEG0. The mainline linux kernel built in legacy + * mode needs to access some of the registers very early in + * the boot and make the assumption that the bootloader has + * already configured them, so we have to match this + * expectation. + */ + create_tlb(tlbix++, MSCC_IO_ORIGIN1_OFFSET, SZ_16M, MMU_REGIO_RW, + MMU_REGIO_RW); +#ifdef CONFIG_SOC_LUTON + create_tlb(tlbix++, MSCC_IO_ORIGIN2_OFFSET, SZ_16M, MMU_REGIO_RW, + MMU_REGIO_RW); +#endif + +#if CONFIG_SYS_TEXT_BASE == MSCC_FLASH_TO + /* + * If U-Boot is located in NOR then we want to be able to use + * the data cache in order to boot in a decent duration + */ + create_tlb(tlbix++, MSCC_FLASH_TO, SZ_16M, MMU_REGIO_RO_C, + MMU_REGIO_RO_C); + create_tlb(tlbix++, MSCC_FLASH_TO + SZ_32M, SZ_16M, MMU_REGIO_RO_C, + MMU_REGIO_RO_C); + + /* + * Using cache for RAM also helps to improve boot time. Thanks + * to this the time to relocate U-Boot in RAM went from 2.092 + * secs to 0.104 secs. + */ + create_tlb(tlbix++, MSCC_DDR_TO, MSCC_RAM_TLB_SIZE, MMU_REGIO_RW, + MSCC_ATTRIB2); + + /* Enable caches by clearing the bit ERL, which is set on reset */ + write_c0_status(read_c0_status() & ~BIT(2)); +#endif /* CONFIG_SYS_TEXT_BASE */ +} + +int mach_cpu_init(void) +{ + /* Speed up NOR flash access */ +#ifdef CONFIG_SOC_LUTON + writel(ICPU_PI_MST_CFG_TRISTATE_CTRL + + ICPU_PI_MST_CFG_CLK_DIV(4), BASE_CFG + ICPU_PI_MST_CFG); + + writel(ICPU_SPI_MST_CFG_FAST_READ_ENA + + ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) + + ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG); +#else + writel(ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) + + ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG); + /* + * Legacy and mainline linux kernel expect that the + * interruption map was set as it was done by redboot. + */ + writel(~0, BASE_CFG + ICPU_DST_INTR_MAP(0)); + writel(0, BASE_CFG + ICPU_DST_INTR_MAP(1)); + writel(0, BASE_CFG + ICPU_DST_INTR_MAP(2)); + writel(0, BASE_CFG + ICPU_DST_INTR_MAP(3)); +#endif + return 0; +} diff --git a/arch/mips/mach-mscc/dram.c b/arch/mips/mach-mscc/dram.c new file mode 100644 index 00000000000..309007c14ef --- /dev/null +++ b/arch/mips/mach-mscc/dram.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> + +#include <asm/io.h> +#include <asm/types.h> + +#include <mach/tlb.h> +#include <mach/ddr.h> + +DECLARE_GLOBAL_DATA_PTR; + +static inline int vcoreiii_train_bytelane(void) +{ + int ret; + + ret = hal_vcoreiii_train_bytelane(0); + +#ifdef CONFIG_SOC_OCELOT + if (ret) + return ret; + ret = hal_vcoreiii_train_bytelane(1); +#endif + + return ret; +} + +int vcoreiii_ddr_init(void) +{ + int res; + + if (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT) + & ICPU_MEMCTRL_STAT_INIT_DONE)) { + hal_vcoreiii_init_memctl(); + hal_vcoreiii_wait_memctl(); + if (hal_vcoreiii_init_dqs() || vcoreiii_train_bytelane()) + hal_vcoreiii_ddr_failed(); + } +#if (CONFIG_SYS_TEXT_BASE != 0x20000000) + res = dram_check(); + if (res == 0) + hal_vcoreiii_ddr_verified(); + else + hal_vcoreiii_ddr_failed(); + + /* Clear boot-mode and read-back to activate/verify */ + clrbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, + ICPU_GENERAL_CTRL_BOOT_MODE_ENA); + readl(BASE_CFG + ICPU_GENERAL_CTRL); +#else + res = 0; +#endif + return res; +} + +int print_cpuinfo(void) +{ + printf("MSCC VCore-III MIPS 24Kec\n"); + + return 0; +} + +int dram_init(void) +{ + while (vcoreiii_ddr_init()) + ; + + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + return 0; +} diff --git a/arch/mips/mach-mscc/include/ioremap.h b/arch/mips/mach-mscc/include/ioremap.h new file mode 100644 index 00000000000..9024364a57f --- /dev/null +++ b/arch/mips/mach-mscc/include/ioremap.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef __ASM_MACH_MSCC_IOREMAP_H +#define __ASM_MACH_MSCC_IOREMAP_H + +#include <linux/types.h> +#include <mach/common.h> + +/* + * Allow physical addresses to be fixed up to help peripherals located + * outside the low 32-bit range -- generic pass-through version. + */ +static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, + phys_addr_t size) +{ + return phys_addr; +} + +static inline int is_vcoreiii_internal_registers(phys_addr_t offset) +{ + if ((offset >= MSCC_IO_ORIGIN1_OFFSET && + offset < (MSCC_IO_ORIGIN1_OFFSET + MSCC_IO_ORIGIN1_SIZE)) || + (offset >= MSCC_IO_ORIGIN2_OFFSET && + offset < (MSCC_IO_ORIGIN2_OFFSET + MSCC_IO_ORIGIN2_SIZE))) + return 1; + + return 0; +} + +static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, + unsigned long flags) +{ + if (is_vcoreiii_internal_registers(offset)) + return (void __iomem *)offset; + + return NULL; +} + +static inline int plat_iounmap(const volatile void __iomem *addr) +{ + return is_vcoreiii_internal_registers((unsigned long)addr); +} + +#define _page_cachable_default _CACHE_CACHABLE_NONCOHERENT + +#endif /* __ASM_MACH_MSCC_IOREMAP_H */ diff --git a/arch/mips/mach-mscc/include/mach/common.h b/arch/mips/mach-mscc/include/mach/common.h new file mode 100644 index 00000000000..931ecd7985e --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/common.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef __ASM_MACH_COMMON_H +#define __ASM_MACH_COMMON_H + +#if defined(CONFIG_SOC_OCELOT) +#include <mach/ocelot/ocelot.h> +#include <mach/ocelot/ocelot_devcpu_gcb.h> +#include <mach/ocelot/ocelot_icpu_cfg.h> +#elif defined(CONFIG_SOC_LUTON) +#include <mach/luton/luton.h> +#include <mach/luton/luton_devcpu_gcb.h> +#include <mach/luton/luton_icpu_cfg.h> +#else +#error Unsupported platform +#endif + +#define MSCC_DDR_TO 0x20000000 /* DDR RAM base offset */ +#define MSCC_MEMCTL1_TO 0x40000000 /* SPI/PI base offset */ +#define MSCC_MEMCTL2_TO 0x50000000 /* SPI/PI base offset */ +#define MSCC_FLASH_TO MSCC_MEMCTL1_TO /* Flash base offset */ + +#define VCOREIII_TIMER_DIVIDER 25 /* Clock tick ~ 0.1 us */ + +#endif /* __ASM_MACH_COMMON_H */ diff --git a/arch/mips/mach-mscc/include/mach/ddr.h b/arch/mips/mach-mscc/include/mach/ddr.h new file mode 100644 index 00000000000..f445e63a35e --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/ddr.h @@ -0,0 +1,814 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef __ASM_MACH_DDR_H +#define __ASM_MACH_DDR_H + +#include <asm/cacheops.h> +#include <asm/io.h> +#include <asm/reboot.h> +#include <mach/common.h> + +#define MIPS_VCOREIII_MEMORY_DDR3 +#define MIPS_VCOREIII_DDR_SIZE CONFIG_SYS_SDRAM_SIZE + +#if defined(CONFIG_DDRTYPE_H5TQ1G63BFA) /* Serval1 Refboard */ + +/* Hynix H5TQ1G63BFA (1Gbit DDR3, x16) @ 3.20ns */ +#define VC3_MPAR_bank_addr_cnt 3 +#define VC3_MPAR_row_addr_cnt 13 +#define VC3_MPAR_col_addr_cnt 10 +#define VC3_MPAR_tREFI 2437 +#define VC3_MPAR_tRAS_min 12 +#define VC3_MPAR_CL 6 +#define VC3_MPAR_tWTR 4 +#define VC3_MPAR_tRC 16 +#define VC3_MPR_tFAW 16 +#define VC3_MPAR_tRP 5 +#define VC3_MPAR_tRRD 4 +#define VC3_MPAR_tRCD 5 +#define VC3_MPAR_tMRD 4 +#define VC3_MPAR_tRFC 35 +#define VC3_MPAR_CWL 5 +#define VC3_MPAR_tXPR 38 +#define VC3_MPAR_tMOD 12 +#define VC3_MPAR_tDLLK 512 +#define VC3_MPAR_tWR 5 + +#elif defined(CONFIG_DDRTYPE_MT41J128M16HA) /* Validation board */ + +/* Micron MT41J128M16HA-15E:D (2Gbit DDR3, x16) @ 3.20ns */ +#define VC3_MPAR_bank_addr_cnt 3 +#define VC3_MPAR_row_addr_cnt 14 +#define VC3_MPAR_col_addr_cnt 10 +#define VC3_MPAR_tREFI 2437 +#define VC3_MPAR_tRAS_min 12 +#define VC3_MPAR_CL 5 +#define VC3_MPAR_tWTR 4 +#define VC3_MPAR_tRC 16 +#define VC3_MPAR_tFAW 16 +#define VC3_MPAR_tRP 5 +#define VC3_MPAR_tRRD 4 +#define VC3_MPAR_tRCD 5 +#define VC3_MPAR_tMRD 4 +#define VC3_MPAR_tRFC 50 +#define VC3_MPAR_CWL 5 +#define VC3_MPAR_tXPR 54 +#define VC3_MPAR_tMOD 12 +#define VC3_MPAR_tDLLK 512 +#define VC3_MPAR_tWR 5 + +#elif defined(CONFIG_DDRTYPE_MT41K256M16) /* JR2 Validation board */ + +/* Micron MT41K256M16 (4Gbit, DDR3L-800, 256Mbitx16) @ 3.20ns */ +#define VC3_MPAR_bank_addr_cnt 3 +#define VC3_MPAR_row_addr_cnt 15 +#define VC3_MPAR_col_addr_cnt 10 +#define VC3_MPAR_tREFI 2437 +#define VC3_MPAR_tRAS_min 12 +#define VC3_MPAR_CL 5 +#define VC3_MPAR_tWTR 4 +#define VC3_MPAR_tRC 16 +#define VC3_MPAR_tFAW 16 +#define VC3_MPAR_tRP 5 +#define VC3_MPAR_tRRD 4 +#define VC3_MPAR_tRCD 5 +#define VC3_MPAR_tMRD 4 +#define VC3_MPAR_tRFC 82 +#define VC3_MPAR_CWL 5 +#define VC3_MPAR_tXPR 85 +#define VC3_MPAR_tMOD 12 +#define VC3_MPAR_tDLLK 512 +#define VC3_MPAR_tWR 5 + +#elif defined(CONFIG_DDRTYPE_H5TQ4G63MFR) /* JR2 Reference board */ + +/* Hynix H5TQ4G63MFR-PBC (4Gbit, DDR3-800, 256Mbitx16) - 2kb pages @ 3.20ns */ +#define VC3_MPAR_bank_addr_cnt 3 +#define VC3_MPAR_row_addr_cnt 15 +#define VC3_MPAR_col_addr_cnt 10 +#define VC3_MPAR_tREFI 2437 +#define VC3_MPAR_tRAS_min 12 +#define VC3_MPAR_CL 6 +#define VC3_MPAR_tWTR 4 +#define VC3_MPAR_tRC 17 +#define VC3_MPAR_tFAW 16 +#define VC3_MPAR_tRP 5 +#define VC3_MPAR_tRRD 4 +#define VC3_MPAR_tRCD 5 +#define VC3_MPAR_tMRD 4 +#define VC3_MPAR_tRFC 82 +#define VC3_MPAR_CWL 5 +#define VC3_MPAR_tXPR 85 +#define VC3_MPAR_tMOD 12 +#define VC3_MPAR_tDLLK 512 +#define VC3_MPAR_tWR 5 + +#elif defined(CONFIG_DDRTYPE_MT41K128M16JT) + +/* Micron Micron MT41K128M16JT-125 (2Gbit DDR3L, 128Mbitx16) @ 3.20ns */ +#define VC3_MPAR_bank_addr_cnt 3 +#define VC3_MPAR_row_addr_cnt 14 +#define VC3_MPAR_col_addr_cnt 10 +#define VC3_MPAR_tREFI 2437 +#define VC3_MPAR_tRAS_min 12 +#define VC3_MPAR_CL 6 +#define VC3_MPAR_tWTR 4 +#define VC3_MPAR_tRC 16 +#define VC3_MPAR_tFAW 16 +#define VC3_MPAR_tRP 5 +#define VC3_MPAR_tRRD 4 +#define VC3_MPAR_tRCD 5 +#define VC3_MPAR_tMRD 4 +#define VC3_MPAR_tRFC 82 +#define VC3_MPAR_CWL 5 +#define VC3_MPAR_tXPR 85 +#define VC3_MPAR_tMOD 12 +#define VC3_MPAR_tDLLK 512 +#define VC3_MPAR_tWR 5 + +#elif defined(CONFIG_DDRTYPE_MT47H128M8HQ) /* Luton10/26 Refboards */ + +/* Micron 1Gb MT47H128M8-3 16Meg x 8 x 8 banks, DDR-533@CL4 @ 4.80ns */ +#define VC3_MPAR_bank_addr_cnt 3 +#define VC3_MPAR_row_addr_cnt 14 +#define VC3_MPAR_col_addr_cnt 10 +#define VC3_MPAR_tREFI 1625 +#define VC3_MPAR_tRAS_min 9 +#define VC3_MPAR_CL 4 +#define VC3_MPAR_tWTR 2 +#define VC3_MPAR_tRC 12 +#define VC3_MPAR_tFAW 8 +#define VC3_MPAR_tRP 4 +#define VC3_MPAR_tRRD 2 +#define VC3_MPAR_tRCD 4 + +#define VC3_MPAR_tRPA 4 +#define VC3_MPAR_tRP 4 + +#define VC3_MPAR_tMRD 2 +#define VC3_MPAR_tRFC 27 + +#define VC3_MPAR__400_ns_dly 84 + +#define VC3_MPAR_tWR 4 +#undef MIPS_VCOREIII_MEMORY_DDR3 +#else + +#error Unknown DDR system configuration - please add! + +#endif + +#ifdef CONFIG_SOC_OCELOT +#define MIPS_VCOREIII_MEMORY_16BIT 1 +#endif + +#define MIPS_VCOREIII_MEMORY_SSTL_ODT 7 +#define MIPS_VCOREIII_MEMORY_SSTL_DRIVE 7 +#define VCOREIII_DDR_DQS_MODE_CALIBRATE + +#ifdef MIPS_VCOREIII_MEMORY_16BIT +#define VC3_MPAR_16BIT 1 +#else +#define VC3_MPAR_16BIT 0 +#endif + +#ifdef MIPS_VCOREIII_MEMORY_DDR3 +#define VC3_MPAR_DDR3_MODE 1 /* DDR3 */ +#define VC3_MPAR_BURST_LENGTH 8 /* Always 8 (1) for DDR3 */ +#ifdef MIPS_VCOREIII_MEMORY_16BIT +#define VC3_MPAR_BURST_SIZE 1 /* Always 1 for DDR3/16bit */ +#else +#define VC3_MPAR_BURST_SIZE 0 +#endif +#else +#define VC3_MPAR_DDR3_MODE 0 /* DDR2 */ +#ifdef MIPS_VCOREIII_MEMORY_16BIT +#define VC3_MPAR_BURST_LENGTH 4 /* in DDR2 16-bit mode, use burstlen 4 */ +#else +#define VC3_MPAR_BURST_LENGTH 8 /* For 8-bit IF we must run burst-8 */ +#endif +#define VC3_MPAR_BURST_SIZE 0 /* Always 0 for DDR2 */ +#endif + +#define VC3_MPAR_RL VC3_MPAR_CL +#if !defined(MIPS_VCOREIII_MEMORY_DDR3) +#define VC3_MPAR_WL (VC3_MPAR_RL - 1) +#define VC3_MPAR_MD VC3_MPAR_tMRD +#define VC3_MPAR_ID VC3_MPAR__400_ns_dly +#define VC3_MPAR_SD VC3_MPAR_tXSRD +#define VC3_MPAR_OW (VC3_MPAR_WL - 2) +#define VC3_MPAR_OR (VC3_MPAR_WL - 3) +#define VC3_MPAR_RP (VC3_MPAR_bank_addr_cnt < 3 ? VC3_MPAR_tRP : VC3_MPAR_tRPA) +#define VC3_MPAR_FAW (VC3_MPAR_bank_addr_cnt < 3 ? 1 : VC3_MPAR_tFAW) +#define VC3_MPAR_BL (VC3_MPAR_BURST_LENGTH == 4 ? 2 : 4) +#define MSCC_MEMPARM_MR0 \ + (VC3_MPAR_BURST_LENGTH == 8 ? 3 : 2) | (VC3_MPAR_CL << 4) | \ + ((VC3_MPAR_tWR - 1) << 9) +/* DLL-on, Full-OD, AL=0, RTT=off, nDQS-on, RDQS-off, out-en */ +#define MSCC_MEMPARM_MR1 0x382 +#define MSCC_MEMPARM_MR2 0 +#define MSCC_MEMPARM_MR3 0 +#else +#define VC3_MPAR_WL VC3_MPAR_CWL +#define VC3_MPAR_MD VC3_MPAR_tMOD +#define VC3_MPAR_ID VC3_MPAR_tXPR +#define VC3_MPAR_SD VC3_MPAR_tDLLK +#define VC3_MPAR_OW 2 +#define VC3_MPAR_OR 2 +#define VC3_MPAR_RP VC3_MPAR_tRP +#define VC3_MPAR_FAW VC3_MPAR_tFAW +#define VC3_MPAR_BL 4 +#define MSCC_MEMPARM_MR0 ((VC3_MPAR_RL - 4) << 4) | ((VC3_MPAR_tWR - 4) << 9) +/* ODT_RTT: “0x0040” for 120ohm, and “0x0004” for 60ohm. */ +#define MSCC_MEMPARM_MR1 0x0040 +#define MSCC_MEMPARM_MR2 ((VC3_MPAR_WL - 5) << 3) +#define MSCC_MEMPARM_MR3 0 +#endif /* MIPS_VCOREIII_MEMORY_DDR3 */ + +#define MSCC_MEMPARM_MEMCFG \ + ((MIPS_VCOREIII_DDR_SIZE > SZ_512M) ? \ + ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS : 0) | \ + (VC3_MPAR_16BIT ? ICPU_MEMCTRL_CFG_DDR_WIDTH : 0) | \ + (VC3_MPAR_DDR3_MODE ? ICPU_MEMCTRL_CFG_DDR_MODE : 0) | \ + (VC3_MPAR_BURST_SIZE ? ICPU_MEMCTRL_CFG_BURST_SIZE : 0) | \ + (VC3_MPAR_BURST_LENGTH == 8 ? ICPU_MEMCTRL_CFG_BURST_LEN : 0) | \ + (VC3_MPAR_bank_addr_cnt == 3 ? ICPU_MEMCTRL_CFG_BANK_CNT : 0) | \ + ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(VC3_MPAR_row_addr_cnt - 1) | \ + ICPU_MEMCTRL_CFG_MSB_COL_ADDR(VC3_MPAR_col_addr_cnt - 1) + +#ifdef CONFIG_SOC_OCELOT +#define MSCC_MEMPARM_PERIOD \ + ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(8) | \ + ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(VC3_MPAR_tREFI) + +#define MSCC_MEMPARM_TIMING0 \ + ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(VC3_MPAR_RL + VC3_MPAR_BL + 1 - \ + VC3_MPAR_WL) | \ + ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(VC3_MPAR_BL - 1) | \ + ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(VC3_MPAR_BL) | \ + ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(VC3_MPAR_tRAS_min - 1) | \ + ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(VC3_MPAR_WL + \ + VC3_MPAR_BL + \ + VC3_MPAR_tWR - 1) | \ + ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(VC3_MPAR_BL - 1) | \ + ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(VC3_MPAR_WL - 1) | \ + ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(VC3_MPAR_RL - 3) + +#define MSCC_MEMPARM_TIMING1 \ + ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(VC3_MPAR_tRC - 1) | \ + ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(VC3_MPAR_FAW - 1) | \ + ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(VC3_MPAR_RP - 1) | \ + ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(VC3_MPAR_tRRD - 1) | \ + ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(VC3_MPAR_tRCD - 1) | \ + ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(VC3_MPAR_WL + \ + VC3_MPAR_BL + \ + VC3_MPAR_tWTR - 1) + +#define MSCC_MEMPARM_TIMING2 \ + ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(VC3_MPAR_RP - 1) | \ + ICPU_MEMCTRL_TIMING2_MDSET_DLY(VC3_MPAR_MD - 1) | \ + ICPU_MEMCTRL_TIMING2_REF_DLY(VC3_MPAR_tRFC - 1) | \ + ICPU_MEMCTRL_TIMING2_INIT_DLY(VC3_MPAR_ID - 1) + +#define MSCC_MEMPARM_TIMING3 \ + ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(VC3_MPAR_WL + \ + VC3_MPAR_tWTR - 1) |\ + ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(VC3_MPAR_OR - 1) | \ + ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(VC3_MPAR_OW - 1) | \ + ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(VC3_MPAR_RL - 3) + +#else +#define MSCC_MEMPARM_PERIOD \ + ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(1) | \ + ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(VC3_MPAR_tREFI) + +#define MSCC_MEMPARM_TIMING0 \ + ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(VC3_MPAR_tRAS_min - 1) | \ + ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(VC3_MPAR_CL + \ + (VC3_MPAR_BURST_LENGTH == 8 ? 2 : 0) + \ + VC3_MPAR_tWR) | \ + ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(VC3_MPAR_BURST_LENGTH == 8 ? 3 : 1) | \ + ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(VC3_MPAR_CL - 3) | \ + ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(VC3_MPAR_CL - 3) + +#define MSCC_MEMPARM_TIMING1 \ + ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(VC3_MPAR_tRC - 1) | \ + ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(VC3_MPAR_tFAW - 1) | \ + ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(VC3_MPAR_tRP - 1) | \ + ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(VC3_MPAR_tRRD - 1) | \ + ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(VC3_MPAR_tRCD - 1) | \ + ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(VC3_MPAR_CL + \ + (VC3_MPAR_BURST_LENGTH == 8 ? 2 : 0) + \ + VC3_MPAR_tWTR) +#define MSCC_MEMPARM_TIMING2 \ + ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(VC3_MPAR_tRPA - 1) | \ + ICPU_MEMCTRL_TIMING2_MDSET_DLY(VC3_MPAR_tMRD - 1) | \ + ICPU_MEMCTRL_TIMING2_REF_DLY(VC3_MPAR_tRFC - 1) | \ + ICPU_MEMCTRL_TIMING2_FOUR_HUNDRED_NS_DLY(VC3_MPAR__400_ns_dly) + +#define MSCC_MEMPARM_TIMING3 \ + ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(VC3_MPAR_CL - 1) | \ + ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(VC3_MPAR_CL - 1) | \ + ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(VC3_MPAR_CL - 1) + +#endif + +enum { + DDR_TRAIN_OK, + DDR_TRAIN_CONTINUE, + DDR_TRAIN_ERROR, +}; + +/* + * We actually have very few 'pause' possibilities apart from + * these assembly nops (at this very early stage). + */ +#define PAUSE() asm volatile("nop; nop; nop; nop; nop; nop; nop; nop") + +/* NB: Assumes inlining as no stack is available! */ +static inline void set_dly(u32 bytelane, u32 dly) +{ + register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)); + + r &= ~ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M; + r |= ICPU_MEMCTRL_DQS_DLY_DQS_DLY(dly); + writel(r, BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)); +} + +static inline bool incr_dly(u32 bytelane) +{ + register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)); + + if (ICPU_MEMCTRL_DQS_DLY_DQS_DLY(r) < 31) { + writel(r + 1, BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)); + return true; + } + + return false; +} + +static inline bool adjust_dly(int adjust) +{ + register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(0)); + + if (ICPU_MEMCTRL_DQS_DLY_DQS_DLY(r) < 31) { + writel(r + adjust, BASE_CFG + ICPU_MEMCTRL_DQS_DLY(0)); + return true; + } + + return false; +} + +/* NB: Assumes inlining as no stack is available! */ +static inline void center_dly(u32 bytelane, u32 start) +{ + register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)) - start; + + writel(start + (r >> 1), BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)); +} + +static inline void memphy_soft_reset(void) +{ + setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_FIFO_RST); + PAUSE(); + clrbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_FIFO_RST); + PAUSE(); +} + +#ifdef CONFIG_SOC_OCELOT +static u8 training_data[] = { 0xfe, 0x11, 0x33, 0x55, 0x77, 0x99, 0xbb, 0xdd }; + +static inline void sleep_100ns(u32 val) +{ + /* Set the timer tick generator to 100 ns */ + writel(VCOREIII_TIMER_DIVIDER - 1, BASE_CFG + ICPU_TIMER_TICK_DIV); + + /* Set the timer value */ + writel(val, BASE_CFG + ICPU_TIMER_VALUE(0)); + + /* Enable timer 0 for one-shot */ + writel(ICPU_TIMER_CTRL_ONE_SHOT_ENA | ICPU_TIMER_CTRL_TIMER_ENA, + BASE_CFG + ICPU_TIMER_CTRL(0)); + + /* Wait for timer 0 to reach 0 */ + while (readl(BASE_CFG + ICPU_TIMER_VALUE(0)) != 0) + ; +} + +static inline void hal_vcoreiii_ddr_reset_assert(void) +{ + /* DDR has reset pin on GPIO 19 toggle Low-High to release */ + setbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19)); + writel(BIT(19), BASE_DEVCPU_GCB + PERF_GPIO_OUT_CLR); + sleep_100ns(10000); +} + +static inline void hal_vcoreiii_ddr_reset_release(void) +{ + /* DDR has reset pin on GPIO 19 toggle Low-High to release */ + setbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19)); + writel(BIT(19), BASE_DEVCPU_GCB + PERF_GPIO_OUT_SET); + sleep_100ns(10000); +} + +/* + * DDR memory sanity checking failed, tally and do hard reset + * + * NB: Assumes inlining as no stack is available! + */ +static inline void hal_vcoreiii_ddr_failed(void) +{ + register u32 reset; + + writel(readl(BASE_CFG + ICPU_GPR(6)) + 1, BASE_CFG + ICPU_GPR(6)); + + clrbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19)); + + /* We have to execute the reset function from cache. Indeed, + * the reboot workaround in _machine_restart() will change the + * SPI NOR into SW bitbang. + * + * This will render the CPU unable to execute directly from + * the NOR, which is why the reset instructions are prefetched + * into the I-cache. + * + * When failing the DDR initialization we are executing from + * NOR. + * + * The last instruction in _machine_restart() will reset the + * MIPS CPU (and the cache), and the CPU will start executing + * from the reset vector. + */ + reset = KSEG0ADDR(_machine_restart); + icache_lock((void *)reset, 128); + asm volatile ("jr %0"::"r" (reset)); + + panic("DDR init failed\n"); +} + +/* + * DDR memory sanity checking done, possibly enable ECC. + * + * NB: Assumes inlining as no stack is available! + */ +static inline void hal_vcoreiii_ddr_verified(void) +{ +#ifdef MIPS_VCOREIII_MEMORY_ECC + /* Finally, enable ECC */ + register u32 val = readl(BASE_CFG + ICPU_MEMCTRL_CFG); + + val |= ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA; + val &= ~ICPU_MEMCTRL_CFG_BURST_SIZE; + + writel(val, BASE_CFG + ICPU_MEMCTRL_CFG); +#endif + + /* Reset Status register - sticky bits */ + writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT), BASE_CFG + ICPU_MEMCTRL_STAT); +} + +/* NB: Assumes inlining as no stack is available! */ +static inline int look_for(u32 bytelane) +{ + register u32 i; + + /* Reset FIFO in case any previous access failed */ + for (i = 0; i < sizeof(training_data); i++) { + register u32 byte; + + memphy_soft_reset(); + /* Reset sticky bits */ + writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT), + BASE_CFG + ICPU_MEMCTRL_STAT); + /* Read data */ + byte = __raw_readb((void __iomem *)MSCC_DDR_TO + bytelane + + (i * 4)); + + /* + * Prevent the compiler reordering the instruction so + * the read of RAM happens after the check of the + * errors. + */ + rmb(); + if (readl(BASE_CFG + ICPU_MEMCTRL_STAT) & + (ICPU_MEMCTRL_STAT_RDATA_MASKED | + ICPU_MEMCTRL_STAT_RDATA_DUMMY)) { + /* Noise on the line */ + goto read_error; + } + /* If mismatch, increment DQS - if possible */ + if (byte != training_data[i]) { + read_error: + if (!incr_dly(bytelane)) + return DDR_TRAIN_ERROR; + return DDR_TRAIN_CONTINUE; + } + } + return DDR_TRAIN_OK; +} + +/* NB: Assumes inlining as no stack is available! */ +static inline int look_past(u32 bytelane) +{ + register u32 i; + + /* Reset FIFO in case any previous access failed */ + for (i = 0; i < sizeof(training_data); i++) { + register u32 byte; + + memphy_soft_reset(); + /* Ack sticky bits */ + writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT), + BASE_CFG + ICPU_MEMCTRL_STAT); + byte = __raw_readb((void __iomem *)MSCC_DDR_TO + bytelane + + (i * 4)); + /* + * Prevent the compiler reordering the instruction so + * the read of RAM happens after the check of the + * errors. + */ + rmb(); + if (readl(BASE_CFG + ICPU_MEMCTRL_STAT) & + (ICPU_MEMCTRL_STAT_RDATA_MASKED | + ICPU_MEMCTRL_STAT_RDATA_DUMMY)) { + /* Noise on the line */ + goto read_error; + } + /* Bail out when we see first mismatch */ + if (byte != training_data[i]) { + read_error: + return DDR_TRAIN_OK; + } + } + /* All data compares OK, increase DQS and retry */ + if (!incr_dly(bytelane)) + return DDR_TRAIN_ERROR; + + return DDR_TRAIN_CONTINUE; +} + +static inline int hal_vcoreiii_train_bytelane(u32 bytelane) +{ + register int res; + register u32 dqs_s; + + set_dly(bytelane, 0); /* Start training at DQS=0 */ + while ((res = look_for(bytelane)) == DDR_TRAIN_CONTINUE) + ; + if (res != DDR_TRAIN_OK) + return res; + + dqs_s = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)); + while ((res = look_past(bytelane)) == DDR_TRAIN_CONTINUE) + ; + if (res != DDR_TRAIN_OK) + return res; + /* Reset FIFO - for good measure */ + memphy_soft_reset(); + /* Adjust to center [dqs_s;cur] */ + center_dly(bytelane, dqs_s); + return DDR_TRAIN_OK; +} + +/* This algorithm is converted from the TCL training algorithm used + * during silicon simulation. + * NB: Assumes inlining as no stack is available! + */ +static inline int hal_vcoreiii_init_dqs(void) +{ +#define MAX_DQS 32 + register u32 i, j; + + for (i = 0; i < MAX_DQS; i++) { + set_dly(0, i); /* Byte-lane 0 */ + for (j = 0; j < MAX_DQS; j++) { + __maybe_unused register u32 byte; + + set_dly(1, j); /* Byte-lane 1 */ + /* Reset FIFO in case any previous access failed */ + memphy_soft_reset(); + writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT), + BASE_CFG + ICPU_MEMCTRL_STAT); + byte = __raw_readb((void __iomem *)MSCC_DDR_TO); + byte = __raw_readb((void __iomem *)(MSCC_DDR_TO + 1)); + if (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT) & + (ICPU_MEMCTRL_STAT_RDATA_MASKED | + ICPU_MEMCTRL_STAT_RDATA_DUMMY))) + return 0; + } + } + return -1; +} + +static inline int dram_check(void) +{ + register u32 i; + + for (i = 0; i < 8; i++) { + __raw_writel(~i, (void __iomem *)(MSCC_DDR_TO + (i * 4))); + if (__raw_readl((void __iomem *)(MSCC_DDR_TO + (i * 4))) != ~i) + return 1; + } + return 0; +} +#else /* Luton */ + +static inline void sleep_100ns(u32 val) +{ +} + +static inline void hal_vcoreiii_ddr_reset_assert(void) +{ + setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_RST); + setbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_MEM_RST_FORCE); +} + +static inline void hal_vcoreiii_ddr_reset_release(void) +{ +} + +static inline void hal_vcoreiii_ddr_failed(void) +{ + register u32 memphy_cfg = readl(BASE_CFG + ICPU_MEMPHY_CFG); + + /* Do a fifo reset and start over */ + writel(memphy_cfg | ICPU_MEMPHY_CFG_PHY_FIFO_RST, + BASE_CFG + ICPU_MEMPHY_CFG); + writel(memphy_cfg & ~ICPU_MEMPHY_CFG_PHY_FIFO_RST, + BASE_CFG + ICPU_MEMPHY_CFG); + writel(memphy_cfg | ICPU_MEMPHY_CFG_PHY_FIFO_RST, + BASE_CFG + ICPU_MEMPHY_CFG); +} + +static inline void hal_vcoreiii_ddr_verified(void) +{ +} + +static inline int look_for(u32 data) +{ + register u32 byte = __raw_readb((void __iomem *)MSCC_DDR_TO); + + if (data != byte) { + if (!incr_dly(0)) + return DDR_TRAIN_ERROR; + return DDR_TRAIN_CONTINUE; + } + + return DDR_TRAIN_OK; +} + +/* This algorithm is converted from the TCL training algorithm used + * during silicon simulation. + * NB: Assumes inlining as no stack is available! + */ +static inline int hal_vcoreiii_train_bytelane(u32 bytelane) +{ + register int res; + + set_dly(bytelane, 0); /* Start training at DQS=0 */ + while ((res = look_for(0xff)) == DDR_TRAIN_CONTINUE) + ; + if (res != DDR_TRAIN_OK) + return res; + + set_dly(bytelane, 0); /* Start training at DQS=0 */ + while ((res = look_for(0x00)) == DDR_TRAIN_CONTINUE) + + ; + + if (res != DDR_TRAIN_OK) + return res; + + adjust_dly(-3); + + return DDR_TRAIN_OK; +} + +static inline int hal_vcoreiii_init_dqs(void) +{ + return 0; +} + +static inline int dram_check(void) +{ + register u32 i; + + for (i = 0; i < 8; i++) { + __raw_writel(~i, (void __iomem *)(MSCC_DDR_TO + (i * 4))); + + if (__raw_readl((void __iomem *)(MSCC_DDR_TO + (i * 4))) != ~i) + return 1; + } + + return 0; +} +#endif + +/* + * NB: Called *early* to init memory controller - assumes inlining as + * no stack is available! + */ +static inline void hal_vcoreiii_init_memctl(void) +{ + /* Ensure DDR is in reset */ + hal_vcoreiii_ddr_reset_assert(); + + /* Wait maybe not needed, but ... */ + PAUSE(); + + /* Drop sys ctl memory controller forced reset */ + clrbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_MEM_RST_FORCE); + + PAUSE(); + + /* Drop Reset, enable SSTL */ + writel(ICPU_MEMPHY_CFG_PHY_SSTL_ENA, BASE_CFG + ICPU_MEMPHY_CFG); + PAUSE(); + + /* Start the automatic SSTL output and ODT drive-strength calibration */ + writel(ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(MIPS_VCOREIII_MEMORY_SSTL_ODT) | + /* drive strength */ + ICPU_MEMPHY_ZCAL_ZCAL_PROG(MIPS_VCOREIII_MEMORY_SSTL_DRIVE) | + /* Start calibration process */ + ICPU_MEMPHY_ZCAL_ZCAL_ENA, BASE_CFG + ICPU_MEMPHY_ZCAL); + + /* Wait for ZCAL to clear */ + while (readl(BASE_CFG + ICPU_MEMPHY_ZCAL) & ICPU_MEMPHY_ZCAL_ZCAL_ENA) + ; +#ifdef CONFIG_SOC_OCELOT + /* Check no ZCAL_ERR */ + if (readl(BASE_CFG + ICPU_MEMPHY_ZCAL_STAT) + & ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR) + hal_vcoreiii_ddr_failed(); +#endif + /* Drive CL, CK, ODT */ + setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_ODT_OE | + ICPU_MEMPHY_CFG_PHY_CK_OE | ICPU_MEMPHY_CFG_PHY_CL_OE); + + /* Initialize memory controller */ + writel(MSCC_MEMPARM_MEMCFG, BASE_CFG + ICPU_MEMCTRL_CFG); + writel(MSCC_MEMPARM_PERIOD, BASE_CFG + ICPU_MEMCTRL_REF_PERIOD); + +#ifdef CONFIG_SOC_OCELOT + writel(MSCC_MEMPARM_TIMING0, BASE_CFG + ICPU_MEMCTRL_TIMING0); +#else /* Luton */ + clrbits_le32(BASE_CFG + ICPU_MEMCTRL_TIMING0, ((1 << 20) - 1)); + setbits_le32(BASE_CFG + ICPU_MEMCTRL_TIMING0, MSCC_MEMPARM_TIMING0); +#endif + + writel(MSCC_MEMPARM_TIMING1, BASE_CFG + ICPU_MEMCTRL_TIMING1); + writel(MSCC_MEMPARM_TIMING2, BASE_CFG + ICPU_MEMCTRL_TIMING2); + writel(MSCC_MEMPARM_TIMING3, BASE_CFG + ICPU_MEMCTRL_TIMING3); + writel(MSCC_MEMPARM_MR0, BASE_CFG + ICPU_MEMCTRL_MR0_VAL); + writel(MSCC_MEMPARM_MR1, BASE_CFG + ICPU_MEMCTRL_MR1_VAL); + writel(MSCC_MEMPARM_MR2, BASE_CFG + ICPU_MEMCTRL_MR2_VAL); + writel(MSCC_MEMPARM_MR3, BASE_CFG + ICPU_MEMCTRL_MR3_VAL); + +#ifdef CONFIG_SOC_OCELOT + /* Termination setup - enable ODT */ + writel(ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA | + /* Assert ODT0 for any write */ + ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(3), + BASE_CFG + ICPU_MEMCTRL_TERMRES_CTRL); + + /* Release Reset from DDR */ + hal_vcoreiii_ddr_reset_release(); + + writel(readl(BASE_CFG + ICPU_GPR(7)) + 1, BASE_CFG + ICPU_GPR(7)); +#else /* Luton */ + /* Termination setup - disable ODT */ + writel(0, BASE_CFG + ICPU_MEMCTRL_TERMRES_CTRL); + +#endif +} + +static inline void hal_vcoreiii_wait_memctl(void) +{ + /* Now, rip it! */ + writel(ICPU_MEMCTRL_CTRL_INITIALIZE, BASE_CFG + ICPU_MEMCTRL_CTRL); + + while (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT) + & ICPU_MEMCTRL_STAT_INIT_DONE)) + ; + + /* Settle...? */ + sleep_100ns(10000); +#ifdef CONFIG_SOC_OCELOT + /* Establish data contents in DDR RAM for training */ + + __raw_writel(0xcacafefe, ((void __iomem *)MSCC_DDR_TO)); + __raw_writel(0x22221111, ((void __iomem *)MSCC_DDR_TO + 0x4)); + __raw_writel(0x44443333, ((void __iomem *)MSCC_DDR_TO + 0x8)); + __raw_writel(0x66665555, ((void __iomem *)MSCC_DDR_TO + 0xC)); + __raw_writel(0x88887777, ((void __iomem *)MSCC_DDR_TO + 0x10)); + __raw_writel(0xaaaa9999, ((void __iomem *)MSCC_DDR_TO + 0x14)); + __raw_writel(0xccccbbbb, ((void __iomem *)MSCC_DDR_TO + 0x18)); + __raw_writel(0xeeeedddd, ((void __iomem *)MSCC_DDR_TO + 0x1C)); +#else + __raw_writel(0xff, ((void __iomem *)MSCC_DDR_TO)); +#endif +} +#endif /* __ASM_MACH_DDR_H */ diff --git a/arch/mips/mach-mscc/include/mach/luton/luton.h b/arch/mips/mach-mscc/include/mach/luton/luton.h new file mode 100644 index 00000000000..19f02ede666 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/luton/luton.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Microsemi Ocelot Switch driver + * + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_H_ +#define _MSCC_OCELOT_H_ + +#include <linux/bitops.h> +#include <dm.h> + +/* + * Target offset base(s) + */ +#define MSCC_IO_ORIGIN1_OFFSET 0x60000000 +#define MSCC_IO_ORIGIN1_SIZE 0x01000000 +#define MSCC_IO_ORIGIN2_OFFSET 0x70000000 +#define MSCC_IO_ORIGIN2_SIZE 0x00200000 +#define BASE_CFG ((void __iomem *)0x70000000) +#define BASE_DEVCPU_GCB ((void __iomem *)0x60070000) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h b/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h new file mode 100644 index 00000000000..8c0b612325e --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_DEVCPU_GCB_H_ +#define _MSCC_OCELOT_DEVCPU_GCB_H_ + +#define PERF_SOFT_RST 0x90 + +#define PERF_SOFT_RST_SOFT_SWC_RST BIT(1) +#define PERF_SOFT_RST_SOFT_CHIP_RST BIT(0) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h b/arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h new file mode 100644 index 00000000000..9233f037bb8 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h @@ -0,0 +1,245 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_ICPU_CFG_H_ +#define _MSCC_OCELOT_ICPU_CFG_H_ + +#define ICPU_GPR(x) (0x4 * (x)) +#define ICPU_GPR_RSZ 0x4 + +#define ICPU_RESET 0x20 + +#define ICPU_RESET_CORE_RST_CPU_ONLY BIT(3) +#define ICPU_RESET_CORE_RST_PROTECT BIT(2) +#define ICPU_RESET_CORE_RST_FORCE BIT(1) +#define ICPU_RESET_MEM_RST_FORCE BIT(0) + +#define ICPU_GENERAL_CTRL 0x24 + +#define ICPU_GENERAL_CTRL_SWC_CLEAR_IF BIT(6) +#define ICPU_GENERAL_CTRL_CPU_BUSIF_SLEEP_DIS BIT(5) +#define ICPU_GENERAL_CTRL_CPU_BUSIF_WERR_ENA BIT(4) +#define ICPU_GENERAL_CTRL_IF_MASTER_DIS BIT(3) +#define ICPU_GENERAL_CTRL_IF_MASTER_SPI_ENA BIT(2) +#define ICPU_GENERAL_CTRL_IF_MASTER_PI_ENA BIT(1) + +#define ICPU_GENERAL_CTRL_BOOT_MODE_ENA BIT(0) + +#define ICPU_PI_MST_CFG 0x2c + +#define ICPU_PI_MST_CFG_ATE_MODE_DIS BIT(7) +#define ICPU_PI_MST_CFG_CLK_POL BIT(6) +#define ICPU_PI_MST_CFG_TRISTATE_CTRL BIT(5) +#define ICPU_PI_MST_CFG_CLK_DIV(x) ((x) & GENMASK(4, 0)) +#define ICPU_PI_MST_CFG_CLK_DIV_M GENMASK(4, 0) + +#define ICPU_SPI_MST_CFG 0x50 + +#define ICPU_SPI_MST_CFG_FAST_READ_ENA BIT(10) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME(x) (((x) << 5) & GENMASK(9, 5)) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_M GENMASK(9, 5) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_X(x) (((x) & GENMASK(9, 5)) >> 5) +#define ICPU_SPI_MST_CFG_CLK_DIV(x) ((x) & GENMASK(4, 0)) +#define ICPU_SPI_MST_CFG_CLK_DIV_M GENMASK(4, 0) + +#define ICPU_SW_MODE 0x64 + +#define ICPU_SW_MODE_SW_PIN_CTRL_MODE BIT(13) +#define ICPU_SW_MODE_SW_SPI_SCK BIT(12) +#define ICPU_SW_MODE_SW_SPI_SCK_OE BIT(11) +#define ICPU_SW_MODE_SW_SPI_SDO BIT(10) +#define ICPU_SW_MODE_SW_SPI_SDO_OE BIT(9) +#define ICPU_SW_MODE_SW_SPI_CS(x) (((x) << 5) & GENMASK(8, 5)) +#define ICPU_SW_MODE_SW_SPI_CS_M GENMASK(8, 5) +#define ICPU_SW_MODE_SW_SPI_CS_X(x) (((x) & GENMASK(8, 5)) >> 5) +#define ICPU_SW_MODE_SW_SPI_CS_OE(x) (((x) << 1) & GENMASK(4, 1)) +#define ICPU_SW_MODE_SW_SPI_CS_OE_M GENMASK(4, 1) +#define ICPU_SW_MODE_SW_SPI_CS_OE_X(x) (((x) & GENMASK(4, 1)) >> 1) +#define ICPU_SW_MODE_SW_SPI_SDI BIT(0) + +#define ICPU_INTR_ENA 0x88 + +#define ICPU_INTR_IRQ0_ENA 0x98 +#define ICPU_INTR_IRQ0_ENA_IRQ0_ENA BIT(0) + +#define ICPU_MEMCTRL_CTRL 0x234 + +#define ICPU_MEMCTRL_CTRL_PWR_DOWN BIT(3) +#define ICPU_MEMCTRL_CTRL_MDSET BIT(2) +#define ICPU_MEMCTRL_CTRL_STALL_REF_ENA BIT(1) +#define ICPU_MEMCTRL_CTRL_INITIALIZE BIT(0) + +#define ICPU_MEMCTRL_CFG 0x238 + +#define ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS BIT(16) +#define ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA BIT(15) +#define ICPU_MEMCTRL_CFG_DDR_ECC_COR_ENA BIT(14) +#define ICPU_MEMCTRL_CFG_DDR_ECC_ENA BIT(13) +#define ICPU_MEMCTRL_CFG_DDR_WIDTH BIT(12) +#define ICPU_MEMCTRL_CFG_DDR_MODE BIT(11) +#define ICPU_MEMCTRL_CFG_BURST_SIZE BIT(10) +#define ICPU_MEMCTRL_CFG_BURST_LEN BIT(9) +#define ICPU_MEMCTRL_CFG_BANK_CNT BIT(8) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_M GENMASK(7, 4) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_STAT 0x23C + +#define ICPU_MEMCTRL_STAT_RDATA_MASKED BIT(5) +#define ICPU_MEMCTRL_STAT_RDATA_DUMMY BIT(4) +#define ICPU_MEMCTRL_STAT_RDATA_ECC_ERR BIT(3) +#define ICPU_MEMCTRL_STAT_RDATA_ECC_COR BIT(2) +#define ICPU_MEMCTRL_STAT_PWR_DOWN_ACK BIT(1) +#define ICPU_MEMCTRL_STAT_INIT_DONE BIT(0) + +#define ICPU_MEMCTRL_REF_PERIOD 0x240 + +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_M GENMASK(19, 16) +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(x) ((x) & GENMASK(15, 0)) +#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD_M GENMASK(15, 0) + +#define ICPU_MEMCTRL_TIMING0 0x248 + +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(x) (((x) << 28) & GENMASK(31, 28)) +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_M GENMASK(31, 28) +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_X(x) (((x) & GENMASK(31, 28)) >> 28) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(x) (((x) << 24) & GENMASK(27, 24)) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_M GENMASK(27, 24) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_X(x) (((x) & GENMASK(27, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(x) (((x) << 20) & GENMASK(23, 20)) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_M GENMASK(23, 20) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_X(x) (((x) & GENMASK(23, 20)) >> 20) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_M GENMASK(19, 16) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_TIMING1 0x24c + +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(x) (((x) << 24) & GENMASK(31, 24)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_M GENMASK(31, 24) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_X(x) (((x) & GENMASK(31, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(x) (((x) << 16) & GENMASK(23, 16)) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_M GENMASK(23, 16) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_X(x) (((x) & GENMASK(23, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_TIMING2 0x250 + +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(x) (((x) << 28) & GENMASK(31, 28)) +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_M GENMASK(31, 28) +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_X(x) (((x) & GENMASK(31, 28)) >> 28) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY(x) (((x) << 24) & GENMASK(27, 24)) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_M GENMASK(27, 24) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_X(x) (((x) & GENMASK(27, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING2_REF_DLY(x) (((x) << 16) & GENMASK(23, 16)) +#define ICPU_MEMCTRL_TIMING2_REF_DLY_M GENMASK(23, 16) +#define ICPU_MEMCTRL_TIMING2_REF_DLY_X(x) (((x) & GENMASK(23, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING2_FOUR_HUNDRED_NS_DLY(x) ((x) & GENMASK(15, 0)) +#define ICPU_MEMCTRL_TIMING2_FOUR_HUNDRED_NS_DLY_M GENMASK(15, 0) + +#define ICPU_MEMCTRL_TIMING3 0x254 + +#define ICPU_MEMCTRL_TIMING3_RMW_DLY(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_TIMING3_RMW_DLY_M GENMASK(19, 16) +#define ICPU_MEMCTRL_TIMING3_RMW_DLY_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_MR0_VAL 0x258 + +#define ICPU_MEMCTRL_MR1_VAL 0x25c + +#define ICPU_MEMCTRL_MR2_VAL 0x260 + +#define ICPU_MEMCTRL_MR3_VAL 0x264 + +#define ICPU_MEMCTRL_TERMRES_CTRL 0x268 + +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_EXT BIT(11) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA(x) (((x) << 7) & GENMASK(10, 7)) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_M GENMASK(10, 7) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_X(x) (((x) & GENMASK(10, 7)) >> 7) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_EXT BIT(6) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(x) (((x) << 2) & GENMASK(5, 2)) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_M GENMASK(5, 2) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_X(x) (((x) & GENMASK(5, 2)) >> 2) +#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_EXT BIT(1) +#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA BIT(0) + +#define ICPU_MEMCTRL_DQS_DLY(x) (0x270) + +#define ICPU_MEMCTRL_DQS_DLY_TRAIN_DQ_ENA BIT(11) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1(x) (((x) << 8) & GENMASK(10, 8)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_M GENMASK(10, 8) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_X(x) (((x) & GENMASK(10, 8)) >> 8) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0(x) (((x) << 5) & GENMASK(7, 5)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_M GENMASK(7, 5) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_X(x) (((x) & GENMASK(7, 5)) >> 5) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY(x) ((x) & GENMASK(4, 0)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M GENMASK(4, 0) + +#define ICPU_MEMPHY_CFG 0x278 + +#define ICPU_MEMPHY_CFG_PHY_FLUSH_DIS BIT(10) +#define ICPU_MEMPHY_CFG_PHY_RD_ADJ_DIS BIT(9) +#define ICPU_MEMPHY_CFG_PHY_DQS_EXT BIT(8) +#define ICPU_MEMPHY_CFG_PHY_FIFO_RST BIT(7) +#define ICPU_MEMPHY_CFG_PHY_DLL_BL_RST BIT(6) +#define ICPU_MEMPHY_CFG_PHY_DLL_CL_RST BIT(5) +#define ICPU_MEMPHY_CFG_PHY_ODT_OE BIT(4) +#define ICPU_MEMPHY_CFG_PHY_CK_OE BIT(3) +#define ICPU_MEMPHY_CFG_PHY_CL_OE BIT(2) +#define ICPU_MEMPHY_CFG_PHY_SSTL_ENA BIT(1) +#define ICPU_MEMPHY_CFG_PHY_RST BIT(0) +#define ICPU_MEMPHY_DQ_DLY_TRM 0x180 +#define ICPU_MEMPHY_DQ_DLY_TRM_RSZ 0x4 + +#define ICPU_MEMPHY_ZCAL 0x294 + +#define ICPU_MEMPHY_ZCAL_ZCAL_CLK_SEL BIT(9) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(x) (((x) << 5) & GENMASK(8, 5)) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_M GENMASK(8, 5) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_X(x) (((x) & GENMASK(8, 5)) >> 5) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG(x) (((x) << 1) & GENMASK(4, 1)) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_M GENMASK(4, 1) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_X(x) (((x) & GENMASK(4, 1)) >> 1) +#define ICPU_MEMPHY_ZCAL_ZCAL_ENA BIT(0) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/ocelot/ocelot.h b/arch/mips/mach-mscc/include/mach/ocelot/ocelot.h new file mode 100644 index 00000000000..2cb2135d374 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/ocelot/ocelot.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Microsemi Ocelot Switch driver + * + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_H_ +#define _MSCC_OCELOT_H_ + +#include <linux/bitops.h> +#include <dm.h> + +/* + * Target offset base(s) + */ +#define MSCC_IO_ORIGIN1_OFFSET 0x70000000 +#define MSCC_IO_ORIGIN1_SIZE 0x00200000 +#define MSCC_IO_ORIGIN2_OFFSET 0x71000000 +#define MSCC_IO_ORIGIN2_SIZE 0x01000000 +#define BASE_CFG ((void __iomem *)0x70000000) +#define BASE_DEVCPU_GCB ((void __iomem *)0x71070000) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h new file mode 100644 index 00000000000..f8aa97ba267 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_DEVCPU_GCB_H_ +#define _MSCC_OCELOT_DEVCPU_GCB_H_ + +#define PERF_SOFT_RST 0x8 + +#define PERF_SOFT_RST_SOFT_NON_CFG_RST BIT(2) +#define PERF_SOFT_RST_SOFT_SWC_RST BIT(1) +#define PERF_SOFT_RST_SOFT_CHIP_RST BIT(0) + +#define PERF_GPIO_OUT_SET 0x34 + +#define PERF_GPIO_OUT_CLR 0x38 + +#define PERF_GPIO_OE 0x44 + +#endif diff --git a/arch/mips/mach-mscc/include/mach/ocelot/ocelot_icpu_cfg.h b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_icpu_cfg.h new file mode 100644 index 00000000000..04cf70bec34 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_icpu_cfg.h @@ -0,0 +1,274 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_ICPU_CFG_H_ +#define _MSCC_OCELOT_ICPU_CFG_H_ + +#define ICPU_GPR(x) (0x4 * (x)) +#define ICPU_GPR_RSZ 0x4 + +#define ICPU_RESET 0x20 + +#define ICPU_RESET_CORE_RST_CPU_ONLY BIT(3) +#define ICPU_RESET_CORE_RST_PROTECT BIT(2) +#define ICPU_RESET_CORE_RST_FORCE BIT(1) +#define ICPU_RESET_MEM_RST_FORCE BIT(0) + +#define ICPU_GENERAL_CTRL 0x24 + +#define ICPU_GENERAL_CTRL_CPU_BUSIF_SLEEP_DIS BIT(14) +#define ICPU_GENERAL_CTRL_CPU_BUSIF_WERR_ENA BIT(13) +#define ICPU_GENERAL_CTRL_CPU_8051_IROM_ENA BIT(12) +#define ICPU_GENERAL_CTRL_CPU_MIPS_DIS BIT(11) +#define ICPU_GENERAL_CTRL_IF_MIIM_SLV_ADDR_SEL BIT(10) +#define ICPU_GENERAL_CTRL_IF_MIIM_SLV_ENA BIT(9) +#define ICPU_GENERAL_CTRL_IF_PI_SLV_DONEPOL BIT(8) +#define ICPU_GENERAL_CTRL_IF_PI_MST_ENA BIT(7) +#define ICPU_GENERAL_CTRL_IF_PI_SLV_ENA BIT(6) +#define ICPU_GENERAL_CTRL_IF_SI_OWNER(x) (((x) << 4) & GENMASK(5, 4)) +#define ICPU_GENERAL_CTRL_IF_SI_OWNER_M GENMASK(5, 4) +#define ICPU_GENERAL_CTRL_IF_SI_OWNER_X(x) (((x) & GENMASK(5, 4)) >> 4) +#define ICPU_GENERAL_CTRL_SSI_MST_CONTENTION BIT(3) +#define ICPU_GENERAL_CTRL_CPU_BE_ENA BIT(2) +#define ICPU_GENERAL_CTRL_CPU_DIS BIT(1) +#define ICPU_GENERAL_CTRL_BOOT_MODE_ENA BIT(0) +#define ICPU_SPI_MST_CFG 0x3c + +#define ICPU_SPI_MST_CFG_A32B_ENA BIT(11) +#define ICPU_SPI_MST_CFG_FAST_READ_ENA BIT(10) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME(x) (((x) << 5) & GENMASK(9, 5)) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_M GENMASK(9, 5) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_X(x) (((x) & GENMASK(9, 5)) >> 5) +#define ICPU_SPI_MST_CFG_CLK_DIV(x) ((x) & GENMASK(4, 0)) +#define ICPU_SPI_MST_CFG_CLK_DIV_M GENMASK(4, 0) + +#define ICPU_SW_MODE 0x50 + +#define ICPU_SW_MODE_SW_PIN_CTRL_MODE BIT(13) +#define ICPU_SW_MODE_SW_SPI_SCK BIT(12) +#define ICPU_SW_MODE_SW_SPI_SCK_OE BIT(11) +#define ICPU_SW_MODE_SW_SPI_SDO BIT(10) +#define ICPU_SW_MODE_SW_SPI_SDO_OE BIT(9) +#define ICPU_SW_MODE_SW_SPI_CS(x) (((x) << 5) & GENMASK(8, 5)) +#define ICPU_SW_MODE_SW_SPI_CS_M GENMASK(8, 5) +#define ICPU_SW_MODE_SW_SPI_CS_X(x) (((x) & GENMASK(8, 5)) >> 5) +#define ICPU_SW_MODE_SW_SPI_CS_OE(x) (((x) << 1) & GENMASK(4, 1)) +#define ICPU_SW_MODE_SW_SPI_CS_OE_M GENMASK(4, 1) +#define ICPU_SW_MODE_SW_SPI_CS_OE_X(x) (((x) & GENMASK(4, 1)) >> 1) +#define ICPU_SW_MODE_SW_SPI_SDI BIT(0) + +#define ICPU_INTR_ENA 0x88 + +#define ICPU_DST_INTR_MAP(x) (0x98 + 0x4 * (x)) +#define ICPU_DST_INTR_MAP_RSZ 0x4 + +#define ICPU_DST_INTR_IDENT 0xa8 +#define ICPU_DST_INTR_IDENT_RSZ 0x4 + +#define ICPU_TIMER_TICK_DIV 0xe8 +#define ICPU_TIMER_VALUE(x) (0xec + 0x4 * (x)) + +#define ICPU_TIMER_CTRL(x) (0x104 + 0x4 * (x)) +#define ICPU_TIMER_CTRL_MAX_FREQ_ENA BIT(3) +#define ICPU_TIMER_CTRL_ONE_SHOT_ENA BIT(2) +#define ICPU_TIMER_CTRL_TIMER_ENA BIT(1) +#define ICPU_TIMER_CTRL_FORCE_RELOAD BIT(0) + +#define ICPU_MEMCTRL_CTRL 0x110 +#define ICPU_MEMCTRL_CTRL_PWR_DOWN BIT(3) +#define ICPU_MEMCTRL_CTRL_MDSET BIT(2) +#define ICPU_MEMCTRL_CTRL_STALL_REF_ENA BIT(1) +#define ICPU_MEMCTRL_CTRL_INITIALIZE BIT(0) + +#define ICPU_MEMCTRL_CFG 0x114 + +#define ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS BIT(16) +#define ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA BIT(15) +#define ICPU_MEMCTRL_CFG_DDR_ECC_COR_ENA BIT(14) +#define ICPU_MEMCTRL_CFG_DDR_ECC_ENA BIT(13) +#define ICPU_MEMCTRL_CFG_DDR_WIDTH BIT(12) +#define ICPU_MEMCTRL_CFG_DDR_MODE BIT(11) +#define ICPU_MEMCTRL_CFG_BURST_SIZE BIT(10) +#define ICPU_MEMCTRL_CFG_BURST_LEN BIT(9) +#define ICPU_MEMCTRL_CFG_BANK_CNT BIT(8) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_M GENMASK(7, 4) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_STAT 0x118 + +#define ICPU_MEMCTRL_STAT_RDATA_MASKED BIT(5) +#define ICPU_MEMCTRL_STAT_RDATA_DUMMY BIT(4) +#define ICPU_MEMCTRL_STAT_RDATA_ECC_ERR BIT(3) +#define ICPU_MEMCTRL_STAT_RDATA_ECC_COR BIT(2) +#define ICPU_MEMCTRL_STAT_PWR_DOWN_ACK BIT(1) +#define ICPU_MEMCTRL_STAT_INIT_DONE BIT(0) + +#define ICPU_MEMCTRL_REF_PERIOD 0x11c + +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_M GENMASK(19, 16) +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(x) ((x) & GENMASK(15, 0)) +#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD_M GENMASK(15, 0) + +#define ICPU_MEMCTRL_TIMING0 0x124 + +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(x) (((x) << 28) & GENMASK(31, 28)) +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_M GENMASK(31, 28) +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_X(x) (((x) & GENMASK(31, 28)) >> 28) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(x) (((x) << 24) & GENMASK(27, 24)) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_M GENMASK(27, 24) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_X(x) (((x) & GENMASK(27, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(x) (((x) << 20) & GENMASK(23, 20)) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_M GENMASK(23, 20) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_X(x) (((x) & GENMASK(23, 20)) >> 20) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_M GENMASK(19, 16) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_TIMING1 0x128 + +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(x) (((x) << 24) & GENMASK(31, 24)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_M GENMASK(31, 24) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_X(x) (((x) & GENMASK(31, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(x) (((x) << 16) & GENMASK(23, 16)) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_M GENMASK(23, 16) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_X(x) (((x) & GENMASK(23, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_TIMING2 0x12c + +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(x) (((x) << 28) & GENMASK(31, 28)) +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_M GENMASK(31, 28) +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_X(x) (((x) & GENMASK(31, 28)) >> 28) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY(x) (((x) << 24) & GENMASK(27, 24)) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_M GENMASK(27, 24) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_X(x) (((x) & GENMASK(27, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING2_REF_DLY(x) (((x) << 16) & GENMASK(23, 16)) +#define ICPU_MEMCTRL_TIMING2_REF_DLY_M GENMASK(23, 16) +#define ICPU_MEMCTRL_TIMING2_REF_DLY_X(x) (((x) & GENMASK(23, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING2_INIT_DLY(x) ((x) & GENMASK(15, 0)) +#define ICPU_MEMCTRL_TIMING2_INIT_DLY_M GENMASK(15, 0) + +#define ICPU_MEMCTRL_TIMING3 0x130 + +#define ICPU_MEMCTRL_TIMING3_RMW_DLY(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_TIMING3_RMW_DLY_M GENMASK(19, 16) +#define ICPU_MEMCTRL_TIMING3_RMW_DLY_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_MR0_VAL 0x138 + +#define ICPU_MEMCTRL_MR1_VAL 0x13c + +#define ICPU_MEMCTRL_MR2_VAL 0x140 + +#define ICPU_MEMCTRL_MR3_VAL 0x144 + +#define ICPU_MEMCTRL_TERMRES_CTRL 0x148 + +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_EXT BIT(11) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA(x) (((x) << 7) & GENMASK(10, 7)) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_M GENMASK(10, 7) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_X(x) (((x) & GENMASK(10, 7)) >> 7) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_EXT BIT(6) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(x) (((x) << 2) & GENMASK(5, 2)) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_M GENMASK(5, 2) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_X(x) (((x) & GENMASK(5, 2)) >> 2) +#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_EXT BIT(1) +#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA BIT(0) + +#define ICPU_MEMCTRL_DQS_DLY(x) (0x150 + 0x4 * (x)) +#define ICPU_MEMCTRL_DQS_DLY_RSZ 0x4 + +#define ICPU_MEMCTRL_DQS_DLY_TRAIN_DQ_ENA BIT(11) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1(x) (((x) << 8) & GENMASK(10, 8)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_M GENMASK(10, 8) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_X(x) (((x) & GENMASK(10, 8)) >> 8) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0(x) (((x) << 5) & GENMASK(7, 5)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_M GENMASK(7, 5) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_X(x) (((x) & GENMASK(7, 5)) >> 5) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY(x) ((x) & GENMASK(4, 0)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M GENMASK(4, 0) + +#define ICPU_MEMPHY_CFG 0x160 + +#define ICPU_MEMPHY_CFG_PHY_FLUSH_DIS BIT(10) +#define ICPU_MEMPHY_CFG_PHY_RD_ADJ_DIS BIT(9) +#define ICPU_MEMPHY_CFG_PHY_DQS_EXT BIT(8) +#define ICPU_MEMPHY_CFG_PHY_FIFO_RST BIT(7) +#define ICPU_MEMPHY_CFG_PHY_DLL_BL_RST BIT(6) +#define ICPU_MEMPHY_CFG_PHY_DLL_CL_RST BIT(5) +#define ICPU_MEMPHY_CFG_PHY_ODT_OE BIT(4) +#define ICPU_MEMPHY_CFG_PHY_CK_OE BIT(3) +#define ICPU_MEMPHY_CFG_PHY_CL_OE BIT(2) +#define ICPU_MEMPHY_CFG_PHY_SSTL_ENA BIT(1) +#define ICPU_MEMPHY_CFG_PHY_RST BIT(0) + +#define ICPU_MEMPHY_ZCAL 0x188 + +#define ICPU_MEMPHY_ZCAL_ZCAL_CLK_SEL BIT(9) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(x) (((x) << 5) & GENMASK(8, 5)) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_M GENMASK(8, 5) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_X(x) (((x) & GENMASK(8, 5)) >> 5) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG(x) (((x) << 1) & GENMASK(4, 1)) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_M GENMASK(4, 1) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_X(x) (((x) & GENMASK(4, 1)) >> 1) +#define ICPU_MEMPHY_ZCAL_ZCAL_ENA BIT(0) + +#define ICPU_MEMPHY_ZCAL_STAT 0x18c + +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL(x) (((x) << 12) & GENMASK(31, 12)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL_M GENMASK(31, 12) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL_X(x) (((x) & GENMASK(31, 12)) >> 12) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU(x) (((x) << 8) & GENMASK(9, 8)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU_M GENMASK(9, 8) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU_X(x) (((x) & GENMASK(9, 8)) >> 8) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD(x) (((x) << 6) & GENMASK(7, 6)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD_M GENMASK(7, 6) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD_X(x) (((x) & GENMASK(7, 6)) >> 6) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU(x) (((x) << 4) & GENMASK(5, 4)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU_M GENMASK(5, 4) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU_X(x) (((x) & GENMASK(5, 4)) >> 4) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD(x) (((x) << 2) & GENMASK(3, 2)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD_M GENMASK(3, 2) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD_X(x) (((x) & GENMASK(3, 2)) >> 2) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR BIT(1) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_DONE BIT(0) +#endif diff --git a/arch/mips/mach-mscc/include/mach/tlb.h b/arch/mips/mach-mscc/include/mach/tlb.h new file mode 100644 index 00000000000..fdb554f5518 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/tlb.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef __ASM_MACH_TLB_H +#define __ASM_MACH_TLB_H + +#include <asm/mipsregs.h> +#include <mach/common.h> +#include <linux/sizes.h> + +#define TLB_HI_MASK 0xffffe000 +#define TLB_LO_MASK 0x3fffffff /* Masks off Fill bits */ +#define TLB_LO_SHIFT 6 /* PFN Start bit */ + +#define PAGEMASK_SHIFT 13 + +#define MMU_PAGE_CACHED (3 << 3) /* C(5:3) Cache Coherency Attributes */ +#define MMU_PAGE_UNCACHED (2 << 3) /* C(5:3) Cache Coherency Attributes */ +#define MMU_PAGE_DIRTY BIT(2) /* = Writeable */ +#define MMU_PAGE_VALID BIT(1) +#define MMU_PAGE_GLOBAL BIT(0) +#define MMU_REGIO_RO_C (MMU_PAGE_CACHED | MMU_PAGE_VALID | MMU_PAGE_GLOBAL) +#define MMU_REGIO_RO (MMU_PAGE_UNCACHED | MMU_PAGE_VALID | MMU_PAGE_GLOBAL) +#define MMU_REGIO_RW (MMU_PAGE_DIRTY | MMU_REGIO_RO) +#define MMU_REGIO_INVAL (MMU_PAGE_GLOBAL) + +#define TLB_COUNT_MASK GENMASK(5, 0) +#define TLB_COUNT_OFF 25 + +static inline u32 get_tlb_count(void) +{ + register u32 config1; + + config1 = read_c0_config1(); + config1 >>= TLB_COUNT_OFF; + config1 &= TLB_COUNT_MASK; + + return 1 + config1; +} + +static inline void create_tlb(int index, u32 offset, u32 size, u32 tlb_attrib1, + u32 tlb_attrib2) +{ + register u32 tlb_mask, tlb_lo0, tlb_lo1; + + tlb_mask = ((size >> 12) - 1) << PAGEMASK_SHIFT; + tlb_lo0 = tlb_attrib1 | (offset >> TLB_LO_SHIFT); + tlb_lo1 = tlb_attrib2 | ((offset + size) >> TLB_LO_SHIFT); + + write_one_tlb(index, tlb_mask, offset & TLB_HI_MASK, + tlb_lo0 & TLB_LO_MASK, tlb_lo1 & TLB_LO_MASK); +} +#endif /* __ASM_MACH_TLB_H */ diff --git a/arch/mips/mach-mscc/lowlevel_init.S b/arch/mips/mach-mscc/lowlevel_init.S new file mode 100644 index 00000000000..dfbe06766cd --- /dev/null +++ b/arch/mips/mach-mscc/lowlevel_init.S @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <asm/asm.h> +#include <asm/regdef.h> + + .set noreorder + .extern vcoreiii_tlb_init +#ifdef CONFIG_SOC_LUTON + .extern pll_init +#endif + +LEAF(lowlevel_init) + /* + * As we have no stack yet, we can assume the restricted + * luxury of the sX-registers without saving them + */ + move s0,ra + + jal vcoreiii_tlb_init + nop +#ifdef CONFIG_SOC_LUTON + jal pll_init + nop +#endif + jr s0 + nop + END(lowlevel_init) diff --git a/arch/mips/mach-mscc/lowlevel_init_luton.S b/arch/mips/mach-mscc/lowlevel_init_luton.S new file mode 100644 index 00000000000..8a528fa83a1 --- /dev/null +++ b/arch/mips/mach-mscc/lowlevel_init_luton.S @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <asm/asm.h> +#include <asm/regdef.h> + +#define BASE_MACRO 0x600a0000 +#define REG_OFFSET(t, o) (t + (o*4)) +#define REG_MACRO(x) REG_OFFSET(BASE_MACRO, x) +#define BIT(nr) (1 << (nr)) + +#define MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0 REG_MACRO(6) +#define MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0_LOCK_STATUS BIT(0) +#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2 REG_MACRO(2) +#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0 REG_MACRO(0) +#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV (0x3F << 6) +#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV_ENC(x) (x << 6) + + .set noreorder +LEAF(pll_init) + /* Make sure PLL is locked */ + lw v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0 + andi v1, v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0_LOCK_STATUS + bne v1, zero, 1f + nop + + /* Black magic from frontend */ + li v1, 0x00610400 + sw v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2 + + li v1, 0x00610c00 + sw v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2 + + li v1, 0x00610800 + sw v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2 + + li v1, 0x00610000 + sw v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2 + + /* Wait for lock */ +2: lw v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0 + andi v1, v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0_LOCK_STATUS + /* Keep looping if zero (no lock bit yet) */ + beq v1, zero, 2b + nop + + /* Setup PLL CPU clock divider for 416MHz */ +1: lw v0, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0 + + /* Keep reserved bits */ + li v1, ~MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV + and v0, v0, v1 + + /* Set code 6 ~ 416.66 MHz */ + ori v0, v0, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV_ENC(6) + + sw v0, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0 + jr ra + nop + END(pll_init) diff --git a/arch/mips/mach-mscc/reset.c b/arch/mips/mach-mscc/reset.c new file mode 100644 index 00000000000..390bbd086a8 --- /dev/null +++ b/arch/mips/mach-mscc/reset.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> + +#include <asm/sections.h> +#include <asm/io.h> + +#include <asm/reboot.h> + +void _machine_restart(void) +{ + register u32 resetbits = PERF_SOFT_RST_SOFT_CHIP_RST; + (void)readl(BASE_DEVCPU_GCB + PERF_SOFT_RST); + + /* Make sure VCore is NOT protected from reset */ + clrbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_CORE_RST_PROTECT); + + /* Change to SPI bitbang for SPI reset workaround... */ + writel(ICPU_SW_MODE_SW_SPI_CS_OE(1) | ICPU_SW_MODE_SW_SPI_CS(1) | + ICPU_SW_MODE_SW_PIN_CTRL_MODE, BASE_CFG + ICPU_SW_MODE); + + /* Do the global reset */ + writel(resetbits, BASE_DEVCPU_GCB + PERF_SOFT_RST); + + while (1) + ; /* NOP */ +} diff --git a/arch/mips/mach-mt7620/cpu.c b/arch/mips/mach-mt7620/cpu.c index 87cc973b756..9e0ca716f72 100644 --- a/arch/mips/mach-mt7620/cpu.c +++ b/arch/mips/mach-mt7620/cpu.c @@ -89,9 +89,21 @@ void watchdog_reset(void) wdt_reset(watchdog_dev); } } +#endif int arch_misc_init(void) { + /* + * It has been noticed, that sometimes the d-cache is not in a + * "clean-state" when U-Boot is running on MT7688. This was + * detected when using the ethernet driver (which uses d-cache) + * and a TFTP command does not complete. Flushing the complete + * d-cache (again?) here seems to fix this issue. + */ + flush_dcache_range(gd->bd->bi_memstart, + gd->bd->bi_memstart + gd->ram_size - 1); + +#ifdef CONFIG_WATCHDOG /* Init watchdog */ if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { debug("Watchdog: Not found by seq!\n"); @@ -103,7 +115,7 @@ int arch_misc_init(void) wdt_start(watchdog_dev, 60000, 0); /* 60 seconds */ printf("Watchdog: Started\n"); +#endif return 0; } -#endif diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 732a357a99b..c45e4d73a8c 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -22,6 +22,7 @@ source "board/emulation/qemu-riscv/Kconfig" # platform-specific options below source "arch/riscv/cpu/ax25/Kconfig" +source "arch/riscv/cpu/qemu/Kconfig" # architecture-specific options below @@ -44,6 +45,40 @@ config ARCH_RV64I endchoice +choice + prompt "Code Model" + default CMODEL_MEDLOW + +config CMODEL_MEDLOW + bool "medium low code model" + help + U-Boot and its statically defined symbols must lie within a single 2 GiB + address range and must lie between absolute addresses -2 GiB and +2 GiB. + +config CMODEL_MEDANY + bool "medium any code model" + help + U-Boot and its statically defined symbols must be within any single 2 GiB + address range. + +endchoice + +choice + prompt "Run Mode" + default RISCV_MMODE + +config RISCV_MMODE + bool "Machine" + help + Choose this option to build U-Boot for RISC-V M-Mode. + +config RISCV_SMODE + bool "Supervisor" + help + Choose this option to build U-Boot for RISC-V S-Mode. + +endchoice + config RISCV_ISA_C bool "Emit compressed instructions" default y @@ -55,15 +90,30 @@ config RISCV_ISA_C config RISCV_ISA_A def_bool y -config RISCV_SMODE - bool "Run in S-Mode" - help - Enable this option to build U-Boot for RISC-V S-Mode - config 32BIT bool config 64BIT bool +config SIFIVE_CLINT + bool + depends on RISCV_MMODE + select REGMAP + select SYSCON + help + The SiFive CLINT block holds memory-mapped control and status registers + associated with software and timer interrupts. + +config RISCV_RDTIME + bool + default y if RISCV_SMODE + help + The provides the riscv_get_time() API that is implemented using the + standard rdtime instruction. This is the case for S-mode U-Boot, and + is useful for processors that support rdtime in M-mode too. + +config SYS_MALLOC_F_LEN + default 0x1000 + endmenu diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 55d7c6550e9..0b80eb8d864 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -17,8 +17,15 @@ endif ifeq ($(CONFIG_RISCV_ISA_C),y) ARCH_C = c endif +ifeq ($(CONFIG_CMODEL_MEDLOW),y) + CMODEL = medlow +endif +ifeq ($(CONFIG_CMODEL_MEDANY),y) + CMODEL = medany +endif -ARCH_FLAGS = -march=$(ARCH_BASE)$(ARCH_A)$(ARCH_C) -mabi=$(ABI) +ARCH_FLAGS = -march=$(ARCH_BASE)$(ARCH_A)$(ARCH_C) -mabi=$(ABI) \ + -mcmodel=$(CMODEL) PLATFORM_CPPFLAGS += $(ARCH_FLAGS) CFLAGS_EFI += $(ARCH_FLAGS) diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile index 2cc6757fcf8..6bf6f911c67 100644 --- a/arch/riscv/cpu/Makefile +++ b/arch/riscv/cpu/Makefile @@ -4,4 +4,4 @@ extra-y = start.o -obj-y += cpu.o +obj-y += cpu.o mtrap.o diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig index 6c7022f0f5c..e9dbca2faea 100644 --- a/arch/riscv/cpu/ax25/Kconfig +++ b/arch/riscv/cpu/ax25/Kconfig @@ -1,7 +1,14 @@ config RISCV_NDS - bool "AndeStar V5 ISA support" - default n + bool help - Say Y here if you plan to run U-Boot on AndeStar v5 - platforms and use some specific features which are - provided by Andes Technology AndeStar V5 Families. + Run U-Boot on AndeStar V5 platforms and use some specific features + which are provided by Andes Technology AndeStar V5 families. + +if RISCV_NDS + +config RISCV_NDS_CACHE + bool "AndeStar V5 families specific cache support" + help + Provide Andes Technology AndeStar V5 families specific cache support. + +endif diff --git a/arch/riscv/cpu/ax25/cache.c b/arch/riscv/cpu/ax25/cache.c index 6600ac2fac1..8d6ae170b8c 100644 --- a/arch/riscv/cpu/ax25/cache.c +++ b/arch/riscv/cpu/ax25/cache.c @@ -9,7 +9,7 @@ void icache_enable(void) { #ifndef CONFIG_SYS_ICACHE_OFF -#ifdef CONFIG_RISCV_NDS +#ifdef CONFIG_RISCV_NDS_CACHE asm volatile ( "csrr t1, mcache_ctl\n\t" "ori t0, t1, 0x1\n\t" @@ -22,7 +22,7 @@ void icache_enable(void) void icache_disable(void) { #ifndef CONFIG_SYS_ICACHE_OFF -#ifdef CONFIG_RISCV_NDS +#ifdef CONFIG_RISCV_NDS_CACHE asm volatile ( "fence.i\n\t" "csrr t1, mcache_ctl\n\t" @@ -36,7 +36,7 @@ void icache_disable(void) void dcache_enable(void) { #ifndef CONFIG_SYS_DCACHE_OFF -#ifdef CONFIG_RISCV_NDS +#ifdef CONFIG_RISCV_NDS_CACHE asm volatile ( "csrr t1, mcache_ctl\n\t" "ori t0, t1, 0x2\n\t" @@ -49,7 +49,7 @@ void dcache_enable(void) void dcache_disable(void) { #ifndef CONFIG_SYS_DCACHE_OFF -#ifdef CONFIG_RISCV_NDS +#ifdef CONFIG_RISCV_NDS_CACHE asm volatile ( "fence\n\t" "csrr t1, mcache_ctl\n\t" @@ -64,7 +64,7 @@ int icache_status(void) { int ret = 0; -#ifdef CONFIG_RISCV_NDS +#ifdef CONFIG_RISCV_NDS_CACHE asm volatile ( "csrr t1, mcache_ctl\n\t" "andi %0, t1, 0x01\n\t" @@ -81,7 +81,7 @@ int dcache_status(void) { int ret = 0; -#ifdef CONFIG_RISCV_NDS +#ifdef CONFIG_RISCV_NDS_CACHE asm volatile ( "csrr t1, mcache_ctl\n\t" "andi %0, t1, 0x02\n\t" diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index d9f820c44c0..e662140427a 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -4,7 +4,12 @@ */ #include <common.h> +#include <cpu.h> +#include <dm.h> +#include <log.h> #include <asm/csr.h> +#include <asm/encoding.h> +#include <dm/uclass-internal.h> /* * prior_stage_fdt_address must be stored in the data section since it is used @@ -12,44 +17,79 @@ */ phys_addr_t prior_stage_fdt_address __attribute__((section(".data"))); -enum { - ISA_INVALID = 0, - ISA_32BIT, - ISA_64BIT, - ISA_128BIT -}; - -static const char * const isa_bits[] = { - [ISA_INVALID] = NULL, - [ISA_32BIT] = "32", - [ISA_64BIT] = "64", - [ISA_128BIT] = "128" -}; - static inline bool supports_extension(char ext) { +#ifdef CONFIG_CPU + struct udevice *dev; + char desc[32]; + + uclass_find_first_device(UCLASS_CPU, &dev); + if (!dev) { + debug("unable to find the RISC-V cpu device\n"); + return false; + } + if (!cpu_get_desc(dev, desc, sizeof(desc))) { + /* skip the first 4 characters (rv32|rv64) */ + if (strchr(desc + 4, ext)) + return true; + } + + return false; +#else /* !CONFIG_CPU */ +#ifdef CONFIG_RISCV_MMODE return csr_read(misa) & (1 << (ext - 'a')); +#else /* !CONFIG_RISCV_MMODE */ +#warning "There is no way to determine the available extensions in S-mode." +#warning "Please convert your board to use the RISC-V CPU driver." + return false; +#endif /* CONFIG_RISCV_MMODE */ +#endif /* CONFIG_CPU */ +} + +static int riscv_cpu_probe(void) +{ +#ifdef CONFIG_CPU + int ret; + + /* probe cpus so that RISC-V timer can be bound */ + ret = cpu_probe_all(); + if (ret) + return log_msg_ret("RISC-V cpus probe failed\n", ret); +#endif + + return 0; } -int print_cpuinfo(void) +int arch_cpu_init_dm(void) { - char name[32]; - char *s = name; - int bit; + int ret; + + ret = riscv_cpu_probe(); + if (ret) + return ret; - s += sprintf(name, "rv"); - bit = csr_read(misa) >> (sizeof(long) * 8 - 2); - s += sprintf(s, isa_bits[bit]); + /* Enable FPU */ + if (supports_extension('d') || supports_extension('f')) { + csr_set(MODE_PREFIX(status), MSTATUS_FS); + csr_write(fcsr, 0); + } - supports_extension('i') ? *s++ = 'i' : 'r'; - supports_extension('m') ? *s++ = 'm' : 'i'; - supports_extension('a') ? *s++ = 'a' : 's'; - supports_extension('f') ? *s++ = 'f' : 'c'; - supports_extension('d') ? *s++ = 'd' : '-'; - supports_extension('c') ? *s++ = 'c' : 'v'; - *s++ = '\0'; + if (CONFIG_IS_ENABLED(RISCV_MMODE)) { + /* + * Enable perf counters for cycle, time, + * and instret counters only + */ + csr_write(mcounteren, GENMASK(2, 0)); - printf("CPU: %s\n", name); + /* Disable paging */ + if (supports_extension('s')) + csr_write(satp, 0); + } return 0; } + +int arch_early_init_r(void) +{ + return riscv_cpu_probe(); +} diff --git a/arch/riscv/cpu/mtrap.S b/arch/riscv/cpu/mtrap.S new file mode 100644 index 00000000000..407ecfa9c07 --- /dev/null +++ b/arch/riscv/cpu/mtrap.S @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * M-mode Trap Handler Code for RISC-V Core + * + * Copyright (c) 2017 Microsemi Corporation. + * Copyright (c) 2017 Padmarao Begari <Padmarao.Begari@microsemi.com> + * + * Copyright (C) 2017 Andes Technology Corporation + * Rick Chen, Andes Technology Corporation <rick@andestech.com> + * + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <common.h> +#include <asm/encoding.h> + +#ifdef CONFIG_32BIT +#define LREG lw +#define SREG sw +#define REGBYTES 4 +#else +#define LREG ld +#define SREG sd +#define REGBYTES 8 +#endif + + .text + + /* trap entry */ + .align 2 + .global trap_entry +trap_entry: + addi sp, sp, -32 * REGBYTES + SREG x1, 1 * REGBYTES(sp) + SREG x2, 2 * REGBYTES(sp) + SREG x3, 3 * REGBYTES(sp) + SREG x4, 4 * REGBYTES(sp) + SREG x5, 5 * REGBYTES(sp) + SREG x6, 6 * REGBYTES(sp) + SREG x7, 7 * REGBYTES(sp) + SREG x8, 8 * REGBYTES(sp) + SREG x9, 9 * REGBYTES(sp) + SREG x10, 10 * REGBYTES(sp) + SREG x11, 11 * REGBYTES(sp) + SREG x12, 12 * REGBYTES(sp) + SREG x13, 13 * REGBYTES(sp) + SREG x14, 14 * REGBYTES(sp) + SREG x15, 15 * REGBYTES(sp) + SREG x16, 16 * REGBYTES(sp) + SREG x17, 17 * REGBYTES(sp) + SREG x18, 18 * REGBYTES(sp) + SREG x19, 19 * REGBYTES(sp) + SREG x20, 20 * REGBYTES(sp) + SREG x21, 21 * REGBYTES(sp) + SREG x22, 22 * REGBYTES(sp) + SREG x23, 23 * REGBYTES(sp) + SREG x24, 24 * REGBYTES(sp) + SREG x25, 25 * REGBYTES(sp) + SREG x26, 26 * REGBYTES(sp) + SREG x27, 27 * REGBYTES(sp) + SREG x28, 28 * REGBYTES(sp) + SREG x29, 29 * REGBYTES(sp) + SREG x30, 30 * REGBYTES(sp) + SREG x31, 31 * REGBYTES(sp) + csrr a0, MODE_PREFIX(cause) + csrr a1, MODE_PREFIX(epc) + mv a2, sp + jal handle_trap + csrw MODE_PREFIX(epc), a0 + + LREG x1, 1 * REGBYTES(sp) + LREG x3, 3 * REGBYTES(sp) + LREG x4, 4 * REGBYTES(sp) + LREG x5, 5 * REGBYTES(sp) + LREG x6, 6 * REGBYTES(sp) + LREG x7, 7 * REGBYTES(sp) + LREG x8, 8 * REGBYTES(sp) + LREG x9, 9 * REGBYTES(sp) + LREG x10, 10 * REGBYTES(sp) + LREG x11, 11 * REGBYTES(sp) + LREG x12, 12 * REGBYTES(sp) + LREG x13, 13 * REGBYTES(sp) + LREG x14, 14 * REGBYTES(sp) + LREG x15, 15 * REGBYTES(sp) + LREG x16, 16 * REGBYTES(sp) + LREG x17, 17 * REGBYTES(sp) + LREG x18, 18 * REGBYTES(sp) + LREG x19, 19 * REGBYTES(sp) + LREG x20, 20 * REGBYTES(sp) + LREG x21, 21 * REGBYTES(sp) + LREG x22, 22 * REGBYTES(sp) + LREG x23, 23 * REGBYTES(sp) + LREG x24, 24 * REGBYTES(sp) + LREG x25, 25 * REGBYTES(sp) + LREG x26, 26 * REGBYTES(sp) + LREG x27, 27 * REGBYTES(sp) + LREG x28, 28 * REGBYTES(sp) + LREG x29, 29 * REGBYTES(sp) + LREG x30, 30 * REGBYTES(sp) + LREG x31, 31 * REGBYTES(sp) + LREG x2, 2 * REGBYTES(sp) + addi sp, sp, 32 * REGBYTES + MODE_PREFIX(ret) diff --git a/arch/riscv/cpu/qemu/Kconfig b/arch/riscv/cpu/qemu/Kconfig new file mode 100644 index 00000000000..f48751e6de7 --- /dev/null +++ b/arch/riscv/cpu/qemu/Kconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + +config QEMU_RISCV + bool + select ARCH_EARLY_INIT_R + imply CPU + imply CPU_RISCV + imply RISCV_TIMER + imply SIFIVE_CLINT if RISCV_MMODE + imply CMD_CPU diff --git a/arch/riscv/cpu/qemu/cpu.c b/arch/riscv/cpu/qemu/cpu.c index 25d97d0b416..ad2950ce40a 100644 --- a/arch/riscv/cpu/qemu/cpu.c +++ b/arch/riscv/cpu/qemu/cpu.c @@ -4,6 +4,7 @@ */ #include <common.h> +#include <dm.h> /* * cleanup_before_linux() is called just before we call linux @@ -19,3 +20,16 @@ int cleanup_before_linux(void) return 0; } + +/* To enumerate devices on the /soc/ node, create a "simple-bus" driver */ +static const struct udevice_id riscv_virtio_soc_ids[] = { + { .compatible = "riscv-virtio-soc" }, + { } +}; + +U_BOOT_DRIVER(riscv_virtio_soc) = { + .name = "riscv_virtio_soc", + .id = UCLASS_SIMPLE_BUS, + .of_match = riscv_virtio_soc_ids, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 64246a4e093..81ea52b170f 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -14,6 +14,7 @@ #include <common.h> #include <elf.h> #include <asm/encoding.h> +#include <generated/asm-offsets.h> #ifdef CONFIG_32BIT #define LREG lw @@ -70,6 +71,9 @@ call_board_init_f_0: jal board_init_f_init_reserve + /* save the boot hart id to global_data */ + SREG s0, GD_BOOT_HART(gp) + mv a0, zero /* a0 <-- boot_flags = 0 */ la t5, board_init_f jr t5 /* jump to board_init_f() */ @@ -198,92 +202,3 @@ call_board_init_r: * jump to it ... */ jr t4 /* jump to board_init_r() */ - -/* - * trap entry - */ -.align 2 -trap_entry: - addi sp, sp, -32*REGBYTES - SREG x1, 1*REGBYTES(sp) - SREG x2, 2*REGBYTES(sp) - SREG x3, 3*REGBYTES(sp) - SREG x4, 4*REGBYTES(sp) - SREG x5, 5*REGBYTES(sp) - SREG x6, 6*REGBYTES(sp) - SREG x7, 7*REGBYTES(sp) - SREG x8, 8*REGBYTES(sp) - SREG x9, 9*REGBYTES(sp) - SREG x10, 10*REGBYTES(sp) - SREG x11, 11*REGBYTES(sp) - SREG x12, 12*REGBYTES(sp) - SREG x13, 13*REGBYTES(sp) - SREG x14, 14*REGBYTES(sp) - SREG x15, 15*REGBYTES(sp) - SREG x16, 16*REGBYTES(sp) - SREG x17, 17*REGBYTES(sp) - SREG x18, 18*REGBYTES(sp) - SREG x19, 19*REGBYTES(sp) - SREG x20, 20*REGBYTES(sp) - SREG x21, 21*REGBYTES(sp) - SREG x22, 22*REGBYTES(sp) - SREG x23, 23*REGBYTES(sp) - SREG x24, 24*REGBYTES(sp) - SREG x25, 25*REGBYTES(sp) - SREG x26, 26*REGBYTES(sp) - SREG x27, 27*REGBYTES(sp) - SREG x28, 28*REGBYTES(sp) - SREG x29, 29*REGBYTES(sp) - SREG x30, 30*REGBYTES(sp) - SREG x31, 31*REGBYTES(sp) - csrr a0, MODE_PREFIX(cause) - csrr a1, MODE_PREFIX(epc) - mv a2, sp - jal handle_trap - csrw MODE_PREFIX(epc), a0 - -#ifdef CONFIG_RISCV_SMODE -/* - * Remain in S-mode after sret - */ - li t0, SSTATUS_SPP -#else -/* - * Remain in M-mode after mret - */ - li t0, MSTATUS_MPP -#endif - csrs MODE_PREFIX(status), t0 - LREG x1, 1*REGBYTES(sp) - LREG x2, 2*REGBYTES(sp) - LREG x3, 3*REGBYTES(sp) - LREG x4, 4*REGBYTES(sp) - LREG x5, 5*REGBYTES(sp) - LREG x6, 6*REGBYTES(sp) - LREG x7, 7*REGBYTES(sp) - LREG x8, 8*REGBYTES(sp) - LREG x9, 9*REGBYTES(sp) - LREG x10, 10*REGBYTES(sp) - LREG x11, 11*REGBYTES(sp) - LREG x12, 12*REGBYTES(sp) - LREG x13, 13*REGBYTES(sp) - LREG x14, 14*REGBYTES(sp) - LREG x15, 15*REGBYTES(sp) - LREG x16, 16*REGBYTES(sp) - LREG x17, 17*REGBYTES(sp) - LREG x18, 18*REGBYTES(sp) - LREG x19, 19*REGBYTES(sp) - LREG x20, 20*REGBYTES(sp) - LREG x21, 21*REGBYTES(sp) - LREG x22, 22*REGBYTES(sp) - LREG x23, 23*REGBYTES(sp) - LREG x24, 24*REGBYTES(sp) - LREG x25, 25*REGBYTES(sp) - LREG x26, 26*REGBYTES(sp) - LREG x27, 27*REGBYTES(sp) - LREG x28, 28*REGBYTES(sp) - LREG x29, 29*REGBYTES(sp) - LREG x30, 30*REGBYTES(sp) - LREG x31, 31*REGBYTES(sp) - addi sp, sp, 32*REGBYTES - MODE_PREFIX(ret) diff --git a/arch/riscv/dts/ae350.dts b/arch/riscv/dts/ae350.dts deleted file mode 100644 index e48c2986452..00000000000 --- a/arch/riscv/dts/ae350.dts +++ /dev/null @@ -1,229 +0,0 @@ -/dts-v1/; - -/ { - #address-cells = <2>; - #size-cells = <2>; - compatible = "andestech,ax25"; - model = "andestech,ax25"; - - aliases { - uart0 = &serial0; - spi0 = &spi; - }; - - chosen { - bootargs = "console=ttyS0,38400n8 debug loglevel=7"; - stdout-path = "uart0:38400n8"; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - timebase-frequency = <60000000>; - CPU0: cpu@0 { - device_type = "cpu"; - reg = <0>; - status = "okay"; - compatible = "riscv"; - riscv,isa = "rv64imafdc"; - mmu-type = "riscv,sv39"; - clock-frequency = <60000000>; - d-cache-size = <0x8000>; - d-cache-line-size = <32>; - CPU0_intc: interrupt-controller { - #interrupt-cells = <1>; - interrupt-controller; - compatible = "riscv,cpu-intc"; - }; - }; - }; - - memory@0 { - device_type = "memory"; - reg = <0x0 0x00000000 0x0 0x40000000>; - }; - - soc { - #address-cells = <2>; - #size-cells = <2>; - compatible = "andestech,riscv-ae350-soc"; - ranges; - - plic0: interrupt-controller@e4000000 { - compatible = "riscv,plic0"; - #address-cells = <2>; - #interrupt-cells = <2>; - interrupt-controller; - reg = <0x0 0xe4000000 0x0 0x2000000>; - riscv,ndev=<71>; - interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>; - }; - - plic1: interrupt-controller@e6400000 { - compatible = "riscv,plic1"; - #address-cells = <2>; - #interrupt-cells = <2>; - interrupt-controller; - reg = <0x0 0xe6400000 0x0 0x400000>; - riscv,ndev=<1>; - interrupts-extended = <&CPU0_intc 3>; - }; - - plmt0@e6000000 { - compatible = "riscv,plmt0"; - interrupts-extended = <&CPU0_intc 7>; - reg = <0x0 0xe6000000 0x0 0x100000>; - }; - }; - - spiclk: virt_100mhz { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <100000000>; - }; - - timer0: timer@f0400000 { - compatible = "andestech,atcpit100"; - reg = <0x0 0xf0400000 0x0 0x1000>; - clock-frequency = <60000000>; - interrupts = <3 4>; - interrupt-parent = <&plic0>; - }; - - serial0: serial@f0300000 { - compatible = "andestech,uart16550", "ns16550a"; - reg = <0x0 0xf0300000 0x0 0x1000>; - interrupts = <9 4>; - clock-frequency = <19660800>; - reg-shift = <2>; - reg-offset = <32>; - no-loopback-test = <1>; - interrupt-parent = <&plic0>; - }; - - mac0: mac@e0100000 { - compatible = "andestech,atmac100"; - reg = <0x0 0xe0100000 0x0 0x1000>; - interrupts = <19 4>; - interrupt-parent = <&plic0>; - }; - - mmc0: mmc@f0e00000 { - compatible = "andestech,atfsdc010"; - max-frequency = <100000000>; - clock-freq-min-max = <400000 100000000>; - fifo-depth = <0x10>; - reg = <0x0 0xf0e00000 0x0 0x1000>; - interrupts = <18 4>; - cap-sd-highspeed; - interrupt-parent = <&plic0>; - }; - - dma0: dma@f0c00000 { - compatible = "andestech,atcdmac300"; - reg = <0x0 0xf0c00000 0x0 0x1000>; - interrupts = <10 4 64 4 65 4 66 4 67 4 68 4 69 4 70 4 71 4>; - dma-channels = <8>; - interrupt-parent = <&plic0>; - }; - - lcd0: lcd@e0200000 { - compatible = "andestech,atflcdc100"; - reg = <0x0 0xe0200000 0x0 0x1000>; - interrupts = <20 4>; - interrupt-parent = <&plic0>; - }; - - smc0: smc@e0400000 { - compatible = "andestech,atfsmc020"; - reg = <0x0 0xe0400000 0x0 0x1000>; - }; - - snd0: snd@f0d00000 { - compatible = "andestech,atfac97"; - reg = <0x0 0xf0d00000 0x0 0x1000>; - interrupts = <17 4>; - interrupt-parent = <&plic0>; - }; - - virtio_mmio@fe007000 { - interrupts = <0x17 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe007000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe006000 { - interrupts = <0x16 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe006000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe005000 { - interrupts = <0x15 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe005000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe004000 { - interrupts = <0x14 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe004000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe003000 { - interrupts = <0x13 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe003000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe002000 { - interrupts = <0x12 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe002000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe001000 { - interrupts = <0x11 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe001000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe000000 { - interrupts = <0x10 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe000000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - nor@0,0 { - compatible = "cfi-flash"; - reg = <0x0 0x88000000 0x0 0x1000>; - bank-width = <2>; - device-width = <1>; - }; - - spi: spi@f0b00000 { - compatible = "andestech,atcspi200"; - reg = <0x0 0xf0b00000 0x0 0x1000>; - #address-cells = <1>; - #size-cells = <0>; - num-cs = <1>; - clocks = <&spiclk>; - interrupts = <4 4>; - interrupt-parent = <&plic0>; - flash@0 { - compatible = "spi-flash"; - spi-max-frequency = <50000000>; - reg = <0>; - spi-cpol; - spi-cpha; - }; - }; -}; diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 29624fdbb55..86136f542c7 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -61,10 +61,12 @@ #ifndef __ASSEMBLY__ +#define xcsr(csr) #csr + #define csr_swap(csr, val) \ ({ \ unsigned long __v = (unsigned long)(val); \ - __asm__ __volatile__ ("csrrw %0, " #csr ", %1" \ + __asm__ __volatile__ ("csrrw %0, " xcsr(csr) ", %1" \ : "=r" (__v) : "rK" (__v) \ : "memory"); \ __v; \ @@ -73,7 +75,7 @@ #define csr_read(csr) \ ({ \ register unsigned long __v; \ - __asm__ __volatile__ ("csrr %0, " #csr \ + __asm__ __volatile__ ("csrr %0, " xcsr(csr) \ : "=r" (__v) : \ : "memory"); \ __v; \ @@ -82,7 +84,7 @@ #define csr_write(csr, val) \ ({ \ unsigned long __v = (unsigned long)(val); \ - __asm__ __volatile__ ("csrw " #csr ", %0" \ + __asm__ __volatile__ ("csrw " xcsr(csr) ", %0" \ : : "rK" (__v) \ : "memory"); \ }) @@ -90,7 +92,7 @@ #define csr_read_set(csr, val) \ ({ \ unsigned long __v = (unsigned long)(val); \ - __asm__ __volatile__ ("csrrs %0, " #csr ", %1" \ + __asm__ __volatile__ ("csrrs %0, " xcsr(csr) ", %1" \ : "=r" (__v) : "rK" (__v) \ : "memory"); \ __v; \ @@ -99,7 +101,7 @@ #define csr_set(csr, val) \ ({ \ unsigned long __v = (unsigned long)(val); \ - __asm__ __volatile__ ("csrs " #csr ", %0" \ + __asm__ __volatile__ ("csrs " xcsr(csr) ", %0" \ : : "rK" (__v) \ : "memory"); \ }) @@ -107,7 +109,7 @@ #define csr_read_clear(csr, val) \ ({ \ unsigned long __v = (unsigned long)(val); \ - __asm__ __volatile__ ("csrrc %0, " #csr ", %1" \ + __asm__ __volatile__ ("csrrc %0, " xcsr(csr) ", %1" \ : "=r" (__v) : "rK" (__v) \ : "memory"); \ __v; \ @@ -116,7 +118,7 @@ #define csr_clear(csr, val) \ ({ \ unsigned long __v = (unsigned long)(val); \ - __asm__ __volatile__ ("csrc " #csr ", %0" \ + __asm__ __volatile__ ("csrc " xcsr(csr) ", %0" \ : : "rK" (__v) \ : "memory"); \ }) diff --git a/arch/riscv/include/asm/encoding.h b/arch/riscv/include/asm/encoding.h index 97cf906aa63..772668c74e6 100644 --- a/arch/riscv/include/asm/encoding.h +++ b/arch/riscv/include/asm/encoding.h @@ -85,6 +85,21 @@ #define IRQ_COP 12 #define IRQ_HOST 13 +#define CAUSE_MISALIGNED_FETCH 0 +#define CAUSE_FETCH_ACCESS 1 +#define CAUSE_ILLEGAL_INSTRUCTION 2 +#define CAUSE_BREAKPOINT 3 +#define CAUSE_MISALIGNED_LOAD 4 +#define CAUSE_LOAD_ACCESS 5 +#define CAUSE_MISALIGNED_STORE 6 +#define CAUSE_STORE_ACCESS 7 +#define CAUSE_USER_ECALL 8 +#define CAUSE_SUPERVISOR_ECALL 9 +#define CAUSE_MACHINE_ECALL 11 +#define CAUSE_FETCH_PAGE_FAULT 12 +#define CAUSE_LOAD_PAGE_FAULT 13 +#define CAUSE_STORE_PAGE_FAULT 15 + #define DEFAULT_RSTVEC 0x00001000 #define DEFAULT_NMIVEC 0x00001004 #define DEFAULT_MTVEC 0x00001010 @@ -152,6 +167,227 @@ #define RISCV_PGSHIFT 12 #define RISCV_PGSIZE BIT(RISCV_PGSHIFT) +/* CSR numbers */ +#define CSR_FFLAGS 0x1 +#define CSR_FRM 0x2 +#define CSR_FCSR 0x3 + +#define CSR_SSTATUS 0x100 +#define CSR_SEDELEG 0x102 +#define CSR_SIDELEG 0x103 +#define CSR_SIE 0x104 +#define CSR_STVEC 0x105 +#define CSR_SCOUNTEREN 0x106 +#define CSR_SSCRATCH 0x140 +#define CSR_SEPC 0x141 +#define CSR_SCAUSE 0x142 +#define CSR_STVAL 0x143 +#define CSR_SIP 0x144 +#define CSR_SATP 0x180 + +#define CSR_MSTATUS 0x300 +#define CSR_MISA 0x301 +#define CSR_MEDELEG 0x302 +#define CSR_MIDELEG 0x303 +#define CSR_MIE 0x304 +#define CSR_MTVEC 0x305 +#define CSR_MCOUNTEREN 0x306 +#define CSR_MHPMEVENT3 0x323 +#define CSR_MHPMEVENT4 0x324 +#define CSR_MHPMEVENT5 0x325 +#define CSR_MHPMEVENT6 0x326 +#define CSR_MHPMEVENT7 0x327 +#define CSR_MHPMEVENT8 0x328 +#define CSR_MHPMEVENT9 0x329 +#define CSR_MHPMEVENT10 0x32a +#define CSR_MHPMEVENT11 0x32b +#define CSR_MHPMEVENT12 0x32c +#define CSR_MHPMEVENT13 0x32d +#define CSR_MHPMEVENT14 0x32e +#define CSR_MHPMEVENT15 0x32f +#define CSR_MHPMEVENT16 0x330 +#define CSR_MHPMEVENT17 0x331 +#define CSR_MHPMEVENT18 0x332 +#define CSR_MHPMEVENT19 0x333 +#define CSR_MHPMEVENT20 0x334 +#define CSR_MHPMEVENT21 0x335 +#define CSR_MHPMEVENT22 0x336 +#define CSR_MHPMEVENT23 0x337 +#define CSR_MHPMEVENT24 0x338 +#define CSR_MHPMEVENT25 0x339 +#define CSR_MHPMEVENT26 0x33a +#define CSR_MHPMEVENT27 0x33b +#define CSR_MHPMEVENT28 0x33c +#define CSR_MHPMEVENT29 0x33d +#define CSR_MHPMEVENT30 0x33e +#define CSR_MHPMEVENT31 0x33f +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MTVAL 0x343 +#define CSR_MIP 0x344 +#define CSR_PMPCFG0 0x3a0 +#define CSR_PMPCFG1 0x3a1 +#define CSR_PMPCFG2 0x3a2 +#define CSR_PMPCFG3 0x3a3 +#define CSR_PMPADDR0 0x3b0 +#define CSR_PMPADDR1 0x3b1 +#define CSR_PMPADDR2 0x3b2 +#define CSR_PMPADDR3 0x3b3 +#define CSR_PMPADDR4 0x3b4 +#define CSR_PMPADDR5 0x3b5 +#define CSR_PMPADDR6 0x3b6 +#define CSR_PMPADDR7 0x3b7 +#define CSR_PMPADDR8 0x3b8 +#define CSR_PMPADDR9 0x3b9 +#define CSR_PMPADDR10 0x3ba +#define CSR_PMPADDR11 0x3bb +#define CSR_PMPADDR12 0x3bc +#define CSR_PMPADDR13 0x3bd +#define CSR_PMPADDR14 0x3be +#define CSR_PMPADDR15 0x3bf + +#define CSR_TSELECT 0x7a0 +#define CSR_TDATA1 0x7a1 +#define CSR_TDATA2 0x7a2 +#define CSR_TDATA3 0x7a3 +#define CSR_DCSR 0x7b0 +#define CSR_DPC 0x7b1 +#define CSR_DSCRATCH 0x7b2 + +#define CSR_MCYCLE 0xb00 +#define CSR_MINSTRET 0xb02 +#define CSR_MHPMCOUNTER3 0xb03 +#define CSR_MHPMCOUNTER4 0xb04 +#define CSR_MHPMCOUNTER5 0xb05 +#define CSR_MHPMCOUNTER6 0xb06 +#define CSR_MHPMCOUNTER7 0xb07 +#define CSR_MHPMCOUNTER8 0xb08 +#define CSR_MHPMCOUNTER9 0xb09 +#define CSR_MHPMCOUNTER10 0xb0a +#define CSR_MHPMCOUNTER11 0xb0b +#define CSR_MHPMCOUNTER12 0xb0c +#define CSR_MHPMCOUNTER13 0xb0d +#define CSR_MHPMCOUNTER14 0xb0e +#define CSR_MHPMCOUNTER15 0xb0f +#define CSR_MHPMCOUNTER16 0xb10 +#define CSR_MHPMCOUNTER17 0xb11 +#define CSR_MHPMCOUNTER18 0xb12 +#define CSR_MHPMCOUNTER19 0xb13 +#define CSR_MHPMCOUNTER20 0xb14 +#define CSR_MHPMCOUNTER21 0xb15 +#define CSR_MHPMCOUNTER22 0xb16 +#define CSR_MHPMCOUNTER23 0xb17 +#define CSR_MHPMCOUNTER24 0xb18 +#define CSR_MHPMCOUNTER25 0xb19 +#define CSR_MHPMCOUNTER26 0xb1a +#define CSR_MHPMCOUNTER27 0xb1b +#define CSR_MHPMCOUNTER28 0xb1c +#define CSR_MHPMCOUNTER29 0xb1d +#define CSR_MHPMCOUNTER30 0xb1e +#define CSR_MHPMCOUNTER31 0xb1f +#define CSR_MCYCLEH 0xb80 +#define CSR_MINSTRETH 0xb82 +#define CSR_MHPMCOUNTER3H 0xb83 +#define CSR_MHPMCOUNTER4H 0xb84 +#define CSR_MHPMCOUNTER5H 0xb85 +#define CSR_MHPMCOUNTER6H 0xb86 +#define CSR_MHPMCOUNTER7H 0xb87 +#define CSR_MHPMCOUNTER8H 0xb88 +#define CSR_MHPMCOUNTER9H 0xb89 +#define CSR_MHPMCOUNTER10H 0xb8a +#define CSR_MHPMCOUNTER11H 0xb8b +#define CSR_MHPMCOUNTER12H 0xb8c +#define CSR_MHPMCOUNTER13H 0xb8d +#define CSR_MHPMCOUNTER14H 0xb8e +#define CSR_MHPMCOUNTER15H 0xb8f +#define CSR_MHPMCOUNTER16H 0xb90 +#define CSR_MHPMCOUNTER17H 0xb91 +#define CSR_MHPMCOUNTER18H 0xb92 +#define CSR_MHPMCOUNTER19H 0xb93 +#define CSR_MHPMCOUNTER20H 0xb94 +#define CSR_MHPMCOUNTER21H 0xb95 +#define CSR_MHPMCOUNTER22H 0xb96 +#define CSR_MHPMCOUNTER23H 0xb97 +#define CSR_MHPMCOUNTER24H 0xb98 +#define CSR_MHPMCOUNTER25H 0xb99 +#define CSR_MHPMCOUNTER26H 0xb9a +#define CSR_MHPMCOUNTER27H 0xb9b +#define CSR_MHPMCOUNTER28H 0xb9c +#define CSR_MHPMCOUNTER29H 0xb9d +#define CSR_MHPMCOUNTER30H 0xb9e +#define CSR_MHPMCOUNTER31H 0xb9f + +#define CSR_CYCLE 0xc00 +#define CSR_TIME 0xc01 +#define CSR_INSTRET 0xc02 +#define CSR_HPMCOUNTER3 0xc03 +#define CSR_HPMCOUNTER4 0xc04 +#define CSR_HPMCOUNTER5 0xc05 +#define CSR_HPMCOUNTER6 0xc06 +#define CSR_HPMCOUNTER7 0xc07 +#define CSR_HPMCOUNTER8 0xc08 +#define CSR_HPMCOUNTER9 0xc09 +#define CSR_HPMCOUNTER10 0xc0a +#define CSR_HPMCOUNTER11 0xc0b +#define CSR_HPMCOUNTER12 0xc0c +#define CSR_HPMCOUNTER13 0xc0d +#define CSR_HPMCOUNTER14 0xc0e +#define CSR_HPMCOUNTER15 0xc0f +#define CSR_HPMCOUNTER16 0xc10 +#define CSR_HPMCOUNTER17 0xc11 +#define CSR_HPMCOUNTER18 0xc12 +#define CSR_HPMCOUNTER19 0xc13 +#define CSR_HPMCOUNTER20 0xc14 +#define CSR_HPMCOUNTER21 0xc15 +#define CSR_HPMCOUNTER22 0xc16 +#define CSR_HPMCOUNTER23 0xc17 +#define CSR_HPMCOUNTER24 0xc18 +#define CSR_HPMCOUNTER25 0xc19 +#define CSR_HPMCOUNTER26 0xc1a +#define CSR_HPMCOUNTER27 0xc1b +#define CSR_HPMCOUNTER28 0xc1c +#define CSR_HPMCOUNTER29 0xc1d +#define CSR_HPMCOUNTER30 0xc1e +#define CSR_HPMCOUNTER31 0xc1f +#define CSR_CYCLEH 0xc80 +#define CSR_TIMEH 0xc81 +#define CSR_INSTRETH 0xc82 +#define CSR_HPMCOUNTER3H 0xc83 +#define CSR_HPMCOUNTER4H 0xc84 +#define CSR_HPMCOUNTER5H 0xc85 +#define CSR_HPMCOUNTER6H 0xc86 +#define CSR_HPMCOUNTER7H 0xc87 +#define CSR_HPMCOUNTER8H 0xc88 +#define CSR_HPMCOUNTER9H 0xc89 +#define CSR_HPMCOUNTER10H 0xc8a +#define CSR_HPMCOUNTER11H 0xc8b +#define CSR_HPMCOUNTER12H 0xc8c +#define CSR_HPMCOUNTER13H 0xc8d +#define CSR_HPMCOUNTER14H 0xc8e +#define CSR_HPMCOUNTER15H 0xc8f +#define CSR_HPMCOUNTER16H 0xc90 +#define CSR_HPMCOUNTER17H 0xc91 +#define CSR_HPMCOUNTER18H 0xc92 +#define CSR_HPMCOUNTER19H 0xc93 +#define CSR_HPMCOUNTER20H 0xc94 +#define CSR_HPMCOUNTER21H 0xc95 +#define CSR_HPMCOUNTER22H 0xc96 +#define CSR_HPMCOUNTER23H 0xc97 +#define CSR_HPMCOUNTER24H 0xc98 +#define CSR_HPMCOUNTER25H 0xc99 +#define CSR_HPMCOUNTER26H 0xc9a +#define CSR_HPMCOUNTER27H 0xc9b +#define CSR_HPMCOUNTER28H 0xc9c +#define CSR_HPMCOUNTER29H 0xc9d +#define CSR_HPMCOUNTER30H 0xc9e +#define CSR_HPMCOUNTER31H 0xc9f + +#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 +#define CSR_MHARTID 0xf14 + #endif /* __riscv */ #endif /* RISCV_CSR_ENCODING_H */ diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h index 4d5d623725e..a3a342c6e1c 100644 --- a/arch/riscv/include/asm/global_data.h +++ b/arch/riscv/include/asm/global_data.h @@ -12,6 +12,10 @@ /* Architecture-specific global data */ struct arch_global_data { + long boot_hart; /* boot hart id */ +#ifdef CONFIG_SIFIVE_CLINT + void __iomem *clint; /* clint base address */ +#endif }; #include <asm-generic/global_data.h> diff --git a/arch/riscv/include/asm/syscon.h b/arch/riscv/include/asm/syscon.h new file mode 100644 index 00000000000..d311ee6b45f --- /dev/null +++ b/arch/riscv/include/asm/syscon.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef _ASM_SYSCON_H +#define _ASM_SYSCON_H + +/* + * System controllers in a RISC-V system + * + * So far only SiFive's Core Local Interruptor (CLINT) is defined. + */ +enum { + RISCV_NONE, + RISCV_SYSCON_CLINT, /* Core Local Interruptor (CLINT) */ +}; + +#endif /* _ASM_SYSCON_H */ diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index b58db897522..edfa61690c7 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -9,6 +9,8 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_GO) += boot.o obj-y += cache.o +obj-$(CONFIG_RISCV_RDTIME) += rdtime.o +obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o obj-y += interrupts.o obj-y += reset.o obj-y += setjmp.o diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c new file mode 100644 index 00000000000..e0b71f56919 --- /dev/null +++ b/arch/riscv/lib/asm-offsets.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + * + * From arch/x86/lib/asm-offsets.c + * + * This program is used to generate definitions needed by + * assembly language modules. + */ + +#include <common.h> +#include <linux/kbuild.h> + +int main(void) +{ + DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart)); + + return 0; +} diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 124aeefff83..f36b8702ef3 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -86,14 +86,14 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) bootstage_mark(BOOTSTAGE_ID_RUN_OS); - debug("## Transferring control to Linux (at address %08lx) ...\n", + debug("## Transferring control to kernel (at address %08lx) ...\n", (ulong)kernel); announce_and_cleanup(fake); if (!fake) { if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) - kernel(csr_read(mhartid), images->ft_addr); + kernel(gd->arch.boot_hart, images->ft_addr); } } @@ -118,3 +118,9 @@ int do_bootm_linux(int flag, int argc, char * const argv[], boot_jump_linux(images, flag); return 0; } + +int do_bootm_vxworks(int flag, int argc, char * const argv[], + bootm_headers_t *images) +{ + return do_bootm_linux(flag, argc, argv, images); +} diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c index 3aff0069773..e185933b01e 100644 --- a/arch/riscv/lib/interrupts.c +++ b/arch/riscv/lib/interrupts.c @@ -12,7 +12,36 @@ #include <asm/system.h> #include <asm/encoding.h> -static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs); +static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs) +{ + static const char * const exception_code[] = { + "Instruction address misaligned", + "Instruction access fault", + "Illegal instruction", + "Breakpoint", + "Load address misaligned", + "Load access fault", + "Store/AMO address misaligned", + "Store/AMO access fault", + "Environment call from U-mode", + "Environment call from S-mode", + "Reserved", + "Environment call from M-mode", + "Instruction page fault", + "Load page fault", + "Reserved", + "Store/AMO page fault", + }; + + if (code < ARRAY_SIZE(exception_code)) { + printf("exception code: %ld , %s , epc %lx , ra %lx\n", + code, exception_code[code], epc, regs->ra); + } else { + printf("Reserved\n"); + } + + hang(); +} int interrupt_init(void) { @@ -72,34 +101,3 @@ __attribute__((weak)) void external_interrupt(struct pt_regs *regs) __attribute__((weak)) void timer_interrupt(struct pt_regs *regs) { } - -static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs) -{ - static const char * const exception_code[] = { - "Instruction address misaligned", - "Instruction access fault", - "Illegal instruction", - "Breakpoint", - "Load address misaligned", - "Load access fault", - "Store/AMO address misaligned", - "Store/AMO access fault", - "Environment call from U-mode", - "Environment call from S-mode", - "Reserved", - "Environment call from M-mode", - "Instruction page fault", - "Load page fault", - "Reserved", - "Store/AMO page fault", - }; - - if (code < ARRAY_SIZE(exception_code)) { - printf("exception code: %ld , %s , epc %lx , ra %lx\n", - code, exception_code[code], epc, regs->ra); - } else { - printf("Reserved\n"); - } - - hang(); -} diff --git a/arch/riscv/lib/rdtime.c b/arch/riscv/lib/rdtime.c new file mode 100644 index 00000000000..e128d7fce69 --- /dev/null +++ b/arch/riscv/lib/rdtime.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Anup Patel <anup@brainfault.org> + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + * + * The riscv_get_time() API implementation that is using the + * standard rdtime instruction. + */ + +#include <common.h> + +/* Implement the API required by RISC-V timer driver */ +int riscv_get_time(u64 *time) +{ +#ifdef CONFIG_64BIT + u64 n; + + __asm__ __volatile__ ( + "rdtime %0" + : "=r" (n)); + + *time = n; +#else + u32 lo, hi, tmp; + + __asm__ __volatile__ ( + "1:\n" + "rdtimeh %0\n" + "rdtime %1\n" + "rdtimeh %2\n" + "bne %0, %2, 1b" + : "=&r" (hi), "=&r" (lo), "=&r" (tmp)); + + *time = ((u64)hi << 32) | lo; +#endif + + return 0; +} diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c new file mode 100644 index 00000000000..d24e0d585b5 --- /dev/null +++ b/arch/riscv/lib/sifive_clint.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + * + * U-Boot syscon driver for SiFive's Core Local Interruptor (CLINT). + * The CLINT block holds memory-mapped control and status registers + * associated with software and timer interrupts. + */ + +#include <common.h> +#include <dm.h> +#include <regmap.h> +#include <syscon.h> +#include <asm/io.h> +#include <asm/syscon.h> + +/* MSIP registers */ +#define MSIP_REG(base, hart) ((ulong)(base) + (hart) * 4) +/* mtime compare register */ +#define MTIMECMP_REG(base, hart) ((ulong)(base) + 0x4000 + (hart) * 8) +/* mtime register */ +#define MTIME_REG(base) ((ulong)(base) + 0xbff8) + +DECLARE_GLOBAL_DATA_PTR; + +#define CLINT_BASE_GET(void) \ + do { \ + long *ret; \ + \ + if (!gd->arch.clint) { \ + ret = syscon_get_first_range(RISCV_SYSCON_CLINT); \ + if (IS_ERR(ret)) \ + return PTR_ERR(ret); \ + gd->arch.clint = ret; \ + } \ + } while (0) + +int riscv_get_time(u64 *time) +{ + CLINT_BASE_GET(); + + *time = readq((void __iomem *)MTIME_REG(gd->arch.clint)); + + return 0; +} + +int riscv_set_timecmp(int hart, u64 cmp) +{ + CLINT_BASE_GET(); + + writeq(cmp, (void __iomem *)MTIMECMP_REG(gd->arch.clint, hart)); + + return 0; +} + +int riscv_send_ipi(int hart) +{ + CLINT_BASE_GET(); + + writel(1, (void __iomem *)MSIP_REG(gd->arch.clint, hart)); + + return 0; +} + +int riscv_clear_ipi(int hart) +{ + CLINT_BASE_GET(); + + writel(0, (void __iomem *)MSIP_REG(gd->arch.clint, hart)); + + return 0; +} + +static const struct udevice_id sifive_clint_ids[] = { + { .compatible = "riscv,clint0", .data = RISCV_SYSCON_CLINT }, + { } +}; + +U_BOOT_DRIVER(sifive_clint) = { + .name = "sifive_clint", + .id = UCLASS_SYSCON, + .of_match = sifive_clint_ids, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/arch/sandbox/cpu/sdl.c b/arch/sandbox/cpu/sdl.c index c7a8d945492..f668f5379a4 100644 --- a/arch/sandbox/cpu/sdl.c +++ b/arch/sandbox/cpu/sdl.c @@ -4,13 +4,24 @@ */ #include <errno.h> +#include <unistd.h> #include <linux/input.h> #include <SDL/SDL.h> -#include <sound.h> #include <asm/state.h> -enum { - SAMPLE_RATE = 22050, +/** + * struct buf_info - a data buffer holding audio data + * + * @pos: Current position playing in audio buffer + * @size: Size of data in audio buffer (0=empty) + * @alloced: Allocated size of audio buffer (max size it can hold) + * @data: Audio data + */ +struct buf_info { + uint pos; + uint size; + uint alloced; + uint8_t *data; }; static struct sdl_info { @@ -20,12 +31,12 @@ static struct sdl_info { int depth; int pitch; uint frequency; - uint audio_pos; - uint audio_size; uint sample_rate; - uint8_t *audio_data; bool audio_active; bool inited; + int cur_buf; + struct buf_info buf[2]; + bool running; } sdl; static void sandbox_sdl_poll_events(void) @@ -243,24 +254,37 @@ int sandbox_sdl_key_pressed(int keycode) void sandbox_sdl_fill_audio(void *udata, Uint8 *stream, int len) { + struct buf_info *buf; int avail; + int i; - avail = sdl.audio_size - sdl.audio_pos; - if (avail < len) - len = avail; - - SDL_MixAudio(stream, sdl.audio_data + sdl.audio_pos, len, - SDL_MIX_MAXVOLUME); - sdl.audio_pos += len; - - /* Loop if we are at the end */ - if (sdl.audio_pos == sdl.audio_size) - sdl.audio_pos = 0; + for (i = 0; i < 2; i++) { + buf = &sdl.buf[sdl.cur_buf]; + avail = buf->size - buf->pos; + if (avail <= 0) { + sdl.cur_buf = 1 - sdl.cur_buf; + continue; + } + if (avail > len) + avail = len; + + SDL_MixAudio(stream, buf->data + buf->pos, avail, + SDL_MIX_MAXVOLUME); + buf->pos += avail; + len -= avail; + + /* Move to next buffer if we are at the end */ + if (buf->pos == buf->size) + buf->size = 0; + else + break; + } } -int sandbox_sdl_sound_init(void) +int sandbox_sdl_sound_init(int rate, int channels) { SDL_AudioSpec wanted; + int i; if (sandbox_sdl_ensure_init()) return -1; @@ -269,20 +293,27 @@ int sandbox_sdl_sound_init(void) return 0; /* Set the audio format */ - wanted.freq = SAMPLE_RATE; + wanted.freq = rate; wanted.format = AUDIO_S16; - wanted.channels = 1; /* 1 = mono, 2 = stereo */ + wanted.channels = channels; wanted.samples = 1024; /* Good low-latency value for callback */ wanted.callback = sandbox_sdl_fill_audio; wanted.userdata = NULL; - sdl.audio_size = sizeof(uint16_t) * wanted.freq; - sdl.audio_data = malloc(sdl.audio_size); - if (!sdl.audio_data) { - printf("%s: Out of memory\n", __func__); - return -1; + for (i = 0; i < 2; i++) { + struct buf_info *buf = &sdl.buf[i]; + + buf->alloced = sizeof(uint16_t) * wanted.freq * wanted.channels; + buf->data = malloc(buf->alloced); + if (!buf->data) { + printf("%s: Out of memory\n", __func__); + if (i == 1) + free(sdl.buf[0].data); + return -1; + } + buf->pos = 0; + buf->size = 0; } - sdl.audio_pos = 0; if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { printf("Unable to initialize SDL audio: %s\n", SDL_GetError()); @@ -296,33 +327,50 @@ int sandbox_sdl_sound_init(void) } sdl.audio_active = true; sdl.sample_rate = wanted.freq; + sdl.cur_buf = 0; + sdl.running = 0; return 0; err: - free(sdl.audio_data); + for (i = 0; i < 2; i++) + free(sdl.buf[i].data); return -1; } -int sandbox_sdl_sound_start(uint frequency) +int sandbox_sdl_sound_play(const void *data, uint size) { + struct buf_info *buf; + if (!sdl.audio_active) - return -1; - sdl.frequency = frequency; - sound_create_square_wave(sdl.sample_rate, - (unsigned short *)sdl.audio_data, - sdl.audio_size, frequency); - sdl.audio_pos = 0; - SDL_PauseAudio(0); + return 0; + + buf = &sdl.buf[0]; + if (buf->size) + buf = &sdl.buf[1]; + while (buf->size) + usleep(1000); + + if (size > buf->alloced) + return -E2BIG; + + memcpy(buf->data, data, size); + buf->size = size; + buf->pos = 0; + if (!sdl.running) { + SDL_PauseAudio(0); + sdl.running = 1; + } return 0; } int sandbox_sdl_sound_stop(void) { - if (!sdl.audio_active) - return -1; - SDL_PauseAudio(1); + if (sdl.running) { + SDL_PauseAudio(1); + sdl.running = 0; + } return 0; } diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts index ce3c88c221d..ae3189ec8cf 100644 --- a/arch/sandbox/dts/sandbox.dts +++ b/arch/sandbox/dts/sandbox.dts @@ -18,6 +18,11 @@ stdout-path = "/serial"; }; + audio: audio-codec { + compatible = "sandbox,audio-codec"; + #sound-dai-cells = <1>; + }; + cros_ec: cros-ec { reg = <0 0>; u-boot,dm-pre-reloc; @@ -127,6 +132,11 @@ }; }; + i2s: i2s { + compatible = "sandbox,i2s"; + #sound-dai-cells = <1>; + }; + lcd { u-boot,dm-pre-reloc; compatible = "sandbox,lcd-sdl"; @@ -190,6 +200,17 @@ compatible = "sandbox,reset"; }; + sound { + compatible = "sandbox,sound"; + cpu { + sound-dai = <&i2s 0>; + }; + + codec { + sound-dai = <&audio 0>; + }; + }; + spi@0 { u-boot,dm-pre-reloc; #address-cells = <1>; diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 6b1c2692baa..3790b4c5208 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -42,6 +42,11 @@ osd0 = "/osd"; }; + audio: audio-codec { + compatible = "sandbox,audio-codec"; + #sound-dai-cells = <1>; + }; + cros_ec: cros-ec { reg = <0 0>; compatible = "google,cros-ec-sandbox"; @@ -82,6 +87,8 @@ test2-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 6 1 3 2 1>, <&gpio_b 7 2 3 2 1>, <&gpio_b 8 4 3 2 1>, <&gpio_b 9 0xc 3 2 1>; + int-value = <1234>; + uint-value = <(-1234)>; }; junk { @@ -373,6 +380,11 @@ u-boot,dm-pre-reloc; }; + i2s: i2s { + compatible = "sandbox,i2s"; + #sound-dai-cells = <1>; + }; + misc-test { compatible = "sandbox,misc_sandbox"; }; @@ -528,6 +540,17 @@ compatible = "sandbox,smem"; }; + sound { + compatible = "sandbox,sound"; + cpu { + sound-dai = <&i2s 0>; + }; + + codec { + sound-dai = <&audio 0>; + }; + }; + spi@0 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/sandbox/include/asm/sdl.h b/arch/sandbox/include/asm/sdl.h index 1c4380c592a..1027b59e732 100644 --- a/arch/sandbox/include/asm/sdl.h +++ b/arch/sandbox/include/asm/sdl.h @@ -54,12 +54,12 @@ int sandbox_sdl_scan_keys(int key[], int max_keys); int sandbox_sdl_key_pressed(int keycode); /** - * sandbox_sdl_sound_start() - start playing a sound + * sandbox_sdl_sound_play() - Play a sound * - * @frequency: Frequency of sounds in Hertz - * @return 0 if OK, -ENODEV if no sound is available + * @data: Data to play (typically 16-bit) + * @count: Number of bytes in data */ -int sandbox_sdl_sound_start(uint frequency); +int sandbox_sdl_sound_play(const void *data, uint count); /** * sandbox_sdl_sound_stop() - stop playing a sound @@ -71,9 +71,11 @@ int sandbox_sdl_sound_stop(void); /** * sandbox_sdl_sound_init() - set up the sound system * + * @rate: Sample rate to use + * @channels: Number of channels to use (1=mono, 2=stereo) * @return 0 if OK, -ENODEV if no sound is available */ -int sandbox_sdl_sound_init(void); +int sandbox_sdl_sound_init(int rate, int channels); #else static inline int sandbox_sdl_init_display(int width, int height, @@ -102,12 +104,17 @@ static inline int sandbox_sdl_sound_start(uint frequency) return -ENODEV; } +int sandbox_sdl_sound_play(const void *data, uint count) +{ + return -ENODEV; +} + static inline int sandbox_sdl_sound_stop(void) { return -ENODEV; } -static inline int sandbox_sdl_sound_init(void) +int sandbox_sdl_sound_init(int rate, int channels) { return -ENODEV; } diff --git a/arch/sandbox/include/asm/sound.h b/arch/sandbox/include/asm/sound.h deleted file mode 100644 index a6015b0f60f..00000000000 --- a/arch/sandbox/include/asm/sound.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 2013 Google, Inc - */ - -#ifndef __SANDBOX_SOUND_H -#define __SANDBOX_SOUND_H - -int sound_play(unsigned int msec, unsigned int frequency); - -int sound_init(const void *blob); - -#endif diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 5e818392959..74f96188220 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -121,4 +121,44 @@ int sandbox_pwm_get_config(struct udevice *dev, uint channel, uint *period_nsp, */ void sandbox_sf_set_block_protect(struct udevice *dev, int bp_mask); +/** + * sandbox_get_codec_params() - Read back codec parameters + * + * This reads back the parameters set by audio_codec_set_params() for the + * sandbox audio driver. Arguments are as for that function. + */ +void sandbox_get_codec_params(struct udevice *dev, int *interfacep, int *ratep, + int *mclk_freqp, int *bits_per_samplep, + uint *channelsp); + +/** + * sandbox_get_i2s_sum() - Read back the sum of the audio data so far + * + * This data is provided to the sandbox driver by the I2S tx_data() method. + * + * @dev: Device to check + * @return sum of audio data + */ +int sandbox_get_i2s_sum(struct udevice *dev); + +/** + * sandbox_get_setup_called() - Returns the number of times setup(*) was called + * + * This is used in the sound test + * + * @dev: Device to check + * @return call count for the setup() method + */ +int sandbox_get_setup_called(struct udevice *dev); + +/** + * sandbox_get_sound_sum() - Read back the sum of the sound data so far + * + * This data is provided to the sandbox driver by the sound play() method. + * + * @dev: Device to check + * @return sum of audio data + */ +int sandbox_get_sound_sum(struct udevice *dev); + #endif diff --git a/board/AndesTech/ax25-ae350/Kconfig b/board/AndesTech/ax25-ae350/Kconfig index bb69ea34892..44cb302f708 100644 --- a/board/AndesTech/ax25-ae350/Kconfig +++ b/board/AndesTech/ax25-ae350/Kconfig @@ -21,4 +21,8 @@ config ENV_SIZE config ENV_OFFSET default 0x140000 if ENV_IS_IN_SPI_FLASH +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select RISCV_NDS + endif diff --git a/board/AndesTech/ax25-ae350/MAINTAINERS b/board/AndesTech/ax25-ae350/MAINTAINERS index d87446ee1c3..b0a99e4ac40 100644 --- a/board/AndesTech/ax25-ae350/MAINTAINERS +++ b/board/AndesTech/ax25-ae350/MAINTAINERS @@ -3,6 +3,5 @@ M: Rick Chen <rick@andestech.com> S: Maintained F: board/AndesTech/ax25-ae350/ F: include/configs/ax25-ae350.h -F: configs/a25-ae350_32_defconfig -F: configs/ax25-ae350_64_defconfig -F: configs/ax25-ae350_defconfig +F: configs/ae350_rv32_defconfig +F: configs/ae350_rv64_defconfig diff --git a/board/elgin/elgin_rv1108/Kconfig b/board/elgin/elgin_rv1108/Kconfig new file mode 100644 index 00000000000..be9243164aa --- /dev/null +++ b/board/elgin/elgin_rv1108/Kconfig @@ -0,0 +1,15 @@ +if TARGET_ELGIN_RV1108 + +config SYS_BOARD + default "elgin_rv1108" + +config SYS_VENDOR + default "elgin" + +config SYS_CONFIG_NAME + default "elgin_rv1108" + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + +endif diff --git a/board/elgin/elgin_rv1108/MAINTAINERS b/board/elgin/elgin_rv1108/MAINTAINERS new file mode 100644 index 00000000000..7747490163a --- /dev/null +++ b/board/elgin/elgin_rv1108/MAINTAINERS @@ -0,0 +1,6 @@ +ELGIN-RV1108 +M: Otavio Salvador <otavio@ossystems.com.br> +S: Maintained +F: board/elgin/elgin_rv1108 +F: include/configs/elgin_rv1108.h +F: configs/elgin-rv1108_defconfig diff --git a/board/elgin/elgin_rv1108/Makefile b/board/elgin/elgin_rv1108/Makefile new file mode 100644 index 00000000000..382218006a6 --- /dev/null +++ b/board/elgin/elgin_rv1108/Makefile @@ -0,0 +1,7 @@ +# +# (C) Copyright 2016 Rockchip Electronics Co., Ltd +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += elgin_rv1108.o diff --git a/board/elgin/elgin_rv1108/elgin_rv1108.c b/board/elgin/elgin_rv1108/elgin_rv1108.c new file mode 100644 index 00000000000..3abc5144129 --- /dev/null +++ b/board/elgin/elgin_rv1108/elgin_rv1108.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C)Copyright 2016 Rockchip Electronics Co., Ltd + * Authors: Andy Yan <andy.yan@rock-chips.com> + */ + +#include <common.h> +#include <asm/io.h> +#include <fdtdec.h> +#include <asm/arch/grf_rv1108.h> +#include <asm/arch/hardware.h> +#include <asm/gpio.h> + +DECLARE_GLOBAL_DATA_PTR; + +int mach_cpu_init(void) +{ + int node; + struct rv1108_grf *grf; + enum { + GPIO3C3_SHIFT = 6, + GPIO3C3_MASK = 3 << GPIO3C3_SHIFT, + + GPIO3C2_SHIFT = 4, + GPIO3C2_MASK = 3 << GPIO3C2_SHIFT, + + GPIO2D2_SHIFT = 4, + GPIO2D2_MASK = 3 << GPIO2D2_SHIFT, + GPIO2D2_GPIO = 0, + GPIO2D2_UART2_SOUT_M0, + + GPIO2D1_SHIFT = 2, + GPIO2D1_MASK = 3 << GPIO2D1_SHIFT, + GPIO2D1_GPIO = 0, + GPIO2D1_UART2_SIN_M0, + }; + + node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "rockchip,rv1108-grf"); + grf = (struct rv1108_grf *)fdtdec_get_addr(gd->fdt_blob, node, "reg"); + + /* Elgin board use UART2 m0 for debug*/ + rk_clrsetreg(&grf->gpio2d_iomux, + GPIO2D2_MASK | GPIO2D1_MASK, + GPIO2D2_UART2_SOUT_M0 << GPIO2D2_SHIFT | + GPIO2D1_UART2_SIN_M0 << GPIO2D1_SHIFT); + rk_clrreg(&grf->gpio3c_iomux, GPIO3C3_MASK | GPIO3C2_MASK); + + return 0; +} + +#define MODEM_ENABLE_GPIO 111 + +int board_init(void) +{ + gpio_request(MODEM_ENABLE_GPIO, "modem_enable"); + gpio_direction_output(MODEM_ENABLE_GPIO, 0); + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = 0x8000000; + + return 0; +} + +int dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = 0x60000000; + gd->bd->bi_dram[0].size = 0x8000000; + + return 0; +} diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig index 56bb5337d4c..0d865acf100 100644 --- a/board/emulation/qemu-riscv/Kconfig +++ b/board/emulation/qemu-riscv/Kconfig @@ -18,6 +18,7 @@ config SYS_TEXT_BASE config BOARD_SPECIFIC_OPTIONS # dummy def_bool y + select QEMU_RISCV imply SYS_NS16550 imply VIRTIO_MMIO imply VIRTIO_NET @@ -32,5 +33,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy imply CMD_FAT imply BOARD_LATE_INIT imply OF_BOARD_SETUP + imply SIFIVE_SERIAL endif diff --git a/board/hisilicon/poplar/MAINTAINERS b/board/hisilicon/poplar/MAINTAINERS index 0cc01c8321e..622e5cb18ed 100644 --- a/board/hisilicon/poplar/MAINTAINERS +++ b/board/hisilicon/poplar/MAINTAINERS @@ -1,5 +1,6 @@ Poplar BOARD M: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> +M: Shawn Guo <shawn.guo@linaro.org> S: Maintained F: board/hisilicon/poplar F: include/configs/poplar.h diff --git a/board/hisilicon/poplar/poplar.c b/board/hisilicon/poplar/poplar.c index 9e8eac78388..8adc750962a 100644 --- a/board/hisilicon/poplar/poplar.c +++ b/board/hisilicon/poplar/poplar.c @@ -35,6 +35,7 @@ static struct mm_region poplar_mem_map[] = { struct mm_region *mem_map = poplar_mem_map; +#if !CONFIG_IS_ENABLED(OF_CONTROL) static const struct pl01x_serial_platdata serial_platdata = { .base = REG_BASE_UART0, .type = TYPE_PL010, @@ -45,6 +46,7 @@ U_BOOT_DEVICE(poplar_serial) = { .name = "serial_pl01x", .platdata = &serial_platdata, }; +#endif int checkboard(void) { diff --git a/board/imgtec/ci20/Kconfig b/board/imgtec/ci20/Kconfig new file mode 100644 index 00000000000..82bf65d64f1 --- /dev/null +++ b/board/imgtec/ci20/Kconfig @@ -0,0 +1,15 @@ +if TARGET_JZ4780_CI20 + +config SYS_BOARD + default "ci20" + +config SYS_VENDOR + default "imgtec" + +config SYS_CONFIG_NAME + default "ci20" + +config SYS_TEXT_BASE + default 0x80000000 + +endif diff --git a/board/imgtec/ci20/MAINTAINERS b/board/imgtec/ci20/MAINTAINERS new file mode 100644 index 00000000000..dca6bf35376 --- /dev/null +++ b/board/imgtec/ci20/MAINTAINERS @@ -0,0 +1,6 @@ +Creator CI20 BOARD +M: Ezequiel Garcia <ezequiel@collabora.com> +S: Maintained +F: board/imgtec/ci20/ +F: include/configs/ci20.h +F: configs/ci20_mmc_defconfig diff --git a/board/imgtec/ci20/Makefile b/board/imgtec/ci20/Makefile new file mode 100644 index 00000000000..7843b467918 --- /dev/null +++ b/board/imgtec/ci20/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-y := ci20.o diff --git a/board/imgtec/ci20/README b/board/imgtec/ci20/README new file mode 100644 index 00000000000..07d89d7e2b3 --- /dev/null +++ b/board/imgtec/ci20/README @@ -0,0 +1,10 @@ +CI20 U-Boot + +Installation to an SD card: + Repartition your card with an MBR such that the first partition starts at an + offset of no less than 270KB. Then install U-Boot SPL & the full U-Boot image + to the card like so: + + dd if=spl/u-boot-spl.bin of=/dev/sdX obs=512 seek=1 + dd if=u-boot-dtb.img of=/dev/sdX obs=1K seek=14 + sync diff --git a/board/imgtec/ci20/ci20.c b/board/imgtec/ci20/ci20.c new file mode 100644 index 00000000000..9811ef559fc --- /dev/null +++ b/board/imgtec/ci20/ci20.c @@ -0,0 +1,362 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * CI20 setup code + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + */ + +#include <common.h> +#include <environment.h> +#include <net.h> +#include <netdev.h> +#include <asm/io.h> +#include <asm/gpio.h> +#include <mach/jz4780.h> +#include <mach/jz4780_dram.h> +#include <mach/jz4780_gpio.h> + +struct ci20_otp { + u32 serial_number; + u32 date; + u8 manufacturer[2]; + u8 mac[6]; +} __packed; + +static void ci20_mux_mmc(void) +{ + void __iomem *gpio_regs = (void __iomem *)GPIO_BASE; + + /* setup MSC1 pins */ + writel(0x30f00000, gpio_regs + GPIO_PXINTC(4)); + writel(0x30f00000, gpio_regs + GPIO_PXMASKC(4)); + writel(0x30f00000, gpio_regs + GPIO_PXPAT1C(4)); + writel(0x30f00000, gpio_regs + GPIO_PXPAT0C(4)); + writel(0x30f00000, gpio_regs + GPIO_PXPENC(4)); + jz4780_clk_ungate_mmc(); +} + +#ifndef CONFIG_SPL_BUILD + +static void ci20_mux_eth(void) +{ + void __iomem *gpio_regs = (void __iomem *)GPIO_BASE; + +#ifdef CONFIG_NAND + /* setup pins (some already setup for NAND) */ + writel(0x04030000, gpio_regs + GPIO_PXINTC(0)); + writel(0x04030000, gpio_regs + GPIO_PXMASKC(0)); + writel(0x04030000, gpio_regs + GPIO_PXPAT1C(0)); + writel(0x04030000, gpio_regs + GPIO_PXPAT0C(0)); + writel(0x04030000, gpio_regs + GPIO_PXPENS(0)); +#else + /* setup pins (as above +NAND CS +RD/WE +SDx +SAx) */ + writel(0x0dff00ff, gpio_regs + GPIO_PXINTC(0)); + writel(0x0dff00ff, gpio_regs + GPIO_PXMASKC(0)); + writel(0x0dff00ff, gpio_regs + GPIO_PXPAT1C(0)); + writel(0x0dff00ff, gpio_regs + GPIO_PXPAT0C(0)); + writel(0x0dff00ff, gpio_regs + GPIO_PXPENS(0)); + writel(0x00000003, gpio_regs + GPIO_PXINTC(1)); + writel(0x00000003, gpio_regs + GPIO_PXMASKC(1)); + writel(0x00000003, gpio_regs + GPIO_PXPAT1C(1)); + writel(0x00000003, gpio_regs + GPIO_PXPAT0C(1)); + writel(0x00000003, gpio_regs + GPIO_PXPENS(1)); +#endif +} + +static void ci20_mux_jtag(void) +{ +#ifdef CONFIG_JTAG + void __iomem *gpio_regs = (void __iomem *)GPIO_BASE; + + /* enable JTAG */ + writel(3 << 30, gpio_regs + GPIO_PXINTC(0)); + writel(3 << 30, gpio_regs + GPIO_PXMASKC(0)); + writel(3 << 30, gpio_regs + GPIO_PXPAT1C(0)); + writel(3 << 30, gpio_regs + GPIO_PXPAT0C(0)); +#endif +} + +static void ci20_mux_nand(void) +{ + void __iomem *gpio_regs = (void __iomem *)GPIO_BASE; + + /* setup pins */ + writel(0x002c00ff, gpio_regs + GPIO_PXINTC(0)); + writel(0x002c00ff, gpio_regs + GPIO_PXMASKC(0)); + writel(0x002c00ff, gpio_regs + GPIO_PXPAT1C(0)); + writel(0x002c00ff, gpio_regs + GPIO_PXPAT0C(0)); + writel(0x002c00ff, gpio_regs + GPIO_PXPENS(0)); + writel(0x00000003, gpio_regs + GPIO_PXINTC(1)); + writel(0x00000003, gpio_regs + GPIO_PXMASKC(1)); + writel(0x00000003, gpio_regs + GPIO_PXPAT1C(1)); + writel(0x00000003, gpio_regs + GPIO_PXPAT0C(1)); + writel(0x00000003, gpio_regs + GPIO_PXPENS(1)); + + /* FRB0_N */ + jz47xx_gpio_direction_input(JZ_GPIO(0, 20)); + writel(20, gpio_regs + GPIO_PXPENS(0)); + + /* disable write protect */ + jz47xx_gpio_direction_output(JZ_GPIO(5, 22), 1); +} + +static void ci20_mux_uart(void) +{ + void __iomem *gpio_regs = (void __iomem *)GPIO_BASE; + + /* UART0 */ + writel(0x9, gpio_regs + GPIO_PXINTC(5)); + writel(0x9, gpio_regs + GPIO_PXMASKC(5)); + writel(0x9, gpio_regs + GPIO_PXPAT1C(5)); + writel(0x9, gpio_regs + GPIO_PXPAT0C(5)); + writel(0x9, gpio_regs + GPIO_PXPENC(5)); + jz4780_clk_ungate_uart(0); + + /* UART 1 and 2 */ + jz4780_clk_ungate_uart(1); + jz4780_clk_ungate_uart(2); + +#ifndef CONFIG_JTAG + /* UART3 */ + writel(1 << 12, gpio_regs + GPIO_PXINTC(3)); + writel(1 << 12, gpio_regs + GPIO_PXMASKS(3)); + writel(1 << 12, gpio_regs + GPIO_PXPAT1S(3)); + writel(1 << 12, gpio_regs + GPIO_PXPAT0C(3)); + writel(3 << 30, gpio_regs + GPIO_PXINTC(0)); + writel(3 << 30, gpio_regs + GPIO_PXMASKC(0)); + writel(3 << 30, gpio_regs + GPIO_PXPAT1C(0)); + writel(1 << 30, gpio_regs + GPIO_PXPAT0C(0)); + writel(1 << 31, gpio_regs + GPIO_PXPAT0S(0)); + jz4780_clk_ungate_uart(3); +#endif + + /* UART4 */ + writel(0x100400, gpio_regs + GPIO_PXINTC(2)); + writel(0x100400, gpio_regs + GPIO_PXMASKC(2)); + writel(0x100400, gpio_regs + GPIO_PXPAT1S(2)); + writel(0x100400, gpio_regs + GPIO_PXPAT0C(2)); + writel(0x100400, gpio_regs + GPIO_PXPENC(2)); + jz4780_clk_ungate_uart(4); +} + +int board_early_init_f(void) +{ + ci20_mux_jtag(); + ci20_mux_uart(); + + ci20_mux_eth(); + ci20_mux_mmc(); + ci20_mux_nand(); + + /* SYS_POWER_IND high (LED blue, VBUS off) */ + jz47xx_gpio_direction_output(JZ_GPIO(5, 15), 0); + + /* LEDs off */ + jz47xx_gpio_direction_output(JZ_GPIO(2, 0), 0); + jz47xx_gpio_direction_output(JZ_GPIO(2, 1), 0); + jz47xx_gpio_direction_output(JZ_GPIO(2, 2), 0); + jz47xx_gpio_direction_output(JZ_GPIO(2, 3), 0); + + return 0; +} + +int misc_init_r(void) +{ + const u32 efuse_clk = jz4780_clk_get_efuse_clk(); + struct ci20_otp otp; + char manufacturer[3]; + + /* Read the board OTP data */ + jz4780_efuse_init(efuse_clk); + jz4780_efuse_read(0x18, 16, (u8 *)&otp); + + /* Set MAC address */ + if (!is_valid_ethaddr(otp.mac)) { + /* no MAC assigned, generate one from the unique chip ID */ + jz4780_efuse_read(0x8, 4, &otp.mac[0]); + jz4780_efuse_read(0x12, 2, &otp.mac[4]); + otp.mac[0] = (otp.mac[0] | 0x02) & ~0x01; + } + eth_env_set_enetaddr("ethaddr", otp.mac); + + /* Put other board information into the environment */ + env_set_ulong("serial#", otp.serial_number); + env_set_ulong("board_date", otp.date); + manufacturer[0] = otp.manufacturer[0]; + manufacturer[1] = otp.manufacturer[1]; + manufacturer[2] = 0; + env_set("board_mfr", manufacturer); + + return 0; +} + +#ifdef CONFIG_DRIVER_DM9000 +int board_eth_init(bd_t *bis) +{ + /* Enable clock */ + jz4780_clk_ungate_ethernet(); + + /* Enable power (PB25) */ + jz47xx_gpio_direction_output(JZ_GPIO(1, 25), 1); + + /* Reset (PF12) */ + mdelay(10); + jz47xx_gpio_direction_output(JZ_GPIO(5, 12), 0); + mdelay(10); + jz47xx_gpio_direction_output(JZ_GPIO(5, 12), 1); + mdelay(10); + + return dm9000_initialize(bis); +} +#endif /* CONFIG_DRIVER_DM9000 */ +#endif + +static u8 ci20_revision(void) +{ + void __iomem *gpio_regs = (void __iomem *)GPIO_BASE; + int val; + + jz47xx_gpio_direction_input(JZ_GPIO(2, 18)); + jz47xx_gpio_direction_input(JZ_GPIO(2, 19)); + + /* Enable pullups */ + writel(BIT(18) | BIT(19), gpio_regs + GPIO_PXPENC(2)); + + /* Read PC18/19 for version */ + val = (!!jz47xx_gpio_get_value(JZ_GPIO(2, 18))) | + ((!!jz47xx_gpio_get_value(JZ_GPIO(2, 19))) << 1); + + if (val == 3) /* Rev 1 boards had no pulldowns - giving 3 */ + return 1; + if (val == 1) /* Rev 2 boards pulldown port C bit 18 giving 1 */ + return 2; + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = sdram_size(0) + sdram_size(1); + return 0; +} + +/* U-Boot common routines */ +int checkboard(void) +{ + printf("Board: Creator CI20 (rev.%d)\n", ci20_revision()); + return 0; +} + +#ifdef CONFIG_SPL_BUILD + +#if defined(CONFIG_SPL_MMC_SUPPORT) +int board_mmc_init(bd_t *bd) +{ + ci20_mux_mmc(); + return jz_mmc_init((void __iomem *)MSC0_BASE); +} +#endif + +static const struct jz4780_ddr_config K4B2G0846Q_48_config = { + .timing = { + (4 << DDRC_TIMING1_TRTP_BIT) | (13 << DDRC_TIMING1_TWTR_BIT) | + (6 << DDRC_TIMING1_TWR_BIT) | (5 << DDRC_TIMING1_TWL_BIT), + + (4 << DDRC_TIMING2_TCCD_BIT) | (15 << DDRC_TIMING2_TRAS_BIT) | + (6 << DDRC_TIMING2_TRCD_BIT) | (6 << DDRC_TIMING2_TRL_BIT), + + (4 << DDRC_TIMING3_ONUM) | (7 << DDRC_TIMING3_TCKSRE_BIT) | + (6 << DDRC_TIMING3_TRP_BIT) | (4 << DDRC_TIMING3_TRRD_BIT) | + (21 << DDRC_TIMING3_TRC_BIT), + + (31 << DDRC_TIMING4_TRFC_BIT) | (1 << DDRC_TIMING4_TRWCOV_BIT) | + (4 << DDRC_TIMING4_TCKE_BIT) | (9 << DDRC_TIMING4_TMINSR_BIT) | + (8 << DDRC_TIMING4_TXP_BIT) | (3 << DDRC_TIMING4_TMRD_BIT), + + (8 << DDRC_TIMING5_TRTW_BIT) | (4 << DDRC_TIMING5_TRDLAT_BIT) | + (4 << DDRC_TIMING5_TWDLAT_BIT), + + (25 << DDRC_TIMING6_TXSRD_BIT) | (12 << DDRC_TIMING6_TFAW_BIT) | + (2 << DDRC_TIMING6_TCFGW_BIT) | (2 << DDRC_TIMING6_TCFGR_BIT), + }, + + /* PHY */ + /* Mode Register 0 */ + .mr0 = 0x420, +#ifdef SDRAM_DISABLE_DLL + .mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS | DDR3_MR1_DLL_DISABLE), +#else + .mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS), +#endif + + .ptr0 = 0x002000d4, + .ptr1 = 0x02230d40, + .ptr2 = 0x04013880, + + .dtpr0 = 0x2a8f6690, + .dtpr1 = 0x00400860, + .dtpr2 = 0x10042a00, + + .pullup = 0x0b, + .pulldn = 0x0b, +}; + +static const struct jz4780_ddr_config H5TQ2G83CFR_48_config = { + .timing = { + (4 << DDRC_TIMING1_TRTP_BIT) | (13 << DDRC_TIMING1_TWTR_BIT) | + (6 << DDRC_TIMING1_TWR_BIT) | (5 << DDRC_TIMING1_TWL_BIT), + + (4 << DDRC_TIMING2_TCCD_BIT) | (16 << DDRC_TIMING2_TRAS_BIT) | + (6 << DDRC_TIMING2_TRCD_BIT) | (6 << DDRC_TIMING2_TRL_BIT), + + (4 << DDRC_TIMING3_ONUM) | (7 << DDRC_TIMING3_TCKSRE_BIT) | + (6 << DDRC_TIMING3_TRP_BIT) | (4 << DDRC_TIMING3_TRRD_BIT) | + (22 << DDRC_TIMING3_TRC_BIT), + + (42 << DDRC_TIMING4_TRFC_BIT) | (1 << DDRC_TIMING4_TRWCOV_BIT) | + (4 << DDRC_TIMING4_TCKE_BIT) | (7 << DDRC_TIMING4_TMINSR_BIT) | + (3 << DDRC_TIMING4_TXP_BIT) | (3 << DDRC_TIMING4_TMRD_BIT), + + (8 << DDRC_TIMING5_TRTW_BIT) | (4 << DDRC_TIMING5_TRDLAT_BIT) | + (4 << DDRC_TIMING5_TWDLAT_BIT), + + (25 << DDRC_TIMING6_TXSRD_BIT) | (20 << DDRC_TIMING6_TFAW_BIT) | + (2 << DDRC_TIMING6_TCFGW_BIT) | (2 << DDRC_TIMING6_TCFGR_BIT), + }, + + /* PHY */ + /* Mode Register 0 */ + .mr0 = 0x420, +#ifdef SDRAM_DISABLE_DLL + .mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS | DDR3_MR1_DLL_DISABLE), +#else + .mr1 = (DDR3_MR1_DIC_7 | DDR3_MR1_RTT_DIS), +#endif + + .ptr0 = 0x002000d4, + .ptr1 = 0x02d30d40, + .ptr2 = 0x04013880, + + .dtpr0 = 0x2c906690, + .dtpr1 = 0x005608a0, + .dtpr2 = 0x10042a00, + + .pullup = 0x0e, + .pulldn = 0x0e, +}; + +#if (CONFIG_SYS_MHZ != 1200) +#error No DDR configuration for CPU speed +#endif + +const struct jz4780_ddr_config *jz4780_get_ddr_config(void) +{ + const int board_revision = ci20_revision(); + + if (board_revision == 2) + return &K4B2G0846Q_48_config; + else /* Fall back to H5TQ2G83CFR RAM */ + return &H5TQ2G83CFR_48_config; +} +#endif diff --git a/board/mscc/luton/Kconfig b/board/mscc/luton/Kconfig new file mode 100644 index 00000000000..e1199808d5b --- /dev/null +++ b/board/mscc/luton/Kconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +if SOC_LUTON + +config SYS_VENDOR + default "mscc" + +config SYS_BOARD + default "luton" + +config SYS_CONFIG_NAME + default "luton" + +endif diff --git a/board/mscc/luton/Makefile b/board/mscc/luton/Makefile new file mode 100644 index 00000000000..b27f7c7739a --- /dev/null +++ b/board/mscc/luton/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +obj-$(CONFIG_SOC_LUTON) := luton.o diff --git a/board/mscc/luton/luton.c b/board/mscc/luton/luton.c new file mode 100644 index 00000000000..41fc6d56a7d --- /dev/null +++ b/board/mscc/luton/luton.c @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <asm/io.h> + +#define MSCC_GPIO_ALT0 0x88 +#define MSCC_GPIO_ALT1 0x8C + +DECLARE_GLOBAL_DATA_PTR; + +void board_debug_uart_init(void) +{ + /* too early for the pinctrl driver, so configure the UART pins here */ + setbits_le32(BASE_DEVCPU_GCB + MSCC_GPIO_ALT0, BIT(30) | BIT(31)); +} + +int board_early_init_r(void) +{ + /* Prepare SPI controller to be used in master mode */ + writel(0, BASE_CFG + ICPU_SW_MODE); + + /* Address of boot parameters */ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE; + return 0; +} diff --git a/board/mscc/ocelot/Kconfig b/board/mscc/ocelot/Kconfig new file mode 100644 index 00000000000..9ddc0880b1a --- /dev/null +++ b/board/mscc/ocelot/Kconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +config SYS_VENDOR + default "mscc" + +if SOC_OCELOT + +config SYS_BOARD + default "ocelot" + +config SYS_CONFIG_NAME + default "ocelot" + +endif diff --git a/board/mscc/ocelot/Makefile b/board/mscc/ocelot/Makefile new file mode 100644 index 00000000000..9f28c812687 --- /dev/null +++ b/board/mscc/ocelot/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +obj-$(CONFIG_SOC_OCELOT) := ocelot.o + diff --git a/board/mscc/ocelot/ocelot.c b/board/mscc/ocelot/ocelot.c new file mode 100644 index 00000000000..d521a619576 --- /dev/null +++ b/board/mscc/ocelot/ocelot.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/addrspace.h> +#include <asm/types.h> +#include <environment.h> +#include <spi.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define MSCC_GPIO_ALT0 0x54 +#define MSCC_GPIO_ALT1 0x58 + +void external_cs_manage(struct udevice *dev, bool enable) +{ + u32 cs = spi_chip_select(dev); + /* IF_SI0_OWNER, select the owner of the SI interface + * Encoding: 0: SI Slave + * 1: SI Boot Master + * 2: SI Master Controller + */ + if (!enable) { + writel(ICPU_SW_MODE_SW_PIN_CTRL_MODE | + ICPU_SW_MODE_SW_SPI_CS(BIT(cs)), BASE_CFG + ICPU_SW_MODE); + clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, + ICPU_GENERAL_CTRL_IF_SI_OWNER_M, + ICPU_GENERAL_CTRL_IF_SI_OWNER(2)); + } else { + writel(0, BASE_CFG + ICPU_SW_MODE); + clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, + ICPU_GENERAL_CTRL_IF_SI_OWNER_M, + ICPU_GENERAL_CTRL_IF_SI_OWNER(1)); + } +} + +void board_debug_uart_init(void) +{ + /* too early for the pinctrl driver, so configure the UART pins here */ + setbits_le32(BASE_DEVCPU_GCB + MSCC_GPIO_ALT0, BIT(6) | BIT(7)); + clrbits_le32(BASE_DEVCPU_GCB + MSCC_GPIO_ALT1, BIT(6) | BIT(7)); +} + +int board_early_init_r(void) +{ + /* Prepare SPI controller to be used in master mode */ + writel(0, BASE_CFG + ICPU_SW_MODE); + clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, + ICPU_GENERAL_CTRL_IF_SI_OWNER_M, + ICPU_GENERAL_CTRL_IF_SI_OWNER(2)); + + /* Address of boot parameters */ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE; + return 0; +} diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c index 31bc0f49a48..536c5b88ed5 100644 --- a/board/ti/am43xx/board.c +++ b/board/ti/am43xx/board.c @@ -705,6 +705,19 @@ int board_init(void) } #ifdef CONFIG_BOARD_LATE_INIT +#if CONFIG_IS_ENABLED(DM_USB) && CONFIG_IS_ENABLED(OF_CONTROL) +static int device_okay(const char *path) +{ + int node; + + node = fdt_path_offset(gd->fdt_blob, path); + if (node < 0) + return 0; + + return fdtdec_get_is_enabled(gd->fdt_blob, node); +} +#endif + int board_late_init(void) { #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG @@ -717,10 +730,18 @@ int board_late_init(void) if (get_device_type() == HS_DEVICE) env_set("boot_fit", "1"); #endif + +#if CONFIG_IS_ENABLED(DM_USB) && CONFIG_IS_ENABLED(OF_CONTROL) + if (device_okay("/ocp/omap_dwc3@48380000")) + enable_usb_clocks(0); + if (device_okay("/ocp/omap_dwc3@483c0000")) + enable_usb_clocks(1); +#endif return 0; } #endif +#if !CONFIG_IS_ENABLED(DM_USB_GADGET) #ifdef CONFIG_USB_DWC3 static struct dwc3_device usb_otg_ss1 = { .maximum_speed = USB_SPEED_HIGH, @@ -823,6 +844,7 @@ int board_usb_cleanup(int index, enum usb_init_type init) return 0; } #endif /* defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP) */ +#endif /* !CONFIG_IS_ENABLED(DM_USB_GADGET) */ #ifdef CONFIG_DRIVER_TI_CPSW diff --git a/board/ti/ks2_evm/board.c b/board/ti/ks2_evm/board.c index 3e06800608a..eed62e9cac2 100644 --- a/board/ti/ks2_evm/board.c +++ b/board/ti/ks2_evm/board.c @@ -66,6 +66,18 @@ struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) int board_init(void) { +#if CONFIG_IS_ENABLED(DM_USB) + int rc = psc_enable_module(KS2_LPSC_USB); + + if (rc) + puts("Cannot enable USB0 module"); +#ifdef KS2_LPSC_USB_1 + rc = psc_enable_module(KS2_LPSC_USB_1); + if (rc) + puts("Cannot enable USB1 module"); +#endif +#endif + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; return 0; diff --git a/cmd/Makefile b/cmd/Makefile index 49986437ba5..15ae4d250f5 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_CMD_CPU) += cpu.o obj-$(CONFIG_DATAFLASH_MMC_SELECT) += dataflash_mmc_mux.o obj-$(CONFIG_CMD_DATE) += date.o obj-$(CONFIG_CMD_DEMO) += demo.o +obj-$(CONFIG_CMD_DM) += dm.o obj-$(CONFIG_CMD_SOUND) += sound.o ifdef CONFIG_POST obj-$(CONFIG_CMD_DIAG) += diag.o diff --git a/cmd/cbfs.c b/cmd/cbfs.c index ece790e56e4..c118a952ac2 100644 --- a/cmd/cbfs.c +++ b/cmd/cbfs.c @@ -112,12 +112,21 @@ static int do_cbfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, printf(" %8d", file_cbfs_size(file)); switch (type) { + case CBFS_TYPE_BOOTBLOCK: + type_name = "bootblock"; + break; + case CBFS_TYPE_CBFSHEADER: + type_name = "cbfs header"; + break; case CBFS_TYPE_STAGE: type_name = "stage"; break; case CBFS_TYPE_PAYLOAD: type_name = "payload"; break; + case CBFS_TYPE_FIT: + type_name = "fit"; + break; case CBFS_TYPE_OPTIONROM: type_name = "option rom"; break; @@ -136,10 +145,31 @@ static int do_cbfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, case CBFS_TYPE_MICROCODE: type_name = "microcode"; break; - case CBFS_COMPONENT_CMOS_DEFAULT: + case CBFS_TYPE_FSP: + type_name = "fsp"; + break; + case CBFS_TYPE_MRC: + type_name = "mrc"; + break; + case CBFS_TYPE_MMA: + type_name = "mma"; + break; + case CBFS_TYPE_EFI: + type_name = "efi"; + break; + case CBFS_TYPE_STRUCT: + type_name = "struct"; + break; + case CBFS_TYPE_CMOS_DEFAULT: type_name = "cmos default"; break; - case CBFS_COMPONENT_CMOS_LAYOUT: + case CBFS_TYPE_SPD: + type_name = "spd"; + break; + case CBFS_TYPE_MRC_CACHE: + type_name = "mrc cache"; + break; + case CBFS_TYPE_CMOS_LAYOUT: type_name = "cmos layout"; break; case -1: diff --git a/test/dm/cmd_dm.c b/cmd/dm.c index 7b271db0bbe..7b271db0bbe 100644 --- a/test/dm/cmd_dm.c +++ b/cmd/dm.c diff --git a/cmd/sound.c b/cmd/sound.c index d1cbc14f8df..638f29df21d 100644 --- a/cmd/sound.c +++ b/cmd/sound.c @@ -6,6 +6,7 @@ #include <common.h> #include <command.h> +#include <dm.h> #include <fdtdec.h> #include <sound.h> @@ -14,11 +15,14 @@ DECLARE_GLOBAL_DATA_PTR; /* Initilaise sound subsystem */ static int do_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { + struct udevice *dev; int ret; - ret = sound_init(gd->fdt_blob); + ret = uclass_first_device_err(UCLASS_SOUND, &dev); + if (!ret) + ret = sound_setup(dev); if (ret) { - printf("Initialise Audio driver failed\n"); + printf("Initialise Audio driver failed (ret=%d)\n", ret); return CMD_RET_FAILURE; } @@ -28,6 +32,7 @@ static int do_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) /* play sound from buffer */ static int do_play(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { + struct udevice *dev; int ret = 0; int msec = 1000; int freq = 400; @@ -37,9 +42,11 @@ static int do_play(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) if (argc > 2) freq = simple_strtoul(argv[2], NULL, 10); - ret = sound_play(msec, freq); + ret = uclass_first_device_err(UCLASS_SOUND, &dev); + if (!ret) + ret = sound_beep(dev, msec, freq); if (ret) { - printf("play failed"); + printf("Sound device failed to play (err=%d)\n", ret); return CMD_RET_FAILURE; } diff --git a/common/Makefile b/common/Makefile index 65d89dc62d5..0de60b3ced2 100644 --- a/common/Makefile +++ b/common/Makefile @@ -74,9 +74,12 @@ obj-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o obj-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o + ifdef CONFIG_SPL_USB_HOST_SUPPORT obj-$(CONFIG_SPL_USB_SUPPORT) += usb.o usb_hub.o obj-$(CONFIG_USB_STORAGE) += usb_storage.o +else +obj-$(CONFIG_USB_MUSB_HOST) += usb.o endif endif # CONFIG_SPL_BUILD diff --git a/common/bootm_os.c b/common/bootm_os.c index f3021358686..855c471c28e 100644 --- a/common/bootm_os.c +++ b/common/bootm_os.c @@ -260,7 +260,7 @@ static int do_bootm_plan9(int flag, int argc, char * const argv[], #if defined(CONFIG_BOOTM_VXWORKS) && \ (defined(CONFIG_PPC) || defined(CONFIG_ARM)) -void do_bootvx_fdt(bootm_headers_t *images) +static void do_bootvx_fdt(bootm_headers_t *images) { #if defined(CONFIG_OF_LIBFDT) int ret; @@ -317,8 +317,8 @@ void do_bootvx_fdt(bootm_headers_t *images) puts("## vxWorks terminated\n"); } -static int do_bootm_vxworks(int flag, int argc, char * const argv[], - bootm_headers_t *images) +int do_bootm_vxworks(int flag, int argc, char * const argv[], + bootm_headers_t *images) { if (flag != BOOTM_STATE_OS_GO) return 0; @@ -482,7 +482,7 @@ static boot_os_fn *boot_os[] = { [IH_OS_PLAN9] = do_bootm_plan9, #endif #if defined(CONFIG_BOOTM_VXWORKS) && \ - (defined(CONFIG_PPC) || defined(CONFIG_ARM)) + (defined(CONFIG_PPC) || defined(CONFIG_ARM) || defined(CONFIG_RISCV)) [IH_OS_VXWORKS] = do_bootm_vxworks, #endif #if defined(CONFIG_CMD_ELF) diff --git a/common/spl/spl_net.c b/common/spl/spl_net.c index b6967ff69ee..c91ad2b6ddd 100644 --- a/common/spl/spl_net.c +++ b/common/spl/spl_net.c @@ -85,7 +85,9 @@ int spl_net_load_image_usb(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { bootdev->boot_device_name = "usb_ether"; - +#if CONFIG_IS_ENABLED(DM_USB_GADGET) + usb_ether_init(); +#endif return spl_net_load_image(spl_image, bootdev); } SPL_LOAD_IMAGE_METHOD("USB eth", 0, BOOT_DEVICE_USBETH, spl_net_load_image_usb); diff --git a/configs/a25-ae350_32_defconfig b/configs/ae350_rv32_defconfig index 5837b48903d..5837b48903d 100644 --- a/configs/a25-ae350_32_defconfig +++ b/configs/ae350_rv32_defconfig diff --git a/configs/ax25-ae350_64_defconfig b/configs/ae350_rv64_defconfig index b250d3fc7e3..b250d3fc7e3 100644 --- a/configs/ax25-ae350_64_defconfig +++ b/configs/ae350_rv64_defconfig diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig index d625599461f..be044243755 100644 --- a/configs/am335x_boneblack_vboot_defconfig +++ b/configs/am335x_boneblack_vboot_defconfig @@ -13,7 +13,11 @@ CONFIG_VERSION_VARIABLE=y CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_MUSB_NEW_SUPPORT=y # CONFIG_SPL_NAND_SUPPORT is not set +CONFIG_SPL_NET_SUPPORT=y +CONFIG_SPL_NET_VCI_STRING="AM33xx U-Boot SPL" CONFIG_SPL_OS_BOOT=y +CONFIG_SPL_USB_GADGET_SUPPORT=y +CONFIG_SPL_USB_ETHER=y CONFIG_AUTOBOOT_KEYED=y CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n" CONFIG_AUTOBOOT_DELAY_STR="d" @@ -31,6 +35,7 @@ CONFIG_DFU_MMC=y CONFIG_DFU_RAM=y CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_DM_I2C=y +CONFIG_MISC=y CONFIG_DM_MMC=y CONFIG_MMC_OMAP_HS=y CONFIG_SPI_FLASH=y @@ -44,8 +49,13 @@ CONFIG_OMAP3_SPI=y CONFIG_TIMER=y CONFIG_OMAP_TIMER=y CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_SPL_DM_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_SPL_DM_USB_GADGET=y CONFIG_USB_MUSB_HOST=y CONFIG_USB_MUSB_GADGET=y +CONFIG_USB_MUSB_TI=y CONFIG_USB_MUSB_DSPS=y CONFIG_USB_STORAGE=y CONFIG_USB_GADGET=y diff --git a/configs/am43xx_evm_defconfig b/configs/am43xx_evm_defconfig index 7601263be47..9bbda434ee1 100644 --- a/configs/am43xx_evm_defconfig +++ b/configs/am43xx_evm_defconfig @@ -3,6 +3,7 @@ CONFIG_ARCH_OMAP2PLUS=y CONFIG_TI_COMMON_CMD_OPTIONS=y CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_AM43XX=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y CONFIG_SPL=y CONFIG_DISTRO_DEFAULTS=y CONFIG_SPL_LOAD_FIT=y @@ -12,7 +13,11 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y # CONFIG_MISC_INIT_R is not set CONFIG_VERSION_VARIABLE=y CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_NET_SUPPORT=y +CONFIG_SPL_NET_VCI_STRING="AM43xx U-Boot SPL" CONFIG_SPL_OS_BOOT=y +CONFIG_SPL_USB_GADGET_SUPPORT=y +CONFIG_SPL_USB_ETHER=y CONFIG_CMD_SPL=y CONFIG_CMD_SPL_NAND_OFS=0x00100000 CONFIG_CMD_SPL_WRITE_SIZE=0x40000 @@ -27,11 +32,16 @@ CONFIG_DEFAULT_DEVICE_TREE="am437x-gp-evm" CONFIG_OF_LIST="am437x-gp-evm am437x-sk-evm am43x-epos-evm am437x-idk-evm" CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_DM=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y # CONFIG_BLK is not set CONFIG_DFU_MMC=y CONFIG_DFU_RAM=y CONFIG_DFU_SF=y CONFIG_DM_GPIO=y +CONFIG_MISC=y CONFIG_DM_MMC=y CONFIG_MMC_OMAP_HS=y CONFIG_NAND=y @@ -40,17 +50,25 @@ CONFIG_SPI_FLASH_MACRONIX=y CONFIG_DRIVER_TI_CPSW=y CONFIG_PHY_GIGE=y CONFIG_MII=y +CONFIG_PHY=y +CONFIG_SPL_PHY=y +CONFIG_OMAP_USB2_PHY=y CONFIG_DM_SERIAL=y CONFIG_SPI=y CONFIG_TI_QSPI=y CONFIG_TIMER=y CONFIG_OMAP_TIMER=y CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_SPL_DM_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_SPL_DM_USB_GADGET=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_OMAP=y +CONFIG_USB_DWC3_GENERIC=y CONFIG_USB_DWC3_PHY_OMAP=y CONFIG_OMAP_USB_PHY=y CONFIG_USB_STORAGE=y @@ -59,3 +77,4 @@ CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" CONFIG_USB_GADGET_VENDOR_NUM=0x0403 CONFIG_USB_GADGET_PRODUCT_NUM=0xbd00 CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_USB_ETHER=y diff --git a/configs/ci20_mmc_defconfig b/configs/ci20_mmc_defconfig new file mode 100644 index 00000000000..c1b1c3f7e9e --- /dev/null +++ b/configs/ci20_mmc_defconfig @@ -0,0 +1,48 @@ +CONFIG_MIPS=y +CONFIG_SPL_LDSCRIPT="arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds" +CONFIG_SYS_TEXT_BASE=0x80010000 +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_SPL=y +CONFIG_ARCH_JZ47XX=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_FIT=y +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="console=ttyS4,115200 rw rootwait root=/dev/mmcblk0p1" +CONFIG_USE_BOOTCOMMAND=y +CONFIG_BOOTCOMMAND="ext4load mmc 0:1 0x88000000 /boot/uImage; bootm 0x88000000" +CONFIG_MISC_INIT_R=y +CONFIG_DISPLAY_CPUINFO=y +CONFIG_BOARD_EARLY_INIT_F=y +# CONFIG_SPL_BANNER_PRINT is not set +# CONFIG_TPL_BANNER_PRINT is not set +CONFIG_HUSH_PARSER=y +CONFIG_CMD_DM=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_FAT=y +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_DEFAULT_DEVICE_TREE="ci20" +CONFIG_ENV_IS_IN_MMC=y +# CONFIG_DM_WARN is not set +# CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_JZ4780_EFUSE=y +CONFIG_MMC=y +CONFIG_MMC_BROKEN_CD=y +CONFIG_DM_MMC=y +# CONFIG_MMC_HW_PARTITIONING is not set +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y +CONFIG_MMC_HS400_SUPPORT=y +# CONFIG_MMC_VERBOSE is not set +CONFIG_SPL_MMC_TINY=y +CONFIG_JZ47XX_MMC=y +CONFIG_DM_SERIAL=y +CONFIG_SYS_NS16550=y +CONFIG_USE_TINY_PRINTF=y +CONFIG_SPL_TINY_MEMSET=y +CONFIG_LZO=y diff --git a/configs/comtrend_ar5315u_ram_defconfig b/configs/comtrend_ar5315u_ram_defconfig index d9ef52e68d2..1b8e4e43c4c 100644 --- a/configs/comtrend_ar5315u_ram_defconfig +++ b/configs/comtrend_ar5315u_ram_defconfig @@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_USB=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5315u" -# CONFIG_NET is not set +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_LED=y CONFIG_LED_BCM6328=y @@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_SPI_FLASH_MTD=y +CONFIG_DM_ETH=y +CONFIG_BCM6368_ETH=y CONFIG_PHY=y CONFIG_BCM6318_USBH_PHY=y CONFIG_BCM6328_POWER_DOMAIN=y diff --git a/configs/comtrend_ar5387un_ram_defconfig b/configs/comtrend_ar5387un_ram_defconfig index f129870ca06..5ba401a4419 100644 --- a/configs/comtrend_ar5387un_ram_defconfig +++ b/configs/comtrend_ar5387un_ram_defconfig @@ -28,11 +28,14 @@ CONFIG_CMD_MEMINFO=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_USB=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5387un" -# CONFIG_NET is not set +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_LED=y CONFIG_LED_BCM6328=y @@ -41,6 +44,8 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_MTD=y +CONFIG_DM_ETH=y +CONFIG_BCM6368_ETH=y CONFIG_PHY=y CONFIG_BCM6368_USBH_PHY=y CONFIG_POWER_DOMAIN=y diff --git a/configs/comtrend_ct5361_ram_defconfig b/configs/comtrend_ct5361_ram_defconfig index 82f20707136..6297e78fd94 100644 --- a/configs/comtrend_ct5361_ram_defconfig +++ b/configs/comtrend_ct5361_ram_defconfig @@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y CONFIG_CMD_MEMINFO=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="comtrend,ct-5361" -# CONFIG_NET is not set +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y @@ -40,6 +43,9 @@ CONFIG_FLASH_CFI_DRIVER=y CONFIG_CFI_FLASH=y CONFIG_SYS_FLASH_PROTECTION=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6348_USBH_PHY=y CONFIG_DM_RESET=y diff --git a/configs/comtrend_vr3032u_ram_defconfig b/configs/comtrend_vr3032u_ram_defconfig index 1689eecec15..47f53998e12 100644 --- a/configs/comtrend_vr3032u_ram_defconfig +++ b/configs/comtrend_vr3032u_ram_defconfig @@ -26,15 +26,20 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="comtrend,vr-3032u" -# CONFIG_NET is not set +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_LED=y CONFIG_LED_BCM6328=y CONFIG_LED_BLINK=y +CONFIG_DM_ETH=y +CONFIG_BCM6368_ETH=y CONFIG_PHY=y CONFIG_BCM6368_USBH_PHY=y CONFIG_POWER_DOMAIN=y diff --git a/configs/comtrend_wap5813n_ram_defconfig b/configs/comtrend_wap5813n_ram_defconfig index 987e4c3fbce..fd5107bb7d8 100644 --- a/configs/comtrend_wap5813n_ram_defconfig +++ b/configs/comtrend_wap5813n_ram_defconfig @@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y CONFIG_CMD_MEMINFO=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="comtrend,wap-5813n" -# CONFIG_NET is not set +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y @@ -40,6 +43,9 @@ CONFIG_FLASH_CFI_DRIVER=y CONFIG_CFI_FLASH=y CONFIG_SYS_FLASH_PROTECTION=y CONFIG_SYS_FLASH_CFI=y +CONFIG_DM_ETH=y +CONFIG_PHY_GIGE=y +CONFIG_BCM6368_ETH=y CONFIG_PHY=y CONFIG_BCM6368_USBH_PHY=y CONFIG_DM_RESET=y diff --git a/configs/db-88f6820-amc_defconfig b/configs/db-88f6820-amc_defconfig index dd58198a546..9068a584060 100644 --- a/configs/db-88f6820-amc_defconfig +++ b/configs/db-88f6820-amc_defconfig @@ -43,6 +43,9 @@ CONFIG_EFI_PARTITION=y CONFIG_DEFAULT_DEVICE_TREE="armada-385-amc" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SPL_OF_TRANSLATE=y +CONFIG_BLK=y +# CONFIG_SPL_BLK is not set +# CONFIG_BLOCK_CACHE is not set CONFIG_DM_I2C=y CONFIG_SYS_I2C_MVTWSI=y # CONFIG_MMC is not set diff --git a/configs/edison_defconfig b/configs/edison_defconfig index eb9f9a089f1..234dbac4e87 100644 --- a/configs/edison_defconfig +++ b/configs/edison_defconfig @@ -18,7 +18,6 @@ CONFIG_CMD_DFU=y CONFIG_CMD_GPT=y CONFIG_CMD_MMC=y CONFIG_CMD_PART=y -# CONFIG_CMD_PCI is not set # CONFIG_CMD_NFS is not set CONFIG_CMD_TIMER=y CONFIG_CMD_HASH=y diff --git a/configs/elgin-rv1108_defconfig b/configs/elgin-rv1108_defconfig new file mode 100644 index 00000000000..40fbd6bd0e8 --- /dev/null +++ b/configs/elgin-rv1108_defconfig @@ -0,0 +1,58 @@ +CONFIG_ARM=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_SYS_TEXT_BASE=0x60000000 +CONFIG_ROCKCHIP_RV1108=y +CONFIG_TARGET_ELGIN_RV1108=y +CONFIG_DEBUG_UART_BASE=0x10210000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_DEBUG_UART=y +CONFIG_NR_DRAM_BANKS=1 +# CONFIG_USE_BOOTCOMMAND is not set +CONFIG_DEFAULT_FDT_FILE="rv1108-elgin-r1.dtb" +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_CMD_GPIO=y +CONFIG_RANDOM_UUID=y +CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_DEFAULT_DEVICE_TREE="rv1108-elgin-r1" +CONFIG_ENV_IS_IN_MMC=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CLK=y +CONFIG_FASTBOOT_BUF_ADDR=0x62000000 +CONFIG_FASTBOOT_BUF_SIZE=0x08000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_DM_ETH=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_GMAC_ROCKCHIP=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RV1108=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_BAUDRATE=1500000 +# CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYSRESET=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_GENERIC=y +CONFIG_USB_DWC2=y +CONFIG_USB_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Rockchip" +CONFIG_USB_GADGET_VENDOR_NUM=0x2207 +CONFIG_USB_GADGET_PRODUCT_NUM=0x110a +CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_ERRNO_STR=y diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig index 05e7cf9f884..ae8bf2981f3 100644 --- a/configs/gardena-smart-gateway-mt7688-ram_defconfig +++ b/configs/gardena-smart-gateway-mt7688-ram_defconfig @@ -36,7 +36,6 @@ CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="spi-nand0=gd5f,nor0=spi0.0" CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);gd5f:-(nand)" CONFIG_CMD_UBI=y -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index a08d1dbc9c7..b7024e3dec1 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -39,7 +39,6 @@ CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="spi-nand0=gd5f,nor0=spi0.0" CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);gd5f:-(nand)" CONFIG_CMD_UBI=y -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/huawei_hg556a_ram_defconfig b/configs/huawei_hg556a_ram_defconfig index 6bb14ba736f..d4e6144319b 100644 --- a/configs/huawei_hg556a_ram_defconfig +++ b/configs/huawei_hg556a_ram_defconfig @@ -25,11 +25,14 @@ CONFIG_CMD_LICENSE=y CONFIG_CMD_MEMINFO=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="huawei,hg556a" -# CONFIG_NET is not set +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y @@ -40,6 +43,9 @@ CONFIG_FLASH_CFI_DRIVER=y CONFIG_CFI_FLASH=y CONFIG_SYS_FLASH_PROTECTION=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6358_USBH_PHY=y CONFIG_DM_RESET=y diff --git a/configs/k2e_evm_defconfig b/configs/k2e_evm_defconfig index 67b1f30c8e6..03a1ceb2682 100644 --- a/configs/k2e_evm_defconfig +++ b/configs/k2e_evm_defconfig @@ -37,6 +37,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SYS_I2C_DAVINCI=y CONFIG_TI_AEMIF=y +CONFIG_MISC=y # CONFIG_MMC is not set CONFIG_NAND=y CONFIG_NAND_DAVINCI=y @@ -47,13 +48,19 @@ CONFIG_PHYLIB=y CONFIG_PHY_MARVELL=y CONFIG_DM_ETH=y CONFIG_MII=y +CONFIG_PHY=y +CONFIG_NOP_PHY=y +CONFIG_KEYSTONE_USB_PHY=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_DAVINCI_SPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y CONFIG_USB_STORAGE=y CONFIG_DRIVER_TI_KEYSTONE_NET=y diff --git a/configs/k2e_hs_evm_defconfig b/configs/k2e_hs_evm_defconfig index 1abda846a1b..bb7b31417e4 100644 --- a/configs/k2e_hs_evm_defconfig +++ b/configs/k2e_hs_evm_defconfig @@ -30,6 +30,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SYS_I2C_DAVINCI=y CONFIG_TI_AEMIF=y +CONFIG_MISC=y # CONFIG_MMC is not set CONFIG_NAND=y CONFIG_NAND_DAVINCI=y @@ -40,13 +41,19 @@ CONFIG_PHYLIB=y CONFIG_PHY_MARVELL=y CONFIG_DM_ETH=y CONFIG_MII=y +CONFIG_PHY=y +CONFIG_NOP_PHY=y +CONFIG_KEYSTONE_USB_PHY=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_DAVINCI_SPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y CONFIG_USB_STORAGE=y CONFIG_DRIVER_TI_KEYSTONE_NET=y diff --git a/configs/k2g_evm_defconfig b/configs/k2g_evm_defconfig index bc4b92b4915..8a070396966 100644 --- a/configs/k2g_evm_defconfig +++ b/configs/k2g_evm_defconfig @@ -35,7 +35,9 @@ CONFIG_MULTI_DTB_FIT=y CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_DM=y # CONFIG_BLK is not set +CONFIG_DFU_MMC=y CONFIG_SYS_I2C_DAVINCI=y +CONFIG_MISC=y CONFIG_DM_MMC=y CONFIG_MMC_OMAP_HS=y CONFIG_NAND=y @@ -50,6 +52,8 @@ CONFIG_PHY_MARVELL=y CONFIG_PHY_MICREL=y CONFIG_DM_ETH=y CONFIG_MII=y +CONFIG_PHY=y +CONFIG_NOP_PHY=y CONFIG_REMOTEPROC_TI_POWER=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y @@ -57,7 +61,15 @@ CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_DAVINCI_SPI=y CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_DM_USB_GADGET=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GADGET=y +CONFIG_USB_DWC3_GENERIC=y CONFIG_USB_STORAGE=y CONFIG_DRIVER_TI_KEYSTONE_NET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_USB_FUNCTION_SDP=y diff --git a/configs/k2g_hs_evm_defconfig b/configs/k2g_hs_evm_defconfig index 66d8220aebb..5f91f11d362 100644 --- a/configs/k2g_hs_evm_defconfig +++ b/configs/k2g_hs_evm_defconfig @@ -28,7 +28,9 @@ CONFIG_MULTI_DTB_FIT=y CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_DM=y # CONFIG_BLK is not set +CONFIG_DFU_MMC=y CONFIG_SYS_I2C_DAVINCI=y +CONFIG_MISC=y CONFIG_DM_MMC=y CONFIG_MMC_OMAP_HS=y CONFIG_NAND=y @@ -43,6 +45,8 @@ CONFIG_PHY_MARVELL=y CONFIG_PHY_MICREL=y CONFIG_DM_ETH=y CONFIG_MII=y +CONFIG_PHY=y +CONFIG_NOP_PHY=y CONFIG_REMOTEPROC_TI_POWER=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y @@ -50,7 +54,15 @@ CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_DAVINCI_SPI=y CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_DM_USB_GADGET=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GADGET=y +CONFIG_USB_DWC3_GENERIC=y CONFIG_USB_STORAGE=y CONFIG_DRIVER_TI_KEYSTONE_NET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_USB_FUNCTION_SDP=y diff --git a/configs/k2hk_evm_defconfig b/configs/k2hk_evm_defconfig index f66d922bf17..700fafd5a35 100644 --- a/configs/k2hk_evm_defconfig +++ b/configs/k2hk_evm_defconfig @@ -37,6 +37,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SYS_I2C_DAVINCI=y CONFIG_TI_AEMIF=y +CONFIG_MISC=y # CONFIG_MMC is not set CONFIG_NAND=y CONFIG_NAND_DAVINCI=y @@ -47,13 +48,19 @@ CONFIG_PHYLIB=y CONFIG_PHY_MARVELL=y CONFIG_DM_ETH=y CONFIG_MII=y +CONFIG_PHY=y +CONFIG_NOP_PHY=y +CONFIG_KEYSTONE_USB_PHY=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_DAVINCI_SPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y CONFIG_USB_STORAGE=y CONFIG_DRIVER_TI_KEYSTONE_NET=y diff --git a/configs/k2hk_hs_evm_defconfig b/configs/k2hk_hs_evm_defconfig index dd91a514145..a6caccce7bc 100644 --- a/configs/k2hk_hs_evm_defconfig +++ b/configs/k2hk_hs_evm_defconfig @@ -30,6 +30,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SYS_I2C_DAVINCI=y CONFIG_TI_AEMIF=y +CONFIG_MISC=y # CONFIG_MMC is not set CONFIG_NAND=y CONFIG_NAND_DAVINCI=y @@ -40,13 +41,19 @@ CONFIG_PHYLIB=y CONFIG_PHY_MARVELL=y CONFIG_DM_ETH=y CONFIG_MII=y +CONFIG_PHY=y +CONFIG_NOP_PHY=y +CONFIG_KEYSTONE_USB_PHY=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_DAVINCI_SPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y CONFIG_USB_STORAGE=y CONFIG_DRIVER_TI_KEYSTONE_NET=y diff --git a/configs/k2l_evm_defconfig b/configs/k2l_evm_defconfig index 4f04caa1a3c..cb638082da6 100644 --- a/configs/k2l_evm_defconfig +++ b/configs/k2l_evm_defconfig @@ -37,6 +37,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SYS_I2C_DAVINCI=y CONFIG_TI_AEMIF=y +CONFIG_MISC=y # CONFIG_MMC is not set CONFIG_NAND=y CONFIG_NAND_DAVINCI=y @@ -47,13 +48,19 @@ CONFIG_PHYLIB=y CONFIG_PHY_MARVELL=y CONFIG_DM_ETH=y CONFIG_MII=y +CONFIG_PHY=y +CONFIG_NOP_PHY=y +CONFIG_KEYSTONE_USB_PHY=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_DAVINCI_SPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y CONFIG_USB_STORAGE=y CONFIG_DRIVER_TI_KEYSTONE_NET=y diff --git a/configs/k2l_hs_evm_defconfig b/configs/k2l_hs_evm_defconfig index 9ce23dec93b..4ce7801e4ed 100644 --- a/configs/k2l_hs_evm_defconfig +++ b/configs/k2l_hs_evm_defconfig @@ -29,6 +29,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SYS_I2C_DAVINCI=y CONFIG_TI_AEMIF=y +CONFIG_MISC=y # CONFIG_MMC is not set CONFIG_NAND=y CONFIG_NAND_DAVINCI=y @@ -39,13 +40,19 @@ CONFIG_PHYLIB=y CONFIG_PHY_MARVELL=y CONFIG_DM_ETH=y CONFIG_MII=y +CONFIG_PHY=y +CONFIG_NOP_PHY=y +CONFIG_KEYSTONE_USB_PHY=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_DAVINCI_SPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y CONFIG_USB_STORAGE=y CONFIG_DRIVER_TI_KEYSTONE_NET=y diff --git a/configs/linkit-smart-7688-ram_defconfig b/configs/linkit-smart-7688-ram_defconfig index 2d20e9edd98..2d3ab7e35c3 100644 --- a/configs/linkit-smart-7688-ram_defconfig +++ b/configs/linkit-smart-7688-ram_defconfig @@ -26,7 +26,6 @@ CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y CONFIG_CMD_TIME=y -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig index 5add29fb333..ad34aaf640c 100644 --- a/configs/linkit-smart-7688_defconfig +++ b/configs/linkit-smart-7688_defconfig @@ -30,7 +30,6 @@ CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y CONFIG_CMD_TIME=y -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/mscc_luton_defconfig b/configs/mscc_luton_defconfig new file mode 100644 index 00000000000..d7476c48633 --- /dev/null +++ b/configs/mscc_luton_defconfig @@ -0,0 +1,64 @@ +CONFIG_MIPS=y +CONFIG_SYS_TEXT_BASE=0x40000000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_DEBUG_UART_BOARD_INIT=y +CONFIG_DEBUG_UART_BASE=0x70100000 +CONFIG_DEBUG_UART_CLOCK=208333333 +CONFIG_ARCH_MSCC=y +CONFIG_TARGET_LUTON_PCB091=y +CONFIG_DDRTYPE_MT47H128M8HQ=y +CONFIG_SYS_LITTLE_ENDIAN=y +CONFIG_MIPS_BOOT_FDT=y +CONFIG_DEBUG_UART=y +CONFIG_FIT=y +CONFIG_BOOTDELAY=3 +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="console=ttyS0,115200" +CONFIG_LOGLEVEL=7 +CONFIG_DISPLAY_CPUINFO=y +CONFIG_SYS_PROMPT="pcb091 # " +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_CRC32 is not set +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MEMTEST=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_DHCP=y +# CONFIG_NET_TFTP_VARS is not set +# CONFIG_CMD_NFS is not set +CONFIG_CMD_PING=y +CONFIG_CMD_MTDPARTS=y +CONFIG_MTDIDS_DEFAULT="nor0=spi_flash" +CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:512k(UBoot),256k(Env),256k(conf),6m@1m(linux)" +# CONFIG_ISO_PARTITION is not set +CONFIG_DEFAULT_DEVICE_TREE="luton_pcb091" +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_CLK=y +CONFIG_DM_GPIO=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_MTD=y +CONFIG_DM_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_DM_SERIAL=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_SOFT_SPI=y +CONFIG_LZMA=y diff --git a/configs/mscc_ocelot_defconfig b/configs/mscc_ocelot_defconfig new file mode 100644 index 00000000000..5fa74db2ff5 --- /dev/null +++ b/configs/mscc_ocelot_defconfig @@ -0,0 +1,67 @@ +CONFIG_MIPS=y +CONFIG_SYS_TEXT_BASE=0x40000000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_DEBUG_UART_BOARD_INIT=y +CONFIG_DEBUG_UART_BASE=0x70100000 +CONFIG_DEBUG_UART_CLOCK=250000000 +CONFIG_ARCH_MSCC=y +CONFIG_TARGET_OCELOT_PCB123=y +CONFIG_SYS_LITTLE_ENDIAN=y +CONFIG_DEBUG_UART=y +CONFIG_FIT=y +CONFIG_BOOTDELAY=3 +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="console=ttyS0,115200" +CONFIG_LOGLEVEL=7 +CONFIG_DISPLAY_CPUINFO=y +CONFIG_SYS_PROMPT="pcb123 # " +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_CRC32 is not set +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MEMTEST=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_MTD=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_DHCP=y +# CONFIG_NET_TFTP_VARS is not set +# CONFIG_CMD_NFS is not set +CONFIG_CMD_PING=y +CONFIG_CMD_MTDPARTS=y +CONFIG_MTDIDS_DEFAULT="nor0=spi_flash" +CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:512k(UBoot),256k(Env),256k(conf),15m(linux),15m(linux.bk)" +CONFIG_CMD_UBI=y +# CONFIG_CMD_UBIFS is not set +# CONFIG_ISO_PARTITION is not set +CONFIG_DEFAULT_DEVICE_TREE="ocelot_pcb123" +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_CLK=y +CONFIG_DM_GPIO=y +CONFIG_MTD=y +CONFIG_MTD_SPI_NAND=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_MTD=y +CONFIG_DM_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_DM_SERIAL=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_DESIGNWARE_SPI=y +CONFIG_LZMA=y diff --git a/configs/mscc_ocelot_pcb120_defconfig b/configs/mscc_ocelot_pcb120_defconfig new file mode 100644 index 00000000000..c5a9f969770 --- /dev/null +++ b/configs/mscc_ocelot_pcb120_defconfig @@ -0,0 +1,60 @@ +CONFIG_MIPS=y +CONFIG_SYS_TEXT_BASE=0x40000000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_ARCH_MSCC=y +CONFIG_SYS_LITTLE_ENDIAN=y +CONFIG_FIT=y +CONFIG_BOOTDELAY=3 +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="console=ttyS0,115200" +CONFIG_LOGLEVEL=7 +CONFIG_DISPLAY_CPUINFO=y +CONFIG_SYS_PROMPT="pcb120 # " +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_CRC32 is not set +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MEMTEST=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_MTD=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_DHCP=y +# CONFIG_NET_TFTP_VARS is not set +# CONFIG_CMD_NFS is not set +CONFIG_CMD_PING=y +CONFIG_CMD_MTDPARTS=y +CONFIG_MTDIDS_DEFAULT="nor0=spi_flash" +CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:512k(UBoot),256k(Env),256k(conf),15m(linux),15m(linux.bk)" +CONFIG_CMD_UBI=y +# CONFIG_CMD_UBIFS is not set +# CONFIG_ISO_PARTITION is not set +CONFIG_DEFAULT_DEVICE_TREE="ocelot_pcb120" +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_CLK=y +CONFIG_DM_GPIO=y +CONFIG_MTD=y +CONFIG_MTD_SPI_NAND=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_MTD=y +CONFIG_DM_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_DM_SERIAL=y +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_DESIGNWARE_SPI=y +CONFIG_LZMA=y diff --git a/configs/netgear_dgnd3700v2_ram_defconfig b/configs/netgear_dgnd3700v2_ram_defconfig index 1abc8698560..0f3914fe7e2 100644 --- a/configs/netgear_dgnd3700v2_ram_defconfig +++ b/configs/netgear_dgnd3700v2_ram_defconfig @@ -27,17 +27,23 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y -# CONFIG_CMD_NET is not set +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="netgear,dgnd3700v2" +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y CONFIG_LED_BCM6328=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y +CONFIG_DM_ETH=y +CONFIG_PHY_GIGE=y +CONFIG_BCM6368_ETH=y CONFIG_PHY=y CONFIG_BCM6368_USBH_PHY=y CONFIG_POWER_DOMAIN=y diff --git a/configs/peach-pi_defconfig b/configs/peach-pi_defconfig index 338eae20b41..14c835cad81 100644 --- a/configs/peach-pi_defconfig +++ b/configs/peach-pi_defconfig @@ -21,6 +21,7 @@ CONFIG_CMD_USB=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_CACHE=y CONFIG_CMD_TIME=y +CONFIG_CMD_SOUND=y CONFIG_CMD_PMIC=y CONFIG_CMD_REGULATOR=y CONFIG_CMD_TPM=y @@ -28,7 +29,6 @@ CONFIG_CMD_TPM_TEST=y CONFIG_CMD_EXT4_WRITE=y CONFIG_DEFAULT_DEVICE_TREE="exynos5800-peach-pi" CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_DM_I2C_COMPAT=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_I2C_MUX=y CONFIG_I2C_ARB_GPIO_CHALLENGE=y @@ -52,6 +52,7 @@ CONFIG_PWM_EXYNOS=y CONFIG_SOUND=y CONFIG_I2S=y CONFIG_I2S_SAMSUNG=y +CONFIG_SOUND_MAX98090=y CONFIG_SOUND_MAX98095=y CONFIG_SOUND_WM8994=y CONFIG_EXYNOS_SPI=y diff --git a/configs/peach-pit_defconfig b/configs/peach-pit_defconfig index 933c823ea86..9a3a11504de 100644 --- a/configs/peach-pit_defconfig +++ b/configs/peach-pit_defconfig @@ -20,6 +20,7 @@ CONFIG_CMD_USB=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_CACHE=y CONFIG_CMD_TIME=y +CONFIG_CMD_SOUND=y CONFIG_CMD_PMIC=y CONFIG_CMD_REGULATOR=y CONFIG_CMD_TPM=y @@ -27,7 +28,6 @@ CONFIG_CMD_TPM_TEST=y CONFIG_CMD_EXT4_WRITE=y CONFIG_DEFAULT_DEVICE_TREE="exynos5420-peach-pit" CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_DM_I2C_COMPAT=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_I2C_MUX=y CONFIG_I2C_ARB_GPIO_CHALLENGE=y @@ -51,6 +51,7 @@ CONFIG_PWM_EXYNOS=y CONFIG_SOUND=y CONFIG_I2S=y CONFIG_I2S_SAMSUNG=y +CONFIG_SOUND_MAX98090=y CONFIG_SOUND_MAX98095=y CONFIG_SOUND_WM8994=y CONFIG_EXYNOS_SPI=y diff --git a/configs/sagem_f@st1704_ram_defconfig b/configs/sagem_f@st1704_ram_defconfig index 91a966327ac..8c36f5dbf83 100644 --- a/configs/sagem_f@st1704_ram_defconfig +++ b/configs/sagem_f@st1704_ram_defconfig @@ -27,11 +27,14 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_SF=y CONFIG_CMD_SPI=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="sagem,f@st1704" -# CONFIG_NET is not set +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y @@ -40,6 +43,9 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_DM_RESET=y CONFIG_RESET_BCM6345=y # CONFIG_SPL_SERIAL_PRESENT is not set diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index e6680d9a594..aede14569df 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -1,5 +1,4 @@ CONFIG_SYS_TEXT_BASE=0 -CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_SANDBOX64=y CONFIG_DISTRO_DEFAULTS=y CONFIG_NR_DRAM_BANKS=1 diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 5b65c6157a0..1e7d41d19e3 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -1,5 +1,4 @@ CONFIG_SYS_TEXT_BASE=0 -CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_DEBUG_UART=y CONFIG_DISTRO_DEFAULTS=y CONFIG_NR_DRAM_BANKS=1 diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 756b839b081..4f3757c8bc5 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -1,5 +1,4 @@ CONFIG_SYS_TEXT_BASE=0 -CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_DISTRO_DEFAULTS=y CONFIG_NR_DRAM_BANKS=1 CONFIG_FIT=y diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig index e71e2d3860c..6c7d08e42e1 100644 --- a/configs/sandbox_noblk_defconfig +++ b/configs/sandbox_noblk_defconfig @@ -1,5 +1,4 @@ CONFIG_SYS_TEXT_BASE=0 -CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_DISTRO_DEFAULTS=y CONFIG_NR_DRAM_BANKS=1 CONFIG_FIT=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index 452a2ef4a50..2f838125289 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -1,7 +1,6 @@ CONFIG_SYS_TEXT_BASE=0 CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL_DRIVERS_MISC_SUPPORT=y CONFIG_SPL=y diff --git a/configs/sfr_nb4-ser_ram_defconfig b/configs/sfr_nb4-ser_ram_defconfig index 12adfb01e7f..39622875b15 100644 --- a/configs/sfr_nb4-ser_ram_defconfig +++ b/configs/sfr_nb4-ser_ram_defconfig @@ -26,11 +26,14 @@ CONFIG_CMD_LICENSE=y CONFIG_CMD_MEMINFO=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_USB=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="sfr,nb4-ser" -# CONFIG_NET is not set +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_BCM6348_IUDMA=y CONFIG_DM_GPIO=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y @@ -42,6 +45,9 @@ CONFIG_FLASH_CFI_DRIVER=y CONFIG_CFI_FLASH=y CONFIG_SYS_FLASH_PROTECTION=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_BCM6348_ETH=y CONFIG_PHY=y CONFIG_BCM6358_USBH_PHY=y CONFIG_DM_RESET=y diff --git a/configs/smdk5250_defconfig b/configs/smdk5250_defconfig index 161454b33fd..21018d8b1b1 100644 --- a/configs/smdk5250_defconfig +++ b/configs/smdk5250_defconfig @@ -30,7 +30,6 @@ CONFIG_CMD_REGULATOR=y CONFIG_CMD_EXT4_WRITE=y CONFIG_DEFAULT_DEVICE_TREE="exynos5250-smdk5250" CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_DM_I2C_COMPAT=y CONFIG_MMC_DW=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_S5P=y diff --git a/configs/smdk5420_defconfig b/configs/smdk5420_defconfig index 433e9a8447f..4e4558944cc 100644 --- a/configs/smdk5420_defconfig +++ b/configs/smdk5420_defconfig @@ -25,7 +25,6 @@ CONFIG_CMD_TIME=y CONFIG_CMD_EXT4_WRITE=y CONFIG_DEFAULT_DEVICE_TREE="exynos5420-smdk5420" CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_DM_I2C_COMPAT=y CONFIG_MMC_DW=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_S5P=y diff --git a/configs/snow_defconfig b/configs/snow_defconfig index 21080091a7d..e0c1bf862c0 100644 --- a/configs/snow_defconfig +++ b/configs/snow_defconfig @@ -34,7 +34,6 @@ CONFIG_CMD_TPM_TEST=y CONFIG_CMD_EXT4_WRITE=y CONFIG_DEFAULT_DEVICE_TREE="exynos5250-snow" CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_DM_I2C_COMPAT=y CONFIG_I2C_CROS_EC_LDO=y CONFIG_I2C_MUX=y CONFIG_I2C_ARB_GPIO_CHALLENGE=y diff --git a/configs/spring_defconfig b/configs/spring_defconfig index ca1799895e8..c089517692e 100644 --- a/configs/spring_defconfig +++ b/configs/spring_defconfig @@ -34,7 +34,6 @@ CONFIG_CMD_TPM_TEST=y CONFIG_CMD_EXT4_WRITE=y CONFIG_DEFAULT_DEVICE_TREE="exynos5250-spring" CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_DM_I2C_COMPAT=y CONFIG_I2C_CROS_EC_LDO=y CONFIG_I2C_MUX=y CONFIG_I2C_ARB_GPIO_CHALLENGE=y diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig new file mode 100644 index 00000000000..fb060767854 --- /dev/null +++ b/configs/tools-only_defconfig @@ -0,0 +1,24 @@ +CONFIG_SYS_TEXT_BASE=0 +CONFIG_ANDROID_BOOT_IMAGE=y +CONFIG_FIT=y +CONFIG_FIT_SIGNATURE=y +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_BOOTM is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_DATE is not set +CONFIG_OF_CONTROL=y +CONFIG_OF_HOSTFILE=y +CONFIG_DEFAULT_DEVICE_TREE="sandbox" +# CONFIG_UDP_FUNCTION_FASTBOOT is not set +CONFIG_SANDBOX_GPIO=y +CONFIG_DM_I2C_COMPAT=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCI_SANDBOX=y +CONFIG_DM_RTC=y +CONFIG_SOUND=y +CONFIG_SYSRESET=y +# CONFIG_VIRTIO_MMIO is not set +# CONFIG_VIRTIO_PCI is not set +# CONFIG_VIRTIO_SANDBOX is not set +# CONFIG_EFI_LOADER is not set diff --git a/configs/uniphier_ld4_sld8_defconfig b/configs/uniphier_ld4_sld8_defconfig index 6b9e22ac0ee..98a00170702 100644 --- a/configs/uniphier_ld4_sld8_defconfig +++ b/configs/uniphier_ld4_sld8_defconfig @@ -9,6 +9,7 @@ CONFIG_ARCH_UNIPHIER_LD4_SLD8=y CONFIG_MICRO_SUPPORT_CARD=y CONFIG_NR_DRAM_BANKS=3 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_BOOTCOMMAND="run ${bootdev}script; run ${bootdev}boot" CONFIG_LOGLEVEL=6 CONFIG_SPL_NAND_SUPPORT=y CONFIG_SPL_NOR_SUPPORT=y diff --git a/configs/uniphier_v7_defconfig b/configs/uniphier_v7_defconfig index 4c06f272b14..bba8e180a5c 100644 --- a/configs/uniphier_v7_defconfig +++ b/configs/uniphier_v7_defconfig @@ -8,6 +8,7 @@ CONFIG_SPL=y CONFIG_MICRO_SUPPORT_CARD=y CONFIG_NR_DRAM_BANKS=3 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_BOOTCOMMAND="run ${bootdev}script; run ${bootdev}boot" CONFIG_LOGLEVEL=6 CONFIG_SPL_NAND_SUPPORT=y CONFIG_SPL_NOR_SUPPORT=y diff --git a/configs/uniphier_v8_defconfig b/configs/uniphier_v8_defconfig index f8f9bdf05c3..df6c5119b05 100644 --- a/configs/uniphier_v8_defconfig +++ b/configs/uniphier_v8_defconfig @@ -7,6 +7,7 @@ CONFIG_ARCH_UNIPHIER_V8_MULTI=y CONFIG_MICRO_SUPPORT_CARD=y CONFIG_NR_DRAM_BANKS=3 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_BOOTCOMMAND="run ${bootdev}script; run ${bootdev}boot" CONFIG_LOGLEVEL=6 CONFIG_CMD_CONFIG=y CONFIG_CMD_IMLS=y diff --git a/doc/README.ae350 b/doc/README.ae350 index fe75b80eb77..189a6b7ec32 100644 --- a/doc/README.ae350 +++ b/doc/README.ae350 @@ -25,7 +25,7 @@ Build and boot steps build: 1. Prepare the toolchains and make sure the $PATH to toolchains is correct. -2. Use `make ax25-ae350_defconfig` in u-boot root to build the image. +2. Use `make ae350_rv[32|64]_defconfig` in u-boot root to build the image for 32 or 64 bit. Verification ==================== diff --git a/doc/README.commands b/doc/README.commands index 1d29c4d91dd..0ccadae0b71 100644 --- a/doc/README.commands +++ b/doc/README.commands @@ -28,6 +28,42 @@ comp: Pointer to the completion function. May be NULL. entering the command arguments to complete the entry. Command completion is only available if CONFIG_AUTO_COMPLETE is defined. +Sub-command definition +---------------------- + +Likewise an array of cmd_tbl_t holding sub-commands can be created using either +of the following macros: + +* U_BOOT_CMD_MKENT(name, maxargs, repeatable, command, "usage", "help") +* U_BOOT_CMD_MKENTCOMPLETE(name, maxargs, repeatable, command, "usage, "help", + comp) + +This table has to be evaluated in the command function of the main command, e.g. + + static cmd_tbl_t cmd_sub[] = { + U_BOOT_CMD_MKENT(foo, CONFIG_SYS_MAXARGS, 1, do_foo, "", ""), + U_BOOT_CMD_MKENT(bar, CONFIG_SYS_MAXARGS, 1, do_bar, "", ""), + }; + + static int do_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) + { + cmd_tbl_t *cp; + + if (argc < 2) + return CMD_RET_USAGE; + + /* drop sub-command argument */ + argc--; + argv++; + + cp = find_cmd_tbl(argv[0], cmd_ut_sub, ARRAY_SIZE(cmd_sub)); + + if (cp) + return cp->cmd(cmdtp, flag, argc, argv); + + return CMD_RET_USAGE; + } + Command function ---------------- diff --git a/drivers/Makefile b/drivers/Makefile index c3c0615c29b..8c53e05d2f5 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_SPL_ETH_SUPPORT) += net/phy/ obj-$(CONFIG_SPL_USB_ETHER) += net/phy/ obj-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += usb/musb-new/ obj-$(CONFIG_SPL_USB_GADGET_SUPPORT) += usb/gadget/ +obj-$(CONFIG_SPL_USB_GADGET_SUPPORT) += usb/common/ obj-$(CONFIG_SPL_USB_GADGET_SUPPORT) += usb/gadget/udc/ obj-$(CONFIG_SPL_DFU_SUPPORT) += dfu/ obj-$(CONFIG_SPL_WATCHDOG_SUPPORT) += watchdog/ diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c b/drivers/clk/uniphier/clk-uniphier-sys.c index 9e087b6bd28..487b43ebdab 100644 --- a/drivers/clk/uniphier/clk-uniphier-sys.c +++ b/drivers/clk/uniphier/clk-uniphier-sys.c @@ -6,13 +6,12 @@ #include "clk-uniphier.h" -/* Denali driver requires clk_x rate (clk: 50MHz, clk_x & ecc_clk: 200MHz) */ #define UNIPHIER_LD4_SYS_CLK_NAND(_id) \ - UNIPHIER_CLK_RATE(128, 200000000), \ + UNIPHIER_CLK_RATE(128, 50000000), \ UNIPHIER_CLK_GATE((_id), 128, 0x2104, 2) #define UNIPHIER_LD11_SYS_CLK_NAND(_id) \ - UNIPHIER_CLK_RATE(128, 200000000), \ + UNIPHIER_CLK_RATE(128, 50000000), \ UNIPHIER_CLK_GATE((_id), 128, 0x210c, 0) const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = { @@ -20,6 +19,7 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = { defined(CONFIG_ARCH_UNIPHIER_PRO4) || defined(CONFIG_ARCH_UNIPHIER_PRO5) ||\ defined(CONFIG_ARCH_UNIPHIER_PXS2) || defined(CONFIG_ARCH_UNIPHIER_LD6B) UNIPHIER_LD4_SYS_CLK_NAND(2), + UNIPHIER_CLK_RATE(3, 200000000), UNIPHIER_CLK_GATE_SIMPLE(6, 0x2104, 12), /* ether (Pro4, PXs2) */ UNIPHIER_CLK_GATE_SIMPLE(7, 0x2104, 5), /* ether-gb (Pro4) */ UNIPHIER_CLK_GATE_SIMPLE(8, 0x2104, 10), /* stdmac */ @@ -36,6 +36,7 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = { const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = { #if defined(CONFIG_ARCH_UNIPHIER_LD11) || defined(CONFIG_ARCH_UNIPHIER_LD20) UNIPHIER_LD11_SYS_CLK_NAND(2), + UNIPHIER_CLK_RATE(3, 200000000), UNIPHIER_CLK_GATE_SIMPLE(6, 0x210c, 6), /* ether */ UNIPHIER_CLK_GATE_SIMPLE(8, 0x210c, 8), /* stdmac */ UNIPHIER_CLK_GATE_SIMPLE(14, 0x210c, 14), /* usb30 (LD20) */ @@ -48,6 +49,7 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = { const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[] = { #if defined(CONFIG_ARCH_UNIPHIER_PXS3) UNIPHIER_LD11_SYS_CLK_NAND(2), + UNIPHIER_CLK_RATE(3, 200000000), UNIPHIER_CLK_GATE_SIMPLE(6, 0x210c, 9), /* ether0 */ UNIPHIER_CLK_GATE_SIMPLE(7, 0x210c, 10), /* ether1 */ UNIPHIER_CLK_GATE_SIMPLE(12, 0x210c, 4), /* usb30 (gio0) */ diff --git a/drivers/core/read.c b/drivers/core/read.c index cdd78be03e2..3c46b3674ed 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -21,6 +21,29 @@ int dev_read_u32_default(struct udevice *dev, const char *propname, int def) return ofnode_read_u32_default(dev_ofnode(dev), propname, def); } +int dev_read_s32(struct udevice *dev, const char *propname, s32 *outp) +{ + return ofnode_read_u32(dev_ofnode(dev), propname, (u32 *)outp); +} + +int dev_read_s32_default(struct udevice *dev, const char *propname, int def) +{ + return ofnode_read_u32_default(dev_ofnode(dev), propname, def); +} + +int dev_read_u32u(struct udevice *dev, const char *propname, uint *outp) +{ + u32 val; + int ret; + + ret = ofnode_read_u32(dev_ofnode(dev), propname, &val); + if (ret) + return ret; + *outp = val; + + return 0; +} + const char *dev_read_string(struct udevice *dev, const char *propname) { return ofnode_read_string(dev_ofnode(dev), propname); diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c index 661cf61d62a..3cf9dd9dbe4 100644 --- a/drivers/core/syscon-uclass.c +++ b/drivers/core/syscon-uclass.c @@ -146,52 +146,31 @@ U_BOOT_DRIVER(generic_syscon) = { * The syscon node can be bound to another driver, but still works * as a syscon provider. */ -static LIST_HEAD(syscon_list); - -struct syscon { - ofnode node; - struct regmap *regmap; - struct list_head list; -}; - -static struct syscon *of_syscon_register(ofnode node) +struct regmap *syscon_node_to_regmap(ofnode node) { - struct syscon *syscon; + struct udevice *dev, *parent; int ret; + if (!uclass_get_device_by_ofnode(UCLASS_SYSCON, node, &dev)) + return syscon_get_regmap(dev); + if (!ofnode_device_is_compatible(node, "syscon")) return ERR_PTR(-EINVAL); - syscon = malloc(sizeof(*syscon)); - if (!syscon) - return ERR_PTR(-ENOMEM); + /* bound to driver with same ofnode or to root if not found */ + if (device_find_global_by_ofnode(node, &parent)) + parent = dm_root(); - ret = regmap_init_mem(node, &syscon->regmap); - if (ret) { - free(syscon); + /* force bound to syscon class */ + ret = device_bind_driver_to_node(parent, "syscon", + ofnode_get_name(node), + node, &dev); + if (ret) return ERR_PTR(ret); - } - - list_add_tail(&syscon->list, &syscon_list); - - return syscon; -} -struct regmap *syscon_node_to_regmap(ofnode node) -{ - struct syscon *entry, *syscon = NULL; - - list_for_each_entry(entry, &syscon_list, list) - if (ofnode_equal(entry->node, node)) { - syscon = entry; - break; - } - - if (!syscon) - syscon = of_syscon_register(node); - - if (IS_ERR(syscon)) - return ERR_CAST(syscon); + ret = device_probe(dev); + if (ret) + return ERR_PTR(ret); - return syscon->regmap; + return syscon_get_regmap(dev); } diff --git a/drivers/cpu/Kconfig b/drivers/cpu/Kconfig index d4052005e24..3d5729f6dca 100644 --- a/drivers/cpu/Kconfig +++ b/drivers/cpu/Kconfig @@ -13,3 +13,9 @@ config CPU_MPC83XX select CLK_MPC83XX help Support CPU cores for SoCs of the MPC83xx series. + +config CPU_RISCV + bool "Enable RISC-V CPU driver" + depends on CPU && RISCV + help + Support CPU cores for RISC-V architecture. diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile index 858b03755f5..be0300cd4a8 100644 --- a/drivers/cpu/Makefile +++ b/drivers/cpu/Makefile @@ -8,4 +8,5 @@ obj-$(CONFIG_CPU) += cpu-uclass.o obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o +obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o obj-$(CONFIG_SANDBOX) += cpu_sandbox.o diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c new file mode 100644 index 00000000000..5e15df590e4 --- /dev/null +++ b/drivers/cpu/riscv_cpu.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <common.h> +#include <cpu.h> +#include <dm.h> +#include <errno.h> +#include <dm/device-internal.h> +#include <dm/lists.h> + +static int riscv_cpu_get_desc(struct udevice *dev, char *buf, int size) +{ + const char *isa; + + isa = dev_read_string(dev, "riscv,isa"); + if (size < (strlen(isa) + 1)) + return -ENOSPC; + + strcpy(buf, isa); + + return 0; +} + +static int riscv_cpu_get_info(struct udevice *dev, struct cpu_info *info) +{ + const char *mmu; + + dev_read_u32(dev, "clock-frequency", (u32 *)&info->cpu_freq); + + mmu = dev_read_string(dev, "mmu-type"); + if (!mmu) + info->features |= BIT(CPU_FEAT_MMU); + + return 0; +} + +static int riscv_cpu_get_count(struct udevice *dev) +{ + ofnode node; + int num = 0; + + ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) { + const char *device_type; + + device_type = ofnode_read_string(node, "device_type"); + if (!device_type) + continue; + if (strcmp(device_type, "cpu") == 0) + num++; + } + + return num; +} + +static int riscv_cpu_bind(struct udevice *dev) +{ + struct cpu_platdata *plat = dev_get_parent_platdata(dev); + struct driver *drv; + int ret; + + /* save the hart id */ + plat->cpu_id = dev_read_addr(dev); + + /* first examine the property in current cpu node */ + ret = dev_read_u32(dev, "timebase-frequency", &plat->timebase_freq); + /* if not found, then look at the parent /cpus node */ + if (ret) + dev_read_u32(dev->parent, "timebase-frequency", + &plat->timebase_freq); + + /* + * Bind riscv-timer driver on hart 0 + * + * We only instantiate one timer device which is enough for U-Boot. + * Pass the "timebase-frequency" value as the driver data for the + * timer device. + * + * Return value is not checked since it's possible that the timer + * driver is not included. + */ + if (!plat->cpu_id && plat->timebase_freq) { + drv = lists_driver_lookup_name("riscv_timer"); + if (!drv) { + debug("Cannot find the timer driver, not included?\n"); + return 0; + } + + device_bind_with_driver_data(dev, drv, "riscv_timer", + plat->timebase_freq, ofnode_null(), + NULL); + } + + return 0; +} + +static const struct cpu_ops riscv_cpu_ops = { + .get_desc = riscv_cpu_get_desc, + .get_info = riscv_cpu_get_info, + .get_count = riscv_cpu_get_count, +}; + +static const struct udevice_id riscv_cpu_ids[] = { + { .compatible = "riscv" }, + { } +}; + +U_BOOT_DRIVER(riscv_cpu) = { + .name = "riscv_cpu", + .id = UCLASS_CPU, + .of_match = riscv_cpu_ids, + .bind = riscv_cpu_bind, + .ops = &riscv_cpu_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 8a4162eccdb..1820676d7a1 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -26,6 +26,15 @@ config SANDBOX_DMA Enable support for a test DMA uclass implementation. It stimulates DMA transfer by simple copying data between channels. +config BCM6348_IUDMA + bool "BCM6348 IUDMA driver" + depends on ARCH_BMIPS + select DMA_CHANNELS + help + Enable the BCM6348 IUDMA driver. + This driver support data transfer from devices to + memory and from memory to devices. + config TI_EDMA3 bool "TI EDMA3 driver" help diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index aff31f986a1..b5f9147e0a5 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_DMA) += dma-uclass.o obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o obj-$(CONFIG_APBH_DMA) += apbh_dma.o +obj-$(CONFIG_BCM6348_IUDMA) += bcm6348-iudma.o obj-$(CONFIG_FSL_DMA) += fsl_dma.o obj-$(CONFIG_SANDBOX_DMA) += sandbox-dma-test.o obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c new file mode 100644 index 00000000000..1d3c192cfe5 --- /dev/null +++ b/drivers/dma/bcm6348-iudma.c @@ -0,0 +1,642 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> + * + * Derived from linux/drivers/dma/bcm63xx-iudma.c: + * Copyright (C) 2015 Simon Arlott <simon@fire.lp0.eu> + * + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c: + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + * + * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h: + * Copyright (C) 2000-2010 Broadcom Corporation + * + * Derived from bcm963xx_4.12L.06B_consumer/bcmdrivers/opensource/net/enet/impl4/bcmenet.c: + * Copyright (C) 2010 Broadcom Corporation + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <dma-uclass.h> +#include <memalign.h> +#include <reset.h> +#include <asm/io.h> + +#define DMA_RX_DESC 6 +#define DMA_TX_DESC 1 + +/* DMA Channels */ +#define DMA_CHAN_FLOWC(x) ((x) >> 1) +#define DMA_CHAN_MAX 16 +#define DMA_CHAN_SIZE 0x10 +#define DMA_CHAN_TOUT 500 + +/* DMA Global Configuration register */ +#define DMA_CFG_REG 0x00 +#define DMA_CFG_ENABLE_SHIFT 0 +#define DMA_CFG_ENABLE_MASK (1 << DMA_CFG_ENABLE_SHIFT) +#define DMA_CFG_FLOWC_ENABLE(x) BIT(DMA_CHAN_FLOWC(x) + 1) +#define DMA_CFG_NCHANS_SHIFT 24 +#define DMA_CFG_NCHANS_MASK (0xf << DMA_CFG_NCHANS_SHIFT) + +/* DMA Global Flow Control registers */ +#define DMA_FLOWC_THR_LO_REG(x) (0x04 + DMA_CHAN_FLOWC(x) * 0x0c) +#define DMA_FLOWC_THR_HI_REG(x) (0x08 + DMA_CHAN_FLOWC(x) * 0x0c) +#define DMA_FLOWC_ALLOC_REG(x) (0x0c + DMA_CHAN_FLOWC(x) * 0x0c) +#define DMA_FLOWC_ALLOC_FORCE_SHIFT 31 +#define DMA_FLOWC_ALLOC_FORCE_MASK (1 << DMA_FLOWC_ALLOC_FORCE_SHIFT) + +/* DMA Global Reset register */ +#define DMA_RST_REG 0x34 +#define DMA_RST_CHAN_SHIFT 0 +#define DMA_RST_CHAN_MASK(x) (1 << x) + +/* DMA Channel Configuration register */ +#define DMAC_CFG_REG(x) (DMA_CHAN_SIZE * (x) + 0x00) +#define DMAC_CFG_ENABLE_SHIFT 0 +#define DMAC_CFG_ENABLE_MASK (1 << DMAC_CFG_ENABLE_SHIFT) +#define DMAC_CFG_PKT_HALT_SHIFT 1 +#define DMAC_CFG_PKT_HALT_MASK (1 << DMAC_CFG_PKT_HALT_SHIFT) +#define DMAC_CFG_BRST_HALT_SHIFT 2 +#define DMAC_CFG_BRST_HALT_MASK (1 << DMAC_CFG_BRST_HALT_SHIFT) + +/* DMA Channel Max Burst Length register */ +#define DMAC_BURST_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c) + +/* DMA SRAM Descriptor Ring Start register */ +#define DMAS_RSTART_REG(x) (DMA_CHAN_SIZE * (x) + 0x00) + +/* DMA SRAM State/Bytes done/ring offset register */ +#define DMAS_STATE_DATA_REG(x) (DMA_CHAN_SIZE * (x) + 0x04) + +/* DMA SRAM Buffer Descriptor status and length register */ +#define DMAS_DESC_LEN_STATUS_REG(x) (DMA_CHAN_SIZE * (x) + 0x08) + +/* DMA SRAM Buffer Descriptor status and length register */ +#define DMAS_DESC_BASE_BUFPTR_REG(x) (DMA_CHAN_SIZE * (x) + 0x0c) + +/* DMA Descriptor Status */ +#define DMAD_ST_CRC_SHIFT 8 +#define DMAD_ST_CRC_MASK (1 << DMAD_ST_CRC_SHIFT) +#define DMAD_ST_WRAP_SHIFT 12 +#define DMAD_ST_WRAP_MASK (1 << DMAD_ST_WRAP_SHIFT) +#define DMAD_ST_SOP_SHIFT 13 +#define DMAD_ST_SOP_MASK (1 << DMAD_ST_SOP_SHIFT) +#define DMAD_ST_EOP_SHIFT 14 +#define DMAD_ST_EOP_MASK (1 << DMAD_ST_EOP_SHIFT) +#define DMAD_ST_OWN_SHIFT 15 +#define DMAD_ST_OWN_MASK (1 << DMAD_ST_OWN_SHIFT) + +#define DMAD6348_ST_OV_ERR_SHIFT 0 +#define DMAD6348_ST_OV_ERR_MASK (1 << DMAD6348_ST_OV_ERR_SHIFT) +#define DMAD6348_ST_CRC_ERR_SHIFT 1 +#define DMAD6348_ST_CRC_ERR_MASK (1 << DMAD6348_ST_CRC_ERR_SHIFT) +#define DMAD6348_ST_RX_ERR_SHIFT 2 +#define DMAD6348_ST_RX_ERR_MASK (1 << DMAD6348_ST_RX_ERR_SHIFT) +#define DMAD6348_ST_OS_ERR_SHIFT 4 +#define DMAD6348_ST_OS_ERR_MASK (1 << DMAD6348_ST_OS_ERR_SHIFT) +#define DMAD6348_ST_UN_ERR_SHIFT 9 +#define DMAD6348_ST_UN_ERR_MASK (1 << DMAD6348_ST_UN_ERR_SHIFT) + +struct bcm6348_dma_desc { + uint16_t length; + uint16_t status; + uint32_t address; +}; + +struct bcm6348_chan_priv { + void __iomem *dma_ring; + uint8_t dma_ring_size; + uint8_t desc_id; + uint8_t desc_cnt; + bool *busy_desc; + bool running; +}; + +struct bcm6348_iudma_hw { + uint16_t err_mask; +}; + +struct bcm6348_iudma_priv { + const struct bcm6348_iudma_hw *hw; + void __iomem *base; + void __iomem *chan; + void __iomem *sram; + struct bcm6348_chan_priv **ch_priv; + uint8_t n_channels; +}; + +static inline bool bcm6348_iudma_chan_is_rx(uint8_t ch) +{ + return !(ch & 1); +} + +static inline void bcm6348_iudma_fdc(void *ptr, ulong size) +{ + ulong start = (ulong) ptr; + + flush_dcache_range(start, start + size); +} + +static inline void bcm6348_iudma_idc(void *ptr, ulong size) +{ + ulong start = (ulong) ptr; + + invalidate_dcache_range(start, start + size); +} + +static void bcm6348_iudma_chan_stop(struct bcm6348_iudma_priv *priv, + uint8_t ch) +{ + unsigned int timeout = DMA_CHAN_TOUT; + + do { + uint32_t cfg, halt; + + if (timeout > DMA_CHAN_TOUT / 2) + halt = DMAC_CFG_PKT_HALT_MASK; + else + halt = DMAC_CFG_BRST_HALT_MASK; + + /* try to stop dma channel */ + writel_be(halt, priv->chan + DMAC_CFG_REG(ch)); + mb(); + + /* check if channel was stopped */ + cfg = readl_be(priv->chan + DMAC_CFG_REG(ch)); + if (!(cfg & DMAC_CFG_ENABLE_MASK)) + break; + + udelay(1); + } while (--timeout); + + if (!timeout) + pr_err("unable to stop channel %u\n", ch); + + /* reset dma channel */ + setbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch)); + mb(); + clrbits_be32(priv->base + DMA_RST_REG, DMA_RST_CHAN_MASK(ch)); +} + +static int bcm6348_iudma_disable(struct dma *dma) +{ + struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev); + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id]; + + /* stop dma channel */ + bcm6348_iudma_chan_stop(priv, dma->id); + + /* dma flow control */ + if (bcm6348_iudma_chan_is_rx(dma->id)) + writel_be(DMA_FLOWC_ALLOC_FORCE_MASK, + DMA_FLOWC_ALLOC_REG(dma->id)); + + /* init channel config */ + ch_priv->running = false; + ch_priv->desc_id = 0; + if (bcm6348_iudma_chan_is_rx(dma->id)) + ch_priv->desc_cnt = 0; + else + ch_priv->desc_cnt = ch_priv->dma_ring_size; + + return 0; +} + +static int bcm6348_iudma_enable(struct dma *dma) +{ + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev); + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id]; + struct bcm6348_dma_desc *dma_desc = ch_priv->dma_ring; + uint8_t i; + + /* dma ring init */ + for (i = 0; i < ch_priv->desc_cnt; i++) { + if (bcm6348_iudma_chan_is_rx(dma->id)) { + ch_priv->busy_desc[i] = false; + dma_desc->status |= DMAD_ST_OWN_MASK; + } else { + dma_desc->status = 0; + dma_desc->length = 0; + dma_desc->address = 0; + } + + if (i == ch_priv->desc_cnt - 1) + dma_desc->status |= DMAD_ST_WRAP_MASK; + + dma_desc++; + } + + /* init to first descriptor */ + ch_priv->desc_id = 0; + + /* force cache writeback */ + bcm6348_iudma_fdc(ch_priv->dma_ring, + sizeof(*dma_desc) * ch_priv->desc_cnt); + + /* clear sram */ + writel_be(0, priv->sram + DMAS_STATE_DATA_REG(dma->id)); + writel_be(0, priv->sram + DMAS_DESC_LEN_STATUS_REG(dma->id)); + writel_be(0, priv->sram + DMAS_DESC_BASE_BUFPTR_REG(dma->id)); + + /* set dma ring start */ + writel_be(virt_to_phys(ch_priv->dma_ring), + priv->sram + DMAS_RSTART_REG(dma->id)); + + /* set flow control */ + if (bcm6348_iudma_chan_is_rx(dma->id)) { + u32 val; + + setbits_be32(priv->base + DMA_CFG_REG, + DMA_CFG_FLOWC_ENABLE(dma->id)); + + val = ch_priv->desc_cnt / 3; + writel_be(val, priv->base + DMA_FLOWC_THR_LO_REG(dma->id)); + + val = (ch_priv->desc_cnt * 2) / 3; + writel_be(val, priv->base + DMA_FLOWC_THR_HI_REG(dma->id)); + + writel_be(0, priv->base + DMA_FLOWC_ALLOC_REG(dma->id)); + } + + /* set dma max burst */ + writel_be(ch_priv->desc_cnt, + priv->chan + DMAC_BURST_REG(dma->id)); + + /* kick rx dma channel */ + if (bcm6348_iudma_chan_is_rx(dma->id)) + setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), + DMAC_CFG_ENABLE_MASK); + + /* channel is now enabled */ + ch_priv->running = true; + + return 0; +} + +static int bcm6348_iudma_request(struct dma *dma) +{ + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev); + struct bcm6348_chan_priv *ch_priv; + + /* check if channel is valid */ + if (dma->id >= priv->n_channels) + return -ENODEV; + + /* alloc channel private data */ + priv->ch_priv[dma->id] = calloc(1, sizeof(struct bcm6348_chan_priv)); + if (!priv->ch_priv[dma->id]) + return -ENOMEM; + ch_priv = priv->ch_priv[dma->id]; + + /* alloc dma ring */ + if (bcm6348_iudma_chan_is_rx(dma->id)) + ch_priv->dma_ring_size = DMA_RX_DESC; + else + ch_priv->dma_ring_size = DMA_TX_DESC; + + ch_priv->dma_ring = + malloc_cache_aligned(sizeof(struct bcm6348_dma_desc) * + ch_priv->dma_ring_size); + if (!ch_priv->dma_ring) + return -ENOMEM; + + /* init channel config */ + ch_priv->running = false; + ch_priv->desc_id = 0; + if (bcm6348_iudma_chan_is_rx(dma->id)) { + ch_priv->desc_cnt = 0; + ch_priv->busy_desc = calloc(ch_priv->desc_cnt, sizeof(bool)); + } else { + ch_priv->desc_cnt = ch_priv->dma_ring_size; + ch_priv->busy_desc = NULL; + } + + return 0; +} + +static int bcm6348_iudma_receive(struct dma *dma, void **dst, void *metadata) +{ + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev); + const struct bcm6348_iudma_hw *hw = priv->hw; + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id]; + struct bcm6348_dma_desc *dma_desc = dma_desc = ch_priv->dma_ring; + int ret; + + /* get dma ring descriptor address */ + dma_desc += ch_priv->desc_id; + + /* invalidate cache data */ + bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc)); + + /* check dma own */ + if (dma_desc->status & DMAD_ST_OWN_MASK) + return -EAGAIN; + + /* check pkt */ + if (!(dma_desc->status & DMAD_ST_EOP_MASK) || + !(dma_desc->status & DMAD_ST_SOP_MASK) || + (dma_desc->status & hw->err_mask)) { + pr_err("invalid pkt received (ch=%ld desc=%u) (st=%04x)\n", + dma->id, ch_priv->desc_id, dma_desc->status); + ret = -EAGAIN; + } else { + /* set dma buffer address */ + *dst = phys_to_virt(dma_desc->address); + + /* invalidate cache data */ + bcm6348_iudma_idc(*dst, dma_desc->length); + + /* return packet length */ + ret = dma_desc->length; + } + + /* busy dma descriptor */ + ch_priv->busy_desc[ch_priv->desc_id] = true; + + /* increment dma descriptor */ + ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt; + + return ret; +} + +static int bcm6348_iudma_send(struct dma *dma, void *src, size_t len, + void *metadata) +{ + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev); + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id]; + struct bcm6348_dma_desc *dma_desc; + uint16_t status; + + /* flush cache */ + bcm6348_iudma_fdc(src, len); + + /* get dma ring descriptor address */ + dma_desc = ch_priv->dma_ring; + dma_desc += ch_priv->desc_id; + + /* config dma descriptor */ + status = (DMAD_ST_OWN_MASK | + DMAD_ST_EOP_MASK | + DMAD_ST_CRC_MASK | + DMAD_ST_SOP_MASK); + if (ch_priv->desc_id == ch_priv->desc_cnt - 1) + status |= DMAD_ST_WRAP_MASK; + + /* set dma descriptor */ + dma_desc->address = virt_to_phys(src); + dma_desc->length = len; + dma_desc->status = status; + + /* flush cache */ + bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc)); + + /* kick tx dma channel */ + setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), DMAC_CFG_ENABLE_MASK); + + /* poll dma status */ + do { + /* invalidate cache */ + bcm6348_iudma_idc(dma_desc, sizeof(*dma_desc)); + + if (!(dma_desc->status & DMAD_ST_OWN_MASK)) + break; + } while(1); + + /* increment dma descriptor */ + ch_priv->desc_id = (ch_priv->desc_id + 1) % ch_priv->desc_cnt; + + return 0; +} + +static int bcm6348_iudma_free_rcv_buf(struct dma *dma, void *dst, size_t size) +{ + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev); + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id]; + struct bcm6348_dma_desc *dma_desc = ch_priv->dma_ring; + uint16_t status; + uint8_t i; + u32 cfg; + + /* get dirty dma descriptor */ + for (i = 0; i < ch_priv->desc_cnt; i++) { + if (phys_to_virt(dma_desc->address) == dst) + break; + + dma_desc++; + } + + /* dma descriptor not found */ + if (i == ch_priv->desc_cnt) { + pr_err("dirty dma descriptor not found\n"); + return -ENOENT; + } + + /* invalidate cache */ + bcm6348_iudma_idc(ch_priv->dma_ring, + sizeof(*dma_desc) * ch_priv->desc_cnt); + + /* free dma descriptor */ + ch_priv->busy_desc[i] = false; + + status = DMAD_ST_OWN_MASK; + if (i == ch_priv->desc_cnt - 1) + status |= DMAD_ST_WRAP_MASK; + + dma_desc->status |= status; + dma_desc->length = PKTSIZE_ALIGN; + + /* tell dma we allocated one buffer */ + writel_be(1, DMA_FLOWC_ALLOC_REG(dma->id)); + + /* flush cache */ + bcm6348_iudma_fdc(ch_priv->dma_ring, + sizeof(*dma_desc) * ch_priv->desc_cnt); + + /* kick rx dma channel if disabled */ + cfg = readl_be(priv->chan + DMAC_CFG_REG(dma->id)); + if (!(cfg & DMAC_CFG_ENABLE_MASK)) + setbits_be32(priv->chan + DMAC_CFG_REG(dma->id), + DMAC_CFG_ENABLE_MASK); + + return 0; +} + +static int bcm6348_iudma_add_rcv_buf(struct dma *dma, void *dst, size_t size) +{ + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev); + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id]; + struct bcm6348_dma_desc *dma_desc = ch_priv->dma_ring; + + /* no more dma descriptors available */ + if (ch_priv->desc_cnt == ch_priv->dma_ring_size) { + pr_err("max number of buffers reached\n"); + return -EINVAL; + } + + /* get next dma descriptor */ + dma_desc += ch_priv->desc_cnt; + + /* init dma descriptor */ + dma_desc->address = virt_to_phys(dst); + dma_desc->length = size; + dma_desc->status = 0; + + /* flush cache */ + bcm6348_iudma_fdc(dma_desc, sizeof(*dma_desc)); + + /* increment dma descriptors */ + ch_priv->desc_cnt++; + + return 0; +} + +static int bcm6348_iudma_prepare_rcv_buf(struct dma *dma, void *dst, + size_t size) +{ + const struct bcm6348_iudma_priv *priv = dev_get_priv(dma->dev); + struct bcm6348_chan_priv *ch_priv = priv->ch_priv[dma->id]; + + /* only add new rx buffers if channel isn't running */ + if (ch_priv->running) + return bcm6348_iudma_free_rcv_buf(dma, dst, size); + else + return bcm6348_iudma_add_rcv_buf(dma, dst, size); +} + +static const struct dma_ops bcm6348_iudma_ops = { + .disable = bcm6348_iudma_disable, + .enable = bcm6348_iudma_enable, + .prepare_rcv_buf = bcm6348_iudma_prepare_rcv_buf, + .request = bcm6348_iudma_request, + .receive = bcm6348_iudma_receive, + .send = bcm6348_iudma_send, +}; + +static const struct bcm6348_iudma_hw bcm6348_hw = { + .err_mask = (DMAD6348_ST_OV_ERR_MASK | + DMAD6348_ST_CRC_ERR_MASK | + DMAD6348_ST_RX_ERR_MASK | + DMAD6348_ST_OS_ERR_MASK | + DMAD6348_ST_UN_ERR_MASK), +}; + +static const struct bcm6348_iudma_hw bcm6368_hw = { + .err_mask = 0, +}; + +static const struct udevice_id bcm6348_iudma_ids[] = { + { + .compatible = "brcm,bcm6348-iudma", + .data = (ulong)&bcm6348_hw, + }, { + .compatible = "brcm,bcm6368-iudma", + .data = (ulong)&bcm6368_hw, + }, { /* sentinel */ } +}; + +static int bcm6348_iudma_probe(struct udevice *dev) +{ + struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct bcm6348_iudma_priv *priv = dev_get_priv(dev); + const struct bcm6348_iudma_hw *hw = + (const struct bcm6348_iudma_hw *)dev_get_driver_data(dev); + uint8_t ch; + int i; + + uc_priv->supported = (DMA_SUPPORTS_DEV_TO_MEM | + DMA_SUPPORTS_MEM_TO_DEV); + priv->hw = hw; + + /* dma global base address */ + priv->base = dev_remap_addr_name(dev, "dma"); + if (!priv->base) + return -EINVAL; + + /* dma channels base address */ + priv->chan = dev_remap_addr_name(dev, "dma-channels"); + if (!priv->chan) + return -EINVAL; + + /* dma sram base address */ + priv->sram = dev_remap_addr_name(dev, "dma-sram"); + if (!priv->sram) + return -EINVAL; + + /* get number of channels */ + priv->n_channels = dev_read_u32_default(dev, "dma-channels", 8); + if (priv->n_channels > DMA_CHAN_MAX) + return -EINVAL; + + /* try to enable clocks */ + for (i = 0; ; i++) { + struct clk clk; + int ret; + + ret = clk_get_by_index(dev, i, &clk); + if (ret < 0) + break; + + ret = clk_enable(&clk); + if (ret < 0) { + pr_err("error enabling clock %d\n", i); + return ret; + } + + ret = clk_free(&clk); + if (ret < 0) { + pr_err("error freeing clock %d\n", i); + return ret; + } + } + + /* try to perform resets */ + for (i = 0; ; i++) { + struct reset_ctl reset; + int ret; + + ret = reset_get_by_index(dev, i, &reset); + if (ret < 0) + break; + + ret = reset_deassert(&reset); + if (ret < 0) { + pr_err("error deasserting reset %d\n", i); + return ret; + } + + ret = reset_free(&reset); + if (ret < 0) { + pr_err("error freeing reset %d\n", i); + return ret; + } + } + + /* disable dma controller */ + clrbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK); + + /* alloc channel private data pointers */ + priv->ch_priv = calloc(priv->n_channels, + sizeof(struct bcm6348_chan_priv*)); + if (!priv->ch_priv) + return -ENOMEM; + + /* stop dma channels */ + for (ch = 0; ch < priv->n_channels; ch++) + bcm6348_iudma_chan_stop(priv, ch); + + /* enable dma controller */ + setbits_be32(priv->base + DMA_CFG_REG, DMA_CFG_ENABLE_MASK); + + return 0; +} + +U_BOOT_DRIVER(bcm6348_iudma) = { + .name = "bcm6348_iudma", + .id = UCLASS_DMA, + .of_match = bcm6348_iudma_ids, + .ops = &bcm6348_iudma_ops, + .priv_auto_alloc_size = sizeof(struct bcm6348_iudma_priv), + .probe = bcm6348_iudma_probe, +}; diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 50e901973d1..8f59193e3c2 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -31,6 +31,17 @@ config FPGA_CYCLON2 Enable FPGA driver for loading bitstream in BIT and BIN format on Altera Cyclone II device. +config FPGA_STRATIX10 + bool "Enable Altera FPGA driver for Stratix 10" + depends on TARGET_SOCFPGA_STRATIX10 + select FPGA_ALTERA + help + Say Y here to enable the Altera Stratix 10 FPGA specific driver + + This provides common functionality for Altera Stratix 10 devices. + Enable FPGA driver for writing bitstream into Altera Stratix10 + device. + config FPGA_XILINX bool "Enable Xilinx FPGA drivers" select FPGA diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index 97d7d5d9be3..5a778c10e80 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_FPGA_ACEX1K) += ACEX1K.o obj-$(CONFIG_FPGA_CYCLON2) += cyclon2.o obj-$(CONFIG_FPGA_STRATIX_II) += stratixII.o obj-$(CONFIG_FPGA_STRATIX_V) += stratixv.o +obj-$(CONFIG_FPGA_STRATIX10) += stratix10.o obj-$(CONFIG_FPGA_SOCFPGA) += socfpga.o obj-$(CONFIG_TARGET_SOCFPGA_GEN5) += socfpga_gen5.o obj-$(CONFIG_TARGET_SOCFPGA_ARRIA10) += socfpga_arria10.o diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c index 9605554c6aa..7c8f5185095 100644 --- a/drivers/fpga/altera.c +++ b/drivers/fpga/altera.c @@ -39,6 +39,9 @@ static const struct altera_fpga { #if defined(CONFIG_FPGA_STRATIX_V) { Altera_StratixV, "StratixV", stratixv_load, NULL, NULL }, #endif +#if defined(CONFIG_FPGA_STRATIX10) + { Intel_FPGA_Stratix10, "Stratix10", stratix10_load, NULL, NULL }, +#endif #if defined(CONFIG_FPGA_SOCFPGA) { Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL }, #endif @@ -154,6 +157,9 @@ int altera_info(Altera_desc *desc) case fast_passive_parallel_security: printf("Fast Passive Parallel with Security (FPPS)\n"); break; + case secure_device_manager_mailbox: + puts("Secure Device Manager (SDM) Mailbox\n"); + break; /* Add new interface types here */ default: printf("Unsupported interface type, %d\n", desc->iface); diff --git a/drivers/fpga/stratix10.c b/drivers/fpga/stratix10.c new file mode 100644 index 00000000000..aae052130e0 --- /dev/null +++ b/drivers/fpga/stratix10.c @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Intel Corporation <www.intel.com> + */ + +#include <common.h> +#include <altera.h> +#include <asm/arch/mailbox_s10.h> + +#define RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS 60000 +#define RECONFIG_STATUS_INTERVAL_DELAY_US 1000000 + +static const struct mbox_cfgstat_state { + int err_no; + const char *error_name; +} mbox_cfgstat_state[] = { + {MBOX_CFGSTAT_STATE_IDLE, "FPGA in idle mode."}, + {MBOX_CFGSTAT_STATE_CONFIG, "FPGA in config mode."}, + {MBOX_CFGSTAT_STATE_FAILACK, "Acknowledgment failed!"}, + {MBOX_CFGSTAT_STATE_ERROR_INVALID, "Invalid bitstream!"}, + {MBOX_CFGSTAT_STATE_ERROR_CORRUPT, "Corrupted bitstream!"}, + {MBOX_CFGSTAT_STATE_ERROR_AUTH, "Authentication failed!"}, + {MBOX_CFGSTAT_STATE_ERROR_CORE_IO, "I/O error!"}, + {MBOX_CFGSTAT_STATE_ERROR_HARDWARE, "Hardware error!"}, + {MBOX_CFGSTAT_STATE_ERROR_FAKE, "Fake error!"}, + {MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO, "Error in boot info!"}, + {MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR, "Error in QSPI!"}, + {MBOX_RESP_ERROR, "Mailbox general error!"}, + {-ETIMEDOUT, "I/O timeout error"}, + {-1, "Unknown error!"} +}; + +#define MBOX_CFGSTAT_MAX ARRAY_SIZE(mbox_cfgstat_state) + +static const char *mbox_cfgstat_to_str(int err) +{ + int i; + + for (i = 0; i < MBOX_CFGSTAT_MAX - 1; i++) { + if (mbox_cfgstat_state[i].err_no == err) + return mbox_cfgstat_state[i].error_name; + } + + return mbox_cfgstat_state[MBOX_CFGSTAT_MAX - 1].error_name; +} + +/* + * Add the ongoing transaction's command ID into pending list and return + * the command ID for next transfer. + */ +static u8 add_transfer(u32 *xfer_pending_list, size_t list_size, u8 id) +{ + int i; + + for (i = 0; i < list_size; i++) { + if (xfer_pending_list[i]) + continue; + xfer_pending_list[i] = id; + debug("ID(%d) added to transaction pending list\n", id); + /* + * Increment command ID for next transaction. + * Valid command ID (4 bits) is from 1 to 15. + */ + id = (id % 15) + 1; + break; + } + + return id; +} + +/* + * Check whether response ID match the command ID in the transfer + * pending list. If a match is found in the transfer pending list, + * it clears the transfer pending list and return the matched + * command ID. + */ +static int get_and_clr_transfer(u32 *xfer_pending_list, size_t list_size, + u8 id) +{ + int i; + + for (i = 0; i < list_size; i++) { + if (id != xfer_pending_list[i]) + continue; + xfer_pending_list[i] = 0; + return id; + } + + return 0; +} + +/* + * Polling the FPGA configuration status. + * Return 0 for success, non-zero for error. + */ +static int reconfig_status_polling_resp(void) +{ + int ret; + unsigned long start = get_timer(0); + + while (1) { + ret = mbox_get_fpga_config_status(MBOX_RECONFIG_STATUS); + if (!ret) + return 0; /* configuration success */ + + if (ret != MBOX_CFGSTAT_STATE_CONFIG) + return ret; + + if (get_timer(start) > RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS) + break; /* time out */ + + puts("."); + udelay(RECONFIG_STATUS_INTERVAL_DELAY_US); + } + + return -ETIMEDOUT; +} + +static u32 get_resp_hdr(u32 *r_index, u32 *w_index, u32 *resp_count, + u32 *resp_buf, u32 buf_size, u32 client_id) +{ + u32 buf[MBOX_RESP_BUFFER_SIZE]; + u32 mbox_hdr; + u32 resp_len; + u32 hdr_len; + u32 i; + + if (*resp_count < buf_size) { + u32 rcv_len_max = buf_size - *resp_count; + + if (rcv_len_max > MBOX_RESP_BUFFER_SIZE) + rcv_len_max = MBOX_RESP_BUFFER_SIZE; + resp_len = mbox_rcv_resp(buf, rcv_len_max); + + for (i = 0; i < resp_len; i++) { + resp_buf[(*w_index)++] = buf[i]; + *w_index %= buf_size; + (*resp_count)++; + } + } + + /* No response in buffer */ + if (*resp_count == 0) + return 0; + + mbox_hdr = resp_buf[*r_index]; + + hdr_len = MBOX_RESP_LEN_GET(mbox_hdr); + + /* Insufficient header length to return a mailbox header */ + if ((*resp_count - 1) < hdr_len) + return 0; + + *r_index += (hdr_len + 1); + *r_index %= buf_size; + *resp_count -= (hdr_len + 1); + + /* Make sure response belongs to us */ + if (MBOX_RESP_CLIENT_GET(mbox_hdr) != client_id) + return 0; + + return mbox_hdr; +} + +/* Send bit stream data to SDM via RECONFIG_DATA mailbox command */ +static int send_reconfig_data(const void *rbf_data, size_t rbf_size, + u32 xfer_max, u32 buf_size_max) +{ + u32 response_buffer[MBOX_RESP_BUFFER_SIZE]; + u32 xfer_pending[MBOX_RESP_BUFFER_SIZE]; + u32 resp_rindex = 0; + u32 resp_windex = 0; + u32 resp_count = 0; + u32 xfer_count = 0; + u8 resp_err = 0; + u8 cmd_id = 1; + u32 args[3]; + int ret; + + debug("SDM xfer_max = %d\n", xfer_max); + debug("SDM buf_size_max = %x\n\n", buf_size_max); + + memset(xfer_pending, 0, sizeof(xfer_pending)); + + while (rbf_size || xfer_count) { + if (!resp_err && rbf_size && xfer_count < xfer_max) { + args[0] = MBOX_ARG_DESC_COUNT(1); + args[1] = (u64)rbf_data; + if (rbf_size >= buf_size_max) { + args[2] = buf_size_max; + rbf_size -= buf_size_max; + rbf_data += buf_size_max; + } else { + args[2] = (u64)rbf_size; + rbf_size = 0; + } + + ret = mbox_send_cmd_only(cmd_id, MBOX_RECONFIG_DATA, + MBOX_CMD_INDIRECT, 3, args); + if (ret) { + resp_err = 1; + } else { + xfer_count++; + cmd_id = add_transfer(xfer_pending, + MBOX_RESP_BUFFER_SIZE, + cmd_id); + } + puts("."); + } else { + u32 resp_hdr = get_resp_hdr(&resp_rindex, &resp_windex, + &resp_count, + response_buffer, + MBOX_RESP_BUFFER_SIZE, + MBOX_CLIENT_ID_UBOOT); + + /* + * If no valid response header found or + * non-zero length from RECONFIG_DATA + */ + if (!resp_hdr || MBOX_RESP_LEN_GET(resp_hdr)) + continue; + + /* Check for response's status */ + if (!resp_err) { + ret = MBOX_RESP_ERR_GET(resp_hdr); + debug("Response error code: %08x\n", ret); + /* Error in response */ + if (ret) + resp_err = 1; + } + + ret = get_and_clr_transfer(xfer_pending, + MBOX_RESP_BUFFER_SIZE, + MBOX_RESP_ID_GET(resp_hdr)); + if (ret) { + /* Claim and reuse the ID */ + cmd_id = (u8)ret; + xfer_count--; + } + + if (resp_err && !xfer_count) + return ret; + } + } + + return 0; +} + +/* + * This is the interface used by FPGA driver. + * Return 0 for success, non-zero for error. + */ +int stratix10_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) +{ + int ret; + u32 resp_len = 2; + u32 resp_buf[2]; + + debug("Sending MBOX_RECONFIG...\n"); + ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_RECONFIG, MBOX_CMD_DIRECT, 0, + NULL, 0, &resp_len, resp_buf); + if (ret) { + puts("Failure in RECONFIG mailbox command!\n"); + return ret; + } + + ret = send_reconfig_data(rbf_data, rbf_size, resp_buf[0], resp_buf[1]); + if (ret) { + printf("RECONFIG_DATA error: %08x, %s\n", ret, + mbox_cfgstat_to_str(ret)); + return ret; + } + + /* Make sure we don't send MBOX_RECONFIG_STATUS too fast */ + udelay(RECONFIG_STATUS_INTERVAL_DELAY_US); + + debug("Polling with MBOX_RECONFIG_STATUS...\n"); + ret = reconfig_status_polling_resp(); + if (ret) { + printf("RECONFIG_STATUS Error: %08x, %s\n", ret, + mbox_cfgstat_to_str(ret)); + return ret; + } + + puts("FPGA reconfiguration OK!\n"); + + return ret; +} diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 35344e57c6c..c8c6c60623e 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -99,6 +99,13 @@ config LPC32XX_GPIO help Support for the LPC32XX GPIO driver. +config MSCC_BITBANG_SPI_GPIO + bool "Microsemi bitbang spi GPIO driver" + depends on DM_GPIO && SOC_VCOREIII + help + Support controlling the GPIO used for SPI bitbang by software. Can + be used by the VCoreIII SoCs, but it was mainly useful for Luton. + config MSM_GPIO bool "Qualcomm GPIO driver" depends on DM_GPIO diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 7ed9a4ec422..61feda15372 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -59,3 +59,4 @@ obj-$(CONFIG_MSM_GPIO) += msm_gpio.o obj-$(CONFIG_$(SPL_)PCF8575_GPIO) += pcf8575_gpio.o obj-$(CONFIG_PM8916_GPIO) += pm8916_gpio.o obj-$(CONFIG_MT7621_GPIO) += mt7621_gpio.o +obj-$(CONFIG_MSCC_BITBANG_SPI_GPIO) += gpio-mscc-bitbang-spi.o diff --git a/drivers/gpio/gpio-mscc-bitbang-spi.c b/drivers/gpio/gpio-mscc-bitbang-spi.c new file mode 100644 index 00000000000..b675f9052c1 --- /dev/null +++ b/drivers/gpio/gpio-mscc-bitbang-spi.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Microsemi SoCs pinctrl driver + * + * Author: <gregory.clement@bootlin.com> + * License: Dual MIT/GPL + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <asm-generic/gpio.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> + +enum { + SDI, + CS0, + CS1, + CS2, + CS3, + SDO, + SCK +}; + +static const int pinmap[] = { 0, 5, 6, 7, 8, 10, 12 }; + +#define SW_SPI_CSn_OE 0x1E /* bits 1 to 4 */ +#define SW_SPI_CS0_OE BIT(1) +#define SW_SPI_SDO_OE BIT(9) +#define SW_SPI_SCK_OE BIT(11) +#define SW_PIN_CTRL_MODE BIT(13) + +struct mscc_bb_spi_gpio { + void __iomem *regs; + u32 cache_val; +}; + +static int mscc_bb_spi_gpio_set(struct udevice *dev, unsigned oft, int val) +{ + struct mscc_bb_spi_gpio *gpio = dev_get_priv(dev); + + if (val) + gpio->cache_val |= BIT(pinmap[oft]); + else + gpio->cache_val &= ~BIT(pinmap[oft]); + + writel(gpio->cache_val, gpio->regs); + + return 0; +} + +static int mscc_bb_spi_gpio_direction_output(struct udevice *dev, unsigned oft, + int val) +{ + if (oft == 0) { + pr_err("SW_SPI_DSI can't be used as output\n"); + return -ENOTSUPP; + } + + mscc_bb_spi_gpio_set(dev, oft, val); + + return 0; +} + +static int mscc_bb_spi_gpio_direction_input(struct udevice *dev, unsigned oft) +{ + return 0; +} + +static int mscc_bb_spi_gpio_get(struct udevice *dev, unsigned int oft) +{ + struct mscc_bb_spi_gpio *gpio = dev_get_priv(dev); + u32 val = readl(gpio->regs); + + return !!(val & BIT(pinmap[oft])); +} + +static const struct dm_gpio_ops mscc_bb_spi_gpio_ops = { + .direction_output = mscc_bb_spi_gpio_direction_output, + .direction_input = mscc_bb_spi_gpio_direction_input, + .set_value = mscc_bb_spi_gpio_set, + .get_value = mscc_bb_spi_gpio_get, +}; + +static int mscc_bb_spi_gpio_probe(struct udevice *dev) +{ + struct mscc_bb_spi_gpio *gpio = dev_get_priv(dev); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + gpio->regs = dev_remap_addr(dev); + if (!gpio->regs) + return -EINVAL; + + uc_priv->bank_name = dev->name; + uc_priv->gpio_count = ARRAY_SIZE(pinmap); + /* + * Enable software mode to control the SPI pin, enables the + * output mode for most of the pin and initialize the cache + * value in the same time + */ + + gpio->cache_val = SW_PIN_CTRL_MODE | SW_SPI_SCK_OE | SW_SPI_SDO_OE | + SW_SPI_CS0_OE; + writel(gpio->cache_val, gpio->regs); + + return 0; +} + +static const struct udevice_id mscc_bb_spi_gpio_ids[] = { + {.compatible = "mscc,spi-bitbang-gpio"}, + {} +}; + +U_BOOT_DRIVER(gpio_mscc_bb_spi) = { + .name = "gpio-mscc-spi-bitbang", + .id = UCLASS_GPIO, + .ops = &mscc_bb_spi_gpio_ops, + .probe = mscc_bb_spi_gpio_probe, + .of_match = of_match_ptr(mscc_bb_spi_gpio_ids), + .priv_auto_alloc_size = sizeof(struct mscc_bb_spi_gpio), +}; diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 48febc47d26..704c8dd1955 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -120,6 +120,12 @@ config FSL_SEC_MON Security Monitor can be transitioned on any security failures, like software violations or hardware security violations. +config JZ4780_EFUSE + bool "Ingenic JZ4780 eFUSE support" + depends on ARCH_JZ47XX + help + This selects support for the eFUSE on Ingenic JZ4780 SoCs. + config MXC_OCOTP bool "Enable MXC OCOTP Driver" help diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 302d4415927..6bdf5054f47 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -62,3 +62,4 @@ obj-$(CONFIG_TEGRA_CAR) += tegra_car.o obj-$(CONFIG_TWL4030_LED) += twl4030_led.o obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress_config.o obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o +obj-$(CONFIG_JZ4780_EFUSE) += jz4780_efuse.o diff --git a/drivers/misc/jz4780_efuse.c b/drivers/misc/jz4780_efuse.c new file mode 100644 index 00000000000..bc3dc93af2d --- /dev/null +++ b/drivers/misc/jz4780_efuse.c @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * JZ4780 EFUSE driver + * + * Copyright (c) 2014 Imagination Technologies + * Author: Alex Smith <alex.smith@imgtec.com> + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/unaligned.h> +#include <errno.h> +#include <mach/jz4780.h> +#include <wait_bit.h> + +#define EFUSE_EFUCTRL 0xd0 +#define EFUSE_EFUCFG 0xd4 +#define EFUSE_EFUSTATE 0xd8 +#define EFUSE_EFUDATA(n) (0xdc + ((n) * 4)) + +#define EFUSE_EFUCTRL_RD_EN BIT(0) +#define EFUSE_EFUCTRL_LEN_BIT 16 +#define EFUSE_EFUCTRL_LEN_MASK 0x1f +#define EFUSE_EFUCTRL_ADDR_BIT 21 +#define EFUSE_EFUCTRL_ADDR_MASK 0x1ff +#define EFUSE_EFUCTRL_CS BIT(30) + +#define EFUSE_EFUCFG_RD_STROBE_BIT 16 +#define EFUSE_EFUCFG_RD_STROBE_MASK 0xf +#define EFUSE_EFUCFG_RD_ADJ_BIT 20 +#define EFUSE_EFUCFG_RD_ADJ_MASK 0xf + +#define EFUSE_EFUSTATE_RD_DONE BIT(0) + +static void jz4780_efuse_read_chunk(size_t addr, size_t count, u8 *buf) +{ + void __iomem *regs = (void __iomem *)NEMC_BASE; + size_t i; + u32 val; + int ret; + + val = EFUSE_EFUCTRL_RD_EN | + ((count - 1) << EFUSE_EFUCTRL_LEN_BIT) | + (addr << EFUSE_EFUCTRL_ADDR_BIT) | + ((addr > 0x200) ? EFUSE_EFUCTRL_CS : 0); + writel(val, regs + EFUSE_EFUCTRL); + + ret = wait_for_bit_le32(regs + EFUSE_EFUSTATE, + EFUSE_EFUSTATE_RD_DONE, true, 10000, false); + if (ret) + return; + + if ((count % 4) == 0) { + for (i = 0; i < count / 4; i++) { + val = readl(regs + EFUSE_EFUDATA(i)); + put_unaligned(val, (u32 *)(buf + (i * 4))); + } + } else { + val = readl(regs + EFUSE_EFUDATA(0)); + if (count > 2) + buf[2] = (val >> 16) & 0xff; + if (count > 1) + buf[1] = (val >> 8) & 0xff; + buf[0] = val & 0xff; + } +} + +static inline int jz4780_efuse_chunk_size(size_t count) +{ + if (count >= 32) + return 32; + else if ((count / 4) > 0) + return (count / 4) * 4; + else + return count % 4; +} + +void jz4780_efuse_read(size_t addr, size_t count, u8 *buf) +{ + size_t chunk; + + while (count > 0) { + chunk = jz4780_efuse_chunk_size(count); + jz4780_efuse_read_chunk(addr, chunk, buf); + addr += chunk; + buf += chunk; + count -= chunk; + } +} + +void jz4780_efuse_init(u32 ahb2_rate) +{ + void __iomem *regs = (void __iomem *)NEMC_BASE; + u32 rd_adj, rd_strobe, tmp; + + rd_adj = (((6500 * (ahb2_rate / 1000000)) / 1000000) + 0xf) / 2; + tmp = (((35000 * (ahb2_rate / 1000000)) / 1000000) - 4) - rd_adj; + rd_strobe = ((tmp + 0xf) / 2 < 7) ? 7 : (tmp + 0xf) / 2; + + tmp = (rd_adj << EFUSE_EFUCFG_RD_ADJ_BIT) | + (rd_strobe << EFUSE_EFUCFG_RD_STROBE_BIT); + writel(tmp, regs + EFUSE_EFUCFG); +} diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index fbd13964a08..496b2cba640 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -332,6 +332,12 @@ config MMC_BCM2835 If unsure, say N. +config JZ47XX_MMC + bool "Ingenic JZ47xx SD/MMC Host Controller support" + depends on ARCH_JZ47XX + help + This selects support for the SD Card Controller on Ingenic JZ47xx SoCs. + config MMC_SANDBOX bool "Sandbox MMC support" depends on SANDBOX diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 801a26d8219..7892c468f05 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_MMC_SANDBOX) += sandbox_mmc.o obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_SH_SDHI) += sh_sdhi.o obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o +obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o # SDHCI obj-$(CONFIG_MMC_SDHCI) += sdhci.o diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c new file mode 100644 index 00000000000..3132c3e191a --- /dev/null +++ b/drivers/mmc/jz_mmc.c @@ -0,0 +1,488 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Ingenic JZ MMC driver + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + */ + +#include <common.h> +#include <malloc.h> +#include <mmc.h> +#include <asm/io.h> +#include <asm/unaligned.h> +#include <errno.h> +#include <mach/jz4780.h> +#include <wait_bit.h> + +/* Registers */ +#define MSC_STRPCL 0x000 +#define MSC_STAT 0x004 +#define MSC_CLKRT 0x008 +#define MSC_CMDAT 0x00c +#define MSC_RESTO 0x010 +#define MSC_RDTO 0x014 +#define MSC_BLKLEN 0x018 +#define MSC_NOB 0x01c +#define MSC_SNOB 0x020 +#define MSC_IMASK 0x024 +#define MSC_IREG 0x028 +#define MSC_CMD 0x02c +#define MSC_ARG 0x030 +#define MSC_RES 0x034 +#define MSC_RXFIFO 0x038 +#define MSC_TXFIFO 0x03c +#define MSC_LPM 0x040 +#define MSC_DMAC 0x044 +#define MSC_DMANDA 0x048 +#define MSC_DMADA 0x04c +#define MSC_DMALEN 0x050 +#define MSC_DMACMD 0x054 +#define MSC_CTRL2 0x058 +#define MSC_RTCNT 0x05c +#define MSC_DBG 0x0fc + +/* MSC Clock and Control Register (MSC_STRPCL) */ +#define MSC_STRPCL_EXIT_MULTIPLE BIT(7) +#define MSC_STRPCL_EXIT_TRANSFER BIT(6) +#define MSC_STRPCL_START_READWAIT BIT(5) +#define MSC_STRPCL_STOP_READWAIT BIT(4) +#define MSC_STRPCL_RESET BIT(3) +#define MSC_STRPCL_START_OP BIT(2) +#define MSC_STRPCL_CLOCK_CONTROL_STOP BIT(0) +#define MSC_STRPCL_CLOCK_CONTROL_START BIT(1) + +/* MSC Status Register (MSC_STAT) */ +#define MSC_STAT_AUTO_CMD_DONE BIT(31) +#define MSC_STAT_IS_RESETTING BIT(15) +#define MSC_STAT_SDIO_INT_ACTIVE BIT(14) +#define MSC_STAT_PRG_DONE BIT(13) +#define MSC_STAT_DATA_TRAN_DONE BIT(12) +#define MSC_STAT_END_CMD_RES BIT(11) +#define MSC_STAT_DATA_FIFO_AFULL BIT(10) +#define MSC_STAT_IS_READWAIT BIT(9) +#define MSC_STAT_CLK_EN BIT(8) +#define MSC_STAT_DATA_FIFO_FULL BIT(7) +#define MSC_STAT_DATA_FIFO_EMPTY BIT(6) +#define MSC_STAT_CRC_RES_ERR BIT(5) +#define MSC_STAT_CRC_READ_ERROR BIT(4) +#define MSC_STAT_CRC_WRITE_ERROR BIT(2) +#define MSC_STAT_CRC_WRITE_ERROR_NOSTS BIT(4) +#define MSC_STAT_TIME_OUT_RES BIT(1) +#define MSC_STAT_TIME_OUT_READ BIT(0) + +/* MSC Bus Clock Control Register (MSC_CLKRT) */ +#define MSC_CLKRT_CLK_RATE_MASK 0x7 + +/* MSC Command Sequence Control Register (MSC_CMDAT) */ +#define MSC_CMDAT_IO_ABORT BIT(11) +#define MSC_CMDAT_BUS_WIDTH_1BIT (0x0 << 9) +#define MSC_CMDAT_BUS_WIDTH_4BIT (0x2 << 9) +#define MSC_CMDAT_DMA_EN BIT(8) +#define MSC_CMDAT_INIT BIT(7) +#define MSC_CMDAT_BUSY BIT(6) +#define MSC_CMDAT_STREAM_BLOCK BIT(5) +#define MSC_CMDAT_WRITE BIT(4) +#define MSC_CMDAT_DATA_EN BIT(3) +#define MSC_CMDAT_RESPONSE_MASK (0x7 << 0) +#define MSC_CMDAT_RESPONSE_NONE (0x0 << 0) /* No response */ +#define MSC_CMDAT_RESPONSE_R1 (0x1 << 0) /* Format R1 and R1b */ +#define MSC_CMDAT_RESPONSE_R2 (0x2 << 0) /* Format R2 */ +#define MSC_CMDAT_RESPONSE_R3 (0x3 << 0) /* Format R3 */ +#define MSC_CMDAT_RESPONSE_R4 (0x4 << 0) /* Format R4 */ +#define MSC_CMDAT_RESPONSE_R5 (0x5 << 0) /* Format R5 */ +#define MSC_CMDAT_RESPONSE_R6 (0x6 << 0) /* Format R6 */ + +/* MSC Interrupts Mask Register (MSC_IMASK) */ +#define MSC_IMASK_TIME_OUT_RES BIT(9) +#define MSC_IMASK_TIME_OUT_READ BIT(8) +#define MSC_IMASK_SDIO BIT(7) +#define MSC_IMASK_TXFIFO_WR_REQ BIT(6) +#define MSC_IMASK_RXFIFO_RD_REQ BIT(5) +#define MSC_IMASK_END_CMD_RES BIT(2) +#define MSC_IMASK_PRG_DONE BIT(1) +#define MSC_IMASK_DATA_TRAN_DONE BIT(0) + +/* MSC Interrupts Status Register (MSC_IREG) */ +#define MSC_IREG_TIME_OUT_RES BIT(9) +#define MSC_IREG_TIME_OUT_READ BIT(8) +#define MSC_IREG_SDIO BIT(7) +#define MSC_IREG_TXFIFO_WR_REQ BIT(6) +#define MSC_IREG_RXFIFO_RD_REQ BIT(5) +#define MSC_IREG_END_CMD_RES BIT(2) +#define MSC_IREG_PRG_DONE BIT(1) +#define MSC_IREG_DATA_TRAN_DONE BIT(0) + +struct jz_mmc_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + +struct jz_mmc_priv { + void __iomem *regs; + u32 flags; +/* priv flags */ +#define JZ_MMC_BUS_WIDTH_MASK 0x3 +#define JZ_MMC_BUS_WIDTH_1 0x0 +#define JZ_MMC_BUS_WIDTH_4 0x2 +#define JZ_MMC_BUS_WIDTH_8 0x3 +#define JZ_MMC_SENT_INIT BIT(2) +}; + +static int jz_mmc_clock_rate(void) +{ + return 24000000; +} + +static int jz_mmc_send_cmd(struct mmc *mmc, struct jz_mmc_priv *priv, + struct mmc_cmd *cmd, struct mmc_data *data) +{ + u32 stat, mask, cmdat = 0; + int i, ret; + + /* stop the clock */ + writel(MSC_STRPCL_CLOCK_CONTROL_STOP, priv->regs + MSC_STRPCL); + ret = wait_for_bit_le32(priv->regs + MSC_STAT, + MSC_STAT_CLK_EN, false, 10000, false); + if (ret) + return ret; + + writel(0, priv->regs + MSC_DMAC); + + /* setup command */ + writel(cmd->cmdidx, priv->regs + MSC_CMD); + writel(cmd->cmdarg, priv->regs + MSC_ARG); + + if (data) { + /* setup data */ + cmdat |= MSC_CMDAT_DATA_EN; + if (data->flags & MMC_DATA_WRITE) + cmdat |= MSC_CMDAT_WRITE; + + writel(data->blocks, priv->regs + MSC_NOB); + writel(data->blocksize, priv->regs + MSC_BLKLEN); + } else { + writel(0, priv->regs + MSC_NOB); + writel(0, priv->regs + MSC_BLKLEN); + } + + /* setup response */ + switch (cmd->resp_type) { + case MMC_RSP_NONE: + break; + case MMC_RSP_R1: + case MMC_RSP_R1b: + cmdat |= MSC_CMDAT_RESPONSE_R1; + break; + case MMC_RSP_R2: + cmdat |= MSC_CMDAT_RESPONSE_R2; + break; + case MMC_RSP_R3: + cmdat |= MSC_CMDAT_RESPONSE_R3; + break; + default: + break; + } + + if (cmd->resp_type & MMC_RSP_BUSY) + cmdat |= MSC_CMDAT_BUSY; + + /* set init for the first command only */ + if (!(priv->flags & JZ_MMC_SENT_INIT)) { + cmdat |= MSC_CMDAT_INIT; + priv->flags |= JZ_MMC_SENT_INIT; + } + + cmdat |= (priv->flags & JZ_MMC_BUS_WIDTH_MASK) << 9; + + /* write the data setup */ + writel(cmdat, priv->regs + MSC_CMDAT); + + /* unmask interrupts */ + mask = 0xffffffff & ~(MSC_IMASK_END_CMD_RES | MSC_IMASK_TIME_OUT_RES); + if (data) { + mask &= ~MSC_IMASK_DATA_TRAN_DONE; + if (data->flags & MMC_DATA_WRITE) { + mask &= ~MSC_IMASK_TXFIFO_WR_REQ; + } else { + mask &= ~(MSC_IMASK_RXFIFO_RD_REQ | + MSC_IMASK_TIME_OUT_READ); + } + } + writel(mask, priv->regs + MSC_IMASK); + + /* clear interrupts */ + writel(0xffffffff, priv->regs + MSC_IREG); + + /* start the command (& the clock) */ + writel(MSC_STRPCL_START_OP | MSC_STRPCL_CLOCK_CONTROL_START, + priv->regs + MSC_STRPCL); + + /* wait for completion */ + for (i = 0; i < 100; i++) { + stat = readl(priv->regs + MSC_IREG); + stat &= MSC_IREG_END_CMD_RES | MSC_IREG_TIME_OUT_RES; + if (stat) + break; + mdelay(1); + } + writel(stat, priv->regs + MSC_IREG); + if (stat & MSC_IREG_TIME_OUT_RES) + return -ETIMEDOUT; + + if (cmd->resp_type & MMC_RSP_PRESENT) { + /* read the response */ + if (cmd->resp_type & MMC_RSP_136) { + u16 a, b, c, i; + + a = readw(priv->regs + MSC_RES); + for (i = 0; i < 4; i++) { + b = readw(priv->regs + MSC_RES); + c = readw(priv->regs + MSC_RES); + cmd->response[i] = + (a << 24) | (b << 8) | (c >> 8); + a = c; + } + } else { + cmd->response[0] = readw(priv->regs + MSC_RES) << 24; + cmd->response[0] |= readw(priv->regs + MSC_RES) << 8; + cmd->response[0] |= readw(priv->regs + MSC_RES) & 0xff; + } + } + + if (data && (data->flags & MMC_DATA_WRITE)) { + /* write the data */ + int sz = DIV_ROUND_UP(data->blocks * data->blocksize, 4); + const void *buf = data->src; + + while (sz--) { + u32 val = get_unaligned_le32(buf); + + wait_for_bit_le32(priv->regs + MSC_IREG, + MSC_IREG_TXFIFO_WR_REQ, + true, 10000, false); + writel(val, priv->regs + MSC_TXFIFO); + buf += 4; + } + } else if (data && (data->flags & MMC_DATA_READ)) { + /* read the data */ + int sz = data->blocks * data->blocksize; + void *buf = data->dest; + + do { + stat = readl(priv->regs + MSC_STAT); + + if (stat & MSC_STAT_TIME_OUT_READ) + return -ETIMEDOUT; + if (stat & MSC_STAT_CRC_READ_ERROR) + return -EINVAL; + if (stat & MSC_STAT_DATA_FIFO_EMPTY) { + udelay(10); + continue; + } + do { + u32 val = readl(priv->regs + MSC_RXFIFO); + + if (sz == 1) + *(u8 *)buf = (u8)val; + else if (sz == 2) + put_unaligned_le16(val, buf); + else if (sz >= 4) + put_unaligned_le32(val, buf); + buf += 4; + sz -= 4; + stat = readl(priv->regs + MSC_STAT); + } while (!(stat & MSC_STAT_DATA_FIFO_EMPTY)); + } while (!(stat & MSC_STAT_DATA_TRAN_DONE)); + } + + return 0; +} + +static int jz_mmc_set_ios(struct mmc *mmc, struct jz_mmc_priv *priv) +{ + u32 real_rate = jz_mmc_clock_rate(); + u8 clk_div = 0; + + /* calculate clock divide */ + while ((real_rate > mmc->clock) && (clk_div < 7)) { + real_rate >>= 1; + clk_div++; + } + writel(clk_div & MSC_CLKRT_CLK_RATE_MASK, priv->regs + MSC_CLKRT); + + /* set the bus width for the next command */ + priv->flags &= ~JZ_MMC_BUS_WIDTH_MASK; + if (mmc->bus_width == 8) + priv->flags |= JZ_MMC_BUS_WIDTH_8; + else if (mmc->bus_width == 4) + priv->flags |= JZ_MMC_BUS_WIDTH_4; + else + priv->flags |= JZ_MMC_BUS_WIDTH_1; + + return 0; +} + +static int jz_mmc_core_init(struct mmc *mmc) +{ + struct jz_mmc_priv *priv = mmc->priv; + int ret; + + /* Reset */ + writel(MSC_STRPCL_RESET, priv->regs + MSC_STRPCL); + ret = wait_for_bit_le32(priv->regs + MSC_STAT, + MSC_STAT_IS_RESETTING, false, 10000, false); + if (ret) + return ret; + + /* Maximum timeouts */ + writel(0xffff, priv->regs + MSC_RESTO); + writel(0xffffffff, priv->regs + MSC_RDTO); + + /* Enable low power mode */ + writel(0x1, priv->regs + MSC_LPM); + + return 0; +} + +#if !CONFIG_IS_ENABLED(DM_MMC) + +static int jz_mmc_legacy_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct jz_mmc_priv *priv = mmc->priv; + + return jz_mmc_send_cmd(mmc, priv, cmd, data); +} + +static int jz_mmc_legacy_set_ios(struct mmc *mmc) +{ + struct jz_mmc_priv *priv = mmc->priv; + + return jz_mmc_set_ios(mmc, priv); +}; + +static const struct mmc_ops jz_msc_ops = { + .send_cmd = jz_mmc_legacy_send_cmd, + .set_ios = jz_mmc_legacy_set_ios, + .init = jz_mmc_core_init, +}; + +static struct jz_mmc_priv jz_mmc_priv_static; +static struct jz_mmc_plat jz_mmc_plat_static = { + .cfg = { + .name = "MSC", + .ops = &jz_msc_ops, + + .voltages = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | + MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | + MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36, + .host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS, + + .f_min = 375000, + .f_max = 48000000, + .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, + }, +}; + +int jz_mmc_init(void __iomem *base) +{ + struct mmc *mmc; + + jz_mmc_priv_static.regs = base; + + mmc = mmc_create(&jz_mmc_plat_static.cfg, &jz_mmc_priv_static); + + return mmc ? 0 : -ENODEV; +} + +#else /* CONFIG_DM_MMC */ + +#include <dm.h> +DECLARE_GLOBAL_DATA_PTR; + +static int jz_mmc_dm_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct jz_mmc_priv *priv = dev_get_priv(dev); + struct mmc *mmc = mmc_get_mmc_dev(dev); + + return jz_mmc_send_cmd(mmc, priv, cmd, data); +} + +static int jz_mmc_dm_set_ios(struct udevice *dev) +{ + struct jz_mmc_priv *priv = dev_get_priv(dev); + struct mmc *mmc = mmc_get_mmc_dev(dev); + + return jz_mmc_set_ios(mmc, priv); +}; + +static const struct dm_mmc_ops jz_msc_ops = { + .send_cmd = jz_mmc_dm_send_cmd, + .set_ios = jz_mmc_dm_set_ios, +}; + +static int jz_mmc_ofdata_to_platdata(struct udevice *dev) +{ + struct jz_mmc_priv *priv = dev_get_priv(dev); + struct jz_mmc_plat *plat = dev_get_platdata(dev); + struct mmc_config *cfg; + int ret; + + priv->regs = map_physmem(devfdt_get_addr(dev), 0x100, MAP_NOCACHE); + cfg = &plat->cfg; + + cfg->name = "MSC"; + cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS; + + ret = mmc_of_parse(dev, cfg); + if (ret < 0) { + dev_err(dev, "failed to parse host caps\n"); + return ret; + } + + cfg->f_min = 400000; + cfg->f_max = 52000000; + + cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + + return 0; +} + +static int jz_mmc_bind(struct udevice *dev) +{ + struct jz_mmc_plat *plat = dev_get_platdata(dev); + + return mmc_bind(dev, &plat->mmc, &plat->cfg); +} + +static int jz_mmc_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct jz_mmc_priv *priv = dev_get_priv(dev); + struct jz_mmc_plat *plat = dev_get_platdata(dev); + + plat->mmc.priv = priv; + upriv->mmc = &plat->mmc; + return jz_mmc_core_init(&plat->mmc); +} + +static const struct udevice_id jz_mmc_ids[] = { + { .compatible = "ingenic,jz4780-mmc" }, + { } +}; + +U_BOOT_DRIVER(jz_mmc_drv) = { + .name = "jz_mmc", + .id = UCLASS_MMC, + .of_match = jz_mmc_ids, + .ofdata_to_platdata = jz_mmc_ofdata_to_platdata, + .bind = jz_mmc_bind, + .probe = jz_mmc_probe, + .priv_auto_alloc_size = sizeof(struct jz_mmc_priv), + .platdata_auto_alloc_size = sizeof(struct jz_mmc_plat), + .ops = &jz_msc_ops, +}; +#endif /* CONFIG_DM_MMC */ diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c index d1cac063f46..e0eb1339ecd 100644 --- a/drivers/mtd/nand/raw/denali.c +++ b/drivers/mtd/nand/raw/denali.c @@ -69,14 +69,6 @@ static int dma_mapping_error(void *dev, dma_addr_t addr) #define DENALI_INVALID_BANK -1 #define DENALI_NR_BANKS 4 -/* - * The bus interface clock, clk_x, is phase aligned with the core clock. The - * clk_x is an integral multiple N of the core clk. The value N is configured - * at IP delivery time, and its available value is 4, 5, or 6. We need to align - * to the largest value to make it work with any possible configuration. - */ -#define DENALI_CLK_X_MULT 6 - static inline struct denali_nand_info *mtd_to_denali(struct mtd_info *mtd) { return container_of(mtd_to_nand(mtd), struct denali_nand_info, nand); @@ -595,6 +587,12 @@ static int denali_dma_xfer(struct denali_nand_info *denali, void *buf, } iowrite32(DMA_ENABLE__FLAG, denali->reg + DMA_ENABLE); + /* + * The ->setup_dma() hook kicks DMA by using the data/command + * interface, which belongs to a different AXI port from the + * register interface. Read back the register to avoid a race. + */ + ioread32(denali->reg + DMA_ENABLE); denali_reset_irq(denali); denali->setup_dma(denali, dma_addr, page, write); @@ -946,7 +944,7 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, { struct denali_nand_info *denali = mtd_to_denali(mtd); const struct nand_sdr_timings *timings; - unsigned long t_clk; + unsigned long t_x, mult_x; int acc_clks, re_2_we, re_2_re, we_2_re, addr_2_data; int rdwr_en_lo, rdwr_en_hi, rdwr_en_lo_hi, cs_setup; int addr_2_data_mask; @@ -957,15 +955,24 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, return PTR_ERR(timings); /* clk_x period in picoseconds */ - t_clk = DIV_ROUND_DOWN_ULL(1000000000000ULL, denali->clk_x_rate); - if (!t_clk) + t_x = DIV_ROUND_DOWN_ULL(1000000000000ULL, denali->clk_x_rate); + if (!t_x) + return -EINVAL; + + /* + * The bus interface clock, clk_x, is phase aligned with the core clock. + * The clk_x is an integral multiple N of the core clk. The value N is + * configured at IP delivery time, and its available value is 4, 5, 6. + */ + mult_x = DIV_ROUND_CLOSEST_ULL(denali->clk_x_rate, denali->clk_rate); + if (mult_x < 4 || mult_x > 6) return -EINVAL; if (chipnr == NAND_DATA_IFACE_CHECK_ONLY) return 0; /* tREA -> ACC_CLKS */ - acc_clks = DIV_ROUND_UP(timings->tREA_max, t_clk); + acc_clks = DIV_ROUND_UP(timings->tREA_max, t_x); acc_clks = min_t(int, acc_clks, ACC_CLKS__VALUE); tmp = ioread32(denali->reg + ACC_CLKS); @@ -974,7 +981,7 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, iowrite32(tmp, denali->reg + ACC_CLKS); /* tRWH -> RE_2_WE */ - re_2_we = DIV_ROUND_UP(timings->tRHW_min, t_clk); + re_2_we = DIV_ROUND_UP(timings->tRHW_min, t_x); re_2_we = min_t(int, re_2_we, RE_2_WE__VALUE); tmp = ioread32(denali->reg + RE_2_WE); @@ -983,7 +990,7 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, iowrite32(tmp, denali->reg + RE_2_WE); /* tRHZ -> RE_2_RE */ - re_2_re = DIV_ROUND_UP(timings->tRHZ_max, t_clk); + re_2_re = DIV_ROUND_UP(timings->tRHZ_max, t_x); re_2_re = min_t(int, re_2_re, RE_2_RE__VALUE); tmp = ioread32(denali->reg + RE_2_RE); @@ -997,8 +1004,7 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, * With WE_2_RE properly set, the Denali controller automatically takes * care of the delay; the driver need not set NAND_WAIT_TCCS. */ - we_2_re = DIV_ROUND_UP(max(timings->tCCS_min, timings->tWHR_min), - t_clk); + we_2_re = DIV_ROUND_UP(max(timings->tCCS_min, timings->tWHR_min), t_x); we_2_re = min_t(int, we_2_re, TWHR2_AND_WE_2_RE__WE_2_RE); tmp = ioread32(denali->reg + TWHR2_AND_WE_2_RE); @@ -1013,7 +1019,7 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, if (denali->revision < 0x0501) addr_2_data_mask >>= 1; - addr_2_data = DIV_ROUND_UP(timings->tADL_min, t_clk); + addr_2_data = DIV_ROUND_UP(timings->tADL_min, t_x); addr_2_data = min_t(int, addr_2_data, addr_2_data_mask); tmp = ioread32(denali->reg + TCWAW_AND_ADDR_2_DATA); @@ -1023,7 +1029,7 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, /* tREH, tWH -> RDWR_EN_HI_CNT */ rdwr_en_hi = DIV_ROUND_UP(max(timings->tREH_min, timings->tWH_min), - t_clk); + t_x); rdwr_en_hi = min_t(int, rdwr_en_hi, RDWR_EN_HI_CNT__VALUE); tmp = ioread32(denali->reg + RDWR_EN_HI_CNT); @@ -1032,11 +1038,10 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, iowrite32(tmp, denali->reg + RDWR_EN_HI_CNT); /* tRP, tWP -> RDWR_EN_LO_CNT */ - rdwr_en_lo = DIV_ROUND_UP(max(timings->tRP_min, timings->tWP_min), - t_clk); + rdwr_en_lo = DIV_ROUND_UP(max(timings->tRP_min, timings->tWP_min), t_x); rdwr_en_lo_hi = DIV_ROUND_UP(max(timings->tRC_min, timings->tWC_min), - t_clk); - rdwr_en_lo_hi = max(rdwr_en_lo_hi, DENALI_CLK_X_MULT); + t_x); + rdwr_en_lo_hi = max_t(int, rdwr_en_lo_hi, mult_x); rdwr_en_lo = max(rdwr_en_lo, rdwr_en_lo_hi - rdwr_en_hi); rdwr_en_lo = min_t(int, rdwr_en_lo, RDWR_EN_LO_CNT__VALUE); @@ -1046,8 +1051,8 @@ static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr, iowrite32(tmp, denali->reg + RDWR_EN_LO_CNT); /* tCS, tCEA -> CS_SETUP_CNT */ - cs_setup = max3((int)DIV_ROUND_UP(timings->tCS_min, t_clk) - rdwr_en_lo, - (int)DIV_ROUND_UP(timings->tCEA_max, t_clk) - acc_clks, + cs_setup = max3((int)DIV_ROUND_UP(timings->tCS_min, t_x) - rdwr_en_lo, + (int)DIV_ROUND_UP(timings->tCEA_max, t_x) - acc_clks, 0); cs_setup = min_t(int, cs_setup, CS_SETUP_CNT__VALUE); diff --git a/drivers/mtd/nand/raw/denali.h b/drivers/mtd/nand/raw/denali.h index 9b797beffa7..019deda094e 100644 --- a/drivers/mtd/nand/raw/denali.h +++ b/drivers/mtd/nand/raw/denali.h @@ -292,6 +292,7 @@ struct udevice; struct denali_nand_info { struct nand_chip nand; + unsigned long clk_rate; /* core clock rate */ unsigned long clk_x_rate; /* bus interface clock rate */ int active_bank; /* currently selected bank */ struct udevice *dev; diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c index 65a7797f0f3..d384b974df1 100644 --- a/drivers/mtd/nand/raw/denali_dt.c +++ b/drivers/mtd/nand/raw/denali_dt.c @@ -62,7 +62,7 @@ static int denali_dt_probe(struct udevice *dev) { struct denali_nand_info *denali = dev_get_priv(dev); const struct denali_dt_data *data; - struct clk clk; + struct clk clk, clk_x, clk_ecc; struct resource res; int ret; @@ -87,15 +87,49 @@ static int denali_dt_probe(struct udevice *dev) denali->host = devm_ioremap(dev, res.start, resource_size(&res)); - ret = clk_get_by_index(dev, 0, &clk); + ret = clk_get_by_name(dev, "nand", &clk); + if (ret) + ret = clk_get_by_index(dev, 0, &clk); if (ret) return ret; + ret = clk_get_by_name(dev, "nand_x", &clk_x); + if (ret) + clk_x.dev = NULL; + + ret = clk_get_by_name(dev, "ecc", &clk_ecc); + if (ret) + clk_ecc.dev = NULL; + ret = clk_enable(&clk); if (ret) return ret; - denali->clk_x_rate = clk_get_rate(&clk); + if (clk_x.dev) { + ret = clk_enable(&clk_x); + if (ret) + return ret; + } + + if (clk_ecc.dev) { + ret = clk_enable(&clk_ecc); + if (ret) + return ret; + } + + if (clk_x.dev) { + denali->clk_rate = clk_get_rate(&clk); + denali->clk_x_rate = clk_get_rate(&clk_x); + } else { + /* + * Hardcode the clock rates for the backward compatibility. + * This works for both SOCFPGA and UniPhier. + */ + dev_notice(dev, + "necessary clock is missing. default clock rates are used.\n"); + denali->clk_rate = 50000000; + denali->clk_x_rate = 200000000; + } return denali_init(denali); } diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 8fb365fc5d2..7044c6adf32 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -72,6 +72,24 @@ config BCM_SF2_ETH_GMAC by the BCM_SF2_ETH driver. Say Y to any bcmcygnus based platforms. +config BCM6348_ETH + bool "BCM6348 EMAC support" + depends on DM_ETH && ARCH_BMIPS + select DMA + select DMA_CHANNELS + select MII + select PHYLIB + help + This driver supports the BCM6348 Ethernet MAC. + +config BCM6368_ETH + bool "BCM6368 EMAC support" + depends on DM_ETH && ARCH_BMIPS + select DMA + select MII + help + This driver supports the BCM6368 Ethernet MAC. + config DWC_ETH_QOS bool "Synopsys DWC Ethernet QOS device support" depends on DM_ETH diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 99056aa041d..0dbfa033068 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -6,6 +6,8 @@ obj-$(CONFIG_ALTERA_TSE) += altera_tse.o obj-$(CONFIG_AG7XXX) += ag7xxx.o obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o +obj-$(CONFIG_BCM6348_ETH) += bcm6348-eth.o +obj-$(CONFIG_BCM6368_ETH) += bcm6368-eth.o obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o obj-$(CONFIG_DRIVER_AX88180) += ax88180.o obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o diff --git a/drivers/net/bcm6348-eth.c b/drivers/net/bcm6348-eth.c new file mode 100644 index 00000000000..7100e68bd20 --- /dev/null +++ b/drivers/net/bcm6348-eth.c @@ -0,0 +1,537 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> + * + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c: + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <dma.h> +#include <miiphy.h> +#include <net.h> +#include <phy.h> +#include <reset.h> +#include <wait_bit.h> +#include <asm/io.h> + +#define ETH_RX_DESC PKTBUFSRX +#define ETH_MAX_MTU_SIZE 1518 +#define ETH_TIMEOUT 100 +#define ETH_TX_WATERMARK 32 + +/* ETH Receiver Configuration register */ +#define ETH_RXCFG_REG 0x00 +#define ETH_RXCFG_ENFLOW_SHIFT 5 +#define ETH_RXCFG_ENFLOW_MASK (1 << ETH_RXCFG_ENFLOW_SHIFT) + +/* ETH Receive Maximum Length register */ +#define ETH_RXMAXLEN_REG 0x04 +#define ETH_RXMAXLEN_SHIFT 0 +#define ETH_RXMAXLEN_MASK (0x7ff << ETH_RXMAXLEN_SHIFT) + +/* ETH Transmit Maximum Length register */ +#define ETH_TXMAXLEN_REG 0x08 +#define ETH_TXMAXLEN_SHIFT 0 +#define ETH_TXMAXLEN_MASK (0x7ff << ETH_TXMAXLEN_SHIFT) + +/* MII Status/Control register */ +#define MII_SC_REG 0x10 +#define MII_SC_MDCFREQDIV_SHIFT 0 +#define MII_SC_MDCFREQDIV_MASK (0x7f << MII_SC_MDCFREQDIV_SHIFT) +#define MII_SC_PREAMBLE_EN_SHIFT 7 +#define MII_SC_PREAMBLE_EN_MASK (1 << MII_SC_PREAMBLE_EN_SHIFT) + +/* MII Data register */ +#define MII_DAT_REG 0x14 +#define MII_DAT_DATA_SHIFT 0 +#define MII_DAT_DATA_MASK (0xffff << MII_DAT_DATA_SHIFT) +#define MII_DAT_TA_SHIFT 16 +#define MII_DAT_TA_MASK (0x3 << MII_DAT_TA_SHIFT) +#define MII_DAT_REG_SHIFT 18 +#define MII_DAT_REG_MASK (0x1f << MII_DAT_REG_SHIFT) +#define MII_DAT_PHY_SHIFT 23 +#define MII_DAT_PHY_MASK (0x1f << MII_DAT_PHY_SHIFT) +#define MII_DAT_OP_SHIFT 28 +#define MII_DAT_OP_WRITE (0x5 << MII_DAT_OP_SHIFT) +#define MII_DAT_OP_READ (0x6 << MII_DAT_OP_SHIFT) + +/* ETH Interrupts Mask register */ +#define ETH_IRMASK_REG 0x18 + +/* ETH Interrupts register */ +#define ETH_IR_REG 0x1c +#define ETH_IR_MII_SHIFT 0 +#define ETH_IR_MII_MASK (1 << ETH_IR_MII_SHIFT) + +/* ETH Control register */ +#define ETH_CTL_REG 0x2c +#define ETH_CTL_ENABLE_SHIFT 0 +#define ETH_CTL_ENABLE_MASK (1 << ETH_CTL_ENABLE_SHIFT) +#define ETH_CTL_DISABLE_SHIFT 1 +#define ETH_CTL_DISABLE_MASK (1 << ETH_CTL_DISABLE_SHIFT) +#define ETH_CTL_RESET_SHIFT 2 +#define ETH_CTL_RESET_MASK (1 << ETH_CTL_RESET_SHIFT) +#define ETH_CTL_EPHY_SHIFT 3 +#define ETH_CTL_EPHY_MASK (1 << ETH_CTL_EPHY_SHIFT) + +/* ETH Transmit Control register */ +#define ETH_TXCTL_REG 0x30 +#define ETH_TXCTL_FD_SHIFT 0 +#define ETH_TXCTL_FD_MASK (1 << ETH_TXCTL_FD_SHIFT) + +/* ETH Transmit Watermask register */ +#define ETH_TXWMARK_REG 0x34 +#define ETH_TXWMARK_WM_SHIFT 0 +#define ETH_TXWMARK_WM_MASK (0x3f << ETH_TXWMARK_WM_SHIFT) + +/* MIB Control register */ +#define MIB_CTL_REG 0x38 +#define MIB_CTL_RDCLEAR_SHIFT 0 +#define MIB_CTL_RDCLEAR_MASK (1 << MIB_CTL_RDCLEAR_SHIFT) + +/* ETH Perfect Match registers */ +#define ETH_PM_CNT 4 +#define ETH_PML_REG(x) (0x58 + (x) * 0x8) +#define ETH_PMH_REG(x) (0x5c + (x) * 0x8) +#define ETH_PMH_VALID_SHIFT 16 +#define ETH_PMH_VALID_MASK (1 << ETH_PMH_VALID_SHIFT) + +/* MIB Counters registers */ +#define MIB_REG_CNT 55 +#define MIB_REG(x) (0x200 + (x) * 4) + +/* ETH data */ +struct bcm6348_eth_priv { + void __iomem *base; + /* DMA */ + struct dma rx_dma; + struct dma tx_dma; + /* PHY */ + int phy_id; + struct phy_device *phy_dev; +}; + +static void bcm6348_eth_mac_disable(struct bcm6348_eth_priv *priv) +{ + /* disable emac */ + clrsetbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_ENABLE_MASK, + ETH_CTL_DISABLE_MASK); + + /* wait until emac is disabled */ + if (wait_for_bit_be32(priv->base + ETH_CTL_REG, + ETH_CTL_DISABLE_MASK, false, + ETH_TIMEOUT, false)) + pr_err("%s: error disabling emac\n", __func__); +} + +static void bcm6348_eth_mac_enable(struct bcm6348_eth_priv *priv) +{ + setbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_ENABLE_MASK); +} + +static void bcm6348_eth_mac_reset(struct bcm6348_eth_priv *priv) +{ + /* reset emac */ + writel_be(ETH_CTL_RESET_MASK, priv->base + ETH_CTL_REG); + wmb(); + + /* wait until emac is reset */ + if (wait_for_bit_be32(priv->base + ETH_CTL_REG, + ETH_CTL_RESET_MASK, false, + ETH_TIMEOUT, false)) + pr_err("%s: error resetting emac\n", __func__); +} + +static int bcm6348_eth_free_pkt(struct udevice *dev, uchar *packet, int len) +{ + struct bcm6348_eth_priv *priv = dev_get_priv(dev); + + return dma_prepare_rcv_buf(&priv->rx_dma, packet, len); +} + +static int bcm6348_eth_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct bcm6348_eth_priv *priv = dev_get_priv(dev); + + return dma_receive(&priv->rx_dma, (void**)packetp, NULL); +} + +static int bcm6348_eth_send(struct udevice *dev, void *packet, int length) +{ + struct bcm6348_eth_priv *priv = dev_get_priv(dev); + + return dma_send(&priv->tx_dma, packet, length, NULL); +} + +static int bcm6348_eth_adjust_link(struct udevice *dev, + struct phy_device *phydev) +{ + struct bcm6348_eth_priv *priv = dev_get_priv(dev); + + /* mac duplex parameters */ + if (phydev->duplex) + setbits_be32(priv->base + ETH_TXCTL_REG, ETH_TXCTL_FD_MASK); + else + clrbits_be32(priv->base + ETH_TXCTL_REG, ETH_TXCTL_FD_MASK); + + /* rx flow control (pause frame handling) */ + if (phydev->pause) + setbits_be32(priv->base + ETH_RXCFG_REG, + ETH_RXCFG_ENFLOW_MASK); + else + clrbits_be32(priv->base + ETH_RXCFG_REG, + ETH_RXCFG_ENFLOW_MASK); + + return 0; +} + +static int bcm6348_eth_start(struct udevice *dev) +{ + struct bcm6348_eth_priv *priv = dev_get_priv(dev); + int ret, i; + + /* prepare rx dma buffers */ + for (i = 0; i < ETH_RX_DESC; i++) { + ret = dma_prepare_rcv_buf(&priv->rx_dma, net_rx_packets[i], + PKTSIZE_ALIGN); + if (ret < 0) + break; + } + + /* enable dma rx channel */ + dma_enable(&priv->rx_dma); + + /* enable dma tx channel */ + dma_enable(&priv->tx_dma); + + ret = phy_startup(priv->phy_dev); + if (ret) { + pr_err("%s: could not initialize phy\n", __func__); + return ret; + } + + if (!priv->phy_dev->link) { + pr_err("%s: no phy link\n", __func__); + return -EIO; + } + + bcm6348_eth_adjust_link(dev, priv->phy_dev); + + /* zero mib counters */ + for (i = 0; i < MIB_REG_CNT; i++) + writel_be(0, MIB_REG(i)); + + /* enable rx flow control */ + setbits_be32(priv->base + ETH_RXCFG_REG, ETH_RXCFG_ENFLOW_MASK); + + /* set max rx/tx length */ + writel_be((ETH_MAX_MTU_SIZE << ETH_RXMAXLEN_SHIFT) & + ETH_RXMAXLEN_MASK, priv->base + ETH_RXMAXLEN_REG); + writel_be((ETH_MAX_MTU_SIZE << ETH_TXMAXLEN_SHIFT) & + ETH_TXMAXLEN_MASK, priv->base + ETH_TXMAXLEN_REG); + + /* set correct transmit fifo watermark */ + writel_be((ETH_TX_WATERMARK << ETH_TXWMARK_WM_SHIFT) & + ETH_TXWMARK_WM_MASK, priv->base + ETH_TXWMARK_REG); + + /* enable emac */ + bcm6348_eth_mac_enable(priv); + + /* clear interrupts */ + writel_be(0, priv->base + ETH_IRMASK_REG); + + return 0; +} + +static void bcm6348_eth_stop(struct udevice *dev) +{ + struct bcm6348_eth_priv *priv = dev_get_priv(dev); + + /* disable dma rx channel */ + dma_disable(&priv->rx_dma); + + /* disable dma tx channel */ + dma_disable(&priv->tx_dma); + + /* disable emac */ + bcm6348_eth_mac_disable(priv); +} + +static int bcm6348_eth_write_hwaddr(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct bcm6348_eth_priv *priv = dev_get_priv(dev); + bool running = false; + + /* check if emac is running */ + if (readl_be(priv->base + ETH_CTL_REG) & ETH_CTL_ENABLE_MASK) + running = true; + + /* disable emac */ + if (running) + bcm6348_eth_mac_disable(priv); + + /* set mac address */ + writel_be((pdata->enetaddr[2] << 24) | (pdata->enetaddr[3]) << 16 | + (pdata->enetaddr[4]) << 8 | (pdata->enetaddr[5]), + priv->base + ETH_PML_REG(0)); + writel_be((pdata->enetaddr[1]) | (pdata->enetaddr[0] << 8) | + ETH_PMH_VALID_MASK, priv->base + ETH_PMH_REG(0)); + + /* enable emac */ + if (running) + bcm6348_eth_mac_enable(priv); + + return 0; +} + +static const struct eth_ops bcm6348_eth_ops = { + .free_pkt = bcm6348_eth_free_pkt, + .recv = bcm6348_eth_recv, + .send = bcm6348_eth_send, + .start = bcm6348_eth_start, + .stop = bcm6348_eth_stop, + .write_hwaddr = bcm6348_eth_write_hwaddr, +}; + +static const struct udevice_id bcm6348_eth_ids[] = { + { .compatible = "brcm,bcm6348-enet", }, + { /* sentinel */ } +}; + +static int bcm6348_mdio_op(void __iomem *base, uint32_t data) +{ + /* make sure mii interrupt status is cleared */ + writel_be(ETH_IR_MII_MASK, base + ETH_IR_REG); + + /* issue mii op */ + writel_be(data, base + MII_DAT_REG); + + /* wait until emac is disabled */ + return wait_for_bit_be32(base + ETH_IR_REG, + ETH_IR_MII_MASK, true, + ETH_TIMEOUT, false); +} + +static int bcm6348_mdio_read(struct mii_dev *bus, int addr, int devaddr, + int reg) +{ + void __iomem *base = bus->priv; + uint32_t val; + + val = MII_DAT_OP_READ; + val |= (reg << MII_DAT_REG_SHIFT) & MII_DAT_REG_MASK; + val |= (0x2 << MII_DAT_TA_SHIFT) & MII_DAT_TA_MASK; + val |= (addr << MII_DAT_PHY_SHIFT) & MII_DAT_PHY_MASK; + + if (bcm6348_mdio_op(base, val)) { + pr_err("%s: timeout\n", __func__); + return -EINVAL; + } + + val = readl_be(base + MII_DAT_REG) & MII_DAT_DATA_MASK; + val >>= MII_DAT_DATA_SHIFT; + + return val; +} + +static int bcm6348_mdio_write(struct mii_dev *bus, int addr, int dev_addr, + int reg, u16 value) +{ + void __iomem *base = bus->priv; + uint32_t val; + + val = MII_DAT_OP_WRITE; + val |= (reg << MII_DAT_REG_SHIFT) & MII_DAT_REG_MASK; + val |= (0x2 << MII_DAT_TA_SHIFT) & MII_DAT_TA_MASK; + val |= (addr << MII_DAT_PHY_SHIFT) & MII_DAT_PHY_MASK; + val |= (value << MII_DAT_DATA_SHIFT) & MII_DAT_DATA_MASK; + + if (bcm6348_mdio_op(base, val)) { + pr_err("%s: timeout\n", __func__); + return -EINVAL; + } + + return 0; +} + +static int bcm6348_mdio_init(const char *name, void __iomem *base) +{ + struct mii_dev *bus; + + bus = mdio_alloc(); + if (!bus) { + pr_err("%s: failed to allocate MDIO bus\n", __func__); + return -ENOMEM; + } + + bus->read = bcm6348_mdio_read; + bus->write = bcm6348_mdio_write; + bus->priv = base; + snprintf(bus->name, sizeof(bus->name), "%s", name); + + return mdio_register(bus); +} + +static int bcm6348_phy_init(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct bcm6348_eth_priv *priv = dev_get_priv(dev); + struct mii_dev *bus; + + /* get mii bus */ + bus = miiphy_get_dev_by_name(dev->name); + + /* phy connect */ + priv->phy_dev = phy_connect(bus, priv->phy_id, dev, + pdata->phy_interface); + if (!priv->phy_dev) { + pr_err("%s: no phy device\n", __func__); + return -ENODEV; + } + + priv->phy_dev->supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_MII); + priv->phy_dev->advertising = priv->phy_dev->supported; + + /* phy config */ + phy_config(priv->phy_dev); + + return 0; +} + +static int bcm6348_eth_probe(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct bcm6348_eth_priv *priv = dev_get_priv(dev); + struct ofnode_phandle_args phy; + const char *phy_mode; + int ret, i; + + /* get base address */ + priv->base = dev_remap_addr(dev); + if (!priv->base) + return -EINVAL; + pdata->iobase = (phys_addr_t) priv->base; + + /* get phy mode */ + pdata->phy_interface = PHY_INTERFACE_MODE_NONE; + phy_mode = dev_read_string(dev, "phy-mode"); + if (phy_mode) + pdata->phy_interface = phy_get_interface_by_name(phy_mode); + if (pdata->phy_interface == PHY_INTERFACE_MODE_NONE) + return -ENODEV; + + /* get phy */ + if (dev_read_phandle_with_args(dev, "phy", NULL, 0, 0, &phy)) + return -ENOENT; + priv->phy_id = ofnode_read_u32_default(phy.node, "reg", -1); + + /* get dma channels */ + ret = dma_get_by_name(dev, "tx", &priv->tx_dma); + if (ret) + return -EINVAL; + + ret = dma_get_by_name(dev, "rx", &priv->rx_dma); + if (ret) + return -EINVAL; + + /* try to enable clocks */ + for (i = 0; ; i++) { + struct clk clk; + int ret; + + ret = clk_get_by_index(dev, i, &clk); + if (ret < 0) + break; + + ret = clk_enable(&clk); + if (ret < 0) { + pr_err("%s: error enabling clock %d\n", __func__, i); + return ret; + } + + ret = clk_free(&clk); + if (ret < 0) { + pr_err("%s: error freeing clock %d\n", __func__, i); + return ret; + } + } + + /* try to perform resets */ + for (i = 0; ; i++) { + struct reset_ctl reset; + int ret; + + ret = reset_get_by_index(dev, i, &reset); + if (ret < 0) + break; + + ret = reset_deassert(&reset); + if (ret < 0) { + pr_err("%s: error deasserting reset %d\n", __func__, i); + return ret; + } + + ret = reset_free(&reset); + if (ret < 0) { + pr_err("%s: error freeing reset %d\n", __func__, i); + return ret; + } + } + + /* disable emac */ + bcm6348_eth_mac_disable(priv); + + /* reset emac */ + bcm6348_eth_mac_reset(priv); + + /* select correct mii interface */ + if (pdata->phy_interface == PHY_INTERFACE_MODE_INTERNAL) + clrbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_EPHY_MASK); + else + setbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_EPHY_MASK); + + /* turn on mdc clock */ + writel_be((0x1f << MII_SC_MDCFREQDIV_SHIFT) | + MII_SC_PREAMBLE_EN_MASK, priv->base + MII_SC_REG); + + /* set mib counters to not clear when read */ + clrbits_be32(priv->base + MIB_CTL_REG, MIB_CTL_RDCLEAR_MASK); + + /* initialize perfect match registers */ + for (i = 0; i < ETH_PM_CNT; i++) { + writel_be(0, priv->base + ETH_PML_REG(i)); + writel_be(0, priv->base + ETH_PMH_REG(i)); + } + + /* init mii bus */ + ret = bcm6348_mdio_init(dev->name, priv->base); + if (ret) + return ret; + + /* init phy */ + ret = bcm6348_phy_init(dev); + if (ret) + return ret; + + return 0; +} + +U_BOOT_DRIVER(bcm6348_eth) = { + .name = "bcm6348_eth", + .id = UCLASS_ETH, + .of_match = bcm6348_eth_ids, + .ops = &bcm6348_eth_ops, + .platdata_auto_alloc_size = sizeof(struct eth_pdata), + .priv_auto_alloc_size = sizeof(struct bcm6348_eth_priv), + .probe = bcm6348_eth_probe, +}; diff --git a/drivers/net/bcm6368-eth.c b/drivers/net/bcm6368-eth.c new file mode 100644 index 00000000000..a31efba9d19 --- /dev/null +++ b/drivers/net/bcm6368-eth.c @@ -0,0 +1,625 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> + * + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c: + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <dma.h> +#include <miiphy.h> +#include <net.h> +#include <reset.h> +#include <wait_bit.h> +#include <asm/io.h> + +#define ETH_PORT_STR "brcm,enetsw-port" + +#define ETH_RX_DESC PKTBUFSRX +#define ETH_ZLEN 60 +#define ETH_TIMEOUT 100 + +#define ETH_MAX_PORT 8 +#define ETH_RGMII_PORT0 4 + +/* Port traffic control */ +#define ETH_PTCTRL_REG(x) (0x0 + (x)) +#define ETH_PTCTRL_RXDIS_SHIFT 0 +#define ETH_PTCTRL_RXDIS_MASK (1 << ETH_PTCTRL_RXDIS_SHIFT) +#define ETH_PTCTRL_TXDIS_SHIFT 1 +#define ETH_PTCTRL_TXDIS_MASK (1 << ETH_PTCTRL_TXDIS_SHIFT) + +/* Switch mode register */ +#define ETH_SWMODE_REG 0xb +#define ETH_SWMODE_FWD_EN_SHIFT 1 +#define ETH_SWMODE_FWD_EN_MASK (1 << ETH_SWMODE_FWD_EN_SHIFT) + +/* IMP override Register */ +#define ETH_IMPOV_REG 0xe +#define ETH_IMPOV_LINKUP_SHIFT 0 +#define ETH_IMPOV_LINKUP_MASK (1 << ETH_IMPOV_LINKUP_SHIFT) +#define ETH_IMPOV_FDX_SHIFT 1 +#define ETH_IMPOV_FDX_MASK (1 << ETH_IMPOV_FDX_SHIFT) +#define ETH_IMPOV_100_SHIFT 2 +#define ETH_IMPOV_100_MASK (1 << ETH_IMPOV_100_SHIFT) +#define ETH_IMPOV_1000_SHIFT 3 +#define ETH_IMPOV_1000_MASK (1 << ETH_IMPOV_1000_SHIFT) +#define ETH_IMPOV_RXFLOW_SHIFT 4 +#define ETH_IMPOV_RXFLOW_MASK (1 << ETH_IMPOV_RXFLOW_SHIFT) +#define ETH_IMPOV_TXFLOW_SHIFT 5 +#define ETH_IMPOV_TXFLOW_MASK (1 << ETH_IMPOV_TXFLOW_SHIFT) +#define ETH_IMPOV_FORCE_SHIFT 7 +#define ETH_IMPOV_FORCE_MASK (1 << ETH_IMPOV_FORCE_SHIFT) + +/* Port override Register */ +#define ETH_PORTOV_REG(x) (0x58 + (x)) +#define ETH_PORTOV_LINKUP_SHIFT 0 +#define ETH_PORTOV_LINKUP_MASK (1 << ETH_PORTOV_LINKUP_SHIFT) +#define ETH_PORTOV_FDX_SHIFT 1 +#define ETH_PORTOV_FDX_MASK (1 << ETH_PORTOV_FDX_SHIFT) +#define ETH_PORTOV_100_SHIFT 2 +#define ETH_PORTOV_100_MASK (1 << ETH_PORTOV_100_SHIFT) +#define ETH_PORTOV_1000_SHIFT 3 +#define ETH_PORTOV_1000_MASK (1 << ETH_PORTOV_1000_SHIFT) +#define ETH_PORTOV_RXFLOW_SHIFT 4 +#define ETH_PORTOV_RXFLOW_MASK (1 << ETH_PORTOV_RXFLOW_SHIFT) +#define ETH_PORTOV_TXFLOW_SHIFT 5 +#define ETH_PORTOV_TXFLOW_MASK (1 << ETH_PORTOV_TXFLOW_SHIFT) +#define ETH_PORTOV_ENABLE_SHIFT 6 +#define ETH_PORTOV_ENABLE_MASK (1 << ETH_PORTOV_ENABLE_SHIFT) + +/* Port RGMII control register */ +#define ETH_RGMII_CTRL_REG(x) (0x60 + (x)) +#define ETH_RGMII_CTRL_GMII_CLK_EN (1 << 7) +#define ETH_RGMII_CTRL_MII_OVERRIDE_EN (1 << 6) +#define ETH_RGMII_CTRL_MII_MODE_MASK (3 << 4) +#define ETH_RGMII_CTRL_RGMII_MODE (0 << 4) +#define ETH_RGMII_CTRL_MII_MODE (1 << 4) +#define ETH_RGMII_CTRL_RVMII_MODE (2 << 4) +#define ETH_RGMII_CTRL_TIMING_SEL_EN (1 << 0) + +/* Port RGMII timing register */ +#define ENETSW_RGMII_TIMING_REG(x) (0x68 + (x)) + +/* MDIO control register */ +#define MII_SC_REG 0xb0 +#define MII_SC_EXT_SHIFT 16 +#define MII_SC_EXT_MASK (1 << MII_SC_EXT_SHIFT) +#define MII_SC_REG_SHIFT 20 +#define MII_SC_PHYID_SHIFT 25 +#define MII_SC_RD_SHIFT 30 +#define MII_SC_RD_MASK (1 << MII_SC_RD_SHIFT) +#define MII_SC_WR_SHIFT 31 +#define MII_SC_WR_MASK (1 << MII_SC_WR_SHIFT) + +/* MDIO data register */ +#define MII_DAT_REG 0xb4 + +/* Global Management Configuration Register */ +#define ETH_GMCR_REG 0x200 +#define ETH_GMCR_RST_MIB_SHIFT 0 +#define ETH_GMCR_RST_MIB_MASK (1 << ETH_GMCR_RST_MIB_SHIFT) + +/* Jumbo control register port mask register */ +#define ETH_JMBCTL_PORT_REG 0x4004 + +/* Jumbo control mib good frame register */ +#define ETH_JMBCTL_MAXSIZE_REG 0x4008 + +/* ETH port data */ +struct bcm_enetsw_port { + bool used; + const char *name; + /* Config */ + bool bypass_link; + int force_speed; + bool force_duplex_full; + /* PHY */ + int phy_id; +}; + +/* ETH data */ +struct bcm6368_eth_priv { + void __iomem *base; + /* DMA */ + struct dma rx_dma; + struct dma tx_dma; + /* Ports */ + uint8_t num_ports; + struct bcm_enetsw_port used_ports[ETH_MAX_PORT]; + int sw_port_link[ETH_MAX_PORT]; + bool rgmii_override; + bool rgmii_timing; + /* PHY */ + int phy_id; +}; + +static inline bool bcm_enet_port_is_rgmii(int portid) +{ + return portid >= ETH_RGMII_PORT0; +} + +static int bcm6368_mdio_read(struct bcm6368_eth_priv *priv, uint8_t ext, + int phy_id, int reg) +{ + uint32_t val; + + writel_be(0, priv->base + MII_SC_REG); + + val = MII_SC_RD_MASK | + (phy_id << MII_SC_PHYID_SHIFT) | + (reg << MII_SC_REG_SHIFT); + + if (ext) + val |= MII_SC_EXT_MASK; + + writel_be(val, priv->base + MII_SC_REG); + udelay(50); + + return readw_be(priv->base + MII_DAT_REG); +} + +static int bcm6368_mdio_write(struct bcm6368_eth_priv *priv, uint8_t ext, + int phy_id, int reg, u16 data) +{ + uint32_t val; + + writel_be(0, priv->base + MII_SC_REG); + + val = MII_SC_WR_MASK | + (phy_id << MII_SC_PHYID_SHIFT) | + (reg << MII_SC_REG_SHIFT); + + if (ext) + val |= MII_SC_EXT_MASK; + + val |= data; + + writel_be(val, priv->base + MII_SC_REG); + udelay(50); + + return 0; +} + +static int bcm6368_eth_free_pkt(struct udevice *dev, uchar *packet, int len) +{ + struct bcm6368_eth_priv *priv = dev_get_priv(dev); + + return dma_prepare_rcv_buf(&priv->rx_dma, packet, len); +} + +static int bcm6368_eth_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct bcm6368_eth_priv *priv = dev_get_priv(dev); + + return dma_receive(&priv->rx_dma, (void**)packetp, NULL); +} + +static int bcm6368_eth_send(struct udevice *dev, void *packet, int length) +{ + struct bcm6368_eth_priv *priv = dev_get_priv(dev); + + /* pad packets smaller than ETH_ZLEN */ + if (length < ETH_ZLEN) { + memset(packet + length, 0, ETH_ZLEN - length); + length = ETH_ZLEN; + } + + return dma_send(&priv->tx_dma, packet, length, NULL); +} + +static int bcm6368_eth_adjust_link(struct udevice *dev) +{ + struct bcm6368_eth_priv *priv = dev_get_priv(dev); + unsigned int i; + + for (i = 0; i < priv->num_ports; i++) { + struct bcm_enetsw_port *port; + int val, j, up, adv, lpa, speed, duplex, media; + int external_phy = bcm_enet_port_is_rgmii(i); + u8 override; + + port = &priv->used_ports[i]; + if (!port->used) + continue; + + if (port->bypass_link) + continue; + + /* dummy read to clear */ + for (j = 0; j < 2; j++) + val = bcm6368_mdio_read(priv, external_phy, + port->phy_id, MII_BMSR); + + if (val == 0xffff) + continue; + + up = (val & BMSR_LSTATUS) ? 1 : 0; + if (!(up ^ priv->sw_port_link[i])) + continue; + + priv->sw_port_link[i] = up; + + /* link changed */ + if (!up) { + dev_info(&priv->pdev->dev, "link DOWN on %s\n", + port->name); + writeb_be(ETH_PORTOV_ENABLE_MASK, + priv->base + ETH_PORTOV_REG(i)); + writeb_be(ETH_PTCTRL_RXDIS_MASK | + ETH_PTCTRL_TXDIS_MASK, + priv->base + ETH_PTCTRL_REG(i)); + continue; + } + + adv = bcm6368_mdio_read(priv, external_phy, + port->phy_id, MII_ADVERTISE); + + lpa = bcm6368_mdio_read(priv, external_phy, port->phy_id, + MII_LPA); + + /* figure out media and duplex from advertise and LPA values */ + media = mii_nway_result(lpa & adv); + duplex = (media & ADVERTISE_FULL) ? 1 : 0; + + if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)) + speed = 100; + else + speed = 10; + + if (val & BMSR_ESTATEN) { + adv = bcm6368_mdio_read(priv, external_phy, + port->phy_id, MII_CTRL1000); + + lpa = bcm6368_mdio_read(priv, external_phy, + port->phy_id, MII_STAT1000); + + if ((adv & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) && + (lpa & (LPA_1000FULL | LPA_1000HALF))) { + speed = 1000; + duplex = (lpa & LPA_1000FULL); + } + } + + pr_alert("link UP on %s, %dMbps, %s-duplex\n", + port->name, speed, duplex ? "full" : "half"); + + override = ETH_PORTOV_ENABLE_MASK | + ETH_PORTOV_LINKUP_MASK; + + if (speed == 1000) + override |= ETH_PORTOV_1000_MASK; + else if (speed == 100) + override |= ETH_PORTOV_100_MASK; + if (duplex) + override |= ETH_PORTOV_FDX_MASK; + + writeb_be(override, priv->base + ETH_PORTOV_REG(i)); + writeb_be(0, priv->base + ETH_PTCTRL_REG(i)); + } + + return 0; +} + +static int bcm6368_eth_start(struct udevice *dev) +{ + struct bcm6368_eth_priv *priv = dev_get_priv(dev); + uint8_t i; + + /* prepare rx dma buffers */ + for (i = 0; i < ETH_RX_DESC; i++) { + int ret = dma_prepare_rcv_buf(&priv->rx_dma, net_rx_packets[i], + PKTSIZE_ALIGN); + if (ret < 0) + break; + } + + /* enable dma rx channel */ + dma_enable(&priv->rx_dma); + + /* enable dma tx channel */ + dma_enable(&priv->tx_dma); + + /* apply override config for bypass_link ports here. */ + for (i = 0; i < priv->num_ports; i++) { + struct bcm_enetsw_port *port; + u8 override; + + port = &priv->used_ports[i]; + if (!port->used) + continue; + + if (!port->bypass_link) + continue; + + override = ETH_PORTOV_ENABLE_MASK | + ETH_PORTOV_LINKUP_MASK; + + switch (port->force_speed) { + case 1000: + override |= ETH_PORTOV_1000_MASK; + break; + case 100: + override |= ETH_PORTOV_100_MASK; + break; + case 10: + break; + default: + pr_warn("%s: invalid forced speed on port %s\n", + __func__, port->name); + break; + } + + if (port->force_duplex_full) + override |= ETH_PORTOV_FDX_MASK; + + writeb_be(override, priv->base + ETH_PORTOV_REG(i)); + writeb_be(0, priv->base + ETH_PTCTRL_REG(i)); + } + + bcm6368_eth_adjust_link(dev); + + return 0; +} + +static void bcm6368_eth_stop(struct udevice *dev) +{ + struct bcm6368_eth_priv *priv = dev_get_priv(dev); + + /* disable dma rx channel */ + dma_disable(&priv->rx_dma); + + /* disable dma tx channel */ + dma_disable(&priv->tx_dma); +} + +static const struct eth_ops bcm6368_eth_ops = { + .free_pkt = bcm6368_eth_free_pkt, + .recv = bcm6368_eth_recv, + .send = bcm6368_eth_send, + .start = bcm6368_eth_start, + .stop = bcm6368_eth_stop, +}; + +static const struct udevice_id bcm6368_eth_ids[] = { + { .compatible = "brcm,bcm6368-enet", }, + { /* sentinel */ } +}; + +static bool bcm6368_phy_is_external(struct bcm6368_eth_priv *priv, int phy_id) +{ + uint8_t i; + + for (i = 0; i < priv->num_ports; ++i) { + if (!priv->used_ports[i].used) + continue; + if (priv->used_ports[i].phy_id == phy_id) + return bcm_enet_port_is_rgmii(i); + } + + return true; +} + +static int bcm6368_mii_mdio_read(struct mii_dev *bus, int addr, int devaddr, + int reg) +{ + struct bcm6368_eth_priv *priv = bus->priv; + bool ext = bcm6368_phy_is_external(priv, addr); + + return bcm6368_mdio_read(priv, ext, addr, reg); +} + +static int bcm6368_mii_mdio_write(struct mii_dev *bus, int addr, int devaddr, + int reg, u16 data) +{ + struct bcm6368_eth_priv *priv = bus->priv; + bool ext = bcm6368_phy_is_external(priv, addr); + + return bcm6368_mdio_write(priv, ext, addr, reg, data); +} + +static int bcm6368_mdio_init(const char *name, struct bcm6368_eth_priv *priv) +{ + struct mii_dev *bus; + + bus = mdio_alloc(); + if (!bus) { + pr_err("%s: failed to allocate MDIO bus\n", __func__); + return -ENOMEM; + } + + bus->read = bcm6368_mii_mdio_read; + bus->write = bcm6368_mii_mdio_write; + bus->priv = priv; + snprintf(bus->name, sizeof(bus->name), "%s", name); + + return mdio_register(bus); +} + +static int bcm6368_eth_probe(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct bcm6368_eth_priv *priv = dev_get_priv(dev); + int num_ports, ret, i; + uint32_t val; + ofnode node; + + /* get base address */ + priv->base = dev_remap_addr(dev); + if (!priv->base) + return -EINVAL; + pdata->iobase = (phys_addr_t) priv->base; + + /* get number of ports */ + num_ports = dev_read_u32_default(dev, "brcm,num-ports", ETH_MAX_PORT); + if (!num_ports || num_ports > ETH_MAX_PORT) + return -EINVAL; + + /* get dma channels */ + ret = dma_get_by_name(dev, "tx", &priv->tx_dma); + if (ret) + return -EINVAL; + + ret = dma_get_by_name(dev, "rx", &priv->rx_dma); + if (ret) + return -EINVAL; + + /* try to enable clocks */ + for (i = 0; ; i++) { + struct clk clk; + int ret; + + ret = clk_get_by_index(dev, i, &clk); + if (ret < 0) + break; + + ret = clk_enable(&clk); + if (ret < 0) { + pr_err("%s: error enabling clock %d\n", __func__, i); + return ret; + } + + ret = clk_free(&clk); + if (ret < 0) { + pr_err("%s: error freeing clock %d\n", __func__, i); + return ret; + } + } + + /* try to perform resets */ + for (i = 0; ; i++) { + struct reset_ctl reset; + int ret; + + ret = reset_get_by_index(dev, i, &reset); + if (ret < 0) + break; + + ret = reset_deassert(&reset); + if (ret < 0) { + pr_err("%s: error deasserting reset %d\n", __func__, i); + return ret; + } + + ret = reset_free(&reset); + if (ret < 0) { + pr_err("%s: error freeing reset %d\n", __func__, i); + return ret; + } + } + + /* set priv data */ + priv->num_ports = num_ports; + if (dev_read_bool(dev, "brcm,rgmii-override")) + priv->rgmii_override = true; + if (dev_read_bool(dev, "brcm,rgmii-timing")) + priv->rgmii_timing = true; + + /* get ports */ + dev_for_each_subnode(node, dev) { + const char *comp; + const char *label; + unsigned int p; + int phy_id; + int speed; + + comp = ofnode_read_string(node, "compatible"); + if (!comp || memcmp(comp, ETH_PORT_STR, sizeof(ETH_PORT_STR))) + continue; + + p = ofnode_read_u32_default(node, "reg", ETH_MAX_PORT); + if (p >= num_ports) + return -EINVAL; + + label = ofnode_read_string(node, "label"); + if (!label) { + debug("%s: node %s has no label\n", __func__, + ofnode_get_name(node)); + return -EINVAL; + } + + phy_id = ofnode_read_u32_default(node, "brcm,phy-id", -1); + + priv->used_ports[p].used = true; + priv->used_ports[p].name = label; + priv->used_ports[p].phy_id = phy_id; + + if (ofnode_read_bool(node, "full-duplex")) + priv->used_ports[p].force_duplex_full = true; + if (ofnode_read_bool(node, "bypass-link")) + priv->used_ports[p].bypass_link = true; + speed = ofnode_read_u32_default(node, "speed", 0); + if (speed) + priv->used_ports[p].force_speed = speed; + } + + /* init mii bus */ + ret = bcm6368_mdio_init(dev->name, priv); + if (ret) + return ret; + + /* disable all ports */ + for (i = 0; i < priv->num_ports; i++) { + writeb_be(ETH_PORTOV_ENABLE_MASK, + priv->base + ETH_PORTOV_REG(i)); + writeb_be(ETH_PTCTRL_RXDIS_MASK | + ETH_PTCTRL_TXDIS_MASK, + priv->base + ETH_PTCTRL_REG(i)); + + priv->sw_port_link[i] = 0; + } + + /* enable external ports */ + for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) { + u8 rgmii_ctrl; + + if (!priv->used_ports[i].used) + continue; + + rgmii_ctrl = readb_be(priv->base + ETH_RGMII_CTRL_REG(i)); + rgmii_ctrl |= ETH_RGMII_CTRL_GMII_CLK_EN; + if (priv->rgmii_override) + rgmii_ctrl |= ETH_RGMII_CTRL_MII_OVERRIDE_EN; + if (priv->rgmii_timing) + rgmii_ctrl |= ETH_RGMII_CTRL_TIMING_SEL_EN; + writeb_be(rgmii_ctrl, priv->base + ETH_RGMII_CTRL_REG(i)); + } + + /* reset mib */ + val = readb_be(priv->base + ETH_GMCR_REG); + val |= ETH_GMCR_RST_MIB_MASK; + writeb_be(val, priv->base + ETH_GMCR_REG); + mdelay(1); + val &= ~ETH_GMCR_RST_MIB_MASK; + writeb_be(val, priv->base + ETH_GMCR_REG); + mdelay(1); + + /* force CPU port state */ + val = readb_be(priv->base + ETH_IMPOV_REG); + val |= ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK; + writeb_be(val, priv->base + ETH_IMPOV_REG); + + /* enable switch forward engine */ + val = readb_be(priv->base + ETH_SWMODE_REG); + val |= ETH_SWMODE_FWD_EN_MASK; + writeb_be(val, priv->base + ETH_SWMODE_REG); + + /* enable jumbo on all ports */ + writel_be(0x1ff, priv->base + ETH_JMBCTL_PORT_REG); + writew_be(9728, priv->base + ETH_JMBCTL_MAXSIZE_REG); + + return 0; +} + +U_BOOT_DRIVER(bcm6368_eth) = { + .name = "bcm6368_eth", + .id = UCLASS_ETH, + .of_match = bcm6368_eth_ids, + .ops = &bcm6368_eth_ops, + .platdata_auto_alloc_size = sizeof(struct eth_pdata), + .priv_auto_alloc_size = sizeof(struct bcm6368_eth_priv), + .probe = bcm6368_eth_probe, +}; diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index e837eb7688c..cda4caa8034 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -656,7 +656,8 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr, phy_probe(dev); - bus->phymap[addr] = dev; + if (addr >= 0 && addr < PHY_MAX_ADDR) + bus->phymap[addr] = dev; return dev; } diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 3921e39d7bc..825ee7c3beb 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -164,4 +164,14 @@ config OMAP_USB2_PHY This PHY is found on OMAP devices supporting USB2. + +config KEYSTONE_USB_PHY + bool "Support TI Keystone USB PHY" + depends on PHY + depends on ARCH_KEYSTONE + help + Support for the USB PHY found on some Keystone (k2) processors + + This PHY is found on some Keystone (K2) devices supporting USB. + endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 53dd5bd0f77..099551d6930 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -18,3 +18,4 @@ obj-$(CONFIG_PHY_STM32_USBPHYC) += phy-stm32-usbphyc.o obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o meson-gxl-usb3.o obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o +obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o diff --git a/drivers/phy/keystone-usb-phy.c b/drivers/phy/keystone-usb-phy.c new file mode 100644 index 00000000000..e8146cabfa5 --- /dev/null +++ b/drivers/phy/keystone-usb-phy.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * Written by Jean-Jacques Hiblot <jjhiblot@ti.com> + */ + +#include <common.h> +#include <dm.h> +#include <dm/device.h> +#include <generic-phy.h> +#include <asm/io.h> + +/* USB PHY control register offsets */ +#define USB_PHY_CTL_UTMI 0x0000 +#define USB_PHY_CTL_PIPE 0x0004 +#define USB_PHY_CTL_PARAM_1 0x0008 +#define USB_PHY_CTL_PARAM_2 0x000c +#define USB_PHY_CTL_CLOCK 0x0010 +#define USB_PHY_CTL_PLL 0x0014 + +#define PHY_OTG_VBUSVLDECTSEL BIT(16) +#define PHY_REF_SSP_EN BIT(29) + +struct keystone_usb_phy { + void __iomem *reg; +}; + +static int keystone_usb_init(struct phy *phy) +{ + u32 val; + struct udevice *dev = phy->dev; + struct keystone_usb_phy *keystone = dev_get_priv(dev); + + /* + * VBUSVLDEXTSEL has a default value of 1 in BootCfg but shouldn't. + * It should always be cleared because our USB PHY has an onchip VBUS + * analog comparator. + */ + val = readl(keystone->reg + USB_PHY_CTL_CLOCK); + /* quit selecting the vbusvldextsel by default! */ + val &= ~PHY_OTG_VBUSVLDECTSEL; + writel(val, keystone->reg + USB_PHY_CTL_CLOCK); + + return 0; +} + +static int keystone_usb_power_on(struct phy *phy) +{ + u32 val; + struct udevice *dev = phy->dev; + struct keystone_usb_phy *keystone = dev_get_priv(dev); + + val = readl(keystone->reg + USB_PHY_CTL_CLOCK); + val |= PHY_REF_SSP_EN; + writel(val, keystone->reg + USB_PHY_CTL_CLOCK); + + return 0; +} + +static int keystone_usb_power_off(struct phy *phy) +{ + u32 val; + struct udevice *dev = phy->dev; + struct keystone_usb_phy *keystone = dev_get_priv(dev); + + val = readl(keystone->reg + USB_PHY_CTL_CLOCK); + val &= ~PHY_REF_SSP_EN; + writel(val, keystone->reg + USB_PHY_CTL_CLOCK); + + return 0; +} + +static int keystone_usb_exit(struct phy *phy) +{ + return 0; +} + +static int keystone_usb_phy_probe(struct udevice *dev) +{ + struct keystone_usb_phy *keystone = dev_get_priv(dev); + + keystone->reg = dev_remap_addr_index(dev, 0); + if (!keystone->reg) { + pr_err("unable to remap usb phy\n"); + return -EINVAL; + } + return 0; +} + +static const struct udevice_id keystone_usb_phy_ids[] = { + { .compatible = "ti,keystone-usbphy" }, + { } +}; + +static struct phy_ops keystone_usb_phy_ops = { + .init = keystone_usb_init, + .power_on = keystone_usb_power_on, + .power_off = keystone_usb_power_off, + .exit = keystone_usb_exit, +}; + +U_BOOT_DRIVER(keystone_usb_phy) = { + .name = "keystone_usb_phy", + .id = UCLASS_PHY, + .of_match = keystone_usb_phy_ids, + .ops = &keystone_usb_phy_ops, + .probe = keystone_usb_phy_probe, + .priv_auto_alloc_size = sizeof(struct keystone_usb_phy), +}; diff --git a/drivers/phy/omap-usb2-phy.c b/drivers/phy/omap-usb2-phy.c index fd20e8c1688..be3bb0d3676 100644 --- a/drivers/phy/omap-usb2-phy.c +++ b/drivers/phy/omap-usb2-phy.c @@ -19,6 +19,11 @@ #define OMAP_DEV_PHY_PD BIT(0) #define OMAP_USB2_PHY_PD BIT(28) +#define AM437X_USB2_PHY_PD BIT(0) +#define AM437X_USB2_OTG_PD BIT(1) +#define AM437X_USB2_OTGVDET_EN BIT(19) +#define AM437X_USB2_OTGSESSEND_EN BIT(20) + #define USB2PHY_DISCON_BYP_LATCH BIT(31) #define USB2PHY_ANA_CONFIG1 (0x4c) @@ -60,6 +65,15 @@ static const struct usb_phy_data dra7x_usb2_phy2_data = { .power_off = OMAP_USB2_PHY_PD, }; +static const struct usb_phy_data am437x_usb2_data = { + .label = "am437x_usb2", + .flags = 0, + .mask = AM437X_USB2_PHY_PD | AM437X_USB2_OTG_PD | + AM437X_USB2_OTGVDET_EN | AM437X_USB2_OTGSESSEND_EN, + .power_on = AM437X_USB2_OTGVDET_EN | AM437X_USB2_OTGSESSEND_EN, + .power_off = AM437X_USB2_PHY_PD | AM437X_USB2_OTG_PD, +}; + static const struct udevice_id omap_usb2_id_table[] = { { .compatible = "ti,omap5-usb2", @@ -73,6 +87,10 @@ static const struct udevice_id omap_usb2_id_table[] = { .compatible = "ti,dra7x-usb2-phy2", .data = (ulong)&dra7x_usb2_phy2_data, }, + { + .compatible = "ti,am437x-usb2", + .data = (ulong)&am437x_usb2_data, + }, {}, }; @@ -170,20 +188,25 @@ int omap_usb2_phy_probe(struct udevice *dev) } regmap = syscon_regmap_lookup_by_phandle(dev, "syscon-phy-power"); - if (IS_ERR(regmap)) { - printf("can't get regmap (err %ld)\n", PTR_ERR(regmap)); - return PTR_ERR(regmap); + if (!IS_ERR(regmap)) { + priv->pwr_regmap = regmap; + rc = dev_read_u32_array(dev, "syscon-phy-power", tmp, 2); + if (rc) { + printf("couldn't get power reg. offset (err %d)\n", rc); + return rc; + } + priv->pwr_reg_offset = tmp[1]; + return 0; } - priv->pwr_regmap = regmap; - - rc = dev_read_u32_array(dev, "syscon-phy-power", tmp, 2); - if (rc) { - printf("couldn't get power reg. offset (err %d)\n", rc); - return rc; + regmap = syscon_regmap_lookup_by_phandle(dev, "ctrl-module"); + if (!IS_ERR(regmap)) { + priv->pwr_regmap = regmap; + priv->pwr_reg_offset = 0; + return 0; } - priv->pwr_reg_offset = tmp[1]; - return 0; + printf("can't get regmap (err %ld)\n", PTR_ERR(regmap)); + return PTR_ERR(regmap); } U_BOOT_DRIVER(omap_usb2_phy) = { diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 7e6fad305ae..1dbe2b104b2 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -306,6 +306,7 @@ source "drivers/pinctrl/nxp/Kconfig" source "drivers/pinctrl/renesas/Kconfig" source "drivers/pinctrl/uniphier/Kconfig" source "drivers/pinctrl/exynos/Kconfig" +source "drivers/pinctrl/mscc/Kconfig" source "drivers/pinctrl/mvebu/Kconfig" source "drivers/pinctrl/broadcom/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 293bad3a950..66d36b99d1e 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_PIC32) += pinctrl_pic32.o obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/ obj-$(CONFIG_PINCTRL_MESON) += meson/ obj-$(CONFIG_PINCTRL_MTK) += mediatek/ +obj-$(CONFIG_PINCTRL_MSCC) += mscc/ obj-$(CONFIG_ARCH_MVEBU) += mvebu/ obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o diff --git a/drivers/pinctrl/mscc/Kconfig b/drivers/pinctrl/mscc/Kconfig new file mode 100644 index 00000000000..cfc6c060767 --- /dev/null +++ b/drivers/pinctrl/mscc/Kconfig @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +config PINCTRL_MSCC + bool + +config PINCTRL_MSCC_OCELOT + depends on SOC_OCELOT && PINCTRL_FULL && OF_CONTROL + select PINCTRL_MSCC + default y + bool "Microsemi ocelot family pin control driver" + help + Support pin multiplexing and pin configuration control on + Microsemi ocelot SoCs. + +config PINCTRL_MSCC_LUTON + depends on SOC_LUTON && PINCTRL_FULL && OF_CONTROL + select PINCTRL_MSCC + default y + bool "Microsemi luton family pin control driver" + help + Support pin multiplexing and pin configuration control on + Microsemi luton SoCs. diff --git a/drivers/pinctrl/mscc/Makefile b/drivers/pinctrl/mscc/Makefile new file mode 100644 index 00000000000..69106717282 --- /dev/null +++ b/drivers/pinctrl/mscc/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +obj-y += mscc-common.o +obj-$(CONFIG_PINCTRL_MSCC_OCELOT) += pinctrl-ocelot.o +obj-$(CONFIG_PINCTRL_MSCC_LUTON) += pinctrl-luton.o diff --git a/drivers/pinctrl/mscc/mscc-common.c b/drivers/pinctrl/mscc/mscc-common.c new file mode 100644 index 00000000000..d74b8a66492 --- /dev/null +++ b/drivers/pinctrl/mscc/mscc-common.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Microsemi SoCs pinctrl driver + * + * Author: <alexandre.belloni@free-electrons.com> + * Author: <gregory.clement@bootlin.com> + * License: Dual MIT/GPL + * Copyright (c) 2017 Microsemi Corporation + */ + +#include <asm/gpio.h> +#include <asm/system.h> +#include <common.h> +#include <config.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dm/pinctrl.h> +#include <dm/root.h> +#include <errno.h> +#include <fdtdec.h> +#include <linux/io.h> +#include "mscc-common.h" + +#define MSCC_GPIO_OUT_SET 0x0 +#define MSCC_GPIO_OUT_CLR 0x4 +#define MSCC_GPIO_OUT 0x8 +#define MSCC_GPIO_IN 0xc +#define MSCC_GPIO_OE 0x10 +#define MSCC_GPIO_INTR 0x14 +#define MSCC_GPIO_INTR_ENA 0x18 +#define MSCC_GPIO_INTR_IDENT 0x1c +#define MSCC_GPIO_ALT0 0x20 +#define MSCC_GPIO_ALT1 0x24 + +static int mscc_get_functions_count(struct udevice *dev) +{ + struct mscc_pinctrl *info = dev_get_priv(dev); + + return info->num_func; +} + +static const char *mscc_get_function_name(struct udevice *dev, + unsigned int function) +{ + struct mscc_pinctrl *info = dev_get_priv(dev); + + return info->function_names[function]; +} + +static int mscc_pin_function_idx(unsigned int pin, unsigned int function, + const struct mscc_pin_data *mscc_pins) +{ + struct mscc_pin_caps *p = mscc_pins[pin].drv_data; + int i; + + for (i = 0; i < MSCC_FUNC_PER_PIN; i++) { + if (function == p->functions[i]) + return i; + } + + return -1; +} + +static int mscc_pinmux_set_mux(struct udevice *dev, + unsigned int pin_selector, unsigned int selector) +{ + struct mscc_pinctrl *info = dev_get_priv(dev); + struct mscc_pin_caps *pin = info->mscc_pins[pin_selector].drv_data; + int f; + + f = mscc_pin_function_idx(pin_selector, selector, info->mscc_pins); + if (f < 0) + return -EINVAL; + /* + * f is encoded on two bits. + * bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of + * ALT1 + * This is racy because both registers can't be updated at the same time + * but it doesn't matter much for now. + */ + if (f & BIT(0)) + setbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin)); + else + clrbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin)); + + if (f & BIT(1)) + setbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1)); + else + clrbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1)); + + return 0; +} + +static int mscc_pctl_get_groups_count(struct udevice *dev) +{ + struct mscc_pinctrl *info = dev_get_priv(dev); + + return info->num_pins; +} + +static const char *mscc_pctl_get_group_name(struct udevice *dev, + unsigned int group) +{ + struct mscc_pinctrl *info = dev_get_priv(dev); + + return info->mscc_pins[group].name; +} + +static int mscc_create_group_func_map(struct udevice *dev, + struct mscc_pinctrl *info) +{ + u16 pins[info->num_pins]; + int f, npins, i; + + for (f = 0; f < info->num_func; f++) { + for (npins = 0, i = 0; i < info->num_pins; i++) { + if (mscc_pin_function_idx(i, f, info->mscc_pins) >= 0) + pins[npins++] = i; + } + + info->func[f].ngroups = npins; + info->func[f].groups = devm_kzalloc(dev, npins * + sizeof(char *), GFP_KERNEL); + if (!info->func[f].groups) + return -ENOMEM; + + for (i = 0; i < npins; i++) + info->func[f].groups[i] = info->mscc_pins[pins[i]].name; + } + + return 0; +} + +static int mscc_pinctrl_register(struct udevice *dev, struct mscc_pinctrl *info) +{ + int ret; + + ret = mscc_create_group_func_map(dev, info); + if (ret) { + dev_err(dev, "Unable to create group func map.\n"); + return ret; + } + + return 0; +} + +static int mscc_gpio_get(struct udevice *dev, unsigned int offset) +{ + struct mscc_pinctrl *info = dev_get_priv(dev->parent); + unsigned int val; + + val = readl(info->regs + MSCC_GPIO_IN); + + return !!(val & BIT(offset)); +} + +static int mscc_gpio_set(struct udevice *dev, unsigned int offset, int value) +{ + struct mscc_pinctrl *info = dev_get_priv(dev->parent); + + if (value) + writel(BIT(offset), info->regs + MSCC_GPIO_OUT_SET); + else + writel(BIT(offset), info->regs + MSCC_GPIO_OUT_CLR); + + return 0; +} + +static int mscc_gpio_get_direction(struct udevice *dev, unsigned int offset) +{ + struct mscc_pinctrl *info = dev_get_priv(dev->parent); + unsigned int val; + + val = readl(info->regs + MSCC_GPIO_OE); + + return (val & BIT(offset)) ? GPIOF_OUTPUT : GPIOF_INPUT; +} + +static int mscc_gpio_direction_input(struct udevice *dev, unsigned int offset) +{ + struct mscc_pinctrl *info = dev_get_priv(dev->parent); + + clrbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset)); + + return 0; +} + +static int mscc_gpio_direction_output(struct udevice *dev, + unsigned int offset, int value) +{ + struct mscc_pinctrl *info = dev_get_priv(dev->parent); + + setbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset)); + + return mscc_gpio_set(dev, offset, value); +} + +const struct dm_gpio_ops mscc_gpio_ops = { + .set_value = mscc_gpio_set, + .get_value = mscc_gpio_get, + .get_function = mscc_gpio_get_direction, + .direction_input = mscc_gpio_direction_input, + .direction_output = mscc_gpio_direction_output, +}; + +const struct pinctrl_ops mscc_pinctrl_ops = { + .get_pins_count = mscc_pctl_get_groups_count, + .get_pin_name = mscc_pctl_get_group_name, + .get_functions_count = mscc_get_functions_count, + .get_function_name = mscc_get_function_name, + .pinmux_set = mscc_pinmux_set_mux, + .set_state = pinctrl_generic_set_state, +}; + +int mscc_pinctrl_probe(struct udevice *dev, int num_func, + const struct mscc_pin_data *mscc_pins, int num_pins, + char *const *function_names) +{ + struct mscc_pinctrl *priv = dev_get_priv(dev); + int ret; + + priv->regs = dev_remap_addr(dev); + if (!priv->regs) + return -EINVAL; + + priv->func = devm_kzalloc(dev, num_func * sizeof(struct mscc_pmx_func), + GFP_KERNEL); + priv->num_func = num_func; + priv->mscc_pins = mscc_pins; + priv->num_pins = num_pins; + priv->function_names = function_names; + ret = mscc_pinctrl_register(dev, priv); + + return ret; +} diff --git a/drivers/pinctrl/mscc/mscc-common.h b/drivers/pinctrl/mscc/mscc-common.h new file mode 100644 index 00000000000..b0001db44c9 --- /dev/null +++ b/drivers/pinctrl/mscc/mscc-common.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ +/* + * Microsemi SoCs pinctrl driver + * + * Author: <alexandre.belloni@free-electrons.com> + * License: Dual MIT/GPL + * Copyright (c) 2017 Microsemi Corporation + */ + +#define MSCC_FUNC_PER_PIN 4 + +struct mscc_pin_caps { + unsigned int pin; + unsigned char functions[MSCC_FUNC_PER_PIN]; +}; + +struct mscc_pin_data { + const char *name; + struct mscc_pin_caps *drv_data; +}; + +#define MSCC_P(p, f0, f1, f2) \ +static struct mscc_pin_caps mscc_pin_##p = { \ + .pin = p, \ + .functions = { \ + FUNC_GPIO, FUNC_##f0, FUNC_##f1, FUNC_##f2, \ + }, \ +} + +struct mscc_pmx_func { + const char **groups; + unsigned int ngroups; +}; + +struct mscc_pinctrl { + struct udevice *dev; + struct pinctrl_dev *pctl; + void __iomem *regs; + struct mscc_pmx_func *func; + int num_func; + const struct mscc_pin_data *mscc_pins; + int num_pins; + char * const *function_names; +}; + +int mscc_pinctrl_probe(struct udevice *dev, int num_func, + const struct mscc_pin_data *mscc_pins, int num_pins, + char * const *function_names); +const struct pinctrl_ops mscc_pinctrl_ops; + +const struct dm_gpio_ops mscc_gpio_ops; diff --git a/drivers/pinctrl/mscc/pinctrl-luton.c b/drivers/pinctrl/mscc/pinctrl-luton.c new file mode 100644 index 00000000000..7166588e3cd --- /dev/null +++ b/drivers/pinctrl/mscc/pinctrl-luton.c @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Microsemi SoCs pinctrl driver + * + * Author: <gregory.clement@bootlin.com> + * License: Dual MIT/GPL + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <config.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dm/pinctrl.h> +#include <dm/root.h> +#include <errno.h> +#include <fdtdec.h> +#include <linux/io.h> +#include <asm/gpio.h> +#include <asm/system.h> +#include "mscc-common.h" + +enum { + FUNC_NONE, + FUNC_GPIO, + FUNC_SIO, + FUNC_TACHO, + FUNC_TWI, + FUNC_PHY_LED, + FUNC_EXT_IRQ, + FUNC_SFP, + FUNC_SI, + FUNC_PWM, + FUNC_UART, + FUNC_MAX +}; + +static char * const luton_function_names[] = { + [FUNC_NONE] = "none", + [FUNC_GPIO] = "gpio", + [FUNC_SIO] = "sio", + [FUNC_TACHO] = "tacho", + [FUNC_TWI] = "twi", + [FUNC_PHY_LED] = "phy_led", + [FUNC_EXT_IRQ] = "ext_irq", + [FUNC_SFP] = "sfp", + [FUNC_SI] = "si", + [FUNC_PWM] = "pwm", + [FUNC_UART] = "uart", +}; + +MSCC_P(0, SIO, NONE, NONE); +MSCC_P(1, SIO, NONE, NONE); +MSCC_P(2, SIO, NONE, NONE); +MSCC_P(3, SIO, NONE, NONE); +MSCC_P(4, TACHO, NONE, NONE); +MSCC_P(5, TWI, PHY_LED, NONE); +MSCC_P(6, TWI, PHY_LED, NONE); +MSCC_P(7, NONE, PHY_LED, NONE); +MSCC_P(8, EXT_IRQ, PHY_LED, NONE); +MSCC_P(9, EXT_IRQ, PHY_LED, NONE); +MSCC_P(10, SFP, PHY_LED, NONE); +MSCC_P(11, SFP, PHY_LED, NONE); +MSCC_P(12, SFP, PHY_LED, NONE); +MSCC_P(13, SFP, PHY_LED, NONE); +MSCC_P(14, SI, PHY_LED, NONE); +MSCC_P(15, SI, PHY_LED, NONE); +MSCC_P(16, SI, PHY_LED, NONE); +MSCC_P(17, SFP, PHY_LED, NONE); +MSCC_P(18, SFP, PHY_LED, NONE); +MSCC_P(19, SFP, PHY_LED, NONE); +MSCC_P(20, SFP, PHY_LED, NONE); +MSCC_P(21, SFP, PHY_LED, NONE); +MSCC_P(22, SFP, PHY_LED, NONE); +MSCC_P(23, SFP, PHY_LED, NONE); +MSCC_P(24, SFP, PHY_LED, NONE); +MSCC_P(25, SFP, PHY_LED, NONE); +MSCC_P(26, SFP, PHY_LED, NONE); +MSCC_P(27, SFP, PHY_LED, NONE); +MSCC_P(28, SFP, PHY_LED, NONE); +MSCC_P(29, PWM, NONE, NONE); +MSCC_P(30, UART, NONE, NONE); +MSCC_P(31, UART, NONE, NONE); + +#define LUTON_PIN(n) { \ + .name = "GPIO_"#n, \ + .drv_data = &mscc_pin_##n \ +} + +static const struct mscc_pin_data luton_pins[] = { + LUTON_PIN(0), + LUTON_PIN(1), + LUTON_PIN(2), + LUTON_PIN(3), + LUTON_PIN(4), + LUTON_PIN(5), + LUTON_PIN(6), + LUTON_PIN(7), + LUTON_PIN(8), + LUTON_PIN(9), + LUTON_PIN(10), + LUTON_PIN(11), + LUTON_PIN(12), + LUTON_PIN(13), + LUTON_PIN(14), + LUTON_PIN(15), + LUTON_PIN(16), + LUTON_PIN(17), + LUTON_PIN(18), + LUTON_PIN(19), + LUTON_PIN(20), + LUTON_PIN(21), + LUTON_PIN(22), + LUTON_PIN(23), + LUTON_PIN(24), + LUTON_PIN(25), + LUTON_PIN(26), + LUTON_PIN(27), + LUTON_PIN(28), + LUTON_PIN(29), + LUTON_PIN(30), + LUTON_PIN(31), +}; + +static int luton_gpio_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv; + + uc_priv = dev_get_uclass_priv(dev); + uc_priv->bank_name = "luton-gpio"; + uc_priv->gpio_count = ARRAY_SIZE(luton_pins); + + return 0; +} + +static struct driver luton_gpio_driver = { + .name = "luton-gpio", + .id = UCLASS_GPIO, + .probe = luton_gpio_probe, + .ops = &mscc_gpio_ops, +}; + +int luton_pinctrl_probe(struct udevice *dev) +{ + int ret; + + ret = mscc_pinctrl_probe(dev, FUNC_MAX, luton_pins, + ARRAY_SIZE(luton_pins), luton_function_names); + + if (ret) + return ret; + + ret = device_bind(dev, &luton_gpio_driver, "luton-gpio", NULL, + dev_of_offset(dev), NULL); + + return 0; +} + +static const struct udevice_id luton_pinctrl_of_match[] = { + {.compatible = "mscc,luton-pinctrl"}, + {}, +}; + +U_BOOT_DRIVER(luton_pinctrl) = { + .name = "luton-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(luton_pinctrl_of_match), + .probe = luton_pinctrl_probe, + .priv_auto_alloc_size = sizeof(struct mscc_pinctrl), + .ops = &mscc_pinctrl_ops, +}; diff --git a/drivers/pinctrl/mscc/pinctrl-ocelot.c b/drivers/pinctrl/mscc/pinctrl-ocelot.c new file mode 100644 index 00000000000..10f9b90aadc --- /dev/null +++ b/drivers/pinctrl/mscc/pinctrl-ocelot.c @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Microsemi SoCs pinctrl driver + * + * Author: <alexandre.belloni@free-electrons.com> + * Author: <gregory.clement@bootlin.com> + * License: Dual MIT/GPL + * Copyright (c) 2017 Microsemi Corporation + */ + +#include <asm/gpio.h> +#include <asm/system.h> +#include <common.h> +#include <config.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dm/pinctrl.h> +#include <dm/root.h> +#include <errno.h> +#include <fdtdec.h> +#include <linux/io.h> +#include "mscc-common.h" + +enum { + FUNC_NONE, + FUNC_GPIO, + FUNC_IRQ0_IN, + FUNC_IRQ0_OUT, + FUNC_IRQ1_IN, + FUNC_IRQ1_OUT, + FUNC_MIIM1, + FUNC_PCI_WAKE, + FUNC_PTP0, + FUNC_PTP1, + FUNC_PTP2, + FUNC_PTP3, + FUNC_PWM, + FUNC_RECO_CLK0, + FUNC_RECO_CLK1, + FUNC_SFP0, + FUNC_SFP1, + FUNC_SFP2, + FUNC_SFP3, + FUNC_SFP4, + FUNC_SFP5, + FUNC_SG0, + FUNC_SI, + FUNC_TACHO, + FUNC_TWI, + FUNC_TWI_SCL_M, + FUNC_UART, + FUNC_UART2, + FUNC_MAX +}; + +static char * const ocelot_function_names[] = { + [FUNC_NONE] = "none", + [FUNC_GPIO] = "gpio", + [FUNC_IRQ0_IN] = "irq0_in", + [FUNC_IRQ0_OUT] = "irq0_out", + [FUNC_IRQ1_IN] = "irq1_in", + [FUNC_IRQ1_OUT] = "irq1_out", + [FUNC_MIIM1] = "miim1", + [FUNC_PCI_WAKE] = "pci_wake", + [FUNC_PTP0] = "ptp0", + [FUNC_PTP1] = "ptp1", + [FUNC_PTP2] = "ptp2", + [FUNC_PTP3] = "ptp3", + [FUNC_PWM] = "pwm", + [FUNC_RECO_CLK0] = "reco_clk0", + [FUNC_RECO_CLK1] = "reco_clk1", + [FUNC_SFP0] = "sfp0", + [FUNC_SFP1] = "sfp1", + [FUNC_SFP2] = "sfp2", + [FUNC_SFP3] = "sfp3", + [FUNC_SFP4] = "sfp4", + [FUNC_SFP5] = "sfp5", + [FUNC_SG0] = "sg0", + [FUNC_SI] = "si", + [FUNC_TACHO] = "tacho", + [FUNC_TWI] = "twi", + [FUNC_TWI_SCL_M] = "twi_scl_m", + [FUNC_UART] = "uart", + [FUNC_UART2] = "uart2", +}; + +MSCC_P(0, SG0, NONE, NONE); +MSCC_P(1, SG0, NONE, NONE); +MSCC_P(2, SG0, NONE, NONE); +MSCC_P(3, SG0, NONE, NONE); +MSCC_P(4, IRQ0_IN, IRQ0_OUT, TWI); +MSCC_P(5, IRQ1_IN, IRQ1_OUT, PCI_WAKE); +MSCC_P(6, UART, TWI_SCL_M, NONE); +MSCC_P(7, UART, TWI_SCL_M, NONE); +MSCC_P(8, SI, TWI_SCL_M, IRQ0_OUT); +MSCC_P(9, SI, TWI_SCL_M, IRQ1_OUT); +MSCC_P(10, PTP2, TWI_SCL_M, SFP0); +MSCC_P(11, PTP3, TWI_SCL_M, SFP1); +MSCC_P(12, UART2, TWI_SCL_M, SFP2); +MSCC_P(13, UART2, TWI_SCL_M, SFP3); +MSCC_P(14, MIIM1, TWI_SCL_M, SFP4); +MSCC_P(15, MIIM1, TWI_SCL_M, SFP5); +MSCC_P(16, TWI, NONE, SI); +MSCC_P(17, TWI, TWI_SCL_M, SI); +MSCC_P(18, PTP0, TWI_SCL_M, NONE); +MSCC_P(19, PTP1, TWI_SCL_M, NONE); +MSCC_P(20, RECO_CLK0, TACHO, NONE); +MSCC_P(21, RECO_CLK1, PWM, NONE); + +#define OCELOT_PIN(n) { \ + .name = "GPIO_"#n, \ + .drv_data = &mscc_pin_##n \ +} + +static const struct mscc_pin_data ocelot_pins[] = { + OCELOT_PIN(0), + OCELOT_PIN(1), + OCELOT_PIN(2), + OCELOT_PIN(3), + OCELOT_PIN(4), + OCELOT_PIN(5), + OCELOT_PIN(6), + OCELOT_PIN(7), + OCELOT_PIN(8), + OCELOT_PIN(9), + OCELOT_PIN(10), + OCELOT_PIN(11), + OCELOT_PIN(12), + OCELOT_PIN(13), + OCELOT_PIN(14), + OCELOT_PIN(15), + OCELOT_PIN(16), + OCELOT_PIN(17), + OCELOT_PIN(18), + OCELOT_PIN(19), + OCELOT_PIN(20), + OCELOT_PIN(21), +}; + +static int ocelot_gpio_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv; + + uc_priv = dev_get_uclass_priv(dev); + uc_priv->bank_name = "ocelot-gpio"; + uc_priv->gpio_count = ARRAY_SIZE(ocelot_pins); + + return 0; +} + +static struct driver ocelot_gpio_driver = { + .name = "ocelot-gpio", + .id = UCLASS_GPIO, + .probe = ocelot_gpio_probe, + .ops = &mscc_gpio_ops, +}; + +int ocelot_pinctrl_probe(struct udevice *dev) +{ + int ret; + + ret = mscc_pinctrl_probe(dev, FUNC_MAX, ocelot_pins, + ARRAY_SIZE(ocelot_pins), + ocelot_function_names); + + if (ret) + return ret; + + ret = device_bind(dev, &ocelot_gpio_driver, "ocelot-gpio", NULL, + dev_of_offset(dev), NULL); + + return ret; +} + +static const struct udevice_id ocelot_pinctrl_of_match[] = { + {.compatible = "mscc,ocelot-pinctrl"}, + {}, +}; + +U_BOOT_DRIVER(ocelot_pinctrl) = { + .name = "ocelot-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(ocelot_pinctrl_of_match), + .probe = ocelot_pinctrl_probe, + .priv_auto_alloc_size = sizeof(struct mscc_pinctrl), + .ops = &mscc_pinctrl_ops, +}; diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c index 6db04450670..29c910c55f3 100644 --- a/drivers/pinctrl/pinctrl-uclass.c +++ b/drivers/pinctrl/pinctrl-uclass.c @@ -117,9 +117,9 @@ static int pinconfig_post_bind(struct udevice *dev) int ret; dev_for_each_subnode(node, dev) { - if (pre_reloc_only && - !ofnode_pre_reloc(node)) + if (pre_reloc_only ^ ofnode_pre_reloc(node)) continue; + /* * If this node has "compatible" property, this is not * a pin configuration node, but a normal device. skip. diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c index 4511625ff25..39e46279d53 100644 --- a/drivers/power/regulator/regulator-uclass.c +++ b/drivers/power/regulator/regulator-uclass.c @@ -113,7 +113,7 @@ int regulator_set_enable(struct udevice *dev, bool enable) uc_pdata = dev_get_uclass_platdata(dev); if (!enable && uc_pdata->always_on) - return -EACCES; + return 0; return ops->set_enable(dev, enable); } diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 6252dd8c4b5..b7ff2960abf 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -343,6 +343,13 @@ config DEBUG_UART_SANDBOX start up driver model. The driver will be available until the real driver model serial is running. +config DEBUG_UART_SIFIVE + bool "SiFive UART" + help + Select this to enable a debug UART using the serial_sifive driver. You + will need to provide parameters to make this work. The driver will + be available until the real driver-model serial is running. + config DEBUG_UART_STM32 bool "STMicroelectronics STM32" depends on STM32_SERIAL @@ -679,6 +686,12 @@ config PXA_SERIAL If you have a machine based on a Marvell XScale PXA2xx CPU you can enable its onboard serial ports by enabling this option. +config SIFIVE_SERIAL + bool "SiFive UART support" + depends on DM_SERIAL + help + This driver supports the SiFive UART. If unsure say N. + config STI_ASC_SERIAL bool "STMicroelectronics on-chip UART" depends on DM_SERIAL && ARCH_STI diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 2f8d065a4c2..06ee30697de 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_NULLDEV_SERIAL) += serial_nulldev.o obj-$(CONFIG_OWL_SERIAL) += serial_owl.o obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o obj-$(CONFIG_MTK_SERIAL) += serial_mtk.o +obj-$(CONFIG_SIFIVE_SERIAL) += serial_sifive.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_USB_TTY) += usbtty.o diff --git a/drivers/serial/serial_sifive.c b/drivers/serial/serial_sifive.c new file mode 100644 index 00000000000..341728a690f --- /dev/null +++ b/drivers/serial/serial_sifive.c @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Anup Patel <anup@brainfault.org> + */ + +#include <clk.h> +#include <common.h> +#include <debug_uart.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <watchdog.h> +#include <asm/io.h> +#include <linux/compiler.h> +#include <serial.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_TXFIFO_FULL 0x80000000 +#define UART_RXFIFO_EMPTY 0x80000000 +#define UART_RXFIFO_DATA 0x000000ff +#define UART_TXCTRL_TXEN 0x1 +#define UART_RXCTRL_RXEN 0x1 + +struct uart_sifive { + u32 txfifo; + u32 rxfifo; + u32 txctrl; + u32 rxctrl; + u32 ie; + u32 ip; + u32 div; +}; + +struct sifive_uart_platdata { + unsigned int clock; + int saved_input_char; + struct uart_sifive *regs; +}; + +/* Set up the baud rate in gd struct */ +static void _sifive_serial_setbrg(struct uart_sifive *regs, + unsigned long clock, unsigned long baud) +{ + writel((u32)((clock / baud) - 1), ®s->div); +} + +static void _sifive_serial_init(struct uart_sifive *regs) +{ + writel(UART_TXCTRL_TXEN, ®s->txctrl); + writel(UART_RXCTRL_RXEN, ®s->rxctrl); + writel(0, ®s->ie); +} + +static int _sifive_serial_putc(struct uart_sifive *regs, const char c) +{ + if (readl(®s->txfifo) & UART_TXFIFO_FULL) + return -EAGAIN; + + writel(c, ®s->txfifo); + + return 0; +} + +static int _sifive_serial_getc(struct uart_sifive *regs) +{ + int ch = readl(®s->rxfifo); + + if (ch & UART_RXFIFO_EMPTY) + return -EAGAIN; + ch &= UART_RXFIFO_DATA; + + return (!ch) ? -EAGAIN : ch; +} + +static int sifive_serial_setbrg(struct udevice *dev, int baudrate) +{ + int err; + struct clk clk; + struct sifive_uart_platdata *platdata = dev_get_platdata(dev); + + err = clk_get_by_index(dev, 0, &clk); + if (!err) { + err = clk_get_rate(&clk); + if (!IS_ERR_VALUE(err)) + platdata->clock = err; + } else if (err != -ENOENT && err != -ENODEV && err != -ENOSYS) { + debug("SiFive UART failed to get clock\n"); + return err; + } + + if (!platdata->clock) + platdata->clock = dev_read_u32_default(dev, "clock-frequency", 0); + if (!platdata->clock) { + debug("SiFive UART clock not defined\n"); + return -EINVAL; + } + + _sifive_serial_setbrg(platdata->regs, platdata->clock, baudrate); + + return 0; +} + +static int sifive_serial_probe(struct udevice *dev) +{ + struct sifive_uart_platdata *platdata = dev_get_platdata(dev); + + /* No need to reinitialize the UART after relocation */ + if (gd->flags & GD_FLG_RELOC) + return 0; + + platdata->saved_input_char = 0; + _sifive_serial_init(platdata->regs); + + return 0; +} + +static int sifive_serial_getc(struct udevice *dev) +{ + int c; + struct sifive_uart_platdata *platdata = dev_get_platdata(dev); + struct uart_sifive *regs = platdata->regs; + + if (platdata->saved_input_char > 0) { + c = platdata->saved_input_char; + platdata->saved_input_char = 0; + return c; + } + + while ((c = _sifive_serial_getc(regs)) == -EAGAIN) ; + + return c; +} + +static int sifive_serial_putc(struct udevice *dev, const char ch) +{ + int rc; + struct sifive_uart_platdata *platdata = dev_get_platdata(dev); + + while ((rc = _sifive_serial_putc(platdata->regs, ch)) == -EAGAIN) ; + + return rc; +} + +static int sifive_serial_pending(struct udevice *dev, bool input) +{ + struct sifive_uart_platdata *platdata = dev_get_platdata(dev); + struct uart_sifive *regs = platdata->regs; + + if (input) { + if (platdata->saved_input_char > 0) + return 1; + platdata->saved_input_char = _sifive_serial_getc(regs); + return (platdata->saved_input_char > 0) ? 1 : 0; + } else { + return !!(readl(®s->txfifo) & UART_TXFIFO_FULL); + } +} + +static int sifive_serial_ofdata_to_platdata(struct udevice *dev) +{ + struct sifive_uart_platdata *platdata = dev_get_platdata(dev); + + platdata->regs = (struct uart_sifive *)dev_read_addr(dev); + if (IS_ERR(platdata->regs)) + return PTR_ERR(platdata->regs); + + return 0; +} + +static const struct dm_serial_ops sifive_serial_ops = { + .putc = sifive_serial_putc, + .getc = sifive_serial_getc, + .pending = sifive_serial_pending, + .setbrg = sifive_serial_setbrg, +}; + +static const struct udevice_id sifive_serial_ids[] = { + { .compatible = "sifive,uart0" }, + { } +}; + +U_BOOT_DRIVER(serial_sifive) = { + .name = "serial_sifive", + .id = UCLASS_SERIAL, + .of_match = sifive_serial_ids, + .ofdata_to_platdata = sifive_serial_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct sifive_uart_platdata), + .probe = sifive_serial_probe, + .ops = &sifive_serial_ops, +}; + +#ifdef CONFIG_DEBUG_UART_SIFIVE +static inline void _debug_uart_init(void) +{ + struct uart_sifive *regs = + (struct uart_sifive *)CONFIG_DEBUG_UART_BASE; + + _sifive_serial_setbrg(regs, CONFIG_DEBUG_UART_CLOCK, + CONFIG_BAUDRATE); + _sifive_serial_init(regs); +} + +static inline void _debug_uart_putc(int ch) +{ + struct uart_sifive *regs = + (struct uart_sifive *)CONFIG_DEBUG_UART_BASE; + + while (_sifive_serial_putc(regs, ch) == -EAGAIN) + WATCHDOG_RESET(); +} + +DEBUG_UART_FUNCS + +#endif diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c index 31b43ee88dd..e31c87b9ac5 100644 --- a/drivers/serial/serial_stm32.c +++ b/drivers/serial/serial_stm32.c @@ -7,6 +7,7 @@ #include <common.h> #include <clk.h> #include <dm.h> +#include <reset.h> #include <serial.h> #include <watchdog.h> #include <asm/io.h> @@ -171,6 +172,7 @@ static int stm32_serial_probe(struct udevice *dev) { struct stm32x7_serial_platdata *plat = dev_get_platdata(dev); struct clk clk; + struct reset_ctl reset; int ret; plat->uart_info = (struct stm32_uart_info *)dev_get_driver_data(dev); @@ -185,6 +187,13 @@ static int stm32_serial_probe(struct udevice *dev) return ret; } + ret = reset_get_by_index(dev, 0, &reset); + if (!ret) { + reset_assert(&reset); + udelay(2); + reset_deassert(&reset); + } + plat->clock_rate = clk_get_rate(&clk); if (plat->clock_rate < 0) { clk_disable(&clk); diff --git a/drivers/sound/Kconfig b/drivers/sound/Kconfig index 5de86c05c60..c0d97cca338 100644 --- a/drivers/sound/Kconfig +++ b/drivers/sound/Kconfig @@ -31,6 +31,14 @@ config I2S_SAMSUNG option provides an implementation for sound_init() and sound_play(). +config SOUND_MAX98090 + bool "Support Maxim max98090 audio codec" + depends on I2S_SAMSUNG + help + Enable the max98090 audio codec. This is connected via I2S for + audio data and I2C for codec control. At present it only works + with the Samsung I2S driver. + config SOUND_MAX98095 bool "Support Maxim max98095 audio codec" depends on I2S_SAMSUNG diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile index 696c5aecbe9..1de4346ec7a 100644 --- a/drivers/sound/Makefile +++ b/drivers/sound/Makefile @@ -4,8 +4,12 @@ # R. Chandrasekar <rcsekar@samsung.com> obj-$(CONFIG_SOUND) += sound.o -obj-$(CONFIG_I2S) += sound-i2s.o +obj-$(CONFIG_SOUND) += codec-uclass.o +obj-$(CONFIG_SOUND) += i2s-uclass.o +obj-$(CONFIG_SOUND) += sound-uclass.o obj-$(CONFIG_I2S_SAMSUNG) += samsung-i2s.o obj-$(CONFIG_SOUND_SANDBOX) += sandbox.o +obj-$(CONFIG_I2S_SAMSUNG) += samsung_sound.o obj-$(CONFIG_SOUND_WM8994) += wm8994.o -obj-$(CONFIG_SOUND_MAX98095) += max98095.o +obj-$(CONFIG_SOUND_MAX98090) += max98090.o maxim_codec.o +obj-$(CONFIG_SOUND_MAX98095) += max98095.o maxim_codec.o diff --git a/drivers/sound/codec-uclass.c b/drivers/sound/codec-uclass.c new file mode 100644 index 00000000000..1ec77acfc1c --- /dev/null +++ b/drivers/sound/codec-uclass.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <dm.h> +#include <audio_codec.h> + +int audio_codec_set_params(struct udevice *dev, int interface, int rate, + int mclk_freq, int bits_per_sample, uint channels) +{ + struct audio_codec_ops *ops = audio_codec_get_ops(dev); + + if (!ops->set_params) + return -ENOSYS; + + return ops->set_params(dev, interface, rate, mclk_freq, bits_per_sample, + channels); +} + +UCLASS_DRIVER(audio_codec) = { + .id = UCLASS_AUDIO_CODEC, + .name = "audio-codec", +}; diff --git a/drivers/sound/i2s-uclass.c b/drivers/sound/i2s-uclass.c new file mode 100644 index 00000000000..b741e3952d1 --- /dev/null +++ b/drivers/sound/i2s-uclass.c @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <dm.h> +#include <i2s.h> + +int i2s_tx_data(struct udevice *dev, void *data, uint data_size) +{ + struct i2s_ops *ops = i2s_get_ops(dev); + + if (!ops->tx_data) + return -ENOSYS; + + return ops->tx_data(dev, data, data_size); +} + +UCLASS_DRIVER(i2s) = { + .id = UCLASS_I2S, + .name = "i2s", + .per_device_auto_alloc_size = sizeof(struct i2s_uc_priv), +}; diff --git a/drivers/sound/max98090.c b/drivers/sound/max98090.c new file mode 100644 index 00000000000..346ff5ffbec --- /dev/null +++ b/drivers/sound/max98090.c @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * max98090.c -- MAX98090 ALSA SoC Audio driver + * + * Copyright 2011 Maxim Integrated Products + */ + +#include <common.h> +#include <audio_codec.h> +#include <div64.h> +#include <dm.h> +#include <i2c.h> +#include <i2s.h> +#include <sound.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <asm/arch/clk.h> +#include <asm/arch/cpu.h> +#include <asm/arch/power.h> +#include "maxim_codec.h" +#include "max98090.h" + +/* + * Sets hw params for max98090 + * + * @priv: max98090 information pointer + * @rate: Sampling rate + * @bits_per_sample: Bits per sample + * + * @return -EIO for error, 0 for success. + */ +int max98090_hw_params(struct maxim_priv *priv, unsigned int rate, + unsigned int bits_per_sample) +{ + int error; + unsigned char value; + + switch (bits_per_sample) { + case 16: + maxim_i2c_read(priv, M98090_REG_INTERFACE_FORMAT, &value); + error = maxim_bic_or(priv, M98090_REG_INTERFACE_FORMAT, + M98090_WS_MASK, 0); + maxim_i2c_read(priv, M98090_REG_INTERFACE_FORMAT, &value); + break; + default: + debug("%s: Illegal bits per sample %d.\n", + __func__, bits_per_sample); + return -1; + } + + /* Update filter mode */ + if (rate < 240000) + error |= maxim_bic_or(priv, M98090_REG_FILTER_CONFIG, + M98090_MODE_MASK, 0); + else + error |= maxim_bic_or(priv, M98090_REG_FILTER_CONFIG, + M98090_MODE_MASK, M98090_MODE_MASK); + + /* Update sample rate mode */ + if (rate < 50000) + error |= maxim_bic_or(priv, M98090_REG_FILTER_CONFIG, + M98090_DHF_MASK, 0); + else + error |= maxim_bic_or(priv, M98090_REG_FILTER_CONFIG, + M98090_DHF_MASK, M98090_DHF_MASK); + + if (error < 0) { + debug("%s: Error setting hardware params.\n", __func__); + return -EIO; + } + priv->rate = rate; + + return 0; +} + +/* + * Configures Audio interface system clock for the given frequency + * + * @priv: max98090 information + * @freq: Sampling frequency in Hz + * + * @return -EIO for error, 0 for success. + */ +int max98090_set_sysclk(struct maxim_priv *priv, unsigned int freq) +{ + int error = 0; + + /* Requested clock frequency is already setup */ + if (freq == priv->sysclk) + return 0; + + /* Setup clocks for slave mode, and using the PLL + * PSCLK = 0x01 (when master clk is 10MHz to 20MHz) + * 0x02 (when master clk is 20MHz to 40MHz).. + * 0x03 (when master clk is 40MHz to 60MHz).. + */ + if (freq >= 10000000 && freq < 20000000) { + error = maxim_i2c_write(priv, M98090_REG_SYSTEM_CLOCK, + M98090_PSCLK_DIV1); + } else if (freq >= 20000000 && freq < 40000000) { + error = maxim_i2c_write(priv, M98090_REG_SYSTEM_CLOCK, + M98090_PSCLK_DIV2); + } else if (freq >= 40000000 && freq < 60000000) { + error = maxim_i2c_write(priv, M98090_REG_SYSTEM_CLOCK, + M98090_PSCLK_DIV4); + } else { + debug("%s: Invalid master clock frequency\n", __func__); + return -1; + } + + debug("%s: Clock at %uHz\n", __func__, freq); + + if (error < 0) + return -1; + + priv->sysclk = freq; + + return 0; +} + +/* + * Sets Max98090 I2S format + * + * @priv: max98090 information + * @fmt: i2S format - supports a subset of the options defined in i2s.h. + * + * @return -EIO for error, 0 for success. + */ +int max98090_set_fmt(struct maxim_priv *priv, int fmt) +{ + u8 regval = 0; + int error = 0; + + if (fmt == priv->fmt) + return 0; + + priv->fmt = fmt; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* Set to slave mode PLL - MAS mode off */ + error |= maxim_i2c_write(priv, M98090_REG_CLOCK_RATIO_NI_MSB, + 0x00); + error |= maxim_i2c_write(priv, M98090_REG_CLOCK_RATIO_NI_LSB, + 0x00); + error |= maxim_bic_or(priv, M98090_REG_CLOCK_MODE, + M98090_USE_M1_MASK, 0); + break; + case SND_SOC_DAIFMT_CBM_CFM: + /* Set to master mode */ + debug("Master mode not supported\n"); + break; + case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBM_CFS: + default: + debug("%s: Clock mode unsupported\n", __func__); + return -EINVAL; + } + + error |= maxim_i2c_write(priv, M98090_REG_MASTER_MODE, regval); + + regval = 0; + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + regval |= M98090_DLY_MASK; + break; + case SND_SOC_DAIFMT_LEFT_J: + break; + case SND_SOC_DAIFMT_RIGHT_J: + regval |= M98090_RJ_MASK; + break; + case SND_SOC_DAIFMT_DSP_A: + /* Not supported mode */ + default: + debug("%s: Unrecognized format.\n", __func__); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_NB_IF: + regval |= M98090_WCI_MASK; + break; + case SND_SOC_DAIFMT_IB_NF: + regval |= M98090_BCI_MASK; + break; + case SND_SOC_DAIFMT_IB_IF: + regval |= M98090_BCI_MASK | M98090_WCI_MASK; + break; + default: + debug("%s: Unrecognized inversion settings.\n", __func__); + return -EINVAL; + } + + error |= maxim_i2c_write(priv, M98090_REG_INTERFACE_FORMAT, regval); + + if (error < 0) { + debug("%s: Error setting i2s format.\n", __func__); + return -EIO; + } + + return 0; +} + +/* + * resets the audio codec + * + * @priv: max98090 information + * @return -EIO for error, 0 for success. + */ +static int max98090_reset(struct maxim_priv *priv) +{ + int ret; + + /* + * Gracefully reset the DSP core and the codec hardware in a proper + * sequence. + */ + ret = maxim_i2c_write(priv, M98090_REG_SOFTWARE_RESET, + M98090_SWRESET_MASK); + if (ret != 0) { + debug("%s: Failed to reset DSP: %d\n", __func__, ret); + return ret; + } + mdelay(20); + + return 0; +} + +/* + * Initialise max98090 codec device + * + * @priv: max98090 information + * + * @return -EIO for error, 0 for success. + */ +int max98090_device_init(struct maxim_priv *priv) +{ + unsigned char id; + int error = 0; + + /* Enable codec clock */ + set_xclkout(); + + /* reset the codec, the DSP core, and disable all interrupts */ + error = max98090_reset(priv); + if (error != 0) { + debug("Reset\n"); + return error; + } + + /* initialize private data */ + priv->sysclk = -1U; + priv->rate = -1U; + priv->fmt = -1U; + + error = maxim_i2c_read(priv, M98090_REG_REVISION_ID, &id); + if (error < 0) { + debug("%s: Failure reading hardware revision: %d\n", + __func__, id); + return -EIO; + } + debug("%s: Hardware revision: %d\n", __func__, id); + + return 0; +} + +static int max98090_setup_interface(struct maxim_priv *priv) +{ + unsigned char id; + int error; + + /* Reading interrupt status to clear them */ + error = maxim_i2c_read(priv, M98090_REG_DEVICE_STATUS, &id); + + error |= maxim_i2c_write(priv, M98090_REG_DAC_CONTROL, + M98090_DACHP_MASK); + error |= maxim_i2c_write(priv, M98090_REG_BIAS_CONTROL, + M98090_VCM_MODE_MASK); + + error |= maxim_i2c_write(priv, M98090_REG_LEFT_SPK_MIXER, 0x1); + error |= maxim_i2c_write(priv, M98090_REG_RIGHT_SPK_MIXER, 0x2); + + error |= maxim_i2c_write(priv, M98090_REG_LEFT_SPK_VOLUME, 0x25); + error |= maxim_i2c_write(priv, M98090_REG_RIGHT_SPK_VOLUME, 0x25); + + error |= maxim_i2c_write(priv, M98090_REG_CLOCK_RATIO_NI_MSB, 0x0); + error |= maxim_i2c_write(priv, M98090_REG_CLOCK_RATIO_NI_LSB, 0x0); + error |= maxim_i2c_write(priv, M98090_REG_MASTER_MODE, 0x0); + error |= maxim_i2c_write(priv, M98090_REG_INTERFACE_FORMAT, 0x0); + error |= maxim_i2c_write(priv, M98090_REG_IO_CONFIGURATION, + M98090_SDIEN_MASK); + error |= maxim_i2c_write(priv, M98090_REG_DEVICE_SHUTDOWN, + M98090_SHDNN_MASK); + error |= maxim_i2c_write(priv, M98090_REG_OUTPUT_ENABLE, + M98090_HPREN_MASK | M98090_HPLEN_MASK | + M98090_SPREN_MASK | M98090_SPLEN_MASK | + M98090_DAREN_MASK | M98090_DALEN_MASK); + error |= maxim_i2c_write(priv, M98090_REG_IO_CONFIGURATION, + M98090_SDOEN_MASK | M98090_SDIEN_MASK); + + if (error < 0) + return -EIO; + + return 0; +} + +static int max98090_do_init(struct maxim_priv *priv, int sampling_rate, + int mclk_freq, int bits_per_sample) +{ + int ret = 0; + + ret = max98090_setup_interface(priv); + if (ret < 0) { + debug("%s: max98090 setup interface failed\n", __func__); + return ret; + } + + ret = max98090_set_sysclk(priv, mclk_freq); + if (ret < 0) { + debug("%s: max98090 codec set sys clock failed\n", __func__); + return ret; + } + + ret = max98090_hw_params(priv, sampling_rate, bits_per_sample); + + if (ret == 0) { + ret = max98090_set_fmt(priv, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS); + } + + return ret; +} + +static int max98090_set_params(struct udevice *dev, int interface, int rate, + int mclk_freq, int bits_per_sample, + uint channels) +{ + struct maxim_priv *priv = dev_get_priv(dev); + + return max98090_do_init(priv, rate, mclk_freq, bits_per_sample); +} + +static int max98090_probe(struct udevice *dev) +{ + struct maxim_priv *priv = dev_get_priv(dev); + int ret; + + priv->dev = dev; + ret = max98090_device_init(priv); + if (ret < 0) { + debug("%s: max98090 codec chip init failed\n", __func__); + return ret; + } + + return 0; +} + +static const struct audio_codec_ops max98090_ops = { + .set_params = max98090_set_params, +}; + +static const struct udevice_id max98090_ids[] = { + { .compatible = "maxim,max98090" }, + { } +}; + +U_BOOT_DRIVER(max98090) = { + .name = "max98090", + .id = UCLASS_AUDIO_CODEC, + .of_match = max98090_ids, + .probe = max98090_probe, + .ops = &max98090_ops, + .priv_auto_alloc_size = sizeof(struct maxim_priv), +}; diff --git a/drivers/sound/max98090.h b/drivers/sound/max98090.h new file mode 100644 index 00000000000..3a6983b8e2c --- /dev/null +++ b/drivers/sound/max98090.h @@ -0,0 +1,663 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * max98090.h -- MAX98090 ALSA SoC Audio driver + * + * Copyright 2011 Maxim Integrated Products + */ + +#ifndef _MAX98090_H +#define _MAX98090_H + +#include "maxim_codec.h" + +/* MAX98090 Registers Definition */ + +#define M98090_REG_SOFTWARE_RESET 0x00 +#define M98090_REG_DEVICE_STATUS 0x01 + +#define M98090_REG_QUICK_SAMPLE_RATE 0x05 +#define M98090_REG_DAI_INTERFACE 0x06 +#define M98090_REG_DAC_PATH 0x07 + +#define M98090_REG_MIC_BIAS_VOLTAGE 0x12 +#define M98090_REG_DIGITAL_MIC_ENABLE 0x13 +#define M98090_REG_DIGITAL_MIC_CONFIG 0x14 +#define M98090_REG_SYSTEM_CLOCK 0x1B +#define M98090_REG_CLOCK_RATIO_NI_MSB 0x1D +#define M98090_REG_CLOCK_MODE 0x1C +#define M98090_REG_CLOCK_RATIO_NI_LSB 0x1E + +#define M98090_REG_MASTER_MODE 0x21 +#define M98090_REG_INTERFACE_FORMAT 0x22 +#define M98090_REG_IO_CONFIGURATION 0x25 +#define M98090_REG_FILTER_CONFIG 0x26 + +#define M98090_REG_LEFT_HP_MIXER 0x29 +#define M98090_REG_RIGHT_HP_MIXER 0x2a +#define M98090_REG_HP_CONTROL 0x2b +#define M98090_REG_LEFT_HP_VOLUME 0x2c +#define M98090_REG_RIGHT_HP_VOLUME 0x2d +#define M98090_REG_LEFT_SPK_MIXER 0x2e +#define M98090_REG_RIGHT_SPK_MIXER 0x2f +#define M98090_REG_SPK_CONTROL 0x30 +#define M98090_REG_LEFT_SPK_VOLUME 0x31 +#define M98090_REG_RIGHT_SPK_VOLUME 0x32 + +#define M98090_REG_RCV_LOUTL_CONTROL 0x38 +#define M98090_REG_RCV_LOUTL_VOLUME 0x39 +#define M98090_REG_LOUTR_MIXER 0x3a +#define M98090_REG_LOUTR_CONTROL 0x3b +#define M98090_REG_LOUTR_VOLUME 0x3c +#define M98090_REG_JACK_DETECT 0x3d +#define M98090_REG_INPUT_ENABLE 0x3e +#define M98090_REG_OUTPUT_ENABLE 0x3f +#define M98090_REG_LEVEL_CONTROL 0x40 +#define M98090_REG_DSP_FILTER_ENABLE 0x41 +#define M98090_REG_BIAS_CONTROL 0x42 +#define M98090_REG_DAC_CONTROL 0x43 +#define M98090_REG_ADC_CONTROL 0x44 +#define M98090_REG_DEVICE_SHUTDOWN 0x45 + +#define M98090_REG_REVISION_ID 0xff + +#define M98090_REG_CNT (0xff + 1) +#define M98090_REG_MAX_CACHed 0x45 + +/* MAX98090 Registers Bit Fields */ + +/* + * M98090_REG_SOFTWARE_RESET 0x00 + */ +#define M98090_SWRESET_MASK BIT(7) + +/* + * M98090_REG_QUICK_SAMPLE_RATE 0x05 + */ +#define M98090_SR_96K_MASK BIT(5) +#define M98090_SR_96K_SHIFT 5 +#define M98090_SR_96K_WIDTH 1 +#define M98090_SR_32K_MASK BIT(4) +#define M98090_SR_32K_SHIFT 4 +#define M98090_SR_32K_WIDTH 1 +#define M98090_SR_48K_MASK BIT(3) +#define M98090_SR_48K_SHIFT 3 +#define M98090_SR_48K_WIDTH 1 +#define M98090_SR_44K1_MASK BIT(2) +#define M98090_SR_44K1_SHIFT 2 +#define M98090_SR_44K1_WIDTH 1 +#define M98090_SR_16K_MASK BIT(1) +#define M98090_SR_16K_SHIFT 1 +#define M98090_SR_16K_WIDTH 1 +#define M98090_SR_8K_MASK BIT(0) +#define M98090_SR_8K_SHIFT 0 +#define M98090_SR_8K_WIDTH 1 +#define M98090_SR_MASK 0x3F +#define M98090_SR_ALL_SHIFT 0 +#define M98090_SR_ALL_WIDTH 8 +#define M98090_SR_ALL_NUM BIT(M98090_SR_ALL_WIDTH) + +/* + * M98090_REG_DAI_INTERFACE 0x06 + */ +#define M98090_RJ_M_MASK BIT(5) +#define M98090_RJ_M_SHIFT 5 +#define M98090_RJ_M_WIDTH 1 +#define M98090_RJ_S_MASK BIT(4) +#define M98090_RJ_S_SHIFT 4 +#define M98090_RJ_S_WIDTH 1 +#define M98090_LJ_M_MASK BIT(3) +#define M98090_LJ_M_SHIFT 3 +#define M98090_LJ_M_WIDTH 1 +#define M98090_LJ_S_MASK BIT(2) +#define M98090_LJ_S_SHIFT 2 +#define M98090_LJ_S_WIDTH 1 +#define M98090_I2S_M_MASK BIT(1) +#define M98090_I2S_M_SHIFT 1 +#define M98090_I2S_M_WIDTH 1 +#define M98090_I2S_S_MASK BIT(0) +#define M98090_I2S_S_SHIFT 0 +#define M98090_I2S_S_WIDTH 1 +#define M98090_DAI_ALL_SHIFT 0 +#define M98090_DAI_ALL_WIDTH 8 +#define M98090_DAI_ALL_NUM BIT(M98090_DAI_ALL_WIDTH) + +/* + * M98090_REG_DAC_PATH 0x07 + */ +#define M98090_DIG2_HP_MASK BIT(7) +#define M98090_DIG2_HP_SHIFT 7 +#define M98090_DIG2_HP_WIDTH 1 +#define M98090_DIG2_EAR_MASK BIT(6) +#define M98090_DIG2_EAR_SHIFT 6 +#define M98090_DIG2_EAR_WIDTH 1 +#define M98090_DIG2_SPK_MASK BIT(5) +#define M98090_DIG2_SPK_SHIFT 5 +#define M98090_DIG2_SPK_WIDTH 1 +#define M98090_DIG2_LOUT_MASK BIT(4) +#define M98090_DIG2_LOUT_SHIFT 4 +#define M98090_DIG2_LOUT_WIDTH 1 +#define M98090_DIG2_ALL_SHIFT 0 +#define M98090_DIG2_ALL_WIDTH 8 +#define M98090_DIG2_ALL_NUM BIT(M98090_DIG2_ALL_WIDTH) + +/* + * M98090_REG_MIC_BIAS_VOLTAGE 0x12 + */ +#define M98090_MBVSEL_MASK (3 << 0) +#define M98090_MBVSEL_SHIFT 0 +#define M98090_MBVSEL_WIDTH 2 +#define M98090_MBVSEL_2V8 (3 << 0) +#define M98090_MBVSEL_2V55 (2 << 0) +#define M98090_MBVSEL_2V4 BIT(0) +#define M98090_MBVSEL_2V2 (0 << 0) + +/* + * M98090_REG_DIGITAL_MIC_ENABLE 0x13 + */ +#define M98090_MICCLK_MASK (7 << 4) +#define M98090_MICCLK_SHIFT 4 +#define M98090_MICCLK_WIDTH 3 +#define M98090_DIGMIC4_MASK BIT(3) +#define M98090_DIGMIC4_SHIFT 3 +#define M98090_DIGMIC4_WIDTH 1 +#define M98090_DIGMIC4_NUM BIT(M98090_DIGMIC4_WIDTH) +#define M98090_DIGMIC3_MASK BIT(2) +#define M98090_DIGMIC3_SHIFT 2 +#define M98090_DIGMIC3_WIDTH 1 +#define M98090_DIGMIC3_NUM BIT(M98090_DIGMIC3_WIDTH) +#define M98090_DIGMICR_MASK BIT(1) +#define M98090_DIGMICR_SHIFT 1 +#define M98090_DIGMICR_WIDTH 1 +#define M98090_DIGMICR_NUM BIT(M98090_DIGMICR_WIDTH) +#define M98090_DIGMICL_MASK BIT(0) +#define M98090_DIGMICL_SHIFT 0 +#define M98090_DIGMICL_WIDTH 1 +#define M98090_DIGMICL_NUM BIT(M98090_DIGMICL_WIDTH) + +/* + * M98090_REG_DIGITAL_MIC_CONFIG 0x14 + */ +#define M98090_DMIC_COMP_MASK (15 << 4) +#define M98090_DMIC_COMP_SHIFT 4 +#define M98090_DMIC_COMP_WIDTH 4 +#define M98090_DMIC_COMP_NUM BIT(M98090_DMIC_COMP_WIDTH) +#define M98090_DMIC_FREQ_MASK (3 << 0) +#define M98090_DMIC_FREQ_SHIFT 0 +#define M98090_DMIC_FREQ_WIDTH 2 + +/* + * M98090_REG_CLOCK_MODE 0x1B + */ +#define M98090_PSCLK_MASK (3 << 4) +#define M98090_PSCLK_SHIFT 4 +#define M98090_PSCLK_WIDTH 2 +#define M98090_PSCLK_DISABLED (0 << 4) +#define M98090_PSCLK_DIV1 BIT(4) +#define M98090_PSCLK_DIV2 (2 << 4) +#define M98090_PSCLK_DIV4 (3 << 4) + +/* + * M98090_REG_INTERFACE_FORMAT 0x22 + */ +#define M98090_RJ_MASK BIT(5) +#define M98090_RJ_SHIFT 5 +#define M98090_RJ_WIDTH 1 +#define M98090_WCI_MASK BIT(4) +#define M98090_WCI_SHIFT 4 +#define M98090_WCI_WIDTH 1 +#define M98090_BCI_MASK BIT(3) +#define M98090_BCI_SHIFT 3 +#define M98090_BCI_WIDTH 1 +#define M98090_DLY_MASK BIT(2) +#define M98090_DLY_SHIFT 2 +#define M98090_DLY_WIDTH 1 +#define M98090_WS_MASK (3 << 0) +#define M98090_WS_SHIFT 0 +#define M98090_WS_WIDTH 2 +#define M98090_WS_NUM BIT(M98090_WS_WIDTH) + +/* M98090_REG_IO_CONFIGURATION 0x25 */ +#define M98090_LTEN_MASK BIT(5) +#define M98090_LTEN_SHIFT 5 +#define M98090_LTEN_WIDTH 1 +#define M98090_LTEN_NUM BIT(M98090_LTEN_WIDTH) +#define M98090_LBEN_MASK BIT(4) +#define M98090_LBEN_SHIFT 4 +#define M98090_LBEN_WIDTH 1 +#define M98090_LBEN_NUM BIT(M98090_LBEN_WIDTH) +#define M98090_DMONO_MASK BIT(3) +#define M98090_DMONO_SHIFT 3 +#define M98090_DMONO_WIDTH 1 +#define M98090_DMONO_NUM BIT(M98090_DMONO_WIDTH) +#define M98090_HIZOFF_MASK BIT(2) +#define M98090_HIZOFF_SHIFT 2 +#define M98090_HIZOFF_WIDTH 1 +#define M98090_HIZOFF_NUM BIT(M98090_HIZOFF_WIDTH) +#define M98090_SDOEN_MASK BIT(1) +#define M98090_SDOEN_SHIFT 1 +#define M98090_SDOEN_WIDTH 1 +#define M98090_SDOEN_NUM BIT(M98090_SDOEN_WIDTH) +#define M98090_SDIEN_MASK BIT(0) +#define M98090_SDIEN_SHIFT 0 +#define M98090_SDIEN_WIDTH 1 +#define M98090_SDIEN_NUM BIT(M98090_SDIEN_WIDTH) + +/* + * M98090_REG_FILTER_CONFIG 0x26 + */ +#define M98090_MODE_MASK BIT(7) +#define M98090_MODE_SHIFT 7 +#define M98090_MODE_WIDTH 1 +#define M98090_AHPF_MASK BIT(6) +#define M98090_AHPF_SHIFT 6 +#define M98090_AHPF_WIDTH 1 +#define M98090_AHPF_NUM BIT(M98090_AHPF_WIDTH) +#define M98090_DHPF_MASK BIT(5) +#define M98090_DHPF_SHIFT 5 +#define M98090_DHPF_WIDTH 1 +#define M98090_DHPF_NUM BIT(M98090_DHPF_WIDTH) +#define M98090_DHF_MASK BIT(4) +#define M98090_DHF_SHIFT 4 +#define M98090_DHF_WIDTH 1 +#define M98090_FLT_DMIC34MODE_MASK BIT(3) +#define M98090_FLT_DMIC34MODE_SHIFT 3 +#define M98090_FLT_DMIC34MODE_WIDTH 1 +#define M98090_FLT_DMIC34HPF_MASK BIT(2) +#define M98090_FLT_DMIC34HPF_SHIFT 2 +#define M98090_FLT_DMIC34HPF_WIDTH 1 +#define M98090_FLT_DMIC34HPF_NUM BIT(M98090_FLT_DMIC34HPF_WIDTH) + +/* + * M98090_REG_CLOCK_MODE + */ +#define M98090_FREQ_MASK (15 << 4) +#define M98090_FREQ_SHIFT 4 +#define M98090_FREQ_WIDTH 4 +#define M98090_USE_M1_MASK BIT(0) +#define M98090_USE_M1_SHIFT 0 +#define M98090_USE_M1_WIDTH 1 +#define M98090_USE_M1_NUM BIT(M98090_USE_M1_WIDTH) + +/* + * M98090_REG_LEFT_HP_MIXER 0x29 + */ +#define M98090_MIXHPL_MIC2_MASK BIT(5) +#define M98090_MIXHPL_MIC2_SHIFT 5 +#define M98090_MIXHPL_MIC2_WIDTH 1 +#define M98090_MIXHPL_MIC1_MASK BIT(4) +#define M98090_MIXHPL_MIC1_SHIFT 4 +#define M98090_MIXHPL_MIC1_WIDTH 1 +#define M98090_MIXHPL_LINEB_MASK BIT(3) +#define M98090_MIXHPL_LINEB_SHIFT 3 +#define M98090_MIXHPL_LINEB_WIDTH 1 +#define M98090_MIXHPL_LINEA_MASK BIT(2) +#define M98090_MIXHPL_LINEA_SHIFT 2 +#define M98090_MIXHPL_LINEA_WIDTH 1 +#define M98090_MIXHPL_DACR_MASK BIT(1) +#define M98090_MIXHPL_DACR_SHIFT 1 +#define M98090_MIXHPL_DACR_WIDTH 1 +#define M98090_MIXHPL_DACL_MASK BIT(0) +#define M98090_MIXHPL_DACL_SHIFT 0 +#define M98090_MIXHPL_DACL_WIDTH 1 +#define M98090_MIXHPL_MASK (63 << 0) +#define M98090_MIXHPL_SHIFT 0 +#define M98090_MIXHPL_WIDTH 6 + +/* + * M98090_REG_RIGHT_HP_MIXER 0x2A + */ +#define M98090_MIXHPR_MIC2_MASK BIT(5) +#define M98090_MIXHPR_MIC2_SHIFT 5 +#define M98090_MIXHPR_MIC2_WIDTH 1 +#define M98090_MIXHPR_MIC1_MASK BIT(4) +#define M98090_MIXHPR_MIC1_SHIFT 4 +#define M98090_MIXHPR_MIC1_WIDTH 1 +#define M98090_MIXHPR_LINEB_MASK BIT(3) +#define M98090_MIXHPR_LINEB_SHIFT 3 +#define M98090_MIXHPR_LINEB_WIDTH 1 +#define M98090_MIXHPR_LINEA_MASK BIT(2) +#define M98090_MIXHPR_LINEA_SHIFT 2 +#define M98090_MIXHPR_LINEA_WIDTH 1 +#define M98090_MIXHPR_DACR_MASK BIT(1) +#define M98090_MIXHPR_DACR_SHIFT 1 +#define M98090_MIXHPR_DACR_WIDTH 1 +#define M98090_MIXHPR_DACL_MASK BIT(0) +#define M98090_MIXHPR_DACL_SHIFT 0 +#define M98090_MIXHPR_DACL_WIDTH 1 +#define M98090_MIXHPR_MASK (63 << 0) +#define M98090_MIXHPR_SHIFT 0 +#define M98090_MIXHPR_WIDTH 6 + +/* + * M98090_REG_LEFT_HP_VOLUME 0x2C + */ +#define M98090_HPLM_MASK BIT(7) +#define M98090_HPLM_SHIFT 7 +#define M98090_HPLM_WIDTH 1 +#define M98090_HPVOLL_MASK (31 << 0) +#define M98090_HPVOLL_SHIFT 0 +#define M98090_HPVOLL_WIDTH 5 +#define M98090_HPVOLL_NUM BIT(M98090_HPVOLL_WIDTH) + +/* + * M98090_REG_RIGHT_HP_VOLUME 0x2D + */ +#define M98090_HPRM_MASK BIT(7) +#define M98090_HPRM_SHIFT 7 +#define M98090_HPRM_WIDTH 1 +#define M98090_HPVOLR_MASK (31 << 0) +#define M98090_HPVOLR_SHIFT 0 +#define M98090_HPVOLR_WIDTH 5 +#define M98090_HPVOLR_NUM BIT(M98090_HPVOLR_WIDTH) + +/* + * M98090_REG_LEFT_SPK_MIXER 0x2E + */ +#define M98090_MIXSPL_MIC2_MASK BIT(5) +#define M98090_MIXSPL_MIC2_SHIFT 5 +#define M98090_MIXSPL_MIC2_WIDTH 1 +#define M98090_MIXSPL_MIC1_MASK BIT(4) +#define M98090_MIXSPL_MIC1_SHIFT 4 +#define M98090_MIXSPL_MIC1_WIDTH 1 +#define M98090_MIXSPL_LINEB_MASK BIT(3) +#define M98090_MIXSPL_LINEB_SHIFT 3 +#define M98090_MIXSPL_LINEB_WIDTH 1 +#define M98090_MIXSPL_LINEA_MASK BIT(2) +#define M98090_MIXSPL_LINEA_SHIFT 2 +#define M98090_MIXSPL_LINEA_WIDTH 1 +#define M98090_MIXSPL_DACR_MASK BIT(1) +#define M98090_MIXSPL_DACR_SHIFT 1 +#define M98090_MIXSPL_DACR_WIDTH 1 +#define M98090_MIXSPL_DACL_MASK BIT(0) +#define M98090_MIXSPL_DACL_SHIFT 0 +#define M98090_MIXSPL_DACL_WIDTH 1 +#define M98090_MIXSPL_MASK (63 << 0) +#define M98090_MIXSPL_SHIFT 0 +#define M98090_MIXSPL_WIDTH 6 +#define M98090_MIXSPR_DACR_MASK BIT(1) +#define M98090_MIXSPR_DACR_SHIFT 1 +#define M98090_MIXSPR_DACR_WIDTH 1 + +/* + * M98090_REG_RIGHT_SPK_MIXER 0x2F + */ +#define M98090_SPK_SLAVE_MASK BIT(6) +#define M98090_SPK_SLAVE_SHIFT 6 +#define M98090_SPK_SLAVE_WIDTH 1 +#define M98090_MIXSPR_MIC2_MASK BIT(5) +#define M98090_MIXSPR_MIC2_SHIFT 5 +#define M98090_MIXSPR_MIC2_WIDTH 1 +#define M98090_MIXSPR_MIC1_MASK BIT(4) +#define M98090_MIXSPR_MIC1_SHIFT 4 +#define M98090_MIXSPR_MIC1_WIDTH 1 +#define M98090_MIXSPR_LINEB_MASK BIT(3) +#define M98090_MIXSPR_LINEB_SHIFT 3 +#define M98090_MIXSPR_LINEB_WIDTH 1 +#define M98090_MIXSPR_LINEA_MASK BIT(2) +#define M98090_MIXSPR_LINEA_SHIFT 2 +#define M98090_MIXSPR_LINEA_WIDTH 1 +#define M98090_MIXSPR_DACR_MASK BIT(1) +#define M98090_MIXSPR_DACR_SHIFT 1 +#define M98090_MIXSPR_DACR_WIDTH 1 +#define M98090_MIXSPR_DACL_MASK BIT(0) +#define M98090_MIXSPR_DACL_SHIFT 0 +#define M98090_MIXSPR_DACL_WIDTH 1 +#define M98090_MIXSPR_MASK (63 << 0) +#define M98090_MIXSPR_SHIFT 0 +#define M98090_MIXSPR_WIDTH 6 + +/* + * M98090_REG_LEFT_SPK_VOLUME 0x31 + */ +#define M98090_SPLM_MASK BIT(7) +#define M98090_SPLM_SHIFT 7 +#define M98090_SPLM_WIDTH 1 +#define M98090_SPVOLL_MASK (63 << 0) +#define M98090_SPVOLL_SHIFT 0 +#define M98090_SPVOLL_WIDTH 6 +#define M98090_SPVOLL_NUM 40 + +/* + * M98090_REG_RIGHT_SPK_VOLUME 0x32 + */ +#define M98090_SPRM_MASK BIT(7) +#define M98090_SPRM_SHIFT 7 +#define M98090_SPRM_WIDTH 1 +#define M98090_SPVOLR_MASK (63 << 0) +#define M98090_SPVOLR_SHIFT 0 +#define M98090_SPVOLR_WIDTH 6 +#define M98090_SPVOLR_NUM 40 + +/* + * M98090_REG_RCV_LOUTL_MIXER 0x37 + */ +#define M98090_MIXRCVL_MIC2_MASK BIT(5) +#define M98090_MIXRCVL_MIC2_SHIFT 5 +#define M98090_MIXRCVL_MIC2_WIDTH 1 +#define M98090_MIXRCVL_MIC1_MASK BIT(4) +#define M98090_MIXRCVL_MIC1_SHIFT 4 +#define M98090_MIXRCVL_MIC1_WIDTH 1 +#define M98090_MIXRCVL_LINEB_MASK BIT(3) +#define M98090_MIXRCVL_LINEB_SHIFT 3 +#define M98090_MIXRCVL_LINEB_WIDTH 1 +#define M98090_MIXRCVL_LINEA_MASK BIT(2) +#define M98090_MIXRCVL_LINEA_SHIFT 2 +#define M98090_MIXRCVL_LINEA_WIDTH 1 +#define M98090_MIXRCVL_DACR_MASK BIT(1) +#define M98090_MIXRCVL_DACR_SHIFT 1 +#define M98090_MIXRCVL_DACR_WIDTH 1 +#define M98090_MIXRCVL_DACL_MASK BIT(0) +#define M98090_MIXRCVL_DACL_SHIFT 0 +#define M98090_MIXRCVL_DACL_WIDTH 1 +#define M98090_MIXRCVL_MASK (63 << 0) +#define M98090_MIXRCVL_SHIFT 0 +#define M98090_MIXRCVL_WIDTH 6 + +/* + * M98090_REG_RCV_LOUTL_CONTROL 0x38 + */ +#define M98090_MIXRCVLG_MASK (3 << 0) +#define M98090_MIXRCVLG_SHIFT 0 +#define M98090_MIXRCVLG_WIDTH 2 +#define M98090_MIXRCVLG_NUM BIT(M98090_MIXRCVLG_WIDTH) + +/* + * M98090_REG_RCV_LOUTL_VOLUME 0x39 + */ +#define M98090_RCVLM_MASK BIT(7) +#define M98090_RCVLM_SHIFT 7 +#define M98090_RCVLM_WIDTH 1 +#define M98090_RCVLVOL_MASK (31 << 0) +#define M98090_RCVLVOL_SHIFT 0 +#define M98090_RCVLVOL_WIDTH 5 +#define M98090_RCVLVOL_NUM BIT(M98090_RCVLVOL_WIDTH) + +/* + * M98090_REG_LOUTR_MIXER 0x3A + */ +#define M98090_LINMOD_MASK BIT(7) +#define M98090_LINMOD_SHIFT 7 +#define M98090_LINMOD_WIDTH 1 +#define M98090_MIXRCVR_MIC2_MASK BIT(5) +#define M98090_MIXRCVR_MIC2_SHIFT 5 +#define M98090_MIXRCVR_MIC2_WIDTH 1 +#define M98090_MIXRCVR_MIC1_MASK BIT(4) +#define M98090_MIXRCVR_MIC1_SHIFT 4 +#define M98090_MIXRCVR_MIC1_WIDTH 1 +#define M98090_MIXRCVR_LINEB_MASK BIT(3) +#define M98090_MIXRCVR_LINEB_SHIFT 3 +#define M98090_MIXRCVR_LINEB_WIDTH 1 +#define M98090_MIXRCVR_LINEA_MASK BIT(2) +#define M98090_MIXRCVR_LINEA_SHIFT 2 +#define M98090_MIXRCVR_LINEA_WIDTH 1 +#define M98090_MIXRCVR_DACR_MASK BIT(1) +#define M98090_MIXRCVR_DACR_SHIFT 1 +#define M98090_MIXRCVR_DACR_WIDTH 1 +#define M98090_MIXRCVR_DACL_MASK BIT(0) +#define M98090_MIXRCVR_DACL_SHIFT 0 +#define M98090_MIXRCVR_DACL_WIDTH 1 +#define M98090_MIXRCVR_MASK (63 << 0) +#define M98090_MIXRCVR_SHIFT 0 +#define M98090_MIXRCVR_WIDTH 6 + +/* + * M98090_REG_LOUTR_VOLUME 0x3C + */ +#define M98090_RCVRM_MASK BIT(7) +#define M98090_RCVRM_SHIFT 7 +#define M98090_RCVRM_WIDTH 1 +#define M98090_RCVRVOL_MASK (31 << 0) +#define M98090_RCVRVOL_SHIFT 0 +#define M98090_RCVRVOL_WIDTH 5 +#define M98090_RCVRVOL_NUM BIT(M98090_RCVRVOL_WIDTH) + +/* + * M98090_REG_JACK_DETECT 0x3D + */ +#define M98090_JDETEN_MASK BIT(7) +#define M98090_JDETEN_SHIFT 7 +#define M98090_JDETEN_WIDTH 1 +#define M98090_JDWK_MASK BIT(6) +#define M98090_JDWK_SHIFT 6 +#define M98090_JDWK_WIDTH 1 +#define M98090_JDEB_MASK (3 << 0) +#define M98090_JDEB_SHIFT 0 +#define M98090_JDEB_WIDTH 2 +#define M98090_JDEB_25MS (0 << 0) +#define M98090_JDEB_50MS BIT(0) +#define M98090_JDEB_100MS (2 << 0) +#define M98090_JDEB_200MS (3 << 0) + +/* + * M98090_REG_INPUT_ENABLE 0x3E + */ +#define M98090_MBEN_MASK BIT(4) +#define M98090_MBEN_SHIFT 4 +#define M98090_MBEN_WIDTH 1 +#define M98090_LINEAEN_MASK BIT(3) +#define M98090_LINEAEN_SHIFT 3 +#define M98090_LINEAEN_WIDTH 1 +#define M98090_LINEBEN_MASK BIT(2) +#define M98090_LINEBEN_SHIFT 2 +#define M98090_LINEBEN_WIDTH 1 +#define M98090_ADREN_MASK BIT(1) +#define M98090_ADREN_SHIFT 1 +#define M98090_ADREN_WIDTH 1 +#define M98090_ADLEN_MASK BIT(0) +#define M98090_ADLEN_SHIFT 0 +#define M98090_ADLEN_WIDTH 1 + +/* + * M98090_REG_OUTPUT_ENABLE 0x3F + */ +#define M98090_HPREN_MASK BIT(7) +#define M98090_HPREN_SHIFT 7 +#define M98090_HPREN_WIDTH 1 +#define M98090_HPLEN_MASK BIT(6) +#define M98090_HPLEN_SHIFT 6 +#define M98090_HPLEN_WIDTH 1 +#define M98090_SPREN_MASK BIT(5) +#define M98090_SPREN_SHIFT 5 +#define M98090_SPREN_WIDTH 1 +#define M98090_SPLEN_MASK BIT(4) +#define M98090_SPLEN_SHIFT 4 +#define M98090_SPLEN_WIDTH 1 +#define M98090_RCVLEN_MASK BIT(3) +#define M98090_RCVLEN_SHIFT 3 +#define M98090_RCVLEN_WIDTH 1 +#define M98090_RCVREN_MASK BIT(2) +#define M98090_RCVREN_SHIFT 2 +#define M98090_RCVREN_WIDTH 1 +#define M98090_DAREN_MASK BIT(1) +#define M98090_DAREN_SHIFT 1 +#define M98090_DAREN_WIDTH 1 +#define M98090_DALEN_MASK BIT(0) +#define M98090_DALEN_SHIFT 0 +#define M98090_DALEN_WIDTH 1 + +/* + * M98090_REG_LEVEL_CONTROL 0x40 + */ +#define M98090_ZDENN_MASK BIT(2) +#define M98090_ZDENN_SHIFT 2 +#define M98090_ZDENN_WIDTH 1 +#define M98090_ZDENN_NUM BIT(M98090_ZDENN_WIDTH) +#define M98090_VS2ENN_MASK BIT(1) +#define M98090_VS2ENN_SHIFT 1 +#define M98090_VS2ENN_WIDTH 1 +#define M98090_VS2ENN_NUM BIT(M98090_VS2ENN_WIDTH) +#define M98090_VSENN_MASK BIT(0) +#define M98090_VSENN_SHIFT 0 +#define M98090_VSENN_WIDTH 1 +#define M98090_VSENN_NUM BIT(M98090_VSENN_WIDTH) + +/* + * M98090_REG_BIAS_CONTROL 0x42 + */ +#define M98090_VCM_MODE_MASK BIT(0) +#define M98090_VCM_MODE_SHIFT 0 +#define M98090_VCM_MODE_WIDTH 1 +#define M98090_VCM_MODE_NUM BIT(M98090_VCM_MODE_WIDTH) + +/* + * M98090_REG_DAC_CONTROL 0x43 + */ +#define M98090_PERFMODE_MASK BIT(1) +#define M98090_PERFMODE_SHIFT 1 +#define M98090_PERFMODE_WIDTH 1 +#define M98090_PERFMODE_NUM BIT(M98090_PERFMODE_WIDTH) +#define M98090_DACHP_MASK BIT(0) +#define M98090_DACHP_SHIFT 0 +#define M98090_DACHP_WIDTH 1 +#define M98090_DACHP_NUM BIT(M98090_DACHP_WIDTH) + +/* + * M98090_REG_ADC_CONTROL 0x44 + */ +#define M98090_OSR128_MASK BIT(2) +#define M98090_OSR128_SHIFT 2 +#define M98090_OSR128_WIDTH 1 +#define M98090_ADCDITHER_MASK BIT(1) +#define M98090_ADCDITHER_SHIFT 1 +#define M98090_ADCDITHER_WIDTH 1 +#define M98090_ADCDITHER_NUM BIT(M98090_ADCDITHER_WIDTH) +#define M98090_ADCHP_MASK BIT(0) +#define M98090_ADCHP_SHIFT 0 +#define M98090_ADCHP_WIDTH 1 +#define M98090_ADCHP_NUM BIT(M98090_ADCHP_WIDTH) + +/* + * M98090_REG_DEVICE_SHUTDOWN 0x45 + */ +#define M98090_SHDNN_MASK BIT(7) +#define M98090_SHDNN_SHIFT 7 +#define M98090_SHDNN_WIDTH 1 + +/* + * M98090_REG_REVISION_ID 0xFF + */ +#define M98090_REVID_MASK (255 << 0) +#define M98090_REVID_SHIFT 0 +#define M98090_REVID_WIDTH 8 +#define M98090_REVID_NUM BIT(M98090_REVID_WIDTH) + +/* function prototype */ + +/* + * initialise max98090 sound codec device for the given configuration + * + * @param blob FDT node for codec values + * @param sampling_rate Sampling rate (Hz) + * @param mclk_freq MCLK Frequency (Hz) + * @param bits_per_sample bits per Sample (must be 16 or 24) + * + * @returns -1 for error and 0 Success. + */ +int max98090_init(const void *blob, int sampling_rate, int mclk_freq, + int bits_per_sample); +int max98090_set_sysclk(struct maxim_priv *max98090, uint freq); +int max98090_hw_params(struct maxim_priv *max98090, uint rate, + uint bits_per_sample); +int max98090_device_init(struct maxim_priv *max98090); +int max98090_set_fmt(struct maxim_priv *max98090, int fmt); +#endif diff --git a/drivers/sound/max98095.c b/drivers/sound/max98095.c index 7c37bd07015..99c0e996b4f 100644 --- a/drivers/sound/max98095.c +++ b/drivers/sound/max98095.c @@ -1,113 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * max98095.c -- MAX98095 ALSA SoC Audio driver * * Copyright 2011 Maxim Integrated Products * - * Modified for uboot by R. Chandrasekar (rcsekar@samsung.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. + * Modified for U-Boot by R. Chandrasekar (rcsekar@samsung.com) */ #include <common.h> -#include <asm/arch/clk.h> -#include <asm/arch/cpu.h> -#include <asm/arch/power.h> -#include <asm/gpio.h> -#include <asm/io.h> -#include <common.h> +#include <audio_codec.h> +#include <dm.h> #include <div64.h> #include <fdtdec.h> #include <i2c.h> #include <sound.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <asm/arch/clk.h> +#include <asm/arch/cpu.h> +#include <asm/arch/power.h> #include "i2s.h" #include "max98095.h" -enum max98095_type { - MAX98095, -}; - -struct max98095_priv { - enum max98095_type devtype; - unsigned int sysclk; - unsigned int rate; - unsigned int fmt; -}; - -static struct sound_codec_info g_codec_info; -struct max98095_priv g_max98095_info; -unsigned int g_max98095_i2c_dev_addr; - /* Index 0 is reserved. */ int rate_table[] = {0, 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000}; /* - * Writes value to a device register through i2c - * - * @param reg reg number to be write - * @param data data to be writen to the above registor - * - * @return int value 1 for change, 0 for no change or negative error code. - */ -static int max98095_i2c_write(unsigned int reg, unsigned char data) -{ - debug("%s: Write Addr : 0x%02X, Data : 0x%02X\n", - __func__, reg, data); - return i2c_write(g_max98095_i2c_dev_addr, reg, 1, &data, 1); -} - -/* - * Read a value from a device register through i2c - * - * @param reg reg number to be read - * @param data address of read data to be stored - * - * @return int value 0 for success, -1 in case of error. - */ -static unsigned int max98095_i2c_read(unsigned int reg, unsigned char *data) -{ - int ret; - - ret = i2c_read(g_max98095_i2c_dev_addr, reg, 1, data, 1); - if (ret != 0) { - debug("%s: Error while reading register %#04x\n", - __func__, reg); - return -1; - } - - return 0; -} - -/* - * update device register bits through i2c - * - * @param reg codec register - * @param mask register mask - * @param value new value - * - * @return int value 0 for success, non-zero error code. - */ -static int max98095_update_bits(unsigned int reg, unsigned char mask, - unsigned char value) -{ - int change, ret = 0; - unsigned char old, new; - - if (max98095_i2c_read(reg, &old) != 0) - return -1; - new = (old & ~mask) | (value & mask); - change = (old != new) ? 1 : 0; - if (change) - ret = max98095_i2c_write(reg, new); - if (ret < 0) - return ret; - - return change; -} - -/* * codec mclk clock divider coefficients based on sampling rate * * @param rate sampling rate @@ -127,19 +46,19 @@ static int rate_value(int rate, u8 *value) } *value = 1; - return -1; + return -EINVAL; } /* * Sets hw params for max98095 * - * @param max98095 max98095 information pointer + * @param priv max98095 information pointer * @param rate Sampling rate * @param bits_per_sample Bits per sample * - * @return -1 for error and 0 Success. + * @return 0 for success or negative error code. */ -static int max98095_hw_params(struct max98095_priv *max98095, +static int max98095_hw_params(struct maxim_priv *priv, enum en_max_audio_interface aif_id, unsigned int rate, unsigned int bits_per_sample) { @@ -161,40 +80,39 @@ static int max98095_hw_params(struct max98095_priv *max98095, switch (bits_per_sample) { case 16: - error = max98095_update_bits(M98095_DAI_FORMAT, - M98095_DAI_WS, 0); + error = maxim_bic_or(priv, M98095_DAI_FORMAT, M98095_DAI_WS, 0); break; case 24: - error = max98095_update_bits(M98095_DAI_FORMAT, - M98095_DAI_WS, M98095_DAI_WS); + error = maxim_bic_or(priv, M98095_DAI_FORMAT, M98095_DAI_WS, + M98095_DAI_WS); break; default: debug("%s: Illegal bits per sample %d.\n", __func__, bits_per_sample); - return -1; + return -EINVAL; } if (rate_value(rate, ®val)) { debug("%s: Failed to set sample rate to %d.\n", __func__, rate); - return -1; + return -EINVAL; } - max98095->rate = rate; + priv->rate = rate; - error |= max98095_update_bits(M98095_DAI_CLKMODE, - M98095_CLKMODE_MASK, regval); + error |= maxim_bic_or(priv, M98095_DAI_CLKMODE, M98095_CLKMODE_MASK, + regval); /* Update sample rate mode */ if (rate < 50000) - error |= max98095_update_bits(M98095_DAI_FILTERS, - M98095_DAI_DHF, 0); + error |= maxim_bic_or(priv, M98095_DAI_FILTERS, + M98095_DAI_DHF, 0); else - error |= max98095_update_bits(M98095_DAI_FILTERS, - M98095_DAI_DHF, M98095_DAI_DHF); + error |= maxim_bic_or(priv, M98095_DAI_FILTERS, + M98095_DAI_DHF, M98095_DAI_DHF); if (error < 0) { debug("%s: Error setting hardware params.\n", __func__); - return -1; + return -EIO; } return 0; @@ -203,18 +121,17 @@ static int max98095_hw_params(struct max98095_priv *max98095, /* * Configures Audio interface system clock for the given frequency * - * @param max98095 max98095 information + * @param priv max98095 information * @param freq Sampling frequency in Hz * - * @return -1 for error and 0 success. + * @return 0 for success or negative error code. */ -static int max98095_set_sysclk(struct max98095_priv *max98095, - unsigned int freq) +static int max98095_set_sysclk(struct maxim_priv *priv, unsigned int freq) { int error = 0; /* Requested clock frequency is already setup */ - if (freq == max98095->sysclk) + if (freq == priv->sysclk) return 0; /* Setup clocks for slave mode, and using the PLL @@ -223,35 +140,35 @@ static int max98095_set_sysclk(struct max98095_priv *max98095, * 0x03 (when master clk is 40MHz to 60MHz).. */ if ((freq >= 10000000) && (freq < 20000000)) { - error = max98095_i2c_write(M98095_026_SYS_CLK, 0x10); + error = maxim_i2c_write(priv, M98095_026_SYS_CLK, 0x10); } else if ((freq >= 20000000) && (freq < 40000000)) { - error = max98095_i2c_write(M98095_026_SYS_CLK, 0x20); + error = maxim_i2c_write(priv, M98095_026_SYS_CLK, 0x20); } else if ((freq >= 40000000) && (freq < 60000000)) { - error = max98095_i2c_write(M98095_026_SYS_CLK, 0x30); + error = maxim_i2c_write(priv, M98095_026_SYS_CLK, 0x30); } else { debug("%s: Invalid master clock frequency\n", __func__); - return -1; + return -EINVAL; } debug("%s: Clock at %uHz\n", __func__, freq); if (error < 0) - return -1; + return -EIO; - max98095->sysclk = freq; + priv->sysclk = freq; return 0; } /* * Sets Max98095 I2S format * - * @param max98095 max98095 information + * @param priv max98095 information * @param fmt i2S format - supports a subset of the options defined * in i2s.h. * - * @return -1 for error and 0 Success. + * @return 0 for success or negative error code. */ -static int max98095_set_fmt(struct max98095_priv *max98095, int fmt, +static int max98095_set_fmt(struct maxim_priv *priv, int fmt, enum en_max_audio_interface aif_id) { u8 regval = 0; @@ -261,10 +178,10 @@ static int max98095_set_fmt(struct max98095_priv *max98095, int fmt, unsigned short M98095_DAI_FORMAT; unsigned short M98095_DAI_CLOCK; - if (fmt == max98095->fmt) + if (fmt == priv->fmt) return 0; - max98095->fmt = fmt; + priv->fmt = fmt; if (aif_id == AIF1) { M98095_DAI_CLKCFG_HI = M98095_028_DAI1_CLKCFG_HI; @@ -281,10 +198,8 @@ static int max98095_set_fmt(struct max98095_priv *max98095, int fmt, switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* Slave mode PLL */ - error |= max98095_i2c_write(M98095_DAI_CLKCFG_HI, - 0x80); - error |= max98095_i2c_write(M98095_DAI_CLKCFG_LO, - 0x00); + error |= maxim_i2c_write(priv, M98095_DAI_CLKCFG_HI, 0x80); + error |= maxim_i2c_write(priv, M98095_DAI_CLKCFG_LO, 0x00); break; case SND_SOC_DAIFMT_CBM_CFM: /* Set to master mode */ @@ -294,7 +209,7 @@ static int max98095_set_fmt(struct max98095_priv *max98095, int fmt, case SND_SOC_DAIFMT_CBM_CFS: default: debug("%s: Clock mode unsupported\n", __func__); - return -1; + return -EINVAL; } switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -305,7 +220,7 @@ static int max98095_set_fmt(struct max98095_priv *max98095, int fmt, break; default: debug("%s: Unrecognized format.\n", __func__); - return -1; + return -EINVAL; } switch (fmt & SND_SOC_DAIFMT_INV_MASK) { @@ -322,20 +237,18 @@ static int max98095_set_fmt(struct max98095_priv *max98095, int fmt, break; default: debug("%s: Unrecognized inversion settings.\n", __func__); - return -1; + return -EINVAL; } - error |= max98095_update_bits(M98095_DAI_FORMAT, - M98095_DAI_MAS | M98095_DAI_DLY | - M98095_DAI_BCI | M98095_DAI_WCI, - regval); + error |= maxim_bic_or(priv, M98095_DAI_FORMAT, + M98095_DAI_MAS | M98095_DAI_DLY | + M98095_DAI_BCI | M98095_DAI_WCI, regval); - error |= max98095_i2c_write(M98095_DAI_CLOCK, - M98095_DAI_BSEL64); + error |= maxim_i2c_write(priv, M98095_DAI_CLOCK, M98095_DAI_BSEL64); if (error < 0) { debug("%s: Error setting i2s format.\n", __func__); - return -1; + return -EIO; } return 0; @@ -344,9 +257,10 @@ static int max98095_set_fmt(struct max98095_priv *max98095, int fmt, /* * resets the audio codec * - * @return -1 for error and 0 success. + * @param priv Private data for driver + * @return 0 for success or negative error code. */ -static int max98095_reset(void) +static int max98095_reset(struct maxim_priv *priv) { int i, ret; @@ -354,13 +268,13 @@ static int max98095_reset(void) * Gracefully reset the DSP core and the codec hardware in a proper * sequence. */ - ret = max98095_i2c_write(M98095_00F_HOST_CFG, 0); + ret = maxim_i2c_write(priv, M98095_00F_HOST_CFG, 0); if (ret != 0) { debug("%s: Failed to reset DSP: %d\n", __func__, ret); return ret; } - ret = max98095_i2c_write(M98095_097_PWR_SYS, 0); + ret = maxim_i2c_write(priv, M98095_097_PWR_SYS, 0); if (ret != 0) { debug("%s: Failed to reset codec: %d\n", __func__, ret); return ret; @@ -371,7 +285,7 @@ static int max98095_reset(void) * reset hardware control register. */ for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) { - ret = max98095_i2c_write(i, 0); + ret = maxim_i2c_write(priv, i, 0); if (ret < 0) { debug("%s: Failed to reset: %d\n", __func__, ret); return ret; @@ -384,132 +298,128 @@ static int max98095_reset(void) /* * Intialise max98095 codec device * - * @param max98095 max98095 information - * - * @returns -1 for error and 0 Success. + * @param priv max98095 information + * @return 0 for success or negative error code. */ -static int max98095_device_init(struct max98095_priv *max98095, - enum en_max_audio_interface aif_id) +static int max98095_device_init(struct maxim_priv *priv) { unsigned char id; - int error = 0; + int ret; + + /* Enable codec clock */ + set_xclkout(); /* reset the codec, the DSP core, and disable all interrupts */ - error = max98095_reset(); - if (error != 0) { + ret = max98095_reset(priv); + if (ret != 0) { debug("Reset\n"); - return error; + return ret; } /* initialize private data */ - max98095->sysclk = -1U; - max98095->rate = -1U; - max98095->fmt = -1U; + priv->sysclk = -1U; + priv->rate = -1U; + priv->fmt = -1U; - error = max98095_i2c_read(M98095_0FF_REV_ID, &id); - if (error < 0) { + ret = maxim_i2c_read(priv, M98095_0FF_REV_ID, &id); + if (ret < 0) { debug("%s: Failure reading hardware revision: %d\n", __func__, id); - goto err_access; + return ret; } debug("%s: Hardware revision: %c\n", __func__, (id - 0x40) + 'A'); - error |= max98095_i2c_write(M98095_097_PWR_SYS, M98095_PWRSV); + return 0; +} + +static int max98095_setup_interface(struct maxim_priv *priv, + enum en_max_audio_interface aif_id) +{ + int error; + + error = maxim_i2c_write(priv, M98095_097_PWR_SYS, M98095_PWRSV); /* * initialize registers to hardware default configuring audio * interface2 to DAC */ if (aif_id == AIF1) - error |= max98095_i2c_write(M98095_048_MIX_DAC_LR, + error |= maxim_i2c_write(priv, M98095_048_MIX_DAC_LR, M98095_DAI1L_TO_DACL | M98095_DAI1R_TO_DACR); else - error |= max98095_i2c_write(M98095_048_MIX_DAC_LR, + error |= maxim_i2c_write(priv, M98095_048_MIX_DAC_LR, M98095_DAI2M_TO_DACL | M98095_DAI2M_TO_DACR); - error |= max98095_i2c_write(M98095_092_PWR_EN_OUT, + error |= maxim_i2c_write(priv, M98095_092_PWR_EN_OUT, M98095_SPK_SPREADSPECTRUM); - error |= max98095_i2c_write(M98095_04E_CFG_HP, M98095_HPNORMAL); + error |= maxim_i2c_write(priv, M98095_04E_CFG_HP, M98095_HPNORMAL); if (aif_id == AIF1) - error |= max98095_i2c_write(M98095_02C_DAI1_IOCFG, + error |= maxim_i2c_write(priv, M98095_02C_DAI1_IOCFG, M98095_S1NORMAL | M98095_SDATA); else - error |= max98095_i2c_write(M98095_036_DAI2_IOCFG, + error |= maxim_i2c_write(priv, M98095_036_DAI2_IOCFG, M98095_S2NORMAL | M98095_SDATA); /* take the codec out of the shut down */ - error |= max98095_update_bits(M98095_097_PWR_SYS, M98095_SHDNRUN, - M98095_SHDNRUN); - /* route DACL and DACR output to HO and Spekers */ - error |= max98095_i2c_write(M98095_050_MIX_SPK_LEFT, 0x01); /* DACL */ - error |= max98095_i2c_write(M98095_051_MIX_SPK_RIGHT, 0x01);/* DACR */ - error |= max98095_i2c_write(M98095_04C_MIX_HP_LEFT, 0x01); /* DACL */ - error |= max98095_i2c_write(M98095_04D_MIX_HP_RIGHT, 0x01); /* DACR */ + error |= maxim_bic_or(priv, M98095_097_PWR_SYS, M98095_SHDNRUN, + M98095_SHDNRUN); + /* + * route DACL and DACR output to HO and Speakers + * Ordering: DACL, DACR, DACL, DACR + */ + error |= maxim_i2c_write(priv, M98095_050_MIX_SPK_LEFT, 0x01); + error |= maxim_i2c_write(priv, M98095_051_MIX_SPK_RIGHT, 0x01); + error |= maxim_i2c_write(priv, M98095_04C_MIX_HP_LEFT, 0x01); + error |= maxim_i2c_write(priv, M98095_04D_MIX_HP_RIGHT, 0x01); /* power Enable */ - error |= max98095_i2c_write(M98095_091_PWR_EN_OUT, 0xF3); + error |= maxim_i2c_write(priv, M98095_091_PWR_EN_OUT, 0xF3); /* set Volume */ - error |= max98095_i2c_write(M98095_064_LVL_HP_L, 15); - error |= max98095_i2c_write(M98095_065_LVL_HP_R, 15); - error |= max98095_i2c_write(M98095_067_LVL_SPK_L, 16); - error |= max98095_i2c_write(M98095_068_LVL_SPK_R, 16); + error |= maxim_i2c_write(priv, M98095_064_LVL_HP_L, 15); + error |= maxim_i2c_write(priv, M98095_065_LVL_HP_R, 15); + error |= maxim_i2c_write(priv, M98095_067_LVL_SPK_L, 16); + error |= maxim_i2c_write(priv, M98095_068_LVL_SPK_R, 16); /* Enable DAIs */ - error |= max98095_i2c_write(M98095_093_BIAS_CTRL, 0x30); + error |= maxim_i2c_write(priv, M98095_093_BIAS_CTRL, 0x30); if (aif_id == AIF1) - error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x01); + error |= maxim_i2c_write(priv, M98095_096_PWR_DAC_CK, 0x01); else - error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x07); + error |= maxim_i2c_write(priv, M98095_096_PWR_DAC_CK, 0x07); -err_access: if (error < 0) - return -1; + return -EIO; return 0; } -static int max98095_do_init(struct sound_codec_info *pcodec_info, +static int max98095_do_init(struct maxim_priv *priv, enum en_max_audio_interface aif_id, int sampling_rate, int mclk_freq, int bits_per_sample) { int ret = 0; - /* Enable codec clock */ - set_xclkout(); - - /* shift the device address by 1 for 7 bit addressing */ - g_max98095_i2c_dev_addr = pcodec_info->i2c_dev_addr >> 1; - - if (pcodec_info->codec_type == CODEC_MAX_98095) { - g_max98095_info.devtype = MAX98095; - } else { - debug("%s: Codec id [%d] not defined\n", __func__, - pcodec_info->codec_type); - return -1; - } - - ret = max98095_device_init(&g_max98095_info, aif_id); + ret = max98095_setup_interface(priv, aif_id); if (ret < 0) { - debug("%s: max98095 codec chip init failed\n", __func__); + debug("%s: max98095 setup interface failed\n", __func__); return ret; } - ret = max98095_set_sysclk(&g_max98095_info, mclk_freq); + ret = max98095_set_sysclk(priv, mclk_freq); if (ret < 0) { debug("%s: max98095 codec set sys clock failed\n", __func__); return ret; } - ret = max98095_hw_params(&g_max98095_info, aif_id, sampling_rate, + ret = max98095_hw_params(priv, aif_id, sampling_rate, bits_per_sample); if (ret == 0) { - ret = max98095_set_fmt(&g_max98095_info, - SND_SOC_DAIFMT_I2S | + ret = max98095_set_fmt(priv, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, aif_id); @@ -518,76 +428,45 @@ static int max98095_do_init(struct sound_codec_info *pcodec_info, return ret; } -static int get_max98095_codec_values(struct sound_codec_info *pcodec_info, - const void *blob) +static int max98095_set_params(struct udevice *dev, int interface, int rate, + int mclk_freq, int bits_per_sample, + uint channels) { - int error = 0; -#if CONFIG_IS_ENABLED(OF_CONTROL) - enum fdt_compat_id compat; - int node; - int parent; - - /* Get the node from FDT for codec */ - node = fdtdec_next_compatible(blob, 0, COMPAT_MAXIM_98095_CODEC); - if (node <= 0) { - debug("EXYNOS_SOUND: No node for codec in device tree\n"); - debug("node = %d\n", node); - return -1; - } - - parent = fdt_parent_offset(blob, node); - if (parent < 0) { - debug("%s: Cannot find node parent\n", __func__); - return -1; - } + struct maxim_priv *priv = dev_get_priv(dev); - compat = fdtdec_lookup(blob, parent); - switch (compat) { - case COMPAT_SAMSUNG_S3C2440_I2C: - pcodec_info->i2c_bus = i2c_get_bus_num_fdt(parent); - error |= pcodec_info->i2c_bus; - debug("i2c bus = %d\n", pcodec_info->i2c_bus); - pcodec_info->i2c_dev_addr = fdtdec_get_int(blob, node, - "reg", 0); - error |= pcodec_info->i2c_dev_addr; - debug("i2c dev addr = %x\n", pcodec_info->i2c_dev_addr); - break; - default: - debug("%s: Unknown compat id %d\n", __func__, compat); - return -1; - } -#else - pcodec_info->i2c_bus = AUDIO_I2C_BUS; - pcodec_info->i2c_dev_addr = AUDIO_I2C_REG; - debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr); -#endif - pcodec_info->codec_type = CODEC_MAX_98095; - if (error == -1) { - debug("fail to get max98095 codec node properties\n"); - return -1; - } - - return 0; + return max98095_do_init(priv, interface, rate, mclk_freq, + bits_per_sample); } -/* max98095 Device Initialisation */ -int max98095_init(const void *blob, enum en_max_audio_interface aif_id, - int sampling_rate, int mclk_freq, - int bits_per_sample) +static int max98095_probe(struct udevice *dev) { + struct maxim_priv *priv = dev_get_priv(dev); int ret; - int old_bus = i2c_get_bus_num(); - struct sound_codec_info *pcodec_info = &g_codec_info; - if (get_max98095_codec_values(pcodec_info, blob) < 0) { - debug("FDT Codec values failed\n"); - return -1; + priv->dev = dev; + ret = max98095_device_init(priv); + if (ret < 0) { + debug("%s: max98095 codec chip init failed\n", __func__); + return ret; } - i2c_set_bus_num(pcodec_info->i2c_bus); - ret = max98095_do_init(pcodec_info, aif_id, sampling_rate, mclk_freq, - bits_per_sample); - i2c_set_bus_num(old_bus); - - return ret; + return 0; } + +static const struct audio_codec_ops max98095_ops = { + .set_params = max98095_set_params, +}; + +static const struct udevice_id max98095_ids[] = { + { .compatible = "maxim,max98095" }, + { } +}; + +U_BOOT_DRIVER(max98095) = { + .name = "max98095", + .id = UCLASS_AUDIO_CODEC, + .of_match = max98095_ids, + .probe = max98095_probe, + .ops = &max98095_ops, + .priv_auto_alloc_size = sizeof(struct maxim_priv), +}; diff --git a/drivers/sound/max98095.h b/drivers/sound/max98095.h index 44b1e3a97b4..1521f3f02f9 100644 --- a/drivers/sound/max98095.h +++ b/drivers/sound/max98095.h @@ -1,19 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * max98095.h -- MAX98095 ALSA SoC Audio driver * * Copyright 2011 Maxim Integrated Products - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef _MAX98095_H #define _MAX98095_H +#include "maxim_codec.h" + /* Available audio interface ports in wm8994 codec */ enum en_max_audio_interface { - AIF1 = 1, + AIF1, AIF2, }; diff --git a/drivers/sound/maxim_codec.c b/drivers/sound/maxim_codec.c new file mode 100644 index 00000000000..dcaf081988b --- /dev/null +++ b/drivers/sound/maxim_codec.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * maxim_codec.c -- MAXIM CODEC Common driver + * + * Copyright 2011 Maxim Integrated Products + */ + +#include <common.h> +#include <div64.h> +#include <i2c.h> +#include <i2s.h> +#include <sound.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <asm/arch/clk.h> +#include <asm/arch/cpu.h> +#include <asm/arch/power.h> +#include "maxim_codec.h" + +/* + * Writes value to a device register through i2c + * + * @param priv Private data for driver + * @param reg reg number to be write + * @param data data to be writen to the above registor + * + * @return int value 1 for change, 0 for no change or negative error code. + */ +int maxim_i2c_write(struct maxim_priv *priv, unsigned int reg, + unsigned char data) +{ + debug("%s: Write Addr : 0x%02X, Data : 0x%02X\n", + __func__, reg, data); + return dm_i2c_write(priv->dev, reg, &data, 1); +} + +/* + * Read a value from a device register through i2c + * + * @param priv Private data for driver + * @param reg reg number to be read + * @param data address of read data to be stored + * + * @return int value 0 for success, -1 in case of error. + */ +unsigned int maxim_i2c_read(struct maxim_priv *priv, unsigned int reg, + unsigned char *data) +{ + int ret; + + return dm_i2c_read(priv->dev, reg, data, 1); + if (ret != 0) { + debug("%s: Error while reading register %#04x\n", + __func__, reg); + return -1; + } + + return 0; +} + +/* + * update device register bits through i2c + * + * @param priv Private data for driver + * @param reg codec register + * @param mask register mask + * @param value new value + * + * @return int value 0 for success, non-zero error code. + */ +int maxim_bic_or(struct maxim_priv *priv, unsigned int reg, unsigned char mask, + unsigned char value) +{ + int change, ret = 0; + unsigned char old, new; + + if (maxim_i2c_read(priv, reg, &old) != 0) + return -1; + new = (old & ~mask) | (value & mask); + change = (old != new) ? 1 : 0; + if (change) + ret = maxim_i2c_write(priv, reg, new); + if (ret < 0) + return ret; + + return change; +} diff --git a/drivers/sound/maxim_codec.h b/drivers/sound/maxim_codec.h new file mode 100644 index 00000000000..a3128e0bb73 --- /dev/null +++ b/drivers/sound/maxim_codec.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * maxim_codec.h -- MAXIM codec common interface file + * + * Copyright (C) 2013 Samsung Electronics + * D Krishna Mohan <krishna.md@samsung.com> + */ + +#ifndef __MAXIM_COMMON_H__ +#define __MAXIM_COMMON_H__ + +enum maxim_codec_type { + MAX98095, + MAX98090, +}; + +struct maxim_priv { + enum maxim_codec_type devtype; + unsigned int sysclk; + unsigned int rate; + unsigned int fmt; + struct udevice *dev; +}; + +#define MAXIM_AUDIO_I2C_BUS 7 +#define MAXIM_AUDIO_I2C_REG_98095 0x22 + +#define MAXIM_AUDIO_I2C_REG MAXIM_AUDIO_I2C_REG_98095 + +/* + * Writes value to a device register through i2c + * + * @param priv Private data for driver + * @param reg reg number to be write + * @param data data to be writen to the above registor + * + * @return int value 1 for change, 0 for no change or negative error code. + */ +int maxim_i2c_write(struct maxim_priv *priv, unsigned int reg, + unsigned char data); + +/* + * Read a value from a device register through i2c + * + * @param priv Private data for driver + * @param reg reg number to be read + * @param data address of read data to be stored + * + * @return int value 0 for success, -1 in case of error. + */ +unsigned int maxim_i2c_read(struct maxim_priv *priv, unsigned int reg, + unsigned char *data); + +/* + * update device register bits through i2c + * + * @param priv Private data for driver + * @param reg codec register + * @param mask register mask + * @param value new value + * + * @return int value 0 for success, non-zero error code. + */ +int maxim_bic_or(struct maxim_priv *priv, unsigned int reg, unsigned char mask, + unsigned char value); + +#endif /* __MAXIM_COMMON_H__ */ diff --git a/drivers/sound/samsung-i2s.c b/drivers/sound/samsung-i2s.c index f39abf5e2a9..c19e08e7e30 100644 --- a/drivers/sound/samsung-i2s.c +++ b/drivers/sound/samsung-i2s.c @@ -4,13 +4,14 @@ * R. Chandrasekar <rcsekar@samsung.com> */ +#include <common.h> +#include <dm.h> +#include <i2s.h> +#include <sound.h> #include <asm/arch/clk.h> #include <asm/arch/pinmux.h> #include <asm/arch/i2s-regs.h> #include <asm/io.h> -#include <common.h> -#include <sound.h> -#include <i2s.h> #define FIC_TX2COUNT(x) (((x) >> 24) & 0xf) #define FIC_TX1COUNT(x) (((x) >> 16) & 0xf) @@ -111,7 +112,7 @@ static void i2s_set_bitclk_framesize(struct i2s_reg *i2s_reg, unsigned bfs) * @param flush Tx fifo flush command (0x00 - do not flush * 0x80 - flush tx fifo) */ -void i2s_fifo(struct i2s_reg *i2s_reg, unsigned int flush) +static void i2s_fifo(struct i2s_reg *i2s_reg, unsigned int flush) { /* Flush the FIFO */ setbits_le32(&i2s_reg->fic, flush); @@ -126,7 +127,7 @@ void i2s_fifo(struct i2s_reg *i2s_reg, unsigned int flush) * * @return int value 0 for success, -1 in case of error */ -int i2s_set_sysclk_dir(struct i2s_reg *i2s_reg, int dir) +static int i2s_set_sysclk_dir(struct i2s_reg *i2s_reg, int dir) { unsigned int mod = readl(&i2s_reg->mod); @@ -148,7 +149,7 @@ int i2s_set_sysclk_dir(struct i2s_reg *i2s_reg, int dir) * * @return int value 0 for success, -1 in case of error */ -int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt) +static int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt) { unsigned int mod = readl(&i2s_reg->mod); unsigned int tmp = 0; @@ -170,7 +171,7 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt) default: debug("%s: Invalid format priority [0x%x]\n", __func__, (fmt & SND_SOC_DAIFMT_FORMAT_MASK)); - return -1; + return -ERANGE; } /* @@ -189,7 +190,7 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt) default: debug("%s: Invalid clock ploarity input [0x%x]\n", __func__, (fmt & SND_SOC_DAIFMT_INV_MASK)); - return -1; + return -ERANGE; } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -201,13 +202,13 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt) ret = i2s_set_sysclk_dir(i2s_reg, SND_SOC_CLOCK_OUT); if (ret != 0) { debug("%s:set i2s clock direction failed\n", __func__); - return -1; + return ret; } break; default: debug("%s: Invalid master selection [0x%x]\n", __func__, (fmt & SND_SOC_DAIFMT_MASTER_MASK)); - return -1; + return -ERANGE; } mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE); @@ -225,7 +226,7 @@ int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt) * * @return int value 0 for success, -1 in case of error */ -int i2s_set_samplesize(struct i2s_reg *i2s_reg, unsigned int blc) +static int i2s_set_samplesize(struct i2s_reg *i2s_reg, unsigned int blc) { unsigned int mod = readl(&i2s_reg->mod); @@ -248,43 +249,43 @@ int i2s_set_samplesize(struct i2s_reg *i2s_reg, unsigned int blc) default: debug("%s: Invalid sample size input [0x%x]\n", __func__, blc); - return -1; + return -ERANGE; } writel(mod, &i2s_reg->mod); return 0; } -int i2s_transfer_tx_data(struct i2stx_info *pi2s_tx, unsigned int *data, - unsigned long data_size) +int i2s_transfer_tx_data(struct i2s_uc_priv *pi2s_tx, void *data, + uint data_size) { + struct i2s_reg *i2s_reg = (struct i2s_reg *)pi2s_tx->base_address; + u32 *ptr; int i; int start; - struct i2s_reg *i2s_reg = - (struct i2s_reg *)pi2s_tx->base_address; if (data_size < FIFO_LENGTH) { debug("%s : Invalid data size\n", __func__); - return -1; /* invalid pcm data size */ + return -ENODATA; /* invalid pcm data size */ } /* fill the tx buffer before stating the tx transmit */ - for (i = 0; i < FIFO_LENGTH; i++) - writel(*data++, &i2s_reg->txd); + for (i = 0, ptr = data; i < FIFO_LENGTH; i++) + writel(*ptr++, &i2s_reg->txd); - data_size -= FIFO_LENGTH; + data_size -= sizeof(*ptr) * FIFO_LENGTH; i2s_txctrl(i2s_reg, I2S_TX_ON); while (data_size > 0) { start = get_timer(0); if (!(CON_TXFIFO_FULL & (readl(&i2s_reg->con)))) { - writel(*data++, &i2s_reg->txd); - data_size--; + writel(*ptr++, &i2s_reg->txd); + data_size -= sizeof(*ptr); } else { if (get_timer(start) > TIMEOUT_I2S_TX) { i2s_txctrl(i2s_reg, I2S_TX_OFF); debug("%s: I2S Transfer Timeout\n", __func__); - return -1; + return -ETIMEDOUT; } } } @@ -293,11 +294,11 @@ int i2s_transfer_tx_data(struct i2stx_info *pi2s_tx, unsigned int *data, return 0; } -int i2s_tx_init(struct i2stx_info *pi2s_tx) +int i2s_tx_init(struct i2s_uc_priv *pi2s_tx) { int ret; - struct i2s_reg *i2s_reg = - (struct i2s_reg *)pi2s_tx->base_address; + struct i2s_reg *i2s_reg = (struct i2s_reg *)pi2s_tx->base_address; + if (pi2s_tx->id == 0) { /* Initialize GPIO for I2S-0 */ exynos_pinmux_config(PERIPH_ID_I2S0, 0); @@ -312,20 +313,20 @@ int i2s_tx_init(struct i2stx_info *pi2s_tx) ret = set_epll_clk(pi2s_tx->audio_pll_clk); } else { debug("%s: unsupported i2s-%d bus\n", __func__, pi2s_tx->id); - return -1; + return -ERANGE; } - if (ret != 0) { + if (ret) { debug("%s: epll clock set rate failed\n", __func__); - return -1; + return ret; } /* Select Clk Source for Audio 0 or 1 */ ret = set_i2s_clk_source(pi2s_tx->id); - if (ret == -1) { + if (ret) { debug("%s: unsupported clock for i2s-%d\n", __func__, pi2s_tx->id); - return -1; + return ret; } if (pi2s_tx->id == 0) { @@ -341,21 +342,21 @@ int i2s_tx_init(struct i2stx_info *pi2s_tx) (pi2s_tx->samplingrate * (pi2s_tx->rfs)), pi2s_tx->id); } - if (ret == -1) { + if (ret) { debug("%s: unsupported prescalar for i2s-%d\n", __func__, pi2s_tx->id); - return -1; + return ret; } /* Configure I2s format */ - ret = i2s_set_fmt(i2s_reg, (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM)); + ret = i2s_set_fmt(i2s_reg, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); if (ret == 0) { i2s_set_lr_framesize(i2s_reg, pi2s_tx->rfs); ret = i2s_set_samplesize(i2s_reg, pi2s_tx->bitspersample); if (ret != 0) { debug("%s:set sample rate failed\n", __func__); - return -1; + return ret; } i2s_set_bitclk_framesize(i2s_reg, pi2s_tx->bfs); @@ -368,3 +369,87 @@ int i2s_tx_init(struct i2stx_info *pi2s_tx) return ret; } + +static int samsung_i2s_tx_data(struct udevice *dev, void *data, uint data_size) +{ + struct i2s_uc_priv *priv = dev_get_uclass_priv(dev); + + return i2s_transfer_tx_data(priv, data, data_size); +} + +static int samsung_i2s_probe(struct udevice *dev) +{ + struct i2s_uc_priv *priv = dev_get_uclass_priv(dev); + + return i2s_tx_init(priv); +} + +static int samsung_i2s_ofdata_to_platdata(struct udevice *dev) +{ + struct i2s_uc_priv *priv = dev_get_uclass_priv(dev); + ulong base; + + /* + * Get the pre-defined sound specific values from FDT. + * All of these are expected to be correct otherwise + * wrong register values in i2s setup parameters + * may result in no sound play. + */ + base = dev_read_addr(dev); + if (base == FDT_ADDR_T_NONE) { + debug("%s: Missing i2s base\n", __func__); + return -EINVAL; + } + priv->base_address = base; + + if (dev_read_u32u(dev, "samsung,i2s-epll-clock-frequency", + &priv->audio_pll_clk)) + goto err; + debug("audio_pll_clk = %d\n", priv->audio_pll_clk); + if (dev_read_u32u(dev, "samsung,i2s-sampling-rate", + &priv->samplingrate)) + goto err; + debug("samplingrate = %d\n", priv->samplingrate); + if (dev_read_u32u(dev, "samsung,i2s-bits-per-sample", + &priv->bitspersample)) + goto err; + debug("bitspersample = %d\n", priv->bitspersample); + if (dev_read_u32u(dev, "samsung,i2s-channels", &priv->channels)) + goto err; + debug("channels = %d\n", priv->channels); + if (dev_read_u32u(dev, "samsung,i2s-lr-clk-framesize", &priv->rfs)) + goto err; + debug("rfs = %d\n", priv->rfs); + if (dev_read_u32u(dev, "samsung,i2s-bit-clk-framesize", &priv->bfs)) + goto err; + debug("bfs = %d\n", priv->bfs); + + if (dev_read_u32u(dev, "samsung,i2s-id", &priv->id)) + goto err; + debug("id = %d\n", priv->id); + + return 0; + +err: + debug("fail to get sound i2s node properties\n"); + + return -EINVAL; +} + +static const struct i2s_ops samsung_i2s_ops = { + .tx_data = samsung_i2s_tx_data, +}; + +static const struct udevice_id samsung_i2s_ids[] = { + { .compatible = "samsung,s5pv210-i2s" }, + { } +}; + +U_BOOT_DRIVER(samsung_i2s) = { + .name = "samsung_i2s", + .id = UCLASS_I2S, + .of_match = samsung_i2s_ids, + .probe = samsung_i2s_probe, + .ofdata_to_platdata = samsung_i2s_ofdata_to_platdata, + .ops = &samsung_i2s_ops, +}; diff --git a/drivers/sound/samsung_sound.c b/drivers/sound/samsung_sound.c new file mode 100644 index 00000000000..1d711c87322 --- /dev/null +++ b/drivers/sound/samsung_sound.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 Google, LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <audio_codec.h> +#include <dm.h> +#include <i2s.h> +#include <sound.h> +#include <asm/gpio.h> + +static int samsung_sound_setup(struct udevice *dev) +{ + struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct i2s_uc_priv *i2c_priv = dev_get_uclass_priv(uc_priv->i2s); + int ret; + + if (uc_priv->setup_done) + return -EALREADY; + ret = audio_codec_set_params(uc_priv->codec, i2c_priv->id, + i2c_priv->samplingrate, + i2c_priv->samplingrate * i2c_priv->rfs, + i2c_priv->bitspersample, + i2c_priv->channels); + if (ret) + return ret; + uc_priv->setup_done = true; + + return 0; +} + +static int samsung_sound_play(struct udevice *dev, void *data, uint data_size) +{ + struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev); + + return i2s_tx_data(uc_priv->i2s, data, data_size); +} + +static int samsung_sound_probe(struct udevice *dev) +{ + struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct ofnode_phandle_args args; + struct gpio_desc en_gpio; + ofnode node; + int ret; + + ret = gpio_request_by_name(dev, "codec-enable-gpio", 0, &en_gpio, + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + + /* Turn on the GPIO which connects to the codec's "enable" line. */ + if (!ret) + gpio_set_pull(gpio_get_number(&en_gpio), S5P_GPIO_PULL_NONE); + + ret = uclass_get_device_by_phandle(UCLASS_AUDIO_CODEC, dev, + "samsung,audio-codec", + &uc_priv->codec); + if (ret) { + debug("Failed to probe audio codec\n"); + return ret; + } + node = ofnode_find_subnode(dev_ofnode(dev), "cpu"); + if (!ofnode_valid(node)) { + debug("Failed to find /cpu subnode\n"); + return -EINVAL; + } + ret = ofnode_parse_phandle_with_args(node, "sound-dai", + "#sound-dai-cells", 0, 0, &args); + if (ret) { + debug("Cannot find phandle: %d\n", ret); + return ret; + } + ret = uclass_get_device_by_ofnode(UCLASS_I2S, args.node, &uc_priv->i2s); + if (ret) { + debug("Cannot find i2s: %d\n", ret); + return ret; + } + debug("Probed sound '%s' with codec '%s' and i2s '%s'\n", dev->name, + uc_priv->codec->name, uc_priv->i2s->name); + + return 0; +} + +static const struct sound_ops samsung_sound_ops = { + .setup = samsung_sound_setup, + .play = samsung_sound_play, +}; + +static const struct udevice_id samsung_sound_ids[] = { + { .compatible = "google,snow-audio-max98095" }, + { .compatible = "google,spring-audio-max98095" }, + { .compatible = "samsung,smdk5420-audio-wm8994" }, + { .compatible = "google,peach-audio-max98090" }, + { } +}; + +U_BOOT_DRIVER(samsung_sound) = { + .name = "samsung_sound", + .id = UCLASS_SOUND, + .of_match = samsung_sound_ids, + .probe = samsung_sound_probe, + .ops = &samsung_sound_ops, +}; diff --git a/drivers/sound/sandbox.c b/drivers/sound/sandbox.c index 94eff542824..b0b07f3239b 100644 --- a/drivers/sound/sandbox.c +++ b/drivers/sound/sandbox.c @@ -4,19 +4,185 @@ */ #include <common.h> -#include <asm/sound.h> +#include <audio_codec.h> +#include <dm.h> +#include <i2s.h> +#include <sound.h> #include <asm/sdl.h> -int sound_play(uint32_t msec, uint32_t frequency) +struct sandbox_codec_priv { + int interface; + int rate; + int mclk_freq; + int bits_per_sample; + uint channels; +}; + +struct sandbox_i2s_priv { + int sum; /* Use to sum the provided audio data */ +}; + +struct sandbox_sound_priv { + int setup_called; + int sum; /* Use to sum the provided audio data */ +}; + +void sandbox_get_codec_params(struct udevice *dev, int *interfacep, int *ratep, + int *mclk_freqp, int *bits_per_samplep, + uint *channelsp) +{ + struct sandbox_codec_priv *priv = dev_get_priv(dev); + + *interfacep = priv->interface; + *ratep = priv->rate; + *mclk_freqp = priv->mclk_freq; + *bits_per_samplep = priv->bits_per_sample; + *channelsp = priv->channels; +} + +int sandbox_get_i2s_sum(struct udevice *dev) +{ + struct sandbox_i2s_priv *priv = dev_get_priv(dev); + + return priv->sum; +} + +int sandbox_get_setup_called(struct udevice *dev) +{ + struct sandbox_sound_priv *priv = dev_get_priv(dev); + + return priv->setup_called; +} + +int sandbox_get_sound_sum(struct udevice *dev) +{ + struct sandbox_sound_priv *priv = dev_get_priv(dev); + + return priv->sum; +} + +static int sandbox_codec_set_params(struct udevice *dev, int interface, + int rate, int mclk_freq, + int bits_per_sample, uint channels) +{ + struct sandbox_codec_priv *priv = dev_get_priv(dev); + + priv->interface = interface; + priv->rate = rate; + priv->mclk_freq = mclk_freq; + priv->bits_per_sample = bits_per_sample; + priv->channels = channels; + + return 0; +} + +static int sandbox_i2s_tx_data(struct udevice *dev, void *data, + uint data_size) +{ + struct sandbox_i2s_priv *priv = dev_get_priv(dev); + int i; + + for (i = 0; i < data_size; i++) + priv->sum += ((uint8_t *)data)[i]; + + return sandbox_sdl_sound_play(data, data_size); +} + +static int sandbox_i2s_probe(struct udevice *dev) { - sandbox_sdl_sound_start(frequency); - mdelay(msec); - sandbox_sdl_sound_stop(); + struct i2s_uc_priv *uc_priv = dev_get_uclass_priv(dev); + + /* Use hard-coded values here */ + uc_priv->rfs = 256; + uc_priv->bfs = 32; + uc_priv->audio_pll_clk = 192000000; + uc_priv->samplingrate = 48000; + uc_priv->bitspersample = 16; + uc_priv->channels = 2; + uc_priv->id = 1; + + /* Ignore any error here - we'll just have no sound */ + sandbox_sdl_sound_init(uc_priv->samplingrate, uc_priv->channels); return 0; } -int sound_init(const void *blob) +static int sandbox_sound_setup(struct udevice *dev) +{ + struct sandbox_sound_priv *priv = dev_get_priv(dev); + + priv->setup_called++; + + return 0; +} + +static int sandbox_sound_play(struct udevice *dev, void *data, uint data_size) +{ + struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct sandbox_sound_priv *priv = dev_get_priv(dev); + int i; + + for (i = 0; i < data_size; i++) + priv->sum += ((uint8_t *)data)[i]; + + return i2s_tx_data(uc_priv->i2s, data, data_size); +} + +static int sandbox_sound_probe(struct udevice *dev) { - return sandbox_sdl_sound_init(); + return sound_find_codec_i2s(dev); } + +static const struct audio_codec_ops sandbox_codec_ops = { + .set_params = sandbox_codec_set_params, +}; + +static const struct udevice_id sandbox_codec_ids[] = { + { .compatible = "sandbox,audio-codec" }, + { } +}; + +U_BOOT_DRIVER(sandbox_codec) = { + .name = "sandbox_codec", + .id = UCLASS_AUDIO_CODEC, + .of_match = sandbox_codec_ids, + .ops = &sandbox_codec_ops, + .priv_auto_alloc_size = sizeof(struct sandbox_codec_priv), +}; + +static const struct i2s_ops sandbox_i2s_ops = { + .tx_data = sandbox_i2s_tx_data, +}; + +static const struct udevice_id sandbox_i2s_ids[] = { + { .compatible = "sandbox,i2s" }, + { } +}; + +U_BOOT_DRIVER(sandbox_i2s) = { + .name = "sandbox_i2s", + .id = UCLASS_I2S, + .of_match = sandbox_i2s_ids, + .ops = &sandbox_i2s_ops, + .probe = sandbox_i2s_probe, + .priv_auto_alloc_size = sizeof(struct sandbox_i2s_priv), +}; + +static const struct sound_ops sandbox_sound_ops = { + .setup = sandbox_sound_setup, + .play = sandbox_sound_play, +}; + +static const struct udevice_id sandbox_sound_ids[] = { + { .compatible = "sandbox,sound" }, + { } +}; + +U_BOOT_DRIVER(sandbox_sound) = { + .name = "sandbox_sound", + .id = UCLASS_SOUND, + .of_match = sandbox_sound_ids, + .ops = &sandbox_sound_ops, + .priv_auto_alloc_size = sizeof(struct sandbox_sound_priv), + .probe = sandbox_sound_probe, +}; diff --git a/drivers/sound/sound-i2s.c b/drivers/sound/sound-i2s.c deleted file mode 100644 index f0f0b79bc52..00000000000 --- a/drivers/sound/sound-i2s.c +++ /dev/null @@ -1,208 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2012 Samsung Electronics - * R. Chandrasekar <rcsekar@samsung.com> - */ - -#include <malloc.h> -#include <common.h> -#include <asm/io.h> -#include <linux/libfdt.h> -#include <fdtdec.h> -#include <i2c.h> -#include <i2s.h> -#include <sound.h> -#include <asm/arch/sound.h> -#include "wm8994.h" -#include "max98095.h" - -/* defines */ -#define SOUND_400_HZ 400 -#define SOUND_BITS_IN_BYTE 8 - -static struct i2stx_info g_i2stx_pri; - -/* - * get_sound_i2s_values gets values for i2s parameters - * - * @param i2stx_info i2s transmitter transfer param structure - * @param blob FDT blob if enabled else NULL - */ -static int get_sound_i2s_values(struct i2stx_info *i2s, const void *blob) -{ - int node; - int error = 0; - int base; - - node = fdt_path_offset(blob, "i2s"); - if (node <= 0) { - debug("EXYNOS_SOUND: No node for sound in device tree\n"); - return -1; - } - - /* - * Get the pre-defined sound specific values from FDT. - * All of these are expected to be correct otherwise - * wrong register values in i2s setup parameters - * may result in no sound play. - */ - base = fdtdec_get_addr(blob, node, "reg"); - if (base == FDT_ADDR_T_NONE) { - debug("%s: Missing i2s base\n", __func__); - return -1; - } - i2s->base_address = base; - - i2s->audio_pll_clk = fdtdec_get_int(blob, - node, "samsung,i2s-epll-clock-frequency", -1); - error |= i2s->audio_pll_clk; - debug("audio_pll_clk = %d\n", i2s->audio_pll_clk); - i2s->samplingrate = fdtdec_get_int(blob, - node, "samsung,i2s-sampling-rate", -1); - error |= i2s->samplingrate; - debug("samplingrate = %d\n", i2s->samplingrate); - i2s->bitspersample = fdtdec_get_int(blob, - node, "samsung,i2s-bits-per-sample", -1); - error |= i2s->bitspersample; - debug("bitspersample = %d\n", i2s->bitspersample); - i2s->channels = fdtdec_get_int(blob, - node, "samsung,i2s-channels", -1); - error |= i2s->channels; - debug("channels = %d\n", i2s->channels); - i2s->rfs = fdtdec_get_int(blob, - node, "samsung,i2s-lr-clk-framesize", -1); - error |= i2s->rfs; - debug("rfs = %d\n", i2s->rfs); - i2s->bfs = fdtdec_get_int(blob, - node, "samsung,i2s-bit-clk-framesize", -1); - error |= i2s->bfs; - debug("bfs = %d\n", i2s->bfs); - - i2s->id = fdtdec_get_int(blob, node, "samsung,i2s-id", -1); - error |= i2s->id; - debug("id = %d\n", i2s->id); - - if (error == -1) { - debug("fail to get sound i2s node properties\n"); - return -1; - } - - return 0; -} - -/* - * Init codec - * - * @param blob FDT blob - * @param pi2s_tx i2s parameters required by codec - * @return int value, 0 for success - */ -static int codec_init(const void *blob, struct i2stx_info *pi2s_tx) -{ - int ret; - const char *codectype; - int node; - - /* Get the node from FDT for sound */ - node = fdt_path_offset(blob, "i2s"); - if (node <= 0) { - debug("EXYNOS_SOUND: No node for sound in device tree\n"); - debug("node = %d\n", node); - return -1; - } - - /* - * Get the pre-defined sound codec specific values from FDT. - * All of these are expected to be correct otherwise sound - * can not be played - */ - codectype = fdt_getprop(blob, node, "samsung,codec-type", NULL); - debug("device = %s\n", codectype); - if (!strcmp(codectype, "wm8994")) { - /* Check the codec type and initialise the same */ - ret = wm8994_init(blob, pi2s_tx->id + 1, - pi2s_tx->samplingrate, - (pi2s_tx->samplingrate * (pi2s_tx->rfs)), - pi2s_tx->bitspersample, pi2s_tx->channels); - } else if (!strcmp(codectype, "max98095")) { - ret = max98095_init(blob, pi2s_tx->id + 1, - pi2s_tx->samplingrate, - (pi2s_tx->samplingrate * (pi2s_tx->rfs)), - pi2s_tx->bitspersample); - } else { - debug("%s: Unknown codec type %s\n", __func__, codectype); - return -1; - } - - if (ret) { - debug("%s: Codec init failed\n", __func__); - return -1; - } - - return 0; -} - -int sound_init(const void *blob) -{ - int ret; - struct i2stx_info *pi2s_tx = &g_i2stx_pri; - - /* Get the I2S Values */ - if (get_sound_i2s_values(pi2s_tx, blob) < 0) { - debug(" FDT I2S values failed\n"); - return -1; - } - - if (codec_init(blob, pi2s_tx) < 0) { - debug(" Codec init failed\n"); - return -1; - } - - ret = i2s_tx_init(pi2s_tx); - if (ret) { - debug("%s: Failed to init i2c transmit: ret=%d\n", __func__, - ret); - return ret; - } - - - return ret; -} - -int sound_play(uint32_t msec, uint32_t frequency) -{ - unsigned int *data; - unsigned long data_size; - unsigned int ret = 0; - - /*Buffer length computation */ - data_size = g_i2stx_pri.samplingrate * g_i2stx_pri.channels; - data_size *= (g_i2stx_pri.bitspersample / SOUND_BITS_IN_BYTE); - data = malloc(data_size); - - if (data == NULL) { - debug("%s: malloc failed\n", __func__); - return -1; - } - - sound_create_square_wave(g_i2stx_pri.samplingrate, - (unsigned short *)data, - data_size / sizeof(unsigned short), - frequency); - - while (msec >= 1000) { - ret = i2s_transfer_tx_data(&g_i2stx_pri, data, - (data_size / sizeof(int))); - msec -= 1000; - } - if (msec) { - unsigned long size = - (data_size * msec) / (sizeof(int) * 1000); - - ret = i2s_transfer_tx_data(&g_i2stx_pri, data, size); - } - - free(data); - - return ret; -} diff --git a/drivers/sound/sound-uclass.c b/drivers/sound/sound-uclass.c new file mode 100644 index 00000000000..2b836268896 --- /dev/null +++ b/drivers/sound/sound-uclass.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <dm.h> +#include <i2s.h> +#include <sound.h> + +#define SOUND_BITS_IN_BYTE 8 + +int sound_setup(struct udevice *dev) +{ + struct sound_ops *ops = sound_get_ops(dev); + + if (!ops->setup) + return -ENOSYS; + + return ops->setup(dev); +} + +int sound_play(struct udevice *dev, void *data, uint data_size) +{ + struct sound_ops *ops = sound_get_ops(dev); + + if (!ops->play) + return -ENOSYS; + + return ops->play(dev, data, data_size); +} + +int sound_beep(struct udevice *dev, int msecs, int frequency_hz) +{ + struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct i2s_uc_priv *i2s_uc_priv = dev_get_uclass_priv(uc_priv->i2s); + unsigned short *data; + uint data_size; + int ret; + + ret = sound_setup(dev); + if (ret && ret != -EALREADY) + return ret; + + /* Buffer length computation */ + data_size = i2s_uc_priv->samplingrate * i2s_uc_priv->channels; + data_size *= (i2s_uc_priv->bitspersample / SOUND_BITS_IN_BYTE); + data = malloc(data_size); + if (!data) { + debug("%s: malloc failed\n", __func__); + return -ENOMEM; + } + + sound_create_square_wave(i2s_uc_priv->samplingrate, data, data_size, + frequency_hz, i2s_uc_priv->channels); + + while (msecs >= 1000) { + ret = sound_play(dev, data, data_size); + msecs -= 1000; + } + if (msecs) { + unsigned long size = + (data_size * msecs) / (sizeof(int) * 1000); + + ret = sound_play(dev, data, size); + } + + free(data); + + return ret; +} + +int sound_find_codec_i2s(struct udevice *dev) +{ + struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct ofnode_phandle_args args; + ofnode node; + int ret; + + /* First the codec */ + node = ofnode_find_subnode(dev_ofnode(dev), "codec"); + if (!ofnode_valid(node)) { + debug("Failed to find /cpu subnode\n"); + return -EINVAL; + } + ret = ofnode_parse_phandle_with_args(node, "sound-dai", + "#sound-dai-cells", 0, 0, &args); + if (ret) { + debug("Cannot find phandle: %d\n", ret); + return ret; + } + ret = uclass_get_device_by_ofnode(UCLASS_AUDIO_CODEC, args.node, + &uc_priv->codec); + if (ret) { + debug("Cannot find codec: %d\n", ret); + return ret; + } + + /* Now the i2s */ + node = ofnode_find_subnode(dev_ofnode(dev), "cpu"); + if (!ofnode_valid(node)) { + debug("Failed to find /cpu subnode\n"); + return -EINVAL; + } + ret = ofnode_parse_phandle_with_args(node, "sound-dai", + "#sound-dai-cells", 0, 0, &args); + if (ret) { + debug("Cannot find phandle: %d\n", ret); + return ret; + } + ret = uclass_get_device_by_ofnode(UCLASS_I2S, args.node, &uc_priv->i2s); + if (ret) { + debug("Cannot find i2s: %d\n", ret); + return ret; + } + debug("Probed sound '%s' with codec '%s' and i2s '%s'\n", dev->name, + uc_priv->codec->name, uc_priv->i2s->name); + + return 0; +} + +UCLASS_DRIVER(sound) = { + .id = UCLASS_SOUND, + .name = "sound", + .per_device_auto_alloc_size = sizeof(struct sound_uc_priv), +}; diff --git a/drivers/sound/sound.c b/drivers/sound/sound.c index 4f0ad0d8f0d..dd3f9db4f75 100644 --- a/drivers/sound/sound.c +++ b/drivers/sound/sound.c @@ -8,7 +8,7 @@ #include <sound.h> void sound_create_square_wave(uint sample_rate, unsigned short *data, int size, - uint freq) + uint freq, uint channels) { const unsigned short amplitude = 16000; /* between 1 and 32767 */ const int period = freq ? sample_rate / freq : 0; @@ -21,14 +21,17 @@ void sound_create_square_wave(uint sample_rate, unsigned short *data, int size, size--; while (size) { - int i; + int i, j; + for (i = 0; size && i < half; i++) { size -= 2; - *data++ = amplitude; + for (j = 0; j < channels; j++) + *data++ = amplitude; } for (i = 0; size && i < period - half; i++) { size -= 2; - *data++ = -amplitude; + for (j = 0; j < channels; j++) + *data++ = -amplitude; } } } diff --git a/drivers/sound/wm8994.c b/drivers/sound/wm8994.c index aaaa3241aa1..b290c4e8791 100644 --- a/drivers/sound/wm8994.c +++ b/drivers/sound/wm8994.c @@ -4,15 +4,17 @@ * R. Chandrasekar <rcsekar@samsung.com> */ #include <common.h> -#include <asm/arch/clk.h> -#include <asm/arch/cpu.h> -#include <asm/gpio.h> -#include <asm/io.h> +#include <audio_codec.h> +#include <dm.h> #include <div64.h> #include <fdtdec.h> #include <i2c.h> #include <i2s.h> #include <sound.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <asm/arch/clk.h> +#include <asm/arch/cpu.h> #include <asm/arch/sound.h> #include "wm8994.h" #include "wm8994_registers.h" @@ -38,6 +40,7 @@ struct wm8994_priv { int mclk[WM8994_MAX_AIF]; /* master clock frequency in Hz */ int aifclk[WM8994_MAX_AIF]; /* audio interface clock in Hz */ struct wm8994_fll_config fll[2]; /* fll config to configure fll */ + struct udevice *dev; }; /* wm 8994 supported sampling rate values */ @@ -60,29 +63,17 @@ static int bclk_divs[] = { 640, 880, 960, 1280, 1760, 1920 }; -static struct wm8994_priv g_wm8994_info; -static unsigned char g_wm8994_i2c_dev_addr; -static struct sound_codec_info g_codec_info; - -/* - * Initialise I2C for wm 8994 - * - * @param bus no i2c bus number in which wm8994 is connected - */ -static void wm8994_i2c_init(int bus_no) -{ - i2c_set_bus_num(bus_no); -} - /* * Writes value to a device register through i2c * + * @param priv Private data for driver * @param reg reg number to be write * @param data data to be writen to the above registor * * @return int value 1 for change, 0 for no change or negative error code. */ -static int wm8994_i2c_write(unsigned int reg, unsigned short data) +static int wm8994_i2c_write(struct wm8994_priv *priv, unsigned int reg, + unsigned short data) { unsigned char val[2]; @@ -90,23 +81,25 @@ static int wm8994_i2c_write(unsigned int reg, unsigned short data) val[1] = (unsigned char)(data & 0xff); debug("Write Addr : 0x%04X, Data : 0x%04X\n", reg, data); - return i2c_write(g_wm8994_i2c_dev_addr, reg, 2, val, 2); + return dm_i2c_write(priv->dev, reg, val, 2); } /* * Read a value from a device register through i2c * + * @param priv Private data for driver * @param reg reg number to be read * @param data address of read data to be stored * * @return int value 0 for success, -1 in case of error. */ -static unsigned int wm8994_i2c_read(unsigned int reg , unsigned short *data) +static unsigned int wm8994_i2c_read(struct wm8994_priv *priv, unsigned int reg, + unsigned short *data) { unsigned char val[2]; int ret; - ret = i2c_read(g_wm8994_i2c_dev_addr, reg, 2, val, 2); + ret = dm_i2c_read(priv->dev, reg, val, 1); if (ret != 0) { debug("%s: Error while reading register %#04x\n", __func__, reg); @@ -123,6 +116,7 @@ static unsigned int wm8994_i2c_read(unsigned int reg , unsigned short *data) /* * update device register bits through i2c * + * @param priv Private data for driver * @param reg codec register * @param mask register mask * @param value new value @@ -130,18 +124,18 @@ static unsigned int wm8994_i2c_read(unsigned int reg , unsigned short *data) * @return int value 1 if change in the register value, * 0 for no change or negative error code. */ -static int wm8994_update_bits(unsigned int reg, unsigned short mask, - unsigned short value) +static int wm8994_bic_or(struct wm8994_priv *priv, unsigned int reg, + unsigned short mask, unsigned short value) { int change , ret = 0; unsigned short old, new; - if (wm8994_i2c_read(reg, &old) != 0) + if (wm8994_i2c_read(priv, reg, &old) != 0) return -1; new = (old & ~mask) | (value & mask); change = (old != new) ? 1 : 0; if (change) - ret = wm8994_i2c_write(reg, new); + ret = wm8994_i2c_write(priv, reg, new); if (ret < 0) return ret; @@ -151,12 +145,13 @@ static int wm8994_update_bits(unsigned int reg, unsigned short mask, /* * Sets i2s set format * + * @param priv wm8994 information * @param aif_id Interface ID * @param fmt i2S format * * @return -1 for error and 0 Success. */ -int wm8994_set_fmt(int aif_id, unsigned int fmt) +static int wm8994_set_fmt(struct wm8994_priv *priv, int aif_id, uint fmt) { int ms_reg; int aif_reg; @@ -254,12 +249,13 @@ int wm8994_set_fmt(int aif_id, unsigned int fmt) return -1; } - error = wm8994_update_bits(aif_reg, WM8994_AIF1_BCLK_INV | - WM8994_AIF1_LRCLK_INV_MASK | WM8994_AIF1_FMT_MASK, aif); + error = wm8994_bic_or(priv, aif_reg, WM8994_AIF1_BCLK_INV | + WM8994_AIF1_LRCLK_INV_MASK | + WM8994_AIF1_FMT_MASK, aif); - error |= wm8994_update_bits(ms_reg, WM8994_AIF1_MSTR_MASK, ms); - error |= wm8994_update_bits(aif_clk, WM8994_AIF1CLK_ENA_MASK, - WM8994_AIF1CLK_ENA); + error |= wm8994_bic_or(priv, ms_reg, WM8994_AIF1_MSTR_MASK, ms); + error |= wm8994_bic_or(priv, aif_clk, WM8994_AIF1CLK_ENA_MASK, + WM8994_AIF1CLK_ENA); if (error < 0) { debug("%s: codec register access error\n", __func__); return -1; @@ -271,7 +267,7 @@ int wm8994_set_fmt(int aif_id, unsigned int fmt) /* * Sets hw params FOR WM8994 * - * @param wm8994 wm8994 information pointer + * @param priv wm8994 information pointer * @param aif_id Audio interface ID * @param sampling_rate Sampling rate * @param bits_per_sample Bits per sample @@ -279,9 +275,9 @@ int wm8994_set_fmt(int aif_id, unsigned int fmt) * * @return -1 for error and 0 Success. */ -static int wm8994_hw_params(struct wm8994_priv *wm8994, int aif_id, - unsigned int sampling_rate, unsigned int bits_per_sample, - unsigned int channels) +static int wm8994_hw_params(struct wm8994_priv *priv, int aif_id, + uint sampling_rate, uint bits_per_sample, + uint channels) { int aif1_reg; int aif2_reg; @@ -349,12 +345,10 @@ static int wm8994_hw_params(struct wm8994_priv *wm8994, int aif_id, /* AIFCLK/fs ratio; look for a close match in either direction */ best = 0; - best_val = abs((fs_ratios[0] * sampling_rate) - - wm8994->aifclk[id]); + best_val = abs((fs_ratios[0] * sampling_rate) - priv->aifclk[id]); for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) { - cur_val = abs((fs_ratios[i] * sampling_rate) - - wm8994->aifclk[id]); + cur_val = abs(fs_ratios[i] * sampling_rate - priv->aifclk[id]); if (cur_val >= best_val) continue; best = i; @@ -371,7 +365,7 @@ static int wm8994_hw_params(struct wm8994_priv *wm8994, int aif_id, */ best = 0; for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) { - cur_val = (wm8994->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate; + cur_val = (priv->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate; if (cur_val < 0) /* BCLK table is sorted */ break; best = i; @@ -383,10 +377,10 @@ static int wm8994_hw_params(struct wm8994_priv *wm8994, int aif_id, return -1; } - bclk_rate = wm8994->aifclk[id] * 10 / bclk_divs[best]; + bclk_rate = priv->aifclk[id] * 10 / bclk_divs[best]; bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT; - if (wm8994_i2c_read(aif1_reg, ®_data) != 0) { + if (wm8994_i2c_read(priv, aif1_reg, ®_data) != 0) { debug("%s: AIF1 register read Failed\n", __func__); return -1; } @@ -394,16 +388,17 @@ static int wm8994_hw_params(struct wm8994_priv *wm8994, int aif_id, if ((channels == 1) && ((reg_data & 0x18) == 0x18)) aif2 |= WM8994_AIF1_MONO; - if (wm8994->aifclk[id] == 0) { + if (priv->aifclk[id] == 0) { debug("%s:Audio interface clock not set\n", __func__); return -1; } - ret = wm8994_update_bits(aif1_reg, WM8994_AIF1_WL_MASK, aif1); - ret |= wm8994_update_bits(aif2_reg, WM8994_AIF1_MONO, aif2); - ret |= wm8994_update_bits(bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk); - ret |= wm8994_update_bits(rate_reg, WM8994_AIF1_SR_MASK | - WM8994_AIF1CLK_RATE_MASK, rate_val); + ret = wm8994_bic_or(priv, aif1_reg, WM8994_AIF1_WL_MASK, aif1); + ret |= wm8994_bic_or(priv, aif2_reg, WM8994_AIF1_MONO, aif2); + ret |= wm8994_bic_or(priv, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, + bclk); + ret |= wm8994_bic_or(priv, rate_reg, WM8994_AIF1_SR_MASK | + WM8994_AIF1CLK_RATE_MASK, rate_val); debug("rate vale = %x , bclk val= %x\n", rate_val, bclk); @@ -418,12 +413,12 @@ static int wm8994_hw_params(struct wm8994_priv *wm8994, int aif_id, /* * Configures Audio interface Clock * - * @param wm8994 wm8994 information pointer + * @param priv wm8994 information pointer * @param aif Audio Interface ID * * @return -1 for error and 0 Success. */ -static int configure_aif_clock(struct wm8994_priv *wm8994, int aif) +static int configure_aif_clock(struct wm8994_priv *priv, int aif) { int rate; int reg1 = 0; @@ -436,30 +431,30 @@ static int configure_aif_clock(struct wm8994_priv *wm8994, int aif) else offset = 0; - switch (wm8994->sysclk[aif-1]) { + switch (priv->sysclk[aif - 1]) { case WM8994_SYSCLK_MCLK1: reg1 |= SEL_MCLK1; - rate = wm8994->mclk[0]; + rate = priv->mclk[0]; break; case WM8994_SYSCLK_MCLK2: reg1 |= SEL_MCLK2; - rate = wm8994->mclk[1]; + rate = priv->mclk[1]; break; case WM8994_SYSCLK_FLL1: reg1 |= SEL_FLL1; - rate = wm8994->fll[0].out; + rate = priv->fll[0].out; break; case WM8994_SYSCLK_FLL2: reg1 |= SEL_FLL2; - rate = wm8994->fll[1].out; + rate = priv->fll[1].out; break; default: debug("%s: Invalid input clock selection [%d]\n", - __func__, wm8994->sysclk[aif-1]); + __func__, priv->sysclk[aif - 1]); return -1; } @@ -469,18 +464,18 @@ static int configure_aif_clock(struct wm8994_priv *wm8994, int aif) reg1 |= WM8994_AIF1CLK_DIV; } - wm8994->aifclk[aif-1] = rate; + priv->aifclk[aif - 1] = rate; - ret = wm8994_update_bits(WM8994_AIF1_CLOCKING_1 + offset, - WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV, - reg1); + ret = wm8994_bic_or(priv, WM8994_AIF1_CLOCKING_1 + offset, + WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV, + reg1); if (aif == WM8994_AIF1) - ret |= wm8994_update_bits(WM8994_CLOCKING_1, + ret |= wm8994_bic_or(priv, WM8994_CLOCKING_1, WM8994_AIF1DSPCLK_ENA_MASK | WM8994_SYSDSPCLK_ENA_MASK, WM8994_AIF1DSPCLK_ENA | WM8994_SYSDSPCLK_ENA); else if (aif == WM8994_AIF2) - ret |= wm8994_update_bits(WM8994_CLOCKING_1, + ret |= wm8994_bic_or(priv, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC | WM8994_AIF2DSPCLK_ENA_MASK | WM8994_SYSDSPCLK_ENA_MASK, WM8994_SYSCLK_SRC | WM8994_AIF2DSPCLK_ENA | WM8994_SYSDSPCLK_ENA); @@ -496,33 +491,33 @@ static int configure_aif_clock(struct wm8994_priv *wm8994, int aif) /* * Configures Audio interface for the given frequency * - * @param wm8994 wm8994 information + * @param priv wm8994 information * @param aif_id Audio Interface * @param clk_id Input Clock ID * @param freq Sampling frequency in Hz * * @return -1 for error and 0 success. */ -static int wm8994_set_sysclk(struct wm8994_priv *wm8994, int aif_id, - int clk_id, unsigned int freq) +static int wm8994_set_sysclk(struct wm8994_priv *priv, int aif_id, int clk_id, + unsigned int freq) { int i; int ret = 0; - wm8994->sysclk[aif_id - 1] = clk_id; + priv->sysclk[aif_id - 1] = clk_id; switch (clk_id) { case WM8994_SYSCLK_MCLK1: - wm8994->mclk[0] = freq; + priv->mclk[0] = freq; if (aif_id == 2) { - ret = wm8994_update_bits(WM8994_AIF1_CLOCKING_2 , - WM8994_AIF2DAC_DIV_MASK , 0); + ret = wm8994_bic_or(priv, WM8994_AIF1_CLOCKING_2, + WM8994_AIF2DAC_DIV_MASK, 0); } break; case WM8994_SYSCLK_MCLK2: /* TODO: Set GPIO AF */ - wm8994->mclk[1] = freq; + priv->mclk[1] = freq; break; case WM8994_SYSCLK_FLL1: @@ -543,13 +538,14 @@ static int wm8994_set_sysclk(struct wm8994_priv *wm8994, int aif_id, __func__); return -1; } - ret = wm8994_update_bits(WM8994_CLOCKING_2, + ret = wm8994_bic_or(priv, WM8994_CLOCKING_2, WM8994_OPCLK_DIV_MASK, i); - ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_2, - WM8994_OPCLK_ENA, WM8994_OPCLK_ENA); + ret |= wm8994_bic_or(priv, WM8994_POWER_MANAGEMENT_2, + WM8994_OPCLK_ENA, + WM8994_OPCLK_ENA); } else { - ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_2, - WM8994_OPCLK_ENA, 0); + ret |= wm8994_bic_or(priv, WM8994_POWER_MANAGEMENT_2, + WM8994_OPCLK_ENA, 0); } default: @@ -558,7 +554,7 @@ static int wm8994_set_sysclk(struct wm8994_priv *wm8994, int aif_id, return -1; } - ret |= configure_aif_clock(wm8994, aif_id); + ret |= configure_aif_clock(priv, aif_id); if (ret < 0) { debug("%s: codec register access error\n", __func__); @@ -571,37 +567,38 @@ static int wm8994_set_sysclk(struct wm8994_priv *wm8994, int aif_id, /* * Initializes Volume for AIF2 to HP path * + * @param priv wm8994 information * @returns -1 for error and 0 Success. * */ -static int wm8994_init_volume_aif2_dac1(void) +static int wm8994_init_volume_aif2_dac1(struct wm8994_priv *priv) { int ret; /* Unmute AIF2DAC */ - ret = wm8994_update_bits(WM8994_AIF2_DAC_FILTERS_1, - WM8994_AIF2DAC_MUTE_MASK, 0); + ret = wm8994_bic_or(priv, WM8994_AIF2_DAC_FILTERS_1, + WM8994_AIF2DAC_MUTE_MASK, 0); - ret |= wm8994_update_bits(WM8994_AIF2_DAC_LEFT_VOLUME, - WM8994_AIF2DAC_VU_MASK | WM8994_AIF2DACL_VOL_MASK, - WM8994_AIF2DAC_VU | 0xff); + ret |= wm8994_bic_or(priv, WM8994_AIF2_DAC_LEFT_VOLUME, + WM8994_AIF2DAC_VU_MASK | WM8994_AIF2DACL_VOL_MASK, + WM8994_AIF2DAC_VU | 0xff); - ret |= wm8994_update_bits(WM8994_AIF2_DAC_RIGHT_VOLUME, - WM8994_AIF2DAC_VU_MASK | WM8994_AIF2DACR_VOL_MASK, - WM8994_AIF2DAC_VU | 0xff); + ret |= wm8994_bic_or(priv, WM8994_AIF2_DAC_RIGHT_VOLUME, + WM8994_AIF2DAC_VU_MASK | WM8994_AIF2DACR_VOL_MASK, + WM8994_AIF2DAC_VU | 0xff); - ret |= wm8994_update_bits(WM8994_DAC1_LEFT_VOLUME, - WM8994_DAC1_VU_MASK | WM8994_DAC1L_VOL_MASK | - WM8994_DAC1L_MUTE_MASK, WM8994_DAC1_VU | 0xc0); + ret |= wm8994_bic_or(priv, WM8994_DAC1_LEFT_VOLUME, + WM8994_DAC1_VU_MASK | WM8994_DAC1L_VOL_MASK | + WM8994_DAC1L_MUTE_MASK, WM8994_DAC1_VU | 0xc0); - ret |= wm8994_update_bits(WM8994_DAC1_RIGHT_VOLUME, - WM8994_DAC1_VU_MASK | WM8994_DAC1R_VOL_MASK | - WM8994_DAC1R_MUTE_MASK, WM8994_DAC1_VU | 0xc0); + ret |= wm8994_bic_or(priv, WM8994_DAC1_RIGHT_VOLUME, + WM8994_DAC1_VU_MASK | WM8994_DAC1R_VOL_MASK | + WM8994_DAC1R_MUTE_MASK, WM8994_DAC1_VU | 0xc0); /* Head Phone Volume */ - ret |= wm8994_i2c_write(WM8994_LEFT_OUTPUT_VOLUME, 0x12D); - ret |= wm8994_i2c_write(WM8994_RIGHT_OUTPUT_VOLUME, 0x12D); + ret |= wm8994_i2c_write(priv, WM8994_LEFT_OUTPUT_VOLUME, 0x12D); + ret |= wm8994_i2c_write(priv, WM8994_RIGHT_OUTPUT_VOLUME, 0x12D); if (ret < 0) { debug("%s: codec register access error\n", __func__); @@ -614,26 +611,27 @@ static int wm8994_init_volume_aif2_dac1(void) /* * Initializes Volume for AIF1 to HP path * + * @param priv wm8994 information * @returns -1 for error and 0 Success. * */ -static int wm8994_init_volume_aif1_dac1(void) +static int wm8994_init_volume_aif1_dac1(struct wm8994_priv *priv) { int ret = 0; /* Unmute AIF1DAC */ - ret |= wm8994_i2c_write(WM8994_AIF1_DAC_FILTERS_1, 0x0000); + ret |= wm8994_i2c_write(priv, WM8994_AIF1_DAC_FILTERS_1, 0x0000); - ret |= wm8994_update_bits(WM8994_DAC1_LEFT_VOLUME, - WM8994_DAC1_VU_MASK | WM8994_DAC1L_VOL_MASK | - WM8994_DAC1L_MUTE_MASK, WM8994_DAC1_VU | 0xc0); + ret |= wm8994_bic_or(priv, WM8994_DAC1_LEFT_VOLUME, + WM8994_DAC1_VU_MASK | WM8994_DAC1L_VOL_MASK | + WM8994_DAC1L_MUTE_MASK, WM8994_DAC1_VU | 0xc0); - ret |= wm8994_update_bits(WM8994_DAC1_RIGHT_VOLUME, - WM8994_DAC1_VU_MASK | WM8994_DAC1R_VOL_MASK | - WM8994_DAC1R_MUTE_MASK, WM8994_DAC1_VU | 0xc0); + ret |= wm8994_bic_or(priv, WM8994_DAC1_RIGHT_VOLUME, + WM8994_DAC1_VU_MASK | WM8994_DAC1R_VOL_MASK | + WM8994_DAC1R_MUTE_MASK, WM8994_DAC1_VU | 0xc0); /* Head Phone Volume */ - ret |= wm8994_i2c_write(WM8994_LEFT_OUTPUT_VOLUME, 0x12D); - ret |= wm8994_i2c_write(WM8994_RIGHT_OUTPUT_VOLUME, 0x12D); + ret |= wm8994_i2c_write(priv, WM8994_LEFT_OUTPUT_VOLUME, 0x12D); + ret |= wm8994_i2c_write(priv, WM8994_RIGHT_OUTPUT_VOLUME, 0x12D); if (ret < 0) { debug("%s: codec register access error\n", __func__); @@ -646,93 +644,99 @@ static int wm8994_init_volume_aif1_dac1(void) /* * Intialise wm8994 codec device * - * @param wm8994 wm8994 information + * @param priv wm8994 information * * @returns -1 for error and 0 Success. */ -static int wm8994_device_init(struct wm8994_priv *wm8994, - enum en_audio_interface aif_id) +static int wm8994_device_init(struct wm8994_priv *priv) { const char *devname; unsigned short reg_data; int ret; - wm8994_i2c_write(WM8994_SOFTWARE_RESET, WM8994_SW_RESET);/* Reset */ + wm8994_i2c_write(priv, WM8994_SOFTWARE_RESET, WM8994_SW_RESET); - ret = wm8994_i2c_read(WM8994_SOFTWARE_RESET, ®_data); + ret = wm8994_i2c_read(priv, WM8994_SOFTWARE_RESET, ®_data); if (ret < 0) { debug("Failed to read ID register\n"); - goto err; + return ret; } if (reg_data == WM8994_ID) { devname = "WM8994"; - debug("Device registered as type %d\n", wm8994->type); - wm8994->type = WM8994; + debug("Device registered as type %d\n", priv->type); + priv->type = WM8994; } else { debug("Device is not a WM8994, ID is %x\n", ret); - ret = -1; - goto err; + return -ENXIO; } - ret = wm8994_i2c_read(WM8994_CHIP_REVISION, ®_data); + ret = wm8994_i2c_read(priv, WM8994_CHIP_REVISION, ®_data); if (ret < 0) { debug("Failed to read revision register: %d\n", ret); - goto err; + return ret; } - wm8994->revision = reg_data; - debug("%s revision %c\n", devname, 'A' + wm8994->revision); + priv->revision = reg_data; + debug("%s revision %c\n", devname, 'A' + priv->revision); + + return 0; +} + +static int wm8994_setup_interface(struct wm8994_priv *priv, + enum en_audio_interface aif_id) +{ + int ret; /* VMID Selection */ - ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_1, - WM8994_VMID_SEL_MASK | WM8994_BIAS_ENA_MASK, 0x3); + ret = wm8994_bic_or(priv, WM8994_POWER_MANAGEMENT_1, + WM8994_VMID_SEL_MASK | WM8994_BIAS_ENA_MASK, 0x3); /* Charge Pump Enable */ - ret |= wm8994_update_bits(WM8994_CHARGE_PUMP_1, WM8994_CP_ENA_MASK, - WM8994_CP_ENA); + ret |= wm8994_bic_or(priv, WM8994_CHARGE_PUMP_1, WM8994_CP_ENA_MASK, + WM8994_CP_ENA); /* Head Phone Power Enable */ - ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_1, - WM8994_HPOUT1L_ENA_MASK, WM8994_HPOUT1L_ENA); + ret |= wm8994_bic_or(priv, WM8994_POWER_MANAGEMENT_1, + WM8994_HPOUT1L_ENA_MASK, WM8994_HPOUT1L_ENA); - ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_1, - WM8994_HPOUT1R_ENA_MASK, WM8994_HPOUT1R_ENA); + ret |= wm8994_bic_or(priv, WM8994_POWER_MANAGEMENT_1, + WM8994_HPOUT1R_ENA_MASK, WM8994_HPOUT1R_ENA); if (aif_id == WM8994_AIF1) { - ret |= wm8994_i2c_write(WM8994_POWER_MANAGEMENT_2, + ret |= wm8994_i2c_write(priv, WM8994_POWER_MANAGEMENT_2, WM8994_TSHUT_ENA | WM8994_MIXINL_ENA | WM8994_MIXINR_ENA | WM8994_IN2L_ENA | WM8994_IN2R_ENA); - ret |= wm8994_i2c_write(WM8994_POWER_MANAGEMENT_4, + ret |= wm8994_i2c_write(priv, WM8994_POWER_MANAGEMENT_4, WM8994_ADCL_ENA | WM8994_ADCR_ENA | WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC1L_ENA); /* Power enable for AIF1 and DAC1 */ - ret |= wm8994_i2c_write(WM8994_POWER_MANAGEMENT_5, + ret |= wm8994_i2c_write(priv, WM8994_POWER_MANAGEMENT_5, WM8994_AIF1DACL_ENA | WM8994_AIF1DACR_ENA | WM8994_DAC1L_ENA | WM8994_DAC1R_ENA); } else if (aif_id == WM8994_AIF2) { /* Power enable for AIF2 and DAC1 */ - ret |= wm8994_update_bits(WM8994_POWER_MANAGEMENT_5, + ret |= wm8994_bic_or(priv, WM8994_POWER_MANAGEMENT_5, WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK | WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK, WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA | WM8994_DAC1L_ENA | WM8994_DAC1R_ENA); } /* Head Phone Initialisation */ - ret |= wm8994_update_bits(WM8994_ANALOGUE_HP_1, + ret |= wm8994_bic_or(priv, WM8994_ANALOGUE_HP_1, WM8994_HPOUT1L_DLY_MASK | WM8994_HPOUT1R_DLY_MASK, WM8994_HPOUT1L_DLY | WM8994_HPOUT1R_DLY); - ret |= wm8994_update_bits(WM8994_DC_SERVO_1, + ret |= wm8994_bic_or(priv, WM8994_DC_SERVO_1, WM8994_DCS_ENA_CHAN_0_MASK | WM8994_DCS_ENA_CHAN_1_MASK , WM8994_DCS_ENA_CHAN_0 | WM8994_DCS_ENA_CHAN_1); - ret |= wm8994_update_bits(WM8994_ANALOGUE_HP_1, + ret |= wm8994_bic_or(priv, WM8994_ANALOGUE_HP_1, WM8994_HPOUT1L_DLY_MASK | WM8994_HPOUT1R_DLY_MASK | WM8994_HPOUT1L_OUTP_MASK | WM8994_HPOUT1R_OUTP_MASK | @@ -743,172 +747,130 @@ static int wm8994_device_init(struct wm8994_priv *wm8994, WM8994_HPOUT1R_RMV_SHORT); /* MIXER Config DAC1 to HP */ - ret |= wm8994_update_bits(WM8994_OUTPUT_MIXER_1, - WM8994_DAC1L_TO_HPOUT1L_MASK, WM8994_DAC1L_TO_HPOUT1L); + ret |= wm8994_bic_or(priv, WM8994_OUTPUT_MIXER_1, + WM8994_DAC1L_TO_HPOUT1L_MASK, + WM8994_DAC1L_TO_HPOUT1L); - ret |= wm8994_update_bits(WM8994_OUTPUT_MIXER_2, - WM8994_DAC1R_TO_HPOUT1R_MASK, WM8994_DAC1R_TO_HPOUT1R); + ret |= wm8994_bic_or(priv, WM8994_OUTPUT_MIXER_2, + WM8994_DAC1R_TO_HPOUT1R_MASK, + WM8994_DAC1R_TO_HPOUT1R); if (aif_id == WM8994_AIF1) { /* Routing AIF1 to DAC1 */ - ret |= wm8994_i2c_write(WM8994_DAC1_LEFT_MIXER_ROUTING, - WM8994_AIF1DAC1L_TO_DAC1L); + ret |= wm8994_i2c_write(priv, WM8994_DAC1_LEFT_MIXER_ROUTING, + WM8994_AIF1DAC1L_TO_DAC1L); - ret |= wm8994_i2c_write(WM8994_DAC1_RIGHT_MIXER_ROUTING, + ret |= wm8994_i2c_write(priv, WM8994_DAC1_RIGHT_MIXER_ROUTING, WM8994_AIF1DAC1R_TO_DAC1R); /* GPIO Settings for AIF1 */ - ret |= wm8994_i2c_write(WM8994_GPIO_1, WM8994_GPIO_DIR_OUTPUT - | WM8994_GPIO_FUNCTION_I2S_CLK - | WM8994_GPIO_INPUT_DEBOUNCE); + ret |= wm8994_i2c_write(priv, WM8994_GPIO_1, + WM8994_GPIO_DIR_OUTPUT | + WM8994_GPIO_FUNCTION_I2S_CLK | + WM8994_GPIO_INPUT_DEBOUNCE); - ret |= wm8994_init_volume_aif1_dac1(); + ret |= wm8994_init_volume_aif1_dac1(priv); } else if (aif_id == WM8994_AIF2) { /* Routing AIF2 to DAC1 */ - ret |= wm8994_update_bits(WM8994_DAC1_LEFT_MIXER_ROUTING, - WM8994_AIF2DACL_TO_DAC1L_MASK, - WM8994_AIF2DACL_TO_DAC1L); + ret |= wm8994_bic_or(priv, WM8994_DAC1_LEFT_MIXER_ROUTING, + WM8994_AIF2DACL_TO_DAC1L_MASK, + WM8994_AIF2DACL_TO_DAC1L); - ret |= wm8994_update_bits(WM8994_DAC1_RIGHT_MIXER_ROUTING, - WM8994_AIF2DACR_TO_DAC1R_MASK, - WM8994_AIF2DACR_TO_DAC1R); + ret |= wm8994_bic_or(priv, WM8994_DAC1_RIGHT_MIXER_ROUTING, + WM8994_AIF2DACR_TO_DAC1R_MASK, + WM8994_AIF2DACR_TO_DAC1R); /* GPIO Settings for AIF2 */ /* B CLK */ - ret |= wm8994_update_bits(WM8994_GPIO_3, WM8994_GPIO_DIR_MASK | - WM8994_GPIO_FUNCTION_MASK , - WM8994_GPIO_DIR_OUTPUT); + ret |= wm8994_bic_or(priv, WM8994_GPIO_3, WM8994_GPIO_DIR_MASK | + WM8994_GPIO_FUNCTION_MASK, + WM8994_GPIO_DIR_OUTPUT); /* LR CLK */ - ret |= wm8994_update_bits(WM8994_GPIO_4, WM8994_GPIO_DIR_MASK | - WM8994_GPIO_FUNCTION_MASK, - WM8994_GPIO_DIR_OUTPUT); + ret |= wm8994_bic_or(priv, WM8994_GPIO_4, WM8994_GPIO_DIR_MASK | + WM8994_GPIO_FUNCTION_MASK, + WM8994_GPIO_DIR_OUTPUT); /* DATA */ - ret |= wm8994_update_bits(WM8994_GPIO_5, WM8994_GPIO_DIR_MASK | - WM8994_GPIO_FUNCTION_MASK, - WM8994_GPIO_DIR_OUTPUT); + ret |= wm8994_bic_or(priv, WM8994_GPIO_5, WM8994_GPIO_DIR_MASK | + WM8994_GPIO_FUNCTION_MASK, + WM8994_GPIO_DIR_OUTPUT); - ret |= wm8994_init_volume_aif2_dac1(); + ret |= wm8994_init_volume_aif2_dac1(priv); } if (ret < 0) goto err; - debug("%s: Codec chip init ok\n", __func__); + debug("%s: Codec chip setup ok\n", __func__); return 0; err: - debug("%s: Codec chip init error\n", __func__); + debug("%s: Codec chip setup error\n", __func__); return -1; } -/* - * Gets fdt values for wm8994 config parameters - * - * @param pcodec_info codec information structure - * @param blob FDT blob - * @return int value, 0 for success - */ -static int get_codec_values(struct sound_codec_info *pcodec_info, - const void *blob) +static int _wm8994_init(struct wm8994_priv *priv, + enum en_audio_interface aif_id, int sampling_rate, + int mclk_freq, int bits_per_sample, + unsigned int channels) { - int error = 0; -#if CONFIG_IS_ENABLED(OF_CONTROL) - enum fdt_compat_id compat; - int node; - int parent; - - /* Get the node from FDT for codec */ - node = fdtdec_next_compatible(blob, 0, COMPAT_WOLFSON_WM8994_CODEC); - if (node <= 0) { - debug("EXYNOS_SOUND: No node for codec in device tree\n"); - debug("node = %d\n", node); - return -1; - } + int ret; - parent = fdt_parent_offset(blob, node); - if (parent < 0) { - debug("%s: Cannot find node parent\n", __func__); - return -1; + ret = wm8994_setup_interface(priv, aif_id); + if (ret < 0) { + debug("%s: wm8994 codec chip init failed\n", __func__); + return ret; } - compat = fdtdec_lookup(blob, parent); - switch (compat) { - case COMPAT_SAMSUNG_S3C2440_I2C: - pcodec_info->i2c_bus = i2c_get_bus_num_fdt(parent); - error |= pcodec_info->i2c_bus; - debug("i2c bus = %d\n", pcodec_info->i2c_bus); - pcodec_info->i2c_dev_addr = fdtdec_get_int(blob, node, - "reg", 0); - error |= pcodec_info->i2c_dev_addr; - debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr); - break; - default: - debug("%s: Unknown compat id %d\n", __func__, compat); - return -1; + ret = wm8994_set_sysclk(priv, aif_id, WM8994_SYSCLK_MCLK1, mclk_freq); + if (ret < 0) { + debug("%s: wm8994 codec set sys clock failed\n", __func__); + return ret; } -#else - pcodec_info->i2c_bus = AUDIO_I2C_BUS; - pcodec_info->i2c_dev_addr = AUDIO_I2C_REG; - debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr); -#endif - pcodec_info->codec_type = CODEC_WM_8994; + ret = wm8994_hw_params(priv, aif_id, sampling_rate, bits_per_sample, + channels); - if (error == -1) { - debug("fail to get wm8994 codec node properties\n"); - return -1; + if (ret == 0) { + ret = wm8994_set_fmt(priv, aif_id, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS); } - return 0; + return ret; } -/* WM8994 Device Initialisation */ -int wm8994_init(const void *blob, enum en_audio_interface aif_id, - int sampling_rate, int mclk_freq, - int bits_per_sample, unsigned int channels) +static int wm8994_set_params(struct udevice *dev, int interface, int rate, + int mclk_freq, int bits_per_sample, uint channels) { - int ret = 0; - struct sound_codec_info *pcodec_info = &g_codec_info; + struct wm8994_priv *priv = dev_get_priv(dev); - /* Get the codec Values */ - if (get_codec_values(pcodec_info, blob) < 0) { - debug("FDT Codec values failed\n"); - return -1; - } - - /* shift the device address by 1 for 7 bit addressing */ - g_wm8994_i2c_dev_addr = pcodec_info->i2c_dev_addr; - wm8994_i2c_init(pcodec_info->i2c_bus); + return _wm8994_init(priv, interface, rate, mclk_freq, bits_per_sample, + channels); +} - if (pcodec_info->codec_type == CODEC_WM_8994) { - g_wm8994_info.type = WM8994; - } else { - debug("%s: Codec id [%d] not defined\n", __func__, - pcodec_info->codec_type); - return -1; - } +static int wm8994_probe(struct udevice *dev) +{ + struct wm8994_priv *priv = dev_get_priv(dev); - ret = wm8994_device_init(&g_wm8994_info, aif_id); - if (ret < 0) { - debug("%s: wm8994 codec chip init failed\n", __func__); - return ret; - } + priv->dev = dev; + return wm8994_device_init(priv); +} - ret = wm8994_set_sysclk(&g_wm8994_info, aif_id, WM8994_SYSCLK_MCLK1, - mclk_freq); - if (ret < 0) { - debug("%s: wm8994 codec set sys clock failed\n", __func__); - return ret; - } +static const struct audio_codec_ops wm8994_ops = { + .set_params = wm8994_set_params, +}; - ret = wm8994_hw_params(&g_wm8994_info, aif_id, sampling_rate, - bits_per_sample, channels); +static const struct udevice_id wm8994_ids[] = { + { .compatible = "wolfson,wm8994" }, + { } +}; - if (ret == 0) { - ret = wm8994_set_fmt(aif_id, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - } - return ret; -} +U_BOOT_DRIVER(wm8994) = { + .name = "wm8994", + .id = UCLASS_AUDIO_CODEC, + .of_match = wm8994_ids, + .probe = wm8994_probe, + .ops = &wm8994_ops, + .priv_auto_alloc_size = sizeof(struct wm8994_priv), +}; diff --git a/drivers/sound/wm8994.h b/drivers/sound/wm8994.h index ef2878f87ca..e36e6269f00 100644 --- a/drivers/sound/wm8994.h +++ b/drivers/sound/wm8994.h @@ -15,7 +15,7 @@ /* Avilable audi interface ports in wm8994 codec */ enum en_audio_interface { - WM8994_AIF1 = 1, + WM8994_AIF1, WM8994_AIF2, WM8994_AIF3 }; diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c index 5cca4144867..02d93763d42 100644 --- a/drivers/spi/designware_spi.c +++ b/drivers/spi/designware_spi.c @@ -369,7 +369,13 @@ static int poll_transfer(struct dw_spi_priv *priv) return 0; } -static void external_cs_manage(struct udevice *dev, bool on) +/* + * We define external_cs_manage function as 'weak' as some targets + * (like MSCC Ocelot) don't control the external CS pin using a GPIO + * controller. These SoCs use specific registers to control by + * software the SPI pins (and especially the CS). + */ +__weak void external_cs_manage(struct udevice *dev, bool on) { #if defined(CONFIG_DM_GPIO) && !defined(CONFIG_SPL_BUILD) struct dw_spi_priv *priv = dev_get_priv(dev->parent); diff --git a/drivers/tee/optee/supplicant.c b/drivers/tee/optee/supplicant.c index b1ea65bdb2e..c5726ecb91b 100644 --- a/drivers/tee/optee/supplicant.c +++ b/drivers/tee/optee/supplicant.c @@ -82,8 +82,8 @@ void optee_suppl_cmd(struct udevice *dev, struct tee_shm *shm_arg, cmd_shm_free(arg); break; case OPTEE_MSG_RPC_CMD_FS: - debug("OPTEE_MSG_RPC_CMD_FS not implemented\n"); - arg->ret = TEE_ERROR_NOT_IMPLEMENTED; + debug("REE FS storage isn't available\n"); + arg->ret = TEE_ERROR_STORAGE_NOT_AVAILABLE; break; case OPTEE_MSG_RPC_CMD_RPMB: optee_suppl_cmd_rpmb(dev, arg); diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index b0e6f32f0bc..df37a798bdc 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -126,6 +126,13 @@ config OMAP_TIMER help Select this to enable an timer for Omap devices. +config RISCV_TIMER + bool "RISC-V timer support" + depends on TIMER && RISCV + help + Select this to enable support for the timer as defined + by the RISC-V privileged architecture spec. + config ROCKCHIP_TIMER bool "Rockchip timer support" depends on TIMER diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile index c4fbab2aaca..d0bf218b114 100644 --- a/drivers/timer/Makefile +++ b/drivers/timer/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence-ttc.o obj-$(CONFIG_DESIGNWARE_APB_TIMER) += dw-apb-timer.o obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o obj-$(CONFIG_OMAP_TIMER) += omap-timer.o +obj-$(CONFIG_RISCV_TIMER) += riscv_timer.o obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o obj-$(CONFIG_SANDBOX_TIMER) += sandbox_timer.o obj-$(CONFIG_STI_TIMER) += sti-timer.o diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c new file mode 100644 index 00000000000..9f9f070e0b3 --- /dev/null +++ b/drivers/timer/riscv_timer.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + * + * RISC-V privileged architecture defined generic timer driver + * + * This driver relies on RISC-V platform codes to provide the essential API + * riscv_get_time() which is supposed to return the timer counter as defined + * by the RISC-V privileged architecture spec. + * + * This driver can be used in both M-mode and S-mode U-Boot. + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <timer.h> +#include <asm/io.h> + +/** + * riscv_get_time() - get the timer counter + * + * Platform codes should provide this API in order to make this driver function. + * + * @time: the 64-bit timer count as defined by the RISC-V privileged + * architecture spec. + * @return: 0 on success, -ve on error. + */ +extern int riscv_get_time(u64 *time); + +static int riscv_timer_get_count(struct udevice *dev, u64 *count) +{ + return riscv_get_time(count); +} + +static int riscv_timer_probe(struct udevice *dev) +{ + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + /* clock frequency was passed from the cpu driver as driver data */ + uc_priv->clock_rate = dev->driver_data; + + return 0; +} + +static const struct timer_ops riscv_timer_ops = { + .get_count = riscv_timer_get_count, +}; + +U_BOOT_DRIVER(riscv_timer) = { + .name = "riscv_timer", + .id = UCLASS_TIMER, + .probe = riscv_timer_probe, + .ops = &riscv_timer_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 98f83433bed..3b53bf2c58a 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -49,7 +49,7 @@ config DM_USB config SPL_DM_USB bool "Enable driver model for USB in SPL" - depends on DM_USB + depends on SPL_DM && DM_USB default y config DM_USB_GADGET diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index bc6bba198e9..3e6c494dc62 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -342,7 +342,9 @@ static int dwc3_glue_remove(struct udevice *dev) static const struct udevice_id dwc3_glue_ids[] = { { .compatible = "xlnx,zynqmp-dwc3" }, + { .compatible = "ti,keystone-dwc3"}, { .compatible = "ti,dwc3", .data = (ulong)&ti_ops }, + { .compatible = "ti,am437x-dwc3", .data = (ulong)&ti_ops }, { } }; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index e340cb268fc..085f7b89688 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -16,7 +16,6 @@ #include <common.h> #include <malloc.h> #include <asm/dma-mapping.h> -#include <usb/lin_gadget_compat.h> #include <linux/bug.h> #include <linux/list.h> diff --git a/drivers/usb/dwc3/ti_usb_phy.c b/drivers/usb/dwc3/ti_usb_phy.c index d168e868e35..e7ea12c163a 100644 --- a/drivers/usb/dwc3/ti_usb_phy.c +++ b/drivers/usb/dwc3/ti_usb_phy.c @@ -19,7 +19,6 @@ #include <common.h> #include <malloc.h> #include <ti-usb-phy-uboot.h> -#include <usb/lin_gadget_compat.h> #include <linux/ioport.h> #include <asm/io.h> #include <asm/arch/sys_proto.h> diff --git a/drivers/usb/eth/r8152.c b/drivers/usb/eth/r8152.c index 941158abdd3..e5f73e3d4c0 100644 --- a/drivers/usb/eth/r8152.c +++ b/drivers/usb/eth/r8152.c @@ -10,7 +10,6 @@ #include <malloc.h> #include <memalign.h> #include <usb.h> -#include <usb/lin_gadget_compat.h> #include <linux/mii.h> #include <linux/bitops.h> #include "usb_ether.h" diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 39ea87005cb..2a6626b4431 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -24,7 +24,6 @@ #include <linux/usb/gadget.h> #include <linux/usb/at91_udc.h> #include <malloc.h> -#include <usb/lin_gadget_compat.h> #include "at91_udc.h" diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index c9d483318fe..dffa5117f9c 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -16,7 +16,6 @@ #include <linux/usb/gadget.h> #include <linux/usb/atmel_usba_udc.h> #include <malloc.h> -#include <usb/lin_gadget_compat.h> #include "atmel_usba_udc.h" diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 5106cc56cb6..c7e76237475 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -735,8 +735,21 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) case USB_DT_DEVICE: cdev->desc.bNumConfigurations = count_configs(cdev, USB_DT_DEVICE); - cdev->desc.bMaxPacketSize0 = - cdev->gadget->ep0->maxpacket; + + /* + * If the speed is Super speed, then the supported + * max packet size is 512 and it should be sent as + * exponent of 2. So, 9(2^9=512) should be filled in + * bMaxPacketSize0. Also fill USB version as 3.0 + * if speed is Super speed. + */ + if (cdev->gadget->speed == USB_SPEED_SUPER) { + cdev->desc.bMaxPacketSize0 = 9; + cdev->desc.bcdUSB = cpu_to_le16(0x0300); + } else { + cdev->desc.bMaxPacketSize0 = + cdev->gadget->ep0->maxpacket; + } value = min(w_length, (u16) sizeof cdev->desc); memcpy(req->buf, &cdev->desc, value); break; diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c index e3edd10e29c..3c7ad033e3f 100644 --- a/drivers/usb/gadget/dwc2_udc_otg.c +++ b/drivers/usb/gadget/dwc2_udc_otg.c @@ -33,7 +33,6 @@ #include "dwc2_udc_otg_regs.h" #include "dwc2_udc_otg_priv.h" -#include <usb/lin_gadget_compat.h> /***********************************************************/ diff --git a/drivers/usb/gadget/dwc2_udc_otg_phy.c b/drivers/usb/gadget/dwc2_udc_otg_phy.c index 47aa78ae947..c4338af0d73 100644 --- a/drivers/usb/gadget/dwc2_udc_otg_phy.c +++ b/drivers/usb/gadget/dwc2_udc_otg_phy.c @@ -33,7 +33,6 @@ #include "dwc2_udc_otg_regs.h" #include "dwc2_udc_otg_priv.h" -#include <usb/lin_gadget_compat.h> #include <usb/dwc2_udc.h> diff --git a/drivers/usb/gadget/dwc2_udc_otg_priv.h b/drivers/usb/gadget/dwc2_udc_otg_priv.h index b64e222b6d7..aaa90187fb7 100644 --- a/drivers/usb/gadget/dwc2_udc_otg_priv.h +++ b/drivers/usb/gadget/dwc2_udc_otg_priv.h @@ -12,7 +12,6 @@ #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> #include <linux/list.h> -#include <usb/lin_gadget_compat.h> #include <usb/dwc2_udc.h> /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index a3101afa0df..45c7b58eed4 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -256,7 +256,7 @@ #include <linux/usb/gadget.h> #include <linux/usb/gadget.h> #include <linux/usb/composite.h> -#include <usb/lin_gadget_compat.h> +#include <linux/bitmap.h> #include <g_dnl.h> /*------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c index 00a9f88a418..ae97ab2b497 100644 --- a/drivers/usb/gadget/f_sdp.c +++ b/drivers/usb/gadget/f_sdp.c @@ -100,6 +100,7 @@ struct f_sdp { enum sdp_state state; enum sdp_state next_state; u32 dnl_address; + u32 dnl_bytes; u32 dnl_bytes_remaining; u32 jmp_address; bool always_send_status; @@ -276,6 +277,7 @@ static void sdp_rx_command_complete(struct usb_ep *ep, struct usb_request *req) sdp->state = SDP_STATE_RX_FILE_DATA; sdp->dnl_address = be32_to_cpu(cmd->addr); sdp->dnl_bytes_remaining = be32_to_cpu(cmd->cnt); + sdp->dnl_bytes = sdp->dnl_bytes_remaining; sdp->next_state = SDP_STATE_IDLE; printf("Downloading file of size %d to 0x%08x... ", @@ -355,6 +357,9 @@ static void sdp_rx_data_complete(struct usb_ep *ep, struct usb_request *req) if (sdp->dnl_bytes_remaining) return; +#ifndef CONFIG_SPL_BUILD + env_set_hex("filesize", sdp->dnl_bytes); +#endif printf("done\n"); switch (sdp->state) { diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 44092df25ba..09c0a30b2ba 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -29,7 +29,6 @@ #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> -#include <usb/lin_gadget_compat.h> #include <asm/arch/pxa-regs.h> #include "pxa25x_udc.h" diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 285c20ae863..948683a52b4 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -50,7 +50,6 @@ obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o -obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o obj-$(CONFIG_USB_XHCI_FSL) += xhci-fsl.o obj-$(CONFIG_USB_XHCI_MVEBU) += xhci-mvebu.o diff --git a/drivers/usb/host/xhci-keystone.c b/drivers/usb/host/xhci-keystone.c deleted file mode 100644 index 200b3f0e104..00000000000 --- a/drivers/usb/host/xhci-keystone.c +++ /dev/null @@ -1,240 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * USB 3.0 DRD Controller - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, <www.ti.com> - */ - -#include <common.h> -#include <watchdog.h> -#include <usb.h> -#include <asm/arch/psc_defs.h> -#include <asm/io.h> -#include <linux/usb/dwc3.h> -#include <asm/arch/xhci-keystone.h> -#include <linux/errno.h> -#include <linux/list.h> -#include "xhci.h" - -struct kdwc3_irq_regs { - u32 revision; /* 0x000 */ - u32 rsvd0[3]; - u32 sysconfig; /* 0x010 */ - u32 rsvd1[1]; - u32 irq_eoi; - u32 rsvd2[1]; - struct { - u32 raw_status; - u32 status; - u32 enable_set; - u32 enable_clr; - } irqs[16]; -}; - -struct keystone_xhci { - struct xhci_hccr *hcd; - struct dwc3 *dwc3_reg; - struct xhci_hcor *hcor; - struct kdwc3_irq_regs *usbss; - struct keystone_xhci_phy *phy; -}; - -struct keystone_xhci keystone; - -static void keystone_xhci_phy_set(struct keystone_xhci_phy *phy) -{ - u32 val; - - /* - * VBUSVLDEXTSEL has a default value of 1 in BootCfg but shouldn't. - * It should always be cleared because our USB PHY has an onchip VBUS - * analog comparator. - */ - val = readl(&phy->phy_clock); - /* quit selecting the vbusvldextsel by default! */ - val &= ~USB3_PHY_OTG_VBUSVLDECTSEL; - writel(val, &phy->phy_clock); -} - -static void keystone_xhci_phy_unset(struct keystone_xhci_phy *phy) -{ - u32 val; - - /* Disable the PHY REFCLK clock gate */ - val = readl(&phy->phy_clock); - val &= ~USB3_PHY_REF_SSP_EN; - writel(val, &phy->phy_clock); -} - -static int keystone_xhci_core_init(struct dwc3 *dwc3_reg) -{ - int ret; - - ret = dwc3_core_init(dwc3_reg); - if (ret) { - debug("failed to initialize core\n"); - return -EINVAL; - } - - /* We are hard-coding DWC3 core to Host Mode */ - dwc3_set_mode(dwc3_reg, DWC3_GCTL_PRTCAP_HOST); - - return 0; -} - -int xhci_hcd_init(int index, - struct xhci_hccr **ret_hccr, struct xhci_hcor **ret_hcor) -{ - u32 val; - int ret; - struct xhci_hccr *hcd; - struct xhci_hcor *hcor; - struct kdwc3_irq_regs *usbss; - struct keystone_xhci_phy *phy; - - usbss = (struct kdwc3_irq_regs *)CONFIG_USB_SS_BASE; - phy = (struct keystone_xhci_phy *)CONFIG_DEV_USB_PHY_BASE; - - /* Enable the PHY REFCLK clock gate with phy_ref_ssp_en = 1 */ - val = readl(&(phy->phy_clock)); - val |= USB3_PHY_REF_SSP_EN; - writel(val, &phy->phy_clock); - - mdelay(100); - - /* Release USB from reset */ - ret = psc_enable_module(KS2_LPSC_USB); - if (ret) { - puts("Cannot enable USB module"); - return -1; - } - - mdelay(100); - - /* Initialize usb phy */ - keystone_xhci_phy_set(phy); - - /* soft reset usbss */ - writel(1, &usbss->sysconfig); - while (readl(&usbss->sysconfig) & 1) - ; - - val = readl(&usbss->revision); - debug("usbss revision %x\n", val); - - /* Initialize usb core */ - hcd = (struct xhci_hccr *)CONFIG_USB_HOST_XHCI_BASE; - keystone.dwc3_reg = (struct dwc3 *)(CONFIG_USB_HOST_XHCI_BASE + - DWC3_REG_OFFSET); - - keystone_xhci_core_init(keystone.dwc3_reg); - - /* set register addresses */ - hcor = (struct xhci_hcor *)((uint32_t)hcd + - HC_LENGTH(readl(&hcd->cr_capbase))); - - debug("Keystone2-xhci: init hccr %08x and hcor %08x hc_length %d\n", - (u32)hcd, (u32)hcor, - (u32)HC_LENGTH(xhci_readl(&hcd->cr_capbase))); - - keystone.usbss = usbss; - keystone.phy = phy; - keystone.hcd = hcd; - keystone.hcor = hcor; - - *ret_hccr = hcd; - *ret_hcor = hcor; - - return 0; -} - -static int keystone_xhci_phy_suspend(void) -{ - int loop_cnt = 0; - struct xhci_hcor *hcor; - uint32_t *portsc_1 = NULL; - uint32_t *portsc_2 = NULL; - u32 val, usb2_pls, usb3_pls, event_q; - struct dwc3 *dwc3_reg = keystone.dwc3_reg; - - /* set register addresses */ - hcor = keystone.hcor; - - /* Bypass Scrambling and Set Shorter Training sequence for simulation */ - val = DWC3_GCTL_PWRDNSCALE(0x4b0) | DWC3_GCTL_PRTCAPDIR(0x2); - writel(val, &dwc3_reg->g_ctl); - - /* GUSB2PHYCFG */ - val = readl(&dwc3_reg->g_usb2phycfg[0]); - - /* assert bit 6 (SusPhy) */ - val |= DWC3_GUSB2PHYCFG_SUSPHY; - writel(val, &dwc3_reg->g_usb2phycfg[0]); - - /* GUSB3PIPECTL */ - val = readl(&dwc3_reg->g_usb3pipectl[0]); - - /* - * assert bit 29 to allow PHY to go to suspend when idle - * and cause the USB3 SS PHY to enter suspend mode - */ - val |= (BIT(29) | DWC3_GUSB3PIPECTL_SUSPHY); - writel(val, &dwc3_reg->g_usb3pipectl[0]); - - /* - * Steps necessary to allow controller to suspend even when - * VBUS is HIGH: - * - Init DCFG[2:0] (DevSpd) to: 1=FS - * - Init GEVNTADR0 to point to an eventQ - * - Init GEVNTSIZ0 to 0x0100 to specify the size of the eventQ - * - Init DCTL::Run_nStop = 1 - */ - writel(0x00020001, &dwc3_reg->d_cfg); - /* TODO: local2global( (Uint32) eventQ )? */ - writel((u32)&event_q, &dwc3_reg->g_evnt_buf[0].g_evntadrlo); - writel(0, &dwc3_reg->g_evnt_buf[0].g_evntadrhi); - writel(0x4, &dwc3_reg->g_evnt_buf[0].g_evntsiz); - /* Run */ - writel(DWC3_DCTL_RUN_STOP, &dwc3_reg->d_ctl); - - mdelay(100); - - /* Wait for USB2 & USB3 PORTSC::PortLinkState to indicate suspend */ - portsc_1 = (uint32_t *)(&hcor->portregs[0].or_portsc); - portsc_2 = (uint32_t *)(&hcor->portregs[1].or_portsc); - usb2_pls = 0; - usb3_pls = 0; - do { - ++loop_cnt; - usb2_pls = (readl(portsc_1) & PORT_PLS_MASK) >> 5; - usb3_pls = (readl(portsc_2) & PORT_PLS_MASK) >> 5; - } while (((usb2_pls != 0x4) || (usb3_pls != 0x4)) && loop_cnt < 1000); - - if (usb2_pls != 0x4 || usb3_pls != 0x4) { - debug("USB suspend failed - PLS USB2=%02x, USB3=%02x\n", - usb2_pls, usb3_pls); - return -1; - } - - debug("USB2 and USB3 PLS - Disabled, loop_cnt=%d\n", loop_cnt); - return 0; -} - -void xhci_hcd_stop(int index) -{ - /* Disable USB */ - if (keystone_xhci_phy_suspend()) - return; - - if (psc_disable_module(KS2_LPSC_USB)) { - debug("PSC disable module USB failed!\n"); - return; - } - - /* Disable PHY */ - keystone_xhci_phy_unset(keystone.phy); - -/* memset(&keystone, 0, sizeof(struct keystone_xhci)); */ - debug("xhci_hcd_stop OK.\n"); -} diff --git a/drivers/usb/musb-new/am35x.c b/drivers/usb/musb-new/am35x.c index 251b4e99692..bda099c63f4 100644 --- a/drivers/usb/musb-new/am35x.c +++ b/drivers/usb/musb-new/am35x.c @@ -406,7 +406,7 @@ static int am35x_musb_init(struct musb *musb) musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK); /* Start the on-chip PHY and its PLL. */ - if (data->set_phy_power) + if (data && data->set_phy_power) data->set_phy_power(data->dev, 1); msleep(5); @@ -437,7 +437,7 @@ static int am35x_musb_exit(struct musb *musb) #endif /* Shutdown the on-chip PHY and its PLL. */ - if (data->set_phy_power) + if (data && data->set_phy_power) data->set_phy_power(data->dev, 0); #ifndef __UBOOT__ @@ -628,7 +628,7 @@ static int am35x_suspend(struct device *dev) struct omap_musb_board_data *data = plat->board_data; /* Shutdown the on-chip PHY and its PLL. */ - if (data->set_phy_power) + if (data && data->set_phy_power) data->set_phy_power(data->dev, 0); clk_disable(glue->phy_clk); @@ -645,7 +645,7 @@ static int am35x_resume(struct device *dev) int ret; /* Start the on-chip PHY and its PLL. */ - if (data->set_phy_power) + if (data && data->set_phy_power) data->set_phy_power(data->dev, 1); ret = clk_enable(glue->phy_clk); diff --git a/drivers/usb/musb-new/musb_dsps.c b/drivers/usb/musb-new/musb_dsps.c index 9b814f4cd4a..0c794b310a3 100644 --- a/drivers/usb/musb-new/musb_dsps.c +++ b/drivers/usb/musb-new/musb_dsps.c @@ -450,7 +450,7 @@ static int dsps_musb_init(struct musb *musb) dsps_writel(reg_base, wrp->control, (1 << wrp->reset)); /* Start the on-chip PHY and its PLL. */ - if (data->set_phy_power) + if (data && data->set_phy_power) data->set_phy_power(data->dev, 1); musb->isr = dsps_interrupt; @@ -491,7 +491,7 @@ static int dsps_musb_exit(struct musb *musb) #endif /* Shutdown the on-chip PHY and its PLL. */ - if (data->set_phy_power) + if (data && data->set_phy_power) data->set_phy_power(data->dev, 0); #ifndef __UBOOT__ @@ -691,7 +691,7 @@ static int dsps_suspend(struct device *dev) struct omap_musb_board_data *data = plat->board_data; /* Shutdown the on-chip PHY and its PLL. */ - if (data->set_phy_power) + if (data && data->set_phy_power) data->set_phy_power(data->dev, 0); return 0; @@ -703,7 +703,7 @@ static int dsps_resume(struct device *dev) struct omap_musb_board_data *data = plat->board_data; /* Start the on-chip PHY and its PLL. */ - if (data->set_phy_power) + if (data && data->set_phy_power) data->set_phy_power(data->dev, 1); return 0; diff --git a/drivers/usb/musb-new/musb_gadget.c b/drivers/usb/musb-new/musb_gadget.c index 8b6cec192fb..b35d33ffedf 100644 --- a/drivers/usb/musb-new/musb_gadget.c +++ b/drivers/usb/musb-new/musb_gadget.c @@ -1775,6 +1775,14 @@ static int musb_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *driver); static int musb_gadget_stop(struct usb_gadget *g, struct usb_gadget_driver *driver); +#else +static int musb_gadget_stop(struct usb_gadget *g) +{ + struct musb *musb = gadget_to_musb(g); + + musb_stop(musb); + return 0; +} #endif static const struct usb_gadget_ops musb_gadget_operations = { @@ -1787,6 +1795,9 @@ static const struct usb_gadget_ops musb_gadget_operations = { #ifndef __UBOOT__ .udc_start = musb_gadget_start, .udc_stop = musb_gadget_stop, +#else + .udc_start = musb_gadget_start, + .udc_stop = musb_gadget_stop, #endif }; diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c index d40772b1aa5..9c8cc6e5844 100644 --- a/drivers/usb/musb-new/musb_uboot.c +++ b/drivers/usb/musb-new/musb_uboot.c @@ -367,7 +367,7 @@ struct dm_usb_ops musb_usb_ops = { #endif /* CONFIG_IS_ENABLED(DM_USB) */ #endif /* CONFIG_USB_MUSB_HOST */ -#ifdef CONFIG_USB_MUSB_GADGET +#if defined(CONFIG_USB_MUSB_GADGET) && !CONFIG_IS_ENABLED(DM_USB_GADGET) static struct musb *gadget; int usb_gadget_handle_interrupts(int index) @@ -430,7 +430,7 @@ struct musb *musb_register(struct musb_hdrc_platform_data *plat, void *bdata, musbp = &musb_host.host; break; #endif -#ifdef CONFIG_USB_MUSB_GADGET +#if defined(CONFIG_USB_MUSB_GADGET) && !CONFIG_IS_ENABLED(DM_USB_GADGET) case MUSB_PERIPHERAL: musbp = &gadget; break; diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index d7170a3078c..f542a181fac 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -435,11 +435,14 @@ static int musb_usb_probe(struct udevice *dev) { struct sunxi_glue *glue = dev_get_priv(dev); struct musb_host_data *host = &glue->mdata; - struct usb_bus_priv *priv = dev_get_uclass_priv(dev); struct musb_hdrc_platform_data pdata; void *base = dev_read_addr_ptr(dev); int ret; +#ifdef CONFIG_USB_MUSB_HOST + struct usb_bus_priv *priv = dev_get_uclass_priv(dev); +#endif + if (!base) return -EINVAL; @@ -459,7 +462,6 @@ static int musb_usb_probe(struct udevice *dev) return ret; } - priv->desc_before_addr = true; memset(&pdata, 0, sizeof(pdata)); pdata.power = 250; @@ -467,6 +469,8 @@ static int musb_usb_probe(struct udevice *dev) pdata.config = glue->cfg->config; #ifdef CONFIG_USB_MUSB_HOST + priv->desc_before_addr = true; + pdata.mode = MUSB_HOST; host->host = musb_init_controller(&pdata, &glue->dev, base); if (!host->host) diff --git a/drivers/usb/musb-new/ti-musb.c b/drivers/usb/musb-new/ti-musb.c index ee0960704a0..20ca2731b49 100644 --- a/drivers/usb/musb-new/ti-musb.c +++ b/drivers/usb/musb-new/ti-musb.c @@ -20,22 +20,33 @@ DECLARE_GLOBAL_DATA_PTR; #if CONFIG_IS_ENABLED(DM_USB) - /* USB 2.0 PHY Control */ #define CM_PHY_PWRDN (1 << 0) #define CM_PHY_OTG_PWRDN (1 << 1) #define OTGVDET_EN (1 << 19) #define OTGSESSENDEN (1 << 20) +#define AM335X_USB0_CTRL 0x0 #define AM335X_USB1_CTRL 0x8 -struct ti_musb_platdata { - void *base; - void *ctrl_mod_base; - struct musb_hdrc_platform_data plat; - struct musb_hdrc_config musb_config; - struct omap_musb_board_data otg_board_data; -}; +static void ti_musb_set_phy_power(struct udevice *dev, u8 on) +{ + struct ti_musb_platdata *platdata = dev_get_platdata(dev); + + if (!platdata->ctrl_mod_base) + return; + + if (on) { + clrsetbits_le32(platdata->ctrl_mod_base, + CM_PHY_PWRDN | CM_PHY_OTG_PWRDN, + OTGVDET_EN | OTGSESSENDEN); + } else { + clrsetbits_le32(platdata->ctrl_mod_base, 0, + CM_PHY_PWRDN | CM_PHY_OTG_PWRDN); + } +} + +#if CONFIG_IS_ENABLED(OF_CONTROL) static int ti_musb_get_usb_index(int node) { @@ -64,20 +75,6 @@ static int ti_musb_get_usb_index(int node) return -ENOENT; } -static void ti_musb_set_phy_power(struct udevice *dev, u8 on) -{ - struct ti_musb_platdata *platdata = dev_get_platdata(dev); - - if (on) { - clrsetbits_le32(platdata->ctrl_mod_base, - CM_PHY_PWRDN | CM_PHY_OTG_PWRDN, - OTGVDET_EN | OTGSESSENDEN); - } else { - clrsetbits_le32(platdata->ctrl_mod_base, 0, - CM_PHY_PWRDN | CM_PHY_OTG_PWRDN); - } -} - static int ti_musb_ofdata_to_platdata(struct udevice *dev) { struct ti_musb_platdata *platdata = dev_get_platdata(dev); @@ -86,6 +83,7 @@ static int ti_musb_ofdata_to_platdata(struct udevice *dev) int phys; int ctrl_mod; int usb_index; + struct musb_hdrc_config *musb_config; platdata->base = (void *)devfdt_get_addr_index(dev, 1); @@ -96,38 +94,41 @@ static int ti_musb_ofdata_to_platdata(struct udevice *dev) switch (usb_index) { case 1: platdata->ctrl_mod_base += AM335X_USB1_CTRL; + break; case 0: + platdata->ctrl_mod_base += AM335X_USB0_CTRL; + break; default: break; } - platdata->musb_config.multipoint = fdtdec_get_int(fdt, node, - "mentor,multipoint", - -1); - if (platdata->musb_config.multipoint < 0) { + musb_config = malloc(sizeof(struct musb_hdrc_config)); + memset(musb_config, 0, sizeof(struct musb_hdrc_config)); + + musb_config->multipoint = fdtdec_get_int(fdt, node, + "mentor,multipoint", -1); + if (musb_config->multipoint < 0) { pr_err("MUSB multipoint DT entry missing\n"); return -ENOENT; } - platdata->musb_config.dyn_fifo = 1; + musb_config->dyn_fifo = 1; - platdata->musb_config.num_eps = fdtdec_get_int(fdt, node, - "mentor,num-eps", -1); - if (platdata->musb_config.num_eps < 0) { + musb_config->num_eps = fdtdec_get_int(fdt, node, "mentor,num-eps", + -1); + if (musb_config->num_eps < 0) { pr_err("MUSB num-eps DT entry missing\n"); return -ENOENT; } - platdata->musb_config.ram_bits = fdtdec_get_int(fdt, node, - "mentor,ram-bits", -1); - if (platdata->musb_config.ram_bits < 0) { + musb_config->ram_bits = fdtdec_get_int(fdt, node, "mentor,ram-bits", + -1); + if (musb_config->ram_bits < 0) { pr_err("MUSB ram-bits DT entry missing\n"); return -ENOENT; } - platdata->otg_board_data.set_phy_power = ti_musb_set_phy_power; - platdata->otg_board_data.dev = dev; - platdata->plat.config = &platdata->musb_config; + platdata->plat.config = musb_config; platdata->plat.power = fdtdec_get_int(fdt, node, "mentor,power", -1); if (platdata->plat.power < 0) { @@ -136,29 +137,27 @@ static int ti_musb_ofdata_to_platdata(struct udevice *dev) } platdata->plat.platform_ops = &musb_dsps_ops; - platdata->plat.board_data = &platdata->otg_board_data; return 0; } +#endif static int ti_musb_host_probe(struct udevice *dev) { struct musb_host_data *host = dev_get_priv(dev); struct ti_musb_platdata *platdata = dev_get_platdata(dev); struct usb_bus_priv *priv = dev_get_uclass_priv(dev); - struct omap_musb_board_data *otg_board_data; int ret; priv->desc_before_addr = true; - otg_board_data = &platdata->otg_board_data; - host->host = musb_init_controller(&platdata->plat, - (struct device *)otg_board_data, + NULL, platdata->base); if (!host->host) return -EIO; + ti_musb_set_phy_power(dev, 1); ret = musb_lowlevel_init(host); return ret; @@ -169,10 +168,12 @@ static int ti_musb_host_remove(struct udevice *dev) struct musb_host_data *host = dev_get_priv(dev); musb_stop(host->host); + ti_musb_set_phy_power(dev, 0); return 0; } +#if CONFIG_IS_ENABLED(OF_CONTROL) static int ti_musb_host_ofdata_to_platdata(struct udevice *dev) { struct ti_musb_platdata *platdata = dev_get_platdata(dev); @@ -190,11 +191,14 @@ static int ti_musb_host_ofdata_to_platdata(struct udevice *dev) return 0; } +#endif U_BOOT_DRIVER(ti_musb_host) = { .name = "ti-musb-host", .id = UCLASS_USB, +#if CONFIG_IS_ENABLED(OF_CONTROL) .ofdata_to_platdata = ti_musb_host_ofdata_to_platdata, +#endif .probe = ti_musb_host_probe, .remove = ti_musb_host_remove, .ops = &musb_usb_ops, @@ -202,6 +206,82 @@ U_BOOT_DRIVER(ti_musb_host) = { .priv_auto_alloc_size = sizeof(struct musb_host_data), }; +#if CONFIG_IS_ENABLED(DM_USB_GADGET) +struct ti_musb_peripheral { + struct musb *periph; +}; + +#if CONFIG_IS_ENABLED(OF_CONTROL) +static int ti_musb_peripheral_ofdata_to_platdata(struct udevice *dev) +{ + struct ti_musb_platdata *platdata = dev_get_platdata(dev); + const void *fdt = gd->fdt_blob; + int node = dev_of_offset(dev); + int ret; + + ret = ti_musb_ofdata_to_platdata(dev); + if (ret) { + pr_err("platdata dt parse error\n"); + return ret; + } + platdata->plat.mode = MUSB_PERIPHERAL; + + return 0; +} +#endif + +int dm_usb_gadget_handle_interrupts(struct udevice *dev) +{ + struct ti_musb_peripheral *priv = dev_get_priv(dev); + + priv->periph->isr(0, priv->periph); + + return 0; +} + +static int ti_musb_peripheral_probe(struct udevice *dev) +{ + struct ti_musb_peripheral *priv = dev_get_priv(dev); + struct ti_musb_platdata *platdata = dev_get_platdata(dev); + int ret; + + priv->periph = musb_init_controller(&platdata->plat, + NULL, + platdata->base); + if (!priv->periph) + return -EIO; + + ti_musb_set_phy_power(dev, 1); + musb_gadget_setup(priv->periph); + return usb_add_gadget_udc((struct device *)dev, &priv->periph->g); +} + +static int ti_musb_peripheral_remove(struct udevice *dev) +{ + struct ti_musb_peripheral *priv = dev_get_priv(dev); + + usb_del_gadget_udc(&priv->periph->g); + ti_musb_set_phy_power(dev, 0); + + return 0; +} + +U_BOOT_DRIVER(ti_musb_peripheral) = { + .name = "ti-musb-peripheral", + .id = UCLASS_USB_GADGET_GENERIC, +#if CONFIG_IS_ENABLED(OF_CONTROL) + .ofdata_to_platdata = ti_musb_peripheral_ofdata_to_platdata, +#endif + .probe = ti_musb_peripheral_probe, + .remove = ti_musb_peripheral_remove, + .ops = &musb_usb_ops, + .platdata_auto_alloc_size = sizeof(struct ti_musb_platdata), + .priv_auto_alloc_size = sizeof(struct ti_musb_peripheral), + .flags = DM_FLAG_PRE_RELOC, +}; +#endif + +#if CONFIG_IS_ENABLED(OF_CONTROL) static int ti_musb_wrapper_bind(struct udevice *parent) { const void *fdt = gd->fdt_blob; @@ -222,15 +302,23 @@ static int ti_musb_wrapper_bind(struct udevice *parent) switch (dr_mode) { case USB_DR_MODE_PERIPHERAL: /* Bind MUSB device */ + ret = device_bind_driver_to_node(parent, + "ti-musb-peripheral", + name, + offset_to_ofnode(node), + &dev); + if (ret) + pr_err("musb - not able to bind usb peripheral node\n"); break; case USB_DR_MODE_HOST: /* Bind MUSB host */ - ret = device_bind_driver_to_node(parent, "ti-musb-host", - name, offset_to_ofnode(node), &dev); - if (ret) { + ret = device_bind_driver_to_node(parent, + "ti-musb-host", + name, + offset_to_ofnode(node), + &dev); + if (ret) pr_err("musb - not able to bind usb host node\n"); - return ret; - } break; default: break; @@ -250,5 +338,6 @@ U_BOOT_DRIVER(ti_musb_wrapper) = { .of_match = ti_musb_ids, .bind = ti_musb_wrapper_bind, }; +#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ #endif /* CONFIG_IS_ENABLED(DM_USB) */ diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index dd42f69a6bf..2508b6ed0d1 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -11,17 +11,10 @@ config USB_MUSB_HCD config USB_MUSB_UDC bool "Legacy USB Device Controller" -config USB_DAVINCI - bool "Legacy MUSB DaVinci" - config USB_OMAP3 bool "Legacy MUSB OMAP3 / OMAP4" depends on ARCH_OMAP2PLUS -config USB_DA8XX - bool "Legacy MUSB DA8xx/OMAP-L1x" - depends on ARCH_DAVINCI - config USB_AM35X bool"Legacy MUSB AM35x" depends on ARCH_OMAP2PLUS && !USB_OMAP3 diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile index bdb3cd87f65..744f2cfaa29 100644 --- a/drivers/usb/musb/Makefile +++ b/drivers/usb/musb/Makefile @@ -5,7 +5,5 @@ obj-$(CONFIG_USB_MUSB_HCD) += musb_hcd.o musb_core.o obj-$(CONFIG_USB_MUSB_UDC) += musb_udc.o musb_core.o -obj-$(CONFIG_USB_DAVINCI) += davinci.o obj-$(CONFIG_USB_OMAP3) += omap3.o -obj-$(CONFIG_USB_DA8XX) += da8xx.o obj-$(CONFIG_USB_AM35X) += am35x.o diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c deleted file mode 100644 index a652a7c3c12..00000000000 --- a/drivers/usb/musb/da8xx.c +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * da8xx.c - TI's DA8xx platform specific usb wrapper functions. - * - * Author: Ajay Kumar Gupta <ajay.gupta@ti.com> - * - * Based on drivers/usb/musb/davinci.c - * - * Copyright (C) 2009 Texas Instruments Incorporated - */ -#include <common.h> - -#include "musb_core.h" -#include <asm/arch/da8xx-usb.h> - -/* MUSB platform configuration */ -struct musb_config musb_cfg = { - .regs = (struct musb_regs *)DA8XX_USB_OTG_CORE_BASE, - .timeout = DA8XX_USB_OTG_TIMEOUT, - .musb_speed = 0, -}; - -/* - * This function enables VBUS by driving the GPIO Bank4 Pin 15 high. - */ -static void enable_vbus(void) -{ - u32 value; - - /* configure GPIO bank4 pin 15 in output direction */ - value = readl(&davinci_gpio_bank45->dir); - writel((value & (~DA8XX_USB_VBUS_GPIO)), &davinci_gpio_bank45->dir); - - /* set GPIO bank4 pin 15 high to drive VBUS */ - value = readl(&davinci_gpio_bank45->set_data); - writel((value | DA8XX_USB_VBUS_GPIO), &davinci_gpio_bank45->set_data); -} - -/* - * Enable the usb0 phy. This initialization procedure is explained in - * the DA8xx USB user guide document. - */ -static u8 phy_on(void) -{ - u32 timeout; - u32 cfgchip2; - - cfgchip2 = readl(&davinci_syscfg_regs->cfgchip2); - - cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN | - CFGCHIP2_OTGMODE | CFGCHIP2_REFFREQ); - cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN | CFGCHIP2_PHY_PLLON | - CFGCHIP2_REFFREQ_24MHZ; - - writel(cfgchip2, &davinci_syscfg_regs->cfgchip2); - - /* wait until the usb phy pll locks */ - timeout = musb_cfg.timeout; - while (timeout--) - if (readl(&davinci_syscfg_regs->cfgchip2) & CFGCHIP2_PHYCLKGD) - return 1; - - /* USB phy was not turned on */ - return 0; -} - -/* - * Disable the usb phy - */ -static void phy_off(void) -{ - u32 cfgchip2; - - /* - * Power down the on-chip PHY. - */ - cfgchip2 = readl(&davinci_syscfg_regs->cfgchip2); - cfgchip2 &= ~CFGCHIP2_PHY_PLLON; - cfgchip2 |= CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN; - writel(cfgchip2, &davinci_syscfg_regs->cfgchip2); -} - -/* - * This function performs DA8xx platform specific initialization for usb0. - */ -int musb_platform_init(void) -{ - u32 revision; - - /* enable psc for usb2.0 */ - lpsc_on(33); - - /* enable usb vbus */ - enable_vbus(); - - /* reset the controller */ - writel(0x1, &da8xx_usb_regs->control); - udelay(5000); - - /* start the on-chip usb phy and its pll */ - if (phy_on() == 0) - return -1; - - /* Returns zero if e.g. not clocked */ - revision = readl(&da8xx_usb_regs->revision); - if (revision == 0) - return -1; - - /* Disable all interrupts */ - writel((DA8XX_USB_USBINT_MASK | DA8XX_USB_TXINT_MASK | - DA8XX_USB_RXINT_MASK), &da8xx_usb_regs->intmsk_set); - return 0; -} - -/* - * This function performs DA8xx platform specific deinitialization for usb0. - */ -void musb_platform_deinit(void) -{ - /* Turn of the phy */ - phy_off(); - - /* flush any interrupts */ - writel((DA8XX_USB_USBINT_MASK | DA8XX_USB_TXINT_MASK | - DA8XX_USB_RXINT_MASK), &da8xx_usb_regs->intmsk_clr); - writel(0, &da8xx_usb_regs->eoi); -} diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c deleted file mode 100644 index 46cdb5ad1f0..00000000000 --- a/drivers/usb/musb/davinci.c +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * TI's Davinci platform specific USB wrapper functions. - * - * Copyright (c) 2008 Texas Instruments - * - * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments - */ - -#include <common.h> -#include <asm/io.h> -#include "davinci.h" -#include <asm/arch/hardware.h> - -#if !defined(CONFIG_DV_USBPHY_CTL) -#define CONFIG_DV_USBPHY_CTL (USBPHY_SESNDEN | USBPHY_VBDTCTEN) -#endif - -/* MUSB platform configuration */ -struct musb_config musb_cfg = { - .regs = (struct musb_regs *)MENTOR_USB0_BASE, - .timeout = DAVINCI_USB_TIMEOUT, - .musb_speed = 0, -}; - -/* MUSB module register overlay */ -struct davinci_usb_regs *dregs; - -/* - * Enable the USB phy - */ -static u8 phy_on(void) -{ - u32 timeout; -#ifdef DAVINCI_DM365EVM - u32 val; -#endif - /* Wait until the USB phy is turned on */ -#ifdef DAVINCI_DM365EVM - writel(USBPHY_PHY24MHZ | USBPHY_SESNDEN | - USBPHY_VBDTCTEN, USBPHY_CTL_PADDR); -#else - writel(CONFIG_DV_USBPHY_CTL, USBPHY_CTL_PADDR); -#endif - timeout = musb_cfg.timeout; - -#ifdef DAVINCI_DM365EVM - /* Set the ownership of GIO33 to USB */ - val = readl(PINMUX4); - val &= ~(PINMUX4_USBDRVBUS_BITCLEAR); - val |= PINMUX4_USBDRVBUS_BITSET; - writel(val, PINMUX4); -#endif - while (timeout--) - if (readl(USBPHY_CTL_PADDR) & USBPHY_PHYCLKGD) - return 1; - - /* USB phy was not turned on */ - return 0; -} - -/* - * Disable the USB phy - */ -static void phy_off(void) -{ - /* powerdown the on-chip PHY and its oscillator */ - writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, USBPHY_CTL_PADDR); -} - -void __enable_vbus(void) -{ - /* - * nothing to do, vbus is handled through the cpu. - * Define this function in board code, if it is - * different on your board. - */ -} -void enable_vbus(void) - __attribute__((weak, alias("__enable_vbus"))); - -/* - * This function performs Davinci platform specific initialization for usb0. - */ -int musb_platform_init(void) -{ - u32 revision; - - /* enable USB VBUS */ - enable_vbus(); - - /* start the on-chip USB phy and its pll */ - if (!phy_on()) - return -1; - - /* reset the controller */ - dregs = (struct davinci_usb_regs *)DAVINCI_USB0_BASE; - writel(1, &dregs->ctrlr); - udelay(5000); - - /* Returns zero if e.g. not clocked */ - revision = readl(&dregs->version); - if (!revision) - return -1; - - /* Disable all interrupts */ - writel(DAVINCI_USB_USBINT_MASK | DAVINCI_USB_RXINT_MASK | - DAVINCI_USB_TXINT_MASK , &dregs->intmsksetr); - return 0; -} - -/* - * This function performs Davinci platform specific deinitialization for usb0. - */ -void musb_platform_deinit(void) -{ - /* Turn of the phy */ - phy_off(); - - /* flush any interrupts */ - writel(DAVINCI_USB_USBINT_MASK | DAVINCI_USB_TXINT_MASK | - DAVINCI_USB_RXINT_MASK , &dregs->intclrr); -} diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h deleted file mode 100644 index 29bb08c307a..00000000000 --- a/drivers/usb/musb/davinci.h +++ /dev/null @@ -1,73 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * TI's Davinci platform specific USB wrapper functions. - * - * Copyright (c) 2008 Texas Instruments - * - * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments - */ - -#ifndef __DAVINCI_USB_H__ -#define __DAVINCI_USB_H__ - -#include <asm/arch/hardware.h> -#include "musb_core.h" - -/* Base address of DAVINCI usb0 wrapper */ -#define DAVINCI_USB0_BASE 0x01C64000 - -/* Base address of DAVINCI musb core */ -#define MENTOR_USB0_BASE (DAVINCI_USB0_BASE+0x400) - -/* - * Davinci platform USB wrapper register overlay. Note: Only the required - * registers are included in this structure. It can be expanded as required. - */ -struct davinci_usb_regs { - u32 version; - u32 ctrlr; - u32 reserved[0x20]; - u32 intclrr; - u32 intmskr; - u32 intmsksetr; -}; - -#define DAVINCI_USB_TX_ENDPTS_MASK 0x1f /* ep0 + 4 tx */ -#define DAVINCI_USB_RX_ENDPTS_MASK 0x1e /* 4 rx */ -#define DAVINCI_USB_USBINT_SHIFT 16 -#define DAVINCI_USB_TXINT_SHIFT 0 -#define DAVINCI_USB_RXINT_SHIFT 8 -#define DAVINCI_INTR_DRVVBUS 0x0100 - -#define DAVINCI_USB_USBINT_MASK 0x01ff0000 /* 8 Mentor, DRVVBUS */ -#define DAVINCI_USB_TXINT_MASK \ - (DAVINCI_USB_TX_ENDPTS_MASK << DAVINCI_USB_TXINT_SHIFT) -#define DAVINCI_USB_RXINT_MASK \ - (DAVINCI_USB_RX_ENDPTS_MASK << DAVINCI_USB_RXINT_SHIFT) -#define MGC_BUSCTL_OFFSET(_bEnd, _bOffset) \ - (0x80 + (8*(_bEnd)) + (_bOffset)) - -/* Integrated highspeed/otg PHY */ -#define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34) -#define USBPHY_PHY24MHZ (1 << 13) -#define USBPHY_PHYCLKGD (1 << 8) -#define USBPHY_SESNDEN (1 << 7) /* v(sess_end) comparator */ -#define USBPHY_VBDTCTEN (1 << 6) /* v(bus) comparator */ -#define USBPHY_PHYPLLON (1 << 4) /* override pll suspend */ -#define USBPHY_CLKO1SEL (1 << 3) -#define USBPHY_OSCPDWN (1 << 2) -#define USBPHY_PHYPDWN (1 << 0) - -/* Timeout for Davinci USB module */ -#define DAVINCI_USB_TIMEOUT 0x3FFFFFF - -/* IO Expander I2C address and VBUS enable mask */ -#define IOEXP_I2C_ADDR 0x3A -#define IOEXP_VBUSEN_MASK 1 - -/* extern functions */ -extern void lpsc_on(unsigned int id); -extern int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len); -extern int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len); -extern void enable_vbus(void); -#endif /* __DAVINCI_USB_H__ */ diff --git a/drivers/usb/musb/musb_udc.c b/drivers/usb/musb/musb_udc.c index f1d6d858628..7620114bec4 100644 --- a/drivers/usb/musb/musb_udc.c +++ b/drivers/usb/musb/musb_udc.c @@ -46,8 +46,6 @@ #include "omap3.h" #elif defined(CONFIG_USB_AM35X) #include "am35x.h" -#elif defined(CONFIG_USB_DAVINCI) -#include "davinci.h" #endif /* Define MUSB_DEBUG for debugging */ diff --git a/fs/cbfs/cbfs.c b/fs/cbfs/cbfs.c index 0dce639b49c..7b2513cb24b 100644 --- a/fs/cbfs/cbfs.c +++ b/fs/cbfs/cbfs.c @@ -96,8 +96,7 @@ static int file_cbfs_next_file(u8 *start, u32 size, u32 align, } swap_file_header(&header, fileHeader); - if (header.offset < sizeof(struct cbfs_fileheader) || - header.offset > header.len) { + if (header.offset < sizeof(struct cbfs_fileheader)) { file_cbfs_result = CBFS_BAD_FILE; return -1; } @@ -190,8 +189,8 @@ void file_cbfs_init(uintptr_t end_of_rom) start_of_rom = (u8 *)(end_of_rom + 1 - cbfs_header.rom_size); - file_cbfs_fill_cache(start_of_rom + cbfs_header.offset, - cbfs_header.rom_size, cbfs_header.align); + file_cbfs_fill_cache(start_of_rom, cbfs_header.rom_size, + cbfs_header.align); if (file_cbfs_result == CBFS_SUCCESS) initialized = 1; } diff --git a/include/altera.h b/include/altera.h index ead5d3d810b..22d55cfd73e 100644 --- a/include/altera.h +++ b/include/altera.h @@ -39,6 +39,8 @@ enum altera_iface { fast_passive_parallel, /* fast passive parallel with security (FPPS) */ fast_passive_parallel_security, + /* secure device manager (SDM) mailbox */ + secure_device_manager_mailbox, /* insert all new types before this */ max_altera_iface_type, }; @@ -54,6 +56,8 @@ enum altera_family { Altera_StratixII, /* StratixV Family */ Altera_StratixV, + /* Stratix10 Family */ + Intel_FPGA_Stratix10, /* SoCFPGA Family */ Altera_SoCFPGA, @@ -116,4 +120,8 @@ int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size); int stratixv_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size); #endif +#ifdef CONFIG_FPGA_STRATIX10 +int stratix10_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size); +#endif + #endif /* _ALTERA_H_ */ diff --git a/include/audio_codec.h b/include/audio_codec.h new file mode 100644 index 00000000000..25870995469 --- /dev/null +++ b/include/audio_codec.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2018 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef __AUDIO_CODEC_H__ +#define __AUDIO_CODEC_H__ + +/* + * An audio codec turns digital data into sound with various parameters to + * control its operation. + */ + +/* Operations for sound */ +struct audio_codec_ops { + /** + * set_params() - Set audio codec parameters + * + * @dev: Sound device + * @inteface: Interface number to use on codec + * @rate: Sampling rate in Hz + * @mclk_freq: Codec clock frequency in Hz + * @bits_per_sample: Must be 16 or 24 + * @channels: Number of channels to use (1=mono, 2=stereo) + * @return 0 if OK, -ve on error + */ + int (*set_params)(struct udevice *dev, int interface, int rate, + int mclk_freq, int bits_per_sample, uint channels); +}; + +#define audio_codec_get_ops(dev) ((struct audio_codec_ops *)(dev)->driver->ops) + +/** + * audio_codec_set_params() - Set audio codec parameters + * + * @dev: Sound device + * @inteface: Interface number to use on codec + * @rate: Sampling rate in Hz + * @mclk_freq: Codec clock frequency in Hz + * @bits_per_sample: Must be 16 or 24 + * @channels: Number of channels to use (1=mono, 2=stereo) + * @return 0 if OK, -ve on error + */ +int audio_codec_set_params(struct udevice *dev, int interface, int rate, + int mclk_freq, int bits_per_sample, uint channels); + +#endif /* __AUDIO_CODEC_H__ */ diff --git a/include/bootm.h b/include/bootm.h index 0501414e0dc..dbd6f49c2df 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -35,6 +35,8 @@ typedef int boot_os_fn(int flag, int argc, char * const argv[], bootm_headers_t *images); extern boot_os_fn do_bootm_linux; +extern boot_os_fn do_bootm_vxworks; + int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); void lynxkdi_boot(image_header_t *hdr); diff --git a/include/cbfs.h b/include/cbfs.h index 1b88ec04ae5..bd1bf75bbfc 100644 --- a/include/cbfs.h +++ b/include/cbfs.h @@ -18,16 +18,26 @@ enum cbfs_result { }; enum cbfs_filetype { + CBFS_TYPE_BOOTBLOCK = 0x01, + CBFS_TYPE_CBFSHEADER = 0x02, CBFS_TYPE_STAGE = 0x10, CBFS_TYPE_PAYLOAD = 0x20, + CBFS_TYPE_FIT = 0x21, CBFS_TYPE_OPTIONROM = 0x30, CBFS_TYPE_BOOTSPLASH = 0x40, CBFS_TYPE_RAW = 0x50, CBFS_TYPE_VSA = 0x51, CBFS_TYPE_MBI = 0x52, CBFS_TYPE_MICROCODE = 0x53, - CBFS_COMPONENT_CMOS_DEFAULT = 0xaa, - CBFS_COMPONENT_CMOS_LAYOUT = 0x01aa + CBFS_TYPE_FSP = 0x60, + CBFS_TYPE_MRC = 0x61, + CBFS_TYPE_MMA = 0x62, + CBFS_TYPE_EFI = 0x63, + CBFS_TYPE_STRUCT = 0x70, + CBFS_TYPE_CMOS_DEFAULT = 0xaa, + CBFS_TYPE_SPD = 0xab, + CBFS_TYPE_MRC_CACHE = 0xac, + CBFS_TYPE_CMOS_LAYOUT = 0x01aa }; struct cbfs_header { diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index 5d5b09bbd1e..3bd96b921b7 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -253,7 +253,6 @@ #ifdef CONFIG_SPL_BUILD #undef CONFIG_DM_MMC #undef CONFIG_TIMER -#undef CONFIG_DM_USB #endif #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_USB_ETHER) diff --git a/include/configs/bmips_common.h b/include/configs/bmips_common.h index 39ca2e0bf3f..788f4af70da 100644 --- a/include/configs/bmips_common.h +++ b/include/configs/bmips_common.h @@ -6,6 +6,10 @@ #ifndef __CONFIG_BMIPS_COMMON_H #define __CONFIG_BMIPS_COMMON_H +/* ETH */ +#define CONFIG_PHY_RESET_DELAY 20 +#define CONFIG_SYS_RX_ETH_BUFFER 6 + /* UART */ #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ 230400, 500000, 1500000 } @@ -16,7 +20,7 @@ /* Memory usage */ #define CONFIG_SYS_MAXARGS 24 -#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) +#define CONFIG_SYS_MALLOC_LEN (2 * 1024 * 1024) #define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024) #define CONFIG_SYS_CBSIZE 512 diff --git a/include/configs/ci20.h b/include/configs/ci20.h new file mode 100644 index 00000000000..9a3621329dc --- /dev/null +++ b/include/configs/ci20.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * CI20 configuration + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + */ + +#ifndef __CONFIG_CI20_H__ +#define __CONFIG_CI20_H__ + +#define CONFIG_SKIP_LOWLEVEL_INIT + +/* Ingenic JZ4780 clock configuration. */ +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_MHZ 1200 +#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000) + +/* Memory configuration */ +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) +#define CONFIG_SYS_MALLOC_LEN (64 * 1024 * 1024) +#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024) + +#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* cached (KSEG0) address */ +#define CONFIG_SYS_INIT_SP_OFFSET 0x400000 +#define CONFIG_SYS_LOAD_ADDR 0x81000000 +#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR +#define CONFIG_SYS_MEMTEST_START 0x80000000 +#define CONFIG_SYS_MEMTEST_END 0x88000000 + +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE + +/* NS16550-ish UARTs */ +#define CONFIG_SYS_NS16550_CLK 48000000 +#define CONFIG_SYS_CONSOLE_IS_IN_ENV + +/* Ethernet: davicom DM9000 */ +#define CONFIG_DRIVER_DM9000 1 +#define CONFIG_DM9000_BASE 0xb6000000 +#define DM9000_IO CONFIG_DM9000_BASE +#define DM9000_DATA (CONFIG_DM9000_BASE + 2) + +/* Environment */ +#define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_ENV_SIZE (32 << 10) +#define CONFIG_ENV_OFFSET ((14 + 512) << 10) +#define CONFIG_ENV_OVERWRITE + +/* Command line configuration. */ +#define CONFIG_SYS_CBSIZE 1024 /* Console I/O buffer size */ +#define CONFIG_SYS_MAXARGS 32 /* Max number of command args */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + /* Boot argument buffer size */ +#define CONFIG_VERSION_VARIABLE /* U-BOOT version */ + +/* Miscellaneous configuration options */ +#define CONFIG_SYS_BOOTM_LEN (64 << 20) + +/* SPL */ +#define CONFIG_SPL_STACK 0xf4008000 /* only max. 2KB spare! */ + +#define CONFIG_SPL_TEXT_BASE 0xf4000a00 +#define CONFIG_SPL_MAX_SIZE ((14 * 1024) - 0xa00) + +#define CONFIG_SPL_BSS_START_ADDR 0xf4004000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x00002000 /* 512KB, arbitrary */ + +#define CONFIG_SPL_START_S_PATH "arch/mips/mach-jz47xx" + +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x1c /* 14 KiB offset */ + +#endif /* __CONFIG_CI20_H__ */ diff --git a/include/configs/edison.h b/include/configs/edison.h index 86c584d73dc..a6155ba5a8b 100644 --- a/include/configs/edison.h +++ b/include/configs/edison.h @@ -8,13 +8,6 @@ #include <asm/ibmpc.h> -/* ACPI */ - -/* Boot */ -#define CONFIG_BOOTCOMMAND "run bootcmd" - -/* DISK Partition support */ - /* Miscellaneous configurable options */ #define CONFIG_SYS_CBSIZE 2048 @@ -43,9 +36,6 @@ #define CONFIG_ENV_OFFSET_REDUND (6 * 1024 * 1024) #define CONFIG_SUPPORT_EMMC_BOOT -/* PCI */ -#define CONFIG_CMD_PCI - /* RTC */ #define CONFIG_SYS_ISA_IO_BASE_ADDRESS 0 diff --git a/include/configs/elgin_rv1108.h b/include/configs/elgin_rv1108.h new file mode 100644 index 00000000000..aa6c4b09e27 --- /dev/null +++ b/include/configs/elgin_rv1108.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2016 Rockchip Electronics Co., Ltd + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include <configs/rv1108_common.h> + +#define CONFIG_SYS_MMC_ENV_DEV 0 + +#endif diff --git a/include/configs/helios4.h b/include/configs/helios4.h index 3157225f067..4e98f19a403 100644 --- a/include/configs/helios4.h +++ b/include/configs/helios4.h @@ -118,7 +118,7 @@ #define CONFIG_SPL_SPI_FLASH_SUPPORT #define CONFIG_SPL_SPI_LOAD #define CONFIG_SPL_SPI_SUPPORT -#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x20000 +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x30000 #define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS #endif diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h index 68da920e300..ba763501cf2 100644 --- a/include/configs/mt7623.h +++ b/include/configs/mt7623.h @@ -46,7 +46,7 @@ /* DRAM */ #define CONFIG_SYS_SDRAM_BASE 0x80000000 -/* This is neede for kernel booting */ +/* This is needed for kernel booting */ #define FDT_HIGH "fdt_high=0xac000000\0" /* Extra environment variables */ diff --git a/include/configs/omap3_igep00x0.h b/include/configs/omap3_igep00x0.h index b9d65697521..775374cf288 100644 --- a/include/configs/omap3_igep00x0.h +++ b/include/configs/omap3_igep00x0.h @@ -20,10 +20,6 @@ #define CONFIG_REVISION_TAG 1 -/* GPIO banks */ -#define CONFIG_OMAP3_GPIO_2 /* GPIO32..63 is in GPIO bank 2 */ -#define CONFIG_OMAP3_GPIO_4 /* GPIO96..127 is in GPIO bank 4 */ - /* TPS65950 */ #define PBIASLITEVMODE1 (1 << 8) diff --git a/include/configs/ti_armv7_keystone2.h b/include/configs/ti_armv7_keystone2.h index 5e504f6d3d2..0c7d6648683 100644 --- a/include/configs/ti_armv7_keystone2.h +++ b/include/configs/ti_armv7_keystone2.h @@ -169,12 +169,16 @@ #define CONFIG_SYS_NAND_MAX_CHIPS 1 #define CONFIG_SYS_NAND_NO_SUBPAGE_WRITE -/* USB Configuration */ -#define CONFIG_USB_XHCI_KEYSTONE -#define CONFIG_USB_SS_BASE KS2_USB_SS_BASE -#define CONFIG_USB_HOST_XHCI_BASE KS2_USB_HOST_XHCI_BASE -#define CONFIG_DEV_USB_PHY_BASE KS2_DEV_USB_PHY_BASE -#define CONFIG_USB_PHY_CFG_BASE KS2_USB_PHY_CFG_BASE +#define DFU_ALT_INFO_MMC \ + "dfu_alt_info_mmc=" \ + "MLO fat 0 1;" \ + "u-boot.img fat 0 1;" \ + "uEnv.txt fat 0 1\0" + +/* DFU settings */ +#define DFUARGS \ + "dfu_bufsiz=0x10000\0" \ + DFU_ALT_INFO_MMC \ /* U-Boot general configuration */ #define CONFIG_MX_CYCLIC @@ -214,6 +218,7 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ DEFAULT_LINUX_BOOT_ENV \ CONFIG_EXTRA_ENV_KS2_BOARD_SETTINGS \ + DFUARGS \ "bootdir=/boot\0" \ "tftp_root=/\0" \ "nfs_root=/export\0" \ diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 70f8712b60c..95d64525535 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -124,6 +124,8 @@ "third_image=u-boot.bin\0" #endif +#define CONFIG_PREBOOT "env exist ${bootdev}preboot && run ${bootdev}preboot" + #define CONFIG_ROOTPATH "/nfs/root/path" #define CONFIG_NFSBOOTCOMMAND \ "setenv bootargs $bootargs root=/dev/nfs rw " \ @@ -169,8 +171,32 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ "netdev=eth0\0" \ "initrd_high=0xffffffffffffffff\0" \ + "script=boot.scr\0" \ "scriptaddr=0x85000000\0" \ "nor_base=0x42000000\0" \ + "emmcboot=mmcsetn && run bootcmd_mmc${mmc_first_dev}\0" \ + "nandboot=run bootcmd_ubifs0\0" \ + "norboot=run tftpboot\0" \ + "usbboot=run bootcmd_usb0\0" \ + "emmcscript=setenv devtype mmc && " \ + "mmcsetn && " \ + "setenv devnum ${mmc_first_dev} && " \ + "run loadscript_fat\0" \ + "nandscript=echo Running ${script} from ubi ... && " \ + "ubi part UBI && " \ + "ubifsmount ubi0:boot && " \ + "ubifsload ${loadaddr} ${script} && " \ + "source\0" \ + "norscript=echo Running ${script} from tftp ... && " \ + "tftpboot ${script} &&" \ + "source\0" \ + "usbscript=usb start && " \ + "setenv devtype usb && " \ + "setenv devnum 0 && " \ + "run loadscript_fat\0" \ + "loadscript_fat=echo Running ${script} from ${devtype}${devnum} ... && " \ + "load ${devtype} ${devnum}:1 ${loadaddr} ${script} && " \ + "source\0" \ "sramupdate=setexpr tmp_addr $nor_base + 0x50000 &&" \ "tftpboot $tmp_addr $second_image && " \ "setexpr tmp_addr $nor_base + 0x70000 && " \ diff --git a/include/configs/vcoreiii.h b/include/configs/vcoreiii.h new file mode 100644 index 00000000000..df89cdaebf1 --- /dev/null +++ b/include/configs/vcoreiii.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef __VCOREIII_H +#define __VCOREIII_H + +#include <linux/sizes.h> + +/* Onboard devices */ + +#define CONFIG_SYS_MALLOC_LEN 0x100000 +#define CONFIG_SYS_LOAD_ADDR 0x00100000 +#define CONFIG_SYS_INIT_SP_OFFSET 0x400000 + +#define CPU_CLOCK_RATE 500000000 /* Clock for the MIPS core */ +#ifdef CONFIG_SOC_LUTON +#define CONFIG_SYS_MIPS_TIMER_FREQ 208333333 +#else +#define CONFIG_SYS_MIPS_TIMER_FREQ (CPU_CLOCK_RATE / 2) +#endif +#define CONFIG_SYS_NS16550_CLK CONFIG_SYS_MIPS_TIMER_FREQ + +#if defined(CONFIG_ENV_IS_IN_SPI_FLASH) && !defined(CONFIG_ENV_OFFSET) +#define CONFIG_ENV_OFFSET (1024 * 1024) +#define CONFIG_ENV_SIZE (256 * 1024) +#define CONFIG_ENV_SECT_SIZE (256 * 1024) + +#define CONFIG_SYS_REDUNDAND_ENVIRONMENT +#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE +#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SECT_SIZE) + +#define CONFIG_ENV_SPI_MAX_HZ 0 /* This force to read from DT */ +#define CONFIG_ENV_SPI_MODE 0 /* This force to read from DT */ +#endif + +#define CONFIG_SYS_SDRAM_BASE 0x80000000 +#if defined(CONFIG_DDRTYPE_H5TQ1G63BFA) || defined(CONFIG_DDRTYPE_MT47H128M8HQ) +#define CONFIG_SYS_SDRAM_SIZE (128 * SZ_1M) +#elif defined(CONFIG_DDRTYPE_MT41J128M16HA) || defined(CONFIG_DDRTYPE_MT41K128M16JT) +#define CONFIG_SYS_SDRAM_SIZE (256 * SZ_1M) +#elif defined(CONFIG_DDRTYPE_H5TQ4G63MFR) || defined(CONFIG_DDRTYPE_MT41K256M16) +#define CONFIG_SYS_SDRAM_SIZE (512 * SZ_1M) +#else +#error Unknown DDR size - please add! +#endif + +#define CONFIG_CONS_INDEX 1 + +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE - SZ_1M) + +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE + +#define CONFIG_BOARD_EARLY_INIT_R +#if defined(CONFIG_MTDIDS_DEFAULT) && defined(CONFIG_MTDPARTS_DEFAULT) +#define VCOREIII_DEFAULT_MTD_ENV \ + "mtdparts="CONFIG_MTDPARTS_DEFAULT"\0" \ + "mtdids="CONFIG_MTDIDS_DEFAULT"\0" +#else +#define VCOREIII_DEFAULT_MTD_ENV /* Go away */ +#endif + +#define CONFIG_SYS_BOOTM_LEN (16 << 20) /* Increase max gunzip size */ + +#define CONFIG_EXTRA_ENV_SETTINGS \ + VCOREIII_DEFAULT_MTD_ENV \ + "loadaddr=0x81000000\0" \ + "spi_image_off=0x00100000\0" \ + "console=ttyS0,115200\0" \ + "setup=setenv bootargs console=${console} ${mtdparts}" \ + "${bootargs_extra}\0" \ + "spiboot=run setup; sf probe; sf read ${loadaddr}" \ + "${spi_image_off} 0x600000; bootm ${loadaddr}\0" \ + "ubootfile=u-boot.bin\0" \ + "update=sf probe;mtdparts;dhcp ${loadaddr} ${ubootfile};" \ + "sf erase UBoot 0x100000;" \ + "sf write ${loadaddr} UBoot ${filesize}\0" \ + "bootcmd=run spiboot\0" \ + "" +#endif /* __VCOREIII_H */ diff --git a/include/cpu.h b/include/cpu.h index 367c5f46a00..28dd48feb8f 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -14,6 +14,8 @@ * @device_id: Driver-defined device identifier * @family: DMTF CPU Family identifier * @id: DMTF CPU Processor identifier + * @timebase_freq: the current frequency at which the cpu timer timebase + * registers are updated (in Hz) * * This can be accessed with dev_get_parent_platdata() for any UCLASS_CPU * device. @@ -24,6 +26,7 @@ struct cpu_platdata { ulong device_id; u16 family; u32 id[2]; + u32 timebase_freq; }; /* CPU features - mostly just a placeholder for now */ diff --git a/include/dm/read.h b/include/dm/read.h index efcbee15eca..389e30e7fb4 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -65,6 +65,38 @@ int dev_read_u32(struct udevice *dev, const char *propname, u32 *outp); int dev_read_u32_default(struct udevice *dev, const char *propname, int def); /** + * dev_read_s32() - read a signed 32-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * @return 0 if OK, -ve on error + */ +int dev_read_s32(struct udevice *dev, const char *propname, s32 *outp); + +/** + * dev_read_s32_default() - read a signed 32-bit int from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * @return property value, or @def if not found + */ +int dev_read_s32_default(struct udevice *dev, const char *propname, int def); + +/** + * dev_read_u32u() - read a 32-bit integer from a device's DT property + * + * This version uses a standard uint type. + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * @return 0 if OK, -ve on error + */ +int dev_read_u32u(struct udevice *dev, const char *propname, uint *outp); + +/** * dev_read_string() - Read a string from a device's DT property * * @dev: device to read DT property from @@ -492,6 +524,32 @@ static inline int dev_read_u32_default(struct udevice *dev, return ofnode_read_u32_default(dev_ofnode(dev), propname, def); } +static inline int dev_read_s32(struct udevice *dev, + const char *propname, s32 *outp) +{ + return ofnode_read_s32(dev_ofnode(dev), propname, outp); +} + +static inline int dev_read_s32_default(struct udevice *dev, + const char *propname, int def) +{ + return ofnode_read_s32_default(dev_ofnode(dev), propname, def); +} + +static inline int dev_read_u32u(struct udevice *dev, + const char *propname, uint *outp) +{ + u32 val; + int ret; + + ret = ofnode_read_u32(dev_ofnode(dev), propname, &val); + if (ret) + return ret; + *outp = val; + + return 0; +} + static inline const char *dev_read_string(struct udevice *dev, const char *propname) { diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index e960e48b855..f3bafb3c635 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -29,6 +29,7 @@ enum uclass_id { /* U-Boot uclasses start here - in alphabetical order */ UCLASS_ADC, /* Analog-to-digital converter */ UCLASS_AHCI, /* SATA disk controller */ + UCLASS_AUDIO_CODEC, /* Audio codec with control and data path */ UCLASS_AXI, /* AXI bus */ UCLASS_BLK, /* Block device */ UCLASS_BOARD, /* Device information from hardware */ @@ -48,6 +49,7 @@ enum uclass_id { UCLASS_I2C_EEPROM, /* I2C EEPROM device */ UCLASS_I2C_GENERIC, /* Generic I2C device */ UCLASS_I2C_MUX, /* I2C multiplexer */ + UCLASS_I2S, /* I2S bus */ UCLASS_IDE, /* IDE device */ UCLASS_IRQ, /* Interrupt controller */ UCLASS_KEYBOARD, /* Keyboard input device */ @@ -82,6 +84,7 @@ enum uclass_id { UCLASS_SERIAL, /* Serial UART */ UCLASS_SIMPLE_BUS, /* Bus with child devices */ UCLASS_SMEM, /* Shared memory interface */ + UCLASS_SOUND, /* Playing simple sounds */ UCLASS_SPI, /* SPI bus */ UCLASS_SPI_FLASH, /* SPI flash */ UCLASS_SPI_GENERIC, /* Generic SPI flash target */ diff --git a/include/dt-bindings/clock/bcm6318-clock.h b/include/dt-bindings/clock/bcm6318-clock.h index d5e13c5c2d3..3f10448cef1 100644 --- a/include/dt-bindings/clock/bcm6318-clock.h +++ b/include/dt-bindings/clock/bcm6318-clock.h @@ -33,4 +33,15 @@ #define BCM6318_CLK_AFE 29 #define BCM6318_CLK_QPROC 30 +#define BCM6318_UCLK_ADSL 0 +#define BCM6318_UCLK_ARB 1 +#define BCM6318_UCLK_MIPS 2 +#define BCM6318_UCLK_PCIE 3 +#define BCM6318_UCLK_PERIPH 4 +#define BCM6318_UCLK_PHYMIPS 5 +#define BCM6318_UCLK_ROBOSW 6 +#define BCM6318_UCLK_SAR 7 +#define BCM6318_UCLK_SDR 8 +#define BCM6318_UCLK_USB 9 + #endif /* __DT_BINDINGS_CLOCK_BCM6318_H */ diff --git a/include/dt-bindings/clock/jz4780-cgu.h b/include/dt-bindings/clock/jz4780-cgu.h new file mode 100644 index 00000000000..73214c52c02 --- /dev/null +++ b/include/dt-bindings/clock/jz4780-cgu.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * This header provides clock numbers for the ingenic,jz4780-cgu DT binding. + * + * They are roughly ordered as: + * - external clocks + * - PLLs + * - muxes/dividers in the order they appear in the jz4780 programmers manual + * - gates in order of their bit in the CLKGR* registers + */ + +#ifndef __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ +#define __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ + +#define JZ4780_CLK_EXCLK 0 +#define JZ4780_CLK_RTCLK 1 +#define JZ4780_CLK_APLL 2 +#define JZ4780_CLK_MPLL 3 +#define JZ4780_CLK_EPLL 4 +#define JZ4780_CLK_VPLL 5 +#define JZ4780_CLK_OTGPHY 6 +#define JZ4780_CLK_SCLKA 7 +#define JZ4780_CLK_CPUMUX 8 +#define JZ4780_CLK_CPU 9 +#define JZ4780_CLK_L2CACHE 10 +#define JZ4780_CLK_AHB0 11 +#define JZ4780_CLK_AHB2PMUX 12 +#define JZ4780_CLK_AHB2 13 +#define JZ4780_CLK_PCLK 14 +#define JZ4780_CLK_DDR 15 +#define JZ4780_CLK_VPU 16 +#define JZ4780_CLK_I2SPLL 17 +#define JZ4780_CLK_I2S 18 +#define JZ4780_CLK_LCD0PIXCLK 19 +#define JZ4780_CLK_LCD1PIXCLK 20 +#define JZ4780_CLK_MSCMUX 21 +#define JZ4780_CLK_MSC0 22 +#define JZ4780_CLK_MSC1 23 +#define JZ4780_CLK_MSC2 24 +#define JZ4780_CLK_UHC 25 +#define JZ4780_CLK_SSIPLL 26 +#define JZ4780_CLK_SSI 27 +#define JZ4780_CLK_CIMMCLK 28 +#define JZ4780_CLK_PCMPLL 29 +#define JZ4780_CLK_PCM 30 +#define JZ4780_CLK_GPU 31 +#define JZ4780_CLK_HDMI 32 +#define JZ4780_CLK_BCH 33 +#define JZ4780_CLK_NEMC 34 +#define JZ4780_CLK_OTG0 35 +#define JZ4780_CLK_SSI0 36 +#define JZ4780_CLK_SMB0 37 +#define JZ4780_CLK_SMB1 38 +#define JZ4780_CLK_SCC 39 +#define JZ4780_CLK_AIC 40 +#define JZ4780_CLK_TSSI0 41 +#define JZ4780_CLK_OWI 42 +#define JZ4780_CLK_KBC 43 +#define JZ4780_CLK_SADC 44 +#define JZ4780_CLK_UART0 45 +#define JZ4780_CLK_UART1 46 +#define JZ4780_CLK_UART2 47 +#define JZ4780_CLK_UART3 48 +#define JZ4780_CLK_SSI1 49 +#define JZ4780_CLK_SSI2 50 +#define JZ4780_CLK_PDMA 51 +#define JZ4780_CLK_GPS 52 +#define JZ4780_CLK_MAC 53 +#define JZ4780_CLK_SMB2 54 +#define JZ4780_CLK_CIM 55 +#define JZ4780_CLK_LCD 56 +#define JZ4780_CLK_TVE 57 +#define JZ4780_CLK_IPU 58 +#define JZ4780_CLK_DDR0 59 +#define JZ4780_CLK_DDR1 60 +#define JZ4780_CLK_SMB3 61 +#define JZ4780_CLK_TSSI1 62 +#define JZ4780_CLK_COMPRESS 63 +#define JZ4780_CLK_AIC1 64 +#define JZ4780_CLK_GPVLC 65 +#define JZ4780_CLK_OTG1 66 +#define JZ4780_CLK_UART4 67 +#define JZ4780_CLK_AHBMON 68 +#define JZ4780_CLK_SMB4 69 +#define JZ4780_CLK_DES 70 +#define JZ4780_CLK_X2D 71 +#define JZ4780_CLK_CORE1 72 + +#endif /* __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ */ diff --git a/include/dt-bindings/dma/bcm6318-dma.h b/include/dt-bindings/dma/bcm6318-dma.h new file mode 100644 index 00000000000..ad7c5ac2dfa --- /dev/null +++ b/include/dt-bindings/dma/bcm6318-dma.h @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> + * + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c + */ + +#ifndef __DT_BINDINGS_DMA_BCM6318_H +#define __DT_BINDINGS_DMA_BCM6318_H + +#define BCM6318_DMA_ENETSW_RX 0 +#define BCM6318_DMA_ENETSW_TX 1 + +#endif /* __DT_BINDINGS_DMA_BCM6318_H */ diff --git a/include/dt-bindings/dma/bcm63268-dma.h b/include/dt-bindings/dma/bcm63268-dma.h new file mode 100644 index 00000000000..7d027119e61 --- /dev/null +++ b/include/dt-bindings/dma/bcm63268-dma.h @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> + * + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c + */ + +#ifndef __DT_BINDINGS_DMA_BCM63268_H +#define __DT_BINDINGS_DMA_BCM63268_H + +#define BCM63268_DMA_ENETSW_RX 0 +#define BCM63268_DMA_ENETSW_TX 1 + +#endif /* __DT_BINDINGS_DMA_BCM63268_H */ diff --git a/include/dt-bindings/dma/bcm6328-dma.h b/include/dt-bindings/dma/bcm6328-dma.h new file mode 100644 index 00000000000..7494df2feba --- /dev/null +++ b/include/dt-bindings/dma/bcm6328-dma.h @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> + * + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c + */ + +#ifndef __DT_BINDINGS_DMA_BCM6328_H +#define __DT_BINDINGS_DMA_BCM6328_H + +#define BCM6328_DMA_ENETSW_RX 0 +#define BCM6328_DMA_ENETSW_TX 1 + +#endif /* __DT_BINDINGS_DMA_BCM6328_H */ diff --git a/include/dt-bindings/dma/bcm6338-dma.h b/include/dt-bindings/dma/bcm6338-dma.h new file mode 100644 index 00000000000..f2e0b20444d --- /dev/null +++ b/include/dt-bindings/dma/bcm6338-dma.h @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> + * + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c + */ + +#ifndef __DT_BINDINGS_DMA_BCM6338_H +#define __DT_BINDINGS_DMA_BCM6338_H + +#define BCM6338_DMA_ENET_RX 0 +#define BCM6338_DMA_ENET_TX 1 + +#endif /* __DT_BINDINGS_DMA_BCM6338_H */ diff --git a/include/dt-bindings/dma/bcm6348-dma.h b/include/dt-bindings/dma/bcm6348-dma.h new file mode 100644 index 00000000000..36c2ffd412c --- /dev/null +++ b/include/dt-bindings/dma/bcm6348-dma.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> + * + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c + */ + +#ifndef __DT_BINDINGS_DMA_BCM6348_H +#define __DT_BINDINGS_DMA_BCM6348_H + +#define BCM6348_DMA_ENET0_RX 0 +#define BCM6348_DMA_ENET0_TX 1 +#define BCM6348_DMA_ENET1_RX 2 +#define BCM6348_DMA_ENET1_TX 3 + +#endif /* __DT_BINDINGS_DMA_BCM6348_H */ diff --git a/include/dt-bindings/dma/bcm6358-dma.h b/include/dt-bindings/dma/bcm6358-dma.h new file mode 100644 index 00000000000..3118b9da0a3 --- /dev/null +++ b/include/dt-bindings/dma/bcm6358-dma.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> + * + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c + */ + +#ifndef __DT_BINDINGS_DMA_BCM6358_H +#define __DT_BINDINGS_DMA_BCM6358_H + +#define BCM6358_DMA_ENET0_RX 0 +#define BCM6358_DMA_ENET0_TX 1 +#define BCM6358_DMA_ENET1_RX 2 +#define BCM6358_DMA_ENET1_TX 3 + +#endif /* __DT_BINDINGS_DMA_BCM6358_H */ diff --git a/include/dt-bindings/dma/bcm6362-dma.h b/include/dt-bindings/dma/bcm6362-dma.h new file mode 100644 index 00000000000..1e62236daa2 --- /dev/null +++ b/include/dt-bindings/dma/bcm6362-dma.h @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> + * + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c + */ + +#ifndef __DT_BINDINGS_DMA_BCM6362_H +#define __DT_BINDINGS_DMA_BCM6362_H + +#define BCM6362_DMA_ENETSW_RX 0 +#define BCM6362_DMA_ENETSW_TX 1 + +#endif /* __DT_BINDINGS_DMA_BCM6362_H */ diff --git a/include/dt-bindings/dma/bcm6368-dma.h b/include/dt-bindings/dma/bcm6368-dma.h new file mode 100644 index 00000000000..36c6caa0e16 --- /dev/null +++ b/include/dt-bindings/dma/bcm6368-dma.h @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com> + * + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c + */ + +#ifndef __DT_BINDINGS_DMA_BCM6368_H +#define __DT_BINDINGS_DMA_BCM6368_H + +#define BCM6368_DMA_ENETSW_RX 0 +#define BCM6368_DMA_ENETSW_TX 1 + +#endif /* __DT_BINDINGS_DMA_BCM6368_H */ diff --git a/include/environment/ti/boot.h b/include/environment/ti/boot.h index 5891009a5a2..86ff6d3ea7c 100644 --- a/include/environment/ti/boot.h +++ b/include/environment/ti/boot.h @@ -41,7 +41,7 @@ "name=crypto,size=16K,uuid=${uuid_gpt_crypto};" \ "name=recovery,size=40M,uuid=${uuid_gpt_recovery};" \ "name=boot,size=10M,uuid=${uuid_gpt_boot};" \ - "name=system,size=768M,uuid=${uuid_gpt_system};" \ + "name=system,size=1024M,uuid=${uuid_gpt_system};" \ "name=vendor,size=256M,uuid=${uuid_gpt_vendor};" \ "name=cache,size=256M,uuid=${uuid_gpt_cache};" \ "name=ipu1,size=1M,uuid=${uuid_gpt_ipu1};" \ diff --git a/include/i2s.h b/include/i2s.h index e6d45ec26d7..28f6184811c 100644 --- a/include/i2s.h +++ b/include/i2s.h @@ -76,7 +76,7 @@ struct i2s_reg { }; /* This structure stores the i2s related information */ -struct i2stx_info { +struct i2s_uc_priv { unsigned int rfs; /* LR clock frame size */ unsigned int bfs; /* Bit slock frame size */ unsigned int audio_pll_clk; /* Audio pll frequency in Hz */ @@ -87,17 +87,41 @@ struct i2stx_info { unsigned int id; /* I2S controller id */ }; +/* Operations for i2s devices */ +struct i2s_ops { + /** + * tx_data() - Transmit audio data + * + * @dev: I2C device + * @data: Data buffer to play + * @data_size: Size of data buffer in bytes + * @return 0 if OK, -ve on error + */ + int (*tx_data)(struct udevice *dev, void *data, uint data_size); +}; + +#define i2s_get_ops(dev) ((struct i2s_ops *)(dev)->driver->ops) + +/** + * i2s_tx_data() - Transmit audio data + * + * @dev: I2C device + * @data: Data buffer to play + * @data_size: Size of data buffer in bytes + * @return 0 if OK, -ve on error + */ +int i2s_tx_data(struct udevice *dev, void *data, uint data_size); + /* * Sends the given data through i2s tx * * @param pi2s_tx pointer of i2s transmitter parameter structure. * @param data address of the data buffer - * @param data_size array size of the int buffer (total size / size of int) - * + * @param data_size size of the data (in bytes) * @return int value 0 for success, -1 in case of error */ -int i2s_transfer_tx_data(struct i2stx_info *pi2s_tx, unsigned *data, - unsigned long data_size); +int i2s_transfer_tx_data(struct i2s_uc_priv *pi2s_tx, void *data, + uint data_size); /* * Initialise i2s transmiter @@ -106,6 +130,6 @@ int i2s_transfer_tx_data(struct i2stx_info *pi2s_tx, unsigned *data, * * @return int value 0 for success, -1 in case of error */ -int i2s_tx_init(struct i2stx_info *pi2s_tx); +int i2s_tx_init(struct i2s_uc_priv *pi2s_tx); #endif /* __I2S_H__ */ diff --git a/include/image.h b/include/image.h index 7ce9670c207..765ffecee0a 100644 --- a/include/image.h +++ b/include/image.h @@ -126,7 +126,8 @@ enum ih_category { * Operating System Codes * * The following are exposed to uImage header. - * Do not change values for backward compatibility. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. */ enum { IH_OS_INVALID = 0, /* Invalid OS */ @@ -164,7 +165,8 @@ enum { * CPU Architecture Codes (supported by Linux) * * The following are exposed to uImage header. - * Do not change values for backward compatibility. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. */ enum { IH_ARCH_INVALID = 0, /* Invalid CPU */ @@ -237,7 +239,8 @@ enum { * as command interpreter (=> Shell Scripts). * * The following are exposed to uImage header. - * Do not change values for backward compatibility. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. */ enum { @@ -252,7 +255,6 @@ enum { IH_TYPE_FLATDT, /* Binary Flat Device Tree Blob */ IH_TYPE_KWBIMAGE, /* Kirkwood Boot Image */ IH_TYPE_IMXIMAGE, /* Freescale IMXBoot Image */ - IH_TYPE_IMX8IMAGE, /* Freescale IMX8Boot Image */ IH_TYPE_UBLIMAGE, /* Davinci UBL Image */ IH_TYPE_OMAPIMAGE, /* TI OMAP Config Header Image */ IH_TYPE_AISIMAGE, /* TI Davinci AIS Image */ @@ -279,8 +281,9 @@ enum { IH_TYPE_PMMC, /* TI Power Management Micro-Controller Firmware */ IH_TYPE_STM32IMAGE, /* STMicroelectronics STM32 Image */ IH_TYPE_SOCFPGAIMAGE_V1, /* Altera SOCFPGA A10 Preloader */ - IH_TYPE_IMX8MIMAGE, /* Freescale IMX8MBoot Image */ IH_TYPE_MTKIMAGE, /* MediaTek BootROM loadable Image */ + IH_TYPE_IMX8MIMAGE, /* Freescale IMX8MBoot Image */ + IH_TYPE_IMX8IMAGE, /* Freescale IMX8Boot Image */ IH_TYPE_COUNT, /* Number of image types */ }; @@ -289,7 +292,8 @@ enum { * Compression Types * * The following are exposed to uImage header. - * Do not change values for backward compatibility. + * New IDs *MUST* be appended at the end of the list and *NEVER* + * inserted for backward compatibility. */ enum { IH_COMP_NONE = 0, /* No Compression Used */ diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h new file mode 100644 index 00000000000..4a54ae05091 --- /dev/null +++ b/include/linux/bitmap.h @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0+ +#ifndef __LINUX_BITMAP_H +#define __LINUX_BITMAP_H + +#include <asm/types.h> +#include <linux/types.h> +#include <linux/bitops.h> + +#define small_const_nbits(nbits) \ + (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG) + +static inline void bitmap_zero(unsigned long *dst, int nbits) +{ + if (small_const_nbits(nbits)) { + *dst = 0UL; + } else { + int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); + + memset(dst, 0, len); + } +} + +#endif /* __LINUX_BITMAP_H */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index bd88483b9f6..a85c15d8dc2 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -102,6 +102,18 @@ (((__x) - ((__d) / 2)) / (__d)); \ } \ ) +/* + * Same as above but for u64 dividends. divisor must be a 32-bit + * number. + */ +#define DIV_ROUND_CLOSEST_ULL(x, divisor)( \ +{ \ + typeof(divisor) __d = divisor; \ + unsigned long long _tmp = (x) + (__d) / 2; \ + do_div(_tmp, __d); \ + _tmp; \ +} \ +) /* * Multiplies an integer by a fraction, while avoiding unnecessary diff --git a/include/linux/types.h b/include/linux/types.h index 1f3cd63b8f2..cc6f7cb39ee 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -158,4 +158,7 @@ struct ustat { char f_fpack[6]; }; +#define DECLARE_BITMAP(name, bits) \ + unsigned long name[BITS_TO_LONGS(bits)] + #endif /* _LINUX_TYPES_H */ diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 30c464ce39d..a49a66f2f82 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -24,7 +24,7 @@ #include <common.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> -#include <usb/lin_gadget_compat.h> +#include <linux/bitmap.h> /* * USB function drivers should return USB_GADGET_DELAYED_STATUS if they diff --git a/include/sound.h b/include/sound.h index 77bfe6a93b2..b7959cc2607 100644 --- a/include/sound.h +++ b/include/sound.h @@ -8,14 +8,6 @@ #define __SOUND_H__ /* sound codec enum */ -enum en_sound_codec { - CODEC_WM_8994, - CODEC_WM_8995, - CODEC_MAX_98095, - CODEC_MAX -}; - -/* sound codec enum */ enum sound_compat { AUDIO_COMPAT_SPI, AUDIO_COMPAT_I2C, @@ -25,33 +17,81 @@ enum sound_compat { struct sound_codec_info { int i2c_bus; int i2c_dev_addr; - enum en_sound_codec codec_type; }; -/* +/** + * struct sound_uc_priv - private uclass information about each sound device + * + * This is used to line the codec and i2s together + * + * @codec: Codec that is used for this sound device + * @i2s: I2S bus that is used for this sound device + * @setup_done: true if setup() has been called + */ +struct sound_uc_priv { + struct udevice *codec; + struct udevice *i2s; + int setup_done; +}; + +/** * Generates square wave sound data for 1 second * - * @param sample_rate Sample rate in Hz - * @param data data buffer pointer - * @param size size of the buffer - * @param freq frequency of the wave + * @sample_rate: Sample rate in Hz + * @data: data buffer pointer + * @size: size of the buffer in bytes + * @freq: frequency of the wave + * @channels: Number of channels to use */ void sound_create_square_wave(uint sample_rate, unsigned short *data, int size, - uint freq); + uint freq, uint channels); /* - * Initialises audio sub system - * @param blob Pointer of device tree node or NULL if none. - * @return int value 0 for success, -1 for error + * The sound uclass brings together a data transport (currently only I2C) and a + * codec (currently connected over I2C). */ -int sound_init(const void *blob); -/* - * plays the pcm data buffer in pcm_data.h through i2s1 to make the - * sine wave sound +/* Operations for sound */ +struct sound_ops { + /** + * setup() - Set up to play a sound + */ + int (*setup)(struct udevice *dev); + + /** + * play() - Play a beep + * + * @dev: Sound device + * @data: Data buffer to play + * @data_size: Size of data buffer in bytes + * @return 0 if OK, -ve on error + */ + int (*play)(struct udevice *dev, void *data, uint data_size); +}; + +#define sound_get_ops(dev) ((struct sound_ops *)(dev)->driver->ops) + +/** + * setup() - Set up to play a sound + */ +int sound_setup(struct udevice *dev); + +/** + * play() - Play a beep + * + * @dev: Sound device + * @msecs: Duration of beep in milliseconds + * @frequency_hz: Frequency of the beep in Hertz + * @return 0 if OK, -ve on error + */ +int sound_beep(struct udevice *dev, int msecs, int frequency_hz); + +/** + * sound_find_codec_i2s() - Called by sound drivers to locate codec and i2s * - * @return int 0 for success, -1 for error + * This finds the audio codec and i2s devices and puts them in the uclass's + * private data for this device. */ -int sound_play(uint32_t msec, uint32_t frequency); +int sound_find_codec_i2s(struct udevice *dev); #endif /* __SOUND__H__ */ diff --git a/include/tee.h b/include/tee.h index 98b1c9cc693..edd9f9b0c96 100644 --- a/include/tee.h +++ b/include/tee.h @@ -34,6 +34,7 @@ * struct tee_version_data::gen_caps */ #define TEE_SUCCESS 0x00000000 +#define TEE_ERROR_STORAGE_NOT_AVAILABLE 0xf0100003 #define TEE_ERROR_GENERIC 0xffff0000 #define TEE_ERROR_BAD_PARAMETERS 0xffff0006 #define TEE_ERROR_ITEM_NOT_FOUND 0xffff0008 diff --git a/include/usb/lin_gadget_compat.h b/include/usb/lin_gadget_compat.h deleted file mode 100644 index e5dba473b7a..00000000000 --- a/include/usb/lin_gadget_compat.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 2011 Samsung Electronics - * Lukasz Majewski <l.majewski@samsung.com> - * - * This is a Linux kernel compatibility layer for USB Gadget - */ - -#ifndef __LIN_COMPAT_H__ -#define __LIN_COMPAT_H__ - -#include <linux/bitops.h> -#include <linux/compat.h> - -/* common */ -#define DECLARE_BITMAP(name, bits) \ - unsigned long name[BITS_TO_LONGS(bits)] - -#define small_const_nbits(nbits) \ - (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG) - -static inline void bitmap_zero(unsigned long *dst, int nbits) -{ - if (small_const_nbits(nbits)) - *dst = 0UL; - else { - int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); - memset(dst, 0, len); - } -} - -#define dma_cache_maint(addr, size, mode) cache_flush() -void cache_flush(void); - -#endif /* __LIN_COMPAT_H__ */ diff --git a/include/vxworks.h b/include/vxworks.h index 60c0efaf6e4..1a29509460b 100644 --- a/include/vxworks.h +++ b/include/vxworks.h @@ -83,6 +83,5 @@ struct efi_gop_info { int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); void boot_prep_vxworks(bootm_headers_t *images); void boot_jump_vxworks(bootm_headers_t *images); -void do_bootvx_fdt(bootm_headers_t *images); #endif diff --git a/lib/crc32.c b/lib/crc32.c index 71e27df78eb..eee21f8d739 100644 --- a/lib/crc32.c +++ b/lib/crc32.c @@ -65,7 +65,8 @@ static void __efi_runtime make_crc_table(void) int n, k; uLong poly; /* polynomial exclusive-or pattern */ /* terms of polynomial defining this crc (except x^32): */ - static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + static Byte __efi_runtime_data p[] = { + 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26}; /* make exclusive-or pattern from polynomial (0xedb88320L) */ poly = 0L; diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c index 95844efdb0e..fff93f0960b 100644 --- a/lib/efi_loader/efi_runtime.c +++ b/lib/efi_loader/efi_runtime.c @@ -436,14 +436,42 @@ static efi_status_t EFIAPI efi_set_virtual_address_map( uint32_t descriptor_version, struct efi_mem_desc *virtmap) { - ulong runtime_start = (ulong)&__efi_runtime_start & - ~(ulong)EFI_PAGE_MASK; int n = memory_map_size / descriptor_size; int i; + int rt_code_sections = 0; EFI_ENTRY("%lx %lx %x %p", memory_map_size, descriptor_size, descriptor_version, virtmap); + /* + * TODO: + * Further down we are cheating. While really we should implement + * SetVirtualAddressMap() events and ConvertPointer() to allow + * dynamically loaded drivers to expose runtime services, we don't + * today. + * + * So let's ensure we see exactly one single runtime section, as + * that is the built-in one. If we see more (or less), someone must + * have tried adding or removing to that which we don't support yet. + * In that case, let's better fail rather than expose broken runtime + * services. + */ + for (i = 0; i < n; i++) { + struct efi_mem_desc *map = (void*)virtmap + + (descriptor_size * i); + + if (map->type == EFI_RUNTIME_SERVICES_CODE) + rt_code_sections++; + } + + if (rt_code_sections != 1) { + /* + * We expose exactly one single runtime code section, so + * something is definitely going wrong. + */ + return EFI_EXIT(EFI_INVALID_PARAMETER); + } + /* Rebind mmio pointers */ for (i = 0; i < n; i++) { struct efi_mem_desc *map = (void*)virtmap + @@ -483,7 +511,7 @@ static efi_status_t EFIAPI efi_set_virtual_address_map( map = (void*)virtmap + (descriptor_size * i); if (map->type == EFI_RUNTIME_SERVICES_CODE) { ulong new_offset = map->virtual_start - - (runtime_start - gd->relocaddr); + map->physical_start + gd->relocaddr; efi_runtime_relocate(new_offset, map); /* Once we're virtual, we can no longer handle diff --git a/lib/efi_selftest/efi_selftest_block_device.c b/lib/efi_selftest/efi_selftest_block_device.c index d4e4fac1c74..f038da9f190 100644 --- a/lib/efi_selftest/efi_selftest_block_device.c +++ b/lib/efi_selftest/efi_selftest_block_device.c @@ -445,11 +445,6 @@ static int execute(void) efi_st_error("Failed to write file\n"); return EFI_ST_FAILURE; } - ret = file->close(file); - if (ret != EFI_SUCCESS) { - efi_st_error("Failed to close file\n"); - return EFI_ST_FAILURE; - } ret = file->getpos(file, &pos); if (ret != EFI_SUCCESS) { efi_st_error("GetPosition failed\n"); @@ -460,6 +455,11 @@ static int execute(void) (unsigned int)pos); return EFI_ST_FAILURE; } + ret = file->close(file); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to close file\n"); + return EFI_ST_FAILURE; + } /* Verify file */ boottime->set_mem(buf, sizeof(buf), 0); diff --git a/lib/hashtable.c b/lib/hashtable.c index 1c48692b69e..93028ed83b2 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -662,7 +662,7 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag, return (-1); } } else { - size = totlen; + size = totlen + 1; } /* Check if the user provided a buffer */ diff --git a/scripts/check-config.sh b/scripts/check-config.sh index 4848ca6e25a..583f7d0963c 100755 --- a/scripts/check-config.sh +++ b/scripts/check-config.sh @@ -17,6 +17,15 @@ set -e set -u +PROG_NAME="${0##*/}" + +usage() { + echo "$PROG_NAME <path to u-boot.cfg> <path to whitelist file> <source dir>" + exit 1 +} + +[ $# -ge 3 ] || usage + path="$1" whitelist="$2" srctree="$3" diff --git a/test/dm/Makefile b/test/dm/Makefile index 2c9081e4dd6..7dc80be25e3 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -2,7 +2,6 @@ # # Copyright (c) 2013 Google, Inc -obj-$(CONFIG_CMD_DM) += cmd_dm.o obj-$(CONFIG_UT_DM) += bus.o obj-$(CONFIG_UT_DM) += test-driver.o obj-$(CONFIG_UT_DM) += test-fdt.o @@ -13,6 +12,7 @@ obj-$(CONFIG_UT_DM) += test-uclass.o # subsystem you must add sandbox tests here. obj-$(CONFIG_UT_DM) += core.o ifneq ($(CONFIG_SANDBOX),) +obj-$(CONFIG_SOUND) += audio.o obj-$(CONFIG_BLK) += blk.o obj-$(CONFIG_BOARD) += board.o obj-$(CONFIG_CLK) += clk.o @@ -21,6 +21,7 @@ obj-$(CONFIG_FIRMWARE) += firmware.o obj-$(CONFIG_DM_GPIO) += gpio.o obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock.o obj-$(CONFIG_DM_I2C) += i2c.o +obj-$(CONFIG_SOUND) += i2s.o obj-$(CONFIG_LED) += led.o obj-$(CONFIG_DM_MAILBOX) += mailbox.o obj-$(CONFIG_DM_MMC) += mmc.o @@ -53,6 +54,7 @@ obj-$(CONFIG_AXI) += axi.o obj-$(CONFIG_MISC) += misc.o obj-$(CONFIG_DM_SERIAL) += serial.o obj-$(CONFIG_CPU) += cpu.o +obj-$(CONFIG_SOUND) += sound.o obj-$(CONFIG_TEE) += tee.o obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o obj-$(CONFIG_DMA) += dma.o diff --git a/test/dm/audio.c b/test/dm/audio.c new file mode 100644 index 00000000000..77c3a3625bd --- /dev/null +++ b/test/dm/audio.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <audio_codec.h> +#include <dm.h> +#include <dm/test.h> +#include <test/ut.h> +#include <asm/test.h> + +/* Basic test of the audio codec uclass */ +static int dm_test_audio(struct unit_test_state *uts) +{ + int interface, rate, mclk_freq, bits_per_sample; + struct udevice *dev; + uint channels; + + /* check probe success */ + ut_assertok(uclass_first_device_err(UCLASS_AUDIO_CODEC, &dev)); + ut_assertok(audio_codec_set_params(dev, 1, 2, 3, 4, 5)); + sandbox_get_codec_params(dev, &interface, &rate, &mclk_freq, + &bits_per_sample, &channels); + ut_asserteq(1, interface); + ut_asserteq(2, rate); + ut_asserteq(3, mclk_freq); + ut_asserteq(4, bits_per_sample); + ut_asserteq(5, channels); + + return 0; +} +DM_TEST(dm_test_audio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/i2s.c b/test/dm/i2s.c new file mode 100644 index 00000000000..49ebc3523c0 --- /dev/null +++ b/test/dm/i2s.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <dm.h> +#include <i2s.h> +#include <dm/test.h> +#include <test/ut.h> +#include <asm/test.h> + +/* Basic test of the i2s codec uclass */ +static int dm_test_i2s(struct unit_test_state *uts) +{ + struct udevice *dev; + u8 data[3]; + + /* check probe success */ + ut_assertok(uclass_first_device_err(UCLASS_I2S, &dev)); + data[0] = 1; + data[1] = 4; + data[2] = 6; + ut_assertok(i2s_tx_data(dev, data, ARRAY_SIZE(data))); + ut_asserteq(11, sandbox_get_i2s_sum(dev)); + ut_assertok(i2s_tx_data(dev, data, 1)); + ut_asserteq(12, sandbox_get_i2s_sum(dev)); + + return 0; +} +DM_TEST(dm_test_i2s, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/sound.c b/test/dm/sound.c new file mode 100644 index 00000000000..7d0b36e7a56 --- /dev/null +++ b/test/dm/sound.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <dm.h> +#include <sound.h> +#include <dm/test.h> +#include <test/ut.h> +#include <asm/test.h> + +/* Basic test of the sound codec uclass */ +static int dm_test_sound(struct unit_test_state *uts) +{ + struct sound_uc_priv *uc_priv; + struct udevice *dev; + + /* check probe success */ + ut_assertok(uclass_first_device_err(UCLASS_SOUND, &dev)); + uc_priv = dev_get_uclass_priv(dev); + ut_asserteq_str("audio-codec", uc_priv->codec->name); + ut_asserteq_str("i2s", uc_priv->i2s->name); + ut_asserteq(0, sandbox_get_setup_called(dev)); + + ut_assertok(sound_beep(dev, 1, 100)); + ut_asserteq(4560, sandbox_get_sound_sum(dev)); + ut_assertok(sound_beep(dev, 1, 100)); + ut_asserteq(9120, sandbox_get_sound_sum(dev)); + + return 0; +} +DM_TEST(dm_test_sound, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 96d2528accb..984b80c02c8 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -736,3 +736,38 @@ static int dm_test_first_child(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_first_child, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test integer functions in dm_read_...() */ +static int dm_test_read_int(struct unit_test_state *uts) +{ + struct udevice *dev; + u32 val32; + s32 sval; + uint val; + + ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev)); + ut_asserteq_str("a-test", dev->name); + ut_assertok(dev_read_u32(dev, "int-value", &val32)); + ut_asserteq(1234, val32); + + ut_asserteq(-EINVAL, dev_read_u32(dev, "missing", &val32)); + ut_asserteq(6, dev_read_u32_default(dev, "missing", 6)); + + ut_asserteq(1234, dev_read_u32_default(dev, "int-value", 6)); + ut_asserteq(1234, val32); + + ut_asserteq(-EINVAL, dev_read_s32(dev, "missing", &sval)); + ut_asserteq(6, dev_read_s32_default(dev, "missing", 6)); + + ut_asserteq(-1234, dev_read_s32_default(dev, "uint-value", 6)); + ut_assertok(dev_read_s32(dev, "uint-value", &sval)); + ut_asserteq(-1234, sval); + + val = 0; + ut_asserteq(-EINVAL, dev_read_u32u(dev, "missing", &val)); + ut_assertok(dev_read_u32u(dev, "uint-value", &val)); + ut_asserteq(-1234, val); + + return 0; +} +DM_TEST(dm_test_read_int, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/overlay/Kconfig b/test/overlay/Kconfig index 13c85428cba..a4f154415db 100644 --- a/test/overlay/Kconfig +++ b/test/overlay/Kconfig @@ -1,11 +1,10 @@ config UT_OVERLAY bool "Enable Device Tree Overlays Unit Tests" - depends on OF_LIBFDT_OVERLAY - depends on UNIT_TEST + depends on UNIT_TEST && OF_CONTROL + default y + select OF_LIBFDT_OVERLAY help This enables the 'ut overlay' command which runs a series of unit tests on the fdt overlay code. If all is well then all tests pass although there will be a few messages printed along the way. - Be warned that it requires an out-of-tree dtc compiler with patches - to support the DT overlays, otherwise it will fail. diff --git a/tools/Makefile b/tools/Makefile index 9a724804d23..081383d7a79 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -127,7 +127,7 @@ fit_info-objs := $(dumpimage-mkimage-objs) fit_info.o fit_check_sign-objs := $(dumpimage-mkimage-objs) fit_check_sign.o file2include-objs := file2include.o -ifneq ($(CONFIG_MX23)$(CONFIG_MX28),) +ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_FIT_SIGNATURE),) # Add CONFIG_MXS into host CFLAGS, so we can check whether or not register # the mxsimage support within tools/mxsimage.c . HOSTCFLAGS_mxsimage.o += -DCONFIG_MXS diff --git a/tools/mtk_image.c b/tools/mtk_image.c index 2706d2de32a..2ca519483d3 100644 --- a/tools/mtk_image.c +++ b/tools/mtk_image.c @@ -322,7 +322,7 @@ static int mtk_brom_parse_imagename(const char *imagename) lk = val; if (!strcmp(key, "lkname")) - strncpy(lk_name, val, sizeof(lk_name)); + snprintf(lk_name, sizeof(lk_name), "%s", val); } if (next) @@ -656,7 +656,7 @@ static void mtk_image_set_gen_header(void *ptr, off_t filesize, bootname = SDMMC_BOOT_NAME; /* Generic device header */ - strncpy(hdr->boot.name, bootname, sizeof(hdr->boot.name)); + snprintf(hdr->boot.name, sizeof(hdr->boot.name), "%s", bootname); hdr->boot.version = cpu_to_le32(1); hdr->boot.size = cpu_to_le32(sizeof(hdr->boot)); |