diff options
author | Tom Rini | 2022-06-27 10:15:50 -0400 |
---|---|---|
committer | Tom Rini | 2022-06-27 10:15:50 -0400 |
commit | c316ee674f25b73285f241ce922307296616a92a (patch) | |
tree | 9067e60451612dee5fbd0d3132548d3e84063f53 /arch | |
parent | 31016a5a853cb5b8e27e9fdf956d8250ae59eca9 (diff) | |
parent | 728a86edb63a647e6faf211c0dbc7bd0e4ff7ac6 (diff) |
Merge tag 'xilinx-for-v2022.10' of https://source.denx.de/u-boot/custodians/u-boot-microblaze into next
Xilinx changes for v2022.10
cpu:
- Add driver for microblaze cpu
net:
- Add support for DM_ETH_PHY to AXI emac and emaclite
xilinx:
- Switch platforms to DM_ETH_PHY
- DT chagnes in ZynqMP and Zynq
- Enable support for SquashFS
zynqmp:
- Add support for KR260 boards
- Move BSS from address 0
- Move platform identification from board code to soc driver
- Improve zynqmp_psu_init_minimize
versal:
- Enable loading app at EL1
serial:
- Setup default address and clock rates for DEBUG uarts
pinctrl:
- Add support for tri state and output enable properties
relocate-rela:
- Clean relocate-rela implementation for ARM64
- Add support for Microblaze
microblaze:
- Add support for runtime relocation
- Rework cache handling (wiring, Kconfig) based on cpuinfo
- Remove interrupt support
timer:
- Extract axi timer driver from Microblaze to generic location
Diffstat (limited to 'arch')
42 files changed, 1570 insertions, 523 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index eab89f255b6..d35a590f93c 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -8,9 +8,6 @@ config CREATE_ARCH_SYMLINK config HAVE_ARCH_IOREMAP bool -config NEEDS_MANUAL_RELOC - bool - config SYS_CACHE_SHIFT_4 bool @@ -76,9 +73,12 @@ config M68K config MICROBLAZE bool "MicroBlaze architecture" - select NEEDS_MANUAL_RELOC select SUPPORT_OF_CONTROL - imply CMD_IRQ + imply CMD_TIMER + imply SPL_REGMAP if SPL + imply SPL_TIMER if SPL + imply TIMER + imply XILINX_TIMER config MIPS bool "MIPS architecture" @@ -452,3 +452,25 @@ source "arch/xtensa/Kconfig" source "arch/riscv/Kconfig" source "board/keymile/Kconfig" + +if MIPS || MICROBLAZE + +choice + prompt "Endianness selection" + help + Some MIPS boards can be configured for either little or big endian + byte order. These modes require different U-Boot images. In general there + is one preferred byteorder for a particular system but some systems are + just as commonly used in the one or the other endianness. + +config SYS_BIG_ENDIAN + bool "Big endian" + depends on (SUPPORTS_BIG_ENDIAN && MIPS) || MICROBLAZE + +config SYS_LITTLE_ENDIAN + bool "Little endian" + depends on (SUPPORTS_LITTLE_ENDIAN && MIPS) || MICROBLAZE + +endchoice + +endif diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 4b940f85169..a9f4cccf8db 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -342,6 +342,8 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += \ zynqmp-mini-qspi.dtb \ zynqmp-sm-k26-revA.dtb \ zynqmp-smk-k26-revA.dtb \ + zynqmp-sck-kr-g-revA.dtbo \ + zynqmp-sck-kr-g-revB.dtbo \ zynqmp-sck-kv-g-revA.dtbo \ zynqmp-sck-kv-g-revB.dtbo \ zynqmp-topic-miamimp-xilinx-xdp-v1r1.dtb \ diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi index 9495911397e..37155df0fd4 100644 --- a/arch/arm/dts/zynq-7000.dtsi +++ b/arch/arm/dts/zynq-7000.dtsi @@ -287,7 +287,7 @@ reg = <0 0 0x1000000>; status = "disabled"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; }; nor0: flash@1,0 { status = "disabled"; diff --git a/arch/arm/dts/zynqmp-e-a2197-00-revA.dts b/arch/arm/dts/zynqmp-e-a2197-00-revA.dts index 72618378230..37c56181c9c 100644 --- a/arch/arm/dts/zynqmp-e-a2197-00-revA.dts +++ b/arch/arm/dts/zynqmp-e-a2197-00-revA.dts @@ -294,10 +294,10 @@ #address-cells = <1>; #size-cells = <0>; reg = <2>; - clock_8t49n287: clock-generator@d8 { /* u39 8T49N240 */ + clock_8t49n287: clock-generator@6c { /* u39 8T49N240 */ #clock-cells = <1>; /* author David Cater <david.cater@idt.com>*/ compatible = "idt,8t49n240", "idt,8t49n241"; /* FIXME no driver for 240 */ - reg = <0xd8>; + reg = <0x6c>; /* Documentation/devicetree/bindings/clock/idt,idt8t49n24x.txt */ /* FIXME there input via J241 Samtec CLK1 and CLK0 from U38 - selection PIN */ }; @@ -447,7 +447,7 @@ si570_user1: clock-generator@5d { /* u205 */ #clock-cells = <0>; compatible = "silabs,si570"; - reg = <0x5f>; + reg = <0x5d>; temperature-stability = <50>; factory-fout = <100000000>; clock-frequency = <100000000>; diff --git a/arch/arm/dts/zynqmp-g-a2197-00-revA.dts b/arch/arm/dts/zynqmp-g-a2197-00-revA.dts index ee530ba3e14..e00428351cb 100644 --- a/arch/arm/dts/zynqmp-g-a2197-00-revA.dts +++ b/arch/arm/dts/zynqmp-g-a2197-00-revA.dts @@ -260,9 +260,9 @@ reg = <0x45>; shunt-resistor = <5000>; }; - tps53681@c0 { /* u53 - FIXME name - don't know what it does - also vcc_io_soc */ + tps53681@60 { /* u53 - 0xc0 - FIXME name - don't know what it does - also vcc_io_soc */ compatible = "ti,tps53681", "ti,tps53679"; - reg = <0xc0>; + reg = <0x60>; }; }; i2c@3 { /* fmc1 via JA2G */ diff --git a/arch/arm/dts/zynqmp-m-a2197-01-revA.dts b/arch/arm/dts/zynqmp-m-a2197-01-revA.dts index 7b3722f0808..1fa023ffb13 100644 --- a/arch/arm/dts/zynqmp-m-a2197-01-revA.dts +++ b/arch/arm/dts/zynqmp-m-a2197-01-revA.dts @@ -247,9 +247,9 @@ #address-cells = <1>; #size-cells = <0>; reg = <2>; - reg_vccint: tps53681@c0 { /* u69 */ + reg_vccint: tps53681@60 { /* u69 - 0xc0 */ compatible = "ti,tps53681", "ti,tps53679"; - reg = <0xc0>; + reg = <0x60>; }; reg_vcc_pmc: tps544@7 { /* u80 */ compatible = "ti,tps544b25"; diff --git a/arch/arm/dts/zynqmp-m-a2197-02-revA.dts b/arch/arm/dts/zynqmp-m-a2197-02-revA.dts index 11b2a58a0f0..2271a6a4906 100644 --- a/arch/arm/dts/zynqmp-m-a2197-02-revA.dts +++ b/arch/arm/dts/zynqmp-m-a2197-02-revA.dts @@ -190,10 +190,6 @@ compatible = "ti,tps544b25"; reg = <0x1e>; }; - reg_vpp_2v5_ddr4: tps544@1x { /* u3007 */ - compatible = "ti,tps544b25"; - reg = <0x17>; /* FIXME wrong in schematics */ - }; }; i2c@1 { /* PMBUS_INA226 */ #address-cells = <1>; @@ -239,9 +235,9 @@ #address-cells = <1>; #size-cells = <0>; reg = <2>; - reg_vccint: tps53681@c0 { /* u69 */ + reg_vccint: tps53681@60 { /* u69 - 0xc0 */ compatible = "ti,tps53681", "ti,tps53679"; - reg = <0xc0>; + reg = <0x60>; }; reg_vcc_pmc: tps544@7 { /* u80 */ compatible = "ti,tps544b25"; diff --git a/arch/arm/dts/zynqmp-m-a2197-03-revA.dts b/arch/arm/dts/zynqmp-m-a2197-03-revA.dts index db199c467b0..a89046a818f 100644 --- a/arch/arm/dts/zynqmp-m-a2197-03-revA.dts +++ b/arch/arm/dts/zynqmp-m-a2197-03-revA.dts @@ -190,9 +190,9 @@ compatible = "ti,tps544b25"; reg = <0x1e>; }; - reg_vpp_2v5_ddr4: tps544@1x { /* u3007 */ + reg_vcc1v2_ddr4: tps544@18 { /* u3022 */ compatible = "ti,tps544b25"; - reg = <0x17>; /* FIXME wrong in schematics */ + reg = <0x18>; }; }; i2c@1 { /* PMBUS_INA226 */ @@ -239,9 +239,9 @@ #address-cells = <1>; #size-cells = <0>; reg = <2>; - reg_vccint: tps53681@c0 { /* u69 */ + reg_vccint: tps53681@60 { /* u69 - 0xc0 */ compatible = "ti,tps53681", "ti,tps53679"; - reg = <0xc0>; + reg = <0x60>; }; reg_vcc_pmc: tps544@7 { /* u80 */ compatible = "ti,tps544b25"; diff --git a/arch/arm/dts/zynqmp-sck-kr-g-revA.dts b/arch/arm/dts/zynqmp-sck-kr-g-revA.dts new file mode 100644 index 00000000000..735c1e3d1a8 --- /dev/null +++ b/arch/arm/dts/zynqmp-sck-kr-g-revA.dts @@ -0,0 +1,388 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for KR260 revA Carrier Card + * + * (C) Copyright 2021, Xilinx, Inc. + * + * Michal Simek <michal.simek@xilinx.com> + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/net/ti-dp83867.h> +#include <dt-bindings/phy/phy.h> +#include <dt-bindings/pinctrl/pinctrl-zynqmp.h> + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sk-kr260-revA", + "xlnx,zynqmp-sk-kr260", "xlnx,zynqmp"; + + ina260-u14 { + compatible = "iio-hwmon"; + io-channels = <&u14 0>, <&u14 1>, <&u14 2>; + }; + + si5332_0: si5332_0 { /* u17 - GEM0/1 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + si5332_1: si5332_1 { /* u17 - DP */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + + si5332_2: si5332_2 { /* u17 - USB */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + si5332_3: si5332_3 { /* u17 - SFP+ */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <156250000>; + }; + + si5332_4: si5332_4 { /* u17 - GEM2 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + si5332_5: si5332_5 { /* u17 - GEM3 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; +}; + +&i2c1 { /* I2C_SCK C26/C27 - MIO from SOM */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; + + u14: ina260@40 { /* u14 */ + compatible = "ti,ina260"; + #io-channel-cells = <1>; + label = "ina260-u14"; + reg = <0x40>; + }; + + slg7xl45106: gpio@11 { /* u19 - reset logic */ + compatible = "dlg,slg7xl45106"; + reg = <0x11>; + label = "resetchip"; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "USB0_PHY_RESET_B", "USB1_PHY_RESET_B", + "SD_RESET_B", "USB0_HUB_RESET_B", + "USB1_HUB_RESET_B", "PS_GEM0_RESET_B", + "PS_GEM1_RESET_B", ""; + }; + + i2c-mux@74 { /* u18 */ + compatible = "nxp,pca9546"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + usbhub_i2c0: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + usbhub_i2c1: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + /* Bus 2/3 are not connected */ + }; + + /* si5332@6a - u17 - clock-generator */ +}; + +/* GEM SGMII/DP and USB 3.0 */ +&psgtr { + status = "okay"; + /* gem0/1, dp, usb */ + clocks = <&si5332_0>, <&si5332_1>, <&si5332_2>; + clock-names = "ref0", "ref1", "ref2"; +}; + +&zynqmp_dpsub { + status = "okay"; + phy-names = "dp-phy0"; + phys = <&psgtr 1 PHY_TYPE_DP 0 1>; + assigned-clock-rates = <27000000>, <25000000>, <300000000>; +}; + +&zynqmp_dpdma { + status = "okay"; + assigned-clock-rates = <600000000>; +}; + +&usb0 { /* mio52 - mio63 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; + reset-gpios = <&slg7xl45106 0 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; + + usbhub0: usb-hub { /* u43 */ + i2c-bus = <&usbhub_i2c0>; + compatible = "microchip,usb5744"; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; + + usb2244: usb-sd { /* u38 */ + compatible = "microchip,usb2244"; + reset-gpios = <&slg7xl45106 2 GPIO_ACTIVE_LOW>; + }; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; +}; + +&usb1 { /* mio64 - mio75 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 3 PHY_TYPE_USB3 1 2>; + reset-gpios = <&slg7xl45106 1 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; + + usbhub1: usb-hub { /* u84 */ + i2c-bus = <&usbhub_i2c1>; + compatible = "microchip,usb5744"; + reset-gpios = <&slg7xl45106 4 GPIO_ACTIVE_LOW>; + }; +}; + +&dwc3_1 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; +}; + +&gem0 { /* mdio mio50/51 */ + status = "okay"; + phys = <&psgtr 0 PHY_TYPE_SGMII 0 0>; + phy-handle = <&phy0>; + phy-mode = "sgmii"; + is-internal-pcspma; +}; + +&gem1 { /* mdio mio50/51, gem mio38 - mio49 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gem1_default>; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@4 { /* u81 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <4>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>; + ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <100>; + reset-deassert-us = <280>; + reset-gpios = <&slg7xl45106 5 GPIO_ACTIVE_LOW>; + }; + phy1: ethernet-phy@8 { /* u36 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <8>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>; + ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <100>; + reset-deassert-us = <280>; + reset-gpios = <&slg7xl45106 6 GPIO_ACTIVE_LOW>; + }; + }; +}; + +/* gem2/gem3 via PL with phys u79@2 and u80@3 */ + +&pinctrl0 { /* required by spec */ + status = "okay"; + + pinctrl_uart1_default: uart1-default { + conf { + groups = "uart1_9_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + drive-strength = <12>; + }; + + conf-rx { + pins = "MIO37"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO36"; + bias-disable; + }; + + mux { + groups = "uart1_9_grp"; + function = "uart1"; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + conf { + groups = "i2c1_6_grp"; + bias-pull-up; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + mux { + groups = "i2c1_6_grp"; + function = "i2c1"; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio { + conf { + groups = "gpio0_24_grp", "gpio0_25_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + mux { + groups = "gpio0_24_grp", "gpio0_25_grp"; + function = "gpio0"; + }; + }; + + pinctrl_gem1_default: gem1-default { + conf { + groups = "ethernet1_0_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO44", "MIO46", "MIO48"; + bias-high-impedance; + low-power-disable; + }; + + conf-bootstrap { + pins = "MIO45", "MIO47", "MIO49"; + bias-disable; + low-power-disable; + }; + + conf-tx { + pins = "MIO38", "MIO39", "MIO40", + "MIO41", "MIO42", "MIO43"; + bias-disable; + low-power-enable; + }; + + conf-mdio { + groups = "mdio1_0_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + bias-disable; + }; + + mux-mdio { + function = "mdio1"; + groups = "mdio1_0_grp"; + }; + + mux { + function = "ethernet1"; + groups = "ethernet1_0_grp"; + }; + }; + + pinctrl_usb0_default: usb0-default { + conf { + groups = "usb0_0_grp"; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO52", "MIO53", "MIO55"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; + }; + + conf-tx { + pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", + "MIO60", "MIO61", "MIO62", "MIO63"; + bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; + }; + + mux { + groups = "usb0_0_grp"; + function = "usb0"; + }; + }; + + pinctrl_usb1_default: usb1-default { + conf { + groups = "usb1_0_grp"; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO64", "MIO65", "MIO67"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; + }; + + conf-tx { + pins = "MIO66", "MIO68", "MIO69", "MIO70", "MIO71", + "MIO72", "MIO73", "MIO74", "MIO75"; + bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; + }; + + mux { + groups = "usb1_0_grp"; + function = "usb1"; + }; + }; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; +}; diff --git a/arch/arm/dts/zynqmp-sck-kr-g-revB.dts b/arch/arm/dts/zynqmp-sck-kr-g-revB.dts new file mode 100644 index 00000000000..63590619d43 --- /dev/null +++ b/arch/arm/dts/zynqmp-sck-kr-g-revB.dts @@ -0,0 +1,388 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for KR260 revB Carrier Card (A03 revision) + * + * (C) Copyright 2021 - 2022, Xilinx, Inc. + * + * Michal Simek <michal.simek@xilinx.com> + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/net/ti-dp83867.h> +#include <dt-bindings/phy/phy.h> +#include <dt-bindings/pinctrl/pinctrl-zynqmp.h> + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sk-kr260-revB", + "xlnx,zynqmp-sk-kr260", "xlnx,zynqmp"; + + ina260-u14 { + compatible = "iio-hwmon"; + io-channels = <&u14 0>, <&u14 1>, <&u14 2>; + }; + + clk_125: clock0 { /* u87 - GEM0/1 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + clk_27: clock1 { /* u86 - DP */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + + clk_26: clock2 { /* u89 - USB */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + clk_156: clock3 { /* u90 - SFP+ */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <156250000>; + }; + + clk_25_0: clock4 { /* u92/u91 - GEM2 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + clk_25_1: clock5 { /* u92/u91 - GEM3 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; +}; + +&i2c1 { /* I2C_SCK C26/C27 - MIO from SOM */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; + + u14: ina260@40 { /* u14 */ + compatible = "ti,ina260"; + #io-channel-cells = <1>; + label = "ina260-u14"; + reg = <0x40>; + }; + + slg7xl45106: gpio@11 { /* u19 - reset logic */ + compatible = "dlg,slg7xl45106"; + reg = <0x11>; + label = "resetchip"; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "USB0_PHY_RESET_B", "USB1_PHY_RESET_B", + "SD_RESET_B", "USB0_HUB_RESET_B", + "USB1_HUB_RESET_B", "PS_GEM0_RESET_B", + "PS_GEM1_RESET_B", ""; + }; + + i2c-mux@74 { /* u18 */ + compatible = "nxp,pca9546"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + usbhub_i2c0: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + usbhub_i2c1: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + /* Bus 2/3 are not connected */ + }; + + /* si5332@6a - u17 - clock-generator */ +}; + +/* GEM SGMII/DP and USB 3.0 */ +&psgtr { + status = "okay"; + /* gem0/1, dp, usb */ + clocks = <&clk_125>, <&clk_27>, <&clk_26>; + clock-names = "ref0", "ref1", "ref2"; +}; + +&zynqmp_dpsub { + status = "okay"; + phy-names = "dp-phy0"; + phys = <&psgtr 1 PHY_TYPE_DP 0 1>; + assigned-clock-rates = <27000000>, <25000000>, <300000000>; +}; + +&zynqmp_dpdma { + status = "okay"; + assigned-clock-rates = <600000000>; +}; + +&usb0 { /* mio52 - mio63 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; + reset-gpios = <&slg7xl45106 0 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; + + usbhub0: usb-hub { /* u43 */ + i2c-bus = <&usbhub_i2c0>; + compatible = "microchip,usb5744"; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; + + usb2244: usb-sd { /* u38 */ + compatible = "microchip,usb2244"; + reset-gpios = <&slg7xl45106 2 GPIO_ACTIVE_LOW>; + }; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; +}; + +&usb1 { /* mio64 - mio75 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 3 PHY_TYPE_USB3 1 2>; + reset-gpios = <&slg7xl45106 1 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; + + usbhub1: usb-hub { /* u84 */ + i2c-bus = <&usbhub_i2c1>; + compatible = "microchip,usb5744"; + reset-gpios = <&slg7xl45106 4 GPIO_ACTIVE_LOW>; + }; +}; + +&dwc3_1 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; +}; + +&gem0 { /* mdio mio50/51 */ + status = "okay"; + phys = <&psgtr 0 PHY_TYPE_SGMII 0 0>; + phy-handle = <&phy0>; + phy-mode = "sgmii"; + is-internal-pcspma; +}; + +&gem1 { /* mdio mio50/51, gem mio38 - mio49 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gem1_default>; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@4 { /* u81 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <4>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>; + ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <100>; + reset-deassert-us = <280>; + reset-gpios = <&slg7xl45106 5 GPIO_ACTIVE_LOW>; + }; + phy1: ethernet-phy@8 { /* u36 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <8>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>; + ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <100>; + reset-deassert-us = <280>; + reset-gpios = <&slg7xl45106 6 GPIO_ACTIVE_LOW>; + }; + }; +}; + +/* gem2/gem3 via PL with phys u79@2 and u80@3 */ + +&pinctrl0 { /* required by spec */ + status = "okay"; + + pinctrl_uart1_default: uart1-default { + conf { + groups = "uart1_9_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + drive-strength = <12>; + }; + + conf-rx { + pins = "MIO37"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO36"; + bias-disable; + }; + + mux { + groups = "uart1_9_grp"; + function = "uart1"; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + conf { + groups = "i2c1_6_grp"; + bias-pull-up; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + mux { + groups = "i2c1_6_grp"; + function = "i2c1"; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio { + conf { + groups = "gpio0_24_grp", "gpio0_25_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + mux { + groups = "gpio0_24_grp", "gpio0_25_grp"; + function = "gpio0"; + }; + }; + + pinctrl_gem1_default: gem1-default { + conf { + groups = "ethernet1_0_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO44", "MIO46", "MIO48"; + bias-high-impedance; + low-power-disable; + }; + + conf-bootstrap { + pins = "MIO45", "MIO47", "MIO49"; + bias-disable; + low-power-disable; + }; + + conf-tx { + pins = "MIO38", "MIO39", "MIO40", + "MIO41", "MIO42", "MIO43"; + bias-disable; + low-power-enable; + }; + + conf-mdio { + groups = "mdio1_0_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + bias-disable; + }; + + mux-mdio { + function = "mdio1"; + groups = "mdio1_0_grp"; + }; + + mux { + function = "ethernet1"; + groups = "ethernet1_0_grp"; + }; + }; + + pinctrl_usb0_default: usb0-default { + conf { + groups = "usb0_0_grp"; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO52", "MIO53", "MIO55"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; + }; + + conf-tx { + pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", + "MIO60", "MIO61", "MIO62", "MIO63"; + bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; + }; + + mux { + groups = "usb0_0_grp"; + function = "usb0"; + }; + }; + + pinctrl_usb1_default: usb1-default { + conf { + groups = "usb1_0_grp"; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO64", "MIO65", "MIO67"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; + }; + + conf-tx { + pins = "MIO66", "MIO68", "MIO69", "MIO70", "MIO71", + "MIO72", "MIO73", "MIO74", "MIO75"; + bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; + }; + + mux { + groups = "usb1_0_grp"; + function = "usb1"; + }; + }; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; +}; diff --git a/arch/arm/dts/zynqmp-sck-kv-g-revA.dts b/arch/arm/dts/zynqmp-sck-kv-g-revA.dts index 85994bef7cc..b714bd3eb1b 100644 --- a/arch/arm/dts/zynqmp-sck-kv-g-revA.dts +++ b/arch/arm/dts/zynqmp-sck-kv-g-revA.dts @@ -112,7 +112,7 @@ }; &zynqmp_dpsub { - status = "disabled"; + status = "okay"; phy-names = "dp-phy0", "dp-phy1"; phys = <&psgtr 1 PHY_TYPE_DP 0 0>, <&psgtr 0 PHY_TYPE_DP 1 0>; assigned-clock-rates = <27000000>, <25000000>, <300000000>; @@ -285,19 +285,22 @@ pinctrl_usb0_default: usb0-default { conf { groups = "usb0_0_grp"; - slew-rate = <SLEW_RATE_SLOW>; power-source = <IO_STANDARD_LVCMOS18>; }; conf-rx { pins = "MIO52", "MIO53", "MIO55"; bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; }; conf-tx { pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", "MIO60", "MIO61", "MIO62", "MIO63"; bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; }; mux { diff --git a/arch/arm/dts/zynqmp-sck-kv-g-revB.dts b/arch/arm/dts/zynqmp-sck-kv-g-revB.dts index b81c2e6b754..a1d8f9f0e51 100644 --- a/arch/arm/dts/zynqmp-sck-kv-g-revB.dts +++ b/arch/arm/dts/zynqmp-sck-kv-g-revB.dts @@ -272,19 +272,22 @@ pinctrl_usb0_default: usb0-default { conf { groups = "usb0_0_grp"; - slew-rate = <SLEW_RATE_SLOW>; power-source = <IO_STANDARD_LVCMOS18>; }; conf-rx { pins = "MIO52", "MIO53", "MIO55"; bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; }; conf-tx { pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", "MIO60", "MIO61", "MIO62", "MIO63"; bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; }; mux { diff --git a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts index d20f6675687..7ea2a1c96f4 100644 --- a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts +++ b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts @@ -187,19 +187,22 @@ conf { groups = "usb0_0_grp"; - slew-rate = <SLEW_RATE_SLOW>; power-source = <IO_STANDARD_LVCMOS18>; }; conf-rx { pins = "MIO52", "MIO53", "MIO55"; bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; }; conf-tx { pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", "MIO60", "MIO61", "MIO62", "MIO63"; bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; }; }; diff --git a/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts b/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts index f32f87acacb..4e6160bcd8b 100644 --- a/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts +++ b/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts @@ -335,19 +335,22 @@ conf { groups = "usb1_0_grp"; - slew-rate = <SLEW_RATE_SLOW>; power-source = <IO_STANDARD_LVCMOS18>; }; conf-rx { pins = "MIO64", "MIO65", "MIO67"; bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; }; conf-tx { pins = "MIO66", "MIO68", "MIO69", "MIO70", "MIO71", "MIO72", "MIO73", "MIO74", "MIO75"; bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; }; }; diff --git a/arch/arm/dts/zynqmp-zcu100-revC.dts b/arch/arm/dts/zynqmp-zcu100-revC.dts index ea630a43dc7..5e7bc7384fc 100644 --- a/arch/arm/dts/zynqmp-zcu100-revC.dts +++ b/arch/arm/dts/zynqmp-zcu100-revC.dts @@ -441,19 +441,22 @@ conf { groups = "usb0_0_grp"; - slew-rate = <SLEW_RATE_SLOW>; power-source = <IO_STANDARD_LVCMOS18>; }; conf-rx { pins = "MIO52", "MIO53", "MIO55"; bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; }; conf-tx { pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", "MIO60", "MIO61", "MIO62", "MIO63"; bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; }; }; @@ -465,19 +468,22 @@ conf { groups = "usb1_0_grp"; - slew-rate = <SLEW_RATE_SLOW>; power-source = <IO_STANDARD_LVCMOS18>; }; conf-rx { pins = "MIO64", "MIO65", "MIO67"; bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; }; conf-tx { pins = "MIO66", "MIO68", "MIO69", "MIO70", "MIO71", "MIO72", "MIO73", "MIO74", "MIO75"; bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu102-revA.dts b/arch/arm/dts/zynqmp-zcu102-revA.dts index c13b52a6aea..a4e92c8bb16 100644 --- a/arch/arm/dts/zynqmp-zcu102-revA.dts +++ b/arch/arm/dts/zynqmp-zcu102-revA.dts @@ -795,19 +795,22 @@ conf { groups = "usb0_0_grp"; - slew-rate = <SLEW_RATE_SLOW>; power-source = <IO_STANDARD_LVCMOS18>; }; conf-rx { pins = "MIO52", "MIO53", "MIO55"; bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; }; conf-tx { pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", "MIO60", "MIO61", "MIO62", "MIO63"; bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; }; }; diff --git a/arch/arm/dts/zynqmp-zcu104-revA.dts b/arch/arm/dts/zynqmp-zcu104-revA.dts index 50bf4790891..1418cffb204 100644 --- a/arch/arm/dts/zynqmp-zcu104-revA.dts +++ b/arch/arm/dts/zynqmp-zcu104-revA.dts @@ -402,20 +402,22 @@ conf { groups = "usb0_0_grp"; - slew-rate = <SLEW_RATE_SLOW>; power-source = <IO_STANDARD_LVCMOS18>; - drive-strength = <12>; }; conf-rx { pins = "MIO52", "MIO53", "MIO55"; bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; }; conf-tx { pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", "MIO60", "MIO61", "MIO62", "MIO63"; bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu104-revC.dts b/arch/arm/dts/zynqmp-zcu104-revC.dts index 752a9e38f3d..7fd19ca3a8c 100644 --- a/arch/arm/dts/zynqmp-zcu104-revC.dts +++ b/arch/arm/dts/zynqmp-zcu104-revC.dts @@ -414,20 +414,22 @@ conf { groups = "usb0_0_grp"; - slew-rate = <SLEW_RATE_SLOW>; power-source = <IO_STANDARD_LVCMOS18>; - drive-strength = <12>; }; conf-rx { pins = "MIO52", "MIO53", "MIO55"; bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; }; conf-tx { pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", "MIO60", "MIO61", "MIO62", "MIO63"; bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu106-revA.dts b/arch/arm/dts/zynqmp-zcu106-revA.dts index 6dfc8fe17bf..3e137676feb 100644 --- a/arch/arm/dts/zynqmp-zcu106-revA.dts +++ b/arch/arm/dts/zynqmp-zcu106-revA.dts @@ -793,19 +793,22 @@ conf { groups = "usb0_0_grp"; - slew-rate = <SLEW_RATE_SLOW>; power-source = <IO_STANDARD_LVCMOS18>; }; conf-rx { pins = "MIO52", "MIO53", "MIO55"; bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; }; conf-tx { pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", "MIO60", "MIO61", "MIO62", "MIO63"; bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; }; }; diff --git a/arch/arm/dts/zynqmp-zcu111-revA.dts b/arch/arm/dts/zynqmp-zcu111-revA.dts index 021fe88670f..e412992ff1b 100644 --- a/arch/arm/dts/zynqmp-zcu111-revA.dts +++ b/arch/arm/dts/zynqmp-zcu111-revA.dts @@ -652,19 +652,22 @@ conf { groups = "usb0_0_grp"; - slew-rate = <SLEW_RATE_SLOW>; power-source = <IO_STANDARD_LVCMOS18>; }; conf-rx { pins = "MIO52", "MIO53", "MIO55"; bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; }; conf-tx { pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", "MIO60", "MIO61", "MIO62", "MIO63"; bias-disable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; }; }; diff --git a/arch/arm/mach-zynqmp/handoff.c b/arch/arm/mach-zynqmp/handoff.c index 31346d9b2e2..b9e0c6c536b 100644 --- a/arch/arm/mach-zynqmp/handoff.c +++ b/arch/arm/mach-zynqmp/handoff.c @@ -79,7 +79,10 @@ struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry, atfhandoffparams->magic[2] = 'N'; atfhandoffparams->magic[3] = 'X'; + debug("Creating handoff:\n"); + if (bl32_entry) { + debug(" to BL32 at 0x%x EL-1, Secure\n", (u32)bl32_entry); atfhandoffparams->partition[index].entry_point = bl32_entry; atfhandoffparams->partition[index].flags = FSBL_FLAGS_EL1 << FSBL_FLAGS_EL_SHIFT | FSBL_FLAGS_SECURE << FSBL_FLAGS_TZ_SHIFT; @@ -87,6 +90,7 @@ struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry, } if (bl33_entry) { + debug(" to BL33 at 0x%x EL-2\n", (u32)bl33_entry); atfhandoffparams->partition[index].entry_point = bl33_entry; atfhandoffparams->partition[index].flags = FSBL_FLAGS_EL2 << FSBL_FLAGS_EL_SHIFT; diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index e609ae0c9cd..76233ef563f 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -4,6 +4,9 @@ menu "M68000 architecture" config SYS_ARCH default "m68k" +config NEEDS_MANUAL_RELOC + def_bool y + # processor family config MCF520x select OF_CONTROL diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index d7d1b219704..ce157a79ccc 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -4,6 +4,20 @@ menu "MicroBlaze architecture" config SYS_ARCH default "microblaze" +config NEEDS_MANUAL_RELOC + bool "Disable position-independent pre-relocation code" + default y + help + U-Boot expects to be linked to a specific hard-coded address, and to + be loaded to and run from that address. This option lifts that + restriction, thus allowing the code to be loaded to and executed from + almost any 4K aligned address. This logic relies on the relocation + information that is embedded in the binary to support U-Boot + relocating itself to the top-of-RAM later during execution. + +config STATIC_RELA + def_bool y if !NEEDS_MANUAL_RELOC + choice prompt "Target select" optional @@ -25,14 +39,6 @@ config TARGET_MICROBLAZE_GENERIC endchoice -config DCACHE - bool "Enable dcache support" - default y - -config ICACHE - bool "Enable icache support" - default y - source "board/xilinx/Kconfig" source "board/xilinx/microblaze-generic/Kconfig" diff --git a/arch/microblaze/config.mk b/arch/microblaze/config.mk index de5b97e719c..d35b4f6db7a 100644 --- a/arch/microblaze/config.mk +++ b/arch/microblaze/config.mk @@ -16,3 +16,14 @@ LDFLAGS_FINAL += --gc-sections ifeq ($(CONFIG_SPL_BUILD),) PLATFORM_CPPFLAGS += -fPIC endif + +ifeq ($(CONFIG_STATIC_RELA),y) +PLATFORM_CPPFLAGS += -fPIC +LDFLAGS_u-boot += -pic +endif + +ifeq ($(CONFIG_SYS_LITTLE_ENDIAN),y) +PLATFORM_ELFFLAGS += -B microblaze $(OBJCOPYFLAGS) -O elf32-microblazeel +else +PLATFORM_ELFFLAGS += -B microblaze $(OBJCOPYFLAGS) -O elf32-microblaze +endif diff --git a/arch/microblaze/cpu/Makefile b/arch/microblaze/cpu/Makefile index f7a83d07b6f..1c586a7de02 100644 --- a/arch/microblaze/cpu/Makefile +++ b/arch/microblaze/cpu/Makefile @@ -5,5 +5,7 @@ extra-y = start.o obj-y = irq.o -obj-y += interrupts.o cache.o exception.o timer.o +obj-y += interrupts.o cache.o exception.o cpuinfo.o +obj-$(CONFIG_STATIC_RELA) += relocate.o +obj-$(CONFIG_XILINX_MICROBLAZE0_PVR) += pvr.o obj-$(CONFIG_SPL_BUILD) += spl.o diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c index aa832d6be6d..829e6c7ae60 100644 --- a/arch/microblaze/cpu/cache.c +++ b/arch/microblaze/cpu/cache.c @@ -9,6 +9,61 @@ #include <cpu_func.h> #include <asm/asm.h> #include <asm/cache.h> +#include <asm/cpuinfo.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +static void __invalidate_icache(ulong addr, ulong size) +{ + if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WIC)) { + for (int i = 0; i < size; + i += gd_cpuinfo()->icache_line_length) { + asm volatile ( + "wic %0, r0;" + "nop;" + : + : "r" (addr + i) + : "memory"); + } + } +} + +void invalidate_icache_all(void) +{ + __invalidate_icache(0, gd_cpuinfo()->icache_size); +} + +static void __flush_dcache(ulong addr, ulong size) +{ + if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) { + for (int i = 0; i < size; + i += gd_cpuinfo()->dcache_line_length) { + asm volatile ( + "wdc.flush %0, r0;" + "nop;" + : + : "r" (addr + i) + : "memory"); + } + } +} + +void flush_dcache_range(unsigned long start, unsigned long end) +{ + if (start >= end) { + debug("Invalid dcache range - start: 0x%08lx end: 0x%08lx\n", + start, end); + return; + } + + __flush_dcache(start, end - start); +} + +void flush_dcache_all(void) +{ + __flush_dcache(0, gd_cpuinfo()->dcache_size); +} int dcache_status(void) { @@ -37,8 +92,8 @@ void icache_enable(void) void icache_disable(void) { - /* we are not generate ICACHE size -> flush whole cache */ - flush_cache(0, 32768); + invalidate_icache_all(); + MSRCLR(0x20); } @@ -49,26 +104,19 @@ void dcache_enable(void) void dcache_disable(void) { -#ifdef XILINX_USE_DCACHE - flush_cache(0, XILINX_DCACHE_BYTE_SIZE); -#endif + flush_dcache_all(); + MSRCLR(0x80); } void flush_cache(ulong addr, ulong size) { - int i; - for (i = 0; i < size; i += 4) - asm volatile ( -#ifdef CONFIG_ICACHE - "wic %0, r0;" -#endif - "nop;" -#ifdef CONFIG_DCACHE - "wdc.flush %0, r0;" -#endif - "nop;" - : - : "r" (addr + i) - : "memory"); + __invalidate_icache(addr, size); + __flush_dcache(addr, size); +} + +void flush_cache_all(void) +{ + invalidate_icache_all(); + flush_dcache_all(); } diff --git a/arch/microblaze/cpu/cpuinfo.c b/arch/microblaze/cpu/cpuinfo.c new file mode 100644 index 00000000000..f021f4e5e25 --- /dev/null +++ b/arch/microblaze/cpu/cpuinfo.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022, Ovidiu Panait <ovpanait@gmail.com> + */ +#include <common.h> +#include <asm/cpuinfo.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if CONFIG_IS_ENABLED(CPU_MICROBLAZE) +/* These key value are as per MBV field in PVR0 */ +static const struct microblaze_version_map cpu_ver_lookup[] = { + {"5.00.a", 0x01}, + {"5.00.b", 0x02}, + {"5.00.c", 0x03}, + {"6.00.a", 0x04}, + {"6.00.b", 0x06}, + {"7.00.a", 0x05}, + {"7.00.b", 0x07}, + {"7.10.a", 0x08}, + {"7.10.b", 0x09}, + {"7.10.c", 0x0a}, + {"7.10.d", 0x0b}, + {"7.20.a", 0x0c}, + {"7.20.b", 0x0d}, + {"7.20.c", 0x0e}, + {"7.20.d", 0x0f}, + {"7.30.a", 0x10}, + {"7.30.b", 0x11}, + {"8.00.a", 0x12}, + {"8.00.b", 0x13}, + {"8.10.a", 0x14}, + {"8.20.a", 0x15}, + {"8.20.b", 0x16}, + {"8.30.a", 0x17}, + {"8.40.a", 0x18}, + {"8.40.b", 0x19}, + {"8.50.a", 0x1a}, + {"8.50.b", 0x1c}, + {"8.50.c", 0x1e}, + {"9.0", 0x1b}, + {"9.1", 0x1d}, + {"9.2", 0x1f}, + {"9.3", 0x20}, + {"9.4", 0x21}, + {"9.5", 0x22}, + {"9.6", 0x23}, + {"10.0", 0x24}, + {"11.0", 0x25}, + {NULL, 0}, +}; + +static const struct microblaze_version_map family_string_lookup[] = { + {"virtex2", 0x4}, + {"virtex2pro", 0x5}, + {"spartan3", 0x6}, + {"virtex4", 0x7}, + {"virtex5", 0x8}, + {"spartan3e", 0x9}, + {"spartan3a", 0xa}, + {"spartan3an", 0xb}, + {"spartan3adsp", 0xc}, + {"spartan6", 0xd}, + {"virtex6", 0xe}, + {"virtex7", 0xf}, + /* FIXME There is no key code defined for spartan2 */ + {"spartan2", 0xf0}, + {"kintex7", 0x10}, + {"artix7", 0x11}, + {"zynq7000", 0x12}, + {"UltraScale Virtex", 0x13}, + {"UltraScale Kintex", 0x14}, + {"UltraScale+ Zynq", 0x15}, + {"UltraScale+ Virtex", 0x16}, + {"UltraScale+ Kintex", 0x17}, + {"Spartan7", 0x18}, + {NULL, 0}, +}; + +static const char *lookup_string(u32 code, + const struct microblaze_version_map *entry) +{ + for (; entry->string; ++entry) + if (entry->code == code) + return entry->string; + + return "(unknown)"; +} + +static const u32 lookup_code(const char *string, + const struct microblaze_version_map *entry) +{ + for (; entry->string; ++entry) + if (!strcmp(entry->string, string)) + return entry->code; + + return 0; +} + +const char *microblaze_lookup_fpga_family_string(const u32 code) +{ + return lookup_string(code, family_string_lookup); +} + +const char *microblaze_lookup_cpu_version_string(const u32 code) +{ + return lookup_string(code, cpu_ver_lookup); +} + +const u32 microblaze_lookup_fpga_family_code(const char *string) +{ + return lookup_code(string, family_string_lookup); +} + +const u32 microblaze_lookup_cpu_version_code(const char *string) +{ + return lookup_code(string, cpu_ver_lookup); +} +#endif /* CONFIG_CPU_MICROBLAZE */ + +void microblaze_early_cpuinfo_init(void) +{ + struct microblaze_cpuinfo *ci = gd_cpuinfo(); + + ci->icache_size = CONFIG_XILINX_MICROBLAZE0_ICACHE_SIZE; + ci->icache_line_length = 4; + + ci->dcache_size = CONFIG_XILINX_MICROBLAZE0_DCACHE_SIZE; + ci->dcache_line_length = 4; +} diff --git a/arch/microblaze/cpu/exception.c b/arch/microblaze/cpu/exception.c index d3640d3903b..9414776afa7 100644 --- a/arch/microblaze/cpu/exception.c +++ b/arch/microblaze/cpu/exception.c @@ -16,7 +16,7 @@ void _hw_exception_handler (void) /* loading address of exception EAR */ MFS(address, rear); - /* loading excetpion state register ESR */ + /* loading exception state register ESR */ MFS(state, resr); printf("Hardware exception at 0x%x address\n", address); R17(address); diff --git a/arch/microblaze/cpu/interrupts.c b/arch/microblaze/cpu/interrupts.c index fe65f3728fd..ac53208bda6 100644 --- a/arch/microblaze/cpu/interrupts.c +++ b/arch/microblaze/cpu/interrupts.c @@ -8,17 +8,8 @@ */ #include <common.h> -#include <command.h> -#include <fdtdec.h> -#include <irq_func.h> -#include <log.h> -#include <malloc.h> -#include <asm/global_data.h> -#include <asm/microblaze_intc.h> #include <asm/asm.h> -DECLARE_GLOBAL_DATA_PTR; - void enable_interrupts(void) { debug("Enable interrupts for the whole CPU\n"); @@ -34,183 +25,12 @@ int disable_interrupts(void) return (msr & 0x2) != 0; } -static struct irq_action *vecs; -static u32 irq_no; - -/* mapping structure to interrupt controller */ -microblaze_intc_t *intc; - -/* default handler */ -static void def_hdlr(void) -{ - puts("def_hdlr\n"); -} - -static void enable_one_interrupt(int irq) -{ - int mask; - int offset = 1; - - offset <<= irq; - mask = intc->ier; - intc->ier = (mask | offset); - - debug("Enable one interrupt irq %x - mask %x,ier %x\n", offset, mask, - intc->ier); - debug("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, - intc->iar, intc->mer); -} - -static void disable_one_interrupt(int irq) -{ - int mask; - int offset = 1; - - offset <<= irq; - mask = intc->ier; - intc->ier = (mask & ~offset); - - debug("Disable one interrupt irq %x - mask %x,ier %x\n", irq, mask, - intc->ier); - debug("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, - intc->iar, intc->mer); -} - -int install_interrupt_handler(int irq, interrupt_handler_t *hdlr, void *arg) -{ - struct irq_action *act; - - /* irq out of range */ - if ((irq < 0) || (irq > irq_no)) { - puts("IRQ out of range\n"); - return -1; - } - act = &vecs[irq]; - if (hdlr) { /* enable */ - act->handler = hdlr; - act->arg = arg; - act->count = 0; - enable_one_interrupt(irq); - return 0; - } - - /* Disable */ - act->handler = (interrupt_handler_t *)def_hdlr; - act->arg = (void *)irq; - disable_one_interrupt(irq); - return 1; -} - -/* initialization interrupt controller - hardware */ -static void intc_init(void) -{ - intc->mer = 0; - intc->ier = 0; - intc->iar = 0xFFFFFFFF; - /* XIntc_Start - hw_interrupt enable and all interrupt enable */ - intc->mer = 0x3; - - debug("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, - intc->iar, intc->mer); -} - int interrupt_init(void) { - int i; - const void *blob = gd->fdt_blob; - int node = 0; - - debug("INTC: Initialization\n"); - - node = fdt_node_offset_by_compatible(blob, node, - "xlnx,xps-intc-1.00.a"); - if (node != -1) { - fdt_addr_t base = fdtdec_get_addr(blob, node, "reg"); - if (base == FDT_ADDR_T_NONE) - return -1; - - debug("INTC: Base addr %lx\n", base); - intc = (microblaze_intc_t *)base; - irq_no = fdtdec_get_int(blob, node, "xlnx,num-intr-inputs", 0); - debug("INTC: IRQ NO %x\n", irq_no); - } else { - return node; - } - - if (irq_no) { - vecs = calloc(1, sizeof(struct irq_action) * irq_no); - if (vecs == NULL) { - puts("Interrupt vector allocation failed\n"); - return -1; - } - - /* initialize irq list */ - for (i = 0; i < irq_no; i++) { - vecs[i].handler = (interrupt_handler_t *)def_hdlr; - vecs[i].arg = (void *)i; - vecs[i].count = 0; - } - /* initialize intc controller */ - intc_init(); - enable_interrupts(); - } else { - puts("Undefined interrupt controller\n"); - } return 0; } void interrupt_handler(void) { - int irqs = intc->ivr; /* find active interrupt */ - int mask = 1; - int value; - struct irq_action *act = vecs + irqs; - - debug("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, - intc->iar, intc->mer); -#ifdef DEBUG - R14(value); -#endif - debug("Interrupt handler on %x line, r14 %x\n", irqs, value); - - debug("Jumping to interrupt handler rutine addr %x,count %x,arg %x\n", - (u32)act->handler, act->count, (u32)act->arg); - act->handler(act->arg); - act->count++; - - intc->iar = mask << irqs; - - debug("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr, - intc->ier, intc->iar, intc->mer); -#ifdef DEBUG - R14(value); -#endif - debug("Interrupt handler on %x line, r14 %x\n", irqs, value); -} - -#if defined(CONFIG_CMD_IRQ) -int do_irqinfo(struct cmd_tbl *cmdtp, int flag, int argc, const char *argv[]) -{ - int i; - struct irq_action *act = vecs; - - if (irq_no) { - puts("\nInterrupt-Information:\n\n" - "Nr Routine Arg Count\n" - "-----------------------------\n"); - - for (i = 0; i < irq_no; i++) { - if (act->handler != (interrupt_handler_t *)def_hdlr) { - printf("%02d %08x %08x %d\n", i, - (int)act->handler, (int)act->arg, - act->count); - } - act++; - } - puts("\n"); - } else { - puts("Undefined interrupt controller\n"); - } - return 0; + panic("Interrupt occurred\n"); } -#endif diff --git a/arch/microblaze/cpu/pvr.c b/arch/microblaze/cpu/pvr.c new file mode 100644 index 00000000000..23c0f912d43 --- /dev/null +++ b/arch/microblaze/cpu/pvr.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022, Ovidiu Panait <ovpanait@gmail.com> + */ +#include <common.h> +#include <asm/asm.h> +#include <asm/pvr.h> + +int microblaze_cpu_has_pvr_full(void) +{ + u32 msr, pvr0; + + MFS(msr, rmsr); + if (!(msr & PVR_MSR_BIT)) + return 0; + + get_pvr(0, pvr0); + debug("%s: pvr0 is 0x%08x\n", __func__, pvr0); + + if (!(pvr0 & PVR0_PVR_FULL_MASK)) + return 0; + + return 1; +} + +void microblaze_get_all_pvrs(u32 pvr[PVR_FULL_COUNT]) +{ + get_pvr(0, pvr[0]); + get_pvr(1, pvr[1]); + get_pvr(2, pvr[2]); + get_pvr(3, pvr[3]); + get_pvr(4, pvr[4]); + get_pvr(5, pvr[5]); + get_pvr(6, pvr[6]); + get_pvr(7, pvr[7]); + get_pvr(8, pvr[8]); + get_pvr(9, pvr[9]); + get_pvr(10, pvr[10]); + get_pvr(11, pvr[11]); + get_pvr(12, pvr[12]); +} diff --git a/arch/microblaze/cpu/relocate.c b/arch/microblaze/cpu/relocate.c new file mode 100644 index 00000000000..b00d02b1dfc --- /dev/null +++ b/arch/microblaze/cpu/relocate.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * (C) Copyright 2022 Advanced Micro Devices, Inc + * Michal Simek <michal.simek@amd.com> + */ + +#include <common.h> +#include <elf.h> + +#define R_MICROBLAZE_NONE 0 +#define R_MICROBLAZE_32 1 +#define R_MICROBLAZE_REL 16 +#define R_MICROBLAZE_GLOB_DAT 18 + +/** + * mb_fix_rela - update relocation to new address + * @reloc_addr: new relocation address + * @verbose: enable version messages + * @rela_start: rela section start + * @rela_end: rela section end + * @dyn_start: dynamic section start + * @origin_addr: address where u-boot starts(doesn't need to be CONFIG_SYS_TEXT_BASE) + */ +void mb_fix_rela(u32 reloc_addr, u32 verbose, u32 rela_start, + u32 rela_end, u32 dyn_start, u32 origin_addr) +{ + u32 num, type, mask, i, reloc_off; + + /* + * Return in case u-boot.elf is used directly. + * Skip it when u-boot.bin is loaded to different address than + * CONFIG_SYS_TEXT_BASE. In this case relocation is necessary to run. + */ + if (reloc_addr == CONFIG_SYS_TEXT_BASE) { + debug_cond(verbose, + "Relocation address is the same - skip relocation\n"); + return; + } + + reloc_off = reloc_addr - origin_addr; + + debug_cond(verbose, "Relocation address:\t0x%08x\n", reloc_addr); + debug_cond(verbose, "Relocation offset:\t0x%08x\n", reloc_off); + debug_cond(verbose, "Origin address:\t0x%08x\n", origin_addr); + debug_cond(verbose, "Rela start:\t0x%08x\n", rela_start); + debug_cond(verbose, "Rela end:\t0x%08x\n", rela_end); + debug_cond(verbose, "Dynsym start:\t0x%08x\n", dyn_start); + + num = (rela_end - rela_start) / sizeof(Elf32_Rela); + + debug_cond(verbose, "Number of entries:\t%u\n", num); + + for (i = 0; i < num; i++) { + Elf32_Rela *rela; + u32 temp; + + rela = (Elf32_Rela *)(rela_start + sizeof(Elf32_Rela) * i); + + mask = 0xffULL; /* would be different on 32-bit */ + type = rela->r_info & mask; + + debug_cond(verbose, "\nRela possition:\t%d/0x%x\n", + i, (u32)rela); + + switch (type) { + case R_MICROBLAZE_REL: + temp = *(u32 *)rela->r_offset; + + debug_cond(verbose, "Type:\tREL\n"); + debug_cond(verbose, "Rela r_offset:\t\t0x%x\n", rela->r_offset); + debug_cond(verbose, "Rela r_info:\t\t0x%x\n", rela->r_info); + debug_cond(verbose, "Rela r_addend:\t\t0x%x\n", rela->r_addend); + debug_cond(verbose, "Value at r_offset:\t0x%x\n", temp); + + rela->r_offset += reloc_off; + rela->r_addend += reloc_off; + + temp = *(u32 *)rela->r_offset; + temp += reloc_off; + *(u32 *)rela->r_offset = temp; + + debug_cond(verbose, "New:Rela r_offset:\t0x%x\n", rela->r_offset); + debug_cond(verbose, "New:Rela r_addend:\t0x%x\n", rela->r_addend); + debug_cond(verbose, "New:Value at r_offset:\t0x%x\n", temp); + break; + case R_MICROBLAZE_32: + case R_MICROBLAZE_GLOB_DAT: + debug_cond(verbose, "Type:\t(32/GLOB) %u\n", type); + debug_cond(verbose, "Rela r_offset:\t\t0x%x\n", rela->r_offset); + debug_cond(verbose, "Rela r_info:\t\t0x%x\n", rela->r_info); + debug_cond(verbose, "Rela r_addend:\t\t0x%x\n", rela->r_addend); + debug_cond(verbose, "Value at r_offset:\t0x%x\n", temp); + + rela->r_offset += reloc_off; + + temp = *(u32 *)rela->r_offset; + temp += reloc_off; + *(u32 *)rela->r_offset = temp; + + debug_cond(verbose, "New:Rela r_offset:\t0x%x\n", rela->r_offset); + debug_cond(verbose, "New:Value at r_offset:\t0x%x\n", temp); + break; + case R_MICROBLAZE_NONE: + debug_cond(verbose, "R_MICROBLAZE_NONE - skip\n"); + break; + default: + debug_cond(verbose, "warning: unsupported relocation type %d at %x\n", + type, rela->r_offset); + } + } +} diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 25e9968e4c6..a877db305e4 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -10,18 +10,64 @@ #include <asm-offsets.h> #include <config.h> +#if defined(CONFIG_STATIC_RELA) +#define SYM_ADDR(reg, reg_add, symbol) \ + mfs r20, rpc; \ + addik r20, r20, _GLOBAL_OFFSET_TABLE_ + 8; \ + lwi reg, r20, symbol@GOT; \ + addk reg, reg reg_add; +#else +#define SYM_ADDR(reg, reg_add, symbol) \ + addi reg, reg_add, symbol +#endif + .text .global _start _start: mts rmsr, r0 /* disable cache */ + mfs r20, rpc + addi r20, r20, -4 - addi r8, r0, _end - mts rslr, r8 + mts rslr, r0 + mts rshr, r20 #if defined(CONFIG_SPL_BUILD) addi r1, r0, CONFIG_SPL_STACK #else - addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET + add r1, r0, r20 +#if defined(CONFIG_STATIC_RELA) + bri 1f + + /* Force alignment for easier ASM code below */ +#define ALIGNMENT_ADDR 0x20 + .align 4 +uboot_dyn_start: + .word __rel_dyn_start + +uboot_dyn_end: + .word __rel_dyn_end + +uboot_sym_start: + .word __dyn_sym_start +1: + + addi r5, r20, 0 + add r6, r0, r0 + + lwi r7, r20, ALIGNMENT_ADDR + addi r7, r7, -CONFIG_SYS_TEXT_BASE + add r7, r7, r5 + lwi r8, r20, ALIGNMENT_ADDR + 0x4 + addi r8, r8, -CONFIG_SYS_TEXT_BASE + add r8, r8, r5 + lwi r9, r20, ALIGNMENT_ADDR + 0x8 + addi r9, r9, -CONFIG_SYS_TEXT_BASE + add r9, r9, r5 + addi r10, r0, CONFIG_SYS_TEXT_BASE + + brlid r15, mb_fix_rela + nop +#endif #endif addi r1, r1, -4 /* Decrement SP to top of memory */ @@ -29,7 +75,7 @@ _start: /* Call board_init_f_alloc_reserve with the current stack pointer as * parameter. */ add r5, r0, r1 - bralid r15, board_init_f_alloc_reserve + brlid r15, board_init_f_alloc_reserve nop /* board_init_f_alloc_reserve returns a pointer to the allocated area @@ -41,20 +87,25 @@ _start: /* Call board_init_f_init_reserve with the address returned by * board_init_f_alloc_reserve as parameter. */ add r5, r0, r3 - bralid r15, board_init_f_init_reserve + brlid r15, board_init_f_init_reserve nop #if !defined(CONFIG_SPL_BUILD) /* Setup vectors with pre-relocation symbols */ or r5, r0, r0 - bralid r15, __setup_exceptions + brlid r15, __setup_exceptions nop #endif + /* + * Initialize global data cpuinfo with default values (cache + * size, cache line size, etc). + */ + brlid r15, microblaze_early_cpuinfo_init + nop + /* Flush cache before enable cache */ - addik r5, r0, 0 - addik r6, r0, XILINX_DCACHE_BYTE_SIZE - bralid r15, flush_cache + brlid r15, flush_cache_all nop /* enable instruction and data cache */ @@ -64,8 +115,8 @@ _start: clear_bss: /* clear BSS segments */ - addi r5, r0, __bss_start - addi r4, r0, __bss_end + SYM_ADDR(r5, r0, __bss_start) + SYM_ADDR(r4, r0, __bss_end) cmp r6, r5, r4 beqi r6, 3f 2: @@ -75,14 +126,14 @@ clear_bss: bnei r6, 2b 3: /* jumping to board_init */ #ifdef CONFIG_DEBUG_UART - bralid r15, debug_uart_init + brlid r15, debug_uart_init nop #endif #ifndef CONFIG_SPL_BUILD or r5, r0, r0 /* flags - empty */ - brai board_init_f + bri board_init_f #else - brai board_init_r + bri board_init_r #endif 1: bri 1b @@ -141,7 +192,8 @@ __setup_exceptions: swi r2, r4, 0x0 /* reset address - imm opcode */ swi r3, r4, 0x4 /* reset address - brai opcode */ - addik r6, r0, CONFIG_SYS_TEXT_BASE + SYM_ADDR(r6, r0, _start) + /* Intentionally keep reset vector back to origin u-boot location */ sw r6, r1, r0 lhu r7, r1, r10 rsubi r8, r10, 0x2 @@ -154,7 +206,7 @@ __setup_exceptions: swi r2, r4, 0x8 /* user vector exception - imm opcode */ swi r3, r4, 0xC /* user vector exception - brai opcode */ - addik r6, r5, _exception_handler + SYM_ADDR(r6, r5, _exception_handler) sw r6, r1, r0 /* * BIG ENDIAN memory map for user exception @@ -187,7 +239,7 @@ __setup_exceptions: swi r2, r4, 0x10 /* interrupt - imm opcode */ swi r3, r4, 0x14 /* interrupt - brai opcode */ - addik r6, r5, _interrupt_handler + SYM_ADDR(r6, r5, _interrupt_handler) sw r6, r1, r0 lhu r7, r1, r10 rsubi r8, r10, 0x12 @@ -199,7 +251,7 @@ __setup_exceptions: swi r2, r4, 0x20 /* hardware exception - imm opcode */ swi r3, r4, 0x24 /* hardware exception - brai opcode */ - addik r6, r5, _hw_exception_handler + SYM_ADDR(r6, r5, _hw_exception_handler) sw r6, r1, r0 lhu r7, r1, r10 rsubi r8, r10, 0x22 @@ -221,39 +273,6 @@ __setup_exceptions: .end __setup_exceptions /* - * Read 16bit little endian - */ - .text - .global in16 - .ent in16 - .align 2 -in16: lhu r3, r0, r5 - bslli r4, r3, 8 - bsrli r3, r3, 8 - andi r4, r4, 0xffff - or r3, r3, r4 - rtsd r15, 8 - sext16 r3, r3 - .end in16 - -/* - * Write 16bit little endian - * first parameter(r5) - address, second(r6) - short value - */ - .text - .global out16 - .ent out16 - .align 2 -out16: bslli r3, r6, 8 - bsrli r6, r6, 8 - andi r3, r3, 0xffff - or r3, r3, r6 - sh r3, r0, r5 - rtsd r15, 8 - or r0, r0, r0 - .end out16 - -/* * Relocate u-boot */ .text @@ -267,31 +286,54 @@ relocate_code: * r7 - reloc_addr */ addi r1, r5, 0 /* Start to use new SP */ + mts rshr, r1 addi r31, r6, 0 /* Start to use new GD */ - add r23, r0, r7 /* Move reloc addr to r23 */ /* Relocate text and data - r12 temp value */ - addi r21, r0, _start - addi r22, r0, _end - 4 /* Include BSS too */ + SYM_ADDR(r21, r0, _start) + SYM_ADDR(r22, r0, _end) /* Include BSS too */ + addi r22, r22, -4 rsub r6, r21, r22 or r5, r0, r0 1: lw r12, r21, r5 /* Load u-boot data */ - sw r12, r23, r5 /* Write zero to loc */ + sw r12, r7, r5 /* Write zero to loc */ cmp r12, r5, r6 /* Check if we have reach the end */ bneid r12, 1b addi r5, r5, 4 /* Increment to next loc - relocate code */ /* R23 points to the base address. */ - add r23, r0, r7 /* Move reloc addr to r23 */ - addi r24, r0, CONFIG_SYS_TEXT_BASE /* Get reloc offset */ - rsub r23, r24, r23 /* keep - this is already here gd->reloc_off */ + rsub r23, r21, r7 /* keep - this is already here gd->reloc_off */ /* Setup vectors with post-relocation symbols */ add r5, r0, r23 /* load gd->reloc_off to r5 */ - bralid r15, __setup_exceptions + brlid r15, __setup_exceptions + nop + +#if defined(CONFIG_STATIC_RELA) + /* reloc_offset is current location */ + SYM_ADDR(r10, r0, _start) + + /* r5 new address where I should copy code */ + add r5, r0, r7 /* Move reloc addr to r5 */ + + /* Verbose message */ + addi r6, r0, 0 + + SYM_ADDR(r7, r0, __rel_dyn_start) + rsub r7, r10, r7 + add r7, r7, r5 + SYM_ADDR(r8, r0, __rel_dyn_end) + rsub r8, r10, r8 + add r8, r8, r5 + SYM_ADDR(r9, r0, __dyn_sym_start) + rsub r9, r10, r9 + add r9, r9, r5 + brlid r15, mb_fix_rela nop + /* end of code which does relocation */ +#else /* Check if GOT exist */ addik r21, r23, _got_start addik r22, r23, _got_end @@ -309,21 +351,15 @@ relocate_code: cmpu r12, r21, r22 /* Check if this cross boundary */ bneid r12, 3b addik r21. r21, 4 - - /* Update pointer to GOT */ - mfs r20, rpc - addik r20, r20, _GLOBAL_OFFSET_TABLE_ + 8 - addk r20, r20, r23 +#endif /* Flush caches to ensure consistency */ - addik r5, r0, 0 - addik r6, r0, XILINX_DCACHE_BYTE_SIZE - bralid r15, flush_cache + brlid r15, flush_cache_all nop 2: addi r5, r31, 0 /* gd is initialized in board_r.c */ - addi r6, r0, CONFIG_SYS_TEXT_BASE - addi r12, r23, board_init_r + SYM_ADDR(r6, r0, _start) + SYM_ADDR(r12, r23, board_init_r) bra r12 /* Jump to relocated code */ .end relocate_code diff --git a/arch/microblaze/cpu/timer.c b/arch/microblaze/cpu/timer.c deleted file mode 100644 index 647bdcd5ba5..00000000000 --- a/arch/microblaze/cpu/timer.c +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2007 Michal Simek - * - * Michal SIMEK <monstr@monstr.eu> - */ - -#include <common.h> -#include <fdtdec.h> -#include <init.h> -#include <log.h> -#include <time.h> -#include <asm/global_data.h> -#include <asm/microblaze_timer.h> -#include <asm/microblaze_intc.h> -#include <linux/delay.h> - -DECLARE_GLOBAL_DATA_PTR; - -volatile int timestamp = 0; -microblaze_timer_t *tmr; - -ulong get_timer (ulong base) -{ - if (tmr) - return timestamp - base; - return timestamp++ - base; -} - -void __udelay(unsigned long usec) -{ - u32 i; - - if (tmr) { - i = get_timer(0); - while ((get_timer(0) - i) < (usec / 1000)) - ; - } -} - -#ifndef CONFIG_SPL_BUILD -static void timer_isr(void *arg) -{ - timestamp++; - tmr->control = tmr->control | TIMER_INTERRUPT; -} - -int timer_init (void) -{ - int irq = -1; - u32 preload = 0; - u32 ret = 0; - const void *blob = gd->fdt_blob; - int node = 0; - u32 cell[2]; - - debug("TIMER: Initialization\n"); - - /* Do not init before relocation */ - if (!(gd->flags & GD_FLG_RELOC)) - return 0; - - node = fdt_node_offset_by_compatible(blob, node, - "xlnx,xps-timer-1.00.a"); - if (node != -1) { - fdt_addr_t base = fdtdec_get_addr(blob, node, "reg"); - if (base == FDT_ADDR_T_NONE) - return -1; - - debug("TIMER: Base addr %lx\n", base); - tmr = (microblaze_timer_t *)base; - - ret = fdtdec_get_int_array(blob, node, "interrupts", - cell, ARRAY_SIZE(cell)); - if (ret) - return ret; - - irq = cell[0]; - debug("TIMER: IRQ %x\n", irq); - - preload = fdtdec_get_int(blob, node, "clock-frequency", 0); - preload /= CONFIG_SYS_HZ; - } else { - return node; - } - - if (tmr && preload && irq >= 0) { - tmr->loadreg = preload; - tmr->control = TIMER_INTERRUPT | TIMER_RESET; - tmr->control = TIMER_ENABLE | TIMER_ENABLE_INTR |\ - TIMER_RELOAD | TIMER_DOWN_COUNT; - timestamp = 0; - ret = install_interrupt_handler (irq, timer_isr, (void *)tmr); - if (ret) - tmr = NULL; - } - /* No problem if timer is not found/initialized */ - return 0; -} -#else -int timer_init(void) -{ - return 0; -} -#endif - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On Microblaze it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On Microblaze it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return CONFIG_SYS_HZ; -} diff --git a/arch/microblaze/cpu/u-boot.lds b/arch/microblaze/cpu/u-boot.lds index 8bd515b0992..a2c8fb2e21c 100644 --- a/arch/microblaze/cpu/u-boot.lds +++ b/arch/microblaze/cpu/u-boot.lds @@ -46,6 +46,20 @@ SECTIONS } __init_end = . ; + . = ALIGN(4); + __rel_dyn_start = .; + .rela.dyn : { + *(.rela.dyn) + } + __rel_dyn_end = .; + + . = ALIGN(4); + __dyn_sym_start = .; + .dynsym : { + *(.dynsym) + } + __dyn_sym_end = .; + .bss ALIGN(0x4): { __bss_start = .; diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h index baee01a0e28..c39b66dd7da 100644 --- a/arch/microblaze/include/asm/cache.h +++ b/arch/microblaze/include/asm/cache.h @@ -18,4 +18,9 @@ #define ARCH_DMA_MINALIGN 16 #endif +/** + * flush_cache_all - flush the entire instruction/data caches + */ +void flush_cache_all(void); + #endif /* __MICROBLAZE_CACHE_H__ */ diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h new file mode 100644 index 00000000000..86d2c8a034d --- /dev/null +++ b/arch/microblaze/include/asm/cpuinfo.h @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2022, Ovidiu Panait <ovpanait@gmail.com> + */ + +#ifndef __ASM_MICROBLAZE_CPUINFO_H +#define __ASM_MICROBLAZE_CPUINFO_H + +/** + * struct microblaze_cpuinfo - CPU info for microblaze processor core. + * + * @icache_size: Size of instruction cache memory in bytes. + * @icache_line_length: Instruction cache line length in bytes. + * @dcache_size: Size of data cache memory in bytes. + * @dcache_line_length: Data cache line length in bytes. + * @use_mmu: MMU support flag. + * @cpu_freq: Cpu clock frequency in Hz. + * @addr_size: Address bus width in bits. + * @ver_code: Cpu version code. + * @fpga_code: FPGA family version code. + */ +struct microblaze_cpuinfo { + u32 icache_size; + u32 icache_line_length; + + u32 dcache_size; + u32 dcache_line_length; + +#if CONFIG_IS_ENABLED(CPU_MICROBLAZE) + u32 use_mmu; + u32 cpu_freq; + u32 addr_size; + + u32 ver_code; + u32 fpga_code; +#endif /* CONFIG_CPU_MICROBLAZE */ +}; + +/** + * struct microblaze_version_data - Maps a hex version code to a cpu/fpga name. + */ +struct microblaze_version_map { + const char *string; + const u32 code; +}; + +/** + * microblaze_lookup_cpu_version_code() - Get hex version code for the + * specified cpu name string. + * + * This function searches the cpu_ver_lookup[] array for the hex version code + * associated with a specific CPU name. The version code is returned if a match + * is found, otherwise 0. + * + * @string: cpu name string + * + * Return: >0 if the entry is found, 0 otherwise. + */ +const u32 microblaze_lookup_cpu_version_code(const char *string); + +/** + * microblaze_lookup_fpga_family_code() - Get hex version code for the + * specified fpga family name. + * + * This function searches the family_string_lookup[] array for the hex version + * code associated with a specific fpga family name. The version code is + * returned if a match is found, otherwise 0. + * + * @string: fpga family name string + * + * Return: >0 if the entry is found, 0 otherwise. + */ +const u32 microblaze_lookup_fpga_family_code(const char *string); + +/** + * microblaze_lookup_cpu_version_string() - Get cpu name for the specified cpu + * version code. + * + * This function searches the cpu_ver_lookup[] array for the cpu name string + * associated with a specific version code. The cpu name is returned if a match + * is found, otherwise "(unknown)". + * + * @code: cpu version code + * + * Return: Pointer to the cpu name if the entry is found, otherwise "(unknown)". + */ +const char *microblaze_lookup_cpu_version_string(const u32 code); + +/** + * microblaze_lookup_fpga_family_string() - Get fpga family name for the + * specified version code. + * + * This function searches the family_string_lookup[] array for the fpga family + * name string associated with a specific version code. The fpga family name is + * returned if a match is found, otherwise "(unknown)". + * + * @code: fpga family version code + * + * Return: Pointer to the fpga family name if the entry is found, otherwise + * "(unknown)". + */ +const char *microblaze_lookup_fpga_family_string(const u32 code); + +/** + * microblaze_early_cpuinfo_init() - Initialize cpuinfo with default values. + * + * Initializes the global data cpuinfo structure with default values (cache + * size, cache line size, etc.). It is called very early in the boot process + * (start.S codepath right before the first cache flush call) to ensure that + * cache related operations are properly handled. + */ +void microblaze_early_cpuinfo_init(void); + +#endif /* __ASM_MICROBLAZE_CPUINFO_H */ diff --git a/arch/microblaze/include/asm/global_data.h b/arch/microblaze/include/asm/global_data.h index 05868ac4f54..93506dec894 100644 --- a/arch/microblaze/include/asm/global_data.h +++ b/arch/microblaze/include/asm/global_data.h @@ -8,12 +8,17 @@ #ifndef __ASM_GBL_DATA_H #define __ASM_GBL_DATA_H +#include <asm/cpuinfo.h> + /* Architecture-specific global data */ struct arch_global_data { + struct microblaze_cpuinfo cpuinfo; }; #include <asm-generic/global_data.h> #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r31") +#define gd_cpuinfo() ((struct microblaze_cpuinfo *)&gd->arch.cpuinfo) + #endif /* __ASM_GBL_DATA_H */ diff --git a/arch/microblaze/include/asm/microblaze_intc.h b/arch/microblaze/include/asm/microblaze_intc.h deleted file mode 100644 index a7e8715851e..00000000000 --- a/arch/microblaze/include/asm/microblaze_intc.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2007 Michal Simek - * - * Michal SIMEK <monstr@monstr.cz> - */ - -#include <irq_func.h> - -typedef volatile struct microblaze_intc_t { - int isr; /* interrupt status register */ - int ipr; /* interrupt pending register */ - int ier; /* interrupt enable register */ - int iar; /* interrupt acknowledge register */ - int sie; /* set interrupt enable bits */ - int cie; /* clear interrupt enable bits */ - int ivr; /* interrupt vector register */ - int mer; /* master enable register */ -} microblaze_intc_t; - -struct irq_action { - interrupt_handler_t *handler; /* pointer to interrupt rutine */ - void *arg; - int count; /* number of interrupt */ -}; - -/** - * Register and unregister interrupt handler rutines - * - * @param irq IRQ number - * @param hdlr Interrupt handler rutine - * @param arg Pointer to argument which is passed to int. handler rutine - * Return: 0 if registration pass, 1 if unregistration pass, - * or an error code < 0 otherwise - */ -int install_interrupt_handler(int irq, interrupt_handler_t *hdlr, - void *arg); diff --git a/arch/microblaze/include/asm/microblaze_timer.h b/arch/microblaze/include/asm/microblaze_timer.h deleted file mode 100644 index 2ed1651ffcf..00000000000 --- a/arch/microblaze/include/asm/microblaze_timer.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2007 Michal Simek - * - * Michal SIMEK <monstr@monstr.cz> - */ - -#define TIMER_ENABLE_ALL 0x400 /* ENALL */ -#define TIMER_PWM 0x200 /* PWMA0 */ -#define TIMER_INTERRUPT 0x100 /* T0INT */ -#define TIMER_ENABLE 0x080 /* ENT0 */ -#define TIMER_ENABLE_INTR 0x040 /* ENIT0 */ -#define TIMER_RESET 0x020 /* LOAD0 */ -#define TIMER_RELOAD 0x010 /* ARHT0 */ -#define TIMER_EXT_CAPTURE 0x008 /* CAPT0 */ -#define TIMER_EXT_COMPARE 0x004 /* GENT0 */ -#define TIMER_DOWN_COUNT 0x002 /* UDT0 */ -#define TIMER_CAPTURE_MODE 0x001 /* MDT0 */ - -typedef volatile struct microblaze_timer_t { - int control; /* control/statuc register TCSR */ - int loadreg; /* load register TLR */ - int counter; /* timer/counter register */ -} microblaze_timer_t; - -int timer_init(void); diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h new file mode 100644 index 00000000000..bfe159af794 --- /dev/null +++ b/arch/microblaze/include/asm/pvr.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2022, Ovidiu Panait <ovpanait@gmail.com> + */ + +#ifndef __ASM_MICROBLAZE_PVR_H +#define __ASM_MICROBLAZE_PVR_H + +#include <asm/asm.h> + +#define PVR_FULL_COUNT 13 /* PVR0 - PVR12 */ + +#define __get_pvr(val, reg) \ + __asm__ __volatile__ ("mfs %0," #reg : "=r" (val) :: "memory") +#define get_pvr(pvrid, val) \ + __get_pvr(val, rpvr ## pvrid) + +#define PVR_MSR_BIT 0x00000400 + +/* PVR0 masks */ +#define PVR0_PVR_FULL_MASK 0x80000000 +#define PVR0_VERSION_MASK 0x0000FF00 + +/* PVR4 masks - ICache configs */ +#define PVR4_ICACHE_LINE_LEN_MASK 0x00E00000 /* ICLL */ +#define PVR4_ICACHE_BYTE_SIZE_MASK 0x001F0000 /* ICBS */ + +/* PVR5 masks - DCache configs */ +#define PVR5_DCACHE_LINE_LEN_MASK 0x00E00000 /* DCLL */ +#define PVR5_DCACHE_BYTE_SIZE_MASK 0x001F0000 /* DCBS */ + +/* PVR10 masks - FPGA family */ +#define PVR10_TARGET_FAMILY_MASK 0xFF000000 + +/* PVR11 masks - MMU */ +#define PVR11_USE_MMU 0xC0000000 + +/* PVR access macros */ +#define PVR_VERSION(pvr) \ + ((pvr[0] & PVR0_VERSION_MASK) >> 8) + +#define PVR_ICACHE_LINE_LEN(pvr) \ + ((1 << ((pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21)) << 2) +#define PVR_ICACHE_BYTE_SIZE(pvr) \ + (1 << ((pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16)) + +#define PVR_DCACHE_LINE_LEN(pvr) \ + ((1 << ((pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21)) << 2) +#define PVR_DCACHE_BYTE_SIZE(pvr) \ + (1 << ((pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16)) + +#define PVR_USE_MMU(pvr) \ + ((pvr[11] & PVR11_USE_MMU) >> 30) + +#define PVR_TARGET_FAMILY(pvr) \ + ((pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24) + +/** + * microblaze_cpu_has_pvr_full() - Check for full PVR support + * + * Check MSR register for PVR support and, if applicable, check the PVR0 + * register for full PVR support. + * + * Return: 1 if there is full PVR support, 0 otherwise. + */ +int microblaze_cpu_has_pvr_full(void); + +/** + * microblaze_get_all_pvrs() - Copy PVR0-PVR12 to destination array + * + * @pvr: destination array of size PVR_FULL_COUNT + */ +void microblaze_get_all_pvrs(u32 pvr[PVR_FULL_COUNT]); + +#endif /* __ASM_MICROBLAZE_PVR_H */ diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 12ea32488e6..af946b86428 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -57,9 +57,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) "(fake run for tracing)" : ""); bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel"); -#ifdef XILINX_USE_DCACHE - flush_cache(0, XILINX_DCACHE_BYTE_SIZE); -#endif + flush_cache_all(); if (!fake) { /* diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9b62764f4fe..2e0793a7a7b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -181,24 +181,6 @@ source "arch/mips/mach-octeon/Kconfig" if MIPS choice - prompt "Endianness selection" - help - Some MIPS boards can be configured for either little or big endian - byte order. These modes require different U-Boot images. In general there - is one preferred byteorder for a particular system but some systems are - just as commonly used in the one or the other endianness. - -config SYS_BIG_ENDIAN - bool "Big endian" - depends on SUPPORTS_BIG_ENDIAN - -config SYS_LITTLE_ENDIAN - bool "Little endian" - depends on SUPPORTS_LITTLE_ENDIAN - -endchoice - -choice prompt "CPU selection" default CPU_MIPS32_R2 |