// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (C) 2021 Marvell International Ltd.
 * Copyright (C) 2023 Addiva Elektronik AB
 *
 * Device tree for Alder board
 */

#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>

#include "../marvell/cn9130-patched.dtsi"

#include "alder-mpp.h"

/ {
	model = "Alder";
	compatible = "alder,alder",
		"marvell,armada-ap807-quad",
		"marvell,armada-ap807";

	chosen {
		stdout-path = "serial0:115200n8";

		infix {
			vpds = <&vpd_cpu &vpd_product &vpd_power>;
			usb-ports = <&cp0_usb3_1>;
			usb-port-names = "USB";
		};
	};

	memory@0 {
		device_type = "memory";
		reg = <0x0 0x0 0x0 0x80000000>;
	};
};


/* UART0 (Console) */

&cp0_pinctrl {
	cp0_uart0_pins: cp0-uart0-pins {
		marvell,pins = CP_UA0_RXD(MPP_ID), CP_UA0_TXD(MPP_ID);
		marvell,function = "uart0";
	};
};

&uart0 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&cp0_uart0_pins>;
};


/* GPIO */

&cp0_gpio1 {
	status = "okay";
};

&cp0_gpio2 {
	status = "okay";
};


/* I2C0 (EEPROM) */

&cp0_pinctrl {
	cp0_i2c0_pins: cp0-i2c0-pins {
		marvell,pins = CP_I2C0_SCK(MPP_ID), CP_I2C0_SDA(MPP_ID);
		marvell,function = "i2c0";
	};
};

&cp0_i2c0 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&cp0_i2c0_pins>;

	vpd_cpu: eeprom@50 {
		// AT24C256C-MAHL-T
		compatible = "atmel,24c256";
                reg = <0x50>;

		infix,board = "cpu";
		infix,trusted;
	};
};


/* I2C1 (Mux) */

&cp0_pinctrl {
	cp0_i2c1_pins: cp0-i2c1-pins {
		marvell,pins = CP_I2C1_SCK(MPP_ID), CP_I2C1_SDA(MPP_ID);
		marvell,function = "i2c1";
	};
};

&cp0_i2c1 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&cp0_i2c1_pins>;

	i2cmux@70 {
		compatible = "nxp,pca9548";
		#address-cells = <1>;
                #size-cells = <0>;
                reg = <0x70>;

		reset-gpios = I2C_RESETn(MPP_GPIO_REF);

		i2c_sysmgmt: i2c@0 {
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <0>;
		};

		i2c_pwr: i2c@1 {
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <1>;
		};

		i2c_sw: i2c@2 {
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <2>;
		};

		i2c_sfp9: i2c@3 {
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <3>;
		};

		i2c_sfpa: i2c@4 {
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <4>;
		};

		i2c@5 {
			status = "disabled";
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <5>;
		};

		i2c@6 {
			status = "disabled";
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <6>;
		};

		i2c@7 {
			status = "disabled";
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <7>;
		};

	};
};


/* System Management */

&i2c_sysmgmt {
	vpd_product: eeprom@b {
		label = "vpd";
                reg = <0x0b>;
		compatible = "atmel,24c02";

		infix,board = "product";

		nvmem-layout {
			compatible = "onie,tlv-layout";

			base_mac: mac-address {
				#nvmem-cell-cells = <1>;
			};
		};
	};
};

/* AP SDHCI (eMMC) */

&ap_sdhci0 {
	status = "okay";
	pinctrl-names = "default";
	/* pinctrl-0 = <&ap_emmc_pins>; No pinctrl in Linux? */
	bus-width = <8>;
	mmc-ddr-1_8v;
	mmc-hs400-1_8v;
};


/* SPI1 (Boot FLASH) */

&cp0_pinctrl {
	cp0_spi1_pins: cp0-spi-pins-0 {
		marvell,pins = \
			CP_SPI1_MISO(MPP_ID), CP_SPI1_CS0(MPP_ID), \
			CP_SPI1_MOSI(MPP_ID), CP_SPI1_SCK(MPP_ID);
		marvell,function = "spi1";
	};
};

