diff options
-rw-r--r-- | plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c | 37 | ||||
-rw-r--r-- | plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h | 2 | ||||
-rw-r--r-- | plat/xilinx/zynqmp/zynqmp_def.h | 9 |
3 files changed, 48 insertions, 0 deletions
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c index cdbb515b..17918338 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c @@ -472,6 +472,40 @@ static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index, } /** + * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset + * + * This function peerforms the ULPI reset sequence for resetting + * the ULPI transceiver. + * + * @return Returns status, either success or error+reason + */ +static enum pm_ret_status pm_ioctl_ulpi_reset(void) +{ + enum pm_ret_status ret; + + ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK, + ZYNQMP_ULPI_RESET_VAL_HIGH); + if (ret != PM_RET_SUCCESS) + return ret; + + /* Drive ULPI assert for atleast 1ms */ + mdelay(1); + + ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK, + ZYNQMP_ULPI_RESET_VAL_LOW); + if (ret != PM_RET_SUCCESS) + return ret; + + /* Drive ULPI de-assert for atleast 1ms */ + mdelay(1); + + ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK, + ZYNQMP_ULPI_RESET_VAL_HIGH); + + return ret; +} + +/** * pm_api_ioctl() - PM IOCTL API for device control and configs * @node_id Node ID of the device * @ioctl_id ID of the requested IOCTL @@ -540,6 +574,9 @@ enum pm_ret_status pm_api_ioctl(enum pm_node_id nid, case IOCTL_READ_PGGS: ret = pm_ioctl_read_pggs(arg1, value); break; + case IOCTL_ULPI_RESET: + ret = pm_ioctl_ulpi_reset(); + break; default: ret = PM_RET_ERROR_NOTSUPPORTED; break; diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h index 081259f6..bf17117f 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h @@ -32,6 +32,8 @@ enum { IOCTL_READ_GGS, IOCTL_WRITE_PGGS, IOCTL_READ_PGGS, + /* IOCTL for ULPI reset */ + IOCTL_ULPI_RESET, }; //RPU operation mode diff --git a/plat/xilinx/zynqmp/zynqmp_def.h b/plat/xilinx/zynqmp/zynqmp_def.h index 22256ebf..dd26c6c2 100644 --- a/plat/xilinx/zynqmp/zynqmp_def.h +++ b/plat/xilinx/zynqmp/zynqmp_def.h @@ -48,6 +48,7 @@ #define CRL_APB_BOOT_MODE_USER (CRL_APB_BASE + 0x200) #define CRL_APB_RESET_CTRL (CRL_APB_BASE + 0x218) #define CRL_APB_RST_LPD_TOP (CRL_APB_BASE + 0x23C) +#define CRL_APB_BOOT_PIN_CTRL (CRL_APB_BASE + U(0x250)) #define CRL_APB_CLK_BASE U(0xFF5E0020) #define CRL_APB_RPU_AMBA_RESET (U(1) << 2) @@ -56,7 +57,15 @@ #define CRL_APB_RESET_CTRL_SOFT_RESET (U(1) << 4) #define CRL_APB_BOOT_MODE_MASK (U(0xf) << 0) +#define CRL_APB_BOOT_PIN_MASK (U(0xf0f) << 0) +#define CRL_APB_BOOT_DRIVE_PIN_1_SHIFT U(9) +#define CRL_APB_BOOT_ENABLE_PIN_1_SHIFT U(1) +#define CRL_APB_BOOT_ENABLE_PIN_1 (U(0x1) << CRL_APB_BOOT_ENABLE_PIN_1_SHIFT) +#define CRL_APB_BOOT_DRIVE_PIN_1 (U(0x1) << CRL_APB_BOOT_DRIVE_PIN_1_SHIFT) #define ZYNQMP_BOOTMODE_JTAG U(0) +#define ZYNQMP_ULPI_RESET_VAL_HIGH (CRL_APB_BOOT_ENABLE_PIN_1 | \ + CRL_APB_BOOT_DRIVE_PIN_1) +#define ZYNQMP_ULPI_RESET_VAL_LOW CRL_APB_BOOT_ENABLE_PIN_1 /* system counter registers and bitfields */ #define IOU_SCNTRS_BASE 0xFF260000 |