Merge tag 'xilinx-for-v2022.07-rc1-v2' of https://source.denx.de/u-boot/custodians/u-boot-microblaze

Xilinx changes for v2022.07-rc1 v2

xilinx:
- Allow booting bigger kernels till 100MB

zynqmp:
- DT updates (reset IDs)
- Remove unneeded low level uart initialization from psu_init*
- Enable PWM features
- Add support for 1EG device

serial_zynq:
- Change fifo behavior in DEBUG mode

zynq_sdhci:
- Fix BASECLK setting calculation

clk_zynqmp:
- Add support for showing video clock

gpio:
- Update slg driver to handle DT flags

net:
- Update ethernet_id code to support also DM_ETH_PHY
- Add support for DM_ETH_PHY in gem driver
- Enable dynamic mode for SGMII config in gem driver

pwm:
- Add driver for cadence PWM

versal:
- Add support for reserved memory

firmware:
- Handle PD enabling for SPL
- Add support for IOUSLCR SGMII configurations

include:
- Sync phy.h with Linux
- Update xilinx power domain dt binding headers
diff --git a/MAINTAINERS b/MAINTAINERS
index f986530..0fc034f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -658,6 +658,7 @@
 F:	drivers/net/zynq_gem.c
 F:	drivers/phy/phy-zynqmp.c
 F:	drivers/power/domain/zynqmp-power-domain.c
+F:	drivers/pwm/pwm-cadence-ttc.c
 F:	drivers/serial/serial_zynq.c
 F:	drivers/reset/reset-zynqmp.c
 F:	drivers/rtc/zynqmp_rtc.c
diff --git a/arch/arm/dts/zynqmp.dtsi b/arch/arm/dts/zynqmp.dtsi
index 755a4ed..c442608 100644
--- a/arch/arm/dts/zynqmp.dtsi
+++ b/arch/arm/dts/zynqmp.dtsi
@@ -742,6 +742,7 @@
 			#clock-cells = <1>;
 			clock-output-names = "clk_out_sd0", "clk_in_sd0";
 			power-domains = <&zynqmp_firmware PD_SD_0>;
+			resets = <&zynqmp_reset ZYNQMP_RESET_SDIO0>;
 		};
 
 		sdhci1: mmc@ff170000 {
@@ -758,6 +759,7 @@
 			#clock-cells = <1>;
 			clock-output-names = "clk_out_sd1", "clk_in_sd1";
 			power-domains = <&zynqmp_firmware PD_SD_1>;
+			resets = <&zynqmp_reset ZYNQMP_RESET_SDIO1>;
 		};
 
 		smmu: iommu@fd800000 {
diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c
index 299e128..9940f2a 100644
--- a/board/xilinx/versal/board.c
+++ b/board/xilinx/versal/board.c
@@ -9,6 +9,7 @@
 #include <env.h>
 #include <fdtdec.h>
 #include <init.h>
+#include <image.h>
 #include <env_internal.h>
 #include <log.h>
 #include <malloc.h>
@@ -249,6 +250,25 @@
 	return 0;
 }
 
+ulong board_get_usable_ram_top(ulong total_size)
+{
+	phys_size_t size;
+	phys_addr_t reg;
+	struct lmb lmb;
+
+	/* found enough not-reserved memory to relocated U-Boot */
+	lmb_init(&lmb);
+	lmb_add(&lmb, gd->ram_base, gd->ram_size);
+	boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob);
+	size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE);
+	reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE);
+
+	if (!reg)
+		reg = gd->ram_top - size;
+
+	return reg + size;
+}
+
 void reset_cpu(void)
 {
 }
diff --git a/board/xilinx/zynqmp/zynqmp-dlc21-revA/psu_init_gpl.c b/board/xilinx/zynqmp/zynqmp-dlc21-revA/psu_init_gpl.c
index 528958d..dae81e6 100644
--- a/board/xilinx/zynqmp/zynqmp-dlc21-revA/psu_init_gpl.c
+++ b/board/xilinx/zynqmp/zynqmp-dlc21-revA/psu_init_gpl.c
@@ -509,10 +509,6 @@
 	psu_mask_write(0xFF5E0238, 0x00000008U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00007800U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00000002U, 0x00000000U);
-	psu_mask_write(0xFF000034, 0x000000FFU, 0x00000005U);
-	psu_mask_write(0xFF000018, 0x0000FFFFU, 0x0000008FU);
-	psu_mask_write(0xFF000000, 0x000001FFU, 0x00000017U);
-	psu_mask_write(0xFF000004, 0x000003FFU, 0x00000020U);
 	psu_mask_write(0xFF5E0238, 0x00040000U, 0x00000000U);
 	psu_mask_write(0xFF4B0024, 0x000000FFU, 0x000000FFU);
 	psu_mask_write(0xFFCA5000, 0x00001FFFU, 0x00000000U);
diff --git a/board/xilinx/zynqmp/zynqmp-e-a2197-00-revA/psu_init_gpl.c b/board/xilinx/zynqmp/zynqmp-e-a2197-00-revA/psu_init_gpl.c
index 348f0e7..40d9279 100644
--- a/board/xilinx/zynqmp/zynqmp-e-a2197-00-revA/psu_init_gpl.c
+++ b/board/xilinx/zynqmp/zynqmp-e-a2197-00-revA/psu_init_gpl.c
@@ -521,10 +521,6 @@
 	psu_mask_write(0xFF180324, 0x03C00000U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00000600U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00000002U, 0x00000000U);
-	psu_mask_write(0xFF000034, 0x000000FFU, 0x00000006U);
-	psu_mask_write(0xFF000018, 0x0000FFFFU, 0x0000007CU);
-	psu_mask_write(0xFF000000, 0x000001FFU, 0x00000017U);
-	psu_mask_write(0xFF000004, 0x000003FFU, 0x00000020U);
 	psu_mask_write(0xFF5E0238, 0x00040000U, 0x00000000U);
 	psu_mask_write(0xFF4B0024, 0x000000FFU, 0x000000FFU);
 	psu_mask_write(0xFFCA5000, 0x00001FFFU, 0x00000000U);