&cp0_spi1 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&cp0_spi1_pins>;

	/* Boot flash */
	spi-flash@0 {
		#address-cells = <0x1>;
		#size-cells = <0x1>;
		compatible = "jedec,spi-nor", "spi-flash";
		reg = <0x0>;
		/* On-board MUX does not allow higher frequencies */
		spi-max-frequency = <40000000>;

		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			boot0@0 {
				label = "boot0";
				reg = <0x0 0x200000>;
			};

			boot1@200000 {
				label = "boot1";
				reg = <0x200000 0x200000>;
			};
		};
	};
};


/* USB1 */

/ {
	cp0_usb3_0_phy1: cp0_usb3_phy {
		compatible = "usb-nop-xceiv";
		vcc-supply = <&reg_cp0_usb3_vbus1>;
	};

	reg_cp0_usb3_vbus1: reg_cp0_usb3_vbus1 {
		compatible = "regulator-fixed";
		regulator-name = "cp0-xhci1-vbus";
		regulator-min-microvolt = <5000000>;
		regulator-max-microvolt = <5000000>;
		enable-active-high;
		gpio = USB1_VBUS_ENABLE(MPP_GPIO_REF);
	};
};

&cp0_utmi {
	status = "okay";
};

&cp0_utmi1 {
	status = "okay";
	dr_mode = "host";
};

&cp0_usb3_1 {
	status = "okay";
	usb-phy = <&cp0_usb3_0_phy1>;
	phys = <&cp0_utmi1>, <&cp0_comphy3 1>;
	phy-names = "usb", "usb3";
	dr_mode = "host";
};




/* ETH0 (DSA connection to switch) */

&cp0_crypto {
	status = "okay";
};

&cp0_ethernet {
	status = "okay";
};

&cp0_eth0 {
	status = "okay";
	phy-mode = "10gbase-r";
	phys = <&cp0_comphy4 0>;
	managed = "in-band-status";

	nvmem-cells = <&base_mac 0>;
	nvmem-cell-names = "mac-address";
};


/* MDIO (Switch) */

&cp0_pinctrl {
	cp0_mdio_pins: cp0-mdio-pins-0 {
		marvell,pins = CP_SMI_MDIO(MPP_ID), CP_SMI_MDC(MPP_ID);
		marvell,function = "ge";
	};
};

