aboutsummaryrefslogtreecommitdiff
path: root/drivers/firmware/firmware-zynqmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware/firmware-zynqmp.c')
-rw-r--r--drivers/firmware/firmware-zynqmp.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index 839203e..8d8492d 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -8,6 +8,7 @@
#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>
@@ -27,6 +28,57 @@ struct zynqmp_power {
struct mbox_chan rx_chan;
} zynqmp_power;
+#define NODE_ID_LOCATION 5
+
+static unsigned int xpm_configobject[] = {
+ /**********************************************************************/
+ /* HEADER */
+ 2, /* Number of remaining words in the header */
+ 1, /* Number of sections included in config object */
+ PM_CONFIG_OBJECT_TYPE_OVERLAY, /* Type of Config object as overlay */
+ /**********************************************************************/
+ /* SLAVE SECTION */
+
+ PM_CONFIG_SLAVE_SECTION_ID, /* Section ID */
+ 1, /* Number of slaves */
+
+ 0, /* Node ID which will be changed below */
+ PM_SLAVE_FLAG_IS_SHAREABLE,
+ PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK |
+ PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK |
+ PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK, /* IPI Mask */
+};
+
+static unsigned int xpm_configobject_close[] = {
+ /**********************************************************************/
+ /* HEADER */
+ 2, /* Number of remaining words in the header */
+ 1, /* Number of sections included in config object */
+ PM_CONFIG_OBJECT_TYPE_OVERLAY, /* Type of Config object as overlay */
+ /**********************************************************************/
+ /* SET CONFIG SECTION */
+ PM_CONFIG_SET_CONFIG_SECTION_ID,
+ 0U, /* Loading permission to Overlay config object */
+};
+
+int zynqmp_pmufw_config_close(void)
+{
+ zynqmp_pmufw_load_config_object(xpm_configobject_close,
+ sizeof(xpm_configobject_close));
+ return 0;
+}
+
+int zynqmp_pmufw_node(u32 id)
+{
+ /* Record power domain id */
+ xpm_configobject[NODE_ID_LOCATION] = id;
+
+ zynqmp_pmufw_load_config_object(xpm_configobject,
+ sizeof(xpm_configobject));
+
+ return 0;
+}
+
static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
{
struct zynqmp_ipi_msg msg;
@@ -226,8 +278,27 @@ static const struct udevice_id zynqmp_firmware_ids[] = {
{ }
};
+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 bound: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return dm_scan_fdt_dev(dev);
+}
+
U_BOOT_DRIVER(zynqmp_firmware) = {
.id = UCLASS_FIRMWARE,
.name = "zynqmp_firmware",
.of_match = zynqmp_firmware_ids,
+ .bind = zynqmp_firmware_bind,
};