diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8f8627f7d003..ddfc1af45320 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,6 +14,8 @@ jobs: strategy: matrix: defconfig: + - 'zynq_pluto_defconfig' + - 'zynq_m2k_defconfig' - 'zynq_adrv9361_defconfig' - 'zynq_adrv9364_defconfig' - 'zynq_coraz7_defconfig' @@ -26,7 +28,8 @@ jobs: matrix: defconfig: - 'adi_zynqmp_adrv9009_zu11eg_adrv2crr_fmc_defconfig' - - 'zynqmp_pluto_ng_defconfig' + - 'zynqmp_jupiter_sdr_defconfig' + - 'zynqmp_kv260_defconfig' check: uses: analogdevicesinc/u-boot/.github/workflows/checks.yml@ci diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 2f4b491f3cb7..accf1774c2db 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -236,6 +236,12 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \ zynq-microzed.dtb \ zynq-minized.dtb \ zynq-picozed.dtb \ + zynq-adrv9361.dtb \ + zynq-adrv9364.dtb \ + zynq-coraz7s.dtb \ + zynq-m2k.dtb \ + zynq-pluto-sdr.dtb \ + zynq-sidekiqz2.dtb \ zynq-syzygy-hub.dtb \ zynq-topic-miami.dtb \ zynq-topic-miamilite.dtb \ @@ -254,6 +260,9 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \ zynq-zybo-z7.dtb dtb-$(CONFIG_ARCH_ZYNQMP) += \ avnet-ultra96-rev1.dtb \ + zynqmp-adrv9009-zu11eg-adrv2crr-fmc.dtb \ + zynqmp-jupiter-sdr.dtb \ + zynqmp-kv260.dtb \ zynqmp-a2197-revA.dtb \ zynqmp-dlc21-revA.dtb \ zynqmp-e-a2197-00-revA.dtb \ diff --git a/arch/arm/dts/zynq-adrv9361.dts b/arch/arm/dts/zynq-adrv9361.dts new file mode 100644 index 000000000000..01aba9ede50f --- /dev/null +++ b/arch/arm/dts/zynq-adrv9361.dts @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Analog Devices Inc. ADRV9361-Z7035 board DTS + * + * Copyright (C) 2015-2026 Analog Devices Inc. + */ +/dts-v1/; +#include "zynq-7000.dtsi" + +/ { + model = "Analog Devices ADRV9361-Z7035 (Z7035/AD9361)"; + compatible = "adi,adrv9361", "xlnx,zynq-7000"; + + aliases { + ethernet0 = &gem0; + serial0 = &uart1; + spi0 = &qspi; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x40000000>; + }; + + chosen { + bootargs = "earlyprintk"; + linux,stdout-path = &uart1; + stdout-path = &uart1; + }; + + usb_phy0: phy0 { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + }; +}; + +&gem0 { + status = "okay"; + phy-mode = "rgmii-id"; + phy-handle = <ðernet_phy>; + + ethernet_phy: ethernet-phy@0 { + reg = <0>; + marvell,reg-init = <3 16 0xff00 0x1e 3 17 0xfff0 0x00>; + }; +}; + +&qspi { + status = "okay"; + is-dual = <0>; + num-cs = <1>; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + spi-max-frequency = <50000000>; + #address-cells = <1>; + #size-cells = <1>; + partition@qspi-fsbl-uboot { + label = "qspi-fsbl-uboot"; + reg = <0x0 0xE0000>; /* 896k */ + }; + partition@qspi-uboot-env { + label = "qspi-uboot-env"; + reg = <0xE0000 0x20000>; /* 128k */ + }; + partition@qspi-linux { + label = "qspi-linux"; + reg = <0x100000 0x500000>; /* 5M */ + }; + partition@qspi-device-tree { + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; /* 128k */ + }; + partition@qspi-rootfs { + label = "qspi-rootfs"; + reg = <0x620000 0xCE0000>; /* ~13M */ + }; + partition@qspi-bitstream { + label = "qspi-bitstream"; + reg = <0x1300000 0xD00000>; /* 13M */ + }; + }; +}; + +&sdhci0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; + usb-phy = <&usb_phy0>; +}; diff --git a/arch/arm/dts/zynq-adrv9364.dts b/arch/arm/dts/zynq-adrv9364.dts new file mode 100644 index 000000000000..f41f609470c9 --- /dev/null +++ b/arch/arm/dts/zynq-adrv9364.dts @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Analog Devices Inc. ADRV9364-Z7020 board DTS + * + * Copyright (C) 2015-2026 Analog Devices Inc. + */ +/dts-v1/; +#include "zynq-7000.dtsi" + +/ { + model = "Analog Devices ADRV9364-Z7020 (Z7020/AD9364)"; + compatible = "adi,adrv9364", "xlnx,zynq-7000"; + + aliases { + ethernet0 = &gem0; + serial0 = &uart1; + spi0 = &qspi; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x40000000>; + }; + + chosen { + bootargs = "earlyprintk"; + linux,stdout-path = &uart1; + stdout-path = &uart1; + }; + + usb_phy0: phy0 { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + }; +}; + +&gem0 { + status = "okay"; + phy-mode = "rgmii-id"; + phy-handle = <ðernet_phy>; + + ethernet_phy: ethernet-phy@0 { + reg = <0>; + marvell,reg-init = <3 16 0xff00 0x1e 3 17 0xfff0 0x00>; + }; +}; + +&qspi { + status = "okay"; + is-dual = <0>; + num-cs = <1>; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + spi-max-frequency = <50000000>; + #address-cells = <1>; + #size-cells = <1>; + partition@qspi-fsbl-uboot { + label = "qspi-fsbl-uboot"; + reg = <0x0 0xE0000>; /* 896k */ + }; + partition@qspi-uboot-env { + label = "qspi-uboot-env"; + reg = <0xE0000 0x20000>; /* 128k */ + }; + partition@qspi-linux { + label = "qspi-linux"; + reg = <0x100000 0x500000>; /* 5M */ + }; + partition@qspi-device-tree { + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; /* 128k */ + }; + partition@qspi-rootfs { + label = "qspi-rootfs"; + reg = <0x620000 0xCE0000>; /* ~13M */ + }; + partition@qspi-bitstream { + label = "qspi-bitstream"; + reg = <0x1300000 0xD00000>; /* 13M */ + }; + }; +}; + +&sdhci0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; + usb-phy = <&usb_phy0>; +}; diff --git a/arch/arm/dts/zynq-coraz7s.dts b/arch/arm/dts/zynq-coraz7s.dts new file mode 100644 index 000000000000..a083a4cb376b --- /dev/null +++ b/arch/arm/dts/zynq-coraz7s.dts @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Digilent Cora Z7 board DTS + * + * Copyright (C) 2016 Digilent + */ +/dts-v1/; +#include "zynq-7000.dtsi" + +/ { + model = "Zynq Cora Z7 Development Board"; + compatible = "digilent,zynq-coraz7", "xlnx,zynq-7000"; + + aliases { + ethernet0 = &gem0; + serial0 = &uart0; + mmc0 = &sdhci0; + }; + + cpus { + /delete-node/ cpu1; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x20000000>; + }; + + chosen { + bootargs = "console=ttyPS0,115200 earlyprintk"; + stdout-path = "serial0:115200n8"; + }; + + usb_phy0: phy0@e0002000 { + compatible = "ulpi-phy"; + #phy-cells = <0>; + reg = <0xe0002000 0x1000>; + view-port = <0x0170>; + drv-vbus; + }; +}; + +&clkc { + ps-clk-frequency = <50000000>; +}; + +&gem0 { + status = "okay"; + phy-mode = "rgmii-id"; + phy-handle = <ðernet_phy>; + + ethernet_phy: ethernet-phy@0 { /* rtl8211e-vl */ + reg = <1>; + }; +}; + +&sdhci0 { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; + usb-phy = <&usb_phy0>; +}; diff --git a/arch/arm/dts/zynq-m2k.dts b/arch/arm/dts/zynq-m2k.dts new file mode 100644 index 000000000000..9c8256885108 --- /dev/null +++ b/arch/arm/dts/zynq-m2k.dts @@ -0,0 +1,82 @@ +/* + * Analog Devices ADALM-2000 board DTS + * + * Copyright (C) 2015-2025 Analog Devices Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/dts-v1/; +#include "zynq-7000.dtsi" + +/ { + model = "Zynq M2k Board"; + compatible = "xlnx,zynq-picozed-sdr2", "xlnx,zynq-7000"; + + aliases { + ethernet0 = &gem0; + serial0 = &uart1; + serial1 = &nulldev; + spi0 = &qspi; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x20000000>; + }; + + chosen { + bootargs = "earlyprintk"; + linux,stdout-path = &uart1; + stdout-path = &uart1; + }; + + usb_phy0: phy0 { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + }; + + nulldev: nulldev { + compatible = "nulldev-serial"; + }; +}; + +&qspi { + status = "okay"; + is-dual = <0>; + num-cs = <1>; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + spi-max-frequency = <50000000>; + #address-cells = <1>; + #size-cells = <1>; + partition@qspi-fsbl-uboot { + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; /* 1M */ + }; + partition@qspi-uboot-env { + label = "qspi-uboot-env"; + reg = <0x100000 0x20000>; /* 128k */ + }; + partition@qspi-nvmfs { + label = "qspi-nvmfs"; + reg = <0x120000 0xE0000>; /* 1M */ + }; + partition@qspi-linux { + label = "qspi-linux"; + reg = <0x200000 0x1E00000>; /* 30M */ + }; + }; +}; + +&uart1 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; + usb-phy = <&usb_phy0>; +}; diff --git a/arch/arm/dts/zynq-pluto-sdr.dts b/arch/arm/dts/zynq-pluto-sdr.dts new file mode 100644 index 000000000000..c7d528919869 --- /dev/null +++ b/arch/arm/dts/zynq-pluto-sdr.dts @@ -0,0 +1,82 @@ +/* + * Analog Devices Inc. Pluto SDR board DTS + * + * Copyright (C) 2015-2018 Analog Devices Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/dts-v1/; +#include "zynq-7000.dtsi" + +/ { + model = "Zynq Pluto SDR Board"; + compatible = "xlnx,zynq-7000"; + + aliases { + ethernet0 = &gem0; + serial0 = &uart1; + serial1 = &nulldev; + spi0 = &qspi; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x20000000>; + }; + + chosen { + bootargs = "earlyprintk"; + linux,stdout-path = &uart1; + stdout-path = &uart1; + }; + + usb_phy0: phy0 { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + }; + + nulldev: nulldev { + compatible = "nulldev-serial"; + }; +}; + +&qspi { + status = "okay"; + is-dual = <0>; + num-cs = <1>; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + spi-max-frequency = <50000000>; + #address-cells = <1>; + #size-cells = <1>; + partition@qspi-fsbl-uboot { + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; /* 1M */ + }; + partition@qspi-uboot-env { + label = "qspi-uboot-env"; + reg = <0x100000 0x20000>; /* 128k */ + }; + partition@qspi-nvmfs { + label = "qspi-nvmfs"; + reg = <0x120000 0xE0000>; /* 1M */ + }; + partition@qspi-linux { + label = "qspi-linux"; + reg = <0x200000 0x1E00000>; /* 30M */ + }; + }; +}; + +&uart1 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; + usb-phy = <&usb_phy0>; +}; diff --git a/arch/arm/dts/zynq-sidekiqz2.dts b/arch/arm/dts/zynq-sidekiqz2.dts new file mode 100644 index 000000000000..43e0184d2448 --- /dev/null +++ b/arch/arm/dts/zynq-sidekiqz2.dts @@ -0,0 +1,82 @@ +/* + * Epiq Solutions Sidekiq Z2 board DTS + * + * Copyright (C) 2018 Analog Devices Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/dts-v1/; +#include "zynq-7000.dtsi" + +/ { + model = "Zynq Sidekiq Z2 Board"; + compatible = "xlnx,zynq-7000"; + + aliases { + ethernet0 = &gem0; + serial0 = &uart1; + serial1 = &nulldev; + spi0 = &qspi; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x20000000>; + }; + + chosen { + bootargs = "earlyprintk"; + linux,stdout-path = &uart1; + stdout-path = &uart1; + }; + + usb_phy0: phy0 { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + }; + + nulldev: nulldev { + compatible = "nulldev-serial"; + }; +}; + +&qspi { + status = "okay"; + is-dual = <0>; + num-cs = <1>; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + spi-max-frequency = <50000000>; + #address-cells = <1>; + #size-cells = <1>; + partition@qspi-fsbl-uboot { + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; /* 1M */ + }; + partition@qspi-uboot-env { + label = "qspi-uboot-env"; + reg = <0x100000 0x20000>; /* 128k */ + }; + partition@qspi-nvmfs { + label = "qspi-nvmfs"; + reg = <0x120000 0xE0000>; /* 1M */ + }; + partition@qspi-linux { + label = "qspi-linux"; + reg = <0x200000 0x1E00000>; /* 30M */ + }; + }; +}; + +&uart1 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; + usb-phy = <&usb_phy0>; +}; diff --git a/arch/arm/dts/zynqmp-adrv9009-zu11eg-adrv2crr-fmc.dts b/arch/arm/dts/zynqmp-adrv9009-zu11eg-adrv2crr-fmc.dts new file mode 100644 index 000000000000..57bada93d58c --- /dev/null +++ b/arch/arm/dts/zynqmp-adrv9009-zu11eg-adrv2crr-fmc.dts @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * dts file for ADRV2CRR-FMC using ADRV9009-ZU11EG System on Module + * + * Copyright (C) 2019-2026 Analog Devices Inc. + */ + +/* + * FPGA Signal GPIO# + * hmc7044_car_gpio_3, 27 105 + * hmc7044_car_gpio_2, 26 104 + * hmc7044_car_gpio_1, 25 103 + * hmc7044_car_gpio_0, 24 102 + * hmc7044_car_reset, 23 101 + * resetb_ad9545, 22 100 + * fan_tach, 21 99 + * fan_pwrm, 20 98 + * pmod0_d7, 19 97 + * pmod0_d6, 18 96 + * pmod0_d5, 17 95 + * pmod0_d4, 16 94 + * pmod0_d3, 15 93 + * pmod0_d2, 14 92 + * pmod0_d1, 13 91 + * pmod0_d0, 12 90 + * led_gpio_3, 11 89 + * led_gpio_2, 10 88 + * led_gpio_1, 9 87 + * led_gpio_0, 8 86 + * dip_gpio_3, 7 85 + * dip_gpio_2, 6 84 + * dip_gpio_1, 5 83 + * dip_gpio_0, 4 82 + * pb_gpio_3, 3 81 + * pb_gpio_2, 2 80 + * pb_gpio_1, 1 79 + * pb_gpio_0})); 0 78 + */ + +#include "zynqmp-adrv9009-zu11eg.dts" + +/ { + leds { + compatible = "gpio-leds"; + led0 { + label = "led0:green"; + gpios = <&gpio 86 0>; + }; + + led1 { + label = "led1:green"; + gpios = <&gpio 87 0>; + }; + + led2 { + label = "led2:green"; + gpios = <&gpio 88 0>; + }; + + led3 { + label = "led3:green"; + gpios = <&gpio 89 0>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + autorepeat; + + bt0 { + label = "BT0"; + linux,code = ; + gpios = <&gpio 78 0>; + }; + + bt1 { + label = "BT1"; + linux,code = ; + gpios = <&gpio 79 0>; + }; + + bt2 { + label = "BT2"; + linux,code = ; + gpios = <&gpio 80 0>; + }; + + bt3 { + label = "BT3"; + linux,code = ; + gpios = <&gpio 81 0>; + }; + + sw0 { + label = "SW0"; + linux,input-type = ; + linux,code = ; + gpios = <&gpio 82 0>; + }; + + sw1 { + label = "SW1"; + linux,input-type = ; + linux,code = ; + gpios = <&gpio 83 0>; + }; + + sw2 { + label = "SW2"; + linux,input-type = ; + linux,code = ; + gpios = <&gpio 84 0>; + }; + + sw3 { + label = "SW3"; + linux,input-type = ; + linux,code = ; + gpios = <&gpio 85 0>; + }; + }; +}; + +/* + * SGMII Ethernet: M1 (PHY1) + * Using gem0 + */ + +&gem0 { + status = "okay"; + phy-handle = <&phy1>; + phy-mode = "sgmii"; +}; + +/* + * DisplayPort: P2 + */ + +&zynqmp_dpsub { + status = "okay"; +}; + +/* + * USB 2.0 & 3.0 + * Using: usb0, dwc3_0 + */ + +&usb0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0_default>; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; +}; + +&gpio { + phy_reset { + gpio-hog; + gpios = <13 0>; + output-high; + line-name = "ulpi-phy-reset"; + }; +}; + +/* + * I2C1 + */ + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "gpio"; + pinctrl-0 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 32 GPIO_ACTIVE_HIGH>; + sda-gpios = <&gpio 33 GPIO_ACTIVE_HIGH>; + + i2c-mux@70 { /* u19 */ + compatible = "nxp,pca9548"; /* TCA9548 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0x70>; + + i2c@0 { /* Audio ADAU1761 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + /* 3B */ + + }; + i2c@1 { /* AD9545 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + /* 4A */ + + }; + i2c@2 { /* PTN5150 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + /* 1D */ + + }; + i2c@3 { /* QSFP */ + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + eeprom@50 { + compatible = "at24,24c02"; + reg = <0x50>; + }; + }; + i2c@4 { /* SFP+ */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + + eeprom@50 { + compatible = "at24,24c02"; + reg = <0x50>; + }; + + }; + i2c@5 { /* FMC HPC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + + eeprom@50 { + compatible = "at24,24c02"; + reg = <0x50>; + }; + }; + }; +}; diff --git a/arch/arm/dts/zynqmp-adrv9009-zu11eg.dts b/arch/arm/dts/zynqmp-adrv9009-zu11eg.dts new file mode 100644 index 000000000000..53fbf7e25ec1 --- /dev/null +++ b/arch/arm/dts/zynqmp-adrv9009-zu11eg.dts @@ -0,0 +1,360 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * dts file for ADRV9009-ZU11EG System on Module + * + * Copyright (C) 2019-2026 Analog Devices Inc. + */ + +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include +#include +#include + +/ { + model = "Analog Devices ADRV9009-ZU11EG"; + compatible = "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem3; + ethernet1 = &gem0; + gpio0 = &gpio; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &dcc; + spi0 = &qspi; + usb0 = &usb0; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial1:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x7ff00000>, <0x8 0x00000000 0x0 0x80000000>; + }; +}; + +&gem3 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gem3_default>; + phy0: phy@0 { + device_type = "ethernet-phy"; + reg = <0x0>; + marvell,reg-init = <3 16 0xff00 0x1e 3 17 0xfff0 0x00>; + }; + phy1: phy@1 { + device_type = "ethernet-phy"; + reg = <1>; + }; +}; + +&gpio { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_default>; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c0_default>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + scl-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>; + sda-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>; + + current_limiter@58 { /* U12 */ + compatible = "adi,adm1177"; + reg = <0x58>; + adi,r-sense-mohm = <10>; /* 10 mOhm */ + adi,shutdown-threshold-ma = <10000>; /* 10 A */ + adi,vrange-high-enable; + }; + + ad9542@4b { + compatible = "adi,ad9542"; + reg = <0x4b>; + }; + + adm1266@48 { + compatible = "adi,adm1266"; + reg = <0x48>; + }; + + eeprom@2c { /* U49 */ + compatible = "24c16"; + reg = <0x2c>; + }; +}; + +&sdhci1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdhci1_default>; + no-1-8-v; + xlnx,mio_bank = <1>; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; +}; + +&watchdog0 { + status = "okay"; +}; + +&xilinx_ams { + status = "okay"; +}; + +&ams_ps { + status = "okay"; +}; + +&ams_pl { + status = "okay"; +}; + +&qspi { + status = "okay"; + is-dual = <1>; + num-cs = <1>; + primary_flash: qspi@0 { + #address-cells = <1>; + #size-cells = <1>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + compatible = "n25q512a", "jedec,spi-nor"; + reg = <0x0>; + spi-max-frequency = <50000000>; + partition@qspi-fsbl-uboot { + label = "qspi-fsbl-uboot"; + reg = <0x0 0x2000000>; /* 32M */ + }; + partition@qspi-uboot-env { + label = "qspi-uboot-env"; + reg = <0x2000000 0x20000>; /* 128k */ + }; + partition@qspi-nvmfs { + label = "qspi-nvmfs"; + reg = <0x2020000 0xE0000>; /* 1M */ + }; + partition@qspi-linux { + label = "qspi-linux"; + reg = <0x2100000 0x5E00000>; /* 94M */ + }; + }; +}; + +/* + * SPI0: ADRV9009 transceivers and HMC7044 clock distribution + * omitted for u-boot - these are Linux FPGA IP drivers that + * reference JESD204 and clock nodes not present in upstream + * zynqmp.dtsi. See the Linux kernel DTS for the full config. + */ + + +&pinctrl0 { + status = "okay"; + + pinctrl_i2c0_default: i2c0-default { + mux { + groups = "i2c0_3_grp"; + function = "i2c0"; + }; + + conf { + groups = "i2c0_3_grp"; + bias-pull-up; + slew-rate = ; + io-standard = ; + }; + }; + + pinctrl_i2c0_gpio: i2c0-gpio { + mux { + groups = "gpio0_14_grp", "gpio0_15_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_14_grp", "gpio0_15_grp"; + slew-rate = ; + io-standard = ; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio { + mux { + groups = "gpio0_32_grp", "gpio0_33_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_32_grp", "gpio0_33_grp"; + slew-rate = ; + io-standard = ; + }; + }; + + pinctrl_uart1_default: uart1-default { + mux { + groups = "uart1_5_grp"; + function = "uart1"; + }; + + conf { + groups = "uart1_5_grp"; + slew-rate = ; + io-standard = ; + }; + + conf-rx { + pins = "MIO21"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO20"; + bias-disable; + }; + }; + + pinctrl_gem3_default: gem3-default { + mux { + function = "ethernet3"; + groups = "ethernet3_0_grp"; + }; + + conf { + groups = "ethernet3_0_grp"; + slew-rate = ; + io-standard = ; + }; + + conf-rx { + pins = "MIO70", "MIO71", "MIO72", "MIO73", "MIO74", + "MIO75"; + bias-high-impedance; + low-power-disable; + }; + + conf-tx { + pins = "MIO64", "MIO65", "MIO66", "MIO67", "MIO68", + "MIO69"; + bias-disable; + low-power-enable; + }; + + mux-mdio { + function = "mdio3"; + groups = "mdio3_0_grp"; + }; + + conf-mdio { + groups = "mdio3_0_grp"; + slew-rate = ; + io-standard = ; + bias-disable; + }; + }; + + pinctrl_sdhci1_default: sdhci1-default { + mux { + groups = "sdio1_0_grp"; + function = "sdio1"; + }; + + conf { + groups = "sdio1_0_grp"; + slew-rate = ; + io-standard = ; + bias-disable; + }; + + mux-cd { + groups = "sdio1_cd_0_grp"; + function = "sdio1_cd"; + }; + + conf-cd { + groups = "sdio1_cd_0_grp"; + bias-high-impedance; + bias-pull-up; + slew-rate = ; + io-standard = ; + }; + + mux-wp { + groups = "sdio1_wp_0_grp"; + function = "sdio1_wp"; + }; + + conf-wp { + groups = "sdio1_wp_0_grp"; + bias-high-impedance; + bias-pull-up; + slew-rate = ; + io-standard = ; + }; + }; + + pinctrl_gpio_default: gpio-default { + mux-usbsw { + function = "gpio0"; + groups = "gpio0_35_grp", "gpio0_36_grp", "gpio0_37_grp", "gpio0_38_grp"; + }; + + conf-usbsw { + groups = "gpio0_35_grp", "gpio0_36_grp", "gpio0_37_grp", "gpio0_38_grp"; + slew-rate = ; + io-standard = ; + }; + }; + + pinctrl_usb0_default: usb0-default { + mux { + groups = "usb0_0_grp"; + function = "usb0"; + }; + + conf { + groups = "usb0_0_grp"; + slew-rate = ; + io-standard = ; + }; + + conf-rx { + pins = "MIO52", "MIO53", "MIO55"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", + "MIO60", "MIO61", "MIO62", "MIO63"; + bias-disable; + }; + }; +}; + +/* + * FPGA AXI bus with ADRV9009 JESD204, DMA, and IP cores + * omitted - not needed for u-boot, and references Xilinx + * vendor clock labels not present in upstream zynqmp.dtsi. + * See the Linux kernel DTS for the full FPGA overlay. + */ diff --git a/arch/arm/dts/zynqmp-jupiter-sdr.dts b/arch/arm/dts/zynqmp-jupiter-sdr.dts new file mode 100644 index 000000000000..fd8ebaceb97b --- /dev/null +++ b/arch/arm/dts/zynqmp-jupiter-sdr.dts @@ -0,0 +1,433 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Analog Devices, Inc. Jupiter SDR + * + * hdl_project: + * board_revision: <> + * + * Copyright (C) 2021 Analog Devices Inc. + */ + +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include +#include +#include +#include + +#undef JUPITER_SDR_USB_ROLE_SW + +/ { + model = "Analog Devices, Inc. Jupiter SDR"; + compatible = "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem3; + mmc0 = &sdhci1; + rtc0 = &rtc; + serial0 = &uart1; + i2c0 = &i2c1; + spi0 = &spi0; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + psgtr_ref0: ad9542_out0_b { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + psgtr_ref1: ad9542_out0_a { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <108000000>; + }; + + psgtr_ref2: ad9542_out1_b { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <150000000>; + }; +}; + +&psgtr { + status = "okay"; + clocks = <&psgtr_ref0>, <&psgtr_ref1>, <&psgtr_ref2>; + clock-names = "ref0", "ref1", "ref2"; +}; + +&pinctrl0 { + status = "okay"; + + pinctrl_uart1_default: uart1-default { + mux { + groups = "uart1_4_grp"; + function = "uart1"; + }; + + conf { + groups = "uart1_4_grp"; + slew-rate = ; + io-standard = ; + }; + + conf-rx { + pins = "MIO17"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO16"; + bias-disable; + }; + }; + + pinctrl_gem3_default: gem3-default { + mux { + function = "ethernet3"; + groups = "ethernet3_0_grp"; + }; + + conf { + groups = "ethernet3_0_grp"; + slew-rate = ; + io-standard = ; + }; + + conf-rx { + pins = "MIO70", "MIO71", "MIO72", + "MIO73", "MIO74", "MIO75"; + bias-high-impedance; + low-power-disable; + }; + + conf-tx { + pins = "MIO64", "MIO65", "MIO66", + "MIO67", "MIO68", "MIO69"; + bias-disable; + low-power-enable; + }; + + mux-mdio { + function = "mdio3"; + groups = "mdio3_0_grp"; + }; + + conf-mdio { + groups = "mdio3_0_grp"; + slew-rate = ; + io-standard = ; + bias-disable; + }; + }; + + pinctrl_sdhci1_default: sdhci1-default { + mux { + groups = "sdio1_0_grp"; + function = "sdio1"; + }; + + conf { + groups = "sdio1_0_grp"; + slew-rate = ; + io-standard = ; + bias-disable; + }; + + mux-cd { + groups = "sdio1_cd_0_grp"; + function = "sdio1_cd"; + }; + + conf-cd { + groups = "sdio1_cd_0_grp"; + bias-high-impedance; + bias-pull-up; + slew-rate = ; + io-standard = ; + }; + + mux-wp { + groups = "sdio1_wp_0_grp"; + function = "sdio1_wp"; + }; + + conf-wp { + groups = "sdio1_wp_0_grp"; + bias-high-impedance; + bias-pull-up; + slew-rate = ; + io-standard = ; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + mux { + groups = "i2c1_8_grp"; + function = "i2c1"; + }; + + conf { + groups = "i2c1_8_grp"; + bias-pull-up; + slew-rate = ; + io-standard = ; + }; + }; + + pinctrl_usb0_default: usb0-default { + mux { + groups = "usb0_0_grp"; + function = "usb0"; + }; + + conf { + groups = "usb0_0_grp"; + slew-rate = ; + io-standard = ; + }; + + conf-rx { + pins = "MIO52", "MIO53", "MIO55"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", + "MIO60", "MIO61", "MIO62", "MIO63"; + bias-disable; + }; + }; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; +}; + +&gem3 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gem3_default>; + + nvmem-cells = <ð0_addr>; + nvmem-cell-names = "mac-address"; + + #address-cells = <1>; + #size-cells = <0>; + + phy0: phy@f { + reg = <0xf>; + adi,rx-internal-delay-ps = <2000>; + adi,tx-internal-delay-ps = <2000>; + }; +}; + +&sdhci1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdhci1_default>; + xlnx,mio_bank = <1>; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1_default>; + + ltc2945@6a { + compatible = "adi,ltc2945"; + reg = <0x6a>; + }; + + eeprom_i2c: eeprom@50 { + compatible = "atmel,24c16", "atmel,24c16a"; + pagesize = <16>; + reg = <0x50>; + #address-cells = <1>; + #size-cells = <1>; + + eth0_addr: eth-mac-addr@B { + reg = <0xB 0x06>; + }; + }; + + typec_pd: usb-pd@38 { + compatible = "ti,tps6598x"; + reg = <0x38>; + interrupt-parent = <&gpio>; + interrupts = <31 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "irq"; + +#ifdef JUPITER_SDR_USB_ROLE_SW + typec_con: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + port { + typec_ep: endpoint { + remote-endpoint = <&otg_ep>; + }; + }; + }; +#endif + }; + + typec_pd1: usb-pd@3f { + compatible = "ti,tps6598x"; + reg = <0x3F>; + interrupt-parent = <&gpio>; + interrupts = <31 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "irq"; + }; +}; + +&zynqmp_dpsub { + status = "okay"; + phy-names = "dp-phy0"; + phys = <&psgtr 3 PHY_TYPE_DP 0 1>, + <&psgtr 2 PHY_TYPE_DP 1 1>; +}; + +&zynqmp_dpdma { + status = "okay"; +}; + +&sata { + status = "okay"; + ceva,p0-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>; + ceva,p0-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>; + ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>; + ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>; + ceva,p1-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>; + ceva,p1-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>; + ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>; + ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>; + phy-names = "sata-phy"; + phys = <&psgtr 1 PHY_TYPE_SATA 1 2>; +}; + +&usb0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0_default>; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "otg"; + phy-names = "usb3-phy"; + phys = <&psgtr 0 PHY_TYPE_USB3 0 0>; + maximum-speed = "super-speed"; +#ifdef JUPITER_SDR_USB_ROLE_SW + usb-role-switch; + role-switch-default-mode = "device"; + + port@0 { + reg = <0>; + + otg_ep: endpoint { + remote-endpoint = <&typec_con>; + }; + }; +#endif +}; + +&qspi { + status = "okay"; + is-dual = <1>; + num-cs = <2>; + primary_flash: mt25qu@0 { + compatible = "n25q512a", "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x4000000 0x4000000>; /* 64MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <40000000>; + partition@0 { + label = "qspi_partition"; + reg = <0x0 0xD00000>; + }; + }; +}; + +&gpio { + status = "okay"; + + usb_reset { + gpio-hog; + gpios = <13 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "usb-reset"; + }; + + adrv9002_clksrc { + gpio-hog; + gpios = <79 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "adrv9002-clksrc"; + }; + + fan_en { + gpio-hog; + gpios = <144 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "fan-en"; + }; + + fan_ctl { + gpio-hog; + gpios = <145 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "fan-ctl"; + }; + + add_on_en { + gpio-hog; + gpios = <136 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "add-on-en"; + }; +}; + +&spi0 { + status = "okay"; +}; + +&watchdog0 { + status = "okay"; +}; + +&xilinx_ams { + status = "okay"; +}; + +&ams_ps { + status = "okay"; +}; + +&ams_pl { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + diff --git a/arch/arm/dts/zynqmp-kv260.dts b/arch/arm/dts/zynqmp-kv260.dts new file mode 100644 index 000000000000..cd9bc156305e --- /dev/null +++ b/arch/arm/dts/zynqmp-kv260.dts @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Kria KV260 + * + * (C) Copyright 2023, Analog Devices, Inc. + * + */ + +#include "zynqmp-smk-k26-revA.dts" + +&sdhci1 { + status = "okay"; + disable-wp; +}; diff --git a/board/xilinx/zynq/Kconfig b/board/xilinx/zynq/Kconfig index d6f40631cca3..ff736f597364 100644 --- a/board/xilinx/zynq/Kconfig +++ b/board/xilinx/zynq/Kconfig @@ -30,4 +30,22 @@ config CMD_ZYNQ_RSA and authentication feature enabled while generating BOOT.BIN using Xilinx bootgen tool. +config CMD_ADI_HWREF + bool "ADI hardware reference detection commands" + depends on ARCH_ZYNQ + help + Enables adi_hwref, xadc, and envversion commands for + Analog Devices PlutoSDR, M2K, and SidekiqZ2 boards. + Provides XADC voltage reading and board revision detection. + +config SPI_FLASH_LOCK_ADI + bool "ADI PlutoSDR/M2K bottom 1MB flash protection" + depends on SPI_FLASH_LOCK + help + Override SPI flash lock/unlock for Analog Devices PlutoSDR, + M2K, and SidekiqZ2 boards. Protects the bottom 1MB (boot + partition) by writing SR with BP2|BP0|TB directly, bypassing + the generic Micron lock which does not handle bottom protect + correctly on N25Q256. + endif diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index a852d5b8ed53..b29dc54d2261 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -45,6 +45,43 @@ int board_init(void) return 0; } +#ifdef CONFIG_CMD_ADI_HWREF +#include +#include + +#define ADI_FACTORY_RESET_GPIO 14 + +static void adi_check_env_version(void) +{ + const char *ver = env_get("env_version"); + + if (ver && !strcmp(ver, PLUTO_ENV_VERSION)) + return; + + printf("Environment version mismatch (%s vs %s), resetting to defaults\n", + ver ? ver : "none", PLUTO_ENV_VERSION); + env_set_default("env version mismatch", 0); + env_save(); +} + +int misc_init_r(void) +{ + gpio_request(ADI_FACTORY_RESET_GPIO, "factory_reset"); + gpio_direction_input(ADI_FACTORY_RESET_GPIO); + + if (!gpio_get_value(ADI_FACTORY_RESET_GPIO)) { + printf("Factory reset button pressed: loading default environment\n"); + env_set_default("Button pressed", 0); + env_save(); + } + + adi_check_env_version(); + + gpio_free(ADI_FACTORY_RESET_GPIO); + return 0; +} +#endif + int board_late_init(void) { int env_targets_len = 0; @@ -141,12 +178,21 @@ enum env_location env_get_location(enum env_operation op, int prio) if (prio) return ENVL_UNKNOWN; +#ifdef CONFIG_CMD_ADI_HWREF + /* PlutoSDR/M2K/SidekiqZ2: always use SPI flash for env */ + if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)) + return ENVL_SPI_FLASH; + return ENVL_NOWHERE; +#endif + switch (bootmode) { case ZYNQ_BM_SD: if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT)) return ENVL_FAT; if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4)) return ENVL_EXT4; + if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)) + return ENVL_SPI_FLASH; return ENVL_NOWHERE; case ZYNQ_BM_NAND: if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND)) diff --git a/cmd/Makefile b/cmd/Makefile index 533d0f6a1be2..3736ffe5c0d0 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_CMD_ACPI) += acpi.o obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o obj-$(CONFIG_CMD_AES) += aes.o obj-$(CONFIG_CMD_ADC) += adc.o +obj-$(CONFIG_CMD_ADI_HWREF) += adi_hwref.o xadcps.o obj-$(CONFIG_CMD_ARMFLASH) += armflash.o obj-$(CONFIG_BLK) += blk_common.o obj-$(CONFIG_CMD_BOOTDEV) += bootdev.o diff --git a/cmd/adi_hwref.c b/cmd/adi_hwref.c new file mode 100644 index 000000000000..63292802ad40 --- /dev/null +++ b/cmd/adi_hwref.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2015-2026 Analog Devices Inc. + * + * ADI hardware reference detection commands for PlutoSDR/M2K/SidekiqZ2. + * Provides XADC voltage reading and board revision detection. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "xadcps.h" + +static int do_xadc(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + static XAdcPs XAdcInst; + XAdcPs_Config *ConfigPtr; + XAdcPs *XAdcInstPtr = &XAdcInst; + u32 RawData, chan, cnt = 2; + int val; + char buf[16]; + + ConfigPtr = XAdcPs_LookupConfig(0); + if (!ConfigPtr) + return -1; + + if (argc > 1) + chan = simple_strtoul(argv[1], NULL, 10); + else + chan = XADCPS_CH_VPVN; + + do { + XAdcPs_CfgInitialize(XAdcInstPtr, ConfigPtr, + ConfigPtr->BaseAddress); + XAdcPs_SetSingleChParams(XAdcInstPtr, chan, 0, 0, 0); + XAdcPs_SetSequencerMode(XAdcInstPtr, XADCPS_SEQ_MODE_SINGCHAN); + RawData = XAdcPs_GetAdcData(XAdcInstPtr, chan); + } while (cnt--); + + XAdcPs_SetPowerdownMode(XAdcInstPtr, XADCPS_PD_MODE_XADC); + + val = ((RawData >> 4) * 1000) / 0xFFF; + + snprintf(buf, sizeof(buf), "%d", val); + printf("%s\n", buf); + + return val; +} + +U_BOOT_CMD( + xadc, CONFIG_SYS_MAXARGS, 1, do_xadc, + "read xadc channel", + "" +); + +static int do_env_version(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + env_set("uboot-version", version_string); + return 0; +} + +U_BOOT_CMD( + envversion, 1, 1, do_env_version, + "set env variable uboot-version", + "" +); + +/* + * Detect PlutoSDR Rev.A by reading SPI flash JEDEC ID directly. + * Original check from old u-boot spi_flash.c: + * jedec == 0xBB19 && ext_jedec == 0x1000 && idcode[5] == 0 + * + * The 6-byte READ_ID response for Rev.A: 20 BB 19 10 00 00 + * Non-Rev.A boards have idcode[5] != 0 or different jedec/ext_jedec. + */ +static int pluto_detect_revA(void) +{ + struct udevice *dev, *bus; + struct spi_slave *slave; + u8 idcode[6]; + u16 jedec, ext_jedec; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_SPI, 0, &bus); + if (ret) + return 0; + + ret = spi_flash_probe_bus_cs(0, 0, &dev); + if (ret) + return 0; + + slave = dev_get_parent_priv(dev); + if (!slave) + return 0; + + ret = spi_claim_bus(slave); + if (ret) + return 0; + + /* Send READ_ID (0x9F) and read 6 bytes */ + u8 cmd = 0x9F; + + ret = spi_xfer(slave, 8, &cmd, NULL, SPI_XFER_BEGIN); + if (!ret) + ret = spi_xfer(slave, 48, NULL, idcode, SPI_XFER_END); + + spi_release_bus(slave); + + if (ret) + return 0; + + /* idcode[0] = mfr_id (0x20 = Micron) */ + jedec = (idcode[1] << 8) | idcode[2]; + ext_jedec = (idcode[3] << 8) | idcode[4]; + + if (jedec == 0xBB19 && ext_jedec == 0x1000 && idcode[5] == 0x00) + return 1; + + return 0; +} + +static int do_adi_hw_version(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int val, ret = 0, i; + char buf[16]; + + if (pluto_detect_revA()) { + env_set("PlutoRevA", "1"); + env_set("fit_config", "config@0"); + return 0; + } + + env_set("PlutoRevA", ""); + + val = do_xadc(cmdtp, flag, 1, argv); + + for (i = 100; i <= 1000; i += 100) { + if ((val >= (i - 50)) && (val < (i + 50))) { + ret = i / 100; + break; + } + } + + snprintf(buf, sizeof(buf), "config@%d", ret); + env_set("fit_config", buf); + + return ret; +} + +U_BOOT_CMD( + adi_hwref, CONFIG_SYS_MAXARGS, 1, do_adi_hw_version, + "determine pluto/m2k/sidekiqz2 hw revision", + "" +); + diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 392f90f86983..cca0d34a2d5c 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -1270,6 +1270,18 @@ U_BOOT_CMD_COMPLETE( var_complete ); +#ifdef CONFIG_CMD_ADI_HWREF +/* Backward compatibility: old PlutoSDR/M2K env scripts use 'set' */ +U_BOOT_CMD_COMPLETE( + set, CONFIG_SYS_MAXARGS, 0, do_env_set, + "set environment variables (alias for setenv)", + "name [value ...]\n" + " - set environment variable 'name' to 'value ...'\n" + " - delete environment variable 'name' if 'value' not specified", + var_complete +); +#endif + #if defined(CONFIG_CMD_ASKENV) U_BOOT_CMD( diff --git a/cmd/xadcps.c b/cmd/xadcps.c new file mode 100644 index 000000000000..91b91204b628 --- /dev/null +++ b/cmd/xadcps.c @@ -0,0 +1,1914 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xadcps.c +* @addtogroup xadcps_v2_2 +* @{ +* +* This file contains the driver API functions that can be used to access +* the XADC device. +* +* Refer to the xadcps.h header file for more information about this driver. +* +* @note None. +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- -----  -------- -----------------------------------------------------
+* 1.00a ssb    12/22/11 First release based on the XPS/AXI xadc driver
+* 1.01a bss    02/18/13	Modified XAdcPs_SetSeqChEnables,XAdcPs_SetSeqAvgEnables
+*			XAdcPs_SetSeqInputMode and XAdcPs_SetSeqAcqTime APIs
+*			to fix CR #693371
+* 2.1   bss    08/05/14	Modified Assert for XAdcPs_SetSingleChParams to fix
+*			CR #807563.
+* 2.2	bss	   04/27/14 Modified to use correct Device Config base address
+*						(CR#854437).
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#ifndef TRUE +# define TRUE 1U +#endif + +#ifndef FALSE +# define FALSE 0U +#endif + +/* Definitions for driver XADCPS */ +#define XPAR_XADCPS_NUM_INSTANCES 1 + +/* Definitions for peripheral PS7_XADC_0 */ +#define XPAR_PS7_XADC_0_DEVICE_ID 0 +#define XPAR_PS7_XADC_0_BASEADDR 0xF8007100 +#define XPAR_PS7_XADC_0_HIGHADDR 0xF8007120 + +/* Canonical definitions for peripheral PS7_XADC_0 */ +#define XPAR_XADCPS_0_DEVICE_ID XPAR_PS7_XADC_0_DEVICE_ID +#define XPAR_XADCPS_0_BASEADDR 0xF8007100 +#define XPAR_XADCPS_0_HIGHADDR 0xF8007120 + +/* Canonical definitions for peripheral PS7_DEV_CFG_0 */ +#define XPAR_XDCFG_0_DEVICE_ID XPAR_PS7_DEV_CFG_0_DEVICE_ID +#define XPAR_XDCFG_0_BASEADDR 0xF8007000 +#define XPAR_XDCFG_0_HIGHADDR 0xF80070FF + +#define Xil_Out32(a, b) writel(b, a) +#define Xil_In32 readl + +#define XIL_COMPONENT_IS_READY 0x11111111U /**< component has been initialized */ +#define XIL_COMPONENT_IS_STARTED 0x22222222U /**< component has been started */ + + +#include +#include +#include +#include "xstatus.h" +#include "xadcps.h" + + +/** + * This table contains configuration information for each XADC Monitor/ADC + * device in the system. + */ +XAdcPs_Config XAdcPs_ConfigTable[XPAR_XADCPS_NUM_INSTANCES] = { + { + XPAR_XADCPS_0_DEVICE_ID, /**< Unique ID of device */ + XPAR_XADCPS_0_BASEADDR /**< Base address of device */ + } +}; + +/*****************************************************************************/ +/** +* +* This function looks up the device configuration based on the unique device ID. +* The table XAdcPs_ConfigTable contains the configuration info for each device +* in the system. +* +* @param DeviceId contains the ID of the device for which the +* device configuration pointer is to be returned. +* +* @return +* - A pointer to the configuration found. +* - NULL if the specified device ID was not found. +* +* @note None. +* +******************************************************************************/ +XAdcPs_Config *XAdcPs_LookupConfig(u16 DeviceId) +{ + XAdcPs_Config *CfgPtr = NULL; + u32 Index; + + for (Index = 0; Index < 1; Index++) { + if (XAdcPs_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XAdcPs_ConfigTable[Index]; + break; + } + } + + return CfgPtr; +} + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Function Prototypes *****************************/ + +void XAdcPs_WriteInternalReg(XAdcPs *InstancePtr, u32 RegOffset, u32 Data); +u32 XAdcPs_ReadInternalReg(XAdcPs *InstancePtr, u32 RegOffset); + + +/************************** Variable Definitions ****************************/ + + +/*****************************************************************************/ +/** +* +* This function initializes a specific XAdcPs device/instance. This function +* must be called prior to using the XADC device. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param ConfigPtr points to the XAdcPs device configuration structure. +* @param EffectiveAddr is the device base address in the virtual memory +* address space. If the address translation is not used then the +* physical address is passed. +* Unexpected errors may occur if the address mapping is changed +* after this function is invoked. +* +* @return +* - XST_SUCCESS if successful. +* +* @note The user needs to first call the XAdcPs_LookupConfig() API +* which returns the Configuration structure pointer which is +* passed as a parameter to the XAdcPs_CfgInitialize() API. +* +******************************************************************************/ +int XAdcPs_CfgInitialize(XAdcPs *InstancePtr, XAdcPs_Config *ConfigPtr, + u32 EffectiveAddr) +{ + + u32 RegValue; + /* + * Assert the input arguments. + */ + assert(InstancePtr != NULL); + assert(ConfigPtr != NULL); + + + /* + * Set the values read from the device config and the base address. + */ + InstancePtr->Config.DeviceId = ConfigPtr->DeviceId; + InstancePtr->Config.BaseAddress = EffectiveAddr; + + /* Write Unlock value to Device Config Unlock register */ + XAdcPs_WriteReg(XPAR_XDCFG_0_BASEADDR, + XADCPS_UNLK_OFFSET, XADCPS_UNLK_VALUE); + + /* Enable the PS access of xadc and set FIFO thresholds */ + + RegValue = XAdcPs_ReadReg((InstancePtr)->Config.BaseAddress, + XADCPS_CFG_OFFSET); + + RegValue = RegValue | XADCPS_CFG_ENABLE_MASK | + XADCPS_CFG_CFIFOTH_MASK | XADCPS_CFG_DFIFOTH_MASK; + + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, + XADCPS_CFG_OFFSET, RegValue); + + /* Release xadc from reset */ + + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, + XADCPS_MCTL_OFFSET, 0x00); + + /* + * Indicate the instance is now ready to use and + * initialized without error. + */ + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + + return XST_SUCCESS; +} + + +/****************************************************************************/ +/** +* +* The functions sets the contents of the Config Register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Data is the 32 bit data to be written to the Register. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_SetConfigRegister(XAdcPs *InstancePtr, u32 Data) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, + XADCPS_CFG_OFFSET, Data); + +} + + +/****************************************************************************/ +/** +* +* The functions reads the contents of the Config Register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return A 32-bit value representing the contents of the Config Register. +* Use the XADCPS_SR_*_MASK constants defined in xadcps_hw.h to +* interpret the returned value. +* +* @note None. +* +*****************************************************************************/ +u32 XAdcPs_GetConfigRegister(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Config Register and return the value. + */ + return XAdcPs_ReadReg((InstancePtr)->Config.BaseAddress, + XADCPS_CFG_OFFSET); +} + + +/****************************************************************************/ +/** +* +* The functions reads the contents of the Miscellaneous Status Register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return A 32-bit value representing the contents of the Miscellaneous +* Status Register. Use the XADCPS_MSTS_*_MASK constants defined +* in xadcps_hw.h to interpret the returned value. +* +* @note None. +* +*****************************************************************************/ +u32 XAdcPs_GetMiscStatus(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Miscellaneous Status Register and return the value. + */ + return XAdcPs_ReadReg((InstancePtr)->Config.BaseAddress, + XADCPS_MSTS_OFFSET); +} + + +/****************************************************************************/ +/** +* +* The functions sets the contents of the Miscellaneous Control register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Data is the 32 bit data to be written to the Register. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_SetMiscCtrlRegister(XAdcPs *InstancePtr, u32 Data) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Write to the Miscellaneous control register Register. + */ + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, + XADCPS_MCTL_OFFSET, Data); +} + + +/****************************************************************************/ +/** +* +* The functions reads the contents of the Miscellaneous control register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return A 32-bit value representing the contents of the Config Register. +* Use the XADCPS_SR_*_MASK constants defined in xadcps_hw.h to +* interpret the returned value. +* +* @note None. +* +*****************************************************************************/ +u32 XAdcPs_GetMiscCtrlRegister(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Miscellaneous control register and return the value. + */ + return XAdcPs_ReadReg((InstancePtr)->Config.BaseAddress, + XADCPS_MCTL_OFFSET); +} + + +/*****************************************************************************/ +/** +* +* This function resets the XADC Hard Macro in the device. +* +* @param InstancePtr is a pointer to the Xxadc instance. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XAdcPs_Reset(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Generate the reset by Control + * register and release from reset + */ + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, + XADCPS_MCTL_OFFSET, 0x10); + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, + XADCPS_MCTL_OFFSET, 0x00); +} + + +/****************************************************************************/ +/** +* +* Get the ADC converted data for the specified channel. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Channel is the channel number. Use the XADCPS_CH_* defined in +* the file xadcps.h. +* The valid channels are +* - 0 to 6 +* - 13 to 31 +* +* @return A 16-bit value representing the ADC converted data for the +* specified channel. The XADC Monitor/ADC device guarantees +* a 10 bit resolution for the ADC converted data and data is the +* 10 MSB bits of the 16 data read from the device. +* +* @note The channels 7,8,9 are used for calibration of the device and +* hence there is no associated data with this channel. +* +*****************************************************************************/ +u16 XAdcPs_GetAdcData(XAdcPs *InstancePtr, u8 Channel) +{ + + u32 RegData; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + assert((Channel <= XADCPS_CH_VBRAM) || + ((Channel >= XADCPS_CH_VCCPINT) && + (Channel <= XADCPS_CH_AUX_MAX))); + + RegData = XAdcPs_ReadInternalReg(InstancePtr, + (XADCPS_TEMP_OFFSET + + Channel)); + return (u16) RegData; +} + +/****************************************************************************/ +/** +* +* This function gets the calibration coefficient data for the specified +* parameter. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param CoeffType specifies the calibration coefficient +* to be read. Use XADCPS_CALIB_* constants defined in xadcps.h to +* specify the calibration coefficient to be read. +* +* @return A 16-bit value representing the calibration coefficient. +* The XADC device guarantees a 10 bit resolution for +* the ADC converted data and data is the 10 MSB bits of the 16 +* data read from the device. +* +* @note None. +* +*****************************************************************************/ +u16 XAdcPs_GetCalibCoefficient(XAdcPs *InstancePtr, u8 CoeffType) +{ + u32 RegData; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + assert(CoeffType <= XADCPS_CALIB_GAIN_ERROR_COEFF); + + /* + * Read the selected calibration coefficient. + */ + RegData = XAdcPs_ReadInternalReg(InstancePtr, + (XADCPS_ADC_A_SUPPLY_CALIB_OFFSET + + CoeffType)); + return (u16) RegData; +} + +/****************************************************************************/ +/** +* +* This function reads the Minimum/Maximum measurement for one of the +* specified parameters. Use XADCPS_MAX_* and XADCPS_MIN_* constants defined in +* xadcps.h to specify the parameters (Temperature, VccInt, VccAux, VBram, +* VccPInt, VccPAux and VccPDro). +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param MeasurementType specifies the parameter for which the +* Minimum/Maximum measurement has to be read. +* Use XADCPS_MAX_* and XADCPS_MIN_* constants defined in xadcps.h to +* specify the data to be read. +* +* @return A 16-bit value representing the maximum/minimum measurement for +* specified parameter. +* The XADC device guarantees a 10 bit resolution for +* the ADC converted data and data is the 10 MSB bits of the 16 +* data read from the device. +* +* @note None. +* +*****************************************************************************/ +u16 XAdcPs_GetMinMaxMeasurement(XAdcPs *InstancePtr, u8 MeasurementType) +{ + u32 RegData; + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + assert((MeasurementType <= XADCPS_MAX_VCCPDRO) || + ((MeasurementType >= XADCPS_MIN_VCCPINT) && + (MeasurementType <= XADCPS_MIN_VCCPDRO))); + + /* + * Read and return the specified Minimum/Maximum measurement. + */ + RegData = XAdcPs_ReadInternalReg(InstancePtr, + (XADCPS_MAX_TEMP_OFFSET + + MeasurementType)); + return (u16) RegData; +} + +/****************************************************************************/ +/** +* +* This function sets the number of samples of averaging that is to be done for +* all the channels in both the single channel mode and sequence mode of +* operations. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Average is the number of samples of averaging programmed to the +* Configuration Register 0. Use the XADCPS_AVG_* definitions defined +* in xadcps.h file : +* - XADCPS_AVG_0_SAMPLES for no averaging +* - XADCPS_AVG_16_SAMPLES for 16 samples of averaging +* - XADCPS_AVG_64_SAMPLES for 64 samples of averaging +* - XADCPS_AVG_256_SAMPLES for 256 samples of averaging +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_SetAvg(XAdcPs *InstancePtr, u8 Average) +{ + u32 RegData; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + assert(Average <= XADCPS_AVG_256_SAMPLES); + + /* + * Write the averaging value into the Configuration Register 0. + */ + RegData = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR0_OFFSET) & + (~XADCPS_CFR0_AVG_VALID_MASK); + + RegData |= (((u32) Average << XADCPS_CFR0_AVG_SHIFT)); + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR0_OFFSET, + RegData); + +} + +/****************************************************************************/ +/** +* +* This function returns the number of samples of averaging configured for all +* the channels in the Configuration Register 0. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return The averaging read from the Configuration Register 0 is +* returned. Use the XADCPS_AVG_* bit definitions defined in +* xadcps.h file to interpret the returned value : +* - XADCPS_AVG_0_SAMPLES means no averaging +* - XADCPS_AVG_16_SAMPLES means 16 samples of averaging +* - XADCPS_AVG_64_SAMPLES means 64 samples of averaging +* - XADCPS_AVG_256_SAMPLES means 256 samples of averaging +* +* @note None. +* +*****************************************************************************/ +u8 XAdcPs_GetAvg(XAdcPs *InstancePtr) +{ + u32 Average; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the averaging value from the Configuration Register 0. + */ + Average = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR0_OFFSET) & XADCPS_CFR0_AVG_VALID_MASK; + + + return ((u8) (Average >> XADCPS_CFR0_AVG_SHIFT)); +} + +/****************************************************************************/ +/** +* +* The function sets the given parameters in the Configuration Register 0 in +* the single channel mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Channel is the channel number for the singel channel mode. +* The valid channels are 0 to 6, 8, and 13 to 31. +* If the external Mux is used then this specifies the channel +* oonnected to the external Mux. Please read the Device Spec +* to know which channels are valid. +* @param IncreaseAcqCycles is a boolean parameter which specifies whether +* the Acquisition time for the external channels has to be +* increased to 10 ADCCLK cycles (specify TRUE) or remain at the +* default 4 ADCCLK cycles (specify FALSE). This parameter is +* only valid for the external channels. +* @param IsDifferentialMode is a boolean parameter which specifies +* unipolar(specify FALSE) or differential mode (specify TRUE) for +* the analog inputs. The input mode is only valid for the +* external channels. +* +* @return +* - XST_SUCCESS if the given values were written successfully to +* the Configuration Register 0. +* - XST_FAILURE if the channel sequencer is enabled or the input +* parameters are not valid for the selected channel. +* +* @note +* - The number of samples for the averaging for all the channels +* is set by using the function XAdcPs_SetAvg. +* - The calibration of the device is done by doing a ADC +* conversion on the calibration channel(channel 8). The input +* parameters IncreaseAcqCycles, IsDifferentialMode and +* IsEventMode are not valid for this channel +* +* +*****************************************************************************/ +int XAdcPs_SetSingleChParams(XAdcPs *InstancePtr, + u8 Channel, + int IncreaseAcqCycles, + int IsEventMode, + int IsDifferentialMode) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + assert((Channel <= XADCPS_CH_VBRAM) || + (Channel == XADCPS_CH_ADC_CALIB) || + ((Channel >= XADCPS_CH_VCCPINT) && + (Channel <= XADCPS_CH_AUX_MAX))); + assert((IncreaseAcqCycles == TRUE) || + (IncreaseAcqCycles == FALSE)); + assert((IsEventMode == TRUE) || (IsEventMode == FALSE)); + assert((IsDifferentialMode == TRUE) || + (IsDifferentialMode == FALSE)); + + /* + * Check if the device is in single channel mode else return failure + */ + if ((XAdcPs_GetSequencerMode(InstancePtr) != + XADCPS_SEQ_MODE_SINGCHAN)) { + return XST_FAILURE; + } + + /* + * Read the Configuration Register 0. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR0_OFFSET) & + XADCPS_CFR0_AVG_VALID_MASK; + + /* + * Select the number of acquisition cycles. The acquisition cycles is + * only valid for the external channels. + */ + if (IncreaseAcqCycles == TRUE) { + if (((Channel >= XADCPS_CH_AUX_MIN) && + (Channel <= XADCPS_CH_AUX_MAX)) || + (Channel == XADCPS_CH_VPVN)) { + RegValue |= XADCPS_CFR0_ACQ_MASK; + } else { + return XST_FAILURE; + } + + } + + /* + * Select the input mode. The input mode is only valid for the + * external channels. + */ + if (IsDifferentialMode == TRUE) { + + if (((Channel >= XADCPS_CH_AUX_MIN) && + (Channel <= XADCPS_CH_AUX_MAX)) || + (Channel == XADCPS_CH_VPVN)) { + RegValue |= XADCPS_CFR0_DU_MASK; + } else { + return XST_FAILURE; + } + } + + /* + * Select the ADC mode. + */ + if (IsEventMode == TRUE) { + RegValue |= XADCPS_CFR0_EC_MASK; + } + + /* + * Write the given values into the Configuration Register 0. + */ + RegValue |= (Channel & XADCPS_CFR0_CHANNEL_MASK); + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR0_OFFSET, + RegValue); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function enables the alarm outputs for the specified alarms in the +* Configuration Register 1. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param AlmEnableMask is the bit-mask of the alarm outputs to be enabled +* in the Configuration Register 1. +* Bit positions of 1 will be enabled. Bit positions of 0 will be +* disabled. This mask is formed by OR'ing XADCPS_CFR1_ALM_*_MASK and +* XADCPS_CFR1_OT_MASK masks defined in xadcps_hw.h. +* +* @return None. +* +* @note The implementation of the alarm enables in the Configuration +* register 1 is such that the alarms for bit positions of 1 will +* be disabled and alarms for bit positions of 0 will be enabled. +* The alarm outputs specified by the AlmEnableMask are negated +* before writing to the Configuration Register 1. +* +* +*****************************************************************************/ +void XAdcPs_SetAlarmEnables(XAdcPs *InstancePtr, u16 AlmEnableMask) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + + RegValue = XAdcPs_ReadInternalReg(InstancePtr, XADCPS_CFR1_OFFSET); + + RegValue &= (u32)~XADCPS_CFR1_ALM_ALL_MASK; + RegValue |= (~AlmEnableMask & XADCPS_CFR1_ALM_ALL_MASK); + + /* + * Enable/disables the alarm enables for the specified alarm bits in the + * Configuration Register 1. + */ + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR1_OFFSET, + RegValue); +} + +/****************************************************************************/ +/** +* +* This function gets the status of the alarm output enables in the +* Configuration Register 1. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return This is the bit-mask of the enabled alarm outputs in the +* Configuration Register 1. Use the masks XADCPS_CFR1_ALM*_* and +* XADCPS_CFR1_OT_MASK defined in xadcps_hw.h to interpret the +* returned value. +* Bit positions of 1 indicate that the alarm output is enabled. +* Bit positions of 0 indicate that the alarm output is disabled. +* +* +* @note The implementation of the alarm enables in the Configuration +* register 1 is such that alarms for the bit positions of 1 will +* be disabled and alarms for bit positions of 0 will be enabled. +* The enabled alarm outputs returned by this function is the +* negated value of the the data read from the Configuration +* Register 1. +* +*****************************************************************************/ +u16 XAdcPs_GetAlarmEnables(XAdcPs *InstancePtr) +{ + u32 RegValue; + + /* + * Assert the arguments + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the status of alarm output enables from the Configuration + * Register 1. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR1_OFFSET) & XADCPS_CFR1_ALM_ALL_MASK; + return (u16) (~RegValue & XADCPS_CFR1_ALM_ALL_MASK); +} + +/****************************************************************************/ +/** +* +* This function enables the specified calibration in the Configuration +* Register 1 : +* +* - XADCPS_CFR1_CAL_ADC_OFFSET_MASK : Calibration 0 -ADC offset correction +* - XADCPS_CFR1_CAL_ADC_GAIN_OFFSET_MASK : Calibration 1 -ADC gain and offset +* correction +* - XADCPS_CFR1_CAL_PS_OFFSET_MASK : Calibration 2 -Power Supply sensor +* offset correction +* - XADCPS_CFR1_CAL_PS_GAIN_OFFSET_MASK : Calibration 3 -Power Supply sensor +* gain and offset correction +* - XADCPS_CFR1_CAL_DISABLE_MASK : No Calibration +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Calibration is the Calibration to be applied. +* Use XADCPS_CFR1_CAL*_* bits defined in xadcps_hw.h. +* Multiple calibrations can be enabled at a time by oring the +* XADCPS_CFR1_CAL_ADC_* and XADCPS_CFR1_CAL_PS_* bits. +* Calibration can be disabled by specifying + XADCPS_CFR1_CAL_DISABLE_MASK; +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_SetCalibEnables(XAdcPs *InstancePtr, u16 Calibration) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + assert(((Calibration >= XADCPS_CFR1_CAL_ADC_OFFSET_MASK) && + (Calibration <= XADCPS_CFR1_CAL_VALID_MASK)) || + (Calibration == XADCPS_CFR1_CAL_DISABLE_MASK)); + + /* + * Set the specified calibration in the Configuration Register 1. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR1_OFFSET); + + RegValue &= (~XADCPS_CFR1_CAL_VALID_MASK); + RegValue |= (Calibration & XADCPS_CFR1_CAL_VALID_MASK); + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR1_OFFSET, + RegValue); + +} + +/****************************************************************************/ +/** +* +* This function reads the value of the calibration enables from the +* Configuration Register 1. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return The value of the calibration enables in the Configuration +* Register 1 : +* - XADCPS_CFR1_CAL_ADC_OFFSET_MASK : ADC offset correction +* - XADCPS_CFR1_CAL_ADC_GAIN_OFFSET_MASK : ADC gain and offset +* correction +* - XADCPS_CFR1_CAL_PS_OFFSET_MASK : Power Supply sensor offset +* correction +* - XADCPS_CFR1_CAL_PS_GAIN_OFFSET_MASK : Power Supply sensor +* gain and offset correction +* - XADCPS_CFR1_CAL_DISABLE_MASK : No Calibration +* +* @note None. +* +*****************************************************************************/ +u16 XAdcPs_GetCalibEnables(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the calibration enables from the Configuration Register 1. + */ + return (u16) XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR1_OFFSET) & XADCPS_CFR1_CAL_VALID_MASK; + +} + +/****************************************************************************/ +/** +* +* This function sets the specified Channel Sequencer Mode in the Configuration +* Register 1 : +* - Default safe mode (XADCPS_SEQ_MODE_SAFE) +* - One pass through sequence (XADCPS_SEQ_MODE_ONEPASS) +* - Continuous channel sequencing (XADCPS_SEQ_MODE_CONTINPASS) +* - Single Channel/Sequencer off (XADCPS_SEQ_MODE_SINGCHAN) +* - Simulataneous sampling mode (XADCPS_SEQ_MODE_SIMUL_SAMPLING) +* - Independent mode (XADCPS_SEQ_MODE_INDEPENDENT) +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param SequencerMode is the sequencer mode to be set. +* Use XADCPS_SEQ_MODE_* bits defined in xadcps.h. +* @return None. +* +* @note Only one of the modes can be enabled at a time. Please +* read the Spec of the XADC for further information about the +* sequencer modes. +* +* +*****************************************************************************/ +void XAdcPs_SetSequencerMode(XAdcPs *InstancePtr, u8 SequencerMode) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + assert((SequencerMode <= XADCPS_SEQ_MODE_SIMUL_SAMPLING) || + (SequencerMode == XADCPS_SEQ_MODE_INDEPENDENT)); + + /* + * Set the specified sequencer mode in the Configuration Register 1. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR1_OFFSET); + RegValue &= (~XADCPS_CFR1_SEQ_VALID_MASK); + RegValue |= ((SequencerMode << XADCPS_CFR1_SEQ_SHIFT) & + XADCPS_CFR1_SEQ_VALID_MASK); + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR1_OFFSET, + RegValue); + +} + +/****************************************************************************/ +/** +* +* This function gets the channel sequencer mode from the Configuration +* Register 1. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return The channel sequencer mode : +* - XADCPS_SEQ_MODE_SAFE : Default safe mode +* - XADCPS_SEQ_MODE_ONEPASS : One pass through sequence +* - XADCPS_SEQ_MODE_CONTINPASS : Continuous channel sequencing +* - XADCPS_SEQ_MODE_SINGCHAN : Single channel/Sequencer off +* - XADCPS_SEQ_MODE_SIMUL_SAMPLING : Simulataneous sampling mode +* - XADCPS_SEQ_MODE_INDEPENDENT : Independent mode +* +* +* @note None. +* +*****************************************************************************/ +u8 XAdcPs_GetSequencerMode(XAdcPs *InstancePtr) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the channel sequencer mode from the Configuration Register 1. + */ + return ((u8) ((XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR1_OFFSET) & XADCPS_CFR1_SEQ_VALID_MASK) >> + XADCPS_CFR1_SEQ_SHIFT)); + +} + +/****************************************************************************/ +/** +* +* The function sets the frequency of the ADCCLK by configuring the DCLK to +* ADCCLK ratio in the Configuration Register #2 +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Divisor is clock divisor used to derive ADCCLK from DCLK. +* Valid values of the divisor are +* - 0 to 255. Values 0, 1, 2 are all mapped to 2. +* Refer to the device specification for more details +* +* @return None. +* +* @note - The ADCCLK is an internal clock used by the ADC and is +* synchronized to the DCLK clock. The ADCCLK is equal to DCLK +* divided by the user selection in the Configuration Register 2. +* - There is no Assert on the minimum value of the Divisor. +* +*****************************************************************************/ +void XAdcPs_SetAdcClkDivisor(XAdcPs *InstancePtr, u8 Divisor) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Write the divisor value into the Configuration Register #2. + */ + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR2_OFFSET, + Divisor << XADCPS_CFR2_CD_SHIFT); + +} + +/****************************************************************************/ +/** +* +* The function gets the ADCCLK divisor from the Configuration Register 2. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return The divisor read from the Configuration Register 2. +* +* @note The ADCCLK is an internal clock used by the ADC and is +* synchronized to the DCLK clock. The ADCCLK is equal to DCLK +* divided by the user selection in the Configuration Register 2. +* +*****************************************************************************/ +u8 XAdcPs_GetAdcClkDivisor(XAdcPs *InstancePtr) +{ + u16 Divisor; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the divisor value from the Configuration Register 2. + */ + Divisor = (u16) XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR2_OFFSET); + + return (u8) (Divisor >> XADCPS_CFR2_CD_SHIFT); +} + +/****************************************************************************/ +/** +* +* This function enables the specified channels in the ADC Channel Selection +* Sequencer Registers. The sequencer must be disabled before writing to these +* regsiters. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param ChEnableMask is the bit mask of all the channels to be enabled. +* Use XADCPS_SEQ_CH__* defined in xadcps_hw.h to specify the Channel +* numbers. Bit masks of 1 will be enabled and bit mask of 0 will +* be disabled. +* The ChEnableMask is a 32 bit mask that is written to the two +* 16 bit ADC Channel Selection Sequencer Registers. +* +* @return +* - XST_SUCCESS if the given values were written successfully to +* the ADC Channel Selection Sequencer Registers. +* - XST_FAILURE if the channel sequencer is enabled. +* +* @note None +* +*****************************************************************************/ +int XAdcPs_SetSeqChEnables(XAdcPs *InstancePtr, u32 ChEnableMask) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The sequencer must be disabled for writing any of these registers + * Return XST_FAILURE if the channel sequencer is enabled. + */ + if ((XAdcPs_GetSequencerMode(InstancePtr) != XADCPS_SEQ_MODE_SAFE)) { + return XST_FAILURE; + } + + /* + * Enable the specified channels in the ADC Channel Selection Sequencer + * Registers. + */ + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ00_OFFSET, + (ChEnableMask & XADCPS_SEQ00_CH_VALID_MASK)); + + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ01_OFFSET, + (ChEnableMask >> XADCPS_SEQ_CH_AUX_SHIFT) & + XADCPS_SEQ01_CH_VALID_MASK); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function gets the channel enable bits status from the ADC Channel +* Selection Sequencer Registers. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return Gets the channel enable bits. Use XADCPS_SEQ_CH__* defined in +* xadcps_hw.h to interpret the Channel numbers. Bit masks of 1 +* are the channels that are enabled and bit mask of 0 are +* the channels that are disabled. +* +* @return None +* +* @note None +* +*****************************************************************************/ +u32 XAdcPs_GetSeqChEnables(XAdcPs *InstancePtr) +{ + u32 RegValEnable; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the channel enable bits for all the channels from the ADC + * Channel Selection Register. + */ + RegValEnable = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ00_OFFSET) & + XADCPS_SEQ00_CH_VALID_MASK; + RegValEnable |= (XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ01_OFFSET) & + XADCPS_SEQ01_CH_VALID_MASK) << + XADCPS_SEQ_CH_AUX_SHIFT; + + + return RegValEnable; +} + +/****************************************************************************/ +/** +* +* This function enables the averaging for the specified channels in the ADC +* Channel Averaging Enable Sequencer Registers. The sequencer must be disabled +* before writing to these regsiters. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param AvgEnableChMask is the bit mask of all the channels for which +* averaging is to be enabled. Use XADCPS_SEQ_CH__* defined in +* xadcps_hw.h to specify the Channel numbers. Averaging will be +* enabled for bit masks of 1 and disabled for bit mask of 0. +* The AvgEnableChMask is a 32 bit mask that is written to the two +* 16 bit ADC Channel Averaging Enable Sequencer Registers. +* +* @return +* - XST_SUCCESS if the given values were written successfully to +* the ADC Channel Averaging Enables Sequencer Registers. +* - XST_FAILURE if the channel sequencer is enabled. +* +* @note None +* +*****************************************************************************/ +int XAdcPs_SetSeqAvgEnables(XAdcPs *InstancePtr, u32 AvgEnableChMask) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The sequencer must be disabled for writing any of these registers + * Return XST_FAILURE if the channel sequencer is enabled. + */ + if ((XAdcPs_GetSequencerMode(InstancePtr) != XADCPS_SEQ_MODE_SAFE)) { + return XST_FAILURE; + } + + /* + * Enable/disable the averaging for the specified channels in the + * ADC Channel Averaging Enables Sequencer Registers. + */ + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ02_OFFSET, + (AvgEnableChMask & XADCPS_SEQ02_CH_VALID_MASK)); + + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ03_OFFSET, + (AvgEnableChMask >> XADCPS_SEQ_CH_AUX_SHIFT) & + XADCPS_SEQ03_CH_VALID_MASK); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function returns the channels for which the averaging has been enabled +* in the ADC Channel Averaging Enables Sequencer Registers. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @returns The status of averaging (enabled/disabled) for all the channels. +* Use XADCPS_SEQ_CH__* defined in xadcps_hw.h to interpret the +* Channel numbers. Bit masks of 1 are the channels for which +* averaging is enabled and bit mask of 0 are the channels for +* averaging is disabled +* +* @note None +* +*****************************************************************************/ +u32 XAdcPs_GetSeqAvgEnables(XAdcPs *InstancePtr) +{ + u32 RegValAvg; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the averaging enable status for all the channels from the + * ADC Channel Averaging Enables Sequencer Registers. + */ + RegValAvg = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ02_OFFSET) & XADCPS_SEQ02_CH_VALID_MASK; + RegValAvg |= (XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ03_OFFSET) & XADCPS_SEQ03_CH_VALID_MASK) << + XADCPS_SEQ_CH_AUX_SHIFT; + + return RegValAvg; +} + +/****************************************************************************/ +/** +* +* This function sets the Analog input mode for the specified channels in the ADC +* Channel Analog-Input Mode Sequencer Registers. The sequencer must be disabled +* before writing to these regsiters. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param InputModeChMask is the bit mask of all the channels for which +* the input mode is differential mode. Use XADCPS_SEQ_CH__* defined +* in xadcps_hw.h to specify the channel numbers. Differential +* input mode will be set for bit masks of 1 and unipolar input +* mode for bit masks of 0. +* The InputModeChMask is a 32 bit mask that is written to the two +* 16 bit ADC Channel Analog-Input Mode Sequencer Registers. +* +* @return +* - XST_SUCCESS if the given values were written successfully to +* the ADC Channel Analog-Input Mode Sequencer Registers. +* - XST_FAILURE if the channel sequencer is enabled. +* +* @note None +* +*****************************************************************************/ +int XAdcPs_SetSeqInputMode(XAdcPs *InstancePtr, u32 InputModeChMask) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The sequencer must be disabled for writing any of these registers + * Return XST_FAILURE if the channel sequencer is enabled. + */ + if ((XAdcPs_GetSequencerMode(InstancePtr) != XADCPS_SEQ_MODE_SAFE)) { + return XST_FAILURE; + } + + /* + * Set the input mode for the specified channels in the ADC Channel + * Analog-Input Mode Sequencer Registers. + */ + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ04_OFFSET, + (InputModeChMask & XADCPS_SEQ04_CH_VALID_MASK)); + + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ05_OFFSET, + (InputModeChMask >> XADCPS_SEQ_CH_AUX_SHIFT) & + XADCPS_SEQ05_CH_VALID_MASK); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function gets the Analog input mode for all the channels from +* the ADC Channel Analog-Input Mode Sequencer Registers. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @returns The input mode for all the channels. +* Use XADCPS_SEQ_CH_* defined in xadcps_hw.h to interpret the +* Channel numbers. Bit masks of 1 are the channels for which +* input mode is differential and bit mask of 0 are the channels +* for which input mode is unipolar. +* +* @note None. +* +*****************************************************************************/ +u32 XAdcPs_GetSeqInputMode(XAdcPs *InstancePtr) +{ + u32 InputMode; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Get the input mode for all the channels from the ADC Channel + * Analog-Input Mode Sequencer Registers. + */ + InputMode = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ04_OFFSET) & + XADCPS_SEQ04_CH_VALID_MASK; + InputMode |= (XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ05_OFFSET) & + XADCPS_SEQ05_CH_VALID_MASK) << + XADCPS_SEQ_CH_AUX_SHIFT; + + return InputMode; +} + +/****************************************************************************/ +/** +* +* This function sets the number of Acquisition cycles in the ADC Channel +* Acquisition Time Sequencer Registers. The sequencer must be disabled +* before writing to these regsiters. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param AcqCyclesChMask is the bit mask of all the channels for which +* the number of acquisition cycles is to be extended. +* Use XADCPS_SEQ_CH__* defined in xadcps_hw.h to specify the Channel +* numbers. Acquisition cycles will be extended to 10 ADCCLK cycles +* for bit masks of 1 and will be the default 4 ADCCLK cycles for +* bit masks of 0. +* The AcqCyclesChMask is a 32 bit mask that is written to the two +* 16 bit ADC Channel Acquisition Time Sequencer Registers. +* +* @return +* - XST_SUCCESS if the given values were written successfully to +* the Channel Sequencer Registers. +* - XST_FAILURE if the channel sequencer is enabled. +* +* @note None. +* +*****************************************************************************/ +int XAdcPs_SetSeqAcqTime(XAdcPs *InstancePtr, u32 AcqCyclesChMask) +{ + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * The sequencer must be disabled for writing any of these registers + * Return XST_FAILURE if the channel sequencer is enabled. + */ + if ((XAdcPs_GetSequencerMode(InstancePtr) != + XADCPS_SEQ_MODE_SAFE)) { + return XST_FAILURE; + } + + /* + * Set the Acquisition time for the specified channels in the + * ADC Channel Acquisition Time Sequencer Registers. + */ + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ06_OFFSET, + (AcqCyclesChMask & XADCPS_SEQ06_CH_VALID_MASK)); + + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_SEQ07_OFFSET, + (AcqCyclesChMask >> XADCPS_SEQ_CH_AUX_SHIFT) & + XADCPS_SEQ07_CH_VALID_MASK); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This function gets the status of acquisition from the ADC Channel Acquisition +* Time Sequencer Registers. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @returns The acquisition time for all the channels. +* Use XADCPS_SEQ_CH__* defined in xadcps_hw.h to interpret the +* Channel numbers. Bit masks of 1 are the channels for which +* acquisition cycles are extended and bit mask of 0 are the +* channels for which acquisition cycles are not extended. +* +* @note None +* +*****************************************************************************/ +u32 XAdcPs_GetSeqAcqTime(XAdcPs *InstancePtr) +{ + u32 RegValAcq; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Get the Acquisition cycles for the specified channels from the ADC + * Channel Acquisition Time Sequencer Registers. + */ + RegValAcq = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ06_OFFSET) & + XADCPS_SEQ06_CH_VALID_MASK; + RegValAcq |= (XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_SEQ07_OFFSET) & + XADCPS_SEQ07_CH_VALID_MASK) << + XADCPS_SEQ_CH_AUX_SHIFT; + + return RegValAcq; +} + +/****************************************************************************/ +/** +* +* This functions sets the contents of the given Alarm Threshold Register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param AlarmThrReg is the index of an Alarm Threshold Register to +* be set. Use XADCPS_ATR_* constants defined in xadcps.h to +* specify the index. +* @param Value is the 16-bit threshold value to write into the register. +* +* @return None. +* +* @note Use XAdcPs_SetOverTemp() to set the Over Temperature upper +* threshold value. +* +*****************************************************************************/ +void XAdcPs_SetAlarmThreshold(XAdcPs *InstancePtr, u8 AlarmThrReg, u16 Value) +{ + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + assert(AlarmThrReg <= XADCPS_ATR_VCCPDRO_LOWER); + + /* + * Write the value into the specified Alarm Threshold Register. + */ + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_ATR_TEMP_UPPER_OFFSET + + AlarmThrReg, Value); + +} + +/****************************************************************************/ +/** +* +* This function returns the contents of the specified Alarm Threshold Register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param AlarmThrReg is the index of an Alarm Threshold Register +* to be read. Use XADCPS_ATR_* constants defined in xadcps_hw.h +* to specify the index. +* +* @return A 16-bit value representing the contents of the selected Alarm +* Threshold Register. +* +* @note None. +* +*****************************************************************************/ +u16 XAdcPs_GetAlarmThreshold(XAdcPs *InstancePtr, u8 AlarmThrReg) +{ + u32 RegData; + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + assert(AlarmThrReg <= XADCPS_ATR_VCCPDRO_LOWER); + + /* + * Read the specified Alarm Threshold Register and return + * the value + */ + RegData = XAdcPs_ReadInternalReg(InstancePtr, + (XADCPS_ATR_TEMP_UPPER_OFFSET + AlarmThrReg)); + + return (u16) RegData; +} + + +/****************************************************************************/ +/** +* +* This function enables programming of the powerdown temperature for the +* OverTemp signal in the OT Powerdown register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_EnableUserOverTemp(XAdcPs *InstancePtr) +{ + u16 OtUpper; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the OT upper Alarm Threshold Register. + */ + OtUpper = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_ATR_OT_UPPER_OFFSET); + OtUpper &= ~(XADCPS_ATR_OT_UPPER_ENB_MASK); + + /* + * Preserve the powerdown value and write OT enable value the into the + * OT Upper Alarm Threshold Register. + */ + OtUpper |= XADCPS_ATR_OT_UPPER_ENB_VAL; + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_ATR_OT_UPPER_OFFSET, OtUpper); +} + +/****************************************************************************/ +/** +* +* This function disables programming of the powerdown temperature for the +* OverTemp signal in the OT Powerdown register. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return None. +* +* @note None. +* +* +*****************************************************************************/ +void XAdcPs_DisableUserOverTemp(XAdcPs *InstancePtr) +{ + u16 OtUpper; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the OT Upper Alarm Threshold Register. + */ + OtUpper = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_ATR_OT_UPPER_OFFSET); + OtUpper &= ~(XADCPS_ATR_OT_UPPER_ENB_MASK); + + XAdcPs_WriteInternalReg(InstancePtr, + XADCPS_ATR_OT_UPPER_OFFSET, OtUpper); +} + + +/****************************************************************************/ +/** +* +* The function enables the Event mode or Continuous mode in the sequencer mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param IsEventMode is a boolean parameter that specifies continuous +* sampling (specify FALSE) or event driven sampling mode (specify +* TRUE) for the given channel. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_SetSequencerEvent(XAdcPs *InstancePtr, int IsEventMode) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + assert((IsEventMode == TRUE) || (IsEventMode == FALSE)); + + /* + * Read the Configuration Register 0. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR0_OFFSET) & + (~XADCPS_CFR0_EC_MASK); + + /* + * Set the ADC mode. + */ + if (IsEventMode == TRUE) { + RegValue |= XADCPS_CFR0_EC_MASK; + } else { + RegValue &= ~XADCPS_CFR0_EC_MASK; + } + + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR0_OFFSET, + RegValue); +} + + +/****************************************************************************/ +/** +* +* This function returns the sampling mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return The sampling mode +* - 0 specifies continuous sampling +* - 1 specifies event driven sampling mode +* +* @note None. +* +*****************************************************************************/ +int XAdcPs_GetSamplingMode(XAdcPs *InstancePtr) +{ + u32 Mode; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the sampling mode from the Configuration Register 0. + */ + Mode = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR0_OFFSET) & + XADCPS_CFR0_EC_MASK; + if (Mode) { + + return 1; + } + + return (0); +} + + +/****************************************************************************/ +/** +* +* This function sets the External Mux mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param MuxMode specifies whether External Mux is used +* - FALSE specifies NO external MUX +* - TRUE specifies External Mux is used +* @param Channel specifies the channel to be used for the +* external Mux. Please read the Device Spec for which +* channels are valid for which mode. +* +* @return None. +* +* @note There is no Assert in this function for checking the channel +* number if the external Mux is used. The user should provide a +* valid channel number. +* +*****************************************************************************/ +void XAdcPs_SetMuxMode(XAdcPs *InstancePtr, int MuxMode, u8 Channel) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + assert((MuxMode == TRUE) || (MuxMode == FALSE)); + + /* + * Read the Configuration Register 0. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR0_OFFSET) & + (~XADCPS_CFR0_MUX_MASK); + /* + * Select the Mux mode and the channel to be used. + */ + if (MuxMode == TRUE) { + RegValue |= XADCPS_CFR0_MUX_MASK; + RegValue |= (Channel & XADCPS_CFR0_CHANNEL_MASK); + + } + + /* + * Write the mux mode into the Configuration Register 0. + */ + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR0_OFFSET, + RegValue); +} + + +/****************************************************************************/ +/** +* +* This function sets the Power Down mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param Mode specifies the Power Down Mode +* - XADCPS_PD_MODE_NONE specifies NO Power Down (Both ADC A and +* ADC B are enabled) +* - XADCPS_PD_MODE_ADCB specfies the Power Down of ADC B +* - XADCPS_PD_MODE_XADC specifies the Power Down of +* both ADC A and ADC B. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XAdcPs_SetPowerdownMode(XAdcPs *InstancePtr, u32 Mode) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + assert(Mode < XADCPS_PD_MODE_XADC); + + + /* + * Read the Configuration Register 2. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR2_OFFSET) & + (~XADCPS_CFR2_PD_MASK); + /* + * Select the Power Down mode. + */ + RegValue |= (Mode << XADCPS_CFR2_PD_SHIFT); + + XAdcPs_WriteInternalReg(InstancePtr, XADCPS_CFR2_OFFSET, + RegValue); +} + +/****************************************************************************/ +/** +* +* This function gets the Power Down mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return Mode specifies the Power Down Mode +* - XADCPS_PD_MODE_NONE specifies NO Power Down (Both ADC A and +* ADC B are enabled) +* - XADCPS_PD_MODE_ADCB specfies the Power Down of ADC B +* - XADCPS_PD_MODE_XADC specifies the Power Down of +* both ADC A and ADC B. +* +* @note None. +* +*****************************************************************************/ +u32 XAdcPs_GetPowerdownMode(XAdcPs *InstancePtr) +{ + u32 RegValue; + + /* + * Assert the arguments. + */ + assert(InstancePtr != NULL); + assert(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the Power Down Mode. + */ + RegValue = XAdcPs_ReadInternalReg(InstancePtr, + XADCPS_CFR2_OFFSET) & + (~XADCPS_CFR2_PD_MASK); + /* + * Return the Power Down mode. + */ + return (RegValue >> XADCPS_CFR2_PD_SHIFT); + +} + +/****************************************************************************/ +/** +* +* This function is used for writing to XADC Registers using the command FIFO. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param RegOffset is the offset of the XADC register to be written. +* @param Data is the data to be written. +* +* @return None. +* +* @note None. +* +* +*****************************************************************************/ +void XAdcPs_WriteInternalReg(XAdcPs *InstancePtr, u32 RegOffset, u32 Data) +{ + u32 RegData; + + /* + * Write the Data into the FIFO Register. + */ + RegData = XAdcPs_FormatWriteData(RegOffset, Data, TRUE); + + XAdcPs_WriteFifo(InstancePtr, RegData); + + /* Read the Read FIFO after any write since for each write + * one location of Read FIFO gets updated + */ + XAdcPs_ReadFifo(InstancePtr); + +} + + +/****************************************************************************/ +/** +* +* This function is used for reading from the XADC Registers using the Data FIFO. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* @param RegOffset is the offset of the XADC register to be read. +* +* @return Data read from the FIFO +* +* @note None. +* +* +*****************************************************************************/ +u32 XAdcPs_ReadInternalReg(XAdcPs *InstancePtr, u32 RegOffset) +{ + + u32 RegData; + + RegData = XAdcPs_FormatWriteData(RegOffset, 0x0, FALSE); + + /* Read cmd to FIFO*/ + XAdcPs_WriteFifo(InstancePtr, RegData); + + /* Do a Dummy read */ + RegData = XAdcPs_ReadFifo(InstancePtr); + + /* Do a Dummy write to get the actual read */ + XAdcPs_WriteFifo(InstancePtr, RegData); + + /* Do the Actual read */ + RegData = XAdcPs_ReadFifo(InstancePtr); + + return RegData; + +} + + +/** @} */ diff --git a/cmd/xadcps.h b/cmd/xadcps.h new file mode 100644 index 000000000000..3e18f62614fb --- /dev/null +++ b/cmd/xadcps.h @@ -0,0 +1,583 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xadcps.h +* @addtogroup xadcps_v2_2 +* @{ +* @details +* +* The XAdcPs driver supports the Xilinx XADC/ADC device. +* +* The XADC/ADC device has the following features: +* - 10-bit, 200-KSPS (kilo samples per second) +* Analog-to-Digital Converter (ADC) +* - Monitoring of on-chip supply voltages and temperature +* - 1 dedicated differential analog-input pair and +* 16 auxiliary differential analog-input pairs +* - Automatic alarms based on user defined limits for the on-chip +* supply voltages and temperature +* - Automatic Channel Sequencer, programmable averaging, programmable +* acquisition time for the external inputs, unipolar or differential +* input selection for the external inputs +* - Inbuilt Calibration +* - Optional interrupt request generation +* +* +* The user should refer to the hardware device specification for detailed +* information about the device. +* +* This header file contains the prototypes of driver functions that can +* be used to access the XADC/ADC device. +* +* +* XADC Channel Sequencer Modes +* +* The XADC Channel Sequencer supports the following operating modes: +* +* - Default : This is the default mode after power up. +* In this mode of operation the XADC operates in +* a sequence mode, monitoring the on chip sensors: +* Temperature, VCCINT, and VCCAUX. +* - One pass through sequence : In this mode the XADC +* converts the channels enabled in the Sequencer Channel Enable +* registers for a single pass and then stops. +* - Continuous cycling of sequence : In this mode the XADC +* converts the channels enabled in the Sequencer Channel Enable +* registers continuously. +* - Single channel mode: In this mode the XADC Channel +* Sequencer is disabled and the XADC operates in a +* Single Channel Mode. +* The XADC can operate either in a Continuous or Event +* driven sampling mode in the single channel mode. +* - Simultaneous Sampling Mode: In this mode the XADC Channel +* Sequencer will automatically sequence through eight fixed pairs +* of auxiliary analog input channels for simulataneous conversion. +* - Independent ADC mode: In this mode the first ADC (A) is used to +* is used to implement a fixed monitoring mode similar to the +* default mode but the alarm fucntions ar eenabled. +* The second ADC (B) is available to be used with external analog +* input channels only. +* +* Read the XADC spec for more information about the sequencer modes. +* +* Initialization and Configuration +* +* The device driver enables higher layer software (e.g., an application) to +* communicate to the XADC/ADC device. +* +* XAdcPs_CfgInitialize() API is used to initialize the XADC/ADC +* device. The user needs to first call the XAdcPs_LookupConfig() API which +* returns the Configuration structure pointer which is passed as a parameter to +* the XAdcPs_CfgInitialize() API. +* +* +* Interrupts +* +* The XADC/ADC device supports interrupt driven mode and the default +* operation mode is polling mode. +* +* The interrupt mode is available only if hardware is configured to support +* interrupts. +* +* This driver does not provide a Interrupt Service Routine (ISR) for the device. +* It is the responsibility of the application to provide one if needed. Refer to +* the interrupt example provided with this driver for details on using the +* device in interrupt mode. +* +* +* Virtual Memory +* +* This driver supports Virtual Memory. The RTOS is responsible for calculating +* the correct device base address in Virtual Memory space. +* +* +* Threads +* +* This driver is not thread safe. Any needs for threads or thread mutual +* exclusion must be satisfied by the layer above this driver. +* +* +* Asserts +* +* Asserts are used within all Xilinx drivers to enforce constraints on argument +* values. Asserts can be turned off on a system-wide basis by defining, at +* compile time, the NDEBUG identifier. By default, asserts are turned on and it +* is recommended that users leave asserts on during development. +* +* +* Building the driver +* +* The XAdcPs driver is composed of several source files. This allows the user +* to build and link only those parts of the driver that are necessary. +* +* Limitations of the driver +* +* XADC/ADC device can be accessed through the JTAG port and the PLB +* interface. The driver implementation does not support the simultaneous access +* of the device by both these interfaces. The user has to care of this situation +* in the user application code. +* +*

+* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- -----  -------- -----------------------------------------------------
+* 1.00a ssb    12/22/11 First release based on the XPS/AXI xadc driver
+* 1.01a bss    02/18/13	Modified XAdcPs_SetSeqChEnables,XAdcPs_SetSeqAvgEnables
+*			XAdcPs_SetSeqInputMode and XAdcPs_SetSeqAcqTime APIs
+*			in xadcps.c to fix CR #693371
+* 1.03a bss    11/01/13 Modified xadcps_hw.h to use correct Register offsets
+*			CR#749687
+* 2.1   bss    08/05/14 Added declarations for XAdcPs_SetSequencerEvent,
+*			XAdcPs_GetSamplingMode, XAdcPs_SetMuxMode,
+*			XAdcPs_SetPowerdownMode and XAdcPs_GetPowerdownMode
+*			functions.
+*			Modified Assert for XAdcPs_SetSingleChParams in
+*			xadcps.c to fix CR #807563.
+* 2.2   bss    04/27/14 Modified to use correct Device Config base address in
+*						xadcps.c (CR#854437).
+*
+*
+* 
+* +*****************************************************************************/ +#ifndef XADCPS_H /* Prevent circular inclusions */ +#define XADCPS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +//#include "xil_types.h" +//#include "xil_assert.h" +//#include "xstatus.h" +#include "xadcps_hw.h" + +/************************** Constant Definitions ****************************/ + + +/** + * @name Indexes for the different channels. + * @{ + */ +#define XADCPS_CH_TEMP 0x0 /**< On Chip Temperature */ +#define XADCPS_CH_VCCINT 0x1 /**< VCCINT */ +#define XADCPS_CH_VCCAUX 0x2 /**< VCCAUX */ +#define XADCPS_CH_VPVN 0x3 /**< VP/VN Dedicated analog inputs */ +#define XADCPS_CH_VREFP 0x4 /**< VREFP */ +#define XADCPS_CH_VREFN 0x5 /**< VREFN */ +#define XADCPS_CH_VBRAM 0x6 /**< On-chip VBRAM Data Reg, 7 series */ +#define XADCPS_CH_SUPPLY_CALIB 0x07 /**< Supply Calib Data Reg */ +#define XADCPS_CH_ADC_CALIB 0x08 /**< ADC Offset Channel Reg */ +#define XADCPS_CH_GAINERR_CALIB 0x09 /**< Gain Error Channel Reg */ +#define XADCPS_CH_VCCPINT 0x0D /**< On-chip PS VCCPINT Channel , Zynq */ +#define XADCPS_CH_VCCPAUX 0x0E /**< On-chip PS VCCPAUX Channel , Zynq */ +#define XADCPS_CH_VCCPDRO 0x0F /**< On-chip PS VCCPDRO Channel , Zynq */ +#define XADCPS_CH_AUX_MIN 16 /**< Channel number for 1st Aux Channel */ +#define XADCPS_CH_AUX_MAX 31 /**< Channel number for Last Aux channel */ + +/*@}*/ + + +/** + * @name Indexes for reading the Calibration Coefficient Data. + * @{ + */ +#define XADCPS_CALIB_SUPPLY_COEFF 0 /**< Supply Offset Calib Coefficient */ +#define XADCPS_CALIB_ADC_COEFF 1 /**< ADC Offset Calib Coefficient */ +#define XADCPS_CALIB_GAIN_ERROR_COEFF 2 /**< Gain Error Calib Coefficient*/ +/*@}*/ + + +/** + * @name Indexes for reading the Minimum/Maximum Measurement Data. + * @{ + */ +#define XADCPS_MAX_TEMP 0 /**< Maximum Temperature Data */ +#define XADCPS_MAX_VCCINT 1 /**< Maximum VCCINT Data */ +#define XADCPS_MAX_VCCAUX 2 /**< Maximum VCCAUX Data */ +#define XADCPS_MAX_VBRAM 3 /**< Maximum VBRAM Data */ +#define XADCPS_MIN_TEMP 4 /**< Minimum Temperature Data */ +#define XADCPS_MIN_VCCINT 5 /**< Minimum VCCINT Data */ +#define XADCPS_MIN_VCCAUX 6 /**< Minimum VCCAUX Data */ +#define XADCPS_MIN_VBRAM 7 /**< Minimum VBRAM Data */ +#define XADCPS_MAX_VCCPINT 8 /**< Maximum VCCPINT Register , Zynq */ +#define XADCPS_MAX_VCCPAUX 9 /**< Maximum VCCPAUX Register , Zynq */ +#define XADCPS_MAX_VCCPDRO 0xA /**< Maximum VCCPDRO Register , Zynq */ +#define XADCPS_MIN_VCCPINT 0xC /**< Minimum VCCPINT Register , Zynq */ +#define XADCPS_MIN_VCCPAUX 0xD /**< Minimum VCCPAUX Register , Zynq */ +#define XADCPS_MIN_VCCPDRO 0xE /**< Minimum VCCPDRO Register , Zynq */ + +/*@}*/ + + +/** + * @name Alarm Threshold(Limit) Register (ATR) indexes. + * @{ + */ +#define XADCPS_ATR_TEMP_UPPER 0 /**< High user Temperature */ +#define XADCPS_ATR_VCCINT_UPPER 1 /**< VCCINT high voltage limit register */ +#define XADCPS_ATR_VCCAUX_UPPER 2 /**< VCCAUX high voltage limit register */ +#define XADCPS_ATR_OT_UPPER 3 /**< VCCAUX high voltage limit register */ +#define XADCPS_ATR_TEMP_LOWER 4 /**< Upper Over Temperature limit Reg */ +#define XADCPS_ATR_VCCINT_LOWER 5 /**< VCCINT high voltage limit register */ +#define XADCPS_ATR_VCCAUX_LOWER 6 /**< VCCAUX low voltage limit register */ +#define XADCPS_ATR_OT_LOWER 7 /**< Lower Over Temperature limit */ +#define XADCPS_ATR_VBRAM_UPPER_ 8 /**< VRBAM Upper Alarm Reg, 7 Series */ +#define XADCPS_ATR_VCCPINT_UPPER 9 /**< VCCPINT Upper Alarm Reg, Zynq */ +#define XADCPS_ATR_VCCPAUX_UPPER 0xA /**< VCCPAUX Upper Alarm Reg, Zynq */ +#define XADCPS_ATR_VCCPDRO_UPPER 0xB /**< VCCPDRO Upper Alarm Reg, Zynq */ +#define XADCPS_ATR_VBRAM_LOWER 0xC /**< VRBAM Lower Alarm Reg, 7 Series */ +#define XADCPS_ATR_VCCPINT_LOWER 0xD /**< VCCPINT Lower Alarm Reg , Zynq */ +#define XADCPS_ATR_VCCPAUX_LOWER 0xE /**< VCCPAUX Lower Alarm Reg , Zynq */ +#define XADCPS_ATR_VCCPDRO_LOWER 0xF /**< VCCPDRO Lower Alarm Reg , Zynq */ + +/*@}*/ + + +/** + * @name Averaging to be done for the channels. + * @{ + */ +#define XADCPS_AVG_0_SAMPLES 0 /**< No Averaging */ +#define XADCPS_AVG_16_SAMPLES 1 /**< Average 16 samples */ +#define XADCPS_AVG_64_SAMPLES 2 /**< Average 64 samples */ +#define XADCPS_AVG_256_SAMPLES 3 /**< Average 256 samples */ + +/*@}*/ + + +/** + * @name Channel Sequencer Modes of operation + * @{ + */ +#define XADCPS_SEQ_MODE_SAFE 0 /**< Default Safe Mode */ +#define XADCPS_SEQ_MODE_ONEPASS 1 /**< Onepass through Sequencer */ +#define XADCPS_SEQ_MODE_CONTINPASS 2 /**< Continuous Cycling Sequencer */ +#define XADCPS_SEQ_MODE_SINGCHAN 3 /**< Single channel -No Sequencing */ +#define XADCPS_SEQ_MODE_SIMUL_SAMPLING 4 /**< Simultaneous sampling */ +#define XADCPS_SEQ_MODE_INDEPENDENT 8 /**< Independent mode */ + +/*@}*/ + + + +/** + * @name Power Down Modes + * @{ + */ +#define XADCPS_PD_MODE_NONE 0 /**< No Power Down */ +#define XADCPS_PD_MODE_ADCB 1 /**< Power Down ADC B */ +#define XADCPS_PD_MODE_XADC 3 /**< Power Down ADC A and ADC B */ +/*@}*/ + +/**************************** Type Definitions ******************************/ + +/** + * This typedef contains configuration information for the XADC/ADC + * device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + u32 BaseAddress; /**< Device base address */ +} XAdcPs_Config; + + +/** + * The driver's instance data. The user is required to allocate a variable + * of this type for every XADC/ADC device in the system. A pointer to + * a variable of this type is then passed to the driver API functions. + */ +typedef struct { + XAdcPs_Config Config; /**< XAdcPs_Config of current device */ + u32 IsReady; /**< Device is initialized and ready */ + +} XAdcPs; + +/***************** Macros (Inline Functions) Definitions ********************/ + +/****************************************************************************/ +/** +* +* This macro checks if the XADC device is in Event Sampling mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return +* - TRUE if the device is in Event Sampling Mode. +* - FALSE if the device is in Continuous Sampling Mode. +* +* @note C-Style signature: +* int XAdcPs_IsEventSamplingMode(XAdcPs *InstancePtr); +* +*****************************************************************************/ +#define XAdcPs_IsEventSamplingModeSet(InstancePtr) \ + (((XAdcPs_ReadInternalReg(InstancePtr, \ + XADCPS_CFR0_OFFSET) & XADCPS_CFR0_EC_MASK) ? \ + TRUE : FALSE)) + + +/****************************************************************************/ +/** +* +* This macro checks if the XADC device is in External Mux mode. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return +* - TRUE if the device is in External Mux Mode. +* - FALSE if the device is NOT in External Mux Mode. +* +* @note C-Style signature: +* int XAdcPs_IsExternalMuxMode(XAdcPs *InstancePtr); +* +*****************************************************************************/ +#define XAdcPs_IsExternalMuxModeSet(InstancePtr) \ + (((XAdcPs_ReadInternalReg(InstancePtr, \ + XADCPS_CFR0_OFFSET) & XADCPS_CFR0_MUX_MASK) ? \ + TRUE : FALSE)) + +/****************************************************************************/ +/** +* +* This macro converts XADC Raw Data to Temperature(centigrades). +* +* @param AdcData is the Raw ADC Data from XADC. +* +* @return The Temperature in centigrades. +* +* @note C-Style signature: +* float XAdcPs_RawToTemperature(u32 AdcData); +* +*****************************************************************************/ +#define XAdcPs_RawToTemperature(AdcData) \ + ((((float)(AdcData)/65536.0f)/0.00198421639f) - 273.15f) + +/****************************************************************************/ +/** +* +* This macro converts XADC/ADC Raw Data to Voltage(volts). +* +* @param AdcData is the XADC/ADC Raw Data. +* +* @return The Voltage in volts. +* +* @note C-Style signature: +* float XAdcPs_RawToVoltage(u32 AdcData); +* +*****************************************************************************/ +#define XAdcPs_RawToVoltage(AdcData) \ + ((((float)(AdcData))* (3.0f))/65536.0f) + +/****************************************************************************/ +/** +* +* This macro converts Temperature in centigrades to XADC/ADC Raw Data. +* +* @param Temperature is the Temperature in centigrades to be +* converted to XADC/ADC Raw Data. +* +* @return The XADC/ADC Raw Data. +* +* @note C-Style signature: +* int XAdcPs_TemperatureToRaw(float Temperature); +* +*****************************************************************************/ +#define XAdcPs_TemperatureToRaw(Temperature) \ + ((int)(((Temperature) + 273.15f)*65536.0f*0.00198421639f)) + +/****************************************************************************/ +/** +* +* This macro converts Voltage in Volts to XADC/ADC Raw Data. +* +* @param Voltage is the Voltage in volts to be converted to +* XADC/ADC Raw Data. +* +* @return The XADC/ADC Raw Data. +* +* @note C-Style signature: +* int XAdcPs_VoltageToRaw(float Voltage); +* +*****************************************************************************/ +#define XAdcPs_VoltageToRaw(Voltage) \ + ((int)((Voltage)*65536.0f/3.0f)) + + +/****************************************************************************/ +/** +* +* This macro is used for writing to the XADC Registers using the +* command FIFO. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return None. +* +* @note C-Style signature: +* void XAdcPs_WriteFifo(XAdcPs *InstancePtr, u32 Data); +* +*****************************************************************************/ +#define XAdcPs_WriteFifo(InstancePtr, Data) \ + XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, \ + XADCPS_CMDFIFO_OFFSET, Data); + + +/****************************************************************************/ +/** +* +* This macro is used for reading from the XADC Registers using the +* data FIFO. +* +* @param InstancePtr is a pointer to the XAdcPs instance. +* +* @return Data read from the FIFO +* +* @note C-Style signature: +* u32 XAdcPs_ReadFifo(XAdcPs *InstancePtr); +* +*****************************************************************************/ +#define XAdcPs_ReadFifo(InstancePtr) \ + XAdcPs_ReadReg((InstancePtr)->Config.BaseAddress, \ + XADCPS_RDFIFO_OFFSET); + + +/************************** Function Prototypes *****************************/ + + + +/** + * Functions in xadcps_sinit.c + */ +XAdcPs_Config *XAdcPs_LookupConfig(u16 DeviceId); + +/** + * Functions in xadcps.c + */ +int XAdcPs_CfgInitialize(XAdcPs *InstancePtr, + XAdcPs_Config *ConfigPtr, + u32 EffectiveAddr); + + +u32 XAdcPs_GetStatus(XAdcPs *InstancePtr); + +u32 XAdcPs_GetAlarmOutputStatus(XAdcPs *InstancePtr); + +void XAdcPs_StartAdcConversion(XAdcPs *InstancePtr); + +void XAdcPs_Reset(XAdcPs *InstancePtr); + +u16 XAdcPs_GetAdcData(XAdcPs *InstancePtr, u8 Channel); + +u16 XAdcPs_GetCalibCoefficient(XAdcPs *InstancePtr, u8 CoeffType); + +u16 XAdcPs_GetMinMaxMeasurement(XAdcPs *InstancePtr, u8 MeasurementType); + +void XAdcPs_SetAvg(XAdcPs *InstancePtr, u8 Average); +u8 XAdcPs_GetAvg(XAdcPs *InstancePtr); + +int XAdcPs_SetSingleChParams(XAdcPs *InstancePtr, + u8 Channel, + int IncreaseAcqCycles, + int IsEventMode, + int IsDifferentialMode); + + +void XAdcPs_SetAlarmEnables(XAdcPs *InstancePtr, u16 AlmEnableMask); +u16 XAdcPs_GetAlarmEnables(XAdcPs *InstancePtr); + +void XAdcPs_SetCalibEnables(XAdcPs *InstancePtr, u16 Calibration); +u16 XAdcPs_GetCalibEnables(XAdcPs *InstancePtr); + +void XAdcPs_SetSequencerMode(XAdcPs *InstancePtr, u8 SequencerMode); +u8 XAdcPs_GetSequencerMode(XAdcPs *InstancePtr); + +void XAdcPs_SetAdcClkDivisor(XAdcPs *InstancePtr, u8 Divisor); +u8 XAdcPs_GetAdcClkDivisor(XAdcPs *InstancePtr); + +int XAdcPs_SetSeqChEnables(XAdcPs *InstancePtr, u32 ChEnableMask); +u32 XAdcPs_GetSeqChEnables(XAdcPs *InstancePtr); + +int XAdcPs_SetSeqAvgEnables(XAdcPs *InstancePtr, u32 AvgEnableChMask); +u32 XAdcPs_GetSeqAvgEnables(XAdcPs *InstancePtr); + +int XAdcPs_SetSeqInputMode(XAdcPs *InstancePtr, u32 InputModeChMask); +u32 XAdcPs_GetSeqInputMode(XAdcPs *InstancePtr); + +int XAdcPs_SetSeqAcqTime(XAdcPs *InstancePtr, u32 AcqCyclesChMask); +u32 XAdcPs_GetSeqAcqTime(XAdcPs *InstancePtr); + +void XAdcPs_SetAlarmThreshold(XAdcPs *InstancePtr, u8 AlarmThrReg, u16 Value); +u16 XAdcPs_GetAlarmThreshold(XAdcPs *InstancePtr, u8 AlarmThrReg); + +void XAdcPs_EnableUserOverTemp(XAdcPs *InstancePtr); +void XAdcPs_DisableUserOverTemp(XAdcPs *InstancePtr); + +void XAdcPs_SetSequencerEvent(XAdcPs *InstancePtr, int IsEventMode); + +int XAdcPs_GetSamplingMode(XAdcPs *InstancePtr); + +void XAdcPs_SetMuxMode(XAdcPs *InstancePtr, int MuxMode, u8 Channel); + +void XAdcPs_SetPowerdownMode(XAdcPs *InstancePtr, u32 Mode); + +u32 XAdcPs_GetPowerdownMode(XAdcPs *InstancePtr); + +/** + * Functions in xadcps_selftest.c + */ +int XAdcPs_SelfTest(XAdcPs *InstancePtr); + +/** + * Functions in xadcps_intr.c + */ +void XAdcPs_IntrEnable(XAdcPs *InstancePtr, u32 Mask); +void XAdcPs_IntrDisable(XAdcPs *InstancePtr, u32 Mask); +u32 XAdcPs_IntrGetEnabled(XAdcPs *InstancePtr); + +u32 XAdcPs_IntrGetStatus(XAdcPs *InstancePtr); +void XAdcPs_IntrClear(XAdcPs *InstancePtr, u32 Mask); + + +#ifdef __cplusplus +} +#endif + +#endif /* End of protection macro. */ +/** @} */ diff --git a/cmd/xadcps_hw.h b/cmd/xadcps_hw.h new file mode 100644 index 000000000000..17c0e3b09811 --- /dev/null +++ b/cmd/xadcps_hw.h @@ -0,0 +1,502 @@ +/****************************************************************************** +* +* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ +/****************************************************************************/ +/** +* +* @file xadcps_hw.h +* @addtogroup xadcps_v2_2 +* @{ +* +* This header file contains identifiers and basic driver functions (or +* macros) that can be used to access the XADC device through the Device +* Config Interface of the Zynq. +* +* +* Refer to the device specification for more information about this driver. +* +* @note None. +* +* +*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date     Changes
+* ----- -----  -------- -----------------------------------------------------
+* 1.00a bss    12/22/11 First release based on the XPS/AXI xadc driver
+* 1.03a bss    11/01/13 Modified macros to use correct Register offsets
+*			CR#749687
+*
+* 
+* +*****************************************************************************/ +#ifndef XADCPS_HW_H /* Prevent circular inclusions */ +#define XADCPS_HW_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +//#include "xil_types.h" +//#include "xil_assert.h" +//#include "xil_io.h" + +/************************** Constant Definitions ****************************/ + + +/**@name Register offsets of XADC in the Device Config + * + * The following constants provide access to each of the registers of the + * XADC device. + * @{ + */ + +#define XADCPS_CFG_OFFSET 0x00 /**< Configuration Register */ +#define XADCPS_INT_STS_OFFSET 0x04 /**< Interrupt Status Register */ +#define XADCPS_INT_MASK_OFFSET 0x08 /**< Interrupt Mask Register */ +#define XADCPS_MSTS_OFFSET 0x0C /**< Misc status register */ +#define XADCPS_CMDFIFO_OFFSET 0x10 /**< Command FIFO Register */ +#define XADCPS_RDFIFO_OFFSET 0x14 /**< Read FIFO Register */ +#define XADCPS_MCTL_OFFSET 0x18 /**< Misc control register */ + +/* @} */ + + + + + +/** @name XADC Config Register Bit definitions + * @{ + */ +#define XADCPS_CFG_ENABLE_MASK 0x80000000 /**< Enable access from PS mask */ +#define XADCPS_CFG_CFIFOTH_MASK 0x00F00000 /**< Command FIFO Threshold mask */ +#define XADCPS_CFG_DFIFOTH_MASK 0x000F0000 /**< Data FIFO Threshold mask */ +#define XADCPS_CFG_WEDGE_MASK 0x00002000 /**< Write Edge Mask */ +#define XADCPS_CFG_REDGE_MASK 0x00001000 /**< Read Edge Mask */ +#define XADCPS_CFG_TCKRATE_MASK 0x00000300 /**< Clock freq control */ +#define XADCPS_CFG_IGAP_MASK 0x0000001F /**< Idle Gap between + * successive commands */ +/* @} */ + + +/** @name XADC Interrupt Status/Mask Register Bit definitions + * + * The definitions are same for the Interrupt Status Register and + * Interrupt Mask Register. They are defined only once. + * @{ + */ +#define XADCPS_INTX_ALL_MASK 0x000003FF /**< Alarm Signals Mask */ +#define XADCPS_INTX_CFIFO_LTH_MASK 0x00000200 /**< CMD FIFO less than threshold */ +#define XADCPS_INTX_DFIFO_GTH_MASK 0x00000100 /**< Data FIFO greater than threshold */ +#define XADCPS_INTX_OT_MASK 0x00000080 /**< Over temperature Alarm Status */ +#define XADCPS_INTX_ALM_ALL_MASK 0x0000007F /**< Alarm Signals Mask */ +#define XADCPS_INTX_ALM6_MASK 0x00000040 /**< Alarm 6 Mask */ +#define XADCPS_INTX_ALM5_MASK 0x00000020 /**< Alarm 5 Mask */ +#define XADCPS_INTX_ALM4_MASK 0x00000010 /**< Alarm 4 Mask */ +#define XADCPS_INTX_ALM3_MASK 0x00000008 /**< Alarm 3 Mask */ +#define XADCPS_INTX_ALM2_MASK 0x00000004 /**< Alarm 2 Mask */ +#define XADCPS_INTX_ALM1_MASK 0x00000002 /**< Alarm 1 Mask */ +#define XADCPS_INTX_ALM0_MASK 0x00000001 /**< Alarm 0 Mask */ + +/* @} */ + + +/** @name XADC Miscellaneous Register Bit definitions + * @{ + */ +#define XADCPS_MSTS_CFIFO_LVL_MASK 0x000F0000 /**< Command FIFO Level mask */ +#define XADCPS_MSTS_DFIFO_LVL_MASK 0x0000F000 /**< Data FIFO Level Mask */ +#define XADCPS_MSTS_CFIFOF_MASK 0x00000800 /**< Command FIFO Full Mask */ +#define XADCPS_MSTS_CFIFOE_MASK 0x00000400 /**< Command FIFO Empty Mask */ +#define XADCPS_MSTS_DFIFOF_MASK 0x00000200 /**< Data FIFO Full Mask */ +#define XADCPS_MSTS_DFIFOE_MASK 0x00000100 /**< Data FIFO Empty Mask */ +#define XADCPS_MSTS_OT_MASK 0x00000080 /**< Over Temperature Mask */ +#define XADCPS_MSTS_ALM_MASK 0x0000007F /**< Alarms Mask */ +/* @} */ + + +/** @name XADC Miscellaneous Control Register Bit definitions + * @{ + */ +#define XADCPS_MCTL_RESET_MASK 0x00000010 /**< Reset XADC */ +#define XADCPS_MCTL_FLUSH_MASK 0x00000001 /**< Flush the FIFOs */ +/* @} */ + + +/**@name Internal Register offsets of the XADC + * + * The following constants provide access to each of the internal registers of + * the XADC device. + * @{ + */ + +/* + * XADC Internal Channel Registers + */ +#define XADCPS_TEMP_OFFSET 0x00 /**< On-chip Temperature Reg */ +#define XADCPS_VCCINT_OFFSET 0x01 /**< On-chip VCCINT Data Reg */ +#define XADCPS_VCCAUX_OFFSET 0x02 /**< On-chip VCCAUX Data Reg */ +#define XADCPS_VPVN_OFFSET 0x03 /**< ADC out of VP/VN */ +#define XADCPS_VREFP_OFFSET 0x04 /**< On-chip VREFP Data Reg */ +#define XADCPS_VREFN_OFFSET 0x05 /**< On-chip VREFN Data Reg */ +#define XADCPS_VBRAM_OFFSET 0x06 /**< On-chip VBRAM , 7 Series */ +#define XADCPS_ADC_A_SUPPLY_CALIB_OFFSET 0x08 /**< ADC A Supply Offset Reg */ +#define XADCPS_ADC_A_OFFSET_CALIB_OFFSET 0x09 /**< ADC A Offset Data Reg */ +#define XADCPS_ADC_A_GAINERR_CALIB_OFFSET 0x0A /**< ADC A Gain Error Reg */ +#define XADCPS_VCCPINT_OFFSET 0x0D /**< On-chip VCCPINT Reg, Zynq */ +#define XADCPS_VCCPAUX_OFFSET 0x0E /**< On-chip VCCPAUX Reg, Zynq */ +#define XADCPS_VCCPDRO_OFFSET 0x0F /**< On-chip VCCPDRO Reg, Zynq */ + +/* + * XADC External Channel Registers + */ +#define XADCPS_AUX00_OFFSET 0x10 /**< ADC out of VAUXP0/VAUXN0 */ +#define XADCPS_AUX01_OFFSET 0x11 /**< ADC out of VAUXP1/VAUXN1 */ +#define XADCPS_AUX02_OFFSET 0x12 /**< ADC out of VAUXP2/VAUXN2 */ +#define XADCPS_AUX03_OFFSET 0x13 /**< ADC out of VAUXP3/VAUXN3 */ +#define XADCPS_AUX04_OFFSET 0x14 /**< ADC out of VAUXP4/VAUXN4 */ +#define XADCPS_AUX05_OFFSET 0x15 /**< ADC out of VAUXP5/VAUXN5 */ +#define XADCPS_AUX06_OFFSET 0x16 /**< ADC out of VAUXP6/VAUXN6 */ +#define XADCPS_AUX07_OFFSET 0x17 /**< ADC out of VAUXP7/VAUXN7 */ +#define XADCPS_AUX08_OFFSET 0x18 /**< ADC out of VAUXP8/VAUXN8 */ +#define XADCPS_AUX09_OFFSET 0x19 /**< ADC out of VAUXP9/VAUXN9 */ +#define XADCPS_AUX10_OFFSET 0x1A /**< ADC out of VAUXP10/VAUXN10 */ +#define XADCPS_AUX11_OFFSET 0x1B /**< ADC out of VAUXP11/VAUXN11 */ +#define XADCPS_AUX12_OFFSET 0x1C /**< ADC out of VAUXP12/VAUXN12 */ +#define XADCPS_AUX13_OFFSET 0x1D /**< ADC out of VAUXP13/VAUXN13 */ +#define XADCPS_AUX14_OFFSET 0x1E /**< ADC out of VAUXP14/VAUXN14 */ +#define XADCPS_AUX15_OFFSET 0x1F /**< ADC out of VAUXP15/VAUXN15 */ + +/* + * XADC Registers for Maximum/Minimum data captured for the + * on chip Temperature/VCCINT/VCCAUX data. + */ +#define XADCPS_MAX_TEMP_OFFSET 0x20 /**< Max Temperature Reg */ +#define XADCPS_MAX_VCCINT_OFFSET 0x21 /**< Max VCCINT Register */ +#define XADCPS_MAX_VCCAUX_OFFSET 0x22 /**< Max VCCAUX Register */ +#define XADCPS_MAX_VCCBRAM_OFFSET 0x23 /**< Max BRAM Register, 7 series */ +#define XADCPS_MIN_TEMP_OFFSET 0x24 /**< Min Temperature Reg */ +#define XADCPS_MIN_VCCINT_OFFSET 0x25 /**< Min VCCINT Register */ +#define XADCPS_MIN_VCCAUX_OFFSET 0x26 /**< Min VCCAUX Register */ +#define XADCPS_MIN_VCCBRAM_OFFSET 0x27 /**< Min BRAM Register, 7 series */ +#define XADCPS_MAX_VCCPINT_OFFSET 0x28 /**< Max VCCPINT Register, Zynq */ +#define XADCPS_MAX_VCCPAUX_OFFSET 0x29 /**< Max VCCPAUX Register, Zynq */ +#define XADCPS_MAX_VCCPDRO_OFFSET 0x2A /**< Max VCCPDRO Register, Zynq */ +#define XADCPS_MIN_VCCPINT_OFFSET 0x2C /**< Min VCCPINT Register, Zynq */ +#define XADCPS_MIN_VCCPAUX_OFFSET 0x2D /**< Min VCCPAUX Register, Zynq */ +#define XADCPS_MIN_VCCPDRO_OFFSET 0x2E /**< Min VCCPDRO Register,Zynq */ + /* Undefined 0x2F to 0x3E */ +#define XADCPS_FLAG_OFFSET 0x3F /**< Flag Register */ + +/* + * XADC Configuration Registers + */ +#define XADCPS_CFR0_OFFSET 0x40 /**< Configuration Register 0 */ +#define XADCPS_CFR1_OFFSET 0x41 /**< Configuration Register 1 */ +#define XADCPS_CFR2_OFFSET 0x42 /**< Configuration Register 2 */ + +/* Test Registers 0x43 to 0x47 */ + +/* + * XADC Sequence Registers + */ +#define XADCPS_SEQ00_OFFSET 0x48 /**< Seq Reg 00 Adc Channel Selection */ +#define XADCPS_SEQ01_OFFSET 0x49 /**< Seq Reg 01 Adc Channel Selection */ +#define XADCPS_SEQ02_OFFSET 0x4A /**< Seq Reg 02 Adc Average Enable */ +#define XADCPS_SEQ03_OFFSET 0x4B /**< Seq Reg 03 Adc Average Enable */ +#define XADCPS_SEQ04_OFFSET 0x4C /**< Seq Reg 04 Adc Input Mode Select */ +#define XADCPS_SEQ05_OFFSET 0x4D /**< Seq Reg 05 Adc Input Mode Select */ +#define XADCPS_SEQ06_OFFSET 0x4E /**< Seq Reg 06 Adc Acquisition Select */ +#define XADCPS_SEQ07_OFFSET 0x4F /**< Seq Reg 07 Adc Acquisition Select */ + +/* + * XADC Alarm Threshold/Limit Registers (ATR) + */ +#define XADCPS_ATR_TEMP_UPPER_OFFSET 0x50 /**< Temp Upper Alarm Register */ +#define XADCPS_ATR_VCCINT_UPPER_OFFSET 0x51 /**< VCCINT Upper Alarm Reg */ +#define XADCPS_ATR_VCCAUX_UPPER_OFFSET 0x52 /**< VCCAUX Upper Alarm Reg */ +#define XADCPS_ATR_OT_UPPER_OFFSET 0x53 /**< Over Temp Upper Alarm Reg */ +#define XADCPS_ATR_TEMP_LOWER_OFFSET 0x54 /**< Temp Lower Alarm Register */ +#define XADCPS_ATR_VCCINT_LOWER_OFFSET 0x55 /**< VCCINT Lower Alarm Reg */ +#define XADCPS_ATR_VCCAUX_LOWER_OFFSET 0x56 /**< VCCAUX Lower Alarm Reg */ +#define XADCPS_ATR_OT_LOWER_OFFSET 0x57 /**< Over Temp Lower Alarm Reg */ +#define XADCPS_ATR_VBRAM_UPPER_OFFSET 0x58 /**< VBRAM Upper Alarm, 7 series */ +#define XADCPS_ATR_VCCPINT_UPPER_OFFSET 0x59 /**< VCCPINT Upper Alarm, Zynq */ +#define XADCPS_ATR_VCCPAUX_UPPER_OFFSET 0x5A /**< VCCPAUX Upper Alarm, Zynq */ +#define XADCPS_ATR_VCCPDRO_UPPER_OFFSET 0x5B /**< VCCPDRO Upper Alarm, Zynq */ +#define XADCPS_ATR_VBRAM_LOWER_OFFSET 0x5C /**< VRBAM Lower Alarm, 7 Series */ +#define XADCPS_ATR_VCCPINT_LOWER_OFFSET 0x5D /**< VCCPINT Lower Alarm, Zynq */ +#define XADCPS_ATR_VCCPAUX_LOWER_OFFSET 0x5E /**< VCCPAUX Lower Alarm, Zynq */ +#define XADCPS_ATR_VCCPDRO_LOWER_OFFSET 0x5F /**< VCCPDRO Lower Alarm, Zynq */ + +/* Undefined 0x60 to 0x7F */ + +/*@}*/ + + + +/** + * @name Configuration Register 0 (CFR0) mask(s) + * @{ + */ +#define XADCPS_CFR0_CAL_AVG_MASK 0x8000 /**< Averaging enable Mask */ +#define XADCPS_CFR0_AVG_VALID_MASK 0x3000 /**< Averaging bit Mask */ +#define XADCPS_CFR0_AVG1_MASK 0x0000 /**< No Averaging */ +#define XADCPS_CFR0_AVG16_MASK 0x1000 /**< Average 16 samples */ +#define XADCPS_CFR0_AVG64_MASK 0x2000 /**< Average 64 samples */ +#define XADCPS_CFR0_AVG256_MASK 0x3000 /**< Average 256 samples */ +#define XADCPS_CFR0_AVG_SHIFT 12 /**< Averaging bits shift */ +#define XADCPS_CFR0_MUX_MASK 0x0800 /**< External Mask Enable */ +#define XADCPS_CFR0_DU_MASK 0x0400 /**< Bipolar/Unipolar mode */ +#define XADCPS_CFR0_EC_MASK 0x0200 /**< Event driven/ + * Continuous mode selection + */ +#define XADCPS_CFR0_ACQ_MASK 0x0100 /**< Add acquisition by 6 ADCCLK */ +#define XADCPS_CFR0_CHANNEL_MASK 0x001F /**< Channel number bit Mask */ + +/*@}*/ + +/** + * @name Configuration Register 1 (CFR1) mask(s) + * @{ + */ +#define XADCPS_CFR1_SEQ_VALID_MASK 0xF000 /**< Sequence bit Mask */ +#define XADCPS_CFR1_SEQ_SAFEMODE_MASK 0x0000 /**< Default Safe Mode */ +#define XADCPS_CFR1_SEQ_ONEPASS_MASK 0x1000 /**< Onepass through Seq */ +#define XADCPS_CFR1_SEQ_CONTINPASS_MASK 0x2000 /**< Continuous Cycling Seq */ +#define XADCPS_CFR1_SEQ_SINGCHAN_MASK 0x3000 /**< Single channel - No Seq */ +#define XADCPS_CFR1_SEQ_SIMUL_SAMPLING_MASK 0x4000 /**< Simulataneous Sampling Mask */ +#define XADCPS_CFR1_SEQ_INDEPENDENT_MASK 0x8000 /**< Independent Mode */ +#define XADCPS_CFR1_SEQ_SHIFT 12 /**< Sequence bit shift */ +#define XADCPS_CFR1_ALM_VCCPDRO_MASK 0x0800 /**< Alm 6 - VCCPDRO, Zynq */ +#define XADCPS_CFR1_ALM_VCCPAUX_MASK 0x0400 /**< Alm 5 - VCCPAUX, Zynq */ +#define XADCPS_CFR1_ALM_VCCPINT_MASK 0x0200 /**< Alm 4 - VCCPINT, Zynq */ +#define XADCPS_CFR1_ALM_VBRAM_MASK 0x0100 /**< Alm 3 - VBRAM, 7 series */ +#define XADCPS_CFR1_CAL_VALID_MASK 0x00F0 /**< Valid Calibration Mask */ +#define XADCPS_CFR1_CAL_PS_GAIN_OFFSET_MASK 0x0080 /**< Calibration 3 -Power + Supply Gain/Offset + Enable */ +#define XADCPS_CFR1_CAL_PS_OFFSET_MASK 0x0040 /**< Calibration 2 -Power + Supply Offset Enable */ +#define XADCPS_CFR1_CAL_ADC_GAIN_OFFSET_MASK 0x0020 /**< Calibration 1 -ADC Gain + Offset Enable */ +#define XADCPS_CFR1_CAL_ADC_OFFSET_MASK 0x0010 /**< Calibration 0 -ADC Offset + Enable */ +#define XADCPS_CFR1_CAL_DISABLE_MASK 0x0000 /**< No Calibration */ +#define XADCPS_CFR1_ALM_ALL_MASK 0x0F0F /**< Mask for all alarms */ +#define XADCPS_CFR1_ALM_VCCAUX_MASK 0x0008 /**< Alarm 2 - VCCAUX Enable */ +#define XADCPS_CFR1_ALM_VCCINT_MASK 0x0004 /**< Alarm 1 - VCCINT Enable */ +#define XADCPS_CFR1_ALM_TEMP_MASK 0x0002 /**< Alarm 0 - Temperature */ +#define XADCPS_CFR1_OT_MASK 0x0001 /**< Over Temperature Enable */ + +/*@}*/ + +/** + * @name Configuration Register 2 (CFR2) mask(s) + * @{ + */ +#define XADCPS_CFR2_CD_VALID_MASK 0xFF00 /**= desc_xilinx->size) return 0; - /* datasize is smaller, must be partial data */ - return 1; + /* + * Compressed bitstreams are smaller than the FPGA size but are + * still full bitstreams. The size check alone is unreliable, + * so always treat as full to ensure ps7_post_config runs. + */ + return 0; } int fpga_loadbitstream(int devnum, char *fpgadata, size_t size, diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 40d88365bded..a24123eb1838 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -1425,6 +1425,17 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) if (status_old < 0) return status_old; +#ifdef CONFIG_SPI_FLASH_LOCK_ADI + /* PlutoSDR/M2K/SidekiqZ2: protect bottom 1MB of flash */ + if (ofs == 0 && len == SZ_1M) { + status_new = status_old & ~(SR_BP3 | SR_BP2 | SR_BP1 | SR_BP0 | SR_TB); + status_new |= SR_BP2 | SR_BP0 | SR_TB; + write_enable(nor); + write_sr(nor, status_new); + return 0; + } +#endif + /* If nothing in our range is unlocked, we don't need to do anything */ if (stm_is_locked_sr(nor, ofs, len, status_old)) return 0; @@ -1505,6 +1516,16 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) if (status_old < 0) return status_old; +#ifdef CONFIG_CMD_ADI_HWREF + /* PlutoSDR/M2K/SidekiqZ2: unprotect bottom 1MB of flash */ + if (ofs == 0 && len == SZ_1M) { + status_new = status_old & ~(SR_BP3 | SR_BP2 | SR_BP1 | SR_BP0 | SR_TB); + write_enable(nor); + write_sr(nor, status_new); + return 0; + } +#endif + /* If nothing in our range is locked, we don't need to do anything */ if (stm_is_unlocked_sr(nor, ofs, len, status_old)) return 0; @@ -6437,7 +6458,7 @@ int spi_nor_scan(struct spi_nor *nor) } #endif -#if defined(CONFIG_SPI_FLASH_STMICRO) +#if defined(CONFIG_SPI_FLASH_STMICRO) && !defined(CONFIG_SPI_FLASH_LOCK_ADI) if (JEDEC_MFR(info) == SNOR_MFR_ST || JEDEC_MFR(info) == SNOR_MFR_MICRON) { nor->flash_lock = micron_flash_lock; nor->flash_unlock = micron_flash_unlock; diff --git a/include/configs/adi_zynqmp_adrv9009_zu11eg.h b/include/configs/adi_zynqmp_adrv9009_zu11eg.h new file mode 100644 index 000000000000..61b6f3e2d019 --- /dev/null +++ b/include/configs/adi_zynqmp_adrv9009_zu11eg.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2019-2026 Analog Devices Inc. + * + * Configuration for the ADI ADRV9009-ZU11EG board + */ + +#ifndef __CONFIG_ADI_ZYNQMP_ADRV9009_ZU11EG_H +#define __CONFIG_ADI_ZYNQMP_ADRV9009_ZU11EG_H + +/* Initial environment variables */ +#define CFG_EXTRA_ENV_SETTINGS \ + "kernel_addr=0x80000\0" \ + "initrd_addr=0xa00000\0" \ + "initrd_size=0x2000000\0" \ + "fdt_addr=4000000\0" \ + "fdt_high=0x10000000\0" \ + "loadbootenv_addr=0x100000\0" \ + "sdbootdev=0\0" \ + "kernel_offset=0x280000\0" \ + "fdt_offset=0x200000\0" \ + "kernel_size=0x1e00000\0" \ + "fdt_size=0x80000\0" \ + "bootenv=uEnv.txt\0" \ + "loadbootenv=load mmc $sdbootdev:$partid ${loadbootenv_addr} ${bootenv}\0" \ + "importbootenv=echo Importing environment from SD ...; " \ + "env import -t ${loadbootenv_addr} $filesize\0" \ + "sd_uEnvtxt_existence_test=test -e mmc $sdbootdev:$partid /uEnv.txt\0" \ + "netboot=tftpboot 10000000 image.ub && bootm\0" \ + "qspiboot=sf probe 0 0 0 && sf read $fdt_addr $fdt_offset $fdt_size && " \ + "sf read $kernel_addr $kernel_offset $kernel_size && " \ + "booti $kernel_addr - $fdt_addr\0" \ + "uenvboot=" \ + "if run sd_uEnvtxt_existence_test; then " \ + "run loadbootenv; " \ + "echo Loaded environment from ${bootenv}; " \ + "run importbootenv; " \ + "fi; " \ + "if test -n $uenvcmd; then " \ + "echo Running uenvcmd ...; " \ + "run uenvcmd; " \ + "fi\0" \ + "sdboot=mmc dev $sdbootdev && mmcinfo && run uenvboot; " \ + "load mmc $sdbootdev:$partid $fdt_addr system.dtb && " \ + "load mmc $sdbootdev:$partid $kernel_addr Image && " \ + "booti $kernel_addr - $fdt_addr\0" \ + "jtagboot=tftpboot 80000 Image && tftpboot $fdt_addr system.dtb && " \ + "tftpboot 6000000 rootfs.cpio.ub && booti 80000 6000000 $fdt_addr\0" \ + "usbhostboot=usb start && load usb 0 $fdt_addr system.dtb && " \ + "load usb 0 $kernel_addr Image && " \ + "booti $kernel_addr - $fdt_addr\0" + +#include + +#endif /* __CONFIG_ADI_ZYNQMP_ADRV9009_ZU11EG_H */ diff --git a/include/configs/zynq_adrv936x.h b/include/configs/zynq_adrv936x.h new file mode 100644 index 000000000000..6e1e9f8edbcd --- /dev/null +++ b/include/configs/zynq_adrv936x.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2015-2026 Analog Devices Inc. + * + * Configuration for the Analog Devices ADRV9361/ADRV9364 boards + */ + +#ifndef __CONFIG_ZYNQ_ADRV936X_H +#define __CONFIG_ZYNQ_ADRV936X_H + +#define DFU_ALT_INFO_RAM \ + "dfu_ram_info=" \ + "setenv dfu_alt_info " \ + "dummy.dfu ram 0 0\\\\;" \ + "firmware.dfu ram ${fit_load_address} 0x1E00000\0" \ + "dfu_ram=echo Entering DFU RAM mode ... && run dfu_ram_info && dfu 0 ram 0\0" \ + "thor_ram=run dfu_ram_info && thordown 0 ram 0\0" + +#define DFU_ALT_INFO_SF \ + "dfu_sf_info=" \ + "setenv dfu_alt_info " \ + "boot.dfu raw 0x0 0xE0000\\\\;" \ + "firmware.dfu raw 0x100000 0x500000\\\\;" \ + "uboot-env.dfu raw 0xE0000 0x20000\0" \ + "dfu_sf=echo Entering DFU SF mode ... && run dfu_sf_info && dfu 0 sf 0:0:50000000:0\0" + +#define CFG_EXTRA_ENV_SETTINGS \ + "modeboot=sdboot\0" \ + "kernel_image=uImage\0" \ + "fit_load_address=0x2080000\0" \ + "fit_config=config@0\0" \ + "ramdisk_image=uramdisk.image.gz\0" \ + "ramdisk_load_address=0x4000000\0" \ + "devicetree_image=devicetree.dtb\0" \ + "devicetree_load_address=0x2000000\0" \ + "bitstream_image=system.bit.bin\0" \ + "boot_image=BOOT.bin\0" \ + "loadbit_addr=0x100000\0" \ + "loadbootenv_addr=0x2000000\0" \ + "fit_size=0x500000\0" \ + "devicetree_size=0x20000\0" \ + "ramdisk_size=0x400000\0" \ + "bitstream_size=0x400000\0" \ + "boot_size=0xF00000\0" \ + "fdt_high=0x20000000\0" \ + "initrd_high=0x20000000\0" \ + "bootenv=uEnv.txt\0" \ + "loadbootenv=load mmc 0 ${loadbootenv_addr} ${bootenv}\0" \ + "importbootenv=echo Importing environment from SD ...; " \ + "env import -t ${loadbootenv_addr} $filesize\0" \ + "sd_uEnvtxt_existence_test=test -e mmc 0 /uEnv.txt\0" \ + "uenvboot=" \ + "if run sd_uEnvtxt_existence_test; then " \ + "run loadbootenv; " \ + "echo Loaded environment from ${bootenv}; " \ + "run importbootenv; " \ + "fi; " \ + "if test -n $uenvcmd; then " \ + "echo Running uenvcmd ...; " \ + "run uenvcmd; " \ + "fi\0" \ + "sdboot=echo Booting from SD ... && " \ + "run uenvboot; " \ + "load mmc 0 ${fit_load_address} ${kernel_image} && " \ + "load mmc 0 ${devicetree_load_address} ${devicetree_image} && " \ + "load mmc 0 ${ramdisk_load_address} ${ramdisk_image} && " \ + "bootm ${fit_load_address} ${ramdisk_load_address} ${devicetree_load_address}\0" \ + "qspiboot=echo Copying Linux from QSPI flash to RAM... && " \ + "sf probe 0 && " \ + "sf read ${fit_load_address} 0x100000 ${fit_size} && " \ + "bootm ${fit_load_address}\0" \ + "usbboot=if usb start; then " \ + "run uenvboot; " \ + "echo Copying Linux from USB to RAM... && " \ + "load usb 0 ${fit_load_address} ${kernel_image} && " \ + "load usb 0 ${devicetree_load_address} ${devicetree_image} && " \ + "load usb 0 ${ramdisk_load_address} ${ramdisk_image} && " \ + "bootm ${fit_load_address} ${ramdisk_load_address} ${devicetree_load_address}; " \ + "fi\0" \ + DFU_ALT_INFO_RAM \ + DFU_ALT_INFO_SF + +#include + +#endif /* __CONFIG_ZYNQ_ADRV936X_H */ diff --git a/include/configs/zynq_coraz7.h b/include/configs/zynq_coraz7.h new file mode 100644 index 000000000000..d4e8407bd48d --- /dev/null +++ b/include/configs/zynq_coraz7.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2016 Digilent Inc. + * + * Configuration for Zynq Development Board - Cora Z7 + */ + +#ifndef __CONFIG_ZYNQ_CORAZ7_H +#define __CONFIG_ZYNQ_CORAZ7_H + +#include + +#endif /* __CONFIG_ZYNQ_CORAZ7_H */ diff --git a/include/configs/zynq_m2k.h b/include/configs/zynq_m2k.h new file mode 100644 index 000000000000..a66eb8544756 --- /dev/null +++ b/include/configs/zynq_m2k.h @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2018-2025 Analog Devices Inc. + * + * Configuration for the Analog Devices ADALM2000 (M2K) board + */ + +#ifndef __CONFIG_ZYNQ_M2K_H +#define __CONFIG_ZYNQ_M2K_H + +#define DFU_ALT_INFO_RAM \ + "dfu_ram_info=" \ + "setenv dfu_alt_info " \ + "dummy.dfu ram 0 0\\\\;" \ + "firmware.dfu ram ${fit_load_address} 0x1E00000\0" \ + "dfu_ram=echo Entering DFU RAM mode ... && run dfu_ram_info && dfu 0 ram 0\0" \ + "thor_ram=run dfu_ram_info && thordown 0 ram 0\0" + +#define DFU_ALT_INFO_SF \ + "dfu_sf_info=" \ + "setenv dfu_alt_info " \ + "boot.dfu raw 0x0 0x100000\\\\;" \ + "firmware.dfu raw 0x200000 0x1E00000\\\\;" \ + "uboot-extra-env.dfu raw 0xFF000 0x1000\\\\;" \ + "uboot-env.dfu raw 0x100000 0x20000\\\\;" \ + "spare.dfu raw 0x120000 0xE0000\0" \ + "dfu_sf=gpio set 15;setenv silent;echo Entering DFU SF mode ... && run dfu_sf_info && dfu 0 sf 0:0:40000000:0 && if test -n ${dfu_alt_num} && test ${dfu_alt_num} = 1; " \ + "then setenv fit_size ${filesize} && setenv dfu_alt_num && env save; fi;gpio clear 15;\0" + +#define M2K_ENV_VERSION "2" + +#define CFG_EXTRA_ENV_SETTINGS \ + "env_version=" M2K_ENV_VERSION "\0" \ + "modeboot=qspiboot\0" \ + "ethaddr=00:0a:35:00:01:22\0" \ + "ipaddr=192.168.2.1\0" \ + "ipaddr_host=192.168.2.10\0" \ + "netmask=255.255.255.0\0" \ + "kernel_image=uImage\0" \ + "fit_load_address=0x2080000\0" \ + "fit_config=config@0\0" \ + "extraenv_load_address=0x207E000\0" \ + "ramdisk_image=uramdisk.image.gz\0" \ + "ramdisk_load_address=0x4000000\0" \ + "devicetree_image=devicetree.dtb\0" \ + "devicetree_load_address=0x2000000\0" \ + "bitstream_image=system.bit.bin\0" \ + "boot_image=BOOT.bin\0" \ + "loadbit_addr=0x100000\0" \ + "loadbootenv_addr=0x2000000\0" \ + "fit_size=0x900000\0" \ + "devicetree_size=0x20000\0" \ + "ramdisk_size=0x400000\0" \ + "bitstream_size=0x400000\0" \ + "boot_size=0xF00000\0" \ + "fdt_high=0x20000000\0" \ + "initrd_high=0x20000000\0" \ + "bootenv=uEnv.txt\0" \ + "maxcpus=1\0" \ + "clear_reset_cause=mw f8000008 df0d && mw f8000258 00400000 && mw f8000004 767b\0" \ + "adi_loadvals=fdt addr ${fit_load_address} && fdt get value fdt_choosen /configurations/${fit_config}/ fdt && " \ + "fdt get addr fdtaddr /images/${fdt_choosen} data && fdt addr ${fdtaddr}\0" \ + "qspiboot_extraenv=sf read ${extraenv_load_address} 0xFF000 0x1000 && " \ + "env import -c ${extraenv_load_address} 0x1000 || true \0" \ + "read_sf=sf probe && run qspiboot_extraenv && " \ + "sf read ${fit_load_address} 0x200000 ${fit_size} && " \ + "iminfo ${fit_load_address} || " \ + "sf read ${fit_load_address} 0x200000 0x1E00000; \0" \ + "ramboot_verbose=adi_hwref;echo Copying Linux from DFU to RAM... && " \ + "run dfu_ram;" \ + "if run adi_loadvals; then " \ + "echo Loaded model into devicetree; " \ + "fi; " \ + "envversion;setenv bootargs console=ttyPS0,115200 maxcpus=${maxcpus} rootfstype=ramfs root=/dev/ram0 rw earlyprintk clk_ignore_unused uboot=\"${uboot-version}\" && " \ + "bootm ${fit_load_address}#${fit_config}\0" \ + "qspiboot_verbose=adi_hwref;echo Copying Linux from QSPI flash to RAM... && " \ + "run read_sf && " \ + "if run adi_loadvals; then " \ + "echo Loaded model into devicetree; " \ + "fi; " \ + "envversion;setenv bootargs console=ttyPS0,115200 maxcpus=${maxcpus} rootfstype=ramfs root=/dev/ram0 rw earlyprintk clk_ignore_unused uboot=\"${uboot-version}\" && " \ + "bootm ${fit_load_address}#${fit_config} || echo BOOT failed entering DFU mode ... && run dfu_sf \0" \ + "qspiboot=setenv silent 1;adi_hwref;gpio input 14 && setenv silent && sf probe && sf protect lock 0 100000 && run dfu_sf; " \ + "setenv silent;" \ + "itest *f8000258 == 480003 && run clear_reset_cause && run dfu_sf; " \ + "itest *f8000258 == 480007 && run clear_reset_cause && run ramboot_verbose; " \ + "itest *f8000258 == 480006 && run clear_reset_cause && run qspiboot_verbose; " \ + "itest *f8000258 == 480002 && run clear_reset_cause && exit; " \ + "echo Booting silently && setenv silent 1; " \ + "run read_sf && run adi_loadvals; " \ + "envversion;setenv bootargs console=ttyPS0,115200 maxcpus=${maxcpus} rootfstype=ramfs root=/dev/ram0 rw quiet loglevel=4 clk_ignore_unused uboot=\"${uboot-version}\" && " \ + "bootm ${fit_load_address}#${fit_config} || setenv silent;echo BOOT failed entering DFU mode ... && sf protect lock 0 100000 && run dfu_sf \0" \ + "jtagboot=env default -a;sf probe && sf protect unlock 0 100000 && run dfu_sf; \0" \ + "uenvboot=" \ + "if run loadbootenv; then " \ + "echo Loaded environment from ${bootenv}; " \ + "run importbootenv; " \ + "fi; " \ + "if test -n $uenvcmd; then " \ + "echo Running uenvcmd ...; " \ + "run uenvcmd; " \ + "fi\0" \ + "usbboot=if usb start; then " \ + "run uenvboot; " \ + "echo Copying Linux from USB to RAM... && " \ + "load usb 0 ${fit_load_address} ${kernel_image} && " \ + "load usb 0 ${devicetree_load_address} ${devicetree_image} && " \ + "load usb 0 ${ramdisk_load_address} ${ramdisk_image} && " \ + "bootm ${fit_load_address} ${ramdisk_load_address} ${devicetree_load_address}; " \ + "fi\0" \ + DFU_ALT_INFO_RAM \ + DFU_ALT_INFO_SF + +#include + +#endif /* __CONFIG_ZYNQ_M2K_H */ diff --git a/include/configs/zynq_pluto_sdr.h b/include/configs/zynq_pluto_sdr.h new file mode 100644 index 000000000000..9a39b02938e7 --- /dev/null +++ b/include/configs/zynq_pluto_sdr.h @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2015-2026 Analog Devices Inc. + * + * Configuration for the Analog Devices PlutoSDR and M2K boards + */ + +#ifndef __CONFIG_ZYNQ_PLUTO_SDR_H +#define __CONFIG_ZYNQ_PLUTO_SDR_H + +#define DFU_ALT_INFO_RAM \ + "dfu_ram_info=" \ + "setenv dfu_alt_info " \ + "dummy.dfu ram 0 0\\\\;" \ + "firmware.dfu ram ${fit_load_address} 0x1E00000\0" \ + "dfu_ram=echo Entering DFU RAM mode ... && run dfu_ram_info && dfu 0 ram 0\0" \ + "thor_ram=run dfu_ram_info && thordown 0 ram 0\0" + +#define DFU_ALT_INFO_SF \ + "dfu_sf_info=" \ + "setenv dfu_alt_info " \ + "boot.dfu raw 0x0 0x100000\\\\;" \ + "firmware.dfu raw 0x200000 0x1E00000\\\\;" \ + "uboot-extra-env.dfu raw 0xFF000 0x1000\\\\;" \ + "uboot-env.dfu raw 0x100000 0x20000\\\\;" \ + "spare.dfu raw 0x120000 0xE0000\0" \ + "dfu_sf=gpio set 15;setenv silent;echo Entering DFU SF mode ... && run dfu_sf_info && dfu 0 sf 0:0:40000000:0 && if test -n ${dfu_alt_num} && test ${dfu_alt_num} = 1; " \ + "then setenv fit_size ${filesize} && setenv dfu_alt_num && env save; fi;gpio clear 15;\0" + +/* + * Env version: increment when boot scripts change in incompatible ways. + * On boot, if saved env_version != this, reset to defaults but preserve + * user-customizable variables via the extraenv area at 0xFF000. + */ +#define PLUTO_ENV_VERSION "2" + +#define CFG_EXTRA_ENV_SETTINGS \ + "env_version=" PLUTO_ENV_VERSION "\0" \ + "modeboot=qspiboot\0" \ + "ethaddr=00:0a:35:00:01:22\0" \ + "ipaddr=192.168.2.1\0" \ + "ipaddr_host=192.168.2.10\0" \ + "netmask=255.255.255.0\0" \ + "kernel_image=uImage\0" \ + "fit_load_address=0x2080000\0" \ + "fit_config=config@0\0" \ + "extraenv_load_address=0x207E000\0" \ + "ramdisk_image=uramdisk.image.gz\0" \ + "ramdisk_load_address=0x4000000\0" \ + "devicetree_image=devicetree.dtb\0" \ + "devicetree_load_address=0x2000000\0" \ + "bitstream_image=system.bit.bin\0" \ + "boot_image=BOOT.bin\0" \ + "loadbit_addr=0x100000\0" \ + "loadbootenv_addr=0x2000000\0" \ + "fit_size=0x900000\0" \ + "devicetree_size=0x20000\0" \ + "ramdisk_size=0x400000\0" \ + "bitstream_size=0x400000\0" \ + "boot_size=0xF00000\0" \ + "fdt_high=0x20000000\0" \ + "initrd_high=0x20000000\0" \ + "bootenv=uEnv.txt\0" \ + "maxcpus=1\0" \ + "clear_reset_cause=mw f8000008 df0d && mw f8000258 00400000 && mw f8000004 767b\0" \ + "refclk_source=internal\0" \ + "mode=1r1t\0" \ + "adi_loadvals_pluto=if test -n \"${ad936x_ext_refclk}\" && test ! -n \"${ad936x_skip_ext_refclk}\"; then " \ + "fdt set /clocks/clock@0 clock-frequency ${ad936x_ext_refclk}; " \ + "fi; " \ + "if test -n \"${ad936x_ext_refclk_override}\"; then " \ + "fdt set /clocks/clock@0 clock-frequency ${ad936x_ext_refclk_override}; " \ + "fi; " \ + "if test -n \"${refclk_source}\" && test ! \"${refclk_source}\" = \"internal\" && test ! \"${refclk_source}\" = \"external\"; then " \ + "setenv refclk_source internal; " \ + "saveenv; " \ + "fi; " \ + "if test \"${refclk_source}\" = \"internal\" && test \"${model}\" = \"Analog Devices PlutoSDR Rev.C (Z7010/AD9363)\" ; then " \ + "fdt rm /amba/gpio@e000a000/clock_extern_en || fdt rm /axi/gpio@e000a000/clock_extern_en; " \ + "fi; " \ + "if test \"${refclk_source}\" = \"external\" && test \"${model}\" = \"Analog Devices PlutoSDR Rev.C (Z7010/AD9363)\" ; then " \ + "fdt rm /amba/gpio@e000a000/clock_internal_en || fdt rm /axi/gpio@e000a000/clock_internal_en; " \ + "fi; " \ + "if test \"${attr_val}\" = \"ad9361\" && test ! \"${model}\" = \"Analog Devices PlutoSDR Rev.C (Z7010/AD9363)\" ; then " \ + "setenv attr_val ad9363a; " \ + "saveenv; " \ + "fi; " \ + "if test -n \"${attr_val}\" && test ! \"${attr_val}\" = \"ad9361\" && test ! \"${attr_val}\" = \"ad9363a\" && test ! \"${attr_val}\" = \"ad9364\"; then " \ + "setenv attr_val ad9363a; " \ + "saveenv; " \ + "fi; " \ + "if test -n \"${mode}\" && test ! \"${mode}\" = \"1r1t\" && test ! \"${mode}\" = \"2r2t\"; then " \ + "setenv mode 1r1t; " \ + "saveenv; " \ + "fi; " \ + "if test -n \"${attr_name}\" && test -n \"${attr_val}\"; then " \ + "fdt set /amba/spi@e0006000/ad9361-phy@0 ${attr_name} ${attr_val} || fdt set /axi/spi@e0006000/ad9361-phy@0 ${attr_name} ${attr_val}; " \ + "fi; " \ + "if test \"${mode}\" = \"1r1t\" && test \"${model}\" = \"Analog Devices PlutoSDR Rev.C (Z7010/AD9363)\"; then " \ + "fdt rm /amba/spi@e0006000/ad9361-phy@0 adi,2rx-2tx-mode-enable || fdt rm /axi/spi@e0006000/ad9361-phy@0 adi,2rx-2tx-mode-enable; " \ + "fdt set /fpga-axi/cf-ad9361-dds-core-lpc@79024000 compatible adi,axi-ad9364-dds-6.00.a; " \ + "fi; " \ + "if test -n \"${cs_gpio}\" && test \"${model}\" = \"Analog Devices PlutoSDR Rev.C (Z7010/AD9363)\"; then " \ + "fdt set /amba/axi_quad_spi@7C430000/ cs-gpios \"<0x06 ${cs_gpio} 0>\" || fdt set /axi/axi_quad_spi@7C430000/ cs-gpios \"<0x06 ${cs_gpio} 0>\"; " \ + "fi; " \ + "if test -n \"${attr_val}\" && test \"${attr_val}\" = \"ad9364\"; then " \ + "fdt set /fpga-axi/cf-ad9361-dds-core-lpc@79024000 compatible adi,axi-ad9364-dds-6.00.a; " \ + "if test ! \"${mode}\" = \"1r1t\"; then " \ + "fdt rm /amba/spi@e0006000/ad9361-phy@0 adi,2rx-2tx-mode-enable || fdt rm /axi/spi@e0006000/ad9361-phy@0 adi,2rx-2tx-mode-enable; " \ + "setenv mode 1r1t; " \ + "saveenv; " \ + "fi; " \ + "fi; \0" \ + "adi_loadvals=fdt addr ${fit_load_address} && fdt get value fdt_choosen /configurations/${fit_config}/ fdt && " \ + "fdt get addr fdtaddr /images/${fdt_choosen} data && fdt addr ${fdtaddr}; " \ + "fdt get value model / model; " \ + "if test \"${model}\" \\> \"Analog Devices Pluto\"; then " \ + "run adi_loadvals_pluto; " \ + "fi; \0" \ + "qspiboot_extraenv=sf read ${extraenv_load_address} 0xFF000 0x1000 && " \ + "env import -c ${extraenv_load_address} 0x1000 || true \0" \ + "read_sf=sf probe && run qspiboot_extraenv && " \ + "sf read ${fit_load_address} 0x200000 ${fit_size} && " \ + "iminfo ${fit_load_address} || " \ + "sf read ${fit_load_address} 0x200000 0x1E00000; \0" \ + "ramboot_verbose=adi_hwref;echo Copying Linux from DFU to RAM... && " \ + "run dfu_ram;" \ + "if run adi_loadvals; then " \ + "echo Loaded AD936x refclk frequency and model into devicetree; " \ + "fi; " \ + "envversion;setenv bootargs console=ttyPS0,115200 maxcpus=${maxcpus} rootfstype=ramfs root=/dev/ram0 rw earlyprintk clk_ignore_unused uboot=\"${uboot-version}\" && " \ + "bootm ${fit_load_address}#${fit_config}\0" \ + "qspiboot_verbose=adi_hwref;echo Copying Linux from QSPI flash to RAM... && " \ + "run read_sf && " \ + "if run adi_loadvals; then " \ + "echo Loaded AD936x refclk frequency and model into devicetree; " \ + "fi; " \ + "envversion;setenv bootargs console=ttyPS0,115200 maxcpus=${maxcpus} rootfstype=ramfs root=/dev/ram0 rw earlyprintk clk_ignore_unused uboot=\"${uboot-version}\" && " \ + "bootm ${fit_load_address}#${fit_config} || echo BOOT failed entering DFU mode ... && run dfu_sf \0" \ + "qspiboot=setenv silent 1;adi_hwref;test -n $PlutoRevA || gpio input 14 && setenv silent && sf probe && sf protect lock 0 100000 && run dfu_sf; " \ + "setenv silent;" \ + "itest *f8000258 == 480003 && run clear_reset_cause && run dfu_sf; " \ + "itest *f8000258 == 480007 && run clear_reset_cause && run ramboot_verbose; " \ + "itest *f8000258 == 480006 && run clear_reset_cause && run qspiboot_verbose; " \ + "itest *f8000258 == 480002 && run clear_reset_cause && exit; " \ + "echo Booting silently && setenv silent 1; " \ + "run read_sf && run adi_loadvals; " \ + "envversion;setenv bootargs console=ttyPS0,115200 maxcpus=${maxcpus} rootfstype=ramfs root=/dev/ram0 rw quiet loglevel=4 clk_ignore_unused uboot=\"${uboot-version}\" && " \ + "bootm ${fit_load_address}#${fit_config} || setenv silent;echo BOOT failed entering DFU mode ... && sf protect lock 0 100000 && run dfu_sf \0" \ + "jtagboot=env default -a;sf probe && sf protect unlock 0 100000 && run dfu_sf; \0" \ + "uenvboot=" \ + "if run loadbootenv; then " \ + "echo Loaded environment from ${bootenv}; " \ + "run importbootenv; " \ + "fi; " \ + "if test -n $uenvcmd; then " \ + "echo Running uenvcmd ...; " \ + "run uenvcmd; " \ + "fi\0" \ + "usbboot=if usb start; then " \ + "run uenvboot; " \ + "echo Copying Linux from USB to RAM... && " \ + "load usb 0 ${fit_load_address} ${kernel_image} && " \ + "load usb 0 ${devicetree_load_address} ${devicetree_image} && " \ + "load usb 0 ${ramdisk_load_address} ${ramdisk_image} && " \ + "bootm ${fit_load_address} ${ramdisk_load_address} ${devicetree_load_address}; " \ + "fi\0" \ + DFU_ALT_INFO_RAM \ + DFU_ALT_INFO_SF + +#include + +#endif /* __CONFIG_ZYNQ_PLUTO_SDR_H */ diff --git a/include/configs/zynq_zc70x_sidekiqz2.h b/include/configs/zynq_zc70x_sidekiqz2.h new file mode 100644 index 000000000000..9c8cbb77aa79 --- /dev/null +++ b/include/configs/zynq_zc70x_sidekiqz2.h @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2018 Analog Devices Inc. / Epiq Solutions + * + * Configuration for the Epiq Solutions SidekiqZ2 board + */ + +#ifndef __CONFIG_ZYNQ_ZC70X_SIDEKIQZ2_H +#define __CONFIG_ZYNQ_ZC70X_SIDEKIQZ2_H + +#define CFG_EXTRA_ENV_SETTINGS \ + "env_version=2\0" \ + "modeboot=qspiboot\0" \ + "ethaddr=00:0a:35:00:01:22\0" \ + "ipaddr=192.168.3.1\0" \ + "ipaddr_host=192.168.3.9\0" \ + "netmask=255.255.255.0\0" \ + "kernel_image=uImage\0" \ + "fit_load_address=0x2080000\0" \ + "fit_config=config@9\0" \ + "extraenv_load_address=0x207E000\0" \ + "ramdisk_image=uramdisk.image.gz\0" \ + "ramdisk_load_address=0x4000000\0" \ + "devicetree_image=devicetree.dtb\0" \ + "devicetree_load_address=0x2000000\0" \ + "dfu_alt_info=boot.dfu raw 0x0 0x100000;firmware.dfu raw 0x200000 0x1E00000;" \ + "uboot-extra-env.dfu raw 0xFF000 0x1000;uboot-env.dfu raw 0x100000 0x20000;" \ + "spare.dfu raw 0x120000 0xE0000\0" \ + "bitstream_image=system.bit.bin\0" \ + "boot_image=BOOT.bin\0" \ + "loadbit_addr=0x100000\0" \ + "loadbootenv_addr=0x2000000\0" \ + "fit_size=0x900000\0" \ + "devicetree_size=0x20000\0" \ + "ramdisk_size=0x400000\0" \ + "bitstream_size=0x400000\0" \ + "boot_size=0xF00000\0" \ + "fdt_high=0x20000000\0" \ + "initrd_high=0x20000000\0" \ + "bootenv=uEnv.txt\0" \ + "maxcpus=2\0" \ + "clear_reset_cause=mw f8000008 df0d && mw f8000258 00400000 && mw f8000004 767b\0" \ + "dfu_ram=echo Entering DFU RAM mode ... && run dfu_ram_info && dfu 0 ram 0\0" \ + "dfu_ram_info=setenv dfu_alt_info dummy.dfu ram 0 0\\\\;firmware.dfu ram ${fit_load_address} 0x1E00000\0" \ + "dfu_sf=gpio set 15;setenv silent;echo Entering DFU SF mode ... && run dfu_sf_info && " \ + "dfu 0 sf 0:0:40000000:0 && if test -n ${dfu_alt_num} && test ${dfu_alt_num} = 1; " \ + "then setenv fit_size ${filesize} && setenv dfu_alt_num && env save; fi;gpio clear 15;\0" \ + "dfu_sf_info=setenv dfu_alt_info boot.dfu raw 0x0 0x100000\\\\;firmware.dfu raw 0x200000 0x1E00000\\\\;" \ + "uboot-extra-env.dfu raw 0xFF000 0x1000\\\\;uboot-env.dfu raw 0x100000 0x20000\\\\;" \ + "spare.dfu raw 0x120000 0xE0000\0" \ + "adi_loadvals=fdt addr ${fit_load_address} && fdt get value fdt_choosen /configurations/${fit_config}/ fdt && " \ + "fdt get addr fdtaddr /images/${fdt_choosen} data && fdt addr ${fdtaddr}; " \ + "if test -n ${ad936x_ext_refclk} && test ! -n ${ad936x_skip_ext_refclk}; then " \ + "fdt set /clocks/clock@0 clock-frequency ${ad936x_ext_refclk}; " \ + "fi; " \ + "if test -n ${model}; then " \ + "fdt set / model ${model}; " \ + "fi; " \ + "if test -n ${attr_name} && test -n ${attr_val}; then " \ + "fdt set /amba/spi@e0006000/ad9361-phy@0 ${attr_name} ${attr_val} || fdt set /axi/spi@e0006000/ad9361-phy@0 ${attr_name} ${attr_val}; " \ + "fi \0" \ + "qspiboot_extraenv=sf read ${extraenv_load_address} 0xFF000 0x1000 && " \ + "env import -c ${extraenv_load_address} 0x1000 || true \0" \ + "read_sf=sf probe && run qspiboot_extraenv && " \ + "sf read ${fit_load_address} 0x200000 ${fit_size} && " \ + "iminfo ${fit_load_address} || " \ + "sf read ${fit_load_address} 0x200000 0x1E00000; \0" \ + "ramboot_verbose=adi_hwref;echo Copying Linux from DFU to RAM... && run dfu_ram;" \ + "if run adi_loadvals; then " \ + "echo Loaded AD936x refclk frequency and model into devicetree; " \ + "fi; " \ + "envversion;setenv bootargs console=ttyPS0,115200 maxcpus=${maxcpus} rootfstype=ramfs root=/dev/ram0 rw earlyprintk clk_ignore_unused uboot=\"${uboot-version}\" && " \ + "bootm ${fit_load_address}#${fit_config}\0" \ + "qspiboot_verbose=adi_hwref;echo Copying Linux from QSPI flash to RAM... && " \ + "run read_sf && " \ + "if run adi_loadvals; then " \ + "echo Loaded AD936x refclk frequency and model into devicetree; " \ + "fi; " \ + "envversion;setenv bootargs console=ttyPS0,115200 maxcpus=${maxcpus} rootfstype=ramfs root=/dev/ram0 rw earlyprintk clk_ignore_unused uboot=\"${uboot-version}\" && " \ + "bootm ${fit_load_address}#${fit_config} || echo BOOT failed entering DFU mode ... && run dfu_sf \0" \ + "qspiboot=adi_hwref; setenv silent; " \ + "if gpio input 48; then " \ + "echo DFU pin asserted && run dfu_sf; " \ + "fi; " \ + "setenv silent;" \ + "itest *f8000258 == 480003 && run clear_reset_cause && run dfu_sf; " \ + "itest *f8000258 == 480007 && run clear_reset_cause && run ramboot_verbose; " \ + "itest *f8000258 == 480006 && run clear_reset_cause && run qspiboot_verbose; " \ + "itest *f8000258 == 480002 && run clear_reset_cause && exit; " \ + "echo Booting silently && setenv silent 1; run read_sf && run adi_loadvals; " \ + "envversion;setenv bootargs console=ttyPS0,115200 maxcpus=${maxcpus} rootfstype=ramfs root=/dev/ram0 rw quiet loglevel=4 clk_ignore_unused uboot=\"${uboot-version}\" && " \ + "bootm ${fit_load_address}#${fit_config} || setenv silent;echo BOOT failed entering DFU mode ... && run dfu_sf \0" \ + "jtagboot=env default -a;sf probe && sf protect unlock 0 100000 && run dfu_sf; \0" \ + "thor_ram=run dfu_ram_info && thordown 0 ram 0\0" \ + "uenvboot=" \ + "if run loadbootenv; then " \ + "echo Loaded environment from ${bootenv}; " \ + "run importbootenv; " \ + "fi; " \ + "if test -n $uenvcmd; then " \ + "echo Running uenvcmd ...; " \ + "run uenvcmd; " \ + "fi\0" \ + "usbboot=if usb start; then " \ + "run uenvboot; " \ + "echo Copying Linux from USB to RAM... && " \ + "load usb 0 ${fit_load_address} ${kernel_image} && " \ + "load usb 0 ${devicetree_load_address} ${devicetree_image} && " \ + "load usb 0 ${ramdisk_load_address} ${ramdisk_image} && " \ + "bootm ${fit_load_address} ${ramdisk_load_address} ${devicetree_load_address}; " \ + "fi\0" + +#include + +#endif /* __CONFIG_ZYNQ_ZC70X_SIDEKIQZ2_H */