// SPDX-License-Identifier: GPL-2.0

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/clock/rp1.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/mfd/rp1.h>
#include <dt-bindings/pwm/pwm.h>
#include <dt-bindings/reset/raspberrypi,firmware-reset.h>

#define i2c0 _i2c0
#define i2c3 _i2c3
#define i2c4 _i2c4
#define i2c5 _i2c5
#define i2c6 _i2c6
#define i2c8 _i2c8
#define i2s _i2s
#define pwm0 _pwm0
#define pwm1 _pwm1
#define spi0 _spi0
#define spi3 _spi3
#define spi4 _spi4
#define spi5 _spi5
#define spi6 _spi6
#define uart0 _uart0
#define uart2 _uart2
#define uart5 _uart5

#include "bcm2712.dtsi"

#undef i2c0
#undef i2c3
#undef i2c4
#undef i2c5
#undef i2c6
#undef i2c8
#undef i2s
#undef pwm0
#undef pwm1
#undef spi0
#undef spi3
#undef spi4
#undef spi5
#undef spi6
#undef uart0
#undef uart2
#undef uart3
#undef uart4
#undef uart5

/ {
	compatible = "raspberrypi,5-compute-module", "brcm,bcm2712";
	model = "Raspberry Pi Compute Module 5";

	/* Will be filled by the bootloader */
	memory@0 {
		device_type = "memory";
		reg = <0 0 0x28000000>;
	};

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

		led_pwr: led-pwr {
			label = "PWR";
			gpios = <&rp1_gpio 44 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "none";
		};

		led_act: led-act {
			label = "ACT";
			gpios = <&gio_aon 9 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "mmc0";
		};
	};

	sd_io_1v8_reg: sd_io_1v8_reg {
		compatible = "regulator-fixed";
		regulator-name = "vdd-sd-io";
		regulator-min-microvolt = <1800000>;
		regulator-max-microvolt = <1800000>;
		regulator-always-on;
	};

	sd_vcc_reg: sd_vcc_reg {
		compatible = "regulator-fixed";
		regulator-name = "vcc-sd";
		regulator-min-microvolt = <3300000>;
		regulator-max-microvolt = <3300000>;
		regulator-boot-on;
		enable-active-high;
		gpios = <&gio_aon 4 GPIO_ACTIVE_HIGH>;
		status = "okay";
	};

	wl_on_reg: wl_on_reg {
		compatible = "regulator-fixed";
		regulator-name = "wl-on-regulator";
		regulator-min-microvolt = <3300000>;
		regulator-max-microvolt = <3300000>;
		pinctrl-0 = <&wl_on_pins>;
		pinctrl-names = "default";

		gpio = <&gio 28 GPIO_ACTIVE_HIGH>;

		startup-delay-us = <150000>;
		enable-active-high;
	};

	clocks: clocks {
	};

	cam1_clk: cam1_clk {
		compatible = "fixed-clock";
		#clock-cells = <0>;
		status = "disabled";
	};

	cam0_clk: cam0_clk {
		compatible = "fixed-clock";
		#clock-cells = <0>;
		status = "disabled";
	};

	cam0_reg: cam0_reg {
		compatible = "regulator-fixed";
		regulator-name = "cam0_reg";
		enable-active-high;
		status = "okay";
		gpio = <&rp1_gpio 34 0>; // CD0_IO0_MICCLK, to CAM_GPIO on connector
	};

	cam_dummy_reg: cam_dummy_reg {
		compatible = "regulator-fixed";
		regulator-name = "cam-dummy-reg";
		status = "okay";
	};

	dummy: dummy {
		// A target for unwanted overlay fragments
	};


	// A few extra labels to keep overlays happy

	i2c0if: i2c0if {};
	i2c0mux: i2c0mux {};
};

rp1_target: &pcie2 {
	brcm,enable-mps-rcb;
	brcm,vdm-qos-map = <0xbbaa9888>;
	aspm-no-l0s;
	status = "okay";
};

// Add some labels to 2712 device

// The system UART
uart10: &_uart0 { status = "okay"; };

// The system SPI for the bootloader EEPROM
spi10: &_spi0 { status = "okay"; };

i2c_rp1boot: &_i2c3 { };

#include "rp1.dtsi"

