mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 09:34:18 +00:00
zynqmp: pm: Add clock control EEMI API and ioctl functions
These are empty functions with no logic right now. Code will be added in subsequent commits. Signed-off-by: Rajan Vaja <rajanv@xilinx.com> Signed-off-by: Jolly Shah <jollys@xilinx.com>
This commit is contained in:
parent
1818c02925
commit
caae497dfc
9 changed files with 885 additions and 1 deletions
|
@ -79,6 +79,7 @@ BL31_SOURCES += drivers/arm/cci/cci.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_api_clock.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
|
||||
|
|
356
plat/xilinx/zynqmp/pm_service/pm_api_clock.c
Normal file
356
plat/xilinx/zynqmp/pm_service/pm_api_clock.c
Normal file
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* ZynqMP system level PM-API functions for clock control.
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <mmio.h>
|
||||
#include <platform.h>
|
||||
#include <string.h>
|
||||
#include "pm_api_clock.h"
|
||||
#include "pm_api_sys.h"
|
||||
#include "pm_client.h"
|
||||
#include "pm_common.h"
|
||||
#include "pm_ipi.h"
|
||||
|
||||
#define CLK_NODE_MAX 6
|
||||
|
||||
/**
|
||||
* struct pm_clock_node - Clock topology node information
|
||||
* @type: Topology type (mux/div1/div2/gate/pll/fixed factor)
|
||||
* @offset: Offset in control register
|
||||
* @width: Width of the specific type in control register
|
||||
* @clkflags: Clk specific flags
|
||||
* @typeflags: Type specific flags
|
||||
* @mult: Multiplier for fixed factor
|
||||
* @div: Divisor for fixed factor
|
||||
*/
|
||||
struct pm_clock_node {
|
||||
uint16_t clkflags;
|
||||
uint16_t typeflags;
|
||||
uint8_t type;
|
||||
uint8_t offset;
|
||||
uint8_t width;
|
||||
uint8_t mult:4;
|
||||
uint8_t div:4;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm_clock - Clock structure
|
||||
* @name: Clock name
|
||||
* @control_reg: Control register address
|
||||
* @status_reg: Status register address
|
||||
* @parents: Parents for first clock node. Lower byte indicates parent
|
||||
* clock id and upper byte indicate flags for that id.
|
||||
* pm_clock_node: Clock nodes
|
||||
*/
|
||||
struct pm_clock {
|
||||
char name[CLK_NAME_LEN];
|
||||
uint8_t num_nodes;
|
||||
unsigned int control_reg;
|
||||
unsigned int status_reg;
|
||||
int32_t (*parents)[];
|
||||
struct pm_clock_node(*nodes)[];
|
||||
};
|
||||
|
||||
/* Clock array containing clock informaton */
|
||||
struct pm_clock clocks[] = {0};
|
||||
|
||||
/**
|
||||
* pm_api_clock_get_name() - PM call to request a clock's name
|
||||
* @clock_id Clock ID
|
||||
* @name Name of clock (max 16 bytes)
|
||||
*
|
||||
* This function is used by master to get nmae of clock specified
|
||||
* by given clock ID.
|
||||
*
|
||||
* @return Returns success. In case of error, name data is 0.
|
||||
*/
|
||||
enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_get_topology() - PM call to request a clock's topology
|
||||
* @clock_id Clock ID
|
||||
* @index Topology index for next toplogy node
|
||||
* @topology Buffer to store nodes in topology and flags
|
||||
*
|
||||
* This function is used by master to get topology information for the
|
||||
* clock specified by given clock ID. Each response would return 3
|
||||
* topology nodes. To get next nodes, caller needs to call this API with
|
||||
* index of next node. Index starts from 0.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
|
||||
unsigned int index,
|
||||
uint32_t *topology)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed
|
||||
* factor parameters for fixed clock
|
||||
* @clock_id Clock ID
|
||||
* @mul Multiplication value
|
||||
* @div Divisor value
|
||||
*
|
||||
* This function is used by master to get fixed factor parameers for the
|
||||
* fixed clock. This API is application only for the fixed clock.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
|
||||
uint32_t *mul,
|
||||
uint32_t *div)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_get_parents() - PM call to request a clock's first 3 parents
|
||||
* @clock_id Clock ID
|
||||
* @index Index of next parent
|
||||
* @parents Parents of the given clock
|
||||
*
|
||||
* This function is used by master to get clock's parents information.
|
||||
* This API will return 3 parents with a single response. To get other
|
||||
* parents, master should call same API in loop with new parent index
|
||||
* till error is returned.
|
||||
*
|
||||
* E.g First call should have index 0 which will return parents 0, 1 and
|
||||
* 2. Next call, index should be 3 which will return parent 3,4 and 5 and
|
||||
* so on.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
|
||||
unsigned int index,
|
||||
uint32_t *parents)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_get_attributes() - PM call to request a clock's attributes
|
||||
* @clock_id Clock ID
|
||||
* @attr Clock attributes
|
||||
*
|
||||
* This function is used by master to get clock's attributes
|
||||
* (e.g. valid, clock type, etc).
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
|
||||
uint32_t *attr)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_enable() - Enable the clock for given id
|
||||
* @clock_id: Id of the clock to be enabled
|
||||
*
|
||||
* This function is used by master to enable the clock
|
||||
* including peripherals and PLL clocks.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_api_clock_enable(unsigned int clock_id)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_disable - Disable the clock for given id
|
||||
* @clock_id Id of the clock to be disable
|
||||
*
|
||||
* This function is used by master to disable the clock
|
||||
* including peripherals and PLL clocks.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
|
||||
enum pm_ret_status pm_api_clock_disable(unsigned int clock_id)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_getstate - Get the clock state for given id
|
||||
* @clock_id Id of the clock to be queried
|
||||
* @state 1/0 (Enabled/Disabled)
|
||||
*
|
||||
* This function is used by master to get the state of clock
|
||||
* including peripherals and PLL clocks.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id,
|
||||
unsigned int *state)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_setdivider - Set the clock divider for given id
|
||||
* @clock_id Id of the clock
|
||||
* @divider Divider value
|
||||
*
|
||||
* This function is used by master to set divider for any clock
|
||||
* to achieve desired rate.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_api_clock_setdivider(unsigned int clock_id,
|
||||
unsigned int divider)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_getdivider - Get the clock divider for given id
|
||||
* @clock_id Id of the clock
|
||||
* @divider Divider value
|
||||
*
|
||||
* This function is used by master to get divider values
|
||||
* for any clock.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_api_clock_getdivider(unsigned int clock_id,
|
||||
unsigned int *divider)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_setrate - Set the clock rate for given id
|
||||
* @clock_id Id of the clock
|
||||
* @rate Rate value in hz
|
||||
*
|
||||
* This function is used by master to set rate for any clock.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_api_clock_setrate(unsigned int clock_id,
|
||||
uint64_t rate)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_getrate - Get the clock rate for given id
|
||||
* @clock_id Id of the clock
|
||||
* @rate rate value in hz
|
||||
*
|
||||
* This function is used by master to get rate
|
||||
* for any clock.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id,
|
||||
uint64_t *rate)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_setparent - Set the clock parent for given id
|
||||
* @clock_id Id of the clock
|
||||
* @parent_id parent id
|
||||
*
|
||||
* 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_api_clock_setparent(unsigned int clock_id,
|
||||
unsigned int parent_idx)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clock_getparent - Get the clock parent for given id
|
||||
* @clock_id Id of the clock
|
||||
* @parent_id parent id
|
||||
*
|
||||
* This function is used by master to get parent index
|
||||
* for any clock.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id,
|
||||
unsigned int *parent_idx)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clk_set_pll_mode() - Set PLL mode
|
||||
* @pll PLL id
|
||||
* @mode Mode fraction/integar
|
||||
*
|
||||
* This function sets PLL mode.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_api_clk_set_pll_mode(unsigned int pll,
|
||||
unsigned int mode)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ioctl_get_pll_mode() - Get PLL mode
|
||||
* @pll PLL id
|
||||
* @mode Mode fraction/integar
|
||||
*
|
||||
* This function returns current PLL mode.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll,
|
||||
unsigned int *mode)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clk_set_pll_frac_data() - Set PLL fraction data
|
||||
* @pll PLL id
|
||||
* @data fraction data
|
||||
*
|
||||
* This function sets fraction data. It is valid for fraction
|
||||
* mode only.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll,
|
||||
unsigned int data)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_clk_get_pll_frac_data() - Get PLL fraction data
|
||||
* @pll PLL id
|
||||
* @data fraction data
|
||||
*
|
||||
* This function returns fraction data value.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll,
|
||||
unsigned int *data)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
54
plat/xilinx/zynqmp/pm_service/pm_api_clock.h
Normal file
54
plat/xilinx/zynqmp/pm_service/pm_api_clock.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* ZynqMP system level PM-API functions for clock control.
|
||||
*/
|
||||
|
||||
#ifndef _PM_API_CLOCK_H_
|
||||
#define _PM_API_CLOCK_H_
|
||||
|
||||
#include "pm_common.h"
|
||||
|
||||
#define CLK_NAME_LEN 15
|
||||
|
||||
enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name);
|
||||
enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
|
||||
unsigned int index,
|
||||
uint32_t *topology);
|
||||
enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
|
||||
uint32_t *mul,
|
||||
uint32_t *div);
|
||||
enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
|
||||
unsigned int index,
|
||||
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);
|
||||
#endif /* _PM_API_CLOCK_H_ */
|
|
@ -12,6 +12,7 @@
|
|||
#include <delay_timer.h>
|
||||
#include <mmio.h>
|
||||
#include <platform.h>
|
||||
#include "pm_api_clock.h"
|
||||
#include "pm_api_ioctl.h"
|
||||
#include "pm_api_sys.h"
|
||||
#include "pm_client.h"
|
||||
|
@ -329,6 +330,71 @@ reset_release:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ioctl_set_pll_frac_mode() - Ioctl function for
|
||||
* setting pll mode
|
||||
* @pll PLL id
|
||||
* @mode Mode fraction/integar
|
||||
*
|
||||
* This function sets PLL mode
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ioctl_get_pll_frac_mode() - Ioctl function for
|
||||
* getting pll mode
|
||||
* @pll PLL id
|
||||
* @mode Mode fraction/integar
|
||||
*
|
||||
* This function return current PLL mode
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ioctl_set_pll_frac_data() - Ioctl function for
|
||||
* setting pll fraction data
|
||||
* @pll PLL id
|
||||
* @data fraction data
|
||||
*
|
||||
* This function sets fraction data.
|
||||
* It is valid for fraction mode only.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ioctl_get_pll_frac_data() - Ioctl function for
|
||||
* getting pll fraction data
|
||||
* @pll PLL id
|
||||
* @data fraction data
|
||||
*
|
||||
* This function returns fraction data value.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_api_ioctl() - PM IOCTL API for device control and configs
|
||||
* @node_id Node ID of the device
|
||||
|
@ -374,6 +440,18 @@ enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
|
|||
case IOCTL_SET_SD_TAPDELAY:
|
||||
ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
|
||||
break;
|
||||
case IOCTL_SET_PLL_FRAC_MODE:
|
||||
ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
|
||||
break;
|
||||
case IOCTL_GET_PLL_FRAC_MODE:
|
||||
ret = pm_ioctl_get_pll_frac_mode(arg1, value);
|
||||
break;
|
||||
case IOCTL_SET_PLL_FRAC_DATA:
|
||||
ret = pm_ioctl_set_pll_frac_data(arg1, arg2);
|
||||
break;
|
||||
case IOCTL_GET_PLL_FRAC_DATA:
|
||||
ret = pm_ioctl_get_pll_frac_data(arg1, value);
|
||||
break;
|
||||
default:
|
||||
ret = PM_RET_ERROR_NOTSUPPORTED;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,11 @@ enum pm_ioctl_id {
|
|||
IOCTL_SET_SGMII_MODE,
|
||||
IOCTL_SD_DLL_RESET,
|
||||
IOCTL_SET_SD_TAPDELAY,
|
||||
/* Ioctl for clock driver */
|
||||
IOCTL_SET_PLL_FRAC_MODE,
|
||||
IOCTL_GET_PLL_FRAC_MODE,
|
||||
IOCTL_SET_PLL_FRAC_DATA,
|
||||
IOCTL_GET_PLL_FRAC_DATA,
|
||||
};
|
||||
|
||||
enum rpu_oper_mode {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <arch_helpers.h>
|
||||
#include <platform.h>
|
||||
#include "pm_api_clock.h"
|
||||
#include "pm_api_ioctl.h"
|
||||
#include "pm_api_pinctrl.h"
|
||||
#include "pm_api_sys.h"
|
||||
|
@ -658,3 +659,285 @@ enum pm_ret_status pm_ioctl(enum pm_node_id nid,
|
|||
{
|
||||
return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_get_name() - PM call to request a clock's name
|
||||
* @clock_id Clock ID
|
||||
* @name Name of clock (max 16 bytes)
|
||||
*
|
||||
* This function is used by master to get nmae of clock specified
|
||||
* by given clock ID.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
static enum pm_ret_status pm_clock_get_name(unsigned int clock_id, char *name)
|
||||
{
|
||||
return pm_api_clock_get_name(clock_id, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_get_topology() - PM call to request a clock's topology
|
||||
* @clock_id Clock ID
|
||||
* @index Topology index for next toplogy node
|
||||
* @topology Buffer to store nodes in topology and flags
|
||||
*
|
||||
* This function is used by master to get topology information for the
|
||||
* clock specified by given clock ID. Each response would return 3
|
||||
* topology nodes. To get next nodes, caller needs to call this API with
|
||||
* index of next node. Index starts from 0.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
static enum pm_ret_status pm_clock_get_topology(unsigned int clock_id,
|
||||
unsigned int index,
|
||||
uint32_t *topology)
|
||||
{
|
||||
return pm_api_clock_get_topology(clock_id, index, topology);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_get_fixedfactor_params() - PM call to request a clock's fixed factor
|
||||
* parameters for fixed clock
|
||||
* @clock_id Clock ID
|
||||
* @mul Multiplication value
|
||||
* @div Divisor value
|
||||
*
|
||||
* This function is used by master to get fixed factor parameers for the
|
||||
* fixed clock. This API is application only for the fixed clock.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
static enum pm_ret_status pm_clock_get_fixedfactor_params(unsigned int clock_id,
|
||||
uint32_t *mul,
|
||||
uint32_t *div)
|
||||
{
|
||||
return pm_api_clock_get_fixedfactor_params(clock_id, mul, div);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_get_parents() - PM call to request a clock's first 3 parents
|
||||
* @clock_id Clock ID
|
||||
* @index Index of next parent
|
||||
* @parents Parents of the given clock
|
||||
*
|
||||
* This function is used by master to get clock's parents information.
|
||||
* This API will return 3 parents with a single response. To get other
|
||||
* parents, master should call same API in loop with new parent index
|
||||
* till error is returned.
|
||||
*
|
||||
* E.g First call should have index 0 which will return parents 0, 1 and
|
||||
* 2. Next call, index should be 3 which will return parent 3,4 and 5 and
|
||||
* so on.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
static enum pm_ret_status pm_clock_get_parents(unsigned int clock_id,
|
||||
unsigned int index,
|
||||
uint32_t *parents)
|
||||
{
|
||||
return pm_api_clock_get_parents(clock_id, index, parents);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_get_attributes() - PM call to request a clock's attributes
|
||||
* @clock_id Clock ID
|
||||
* @attr Clock attributes
|
||||
*
|
||||
* This function is used by master to get clock's attributes
|
||||
* (e.g. valid, clock type, etc).
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
static enum pm_ret_status pm_clock_get_attributes(unsigned int clock_id,
|
||||
uint32_t *attr)
|
||||
{
|
||||
return pm_api_clock_get_attributes(clock_id, attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_enable() - Enable the clock for given id
|
||||
* @clock_id: Id of the clock to be enabled
|
||||
*
|
||||
* This function is used by master to enable the clock
|
||||
* including peripherals and PLL clocks.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
|
||||
enum pm_ret_status pm_clock_enable(unsigned int clock_id)
|
||||
{
|
||||
return pm_api_clock_enable(clock_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_disable - Disable the clock for given id
|
||||
* @clock_id: Id of the clock to be disable
|
||||
*
|
||||
* This function is used by master to disable the clock
|
||||
* including peripherals and PLL clocks.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
|
||||
enum pm_ret_status pm_clock_disable(unsigned int clock_id)
|
||||
{
|
||||
return pm_api_clock_disable(clock_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_getstate - Get the clock state for given id
|
||||
* @clock_id: Id of the clock to be queried
|
||||
* @state: 1/0 (Enabled/Disabled)
|
||||
*
|
||||
* This function is used by master to get the state of clock
|
||||
* including peripherals and PLL clocks.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
|
||||
unsigned int *state)
|
||||
{
|
||||
return pm_api_clock_getstate(clock_id, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_setdivider - Set the clock divider for given id
|
||||
* @clock_id: Id of the clock
|
||||
* @divider: divider value
|
||||
*
|
||||
* This function is used by master to set divider for any clock
|
||||
* to achieve desired rate.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
|
||||
unsigned int divider)
|
||||
{
|
||||
return pm_api_clock_setdivider(clock_id, divider);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_getdivider - Get the clock divider for given id
|
||||
* @clock_id: Id of the clock
|
||||
* @divider: divider value
|
||||
*
|
||||
* This function is used by master to get divider values
|
||||
* for any clock.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
|
||||
unsigned int *divider)
|
||||
{
|
||||
return pm_api_clock_getdivider(clock_id, divider);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_setrate - Set the clock rate for given id
|
||||
* @clock_id: Id of the clock
|
||||
* @rate: rate value in hz
|
||||
*
|
||||
* This function is used by master to set rate for any clock.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
|
||||
uint64_t rate)
|
||||
{
|
||||
return pm_api_clock_setrate(clock_id, rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_getrate - Get the clock rate for given id
|
||||
* @clock_id: Id of the clock
|
||||
* @rate: rate value in hz
|
||||
*
|
||||
* This function is used by master to get rate
|
||||
* for any clock.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
|
||||
uint64_t *rate)
|
||||
{
|
||||
return pm_api_clock_getrate(clock_id, rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_setparent - Set the clock parent for given id
|
||||
* @clock_id: Id of the clock
|
||||
* @parent_id: parent id
|
||||
*
|
||||
* 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_id)
|
||||
{
|
||||
return pm_api_clock_setparent(clock_id, parent_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_clock_getparent - Get the clock parent for given id
|
||||
* @clock_id: Id of the clock
|
||||
* @parent_id: parent id
|
||||
*
|
||||
* This function is used by master to get parent index
|
||||
* for any clock.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason.
|
||||
*/
|
||||
enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
|
||||
unsigned int *parent_id)
|
||||
{
|
||||
return pm_api_clock_getparent(clock_id, parent_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_query_data() - PM API for querying firmware data
|
||||
* @arg1 Argument 1 to requested IOCTL call
|
||||
* @arg2 Argument 2 to requested IOCTL call
|
||||
* @arg3 Argument 3 to requested IOCTL call
|
||||
* @arg4 Argument 4 to requested IOCTL call
|
||||
* @data Returned output data
|
||||
*
|
||||
* This function returns requested data.
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_query_data(enum pm_query_id qid,
|
||||
unsigned int arg1,
|
||||
unsigned int arg2,
|
||||
unsigned int arg3,
|
||||
unsigned int *data)
|
||||
{
|
||||
enum pm_ret_status ret;
|
||||
|
||||
switch (qid) {
|
||||
case PM_QID_CLOCK_GET_NAME:
|
||||
ret = pm_clock_get_name(arg1, (char *)data);
|
||||
break;
|
||||
case PM_QID_CLOCK_GET_TOPOLOGY:
|
||||
ret = pm_clock_get_topology(arg1, arg2, &data[1]);
|
||||
data[0] = ret;
|
||||
break;
|
||||
case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
|
||||
ret = pm_clock_get_fixedfactor_params(arg1, &data[1], &data[2]);
|
||||
data[0] = ret;
|
||||
break;
|
||||
case PM_QID_CLOCK_GET_PARENTS:
|
||||
ret = pm_clock_get_parents(arg1, arg2, &data[1]);
|
||||
data[0] = ret;
|
||||
break;
|
||||
case PM_QID_CLOCK_GET_ATTRIBUTES:
|
||||
ret = pm_clock_get_attributes(arg1, &data[1]);
|
||||
data[0] = ret;
|
||||
break;
|
||||
default:
|
||||
ret = PM_RET_ERROR_ARGS;
|
||||
WARN("Unimplemented query service call: 0x%x\n", qid);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,15 @@
|
|||
#include <stdint.h>
|
||||
#include "pm_defs.h"
|
||||
|
||||
enum pm_query_id {
|
||||
PM_QID_INVALID,
|
||||
PM_QID_CLOCK_GET_NAME,
|
||||
PM_QID_CLOCK_GET_TOPOLOGY,
|
||||
PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS,
|
||||
PM_QID_CLOCK_GET_PARENTS,
|
||||
PM_QID_CLOCK_GET_ATTRIBUTES,
|
||||
};
|
||||
|
||||
/**********************************************************
|
||||
* System-level API function declarations
|
||||
**********************************************************/
|
||||
|
@ -110,5 +119,25 @@ enum pm_ret_status pm_ioctl(enum pm_node_id nid,
|
|||
unsigned int arg1,
|
||||
unsigned int arg2,
|
||||
unsigned int *value);
|
||||
|
||||
enum pm_ret_status pm_clock_enable(unsigned int clock_id);
|
||||
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);
|
||||
enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
|
||||
unsigned int divider);
|
||||
enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
|
||||
unsigned int *divider);
|
||||
enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
|
||||
uint64_t rate);
|
||||
enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
|
||||
uint64_t *rate);
|
||||
enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
|
||||
unsigned int parent_id);
|
||||
enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
|
||||
unsigned int *parent_id);
|
||||
enum pm_ret_status pm_query_data(enum pm_query_id qid,
|
||||
unsigned int arg1,
|
||||
unsigned int arg2,
|
||||
unsigned int arg3,
|
||||
unsigned int *data);
|
||||
#endif /* _PM_API_SYS_H_ */
|
||||
|
|
|
@ -76,6 +76,18 @@ enum pm_api_id {
|
|||
PM_PINCTRL_CONFIG_PARAM_GET,
|
||||
PM_PINCTRL_CONFIG_PARAM_SET,
|
||||
PM_IOCTL,
|
||||
/* API to query information from firmware */
|
||||
PM_QUERY_DATA,
|
||||
/* Clock control API functions */
|
||||
PM_CLOCK_ENABLE,
|
||||
PM_CLOCK_DISABLE,
|
||||
PM_CLOCK_GETSTATE,
|
||||
PM_CLOCK_SETDIVIDER,
|
||||
PM_CLOCK_GETDIVIDER,
|
||||
PM_CLOCK_SETRATE,
|
||||
PM_CLOCK_GETRATE,
|
||||
PM_CLOCK_SETPARENT,
|
||||
PM_CLOCK_GETPARENT,
|
||||
PM_API_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -289,6 +289,72 @@ 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_QUERY_DATA:
|
||||
{
|
||||
uint32_t data[4];
|
||||
|
||||
ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
pm_arg[3], data);
|
||||
SMC_RET2(handle, (uint64_t)data[0] | ((uint64_t)data[1] << 32),
|
||||
(uint64_t)data[2] | ((uint64_t)data[3] << 32));
|
||||
}
|
||||
|
||||
case PM_CLOCK_ENABLE:
|
||||
ret = pm_clock_enable(pm_arg[0]);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_CLOCK_DISABLE:
|
||||
ret = pm_clock_disable(pm_arg[0]);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_CLOCK_GETSTATE:
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
ret = pm_clock_getstate(pm_arg[0], &value);
|
||||
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
|
||||
}
|
||||
|
||||
case PM_CLOCK_SETDIVIDER:
|
||||
ret = pm_clock_setdivider(pm_arg[0], pm_arg[1]);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_CLOCK_GETDIVIDER:
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
ret = pm_clock_getdivider(pm_arg[0], &value);
|
||||
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
|
||||
}
|
||||
|
||||
case PM_CLOCK_SETRATE:
|
||||
ret = pm_clock_setrate(pm_arg[0],
|
||||
((uint64_t)pm_arg[2]) << 32 | pm_arg[1]);
|
||||
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_CLOCK_GETRATE:
|
||||
{
|
||||
uint64_t value;
|
||||
|
||||
ret = pm_clock_getrate(pm_arg[0], &value);
|
||||
SMC_RET2(handle, (uint64_t)ret | (value & 0xFFFFFFFF) << 32,
|
||||
(value >> 32) & 0xFFFFFFFF);
|
||||
|
||||
}
|
||||
|
||||
case PM_CLOCK_SETPARENT:
|
||||
ret = pm_clock_setparent(pm_arg[0], pm_arg[1]);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_CLOCK_GETPARENT:
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
ret = pm_clock_getparent(pm_arg[0], &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);
|
||||
|
|
Loading…
Add table
Reference in a new issue