zynqmp: pm: Reimplement clock get state (status) EEMI API
authorJolly Shah <jollys@xilinx.com>
Wed, 2 Jan 2019 20:55:41 +0000 (12:55 -0800)
committerJolly Shah <jollys@xilinx.com>
Fri, 4 Jan 2019 19:48:27 +0000 (11:48 -0800)
Clock get state EEMI API is reimplemented to use system-level clock
and pll EEMI APIs rather than direct MMIO read/write accesses to clock
and pll control registers.
Since linux is_enabled method for PLLs still uses clock get state API
get the PLL state, in the implementation of pm_clock_getstate() we need
to workaround this by distinguishing two cases: 1) if the given clock ID
corresponds to a PLL output clock ID; or 2) given clock ID is truly an
on-chip clock whose state of the gate should be returned.
For case 1) we'll call pm_api_clock_pll_getstate() implemented in
pm_api_clock.h/c. This function will query the PLL state from PMU using
the system-level PLL get mode EEMI API.
For case 2) we'll call the PMU to query the clock gate state using
system-level clock get status EEMI API.
Functions that appear to be unused after this change is made are removed.

Signed-off-by: Mirela Simonovic <mirela.simonovic@aggios.com>
Acked-by: Will Wong <WILLW@xilinx.com>
Signed-off-by: Jolly Shah <jollys@xilinx.com>
plat/xilinx/zynqmp/pm_service/pm_api_clock.c
plat/xilinx/zynqmp/pm_service/pm_api_clock.h
plat/xilinx/zynqmp/pm_service/pm_api_sys.c

index 542dbdcd6ca6e7d62ba2657c1becb058abdb1aca..536889ce1b33209e288c6afc3b6f6eb3c6b16223 100644 (file)
@@ -2665,94 +2665,35 @@ enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll)
 }
 
 /**
- * pm_api_get_pll_state() - Get state of PLL
- * @clock_id   Id of the PLL
- * @state      State of PLL(1: Enable, 0: Reset)
+ * pm_clock_pll_get_state - Get state of the PLL
+ * @pll                Pointer to the target PLL structure
+ * @state      Location to store the state: 1/0 ("Enabled"/"Disabled")
  *
- * This function is to check state of PLL.
- */
-static inline enum pm_ret_status pm_api_get_pll_state(unsigned int clock_id,
-                                       unsigned int *state)
-{
-       enum pm_ret_status ret = PM_RET_SUCCESS;
-       unsigned int reg, val;
-
-       reg = clocks[clock_id].control_reg;
-
-       ret = pm_mmio_read(reg, &val);
-
-       /* state:
-        * 1 - PLL is enabled
-        * 0 - PLL is in reset state
-        */
-       *state = !(val & PLLCTRL_RESET_MASK);
-       return ret;
-}
-
-/**
- * pm_api_get_clk_state() - Get the state of clock for given id
- * @clock_id: Id of the clock to be enabled
- * @state: Enable(1)/Disable(0)
- *
- * This function is to get state of the clock which is not PLL.
+ * "Enable" actually means that the PLL is locked and its bypass is deasserted,
+ * "Disable" means that it is bypassed.
  *
- * Return: Returns status, either success or error+reason.
+ * Return: PM_RET_ERROR_ARGS error if the argument is not valid, success if
+ * returned state value is valid or an error if returned by PMU
  */
-static enum pm_ret_status pm_api_get_clk_state(unsigned int clock_id,
-                                              unsigned int *state)
+enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll,
+                                         unsigned int *state)
 {
-       enum pm_ret_status ret = PM_RET_SUCCESS;
-       struct pm_clock_node *nodes = *clocks[clock_id].nodes;
-       uint8_t num_nodes = clocks[clock_id].num_nodes;
-       unsigned int reg, val;
-       uint8_t i = 0;
-       uint8_t offset = NA_SHIFT, width = NA_WIDTH;
-
-       reg = clocks[clock_id].control_reg;
+       enum pm_ret_status status;
+       enum pm_pll_mode mode;
 
-       for (i = 0; i < num_nodes; i++) {
-               if (nodes->type == TYPE_GATE) {
-                       offset = nodes->offset;
-                       width = nodes->width;
-               }
-               nodes++;
-       }
-       if (width == NA_WIDTH)
-               return PM_RET_ERROR_NOTSUPPORTED;
-
-       ret = pm_mmio_read(reg, &val);
-       *state = (val & BIT_MASK(offset, width)) >> offset;
-
-       return ret;
-}
-
-/**
- * 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)
-{
-       enum pm_ret_status ret = PM_RET_SUCCESS;
-
-       if (!pm_clock_valid(clock_id))
+       if (!pll || !state)
                return PM_RET_ERROR_ARGS;
 
-       if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
-               return PM_RET_ERROR_NOTSUPPORTED;
+       status = pm_pll_get_mode(pll->nid, &mode);
+       if (status != PM_RET_SUCCESS)
+               return status;
 
-       if (ISPLL(clock_id))
-               ret = pm_api_get_pll_state(clock_id, state);
+       if (mode == PM_PLL_MODE_RESET)
+               *state = 0;
        else
-               ret = pm_api_get_clk_state(clock_id, state);
+               *state = 1;
 
-       return ret;
+       return PM_RET_SUCCESS;
 }
 
 static enum pm_ret_status pm_api_clk_set_divider(unsigned int clock_id,
index 5ec4d7496bbc8db2ef9bce97c229260dd10c6474..dfdaf895f3c3279c5ede3cfcc96b9ca66bf90ebc 100644 (file)
@@ -297,8 +297,9 @@ enum pm_ret_status pm_clock_id_is_valid(unsigned int clock_id);
 
 enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll);
 enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll);
-enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id,
-                                        unsigned int *state);
+enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll,
+                                         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,
index fe5828edd94f58b501b773efa6b1771b63e98fbe..49471dcac761b40e59c8572f655b65628b7ac04a 100644 (file)
@@ -932,7 +932,23 @@ enum pm_ret_status pm_clock_disable(unsigned int clock_id)
 enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
                                     unsigned int *state)
 {
-       return pm_api_clock_getstate(clock_id, state);
+       struct pm_pll *pll;
+       uint32_t payload[PAYLOAD_ARG_CNT];
+       enum pm_ret_status status;
+
+       /* First try to handle it as a PLL */
+       pll = pm_clock_get_pll(clock_id);
+       if (pll)
+               return pm_clock_pll_get_state(pll, state);
+
+       /* Check if clock ID is a valid on-chip clock */
+       status = pm_clock_id_is_valid(clock_id);
+       if (status != PM_RET_SUCCESS)
+               return status;
+
+       /* Send request to the PMU */
+       PM_PACK_PAYLOAD2(payload, PM_CLOCK_GETSTATE, clock_id);
+       return pm_ipi_send_sync(primary_proc, payload, state, 1);
 }
 
 /**