&rp1 {
	// PCIe address space layout:
	// 00_00000000-00_00xxxxxx = RP1 peripherals
	// 10_00000000-1x_xxxxxxxx = up to 64GB system RAM

	// outbound access aimed at PCIe 0_00xxxxxx -> RP1 c0_40xxxxxx
	// This is the RP1 peripheral space
	ranges = <0xc0 0x40000000
		  0x02000000 0x00 0x00000000
		  0x00 0x00410000>;

	dma-ranges =
	// inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
		     <0x10 0x00000000
		      0x43000000 0x10 0x00000000
		      0x10 0x00000000>,

	// inbound RP1 c0_40xxxxxx -> PCIe 00_00xxxxxx
	// This allows the RP1 DMA controller to address RP1 hardware
		     <0xc0 0x40000000
		      0x02000000 0x0 0x00000000
		      0x0 0x00410000>,

	// inbound RP1 0x_xxxxxxxx -> PCIe 1x_xxxxxxxx
		     <0x00 0x00000000
		      0x02000000 0x10 0x00000000
		      0x10 0x00000000>;
};

// Expose RP1 nodes as system nodes with labels

&rp1_dma  {
	status = "okay";
};

&rp1_eth {
	status = "okay";
	phy-handle = <&phy1>;
	phy-reset-gpios = <&rp1_gpio 32 GPIO_ACTIVE_LOW>;
	phy-reset-duration = <5>;

	phy1: ethernet-phy@1 {
		reg = <0x1>;
		brcm,powerdown-enable;
		interrupt-parent = <&gpio>;
		interrupts = <37 IRQ_TYPE_LEVEL_LOW>;
	};
};

gpio: &rp1_gpio {
	status = "okay";
};

aux: &dummy {};

&rp1_usb0 {
	pinctrl-0 = <&usb_vbus_pins>;
	pinctrl-names = "default";
	status = "okay";
};

&rp1_usb1 {
	status = "okay";
};

#include "bcm2712-rpi.dtsi"

cam1_reg: &cam0_reg { // Shares CAM_GPIO with cam0_reg
};

csi0: &rp1_csi0 { };
csi1: &rp1_csi1 { };
dsi0: &rp1_dsi0 { };
dsi1: &rp1_dsi1 { };
dpi: &rp1_dpi { };
vec: &rp1_vec { };
dpi_gpio0:              &rp1_dpi_24bit_gpio0        { };
dpi_gpio1:              &rp1_dpi_24bit_gpio2        { };
dpi_18bit_cpadhi_gpio0: &rp1_dpi_18bit_cpadhi_gpio0 { };
dpi_18bit_cpadhi_gpio2: &rp1_dpi_18bit_cpadhi_gpio2 { };
dpi_18bit_gpio0:        &rp1_dpi_18bit_gpio0        { };
dpi_18bit_gpio2:        &rp1_dpi_18bit_gpio2        { };
dpi_16bit_cpadhi_gpio0: &rp1_dpi_16bit_cpadhi_gpio0 { };
dpi_16bit_cpadhi_gpio2: &rp1_dpi_16bit_cpadhi_gpio2 { };
dpi_16bit_gpio0:        &rp1_dpi_16bit_gpio0        { };
dpi_16bit_gpio2:        &rp1_dpi_16bit_gpio2        { };

/* Add the IOMMUs for some RP1 bus masters */

&csi0 {
	iommus = <&iommu5>;
};

&csi1 {
	iommus = <&iommu5>;
};

&dsi0 {
	iommus = <&iommu5>;
};

&dsi1 {
	iommus = <&iommu5>;
};

&dpi {
	iommus = <&iommu5>;
};

&vec {
	iommus = <&iommu5>;
};

&ddc0 {
	status = "disabled";
};

&ddc1 {
	status = "disabled";
};

&hdmi0 {
	clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>;
	clock-names = "hdmi", "bvb", "audio", "cec";
	status = "disabled";
};

&hdmi1 {
	clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
	clock-names = "hdmi", "bvb", "audio", "cec";
	status = "disabled";
};

&hvs {
	clocks = <&firmware_clocks 4>, <&firmware_clocks 16>;
	clock-names = "core", "disp";
};

&mop {
	status = "disabled";
};

&moplet {
	status = "disabled";
};

&pixelvalve0 {
	status = "disabled";
};

&pixelvalve1 {
	status = "disabled";
};

&disp_intr {
	status = "disabled";
};

