zynqmp: pm: Implement IOCTL APIs for remoteproc
Implement ioctl APIs which uses MMIO operations to control RPU operations. Below IOCTLs are supported in this patch: * Get RPU operation mode * Set RPU operation mode * Configure RPU boot address (OCM/TCM) * Configure TCM combined mode Signed-off-by: Rajan Vaja <rajanv@xilinx.com> Signed-off-by: Jolly Shah <jollys@xilinx.com>
This commit is contained in:
parent
d0e2c51ae3
commit
f76918a806
|
@ -78,6 +78,7 @@ BL31_SOURCES += drivers/arm/cci/cci.c \
|
|||
plat/xilinx/zynqmp/pm_service/pm_svc_main.c \
|
||||
plat/xilinx/zynqmp/pm_service/pm_api_sys.c \
|
||||
plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c \
|
||||
plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c \
|
||||
plat/xilinx/zynqmp/pm_service/pm_ipi.c \
|
||||
plat/xilinx/zynqmp/pm_service/pm_client.c \
|
||||
plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* ZynqMP system level PM-API functions for ioctl.
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <delay_timer.h>
|
||||
#include <mmio.h>
|
||||
#include <platform.h>
|
||||
#include "pm_api_ioctl.h"
|
||||
#include "pm_api_sys.h"
|
||||
#include "pm_client.h"
|
||||
#include "pm_common.h"
|
||||
#include "pm_ipi.h"
|
||||
#include "../zynqmp_def.h"
|
||||
|
||||
/**
|
||||
* pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
|
||||
* @mode Buffer to store value of oper mode(Split/Lock-step)
|
||||
*
|
||||
* This function provides current configured RPU operational mode.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(unsigned int *mode)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
|
||||
val &= ZYNQMP_SLSPLIT_MASK;
|
||||
if (val)
|
||||
*mode = PM_RPU_MODE_SPLIT;
|
||||
else
|
||||
*mode = PM_RPU_MODE_LOCKSTEP;
|
||||
|
||||
return PM_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode
|
||||
* @mode Value to set for oper mode(Split/Lock-step)
|
||||
*
|
||||
* This function configures RPU operational mode(Split/Lock-step).
|
||||
* It also sets TCM combined mode in RPU lock-step and TCM non-combined
|
||||
* mode for RPU split mode. In case of Lock step mode, RPU1's output is
|
||||
* clamped.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(unsigned int mode)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
if (mmio_read_32(CRL_APB_RST_LPD_TOP) && CRL_APB_RPU_AMBA_RESET)
|
||||
return PM_RET_ERROR_ACCESS;
|
||||
|
||||
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
|
||||
|
||||
if (mode == PM_RPU_MODE_SPLIT) {
|
||||
val |= ZYNQMP_SLSPLIT_MASK;
|
||||
val &= ~ZYNQMP_TCM_COMB_MASK;
|
||||
val &= ~ZYNQMP_SLCLAMP_MASK;
|
||||
} else if (mode == PM_RPU_MODE_LOCKSTEP) {
|
||||
val &= ~ZYNQMP_SLSPLIT_MASK;
|
||||
val |= ZYNQMP_TCM_COMB_MASK;
|
||||
val |= ZYNQMP_SLCLAMP_MASK;
|
||||
} else {
|
||||
return PM_RET_ERROR_ARGS;
|
||||
}
|
||||
|
||||
mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
|
||||
|
||||
return PM_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ioctl_config_boot_addr() - Configure RPU boot address
|
||||
* @nid Node ID of RPU
|
||||
* @value Value to set for boot address (TCM/OCM)
|
||||
*
|
||||
* This function configures RPU boot address(memory).
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
|
||||
unsigned int value)
|
||||
{
|
||||
unsigned int rpu_cfg_addr, val;
|
||||
|
||||
if (nid == NODE_RPU_0)
|
||||
rpu_cfg_addr = ZYNQMP_RPU0_CFG;
|
||||
else if (nid == NODE_RPU_1)
|
||||
rpu_cfg_addr = ZYNQMP_RPU1_CFG;
|
||||
else
|
||||
return PM_RET_ERROR_ARGS;
|
||||
|
||||
val = mmio_read_32(rpu_cfg_addr);
|
||||
|
||||
if (value == PM_RPU_BOOTMEM_LOVEC)
|
||||
val &= ~ZYNQMP_VINITHI_MASK;
|
||||
else if (value == PM_RPU_BOOTMEM_HIVEC)
|
||||
val |= ZYNQMP_VINITHI_MASK;
|
||||
else
|
||||
return PM_RET_ERROR_ARGS;
|
||||
|
||||
mmio_write_32(rpu_cfg_addr, val);
|
||||
|
||||
return PM_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ioctl_config_tcm_comb() - Configure TCM combined mode
|
||||
* @value Value to set (Split/Combined)
|
||||
*
|
||||
* This function configures TCM to be in split mode or combined
|
||||
* mode.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
static enum pm_ret_status pm_ioctl_config_tcm_comb(unsigned int value)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
|
||||
|
||||
if (value == PM_RPU_TCM_SPLIT)
|
||||
val &= ~ZYNQMP_TCM_COMB_MASK;
|
||||
else if (value == PM_RPU_TCM_COMB)
|
||||
val |= ZYNQMP_TCM_COMB_MASK;
|
||||
else
|
||||
return PM_RET_ERROR_ARGS;
|
||||
|
||||
mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
|
||||
|
||||
return PM_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @arg1 Argument 1 to requested IOCTL call
|
||||
* @arg2 Argument 2 to requested IOCTL call
|
||||
* @value Returned output value
|
||||
*
|
||||
* This function calls IOCTL to firmware for device control and configuration.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
|
||||
unsigned int ioctl_id,
|
||||
unsigned int arg1,
|
||||
unsigned int arg2,
|
||||
unsigned int *value)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (ioctl_id) {
|
||||
case IOCTL_GET_RPU_OPER_MODE:
|
||||
ret = pm_ioctl_get_rpu_oper_mode(value);
|
||||
break;
|
||||
case IOCTL_SET_RPU_OPER_MODE:
|
||||
ret = pm_ioctl_set_rpu_oper_mode(arg1);
|
||||
break;
|
||||
case IOCTL_RPU_BOOT_ADDR_CONFIG:
|
||||
ret = pm_ioctl_config_boot_addr(nid, arg1);
|
||||
break;
|
||||
case IOCTL_TCM_COMB_CONFIG:
|
||||
ret = pm_ioctl_config_tcm_comb(arg1);
|
||||
break;
|
||||
default:
|
||||
ret = PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* ZynqMP system level PM-API functions for pin control.
|
||||
*/
|
||||
|
||||
#ifndef _PM_API_IOCTL_H_
|
||||
#define _PM_API_IOCTL_H_
|
||||
|
||||
#include "pm_common.h"
|
||||
|
||||
enum pm_ioctl_id {
|
||||
IOCTL_GET_RPU_OPER_MODE,
|
||||
IOCTL_SET_RPU_OPER_MODE,
|
||||
IOCTL_RPU_BOOT_ADDR_CONFIG,
|
||||
IOCTL_TCM_COMB_CONFIG,
|
||||
};
|
||||
|
||||
enum rpu_oper_mode {
|
||||
PM_RPU_MODE_LOCKSTEP,
|
||||
PM_RPU_MODE_SPLIT,
|
||||
};
|
||||
|
||||
enum rpu_boot_mem {
|
||||
PM_RPU_BOOTMEM_LOVEC,
|
||||
PM_RPU_BOOTMEM_HIVEC,
|
||||
};
|
||||
|
||||
enum rpu_tcm_comb {
|
||||
PM_RPU_TCM_SPLIT,
|
||||
PM_RPU_TCM_COMB,
|
||||
};
|
||||
|
||||
enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
|
||||
unsigned int ioctl_id,
|
||||
unsigned int arg1,
|
||||
unsigned int arg2,
|
||||
unsigned int *value);
|
||||
#endif /* _PM_API_IOCTL_H_ */
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <arch_helpers.h>
|
||||
#include <platform.h>
|
||||
#include "pm_api_ioctl.h"
|
||||
#include "pm_api_pinctrl.h"
|
||||
#include "pm_api_sys.h"
|
||||
#include "pm_client.h"
|
||||
|
@ -636,3 +637,24 @@ enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
|
|||
{
|
||||
return pm_api_pinctrl_set_config(pin, param, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ioctl() - PM IOCTL API for device control and configs
|
||||
* @node_id Node ID of the device
|
||||
* @ioctl_id ID of the requested IOCTL
|
||||
* @arg1 Argument 1 to requested IOCTL call
|
||||
* @arg2 Argument 2 to requested IOCTL call
|
||||
* @out Returned output value
|
||||
*
|
||||
* This function calls IOCTL to firmware for device control and configuration.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_ioctl(enum pm_node_id nid,
|
||||
unsigned int ioctl_id,
|
||||
unsigned int arg1,
|
||||
unsigned int arg2,
|
||||
unsigned int *value)
|
||||
{
|
||||
return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
|
||||
}
|
||||
|
|
|
@ -105,5 +105,10 @@ enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
|
|||
enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
|
||||
unsigned int param,
|
||||
unsigned int value);
|
||||
enum pm_ret_status pm_ioctl(enum pm_node_id nid,
|
||||
unsigned int ioctl_id,
|
||||
unsigned int arg1,
|
||||
unsigned int arg2,
|
||||
unsigned int *value);
|
||||
|
||||
#endif /* _PM_API_SYS_H_ */
|
||||
|
|
|
@ -75,6 +75,7 @@ enum pm_api_id {
|
|||
PM_PINCTRL_SET_FUNCTION,
|
||||
PM_PINCTRL_CONFIG_PARAM_GET,
|
||||
PM_PINCTRL_CONFIG_PARAM_SET,
|
||||
PM_IOCTL,
|
||||
PM_API_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -280,6 +280,15 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
|
|||
ret = pm_pinctrl_set_config(pm_arg[0], pm_arg[1], pm_arg[2]);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_IOCTL:
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
ret = pm_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
pm_arg[3], &value);
|
||||
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
|
||||
}
|
||||
|
||||
default:
|
||||
WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
|
|
|
@ -47,7 +47,9 @@
|
|||
#define CRL_APB_RPLL_CTRL (CRL_APB_BASE + 0x30)
|
||||
#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_RPU_AMBA_RESET (1 << 2)
|
||||
#define CRL_APB_RPLL_CTRL_BYPASS (1 << 3)
|
||||
|
||||
#define CRL_APB_RESET_CTRL_SOFT_RESET (1 << 4)
|
||||
|
@ -176,4 +178,12 @@
|
|||
|
||||
#define IOU_SLCR_BASEADDR 0xFF180000
|
||||
|
||||
#define ZYNQMP_RPU_GLBL_CNTL 0xFF9A0000
|
||||
#define ZYNQMP_RPU0_CFG 0xFF9A0100
|
||||
#define ZYNQMP_RPU1_CFG 0xFF9A0200
|
||||
#define ZYNQMP_SLSPLIT_MASK 0x08
|
||||
#define ZYNQMP_TCM_COMB_MASK 0x40
|
||||
#define ZYNQMP_SLCLAMP_MASK 0x10
|
||||
#define ZYNQMP_VINITHI_MASK 0x04
|
||||
|
||||
#endif /* __ZYNQMP_DEF_H__ */
|
||||
|
|
Loading…
Reference in New Issue