F: drivers/mtd/nand/raw/zynq_nand.c
F: drivers/net/phy/xilinx_phy.c
F: drivers/net/zynq_gem.c
+F: drivers/power/domain/zynqmp-power-domain.c
F: drivers/serial/serial_zynq.c
F: drivers/reset/reset-zynqmp.c
F: drivers/rtc/zynqmp_rtc.c
#include <common.h>
#include <cpu_func.h>
#include <dm.h>
+#include <dm/lists.h>
#include <log.h>
#include <zynqmp_firmware.h>
#include <asm/cache.h>
{ }
};
+static int zynqmp_firmware_bind(struct udevice *dev)
+{
+ int ret;
+ struct udevice *child;
+
+ if (IS_ENABLED(CONFIG_ZYNQMP_POWER_DOMAIN)) {
+ ret = device_bind_driver_to_node(dev, "zynqmp_power_domain",
+ "zynqmp_power_domain",
+ dev_ofnode(dev), &child);
+ if (ret)
+ printf("zynqmp power domain driver is not binded\n");
+ }
+
+ return 0;
+}
+
U_BOOT_DRIVER(zynqmp_firmware) = {
.id = UCLASS_FIRMWARE,
.name = "zynqmp_firmware",
.of_match = zynqmp_firmware_ids,
+ .bind = zynqmp_firmware_bind,
};
help
Generic power domain implementation for TI K3 devices.
+config ZYNQMP_POWER_DOMAIN
+ bool "Enable the Xilinx ZynqMP Power domain driver"
+ depends on POWER_DOMAIN && ZYNQMP_FIRMWARE
+ help
+ Generic power domain implementation for Xilinx ZynqMP devices.
+ The driver should be enabled when system starts in very minimal
+ configuration and it is extended at run time. Then enabling
+ the driver will ensure that PMUFW enable access to requested IP.
+
endmenu
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021, Xilinx. Inc.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <log.h>
+#include <malloc.h>
+#include <misc.h>
+#include <power-domain-uclass.h>
+#include <linux/bitops.h>
+
+#include <zynqmp_firmware.h>
+
+static int zynqmp_pm_request_node(const u32 node, const u32 capabilities,
+ const u32 qos, const enum zynqmp_pm_request_ack ack)
+{
+ return xilinx_pm_request(PM_REQUEST_NODE, node, capabilities,
+ qos, ack, NULL);
+}
+
+static int zynqmp_power_domain_request(struct power_domain *power_domain)
+{
+ dev_dbg(power_domain->dev, "Request for id: %ld\n", power_domain->id);
+
+ return zynqmp_pmufw_node(power_domain->id);
+}
+
+static int zynqmp_power_domain_free(struct power_domain *power_domain)
+{
+ /* nop now */
+ return 0;
+}
+
+static int zynqmp_power_domain_on(struct power_domain *power_domain)
+{
+ dev_dbg(power_domain->dev, "Domain ON for id: %ld\n", power_domain->id);
+
+ return zynqmp_pm_request_node(power_domain->id,
+ ZYNQMP_PM_CAPABILITY_ACCESS,
+ ZYNQMP_PM_MAX_QOS,
+ ZYNQMP_PM_REQUEST_ACK_BLOCKING);
+}
+
+static int zynqmp_power_domain_off(struct power_domain *power_domain)
+{
+ /* nop now */
+ return 0;
+}
+
+struct power_domain_ops zynqmp_power_domain_ops = {
+ .request = zynqmp_power_domain_request,
+ .rfree = zynqmp_power_domain_free,
+ .on = zynqmp_power_domain_on,
+ .off = zynqmp_power_domain_off,
+};
+
+static int zynqmp_power_domain_probe(struct udevice *dev)
+{
+ return 0;
+}
+
+U_BOOT_DRIVER(zynqmp_power_domain) = {
+ .name = "zynqmp_power_domain",
+ .id = UCLASS_POWER_DOMAIN,
+ .probe = zynqmp_power_domain_probe,
+ .ops = &zynqmp_power_domain_ops,
+};
#define PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK 0x00000100
#define PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK 0x00000200
+/* Node capabilities */
+#define ZYNQMP_PM_CAPABILITY_ACCESS 0x1U
+#define ZYNQMP_PM_CAPABILITY_CONTEXT 0x2U
+#define ZYNQMP_PM_CAPABILITY_WAKEUP 0x4U
+#define ZYNQMP_PM_CAPABILITY_UNUSABLE 0x8U
+
+#define ZYNQMP_PM_MAX_QOS 100U
+
#endif /* _ZYNQMP_FIRMWARE_H_ */