/* SDIO1 is used to drive the eMMC/SD card */
&sdio1 {
	pinctrl-0 = <&emmc_cmddat_pulls>, <&emmc_ds_pull>;
	pinctrl-names = "default";
	vqmmc-supply = <&sd_io_1v8_reg>;
	vmmc-supply = <&sd_vcc_reg>;
	bus-width = <8>;
	sd-uhs-sdr50;
	sd-uhs-ddr50;
	sd-uhs-sdr104;
	mmc-hs200-1_8v;
	mmc-hs400-1_8v;
	mmc-hs400-enhanced-strobe;
	broken-cd;
	supports-cqe;
	status = "okay";
};

&pinctrl_aon {
	ant_pins: ant_pins {
		function = "gpio";
		pins = "aon_gpio5", "aon_gpio6";
	};

	/* Slight hack - only one PWM pin (status LED) is usable */
	aon_pwm_1pin: aon_pwm_1pin {
		function = "aon_pwm";
		pins = "aon_gpio9";
	};
};

&pinctrl {
	pwr_button_pins: pwr_button_pins {
		function = "gpio";
		pins = "gpio20";
		bias-pull-up;
	};

	wl_on_pins: wl_on_pins {
		function = "gpio";
		pins = "gpio28";
	};

	bt_shutdown_pins: bt_shutdown_pins {
		function = "gpio";
		pins = "gpio29";
	};

	emmc_ds_pull: emmc_ds_pull {
		pins = "emmc_ds";
		bias-pull-down;
	};

	emmc_cmddat_pulls: emmc_cmddat_pulls {
		pins = "emmc_cmd", "emmc_dat0", "emmc_dat1", "emmc_dat2", "emmc_dat3",
		       "emmc_dat4", "emmc_dat5", "emmc_dat6", "emmc_dat7";
		bias-pull-up;
	};
};

/* uarta communicates with the BT module */
&uarta {
	uart-has-rtscts;
	auto-flow-control;
	status = "okay";
	clock-frequency = <96000000>;
	pinctrl-0 = <&uarta_24_pins &bt_shutdown_pins>;
	pinctrl-names = "default";

	bluetooth: bluetooth {
		compatible = "brcm,bcm43438-bt";
		max-speed = <3000000>;
		shutdown-gpios = <&gio 29 GPIO_ACTIVE_HIGH>;
		local-bd-address = [ 00 00 00 00 00 00 ];
	};
};

&i2c_rp1boot {
	clock-frequency = <400000>;
	pinctrl-0 = <&i2c3_m4_agpio0_pins>;
	pinctrl-names = "default";
};

/ {
	fan: cooling_fan {
		status = "disabled";
		compatible = "pwm-fan";
		#cooling-cells = <2>;
		cooling-min-state = <0>;
		cooling-max-state = <3>;
		cooling-levels = <0 75 125 175 250>;
		pwms = <&rp1_pwm1 3 41566 PWM_POLARITY_INVERTED>;
		rpm-regmap = <&rp1_pwm1>;
		rpm-offset = <0x3c>;
	};

	pwr_button {
		compatible = "gpio-keys";

		pinctrl-names = "default";
		pinctrl-0 = <&pwr_button_pins>;
		status = "okay";

		pwr_key: pwr {
			label = "pwr_button";
			// linux,code = <205>; // KEY_SUSPEND
			linux,code = <116>; // KEY_POWER
			gpios = <&gio 20 GPIO_ACTIVE_LOW>;
			debounce-interval = <50>; // ms
		};
	};
};

&usb {
	power-domains = <&power RPI_POWER_DOMAIN_USB>;
};

/* SDIO2 drives the WLAN interface */
&sdio2 {
	pinctrl-0 = <&sdio2_30_pins>, <&ant_pins>;
	pinctrl-names = "default";
	bus-width = <4>;
	vmmc-supply = <&wl_on_reg>;
	sd-uhs-ddr50;
	non-removable;
	status = "okay";
	#address-cells = <1>;
	#size-cells = <0>;

	wifi: wifi@1 {
		reg = <1>;
		compatible = "brcm,bcm4329-fmac";
		local-mac-address = [00 00 00 00 00 00];
	};
};

&rpivid {
	status = "okay";
};

&pinctrl {
	spi10_gpio2: spi10_gpio2 {
		function = "vc_spi0";
		pins = "gpio2", "gpio3", "gpio4";
		bias-disable;
	};

	spi10_cs_gpio1: spi10_cs_gpio1 {
		function = "gpio";
		pins = "gpio1";
		bias-pull-up;
	};
};

spi10_pins: &spi10_gpio2 {};
spi10_cs_pins: &spi10_cs_gpio1 {};

&spi10 {
	pinctrl-names = "default";
	cs-gpios = <&gio 1 1>;
	pinctrl-0 = <&spi10_pins &spi10_cs_pins>;

	spidev10: spidev@0 {
		compatible = "spidev";
		reg = <0>;	/* CE0 */
		#address-cells = <1>;
		#size-cells = <0>;
		spi-max-frequency = <20000000>;
		status = "okay";
	};
};

// =============================================
// Board specific stuff here

&gio_aon {
	// Don't use GIO_AON as an interrupt controller because it will
	// clash with the firmware monitoring the PMIC interrupt via the VPU.

	/delete-property/ interrupt-controller;
};

&main_aon_irq {
	// Don't use the MAIN_AON_IRQ interrupt controller because it will
	// clash with the firmware monitoring the PMIC interrupt via the VPU.

	status = "disabled";
};

&rp1_pwm1 {
	status = "disabled";
	pinctrl-0 = <&rp1_pwm1_gpio45>;
	pinctrl-names = "default";
};

&thermal_trips {
	cpu_tepid: cpu-tepid {
		temperature = <50000>;
		hysteresis = <5000>;
		type = "active";
	};

	cpu_warm: cpu-warm {
		temperature = <60000>;
		hysteresis = <5000>;
		type = "active";
	};

	cpu_hot: cpu-hot {
		temperature = <67500>;
		hysteresis = <5000>;
		type = "active";
	};

	cpu_vhot: cpu-vhot {
		temperature = <75000>;
		hysteresis = <5000>;
		type = "active";
	};
};

&cooling_maps {
	tepid {
		trip = <&cpu_tepid>;
		cooling-device = <&fan 1 1>;
	};

	warm {
		trip = <&cpu_warm>;
		cooling-device = <&fan 2 2>;
	};

	hot {
		trip = <&cpu_hot>;
		cooling-device = <&fan 3 3>;
	};

	vhot {
		trip = <&cpu_vhot>;
		cooling-device = <&fan 4 4>;
	};

	melt {
		trip = <&cpu_crit>;
		cooling-device = <&fan 4 4>;
	};
};

&gio {
	// The GPIOs above 35 are not used on Pi 5, so shrink the upper bank
	// to reduce the clutter in gpioinfo/pinctrl
	brcm,gpio-bank-widths = <32 4>;

	gpio-line-names =
		"-", // GPIO_000
		"2712_BOOT_CS_N", // GPIO_001
		"2712_BOOT_MISO", // GPIO_002
		"2712_BOOT_MOSI", // GPIO_003
		"2712_BOOT_SCLK", // GPIO_004
		"-", // GPIO_005
		"-", // GPIO_006
		"-", // GPIO_007
		"-", // GPIO_008
		"-", // GPIO_009
		"-", // GPIO_010
		"-", // GPIO_011
		"-", // GPIO_012
		"-", // GPIO_013
		"-", // GPIO_014
		"-", // GPIO_015
		"-", // GPIO_016
		"-", // GPIO_017
		"-", // GPIO_018
		"-", // GPIO_019
		"PWR_GPIO", // GPIO_020
		"2712_G21_FS", // GPIO_021
		"-", // GPIO_022
		"-", // GPIO_023
		"BT_RTS", // GPIO_024
		"BT_CTS", // GPIO_025
		"BT_TXD", // GPIO_026
		"BT_RXD", // GPIO_027
		"WL_ON", // GPIO_028
		"BT_ON", // GPIO_029
		"WIFI_SDIO_CLK", // GPIO_030
		"WIFI_SDIO_CMD", // GPIO_031
		"WIFI_SDIO_D0", // GPIO_032
		"WIFI_SDIO_D1", // GPIO_033
		"WIFI_SDIO_D2", // GPIO_034
		"WIFI_SDIO_D3"; // GPIO_035
};