diff --git a/board/xilinx/zynqmp/zynqmp-topic-miamimp-xilinx-xdp-v1r1/psu_init_gpl.c b/board/xilinx/zynqmp/zynqmp-topic-miamimp-xilinx-xdp-v1r1/psu_init_gpl.c
index dbed7b7..333510b 100644
--- a/board/xilinx/zynqmp/zynqmp-topic-miamimp-xilinx-xdp-v1r1/psu_init_gpl.c
+++ b/board/xilinx/zynqmp/zynqmp-topic-miamimp-xilinx-xdp-v1r1/psu_init_gpl.c
@@ -522,14 +522,6 @@
 	psu_mask_write(0xFF5E0238, 0x00000018U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00007800U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00000006U, 0x00000000U);
-	psu_mask_write(0xFF000034, 0x000000FFU, 0x00000005U);
-	psu_mask_write(0xFF000018, 0x0000FFFFU, 0x0000008FU);
-	psu_mask_write(0xFF000000, 0x000001FFU, 0x00000017U);
-	psu_mask_write(0xFF000004, 0x000003FFU, 0x00000020U);
-	psu_mask_write(0xFF010034, 0x000000FFU, 0x00000005U);
-	psu_mask_write(0xFF010018, 0x0000FFFFU, 0x0000008FU);
-	psu_mask_write(0xFF010000, 0x000001FFU, 0x00000017U);
-	psu_mask_write(0xFF010004, 0x000003FFU, 0x00000020U);
 	psu_mask_write(0xFF5E0238, 0x00040000U, 0x00000000U);
 	psu_mask_write(0xFF4B0024, 0x000000FFU, 0x000000FFU);
 	psu_mask_write(0xFFCA5000, 0x00001FFFU, 0x00000000U);
diff --git a/board/xilinx/zynqmp/zynqmp-zcu102-rev1.1/psu_init_gpl.c b/board/xilinx/zynqmp/zynqmp-zcu102-rev1.1/psu_init_gpl.c
index 1f3f2e6..f1fdc7d 100644
--- a/board/xilinx/zynqmp/zynqmp-zcu102-rev1.1/psu_init_gpl.c
+++ b/board/xilinx/zynqmp/zynqmp-zcu102-rev1.1/psu_init_gpl.c
@@ -516,14 +516,6 @@
 	psu_mask_write(0xFF5E0238, 0x00008000U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00007800U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00000006U, 0x00000000U);
-	psu_mask_write(0xFF000034, 0x000000FFU, 0x0000000CU);
-	psu_mask_write(0xFF000018, 0x0000FFFFU, 0x0000003EU);
-	psu_mask_write(0xFF000000, 0x000001FFU, 0x00000017U);
-	psu_mask_write(0xFF000004, 0x000003FFU, 0x00000020U);
-	psu_mask_write(0xFF010034, 0x000000FFU, 0x0000000CU);
-	psu_mask_write(0xFF010018, 0x0000FFFFU, 0x0000003EU);
-	psu_mask_write(0xFF010000, 0x000001FFU, 0x00000017U);
-	psu_mask_write(0xFF010004, 0x000003FFU, 0x00000020U);
 	psu_mask_write(0xFF5E0238, 0x00040000U, 0x00000000U);
 	psu_mask_write(0xFF4B0024, 0x000000FFU, 0x000000FFU);
 	psu_mask_write(0xFFCA5000, 0x00001FFFU, 0x00000000U);
diff --git a/board/xilinx/zynqmp/zynqmp-zcu111-revA/psu_init_gpl.c b/board/xilinx/zynqmp/zynqmp-zcu111-revA/psu_init_gpl.c
index 7c6664d..8963aa4 100644
--- a/board/xilinx/zynqmp/zynqmp-zcu111-revA/psu_init_gpl.c
+++ b/board/xilinx/zynqmp/zynqmp-zcu111-revA/psu_init_gpl.c
@@ -512,14 +512,6 @@
 	psu_mask_write(0xFF5E0238, 0x00008000U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00007800U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00000006U, 0x00000000U);
-	psu_mask_write(0xFF000034, 0x000000FFU, 0x00000005U);
-	psu_mask_write(0xFF000018, 0x0000FFFFU, 0x0000008FU);
-	psu_mask_write(0xFF000000, 0x000001FFU, 0x00000017U);
-	psu_mask_write(0xFF000004, 0x000003FFU, 0x00000020U);
-	psu_mask_write(0xFF010034, 0x000000FFU, 0x00000005U);
-	psu_mask_write(0xFF010018, 0x0000FFFFU, 0x0000008FU);
-	psu_mask_write(0xFF010000, 0x000001FFU, 0x00000017U);
-	psu_mask_write(0xFF010004, 0x000003FFU, 0x00000020U);
 	psu_mask_write(0xFF5E0238, 0x00040000U, 0x00000000U);
 	psu_mask_write(0xFF4B0024, 0x000000FFU, 0x000000FFU);
 	psu_mask_write(0xFFCA5000, 0x00001FFFU, 0x00000000U);
diff --git a/board/xilinx/zynqmp/zynqmp-zcu208-revA/psu_init_gpl.c b/board/xilinx/zynqmp/zynqmp-zcu208-revA/psu_init_gpl.c
index f07e60a..2adcad0 100644
--- a/board/xilinx/zynqmp/zynqmp-zcu208-revA/psu_init_gpl.c
+++ b/board/xilinx/zynqmp/zynqmp-zcu208-revA/psu_init_gpl.c
@@ -513,10 +513,6 @@
 	psu_mask_write(0xFF5E0238, 0x00008000U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00007800U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00000002U, 0x00000000U);