&cp0_mdio {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&cp0_mdio_pins>;

	sw: switch@0 {
		compatible = "marvell,mv88e6190";
		#address-cells = <1>;
		#size-cells = <0>;
		reg = <0>;

		reset-gpios = SW_RESETn(MPP_GPIO_REF);

		interrupts-extended = SW_INTn(MPP_IRQ_REF);
		interrupt-controller;

		dsa,member = <0 0>;

		ports {
			#address-cells = <1>;
			#size-cells = <0>;
			port@0 {
				reg = <0x0>;
				label = "cpu";
				ethernet = <&cp0_eth0>;
				phy-mode = "10gbase-r";
				fixed-link {
					speed = <10000>;
					full-duplex;
				};
			};

#define SWP_COMMON(_n, _label, _mac_offs, _phymode, _phy) \
				reg = <0x ## _n>; \
				label = _label; \
				phy-mode = _phymode; \
				phy-handle = <&_phy>; \
				\
				nvmem-cells = <&base_mac _mac_offs>; \
				nvmem-cell-names = "mac-address"

#define XSWP(_n, _label, _mac_offs, _phy) \
			port@_n { \
				SWP_COMMON(_n, _label, _mac_offs, "usxgmii", _phy); \
			}

#define GSWP(_n, _label, _mac_offs, _phy) \
			port@_n { \
				SWP_COMMON(_n, _label, _mac_offs, "gmii", _phy); \
				\
				leds { \
					#address-cells = <1>; \
					#size-cells = <0>; \
					\
					led@0 { \
						reg = <0>; \
						function = "tp"; \
						color = <LED_COLOR_ID_GREEN>; \
						default-state = "keep"; \
					}; \
					led@1 { \
						reg = <1>; \
						function = "tp"; \
						color = <LED_COLOR_ID_YELLOW>; \
						default-state = "off"; \
					}; \
				}; \
			}

			XSWP(9,  "x1",  1,  xphy9);
			XSWP(a,  "x2",  2,  xphya);

			GSWP(8,  "x3",  3, swphy8);
			GSWP(7,  "x4",  4, swphy7);
			GSWP(6,  "x5",  5, swphy6);
			GSWP(5,  "x6",  6, swphy5);
			GSWP(4,  "x7",  7, swphy4);
			GSWP(3,  "x8",  8, swphy3);
			GSWP(2,  "x9",  9, swphy2);
			GSWP(1, "x10", 10, swphy1);
#undef GSWP
#undef XSWP
#undef SWP_COMMON
		};

		mdio {
			#address-cells = <1>;
			#size-cells = <0>;

#define SWPHY(_n) \
			ethernet-phy@_n { \
				compatible = "ethernet-phy-ieee802.3-c22"; \
				reg = <_n>; \
				eee-broken-100tx; \
				eee-broken-1000t; \
			}

			swphy1: SWPHY(1);
			swphy2: SWPHY(2);
			swphy3: SWPHY(3);
			swphy4: SWPHY(4);
			swphy5: SWPHY(5);
			swphy6: SWPHY(6);
			swphy7: SWPHY(7);
			swphy8: SWPHY(8);
#undef SWPHY
		};
	};
};


/* XMDIO (88X3310P 10G PHYs) */

&cp0_pinctrl {
	cp0_xmdio_pins: cp0-xmdio-pins-0 {
		marvell,pins = CP_XSMI_MDIO(MPP_ID), CP_XSMI_MDC(MPP_ID);
		marvell,function = "xg";
	};
};

&ETH9_RESETn(MPP_GPIO_CHIP) {
	xphy9-reset-hog {
		gpio-hog;
		gpios = ETH9_RESETn(MPP_GPIO_REF_NO_CHIP);
		output-low;
		line-name = "x1-phy-reset";
	};
};

&ETH10_RESETn(MPP_GPIO_CHIP) {
	xphya-reset-hog {
		gpio-hog;
		gpios = ETH10_RESETn(MPP_GPIO_REF_NO_CHIP);
		output-low;
		line-name = "x2-phy-reset";
	};
};

&cp0_xmdio {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&cp0_xmdio_pins>;

	/* 88X3310 specifices 35ns minimum MDC period (28.57 MHz). */
	clock-frequency = <28571428>;

#define XPHY(_n, _sfp) \
	ethernet-phy@_n { \
		compatible = "ethernet-phy-ieee802.3-c45"; \
		reg = <_n>; \
		sfp = <&_sfp>; \
		\
		leds { \
			#address-cells = <1>; \
			#size-cells = <0>; \
			\
			led@0 { \
				reg = <0>; \
				function = "tp"; \
				color = <LED_COLOR_ID_YELLOW>; \
				default-state = "off"; \
				\
				marvell,media = "copper"; \
				marvell,polarity = "active-high"; \
			}; \
			led@1 { \
				reg = <1>; \
				function = "tp"; \
				color = <LED_COLOR_ID_GREEN>; \
				default-state = "keep"; \
				\
				marvell,media = "copper"; \
				marvell,polarity = "active-high"; \
			}; \
			\
			led@2 { \
				reg = <2>; \
				function = "sfp"; \
				color = <LED_COLOR_ID_YELLOW>; \
				default-state = "off"; \
				\
				marvell,media = "fiber"; \
				marvell,polarity = "active-high"; \
			}; \
			led@3 { \
				reg = <3>; \
				function = "sfp"; \
				color = <LED_COLOR_ID_GREEN>; \
				default-state = "keep"; \
				\
				marvell,media = "fiber"; \
				marvell,polarity = "active-high"; \
			}; \
		}; \
	}

	xphy9: XPHY(4, sfp9);
	xphya: XPHY(5, sfpa);
#undef XPHY
};

