Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
e33aca3e
Unverified
Commit
e33aca3e
authored
Jan 08, 2019
by
Antonio Niño Díaz
Committed by
GitHub
Jan 08, 2019
Browse files
Merge pull request #1732 from jollysxilinx/integration
plat: xilinx: Clock and PLL EEMI API Support
parents
a9f803b7
ff966c27
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
plat/xilinx/zynqmp/pm_service/pm_api_clock.c
View file @
e33aca3e
This diff is collapsed.
Click to expand it.
plat/xilinx/zynqmp/pm_service/pm_api_clock.h
View file @
e33aca3e
...
...
@@ -56,7 +56,7 @@
#define END_OF_CLK "END_OF_CLK"
//CLock Ids
enum
{
enum
clock_id
{
CLK_IOPLL
,
CLK_RPLL
,
CLK_APLL
,
...
...
@@ -160,6 +160,7 @@ enum {
CLK_VPLL_POST_SRC
,
CLK_CAN0_MIO
,
CLK_CAN1_MIO
,
CLK_ACPU_FULL
,
END_OF_OUTPUT_CLKS
,
};
...
...
@@ -275,6 +276,10 @@ enum {
#define TYPE_DIV2 5U
#define TYPE_GATE 6U
struct
pm_pll
;
struct
pm_pll
*
pm_clock_get_pll
(
enum
clock_id
clock_id
);
struct
pm_pll
*
pm_clock_get_pll_by_related_clk
(
enum
clock_id
clock_id
);
uint8_t
pm_clock_has_div
(
unsigned
int
clock_id
,
enum
pm_clock_div_id
div_id
);
enum
pm_ret_status
pm_api_clock_get_name
(
unsigned
int
clock_id
,
char
*
name
);
enum
pm_ret_status
pm_api_clock_get_num_clocks
(
unsigned
int
*
nclocks
);
...
...
@@ -289,29 +294,24 @@ enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
uint32_t
*
parents
);
enum
pm_ret_status
pm_api_clock_get_attributes
(
unsigned
int
clock_id
,
uint32_t
*
attr
);
enum
pm_ret_status
pm_api_clock_enable
(
unsigned
int
clock_id
);
enum
pm_ret_status
pm_api_clock_disable
(
unsigned
int
clock_id
);
enum
pm_ret_status
pm_api_clock_getstate
(
unsigned
int
clock_id
,
unsigned
int
*
state
);
enum
pm_ret_status
pm_api_clock_setdivider
(
unsigned
int
clock_id
,
unsigned
int
divider
);
enum
pm_ret_status
pm_api_clock_getdivider
(
unsigned
int
clock_id
,
unsigned
int
*
divider
);
enum
pm_ret_status
pm_api_clock_setrate
(
unsigned
int
clock_id
,
uint64_t
rate
);
enum
pm_ret_status
pm_api_clock_getrate
(
unsigned
int
clock_id
,
uint64_t
*
rate
);
enum
pm_ret_status
pm_api_clock_setparent
(
unsigned
int
clock_id
,
unsigned
int
parent_idx
);
enum
pm_ret_status
pm_api_clock_getparent
(
unsigned
int
clock_id
,
unsigned
int
*
parent_idx
);
enum
pm_ret_status
pm_api_clk_set_pll_mode
(
unsigned
int
pll
,
unsigned
int
mode
);
enum
pm_ret_status
pm_api_clk_get_pll_mode
(
unsigned
int
pll
,
unsigned
int
*
mode
);
enum
pm_ret_status
pm_api_clk_set_pll_frac_data
(
unsigned
int
pll
,
unsigned
int
data
);
enum
pm_ret_status
pm_api_clk_get_pll_frac_data
(
unsigned
int
pll
,
unsigned
int
*
data
);
enum
pm_ret_status
pm_clock_get_pll_node_id
(
enum
clock_id
clock_id
,
enum
pm_node_id
*
node_id
);
enum
pm_ret_status
pm_clock_id_is_valid
(
unsigned
int
clock_id
);
enum
pm_ret_status
pm_clock_pll_enable
(
struct
pm_pll
*
pll
);
enum
pm_ret_status
pm_clock_pll_disable
(
struct
pm_pll
*
pll
);
enum
pm_ret_status
pm_clock_pll_get_state
(
struct
pm_pll
*
pll
,
unsigned
int
*
state
);
enum
pm_ret_status
pm_clock_pll_set_parent
(
struct
pm_pll
*
pll
,
enum
clock_id
clock_id
,
unsigned
int
parent_index
);
enum
pm_ret_status
pm_clock_pll_get_parent
(
struct
pm_pll
*
pll
,
enum
clock_id
clock_id
,
unsigned
int
*
parent_index
);
enum
pm_ret_status
pm_clock_set_pll_mode
(
enum
clock_id
clock_id
,
unsigned
int
mode
);
enum
pm_ret_status
pm_clock_get_pll_mode
(
enum
clock_id
clock_id
,
unsigned
int
*
mode
);
#endif
/* PM_API_CLOCK_H */
plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
View file @
e33aca3e
...
...
@@ -333,7 +333,7 @@ reset_release:
/**
* pm_ioctl_set_pll_frac_mode() - Ioctl function for
* setting pll mode
* @pll PLL id
* @pll PLL
clock
id
* @mode Mode fraction/integar
*
* This function sets PLL mode
...
...
@@ -343,13 +343,13 @@ reset_release:
static
enum
pm_ret_status
pm_ioctl_set_pll_frac_mode
(
unsigned
int
pll
,
unsigned
int
mode
)
{
return
pm_
api_
clk_set_pll_mode
(
pll
,
mode
);
return
pm_cl
oc
k_set_pll_mode
(
pll
,
mode
);
}
/**
* pm_ioctl_get_pll_frac_mode() - Ioctl function for
* getting pll mode
* @pll PLL id
* @pll PLL
clock
id
* @mode Mode fraction/integar
*
* This function return current PLL mode
...
...
@@ -359,13 +359,13 @@ static enum pm_ret_status pm_ioctl_set_pll_frac_mode
static
enum
pm_ret_status
pm_ioctl_get_pll_frac_mode
(
unsigned
int
pll
,
unsigned
int
*
mode
)
{
return
pm_
api_
clk_get_pll_mode
(
pll
,
mode
);
return
pm_cl
oc
k_get_pll_mode
(
pll
,
mode
);
}
/**
* pm_ioctl_set_pll_frac_data() - Ioctl function for
* setting pll fraction data
* @pll PLL id
* @pll PLL
clock
id
* @data fraction data
*
* This function sets fraction data.
...
...
@@ -376,13 +376,21 @@ static enum pm_ret_status pm_ioctl_get_pll_frac_mode
static
enum
pm_ret_status
pm_ioctl_set_pll_frac_data
(
unsigned
int
pll
,
unsigned
int
data
)
{
return
pm_api_clk_set_pll_frac_data
(
pll
,
data
);
enum
pm_node_id
pll_nid
;
enum
pm_ret_status
status
;
/* Get PLL node ID using PLL clock ID */
status
=
pm_clock_get_pll_node_id
(
pll
,
&
pll_nid
);
if
(
status
!=
PM_RET_SUCCESS
)
return
status
;
return
pm_pll_set_parameter
(
pll_nid
,
PM_PLL_PARAM_DATA
,
data
);
}
/**
* pm_ioctl_get_pll_frac_data() - Ioctl function for
* getting pll fraction data
* @pll PLL id
* @pll PLL
clock
id
* @data fraction data
*
* This function returns fraction data value.
...
...
@@ -392,7 +400,15 @@ static enum pm_ret_status pm_ioctl_set_pll_frac_data
static
enum
pm_ret_status
pm_ioctl_get_pll_frac_data
(
unsigned
int
pll
,
unsigned
int
*
data
)
{
return
pm_api_clk_get_pll_frac_data
(
pll
,
data
);
enum
pm_node_id
pll_nid
;
enum
pm_ret_status
status
;
/* Get PLL node ID using PLL clock ID */
status
=
pm_clock_get_pll_node_id
(
pll
,
&
pll_nid
);
if
(
status
!=
PM_RET_SUCCESS
)
return
status
;
return
pm_pll_get_parameter
(
pll_nid
,
PM_PLL_PARAM_DATA
,
data
);
}
/**
...
...
plat/xilinx/zynqmp/pm_service/pm_api_sys.c
View file @
e33aca3e
...
...
@@ -844,6 +844,36 @@ static enum pm_ret_status pm_clock_get_attributes(unsigned int clock_id,
return
pm_api_clock_get_attributes
(
clock_id
,
attr
);
}
/**
* pm_clock_gate() - Configure clock gate
* @clock_id Id of the clock to be configured
* @enable Flag 0=disable (gate the clock), !0=enable (activate the clock)
*
* @return Error if an argument is not valid or status as returned by the
* PM controller (PMU)
*/
static
enum
pm_ret_status
pm_clock_gate
(
unsigned
int
clock_id
,
unsigned
char
enable
)
{
uint32_t
payload
[
PAYLOAD_ARG_CNT
];
enum
pm_ret_status
status
;
enum
pm_api_id
api_id
;
/* Check if clock ID is valid and return an error if it is not */
status
=
pm_clock_id_is_valid
(
clock_id
);
if
(
status
!=
PM_RET_SUCCESS
)
return
status
;
if
(
enable
)
api_id
=
PM_CLOCK_ENABLE
;
else
api_id
=
PM_CLOCK_DISABLE
;
/* Send request to the PMU */
PM_PACK_PAYLOAD2
(
payload
,
api_id
,
clock_id
);
return
pm_ipi_send_sync
(
primary_proc
,
payload
,
NULL
,
0
);
}
/**
* pm_clock_enable() - Enable the clock for given id
* @clock_id: Id of the clock to be enabled
...
...
@@ -851,12 +881,20 @@ static enum pm_ret_status pm_clock_get_attributes(unsigned int clock_id,
* This function is used by master to enable the clock
* including peripherals and PLL clocks.
*
* Return: Returns status, either success or error+reason.
* @return: Error if an argument is not valid or status as returned by the
* pm_clock_gate
*/
enum
pm_ret_status
pm_clock_enable
(
unsigned
int
clock_id
)
{
return
pm_api_clock_enable
(
clock_id
);
struct
pm_pll
*
pll
;
/* First try to handle it as a PLL */
pll
=
pm_clock_get_pll
(
clock_id
);
if
(
pll
)
return
pm_clock_pll_enable
(
pll
);
/* It's an on-chip clock, PMU should configure clock's gate */
return
pm_clock_gate
(
clock_id
,
1
);
}
/**
...
...
@@ -866,12 +904,20 @@ enum pm_ret_status pm_clock_enable(unsigned int clock_id)
* This function is used by master to disable the clock
* including peripherals and PLL clocks.
*
* Return: Returns status, either success or error+reason.
* @return: Error if an argument is not valid or status as returned by the
* pm_clock_gate
*/
enum
pm_ret_status
pm_clock_disable
(
unsigned
int
clock_id
)
{
return
pm_api_clock_disable
(
clock_id
);
struct
pm_pll
*
pll
;
/* First try to handle it as a PLL */
pll
=
pm_clock_get_pll
(
clock_id
);
if
(
pll
)
return
pm_clock_pll_disable
(
pll
);
/* It's an on-chip clock, PMU should configure clock's gate */
return
pm_clock_gate
(
clock_id
,
0
);
}
/**
...
...
@@ -887,7 +933,23 @@ enum pm_ret_status pm_clock_disable(unsigned int clock_id)
enum
pm_ret_status
pm_clock_getstate
(
unsigned
int
clock_id
,
unsigned
int
*
state
)
{
return
pm_api_clock_getstate
(
clock_id
,
state
);
struct
pm_pll
*
pll
;
uint32_t
payload
[
PAYLOAD_ARG_CNT
];
enum
pm_ret_status
status
;
/* First try to handle it as a PLL */
pll
=
pm_clock_get_pll
(
clock_id
);
if
(
pll
)
return
pm_clock_pll_get_state
(
pll
,
state
);
/* Check if clock ID is a valid on-chip clock */
status
=
pm_clock_id_is_valid
(
clock_id
);
if
(
status
!=
PM_RET_SUCCESS
)
return
status
;
/* Send request to the PMU */
PM_PACK_PAYLOAD2
(
payload
,
PM_CLOCK_GETSTATE
,
clock_id
);
return
pm_ipi_send_sync
(
primary_proc
,
payload
,
state
,
1
);
}
/**
...
...
@@ -903,7 +965,37 @@ enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
enum
pm_ret_status
pm_clock_setdivider
(
unsigned
int
clock_id
,
unsigned
int
divider
)
{
return
pm_api_clock_setdivider
(
clock_id
,
divider
);
enum
pm_ret_status
status
;
enum
pm_node_id
nid
;
enum
pm_clock_div_id
div_id
;
uint32_t
payload
[
PAYLOAD_ARG_CNT
];
const
uint32_t
div0
=
0xFFFF0000
;
const
uint32_t
div1
=
0x0000FFFF
;
uint32_t
val
;
/* Get PLL node ID using PLL clock ID */
status
=
pm_clock_get_pll_node_id
(
clock_id
,
&
nid
);
if
(
status
==
PM_RET_SUCCESS
)
return
pm_pll_set_parameter
(
nid
,
PM_PLL_PARAM_FBDIV
,
divider
);
/* Check if clock ID is a valid on-chip clock */
status
=
pm_clock_id_is_valid
(
clock_id
);
if
(
status
!=
PM_RET_SUCCESS
)
return
status
;
if
(
div0
==
(
divider
&
div0
))
{
div_id
=
PM_CLOCK_DIV0_ID
;
val
=
divider
&
~
div0
;
}
else
if
(
div1
==
(
divider
&
div1
))
{
div_id
=
PM_CLOCK_DIV1_ID
;
val
=
(
divider
&
~
div1
)
>>
16
;
}
else
{
return
PM_RET_ERROR_ARGS
;
}
/* Send request to the PMU */
PM_PACK_PAYLOAD4
(
payload
,
PM_CLOCK_SETDIVIDER
,
clock_id
,
div_id
,
val
);
return
pm_ipi_send_sync
(
primary_proc
,
payload
,
NULL
,
0
);
}
/**
...
...
@@ -919,7 +1011,42 @@ enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
enum
pm_ret_status
pm_clock_getdivider
(
unsigned
int
clock_id
,
unsigned
int
*
divider
)
{
return
pm_api_clock_getdivider
(
clock_id
,
divider
);
enum
pm_ret_status
status
;
enum
pm_node_id
nid
;
uint32_t
payload
[
PAYLOAD_ARG_CNT
];
uint32_t
val
;
/* Get PLL node ID using PLL clock ID */
status
=
pm_clock_get_pll_node_id
(
clock_id
,
&
nid
);
if
(
status
==
PM_RET_SUCCESS
)
return
pm_pll_get_parameter
(
nid
,
PM_PLL_PARAM_FBDIV
,
divider
);
/* Check if clock ID is a valid on-chip clock */
status
=
pm_clock_id_is_valid
(
clock_id
);
if
(
status
!=
PM_RET_SUCCESS
)
return
status
;
if
(
pm_clock_has_div
(
clock_id
,
PM_CLOCK_DIV0_ID
))
{
/* Send request to the PMU to get div0 */
PM_PACK_PAYLOAD3
(
payload
,
PM_CLOCK_GETDIVIDER
,
clock_id
,
PM_CLOCK_DIV0_ID
);
status
=
pm_ipi_send_sync
(
primary_proc
,
payload
,
&
val
,
1
);
if
(
status
!=
PM_RET_SUCCESS
)
return
status
;
*
divider
=
val
;
}
if
(
pm_clock_has_div
(
clock_id
,
PM_CLOCK_DIV1_ID
))
{
/* Send request to the PMU to get div1 */
PM_PACK_PAYLOAD3
(
payload
,
PM_CLOCK_GETDIVIDER
,
clock_id
,
PM_CLOCK_DIV1_ID
);
status
=
pm_ipi_send_sync
(
primary_proc
,
payload
,
&
val
,
1
);
if
(
status
!=
PM_RET_SUCCESS
)
return
status
;
*
divider
|=
val
<<
16
;
}
return
status
;
}
/**
...
...
@@ -934,7 +1061,7 @@ enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
enum
pm_ret_status
pm_clock_setrate
(
unsigned
int
clock_id
,
uint64_t
rate
)
{
return
pm_api_clock_setrate
(
clock_id
,
rate
)
;
return
PM_RET_ERROR_NOTSUPPORTED
;
}
/**
...
...
@@ -950,28 +1077,44 @@ enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
enum
pm_ret_status
pm_clock_getrate
(
unsigned
int
clock_id
,
uint64_t
*
rate
)
{
return
pm_api_clock_getrate
(
clock_id
,
rate
)
;
return
PM_RET_ERROR_NOTSUPPORTED
;
}
/**
* pm_clock_setparent - Set the clock parent for given id
* @clock_id: Id of the clock
* @parent_i
d: parent id
* @parent_i
ndex: Index of the parent clock into clock's parents array
*
* This function is used by master to set parent for any clock.
*
* Return: Returns status, either success or error+reason.
*/
enum
pm_ret_status
pm_clock_setparent
(
unsigned
int
clock_id
,
unsigned
int
parent_i
d
)
unsigned
int
parent_i
ndex
)
{
return
pm_api_clock_setparent
(
clock_id
,
parent_id
);
struct
pm_pll
*
pll
;
uint32_t
payload
[
PAYLOAD_ARG_CNT
];
enum
pm_ret_status
status
;
/* First try to handle it as a PLL */
pll
=
pm_clock_get_pll_by_related_clk
(
clock_id
);
if
(
pll
)
return
pm_clock_pll_set_parent
(
pll
,
clock_id
,
parent_index
);
/* Check if clock ID is a valid on-chip clock */
status
=
pm_clock_id_is_valid
(
clock_id
);
if
(
status
!=
PM_RET_SUCCESS
)
return
status
;
/* Send request to the PMU */
PM_PACK_PAYLOAD3
(
payload
,
PM_CLOCK_SETPARENT
,
clock_id
,
parent_index
);
return
pm_ipi_send_sync
(
primary_proc
,
payload
,
NULL
,
0
);
}
/**
* pm_clock_getparent - Get the clock parent for given id
* @clock_id: Id of the clock
* @parent_i
d
: parent i
d
* @parent_i
ndex
: parent i
ndex
*
* This function is used by master to get parent index
* for any clock.
...
...
@@ -979,9 +1122,25 @@ enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
* Return: Returns status, either success or error+reason.
*/
enum
pm_ret_status
pm_clock_getparent
(
unsigned
int
clock_id
,
unsigned
int
*
parent_i
d
)
unsigned
int
*
parent_i
ndex
)
{
return
pm_api_clock_getparent
(
clock_id
,
parent_id
);
struct
pm_pll
*
pll
;
uint32_t
payload
[
PAYLOAD_ARG_CNT
];
enum
pm_ret_status
status
;
/* First try to handle it as a PLL */
pll
=
pm_clock_get_pll_by_related_clk
(
clock_id
);
if
(
pll
)
return
pm_clock_pll_get_parent
(
pll
,
clock_id
,
parent_index
);
/* Check if clock ID is a valid on-chip clock */
status
=
pm_clock_id_is_valid
(
clock_id
);
if
(
status
!=
PM_RET_SUCCESS
)
return
status
;
/* Send request to the PMU */
PM_PACK_PAYLOAD2
(
payload
,
PM_CLOCK_GETPARENT
,
clock_id
);
return
pm_ipi_send_sync
(
primary_proc
,
payload
,
parent_index
,
1
);
}
/**
...
...
@@ -1238,3 +1397,113 @@ enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
address_high
,
readback_type
);
return
pm_ipi_send_sync
(
primary_proc
,
payload
,
value
,
1
);
}
/*
* pm_pll_set_parameter() - Set the PLL parameter value
* @nid Node id of the target PLL
* @param_id ID of the PLL parameter
* @value Parameter value to be set
*
* Setting the parameter will have physical effect once the PLL mode is set to
* integer or fractional.
*
* @return Error if an argument is not valid or status as returned by the
* PM controller (PMU)
*/
enum
pm_ret_status
pm_pll_set_parameter
(
enum
pm_node_id
nid
,
enum
pm_pll_param
param_id
,
unsigned
int
value
)
{
uint32_t
payload
[
PAYLOAD_ARG_CNT
];
/* Check if given node ID is a PLL node */
if
(
nid
<
NODE_APLL
||
nid
>
NODE_IOPLL
)
return
PM_RET_ERROR_ARGS
;
/* Check if parameter ID is valid and return an error if it's not */
if
(
param_id
>=
PM_PLL_PARAM_MAX
)
return
PM_RET_ERROR_ARGS
;
/* Send request to the PMU */
PM_PACK_PAYLOAD4
(
payload
,
PM_PLL_SET_PARAMETER
,
nid
,
param_id
,
value
);
return
pm_ipi_send_sync
(
primary_proc
,
payload
,
NULL
,
0
);
}
/**
* pm_pll_get_parameter() - Get the PLL parameter value
* @nid Node id of the target PLL
* @param_id ID of the PLL parameter
* @value Location to store the parameter value
*
* @return Error if an argument is not valid or status as returned by the
* PM controller (PMU)
*/
enum
pm_ret_status
pm_pll_get_parameter
(
enum
pm_node_id
nid
,
enum
pm_pll_param
param_id
,
unsigned
int
*
value
)
{
uint32_t
payload
[
PAYLOAD_ARG_CNT
];
/* Check if given node ID is a PLL node */
if
(
nid
<
NODE_APLL
||
nid
>
NODE_IOPLL
)
return
PM_RET_ERROR_ARGS
;
/* Check if parameter ID is valid and return an error if it's not */
if
(
param_id
>=
PM_PLL_PARAM_MAX
)
return
PM_RET_ERROR_ARGS
;
/* Send request to the PMU */
PM_PACK_PAYLOAD3
(
payload
,
PM_PLL_GET_PARAMETER
,
nid
,
param_id
);
return
pm_ipi_send_sync
(
primary_proc
,
payload
,
value
,
1
);
}
/**
* pm_pll_set_mode() - Set the PLL mode
* @nid Node id of the target PLL
* @mode PLL mode to be set
*
* If reset mode is set the PM controller will first bypass the PLL and then
* assert the reset. If integer or fractional mode is set the PM controller will
* ensure that the complete PLL programming sequence is satisfied. After this
* function returns success the PLL is locked and its bypass is deasserted.
*
* @return Error if an argument is not valid or status as returned by the
* PM controller (PMU)
*/
enum
pm_ret_status
pm_pll_set_mode
(
enum
pm_node_id
nid
,
enum
pm_pll_mode
mode
)
{
uint32_t
payload
[
PAYLOAD_ARG_CNT
];
/* Check if given node ID is a PLL node */
if
(
nid
<
NODE_APLL
||
nid
>
NODE_IOPLL
)
return
PM_RET_ERROR_ARGS
;
/* Check if PLL mode is valid */
if
(
mode
>=
PM_PLL_MODE_MAX
)
return
PM_RET_ERROR_ARGS
;
/* Send request to the PMU */
PM_PACK_PAYLOAD3
(
payload
,
PM_PLL_SET_MODE
,
nid
,
mode
);
return
pm_ipi_send_sync
(
primary_proc
,
payload
,
NULL
,
0
);
}
/**
* pm_pll_get_mode() - Get the PLL mode
* @nid Node id of the target PLL
* @mode Location to store the mode of the PLL
*
* @return Error if an argument is not valid or status as returned by the
* PM controller (PMU)
*/
enum
pm_ret_status
pm_pll_get_mode
(
enum
pm_node_id
nid
,
enum
pm_pll_mode
*
mode
)
{
uint32_t
payload
[
PAYLOAD_ARG_CNT
];
/* Check if given node ID is a PLL node */
if
(
nid
<
NODE_APLL
||
nid
>
NODE_IOPLL
)
return
PM_RET_ERROR_ARGS
;
/* Send request to the PMU */
PM_PACK_PAYLOAD2
(
payload
,
PM_PLL_GET_MODE
,
nid
);
return
pm_ipi_send_sync
(
primary_proc
,
payload
,
mode
,
1
);
}
plat/xilinx/zynqmp/pm_service/pm_api_sys.h
View file @
e33aca3e
...
...
@@ -177,4 +177,15 @@ enum pm_ret_status pm_aes_engine(uint32_t address_high,
uint32_t
address_low
,
uint32_t
*
value
);
enum
pm_ret_status
pm_pll_set_parameter
(
enum
pm_node_id
nid
,
enum
pm_pll_param
param_id
,
unsigned
int
value
);
enum
pm_ret_status
pm_pll_get_parameter
(
enum
pm_node_id
nid
,
enum
pm_pll_param
param_id
,
unsigned
int
*
value
);
enum
pm_ret_status
pm_pll_set_mode
(
enum
pm_node_id
nid
,
enum
pm_pll_mode
mode
);
enum
pm_ret_status
pm_pll_get_mode
(
enum
pm_node_id
nid
,
enum
pm_pll_mode
*
mode
);
#endif
/* PM_API_SYS_H */
plat/xilinx/zynqmp/pm_service/pm_defs.h
View file @
e33aca3e
...
...
@@ -92,6 +92,11 @@ enum pm_api_id {
/* FPGA PL Readback */
PM_FPGA_READ
,
PM_SECURE_AES
,
/* PLL control API functions */
PM_PLL_SET_PARAMETER
,
PM_PLL_GET_PARAMETER
,
PM_PLL_SET_MODE
,
PM_PLL_GET_MODE
,
PM_API_MAX
};
...
...
@@ -265,4 +270,51 @@ enum pm_shutdown_subtype {
PMF_SHUTDOWN_SUBTYPE_SYSTEM
,
};
/**
* @PM_PLL_PARAM_DIV2: Enable for divide by 2 function inside the PLL
* @PM_PLL_PARAM_FBDIV: Feedback divisor integer portion for the PLL
* @PM_PLL_PARAM_DATA: Feedback divisor fractional portion for the PLL
* @PM_PLL_PARAM_PRE_SRC: Clock source for PLL input
* @PM_PLL_PARAM_POST_SRC: Clock source for PLL Bypass mode
* @PM_PLL_PARAM_LOCK_DLY: Lock circuit config settings for lock windowsize
* @PM_PLL_PARAM_LOCK_CNT: Lock circuit counter setting
* @PM_PLL_PARAM_LFHF: PLL loop filter high frequency capacitor control
* @PM_PLL_PARAM_CP: PLL charge pump control
* @PM_PLL_PARAM_RES: PLL loop filter resistor control
*/
enum
pm_pll_param
{
PM_PLL_PARAM_DIV2
,
PM_PLL_PARAM_FBDIV
,
PM_PLL_PARAM_DATA
,
PM_PLL_PARAM_PRE_SRC
,
PM_PLL_PARAM_POST_SRC
,
PM_PLL_PARAM_LOCK_DLY
,
PM_PLL_PARAM_LOCK_CNT
,
PM_PLL_PARAM_LFHF
,
PM_PLL_PARAM_CP
,
PM_PLL_PARAM_RES
,
PM_PLL_PARAM_MAX
,
};
/**
* @PM_PLL_MODE_RESET: PLL is in reset (not locked)
* @PM_PLL_MODE_INTEGER: PLL is locked in integer mode
* @PM_PLL_MODE_FRACTIONAL: PLL is locked in fractional mode
*/
enum
pm_pll_mode
{
PM_PLL_MODE_RESET
,
PM_PLL_MODE_INTEGER
,
PM_PLL_MODE_FRACTIONAL
,
PM_PLL_MODE_MAX
,
};
/**
* @PM_CLOCK_DIV0_ID: Clock divider 0
* @PM_CLOCK_DIV1_ID: Clock divider 1
*/
enum
pm_clock_div_id
{
PM_CLOCK_DIV0_ID
,
PM_CLOCK_DIV1_ID
,
};
#endif
/* PM_DEFS_H */
plat/xilinx/zynqmp/pm_service/pm_svc_main.c
View file @
e33aca3e
...
...
@@ -565,6 +565,30 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
SMC_RET1
(
handle
,
(
uint64_t
)
ret
|
((
uint64_t
)
value
)
<<
32
);
}
case
PM_PLL_SET_PARAMETER
:
ret
=
pm_pll_set_parameter
(
pm_arg
[
0
],
pm_arg
[
1
],
pm_arg
[
2
]);
SMC_RET1
(
handle
,
(
uint64_t
)
ret
);
case
PM_PLL_GET_PARAMETER
:
{
uint32_t
value
;
ret
=
pm_pll_get_parameter
(
pm_arg
[
0
],
pm_arg
[
1
],
&
value
);
SMC_RET1
(
handle
,
(
uint64_t
)
ret
|
((
uint64_t
)
value
<<
32
));
}
case
PM_PLL_SET_MODE
:
ret
=
pm_pll_set_mode
(
pm_arg
[
0
],
pm_arg
[
1
]);
SMC_RET1
(
handle
,
(
uint64_t
)
ret
);
case
PM_PLL_GET_MODE
:
{
uint32_t
mode
;
ret
=
pm_pll_get_mode
(
pm_arg
[
0
],
&
mode
);
SMC_RET1
(
handle
,
(
uint64_t
)
ret
|
((
uint64_t
)
mode
<<
32
));
}
default:
WARN
(
"Unimplemented PM Service Call: 0x%x
\n
"
,
smc_fid
);
SMC_RET1
(
handle
,
SMC_UNK
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment