zynqmp: pm: Add clock control EEMI API and ioctl functions
authorRajan Vaja <rajan.vaja@xilinx.com>
Wed, 17 Jan 2018 10:39:25 +0000 (02:39 -0800)
committerJolly Shah <jollys@xilinx.com>
Thu, 15 Mar 2018 17:23:41 +0000 (10:23 -0700)
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>
plat/xilinx/zynqmp/platform.mk
plat/xilinx/zynqmp/pm_service/pm_api_clock.c [new file with mode: 0644]
plat/xilinx/zynqmp/pm_service/pm_api_clock.h [new file with mode: 0644]
plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
plat/xilinx/zynqmp/pm_service/pm_api_sys.c
plat/xilinx/zynqmp/pm_service/pm_api_sys.h
plat/xilinx/zynqmp/pm_service/pm_defs.h
plat/xilinx/zynqmp/pm_service/pm_svc_main.c

index 2abcd288ce9bef0f92736c77e15a510b42056c4c..e49a9cdf78e2d7f83a081f7d00ea2c166118fe9c 100644 (file)
@@ -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
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
new file mode 100644 (file)
index 0000000..4096a81
--- /dev/null
@@ -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;
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
new file mode 100644 (file)
index 0000000..2e7260e
--- /dev/null
@@ -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_ */
index c881d1248eb4529cd3741325f1b6b0b4890e30d0..7634b8c873d2f2bfffde851b47459dccb10be53b 100644 (file)
@@ -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;
        }
index a7f14a477418e8cdd98d355cd3555f588051b70b..b290574c84602949dc3cf2232d8e1d5ab50e5f78 100644 (file)
@@ -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 {
index be243717e4ae314d780e7b771c1413467e2c8b52..fcc0c6e76f0cbd6d374b628c5806ef1519b5899f 100644 (file)
@@ -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;
+}
index 1c91e8f49f76073be991012de4842944bf1e47f9..20d80c21760e07ce5557e37c31d37160d21350eb 100644 (file)
 #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_ */
index afd92f649fee40b64db92eb7409f5d5fa52dbfdb..45a92e95442e61276cc8f59964ac42415b151f75 100644 (file)
@@ -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
 };
 
index 648de24bad47e986677ad11c9186afdf03310c55..4fd69b91f5e6c27daf69c4c36979aabc0abc65e0 100644 (file)
@@ -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);