-	psu_mask_write(0xFF000034, 0x000000FFU, 0x00000006U);
-	psu_mask_write(0xFF000018, 0x0000FFFFU, 0x0000007CU);
-	psu_mask_write(0xFF000000, 0x000001FFU, 0x00000017U);
-	psu_mask_write(0xFF000004, 0x000003FFU, 0x00000020U);
 	psu_mask_write(0xFF5E0238, 0x00040000U, 0x00000000U);
 	psu_mask_write(0xFF4B0024, 0x000000FFU, 0x000000FFU);
 	psu_mask_write(0xFFCA5000, 0x00001FFFU, 0x00000000U);
diff --git a/board/xilinx/zynqmp/zynqmp-zcu216-revA/psu_init_gpl.c b/board/xilinx/zynqmp/zynqmp-zcu216-revA/psu_init_gpl.c
index fc3605d..bd31687 100644
--- a/board/xilinx/zynqmp/zynqmp-zcu216-revA/psu_init_gpl.c
+++ b/board/xilinx/zynqmp/zynqmp-zcu216-revA/psu_init_gpl.c
@@ -513,10 +513,6 @@
 	psu_mask_write(0xFF5E0238, 0x00008000U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00007800U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x00000002U, 0x00000000U);
-	psu_mask_write(0xFF000034, 0x000000FFU, 0x00000006U);
-	psu_mask_write(0xFF000018, 0x0000FFFFU, 0x0000007CU);
-	psu_mask_write(0xFF000000, 0x000001FFU, 0x00000017U);
-	psu_mask_write(0xFF000004, 0x000003FFU, 0x00000020U);
 	psu_mask_write(0xFF5E0238, 0x00040000U, 0x00000000U);
 	psu_mask_write(0xFF4B0024, 0x000000FFU, 0x000000FFU);
 	psu_mask_write(0xFFCA5000, 0x00001FFFU, 0x00000000U);
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index bc20909..e7e8e91 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -70,6 +70,11 @@
 	u8 variants;
 } zynqmp_devices[] = {
 	{
+		.id = 0x04688093,
+		.device = 1,
+		.variants = ZYNQMP_VARIANT_EG,
+	},
+	{
 		.id = 0x04711093,
 		.device = 2,
 		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig
index 3e6b1ec..990f518 100644
--- a/configs/xilinx_zynqmp_virt_defconfig
+++ b/configs/xilinx_zynqmp_virt_defconfig
@@ -53,6 +53,7 @@
 CONFIG_CMD_FPGA_LOADP=y
 CONFIG_CMD_FPGA_LOAD_SECURE=y
 CONFIG_CMD_GPIO=y
+CONFIG_CMD_PWM=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
@@ -164,6 +165,8 @@
 CONFIG_ZYNQ_GEM=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_CADENCE_TTC=y
 CONFIG_DM_RTC=y
 CONFIG_RTC_EMULATION=y
 CONFIG_RTC_ZYNQMP=y
diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c
index 9038fb8..45c679a 100644
--- a/drivers/clk/clk_zynqmp.c
+++ b/drivers/clk/clk_zynqmp.c
@@ -238,6 +238,12 @@
 		return CRF_APB_DBG_TRACE_CTRL;
 	case dbg_tstmp:
 		return CRF_APB_DBG_TSTMP_CTRL;
+	case dp_video_ref:
+		return CRF_APB_DP_VIDEO_REF_CTRL;
+	case dp_audio_ref:
+		return CRF_APB_DP_AUDIO_REF_CTRL;
+	case dp_stc_ref:
+		return CRF_APB_DP_STC_REF_CTRL;
 	case gpu_ref ...  gpu_pp1_ref:
 		return CRF_APB_GPU_REF_CTRL;
 	case ddr_ref:
@@ -673,6 +679,7 @@
 	case dll_ref:
 		return zynqmp_clk_get_dll_rate(priv);
 	case gem_tsu_ref:
+	case dp_video_ref ... dp_stc_ref:
 	case pl0 ... pl3:
 	case gem0_ref ... gem3_ref:
 	case gem0_tx ... gem3_tx:
diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index 8916c55..0f0d2b0 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -140,6 +140,19 @@
 	return pm_api_version;
 };
 
+int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config, u32 value)
+{
+	int ret;
+
+	ret = xilinx_pm_request(PM_IOCTL, node, IOCTL_SET_GEM_CONFIG,
+				config, value, NULL);
+	if (ret)
+		printf("%s: node %d: set_gem_config %d failed\n",
+		       __func__, node, config);
+
+	return ret;
+}
+
 int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value)
 {
 	int ret;
@@ -334,7 +347,11 @@
 	int ret;
 	struct udevice *child;
 
-	if (IS_ENABLED(CONFIG_ZYNQMP_POWER_DOMAIN)) {
+	if ((IS_ENABLED(CONFIG_SPL_BUILD) &&
+	     IS_ENABLED(CONFIG_SPL_POWER_DOMAIN) &&
+	     IS_ENABLED(CONFIG_ZYNQMP_POWER_DOMAIN)) ||
+	     (!IS_ENABLED(CONFIG_SPL_BUILD) &&
+	      IS_ENABLED(CONFIG_ZYNQMP_POWER_DOMAIN))) {
 		ret = device_bind_driver_to_node(dev, "zynqmp_power_domain",
 						 "zynqmp_power_domain",
 						 dev_ofnode(dev), &child);
diff --git a/drivers/gpio/gpio_slg7xl45106.c b/drivers/gpio/gpio_slg7xl45106.c
index 2cbf748..4ad06c1 100644
--- a/drivers/gpio/gpio_slg7xl45106.c
+++ b/drivers/gpio/gpio_slg7xl45106.c
@@ -11,6 +11,7 @@
 #include <asm/gpio.h>
 #include <dm.h>
 #include <i2c.h>
+#include <dt-bindings/gpio/gpio.h>
 #include <asm/arch/hardware.h>
 
 #define SLG7XL45106_REG		0xdb
@@ -26,6 +27,7 @@
 				     struct ofnode_phandle_args *args)
 {
 	desc->offset = (unsigned int)args->args[0];
+	desc->flags = (args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0);
 
 	return 0;
 }
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index d96f5d5..a59d96c 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -765,6 +765,15 @@
 
 	mhz = DIV64_U64_ROUND_UP(clock, 1000000);
 
+	if (mhz > 100 && mhz <= 200)
+		mhz = 200;
+	else if (mhz > 50 && mhz <= 100)
+		mhz = 100;
+	else if (mhz > 25 && mhz <= 50)
+		mhz = 50;
+	else
+		mhz = 25;
+
 	ret = zynqmp_pm_set_sd_config(node_id, SD_CONFIG_BASECLK, mhz);
 	if (ret) {
 		dev_err(dev, "SD_CONFIG_BASECLK failed\n");
diff --git a/drivers/net/phy/ethernet_id.c b/drivers/net/phy/ethernet_id.c
index 5617ac3..1a78a75 100644
--- a/drivers/net/phy/ethernet_id.c
+++ b/drivers/net/phy/ethernet_id.c
@@ -12,7 +12,7 @@
 #include <asm/gpio.h>
 
 struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev,
-				      phy_interface_t interface)
+				      int phyaddr, phy_interface_t interface)
 {
 	struct phy_device *phydev;
 	struct ofnode_phandle_args phandle_args;
@@ -33,35 +33,42 @@
 
 	ret = ofnode_read_eth_phy_id(node, &vendor, &device);
 	if (ret) {
-		dev_err(dev, "Failed to read eth PHY id, err: %d\n", ret);
+		debug("Failed to read eth PHY id, err: %d\n", ret);
 		return NULL;
 	}
 
-	ret = gpio_request_by_name_nodev(node, "reset-gpios", 0, &gpio,
-					 GPIOD_ACTIVE_LOW);
-	if (!ret) {
-		assert = ofnode_read_u32_default(node, "reset-assert-us", 0);
-		deassert = ofnode_read_u32_default(node,
-						   "reset-deassert-us", 0);
-		ret = dm_gpio_set_value(&gpio, 1);
-		if (ret) {
-			dev_err(dev, "Failed assert gpio, err: %d\n", ret);
-			return NULL;
+	if (!IS_ENABLED(CONFIG_DM_ETH_PHY)) {
+		ret = gpio_request_by_name_nodev(node, "reset-gpios", 0, &gpio,
+						 GPIOD_ACTIVE_LOW);
+		if (!ret) {
+			assert = ofnode_read_u32_default(node,
+							 "reset-assert-us", 0);
+			deassert = ofnode_read_u32_default(node,
+							   "reset-deassert-us",
+							   0);
+			ret = dm_gpio_set_value(&gpio, 1);
+			if (ret) {
+				dev_err(dev,
+					"Failed assert gpio, err: %d\n", ret);
+				return NULL;
+			}
+
+			udelay(assert);
+
+			ret = dm_gpio_set_value(&gpio, 0);
+			if (ret) {
+				dev_err(dev,
+					"Failed deassert gpio, err: %d\n",
+					ret);
+				return NULL;
+			}
+
+			udelay(deassert);
 		}
-
-		udelay(assert);
-
-		ret = dm_gpio_set_value(&gpio, 0);
-		if (ret) {
-			dev_err(dev, "Failed deassert gpio, err: %d\n", ret);
-			return NULL;
-		}
-
-		udelay(deassert);
 	}
 
 	id =  vendor << 16 | device;
-	phydev = phy_device_create(bus, 0, id, false, interface);
+	phydev = phy_device_create(bus, phyaddr, id, false, interface);
 	if (phydev)
 		phydev->node = node;
 
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 92fff5b..d473186 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1049,7 +1049,7 @@
 
 #ifdef CONFIG_PHY_ETHERNET_ID
 	if (!phydev)
-		phydev = phy_connect_phy_id(bus, dev, interface);
+		phydev = phy_connect_phy_id(bus, dev, addr, interface);
 #endif
 
 #ifdef CONFIG_PHY_XILINX_GMII2RGMII
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 3118d14..4c83ccc 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -33,6 +33,8 @@
 #include <linux/bitops.h>
 #include <linux/err.h>
 #include <linux/errno.h>
+#include <eth_phy.h>
+#include <zynqmp_firmware.h>
 
 /* Bit/mask specification */
 #define ZYNQ_GEM_PHYMNTNC_OP_MASK	0x40020000 /* operation mask bits */
@@ -321,6 +323,9 @@
 	/* Enable only MDIO bus */
 	writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, &regs_mdio->nwctrl);
 
+	if (IS_ENABLED(CONFIG_DM_ETH_PHY))
+		priv->phyaddr = eth_phy_get_addr(dev);
+
 	priv->phydev = phy_connect(priv->bus, priv->phyaddr, dev,
 				   priv->interface);
 	if (!priv->phydev)
@@ -710,6 +715,40 @@
 	return 0;
 }
 
+static int gem_zynqmp_set_dynamic_config(struct udevice *dev)
+{
+	u32 pm_info[2];
+	int ret;
+
+	if (IS_ENABLED(CONFIG_ARCH_ZYNQMP)) {
+		if (!zynqmp_pm_is_function_supported(PM_IOCTL,
+						     IOCTL_SET_GEM_CONFIG)) {
+			ret = ofnode_read_u32_array(dev_ofnode(dev),
+						    "power-domains",
+						    pm_info,
+						    ARRAY_SIZE(pm_info));
+			if (ret) {
+				dev_err(dev,
+					"Failed to read power-domains info\n");
+				return ret;
+			}
+
+			ret = zynqmp_pm_set_gem_config(pm_info[1],
+						       GEM_CONFIG_FIXED, 0);
+			if (ret)
+				return ret;
+
+			ret = zynqmp_pm_set_gem_config(pm_info[1],
+						       GEM_CONFIG_SGMII_MODE,
+						       1);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
 static int zynq_gem_probe(struct udevice *dev)
 {
 	void *bd_space;
@@ -771,25 +810,48 @@
 		}
 	}
 
-	priv->bus = mdio_alloc();
-	priv->bus->read = zynq_gem_miiphy_read;
-	priv->bus->write = zynq_gem_miiphy_write;
-	priv->bus->priv = priv;
+	if (IS_ENABLED(CONFIG_DM_ETH_PHY))
+		priv->bus = eth_phy_get_mdio_bus(dev);
 
-	ret = mdio_register_seq(priv->bus, dev_seq(dev));
-	if (ret)
-		goto err2;
+	if (!priv->bus) {
+		priv->bus = mdio_alloc();
+		priv->bus->read = zynq_gem_miiphy_read;
+		priv->bus->write = zynq_gem_miiphy_write;
+		priv->bus->priv = priv;
+
+		ret = mdio_register_seq(priv->bus, dev_seq(dev));
+		if (ret)
+			goto err2;
+	}
+
+	if (IS_ENABLED(CONFIG_DM_ETH_PHY))
+		eth_phy_set_mdio_bus(dev, priv->bus);
 
 	ret = zynq_phy_init(dev);
 	if (ret)
 		goto err3;
 
 	if (priv->interface == PHY_INTERFACE_MODE_SGMII && phy.dev) {
+		if (IS_ENABLED(CONFIG_DM_ETH_PHY)) {
+			if (device_is_compatible(dev, "cdns,zynqmp-gem")) {
+				ret = gem_zynqmp_set_dynamic_config(dev);
+				if (ret) {
+					dev_err
+					(dev,
+					 "Failed to set gem dynamic config\n");
+					return ret;
+				}
+			}
+		}
 		ret = generic_phy_power_on(&phy);
 		if (ret)
 			return ret;
 	}
 
+	printf("\nZYNQ GEM: %lx, mdio bus %lx, phyaddr %d, interface %s\n",
+	       (ulong)priv->iobase, (ulong)priv->mdiobase, priv->phydev->addr,
+	       phy_string_for_interface(priv->interface));
+
 	return ret;
 
 err3:
@@ -841,8 +903,10 @@
 		ofnode parent;
 
 		debug("phy-handle does exist %s\n", dev->name);
-		priv->phyaddr = ofnode_read_u32_default(phandle_args.node,
-							"reg", -1);
+		if (!(IS_ENABLED(CONFIG_DM_ETH_PHY)))
+			priv->phyaddr = ofnode_read_u32_default
+					(phandle_args.node, "reg", -1);
+
 		priv->phy_of_node = phandle_args.node;
 		priv->max_speed = ofnode_read_u32_default(phandle_args.node,
 							  "max-speed",
@@ -870,10 +934,6 @@
 
 	priv->int_pcs = dev_read_bool(dev, "is-internal-pcspma");
 
-	printf("\nZYNQ GEM: %lx, mdio bus %lx, phyaddr %d, interface %s\n",
-	       (ulong)priv->iobase, (ulong)priv->mdiobase, priv->phyaddr,
-	       phy_string_for_interface(priv->interface));
-
 	priv->clk_en_info = dev_get_driver_data(dev);
 
 	return 0;
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 6be612d..cb54e67 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -23,6 +23,13 @@
 	help
 	  Support for PWM hardware on AT91 based SoC.
 
+config PWM_CADENCE_TTC
+	bool "Enable support for the Cadence TTC PWM"
+	depends on DM_PWM && !CADENCE_TTC_TIMER
+	help
+	  Cadence TTC can be configured as timer which is done via
+	  CONFIG_CADENCE_TTC_TIMER or as PWM. This is covering only PWM now.
+
 config PWM_CROS_EC
 	bool "Enable support for the Chrome OS EC PWM"
 	depends on DM_PWM
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 5d31812..bd119a6 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -12,6 +12,7 @@
 
 obj-$(CONFIG_PWM_ASPEED)	+= pwm-aspeed.o
 obj-$(CONFIG_PWM_AT91)		+= pwm-at91.o
+obj-$(CONFIG_PWM_CADENCE_TTC)	+= pwm-cadence-ttc.o
 obj-$(CONFIG_PWM_CROS_EC)	+= cros_ec_pwm.o
 obj-$(CONFIG_PWM_EXYNOS)	+= exynos_pwm.o
 obj-$(CONFIG_PWM_IMX)		+= pwm-imx.o pwm-imx-util.o
diff --git a/drivers/pwm/pwm-cadence-ttc.c b/drivers/pwm/pwm-cadence-ttc.c
new file mode 100644
index 0000000..dc3b314
--- /dev/null
+++ b/drivers/pwm/pwm-cadence-ttc.c
@@ -0,0 +1,261 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2021 Xilinx, Inc. Michal Simek
+ */
+
+#define LOG_CATEGORY UCLASS_PWM
+
+#include <clk.h>
+#include <common.h>
+#include <div64.h>
+#include <dm.h>
+#include <log.h>
+#include <pwm.h>
+#include <asm/io.h>
+#include <log.h>
+#include <div64.h>
+#include <linux/bitfield.h>
+#include <linux/math64.h>
+#include <linux/log2.h>
+#include <dm/device_compat.h>
+
+#define CLOCK_CONTROL		0
+#define COUNTER_CONTROL		0xc
+#define INTERVAL_COUNTER	0x24
+#define MATCH_1_COUNTER		0x30
+
+#define CLK_FALLING_EDGE	BIT(6)
+#define CLK_SRC_EXTERNAL	BIT(5)
+#define CLK_PRESCALE_MASK	GENMASK(4, 1)
+#define CLK_PRESCALE_ENABLE	BIT(0)
+
+#define COUNTER_WAVE_POL		BIT(6)
+#define COUNTER_WAVE_DISABLE		BIT(5)
+#define COUNTER_RESET			BIT(4)
+#define COUNTER_MATCH_ENABLE		BIT(3)
+#define COUNTER_DECREMENT_ENABLE	BIT(2)
+#define COUNTER_INTERVAL_ENABLE		BIT(1)
+#define COUNTER_COUNTING_DISABLE	BIT(0)
+
+#define NSEC_PER_SEC	1000000000L
+
+#define TTC_REG(reg, channel) ((reg) + (channel) * sizeof(u32))
+#define TTC_CLOCK_CONTROL(reg, channel) \
+	TTC_REG((reg) + CLOCK_CONTROL, (channel))
+#define TTC_COUNTER_CONTROL(reg, channel) \
+	TTC_REG((reg) + COUNTER_CONTROL, (channel))
+#define TTC_INTERVAL_COUNTER(reg, channel) \
+	TTC_REG((reg) + INTERVAL_COUNTER, (channel))
+#define TTC_MATCH_1_COUNTER(reg, channel) \
+	TTC_REG((reg) + MATCH_1_COUNTER, (channel))
+
+struct cadence_ttc_pwm_plat {
+	u8 *regs;
+	u32 timer_width;
+};
+
+struct cadence_ttc_pwm_priv {
+	u8 *regs;
+	u32 timer_width;
+	u32 timer_mask;
+	unsigned long frequency;
+	bool invert[2];
+};
+
+static int cadence_ttc_pwm_set_invert(struct udevice *dev, uint channel,
+				      bool polarity)
+{
+	struct cadence_ttc_pwm_priv *priv = dev_get_priv(dev);
+
+	if (channel > 2) {
+		dev_err(dev, "Unsupported channel number %d(max 2)\n", channel);
+		return -EINVAL;
+	}
+
+	priv->invert[channel] = polarity;
+
+	dev_dbg(dev, "polarity=%u. Please config PWM again\n", polarity);
+
+	return 0;
+}
+
+static int cadence_ttc_pwm_set_config(struct udevice *dev, uint channel,
+				      uint period_ns, uint duty_ns)
+{
+	struct cadence_ttc_pwm_priv *priv = dev_get_priv(dev);
+	u32 counter_ctrl, clock_ctrl;
+	int period_clocks, duty_clocks, prescaler;
+
+	dev_dbg(dev, "channel %d, duty %d/period %d ns\n", channel,
+		duty_ns, period_ns);
+
+	if (channel > 2) {
+		dev_err(dev, "Unsupported channel number %d(max 2)\n", channel);
+		return -EINVAL;
+	}
+
+	/* Make sure counter is stopped */
+	counter_ctrl = readl(TTC_COUNTER_CONTROL(priv->regs, channel));
+	setbits_le32(TTC_COUNTER_CONTROL(priv->regs, channel),
+		     COUNTER_COUNTING_DISABLE | COUNTER_WAVE_DISABLE);
+
+	/* Calculate period, prescaler and set clock control register */
+	period_clocks = div64_u64(((int64_t)period_ns * priv->frequency),
+				  NSEC_PER_SEC);
+
+	prescaler = ilog2(period_clocks) + 1 - priv->timer_width;
+	if (prescaler < 0)
+		prescaler = 0;
+
+	clock_ctrl = readl(TTC_CLOCK_CONTROL(priv->regs, channel));
+
+	if (!prescaler) {
+		clock_ctrl &= ~(CLK_PRESCALE_ENABLE | CLK_PRESCALE_MASK);
+	} else {
+		clock_ctrl &= ~CLK_PRESCALE_MASK;
+		clock_ctrl |= CLK_PRESCALE_ENABLE;
+		clock_ctrl |= FIELD_PREP(CLK_PRESCALE_MASK, prescaler - 1);
+	};
+
+	/* External source is not handled by this driver now */
+	clock_ctrl &= ~CLK_SRC_EXTERNAL;
+
+	writel(clock_ctrl, TTC_CLOCK_CONTROL(priv->regs, channel));
+
+	/* Calculate interval and set counter control value */
+	duty_clocks = div64_u64(((int64_t)duty_ns * priv->frequency),
+				NSEC_PER_SEC);
+
+	writel((period_clocks >> prescaler) & priv->timer_mask,
+	       TTC_INTERVAL_COUNTER(priv->regs, channel));
+	writel((duty_clocks >> prescaler) & priv->timer_mask,
+	       TTC_MATCH_1_COUNTER(priv->regs, channel));
+
+	/* Restore/reset counter */
+	counter_ctrl &= ~COUNTER_DECREMENT_ENABLE;
+	counter_ctrl |= COUNTER_INTERVAL_ENABLE |
+			COUNTER_RESET |
+			COUNTER_MATCH_ENABLE;
+
+	if (priv->invert[channel])
+		counter_ctrl |= COUNTER_WAVE_POL;
+	else
+		counter_ctrl &= ~COUNTER_WAVE_POL;
+
+	writel(counter_ctrl, TTC_COUNTER_CONTROL(priv->regs, channel));
+
+	dev_dbg(dev, "%d/%d clocks, prescaler 2^%d\n", duty_clocks,
+		period_clocks, prescaler);
+
+	return 0;
+};
+
+static int cadence_ttc_pwm_set_enable(struct udevice *dev, uint channel,
+				      bool enable)
+{
+	struct cadence_ttc_pwm_priv *priv = dev_get_priv(dev);
+
+	if (channel > 2) {
+		dev_err(dev, "Unsupported channel number %d(max 2)\n", channel);
+		return -EINVAL;
+	}
+
+	dev_dbg(dev, "Enable: %d, channel %d\n", enable, channel);
+
+	if (enable) {
+		clrbits_le32(TTC_COUNTER_CONTROL(priv->regs, channel),
+			     COUNTER_COUNTING_DISABLE |
+			     COUNTER_WAVE_DISABLE);
+		setbits_le32(TTC_COUNTER_CONTROL(priv->regs, channel),
+			     COUNTER_RESET);
+	} else {
+		setbits_le32(TTC_COUNTER_CONTROL(priv->regs, channel),
+			     COUNTER_COUNTING_DISABLE |
+			     COUNTER_WAVE_DISABLE);
+	}
+
+	return 0;
+};
+
+static int cadence_ttc_pwm_probe(struct udevice *dev)
+{
+	struct cadence_ttc_pwm_priv *priv = dev_get_priv(dev);
+	struct cadence_ttc_pwm_plat *plat = dev_get_plat(dev);
+	struct clk clk;
+	int ret;
+
+	priv->regs = plat->regs;
+	priv->timer_width = plat->timer_width;
+	priv->timer_mask = GENMASK(priv->timer_width - 1, 0);
+
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to get clock\n");
+		return ret;
+	}
+
+	priv->frequency = clk_get_rate(&clk);
+	if (IS_ERR_VALUE(priv->frequency)) {
+		dev_err(dev, "failed to get rate\n");
+		return priv->frequency;
+	}
+	dev_dbg(dev, "Clk frequency: %ld\n", priv->frequency);
+
+	ret = clk_enable(&clk);
+	if (ret) {
+		dev_err(dev, "failed to enable clock\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int cadence_ttc_pwm_of_to_plat(struct udevice *dev)
+{
+	struct cadence_ttc_pwm_plat *plat = dev_get_plat(dev);
+	const char *cells;
+
+	cells = dev_read_prop(dev, "#pwm-cells", NULL);
+	if (!cells)
+		return -EINVAL;
+
+	plat->regs = dev_read_addr_ptr(dev);
+
+	plat->timer_width = dev_read_u32_default(dev, "timer-width", 16);
+
+	return 0;
+}
+
+static int cadence_ttc_pwm_bind(struct udevice *dev)
+{
+	const char *cells;
+
+	cells = dev_read_prop(dev, "#pwm-cells", NULL);
+	if (!cells)
+		return -ENODEV;
+
+	return 0;
+}
+
+static const struct pwm_ops cadence_ttc_pwm_ops = {
+	.set_invert = cadence_ttc_pwm_set_invert,
+	.set_config = cadence_ttc_pwm_set_config,
+	.set_enable = cadence_ttc_pwm_set_enable,
+};
+
+static const struct udevice_id cadence_ttc_pwm_ids[] = {
+	{ .compatible = "cdns,ttc" },
+	{ }
+};
+
+U_BOOT_DRIVER(cadence_ttc_pwm) = {
+	.name = "cadence_ttc_pwm",
+	.id = UCLASS_PWM,
+	.of_match = cadence_ttc_pwm_ids,
+	.ops = &cadence_ttc_pwm_ops,
+	.bind = cadence_ttc_pwm_bind,
+	.of_to_plat = cadence_ttc_pwm_of_to_plat,
+	.probe = cadence_ttc_pwm_probe,
+	.priv_auto = sizeof(struct cadence_ttc_pwm_priv),
+	.plat_auto = sizeof(struct cadence_ttc_pwm_plat),
+};
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index fd99936..6bb003d 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -21,6 +21,7 @@
 
 #define ZYNQ_UART_SR_TXACTIVE	BIT(11) /* TX active */
 #define ZYNQ_UART_SR_TXFULL	BIT(4) /* TX FIFO full */
+#define ZYNQ_UART_SR_TXEMPTY	BIT(3) /* TX FIFO empty */
 #define ZYNQ_UART_SR_RXEMPTY	BIT(1) /* RX FIFO empty */
 
 #define ZYNQ_UART_CR_TX_EN	BIT(4) /* TX enabled */
@@ -107,8 +108,13 @@
 
 static int _uart_zynq_serial_putc(struct uart_zynq *regs, const char c)
 {
-	if (readl(&regs->channel_sts) & ZYNQ_UART_SR_TXFULL)
-		return -EAGAIN;
+	if (CONFIG_IS_ENABLED(DEBUG_UART_ZYNQ)) {
+		if (!(readl(&regs->channel_sts) & ZYNQ_UART_SR_TXEMPTY))
+			return -EAGAIN;
+	} else {
+		if (readl(&regs->channel_sts) & ZYNQ_UART_SR_TXFULL)
+			return -EAGAIN;
+	}
 
 	writel(c, &regs->tx_rx_fifo);
 
diff --git a/drivers/timer/cadence-ttc.c b/drivers/timer/cadence-ttc.c
index 2f95d45..2eff450 100644
--- a/drivers/timer/cadence-ttc.c
+++ b/drivers/timer/cadence-ttc.c
@@ -97,6 +97,17 @@
 	return 0;
 }
 
+static int cadence_ttc_bind(struct udevice *dev)
+{
+	const char *cells;
+
+	cells = dev_read_prop(dev, "#pwm-cells", NULL);
+	if (cells)
+		return -ENODEV;
+
+	return 0;
+}
+
 static const struct timer_ops cadence_ttc_ops = {
 	.get_count = cadence_ttc_get_count,
 };
@@ -114,4 +125,5 @@
 	.priv_auto	= sizeof(struct cadence_ttc_priv),
 	.probe = cadence_ttc_probe,
 	.ops = &cadence_ttc_ops,
+	.bind = cadence_ttc_bind,
 };
diff --git a/include/configs/xilinx_versal.h b/include/configs/xilinx_versal.h
index 60df795..80e9411 100644
--- a/include/configs/xilinx_versal.h
+++ b/include/configs/xilinx_versal.h
@@ -43,7 +43,7 @@
 # define PHY_ANEG_TIMEOUT       20000
 #endif
 
-#define CONFIG_SYS_BOOTM_LEN	(60 * 1024 * 1024)
+#define CONFIG_SYS_BOOTM_LEN	(100 * 1024 * 1024)
 
 #define ENV_MEM_LAYOUT_SETTINGS \
 	"fdt_addr_r=0x40000000\0" \
diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h
index a063c01..1985a09 100644
--- a/include/configs/xilinx_zynqmp.h
+++ b/include/configs/xilinx_zynqmp.h
@@ -58,7 +58,7 @@
 # define PHY_ANEG_TIMEOUT       20000
 #endif
 
-#define CONFIG_SYS_BOOTM_LEN	(60 * 1024 * 1024)
+#define CONFIG_SYS_BOOTM_LEN	(100 * 1024 * 1024)
 
 #define ENV_MEM_LAYOUT_SETTINGS \
 	"fdt_addr_r=0x40000000\0" \
diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h
index d3714ed..f48c9ac 100644
--- a/include/dt-bindings/phy/phy.h
+++ b/include/dt-bindings/phy/phy.h
@@ -1,10 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
 /*
  *
  * This header provides constants for the phy framework
  *
  * Copyright (C) 2014 STMicroelectronics
  * Author: Gabriel Fernandez <gabriel.fernandez@st.com>
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #ifndef _DT_BINDINGS_PHY
@@ -20,5 +20,7 @@
 #define PHY_TYPE_XPCS		7
 #define PHY_TYPE_SGMII		8
 #define PHY_TYPE_QSGMII		9
+#define PHY_TYPE_DPHY		10
+#define PHY_TYPE_CPHY		11
 
 #endif /* _DT_BINDINGS_PHY */
diff --git a/include/dt-bindings/power/xlnx-versal-power.h b/include/dt-bindings/power/xlnx-versal-power.h
index 4a72775..51d1def 100644
--- a/include/dt-bindings/power/xlnx-versal-power.h
+++ b/include/dt-bindings/power/xlnx-versal-power.h
@@ -6,6 +6,16 @@
 #ifndef _DT_BINDINGS_VERSAL_POWER_H
 #define _DT_BINDINGS_VERSAL_POWER_H
 
+#define PM_DEV_RPU0_0				(0x18110005U)
+#define PM_DEV_RPU0_1				(0x18110006U)
+#define PM_DEV_OCM_0				(0x18314007U)
+#define PM_DEV_OCM_1				(0x18314008U)
+#define PM_DEV_OCM_2				(0x18314009U)
+#define PM_DEV_OCM_3				(0x1831400aU)
+#define PM_DEV_TCM_0_A				(0x1831800bU)
+#define PM_DEV_TCM_0_B				(0x1831800cU)
+#define PM_DEV_TCM_1_A				(0x1831800dU)
+#define PM_DEV_TCM_1_B				(0x1831800eU)
 #define PM_DEV_USB_0				(0x18224018U)
 #define PM_DEV_GEM_0				(0x18224019U)
 #define PM_DEV_GEM_1				(0x1822401aU)
@@ -38,6 +48,7 @@
 #define PM_DEV_ADMA_5				(0x1822403aU)
 #define PM_DEV_ADMA_6				(0x1822403bU)
 #define PM_DEV_ADMA_7				(0x1822403cU)
+#define PM_DEV_AMS_ROOT				(0x18224055U)
 #define PM_DEV_AI				(0x18224072U)
 
 #endif
diff --git a/include/dt-bindings/power/xlnx-zynqmp-power.h b/include/dt-bindings/power/xlnx-zynqmp-power.h
index 0d9a412..e7eb096 100644
--- a/include/dt-bindings/power/xlnx-zynqmp-power.h
+++ b/include/dt-bindings/power/xlnx-zynqmp-power.h
@@ -6,6 +6,16 @@
 #ifndef _DT_BINDINGS_ZYNQMP_POWER_H
 #define _DT_BINDINGS_ZYNQMP_POWER_H
 
+#define		PD_RPU_0	6
+#define		PD_RPU_1	7
+#define		PD_OCM_BANK_0	11
+#define		PD_OCM_BANK_1	12
+#define		PD_OCM_BANK_2	13
+#define		PD_OCM_BANK_3	14
+#define		PD_TCM_BANK_0	15
+#define		PD_TCM_BANK_1	16
+#define		PD_TCM_BANK_2	17
+#define		PD_TCM_BANK_3	18
 #define		PD_USB_0	22
 #define		PD_USB_1	23
 #define		PD_TTC_0	24
@@ -35,5 +45,6 @@
 #define		PD_CAN_1	48
 #define		PD_GPU		58
 #define		PD_PCIE		59
+#define		PD_PL		69
 
 #endif
diff --git a/include/phy.h b/include/phy.h
index 9ea4bd4..5e3da4b 100644
--- a/include/phy.h
+++ b/include/phy.h
@@ -479,7 +479,7 @@
  *			or NULL otherwise
  */
 struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev,
-				      phy_interface_t interface);
+				      int phyaddr, phy_interface_t interface);
 
 static inline ofnode phy_get_ofnode(struct phy_device *phydev)
 {
diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h
index f577008..76ec214 100644
--- a/include/zynqmp_firmware.h
+++ b/include/zynqmp_firmware.h
@@ -408,6 +408,11 @@
 	SD_CONFIG_FIXED = 4,	/* To set fixed config registers */
 };
 
+enum pm_gem_config_type {
+	GEM_CONFIG_SGMII_MODE = 1, /* To set GEM_SGMII_MODE in GEM_CLK_CTRL */
+	GEM_CONFIG_FIXED = 2,   /* To set fixed config registers */
+};
+
 #define PM_SIP_SVC	0xc2000000
 
 #define ZYNQMP_PM_VERSION_MAJOR		1
@@ -439,6 +444,8 @@
 int xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
 		      u32 arg3, u32 *ret_payload);
 int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value);
+int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
+			     u32 value);
 int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id);
 
 /* Type of Config Object */