&gio_aon {
	gpio-line-names =
		"RP1_SDA", // AON_GPIO_00
		"RP1_SCL", // AON_GPIO_01
		"RP1_RUN", // AON_GPIO_02
		"SD_IOVDD_SEL", // AON_GPIO_03
		"SD_PWR_ON", // AON_GPIO_04
		"ANT1", // AON_GPIO_05
		"ANT2", // AON_GPIO_06
		"-", // AON_GPIO_07
		"2712_WAKE", // AON_GPIO_08
		"2712_STAT_LED", // AON_GPIO_09
		"-", // AON_GPIO_10
		"-", // AON_GPIO_11
		"PMIC_INT", // AON_GPIO_12
		"UART_TX_FS", // AON_GPIO_13
		"UART_RX_FS", // AON_GPIO_14
		"-", // AON_GPIO_15
		"-", // AON_GPIO_16

		// Pad bank0 out to 32 entries
		"", "", "", "", "", "", "", "", "", "", "", "", "", "", "",

		"HDMI0_SCL", // AON_SGPIO_00
		"HDMI0_SDA", // AON_SGPIO_01
		"HDMI1_SCL", // AON_SGPIO_02
		"HDMI1_SDA", // AON_SGPIO_03
		"PMIC_SCL", // AON_SGPIO_04
		"PMIC_SDA"; // AON_SGPIO_05

	rp1_run_hog {
		gpio-hog;
		gpios = <2 GPIO_ACTIVE_HIGH>;
		output-high;
		line-name = "RP1 RUN pin";
	};

	ant1: ant1-hog {
		gpio-hog;
		gpios = <5 GPIO_ACTIVE_HIGH>;
		/* internal antenna enabled */
		output-high;
		line-name = "ant1";
	};

	ant2: ant2-hog {
		gpio-hog;
		gpios = <6 GPIO_ACTIVE_HIGH>;
		/* external antenna disabled */
		output-low;
		line-name = "ant2";
	};
};

&rp1_gpio {
	gpio-line-names =
		"ID_SDA", // GPIO0
		"ID_SCL", // GPIO1
		"GPIO2", // GPIO2
		"GPIO3", // GPIO3
		"GPIO4", // GPIO4
		"GPIO5", // GPIO5
		"GPIO6", // GPIO6
		"GPIO7", // GPIO7
		"GPIO8", // GPIO8
		"GPIO9", // GPIO9
		"GPIO10", // GPIO10
		"GPIO11", // GPIO11
		"GPIO12", // GPIO12
		"GPIO13", // GPIO13
		"GPIO14", // GPIO14
		"GPIO15", // GPIO15
		"GPIO16", // GPIO16
		"GPIO17", // GPIO17
		"GPIO18", // GPIO18
		"GPIO19", // GPIO19
		"GPIO20", // GPIO20
		"GPIO21", // GPIO21
		"GPIO22", // GPIO22
		"GPIO23", // GPIO23
		"GPIO24", // GPIO24
		"GPIO25", // GPIO25
		"GPIO26", // GPIO26
		"GPIO27", // GPIO27

		"PCIE_PWR_EN", // GPIO28
		"FAN_TACH", // GPIO29
		"HOST_SDA", // GPIO30
		"HOST_SCL", // GPIO31
		"ETH_RST_N", // GPIO32
		"PCIE_DET_WAKE", // GPIO33

		"CD0_IO0_MICCLK", // GPIO34
		"CD0_IO0_MICDAT0", // GPIO35
		"RP1_PCIE_CLKREQ_N", // GPIO36
		"ETH_IRQ_N", // GPIO37
		"SDA0", // GPIO38
		"SCL0", // GPIO39
		"-", // GPIO40
		"-", // GPIO41
		"USB_VBUS_EN", // GPIO42
		"-", // GPIO43
		"RP1_STAT_LED", // GPIO44
		"FAN_PWM", // GPIO45
		"-", // GPIO46
		"2712_WAKE", // GPIO47
		"-", // GPIO48
		"-", // GPIO49
		"-", // GPIO50
		"-", // GPIO51
		"-", // GPIO52
		"-"; // GPIO53

	usb_vbus_pins: usb_vbus_pins {
		function = "vbus1";
		pins = "gpio42", "gpio43";
	};
};

/ {
	__overrides__ {
		ant1 =  <&ant1>,"output-high?=on",
			<&ant1>, "output-low?=off",
			<&ant2>, "output-high?=off",
			<&ant2>, "output-low?=on";
		ant2 =  <&ant1>,"output-high?=off",
			<&ant1>, "output-low?=on",
			<&ant2>, "output-high?=on",
			<&ant2>, "output-low?=off";
		noant = <&ant1>,"output-high?=off",
			<&ant1>, "output-low?=on",
			<&ant2>, "output-high?=off",
			<&ant2>, "output-low?=on";
	};
};