/ {
	sfp9: sfp@9 {
		compatible = "sff,sfp";
		i2c-bus = <&i2c_sfp9>;
		mod-def0-gpios = SFP9_MOD_ABS(MPP_GPIO_REF);
		los-gpios = SFP9_RX_LOS(MPP_GPIO_REF);
		tx-disable-gpios = SFP9_TX_DISABLE(MPP_GPIO_REF);
		tx-fault-gpios = SFP9_TX_FAULT(MPP_GPIO_REF);
		rate-select0-gpios = SFP9_RS0(MPP_GPIO_REF);
		rate-select1-gpios = SFP9_RS1(MPP_GPIO_REF);
		maximum-power-milliwatt = <3000>;
	};

	sfpa: sfp@a {
		compatible = "sff,sfp";
		i2c-bus = <&i2c_sfpa>;
		mod-def0-gpios = SFP10_MOD_ABS(MPP_GPIO_REF);
		los-gpios = SFP10_RX_LOS(MPP_GPIO_REF);
		tx-disable-gpios = SFP10_TX_DISABLE(MPP_GPIO_REF);
		tx-fault-gpios = SFP10_TX_FAULT(MPP_GPIO_REF);
		rate-select0-gpios = SFP10_RS0(MPP_GPIO_REF);
		rate-select1-gpios = SFP10_RS1(MPP_GPIO_REF);
		maximum-power-milliwatt = <3000>;
	};
};


/* Power Board */

&cp0_pinctrl {
	cp0_pwr_gpio_pins: cp0-pwr-gpio-0 {
		marvell,pins = I2C_IRQ(MPP_ID);
		marvell,function = "gpio";
	};
};

&i2c_pwr {
	// Shared IRQ on I2C_IRQ
	pinctrl-names = "default";
	pinctrl-0 = <&cp0_pwr_gpio_pins>;

	// 0x26  U13 PCF8574        GPIO I/O
	gpio_pwr1: gpio@26 {
		compatible = "nxp,pcf8574a";
		#gpio-cells = <2>;
		gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
		interrupts-extended = I2C_IRQ(MPP_IRQ_REF);
		reg = <0x26>;
#define GPIO_PWR1_UNUSED0	gpio_pwr1 0 GPIO_ACTIVE_HIGH
#define GPIO_PWR1_UNUSED1	gpio_pwr1 1 GPIO_ACTIVE_HIGH
#define GPIO_POE_PGOOD		gpio_pwr1 2 GPIO_ACTIVE_HIGH
#define GPIO_RESET_BUTTON	gpio_pwr1 3 GPIO_ACTIVE_LOW
#define GPIO_VIN1_PGOOD		gpio_pwr1 4 GPIO_ACTIVE_LOW
#define GPIO_LED_VIN2_ALERT	gpio_pwr1 5 GPIO_ACTIVE_LOW
#define GPIO_VIN2_PGOOD		gpio_pwr1 6 GPIO_ACTIVE_LOW
#define GPIO_LED_VIN1_ALERT	gpio_pwr1 7 GPIO_ACTIVE_LOW
	};

	//0x27  U3  PCF8574        GPIO LED
	gpio_pwr2: gpio@27 {
		compatible = "nxp,pcf8574a";
		#gpio-cells = <2>;
		gpio-controller;
                #interrupt-cells = <2>;
                interrupt-controller;
		interrupts-extended = I2C_IRQ(MPP_IRQ_REF);
		reg = <0x27>;
#define GPIO_LED2G		gpio_pwr2 0 GPIO_ACTIVE_LOW
#define GPIO_LED2R		gpio_pwr2 1 GPIO_ACTIVE_LOW
#define GPIO_LED1G		gpio_pwr2 2 GPIO_ACTIVE_LOW
#define GPIO_LED1R		gpio_pwr2 3 GPIO_ACTIVE_LOW
#define GPIO_LED4G		gpio_pwr2 4 GPIO_ACTIVE_LOW
#define GPIO_LED4R		gpio_pwr2 5 GPIO_ACTIVE_LOW
#define GPIO_LED3G		gpio_pwr2 6 GPIO_ACTIVE_LOW
#define GPIO_LED3R		gpio_pwr2 7 GPIO_ACTIVE_LOW
	};

	//0x28* U5  TPS23861PWR    PoE Controller
	//0x30  U5  TPS23861PWR    PoE Controller broadcast

	//0x50  U15 AT24C256C      EEPROM
	vpd_power: eeprom@50 {
		// AT24C256C-MAHL-T
		compatible = "atmel,24c256";
                reg = <0x50>;

		infix,board = "power";
	};
};

