aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/zynqmp/clkc.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c
index b0908ec62f73..112ae7d157e1 100644
--- a/drivers/clk/zynqmp/clkc.c
+++ b/drivers/clk/zynqmp/clkc.c
@@ -53,6 +53,10 @@
53#define RESERVED_CLK_NAME "" 53#define RESERVED_CLK_NAME ""
54 54
55#define CLK_VALID_MASK 0x1 55#define CLK_VALID_MASK 0x1
56#define NODE_CLASS_SHIFT 26U
57#define NODE_SUBCLASS_SHIFT 20U
58#define NODE_TYPE_SHIFT 14U
59#define NODE_INDEX_SHIFT 0U
56 60
57enum clk_type { 61enum clk_type {
58 CLK_TYPE_OUTPUT, 62 CLK_TYPE_OUTPUT,
@@ -80,6 +84,7 @@ struct clock_parent {
80 * @num_nodes: Number of nodes present in topology 84 * @num_nodes: Number of nodes present in topology
81 * @parent: Parent of clock 85 * @parent: Parent of clock
82 * @num_parents: Number of parents of clock 86 * @num_parents: Number of parents of clock
87 * @clk_id: Clock id
83 */ 88 */
84struct zynqmp_clock { 89struct zynqmp_clock {
85 char clk_name[MAX_NAME_LEN]; 90 char clk_name[MAX_NAME_LEN];
@@ -89,6 +94,7 @@ struct zynqmp_clock {
89 u32 num_nodes; 94 u32 num_nodes;
90 struct clock_parent parent[MAX_PARENT]; 95 struct clock_parent parent[MAX_PARENT];
91 u32 num_parents; 96 u32 num_parents;
97 u32 clk_id;
92}; 98};
93 99
94static const char clk_type_postfix[][10] = { 100static const char clk_type_postfix[][10] = {
@@ -396,7 +402,8 @@ static int zynqmp_clock_get_topology(u32 clk_id,
396 402
397 *num_nodes = 0; 403 *num_nodes = 0;
398 for (j = 0; j <= MAX_NODES; j += 3) { 404 for (j = 0; j <= MAX_NODES; j += 3) {
399 ret = zynqmp_pm_clock_get_topology(clk_id, j, pm_resp); 405 ret = zynqmp_pm_clock_get_topology(clock[clk_id].clk_id, j,
406 pm_resp);
400 if (ret) 407 if (ret)
401 return ret; 408 return ret;
402 ret = __zynqmp_clock_get_topology(topology, pm_resp, num_nodes); 409 ret = __zynqmp_clock_get_topology(topology, pm_resp, num_nodes);
@@ -459,7 +466,8 @@ static int zynqmp_clock_get_parents(u32 clk_id, struct clock_parent *parents,
459 *num_parents = 0; 466 *num_parents = 0;
460 do { 467 do {
461 /* Get parents from firmware */ 468 /* Get parents from firmware */
462 ret = zynqmp_pm_clock_get_parents(clk_id, j, pm_resp); 469 ret = zynqmp_pm_clock_get_parents(clock[clk_id].clk_id, j,
470 pm_resp);
463 if (ret) 471 if (ret)
464 return ret; 472 return ret;
465 473
@@ -528,13 +536,14 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
528 const char **parent_names) 536 const char **parent_names)
529{ 537{
530 int j; 538 int j;
531 u32 num_nodes; 539 u32 num_nodes, clk_dev_id;
532 char *clk_out = NULL; 540 char *clk_out = NULL;
533 struct clock_topology *nodes; 541 struct clock_topology *nodes;
534 struct clk_hw *hw = NULL; 542 struct clk_hw *hw = NULL;
535 543
536 nodes = clock[clk_id].node; 544 nodes = clock[clk_id].node;
537 num_nodes = clock[clk_id].num_nodes; 545 num_nodes = clock[clk_id].num_nodes;
546 clk_dev_id = clock[clk_id].clk_id;
538 547
539 for (j = 0; j < num_nodes; j++) { 548 for (j = 0; j < num_nodes; j++) {
540 /* 549 /*
@@ -551,13 +560,14 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
551 if (!clk_topology[nodes[j].type]) 560 if (!clk_topology[nodes[j].type])
552 continue; 561 continue;
553 562
554 hw = (*clk_topology[nodes[j].type])(clk_out, clk_id, 563 hw = (*clk_topology[nodes[j].type])(clk_out, clk_dev_id,
555 parent_names, 564 parent_names,
556 num_parents, 565 num_parents,
557 &nodes[j]); 566 &nodes[j]);
558 if (IS_ERR(hw)) 567 if (IS_ERR(hw))
559 pr_warn_once("%s() %s register fail with %ld\n", 568 pr_warn_once("%s() 0x%x: %s register fail with %ld\n",
560 __func__, clk_name, PTR_ERR(hw)); 569 __func__, clk_dev_id, clk_name,
570 PTR_ERR(hw));
561 571
562 parent_names[0] = clk_out; 572 parent_names[0] = clk_out;
563 } 573 }
@@ -621,20 +631,26 @@ static int zynqmp_register_clocks(struct device_node *np)
621static void zynqmp_get_clock_info(void) 631static void zynqmp_get_clock_info(void)
622{ 632{
623 int i, ret; 633 int i, ret;
624 u32 attr, type = 0; 634 u32 attr, type = 0, nodetype, subclass, class;
625 635
626 for (i = 0; i < clock_max_idx; i++) { 636 for (i = 0; i < clock_max_idx; i++) {
627 zynqmp_pm_clock_get_name(i, clock[i].clk_name);
628 if (!strcmp(clock[i].clk_name, RESERVED_CLK_NAME))
629 continue;
630
631 ret = zynqmp_pm_clock_get_attributes(i, &attr); 637 ret = zynqmp_pm_clock_get_attributes(i, &attr);
632 if (ret) 638 if (ret)
633 continue; 639 continue;
634 640
635 clock[i].valid = attr & CLK_VALID_MASK; 641 clock[i].valid = attr & CLK_VALID_MASK;
636 clock[i].type = attr >> CLK_TYPE_SHIFT ? CLK_TYPE_EXTERNAL : 642 clock[i].type = ((attr >> CLK_TYPE_SHIFT) & 0x1) ?
637 CLK_TYPE_OUTPUT; 643 CLK_TYPE_EXTERNAL : CLK_TYPE_OUTPUT;
644 nodetype = (attr >> NODE_TYPE_SHIFT) & 0x3F;
645 subclass = (attr >> NODE_SUBCLASS_SHIFT) & 0x3F;
646 class = (attr >> NODE_CLASS_SHIFT) & 0x3F;
647
648 clock[i].clk_id = (class << NODE_CLASS_SHIFT) |
649 (subclass << NODE_SUBCLASS_SHIFT) |
650 (nodetype << NODE_TYPE_SHIFT) |
651 (i << NODE_INDEX_SHIFT);
652
653 zynqmp_pm_clock_get_name(clock[i].clk_id, clock[i].clk_name);
638 } 654 }
639 655
640 /* Get topology of all clock */ 656 /* Get topology of all clock */