diff options
| -rw-r--r-- | drivers/clk/zynqmp/clkc.c | 42 |
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 | ||
| 57 | enum clk_type { | 61 | enum 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 | */ |
| 84 | struct zynqmp_clock { | 89 | struct 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 | ||
| 94 | static const char clk_type_postfix[][10] = { | 100 | static 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) | |||
| 621 | static void zynqmp_get_clock_info(void) | 631 | static 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 */ |
