Commit caae497d authored by Rajan Vaja's avatar Rajan Vaja Committed by Jolly Shah
Browse files

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: default avatarRajan Vaja <rajanv@xilinx.com>
Signed-off-by: default avatarJolly Shah <jollys@xilinx.com>
parent 1818c029
...@@ -79,6 +79,7 @@ BL31_SOURCES += drivers/arm/cci/cci.c \ ...@@ -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_sys.c \
plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.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_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_ipi.c \
plat/xilinx/zynqmp/pm_service/pm_client.c \ plat/xilinx/zynqmp/pm_service/pm_client.c \
plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c
/*
* 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;
}
/*
* 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 @@ ...@@ -12,6 +12,7 @@
#include <delay_timer.h> #include <delay_timer.h>
#include <mmio.h> #include <mmio.h>
#include <platform.h> #include <platform.h>
#include "pm_api_clock.h"
#include "pm_api_ioctl.h" #include "pm_api_ioctl.h"
#include "pm_api_sys.h" #include "pm_api_sys.h"
#include "pm_client.h" #include "pm_client.h"
...@@ -329,6 +330,71 @@ reset_release: ...@@ -329,6 +330,71 @@ reset_release:
return ret; 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 * pm_api_ioctl() - PM IOCTL API for device control and configs
* @node_id Node ID of the device * @node_id Node ID of the device
...@@ -374,6 +440,18 @@ enum pm_ret_status pm_api_ioctl(enum pm_node_id nid, ...@@ -374,6 +440,18 @@ enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
case IOCTL_SET_SD_TAPDELAY: case IOCTL_SET_SD_TAPDELAY:
ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2); ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
break; 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: default:
ret = PM_RET_ERROR_NOTSUPPORTED; ret = PM_RET_ERROR_NOTSUPPORTED;
} }
......
...@@ -22,6 +22,11 @@ enum pm_ioctl_id { ...@@ -22,6 +22,11 @@ enum pm_ioctl_id {
IOCTL_SET_SGMII_MODE, IOCTL_SET_SGMII_MODE,
IOCTL_SD_DLL_RESET, IOCTL_SD_DLL_RESET,
IOCTL_SET_SD_TAPDELAY, 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 { enum rpu_oper_mode {
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <arch_helpers.h> #include <arch_helpers.h>
#include <platform.h> #include <platform.h>
#include "pm_api_clock.h"
#include "pm_api_ioctl.h" #include "pm_api_ioctl.h"
#include "pm_api_pinctrl.h" #include "pm_api_pinctrl.h"
#include "pm_api_sys.h" #include "pm_api_sys.h"
...@@ -658,3 +659,285 @@ enum pm_ret_status pm_ioctl(enum pm_node_id nid, ...@@ -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); 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 @@ ...@@ -10,6 +10,15 @@
#include <stdint.h> #include <stdint.h>
#include "pm_defs.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 * System-level API function declarations
**********************************************************/ **********************************************************/
...@@ -110,5 +119,25 @@ enum pm_ret_status pm_ioctl(enum pm_node_id nid, ...@@ -110,5 +119,25 @@ enum pm_ret_status pm_ioctl(enum pm_node_id nid,
unsigned int arg1, unsigned int arg1,
unsigned int arg2, unsigned int arg2,
unsigned int *value); 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_ */ #endif /* _PM_API_SYS_H_ */
...@@ -76,6 +76,18 @@ enum pm_api_id { ...@@ -76,6 +76,18 @@ enum pm_api_id {
PM_PINCTRL_CONFIG_PARAM_GET, PM_PINCTRL_CONFIG_PARAM_GET,
PM_PINCTRL_CONFIG_PARAM_SET, PM_PINCTRL_CONFIG_PARAM_SET,
PM_IOCTL, 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 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, ...@@ -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); 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: default:
WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid); WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK); SMC_RET1(handle, SMC_UNK);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment