[PATCH 4/7] clk: zynqmp: Add support for get max divider

Rajan Vaja
2019-11-12T13:18:05Z

To achieve best possible rate, maximum limit of divider is required
while computation. Get maximum supported divisor from firmware. To
maintain backward compatibility assign maximum possible value(0xFFFF)
if query for max divisor is not successful.

Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
---
drivers/clk/zynqmp/divider.c | 19 +++++++++++++++++++
include/linux/firmware/xlnx-zynqmp.h | 1 +
2 files changed, 20 insertions(+)

diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c
index d8f5b70d..b79cd45 100644
--- a/drivers/clk/zynqmp/divider.c
+++ b/drivers/clk/zynqmp/divider.c
@@ -41,6 +41,7 @@ struct zynqmp_clk_divider {
bool is_frac;
u32 clk_id;
u32 div_type;
+ u16 max_div;
};

static inline int zynqmp_divider_get_val(unsigned long parent_rate,
@@ -195,6 +196,9 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name,
struct clk_hw *hw;
struct clk_init_data init;
int ret;
+ const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+ struct zynqmp_pm_query_data qdata = {0};
+ u32 ret_payload[PAYLOAD_ARG_CNT];

/* allocate the divider */
div = kzalloc(sizeof(*div), GFP_KERNEL);
@@ -215,6 +219,21 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name,
div->clk_id = clk_id;
div->div_type = nodes->type;

+ /*
+ * To achieve best possible rate, maximum limit of divider is required
+ * while computation. Get maximum supported divisor from firmware. To
+ * maintain backward compatibility assign maximum possible value(0xFFFF)
+ * if query for max divisor is not successful.
+ */
+ qdata.qid = PM_QID_CLOCK_GET_MAX_DIVISOR;
+ qdata.arg1 = clk_id;
+ qdata.arg2 = nodes->type;
+ ret = eemi_ops->query_data(qdata, ret_payload);
+ if (ret)
+ div->max_div = U16_MAX;
+ else
+ div->max_div = ret_payload[1];
+
hw = &div->hw;
ret = clk_hw_register(NULL, hw);
if (ret) {
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index f019d1c..f0d4558 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -114,6 +114,7 @@ enum pm_query_id {
PM_QID_CLOCK_GET_PARENTS,
PM_QID_CLOCK_GET_ATTRIBUTES,
PM_QID_CLOCK_GET_NUM_CLOCKS = 12,
+ PM_QID_CLOCK_GET_MAX_DIVISOR,
};

enum zynqmp_pm_reset_action {
--
2.7.4