/* Reset button */
/ {
	gpio-keys {
		compatible = "gpio-keys";
		up {
			label = "factory-reset";
			linux,code = <KEY_RESTART>;
			gpios = <&GPIO_RESET_BUTTON>;
		};
	};
};

/* System LEDs */
/ {
	power-a {
		compatible = "gpio-charger";
		charger-type = "mains";
		gpios = <&GPIO_VIN1_PGOOD>;
	};

	power-b {
		compatible = "gpio-charger";
		charger-type = "mains";
		gpios = <&GPIO_VIN2_PGOOD>;
	};

	leds: leds {
		compatible = "gpio-leds";

		led-statg {
			function = LED_FUNCTION_STATUS;
			color = <LED_COLOR_ID_GREEN>;
			gpios = <&GPIO_LED1G>;
		};

		led-statr {
			function = LED_FUNCTION_STATUS;
			color = <LED_COLOR_ID_RED>;
			gpios = <&GPIO_LED1R>;
		};

		led-faultg {
			function = LED_FUNCTION_FAULT;
			color = <LED_COLOR_ID_GREEN>;
			gpios = <&GPIO_LED2G>;
		};

		led-faultr {
			function = LED_FUNCTION_FAULT;
			color = <LED_COLOR_ID_RED>;
			gpios = <&GPIO_LED2R>;
		};

		led-lang {
			function = LED_FUNCTION_LAN;
			color = <LED_COLOR_ID_GREEN>;
			gpios = <&GPIO_LED3G>;
		};

		led-lanr {
			function = LED_FUNCTION_LAN;
			color = <LED_COLOR_ID_RED>;
			gpios = <&GPIO_LED3R>;
		};

		led-bootg {
			function = LED_FUNCTION_BOOT;
			color = <LED_COLOR_ID_GREEN>;
			gpios = <&GPIO_LED4G>;
		};

		led-bootr {
			function = LED_FUNCTION_BOOT;
			color = <LED_COLOR_ID_RED>;
			gpios = <&GPIO_LED4R>;
			default-state = "on";
			linux,default-trigger = "timer";
		};

		led-vin1-alert {
			function = "power-a";
			color = <LED_COLOR_ID_RED>;
			gpios = <&GPIO_LED_VIN1_ALERT>;
		};

		led-vin2-alert {
			function = "power-b";
			color = <LED_COLOR_ID_RED>;
			gpios = <&GPIO_LED_VIN2_ALERT>;
		};
	};
};

/* Watchdog */

&cp0_pinctrl {
	watchdog_pins: watchdog-pins {
		marvell,pins = WDT_TICKLE(MPP_ID);
		marvell,function = "gpio";
	};
};

/ {
        sysmgmt-watchdog {
                pinctrl-names = "default";
                pinctrl-0 = <&watchdog_pins>;
                compatible = "linux,wdt-gpio";
                gpios = WDT_TICKLE(MPP_GPIO_REF);
                always-running;
                hw_algo = "toggle";
                hw_margin_ms = <20000>; /* toggle period must be below 1 minute */
        };
};
